Thread (2 messages) 2 messages, 2 authors, 2d ago

[PATCH nf-next v2] netfilter: nft_flow_offload: do not offload multicast

flat view
WARM2d

From: Koral Ilgun <hidden>
Date: 2026-10-29 22:01:52
Also in: lkml, netfilter-devel
Subsystem: netfilter, networking [general], the rest · Maintainers: Pablo Neira Ayuso, Florian Westphal, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds

From: Koral Ilgun <redacted>

A flow holds one output per direction, which it resolves when it is
added. The outputs of a multicast route change when listeners join
or leave. So a multicast flow in the flowtable continues to send to
the output that it resolved, also after the last listener left, and
the counters of the multicast routing stop.

A ruleset can keep multicast out with a match before the flow
offload statement. Without one, IPv4 multicast stays out of the
flowtable only because the reverse route lookup in nft_flow_route()
refuses a multicast source address. The IPv6 route lookup has no such
check, so IPv6 multicast that ip6mr forwards goes into the flowtable.

Skip a multicast destination for both families in the flow offload
expression itself, so that the result no longer depends on the
ruleset or on the route lookup.

Signed-off-by: Koral Ilgun <redacted>
---
v2:
- Target nf-next, and drop the Fixes tag (Pablo).
- Use the shorter form that Fernando suggested; the result is the same.
- Say in the commit message that a ruleset can keep multicast out.
v1: https://lore.kernel.org/all/20261028205938.662312-1-koralilgun@gmail.com/ (local)

Tested with v1, which skips the same packets: on an arm64 router with
Linux 6.18.54, with an inet flowtable that offloads forwarded flows,
and IPv4 and IPv6 multicast routed from the WAN to one VLAN. Without
this change, the IPv6 flow went into the flowtable after its first
packets: the ip6mr vif counters showed 25 of 1,500 packets, and the
receiver still got all 400 packets after its leave. With it, the vif
counters showed 1,500 of 1,500, the flow stayed out of the flowtable,
and the stream stopped about 2.5 s after the leave. Unicast IPv4 and
IPv6 flows still went into the flowtable.

 net/netfilter/nft_flow_offload.c | 5 +++++
 1 file changed, 5 insertions(+)
diff --git a/net/netfilter/nft_flow_offload.c b/net/netfilter/nft_flow_offload.c
index d3c5651dd699..530e20c7fd45 100644
--- a/net/netfilter/nft_flow_offload.c
+++ b/net/netfilter/nft_flow_offload.c
@@ -10,6 +10,7 @@
 #include <linux/netfilter/nf_conntrack_common.h>
 #include <linux/netfilter/nf_tables.h>
 #include <net/ip.h>
+#include <net/ipv6.h>
 #include <net/flow.h>
 #include <net/netfilter/nf_tables.h>
 #include <net/netfilter/nf_tables_core.h>
@@ -33,6 +34,10 @@ static bool nft_flow_offload_skip(struct sk_buff *skb, int family)
 
 		if (unlikely(opt->optlen))
 			return true;
+
+		return ipv4_is_multicast(ip_hdr(skb)->daddr);
+	} else if (family == NFPROTO_IPV6) {
+		return ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr);
 	}
 
 	return false;
base-commit: 734bef548a96e8774d6eef5dfa2026c6edc4e80b
-- 
2.43.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help