[PATCH-22.03 4/4] kernel: xt_FLOWOFFLOAD: support more complete flowtable

LiXiong Liu lxliu at ikuai8.com
Thu Nov 24 03:24:08 PST 2022


1. fix an crash bug at 'devs[dir] = xt_out(par)'.
   dir = CTINFO2DIR(ctinfo), it must before 'devs[dir] = xt_out(par)'.
2. not recommended use hardware offload if encaps >= 2
   hardware cannot dispose (8021q+8021q+pppoe) L2 head.
3. already solved PPPoE header offset issue, so need remove
   704-03-netfilter-nft_flow_offload-fix-offload-with-pppoe-vl.patch

Signed-off-by: LiXiong Liu <lxliu at ikuai8.com>
---
 ...ft_flow_offload-fix-offload-with-pppoe-vl.patch |  24 -----
 ...tfilter-xt_FLOWOFFLOAD-support-qinq-pppoe.patch | 107 +++++++++++++++++++++
 2 files changed, 107 insertions(+), 24 deletions(-)
 delete mode 100644 target/linux/generic/pending-5.10/704-03-netfilter-nft_flow_offload-fix-offload-with-pppoe-vl.patch
 create mode 100644 target/linux/generic/pending-5.10/706-04-netfilter-xt_FLOWOFFLOAD-support-qinq-pppoe.patch

diff --git a/target/linux/generic/pending-5.10/704-03-netfilter-nft_flow_offload-fix-offload-with-pppoe-vl.patch b/target/linux/generic/pending-5.10/704-03-netfilter-nft_flow_offload-fix-offload-with-pppoe-vl.patch
deleted file mode 100644
index 1e0dc99..0000000
--- a/target/linux/generic/pending-5.10/704-03-netfilter-nft_flow_offload-fix-offload-with-pppoe-vl.patch
+++ /dev/null
@@ -1,24 +0,0 @@
-From: Felix Fietkau <nbd at nbd.name>
-Date: Fri, 6 May 2022 15:15:06 +0200
-Subject: [PATCH] netfilter: nft_flow_offload: fix offload with pppoe +
- vlan
-
-When running a combination of PPPoE on top of a VLAN, we need to set
-info->outdev to the PPPoE device, otherwise PPPoE encap is skipped
-during software offload.
-
-Signed-off-by: Felix Fietkau <nbd at nbd.name>
----
-
---- a/net/netfilter/nft_flow_offload.c
-+++ b/net/netfilter/nft_flow_offload.c
-@@ -123,7 +123,8 @@ static void nft_dev_path_info(const stru
- 				info->indev = NULL;
- 				break;
- 			}
--			info->outdev = path->dev;
-+			if (!info->outdev)
-+				info->outdev = path->dev;
- 			info->encap[info->num_encaps].id = path->encap.id;
- 			info->encap[info->num_encaps].proto = path->encap.proto;
- 			info->num_encaps++;
diff --git a/target/linux/generic/pending-5.10/706-04-netfilter-xt_FLOWOFFLOAD-support-qinq-pppoe.patch b/target/linux/generic/pending-5.10/706-04-netfilter-xt_FLOWOFFLOAD-support-qinq-pppoe.patch
new file mode 100644
index 0000000..e9289b5
--- /dev/null
+++ b/target/linux/generic/pending-5.10/706-04-netfilter-xt_FLOWOFFLOAD-support-qinq-pppoe.patch
@@ -0,0 +1,107 @@
+--- a/net/netfilter/xt_FLOWOFFLOAD.c
++++ b/net/netfilter/xt_FLOWOFFLOAD.c
+@@ -51,11 +51,11 @@ static DEFINE_SPINLOCK(hooks_lock);
+ 
+ struct xt_flowoffload_table flowtable[2];
+ 
+-static inline __be16 nf_flow_pppoe_proto(const struct sk_buff *skb)
++static inline __be16 nf_flow_pppoe_proto(const struct sk_buff *skb, u16 offset)
+ {
+ 	__be16 proto;
+ 
+-	proto = *((__be16 *)(skb_mac_header(skb) + ETH_HLEN +
++	proto = *((__be16 *)(skb_mac_header(skb) + ETH_HLEN + offset +
+ 			     sizeof(struct pppoe_hdr)));
+ 	switch (proto) {
+ 	case htons(PPP_IP):
+@@ -72,26 +72,33 @@ xt_flowoffload_net_hook(void *priv, stru
+ 			const struct nf_hook_state *state)
+ {
+ 	struct vlan_ethhdr *veth;
+-	__be16 proto;
++	__be16 proto, offset = 0;
+ 
+ 	switch (skb->protocol) {
+ 	case htons(ETH_P_8021Q):
+ 		veth = (struct vlan_ethhdr *)skb_mac_header(skb);
+ 		proto = veth->h_vlan_encapsulated_proto;
++		offset += VLAN_HLEN;
+ 		break;
+ 	case htons(ETH_P_PPP_SES):
+-		proto = nf_flow_pppoe_proto(skb);
++		proto = nf_flow_pppoe_proto(skb, offset);
+ 		break;
+ 	default:
+ 		proto = skb->protocol;
+ 		break;
+ 	}
+ 
++check_ip:
+ 	switch (proto) {
+ 	case htons(ETH_P_IP):
+ 		return nf_flow_offload_ip_hook(priv, skb, state);
+ 	case htons(ETH_P_IPV6):
+ 		return nf_flow_offload_ipv6_hook(priv, skb, state);
++	case htons(ETH_P_PPP_SES):
++		proto = nf_flow_pppoe_proto(skb, offset);
++		offset += PPPOE_SES_HLEN;
++		goto check_ip;
++		break;
+ 	}
+ 
+ 	return NF_ACCEPT;
+@@ -311,7 +318,8 @@ static void nf_dev_path_info(const struc
+ 		case DEV_PATH_DSA:
+ 		case DEV_PATH_VLAN:
+ 		case DEV_PATH_PPPOE:
+-			info->indev = path->dev;
++			info->indev  = path->dev;
++			info->outdev = path->dev;
+ 			if (is_zero_ether_addr(info->h_source))
+ 				memcpy(info->h_source, path->dev->dev_addr, ETH_ALEN);
+ 
+@@ -324,11 +332,11 @@ static void nf_dev_path_info(const struc
+ 
+ 			/* DEV_PATH_VLAN and DEV_PATH_PPPOE */
+ 			if (info->num_encaps >= NF_FLOW_TABLE_ENCAP_MAX) {
+-				info->indev = NULL;
++				info->indev  = NULL;
++				info->outdev = NULL;
+ 				break;
+ 			}
+-			if (!info->outdev)
+-				info->outdev = path->dev;
++
+ 			info->encap[info->num_encaps].id = path->encap.id;
+ 			info->encap[info->num_encaps].proto = path->encap.proto;
+ 			info->num_encaps++;
+@@ -518,6 +526,7 @@ flowoffload_tg(struct sk_buff *skb, cons
+ 	if (!nf_ct_is_confirmed(ct))
+ 		return XT_CONTINUE;
+ 
++	dir = CTINFO2DIR(ctinfo);
+ 	devs[dir] = xt_out(par);
+ 	devs[!dir] = xt_in(par);
+ 
+@@ -527,8 +536,6 @@ flowoffload_tg(struct sk_buff *skb, cons
+ 	if (test_and_set_bit(IPS_OFFLOAD_BIT, &ct->status))
+ 		return XT_CONTINUE;
+ 
+-	dir = CTINFO2DIR(ctinfo);
+-
+ 	if (xt_flowoffload_route(skb, ct, par, &route, dir, devs) < 0)
+ 		goto err_flow_route;
+ 
+@@ -544,7 +551,11 @@ flowoffload_tg(struct sk_buff *skb, cons
+ 		ct->proto.tcp.seen[1].flags |= IP_CT_TCP_FLAG_BE_LIBERAL;
+ 	}
+ 
+-	table = &flowtable[!!(info->flags & XT_FLOWOFFLOAD_HW)];
++	/* not recommended use hardware offload if encaps >= 2 */
++	if(route.tuple[0].in.num_encaps >= 2 || route.tuple[1].in.num_encaps >= 2)
++		table = &flowtable[0];
++	else
++		table = &flowtable[!!(info->flags & XT_FLOWOFFLOAD_HW)];
+ 
+ 	net = read_pnet(&table->ft.net);
+ 	if (!net)
-- 
2.7.4




More information about the openwrt-devel mailing list