From owner-svn-src-projects@FreeBSD.ORG Fri Feb 27 00:54:56 2015 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 4E5B7411; Fri, 27 Feb 2015 00:54:56 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 3736530F; Fri, 27 Feb 2015 00:54:56 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t1R0suYY028962; Fri, 27 Feb 2015 00:54:56 GMT (envelope-from glebius@FreeBSD.org) Received: (from glebius@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t1R0srAd028950; Fri, 27 Feb 2015 00:54:53 GMT (envelope-from glebius@FreeBSD.org) Message-Id: <201502270054.t1R0srAd028950@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: glebius set sender to glebius@FreeBSD.org using -f From: Gleb Smirnoff Date: Fri, 27 Feb 2015 00:54:53 +0000 (UTC) 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 X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 27 Feb 2015 00:54:56 -0000 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);