Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 22 Jan 2010 17:57:18 +0200
From:      Shteryana Shopova <syrinx@FreeBSD.org>
To:        bug-followup@FreeBSD.org, kvedulv@kvedulv.de
Cc:        freebsd-net@freebsd.org, syrinx@freebsd.org
Subject:   Re: kern/142391: [panic] bsnmpd(8) triggers kernel panic when a  second cloned WLAN interface was created before starting
Message-ID:  <61b573981001220757n1e0495c8t235617ebcf4012e8@mail.gmail.com>
In-Reply-To: <201001221551.o0MFpkTM012396@freefall.freebsd.org>

index | next in thread | previous in thread | raw e-mail

[-- Attachment #1 --]
Could you please try attached patch and confim it fixes the panic.

On Fri, Jan 22, 2010 at 5:51 PM,  <syrinx@freebsd.org> wrote:
> Synopsis: [panic] bsnmpd(8) triggers kernel panic when a second cloned WLAN interface was created before starting
>
> Responsible-Changed-From-To: freebsd-net->syrinx
> Responsible-Changed-By: syrinx
> Responsible-Changed-When: Fri Jan 22 15:50:57 UTC 2010
> Responsible-Changed-Why:
> Take over responsibility for this PR
>
> http://www.freebsd.org/cgi/query-pr.cgi?pr=142391
>

[-- Attachment #2 --]
Index: net/if.c
===================================================================
--- net/if.c	(revision 202292)
+++ net/if.c	(working copy)
@@ -742,7 +742,13 @@
 /*
  * Remove any multicast network addresses from an interface.
  */
-void
+/*
+ * syrinx@freebsd.org - 20100120 Do not export this API call for now
+ * as it NULLs the ifmultiaddr structures' reference to the parent interface.
+ * Any external subsystem that wants to purge the multicast addresses on
+ * an interface (net80211 only for now) should use if_delallmulti instead.
+ */
+static void
 if_purgemaddrs(struct ifnet *ifp)
 {
 	struct ifmultiaddr *ifma;
@@ -2939,6 +2945,22 @@
 }
 
 /*
+ * Delete all multicast group membership for an interface.
+ * Should be used to quickly flush all multicast filters.
+ */
+void
+if_delallmulti(struct ifnet *ifp)
+{
+	struct ifmultiaddr *ifma;
+	struct ifmultiaddr *next;
+
+	IF_ADDR_LOCK(ifp);
+	TAILQ_FOREACH_SAFE(ifma, &ifp->if_multiaddrs, ifma_link, next)
+		if_delmulti_locked(ifp, ifma, 0);
+	IF_ADDR_UNLOCK(ifp);
+}
+
+/*
  * Delete a multicast group membership by group membership pointer.
  * Network-layer protocol domains must use this routine.
  *
Index: net/if_var.h
===================================================================
--- net/if_var.h	(revision 202292)
+++ net/if_var.h	(working copy)
@@ -830,7 +830,8 @@
 void	if_detach(struct ifnet *);
 void	if_vmove(struct ifnet *, struct vnet *);
 void	if_purgeaddrs(struct ifnet *);
-void	if_purgemaddrs(struct ifnet *);
+/* void	if_purgemaddrs(struct ifnet *); */
+void	if_delallmulti(struct ifnet *ifp);
 void	if_down(struct ifnet *);
 struct ifmultiaddr *
 	if_findmulti(struct ifnet *, struct sockaddr *);
Index: net80211/ieee80211_ioctl.c
===================================================================
--- net80211/ieee80211_ioctl.c	(revision 202292)
+++ net80211/ieee80211_ioctl.c	(working copy)
@@ -3199,15 +3199,18 @@
 	void *ioctl;
 
 	IEEE80211_LOCK(ic);
-	if_purgemaddrs(parent);
+	if_delallmulti(parent);
 	ioctl = parent->if_ioctl;	/* XXX WAR if_allmulti */
 	parent->if_ioctl = NULL;
 	TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) {
 		struct ifnet *ifp = vap->iv_ifp;
 		struct ifmultiaddr *ifma;
 
-		TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link)
+		TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
+			if (ifma->ifma_addr->sa_family != AF_LINK)
+				continue;
 			(void) if_addmulti(parent, ifma->ifma_addr, NULL);
+		}
 	}
 	parent->if_ioctl = ioctl;
 	ieee80211_runtask(ic, &ic->ic_mcast_task);
home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?61b573981001220757n1e0495c8t235617ebcf4012e8>