diff --git a/0141-Improve-size-of-multicast-specifications.patch b/0141-Improve-size-of-multicast-specifications.patch new file mode 100644 index 0000000..676352b --- /dev/null +++ b/0141-Improve-size-of-multicast-specifications.patch @@ -0,0 +1,476 @@ +From 9b98c8f97e88ddc6db3e3e14ad5415ff780d381a Mon Sep 17 00:00:00 2001 +From: wanfeng +Date: Thu, 27 Jun 2024 09:40:41 +0800 +Subject: [PATCH] Improve the size of multicast specifications, with a maximum + of 16 groups and 32 members per group + +--- + src/core/ipv4/igmp.c | 11 ++- + src/core/ipv6/mld6.c | 6 +- + src/core/mcast.c | 165 +++++++++++++++++++++++++-------------- + src/include/lwip/mcast.h | 8 +- + src/include/lwipopts.h | 1 + + 5 files changed, 128 insertions(+), 63 deletions(-) + +diff --git a/src/core/ipv4/igmp.c b/src/core/ipv4/igmp.c +index 2567a41..af298be 100644 +--- a/src/core/ipv4/igmp.c ++++ b/src/core/ipv4/igmp.c +@@ -449,8 +449,8 @@ igmp_input(struct pbuf *p, struct netif *inp, const ip4_addr_t *dest) + LWIP_ASSERT("igmp_v3_query packet source address array not aligned!", !((mem_ptr_t)src_buf & 0x3)); + ip4_addr_t igmp_v3_group_address; + memcpy(&igmp_v3_group_address, &igmp_v3->igmp_v3_group_address, sizeof(igmp_v3_group_address)); +- if (mcast_ip4_filter_interest(inp, (const ip4_addr_t *)&igmp_v3_group_address, src_buf, src_cnt)) { +- /* We interest! */ ++ if (mcast_ip4_filter_interest(inp, (const ip4_addr_t *)&igmp_v3_group_address, src_buf, src_cnt)) { ++ /* We interest! */ + igmp_v3_delaying_member(group, igmp_v3->igmp_v3_maxresp); + } + +@@ -463,6 +463,7 @@ igmp_input(struct pbuf *p, struct netif *inp, const ip4_addr_t *dest) + } + } + } ++ break; + } + #endif /* LWIP_IGMP_V3 */ + /* IGMP_MEMB_QUERY to the "all systems" address ? */ +@@ -617,13 +618,14 @@ igmp_joingroup_netif(struct netif *netif, const ip4_addr_t *groupaddr) + } + + IGMP_STATS_INC(igmp.tx_join); ++#if !LWIP_IGMP_V3 + igmp_send(netif, group, IGMP_V2_MEMB_REPORT); + + igmp_start_timer(group, IGMP_JOIN_DELAYING_MEMBER_TMR); + + /* Need to work out where this timer comes from */ + group->group_state = IGMP_GROUP_DELAYING_MEMBER; +- ++#endif + + #if LWIP_IGMP_V3 + igmp_v3_send(netif, group, IGMP_V3_MEMB_REPORT); +@@ -715,16 +717,19 @@ igmp_leavegroup_netif(struct netif *netif, const ip4_addr_t *groupaddr) + /* Remove the group from the list */ + igmp_remove_group(netif, group); + ++#if !LWIP_IGMP_V3 + /* If we are the last reporter for this group */ + if (group->last_reporter_flag) { + LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup_netif: sending leaving group\n")); + IGMP_STATS_INC(igmp.tx_leave); + igmp_send(netif, group, IGMP_LEAVE_GROUP); + } ++#endif + + #if LWIP_IGMP_V3 + /* If we are the last reporter for this group */ + if (group->v3_last_reporter_flag) { ++ IGMP_STATS_INC(igmp.tx_leave); + igmp_v3_send(netif, group, IGMP_LEAVE_GROUP); + } + #endif /* LWIP_IGMP_V3 */ +diff --git a/src/core/ipv6/mld6.c b/src/core/ipv6/mld6.c +index 29c45bc..3aecb35 100644 +--- a/src/core/ipv6/mld6.c ++++ b/src/core/ipv6/mld6.c +@@ -313,7 +313,7 @@ mld6_input(struct pbuf *p, struct netif *inp) + } + } + } +- ++ break; + } + #endif + /* Is it a general query? */ +@@ -451,8 +451,10 @@ mld6_joingroup_netif(struct netif *netif, const ip6_addr_t *groupaddr) + + /* Report our membership. */ + MLD6_STATS_INC(mld6.tx_report); ++#if !LWIP_IPV6_MLD_V2 + mld6_send(netif, group, ICMP6_TYPE_MLR); + mld6_delayed_report(group, MLD6_JOIN_DELAYING_MEMBER_TMR_MS); ++#endif + #if LWIP_IPV6_MLD_V2 + mld6_v2_send(netif, group, ICMP6_TYPE_MLR2); + mld6_v2_delayed_report(group, MLD6_JOIN_DELAYING_MEMBER_TMR_MS); +@@ -536,10 +538,12 @@ mld6_leavegroup_netif(struct netif *netif, const ip6_addr_t *groupaddr) + mld6_remove_group(netif, group); + + /* If we are the last reporter for this group */ ++#if !LWIP_IPV6_MLD_V2 + if (group->last_reporter_flag) { + MLD6_STATS_INC(mld6.tx_leave); + mld6_send(netif, group, ICMP6_TYPE_MLD); + } ++#endif + #if LWIP_IPV6_MLD_V2 + /* If we are the last reporter for this group */ + if (group->v2_last_reporter_flag) { +diff --git a/src/core/mcast.c b/src/core/mcast.c +index fa46f10..0df6373 100644 +--- a/src/core/mcast.c ++++ b/src/core/mcast.c +@@ -449,6 +449,81 @@ mcast_ip6_filter_interest(struct netif *netif, const ip6_addr_t *multi_addr, con + #endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ + + #if (LWIP_IPV4 && LWIP_IGMP) || (LWIP_IPV6 && LWIP_IPV6_MLD) ++ ++#if (LWIP_IPV4 && LWIP_IGMP) ++err_t ++mcast_mc_new_src(struct ip4_mc *mc, const ip_addr_t *src_addr) ++{ ++ struct igmp_src *src; ++ if (mc->num_src >= LWIP_MCAST_SRC_TBL_SIZE) { ++ return ERR_MEM; ++ } ++ src = (struct igmp_src *)mem_malloc(sizeof(struct igmp_src)); ++ if (src == NULL) { ++ return ERR_MEM; /* no memory */ ++ } ++ ip4_addr_set(&src->src_addr, ip_2_ip4(src_addr)); ++ src->next = mc->src; ++ mc->src = src; ++ mc->num_src++; ++ return ERR_OK; ++} ++ ++err_t ++mcast_mc_free_src(struct ip4_mc *mc, struct igmp_src *src, struct igmp_src *src_prev) ++{ ++ if (src == NULL) { ++ return ERR_OK; ++ } ++ if (src_prev) { ++ src_prev->next = src->next; ++ } else { ++ mc->src = src->next; ++ } ++ mem_free(src); ++ if (mc->num_src > 0) ++ mc->num_src--; ++ return ERR_OK; ++} ++#endif ++ ++#if (LWIP_IPV6 && LWIP_IPV6_MLD) ++err_t ++mcast_mc_new_ipv6_src(struct ip6_mc *mc, const ip_addr_t *src_addr) ++{ ++ struct mld6_src *src; ++ if (mc->num_src >= LWIP_MCAST_SRC_TBL_SIZE) { ++ return ERR_MEM; ++ } ++ src = (struct mld6_src *)mem_malloc(sizeof(struct mld6_src)); ++ if (src == NULL) { ++ return ERR_MEM; /* no memory */ ++ } ++ ip6_addr_set(&src->src_addr, ip_2_ip6(src_addr)); ++ src->next = mc->src; ++ mc->src = src; ++ mc->num_src++; ++ return ERR_OK; ++} ++ ++err_t ++mcast_mc_free_ipv6_src(struct ip6_mc *mc, struct mld6_src *src, struct mld6_src *src_prev) ++{ ++ if (src == NULL) { ++ return ERR_OK; ++ } ++ if (src_prev) { ++ src_prev->next = src->next; ++ } else { ++ mc->src = src->next; ++ } ++ mem_free(src); ++ if (mc->num_src > 0) ++ mc->num_src--; ++ return ERR_OK; ++} ++#endif ++ + /** Join a multicast group (Can with a source specified) + * + * @param ipmc multicast filter control block +@@ -480,6 +555,7 @@ mcast_join_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *multi + if (IP_IS_V4(multi_addr)) { + struct ip4_mc *mc; + struct igmp_src *src; ++ err_t err; + + mc = mcast_ip4_mc_find(ipmc, netif, ip_2_ip4(multi_addr), NULL); + if (mc) { +@@ -492,13 +568,9 @@ mcast_join_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *multi + return ERR_ALREADY; /* already in source list */ + } + +- src = (struct igmp_src *)mem_malloc(sizeof(struct igmp_src)); +- if (src == NULL) { ++ if (mcast_mc_new_src(mc, src_addr) != ERR_OK) { + return ERR_MEM; /* no memory */ + } +- ip4_addr_set(&src->src_addr, ip_2_ip4(src_addr)); +- src->next = mc->src; +- mc->src = src; + mc->fmode = MCAST_INCLUDE; /* change to include mode */ + IP4_MC_TRIGGER_CALL(netif, ip_2_ip4(multi_addr)); /* trigger a report */ + return ERR_OK; +@@ -511,20 +583,19 @@ mcast_join_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *multi + igmp_leavegroup_netif(netif, ip_2_ip4(multi_addr)); + return ERR_MEM; /* no memory */ + } ++ mc->num_src = 0; ++ mc->src = NULL; ++ mc->if_idx = netif_get_index(netif); + ip4_addr_set(&mc->if_addr, netif_ip4_addr(netif)); + ip4_addr_set(&mc->multi_addr, ip_2_ip4(multi_addr)); + + if (src_addr) { /* have a source specified */ + mc->fmode = MCAST_INCLUDE; +- src = (struct igmp_src *)mem_malloc(sizeof(struct igmp_src)); +- if (src == NULL) { ++ if (mcast_mc_new_src(mc, src_addr) != ERR_OK) { ++ igmp_leavegroup_netif(netif, ip_2_ip4(multi_addr)); + mem_free(mc); + return ERR_MEM; /* no memory */ + } +- ip4_addr_set(&src->src_addr, ip_2_ip4(src_addr)); +- src->next = NULL; +- mc->src = src; +- + } else { + mc->fmode = MCAST_EXCLUDE; /* no source specified */ + mc->src = NULL; +@@ -532,13 +603,19 @@ mcast_join_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *multi + + mc->next = ipmc->mc4; + ipmc->mc4 = mc; +- igmp_joingroup_netif(netif, ip_2_ip4(multi_addr)); ++ err = igmp_joingroup_netif(netif, ip_2_ip4(multi_addr)); ++ if (err != ERR_OK) { ++ ipmc->mc4 = mc->next; ++ mem_free(mc); ++ } ++ return err; + } else + #endif /* LWIP_IPV4 && LWIP_IGMP */ + { + #if LWIP_IPV6 && LWIP_IPV6_MLD + struct ip6_mc *mc; + struct mld6_src *src; ++ err_t err; + + mc = mcast_ip6_mc_find(ipmc, netif, ip_2_ip6(multi_addr), NULL); + if (mc) { +@@ -551,13 +628,9 @@ mcast_join_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *multi + return ERR_ALREADY; /* already in source list */ + } + +- src = (struct mld6_src *)mem_malloc(sizeof(struct mld6_src)); +- if (src == NULL) { ++ if (mcast_mc_new_ipv6_src(mc, src_addr) != ERR_OK) { + return ERR_MEM; /* no memory */ + } +- ip6_addr_set(&src->src_addr, ip_2_ip6(src_addr)); +- src->next = mc->src; +- mc->src = src; + mc->fmode = MCAST_INCLUDE; /* change to include mode */ + IP6_MC_TRIGGER_CALL(netif, ip_2_ip6(multi_addr)); /* trigger a report */ + return ERR_OK; +@@ -570,21 +643,18 @@ mcast_join_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *multi + mld6_leavegroup_netif(netif, ip_2_ip6(multi_addr)); + return ERR_MEM; /* no memory */ + } ++ mc->num_src = 0; ++ mc->src = NULL; + mc->if_idx = netif_get_index(netif); + ip6_addr_set(&mc->multi_addr, ip_2_ip6(multi_addr)); + + if (src_addr) { + mc->fmode = MCAST_INCLUDE; +- src = (struct mld6_src *)mem_malloc(sizeof(struct mld6_src)); +- if (src == NULL) { ++ if (mcast_mc_new_ipv6_src(mc, src_addr) != ERR_OK) { + mld6_leavegroup_netif(netif, ip_2_ip6(multi_addr)); + mem_free(mc); + return ERR_MEM; /* no memory */ + } +- ip6_addr_set(&src->src_addr, ip_2_ip6(src_addr)); +- src->next = NULL; +- mc->src = src; +- + } else { + mc->fmode = MCAST_EXCLUDE; /* no source specified */ + mc->src = NULL; +@@ -592,7 +662,12 @@ mcast_join_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *multi + + mc->next = ipmc->mc6; + ipmc->mc6 = mc; +- mld6_joingroup_netif(netif, ip_2_ip6(multi_addr)); ++ err = mld6_joingroup_netif(netif, ip_2_ip6(multi_addr)); ++ if (err != ERR_OK) { ++ ipmc->mc6 = mc->next; ++ mem_free(mc); ++ } ++ return err; + #endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ + } + return ERR_OK; +@@ -673,12 +748,7 @@ mcast_leave_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *mult + + src = mcast_ip4_mc_src_find(mc, ip_2_ip4(src_addr), &src_prev); + if (src) { +- if (src_prev) { +- src_prev->next = src->next; +- } else { +- mc->src = src->next; +- } +- mem_free(src); ++ mcast_mc_free_src(mc, src, src_prev); + } else { + return ERR_VAL; + } +@@ -688,6 +758,7 @@ mcast_leave_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *mult + } + } else { /* we want drop this group */ + mcast_ip4_mc_src_remove(mc->src); ++ mc->num_src = 0; + } + + igmp_leavegroup_netif(netif, ip_2_ip4(multi_addr)); +@@ -718,12 +789,7 @@ mcast_leave_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *mult + + src = mcast_ip6_mc_src_find(mc, ip_2_ip6(src_addr), &src_prev); + if (src) { +- if (src_prev) { +- src_prev->next = src->next; +- } else { +- mc->src = src->next; +- } +- mem_free(src); ++ mcast_mc_free_ipv6_src(mc, src, src_prev); + } else { + return ERR_VAL; + } +@@ -733,6 +799,7 @@ mcast_leave_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *mult + } + } else { /* we want drop this group */ + mcast_ip6_mc_src_remove(mc->src); ++ mc->num_src = 0; + } + + mld6_leavegroup_netif(netif, ip_2_ip6(multi_addr)); +@@ -818,13 +885,9 @@ mcast_block_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *mult + + src = mcast_ip4_mc_src_find(mc, ip_2_ip4(blk_addr), NULL); + if (src == NULL) { +- src = (struct igmp_src *)mem_malloc(sizeof(struct igmp_src)); +- if (src == NULL) { ++ if (mcast_mc_new_src(mc, blk_addr) != ERR_OK) { + return ERR_MEM; + } +- ip4_addr_set(&src->src_addr, ip_2_ip4(blk_addr)); +- src->next = mc->src; +- mc->src = src; + IP4_MC_TRIGGER_CALL(netif, ip_2_ip4(multi_addr)); /* trigger a report */ + } + } else +@@ -844,13 +907,9 @@ mcast_block_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *mult + + src = mcast_ip6_mc_src_find(mc, ip_2_ip6(blk_addr), NULL); + if (src == NULL) { +- src = (struct mld6_src *)mem_malloc(sizeof(struct mld6_src)); +- if (src == NULL) { ++ if (mcast_mc_new_ipv6_src(mc, blk_addr) != ERR_OK) { + return ERR_MEM; + } +- ip6_addr_set(&src->src_addr, ip_2_ip6(blk_addr)); +- src->next = mc->src; +- mc->src = src; + IP6_MC_TRIGGER_CALL(netif, ip_2_ip6(multi_addr)); /* trigger a report */ + } + #endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ +@@ -932,12 +991,7 @@ mcast_unblock_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *mu + if (src == NULL) { + return ERR_VAL; + } +- if (src_prev) { +- src_prev->next = src->next; +- } else { +- mc->src = src->next; +- } +- mem_free(src); ++ mcast_mc_free_src(mc, src, src_prev); + IP4_MC_TRIGGER_CALL(netif, ip_2_ip4(multi_addr)); /* trigger a report */ + } else + #endif /* LWIP_IPV4 && LWIP_IGMP */ +@@ -959,12 +1013,7 @@ mcast_unblock_netif(struct ip_mc *ipmc, struct netif *netif, const ip_addr_t *mu + if (src == NULL) { + return ERR_VAL; + } +- if (src_prev) { +- src_prev->next = src->next; +- } else { +- mc->src = src->next; +- } +- mem_free(src); ++ mcast_mc_free_ipv6_src(mc, src, src_prev); + IP6_MC_TRIGGER_CALL(netif, ip_2_ip6(multi_addr)); /* trigger a report */ + #endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ + } +diff --git a/src/include/lwip/mcast.h b/src/include/lwip/mcast.h +index 16a27ae..6067a3c 100644 +--- a/src/include/lwip/mcast.h ++++ b/src/include/lwip/mcast.h +@@ -4,7 +4,7 @@ + */ + + /* +- * Copyright (c) 2001-2004 Swedish Institute of Computer Science. ++ * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, +@@ -56,12 +56,16 @@ + /** the IPv4 multicast filter */ + struct ip4_mc { + struct ip4_mc *next; ++ /** the interface index */ ++ u8_t if_idx; + /** the interface address */ + ip4_addr_t if_addr; + /** the group address */ + ip4_addr_t multi_addr; + /** the source address list filter mode 0: EXCLUDE 1: INCLUDE */ + u8_t fmode; ++ /** the num of source address**/ ++ u8_t num_src; + /** the source address list */ + struct igmp_src *src; + }; +@@ -84,6 +88,8 @@ struct ip6_mc { + ip6_addr_t multi_addr; + /** the source address list filter mode 0: EXCLUDE 1: INCLUDE */ + u8_t fmode; ++ /** the num of source address**/ ++ u8_t num_src; + /** the source address list */ + struct mld6_src *src; + }; +diff --git a/src/include/lwipopts.h b/src/include/lwipopts.h +index cb3154a..44dcddf 100644 +--- a/src/include/lwipopts.h ++++ b/src/include/lwipopts.h +@@ -194,6 +194,7 @@ + + #define MEMP_NUM_UDP_PCB (GAZELLE_MAX_CLIENTS + GAZELLE_RESERVED_CLIENTS) + #define MEMP_NUM_IGMP_GROUP 16 ++#define MEMP_NUM_MLD6_GROUP 16 + + #define DEFAULT_UDP_RECVMBOX_SIZE 4096 + +-- +2.25.1 + diff --git a/lwip.spec b/lwip.spec index 5c23860..b6ab04a 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: 33 +Release: 34 License: BSD URL: http://savannah.nongnu.org/projects/lwip/ Source0: http://download.savannah.nongnu.org/releases/lwip/%{name}-%{version}.zip @@ -152,6 +152,7 @@ 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 +Patch9140: 0141-Improve-size-of-multicast-specifications.patch BuildRequires: gcc-c++ dos2unix dpdk-devel #Requires: @@ -180,6 +181,9 @@ cd %{_builddir}/%{name}-%{version}/src %{_libdir}/liblwip.a %changelog +* Thu Jun 27 2024 wanfeng - 2.2.0-34 +- Improve the size of multicast specifications, with a maximum of 16 groups and 32 members per group + * Tue Jun 25 2024 wanfeng - 2.2.0-33 - add IP_ADD_SOURCE_MEMBERSHIP and IP_DROP_SOURCE_MEMBERSHIP to setsockopt for igmpv3