On Wed, Mar 19, 2008 at 04:59:40PM -0700, Matthew Dempsky wrote:
> OpenBSD's currently limited to using interfaces with an index < 32 for
> multicast, and on one of my machines I created and destroyed enough
> virtual interfaces during experimentation that some of the interfaces
> currently in use and that I would like to route multicast traffic to
> have indexes >= 32.
>
That's a bug in the multicast code that needs fixing.
> The simple solution is to reboot since I have fewer than 32 interfaces
> total, they'll renumber and everything will be fine. However, I saw
> if_attachsetup (in net/if.c) there's some code for looping through
> ifindex2ifnet twice to try to find an unused interface index, so I
> figured I could avoid rebooting by creating and destroying ~65000
> virtual devices to wrap the counter, and then recreating the necessary
> interfaces so I could use them in multicast.
>
> Fortunately, I tested this idea first, because it actually leads to a
> kernel panic. :-)
>
I somewhat expected that. Nobody ever expected the ifindex to wrap.
> A second somewhat closer look at the kernel's interface handling code
> gives me the impression that the ifnet structures are never freed, the
> ifindex2ifnet table is never zero'd out, and so that loop always
> results in a panic.
>
> Looking at the history on net/if.c, I see a commit comment from itojun
> that "ifindex2ifnet could become NULL when interface gets destroyed,
> when we introduce dynamically-created interfaces", but this was four
> years ago and if_vlan has existed for 7 (though seemingly in a
> different form then). What does "dynamically-created" mean if not
> something like vlan/gif/carp/trunk?
>
> Is there anything major preventing ifindex2ifnet being cleared? (If
> it's just developer interest, it *looks* like it should be a
> straight-forward-enough fix that I'd be interested in trying to write
> a patch.)
>
See attached diff which should help finding free slots (at least it helped
in my case). It will only reuse the last if_index and not previous free
slots. See if.c:if_attachsetup() use of the static if_index.
The main issue with this diff is that ifindexes are reused and some
userland apps (mainly SNMP) require that the ifindex is unique and not
reused. I don't care about SNMP but I wanted to warn you about that.
--
:wq Claudio
Index: if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.168
diff -u -p -r1.168 if.c
--- if.c 5 Jan 2008 19:08:19 -0000 1.168
+++ if.c 18 Jan 2008 22:08:33 -0000
@@ -601,6 +601,7 @@ do { \
/* Announce that the interface is gone. */
rt_ifannouncemsg(ifp, IFAN_DEPARTURE);
+ ifindex2ifnet[ifp->if_index] = NULL;
splx(s);
}