summaryrefslogtreecommitdiff
path: root/sys/net/if.c
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2013-10-19 11:11:25 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2013-10-19 11:11:25 +0000
commit55ef402852967bd82ed711667cb0760899be809b (patch)
treecce98065a9d5e96ac884b8a418fea035e6090964 /sys/net/if.c
parente6e9a9ce763489d6e39c51946126dad6b23a635c (diff)
When we attach an interface, do not try to reuse the last index to
limit the possible races related to unscheduled task, or anything else, relying on an unique index. I say "limit" here because a race can still occurs if you run out of indexes and jump back to 1. A generation number can be added later to avoid this problem. ok deraadt@, claudio@, krw@, mikeb@, "I can live with it" reyk@
Diffstat (limited to 'sys/net/if.c')
-rw-r--r--sys/net/if.c52
1 files changed, 29 insertions, 23 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index 85f0d28ae43..a8328ad155f 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.268 2013/10/17 16:27:40 bluhm Exp $ */
+/* $OpenBSD: if.c,v 1.269 2013/10/19 11:11:24 mpi Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -210,31 +210,37 @@ if_attachsetup(struct ifnet *ifp)
{
int wrapped = 0;
- if (ifindex2ifnet == 0)
+ /*
+ * Always increment the index to avoid races.
+ */
+ if_index++;
+
+ /*
+ * If we hit USHRT_MAX, we skip back to 1 since there are a
+ * number of places where the value of ifp->if_index or
+ * if_index itself is compared to or stored in an unsigned
+ * short. By jumping back, we won't botch those assignments
+ * or comparisons.
+ */
+ if (if_index == USHRT_MAX) {
if_index = 1;
- else {
- while (if_index < if_indexlim &&
- ifindex2ifnet[if_index] != NULL) {
- if_index++;
+ wrapped++;
+ }
+
+ while (if_index < if_indexlim && ifindex2ifnet[if_index] != NULL) {
+ if_index++;
+
+ if (if_index == USHRT_MAX) {
/*
- * If we hit USHRT_MAX, we skip back to 1 since
- * there are a number of places where the value
- * of ifp->if_index or if_index itself is compared
- * to or stored in an unsigned short. By
- * jumping back, we won't botch those assignments
- * or comparisons.
+ * If we have to jump back to 1 twice without
+ * finding an empty slot then there are too many
+ * interfaces.
*/
- if (if_index == USHRT_MAX) {
- if_index = 1;
- /*
- * However, if we have to jump back to 1
- * *twice* without finding an empty
- * slot in ifindex2ifnet[], then there
- * there are too many (>65535) interfaces.
- */
- if (wrapped++)
- panic("too many interfaces");
- }
+ if (wrapped)
+ panic("too many interfaces");
+
+ if_index = 1;
+ wrapped++;
}
}
ifp->if_index = if_index;