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
>> 
> 


Reply via email to