Skip site navigation (1)Skip section navigation (2)
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>