Re: vlan+bridge fix

2015-05-19 Thread Martin Pieuchot
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 -  1.198
  +++ net/if_ethersubr.c  15 May 2015 10:58:37 -
  @@ -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.c15 May 2015 10:15:13 -  1.331
  +++ net/if.c15 May 2015 10:58:37 -
  @@ -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) {
  

vlan+bridge fix

2015-05-15 Thread Martin Pieuchot
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 -  1.198
+++ net/if_ethersubr.c  15 May 2015 10:58:37 -
@@ -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.c15 May 2015 10:15:13 -  1.331
+++ net/if.c15 May 2015 10:58:37 -
@@ -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, 

Re: vlan+bridge fix

2015-05-15 Thread mxb
Diff is applied. So far no problems.
Unfortunately I can’t test this fully - no vlans on my side.

//mxb


 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.c15 May 2015 10:15:13 -  1.198
 +++ net/if_ethersubr.c15 May 2015 10:58:37 -
 @@ -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 -  1.331
 +++ net/if.c  15 May 2015 10:58:37 -
 @@ -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) {