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