diff mbox series

[ovs-dev,V2,29/41] erspan: auto detect truncated packets.

Message ID 1526608674-12702-30-git-send-email-gvrose8192@gmail.com
State Superseded
Headers show
Series Add ERSPAN support | expand

Commit Message

Gregory Rose May 18, 2018, 1:57 a.m. UTC
From: William Tu <u9012063@gmail.com>

Upstream commit:
    commit 1baf5ebf8954d9bff8fa4e7dd6c416a0cebdb9e2
    Author: William Tu <u9012063@gmail.com>
    Date:   Fri Apr 27 14:16:32 2018 -0700

    erspan: auto detect truncated packets.

    Currently the truncated bit is set only when the mirrored packet
    is larger than mtu.  For certain cases, the packet might already
    been truncated before sending to the erspan tunnel.  In this case,
    the patch detect whether the IP header's total length is larger
    than the actual skb->len.  If true, this indicated that the
    mirrored packet is truncated and set the erspan truncate bit.

    I tested the patch using bpf_skb_change_tail helper function to
    shrink the packet size and send to erspan tunnel.

    Reported-by: Xiaoyan Jin <xiaoyanj@vmware.com>
    Signed-off-by: William Tu <u9012063@gmail.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>

Cc: William Tu <u9012063@gmail.com>
Signed-off-by: Greg Rose <gvrose8192@gmail.com>
---
 datapath/linux/compat/ip6_gre.c | 6 ++++++
 datapath/linux/compat/ip_gre.c  | 6 ++++++
 2 files changed, 12 insertions(+)
diff mbox series

Patch

diff --git a/datapath/linux/compat/ip6_gre.c b/datapath/linux/compat/ip6_gre.c
index 085d04f..e0246d1 100644
--- a/datapath/linux/compat/ip6_gre.c
+++ b/datapath/linux/compat/ip6_gre.c
@@ -1069,6 +1069,7 @@  static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
 	int err = -EINVAL;
 	__be32 tun_id;
 	__u32 mtu;
+	int nhoff;
 
 
 	/* OVS doesn't support native mode ip6 tunnel traffic so
@@ -1087,6 +1088,11 @@  static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
 		truncate = true;
 	}
 
+	nhoff = skb_network_header(skb) - skb_mac_header(skb);
+	if (skb->protocol == htons(ETH_P_IP) &&
+	    (ntohs(ip_hdr(skb)->tot_len) > skb->len - nhoff))
+		truncate = true;
+
 	t->parms.o_flags &= ~TUNNEL_KEY;
 	IPCB(skb)->flags = 0;
 
diff --git a/datapath/linux/compat/ip_gre.c b/datapath/linux/compat/ip_gre.c
index 958965f..6b40013 100644
--- a/datapath/linux/compat/ip_gre.c
+++ b/datapath/linux/compat/ip_gre.c
@@ -631,6 +631,7 @@  static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev,
 	int tunnel_hlen;
 	int version;
 	__be16 df;
+	int nhoff;
 
 	tun_info = skb_tunnel_info(skb);
 	if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX) ||
@@ -658,6 +659,11 @@  static void erspan_fb_xmit(struct sk_buff *skb, struct net_device *dev,
 		truncate = true;
 	}
 
+	nhoff = skb_network_header(skb) - skb_mac_header(skb);
+	if (skb->protocol == htons(ETH_P_IP) &&
+	    (ntohs(ip_hdr(skb)->tot_len) > skb->len - nhoff))
+		truncate = true;
+
 	if (version == 1) {
 		erspan_build_header(skb, ntohl(tunnel_id_to_key32(key->tun_id)),
 				    ntohl(md->u.index), truncate, true);