On Sep 17, 2007 10:32 AM, Peter Avalos <[EMAIL PROTECTED]> wrote: > > On Sat, Sep 01, 2007 at 05:54:10PM -0400, Peter Avalos wrote: > > On Wed, Aug 29, 2007 at 09:50:27PM -0700, Matthew Dillon wrote: > > > > > > So we need to audit all the code that manipulates the in_ifaddrhead > > > list and check for structures that might get freed without being > > > removed > > > from the list. > > > > > > > I'm having no luck. Got any pointers/ideas? > > > > Looking around FreeBSD source I saw this, and was wondering if it could > help?
My question about the panic is: Have you assigned IP address to the tap(4) device via -I option to vkernel? The patch looks good to me; it still needs little modification tho. If you had not assign IP address to tap(4) then I think this patch probably won't fix your panic. Best Regards, sephe > > http://www.theshell.com/cgi-bin/gitweb.cgi?p=freebsd-src.git;a=commitdiff;h=16f96b132d344c7682df05b3bf74278150a5b3b1 > > commit 16f96b132d344c7682df05b3bf74278150a5b3b1 > Author: peadar <peadar> > Date: Wed May 25 13:52:03 2005 +0000 > > Separate out address-detaching part of if_detach into if_purgeaddrs, > so if_tap doesn't need to rely on locally-rolled code to do same. > > The observable symptom of if_tap's bzero'ing the address details > was a crash in "ifconfig tap0" after an if_tap device was closed. > > Reported By: Matti Saarinen (mjsaarin at cc dot helsinki dot fi) > > diff --git a/sys/net/if.c b/sys/net/if.c > index 8aff428..f056329 100644 > --- a/sys/net/if.c > +++ b/sys/net/if.c > @@ -27,7 +27,7 @@ > * SUCH DAMAGE. > * > * @(#)if.c 8.5 (Berkeley) 1/9/95 > - * $FreeBSD: src/sys/net/if.c,v 1.227 2005/04/20 09:30:54 glebius Exp $ > + * $FreeBSD: src/sys/net/if.c,v 1.228 2005/05/25 13:52:03 peadar Exp $ > */ > > #include "opt_compat.h" > @@ -530,13 +530,52 @@ if_attachdomain1(struct ifnet *ifp) > } > > /* > + * Remove any network addresses from an interface. > + */ > + > +void > +if_purgeaddrs(struct ifnet *ifp) > +{ > + struct ifaddr *ifa, *next; > + > + TAILQ_FOREACH_SAFE(ifa, &ifp->if_addrhead, ifa_link, next) { > + > + if (ifa->ifa_addr->sa_family == AF_LINK) > + continue; > +#ifdef INET > + /* XXX: Ugly!! ad hoc just for INET */ > + if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET) { > + struct ifaliasreq ifr; > + > + bzero(&ifr, sizeof(ifr)); > + ifr.ifra_addr = *ifa->ifa_addr; > + if (ifa->ifa_dstaddr) > + ifr.ifra_broadaddr = *ifa->ifa_dstaddr; > + if (in_control(NULL, SIOCDIFADDR, (caddr_t)&ifr, ifp, > + NULL) == 0) > + continue; > + } > +#endif /* INET */ > +#ifdef INET6 > + if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET6) { > + in6_purgeaddr(ifa); > + /* ifp_addrhead is already updated */ > + continue; > + } > +#endif /* INET6 */ > + TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link); > + IFAFREE(ifa); > + } > +} > + > +/* > * Detach an interface, removing it from the > * list of "active" interfaces. > */ > void > if_detach(struct ifnet *ifp) > { > - struct ifaddr *ifa, *next; > + struct ifaddr *ifa; > struct radix_node_head *rnh; > int s; > int i; > @@ -568,35 +607,7 @@ if_detach(struct ifnet *ifp) > altq_detach(&ifp->if_snd); > #endif > > - for (ifa = TAILQ_FIRST(&ifp->if_addrhead); ifa; ifa = next) { > - next = TAILQ_NEXT(ifa, ifa_link); > - > - if (ifa->ifa_addr->sa_family == AF_LINK) > - continue; > -#ifdef INET > - /* XXX: Ugly!! ad hoc just for INET */ > - if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET) { > - struct ifaliasreq ifr; > - > - bzero(&ifr, sizeof(ifr)); > - ifr.ifra_addr = *ifa->ifa_addr; > - if (ifa->ifa_dstaddr) > - ifr.ifra_broadaddr = *ifa->ifa_dstaddr; > - if (in_control(NULL, SIOCDIFADDR, (caddr_t)&ifr, ifp, > - NULL) == 0) > - continue; > - } > -#endif /* INET */ > -#ifdef INET6 > - if (ifa->ifa_addr && ifa->ifa_addr->sa_family == AF_INET6) { > - in6_purgeaddr(ifa); > - /* ifp_addrhead is already updated */ > - continue; > - } > -#endif /* INET6 */ > - TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link); > - IFAFREE(ifa); > - } > + if_purgeaddrs(ifp); > > #ifdef INET6 > /* > diff --git a/sys/net/if_tap.c b/sys/net/if_tap.c > index 232c96d..a807bd5 100644 > --- a/sys/net/if_tap.c > +++ b/sys/net/if_tap.c > @@ -31,7 +31,7 @@ > */ > > /* > - * $FreeBSD: src/sys/net/if_tap.c,v 1.53 2005/05/04 18:55:02 emax Exp $ > + * $FreeBSD: src/sys/net/if_tap.c,v 1.54 2005/05/25 13:52:03 peadar Exp $ > * $Id: if_tap.c,v 0.21 2000/07/23 21:46:02 max Exp $ > */ > > @@ -408,6 +408,7 @@ tapclose(dev, foo, bar, td) > int bar; > struct thread *td; > { > + struct ifaddr *ifa; > struct tap_softc *tp = dev->si_drv1; > struct ifnet *ifp = &tp->tap_if; > int s; > @@ -426,24 +427,10 @@ tapclose(dev, foo, bar, td) > s = splimp(); > if_down(ifp); > if (ifp->if_flags & IFF_RUNNING) { > - /* find internet addresses and delete routes */ > - struct ifaddr *ifa = NULL; > - > - /* In desparate need of ifaddr locking. */ > TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { > - if (ifa->ifa_addr->sa_family == AF_INET) { > - rtinit(ifa, (int)RTM_DELETE, 0); > - > - /* remove address from interface */ > - bzero(ifa->ifa_addr, > - sizeof(*(ifa->ifa_addr))); > - bzero(ifa->ifa_dstaddr, > - > sizeof(*(ifa->ifa_dstaddr))); > - bzero(ifa->ifa_netmask, > - > sizeof(*(ifa->ifa_netmask))); > - } > + rtinit(ifa, (int)RTM_DELETE, 0); > } > - > + if_purgeaddrs(ifp); > ifp->if_flags &= ~IFF_RUNNING; > } > splx(s); > diff --git a/sys/net/if_var.h b/sys/net/if_var.h > index ab8d389..6d9cbed 100644 > --- a/sys/net/if_var.h > +++ b/sys/net/if_var.h > @@ -27,7 +27,7 @@ > * SUCH DAMAGE. > * > * From: @(#)if.h 8.1 (Berkeley) 6/10/93 > - * $FreeBSD: src/sys/net/if_var.h,v 1.95 2005/04/20 09:30:54 glebius Exp $ > + * $FreeBSD: src/sys/net/if_var.h,v 1.96 2005/05/25 13:52:03 peadar Exp $ > */ > > #ifndef _NET_IF_VAR_H_ > @@ -629,6 +629,7 @@ int if_allmulti(struct ifnet *, int); > void if_attach(struct ifnet *); > int if_delmulti(struct ifnet *, struct sockaddr *); > void if_detach(struct ifnet *); > +void if_purgeaddrs(struct ifnet *); > void if_down(struct ifnet *); > void if_initname(struct ifnet *, const char *, int); > void if_link_state_change(struct ifnet *, int); > -- Live Free or Die
