[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <055d987a-e530-c65c-82de-de761cc31878@oracle.com>
Date: Wed, 22 Nov 2017 19:06:13 +0300
From: Alexey Kodanev <alexey.kodanev@...cle.com>
To: Steffen Klassert <steffen.klassert@...unet.com>
Cc: Petr Vorel <pvorel@...e.cz>, netdev <netdev@...r.kernel.org>
Subject: ipsec: ipcomp alg problem on vti interface
Hi Steffen,
LTP has vti test-cases which fail on ipcomp alg, e.g.
"tcp_ipsec_vti.sh -p comp -m tunnel -s 100"
Basically, the setupconsists of the following commands:
ip li add ltp_vti0 type vti local 10.0.0.2 remote 10.0.0.1 key 10 dev ltp_ns_veth2
ip li set ltp_vti0 up
ip -4 xf st add src 10.0.0.1 dst 10.0.0.2 proto comp spi 0x1001 comp deflate mode tunnel
ip -4 xf po add dir out tmpl src 10.0.0.2 dst 10.0.0.1 proto comp mode tunnel mark 10
ip -4 xf po add dir in tmpl src 10.0.0.1 dst 10.0.0.2 proto comp mode tunnel mark 10
ip route add 10.23.1.0/30 dev ltp_vti0
ip a add 10.23.1.1/30 dev ltp_vti0
...omitted corresponded setup in netns for the other end.
The problem appears with the small packets like SYN which are not
compressed and sent as is through vti tunnel and appear on ltp_ns_veth2
as IPIP packets. On the other end, vti doesn't handle them and theyare
rejected (InNoPol stats increased).
As a workaround, setting:
# sysctl net.ipv4.conf.ltp_ns_veth2.disable_policy=1
# sysctl net.ipv4.conf.ltp_ns_veth1.disable_policy=1
works, but compressed packets seen on vti device, the other on ltp_ns_veth2.
Is there some flaw in setup or vti not designed to handle ipcomp alg that
can send packets with/without compression (or without further encryption)?
May be we should handle such packets by registering additional tunnel
handler onvti, like in the diff below?
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c
index 89453cf..99ad70b 100644
--- a/net/ipv4/ip_vti.c
+++ b/net/ipv4/ip_vti.c
@@ -44,11 +44,20 @@
#include <net/net_namespace.h>
#include <net/netns/generic.h>
+static bool log_ecn_error = true;
+module_param(log_ecn_error, bool, 0644);
+MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN");
+
static struct rtnl_link_ops vti_link_ops __read_mostly;
static unsigned int vti_net_id __read_mostly;
static int vti_tunnel_init(struct net_device *dev);
+static const struct tnl_ptk_info tpi = {
+ /* no tunnel info required for ipip. */
+ .proto = htons(ETH_P_IP),
+};
+
static int vti_input(struct sk_buff *skb, int nexthdr, __be32 spi,
int encap_type)
{
@@ -65,6 +74,13 @@ static int vti_input(struct sk_buff *skb, int nexthdr, __be32 spi,
XFRM_TUNNEL_SKB_CB(skb)->tunnel.ip4 = tunnel;
+ if (ip_hdr(skb)->protocol == IPPROTO_IPIP) {
+ if (iptunnel_pull_header(skb, 0, tpi.proto, false))
+ goto drop;
+ return ip_tunnel_rcv(tunnel, skb, &tpi, NULL,
+ log_ecn_error);
+ }
+
return xfrm_input(skb, nexthdr, spi, encap_type);
}
@@ -335,6 +351,11 @@ static int vti4_err(struct sk_buff *skb, u32 info)
return 0;
}
+static int vti_ip_err(struct sk_buff *skb, u32 info)
+{
+ return -ENOENT;
+}
+
static int
vti_tunnel_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
@@ -440,6 +461,12 @@ static void __net_init vti_fb_tunnel_init(struct net_device *dev)
.priority = 100,
};
+static struct xfrm_tunnel vti_ip4_tunnnel __read_mostly = {
+ .handler = vti_rcv,
+ .err_handler = vti_ip_err,
+ .priority = 1,
+};
+
static int __net_init vti_init_net(struct net *net)
{
int err;
@@ -607,6 +634,9 @@ static int __init vti_init(void)
err = xfrm4_protocol_register(&vti_ipcomp4_protocol, IPPROTO_COMP);
if (err < 0)
goto xfrm_proto_comp_failed;
+ err = xfrm4_tunnel_register(&vti_ip4_tunnnel, AF_INET);
+ if (err < 0)
+ goto xfrm_tunnel_failed;
msg = "netlink interface";
err = rtnl_link_register(&vti_link_ops);
@@ -616,6 +646,8 @@ static int __init vti_init(void)
return err;
rtnl_link_failed:
+ xfrm4_tunnel_deregister(&vti_ip4_tunnnel, AF_INET);
+xfrm_tunnel_failed:
xfrm4_protocol_deregister(&vti_ipcomp4_protocol, IPPROTO_COMP);
xfrm_proto_comp_failed:
xfrm4_protocol_deregister(&vti_ah4_protocol, IPPROTO_AH);
@@ -631,6 +663,7 @@ static int __init vti_init(void)
static void __exit vti_fini(void)
{
rtnl_link_unregister(&vti_link_ops);
+ xfrm4_tunnel_deregister(&vti_ip4_tunnnel, AF_INET);
xfrm4_protocol_deregister(&vti_ipcomp4_protocol, IPPROTO_COMP);
xfrm4_protocol_deregister(&vti_ah4_protocol, IPPROTO_AH);
xfrm4_protocol_deregister(&vti_esp4_protocol, IPPROTO_ESP);
Thanks,
Alexey
Powered by blists - more mailing lists