[BACK]Return to mld6.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / netinet6

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/netinet6/mld6.c between version 1.26.10.1 and 1.28.2.1

version 1.26.10.1, 2005/03/19 08:36:41 version 1.28.2.1, 2006/02/01 14:52:42
Line 119  __KERNEL_RCSID(0, "$NetBSD$");
Line 119  __KERNEL_RCSID(0, "$NetBSD$");
 #include <netinet/in_var.h>  #include <netinet/in_var.h>
 #include <netinet/ip6.h>  #include <netinet/ip6.h>
 #include <netinet6/ip6_var.h>  #include <netinet6/ip6_var.h>
   #include <netinet6/scope6_var.h>
 #include <netinet/icmp6.h>  #include <netinet/icmp6.h>
 #include <netinet6/mld6_var.h>  #include <netinet6/mld6_var.h>
   
Line 138  __KERNEL_RCSID(0, "$NetBSD$");
Line 139  __KERNEL_RCSID(0, "$NetBSD$");
   
 static struct ip6_pktopts ip6_opts;  static struct ip6_pktopts ip6_opts;
 static int mld_timers_are_running;  static int mld_timers_are_running;
 /* XXX: These are necessary for KAME's link-local hack */  
 static struct in6_addr mld_all_nodes_linklocal = IN6ADDR_LINKLOCAL_ALLNODES_INIT;  
 static struct in6_addr mld_all_routers_linklocal = IN6ADDR_LINKLOCAL_ALLROUTERS_INIT;  
   
 static void mld6_sendpkt __P((struct in6_multi *, int, const struct in6_addr *));  static void mld6_sendpkt __P((struct in6_multi *, int, const struct in6_addr *));
   
Line 172  void
Line 170  void
 mld6_start_listening(in6m)  mld6_start_listening(in6m)
         struct in6_multi *in6m;          struct in6_multi *in6m;
 {  {
           struct in6_addr all_in6;
   
         /*          /*
          * RFC2710 page 10:           * RFC2710 page 10:
          * The node never sends a Report or Done for the link-scope all-nodes           * The node never sends a Report or Done for the link-scope all-nodes
Line 179  mld6_start_listening(in6m)
Line 179  mld6_start_listening(in6m)
          * MLD messages are never sent for multicast addresses whose scope is 0           * MLD messages are never sent for multicast addresses whose scope is 0
          * (reserved) or 1 (node-local).           * (reserved) or 1 (node-local).
          */           */
         mld_all_nodes_linklocal.s6_addr16[1] =          all_in6 = in6addr_linklocal_allnodes;
             htons(in6m->in6m_ifp->if_index); /* XXX */          if (in6_setscope(&all_in6, in6m->in6m_ifp, NULL)) {
         if (IN6_ARE_ADDR_EQUAL(&in6m->in6m_addr, &mld_all_nodes_linklocal) ||                  /* XXX: this should not happen! */
                   in6m->in6m_timer = 0;
                   in6m->in6m_state = MLD_OTHERLISTENER;
           }
           if (IN6_ARE_ADDR_EQUAL(&in6m->in6m_addr, &all_in6) ||
             IPV6_ADDR_MC_SCOPE(&in6m->in6m_addr) < IPV6_ADDR_SCOPE_LINKLOCAL) {              IPV6_ADDR_MC_SCOPE(&in6m->in6m_addr) < IPV6_ADDR_SCOPE_LINKLOCAL) {
                 in6m->in6m_timer = 0;                  in6m->in6m_timer = 0;
                 in6m->in6m_state = MLD_OTHERLISTENER;                  in6m->in6m_state = MLD_OTHERLISTENER;
Line 199  void
Line 203  void
 mld6_stop_listening(in6m)  mld6_stop_listening(in6m)
         struct in6_multi *in6m;          struct in6_multi *in6m;
 {  {
         mld_all_nodes_linklocal.s6_addr16[1] =          struct in6_addr allnode, allrouter;
             htons(in6m->in6m_ifp->if_index); /* XXX */  
         mld_all_routers_linklocal.s6_addr16[1] =          allnode = in6addr_linklocal_allnodes;
             htons(in6m->in6m_ifp->if_index); /* XXX: necessary when mrouting */          if (in6_setscope(&allnode, in6m->in6m_ifp, NULL)) {
                   /* XXX: this should not happen! */
                   return;
           }
           allrouter = in6addr_linklocal_allrouters;
           if (in6_setscope(&allrouter, in6m->in6m_ifp, NULL)) {
                   /* XXX impossible */
                   return;
           }
   
         if (in6m->in6m_state == MLD_IREPORTEDLAST &&          if (in6m->in6m_state == MLD_IREPORTEDLAST &&
             (!IN6_ARE_ADDR_EQUAL(&in6m->in6m_addr, &mld_all_nodes_linklocal)) &&              (!IN6_ARE_ADDR_EQUAL(&in6m->in6m_addr, &allnode)) &&
             IPV6_ADDR_MC_SCOPE(&in6m->in6m_addr) > IPV6_ADDR_SCOPE_NODELOCAL)              IPV6_ADDR_MC_SCOPE(&in6m->in6m_addr) >
                 mld6_sendpkt(in6m, MLD_LISTENER_DONE,              IPV6_ADDR_SCOPE_INTFACELOCAL) {
                     &mld_all_routers_linklocal);                  mld6_sendpkt(in6m, MLD_LISTENER_DONE, &allrouter);
           }
 }  }
   
 void  void
Line 220  mld6_input(m, off)
Line 233  mld6_input(m, off)
         struct mld_hdr *mldh;          struct mld_hdr *mldh;
         struct ifnet *ifp = m->m_pkthdr.rcvif;          struct ifnet *ifp = m->m_pkthdr.rcvif;
         struct in6_multi *in6m;          struct in6_multi *in6m;
           struct in6_addr mld_addr, all_in6;
         struct in6_ifaddr *ia;          struct in6_ifaddr *ia;
         int timer;              /* timer value in the MLD query header */          int timer;              /* timer value in the MLD query header */
   
Line 249  mld6_input(m, off)
Line 263  mld6_input(m, off)
         }          }
   
         /*          /*
            * make a copy for local work (in6_setscope() may modify the 1st arg)
            */
           mld_addr = mldh->mld_addr;
           if (in6_setscope(&mld_addr, ifp, NULL)) {
                   /* XXX: this should not happen! */
                   m_free(m);
                   return;
           }
   
           /*
          * In the MLD6 specification, there are 3 states and a flag.           * In the MLD6 specification, there are 3 states and a flag.
          *           *
          * In Non-Listener state, we simply don't have a membership record.           * In Non-Listener state, we simply don't have a membership record.
Line 264  mld6_input(m, off)
Line 288  mld6_input(m, off)
                 if (ifp->if_flags & IFF_LOOPBACK)                  if (ifp->if_flags & IFF_LOOPBACK)
                         break;                          break;
   
                 if (!IN6_IS_ADDR_UNSPECIFIED(&mldh->mld_addr) &&                  if (!IN6_IS_ADDR_UNSPECIFIED(&mld_addr) &&
                     !IN6_IS_ADDR_MULTICAST(&mldh->mld_addr))                      !IN6_IS_ADDR_MULTICAST(&mld_addr))
                         break;  /* print error or log stat? */                          break;  /* print error or log stat? */
                 if (IN6_IS_ADDR_MC_LINKLOCAL(&mldh->mld_addr))  
                         mldh->mld_addr.s6_addr16[1] =                  all_in6 = in6addr_linklocal_allnodes;
                             htons(ifp->if_index); /* XXX */                  if (in6_setscope(&all_in6, ifp, NULL)) {
                           /* XXX: this should not happen! */
                           break;
                   }
   
                 /*                  /*
                  * - Start the timers in all of our membership records                   * - Start the timers in all of our membership records
Line 294  mld6_input(m, off)
Line 321  mld6_input(m, off)
                 timer = ntohs(mldh->mld_maxdelay)*PR_FASTHZ/MLD_TIMER_SCALE;                  timer = ntohs(mldh->mld_maxdelay)*PR_FASTHZ/MLD_TIMER_SCALE;
                 if (timer == 0 && mldh->mld_maxdelay)                  if (timer == 0 && mldh->mld_maxdelay)
                         timer = 1;                          timer = 1;
                 mld_all_nodes_linklocal.s6_addr16[1] =  
                         htons(ifp->if_index); /* XXX */  
   
                 for (in6m = ia->ia6_multiaddrs.lh_first;                  for (in6m = ia->ia6_multiaddrs.lh_first;
                      in6m;                       in6m;
                      in6m = in6m->in6m_entry.le_next)                       in6m = in6m->in6m_entry.le_next)
                 {                  {
                         if (IN6_ARE_ADDR_EQUAL(&in6m->in6m_addr,                          if (IN6_ARE_ADDR_EQUAL(&in6m->in6m_addr, &all_in6) ||
                                                 &mld_all_nodes_linklocal) ||  
                             IPV6_ADDR_MC_SCOPE(&in6m->in6m_addr) <                              IPV6_ADDR_MC_SCOPE(&in6m->in6m_addr) <
                             IPV6_ADDR_SCOPE_LINKLOCAL)                              IPV6_ADDR_SCOPE_LINKLOCAL)
                                 continue;                                  continue;
   
                         if (IN6_IS_ADDR_UNSPECIFIED(&mldh->mld_addr) ||                          if (IN6_IS_ADDR_UNSPECIFIED(&mld_addr) ||
                             IN6_ARE_ADDR_EQUAL(&mldh->mld_addr,                              IN6_ARE_ADDR_EQUAL(&mld_addr, &in6m->in6m_addr)) {
                                                 &in6m->in6m_addr))  
                         {  
                                 if (timer == 0) {                                  if (timer == 0) {
                                         /* send a report immediately */                                          /* send a report immediately */
                                         mld6_sendpkt(in6m, MLD_LISTENER_REPORT,                                          mld6_sendpkt(in6m, MLD_LISTENER_REPORT,
Line 326  mld6_input(m, off)
Line 348  mld6_input(m, off)
                                 }                                  }
                         }                          }
                 }                  }
   
                 if (IN6_IS_ADDR_MC_LINKLOCAL(&mldh->mld_addr))  
                         mldh->mld_addr.s6_addr16[1] = 0; /* XXX */  
                 break;                  break;
   
         case MLD_LISTENER_REPORT:          case MLD_LISTENER_REPORT:
                 /*                  /*
                  * For fast leave to work, we have to know that we are the                   * For fast leave to work, we have to know that we are the
Line 346  mld6_input(m, off)
Line 366  mld6_input(m, off)
                 if (!IN6_IS_ADDR_MULTICAST(&mldh->mld_addr))                  if (!IN6_IS_ADDR_MULTICAST(&mldh->mld_addr))
                         break;                          break;
   
                 if (IN6_IS_ADDR_MC_LINKLOCAL(&mldh->mld_addr))  
                         mldh->mld_addr.s6_addr16[1] =  
                                 htons(ifp->if_index); /* XXX */  
                 /*                  /*
                  * If we belong to the group being reported, stop                   * If we belong to the group being reported, stop
                  * our timer for that group.                   * our timer for that group.
                  */                   */
                 IN6_LOOKUP_MULTI(mldh->mld_addr, ifp, in6m);                  IN6_LOOKUP_MULTI(mld_addr, ifp, in6m);
                 if (in6m) {                  if (in6m) {
                         in6m->in6m_timer = 0; /* transit to idle state */                          in6m->in6m_timer = 0; /* transit to idle state */
                         in6m->in6m_state = MLD_OTHERLISTENER; /* clear flag */                          in6m->in6m_state = MLD_OTHERLISTENER; /* clear flag */
                 }                  }
   
                 if (IN6_IS_ADDR_MC_LINKLOCAL(&mldh->mld_addr))  
                         mldh->mld_addr.s6_addr16[1] = 0; /* XXX */  
                 break;                  break;
         default:                /* this is impossible */          default:                /* this is impossible */
 #if 0  #if 0
Line 474  mld6_sendpkt(in6m, type, dst)
Line 488  mld6_sendpkt(in6m, type, dst)
         mldh->mld_maxdelay = 0;          mldh->mld_maxdelay = 0;
         mldh->mld_reserved = 0;          mldh->mld_reserved = 0;
         mldh->mld_addr = in6m->in6m_addr;          mldh->mld_addr = in6m->in6m_addr;
         if (IN6_IS_ADDR_MC_LINKLOCAL(&mldh->mld_addr))          in6_clearscope(&mldh->mld_addr); /* XXX */
                 mldh->mld_addr.s6_addr16[1] = 0; /* XXX */  
         mldh->mld_cksum = in6_cksum(mh, IPPROTO_ICMPV6, sizeof(struct ip6_hdr),          mldh->mld_cksum = in6_cksum(mh, IPPROTO_ICMPV6, sizeof(struct ip6_hdr),
             sizeof(struct mld_hdr));              sizeof(struct mld_hdr));
   

Legend:
Removed from v.1.26.10.1  
changed lines
  Added in v.1.28.2.1

CVSweb <webmaster@jp.NetBSD.org>