Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/netinet/ip_input.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/netinet/ip_input.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.275.2.2 retrieving revision 1.284.2.1 diff -u -p -r1.275.2.2 -r1.284.2.1 --- src/sys/netinet/ip_input.c 2009/04/28 07:37:22 1.275.2.2 +++ src/sys/netinet/ip_input.c 2010/04/30 14:44:21 1.284.2.1 @@ -1,4 +1,4 @@ -/* $NetBSD: ip_input.c,v 1.275.2.2 2009/04/28 07:37:22 skrll Exp $ */ +/* $NetBSD: ip_input.c,v 1.284.2.1 2010/04/30 14:44:21 uebayasi Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -91,7 +91,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.275.2.2 2009/04/28 07:37:22 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.284.2.1 2010/04/30 14:44:21 uebayasi Exp $"); #include "opt_inet.h" #include "opt_compat_netbsd.h" @@ -231,6 +231,7 @@ u_long in_multihash; /* size of hash int in_multientries; /* total number of addrs */ struct in_multihashhead *in_multihashtbl; struct ifqueue ipintrq; + uint16_t ip_id; percpu_t *ipstat_percpu; @@ -383,6 +384,8 @@ struct mowner ip_rx_mowner = MOWNER_INIT struct mowner ip_tx_mowner = MOWNER_INIT("internet", "tx"); #endif +static void sysctl_net_inet_ip_setup(struct sysctllog **); + /* * Compute IP limits derived from the value of nmbclusters. */ @@ -403,6 +406,8 @@ ip_init(void) const struct protosw *pr; int i; + sysctl_net_inet_ip_setup(NULL); + pool_init(&inmulti_pool, sizeof(struct in_multi), 0, 0, 0, "inmltpl", NULL, IPL_SOFTNET); pool_init(&ipqent_pool, sizeof(struct ipqent), 0, 0, 0, "ipqepl", @@ -470,18 +475,35 @@ ipintr(void) { int s; struct mbuf *m; + struct ifqueue lcl_intrq; + + memset(&lcl_intrq, 0, sizeof(lcl_intrq)); + ipintrq.ifq_maxlen = ipqmaxlen; mutex_enter(softnet_lock); KERNEL_LOCK(1, NULL); - while (!IF_IS_EMPTY(&ipintrq)) { + if (!IF_IS_EMPTY(&ipintrq)) { s = splnet(); - IF_DEQUEUE(&ipintrq, m); + + /* Take existing queue onto stack */ + lcl_intrq = ipintrq; + + /* Zero out global queue, preserving maxlen and drops */ + ipintrq.ifq_head = NULL; + ipintrq.ifq_tail = NULL; + ipintrq.ifq_len = 0; + ipintrq.ifq_maxlen = lcl_intrq.ifq_maxlen; + ipintrq.ifq_drops = lcl_intrq.ifq_drops; + splx(s); + } + KERNEL_UNLOCK_ONE(NULL); + while (!IF_IS_EMPTY(&lcl_intrq)) { + IF_DEQUEUE(&lcl_intrq, m); if (m == NULL) break; ip_input(m); } - KERNEL_UNLOCK_ONE(NULL); mutex_exit(softnet_lock); } @@ -2057,9 +2079,9 @@ ip_savecontrol(struct inpcb *inp, struct struct mbuf *m) { - if (inp->inp_socket->so_options & SO_TIMESTAMP + if (inp->inp_socket->so_options & SO_TIMESTAMP #ifdef SO_OTIMESTAMP - || inp->inp_socket->so_options & SO_OTIMESTAMP + || inp->inp_socket->so_options & SO_OTIMESTAMP #endif ) { struct timeval tv; @@ -2118,6 +2140,12 @@ ip_savecontrol(struct inpcb *inp, struct if (*mp) mp = &(*mp)->m_next; } + if (inp->inp_flags & INP_RECVTTL) { + *mp = sbcreatecontrol((void *) &ip->ip_ttl, + sizeof(uint8_t), IP_RECVTTL, IPPROTO_IP); + if (*mp) + mp = &(*mp)->m_next; + } } /* @@ -2201,7 +2229,7 @@ sysctl_net_inet_ip_maxflows(SYSCTLFN_ARG static int sysctl_net_inet_ip_hashsize(SYSCTLFN_ARGS) -{ +{ int error, tmp; struct sysctlnode node; @@ -2229,7 +2257,7 @@ sysctl_net_inet_ip_hashsize(SYSCTLFN_ARG * EINVAL if not a power of 2 */ error = EINVAL; - } + } return error; } @@ -2242,7 +2270,8 @@ sysctl_net_inet_ip_stats(SYSCTLFN_ARGS) return (NETSTAT_SYSCTL(ipstat_percpu, IP_NSTATS)); } -SYSCTL_SETUP(sysctl_net_inet_ip_setup, "sysctl net.inet.ip subtree setup") +static void +sysctl_net_inet_ip_setup(struct sysctllog **clog) { extern int subnetsarelocal, hostzeroisbroadcast;