[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.73 and 1.74

version 1.73, 2016/07/20 07:37:51 version 1.74, 2016/08/01 03:15:31
Line 402  mld_input(struct mbuf *m, int off)
Line 402  mld_input(struct mbuf *m, int off)
          * if we sent the last report.           * if we sent the last report.
          */           */
         switch (mldh->mld_type) {          switch (mldh->mld_type) {
         case MLD_LISTENER_QUERY:          case MLD_LISTENER_QUERY: {
                   struct psref psref;
   
                 if (ifp->if_flags & IFF_LOOPBACK)                  if (ifp->if_flags & IFF_LOOPBACK)
                         break;                          break;
   
Line 428  mld_input(struct mbuf *m, int off)
Line 430  mld_input(struct mbuf *m, int off)
                  */                   */
                 timer = ntohs(mldh->mld_maxdelay);                  timer = ntohs(mldh->mld_maxdelay);
   
                 ia = in6_get_ia_from_ifp(ifp);                  ia = in6_get_ia_from_ifp_psref(ifp, &psref);
                 if (ia == NULL)                  if (ia == NULL)
                         break;                          break;
   
                   /* The following operations may sleep */
                   m_put_rcvif(ifp, &s);
                   ifp = NULL;
   
                 LIST_FOREACH(in6m, &ia->ia6_multiaddrs, in6m_entry) {                  LIST_FOREACH(in6m, &ia->ia6_multiaddrs, in6m_entry) {
                         if (IN6_ARE_ADDR_EQUAL(&in6m->in6m_addr, &all_in6) ||                          if (IN6_ARE_ADDR_EQUAL(&in6m->in6m_addr, &all_in6) ||
                             IPV6_ADDR_MC_SCOPE(&in6m->in6m_addr) <                              IPV6_ADDR_MC_SCOPE(&in6m->in6m_addr) <
Line 457  mld_input(struct mbuf *m, int off)
Line 463  mld_input(struct mbuf *m, int off)
                                 mld_starttimer(in6m);                                  mld_starttimer(in6m);
                         }                          }
                 }                  }
                   ia6_release(ia, &psref);
                 break;                  break;
               }
   
         case MLD_LISTENER_REPORT:          case MLD_LISTENER_REPORT:
                 /*                  /*
Line 514  mld_sendpkt(struct in6_multi *in6m, int 
Line 522  mld_sendpkt(struct in6_multi *in6m, int 
         struct in6_ifaddr *ia = NULL;          struct in6_ifaddr *ia = NULL;
         struct ifnet *ifp = in6m->in6m_ifp;          struct ifnet *ifp = in6m->in6m_ifp;
         int ignflags;          int ignflags;
           struct psref psref;
           int bound;
   
         /*          /*
          * At first, find a link local address on the outgoing interface           * At first, find a link local address on the outgoing interface
Line 522  mld_sendpkt(struct in6_multi *in6m, int 
Line 532  mld_sendpkt(struct in6_multi *in6m, int 
          * the case where we first join a link-local address.           * the case where we first join a link-local address.
          */           */
         ignflags = (IN6_IFF_NOTREADY|IN6_IFF_ANYCAST) & ~IN6_IFF_TENTATIVE;          ignflags = (IN6_IFF_NOTREADY|IN6_IFF_ANYCAST) & ~IN6_IFF_TENTATIVE;
         if ((ia = in6ifa_ifpforlinklocal(ifp, ignflags)) == NULL)          bound = curlwp_bind();
           ia = in6ifa_ifpforlinklocal_psref(ifp, ignflags, &psref);
           if (ia == NULL) {
                   curlwp_bindx(bound);
                 return;                  return;
         if ((ia->ia6_flags & IN6_IFF_TENTATIVE))          }
           if ((ia->ia6_flags & IN6_IFF_TENTATIVE)) {
                   ia6_release(ia, &psref);
                 ia = NULL;                  ia = NULL;
           }
   
         /* Allocate two mbufs to store IPv6 header and MLD header */          /* Allocate two mbufs to store IPv6 header and MLD header */
         mldh = mld_allocbuf(&mh, sizeof(struct mld_hdr), in6m, type);          mldh = mld_allocbuf(&mh, sizeof(struct mld_hdr), in6m, type);
         if (mldh == NULL)          if (mldh == NULL) {
                   ia6_release(ia, &psref);
                   curlwp_bindx(bound);
                 return;                  return;
           }
   
         /* fill src/dst here */          /* fill src/dst here */
         ip6 = mtod(mh, struct ip6_hdr *);          ip6 = mtod(mh, struct ip6_hdr *);
         ip6->ip6_src = ia ? ia->ia_addr.sin6_addr : in6addr_any;          ip6->ip6_src = ia ? ia->ia_addr.sin6_addr : in6addr_any;
         ip6->ip6_dst = dst ? *dst : in6m->in6m_addr;          ip6->ip6_dst = dst ? *dst : in6m->in6m_addr;
           ia6_release(ia, &psref);
           curlwp_bindx(bound);
   
         mldh->mld_addr = in6m->in6m_addr;          mldh->mld_addr = in6m->in6m_addr;
         in6_clearscope(&mldh->mld_addr); /* XXX */          in6_clearscope(&mldh->mld_addr); /* XXX */
Line 645  in6_addmulti(struct in6_addr *maddr6, st
Line 666  in6_addmulti(struct in6_addr *maddr6, st
                  */                   */
                 in6m->in6m_refcount++;                  in6m->in6m_refcount++;
         } else {          } else {
                   int _s;
                 /*                  /*
                  * New address; allocate a new multicast record                   * New address; allocate a new multicast record
                  * and link it into the interface's multicast list.                   * and link it into the interface's multicast list.
Line 664  in6_addmulti(struct in6_addr *maddr6, st
Line 686  in6_addmulti(struct in6_addr *maddr6, st
                 callout_init(&in6m->in6m_timer_ch, CALLOUT_MPSAFE);                  callout_init(&in6m->in6m_timer_ch, CALLOUT_MPSAFE);
                 callout_setfunc(&in6m->in6m_timer_ch, mld_timeo, in6m);                  callout_setfunc(&in6m->in6m_timer_ch, mld_timeo, in6m);
   
                   _s = pserialize_read_enter();
                 ia = in6_get_ia_from_ifp(ifp);                  ia = in6_get_ia_from_ifp(ifp);
                 if (ia == NULL) {                  if (ia == NULL) {
                           pserialize_read_exit(_s);
                         callout_destroy(&in6m->in6m_timer_ch);                          callout_destroy(&in6m->in6m_timer_ch);
                         free(in6m, M_IPMADDR);                          free(in6m, M_IPMADDR);
                         splx(s);                          splx(s);
Line 674  in6_addmulti(struct in6_addr *maddr6, st
Line 698  in6_addmulti(struct in6_addr *maddr6, st
                 }                  }
                 in6m->in6m_ia = ia;                  in6m->in6m_ia = ia;
                 ifaref(&ia->ia_ifa); /* gain a reference */                  ifaref(&ia->ia_ifa); /* gain a reference */
                   /* FIXME NOMPSAFE: need to lock */
                 LIST_INSERT_HEAD(&ia->ia6_multiaddrs, in6m, in6m_entry);                  LIST_INSERT_HEAD(&ia->ia6_multiaddrs, in6m, in6m_entry);
                   pserialize_read_exit(_s);
   
                 /*                  /*
                  * Ask the network driver to update its multicast reception                   * Ask the network driver to update its multicast reception
Line 816  in6_savemkludge(struct in6_ifaddr *oia)
Line 842  in6_savemkludge(struct in6_ifaddr *oia)
 {  {
         struct in6_ifaddr *ia;          struct in6_ifaddr *ia;
         struct in6_multi *in6m;          struct in6_multi *in6m;
           int s;
   
           s = pserialize_read_enter();
         ia = in6_get_ia_from_ifp(oia->ia_ifp);          ia = in6_get_ia_from_ifp(oia->ia_ifp);
         if (ia) {       /* there is another address */          if (ia) {       /* there is another address */
                 KASSERT(ia != oia);                  KASSERT(ia != oia);
Line 825  in6_savemkludge(struct in6_ifaddr *oia)
Line 853  in6_savemkludge(struct in6_ifaddr *oia)
                         ifaref(&ia->ia_ifa);                          ifaref(&ia->ia_ifa);
                         ifafree(&in6m->in6m_ia->ia_ifa);                          ifafree(&in6m->in6m_ia->ia_ifa);
                         in6m->in6m_ia = ia;                          in6m->in6m_ia = ia;
                           /* FIXME NOMPSAFE: need to lock */
                         LIST_INSERT_HEAD(&ia->ia6_multiaddrs, in6m, in6m_entry);                          LIST_INSERT_HEAD(&ia->ia6_multiaddrs, in6m, in6m_entry);
                 }                  }
         } else {        /* last address on this if deleted, save */          } else {        /* last address on this if deleted, save */
Line 844  in6_savemkludge(struct in6_ifaddr *oia)
Line 873  in6_savemkludge(struct in6_ifaddr *oia)
                         LIST_INSERT_HEAD(&mk->mk_head, in6m, in6m_entry);                          LIST_INSERT_HEAD(&mk->mk_head, in6m, in6m_entry);
                 }                  }
         }          }
           pserialize_read_exit(s);
 }  }
   
 /*  /*
Line 986  in6_multicast_sysctl(SYSCTLFN_ARGS)
Line 1016  in6_multicast_sysctl(SYSCTLFN_ARGS)
         uint32_t tmp;          uint32_t tmp;
         int error;          int error;
         size_t written;          size_t written;
         struct psref psref;          struct psref psref, psref_ia;
         int bound;          int bound, s;
   
         if (namelen != 1)          if (namelen != 1)
                 return EINVAL;                  return EINVAL;
Line 1001  in6_multicast_sysctl(SYSCTLFN_ARGS)
Line 1031  in6_multicast_sysctl(SYSCTLFN_ARGS)
   
         if (oldp == NULL) {          if (oldp == NULL) {
                 *oldlenp = 0;                  *oldlenp = 0;
                   s = pserialize_read_enter();
                 IFADDR_READER_FOREACH(ifa, ifp) {                  IFADDR_READER_FOREACH(ifa, ifp) {
                         if (ifa->ifa_addr->sa_family != AF_INET6)                          if (ifa->ifa_addr->sa_family != AF_INET6)
                                 continue;                                  continue;
Line 1010  in6_multicast_sysctl(SYSCTLFN_ARGS)
Line 1041  in6_multicast_sysctl(SYSCTLFN_ARGS)
                                     sizeof(uint32_t);                                      sizeof(uint32_t);
                         }                          }
                 }                  }
                   pserialize_read_exit(s);
                 if_put(ifp, &psref);                  if_put(ifp, &psref);
                 curlwp_bindx(bound);                  curlwp_bindx(bound);
                 return 0;                  return 0;
Line 1017  in6_multicast_sysctl(SYSCTLFN_ARGS)
Line 1049  in6_multicast_sysctl(SYSCTLFN_ARGS)
   
         error = 0;          error = 0;
         written = 0;          written = 0;
           s = pserialize_read_enter();
         IFADDR_READER_FOREACH(ifa, ifp) {          IFADDR_READER_FOREACH(ifa, ifp) {
                 if (ifa->ifa_addr->sa_family != AF_INET6)                  if (ifa->ifa_addr->sa_family != AF_INET6)
                         continue;                          continue;
   
                   ifa_acquire(ifa, &psref_ia);
                   pserialize_read_exit(s);
   
                 ifa6 = (struct in6_ifaddr *)ifa;                  ifa6 = (struct in6_ifaddr *)ifa;
                 LIST_FOREACH(in6m, &ifa6->ia6_multiaddrs, in6m_entry) {                  LIST_FOREACH(in6m, &ifa6->ia6_multiaddrs, in6m_entry) {
                         if (written + 2 * sizeof(struct in6_addr) +                          if (written + 2 * sizeof(struct in6_addr) +
Line 1044  in6_multicast_sysctl(SYSCTLFN_ARGS)
Line 1081  in6_multicast_sysctl(SYSCTLFN_ARGS)
                         oldp = (char *)oldp + sizeof(tmp);                          oldp = (char *)oldp + sizeof(tmp);
                         written += sizeof(tmp);                          written += sizeof(tmp);
                 }                  }
   
                   s = pserialize_read_enter();
                   ifa_release(ifa, &psref_ia);
         }          }
           pserialize_read_exit(s);
 done:  done:
           ifa_release(ifa, &psref_ia);
         if_put(ifp, &psref);          if_put(ifp, &psref);
         curlwp_bindx(bound);          curlwp_bindx(bound);
         *oldlenp = written;          *oldlenp = written;

Legend:
Removed from v.1.73  
changed lines
  Added in v.1.74

CVSweb <webmaster@jp.NetBSD.org>