|
@@ -248,12 +248,6 @@ static void ip6_rt_blackhole_redirect(struct dst_entry *dst, struct sock *sk,
|
|
|
{
|
|
|
}
|
|
|
|
|
|
-static u32 *ip6_rt_blackhole_cow_metrics(struct dst_entry *dst,
|
|
|
- unsigned long old)
|
|
|
-{
|
|
|
- return NULL;
|
|
|
-}
|
|
|
-
|
|
|
static struct dst_ops ip6_dst_blackhole_ops = {
|
|
|
.family = AF_INET6,
|
|
|
.destroy = ip6_dst_destroy,
|
|
@@ -262,7 +256,7 @@ static struct dst_ops ip6_dst_blackhole_ops = {
|
|
|
.default_advmss = ip6_default_advmss,
|
|
|
.update_pmtu = ip6_rt_blackhole_update_pmtu,
|
|
|
.redirect = ip6_rt_blackhole_redirect,
|
|
|
- .cow_metrics = ip6_rt_blackhole_cow_metrics,
|
|
|
+ .cow_metrics = dst_cow_metrics_generic,
|
|
|
.neigh_lookup = ip6_neigh_lookup,
|
|
|
};
|
|
|
|
|
@@ -319,6 +313,15 @@ static const struct rt6_info ip6_blk_hole_entry_template = {
|
|
|
|
|
|
#endif
|
|
|
|
|
|
+static void rt6_info_init(struct rt6_info *rt)
|
|
|
+{
|
|
|
+ struct dst_entry *dst = &rt->dst;
|
|
|
+
|
|
|
+ memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst));
|
|
|
+ INIT_LIST_HEAD(&rt->rt6i_siblings);
|
|
|
+ INIT_LIST_HEAD(&rt->rt6i_uncached);
|
|
|
+}
|
|
|
+
|
|
|
/* allocate dst with ip6_dst_ops */
|
|
|
static struct rt6_info *__ip6_dst_alloc(struct net *net,
|
|
|
struct net_device *dev,
|
|
@@ -327,13 +330,9 @@ static struct rt6_info *__ip6_dst_alloc(struct net *net,
|
|
|
struct rt6_info *rt = dst_alloc(&net->ipv6.ip6_dst_ops, dev,
|
|
|
0, DST_OBSOLETE_FORCE_CHK, flags);
|
|
|
|
|
|
- if (rt) {
|
|
|
- struct dst_entry *dst = &rt->dst;
|
|
|
+ if (rt)
|
|
|
+ rt6_info_init(rt);
|
|
|
|
|
|
- memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst));
|
|
|
- INIT_LIST_HEAD(&rt->rt6i_siblings);
|
|
|
- INIT_LIST_HEAD(&rt->rt6i_uncached);
|
|
|
- }
|
|
|
return rt;
|
|
|
}
|
|
|
|
|
@@ -1214,24 +1213,20 @@ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_ori
|
|
|
|
|
|
rt = dst_alloc(&ip6_dst_blackhole_ops, ort->dst.dev, 1, DST_OBSOLETE_NONE, 0);
|
|
|
if (rt) {
|
|
|
- new = &rt->dst;
|
|
|
-
|
|
|
- memset(new + 1, 0, sizeof(*rt) - sizeof(*new));
|
|
|
+ rt6_info_init(rt);
|
|
|
|
|
|
+ new = &rt->dst;
|
|
|
new->__use = 1;
|
|
|
new->input = dst_discard;
|
|
|
new->output = dst_discard_sk;
|
|
|
|
|
|
- if (dst_metrics_read_only(&ort->dst))
|
|
|
- new->_metrics = ort->dst._metrics;
|
|
|
- else
|
|
|
- dst_copy_metrics(new, &ort->dst);
|
|
|
+ dst_copy_metrics(new, &ort->dst);
|
|
|
rt->rt6i_idev = ort->rt6i_idev;
|
|
|
if (rt->rt6i_idev)
|
|
|
in6_dev_hold(rt->rt6i_idev);
|
|
|
|
|
|
rt->rt6i_gateway = ort->rt6i_gateway;
|
|
|
- rt->rt6i_flags = ort->rt6i_flags;
|
|
|
+ rt->rt6i_flags = ort->rt6i_flags & ~RTF_PCPU;
|
|
|
rt->rt6i_metric = 0;
|
|
|
|
|
|
memcpy(&rt->rt6i_dst, &ort->rt6i_dst, sizeof(struct rt6key));
|