summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--net/ipv6/route.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 9658939511e0..08bd68f1b5bb 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -4019,6 +4019,7 @@ static int __ip6_del_rt_siblings(struct fib6_info *rt, struct fib6_config *cfg)
struct net *net = info->nl_net;
struct sk_buff *skb = NULL;
struct fib6_table *table;
+ struct fib6_node *fn;
int err = -ENOENT;
if (rt == net->ipv6.fib6_null_entry)
@@ -4026,9 +4027,13 @@ static int __ip6_del_rt_siblings(struct fib6_info *rt, struct fib6_config *cfg)
table = rt->fib6_table;
spin_lock_bh(&table->tb6_lock);
+ fn = rcu_dereference_protected(rt->fib6_node,
+ lockdep_is_held(&table->tb6_lock));
+ if (!fn)
+ goto out_unlock;
+
if (rt->fib6_nsiblings && cfg->fc_delete_all_nh) {
struct fib6_info *sibling, *next_sibling;
- struct fib6_node *fn;
/* prefer to send a single notification with all hops */
skb = nlmsg_new(rt6_nlmsg_size(rt), GFP_ATOMIC);
@@ -4051,8 +4056,6 @@ static int __ip6_del_rt_siblings(struct fib6_info *rt, struct fib6_config *cfg)
* and emit a replace or delete notification, respectively.
*/
info->skip_notify_kernel = 1;
- fn = rcu_dereference_protected(rt->fib6_node,
- lockdep_is_held(&table->tb6_lock));
if (rcu_access_pointer(fn->leaf) == rt) {
struct fib6_info *last_sibling, *replace_rt;