[ovs-dev] [PATCH V2 21/41] datapath: erspan: introduce erspan v2 for ip_gre

Greg Rose gvrose8192 at gmail.com
Fri May 18 01:57:34 UTC 2018


From: William Tu <u9012063 at gmail.com>

Upstream commit:

    commit f551c91de262ba36b20c3ac19538afb4f4507441
    Author: William Tu <u9012063 at gmail.com>
    Date:   Wed Dec 13 16:38:56 2017 -0800

    net: erspan: introduce erspan v2 for ip_gre

    The patch adds support for erspan version 2.  Not all features are
    supported in this patch.  The SGT (security group tag), GRA (timestamp
    granularity), FT (frame type) are set to fixed value.  Only hardware
    ID and direction are configurable.  Optional subheader is also not
    supported.

    Signed-off-by: William Tu <u9012063 at gmail.com>
    Signed-off-by: David S. Miller <davem at davemloft.net>

Includes some compatability layer adjustments and portions of this
commit were introduced earlier while pulling in ipv6 erspan.

Cc: William Tu <u9012063 at gmail.com>
Signed-off-by: Greg Rose <gvrose8192 at gmail.com>
---
 datapath/linux/compat/include/net/ip_tunnels.h | 10 +++---
 datapath/linux/compat/ip_gre.c                 | 44 ++++++++++++++++++++++----
 2 files changed, 42 insertions(+), 12 deletions(-)

diff --git a/datapath/linux/compat/include/net/ip_tunnels.h b/datapath/linux/compat/include/net/ip_tunnels.h
index ea3fb8d..9b2621e 100644
--- a/datapath/linux/compat/include/net/ip_tunnels.h
+++ b/datapath/linux/compat/include/net/ip_tunnels.h
@@ -257,7 +257,7 @@ struct rpl_ip_tunnel_dst {
 };
 
 #define ip_tunnel rpl_ip_tunnel
-struct ip_tunnel {
+struct rpl_ip_tunnel {
 	struct ip_tunnel __rcu	*next;
 	struct hlist_node hash_node;
 	struct net_device	*dev;
@@ -301,7 +301,7 @@ struct ip_tunnel {
 };
 
 #define ip_tunnel_net rpl_ip_tunnel_net
-struct ip_tunnel_net {
+struct rpl_ip_tunnel_net {
 	struct net_device *fb_tunnel_dev;
 	struct hlist_head tunnels[IP_TNL_HASH_SIZE];
 	struct ip_tunnel __rcu *collect_md_tun;
@@ -368,8 +368,8 @@ struct rtnl_link_stats64 *rpl_ip_tunnel_get_stats64(struct net_device *dev,
 						    struct rtnl_link_stats64 *tot);
 
 #define ip_tunnel_get_dsfield rpl_ip_tunnel_get_dsfield
-static inline u8 ip_tunnel_get_dsfield(const struct iphdr *iph,
-		const struct sk_buff *skb)
+static inline u8 rpl_ip_tunnel_get_dsfield(const struct iphdr *iph,
+					   const struct sk_buff *skb)
 {
 	if (skb->protocol == htons(ETH_P_IP))
 		return iph->tos;
@@ -380,7 +380,7 @@ static inline u8 ip_tunnel_get_dsfield(const struct iphdr *iph,
 }
 
 #define ip_tunnel_ecn_encap rpl_ip_tunnel_ecn_encap
-static inline u8 ip_tunnel_ecn_encap(u8 tos, const struct iphdr *iph,
+static inline u8 rpl_ip_tunnel_ecn_encap(u8 tos, const struct iphdr *iph,
 		const struct sk_buff *skb)
 {
 	u8 inner = ip_tunnel_get_dsfield(iph, skb);
diff --git a/datapath/linux/compat/ip_gre.c b/datapath/linux/compat/ip_gre.c
index 0b0a17f..9bc3277 100644
--- a/datapath/linux/compat/ip_gre.c
+++ b/datapath/linux/compat/ip_gre.c
@@ -364,7 +364,8 @@ static int gre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *unused_tpi)
 	if (hdr_len < 0)
 		goto drop;
 
-	if (unlikely(tpi.proto == htons(ETH_P_ERSPAN))) {
+	if (unlikely(tpi.proto == htons(ETH_P_ERSPAN) ||
+		     tpi.proto == htons(ETH_P_ERSPAN2))) {
 		if (erspan_rcv(skb, &tpi, hdr_len) == PACKET_RCVD)
 			return 0;
 		goto drop;
@@ -819,9 +820,14 @@ enum {
 #if LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0)
 	IFLA_GRE_ERSPAN_INDEX = IFLA_GRE_FWMARK + 1,
 #endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,16,0)
+	IFLA_GRE_ERSPAN_VER = IFLA_GRE_ERSPAN_INDEX + 1,
+	IFLA_GRE_ERSPAN_DIR,
+	IFLA_GRE_ERSPAN_HWID,
+#endif
 };
 
-#define RPL_IFLA_GRE_MAX (IFLA_GRE_ERSPAN_INDEX + 1)
+#define RPL_IFLA_GRE_MAX (IFLA_GRE_ERSPAN_HWID + 1)
 
 static int erspan_validate(struct nlattr *tb[], struct nlattr *data[])
 {
@@ -966,8 +972,14 @@ static netdev_tx_t erspan_xmit(struct sk_buff *skb,
 	}
 
 	/* Push ERSPAN header */
-	erspan_build_header(skb, tunnel->parms.o_key, tunnel->index,
-			    truncate, true);
+	if (tunnel->erspan_ver == 1)
+		erspan_build_header(skb, tunnel->parms.o_key, tunnel->index,
+				    truncate, true);
+	else
+		erspan_build_header_v2(skb, tunnel->parms.o_key,
+				       tunnel->dir, tunnel->hwid,
+				       truncate, true);
+
 	tunnel->parms.o_flags &= ~TUNNEL_KEY;
 	__gre_xmit(skb, dev, &tunnel->parms.iph, htons(ETH_P_ERSPAN));
 	return NETDEV_TX_OK;
@@ -1011,7 +1023,7 @@ static int erspan_tunnel_init(struct net_device *dev)
 	tunnel->tun_hlen = 8;
 	tunnel->parms.iph.protocol = IPPROTO_GRE;
 	tunnel->hlen = tunnel->tun_hlen + tunnel->encap_hlen +
-		       sizeof(struct erspan_base_hdr) + ERSPAN_V1_MDSIZE;
+		       erspan_hdr_len(tunnel->erspan_ver);
 	t_hlen = tunnel->hlen + sizeof(struct iphdr);
 
 	dev->needed_headroom = LL_MAX_HEADER + t_hlen + 4;
@@ -1248,6 +1260,12 @@ static size_t ipgre_get_size(const struct net_device *dev)
 		nla_total_size(0) +
 		/* IFLA_GRE_ERSPAN_INDEX */
 		nla_total_size(4) +
+		/* IFLA_GRE_ERSPAN_VER */
+		nla_total_size(1) +
+		/* IFLA_GRE_ERSPAN_DIR */
+		nla_total_size(1) +
+		/* IFLA_GRE_ERSPAN_HWID */
+		nla_total_size(2) +
 		0;
 }
 
@@ -1269,9 +1287,18 @@ static int ipgre_fill_info(struct sk_buff *skb, const struct net_device *dev)
 		       !!(p->iph.frag_off & htons(IP_DF))))
 		goto nla_put_failure;
 
-	if (t->index)
-		if (nla_put_u32(skb, IFLA_GRE_ERSPAN_INDEX, t->index))
+	if (nla_put_u8(skb, IFLA_GRE_ERSPAN_VER, t->erspan_ver))
+		goto nla_put_failure;
+
+	if (t->erspan_ver == 1) {
+ 		if (nla_put_u32(skb, IFLA_GRE_ERSPAN_INDEX, t->index))
+ 			goto nla_put_failure;
+	} else if (t->erspan_ver == 2) {
+		if (nla_put_u8(skb, IFLA_GRE_ERSPAN_DIR, t->dir))
+			goto nla_put_failure;
+		if (nla_put_u16(skb, IFLA_GRE_ERSPAN_HWID, t->hwid))
 			goto nla_put_failure;
+	}
 
 	return 0;
 
@@ -1291,6 +1318,9 @@ static const struct nla_policy ipgre_policy[RPL_IFLA_GRE_MAX + 1] = {
 	[IFLA_GRE_TOS]		= { .type = NLA_U8 },
 	[IFLA_GRE_PMTUDISC]	= { .type = NLA_U8 },
 	[IFLA_GRE_ERSPAN_INDEX]	= { .type = NLA_U32 },
+	[IFLA_GRE_ERSPAN_VER]	= { .type = NLA_U8 },
+	[IFLA_GRE_ERSPAN_DIR]	= { .type = NLA_U8 },
+	[IFLA_GRE_ERSPAN_HWID]	= { .type = NLA_U16 },
 };
 
 static struct rtnl_link_ops ipgre_link_ops __read_mostly = {
-- 
1.8.3.1



More information about the dev mailing list