diff --git a/0140-add-IP_ADD_SOURCE_MEMBERSHIP-to-setsockopt-for-igmpv3.patch b/0140-add-IP_ADD_SOURCE_MEMBERSHIP-to-setsockopt-for-igmpv3.patch new file mode 100644 index 0000000..a45a262 --- /dev/null +++ b/0140-add-IP_ADD_SOURCE_MEMBERSHIP-to-setsockopt-for-igmpv3.patch @@ -0,0 +1,143 @@ +From 50833670dbebaa12337b3ce909ab95c55d5d8eca Mon Sep 17 00:00:00 2001 +From: wanfeng +Date: Wed, 19 Jun 2024 17:04:35 +0800 +Subject: [PATCH] add IP_ADD_SOURCE_MEMBERSHIP to setsockopt for igmpv3 + +modify ip_mreq_source + +add IP_ADD_SOURCE_MEMBERSHIP to setsockopt for igmpv3 + +add IP_ADD_SOURCE_MEMBERSHIP to setsockopt for igmpv3 +--- + src/api/sockets.c | 93 ++++++++++++++++++++++++++++++++++++++ + src/include/lwip/sockets.h | 2 +- + 2 files changed, 94 insertions(+), 1 deletion(-) + +diff --git a/src/api/sockets.c b/src/api/sockets.c +index 5a72b62..a030f4b 100644 +--- a/src/api/sockets.c ++++ b/src/api/sockets.c +@@ -3859,6 +3859,24 @@ lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_ + return ENOPROTOOPT; + } + break; ++ case IP_ADD_SOURCE_MEMBERSHIP: ++ case IP_DROP_SOURCE_MEMBERSHIP: ++ LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, struct ip_mreq_source); ++#if LWIP_UDP ++ if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_UDP) { ++ err = mcast_sock_add_drop_source_membership(s, &sock->conn->pcb.udp->ipmc, optname, (const struct ip_mreq_source *)optval); ++ } else ++#endif /* LWIP_UDP */ ++#if LWIP_RAW ++ if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_RAW) { ++ err = mcast_sock_add_drop_source_membership(s, &sock->conn->pcb.raw->ipmc, optname, (const struct ip_mreq_source *)optval); ++ } else ++#endif /* LWIP_RAW */ ++ { ++ done_socket(sock); ++ return ENOPROTOOPT; ++ } ++ break; + case MCAST_JOIN_GROUP: + case MCAST_LEAVE_GROUP: { + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, struct group_req); +@@ -4907,6 +4925,81 @@ out: + return (u8_t)err_to_errno(err); + } + ++/** ++ * setsockopt() IP_ADD_SOURCE_MEMBERSHIP / IP_DROP_SOURCE_MEMBERSHIP command ++ */ ++int ++mcast_sock_add_drop_source_membership(int s, struct ip_mc *ipmc, int optname, const struct ip_mreq_source *imr) ++{ ++ struct netif *netif; ++ ip_addr_t if_addr; ++ ip_addr_t multi_addr; ++ ip_addr_t src_addr; ++ err_t err; ++ u8_t if_idx; ++ ++ inet_addr_to_ip4addr(ip_2_ip4(&if_addr), &imr->imr_interface); ++ inet_addr_to_ip4addr(ip_2_ip4(&multi_addr), &imr->imr_multiaddr); ++ inet_addr_to_ip4addr(ip_2_ip4(&src_addr), &imr->imr_sourceaddr); ++ IP_SET_TYPE_VAL(if_addr, IPADDR_TYPE_V4); ++ IP_SET_TYPE_VAL(multi_addr, IPADDR_TYPE_V4); ++ IP_SET_TYPE_VAL(src_addr, IPADDR_TYPE_V4); ++ ++ if (!ip4_addr_ismulticast(ip_2_ip4(&multi_addr)) || ip4_addr_isany(ip_2_ip4(&src_addr))) { ++ return EADDRNOTAVAIL; ++ } ++ ++ if (ip4_addr_isany(ip_2_ip4(&if_addr))) { /* To all network interface */ ++ if (optname == IP_ADD_SOURCE_MEMBERSHIP) { ++ NETIF_FOREACH(netif) { ++ if_idx = netif_get_index(netif); ++ if (!lwip_socket_register_membership(s, if_idx, ip_2_ip4(&multi_addr))) { ++ /* cannot track membership (out of memory) */ ++ err = ENOMEM; ++ goto out; ++ } ++ } ++ err = mcast_join_group(ipmc, &if_addr, &multi_addr, &src_addr); ++ } else { ++ err = mcast_leave_group(ipmc, &if_addr, &multi_addr, &src_addr); ++ } ++ ++ } else { /* To specified network interface */ ++ if (!(ip_2_ip4(&if_addr)->addr & PP_HTONL(IP_CLASSA_NET))) { /* IS a BSD style index ? */ ++ u8_t idx = (u8_t)PP_NTOHL(ip_2_ip4(&if_addr)->addr); ++ netif = netif_get_by_index(idx); ++ if (netif == NULL) { ++ return ENXIO; ++ } ++ *ip_2_ip4(&if_addr) = *netif_ip4_addr(netif); ++ ++ } else { ++ NETIF_FOREACH(netif) { ++ if (ip4_addr_cmp(ip_2_ip4(&if_addr), netif_ip4_addr(netif))) { ++ break; ++ } ++ } ++ if (netif == NULL) { ++ return ENXIO; ++ } ++ } ++ ++ if (optname == IP_ADD_SOURCE_MEMBERSHIP) { ++ if_idx = netif_get_index(netif); ++ if (!lwip_socket_register_membership(s, if_idx, ip_2_ip4(&multi_addr))) { ++ /* cannot track membership (out of memory) */ ++ err = ENOMEM; ++ goto out; ++ } ++ err = mcast_join_netif(ipmc, netif, &multi_addr, &src_addr); ++ } else { ++ err = mcast_leave_netif(ipmc, netif, &multi_addr, &src_addr); ++ } ++ } ++out: ++ return err_to_errno(err); ++} ++ + /** + * setsockopt() MCAST_JOIN_GROUP / MCAST_LEAVE_GROUP command + */ +diff --git a/src/include/lwip/sockets.h b/src/include/lwip/sockets.h +index f2a1b59..038afba 100644 +--- a/src/include/lwip/sockets.h ++++ b/src/include/lwip/sockets.h +@@ -785,8 +785,8 @@ typedef struct ip_mreq { + */ + struct ip_mreq_source { + struct in_addr imr_multiaddr; /* IP multicast address of group */ +- struct in_addr imr_sourceaddr; /* IP address of source */ + struct in_addr imr_interface; /* local IP address of interface */ ++ struct in_addr imr_sourceaddr; /* IP address of source */ + }; + + #define IP_MSFILTER_SIZE(numsrc) \ +-- +2.25.1 + diff --git a/lwip.spec b/lwip.spec index 64d1b3b..5c23860 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: 32 +Release: 33 License: BSD URL: http://savannah.nongnu.org/projects/lwip/ Source0: http://download.savannah.nongnu.org/releases/lwip/%{name}-%{version}.zip @@ -151,7 +151,7 @@ Patch9135: 0136-fix-vlan-filter-bug.patch Patch9136: 0137-reduce-pbuf-pool-size.patch Patch9137: 0138-lwip_sock-add-sock_time_stamp.patch Patch9138: 0139-distinguish-tcp-udp-get_from_sendring.patch - +Patch9139: 0140-add-IP_ADD_SOURCE_MEMBERSHIP-to-setsockopt-for-igmpv3.patch BuildRequires: gcc-c++ dos2unix dpdk-devel #Requires: @@ -180,6 +180,9 @@ cd %{_builddir}/%{name}-%{version}/src %{_libdir}/liblwip.a %changelog +* Tue Jun 25 2024 wanfeng - 2.2.0-33 +- add IP_ADD_SOURCE_MEMBERSHIP and IP_DROP_SOURCE_MEMBERSHIP to setsockopt for igmpv3 + * Mon Jun 17 2024 jiangheng - 2.2.0-32 - distinguish tcp/udp from sendring