Index: if.c =================================================================== RCS file: /cvs/src/sys/net/if.c,v retrieving revision 1.571 diff -u -p -r1.571 if.c --- if.c 9 Jan 2019 01:14:21 -0000 1.571 +++ if.c 23 Feb 2019 09:06:27 -0000 @@ -738,7 +738,7 @@ if_enqueue_ifq(struct ifnet *ifp, struct void if_input(struct ifnet *ifp, struct mbuf_list *ml) { - ifiq_input(&ifp->if_rcv, ml, 2048); + ifiq_input(&ifp->if_rcv, ml); } int @@ -895,11 +895,29 @@ if_ih_remove(struct ifnet *ifp, int (*in } void -if_input_process(struct ifnet *ifp, struct mbuf_list *ml) +if_input_ih(struct ifnet *ifp, struct mbuf *m) { - struct mbuf *m; struct ifih *ifih; struct srp_ref sr; + + /* + * 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); +} + +void +if_input_process(struct ifnet *ifp, struct mbuf_list *ml) +{ + struct mbuf *m; int s; if (ml_empty(ml)) @@ -922,22 +940,32 @@ if_input_process(struct ifnet *ifp, stru */ NET_RLOCK(); 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); + while ((m = ml_dequeue(ml)) != NULL) + if_input_ih(ifp, m); + splx(s); + NET_RUNLOCK(); +} + +void +if_vinput(struct ifnet *ifp, struct mbuf *m) +{ +#if NBPFILTER > 0 + caddr_t if_bpf = ifp->if_bpf; +#endif + + m->m_pkthdr.ph_ifidx = ifp->if_index; + m->m_pkthdr.ph_rtableid = ifp->if_rdomain; - if (ifih == NULL) +#if NBPFILTER > 0 + if (if_bpf) { + if (bpf_mtap_ether(if_bpf, m, BPF_DIRECTION_OUT)) { m_freem(m); + return; + } } - splx(s); - NET_RUNLOCK(); +#endif + + if_input_ih(ifp, m); } void Index: if_var.h =================================================================== RCS file: /cvs/src/sys/net/if_var.h,v retrieving revision 1.94 diff -u -p -r1.94 if_var.h --- if_var.h 9 Jan 2019 01:14:21 -0000 1.94 +++ if_var.h 23 Feb 2019 09:06:27 -0000 @@ -334,6 +334,7 @@ void if_start(struct ifnet *); int if_enqueue(struct ifnet *, struct mbuf *); int if_enqueue_ifq(struct ifnet *, struct mbuf *); void if_input(struct ifnet *, struct mbuf_list *); +void if_vinput(struct ifnet *, struct mbuf *); void if_input_process(struct ifnet *, struct mbuf_list *); int if_input_local(struct ifnet *, struct mbuf *, sa_family_t); int if_output_local(struct ifnet *, struct mbuf *, sa_family_t); Index: if_vlan.c =================================================================== RCS file: /cvs/src/sys/net/if_vlan.c,v retrieving revision 1.183 diff -u -p -r1.183 if_vlan.c --- if_vlan.c 15 Feb 2019 13:00:51 -0000 1.183 +++ if_vlan.c 23 Feb 2019 09:06:27 -0000 @@ -342,12 +342,12 @@ int vlan_input(struct ifnet *ifp0, struct mbuf *m, void *cookie) { struct ifvlan *ifv; + struct ifnet *ifp; struct ether_vlan_header *evl; struct ether_header *eh; SRPL_HEAD(, ifvlan) *tagh, *list; struct srp_ref sr; u_int tag; - struct mbuf_list ml = MBUF_LIST_INITIALIZER(); u_int16_t etype; eh = mtod(m, struct ether_header *); @@ -359,7 +359,6 @@ vlan_input(struct ifnet *ifp0, struct mb } else if ((etype == ETHERTYPE_VLAN) || (etype == ETHERTYPE_QINQ)) { if (m->m_len < sizeof(*evl) && (m = m_pullup(m, sizeof(*evl))) == NULL) { - ifp0->if_ierrors++; return (1); } @@ -373,12 +372,6 @@ vlan_input(struct ifnet *ifp0, struct mb /* 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); - - /* IEEE 802.1p has prio 0 and 1 swapped */ - if (m->m_pkthdr.pf.prio <= 1) - m->m_pkthdr.pf.prio = !m->m_pkthdr.pf.prio; - list = &tagh[TAG_HASH(tag)]; SRPL_FOREACH(ifv, &sr, list, ifv_list) { if (ifp0->if_index == ifv->ifv_ifidx0 && tag == ifv->ifv_tag && @@ -386,14 +379,18 @@ vlan_input(struct ifnet *ifp0, struct mb break; } - if (ifv == NULL) { - ifp0->if_noproto++; - goto drop; + if (ifv == NULL || !ISSET(ifv->ifv_if.if_flags, IFF_RUNNING)) { + SRPL_LEAVE(&sr); + m_freem(m); + return (1); } - if ((ifv->ifv_if.if_flags & (IFF_UP|IFF_RUNNING)) != - (IFF_UP|IFF_RUNNING)) - goto drop; + /* The packet is ours now */ + + m->m_pkthdr.pf.prio = EVL_PRIOFTAG(m->m_pkthdr.ether_vtag); + /* IEEE 802.1p has prio 0 and 1 swapped */ + if (m->m_pkthdr.pf.prio <= 1) + m->m_pkthdr.pf.prio = !m->m_pkthdr.pf.prio; /* * Having found a valid vlan interface corresponding to @@ -403,19 +400,17 @@ vlan_input(struct ifnet *ifp0, struct mb if (m->m_flags & M_VLANTAG) { m->m_flags &= ~M_VLANTAG; } else { - eh->ether_type = evl->evl_proto; - memmove((char *)eh + EVL_ENCAPLEN, eh, sizeof(*eh)); + memmove((char *)evl + EVL_ENCAPLEN, evl, + offsetof(struct ether_vlan_header, evl_encap_proto)); m_adj(m, EVL_ENCAPLEN); } - ml_enqueue(&ml, m); - if_input(&ifv->ifv_if, &ml); - SRPL_LEAVE(&sr); - return (1); + ifp = &ifv->ifv_if; + counters_pkt(ifp->if_counters, + ifc_ipackets, ifc_ibytes, m->m_pkthdr.len); -drop: + if_vinput(ifp, m); SRPL_LEAVE(&sr); - m_freem(m); return (1); } Index: ifq.c =================================================================== RCS file: /cvs/src/sys/net/ifq.c,v retrieving revision 1.25 diff -u -p -r1.25 ifq.c --- ifq.c 16 Dec 2018 03:36:02 -0000 1.25 +++ ifq.c 23 Feb 2019 09:06:27 -0000 @@ -467,17 +467,20 @@ ifiq_destroy(struct ifiqueue *ifiq) ml_purge(&ifiq->ifiq_ml); } +unsigned int ifiq_pressure_drop = 4; +unsigned int ifiq_pressure_report = 2; + int -ifiq_input(struct ifiqueue *ifiq, struct mbuf_list *ml, unsigned int cwm) +ifiq_input(struct ifiqueue *ifiq, struct mbuf_list *ml) { struct ifnet *ifp = ifiq->ifiq_if; struct mbuf *m; uint64_t packets; uint64_t bytes = 0; + unsigned int pressure; #if NBPFILTER > 0 caddr_t if_bpf; #endif - int rv = 1; if (ml_empty(ml)) return (0); @@ -518,12 +521,11 @@ ifiq_input(struct ifiqueue *ifiq, struct ifiq->ifiq_packets += packets; ifiq->ifiq_bytes += bytes; - if (ifiq_len(ifiq) >= cwm * 5) + pressure = ++ifiq->ifiq_pressure; + if (pressure > ifiq_pressure_drop) ifiq->ifiq_qdrops += ml_len(ml); - else { - rv = (ifiq_len(ifiq) >= cwm * 3); + else ml_enlist(&ifiq->ifiq_ml, ml); - } mtx_leave(&ifiq->ifiq_mtx); if (ml_empty(ml)) @@ -531,7 +533,7 @@ ifiq_input(struct ifiqueue *ifiq, struct else ml_purge(ml); - return (rv); + return (pressure > ifiq_pressure_report); } void @@ -573,6 +575,7 @@ ifiq_process(void *arg) return; mtx_enter(&ifiq->ifiq_mtx); + ifiq->ifiq_pressure = 0; ml = ifiq->ifiq_ml; ml_init(&ifiq->ifiq_ml); mtx_leave(&ifiq->ifiq_mtx); Index: ifq.h =================================================================== RCS file: /cvs/src/sys/net/ifq.h,v retrieving revision 1.22 diff -u -p -r1.22 ifq.h --- ifq.h 11 Dec 2018 01:36:42 -0000 1.22 +++ ifq.h 23 Feb 2019 09:06:27 -0000 @@ -80,6 +80,7 @@ struct ifiqueue { struct mutex ifiq_mtx; struct mbuf_list ifiq_ml; struct task ifiq_task; + unsigned int ifiq_pressure; /* counters */ uint64_t ifiq_packets; @@ -473,8 +474,7 @@ ifq_idx(struct ifqueue *ifq, unsigned in void ifiq_init(struct ifiqueue *, struct ifnet *, unsigned int); void ifiq_destroy(struct ifiqueue *); -int ifiq_input(struct ifiqueue *, struct mbuf_list *, - unsigned int); +int ifiq_input(struct ifiqueue *, struct mbuf_list *); int ifiq_enqueue(struct ifiqueue *, struct mbuf *); void ifiq_add_data(struct ifiqueue *, struct if_data *); void ifiq_barrier(struct ifiqueue *);