net: ipv4: Added mechanism to add 224.0.0.1 address to a multicast filter
The purpose of the change was to have the Zephyr network stack internally add the IGMP all systems 224.0.0.1 multicast address to a multicast membership list so that multicast hash filter implementations can add this address to the hash filter. Fixes #53548 Signed-off-by: Chamira Perera <chamira.perera@audinate.com>
This commit is contained in:
parent
86f48609fb
commit
b71b514e93
4 changed files with 81 additions and 2 deletions
|
@ -34,6 +34,7 @@ config NET_IF_UNICAST_IPV4_ADDR_COUNT
|
||||||
|
|
||||||
config NET_IF_MCAST_IPV4_ADDR_COUNT
|
config NET_IF_MCAST_IPV4_ADDR_COUNT
|
||||||
int "Max number of multicast IPv4 addresses per network interface"
|
int "Max number of multicast IPv4 addresses per network interface"
|
||||||
|
default 2 if NET_IPV4_IGMP
|
||||||
default 1
|
default 1
|
||||||
|
|
||||||
config NET_ICMPV4_ACCEPT_BROADCAST
|
config NET_ICMPV4_ACCEPT_BROADCAST
|
||||||
|
|
|
@ -127,7 +127,15 @@ static int send_igmp_report(struct net_if *iface,
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < NET_IF_MAX_IPV4_MADDR; i++) {
|
for (i = 0; i < NET_IF_MAX_IPV4_MADDR; i++) {
|
||||||
if (!ipv4->mcast[i].is_used || !ipv4->mcast[i].is_joined) {
|
/* We don't need to send an IGMP membership report to the IGMP
|
||||||
|
* all systems multicast address of 224.0.0.1 so skip over it.
|
||||||
|
* Since the IGMP all systems multicast address is marked as
|
||||||
|
* used and joined during init time, we have to check this
|
||||||
|
* address separately to skip over it.
|
||||||
|
*/
|
||||||
|
if (!ipv4->mcast[i].is_used || !ipv4->mcast[i].is_joined ||
|
||||||
|
net_ipv4_addr_cmp_raw((uint8_t *)&ipv4->mcast[i].address.in_addr,
|
||||||
|
(uint8_t *)&all_systems)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +147,15 @@ static int send_igmp_report(struct net_if *iface,
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < NET_IF_MAX_IPV4_MADDR; i++) {
|
for (i = 0; i < NET_IF_MAX_IPV4_MADDR; i++) {
|
||||||
if (!ipv4->mcast[i].is_used || !ipv4->mcast[i].is_joined) {
|
/* We don't need to send an IGMP membership report to the IGMP
|
||||||
|
* all systems multicast address of 224.0.0.1 so skip over it.
|
||||||
|
* Since the IGMP all systems multicast address is marked as
|
||||||
|
* used and joined during init time, we have to check this
|
||||||
|
* address separately to skip over it.
|
||||||
|
*/
|
||||||
|
if (!ipv4->mcast[i].is_used || !ipv4->mcast[i].is_joined ||
|
||||||
|
net_ipv4_addr_cmp_raw((uint8_t *)&ipv4->mcast[i].address.in_addr,
|
||||||
|
(uint8_t *)&all_systems)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,3 +342,39 @@ int net_ipv4_igmp_leave(struct net_if *iface, const struct in_addr *addr)
|
||||||
sizeof(struct in_addr));
|
sizeof(struct in_addr));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void net_ipv4_igmp_init(struct net_if *iface)
|
||||||
|
{
|
||||||
|
struct net_if_mcast_addr *maddr;
|
||||||
|
|
||||||
|
/* Ensure multicast addresses are available */
|
||||||
|
if (CONFIG_NET_IF_MCAST_IPV4_ADDR_COUNT < 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This code adds the IGMP all systems 224.0.0.1 multicast address
|
||||||
|
* to the list of multicast addresses of the given interface.
|
||||||
|
* The address is marked as joined. However, an IGMP membership
|
||||||
|
* report is not generated for this address. Populating this
|
||||||
|
* address in the list of multicast addresses of the interface
|
||||||
|
* and marking it as joined is helpful for multicast hash filter
|
||||||
|
* implementations that need a list of multicast addresses it needs
|
||||||
|
* to add to the multicast hash filter after a multicast address
|
||||||
|
* has been removed from the membership list.
|
||||||
|
*/
|
||||||
|
maddr = net_if_ipv4_maddr_lookup(&all_systems, &iface);
|
||||||
|
if (maddr && net_if_ipv4_maddr_is_joined(maddr)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!maddr) {
|
||||||
|
maddr = net_if_ipv4_maddr_add(iface, &all_systems);
|
||||||
|
if (!maddr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
net_if_ipv4_maddr_join(maddr);
|
||||||
|
|
||||||
|
net_if_mcast_monitor(iface, &maddr->address, true);
|
||||||
|
}
|
||||||
|
|
|
@ -4159,6 +4159,21 @@ exit:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void init_igmp(struct net_if *iface)
|
||||||
|
{
|
||||||
|
#if defined(CONFIG_NET_IPV4_IGMP)
|
||||||
|
/* Ensure IPv4 is enabled for this interface */
|
||||||
|
if (iface->config.ip.ipv4 == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
net_ipv4_igmp_init(iface);
|
||||||
|
#else
|
||||||
|
ARG_UNUSED(iface);
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int net_if_up(struct net_if *iface)
|
int net_if_up(struct net_if *iface)
|
||||||
{
|
{
|
||||||
int status = 0;
|
int status = 0;
|
||||||
|
@ -4187,6 +4202,8 @@ int net_if_up(struct net_if *iface)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
init_igmp(iface);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
net_if_flag_set(iface, NET_IF_UP);
|
net_if_flag_set(iface, NET_IF_UP);
|
||||||
net_mgmt_event_notify(NET_EVENT_IF_ADMIN_UP, iface);
|
net_mgmt_event_notify(NET_EVENT_IF_ADMIN_UP, iface);
|
||||||
|
|
|
@ -173,6 +173,15 @@ enum net_verdict net_context_packet_received(struct net_conn *conn,
|
||||||
extern uint16_t net_calc_chksum_ipv4(struct net_pkt *pkt);
|
extern uint16_t net_calc_chksum_ipv4(struct net_pkt *pkt);
|
||||||
#endif /* CONFIG_NET_IPV4 */
|
#endif /* CONFIG_NET_IPV4 */
|
||||||
|
|
||||||
|
#if defined(CONFIG_NET_IPV4_IGMP)
|
||||||
|
/**
|
||||||
|
* @brief Initialise the IGMP module for a given interface
|
||||||
|
*
|
||||||
|
* @param iface Interface to init IGMP
|
||||||
|
*/
|
||||||
|
void net_ipv4_igmp_init(struct net_if *iface);
|
||||||
|
#endif /* CONFIG_NET_IPV4_IGMP */
|
||||||
|
|
||||||
#if defined(CONFIG_NET_IPV4_IGMP)
|
#if defined(CONFIG_NET_IPV4_IGMP)
|
||||||
uint16_t net_calc_chksum_igmp(uint8_t *data, size_t len);
|
uint16_t net_calc_chksum_igmp(uint8_t *data, size_t len);
|
||||||
enum net_verdict net_ipv4_igmp_input(struct net_pkt *pkt,
|
enum net_verdict net_ipv4_igmp_input(struct net_pkt *pkt,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue