aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2017-10-02 01:30:33 -0400
committerDavid S. Miller <davem@davemloft.net>2017-10-02 01:30:33 -0400
commitc79c314bb422482b88fa9881d783d2d5752f6ac6 (patch)
tree037f60ca472cd85fa942b6e5da0c8e4eb405220b
parentaad06212d36cf34859428a0a279e5c14ee5c9e26 (diff)
parentc84bed440e4e11a973e8c0254d0dfaccfca41fb0 (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.c11
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}