On 15/05/15(Fri) 17:34, mxb wrote:
> Diff is applied. So far no problems.
> Unfortunately I can’t test this fully - no vlans on my side.

Thanks for testing.  A "no regression" report is always welcome.

There's some more issues with bridge+vlan but jasper@ also confirmed
this diff improve the situation.

Can I have oks?

> > On 15 maj 2015, at 13:14, Martin Pieuchot <m...@openbsd.org> wrote:
> > 
> > I have one setup with multiple interfaces in a bridge and on some of
> > these interfaces some vlan(4)s.  But there's currently a bug that
> > prevent us to send (receive is fine) VLAN packets in such config.
> > Diff below fixes that.
> > 
> > The problem is that vlan_output() does not pass its parent interface
> > to ether_output().  That's a mis-design that should be fixed later.
> > The reason for not passing the parent interface is that we want to
> > tcpdump(8) packets on vlan interfaces and the easiest hack^Wsolution
> > was to add a bpf handler in vlan_start()*.
> > 
> > Since my vlans are not part of the bridge, the check below is never
> > true and my packets never go through the bridge.  By moving this
> > check to if_output() we kill two birds with one diff.  First of
> > all we fix this vlan bug and secondly we simplify ether_output()
> > which in turn will allow us to fix all pseudo-interface *output()
> > functions.
> > 
> > One of the goals of if_output() is to move all bpf handlers instead
> > of having them in multiple if_start().  Of course, this will also
> > help us removing the various "#if PSEUDODRIVER" from our stack...
> > 
> > Ok?
> > 
> > *: Note that for the exact same reason we cannot tcpdump output
> > packets on a carp(4) interface, this will be fixed at the same
> > time in upcoming diffs.
> > 
> > 
> > Index: net/if_ethersubr.c
> > ===================================================================
> > RCS file: /cvs/src/sys/net/if_ethersubr.c,v
> > retrieving revision 1.198
> > diff -u -p -r1.198 if_ethersubr.c
> > --- net/if_ethersubr.c      15 May 2015 10:15:13 -0000      1.198
> > +++ net/if_ethersubr.c      15 May 2015 10:58:37 -0000
> > @@ -363,47 +363,6 @@ ether_output(struct ifnet *ifp0, struct 
> >     if (ether_addheader(&m, ifp, etype, esrc, edst) == -1)
> >             senderr(ENOBUFS);
> > 
> > -#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
> > -
> >     len = m->m_pkthdr.len;
> > 
> >     error = if_output(ifp, m);
> > Index: net/if.c
> > ===================================================================
> > RCS file: /cvs/src/sys/net/if.c,v
> > retrieving revision 1.331
> > diff -u -p -r1.331 if.c
> > --- net/if.c        15 May 2015 10:15:13 -0000      1.331
> > +++ net/if.c        15 May 2015 10:58:37 -0000
> > @@ -450,6 +450,40 @@ if_output(struct ifnet *ifp, struct mbuf
> >     length = m->m_pkthdr.len;
> >     mflags = m->m_flags;
> > 
> > +#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)) {
> > +                   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) {
> > +                           m_freem(m);
> > +                           return (ENOBUFS);
> > +                   }
> > +                   memcpy(mtag + 1, &ifp->if_bridgeport, sizeof(caddr_t));
> > +                   m_tag_prepend(m, mtag);
> > +                   error = bridge_output(ifp, m, NULL, NULL);
> > +                   return (error);
> > +           }
> > +   }
> > +#endif
> > +
> >     s = splnet();
> > 
> >     /*
> > 
> 
> 

Reply via email to