diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2013-10-19 11:11:25 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2013-10-19 11:11:25 +0000 |
commit | 55ef402852967bd82ed711667cb0760899be809b (patch) | |
tree | cce98065a9d5e96ac884b8a418fea035e6090964 /sys/net/if.c | |
parent | e6e9a9ce763489d6e39c51946126dad6b23a635c (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.c | 52 |
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; |