Index: net/if.c =================================================================== RCS file: /cvs/src/sys/net/if.c,v retrieving revision 1.520 diff -u -p -r1.520 if.c --- net/if.c 26 Oct 2017 15:13:40 -0000 1.520 +++ net/if.c 31 Oct 2017 06:58:47 -0000 @@ -234,12 +234,27 @@ struct task if_input_task_locked = TASK_ */ struct rwlock netlock = RWLOCK_INITIALIZER("netlock"); +static void +net_peg(void *null) +{ + CPU_INFO_ITERATOR cii; + struct cpu_info *ci; + + CPU_INFO_FOREACH(cii, ci) { + if (CPU_INFO_UNIT(ci) == 2) { + //sched_peg_curproc(ci); + return; + } + } +} + /* * Network interface utility routines. */ void ifinit(void) { + static struct task t = TASK_INITIALIZER(net_peg, NULL); /* * most machines boot with 4 or 5 interfaces, so size the initial map * to accomodate this @@ -252,6 +267,8 @@ ifinit(void) if (softnettq == NULL) panic("unable to create softnet taskq"); + task_add(softnettq, &t); + net_tick(&net_tick_to); } @@ -428,8 +445,6 @@ if_attachsetup(struct ifnet *ifp) ifidx = ifp->if_index; - mq_init(&ifp->if_inputqueue, 8192, IPL_NET); - task_set(ifp->if_inputtask, if_input_process, (void *)ifidx); task_set(ifp->if_watchdogtask, if_watchdog_task, (void *)ifidx); task_set(ifp->if_linkstatetask, if_linkstate_task, (void *)ifidx); @@ -596,11 +611,7 @@ if_attach_common(struct ifnet *ifp) M_TEMP, M_WAITOK|M_ZERO); ifp->if_linkstatetask = malloc(sizeof(*ifp->if_linkstatetask), M_TEMP, M_WAITOK|M_ZERO); - ifp->if_inputtask = malloc(sizeof(*ifp->if_inputtask), - M_TEMP, M_WAITOK|M_ZERO); ifp->if_llprio = IFQ_DEFPRIO; - - SRPL_INIT(&ifp->if_inputs); } void @@ -637,7 +648,7 @@ if_qstart_compat(struct ifqueue *ifq) * this provides compatability between the stack and the older * drivers by translating from the only queue they have * (ifp->if_snd) back to the interface and calling if_start. - */ + */ KERNEL_LOCK(); s = splnet(); @@ -677,11 +688,98 @@ if_enqueue(struct ifnet *ifp, struct mbu if (error) return (error); - ifq_start(ifq); + if (ifq_len(ifq) >= 4) { + task_del(softnettq, &ifq->ifq_bundle); + ifq_start(ifq); + } else + task_add(softnettq, &ifq->ifq_bundle); return (0); } +struct net_proc { + struct mbuf_queue n_q; + struct task n_task; +}; + +struct net_proc if_input_proc = { + MBUF_QUEUE_INITIALIZER(8192, IPL_NET), + TASK_INITIALIZER(if_input_process, &if_input_proc), +}; + +void +if_input_process(void *arg) +{ + struct net_proc *net_proc = arg; + struct mbuf_list ml; + struct srp_ref sr; + struct ifnet *ifp; + struct mbuf *m; + int s; +#ifdef IPSEC + int locked = 0; + extern int ipsec_in_use; +#endif /* IPSEC */ + + mq_delist(&net_proc->n_q, &ml); + if (ml_empty(&ml)) + return; + + add_net_randomness(ml_len(&ml)); + +#ifdef IPSEC + if (ipsec_in_use) { + KERNEL_LOCK(); + locked = 1; + } +#endif + + NET_LOCK(); + s = splnet(); + + while ((m = ml_dequeue(&ml)) != NULL) { + ifp = if_enter(&sr, m->m_pkthdr.ph_ifidx); + if (ifp != NULL) + ifp->if_input(&ml, ifp, m); + else + m_freem(m); + if_leave(&sr); + } + + splx(s); + NET_UNLOCK(); + +#ifdef IPSEC + if (locked) + KERNEL_UNLOCK(); +#endif +} + +void +if_input_m(struct mbuf_list *ml, struct ifnet *ifp, struct mbuf *m) +{ +#if NBPFILTER > 0 + caddr_t if_bpf; +#endif + + m->m_pkthdr.ph_ifidx = ifp->if_index; + m->m_pkthdr.ph_rtableid = ifp->if_rdomain; + + ifp->if_ipackets++; + ifp->if_ibytes += m->m_pkthdr.len; + +#if NBPFILTER > 0 + if_bpf = ifp->if_bpf; + if (if_bpf) { + if (bpf_mtap_ether(if_bpf, m, BPF_DIRECTION_IN)) { + m_freem(m); + return; + } + } +#endif + ml_enqueue(ml, m); +} + void if_input(struct ifnet *ifp, struct mbuf_list *ml) { @@ -706,10 +804,8 @@ if_input(struct ifnet *ifp, struct mbuf_ #if NBPFILTER > 0 if_bpf = ifp->if_bpf; if (if_bpf) { - struct mbuf_list ml0; + struct mbuf_list ml0 = *ml; - ml_init(&ml0); - ml_enlist(&ml0, ml); ml_init(ml); while ((m = ml_dequeue(&ml0)) != NULL) { @@ -724,8 +820,23 @@ if_input(struct ifnet *ifp, struct mbuf_ } #endif - if (mq_enlist(&ifp->if_inputqueue, ml) == 0) - task_add(softnettq, ifp->if_inputtask); + if (mq_enlist(&if_input_proc.n_q, ml) == 0) + task_add(softnettq, &if_input_proc.n_task); +} + +int +if_output_local(struct ifnet *ifp, struct mbuf *m, sa_family_t af) +{ + m->m_pkthdr.ph_family = af; + m->m_pkthdr.ph_ifidx = ifp->if_index; + m->m_pkthdr.ph_rtableid = ifp->if_rdomain; + + if (mq_enqueue(&if_input_proc.n_q, m) == 0) { + task_add(softnettq, &if_input_proc.n_task); + return (0); + } + + return (ENOBUFS); } int @@ -780,145 +891,6 @@ if_input_local(struct ifnet *ifp, struct return (0); } -struct ifih { - SRPL_ENTRY(ifih) ifih_next; - int (*ifih_input)(struct ifnet *, struct mbuf *, - void *); - void *ifih_cookie; - int ifih_refcnt; - struct refcnt ifih_srpcnt; -}; - -void if_ih_ref(void *, void *); -void if_ih_unref(void *, void *); - -struct srpl_rc ifih_rc = SRPL_RC_INITIALIZER(if_ih_ref, if_ih_unref, NULL); - -void -if_ih_insert(struct ifnet *ifp, int (*input)(struct ifnet *, struct mbuf *, - void *), void *cookie) -{ - struct ifih *ifih; - - /* the kernel lock guarantees serialised modifications to if_inputs */ - KERNEL_ASSERT_LOCKED(); - - SRPL_FOREACH_LOCKED(ifih, &ifp->if_inputs, ifih_next) { - if (ifih->ifih_input == input && ifih->ifih_cookie == cookie) { - ifih->ifih_refcnt++; - break; - } - } - - if (ifih == NULL) { - ifih = malloc(sizeof(*ifih), M_DEVBUF, M_WAITOK); - - ifih->ifih_input = input; - ifih->ifih_cookie = cookie; - ifih->ifih_refcnt = 1; - refcnt_init(&ifih->ifih_srpcnt); - SRPL_INSERT_HEAD_LOCKED(&ifih_rc, &ifp->if_inputs, - ifih, ifih_next); - } -} - -void -if_ih_ref(void *null, void *i) -{ - struct ifih *ifih = i; - - refcnt_take(&ifih->ifih_srpcnt); -} - -void -if_ih_unref(void *null, void *i) -{ - struct ifih *ifih = i; - - refcnt_rele_wake(&ifih->ifih_srpcnt); -} - -void -if_ih_remove(struct ifnet *ifp, int (*input)(struct ifnet *, struct mbuf *, - void *), void *cookie) -{ - struct ifih *ifih; - - /* the kernel lock guarantees serialised modifications to if_inputs */ - KERNEL_ASSERT_LOCKED(); - - SRPL_FOREACH_LOCKED(ifih, &ifp->if_inputs, ifih_next) { - if (ifih->ifih_input == input && ifih->ifih_cookie == cookie) - break; - } - - KASSERT(ifih != NULL); - - if (--ifih->ifih_refcnt == 0) { - SRPL_REMOVE_LOCKED(&ifih_rc, &ifp->if_inputs, ifih, - ifih, ifih_next); - - refcnt_finalize(&ifih->ifih_srpcnt, "ifihrm"); - free(ifih, M_DEVBUF, sizeof(*ifih)); - } -} - -void -if_input_process(void *xifidx) -{ - unsigned int ifidx = (unsigned long)xifidx; - struct mbuf_list ml; - struct mbuf *m; - struct ifnet *ifp; - struct ifih *ifih; - struct srp_ref sr; - int s; - - ifp = if_get(ifidx); - if (ifp == NULL) - return; - - mq_delist(&ifp->if_inputqueue, &ml); - if (ml_empty(&ml)) - goto out; - - if (!ISSET(ifp->if_xflags, IFXF_CLONED)) - add_net_randomness(ml_len(&ml)); - - /* - * We grab the NET_LOCK() before processing any packet to - * ensure there's no contention on the routing table lock. - * - * Without it we could race with a userland thread to insert - * a L2 entry in ip{6,}_output(). Such race would result in - * one of the threads sleeping *inside* the IP output path. - * - * Since we have a NET_LOCK() we also use it to serialize access - * to PF globals, pipex globals, unicast and multicast addresses - * lists. - */ - NET_LOCK(); - s = splnet(); - while ((m = ml_dequeue(&ml)) != NULL) { - /* - * Pass this mbuf to all input handlers of its - * interface until it is consumed. - */ - SRPL_FOREACH(ifih, &sr, &ifp->if_inputs, ifih_next) { - if ((*ifih->ifih_input)(ifp, m, ifih->ifih_cookie)) - break; - } - SRPL_LEAVE(&sr); - - if (ifih == NULL) - m_freem(m); - } - splx(s); - NET_UNLOCK(); -out: - if_put(ifp); -} - void if_netisr(void *unused) { @@ -1024,10 +996,6 @@ if_detach(struct ifnet *ifp) ifp->if_ioctl = if_detached_ioctl; ifp->if_watchdog = NULL; - /* Remove the input task */ - task_del(softnettq, ifp->if_inputtask); - mq_purge(&ifp->if_inputqueue); - /* Remove the watchdog timeout & task */ timeout_del(ifp->if_slowtimo); task_del(softnettq, ifp->if_watchdogtask); @@ -1081,7 +1049,6 @@ if_detach(struct ifnet *ifp) free(ifp->if_slowtimo, M_TEMP, sizeof(*ifp->if_slowtimo)); free(ifp->if_watchdogtask, M_TEMP, sizeof(*ifp->if_watchdogtask)); free(ifp->if_linkstatetask, M_TEMP, sizeof(*ifp->if_linkstatetask)); - free(ifp->if_inputtask, M_TEMP, sizeof(*ifp->if_inputtask)); for (i = 0; (dp = domains[i]) != NULL; i++) { if (dp->dom_ifdetach && ifp->if_afdata[dp->dom_family]) @@ -1645,24 +1612,37 @@ ifunit(const char *name) * Map interface index to interface structure pointer. */ struct ifnet * -if_get(unsigned int index) +if_enter(struct srp_ref *sr, unsigned int index) { - struct srp_ref sr; struct if_map *if_map; struct srp *map; struct ifnet *ifp = NULL; - if_map = srp_enter(&sr, &if_idxmap.map); + if_map = srp_enter(sr, &if_idxmap.map); if (index < if_map->limit) { map = (struct srp *)(if_map + 1); - - ifp = srp_follow(&sr, &map[index]); - if (ifp != NULL) { - KASSERT(ifp->if_index == index); - if_ref(ifp); - } + ifp = srp_follow(sr, &map[index]); } - srp_leave(&sr); + + return (ifp); +} + +void +if_leave(struct srp_ref *sr) +{ + srp_leave(sr); +} + +struct ifnet * +if_get(unsigned int index) +{ + struct srp_ref sr; + struct ifnet *ifp; + + ifp = if_enter(&sr, index); + if (ifp != NULL) + if_ref(ifp); + if_leave(&sr); return (ifp); } @@ -2777,11 +2757,24 @@ if_rxr_adjust_cwm(struct if_rxring *rxr) rxr->rxr_adjusted = ticks; } -u_int +void +if_rxr_livelocked(struct if_rxring *rxr) +{ + extern int ticks; + + if (ticks - rxr->rxr_adjusted >= 1) { + if (rxr->rxr_cwm > rxr->rxr_lwm) + rxr->rxr_cwm--; + + rxr->rxr_adjusted = ticks; + } +} + +unsigned int if_rxr_get(struct if_rxring *rxr, u_int max) { extern int ticks; - u_int diff; + unsigned int diff; if (ticks - rxr->rxr_adjusted >= 1) { /* we're free to try for an adjustment */ Index: net/if.h =================================================================== RCS file: /cvs/src/sys/net/if.h,v retrieving revision 1.186 diff -u -p -r1.186 if.h --- net/if.h 24 Jan 2017 10:08:30 -0000 1.186 +++ net/if.h 31 Oct 2017 06:58:47 -0000 @@ -458,6 +458,7 @@ struct if_parent { struct socket; struct ifnet; struct ifq_ops; +struct srp_ref; void if_alloc_sadl(struct ifnet *); void if_free_sadl(struct ifnet *); @@ -482,6 +483,8 @@ int if_addgroup(struct ifnet *, const ch int if_delgroup(struct ifnet *, const char *); void if_group_routechange(struct sockaddr *, struct sockaddr *); struct ifnet *ifunit(const char *); +struct ifnet *if_enter(struct srp_ref *, unsigned int); +void if_leave(struct srp_ref *); struct ifnet *if_get(unsigned int); void if_put(struct ifnet *); void ifnewlladdr(struct ifnet *); Index: net/if_bridge.c =================================================================== RCS file: /cvs/src/sys/net/if_bridge.c,v retrieving revision 1.298 diff -u -p -r1.298 if_bridge.c --- net/if_bridge.c 17 Aug 2017 10:14:08 -0000 1.298 +++ net/if_bridge.c 31 Oct 2017 06:58:47 -0000 @@ -185,6 +185,7 @@ bridge_clone_create(struct if_clone *ifc ifp->if_start = NULL; ifp->if_type = IFT_BRIDGE; ifp->if_hdrlen = ETHER_HDR_LEN; + ifp->if_input = ether_input; if_attach(ifp); if_alloc_sadl(ifp); @@ -194,8 +195,6 @@ bridge_clone_create(struct if_clone *ifc DLT_EN10MB, ETHER_HDR_LEN); #endif - if_ih_insert(ifp, ether_input, NULL); - return (0); } @@ -225,10 +224,6 @@ bridge_clone_destroy(struct ifnet *ifp) /* Undo pseudo-driver changes. */ if_deactivate(ifp); - if_ih_remove(ifp, ether_input, NULL); - - KASSERT(SRPL_EMPTY_LOCKED(&ifp->if_inputs)); - if_detach(ifp); free(sc, M_DEVBUF, sizeof *sc); @@ -247,7 +242,6 @@ bridge_delete(struct bridge_softc *sc, s error = ifpromisc(p->ifp, 0); hook_disestablish(p->ifp->if_detachhooks, p->bif_dhcookie); - if_ih_remove(p->ifp, bridge_input, NULL); TAILQ_REMOVE(&sc->sc_iflist, p, next); bridge_rtdelete(sc, p->ifp, 0); bridge_flushrule(p); @@ -361,7 +355,6 @@ bridge_ioctl(struct ifnet *ifp, u_long c ifs->if_bridgeport = (caddr_t)p; p->bif_dhcookie = hook_establish(ifs->if_detachhooks, 0, bridge_ifdetach, ifs); - if_ih_insert(p->ifp, bridge_input, NULL); TAILQ_INSERT_TAIL(&sc->sc_iflist, p, next); break; case SIOCBRDGDEL: Index: net/if_ethersubr.c =================================================================== RCS file: /cvs/src/sys/net/if_ethersubr.c,v retrieving revision 1.246 diff -u -p -r1.246 if_ethersubr.c --- net/if_ethersubr.c 31 May 2017 05:59:09 -0000 1.246 +++ net/if_ethersubr.c 31 Oct 2017 06:58:47 -0000 @@ -98,16 +98,27 @@ didn't get a copy, you may request one f #include #include #include +#include #if NBPFILTER > 0 #include #endif +#include "vlan.h" +#if NVLAN > 0 +#include +#endif + #include "pppoe.h" #if NPPPOE > 0 #include #endif +#include "carp.h" +#if NCARP > 0 +#include +#endif + #ifdef INET6 #include #include @@ -301,171 +312,118 @@ bad: return (error); } -/* - * Process a received Ethernet packet; - * the packet is in the mbuf chain m without - * the ether header, which is provided separately. - */ -int -ether_input(struct ifnet *ifp, struct mbuf *m, void *cookie) +void +ether_input(struct mbuf_list *ml, struct ifnet *ifp, struct mbuf *m) { - struct ether_header *eh; - struct niqueue *inq; - u_int16_t etype; - int llcfound = 0; - struct llc *l; struct arpcom *ac; -#if NPPPOE > 0 - struct ether_header *eh_tmp; -#endif + struct niqueue *inq; + struct ether_header *eh; + uint16_t etype; - /* Drop short frames */ - if (m->m_len < ETHER_HDR_LEN) - goto dropanyway; + if (m->m_len < sizeof(*eh)) + goto drop; ac = (struct arpcom *)ifp; eh = mtod(m, struct ether_header *); - m_adj(m, ETHER_HDR_LEN); + etype = eh->ether_type; + + if (ISSET(m->m_flags, M_VLANTAG) || + etype == htons(ETHERTYPE_VLAN) || + etype == htons(ETHERTYPE_QINQ)) { +#if NVLAN > 0 + vlan_input(ml, ifp, m); + return; +#else + goto drop; +#endif + } + +#if NCARP > 0 + if (ifp->if_carp && carp_input(ml, ifp, m)) + return; +#endif + + if (memcmp(ac->ac_enaddr, eh->ether_dhost, ETHER_ADDR_LEN) != 0) { + if (!ETHER_IS_MULTICAST(eh->ether_dhost)) + goto drop; - if (ETHER_IS_MULTICAST(eh->ether_dhost)) { /* * If this is not a simplex interface, drop the packet * if it came from us. */ - if ((ifp->if_flags & IFF_SIMPLEX) == 0) { - if (memcmp(ac->ac_enaddr, eh->ether_shost, - ETHER_ADDR_LEN) == 0) { - m_freem(m); - return (1); - } - } + if (!ISSET(ifp->if_flags, IFF_SIMPLEX) && + memcmp(ac->ac_enaddr, eh->ether_shost, + ETHER_ADDR_LEN) == 0) + goto drop; + + SET(m->m_flags, (memcmp(etherbroadcastaddr, eh->ether_dhost, + sizeof(etherbroadcastaddr)) == 0) ? M_BCAST : M_MCAST); - if (memcmp(etherbroadcastaddr, eh->ether_dhost, - sizeof(etherbroadcastaddr)) == 0) - m->m_flags |= M_BCAST; - else - m->m_flags |= M_MCAST; ifp->if_imcasts++; } - /* - * HW vlan tagged packets that were not collected by vlan(4) must - * be dropped now. - */ - if (m->m_flags & M_VLANTAG) { - m_freem(m); - return (1); - } +#if NPPPOE > 0 || defined(PIPEX) + switch (etype) { + case HTON16(ETHERTYPE_PPPOEDISC): + case HTON16(ETHERTYPE_PPPOE): + if (ISSET(m->m_flags, M_MCAST|M_BCAST)) + goto drop; - /* - * If packet is unicast, make sure it is for us. Drop otherwise. - * This check is required in promiscous mode, and for some hypervisors - * where the MAC filter is 'best effort' only. - */ - if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) { - if (memcmp(ac->ac_enaddr, eh->ether_dhost, ETHER_ADDR_LEN)) { - m_freem(m); - return (1); +#ifdef PIPEX + if (pipex_enable) { + struct pipex_session *session; + + if ((session = pipex_pppoe_lookup_session(m)) != NULL) { + pipex_pppoe_input(m, session); + return; + } } +#endif + if (etype == HTON16(ETHERTYPE_PPPOEDISC)) + inq = &pppoediscinq; + else + inq = &pppoeinq; + + niq_enqueue(inq, m); + return; } +#endif - etype = ntohs(eh->ether_type); + m_adj(m, sizeof(*eh)); -decapsulate: switch (etype) { - case ETHERTYPE_IP: + case HTON16(ETHERTYPE_IP): ipv4_input(ifp, m); - return (1); + return; - case ETHERTYPE_ARP: - if (ifp->if_flags & IFF_NOARP) - goto dropanyway; + case HTON16(ETHERTYPE_ARP): + if (ISSET(ifp->if_flags, IFF_NOARP)) + goto drop; arpinput(ifp, m); - return (1); + return; - case ETHERTYPE_REVARP: - if (ifp->if_flags & IFF_NOARP) - goto dropanyway; + case HTON16(ETHERTYPE_REVARP): + if (ISSET(ifp->if_flags, IFF_NOARP)) + goto drop; revarpinput(ifp, m); - return (1); + return; #ifdef INET6 - /* - * Schedule IPv6 software interrupt for incoming IPv6 packet. - */ - case ETHERTYPE_IPV6: + case HTON16(ETHERTYPE_IPV6): ipv6_input(ifp, m); - return (1); + return; #endif /* INET6 */ -#if NPPPOE > 0 || defined(PIPEX) - case ETHERTYPE_PPPOEDISC: - case ETHERTYPE_PPPOE: - if (m->m_flags & (M_MCAST | M_BCAST)) - goto dropanyway; - M_PREPEND(m, sizeof(*eh), M_DONTWAIT); - if (m == NULL) - return (1); - - eh_tmp = mtod(m, struct ether_header *); - /* - * danger! - * eh_tmp and eh may overlap because eh - * is stolen from the mbuf above. - */ - memmove(eh_tmp, eh, sizeof(struct ether_header)); -#ifdef PIPEX - if (pipex_enable) { - struct pipex_session *session; - if ((session = pipex_pppoe_lookup_session(m)) != NULL) { - pipex_pppoe_input(m, session); - return (1); - } - } -#endif - if (etype == ETHERTYPE_PPPOEDISC) - inq = &pppoediscinq; - else - inq = &pppoeinq; - break; -#endif #ifdef MPLS - case ETHERTYPE_MPLS: - case ETHERTYPE_MPLS_MCAST: + case HTON16(ETHERTYPE_MPLS): + case HTON16(ETHERTYPE_MPLS_MCAST): mpls_input(m); - return (1); + return; #endif - default: - if (llcfound || etype > ETHERMTU || - m->m_len < sizeof(struct llc)) - goto dropanyway; - llcfound = 1; - l = mtod(m, struct llc *); - switch (l->llc_dsap) { - case LLC_SNAP_LSAP: - if (l->llc_control == LLC_UI && - l->llc_dsap == LLC_SNAP_LSAP && - l->llc_ssap == LLC_SNAP_LSAP) { - /* SNAP */ - if (m->m_pkthdr.len > etype) - m_adj(m, etype - m->m_pkthdr.len); - m_adj(m, 6); - M_PREPEND(m, sizeof(*eh), M_DONTWAIT); - if (m == NULL) - return (1); - *mtod(m, struct ether_header *) = *eh; - goto decapsulate; - } - default: - goto dropanyway; - } } - niq_enqueue(inq, m); - return (1); -dropanyway: +drop: m_freem(m); - return (1); } /* @@ -528,7 +486,7 @@ ether_ifattach(struct ifnet *ifp) ifp->if_output = ether_output; ifp->if_rtrequest = ether_rtrequest; - if_ih_insert(ifp, ether_input, NULL); + ifp->if_input = ether_input; if (ifp->if_hardmtu == 0) ifp->if_hardmtu = ETHERMTU; @@ -550,9 +508,7 @@ ether_ifdetach(struct ifnet *ifp) /* Undo pseudo-driver changes. */ if_deactivate(ifp); - if_ih_remove(ifp, ether_input, NULL); - - KASSERT(SRPL_EMPTY_LOCKED(&ifp->if_inputs)); + KASSERT(ifp->if_input == ether_input); for (enm = LIST_FIRST(&ac->ac_multiaddrs); enm != NULL; Index: net/if_loop.c =================================================================== RCS file: /cvs/src/sys/net/if_loop.c,v retrieving revision 1.82 diff -u -p -r1.82 if_loop.c --- net/if_loop.c 19 Oct 2017 11:02:42 -0000 1.82 +++ net/if_loop.c 31 Oct 2017 06:58:47 -0000 @@ -143,7 +143,7 @@ int loioctl(struct ifnet *, u_long, caddr_t); void loopattach(int); void lortrequest(struct ifnet *, int, struct rtentry *); -int loinput(struct ifnet *, struct mbuf *, void *); +void loinput(struct mbuf_list *, struct ifnet *, struct mbuf *); int looutput(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); @@ -192,7 +192,7 @@ loop_clone_create(struct if_clone *ifc, #if NBPFILTER > 0 bpfattach(&ifp->if_bpf, ifp, DLT_LOOP, sizeof(u_int32_t)); #endif - if_ih_insert(ifp, loinput, NULL); + ifp->if_input = loinput; return (0); } @@ -202,26 +202,20 @@ loop_clone_destroy(struct ifnet *ifp) if (ifp->if_index == rtable_loindex(ifp->if_rdomain)) return (EPERM); - if_ih_remove(ifp, loinput, NULL); if_detach(ifp); free(ifp, M_DEVBUF, sizeof(*ifp)); return (0); } -int -loinput(struct ifnet *ifp, struct mbuf *m, void *cookie) +void +loinput(struct mbuf_list *ml, struct ifnet *ifp, struct mbuf *m) { - int error; - if ((m->m_flags & M_PKTHDR) == 0) panic("%s: no header mbuf", __func__); - error = if_input_local(ifp, m, m->m_pkthdr.ph_family); - if (error) + if (if_input_local(ifp, m, m->m_pkthdr.ph_family) != 0) ifp->if_ierrors++; - - return (1); } int @@ -241,12 +235,7 @@ looutput(struct ifnet *ifp, struct mbuf if ((m->m_flags & M_LOOP) == 0) return (if_input_local(ifp, m, dst->sa_family)); - m->m_pkthdr.ph_family = dst->sa_family; - if (mq_enqueue(&ifp->if_inputqueue, m)) - return ENOBUFS; - task_add(softnettq, ifp->if_inputtask); - - return (0); + return (if_output_local(ifp, m, dst->sa_family)); } void Index: net/if_mpw.c =================================================================== RCS file: /cvs/src/sys/net/if_mpw.c,v retrieving revision 1.22 diff -u -p -r1.22 if_mpw.c --- net/if_mpw.c 15 May 2017 14:03:53 -0000 1.22 +++ net/if_mpw.c 31 Oct 2017 06:58:47 -0000 @@ -63,7 +63,9 @@ int mpw_ioctl(struct ifnet *, u_long, ca int mpw_output(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); void mpw_start(struct ifnet *); +#if 0 int mpw_input(struct ifnet *, struct mbuf *, void *); +#endif #if NVLAN > 0 struct mbuf *mpw_vlan_handle(struct mbuf *, struct mpw_softc *); #endif /* NVLAN */ @@ -108,8 +110,6 @@ mpw_clone_create(struct if_clone *ifc, i sc->sc_smpls.smpls_len = sizeof(sc->sc_smpls); sc->sc_smpls.smpls_family = AF_MPLS; - if_ih_insert(ifp, mpw_input, NULL); - #if NBPFILTER > 0 bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, ETHER_HDR_LEN); #endif /* NBFILTER */ @@ -129,14 +129,13 @@ mpw_clone_destroy(struct ifnet *ifp) smplstosa(&sc->sc_smpls)); } - if_ih_remove(ifp, mpw_input, NULL); - if_detach(ifp); free(sc, M_DEVBUF, sizeof(*sc)); return (0); } +#if 0 int mpw_input(struct ifnet *ifp, struct mbuf *m, void *cookie) { @@ -144,6 +143,7 @@ mpw_input(struct ifnet *ifp, struct mbuf m_freem(m); return (1); } +#endif int mpw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) Index: net/if_switch.c =================================================================== RCS file: /cvs/src/sys/net/if_switch.c,v retrieving revision 1.20 diff -u -p -r1.20 if_switch.c --- net/if_switch.c 31 May 2017 05:59:09 -0000 1.20 +++ net/if_switch.c 31 Oct 2017 06:58:47 -0000 @@ -543,7 +543,6 @@ switch_port_add(struct switch_softc *sc, swpo->swpo_switch = sc; swpo->swpo_ifindex = ifs->if_index; ifs->if_switchport = (caddr_t)swpo; - if_ih_insert(ifs, switch_input, NULL); swpo->swpo_port_no = swofp_assign_portno(sc, ifs->if_index); swpo->swpo_dhcookie = hook_establish(ifs->if_detachhooks, 0, switch_port_detach, ifs); @@ -615,7 +614,6 @@ switch_port_detach(void *arg) ifp->if_switchport = NULL; hook_disestablish(ifp->if_detachhooks, swpo->swpo_dhcookie); ifpromisc(ifp, 0); - if_ih_remove(ifp, switch_input, NULL); TAILQ_REMOVE(&sc->sc_swpo_list, swpo, swpo_list_next); free(swpo, M_DEVBUF, sizeof(*swpo)); } Index: net/if_switch.h =================================================================== RCS file: /cvs/src/sys/net/if_switch.h,v retrieving revision 1.10 diff -u -p -r1.10 if_switch.h --- net/if_switch.h 20 Nov 2016 12:45:26 -0000 1.10 +++ net/if_switch.h 31 Oct 2017 06:58:47 -0000 @@ -176,6 +176,8 @@ struct switch_port { uint32_t swpo_flags; void *swpo_dhcookie; void (*swop_bk_start)(struct ifnet *); + void (*swpo_if_input)(struct mbuf_list *, + struct ifnet *, struct mbuf *); }; TAILQ_HEAD(switch_fwdp_queue, switch_port); Index: net/if_trunk.c =================================================================== RCS file: /cvs/src/sys/net/if_trunk.c,v retrieving revision 1.134 diff -u -p -r1.134 if_trunk.c --- net/if_trunk.c 14 Aug 2017 08:31:00 -0000 1.134 +++ net/if_trunk.c 31 Oct 2017 06:58:47 -0000 @@ -75,7 +75,7 @@ int trunk_ether_delmulti(struct trunk_s void trunk_ether_purgemulti(struct trunk_softc *); int trunk_ether_cmdmulti(struct trunk_port *, u_long); int trunk_ioctl_allports(struct trunk_softc *, u_long, caddr_t); -int trunk_input(struct ifnet *, struct mbuf *, void *); +void trunk_port_input_m(struct mbuf_list *, struct ifnet *, struct mbuf *); void trunk_start(struct ifnet *); void trunk_init(struct ifnet *); void trunk_stop(struct ifnet *); @@ -331,22 +331,24 @@ trunk_port_create(struct trunk_softc *tr } } - /* Change the interface type */ + tp->tp_if = ifp; + tp->tp_trunk = tr; tp->tp_iftype = ifp->if_type; - ifp->if_type = IFT_IEEE8023ADLAG; - + tp->tp_input = ifp->if_input; tp->tp_ioctl = ifp->if_ioctl; - ifp->if_ioctl = trunk_port_ioctl; - tp->tp_output = ifp->if_output; - ifp->if_output = trunk_port_output; - - tp->tp_if = ifp; - tp->tp_trunk = tr; /* Save port link layer address */ bcopy(((struct arpcom *)ifp)->ac_enaddr, tp->tp_lladdr, ETHER_ADDR_LEN); + ifp->if_trunkport = (caddr_t)tp; + + /* Change the interface type */ + ifp->if_type = IFT_IEEE8023ADLAG; + ifp->if_ioctl = trunk_port_ioctl; + ifp->if_output = trunk_port_output; + ifp->if_input = trunk_port_input_m; + if (SLIST_EMPTY(&tr->tr_ports)) { tr->tr_primary = tp; tp->tp_flags |= TRUNK_PORT_MASTER; @@ -378,9 +380,6 @@ trunk_port_create(struct trunk_softc *tr if (tr->tr_port_create != NULL) error = (*tr->tr_port_create)(tp); - /* Change input handler of the physical interface. */ - if_ih_insert(ifp, trunk_input, tp); - return (error); } @@ -408,9 +407,6 @@ trunk_port_destroy(struct trunk_port *tp struct trunk_port *tp_ptr; struct ifnet *ifp = tp->tp_if; - /* Restore previous input handler. */ - if_ih_remove(ifp, trunk_input, tp); - /* Remove multicast addresses from this port */ trunk_ether_cmdmulti(tp, SIOCDELMULTI); @@ -428,6 +424,7 @@ trunk_port_destroy(struct trunk_port *tp ifp->if_ioctl = tp->tp_ioctl; ifp->if_output = tp->tp_output; + ifp->if_input = tp->tp_input; hook_disestablish(ifp->if_linkstatehooks, tp->lh_cookie); hook_disestablish(ifp->if_detachhooks, tp->dh_cookie); @@ -648,8 +645,6 @@ trunk_ioctl(struct ifnet *ifp, u_long cm * running trunk_input's on this port to finish * granting us an exclusive access to it. */ - SLIST_FOREACH(tp, &tr->tr_ports, tp_entries) - if_ih_remove(tp->tp_if, trunk_input, tp); if (tr->tr_proto != TRUNK_PROTO_NONE) error = tr->tr_detach(tr); if (error != 0) @@ -663,9 +658,6 @@ trunk_ioctl(struct ifnet *ifp, u_long cm tr->tr_proto = trunk_protos[i].ti_proto; if (tr->tr_proto != TRUNK_PROTO_NONE) error = trunk_protos[i].ti_attach(tr); - SLIST_FOREACH(tp, &tr->tr_ports, tp_entries) - if_ih_insert(tp->tp_if, - trunk_input, tp); /* Update trunk capabilities */ tr->tr_capabilities = trunk_capabilities(tr); goto out; @@ -1022,66 +1014,36 @@ trunk_stop(struct ifnet *ifp) (*tr->tr_stop)(tr); } -int -trunk_input(struct ifnet *ifp, struct mbuf *m, void *cookie) +void +trunk_port_input_m(struct mbuf_list *ml, struct ifnet *ifp, struct mbuf *m) { - struct trunk_softc *tr; struct trunk_port *tp; - struct ifnet *trifp = NULL; - struct ether_header *eh; - struct mbuf_list ml = MBUF_LIST_INITIALIZER(); - - eh = mtod(m, struct ether_header *); - if (ETHER_IS_MULTICAST(eh->ether_dhost)) - ifp->if_imcasts++; - - /* Should be checked by the caller */ - if (ifp->if_type != IFT_IEEE8023ADLAG) - goto bad; - - tp = (struct trunk_port *)cookie; - if ((tr = (struct trunk_softc *)tp->tp_trunk) == NULL) - goto bad; + struct trunk_softc *tr; + struct ifnet *trifp; + tp = (struct trunk_port *)ifp->if_trunkport; + tr = (struct trunk_softc *)tp->tp_trunk; trifp = &tr->tr_ac.ac_if; + if (tr->tr_proto == TRUNK_PROTO_NONE) goto bad; - if ((*tr->tr_input)(tr, tp, m)) { + if ((*tr->tr_input)(tr, tp, m) != 0) { /* * We stop here if the packet has been consumed * by the protocol routine. */ - return (1); + return; } - if ((trifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) + if (!ISSET(trifp->if_flags, IFF_RUNNING)) goto bad; - /* - * Drop promiscuously received packets if we are not in - * promiscuous mode. - */ - if (!ETHER_IS_MULTICAST(eh->ether_dhost) && - (ifp->if_flags & IFF_PROMISC) && - (trifp->if_flags & IFF_PROMISC) == 0) { - if (bcmp(&tr->tr_ac.ac_enaddr, eh->ether_dhost, - ETHER_ADDR_LEN)) { - m_freem(m); - return (1); - } - } - - - ml_enqueue(&ml, m); - if_input(trifp, &ml); - return (1); + if_input_m(ml, trifp, m); + return; bad: - if (trifp != NULL) - trifp->if_ierrors++; m_freem(m); - return (1); } int Index: net/if_trunk.h =================================================================== RCS file: /cvs/src/sys/net/if_trunk.h,v retrieving revision 1.25 diff -u -p -r1.25 if_trunk.h --- net/if_trunk.h 23 Sep 2015 12:40:12 -0000 1.25 +++ net/if_trunk.h 31 Oct 2017 06:58:47 -0000 @@ -139,6 +139,7 @@ struct trunk_port { void *dh_cookie; /* if detach hook */ /* Redirected callbacks */ + void (*tp_input)(struct mbuf_list *, struct ifnet *, struct mbuf *); int (*tp_ioctl)(struct ifnet *, u_long, caddr_t); int (*tp_output)(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); Index: net/if_var.h =================================================================== RCS file: /cvs/src/sys/net/if_var.h,v retrieving revision 1.82 diff -u -p -r1.82 if_var.h --- net/if_var.h 12 Oct 2017 09:14:16 -0000 1.82 +++ net/if_var.h 31 Oct 2017 06:58:47 -0000 @@ -75,7 +75,6 @@ struct rtentry; struct timeout; struct ifnet; -struct task; /* * Structure describing a `cloning' interface. @@ -116,6 +115,7 @@ struct ifnet { /* and the entries */ caddr_t if_bpf; /* packet filter structure */ caddr_t if_bridgeport; /* used by bridge ports */ caddr_t if_switchport; /* used by switch ports */ + caddr_t if_trunkport; /* used by trunk ports */ caddr_t if_mcast; /* used by multicast code */ caddr_t if_mcast6; /* used by IPv6 multicast code */ caddr_t if_pf_kif; /* pf interface abstraction */ @@ -140,9 +140,9 @@ struct ifnet { /* and the entries */ struct task *if_linkstatetask; /* task to do route updates */ /* procedure handles */ - struct mbuf_queue if_inputqueue; - struct task *if_inputtask; /* input task */ - SRPL_HEAD(, ifih) if_inputs; /* input routines (dequeue) */ + SRPL_HEAD(, ifih) if_inputs; /* input routines (dequeue) */ + + void (*if_input)(struct mbuf_list *, struct ifnet *, struct mbuf *); /* output routine (enqueue) */ int (*if_output)(struct ifnet *, struct mbuf *, struct sockaddr *, @@ -154,6 +154,7 @@ struct ifnet { /* and the entries */ /* initiate output routine */ void (*if_start)(struct ifnet *); /* ioctl routine */ + void (*if_qstart)(struct ifqueue *); int (*if_ioctl)(struct ifnet *, u_long, caddr_t); /* timer routine */ void (*if_watchdog)(struct ifnet *); @@ -161,9 +162,11 @@ struct ifnet { /* and the entries */ struct ifqueue if_snd; /* transmit queue */ struct ifqueue **if_ifqs; /* pointer to an array of sndqs */ - void (*if_qstart)(struct ifqueue *); unsigned int if_nifqs; + struct ifrqueue **if_ifrqs; + unsigned int if_nifrqs; + struct sockaddr_dl *if_sadl; /* pointer to our sockaddr_dl */ void *if_afdata[AF_MAX]; @@ -304,7 +307,9 @@ void if_start(struct ifnet *); int if_enqueue_try(struct ifnet *, struct mbuf *); int if_enqueue(struct ifnet *, struct mbuf *); void if_input(struct ifnet *, struct mbuf_list *); +void if_input_m(struct mbuf_list *, struct ifnet *, struct mbuf *); int if_input_local(struct ifnet *, struct mbuf *, sa_family_t); +int if_output_local(struct ifnet *, struct mbuf *, sa_family_t); void if_rtrequest_dummy(struct ifnet *, int, struct rtentry *); void p2p_rtrequest(struct ifnet *, int, struct rtentry *); @@ -334,6 +339,7 @@ void if_ih_insert(struct ifnet *, int (* void if_ih_remove(struct ifnet *, int (*)(struct ifnet *, struct mbuf *, void *), void *); +void if_rxr_livelocked(struct if_rxring *); void if_rxr_init(struct if_rxring *, u_int, u_int); u_int if_rxr_get(struct if_rxring *, u_int); Index: net/if_vlan.c =================================================================== RCS file: /cvs/src/sys/net/if_vlan.c,v retrieving revision 1.174 diff -u -p -r1.174 if_vlan.c --- net/if_vlan.c 22 Jun 2017 11:34:51 -0000 1.174 +++ net/if_vlan.c 31 Oct 2017 06:58:47 -0000 @@ -84,7 +84,6 @@ void vlanattach(int count); int vlan_clone_create(struct if_clone *, int); int vlan_clone_destroy(struct ifnet *); -int vlan_input(struct ifnet *, struct mbuf *, void *); void vlan_start(struct ifqueue *ifq); int vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr); @@ -227,14 +226,15 @@ static inline int vlan_mplstunnel(int ifidx) { #if NMPW > 0 + struct srp_ref sr; struct ifnet *ifp; int rv = 0; - ifp = if_get(ifidx); - if (ifp != NULL) { + ifp = if_enter(&sr, ifidx); + if (ifp != NULL) rv = ifp->if_type == IFT_MPLSTUNNEL; - if_put(ifp); - } + if_leave(&sr); + return (rv); #else return (0); @@ -244,6 +244,7 @@ vlan_mplstunnel(int ifidx) void vlan_start(struct ifqueue *ifq) { + struct srp_ref sr; struct ifnet *ifp = ifq->ifq_if; struct ifvlan *ifv; struct ifnet *ifp0; @@ -251,9 +252,8 @@ vlan_start(struct ifqueue *ifq) uint8_t prio; ifv = ifp->if_softc; - ifp0 = if_get(ifv->ifv_ifp0); - if (ifp0 == NULL || (ifp0->if_flags & (IFF_UP|IFF_RUNNING)) != - (IFF_UP|IFF_RUNNING)) { + ifp0 = if_enter(&sr, ifv->ifv_ifp0); + if (ifp0 == NULL || !ISSET(ifp0->if_flags, IFF_RUNNING)) { ifq_purge(ifq); goto leave; } @@ -271,17 +271,10 @@ vlan_start(struct ifqueue *ifq) prio = !prio; /* - * If this packet came from a pseudowire it means it already - * has all tags it needs, so just output it. - */ - if (vlan_mplstunnel(m->m_pkthdr.ph_ifidx)) { - /* NOTHING */ - - /* * If the underlying interface cannot do VLAN tag insertion * itself, create an encapsulation header. */ - } else if ((ifp0->if_capabilities & IFCAP_VLAN_HWTAGGING) && + if ((ifp0->if_capabilities & IFCAP_VLAN_HWTAGGING) && (ifv->ifv_type == ETHERTYPE_VLAN)) { m->m_pkthdr.ether_vtag = ifv->ifv_tag + (prio << EVL_PRIO_BITS); @@ -303,7 +296,7 @@ vlan_start(struct ifqueue *ifq) } leave: - if_put(ifp0); + if_leave(&sr); } struct mbuf * @@ -328,45 +321,40 @@ vlan_inject(struct mbuf *m, uint16_t typ return (m); } -/* - * vlan_input() returns 1 if it has consumed the packet, 0 otherwise. - */ -int -vlan_input(struct ifnet *ifp0, struct mbuf *m, void *cookie) +void +vlan_input(struct mbuf_list *ml, struct ifnet *ifp0, struct mbuf *m) { struct ifvlan *ifv; struct ether_vlan_header *evl; struct ether_header *eh; SRPL_HEAD(, ifvlan) *tagh, *list; struct srp_ref sr; + uint64_t vtag; u_int tag; - struct mbuf_list ml = MBUF_LIST_INITIALIZER(); u_int16_t etype; eh = mtod(m, struct ether_header *); etype = ntohs(eh->ether_type); - if (m->m_flags & M_VLANTAG) { + if (ISSET(m->m_flags, M_VLANTAG)) { etype = ETHERTYPE_VLAN; + vtag = m->m_pkthdr.ether_vtag; tagh = vlan_tagh; - } else if ((etype == ETHERTYPE_VLAN) || (etype == ETHERTYPE_QINQ)) { + } else { if (m->m_len < sizeof(*evl) && (m = m_pullup(m, sizeof(*evl))) == NULL) { ifp0->if_ierrors++; - return (1); + return; } evl = mtod(m, struct ether_vlan_header *); - m->m_pkthdr.ether_vtag = ntohs(evl->evl_tag); + vtag = ntohs(evl->evl_tag); tagh = etype == ETHERTYPE_QINQ ? svlan_tagh : vlan_tagh; - } else { - /* Skip non-VLAN packets. */ - return (0); } /* From now on ether_vtag is fine */ - tag = EVL_VLANOFTAG(m->m_pkthdr.ether_vtag); - m->m_pkthdr.pf.prio = EVL_PRIOFTAG(m->m_pkthdr.ether_vtag); + tag = EVL_VLANOFTAG(vtag); + m->m_pkthdr.pf.prio = EVL_PRIOFTAG(vtag); /* IEEE 802.1p has prio 0 and 1 swapped */ if (m->m_pkthdr.pf.prio <= 1) @@ -374,7 +362,8 @@ vlan_input(struct ifnet *ifp0, struct mb list = &tagh[TAG_HASH(tag)]; SRPL_FOREACH(ifv, &sr, list, ifv_list) { - if (ifp0->if_index == ifv->ifv_ifp0 && tag == ifv->ifv_tag && + if (ifp0->if_index == ifv->ifv_ifp0 && + tag == ifv->ifv_tag && etype == ifv->ifv_type) break; } @@ -384,8 +373,7 @@ vlan_input(struct ifnet *ifp0, struct mb goto drop; } - if ((ifv->ifv_if.if_flags & (IFF_UP|IFF_RUNNING)) != - (IFF_UP|IFF_RUNNING)) + if (!ISSET(ifv->ifv_if.if_flags, IFF_RUNNING)) goto drop; /* @@ -393,23 +381,22 @@ vlan_input(struct ifnet *ifp0, struct mb * the given source interface and vlan tag, remove the * encapsulation. */ - if (m->m_flags & M_VLANTAG) { - m->m_flags &= ~M_VLANTAG; - } else { + if (ISSET(m->m_flags, M_VLANTAG)) + CLR(m->m_flags, M_VLANTAG); + else { eh->ether_type = evl->evl_proto; memmove((char *)eh + EVL_ENCAPLEN, eh, sizeof(*eh)); m_adj(m, EVL_ENCAPLEN); } - ml_enqueue(&ml, m); - if_input(&ifv->ifv_if, &ml); + if_input_m(ml, &ifv->ifv_if, m); + SRPL_LEAVE(&sr); - return (1); + return; drop: SRPL_LEAVE(&sr); m_freem(m); - return (1); } int @@ -433,8 +420,6 @@ vlan_parent_up(struct ifvlan *ifv, struc vlan_multi_apply(ifv, ifp0, SIOCADDMULTI); - if_ih_insert(ifp0, vlan_input, NULL); - return (0); } @@ -552,7 +537,6 @@ vlan_down(struct ifvlan *ifv) ifp0 = if_get(ifv->ifv_ifp0); if (ifp0 != NULL) { - if_ih_remove(ifp0, vlan_input, NULL); if (ISSET(ifv->ifv_flags, IFVF_PROMISC)) ifpromisc(ifp0, 0); vlan_multi_apply(ifv, ifp0, SIOCDELMULTI); Index: net/if_vlan_var.h =================================================================== RCS file: /cvs/src/sys/net/if_vlan_var.h,v retrieving revision 1.37 diff -u -p -r1.37 if_vlan_var.h --- net/if_vlan_var.h 24 Jan 2017 10:08:30 -0000 1.37 +++ net/if_vlan_var.h 31 Oct 2017 06:58:47 -0000 @@ -85,6 +85,7 @@ struct ifvlan { #define IFVF_LLADDR 0x02 /* don't inherit the parents mac */ struct mbuf *vlan_inject(struct mbuf *, uint16_t, uint16_t); +void vlan_input(struct mbuf_list *, struct ifnet *, struct mbuf *); #endif /* _KERNEL */ #endif /* _NET_IF_VLAN_VAR_H_ */ Index: net/ifq.c =================================================================== RCS file: /cvs/src/sys/net/ifq.c,v retrieving revision 1.12 diff -u -p -r1.12 ifq.c --- net/ifq.c 2 Jun 2017 00:07:12 -0000 1.12 +++ net/ifq.c 31 Oct 2017 06:58:47 -0000 @@ -64,6 +64,7 @@ struct priq { void ifq_start_task(void *); void ifq_restart_task(void *); void ifq_barrier_task(void *); +void ifq_bundle_task(void *); #define TASK_ONQUEUE 0x1 @@ -160,6 +161,14 @@ ifq_barrier_task(void *p) wakeup_one(notdone); } +void +ifq_bundle_task(void *p) +{ + struct ifqueue *ifq = p; + + ifq_start(ifq); +} + /* * ifqueue mbuf queue API */ @@ -193,6 +202,8 @@ ifq_init(struct ifqueue *ifq, struct ifn task_set(&ifq->ifq_start, ifq_start_task, ifq); task_set(&ifq->ifq_restart, ifq_restart_task, ifq); + task_set(&ifq->ifq_bundle, ifq_bundle_task, ifq); + if (ifq->ifq_maxlen == 0) ifq_set_maxlen(ifq, IFQ_MAXLEN); @@ -300,9 +311,12 @@ ifq_deq_begin(struct ifqueue *ifq) struct mbuf *m = NULL; void *cookie; + if (ifq_empty(ifq)) + return (NULL); + ifq_deq_enter(ifq); - if (ifq->ifq_len == 0 || - (m = ifq->ifq_ops->ifqop_deq_begin(ifq, &cookie)) == NULL) { + m = ifq->ifq_ops->ifqop_deq_begin(ifq, &cookie); + if (m == NULL) { ifq_deq_leave(ifq); return (NULL); } @@ -317,7 +331,7 @@ ifq_deq_commit(struct ifqueue *ifq, stru { void *cookie; - KASSERT(m != NULL); + KDASSERT(m != NULL); cookie = m->m_pkthdr.ph_cookie; ifq->ifq_ops->ifqop_deq_commit(ifq, m, cookie); @@ -328,7 +342,7 @@ ifq_deq_commit(struct ifqueue *ifq, stru void ifq_deq_rollback(struct ifqueue *ifq, struct mbuf *m) { - KASSERT(m != NULL); + KDASSERT(m != NULL); ifq_deq_leave(ifq); } @@ -337,12 +351,18 @@ struct mbuf * ifq_dequeue(struct ifqueue *ifq) { struct mbuf *m; + void *cookie; - m = ifq_deq_begin(ifq); - if (m == NULL) + if (ifq_empty(ifq)) return (NULL); - ifq_deq_commit(ifq, m); + ifq_deq_enter(ifq); + m = ifq->ifq_ops->ifqop_deq_begin(ifq, &cookie); + if (m != NULL) { + ifq->ifq_ops->ifqop_deq_commit(ifq, m, cookie); + ifq->ifq_len--; + } + ifq_deq_leave(ifq); return (m); } @@ -360,7 +380,7 @@ ifq_purge(struct ifqueue *ifq) ifq->ifq_qdrops += rv; mtx_leave(&ifq->ifq_mtx); - KASSERT(rv == ml_len(&ml)); + KDASSERT(rv == ml_len(&ml)); ml_purge(&ml); @@ -382,7 +402,7 @@ ifq_q_enter(struct ifqueue *ifq, const s void ifq_q_leave(struct ifqueue *ifq, void *q) { - KASSERT(q == ifq->ifq_q); + KDASSERT(q == ifq->ifq_q); mtx_leave(&ifq->ifq_mtx); } @@ -448,7 +468,7 @@ priq_enq(struct ifqueue *ifq, struct mbu unsigned int prio; pq = ifq->ifq_q; - KASSERT(m->m_pkthdr.pf.prio <= IFQ_MAXPRIO); + KDASSERT(m->m_pkthdr.pf.prio <= IFQ_MAXPRIO); /* Find a lower priority queue to drop from */ if (ifq_len(ifq) >= ifq->ifq_maxlen) { @@ -498,7 +518,7 @@ priq_deq_commit(struct ifqueue *ifq, str { struct mbuf_list *pl = cookie; - KASSERT(MBUF_LIST_FIRST(pl) == m); + KDASSERT(MBUF_LIST_FIRST(pl) == m); ml_dequeue(pl); } Index: net/ifq.h =================================================================== RCS file: /cvs/src/sys/net/ifq.h,v retrieving revision 1.13 diff -u -p -r1.13 ifq.h --- net/ifq.h 3 May 2017 20:55:29 -0000 1.13 +++ net/ifq.h 31 Oct 2017 06:58:47 -0000 @@ -62,9 +62,39 @@ struct ifqueue { struct task ifq_start; struct task ifq_restart; + struct task ifq_bundle; + /* properties */ unsigned int ifq_maxlen; unsigned int ifq_idx; +}; + +struct ifrqueue { + struct ifnet *ifrq_if; + union { + void *_ifrq_softc; + struct ifrqueue *_ifrq_ifrqs[1]; + } _ifrq_ptr; +#define ifrq_softc _ifrq_ptr._ifrq_softc +#define ifrq_ifrqs _ifrq_ptr._ifrq_ifrqs + + struct mutex ifrq_mtx; + struct mbuf_list ifrq_list; + struct task ifrq_task; + + /* counters */ + unsigned int ifrq_gen; + + uint64_t ifrq_packets; + uint64_t ifrq_bytes; + uint64_t ifrq_qdrops; + uint64_t ifrq_errors; + uint64_t ifrq_mcasts; + uint64_t ifrq_noproto; + + /* properties */ + unsigned int ifrq_maxlen; + unsigned int ifrq_idx; }; #ifdef _KERNEL Index: net/pf.c =================================================================== RCS file: /cvs/src/sys/net/pf.c,v retrieving revision 1.1042 diff -u -p -r1.1042 pf.c --- net/pf.c 14 Aug 2017 15:58:16 -0000 1.1042 +++ net/pf.c 31 Oct 2017 06:58:47 -0000 @@ -7089,10 +7089,6 @@ pf_ouraddr(struct mbuf *m) if (sk != NULL) { if (sk->inp != NULL) return (1); - - /* If we have linked state keys it is certainly forwarded. */ - if (sk->reverse != NULL) - return (0); } return (-1); Index: net/trunklacp.c =================================================================== RCS file: /cvs/src/sys/net/trunklacp.c,v retrieving revision 1.29 diff -u -p -r1.29 trunklacp.c --- net/trunklacp.c 24 Jan 2017 10:08:30 -0000 1.29 +++ net/trunklacp.c 31 Oct 2017 06:58:47 -0000 @@ -231,16 +231,14 @@ lacp_input(struct trunk_port *tp, struct struct ether_header *eh; u_int8_t subtype; - eh = mtod(m, struct ether_header *); + if (m->m_len < sizeof(*eh)) + goto drop; - if (ntohs(eh->ether_type) == ETHERTYPE_SLOW) { -#if NBPFILTER > 0 - if (tp->tp_if->if_bpf) - bpf_mtap_ether(tp->tp_if->if_bpf, m, BPF_DIRECTION_IN); -#endif + eh = mtod(m, struct ether_header *); + if (eh->ether_type == ntohs(ETHERTYPE_SLOW)) { if (m->m_pkthdr.len < (sizeof(*eh) + sizeof(subtype))) - return (-1); + goto drop; m_copydata(m, sizeof(*eh), sizeof(subtype), &subtype); switch (subtype) { @@ -257,14 +255,16 @@ lacp_input(struct trunk_port *tp, struct * free and return. */ /* This port is joined to the active aggregator */ - if ((lp->lp_state & LACP_STATE_COLLECTING) == 0 || - la == NULL || la != lsc->lsc_active_aggregator) { - m_freem(m); - return (-1); - } + if (!ISSET(lp->lp_state, LACP_STATE_COLLECTING) || + la == NULL || la != lsc->lsc_active_aggregator) + goto drop; /* Not a subtype we are interested in */ return (0); + +drop: + m_freem(m); + return (-1); } void Index: netinet/if_ether.h =================================================================== RCS file: /cvs/src/sys/netinet/if_ether.h,v retrieving revision 1.73 diff -u -p -r1.73 if_ether.h --- netinet/if_ether.h 29 Nov 2016 10:09:57 -0000 1.73 +++ netinet/if_ether.h 31 Oct 2017 06:58:47 -0000 @@ -239,7 +239,7 @@ int ether_multiaddr(struct sockaddr *, u void ether_ifattach(struct ifnet *); void ether_ifdetach(struct ifnet *); int ether_ioctl(struct ifnet *, struct arpcom *, u_long, caddr_t); -int ether_input(struct ifnet *, struct mbuf *, void *); +void ether_input(struct mbuf_list *, struct ifnet *, struct mbuf *); int ether_output(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); void ether_rtrequest(struct ifnet *, int, struct rtentry *); Index: netinet/ip_carp.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_carp.c,v retrieving revision 1.317 diff -u -p -r1.317 ip_carp.c --- netinet/ip_carp.c 16 Oct 2017 13:20:20 -0000 1.317 +++ netinet/ip_carp.c 31 Oct 2017 06:58:47 -0000 @@ -211,7 +211,6 @@ void carp_hmac_generate(struct carp_vhos unsigned char *, u_int8_t); int carp_hmac_verify(struct carp_vhost_entry *, u_int32_t *, unsigned char *); -int carp_input(struct ifnet *, struct mbuf *, void *); void carp_proto_input_c(struct ifnet *, struct mbuf *, struct carp_header *, int, sa_family_t); int carp_proto_input_if(struct ifnet *, struct mbuf **, int *, int); @@ -931,9 +930,6 @@ carpdetach(struct carp_softc *sc) cif = (struct carp_if *)ifp0->if_carp; - /* Restore previous input handler. */ - if_ih_remove(ifp0, carp_input, cif); - if (sc->lh_cookie != NULL) hook_disestablish(ifp0->if_linkstatehooks, sc->lh_cookie); @@ -1402,30 +1398,20 @@ carp_vhe_match(struct carp_softc *sc, ui } int -carp_input(struct ifnet *ifp0, struct mbuf *m, void *cookie) +carp_input(struct mbuf_list *ml, struct ifnet *ifp0, struct mbuf *m) { struct ether_header *eh; - struct mbuf_list ml = MBUF_LIST_INITIALIZER(); struct carp_if *cif; struct carp_softc *sc; struct srp_ref sr; -#if NVLAN > 0 - /* - * If the underlying interface removed the VLAN header itself, - * it's not for us. - */ - if (ISSET(m->m_flags, M_VLANTAG)) - return (0); -#endif + NET_ASSERT_LOCKED(); eh = mtod(m, struct ether_header *); - cif = (struct carp_if *)cookie; KASSERT(cif == (struct carp_if *)ifp0->if_carp); SRPL_FOREACH(sc, &sr, &cif->vhif_vrs, sc_list) { - if ((sc->sc_if.if_flags & (IFF_UP|IFF_RUNNING)) != - (IFF_UP|IFF_RUNNING)) + if (!ISSET(sc->sc_if.if_flags, IFF_RUNNING)) continue; if (carp_vhe_match(sc, eh->ether_dhost)) { @@ -1462,25 +1448,21 @@ carp_input(struct ifnet *ifp0, struct mb SRPL_FOREACH(sc, &sr, &cif->vhif_vrs, sc_list) { struct mbuf *m0; - if (!(sc->sc_if.if_flags & IFF_UP)) + if (!ISSET(sc->sc_if.if_flags, IFF_RUNNING)) continue; m0 = m_dup_pkt(m, ETHER_ALIGN, M_DONTWAIT); if (m0 == NULL) continue; - ml_init(&ml); - ml_enqueue(&ml, m0); - - if_input(&sc->sc_if, &ml); + if_input_m(ml, &sc->sc_if, m0); } SRPL_LEAVE(&sr); return (0); } - ml_enqueue(&ml, m); - if_input(&sc->sc_if, &ml); + if_input_m(ml, &sc->sc_if, m); out: SRPL_LEAVE(&sr); @@ -1780,9 +1762,6 @@ carp_set_ifp(struct carp_softc *sc, stru sc->lh_cookie = hook_establish(ifp0->if_linkstatehooks, 1, carp_carpdev_state, ifp0); - - /* Change input handler of the physical interface. */ - if_ih_insert(ifp0, carp_input, cif); carp_carpdev_state(ifp0); Index: netinet/ip_carp.h =================================================================== RCS file: /cvs/src/sys/netinet/ip_carp.h,v retrieving revision 1.43 diff -u -p -r1.43 ip_carp.h --- netinet/ip_carp.h 30 May 2017 12:09:27 -0000 1.43 +++ netinet/ip_carp.h 31 Oct 2017 06:58:47 -0000 @@ -201,6 +201,7 @@ int carp6_proto_input(struct mbuf **, int carp_iamatch(struct ifnet *); int carp_iamatch6(struct ifnet *); struct ifnet *carp_ourether(void *, u_int8_t *); +int carp_input(struct mbuf_list *, struct ifnet *, struct mbuf *); int carp_output(struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *); int carp_sysctl(int *, u_int, void *, size_t *, void *, size_t); Index: sys/_endian.h =================================================================== RCS file: /cvs/src/sys/sys/_endian.h,v retrieving revision 1.2 diff -u -p -r1.2 _endian.h --- sys/_endian.h 21 Apr 2017 19:04:22 -0000 1.2 +++ sys/_endian.h 31 Oct 2017 06:58:47 -0000 @@ -43,13 +43,14 @@ #define _BIG_ENDIAN 4321 #define _PDP_ENDIAN 3412 +#define __swap16op(_x) \ + (__uint16_t)(((_x) & 0xff) << 8 | ((_x) & 0xff00) >> 8) + #ifdef __GNUC__ #define __swap16gen(x) __statement({ \ __uint16_t __swap16gen_x = (x); \ - \ - (__uint16_t)((__swap16gen_x & 0xff) << 8 | \ - (__swap16gen_x & 0xff00) >> 8); \ + __swap16op(__swap16gen_x); \ }) #define __swap32gen(x) __statement({ \ @@ -168,6 +169,7 @@ #define __htole64(x) ((__uint64_t)(x)) #ifdef _KERNEL +#define __HTON16(x) __swap16op(x) #ifdef __HAVE_MD_SWAPIO #define __bemtoh16(_x) __mswap16(_x) @@ -239,6 +241,11 @@ #define __htolem32(_x, _v) (*(__uint32_t *)(_x) = __htole32(_v)) #define __htolem64(_x, _v) (*(__uint64_t *)(_x) = __htole64(_v)) #endif + +#ifndef __HTON16 +#define __HTON16(x) ((__uint16_t)(x)) +#endif + #endif /* _KERNEL */ #endif /* _SYS__ENDIAN_H_ */ Index: sys/endian.h =================================================================== RCS file: /cvs/src/sys/sys/endian.h,v retrieving revision 1.25 diff -u -p -r1.25 endian.h --- sys/endian.h 21 Dec 2014 04:49:00 -0000 1.25 +++ sys/endian.h 31 Oct 2017 06:58:47 -0000 @@ -119,6 +119,8 @@ #define htolem16 __htolem16 #define htolem32 __htolem32 #define htolem64 __htolem64 + +#define HTON16 __HTON16 #endif /* _KERNEL */ #endif /* _SYS_ENDIAN_H_ */