On Tue, Nov 4, 2014 at 12:48 AM, David Gwynne <[email protected]> wrote:
>> On 4 Nov 2014, at 06:41, Pieter Verberne <[email protected]> wrote:
>>
>>> On 2014-11-02 13:51, Jorge Schrauwen wrote:
>>>> Hey All,
>>>> TL;DR: traffic leaving a bridge over a vlan does
>>>> not get tagged but leaves untagged after upgrade.
>>>> Is this by design?
>>> Looks exactly like my problem. Running 5.6 release.
>
> bridge(4) puts frames on the wire by calling the outgoing interfaces start 
> routine, which in this case is vlan_start() because you're bridging vlan(4) 
> interfaces.
>
> mpi@ and weerd@ correctly identified the diff where henning@ changed 
> vlan_start(). he assumed that ether_output is always called before 
> vlan_start, and moved the tagging code into ether_output to make injecting 
> the vlan tag more streamlined.
>
> bridge obviously breaks this assumption cos it just shoves the packet into 
> vlan_start() which then just shoves the packet onto the parent interface.
>
> i have a massive headache and sleep deficit right now so im not going to 
> suggest a way to fix this.

I have revert the all patch
http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/if_ethersubr.c.diff?r1=1.170&r2=1.171&f=h
http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/sys/net/if_vlan.c.diff?r1=1.102&r2=1.103&f=h

and rebuilt and test, my 5.6 is sending vlan in the bridge

I strongly suspet this
-       ifp->if_output = vlan_output;
to be the source of headache, the fact there is hardware tagging and
code in vlan make me wonder:

would it be better to break the if

   if ((p->if_capabilities & IFCAP_VLAN_HWTAGGING) &&

put this in if_ethersubr.c.

 and the else in

if_vlan.c

because a virtual iface with hwtagging, it does look strange , doesn'it ?


>
> dlg
>

for lazy just apply this :

cvs server: Diffing .
Index: if_ethersubr.c
===================================================================
RCS file: /cvs/src/sys/net/if_ethersubr.c,v
retrieving revision 1.174
diff -u -p -u -r1.174 if_ethersubr.c
--- if_ethersubr.c      12 Jul 2014 18:44:22 -0000      1.174
+++ if_ethersubr.c      4 Nov 2014 20:07:47 -0000
@@ -155,8 +155,8 @@ u_char etherbroadcastaddr[ETHER_ADDR_LEN
     { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 #define senderr(e) { error = (e); goto bad;}

-static inline int      ether_addheader(struct mbuf **, struct ifnet *,
-                          u_int16_t, u_char *, u_char *);
+static inline int    ether_addheader(struct mbuf **, u_int16_t, u_char *,
+                                     u_char *);

 int
 ether_ioctl(struct ifnet *ifp, struct arpcom *arp, u_long cmd, caddr_t data)
@@ -193,12 +193,11 @@ ether_ioctl(struct ifnet *ifp, struct ar
 }

 static inline int
-ether_addheader(struct mbuf **m, struct ifnet *ifp, u_int16_t etype,
-    u_char *esrc, u_char *edst)
+ether_addheader(struct mbuf **m, u_int16_t etype, u_char *esrc, u_char *edst)
 {
        struct ether_header *eh;

-#if NVLAN > 0
+#if 0
        if ((*m)->m_flags & M_VLANTAG) {
                struct ifvlan   *ifv = ifp->if_softc;
                struct ifnet    *p = ifv->ifv_p;
@@ -394,7 +393,7 @@ ether_output(struct ifnet *ifp0, struct
                esrc = carp_get_srclladdr(ifp0, esrc);
 #endif

-       if (ether_addheader(&m, ifp, etype, esrc, edst) == -1)
+       if (ether_addheader(&m, etype, esrc, edst) == -1)
                senderr(ENOBUFS);

 #if NBRIDGE > 0
Index: if_vlan.c
===================================================================
RCS file: /cvs/src/sys/net/if_vlan.c,v
retrieving revision 1.108
diff -u -p -u -r1.108 if_vlan.c
--- if_vlan.c   12 Jul 2014 18:44:22 -0000      1.108
+++ if_vlan.c   4 Nov 2014 20:07:47 -0000
@@ -151,7 +151,6 @@ vlan_clone_create(struct if_clone *ifc,
        if_attach(ifp);
        ether_ifattach(ifp);
        ifp->if_hdrlen = EVL_ENCAPLEN;
-       ifp->if_output = vlan_output;

        return (0);
 }
@@ -215,6 +214,36 @@ vlan_start(struct ifnet *ifp)
                if (ifp->if_bpf)
                        bpf_mtap_stripvlan(ifp->if_bpf, m, BPF_DIRECTION_OUT);
 #endif
+
+                 /*
+                  * If the IFCAP_VLAN_HWTAGGING capability is set on
the parent,
+                  * it can do VLAN tag insertion itself and doesn't require us
+                  * to create a special header for it. In this case,
we just pass
+                  * the packet along.
+                  */
+                 if ((p->if_capabilities & IFCAP_VLAN_HWTAGGING) &&
+                     (ifv->ifv_type == ETHERTYPE_VLAN)) {
+                         m->m_pkthdr.ether_vtag = ifv->ifv_tag +
+                             (m->m_pkthdr.pf.prio << EVL_PRIO_BITS);
+                         m->m_flags |= M_VLANTAG;
+                 } else {
+                         struct ether_vlan_header evh;
+
+                         m_copydata(m, 0, ETHER_HDR_LEN, (caddr_t)&evh);
+                         evh.evl_proto = evh.evl_encap_proto;
+                         evh.evl_encap_proto = htons(ifv->ifv_type);
+                         evh.evl_tag = htons(ifv->ifv_tag +
+                             (m->m_pkthdr.pf.prio << EVL_PRIO_BITS));
+
+                         m_adj(m, ETHER_HDR_LEN);
+                         M_PREPEND(m, sizeof(evh), M_DONTWAIT);
+                         if (m == NULL) {
+                                 ifp->if_oerrors++;
+                                 continue;
+                         }
+
+                         m_copyback(m, 0, sizeof(evh), &evh, M_NOWAIT);
+                 }

                /*
                 * Send it, precisely as ether_output() would have.

-- 
---------------------------------------------------------------------------------------------------------------------
() ascii ribbon campaign - against html e-mail
/\

Reply via email to