[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