Applied. I don’t see any regressions so far. I use bridge+vether. //mxb
> On 28 apr 2015, at 23:06, Martin Pieuchot <m...@openbsd.org> wrote: > > On 21/04/15(Tue) 12:35, Martin Pieuchot wrote: >> This diff adds the necessary glue to bridge(4) to be able to convert >> other pseudo-drivers to if_input(). This will also help bridge(4)'s >> own conversion. >> >> Since bridge_input() already returns a mbuf, I believe this change is >> less error prone than the carp(4) one. But I appreciate reviews, >> tests and oks. > > Anybody? > >> >> Index: net/bridgestp.c >> =================================================================== >> RCS file: /cvs/src/sys/net/bridgestp.c,v >> retrieving revision 1.52 >> diff -u -p -r1.52 bridgestp.c >> --- net/bridgestp.c 14 Mar 2015 03:38:51 -0000 1.52 >> +++ net/bridgestp.c 20 Apr 2015 11:35:56 -0000 >> @@ -596,6 +596,9 @@ bstp_input(struct bstp_state *bs, struct >> len = ntohs(eh->ether_type); >> if (len < sizeof(tpdu)) >> goto out; >> + >> + m_adj(m, ETHER_HDR_LEN); >> + >> if (m->m_pkthdr.len > len) >> m_adj(m, len - m->m_pkthdr.len); >> if ((m = m_pullup(m, sizeof(tpdu))) == NULL) >> Index: net/if_bridge.c >> =================================================================== >> RCS file: /cvs/src/sys/net/if_bridge.c,v >> retrieving revision 1.235 >> diff -u -p -r1.235 if_bridge.c >> --- net/if_bridge.c 17 Apr 2015 11:04:01 -0000 1.235 >> +++ net/if_bridge.c 20 Apr 2015 11:55:38 -0000 >> @@ -115,10 +115,9 @@ void bridge_broadcast(struct bridge_soft >> struct ether_header *, struct mbuf *); >> void bridge_localbroadcast(struct bridge_softc *, struct ifnet *, >> struct ether_header *, struct mbuf *); >> -void bridge_span(struct bridge_softc *, struct ether_header *, >> - struct mbuf *); >> +void bridge_span(struct bridge_softc *, struct mbuf *); >> struct mbuf *bridge_dispatch(struct bridge_iflist *, struct ifnet *, >> - struct ether_header *, struct mbuf *); >> + struct mbuf *); >> void bridge_stop(struct bridge_softc *); >> void bridge_init(struct bridge_softc *); >> int bridge_bifconf(struct bridge_softc *, struct ifbifconf *); >> @@ -180,6 +179,7 @@ int >> bridge_clone_create(struct if_clone *ifc, int unit) >> { >> struct bridge_softc *sc; >> + struct ifih *bridge_ifih; >> struct ifnet *ifp; >> int i, s; >> >> @@ -187,8 +187,15 @@ bridge_clone_create(struct if_clone *ifc >> if (!sc) >> return (ENOMEM); >> >> + bridge_ifih = malloc(sizeof(*bridge_ifih), M_DEVBUF, M_NOWAIT); >> + if (bridge_ifih == NULL) { >> + free(sc, M_DEVBUF, 0); >> + return (ENOMEM); >> + } >> + >> sc->sc_stp = bstp_create(&sc->sc_if); >> if (!sc->sc_stp) { >> + free(bridge_ifih, M_DEVBUF, sizeof(*bridge_ifih)); >> free(sc, M_DEVBUF, 0); >> return (ENOMEM); >> } >> @@ -222,6 +229,9 @@ bridge_clone_create(struct if_clone *ifc >> DLT_EN10MB, ETHER_HDR_LEN); >> #endif >> >> + bridge_ifih->ifih_input = ether_input; >> + SLIST_INSERT_HEAD(&ifp->if_inputs, bridge_ifih, ifih_next); >> + >> s = splnet(); >> LIST_INSERT_HEAD(&bridge_list, sc, sc_list); >> splx(s); >> @@ -234,6 +244,7 @@ bridge_clone_destroy(struct ifnet *ifp) >> { >> struct bridge_softc *sc = ifp->if_softc; >> struct bridge_iflist *bif; >> + struct ifih *bridge_ifih; >> int s; >> >> bridge_stop(sc); >> @@ -250,6 +261,17 @@ bridge_clone_destroy(struct ifnet *ifp) >> splx(s); >> >> bstp_destroy(sc->sc_stp); >> + >> + /* Undo pseudo-driver changes. */ >> + if_deactivate(ifp); >> + >> + bridge_ifih = SLIST_FIRST(&ifp->if_inputs); >> + SLIST_REMOVE_HEAD(&ifp->if_inputs, ifih_next); >> + >> + KASSERT(SLIST_EMPTY(&ifp->if_inputs)); >> + >> + free(bridge_ifih, M_DEVBUF, sizeof(*bridge_ifih)); >> + >> if_detach(ifp); >> >> free(sc, M_DEVBUF, 0); >> @@ -990,7 +1012,7 @@ bridge_output(struct ifnet *ifp, struct >> struct mbuf *mc; >> int used = 0; >> >> - bridge_span(sc, NULL, m); >> + bridge_span(sc, m); >> >> TAILQ_FOREACH(p, &sc->sc_iflist, next) { >> dst_if = p->ifp; >> @@ -1066,7 +1088,7 @@ sendunicast: >> (sa = bridge_tunneltag(m, dst_p->brt_tunnel.sa.sa_family)) != NULL) >> memcpy(sa, &dst_p->brt_tunnel.sa, dst_p->brt_tunnel.sa.sa_len); >> >> - bridge_span(sc, NULL, m); >> + bridge_span(sc, m); >> if ((dst_if->if_flags & IFF_RUNNING) == 0) { >> m_freem(m); >> return (ENETDOWN); >> @@ -1282,12 +1304,13 @@ bridgeintr_frame(struct bridge_softc *sc >> * not for us, and schedule an interrupt. >> */ >> struct mbuf * >> -bridge_input(struct ifnet *ifp, struct ether_header *eh, struct mbuf *m) >> +bridge_input(struct ifnet *ifp, struct ether_header *eh0, struct mbuf *m) >> { >> struct bridge_softc *sc; >> struct bridge_iflist *ifl; >> + struct ether_header *eh; >> #if NVLAN > 0 >> - uint16_t etype = ntohs(eh->ether_type); >> + uint16_t etype = ntohs(eh0->ether_type); >> #endif /* NVLAN > 0 */ >> >> /* >> @@ -1306,15 +1329,20 @@ bridge_input(struct ifnet *ifp, struct e >> if ((sc->sc_if.if_flags & IFF_RUNNING) == 0) >> return (m); >> >> + M_PREPEND(m, sizeof(*eh), M_DONTWAIT); >> + if (m == NULL) >> + return (NULL); >> + eh = mtod(m, struct ether_header *); >> + memmove(eh, eh0, sizeof(*eh)); >> + >> #if NBPFILTER > 0 >> if (sc->sc_if.if_bpf) >> - bpf_mtap_hdr(sc->sc_if.if_bpf, (caddr_t)eh, >> - ETHER_HDR_LEN, m, BPF_DIRECTION_IN, NULL); >> + bpf_mtap_ether(sc->sc_if.if_bpf, m, BPF_DIRECTION_IN); >> #endif >> >> - bridge_span(sc, eh, m); >> + bridge_span(sc, m); >> >> - m = bridge_dispatch(ifl, ifp, eh, m); >> + m = bridge_dispatch(ifl, ifp, m); >> >> #if NVLAN > 0 >> if ((m != NULL) && ((m->m_flags & M_VLANTAG) || >> @@ -1330,15 +1358,17 @@ bridge_input(struct ifnet *ifp, struct e >> } >> >> struct mbuf * >> -bridge_dispatch(struct bridge_iflist *ifl, struct ifnet *ifp, >> - struct ether_header *eh, struct mbuf *m) >> +bridge_dispatch(struct bridge_iflist *ifl, struct ifnet *ifp, struct mbuf >> *m) >> { >> struct bridge_softc *sc = ifl->bridge_sc; >> struct bridge_iflist *srcifl; >> + struct ether_header *eh; >> struct arpcom *ac; >> struct mbuf *mc; >> int s; >> >> + eh = mtod(m, struct ether_header *); >> + >> if (m->m_flags & (M_BCAST | M_MCAST)) { >> /* >> * Reserved destination MAC addresses (01:80:C2:00:00:0x) >> @@ -1367,18 +1397,9 @@ bridge_dispatch(struct bridge_iflist *if >> (ifl->bif_state == BSTP_IFSTATE_DISCARDING)) >> return (m); >> >> - /* >> - * make a copy of 'm' with 'eh' tacked on to the >> - * beginning. Return 'm' for local processing >> - * and enqueue the copy. Schedule netisr. >> - */ >> mc = m_copym2(m, 0, M_COPYALL, M_NOWAIT); >> if (mc == NULL) >> return (m); >> - M_PREPEND(mc, ETHER_HDR_LEN, M_DONTWAIT); >> - if (mc == NULL) >> - return (m); >> - bcopy(eh, mtod(mc, caddr_t), ETHER_HDR_LEN); >> s = splnet(); >> if (IF_QFULL(&sc->sc_if.if_snd)) { >> m_freem(mc); >> @@ -1398,11 +1419,11 @@ bridge_dispatch(struct bridge_iflist *if >> m->m_pkthdr.ph_rtableid = ifl->ifp->if_rdomain; >> #if NBPFILTER > 0 >> if (ifl->ifp->if_bpf) >> - bpf_mtap(ifl->ifp->if_bpf, m, >> + bpf_mtap_ether(ifl->ifp->if_bpf, m, >> BPF_DIRECTION_IN); >> #endif >> m->m_flags |= M_PROTO1; >> - ether_input(m, eh); >> + ether_input_mbuf(ifl->ifp, m); >> ifl->ifp->if_ipackets++; >> m = NULL; >> } >> @@ -1445,21 +1466,21 @@ bridge_dispatch(struct bridge_iflist *if >> * is aware */ >> #if NBPFILTER > 0 >> if (ifl->ifp->if_bpf) >> - bpf_mtap_hdr(ifl->ifp->if_bpf, (caddr_t)eh, >> - ETHER_HDR_LEN, m, BPF_DIRECTION_IN, NULL); >> + bpf_mtap_ether(ifl->ifp->if_bpf, m, >> + BPF_DIRECTION_IN); >> #endif >> /* Count for the interface we are going to */ >> ifl->ifp->if_ipackets++; >> >> /* Count for the bridge */ >> sc->sc_if.if_ipackets++; >> - sc->sc_if.if_ibytes += ETHER_HDR_LEN + m->m_pkthdr.len; >> + sc->sc_if.if_ibytes += m->m_pkthdr.len; >> >> m->m_pkthdr.rcvif = ifl->ifp; >> m->m_pkthdr.ph_rtableid = ifl->ifp->if_rdomain; >> if (ifp->if_type == IFT_GIF) { >> m->m_flags |= M_PROTO1; >> - ether_input(m, eh); >> + ether_input_mbuf(ifl->ifp, m); >> m = NULL; >> } >> return (m); >> @@ -1474,10 +1495,6 @@ bridge_dispatch(struct bridge_iflist *if >> return (NULL); >> } >> } >> - M_PREPEND(m, ETHER_HDR_LEN, M_DONTWAIT); >> - if (m == NULL) >> - return (NULL); >> - bcopy(eh, mtod(m, caddr_t), ETHER_HDR_LEN); >> s = splnet(); >> if (IF_QFULL(&sc->sc_if.if_snd)) { >> m_freem(m); >> @@ -1635,13 +1652,12 @@ bridge_localbroadcast(struct bridge_soft >> BPF_DIRECTION_IN); >> #endif >> >> - ether_input(m1, NULL); >> + ether_input_mbuf(ifp, m1); >> ifp->if_ipackets++; >> } >> >> void >> -bridge_span(struct bridge_softc *sc, struct ether_header *eh, >> - struct mbuf *morig) >> +bridge_span(struct bridge_softc *sc, struct mbuf *morig) >> { >> struct bridge_iflist *p; >> struct ifnet *ifp; >> @@ -1654,12 +1670,6 @@ bridge_span(struct bridge_softc *sc, str >> m = m_copym2(morig, 0, M_COPYALL, M_NOWAIT); >> if (m == NULL) >> return; >> - if (eh != NULL) { >> - M_PREPEND(m, ETHER_HDR_LEN, M_DONTWAIT); >> - if (m == NULL) >> - return; >> - bcopy(eh, mtod(m, caddr_t), ETHER_HDR_LEN); >> - } >> >> TAILQ_FOREACH(p, &sc->sc_spanlist, next) { >> ifp = p->ifp; >> Index: net/if_ethersubr.c >> =================================================================== >> RCS file: /cvs/src/sys/net/if_ethersubr.c,v >> retrieving revision 1.194 >> diff -u -p -r1.194 if_ethersubr.c >> --- net/if_ethersubr.c 13 Apr 2015 08:52:51 -0000 1.194 >> +++ net/if_ethersubr.c 20 Apr 2015 11:35:56 -0000 >> @@ -559,6 +559,7 @@ ether_input(struct mbuf *m, void *hdr) >> return (1); >> /* The bridge has determined it's for us. */ >> ifp = m->m_pkthdr.rcvif; >> + m_adj(m, ETHER_HDR_LEN); >> } >> } >> #endif >> >