Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 1 Jul 2015 21:21:15 +0000 (UTC)
From:      Kristof Provost <kp@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r285016 - in stable/10/sys: dev/virtio/network net
Message-ID:  <201507012121.t61LLFjM069238@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kp
Date: Wed Jul  1 21:21:14 2015
New Revision: 285016
URL: https://svnweb.freebsd.org/changeset/base/285016

Log:
  MFC r284348: Fix panic when adding vtnet interfaces to a bridge
  
  vtnet interfaces are always in promiscuous mode (at least if the
  VIRTIO_NET_F_CTRL_RX feature is not negotiated with the host).  if_promisc() on
  a vtnet interface returned ENOTSUP although it has IFF_PROMISC set. This
  confused the bridge code. Instead we now accept all enable/disable promiscuous
  commands (and always keep IFF_PROMISC set).
  
  There are also two issues with the if_bridge error handling.
  
  If if_promisc() fails it uses bridge_delete_member() to clean up. This tries to
  disable promiscuous mode on the interface. That runs into an assert, because
  promiscuous mode was never set in the first place. (That's the panic reported in
  PR 200210.)
  We can only unset promiscuous mode if the interface actually is promiscuous.
  This goes against the reference counting done by if_promisc(), but only the
  first/last if_promic() calls can actually fail, so this is safe.
  
  A second issue is a double free of bif. It's already freed by
  bridge_delete_member().
  
  PR:         200210

Modified:
  stable/10/sys/dev/virtio/network/if_vtnet.c
  stable/10/sys/net/if_bridge.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/virtio/network/if_vtnet.c
==============================================================================
--- stable/10/sys/dev/virtio/network/if_vtnet.c	Wed Jul  1 19:46:57 2015	(r285015)
+++ stable/10/sys/dev/virtio/network/if_vtnet.c	Wed Jul  1 21:21:14 2015	(r285016)
@@ -1078,8 +1078,12 @@ vtnet_ioctl(struct ifnet *ifp, u_long cm
 			    (IFF_PROMISC | IFF_ALLMULTI)) {
 				if (sc->vtnet_flags & VTNET_FLAG_CTRL_RX)
 					vtnet_rx_filter(sc);
-				else
-					error = ENOTSUP;
+				else {
+					ifp->if_flags |= IFF_PROMISC;
+					if ((ifp->if_flags ^ sc->vtnet_if_flags)
+					    & IFF_ALLMULTI)
+						error = ENOTSUP;
+				}
 			}
 		} else
 			vtnet_init_locked(sc);

Modified: stable/10/sys/net/if_bridge.c
==============================================================================
--- stable/10/sys/net/if_bridge.c	Wed Jul  1 19:46:57 2015	(r285015)
+++ stable/10/sys/net/if_bridge.c	Wed Jul  1 21:21:14 2015	(r285016)
@@ -984,9 +984,12 @@ bridge_delete_member(struct bridge_softc
 		case IFT_ETHER:
 		case IFT_L2VLAN:
 			/*
-			 * Take the interface out of promiscuous mode.
+			 * Take the interface out of promiscuous mode, but only
+			 * if it was promiscuous in the first place. It might
+			 * not be if we're in the bridge_ioctl_add() error path.
 			 */
-			(void) ifpromisc(ifs, 0);
+			if (ifs->if_flags & IFF_PROMISC)
+				(void) ifpromisc(ifs, 0);
 			break;
 
 		case IFT_GIF:
@@ -1154,10 +1157,8 @@ bridge_ioctl_add(struct bridge_softc *sc
 			break;
 	}
 
-	if (error) {
+	if (error)
 		bridge_delete_member(sc, bif, 0);
-		free(bif, M_DEVBUF);
-	}
 	return (error);
 }
 



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