aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/generic/backport-5.4/610-v5.18-netfilter-flowtable-add-check_dst-in-packet-path.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/generic/backport-5.4/610-v5.18-netfilter-flowtable-add-check_dst-in-packet-path.patch')
-rw-r--r--target/linux/generic/backport-5.4/610-v5.18-netfilter-flowtable-add-check_dst-in-packet-path.patch97
1 files changed, 97 insertions, 0 deletions
diff --git a/target/linux/generic/backport-5.4/610-v5.18-netfilter-flowtable-add-check_dst-in-packet-path.patch b/target/linux/generic/backport-5.4/610-v5.18-netfilter-flowtable-add-check_dst-in-packet-path.patch
new file mode 100644
index 0000000000..8413f03714
--- /dev/null
+++ b/target/linux/generic/backport-5.4/610-v5.18-netfilter-flowtable-add-check_dst-in-packet-path.patch
@@ -0,0 +1,97 @@
+From 94936600fce68845edea66ae6d06ad12d6469e0b Mon Sep 17 00:00:00 2001
+From: Ritaro Takenaka <ritarot634@gmail.com>
+Date: Tue, 31 May 2022 00:25:08 +0900
+Subject: [PATCH] netfilter: flowtable: add check_dst in packet path
+
+Flow offload dst can become invalid after the route cache is created.
+dst_check() in packet path is necessary to prevent packet drop.
+
+[ Upstream commit 2738d9d963bd1f06d5114c2b4fa5771a95703991
+ 8b9229d15877ec77775633f058d14145f6eb98fa
+ e5075c0badaaac245a6fa0b4625b5cd714d8ade3 ]
+
+Signed-off-by: Ritaro Takenaka <ritarot634@gmail.com>
+---
+ include/net/netfilter/nf_flow_table.h | 5 ++++-
+ net/netfilter/nf_flow_table_core.c | 13 +++++++++++++
+ net/netfilter/nf_flow_table_ip.c | 12 ++----------
+ 3 files changed, 19 insertions(+), 11 deletions(-)
+
+--- a/include/net/netfilter/nf_flow_table.h
++++ b/include/net/netfilter/nf_flow_table.h
+@@ -56,7 +56,10 @@ struct flow_offload_tuple {
+
+ u16 mtu;
+
+- struct dst_entry *dst_cache;
++ struct {
++ struct dst_entry *dst_cache;
++ u32 dst_cookie;
++ };
+ };
+
+ struct flow_offload_tuple_rhash {
+--- a/net/netfilter/nf_flow_table_core.c
++++ b/net/netfilter/nf_flow_table_core.c
+@@ -23,6 +23,18 @@ struct flow_offload_entry {
+ static DEFINE_MUTEX(flowtable_lock);
+ static LIST_HEAD(flowtables);
+
++static u32 flow_offload_dst_cookie(struct flow_offload_tuple *flow_tuple)
++{
++ const struct rt6_info *rt;
++
++ if (flow_tuple->l3proto == NFPROTO_IPV6) {
++ rt = (const struct rt6_info *)flow_tuple->dst_cache;
++ return rt6_get_cookie(rt);
++ }
++
++ return 0;
++}
++
+ static void
+ flow_offload_fill_dir(struct flow_offload *flow, struct nf_conn *ct,
+ struct nf_flow_route *route,
+@@ -55,6 +67,7 @@ flow_offload_fill_dir(struct flow_offloa
+
+ ft->iifidx = other_dst->dev->ifindex;
+ ft->dst_cache = dst;
++ ft->dst_cookie = flow_offload_dst_cookie(ft);
+ }
+
+ struct flow_offload *
+--- a/net/netfilter/nf_flow_table_ip.c
++++ b/net/netfilter/nf_flow_table_ip.c
+@@ -215,14 +215,6 @@ static bool nf_flow_exceeds_mtu(const st
+ 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)
+@@ -273,7 +265,7 @@ nf_flow_offload_ip_hook(void *priv, stru
+ if (nf_flow_state_check(flow, ip_hdr(skb)->protocol, skb, thoff))
+ return NF_ACCEPT;
+
+- if (nf_flow_offload_dst_check(&rt->dst)) {
++ if (!dst_check(&rt->dst, 0)) {
+ flow_offload_teardown(flow);
+ return NF_ACCEPT;
+ }
+@@ -500,7 +492,7 @@ nf_flow_offload_ipv6_hook(void *priv, st
+ sizeof(*ip6h)))
+ return NF_ACCEPT;
+
+- if (nf_flow_offload_dst_check(&rt->dst)) {
++ if (!dst_check(&rt->dst, tuplehash->tuple.dst_cookie)) {
+ flow_offload_teardown(flow);
+ return NF_ACCEPT;
+ }