[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.189 and 1.190

version 1.189, 2003/12/04 19:38:24 version 1.190, 2003/12/06 23:56:10
Line 236  uint16_t ip_id;
Line 236  uint16_t ip_id;
 struct pfil_head inet_pfil_hook;  struct pfil_head inet_pfil_hook;
 #endif  #endif
   
 struct ipqhead ipq;  /* IP datagram reassembly queues (hashed) */
   #define IPREASS_NHASH_LOG2      6
   #define IPREASS_NHASH           (1 << IPREASS_NHASH_LOG2)
   #define IPREASS_HMASK           (IPREASS_NHASH - 1)
   #define IPREASS_HASH(x,y) \
           (((((x) & 0xF) | ((((x) >> 8) & 0xF) << 4)) ^ (y)) & IPREASS_HMASK)
   struct ipqhead ipq[IPREASS_NHASH];
   #ifdef notyet
   static int    nipq = 0;         /* total # of reass queues */
   #endif
 int     ipq_locked;  int     ipq_locked;
 int     ip_nfragpackets = 0;  int     ip_nfragpackets = 0;
 int     ip_maxfragpackets = 200;  int     ip_maxfragpackets = 200;
Line 363  ip_init()
Line 372  ip_init()
                 if (pr->pr_domain->dom_family == PF_INET &&                  if (pr->pr_domain->dom_family == PF_INET &&
                     pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW)                      pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW)
                         ip_protox[pr->pr_protocol] = pr - inetsw;                          ip_protox[pr->pr_protocol] = pr - inetsw;
         LIST_INIT(&ipq);          for (i = 0; i < IPREASS_NHASH; i++)
                   LIST_INIT(&ipq[i]);
   
         ip_id = time.tv_sec & 0xfffff;          ip_id = time.tv_sec & 0xfffff;
         ipintrq.ifq_maxlen = ipqmaxlen;          ipintrq.ifq_maxlen = ipqmaxlen;
         TAILQ_INIT(&in_ifaddrhead);          TAILQ_INIT(&in_ifaddrhead);
Line 437  ip_input(struct mbuf *m)
Line 448  ip_input(struct mbuf *m)
         int downmatch;          int downmatch;
         int checkif;          int checkif;
         int srcrt = 0;          int srcrt = 0;
           u_int hash;
 #ifdef FAST_IPSEC  #ifdef FAST_IPSEC
         struct m_tag *mtag;          struct m_tag *mtag;
         struct tdb_ident *tdbi;          struct tdb_ident *tdbi;
Line 823  ours:
Line 835  ours:
                  * of this datagram.                   * of this datagram.
                  */                   */
                 IPQ_LOCK();                  IPQ_LOCK();
                 LIST_FOREACH(fp, &ipq, ipq_q)                  hash = IPREASS_HASH(ip->ip_src.s_addr, ip->ip_id);
                   /* XXX LIST_FOREACH(fp, &ipq[hash], ipq_q) */
                   for (fp = LIST_FIRST(&ipq[hash]); fp != NULL;
                        fp = LIST_NEXT(fp, ipq_q)) {
                         if (ip->ip_id == fp->ipq_id &&                          if (ip->ip_id == fp->ipq_id &&
                             in_hosteq(ip->ip_src, fp->ipq_src) &&                              in_hosteq(ip->ip_src, fp->ipq_src) &&
                             in_hosteq(ip->ip_dst, fp->ipq_dst) &&                              in_hosteq(ip->ip_dst, fp->ipq_dst) &&
                             ip->ip_p == fp->ipq_p)                              ip->ip_p == fp->ipq_p)
                                 goto found;                                  goto found;
   
                   }
                 fp = 0;                  fp = 0;
 found:  found:
   
Line 869  found:
Line 886  found:
                         ipqe->ipqe_mff = mff;                          ipqe->ipqe_mff = mff;
                         ipqe->ipqe_m = m;                          ipqe->ipqe_m = m;
                         ipqe->ipqe_ip = ip;                          ipqe->ipqe_ip = ip;
                         m = ip_reass(ipqe, fp);                          m = ip_reass(ipqe, fp, &ipq[hash]);
                         if (m == 0) {                          if (m == 0) {
                                 IPQ_UNLOCK();                                  IPQ_UNLOCK();
                                 return;                                  return;
Line 966  badcsum:
Line 983  badcsum:
  * is given as fp; otherwise have to make a chain.   * is given as fp; otherwise have to make a chain.
  */   */
 struct mbuf *  struct mbuf *
 ip_reass(ipqe, fp)  ip_reass(ipqe, fp, ipqhead)
         struct ipqent *ipqe;          struct ipqent *ipqe;
         struct ipq *fp;          struct ipq *fp;
           struct ipqhead *ipqhead;
 {  {
         struct mbuf *m = ipqe->ipqe_m;          struct mbuf *m = ipqe->ipqe_m;
         struct ipqent *nq, *p, *q;          struct ipqent *nq, *p, *q;
Line 1005  ip_reass(ipqe, fp)
Line 1023  ip_reass(ipqe, fp)
                     M_FTABLE, M_NOWAIT);                      M_FTABLE, M_NOWAIT);
                 if (fp == NULL)                  if (fp == NULL)
                         goto dropfrag;                          goto dropfrag;
                 LIST_INSERT_HEAD(&ipq, fp, ipq_q);                  LIST_INSERT_HEAD(ipqhead, fp, ipq_q);
                 fp->ipq_ttl = IPFRAGTTL;                  fp->ipq_ttl = IPFRAGTTL;
                 fp->ipq_p = ipqe->ipqe_ip->ip_p;                  fp->ipq_p = ipqe->ipqe_ip->ip_p;
                 fp->ipq_id = ipqe->ipqe_ip->ip_id;                  fp->ipq_id = ipqe->ipqe_ip->ip_id;
Line 1171  ip_freef(fp)
Line 1189  ip_freef(fp)
 void  void
 ip_slowtimo()  ip_slowtimo()
 {  {
           static unsigned dropscanidx = 0;
           unsigned i;
         struct ipq *fp, *nfp;          struct ipq *fp, *nfp;
         int s = splsoftnet();          int s = splsoftnet();
   
         IPQ_LOCK();          IPQ_LOCK();
         for (fp = LIST_FIRST(&ipq); fp != NULL; fp = nfp) {          for (i = 0; i < IPREASS_NHASH; i++) {
                 nfp = LIST_NEXT(fp, ipq_q);                  for (fp = LIST_FIRST(&ipq[i]); fp != NULL; fp = nfp) {
                 if (--fp->ipq_ttl == 0) {                          nfp = LIST_NEXT(fp, ipq_q);
                         ipstat.ips_fragtimeout++;                          if (--fp->ipq_ttl == 0) {
                         ip_freef(fp);                                  ipstat.ips_fragtimeout++;
                                   ip_freef(fp);
                           }
                 }                  }
         }          }
         /*          /*
          * If we are over the maximum number of fragments           * If we are over the maximum number of fragments
          * (due to the limit being lowered), drain off           * (due to the limit being lowered), drain off
          * enough to get down to the new limit.           * enough to get down to the new limit. Start draining
            * from the reassembly hashqueue most recently drained.
          */           */
         if (ip_maxfragpackets < 0)          if (ip_maxfragpackets < 0)
                 ;                  ;
         else {          else {
                 while (ip_nfragpackets > ip_maxfragpackets && LIST_FIRST(&ipq))                  int wrapped = 0;
                         ip_freef(LIST_FIRST(&ipq));  
                   i = dropscanidx;
                   while (ip_nfragpackets > ip_maxfragpackets && wrapped == 0) {
                           while (LIST_FIRST(&ipq[i]) != NULL)
                                   ip_freef(LIST_FIRST(&ipq[i]));
                           if (++i >= IPREASS_NHASH) {
                                   i = 0;
                           }
                           /*
                            * Dont scan forever even if fragment counters are
                            * wrong: stop after scanning entire reassembly queue.
                            */
                           if (i == dropscanidx)
                               wrapped = 1;
                   }
                   dropscanidx = i;
         }          }
         IPQ_UNLOCK();          IPQ_UNLOCK();
 #ifdef GATEWAY  #ifdef GATEWAY
Line 1206  ip_slowtimo()
Line 1244  ip_slowtimo()
 void  void
 ip_drain()  ip_drain()
 {  {
           int i;
   
         /*          /*
          * We may be called from a device's interrupt context.  If           * We may be called from a device's interrupt context.  If
Line 1214  ip_drain()
Line 1253  ip_drain()
         if (ipq_lock_try() == 0)          if (ipq_lock_try() == 0)
                 return;                  return;
   
         while (LIST_FIRST(&ipq) != NULL) {          for (i = 0; i < IPREASS_NHASH; i++) {
                 ipstat.ips_fragdropped++;                  struct ipqhead *ipqh = &ipq[i];
                 ip_freef(LIST_FIRST(&ipq));                  struct ipq *fp, *nfp;
                   for (fp = LIST_FIRST(ipqh); fp != NULL; fp = nfp) {
                           nfp = LIST_NEXT(fp, ipq_q);
                           ip_freef(fp);
                           ipstat.ips_fragdropped++;
                   }
         }          }
   
         IPQ_UNLOCK();          IPQ_UNLOCK();

Legend:
Removed from v.1.189  
changed lines
  Added in v.1.190

CVSweb <webmaster@jp.NetBSD.org>