[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 and 1.149.4.7

version 1.149, 2014/06/16 00:33:39 version 1.149.4.7, 2016/07/09 20:25:22
Line 64 
Line 64 
 #include <sys/cdefs.h>  #include <sys/cdefs.h>
 __KERNEL_RCSID(0, "$NetBSD$");  __KERNEL_RCSID(0, "$NetBSD$");
   
   #ifdef _KERNEL_OPT
 #include "opt_gateway.h"  #include "opt_gateway.h"
 #include "opt_inet.h"  #include "opt_inet.h"
 #include "opt_inet6.h"  #include "opt_inet6.h"
 #include "opt_ipsec.h"  #include "opt_ipsec.h"
 #include "opt_compat_netbsd.h"  #include "opt_compat_netbsd.h"
   #endif
   
 #include <sys/param.h>  #include <sys/param.h>
 #include <sys/systm.h>  #include <sys/systm.h>
Line 125  __KERNEL_RCSID(0, "$NetBSD$");
Line 127  __KERNEL_RCSID(0, "$NetBSD$");
 #include <netinet6/ip6protosw.h>  #include <netinet6/ip6protosw.h>
   
 #include "faith.h"  #include "faith.h"
 #include "gif.h"  
   
 #if NGIF > 0  
 #include <netinet6/in6_gif.h>  
 #endif  
   
 #include <net/net_osdep.h>  #include <net/net_osdep.h>
   
 extern struct domain inet6domain;  extern struct domain inet6domain;
   
 u_char ip6_protox[IPPROTO_MAX];  u_char ip6_protox[IPPROTO_MAX];
 struct in6_ifaddr *in6_ifaddr;  
 pktqueue_t *ip6_pktq __read_mostly;  pktqueue_t *ip6_pktq __read_mostly;
   
 extern callout_t in6_tmpaddrtimer_ch;  
   
 int ip6_forward_srcrt;                  /* XXX */  int ip6_forward_srcrt;                  /* XXX */
 int ip6_sourcecheck;                    /* XXX */  int ip6_sourcecheck;                    /* XXX */
 int ip6_sourcecheck_interval;           /* XXX */  int ip6_sourcecheck_interval;           /* XXX */
Line 149  pfil_head_t *inet6_pfil_hook;
Line 143  pfil_head_t *inet6_pfil_hook;
   
 percpu_t *ip6stat_percpu;  percpu_t *ip6stat_percpu;
   
 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 168  ip6_init(void)
Line 162  ip6_init(void)
         const struct ip6protosw *pr;          const struct ip6protosw *pr;
         int i;          int i;
   
           in6_init();
   
         sysctl_net_inet6_ip6_setup(NULL);          sysctl_net_inet6_ip6_setup(NULL);
         pr = (const struct ip6protosw *)pffindproto(PF_INET6, IPPROTO_RAW, SOCK_RAW);          pr = (const struct ip6protosw *)pffindproto(PF_INET6, IPPROTO_RAW, SOCK_RAW);
         if (pr == 0)          if (pr == 0)
Line 189  ip6_init(void)
Line 185  ip6_init(void)
         frag6_init();          frag6_init();
         ip6_desync_factor = cprng_fast32() % MAX_TEMP_DESYNC_FACTOR;          ip6_desync_factor = cprng_fast32() % MAX_TEMP_DESYNC_FACTOR;
   
         ip6_init2(NULL);          ip6_init2();
 #ifdef GATEWAY  #ifdef GATEWAY
         ip6flow_init(ip6_hashsize);          ip6flow_init(ip6_hashsize);
 #endif  #endif
Line 201  ip6_init(void)
Line 197  ip6_init(void)
 }  }
   
 static void  static void
 ip6_init2(void *dummy)  ip6_init2(void)
 {  {
   
         /* nd6_timer_init */  
         callout_init(&nd6_timer_ch, CALLOUT_MPSAFE);  
         callout_reset(&nd6_timer_ch, hz, nd6_timer, NULL);  
   
         /* timer for regeneranation of temporary addresses randomize ID */          /* timer for regeneranation of temporary addresses randomize ID */
         callout_init(&in6_tmpaddrtimer_ch, CALLOUT_MPSAFE);          callout_init(&in6_tmpaddrtimer_ch, CALLOUT_MPSAFE);
         callout_reset(&in6_tmpaddrtimer_ch,          callout_reset(&in6_tmpaddrtimer_ch,
Line 226  ip6intr(void *arg __unused)
Line 218  ip6intr(void *arg __unused)
   
         mutex_enter(softnet_lock);          mutex_enter(softnet_lock);
         while ((m = pktq_dequeue(ip6_pktq)) != NULL) {          while ((m = pktq_dequeue(ip6_pktq)) != NULL) {
                 const ifnet_t *ifp = m->m_pkthdr.rcvif;                  struct psref psref;
                   struct ifnet *rcvif = m_get_rcvif_psref(m, &psref);
   
                   if (rcvif == NULL) {
                           m_freem(m);
                           continue;
                   }
                 /*                  /*
                  * Drop the packet if IPv6 is disabled on the interface.                   * Drop the packet if IPv6 is disabled on the interface.
                  */                   */
                 if ((ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED)) {                  if ((ND_IFINFO(rcvif)->flags & ND6_IFF_IFDISABLED)) {
                           m_put_rcvif_psref(rcvif, &psref);
                         m_freem(m);                          m_freem(m);
                         continue;                          continue;
                 }                  }
                 ip6_input(m);                  ip6_input(m, rcvif);
                   m_put_rcvif_psref(rcvif, &psref);
         }          }
         mutex_exit(softnet_lock);          mutex_exit(softnet_lock);
 }  }
Line 243  ip6intr(void *arg __unused)
Line 242  ip6intr(void *arg __unused)
 extern struct   route ip6_forward_rt;  extern struct   route ip6_forward_rt;
   
 void  void
 ip6_input(struct mbuf *m)  ip6_input(struct mbuf *m, struct ifnet *rcvif)
 {  {
         struct ip6_hdr *ip6;          struct ip6_hdr *ip6;
         int hit, off = sizeof(struct ip6_hdr), nest;          int hit, off = sizeof(struct ip6_hdr), nest;
Line 274  ip6_input(struct mbuf *m)
Line 273  ip6_input(struct mbuf *m)
         } else {          } else {
 #define M2MMAX  32  #define M2MMAX  32
                 if (m->m_next) {                  if (m->m_next) {
                         if (m->m_flags & M_LOOP) {                          if (m->m_flags & M_LOOP)
                         /*XXX*/ IP6_STATINC(IP6_STAT_M2M + lo0ifp->if_index);                          /*XXX*/ IP6_STATINC(IP6_STAT_M2M + lo0ifp->if_index);
                         } else if (m->m_pkthdr.rcvif->if_index < M2MMAX) {                          else if (rcvif->if_index < M2MMAX)
                                 IP6_STATINC(IP6_STAT_M2M +                                  IP6_STATINC(IP6_STAT_M2M + rcvif->if_index);
                                             m->m_pkthdr.rcvif->if_index);                          else
                         } else  
                                 IP6_STATINC(IP6_STAT_M2M);                                  IP6_STATINC(IP6_STAT_M2M);
                 } else                  } else
                         IP6_STATINC(IP6_STAT_M1);                          IP6_STATINC(IP6_STAT_M1);
 #undef M2MMAX  #undef M2MMAX
         }          }
   
         in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_receive);          in6_ifstat_inc(rcvif, ifs6_in_receive);
         IP6_STATINC(IP6_STAT_TOTAL);          IP6_STATINC(IP6_STAT_TOTAL);
   
         /*          /*
Line 296  ip6_input(struct mbuf *m)
Line 294  ip6_input(struct mbuf *m)
          * IPv6 header is in the first mbuf of the chain.           * IPv6 header is in the first mbuf of the chain.
          */           */
         if (IP6_HDR_ALIGNED_P(mtod(m, void *)) == 0) {          if (IP6_HDR_ALIGNED_P(mtod(m, void *)) == 0) {
                 struct ifnet *inifp = m->m_pkthdr.rcvif;  
                 if ((m = m_copyup(m, sizeof(struct ip6_hdr),                  if ((m = m_copyup(m, sizeof(struct ip6_hdr),
                                   (max_linkhdr + 3) & ~3)) == NULL) {                                    (max_linkhdr + 3) & ~3)) == NULL) {
                         /* XXXJRT new stat, please */                          /* XXXJRT new stat, please */
                         IP6_STATINC(IP6_STAT_TOOSMALL);                          IP6_STATINC(IP6_STAT_TOOSMALL);
                         in6_ifstat_inc(inifp, ifs6_in_hdrerr);                          in6_ifstat_inc(rcvif, ifs6_in_hdrerr);
                         return;                          return;
                 }                  }
         } else if (__predict_false(m->m_len < sizeof(struct ip6_hdr))) {          } else if (__predict_false(m->m_len < sizeof(struct ip6_hdr))) {
                 struct ifnet *inifp = m->m_pkthdr.rcvif;  
                 if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {                  if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) {
                         IP6_STATINC(IP6_STAT_TOOSMALL);                          IP6_STATINC(IP6_STAT_TOOSMALL);
                         in6_ifstat_inc(inifp, ifs6_in_hdrerr);                          in6_ifstat_inc(rcvif, ifs6_in_hdrerr);
                         return;                          return;
                 }                  }
         }          }
Line 317  ip6_input(struct mbuf *m)
Line 313  ip6_input(struct mbuf *m)
   
         if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {          if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
                 IP6_STATINC(IP6_STAT_BADVERS);                  IP6_STATINC(IP6_STAT_BADVERS);
                 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);                  in6_ifstat_inc(rcvif, ifs6_in_hdrerr);
                 goto bad;                  goto bad;
         }          }
   
Line 347  ip6_input(struct mbuf *m)
Line 343  ip6_input(struct mbuf *m)
                 struct in6_addr odst;                  struct in6_addr odst;
   
                 odst = ip6->ip6_dst;                  odst = ip6->ip6_dst;
                 if (pfil_run_hooks(inet6_pfil_hook, &m, m->m_pkthdr.rcvif,                  if (pfil_run_hooks(inet6_pfil_hook, &m, rcvif, PFIL_IN) != 0)
                                    PFIL_IN) != 0)  
                         return;                          return;
                 if (m == NULL)                  if (m == NULL)
                         return;                          return;
Line 374  ip6_input(struct mbuf *m)
Line 369  ip6_input(struct mbuf *m)
                  * XXX: "badscope" is not very suitable for a multicast source.                   * XXX: "badscope" is not very suitable for a multicast source.
                  */                   */
                 IP6_STATINC(IP6_STAT_BADSCOPE);                  IP6_STATINC(IP6_STAT_BADSCOPE);
                 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);                  in6_ifstat_inc(rcvif, ifs6_in_addrerr);
                 goto bad;                  goto bad;
         }          }
         /*          /*
Line 392  ip6_input(struct mbuf *m)
Line 387  ip6_input(struct mbuf *m)
         if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) ||          if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) ||
             IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) {              IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) {
                 IP6_STATINC(IP6_STAT_BADSCOPE);                  IP6_STATINC(IP6_STAT_BADSCOPE);
                 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);                  in6_ifstat_inc(rcvif, ifs6_in_addrerr);
                 goto bad;                  goto bad;
         }          }
 #if 0  #if 0
Line 406  ip6_input(struct mbuf *m)
Line 401  ip6_input(struct mbuf *m)
         if (IN6_IS_ADDR_V4COMPAT(&ip6->ip6_src) ||          if (IN6_IS_ADDR_V4COMPAT(&ip6->ip6_src) ||
             IN6_IS_ADDR_V4COMPAT(&ip6->ip6_dst)) {              IN6_IS_ADDR_V4COMPAT(&ip6->ip6_dst)) {
                 IP6_STATINC(IP6_STAT_BADSCOPE);                  IP6_STATINC(IP6_STAT_BADSCOPE);
                 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);                  in6_ifstat_inc(rcvif, ifs6_in_addrerr);
                 goto bad;                  goto bad;
         }          }
 #endif  #endif
Line 419  ip6_input(struct mbuf *m)
Line 414  ip6_input(struct mbuf *m)
          * 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 429  ip6_input(struct mbuf *m)
Line 424  ip6_input(struct mbuf *m)
                 IP6_STATINC(IP6_STAT_BADSCOPE); /* XXX */                  IP6_STATINC(IP6_STAT_BADSCOPE); /* XXX */
                 goto bad;                  goto bad;
         }          }
         if (in6_setscope(&ip6->ip6_src, m->m_pkthdr.rcvif, NULL) ||          if (in6_setscope(&ip6->ip6_src, rcvif, NULL) ||
             in6_setscope(&ip6->ip6_dst, m->m_pkthdr.rcvif, NULL)) {              in6_setscope(&ip6->ip6_dst, rcvif, NULL)) {
                 IP6_STATINC(IP6_STAT_BADSCOPE);                  IP6_STATINC(IP6_STAT_BADSCOPE);
                 goto bad;                  goto bad;
         }          }
Line 441  ip6_input(struct mbuf *m)
Line 436  ip6_input(struct mbuf *m)
         if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {          if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
                 struct  in6_multi *in6m = 0;                  struct  in6_multi *in6m = 0;
   
                 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_mcast);                  in6_ifstat_inc(rcvif, ifs6_in_mcast);
                 /*                  /*
                  * See if we belong to the destination multicast group on the                   * See if we belong to the destination multicast group on the
                  * arrival interface.                   * arrival interface.
                  */                   */
                 IN6_LOOKUP_MULTI(ip6->ip6_dst, m->m_pkthdr.rcvif, in6m);                  IN6_LOOKUP_MULTI(ip6->ip6_dst, rcvif, in6m);
                 if (in6m)                  if (in6m)
                         ours = 1;                          ours = 1;
                 else if (!ip6_mrouter) {                  else if (!ip6_mrouter) {
Line 454  ip6_input(struct mbuf *m)
Line 449  ip6_input(struct mbuf *m)
                         ip6s[IP6_STAT_NOTMEMBER]++;                          ip6s[IP6_STAT_NOTMEMBER]++;
                         ip6s[IP6_STAT_CANTFORWARD]++;                          ip6s[IP6_STAT_CANTFORWARD]++;
                         IP6_STAT_PUTREF();                          IP6_STAT_PUTREF();
                         in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);                          in6_ifstat_inc(rcvif, ifs6_in_discard);
                         goto bad;                          goto bad;
                 }                  }
                 deliverifp = m->m_pkthdr.rcvif;                  deliverifp = rcvif;
                 goto hbhcheck;                  goto hbhcheck;
         }          }
   
Line 485  ip6_input(struct mbuf *m)
Line 480  ip6_input(struct mbuf *m)
          */           */
         if (rt != NULL &&          if (rt != NULL &&
             (rt->rt_flags & (RTF_HOST|RTF_GATEWAY)) == RTF_HOST &&              (rt->rt_flags & (RTF_HOST|RTF_GATEWAY)) == RTF_HOST &&
             !(rt->rt_flags & RTF_CLONED) &&  
 #if 0  #if 0
             /*              /*
              * The check below is redundant since the comparison of               * The check below is redundant since the comparison of
Line 509  ip6_input(struct mbuf *m)
Line 503  ip6_input(struct mbuf *m)
                         goto hbhcheck;                          goto hbhcheck;
                 } else {                  } else {
                         /* address is not ready, so discard the packet. */                          /* address is not ready, so discard the packet. */
                         nd6log((LOG_INFO,                          nd6log(LOG_INFO, "packet to an unready address %s->%s\n",
                             "ip6_input: packet to an unready address %s->%s\n",  
                             ip6_sprintf(&ip6->ip6_src),                              ip6_sprintf(&ip6->ip6_src),
                             ip6_sprintf(&ip6->ip6_dst)));                              ip6_sprintf(&ip6->ip6_dst));
   
                         goto bad;                          goto bad;
                 }                  }
Line 541  ip6_input(struct mbuf *m)
Line 534  ip6_input(struct mbuf *m)
          * working right.           * working right.
          */           */
         struct ifaddr *ifa;          struct ifaddr *ifa;
         IFADDR_FOREACH(ifa, m->m_pkthdr.rcvif) {          IFADDR_READER_FOREACH(ifa, rcvif) {
                 if (ifa->ifa_addr == NULL)  
                         continue;       /* just for safety */  
                 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 561  ip6_input(struct mbuf *m)
Line 552  ip6_input(struct mbuf *m)
          */           */
         if (!ip6_forwarding) {          if (!ip6_forwarding) {
                 IP6_STATINC(IP6_STAT_CANTFORWARD);                  IP6_STATINC(IP6_STAT_CANTFORWARD);
                 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);                  in6_ifstat_inc(rcvif, ifs6_in_discard);
                 goto bad;                  goto bad;
         }          }
   
Line 596  ip6_input(struct mbuf *m)
Line 587  ip6_input(struct mbuf *m)
   
                 if (ip6_hopopts_input(&plen, &rtalert, &m, &off)) {                  if (ip6_hopopts_input(&plen, &rtalert, &m, &off)) {
 #if 0   /*touches NULL pointer*/  #if 0   /*touches NULL pointer*/
                         in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);                          in6_ifstat_inc(rcvif, ifs6_in_discard);
 #endif  #endif
                         return; /* m have already been freed */                          return; /* m have already been freed */
                 }                  }
Line 616  ip6_input(struct mbuf *m)
Line 607  ip6_input(struct mbuf *m)
                          * (non-zero) payload length to the variable plen.                           * (non-zero) payload length to the variable plen.
                          */                           */
                         IP6_STATINC(IP6_STAT_BADOPTIONS);                          IP6_STATINC(IP6_STAT_BADOPTIONS);
                         in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_discard);                          in6_ifstat_inc(rcvif, ifs6_in_discard);
                         in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);                          in6_ifstat_inc(rcvif, ifs6_in_hdrerr);
                         icmp6_error(m, ICMP6_PARAM_PROB,                          icmp6_error(m, ICMP6_PARAM_PROB,
                                     ICMP6_PARAMPROB_HEADER,                                      ICMP6_PARAMPROB_HEADER,
                                     (char *)&ip6->ip6_plen - (char *)ip6);                                      (char *)&ip6->ip6_plen - (char *)ip6);
Line 649  ip6_input(struct mbuf *m)
Line 640  ip6_input(struct mbuf *m)
          */           */
         if (m->m_pkthdr.len - sizeof(struct ip6_hdr) < plen) {          if (m->m_pkthdr.len - sizeof(struct ip6_hdr) < plen) {
                 IP6_STATINC(IP6_STAT_TOOSHORT);                  IP6_STATINC(IP6_STAT_TOOSHORT);
                 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated);                  in6_ifstat_inc(rcvif, ifs6_in_truncated);
                 goto bad;                  goto bad;
         }          }
         if (m->m_pkthdr.len > sizeof(struct ip6_hdr) + plen) {          if (m->m_pkthdr.len > sizeof(struct ip6_hdr) + plen) {
Line 672  ip6_input(struct mbuf *m)
Line 663  ip6_input(struct mbuf *m)
                  * ip6_mforward() returns a non-zero value, the packet                   * ip6_mforward() returns a non-zero value, the packet
                  * must be discarded, else it may be accepted below.                   * must be discarded, else it may be accepted below.
                  */                   */
                 if (ip6_mrouter && ip6_mforward(ip6, m->m_pkthdr.rcvif, m)) {                  if (ip6_mrouter && ip6_mforward(ip6, rcvif, m)) {
                         IP6_STATINC(IP6_STAT_CANTFORWARD);                          IP6_STATINC(IP6_STAT_CANTFORWARD);
                         m_freem(m);                          m_freem(m);
                         return;                          return;
Line 700  ip6_input(struct mbuf *m)
Line 691  ip6_input(struct mbuf *m)
         if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) ||          if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) ||
             IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) {              IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) {
                 IP6_STATINC(IP6_STAT_BADSCOPE);                  IP6_STATINC(IP6_STAT_BADSCOPE);
                 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_addrerr);                  in6_ifstat_inc(rcvif, ifs6_in_addrerr);
                 goto bad;                  goto bad;
         }          }
   
Line 723  ip6_input(struct mbuf *m)
Line 714  ip6_input(struct mbuf *m)
         while (nxt != IPPROTO_DONE) {          while (nxt != IPPROTO_DONE) {
                 if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) {                  if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) {
                         IP6_STATINC(IP6_STAT_TOOMANYHDR);                          IP6_STATINC(IP6_STAT_TOOMANYHDR);
                         in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);                          in6_ifstat_inc(rcvif, ifs6_in_hdrerr);
                         goto bad;                          goto bad;
                 }                  }
   
Line 733  ip6_input(struct mbuf *m)
Line 724  ip6_input(struct mbuf *m)
                  */                   */
                 if (m->m_pkthdr.len < off) {                  if (m->m_pkthdr.len < off) {
                         IP6_STATINC(IP6_STAT_TOOSHORT);                          IP6_STATINC(IP6_STAT_TOOSHORT);
                         in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_truncated);                          in6_ifstat_inc(rcvif, ifs6_in_truncated);
                         goto bad;                          goto bad;
                 }                  }
   
                 if (nxt == IPPROTO_ROUTING) {                  if (nxt == IPPROTO_ROUTING) {
                         if (rh_present++) {                          if (rh_present++) {
                                 in6_ifstat_inc(m->m_pkthdr.rcvif,                                  in6_ifstat_inc(rcvif, ifs6_in_hdrerr);
                                     ifs6_in_hdrerr);  
                                 IP6_STATINC(IP6_STAT_BADOPTIONS);                                  IP6_STATINC(IP6_STAT_BADOPTIONS);
                                 goto bad;                                  goto bad;
                         }                          }
Line 748  ip6_input(struct mbuf *m)
Line 738  ip6_input(struct mbuf *m)
   
 #ifdef IPSEC  #ifdef IPSEC
                 if (ipsec_used) {                  if (ipsec_used) {
                         struct m_tag *mtag;  
                         struct tdb_ident *tdbi;  
                         struct secpolicy *sp;  
                         int s, error;  
   
                         /*                          /*
                          * enforce IPsec policy checking if we are seeing last                           * enforce IPsec policy checking if we are seeing last
                          * header. note that we do not visit this with                           * header. note that we do not visit this with
Line 760  ip6_input(struct mbuf *m)
Line 745  ip6_input(struct mbuf *m)
                          */                           */
                         if ((inet6sw[ip_protox[nxt]].pr_flags                          if ((inet6sw[ip_protox[nxt]].pr_flags
                             & PR_LASTHDR) != 0) {                              & PR_LASTHDR) != 0) {
                                 /*                                  int error = ipsec6_input(m);
                                  * Check if the packet has already had IPsec  
                                  * processing done. If so, then just pass it  
                                  * along. This tag gets set during AH, ESP,  
                                  * etc. input handling, before the packet is  
                                  * returned to the ip input queue for delivery.  
                                  */  
                                 mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE,  
                                     NULL);  
                                 s = splsoftnet();  
                                 if (mtag != NULL) {  
                                         tdbi = (struct tdb_ident *)(mtag + 1);  
                                         sp = ipsec_getpolicy(tdbi,  
                                             IPSEC_DIR_INBOUND);  
                                 } else {  
                                         sp = ipsec_getpolicybyaddr(m,  
                                             IPSEC_DIR_INBOUND, IP_FORWARDING,  
                                             &error);  
                                 }  
                                 if (sp != NULL) {  
                                         /*  
                                          * Check security policy against packet  
                                          * attributes.  
                                          */  
                                         error = ipsec_in_reject(sp, m);  
                                         KEY_FREESP(&sp);  
                                 } else {  
                                         /* XXX error stat??? */  
                                         error = EINVAL;  
                                         DPRINTF(("ip6_input: no SP, packet"  
                                             " discarded\n"));/*XXX*/  
                                 }  
                                 splx(s);  
                                 if (error)                                  if (error)
                                         goto bad;                                          goto bad;
                         }                          }
Line 849  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 894  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 1069  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 1110  ip6_savecontrol(struct in6pcb *in6p, str
Line 1063  ip6_savecontrol(struct in6pcb *in6p, str
   
                 memcpy(&pi6.ipi6_addr, &ip6->ip6_dst, sizeof(struct in6_addr));                  memcpy(&pi6.ipi6_addr, &ip6->ip6_dst, sizeof(struct in6_addr));
                 in6_clearscope(&pi6.ipi6_addr); /* XXX */                  in6_clearscope(&pi6.ipi6_addr); /* XXX */
                 pi6.ipi6_ifindex = m->m_pkthdr.rcvif ?                  pi6.ipi6_ifindex = m->m_pkthdr.rcvif_index;
                     m->m_pkthdr.rcvif->if_index : 0;  
                 *mp = sbcreatecontrol((void *) &pi6,                  *mp = sbcreatecontrol((void *) &pi6,
                     sizeof(struct in6_pktinfo),                      sizeof(struct in6_pktinfo),
                     IS2292(IPV6_2292PKTINFO, IPV6_PKTINFO), IPPROTO_IPV6);                      IS2292(IPV6_2292PKTINFO, IPV6_PKTINFO), IPPROTO_IPV6);
Line 1574  ip6_delaux(struct mbuf *m)
Line 1526  ip6_delaux(struct mbuf *m)
 }  }
   
 #ifdef GATEWAY  #ifdef GATEWAY
 /*  /*
  * sysctl helper routine for net.inet.ip6.maxflows. Since   * sysctl helper routine for net.inet.ip6.maxflows. Since
  * we could reduce this value, call ip6flow_reap();   * we could reduce this value, call ip6flow_reap();
  */   */
 static int  static int
 sysctl_net_inet6_ip6_maxflows(SYSCTLFN_ARGS)  sysctl_net_inet6_ip6_maxflows(SYSCTLFN_ARGS)
 {  {
         int error;          int error;
   
         error = sysctl_lookup(SYSCTLFN_CALL(rnode));          error = sysctl_lookup(SYSCTLFN_CALL(rnode));
         if (error || newp == NULL)          if (error || newp == NULL)
                 return (error);                  return (error);
   
         mutex_enter(softnet_lock);          mutex_enter(softnet_lock);
         KERNEL_LOCK(1, NULL);          KERNEL_LOCK(1, NULL);
   
Line 1594  sysctl_net_inet6_ip6_maxflows(SYSCTLFN_A
Line 1546  sysctl_net_inet6_ip6_maxflows(SYSCTLFN_A
   
         KERNEL_UNLOCK_ONE(NULL);          KERNEL_UNLOCK_ONE(NULL);
         mutex_exit(softnet_lock);          mutex_exit(softnet_lock);
   
         return (0);          return (0);
 }  }
   
 static int  static int
 sysctl_net_inet6_ip6_hashsize(SYSCTLFN_ARGS)  sysctl_net_inet6_ip6_hashsize(SYSCTLFN_ARGS)
 {  {
         int error, tmp;          int error, tmp;
         struct sysctlnode node;          struct sysctlnode node;
   
Line 1627  sysctl_net_inet6_ip6_hashsize(SYSCTLFN_A
Line 1579  sysctl_net_inet6_ip6_hashsize(SYSCTLFN_A
                  * EINVAL if not a power of 2                   * EINVAL if not a power of 2
                  */                   */
                 error = EINVAL;                  error = EINVAL;
         }          }
   
         return error;          return error;
 }  }
Line 1646  const u_char inet6ctlerrmap[PRC_NCMDS] =
Line 1598  const u_char inet6ctlerrmap[PRC_NCMDS] =
         ENOPROTOOPT          ENOPROTOOPT
 };  };
   
   extern int sysctl_net_inet6_addrctlpolicy(SYSCTLFN_ARGS);
   
 static int  static int
 sysctl_net_inet6_ip6_stats(SYSCTLFN_ARGS)  sysctl_net_inet6_ip6_stats(SYSCTLFN_ARGS)
 {  {
Line 1811  sysctl_net_inet6_ip6_setup(struct sysctl
Line 1765  sysctl_net_inet6_ip6_setup(struct sysctl
                        NULL, 0, &ip6_defmcasthlim, 0,                         NULL, 0, &ip6_defmcasthlim, 0,
                        CTL_NET, PF_INET6, IPPROTO_IPV6,                         CTL_NET, PF_INET6, IPPROTO_IPV6,
                        IPV6CTL_DEFMCASTHLIM, CTL_EOL);                         IPV6CTL_DEFMCASTHLIM, CTL_EOL);
 #if NGIF > 0  
         sysctl_createv(clog, 0, NULL, NULL,  
                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,  
                        CTLTYPE_INT, "gifhlim",  
                        SYSCTL_DESCR("Default hop limit for a gif tunnel datagram"),  
                        NULL, 0, &ip6_gif_hlim, 0,  
                        CTL_NET, PF_INET6, IPPROTO_IPV6,  
                        IPV6CTL_GIF_HLIM, CTL_EOL);  
 #endif /* NGIF */  
         sysctl_createv(clog, 0, NULL, NULL,          sysctl_createv(clog, 0, NULL, NULL,
                        CTLFLAG_PERMANENT,                         CTLFLAG_PERMANENT,
                        CTLTYPE_STRING, "kame_version",                         CTLTYPE_STRING, "kame_version",
Line 1854  sysctl_net_inet6_ip6_setup(struct sysctl
Line 1799  sysctl_net_inet6_ip6_setup(struct sysctl
                        IPV6CTL_V6ONLY, CTL_EOL);                         IPV6CTL_V6ONLY, CTL_EOL);
         sysctl_createv(clog, 0, NULL, NULL,          sysctl_createv(clog, 0, NULL, NULL,
                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,                         CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
                        CTLTYPE_INT, "auto_linklocal",  
                        SYSCTL_DESCR("Default value of per-interface flag for "  
                                     "adding an IPv6 link-local address to "  
                                     "interfaces when attached"),  
                        NULL, 0, &ip6_auto_linklocal, 0,  
                        CTL_NET, PF_INET6, IPPROTO_IPV6,  
                        IPV6CTL_AUTO_LINKLOCAL, CTL_EOL);  
         sysctl_createv(clog, 0, NULL, NULL,  
                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,  
                        CTLTYPE_INT, "anonportmin",                         CTLTYPE_INT, "anonportmin",
                        SYSCTL_DESCR("Lowest ephemeral port number to assign"),                         SYSCTL_DESCR("Lowest ephemeral port number to assign"),
                        sysctl_net_inet_ip_ports, 0, &ip6_anonportmin, 0,                         sysctl_net_inet_ip_ports, 0, &ip6_anonportmin, 0,
Line 1895  sysctl_net_inet6_ip6_setup(struct sysctl
Line 1831  sysctl_net_inet6_ip6_setup(struct sysctl
 #endif /* IPNOPRIVPORTS */  #endif /* IPNOPRIVPORTS */
         sysctl_createv(clog, 0, NULL, NULL,          sysctl_createv(clog, 0, NULL, NULL,
                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,                         CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
                          CTLTYPE_INT, "auto_linklocal",
                          SYSCTL_DESCR("Default value of per-interface flag for "
                                       "adding an IPv6 link-local address to "
                                       "interfaces when attached"),
                          NULL, 0, &ip6_auto_linklocal, 0,
                          CTL_NET, PF_INET6, IPPROTO_IPV6,
                          IPV6CTL_AUTO_LINKLOCAL, CTL_EOL);
           sysctl_createv(clog, 0, NULL, NULL,
                          CTLFLAG_PERMANENT|CTLFLAG_READONLY,
                          CTLTYPE_STRUCT, "addctlpolicy",
                          SYSCTL_DESCR("Return the current address control"
                              " policy"),
                          sysctl_net_inet6_addrctlpolicy, 0, NULL, 0,
                          CTL_NET, PF_INET6, IPPROTO_IPV6,
                          IPV6CTL_ADDRCTLPOLICY, CTL_EOL);
           sysctl_createv(clog, 0, NULL, NULL,
                          CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
                        CTLTYPE_INT, "use_tempaddr",                         CTLTYPE_INT, "use_tempaddr",
                        SYSCTL_DESCR("Use temporary address"),                         SYSCTL_DESCR("Use temporary address"),
                        NULL, 0, &ip6_use_tempaddr, 0,                         NULL, 0, &ip6_use_tempaddr, 0,
Line 1902  sysctl_net_inet6_ip6_setup(struct sysctl
Line 1855  sysctl_net_inet6_ip6_setup(struct sysctl
                        CTL_CREATE, CTL_EOL);                         CTL_CREATE, CTL_EOL);
         sysctl_createv(clog, 0, NULL, NULL,          sysctl_createv(clog, 0, NULL, NULL,
                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,                         CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
                          CTLTYPE_INT, "prefer_tempaddr",
                          SYSCTL_DESCR("Prefer temporary address as source "
                                       "address"),
                          NULL, 0, &ip6_prefer_tempaddr, 0,
                          CTL_NET, PF_INET6, IPPROTO_IPV6,
                          CTL_CREATE, CTL_EOL);
           sysctl_createv(clog, 0, NULL, NULL,
                          CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
                        CTLTYPE_INT, "temppltime",                         CTLTYPE_INT, "temppltime",
                        SYSCTL_DESCR("preferred lifetime of a temporary address"),                         SYSCTL_DESCR("preferred lifetime of a temporary address"),
                        NULL, 0, &ip6_temp_preferred_lifetime, 0,                         NULL, 0, &ip6_temp_preferred_lifetime, 0,
Line 1942  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  #ifdef GATEWAY
         sysctl_createv(clog, 0, NULL, NULL,          sysctl_createv(clog, 0, NULL, NULL,
                         CTLFLAG_PERMANENT|CTLFLAG_READWRITE,                          CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
                         CTLTYPE_INT, "maxflows",                          CTLTYPE_INT, "maxflows",

Legend:
Removed from v.1.149  
changed lines
  Added in v.1.149.4.7

CVSweb <webmaster@jp.NetBSD.org>