kernel: fix flow offload issues with pppoe
sync xt_FLOWOFFLOAD code with latest version of nft_flow_offload Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Fri, 6 May 2022 12:37:23 +0200
|
||||
Subject: [PATCH] netfilter: flowtable: fix excessive hw offload attempts
|
||||
after failure
|
||||
|
||||
If a flow cannot be offloaded, the code currently repeatedly tries again as
|
||||
quickly as possible, which can significantly increase system load.
|
||||
Fix this by limiting flow timeout update and hardware offload retry to once
|
||||
per second.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/netfilter/nf_flow_table_core.c
|
||||
+++ b/net/netfilter/nf_flow_table_core.c
|
||||
@@ -329,8 +329,10 @@ void flow_offload_refresh(struct nf_flow
|
||||
u32 timeout;
|
||||
|
||||
timeout = nf_flowtable_time_stamp + flow_offload_get_timeout(flow);
|
||||
- if (READ_ONCE(flow->timeout) != timeout)
|
||||
+ if (timeout - READ_ONCE(flow->timeout) > HZ)
|
||||
WRITE_ONCE(flow->timeout, timeout);
|
||||
+ else
|
||||
+ return;
|
||||
|
||||
if (likely(!nf_flowtable_hw_offload(flow_table)))
|
||||
return;
|
||||
@@ -0,0 +1,64 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Fri, 6 May 2022 12:43:58 +0200
|
||||
Subject: [PATCH] netfilter: nft_flow_offload: skip dst neigh lookup for
|
||||
ppp devices
|
||||
|
||||
The dst entry does not contain a valid hardware address, so skip the lookup
|
||||
in order to avoid running into errors here.
|
||||
The proper hardware address is filled in from nft_dev_path_info
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/net/netfilter/nft_flow_offload.c
|
||||
+++ b/net/netfilter/nft_flow_offload.c
|
||||
@@ -36,6 +36,15 @@ static void nft_default_forward_path(str
|
||||
route->tuple[dir].xmit_type = nft_xmit_type(dst_cache);
|
||||
}
|
||||
|
||||
+static bool nft_is_valid_ether_device(const struct net_device *dev)
|
||||
+{
|
||||
+ if (!dev || (dev->flags & IFF_LOOPBACK) || dev->type != ARPHRD_ETHER ||
|
||||
+ dev->addr_len != ETH_ALEN || !is_valid_ether_addr(dev->dev_addr))
|
||||
+ return false;
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
static int nft_dev_fill_forward_path(const struct nf_flow_route *route,
|
||||
const struct dst_entry *dst_cache,
|
||||
const struct nf_conn *ct,
|
||||
@@ -47,6 +56,9 @@ static int nft_dev_fill_forward_path(con
|
||||
struct neighbour *n;
|
||||
u8 nud_state;
|
||||
|
||||
+ if (!nft_is_valid_ether_device(dev))
|
||||
+ goto out;
|
||||
+
|
||||
n = dst_neigh_lookup(dst_cache, daddr);
|
||||
if (!n)
|
||||
return -1;
|
||||
@@ -60,6 +72,7 @@ static int nft_dev_fill_forward_path(con
|
||||
if (!(nud_state & NUD_VALID))
|
||||
return -1;
|
||||
|
||||
+out:
|
||||
return dev_fill_forward_path(dev, ha, stack);
|
||||
}
|
||||
|
||||
@@ -78,15 +91,6 @@ struct nft_forward_info {
|
||||
enum flow_offload_xmit_type xmit_type;
|
||||
};
|
||||
|
||||
-static bool nft_is_valid_ether_device(const struct net_device *dev)
|
||||
-{
|
||||
- if (!dev || (dev->flags & IFF_LOOPBACK) || dev->type != ARPHRD_ETHER ||
|
||||
- dev->addr_len != ETH_ALEN || !is_valid_ether_addr(dev->dev_addr))
|
||||
- return false;
|
||||
-
|
||||
- return true;
|
||||
-}
|
||||
-
|
||||
static void nft_dev_path_info(const struct net_device_path_stack *stack,
|
||||
struct nft_forward_info *info,
|
||||
unsigned char *ha, struct nf_flowtable *flowtable)
|
||||
@@ -0,0 +1,66 @@
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Fri, 6 May 2022 13:54:44 +0200
|
||||
Subject: [PATCH] net: fix dev_fill_forward_path with pppoe + bridge
|
||||
|
||||
When calling dev_fill_forward_path on a pppoe device, the provided destination
|
||||
address is invalid. In order for the bridge fdb lookup to succeed, the pppoe
|
||||
code needs to update ctx->daddr to the correct value.
|
||||
Fix this by storing the address inside struct net_device_path_ctx
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
---
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_ppe_offload.c
|
||||
@@ -90,7 +90,6 @@ mtk_flow_get_wdma_info(struct net_device
|
||||
{
|
||||
struct net_device_path_ctx ctx = {
|
||||
.dev = dev,
|
||||
- .daddr = addr,
|
||||
};
|
||||
struct net_device_path path = {};
|
||||
|
||||
@@ -100,6 +99,7 @@ mtk_flow_get_wdma_info(struct net_device
|
||||
if (!dev->netdev_ops->ndo_fill_forward_path)
|
||||
return -1;
|
||||
|
||||
+ memcpy(ctx.daddr, addr, sizeof(ctx.daddr));
|
||||
if (dev->netdev_ops->ndo_fill_forward_path(&ctx, &path))
|
||||
return -1;
|
||||
|
||||
--- a/drivers/net/ppp/pppoe.c
|
||||
+++ b/drivers/net/ppp/pppoe.c
|
||||
@@ -988,6 +988,7 @@ static int pppoe_fill_forward_path(struc
|
||||
path->encap.proto = htons(ETH_P_PPP_SES);
|
||||
path->encap.id = be16_to_cpu(po->num);
|
||||
memcpy(path->encap.h_dest, po->pppoe_pa.remote, ETH_ALEN);
|
||||
+ memcpy(ctx->daddr, po->pppoe_pa.remote, ETH_ALEN);
|
||||
path->dev = ctx->dev;
|
||||
ctx->dev = dev;
|
||||
|
||||
--- a/include/linux/netdevice.h
|
||||
+++ b/include/linux/netdevice.h
|
||||
@@ -894,7 +894,7 @@ struct net_device_path_stack {
|
||||
|
||||
struct net_device_path_ctx {
|
||||
const struct net_device *dev;
|
||||
- const u8 *daddr;
|
||||
+ u8 daddr[ETH_ALEN];
|
||||
|
||||
int num_vlans;
|
||||
struct {
|
||||
--- a/net/core/dev.c
|
||||
+++ b/net/core/dev.c
|
||||
@@ -741,11 +741,11 @@ int dev_fill_forward_path(const struct n
|
||||
const struct net_device *last_dev;
|
||||
struct net_device_path_ctx ctx = {
|
||||
.dev = dev,
|
||||
- .daddr = daddr,
|
||||
};
|
||||
struct net_device_path *path;
|
||||
int ret = 0;
|
||||
|
||||
+ memcpy(ctx.daddr, daddr, sizeof(ctx.daddr));
|
||||
stack->num_paths = 0;
|
||||
while (ctx.dev && ctx.dev->netdev_ops->ndo_fill_forward_path) {
|
||||
last_dev = ctx.dev;
|
||||
@@ -0,0 +1,24 @@
|
||||
From: Felix Fietkau <nbd@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@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++;
|
||||
Reference in New Issue
Block a user