|
|
@@ -1081,8 +1081,24 @@ add:
|
|
|
err = call_fib6_entry_notifiers(info->nl_net,
|
|
|
FIB_EVENT_ENTRY_ADD,
|
|
|
rt, extack);
|
|
|
- if (err)
|
|
|
+ if (err) {
|
|
|
+ struct fib6_info *sibling, *next_sibling;
|
|
|
+
|
|
|
+ /* If the route has siblings, then it first
|
|
|
+ * needs to be unlinked from them.
|
|
|
+ */
|
|
|
+ if (!rt->fib6_nsiblings)
|
|
|
+ return err;
|
|
|
+
|
|
|
+ list_for_each_entry_safe(sibling, next_sibling,
|
|
|
+ &rt->fib6_siblings,
|
|
|
+ fib6_siblings)
|
|
|
+ sibling->fib6_nsiblings--;
|
|
|
+ rt->fib6_nsiblings = 0;
|
|
|
+ list_del_init(&rt->fib6_siblings);
|
|
|
+ rt6_multipath_rebalance(next_sibling);
|
|
|
return err;
|
|
|
+ }
|
|
|
|
|
|
rcu_assign_pointer(rt->fib6_next, iter);
|
|
|
atomic_inc(&rt->fib6_ref);
|