47 #if LWIP_IPV6 && LWIP_IPV6_MLD 67 #define MLD6_JOIN_DELAYING_MEMBER_TMR_MS (500) 69 #define MLD6_GROUP_NON_MEMBER 0 70 #define MLD6_GROUP_DELAYING_MEMBER 1 71 #define MLD6_GROUP_IDLE_MEMBER 2 75 static struct mld_group* mld_group_list;
79 static struct mld_group * mld6_new_group(
struct netif *ifp,
const ip6_addr_t *addr);
80 static err_t mld6_free_group(
struct mld_group *group);
81 static void mld6_delayed_report(
struct mld_group *group,
u16_t maxresp);
82 static void mld6_send(
struct mld_group *group,
u8_t type);
93 struct mld_group *group = mld_group_list;
94 struct mld_group *prev =
NULL;
95 struct mld_group *next;
98 while (group !=
NULL) {
101 if (group->netif == netif) {
103 if (group == mld_group_list) {
104 mld_group_list = next;
111 if (netif->mld_mac_filter !=
NULL) {
112 netif->mld_mac_filter(netif, &(group->group_address), MLD6_DEL_MAC_FILTER);
132 mld6_report_groups(
struct netif *netif)
134 struct mld_group *group = mld_group_list;
136 while (group !=
NULL) {
137 if (group->netif == netif) {
138 mld6_delayed_report(group, MLD6_JOIN_DELAYING_MEMBER_TMR_MS);
153 mld6_lookfor_group(
struct netif *ifp,
const ip6_addr_t *addr)
155 struct mld_group *group = mld_group_list;
157 while (group !=
NULL) {
158 if ((group->netif == ifp) && (ip6_addr_cmp(&(group->group_address), addr))) {
176 static struct mld_group *
177 mld6_new_group(
struct netif *ifp,
const ip6_addr_t *addr)
179 struct mld_group *group;
181 group = (
struct mld_group *)
memp_malloc(MEMP_MLD6_GROUP);
184 ip6_addr_set(&(group->group_address), addr);
186 group->group_state = MLD6_GROUP_IDLE_MEMBER;
187 group->last_reporter_flag = 0;
189 group->next = mld_group_list;
191 mld_group_list = group;
204 mld6_free_group(
struct mld_group *group)
209 if (mld_group_list == group) {
210 mld_group_list = group->next;
213 struct mld_group *tmpGroup;
214 for (tmpGroup = mld_group_list; tmpGroup !=
NULL; tmpGroup = tmpGroup->next) {
215 if (tmpGroup->next == group) {
216 tmpGroup->next = group->next;
221 if (tmpGroup ==
NULL) {
239 mld6_input(
struct pbuf *p,
struct netif *inp)
241 struct mld_header * mld_hdr;
242 struct mld_group* group;
247 if (p->
len <
sizeof(
struct mld_header)) {
255 mld_hdr = (
struct mld_header *)p->
payload;
257 switch (mld_hdr->type) {
260 if (ip6_addr_isallnodes_linklocal(ip6_current_dest_addr()) &&
261 ip6_addr_isany(&(mld_hdr->multicast_address))) {
264 group = mld_group_list;
265 while (group !=
NULL) {
266 if ((group->netif == inp) &&
267 (!(ip6_addr_ismulticast_iflocal(&(group->group_address)))) &&
268 (!(ip6_addr_isallnodes_linklocal(&(group->group_address))))) {
269 mld6_delayed_report(group, mld_hdr->max_resp_delay);
278 group = mld6_lookfor_group(inp, ip6_current_dest_addr());
281 mld6_delayed_report(group, mld_hdr->max_resp_delay);
290 group = mld6_lookfor_group(inp, ip6_current_dest_addr());
293 if (group->group_state == MLD6_GROUP_DELAYING_MEMBER) {
295 group->group_state = MLD6_GROUP_IDLE_MEMBER;
296 group->last_reporter_flag = 0;
321 mld6_joingroup(
const ip6_addr_t *srcaddr,
const ip6_addr_t *groupaddr)
328 while (netif !=
NULL) {
330 if (ip6_addr_isany(srcaddr) ||
331 netif_get_ip6_addr_match(netif, srcaddr) >= 0) {
332 err = mld6_joingroup_netif(netif, groupaddr);
353 mld6_joingroup_netif(
struct netif *netif,
const ip6_addr_t *groupaddr)
355 struct mld_group *group;
358 group = mld6_lookfor_group(netif, groupaddr);
362 group = mld6_new_group(netif, groupaddr);
368 if (netif->mld_mac_filter !=
NULL) {
369 netif->mld_mac_filter(netif, groupaddr, MLD6_ADD_MAC_FILTER);
375 mld6_delayed_report(group, MLD6_JOIN_DELAYING_MEMBER_TMR_MS);
392 mld6_leavegroup(
const ip6_addr_t *srcaddr,
const ip6_addr_t *groupaddr)
399 while (netif !=
NULL) {
401 if (ip6_addr_isany(srcaddr) ||
402 netif_get_ip6_addr_match(netif, srcaddr) >= 0) {
403 err_t res = mld6_leavegroup_netif(netif, groupaddr);
424 mld6_leavegroup_netif(
struct netif *netif,
const ip6_addr_t *groupaddr)
426 struct mld_group *group;
429 group = mld6_lookfor_group(netif, groupaddr);
433 if (group->use <= 1) {
435 if (group->last_reporter_flag) {
441 if (netif->mld_mac_filter !=
NULL) {
442 netif->mld_mac_filter(netif, groupaddr, MLD6_DEL_MAC_FILTER);
446 mld6_free_group(group);
470 struct mld_group *group = mld_group_list;
472 while (group !=
NULL) {
473 if (group->timer > 0) {
475 if (group->timer == 0) {
477 if (group->group_state == MLD6_GROUP_DELAYING_MEMBER) {
480 group->group_state = MLD6_GROUP_IDLE_MEMBER;
496 mld6_delayed_report(
struct mld_group *group,
u16_t maxresp)
499 maxresp = maxresp / MLD6_TMR_INTERVAL;
513 if ((group->group_state == MLD6_GROUP_IDLE_MEMBER) ||
514 ((group->group_state == MLD6_GROUP_DELAYING_MEMBER) &&
515 ((group->timer == 0) || (maxresp < group->timer)))) {
516 group->timer = maxresp;
517 group->group_state = MLD6_GROUP_DELAYING_MEMBER;
531 mld6_send(
struct mld_group *group,
u8_t type)
533 struct mld_header * mld_hdr;
535 const ip6_addr_t * src_addr;
552 if (!ip6_addr_isvalid(netif_ip6_addr_state(group->netif, 0))) {
555 src_addr = IP6_ADDR_ANY6;
558 src_addr = netif_ip6_addr(group->netif, 0);
562 mld_hdr = (
struct mld_header *)p->
payload;
565 mld_hdr->type = type;
568 mld_hdr->max_resp_delay = 0;
569 mld_hdr->reserved = 0;
570 ip6_addr_set(&(mld_hdr->multicast_address), &(group->group_address));
572 #if CHECKSUM_GEN_ICMP6 574 mld_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->
len,
575 src_addr, &(group->group_address));
580 ip6_options_add_hbh_ra(p, IP6_NEXTH_ICMP6, IP6_ROUTER_ALERT_VALUE_MLD);
584 ip6_output_if(p, (ip6_addr_isany(src_addr)) ?
NULL : src_addr, &(group->group_address),
585 MLD6_HL, 0, IP6_NEXTH_HOPBYHOP, group->netif);
struct netif * netif_list
u8_t pbuf_header(struct pbuf *p, s16_t header_size_increment)
#define MLD6_STATS_INC(x)
#define IF__NETIF_CHECKSUM_ENABLED(netif, chksumflag)
void memp_free(memp_t type, void *mem)
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)