Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 34684
b: refs/heads/master
c: a1e59ab
h: refs/heads/master
v: v3
  • Loading branch information
Patrick McHardy authored and David S. Miller committed Sep 22, 2006
1 parent f18cc0c commit 45b0835
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 32 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1ef9696c909060ccdae3ade245ca88692b49285b
refs/heads/master: a1e59abf824969554b90facd44a4ab16e265afa4
13 changes: 13 additions & 0 deletions trunk/include/net/xfrm.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ struct xfrm_policy_afinfo {
struct dst_ops *dst_ops;
void (*garbage_collect)(void);
int (*dst_lookup)(struct xfrm_dst **dst, struct flowi *fl);
int (*get_saddr)(xfrm_address_t *saddr, xfrm_address_t *daddr);
struct dst_entry *(*find_bundle)(struct flowi *fl, struct xfrm_policy *policy);
int (*bundle_create)(struct xfrm_policy *policy,
struct xfrm_state **xfrm,
Expand Down Expand Up @@ -630,6 +631,18 @@ secpath_reset(struct sk_buff *skb)
#endif
}

static inline int
xfrm_addr_any(xfrm_address_t *addr, unsigned short family)
{
switch (family) {
case AF_INET:
return addr->a4 == 0;
case AF_INET6:
return ipv6_addr_any((struct in6_addr *)&addr->a6);
}
return 0;
}

static inline int
__xfrm4_state_addr_cmp(struct xfrm_tmpl *tmpl, struct xfrm_state *x)
{
Expand Down
20 changes: 20 additions & 0 deletions trunk/net/ipv4/xfrm4_policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,25 @@ static int xfrm4_dst_lookup(struct xfrm_dst **dst, struct flowi *fl)
return __ip_route_output_key((struct rtable**)dst, fl);
}

static int xfrm4_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr)
{
struct rtable *rt;
struct flowi fl_tunnel = {
.nl_u = {
.ip4_u = {
.daddr = daddr->a4,
},
},
};

if (!xfrm4_dst_lookup((struct xfrm_dst **)&rt, &fl_tunnel)) {
saddr->a4 = rt->rt_src;
dst_release(&rt->u.dst);
return 0;
}
return -EHOSTUNREACH;
}

static struct dst_entry *
__xfrm4_find_bundle(struct flowi *fl, struct xfrm_policy *policy)
{
Expand Down Expand Up @@ -298,6 +317,7 @@ static struct xfrm_policy_afinfo xfrm4_policy_afinfo = {
.family = AF_INET,
.dst_ops = &xfrm4_dst_ops,
.dst_lookup = xfrm4_dst_lookup,
.get_saddr = xfrm4_get_saddr,
.find_bundle = __xfrm4_find_bundle,
.bundle_create = __xfrm4_bundle_create,
.decode_session = _decode_session4,
Expand Down
15 changes: 0 additions & 15 deletions trunk/net/ipv4/xfrm4_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,21 +42,6 @@ __xfrm4_init_tempsel(struct xfrm_state *x, struct flowi *fl,
x->props.saddr = tmpl->saddr;
if (x->props.saddr.a4 == 0)
x->props.saddr.a4 = saddr->a4;
if (tmpl->mode == XFRM_MODE_TUNNEL && x->props.saddr.a4 == 0) {
struct rtable *rt;
struct flowi fl_tunnel = {
.nl_u = {
.ip4_u = {
.daddr = x->id.daddr.a4,
}
}
};
if (!xfrm_dst_lookup((struct xfrm_dst **)&rt,
&fl_tunnel, AF_INET)) {
x->props.saddr.a4 = rt->rt_src;
dst_release(&rt->u.dst);
}
}
x->props.mode = tmpl->mode;
x->props.reqid = tmpl->reqid;
x->props.family = AF_INET;
Expand Down
21 changes: 21 additions & 0 deletions trunk/net/ipv6/xfrm6_policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,26 @@ static int xfrm6_dst_lookup(struct xfrm_dst **dst, struct flowi *fl)
return err;
}

static int xfrm6_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr)
{
struct rt6_info *rt;
struct flowi fl_tunnel = {
.nl_u = {
.ip6_u = {
.daddr = *(struct in6_addr *)&daddr->a6,
},
},
};

if (!xfrm6_dst_lookup((struct xfrm_dst **)&rt, &fl_tunnel)) {
ipv6_get_saddr(&rt->u.dst, (struct in6_addr *)&daddr->a6,
(struct in6_addr *)&saddr->a6);
dst_release(&rt->u.dst);
return 0;
}
return -EHOSTUNREACH;
}

static struct dst_entry *
__xfrm6_find_bundle(struct flowi *fl, struct xfrm_policy *policy)
{
Expand Down Expand Up @@ -362,6 +382,7 @@ static struct xfrm_policy_afinfo xfrm6_policy_afinfo = {
.family = AF_INET6,
.dst_ops = &xfrm6_dst_ops,
.dst_lookup = xfrm6_dst_lookup,
.get_saddr = xfrm6_get_saddr,
.find_bundle = __xfrm6_find_bundle,
.bundle_create = __xfrm6_bundle_create,
.decode_session = _decode_session6,
Expand Down
16 changes: 0 additions & 16 deletions trunk/net/ipv6/xfrm6_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,6 @@ __xfrm6_init_tempsel(struct xfrm_state *x, struct flowi *fl,
memcpy(&x->props.saddr, &tmpl->saddr, sizeof(x->props.saddr));
if (ipv6_addr_any((struct in6_addr*)&x->props.saddr))
memcpy(&x->props.saddr, saddr, sizeof(x->props.saddr));
if (tmpl->mode == XFRM_MODE_TUNNEL && ipv6_addr_any((struct in6_addr*)&x->props.saddr)) {
struct rt6_info *rt;
struct flowi fl_tunnel = {
.nl_u = {
.ip6_u = {
.daddr = *(struct in6_addr *)daddr,
}
}
};
if (!xfrm_dst_lookup((struct xfrm_dst **)&rt,
&fl_tunnel, AF_INET6)) {
ipv6_get_saddr(&rt->u.dst, (struct in6_addr *)daddr,
(struct in6_addr *)&x->props.saddr);
dst_release(&rt->u.dst);
}
}
x->props.mode = tmpl->mode;
x->props.reqid = tmpl->reqid;
x->props.family = AF_INET6;
Expand Down
21 changes: 21 additions & 0 deletions trunk/net/xfrm/xfrm_policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -1107,6 +1107,20 @@ int __xfrm_sk_clone_policy(struct sock *sk)
return 0;
}

static int
xfrm_get_saddr(xfrm_address_t *local, xfrm_address_t *remote,
unsigned short family)
{
int err;
struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);

if (unlikely(afinfo == NULL))
return -EINVAL;
err = afinfo->get_saddr(local, remote);
xfrm_policy_put_afinfo(afinfo);
return err;
}

/* Resolve list of templates for the flow, given policy. */

static int
Expand All @@ -1118,6 +1132,7 @@ xfrm_tmpl_resolve_one(struct xfrm_policy *policy, struct flowi *fl,
int i, error;
xfrm_address_t *daddr = xfrm_flowi_daddr(fl, family);
xfrm_address_t *saddr = xfrm_flowi_saddr(fl, family);
xfrm_address_t tmp;

for (nx=0, i = 0; i < policy->xfrm_nr; i++) {
struct xfrm_state *x;
Expand All @@ -1128,6 +1143,12 @@ xfrm_tmpl_resolve_one(struct xfrm_policy *policy, struct flowi *fl,
if (tmpl->mode == XFRM_MODE_TUNNEL) {
remote = &tmpl->id.daddr;
local = &tmpl->saddr;
if (xfrm_addr_any(local, family)) {
error = xfrm_get_saddr(&tmp, remote, family);
if (error)
goto fail;
local = &tmp;
}
}

x = xfrm_state_find(remote, local, fl, tmpl, policy, &error, family);
Expand Down

0 comments on commit 45b0835

Please sign in to comment.