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

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

Diff for /src/sys/netinet/ip_input.c between version 1.265 and 1.266

version 1.265, 2008/04/09 05:14:20 version 1.266, 2008/04/12 05:58:22
Line 135  __KERNEL_RCSID(0, "$NetBSD$");
Line 135  __KERNEL_RCSID(0, "$NetBSD$");
 #include <netinet/in_proto.h>  #include <netinet/in_proto.h>
 #include <netinet/in_var.h>  #include <netinet/in_var.h>
 #include <netinet/ip_var.h>  #include <netinet/ip_var.h>
   #include <netinet/ip_private.h>
 #include <netinet/ip_icmp.h>  #include <netinet/ip_icmp.h>
 /* just for gif_ttl */  /* just for gif_ttl */
 #include <netinet/in_gif.h>  #include <netinet/in_gif.h>
Line 230  u_long in_multihash;    /* size of hash 
Line 231  u_long in_multihash;    /* size of hash 
 int     in_multientries;                        /* total number of addrs */  int     in_multientries;                        /* total number of addrs */
 struct  in_multihashhead *in_multihashtbl;  struct  in_multihashhead *in_multihashtbl;
 struct  ifqueue ipintrq;  struct  ifqueue ipintrq;
 uint64_t ipstat[IP_NSTATS];  
 uint16_t ip_id;  uint16_t ip_id;
   
   percpu_t *ipstat_percpu;
   
 #ifdef PFIL_HOOKS  #ifdef PFIL_HOOKS
 struct pfil_head inet_pfil_hook;  struct pfil_head inet_pfil_hook;
 #endif  #endif
Line 447  ip_init(void)
Line 449  ip_init(void)
         MOWNER_ATTACH(&ip_tx_mowner);          MOWNER_ATTACH(&ip_tx_mowner);
         MOWNER_ATTACH(&ip_rx_mowner);          MOWNER_ATTACH(&ip_rx_mowner);
 #endif /* MBUFTRACE */  #endif /* MBUFTRACE */
   
           ipstat_percpu = percpu_alloc(sizeof(uint64_t) * IP_NSTATS);
 }  }
   
 struct  sockaddr_in ipaddr = {  struct  sockaddr_in ipaddr = {
Line 511  ip_input(struct mbuf *m)
Line 515  ip_input(struct mbuf *m)
          */           */
         if (TAILQ_FIRST(&in_ifaddrhead) == 0)          if (TAILQ_FIRST(&in_ifaddrhead) == 0)
                 goto bad;                  goto bad;
         ipstat[IP_STAT_TOTAL]++;          IP_STATINC(IP_STAT_TOTAL);
         /*          /*
          * If the IP header is not aligned, slurp it up into a new           * If the IP header is not aligned, slurp it up into a new
          * mbuf with space for link headers, in the event we forward           * mbuf with space for link headers, in the event we forward
Line 522  ip_input(struct mbuf *m)
Line 526  ip_input(struct mbuf *m)
                 if ((m = m_copyup(m, sizeof(struct ip),                  if ((m = m_copyup(m, sizeof(struct ip),
                                   (max_linkhdr + 3) & ~3)) == NULL) {                                    (max_linkhdr + 3) & ~3)) == NULL) {
                         /* XXXJRT new stat, please */                          /* XXXJRT new stat, please */
                         ipstat[IP_STAT_TOOSMALL]++;                          IP_STATINC(IP_STAT_TOOSMALL);
                         return;                          return;
                 }                  }
         } else if (__predict_false(m->m_len < sizeof (struct ip))) {          } else if (__predict_false(m->m_len < sizeof (struct ip))) {
                 if ((m = m_pullup(m, sizeof (struct ip))) == NULL) {                  if ((m = m_pullup(m, sizeof (struct ip))) == NULL) {
                         ipstat[IP_STAT_TOOSMALL]++;                          IP_STATINC(IP_STAT_TOOSMALL);
                         return;                          return;
                 }                  }
         }          }
         ip = mtod(m, struct ip *);          ip = mtod(m, struct ip *);
         if (ip->ip_v != IPVERSION) {          if (ip->ip_v != IPVERSION) {
                 ipstat[IP_STAT_BADVERS]++;                  IP_STATINC(IP_STAT_BADVERS);
                 goto bad;                  goto bad;
         }          }
         hlen = ip->ip_hl << 2;          hlen = ip->ip_hl << 2;
         if (hlen < sizeof(struct ip)) { /* minimum header length */          if (hlen < sizeof(struct ip)) { /* minimum header length */
                 ipstat[IP_STAT_BADHLEN]++;                  IP_STATINC(IP_STAT_BADHLEN);
                 goto bad;                  goto bad;
         }          }
         if (hlen > m->m_len) {          if (hlen > m->m_len) {
                 if ((m = m_pullup(m, hlen)) == 0) {                  if ((m = m_pullup(m, hlen)) == 0) {
                         ipstat[IP_STAT_BADHLEN]++;                          IP_STATINC(IP_STAT_BADHLEN);
                         return;                          return;
                 }                  }
                 ip = mtod(m, struct ip *);                  ip = mtod(m, struct ip *);
Line 554  ip_input(struct mbuf *m)
Line 558  ip_input(struct mbuf *m)
          * not allowed.           * not allowed.
          */           */
         if (IN_MULTICAST(ip->ip_src.s_addr)) {          if (IN_MULTICAST(ip->ip_src.s_addr)) {
                 ipstat[IP_STAT_BADADDR]++;                  IP_STATINC(IP_STAT_BADADDR);
                 goto bad;                  goto bad;
         }          }
   
Line 562  ip_input(struct mbuf *m)
Line 566  ip_input(struct mbuf *m)
         if ((ntohl(ip->ip_dst.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET ||          if ((ntohl(ip->ip_dst.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET ||
             (ntohl(ip->ip_src.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) {              (ntohl(ip->ip_src.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) {
                 if ((m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) == 0) {                  if ((m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) == 0) {
                         ipstat[IP_STAT_BADADDR]++;                          IP_STATINC(IP_STAT_BADADDR);
                         goto bad;                          goto bad;
                 }                  }
         }          }
Line 600  ip_input(struct mbuf *m)
Line 604  ip_input(struct mbuf *m)
          * Check for additional length bogosity           * Check for additional length bogosity
          */           */
         if (len < hlen) {          if (len < hlen) {
                 ipstat[IP_STAT_BADLEN]++;                  IP_STATINC(IP_STAT_BADLEN);
                 goto bad;                  goto bad;
         }          }
   
Line 611  ip_input(struct mbuf *m)
Line 615  ip_input(struct mbuf *m)
          * Drop packet if shorter than we expect.           * Drop packet if shorter than we expect.
          */           */
         if (m->m_pkthdr.len < len) {          if (m->m_pkthdr.len < len) {
                 ipstat[IP_STAT_TOOSHORT]++;                  IP_STATINC(IP_STAT_TOOSHORT);
                 goto bad;                  goto bad;
         }          }
         if (m->m_pkthdr.len > len) {          if (m->m_pkthdr.len > len) {
Line 780  ip_input(struct mbuf *m)
Line 784  ip_input(struct mbuf *m)
                          * ip_output().)                           * ip_output().)
                          */                           */
                         if (ip_mforward(m, m->m_pkthdr.rcvif) != 0) {                          if (ip_mforward(m, m->m_pkthdr.rcvif) != 0) {
                                 ipstat[IP_STAT_CANTFORWARD]++;                                  IP_STATINC(IP_STAT_CANTFORWARD);
                                 m_freem(m);                                  m_freem(m);
                                 return;                                  return;
                         }                          }
Line 792  ip_input(struct mbuf *m)
Line 796  ip_input(struct mbuf *m)
                          */                           */
                         if (ip->ip_p == IPPROTO_IGMP)                          if (ip->ip_p == IPPROTO_IGMP)
                                 goto ours;                                  goto ours;
                         ipstat[IP_STAT_CANTFORWARD]++;                          IP_STATINC(IP_STAT_CANTFORWARD);
                 }                  }
 #endif  #endif
                 /*                  /*
Line 801  ip_input(struct mbuf *m)
Line 805  ip_input(struct mbuf *m)
                  */                   */
                 IN_LOOKUP_MULTI(ip->ip_dst, m->m_pkthdr.rcvif, inm);                  IN_LOOKUP_MULTI(ip->ip_dst, m->m_pkthdr.rcvif, inm);
                 if (inm == NULL) {                  if (inm == NULL) {
                         ipstat[IP_STAT_CANTFORWARD]++;                          IP_STATINC(IP_STAT_CANTFORWARD);
                         m_freem(m);                          m_freem(m);
                         return;                          return;
                 }                  }
Line 815  ip_input(struct mbuf *m)
Line 819  ip_input(struct mbuf *m)
          * Not for us; forward if possible and desirable.           * Not for us; forward if possible and desirable.
          */           */
         if (ipforwarding == 0) {          if (ipforwarding == 0) {
                 ipstat[IP_STAT_CANTFORWARD]++;                  IP_STATINC(IP_STAT_CANTFORWARD);
                 m_freem(m);                  m_freem(m);
         } else {          } else {
                 /*                  /*
Line 826  ip_input(struct mbuf *m)
Line 830  ip_input(struct mbuf *m)
                  */                   */
                 if (downmatch) {                  if (downmatch) {
                         icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0);                          icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0);
                         ipstat[IP_STAT_CANTFORWARD]++;                          IP_STATINC(IP_STAT_CANTFORWARD);
                         return;                          return;
                 }                  }
 #ifdef IPSEC  #ifdef IPSEC
Line 859  ip_input(struct mbuf *m)
Line 863  ip_input(struct mbuf *m)
                 KEY_FREESP(&sp);                  KEY_FREESP(&sp);
                 splx(s);                  splx(s);
                 if (error) {                  if (error) {
                         ipstat[IP_STAT_CANTFORWARD]++;                          IP_STATINC(IP_STAT_CANTFORWARD);
                         goto bad;                          goto bad;
                 }                  }
   
Line 906  ours:
Line 910  ours:
                  */                   */
                 off = (ntohs(ip->ip_off) & IP_OFFMASK) << 3;                  off = (ntohs(ip->ip_off) & IP_OFFMASK) << 3;
                 if ((off > 0 ? off + hlen : len) < IP_MINFRAGSIZE - 1) {                  if ((off > 0 ? off + hlen : len) < IP_MINFRAGSIZE - 1) {
                         ipstat[IP_STAT_BADFRAGS]++;                          IP_STATINC(IP_STAT_BADFRAGS);
                         goto bad;                          goto bad;
                 }                  }
                 /*                  /*
Line 925  ours:
Line 929  ours:
                                  * fragments.                                   * fragments.
                                  */                                   */
                                 if (ip->ip_tos != fp->ipq_tos) {                                  if (ip->ip_tos != fp->ipq_tos) {
                                         ipstat[IP_STAT_BADFRAGS]++;                                          IP_STATINC(IP_STAT_BADFRAGS);
                                         goto bad;                                          goto bad;
                                 }                                  }
                                 goto found;                                  goto found;
Line 948  found:
Line 952  found:
                          */                           */
                         if (ntohs(ip->ip_len) == 0 ||                          if (ntohs(ip->ip_len) == 0 ||
                             (ntohs(ip->ip_len) & 0x7) != 0) {                              (ntohs(ip->ip_len) & 0x7) != 0) {
                                 ipstat[IP_STAT_BADFRAGS]++;                                  IP_STATINC(IP_STAT_BADFRAGS);
                                 IPQ_UNLOCK();                                  IPQ_UNLOCK();
                                 goto bad;                                  goto bad;
                         }                          }
Line 961  found:
Line 965  found:
                  * attempt reassembly; if it succeeds, proceed.                   * attempt reassembly; if it succeeds, proceed.
                  */                   */
                 if (mff || ip->ip_off != htons(0)) {                  if (mff || ip->ip_off != htons(0)) {
                         ipstat[IP_STAT_FRAGMENTS]++;                          IP_STATINC(IP_STAT_FRAGMENTS);
                         s = splvm();                          s = splvm();
                         ipqe = pool_get(&ipqent_pool, PR_NOWAIT);                          ipqe = pool_get(&ipqent_pool, PR_NOWAIT);
                         splx(s);                          splx(s);
                         if (ipqe == NULL) {                          if (ipqe == NULL) {
                                 ipstat[IP_STAT_RCVMEMDROP]++;                                  IP_STATINC(IP_STAT_RCVMEMDROP);
                                 IPQ_UNLOCK();                                  IPQ_UNLOCK();
                                 goto bad;                                  goto bad;
                         }                          }
Line 978  found:
Line 982  found:
                                 IPQ_UNLOCK();                                  IPQ_UNLOCK();
                                 return;                                  return;
                         }                          }
                         ipstat[IP_STAT_REASSEMBLED]++;                          IP_STATINC(IP_STAT_REASSEMBLED);
                         ip = mtod(m, struct ip *);                          ip = mtod(m, struct ip *);
                         hlen = ip->ip_hl << 2;                          hlen = ip->ip_hl << 2;
                         ip->ip_len = htons(ntohs(ip->ip_len) + hlen);                          ip->ip_len = htons(ntohs(ip->ip_len) + hlen);
Line 1046  DPRINTF(("ip_input: no SP, packet discar
Line 1050  DPRINTF(("ip_input: no SP, packet discar
         if (ia && ip)          if (ia && ip)
                 ia->ia_ifa.ifa_data.ifad_inbytes += ntohs(ip->ip_len);                  ia->ia_ifa.ifa_data.ifad_inbytes += ntohs(ip->ip_len);
 #endif  #endif
         ipstat[IP_STAT_DELIVERED]++;          IP_STATINC(IP_STAT_DELIVERED);
     {      {
         int off = hlen, nh = ip->ip_p;          int off = hlen, nh = ip->ip_p;
   
Line 1058  bad:
Line 1062  bad:
         return;          return;
   
 badcsum:  badcsum:
         ipstat[IP_STAT_BADSUM]++;          IP_STATINC(IP_STAT_BADSUM);
         m_freem(m);          m_freem(m);
 }  }
   
Line 1216  insert:
Line 1220  insert:
         q = TAILQ_FIRST(&fp->ipq_fragq);          q = TAILQ_FIRST(&fp->ipq_fragq);
         ip = q->ipqe_ip;          ip = q->ipqe_ip;
         if ((next + (ip->ip_hl << 2)) > IP_MAXPACKET) {          if ((next + (ip->ip_hl << 2)) > IP_MAXPACKET) {
                 ipstat[IP_STAT_TOOLONG]++;                  IP_STATINC(IP_STAT_TOOLONG);
                 ip_freef(fp);                  ip_freef(fp);
                 return (0);                  return (0);
         }          }
Line 1266  dropfrag:
Line 1270  dropfrag:
         if (fp != 0)          if (fp != 0)
                 fp->ipq_nfrags--;                  fp->ipq_nfrags--;
         ip_nfrags--;          ip_nfrags--;
         ipstat[IP_STAT_FRAGDROPPED]++;          IP_STATINC(IP_STAT_FRAGDROPPED);
         m_freem(m);          m_freem(m);
         s = splvm();          s = splvm();
         pool_put(&ipqent_pool, ipqe);          pool_put(&ipqent_pool, ipqe);
Line 1333  ip_reass_ttl_decr(u_int ticks)
Line 1337  ip_reass_ttl_decr(u_int ticks)
                                        0 : fp->ipq_ttl - ticks);                                         0 : fp->ipq_ttl - ticks);
                         nfp = LIST_NEXT(fp, ipq_q);                          nfp = LIST_NEXT(fp, ipq_q);
                         if (fp->ipq_ttl == 0) {                          if (fp->ipq_ttl == 0) {
                                 ipstat[IP_STAT_FRAGTIMEOUT]++;                                  IP_STATINC(IP_STAT_FRAGTIMEOUT);
                                 ip_freef(fp);                                  ip_freef(fp);
                         } else {                          } else {
                                 nfrags += fp->ipq_nfrags;                                  nfrags += fp->ipq_nfrags;
Line 1680  ip_dooptions(struct mbuf *m)
Line 1684  ip_dooptions(struct mbuf *m)
         return (0);          return (0);
 bad:  bad:
         icmp_error(m, type, code, 0, 0);          icmp_error(m, type, code, 0, 0);
         ipstat[IP_STAT_BADOPTIONS]++;          IP_STATINC(IP_STAT_BADOPTIONS);
         return (1);          return (1);
 }  }
   
Line 1853  ip_forward(struct mbuf *m, int srcrt)
Line 1857  ip_forward(struct mbuf *m, int srcrt)
         }          }
 #endif  #endif
         if (m->m_flags & (M_BCAST|M_MCAST) || in_canforward(ip->ip_dst) == 0) {          if (m->m_flags & (M_BCAST|M_MCAST) || in_canforward(ip->ip_dst) == 0) {
                 ipstat[IP_STAT_CANTFORWARD]++;                  IP_STATINC(IP_STAT_CANTFORWARD);
                 m_freem(m);                  m_freem(m);
                 return;                  return;
         }          }
Line 1917  ip_forward(struct mbuf *m, int srcrt)
Line 1921  ip_forward(struct mbuf *m, int srcrt)
             (struct ip_moptions *)NULL, (struct socket *)NULL);              (struct ip_moptions *)NULL, (struct socket *)NULL);
   
         if (error)          if (error)
                 ipstat[IP_STAT_CANTFORWARD]++;                  IP_STATINC(IP_STAT_CANTFORWARD);
         else {          else {
                 ipstat[IP_STAT_FORWARD]++;                  uint64_t *ips = IP_STAT_GETREF();
                 if (type)                  ips[IP_STAT_FORWARD]++;
                         ipstat[IP_STAT_REDIRECTSENT]++;                  if (type) {
                 else {                          ips[IP_STAT_REDIRECTSENT]++;
                           IP_STAT_PUTREF();
                   } else {
                           IP_STAT_PUTREF();
                         if (mcopy) {                          if (mcopy) {
 #ifdef GATEWAY  #ifdef GATEWAY
                                 if (mcopy->m_flags & M_CANFASTFWD)                                  if (mcopy->m_flags & M_CANFASTFWD)
Line 2008  ip_forward(struct mbuf *m, int srcrt)
Line 2015  ip_forward(struct mbuf *m, int srcrt)
                         }                          }
 #endif /*defined(IPSEC) || defined(FAST_IPSEC)*/  #endif /*defined(IPSEC) || defined(FAST_IPSEC)*/
                 }                  }
                 ipstat[IP_STAT_CANTFRAG]++;                  IP_STATINC(IP_STAT_CANTFRAG);
                 break;                  break;
   
         case ENOBUFS:          case ENOBUFS:
Line 2187  sysctl_net_inet_ip_hashsize(SYSCTLFN_ARG
Line 2194  sysctl_net_inet_ip_hashsize(SYSCTLFN_ARG
 }  }
 #endif /* GATEWAY */  #endif /* GATEWAY */
   
   static void
   ipstat_convert_to_user_cb(void *v1, void *v2, struct cpu_info *ci)
   {
           uint64_t *ipsc = v1;
           uint64_t *ips = v2;
           u_int i;
   
           for (i = 0; i < IP_NSTATS; i++)
                   ips[i] += ipsc[i];
   }
   
   static void
   ipstat_convert_to_user(uint64_t *ips)
   {
   
           memset(ips, 0, sizeof(uint64_t) * IP_NSTATS);
           percpu_foreach(ipstat_percpu, ipstat_convert_to_user_cb, ips);
   }
   
   static int
   sysctl_net_inet_ip_stats(SYSCTLFN_ARGS)
   {
           struct sysctlnode node;
           uint64_t ips[IP_NSTATS];
   
           ipstat_convert_to_user(ips);
           node = *rnode;
           node.sysctl_data = ips;
           node.sysctl_size = sizeof(ips);
           return (sysctl_lookup(SYSCTLFN_CALL(&node)));
   }
   
 SYSCTL_SETUP(sysctl_net_inet_ip_setup, "sysctl net.inet.ip subtree setup")  SYSCTL_SETUP(sysctl_net_inet_ip_setup, "sysctl net.inet.ip subtree setup")
 {  {
Line 2391  SYSCTL_SETUP(sysctl_net_inet_ip_setup, "
Line 2429  SYSCTL_SETUP(sysctl_net_inet_ip_setup, "
                        CTLFLAG_PERMANENT,                         CTLFLAG_PERMANENT,
                        CTLTYPE_STRUCT, "stats",                         CTLTYPE_STRUCT, "stats",
                        SYSCTL_DESCR("IP statistics"),                         SYSCTL_DESCR("IP statistics"),
                        NULL, 0, ipstat, sizeof(ipstat),                         sysctl_net_inet_ip_stats, 0, NULL, 0,
                        CTL_NET, PF_INET, IPPROTO_IP, IPCTL_STATS,                         CTL_NET, PF_INET, IPPROTO_IP, IPCTL_STATS,
                        CTL_EOL);                         CTL_EOL);
 }  }
   
   void
   ip_statinc(u_int stat)
   {
   
           KASSERT(stat < IP_NSTATS);
           IP_STATINC(stat);
   }

Legend:
Removed from v.1.265  
changed lines
  Added in v.1.266

CVSweb <webmaster@jp.NetBSD.org>