Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 99505a84 authored by Masahide NAKAMURA's avatar Masahide NAKAMURA Committed by David S. Miller
Browse files

[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: default avatarMasahide NAKAMURA <nakam@linux-ipv6.org>
Signed-off-by: default avatarYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9e51fd37
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -266,6 +266,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);
};
+18 −2
Original line number Diff line number Diff line
@@ -59,6 +59,22 @@ __xfrm6_find_bundle(struct flowi *fl, struct xfrm_policy *policy)
	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 *policy, struct xfrm_state **xfrm, int
		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;