51 #if LWIP_IPV6 && LWIP_IPV6_MLD   
   72 #define MLD6_JOIN_DELAYING_MEMBER_TMR_MS  (500) 
   74 #define MLD6_GROUP_NON_MEMBER             0 
   75 #define MLD6_GROUP_DELAYING_MEMBER        1 
   76 #define MLD6_GROUP_IDLE_MEMBER            2 
   79 static struct mld_group *mld6_new_group(
struct netif *ifp, 
const ip6_addr_t *addr);
 
   80 static err_t mld6_remove_group(
struct netif *
netif, 
struct mld_group *group);
 
   81 static void mld6_delayed_report(
struct mld_group *group, 
u16_t maxresp);
 
   82 static void mld6_send(
struct netif *
netif, 
struct mld_group *group, 
u8_t type);
 
   93   struct mld_group *group = netif_mld6_data(
netif);
 
   95   netif_set_client_data(
netif, LWIP_NETIF_CLIENT_DATA_INDEX_MLD6, 
NULL);
 
   97   while (group != 
NULL) {
 
   98     struct mld_group *next = group->next; 
 
  122   struct mld_group *group = netif_mld6_data(
netif);
 
  124   while (group != 
NULL) {
 
  125     mld6_delayed_report(group, MLD6_JOIN_DELAYING_MEMBER_TMR_MS);
 
  139 mld6_lookfor_group(
struct netif *ifp, 
const ip6_addr_t *addr)
 
  141   struct mld_group *group = netif_mld6_data(ifp);
 
  143   while (group != 
NULL) {
 
  144     if (ip6_addr_cmp(&(group->group_address), addr)) {
 
  162 static struct mld_group *
 
  163 mld6_new_group(
struct netif *ifp, 
const ip6_addr_t *addr)
 
  165   struct mld_group *group;
 
  167   group = (
struct mld_group *)
memp_malloc(MEMP_MLD6_GROUP);
 
  169     ip6_addr_set(&(group->group_address), addr);
 
  171     group->group_state        = MLD6_GROUP_IDLE_MEMBER;
 
  172     group->last_reporter_flag = 0;
 
  174     group->next               = netif_mld6_data(ifp);
 
  176     netif_set_client_data(ifp, LWIP_NETIF_CLIENT_DATA_INDEX_MLD6, group);
 
  189 mld6_remove_group(
struct netif *
netif, 
struct mld_group *group)
 
  194   if (netif_mld6_data(
netif) == group) {
 
  195     netif_set_client_data(
netif, LWIP_NETIF_CLIENT_DATA_INDEX_MLD6, group->
next);
 
  198     struct mld_group *tmpGroup;
 
  199     for (tmpGroup = netif_mld6_data(
netif); tmpGroup != 
NULL; tmpGroup = tmpGroup->next) {
 
  200       if (tmpGroup->next == group) {
 
  201         tmpGroup->next = group->next;
 
  206     if (tmpGroup == 
NULL) {
 
  222 mld6_input(
struct pbuf *p, 
struct netif *inp)
 
  225   struct mld_group *group;
 
  240   switch (mld_hdr->type) {
 
  243     if (ip6_addr_isallnodes_linklocal(ip6_current_dest_addr()) &&
 
  244         ip6_addr_isany(&(mld_hdr->multicast_address))) {
 
  247       group = netif_mld6_data(inp);
 
  248       while (group != 
NULL) {
 
  249         if ((!(ip6_addr_ismulticast_iflocal(&(group->group_address)))) &&
 
  250             (!(ip6_addr_isallnodes_linklocal(&(group->group_address))))) {
 
  251           mld6_delayed_report(group, mld_hdr->max_resp_delay);
 
  260       group = mld6_lookfor_group(inp, ip6_current_dest_addr());
 
  263         mld6_delayed_report(group, mld_hdr->max_resp_delay);
 
  272     group = mld6_lookfor_group(inp, ip6_current_dest_addr());
 
  275       if (group->group_state == MLD6_GROUP_DELAYING_MEMBER) {
 
  277         group->group_state = MLD6_GROUP_IDLE_MEMBER;
 
  278         group->last_reporter_flag = 0;
 
  304 mld6_joingroup(
const ip6_addr_t *srcaddr, 
const ip6_addr_t *groupaddr)
 
  313     if (ip6_addr_isany(srcaddr) ||
 
  314         netif_get_ip6_addr_match(
netif, srcaddr) >= 0) {
 
  315       err = mld6_joingroup_netif(
netif, groupaddr);
 
  337 mld6_joingroup_netif(
struct netif *
netif, 
const ip6_addr_t *groupaddr)
 
  339   struct mld_group *group;
 
  342   group = mld6_lookfor_group(
netif, groupaddr);
 
  346     group = mld6_new_group(
netif, groupaddr);
 
  359     mld6_delayed_report(group, MLD6_JOIN_DELAYING_MEMBER_TMR_MS);
 
  377 mld6_leavegroup(
const ip6_addr_t *srcaddr, 
const ip6_addr_t *groupaddr)
 
  386     if (ip6_addr_isany(srcaddr) ||
 
  387         netif_get_ip6_addr_match(
netif, srcaddr) >= 0) {
 
  388       err_t res = mld6_leavegroup_netif(
netif, groupaddr);
 
  410 mld6_leavegroup_netif(
struct netif *
netif, 
const ip6_addr_t *groupaddr)
 
  412   struct mld_group *group;
 
  415   group = mld6_lookfor_group(
netif, groupaddr);
 
  419     if (group->use <= 1) {
 
  421       mld6_remove_group(
netif, group);
 
  424       if (group->last_reporter_flag) {
 
  462     struct mld_group *group = netif_mld6_data(
netif);
 
  464     while (group != 
NULL) {
 
  465       if (group->timer > 0) {
 
  467         if (group->timer == 0) {
 
  469           if (group->group_state == MLD6_GROUP_DELAYING_MEMBER) {
 
  472             group->group_state = MLD6_GROUP_IDLE_MEMBER;
 
  490 mld6_delayed_report(
struct mld_group *group, 
u16_t maxresp)
 
  493   maxresp = maxresp / MLD6_TMR_INTERVAL;
 
  500   maxresp = LWIP_RAND() % maxresp;
 
  507   if ((group->group_state == MLD6_GROUP_IDLE_MEMBER) ||
 
  508      ((group->group_state == MLD6_GROUP_DELAYING_MEMBER) &&
 
  509       ((group->timer == 0) || (maxresp < group->timer)))) {
 
  510     group->timer = maxresp;
 
  511     group->group_state = MLD6_GROUP_DELAYING_MEMBER;
 
  525 mld6_send(
struct netif *
netif, 
struct mld_group *group, 
u8_t type)
 
  529   const ip6_addr_t *src_addr;
 
  546   if (!ip6_addr_isvalid(netif_ip6_addr_state(
netif, 0))) {
 
  549     src_addr = IP6_ADDR_ANY6;
 
  552     src_addr = netif_ip6_addr(
netif, 0);
 
  559   mld_hdr->type = type;
 
  562   mld_hdr->max_resp_delay = 0;
 
  563   mld_hdr->reserved = 0;
 
  564   ip6_addr_set(&(mld_hdr->multicast_address), &(group->group_address));
 
  566 #if CHECKSUM_GEN_ICMP6 
  569       src_addr, &(group->group_address));
 
  578     group->last_reporter_flag = 1;
 
  583   ip6_output_if(p, (ip6_addr_isany(src_addr)) ? 
NULL : src_addr, &(group->group_address),