aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/route.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/route.c')
-rw-r--r--net/ipv4/route.c45
1 files changed, 18 insertions, 27 deletions
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 @@
55 * Robert Olsson : Added rt_cache statistics 55 * Robert Olsson : Added rt_cache statistics
56 * Arnaldo C. Melo : Convert proc stuff to seq_file 56 * Arnaldo C. Melo : Convert proc stuff to seq_file
57 * Eric Dumazet : hashed spinlocks and rt_check_expire() fixes. 57 * Eric Dumazet : hashed spinlocks and rt_check_expire() fixes.
58 * Ilia Sotnikov : Ignore TOS on PMTUD and Redirect
59 * Ilia Sotnikov : Removed TOS from hash calculations
58 * 60 *
59 * This program is free software; you can redistribute it and/or 61 * This program is free software; you can redistribute it and/or
60 * modify it under the terms of the GNU General Public License 62 * 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);
247static int rt_intern_hash(unsigned hash, struct rtable *rth, 249static int rt_intern_hash(unsigned hash, struct rtable *rth,
248 struct rtable **res); 250 struct rtable **res);
249 251
250static unsigned int rt_hash_code(u32 daddr, u32 saddr, u8 tos) 252static unsigned int rt_hash_code(u32 daddr, u32 saddr)
251{ 253{
252 return (jhash_3words(daddr, saddr, (u32) tos, rt_hash_rnd) 254 return (jhash_2words(daddr, saddr, rt_hash_rnd)
253 & rt_hash_mask); 255 & rt_hash_mask);
254} 256}
255 257
@@ -1111,7 +1113,7 @@ static void rt_del(unsigned hash, struct rtable *rt)
1111} 1113}
1112 1114
1113void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw, 1115void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw,
1114 u32 saddr, u8 tos, struct net_device *dev) 1116 u32 saddr, struct net_device *dev)
1115{ 1117{
1116 int i, k; 1118 int i, k;
1117 struct in_device *in_dev = in_dev_get(dev); 1119 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,
1119 u32 skeys[2] = { saddr, 0 }; 1121 u32 skeys[2] = { saddr, 0 };
1120 int ikeys[2] = { dev->ifindex, 0 }; 1122 int ikeys[2] = { dev->ifindex, 0 };
1121 1123
1122 tos &= IPTOS_RT_MASK;
1123
1124 if (!in_dev) 1124 if (!in_dev)
1125 return; 1125 return;
1126 1126
@@ -1141,8 +1141,7 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw,
1141 for (i = 0; i < 2; i++) { 1141 for (i = 0; i < 2; i++) {
1142 for (k = 0; k < 2; k++) { 1142 for (k = 0; k < 2; k++) {
1143 unsigned hash = rt_hash_code(daddr, 1143 unsigned hash = rt_hash_code(daddr,
1144 skeys[i] ^ (ikeys[k] << 5), 1144 skeys[i] ^ (ikeys[k] << 5));
1145 tos);
1146 1145
1147 rthp=&rt_hash_table[hash].chain; 1146 rthp=&rt_hash_table[hash].chain;
1148 1147
@@ -1152,7 +1151,6 @@ void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw,
1152 1151
1153 if (rth->fl.fl4_dst != daddr || 1152 if (rth->fl.fl4_dst != daddr ||
1154 rth->fl.fl4_src != skeys[i] || 1153 rth->fl.fl4_src != skeys[i] ||
1155 rth->fl.fl4_tos != tos ||
1156 rth->fl.oif != ikeys[k] || 1154 rth->fl.oif != ikeys[k] ||
1157 rth->fl.iif != 0) { 1155 rth->fl.iif != 0) {
1158 rthp = &rth->u.rt_next; 1156 rthp = &rth->u.rt_next;
@@ -1232,10 +1230,9 @@ reject_redirect:
1232 if (IN_DEV_LOG_MARTIANS(in_dev) && net_ratelimit()) 1230 if (IN_DEV_LOG_MARTIANS(in_dev) && net_ratelimit())
1233 printk(KERN_INFO "Redirect from %u.%u.%u.%u on %s about " 1231 printk(KERN_INFO "Redirect from %u.%u.%u.%u on %s about "
1234 "%u.%u.%u.%u ignored.\n" 1232 "%u.%u.%u.%u ignored.\n"
1235 " Advised path = %u.%u.%u.%u -> %u.%u.%u.%u, " 1233 " Advised path = %u.%u.%u.%u -> %u.%u.%u.%u\n",
1236 "tos %02x\n",
1237 NIPQUAD(old_gw), dev->name, NIPQUAD(new_gw), 1234 NIPQUAD(old_gw), dev->name, NIPQUAD(new_gw),
1238 NIPQUAD(saddr), NIPQUAD(daddr), tos); 1235 NIPQUAD(saddr), NIPQUAD(daddr));
1239#endif 1236#endif
1240 in_dev_put(in_dev); 1237 in_dev_put(in_dev);
1241} 1238}
@@ -1253,8 +1250,7 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
1253 rt->u.dst.expires) { 1250 rt->u.dst.expires) {
1254 unsigned hash = rt_hash_code(rt->fl.fl4_dst, 1251 unsigned hash = rt_hash_code(rt->fl.fl4_dst,
1255 rt->fl.fl4_src ^ 1252 rt->fl.fl4_src ^
1256 (rt->fl.oif << 5), 1253 (rt->fl.oif << 5));
1257 rt->fl.fl4_tos);
1258#if RT_CACHE_DEBUG >= 1 1254#if RT_CACHE_DEBUG >= 1
1259 printk(KERN_DEBUG "ip_rt_advice: redirect to " 1255 printk(KERN_DEBUG "ip_rt_advice: redirect to "
1260 "%u.%u.%u.%u/%02x dropped\n", 1256 "%u.%u.%u.%u/%02x dropped\n",
@@ -1391,14 +1387,13 @@ unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu)
1391 struct rtable *rth; 1387 struct rtable *rth;
1392 u32 skeys[2] = { iph->saddr, 0, }; 1388 u32 skeys[2] = { iph->saddr, 0, };
1393 u32 daddr = iph->daddr; 1389 u32 daddr = iph->daddr;
1394 u8 tos = iph->tos & IPTOS_RT_MASK;
1395 unsigned short est_mtu = 0; 1390 unsigned short est_mtu = 0;
1396 1391
1397 if (ipv4_config.no_pmtu_disc) 1392 if (ipv4_config.no_pmtu_disc)
1398 return 0; 1393 return 0;
1399 1394
1400 for (i = 0; i < 2; i++) { 1395 for (i = 0; i < 2; i++) {
1401 unsigned hash = rt_hash_code(daddr, skeys[i], tos); 1396 unsigned hash = rt_hash_code(daddr, skeys[i]);
1402 1397
1403 rcu_read_lock(); 1398 rcu_read_lock();
1404 for (rth = rcu_dereference(rt_hash_table[hash].chain); rth; 1399 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)
1407 rth->fl.fl4_src == skeys[i] && 1402 rth->fl.fl4_src == skeys[i] &&
1408 rth->rt_dst == daddr && 1403 rth->rt_dst == daddr &&
1409 rth->rt_src == iph->saddr && 1404 rth->rt_src == iph->saddr &&
1410 rth->fl.fl4_tos == tos &&
1411 rth->fl.iif == 0 && 1405 rth->fl.iif == 0 &&
1412 !(dst_metric_locked(&rth->u.dst, RTAX_MTU))) { 1406 !(dst_metric_locked(&rth->u.dst, RTAX_MTU))) {
1413 unsigned short mtu = new_mtu; 1407 unsigned short mtu = new_mtu;
@@ -1658,7 +1652,7 @@ static int ip_route_input_mc(struct sk_buff *skb, u32 daddr, u32 saddr,
1658 RT_CACHE_STAT_INC(in_slow_mc); 1652 RT_CACHE_STAT_INC(in_slow_mc);
1659 1653
1660 in_dev_put(in_dev); 1654 in_dev_put(in_dev);
1661 hash = rt_hash_code(daddr, saddr ^ (dev->ifindex << 5), tos); 1655 hash = rt_hash_code(daddr, saddr ^ (dev->ifindex << 5));
1662 return rt_intern_hash(hash, rth, (struct rtable**) &skb->dst); 1656 return rt_intern_hash(hash, rth, (struct rtable**) &skb->dst);
1663 1657
1664e_nobufs: 1658e_nobufs:
@@ -1823,7 +1817,7 @@ static inline int ip_mkroute_input_def(struct sk_buff *skb,
1823 return err; 1817 return err;
1824 1818
1825 /* put it into the cache */ 1819 /* put it into the cache */
1826 hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5), tos); 1820 hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5));
1827 return rt_intern_hash(hash, rth, (struct rtable**)&skb->dst); 1821 return rt_intern_hash(hash, rth, (struct rtable**)&skb->dst);
1828} 1822}
1829 1823
@@ -1864,7 +1858,7 @@ static inline int ip_mkroute_input(struct sk_buff *skb,
1864 return err; 1858 return err;
1865 1859
1866 /* put it into the cache */ 1860 /* put it into the cache */
1867 hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5), tos); 1861 hash = rt_hash_code(daddr, saddr ^ (fl->iif << 5));
1868 err = rt_intern_hash(hash, rth, &rtres); 1862 err = rt_intern_hash(hash, rth, &rtres);
1869 if (err) 1863 if (err)
1870 return err; 1864 return err;
@@ -2041,7 +2035,7 @@ local_input:
2041 rth->rt_flags &= ~RTCF_LOCAL; 2035 rth->rt_flags &= ~RTCF_LOCAL;
2042 } 2036 }
2043 rth->rt_type = res.type; 2037 rth->rt_type = res.type;
2044 hash = rt_hash_code(daddr, saddr ^ (fl.iif << 5), tos); 2038 hash = rt_hash_code(daddr, saddr ^ (fl.iif << 5));
2045 err = rt_intern_hash(hash, rth, (struct rtable**)&skb->dst); 2039 err = rt_intern_hash(hash, rth, (struct rtable**)&skb->dst);
2046 goto done; 2040 goto done;
2047 2041
@@ -2088,7 +2082,7 @@ int ip_route_input(struct sk_buff *skb, u32 daddr, u32 saddr,
2088 int iif = dev->ifindex; 2082 int iif = dev->ifindex;
2089 2083
2090 tos &= IPTOS_RT_MASK; 2084 tos &= IPTOS_RT_MASK;
2091 hash = rt_hash_code(daddr, saddr ^ (iif << 5), tos); 2085 hash = rt_hash_code(daddr, saddr ^ (iif << 5));
2092 2086
2093 rcu_read_lock(); 2087 rcu_read_lock();
2094 for (rth = rcu_dereference(rt_hash_table[hash].chain); rth; 2088 for (rth = rcu_dereference(rt_hash_table[hash].chain); rth;
@@ -2286,10 +2280,8 @@ static inline int ip_mkroute_output_def(struct rtable **rp,
2286 int err = __mkroute_output(&rth, res, fl, oldflp, dev_out, flags); 2280 int err = __mkroute_output(&rth, res, fl, oldflp, dev_out, flags);
2287 unsigned hash; 2281 unsigned hash;
2288 if (err == 0) { 2282 if (err == 0) {
2289 u32 tos = RT_FL_TOS(oldflp);
2290
2291 hash = rt_hash_code(oldflp->fl4_dst, 2283 hash = rt_hash_code(oldflp->fl4_dst,
2292 oldflp->fl4_src ^ (oldflp->oif << 5), tos); 2284 oldflp->fl4_src ^ (oldflp->oif << 5));
2293 err = rt_intern_hash(hash, rth, rp); 2285 err = rt_intern_hash(hash, rth, rp);
2294 } 2286 }
2295 2287
@@ -2304,7 +2296,6 @@ static inline int ip_mkroute_output(struct rtable** rp,
2304 unsigned flags) 2296 unsigned flags)
2305{ 2297{
2306#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED 2298#ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED
2307 u32 tos = RT_FL_TOS(oldflp);
2308 unsigned char hop; 2299 unsigned char hop;
2309 unsigned hash; 2300 unsigned hash;
2310 int err = -EINVAL; 2301 int err = -EINVAL;
@@ -2334,7 +2325,7 @@ static inline int ip_mkroute_output(struct rtable** rp,
2334 2325
2335 hash = rt_hash_code(oldflp->fl4_dst, 2326 hash = rt_hash_code(oldflp->fl4_dst,
2336 oldflp->fl4_src ^ 2327 oldflp->fl4_src ^
2337 (oldflp->oif << 5), tos); 2328 (oldflp->oif << 5));
2338 err = rt_intern_hash(hash, rth, rp); 2329 err = rt_intern_hash(hash, rth, rp);
2339 2330
2340 /* forward hop information to multipath impl. */ 2331 /* forward hop information to multipath impl. */
@@ -2563,7 +2554,7 @@ int __ip_route_output_key(struct rtable **rp, const struct flowi *flp)
2563 unsigned hash; 2554 unsigned hash;
2564 struct rtable *rth; 2555 struct rtable *rth;
2565 2556
2566 hash = rt_hash_code(flp->fl4_dst, flp->fl4_src ^ (flp->oif << 5), flp->fl4_tos); 2557 hash = rt_hash_code(flp->fl4_dst, flp->fl4_src ^ (flp->oif << 5));
2567 2558
2568 rcu_read_lock_bh(); 2559 rcu_read_lock_bh();
2569 for (rth = rcu_dereference(rt_hash_table[hash].chain); rth; 2560 for (rth = rcu_dereference(rt_hash_table[hash].chain); rth;