diff options
| author | Pablo Neira Ayuso <pablo@netfilter.org> | 2026-07-10 09:54:09 +0200 |
|---|---|---|
| committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2026-07-24 11:22:30 +0200 |
| commit | edd51a23343870dbd7cedf6e2765c13cf7a5ccbc (patch) | |
| tree | ec805fbde51351866e539d77590631185779cd3e | |
| parent | 16aecbe3036f6097c26b51b12e4c1cf207769690 (diff) | |
| download | linux-next-edd51a23343870dbd7cedf6e2765c13cf7a5ccbc.tar.gz linux-next-edd51a23343870dbd7cedf6e2765c13cf7a5ccbc.zip | |
netfilter: flowtable: tear down flow entries with stale dst from GC
In case of route updates, tear down flow entries with stale dst to give
them a chance to obtain a fresh route.
This is specifically useful for hardware offloaded entries, where the
flowtable software dataplane sees no packet, where the existing check
for stale dst entries does not help.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
| -rw-r--r-- | include/net/netfilter/nf_flow_table.h | 8 | ||||
| -rw-r--r-- | net/netfilter/nf_flow_table_core.c | 2 | ||||
| -rw-r--r-- | net/netfilter/nf_flow_table_ip.c | 8 |
3 files changed, 10 insertions, 8 deletions
diff --git a/include/net/netfilter/nf_flow_table.h b/include/net/netfilter/nf_flow_table.h index ce414118962f..a090ec3ffef2 100644 --- a/include/net/netfilter/nf_flow_table.h +++ b/include/net/netfilter/nf_flow_table.h @@ -310,6 +310,14 @@ int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow) void flow_offload_refresh(struct nf_flowtable *flow_table, struct flow_offload *flow, bool force); +static inline bool nf_flow_dst_check(struct flow_offload_tuple *tuple) +{ + if (!tuple->dst_cache) + return true; + + return dst_check(tuple->dst_cache, tuple->dst_cookie); +} + struct flow_offload_tuple_rhash *flow_offload_lookup(struct nf_flowtable *flow_table, struct flow_offload_tuple *tuple); void nf_flow_table_gc_run(struct nf_flowtable *flow_table); diff --git a/net/netfilter/nf_flow_table_core.c b/net/netfilter/nf_flow_table_core.c index b66e65439341..58e6a675332d 100644 --- a/net/netfilter/nf_flow_table_core.c +++ b/net/netfilter/nf_flow_table_core.c @@ -571,6 +571,8 @@ static void nf_flow_offload_gc_step(struct nf_flowtable *flow_table, if (nf_flow_has_expired(flow) || nf_ct_is_dying(flow->ct) || + !nf_flow_dst_check(&flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple) || + !nf_flow_dst_check(&flow->tuplehash[FLOW_OFFLOAD_DIR_REPLY].tuple) || nf_flow_custom_gc(flow_table, flow)) { flow_offload_teardown(flow); teardown = true; diff --git a/net/netfilter/nf_flow_table_ip.c b/net/netfilter/nf_flow_table_ip.c index 0b78decce8a9..0b314b10e705 100644 --- a/net/netfilter/nf_flow_table_ip.c +++ b/net/netfilter/nf_flow_table_ip.c @@ -297,14 +297,6 @@ static bool nf_flow_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu) return true; } -static inline bool nf_flow_dst_check(struct flow_offload_tuple *tuple) -{ - if (!tuple->dst_cache) - return true; - - return dst_check(tuple->dst_cache, tuple->dst_cookie); -} - static unsigned int nf_flow_xmit_xfrm(struct sk_buff *skb, const struct nf_hook_state *state, struct dst_entry *dst) |
