From cb3c08735036c244d5b84bfcbe421f45d414ccbe Mon Sep 17 00:00:00 2001 From: Konrad Derda Date: Wed, 8 May 2024 12:21:16 +0200 Subject: [PATCH] net: ipv6: mcast_routing: hop limit handling While forwarding a multicast packet decrement hop limit in a common net buffer. Also, packets with hop limit equal to 0 should not be forwarded. Signed-off-by: Konrad Derda --- subsys/net/ip/ipv6.c | 13 ++++++++----- subsys/net/ip/route.c | 9 +++++++-- subsys/net/ip/route.h | 2 +- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/subsys/net/ip/ipv6.c b/subsys/net/ip/ipv6.c index 9d094c9c4c9..f9f5487c3cc 100644 --- a/subsys/net/ip/ipv6.c +++ b/subsys/net/ip/ipv6.c @@ -411,12 +411,15 @@ static enum net_verdict ipv6_forward_mcast_packet(struct net_pkt *pkt, #if defined(CONFIG_NET_ROUTE_MCAST) int routed; - /* check if routing loop could be created or if the destination is of - * interface local scope or if from link local source + /* Continue processing without forwarding if: + * 1. routing loop could be created + * 2. the destination is of interface local scope + * 3. is from link local source + * 4. hop limit is or would become zero */ - if (net_ipv6_is_addr_mcast((struct in6_addr *)hdr->src) || - net_ipv6_is_addr_mcast_iface((struct in6_addr *)hdr->dst) || - net_ipv6_is_ll_addr((struct in6_addr *)hdr->src)) { + if (net_ipv6_is_addr_mcast((struct in6_addr *)hdr->src) || + net_ipv6_is_addr_mcast_iface((struct in6_addr *)hdr->dst) || + net_ipv6_is_ll_addr((struct in6_addr *)hdr->src) || hdr->hop_limit <= 1) { return NET_CONTINUE; } diff --git a/subsys/net/ip/route.c b/subsys/net/ip/route.c index a292e77e880..8612f0ed169 100644 --- a/subsys/net/ip/route.c +++ b/subsys/net/ip/route.c @@ -815,11 +815,16 @@ static void propagate_mld_event(struct net_route_entry_mcast *route, bool route_ #define propagate_mld_event(...) #endif /* CONFIG_NET_MCAST_ROUTE_MLD_REPORTS */ -int net_route_mcast_forward_packet(struct net_pkt *pkt, - const struct net_ipv6_hdr *hdr) +int net_route_mcast_forward_packet(struct net_pkt *pkt, struct net_ipv6_hdr *hdr) { int ret = 0, err = 0; + /* At this point, the original pkt has already stored the hop limit in its metadata. + * Change its value in a common buffer so the forwardee has a proper count. As we have + * a direct access to the buffer there is no need to perform read/write operations. + */ + hdr->hop_limit--; + ARRAY_FOR_EACH_PTR(route_mcast_entries, route) { struct net_pkt *pkt_cpy = NULL; diff --git a/subsys/net/ip/route.h b/subsys/net/ip/route.h index e6dc4a1aac9..d8e4647f62d 100644 --- a/subsys/net/ip/route.h +++ b/subsys/net/ip/route.h @@ -224,7 +224,7 @@ typedef void (*net_route_mcast_cb_t)(struct net_route_entry_mcast *entry, * value in case of an error. */ int net_route_mcast_forward_packet(struct net_pkt *pkt, - const struct net_ipv6_hdr *hdr); + struct net_ipv6_hdr *hdr); /** * @brief Go through all the multicast routing entries and call callback