[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.284.2.2 and 1.302.2.1

version 1.284.2.2, 2010/08/17 06:47:46 version 1.302.2.1, 2013/02/25 00:30:04
Line 139  __KERNEL_RCSID(0, "$NetBSD$");
Line 139  __KERNEL_RCSID(0, "$NetBSD$");
 #ifdef MROUTING  #ifdef MROUTING
 #include <netinet/ip_mroute.h>  #include <netinet/ip_mroute.h>
 #endif  #endif
   #include <netinet/portalgo.h>
   
 #ifdef IPSEC  
 #include <netinet6/ipsec.h>  
 #include <netinet6/ipsec_private.h>  
 #include <netkey/key.h>  
 #endif  
 #ifdef FAST_IPSEC  #ifdef FAST_IPSEC
 #include <netipsec/ipsec.h>  #include <netipsec/ipsec.h>
 #include <netipsec/key.h>  #include <netipsec/key.h>
Line 221  int ip_checkinterface = 0;
Line 217  int ip_checkinterface = 0;
   
 struct rttimer_queue *ip_mtudisc_timeout_q = NULL;  struct rttimer_queue *ip_mtudisc_timeout_q = NULL;
   
 int     ipqmaxlen = IFQ_MAXLEN;  
 u_long  in_ifaddrhash;                          /* size of hash table - 1 */  u_long  in_ifaddrhash;                          /* size of hash table - 1 */
 int     in_ifaddrentries;                       /* total number of addrs */  int     in_ifaddrentries;                       /* total number of addrs */
 struct in_ifaddrhead in_ifaddrhead;  struct in_ifaddrhead in_ifaddrhead;
Line 231  int in_multientries;   /* total number o
Line 226  int in_multientries;   /* total number o
 struct  in_multihashhead *in_multihashtbl;  struct  in_multihashhead *in_multihashtbl;
 struct  ifqueue ipintrq;  struct  ifqueue ipintrq;
   
   ipid_state_t *          ip_ids;
 uint16_t ip_id;  uint16_t ip_id;
   
 percpu_t *ipstat_percpu;  percpu_t *ipstat_percpu;
Line 278  static struct ip_srcrt {
Line 274  static struct ip_srcrt {
         struct  in_addr route[MAX_IPOPTLEN/sizeof(struct in_addr)];          struct  in_addr route[MAX_IPOPTLEN/sizeof(struct in_addr)];
 } ip_srcrt;  } ip_srcrt;
   
   static int ip_drainwanted;
   
 static void save_rte(u_char *, struct in_addr);  static void save_rte(u_char *, struct in_addr);
   
 #ifdef MBUFTRACE  #ifdef MBUFTRACE
Line 315  ip_init(void)
Line 313  ip_init(void)
   
         ip_reass_init();          ip_reass_init();
   
         ip_initid();          ip_ids = ip_id_init();
         ip_id = time_second & 0xfffff;          ip_id = time_second & 0xfffff;
   
         ipintrq.ifq_maxlen = ipqmaxlen;          ipintrq.ifq_maxlen = IFQ_MAXLEN;
   
         TAILQ_INIT(&in_ifaddrhead);          TAILQ_INIT(&in_ifaddrhead);
         in_ifaddrhashtbl = hashinit(IN_IFADDR_HASH_SIZE, HASH_LIST, true,          in_ifaddrhashtbl = hashinit(IN_IFADDR_HASH_SIZE, HASH_LIST, true,
Line 365  ipintr(void)
Line 363  ipintr(void)
         struct ifqueue lcl_intrq;          struct ifqueue lcl_intrq;
   
         memset(&lcl_intrq, 0, sizeof(lcl_intrq));          memset(&lcl_intrq, 0, sizeof(lcl_intrq));
         ipintrq.ifq_maxlen = ipqmaxlen;  
   
         mutex_enter(softnet_lock);          mutex_enter(softnet_lock);
         KERNEL_LOCK(1, NULL);          KERNEL_LOCK(1, NULL);
Line 455  ip_input(struct mbuf *m)
Line 452  ip_input(struct mbuf *m)
                 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)) == NULL) {
                         IP_STATINC(IP_STAT_BADHLEN);                          IP_STATINC(IP_STAT_BADHLEN);
                         return;                          return;
                 }                  }
Line 535  ip_input(struct mbuf *m)
Line 532  ip_input(struct mbuf *m)
                         m_adj(m, len - m->m_pkthdr.len);                          m_adj(m, len - m->m_pkthdr.len);
         }          }
   
 #if defined(IPSEC)  
         /* ipflow (IP fast forwarding) is not compatible with IPsec. */  
         m->m_flags &= ~M_CANFASTFWD;  
 #else  
         /*          /*
          * Assume that we can create a fast-forward IP flow entry           * Assume that we can create a fast-forward IP flow entry
          * based on this packet.           * based on this packet.
          */           */
         m->m_flags |= M_CANFASTFWD;          m->m_flags |= M_CANFASTFWD;
 #endif  
   
 #ifdef PFIL_HOOKS  #ifdef PFIL_HOOKS
         /*          /*
Line 558  ip_input(struct mbuf *m)
Line 550  ip_input(struct mbuf *m)
          * let ipfilter look at packet on the wire,           * let ipfilter look at packet on the wire,
          * not the decapsulated packet.           * not the decapsulated packet.
          */           */
 #ifdef IPSEC  #if defined(FAST_IPSEC)
         if (!ipsec_getnhist(m))  
 #elif defined(FAST_IPSEC)  
         if (!ipsec_indone(m))          if (!ipsec_indone(m))
 #else  #else
         if (1)          if (1)
Line 742  ip_input(struct mbuf *m)
Line 732  ip_input(struct mbuf *m)
                         IP_STATINC(IP_STAT_CANTFORWARD);                          IP_STATINC(IP_STAT_CANTFORWARD);
                         return;                          return;
                 }                  }
 #ifdef IPSEC  
                 if (ipsec4_in_reject(m, NULL)) {  
                         IPSEC_STATINC(IPSEC_STAT_IN_POLVIO);  
                         goto bad;  
                 }  
 #endif  
 #ifdef FAST_IPSEC  #ifdef FAST_IPSEC
                 mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL);                  mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL);
                 s = splsoftnet();                  s = splsoftnet();
Line 806  ours:
Line 790  ours:
          * If offset or IP_MF are set, must reassemble.           * If offset or IP_MF are set, must reassemble.
          */           */
         if (ip->ip_off & ~htons(IP_DF|IP_RF)) {          if (ip->ip_off & ~htons(IP_DF|IP_RF)) {
                 struct mbuf *m_final;  
                 u_int off, flen;  
                 bool mff;  
   
                 /*  
                  * Prevent TCP blind data attacks by not allowing non-initial  
                  * fragments to start at less than 68 bytes (minimal fragment  
                  * size) and making sure the first fragment is at least 68  
                  * bytes.  
                  */  
                 off = (ntohs(ip->ip_off) & IP_OFFMASK) << 3;  
                 if ((off > 0 ? off + hlen : len) < IP_MINFRAGSIZE - 1) {  
                         IP_STATINC(IP_STAT_BADFRAGS);  
                         goto bad;  
                 }  
   
                 /* Fragment length and MF flag. */  
                 flen = ntohs(ip->ip_len) - hlen;  
                 mff = (ip->ip_off & htons(IP_MF)) != 0;  
                 if (mff) {  
                         /*  
                          * Make sure that fragments have a data length  
                          * which is non-zero and multiple of 8 bytes.  
                          */  
                         if (flen == 0 || (flen & 0x7) != 0) {  
                                 IP_STATINC(IP_STAT_BADFRAGS);  
                                 goto bad;  
                         }  
                 }  
   
                 /*  
                  * Adjust total IP length to not reflect header and convert  
                  * offset of this to bytes.  XXX: clobbers struct ip.  
                  */  
                 ip->ip_len = htons(flen);  
                 ip->ip_off = htons(off);  
   
                 /*                  /*
                  * Pass to IP reassembly mechanism.                   * Pass to IP reassembly mechanism.
                  */                   */
                 if (ip_reass_packet(m, ip, mff, &m_final) != 0) {                  if (ip_reass_packet(&m, ip) != 0) {
                         /* Failed; invalid fragment(s) or packet. */                          /* Failed; invalid fragment(s) or packet. */
                         goto bad;                          goto bad;
                 }                  }
                 if (m_final == NULL) {                  if (m == NULL) {
                         /* More fragments should come; silently return. */                          /* More fragments should come; silently return. */
                         return;                          return;
                 }                  }
                 /* Reassembly is done, we have the final packet. */                  /*
                 m = m_final;                   * Reassembly is done, we have the final packet.
                    * Updated cached data in local variable(s).
                 /* Updated local variable(s). */                   */
                 ip = mtod(m, struct ip *);                  ip = mtod(m, struct ip *);
                 hlen = ip->ip_hl << 2;                  hlen = ip->ip_hl << 2;
         }          }
   
 #if defined(IPSEC)  
         /*  
          * enforce IPsec policy checking if we are seeing last header.  
          * note that we do not visit this with protocols with pcb layer  
          * code - like udp/tcp/raw ip.  
          */  
         if ((inetsw[ip_protox[ip->ip_p]].pr_flags & PR_LASTHDR) != 0 &&  
             ipsec4_in_reject(m, NULL)) {  
                 IPSEC_STATINC(IPSEC_STAT_IN_POLVIO);  
                 goto bad;  
         }  
 #endif  
 #ifdef FAST_IPSEC  #ifdef FAST_IPSEC
         /*          /*
          * enforce IPsec policy checking if we are seeing last header.           * enforce IPsec policy checking if we are seeing last header.
Line 1320  const int inetctlerrmap[PRC_NCMDS] = {
Line 1255  const int inetctlerrmap[PRC_NCMDS] = {
         [PRC_PARAMPROB] = ENOPROTOOPT,          [PRC_PARAMPROB] = ENOPROTOOPT,
 };  };
   
   void
   ip_fasttimo(void)
   {
           if (ip_drainwanted) {
                   ip_drain();
                   ip_drainwanted = 0;
           }
   }
   
   void
   ip_drainstub(void)
   {
           ip_drainwanted = 1;
   }
   
 /*  /*
  * Forward a packet.  If some error occurs return the sender   * Forward a packet.  If some error occurs return the sender
  * an icmp packet.  Note we can't always generate a meaningful   * an icmp packet.  Note we can't always generate a meaningful
Line 1426  ip_forward(struct mbuf *m, int srcrt)
Line 1376  ip_forward(struct mbuf *m, int srcrt)
   
         error = ip_output(m, NULL, &ipforward_rt,          error = ip_output(m, NULL, &ipforward_rt,
             (IP_FORWARDING | (ip_directedbcast ? IP_ALLOWBROADCAST : 0)),              (IP_FORWARDING | (ip_directedbcast ? IP_ALLOWBROADCAST : 0)),
             (struct ip_moptions *)NULL, (struct socket *)NULL);              NULL, NULL);
   
         if (error)          if (error)
                 IP_STATINC(IP_STAT_CANTFORWARD);                  IP_STATINC(IP_STAT_CANTFORWARD);
Line 1473  ip_forward(struct mbuf *m, int srcrt)
Line 1423  ip_forward(struct mbuf *m, int srcrt)
                 if ((rt = rtcache_validate(&ipforward_rt)) != NULL)                  if ((rt = rtcache_validate(&ipforward_rt)) != NULL)
                         destmtu = rt->rt_ifp->if_mtu;                          destmtu = rt->rt_ifp->if_mtu;
   
 #if defined(IPSEC) || defined(FAST_IPSEC)  #if defined(FAST_IPSEC)
                 {                  {
                         /*                          /*
                          * If the packet is routed over IPsec tunnel, tell the                           * If the packet is routed over IPsec tunnel, tell the
Line 1515  ip_forward(struct mbuf *m, int srcrt)
Line 1465  ip_forward(struct mbuf *m, int srcrt)
                                         }                                          }
                                 }                                  }
   
 #ifdef  IPSEC  
                                 key_freesp(sp);  
 #else  
                                 KEY_FREESP(&sp);                                  KEY_FREESP(&sp);
 #endif  
                         }                          }
                 }                  }
 #endif /*defined(IPSEC) || defined(FAST_IPSEC)*/  #endif /*defined(FAST_IPSEC)*/
                 IP_STATINC(IP_STAT_CANTFRAG);                  IP_STATINC(IP_STAT_CANTFRAG);
                 break;                  break;
   
Line 1850  sysctl_net_inet_ip_setup(struct sysctllo
Line 1796  sysctl_net_inet_ip_setup(struct sysctllo
                        CTLFLAG_PERMANENT|CTLFLAG_READWRITE,                         CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
                        CTLTYPE_INT, "mtudisctimeout",                         CTLTYPE_INT, "mtudisctimeout",
                        SYSCTL_DESCR("Lifetime of a Path MTU Discovered route"),                         SYSCTL_DESCR("Lifetime of a Path MTU Discovered route"),
                        sysctl_net_inet_ip_pmtudto, 0, &ip_mtudisc_timeout, 0,                         sysctl_net_inet_ip_pmtudto, 0, (void *)&ip_mtudisc_timeout, 0,
                        CTL_NET, PF_INET, IPPROTO_IP,                         CTL_NET, PF_INET, IPPROTO_IP,
                        IPCTL_MTUDISCTIMEOUT, CTL_EOL);                         IPCTL_MTUDISCTIMEOUT, CTL_EOL);
 #ifdef GATEWAY  #ifdef GATEWAY
Line 1941  sysctl_net_inet_ip_setup(struct sysctllo
Line 1887  sysctl_net_inet_ip_setup(struct sysctllo
                        sysctl_net_inet_ip_stats, 0, NULL, 0,                         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);
   
           /* anonportalgo RFC6056 subtree */
           const struct sysctlnode *portalgo_node;
           sysctl_createv(clog, 0, NULL, &portalgo_node,
                          CTLFLAG_PERMANENT,
                          CTLTYPE_NODE, "anonportalgo",
                          SYSCTL_DESCR("Anonymous Port Algorithm Selection (RFC 6056)"),
                          NULL, 0, NULL, 0,
                          CTL_NET, PF_INET, IPPROTO_IP, CTL_CREATE, CTL_EOL);
           sysctl_createv(clog, 0, &portalgo_node, NULL,
                          CTLFLAG_PERMANENT,
                          CTLTYPE_STRING, "available",
                          SYSCTL_DESCR("available algorithms"),
                          sysctl_portalgo_available, 0, NULL, PORTALGO_MAXLEN,
                          CTL_CREATE, CTL_EOL);
           sysctl_createv(clog, 0, &portalgo_node, NULL,
                          CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
                          CTLTYPE_STRING, "selected",
                          SYSCTL_DESCR("selected algorithm"),
                          sysctl_portalgo_selected4, 0, NULL, PORTALGO_MAXLEN,
                          CTL_CREATE, CTL_EOL);
           sysctl_createv(clog, 0, &portalgo_node, NULL,
                          CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
                          CTLTYPE_STRUCT, "reserve",
                          SYSCTL_DESCR("bitmap of reserved ports"),
                          sysctl_portalgo_reserve4, 0, NULL, 0,
                          CTL_CREATE, CTL_EOL);
 }  }
   
 void  void

Legend:
Removed from v.1.284.2.2  
changed lines
  Added in v.1.302.2.1

CVSweb <webmaster@jp.NetBSD.org>