Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 27 Feb 2015 00:54:53 +0000 (UTC)
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r279340 - in projects/ifnet/sys: dev/bge dev/msk dev/virtio/network dev/xl net netinet
Message-ID:  <201502270054.t1R0srAd028950@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: glebius
Date: Fri Feb 27 00:54:53 2015
New Revision: 279340
URL: https://svnweb.freebsd.org/changeset/base/279340

Log:
  Historically all interfaces have their if_init() method, which initializes
  final resources and brings it up. Usually, the driver code calls its
  xxx_init() method internally, when being brought IFF_UP via SIOCSIFFLAGS.
  However, for IPv4 there historically existed another quite ugly code path:
  
  sys_ioctl(SIOCAIFADDR) -> .. -> in_control(SIOCAIFADDR) ->
  -> if_ioctl(SIOCSIFADDR) -> ether_ioctl(SIOCSIFADDR) -> if_init().
  
  Note that a legitimate SIOCAIFADDR is temporarily substituted with
  obsoleted SIOCSIFADDR. Moreover, the pointer provided with command
  is not ifreq pointer, but ifaddr. Finally, the IFF_UP was set by
  ether_ioctl() blindly, without executing if_up().
  
  Unentangle that:
  - All xxx_init()s are no longer a driver methods, but a static functions.
    The only legitimate way of upping an interface is SIOCSIFFLAGS.
  - in_control() calls SIOCSIFFLAGS if it sees interface not IFF_UP.
  - arp_ifinit() moves to in_control(), out of Ethernet code.
  - ether_ioctl() no longer contains #ifdef INET hack.
  
  Sponsored by:	Netflix
  Sponsored by:	Nginx, Inc.

Modified:
  projects/ifnet/sys/dev/bge/if_bge.c
  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_ethersubr.c
  projects/ifnet/sys/net/if_var.h
  projects/ifnet/sys/netinet/in.c

Modified: projects/ifnet/sys/dev/bge/if_bge.c
==============================================================================
--- projects/ifnet/sys/dev/bge/if_bge.c	Fri Feb 27 00:26:17 2015	(r279339)
+++ projects/ifnet/sys/dev/bge/if_bge.c	Fri Feb 27 00:54:53 2015	(r279340)
@@ -419,8 +419,7 @@ static void bge_intr_task(void *, int);
 static int bge_start_locked(struct bge_softc *);
 static int bge_transmit(if_t, struct mbuf *);
 static int bge_ioctl(if_t, u_long, void *, struct thread *);
-static void bge_init_locked(struct bge_softc *);
-static void bge_init(void *);
+static void bge_init(struct bge_softc *);
 static void bge_stop_block(struct bge_softc *, bus_size_t, uint32_t);
 static void bge_stop(struct bge_softc *);
 static void bge_watchdog(struct bge_softc *);
@@ -536,7 +535,6 @@ static struct ifdriver bge_ifdrv = {
 	.ifdrv_ops = {
 		.ifop_origin = IFOP_ORIGIN_DRIVER,
 		.ifop_ioctl = bge_ioctl,
-		.ifop_init = bge_init,
 		.ifop_transmit = bge_transmit,
 		.ifop_get_counter = bge_get_counter,
 #ifdef DEVICE_POLLING
@@ -5408,7 +5406,7 @@ bge_transmit(if_t ifp, struct mbuf *m)
 }
 
 static void
-bge_init_locked(struct bge_softc *sc)
+bge_init(struct bge_softc *sc)
 {
 	if_t ifp;
 	uint16_t *m;
@@ -5578,16 +5576,6 @@ bge_init_locked(struct bge_softc *sc)
 	callout_reset(&sc->bge_stat_ch, hz, bge_tick, sc);
 }
 
-static void
-bge_init(void *xsc)
-{
-	struct bge_softc *sc = xsc;
-
-	BGE_LOCK(sc);
-	bge_init_locked(sc);
-	BGE_UNLOCK(sc);
-}
-
 /*
  * Set media options.
  */
@@ -5754,7 +5742,7 @@ bge_ioctl(if_t ifp, u_long command, void
 		sc->bge_mtu = ifr->ifr_mtu;
 		if (sc->bge_flags & BGE_FLAG_RUNNING) {
 			sc->bge_flags &= ~BGE_FLAG_RUNNING;
-			bge_init_locked(sc);
+			bge_init(sc);
 		}
 		BGE_UNLOCK(sc);
 		break;
@@ -5777,7 +5765,7 @@ bge_ioctl(if_t ifp, u_long command, void
 				if ((oflags ^ sc->bge_if_flags) & IFF_ALLMULTI)
 					bge_setmulti(sc);
 			} else
-				bge_init_locked(sc);
+				bge_init(sc);
 		} else if (sc->bge_flags & BGE_FLAG_RUNNING)
 			bge_stop(sc);
 		BGE_UNLOCK(sc);
@@ -5827,8 +5815,10 @@ bge_ioctl(if_t ifp, u_long command, void
 		    (sc->bge_flags & (BGE_FLAG_TSO | BGE_FLAG_TSO3)) != 0)
 			ifr->ifr_hwassist |= CSUM_TSO;
 		if (mask & IFCAP_VLAN_MTU) {
+			BGE_LOCK(sc);
 			sc->bge_flags &= ~BGE_FLAG_RUNNING;
 			bge_init(sc);
+			BGE_UNLOCK(sc);
 		}
 		if ((mask & IFCAP_VLAN_HWTAGGING) != 0) {
 			BGE_LOCK(sc);
@@ -5887,7 +5877,7 @@ bge_watchdog(struct bge_softc *sc)
 	if_printf(ifp, "watchdog timeout -- resetting\n");
 
 	sc->bge_flags &= ~BGE_FLAG_RUNNING;
-	bge_init_locked(sc);
+	bge_init(sc);
 
 	if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
 }
@@ -6043,7 +6033,7 @@ bge_resume(device_t dev)
 	sc = device_get_softc(dev);
 	BGE_LOCK(sc);
 	if (sc->bge_if_flags & IFF_UP) {
-		bge_init_locked(sc);
+		bge_init(sc);
 		if (sc->bge_flags & BGE_FLAG_RUNNING)
 			bge_start_locked(sc);
 	}

Modified: projects/ifnet/sys/dev/msk/if_msk.c
==============================================================================
--- projects/ifnet/sys/dev/msk/if_msk.c	Fri Feb 27 00:26:17 2015	(r279339)
+++ projects/ifnet/sys/dev/msk/if_msk.c	Fri Feb 27 00:54:53 2015	(r279340)
@@ -286,8 +286,7 @@ static int msk_ioctl(if_t, u_long, void 
 static void msk_set_prefetch(struct msk_softc *, int, bus_addr_t, uint32_t);
 static void msk_set_rambuffer(struct msk_if_softc *);
 static void msk_set_tx_stfwd(struct msk_if_softc *);
-static void msk_init(void *);
-static void msk_init_locked(struct msk_if_softc *);
+static void msk_init(struct msk_if_softc *);
 static void msk_stop(struct msk_if_softc *);
 static void msk_watchdog(struct msk_if_softc *);
 static int msk_mediachange(if_t);
@@ -399,7 +398,6 @@ static struct ifdriver msk_ifdrv = {
 	.ifdrv_ops = {
 		.ifop_origin = IFOP_ORIGIN_DRIVER,
 		.ifop_ioctl = msk_ioctl,
-		.ifop_init = msk_init,
 		.ifop_transmit = msk_transmit,
 	},
 	.ifdrv_name = "msk",
@@ -1108,7 +1106,7 @@ msk_ioctl(if_t ifp, u_long command, void
 		    ETHER_VLAN_ENCAP_LEN;
 		if ((sc_if->msk_flags & MSK_FLAG_RUNNING) != 0) {
 			sc_if->msk_flags &= ~MSK_FLAG_RUNNING;
-			msk_init_locked(sc_if);
+			msk_init(sc_if);
 		}
 		MSK_IF_UNLOCK(sc_if);
 		break;
@@ -1122,7 +1120,7 @@ msk_ioctl(if_t ifp, u_long command, void
 			    (IFF_PROMISC | IFF_ALLMULTI)) != 0)
 				msk_rxfilter(sc_if);
 			else if ((sc_if->msk_flags & MSK_FLAG_DETACH) == 0)
-				msk_init_locked(sc_if);
+				msk_init(sc_if);
 		} else if ((sc_if->msk_flags & MSK_FLAG_RUNNING) != 0)
 			msk_stop(sc_if);
 		MSK_IF_UNLOCK(sc_if);
@@ -1164,7 +1162,7 @@ msk_ioctl(if_t ifp, u_long command, void
 			msk_setvlan(sc_if);
 		if (reinit && (sc_if->msk_flags & MSK_FLAG_RUNNING) != 0) {
 			sc_if->msk_flags &= ~MSK_FLAG_RUNNING;
-			msk_init_locked(sc_if);
+			msk_init(sc_if);
 		}
 		MSK_IF_UNLOCK(sc_if);
 		break;
@@ -2957,14 +2955,14 @@ msk_watchdog(struct msk_if_softc *sc_if)
 			   "(missed link)\n");
 		if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
 		sc_if->msk_flags &= ~MSK_FLAG_RUNNING;
-		msk_init_locked(sc_if);
+		msk_init(sc_if);
 		return;
 	}
 
 	if_printf(ifp, "watchdog timeout\n");
 	if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
 	sc_if->msk_flags &= ~MSK_FLAG_RUNNING;
-	msk_init_locked(sc_if);
+	msk_init(sc_if);
 	msk_start(sc_if);
 }
 
@@ -3037,7 +3035,7 @@ mskc_resume(device_t dev)
 		if (sc->msk_if[i] != NULL && sc->msk_if[i]->msk_ifp != NULL &&
 		    (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]);
+			msk_init(sc->msk_if[i]);
 		}
 	}
 	sc->msk_pflags &= ~MSK_FLAG_SUSPEND;
@@ -3742,17 +3740,7 @@ msk_set_tx_stfwd(struct msk_if_softc *sc
 }
 
 static void
-msk_init(void *xsc)
-{
-	struct msk_if_softc *sc_if = xsc;
-
-	MSK_IF_LOCK(sc_if);
-	msk_init_locked(sc_if);
-	MSK_IF_UNLOCK(sc_if);
-}
-
-static void
-msk_init_locked(struct msk_if_softc *sc_if)
+msk_init(struct msk_if_softc *sc_if)
 {
 	struct msk_softc *sc;
 	if_t ifp;

Modified: projects/ifnet/sys/dev/virtio/network/if_vtnet.c
==============================================================================
--- projects/ifnet/sys/dev/virtio/network/if_vtnet.c	Fri Feb 27 00:26:17 2015	(r279339)
+++ projects/ifnet/sys/dev/virtio/network/if_vtnet.c	Fri Feb 27 00:54:53 2015	(r279340)
@@ -173,8 +173,7 @@ static int	vtnet_init_tx_queues(struct v
 static int	vtnet_init_rxtx_queues(struct vtnet_softc *);
 static void	vtnet_set_active_vq_pairs(struct vtnet_softc *);
 static int	vtnet_reinit(struct vtnet_softc *);
-static void	vtnet_init_locked(struct vtnet_softc *);
-static void	vtnet_init(void *);
+static void	vtnet_init(struct vtnet_softc *);
 
 static void	vtnet_free_ctrl_vq(struct vtnet_softc *);
 static void	vtnet_exec_ctrl_cmd(struct vtnet_softc *, void *,
@@ -299,7 +298,6 @@ static struct ifdriver vtnet_ifdrv = {
 	.ifdrv_ops = {
 		.ifop_origin = IFOP_ORIGIN_DRIVER,
 		.ifop_ioctl = vtnet_ioctl,
-		.ifop_init = vtnet_init,
 		.ifop_get_counter = vtnet_get_counter,
 		.ifop_transmit = vtnet_txq_mq_start,
 		.ifop_qflush = vtnet_qflush,
@@ -480,7 +478,7 @@ vtnet_resume(device_t dev)
 
 	VTNET_CORE_LOCK(sc);
 	if (sc->vtnet_if_flags & IFF_UP)
-		vtnet_init_locked(sc);
+		vtnet_init(sc);
 	sc->vtnet_flags &= ~VTNET_FLAG_SUSPENDED;
 	VTNET_CORE_UNLOCK(sc);
 
@@ -1003,7 +1001,7 @@ vtnet_change_mtu(struct vtnet_softc *sc,
 
 	if (sc->vtnet_flags & VTNET_FLAG_RUNNING) {
 		sc->vtnet_flags &= ~VTNET_FLAG_RUNNING;
-		vtnet_init_locked(sc);
+		vtnet_init(sc);
 	}
 
 	return (0);
@@ -1044,7 +1042,7 @@ vtnet_ioctl(if_t ifp, u_long cmd, void *
 			    (IFF_PROMISC | IFF_ALLMULTI))
 				vtnet_rx_filter(sc);
 		} else
-			vtnet_init_locked(sc);
+			vtnet_init(sc);
 		VTNET_CORE_UNLOCK(sc);
 		break;
 
@@ -1072,7 +1070,7 @@ vtnet_ioctl(if_t ifp, u_long cmd, void *
 		    (sc->vtnet_flags & VTNET_FLAG_RUNNING)) {
 			VTNET_CORE_LOCK(sc);
 			sc->vtnet_flags &= ~VTNET_FLAG_RUNNING;
-			vtnet_init_locked(sc);
+			vtnet_init(sc);
 			VTNET_CORE_UNLOCK(sc);
 		}
 		ifr->ifr_hwassist = 0;
@@ -2502,7 +2500,7 @@ vtnet_tick(void *xsc)
 
 	if (timedout != 0) {
 		sc->vtnet_flags &= ~VTNET_FLAG_RUNNING;
-		vtnet_init_locked(sc);
+		vtnet_init(sc);
 	} else
 		callout_schedule(&sc->vtnet_tick_ch, hz);
 }
@@ -2858,7 +2856,7 @@ vtnet_reinit(struct vtnet_softc *sc)
 }
 
 static void
-vtnet_init_locked(struct vtnet_softc *sc)
+vtnet_init(struct vtnet_softc *sc)
 {
 	device_t dev;
 	if_t ifp;
@@ -2892,25 +2890,6 @@ fail:
 }
 
 static void
-vtnet_init(void *xsc)
-{
-	struct vtnet_softc *sc;
-
-	sc = xsc;
-
-#ifdef DEV_NETMAP
-	if (!NA(sc->vtnet_ifp)) {
-		D("try to attach again");
-		vtnet_netmap_attach(sc);
-	}
-#endif /* DEV_NETMAP */
-
-	VTNET_CORE_LOCK(sc);
-	vtnet_init_locked(sc);
-	VTNET_CORE_UNLOCK(sc);
-}
-
-static void
 vtnet_free_ctrl_vq(struct vtnet_softc *sc)
 {
 	struct virtqueue *vq;

Modified: projects/ifnet/sys/dev/xl/if_xl.c
==============================================================================
--- projects/ifnet/sys/dev/xl/if_xl.c	Fri Feb 27 00:26:17 2015	(r279339)
+++ projects/ifnet/sys/dev/xl/if_xl.c	Fri Feb 27 00:54:53 2015	(r279340)
@@ -238,8 +238,7 @@ static int xl_transmit(if_t, struct mbuf
 static void xl_start_locked(struct xl_softc *);
 static void xl_start_90xB_locked(struct xl_softc *);
 static int xl_ioctl(if_t, u_long, void *, struct thread *);
-static void xl_init(void *);
-static void xl_init_locked(struct xl_softc *);
+static void xl_init(struct xl_softc *);
 static void xl_stop(struct xl_softc *);
 static int xl_watchdog(struct xl_softc *);
 static int xl_shutdown(device_t);
@@ -333,7 +332,6 @@ static struct ifdriver xl_ifdrv = {
 		.ifop_origin = IFOP_ORIGIN_DRIVER,
 		.ifop_ioctl = xl_ioctl,
 		.ifop_transmit = xl_transmit,
-		.ifop_init = xl_init,
 #ifdef DEVICE_POLLING
 		.ifop_poll = xl_poll,
 #endif
@@ -2175,7 +2173,7 @@ xl_intr(void *arg)
 
 		if (status & XL_STAT_ADFAIL) {
 			sc->xl_flags &= ~XL_FLAG_RUNNING;
-			xl_init_locked(sc);
+			xl_init(sc);
 			break;
 		}
 
@@ -2236,7 +2234,7 @@ xl_poll(if_t ifp, enum poll_cmd cmd, int
 
 			if (status & XL_STAT_ADFAIL) {
 				sc->xl_flags &= ~XL_FLAG_RUNNING;
-				xl_init_locked(sc);
+				xl_init(sc);
 			}
 
 			if (status & XL_STAT_STATSOFLOW)
@@ -2624,17 +2622,7 @@ xl_start_90xB_locked(struct xl_softc *sc
 }
 
 static void
-xl_init(void *xsc)
-{
-	struct xl_softc		*sc = xsc;
-
-	XL_LOCK(sc);
-	xl_init_locked(sc);
-	XL_UNLOCK(sc);
-}
-
-static void
-xl_init_locked(struct xl_softc *sc)
+xl_init(struct xl_softc *sc)
 {
 	int			error, i;
 	struct mii_data		*mii = NULL;
@@ -2870,7 +2858,7 @@ xl_ifmedia_upd(if_t ifp)
 	    sc->xl_media & XL_MEDIAOPT_BTX ||
 	    sc->xl_media & XL_MEDIAOPT_BT4) {
 		sc->xl_flags &= ~XL_FLAG_RUNNING;
-		xl_init_locked(sc);
+		xl_init(sc);
 	} else {
 		xl_setmode(sc, ifm->ifm_media);
 	}
@@ -2978,7 +2966,7 @@ xl_ioctl(if_t ifp, u_long command, void 
 			    (IFF_PROMISC | IFF_ALLMULTI))
 				xl_rxfilter(sc);
 			else
-				xl_init_locked(sc);
+				xl_init(sc);
 		} else if (sc->xl_flags & XL_FLAG_RUNNING)
 			xl_stop(sc);
 		XL_UNLOCK(sc);
@@ -3077,7 +3065,7 @@ xl_watchdog(struct xl_softc *sc)
 		    "no carrier - transceiver cable problem?\n");
 
 	sc->xl_flags &= ~XL_FLAG_RUNNING;
-	xl_init_locked(sc);
+	xl_init(sc);
 
 	if (if_snd_len(ifp)) {
 		if (sc->xl_type == XL_TYPE_905B)
@@ -3196,7 +3184,7 @@ xl_resume(device_t dev)
 	XL_LOCK(sc);
 	if (sc->xl_if_flags & IFF_UP) {
 		sc->xl_flags &= ~XL_FLAG_RUNNING;
-		xl_init_locked(sc);
+		xl_init(sc);
 	}
 	XL_UNLOCK(sc);
 

Modified: projects/ifnet/sys/net/if.c
==============================================================================
--- projects/ifnet/sys/net/if.c	Fri Feb 27 00:26:17 2015	(r279339)
+++ projects/ifnet/sys/net/if.c	Fri Feb 27 00:54:53 2015	(r279340)
@@ -442,7 +442,6 @@ ifdriver_bless(struct ifdriver *ifdrv, s
 		COPY(ifop_output);
 		COPY(ifop_ioctl);
 		COPY(ifop_get_counter);
-		COPY(ifop_init);
 		COPY(ifop_qflush);
 		COPY(ifop_resolvemulti);
 		COPY(ifop_reassign);
@@ -2261,7 +2260,7 @@ if_drvioctl(struct ifnet *ifp, u_long cm
 	char new_name[IFNAMSIZ];
 	struct ifaddr *ifa;
 	struct sockaddr_dl *sdl;
-	uint32_t flags;
+	uint32_t flags, oflags;
 	int error = 0;
 
 	ifr = (struct ifreq *)data;
@@ -2379,8 +2378,10 @@ if_drvioctl(struct ifnet *ifp, u_long cm
 		/*
 		 * Historically if_flags were 16-bit, and thus
 		 * they come from userland in two parts, that
-		 * we need to swap.
+		 * we need to swap.  Clear IFF_RUNNING that is
+		 * no longer used in kernel.
 		 */
+		ifr->ifr_flags &= ~IFF_RUNNING;
 		flags = (ifr->ifr_flags & 0xffff) |
 		    (ifr->ifr_flagshigh << 16);
 		if ((flags & IFF_CANTCHANGE) !=
@@ -2394,15 +2395,18 @@ if_drvioctl(struct ifnet *ifp, u_long cm
 			return (error);
 		flags = (ifr->ifr_flags & 0xffff) |
 		    (ifr->ifr_flagshigh << 16);
+		oflags = ifp->if_flags;
+		ifp->if_flags = flags;
+		getmicrotime(&ifp->if_lastchange);
 		/*
 		 * Manage IFF_UP flip.
 		 */
-		if (ifp->if_flags & IFF_UP && (flags & IFF_UP) == 0)
+		if (oflags & IFF_UP && (flags & IFF_UP) == 0)
 			if_down(ifp);
-		else if (flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0)
+		else if (flags & IFF_UP && (oflags & IFF_UP) == 0)
 			if_up(ifp);
-		/* See if permanently promiscuous mode bit is about to flip */
-		if ((ifp->if_flags ^ flags) & IFF_PPROMISC) {
+		/* See if permanently promiscuous mode bit is about to flip. */
+		if ((oflags ^ flags) & IFF_PPROMISC) {
 			if (flags & IFF_PPROMISC)
 				ifp->if_flags |= IFF_PROMISC;
 			else if (ifp->if_pcount == 0)
@@ -2411,8 +2415,6 @@ if_drvioctl(struct ifnet *ifp, u_long cm
 			    ifp->if_xname,
 			    (flags & IFF_PPROMISC) ? "enabled" : "disabled");
 		}
-		ifp->if_flags = flags;
-		getmicrotime(&ifp->if_lastchange);
 		break;
 
 	case SIOCSIFCAP:
@@ -2779,17 +2781,10 @@ ifioctl(struct socket *so, u_long cmd, c
 	/*
 	 * Pass the request on to the socket control method, and if the
 	 * latter returns EOPNOTSUPP, directly to the interface.
-	 *
-	 * Make an exception for the legacy SIOCSIF* requests.  Drivers
-	 * trust SIOCSIFADDR et al to come from an already privileged
-	 * layer, and do not perform any credentials checks or input
-	 * validation.
 	 */
 	error = ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data,
 	    ifp, td));
-	if (error == EOPNOTSUPP && ifp != NULL &&
-	    cmd != SIOCSIFADDR && cmd != SIOCSIFBRDADDR &&
-	    cmd != SIOCSIFDSTADDR && cmd != SIOCSIFNETMASK)
+	if (error == EOPNOTSUPP)
 		error = if_ioctl(ifp, cmd, data, td);
 
 	if ((oif_flags ^ ifp->if_flags) & IFF_UP) {

Modified: projects/ifnet/sys/net/if.h
==============================================================================
--- projects/ifnet/sys/net/if.h	Fri Feb 27 00:26:17 2015	(r279339)
+++ projects/ifnet/sys/net/if.h	Fri Feb 27 00:54:53 2015	(r279340)
@@ -581,7 +581,6 @@ typedef enum {
 
 typedef struct ifnet * if_t;
 
-typedef void	(*if_init_t)(void *);
 typedef void	(*if_input_t)(if_t, struct mbuf *);
 typedef int	(*if_transmit_t)(if_t, struct mbuf *);
 typedef int	(*if_output_t)(if_t, struct mbuf *, const struct sockaddr *,
@@ -611,7 +610,6 @@ struct ifops {
 #endif
 	if_ioctl_t	ifop_ioctl;	/* ioctl routine */
 	if_get_counter_t ifop_get_counter; /* get counter values */
-	if_init_t	ifop_init;	/* init routine */
 	if_qflush_t	ifop_qflush;	/* flush any queue */	
 	if_resolvemulti_t ifop_resolvemulti; /* validate/resolve multicast */
 	if_reassign_t	ifop_reassign;	/* reassign to vnet routine */

Modified: projects/ifnet/sys/net/if_ethersubr.c
==============================================================================
--- projects/ifnet/sys/net/if_ethersubr.c	Fri Feb 27 00:26:17 2015	(r279339)
+++ projects/ifnet/sys/net/if_ethersubr.c	Fri Feb 27 00:54:53 2015	(r279340)
@@ -943,27 +943,9 @@ ether_crc32_be(const uint8_t *buf, size_
 static int
 ether_ioctl(struct ifnet *ifp, u_long command, void *data, struct thread *td)
 {
-	struct ifaddr *ifa = (struct ifaddr *) data;
 	struct ifreq *ifr = (struct ifreq *) data;
-	int error = 0;
 
 	switch (command) {
-	case SIOCSIFADDR:
-		ifp->if_flags |= IFF_UP;
-
-		switch (ifa->ifa_addr->sa_family) {
-#ifdef INET
-		case AF_INET:
-			if_init(ifp, ifp->if_softc);	/* before arpwhohas */
-			arp_ifinit(ifp, ifa);
-			break;
-#endif
-		default:
-			if_init(ifp, ifp->if_softc);
-			break;
-		}
-		break;
-
 	case SIOCGIFADDR:
 		{
 			struct sockaddr *sa;
@@ -978,17 +960,16 @@ ether_ioctl(struct ifnet *ifp, u_long co
 		/*
 		 * Set the interface MTU.
 		 */
-		if (ifr->ifr_mtu > ETHERMTU) {
-			error = EINVAL;
-		} else {
+		if (ifr->ifr_mtu > ETHERMTU)
+			return (EINVAL);
+		else
 			ifp->if_mtu = ifr->ifr_mtu;
-		}
 		break;
 	default:
-		error = EOPNOTSUPP;
-		break;
+		return (EOPNOTSUPP);
 	}
-	return (error);
+
+	return (0);
 }
 
 static int

Modified: projects/ifnet/sys/net/if_var.h
==============================================================================
--- projects/ifnet/sys/net/if_var.h	Fri Feb 27 00:26:17 2015	(r279339)
+++ projects/ifnet/sys/net/if_var.h	Fri Feb 27 00:54:53 2015	(r279340)
@@ -427,14 +427,6 @@ void if_poll_deregister(struct ifnet *if
  * others are mandatory.  Those wrappers that driver can invoke
  * theirselves are not inlined, but implemented in if.c.
  */
-static inline void
-if_init(if_t ifp, void *sc)
-{
-
-	if (ifp->if_ops->ifop_init != NULL)
-		return (ifp->if_ops->ifop_init(sc));
-}
-
 #undef if_input
 static inline void
 if_input(if_t ifp, struct mbuf *m)

Modified: projects/ifnet/sys/netinet/in.c
==============================================================================
--- projects/ifnet/sys/netinet/in.c	Fri Feb 27 00:26:17 2015	(r279339)
+++ projects/ifnet/sys/netinet/in.c	Fri Feb 27 00:54:53 2015	(r279340)
@@ -339,6 +339,22 @@ in_aifaddr_ioctl(u_long cmd, caddr_t dat
 		return (EPROTONOSUPPORT);
 
 	/*
+	 * Historically assigning address to an interface is an
+	 * implicit IFF_UP.  Even if address assignment fails,
+	 * the interface stays up.
+	 */
+	if ((ifp->if_flags & IFF_UP) == 0) {
+		struct ifreq ifr;
+
+		ifr.ifr_flags = ifp->if_flags & 0xffff;
+		ifr.ifr_flagshigh = ifp->if_flags >> 16;
+		ifr.ifr_flags |= IFF_UP;
+		error = if_drvioctl(ifp, SIOCSIFFLAGS, &ifr, td);
+		if (error)
+			return (error);
+	}
+
+	/*
 	 * See whether address already exist.
 	 */
 	iaIsFirst = true;
@@ -430,15 +446,6 @@ in_aifaddr_ioctl(u_long cmd, caddr_t dat
 	IN_IFADDR_WUNLOCK();
 
 	/*
-	 * Give the interface a chance to initialize
-	 * if this is its first address,
-	 * and to validate the address if necessary.
-	 */
-	error = if_ioctl(ifp, SIOCSIFADDR, ia, td);
-	if (error != 0 && error != EOPNOTSUPP)
-		goto fail1;
-
-	/*
 	 * Add route for the network.
 	 */
 	if (vhid == 0) {
@@ -483,6 +490,9 @@ in_aifaddr_ioctl(u_long cmd, caddr_t dat
 			&ii->ii_allhosts);
 	}
 
+	if (vhid == 0 && (ifp->if_flags & IFF_BROADCAST))
+		arp_ifinit(ifp, ifa);
+
 	EVENTHANDLER_INVOKE(ifaddr_event, ifp);
 
 	return (error);



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