aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-04-28 17:13:38 -0400
committerDavid S. Miller <davem@davemloft.net>2011-04-29 01:25:59 -0400
commit5c1e6aa300a7a669dc469d2dcb20172c6bd8fed9 (patch)
tree61796a49f8b9236eee4730ff8142e79bd43f0f51 /net
parent778865a550e7958c1211242cc481f48d46de0f04 (diff)
net: Make dst_alloc() take more explicit initializations.
Now the dst->dev, dev->obsolete, and dst->flags values can be specified as well. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/core/dst.c18
-rw-r--r--net/decnet/dn_route.c13
-rw-r--r--net/ipv4/route.c40
-rw-r--r--net/ipv6/route.c29
-rw-r--r--net/xfrm/xfrm_policy.c2
5 files changed, 42 insertions, 60 deletions
diff --git a/net/core/dst.c b/net/core/dst.c
index 91104d35de7d..9505778ec800 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -166,7 +166,8 @@ EXPORT_SYMBOL(dst_discard);
166 166
167const u32 dst_default_metrics[RTAX_MAX]; 167const u32 dst_default_metrics[RTAX_MAX];
168 168
169void *dst_alloc(struct dst_ops *ops, int initial_ref) 169void *dst_alloc(struct dst_ops *ops, struct net_device *dev,
170 int initial_ref, int initial_obsolete, int flags)
170{ 171{
171 struct dst_entry *dst; 172 struct dst_entry *dst;
172 173
@@ -177,12 +178,19 @@ void *dst_alloc(struct dst_ops *ops, int initial_ref)
177 dst = kmem_cache_zalloc(ops->kmem_cachep, GFP_ATOMIC); 178 dst = kmem_cache_zalloc(ops->kmem_cachep, GFP_ATOMIC);
178 if (!dst) 179 if (!dst)
179 return NULL; 180 return NULL;
180 atomic_set(&dst->__refcnt, initial_ref);
181 dst->ops = ops; 181 dst->ops = ops;
182 dst->lastuse = jiffies; 182 dst->dev = dev;
183 dst->path = dst; 183 if (dev)
184 dst->input = dst->output = dst_discard; 184 dev_hold(dev);
185 dst_init_metrics(dst, dst_default_metrics, true); 185 dst_init_metrics(dst, dst_default_metrics, true);
186 dst->path = dst;
187 dst->input = dst_discard;
188 dst->output = dst_discard;
189
190 dst->obsolete = initial_obsolete;
191 atomic_set(&dst->__refcnt, initial_ref);
192 dst->lastuse = jiffies;
193 dst->flags = flags;
186#if RT_CACHE_DEBUG >= 2 194#if RT_CACHE_DEBUG >= 2
187 atomic_inc(&dst_total); 195 atomic_inc(&dst_total);
188#endif 196#endif
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 9f09d4fc2880..f489b081c25d 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -1125,13 +1125,10 @@ make_route:
1125 if (dev_out->flags & IFF_LOOPBACK) 1125 if (dev_out->flags & IFF_LOOPBACK)
1126 flags |= RTCF_LOCAL; 1126 flags |= RTCF_LOCAL;
1127 1127
1128 rt = dst_alloc(&dn_dst_ops, 0); 1128 rt = dst_alloc(&dn_dst_ops, dev_out, 1, 0, DST_HOST);
1129 if (rt == NULL) 1129 if (rt == NULL)
1130 goto e_nobufs; 1130 goto e_nobufs;
1131 1131
1132 atomic_set(&rt->dst.__refcnt, 1);
1133 rt->dst.flags = DST_HOST;
1134
1135 rt->fld.saddr = oldflp->saddr; 1132 rt->fld.saddr = oldflp->saddr;
1136 rt->fld.daddr = oldflp->daddr; 1133 rt->fld.daddr = oldflp->daddr;
1137 rt->fld.flowidn_oif = oldflp->flowidn_oif; 1134 rt->fld.flowidn_oif = oldflp->flowidn_oif;
@@ -1146,8 +1143,6 @@ make_route:
1146 rt->rt_dst_map = fld.daddr; 1143 rt->rt_dst_map = fld.daddr;
1147 rt->rt_src_map = fld.saddr; 1144 rt->rt_src_map = fld.saddr;
1148 1145
1149 rt->dst.dev = dev_out;
1150 dev_hold(dev_out);
1151 rt->dst.neighbour = neigh; 1146 rt->dst.neighbour = neigh;
1152 neigh = NULL; 1147 neigh = NULL;
1153 1148
@@ -1399,7 +1394,7 @@ static int dn_route_input_slow(struct sk_buff *skb)
1399 } 1394 }
1400 1395
1401make_route: 1396make_route:
1402 rt = dst_alloc(&dn_dst_ops, 0); 1397 rt = dst_alloc(&dn_dst_ops, out_dev, 0, 0, DST_HOST);
1403 if (rt == NULL) 1398 if (rt == NULL)
1404 goto e_nobufs; 1399 goto e_nobufs;
1405 1400
@@ -1419,9 +1414,7 @@ make_route:
1419 rt->fld.flowidn_iif = in_dev->ifindex; 1414 rt->fld.flowidn_iif = in_dev->ifindex;
1420 rt->fld.flowidn_mark = fld.flowidn_mark; 1415 rt->fld.flowidn_mark = fld.flowidn_mark;
1421 1416
1422 rt->dst.flags = DST_HOST;
1423 rt->dst.neighbour = neigh; 1417 rt->dst.neighbour = neigh;
1424 rt->dst.dev = out_dev;
1425 rt->dst.lastuse = jiffies; 1418 rt->dst.lastuse = jiffies;
1426 rt->dst.output = dn_rt_bug; 1419 rt->dst.output = dn_rt_bug;
1427 switch(res.type) { 1420 switch(res.type) {
@@ -1440,8 +1433,6 @@ make_route:
1440 rt->dst.input = dst_discard; 1433 rt->dst.input = dst_discard;
1441 } 1434 }
1442 rt->rt_flags = flags; 1435 rt->rt_flags = flags;
1443 if (rt->dst.dev)
1444 dev_hold(rt->dst.dev);
1445 1436
1446 err = dn_rt_set_next_hop(rt, &res); 1437 err = dn_rt_set_next_hop(rt, &res);
1447 if (err) 1438 if (err)
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index d63f780c6941..b471d89b57ee 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1833,17 +1833,13 @@ static void rt_set_nexthop(struct rtable *rt, const struct flowi4 *oldflp4,
1833 rt->rt_type = type; 1833 rt->rt_type = type;
1834} 1834}
1835 1835
1836static struct rtable *rt_dst_alloc(bool nopolicy, bool noxfrm) 1836static struct rtable *rt_dst_alloc(struct net_device *dev,
1837 bool nopolicy, bool noxfrm)
1837{ 1838{
1838 struct rtable *rt = dst_alloc(&ipv4_dst_ops, 1); 1839 return dst_alloc(&ipv4_dst_ops, dev, 1, -1,
1839 if (rt) { 1840 DST_HOST |
1840 rt->dst.obsolete = -1; 1841 (nopolicy ? DST_NOPOLICY : 0) |
1841 1842 (noxfrm ? DST_NOXFRM : 0));
1842 rt->dst.flags = DST_HOST |
1843 (nopolicy ? DST_NOPOLICY : 0) |
1844 (noxfrm ? DST_NOXFRM : 0);
1845 }
1846 return rt;
1847} 1843}
1848 1844
1849/* called in rcu_read_lock() section */ 1845/* called in rcu_read_lock() section */
@@ -1876,7 +1872,8 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
1876 if (err < 0) 1872 if (err < 0)
1877 goto e_err; 1873 goto e_err;
1878 } 1874 }
1879 rth = rt_dst_alloc(IN_DEV_CONF_GET(in_dev, NOPOLICY), false); 1875 rth = rt_dst_alloc(init_net.loopback_dev,
1876 IN_DEV_CONF_GET(in_dev, NOPOLICY), false);
1880 if (!rth) 1877 if (!rth)
1881 goto e_nobufs; 1878 goto e_nobufs;
1882 1879
@@ -1893,8 +1890,6 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
1893#endif 1890#endif
1894 rth->rt_route_iif = dev->ifindex; 1891 rth->rt_route_iif = dev->ifindex;
1895 rth->rt_iif = dev->ifindex; 1892 rth->rt_iif = dev->ifindex;
1896 rth->dst.dev = init_net.loopback_dev;
1897 dev_hold(rth->dst.dev);
1898 rth->rt_oif = 0; 1893 rth->rt_oif = 0;
1899 rth->rt_gateway = daddr; 1894 rth->rt_gateway = daddr;
1900 rth->rt_spec_dst= spec_dst; 1895 rth->rt_spec_dst= spec_dst;
@@ -2013,7 +2008,8 @@ static int __mkroute_input(struct sk_buff *skb,
2013 } 2008 }
2014 } 2009 }
2015 2010
2016 rth = rt_dst_alloc(IN_DEV_CONF_GET(in_dev, NOPOLICY), 2011 rth = rt_dst_alloc(out_dev->dev,
2012 IN_DEV_CONF_GET(in_dev, NOPOLICY),
2017 IN_DEV_CONF_GET(out_dev, NOXFRM)); 2013 IN_DEV_CONF_GET(out_dev, NOXFRM));
2018 if (!rth) { 2014 if (!rth) {
2019 err = -ENOBUFS; 2015 err = -ENOBUFS;
@@ -2029,8 +2025,6 @@ static int __mkroute_input(struct sk_buff *skb,
2029 rth->rt_gateway = daddr; 2025 rth->rt_gateway = daddr;
2030 rth->rt_route_iif = in_dev->dev->ifindex; 2026 rth->rt_route_iif = in_dev->dev->ifindex;
2031 rth->rt_iif = in_dev->dev->ifindex; 2027 rth->rt_iif = in_dev->dev->ifindex;
2032 rth->dst.dev = (out_dev)->dev;
2033 dev_hold(rth->dst.dev);
2034 rth->rt_oif = 0; 2028 rth->rt_oif = 0;
2035 rth->rt_spec_dst= spec_dst; 2029 rth->rt_spec_dst= spec_dst;
2036 2030
@@ -2188,7 +2182,8 @@ brd_input:
2188 RT_CACHE_STAT_INC(in_brd); 2182 RT_CACHE_STAT_INC(in_brd);
2189 2183
2190local_input: 2184local_input:
2191 rth = rt_dst_alloc(IN_DEV_CONF_GET(in_dev, NOPOLICY), false); 2185 rth = rt_dst_alloc(net->loopback_dev,
2186 IN_DEV_CONF_GET(in_dev, NOPOLICY), false);
2192 if (!rth) 2187 if (!rth)
2193 goto e_nobufs; 2188 goto e_nobufs;
2194 2189
@@ -2206,8 +2201,6 @@ local_input:
2206#endif 2201#endif
2207 rth->rt_route_iif = dev->ifindex; 2202 rth->rt_route_iif = dev->ifindex;
2208 rth->rt_iif = dev->ifindex; 2203 rth->rt_iif = dev->ifindex;
2209 rth->dst.dev = net->loopback_dev;
2210 dev_hold(rth->dst.dev);
2211 rth->rt_gateway = daddr; 2204 rth->rt_gateway = daddr;
2212 rth->rt_spec_dst= spec_dst; 2205 rth->rt_spec_dst= spec_dst;
2213 rth->dst.input= ip_local_deliver; 2206 rth->dst.input= ip_local_deliver;
@@ -2392,7 +2385,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
2392 fi = NULL; 2385 fi = NULL;
2393 } 2386 }
2394 2387
2395 rth = rt_dst_alloc(IN_DEV_CONF_GET(in_dev, NOPOLICY), 2388 rth = rt_dst_alloc(dev_out,
2389 IN_DEV_CONF_GET(in_dev, NOPOLICY),
2396 IN_DEV_CONF_GET(in_dev, NOXFRM)); 2390 IN_DEV_CONF_GET(in_dev, NOXFRM));
2397 if (!rth) 2391 if (!rth)
2398 return ERR_PTR(-ENOBUFS); 2392 return ERR_PTR(-ENOBUFS);
@@ -2406,10 +2400,6 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
2406 rth->rt_src = fl4->saddr; 2400 rth->rt_src = fl4->saddr;
2407 rth->rt_route_iif = 0; 2401 rth->rt_route_iif = 0;
2408 rth->rt_iif = oldflp4->flowi4_oif ? : dev_out->ifindex; 2402 rth->rt_iif = oldflp4->flowi4_oif ? : dev_out->ifindex;
2409 /* get references to the devices that are to be hold by the routing
2410 cache entry */
2411 rth->dst.dev = dev_out;
2412 dev_hold(dev_out);
2413 rth->rt_gateway = fl4->daddr; 2403 rth->rt_gateway = fl4->daddr;
2414 rth->rt_spec_dst= fl4->saddr; 2404 rth->rt_spec_dst= fl4->saddr;
2415 2405
@@ -2711,7 +2701,7 @@ static struct dst_ops ipv4_dst_blackhole_ops = {
2711 2701
2712struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig) 2702struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig)
2713{ 2703{
2714 struct rtable *rt = dst_alloc(&ipv4_dst_blackhole_ops, 1); 2704 struct rtable *rt = dst_alloc(&ipv4_dst_blackhole_ops, NULL, 1, 0, 0);
2715 struct rtable *ort = (struct rtable *) dst_orig; 2705 struct rtable *ort = (struct rtable *) dst_orig;
2716 2706
2717 if (rt) { 2707 if (rt) {
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 19a77d0e0308..e8b2bb9060ef 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -227,9 +227,10 @@ static struct rt6_info ip6_blk_hole_entry_template = {
227#endif 227#endif
228 228
229/* allocate dst with ip6_dst_ops */ 229/* allocate dst with ip6_dst_ops */
230static inline struct rt6_info *ip6_dst_alloc(struct dst_ops *ops) 230static inline struct rt6_info *ip6_dst_alloc(struct dst_ops *ops,
231 struct net_device *dev)
231{ 232{
232 return (struct rt6_info *)dst_alloc(ops, 0); 233 return (struct rt6_info *)dst_alloc(ops, dev, 0, 0, 0);
233} 234}
234 235
235static void ip6_dst_destroy(struct dst_entry *dst) 236static void ip6_dst_destroy(struct dst_entry *dst)
@@ -881,10 +882,10 @@ EXPORT_SYMBOL(ip6_route_output);
881 882
882struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_orig) 883struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_orig)
883{ 884{
884 struct rt6_info *rt = dst_alloc(&ip6_dst_blackhole_ops, 1); 885 struct rt6_info *rt, *ort = (struct rt6_info *) dst_orig;
885 struct rt6_info *ort = (struct rt6_info *) dst_orig;
886 struct dst_entry *new = NULL; 886 struct dst_entry *new = NULL;
887 887
888 rt = dst_alloc(&ip6_dst_blackhole_ops, ort->dst.dev, 1, 0, 0);
888 if (rt) { 889 if (rt) {
889 new = &rt->dst; 890 new = &rt->dst;
890 891
@@ -893,9 +894,6 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori
893 new->output = dst_discard; 894 new->output = dst_discard;
894 895
895 dst_copy_metrics(new, &ort->dst); 896 dst_copy_metrics(new, &ort->dst);
896 new->dev = ort->dst.dev;
897 if (new->dev)
898 dev_hold(new->dev);
899 rt->rt6i_idev = ort->rt6i_idev; 897 rt->rt6i_idev = ort->rt6i_idev;
900 if (rt->rt6i_idev) 898 if (rt->rt6i_idev)
901 in6_dev_hold(rt->rt6i_idev); 899 in6_dev_hold(rt->rt6i_idev);
@@ -1038,13 +1036,12 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
1038 if (unlikely(idev == NULL)) 1036 if (unlikely(idev == NULL))
1039 return NULL; 1037 return NULL;
1040 1038
1041 rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops); 1039 rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, dev);
1042 if (unlikely(rt == NULL)) { 1040 if (unlikely(rt == NULL)) {
1043 in6_dev_put(idev); 1041 in6_dev_put(idev);
1044 goto out; 1042 goto out;
1045 } 1043 }
1046 1044
1047 dev_hold(dev);
1048 if (neigh) 1045 if (neigh)
1049 neigh_hold(neigh); 1046 neigh_hold(neigh);
1050 else { 1047 else {
@@ -1053,7 +1050,6 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
1053 neigh = NULL; 1050 neigh = NULL;
1054 } 1051 }
1055 1052
1056 rt->rt6i_dev = dev;
1057 rt->rt6i_idev = idev; 1053 rt->rt6i_idev = idev;
1058 rt->rt6i_nexthop = neigh; 1054 rt->rt6i_nexthop = neigh;
1059 atomic_set(&rt->dst.__refcnt, 1); 1055 atomic_set(&rt->dst.__refcnt, 1);
@@ -1212,7 +1208,7 @@ int ip6_route_add(struct fib6_config *cfg)
1212 goto out; 1208 goto out;
1213 } 1209 }
1214 1210
1215 rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops); 1211 rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, NULL);
1216 1212
1217 if (rt == NULL) { 1213 if (rt == NULL) {
1218 err = -ENOMEM; 1214 err = -ENOMEM;
@@ -1731,7 +1727,8 @@ void rt6_pmtu_discovery(const struct in6_addr *daddr, const struct in6_addr *sad
1731static struct rt6_info * ip6_rt_copy(struct rt6_info *ort) 1727static struct rt6_info * ip6_rt_copy(struct rt6_info *ort)
1732{ 1728{
1733 struct net *net = dev_net(ort->rt6i_dev); 1729 struct net *net = dev_net(ort->rt6i_dev);
1734 struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops); 1730 struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops,
1731 ort->dst.dev);
1735 1732
1736 if (rt) { 1733 if (rt) {
1737 rt->dst.input = ort->dst.input; 1734 rt->dst.input = ort->dst.input;
@@ -1739,9 +1736,6 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort)
1739 1736
1740 dst_copy_metrics(&rt->dst, &ort->dst); 1737 dst_copy_metrics(&rt->dst, &ort->dst);
1741 rt->dst.error = ort->dst.error; 1738 rt->dst.error = ort->dst.error;
1742 rt->dst.dev = ort->dst.dev;
1743 if (rt->dst.dev)
1744 dev_hold(rt->dst.dev);
1745 rt->rt6i_idev = ort->rt6i_idev; 1739 rt->rt6i_idev = ort->rt6i_idev;
1746 if (rt->rt6i_idev) 1740 if (rt->rt6i_idev)
1747 in6_dev_hold(rt->rt6i_idev); 1741 in6_dev_hold(rt->rt6i_idev);
@@ -2011,7 +2005,8 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
2011 int anycast) 2005 int anycast)
2012{ 2006{
2013 struct net *net = dev_net(idev->dev); 2007 struct net *net = dev_net(idev->dev);
2014 struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops); 2008 struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops,
2009 net->loopback_dev);
2015 struct neighbour *neigh; 2010 struct neighbour *neigh;
2016 2011
2017 if (rt == NULL) { 2012 if (rt == NULL) {
@@ -2021,13 +2016,11 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
2021 return ERR_PTR(-ENOMEM); 2016 return ERR_PTR(-ENOMEM);
2022 } 2017 }
2023 2018
2024 dev_hold(net->loopback_dev);
2025 in6_dev_hold(idev); 2019 in6_dev_hold(idev);
2026 2020
2027 rt->dst.flags = DST_HOST; 2021 rt->dst.flags = DST_HOST;
2028 rt->dst.input = ip6_input; 2022 rt->dst.input = ip6_input;
2029 rt->dst.output = ip6_output; 2023 rt->dst.output = ip6_output;
2030 rt->rt6i_dev = net->loopback_dev;
2031 rt->rt6i_idev = idev; 2024 rt->rt6i_idev = idev;
2032 rt->dst.obsolete = -1; 2025 rt->dst.obsolete = -1;
2033 2026
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 15792d8b6272..70552c4e2272 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1348,7 +1348,7 @@ static inline struct xfrm_dst *xfrm_alloc_dst(struct net *net, int family)
1348 default: 1348 default:
1349 BUG(); 1349 BUG();
1350 } 1350 }
1351 xdst = dst_alloc(dst_ops, 0); 1351 xdst = dst_alloc(dst_ops, NULL, 0, 0, 0);
1352 xfrm_policy_put_afinfo(afinfo); 1352 xfrm_policy_put_afinfo(afinfo);
1353 1353
1354 if (likely(xdst)) 1354 if (likely(xdst))