diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 1dd20cf17982663b8881f55c76440d7dd096d98d..3434fdc7de37db524c065b0a21ca1f2bcae953ab 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -282,6 +282,8 @@ struct xfrm_type
 	__u8			flags;
 #define XFRM_TYPE_NON_FRAGMENT	1
 #define XFRM_TYPE_REPLAY_PROT	2
+#define XFRM_TYPE_LOCAL_COADDR	4
+#define XFRM_TYPE_REMOTE_COADDR	8
 
 	int			(*init_state)(struct xfrm_state *x);
 	void			(*destructor)(struct xfrm_state *);
@@ -289,8 +291,6 @@ struct xfrm_type
 	int			(*output)(struct xfrm_state *, struct sk_buff *pskb);
 	int			(*reject)(struct xfrm_state *, struct sk_buff *, struct flowi *);
 	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_mtu)(struct xfrm_state *, int size);
 };
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c
index 7fd841d410190382fe5ea1c4b31df9ebada0f07f..edfd9cdd721c8b283ac55e2460ed4c85d12b7fcd 100644
--- a/net/ipv6/mip6.c
+++ b/net/ipv6/mip6.c
@@ -34,11 +34,6 @@
 #include <net/xfrm.h>
 #include <net/mip6.h>
 
-static xfrm_address_t *mip6_xfrm_addr(struct xfrm_state *x, xfrm_address_t *addr)
-{
-	return x->coaddr;
-}
-
 static inline unsigned int calc_padlen(unsigned int len, unsigned int n)
 {
 	return (n - len + 16) & 0x7;
@@ -337,14 +332,13 @@ static struct xfrm_type mip6_destopt_type =
 	.description	= "MIP6DESTOPT",
 	.owner		= THIS_MODULE,
 	.proto	     	= IPPROTO_DSTOPTS,
-	.flags		= XFRM_TYPE_NON_FRAGMENT,
+	.flags		= XFRM_TYPE_NON_FRAGMENT | XFRM_TYPE_LOCAL_COADDR,
 	.init_state	= mip6_destopt_init_state,
 	.destructor	= mip6_destopt_destroy,
 	.input		= mip6_destopt_input,
 	.output		= mip6_destopt_output,
 	.reject		= mip6_destopt_reject,
 	.hdr_offset	= mip6_destopt_offset,
-	.local_addr	= mip6_xfrm_addr,
 };
 
 static int mip6_rthdr_input(struct xfrm_state *x, struct sk_buff *skb)
@@ -467,13 +461,12 @@ static struct xfrm_type mip6_rthdr_type =
 	.description	= "MIP6RT",
 	.owner		= THIS_MODULE,
 	.proto	     	= IPPROTO_ROUTING,
-	.flags		= XFRM_TYPE_NON_FRAGMENT,
+	.flags		= XFRM_TYPE_NON_FRAGMENT | XFRM_TYPE_REMOTE_COADDR,
 	.init_state	= mip6_rthdr_init_state,
 	.destructor	= mip6_rthdr_destroy,
 	.input		= mip6_rthdr_input,
 	.output		= mip6_rthdr_output,
 	.hdr_offset	= mip6_rthdr_offset,
-	.remote_addr	= mip6_xfrm_addr,
 };
 
 static int __init mip6_init(void)
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 77dc3651437eb5d1761f6856dc7f17c41e412234..3b38e493d151c7048e21c29858deebf2dc1cba89 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -87,20 +87,16 @@ __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)
+static inline xfrm_address_t *__xfrm6_bundle_addr_remote(struct xfrm_state *x)
 {
-	return (x->type->remote_addr) ?
-		(struct in6_addr*)x->type->remote_addr(x, (xfrm_address_t *)addr) :
-		(struct in6_addr*)&x->id.daddr;
+	return (x->type->flags & XFRM_TYPE_REMOTE_COADDR) ? x->coaddr :
+							    &x->id.daddr;
 }
 
-static inline struct in6_addr*
-__xfrm6_bundle_addr_local(struct xfrm_state *x, struct in6_addr *addr)
+static inline xfrm_address_t *__xfrm6_bundle_addr_local(struct xfrm_state *x)
 {
-	return (x->type->local_addr) ?
-		(struct in6_addr*)x->type->local_addr(x, (xfrm_address_t *)addr) :
-		(struct in6_addr*)&x->props.saddr;
+	return (x->type->flags & XFRM_TYPE_LOCAL_COADDR) ? x->coaddr :
+							   &x->props.saddr;
 }
 
 /* Allocate chain of dst_entry's, attach known xfrm's, calculate
@@ -171,9 +167,9 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
 				fl_tunnel.fl4_src = xfrm[i]->props.saddr.a4;
 				break;
 			case AF_INET6:
-				ipv6_addr_copy(&fl_tunnel.fl6_dst, __xfrm6_bundle_addr_remote(xfrm[i], &fl->fl6_dst));
+				ipv6_addr_copy(&fl_tunnel.fl6_dst, (struct in6_addr *)__xfrm6_bundle_addr_remote(xfrm[i]));
 
-				ipv6_addr_copy(&fl_tunnel.fl6_src, __xfrm6_bundle_addr_local(xfrm[i], &fl->fl6_src));
+				ipv6_addr_copy(&fl_tunnel.fl6_src, (struct in6_addr *)__xfrm6_bundle_addr_local(xfrm[i]));
 				break;
 			default:
 				BUG_ON(1);