Commit 910fe9cf authored by David S. Miller's avatar David S. Miller

[XFRM] make xfrm_lookup() fully af-independent.

Simplified from 2 patches by Hideaki YOSHIFUJI
<yoshfuji@linux-ipv6.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6c4b867b
......@@ -2206,22 +2206,27 @@ int __ip_route_output_key(struct rtable **rp, const struct flowi *flp)
return ip_route_output_slow(rp, flp);
}
int ip_route_output_key(struct rtable **rp, struct flowi *flp)
int ip_route_output_flow(struct rtable **rp, struct flowi *flp, struct sock *sk, int flags)
{
int err;
if ((err = __ip_route_output_key(rp, flp)) != 0)
return err;
return flp->proto ? xfrm_lookup((struct dst_entry**)rp, flp, NULL, 0) : 0;
if (flp->proto) {
if (!flp->fl4_src)
flp->fl4_src = (*rp)->rt_src;
if (!flp->fl4_dst)
flp->fl4_dst = (*rp)->rt_dst;
return xfrm_lookup((struct dst_entry **)rp, flp, sk, flags);
}
return 0;
}
int ip_route_output_flow(struct rtable **rp, struct flowi *flp, struct sock *sk, int flags)
int ip_route_output_key(struct rtable **rp, struct flowi *flp)
{
int err;
if ((err = __ip_route_output_key(rp, flp)) != 0)
return err;
return flp->proto ? xfrm_lookup((struct dst_entry**)rp, flp, sk, flags) : 0;
return ip_route_output_flow(rp, flp, NULL, 0);
}
static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
......
......@@ -711,25 +711,11 @@ int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
{
struct xfrm_policy *policy;
struct xfrm_state *xfrm[XFRM_MAX_DEPTH];
struct rtable *rt = (struct rtable*)*dst_p;
struct dst_entry *dst;
struct dst_entry *dst, *dst_orig = *dst_p;
int nx = 0;
int err;
u32 genid;
u16 family = (*dst_p)->ops->family;
switch (family) {
case AF_INET:
if (!fl->fl4_src)
fl->fl4_src = rt->rt_src;
if (!fl->fl4_dst)
fl->fl4_dst = rt->rt_dst;
case AF_INET6:
/* Still not clear... */
default:
/* nothing */;
}
u16 family = dst_orig->ops->family;
restart:
genid = atomic_read(&flow_cache_genid);
policy = NULL;
......@@ -738,7 +724,7 @@ int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
if (!policy) {
/* To accelerate a bit... */
if ((rt->u.dst.flags & DST_NOXFRM) || !xfrm_policy_list[XFRM_POLICY_OUT])
if ((dst_orig->flags & DST_NOXFRM) || !xfrm_policy_list[XFRM_POLICY_OUT])
return 0;
policy = flow_cache_lookup(fl, family,
......@@ -813,7 +799,7 @@ int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
return 0;
}
dst = &rt->u.dst;
dst = dst_orig;
err = xfrm_bundle_create(policy, xfrm, nx, fl, &dst, family);
if (unlikely(err)) {
......@@ -843,12 +829,12 @@ int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
write_unlock_bh(&policy->lock);
}
*dst_p = dst;
ip_rt_put(rt);
dst_release(dst_orig);
xfrm_pol_put(policy);
return 0;
error:
ip_rt_put(rt);
dst_release(dst_orig);
xfrm_pol_put(policy);
*dst_p = NULL;
return err;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment