diff -Nur racoon2-20070817cvs/iked/ikev2_payload.c racoon2-patched/iked/ikev2_payload.c
--- racoon2-20070817cvs/iked/ikev2_payload.c	2007-08-17 10:57:42.000000000 +0900
+++ racoon2-patched/iked/ikev2_payload.c	2007-08-17 11:52:12.000000000 +0900
@@ -783,15 +783,20 @@
 /*
  * encode special upper layer protocol selector into port
  */
+enum local_remote { 
+	LOCAL,
+	REMOTE
+};
 enum start_end { 
 	START,
 	END
 };
 
 static u_int32_t
-ulpsel2port(enum start_end which, struct rcf_selector *s)
+ulpsel2port(enum local_remote which_side, enum start_end which_port, struct rcf_selector *s)
 {
 	u_int32_t port;
+	struct rc_addrlist * al;
 
 	switch (s->upper_layer_protocol) {
 	case IPPROTO_ICMP:
@@ -807,14 +812,14 @@
 		 */
 		if (s->src->port != RC_PORT_ANY)
 			port = s->src->port << 8;
-		else if (which == START)
+		else if (which_port == START)
 			port = 0x0000;
 		else
 			port = 0xFF00;
 		port &= 0xff00;
 		if (s->dst->port != RC_PORT_ANY)
 			port |= s->dst->port & 0xff;
-		else if (which == START)
+		else if (which_port == START)
 			port |= 0x00;
 		else
 			port |= 0xFF;
@@ -828,9 +833,14 @@
 		 * the 16 bit local "port" selector during IKEv2
 		 * exchange.
 		 */
-		if (s->src->port != RC_PROTO_ANY)
-			port = s->src->port << 8;
-		else if (which == START)
+		if (which_side == LOCAL)
+			al = s->src;
+		else
+			al = s->dst;
+			
+		if (al->port != RC_PROTO_ANY)
+			port = al->port << 8;
+		else if (which_port == START)
 			port = 0x0000;
 		else
 			port = 0xFF00;
@@ -860,8 +870,8 @@
 	}
 
 	return ikev2_construct_ts(s->upper_layer_protocol,
-				  ulpsel2port(START, s),
-				  ulpsel2port(END, s),
+				  ulpsel2port(LOCAL, START, s),
+				  ulpsel2port(LOCAL, END, s),
 				  s->src);
 }
 
@@ -880,8 +890,8 @@
 	}
 
 	return ikev2_construct_ts(s->upper_layer_protocol,
-				  ulpsel2port(START, s),
-				  ulpsel2port(END, s),
+				  ulpsel2port(REMOTE, START, s),
+				  ulpsel2port(REMOTE, END, s),
 				  s->dst);
 }
 
@@ -1122,16 +1132,16 @@
 			case IPPROTO_ICMPV6:
 				if (sel->src->port != 0 ||
 				    sel->dst->port != 0) {
-					if (ulpsel2port(START, sel) != sport ||
-					    ulpsel2port(END, sel) != eport)
+					if (ulpsel2port(LOCAL, START, sel) != sport ||
+					    ulpsel2port(LOCAL, END, sel) != eport)
 						continue;
 				} else if (!IKEV2_TS_PORT_IS_ANY(sport, eport))
 					continue;
 				break;
 			case IPPROTO_MH:
 				if (sel->src->port != 0) {
-					if (ulpsel2port(START, sel) != sport ||
-					    ulpsel2port(END, sel) != eport)
+					if (ulpsel2port(LOCAL, START, sel) != sport ||
+					    ulpsel2port(LOCAL, END, sel) != eport)
 						continue;
 				} else if (!IKEV2_TS_PORT_IS_ANY(sport, eport))
 					continue;
@@ -1237,16 +1247,16 @@
 			case IPPROTO_ICMPV6:
 				if (sel->src->port != 0 ||
 				    sel->dst->port != 0) {
-					if (ulpsel2port(START, sel) != sport ||
-					    ulpsel2port(END, sel) != eport)
+					if (ulpsel2port(REMOTE, START, sel) != sport ||
+					    ulpsel2port(REMOTE, END, sel) != eport)
 						continue;
 				} else if (!IKEV2_TS_PORT_IS_ANY(sport, eport))
 					continue;
 				break;
 			case IPPROTO_MH:
 				if (sel->src->port != 0) {
-					if (ulpsel2port(START, sel) != sport ||
-					    ulpsel2port(END, sel) != eport)
+					if (ulpsel2port(REMOTE, START, sel) != sport ||
+					    ulpsel2port(REMOTE, END, sel) != eport)
 						continue;
 				} else if (!IKEV2_TS_PORT_IS_ANY(sport, eport))
 					continue;
diff -Nur racoon2-20070817cvs/lib/cfsetup.c racoon2-patched/lib/cfsetup.c
--- racoon2-20070817cvs/lib/cfsetup.c	2007-08-17 10:57:42.000000000 +0900
+++ racoon2-patched/lib/cfsetup.c	2007-08-17 11:52:12.000000000 +0900
@@ -1888,7 +1888,7 @@
 		if (n->type != CFT_NUMBER)
 			return -1;
 		for (al = dst->src; al; al = al->next)
-			al->port = n->d.num;
+			al->port = n->d.num; /* type */
 
 		n = n->nexts;
 		if (!n)
@@ -1896,7 +1896,7 @@
 		if (n->type != CFT_NUMBER)
 			return -1;
 		for (al = dst->dst; al; al = al->next)
-			al->port = n->d.num;
+			al->port = n->d.num; /* code */
 		break;
 	case IPPROTO_MH:
 		n = head->nextp->nexts;
@@ -1905,7 +1905,30 @@
 		if (n->type != CFT_NUMBER)
 			return -1;
 		for (al = dst->src; al; al = al->next)
+		{
+			al->port = n->d.num;
+			if (al->type == RCT_ADDR_INET)
+				rcs_setsaport(al->a.ipaddr, al->port << 8);
+		}
+			
+		/* We allow a second value for MH type. 
+		 * It is the type of reverse path messages. 
+		 * for example, valid configuration will be (for outbound selectors):
+		 * On MN: upper_layer_protocol "mh" 5 6; (5 = BU and 6 = BA)
+		 * On HA: upper_layer_protocol "mh" 6 5;
+		 */
+		n = n->nexts;
+		if (!n)
+			break;
+		if (n->type != CFT_NUMBER)
+			return -1;
+		for (al = dst->dst; al; al = al->next)
+		{
 			al->port = n->d.num;
+			if (al->type == RCT_ADDR_INET)
+				rcs_setsaport(al->a.ipaddr, al->port << 8);
+		}
+
 		if (n->nexts)
 			plog(PLOG_INTWARN, PLOGLOC, NULL,
 			     "spurious extra ulp parameter at %d in %s\n",
