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.c68
1 files changed, 45 insertions, 23 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 28205e5bfa9b..65b3a8b11a6c 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -131,8 +131,8 @@ static int ip_rt_min_advmss __read_mostly = 256;
131static int ip_rt_secret_interval __read_mostly = 10 * 60 * HZ; 131static int ip_rt_secret_interval __read_mostly = 10 * 60 * HZ;
132static int rt_chain_length_max __read_mostly = 20; 132static int rt_chain_length_max __read_mostly = 20;
133 133
134static void rt_worker_func(struct work_struct *work); 134static struct delayed_work expires_work;
135static DECLARE_DELAYED_WORK(expires_work, rt_worker_func); 135static unsigned long expires_ljiffies;
136 136
137/* 137/*
138 * Interface to generic destination cache. 138 * Interface to generic destination cache.
@@ -787,9 +787,12 @@ static void rt_check_expire(void)
787 struct rtable *rth, *aux, **rthp; 787 struct rtable *rth, *aux, **rthp;
788 unsigned long samples = 0; 788 unsigned long samples = 0;
789 unsigned long sum = 0, sum2 = 0; 789 unsigned long sum = 0, sum2 = 0;
790 unsigned long delta;
790 u64 mult; 791 u64 mult;
791 792
792 mult = ((u64)ip_rt_gc_interval) << rt_hash_log; 793 delta = jiffies - expires_ljiffies;
794 expires_ljiffies = jiffies;
795 mult = ((u64)delta) << rt_hash_log;
793 if (ip_rt_gc_timeout > 1) 796 if (ip_rt_gc_timeout > 1)
794 do_div(mult, ip_rt_gc_timeout); 797 do_div(mult, ip_rt_gc_timeout);
795 goal = (unsigned int)mult; 798 goal = (unsigned int)mult;
@@ -1064,7 +1067,8 @@ work_done:
1064out: return 0; 1067out: return 0;
1065} 1068}
1066 1069
1067static int rt_intern_hash(unsigned hash, struct rtable *rt, struct rtable **rp) 1070static int rt_intern_hash(unsigned hash, struct rtable *rt,
1071 struct rtable **rp, struct sk_buff *skb)
1068{ 1072{
1069 struct rtable *rth, **rthp; 1073 struct rtable *rth, **rthp;
1070 unsigned long now; 1074 unsigned long now;
@@ -1081,8 +1085,16 @@ restart:
1081 now = jiffies; 1085 now = jiffies;
1082 1086
1083 if (!rt_caching(dev_net(rt->u.dst.dev))) { 1087 if (!rt_caching(dev_net(rt->u.dst.dev))) {
1084 rt_drop(rt); 1088 /*
1085 return 0; 1089 * If we're not caching, just tell the caller we
1090 * were successful and don't touch the route. The
1091 * caller hold the sole reference to the cache entry, and
1092 * it will be released when the caller is done with it.
1093 * If we drop it here, the callers have no way to resolve routes
1094 * when we're not caching. Instead, just point *rp at rt, so
1095 * the caller gets a single use out of the route
1096 */
1097 goto report_and_exit;
1086 } 1098 }
1087 1099
1088 rthp = &rt_hash_table[hash].chain; 1100 rthp = &rt_hash_table[hash].chain;
@@ -1114,7 +1126,10 @@ restart:
1114 spin_unlock_bh(rt_hash_lock_addr(hash)); 1126 spin_unlock_bh(rt_hash_lock_addr(hash));
1115 1127
1116 rt_drop(rt); 1128 rt_drop(rt);
1117 *rp = rth; 1129 if (rp)
1130 *rp = rth;
1131 else
1132 skb_dst_set(skb, &rth->u.dst);
1118 return 0; 1133 return 0;
1119 } 1134 }
1120 1135
@@ -1210,7 +1225,12 @@ restart:
1210 rcu_assign_pointer(rt_hash_table[hash].chain, rt); 1225 rcu_assign_pointer(rt_hash_table[hash].chain, rt);
1211 1226
1212 spin_unlock_bh(rt_hash_lock_addr(hash)); 1227 spin_unlock_bh(rt_hash_lock_addr(hash));
1213 *rp = rt; 1228
1229report_and_exit:
1230 if (rp)
1231 *rp = rt;
1232 else
1233 skb_dst_set(skb, &rt->u.dst);
1214 return 0; 1234 return 0;
1215} 1235}
1216 1236
@@ -1407,7 +1427,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
1407 &netevent); 1427 &netevent);
1408 1428
1409 rt_del(hash, rth); 1429 rt_del(hash, rth);
1410 if (!rt_intern_hash(hash, rt, &rt)) 1430 if (!rt_intern_hash(hash, rt, &rt, NULL))
1411 ip_rt_put(rt); 1431 ip_rt_put(rt);
1412 goto do_next; 1432 goto do_next;
1413 } 1433 }
@@ -1473,7 +1493,7 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
1473 1493
1474void ip_rt_send_redirect(struct sk_buff *skb) 1494void ip_rt_send_redirect(struct sk_buff *skb)
1475{ 1495{
1476 struct rtable *rt = skb->rtable; 1496 struct rtable *rt = skb_rtable(skb);
1477 struct in_device *in_dev = in_dev_get(rt->u.dst.dev); 1497 struct in_device *in_dev = in_dev_get(rt->u.dst.dev);
1478 1498
1479 if (!in_dev) 1499 if (!in_dev)
@@ -1521,7 +1541,7 @@ out:
1521 1541
1522static int ip_error(struct sk_buff *skb) 1542static int ip_error(struct sk_buff *skb)
1523{ 1543{
1524 struct rtable *rt = skb->rtable; 1544 struct rtable *rt = skb_rtable(skb);
1525 unsigned long now; 1545 unsigned long now;
1526 int code; 1546 int code;
1527 1547
@@ -1698,7 +1718,7 @@ static void ipv4_link_failure(struct sk_buff *skb)
1698 1718
1699 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0); 1719 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
1700 1720
1701 rt = skb->rtable; 1721 rt = skb_rtable(skb);
1702 if (rt) 1722 if (rt)
1703 dst_set_expires(&rt->u.dst, 0); 1723 dst_set_expires(&rt->u.dst, 0);
1704} 1724}
@@ -1858,7 +1878,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
1858 1878
1859 in_dev_put(in_dev); 1879 in_dev_put(in_dev);
1860 hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev))); 1880 hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev)));
1861 return rt_intern_hash(hash, rth, &skb->rtable); 1881 return rt_intern_hash(hash, rth, NULL, skb);
1862 1882
1863e_nobufs: 1883e_nobufs:
1864 in_dev_put(in_dev); 1884 in_dev_put(in_dev);
@@ -2019,7 +2039,7 @@ static int ip_mkroute_input(struct sk_buff *skb,
2019 /* put it into the cache */ 2039 /* put it into the cache */
2020 hash = rt_hash(daddr, saddr, fl->iif, 2040 hash = rt_hash(daddr, saddr, fl->iif,
2021 rt_genid(dev_net(rth->u.dst.dev))); 2041 rt_genid(dev_net(rth->u.dst.dev)));
2022 return rt_intern_hash(hash, rth, &skb->rtable); 2042 return rt_intern_hash(hash, rth, NULL, skb);
2023} 2043}
2024 2044
2025/* 2045/*
@@ -2175,7 +2195,7 @@ local_input:
2175 } 2195 }
2176 rth->rt_type = res.type; 2196 rth->rt_type = res.type;
2177 hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net)); 2197 hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net));
2178 err = rt_intern_hash(hash, rth, &skb->rtable); 2198 err = rt_intern_hash(hash, rth, NULL, skb);
2179 goto done; 2199 goto done;
2180 2200
2181no_route: 2201no_route:
@@ -2244,7 +2264,7 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr,
2244 dst_use(&rth->u.dst, jiffies); 2264 dst_use(&rth->u.dst, jiffies);
2245 RT_CACHE_STAT_INC(in_hit); 2265 RT_CACHE_STAT_INC(in_hit);
2246 rcu_read_unlock(); 2266 rcu_read_unlock();
2247 skb->rtable = rth; 2267 skb_dst_set(skb, &rth->u.dst);
2248 return 0; 2268 return 0;
2249 } 2269 }
2250 RT_CACHE_STAT_INC(in_hlist_search); 2270 RT_CACHE_STAT_INC(in_hlist_search);
@@ -2420,7 +2440,7 @@ static int ip_mkroute_output(struct rtable **rp,
2420 if (err == 0) { 2440 if (err == 0) {
2421 hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif, 2441 hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif,
2422 rt_genid(dev_net(dev_out))); 2442 rt_genid(dev_net(dev_out)));
2423 err = rt_intern_hash(hash, rth, rp); 2443 err = rt_intern_hash(hash, rth, rp, NULL);
2424 } 2444 }
2425 2445
2426 return err; 2446 return err;
@@ -2763,7 +2783,7 @@ static int rt_fill_info(struct net *net,
2763 struct sk_buff *skb, u32 pid, u32 seq, int event, 2783 struct sk_buff *skb, u32 pid, u32 seq, int event,
2764 int nowait, unsigned int flags) 2784 int nowait, unsigned int flags)
2765{ 2785{
2766 struct rtable *rt = skb->rtable; 2786 struct rtable *rt = skb_rtable(skb);
2767 struct rtmsg *r; 2787 struct rtmsg *r;
2768 struct nlmsghdr *nlh; 2788 struct nlmsghdr *nlh;
2769 long expires; 2789 long expires;
@@ -2907,7 +2927,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
2907 err = ip_route_input(skb, dst, src, rtm->rtm_tos, dev); 2927 err = ip_route_input(skb, dst, src, rtm->rtm_tos, dev);
2908 local_bh_enable(); 2928 local_bh_enable();
2909 2929
2910 rt = skb->rtable; 2930 rt = skb_rtable(skb);
2911 if (err == 0 && rt->u.dst.error) 2931 if (err == 0 && rt->u.dst.error)
2912 err = -rt->u.dst.error; 2932 err = -rt->u.dst.error;
2913 } else { 2933 } else {
@@ -2927,7 +2947,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
2927 if (err) 2947 if (err)
2928 goto errout_free; 2948 goto errout_free;
2929 2949
2930 skb->rtable = rt; 2950 skb_dst_set(skb, &rt->u.dst);
2931 if (rtm->rtm_flags & RTM_F_NOTIFY) 2951 if (rtm->rtm_flags & RTM_F_NOTIFY)
2932 rt->rt_flags |= RTCF_NOTIFY; 2952 rt->rt_flags |= RTCF_NOTIFY;
2933 2953
@@ -2968,15 +2988,15 @@ int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb)
2968 continue; 2988 continue;
2969 if (rt_is_expired(rt)) 2989 if (rt_is_expired(rt))
2970 continue; 2990 continue;
2971 skb->dst = dst_clone(&rt->u.dst); 2991 skb_dst_set(skb, dst_clone(&rt->u.dst));
2972 if (rt_fill_info(net, skb, NETLINK_CB(cb->skb).pid, 2992 if (rt_fill_info(net, skb, NETLINK_CB(cb->skb).pid,
2973 cb->nlh->nlmsg_seq, RTM_NEWROUTE, 2993 cb->nlh->nlmsg_seq, RTM_NEWROUTE,
2974 1, NLM_F_MULTI) <= 0) { 2994 1, NLM_F_MULTI) <= 0) {
2975 dst_release(xchg(&skb->dst, NULL)); 2995 skb_dst_drop(skb);
2976 rcu_read_unlock_bh(); 2996 rcu_read_unlock_bh();
2977 goto done; 2997 goto done;
2978 } 2998 }
2979 dst_release(xchg(&skb->dst, NULL)); 2999 skb_dst_drop(skb);
2980 } 3000 }
2981 rcu_read_unlock_bh(); 3001 rcu_read_unlock_bh();
2982 } 3002 }
@@ -3390,6 +3410,8 @@ int __init ip_rt_init(void)
3390 /* All the timers, started at system startup tend 3410 /* All the timers, started at system startup tend
3391 to synchronize. Perturb it a bit. 3411 to synchronize. Perturb it a bit.
3392 */ 3412 */
3413 INIT_DELAYED_WORK_DEFERRABLE(&expires_work, rt_worker_func);
3414 expires_ljiffies = jiffies;
3393 schedule_delayed_work(&expires_work, 3415 schedule_delayed_work(&expires_work,
3394 net_random() % ip_rt_gc_interval + ip_rt_gc_interval); 3416 net_random() % ip_rt_gc_interval + ip_rt_gc_interval);
3395 3417