Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 20 Jan 2015 23:05:01 +0000 (UTC)
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r277456 - in projects/ifnet/sys: dev/bge dev/msk dev/virtio/network dev/xl net
Message-ID:  <201501202305.t0KN51NG091685@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: glebius
Date: Tue Jan 20 23:05:00 2015
New Revision: 277456
URL: https://svnweb.freebsd.org/changeset/base/277456

Log:
  New KPI for if_flags management: stack sends SICSIFFLAGS to a driver,
  and if driver approves, then stack updates flags. Drivers usually cache
  if_flags in their softc. If a driver needs to change its flags, it needs
  to run if_drvioctl().
  
  Sponsored by:	Netflix
  Sponsored by:	Nginx, Inc.

Modified:
  projects/ifnet/sys/dev/bge/if_bge.c
  projects/ifnet/sys/dev/bge/if_bgereg.h
  projects/ifnet/sys/dev/msk/if_msk.c
  projects/ifnet/sys/dev/virtio/network/if_vtnet.c
  projects/ifnet/sys/dev/xl/if_xl.c
  projects/ifnet/sys/net/if.c
  projects/ifnet/sys/net/if.h
  projects/ifnet/sys/net/if_loop.c

Modified: projects/ifnet/sys/dev/bge/if_bge.c
==============================================================================
--- projects/ifnet/sys/dev/bge/if_bge.c	Tue Jan 20 23:00:17 2015	(r277455)
+++ projects/ifnet/sys/dev/bge/if_bge.c	Tue Jan 20 23:05:00 2015	(r277456)
@@ -1634,14 +1634,11 @@ bge_init_tx_ring(struct bge_softc *sc)
 static void
 bge_setpromisc(struct bge_softc *sc)
 {
-	if_t ifp;
 
 	BGE_LOCK_ASSERT(sc);
 
-	ifp = sc->bge_ifp;
-
 	/* Enable or disable promiscuous mode as needed. */
-	if (if_get(ifp, IF_FLAGS) & IFF_PROMISC)
+	if (sc->bge_if_flags & IFF_PROMISC)
 		BGE_SETBIT(sc, BGE_RX_MODE, BGE_RXMODE_RX_PROMISC);
 	else
 		BGE_CLRBIT(sc, BGE_RX_MODE, BGE_RXMODE_RX_PROMISC);
@@ -1664,15 +1661,12 @@ bge_hash_maddr(void *arg, struct sockadd
 static void
 bge_setmulti(struct bge_softc *sc)
 {
-	if_t ifp;
 	uint32_t hashes[4] = { 0, 0, 0, 0 };
 	int i;
 
 	BGE_LOCK_ASSERT(sc);
 
-	ifp = sc->bge_ifp;
-
-	if (if_get(ifp, IF_FLAGS) & (IFF_ALLMULTI | IFF_PROMISC)) {
+	if (sc->bge_if_flags & (IFF_ALLMULTI | IFF_PROMISC)) {
 		for (i = 0; i < 4; i++)
 			CSR_WRITE_4(sc, BGE_MAR0 + (i * 4), 0xFFFFFFFF);
 		return;
@@ -1682,7 +1676,7 @@ bge_setmulti(struct bge_softc *sc)
 	for (i = 0; i < 4; i++)
 		CSR_WRITE_4(sc, BGE_MAR0 + (i * 4), 0);
 
-	if_foreach_maddr(ifp, bge_hash_maddr, hashes);
+	if_foreach_maddr(sc->bge_ifp, bge_hash_maddr, hashes);
 
 	for (i = 0; i < 4; i++)
 		CSR_WRITE_4(sc, BGE_MAR0 + (i * 4), hashes[i]);
@@ -5703,7 +5697,7 @@ bge_ifmedia_sts(if_t ifp, struct ifmedia
 
 	BGE_LOCK(sc);
 
-	if ((if_get(ifp, IF_FLAGS) & IFF_UP) == 0) {
+	if ((sc->bge_if_flags & IFF_UP) == 0) {
 		BGE_UNLOCK(sc);
 		return;
 	}
@@ -5741,7 +5735,7 @@ bge_ioctl(if_t ifp, u_long command, void
 	struct bge_softc *sc = if_getsoftc(ifp, IF_DRIVER_SOFTC);
 	struct ifreq *ifr = (struct ifreq *) data;
 	struct mii_data *mii;
-	int flags, mask, error = 0;
+	int oflags, mask, error = 0;
 
 	switch (command) {
 	case SIOCSIFMTU:
@@ -5766,7 +5760,9 @@ bge_ioctl(if_t ifp, u_long command, void
 		break;
 	case SIOCSIFFLAGS:
 		BGE_LOCK(sc);
-		if (if_get(ifp, IF_FLAGS) & IFF_UP) {
+		oflags = sc->bge_if_flags;
+		sc->bge_if_flags = ifr->ifr_flags;
+		if (sc->bge_if_flags & IFF_UP) {
 			/*
 			 * If only the state of the PROMISC flag changed,
 			 * then just use the 'set promisc mode' command
@@ -5776,22 +5772,15 @@ bge_ioctl(if_t ifp, u_long command, void
 			 * second or two.  Similarly for ALLMULTI.
 			 */
 			if (sc->bge_flags & BGE_FLAG_RUNNING) {
-				flags = if_get(ifp, IF_FLAGS) ^
-				    sc->bge_if_flags;
-				if (flags & IFF_PROMISC)
+				if ((oflags ^ sc->bge_if_flags) & IFF_PROMISC)
 					bge_setpromisc(sc);
-				if (flags & IFF_ALLMULTI)
+				if ((oflags ^ sc->bge_if_flags) & IFF_ALLMULTI)
 					bge_setmulti(sc);
 			} else
 				bge_init_locked(sc);
-		} else {
-			if (sc->bge_flags & BGE_FLAG_RUNNING) {
-				bge_stop(sc);
-			}
-		}
-		sc->bge_if_flags = if_get(ifp, IF_FLAGS);
+		} else if (sc->bge_flags & BGE_FLAG_RUNNING)
+			bge_stop(sc);
 		BGE_UNLOCK(sc);
-		error = 0;
 		break;
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:
@@ -6050,12 +6039,10 @@ static int
 bge_resume(device_t dev)
 {
 	struct bge_softc *sc;
-	if_t ifp;
 
 	sc = device_get_softc(dev);
 	BGE_LOCK(sc);
-	ifp = sc->bge_ifp;
-	if (if_get(ifp, IF_FLAGS) & IFF_UP) {
+	if (sc->bge_if_flags & IFF_UP) {
 		bge_init_locked(sc);
 		if (sc->bge_flags & BGE_FLAG_RUNNING)
 			bge_start_locked(sc);

Modified: projects/ifnet/sys/dev/bge/if_bgereg.h
==============================================================================
--- projects/ifnet/sys/dev/bge/if_bgereg.h	Tue Jan 20 23:00:17 2015	(r277455)
+++ projects/ifnet/sys/dev/bge/if_bgereg.h	Tue Jan 20 23:05:00 2015	(r277456)
@@ -3035,7 +3035,7 @@ struct bge_softc {
 	uint32_t		bge_rx_max_coal_bds;
 	uint32_t		bge_tx_max_coal_bds;
 	uint32_t		bge_mi_mode;
-	int			bge_if_flags;
+	uint32_t		bge_if_flags;
 	int			bge_txcnt;
 	int			bge_link;	/* link state */
 	int			bge_link_evt;	/* pending link event */

Modified: projects/ifnet/sys/dev/msk/if_msk.c
==============================================================================
--- projects/ifnet/sys/dev/msk/if_msk.c	Tue Jan 20 23:00:17 2015	(r277455)
+++ projects/ifnet/sys/dev/msk/if_msk.c	Tue Jan 20 23:05:00 2015	(r277456)
@@ -607,7 +607,7 @@ msk_rxfilter(struct msk_if_softc *sc_if)
 {
 	struct msk_softc *sc;
 	if_t ifp;
-	uint32_t mchash[2], flags;
+	uint32_t mchash[2];
 	uint16_t mode;
 
 	sc = sc_if->msk_softc;
@@ -618,10 +618,9 @@ msk_rxfilter(struct msk_if_softc *sc_if)
 
 	bzero(mchash, sizeof(mchash));
 	mode = GMAC_READ_2(sc, sc_if->msk_port, GM_RX_CTRL);
-	flags = if_get(ifp, IF_FLAGS);
-	if ((flags & IFF_PROMISC) != 0)
+	if ((sc_if->msk_if_flags & IFF_PROMISC) != 0)
 		mode &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
-	else if ((flags & IFF_ALLMULTI) != 0) {
+	else if ((sc_if->msk_if_flags & IFF_ALLMULTI) != 0) {
 		mode |= GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA;
 		mchash[0] = 0xffff;
 		mchash[1] = 0xffff;
@@ -1055,11 +1054,12 @@ msk_mediastatus(if_t ifp, struct ifmedia
 	struct msk_if_softc *sc_if;
 	struct mii_data	*mii;
 
-	if ((if_get(ifp, IF_FLAGS) & IFF_UP) == 0)
-		return;
 	sc_if = if_getsoftc(ifp, IF_DRIVER_SOFTC);
 	MSK_IF_LOCK(sc_if);
-	sc_if = if_getsoftc(ifp, IF_DRIVER_SOFTC);
+	if ((sc_if->msk_if_flags & IFF_UP) == 0) {
+		MSK_IF_UNLOCK(sc_if);
+		return;
+	}
 	mii = device_get_softc(sc_if->msk_miibus);
 	mii_pollstat(mii);
 	ifmr->ifm_active = mii->mii_media_active;
@@ -1074,7 +1074,7 @@ msk_ioctl(if_t ifp, u_long command, void
 	struct ifreq *ifr;
 	struct mii_data	*mii;
 	int error, reinit, setvlan;
-	uint32_t flags, mask;
+	uint32_t oflags, mask;
 
 	sc_if = if_getsoftc(ifp, IF_DRIVER_SOFTC);
 	ifr = (struct ifreq *)data;
@@ -1114,17 +1114,17 @@ msk_ioctl(if_t ifp, u_long command, void
 		break;
 	case SIOCSIFFLAGS:
 		MSK_IF_LOCK(sc_if);
-		flags = if_get(ifp, IF_FLAGS);
-		if ((flags & IFF_UP) != 0) {
+		oflags = sc_if->msk_if_flags;
+		sc_if->msk_if_flags = ifr->ifr_flags;
+		if ((sc_if->msk_if_flags & IFF_UP) != 0) {
 			if ((sc_if->msk_flags & MSK_FLAG_RUNNING) != 0 &&
-			    ((flags ^ sc_if->msk_if_flags) &
+			    ((oflags ^ sc_if->msk_if_flags) &
 			    (IFF_PROMISC | IFF_ALLMULTI)) != 0)
 				msk_rxfilter(sc_if);
 			else if ((sc_if->msk_flags & MSK_FLAG_DETACH) == 0)
 				msk_init_locked(sc_if);
 		} else if ((sc_if->msk_flags & MSK_FLAG_RUNNING) != 0)
 			msk_stop(sc_if);
-		sc_if->msk_if_flags = flags;
 		MSK_IF_UNLOCK(sc_if);
 		break;
 	case SIOCADDMULTI:
@@ -3035,7 +3035,7 @@ mskc_resume(device_t dev)
 	mskc_reset(sc);
 	for (i = 0; i < sc->msk_num_port; i++) {
 		if (sc->msk_if[i] != NULL && sc->msk_if[i]->msk_ifp != NULL &&
-		    (if_get(sc->msk_if[i]->msk_ifp, IF_FLAGS) & IFF_UP)) {
+		    (sc->msk_if[i]->msk_if_flags & IFF_UP)) {
 			sc->msk_if[i]->msk_flags &= ~MSK_FLAG_RUNNING;
 			msk_init_locked(sc->msk_if[i]);
 		}

Modified: projects/ifnet/sys/dev/virtio/network/if_vtnet.c
==============================================================================
--- projects/ifnet/sys/dev/virtio/network/if_vtnet.c	Tue Jan 20 23:00:17 2015	(r277455)
+++ projects/ifnet/sys/dev/virtio/network/if_vtnet.c	Tue Jan 20 23:05:00 2015	(r277456)
@@ -475,13 +475,11 @@ static int
 vtnet_resume(device_t dev)
 {
 	struct vtnet_softc *sc;
-	if_t ifp;
 
 	sc = device_get_softc(dev);
-	ifp = sc->vtnet_ifp;
 
 	VTNET_CORE_LOCK(sc);
-	if (if_get(ifp, IF_FLAGS) & IFF_UP)
+	if (sc->vtnet_if_flags & IFF_UP)
 		vtnet_init_locked(sc);
 	sc->vtnet_flags &= ~VTNET_FLAG_SUSPENDED;
 	VTNET_CORE_UNLOCK(sc);
@@ -1016,7 +1014,7 @@ vtnet_ioctl(if_t ifp, u_long cmd, void *
 {
 	struct vtnet_softc *sc;
 	struct ifreq *ifr;
-	int error;
+	int oflags, error;
 
 	sc = if_getsoftc(ifp, IF_DRIVER_SOFTC);
 	ifr = (struct ifreq *) data;
@@ -1030,23 +1028,23 @@ vtnet_ioctl(if_t ifp, u_long cmd, void *
 		break;
 
 	case SIOCSIFFLAGS:
+		if ((ifr->ifr_flags & (IFF_PROMISC | IFF_ALLMULTI)) &&
+		    (sc->vtnet_flags & VTNET_FLAG_CTRL_RX) == 0) {
+			error = EINVAL;
+			break;
+		}
 		VTNET_CORE_LOCK(sc);
-		if ((if_get(ifp, IF_FLAGS) & IFF_UP) == 0) {
+		oflags = sc->vtnet_if_flags;
+		sc->vtnet_if_flags = ifr->ifr_flags;
+		if ((sc->vtnet_if_flags & IFF_UP) == 0) {
 			if (sc->vtnet_flags & VTNET_FLAG_RUNNING)
 				vtnet_stop(sc);
 		} else if (sc->vtnet_flags & VTNET_FLAG_RUNNING) {
-			if ((if_get(ifp, IF_FLAGS) ^ sc->vtnet_if_flags) &
-			    (IFF_PROMISC | IFF_ALLMULTI)) {
-				if (sc->vtnet_flags & VTNET_FLAG_CTRL_RX)
-					vtnet_rx_filter(sc);
-				else
-					error = ENOTSUP;
-			}
+			if ((oflags ^ sc->vtnet_if_flags) &
+			    (IFF_PROMISC | IFF_ALLMULTI))
+				vtnet_rx_filter(sc);
 		} else
 			vtnet_init_locked(sc);
-
-		if (error == 0)
-			sc->vtnet_if_flags = if_get(ifp, IF_FLAGS);
 		VTNET_CORE_UNLOCK(sc);
 		break;
 
@@ -3066,15 +3064,20 @@ vtnet_set_allmulti(struct vtnet_softc *s
 static void
 vtnet_attach_disable_promisc(struct vtnet_softc *sc)
 {
+	struct ifreq ifr;
 	if_t ifp;
 
 	ifp = sc->vtnet_ifp;
 
 	VTNET_CORE_LOCK(sc);
 	if ((sc->vtnet_flags & VTNET_FLAG_CTRL_RX) == 0) {
-		if_addflags(ifp, IF_FLAGS, IFF_PROMISC);
+		(void )if_drvioctl(SIOCGIFFLAGS, ifp, &ifr, curthread);
+		ifr.ifr_flagslow |= IFF_PROMISC;
+		(void )if_drvioctl(SIOCSIFFLAGS, ifp, &ifr, curthread);
 	} else if (vtnet_set_promisc(sc, 0) != 0) {
-		if_addflags(ifp, IF_FLAGS, IFF_PROMISC);
+		(void )if_drvioctl(SIOCGIFFLAGS, ifp, &ifr, curthread);
+		ifr.ifr_flagslow |= IFF_PROMISC;
+		(void )if_drvioctl(SIOCSIFFLAGS, ifp, &ifr, curthread);
 		device_printf(sc->vtnet_dev,
 		    "cannot disable default promiscuous mode\n");
 	}
@@ -3092,16 +3095,14 @@ vtnet_rx_filter(struct vtnet_softc *sc)
 
 	VTNET_CORE_LOCK_ASSERT(sc);
 
-	if (vtnet_set_promisc(sc,
-	    if_get(ifp, IF_FLAGS) & IFF_PROMISC) != 0)
+	if (vtnet_set_promisc(sc, sc->vtnet_if_flags & IFF_PROMISC) != 0)
 		device_printf(dev, "cannot %s promiscuous mode\n",
-		    if_get(ifp, IF_FLAGS) & IFF_PROMISC ?
+		    sc->vtnet_if_flags & IFF_PROMISC ?
 		    "enable" : "disable");
 
-	if (vtnet_set_allmulti(sc,
-	    if_get(ifp, IF_FLAGS) & IFF_ALLMULTI) != 0)
+	if (vtnet_set_allmulti(sc, sc->vtnet_if_flags & IFF_ALLMULTI) != 0)
 		device_printf(dev, "cannot %s all-multicast mode\n",
-		    if_get(ifp, IF_FLAGS) & IFF_ALLMULTI ?
+		    sc->vtnet_if_flags & IFF_ALLMULTI ?
 		    "enable" : "disable");
 }
 

Modified: projects/ifnet/sys/dev/xl/if_xl.c
==============================================================================
--- projects/ifnet/sys/dev/xl/if_xl.c	Tue Jan 20 23:00:17 2015	(r277455)
+++ projects/ifnet/sys/dev/xl/if_xl.c	Tue Jan 20 23:05:00 2015	(r277456)
@@ -630,15 +630,10 @@ xl_check_maddr_90x(void *arg, struct soc
 static void
 xl_rxfilter_90x(struct xl_softc *sc)
 {
-	if_t ifp;
-	uint32_t flags;
 	uint8_t rxfilt;
 
 	XL_LOCK_ASSERT(sc);
 
-	ifp = sc->xl_ifp;
-	flags = if_get(ifp, IF_FLAGS);
-
 	XL_SEL_WIN(5);
 	rxfilt = CSR_READ_1(sc, XL_W5_RX_FILTER);
 	rxfilt &= ~(XL_RXFILTER_ALLFRAMES | XL_RXFILTER_ALLMULTI |
@@ -647,17 +642,16 @@ xl_rxfilter_90x(struct xl_softc *sc)
 	/* Set the individual bit to receive frames for this host only. */
 	rxfilt |= XL_RXFILTER_INDIVIDUAL;
 	/* Set capture broadcast bit to capture broadcast frames. */
-	if (flags & IFF_BROADCAST)
-		rxfilt |= XL_RXFILTER_BROADCAST;
+	rxfilt |= XL_RXFILTER_BROADCAST;
 
 	/* If we want promiscuous mode, set the allframes bit. */
-	if (flags & (IFF_PROMISC | IFF_ALLMULTI)) {
-		if (flags & IFF_PROMISC)
+	if (sc->xl_if_flags & (IFF_PROMISC | IFF_ALLMULTI)) {
+		if (sc->xl_if_flags & IFF_PROMISC)
 			rxfilt |= XL_RXFILTER_ALLFRAMES;
-		if (flags & IFF_ALLMULTI)
+		if (sc->xl_if_flags & IFF_ALLMULTI)
 			rxfilt |= XL_RXFILTER_ALLMULTI;
 	} else
-		if_foreach_maddr(ifp, xl_check_maddr_90x, &rxfilt);
+		if_foreach_maddr(sc->xl_ifp, xl_check_maddr_90x, &rxfilt);
 
 	CSR_WRITE_2(sc, XL_COMMAND, rxfilt | XL_CMD_RX_SET_FILT);
 	XL_SEL_WIN(7);
@@ -689,15 +683,10 @@ xl_check_maddr_90xB(void *arg, struct so
 static void
 xl_rxfilter_90xB(struct xl_softc *sc)
 {
-	if_t ifp;
-	uint32_t flags;
 	uint8_t rxfilt;
 
 	XL_LOCK_ASSERT(sc);
 
-	ifp = sc->xl_ifp;
-	flags = if_get(ifp, IF_FLAGS);
-
 	XL_SEL_WIN(5);
 	rxfilt = CSR_READ_1(sc, XL_W5_RX_FILTER);
 	rxfilt &= ~(XL_RXFILTER_ALLFRAMES | XL_RXFILTER_ALLMULTI |
@@ -707,14 +696,13 @@ xl_rxfilter_90xB(struct xl_softc *sc)
 	/* Set the individual bit to receive frames for this host only. */
 	rxfilt |= XL_RXFILTER_INDIVIDUAL;
 	/* Set capture broadcast bit to capture broadcast frames. */
-	if (flags & IFF_BROADCAST)
-		rxfilt |= XL_RXFILTER_BROADCAST;
+	rxfilt |= XL_RXFILTER_BROADCAST;
 
 	/* If we want promiscuous mode, set the allframes bit. */
-	if (flags & (IFF_PROMISC | IFF_ALLMULTI)) {
-		if (flags & IFF_PROMISC)
+	if (sc->xl_if_flags & (IFF_PROMISC | IFF_ALLMULTI)) {
+		if (sc->xl_if_flags & IFF_PROMISC)
 			rxfilt |= XL_RXFILTER_ALLFRAMES;
-		if (flags & IFF_ALLMULTI)
+		if (sc->xl_if_flags & IFF_ALLMULTI)
 			rxfilt |= XL_RXFILTER_ALLMULTI;
 	} else {
 		/* First, zot all the existing hash bits. */
@@ -722,12 +710,12 @@ xl_rxfilter_90xB(struct xl_softc *sc)
 			CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_HASH | i);
 
 		/* Now program new ones. */
-		if_foreach_maddr(ifp, xl_check_maddr_90xB, sc);
+		if_foreach_maddr(sc->xl_ifp, xl_check_maddr_90xB, sc);
 		/*
 		 * XXXGL: a bit dirty, but easier then make a context
 		 * containing softc and rxfilt.
 		 */
-		if_foreach_maddr(ifp, xl_check_maddr_90x, &rxfilt);
+		if_foreach_maddr(sc->xl_ifp, xl_check_maddr_90x, &rxfilt);
 	}
 
 	CSR_WRITE_2(sc, XL_COMMAND, rxfilt | XL_CMD_RX_SET_FILT);
@@ -2973,7 +2961,7 @@ xl_ioctl(if_t ifp, u_long command, void 
 {
 	struct xl_softc		*sc;
 	struct ifreq		*ifr = (struct ifreq *) data;
-	uint32_t		flags;
+	uint32_t		oflags;
 	int			error = 0;
 	struct mii_data		*mii = NULL;
 
@@ -2982,19 +2970,17 @@ xl_ioctl(if_t ifp, u_long command, void 
 	switch (command) {
 	case SIOCSIFFLAGS:
 		XL_LOCK(sc);
-		flags = if_get(ifp, IF_FLAGS);
-		if (flags & IFF_UP) {
+		oflags = sc->xl_if_flags;
+		sc->xl_if_flags = ifr->ifr_flags;
+		if (sc->xl_if_flags & IFF_UP) {
 			if (sc->xl_flags & XL_FLAG_RUNNING &&
-			    (flags ^ sc->xl_if_flags) &
+			    (oflags ^ sc->xl_if_flags) &
 			    (IFF_PROMISC | IFF_ALLMULTI))
 				xl_rxfilter(sc);
 			else
 				xl_init_locked(sc);
-		} else {
-			if (sc->xl_flags & XL_FLAG_RUNNING)
-				xl_stop(sc);
-		}
-		sc->xl_if_flags = flags;
+		} else if (sc->xl_flags & XL_FLAG_RUNNING)
+			xl_stop(sc);
 		XL_UNLOCK(sc);
 		break;
 	case SIOCADDMULTI:
@@ -3205,18 +3191,13 @@ static int
 xl_resume(device_t dev)
 {
 	struct xl_softc		*sc;
-	if_t			ifp;
 
 	sc = device_get_softc(dev);
-	ifp = sc->xl_ifp;
-
 	XL_LOCK(sc);
-
-	if (if_get(ifp, IF_FLAGS) & IFF_UP) {
+	if (sc->xl_if_flags & IFF_UP) {
 		sc->xl_flags &= ~XL_FLAG_RUNNING;
 		xl_init_locked(sc);
 	}
-
 	XL_UNLOCK(sc);
 
 	return (0);

Modified: projects/ifnet/sys/net/if.c
==============================================================================
--- projects/ifnet/sys/net/if.c	Tue Jan 20 23:00:17 2015	(r277455)
+++ projects/ifnet/sys/net/if.c	Tue Jan 20 23:05:00 2015	(r277456)
@@ -1528,9 +1528,6 @@ if_getfeature(if_t ifp, ift_feature f, u
 		*ptr = NULL;
 
 	switch (f) {
-	case IF_FLAGS:
-		*f32 = &ifp->if_flags;
-		break;
 	case IF_BAUDRATE:
 		*f64 = &ifp->if_baudrate;
 		break;
@@ -2367,14 +2364,14 @@ int
 if_drvioctl(u_long cmd, struct ifnet *ifp, void *data, struct thread *td)
 {
 	struct ifreq *ifr;
-	int error = 0;
-	int new_flags, temp_flags;
 	size_t namelen, onamelen;
 	size_t descrlen;
 	char *descrbuf, *odescrbuf;
 	char new_name[IFNAMSIZ];
 	struct ifaddr *ifa;
 	struct sockaddr_dl *sdl;
+	uint32_t flags;
+	int error = 0;
 
 	ifr = (struct ifreq *)data;
 	switch (cmd) {
@@ -2383,9 +2380,8 @@ if_drvioctl(u_long cmd, struct ifnet *if
 		break;
 
 	case SIOCGIFFLAGS:
-		temp_flags = ifp->if_flags;
-		ifr->ifr_flags = temp_flags & 0xffff;
-		ifr->ifr_flagshigh = temp_flags >> 16;
+		ifr->ifr_flagslow = ifp->if_flags & 0xffff;
+		ifr->ifr_flagshigh = ifp->if_flags >> 16;
 		break;
 
 	case SIOCGIFCAP:
@@ -2484,31 +2480,41 @@ if_drvioctl(u_long cmd, struct ifnet *if
 		if (error)
 			return (error);
 		/*
-		 * Currently, no driver owned flags pass the IFF_CANTCHANGE
-		 * check, so we don't need special handling here yet.
+		 * Historically if_flags were 16-bit, and thus
+		 * they come from userland in two parts, that
+		 * we need to swap.
 		 */
-		new_flags = (ifr->ifr_flags & 0xffff) |
+		flags = (ifr->ifr_flagslow & 0xffff) |
 		    (ifr->ifr_flagshigh << 16);
-		if (ifp->if_flags & IFF_UP &&
-		    (new_flags & IFF_UP) == 0) {
+		if ((flags & IFF_CANTCHANGE) !=
+		    (ifp->if_flags & IFF_CANTCHANGE))
+			return (EINVAL);
+		/*
+		 * Pass new flags down to driver and see if it accepts them.
+		 */
+		ifr->ifr_flags = flags;
+		error = if_ioctl(ifp, cmd, data, td);
+		if (error)
+			return (error);
+		flags = ifr->ifr_flags;
+		/*
+		 * Manage IFF_UP flip.
+		 */
+		if (ifp->if_flags & IFF_UP && (flags & IFF_UP) == 0)
 			if_down(ifp);
-		} else if (new_flags & IFF_UP &&
-		    (ifp->if_flags & IFF_UP) == 0) {
+		else if (flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0)
 			if_up(ifp);
-		}
 		/* See if permanently promiscuous mode bit is about to flip */
-		if ((ifp->if_flags ^ new_flags) & IFF_PPROMISC) {
-			if (new_flags & IFF_PPROMISC)
+		if ((ifp->if_flags ^ flags) & IFF_PPROMISC) {
+			if (flags & IFF_PPROMISC)
 				ifp->if_flags |= IFF_PROMISC;
 			else if (ifp->if_pcount == 0)
 				ifp->if_flags &= ~IFF_PROMISC;
 			log(LOG_INFO, "%s: permanently promiscuous mode %s\n",
 			    ifp->if_xname,
-			    (new_flags & IFF_PPROMISC) ? "enabled" : "disabled");
+			    (flags & IFF_PPROMISC) ? "enabled" : "disabled");
 		}
-		ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |
-			(new_flags &~ IFF_CANTCHANGE);
-		if_ioctl(ifp, cmd, data, td);
+		ifp->if_flags = flags;
 		getmicrotime(&ifp->if_lastchange);
 		break;
 

Modified: projects/ifnet/sys/net/if.h
==============================================================================
--- projects/ifnet/sys/net/if.h	Tue Jan 20 23:00:17 2015	(r277455)
+++ projects/ifnet/sys/net/if.h	Tue Jan 20 23:05:00 2015	(r277456)
@@ -382,7 +382,8 @@ struct	ifreq {
 			uint32_t ifrucap_curcap;	/* current values */
 			uint64_t ifrucap_hwassist;	/* returned hwassist */
 		}	ifru_cap;
-		short	ifru_flags[2];
+		u_int	ifru_flags;
+		short	ifru_sflags[2];
 		short	ifru_index;
 		int	ifru_jid;
 		int	ifru_metric;
@@ -396,8 +397,9 @@ struct	ifreq {
 #define	ifr_dstaddr	ifr_ifru.ifru_dstaddr	/* other end of p-to-p link */
 #define	ifr_broadaddr	ifr_ifru.ifru_broadaddr	/* broadcast address */
 #define	ifr_buffer	ifr_ifru.ifru_buffer	/* user supplied buffer with its length */
-#define	ifr_flags	ifr_ifru.ifru_flags[0]	/* flags (low 16 bits) */
-#define	ifr_flagshigh	ifr_ifru.ifru_flags[1]	/* flags (high 16 bits) */
+#define	ifr_flags	ifr_ifru.ifru_flags	/* flags (after fixup) */
+#define	ifr_flagslow	ifr_ifru.ifru_sflags[0]	/* flags (low 16 bits) */
+#define	ifr_flagshigh	ifr_ifru.ifru_sflags[1]	/* flags (high 16 bits) */
 #define	ifr_jid		ifr_ifru.ifru_jid	/* jail/vnet */
 #define	ifr_metric	ifr_ifru.ifru_metric	/* metric */
 #define	ifr_mtu		ifr_ifru.ifru_mtu	/* mtu */
@@ -573,8 +575,6 @@ typedef enum {
 } ift_counter;
 
 typedef enum {
-	/* uint32_t */
-	IF_FLAGS,
 	/* uint64_t */
 	IF_BAUDRATE,
 	/* pointers */

Modified: projects/ifnet/sys/net/if_loop.c
==============================================================================
--- projects/ifnet/sys/net/if_loop.c	Tue Jan 20 23:00:17 2015	(r277455)
+++ projects/ifnet/sys/net/if_loop.c	Tue Jan 20 23:05:00 2015	(r277456)
@@ -346,22 +346,12 @@ int
 loioctl(if_t ifp, u_long cmd, void  *data, struct thread *td)
 {
 	struct ifreq *ifr = (struct ifreq *)data;
-	int error = 0;
 
 	switch (cmd) {
-	case SIOCSIFADDR:
-		if_addflags(ifp, IF_FLAGS, IFF_UP);
-		/*
-		 * Everything else is done at a higher level.
-		 */
-		break;
-
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:
-		if (ifr == 0) {
-			error = EAFNOSUPPORT;		/* XXX */
-			break;
-		}
+		if (ifr == NULL)
+			return (EAFNOSUPPORT);		/* XXX */
 		switch (ifr->ifr_addr.sa_family) {
 
 #ifdef INET
@@ -374,8 +364,7 @@ loioctl(if_t ifp, u_long cmd, void  *dat
 #endif
 
 		default:
-			error = EAFNOSUPPORT;
-			break;
+			return (EAFNOSUPPORT);
 		}
 		break;
 
@@ -384,7 +373,7 @@ loioctl(if_t ifp, u_long cmd, void  *dat
 		break;
 
 	default:
-		error = EINVAL;
+		return (EOPNOTSUPP);
 	}
-	return (error);
+	return (0);
 }



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