[BACK]Return to ip6_input.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/ip6_input.c between version 1.149.4.8 and 1.163

version 1.149.4.8, 2016/10/05 20:56:09 version 1.163, 2016/07/06 10:49:49
Line 87  __KERNEL_RCSID(0, "$NetBSD$");
Line 87  __KERNEL_RCSID(0, "$NetBSD$");
 #include <sys/proc.h>  #include <sys/proc.h>
 #include <sys/sysctl.h>  #include <sys/sysctl.h>
 #include <sys/cprng.h>  #include <sys/cprng.h>
 #include <sys/percpu.h>  
   
 #include <net/if.h>  #include <net/if.h>
 #include <net/if_types.h>  #include <net/if_types.h>
Line 144  pfil_head_t *inet6_pfil_hook;
Line 143  pfil_head_t *inet6_pfil_hook;
   
 percpu_t *ip6stat_percpu;  percpu_t *ip6stat_percpu;
   
 percpu_t *ip6_forward_rt_percpu __cacheline_aligned;  
   
 static void ip6_init2(void);  static void ip6_init2(void);
 static void ip6intr(void *);  static void ip6intr(void *);
 static struct m_tag *ip6_setdstifaddr(struct mbuf *, const struct in6_ifaddr *);  static struct m_tag *ip6_setdstifaddr(struct mbuf *, const struct in6_ifaddr *);
Line 197  ip6_init(void)
Line 194  ip6_init(void)
         KASSERT(inet6_pfil_hook != NULL);          KASSERT(inet6_pfil_hook != NULL);
   
         ip6stat_percpu = percpu_alloc(sizeof(uint64_t) * IP6_NSTATS);          ip6stat_percpu = percpu_alloc(sizeof(uint64_t) * IP6_NSTATS);
   
         ip6_forward_rt_percpu = percpu_alloc(sizeof(struct route));  
         if (ip6_forward_rt_percpu == NULL)  
                 panic("failed to alllocate ip6_forward_rt_percpu");  
 }  }
   
 static void  static void
Line 246  ip6intr(void *arg __unused)
Line 239  ip6intr(void *arg __unused)
         mutex_exit(softnet_lock);          mutex_exit(softnet_lock);
 }  }
   
   extern struct   route ip6_forward_rt;
   
 void  void
 ip6_input(struct mbuf *m, struct ifnet *rcvif)  ip6_input(struct mbuf *m, struct ifnet *rcvif)
 {  {
Line 261  ip6_input(struct mbuf *m, struct ifnet *
Line 256  ip6_input(struct mbuf *m, struct ifnet *
                 struct sockaddr         dst;                  struct sockaddr         dst;
                 struct sockaddr_in6     dst6;                  struct sockaddr_in6     dst6;
         } u;          } u;
         struct route *ro;  
   
         /*          /*
          * make sure we don't have onion peering information into m_tag.           * make sure we don't have onion peering information into m_tag.
Line 420  ip6_input(struct mbuf *m, struct ifnet *
Line 414  ip6_input(struct mbuf *m, struct ifnet *
          * to the usage conflict.           * to the usage conflict.
          * in6_setscope() then also checks and rejects the cases where src or           * in6_setscope() then also checks and rejects the cases where src or
          * dst are the loopback address and the receiving interface           * dst are the loopback address and the receiving interface
          * is not loopback.           * is not loopback.
          */           */
         if (__predict_false(          if (__predict_false(
             m_makewritable(&m, 0, sizeof(struct ip6_hdr), M_DONTWAIT)))              m_makewritable(&m, 0, sizeof(struct ip6_hdr), M_DONTWAIT)))
Line 467  ip6_input(struct mbuf *m, struct ifnet *
Line 461  ip6_input(struct mbuf *m, struct ifnet *
         /*          /*
          *  Unicast check           *  Unicast check
          */           */
         ro = percpu_getref(ip6_forward_rt_percpu);          rt = rtcache_lookup2(&ip6_forward_rt, &u.dst, 1, &hit);
         rt = rtcache_lookup2(ro, &u.dst, 1, &hit);  
         percpu_putref(ip6_forward_rt_percpu);  
         if (hit)          if (hit)
                 IP6_STATINC(IP6_STAT_FORWARD_CACHEHIT);                  IP6_STATINC(IP6_STAT_FORWARD_CACHEHIT);
         else          else
Line 504  ip6_input(struct mbuf *m, struct ifnet *
Line 496  ip6_input(struct mbuf *m, struct ifnet *
                  * packets to a tentative, duplicated, or somehow invalid                   * packets to a tentative, duplicated, or somehow invalid
                  * address must not be accepted.                   * address must not be accepted.
                  */                   */
                 if (!(ia6->ia6_flags & (IN6_IFF_NOTREADY | IN6_IFF_DETACHED))) {                  if (!(ia6->ia6_flags & IN6_IFF_NOTREADY)) {
                         /* this address is ready */                          /* this address is ready */
                         ours = 1;                          ours = 1;
                         deliverifp = ia6->ia_ifp;       /* correct? */                          deliverifp = ia6->ia_ifp;       /* correct? */
Line 542  ip6_input(struct mbuf *m, struct ifnet *
Line 534  ip6_input(struct mbuf *m, struct ifnet *
          * working right.           * working right.
          */           */
         struct ifaddr *ifa;          struct ifaddr *ifa;
         IFADDR_READER_FOREACH(ifa, rcvif) {          IFADDR_FOREACH(ifa, rcvif) {
                 if (ifa->ifa_addr->sa_family != AF_INET6)                  if (ifa->ifa_addr->sa_family != AF_INET6)
                         continue;                          continue;
                 if (IN6_ARE_ADDR_EQUAL(IFA_IN6(ifa), &ip6->ip6_dst)) {                  if (IN6_ARE_ADDR_EQUAL(IFA_IN6(ifa), &ip6->ip6_dst)) {
Line 573  ip6_input(struct mbuf *m, struct ifnet *
Line 565  ip6_input(struct mbuf *m, struct ifnet *
          */           */
         if (deliverifp && ip6_getdstifaddr(m) == NULL) {          if (deliverifp && ip6_getdstifaddr(m) == NULL) {
                 struct in6_ifaddr *ia6;                  struct in6_ifaddr *ia6;
                 int s = pserialize_read_enter();  
   
                 ia6 = in6_ifawithifp(deliverifp, &ip6->ip6_dst);                  ia6 = in6_ifawithifp(deliverifp, &ip6->ip6_dst);
                 /* Depends on ip6_setdstifaddr never sleep */  
                 if (ia6 != NULL && ip6_setdstifaddr(m, ia6) == NULL) {                  if (ia6 != NULL && ip6_setdstifaddr(m, ia6) == NULL) {
                         /*                          /*
                          * XXX maybe we should drop the packet here,                           * XXX maybe we should drop the packet here,
Line 584  ip6_input(struct mbuf *m, struct ifnet *
Line 574  ip6_input(struct mbuf *m, struct ifnet *
                          * to the upper layers.                           * to the upper layers.
                          */                           */
                 }                  }
                 pserialize_read_exit(s);  
         }          }
   
         /*          /*
Line 712  ip6_input(struct mbuf *m, struct ifnet *
Line 701  ip6_input(struct mbuf *m, struct ifnet *
 #ifdef IFA_STATS  #ifdef IFA_STATS
         if (deliverifp != NULL) {          if (deliverifp != NULL) {
                 struct in6_ifaddr *ia6;                  struct in6_ifaddr *ia6;
                 int s = pserialize_read_enter();  
                 ia6 = in6_ifawithifp(deliverifp, &ip6->ip6_dst);                  ia6 = in6_ifawithifp(deliverifp, &ip6->ip6_dst);
                 if (ia6)                  if (ia6)
                         ia6->ia_ifa.ifa_data.ifad_inbytes += m->m_pkthdr.len;                          ia6->ia_ifa.ifa_data.ifad_inbytes += m->m_pkthdr.len;
                 pserialize_read_exit(s);  
         }          }
 #endif  #endif
         IP6_STATINC(IP6_STAT_DELIVERED);          IP6_STATINC(IP6_STAT_DELIVERED);
Line 815  ip6_getdstifaddr(struct mbuf *m)
Line 802  ip6_getdstifaddr(struct mbuf *m)
  * rtalertp - XXX: should be stored more smart way   * rtalertp - XXX: should be stored more smart way
  */   */
 int  int
 ip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalertp,  ip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalertp,
         struct mbuf **mp, int *offp)          struct mbuf **mp, int *offp)
 {  {
         struct mbuf *m = *mp;          struct mbuf *m = *mp;
Line 860  ip6_hopopts_input(u_int32_t *plenp, u_in
Line 847  ip6_hopopts_input(u_int32_t *plenp, u_in
  * opthead + hbhlen is located in continuous memory region.   * opthead + hbhlen is located in continuous memory region.
  */   */
 static int  static int
 ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen,  ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen,
         u_int32_t *rtalertp, u_int32_t *plenp)          u_int32_t *rtalertp, u_int32_t *plenp)
 {  {
         struct ip6_hdr *ip6;          struct ip6_hdr *ip6;
Line 1035  ip6_unknown_opt(u_int8_t *optp, struct m
Line 1022  ip6_unknown_opt(u_int8_t *optp, struct m
  * you are using IP6_EXTHDR_CHECK() not m_pulldown())   * you are using IP6_EXTHDR_CHECK() not m_pulldown())
  */   */
 void  void
 ip6_savecontrol(struct in6pcb *in6p, struct mbuf **mp,  ip6_savecontrol(struct in6pcb *in6p, struct mbuf **mp,
         struct ip6_hdr *ip6, struct mbuf *m)          struct ip6_hdr *ip6, struct mbuf *m)
 {  {
 #ifdef RFC2292  #ifdef RFC2292
Line 1538  ip6_delaux(struct mbuf *m)
Line 1525  ip6_delaux(struct mbuf *m)
                 m_tag_delete(m, mtag);                  m_tag_delete(m, mtag);
 }  }
   
   #ifdef GATEWAY
   /*
    * sysctl helper routine for net.inet.ip6.maxflows. Since
    * we could reduce this value, call ip6flow_reap();
    */
   static int
   sysctl_net_inet6_ip6_maxflows(SYSCTLFN_ARGS)
   {
           int error;
   
           error = sysctl_lookup(SYSCTLFN_CALL(rnode));
           if (error || newp == NULL)
                   return (error);
   
           mutex_enter(softnet_lock);
           KERNEL_LOCK(1, NULL);
   
           ip6flow_reap(0);
   
           KERNEL_UNLOCK_ONE(NULL);
           mutex_exit(softnet_lock);
   
           return (0);
   }
   
   static int
   sysctl_net_inet6_ip6_hashsize(SYSCTLFN_ARGS)
   {
           int error, tmp;
           struct sysctlnode node;
   
           node = *rnode;
           tmp = ip6_hashsize;
           node.sysctl_data = &tmp;
           error = sysctl_lookup(SYSCTLFN_CALL(&node));
           if (error || newp == NULL)
                   return (error);
   
           if ((tmp & (tmp - 1)) == 0 && tmp != 0) {
                   /*
                    * Can only fail due to malloc()
                    */
                   mutex_enter(softnet_lock);
                   KERNEL_LOCK(1, NULL);
   
                   error = ip6flow_invalidate_all(tmp);
   
                   KERNEL_UNLOCK_ONE(NULL);
                   mutex_exit(softnet_lock);
           } else {
                   /*
                    * EINVAL if not a power of 2
                    */
                   error = EINVAL;
           }
   
           return error;
   }
   #endif /* GATEWAY */
   
 /*  /*
  * System control for IP6   * System control for IP6
  */   */
Line 1856  sysctl_net_inet6_ip6_setup(struct sysctl
Line 1903  sysctl_net_inet6_ip6_setup(struct sysctl
                        NULL, 0, &ip6_mcast_pmtu, 0,                         NULL, 0, &ip6_mcast_pmtu, 0,
                        CTL_NET, PF_INET6, IPPROTO_IPV6,                         CTL_NET, PF_INET6, IPPROTO_IPV6,
                        CTL_CREATE, CTL_EOL);                         CTL_CREATE, CTL_EOL);
   #ifdef GATEWAY
           sysctl_createv(clog, 0, NULL, NULL,
                           CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
                           CTLTYPE_INT, "maxflows",
                           SYSCTL_DESCR("Number of flows for fast forwarding (IPv6)"),
                           sysctl_net_inet6_ip6_maxflows, 0, &ip6_maxflows, 0,
                           CTL_NET, PF_INET6, IPPROTO_IPV6,
                           CTL_CREATE, CTL_EOL);
           sysctl_createv(clog, 0, NULL, NULL,
                           CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
                           CTLTYPE_INT, "hashsize",
                           SYSCTL_DESCR("Size of hash table for fast forwarding (IPv6)"),
                           sysctl_net_inet6_ip6_hashsize, 0, &ip6_hashsize, 0,
                           CTL_NET, PF_INET6, IPPROTO_IPV6,
                           CTL_CREATE, CTL_EOL);
   #endif
         /* anonportalgo RFC6056 subtree */          /* anonportalgo RFC6056 subtree */
         const struct sysctlnode *portalgo_node;          const struct sysctlnode *portalgo_node;
         sysctl_createv(clog, 0, NULL, &portalgo_node,          sysctl_createv(clog, 0, NULL, &portalgo_node,

Legend:
Removed from v.1.149.4.8  
changed lines
  Added in v.1.163

CVSweb <webmaster@jp.NetBSD.org>