diff options
Diffstat (limited to 'net/xfrm/xfrm_policy.c')
-rw-r--r-- | net/xfrm/xfrm_policy.c | 47 |
1 files changed, 20 insertions, 27 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 5b47180986f8..167c67d46c6a 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -379,27 +379,27 @@ static void xfrm_dst_hash_transfer(struct hlist_head *list, | |||
379 | struct hlist_head *ndsttable, | 379 | struct hlist_head *ndsttable, |
380 | unsigned int nhashmask) | 380 | unsigned int nhashmask) |
381 | { | 381 | { |
382 | struct hlist_node *entry, *tmp, *entry0 = NULL; | 382 | struct hlist_node *tmp, *entry0 = NULL; |
383 | struct xfrm_policy *pol; | 383 | struct xfrm_policy *pol; |
384 | unsigned int h0 = 0; | 384 | unsigned int h0 = 0; |
385 | 385 | ||
386 | redo: | 386 | redo: |
387 | hlist_for_each_entry_safe(pol, entry, tmp, list, bydst) { | 387 | hlist_for_each_entry_safe(pol, tmp, list, bydst) { |
388 | unsigned int h; | 388 | unsigned int h; |
389 | 389 | ||
390 | h = __addr_hash(&pol->selector.daddr, &pol->selector.saddr, | 390 | h = __addr_hash(&pol->selector.daddr, &pol->selector.saddr, |
391 | pol->family, nhashmask); | 391 | pol->family, nhashmask); |
392 | if (!entry0) { | 392 | if (!entry0) { |
393 | hlist_del(entry); | 393 | hlist_del(&pol->bydst); |
394 | hlist_add_head(&pol->bydst, ndsttable+h); | 394 | hlist_add_head(&pol->bydst, ndsttable+h); |
395 | h0 = h; | 395 | h0 = h; |
396 | } else { | 396 | } else { |
397 | if (h != h0) | 397 | if (h != h0) |
398 | continue; | 398 | continue; |
399 | hlist_del(entry); | 399 | hlist_del(&pol->bydst); |
400 | hlist_add_after(entry0, &pol->bydst); | 400 | hlist_add_after(entry0, &pol->bydst); |
401 | } | 401 | } |
402 | entry0 = entry; | 402 | entry0 = &pol->bydst; |
403 | } | 403 | } |
404 | if (!hlist_empty(list)) { | 404 | if (!hlist_empty(list)) { |
405 | entry0 = NULL; | 405 | entry0 = NULL; |
@@ -411,10 +411,10 @@ static void xfrm_idx_hash_transfer(struct hlist_head *list, | |||
411 | struct hlist_head *nidxtable, | 411 | struct hlist_head *nidxtable, |
412 | unsigned int nhashmask) | 412 | unsigned int nhashmask) |
413 | { | 413 | { |
414 | struct hlist_node *entry, *tmp; | 414 | struct hlist_node *tmp; |
415 | struct xfrm_policy *pol; | 415 | struct xfrm_policy *pol; |
416 | 416 | ||
417 | hlist_for_each_entry_safe(pol, entry, tmp, list, byidx) { | 417 | hlist_for_each_entry_safe(pol, tmp, list, byidx) { |
418 | unsigned int h; | 418 | unsigned int h; |
419 | 419 | ||
420 | h = __idx_hash(pol->index, nhashmask); | 420 | h = __idx_hash(pol->index, nhashmask); |
@@ -544,7 +544,6 @@ static u32 xfrm_gen_index(struct net *net, int dir) | |||
544 | static u32 idx_generator; | 544 | static u32 idx_generator; |
545 | 545 | ||
546 | for (;;) { | 546 | for (;;) { |
547 | struct hlist_node *entry; | ||
548 | struct hlist_head *list; | 547 | struct hlist_head *list; |
549 | struct xfrm_policy *p; | 548 | struct xfrm_policy *p; |
550 | u32 idx; | 549 | u32 idx; |
@@ -556,7 +555,7 @@ static u32 xfrm_gen_index(struct net *net, int dir) | |||
556 | idx = 8; | 555 | idx = 8; |
557 | list = net->xfrm.policy_byidx + idx_hash(net, idx); | 556 | list = net->xfrm.policy_byidx + idx_hash(net, idx); |
558 | found = 0; | 557 | found = 0; |
559 | hlist_for_each_entry(p, entry, list, byidx) { | 558 | hlist_for_each_entry(p, list, byidx) { |
560 | if (p->index == idx) { | 559 | if (p->index == idx) { |
561 | found = 1; | 560 | found = 1; |
562 | break; | 561 | break; |
@@ -628,13 +627,13 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) | |||
628 | struct xfrm_policy *pol; | 627 | struct xfrm_policy *pol; |
629 | struct xfrm_policy *delpol; | 628 | struct xfrm_policy *delpol; |
630 | struct hlist_head *chain; | 629 | struct hlist_head *chain; |
631 | struct hlist_node *entry, *newpos; | 630 | struct hlist_node *newpos; |
632 | 631 | ||
633 | write_lock_bh(&xfrm_policy_lock); | 632 | write_lock_bh(&xfrm_policy_lock); |
634 | chain = policy_hash_bysel(net, &policy->selector, policy->family, dir); | 633 | chain = policy_hash_bysel(net, &policy->selector, policy->family, dir); |
635 | delpol = NULL; | 634 | delpol = NULL; |
636 | newpos = NULL; | 635 | newpos = NULL; |
637 | hlist_for_each_entry(pol, entry, chain, bydst) { | 636 | hlist_for_each_entry(pol, chain, bydst) { |
638 | if (pol->type == policy->type && | 637 | if (pol->type == policy->type && |
639 | !selector_cmp(&pol->selector, &policy->selector) && | 638 | !selector_cmp(&pol->selector, &policy->selector) && |
640 | xfrm_policy_mark_match(policy, pol) && | 639 | xfrm_policy_mark_match(policy, pol) && |
@@ -691,13 +690,12 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, u8 type, | |||
691 | { | 690 | { |
692 | struct xfrm_policy *pol, *ret; | 691 | struct xfrm_policy *pol, *ret; |
693 | struct hlist_head *chain; | 692 | struct hlist_head *chain; |
694 | struct hlist_node *entry; | ||
695 | 693 | ||
696 | *err = 0; | 694 | *err = 0; |
697 | write_lock_bh(&xfrm_policy_lock); | 695 | write_lock_bh(&xfrm_policy_lock); |
698 | chain = policy_hash_bysel(net, sel, sel->family, dir); | 696 | chain = policy_hash_bysel(net, sel, sel->family, dir); |
699 | ret = NULL; | 697 | ret = NULL; |
700 | hlist_for_each_entry(pol, entry, chain, bydst) { | 698 | hlist_for_each_entry(pol, chain, bydst) { |
701 | if (pol->type == type && | 699 | if (pol->type == type && |
702 | (mark & pol->mark.m) == pol->mark.v && | 700 | (mark & pol->mark.m) == pol->mark.v && |
703 | !selector_cmp(sel, &pol->selector) && | 701 | !selector_cmp(sel, &pol->selector) && |
@@ -729,7 +727,6 @@ struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u8 type, | |||
729 | { | 727 | { |
730 | struct xfrm_policy *pol, *ret; | 728 | struct xfrm_policy *pol, *ret; |
731 | struct hlist_head *chain; | 729 | struct hlist_head *chain; |
732 | struct hlist_node *entry; | ||
733 | 730 | ||
734 | *err = -ENOENT; | 731 | *err = -ENOENT; |
735 | if (xfrm_policy_id2dir(id) != dir) | 732 | if (xfrm_policy_id2dir(id) != dir) |
@@ -739,7 +736,7 @@ struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u8 type, | |||
739 | write_lock_bh(&xfrm_policy_lock); | 736 | write_lock_bh(&xfrm_policy_lock); |
740 | chain = net->xfrm.policy_byidx + idx_hash(net, id); | 737 | chain = net->xfrm.policy_byidx + idx_hash(net, id); |
741 | ret = NULL; | 738 | ret = NULL; |
742 | hlist_for_each_entry(pol, entry, chain, byidx) { | 739 | hlist_for_each_entry(pol, chain, byidx) { |
743 | if (pol->type == type && pol->index == id && | 740 | if (pol->type == type && pol->index == id && |
744 | (mark & pol->mark.m) == pol->mark.v) { | 741 | (mark & pol->mark.m) == pol->mark.v) { |
745 | xfrm_pol_hold(pol); | 742 | xfrm_pol_hold(pol); |
@@ -772,10 +769,9 @@ xfrm_policy_flush_secctx_check(struct net *net, u8 type, struct xfrm_audit *audi | |||
772 | 769 | ||
773 | for (dir = 0; dir < XFRM_POLICY_MAX; dir++) { | 770 | for (dir = 0; dir < XFRM_POLICY_MAX; dir++) { |
774 | struct xfrm_policy *pol; | 771 | struct xfrm_policy *pol; |
775 | struct hlist_node *entry; | ||
776 | int i; | 772 | int i; |
777 | 773 | ||
778 | hlist_for_each_entry(pol, entry, | 774 | hlist_for_each_entry(pol, |
779 | &net->xfrm.policy_inexact[dir], bydst) { | 775 | &net->xfrm.policy_inexact[dir], bydst) { |
780 | if (pol->type != type) | 776 | if (pol->type != type) |
781 | continue; | 777 | continue; |
@@ -789,7 +785,7 @@ xfrm_policy_flush_secctx_check(struct net *net, u8 type, struct xfrm_audit *audi | |||
789 | } | 785 | } |
790 | } | 786 | } |
791 | for (i = net->xfrm.policy_bydst[dir].hmask; i >= 0; i--) { | 787 | for (i = net->xfrm.policy_bydst[dir].hmask; i >= 0; i--) { |
792 | hlist_for_each_entry(pol, entry, | 788 | hlist_for_each_entry(pol, |
793 | net->xfrm.policy_bydst[dir].table + i, | 789 | net->xfrm.policy_bydst[dir].table + i, |
794 | bydst) { | 790 | bydst) { |
795 | if (pol->type != type) | 791 | if (pol->type != type) |
@@ -828,11 +824,10 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info) | |||
828 | 824 | ||
829 | for (dir = 0; dir < XFRM_POLICY_MAX; dir++) { | 825 | for (dir = 0; dir < XFRM_POLICY_MAX; dir++) { |
830 | struct xfrm_policy *pol; | 826 | struct xfrm_policy *pol; |
831 | struct hlist_node *entry; | ||
832 | int i; | 827 | int i; |
833 | 828 | ||
834 | again1: | 829 | again1: |
835 | hlist_for_each_entry(pol, entry, | 830 | hlist_for_each_entry(pol, |
836 | &net->xfrm.policy_inexact[dir], bydst) { | 831 | &net->xfrm.policy_inexact[dir], bydst) { |
837 | if (pol->type != type) | 832 | if (pol->type != type) |
838 | continue; | 833 | continue; |
@@ -852,7 +847,7 @@ int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info) | |||
852 | 847 | ||
853 | for (i = net->xfrm.policy_bydst[dir].hmask; i >= 0; i--) { | 848 | for (i = net->xfrm.policy_bydst[dir].hmask; i >= 0; i--) { |
854 | again2: | 849 | again2: |
855 | hlist_for_each_entry(pol, entry, | 850 | hlist_for_each_entry(pol, |
856 | net->xfrm.policy_bydst[dir].table + i, | 851 | net->xfrm.policy_bydst[dir].table + i, |
857 | bydst) { | 852 | bydst) { |
858 | if (pol->type != type) | 853 | if (pol->type != type) |
@@ -980,7 +975,6 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(struct net *net, u8 type, | |||
980 | int err; | 975 | int err; |
981 | struct xfrm_policy *pol, *ret; | 976 | struct xfrm_policy *pol, *ret; |
982 | const xfrm_address_t *daddr, *saddr; | 977 | const xfrm_address_t *daddr, *saddr; |
983 | struct hlist_node *entry; | ||
984 | struct hlist_head *chain; | 978 | struct hlist_head *chain; |
985 | u32 priority = ~0U; | 979 | u32 priority = ~0U; |
986 | 980 | ||
@@ -992,7 +986,7 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(struct net *net, u8 type, | |||
992 | read_lock_bh(&xfrm_policy_lock); | 986 | read_lock_bh(&xfrm_policy_lock); |
993 | chain = policy_hash_direct(net, daddr, saddr, family, dir); | 987 | chain = policy_hash_direct(net, daddr, saddr, family, dir); |
994 | ret = NULL; | 988 | ret = NULL; |
995 | hlist_for_each_entry(pol, entry, chain, bydst) { | 989 | hlist_for_each_entry(pol, chain, bydst) { |
996 | err = xfrm_policy_match(pol, fl, type, family, dir); | 990 | err = xfrm_policy_match(pol, fl, type, family, dir); |
997 | if (err) { | 991 | if (err) { |
998 | if (err == -ESRCH) | 992 | if (err == -ESRCH) |
@@ -1008,7 +1002,7 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(struct net *net, u8 type, | |||
1008 | } | 1002 | } |
1009 | } | 1003 | } |
1010 | chain = &net->xfrm.policy_inexact[dir]; | 1004 | chain = &net->xfrm.policy_inexact[dir]; |
1011 | hlist_for_each_entry(pol, entry, chain, bydst) { | 1005 | hlist_for_each_entry(pol, chain, bydst) { |
1012 | err = xfrm_policy_match(pol, fl, type, family, dir); | 1006 | err = xfrm_policy_match(pol, fl, type, family, dir); |
1013 | if (err) { | 1007 | if (err) { |
1014 | if (err == -ESRCH) | 1008 | if (err == -ESRCH) |
@@ -3041,13 +3035,12 @@ static struct xfrm_policy * xfrm_migrate_policy_find(const struct xfrm_selector | |||
3041 | u8 dir, u8 type) | 3035 | u8 dir, u8 type) |
3042 | { | 3036 | { |
3043 | struct xfrm_policy *pol, *ret = NULL; | 3037 | struct xfrm_policy *pol, *ret = NULL; |
3044 | struct hlist_node *entry; | ||
3045 | struct hlist_head *chain; | 3038 | struct hlist_head *chain; |
3046 | u32 priority = ~0U; | 3039 | u32 priority = ~0U; |
3047 | 3040 | ||
3048 | read_lock_bh(&xfrm_policy_lock); | 3041 | read_lock_bh(&xfrm_policy_lock); |
3049 | chain = policy_hash_direct(&init_net, &sel->daddr, &sel->saddr, sel->family, dir); | 3042 | chain = policy_hash_direct(&init_net, &sel->daddr, &sel->saddr, sel->family, dir); |
3050 | hlist_for_each_entry(pol, entry, chain, bydst) { | 3043 | hlist_for_each_entry(pol, chain, bydst) { |
3051 | if (xfrm_migrate_selector_match(sel, &pol->selector) && | 3044 | if (xfrm_migrate_selector_match(sel, &pol->selector) && |
3052 | pol->type == type) { | 3045 | pol->type == type) { |
3053 | ret = pol; | 3046 | ret = pol; |
@@ -3056,7 +3049,7 @@ static struct xfrm_policy * xfrm_migrate_policy_find(const struct xfrm_selector | |||
3056 | } | 3049 | } |
3057 | } | 3050 | } |
3058 | chain = &init_net.xfrm.policy_inexact[dir]; | 3051 | chain = &init_net.xfrm.policy_inexact[dir]; |
3059 | hlist_for_each_entry(pol, entry, chain, bydst) { | 3052 | hlist_for_each_entry(pol, chain, bydst) { |
3060 | if (xfrm_migrate_selector_match(sel, &pol->selector) && | 3053 | if (xfrm_migrate_selector_match(sel, &pol->selector) && |
3061 | pol->type == type && | 3054 | pol->type == type && |
3062 | pol->priority < priority) { | 3055 | pol->priority < priority) { |