Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gre6: Fix reception with IP6_TNL_F_RCV_DSCP_COPY

When receiving an IPv4 packet inside an IPv6 GRE packet, and the
IP6_TNL_F_RCV_DSCP_COPY flag is set on the tunnel, the IPv4 header would
get corrupted. This is due to the common ip6_tnl_rcv() function assuming
that the inner header is always IPv6. This patch checks the tunnel
protocol for IPv4 inner packets, but still defaults to IPv6.

Fixes: 308edfdf1563 ("gre6: Cleanup GREv6 receive path, call common GRE functions")
Signed-off-by: Mark Tomlinson <mark.tomlinson@alliedtelesis.co.nz>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Mark Tomlinson and committed by
David S. Miller
272502fc e14fd8da

+9 -1
+9 -1
net/ipv6/ip6_tunnel.c
··· 915 915 struct metadata_dst *tun_dst, 916 916 bool log_ecn_err) 917 917 { 918 - return __ip6_tnl_rcv(t, skb, tpi, tun_dst, ip6ip6_dscp_ecn_decapsulate, 918 + int (*dscp_ecn_decapsulate)(const struct ip6_tnl *t, 919 + const struct ipv6hdr *ipv6h, 920 + struct sk_buff *skb); 921 + 922 + dscp_ecn_decapsulate = ip6ip6_dscp_ecn_decapsulate; 923 + if (tpi->proto == htons(ETH_P_IP)) 924 + dscp_ecn_decapsulate = ip4ip6_dscp_ecn_decapsulate; 925 + 926 + return __ip6_tnl_rcv(t, skb, tpi, tun_dst, dscp_ecn_decapsulate, 919 927 log_ecn_err); 920 928 } 921 929 EXPORT_SYMBOL(ip6_tnl_rcv);