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.c80
1 files changed, 24 insertions, 56 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index e4ba974f143..ff622069fce 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -202,11 +202,6 @@ EXPORT_SYMBOL(ip_tos2prio);
202static DEFINE_PER_CPU(struct rt_cache_stat, rt_cache_stat); 202static DEFINE_PER_CPU(struct rt_cache_stat, rt_cache_stat);
203#define RT_CACHE_STAT_INC(field) __this_cpu_inc(rt_cache_stat.field) 203#define RT_CACHE_STAT_INC(field) __this_cpu_inc(rt_cache_stat.field)
204 204
205static inline int rt_genid(struct net *net)
206{
207 return atomic_read(&net->ipv4.rt_genid);
208}
209
210#ifdef CONFIG_PROC_FS 205#ifdef CONFIG_PROC_FS
211static void *rt_cache_seq_start(struct seq_file *seq, loff_t *pos) 206static void *rt_cache_seq_start(struct seq_file *seq, loff_t *pos)
212{ 207{
@@ -447,27 +442,9 @@ static inline bool rt_is_expired(const struct rtable *rth)
447 return rth->rt_genid != rt_genid(dev_net(rth->dst.dev)); 442 return rth->rt_genid != rt_genid(dev_net(rth->dst.dev));
448} 443}
449 444
450/* 445void rt_cache_flush(struct net *net)
451 * Perturbation of rt_genid by a small quantity [1..256]
452 * Using 8 bits of shuffling ensure we can call rt_cache_invalidate()
453 * many times (2^24) without giving recent rt_genid.
454 * Jenkins hash is strong enough that litle changes of rt_genid are OK.
455 */
456static void rt_cache_invalidate(struct net *net)
457{
458 unsigned char shuffle;
459
460 get_random_bytes(&shuffle, sizeof(shuffle));
461 atomic_add(shuffle + 1U, &net->ipv4.rt_genid);
462}
463
464/*
465 * delay < 0 : invalidate cache (fast : entries will be deleted later)
466 * delay >= 0 : invalidate & flush cache (can be long)
467 */
468void rt_cache_flush(struct net *net, int delay)
469{ 446{
470 rt_cache_invalidate(net); 447 rt_genid_bump(net);
471} 448}
472 449
473static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst, 450static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst,
@@ -934,12 +911,14 @@ static u32 __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu)
934 if (mtu < ip_rt_min_pmtu) 911 if (mtu < ip_rt_min_pmtu)
935 mtu = ip_rt_min_pmtu; 912 mtu = ip_rt_min_pmtu;
936 913
914 rcu_read_lock();
937 if (fib_lookup(dev_net(rt->dst.dev), fl4, &res) == 0) { 915 if (fib_lookup(dev_net(rt->dst.dev), fl4, &res) == 0) {
938 struct fib_nh *nh = &FIB_RES_NH(res); 916 struct fib_nh *nh = &FIB_RES_NH(res);
939 917
940 update_or_create_fnhe(nh, fl4->daddr, 0, mtu, 918 update_or_create_fnhe(nh, fl4->daddr, 0, mtu,
941 jiffies + ip_rt_mtu_expires); 919 jiffies + ip_rt_mtu_expires);
942 } 920 }
921 rcu_read_unlock();
943 return mtu; 922 return mtu;
944} 923}
945 924
@@ -956,7 +935,7 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
956 dst->obsolete = DST_OBSOLETE_KILL; 935 dst->obsolete = DST_OBSOLETE_KILL;
957 } else { 936 } else {
958 rt->rt_pmtu = mtu; 937 rt->rt_pmtu = mtu;
959 dst_set_expires(&rt->dst, ip_rt_mtu_expires); 938 rt->dst.expires = max(1UL, jiffies + ip_rt_mtu_expires);
960 } 939 }
961} 940}
962 941
@@ -1132,10 +1111,7 @@ static unsigned int ipv4_mtu(const struct dst_entry *dst)
1132 const struct rtable *rt = (const struct rtable *) dst; 1111 const struct rtable *rt = (const struct rtable *) dst;
1133 unsigned int mtu = rt->rt_pmtu; 1112 unsigned int mtu = rt->rt_pmtu;
1134 1113
1135 if (mtu && time_after_eq(jiffies, rt->dst.expires)) 1114 if (!mtu || time_after_eq(jiffies, rt->dst.expires))
1136 mtu = 0;
1137
1138 if (!mtu)
1139 mtu = dst_metric_raw(dst, RTAX_MTU); 1115 mtu = dst_metric_raw(dst, RTAX_MTU);
1140 1116
1141 if (mtu && rt_is_output_route(rt)) 1117 if (mtu && rt_is_output_route(rt))
@@ -1263,7 +1239,7 @@ static void ipv4_dst_destroy(struct dst_entry *dst)
1263{ 1239{
1264 struct rtable *rt = (struct rtable *) dst; 1240 struct rtable *rt = (struct rtable *) dst;
1265 1241
1266 if (dst->flags & DST_NOCACHE) { 1242 if (!list_empty(&rt->rt_uncached)) {
1267 spin_lock_bh(&rt_uncached_lock); 1243 spin_lock_bh(&rt_uncached_lock);
1268 list_del(&rt->rt_uncached); 1244 list_del(&rt->rt_uncached);
1269 spin_unlock_bh(&rt_uncached_lock); 1245 spin_unlock_bh(&rt_uncached_lock);
@@ -1587,11 +1563,14 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
1587 if (ipv4_is_zeronet(daddr)) 1563 if (ipv4_is_zeronet(daddr))
1588 goto martian_destination; 1564 goto martian_destination;
1589 1565
1590 if (likely(!IN_DEV_ROUTE_LOCALNET(in_dev))) { 1566 /* Following code try to avoid calling IN_DEV_NET_ROUTE_LOCALNET(),
1591 if (ipv4_is_loopback(daddr)) 1567 * and call it once if daddr or/and saddr are loopback addresses
1568 */
1569 if (ipv4_is_loopback(daddr)) {
1570 if (!IN_DEV_NET_ROUTE_LOCALNET(in_dev, net))
1592 goto martian_destination; 1571 goto martian_destination;
1593 1572 } else if (ipv4_is_loopback(saddr)) {
1594 if (ipv4_is_loopback(saddr)) 1573 if (!IN_DEV_NET_ROUTE_LOCALNET(in_dev, net))
1595 goto martian_source; 1574 goto martian_source;
1596 } 1575 }
1597 1576
@@ -1616,7 +1595,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
1616 1595
1617 if (res.type == RTN_LOCAL) { 1596 if (res.type == RTN_LOCAL) {
1618 err = fib_validate_source(skb, saddr, daddr, tos, 1597 err = fib_validate_source(skb, saddr, daddr, tos,
1619 net->loopback_dev->ifindex, 1598 LOOPBACK_IFINDEX,
1620 dev, in_dev, &itag); 1599 dev, in_dev, &itag);
1621 if (err < 0) 1600 if (err < 0)
1622 goto martian_source_keep_err; 1601 goto martian_source_keep_err;
@@ -1892,7 +1871,7 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *fl4)
1892 1871
1893 orig_oif = fl4->flowi4_oif; 1872 orig_oif = fl4->flowi4_oif;
1894 1873
1895 fl4->flowi4_iif = net->loopback_dev->ifindex; 1874 fl4->flowi4_iif = LOOPBACK_IFINDEX;
1896 fl4->flowi4_tos = tos & IPTOS_RT_MASK; 1875 fl4->flowi4_tos = tos & IPTOS_RT_MASK;
1897 fl4->flowi4_scope = ((tos & RTO_ONLINK) ? 1876 fl4->flowi4_scope = ((tos & RTO_ONLINK) ?
1898 RT_SCOPE_LINK : RT_SCOPE_UNIVERSE); 1877 RT_SCOPE_LINK : RT_SCOPE_UNIVERSE);
@@ -1981,7 +1960,7 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *fl4)
1981 if (!fl4->daddr) 1960 if (!fl4->daddr)
1982 fl4->daddr = fl4->saddr = htonl(INADDR_LOOPBACK); 1961 fl4->daddr = fl4->saddr = htonl(INADDR_LOOPBACK);
1983 dev_out = net->loopback_dev; 1962 dev_out = net->loopback_dev;
1984 fl4->flowi4_oif = net->loopback_dev->ifindex; 1963 fl4->flowi4_oif = LOOPBACK_IFINDEX;
1985 res.type = RTN_LOCAL; 1964 res.type = RTN_LOCAL;
1986 flags |= RTCF_LOCAL; 1965 flags |= RTCF_LOCAL;
1987 goto make_route; 1966 goto make_route;
@@ -2028,7 +2007,6 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *fl4)
2028 } 2007 }
2029 dev_out = net->loopback_dev; 2008 dev_out = net->loopback_dev;
2030 fl4->flowi4_oif = dev_out->ifindex; 2009 fl4->flowi4_oif = dev_out->ifindex;
2031 res.fi = NULL;
2032 flags |= RTCF_LOCAL; 2010 flags |= RTCF_LOCAL;
2033 goto make_route; 2011 goto make_route;
2034 } 2012 }
@@ -2153,7 +2131,7 @@ struct rtable *ip_route_output_flow(struct net *net, struct flowi4 *flp4,
2153EXPORT_SYMBOL_GPL(ip_route_output_flow); 2131EXPORT_SYMBOL_GPL(ip_route_output_flow);
2154 2132
2155static int rt_fill_info(struct net *net, __be32 dst, __be32 src, 2133static int rt_fill_info(struct net *net, __be32 dst, __be32 src,
2156 struct flowi4 *fl4, struct sk_buff *skb, u32 pid, 2134 struct flowi4 *fl4, struct sk_buff *skb, u32 portid,
2157 u32 seq, int event, int nowait, unsigned int flags) 2135 u32 seq, int event, int nowait, unsigned int flags)
2158{ 2136{
2159 struct rtable *rt = skb_rtable(skb); 2137 struct rtable *rt = skb_rtable(skb);
@@ -2163,7 +2141,7 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src,
2163 u32 error; 2141 u32 error;
2164 u32 metrics[RTAX_MAX]; 2142 u32 metrics[RTAX_MAX];
2165 2143
2166 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*r), flags); 2144 nlh = nlmsg_put(skb, portid, seq, event, sizeof(*r), flags);
2167 if (nlh == NULL) 2145 if (nlh == NULL)
2168 return -EMSGSIZE; 2146 return -EMSGSIZE;
2169 2147
@@ -2323,12 +2301,12 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void
2323 rt->rt_flags |= RTCF_NOTIFY; 2301 rt->rt_flags |= RTCF_NOTIFY;
2324 2302
2325 err = rt_fill_info(net, dst, src, &fl4, skb, 2303 err = rt_fill_info(net, dst, src, &fl4, skb,
2326 NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, 2304 NETLINK_CB(in_skb).portid, nlh->nlmsg_seq,
2327 RTM_NEWROUTE, 0, 0); 2305 RTM_NEWROUTE, 0, 0);
2328 if (err <= 0) 2306 if (err <= 0)
2329 goto errout_free; 2307 goto errout_free;
2330 2308
2331 err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).pid); 2309 err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).portid);
2332errout: 2310errout:
2333 return err; 2311 return err;
2334 2312
@@ -2344,7 +2322,7 @@ int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb)
2344 2322
2345void ip_rt_multicast_event(struct in_device *in_dev) 2323void ip_rt_multicast_event(struct in_device *in_dev)
2346{ 2324{
2347 rt_cache_flush(dev_net(in_dev->dev), 0); 2325 rt_cache_flush(dev_net(in_dev->dev));
2348} 2326}
2349 2327
2350#ifdef CONFIG_SYSCTL 2328#ifdef CONFIG_SYSCTL
@@ -2353,16 +2331,7 @@ static int ipv4_sysctl_rtcache_flush(ctl_table *__ctl, int write,
2353 size_t *lenp, loff_t *ppos) 2331 size_t *lenp, loff_t *ppos)
2354{ 2332{
2355 if (write) { 2333 if (write) {
2356 int flush_delay; 2334 rt_cache_flush((struct net *)__ctl->extra1);
2357 ctl_table ctl;
2358 struct net *net;
2359
2360 memcpy(&ctl, __ctl, sizeof(ctl));
2361 ctl.data = &flush_delay;
2362 proc_dointvec(&ctl, write, buffer, lenp, ppos);
2363
2364 net = (struct net *)__ctl->extra1;
2365 rt_cache_flush(net, flush_delay);
2366 return 0; 2335 return 0;
2367 } 2336 }
2368 2337
@@ -2532,8 +2501,7 @@ static __net_initdata struct pernet_operations sysctl_route_ops = {
2532 2501
2533static __net_init int rt_genid_init(struct net *net) 2502static __net_init int rt_genid_init(struct net *net)
2534{ 2503{
2535 get_random_bytes(&net->ipv4.rt_genid, 2504 atomic_set(&net->rt_genid, 0);
2536 sizeof(net->ipv4.rt_genid));
2537 get_random_bytes(&net->ipv4.dev_addr_genid, 2505 get_random_bytes(&net->ipv4.dev_addr_genid,
2538 sizeof(net->ipv4.dev_addr_genid)); 2506 sizeof(net->ipv4.dev_addr_genid));
2539 return 0; 2507 return 0;