From 9dc9d24390a0693bb55a386f03e2de2662648127 Mon Sep 17 00:00:00 2001 From: wanfeng Date: Fri, 28 Jun 2024 11:24:45 +0800 Subject: [PATCH] add MCAST_MSFILTER to setsockopt for IGMPv3 (cherry picked from commit 836544f19c307b9148cd3aa95b261e8d95775e16) --- ...ST_MSFILTER-to-setsockopt-for-IGMPv3.patch | 174 ++++++++++++++++++ lwip.spec | 7 +- 2 files changed, 179 insertions(+), 2 deletions(-) create mode 100644 0143-add-MCAST_MSFILTER-to-setsockopt-for-IGMPv3.patch diff --git a/0143-add-MCAST_MSFILTER-to-setsockopt-for-IGMPv3.patch b/0143-add-MCAST_MSFILTER-to-setsockopt-for-IGMPv3.patch new file mode 100644 index 0000000..ed89a9e --- /dev/null +++ b/0143-add-MCAST_MSFILTER-to-setsockopt-for-IGMPv3.patch @@ -0,0 +1,174 @@ +From 6546c316644dd1c04088242f3274ef6a1579e3c4 Mon Sep 17 00:00:00 2001 +From: wanfeng +Date: Fri, 28 Jun 2024 10:56:51 +0800 +Subject: [PATCH] add MCAST_MSFILTER to setsockopt for IGMPv3 + +--- + src/api/sockets.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 137 insertions(+) + +diff --git a/src/api/sockets.c b/src/api/sockets.c +index a030f4b..7a67650 100644 +--- a/src/api/sockets.c ++++ b/src/api/sockets.c +@@ -3940,6 +3940,27 @@ lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_ + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_RAW) { + err = mcast_sock_block_unblock_source_group(&sock->conn->pcb.raw->ipmc, optname, (const struct group_source_req *)optval); + } else ++#endif /* LWIP_RAW */ ++ { ++ done_socket(sock); ++ return ENOPROTOOPT; ++ } ++ break; ++ case MCAST_MSFILTER: ++ LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, struct group_filter); ++ if (((const struct group_filter *)optval)->gf_group.ss_family != AF_INET) { ++ done_socket(sock); ++ return EINVAL; ++ } ++#if LWIP_UDP ++ if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_UDP) { ++ err = mcast_sock_set_groupfilter(&sock->conn->pcb.udp->ipmc, optname, (const struct group_filter *)optval); ++ } else ++#endif /* LWIP_UDP */ ++#if LWIP_RAW ++ if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_RAW) { ++ err = mcast_sock_set_groupfilter(&sock->conn->pcb.raw->ipmc, optname, (const struct group_filter *)optval); ++ } else + #endif /* LWIP_RAW */ + { + done_socket(sock); +@@ -4729,6 +4750,78 @@ lwip_socket_drop_registered_mld6_memberships(int s) + } + #endif /* LWIP_IPV6_MLD */ + ++/** Set filter to a multicast group (group_filter) ++ * ++ * @param ipmc multicast filter control block ++ * @param netif the network interface which group we already join. ++ * @param multi_addr the address of the group to add source ++ * @param gf filter ++ * @return lwIP error definitions ++ */ ++err_t ++mcast_set_groupfilter_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *multi_addr, const struct group_filter *gf) ++{ ++#if LWIP_IPV4 && LWIP_IGMP ++ if (IP_IS_V4(multi_addr)) { ++ struct ip4_mc *mc; ++ struct igmp_src *src, *head = NULL; ++ u32_t i; ++ ++ mc = mcast_ip4_mc_find(ipmc, netif, ip_2_ip4(multi_addr), NULL); ++ if (mc == NULL) { ++ return ERR_VAL; ++ } ++ mc->num_src = 0; ++ for (i = 0; i < gf->gf_numsrc; i++) { ++ src = (struct igmp_src *)mem_malloc(sizeof(struct igmp_src)); ++ if (src == NULL) { ++ mcast_ip4_mc_src_remove(head); ++ return ERR_MEM; ++ } ++ inet_addr_to_ip4addr(&src->src_addr, &(((struct sockaddr_in *)&(gf->gf_slist[i]))->sin_addr)); ++ src->next = head; ++ head = src; ++ mc->num_src++; ++ } ++ ++ mc->fmode = (u8_t)gf->gf_fmode; ++ mcast_ip4_mc_src_remove(mc->src); ++ mc->src = head; ++ IP4_MC_TRIGGER_CALL(netif, ip_2_ip4(multi_addr)); /* trigger a report */ ++ } else ++#endif /* LWIP_IPV4 && LWIP_IGMP */ ++ { ++#if LWIP_IPV6 && LWIP_IPV6_MLD ++ struct ip6_mc *mc; ++ struct mld6_src *src, *head = NULL; ++ u32_t i; ++ ++ mc = mcast_ip6_mc_find(ipmc, netif, ip_2_ip6(multi_addr), NULL); ++ if (mc == NULL) { ++ return ERR_VAL; ++ } ++ mc->num_src = 0; ++ for (i = 0; i < gf->gf_numsrc; i++) { ++ src = (struct mld6_src *)mem_malloc(sizeof(struct mld6_src)); ++ if (src == NULL) { ++ mcast_ip6_mc_src_remove(head); ++ return ERR_MEM; ++ } ++ inet6_addr_to_ip6addr(&src->src_addr, &(((struct sockaddr_in6 *)&(gf->gf_slist[i]))->sin6_addr)); ++ src->next = head; ++ head = src; ++ mc->num_src++; ++ } ++ ++ mc->fmode = (u8_t)gf->gf_fmode; ++ mcast_ip6_mc_src_remove(mc->src); ++ mc->src = head; ++ IP6_MC_TRIGGER_CALL(netif, ip_2_ip6(multi_addr)); /* trigger a report */ ++#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ ++ } ++ return ERR_OK; ++} ++ + /** Remove multicast filter when pcb remove + * + * @param ipmc multicast filter control block +@@ -5199,6 +5292,50 @@ mcast_sock_block_unblock_source_group(struct ip_mc *ipmc, int optname, const str + return err_to_errno(err); + } + ++/** ++ * setsockopt() MCAST_MSFILTER command ++ */ ++int ++mcast_sock_set_groupfilter(struct ip_mc *ipmc, int optname, const struct group_filter *gf) ++{ ++ struct netif *netif; ++ ip_addr_t multi_addr; ++ ++ LWIP_UNUSED_ARG(optname); ++ ++ if (gf->gf_numsrc > LWIP_MCAST_SRC_TBL_SIZE) { ++ return ERR_VAL; ++ } ++ if (gf->gf_group.ss_family == AF_INET) { ++ inet_addr_to_ip4addr(ip_2_ip4(&multi_addr), &(((struct sockaddr_in *)&(gf->gf_group))->sin_addr)); ++ IP_SET_TYPE_VAL(multi_addr, IPADDR_TYPE_V4); ++ if (!ip4_addr_ismulticast(ip_2_ip4(&multi_addr))) { ++ return EADDRNOTAVAIL; ++ } ++ ++ } else if (gf->gf_group.ss_family == AF_INET6) { ++ inet6_addr_to_ip6addr(ip_2_ip6(&multi_addr), &(((struct sockaddr_in6 *)&(gf->gf_group))->sin6_addr)); ++ IP_SET_TYPE_VAL(multi_addr, IPADDR_TYPE_V6); ++ if (!ip6_addr_ismulticast(ip_2_ip6(&multi_addr))) { ++ return EADDRNOTAVAIL; ++ } ++ ++ } else { ++ return EADDRNOTAVAIL; ++ } ++ ++ if (gf->gf_interface) { ++ netif = netif_get_by_index((u8_t)gf->gf_interface); ++ } else { ++ netif = netif_default; /* To default network interface */ ++ } ++ if (netif == NULL) { ++ return ENXIO; ++ } ++ ++ return err_to_errno(mcast_set_groupfilter_netif(ipmc, netif, &multi_addr, gf)); ++} ++ + /** + * setsockopt() IPV6_JOIN_GROUP / IPV6_LEAVE_GROUP command + */ +-- +2.25.1 + diff --git a/lwip.spec b/lwip.spec index 05dac9d..7f31f1f 100644 --- a/lwip.spec +++ b/lwip.spec @@ -4,7 +4,7 @@ Summary: lwip is a small independent implementation of the TCP/IP protocol suite Name: lwip Version: 2.2.0 -Release: 35 +Release: 36 License: BSD URL: http://savannah.nongnu.org/projects/lwip/ Source0: http://download.savannah.nongnu.org/releases/lwip/%{name}-%{version}.zip @@ -154,7 +154,7 @@ Patch9138: 0139-distinguish-tcp-udp-get_from_sendring.patch Patch9139: 0140-add-IP_ADD_SOURCE_MEMBERSHIP-to-setsockopt-for-igmpv3.patch Patch9140: 0141-Improve-size-of-multicast-specifications.patch Patch9141: 0142-virtio-record-local_port-for-port_map-of-virtio.patch - +Patch9142: 0143-add-MCAST_MSFILTER-to-setsockopt-for-IGMPv3.patch BuildRequires: gcc-c++ dos2unix dpdk-devel #Requires: @@ -183,6 +183,9 @@ cd %{_builddir}/%{name}-%{version}/src %{_libdir}/liblwip.a %changelog +* Fri Jun 28 2024 wanfeng - 2.2.0-36 +- add MCAST_MSFILTER to setsockopt for IGMPv3 + * Tue Jun 25 2024 hankangkang - 2.2.0-35 - virtio: record local_port for distributing pkts in virtio_user.