diff options
author | Baker Zhang <baker.kernel@gmail.com> | 2013-03-19 00:24:30 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-03-19 10:35:11 -0400 |
commit | b5fb82c48b5898c50a9cf75fc957911b56fe1dc5 (patch) | |
tree | 94061aef10d0da5f8b4eec7fab1b1ebb0293f026 /net/xfrm | |
parent | 6fed9592de7bd9c904ab476c3e264a18d1cf3598 (diff) |
xfrm: use xfrm direction when lookup policy
because xfrm policy direction has same value with corresponding
flow direction, so this problem is covered.
In xfrm_lookup and __xfrm_policy_check, flow_cache_lookup is used to
accelerate the lookup.
Flow direction is given to flow_cache_lookup by policy_to_flow_dir.
When the flow cache is mismatched, callback 'resolver' is called.
'resolver' requires xfrm direction,
so convert direction back to xfrm direction.
Signed-off-by: Baker Zhang <baker.zhang@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/xfrm')
-rw-r--r-- | net/xfrm/xfrm_policy.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 167c67d46c6a..23cea0f74336 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -1037,6 +1037,24 @@ __xfrm_policy_lookup(struct net *net, const struct flowi *fl, u16 family, u8 dir | |||
1037 | return xfrm_policy_lookup_bytype(net, XFRM_POLICY_TYPE_MAIN, fl, family, dir); | 1037 | return xfrm_policy_lookup_bytype(net, XFRM_POLICY_TYPE_MAIN, fl, family, dir); |
1038 | } | 1038 | } |
1039 | 1039 | ||
1040 | static int flow_to_policy_dir(int dir) | ||
1041 | { | ||
1042 | if (XFRM_POLICY_IN == FLOW_DIR_IN && | ||
1043 | XFRM_POLICY_OUT == FLOW_DIR_OUT && | ||
1044 | XFRM_POLICY_FWD == FLOW_DIR_FWD) | ||
1045 | return dir; | ||
1046 | |||
1047 | switch (dir) { | ||
1048 | default: | ||
1049 | case FLOW_DIR_IN: | ||
1050 | return XFRM_POLICY_IN; | ||
1051 | case FLOW_DIR_OUT: | ||
1052 | return XFRM_POLICY_OUT; | ||
1053 | case FLOW_DIR_FWD: | ||
1054 | return XFRM_POLICY_FWD; | ||
1055 | } | ||
1056 | } | ||
1057 | |||
1040 | static struct flow_cache_object * | 1058 | static struct flow_cache_object * |
1041 | xfrm_policy_lookup(struct net *net, const struct flowi *fl, u16 family, | 1059 | xfrm_policy_lookup(struct net *net, const struct flowi *fl, u16 family, |
1042 | u8 dir, struct flow_cache_object *old_obj, void *ctx) | 1060 | u8 dir, struct flow_cache_object *old_obj, void *ctx) |
@@ -1046,7 +1064,7 @@ xfrm_policy_lookup(struct net *net, const struct flowi *fl, u16 family, | |||
1046 | if (old_obj) | 1064 | if (old_obj) |
1047 | xfrm_pol_put(container_of(old_obj, struct xfrm_policy, flo)); | 1065 | xfrm_pol_put(container_of(old_obj, struct xfrm_policy, flo)); |
1048 | 1066 | ||
1049 | pol = __xfrm_policy_lookup(net, fl, family, dir); | 1067 | pol = __xfrm_policy_lookup(net, fl, family, flow_to_policy_dir(dir)); |
1050 | if (IS_ERR_OR_NULL(pol)) | 1068 | if (IS_ERR_OR_NULL(pol)) |
1051 | return ERR_CAST(pol); | 1069 | return ERR_CAST(pol); |
1052 | 1070 | ||
@@ -1932,7 +1950,8 @@ xfrm_bundle_lookup(struct net *net, const struct flowi *fl, u16 family, u8 dir, | |||
1932 | * previous cache entry */ | 1950 | * previous cache entry */ |
1933 | if (xdst == NULL) { | 1951 | if (xdst == NULL) { |
1934 | num_pols = 1; | 1952 | num_pols = 1; |
1935 | pols[0] = __xfrm_policy_lookup(net, fl, family, dir); | 1953 | pols[0] = __xfrm_policy_lookup(net, fl, family, |
1954 | flow_to_policy_dir(dir)); | ||
1936 | err = xfrm_expand_policies(fl, family, pols, | 1955 | err = xfrm_expand_policies(fl, family, pols, |
1937 | &num_pols, &num_xfrms); | 1956 | &num_pols, &num_xfrms); |
1938 | if (err < 0) | 1957 | if (err < 0) |