svn commit: r277456 - in projects/ifnet/sys: dev/bge dev/msk dev/virtio/network dev/xl net
Gleb Smirnoff
glebius at FreeBSD.org
Tue Jan 20 23:05:03 UTC 2015
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);
}
More information about the svn-src-projects
mailing list