ipv6: Move rt6_next from dst_entry into ipv6 route structure.
Signed-off-by: David S. Miller <davem@davemloft.net> Reviewed-by: Eric Dumazet <edumazet@google.com>
This commit is contained in:
parent
fe736e778c
commit
071fb37ec4
|
@ -101,7 +101,6 @@ struct dst_entry {
|
||||||
struct lwtunnel_state *lwtstate;
|
struct lwtunnel_state *lwtstate;
|
||||||
union {
|
union {
|
||||||
struct dst_entry *next;
|
struct dst_entry *next;
|
||||||
struct rt6_info __rcu *rt6_next;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -129,6 +129,7 @@ struct rt6_exception {
|
||||||
|
|
||||||
struct rt6_info {
|
struct rt6_info {
|
||||||
struct dst_entry dst;
|
struct dst_entry dst;
|
||||||
|
struct rt6_info __rcu *rt6_next;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tail elements of dst_entry (__refcnt etc.)
|
* Tail elements of dst_entry (__refcnt etc.)
|
||||||
|
@ -176,11 +177,11 @@ struct rt6_info {
|
||||||
|
|
||||||
#define for_each_fib6_node_rt_rcu(fn) \
|
#define for_each_fib6_node_rt_rcu(fn) \
|
||||||
for (rt = rcu_dereference((fn)->leaf); rt; \
|
for (rt = rcu_dereference((fn)->leaf); rt; \
|
||||||
rt = rcu_dereference(rt->dst.rt6_next))
|
rt = rcu_dereference(rt->rt6_next))
|
||||||
|
|
||||||
#define for_each_fib6_walker_rt(w) \
|
#define for_each_fib6_walker_rt(w) \
|
||||||
for (rt = (w)->leaf; rt; \
|
for (rt = (w)->leaf; rt; \
|
||||||
rt = rcu_dereference_protected(rt->dst.rt6_next, 1))
|
rt = rcu_dereference_protected(rt->rt6_next, 1))
|
||||||
|
|
||||||
static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst)
|
static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst)
|
||||||
{
|
{
|
||||||
|
|
|
@ -893,7 +893,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
|
||||||
ins = &fn->leaf;
|
ins = &fn->leaf;
|
||||||
|
|
||||||
for (iter = leaf; iter;
|
for (iter = leaf; iter;
|
||||||
iter = rcu_dereference_protected(iter->dst.rt6_next,
|
iter = rcu_dereference_protected(iter->rt6_next,
|
||||||
lockdep_is_held(&rt->rt6i_table->tb6_lock))) {
|
lockdep_is_held(&rt->rt6i_table->tb6_lock))) {
|
||||||
/*
|
/*
|
||||||
* Search for duplicates
|
* Search for duplicates
|
||||||
|
@ -950,7 +950,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
next_iter:
|
next_iter:
|
||||||
ins = &iter->dst.rt6_next;
|
ins = &iter->rt6_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fallback_ins && !found) {
|
if (fallback_ins && !found) {
|
||||||
|
@ -979,7 +979,7 @@ next_iter:
|
||||||
&sibling->rt6i_siblings);
|
&sibling->rt6i_siblings);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sibling = rcu_dereference_protected(sibling->dst.rt6_next,
|
sibling = rcu_dereference_protected(sibling->rt6_next,
|
||||||
lockdep_is_held(&rt->rt6i_table->tb6_lock));
|
lockdep_is_held(&rt->rt6i_table->tb6_lock));
|
||||||
}
|
}
|
||||||
/* For each sibling in the list, increment the counter of
|
/* For each sibling in the list, increment the counter of
|
||||||
|
@ -1009,7 +1009,7 @@ add:
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
rcu_assign_pointer(rt->dst.rt6_next, iter);
|
rcu_assign_pointer(rt->rt6_next, iter);
|
||||||
atomic_inc(&rt->rt6i_ref);
|
atomic_inc(&rt->rt6i_ref);
|
||||||
rcu_assign_pointer(rt->rt6i_node, fn);
|
rcu_assign_pointer(rt->rt6i_node, fn);
|
||||||
rcu_assign_pointer(*ins, rt);
|
rcu_assign_pointer(*ins, rt);
|
||||||
|
@ -1040,7 +1040,7 @@ add:
|
||||||
|
|
||||||
atomic_inc(&rt->rt6i_ref);
|
atomic_inc(&rt->rt6i_ref);
|
||||||
rcu_assign_pointer(rt->rt6i_node, fn);
|
rcu_assign_pointer(rt->rt6i_node, fn);
|
||||||
rt->dst.rt6_next = iter->dst.rt6_next;
|
rt->rt6_next = iter->rt6_next;
|
||||||
rcu_assign_pointer(*ins, rt);
|
rcu_assign_pointer(*ins, rt);
|
||||||
call_fib6_entry_notifiers(info->nl_net, FIB_EVENT_ENTRY_REPLACE,
|
call_fib6_entry_notifiers(info->nl_net, FIB_EVENT_ENTRY_REPLACE,
|
||||||
rt, extack);
|
rt, extack);
|
||||||
|
@ -1059,14 +1059,14 @@ add:
|
||||||
|
|
||||||
if (nsiblings) {
|
if (nsiblings) {
|
||||||
/* Replacing an ECMP route, remove all siblings */
|
/* Replacing an ECMP route, remove all siblings */
|
||||||
ins = &rt->dst.rt6_next;
|
ins = &rt->rt6_next;
|
||||||
iter = rcu_dereference_protected(*ins,
|
iter = rcu_dereference_protected(*ins,
|
||||||
lockdep_is_held(&rt->rt6i_table->tb6_lock));
|
lockdep_is_held(&rt->rt6i_table->tb6_lock));
|
||||||
while (iter) {
|
while (iter) {
|
||||||
if (iter->rt6i_metric > rt->rt6i_metric)
|
if (iter->rt6i_metric > rt->rt6i_metric)
|
||||||
break;
|
break;
|
||||||
if (rt6_qualify_for_ecmp(iter)) {
|
if (rt6_qualify_for_ecmp(iter)) {
|
||||||
*ins = iter->dst.rt6_next;
|
*ins = iter->rt6_next;
|
||||||
iter->rt6i_node = NULL;
|
iter->rt6i_node = NULL;
|
||||||
fib6_purge_rt(iter, fn, info->nl_net);
|
fib6_purge_rt(iter, fn, info->nl_net);
|
||||||
if (rcu_access_pointer(fn->rr_ptr) == iter)
|
if (rcu_access_pointer(fn->rr_ptr) == iter)
|
||||||
|
@ -1075,7 +1075,7 @@ add:
|
||||||
nsiblings--;
|
nsiblings--;
|
||||||
info->nl_net->ipv6.rt6_stats->fib_rt_entries--;
|
info->nl_net->ipv6.rt6_stats->fib_rt_entries--;
|
||||||
} else {
|
} else {
|
||||||
ins = &iter->dst.rt6_next;
|
ins = &iter->rt6_next;
|
||||||
}
|
}
|
||||||
iter = rcu_dereference_protected(*ins,
|
iter = rcu_dereference_protected(*ins,
|
||||||
lockdep_is_held(&rt->rt6i_table->tb6_lock));
|
lockdep_is_held(&rt->rt6i_table->tb6_lock));
|
||||||
|
@ -1644,7 +1644,7 @@ static void fib6_del_route(struct fib6_table *table, struct fib6_node *fn,
|
||||||
WARN_ON_ONCE(rt->rt6i_flags & RTF_CACHE);
|
WARN_ON_ONCE(rt->rt6i_flags & RTF_CACHE);
|
||||||
|
|
||||||
/* Unlink it */
|
/* Unlink it */
|
||||||
*rtp = rt->dst.rt6_next;
|
*rtp = rt->rt6_next;
|
||||||
rt->rt6i_node = NULL;
|
rt->rt6i_node = NULL;
|
||||||
net->ipv6.rt6_stats->fib_rt_entries--;
|
net->ipv6.rt6_stats->fib_rt_entries--;
|
||||||
net->ipv6.rt6_stats->fib_discarded_routes++;
|
net->ipv6.rt6_stats->fib_discarded_routes++;
|
||||||
|
@ -1672,7 +1672,7 @@ static void fib6_del_route(struct fib6_table *table, struct fib6_node *fn,
|
||||||
FOR_WALKERS(net, w) {
|
FOR_WALKERS(net, w) {
|
||||||
if (w->state == FWS_C && w->leaf == rt) {
|
if (w->state == FWS_C && w->leaf == rt) {
|
||||||
RT6_TRACE("walker %p adjusted by delroute\n", w);
|
RT6_TRACE("walker %p adjusted by delroute\n", w);
|
||||||
w->leaf = rcu_dereference_protected(rt->dst.rt6_next,
|
w->leaf = rcu_dereference_protected(rt->rt6_next,
|
||||||
lockdep_is_held(&table->tb6_lock));
|
lockdep_is_held(&table->tb6_lock));
|
||||||
if (!w->leaf)
|
if (!w->leaf)
|
||||||
w->state = FWS_U;
|
w->state = FWS_U;
|
||||||
|
@ -1731,7 +1731,7 @@ int fib6_del(struct rt6_info *rt, struct nl_info *info)
|
||||||
fib6_del_route(table, fn, rtp, info);
|
fib6_del_route(table, fn, rtp, info);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
rtp_next = &cur->dst.rt6_next;
|
rtp_next = &cur->rt6_next;
|
||||||
}
|
}
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
@ -2208,7 +2208,7 @@ static int ipv6_route_yield(struct fib6_walker *w)
|
||||||
|
|
||||||
do {
|
do {
|
||||||
iter->w.leaf = rcu_dereference_protected(
|
iter->w.leaf = rcu_dereference_protected(
|
||||||
iter->w.leaf->dst.rt6_next,
|
iter->w.leaf->rt6_next,
|
||||||
lockdep_is_held(&iter->tbl->tb6_lock));
|
lockdep_is_held(&iter->tbl->tb6_lock));
|
||||||
iter->skip--;
|
iter->skip--;
|
||||||
if (!iter->skip && iter->w.leaf)
|
if (!iter->skip && iter->w.leaf)
|
||||||
|
@ -2274,7 +2274,7 @@ static void *ipv6_route_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
||||||
if (!v)
|
if (!v)
|
||||||
goto iter_table;
|
goto iter_table;
|
||||||
|
|
||||||
n = rcu_dereference_bh(((struct rt6_info *)v)->dst.rt6_next);
|
n = rcu_dereference_bh(((struct rt6_info *)v)->rt6_next);
|
||||||
if (n) {
|
if (n) {
|
||||||
++*pos;
|
++*pos;
|
||||||
return n;
|
return n;
|
||||||
|
|
|
@ -502,7 +502,7 @@ static inline struct rt6_info *rt6_device_match(struct net *net,
|
||||||
if (!oif && ipv6_addr_any(saddr))
|
if (!oif && ipv6_addr_any(saddr))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
for (sprt = rt; sprt; sprt = rcu_dereference(sprt->dst.rt6_next)) {
|
for (sprt = rt; sprt; sprt = rcu_dereference(sprt->rt6_next)) {
|
||||||
struct net_device *dev = sprt->dst.dev;
|
struct net_device *dev = sprt->dst.dev;
|
||||||
|
|
||||||
if (oif) {
|
if (oif) {
|
||||||
|
@ -721,7 +721,7 @@ static struct rt6_info *find_rr_leaf(struct fib6_node *fn,
|
||||||
|
|
||||||
match = NULL;
|
match = NULL;
|
||||||
cont = NULL;
|
cont = NULL;
|
||||||
for (rt = rr_head; rt; rt = rcu_dereference(rt->dst.rt6_next)) {
|
for (rt = rr_head; rt; rt = rcu_dereference(rt->rt6_next)) {
|
||||||
if (rt->rt6i_metric != metric) {
|
if (rt->rt6i_metric != metric) {
|
||||||
cont = rt;
|
cont = rt;
|
||||||
break;
|
break;
|
||||||
|
@ -731,7 +731,7 @@ static struct rt6_info *find_rr_leaf(struct fib6_node *fn,
|
||||||
}
|
}
|
||||||
|
|
||||||
for (rt = leaf; rt && rt != rr_head;
|
for (rt = leaf; rt && rt != rr_head;
|
||||||
rt = rcu_dereference(rt->dst.rt6_next)) {
|
rt = rcu_dereference(rt->rt6_next)) {
|
||||||
if (rt->rt6i_metric != metric) {
|
if (rt->rt6i_metric != metric) {
|
||||||
cont = rt;
|
cont = rt;
|
||||||
break;
|
break;
|
||||||
|
@ -743,7 +743,7 @@ static struct rt6_info *find_rr_leaf(struct fib6_node *fn,
|
||||||
if (match || !cont)
|
if (match || !cont)
|
||||||
return match;
|
return match;
|
||||||
|
|
||||||
for (rt = cont; rt; rt = rcu_dereference(rt->dst.rt6_next))
|
for (rt = cont; rt; rt = rcu_dereference(rt->rt6_next))
|
||||||
match = find_match(rt, oif, strict, &mpri, match, do_rr);
|
match = find_match(rt, oif, strict, &mpri, match, do_rr);
|
||||||
|
|
||||||
return match;
|
return match;
|
||||||
|
@ -781,7 +781,7 @@ static struct rt6_info *rt6_select(struct net *net, struct fib6_node *fn,
|
||||||
&do_rr);
|
&do_rr);
|
||||||
|
|
||||||
if (do_rr) {
|
if (do_rr) {
|
||||||
struct rt6_info *next = rcu_dereference(rt0->dst.rt6_next);
|
struct rt6_info *next = rcu_dereference(rt0->rt6_next);
|
||||||
|
|
||||||
/* no entries matched; do round-robin */
|
/* no entries matched; do round-robin */
|
||||||
if (!next || next->rt6i_metric != rt0->rt6i_metric)
|
if (!next || next->rt6i_metric != rt0->rt6i_metric)
|
||||||
|
|
Loading…
Reference in New Issue