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);
 }

Reply via email to