[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.74.2.1 and 1.75

version 1.74.2.1, 1998/12/11 04:53:08 version 1.75, 1998/12/18 21:35:11
Line 164  struct ifqueue ipintrq;
Line 164  struct ifqueue ipintrq;
 struct  ipstat  ipstat;  struct  ipstat  ipstat;
 u_int16_t       ip_id;  u_int16_t       ip_id;
 int     ip_defttl;  int     ip_defttl;
   
 struct ipqhead ipq;  struct ipqhead ipq;
   int     ipq_locked;
   
   static __inline int ipq_lock_try __P((void));
   static __inline void ipq_unlock __P((void));
   
   static __inline int
   ipq_lock_try()
   {
           int s;
   
           s = splimp();
           if (ipq_locked) {
                   splx(s);
                   return (0);
           }
           ipq_locked = 1;
           splx(s);
           return (1);
   }
   
   static __inline void
   ipq_unlock()
   {
           int s;
   
           s = splimp();
           ipq_locked = 0;
           splx(s);
   }
   
   #ifdef DIAGNOSTIC
   #define IPQ_LOCK()                                                      \
   do {                                                                    \
           if (ipq_lock_try() == 0) {                                      \
                   printf("%s:%d: ipq already locked\n", __FILE__, __LINE__); \
                   panic("ipq_lock");                                      \
           }                                                               \
   } while (0)
   #define IPQ_LOCK_CHECK()                                                \
   do {                                                                    \
           if (ipq_locked == 0) {                                          \
                   printf("%s:%d: ipq lock not held\n", __FILE__, __LINE__); \
                   panic("ipq lock check");                                \
           }                                                               \
   } while (0)
   #else
   #define IPQ_LOCK()              (void) ipq_lock_try()
   #define IPQ_LOCK_CHECK()        /* nothing */
   #endif
   
   #define IPQ_UNLOCK()            ipq_unlock()
   
 struct pool ipqent_pool;  struct pool ipqent_pool;
   
Line 359  next:
Line 411  next:
         /*          /*
          * Check our list of addresses, to see if the packet is for us.           * Check our list of addresses, to see if the packet is for us.
          */           */
         s = splimp();  
         INADDR_TO_IA(ip->ip_dst, ia);          INADDR_TO_IA(ip->ip_dst, ia);
         if (ia != NULL) {          if (ia != NULL) goto ours;
                 ifa_delref(&ia->ia_ifa);  
                 splx(s);  
                 goto ours;  
         }  
         if (m->m_pkthdr.rcvif->if_flags & IFF_BROADCAST) {          if (m->m_pkthdr.rcvif->if_flags & IFF_BROADCAST) {
                 for (ifa = m->m_pkthdr.rcvif->if_addrlist.tqh_first;                  for (ifa = m->m_pkthdr.rcvif->if_addrlist.tqh_first;
                     ifa != NULL; ifa = ifa->ifa_list.tqe_next) {                      ifa != NULL; ifa = ifa->ifa_list.tqe_next) {
                         if (ifa->ifa_addr->sa_family != AF_INET) continue;                          if (ifa->ifa_addr->sa_family != AF_INET) continue;
                         ia = ifatoia(ifa);                          ia = ifatoia(ifa);
                         /*  
                          * Don't ifa_addref ia as we don't use it after  
                          * we splx(s) below  
                          */  
                         if (in_hosteq(ip->ip_dst, ia->ia_broadaddr.sin_addr) ||                          if (in_hosteq(ip->ip_dst, ia->ia_broadaddr.sin_addr) ||
                             in_hosteq(ip->ip_dst, ia->ia_netbroadcast) ||                              in_hosteq(ip->ip_dst, ia->ia_netbroadcast) ||
                             /*                              /*
Line 382  next:
Line 425  next:
                              * either for subnet or net.                               * either for subnet or net.
                              */                               */
                             ip->ip_dst.s_addr == ia->ia_subnet ||                              ip->ip_dst.s_addr == ia->ia_subnet ||
                             ip->ip_dst.s_addr == ia->ia_net) {                              ip->ip_dst.s_addr == ia->ia_net)
                                 splx(s);  
                                 goto ours;                                  goto ours;
                         }  
                         /*                          /*
                          * An interface with IP address zero accepts                           * An interface with IP address zero accepts
                          * all packets that arrive on that interface.                           * all packets that arrive on that interface.
                          */                           */
                         if (in_nullhost(ia->ia_addr.sin_addr)) {                          if (in_nullhost(ia->ia_addr.sin_addr))
                                 splx(s);  
                                 goto ours;                                  goto ours;
                         }  
                 }                  }
         }          }
         splx(s);  
         if (IN_MULTICAST(ip->ip_dst.s_addr)) {          if (IN_MULTICAST(ip->ip_dst.s_addr)) {
                 struct in_multi *inm;                  struct in_multi *inm;
 #ifdef MROUTING  #ifdef MROUTING
Line 480  ours:
Line 518  ours:
                  * Look for queue of fragments                   * Look for queue of fragments
                  * of this datagram.                   * of this datagram.
                  */                   */
                   IPQ_LOCK();
                 for (fp = ipq.lh_first; fp != NULL; fp = fp->ipq_q.le_next)                  for (fp = ipq.lh_first; fp != NULL; fp = fp->ipq_q.le_next)
                         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) &&
Line 503  found:
Line 542  found:
                          */                           */
                         if (ip->ip_len == 0 || (ip->ip_len & 0x7) != 0) {                          if (ip->ip_len == 0 || (ip->ip_len & 0x7) != 0) {
                                 ipstat.ips_badfrags++;                                  ipstat.ips_badfrags++;
                                   IPQ_UNLOCK();
                                 goto bad;                                  goto bad;
                         }                          }
                 }                  }
Line 518  found:
Line 558  found:
                         ipqe = pool_get(&ipqent_pool, PR_NOWAIT);                          ipqe = pool_get(&ipqent_pool, PR_NOWAIT);
                         if (ipqe == NULL) {                          if (ipqe == NULL) {
                                 ipstat.ips_rcvmemdrop++;                                  ipstat.ips_rcvmemdrop++;
                                   IPQ_UNLOCK();
                                 goto bad;                                  goto bad;
                         }                          }
                         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);
                         if (m == 0)                          if (m == 0) {
                                   IPQ_UNLOCK();
                                 goto next;                                  goto next;
                           }
                         ipstat.ips_reassembled++;                          ipstat.ips_reassembled++;
                         ip = mtod(m, struct ip *);                          ip = mtod(m, struct ip *);
                         hlen = ip->ip_hl << 2;                          hlen = ip->ip_hl << 2;
                 } else                  } else
                         if (fp)                          if (fp)
                                 ip_freef(fp);                                  ip_freef(fp);
                   IPQ_UNLOCK();
         } else          } else
                 ip->ip_len -= hlen;                  ip->ip_len -= hlen;
   
Line 564  ip_reass(ipqe, fp)
Line 608  ip_reass(ipqe, fp)
         int hlen = ipqe->ipqe_ip->ip_hl << 2;          int hlen = ipqe->ipqe_ip->ip_hl << 2;
         int i, next;          int i, next;
   
           IPQ_LOCK_CHECK();
   
         /*          /*
          * Presence of header sizes in mbufs           * Presence of header sizes in mbufs
          * would confuse code below.           * would confuse code below.
Line 718  ip_freef(fp)
Line 764  ip_freef(fp)
 {  {
         register struct ipqent *q, *p;          register struct ipqent *q, *p;
   
           IPQ_LOCK_CHECK();
   
         for (q = fp->ipq_fragq.lh_first; q != NULL; q = p) {          for (q = fp->ipq_fragq.lh_first; q != NULL; q = p) {
                 p = q->ipqe_q.le_next;                  p = q->ipqe_q.le_next;
                 m_freem(q->ipqe_m);                  m_freem(q->ipqe_m);
Line 739  ip_slowtimo()
Line 787  ip_slowtimo()
         register struct ipq *fp, *nfp;          register struct ipq *fp, *nfp;
         int s = splsoftnet();          int s = splsoftnet();
   
           IPQ_LOCK();
         for (fp = ipq.lh_first; fp != NULL; fp = nfp) {          for (fp = ipq.lh_first; fp != NULL; fp = nfp) {
                 nfp = fp->ipq_q.le_next;                  nfp = fp->ipq_q.le_next;
                 if (--fp->ipq_ttl == 0) {                  if (--fp->ipq_ttl == 0) {
Line 746  ip_slowtimo()
Line 795  ip_slowtimo()
                         ip_freef(fp);                          ip_freef(fp);
                 }                  }
         }          }
           IPQ_UNLOCK();
 #ifdef GATEWAY  #ifdef GATEWAY
         ipflow_slowtimo();          ipflow_slowtimo();
 #endif  #endif
Line 759  void
Line 809  void
 ip_drain()  ip_drain()
 {  {
   
           /*
            * We may be called from a device's interrupt context.  If
            * the ipq is already busy, just bail out now.
            */
           if (ipq_lock_try() == 0)
                   return;
   
         while (ipq.lh_first != NULL) {          while (ipq.lh_first != NULL) {
                 ipstat.ips_fragdropped++;                  ipstat.ips_fragdropped++;
                 ip_freef(ipq.lh_first);                  ip_freef(ipq.lh_first);
         }          }
   
           IPQ_UNLOCK();
 }  }
   
 /*  /*
Line 845  ip_dooptions(m)
Line 904  ip_dooptions(m)
                                  * End of source route.  Should be for us.                                   * End of source route.  Should be for us.
                                  */                                   */
                                 save_rte(cp, ip->ip_src);                                  save_rte(cp, ip->ip_src);
                                 ifa_delref(&ia->ia_ifa);  
                                 break;                                  break;
                         }                          }
                         /*                          /*
Line 853  ip_dooptions(m)
Line 911  ip_dooptions(m)
                          */                           */
                         bcopy((caddr_t)(cp + off), (caddr_t)&ipaddr.sin_addr,                          bcopy((caddr_t)(cp + off), (caddr_t)&ipaddr.sin_addr,
                             sizeof(ipaddr.sin_addr));                              sizeof(ipaddr.sin_addr));
                         ifa_delref(&ia->ia_ifa);  
                         if (opt == IPOPT_SSRR) {                          if (opt == IPOPT_SSRR) {
 #define INA     struct in_ifaddr *  #define INA     struct in_ifaddr *
 #define SA      struct sockaddr *  #define SA      struct sockaddr *
Line 873  ip_dooptions(m)
Line 930  ip_dooptions(m)
                          * Let ip_intr's mcast routing check handle mcast pkts                           * Let ip_intr's mcast routing check handle mcast pkts
                          */                           */
                         forward = !IN_MULTICAST(ip->ip_dst.s_addr);                          forward = !IN_MULTICAST(ip->ip_dst.s_addr);
                         ifa_delref(&ia->ia_ifa);  
                         break;                          break;
   
                 case IPOPT_RR:                  case IPOPT_RR:
Line 902  ip_dooptions(m)
Line 958  ip_dooptions(m)
                         bcopy((caddr_t)&ia->ia_addr.sin_addr,                          bcopy((caddr_t)&ia->ia_addr.sin_addr,
                             (caddr_t)(cp + off), sizeof(struct in_addr));                              (caddr_t)(cp + off), sizeof(struct in_addr));
                         cp[IPOPT_OFFSET] += sizeof(struct in_addr);                          cp[IPOPT_OFFSET] += sizeof(struct in_addr);
                         ifa_delref(&ia->ia_ifa);  
                         break;                          break;
   
                 case IPOPT_TS:                  case IPOPT_TS:
Line 932  ip_dooptions(m)
Line 987  ip_dooptions(m)
                                         continue;                                          continue;
                                 bcopy((caddr_t)&ia->ia_addr.sin_addr,                                  bcopy((caddr_t)&ia->ia_addr.sin_addr,
                                     (caddr_t)sin, sizeof(struct in_addr));                                      (caddr_t)sin, sizeof(struct in_addr));
                                 ifa_delref(&ia->ia_ifa);  
                                 ipt->ipt_ptr += sizeof(struct in_addr);                                  ipt->ipt_ptr += sizeof(struct in_addr);
                                 break;                                  break;
   
Line 942  ip_dooptions(m)
Line 996  ip_dooptions(m)
                                         goto bad;                                          goto bad;
                                 bcopy((caddr_t)sin, (caddr_t)&ipaddr.sin_addr,                                  bcopy((caddr_t)sin, (caddr_t)&ipaddr.sin_addr,
                                     sizeof(struct in_addr));                                      sizeof(struct in_addr));
                                 ia = (INA)ifa_ifwithaddr((SA)&ipaddr);                                  if (ifa_ifwithaddr((SA)&ipaddr) == 0)
                                 if (ia == 0)  
                                         continue;                                          continue;
                                 ifa_delref(&ia->ia_ifa);  
                                 ipt->ipt_ptr += sizeof(struct in_addr);                                  ipt->ipt_ptr += sizeof(struct in_addr);
                                 break;                                  break;
   
Line 984  ip_rtaddr(dst)
Line 1036  ip_rtaddr(dst)
          struct in_addr dst;           struct in_addr dst;
 {  {
         register struct sockaddr_in *sin;          register struct sockaddr_in *sin;
         struct in_ifaddr *ia;  
         int s;  
   
         sin = satosin(&ipforward_rt.ro_dst);          sin = satosin(&ipforward_rt.ro_dst);
   
Line 1002  ip_rtaddr(dst)
Line 1052  ip_rtaddr(dst)
         }          }
         if (ipforward_rt.ro_rt == 0)          if (ipforward_rt.ro_rt == 0)
                 return ((struct in_ifaddr *)0);                  return ((struct in_ifaddr *)0);
         s = splimp();          return (ifatoia(ipforward_rt.ro_rt->rt_ifa));
         ia = (ifatoia(ipforward_rt.ro_rt->rt_ifa));  
         ifa_addref(&ia->ia_ifa);  
         splx(s);  
         return ia;  
 }  }
   
 /*  /*

Legend:
Removed from v.1.74.2.1  
changed lines
  Added in v.1.75

CVSweb <webmaster@jp.NetBSD.org>