summaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-04-28 01:09:25 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-04-28 01:09:25 +0000
commitb9ba7aeb165cffecdffb60aec8c3fa8d590d9ca9 (patch)
tree42d07b0c7246ae2536a702e7c5de9e2732341116 /net/ipv4
parent7406b0a326f2d70ade2671c37d1beef62249db97 (diff)
Merge with 2.3.99-pre6.
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/af_inet.c72
-rw-r--r--net/ipv4/arp.c31
-rw-r--r--net/ipv4/fib_rules.c5
-rw-r--r--net/ipv4/icmp.c22
-rw-r--r--net/ipv4/ip_fragment.c9
-rw-r--r--net/ipv4/ip_input.c12
-rw-r--r--net/ipv4/ipconfig.c29
-rw-r--r--net/ipv4/netfilter/ip_conntrack_core.c54
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_generic.c5
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_icmp.c6
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_tcp.c12
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_udp.c6
-rw-r--r--net/ipv4/netfilter/ip_conntrack_standalone.c20
-rw-r--r--net/ipv4/netfilter/ip_nat_standalone.c22
-rw-r--r--net/ipv4/netfilter/ip_queue.c2
-rw-r--r--net/ipv4/netfilter/ip_tables.c24
-rw-r--r--net/ipv4/netfilter/ipchains_core.c14
-rw-r--r--net/ipv4/netfilter/ipfwadm_core.c7
-rw-r--r--net/ipv4/netfilter/ipt_LOG.c15
-rw-r--r--net/ipv4/proc.c10
-rw-r--r--net/ipv4/raw.c36
-rw-r--r--net/ipv4/route.c60
-rw-r--r--net/ipv4/tcp.c30
-rw-r--r--net/ipv4/tcp_input.c15
-rw-r--r--net/ipv4/tcp_ipv4.c44
-rw-r--r--net/ipv4/tcp_output.c23
-rw-r--r--net/ipv4/tcp_timer.c87
-rw-r--r--net/ipv4/udp.c33
28 files changed, 396 insertions, 309 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index d3fc0e38f..40aa7cd3a 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -5,7 +5,7 @@
*
* PF_INET protocol family socket handler.
*
- * Version: $Id: af_inet.c,v 1.109 2000/03/25 01:55:10 davem Exp $
+ * Version: $Id: af_inet.c,v 1.110 2000/04/25 04:13:34 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -893,45 +893,43 @@ static int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
}
struct proto_ops inet_stream_ops = {
- PF_INET,
-
- inet_release,
- inet_bind,
- inet_stream_connect,
- sock_no_socketpair,
- inet_accept,
- inet_getname,
- tcp_poll,
- inet_ioctl,
- inet_listen,
- inet_shutdown,
- inet_setsockopt,
- inet_getsockopt,
- sock_no_fcntl,
- inet_sendmsg,
- inet_recvmsg,
- sock_no_mmap
+ family: PF_INET,
+
+ release: inet_release,
+ bind: inet_bind,
+ connect: inet_stream_connect,
+ socketpair: sock_no_socketpair,
+ accept: inet_accept,
+ getname: inet_getname,
+ poll: tcp_poll,
+ ioctl: inet_ioctl,
+ listen: inet_listen,
+ shutdown: inet_shutdown,
+ setsockopt: inet_setsockopt,
+ getsockopt: inet_getsockopt,
+ sendmsg: inet_sendmsg,
+ recvmsg: inet_recvmsg,
+ mmap: sock_no_mmap
};
struct proto_ops inet_dgram_ops = {
- PF_INET,
-
- inet_release,
- inet_bind,
- inet_dgram_connect,
- sock_no_socketpair,
- sock_no_accept,
- inet_getname,
- datagram_poll,
- inet_ioctl,
- sock_no_listen,
- inet_shutdown,
- inet_setsockopt,
- inet_getsockopt,
- sock_no_fcntl,
- inet_sendmsg,
- inet_recvmsg,
- sock_no_mmap
+ family: PF_INET,
+
+ release: inet_release,
+ bind: inet_bind,
+ connect: inet_dgram_connect,
+ socketpair: sock_no_socketpair,
+ accept: sock_no_accept,
+ getname: inet_getname,
+ poll: datagram_poll,
+ ioctl: inet_ioctl,
+ listen: sock_no_listen,
+ shutdown: inet_shutdown,
+ setsockopt: inet_setsockopt,
+ getsockopt: inet_getsockopt,
+ sendmsg: inet_sendmsg,
+ recvmsg: inet_recvmsg,
+ mmap: sock_no_mmap,
};
struct net_proto_family inet_family_ops = {
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 588cdf030..9def6b16b 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -1,6 +1,6 @@
/* linux/net/inet/arp.c
*
- * Version: $Id: arp.c,v 1.84 2000/01/18 08:24:14 davem Exp $
+ * Version: $Id: arp.c,v 1.86 2000/04/26 09:36:36 davem Exp $
*
* Copyright (C) 1994 by Florian La Roche
*
@@ -1021,7 +1021,6 @@ static int arp_get_info(char *buffer, char **start, off_t offset, int length)
char hbuffer[HBUFFERLEN];
int i,j,k;
const char hexbuf[] = "0123456789ABCDEF";
- char abuf[16];
size = sprintf(buffer,"IP address HW type Flags HW address Mask Device\n");
@@ -1060,15 +1059,21 @@ static int arp_get_info(char *buffer, char **start, off_t offset, int length)
}
#endif
- size = sprintf(buffer+len,
- "%-17s0x%-10x0x%-10x%s",
- in_ntoa2(*(u32*)n->primary_key, abuf),
- hatype,
- arp_state_to_flags(n),
- hbuffer);
- size += sprintf(buffer+len+size,
- " %-17s %s\n",
- "*", dev->name);
+ {
+ char tbuf[16];
+ sprintf(tbuf, "%u.%u.%u.%u", NIPQUAD(*(u32*)n->primary_key));
+
+ size = sprintf(buffer+len, "%-16s 0x%-10x0x%-10x%s",
+ tbuf,
+ hatype,
+ arp_state_to_flags(n),
+ hbuffer);
+
+ size += sprintf(buffer+len+size,
+ " %-8s %s\n",
+ "*", dev->name);
+ }
+
read_unlock(&n->lock);
len += size;
@@ -1091,8 +1096,8 @@ static int arp_get_info(char *buffer, char **start, off_t offset, int length)
int hatype = dev ? dev->type : 0;
size = sprintf(buffer+len,
- "%-17s0x%-10x0x%-10x%s",
- in_ntoa2(*(u32*)n->key, abuf),
+ "%u.%u.%u.%u0x%-10x0x%-10x%s",
+ NIPQUAD(*(u32*)n->key),
hatype,
ATF_PUBL|ATF_PERM,
"00:00:00:00:00:00");
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index 5ee1bfd78..03095f1a2 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -5,7 +5,7 @@
*
* IPv4 Forwarding Information Base: policy rules.
*
- * Version: $Id: fib_rules.c,v 1.14 1999/08/31 07:03:29 davem Exp $
+ * Version: $Id: fib_rules.c,v 1.15 2000/04/15 01:48:10 davem Exp $
*
* Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
*
@@ -298,7 +298,8 @@ int fib_lookup(const struct rt_key *key, struct fib_result *res)
u32 daddr = key->dst;
u32 saddr = key->src;
-FRprintk("Lookup: %08x <- %08x ", key->dst, key->src);
+FRprintk("Lookup: %u.%u.%u.%u <- %u.%u.%u.%u ",
+ NIPQUAD(key->dst), NIPQUAD(key->src));
read_lock(&fib_rules_lock);
for (r = fib_rules; r; r=r->r_next) {
if (((saddr^r->r_src) & r->r_srcmask) ||
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 7c462ac08..f15d94388 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -3,7 +3,7 @@
*
* Alan Cox, <alan@redhat.com>
*
- * Version: $Id: icmp.c,v 1.67 2000/03/25 01:55:11 davem Exp $
+ * Version: $Id: icmp.c,v 1.69 2000/04/15 01:48:10 davem Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -521,9 +521,12 @@ void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb)
}
if (ip_route_output(&rt, daddr, rt->rt_spec_dst, RT_TOS(skb->nh.iph->tos), 0))
goto out;
- ip_build_xmit(sk, icmp_glue_bits, icmp_param,
- icmp_param->data_len+sizeof(struct icmphdr),
- &ipc, rt, MSG_DONTWAIT);
+ if (icmpv4_xrlim_allow(rt, icmp_param->icmph.type,
+ icmp_param->icmph.code)) {
+ ip_build_xmit(sk, icmp_glue_bits, icmp_param,
+ icmp_param->data_len+sizeof(struct icmphdr),
+ &ipc, rt, MSG_DONTWAIT);
+ }
ip_rt_put(rt);
out:
icmp_xmit_unlock_bh();
@@ -720,7 +723,7 @@ static void icmp_unreach(struct icmphdr *icmph, struct sk_buff *skb, int len)
case ICMP_FRAG_NEEDED:
if (ipv4_config.no_pmtu_disc) {
if (net_ratelimit())
- printk(KERN_INFO "ICMP: %d.%d.%d.%d: fragmentation needed and DF set.\n",
+ printk(KERN_INFO "ICMP: %u.%u.%u.%u: fragmentation needed and DF set.\n",
NIPQUAD(iph->daddr));
} else {
unsigned short new_mtu;
@@ -732,7 +735,7 @@ static void icmp_unreach(struct icmphdr *icmph, struct sk_buff *skb, int len)
break;
case ICMP_SR_FAILED:
if (net_ratelimit())
- printk(KERN_INFO "ICMP: %d.%d.%d.%d: Source Route Failed.\n", NIPQUAD(iph->daddr));
+ printk(KERN_INFO "ICMP: %u.%u.%u.%u: Source Route Failed.\n", NIPQUAD(iph->daddr));
break;
default:
break;
@@ -762,7 +765,7 @@ static void icmp_unreach(struct icmphdr *icmph, struct sk_buff *skb, int len)
if (inet_addr_type(iph->daddr) == RTN_BROADCAST)
{
if (net_ratelimit())
- printk(KERN_WARNING "%d.%d.%d.%d sent an invalid ICMP error to a broadcast.\n",
+ printk(KERN_WARNING "%u.%u.%u.%u sent an invalid ICMP error to a broadcast.\n",
NIPQUAD(skb->nh.iph->saddr));
return;
}
@@ -983,9 +986,8 @@ static void icmp_address_reply(struct icmphdr *icmph, struct sk_buff *skb, int l
break;
}
if (!ifa && net_ratelimit()) {
- char b1[16], b2[16];
- printk(KERN_INFO "Wrong address mask %s from %s/%s\n",
- in_ntoa2(mask, b1), in_ntoa2(rt->rt_src, b2), dev->name);
+ printk(KERN_INFO "Wrong address mask %u.%u.%u.%u from %s/%u.%u.%u.%u\n",
+ NIPQUAD(mask), dev->name, NIPQUAD(rt->rt_src));
}
}
read_unlock(&in_dev->lock);
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index 852a4fb2c..70f8cfb90 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -5,7 +5,7 @@
*
* The IP fragmentation functionality.
*
- * Version: $Id: ip_fragment.c,v 1.47 2000/02/09 21:11:33 davem Exp $
+ * Version: $Id: ip_fragment.c,v 1.49 2000/04/15 01:48:10 davem Exp $
*
* Authors: Fred N. van Kempen <waltje@uWalt.NL.Mugnet.ORG>
* Alan Cox <Alan.Cox@linux.org>
@@ -387,9 +387,14 @@ static struct sk_buff *ip_glue(struct ipq *qp)
*/
skb->security = qp->fragments->skb->security;
+#ifdef CONFIG_NETFILTER
+ /* Connection association is same as fragment (if any). */
+ skb->nfct = qp->fragments->skb->nfct;
+ nf_conntrack_get(skb->nfct);
#ifdef CONFIG_NETFILTER_DEBUG
skb->nf_debug = qp->fragments->skb->nf_debug;
#endif
+#endif
/* Done with all fragments. Fixup the new IP header. */
iph = skb->nh.iph;
@@ -594,7 +599,7 @@ out:
*/
out_oversize:
if (net_ratelimit())
- printk(KERN_INFO "Oversized packet received from %d.%d.%d.%d\n",
+ printk(KERN_INFO "Oversized packet received from %u.%u.%u.%u\n",
NIPQUAD(iph->saddr));
/* the skb isn't in a fragment, so fall through to free it */
out_freeskb:
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index 0c755dbcd..700bb24f7 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -5,7 +5,7 @@
*
* The Internet Protocol (IP) module.
*
- * Version: $Id: ip_input.c,v 1.46 2000/02/22 23:54:26 davem Exp $
+ * Version: $Id: ip_input.c,v 1.48 2000/04/15 01:48:10 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -162,7 +162,13 @@ int ip_call_ra_chain(struct sk_buff *skb)
read_lock(&ip_ra_lock);
for (ra = ip_ra_chain; ra; ra = ra->next) {
struct sock *sk = ra->sk;
- if (sk && sk->num == protocol) {
+
+ /* If socket is bound to an interface, only report
+ * the packet if it came from that interface.
+ */
+ if (sk && sk->num == protocol
+ && ((sk->bound_dev_if == 0)
+ || (sk->bound_dev_if == skb->dev->ifindex))) {
if (skb->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
skb = ip_defrag(skb);
if (skb == NULL) {
@@ -349,7 +355,7 @@ static inline int ip_rcv_finish(struct sk_buff *skb)
if (in_dev) {
if (!IN_DEV_SOURCE_ROUTE(in_dev)) {
if (IN_DEV_LOG_MARTIANS(in_dev) && net_ratelimit())
- printk(KERN_INFO "source route option %d.%d.%d.%d -> %d.%d.%d.%d\n",
+ printk(KERN_INFO "source route option %u.%u.%u.%u -> %u.%u.%u.%u\n",
NIPQUAD(iph->saddr), NIPQUAD(iph->daddr));
in_dev_put(in_dev);
goto drop;
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index 454e81fea..cd51bcef3 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -1,5 +1,5 @@
/*
- * $Id: ipconfig.c,v 1.27 2000/02/21 15:51:41 davem Exp $
+ * $Id: ipconfig.c,v 1.30 2000/04/15 01:48:10 davem Exp $
*
* Automatic Configuration of IP -- use BOOTP or RARP or user-supplied
* information to configure own IP address and routes.
@@ -77,7 +77,7 @@ u8 root_server_path[256] __initdata = { 0, }; /* Path to mount as root */
#define CONFIG_IP_PNP_DYNAMIC
-static int ic_proto_enabled __initdata = 0 /* Protocols enabled */
+int ic_proto_enabled __initdata = 0 /* Protocols enabled */
#ifdef CONFIG_IP_PNP_BOOTP
| IC_BOOTP
#endif
@@ -227,17 +227,20 @@ static int __init ic_setup_if(void)
strcpy(ir.ifr_ifrn.ifrn_name, ic_dev->name);
set_sockaddr(sin, ic_myaddr, 0);
if ((err = ic_dev_ioctl(SIOCSIFADDR, &ir)) < 0) {
- printk(KERN_ERR "IP-Config: Unable to set interface address (%d).\n", err);
+ printk(KERN_ERR "IP-Config: Unable to set interface address (%u.%u.%u.%u).\n",
+ NIPQUAD(err));
return -1;
}
set_sockaddr(sin, ic_netmask, 0);
if ((err = ic_dev_ioctl(SIOCSIFNETMASK, &ir)) < 0) {
- printk(KERN_ERR "IP-Config: Unable to set interface netmask (%d).\n", err);
+ printk(KERN_ERR "IP-Config: Unable to set interface netmask (%u.%u.%u.%u).\n",
+ NIPQUAD(err));
return -1;
}
set_sockaddr(sin, ic_myaddr | ~ic_netmask, 0);
if ((err = ic_dev_ioctl(SIOCSIFBRDADDR, &ir)) < 0) {
- printk(KERN_ERR "IP-Config: Unable to set interface broadcast address (%d).\n", err);
+ printk(KERN_ERR "IP-Config: Unable to set interface broadcast address (%u.%u.%u.%u).\n",
+ NIPQUAD(err));
return -1;
}
return 0;
@@ -261,7 +264,8 @@ static int __init ic_setup_routes(void)
set_sockaddr((struct sockaddr_in *) &rm.rt_gateway, ic_gateway, 0);
rm.rt_flags = RTF_UP | RTF_GATEWAY;
if ((err = ic_route_ioctl(SIOCADDRT, &rm)) < 0) {
- printk(KERN_ERR "IP-Config: Cannot add default route (%d).\n", err);
+ printk(KERN_ERR "IP-Config: Cannot add default route (%u.%u.%u.%u).\n",
+ NIPQUAD(err));
return -1;
}
}
@@ -294,10 +298,11 @@ static int __init ic_defaults(void)
else if (IN_CLASSC(ntohl(ic_myaddr)))
ic_netmask = htonl(IN_CLASSC_NET);
else {
- printk(KERN_ERR "IP-Config: Unable to guess netmask for address %08x\n", ic_myaddr);
+ printk(KERN_ERR "IP-Config: Unable to guess netmask for address %u.%u.%u.%u\n",
+ NIPQUAD(ic_myaddr));
return -1;
}
- printk("IP-Config: Guessing netmask %s\n", in_ntoa(ic_netmask));
+ printk("IP-Config: Guessing netmask %u.%u.%u.%u\n", NIPQUAD(ic_netmask));
}
return 0;
@@ -807,10 +812,10 @@ static int __init ic_dynamic(void)
if (!ic_got_reply)
return -1;
- printk("IP-Config: Got %s answer from %s, ",
+ printk("IP-Config: Got %s answer from %u.%u.%u.%u, ",
(ic_got_reply & IC_BOOTP) ? "BOOTP" : "RARP",
- in_ntoa(ic_servaddr));
- printk("my address is %s\n", in_ntoa(ic_myaddr));
+ NIPQUAD(ic_servaddr));
+ printk("my address is %u.%u.%u.%u\n", NIPQUAD(ic_myaddr));
return 0;
}
@@ -986,7 +991,7 @@ static int __init ip_auto_config_setup(char *addrs)
num++;
}
- return 0;
+ return 1;
}
static int __init nfsaddrs_config_setup(char *addrs)
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
index 197c2e3b4..fdfd747e2 100644
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -343,6 +343,7 @@ init_conntrack(const struct ip_conntrack_tuple *tuple,
size_t hash, repl_hash;
struct ip_conntrack_expect *expected;
enum ip_conntrack_info ctinfo;
+ unsigned long extra_jiffies;
int i;
if (!invert_tuple(&repl_tuple, tuple, protocol)) {
@@ -366,19 +367,24 @@ init_conntrack(const struct ip_conntrack_tuple *tuple,
repl_hash = hash_conntrack(&repl_tuple);
memset(conntrack, 0, sizeof(struct ip_conntrack));
- atomic_set(&conntrack->ct_general.use, 1);
+ atomic_set(&conntrack->ct_general.use, 2);
conntrack->ct_general.destroy = destroy_conntrack;
conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple = *tuple;
conntrack->tuplehash[IP_CT_DIR_ORIGINAL].ctrack = conntrack;
conntrack->tuplehash[IP_CT_DIR_REPLY].tuple = repl_tuple;
conntrack->tuplehash[IP_CT_DIR_REPLY].ctrack = conntrack;
- for(i=0; i < IP_CT_NUMBER; i++)
+ for (i=0; i < IP_CT_NUMBER; i++)
conntrack->infos[i].master = &conntrack->ct_general;
- if (!protocol->new(conntrack, skb->nh.iph, skb->len)) {
+ extra_jiffies = protocol->new(conntrack, skb->nh.iph, skb->len);
+ if (!extra_jiffies) {
kmem_cache_free(ip_conntrack_cachep, conntrack);
return 1;
}
+ conntrack->timeout.data = (unsigned long)conntrack;
+ conntrack->timeout.function = death_by_timeout;
+ conntrack->timeout.expires = jiffies + extra_jiffies;
+ add_timer(&conntrack->timeout);
/* Sew in at head of hash list. */
WRITE_LOCK(&ip_conntrack_lock);
@@ -421,7 +427,7 @@ init_conntrack(const struct ip_conntrack_tuple *tuple,
}
static void
-resolve_normal_ct(struct sk_buff *skb)
+resolve_normal_ct(struct sk_buff *skb, int create)
{
struct ip_conntrack_tuple tuple;
struct ip_conntrack_tuple_hash *h;
@@ -436,7 +442,7 @@ resolve_normal_ct(struct sk_buff *skb)
do {
/* look for tuple match */
h = ip_conntrack_find_get(&tuple, NULL);
- if (!h && init_conntrack(&tuple, proto, skb))
+ if (!h && (!create || init_conntrack(&tuple, proto, skb)))
return;
} while (!h);
@@ -464,13 +470,15 @@ resolve_normal_ct(struct sk_buff *skb)
}
/* Return conntrack and conntrack_info a given skb */
-struct ip_conntrack *
-ip_conntrack_get(struct sk_buff *skb, enum ip_conntrack_info *ctinfo)
+static struct ip_conntrack *
+__ip_conntrack_get(struct sk_buff *skb,
+ enum ip_conntrack_info *ctinfo,
+ int create)
{
if (!skb->nfct) {
/* It may be an icmp error... */
if (!icmp_error_track(skb))
- resolve_normal_ct(skb);
+ resolve_normal_ct(skb, create);
}
if (skb->nfct) {
@@ -485,6 +493,12 @@ ip_conntrack_get(struct sk_buff *skb, enum ip_conntrack_info *ctinfo)
return NULL;
}
+struct ip_conntrack *
+ip_conntrack_get(struct sk_buff *skb, enum ip_conntrack_info *ctinfo)
+{
+ return __ip_conntrack_get(skb, ctinfo, 0);
+}
+
/* Netfilter hook itself. */
unsigned int ip_conntrack_in(unsigned int hooknum,
struct sk_buff **pskb,
@@ -512,13 +526,13 @@ unsigned int ip_conntrack_in(unsigned int hooknum,
return NF_STOLEN;
}
- ct = ip_conntrack_get(*pskb, &ctinfo);
- if (!ct)
+ ct = __ip_conntrack_get(*pskb, &ctinfo, 1);
+ if (!ct) {
/* Not valid part of a connection */
return NF_ACCEPT;
+ }
proto = find_proto((*pskb)->nh.iph->protocol);
- /* If this is new, this is first time timer will be set */
ret = proto->packet(ct, (*pskb)->nh.iph, (*pskb)->len, ctinfo);
if (ret == -1) {
@@ -645,24 +659,16 @@ void ip_conntrack_helper_unregister(struct ip_conntrack_helper *me)
MOD_DEC_USE_COUNT;
}
-/* Refresh conntrack for this many jiffies: if noone calls this,
- conntrack will vanish with current skb. */
+/* Refresh conntrack for this many jiffies. */
void ip_ct_refresh(struct ip_conntrack *ct, unsigned long extra_jiffies)
{
+ IP_NF_ASSERT(ct->timeout.data == (unsigned long)ct);
+
WRITE_LOCK(&ip_conntrack_lock);
- /* If this hasn't had a timer before, it's still being set up */
- if (ct->timeout.data == 0) {
- ct->timeout.data = (unsigned long)ct;
- ct->timeout.function = death_by_timeout;
+ /* Need del_timer for race avoidance (may already be dying). */
+ if (del_timer(&ct->timeout)) {
ct->timeout.expires = jiffies + extra_jiffies;
- atomic_inc(&ct->ct_general.use);
add_timer(&ct->timeout);
- } else {
- /* Need del_timer for race avoidance (may already be dying). */
- if (del_timer(&ct->timeout)) {
- ct->timeout.expires = jiffies + extra_jiffies;
- add_timer(&ct->timeout);
- }
}
WRITE_UNLOCK(&ip_conntrack_lock);
}
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_generic.c b/net/ipv4/netfilter/ip_conntrack_proto_generic.c
index 77a491e34..6e2bcbcec 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_generic.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_generic.c
@@ -48,9 +48,10 @@ static int established(struct ip_conntrack *conntrack,
}
/* Called when a new connection for this protocol found. */
-static int new(struct ip_conntrack *conntrack, struct iphdr *iph, size_t len)
+static unsigned long
+new(struct ip_conntrack *conntrack, struct iphdr *iph, size_t len)
{
- return 1;
+ return GENERIC_TIMEOUT;
}
struct ip_conntrack_protocol ip_conntrack_generic_protocol
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
index cbbc1ab8c..17e126119 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
@@ -86,8 +86,8 @@ static int icmp_packet(struct ip_conntrack *ct,
}
/* Called when a new connection for this protocol found. */
-static int icmp_new(struct ip_conntrack *conntrack,
- struct iphdr *iph, size_t len)
+static unsigned long icmp_new(struct ip_conntrack *conntrack,
+ struct iphdr *iph, size_t len)
{
static u_int8_t valid_new[]
= { [ICMP_ECHO] = 1,
@@ -103,7 +103,7 @@ static int icmp_new(struct ip_conntrack *conntrack,
DUMP_TUPLE(&conntrack->tuplehash[0].tuple);
return 0;
}
- return 1;
+ return ICMP_TIMEOUT;
}
struct ip_conntrack_protocol ip_conntrack_protocol_icmp
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
index 893248943..997a917bc 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
@@ -189,14 +189,13 @@ static int tcp_packet(struct ip_conntrack *conntrack,
conntrack->proto.tcp_state = newconntrack;
WRITE_UNLOCK(&tcp_lock);
- /* Refresh: need write lock to write to conntrack. */
ip_ct_refresh(conntrack, tcp_timeouts[conntrack->proto.tcp_state]);
return NF_ACCEPT;
}
/* Called when a new connection for this protocol found. */
-static int tcp_new(struct ip_conntrack *conntrack,
- struct iphdr *iph, size_t len)
+static unsigned long tcp_new(struct ip_conntrack *conntrack,
+ struct iphdr *iph, size_t len)
{
enum tcp_conntrack newconntrack;
struct tcphdr *tcph = (struct tcphdr *)((u_int32_t *)iph + iph->ihl);
@@ -210,11 +209,10 @@ static int tcp_new(struct ip_conntrack *conntrack,
if (newconntrack == TCP_CONNTRACK_MAX) {
DEBUGP("ip_conntrack_tcp: invalid new deleting.\n");
return 0;
- } else {
- conntrack->proto.tcp_state = newconntrack;
- ip_ct_refresh(conntrack, tcp_timeouts[conntrack->proto.tcp_state]);
}
- return 1;
+
+ conntrack->proto.tcp_state = newconntrack;
+ return tcp_timeouts[conntrack->proto.tcp_state];
}
struct ip_conntrack_protocol ip_conntrack_protocol_tcp
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_udp.c b/net/ipv4/netfilter/ip_conntrack_proto_udp.c
index 79ec82151..521bd7654 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_udp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_udp.c
@@ -54,10 +54,10 @@ static int udp_packet(struct ip_conntrack *conntrack,
}
/* Called when a new connection for this protocol found. */
-static int udp_new(struct ip_conntrack *conntrack,
- struct iphdr *iph, size_t len)
+static unsigned long udp_new(struct ip_conntrack *conntrack,
+ struct iphdr *iph, size_t len)
{
- return 1;
+ return UDP_TIMEOUT;
}
struct ip_conntrack_protocol ip_conntrack_protocol_udp
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
index 9030d9d41..3219f4c85 100644
--- a/net/ipv4/netfilter/ip_conntrack_standalone.c
+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c
@@ -169,8 +169,6 @@ static unsigned int ip_refrag(unsigned int hooknum,
interface. We degfragment them at LOCAL_OUT, however,
so we have to refragment them here. */
if ((*pskb)->len > rt->u.dst.pmtu) {
- DEBUGP("ip_conntrack: refragm %p (size %u) to %u (okfn %p)\n",
- *pskb, (*pskb)->len, rt->u.dst.pmtu, okfn);
/* No hook can be after us, so this should be OK. */
ip_fragment(*pskb, okfn);
return NF_STOLEN;
@@ -178,13 +176,29 @@ static unsigned int ip_refrag(unsigned int hooknum,
return NF_ACCEPT;
}
+static unsigned int ip_conntrack_local(unsigned int hooknum,
+ struct sk_buff **pskb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ /* root is playing with raw sockets. */
+ if ((*pskb)->len < sizeof(struct iphdr)
+ || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) {
+ if (net_ratelimit())
+ printk("ipt_hook: happy cracking.\n");
+ return NF_ACCEPT;
+ }
+ return ip_conntrack_in(hooknum, pskb, in, out, okfn);
+}
+
/* Connection tracking may drop packets, but never alters them, so
make it the first hook. */
static struct nf_hook_ops ip_conntrack_in_ops
= { { NULL, NULL }, ip_conntrack_in, PF_INET, NF_IP_PRE_ROUTING,
NF_IP_PRI_CONNTRACK };
static struct nf_hook_ops ip_conntrack_local_out_ops
-= { { NULL, NULL }, ip_conntrack_in, PF_INET, NF_IP_LOCAL_OUT,
+= { { NULL, NULL }, ip_conntrack_local, PF_INET, NF_IP_LOCAL_OUT,
NF_IP_PRI_CONNTRACK };
/* Refragmenter; last chance. */
static struct nf_hook_ops ip_conntrack_out_ops
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index bfcc435c2..0c582b867 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -130,6 +130,11 @@ ip_nat_out(unsigned int hooknum,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
+ /* root is playing with raw sockets. */
+ if ((*pskb)->len < sizeof(struct iphdr)
+ || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
+ return NF_ACCEPT;
+
/* We can hit fragment here; forwarded packets get
defragmented by connection tracking coming in, then
fragmented (grr) by the forward code.
@@ -150,6 +155,21 @@ ip_nat_out(unsigned int hooknum,
return ip_nat_fn(hooknum, pskb, in, out, okfn);
}
+static unsigned int
+ip_nat_local_fn(unsigned int hooknum,
+ struct sk_buff **pskb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ /* root is playing with raw sockets. */
+ if ((*pskb)->len < sizeof(struct iphdr)
+ || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
+ return NF_ACCEPT;
+
+ return ip_nat_fn(hooknum, pskb, in, out, okfn);
+}
+
/* We must be after connection tracking and before packet filtering. */
/* Before packet filtering, change destination */
@@ -160,7 +180,7 @@ static struct nf_hook_ops ip_nat_out_ops
= { { NULL, NULL }, ip_nat_out, PF_INET, NF_IP_POST_ROUTING, NF_IP_PRI_NAT_SRC};
/* Before packet filtering, change destination */
static struct nf_hook_ops ip_nat_local_out_ops
-= { { NULL, NULL }, ip_nat_fn, PF_INET, NF_IP_LOCAL_OUT, NF_IP_PRI_NAT_DST };
+= { { NULL, NULL }, ip_nat_local_fn, PF_INET, NF_IP_LOCAL_OUT, NF_IP_PRI_NAT_DST };
/* Protocol registration. */
int ip_nat_protocol_register(struct ip_nat_protocol *proto)
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index 80e43d977..72b47568b 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -509,7 +509,7 @@ static int ipq_get_info(char *buffer, char **start, off_t offset, int length)
"Peer pid : %d\n"
"Peer died : %d\n"
"Peer copy mode : %d\n"
- "Peer copy range : %d\n"
+ "Peer copy range : %Zu\n"
"Queue length : %d\n"
"Queue max. length : %d\n"
"Queue flushing : %d\n"
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 66f47c386..73424cef8 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -39,7 +39,7 @@
#define IP_NF_ASSERT(x) \
do { \
if (!(x)) \
- printk("IPT_ASSERT: %s:%s:%u\n", \
+ printk("IP_NF_ASSERT: %s:%s:%u\n", \
__FUNCTION__, __FILE__, __LINE__); \
} while(0)
#else
@@ -683,7 +683,6 @@ check_entry(struct ipt_entry *e, const char *name, unsigned int size,
target = find_target_lock(t->u.name, &ret, &ipt_mutex);
if (!target) {
duprintf("check_entry: `%s' not found\n", t->u.name);
- up(&ipt_mutex);
return ret;
}
if (target->me)
@@ -1283,17 +1282,16 @@ ipt_register_target(struct ipt_target *target)
{
int ret;
+ MOD_INC_USE_COUNT;
ret = down_interruptible(&ipt_mutex);
if (ret != 0)
return ret;
- if (list_named_insert(&ipt_target, target)) {
- MOD_INC_USE_COUNT;
- ret = 0;
- } else {
+ if (!list_named_insert(&ipt_target, target)) {
duprintf("ipt_register_target: `%s' already in list!\n",
target->name);
ret = -EINVAL;
+ MOD_DEC_USE_COUNT;
}
up(&ipt_mutex);
return ret;
@@ -1313,16 +1311,18 @@ ipt_register_match(struct ipt_match *match)
{
int ret;
+ MOD_INC_USE_COUNT;
ret = down_interruptible(&ipt_mutex);
- if (ret != 0)
+ if (ret != 0) {
+ MOD_DEC_USE_COUNT;
return ret;
-
+ }
if (list_named_insert(&ipt_match, match)) {
- MOD_INC_USE_COUNT;
ret = 0;
} else {
duprintf("ipt_register_match: `%s' already in list!\n",
match->name);
+ MOD_DEC_USE_COUNT;
ret = -EINVAL;
}
up(&ipt_mutex);
@@ -1346,10 +1346,12 @@ int ipt_register_table(struct ipt_table *table)
static struct ipt_table_info bootstrap
= { 0, 0, { 0 }, { 0 }, { }, { } };
+ MOD_INC_USE_COUNT;
newinfo = vmalloc(sizeof(struct ipt_table_info)
+ SMP_ALIGN(table->table->size) * smp_num_cpus);
if (!newinfo) {
ret = -ENOMEM;
+ MOD_DEC_USE_COUNT;
return ret;
}
memcpy(newinfo->entries, table->table->entries, table->table->size);
@@ -1361,12 +1363,14 @@ int ipt_register_table(struct ipt_table *table)
table->table->underflow);
if (ret != 0) {
vfree(newinfo);
+ MOD_DEC_USE_COUNT;
return ret;
}
ret = down_interruptible(&ipt_mutex);
if (ret != 0) {
vfree(newinfo);
+ MOD_DEC_USE_COUNT;
return ret;
}
@@ -1386,7 +1390,6 @@ int ipt_register_table(struct ipt_table *table)
table->lock = RW_LOCK_UNLOCKED;
list_prepend(&ipt_tables, table);
- MOD_INC_USE_COUNT;
unlock:
up(&ipt_mutex);
@@ -1394,6 +1397,7 @@ int ipt_register_table(struct ipt_table *table)
free_unlock:
vfree(newinfo);
+ MOD_DEC_USE_COUNT;
goto unlock;
}
diff --git a/net/ipv4/netfilter/ipchains_core.c b/net/ipv4/netfilter/ipchains_core.c
index 419b0382c..e22898512 100644
--- a/net/ipv4/netfilter/ipchains_core.c
+++ b/net/ipv4/netfilter/ipchains_core.c
@@ -419,18 +419,10 @@ static void dump_packet(const struct iphdr *ip,
printk("%d ",f->ipfw.fw_redirpt);
}
- printk("%s PROTO=%d %d.%d.%d.%d:%hu %d.%d.%d.%d:%hu"
+ printk("%s PROTO=%d %u.%u.%u.%u:%hu %u.%u.%u.%u:%hu"
" L=%hu S=0x%2.2hX I=%hu F=0x%4.4hX T=%hu",
- ifname, ip->protocol,
- (ntohl(ip->saddr)>>24)&0xFF,
- (ntohl(ip->saddr)>>16)&0xFF,
- (ntohl(ip->saddr)>>8)&0xFF,
- (ntohl(ip->saddr))&0xFF,
- src_port,
- (ntohl(ip->daddr)>>24)&0xFF,
- (ntohl(ip->daddr)>>16)&0xFF,
- (ntohl(ip->daddr)>>8)&0xFF,
- (ntohl(ip->daddr))&0xFF,
+ ifname, ip->protocol, NIPQUAD(ip->saddr),
+ src_port, NIPQUAD(ip->daddr),
dst_port,
ntohs(ip->tot_len), ip->tos, ntohs(ip->id),
ntohs(ip->frag_off), ip->ttl);
diff --git a/net/ipv4/netfilter/ipfwadm_core.c b/net/ipv4/netfilter/ipfwadm_core.c
index a1f4e16cf..904e7c824 100644
--- a/net/ipv4/netfilter/ipfwadm_core.c
+++ b/net/ipv4/netfilter/ipfwadm_core.c
@@ -17,7 +17,7 @@
* license in recognition of the original copyright.
* -- Alan Cox.
*
- * $Id: ipfwadm_core.c,v 1.1 2000/03/17 14:42:00 davem Exp $
+ * $Id: ipfwadm_core.c,v 1.2 2000/04/15 01:48:10 davem Exp $
*
* Ported from BSD to Linux,
* Alan Cox 22/Nov/1994.
@@ -143,10 +143,7 @@
#define dprintf4(a1,a2,a3,a4)
#endif
-#define print_ip(a) printk("%d.%d.%d.%d",(ntohl(a)>>24)&0xFF,\
- (ntohl(a)>>16)&0xFF,\
- (ntohl(a)>>8)&0xFF,\
- (ntohl(a))&0xFF);
+#define print_ip(a) printk("%u.%u.%u.%u", NIPQUAD(a));
#ifdef DEBUG_IP_FIREWALL
#define dprint_ip(a) print_ip(a)
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c
index 4675a94b8..395b1b301 100644
--- a/net/ipv4/netfilter/ipt_LOG.c
+++ b/net/ipv4/netfilter/ipt_LOG.c
@@ -38,14 +38,7 @@ static void dump_packet(const struct ipt_log_info *info,
* TOS, len, DF/MF, fragment offset, TTL, src, dst, options. */
/* Max length: 40 "SRC=255.255.255.255 DST=255.255.255.255 " */
printk("SRC=%u.%u.%u.%u DST=%u.%u.%u.%u ",
- (ntohl(iph->saddr)>>24)&0xFF,
- (ntohl(iph->saddr)>>16)&0xFF,
- (ntohl(iph->saddr)>>8)&0xFF,
- (ntohl(iph->saddr))&0xFF,
- (ntohl(iph->daddr)>>24)&0xFF,
- (ntohl(iph->daddr)>>16)&0xFF,
- (ntohl(iph->daddr)>>8)&0xFF,
- (ntohl(iph->daddr))&0xFF);
+ NIPQUAD(iph->saddr), NIPQUAD(iph->daddr));
/* Max length: 46 "LEN=65535 TOS=0xFF PREC=0xFF TTL=255 ID=65535 " */
printk("LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u ",
@@ -210,11 +203,7 @@ static void dump_packet(const struct ipt_log_info *info,
break;
case ICMP_REDIRECT:
/* Max length: 24 "GATEWAY=255.255.255.255 " */
- printk("GATEWAY=%u.%u.%u.%u ",
- (ntohl(icmph->un.gateway)>>24)&0xFF,
- (ntohl(icmph->un.gateway)>>16)&0xFF,
- (ntohl(icmph->un.gateway)>>8)&0xFF,
- (ntohl(icmph->un.gateway))&0xFF);
+ printk("GATEWAY=%u.%u.%u.%u ", NIPQUAD(icmph->un.gateway));
/* Fall through */
case ICMP_DEST_UNREACH:
case ICMP_SOURCE_QUENCH:
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index d6a7c57f5..4d94a4cc0 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -7,7 +7,7 @@
* PROC file system. It is mainly used for debugging and
* statistics.
*
- * Version: $Id: proc.c,v 1.41 2000/01/21 23:45:57 davem Exp $
+ * Version: $Id: proc.c,v 1.42 2000/04/16 01:11:37 davem Exp $
*
* Authors: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Gerald J. Heim, <heim@peanuts.informatik.uni-tuebingen.de>
@@ -56,7 +56,7 @@ static int fold_prot_inuse(struct proto *proto)
int cpu;
for (cpu=0; cpu<smp_num_cpus; cpu++)
- res += proto->stats[cpu].inuse;
+ res += proto->stats[cpu_logical_map(cpu)].inuse;
return res;
}
@@ -99,8 +99,10 @@ static unsigned long fold_field(unsigned long *begin, int sz, int nr)
sz /= sizeof(unsigned long);
- for (i=0; i<2*smp_num_cpus; i++)
- res += begin[i*sz + nr];
+ for (i=0; i<smp_num_cpus; i++) {
+ res += begin[2*cpu_logical_map(i)*sz + nr];
+ res += begin[(2*cpu_logical_map(i)+1)*sz + nr];
+ }
return res;
}
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index e9aa1952a..a7555b6b5 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -5,7 +5,7 @@
*
* RAW - implementation of IP "raw" sockets.
*
- * Version: $Id: raw.c,v 1.48 2000/01/18 08:24:15 davem Exp $
+ * Version: $Id: raw.c,v 1.49 2000/04/25 04:13:34 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -644,26 +644,20 @@ out:
}
struct proto raw_prot = {
- raw_close, /* close */
- udp_connect, /* connect */
- udp_disconnect, /* disconnect */
- NULL, /* accept */
+ name: "RAW",
+ close: raw_close,
+ connect: udp_connect,
+ disconnect: udp_disconnect,
#ifdef CONFIG_IP_MROUTE
- ipmr_ioctl, /* ioctl */
-#else
- NULL, /* ioctl */
+ ioctl: ipmr_ioctl,
#endif
- raw_init, /* init */
- NULL, /* destroy */
- NULL, /* shutdown */
- raw_setsockopt, /* setsockopt */
- raw_getsockopt, /* getsockopt */
- raw_sendmsg, /* sendmsg */
- raw_recvmsg, /* recvmsg */
- raw_bind, /* bind */
- raw_rcv_skb, /* backlog_rcv */
- raw_v4_hash, /* hash */
- raw_v4_unhash, /* unhash */
- NULL, /* get_port */
- "RAW", /* name */
+ init: raw_init,
+ setsockopt: raw_setsockopt,
+ getsockopt: raw_getsockopt,
+ sendmsg: raw_sendmsg,
+ recvmsg: raw_recvmsg,
+ bind: raw_bind,
+ backlog_rcv: raw_rcv_skb,
+ hash: raw_v4_hash,
+ unhash: raw_v4_unhash,
};
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index afab828fb..ec254e313 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -5,7 +5,7 @@
*
* ROUTE - implementation of the IP router.
*
- * Version: $Id: route.c,v 1.83 2000/03/23 05:34:13 davem Exp $
+ * Version: $Id: route.c,v 1.86 2000/04/24 07:03:14 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -616,9 +616,9 @@ restart:
#if RT_CACHE_DEBUG >= 2
if (rt->u.rt_next) {
struct rtable * trt;
- printk("rt_cache @%02x: %08x", hash, rt->rt_dst);
+ printk("rt_cache @%02x: %u.%u.%u.%u", hash, NIPQUAD(rt->rt_dst));
for (trt=rt->u.rt_next; trt; trt=trt->u.rt_next)
- printk(" . %08x", trt->rt_dst);
+ printk(" . %u.%u.%u.%u", NIPQUAD(trt->rt_dst));
printk("\n");
}
#endif
@@ -816,10 +816,10 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw,
reject_redirect:
#ifdef CONFIG_IP_ROUTE_VERBOSE
if (IN_DEV_LOG_MARTIANS(in_dev) && net_ratelimit())
- printk(KERN_INFO "Redirect from %X/%s to %X ignored."
- "Path = %X -> %X, tos %02x\n",
- ntohl(old_gw), dev->name, ntohl(new_gw),
- ntohl(saddr), ntohl(daddr), tos);
+ printk(KERN_INFO "Redirect from %u.%u.%u.%u on %s about %u.%u.%u.%u ignored.\n"
+ " Advised path = %u.%u.%u.%u -> %u.%u.%u.%u, tos %02x\n",
+ NIPQUAD(old_gw), dev->name, NIPQUAD(new_gw),
+ NIPQUAD(saddr), NIPQUAD(daddr), tos);
#endif
in_dev_put(in_dev);
}
@@ -836,7 +836,8 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
if ((rt->rt_flags&RTCF_REDIRECTED) || rt->u.dst.expires) {
unsigned hash = rt_hash_code(rt->key.dst, rt->key.src^(rt->key.oif<<5), rt->key.tos);
#if RT_CACHE_DEBUG >= 1
- printk(KERN_DEBUG "ip_rt_advice: redirect to %d.%d.%d.%d/%02x dropped\n", NIPQUAD(rt->rt_dst), rt->key.tos);
+ printk(KERN_DEBUG "ip_rt_advice: redirect to %u.%u.%u.%u/%02x dropped\n",
+ NIPQUAD(rt->rt_dst), rt->key.tos);
#endif
rt_del(hash, rt);
return NULL;
@@ -896,8 +897,10 @@ void ip_rt_send_redirect(struct sk_buff *skb)
#ifdef CONFIG_IP_ROUTE_VERBOSE
if (IN_DEV_LOG_MARTIANS(in_dev) &&
rt->u.dst.rate_tokens == ip_rt_redirect_number && net_ratelimit())
- printk(KERN_WARNING "host %08x/if%d ignores redirects for %08x to %08x.\n",
- rt->rt_src, rt->rt_iif, rt->rt_dst, rt->rt_gateway);
+ printk(KERN_WARNING "host %u.%u.%u.%u/if%d ignores redirects for "
+ "%u.%u.%u.%u to %u.%u.%u.%u.\n",
+ NIPQUAD(rt->rt_src), rt->rt_iif,
+ NIPQUAD(rt->rt_dst), NIPQUAD(rt->rt_gateway));
#endif
}
out:
@@ -1061,8 +1064,9 @@ static void ipv4_link_failure(struct sk_buff *skb)
static int ip_rt_bug(struct sk_buff *skb)
{
- printk(KERN_DEBUG "ip_rt_bug: %08x -> %08x, %s\n", skb->nh.iph->saddr,
- skb->nh.iph->daddr, skb->dev ? skb->dev->name : "?");
+ printk(KERN_DEBUG "ip_rt_bug: %u.%u.%u.%u -> %u.%u.%u.%u, %s\n",
+ NIPQUAD(skb->nh.iph->saddr), NIPQUAD(skb->nh.iph->daddr),
+ skb->dev ? skb->dev->name : "?");
kfree_skb(skb);
return 0;
}
@@ -1499,7 +1503,8 @@ no_route:
martian_destination:
#ifdef CONFIG_IP_ROUTE_VERBOSE
if (IN_DEV_LOG_MARTIANS(in_dev) && net_ratelimit())
- printk(KERN_WARNING "martian destination %08x from %08x, dev %s\n", daddr, saddr, dev->name);
+ printk(KERN_WARNING "martian destination %u.%u.%u.%u from %u.%u.%u.%u, dev %s\n",
+ NIPQUAD(daddr), NIPQUAD(saddr), dev->name);
#endif
e_inval:
err = -EINVAL;
@@ -1513,16 +1518,20 @@ martian_source:
#ifdef CONFIG_IP_ROUTE_VERBOSE
if (IN_DEV_LOG_MARTIANS(in_dev) && net_ratelimit()) {
/*
- * RFC1812 recommenadtion, if source is martian,
+ * RFC1812 recommendation, if source is martian,
* the only hint is MAC header.
*/
- printk(KERN_WARNING "martian source %08x for %08x, dev %s\n", saddr, daddr, dev->name);
+ printk(KERN_WARNING "martian source %u.%u.%u.%u from %u.%u.%u.%u, on dev %s\n",
+ NIPQUAD(daddr), NIPQUAD(saddr), dev->name);
if (dev->hard_header_len) {
int i;
unsigned char *p = skb->mac.raw;
- printk(KERN_WARNING "ll header:");
- for (i=0; i<dev->hard_header_len; i++, p++)
- printk(" %02x", *p);
+ printk(KERN_WARNING "ll header: ");
+ for (i=0; i<dev->hard_header_len; i++, p++) {
+ printk("%02x", *p);
+ if(i<(dev->hard_header_len-1))
+ printk(":");
+ }
printk("\n");
}
}
@@ -2218,15 +2227,20 @@ static int ip_rt_acct_read(char *buffer, char **start, off_t offset,
memcpy(dst, src, length);
-#ifdef __SMP__
- if (smp_num_cpus > 1) {
+#ifdef CONFIG_SMP
+ if (smp_num_cpus > 1 || cpu_logical_map(0) != 0) {
int i;
int cnt = length/4;
- for (i=1; i<smp_num_cpus; i++) {
+ for (i=0; i<smp_num_cpus; i++) {
+ int cpu = cpu_logical_map(i);
int k;
- src += (256/4)*sizeof(struct ip_rt_acct);
+ if (cpu == 0)
+ continue;
+
+ src = (u32*)(((u8*)ip_rt_acct) + offset +
+ cpu*256*sizeof(struct ip_rt_acct));
for (k=0; k<cnt; k++)
dst[k] += src[k];
@@ -2245,7 +2259,7 @@ void __init ip_rt_init(void)
#ifdef CONFIG_NET_CLS_ROUTE
for (order=0;
- (PAGE_SIZE<<order) < 256*sizeof(ip_rt_acct)*smp_num_cpus; order++)
+ (PAGE_SIZE<<order) < 256*sizeof(ip_rt_acct)*NR_CPUS; order++)
/* NOTHING */;
ip_rt_acct = (struct ip_rt_acct *)__get_free_pages(GFP_KERNEL, order);
if (!ip_rt_acct)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 098d91ba1..c4343b707 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -5,7 +5,7 @@
*
* Implementation of the Transmission Control Protocol(TCP).
*
- * Version: $Id: tcp.c,v 1.166 2000/03/25 01:55:11 davem Exp $
+ * Version: $Id: tcp.c,v 1.169 2000/04/20 14:41:16 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -583,9 +583,13 @@ int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg)
answ = 0;
else if (sk->urginline || !tp->urg_data ||
before(tp->urg_seq,tp->copied_seq) ||
- !before(tp->urg_seq,tp->rcv_nxt))
+ !before(tp->urg_seq,tp->rcv_nxt)) {
answ = tp->rcv_nxt - tp->copied_seq;
- else
+
+ /* Subtract 1, if FIN is in queue. */
+ if (answ && !skb_queue_empty(&sk->receive_queue))
+ answ -= ((struct sk_buff*)sk->receive_queue.prev)->h.th->fin;
+ } else
answ = tp->urg_seq - tp->copied_seq;
release_sock(sk);
break;
@@ -618,7 +622,7 @@ int tcp_listen_start(struct sock *sk)
sk->max_ack_backlog = 0;
sk->ack_backlog = 0;
- tp->accept_queue = NULL;
+ tp->accept_queue = tp->accept_queue_tail = NULL;
tp->syn_wait_lock = RW_LOCK_UNLOCKED;
lopt = kmalloc(sizeof(struct tcp_listen_opt), GFP_KERNEL);
@@ -677,7 +681,7 @@ static void tcp_listen_stop (struct sock *sk)
write_lock_bh(&tp->syn_wait_lock);
tp->listen_opt =NULL;
write_unlock_bh(&tp->syn_wait_lock);
- tp->accept_queue = NULL;
+ tp->accept_queue = tp->accept_queue_tail = NULL;
if (lopt->qlen) {
for (i=0; i<TCP_SYNQ_HSIZE; i++) {
@@ -951,10 +955,14 @@ int tcp_sendmsg(struct sock *sk, struct msghdr *msg, int size)
tmp += copy;
queue_it = 0;
}
- skb = sock_wmalloc(sk, tmp, 0, GFP_KERNEL);
- /* If we didn't get any memory, we need to sleep. */
- if (skb == NULL) {
+ if (tcp_memory_free(sk)) {
+ skb = alloc_skb(tmp, GFP_KERNEL);
+ if (skb == NULL)
+ goto do_oom;
+ skb_set_owner_w(skb, sk);
+ } else {
+ /* If we didn't get any memory, we need to sleep. */
set_bit(SOCK_ASYNC_NOSPACE, &sk->socket->flags);
set_bit(SOCK_NOSPACE, &sk->socket->flags);
@@ -1029,6 +1037,9 @@ do_shutdown:
err = -EPIPE;
}
goto out;
+do_oom:
+ err = copied ? : -ENOBUFS;
+ goto out;
do_interrupted:
if(copied)
err = copied;
@@ -2027,7 +2038,8 @@ struct sock *tcp_accept(struct sock *sk, int flags, int *err)
}
req = tp->accept_queue;
- tp->accept_queue = req->dl_next;
+ if ((tp->accept_queue = req->dl_next) == NULL)
+ tp->accept_queue_tail = NULL;
newsk = req->sk;
tcp_acceptq_removed(sk);
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 3ba12bc52..f062cb2fb 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -5,7 +5,7 @@
*
* Implementation of the Transmission Control Protocol(TCP).
*
- * Version: $Id: tcp_input.c,v 1.191 2000/03/25 01:55:13 davem Exp $
+ * Version: $Id: tcp_input.c,v 1.193 2000/04/20 14:41:16 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -1618,6 +1618,7 @@ static void tcp_fin(struct sk_buff *skb, struct sock *sk, struct tcphdr *th)
tp->fin_seq = TCP_SKB_CB(skb)->end_seq;
tp->ack.pending = 1;
+ tp->ack.quick = 0;
sk->shutdown |= RCV_SHUTDOWN;
@@ -1670,9 +1671,9 @@ static void tcp_fin(struct sk_buff *skb, struct sock *sk, struct tcphdr *th)
/* Do not send POLL_HUP for half duplex close. */
if (sk->shutdown == SHUTDOWN_MASK || sk->state == TCP_CLOSE)
- sock_wake_async(sk->socket, 1, POLL_HUP);
+ sk_wake_async(sk, 1, POLL_HUP);
else
- sock_wake_async(sk->socket, 1, POLL_IN);
+ sk_wake_async(sk, 1, POLL_IN);
}
}
@@ -2207,7 +2208,7 @@ static void tcp_check_urg(struct sock * sk, struct tcphdr * th)
kill_proc(sk->proc, SIGURG, 1);
else
kill_pg(-sk->proc, SIGURG, 1);
- sock_wake_async(sk->socket, 3, POLL_PRI);
+ sk_wake_async(sk, 3, POLL_PRI);
}
/* We may be adding urgent data when the last byte read was
@@ -2783,7 +2784,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req,
newtp->fin_seq = req->rcv_isn;
newtp->urg_data = 0;
newtp->listen_opt = NULL;
- newtp->accept_queue = NULL;
+ newtp->accept_queue = newtp->accept_queue_tail = NULL;
/* Deinitialize syn_wait_lock to trap illegal accesses. */
memset(&newtp->syn_wait_lock, 0, sizeof(newtp->syn_wait_lock));
@@ -3162,7 +3163,7 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
if(!sk->dead) {
sk->state_change(sk);
- sock_wake_async(sk->socket, 0, POLL_OUT);
+ sk_wake_async(sk, 0, POLL_OUT);
}
if (tp->write_pending) {
@@ -3444,7 +3445,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
*/
if (!sk->dead) {
sk->state_change(sk);
- sock_wake_async(sk->socket,0,POLL_OUT);
+ sk_wake_async(sk,0,POLL_OUT);
}
tp->snd_una = TCP_SKB_CB(skb)->ack_seq;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 3c9f4e82b..5facec2c8 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -5,7 +5,7 @@
*
* Implementation of the Transmission Control Protocol(TCP).
*
- * Version: $Id: tcp_ipv4.c,v 1.205 2000/03/26 09:16:08 davem Exp $
+ * Version: $Id: tcp_ipv4.c,v 1.207 2000/04/25 04:13:34 davem Exp $
*
* IPv4 specific functions
*
@@ -1384,7 +1384,8 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
peer->v4daddr == saddr) {
if (xtime.tv_sec < peer->tcp_ts_stamp + TCP_PAWS_MSL &&
(s32)(peer->tcp_ts - req->ts_recent) > TCP_PAWS_WINDOW) {
- NETDEBUG(printk(KERN_DEBUG "TW_REC: reject openreq %u/%u %08x/%u\n", peer->tcp_ts, req->ts_recent, saddr, ntohs(skb->h.th->source)));
+ NETDEBUG(printk(KERN_DEBUG "TW_REC: reject openreq %u/%u %u.%u.%u.%u/%u\n", \
+ peer->tcp_ts, req->ts_recent, NIPQUAD(saddr), ntohs(skb->h.th->source)));
NET_INC_STATS_BH(PAWSPassiveRejected);
dst_release(dst);
goto drop_and_free;
@@ -1402,7 +1403,9 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
* to destinations, already remembered
* to the moment of synflood.
*/
- NETDEBUG(if (net_ratelimit()) printk(KERN_DEBUG "TCP: drop open request from %08x/%u\n", saddr, ntohs(skb->h.th->source)));
+ NETDEBUG(if (net_ratelimit()) \
+ printk(KERN_DEBUG "TCP: drop open request from %u.%u.%u.%u/%u\n", \
+ NIPQUAD(saddr), ntohs(skb->h.th->source)));
TCP_INC_STATS_BH(TcpAttemptFails);
dst_release(dst);
goto drop_and_free;
@@ -2169,24 +2172,23 @@ out_no_bh:
}
struct proto tcp_prot = {
- tcp_close, /* close */
- tcp_v4_connect, /* connect */
- tcp_disconnect, /* disconnect */
- tcp_accept, /* accept */
- tcp_ioctl, /* ioctl */
- tcp_v4_init_sock, /* init */
- tcp_v4_destroy_sock, /* destroy */
- tcp_shutdown, /* shutdown */
- tcp_setsockopt, /* setsockopt */
- tcp_getsockopt, /* getsockopt */
- tcp_sendmsg, /* sendmsg */
- tcp_recvmsg, /* recvmsg */
- NULL, /* bind */
- tcp_v4_do_rcv, /* backlog_rcv */
- tcp_v4_hash, /* hash */
- tcp_unhash, /* unhash */
- tcp_v4_get_port, /* get_port */
- "TCP", /* name */
+ name: "TCP",
+ close: tcp_close,
+ connect: tcp_v4_connect,
+ disconnect: tcp_disconnect,
+ accept: tcp_accept,
+ ioctl: tcp_ioctl,
+ init: tcp_v4_init_sock,
+ destroy: tcp_v4_destroy_sock,
+ shutdown: tcp_shutdown,
+ setsockopt: tcp_setsockopt,
+ getsockopt: tcp_getsockopt,
+ sendmsg: tcp_sendmsg,
+ recvmsg: tcp_recvmsg,
+ backlog_rcv: tcp_v4_do_rcv,
+ hash: tcp_v4_hash,
+ unhash: tcp_unhash,
+ get_port: tcp_v4_get_port,
};
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 600140764..0fdb6b3f8 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -5,7 +5,7 @@
*
* Implementation of the Transmission Control Protocol(TCP).
*
- * Version: $Id: tcp_output.c,v 1.123 2000/03/25 01:52:05 davem Exp $
+ * Version: $Id: tcp_output.c,v 1.124 2000/04/08 07:21:24 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -1121,27 +1121,22 @@ void tcp_send_delayed_ack(struct sock *sk)
timeout = jiffies + ato;
/* Use new timeout only if there wasn't a older one earlier. */
- spin_lock_bh(&sk->timer_lock);
- if (!tp->delack_timer.prev || !del_timer(&tp->delack_timer)) {
- sock_hold(sk);
- tp->delack_timer.expires = timeout;
- } else {
+ if (timer_pending(&tp->delack_timer)) {
+ unsigned long old_timeout = tp->delack_timer.expires;
+
/* If delack timer was blocked or is about to expire,
* send ACK now.
*/
- if (tp->ack.blocked || time_before_eq(tp->delack_timer.expires, jiffies+(ato>>2))) {
- spin_unlock_bh(&sk->timer_lock);
-
+ if (tp->ack.blocked || time_before_eq(old_timeout, jiffies+(ato>>2))) {
tcp_send_ack(sk);
- __sock_put(sk);
return;
}
- if (time_before(timeout, tp->delack_timer.expires))
- tp->delack_timer.expires = timeout;
+ if (!time_before(timeout, old_timeout))
+ timeout = old_timeout;
}
- add_timer(&tp->delack_timer);
- spin_unlock_bh(&sk->timer_lock);
+ if (!mod_timer(&tp->delack_timer, timeout))
+ sock_hold(sk);
#ifdef TCP_FORMAL_WINDOW
/* Explanation. Header prediction path does not handle
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index 6b3695c3e..9e9887707 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -5,7 +5,7 @@
*
* Implementation of the Transmission Control Protocol(TCP).
*
- * Version: $Id: tcp_timer.c,v 1.74 2000/02/14 20:56:30 davem Exp $
+ * Version: $Id: tcp_timer.c,v 1.75 2000/04/08 07:21:25 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -49,8 +49,6 @@ void tcp_init_xmit_timers(struct sock *sk)
{
struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
- spin_lock_init(&sk->timer_lock);
-
init_timer(&tp->retransmit_timer);
tp->retransmit_timer.function=&tcp_retransmit_timer;
tp->retransmit_timer.data = (unsigned long) sk;
@@ -76,7 +74,6 @@ void tcp_reset_xmit_timer(struct sock *sk, int what, unsigned long when)
{
struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
- spin_lock_bh(&sk->timer_lock);
switch (what) {
case TCP_TIME_RETRANS:
/* When seting the transmit timer the probe timer
@@ -84,50 +81,44 @@ void tcp_reset_xmit_timer(struct sock *sk, int what, unsigned long when)
* The delayed ack timer can be set if we are changing the
* retransmit timer when removing acked frames.
*/
- if(tp->probe_timer.prev && del_timer(&tp->probe_timer))
+ if (timer_pending(&tp->probe_timer) && del_timer(&tp->probe_timer))
__sock_put(sk);
- if (!tp->retransmit_timer.prev || !del_timer(&tp->retransmit_timer))
- sock_hold(sk);
if (when > TCP_RTO_MAX) {
printk(KERN_DEBUG "reset_xmit_timer sk=%p when=0x%lx, caller=%p\n", sk, when, NET_CALLER(sk));
when = TCP_RTO_MAX;
}
- mod_timer(&tp->retransmit_timer, jiffies+when);
+ if (!mod_timer(&tp->retransmit_timer, jiffies+when))
+ sock_hold(sk);
break;
case TCP_TIME_DACK:
- if (!tp->delack_timer.prev || !del_timer(&tp->delack_timer))
+ if (!mod_timer(&tp->delack_timer, jiffies+when))
sock_hold(sk);
- mod_timer(&tp->delack_timer, jiffies+when);
break;
case TCP_TIME_PROBE0:
- if (!tp->probe_timer.prev || !del_timer(&tp->probe_timer))
+ if (!mod_timer(&tp->probe_timer, jiffies+when))
sock_hold(sk);
- mod_timer(&tp->probe_timer, jiffies+when);
- break;
+ break;
default:
printk(KERN_DEBUG "bug: unknown timer value\n");
};
- spin_unlock_bh(&sk->timer_lock);
}
void tcp_clear_xmit_timers(struct sock *sk)
{
struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
- spin_lock_bh(&sk->timer_lock);
- if(tp->retransmit_timer.prev && del_timer(&tp->retransmit_timer))
+ if(timer_pending(&tp->retransmit_timer) && del_timer(&tp->retransmit_timer))
__sock_put(sk);
- if(tp->delack_timer.prev && del_timer(&tp->delack_timer))
+ if(timer_pending(&tp->delack_timer) && del_timer(&tp->delack_timer))
__sock_put(sk);
tp->ack.blocked = 0;
- if(tp->probe_timer.prev && del_timer(&tp->probe_timer))
+ if(timer_pending(&tp->probe_timer) && del_timer(&tp->probe_timer))
__sock_put(sk);
- if(sk->timer.prev && del_timer(&sk->timer))
+ if(timer_pending(&sk->timer) && del_timer(&sk->timer))
__sock_put(sk);
- spin_unlock_bh(&sk->timer_lock);
}
static void tcp_write_err(struct sock *sk)
@@ -138,6 +129,35 @@ static void tcp_write_err(struct sock *sk)
tcp_done(sk);
}
+/* Do not allow orphaned sockets to eat all our resources.
+ * This is direct violation of TCP specs, but it is required
+ * to prevent DoS attacks. It is called when a retransmission timeout
+ * or zero probe timeout occurs on orphaned socket.
+ *
+ * Criterium is still not confirmed experimentally and may change.
+ * We kill the socket, if:
+ * 1. If number of orphaned sockets exceeds an administratively configured
+ * limit.
+ * 2. Under pessimistic assumption that all the orphans eat memory not
+ * less than this one, total consumed memory exceeds all
+ * the available memory.
+ */
+static int tcp_out_of_resources(struct sock *sk, int do_reset)
+{
+ int orphans = atomic_read(&tcp_orphan_count);
+
+ if (orphans >= sysctl_tcp_max_orphans ||
+ ((orphans*atomic_read(&sk->wmem_alloc))>>PAGE_SHIFT) >= num_physpages) {
+ if (net_ratelimit())
+ printk(KERN_INFO "Out of socket memory\n");
+ if (do_reset)
+ tcp_send_active_reset(sk, GFP_ATOMIC);
+ tcp_done(sk);
+ return 1;
+ }
+ return 0;
+}
+
/* A write timeout has occurred. Process the after effects. */
static int tcp_write_timeout(struct sock *sk)
{
@@ -172,9 +192,14 @@ static int tcp_write_timeout(struct sock *sk)
dst_negative_advice(&sk->dst_cache);
}
+
retry_until = sysctl_tcp_retries2;
- if (sk->dead)
+ if (sk->dead) {
+ if (tcp_out_of_resources(sk, tp->retransmits < retry_until))
+ return 1;
+
retry_until = sysctl_tcp_orphan_retries;
+ }
}
if (tp->retransmits >= retry_until) {
@@ -257,7 +282,14 @@ static void tcp_probe_timer(unsigned long data)
* with RFCs, only probe timer combines both retransmission timeout
* and probe timeout in one bottle. --ANK
*/
- max_probes = sk->dead ? sysctl_tcp_orphan_retries : sysctl_tcp_retries2;
+ max_probes = sysctl_tcp_retries2;
+
+ if (sk->dead) {
+ if (tcp_out_of_resources(sk, tp->probes_out <= max_probes))
+ goto out_unlock;
+
+ max_probes = sysctl_tcp_orphan_retries;
+ }
if (tp->probes_out > max_probes) {
tcp_write_err(sk);
@@ -574,6 +606,8 @@ static void tcp_retransmit_timer(unsigned long data)
tp->retransmits++;
tp->rto = min(tp->rto << 1, TCP_RTO_MAX);
tcp_reset_xmit_timer(sk, TCP_TIME_RETRANS, tp->rto);
+ if (tp->retransmits > sysctl_tcp_retries1)
+ __sk_dst_reset(sk);
TCP_CHECK_TIMER(sk);
out_unlock:
@@ -676,19 +710,14 @@ static void tcp_synack_timer(struct sock *sk)
void tcp_delete_keepalive_timer (struct sock *sk)
{
- spin_lock_bh(&sk->timer_lock);
- if (sk->timer.prev && del_timer (&sk->timer))
+ if (timer_pending(&sk->timer) && del_timer (&sk->timer))
__sock_put(sk);
- spin_unlock_bh(&sk->timer_lock);
}
void tcp_reset_keepalive_timer (struct sock *sk, unsigned long len)
{
- spin_lock_bh(&sk->timer_lock);
- if(!sk->timer.prev || !del_timer(&sk->timer))
+ if (!mod_timer(&sk->timer, jiffies+len))
sock_hold(sk);
- mod_timer(&sk->timer, jiffies+len);
- spin_unlock_bh(&sk->timer_lock);
}
void tcp_set_keepalive(struct sock *sk, int val)
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index e188b4997..570e1de2b 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -5,7 +5,7 @@
*
* The User Datagram Protocol (UDP).
*
- * Version: $Id: udp.c,v 1.80 2000/02/27 19:51:43 davem Exp $
+ * Version: $Id: udp.c,v 1.81 2000/04/25 04:13:34 davem Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -1041,22 +1041,17 @@ out:
}
struct proto udp_prot = {
- udp_close, /* close */
- udp_connect, /* connect */
- udp_disconnect, /* disconnect */
- NULL, /* accept */
- udp_ioctl, /* ioctl */
- NULL, /* init */
- NULL, /* destroy */
- NULL, /* shutdown */
- ip_setsockopt, /* setsockopt */
- ip_getsockopt, /* getsockopt */
- udp_sendmsg, /* sendmsg */
- udp_recvmsg, /* recvmsg */
- NULL, /* bind */
- udp_queue_rcv_skb, /* backlog_rcv */
- udp_v4_hash, /* hash */
- udp_v4_unhash, /* unhash */
- udp_v4_get_port, /* good_socknum */
- "UDP", /* name */
+ name: "UDP",
+ close: udp_close,
+ connect: udp_connect,
+ disconnect: udp_disconnect,
+ ioctl: udp_ioctl,
+ setsockopt: ip_setsockopt,
+ getsockopt: ip_getsockopt,
+ sendmsg: udp_sendmsg,
+ recvmsg: udp_recvmsg,
+ backlog_rcv: udp_queue_rcv_skb,
+ hash: udp_v4_hash,
+ unhash: udp_v4_unhash,
+ get_port: udp_v4_get_port,
};