route.c (0ee0f47c26b2f909ec95d7d8fed8119e288c4dd3) | route.c (0284696b97b2fad1b220871559dff410cc3187e0) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Linux INET6 implementation 4 * FIB front-end. 5 * 6 * Authors: 7 * Pedro Roque <roque@di.fc.ul.pt> 8 */ --- 3735 unchanged lines hidden (view full) --- 3744 3745 if (rt == net->ipv6.fib6_null_entry) 3746 goto out_put; 3747 table = rt->fib6_table; 3748 spin_lock_bh(&table->tb6_lock); 3749 3750 if (rt->fib6_nsiblings && cfg->fc_delete_all_nh) { 3751 struct fib6_info *sibling, *next_sibling; | 1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Linux INET6 implementation 4 * FIB front-end. 5 * 6 * Authors: 7 * Pedro Roque <roque@di.fc.ul.pt> 8 */ --- 3735 unchanged lines hidden (view full) --- 3744 3745 if (rt == net->ipv6.fib6_null_entry) 3746 goto out_put; 3747 table = rt->fib6_table; 3748 spin_lock_bh(&table->tb6_lock); 3749 3750 if (rt->fib6_nsiblings && cfg->fc_delete_all_nh) { 3751 struct fib6_info *sibling, *next_sibling; |
3752 struct fib6_node *fn; |
|
3752 3753 /* prefer to send a single notification with all hops */ 3754 skb = nlmsg_new(rt6_nlmsg_size(rt), gfp_any()); 3755 if (skb) { 3756 u32 seq = info->nlh ? info->nlh->nlmsg_seq : 0; 3757 3758 if (rt6_fill_node(net, skb, rt, NULL, 3759 NULL, NULL, 0, RTM_DELROUTE, 3760 info->portid, seq, 0) < 0) { 3761 kfree_skb(skb); 3762 skb = NULL; 3763 } else 3764 info->skip_notify = 1; 3765 } 3766 | 3753 3754 /* prefer to send a single notification with all hops */ 3755 skb = nlmsg_new(rt6_nlmsg_size(rt), gfp_any()); 3756 if (skb) { 3757 u32 seq = info->nlh ? info->nlh->nlmsg_seq : 0; 3758 3759 if (rt6_fill_node(net, skb, rt, NULL, 3760 NULL, NULL, 0, RTM_DELROUTE, 3761 info->portid, seq, 0) < 0) { 3762 kfree_skb(skb); 3763 skb = NULL; 3764 } else 3765 info->skip_notify = 1; 3766 } 3767 |
3768 /* 'rt' points to the first sibling route. If it is not the 3769 * leaf, then we do not need to send a notification. Otherwise, 3770 * we need to check if the last sibling has a next route or not 3771 * and emit a replace or delete notification, respectively. 3772 */ |
|
3767 info->skip_notify_kernel = 1; | 3773 info->skip_notify_kernel = 1; |
3774 fn = rcu_dereference_protected(rt->fib6_node, 3775 lockdep_is_held(&table->tb6_lock)); 3776 if (rcu_access_pointer(fn->leaf) == rt) { 3777 struct fib6_info *last_sibling, *replace_rt; 3778 3779 last_sibling = list_last_entry(&rt->fib6_siblings, 3780 struct fib6_info, 3781 fib6_siblings); 3782 replace_rt = rcu_dereference_protected( 3783 last_sibling->fib6_next, 3784 lockdep_is_held(&table->tb6_lock)); 3785 if (replace_rt) 3786 call_fib6_entry_notifiers_replace(net, 3787 replace_rt); 3788 else 3789 call_fib6_multipath_entry_notifiers(net, 3790 FIB_EVENT_ENTRY_DEL_TMP, 3791 rt, rt->fib6_nsiblings, 3792 NULL); 3793 } |
|
3768 call_fib6_multipath_entry_notifiers(net, 3769 FIB_EVENT_ENTRY_DEL, 3770 rt, 3771 rt->fib6_nsiblings, 3772 NULL); 3773 list_for_each_entry_safe(sibling, next_sibling, 3774 &rt->fib6_siblings, 3775 fib6_siblings) { --- 2699 unchanged lines hidden --- | 3794 call_fib6_multipath_entry_notifiers(net, 3795 FIB_EVENT_ENTRY_DEL, 3796 rt, 3797 rt->fib6_nsiblings, 3798 NULL); 3799 list_for_each_entry_safe(sibling, next_sibling, 3800 &rt->fib6_siblings, 3801 fib6_siblings) { --- 2699 unchanged lines hidden --- |