56#if LWIP_IPV6 && LWIP_IPV6_MLD
77#define MLD6_JOIN_DELAYING_MEMBER_TMR_MS (500)
79#define MLD6_GROUP_NON_MEMBER 0
80#define MLD6_GROUP_DELAYING_MEMBER 1
81#define MLD6_GROUP_IDLE_MEMBER 2
84static struct mld_group *mld6_new_group(
struct netif *ifp,
const ip6_addr_t *
addr);
86static void mld6_delayed_report(
struct mld_group *
group,
u16_t maxresp);
98 struct mld_group *
group = netif_mld6_data(
netif);
100 netif_set_client_data(
netif, LWIP_NETIF_CLIENT_DATA_INDEX_MLD6,
NULL);
127 struct mld_group *
group = netif_mld6_data(
netif);
130 mld6_delayed_report(
group, MLD6_JOIN_DELAYING_MEMBER_TMR_MS);
144mld6_lookfor_group(
struct netif *ifp,
const ip6_addr_t *
addr)
146 struct mld_group *
group = netif_mld6_data(ifp);
149 if (ip6_addr_eq(&(
group->group_address),
addr)) {
167static struct mld_group *
168mld6_new_group(
struct netif *ifp,
const ip6_addr_t *
addr)
170 struct mld_group *
group;
174 ip6_addr_set(&(
group->group_address),
addr);
176 group->group_state = MLD6_GROUP_IDLE_MEMBER;
177 group->last_reporter_flag = 0;
179 group->next = netif_mld6_data(ifp);
181 netif_set_client_data(ifp, LWIP_NETIF_CLIENT_DATA_INDEX_MLD6,
group);
200 netif_set_client_data(
netif, LWIP_NETIF_CLIENT_DATA_INDEX_MLD6,
group->
next);
203 struct mld_group *tmpGroup;
204 for (tmpGroup = netif_mld6_data(
netif); tmpGroup !=
NULL; tmpGroup = tmpGroup->
next) {
205 if (tmpGroup->next ==
group) {
206 tmpGroup->next =
group->next;
211 if (tmpGroup ==
NULL) {
230 struct mld_group *
group;
248 if (ip6_addr_isallnodes_linklocal(ip6_current_dest_addr()) &&
249 ip6_addr_isany(&(mld_hdr->multicast_address))) {
252 group = netif_mld6_data(inp);
254 if ((!(ip6_addr_ismulticast_iflocal(&(
group->group_address)))) &&
255 (!(ip6_addr_isallnodes_linklocal(&(
group->group_address))))) {
265 group = mld6_lookfor_group(inp, ip6_current_dest_addr());
277 group = mld6_lookfor_group(inp, ip6_current_dest_addr());
280 if (
group->group_state == MLD6_GROUP_DELAYING_MEMBER) {
282 group->group_state = MLD6_GROUP_IDLE_MEMBER;
283 group->last_reporter_flag = 0;
315mld6_joingroup(
const ip6_addr_t *srcaddr,
const ip6_addr_t *groupaddr)
325 if (ip6_addr_isany(srcaddr) ||
326 netif_get_ip6_addr_match(
netif, srcaddr) >= 0) {
327 err = mld6_joingroup_netif(
netif, groupaddr);
347mld6_joingroup_netif(
struct netif *
netif,
const ip6_addr_t *groupaddr)
349 struct mld_group *
group;
355 if (ip6_addr_lacks_zone(groupaddr, IP6_MULTICAST)) {
356 ip6_addr_set(&ip6addr, groupaddr);
357 ip6_addr_assign_zone(&ip6addr, IP6_MULTICAST,
netif);
358 groupaddr = &ip6addr;
360 IP6_ADDR_ZONECHECK_NETIF(groupaddr,
netif);
383 mld6_delayed_report(
group, MLD6_JOIN_DELAYING_MEMBER_TMR_MS);
404mld6_leavegroup(
const ip6_addr_t *srcaddr,
const ip6_addr_t *groupaddr)
414 if (ip6_addr_isany(srcaddr) ||
415 netif_get_ip6_addr_match(
netif, srcaddr) >= 0) {
437mld6_leavegroup_netif(
struct netif *
netif,
const ip6_addr_t *groupaddr)
439 struct mld_group *
group;
443 if (ip6_addr_lacks_zone(groupaddr, IP6_MULTICAST)) {
444 ip6_addr_set(&ip6addr, groupaddr);
445 ip6_addr_assign_zone(&ip6addr, IP6_MULTICAST,
netif);
446 groupaddr = &ip6addr;
448 IP6_ADDR_ZONECHECK_NETIF(groupaddr,
netif);
458 if (
group->use <= 1) {
463 if (
group->last_reporter_flag) {
501 struct mld_group *
group = netif_mld6_data(
netif);
504 if (
group->timer > 0) {
506 if (
group->timer == 0) {
508 if (
group->group_state == MLD6_GROUP_DELAYING_MEMBER) {
511 group->group_state = MLD6_GROUP_IDLE_MEMBER;
528mld6_delayed_report(
struct mld_group *
group,
u16_t maxresp_in)
531 u16_t maxresp = maxresp_in / MLD6_TMR_INTERVAL;
538 maxresp = (
u16_t)(LWIP_RAND() % maxresp);
545 if ((
group->group_state == MLD6_GROUP_IDLE_MEMBER) ||
546 ((
group->group_state == MLD6_GROUP_DELAYING_MEMBER) &&
547 ((
group->timer == 0) || (maxresp <
group->timer)))) {
548 group->timer = maxresp;
549 group->group_state = MLD6_GROUP_DELAYING_MEMBER;
567 const ip6_addr_t *src_addr;
584 if (!ip6_addr_isvalid(netif_ip6_addr_state(
netif, 0))) {
587 src_addr = IP6_ADDR_ANY6;
590 src_addr = netif_ip6_addr(
netif, 0);
597 mld_hdr->type =
type;
600 mld_hdr->max_resp_delay = 0;
601 mld_hdr->reserved = 0;
602 ip6_addr_copy_to_packed(mld_hdr->multicast_address,
group->group_address);
604#if CHECKSUM_GEN_ICMP6
607 src_addr, &(
group->group_address));
616 group->last_reporter_flag = 1;
621 ip6_output_if(
p, (ip6_addr_isany(src_addr)) ?
NULL : src_addr, &(
group->group_address),
GLuint GLuint GLsizei GLenum type
GLenum const GLvoid * addr
#define LWIP_ASSERT_CORE_LOCKED()
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
u8_t pbuf_free(struct pbuf *p)
void * memp_malloc(memp_t type)
void memp_free(memp_t type, void *mem)
#define NETIF_FOREACH(netif)
#define IF__NETIF_CHECKSUM_ENABLED(netif, chksumflag)
u8_t pbuf_remove_header(struct pbuf *p, size_t header_size_decrement)
#define IP6_NEXTH_HOPBYHOP
#define IP6_ROUTER_ALERT_VALUE_MLD
static unsigned __int64 next
#define MLD6_STATS_INC(x)