On 17/06/15(Wed) 14:07, Martin Pieuchot wrote:
> On 08/06/15(Mon) 15:58, Martin Pieuchot wrote:
> > Diff below moves bridge_output() to if_output().  It fixes the case I
> > already described some weeks ago where you have a physical interface
> > in a bridge and a vlan on top of it which is not in the bridge.
> > 
> > It also change the loop prevention code to use M_PROTO1 like in the
> > input path.
> > 
> > Tests, comments and oks welcome.
> 
> Updated diff to match the recent if_get() change.  I've got one positive
> report so far, any ok?

I'm still looking for oks.

> 
> Index: net/if.c
> ===================================================================
> RCS file: /cvs/src/sys/net/if.c,v
> retrieving revision 1.340
> diff -u -p -r1.340 if.c
> --- net/if.c  16 Jun 2015 11:09:39 -0000      1.340
> +++ net/if.c  17 Jun 2015 12:01:12 -0000
> @@ -449,6 +449,19 @@ if_output(struct ifnet *ifp, struct mbuf
>       int s, length, error = 0;
>       unsigned short mflags;
>  
> +#ifdef DIAGNOSTIC
> +     if (ifp->if_rdomain != rtable_l2(m->m_pkthdr.ph_rtableid)) {
> +             printf("%s: trying to send packet on wrong domain. "
> +                 "if %d vs. mbuf %d\n", ifp->if_xname, ifp->if_rdomain,
> +                 rtable_l2(m->m_pkthdr.ph_rtableid));
> +     }
> +#endif
> +
> +#if NBRIDGE > 0
> +     if (ifp->if_bridgeport && (m->m_flags & M_PROTO1) == 0)
> +             return (bridge_output(ifp, m, NULL, NULL));
> +#endif
> +
>       length = m->m_pkthdr.len;
>       mflags = m->m_flags;
>  
> Index: net/if_bridge.c
> ===================================================================
> RCS file: /cvs/src/sys/net/if_bridge.c,v
> retrieving revision 1.244
> diff -u -p -r1.244 if_bridge.c
> --- net/if_bridge.c   16 Jun 2015 11:09:39 -0000      1.244
> +++ net/if_bridge.c   17 Jun 2015 12:01:12 -0000
> @@ -2635,10 +2635,12 @@ bridge_ifenqueue(struct bridge_softc *sc
>  {
>       int error, len;
>  
> +     /* Loop prevention. */
> +     m->m_flags |= M_PROTO1;
> +
>  #if NGIF > 0
>       /* Packet needs etherip encapsulation. */
>       if (ifp->if_type == IFT_GIF) {
> -             m->m_flags |= M_PROTO1;
>  
>               /* Count packets input into the gif from outside */
>               ifp->if_ipackets++;
> Index: net/if_ethersubr.c
> ===================================================================
> RCS file: /cvs/src/sys/net/if_ethersubr.c,v
> retrieving revision 1.205
> diff -u -p -r1.205 if_ethersubr.c
> --- net/if_ethersubr.c        16 Jun 2015 11:09:39 -0000      1.205
> +++ net/if_ethersubr.c        17 Jun 2015 12:01:12 -0000
> @@ -181,15 +181,6 @@ ether_output(struct ifnet *ifp, struct m
>       struct arpcom *ac = (struct arpcom *)ifp;
>       int error = 0;
>  
> -#ifdef DIAGNOSTIC
> -     if (ifp->if_rdomain != rtable_l2(m->m_pkthdr.ph_rtableid)) {
> -             printf("%s: trying to send packet on wrong domain. "
> -                 "if %d vs. mbuf %d, AF %d\n", ifp->if_xname,
> -                 ifp->if_rdomain, rtable_l2(m->m_pkthdr.ph_rtableid),
> -                 dst->sa_family);
> -     }
> -#endif
> -
>       esrc = ac->ac_enaddr;
>  
>       if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
> @@ -276,47 +267,6 @@ ether_output(struct ifnet *ifp, struct m
>       eh->ether_type = etype;
>       memcpy(eh->ether_dhost, edst, sizeof(eh->ether_dhost));
>       memcpy(eh->ether_shost, esrc, sizeof(eh->ether_shost));
> -
> -#if NBRIDGE > 0
> -     /*
> -      * Interfaces that are bridgeports need special handling for output.
> -      */
> -     if (ifp->if_bridgeport) {
> -             struct m_tag *mtag;
> -
> -             /*
> -              * Check if this packet has already been sent out through
> -              * this bridgeport, in which case we simply send it out
> -              * without further bridge processing.
> -              */
> -             for (mtag = m_tag_find(m, PACKET_TAG_BRIDGE, NULL); mtag;
> -                 mtag = m_tag_find(m, PACKET_TAG_BRIDGE, mtag)) {
> -#ifdef DEBUG
> -                     /* Check that the information is there */
> -                     if (mtag->m_tag_len != sizeof(caddr_t)) {
> -                             error = EINVAL;
> -                             goto bad;
> -                     }
> -#endif
> -                     if (!memcmp(&ifp->if_bridgeport, mtag + 1,
> -                         sizeof(caddr_t)))
> -                             break;
> -             }
> -             if (mtag == NULL) {
> -                     /* Attach a tag so we can detect loops */
> -                     mtag = m_tag_get(PACKET_TAG_BRIDGE, sizeof(caddr_t),
> -                         M_NOWAIT);
> -                     if (mtag == NULL) {
> -                             error = ENOBUFS;
> -                             goto bad;
> -                     }
> -                     memcpy(mtag + 1, &ifp->if_bridgeport, sizeof(caddr_t));
> -                     m_tag_prepend(m, mtag);
> -                     error = bridge_output(ifp, m, NULL, NULL);
> -                     return (error);
> -             }
> -     }
> -#endif
>  
>       return (if_output(ifp, m));
>  bad:
> Index: sys/mbuf.h
> ===================================================================
> RCS file: /cvs/src/sys/sys/mbuf.h,v
> retrieving revision 1.192
> diff -u -p -r1.192 mbuf.h
> --- sys/mbuf.h        16 Jun 2015 11:09:40 -0000      1.192
> +++ sys/mbuf.h        17 Jun 2015 12:01:12 -0000
> @@ -454,7 +454,6 @@ struct m_tag *m_tag_next(struct mbuf *, 
>  /* Packet tag types */
>  #define PACKET_TAG_IPSEC_IN_DONE     0x0001  /* IPsec applied, in */
>  #define PACKET_TAG_IPSEC_OUT_DONE    0x0002  /* IPsec applied, out */
> -#define PACKET_TAG_BRIDGE            0x0020  /* Bridge processing done */
>  #define PACKET_TAG_GIF                       0x0040  /* GIF processing done 
> */
>  #define PACKET_TAG_GRE                       0x0080  /* GRE processing done 
> */
>  #define PACKET_TAG_DLT                       0x0100 /* data link layer type 
> */
> 

Reply via email to