[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.27.4.3 and 1.41.18.4

version 1.27.4.3, 2007/09/03 14:43:40 version 1.41.18.4, 2009/01/17 13:29:33
Line 110  __KERNEL_RCSID(0, "$NetBSD$");
Line 110  __KERNEL_RCSID(0, "$NetBSD$");
 #include <sys/systm.h>  #include <sys/systm.h>
 #include <sys/mbuf.h>  #include <sys/mbuf.h>
 #include <sys/socket.h>  #include <sys/socket.h>
   #include <sys/socketvar.h>
 #include <sys/protosw.h>  #include <sys/protosw.h>
 #include <sys/syslog.h>  #include <sys/syslog.h>
 #include <sys/sysctl.h>  #include <sys/sysctl.h>
Line 125  __KERNEL_RCSID(0, "$NetBSD$");
Line 126  __KERNEL_RCSID(0, "$NetBSD$");
 #include <netinet6/ip6_var.h>  #include <netinet6/ip6_var.h>
 #include <netinet6/scope6_var.h>  #include <netinet6/scope6_var.h>
 #include <netinet/icmp6.h>  #include <netinet/icmp6.h>
   #include <netinet6/icmp6_private.h>
 #include <netinet6/mld6_var.h>  #include <netinet6/mld6_var.h>
   
 #include <net/net_osdep.h>  #include <net/net_osdep.h>
Line 163  static struct mld_hdr * mld_allocbuf(str
Line 165  static struct mld_hdr * mld_allocbuf(str
 static void mld_sendpkt(struct in6_multi *, int, const struct in6_addr *);  static void mld_sendpkt(struct in6_multi *, int, const struct in6_addr *);
 static void mld_starttimer(struct in6_multi *);  static void mld_starttimer(struct in6_multi *);
 static void mld_stoptimer(struct in6_multi *);  static void mld_stoptimer(struct in6_multi *);
 static void mld_timeo(struct in6_multi *);  
 static u_long mld_timerresid(struct in6_multi *);  static u_long mld_timerresid(struct in6_multi *);
   
 void  void
 mld_init()  mld_init(void)
 {  {
         static u_int8_t hbh_buf[8];          static u_int8_t hbh_buf[8];
         struct ip6_hbh *hbh = (struct ip6_hbh *)hbh_buf;          struct ip6_hbh *hbh = (struct ip6_hbh *)hbh_buf;
Line 203  mld_starttimer(struct in6_multi *in6m)
Line 204  mld_starttimer(struct in6_multi *in6m)
         }          }
   
         /* start or restart the timer */          /* start or restart the timer */
         callout_reset(in6m->in6m_timer_ch, in6m->in6m_timer,          callout_schedule(&in6m->in6m_timer_ch, in6m->in6m_timer);
             (void (*) __P((void *)))mld_timeo, in6m);  
 }  }
   
 static void  static void
Line 213  mld_stoptimer(struct in6_multi *in6m)
Line 213  mld_stoptimer(struct in6_multi *in6m)
         if (in6m->in6m_timer == IN6M_TIMER_UNDEF)          if (in6m->in6m_timer == IN6M_TIMER_UNDEF)
                 return;                  return;
   
         callout_stop(in6m->in6m_timer_ch);          callout_stop(&in6m->in6m_timer_ch);
   
         in6m->in6m_timer = IN6M_TIMER_UNDEF;          in6m->in6m_timer = IN6M_TIMER_UNDEF;
 }  }
   
 static void  static void
 mld_timeo(struct in6_multi *in6m)  mld_timeo(void *arg)
 {  {
         int s = splsoftnet();          struct in6_multi *in6m = arg;
   
         in6m->in6m_timer = IN6M_TIMER_UNDEF;          mutex_enter(softnet_lock);
           KERNEL_LOCK(1, NULL);
   
         callout_stop(in6m->in6m_timer_ch);          in6m->in6m_timer = IN6M_TIMER_UNDEF;
   
         switch (in6m->in6m_state) {          switch (in6m->in6m_state) {
         case MLD_REPORTPENDING:          case MLD_REPORTPENDING:
Line 236  mld_timeo(struct in6_multi *in6m)
Line 237  mld_timeo(struct in6_multi *in6m)
                 break;                  break;
         }          }
   
         splx(s);          KERNEL_UNLOCK_ONE(NULL);
           mutex_exit(softnet_lock);
 }  }
   
 static u_long  static u_long
Line 260  mld_timerresid(struct in6_multi *in6m)
Line 262  mld_timerresid(struct in6_multi *in6m)
         }          }
   
         /* return the remaining time in milliseconds */          /* return the remaining time in milliseconds */
         return (((u_long)(diff.tv_sec * 1000000 + diff.tv_usec)) / 1000);          return diff.tv_sec * 1000 + diff.tv_usec / 1000;
 }  }
   
 static void  static void
Line 328  mld_input(struct mbuf *m, int off)
Line 330  mld_input(struct mbuf *m, int off)
         struct in6_multi *in6m = NULL;          struct in6_multi *in6m = NULL;
         struct in6_addr mld_addr, all_in6;          struct in6_addr mld_addr, all_in6;
         struct in6_ifaddr *ia;          struct in6_ifaddr *ia;
         int timer = 0;          /* timer value in the MLD query header */          u_long timer = 0;       /* timer value in the MLD query header */
   
         IP6_EXTHDR_GET(mldh, struct mld_hdr *, m, off, sizeof(*mldh));          IP6_EXTHDR_GET(mldh, struct mld_hdr *, m, off, sizeof(*mldh));
         if (mldh == NULL) {          if (mldh == NULL) {
                 icmp6stat.icp6s_tooshort++;                  ICMP6_STATINC(ICMP6_STAT_TOOSHORT);
                 return;                  return;
         }          }
   
Line 439  mld_input(struct mbuf *m, int off)
Line 441  mld_input(struct mbuf *m, int off)
                                 mld_sendpkt(in6m, MLD_LISTENER_REPORT, NULL);                                  mld_sendpkt(in6m, MLD_LISTENER_REPORT, NULL);
                                 in6m->in6m_state = MLD_IREPORTEDLAST;                                  in6m->in6m_state = MLD_IREPORTEDLAST;
                         } else if (in6m->in6m_timer == IN6M_TIMER_UNDEF ||                          } else if (in6m->in6m_timer == IN6M_TIMER_UNDEF ||
                             mld_timerresid(in6m) > (u_long)timer) {                              mld_timerresid(in6m) > timer) {
                                 in6m->in6m_timer = arc4random() %                                  in6m->in6m_timer =
                                     (int)(((long)timer * hz) / 1000);                                     1 + (arc4random() % timer) * hz / 1000;
                                 mld_starttimer(in6m);                                  mld_starttimer(in6m);
                         }                          }
                 }                  }
Line 539  mld_sendpkt(struct in6_multi *in6m, int 
Line 541  mld_sendpkt(struct in6_multi *in6m, int 
         im6o.im6o_multicast_loop = (ip6_mrouter != NULL);          im6o.im6o_multicast_loop = (ip6_mrouter != NULL);
   
         /* increment output statictics */          /* increment output statictics */
         icmp6stat.icp6s_outhist[type]++;          ICMP6_STATINC(ICMP6_STAT_OUTHIST + type);
         icmp6_ifstat_inc(ifp, ifs6_out_msg);          icmp6_ifstat_inc(ifp, ifs6_out_msg);
         switch (type) {          switch (type) {
         case MLD_LISTENER_QUERY:          case MLD_LISTENER_QUERY:
Line 647  in6_addmulti(struct in6_addr *maddr6, st
Line 649  in6_addmulti(struct in6_addr *maddr6, st
                 in6m->in6m_ifp = ifp;                  in6m->in6m_ifp = ifp;
                 in6m->in6m_refcount = 1;                  in6m->in6m_refcount = 1;
                 in6m->in6m_timer = IN6M_TIMER_UNDEF;                  in6m->in6m_timer = IN6M_TIMER_UNDEF;
                 in6m->in6m_timer_ch =  
                     malloc(sizeof(*in6m->in6m_timer_ch), M_IPMADDR, M_NOWAIT);  
                 if (in6m->in6m_timer_ch == NULL) {  
                         free(in6m, M_IPMADDR);  
                         splx(s);  
                         return (NULL);  
                 }  
                 IFP_TO_IA6(ifp, ia);                  IFP_TO_IA6(ifp, ia);
                 if (ia == NULL) {                  if (ia == NULL) {
                         /* leaks in6m_timer_ch */  
                         free(in6m, M_IPMADDR);                          free(in6m, M_IPMADDR);
                         splx(s);                          splx(s);
                         *errorp = EADDRNOTAVAIL; /* appropriate? */                          *errorp = EADDRNOTAVAIL; /* appropriate? */
Line 671  in6_addmulti(struct in6_addr *maddr6, st
Line 665  in6_addmulti(struct in6_addr *maddr6, st
                  * filter appropriately for the new address.                   * filter appropriately for the new address.
                  */                   */
                 sockaddr_in6_init(&ifr.ifr_addr, maddr6, 0, 0, 0);                  sockaddr_in6_init(&ifr.ifr_addr, maddr6, 0, 0, 0);
                 if (ifp->if_ioctl == NULL)                  *errorp = (*ifp->if_ioctl)(ifp, SIOCADDMULTI, &ifr);
                         *errorp = ENXIO; /* XXX: appropriate? */  
                 else  
                         *errorp = (*ifp->if_ioctl)(ifp, SIOCADDMULTI,  
                             (void *)&ifr);  
                 if (*errorp) {                  if (*errorp) {
                         LIST_REMOVE(in6m, in6m_entry);                          LIST_REMOVE(in6m, in6m_entry);
                         /* leaks in6m_timer_ch */  
                         free(in6m, M_IPMADDR);                          free(in6m, M_IPMADDR);
                         IFAFREE(&ia->ia_ifa);                          IFAFREE(&ia->ia_ifa);
                         splx(s);                          splx(s);
                         return (NULL);                          return (NULL);
                 }                  }
   
                 callout_init(in6m->in6m_timer_ch, 0);                  callout_init(&in6m->in6m_timer_ch, CALLOUT_MPSAFE);
                   callout_setfunc(&in6m->in6m_timer_ch, mld_timeo, in6m);
                 in6m->in6m_timer = timer;                  in6m->in6m_timer = timer;
                 if (in6m->in6m_timer > 0) {                  if (in6m->in6m_timer > 0) {
                         in6m->in6m_state = MLD_REPORTPENDING;                          in6m->in6m_state = MLD_REPORTPENDING;
Line 750  in6_delmulti(struct in6_multi *in6m)
Line 740  in6_delmulti(struct in6_multi *in6m)
                  * reception filter.                   * reception filter.
                  */                   */
                 sockaddr_in6_init(&ifr.ifr_addr, &in6m->in6m_addr, 0, 0, 0);                  sockaddr_in6_init(&ifr.ifr_addr, &in6m->in6m_addr, 0, 0, 0);
                 (*in6m->in6m_ifp->if_ioctl)(in6m->in6m_ifp,                  (*in6m->in6m_ifp->if_ioctl)(in6m->in6m_ifp, SIOCDELMULTI, &ifr);
                     SIOCDELMULTI, (void *)&ifr);                  callout_destroy(&in6m->in6m_timer_ch);
                 free(in6m->in6m_timer_ch, M_IPMADDR);  
                 free(in6m, M_IPMADDR);                  free(in6m, M_IPMADDR);
         }          }
         splx(s);          splx(s);

Legend:
Removed from v.1.27.4.3  
changed lines
  Added in v.1.41.18.4

CVSweb <webmaster@jp.NetBSD.org>