summaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/af_inet.c3
-rw-r--r--net/ipv4/devinet.c23
-rw-r--r--net/ipv4/ip_input.c2
-rw-r--r--net/ipv4/ip_output.c5
-rw-r--r--net/ipv4/multipath_wrandom.c6
-rw-r--r--net/ipv4/netfilter/ip_conntrack_ftp.c4
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_tcp.c2
-rw-r--r--net/ipv4/netfilter/ip_conntrack_standalone.c58
-rw-r--r--net/ipv4/netfilter/ip_nat_core.c9
-rw-r--r--net/ipv4/netfilter/ip_nat_standalone.c54
-rw-r--r--net/ipv4/netfilter/ip_queue.c20
-rw-r--r--net/ipv4/netfilter/iptable_raw.c6
-rw-r--r--net/ipv4/protocol.c2
-rw-r--r--net/ipv4/raw.c2
-rw-r--r--net/ipv4/route.c6
-rw-r--r--net/ipv4/tcp.c2
-rw-r--r--net/ipv4/tcp_diag.c3
-rw-r--r--net/ipv4/tcp_input.c3
-rw-r--r--net/ipv4/tcp_ipv4.c7
-rw-r--r--net/ipv4/tcp_minisocks.c2
-rw-r--r--net/ipv4/tcp_output.c27
-rw-r--r--net/ipv4/tcp_timer.c2
-rw-r--r--net/ipv4/udp.c2
-rw-r--r--net/ipv4/xfrm4_policy.c42
24 files changed, 210 insertions, 82 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index c34dab6..b3cb49c 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -7,7 +7,7 @@
*
* Version: $Id: af_inet.c,v 1.137 2002/02/01 22:01:03 davem Exp $
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Florian La Roche, <flla@stud.uni-sb.de>
* Alan Cox, <A.Cox@swansea.ac.uk>
@@ -73,7 +73,6 @@
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/kernel.h>
-#include <linux/major.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/timer.h>
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index eea7ef0..3cc9673 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -9,7 +9,7 @@
* 2 of the License, or (at your option) any later version.
*
* Derived from the IP parts of dev.c 1.0.19
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Mark Evans, <evansmp@uhura.aston.ac.uk>
*
@@ -1107,17 +1107,18 @@ static void rtmsg_ifa(int event, struct in_ifaddr* ifa)
}
}
-static struct rtnetlink_link inet_rtnetlink_table[RTM_MAX - RTM_BASE + 1] = {
- [4] = { .doit = inet_rtm_newaddr, },
- [5] = { .doit = inet_rtm_deladdr, },
- [6] = { .dumpit = inet_dump_ifaddr, },
- [8] = { .doit = inet_rtm_newroute, },
- [9] = { .doit = inet_rtm_delroute, },
- [10] = { .doit = inet_rtm_getroute, .dumpit = inet_dump_fib, },
+static struct rtnetlink_link inet_rtnetlink_table[RTM_NR_MSGTYPES] = {
+ [RTM_NEWADDR - RTM_BASE] = { .doit = inet_rtm_newaddr, },
+ [RTM_DELADDR - RTM_BASE] = { .doit = inet_rtm_deladdr, },
+ [RTM_GETADDR - RTM_BASE] = { .dumpit = inet_dump_ifaddr, },
+ [RTM_NEWROUTE - RTM_BASE] = { .doit = inet_rtm_newroute, },
+ [RTM_DELROUTE - RTM_BASE] = { .doit = inet_rtm_delroute, },
+ [RTM_GETROUTE - RTM_BASE] = { .doit = inet_rtm_getroute,
+ .dumpit = inet_dump_fib, },
#ifdef CONFIG_IP_MULTIPLE_TABLES
- [16] = { .doit = inet_rtm_newrule, },
- [17] = { .doit = inet_rtm_delrule, },
- [18] = { .dumpit = inet_dump_rules, },
+ [RTM_NEWRULE - RTM_BASE] = { .doit = inet_rtm_newrule, },
+ [RTM_DELRULE - RTM_BASE] = { .doit = inet_rtm_delrule, },
+ [RTM_GETRULE - RTM_BASE] = { .dumpit = inet_dump_rules, },
#endif
};
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c
index a0d0833..4e47a26 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -7,7 +7,7 @@
*
* Version: $Id: ip_input.c,v 1.55 2002/01/12 07:39:45 davem Exp $
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Donald Becker, <becker@super.org>
* Alan Cox, <Alan.Cox@linux.org>
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 30ab7b6..daebd93 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -7,7 +7,7 @@
*
* Version: $Id: ip_output.c,v 1.100 2002/02/01 22:01:03 davem Exp $
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Donald Becker, <becker@super.org>
* Alan Cox, <Alan.Cox@linux.org>
@@ -111,6 +111,7 @@ static int ip_dev_loopback_xmit(struct sk_buff *newskb)
#ifdef CONFIG_NETFILTER_DEBUG
nf_debug_ip_loopback_xmit(newskb);
#endif
+ nf_reset(newskb);
netif_rx(newskb);
return 0;
}
@@ -195,6 +196,8 @@ static inline int ip_finish_output2(struct sk_buff *skb)
nf_debug_ip_finish_output2(skb);
#endif /*CONFIG_NETFILTER_DEBUG*/
+ nf_reset(skb);
+
if (hh) {
int hh_alen;
diff --git a/net/ipv4/multipath_wrandom.c b/net/ipv4/multipath_wrandom.c
index 10b23e1..c3d2ca1 100644
--- a/net/ipv4/multipath_wrandom.c
+++ b/net/ipv4/multipath_wrandom.c
@@ -172,7 +172,7 @@ static void wrandom_select_route(const struct flowi *flp,
multipath_comparekeys(&rt->fl, flp)) {
struct multipath_candidate* mpc =
(struct multipath_candidate*)
- kmalloc(size_mpc, GFP_KERNEL);
+ kmalloc(size_mpc, GFP_ATOMIC);
if (!mpc)
return;
@@ -244,7 +244,7 @@ static void wrandom_set_nhinfo(__u32 network,
if (!target_route) {
const size_t size_rt = sizeof(struct multipath_route);
target_route = (struct multipath_route *)
- kmalloc(size_rt, GFP_KERNEL);
+ kmalloc(size_rt, GFP_ATOMIC);
target_route->gw = nh->nh_gw;
target_route->oif = nh->nh_oif;
@@ -265,7 +265,7 @@ static void wrandom_set_nhinfo(__u32 network,
if (!target_dest) {
const size_t size_dst = sizeof(struct multipath_dest);
target_dest = (struct multipath_dest*)
- kmalloc(size_dst, GFP_KERNEL);
+ kmalloc(size_dst, GFP_ATOMIC);
target_dest->nh_info = nh;
target_dest->network = network;
diff --git a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c
index 12b88cb..dd86503 100644
--- a/net/ipv4/netfilter/ip_conntrack_ftp.c
+++ b/net/ipv4/netfilter/ip_conntrack_ftp.c
@@ -252,7 +252,7 @@ static int find_pattern(const char *data, size_t dlen,
}
/* Look up to see if we're just after a \n. */
-static int find_nl_seq(u16 seq, const struct ip_ct_ftp_master *info, int dir)
+static int find_nl_seq(u32 seq, const struct ip_ct_ftp_master *info, int dir)
{
unsigned int i;
@@ -263,7 +263,7 @@ static int find_nl_seq(u16 seq, const struct ip_ct_ftp_master *info, int dir)
}
/* We don't update if it's older than what we have. */
-static void update_nl_seq(u16 nl_seq, struct ip_ct_ftp_master *info, int dir)
+static void update_nl_seq(u32 nl_seq, struct ip_ct_ftp_master *info, int dir)
{
unsigned int i, oldest = NUM_SEQ_TO_REMEMBER;
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
index e800b16..721ddbf 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
@@ -770,6 +770,7 @@ static u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG) + 1] =
{
[TH_SYN] = 1,
[TH_SYN|TH_ACK] = 1,
+ [TH_SYN|TH_ACK|TH_PUSH] = 1,
[TH_RST] = 1,
[TH_RST|TH_ACK] = 1,
[TH_RST|TH_ACK|TH_PUSH] = 1,
@@ -818,6 +819,7 @@ static int tcp_error(struct sk_buff *skb,
*/
/* FIXME: Source route IP option packets --RR */
if (hooknum == NF_IP_PRE_ROUTING
+ && skb->ip_summed != CHECKSUM_UNNECESSARY
&& csum_tcpudp_magic(iph->saddr, iph->daddr, tcplen, IPPROTO_TCP,
skb->ip_summed == CHECKSUM_HW ? skb->csum
: skb_checksum(skb, iph->ihl*4, tcplen, 0))) {
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
index 80a7bde..46ca45f 100644
--- a/net/ipv4/netfilter/ip_conntrack_standalone.c
+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c
@@ -401,6 +401,16 @@ static unsigned int ip_confirm(unsigned int hooknum,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
+ /* We've seen it coming out the other side: confirm it */
+ return ip_conntrack_confirm(pskb);
+}
+
+static unsigned int ip_conntrack_help(unsigned int hooknum,
+ struct sk_buff **pskb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
struct ip_conntrack *ct;
enum ip_conntrack_info ctinfo;
@@ -412,9 +422,7 @@ static unsigned int ip_confirm(unsigned int hooknum,
if (ret != NF_ACCEPT)
return ret;
}
-
- /* We've seen it coming out the other side: confirm it */
- return ip_conntrack_confirm(pskb);
+ return NF_ACCEPT;
}
static unsigned int ip_conntrack_defrag(unsigned int hooknum,
@@ -423,13 +431,6 @@ static unsigned int ip_conntrack_defrag(unsigned int hooknum,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
-#if !defined(CONFIG_IP_NF_NAT) && !defined(CONFIG_IP_NF_NAT_MODULE)
- /* Previously seen (loopback)? Ignore. Do this before
- fragment check. */
- if ((*pskb)->nfct)
- return NF_ACCEPT;
-#endif
-
/* Gather fragments. */
if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
*pskb = ip_ct_gather_frags(*pskb,
@@ -516,13 +517,30 @@ static struct nf_hook_ops ip_conntrack_local_out_ops = {
.priority = NF_IP_PRI_CONNTRACK,
};
+/* helpers */
+static struct nf_hook_ops ip_conntrack_helper_out_ops = {
+ .hook = ip_conntrack_help,
+ .owner = THIS_MODULE,
+ .pf = PF_INET,
+ .hooknum = NF_IP_POST_ROUTING,
+ .priority = NF_IP_PRI_CONNTRACK_HELPER,
+};
+
+static struct nf_hook_ops ip_conntrack_helper_in_ops = {
+ .hook = ip_conntrack_help,
+ .owner = THIS_MODULE,
+ .pf = PF_INET,
+ .hooknum = NF_IP_LOCAL_IN,
+ .priority = NF_IP_PRI_CONNTRACK_HELPER,
+};
+
/* Refragmenter; last chance. */
static struct nf_hook_ops ip_conntrack_out_ops = {
.hook = ip_refrag,
.owner = THIS_MODULE,
.pf = PF_INET,
.hooknum = NF_IP_POST_ROUTING,
- .priority = NF_IP_PRI_LAST,
+ .priority = NF_IP_PRI_CONNTRACK_CONFIRM,
};
static struct nf_hook_ops ip_conntrack_local_in_ops = {
@@ -530,7 +548,7 @@ static struct nf_hook_ops ip_conntrack_local_in_ops = {
.owner = THIS_MODULE,
.pf = PF_INET,
.hooknum = NF_IP_LOCAL_IN,
- .priority = NF_IP_PRI_LAST-1,
+ .priority = NF_IP_PRI_CONNTRACK_CONFIRM,
};
/* Sysctl support */
@@ -831,10 +849,20 @@ static int init_or_cleanup(int init)
printk("ip_conntrack: can't register local out hook.\n");
goto cleanup_inops;
}
+ ret = nf_register_hook(&ip_conntrack_helper_in_ops);
+ if (ret < 0) {
+ printk("ip_conntrack: can't register local in helper hook.\n");
+ goto cleanup_inandlocalops;
+ }
+ ret = nf_register_hook(&ip_conntrack_helper_out_ops);
+ if (ret < 0) {
+ printk("ip_conntrack: can't register postrouting helper hook.\n");
+ goto cleanup_helperinops;
+ }
ret = nf_register_hook(&ip_conntrack_out_ops);
if (ret < 0) {
printk("ip_conntrack: can't register post-routing hook.\n");
- goto cleanup_inandlocalops;
+ goto cleanup_helperoutops;
}
ret = nf_register_hook(&ip_conntrack_local_in_ops);
if (ret < 0) {
@@ -860,6 +888,10 @@ static int init_or_cleanup(int init)
nf_unregister_hook(&ip_conntrack_local_in_ops);
cleanup_inoutandlocalops:
nf_unregister_hook(&ip_conntrack_out_ops);
+ cleanup_helperoutops:
+ nf_unregister_hook(&ip_conntrack_helper_out_ops);
+ cleanup_helperinops:
+ nf_unregister_hook(&ip_conntrack_helper_in_ops);
cleanup_inandlocalops:
nf_unregister_hook(&ip_conntrack_local_out_ops);
cleanup_inops:
diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
index 162ceac..9fc6f93 100644
--- a/net/ipv4/netfilter/ip_nat_core.c
+++ b/net/ipv4/netfilter/ip_nat_core.c
@@ -356,15 +356,6 @@ unsigned int nat_packet(struct ip_conntrack *ct,
unsigned long statusbit;
enum ip_nat_manip_type mtype = HOOK2MANIP(hooknum);
- if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)
- && (hooknum == NF_IP_POST_ROUTING || hooknum == NF_IP_LOCAL_IN)) {
- DEBUGP("ip_nat_core: adjusting sequence number\n");
- /* future: put this in a l4-proto specific function,
- * and call this function here. */
- if (!ip_nat_seq_adjust(pskb, ct, ctinfo))
- return NF_DROP;
- }
-
if (mtype == IP_NAT_MANIP_SRC)
statusbit = IPS_SRC_NAT;
else
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index dec4a74..79f56f6 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -230,6 +230,25 @@ ip_nat_local_fn(unsigned int hooknum,
return ret;
}
+static unsigned int
+ip_nat_adjust(unsigned int hooknum,
+ struct sk_buff **pskb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *))
+{
+ struct ip_conntrack *ct;
+ enum ip_conntrack_info ctinfo;
+
+ ct = ip_conntrack_get(*pskb, &ctinfo);
+ if (ct && test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)) {
+ DEBUGP("ip_nat_standalone: adjusting sequence number\n");
+ if (!ip_nat_seq_adjust(pskb, ct, ctinfo))
+ return NF_DROP;
+ }
+ return NF_ACCEPT;
+}
+
/* We must be after connection tracking and before packet filtering. */
/* Before packet filtering, change destination */
@@ -250,6 +269,15 @@ static struct nf_hook_ops ip_nat_out_ops = {
.priority = NF_IP_PRI_NAT_SRC,
};
+/* After conntrack, adjust sequence number */
+static struct nf_hook_ops ip_nat_adjust_out_ops = {
+ .hook = ip_nat_adjust,
+ .owner = THIS_MODULE,
+ .pf = PF_INET,
+ .hooknum = NF_IP_POST_ROUTING,
+ .priority = NF_IP_PRI_NAT_SEQ_ADJUST,
+};
+
/* Before packet filtering, change destination */
static struct nf_hook_ops ip_nat_local_out_ops = {
.hook = ip_nat_local_fn,
@@ -268,6 +296,16 @@ static struct nf_hook_ops ip_nat_local_in_ops = {
.priority = NF_IP_PRI_NAT_SRC,
};
+/* After conntrack, adjust sequence number */
+static struct nf_hook_ops ip_nat_adjust_in_ops = {
+ .hook = ip_nat_adjust,
+ .owner = THIS_MODULE,
+ .pf = PF_INET,
+ .hooknum = NF_IP_LOCAL_IN,
+ .priority = NF_IP_PRI_NAT_SEQ_ADJUST,
+};
+
+
static int init_or_cleanup(int init)
{
int ret = 0;
@@ -296,10 +334,20 @@ static int init_or_cleanup(int init)
printk("ip_nat_init: can't register out hook.\n");
goto cleanup_inops;
}
+ ret = nf_register_hook(&ip_nat_adjust_in_ops);
+ if (ret < 0) {
+ printk("ip_nat_init: can't register adjust in hook.\n");
+ goto cleanup_outops;
+ }
+ ret = nf_register_hook(&ip_nat_adjust_out_ops);
+ if (ret < 0) {
+ printk("ip_nat_init: can't register adjust out hook.\n");
+ goto cleanup_adjustin_ops;
+ }
ret = nf_register_hook(&ip_nat_local_out_ops);
if (ret < 0) {
printk("ip_nat_init: can't register local out hook.\n");
- goto cleanup_outops;
+ goto cleanup_adjustout_ops;;
}
ret = nf_register_hook(&ip_nat_local_in_ops);
if (ret < 0) {
@@ -312,6 +360,10 @@ static int init_or_cleanup(int init)
nf_unregister_hook(&ip_nat_local_in_ops);
cleanup_localoutops:
nf_unregister_hook(&ip_nat_local_out_ops);
+ cleanup_adjustout_ops:
+ nf_unregister_hook(&ip_nat_adjust_out_ops);
+ cleanup_adjustin_ops:
+ nf_unregister_hook(&ip_nat_adjust_in_ops);
cleanup_outops:
nf_unregister_hook(&ip_nat_out_ops);
cleanup_inops:
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index 9e40dff..e5746b6 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -546,20 +546,18 @@ ipq_rcv_skb(struct sk_buff *skb)
static void
ipq_rcv_sk(struct sock *sk, int len)
{
- do {
- struct sk_buff *skb;
+ struct sk_buff *skb;
+ unsigned int qlen;
- if (down_trylock(&ipqnl_sem))
- return;
+ down(&ipqnl_sem);
- while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
- ipq_rcv_skb(skb);
- kfree_skb(skb);
- }
+ for (qlen = skb_queue_len(&sk->sk_receive_queue); qlen; qlen--) {
+ skb = skb_dequeue(&sk->sk_receive_queue);
+ ipq_rcv_skb(skb);
+ kfree_skb(skb);
+ }
- up(&ipqnl_sem);
-
- } while (ipqnl && ipqnl->sk_receive_queue.qlen);
+ up(&ipqnl_sem);
}
static int
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c
index 01b4a3c..47449ba 100644
--- a/net/ipv4/netfilter/iptable_raw.c
+++ b/net/ipv4/netfilter/iptable_raw.c
@@ -103,13 +103,15 @@ static struct nf_hook_ops ipt_ops[] = {
.hook = ipt_hook,
.pf = PF_INET,
.hooknum = NF_IP_PRE_ROUTING,
- .priority = NF_IP_PRI_RAW
+ .priority = NF_IP_PRI_RAW,
+ .owner = THIS_MODULE,
},
{
.hook = ipt_hook,
.pf = PF_INET,
.hooknum = NF_IP_LOCAL_OUT,
- .priority = NF_IP_PRI_RAW
+ .priority = NF_IP_PRI_RAW,
+ .owner = THIS_MODULE,
},
};
diff --git a/net/ipv4/protocol.c b/net/ipv4/protocol.c
index 90a587c..0db405a 100644
--- a/net/ipv4/protocol.c
+++ b/net/ipv4/protocol.c
@@ -7,7 +7,7 @@
*
* Version: $Id: protocol.c,v 1.14 2001/05/18 02:25:49 davem Exp $
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
*
* Fixes:
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 93624a3..5b1ec58 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -7,7 +7,7 @@
*
* Version: $Id: raw.c,v 1.64 2002/02/01 22:01:04 davem Exp $
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
*
* Fixes:
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index bb90a0c..a682d28 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -7,7 +7,7 @@
*
* Version: $Id: route.c,v 1.103 2002/01/12 07:44:09 davem Exp $
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Alan Cox, <gw4pts@gw4pts.ampr.org>
* Linus Torvalds, <Linus.Torvalds@helsinki.fi>
@@ -397,7 +397,7 @@ static int rt_cpu_seq_show(struct seq_file *seq, void *v)
struct rt_cache_stat *st = v;
if (v == SEQ_START_TOKEN) {
- seq_printf(seq, "entries in_hit in_slow_tot in_no_route in_brd in_martian_dst in_martian_src out_hit out_slow_tot out_slow_mc gc_total gc_ignored gc_goal_miss gc_dst_overflow in_hlist_search out_hlist_search\n");
+ seq_printf(seq, "entries in_hit in_slow_tot in_slow_mc in_no_route in_brd in_martian_dst in_martian_src out_hit out_slow_tot out_slow_mc gc_total gc_ignored gc_goal_miss gc_dst_overflow in_hlist_search out_hlist_search\n");
return 0;
}
@@ -2843,7 +2843,7 @@ ctl_table ipv4_route_table[] = {
.procname = "flush",
.data = &flush_delay,
.maxlen = sizeof(int),
- .mode = 0644,
+ .mode = 0200,
.proc_handler = &ipv4_sysctl_rtcache_flush,
.strategy = &ipv4_sysctl_rtcache_flush_strategy,
},
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 5cff56a..a037baf 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -7,7 +7,7 @@
*
* Version: $Id: tcp.c,v 1.216 2002/02/01 22:01:04 davem Exp $
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Mark Evans, <evansmp@uhura.aston.ac.uk>
* Corey Minyard <wf-rch!minyard@relay.EU.net>
diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c
index 313c140..8faa894 100644
--- a/net/ipv4/tcp_diag.c
+++ b/net/ipv4/tcp_diag.c
@@ -777,8 +777,9 @@ static inline void tcpdiag_rcv_skb(struct sk_buff *skb)
static void tcpdiag_rcv(struct sock *sk, int len)
{
struct sk_buff *skb;
+ unsigned int qlen = skb_queue_len(&sk->sk_receive_queue);
- while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) {
+ while (qlen-- && (skb = skb_dequeue(&sk->sk_receive_queue))) {
tcpdiag_rcv_skb(skb);
kfree_skb(skb);
}
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 2504927..79835a6 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -7,7 +7,7 @@
*
* Version: $Id: tcp_input.c,v 1.243 2002/02/01 22:01:04 davem Exp $
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Mark Evans, <evansmp@uhura.aston.ac.uk>
* Corey Minyard <wf-rch!minyard@relay.EU.net>
@@ -3517,7 +3517,6 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
if (TCP_SKB_CB(skb)->seq == TCP_SKB_CB(skb)->end_seq)
goto drop;
- th = skb->h.th;
__skb_pull(skb, th->doff*4);
TCP_ECN_accept_cwr(tp, skb);
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 3ac6659..dad98e4 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -222,10 +222,13 @@ static int tcp_v4_get_port(struct sock *sk, unsigned short snum)
int rover;
spin_lock(&tcp_portalloc_lock);
- rover = tcp_port_rover;
+ if (tcp_port_rover < low)
+ rover = low;
+ else
+ rover = tcp_port_rover;
do {
rover++;
- if (rover < low || rover > high)
+ if (rover > high)
rover = low;
head = &tcp_bhash[tcp_bhashfn(rover)];
spin_lock(&head->lock);
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index fd70509..eea1a17 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -7,7 +7,7 @@
*
* Version: $Id: tcp_minisocks.c,v 1.15 2002/02/01 22:01:04 davem Exp $
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Mark Evans, <evansmp@uhura.aston.ac.uk>
* Corey Minyard <wf-rch!minyard@relay.EU.net>
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 13c14cb..fa24e7a 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -7,7 +7,7 @@
*
* Version: $Id: tcp_output.c,v 1.146 2002/02/01 22:01:04 davem Exp $
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Mark Evans, <evansmp@uhura.aston.ac.uk>
* Corey Minyard <wf-rch!minyard@relay.EU.net>
@@ -427,7 +427,7 @@ void tcp_push_one(struct sock *sk, unsigned cur_mss)
struct tcp_sock *tp = tcp_sk(sk);
struct sk_buff *skb = sk->sk_send_head;
- if (tcp_snd_test(tp, skb, cur_mss, TCP_NAGLE_PUSH)) {
+ if (tcp_snd_test(sk, skb, cur_mss, TCP_NAGLE_PUSH)) {
/* Send it out now. */
TCP_SKB_CB(skb)->when = tcp_time_stamp;
tcp_tso_set_push(skb);
@@ -440,9 +440,12 @@ void tcp_push_one(struct sock *sk, unsigned cur_mss)
}
}
-void tcp_set_skb_tso_segs(struct sk_buff *skb, unsigned int mss_std)
+void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb)
{
- if (skb->len <= mss_std) {
+ struct tcp_sock *tp = tcp_sk(sk);
+
+ if (skb->len <= tp->mss_cache_std ||
+ !(sk->sk_route_caps & NETIF_F_TSO)) {
/* Avoid the costly divide in the normal
* non-TSO case.
*/
@@ -451,10 +454,10 @@ void tcp_set_skb_tso_segs(struct sk_buff *skb, unsigned int mss_std)
} else {
unsigned int factor;
- factor = skb->len + (mss_std - 1);
- factor /= mss_std;
+ factor = skb->len + (tp->mss_cache_std - 1);
+ factor /= tp->mss_cache_std;
skb_shinfo(skb)->tso_segs = factor;
- skb_shinfo(skb)->tso_size = mss_std;
+ skb_shinfo(skb)->tso_size = tp->mss_cache_std;
}
}
@@ -525,8 +528,8 @@ static int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len)
}
/* Fix up tso_factor for both original and new SKB. */
- tcp_set_skb_tso_segs(skb, tp->mss_cache_std);
- tcp_set_skb_tso_segs(buff, tp->mss_cache_std);
+ tcp_set_skb_tso_segs(sk, skb);
+ tcp_set_skb_tso_segs(sk, buff);
if (TCP_SKB_CB(skb)->sacked & TCPCB_LOST) {
tp->lost_out += tcp_skb_pcount(skb);
@@ -601,7 +604,7 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len)
* factor and mss.
*/
if (tcp_skb_pcount(skb) > 1)
- tcp_set_skb_tso_segs(skb, tcp_skb_mss(skb));
+ tcp_set_skb_tso_segs(sk, skb);
return 0;
}
@@ -752,7 +755,7 @@ int tcp_write_xmit(struct sock *sk, int nonagle)
mss_now = tcp_current_mss(sk, 1);
while ((skb = sk->sk_send_head) &&
- tcp_snd_test(tp, skb, mss_now,
+ tcp_snd_test(sk, skb, mss_now,
tcp_skb_is_last(sk, skb) ? nonagle :
TCP_NAGLE_PUSH)) {
if (skb->len > mss_now) {
@@ -1676,7 +1679,7 @@ int tcp_write_wakeup(struct sock *sk)
tp->mss_cache = tp->mss_cache_std;
}
} else if (!tcp_skb_pcount(skb))
- tcp_set_skb_tso_segs(skb, tp->mss_cache_std);
+ tcp_set_skb_tso_segs(sk, skb);
TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH;
TCP_SKB_CB(skb)->when = tcp_time_stamp;
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index 85b279f..799ebe0 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -7,7 +7,7 @@
*
* Version: $Id: tcp_timer.c,v 1.88 2002/02/01 22:01:04 davem Exp $
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Mark Evans, <evansmp@uhura.aston.ac.uk>
* Corey Minyard <wf-rch!minyard@relay.EU.net>
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 8a21323..4a6952e 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -7,7 +7,7 @@
*
* Version: $Id: udp.c,v 1.102 2002/02/01 22:01:04 davem Exp $
*
- * Authors: Ross Biro, <bir7@leland.Stanford.Edu>
+ * Authors: Ross Biro
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
* Arnt Gulbrandsen, <agulbra@nvg.unit.no>
* Alan Cox, <Alan.Cox@linux.org>
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 7fe2afd..b2b60f3 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -8,7 +8,10 @@
*
*/
+#include <asm/bug.h>
+#include <linux/compiler.h>
#include <linux/config.h>
+#include <linux/inetdevice.h>
#include <net/xfrm.h>
#include <net/ip.h>
@@ -152,6 +155,8 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
x->u.rt.rt_dst = rt0->rt_dst;
x->u.rt.rt_gateway = rt->rt_gateway;
x->u.rt.rt_spec_dst = rt0->rt_spec_dst;
+ x->u.rt.idev = rt0->idev;
+ in_dev_hold(rt0->idev);
header_len -= x->u.dst.xfrm->props.header_len;
trailer_len -= x->u.dst.xfrm->props.trailer_len;
}
@@ -243,11 +248,48 @@ static void xfrm4_update_pmtu(struct dst_entry *dst, u32 mtu)
path->ops->update_pmtu(path, mtu);
}
+static void xfrm4_dst_destroy(struct dst_entry *dst)
+{
+ struct xfrm_dst *xdst = (struct xfrm_dst *)dst;
+
+ if (likely(xdst->u.rt.idev))
+ in_dev_put(xdst->u.rt.idev);
+ xfrm_dst_destroy(xdst);
+}
+
+static void xfrm4_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
+ int unregister)
+{
+ struct xfrm_dst *xdst;
+
+ if (!unregister)
+ return;
+
+ xdst = (struct xfrm_dst *)dst;
+ if (xdst->u.rt.idev->dev == dev) {
+ struct in_device *loopback_idev = in_dev_get(&loopback_dev);
+ BUG_ON(!loopback_idev);
+
+ do {
+ in_dev_put(xdst->u.rt.idev);
+ xdst->u.rt.idev = loopback_idev;
+ in_dev_hold(loopback_idev);
+ xdst = (struct xfrm_dst *)xdst->u.dst.child;
+ } while (xdst->u.dst.xfrm);
+
+ __in_dev_put(loopback_idev);
+ }
+
+ xfrm_dst_ifdown(dst, dev);
+}
+
static struct dst_ops xfrm4_dst_ops = {
.family = AF_INET,
.protocol = __constant_htons(ETH_P_IP),
.gc = xfrm4_garbage_collect,
.update_pmtu = xfrm4_update_pmtu,
+ .destroy = xfrm4_dst_destroy,
+ .ifdown = xfrm4_dst_ifdown,
.gc_thresh = 1024,
.entry_size = sizeof(struct xfrm_dst),
};
OpenPOWER on IntegriCloud