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

xfrm: interface: fix the priorities for ipip and ipv6 tunnels

As Nicolas noticed in his case, when xfrm_interface module is installed
the standard IP tunnels will break in receiving packets.

This is caused by the IP tunnel handlers with a higher priority in xfrm
interface processing incoming packets by xfrm_input(), which would drop
the packets and return 0 instead when anything wrong happens.

Rather than changing xfrm_input(), this patch is to adjust the priority
for the IP tunnel handlers in xfrm interface, so that the packets would
go to xfrmi's later than the others', as the others' would not drop the
packets when the handlers couldn't process them.

Note that IPCOMP also defines its own IPIP tunnel handler and it calls
xfrm_input() as well, so we must make its priority lower than xfrmi's,
which means having xfrmi loaded would still break IPCOMP. We may seek
another way to fix it in xfrm_input() in the future.

Reported-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Tested-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Fixes: da9bbf0598c9 ("xfrm: interface: support IPIP and IPIP6 tunnels processing with .cb_handler")
FIxes: d7b360c2869f ("xfrm: interface: support IP6IP6 and IP6IP tunnels processing with .cb_handler")
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>

authored by

Xin Long and committed by
Steffen Klassert
7fe94612 3fdd47c3

+8 -8
+2 -2
net/ipv4/xfrm4_tunnel.c
··· 64 64 static struct xfrm_tunnel xfrm_tunnel_handler __read_mostly = { 65 65 .handler = xfrm_tunnel_rcv, 66 66 .err_handler = xfrm_tunnel_err, 67 - .priority = 3, 67 + .priority = 4, 68 68 }; 69 69 70 70 #if IS_ENABLED(CONFIG_IPV6) 71 71 static struct xfrm_tunnel xfrm64_tunnel_handler __read_mostly = { 72 72 .handler = xfrm_tunnel_rcv, 73 73 .err_handler = xfrm_tunnel_err, 74 - .priority = 2, 74 + .priority = 3, 75 75 }; 76 76 #endif 77 77
+2 -2
net/ipv6/xfrm6_tunnel.c
··· 303 303 static struct xfrm6_tunnel xfrm6_tunnel_handler __read_mostly = { 304 304 .handler = xfrm6_tunnel_rcv, 305 305 .err_handler = xfrm6_tunnel_err, 306 - .priority = 2, 306 + .priority = 3, 307 307 }; 308 308 309 309 static struct xfrm6_tunnel xfrm46_tunnel_handler __read_mostly = { 310 310 .handler = xfrm6_tunnel_rcv, 311 311 .err_handler = xfrm6_tunnel_err, 312 - .priority = 2, 312 + .priority = 3, 313 313 }; 314 314 315 315 static int __net_init xfrm6_tunnel_net_init(struct net *net)
+4 -4
net/xfrm/xfrm_interface.c
··· 830 830 .handler = xfrmi6_rcv_tunnel, 831 831 .cb_handler = xfrmi_rcv_cb, 832 832 .err_handler = xfrmi6_err, 833 - .priority = -1, 833 + .priority = 2, 834 834 }; 835 835 836 836 static struct xfrm6_tunnel xfrmi_ip6ip_handler __read_mostly = { 837 837 .handler = xfrmi6_rcv_tunnel, 838 838 .cb_handler = xfrmi_rcv_cb, 839 839 .err_handler = xfrmi6_err, 840 - .priority = -1, 840 + .priority = 2, 841 841 }; 842 842 #endif 843 843 ··· 875 875 .handler = xfrmi4_rcv_tunnel, 876 876 .cb_handler = xfrmi_rcv_cb, 877 877 .err_handler = xfrmi4_err, 878 - .priority = -1, 878 + .priority = 3, 879 879 }; 880 880 881 881 static struct xfrm_tunnel xfrmi_ipip6_handler __read_mostly = { 882 882 .handler = xfrmi4_rcv_tunnel, 883 883 .cb_handler = xfrmi_rcv_cb, 884 884 .err_handler = xfrmi4_err, 885 - .priority = -1, 885 + .priority = 2, 886 886 }; 887 887 #endif 888 888