Date: Thu, 7 Dec 2006 19:10:11 GMT From: Max Laier <max@love2party.net> To: freebsd-pf@FreeBSD.org Subject: Re: kern/106400: fatal trap 12 at restart of PF with ALTQ if ng0 device has detached Message-ID: <200612071910.kB7JAB84080285@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/106400; it has been noted by GNATS. From: Max Laier <max@love2party.net> To: bug-followup@freebsd.org, bst2006@dva.dyndns.org Cc: Subject: Re: kern/106400: fatal trap 12 at restart of PF with ALTQ if ng0 device has detached Date: Thu, 7 Dec 2006 20:00:25 +0100 --Boundary-00=_LTGeFqtfh+L0SPO Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline Okay, this is highly untested and certainly needs more work, but I don't have a crashbox set up right now, so if you could give it a try we might be getting somewhere quick. Please turn on misc debugging (pfctl -xm). This also might be a way to use ALTQ on not yet created interfaces, though this needs even more work. Report back if this changes anything. If you get a crash I'd like to see a dump and dmesg if possible. Thanks a lot. -- Max --Boundary-00=_LTGeFqtfh+L0SPO Content-Type: text/x-diff; charset="us-ascii"; name="altq_remove_if.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="altq_remove_if.diff" Index: pf_ioctl.c =================================================================== RCS file: /usr/store/mlaier/fcvs/src/sys/contrib/pf/net/pf_ioctl.c,v retrieving revision 1.20.2.4 diff -u -r1.20.2.4 pf_ioctl.c --- pf_ioctl.c 9 Sep 2006 00:50:25 -0000 1.20.2.4 +++ pf_ioctl.c 7 Dec 2006 18:54:24 -0000 @@ -211,6 +211,8 @@ static int pf_load(void); static int pf_unload(void); +void pf_detach_ifnet_event(void * __unused, struct ifnet *); + static struct cdevsw pf_cdevsw = { .d_ioctl = pfioctl, .d_name = PF_NAME, @@ -221,6 +223,8 @@ struct mtx pf_task_mtx; pflog_packet_t *pflog_packet_ptr = NULL; +eventhandler_tag pf_detach_cookie = NULL; + void init_pf_mutex(void) { @@ -351,9 +355,52 @@ /* XXX do our best to avoid a conflict */ pf_status.hostid = arc4random(); + pf_detach_cookie = EVENTHANDLER_REGISTER(ifnet_departure_event, + pf_detach_ifnet_event, NULL, EVENTHANDLER_PRI_ANY); return (error); } + +void +pf_detach_ifnet_event(void *arg __unused, struct ifnet *ifp) +{ +#ifdef ALTQ + struct pf_altq *altq; + int err, error = 0; + + PF_LOCK(); + TAILQ_FOREACH(altq, pf_altqs_active, entries) { + if (strncmp(ifp->if_xname, altq->ifname, IFNAMSIZ) != 0) + continue; + if (altq->qname[0] != 0) { +/* XXX: maybe later + altq->flags |= PFALTQ_FLAG_IF_REMOVED; + */ + continue; + } + KASSERT((altq->flags & PFALTQ_FLAG_IF_REMOVED) == 0, + ("flag already in use")); + /* detach and destroy the discipline */ + DPFPRINTF(PF_DEBUG_MISC, ("pf: remove altq %s.%s ...", + altq->ifname, altq->parent)); + if (pf_altq_running) + error = pf_disable_altq(altq); + DPFPRINTF(PF_DEBUG_MISC, ("%d ", error)); + err = altq_pfdetach(altq); + if (err != 0 && error == 0) + error = err; + DPFPRINTF(PF_DEBUG_MISC, ("%d ", error)); + err = altq_remove(altq); + if (err != 0 && error == 0) + error = err; + DPFPRINTF(PF_DEBUG_MISC, ("%d\n", error)); + altq->flags |= PFALTQ_FLAG_IF_REMOVED; + } + PF_UNLOCK(); +#endif +} + + #else /* !__FreeBSD__ */ void pfattach(int num) @@ -1042,7 +1089,8 @@ /* Purge the old altq list */ while ((altq = TAILQ_FIRST(pf_altqs_inactive)) != NULL) { TAILQ_REMOVE(pf_altqs_inactive, altq, entries); - if (altq->qname[0] == 0) { + if (altq->qname[0] == 0 && + (altq->flags & PFALTQ_FLAG_IF_REMOVED) == 0) { /* detach and destroy the discipline */ error = altq_remove(altq); } else @@ -1067,7 +1115,8 @@ /* Purge the old altq list */ while ((altq = TAILQ_FIRST(pf_altqs_inactive)) != NULL) { TAILQ_REMOVE(pf_altqs_inactive, altq, entries); - if (altq->qname[0] == 0) { + if (altq->qname[0] == 0 && + (altq->flags & PFALTQ_FLAG_IF_REMOVED) == 0) { /* detach and destroy the discipline */ error = altq_remove(altq); } else @@ -1112,7 +1161,8 @@ /* Purge the old altq list */ while ((altq = TAILQ_FIRST(pf_altqs_inactive)) != NULL) { TAILQ_REMOVE(pf_altqs_inactive, altq, entries); - if (altq->qname[0] == 0) { + if (altq->qname[0] == 0 && + (altq->flags & PFALTQ_FLAG_IF_REMOVED) == 0) { /* detach and destroy the discipline */ if (pf_altq_running) error = pf_disable_altq(altq); @@ -1139,6 +1189,9 @@ struct tb_profile tb; int s, error = 0; + if (altq->flags & PFALTQ_FLAG_IF_REMOVED) + return (0); + if ((ifp = ifunit(altq->ifname)) == NULL) return (EINVAL); @@ -1170,6 +1223,9 @@ struct tb_profile tb; int s, error; + if (altq->flags & PFALTQ_FLAG_IF_REMOVED) + return (0); + if ((ifp = ifunit(altq->ifname)) == NULL) return (EINVAL); @@ -3548,6 +3604,7 @@ PF_LOCK(); pf_status.running = 0; PF_UNLOCK(); + EVENTHANDLER_DEREGISTER(ifnet_departure_event, pf_detach_cookie); error = dehook_pf(); if (error) { /* Index: pfvar.h =================================================================== RCS file: /usr/store/mlaier/fcvs/src/sys/contrib/pf/net/pfvar.h,v retrieving revision 1.11.2.2 diff -u -r1.11.2.2 pfvar.h --- pfvar.h 30 Dec 2005 00:50:18 -0000 1.11.2.2 +++ pfvar.h 7 Dec 2006 18:33:46 -0000 @@ -1214,6 +1214,8 @@ u_int8_t priority; /* priority */ u_int16_t qlimit; /* queue size limit */ u_int16_t flags; /* misc flags */ +/* XXX: unused?!? */ +#define PFALTQ_FLAG_IF_REMOVED 0x8000 union { struct cbq_opts cbq_opts; struct priq_opts priq_opts; --Boundary-00=_LTGeFqtfh+L0SPO--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200612071910.kB7JAB84080285>