aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_policy.c
diff options
context:
space:
mode:
authorYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>2008-02-22 00:48:22 -0500
committerYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>2008-03-24 21:23:57 -0400
commit9bb182a7007515239091b237fe7169b1328a61d3 (patch)
tree7be7f556c58c650a547a0db34058f8ffffbf98aa /net/xfrm/xfrm_policy.c
parentdf8ea19b5d2e7512095bb1e0737513b8da196d64 (diff)
[XFRM] MIP6: Fix address keys for routing search.
Each MIPv6 XFRM state (DSTOPT/RH2) holds either destination or source address to be mangled in the IPv6 header (that is "CoA"). On Inter-MN communication after both nodes binds each other, they use route optimized traffic two MIPv6 states applied, and both source and destination address in the IPv6 header are replaced by the states respectively. The packet format is correct, however, next-hop routing search are not. This patch fixes it by remembering address pairs for later states. Based on patch from Masahide NAKAMURA <nakam@linux-ipv6.org>. Signed-off-by: Masahide NAKAMURA <nakam@linux-ipv6.org> Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Diffstat (limited to 'net/xfrm/xfrm_policy.c')
-rw-r--r--net/xfrm/xfrm_policy.c49
1 files changed, 40 insertions, 9 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index bae94a8031a2..8e588f20c60c 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -97,25 +97,52 @@ int xfrm_selector_match(struct xfrm_selector *sel, struct flowi *fl,
97 return 0; 97 return 0;
98} 98}
99 99
100static inline struct dst_entry *__xfrm_dst_lookup(int tos,
101 xfrm_address_t *saddr,
102 xfrm_address_t *daddr,
103 int family)
104{
105 struct xfrm_policy_afinfo *afinfo;
106 struct dst_entry *dst;
107
108 afinfo = xfrm_policy_get_afinfo(family);
109 if (unlikely(afinfo == NULL))
110 return ERR_PTR(-EAFNOSUPPORT);
111
112 dst = afinfo->dst_lookup(tos, saddr, daddr);
113
114 xfrm_policy_put_afinfo(afinfo);
115
116 return dst;
117}
118
100static inline struct dst_entry *xfrm_dst_lookup(struct xfrm_state *x, int tos, 119static inline struct dst_entry *xfrm_dst_lookup(struct xfrm_state *x, int tos,
120 xfrm_address_t *prev_saddr,
121 xfrm_address_t *prev_daddr,
101 int family) 122 int family)
102{ 123{
103 xfrm_address_t *saddr = &x->props.saddr; 124 xfrm_address_t *saddr = &x->props.saddr;
104 xfrm_address_t *daddr = &x->id.daddr; 125 xfrm_address_t *daddr = &x->id.daddr;
105 struct xfrm_policy_afinfo *afinfo;
106 struct dst_entry *dst; 126 struct dst_entry *dst;
107 127
108 if (x->type->flags & XFRM_TYPE_LOCAL_COADDR) 128 if (x->type->flags & XFRM_TYPE_LOCAL_COADDR) {
109 saddr = x->coaddr; 129 saddr = x->coaddr;
110 if (x->type->flags & XFRM_TYPE_REMOTE_COADDR) 130 daddr = prev_daddr;
131 }
132 if (x->type->flags & XFRM_TYPE_REMOTE_COADDR) {
133 saddr = prev_saddr;
111 daddr = x->coaddr; 134 daddr = x->coaddr;
135 }
112 136
113 afinfo = xfrm_policy_get_afinfo(family); 137 dst = __xfrm_dst_lookup(tos, saddr, daddr, family);
114 if (unlikely(afinfo == NULL)) 138
115 return ERR_PTR(-EAFNOSUPPORT); 139 if (!IS_ERR(dst)) {
140 if (prev_saddr != saddr)
141 memcpy(prev_saddr, saddr, sizeof(*prev_saddr));
142 if (prev_daddr != daddr)
143 memcpy(prev_daddr, daddr, sizeof(*prev_daddr));
144 }
116 145
117 dst = afinfo->dst_lookup(tos, saddr, daddr);
118 xfrm_policy_put_afinfo(afinfo);
119 return dst; 146 return dst;
120} 147}
121 148
@@ -1354,6 +1381,9 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy,
1354 int trailer_len = 0; 1381 int trailer_len = 0;
1355 int tos; 1382 int tos;
1356 int family = policy->selector.family; 1383 int family = policy->selector.family;
1384 xfrm_address_t saddr, daddr;
1385
1386 xfrm_flowi_addr_get(fl, &saddr, &daddr, family);
1357 1387
1358 tos = xfrm_get_tos(fl, family); 1388 tos = xfrm_get_tos(fl, family);
1359 err = tos; 1389 err = tos;
@@ -1384,7 +1414,8 @@ static struct dst_entry *xfrm_bundle_create(struct xfrm_policy *policy,
1384 1414
1385 if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) { 1415 if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
1386 family = xfrm[i]->props.family; 1416 family = xfrm[i]->props.family;
1387 dst = xfrm_dst_lookup(xfrm[i], tos, family); 1417 dst = xfrm_dst_lookup(xfrm[i], tos, &saddr, &daddr,
1418 family);
1388 err = PTR_ERR(dst); 1419 err = PTR_ERR(dst);
1389 if (IS_ERR(dst)) 1420 if (IS_ERR(dst))
1390 goto put_states; 1421 goto put_states;