Index: net/if.c =================================================================== RCS file: /cvsroot/src/sys/net/if.c,v retrieving revision 1.256 diff -u -p -r1.256 if.c --- net/if.c 28 Oct 2011 20:11:58 -0000 1.256 +++ net/if.c 14 Nov 2011 17:59:26 -0000 @@ -112,7 +112,6 @@ __KERNEL_RCSID(0, "$NetBSD: if.c,v 1.256 #include #include #include -#include #include #include @@ -169,10 +168,6 @@ struct pfil_head if_pfil; /* packet filt static kauth_listener_t if_listener; -static int ifioctl_attach(struct ifnet *); -static void ifioctl_detach(struct ifnet *); -static void ifnet_lock_enter(struct ifnet_lock *); -static void ifnet_lock_exit(struct ifnet_lock *); static void if_detach_queues(struct ifnet *, struct ifqueue *); static void sysctl_sndq_setup(struct sysctllog **, const char *, struct ifaltq *); @@ -297,10 +292,6 @@ int if_nullioctl(struct ifnet *ifp, u_long cmd, void *data) { - /* Wake ifioctl_detach(), who may wait for all threads to - * quit the critical section. - */ - cv_signal(&ifp->if_ioctl_lock->il_emptied); return ENXIO; } @@ -506,9 +497,8 @@ if_attach(struct ifnet *ifp) } TAILQ_INIT(&ifp->if_addrlist); TAILQ_INSERT_TAIL(&ifnet, ifp, if_list); - - if (ifioctl_attach(ifp) != 0) - panic("%s: ifioctl_attach() failed", __func__); + if (ifp->if_ioctl == NULL) + ifp->if_ioctl = ifioctl_common; mutex_enter(&index_gen_mtx); ifp->if_index_gen = index_gen++; @@ -852,8 +842,6 @@ again: TAILQ_REMOVE(&ifnet, ifp, if_list); - ifioctl_detach(ifp); - /* * remove packets that came from ifp, from software interrupt queues. */ @@ -1415,7 +1403,8 @@ int ifpromisc(struct ifnet *ifp, int pswitch) { int pcount, ret; - short flags, nflags; + short flags; + struct ifreq ifr; pcount = ifp->if_pcount; flags = ifp->if_flags; @@ -1427,26 +1416,29 @@ ifpromisc(struct ifnet *ifp, int pswitch */ if (ifp->if_pcount++ != 0) return 0; - nflags = ifp->if_flags | IFF_PROMISC; - if ((nflags & IFF_UP) == 0) + ifp->if_flags |= IFF_PROMISC; + if ((ifp->if_flags & IFF_UP) == 0) return 0; } else { if (--ifp->if_pcount > 0) return 0; - nflags = ifp->if_flags & ~IFF_PROMISC; + ifp->if_flags &= ~IFF_PROMISC; /* * If the device is not configured up, we should not need to * turn off promiscuous mode (device should have turned it * off when interface went down; and will look at IFF_PROMISC * again next time interface comes up). */ - if ((nflags & IFF_UP) == 0) + if ((ifp->if_flags & IFF_UP) == 0) return 0; } - ret = if_flags_set(ifp, nflags); + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = ifp->if_flags; + ret = (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, &ifr); /* Restore interface state if not successful. */ if (ret != 0) { ifp->if_pcount = pcount; + ifp->if_flags = flags; } return ret; } @@ -1701,32 +1693,6 @@ ifaddrpref_ioctl(struct socket *so, u_lo } } -static void -ifnet_lock_enter(struct ifnet_lock *il) -{ - uint64_t *nenter; - - /* Before trying to acquire the mutex, increase the count of threads - * who have entered or who wait to enter the critical section. - * Avoid one costly locked memory transaction by keeping a count for - * each CPU. - */ - nenter = percpu_getref(il->il_nenter); - (*nenter)++; - percpu_putref(il->il_nenter); - mutex_enter(&il->il_lock); -} - -static void -ifnet_lock_exit(struct ifnet_lock *il) -{ - /* Increase the count of threads who have exited the critical - * section. Increase while we still hold the lock. - */ - il->il_nexit++; - mutex_exit(&il->il_lock); -} - /* * Interface ioctls. */ @@ -1835,12 +1801,11 @@ ifioctl(struct socket *so, u_long cmd, v oif_flags = ifp->if_flags; - ifnet_lock_enter(ifp->if_ioctl_lock); error = (*ifp->if_ioctl)(ifp, cmd, data); if (error != ENOTTY) ; else if (so->so_proto == NULL) - error = EOPNOTSUPP; + return EOPNOTSUPP; else { #ifdef COMPAT_OSOCK error = compat_ifioctl(so, ocmd, cmd, data, l); @@ -1865,98 +1830,9 @@ ifioctl(struct socket *so, u_long cmd, v ifreqn2o(oifr, ifr); #endif - ifnet_lock_exit(ifp->if_ioctl_lock); return error; } -/* This callback adds to the sum in `arg' the number of - * threads on `ci' who have entered or who wait to enter the - * critical section. - */ -static void -ifnet_lock_sum(void *p, void *arg, struct cpu_info *ci) -{ - uint64_t *sum = arg, *nenter = p; - - *sum += *nenter; -} - -/* Return the number of threads who have entered or who wait - * to enter the critical section on all CPUs. - */ -static uint64_t -ifnet_lock_entrances(struct ifnet_lock *il) -{ - uint64_t sum = 0; - - percpu_foreach(il->il_nenter, ifnet_lock_sum, &sum); - - return sum; -} - -static int -ifioctl_attach(struct ifnet *ifp) -{ - struct ifnet_lock *il; - - /* If the driver has not supplied its own if_ioctl, then - * supply the default. - */ - if (ifp->if_ioctl == NULL) - ifp->if_ioctl = ifioctl_common; - - /* Create an ifnet_lock for synchronizing ifioctls. */ - if ((il = kmem_zalloc(sizeof(*il), KM_SLEEP)) == NULL) - return ENOMEM; - - il->il_nenter = percpu_alloc(sizeof(uint64_t)); - if (il->il_nenter == NULL) { - kmem_free(il, sizeof(*il)); - return ENOMEM; - } - - mutex_init(&il->il_lock, MUTEX_DEFAULT, IPL_NONE); - cv_init(&il->il_emptied, ifp->if_xname); - - ifp->if_ioctl_lock = il; - - return 0; -} - -/* - * This must not be called until after `ifp' has been withdrawn from the - * ifnet tables so that ifioctl() cannot get a handle on it by calling - * ifunit(). - */ -static void -ifioctl_detach(struct ifnet *ifp) -{ - struct ifnet_lock *il; - - il = ifp->if_ioctl_lock; - mutex_enter(&il->il_lock); - /* Install if_nullioctl to make sure that any thread that - * subsequently enters the critical section will quit it - * immediately and signal the condition variable that we - * wait on, below. - */ - ifp->if_ioctl = if_nullioctl; - /* Sleep while threads are still in the critical section or - * wait to enter it. - */ - while (ifnet_lock_entrances(il) != il->il_nexit) - cv_wait(&il->il_emptied, &il->il_lock); - /* At this point, we are the only thread still in the critical - * section, and no new thread can get a handle on the ifioctl - * lock, so it is safe to free its memory. - */ - mutex_exit(&il->il_lock); - ifp->if_ioctl_lock = NULL; - percpu_free(il->il_nenter, sizeof(uint64_t)); - il->il_nenter = NULL; - kmem_free(il, sizeof(*il)); -} - /* * Return interface configuration * of system. List may be used @@ -2136,62 +2012,6 @@ ifq_enqueue2(struct ifnet *ifp, struct i return 0; } -int -if_addr_init(ifnet_t *ifp, struct ifaddr *ifa, const bool src) -{ - int rc; - - if (ifp->if_initaddr != NULL) - rc = (*ifp->if_initaddr)(ifp, ifa, src); - else if (src || - (rc = (*ifp->if_ioctl)(ifp, SIOCSIFDSTADDR, ifa)) == ENOTTY) - rc = (*ifp->if_ioctl)(ifp, SIOCINITIFADDR, ifa); - - return rc; -} - -int -if_flags_set(ifnet_t *ifp, const short flags) -{ - int rc; - - if (ifp->if_setflags != NULL) - rc = (*ifp->if_setflags)(ifp, flags); - else { - short cantflags; - struct ifreq ifr; - - memset(&ifr, 0, sizeof(ifr)); - - cantflags = (ifp->if_flags ^ flags) & IFF_CANTCHANGE; - if (cantflags != 0) - ifp->if_flags ^= cantflags; - - ifr.ifr_flags = flags & ~IFF_CANTCHANGE; - rc = (*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, &ifr); - - if (rc != 0 && cantflags != 0) - ifp->if_flags ^= cantflags; - } - - return rc; -} - -int -if_mcast_op(ifnet_t *ifp, const unsigned long cmd, const struct sockaddr *sa) -{ - int rc; - struct ifreq ifr; - - if (ifp->if_mcastop != NULL) - rc = (*ifp->if_mcastop)(ifp, cmd, sa); - else { - ifreq_setaddr(cmd, &ifr, sa); - rc = (*ifp->if_ioctl)(ifp, cmd, &ifr); - } - - return rc; -} static void sysctl_sndq_setup(struct sysctllog **clog, const char *ifname, Index: net/if.h =================================================================== RCS file: /cvsroot/src/sys/net/if.h,v retrieving revision 1.154 diff -u -p -r1.154 if.h --- net/if.h 25 Oct 2011 22:26:18 -0000 1.154 +++ net/if.h 14 Nov 2011 17:59:26 -0000 @@ -63,10 +63,6 @@ #ifndef _NET_IF_H_ #define _NET_IF_H_ -#if !defined(_KERNEL) && !defined(_STANDALONE) -#include -#endif - #include /* @@ -77,6 +73,8 @@ #if defined(_NETBSD_SOURCE) +#include +#include #include #include #include @@ -201,33 +199,6 @@ struct ifqueue { int ifq_drops; }; -struct ifnet_lock; - -#ifdef _KERNEL -#include -#include -#include - -struct ifnet_lock { - kmutex_t il_lock; /* Protects the critical section. */ - uint64_t il_nexit; /* Counts threads across all CPUs who - * have exited the critical section. - * Access to il_nexit is synchronized - * by il_lock. - */ - percpu_t *il_nenter; /* Counts threads on each CPU who have - * entered or who wait to enter the - * critical section protected by il_lock. - * Synchronization is not required. - */ - kcondvar_t il_emptied; /* The ifnet_lock user must arrange for - * the last threads in the critical - * section to signal this condition variable - * before they leave. - */ -}; -#endif /* _KERNEL */ - /* * Structure defining a queue for a network interface. * @@ -325,13 +296,8 @@ typedef struct ifnet { * same, they are the same ifnet. */ struct sysctllog *if_sysctl_log; - int (*if_initaddr)(struct ifnet *, struct ifaddr *, bool); - int (*if_mcastop)(struct ifnet *, const unsigned long, - const struct sockaddr *); - int (*if_setflags)(struct ifnet *, const short); - struct ifnet_lock *if_ioctl_lock; } ifnet_t; - + #define if_mtu if_data.ifi_mtu #define if_type if_data.ifi_type #define if_addrlen if_data.ifi_addrlen @@ -884,9 +850,6 @@ int ifioctl(struct socket *, u_long, voi int ifioctl_common(struct ifnet *, u_long, void *); int ifpromisc(struct ifnet *, int); struct ifnet *ifunit(const char *); -int if_addr_init(ifnet_t *, struct ifaddr *, bool); -int if_mcast_op(ifnet_t *, const unsigned long, const struct sockaddr *); -int if_flags_set(struct ifnet *, const short); void ifa_insert(struct ifnet *, struct ifaddr *); void ifa_remove(struct ifnet *, struct ifaddr *); Index: net/if_etherip.c =================================================================== RCS file: /cvsroot/src/sys/net/if_etherip.c,v retrieving revision 1.31 diff -u -p -r1.31 if_etherip.c --- net/if_etherip.c 28 Oct 2011 16:10:12 -0000 1.31 +++ net/if_etherip.c 14 Nov 2011 17:59:26 -0000 @@ -100,6 +100,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_etherip.c #include #include #include +#include #include #include #include Index: net/if_gif.c =================================================================== RCS file: /cvsroot/src/sys/net/if_gif.c,v retrieving revision 1.80 diff -u -p -r1.80 if_gif.c --- net/if_gif.c 28 Oct 2011 16:42:52 -0000 1.80 +++ net/if_gif.c 14 Nov 2011 17:59:27 -0000 @@ -48,6 +48,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_gif.c,v 1 #include #include #include +#include #include #include @@ -311,10 +312,6 @@ gif_output(struct ifnet *ifp, struct mbu } *mtod(m, int *) = dst->sa_family; - /* Clear checksum-offload flags. */ - m->m_pkthdr.csum_flags = 0; - m->m_pkthdr.csum_data = 0; - s = splnet(); IFQ_ENQUEUE(&ifp->if_snd, m, &pktattr, error); if (error) { @@ -469,16 +466,36 @@ gif_input(struct mbuf *m, int af, struct int gif_ioctl(struct ifnet *ifp, u_long cmd, void *data) { + struct lwp *l = curlwp; /* XXX */ struct gif_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq*)data; int error = 0, size; struct sockaddr *dst, *src; switch (cmd) { + case SIOCSIFMTU: + case SIOCSLIFPHYADDR: +#ifdef SIOCDIFPHYADDR + case SIOCDIFPHYADDR: +#endif + if ((error = kauth_authorize_network(l->l_cred, + KAUTH_NETWORK_INTERFACE, + KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, (void *)cmd, + NULL)) != 0) + return (error); + /* FALLTHROUGH */ + default: + break; + } + + switch (cmd) { case SIOCINITIFADDR: ifp->if_flags |= IFF_UP; break; + case SIOCSIFDSTADDR: + break; + case SIOCADDMULTI: case SIOCDELMULTI: switch (ifr->ifr_addr.sa_family) { Index: net/if_gre.c =================================================================== RCS file: /cvsroot/src/sys/net/if_gre.c,v retrieving revision 1.148 diff -u -p -r1.148 if_gre.c --- net/if_gre.c 28 Oct 2011 16:42:52 -0000 1.148 +++ net/if_gre.c 14 Nov 2011 17:59:27 -0000 @@ -266,6 +266,14 @@ greintr(void *arg) /* Caller must hold sc->sc_mtx. */ static void +gre_wait(struct gre_softc *sc) +{ + sc->sc_waiters++; + cv_wait(&sc->sc_condvar, &sc->sc_mtx); + sc->sc_waiters--; +} + +static void gre_fp_wait(struct gre_softc *sc) { sc->sc_fp_waiters++; @@ -354,6 +362,7 @@ gre_clone_create(struct if_clone *ifc, i if_attach(&sc->sc_if); if_alloc_sadl(&sc->sc_if); bpf_attach(&sc->sc_if, DLT_NULL, sizeof(uint32_t)); + sc->sc_state = GRE_S_IDLE; return 0; } @@ -369,6 +378,23 @@ gre_clone_destroy(struct ifnet *ifp) s = splnet(); if_detach(ifp); + /* Some LWPs may still wait in gre_ioctl_lock(), however, + * no new LWP will enter gre_ioctl_lock(), because ifunit() + * cannot locate the interface any longer. + */ + mutex_enter(&sc->sc_mtx); + GRE_DPRINTF(sc, "\n"); + while (sc->sc_state != GRE_S_IDLE) + gre_wait(sc); + GRE_DPRINTF(sc, "\n"); + sc->sc_state = GRE_S_DIE; + cv_broadcast(&sc->sc_condvar); + while (sc->sc_waiters > 0) + cv_wait(&sc->sc_condvar, &sc->sc_mtx); + /* At this point, no other LWP will access the gre_softc, so + * we can release the mutex. + */ + mutex_exit(&sc->sc_mtx); GRE_DPRINTF(sc, "\n"); /* Note that we must not hold the mutex while we call gre_reconf(). */ gre_reconf(sc, NULL); @@ -993,10 +1019,6 @@ gre_output(struct ifnet *ifp, struct mbu ifp->if_opackets++; ifp->if_obytes += m->m_pkthdr.len; - /* Clear checksum-offload flags. */ - m->m_pkthdr.csum_flags = 0; - m->m_pkthdr.csum_data = 0; - /* send it off */ if ((error = gre_bufq_enqueue(&sc->sc_snd, m)) != 0) { sc->sc_oflow_ev.ev_count++; @@ -1220,6 +1242,39 @@ gre_clearconf(struct gre_soparm *sp, boo } static int +gre_ioctl_lock(struct gre_softc *sc) +{ + mutex_enter(&sc->sc_mtx); + + while (sc->sc_state == GRE_S_IOCTL) + gre_wait(sc); + + if (sc->sc_state != GRE_S_IDLE) { + cv_signal(&sc->sc_condvar); + mutex_exit(&sc->sc_mtx); + GRE_DPRINTF(sc, "\n"); + return ENXIO; + } + + sc->sc_state = GRE_S_IOCTL; + + mutex_exit(&sc->sc_mtx); + return 0; +} + +static void +gre_ioctl_unlock(struct gre_softc *sc) +{ + mutex_enter(&sc->sc_mtx); + + KASSERT(sc->sc_state == GRE_S_IOCTL); + sc->sc_state = GRE_S_IDLE; + cv_signal(&sc->sc_condvar); + + mutex_exit(&sc->sc_mtx); +} + +static int gre_ioctl(struct ifnet *ifp, const u_long cmd, void *data) { struct ifreq *ifr; @@ -1234,11 +1289,15 @@ gre_ioctl(struct ifnet *ifp, const u_lon GRE_DPRINTF(sc, "cmd %lu\n", cmd); switch (cmd) { + case SIOCSIFFLAGS: + case SIOCSIFMTU: case GRESPROTO: case GRESADDRD: case GRESADDRS: case GRESSOCK: case GREDSOCK: + case SIOCSLIFPHYADDR: + case SIOCDIFPHYADDR: if (kauth_authorize_network(curlwp->l_cred, KAUTH_NETWORK_INTERFACE, KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, (void *)cmd, @@ -1249,6 +1308,10 @@ gre_ioctl(struct ifnet *ifp, const u_lon break; } + if ((error = gre_ioctl_lock(sc)) != 0) { + GRE_DPRINTF(sc, "\n"); + return error; + } s = splnet(); sp0 = sc->sc_soparm; @@ -1265,6 +1328,8 @@ gre_ioctl(struct ifnet *ifp, const u_lon gre_clearconf(sp, false); ifp->if_flags |= IFF_UP; goto mksocket; + case SIOCSIFDSTADDR: + break; case SIOCSIFFLAGS: if ((error = ifioctl_common(ifp, cmd, data)) != 0) break; @@ -1484,6 +1549,7 @@ gre_ioctl(struct ifnet *ifp, const u_lon out: GRE_DPRINTF(sc, "\n"); splx(s); + gre_ioctl_unlock(sc); return error; } Index: net/if_ppp.c =================================================================== RCS file: /cvsroot/src/sys/net/if_ppp.c,v retrieving revision 1.136 diff -u -p -r1.136 if_ppp.c --- net/if_ppp.c 28 Oct 2011 22:08:14 -0000 1.136 +++ net/if_ppp.c 14 Nov 2011 17:59:27 -0000 @@ -734,6 +734,7 @@ pppioctl(struct ppp_softc *sc, u_long cm static int pppsioctl(struct ifnet *ifp, u_long cmd, void *data) { + struct lwp *l = curlwp; /* XXX */ struct ppp_softc *sc = ifp->if_softc; struct ifaddr *ifa = (struct ifaddr *)data; struct ifreq *ifr = (struct ifreq *)data; @@ -767,6 +768,22 @@ pppsioctl(struct ifnet *ifp, u_long cmd, } break; + case SIOCSIFDSTADDR: + switch (ifa->ifa_addr->sa_family) { +#ifdef INET + case AF_INET: + break; +#endif +#ifdef INET6 + case AF_INET6: + break; +#endif + default: + error = EAFNOSUPPORT; + break; + } + break; + case SIOCADDMULTI: case SIOCDELMULTI: if (ifr == NULL) { @@ -817,6 +834,12 @@ pppsioctl(struct ifnet *ifp, u_long cmd, break; #endif /* PPP_COMPRESS */ + case SIOCSIFMTU: + if ((error = kauth_authorize_network(l->l_cred, + KAUTH_NETWORK_INTERFACE, KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, + ifp, (void *)cmd, NULL)) != 0) + break; + /*FALLTHROUGH*/ default: if ((error = ifioctl_common(&sc->sc_if, cmd, data)) == ENETRESET) error = 0; Index: net/if_spppsubr.c =================================================================== RCS file: /cvsroot/src/sys/net/if_spppsubr.c,v retrieving revision 1.123 diff -u -p -r1.123 if_spppsubr.c --- net/if_spppsubr.c 28 Oct 2011 22:08:14 -0000 1.123 +++ net/if_spppsubr.c 14 Nov 2011 17:59:28 -0000 @@ -1045,6 +1045,7 @@ sppp_ioctl(struct ifnet *ifp, u_long cmd s = splnet(); switch (cmd) { + case SIOCSIFDSTADDR: case SIOCINITIFADDR: break; Index: net/if_srt.c =================================================================== RCS file: /cvsroot/src/sys/net/if_srt.c,v retrieving revision 1.17 diff -u -p -r1.17 if_srt.c --- net/if_srt.c 28 Oct 2011 22:08:14 -0000 1.17 +++ net/if_srt.c 14 Nov 2011 17:59:30 -0000 @@ -150,6 +150,7 @@ srt_if_ioctl(struct ifnet *ifp, u_long c s = splnet(); switch (cmd) { case SIOCINITIFADDR: + case SIOCSIFDSTADDR: ifa = (void *) data; switch (ifa->ifa_addr->sa_family) { #ifdef INET @@ -164,6 +165,7 @@ srt_if_ioctl(struct ifnet *ifp, u_long c err = EAFNOSUPPORT; break; } + /* XXX do we need to do more here for either of these? */ break; default: if ((err = ifioctl_common(ifp, cmd, data)) == ENETRESET) Index: net/if_stf.c =================================================================== RCS file: /cvsroot/src/sys/net/if_stf.c,v retrieving revision 1.77 diff -u -p -r1.77 if_stf.c --- net/if_stf.c 28 Oct 2011 20:13:32 -0000 1.77 +++ net/if_stf.c 14 Nov 2011 17:59:30 -0000 @@ -90,6 +90,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_stf.c,v 1 #include #include #include +#include #include @@ -660,6 +661,7 @@ stf_rtrequest(int cmd, struct rtentry *r static int stf_ioctl(struct ifnet *ifp, u_long cmd, void *data) { + struct lwp *l = curlwp; /* XXX */ struct ifaddr *ifa; struct ifreq *ifr = data; struct sockaddr_in6 *sin6; @@ -692,6 +694,12 @@ stf_ioctl(struct ifnet *ifp, u_long cmd, break; case SIOCSIFMTU: + error = kauth_authorize_network(l->l_cred, + KAUTH_NETWORK_INTERFACE, + KAUTH_REQ_NETWORK_INTERFACE_SETPRIV, ifp, KAUTH_ARG(cmd), + NULL); + if (error) + break; if (ifr->ifr_mtu < STF_MTU_MIN || ifr->ifr_mtu > STF_MTU_MAX) return EINVAL; else if ((error = ifioctl_common(ifp, cmd, data)) == ENETRESET) Index: net/if_tun.c =================================================================== RCS file: /cvsroot/src/sys/net/if_tun.c,v retrieving revision 1.114 diff -u -p -r1.114 if_tun.c --- net/if_tun.c 28 Oct 2011 22:08:14 -0000 1.114 +++ net/if_tun.c 14 Nov 2011 17:59:30 -0000 @@ -442,6 +442,10 @@ tun_ioctl(struct ifnet *ifp, u_long cmd, tuninit(tp); TUNDEBUG("%s: address set\n", ifp->if_xname); break; + case SIOCSIFDSTADDR: + tuninit(tp); + TUNDEBUG("%s: destination address set\n", ifp->if_xname); + break; case SIOCSIFBRDADDR: TUNDEBUG("%s: broadcast address set\n", ifp->if_xname); break; Index: net/if_vlan.c =================================================================== RCS file: /cvsroot/src/sys/net/if_vlan.c,v retrieving revision 1.69 diff -u -p -r1.69 if_vlan.c --- net/if_vlan.c 19 Oct 2011 22:07:09 -0000 1.69 +++ net/if_vlan.c 14 Nov 2011 17:59:30 -0000 @@ -286,7 +286,11 @@ vlan_config(struct ifvlan *ifv, struct i */ ec->ec_capenable |= ETHERCAP_VLAN_MTU; if (p->if_flags & IFF_UP) { - error = if_flags_set(p, p->if_flags); + struct ifreq ifr; + + ifr.ifr_flags = p->if_flags; + error = (*p->if_ioctl)(p, SIOCSIFFLAGS, + (void *) &ifr); if (error) { if (ec->ec_nvlans-- == 1) ec->ec_capenable &= @@ -378,8 +382,11 @@ vlan_unconfig(struct ifnet *ifp) */ ec->ec_capenable &= ~ETHERCAP_VLAN_MTU; if (ifv->ifv_p->if_flags & IFF_UP) { - (void)if_flags_set(ifv->ifv_p, - ifv->ifv_p->if_flags); + struct ifreq ifr; + + ifr.ifr_flags = ifv->ifv_p->if_flags; + (void) (*ifv->ifv_p->if_ioctl)(ifv->ifv_p, + SIOCSIFFLAGS, (void *) &ifr); } } @@ -462,6 +469,24 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd s = splnet(); switch (cmd) { + case SIOCINITIFADDR: + if (ifv->ifv_p != NULL) { + ifp->if_flags |= IFF_UP; + + switch (ifa->ifa_addr->sa_family) { +#ifdef INET + case AF_INET: + arp_ifinit(ifp, ifa); + break; +#endif + default: + break; + } + } else { + error = EINVAL; + } + break; + case SIOCSIFMTU: if (ifv->ifv_p == NULL) error = EINVAL; @@ -544,19 +569,6 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd if ((error = ifioctl_common(ifp, cmd, data)) == ENETRESET) error = 0; break; - case SIOCINITIFADDR: - if (ifv->ifv_p == NULL) { - error = EINVAL; - break; - } - - ifp->if_flags |= IFF_UP; -#ifdef INET - if (ifa->ifa_addr->sa_family == AF_INET) - arp_ifinit(ifp, ifa); -#endif - break; - default: error = ether_ioctl(ifp, cmd, data); } @@ -601,7 +613,8 @@ vlan_ether_addmulti(struct ifvlan *ifv, memcpy(&mc->mc_addr, sa, sa->sa_len); LIST_INSERT_HEAD(&ifv->ifv_mc_listhead, mc, mc_entries); - error = if_mcast_op(ifv->ifv_p, SIOCADDMULTI, sa); + error = (*ifv->ifv_p->if_ioctl)(ifv->ifv_p, SIOCADDMULTI, + (void *)ifr); if (error != 0) goto ioctl_failed; return (error); @@ -636,7 +649,8 @@ vlan_ether_delmulti(struct ifvlan *ifv, return (error); /* We no longer use this multicast address. Tell parent so. */ - error = if_mcast_op(ifv->ifv_p, SIOCDELMULTI, sa); + error = (*ifv->ifv_p->if_ioctl)(ifv->ifv_p, SIOCDELMULTI, + (void *)ifr); if (error == 0) { /* And forget about this address. */ for (mc = LIST_FIRST(&ifv->ifv_mc_listhead); mc != NULL; @@ -662,10 +676,20 @@ vlan_ether_purgemulti(struct ifvlan *ifv { struct ifnet *ifp = ifv->ifv_p; /* Parent. */ struct vlan_mc_entry *mc; + union { + struct ifreq ifreq; + struct { + char ifr_name[IFNAMSIZ]; + struct sockaddr_storage ifr_ss; + } ifreq_storage; + } ifreq; + struct ifreq *ifr = &ifreq.ifreq; + memcpy(ifr->ifr_name, ifp->if_xname, IFNAMSIZ); while ((mc = LIST_FIRST(&ifv->ifv_mc_listhead)) != NULL) { - (void)if_mcast_op(ifp, SIOCDELMULTI, + ifreq_setaddr(SIOCDELMULTI, ifr, (const struct sockaddr *)&mc->mc_addr); + (void)(*ifp->if_ioctl)(ifp, SIOCDELMULTI, (void *)ifr); LIST_REMOVE(mc, mc_entries); free(mc, M_DEVBUF); } Index: net/agr/if_agr.c =================================================================== RCS file: /cvsroot/src/sys/net/agr/if_agr.c,v retrieving revision 1.30 diff -u -p -r1.30 if_agr.c --- net/agr/if_agr.c 19 Oct 2011 01:49:50 -0000 1.30 +++ net/agr/if_agr.c 14 Nov 2011 17:59:31 -0000 @@ -235,6 +235,7 @@ agr_vlan_add(struct agr_port *port, void { struct ifnet *ifp = port->port_ifp; struct ethercom *ec_port = (void *)ifp; + struct ifreq ifr; int error=0; if (ec_port->ec_nvlans++ == 0 && @@ -245,7 +246,9 @@ agr_vlan_add(struct agr_port *port, void */ ec_port->ec_capenable |= ETHERCAP_VLAN_MTU; if (p->if_flags & IFF_UP) { - error = if_flags_set(p, p->if_flags); + ifr.ifr_flags = p->if_flags; + error = (*p->if_ioctl)(p, SIOCSIFFLAGS, + (void *) &ifr); if (error) { if (ec_port->ec_nvlans-- == 1) ec_port->ec_capenable &= @@ -265,6 +268,7 @@ static int agr_vlan_del(struct agr_port *port, void *arg) { struct ethercom *ec_port = (void *)port->port_ifp; + struct ifreq ifr; /* Disable vlan support */ if (ec_port->ec_nvlans-- == 1) { @@ -273,8 +277,9 @@ agr_vlan_del(struct agr_port *port, void */ ec_port->ec_capenable &= ~ETHERCAP_VLAN_MTU; if (port->port_ifp->if_flags & IFF_UP) { - (void)if_flags_set(port->port_ifp, - port->port_ifp->if_flags); + ifr.ifr_flags = port->port_ifp->if_flags; + (void) (*port->port_ifp->if_ioctl)(port->port_ifp, + SIOCSIFFLAGS, (void *) &ifr); } } @@ -636,10 +641,10 @@ agr_addport(struct ifnet *ifp, struct if * of each port to that of the first port. No need for arps * since there are no inet addresses assigned to the ports. */ - error = if_addr_init(ifp_port, ifp->if_dl, true); + error = (*ifp_port->if_ioctl)(ifp_port, SIOCINITIFADDR, ifp->if_dl); if (error) { - printf("%s: if_addr_init error %d\n", __func__, error); + printf("%s: SIOCINITIFADDR error %d\n", __func__, error); goto cleanup; } port->port_flags |= AGRPORT_LADDRCHANGED; Index: net/agr/if_agrether.c =================================================================== RCS file: /cvsroot/src/sys/net/agr/if_agrether.c,v retrieving revision 1.9 diff -u -p -r1.9 if_agrether.c --- net/agr/if_agrether.c 19 Oct 2011 01:49:50 -0000 1.9 +++ net/agr/if_agrether.c 14 Nov 2011 17:59:31 -0000 @@ -175,7 +175,9 @@ agrether_portinit(struct agr_softc *sc, */ ec_port->ec_capenable |= ETHERCAP_VLAN_MTU; if (p->if_flags & IFF_UP) { - error = if_flags_set(p, p->if_flags); + ifr.ifr_flags = p->if_flags; + error = (*p->if_ioctl)(p, SIOCSIFFLAGS, + (void *) &ifr); if (error) { if (ec_port->ec_nvlans-- == 1) ec_port->ec_capenable &= @@ -232,8 +234,9 @@ agrether_portfini(struct agr_softc *sc, */ ec_port->ec_capenable &= ~ETHERCAP_VLAN_MTU; if (port->port_ifp->if_flags & IFF_UP) { - (void)if_flags_set(port->port_ifp, - port->port_ifp->if_flags); + ifr.ifr_flags = port->port_ifp->if_flags; + (void) (*port->port_ifp->if_ioctl)(port->port_ifp, + SIOCSIFFLAGS, (void *) &ifr); } } Index: netatalk/at_control.c =================================================================== RCS file: /cvsroot/src/sys/netatalk/at_control.c,v retrieving revision 1.34 diff -u -p -r1.34 at_control.c --- netatalk/at_control.c 19 Oct 2011 01:50:27 -0000 1.34 +++ netatalk/at_control.c 14 Nov 2011 17:59:31 -0000 @@ -575,7 +575,7 @@ at_ifinit(struct ifnet *ifp, struct at_i * Now that we have selected an address, we need to tell the * interface about it, just in case it needs to adjust something. */ - if ((error = if_addr_init(ifp, &aa->aa_ifa, true)) != 0) { + if ((error = (*ifp->if_ioctl)(ifp, SIOCINITIFADDR, aa)) != 0) { /* * of course this could mean that it objects violently * so if it does, we back out again.. Index: netinet/in.c =================================================================== RCS file: /cvsroot/src/sys/netinet/in.c,v retrieving revision 1.140 diff -u -p -r1.140 in.c --- netinet/in.c 28 Oct 2011 22:23:54 -0000 1.140 +++ netinet/in.c 14 Nov 2011 17:59:31 -0000 @@ -352,10 +352,12 @@ in_control(struct socket *so, u_long cmd if ((cmd == SIOCDIFADDR || cmd == SIOCGIFALIAS) && ia == NULL) return (EADDRNOTAVAIL); +#if 1 /*def COMPAT_43*/ if (cmd == SIOCDIFADDR && ifra->ifra_addr.sin_family == AF_UNSPEC) { ifra->ifra_addr.sin_family = AF_INET; } +#endif /* FALLTHROUGH */ case SIOCSIFADDR: case SIOCSIFDSTADDR: @@ -452,7 +454,7 @@ in_control(struct socket *so, u_long cmd return (EINVAL); oldaddr = ia->ia_dstaddr; ia->ia_dstaddr = *satocsin(ifreq_getdstaddr(cmd, ifr)); - if ((error = if_addr_init(ifp, &ia->ia_ifa, false)) != 0) { + if ((error = (*ifp->if_ioctl)(ifp, SIOCSIFDSTADDR, ia)) != 0) { ia->ia_dstaddr = oldaddr; return error; } @@ -811,7 +813,7 @@ in_ifinit(struct ifnet *ifp, struct in_i * if this is its first address, * and to validate the address if necessary. */ - if ((error = if_addr_init(ifp, &ia->ia_ifa, true)) != 0) + if ((error = (*ifp->if_ioctl)(ifp, SIOCINITIFADDR, ia)) != 0) goto bad; splx(s); if (scrub) { @@ -1043,6 +1045,7 @@ in_addmulti(struct in_addr *ap, struct i { struct sockaddr_in sin; struct in_multi *inm; + struct ifreq ifr; int s = splsoftnet(); /* @@ -1075,7 +1078,8 @@ in_addmulti(struct in_addr *ap, struct i * filter appropriately for the new address. */ sockaddr_in_init(&sin, ap, 0); - if (if_mcast_op(ifp, SIOCADDMULTI, sintosa(&sin)) != 0) { + ifreq_setaddr(SIOCADDMULTI, &ifr, sintosa(&sin)); + if ((*ifp->if_ioctl)(ifp, SIOCADDMULTI, &ifr) != 0) { LIST_REMOVE(inm, inm_list); pool_put(&inmulti_pool, inm); splx(s); @@ -1103,6 +1107,7 @@ void in_delmulti(struct in_multi *inm) { struct sockaddr_in sin; + struct ifreq ifr; int s = splsoftnet(); if (--inm->inm_refcount == 0) { @@ -1121,7 +1126,8 @@ in_delmulti(struct in_multi *inm) * filter. */ sockaddr_in_init(&sin, &inm->inm_addr, 0); - if_mcast_op(inm->inm_ifp, SIOCDELMULTI, sintosa(&sin)); + ifreq_setaddr(SIOCDELMULTI, &ifr, sintosa(&sin)); + (*inm->inm_ifp->if_ioctl)(inm->inm_ifp, SIOCDELMULTI, &ifr); pool_put(&inmulti_pool, inm); } splx(s); Index: netinet/ip_carp.c =================================================================== RCS file: /cvsroot/src/sys/netinet/ip_carp.c,v retrieving revision 1.46 diff -u -p -r1.46 ip_carp.c --- netinet/ip_carp.c 19 Oct 2011 01:52:22 -0000 1.46 +++ netinet/ip_carp.c 14 Nov 2011 17:59:32 -0000 @@ -2151,7 +2151,7 @@ carp_ether_addmulti(struct carp_softc *s memcpy(&mc->mc_addr, sa, sa->sa_len); LIST_INSERT_HEAD(&sc->carp_mc_listhead, mc, mc_entries); - error = if_mcast_op(ifp, SIOCADDMULTI, sa); + error = (*ifp->if_ioctl)(ifp, SIOCADDMULTI, ifr); if (error != 0) goto ioctl_failed; @@ -2203,7 +2203,7 @@ carp_ether_delmulti(struct carp_softc *s return (error); /* We no longer use this multicast address. Tell parent so. */ - error = if_mcast_op(ifp, SIOCDELMULTI, sa); + error = (*ifp->if_ioctl)(ifp, SIOCDELMULTI, ifr); if (error == 0) { /* And forget about this address. */ LIST_REMOVE(mc, mc_entries); @@ -2222,12 +2222,22 @@ carp_ether_purgemulti(struct carp_softc { struct ifnet *ifp = sc->sc_carpdev; /* Parent. */ struct carp_mc_entry *mc; + union { + struct ifreq ifreq; + struct { + char ifr_name[IFNAMSIZ]; + struct sockaddr_storage ifr_ss; + } ifreq_storage; + } u; + struct ifreq *ifr = &u.ifreq; if (ifp == NULL) return; + memcpy(ifr->ifr_name, ifp->if_xname, IFNAMSIZ); while ((mc = LIST_FIRST(&sc->carp_mc_listhead)) != NULL) { - (void)if_mcast_op(ifp, SIOCDELMULTI, sstosa(&mc->mc_addr)); + memcpy(&ifr->ifr_addr, &mc->mc_addr, mc->mc_addr.ss_len); + (void)(*ifp->if_ioctl)(ifp, SIOCDELMULTI, ifr); LIST_REMOVE(mc, mc_entries); free(mc, M_DEVBUF); } Index: netinet/ip_mroute.c =================================================================== RCS file: /cvsroot/src/sys/netinet/ip_mroute.c,v retrieving revision 1.121 diff -u -p -r1.121 ip_mroute.c --- netinet/ip_mroute.c 19 Oct 2011 01:52:22 -0000 1.121 +++ netinet/ip_mroute.c 14 Nov 2011 17:59:32 -0000 @@ -787,6 +787,7 @@ add_vif(struct vifctl *vifcp) struct vif *vifp; struct ifaddr *ifa; struct ifnet *ifp; + struct ifreq ifr; int error, s; struct sockaddr_in sin; @@ -866,7 +867,8 @@ add_vif(struct vifctl *vifcp) /* Enable promiscuous reception of all IP multicasts. */ sockaddr_in_init(&sin, &zeroin_addr, 0); - error = if_mcast_op(ifp, SIOCADDMULTI, sintosa(&sin)); + ifreq_setaddr(SIOCADDMULTI, &ifr, sintosa(&sin)); + error = (*ifp->if_ioctl)(ifp, SIOCADDMULTI, &ifr); if (error) return (error); } @@ -924,6 +926,7 @@ reset_vif(struct vif *vifp) { struct mbuf *m, *n; struct ifnet *ifp; + struct ifreq ifr; struct sockaddr_in sin; callout_stop(&vifp->v_repq_ch); @@ -948,8 +951,9 @@ reset_vif(struct vif *vifp) #endif } else { sockaddr_in_init(&sin, &zeroin_addr, 0); + ifreq_setaddr(SIOCDELMULTI, &ifr, sintosa(&sin)); ifp = vifp->v_ifp; - if_mcast_op(ifp, SIOCDELMULTI, sintosa(&sin)); + (*ifp->if_ioctl)(ifp, SIOCDELMULTI, &ifr); } memset((void *)vifp, 0, sizeof(*vifp)); } Index: netinet6/in6.c =================================================================== RCS file: /cvsroot/src/sys/netinet6/in6.c,v retrieving revision 1.158 diff -u -p -r1.158 in6.c --- netinet6/in6.c 19 Oct 2011 01:53:07 -0000 1.158 +++ netinet6/in6.c 14 Nov 2011 17:59:32 -0000 @@ -1753,8 +1753,8 @@ in6_ifinit(struct ifnet *ifp, struct in6 ia->ia_addr = *sin6; - if (ifacount <= 1 && - (error = if_addr_init(ifp, &ia->ia_ifa, true)) != 0) { + if (ifacount <= 1 && + (error = (*ifp->if_ioctl)(ifp, SIOCINITIFADDR, ia)) != 0) { splx(s); return error; } Index: netinet6/ip6_mroute.c =================================================================== RCS file: /cvsroot/src/sys/netinet6/ip6_mroute.c,v retrieving revision 1.102 diff -u -p -r1.102 ip6_mroute.c --- netinet6/ip6_mroute.c 19 Oct 2011 01:53:07 -0000 1.102 +++ netinet6/ip6_mroute.c 14 Nov 2011 17:59:32 -0000 @@ -512,7 +512,7 @@ ip6_mrouter_done(void) mifi_t mifi; int i; struct ifnet *ifp; - struct sockaddr_in6 sin6; + struct in6_ifreq ifr; struct mf6c *rt; struct rtdetq *rte; int s; @@ -538,11 +538,10 @@ ip6_mrouter_done(void) for (mifi = 0; mifi < nummifs; mifi++) { if (mif6table[mifi].m6_ifp && !(mif6table[mifi].m6_flags & MIFF_REGISTER)) { - sin6.sin6_family = AF_INET6; - sin6.sin6_addr = in6addr_any; + ifr.ifr_addr.sin6_family = AF_INET6; + ifr.ifr_addr.sin6_addr= in6addr_any; ifp = mif6table[mifi].m6_ifp; - if_mcast_op(ifp, SIOCDELMULTI, - sin6tocsa(&sin6)); + (*ifp->if_ioctl)(ifp, SIOCDELMULTI, &ifr); } } } @@ -644,7 +643,7 @@ add_m6if(struct mif6ctl *mifcp) { struct mif6 *mifp; struct ifnet *ifp; - struct sockaddr_in6 sin6; + struct in6_ifreq ifr; int error, s; #ifdef notyet struct tbf *m_tbf = tbftable + mifcp->mif6c_mifi; @@ -687,9 +686,9 @@ add_m6if(struct mif6ctl *mifcp) * Enable promiscuous reception of all IPv6 multicasts * from the interface. */ - sin6.sin6_family = AF_INET6; - sin6.sin6_addr = in6addr_any; - error = if_mcast_op(ifp, SIOCADDMULTI, sin6tosa(&sin6)); + ifr.ifr_addr.sin6_family = AF_INET6; + ifr.ifr_addr.sin6_addr = in6addr_any; + error = (*ifp->if_ioctl)(ifp, SIOCADDMULTI, &ifr); splx(s); if (error) return error; @@ -732,7 +731,7 @@ del_m6if(mifi_t *mifip) struct mif6 *mifp = mif6table + *mifip; mifi_t mifi; struct ifnet *ifp; - struct sockaddr_in6 sin6; + struct in6_ifreq ifr; int s; if (*mifip >= nummifs) @@ -749,9 +748,9 @@ del_m6if(mifi_t *mifip) */ ifp = mifp->m6_ifp; - sin6.sin6_family = AF_INET6; - sin6.sin6_addr = in6addr_any; - if_mcast_op(ifp, SIOCDELMULTI, sin6tosa(&sin6)); + ifr.ifr_addr.sin6_family = AF_INET6; + ifr.ifr_addr.sin6_addr = in6addr_any; + (*ifp->if_ioctl)(ifp, SIOCDELMULTI, &ifr); } else { if (reg_mif_num != (mifi_t)-1) { if_detach(&multicast_register_if6); Index: netinet6/mld6.c =================================================================== RCS file: /cvsroot/src/sys/netinet6/mld6.c,v retrieving revision 1.54 diff -u -p -r1.54 mld6.c --- netinet6/mld6.c 19 Oct 2011 01:53:07 -0000 1.54 +++ netinet6/mld6.c 14 Nov 2011 17:59:33 -0000 @@ -616,7 +616,7 @@ in6_addmulti(struct in6_addr *maddr6, st int *errorp, int timer) { struct in6_ifaddr *ia; - struct sockaddr_in6 sin6; + struct in6_ifreq ifr; struct in6_multi *in6m; int s = splsoftnet(); @@ -663,8 +663,8 @@ in6_addmulti(struct in6_addr *maddr6, st * Ask the network driver to update its multicast reception * filter appropriately for the new address. */ - sockaddr_in6_init(&sin6, maddr6, 0, 0, 0); - *errorp = if_mcast_op(ifp, SIOCADDMULTI, sin6tosa(&sin6)); + sockaddr_in6_init(&ifr.ifr_addr, maddr6, 0, 0, 0); + *errorp = (*ifp->if_ioctl)(ifp, SIOCADDMULTI, &ifr); if (*errorp) { LIST_REMOVE(in6m, in6m_entry); free(in6m, M_IPMADDR); @@ -700,7 +700,7 @@ in6_addmulti(struct in6_addr *maddr6, st void in6_delmulti(struct in6_multi *in6m) { - struct sockaddr_in6 sin6; + struct in6_ifreq ifr; struct in6_ifaddr *ia; int s = splsoftnet(); @@ -738,8 +738,8 @@ in6_delmulti(struct in6_multi *in6m) * Notify the network driver to update its multicast * reception filter. */ - sockaddr_in6_init(&sin6, &in6m->in6m_addr, 0, 0, 0); - if_mcast_op(in6m->in6m_ifp, SIOCDELMULTI, sin6tosa(&sin6)); + sockaddr_in6_init(&ifr.ifr_addr, &in6m->in6m_addr, 0, 0, 0); + (*in6m->in6m_ifp->if_ioctl)(in6m->in6m_ifp, SIOCDELMULTI, &ifr); callout_destroy(&in6m->in6m_timer_ch); free(in6m, M_IPMADDR); } Index: netiso/iso.c =================================================================== RCS file: /cvsroot/src/sys/netiso/iso.c,v retrieving revision 1.58 diff -u -p -r1.58 iso.c --- netiso/iso.c 19 Oct 2011 01:53:35 -0000 1.58 +++ netiso/iso.c 14 Nov 2011 17:59:33 -0000 @@ -649,7 +649,7 @@ iso_ifinit(struct ifnet *ifp, struct iso * if this is its first address, * and to validate the address if necessary. */ - if ((error = if_addr_init(ifp, &ia->ia_ifa, true)) != 0) { + if ((error = (*ifp->if_ioctl)(ifp, SIOCINITIFADDR, ia)) != 0) { splx(s); ia->ia_addr = oldaddr; return (error); Index: netiso/iso_snpac.c =================================================================== RCS file: /cvsroot/src/sys/netiso/iso_snpac.c,v retrieving revision 1.54 diff -u -p -r1.54 iso_snpac.c --- netiso/iso_snpac.c 19 Oct 2011 01:53:35 -0000 1.54 +++ netiso/iso_snpac.c 14 Nov 2011 17:59:33 -0000 @@ -275,18 +275,18 @@ iso_setmcasts(struct ifnet *ifp, int req { static const char * const addrlist[] = {all_es_snpa, all_is_snpa, all_l1is_snpa, all_l2is_snpa, 0}; - struct sockaddr sa; + struct ifreq ifr; const char *const *cpp; - (void)memset(&sa, 0, sizeof(sa)); + (void)memset(&ifr, 0, sizeof(ifr)); for (cpp = addrlist; *cpp; cpp++) { - (void)memcpy(sa.sa_data, *cpp, 6); + (void)memcpy(ifr.ifr_addr.sa_data, *cpp, 6); if (req == RTM_ADD && - if_mcast_op(ifp, SIOCADDMULTI, &sa) != 0) + (*ifp->if_ioctl)(ifp, SIOCADDMULTI, &ifr) != 0) printf("iso_setmcasts: %s unable to add mcast\n", ifp->if_xname); else if (req == RTM_DELETE && - if_mcast_op(ifp, SIOCDELMULTI, &sa) != 0) + (*ifp->if_ioctl)(ifp, SIOCDELMULTI, &ifr) != 0) printf("iso_setmcasts: %s unable to delete mcast\n", ifp->if_xname); }