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