Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

xfrm: policy: split list insertion into a helper

... so we can reuse this later without code duplication when we add
policy to a second inexact list.

Signed-off-by: Florian Westphal <fw@strlen.de>
Acked-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>

authored by

Florian Westphal and committed by
Steffen Klassert
a927d6af ceb159e3

+27 -16
+27 -16
net/xfrm/xfrm_policy.c
··· 740 740 return false; 741 741 } 742 742 743 - int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) 743 + static struct xfrm_policy *xfrm_policy_insert_list(struct hlist_head *chain, 744 + struct xfrm_policy *policy, 745 + bool excl) 744 746 { 745 - struct net *net = xp_net(policy); 746 - struct xfrm_policy *pol; 747 - struct xfrm_policy *delpol; 748 - struct hlist_head *chain; 749 - struct hlist_node *newpos; 747 + struct xfrm_policy *pol, *newpos = NULL, *delpol = NULL; 750 748 751 - spin_lock_bh(&net->xfrm.xfrm_policy_lock); 752 - chain = policy_hash_bysel(net, &policy->selector, policy->family, dir); 753 - delpol = NULL; 754 - newpos = NULL; 755 749 hlist_for_each_entry(pol, chain, bydst) { 756 750 if (pol->type == policy->type && 757 751 pol->if_id == policy->if_id && ··· 753 759 xfrm_policy_mark_match(policy, pol) && 754 760 xfrm_sec_ctx_match(pol->security, policy->security) && 755 761 !WARN_ON(delpol)) { 756 - if (excl) { 757 - spin_unlock_bh(&net->xfrm.xfrm_policy_lock); 758 - return -EEXIST; 759 - } 762 + if (excl) 763 + return ERR_PTR(-EEXIST); 760 764 delpol = pol; 761 765 if (policy->priority > pol->priority) 762 766 continue; 763 767 } else if (policy->priority >= pol->priority) { 764 - newpos = &pol->bydst; 768 + newpos = pol; 765 769 continue; 766 770 } 767 771 if (delpol) 768 772 break; 769 773 } 770 774 if (newpos) 771 - hlist_add_behind_rcu(&policy->bydst, newpos); 775 + hlist_add_behind_rcu(&policy->bydst, &newpos->bydst); 772 776 else 773 777 hlist_add_head_rcu(&policy->bydst, chain); 778 + 779 + return delpol; 780 + } 781 + 782 + int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) 783 + { 784 + struct net *net = xp_net(policy); 785 + struct xfrm_policy *delpol; 786 + struct hlist_head *chain; 787 + 788 + spin_lock_bh(&net->xfrm.xfrm_policy_lock); 789 + chain = policy_hash_bysel(net, &policy->selector, policy->family, dir); 790 + delpol = xfrm_policy_insert_list(chain, policy, excl); 791 + 792 + if (IS_ERR(delpol)) { 793 + spin_unlock_bh(&net->xfrm.xfrm_policy_lock); 794 + return PTR_ERR(delpol); 795 + } 796 + 774 797 __xfrm_policy_link(policy, dir); 775 798 776 799 /* After previous checking, family can either be AF_INET or AF_INET6 */