netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH nf 1/2] selftests: netfilter: extend flowtable test script for ipsec
@ 2019-07-30 12:57 Florian Westphal
  2019-07-30 12:57 ` [PATCH nf 2/2] netfilter: nf_flow_table: fix offload for flows that are subject to xfrm Florian Westphal
  2019-08-05  9:30 ` [PATCH nf 1/2] selftests: netfilter: extend flowtable test script for ipsec Pablo Neira Ayuso
  0 siblings, 2 replies; 4+ messages in thread
From: Florian Westphal @ 2019-07-30 12:57 UTC (permalink / raw)
  To: netfilter-devel; +Cc: steffen.klassert, Florian Westphal

'flow offload' expression should not offload flows that will be subject
to ipsec, but it does.

This results in a connectivity blackhole for the affected flows -- first
packets will go through (offload happens after established state is
reached), but all remaining ones bypass ipsec encryption and are thus
discarded by the peer.

This can be worked around by adding "rt ipsec exists accept"
before the 'flow offload' rule matches.

This test case will fail, support for such flows is added in
next patch.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 .../selftests/netfilter/nft_flowtable.sh      | 48 +++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/tools/testing/selftests/netfilter/nft_flowtable.sh b/tools/testing/selftests/netfilter/nft_flowtable.sh
index fe52488a6f72..16571ac1dab4 100755
--- a/tools/testing/selftests/netfilter/nft_flowtable.sh
+++ b/tools/testing/selftests/netfilter/nft_flowtable.sh
@@ -321,4 +321,52 @@ else
 	ip netns exec nsr1 nft list ruleset
 fi
 
+KEY_SHA="0x"$(ps -xaf | sha1sum | cut -d " " -f 1)
+KEY_AES="0x"$(ps -xaf | md5sum | cut -d " " -f 1)
+SPI1=$RANDOM
+SPI2=$RANDOM
+
+if [ $SPI1 -eq $SPI2 ]; then
+	SPI2=$((SPI2+1))
+fi
+
+do_esp() {
+    local ns=$1
+    local me=$2
+    local remote=$3
+    local lnet=$4
+    local rnet=$5
+    local spi_out=$6
+    local spi_in=$7
+
+    ip -net $ns xfrm state add src $remote dst $me proto esp spi $spi_in  enc aes $KEY_AES  auth sha1 $KEY_SHA mode tunnel sel src $rnet dst $lnet
+    ip -net $ns xfrm state add src $me  dst $remote proto esp spi $spi_out enc aes $KEY_AES auth sha1 $KEY_SHA mode tunnel sel src $lnet dst $rnet
+
+    # to encrypt packets as they go out (includes forwarded packets that need encapsulation)
+    ip -net $ns xfrm policy add src $lnet dst $rnet dir out tmpl src $me dst $remote proto esp mode tunnel priority 1 action allow
+    # to fwd decrypted packets after esp processing:
+    ip -net $ns xfrm policy add src $rnet dst $lnet dir fwd tmpl src $remote dst $me proto esp mode tunnel priority 1 action allow
+
+}
+
+do_esp nsr1 192.168.10.1 192.168.10.2 10.0.1.0/24 10.0.2.0/24 $SPI1 $SPI2
+
+do_esp nsr2 192.168.10.2 192.168.10.1 10.0.2.0/24 10.0.1.0/24 $SPI2 $SPI1
+
+ip netns exec nsr1 nft delete table ip nat
+
+# restore default routes
+ip -net ns2 route del 192.168.10.1 via 10.0.2.1
+ip -net ns2 route add default via 10.0.2.1
+ip -net ns2 route add default via dead:2::1
+
+test_tcp_forwarding ns1 ns2
+if [ $? -eq 0 ] ;then
+	echo "PASS: ipsec tunnel mode for ns1/ns2"
+else
+	echo "FAIL: ipsec tunnel mode for ns1/ns2"
+	ip netns exec nsr1 nft list ruleset 1>&2
+	ip netns exec nsr1 cat /proc/net/xfrm_stat 1>&2
+fi
+
 exit $ret
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH nf 2/2] netfilter: nf_flow_table: fix offload for flows that are subject to xfrm
  2019-07-30 12:57 [PATCH nf 1/2] selftests: netfilter: extend flowtable test script for ipsec Florian Westphal
@ 2019-07-30 12:57 ` Florian Westphal
  2019-08-05  9:30   ` Pablo Neira Ayuso
  2019-08-05  9:30 ` [PATCH nf 1/2] selftests: netfilter: extend flowtable test script for ipsec Pablo Neira Ayuso
  1 sibling, 1 reply; 4+ messages in thread
From: Florian Westphal @ 2019-07-30 12:57 UTC (permalink / raw)
  To: netfilter-devel; +Cc: steffen.klassert, Florian Westphal

This makes the previously added 'encap test' pass.
Because its possible that the xfrm dst entry becomes stale while such
a flow is offloaded, we need to call dst_check() -- the notifier that
handles this for non-tunneled traffic isn't sufficient, because SA or
or policies might have changed.

If dst becomes stale the flow offload entry will be tagged for teardown
and packets will be passed to 'classic' forwarding path.

Removing the entry right away is problematic, as this would
introduce a race condition with the gc worker.

In case flow is long-lived, it could eventually be offloaded again
once the gc worker removes the entry from the flow table.

Signed-off-by: Florian Westphal <fw@strlen.de>
---
 net/netfilter/nf_flow_table_ip.c | 43 ++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/net/netfilter/nf_flow_table_ip.c b/net/netfilter/nf_flow_table_ip.c
index cdfc33517e85..d68c801dd614 100644
--- a/net/netfilter/nf_flow_table_ip.c
+++ b/net/netfilter/nf_flow_table_ip.c
@@ -214,6 +214,25 @@ static bool nf_flow_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu)
 	return true;
 }
 
+static int nf_flow_offload_dst_check(struct dst_entry *dst)
+{
+	if (unlikely(dst_xfrm(dst)))
+		return dst_check(dst, 0) ? 0 : -1;
+
+	return 0;
+}
+
+static unsigned int nf_flow_xmit_xfrm(struct sk_buff *skb,
+				      const struct nf_hook_state *state,
+				      struct dst_entry *dst)
+{
+	skb_orphan(skb);
+	skb_dst_set_noref(skb, dst);
+	skb->tstamp = 0;
+	dst_output(state->net, state->sk, skb);
+	return NF_STOLEN;
+}
+
 unsigned int
 nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb,
 			const struct nf_hook_state *state)
@@ -254,6 +273,11 @@ nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb,
 	if (nf_flow_state_check(flow, ip_hdr(skb)->protocol, skb, thoff))
 		return NF_ACCEPT;
 
+	if (nf_flow_offload_dst_check(&rt->dst)) {
+		flow_offload_teardown(flow);
+		return NF_ACCEPT;
+	}
+
 	if (nf_flow_nat_ip(flow, skb, thoff, dir) < 0)
 		return NF_DROP;
 
@@ -261,6 +285,13 @@ nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb,
 	iph = ip_hdr(skb);
 	ip_decrease_ttl(iph);
 
+	if (unlikely(dst_xfrm(&rt->dst))) {
+		memset(skb->cb, 0, sizeof(struct inet_skb_parm));
+		IPCB(skb)->iif = skb->dev->ifindex;
+		IPCB(skb)->flags = IPSKB_FORWARDED;
+		return nf_flow_xmit_xfrm(skb, state, &rt->dst);
+	}
+
 	skb->dev = outdev;
 	nexthop = rt_nexthop(rt, flow->tuplehash[!dir].tuple.src_v4.s_addr);
 	skb_dst_set_noref(skb, &rt->dst);
@@ -467,6 +498,11 @@ nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb,
 				sizeof(*ip6h)))
 		return NF_ACCEPT;
 
+	if (nf_flow_offload_dst_check(&rt->dst)) {
+		flow_offload_teardown(flow);
+		return NF_ACCEPT;
+	}
+
 	if (skb_try_make_writable(skb, sizeof(*ip6h)))
 		return NF_DROP;
 
@@ -477,6 +513,13 @@ nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb,
 	ip6h = ipv6_hdr(skb);
 	ip6h->hop_limit--;
 
+	if (unlikely(dst_xfrm(&rt->dst))) {
+		memset(skb->cb, 0, sizeof(struct inet6_skb_parm));
+		IP6CB(skb)->iif = skb->dev->ifindex;
+		IP6CB(skb)->flags = IP6SKB_FORWARDED;
+		return nf_flow_xmit_xfrm(skb, state, &rt->dst);
+	}
+
 	skb->dev = outdev;
 	nexthop = rt6_nexthop(rt, &flow->tuplehash[!dir].tuple.src_v6);
 	skb_dst_set_noref(skb, &rt->dst);
-- 
2.21.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH nf 1/2] selftests: netfilter: extend flowtable test script for ipsec
  2019-07-30 12:57 [PATCH nf 1/2] selftests: netfilter: extend flowtable test script for ipsec Florian Westphal
  2019-07-30 12:57 ` [PATCH nf 2/2] netfilter: nf_flow_table: fix offload for flows that are subject to xfrm Florian Westphal
@ 2019-08-05  9:30 ` Pablo Neira Ayuso
  1 sibling, 0 replies; 4+ messages in thread
From: Pablo Neira Ayuso @ 2019-08-05  9:30 UTC (permalink / raw)
  To: Florian Westphal; +Cc: netfilter-devel, steffen.klassert

On Tue, Jul 30, 2019 at 02:57:18PM +0200, Florian Westphal wrote:
> 'flow offload' expression should not offload flows that will be subject
> to ipsec, but it does.
> 
> This results in a connectivity blackhole for the affected flows -- first
> packets will go through (offload happens after established state is
> reached), but all remaining ones bypass ipsec encryption and are thus
> discarded by the peer.
> 
> This can be worked around by adding "rt ipsec exists accept"
> before the 'flow offload' rule matches.
> 
> This test case will fail, support for such flows is added in
> next patch.

Applied, thanks Florian.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH nf 2/2] netfilter: nf_flow_table: fix offload for flows that are subject to xfrm
  2019-07-30 12:57 ` [PATCH nf 2/2] netfilter: nf_flow_table: fix offload for flows that are subject to xfrm Florian Westphal
@ 2019-08-05  9:30   ` Pablo Neira Ayuso
  0 siblings, 0 replies; 4+ messages in thread
From: Pablo Neira Ayuso @ 2019-08-05  9:30 UTC (permalink / raw)
  To: Florian Westphal; +Cc: netfilter-devel, steffen.klassert

On Tue, Jul 30, 2019 at 02:57:19PM +0200, Florian Westphal wrote:
> This makes the previously added 'encap test' pass.
> Because its possible that the xfrm dst entry becomes stale while such
> a flow is offloaded, we need to call dst_check() -- the notifier that
> handles this for non-tunneled traffic isn't sufficient, because SA or
> or policies might have changed.
> 
> If dst becomes stale the flow offload entry will be tagged for teardown
> and packets will be passed to 'classic' forwarding path.
> 
> Removing the entry right away is problematic, as this would
> introduce a race condition with the gc worker.
> 
> In case flow is long-lived, it could eventually be offloaded again
> once the gc worker removes the entry from the flow table.

Also applied, thanks.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-08-05  9:31 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-07-30 12:57 [PATCH nf 1/2] selftests: netfilter: extend flowtable test script for ipsec Florian Westphal
2019-07-30 12:57 ` [PATCH nf 2/2] netfilter: nf_flow_table: fix offload for flows that are subject to xfrm Florian Westphal
2019-08-05  9:30   ` Pablo Neira Ayuso
2019-08-05  9:30 ` [PATCH nf 1/2] selftests: netfilter: extend flowtable test script for ipsec Pablo Neira Ayuso

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).