From 9794938c7bd835d948aaac9a81bd5fefd16b92db Mon Sep 17 00:00:00 2001
From: Shinta Sugimoto <shinta@sfc.wide.ad.jp>
Date: Sat, 24 Feb 2007 01:34:45 +0900
Subject: [KERNELIF] XFRM: Invoke trigger for flushing bundle in MH output.

Add xfrm_cn_policy_mh_out_touch() to mh_send() so that unnecessary
bundles could be flushed whenever MH messages is sent to the raw socket.
---
 src/mh.c   |   11 +++++++++++
 src/xfrm.c |   18 ++++++++++++++----
 src/xfrm.h |    2 ++
 3 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/src/mh.c b/src/mh.c
index 413d4f9..0e946fb 100644
--- a/src/mh.c
+++ b/src/mh.c
@@ -553,6 +553,17 @@ int mh_send(const struct in6_addr_bundle *addrs, const struct iovec *mh_vec,
 	mh = (struct ip6_mh *)iov[0].iov_base;
 	mh->ip6mh_hdrlen = (mh_length(iov, iov_count) >> 3) - 1;
 
+	/*
+	 * We use MH out policy for all address. Then we should update it
+	 * to refresh its bundle in kernel to be used with correct
+	 * route, IPsec SA and neighbor cache entry for the destination.
+	 * IKE daemon does the same thing for rekeying process.
+	 */
+        if (xfrm_cn_policy_mh_out_touch(1) < 0) {
+                MDBG("MH out policy touch failed: BA for "
+                     "%x:%x:%x:%x:%x:%x:%x:%x\n", NIP6ADDR(addrs->dst));
+        }
+
 	MDBG("sending MH type %d\n"
 	     "from %x:%x:%x:%x:%x:%x:%x:%x\n"
 	     "to %x:%x:%x:%x:%x:%x:%x:%x\n",
diff --git a/src/xfrm.c b/src/xfrm.c
index a29917b..4309090 100644
--- a/src/xfrm.c
+++ b/src/xfrm.c
@@ -904,6 +904,19 @@ static void xfrm_ha_cleanup(void)
 		ha_mn_ipsec_cleanup();
 }
 
+int xfrm_cn_policy_mh_out_touch(int update)
+{
+	struct xfrm_selector sel;
+
+	/* policy to not add rth type 2 to MH msgs */
+	set_selector(&in6addr_any, &in6addr_any, IPPROTO_MH, 0, 0, 0, &sel);
+	if (xfrm_mip_policy_add(&sel, update, XFRM_POLICY_OUT,
+				XFRM_POLICY_ALLOW, MIP6_PRIO_NO_RO_SIG_ANY,
+				NULL, 0) < 0)
+		return -1;
+	return 0;
+}
+
 /* Create or clean up initial xfrm policies and states for CN */
 static int xfrm_cn_init(void)
 {
@@ -921,10 +934,7 @@ static int xfrm_cn_init(void)
 			   &in6addr_any, 0, XFRM_STATE_WILDRECV) < 0)
 		return -1;
 
-	/* policy to not add rth type 2 to MH msgs */
-	set_selector(&in6addr_any, &in6addr_any, IPPROTO_MH, 0, 0, 0, &sel);
-	if (xfrm_mip_policy_add(&sel, 0, XFRM_POLICY_OUT, XFRM_POLICY_ALLOW,
-				MIP6_PRIO_NO_RO_SIG_ANY, NULL, 0) < 0)
+	if (xfrm_cn_policy_mh_out_touch(0) < 0)
 		return -1;
 
 	/* Let Neighbor Solicitation messages bypass bindings */
diff --git a/src/xfrm.h b/src/xfrm.h
index dabf630..1271c41 100644
--- a/src/xfrm.h
+++ b/src/xfrm.h
@@ -75,6 +75,8 @@ int mn_ipsec_recv_bu_tnl_pol_add(struct bulentry *bule, int ifindex,
 void mn_ipsec_recv_bu_tnl_pol_del(struct bulentry *bule, int ifindex,
 				  struct ipsec_policy_entry *e);
 
+int xfrm_cn_policy_mh_out_touch(int update);
+
 int cn_wildrecv_bu_pol_add(void);
 void cn_wildrecv_bu_pol_del(void);
 
-- 
1.5.0.3

