diff options
author | David S. Miller <davem@davemloft.net> | 2017-10-02 01:30:33 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-10-02 01:30:33 -0400 |
commit | c79c314bb422482b88fa9881d783d2d5752f6ac6 (patch) | |
tree | 037f60ca472cd85fa942b6e5da0c8e4eb405220b | |
parent | aad06212d36cf34859428a0a279e5c14ee5c9e26 (diff) | |
parent | c84bed440e4e11a973e8c0254d0dfaccfca41fb0 (diff) |
Merge branch 'erspan-fixes'
Xin Long says:
====================
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.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/ipv4/ip_gre.c | 11 |
1 files changed, 6 insertions, 5 deletions
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 8b837f6f5532..467e44d7587d 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -259,7 +259,6 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi, | |||
259 | struct ip_tunnel *tunnel; | 259 | struct ip_tunnel *tunnel; |
260 | struct erspanhdr *ershdr; | 260 | struct erspanhdr *ershdr; |
261 | const struct iphdr *iph; | 261 | const struct iphdr *iph; |
262 | __be32 session_id; | ||
263 | __be32 index; | 262 | __be32 index; |
264 | int len; | 263 | int len; |
265 | 264 | ||
@@ -275,8 +274,7 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi, | |||
275 | /* The original GRE header does not have key field, | 274 | /* The original GRE header does not have key field, |
276 | * Use ERSPAN 10-bit session ID as key. | 275 | * Use ERSPAN 10-bit session ID as key. |
277 | */ | 276 | */ |
278 | session_id = cpu_to_be32(ntohs(ershdr->session_id)); | 277 | tpi->key = cpu_to_be32(ntohs(ershdr->session_id) & ID_MASK); |
279 | tpi->key = session_id; | ||
280 | index = ershdr->md.index; | 278 | index = ershdr->md.index; |
281 | tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, | 279 | tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, |
282 | tpi->flags | TUNNEL_KEY, | 280 | tpi->flags | TUNNEL_KEY, |
@@ -733,7 +731,7 @@ static netdev_tx_t erspan_xmit(struct sk_buff *skb, | |||
733 | if (skb_cow_head(skb, dev->needed_headroom)) | 731 | if (skb_cow_head(skb, dev->needed_headroom)) |
734 | goto free_skb; | 732 | goto free_skb; |
735 | 733 | ||
736 | if (skb->len > dev->mtu) { | 734 | if (skb->len - dev->hard_header_len > dev->mtu) { |
737 | pskb_trim(skb, dev->mtu); | 735 | pskb_trim(skb, dev->mtu); |
738 | truncate = true; | 736 | truncate = true; |
739 | } | 737 | } |
@@ -1247,13 +1245,16 @@ static int erspan_tunnel_init(struct net_device *dev) | |||
1247 | 1245 | ||
1248 | tunnel->tun_hlen = 8; | 1246 | tunnel->tun_hlen = 8; |
1249 | tunnel->parms.iph.protocol = IPPROTO_GRE; | 1247 | tunnel->parms.iph.protocol = IPPROTO_GRE; |
1250 | t_hlen = tunnel->hlen + sizeof(struct iphdr) + sizeof(struct erspanhdr); | 1248 | tunnel->hlen = tunnel->tun_hlen + tunnel->encap_hlen + |
1249 | sizeof(struct erspanhdr); | ||
1250 | t_hlen = tunnel->hlen + sizeof(struct iphdr); | ||
1251 | 1251 | ||
1252 | dev->needed_headroom = LL_MAX_HEADER + t_hlen + 4; | 1252 | dev->needed_headroom = LL_MAX_HEADER + t_hlen + 4; |
1253 | dev->mtu = ETH_DATA_LEN - t_hlen - 4; | 1253 | dev->mtu = ETH_DATA_LEN - t_hlen - 4; |
1254 | dev->features |= GRE_FEATURES; | 1254 | dev->features |= GRE_FEATURES; |
1255 | dev->hw_features |= GRE_FEATURES; | 1255 | dev->hw_features |= GRE_FEATURES; |
1256 | dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; | 1256 | dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; |
1257 | netif_keep_dst(dev); | ||
1257 | 1258 | ||
1258 | return ip_tunnel_init(dev); | 1259 | return ip_tunnel_init(dev); |
1259 | } | 1260 | } |