Set of patches for Mobile IPv6 support
[Prev by ID] [Next by ID] [Prev by Thread] [Next by Thread] [Monthly ID Index] [Monthly Thread Index] [Top Index]
From: Sebastien Decugis
To: racoon2-users@xxx.xxx.xxx.xxx
Subject: Set of patches for Mobile IPv6 support
Date: Wed, 08 Aug 2007 17:38:58 +0900
Message-Id: <46B98122.1010507@hongo.wide.ad.jp>
X-Sequence: racoon2-users 248

Hello all,
Here is a set of patches that implement some fixes and features that are 
needed to use racoon2 as a key management daemon for establishing the SA 
between a Mobile Node and its Home Agent.
* rc2-fix_include_route_h/patch:
Racoon2 will not compile in my environment without this. Do other people 
have the same problem? I am configuring racoon2 with the 
--with-kernel-build-dir option.
* rc2-fix_transmit_response_addresses.patch:
Use the source/destination addresses from the IKE_SA to send 
CREATE_CHILD_SA answer message.
* rc2-support_external_spd_entries.patch:
This patch implements basic support for spmd to handle configuration 
directives for SPD entries installed by mip6d. To use this, one needs to 
configure an outbound selector with reqid set and the corresponding 
policy with install off flag. The same reqid must be used in mip6d 
configuration file. When the SPD policy is added to the kernel, spmd 
will create the spid_data matching between the spid and the selector id; 
which allow later iked to be able to acquire an SA for this policy.
* rc2-support_altcoa_in_SADB_X_EXT_PACKET.patch:
This patch fixes the racoon2 code that deals with BU packets in 
X_EXT_PACKET extension. We want to retrieve the CoA, not the HoA.
* rc2-support_asymetrical_TS_for_MH.patch:
This patch provides support for protecting two different selectors with 
the same SA pair. It is limited to MH messages yet. It allows to have a 
single pair of SA to protect (MN->HA) BU and (HA->MN) BA messages. The 
usage is as follow:
On MN:
selector bu_out {
        direction outbound;
        src (1);
        dst (2);
        policy_index (3);
        reqid (4)
        upper_layer_protocol "mh" 5 6;
}
On HA:
selector ba_out {
        direction outbound;
        src (2);
        dst (1);
        policy_index (3');
        reqid (4');
        upper_layer_protocol "mh" 6 5;
}
Where:
(1): MN Home Address.
(2): HA address.
(3) and (3'): Policies with install off; flag.
(4) and (4'): reqid must match value from mip6d.conf HomeRegBinding (for 
bu/ba traffic)
Note that with SPD entries that are not installed by smpd, we don't need 
an inbound selector.
Maybe the last patch could be implemented in a more general way, to 
allow for ICMP exchanges (for example) to be asymetrical as well. Anyway 
for the needs of MIPv6, this implementation is sufficient, and not 
intrusive for racoon2.
Please let me know if you have questions about these patches.
Best regards,
Sebastien.
Index: iked/ikev1/pfkey.c
===================================================================
RCS file: /anoncvs/racoon2/racoon2/iked/ikev1/pfkey.c,v
retrieving revision 1.12
diff -u -r1.12 pfkey.c
--- iked/ikev1/pfkey.c  24 Jul 2007 11:19:31 -0000      1.12
+++ iked/ikev1/pfkey.c  26 Jul 2007 02:55:43 -0000
@@ -59,7 +59,11 @@
 #include <sys/queue.h>
 #include <sys/sysctl.h>
 
-#include <net/route.h>
+#ifdef __linux__
+# include <linux/route.h>
+#else
+# include <net/route.h>
+#endif
 
 #include <netinet/in.h>
 #ifdef HAVE_NETINET6_IPSEC_H
Index: iked/ikev2.c
===================================================================
RCS file: /anoncvs/racoon2/racoon2/iked/ikev2.c,v
retrieving revision 1.205
diff -u -r1.205 ikev2.c
--- iked/ikev2.c        2 Aug 2007 10:50:56 -0000       1.205
+++ iked/ikev2.c        7 Aug 2007 09:19:54 -0000
@@ -2446,8 +2446,8 @@
        if (!pkt)
                goto fail;
 
-       if (ikev2_transmit_response(ike_sa, pkt, child_sa->local,
-                                   child_sa->remote) != 0)
+       if (ikev2_transmit_response(ike_sa, pkt, child_sa->parent->local,
+                                   child_sa->parent->remote) != 0)
                goto fail;
        pkt = 0;
 
@@ -3567,7 +3567,7 @@
        if (!pkt)
                goto fail;
 
-       if (ikev2_transmit_response(ike_sa, pkt, child_sa->local, child_sa->remote) != 0)
+       if (ikev2_transmit_response(ike_sa, pkt, child_sa->parent->local, child_sa->parent->remote) != 0)
                goto fail;
 
       done:
Index: lib/if_pfkeyv2.c
===================================================================
RCS file: /anoncvs/racoon2/racoon2/lib/if_pfkeyv2.c,v
retrieving revision 1.89
diff -u -r1.89 if_pfkeyv2.c
--- lib/if_pfkeyv2.c    25 Jul 2007 07:06:24 -0000      1.89
+++ lib/if_pfkeyv2.c    8 Aug 2007 06:24:55 -0000
@@ -1894,12 +1894,11 @@
        struct sadb_x_packet *pkt;
        struct ip6_hdr *ip;
        struct ip6_ext *ep;
-       struct ip6_opt *op;
-       struct ip6_opt_home_address *hao = NULL;
+       struct ip6_mh_opt_altcoa *altcoa=NULL;
        struct ip6_mh *mh = NULL;
        struct ip6_mh_binding_update *hrbu = NULL;
        struct sockaddr_in6 *src6;
-       int len, nxt, l;
+       int len, nxt, l=0;
 #endif
 
        /* ignore this message in the case of the local test mode. */
@@ -1959,19 +1958,18 @@
         * Decode the triggering packet for the case it is
         * a MIPv6 home registration binding update.
         */
-#define HRBU_MIN_LEN   (40 + 24 + 12)
        if (mhp[SADB_X_EXT_PACKET] == 0)
                goto skippa;
        pkt = (struct sadb_x_packet *)mhp[SADB_X_EXT_PACKET];
        ip = (struct ip6_hdr *)(pkt + 1);
        ep = (struct ip6_ext *)(ip + 1);
 
-       if (pkt->sadb_x_packet_copylen < HRBU_MIN_LEN)
+       if (pkt->sadb_x_packet_copylen < sizeof( struct ip6_hdr))
                goto skippa;
        if ((ip->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) 
                goto skippa;
 
-       /* chasing for HOA and HRBU */
+       /* chasing for HRBU */
 
        len = ntohs(ip->ip6_plen) + sizeof(*ip);
        if (len > pkt->sadb_x_packet_copylen)
@@ -1983,6 +1981,7 @@
                case IPPROTO_HOPOPTS:
                case IPPROTO_ROUTING:
                case IPPROTO_FRAGMENT:
+               case IPPROTO_DSTOPTS:
                        l = (ep->ip6e_len + 1) << 3;
                skip:
                        nxt = ep->ip6e_nxt;
@@ -2000,31 +1999,6 @@
                default:
                        goto skippa;
 
-               case IPPROTO_DSTOPTS:
-                       l = (ep->ip6e_len + 1) << 3;
-                       if (l > len)
-                               goto skippa;
-                       op = (struct ip6_opt *)(ep + 1);
-                       l -= sizeof(*ep);
-                       while (l > 0)
-                               switch (op->ip6o_type) {
-                               case IP6OPT_PAD1:
-                                       l -= 1;
-                                       op = (struct ip6_opt *)((caddr_t)op + 1);
-                                       break;
-
-                               case IP6OPT_HOME_ADDRESS:
-                                       hao = (struct ip6_opt_home_address *)op;
-                                       /* fall into */
-
-                               case IP6OPT_PADN:
-                               default:
-                                       l -= 2 + op->ip6o_len;
-                                       op = (struct ip6_opt *)((caddr_t)op + 2 + op->ip6o_len);
-                               }
-                       l = (ep->ip6e_len + 1) << 3;
-                       goto skip;
-
                case IPPROTO_MH:
                        l = (ep->ip6e_len + 1) << 3;
                        hrbu = (struct ip6_mh_binding_update *)ep;
@@ -2034,28 +2008,54 @@
                        if (mh->ip6mh_type != IP6_MH_TYPE_BU ||
                            (hrbu->ip6mhbu_flags & IP6_MH_BU_HOME) == 0) {
                                hrbu = NULL;
-                               goto skip;
+                               goto skippa;
                        }
+                       altcoa = (struct ip6_mh_opt_altcoa *)(hrbu + 1);
+                       
                        /* force exit */
                        len = 0;
                }
 
-       /* found? */
-
-       if (hao == NULL || hrbu == NULL)
-               goto skippa;
-       if (hao->ip6oh_len < 16)
+       /* found mobility header? */
+       if (! altcoa)
                goto skippa;
-
-       /* cache the right address to use in src2 */
-       rc->sa2_src = (struct sockaddr *)&rc->sa2_src_storage;
-       src6 = (struct sockaddr_in6 *)rc->sa2_src;
-       bzero(src6, sizeof(struct sockaddr_in6));
-       src6->sin6_family = AF_INET6;
-#ifdef HAVE_SA_LEN
-       src6->sin6_len = sizeof(*src6);
-#endif
-       memcpy(&src6->sin6_addr, hao->ip6oh_addr, sizeof(hao->ip6oh_addr));
+       
+       len = l - sizeof(*hrbu);
+       
+       /* Parse the MH options -- we are looking for ALTCOA */
+       while (len > 0)
+               switch (altcoa->ip6moa_type){
+               case IP6_MHOPT_PAD1:
+                       len -= 1;
+                       altcoa = (struct ip6_mh_opt_altcoa *)((caddr_t)altcoa + 1);
+                       break;
+
+               case IP6_MHOPT_PADN:
+                       len -= 2 + altcoa->ip6moa_len;
+                       altcoa = (struct ip6_mh_opt_altcoa *)((caddr_t)altcoa + 2 + altcoa->ip6moa_len);
+                       break;
+               
+               case IP6_MHOPT_ALTCOA:
+                       /* This is what we were looking for. We save CoA in sa2_src */
+                       if (len < sizeof (*altcoa))
+                               goto skippa;
+                       
+                       /* cache the right address to use in src2 */
+                       rc->sa2_src = (struct sockaddr *)&rc->sa2_src_storage;
+                       src6 = (struct sockaddr_in6 *)rc->sa2_src;
+                       bzero(src6, sizeof(struct sockaddr_in6));
+                       src6->sin6_family = AF_INET6;
+                       #ifdef HAVE_SA_LEN
+                       src6->sin6_len = sizeof(*src6);
+                       #endif
+
+                       memcpy(&src6->sin6_addr, &altcoa->ip6moa_addr, sizeof(altcoa->ip6moa_addr));
+                       goto skippa; /* we are done here */
+               
+               default:
+                       /* not implemented yet */
+                       goto skippa;
+               }
 
     skippa:
 #endif
Index: lib/mipv6aux.h
===================================================================
RCS file: /anoncvs/racoon2/racoon2/lib/mipv6aux.h,v
retrieving revision 1.2
diff -u -r1.2 mipv6aux.h
--- lib/mipv6aux.h      7 Jul 2006 11:13:14 -0000       1.2
+++ lib/mipv6aux.h      8 Aug 2007 06:24:55 -0000
@@ -103,6 +103,26 @@
        /* followed by mobility options */
 } __attribute__((__packed__));
 
-#define IP6_MH_BU_HOME         0x4000  /* home registration */
+/* ip6mhbu_flags */
+#if BYTE_ORDER == BIG_ENDIAN
+#define IP6_MH_BU_HOME         0x4000  /* Home Registration */
+#else                          /* BYTE_ORDER == LITTLE_ENDIAN */
+#define IP6_MH_BU_HOME         0x0040  /* Home Registration */
+#endif
+
+#define IP6_MHOPT_PAD1         0x00    /* PAD1 */
+#define IP6_MHOPT_PADN         0x01    /* PADN */
+#define IP6_MHOPT_BREFRESH     0x02    /* Binding Refresh */
+#define IP6_MHOPT_ALTCOA       0x03    /* Alternate COA */
+#define IP6_MHOPT_NONCEID      0x04    /* Nonce Index */
+#define IP6_MHOPT_BAUTH                0x05    /* Binding Auth Data */
+#define IP6_MHOPT_MOB_NET_PRFX 0x06    /* Mobile Network Prefix */
+
+struct ip6_mh_opt_altcoa {
+       uint8_t         ip6moa_type;
+       uint8_t         ip6moa_len;
+       struct in6_addr ip6moa_addr;            /* Alternate Care-of Address */
+} __attribute__ ((packed));
+
 
 #endif
Index: iked/ikev2_payload.c
===================================================================
RCS file: /anoncvs/racoon2/racoon2/iked/ikev2_payload.c,v
retrieving revision 1.31
diff -u -r1.31 ikev2_payload.c
--- iked/ikev2_payload.c        4 Jul 2007 11:54:47 -0000       1.31
+++ iked/ikev2_payload.c        8 Aug 2007 05:59:01 -0000
@@ -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;
Index: lib/cfsetup.c
===================================================================
RCS file: /anoncvs/racoon2/racoon2/lib/cfsetup.c,v
retrieving revision 1.97
diff -u -r1.97 cfsetup.c
--- lib/cfsetup.c       2 Aug 2007 10:50:56 -0000       1.97
+++ lib/cfsetup.c       8 Aug 2007 05:59:01 -0000
@@ -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",
Index: lib/if_pfkeyv2.c
===================================================================
RCS file: /anoncvs/racoon2/racoon2/lib/if_pfkeyv2.c,v
retrieving revision 1.89
diff -u -r1.89 if_pfkeyv2.c
--- lib/if_pfkeyv2.c    25 Jul 2007 07:06:24 -0000      1.89
+++ lib/if_pfkeyv2.c    8 Aug 2007 03:14:02 -0000
@@ -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;
Index: spmd/spmd_pfkey.c
===================================================================
RCS file: /anoncvs/racoon2/racoon2/spmd/spmd_pfkey.c,v
retrieving revision 1.81
diff -u -r1.81 spmd_pfkey.c
--- spmd/spmd_pfkey.c   25 Jul 2007 12:22:18 -0000      1.81
+++ spmd/spmd_pfkey.c   8 Aug 2007 03:14:02 -0000
@@ -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;
+}


Prev by ID: Re: Compilation errors
Next by ID: MIGRATE problem
Prev by Thread: Re: Compilation errors
Next by Thread: Re: Set of patches for Mobile IPv6 support
[Monthly ID Index] [Monthly Thread Index] [Top Index]