Commit 071fb37e authored by David Miller's avatar David Miller Committed by David S. Miller

ipv6: Move rt6_next from dst_entry into ipv6 route structure.

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Reviewed-by: default avatarEric Dumazet <edumazet@google.com>
parent fe736e77
...@@ -101,7 +101,6 @@ struct dst_entry { ...@@ -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 { ...@@ -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 { ...@@ -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, ...@@ -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, ...@@ -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 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, ...@@ -979,7 +979,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
&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 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, ...@@ -1009,7 +1009,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
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 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, ...@@ -1040,7 +1040,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
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 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, ...@@ -1059,14 +1059,14 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
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 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, ...@@ -1075,7 +1075,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment