aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-07-17 17:55:59 -0400
committerDavid S. Miller <davem@davemloft.net>2012-07-20 16:40:07 -0400
commit2860583fe840d972573363dfa190b2149a604534 (patch)
tree473a69bdcc3e45dd35bc0452a588cfbbac54c6e6 /net
parent9917e1e8762745191eba5a3bf2040278cbddbee1 (diff)
ipv4: Kill rt->fi
It's not really needed. We only grabbed a reference to the fib_info for the sake of fib_info local metrics. However, fib_info objects are freed using RCU, as are therefore their private metrics (if any). We would have triggered a route cache flush if we eliminated a reference to a fib_info object in the routing tables. Therefore, any existing cached routes will first check and see that they have been invalidated before an errant reference to these metric values would occur. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/route.c32
1 files changed, 1 insertions, 31 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index fac4c4acdbac..9add08869c75 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -141,7 +141,6 @@ static int ip_rt_min_advmss __read_mostly = 256;
141static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie); 141static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie);
142static unsigned int ipv4_default_advmss(const struct dst_entry *dst); 142static unsigned int ipv4_default_advmss(const struct dst_entry *dst);
143static unsigned int ipv4_mtu(const struct dst_entry *dst); 143static unsigned int ipv4_mtu(const struct dst_entry *dst);
144static void ipv4_dst_destroy(struct dst_entry *dst);
145static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst); 144static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst);
146static void ipv4_link_failure(struct sk_buff *skb); 145static void ipv4_link_failure(struct sk_buff *skb);
147static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, 146static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
@@ -171,7 +170,6 @@ static struct dst_ops ipv4_dst_ops = {
171 .default_advmss = ipv4_default_advmss, 170 .default_advmss = ipv4_default_advmss,
172 .mtu = ipv4_mtu, 171 .mtu = ipv4_mtu,
173 .cow_metrics = ipv4_cow_metrics, 172 .cow_metrics = ipv4_cow_metrics,
174 .destroy = ipv4_dst_destroy,
175 .ifdown = ipv4_dst_ifdown, 173 .ifdown = ipv4_dst_ifdown,
176 .negative_advice = ipv4_negative_advice, 174 .negative_advice = ipv4_negative_advice,
177 .link_failure = ipv4_link_failure, 175 .link_failure = ipv4_link_failure,
@@ -1034,17 +1032,6 @@ static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)
1034 return dst; 1032 return dst;
1035} 1033}
1036 1034
1037static void ipv4_dst_destroy(struct dst_entry *dst)
1038{
1039 struct rtable *rt = (struct rtable *) dst;
1040
1041 if (rt->fi) {
1042 fib_info_put(rt->fi);
1043 rt->fi = NULL;
1044 }
1045}
1046
1047
1048static void ipv4_link_failure(struct sk_buff *skb) 1035static void ipv4_link_failure(struct sk_buff *skb)
1049{ 1036{
1050 struct rtable *rt; 1037 struct rtable *rt;
@@ -1158,15 +1145,6 @@ static unsigned int ipv4_mtu(const struct dst_entry *dst)
1158 return mtu; 1145 return mtu;
1159} 1146}
1160 1147
1161static void rt_init_metrics(struct rtable *rt, struct fib_info *fi)
1162{
1163 if (fi->fib_metrics != (u32 *) dst_default_metrics) {
1164 rt->fi = fi;
1165 atomic_inc(&fi->fib_clntref);
1166 }
1167 dst_init_metrics(&rt->dst, fi->fib_metrics, true);
1168}
1169
1170static struct fib_nh_exception *find_exception(struct fib_nh *nh, __be32 daddr) 1148static struct fib_nh_exception *find_exception(struct fib_nh *nh, __be32 daddr)
1171{ 1149{
1172 struct fnhe_hash_bucket *hash = nh->nh_exceptions; 1150 struct fnhe_hash_bucket *hash = nh->nh_exceptions;
@@ -1261,7 +1239,7 @@ static void rt_set_nexthop(struct rtable *rt, __be32 daddr,
1261 rt->rt_gateway = nh->nh_gw; 1239 rt->rt_gateway = nh->nh_gw;
1262 if (unlikely(fnhe)) 1240 if (unlikely(fnhe))
1263 rt_bind_exception(rt, fnhe, daddr); 1241 rt_bind_exception(rt, fnhe, daddr);
1264 rt_init_metrics(rt, fi); 1242 dst_init_metrics(&rt->dst, fi->fib_metrics, true);
1265#ifdef CONFIG_IP_ROUTE_CLASSID 1243#ifdef CONFIG_IP_ROUTE_CLASSID
1266 rt->dst.tclassid = nh->nh_tclassid; 1244 rt->dst.tclassid = nh->nh_tclassid;
1267#endif 1245#endif
@@ -1334,7 +1312,6 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
1334 rth->rt_iif = dev->ifindex; 1312 rth->rt_iif = dev->ifindex;
1335 rth->rt_pmtu = 0; 1313 rth->rt_pmtu = 0;
1336 rth->rt_gateway = 0; 1314 rth->rt_gateway = 0;
1337 rth->fi = NULL;
1338 if (our) { 1315 if (our) {
1339 rth->dst.input= ip_local_deliver; 1316 rth->dst.input= ip_local_deliver;
1340 rth->rt_flags |= RTCF_LOCAL; 1317 rth->rt_flags |= RTCF_LOCAL;
@@ -1464,7 +1441,6 @@ static int __mkroute_input(struct sk_buff *skb,
1464 rth->rt_iif = in_dev->dev->ifindex; 1441 rth->rt_iif = in_dev->dev->ifindex;
1465 rth->rt_pmtu = 0; 1442 rth->rt_pmtu = 0;
1466 rth->rt_gateway = 0; 1443 rth->rt_gateway = 0;
1467 rth->fi = NULL;
1468 1444
1469 rth->dst.input = ip_forward; 1445 rth->dst.input = ip_forward;
1470 rth->dst.output = ip_output; 1446 rth->dst.output = ip_output;
@@ -1642,7 +1618,6 @@ local_input:
1642 rth->rt_iif = dev->ifindex; 1618 rth->rt_iif = dev->ifindex;
1643 rth->rt_pmtu = 0; 1619 rth->rt_pmtu = 0;
1644 rth->rt_gateway = 0; 1620 rth->rt_gateway = 0;
1645 rth->fi = NULL;
1646 if (res.type == RTN_UNREACHABLE) { 1621 if (res.type == RTN_UNREACHABLE) {
1647 rth->dst.input= ip_error; 1622 rth->dst.input= ip_error;
1648 rth->dst.error= -err; 1623 rth->dst.error= -err;
@@ -1807,7 +1782,6 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
1807 rth->rt_iif = orig_oif ? : dev_out->ifindex; 1782 rth->rt_iif = orig_oif ? : dev_out->ifindex;
1808 rth->rt_pmtu = 0; 1783 rth->rt_pmtu = 0;
1809 rth->rt_gateway = 0; 1784 rth->rt_gateway = 0;
1810 rth->fi = NULL;
1811 1785
1812 RT_CACHE_STAT_INC(out_slow_tot); 1786 RT_CACHE_STAT_INC(out_slow_tot);
1813 1787
@@ -2052,7 +2026,6 @@ static u32 *ipv4_rt_blackhole_cow_metrics(struct dst_entry *dst,
2052static struct dst_ops ipv4_dst_blackhole_ops = { 2026static struct dst_ops ipv4_dst_blackhole_ops = {
2053 .family = AF_INET, 2027 .family = AF_INET,
2054 .protocol = cpu_to_be16(ETH_P_IP), 2028 .protocol = cpu_to_be16(ETH_P_IP),
2055 .destroy = ipv4_dst_destroy,
2056 .check = ipv4_blackhole_dst_check, 2029 .check = ipv4_blackhole_dst_check,
2057 .mtu = ipv4_blackhole_mtu, 2030 .mtu = ipv4_blackhole_mtu,
2058 .default_advmss = ipv4_default_advmss, 2031 .default_advmss = ipv4_default_advmss,
@@ -2087,9 +2060,6 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or
2087 rt->rt_flags = ort->rt_flags; 2060 rt->rt_flags = ort->rt_flags;
2088 rt->rt_type = ort->rt_type; 2061 rt->rt_type = ort->rt_type;
2089 rt->rt_gateway = ort->rt_gateway; 2062 rt->rt_gateway = ort->rt_gateway;
2090 rt->fi = ort->fi;
2091 if (rt->fi)
2092 atomic_inc(&rt->fi->fib_clntref);
2093 2063
2094 dst_free(new); 2064 dst_free(new);
2095 } 2065 }