Skip to contentSkip to conversation

ip_gre: a bunch of fixes for erspan

PATCH In review Xin Long 2 participants 6 messages Oct 1, 2017 – Oct 2, 2017

Subsystems (3)
lore
Share & tools
lore

Xin Long

author
#0 lore raw

cover ip_gre: a bunch of fixes for erspan

This patchset is to fix some issues that could cause 0 or low performance, and even unexpected truncated packets on erspan.

Xin Long (4):
ip_gre: get key from session_id correctly in erspan_rcv
ip_gre: check packet length and mtu correctly in erspan_xmit
ip_gre: set tunnel hlen properly in erspan_tunnel_init
ip_gre: erspan device should keep dst

 net/ipv4/ip_gre.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)
Signature · 1 line
2.1.0
author
#1 lore raw

PATCH 1/4 ip_gre: get key from session_id correctly in erspan_rcv

erspan only uses the first 10 bits of session_id as the key to look up the tunnel. But in erspan_rcv, it missed 'session_id & ID_MASK' when getting the key from session_id.

If any other flag is also set in session_id in a packet, it would fail to find the tunnel due to incorrect key in erspan_rcv.

This patch is to add 'session_id & ID_MASK' there and also remove the unnecessary variable session_id.

Fixes 84e54fe0a5ea ("gre: introduce native tunnel support for ERSPAN")
---
 net/ipv4/ip_gre.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)
net/ipv4/ip_gre.c +1 -3
index 8b837f6..b25b1e5 100644
@@ -259,7 +259,6 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
 	struct ip_tunnel *tunnel;
 	struct erspanhdr *ershdr;
 	const struct iphdr *iph;
-	__be32 session_id;
 	__be32 index;
 	int len;
 
@@ -275,8 +274,7 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
 	/* The original GRE header does not have key field,
 	 * Use ERSPAN 10-bit session ID as key.
 	 */
-	session_id = cpu_to_be32(ntohs(ershdr->session_id));
-	tpi->key = session_id;
+	tpi->key = cpu_to_be32(ntohs(ershdr->session_id) & ID_MASK);
 	index = ershdr->md.index;
 	tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex,
 				  tpi->flags | TUNNEL_KEY,
Signature · 1 line
2.1.0
author
#2 lore raw

PATCH 2/4 ip_gre: check packet length and mtu correctly in erspan_xmit

As a ARPHRD_ETHER device, skb->len in erspan_xmit is the length of the whole ether packet. So before checking if a packet size exceeds the mtu, skb->len should subtract dev->hard_header_len.

Otherwise, all packets with max size according to mtu would be trimmed to be truncated packet.

Fixes 84e54fe0a5ea ("gre: introduce native tunnel support for ERSPAN")
---
 net/ipv4/ip_gre.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv4/ip_gre.c +1 -1
index b25b1e5..2a4ef9d 100644
@@ -731,7 +731,7 @@ static netdev_tx_t erspan_xmit(struct sk_buff *skb,
 	if (skb_cow_head(skb, dev->needed_headroom))
 		goto free_skb;
 
-	if (skb->len > dev->mtu) {
+	if (skb->len - dev->hard_header_len > dev->mtu) {
 		pskb_trim(skb, dev->mtu);
 		truncate = true;
 	}
Signature · 1 line
2.1.0
author
#3 lore raw

PATCH 3/4 ip_gre: set tunnel hlen properly in erspan_tunnel_init

According to __gre_tunnel_init, tunnel->hlen should be set as the headers' length between inner packet and outer iphdr.

It would be used especially to calculate a proper mtu when updating mtu in tnl_update_pmtu. Now without setting it, a bigger mtu value than expected would be updated, which hurts performance a lot.

This patch is to fix it by setting tunnel->hlen with:
tunnel->tun_hlen + tunnel->encap_hlen + sizeof(struct erspanhdr)

Fixes 84e54fe0a5ea ("gre: introduce native tunnel support for ERSPAN")
---
 net/ipv4/ip_gre.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
net/ipv4/ip_gre.c +3 -1
index 2a4ef9d..fad0bb1 100644
@@ -1245,7 +1245,9 @@ static int erspan_tunnel_init(struct net_device *dev)
 
 	tunnel->tun_hlen = 8;
 	tunnel->parms.iph.protocol = IPPROTO_GRE;
-	t_hlen = tunnel->hlen + sizeof(struct iphdr) + sizeof(struct erspanhdr);
+	tunnel->hlen = tunnel->tun_hlen + tunnel->encap_hlen +
+		       sizeof(struct erspanhdr);
+	t_hlen = tunnel->hlen + sizeof(struct iphdr);
 
 	dev->needed_headroom = LL_MAX_HEADER + t_hlen + 4;
 	dev->mtu = ETH_DATA_LEN - t_hlen - 4;
Signature · 1 line
2.1.0
author
#4 lore raw

PATCH 4/4 ip_gre: erspan device should keep dst

The patch 'ip_gre: ipgre_tap device should keep dst' fixed the issue ipgre_tap dev mtu couldn't be updated in tx path.

The same fix is needed for erspan as well.

Fixes 84e54fe0a5ea ("gre: introduce native tunnel support for ERSPAN")
---
 net/ipv4/ip_gre.c | 1 +
 1 file changed, 1 insertion(+)
net/ipv4/ip_gre.c +1 -0
index fad0bb1..467e44d 100644
@@ -1254,6 +1254,7 @@ static int erspan_tunnel_init(struct net_device *dev)
 	dev->features		|= GRE_FEATURES;
 	dev->hw_features	|= GRE_FEATURES;
 	dev->priv_flags		|= IFF_LIVE_ADDR_CHANGE;
+	netif_keep_dst(dev);
 
 	return ip_tunnel_init(dev);
 }
Signature · 1 line
2.1.0
maintainer
#5 lore raw
In reply to Xin Long

From: Xin Long <[email protected]>
Date: Sun, 1 Oct 2017 22:00:52 +0800

Quoted 2 lines

This patchset is to fix some issues that could cause 0 or low performance, and even unexpected truncated packets on erspan.

Series applied, thanks.