diff options
author | Yossi Kuperman <yossiku@mellanox.com> | 2018-03-04 22:03:52 +0300 |
---|---|---|
committer | Steffen Klassert <steffen.klassert@secunet.com> | 2018-03-07 12:54:29 +0300 |
commit | 87cdf3148b11d46382dbce2754ae7036aba96380 (patch) | |
tree | 24198025d23c7af2c8ad5f280304b59ec4201b64 | |
parent | b8b549eec8187ac1b12075d69a2d84d89b5e811a (diff) | |
download | linux-87cdf3148b11d46382dbce2754ae7036aba96380.tar.xz |
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>
-rw-r--r-- | net/ipv4/xfrm4_mode_tunnel.c | 3 | ||||
-rw-r--r-- | net/ipv6/xfrm6_mode_tunnel.c | 3 |
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; |