bpf_mtap_stripvlan

2014-07-09 Thread Henning Brauer
so dlg noticed that tcpdump on vlan is now somewhat busted,
specifically dhc* don't work on the any more. the reason is that bpf
now sees the ether_vlan_header instead of the ether_header. only
visible if your NIC does NOT have hw vlan tagging.
reason: while we previously would prepend an ethernet header in
ether_output and way later in vlan_start throw the ethernet header
away again, replacing it by an ether_vlan_header, we now add the
ether_vlan_header in ether_output already. the mtap is in vlan_start,
aka after.
now removing the ether_vlan_header and either prepending a new
ether_header or calling bpf_mtap_ether which adds a fake one didn't
seem too smart. so I made a bpf_mcopy_stripvlan which, well, cuts
those extra 4 bytes out.

the if_ethersubr.c chunk eases testing, it'll make us hit the right
codepath wether the hw has tagging or not. that chunk not to be
committed of course.

Index: net/bpf.c
===
RCS file: /cvs/src/sys/net/bpf.c,v
retrieving revision 1.97
diff -u -p -r1.97 bpf.c
--- net/bpf.c   9 Jul 2014 13:52:35 -   1.97
+++ net/bpf.c   9 Jul 2014 21:30:19 -
@@ -90,6 +90,7 @@ void  bpf_ifname(struct ifnet *, struct i
 void   _bpf_mtap(caddr_t, struct mbuf *, u_int,
void (*)(const void *, void *, size_t));
 void   bpf_mcopy(const void *, void *, size_t);
+void   bpf_mcopy_stripvlan(const void *, void *, size_t);
 intbpf_movein(struct uio *, u_int, struct mbuf **,
struct sockaddr *, struct bpf_insn *);
 void   bpf_attachd(struct bpf_d *, struct bpf_if *);
@@ -1169,6 +1170,46 @@ bpf_mcopy(const void *src_arg, void *dst
 }
 
 /*
+ * Copy an ethernet frame from an mbuf chain into a buffer, strip the
+ * vlan header bits
+ */
+void
+bpf_mcopy_stripvlan(const void *src_arg, void *dst_arg, size_t len)
+{
+#if NVLAN > 0
+   const struct mbuf   *m;
+   u_intcount, copied = 0, hdrdone = 0;
+   u_char  *dst;
+   struct ether_vlan_header*evh;
+
+   m = src_arg;
+   dst = dst_arg;
+   evh = dst_arg;
+   while (len > 0) {
+   if (m == 0)
+   panic("bpf_mcopy_stripvlan");
+   count = min(m->m_len, len);
+   bcopy(mtod(m, caddr_t), (caddr_t)dst, count);
+   m = m->m_next;
+   dst += count;
+   len -= count;
+   copied += count;
+   if (!hdrdone && copied >= sizeof(struct ether_vlan_header) &&
+   (ntohs(evh->evl_encap_proto) == ETHERTYPE_VLAN ||
+   ntohs(evh->evl_encap_proto) == ETHERTYPE_QINQ)) {
+   /* move up by 4 bytes, overwrite encap_proto + tag */
+   memmove(&evh->evl_encap_proto, &evh->evl_proto, copied -
+   offsetof(struct ether_vlan_header, evl_proto));
+   dst -= (offsetof(struct ether_vlan_header, evl_proto) -
+   offsetof(struct ether_vlan_header,
+   evl_encap_proto)); /* long expression for "4" */
+   hdrdone = 1;
+   }
+   }
+#endif
+}
+
+/*
  * like bpf_mtap, but copy fn can be given. used by various bpf_mtap*
  */
 void
@@ -1218,6 +1259,13 @@ void
 bpf_mtap(caddr_t arg, struct mbuf *m, u_int direction)
 {
_bpf_mtap(arg, m, direction, NULL);
+}
+
+/* like bpf_mtap, but strip the vlan header, leave regular ethernet hdr */
+void
+bpf_mtap_stripvlan(caddr_t arg, struct mbuf *m, u_int direction)
+{
+   _bpf_mtap(arg, m, direction, bpf_mcopy_stripvlan);
 }
 
 /*
Index: net/bpf.h
===
RCS file: /cvs/src/sys/net/bpf.h,v
retrieving revision 1.45
diff -u -p -r1.45 bpf.h
--- net/bpf.h   9 Jul 2014 11:03:04 -   1.45
+++ net/bpf.h   9 Jul 2014 13:16:31 -
@@ -272,6 +272,7 @@ struct bpf_dltlist {
 int bpf_validate(struct bpf_insn *, int);
 int bpf_tap(caddr_t, u_char *, u_int, u_int);
 voidbpf_mtap(caddr_t, struct mbuf *, u_int);
+voidbpf_mtap_stripvlan(caddr_t, struct mbuf *, u_int);
 voidbpf_mtap_hdr(caddr_t, caddr_t, u_int, struct mbuf *, u_int,
void (*)(const void *, void *, size_t));
 voidbpf_mtap_af(caddr_t, u_int32_t, struct mbuf *, u_int);
Index: net/if_ethersubr.c
===
RCS file: /cvs/src/sys/net/if_ethersubr.c,v
retrieving revision 1.173
diff -u -p -r1.173 if_ethersubr.c
--- net/if_ethersubr.c  8 Jul 2014 07:10:12 -   1.173
+++ net/if_ethersubr.c  9 Jul 2014 14:03:10 -
@@ -204,7 +204,7 @@ ether_addheader(struct mbuf **m, struct 
struct ifnet*p = ifv->ifv_p;
 
/* should we use the tx tagging hw offload at all? */
-   if ((p->if_capabilities &a

Re: bpf_mtap_stripvlan

2014-07-10 Thread Henning Brauer
I committed the bpf chunk, but nothing is using it yet. pls give the
if_vlan.c chunk a spin.

Index: net/if_vlan.c
===
RCS file: /cvs/src/sys/net/if_vlan.c,v
retrieving revision 1.106
diff -u -p -r1.106 if_vlan.c
--- net/if_vlan.c   9 Jul 2014 09:30:49 -   1.106
+++ net/if_vlan.c   9 Jul 2014 14:09:43 -
@@ -213,7 +213,7 @@ vlan_start(struct ifnet *ifp)
 
 #if NBPFILTER > 0
if (ifp->if_bpf)
-   bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
+   bpf_mtap_stripvlan(ifp->if_bpf, m, BPF_DIRECTION_OUT);
 #endif
 
/*


* Henning Brauer  [2014-07-09 23:46]:
> so dlg noticed that tcpdump on vlan is now somewhat busted,
> specifically dhc* don't work on the any more. the reason is that bpf
> now sees the ether_vlan_header instead of the ether_header. only
> visible if your NIC does NOT have hw vlan tagging.
> reason: while we previously would prepend an ethernet header in
> ether_output and way later in vlan_start throw the ethernet header
> away again, replacing it by an ether_vlan_header, we now add the
> ether_vlan_header in ether_output already. the mtap is in vlan_start,
> aka after.
> now removing the ether_vlan_header and either prepending a new
> ether_header or calling bpf_mtap_ether which adds a fake one didn't
> seem too smart. so I made a bpf_mcopy_stripvlan which, well, cuts
> those extra 4 bytes out.
> 
> the if_ethersubr.c chunk eases testing, it'll make us hit the right
> codepath wether the hw has tagging or not. that chunk not to be
> committed of course.

-- 
Henning Brauer, h...@bsws.de, henn...@openbsd.org
BS Web Services GmbH, http://bsws.de, Full-Service ISP
Secure Hosting, Mail and DNS. Virtual & Dedicated Servers, Root to Fully Managed
Henning Brauer Consulting, http://henningbrauer.com/



Re: bpf_mtap_stripvlan

2014-07-10 Thread Stuart Henderson
On 2014/07/10 13:11, Henning Brauer wrote:
> I committed the bpf chunk, but nothing is using it yet. pls give the
> if_vlan.c chunk a spin.

I think weerd@ might need something similar for bridge for his tv...

> Index: net/if_vlan.c
> ===
> RCS file: /cvs/src/sys/net/if_vlan.c,v
> retrieving revision 1.106
> diff -u -p -r1.106 if_vlan.c
> --- net/if_vlan.c 9 Jul 2014 09:30:49 -   1.106
> +++ net/if_vlan.c 9 Jul 2014 14:09:43 -
> @@ -213,7 +213,7 @@ vlan_start(struct ifnet *ifp)
>  
>  #if NBPFILTER > 0
>   if (ifp->if_bpf)
> - bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT);
> + bpf_mtap_stripvlan(ifp->if_bpf, m, BPF_DIRECTION_OUT);
>  #endif
>  
>   /*
> 
> 
> * Henning Brauer  [2014-07-09 23:46]:
> > so dlg noticed that tcpdump on vlan is now somewhat busted,
> > specifically dhc* don't work on the any more. the reason is that bpf
> > now sees the ether_vlan_header instead of the ether_header. only
> > visible if your NIC does NOT have hw vlan tagging.
> > reason: while we previously would prepend an ethernet header in
> > ether_output and way later in vlan_start throw the ethernet header
> > away again, replacing it by an ether_vlan_header, we now add the
> > ether_vlan_header in ether_output already. the mtap is in vlan_start,
> > aka after.
> > now removing the ether_vlan_header and either prepending a new
> > ether_header or calling bpf_mtap_ether which adds a fake one didn't
> > seem too smart. so I made a bpf_mcopy_stripvlan which, well, cuts
> > those extra 4 bytes out.
> > 
> > the if_ethersubr.c chunk eases testing, it'll make us hit the right
> > codepath wether the hw has tagging or not. that chunk not to be
> > committed of course.
> 
> -- 
> Henning Brauer, h...@bsws.de, henn...@openbsd.org
> BS Web Services GmbH, http://bsws.de, Full-Service ISP
> Secure Hosting, Mail and DNS. Virtual & Dedicated Servers, Root to Fully 
> Managed
> Henning Brauer Consulting, http://henningbrauer.com/
> 



Re: bpf_mtap_stripvlan

2014-07-10 Thread Paul de Weerd
On Thu, Jul 10, 2014 at 01:30:29PM +0100, Stuart Henderson wrote:
| On 2014/07/10 13:11, Henning Brauer wrote:
| > I committed the bpf chunk, but nothing is using it yet. pls give the
| > if_vlan.c chunk a spin.
| 
| I think weerd@ might need something similar for bridge for his tv...

I'm testing this diff later today or tomorrow...

-- 
>[<++>-]<+++.>+++[<-->-]<.>+++[<+
+++>-]<.>++[<>-]<+.--.[-]
 http://www.weirdnet.nl/ 



Re: bpf_mtap_stripvlan

2014-07-10 Thread Henning Brauer
* Stuart Henderson  [2014-07-10 14:30]:
> On 2014/07/10 13:11, Henning Brauer wrote:
> > I committed the bpf chunk, but nothing is using it yet. pls give the
> > if_vlan.c chunk a spin.
> I think weerd@ might need something similar for bridge for his tv...

the f&^(*$@&)($#@ bridge needs to die. I was told about some
bridging-between-vlans issue yesterday (have no details tho), peeked
into the bridge code and... found vlan tagging code.

Sigh.

whatever else does the job cannot be worse.

-- 
Henning Brauer, h...@bsws.de, henn...@openbsd.org
BS Web Services GmbH, http://bsws.de, Full-Service ISP
Secure Hosting, Mail and DNS. Virtual & Dedicated Servers, Root to Fully Managed
Henning Brauer Consulting, http://henningbrauer.com/



Re: bpf_mtap_stripvlan

2014-07-10 Thread Henning Brauer
* Paul de Weerd  [2014-07-10 14:33]:
> On Thu, Jul 10, 2014 at 01:30:29PM +0100, Stuart Henderson wrote:
> | On 2014/07/10 13:11, Henning Brauer wrote:
> | > I committed the bpf chunk, but nothing is using it yet. pls give the
> | > if_vlan.c chunk a spin.
> | I think weerd@ might need something similar for bridge for his tv...
> I'm testing this diff later today or tomorrow...

can't help the bridge case, not using bpf.

-- 
Henning Brauer, h...@bsws.de, henn...@openbsd.org
BS Web Services GmbH, http://bsws.de, Full-Service ISP
Secure Hosting, Mail and DNS. Virtual & Dedicated Servers, Root to Fully Managed
Henning Brauer Consulting, http://henningbrauer.com/