[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.114.4.4 and 1.135.2.1

version 1.114.4.4, 2001/03/11 21:10:34 version 1.135.2.1, 2001/08/25 06:17:02
Line 105 
Line 105 
 #include "opt_pfil_hooks.h"  #include "opt_pfil_hooks.h"
 #include "opt_ipsec.h"  #include "opt_ipsec.h"
 #include "opt_mrouting.h"  #include "opt_mrouting.h"
   #include "opt_inet_csum.h"
   
 #include <sys/param.h>  #include <sys/param.h>
 #include <sys/systm.h>  #include <sys/systm.h>
Line 120 
Line 121 
 #include <sys/proc.h>  #include <sys/proc.h>
 #include <sys/pool.h>  #include <sys/pool.h>
   
 #include <vm/vm.h>  #include <uvm/uvm_extern.h>
   
 #include <sys/sysctl.h>  #include <sys/sysctl.h>
   
 #include <net/if.h>  #include <net/if.h>
Line 146 
Line 148 
 #ifdef IPSEC  #ifdef IPSEC
 #include <netinet6/ipsec.h>  #include <netinet6/ipsec.h>
 #include <netkey/key.h>  #include <netkey/key.h>
 #include <netkey/key_debug.h>  
 #endif  #endif
   
 #ifndef IPFORWARDING  #ifndef IPFORWARDING
Line 205  struct ifqueue ipintrq;
Line 206  struct ifqueue ipintrq;
 struct  ipstat  ipstat;  struct  ipstat  ipstat;
 u_int16_t       ip_id;  u_int16_t       ip_id;
   
   #ifdef PFIL_HOOKS
   struct pfil_head inet_pfil_hook;
   #endif
   
 struct ipqhead ipq;  struct ipqhead ipq;
 int     ipq_locked;  int     ipq_locked;
   int     ip_nfragpackets = 0;
   int     ip_maxfragpackets = 200;
   
 static __inline int ipq_lock_try __P((void));  static __inline int ipq_lock_try __P((void));
 static __inline void ipq_unlock __P((void));  static __inline void ipq_unlock __P((void));
Line 216  ipq_lock_try()
Line 223  ipq_lock_try()
 {  {
         int s;          int s;
   
         s = splimp();          /*
            * Use splvm() -- we're bloking things that would cause
            * mbuf allocation.
            */
           s = splvm();
         if (ipq_locked) {          if (ipq_locked) {
                 splx(s);                  splx(s);
                 return (0);                  return (0);
Line 231  ipq_unlock()
Line 242  ipq_unlock()
 {  {
         int s;          int s;
   
         s = splimp();          s = splvm();
         ipq_locked = 0;          ipq_locked = 0;
         splx(s);          splx(s);
 }  }
Line 260  do {         \
Line 271  do {         \
   
 struct pool ipqent_pool;  struct pool ipqent_pool;
   
   #ifdef INET_CSUM_COUNTERS
   #include <sys/device.h>
   
   struct evcnt ip_hwcsum_bad = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
       NULL, "inet", "hwcsum bad");
   struct evcnt ip_hwcsum_ok = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
       NULL, "inet", "hwcsum ok");
   struct evcnt ip_swcsum = EVCNT_INITIALIZER(EVCNT_TYPE_MISC,
       NULL, "inet", "swcsum");
   
   #define INET_CSUM_COUNTER_INCR(ev)      (ev)->ev_count++
   
   #else
   
   #define INET_CSUM_COUNTER_INCR(ev)      /* nothing */
   
   #endif /* INET_CSUM_COUNTERS */
   
 /*  /*
  * We need to save the IP options in case a protocol wants to respond   * We need to save the IP options in case a protocol wants to respond
  * to an incoming packet over the same route if the packet got here   * to an incoming packet over the same route if the packet got here
Line 304  ip_init()
Line 333  ip_init()
         ip_id = time.tv_sec & 0xffff;          ip_id = time.tv_sec & 0xffff;
         ipintrq.ifq_maxlen = ipqmaxlen;          ipintrq.ifq_maxlen = ipqmaxlen;
         TAILQ_INIT(&in_ifaddr);          TAILQ_INIT(&in_ifaddr);
         in_ifaddrhashtbl =          in_ifaddrhashtbl = hashinit(IN_IFADDR_HASH_SIZE, HASH_LIST, M_IFADDR,
             hashinit(IN_IFADDR_HASH_SIZE, M_IFADDR, M_WAITOK, &in_ifaddrhash);              M_WAITOK, &in_ifaddrhash);
         if (ip_mtudisc != 0)          if (ip_mtudisc != 0)
                 ip_mtudisc_timeout_q =                  ip_mtudisc_timeout_q =
                     rt_timer_queue_create(ip_mtudisc_timeout);                      rt_timer_queue_create(ip_mtudisc_timeout);
 #ifdef GATEWAY  #ifdef GATEWAY
         ipflow_init();          ipflow_init();
 #endif  #endif
   
   #ifdef PFIL_HOOKS
           /* Register our Packet Filter hook. */
           inet_pfil_hook.ph_type = PFIL_TYPE_AF;
           inet_pfil_hook.ph_af   = AF_INET;
           i = pfil_head_register(&inet_pfil_hook);
           if (i != 0)
                   printf("ip_init: WARNING: unable to register pfil hook, "
                       "error %d\n", i);
   #endif /* PFIL_HOOKS */
   
   #ifdef INET_CSUM_COUNTERS
           evcnt_attach_static(&ip_hwcsum_bad);
           evcnt_attach_static(&ip_hwcsum_ok);
           evcnt_attach_static(&ip_swcsum);
   #endif /* INET_CSUM_COUNTERS */
 }  }
   
 struct  sockaddr_in ipaddr = { sizeof(ipaddr), AF_INET };  struct  sockaddr_in ipaddr = { sizeof(ipaddr), AF_INET };
Line 327  ipintr()
Line 372  ipintr()
         struct mbuf *m;          struct mbuf *m;
   
         while (1) {          while (1) {
                 s = splimp();                  s = splnet();
                 IF_DEQUEUE(&ipintrq, m);                  IF_DEQUEUE(&ipintrq, m);
                 splx(s);                  splx(s);
                 if (m == 0)                  if (m == 0)
Line 350  ip_input(struct mbuf *m)
Line 395  ip_input(struct mbuf *m)
         struct ipqent *ipqe;          struct ipqent *ipqe;
         int hlen = 0, mff, len;          int hlen = 0, mff, len;
         int downmatch;          int downmatch;
 #ifdef PFIL_HOOKS  
         struct packet_filter_hook *pfh;  
         struct mbuf *m0;  
         int rv;  
 #endif /* PFIL_HOOKS */  
   
 #ifdef  DIAGNOSTIC  #ifdef  DIAGNOSTIC
         if ((m->m_flags & M_PKTHDR) == 0)          if ((m->m_flags & M_PKTHDR) == 0)
Line 405  ip_input(struct mbuf *m)
Line 445  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)) {
                 /* XXX stat */                  ipstat.ips_badaddr++;
                 goto bad;                  goto bad;
         }          }
   
         if (in_cksum(m, hlen) != 0) {          /* 127/8 must not appear on wire - RFC1122 */
                 ipstat.ips_badsum++;          if ((ntohl(ip->ip_dst.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET ||
                 goto bad;              (ntohl(ip->ip_src.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) {
                   if ((m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK) == 0) {
                           ipstat.ips_badaddr++;
                           goto bad;
                   }
         }          }
   
         /*          switch (m->m_pkthdr.csum_flags &
          * Convert fields to host representation.                  ((m->m_pkthdr.rcvif->if_csum_flags & M_CSUM_IPv4) |
          */                   M_CSUM_IPv4_BAD)) {
         NTOHS(ip->ip_len);          case M_CSUM_IPv4|M_CSUM_IPv4_BAD:
         NTOHS(ip->ip_off);                  INET_CSUM_COUNTER_INCR(&ip_hwcsum_bad);
         len = ip->ip_len;                  goto badcsum;
   
           case M_CSUM_IPv4:
                   /* Checksum was okay. */
                   INET_CSUM_COUNTER_INCR(&ip_hwcsum_ok);
                   break;
   
           default:
                   /* Must compute it ourselves. */
                   INET_CSUM_COUNTER_INCR(&ip_swcsum);
                   if (in_cksum(m, hlen) != 0)
                           goto bad;
                   break;
           }
   
           /* Retrieve the packet length. */
           len = ntohs(ip->ip_len);
   
         /*          /*
          * Check for additional length bogosity           * Check for additional length bogosity
Line 466  ip_input(struct mbuf *m)
Line 526  ip_input(struct mbuf *m)
          * Note that filters must _never_ set this flag, as another filter           * Note that filters must _never_ set this flag, as another filter
          * in the list may have previously cleared it.           * in the list may have previously cleared it.
          */           */
         m0 = m;          /*
         pfh = pfil_hook_get(PFIL_IN, &inetsw[ip_protox[IPPROTO_IP]].pr_pfh);           * let ipfilter look at packet on the wire,
         for (; pfh; pfh = pfh->pfil_link.tqe_next)           * not the decapsulated packet.
                 if (pfh->pfil_func) {           */
                         rv = pfh->pfil_func(ip, hlen,  #ifdef IPSEC
                                             m->m_pkthdr.rcvif, 0, &m0);          if (!ipsec_getnhist(m))
                         if (rv)  #else
                                 return;          if (1)
                         m = m0;  #endif
                         if (m == NULL)          {
                                 return;                  if (pfil_run_hooks(&inet_pfil_hook, &m, m->m_pkthdr.rcvif,
                         ip = mtod(m, struct ip *);                                     PFIL_IN) != 0)
                 }                  return;
                   if (m == NULL)
                           return;
                   ip = mtod(m, struct ip *);
           }
 #endif /* PFIL_HOOKS */  #endif /* PFIL_HOOKS */
   
   #ifdef ALTQ
           /* XXX Temporary until ALTQ is changed to use a pfil hook */
           if (altq_input != NULL && (*altq_input)(m, AF_INET) == 0) {
                   /* packet dropped by traffic conditioner */
                   return;
           }
   #endif
   
           /*
            * Convert fields to host representation.
            */
           NTOHS(ip->ip_len);
           NTOHS(ip->ip_off);
   
         /*          /*
          * Process options and, if not destined for us,           * Process options and, if not destined for us,
          * ship it on.  ip_dooptions returns 1 when an           * ship it on.  ip_dooptions returns 1 when an
Line 704  found:
Line 782  found:
          * Switch out to protocol's input routine.           * Switch out to protocol's input routine.
          */           */
 #if IFA_STATS  #if IFA_STATS
         ia->ia_ifa.ifa_data.ifad_inbytes += ip->ip_len;          if (ia && ip)
                   ia->ia_ifa.ifa_data.ifad_inbytes += ip->ip_len;
 #endif  #endif
         ipstat.ips_delivered++;          ipstat.ips_delivered++;
     {      {
Line 715  found:
Line 794  found:
     }      }
 bad:  bad:
         m_freem(m);          m_freem(m);
           return;
   
   badcsum:
           ipstat.ips_badsum++;
           m_freem(m);
 }  }
   
 /*  /*
Line 748  ip_reass(ipqe, fp)
Line 832  ip_reass(ipqe, fp)
          * If first fragment to arrive, create a reassembly queue.           * If first fragment to arrive, create a reassembly queue.
          */           */
         if (fp == 0) {          if (fp == 0) {
                   /*
                    * Enforce upper bound on number of fragmented packets
                    * for which we attempt reassembly;
                    * If maxfrag is 0, never accept fragments.
                    * If maxfrag is -1, accept all fragments without limitation.
                    */
                   if (ip_maxfragpackets < 0)
                           ;
                   else if (ip_nfragpackets >= ip_maxfragpackets)
                           goto dropfrag;
                   ip_nfragpackets++;
                 MALLOC(fp, struct ipq *, sizeof (struct ipq),                  MALLOC(fp, struct ipq *, sizeof (struct ipq),
                     M_FTABLE, M_NOWAIT);                      M_FTABLE, M_NOWAIT);
                 if (fp == NULL)                  if (fp == NULL)
Line 863  insert:
Line 958  insert:
         ip->ip_dst = fp->ipq_dst;          ip->ip_dst = fp->ipq_dst;
         LIST_REMOVE(fp, ipq_q);          LIST_REMOVE(fp, ipq_q);
         FREE(fp, M_FTABLE);          FREE(fp, M_FTABLE);
           ip_nfragpackets--;
         m->m_len += (ip->ip_hl << 2);          m->m_len += (ip->ip_hl << 2);
         m->m_data -= (ip->ip_hl << 2);          m->m_data -= (ip->ip_hl << 2);
         /* some debugging cruft by sklower, below, will go away soon */          /* some debugging cruft by sklower, below, will go away soon */
Line 901  ip_freef(fp)
Line 997  ip_freef(fp)
         }          }
         LIST_REMOVE(fp, ipq_q);          LIST_REMOVE(fp, ipq_q);
         FREE(fp, M_FTABLE);          FREE(fp, M_FTABLE);
           ip_nfragpackets--;
 }  }
   
 /*  /*
Line 922  ip_slowtimo()
Line 1019  ip_slowtimo()
                         ip_freef(fp);                          ip_freef(fp);
                 }                  }
         }          }
           /*
            * If we are over the maximum number of fragments
            * (due to the limit being lowered), drain off
            * enough to get down to the new limit.
            */
           if (ip_maxfragpackets < 0)
                   ;
           else {
                   while (ip_nfragpackets > ip_maxfragpackets && ipq.lh_first)
                           ip_freef(ipq.lh_first);
           }
         IPQ_UNLOCK();          IPQ_UNLOCK();
 #ifdef GATEWAY  #ifdef GATEWAY
         ipflow_slowtimo();          ipflow_slowtimo();
Line 1371  ip_forward(m, srcrt)
Line 1479  ip_forward(m, srcrt)
         struct ifnet dummyifp;          struct ifnet dummyifp;
 #endif  #endif
   
           /*
            * Clear any in-bound checksum flags for this packet.
            */
           m->m_pkthdr.csum_flags = 0;
   
         dest = 0;          dest = 0;
 #ifdef DIAGNOSTIC  #ifdef DIAGNOSTIC
         if (ipprintfs)          if (ipprintfs)
Line 1451  ip_forward(m, srcrt)
Line 1564  ip_forward(m, srcrt)
         }          }
   
 #ifdef IPSEC  #ifdef IPSEC
         /* Don't lookup socket in forwading case */          /* Don't lookup socket in forwarding case */
         ipsec_setsocket(m, NULL);          (void)ipsec_setsocket(m, NULL);
 #endif  #endif
         error = ip_output(m, (struct mbuf *)0, &ipforward_rt,          error = ip_output(m, (struct mbuf *)0, &ipforward_rt,
             (IP_FORWARDING | (ip_directedbcast ? IP_ALLOWBROADCAST : 0)), 0);              (IP_FORWARDING | (ip_directedbcast ? IP_ALLOWBROADCAST : 0)), 0);
Line 1758  ip_sysctl(name, namelen, oldp, oldlenp, 
Line 1871  ip_sysctl(name, namelen, oldp, oldlenp, 
                 return (error);                  return (error);
 #endif  #endif
   
           case IPCTL_MAXFRAGPACKETS:
                   return (sysctl_int(oldp, oldlenp, newp, newlen,
                       &ip_maxfragpackets));
   
         default:          default:
                 return (EOPNOTSUPP);                  return (EOPNOTSUPP);
         }          }

Legend:
Removed from v.1.114.4.4  
changed lines
  Added in v.1.135.2.1

CVSweb <webmaster@jp.NetBSD.org>