From: Pablo Neira Ayuso <pablo@netfilter.org>
To: netfilter-devel@vger.kernel.org
Cc: davem@davemloft.net, netdev@vger.kernel.org, kuba@kernel.org,
pabeni@redhat.com, edumazet@google.com, fw@strlen.de,
horms@kernel.org
Subject: [PATCH net-next 09/11] netfilter: flowtable: bail out if forward path cannot be discovered
Date: Sun, 14 Jun 2026 13:46:03 +0200 [thread overview]
Message-ID: <20260614114605.474783-10-pablo@netfilter.org> (raw)
In-Reply-To: <20260614114605.474783-1-pablo@netfilter.org>
If forward path discovery fails for any reason or netdevice is not
registered for this flowtable, then bail out to classic forwarding path
rather than providing incomplete forwarding path.
Update the existing forward path parser functions to report an error
so the flow_offload expressions gives up on setting up the flowtable
entry.
Link: https://sashiko.dev/#/patchset/20260607094954.48892-15-pablo%40netfilter.org?part=14
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/nf_flow_table_path.c | 81 +++++++++++++++++-------------
1 file changed, 46 insertions(+), 35 deletions(-)
diff --git a/net/netfilter/nf_flow_table_path.c b/net/netfilter/nf_flow_table_path.c
index a3e6b82f2f8e..1e7e216b9f89 100644
--- a/net/netfilter/nf_flow_table_path.c
+++ b/net/netfilter/nf_flow_table_path.c
@@ -90,9 +90,9 @@ struct nft_forward_info {
enum flow_offload_xmit_type xmit_type;
};
-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)
+static int nft_dev_path_info(const struct net_device_path_stack *stack,
+ struct nft_forward_info *info,
+ unsigned char *ha, struct nf_flowtable *flowtable)
{
const struct net_device_path *path;
int i;
@@ -120,19 +120,17 @@ static void nft_dev_path_info(const struct net_device_path_stack *stack,
/* DEV_PATH_VLAN, DEV_PATH_PPPOE and DEV_PATH_TUN */
if (path->type == DEV_PATH_TUN) {
- if (info->num_tuns) {
- info->indev = NULL;
- break;
- }
+ if (info->num_tuns)
+ return -1;
+
info->tun.src_v6 = path->tun.src_v6;
info->tun.dst_v6 = path->tun.dst_v6;
info->tun.l3_proto = path->tun.l3_proto;
info->num_tuns++;
} else {
- if (info->num_encaps >= NF_FLOW_TABLE_ENCAP_MAX) {
- info->indev = NULL;
- break;
- }
+ if (info->num_encaps >= NF_FLOW_TABLE_ENCAP_MAX)
+ return -1;
+
info->encap[info->num_encaps].id =
path->encap.id;
info->encap[info->num_encaps].proto =
@@ -151,22 +149,23 @@ static void nft_dev_path_info(const struct net_device_path_stack *stack,
switch (path->bridge.vlan_mode) {
case DEV_PATH_BR_VLAN_UNTAG_HW:
+ if (info->num_encaps == 0)
+ return -1;
+
info->ingress_vlans |= BIT(info->num_encaps - 1);
break;
case DEV_PATH_BR_VLAN_TAG:
- if (info->num_encaps >= NF_FLOW_TABLE_ENCAP_MAX) {
- info->indev = NULL;
- break;
- }
+ if (info->num_encaps >= NF_FLOW_TABLE_ENCAP_MAX)
+ return -1;
+
info->encap[info->num_encaps].id = path->bridge.vlan_id;
info->encap[info->num_encaps].proto = path->bridge.vlan_proto;
info->num_encaps++;
break;
case DEV_PATH_BR_VLAN_UNTAG:
- if (info->num_encaps == 0) {
- info->indev = NULL;
- break;
- }
+ if (info->num_encaps == 0)
+ return -1;
+
info->num_encaps--;
break;
case DEV_PATH_BR_VLAN_KEEP:
@@ -175,8 +174,7 @@ static void nft_dev_path_info(const struct net_device_path_stack *stack,
info->xmit_type = FLOW_OFFLOAD_XMIT_DIRECT;
break;
default:
- info->indev = NULL;
- break;
+ return -1;
}
}
info->outdev = info->indev;
@@ -184,6 +182,8 @@ static void nft_dev_path_info(const struct net_device_path_stack *stack,
if (nf_flowtable_hw_offload(flowtable) &&
nft_is_valid_ether_device(info->indev))
info->xmit_type = FLOW_OFFLOAD_XMIT_DIRECT;
+
+ return 0;
}
static bool nft_flowtable_find_dev(const struct net_device *dev,
@@ -241,11 +241,11 @@ static int nft_flow_tunnel_update_route(const struct nft_pktinfo *pkt,
return 0;
}
-static void nft_dev_forward_path(const struct nft_pktinfo *pkt,
- struct nf_flow_route *route,
- const struct nf_conn *ct,
- enum ip_conntrack_dir dir,
- struct nft_flowtable *ft)
+static int nft_dev_forward_path(const struct nft_pktinfo *pkt,
+ struct nf_flow_route *route,
+ const struct nf_conn *ct,
+ enum ip_conntrack_dir dir,
+ struct nft_flowtable *ft)
{
const struct dst_entry *dst = route->tuple[dir].dst;
struct net_device_path_stack stack;
@@ -253,15 +253,16 @@ static void nft_dev_forward_path(const struct nft_pktinfo *pkt,
unsigned char ha[ETH_ALEN];
int i;
- if (nft_dev_fill_forward_path(route, dst, ct, dir, ha, &stack) >= 0)
- nft_dev_path_info(&stack, &info, ha, &ft->data);
+ if (nft_dev_fill_forward_path(route, dst, ct, dir, ha, &stack) < 0 ||
+ nft_dev_path_info(&stack, &info, ha, &ft->data) < 0)
+ return -ENOENT;
+
+ if (!nft_flowtable_find_dev(info.indev, ft))
+ return -ENOENT;
if (info.outdev)
route->tuple[dir].out.ifindex = info.outdev->ifindex;
- if (!info.indev || !nft_flowtable_find_dev(info.indev, ft))
- return;
-
route->tuple[!dir].in.ifindex = info.indev->ifindex;
for (i = 0; i < info.num_encaps; i++) {
route->tuple[!dir].in.encap[i].id = info.encap[i].id;
@@ -285,6 +286,8 @@ static void nft_dev_forward_path(const struct nft_pktinfo *pkt,
route->tuple[dir].xmit_type = info.xmit_type;
}
route->tuple[dir].out.needs_gso_segment = info.needs_gso_segment;
+
+ return 0;
}
int nft_flow_route(const struct nft_pktinfo *pkt, const struct nf_conn *ct,
@@ -329,11 +332,19 @@ int nft_flow_route(const struct nft_pktinfo *pkt, const struct nf_conn *ct,
nft_default_forward_path(route, this_dst, dir);
nft_default_forward_path(route, other_dst, !dir);
- if (route->tuple[dir].xmit_type == FLOW_OFFLOAD_XMIT_NEIGH)
- nft_dev_forward_path(pkt, route, ct, dir, ft);
- if (route->tuple[!dir].xmit_type == FLOW_OFFLOAD_XMIT_NEIGH)
- nft_dev_forward_path(pkt, route, ct, !dir, ft);
+ if (route->tuple[dir].xmit_type == FLOW_OFFLOAD_XMIT_NEIGH &&
+ nft_dev_forward_path(pkt, route, ct, dir, ft) < 0)
+ goto err_dst_release;
+
+ if (route->tuple[!dir].xmit_type == FLOW_OFFLOAD_XMIT_NEIGH &&
+ nft_dev_forward_path(pkt, route, ct, !dir, ft) < 0)
+ goto err_dst_release;
return 0;
+
+err_dst_release:
+ dst_release(route->tuple[dir].dst);
+ dst_release(route->tuple[!dir].dst);
+ return -ENOENT;
}
EXPORT_SYMBOL_GPL(nft_flow_route);
--
2.47.3
next prev parent reply other threads:[~2026-06-14 11:46 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-14 11:45 [PATCH net-next 00/11] Netfilter/IPVS updates for net-next Pablo Neira Ayuso
2026-06-14 11:45 ` [PATCH net-next 01/11] ipvs: Replace use of system_unbound_wq with system_dfl_long_wq Pablo Neira Ayuso
2026-06-14 11:45 ` [PATCH net-next 02/11] netfilter: nf_tables: use DEBUG_NET_WARN_ON_ONCE in packet and control paths Pablo Neira Ayuso
2026-06-14 11:45 ` [PATCH net-next 03/11] netfilter: nf_conncount: callers must hold rcu read lock Pablo Neira Ayuso
2026-06-14 11:45 ` [PATCH net-next 04/11] netfilter: nf_conncount: use per nf_conncount_data spinlocks Pablo Neira Ayuso
2026-06-14 11:45 ` [PATCH net-next 05/11] netfilter: nf_conncount: split count_tree_node rbtree walk into helper Pablo Neira Ayuso
2026-06-14 11:46 ` [PATCH net-next 06/11] netfilter: nf_conncount: add sequence counter to detect tree modifications Pablo Neira Ayuso
2026-06-14 11:46 ` [PATCH net-next 07/11] netfilter: nf_conncount: gc and rcu fixes Pablo Neira Ayuso
2026-06-14 11:46 ` [PATCH net-next 08/11] netfilter: conntrack: check NULL when retrieving ct extension Pablo Neira Ayuso
2026-06-14 11:46 ` Pablo Neira Ayuso [this message]
2026-06-14 11:46 ` [PATCH net-next 10/11] ipvs: fix doc syntax for conn_max sysctl Pablo Neira Ayuso
2026-06-14 11:46 ` [PATCH net-next 11/11] netfilter: nf_dup_netdev: add nf_dev_xmit_recursion*() helpers and use them Pablo Neira Ayuso
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260614114605.474783-10-pablo@netfilter.org \
--to=pablo@netfilter.org \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=fw@strlen.de \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=netfilter-devel@vger.kernel.org \
--cc=pabeni@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox