]> err.no Git - linux-2.6/blobdiff - net/xfrm/xfrm_policy.c
[IPSEC]: Move flow construction into xfrm_dst_lookup
[linux-2.6] / net / xfrm / xfrm_policy.c
index 9a4cf2e45a15f2b10c94aaba287b1f534cc32989..085c19d4d1b7bb6c0b32ab7a26d9e5a4b3533468 100644 (file)
@@ -13,6 +13,7 @@
  *
  */
 
+#include <linux/err.h>
 #include <linux/slab.h>
 #include <linux/kmod.h>
 #include <linux/list.h>
@@ -84,21 +85,25 @@ int xfrm_selector_match(struct xfrm_selector *sel, struct flowi *fl,
        return 0;
 }
 
-int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl,
-                   unsigned short family)
+struct dst_entry *xfrm_dst_lookup(struct xfrm_state *x, int tos)
 {
-       struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
-       int err = 0;
+       xfrm_address_t *saddr = &x->props.saddr;
+       xfrm_address_t *daddr = &x->id.daddr;
+       struct xfrm_policy_afinfo *afinfo;
+       struct dst_entry *dst;
+
+       if (x->type->flags & XFRM_TYPE_LOCAL_COADDR)
+               saddr = x->coaddr;
+       if (x->type->flags & XFRM_TYPE_REMOTE_COADDR)
+               daddr = x->coaddr;
 
+       afinfo = xfrm_policy_get_afinfo(x->props.family);
        if (unlikely(afinfo == NULL))
-               return -EAFNOSUPPORT;
+               return ERR_PTR(-EAFNOSUPPORT);
 
-       if (likely(afinfo->dst_lookup != NULL))
-               err = afinfo->dst_lookup(dst, fl);
-       else
-               err = -EINVAL;
+       dst = afinfo->dst_lookup(tos, saddr, daddr);
        xfrm_policy_put_afinfo(afinfo);
-       return err;
+       return dst;
 }
 EXPORT_SYMBOL(xfrm_dst_lookup);
 
@@ -196,9 +201,8 @@ struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp)
                INIT_HLIST_NODE(&policy->byidx);
                rwlock_init(&policy->lock);
                atomic_set(&policy->refcnt, 1);
-               init_timer(&policy->timer);
-               policy->timer.data = (unsigned long)policy;
-               policy->timer.function = xfrm_policy_timer;
+               setup_timer(&policy->timer, xfrm_policy_timer,
+                               (unsigned long)policy);
        }
        return policy;
 }
@@ -1318,8 +1322,9 @@ restart:
 
        if (sk && sk->sk_policy[XFRM_POLICY_OUT]) {
                policy = xfrm_sk_policy_lookup(sk, XFRM_POLICY_OUT, fl);
+               err = PTR_ERR(policy);
                if (IS_ERR(policy))
-                       return PTR_ERR(policy);
+                       goto dropdst;
        }
 
        if (!policy) {
@@ -1330,8 +1335,9 @@ restart:
 
                policy = flow_cache_lookup(fl, dst_orig->ops->family,
                                           dir, xfrm_policy_lookup);
+               err = PTR_ERR(policy);
                if (IS_ERR(policy))
-                       return PTR_ERR(policy);
+                       goto dropdst;
        }
 
        if (!policy)
@@ -1501,8 +1507,9 @@ restart:
        return 0;
 
 error:
-       dst_release(dst_orig);
        xfrm_pols_put(pols, npols);
+dropdst:
+       dst_release(dst_orig);
        *dst_p = NULL;
        return err;
 }
@@ -2159,7 +2166,7 @@ xfrm_audit_policy_add(struct xfrm_policy *xp, int result, u32 auid, u32 sid)
 
        if (audit_enabled == 0)
                return;
-       audit_buf = xfrm_audit_start(sid, auid);
+       audit_buf = xfrm_audit_start(auid, sid);
        if (audit_buf == NULL)
                return;
        audit_log_format(audit_buf, " op=SPD-add res=%u", result);
@@ -2176,7 +2183,7 @@ xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, u32 auid, u32 sid)
 
        if (audit_enabled == 0)
                return;
-       audit_buf = xfrm_audit_start(sid, auid);
+       audit_buf = xfrm_audit_start(auid, sid);
        if (audit_buf == NULL)
                return;
        audit_log_format(audit_buf, " op=SPD-delete res=%u", result);