aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMasahide NAKAMURA <nakam@linux-ipv6.org>2006-08-23 21:10:33 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-09-22 18:06:41 -0400
commit99505a843673faeae962a8cde128c7c034ba6b5e (patch)
treef12a7409b5981881e56fcf5ca973de0d5d6001bd
parent9e51fd371a022318c5b64b831c43026e89bc4f75 (diff)
[XFRM] STATE: Add a hook to obtain local/remote outbound address.
Outbound transformation replaces both source and destination address with state's end-point addresses at the same time when IPsec tunnel mode. It is also required to change them for Mobile IPv6 route optimization, but we should care about the following differences: - changing result is not end-point but care-of address - either source or destination is replaced for each state This hook is a common platform to change outbound address. Based on MIPL2 kernel patch. Signed-off-by: Masahide NAKAMURA <nakam@linux-ipv6.org> Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/xfrm.h2
-rw-r--r--net/ipv6/xfrm6_policy.c20
2 files changed, 20 insertions, 2 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 0d735a5aba61..aa3ac994477b 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -266,6 +266,8 @@ struct xfrm_type
266 int (*input)(struct xfrm_state *, struct sk_buff *skb); 266 int (*input)(struct xfrm_state *, struct sk_buff *skb);
267 int (*output)(struct xfrm_state *, struct sk_buff *pskb); 267 int (*output)(struct xfrm_state *, struct sk_buff *pskb);
268 int (*hdr_offset)(struct xfrm_state *, struct sk_buff *, u8 **); 268 int (*hdr_offset)(struct xfrm_state *, struct sk_buff *, u8 **);
269 xfrm_address_t *(*local_addr)(struct xfrm_state *, xfrm_address_t *);
270 xfrm_address_t *(*remote_addr)(struct xfrm_state *, xfrm_address_t *);
269 /* Estimate maximal size of result of transformation of a dgram */ 271 /* Estimate maximal size of result of transformation of a dgram */
270 u32 (*get_max_size)(struct xfrm_state *, int size); 272 u32 (*get_max_size)(struct xfrm_state *, int size);
271}; 273};
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 81355bb50328..9328fc88708a 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -59,6 +59,22 @@ __xfrm6_find_bundle(struct flowi *fl, struct xfrm_policy *policy)
59 return dst; 59 return dst;
60} 60}
61 61
62static inline struct in6_addr*
63__xfrm6_bundle_addr_remote(struct xfrm_state *x, struct in6_addr *addr)
64{
65 return (x->type->remote_addr) ?
66 (struct in6_addr*)x->type->remote_addr(x, (xfrm_address_t *)addr) :
67 (struct in6_addr*)&x->id.daddr;
68}
69
70static inline struct in6_addr*
71__xfrm6_bundle_addr_local(struct xfrm_state *x, struct in6_addr *addr)
72{
73 return (x->type->local_addr) ?
74 (struct in6_addr*)x->type->local_addr(x, (xfrm_address_t *)addr) :
75 (struct in6_addr*)&x->props.saddr;
76}
77
62/* Allocate chain of dst_entry's, attach known xfrm's, calculate 78/* Allocate chain of dst_entry's, attach known xfrm's, calculate
63 * all the metrics... Shortly, bundle a bundle. 79 * all the metrics... Shortly, bundle a bundle.
64 */ 80 */
@@ -115,8 +131,8 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
115 dst1->next = dst_prev; 131 dst1->next = dst_prev;
116 dst_prev = dst1; 132 dst_prev = dst1;
117 if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) { 133 if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
118 remote = (struct in6_addr*)&xfrm[i]->id.daddr; 134 remote = __xfrm6_bundle_addr_remote(xfrm[i], remote);
119 local = (struct in6_addr*)&xfrm[i]->props.saddr; 135 local = __xfrm6_bundle_addr_local(xfrm[i], local);
120 tunnel = 1; 136 tunnel = 1;
121 } 137 }
122 header_len += xfrm[i]->props.header_len; 138 header_len += xfrm[i]->props.header_len;