diff options
author | Jamal Hadi Salim <hadi@cyberus.ca> | 2010-02-22 06:32:58 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-02-22 19:21:25 -0500 |
commit | 34f8d8846f69f3b5bc3916ba9145e4eebae9394e (patch) | |
tree | 99f778801ae5753e250deb0a69986912a529863e /net/xfrm | |
parent | 8ca2e93b557f2a0b35f7769038abf600177e1122 (diff) |
xfrm: SP lookups with mark
Allow mark to be used when doing SP lookup
Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/xfrm')
-rw-r--r-- | net/xfrm/xfrm_policy.c | 12 |
1 files changed, 11 insertions, 1 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index e67d3ca6e657..2a6e64652654 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -556,6 +556,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) | |||
556 | struct hlist_head *chain; | 556 | struct hlist_head *chain; |
557 | struct hlist_node *entry, *newpos; | 557 | struct hlist_node *entry, *newpos; |
558 | struct dst_entry *gc_list; | 558 | struct dst_entry *gc_list; |
559 | u32 mark = policy->mark.v & policy->mark.m; | ||
559 | 560 | ||
560 | write_lock_bh(&xfrm_policy_lock); | 561 | write_lock_bh(&xfrm_policy_lock); |
561 | chain = policy_hash_bysel(net, &policy->selector, policy->family, dir); | 562 | chain = policy_hash_bysel(net, &policy->selector, policy->family, dir); |
@@ -564,6 +565,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl) | |||
564 | hlist_for_each_entry(pol, entry, chain, bydst) { | 565 | hlist_for_each_entry(pol, entry, chain, bydst) { |
565 | if (pol->type == policy->type && | 566 | if (pol->type == policy->type && |
566 | !selector_cmp(&pol->selector, &policy->selector) && | 567 | !selector_cmp(&pol->selector, &policy->selector) && |
568 | (mark & pol->mark.m) == pol->mark.v && | ||
567 | xfrm_sec_ctx_match(pol->security, policy->security) && | 569 | xfrm_sec_ctx_match(pol->security, policy->security) && |
568 | !WARN_ON(delpol)) { | 570 | !WARN_ON(delpol)) { |
569 | if (excl) { | 571 | if (excl) { |
@@ -650,6 +652,7 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, u8 type, | |||
650 | ret = NULL; | 652 | ret = NULL; |
651 | hlist_for_each_entry(pol, entry, chain, bydst) { | 653 | hlist_for_each_entry(pol, entry, chain, bydst) { |
652 | if (pol->type == type && | 654 | if (pol->type == type && |
655 | (mark & pol->mark.m) == pol->mark.v && | ||
653 | !selector_cmp(sel, &pol->selector) && | 656 | !selector_cmp(sel, &pol->selector) && |
654 | xfrm_sec_ctx_match(ctx, pol->security)) { | 657 | xfrm_sec_ctx_match(ctx, pol->security)) { |
655 | xfrm_pol_hold(pol); | 658 | xfrm_pol_hold(pol); |
@@ -692,7 +695,8 @@ struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u8 type, | |||
692 | chain = net->xfrm.policy_byidx + idx_hash(net, id); | 695 | chain = net->xfrm.policy_byidx + idx_hash(net, id); |
693 | ret = NULL; | 696 | ret = NULL; |
694 | hlist_for_each_entry(pol, entry, chain, byidx) { | 697 | hlist_for_each_entry(pol, entry, chain, byidx) { |
695 | if (pol->type == type && pol->index == id) { | 698 | if (pol->type == type && pol->index == id && |
699 | (mark & pol->mark.m) == pol->mark.v) { | ||
696 | xfrm_pol_hold(pol); | 700 | xfrm_pol_hold(pol); |
697 | if (delete) { | 701 | if (delete) { |
698 | *err = security_xfrm_policy_delete( | 702 | *err = security_xfrm_policy_delete( |
@@ -916,6 +920,7 @@ static int xfrm_policy_match(struct xfrm_policy *pol, struct flowi *fl, | |||
916 | int match, ret = -ESRCH; | 920 | int match, ret = -ESRCH; |
917 | 921 | ||
918 | if (pol->family != family || | 922 | if (pol->family != family || |
923 | (fl->mark & pol->mark.m) != pol->mark.v || | ||
919 | pol->type != type) | 924 | pol->type != type) |
920 | return ret; | 925 | return ret; |
921 | 926 | ||
@@ -1040,6 +1045,10 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struc | |||
1040 | int err = 0; | 1045 | int err = 0; |
1041 | 1046 | ||
1042 | if (match) { | 1047 | if (match) { |
1048 | if ((sk->sk_mark & pol->mark.m) != pol->mark.v) { | ||
1049 | pol = NULL; | ||
1050 | goto out; | ||
1051 | } | ||
1043 | err = security_xfrm_policy_lookup(pol->security, | 1052 | err = security_xfrm_policy_lookup(pol->security, |
1044 | fl->secid, | 1053 | fl->secid, |
1045 | policy_to_flow_dir(dir)); | 1054 | policy_to_flow_dir(dir)); |
@@ -1052,6 +1061,7 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struc | |||
1052 | } else | 1061 | } else |
1053 | pol = NULL; | 1062 | pol = NULL; |
1054 | } | 1063 | } |
1064 | out: | ||
1055 | read_unlock_bh(&xfrm_policy_lock); | 1065 | read_unlock_bh(&xfrm_policy_lock); |
1056 | return pol; | 1066 | return pol; |
1057 | } | 1067 | } |