xfrm: use xfrm direction when lookup policy
authorBaker Zhang <baker.kernel@gmail.com>
Tue, 19 Mar 2013 04:24:30 +0000 (04:24 +0000)
committerDavid S. Miller <davem@davemloft.net>
Tue, 19 Mar 2013 14:35:11 +0000 (10:35 -0400)
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>
net/xfrm/xfrm_policy.c

index 167c67d46c6a56a87baed9d3f6be17d137ffbe1a..23cea0f74336c72b332e909994e242d216e5e2ae 100644 (file)
@@ -1037,6 +1037,24 @@ __xfrm_policy_lookup(struct net *net, const struct flowi *fl, u16 family, u8 dir
        return xfrm_policy_lookup_bytype(net, XFRM_POLICY_TYPE_MAIN, fl, family, dir);
 }
 
+static int flow_to_policy_dir(int dir)
+{
+       if (XFRM_POLICY_IN == FLOW_DIR_IN &&
+           XFRM_POLICY_OUT == FLOW_DIR_OUT &&
+           XFRM_POLICY_FWD == FLOW_DIR_FWD)
+               return dir;
+
+       switch (dir) {
+       default:
+       case FLOW_DIR_IN:
+               return XFRM_POLICY_IN;
+       case FLOW_DIR_OUT:
+               return XFRM_POLICY_OUT;
+       case FLOW_DIR_FWD:
+               return XFRM_POLICY_FWD;
+       }
+}
+
 static struct flow_cache_object *
 xfrm_policy_lookup(struct net *net, const struct flowi *fl, u16 family,
                   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,
        if (old_obj)
                xfrm_pol_put(container_of(old_obj, struct xfrm_policy, flo));
 
-       pol = __xfrm_policy_lookup(net, fl, family, dir);
+       pol = __xfrm_policy_lookup(net, fl, family, flow_to_policy_dir(dir));
        if (IS_ERR_OR_NULL(pol))
                return ERR_CAST(pol);
 
@@ -1932,7 +1950,8 @@ xfrm_bundle_lookup(struct net *net, const struct flowi *fl, u16 family, u8 dir,
         * previous cache entry */
        if (xdst == NULL) {
                num_pols = 1;
-               pols[0] = __xfrm_policy_lookup(net, fl, family, dir);
+               pols[0] = __xfrm_policy_lookup(net, fl, family,
+                                              flow_to_policy_dir(dir));
                err = xfrm_expand_policies(fl, family, pols,
                                           &num_pols, &num_xfrms);
                if (err < 0)