diff --git a/subsys/net/ip/route.c b/subsys/net/ip/route.c index 4f646b3d37b46..ae4989540f8aa 100644 --- a/subsys/net/ip/route.c +++ b/subsys/net/ip/route.c @@ -957,6 +957,30 @@ net_route_mcast_lookup(struct in6_addr *group) return NULL; } + +struct net_route_entry_mcast * +net_route_mcast_lookup_by_iface(struct in6_addr *group, struct net_if *iface) +{ + ARRAY_FOR_EACH_PTR(route_mcast_entries, route) { + if (!route->is_used) { + continue; + } + + ARRAY_FOR_EACH(route->ifaces, i) { + if (route->ifaces[i] == NULL || route->ifaces[i] != iface) { + continue; + } + + if (net_ipv6_is_prefix(group->s6_addr, + route->group.s6_addr, + route->prefix_len)) { + return route; + } + } + } + + return NULL; +} #endif /* CONFIG_NET_ROUTE_MCAST */ bool net_route_get_info(struct net_if *iface, diff --git a/subsys/net/ip/route.h b/subsys/net/ip/route.h index d8e4647f62d0a..388b53530ab4e 100644 --- a/subsys/net/ip/route.h +++ b/subsys/net/ip/route.h @@ -272,6 +272,17 @@ bool net_route_mcast_del(struct net_route_entry_mcast *route); struct net_route_entry_mcast * net_route_mcast_lookup(struct in6_addr *group); +/** + * @brief Lookup a multicast routing entry on a given interface. + * + * @param group IPv6 multicast group address + * @param iface Network interface to check + * + * @return Routing entry corresponding to this multicast group and interface. + */ +struct net_route_entry_mcast * +net_route_mcast_lookup_by_iface(struct in6_addr *group, struct net_if *iface); + /** * @brief Add an interface to multicast routing entry. * diff --git a/tests/net/route_mcast/src/main.c b/tests/net/route_mcast/src/main.c index 3dd3637bbf881..140809c86a375 100644 --- a/tests/net/route_mcast/src/main.c +++ b/tests/net/route_mcast/src/main.c @@ -417,6 +417,23 @@ static void test_route_mcast_lookup(void) zassert_equal_ptr(test_mcast_routes[3], route, "mcast lookup failed"); } + +static void test_route_mcast_lookup_by_iface(void) +{ + struct net_route_entry_mcast *route = + net_route_mcast_lookup_by_iface(&mcast_prefix_admin, iface_1); + + zassert_not_null(route, "mcast lookup by iface failed"); + + route = net_route_mcast_lookup_by_iface(&mcast_prefix_site_local, iface_2); + + zassert_not_null(route, "mcast lookup by iface failed"); + + route = net_route_mcast_lookup_by_iface(&mcast_prefix_site_local, iface_1); + + zassert_is_null(route, "mcast lookup by iface should not find a route on this interface"); +} + static void test_route_mcast_route_del(void) { struct net_route_entry_mcast *route; @@ -752,6 +769,7 @@ ZTEST(route_mcast_test_suite, test_route_mcast) test_route_mcast_scenario3(); test_route_mcast_multiple_route_ifaces(); test_route_mcast_lookup(); + test_route_mcast_lookup_by_iface(); test_route_mcast_route_del(); } ZTEST_SUITE(route_mcast_test_suite, NULL, NULL, NULL, NULL, NULL);