Re: [PATCHv4 net-next] gre: introduce native tunnel support for ERSPAN

2017-08-22 Thread David Miller
From: William Tu 
Date: Tue, 22 Aug 2017 09:40:28 -0700

> The patch adds ERSPAN type II tunnel support.  The implementation
> is based on the draft at [1].  One of the purposes is for Linux
> box to be able to receive ERSPAN monitoring traffic sent from
> the Cisco switch, by creating a ERSPAN tunnel device.
> In addition, the patch also adds ERSPAN TX, so Linux virtual
> switch can redirect monitored traffic to the ERSPAN tunnel device.
> The traffic will be encapsulated into ERSPAN and sent out.
> 
> The implementation reuses tunnel key as ERSPAN session ID, and
> field 'erspan' as ERSPAN Index fields:
> ./ip link add dev ers11 type erspan seq key 100 erspan 123 \
>   local 172.16.1.200 remote 172.16.1.100
> 
> To use the above device as ERSPAN receiver, configure
> Nexus 5000 switch as below:
> 
> monitor session 100 type erspan-source
>   erspan-id 123
>   vrf default
>   destination ip 172.16.1.200
>   source interface Ethernet1/11 both
>   source interface Ethernet1/12 both
>   no shut
> monitor erspan origin ip-address 172.16.1.100 global
> 
> [1] https://tools.ietf.org/html/draft-foschiano-erspan-01
> [2] iproute2 patch: http://marc.info/?l=linux-netdev=150306086924951=2
> [3] test script: http://marc.info/?l=linux-netdev=150231021807304=2
> 
> Signed-off-by: William Tu 
> Signed-off-by: Meenakshi Vohra 

Applied, thank you.


[PATCHv4 net-next] gre: introduce native tunnel support for ERSPAN

2017-08-22 Thread William Tu
The patch adds ERSPAN type II tunnel support.  The implementation
is based on the draft at [1].  One of the purposes is for Linux
box to be able to receive ERSPAN monitoring traffic sent from
the Cisco switch, by creating a ERSPAN tunnel device.
In addition, the patch also adds ERSPAN TX, so Linux virtual
switch can redirect monitored traffic to the ERSPAN tunnel device.
The traffic will be encapsulated into ERSPAN and sent out.

The implementation reuses tunnel key as ERSPAN session ID, and
field 'erspan' as ERSPAN Index fields:
./ip link add dev ers11 type erspan seq key 100 erspan 123 \
local 172.16.1.200 remote 172.16.1.100

To use the above device as ERSPAN receiver, configure
Nexus 5000 switch as below:

monitor session 100 type erspan-source
  erspan-id 123
  vrf default
  destination ip 172.16.1.200
  source interface Ethernet1/11 both
  source interface Ethernet1/12 both
  no shut
monitor erspan origin ip-address 172.16.1.100 global

[1] https://tools.ietf.org/html/draft-foschiano-erspan-01
[2] iproute2 patch: http://marc.info/?l=linux-netdev=150306086924951=2
[3] test script: http://marc.info/?l=linux-netdev=150231021807304=2

Signed-off-by: William Tu 
Signed-off-by: Meenakshi Vohra 
Cc: Alexey Kuznetsov 
Cc: Hideaki YOSHIFUJI 
---
v3->v4:
  fix skb_may_pull len
  fix local variable ordering
  fix commit message Nexus set-up
v2->v3:
  add skb_may_pull check at erspan_rcv
  a couple of minor fixes and checks for index value
v1->v2:
  Add missing erspan.h header
---
 include/net/erspan.h   |  61 ++
 include/net/ip_tunnels.h   |   3 +
 include/uapi/linux/if_ether.h  |   1 +
 include/uapi/linux/if_tunnel.h |   1 +
 net/ipv4/ip_gre.c  | 269 +
 5 files changed, 335 insertions(+)
 create mode 100644 include/net/erspan.h

diff --git a/include/net/erspan.h b/include/net/erspan.h
new file mode 100644
index ..ca94fc86865e
--- /dev/null
+++ b/include/net/erspan.h
@@ -0,0 +1,61 @@
+#ifndef __LINUX_ERSPAN_H
+#define __LINUX_ERSPAN_H
+
+/*
+ * GRE header for ERSPAN encapsulation (8 octets [34:41]) -- 8 bytes
+ *   0   1   2   3
+ *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |0|0|0|1|0|0|0|0|Protocol Type for ERSPAN   |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |  Sequence Number (increments per packet per session)  |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ *  Note that in the above GRE header [RFC1701] out of the C, R, K, S,
+ *  s, Recur, Flags, Version fields only S (bit 03) is set to 1. The
+ *  other fields are set to zero, so only a sequence number follows.
+ *
+ *  ERSPAN Type II header (8 octets [42:49])
+ *  0   1   2   3
+ *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |  Ver  |  VLAN | COS | En|T|Session ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |  Reserved |  Index|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * GRE proto ERSPAN type II = 0x88BE, type III = 0x22EB
+ */
+
+#define ERSPAN_VERSION 0x1
+
+#define VER_MASK   0xf000
+#define VLAN_MASK  0x0fff
+#define COS_MASK   0xe000
+#define EN_MASK0x1800
+#define T_MASK 0x0400
+#define ID_MASK0x03ff
+#define INDEX_MASK 0xf
+
+enum erspan_encap_type {
+   ERSPAN_ENCAP_NOVLAN = 0x0,  /* originally without VLAN tag */
+   ERSPAN_ENCAP_ISL = 0x1, /* originally ISL encapsulated */
+   ERSPAN_ENCAP_8021Q = 0x2,   /* originally 802.1Q encapsulated */
+   ERSPAN_ENCAP_INFRAME = 0x3, /* VLAN tag perserved in frame */
+};
+
+struct erspan_metadata {
+   __be32 index;   /* type II */
+};
+
+struct erspanhdr {
+   __be16 ver_vlan;
+#define VER_OFFSET  12
+   __be16 session_id;
+#define COS_OFFSET  13
+#define EN_OFFSET   11
+#define T_OFFSET10
+   struct erspan_metadata md;
+};
+
+#endif
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index 520809912f03..625c29329372 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -115,6 +115,9 @@ struct ip_tunnel {
u32 o_seqno;/* The last output seqno */
int tun_hlen;   /* Precalculated header length */
 
+   /* This field used only by ERSPAN */
+   u32 index;  /* ERSPAN type II index */
+
struct dst_cache dst_cache;
 
struct ip_tunnel_parm parms;
diff