diff -Nur racoon2-20070817cvs/lib/if_pfkeyv2.c racoon2-patched/lib/if_pfkeyv2.c
--- racoon2-20070817cvs/lib/if_pfkeyv2.c	2007-08-17 10:57:42.000000000 +0900
+++ racoon2-patched/lib/if_pfkeyv2.c	2007-08-17 11:52:12.000000000 +0900
@@ -2272,6 +2272,16 @@
 
 	rc->seq = base->sadb_msg_seq;
 	rc->slid = xpl->sadb_x_policy_id;
+	
+	/* We need also the reqid for matching not-installed selectors */
+	rc->reqid = 0;
+	if (xpl->sadb_x_policy_len > 2)
+	{
+		struct sadb_x_ipsecrequest *xisr;
+		
+		xisr = (struct sadb_x_ipsecrequest *)(xpl + 1);
+		rc->reqid = xisr->sadb_x_ipsecrequest_reqid;
+	}
 
 	if (cb->cb_spdadd != 0 && cb->cb_spdadd(rc) < 0)
 		return -1;
diff -Nur racoon2-20070817cvs/spmd/spmd_pfkey.c racoon2-patched/spmd/spmd_pfkey.c
--- racoon2-20070817cvs/spmd/spmd_pfkey.c	2007-08-17 10:57:42.000000000 +0900
+++ racoon2-patched/spmd/spmd_pfkey.c	2007-08-17 11:52:12.000000000 +0900
@@ -141,11 +141,19 @@
 #else
 static int spid_data_add(uint32_t seq, const char *slid);
 #endif
+static int spid_data_add_complete(uint32_t spid, const char *slid);
 static int spid_data_del(struct spid_data *sd);
 static int spid_data_del_by_spid(int32_t spid);
 static int spid_data_dump(void);
 /*const struct spid_data *spid_data_top(void);*/
 
+
+/************************************************************************
+ * Handle SPD entries from other apps (e.g. mobile ipv6)
+ ************************************************************************/
+static int spmd_handle_external(struct rcpfk_msg *rc);
+
+
 /**********
            SUBSTANCE
 	            **********/
@@ -892,24 +900,31 @@
 static int 
 spmd_pfkey_spdadd_cb(struct rcpfk_msg *rc)
 {
-	if (spid_data_update(rc->seq, rc->slid)<0) { /* returned rc->slid is spid */
-		SPMD_PLOG(SPMD_L_INTERR, "Failed to update slid<->spid matching");
-		return -1;
-	}
 
+
+
+	if (spid_data_update(rc->seq, rc->slid)>=0) { /* returned rc->slid is spid */
 #ifdef SPMD_DEBUG
-	{
-		char *slid = NULL;
+		{
+			char *slid = NULL;
 
-		get_slid_by_spid(rc->slid, &slid); /* rc->slid is real spid */
-		if (slid) {
-			SPMD_PLOG(SPMD_L_DEBUG, "Updated: slid=%s, spid=%u", slid, rc->slid);
-			spmd_free(slid);
+			get_slid_by_spid(rc->slid, &slid); /* rc->slid is real spid */
+			if (slid) {
+				SPMD_PLOG(SPMD_L_DEBUG, "Updated: slid=%s, spid=%u", slid, rc->slid);
+				spmd_free(slid);
+			}
 		}
-	}
 #endif /* SPMD_DEBUG */
+		return 0;
+	}
+
+	/* Fallback if we have not found a valid spid_data entry yet. */
+	if (spmd_handle_external(rc) == 0)
+		return 0;
+
+	SPMD_PLOG(SPMD_L_INTERR, "Failed to update slid<->spid matching");
+	return -1;
 
-	return 0;
 }
 
 /*
@@ -1783,7 +1798,7 @@
 		return -1;
 	}
 	if (!sd) { /* NULL */
-		SPMD_PLOG(SPMD_L_INTERR, "Can't find spid entry, spid list is nothing");
+		SPMD_PLOG(SPMD_L_INTERR, "No spid_data entry with this sequence.");
 		return -1;
 	}
 
@@ -1934,6 +1949,50 @@
 }
 #endif /* NO_SPDUPDATE_BUG */
 
+/* Add a new entry in one-step, when we already have slid and spid. */
+static int
+spid_data_add_complete(uint32_t spid, const char *slid)
+{
+	struct spid_data *sd = NULL;
+	struct spid_data *td = NULL;
+	char *p = NULL;
+
+	if (!slid) {
+		SPMD_PLOG(SPMD_L_INTERR, "argument slid is NULL");
+		return -1;
+	}
+
+	sd = spmd_calloc(sizeof(struct spid_data));
+	if (!sd) {
+		SPMD_PLOG(SPMD_L_INTERR, "Out of memory");
+		return -1;
+	}
+
+	p = spmd_strdup(slid);
+	if (!p) {
+		SPMD_PLOG(SPMD_L_INTERR, "Out of memory");
+		spmd_free(sd);
+		return -1;
+	}
+
+	sd->seq = 0; /* No update needed afterwards */
+	sd->slid = p;
+	sd->spid = spid;
+
+	if (sd_top==NULL) {
+		sd_top = sd;
+	} else {
+		td = sd_top;
+		while (td->next) {
+			td = td->next;
+		}
+		td->next = sd;
+		sd->pre = td;
+	}
+
+	return 0;
+}
+
 /*
  * Delete an element from SPID<->SLID list 
  */
@@ -2059,3 +2118,63 @@
 	return sd_top;
 }
 
+
+/************************************************************************
+ * Handle SPD entries from other apps (e.g. mobile ipv6)
+ * Based on:
+ *  -> the policy in the configuration must have flag: install off;
+ *  -> the selector reqid must match sadb message reqid (!= 0).
+ * This is called on SPDADD messages (what about SPDUPDATE ?)
+ ************************************************************************/
+static int spmd_handle_external(struct rcpfk_msg *rc)
+{
+	struct rcf_selector *sl_head = NULL;
+	struct rcf_selector *sl = NULL;
+
+	/* We should have the reqid of the policy we are adding in rc. */
+	if (rc->reqid == 0)
+	{
+		SPMD_PLOG(SPMD_L_DEBUG, "spmd_handle_external: reqid=0, skipping.");
+		return -1;
+	}
+	
+	/* Ok now we need to find in the configuration if we have a selector that was not installed and with matching reqid. */
+	if (rcf_get_selectorlist(&sl_head) < 0) {
+		SPMD_PLOG(SPMD_L_INTERR, 
+			"Can't get Selector list in your configuration file");
+		return -1;
+	}
+
+	for (sl = sl_head;sl;sl=sl->next) {
+		
+		/* Ignore selectors without policies */
+		if (!sl->pl)
+			continue;
+		/* Ignore selectors with installed policies */
+		if (sl->pl->install == RCT_BOOL_ON)
+			continue;
+		
+		/* Try and match the reqid */
+		if (sl->reqid != rc->reqid)
+			continue;
+		
+		/* We have found a selector */
+		SPMD_PLOG(SPMD_L_DEBUG, "Found selector(=%.*s) suitable for the external policy.",
+			  sl->sl_index->l, sl->sl_index->v);
+		
+		if (spid_data_add_complete(rc->slid /* this is the spid */, rc_vmem2str(sl->sl_index)) < 0)
+		{
+			SPMD_PLOG(SPMD_L_INTERR, "Failed to create spid_data entry...");
+			return -1;
+		}
+		
+#ifdef SPMD_DEBUG
+		spid_data_dump();
+#endif /* SPMD_DEBUG */
+
+		return 0;
+	}
+
+	/* Not found suitable selector */
+	return -1;
+}
