From eb4df019afa3c46f2dff3d8d716e267034e1e006 Mon Sep 17 00:00:00 2001 From: Shunchao Hu Date: Wed, 15 Apr 2026 14:36:32 +0800 Subject: [PATCH] net/ipforward: Forbid non-forwardable multicast scopes. RFC 3171 reserves 224.0.0.0/24 for link-local IPv4 multicast scope, so packets in this range must not be forwarded by routers, regardless of the TTL value. IPv6 also defines multicast scopes that must not be forwarded beyond the local topology. In particular, interface-local and link-local multicast destinations must not be routed across interfaces. Add IPv4/IPv6 scope checks so non-forwardable multicast packets are rejected before entering the multicast forwarding path. Signed-off-by: Shunchao Hu --- net/ipforward/ipv4_forward.c | 12 ++++++++++++ net/ipforward/ipv6_forward.c | 11 +++++++++++ 2 files changed, 23 insertions(+) diff --git a/net/ipforward/ipv4_forward.c b/net/ipforward/ipv4_forward.c index f03e50811e1..5bd509042e7 100644 --- a/net/ipforward/ipv4_forward.c +++ b/net/ipforward/ipv4_forward.c @@ -634,6 +634,18 @@ void ipv4_forward_broadcast(FAR struct net_driver_s *dev, return; } + /* Do not forward link-local multicast packets (224.0.0.0/24). + * Per RFC 3171, addresses in 224.0.0.0/24 are reserved for + * link-local scope and MUST NOT be forwarded by any router, + * regardless of TTL. + */ + + if ((net_ip4addr_conv32(ipv4->destipaddr) & + HTONL(0xffffff00)) == HTONL(0xe0000000)) + { + return; + } + /* Don't bother if the TTL would expire */ if (ipv4->ttl > 1) diff --git a/net/ipforward/ipv6_forward.c b/net/ipforward/ipv6_forward.c index 6a28afdf85f..18d7a941ad7 100644 --- a/net/ipforward/ipv6_forward.c +++ b/net/ipforward/ipv6_forward.c @@ -810,6 +810,17 @@ void ipv6_forward_broadcast(FAR struct net_driver_s *dev, return; } + /* Do not forward reserved, interface-local, or link-local multicast + * destinations (ffx0::/16, ffx1::/16, ffx2::/16). + */ + + if (((ipv6->destipaddr[0] & HTONS(0xff0f)) == HTONS(0xff00)) || + ((ipv6->destipaddr[0] & HTONS(0xff0f)) == HTONS(0xff01)) || + ((ipv6->destipaddr[0] & HTONS(0xff0f)) == HTONS(0xff02))) + { + return; + } + /* Don't bother if the TTL would expire */ if (ipv6->ttl > 1)