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 22 Feb 2019 02:13:03 -0000 @@ -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_one(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,20 +940,8 @@ 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); - - if (ifih == NULL) - m_freem(m); - } + while ((m = ml_dequeue(ml)) != NULL) + if_input_one(ifp, m); splx(s); NET_RUNLOCK(); } 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 22 Feb 2019 02:13:03 -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_input_one(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 22 Feb 2019 02:13:03 -0000 @@ -342,13 +342,16 @@ 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; +#if NBPFILTER > 0 + caddr_t if_bpf; +#endif eh = mtod(m, struct ether_header *); etype = ntohs(eh->ether_type); @@ -359,7 +362,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 +375,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 && @@ -395,6 +391,8 @@ vlan_input(struct ifnet *ifp0, struct mb (IFF_UP|IFF_RUNNING)) goto drop; + /* The packet is ours now */ + /* * Having found a valid vlan interface corresponding to * the given source interface and vlan tag, remove the @@ -403,13 +401,34 @@ 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); + ifp = &ifv->ifv_if; + counters_pkt(ifp->if_counters, + ifc_ipackets, ifc_ibytes, m->m_pkthdr.len); + + m->m_pkthdr.ph_ifidx = ifp->if_index; + m->m_pkthdr.ph_rtableid = ifp->if_rdomain; + 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; + +#if NBPFILTER > 0 + if_bpf = ifp->if_bpf; + if (if_bpf) { + if (bpf_mtap_ether(if_bpf, m, BPF_DIRECTION_OUT)) { + m_freem(m); + goto leave; + } + } +#endif + + if_input_one(ifp, m); +leave: SRPL_LEAVE(&sr); return (1);