summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorYossi Kuperman <yossiku@mellanox.com>2018-03-04 21:03:52 +0200
committerSteffen Klassert <steffen.klassert@secunet.com>2018-03-07 10:54:29 +0100
commit87cdf3148b11d46382dbce2754ae7036aba96380 (patch)
tree24198025d23c7af2c8ad5f280304b59ec4201b64 /net
parentb8b549eec8187ac1b12075d69a2d84d89b5e811a (diff)
downloadlinux-87cdf3148b11d46382dbce2754ae7036aba96380.tar.gz
linux-87cdf3148b11d46382dbce2754ae7036aba96380.tar.bz2
linux-87cdf3148b11d46382dbce2754ae7036aba96380.zip
xfrm: Verify MAC header exists before overwriting eth_hdr(skb)->h_proto
Artem Savkov reported that commit 5efec5c655dd leads to a packet loss under IPSec configuration. It appears that his setup consists of a TUN device, which does not have a MAC header. Make sure MAC header exists. Note: TUN device sets a MAC header pointer, although it does not have one. Fixes: 5efec5c655dd ("xfrm: Fix eth_hdr(skb)->h_proto to reflect inner IP version") Reported-by: Artem Savkov <artem.savkov@gmail.com> Tested-by: Artem Savkov <artem.savkov@gmail.com> Signed-off-by: Yossi Kuperman <yossiku@mellanox.com> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/xfrm4_mode_tunnel.c3
-rw-r--r--net/ipv6/xfrm6_mode_tunnel.c3
2 files changed, 4 insertions, 2 deletions
diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c
index 63faeee989a9..2a9764bd1719 100644
--- a/net/ipv4/xfrm4_mode_tunnel.c
+++ b/net/ipv4/xfrm4_mode_tunnel.c
@@ -92,7 +92,8 @@ static int xfrm4_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
skb_reset_network_header(skb);
skb_mac_header_rebuild(skb);
- eth_hdr(skb)->h_proto = skb->protocol;
+ if (skb->mac_len)
+ eth_hdr(skb)->h_proto = skb->protocol;
err = 0;
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c
index bb935a3b7fea..de1b0b8c53b0 100644
--- a/net/ipv6/xfrm6_mode_tunnel.c
+++ b/net/ipv6/xfrm6_mode_tunnel.c
@@ -92,7 +92,8 @@ static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
skb_reset_network_header(skb);
skb_mac_header_rebuild(skb);
- eth_hdr(skb)->h_proto = skb->protocol;
+ if (skb->mac_len)
+ eth_hdr(skb)->h_proto = skb->protocol;
err = 0;