[openwrt/openwrt] kernel: check dst of flow offloading table

LEDE Commits lede-commits at lists.infradead.org
Sun Jul 3 11:23:02 PDT 2022


hauke pushed a commit to openwrt/openwrt.git, branch openwrt-21.02:
https://git.openwrt.org/6d891adf390dd232c63fa77a8e71750495c04159

commit 6d891adf390dd232c63fa77a8e71750495c04159
Author: Ritaro Takenaka <ritarot634 at gmail.com>
AuthorDate: Wed May 25 15:55:48 2022 +0900

    kernel: check dst of flow offloading table
    
    Flow offload dst can become invalid after the route cache is created.
    dst_check() in packet path is necessary to prevent packet drop.
    
    Signed-off-by: Ritaro Takenaka <ritarot634 at gmail.com>
---
 ...er-flowtable-add-check_dst-in-packet-path.patch | 97 ++++++++++++++++++++++
 .../generic/hack-5.4/647-netfilter-flow-acct.patch |  8 +-
 .../650-netfilter-add-xt_OFFLOAD-target.patch      |  6 +-
 ...f_flow_table-add-hardware-offload-support.patch | 18 ++--
 ...f_flow_table-support-hw-offload-through-v.patch |  2 +-
 ...f_flow_table-rework-hardware-offload-time.patch |  4 +-
 ...-nf_flow_table-rework-private-driver-data.patch |  2 +-
 ...t-dsa-support-hardware-flow-table-offload.patch |  4 +-
 8 files changed, 119 insertions(+), 22 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 at 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 at 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;
+ 	}
diff --git a/target/linux/generic/hack-5.4/647-netfilter-flow-acct.patch b/target/linux/generic/hack-5.4/647-netfilter-flow-acct.patch
index f9480d59d1..9f7ca61546 100644
--- a/target/linux/generic/hack-5.4/647-netfilter-flow-acct.patch
+++ b/target/linux/generic/hack-5.4/647-netfilter-flow-acct.patch
@@ -1,6 +1,6 @@
 --- a/include/net/netfilter/nf_flow_table.h
 +++ b/include/net/netfilter/nf_flow_table.h
-@@ -160,6 +160,8 @@ struct nf_flow_table_hw {
+@@ -163,6 +163,8 @@ struct nf_flow_table_hw {
  int nf_flow_table_hw_register(const struct nf_flow_table_hw *offload);
  void nf_flow_table_hw_unregister(const struct nf_flow_table_hw *offload);
  
@@ -19,7 +19,7 @@
  
  struct flow_offload_entry {
  	struct flow_offload	flow;
-@@ -164,6 +165,22 @@ void flow_offload_free(struct flow_offlo
+@@ -177,6 +178,22 @@ void flow_offload_free(struct flow_offlo
  }
  EXPORT_SYMBOL_GPL(flow_offload_free);
  
@@ -52,7 +52,7 @@
  /* For layer 4 checksum field offset. */
  #include <linux/tcp.h>
  #include <linux/udp.h>
-@@ -296,6 +297,7 @@ nf_flow_offload_ip_hook(void *priv, stru
+@@ -288,6 +289,7 @@ nf_flow_offload_ip_hook(void *priv, stru
  	skb->dev = outdev;
  	nexthop = rt_nexthop(rt, flow->tuplehash[!dir].tuple.src_v4.s_addr);
  	skb_dst_set_noref(skb, &rt->dst);
@@ -60,7 +60,7 @@
  	neigh_xmit(NEIGH_ARP_TABLE, outdev, &nexthop, skb);
  
  	return NF_STOLEN;
-@@ -526,6 +528,7 @@ nf_flow_offload_ipv6_hook(void *priv, st
+@@ -518,6 +520,7 @@ nf_flow_offload_ipv6_hook(void *priv, st
  	skb->dev = outdev;
  	nexthop = rt6_nexthop(rt, &flow->tuplehash[!dir].tuple.src_v6);
  	skb_dst_set_noref(skb, &rt->dst);
diff --git a/target/linux/generic/hack-5.4/650-netfilter-add-xt_OFFLOAD-target.patch b/target/linux/generic/hack-5.4/650-netfilter-add-xt_OFFLOAD-target.patch
index d584cb5c6c..0da4ad4432 100644
--- a/target/linux/generic/hack-5.4/650-netfilter-add-xt_OFFLOAD-target.patch
+++ b/target/linux/generic/hack-5.4/650-netfilter-add-xt_OFFLOAD-target.patch
@@ -536,7 +536,7 @@ Signed-off-by: Felix Fietkau <nbd at nbd.name>
  #include <net/netfilter/nf_flow_table.h>
  #include <net/netfilter/nf_conntrack.h>
  #include <net/netfilter/nf_conntrack_core.h>
-@@ -338,8 +337,7 @@ flow_offload_lookup(struct nf_flowtable
+@@ -351,8 +350,7 @@ flow_offload_lookup(struct nf_flowtable
  }
  EXPORT_SYMBOL_GPL(flow_offload_lookup);
  
@@ -546,7 +546,7 @@ Signed-off-by: Felix Fietkau <nbd at nbd.name>
  		      void (*iter)(struct flow_offload *flow, void *data),
  		      void *data)
  {
-@@ -372,6 +370,7 @@ nf_flow_table_iterate(struct nf_flowtabl
+@@ -385,6 +383,7 @@ nf_flow_table_iterate(struct nf_flowtabl
  
  	return err;
  }
@@ -576,7 +576,7 @@ Signed-off-by: Felix Fietkau <nbd at nbd.name>
 +#endif /* _XT_FLOWOFFLOAD_H */
 --- a/include/net/netfilter/nf_flow_table.h
 +++ b/include/net/netfilter/nf_flow_table.h
-@@ -130,6 +130,10 @@ static inline void flow_offload_dead(str
+@@ -133,6 +133,10 @@ static inline void flow_offload_dead(str
  	flow->flags |= FLOW_OFFLOAD_DYING;
  }
  
diff --git a/target/linux/generic/pending-5.4/640-netfilter-nf_flow_table-add-hardware-offload-support.patch b/target/linux/generic/pending-5.4/640-netfilter-nf_flow_table-add-hardware-offload-support.patch
index 1dbf49a97f..6192df9319 100644
--- a/target/linux/generic/pending-5.4/640-netfilter-nf_flow_table-add-hardware-offload-support.patch
+++ b/target/linux/generic/pending-5.4/640-netfilter-nf_flow_table-add-hardware-offload-support.patch
@@ -77,7 +77,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>
  };
  
  enum flow_offload_tuple_dir {
-@@ -68,6 +74,7 @@ struct flow_offload_tuple_rhash {
+@@ -71,6 +77,7 @@ struct flow_offload_tuple_rhash {
  #define FLOW_OFFLOAD_DNAT	0x2
  #define FLOW_OFFLOAD_DYING	0x4
  #define FLOW_OFFLOAD_TEARDOWN	0x8
@@ -85,7 +85,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>
  
  struct flow_offload {
  	struct flow_offload_tuple_rhash		tuplehash[FLOW_OFFLOAD_DIR_MAX];
-@@ -120,6 +127,22 @@ unsigned int nf_flow_offload_ip_hook(voi
+@@ -123,6 +130,22 @@ unsigned int nf_flow_offload_ip_hook(voi
  unsigned int nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb,
  				       const struct nf_hook_state *state);
  
@@ -156,7 +156,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>
  obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o
 --- a/net/netfilter/nf_flow_table_core.c
 +++ b/net/netfilter/nf_flow_table_core.c
-@@ -248,10 +248,16 @@ static inline bool nf_flow_has_expired(c
+@@ -261,10 +261,16 @@ static inline bool nf_flow_has_expired(c
  	return nf_flow_timeout_delta(flow->timeout) <= 0;
  }
  
@@ -173,7 +173,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>
  
  	rhashtable_remove_fast(&flow_table->rhashtable,
  			       &flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].node,
-@@ -271,6 +277,9 @@ static void flow_offload_del(struct nf_f
+@@ -284,6 +290,9 @@ static void flow_offload_del(struct nf_f
  	if (!(flow->flags & FLOW_OFFLOAD_TEARDOWN))
  		flow_offload_fixup_ct_state(e->ct);
  
@@ -183,7 +183,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>
  	flow_offload_free(flow);
  }
  
-@@ -361,6 +370,9 @@ static void nf_flow_offload_gc_step(stru
+@@ -374,6 +383,9 @@ static void nf_flow_offload_gc_step(stru
  	if (!teardown)
  		nf_ct_offload_timeout(flow);
  
@@ -193,7 +193,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>
  	if (nf_flow_has_expired(flow) || teardown)
  		flow_offload_del(flow_table, flow);
  }
-@@ -490,10 +502,43 @@ int nf_flow_dnat_port(const struct flow_
+@@ -503,10 +515,43 @@ int nf_flow_dnat_port(const struct flow_
  }
  EXPORT_SYMBOL_GPL(nf_flow_dnat_port);
  
@@ -237,7 +237,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>
  	INIT_DEFERRABLE_WORK(&flowtable->gc_work, nf_flow_offload_work_gc);
  
  	err = rhashtable_init(&flowtable->rhashtable,
-@@ -534,6 +579,8 @@ static void nf_flow_table_iterate_cleanu
+@@ -547,6 +592,8 @@ static void nf_flow_table_iterate_cleanu
  {
  	nf_flow_table_iterate(flowtable, nf_flow_table_do_cleanup, dev);
  	flush_delayed_work(&flowtable->gc_work);
@@ -246,7 +246,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>
  }
  
  void nf_flow_table_cleanup(struct net_device *dev)
-@@ -547,6 +594,26 @@ void nf_flow_table_cleanup(struct net_de
+@@ -560,6 +607,26 @@ void nf_flow_table_cleanup(struct net_de
  }
  EXPORT_SYMBOL_GPL(nf_flow_table_cleanup);
  
@@ -273,7 +273,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo at netfilter.org>
  void nf_flow_table_free(struct nf_flowtable *flow_table)
  {
  	mutex_lock(&flowtable_lock);
-@@ -556,9 +623,58 @@ void nf_flow_table_free(struct nf_flowta
+@@ -569,9 +636,58 @@ void nf_flow_table_free(struct nf_flowta
  	nf_flow_table_iterate(flow_table, nf_flow_table_do_cleanup, NULL);
  	nf_flow_table_iterate(flow_table, nf_flow_offload_gc_step, flow_table);
  	rhashtable_destroy(&flow_table->rhashtable);
diff --git a/target/linux/generic/pending-5.4/641-netfilter-nf_flow_table-support-hw-offload-through-v.patch b/target/linux/generic/pending-5.4/641-netfilter-nf_flow_table-support-hw-offload-through-v.patch
index b808c0257d..ae9f7f0d83 100644
--- a/target/linux/generic/pending-5.4/641-netfilter-nf_flow_table-support-hw-offload-through-v.patch
+++ b/target/linux/generic/pending-5.4/641-netfilter-nf_flow_table-support-hw-offload-through-v.patch
@@ -55,7 +55,7 @@ Signed-off-by: Felix Fietkau <nbd at nbd.name>
  	int			(*ndo_get_phys_port_id)(struct net_device *dev,
 --- a/include/net/netfilter/nf_flow_table.h
 +++ b/include/net/netfilter/nf_flow_table.h
-@@ -85,6 +85,21 @@ struct flow_offload {
+@@ -88,6 +88,21 @@ struct flow_offload {
  	};
  };
  
diff --git a/target/linux/generic/pending-5.4/645-netfilter-nf_flow_table-rework-hardware-offload-time.patch b/target/linux/generic/pending-5.4/645-netfilter-nf_flow_table-rework-hardware-offload-time.patch
index 3c44c29273..f4efbcdda8 100644
--- a/target/linux/generic/pending-5.4/645-netfilter-nf_flow_table-rework-hardware-offload-time.patch
+++ b/target/linux/generic/pending-5.4/645-netfilter-nf_flow_table-rework-hardware-offload-time.patch
@@ -16,7 +16,7 @@ Signed-off-by: Felix Fietkau <nbd at nbd.name>
 
 --- a/include/net/netfilter/nf_flow_table.h
 +++ b/include/net/netfilter/nf_flow_table.h
-@@ -75,6 +75,7 @@ struct flow_offload_tuple_rhash {
+@@ -78,6 +78,7 @@ struct flow_offload_tuple_rhash {
  #define FLOW_OFFLOAD_DYING	0x4
  #define FLOW_OFFLOAD_TEARDOWN	0x8
  #define FLOW_OFFLOAD_HW		0x10
@@ -26,7 +26,7 @@ Signed-off-by: Felix Fietkau <nbd at nbd.name>
  	struct flow_offload_tuple_rhash		tuplehash[FLOW_OFFLOAD_DIR_MAX];
 --- a/net/netfilter/nf_flow_table_core.c
 +++ b/net/netfilter/nf_flow_table_core.c
-@@ -370,7 +370,7 @@ static void nf_flow_offload_gc_step(stru
+@@ -383,7 +383,7 @@ static void nf_flow_offload_gc_step(stru
  	if (!teardown)
  		nf_ct_offload_timeout(flow);
  
diff --git a/target/linux/generic/pending-5.4/646-netfilter-nf_flow_table-rework-private-driver-data.patch b/target/linux/generic/pending-5.4/646-netfilter-nf_flow_table-rework-private-driver-data.patch
index 159ad8a0aa..235f2a3710 100644
--- a/target/linux/generic/pending-5.4/646-netfilter-nf_flow_table-rework-private-driver-data.patch
+++ b/target/linux/generic/pending-5.4/646-netfilter-nf_flow_table-rework-private-driver-data.patch
@@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau <nbd at nbd.name>
 
 --- a/include/net/netfilter/nf_flow_table.h
 +++ b/include/net/netfilter/nf_flow_table.h
-@@ -80,9 +80,10 @@ struct flow_offload_tuple_rhash {
+@@ -83,9 +83,10 @@ struct flow_offload_tuple_rhash {
  struct flow_offload {
  	struct flow_offload_tuple_rhash		tuplehash[FLOW_OFFLOAD_DIR_MAX];
  	u32					flags;
diff --git a/target/linux/generic/pending-5.4/647-net-dsa-support-hardware-flow-table-offload.patch b/target/linux/generic/pending-5.4/647-net-dsa-support-hardware-flow-table-offload.patch
index 91aae5b65c..369a09caac 100644
--- a/target/linux/generic/pending-5.4/647-net-dsa-support-hardware-flow-table-offload.patch
+++ b/target/linux/generic/pending-5.4/647-net-dsa-support-hardware-flow-table-offload.patch
@@ -9,7 +9,7 @@ Signed-off-by: Felix Fietkau <nbd at nbd.name>
 
 --- a/include/net/netfilter/nf_flow_table.h
 +++ b/include/net/netfilter/nf_flow_table.h
-@@ -90,6 +90,7 @@ struct flow_offload {
+@@ -93,6 +93,7 @@ struct flow_offload {
  #define FLOW_OFFLOAD_PATH_ETHERNET	BIT(0)
  #define FLOW_OFFLOAD_PATH_VLAN		BIT(1)
  #define FLOW_OFFLOAD_PATH_PPPOE		BIT(2)
@@ -17,7 +17,7 @@ Signed-off-by: Felix Fietkau <nbd at nbd.name>
  
  struct flow_offload_hw_path {
  	struct net_device *dev;
-@@ -100,6 +101,7 @@ struct flow_offload_hw_path {
+@@ -103,6 +104,7 @@ struct flow_offload_hw_path {
  	u16 vlan_proto;
  	u16 vlan_id;
  	u16 pppoe_sid;




More information about the lede-commits mailing list