diff options
| -rw-r--r-- | net/xfrm/xfrm_policy.c | 16 |
1 files changed, 5 insertions, 11 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index bebd40e5a62e..b7e537fe2d75 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
| @@ -650,19 +650,18 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) | |||
| 650 | struct xfrm_policy *pol; | 650 | struct xfrm_policy *pol; |
| 651 | struct xfrm_policy *delpol; | 651 | struct xfrm_policy *delpol; |
| 652 | struct hlist_head *chain; | 652 | struct hlist_head *chain; |
| 653 | struct hlist_node *entry, *newpos, *last; | 653 | struct hlist_node *entry, *newpos; |
| 654 | struct dst_entry *gc_list; | 654 | struct dst_entry *gc_list; |
| 655 | 655 | ||
| 656 | write_lock_bh(&xfrm_policy_lock); | 656 | write_lock_bh(&xfrm_policy_lock); |
| 657 | chain = policy_hash_bysel(&policy->selector, policy->family, dir); | 657 | chain = policy_hash_bysel(&policy->selector, policy->family, dir); |
| 658 | delpol = NULL; | 658 | delpol = NULL; |
| 659 | newpos = NULL; | 659 | newpos = NULL; |
| 660 | last = NULL; | ||
| 661 | hlist_for_each_entry(pol, entry, chain, bydst) { | 660 | hlist_for_each_entry(pol, entry, chain, bydst) { |
| 662 | if (!delpol && | 661 | if (pol->type == policy->type && |
| 663 | pol->type == policy->type && | ||
| 664 | !selector_cmp(&pol->selector, &policy->selector) && | 662 | !selector_cmp(&pol->selector, &policy->selector) && |
| 665 | xfrm_sec_ctx_match(pol->security, policy->security)) { | 663 | xfrm_sec_ctx_match(pol->security, policy->security) && |
| 664 | !WARN_ON(delpol)) { | ||
| 666 | if (excl) { | 665 | if (excl) { |
| 667 | write_unlock_bh(&xfrm_policy_lock); | 666 | write_unlock_bh(&xfrm_policy_lock); |
| 668 | return -EEXIST; | 667 | return -EEXIST; |
| @@ -671,17 +670,12 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) | |||
| 671 | if (policy->priority > pol->priority) | 670 | if (policy->priority > pol->priority) |
| 672 | continue; | 671 | continue; |
| 673 | } else if (policy->priority >= pol->priority) { | 672 | } else if (policy->priority >= pol->priority) { |
| 674 | last = &pol->bydst; | 673 | newpos = &pol->bydst; |
| 675 | continue; | 674 | continue; |
| 676 | } | 675 | } |
| 677 | if (!newpos) | ||
| 678 | newpos = &pol->bydst; | ||
| 679 | if (delpol) | 676 | if (delpol) |
| 680 | break; | 677 | break; |
| 681 | last = &pol->bydst; | ||
| 682 | } | 678 | } |
| 683 | if (!newpos) | ||
| 684 | newpos = last; | ||
| 685 | if (newpos) | 679 | if (newpos) |
| 686 | hlist_add_after(newpos, &policy->bydst); | 680 | hlist_add_after(newpos, &policy->bydst); |
| 687 | else | 681 | else |
