diff --git a/net/yaip/Kconfig b/net/yaip/Kconfig index e7e3a33b8d4..3e1cddb8a66 100644 --- a/net/yaip/Kconfig +++ b/net/yaip/Kconfig @@ -69,6 +69,19 @@ config NET_MAX_NEXTHOPS help This determines how many entries can be stored in nexthop table. +config NET_ROUTE_MCAST + bool + depends on NET_ROUTE + default n + +config NET_MAX_MCAST_ROUTES + int "Max number of multicast routing entries stored." + default 1 + depends on NET_ROUTE_MCAST + help + This determines how many entries can be stored in multicast + routing table. + config NET_TCP bool "Enable TCP" default n diff --git a/net/yaip/route.c b/net/yaip/route.c index b2f3b791346..516b8a1f6f4 100644 --- a/net/yaip/route.c +++ b/net/yaip/route.c @@ -602,6 +602,92 @@ struct in6_addr *net_route_get_nexthop(struct net_route_entry *route) return NULL; } +#if defined(CONFIG_NET_ROUTE_MCAST) +/* + * This array contains multicast routing entries. + */ +static +struct net_route_entry_mcast route_mcast_entries[CONFIG_NET_MAX_MCAST_ROUTES]; + +int net_route_mcast_foreach(net_route_mcast_cb_t cb, + struct in6_addr *skip, + void *user_data) +{ + int i, ret = 0; + + for (i = 0; i < CONFIG_NET_MAX_MCAST_ROUTES; i++) { + struct net_route_entry_mcast *route = &route_mcast_entries[i]; + + if (route->is_used) { + if (skip && net_ipv6_addr_cmp(skip, &route->group)) { + continue; + } + + cb(route, user_data); + + ret++; + } + } + + return ret; +} + +struct net_route_entry_mcast *net_route_mcast_add(struct net_if *iface, + struct in6_addr *group) +{ + int i; + + for (i = 0; i < CONFIG_NET_MAX_MCAST_ROUTES; i++) { + struct net_route_entry_mcast *route = &route_mcast_entries[i]; + + if (!route->is_used) { + net_ipaddr_copy(&route->group, group); + + route->iface = iface; + route->is_used = true; + + return route; + } + } + + return NULL; +} + +bool net_route_mcast_del(struct net_route_entry_mcast *route) +{ + if (route > &route_mcast_entries[CONFIG_NET_MAX_MCAST_ROUTES - 1] || + route < &route_mcast_entries[0]) { + return false; + } + + NET_ASSERT_INFO(route->is_used, + "Multicast route %d to %s was already removed", i, + net_sprint_ipv6_addr(&route->group)); + + route->is_used = false; + + return true; +} + +struct net_route_entry_mcast * +net_route_mcast_lookup(struct in6_addr *group) +{ + int i; + + for (i = 0; i < CONFIG_NET_MAX_MCAST_ROUTES; i++) { + struct net_route_entry_mcast *route = &route_mcast_entries[i]; + + if (!route->is_used) { + if (net_ipv6_addr_cmp(group, &route->group)) { + return route; + } + } + } + + return NULL; +} +#endif /* CONFIG_NET_ROUTE_MCAST */ + void net_route_init(void) { NET_DBG("Allocated %d routing entries (%d bytes)", diff --git a/net/yaip/route.h b/net/yaip/route.h index 86375c2de59..b84c6af529c 100644 --- a/net/yaip/route.h +++ b/net/yaip/route.h @@ -158,7 +158,78 @@ struct in6_addr *net_route_get_nexthop(struct net_route_entry *entry); struct net_nbr *net_route_get_nbr(struct net_route_entry *route); void net_route_init(void); -#else + +#if defined(CONFIG_NET_ROUTE_MCAST) +/** + * @brief Multicast route entry. + */ +struct net_route_entry_mcast { + /** Network interface for the route. */ + struct net_if *iface; + + /** Extra routing engine specific data */ + void *data; + + /** IPv6 multicast group of the route. */ + struct in6_addr group; + + /** Routing entry lifetime in seconds. */ + uint32_t lifetime; + + /** Is this entry in user or not */ + bool is_used; +}; + +typedef void (*net_route_mcast_cb_t)(struct net_route_entry_mcast *entry, + void *user_data); + +/** + * @brief Go through all the multicast routing entries and call callback + * for each entry that is in use. + * + * @param cb User supplied callback function to call. + * @param skip Do not call callback for this address. + * @param user_data User specified data. + * + * @return Total number of multicast routing entries that are in use. + */ +int net_route_mcast_foreach(net_route_mcast_cb_t cb, + struct in6_addr *skip, + void *user_data); + +/** + * @brief Add a multicast routing entry. + * + * @param iface Network interface to use. + * @param group IPv6 multicast address. + * + * @return Multicast routing entry. + */ +struct net_route_entry_mcast *net_route_mcast_add(struct net_if *iface, + struct in6_addr *group); + +/** + * @brief Delete a multicast routing entry. + * + * @param route Multicast routing entry. + * + * @return True if entry was deleted, false otherwise. + */ +bool net_route_mcast_del(struct net_route_entry_mcast *route); + +/** + * @brief Lookup a multicast routing entry. + * + * @param group IPv6 multicast group address + * + * @return Routing entry corresponding this multicast group. + */ +struct net_route_entry_mcast * +net_route_mcast_lookup(struct in6_addr *group); + +#endif /* CONFIG_NET_ROUTE_MCAST */ + +#else /* CONFIG_NET_ROUTE */ #define net_route_init(...) #endif /* CONFIG_NET_ROUTE */