From: Masahide NAKAMURA <[EMAIL PROTECTED]>

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 <[EMAIL PROTECTED]>
Signed-off-by: YOSHIFUJI Hideaki <[EMAIL PROTECTED]>
---
 include/net/xfrm.h      |    2 ++
 net/ipv6/xfrm6_policy.c |   20 ++++++++++++++++++--
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 6d0dafb..cbfacdb 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -267,6 +267,8 @@ struct xfrm_type
        int                     (*input)(struct xfrm_state *, struct sk_buff 
*skb);
        int                     (*output)(struct xfrm_state *, struct sk_buff 
*pskb);
        int                     (*hdr_offset)(struct xfrm_state *, struct 
sk_buff *, u8 **);
+       xfrm_address_t          *(*local_addr)(struct xfrm_state *, 
xfrm_address_t *);
+       xfrm_address_t          *(*remote_addr)(struct xfrm_state *, 
xfrm_address_t *);
        /* Estimate maximal size of result of transformation of a dgram */
        u32                     (*get_max_size)(struct xfrm_state *, int size);
 };
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 81355bb..9328fc8 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -59,6 +59,22 @@ __xfrm6_find_bundle(struct flowi *fl, st
        return dst;
 }
 
+static inline struct in6_addr*
+__xfrm6_bundle_addr_remote(struct xfrm_state *x, struct in6_addr *addr)
+{
+       return (x->type->remote_addr) ?
+               (struct in6_addr*)x->type->remote_addr(x, (xfrm_address_t 
*)addr) :
+               (struct in6_addr*)&x->id.daddr;
+}
+
+static inline struct in6_addr*
+__xfrm6_bundle_addr_local(struct xfrm_state *x, struct in6_addr *addr)
+{
+       return (x->type->local_addr) ?
+               (struct in6_addr*)x->type->local_addr(x, (xfrm_address_t 
*)addr) :
+               (struct in6_addr*)&x->props.saddr;
+}
+
 /* Allocate chain of dst_entry's, attach known xfrm's, calculate
  * all the metrics... Shortly, bundle a bundle.
  */
@@ -115,8 +131,8 @@ __xfrm6_bundle_create(struct xfrm_policy
                dst1->next = dst_prev;
                dst_prev = dst1;
                if (xfrm[i]->props.mode != XFRM_MODE_TRANSPORT) {
-                       remote = (struct in6_addr*)&xfrm[i]->id.daddr;
-                       local  = (struct in6_addr*)&xfrm[i]->props.saddr;
+                       remote = __xfrm6_bundle_addr_remote(xfrm[i], remote);
+                       local  = __xfrm6_bundle_addr_local(xfrm[i], local);
                        tunnel = 1;
                }
                header_len += xfrm[i]->props.header_len;
-- 
1.4.0

-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to