|
@@ -55,6 +55,8 @@
|
|
* Robert Olsson : Added rt_cache statistics
|
|
* Robert Olsson : Added rt_cache statistics
|
|
* Arnaldo C. Melo : Convert proc stuff to seq_file
|
|
* Arnaldo C. Melo : Convert proc stuff to seq_file
|
|
* Eric Dumazet : hashed spinlocks and rt_check_expire() fixes.
|
|
* 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
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* 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,
|
|
static int rt_intern_hash(unsigned hash, struct rtable *rth,
|
|
struct rtable **res);
|
|
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);
|
|
& 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,
|
|
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;
|
|
int i, k;
|
|
struct in_device *in_dev = in_dev_get(dev);
|
|
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 };
|
|
u32 skeys[2] = { saddr, 0 };
|
|
int ikeys[2] = { dev->ifindex, 0 };
|
|
int ikeys[2] = { dev->ifindex, 0 };
|
|
|
|
|
|
- tos &= IPTOS_RT_MASK;
|
|
|
|
-
|
|
|
|
if (!in_dev)
|
|
if (!in_dev)
|
|
return;
|
|
return;
|
|
|
|
|
|
@@ -1141,8 +1141,7 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw,
|
|
for (i = 0; i < 2; i++) {
|
|
for (i = 0; i < 2; i++) {
|
|
for (k = 0; k < 2; k++) {
|
|
for (k = 0; k < 2; k++) {
|
|
unsigned hash = rt_hash_code(daddr,
|
|
unsigned hash = rt_hash_code(daddr,
|
|
- skeys[i] ^ (ikeys[k] << 5),
|
|
|
|
- tos);
|
|
|
|
|
|
+ skeys[i] ^ (ikeys[k] << 5));
|
|
|
|
|
|
rthp=&rt_hash_table[hash].chain;
|
|
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 ||
|
|
if (rth->fl.fl4_dst != daddr ||
|
|
rth->fl.fl4_src != skeys[i] ||
|
|
rth->fl.fl4_src != skeys[i] ||
|
|
- rth->fl.fl4_tos != tos ||
|
|
|
|
rth->fl.oif != ikeys[k] ||
|
|
rth->fl.oif != ikeys[k] ||
|
|
rth->fl.iif != 0) {
|
|
rth->fl.iif != 0) {
|
|
rthp = &rth->u.rt_next;
|
|
rthp = &rth->u.rt_next;
|
|
@@ -1232,10 +1230,9 @@ reject_redirect:
|
|
if (IN_DEV_LOG_MARTIANS(in_dev) && net_ratelimit())
|
|
if (IN_DEV_LOG_MARTIANS(in_dev) && net_ratelimit())
|
|
printk(KERN_INFO "Redirect from %u.%u.%u.%u on %s about "
|
|
printk(KERN_INFO "Redirect from %u.%u.%u.%u on %s about "
|
|
"%u.%u.%u.%u ignored.\n"
|
|
"%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(old_gw), dev->name, NIPQUAD(new_gw),
|
|
- NIPQUAD(saddr), NIPQUAD(daddr), tos);
|
|
|
|
|
|
+ NIPQUAD(saddr), NIPQUAD(daddr));
|
|
#endif
|
|
#endif
|
|
in_dev_put(in_dev);
|
|
in_dev_put(in_dev);
|
|
}
|
|
}
|
|
@@ -1253,8 +1250,7 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
|
|
rt->u.dst.expires) {
|
|
rt->u.dst.expires) {
|
|
unsigned hash = rt_hash_code(rt->fl.fl4_dst,
|
|
unsigned hash = rt_hash_code(rt->fl.fl4_dst,
|
|
rt->fl.fl4_src ^
|
|
rt->fl.fl4_src ^
|
|
- (rt->fl.oif << 5),
|
|
|
|
- rt->fl.fl4_tos);
|
|
|
|
|
|
+ (rt->fl.oif << 5));
|
|
#if RT_CACHE_DEBUG >= 1
|
|
#if RT_CACHE_DEBUG >= 1
|
|
printk(KERN_DEBUG "ip_rt_advice: redirect to "
|
|
printk(KERN_DEBUG "ip_rt_advice: redirect to "
|
|
"%u.%u.%u.%u/%02x dropped\n",
|
|
"%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;
|
|
struct rtable *rth;
|
|
u32 skeys[2] = { iph->saddr, 0, };
|
|
u32 skeys[2] = { iph->saddr, 0, };
|
|
u32 daddr = iph->daddr;
|
|
u32 daddr = iph->daddr;
|
|
- u8 tos = iph->tos & IPTOS_RT_MASK;
|
|
|
|
unsigned short est_mtu = 0;
|
|
unsigned short est_mtu = 0;
|
|
|
|
|
|
if (ipv4_config.no_pmtu_disc)
|
|
if (ipv4_config.no_pmtu_disc)
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
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();
|
|
rcu_read_lock();
|
|
for (rth = rcu_dereference(rt_hash_table[hash].chain); rth;
|
|
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->fl.fl4_src == skeys[i] &&
|
|
rth->rt_dst == daddr &&
|
|
rth->rt_dst == daddr &&
|
|
rth->rt_src == iph->saddr &&
|
|
rth->rt_src == iph->saddr &&
|
|
- rth->fl.fl4_tos == tos &&
|
|
|
|
rth->fl.iif == 0 &&
|
|
rth->fl.iif == 0 &&
|
|
!(dst_metric_locked(&rth->u.dst, RTAX_MTU))) {
|
|
!(dst_metric_locked(&rth->u.dst, RTAX_MTU))) {
|
|
unsigned short mtu = new_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);
|
|
RT_CACHE_STAT_INC(in_slow_mc);
|
|
|
|
|
|
in_dev_put(in_dev);
|
|
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);
|
|
return rt_intern_hash(hash, rth, (struct rtable**) &skb->dst);
|
|
|
|
|
|
e_nobufs:
|
|
e_nobufs:
|
|
@@ -1823,7 +1817,7 @@ static inline int ip_mkroute_input_def(struct sk_buff *skb,
|
|
return err;
|
|
return err;
|
|
|
|
|
|
/* put it into the cache */
|
|
/* 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);
|
|
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;
|
|
return err;
|
|
|
|
|
|
/* put it into the cache */
|
|
/* 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);
|
|
err = rt_intern_hash(hash, rth, &rtres);
|
|
if (err)
|
|
if (err)
|
|
return err;
|
|
return err;
|
|
@@ -2041,7 +2035,7 @@ local_input:
|
|
rth->rt_flags &= ~RTCF_LOCAL;
|
|
rth->rt_flags &= ~RTCF_LOCAL;
|
|
}
|
|
}
|
|
rth->rt_type = res.type;
|
|
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);
|
|
err = rt_intern_hash(hash, rth, (struct rtable**)&skb->dst);
|
|
goto done;
|
|
goto done;
|
|
|
|
|
|
@@ -2088,7 +2082,7 @@ int ip_route_input(struct sk_buff *skb, u32 daddr, u32 saddr,
|
|
int iif = dev->ifindex;
|
|
int iif = dev->ifindex;
|
|
|
|
|
|
tos &= IPTOS_RT_MASK;
|
|
tos &= IPTOS_RT_MASK;
|
|
- hash = rt_hash_code(daddr, saddr ^ (iif << 5), tos);
|
|
|
|
|
|
+ hash = rt_hash_code(daddr, saddr ^ (iif << 5));
|
|
|
|
|
|
rcu_read_lock();
|
|
rcu_read_lock();
|
|
for (rth = rcu_dereference(rt_hash_table[hash].chain); rth;
|
|
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);
|
|
int err = __mkroute_output(&rth, res, fl, oldflp, dev_out, flags);
|
|
unsigned hash;
|
|
unsigned hash;
|
|
if (err == 0) {
|
|
if (err == 0) {
|
|
- u32 tos = RT_FL_TOS(oldflp);
|
|
|
|
-
|
|
|
|
hash = rt_hash_code(oldflp->fl4_dst,
|
|
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);
|
|
err = rt_intern_hash(hash, rth, rp);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2304,7 +2296,6 @@ static inline int ip_mkroute_output(struct rtable** rp,
|
|
unsigned flags)
|
|
unsigned flags)
|
|
{
|
|
{
|
|
#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
|
|
#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
|
|
- u32 tos = RT_FL_TOS(oldflp);
|
|
|
|
unsigned char hop;
|
|
unsigned char hop;
|
|
unsigned hash;
|
|
unsigned hash;
|
|
int err = -EINVAL;
|
|
int err = -EINVAL;
|
|
@@ -2334,7 +2325,7 @@ static inline int ip_mkroute_output(struct rtable** rp,
|
|
|
|
|
|
hash = rt_hash_code(oldflp->fl4_dst,
|
|
hash = rt_hash_code(oldflp->fl4_dst,
|
|
oldflp->fl4_src ^
|
|
oldflp->fl4_src ^
|
|
- (oldflp->oif << 5), tos);
|
|
|
|
|
|
+ (oldflp->oif << 5));
|
|
err = rt_intern_hash(hash, rth, rp);
|
|
err = rt_intern_hash(hash, rth, rp);
|
|
|
|
|
|
/* forward hop information to multipath impl. */
|
|
/* forward hop information to multipath impl. */
|
|
@@ -2563,7 +2554,7 @@ int __ip_route_output_key(struct rtable **rp, const struct flowi *flp)
|
|
unsigned hash;
|
|
unsigned hash;
|
|
struct rtable *rth;
|
|
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();
|
|
rcu_read_lock_bh();
|
|
for (rth = rcu_dereference(rt_hash_table[hash].chain); rth;
|
|
for (rth = rcu_dereference(rt_hash_table[hash].chain); rth;
|