summaryrefslogtreecommitdiff
path: root/net/ipv4
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/fib_rules.c27
-rw-r--r--net/ipv4/icmp.c2
-rw-r--r--net/ipv4/inet_hashtables.c2
-rw-r--r--net/ipv4/ip_output.c6
-rw-r--r--net/ipv4/netfilter/arp_tables.c6
-rw-r--r--net/ipv4/netfilter/ip_conntrack_core.c4
-rw-r--r--net/ipv4/netfilter/ip_conntrack_helper_h323.c4
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netlink.c72
-rw-r--r--net/ipv4/netfilter/ip_nat_standalone.c2
-rw-r--r--net/ipv4/netfilter/ip_tables.c15
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c1
-rw-r--r--net/ipv4/route.c45
-rw-r--r--net/ipv4/tcp.c28
13 files changed, 136 insertions, 78 deletions
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index 768e8f5d7daa..ec566f3e66c7 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -104,6 +104,8 @@ static struct hlist_head fib_rules;
/* writer func called from netlink -- rtnl_sem hold*/
+static void rtmsg_rule(int, struct fib_rule *);
+
int inet_rtm_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
{
struct rtattr **rta = arg;
@@ -131,6 +133,7 @@ int inet_rtm_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
hlist_del_rcu(&r->hlist);
r->r_dead = 1;
+ rtmsg_rule(RTM_DELRULE, r);
fib_rule_put(r);
err = 0;
break;
@@ -253,6 +256,7 @@ int inet_rtm_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
else
hlist_add_before_rcu(&new_r->hlist, &r->hlist);
+ rtmsg_rule(RTM_NEWRULE, new_r);
return 0;
}
@@ -382,14 +386,14 @@ static struct notifier_block fib_rules_notifier = {
static __inline__ int inet_fill_rule(struct sk_buff *skb,
struct fib_rule *r,
- struct netlink_callback *cb,
+ u32 pid, u32 seq, int event,
unsigned int flags)
{
struct rtmsg *rtm;
struct nlmsghdr *nlh;
unsigned char *b = skb->tail;
- nlh = NLMSG_NEW_ANSWER(skb, cb, RTM_NEWRULE, sizeof(*rtm), flags);
+ nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*rtm), flags);
rtm = NLMSG_DATA(nlh);
rtm->rtm_family = AF_INET;
rtm->rtm_dst_len = r->r_dst_len;
@@ -430,6 +434,21 @@ rtattr_failure:
/* callers should hold rtnl semaphore */
+static void rtmsg_rule(int event, struct fib_rule *r)
+{
+ int size = NLMSG_SPACE(sizeof(struct rtmsg) + 128);
+ struct sk_buff *skb = alloc_skb(size, GFP_KERNEL);
+
+ if (!skb)
+ netlink_set_err(rtnl, 0, RTNLGRP_IPV4_RULE, ENOBUFS);
+ else if (inet_fill_rule(skb, r, 0, 0, event, 0) < 0) {
+ kfree_skb(skb);
+ netlink_set_err(rtnl, 0, RTNLGRP_IPV4_RULE, EINVAL);
+ } else {
+ netlink_broadcast(rtnl, skb, 0, RTNLGRP_IPV4_RULE, GFP_KERNEL);
+ }
+}
+
int inet_dump_rules(struct sk_buff *skb, struct netlink_callback *cb)
{
int idx = 0;
@@ -442,7 +461,9 @@ int inet_dump_rules(struct sk_buff *skb, struct netlink_callback *cb)
if (idx < s_idx)
continue;
- if (inet_fill_rule(skb, r, cb, NLM_F_MULTI) < 0)
+ if (inet_fill_rule(skb, r, NETLINK_CB(cb->skb).pid,
+ cb->nlh->nlmsg_seq,
+ RTM_NEWRULE, NLM_F_MULTI) < 0)
break;
idx++;
}
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index e7bbff4340bb..9831fd2c73a0 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -753,7 +753,7 @@ static void icmp_redirect(struct sk_buff *skb)
case ICMP_REDIR_HOST:
case ICMP_REDIR_HOSTTOS:
ip_rt_redirect(skb->nh.iph->saddr, ip, skb->h.icmph->un.gateway,
- iph->saddr, iph->tos, skb->dev);
+ iph->saddr, skb->dev);
break;
}
out:
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index 33228115cda4..ef7366fc132f 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -315,7 +315,7 @@ ok:
spin_unlock(&head->lock);
if (tw) {
- inet_twsk_deschedule(tw, death_row);;
+ inet_twsk_deschedule(tw, death_row);
inet_twsk_put(tw);
}
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 8ee4d016740d..f75ff1d96551 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1249,11 +1249,7 @@ int ip_push_pending_frames(struct sock *sk)
iph->tos = inet->tos;
iph->tot_len = htons(skb->len);
iph->frag_off = df;
- if (!df) {
- __ip_select_ident(iph, &rt->u.dst, 0);
- } else {
- iph->id = htons(inet->id++);
- }
+ ip_select_ident(iph, &rt->u.dst, sk);
iph->ttl = ttl;
iph->protocol = sk->sk_protocol;
iph->saddr = rt->rt_src;
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index f7efb3f27bf5..ff0c594a4198 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -1146,12 +1146,14 @@ void arpt_unregister_table(struct arpt_table *table)
static struct arpt_target arpt_standard_target = {
.name = ARPT_STANDARD_TARGET,
.targetsize = sizeof(int),
+ .family = NF_ARP,
};
static struct arpt_target arpt_error_target = {
.name = ARPT_ERROR_TARGET,
.target = arpt_error,
.targetsize = ARPT_FUNCTION_MAXNAMELEN,
+ .family = NF_ARP,
};
static struct nf_sockopt_ops arpt_sockopts = {
@@ -1171,8 +1173,8 @@ static int __init init(void)
xt_proto_init(NF_ARP);
/* Noone else will be downing sem now, so we won't sleep */
- xt_register_target(NF_ARP, &arpt_standard_target);
- xt_register_target(NF_ARP, &arpt_error_target);
+ xt_register_target(&arpt_standard_target);
+ xt_register_target(&arpt_error_target);
/* Register setsockopt */
ret = nf_register_sockopt(&arpt_sockopts);
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
index 84c66dbfedaf..9e34034729a6 100644
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -77,8 +77,8 @@ unsigned int ip_ct_log_invalid;
static LIST_HEAD(unconfirmed);
static int ip_conntrack_vmalloc;
-static unsigned int ip_conntrack_next_id = 1;
-static unsigned int ip_conntrack_expect_next_id = 1;
+static unsigned int ip_conntrack_next_id;
+static unsigned int ip_conntrack_expect_next_id;
#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
struct notifier_block *ip_conntrack_chain;
struct notifier_block *ip_conntrack_expect_chain;
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323.c b/net/ipv4/netfilter/ip_conntrack_helper_h323.c
index 20da6730b860..daeb1395faa4 100644
--- a/net/ipv4/netfilter/ip_conntrack_helper_h323.c
+++ b/net/ipv4/netfilter/ip_conntrack_helper_h323.c
@@ -639,8 +639,8 @@ void ip_conntrack_h245_expect(struct ip_conntrack *new,
}
/****************************************************************************/
-static int get_h225_addr(unsigned char *data, TransportAddress * addr,
- u_int32_t * ip, u_int16_t * port)
+int get_h225_addr(unsigned char *data, TransportAddress * addr,
+ u_int32_t * ip, u_int16_t * port)
{
unsigned char *p;
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c
index 5ce2e3fc2c7f..9b6e19bae90f 100644
--- a/net/ipv4/netfilter/ip_conntrack_netlink.c
+++ b/net/ipv4/netfilter/ip_conntrack_netlink.c
@@ -4,7 +4,7 @@
* (C) 2001 by Jay Schulist <jschlst@samba.org>
* (C) 2002-2005 by Harald Welte <laforge@gnumonks.org>
* (C) 2003 by Patrick Mchardy <kaber@trash.net>
- * (C) 2005 by Pablo Neira Ayuso <pablo@eurodev.net>
+ * (C) 2005-2006 by Pablo Neira Ayuso <pablo@eurodev.net>
*
* I've reworked this stuff to use attributes instead of conntrack
* structures. 5.44 am. I need more tea. --pablo 05/07/11.
@@ -53,20 +53,18 @@ static char __initdata version[] = "0.90";
static inline int
ctnetlink_dump_tuples_proto(struct sk_buff *skb,
- const struct ip_conntrack_tuple *tuple)
+ const struct ip_conntrack_tuple *tuple,
+ struct ip_conntrack_protocol *proto)
{
- struct ip_conntrack_protocol *proto;
int ret = 0;
+ struct nfattr *nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO);
NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum);
- /* If no protocol helper is found, this function will return the
- * generic protocol helper, so proto won't *ever* be NULL */
- proto = ip_conntrack_proto_find_get(tuple->dst.protonum);
if (likely(proto->tuple_to_nfattr))
ret = proto->tuple_to_nfattr(skb, tuple);
- ip_conntrack_proto_put(proto);
+ NFA_NEST_END(skb, nest_parms);
return ret;
@@ -75,28 +73,41 @@ nfattr_failure:
}
static inline int
-ctnetlink_dump_tuples(struct sk_buff *skb,
- const struct ip_conntrack_tuple *tuple)
+ctnetlink_dump_tuples_ip(struct sk_buff *skb,
+ const struct ip_conntrack_tuple *tuple)
{
- struct nfattr *nest_parms;
- int ret;
+ struct nfattr *nest_parms = NFA_NEST(skb, CTA_TUPLE_IP);
- nest_parms = NFA_NEST(skb, CTA_TUPLE_IP);
NFA_PUT(skb, CTA_IP_V4_SRC, sizeof(u_int32_t), &tuple->src.ip);
NFA_PUT(skb, CTA_IP_V4_DST, sizeof(u_int32_t), &tuple->dst.ip);
- NFA_NEST_END(skb, nest_parms);
- nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO);
- ret = ctnetlink_dump_tuples_proto(skb, tuple);
NFA_NEST_END(skb, nest_parms);
- return ret;
+ return 0;
nfattr_failure:
return -1;
}
static inline int
+ctnetlink_dump_tuples(struct sk_buff *skb,
+ const struct ip_conntrack_tuple *tuple)
+{
+ int ret;
+ struct ip_conntrack_protocol *proto;
+
+ ret = ctnetlink_dump_tuples_ip(skb, tuple);
+ if (unlikely(ret < 0))
+ return ret;
+
+ proto = ip_conntrack_proto_find_get(tuple->dst.protonum);
+ ret = ctnetlink_dump_tuples_proto(skb, tuple, proto);
+ ip_conntrack_proto_put(proto);
+
+ return ret;
+}
+
+static inline int
ctnetlink_dump_status(struct sk_buff *skb, const struct ip_conntrack *ct)
{
u_int32_t status = htonl((u_int32_t) ct->status);
@@ -1135,6 +1146,33 @@ nfattr_failure:
}
static inline int
+ctnetlink_exp_dump_mask(struct sk_buff *skb,
+ const struct ip_conntrack_tuple *tuple,
+ const struct ip_conntrack_tuple *mask)
+{
+ int ret;
+ struct ip_conntrack_protocol *proto;
+ struct nfattr *nest_parms = NFA_NEST(skb, CTA_EXPECT_MASK);
+
+ ret = ctnetlink_dump_tuples_ip(skb, mask);
+ if (unlikely(ret < 0))
+ goto nfattr_failure;
+
+ proto = ip_conntrack_proto_find_get(tuple->dst.protonum);
+ ret = ctnetlink_dump_tuples_proto(skb, mask, proto);
+ ip_conntrack_proto_put(proto);
+ if (unlikely(ret < 0))
+ goto nfattr_failure;
+
+ NFA_NEST_END(skb, nest_parms);
+
+ return 0;
+
+nfattr_failure:
+ return -1;
+}
+
+static inline int
ctnetlink_exp_dump_expect(struct sk_buff *skb,
const struct ip_conntrack_expect *exp)
{
@@ -1144,7 +1182,7 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb,
if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0)
goto nfattr_failure;
- if (ctnetlink_exp_dump_tuple(skb, &exp->mask, CTA_EXPECT_MASK) < 0)
+ if (ctnetlink_exp_dump_mask(skb, &exp->tuple, &exp->mask) < 0)
goto nfattr_failure;
if (ctnetlink_exp_dump_tuple(skb,
&master->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index ab1f88fa21ec..380aef3d7865 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -394,7 +394,7 @@ static int init_or_cleanup(int init)
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_adjustout_ops;;
+ goto cleanup_adjustout_ops;
}
ret = nf_register_hook(&ip_nat_local_in_ops);
if (ret < 0) {
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 39705f9bc154..a7b194c4d79d 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -1335,12 +1335,14 @@ icmp_checkentry(const char *tablename,
static struct ipt_target ipt_standard_target = {
.name = IPT_STANDARD_TARGET,
.targetsize = sizeof(int),
+ .family = AF_INET,
};
static struct ipt_target ipt_error_target = {
.name = IPT_ERROR_TARGET,
.target = ipt_error,
.targetsize = IPT_FUNCTION_MAXNAMELEN,
+ .family = AF_INET,
};
static struct nf_sockopt_ops ipt_sockopts = {
@@ -1358,6 +1360,7 @@ static struct ipt_match icmp_matchstruct = {
.match = icmp_match,
.matchsize = sizeof(struct ipt_icmp),
.proto = IPPROTO_ICMP,
+ .family = AF_INET,
.checkentry = icmp_checkentry,
};
@@ -1368,9 +1371,9 @@ static int __init init(void)
xt_proto_init(AF_INET);
/* Noone else will be downing sem now, so we won't sleep */
- xt_register_target(AF_INET, &ipt_standard_target);
- xt_register_target(AF_INET, &ipt_error_target);
- xt_register_match(AF_INET, &icmp_matchstruct);
+ xt_register_target(&ipt_standard_target);
+ xt_register_target(&ipt_error_target);
+ xt_register_match(&icmp_matchstruct);
/* Register setsockopt */
ret = nf_register_sockopt(&ipt_sockopts);
@@ -1387,9 +1390,9 @@ static void __exit fini(void)
{
nf_unregister_sockopt(&ipt_sockopts);
- xt_unregister_match(AF_INET, &icmp_matchstruct);
- xt_unregister_target(AF_INET, &ipt_error_target);
- xt_unregister_target(AF_INET, &ipt_standard_target);
+ xt_unregister_match(&icmp_matchstruct);
+ xt_unregister_target(&ipt_error_target);
+ xt_unregister_target(&ipt_standard_target);
xt_proto_fini(AF_INET);
}
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index cb9c661f3f33..c8abc9d859b9 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -568,6 +568,7 @@ static int init_or_cleanup(int init)
return ret;
}
+MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET));
MODULE_LICENSE("GPL");
static int __init init(void)
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index fca5fe0cf94a..94fcbc5e5a1b 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -55,6 +55,8 @@
* Robert Olsson : Added rt_cache statistics
* Arnaldo C. Melo : Convert proc stuff to seq_file
* Eric Dumazet : hashed spinlocks and rt_check_expire() fixes.
+ * Ilia Sotnikov : Ignore TOS on PMTUD and Redirect
+ * Ilia Sotnikov : Removed TOS from hash calculations
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -247,9 +249,9 @@ static DEFINE_PER_CPU(struct rt_cache_stat, rt_cache_stat);
static int rt_intern_hash(unsigned hash, struct rtable *rth,
struct rtable **res);
-static unsigned int rt_hash_code(u32 daddr, u32 saddr, u8 tos)
+static unsigned int rt_hash_code(u32 daddr, u32 saddr)
{
- return (jhash_3words(daddr, saddr, (u32) tos, rt_hash_rnd)
+ return (jhash_2words(daddr, saddr, rt_hash_rnd)
& rt_hash_mask);
}
@@ -1111,7 +1113,7 @@ static void rt_del(unsigned hash, struct rtable *rt)
}
void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw,
- u32 saddr, u8 tos, struct net_device *dev)
+ u32 saddr, struct net_device *dev)
{
int i, k;
struct in_device *in_dev = in_dev_get(dev);
@@ -1119,8 +1121,6 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw,
u32 skeys[2] = { saddr, 0 };
int ikeys[2] = { dev->ifindex, 0 };
- tos &= IPTOS_RT_MASK;
-
if (!in_dev)
return;
@@ -1141,8 +1141,7 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw,
for (i = 0; i < 2; i++) {
for (k = 0; k < 2; k++) {
unsigned hash = rt_hash_code(daddr,
- skeys[i] ^ (ikeys[k] << 5),
- tos);
+ skeys[i] ^ (ikeys[k] << 5));
rthp=&rt_hash_table[hash].chain;
@@ -1152,7 +1151,6 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw,
if (rth->fl.fl4_dst != daddr ||
rth->fl.fl4_src != skeys[i] ||
- rth->fl.fl4_tos != tos ||
rth->fl.oif != ikeys[k] ||
rth->fl.iif != 0) {
rthp = &rth->u.rt_next;
@@ -1232,10 +1230,9 @@ reject_redirect:
if (IN_DEV_LOG_MARTIANS(in_dev) && net_ratelimit())
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",
+ " Advised path = %u.%u.%u.%u -> %u.%u.%u.%u\n",
NIPQUAD(old_gw), dev->name, NIPQUAD(new_gw),
- NIPQUAD(saddr), NIPQUAD(daddr), tos);
+ NIPQUAD(saddr), NIPQUAD(daddr));
#endif
in_dev_put(in_dev);
}
@@ -1253,8 +1250,7 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
rt->u.dst.expires) {
unsigned hash = rt_hash_code(rt->fl.fl4_dst,
rt->fl.fl4_src ^
- (rt->fl.oif << 5),
- rt->fl.fl4_tos);
+ (rt->fl.oif << 5));
#if RT_CACHE_DEBUG >= 1
printk(KERN_DEBUG "ip_rt_advice: redirect to "
"%u.%u.%u.%u/%02x dropped\n",
@@ -1391,14 +1387,13 @@ unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu)
struct rtable *rth;
u32 skeys[2] = { iph->saddr, 0, };
u32 daddr = iph->daddr;
- u8 tos = iph->tos & IPTOS_RT_MASK;
unsigned short est_mtu = 0;
if (ipv4_config.no_pmtu_disc)
return 0;
for (i = 0; i < 2; i++) {
- unsigned hash = rt_hash_code(daddr, skeys[i], tos);
+ unsigned hash = rt_hash_code(daddr, skeys[i]);
rcu_read_lock();
for (rth = rcu_dereference(rt_hash_table[hash].chain); rth;
@@ -1407,7 +1402,6 @@ unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu)
rth->fl.fl4_src == skeys[i] &&
rth->rt_dst == daddr &&
rth->rt_src == iph->saddr &&
- rth->fl.fl4_tos == tos &&
rth->fl.iif == 0 &&
!(dst_metric_locked(&rth->u.dst, RTAX_MTU))) {
unsigned short mtu = new_mtu;
@@ -1658,7 +1652,7 @@ static int ip_route_input_mc(struct sk_buff *skb, u32 daddr, u32 saddr,
RT_CACHE_STAT_INC(in_slow_mc);
in_dev_put(in_dev);
- hash = rt_hash_code(daddr, saddr ^ (dev->ifindex << 5), tos);
+ hash = rt_hash_code(daddr, saddr ^ (dev->ifindex << 5));
return rt_intern_hash(hash, rth, (struct rtable**) &skb->dst);
e_nobufs:
@@ -1823,7 +1817,7 @@ static inline int ip_mkroute_input_def(struct sk_buff *skb,
return err;
/* put it into the cache */
- hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5), tos);
+ hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5));
return rt_intern_hash(hash, rth, (struct rtable**)&skb->dst);
}
@@ -1864,7 +1858,7 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
return err;
/* put it into the cache */
- hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5), tos);
+ hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5));
err = rt_intern_hash(hash, rth, &rtres);
if (err)
return err;
@@ -2041,7 +2035,7 @@ local_input:
rth->rt_flags &= ~RTCF_LOCAL;
}
rth->rt_type = res.type;
- hash = rt_hash_code(daddr, saddr ^ (fl.iif << 5), tos);
+ hash = rt_hash_code(daddr, saddr ^ (fl.iif << 5));
err = rt_intern_hash(hash, rth, (struct rtable**)&skb->dst);
goto done;
@@ -2088,7 +2082,7 @@ int ip_route_input(struct sk_buff *skb, u32 daddr, u32 saddr,
int iif = dev->ifindex;
tos &= IPTOS_RT_MASK;
- hash = rt_hash_code(daddr, saddr ^ (iif << 5), tos);
+ hash = rt_hash_code(daddr, saddr ^ (iif << 5));
rcu_read_lock();
for (rth = rcu_dereference(rt_hash_table[hash].chain); rth;
@@ -2286,10 +2280,8 @@ static inline int ip_mkroute_output_def(struct rtable **rp,
int err = __mkroute_output(&rth, res, fl, oldflp, dev_out, flags);
unsigned hash;
if (err == 0) {
- u32 tos = RT_FL_TOS(oldflp);
-
hash = rt_hash_code(oldflp->fl4_dst,
- oldflp->fl4_src ^ (oldflp->oif << 5), tos);
+ oldflp->fl4_src ^ (oldflp->oif << 5));
err = rt_intern_hash(hash, rth, rp);
}
@@ -2304,7 +2296,6 @@ static inline int ip_mkroute_output(struct rtable** rp,
unsigned flags)
{
#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
- u32 tos = RT_FL_TOS(oldflp);
unsigned char hop;
unsigned hash;
int err = -EINVAL;
@@ -2334,7 +2325,7 @@ static inline int ip_mkroute_output(struct rtable** rp,
hash = rt_hash_code(oldflp->fl4_dst,
oldflp->fl4_src ^
- (oldflp->oif << 5), tos);
+ (oldflp->oif << 5));
err = rt_intern_hash(hash, rth, rp);
/* forward hop information to multipath impl. */
@@ -2563,7 +2554,7 @@ int __ip_route_output_key(struct rtable **rp, const struct flowi *flp)
unsigned hash;
struct rtable *rth;
- hash = rt_hash_code(flp->fl4_dst, flp->fl4_src ^ (flp->oif << 5), flp->fl4_tos);
+ hash = rt_hash_code(flp->fl4_dst, flp->fl4_src ^ (flp->oif << 5));
rcu_read_lock_bh();
for (rth = rcu_dereference(rt_hash_table[hash].chain); rth;
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 4b0272c92d66..87f68e787d0c 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -257,6 +257,7 @@
#include <linux/fs.h>
#include <linux/random.h>
#include <linux/bootmem.h>
+#include <linux/cache.h>
#include <net/icmp.h>
#include <net/tcp.h>
@@ -275,9 +276,9 @@ atomic_t tcp_orphan_count = ATOMIC_INIT(0);
EXPORT_SYMBOL_GPL(tcp_orphan_count);
-int sysctl_tcp_mem[3];
-int sysctl_tcp_wmem[3] = { 4 * 1024, 16 * 1024, 128 * 1024 };
-int sysctl_tcp_rmem[3] = { 4 * 1024, 87380, 87380 * 2 };
+int sysctl_tcp_mem[3] __read_mostly;
+int sysctl_tcp_wmem[3] __read_mostly;
+int sysctl_tcp_rmem[3] __read_mostly;
EXPORT_SYMBOL(sysctl_tcp_mem);
EXPORT_SYMBOL(sysctl_tcp_rmem);
@@ -365,7 +366,7 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait)
if (sk->sk_shutdown == SHUTDOWN_MASK || sk->sk_state == TCP_CLOSE)
mask |= POLLHUP;
if (sk->sk_shutdown & RCV_SHUTDOWN)
- mask |= POLLIN | POLLRDNORM;
+ mask |= POLLIN | POLLRDNORM | POLLRDHUP;
/* Connected? */
if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV)) {
@@ -2081,7 +2082,8 @@ __setup("thash_entries=", set_thash_entries);
void __init tcp_init(void)
{
struct sk_buff *skb = NULL;
- int order, i;
+ unsigned long limit;
+ int order, i, max_share;
if (sizeof(struct tcp_skb_cb) > sizeof(skb->cb))
__skb_cb_too_small_for_tcp(sizeof(struct tcp_skb_cb),
@@ -2155,12 +2157,16 @@ void __init tcp_init(void)
sysctl_tcp_mem[1] = 1024 << order;
sysctl_tcp_mem[2] = 1536 << order;
- if (order < 3) {
- sysctl_tcp_wmem[2] = 64 * 1024;
- sysctl_tcp_rmem[0] = PAGE_SIZE;
- sysctl_tcp_rmem[1] = 43689;
- sysctl_tcp_rmem[2] = 2 * 43689;
- }
+ limit = ((unsigned long)sysctl_tcp_mem[1]) << (PAGE_SHIFT - 7);
+ max_share = min(4UL*1024*1024, limit);
+
+ sysctl_tcp_wmem[0] = SK_STREAM_MEM_QUANTUM;
+ sysctl_tcp_wmem[1] = 16*1024;
+ sysctl_tcp_wmem[2] = max(64*1024, max_share);
+
+ sysctl_tcp_rmem[0] = SK_STREAM_MEM_QUANTUM;
+ sysctl_tcp_rmem[1] = 87380;
+ sysctl_tcp_rmem[2] = max(87380, max_share);
printk(KERN_INFO "TCP: Hash tables configured "
"(established %d bind %d)\n",