aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_policy.c
diff options
context:
space:
mode:
authorVenkat Yekkirala <vyekkirala@TrustedCS.com>2006-07-25 02:29:07 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-09-22 17:53:24 -0400
commite0d1caa7b0d5f02e4f34aa09c695d04251310c6c (patch)
treebf023c17abf6813f2694ebf5fafff82edd6a1023 /net/xfrm/xfrm_policy.c
parentb6340fcd761acf9249b3acbc95c4dc555d9beb07 (diff)
[MLSXFRM]: Flow based matching of xfrm policy and state
This implements a seemless mechanism for xfrm policy selection and state matching based on the flow sid. This also includes the necessary SELinux enforcement pieces. Signed-off-by: Venkat Yekkirala <vyekkirala@TrustedCS.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/xfrm/xfrm_policy.c')
-rw-r--r--net/xfrm/xfrm_policy.c28
1 files changed, 15 insertions, 13 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 3da67ca2c3ce..79405daadc52 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -597,7 +597,7 @@ EXPORT_SYMBOL(xfrm_policy_walk);
597 597
598/* Find policy to apply to this flow. */ 598/* Find policy to apply to this flow. */
599 599
600static void xfrm_policy_lookup(struct flowi *fl, u32 sk_sid, u16 family, u8 dir, 600static void xfrm_policy_lookup(struct flowi *fl, u16 family, u8 dir,
601 void **objp, atomic_t **obj_refp) 601 void **objp, atomic_t **obj_refp)
602{ 602{
603 struct xfrm_policy *pol; 603 struct xfrm_policy *pol;
@@ -613,7 +613,7 @@ static void xfrm_policy_lookup(struct flowi *fl, u32 sk_sid, u16 family, u8 dir,
613 match = xfrm_selector_match(sel, fl, family); 613 match = xfrm_selector_match(sel, fl, family);
614 614
615 if (match) { 615 if (match) {
616 if (!security_xfrm_policy_lookup(pol, sk_sid, dir)) { 616 if (!security_xfrm_policy_lookup(pol, fl->secid, dir)) {
617 xfrm_pol_hold(pol); 617 xfrm_pol_hold(pol);
618 break; 618 break;
619 } 619 }
@@ -641,7 +641,7 @@ static inline int policy_to_flow_dir(int dir)
641 }; 641 };
642} 642}
643 643
644static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struct flowi *fl, u32 sk_sid) 644static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struct flowi *fl)
645{ 645{
646 struct xfrm_policy *pol; 646 struct xfrm_policy *pol;
647 647
@@ -652,7 +652,7 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struc
652 int err = 0; 652 int err = 0;
653 653
654 if (match) 654 if (match)
655 err = security_xfrm_policy_lookup(pol, sk_sid, policy_to_flow_dir(dir)); 655 err = security_xfrm_policy_lookup(pol, fl->secid, policy_to_flow_dir(dir));
656 656
657 if (match && !err) 657 if (match && !err)
658 xfrm_pol_hold(pol); 658 xfrm_pol_hold(pol);
@@ -862,19 +862,20 @@ int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
862 u32 genid; 862 u32 genid;
863 u16 family; 863 u16 family;
864 u8 dir = policy_to_flow_dir(XFRM_POLICY_OUT); 864 u8 dir = policy_to_flow_dir(XFRM_POLICY_OUT);
865 u32 sk_sid = security_sk_sid(sk, fl, dir); 865
866 fl->secid = security_sk_sid(sk, fl, dir);
866restart: 867restart:
867 genid = atomic_read(&flow_cache_genid); 868 genid = atomic_read(&flow_cache_genid);
868 policy = NULL; 869 policy = NULL;
869 if (sk && sk->sk_policy[1]) 870 if (sk && sk->sk_policy[1])
870 policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl, sk_sid); 871 policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl);
871 872
872 if (!policy) { 873 if (!policy) {
873 /* To accelerate a bit... */ 874 /* To accelerate a bit... */
874 if ((dst_orig->flags & DST_NOXFRM) || !xfrm_policy_list[XFRM_POLICY_OUT]) 875 if ((dst_orig->flags & DST_NOXFRM) || !xfrm_policy_list[XFRM_POLICY_OUT])
875 return 0; 876 return 0;
876 877
877 policy = flow_cache_lookup(fl, sk_sid, dst_orig->ops->family, 878 policy = flow_cache_lookup(fl, dst_orig->ops->family,
878 dir, xfrm_policy_lookup); 879 dir, xfrm_policy_lookup);
879 } 880 }
880 881
@@ -1032,13 +1033,15 @@ int
1032xfrm_decode_session(struct sk_buff *skb, struct flowi *fl, unsigned short family) 1033xfrm_decode_session(struct sk_buff *skb, struct flowi *fl, unsigned short family)
1033{ 1034{
1034 struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family); 1035 struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
1036 int err;
1035 1037
1036 if (unlikely(afinfo == NULL)) 1038 if (unlikely(afinfo == NULL))
1037 return -EAFNOSUPPORT; 1039 return -EAFNOSUPPORT;
1038 1040
1039 afinfo->decode_session(skb, fl); 1041 afinfo->decode_session(skb, fl);
1042 err = security_xfrm_decode_session(skb, fl);
1040 xfrm_policy_put_afinfo(afinfo); 1043 xfrm_policy_put_afinfo(afinfo);
1041 return 0; 1044 return err;
1042} 1045}
1043EXPORT_SYMBOL(xfrm_decode_session); 1046EXPORT_SYMBOL(xfrm_decode_session);
1044 1047
@@ -1058,14 +1061,11 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
1058 struct xfrm_policy *pol; 1061 struct xfrm_policy *pol;
1059 struct flowi fl; 1062 struct flowi fl;
1060 u8 fl_dir = policy_to_flow_dir(dir); 1063 u8 fl_dir = policy_to_flow_dir(dir);
1061 u32 sk_sid;
1062 1064
1063 if (xfrm_decode_session(skb, &fl, family) < 0) 1065 if (xfrm_decode_session(skb, &fl, family) < 0)
1064 return 0; 1066 return 0;
1065 nf_nat_decode_session(skb, &fl, family); 1067 nf_nat_decode_session(skb, &fl, family);
1066 1068
1067 sk_sid = security_sk_sid(sk, &fl, fl_dir);
1068
1069 /* First, check used SA against their selectors. */ 1069 /* First, check used SA against their selectors. */
1070 if (skb->sp) { 1070 if (skb->sp) {
1071 int i; 1071 int i;
@@ -1079,10 +1079,10 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
1079 1079
1080 pol = NULL; 1080 pol = NULL;
1081 if (sk && sk->sk_policy[dir]) 1081 if (sk && sk->sk_policy[dir])
1082 pol = xfrm_sk_policy_lookup(sk, dir, &fl, sk_sid); 1082 pol = xfrm_sk_policy_lookup(sk, dir, &fl);
1083 1083
1084 if (!pol) 1084 if (!pol)
1085 pol = flow_cache_lookup(&fl, sk_sid, family, fl_dir, 1085 pol = flow_cache_lookup(&fl, family, fl_dir,
1086 xfrm_policy_lookup); 1086 xfrm_policy_lookup);
1087 1087
1088 if (!pol) 1088 if (!pol)
@@ -1298,6 +1298,8 @@ int xfrm_bundle_ok(struct xfrm_dst *first, struct flowi *fl, int family)
1298 1298
1299 if (fl && !xfrm_selector_match(&dst->xfrm->sel, fl, family)) 1299 if (fl && !xfrm_selector_match(&dst->xfrm->sel, fl, family))
1300 return 0; 1300 return 0;
1301 if (fl && !security_xfrm_flow_state_match(fl, dst->xfrm))
1302 return 0;
1301 if (dst->xfrm->km.state != XFRM_STATE_VALID) 1303 if (dst->xfrm->km.state != XFRM_STATE_VALID)
1302 return 0; 1304 return 0;
1303 1305