diff --git a/include/zephyr/net/igmp.h b/include/zephyr/net/igmp.h index 7119676f237..ed39a31359f 100644 --- a/include/zephyr/net/igmp.h +++ b/include/zephyr/net/igmp.h @@ -27,22 +27,31 @@ extern "C" { #endif +struct igmp_param { + struct in_addr *source_list; /* List of sources to include or exclude */ + size_t sources_len; /* Length of source list */ + bool include; /* Source list filter type */ +}; + /** * @brief Join a given multicast group. * * @param iface Network interface where join message is sent * @param addr Multicast group to join + * @param param Optional parameters * * @return Return 0 if joining was done, <0 otherwise. */ #if defined(CONFIG_NET_IPV4_IGMP) -int net_ipv4_igmp_join(struct net_if *iface, const struct in_addr *addr); +int net_ipv4_igmp_join(struct net_if *iface, const struct in_addr *addr, + const struct igmp_param *param); #else -static inline int net_ipv4_igmp_join(struct net_if *iface, - const struct in_addr *addr) +static inline int net_ipv4_igmp_join(struct net_if *iface, const struct in_addr *addr, + const struct igmp_param *param) { ARG_UNUSED(iface); ARG_UNUSED(addr); + ARG_UNUSED(param); return -ENOSYS; } diff --git a/include/zephyr/net/net_if.h b/include/zephyr/net/net_if.h index 788c3316391..1780adeb5ca 100644 --- a/include/zephyr/net/net_if.h +++ b/include/zephyr/net/net_if.h @@ -94,6 +94,17 @@ struct net_if_mcast_addr { /** IP address */ struct net_addr address; +#if defined(CONFIG_NET_IPV4_IGMPV3) + /** Sources to filter on */ + struct net_addr sources[CONFIG_NET_IF_MCAST_IPV4_SOURCE_COUNT]; + + /** Number of sources to be used by the filter */ + uint16_t sources_len; + + /** Filter mode (used in IGMPV3) */ + uint8_t record_type; +#endif + /** Is this multicast IP address used or not */ uint8_t is_used : 1; diff --git a/subsys/net/ip/Kconfig.ipv4 b/subsys/net/ip/Kconfig.ipv4 index 3158fe43e41..e5d30cfc27c 100644 --- a/subsys/net/ip/Kconfig.ipv4 +++ b/subsys/net/ip/Kconfig.ipv4 @@ -37,6 +37,10 @@ config NET_IF_MCAST_IPV4_ADDR_COUNT default 2 if NET_IPV4_IGMP default 1 +config NET_IF_MCAST_IPV4_SOURCE_COUNT + int "Max number of IPv4 sources per mcast address to be included or excluded" + default 1 + config NET_ICMPV4_ACCEPT_BROADCAST bool "Accept broadcast ICMPv4 echo-request" help diff --git a/subsys/net/ip/igmp.c b/subsys/net/ip/igmp.c index a8ecc0d28f9..3cd7be7de49 100644 --- a/subsys/net/ip/igmp.c +++ b/subsys/net/ip/igmp.c @@ -28,8 +28,18 @@ LOG_MODULE_DECLARE(net_ipv4, CONFIG_NET_IPV4_LOG_LEVEL); #define IPV4_OPT_HDR_ROUTER_ALERT_LEN 4 +#define IGMPV3_MODE_IS_INCLUDE 0x01 +#define IGMPV3_MODE_IS_EXCLUDE 0x02 +#define IGMPV3_CHANGE_TO_INCLUDE_MODE 0x03 +#define IGMPV3_CHANGE_TO_EXCLUDE_MODE 0x04 +#define IGMPV3_ALLOW_NEW_SOURCES 0x05 +#define IGMPV3_BLOCK_OLD_SOURCES 0x06 + static const struct in_addr all_systems = { { { 224, 0, 0, 1 } } }; static const struct in_addr all_routers = { { { 224, 0, 0, 2 } } }; +#if defined(CONFIG_NET_IPV4_IGMPV3) +static const struct in_addr igmp_multicast_addr = { { { 224, 0, 0, 22 } } }; +#endif #define dbg_addr(action, pkt_str, src, dst) \ NET_DBG("%s %s from %s to %s", action, pkt_str, \ @@ -39,6 +49,12 @@ static const struct in_addr all_routers = { { { 224, 0, 0, 2 } } }; #define dbg_addr_recv(pkt_str, src, dst) \ dbg_addr("Received", pkt_str, src, dst) +enum igmp_version { + IGMPV1, + IGMPV2, + IGMPV3, +}; + static int igmp_v2_create(struct net_pkt *pkt, const struct in_addr *addr, uint8_t type) { @@ -56,15 +72,119 @@ static int igmp_v2_create(struct net_pkt *pkt, const struct in_addr *addr, igmp->max_rsp = 0U; net_ipaddr_copy(&igmp->address, addr); igmp->chksum = 0; - igmp->chksum = net_calc_chksum_igmp(pkt); if (net_pkt_set_data(pkt, &igmp_access)) { return -ENOBUFS; } + igmp->chksum = net_calc_chksum_igmp(pkt); + + net_pkt_set_overwrite(pkt, true); + net_pkt_cursor_init(pkt); + + net_pkt_skip(pkt, offsetof(struct net_ipv4_igmp_v2_report, chksum)); + if (net_pkt_write(pkt, &igmp->chksum, sizeof(igmp->chksum))) { + return -ENOBUFS; + } + return 0; } +#if defined(CONFIG_NET_IPV4_IGMPV3) +static int igmp_v3_create(struct net_pkt *pkt, uint8_t type, struct net_if_mcast_addr mcast[], + size_t mcast_len) +{ + NET_PKT_DATA_ACCESS_DEFINE(igmp_access, struct net_ipv4_igmp_v3_report); + NET_PKT_DATA_ACCESS_DEFINE(group_record_access, struct net_ipv4_igmp_v3_group_record); + struct net_ipv4_igmp_v3_report *igmp; + struct net_ipv4_igmp_v3_group_record *group_record; + + uint16_t group_count = 0; + + igmp = (struct net_ipv4_igmp_v3_report *)net_pkt_get_data(pkt, &igmp_access); + if (!igmp) { + return -ENOBUFS; + } + + for (int i = 0; i < mcast_len; i++) { + /* 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 (!mcast[i].is_used || !mcast[i].is_joined || + net_ipv4_addr_cmp_raw((uint8_t *)&mcast[i].address.in_addr, + (uint8_t *)&all_systems)) { + continue; + } + + group_count++; + } + + igmp->type = type; + igmp->reserved_1 = 0U; + igmp->reserved_2 = 0U; + igmp->groups_len = htons(group_count); + /* Setting initial value of chksum to 0 to calculate chksum as described in RFC 3376 + * ch 4.1.2 + */ + igmp->chksum = 0; + + if (net_pkt_set_data(pkt, &igmp_access)) { + return -ENOBUFS; + } + + for (int i = 0; i < mcast_len; i++) { + /* 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 (!mcast[i].is_used || !mcast[i].is_joined || + net_ipv4_addr_cmp_raw((uint8_t *)&mcast[i].address.in_addr, + (uint8_t *)&all_systems)) { + continue; + } + + group_record = (struct net_ipv4_igmp_v3_group_record *)net_pkt_get_data( + pkt, &group_record_access); + if (!group_record) { + return -ENOBUFS; + } + + group_record->type = mcast[i].record_type; + group_record->aux_len = 0U; + net_ipaddr_copy(&group_record->address, &mcast[i].address.in_addr); + group_record->sources_len = htons(mcast[i].sources_len); + + if (net_pkt_set_data(pkt, &group_record_access)) { + return -ENOBUFS; + } + + for (int j = 0; j < mcast[i].sources_len; j++) { + if (net_pkt_write(pkt, &mcast[i].sources[j].in_addr.s_addr, + sizeof(mcast[i].sources[j].in_addr.s_addr))) { + return -ENOBUFS; + } + } + } + + igmp->chksum = net_calc_chksum_igmp(pkt); + + net_pkt_set_overwrite(pkt, true); + net_pkt_cursor_init(pkt); + + net_pkt_skip(pkt, offsetof(struct net_ipv4_igmp_v3_report, chksum)); + if (net_pkt_write(pkt, &igmp->chksum, sizeof(igmp->chksum))) { + return -ENOBUFS; + } + + return 0; +} +#endif + static int igmp_v2_create_packet(struct net_pkt *pkt, const struct in_addr *dst, const struct in_addr *group, uint8_t type) { @@ -95,6 +215,30 @@ static int igmp_v2_create_packet(struct net_pkt *pkt, const struct in_addr *dst, return igmp_v2_create(pkt, group, type); } +#if defined(CONFIG_NET_IPV4_IGMPV3) +static int igmp_v3_create_packet(struct net_pkt *pkt, const struct in_addr *dst, + struct net_if_mcast_addr mcast[], size_t mcast_len, uint8_t type) +{ + const uint32_t router_alert = 0x94040000; /* RFC 2213 ch 2.1 */ + int ret; + + ret = net_ipv4_create_full(pkt, net_if_ipv4_select_src_addr(net_pkt_iface(pkt), dst), dst, + 0U, 0U, 0U, 0U, 1U); /* TTL set to 1, RFC 3376 ch 2 */ + if (ret) { + return -ENOBUFS; + } + + /* Add router alert option, RFC 3376 ch 2 */ + if (net_pkt_write_be32(pkt, router_alert)) { + return -ENOBUFS; + } + + net_pkt_set_ipv4_opts_len(pkt, IPV4_OPT_HDR_ROUTER_ALERT_LEN); + + return igmp_v3_create(pkt, type, mcast, mcast_len); +} +#endif + static int igmp_send(struct net_pkt *pkt) { int ret; @@ -195,41 +339,156 @@ drop: return ret; } -enum net_verdict net_ipv4_igmp_input(struct net_pkt *pkt, - struct net_ipv4_hdr *ip_hdr) +#if defined(CONFIG_NET_IPV4_IGMPV3) +static int send_igmp_v3_report(struct net_if *iface, struct net_ipv4_igmp_v3_query *igmp_v3_hdr) { - NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(igmp_access, - struct net_ipv4_igmp_v2_query); - struct net_ipv4_igmp_v2_query *igmp_hdr; + struct net_if_ipv4 *ipv4 = iface->config.ip.ipv4; + struct net_pkt *pkt = NULL; + int i, group_count = 0, source_count = 0; + int ret = 0; - /* TODO: receive from arbitrary group address instead of - * all_systems + if (!ipv4) { + return -ENOENT; + } + + for (i = 0; i < NET_IF_MAX_IPV4_MADDR; i++) { + /* 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; + } + + group_count++; + source_count += ipv4->mcast[i].sources_len; + } + + if (group_count == 0) { + return -ESRCH; + } + + pkt = net_pkt_alloc_with_buffer( + iface, + IPV4_OPT_HDR_ROUTER_ALERT_LEN + sizeof(struct net_ipv4_igmp_v3_report) + + sizeof(struct net_ipv4_igmp_v3_group_record) * group_count + + sizeof(struct in_addr) * source_count, + AF_INET, IPPROTO_IGMP, PKT_WAIT_TIME); + if (!pkt) { + return -ENOMEM; + } + + /* Send the IGMP V3 membership report to the igmp multicast + * address, as per RFC 3376 Section 4.2.14. */ + + ret = igmp_v3_create_packet(pkt, &igmp_multicast_addr, ipv4->mcast, NET_IF_MAX_IPV4_MADDR, + NET_IPV4_IGMP_REPORT_V3); + if (ret < 0) { + goto drop; + } + + ret = igmp_send(pkt); + if (ret < 0) { + goto drop; + } + + /* So that we do not free the data while it is being sent */ + pkt = NULL; + +drop: + if (pkt) { + net_pkt_unref(pkt); + } + + return ret; +} +#endif + +enum net_verdict net_ipv4_igmp_input(struct net_pkt *pkt, struct net_ipv4_hdr *ip_hdr) +{ +#if defined(CONFIG_NET_IPV4_IGMPV3) + NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(igmpv3_access, struct net_ipv4_igmp_v3_query); + struct net_ipv4_igmp_v3_query *igmpv3_hdr; +#endif + NET_PKT_DATA_ACCESS_CONTIGUOUS_DEFINE(igmpv2_access, struct net_ipv4_igmp_v2_query); + struct net_ipv4_igmp_v2_query *igmpv2_hdr; + enum igmp_version version; + int ret; + int igmp_buf_len = pkt->buffer->len - net_pkt_ip_hdr_len(pkt); + + /* Detect IGMP type (RFC 3376 ch 7.1) */ + if (igmp_buf_len == 8) { + /* IGMPv1/2 detected */ + version = IGMPV2; + } else if (igmp_buf_len >= 12) { + /* IGMPv3 detected */ + version = IGMPV3; +#if !defined(CONFIG_NET_IPV4_IGMPV3) + NET_DBG("DROP: %sv3 msg received but %s support is disabled", "IGMP", "IGMP"); + return NET_DROP; +#endif + } else { + NET_DBG("DROP: unsupported payload length"); + return NET_DROP; + } + if (!net_ipv4_addr_cmp_raw(ip_hdr->dst, (uint8_t *)&all_systems)) { NET_DBG("DROP: Invalid dst address"); return NET_DROP; } - igmp_hdr = (struct net_ipv4_igmp_v2_query *)net_pkt_get_data(pkt, - &igmp_access); - if (!igmp_hdr) { - NET_DBG("DROP: NULL IGMP header"); - return NET_DROP; +#if defined(CONFIG_NET_IPV4_IGMPV3) + if (version == IGMPV3) { + igmpv3_hdr = (struct net_ipv4_igmp_v3_query *)net_pkt_get_data(pkt, &igmpv3_access); + if (!igmpv3_hdr) { + NET_DBG("DROP: NULL %sv3 header", "IGMP"); + return NET_DROP; + } + } else { +#endif + igmpv2_hdr = (struct net_ipv4_igmp_v2_query *)net_pkt_get_data(pkt, &igmpv2_access); + if (!igmpv2_hdr) { + NET_DBG("DROP: NULL %s header", "IGMP"); + return NET_DROP; + } +#if defined(CONFIG_NET_IPV4_IGMPV3) } +#endif - if (net_calc_chksum_igmp(pkt)) { + ret = net_calc_chksum_igmp(pkt); + if (ret != 0u) { NET_DBG("DROP: Invalid checksum"); goto drop; } - net_pkt_acknowledge_data(pkt, &igmp_access); +#if defined(CONFIG_NET_IPV4_IGMPV3) + if (version == IGMPV3) { + net_pkt_acknowledge_data(pkt, &igmpv3_access); + } else { +#endif + net_pkt_acknowledge_data(pkt, &igmpv2_access); +#if defined(CONFIG_NET_IPV4_IGMPV3) + } +#endif - dbg_addr_recv("Internet Group Management Protocol", &ip_hdr->src, - &ip_hdr->dst); + dbg_addr_recv("Internet Group Management Protocol", &ip_hdr->src, &ip_hdr->dst); net_stats_update_ipv4_igmp_recv(net_pkt_iface(pkt)); - (void)send_igmp_report(net_pkt_iface(pkt), igmp_hdr); +#if defined(CONFIG_NET_IPV4_IGMPV3) + if (version == IGMPV3) { + (void)send_igmp_v3_report(net_pkt_iface(pkt), igmpv3_hdr); + } else { +#endif + (void)send_igmp_report(net_pkt_iface(pkt), igmpv2_hdr); +#if defined(CONFIG_NET_IPV4_IGMPV3) + } +#endif net_pkt_unref(pkt); @@ -241,6 +500,7 @@ drop: return NET_DROP; } +#if !defined(CONFIG_NET_IPV4_IGMPV3) static int igmp_send_generic(struct net_if *iface, const struct in_addr *addr, bool join) @@ -280,12 +540,57 @@ drop: return ret; } +#endif -int net_ipv4_igmp_join(struct net_if *iface, const struct in_addr *addr) +#if defined(CONFIG_NET_IPV4_IGMPV3) +static int igmpv3_send_generic(struct net_if *iface, struct net_if_mcast_addr *mcast) +{ + struct net_pkt *pkt; + int ret; + + pkt = net_pkt_alloc_with_buffer(iface, + IPV4_OPT_HDR_ROUTER_ALERT_LEN + + sizeof(struct net_ipv4_igmp_v3_report) + + sizeof(struct net_ipv4_igmp_v3_group_record) + + sizeof(struct in_addr) * mcast->sources_len, + AF_INET, IPPROTO_IGMP, PKT_WAIT_TIME); + if (!pkt) { + return -ENOMEM; + } + + ret = igmp_v3_create_packet(pkt, &igmp_multicast_addr, mcast, 1, NET_IPV4_IGMP_REPORT_V3); + if (ret < 0) { + goto drop; + } + + ret = igmp_send(pkt); + if (ret < 0) { + goto drop; + } + + return 0; + +drop: + net_pkt_unref(pkt); + + return ret; +} +#endif + +int net_ipv4_igmp_join(struct net_if *iface, const struct in_addr *addr, + const struct igmp_param *param) { struct net_if_mcast_addr *maddr; int ret; +#if defined(CONFIG_NET_IPV4_IGMPV3) + if (param != NULL) { + if (param->sources_len > CONFIG_NET_IF_MCAST_IPV4_SOURCE_COUNT) { + return -ENOMEM; + } + } +#endif + maddr = net_if_ipv4_maddr_lookup(addr, &iface); if (maddr && net_if_ipv4_maddr_is_joined(maddr)) { return -EALREADY; @@ -298,18 +603,45 @@ int net_ipv4_igmp_join(struct net_if *iface, const struct in_addr *addr) } } - ret = igmp_send_generic(iface, addr, true); - if (ret < 0) { - return ret; +#if defined(CONFIG_NET_IPV4_IGMPV3) + if (param != NULL) { + maddr->record_type = param->include ? IGMPV3_CHANGE_TO_INCLUDE_MODE + : IGMPV3_CHANGE_TO_EXCLUDE_MODE; + maddr->sources_len = param->sources_len; + for (int i = 0; i < param->sources_len; i++) { + net_ipaddr_copy(&maddr->sources[i].in_addr.s_addr, + ¶m->source_list[i].s_addr); + } + } else { + maddr->record_type = IGMPV3_CHANGE_TO_EXCLUDE_MODE; } +#endif net_if_ipv4_maddr_join(iface, maddr); +#if defined(CONFIG_NET_IPV4_IGMPV3) + ret = igmpv3_send_generic(iface, maddr); +#else + ret = igmp_send_generic(iface, addr, true); +#endif + if (ret < 0) { + net_if_ipv4_maddr_leave(iface, maddr); + return ret; + } + +#if defined(CONFIG_NET_IPV4_IGMPV3) + if (param != NULL) { + /* Updating the record type for further use after sending the join report */ + maddr->record_type = + param->include ? IGMPV3_MODE_IS_INCLUDE : IGMPV3_MODE_IS_EXCLUDE; + } +#endif + net_if_mcast_monitor(iface, &maddr->address, true); - net_mgmt_event_notify_with_info(NET_EVENT_IPV4_MCAST_JOIN, iface, - &maddr->address.in_addr, + net_mgmt_event_notify_with_info(NET_EVENT_IPV4_MCAST_JOIN, iface, &maddr->address.in_addr, sizeof(struct in_addr)); + return ret; } @@ -323,21 +655,27 @@ int net_ipv4_igmp_leave(struct net_if *iface, const struct in_addr *addr) return -ENOENT; } - if (!net_if_ipv4_maddr_rm(iface, addr)) { - return -EINVAL; - } +#if defined(CONFIG_NET_IPV4_IGMPV3) + maddr->record_type = IGMPV3_CHANGE_TO_INCLUDE_MODE; + maddr->sources_len = 0; + ret = igmpv3_send_generic(iface, maddr); +#else ret = igmp_send_generic(iface, addr, false); +#endif if (ret < 0) { return ret; } + if (!net_if_ipv4_maddr_rm(iface, addr)) { + return -EINVAL; + } + net_if_ipv4_maddr_leave(iface, maddr); net_if_mcast_monitor(iface, &maddr->address, false); - net_mgmt_event_notify_with_info(NET_EVENT_IPV4_MCAST_LEAVE, iface, - &maddr->address.in_addr, + net_mgmt_event_notify_with_info(NET_EVENT_IPV4_MCAST_LEAVE, iface, &maddr->address.in_addr, sizeof(struct in_addr)); return ret; } diff --git a/subsys/net/ip/ipv4.h b/subsys/net/ip/ipv4.h index 1359d04bc03..1d7d64fd0b5 100644 --- a/subsys/net/ip/ipv4.h +++ b/subsys/net/ip/ipv4.h @@ -50,19 +50,72 @@ #define NET_IPV4_IGMP_REPORT_V3 0x22 /* v3 Membership report */ struct net_ipv4_igmp_v2_query { + /* IGMP message type */ uint8_t type; + /* Max response code */ uint8_t max_rsp; + /* 16-bit ones' complement of the entire message */ uint16_t chksum; + /* The multicast address being queried */ struct in_addr address; } __packed; struct net_ipv4_igmp_v2_report { + /* IGMP message type */ uint8_t type; + /* Max response code */ uint8_t max_rsp; + /* 16-bit ones' complement of the entire message */ uint16_t chksum; + /* The multicast address being queried */ struct in_addr address; } __packed; +struct net_ipv4_igmp_v3_query { + /* IGMP message type */ + uint8_t type; + /* Max response code */ + uint8_t max_rsp; + /* 16-bit ones' complement of the entire message */ + uint16_t chksum; + /* The multicast address being queried */ + struct in_addr address; + /* Reserved field, ignore */ + uint8_t reserved: 4; + /* Suppress Router-side Processing Flag */ + uint8_t suppress: 1; + /* Querier's Robustness Variable */ + uint8_t qrv: 3; + /* Querier's Query Interval Code */ + uint8_t qqic; + /* Number of Source Addresses */ + uint16_t sources_len; +} __packed; + +struct net_ipv4_igmp_v3_group_record { + /* Record type */ + uint8_t type; + /* Aux Data Len */ + uint8_t aux_len; + /* Number of Source Addresses */ + uint16_t sources_len; + /* The multicast address to report to*/ + struct in_addr address; +} __packed; + +struct net_ipv4_igmp_v3_report { + /* IGMP message type */ + uint8_t type; + /* Reserved field, ignore */ + uint8_t reserved_1; + /* 16-bit ones' complement of the entire message */ + uint16_t chksum; + /* Reserved field, ignore */ + uint16_t reserved_2; + /* Number of Group Records */ + uint16_t groups_len; +} __packed; + /** * @brief Create IPv4 packet in provided net_pkt with option to set all the * caller settable values. diff --git a/subsys/net/ip/net_private.h b/subsys/net/ip/net_private.h index 2fd0928b170..73b15ae4cfa 100644 --- a/subsys/net/ip/net_private.h +++ b/subsys/net/ip/net_private.h @@ -235,7 +235,7 @@ enum net_verdict net_ipv4_igmp_input(struct net_pkt *pkt, struct net_ipv4_hdr *ip_hdr); #else #define net_ipv4_igmp_input(...) -#define net_calc_chksum_igmp(struct net_pkt *pkt) 0U +#define net_calc_chksum_igmp(pkt) 0U #endif /* CONFIG_NET_IPV4_IGMP */ static inline uint16_t net_calc_chksum_icmpv6(struct net_pkt *pkt) diff --git a/subsys/net/lib/dns/llmnr_responder.c b/subsys/net/lib/dns/llmnr_responder.c index e52e986d145..0c41b7df424 100644 --- a/subsys/net/lib/dns/llmnr_responder.c +++ b/subsys/net/lib/dns/llmnr_responder.c @@ -118,7 +118,7 @@ static void llmnr_iface_event_handler(struct net_mgmt_event_callback *cb, { if (mgmt_event == NET_EVENT_IF_UP) { #if defined(CONFIG_NET_IPV4) - int ret = net_ipv4_igmp_join(iface, &local_addr4.sin_addr); + int ret = net_ipv4_igmp_join(iface, &local_addr4.sin_addr, NULL); if (ret < 0) { NET_DBG("Cannot add IPv4 multicast address to iface %p", @@ -592,7 +592,7 @@ static void iface_ipv4_cb(struct net_if *iface, void *user_data) struct in_addr *addr = user_data; int ret; - ret = net_ipv4_igmp_join(iface, addr); + ret = net_ipv4_igmp_join(iface, addr, NULL); if (ret < 0) { NET_DBG("Cannot add IPv4 multicast address to iface %p", iface); diff --git a/subsys/net/lib/dns/mdns_responder.c b/subsys/net/lib/dns/mdns_responder.c index 04acbabbecd..4b8ad11dc1b 100644 --- a/subsys/net/lib/dns/mdns_responder.c +++ b/subsys/net/lib/dns/mdns_responder.c @@ -94,7 +94,7 @@ static void mdns_iface_event_handler(struct net_mgmt_event_callback *cb, { if (mgmt_event == NET_EVENT_IF_UP) { #if defined(CONFIG_NET_IPV4) - int ret = net_ipv4_igmp_join(iface, &local_addr4.sin_addr); + int ret = net_ipv4_igmp_join(iface, &local_addr4.sin_addr, NULL); if (ret < 0) { NET_DBG("Cannot add IPv4 multicast address to iface %p", @@ -634,7 +634,7 @@ static void iface_ipv4_cb(struct net_if *iface, void *user_data) struct in_addr *addr = user_data; int ret; - ret = net_ipv4_igmp_join(iface, addr); + ret = net_ipv4_igmp_join(iface, addr, NULL); if (ret < 0) { NET_DBG("Cannot add IPv4 multicast address to iface %p", iface); diff --git a/subsys/net/lib/shell/ipv4.c b/subsys/net/lib/shell/ipv4.c index 8fc88168c9a..752b1cda046 100644 --- a/subsys/net/lib/shell/ipv4.c +++ b/subsys/net/lib/shell/ipv4.c @@ -118,7 +118,7 @@ static int cmd_net_ip_add(const struct shell *sh, size_t argc, char *argv[]) if (net_ipv4_is_addr_mcast(&addr)) { int ret; - ret = net_ipv4_igmp_join(iface, &addr); + ret = net_ipv4_igmp_join(iface, &addr, NULL); if (ret < 0) { PR_ERROR("Cannot %s multicast group %s for interface %d (%d)\n", "join", net_sprint_ipv4_addr(&addr), idx, ret); diff --git a/tests/net/igmp/src/main.c b/tests/net/igmp/src/main.c index 473b66d3241..ca43c33d164 100644 --- a/tests/net/igmp/src/main.c +++ b/tests/net/igmp/src/main.c @@ -236,7 +236,7 @@ static void join_group(void) { int ret; - ret = net_ipv4_igmp_join(net_iface, &mcast_addr); + ret = net_ipv4_igmp_join(net_iface, &mcast_addr, NULL); if (ignore_already) { zassert_true(ret == 0 || ret == -EALREADY,