From ba7a48af9f538f6b5ebd8c8039a5a92804236587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Fri, 4 Mar 2011 13:57:21 +0200 Subject: main/ipsec-tools: update to 0.8.0 RC, and include additional patches * improve handling of setups where single node participates to multiple dmvpn networks. enable using of grekey in setkey, SPD and sainfo; also match remoteconfs using sainfo ph1id --- main/ipsec-tools/20-grekey-support.patch | 608 +++++++++++++++++++++++++++++++ 1 file changed, 608 insertions(+) create mode 100644 main/ipsec-tools/20-grekey-support.patch (limited to 'main/ipsec-tools/20-grekey-support.patch') diff --git a/main/ipsec-tools/20-grekey-support.patch b/main/ipsec-tools/20-grekey-support.patch new file mode 100644 index 0000000000..9ad2bca740 --- /dev/null +++ b/main/ipsec-tools/20-grekey-support.patch @@ -0,0 +1,608 @@ +Index: ipsec-tools-cvs-HEAD/src/racoon/racoonctl.c +=================================================================== +--- ipsec-tools-cvs-HEAD.orig/src/racoon/racoonctl.c 2011-03-03 19:28:29.000000000 +0200 ++++ ipsec-tools-cvs-HEAD/src/racoon/racoonctl.c 2011-03-03 19:29:42.000000000 +0200 +@@ -232,7 +232,7 @@ + "\n" + " : \"isakmp\" \n" + " : {\"esp\",\"ah\"} \n" +-" \n" ++" [grekey ]\n" + " : \"inet\" or \"inet6\"\n" + " : \"icmp\", \"tcp\", \"udp\", \"gre\" or \"any\"\n" + "\n", +@@ -819,7 +819,7 @@ + { + int family; + +- if (ac != 3 && ac != 4) { ++ if (ac < 3) { + errno = EINVAL; + return NULL; + } +@@ -861,10 +861,8 @@ + struct sockaddr *src = NULL, *dst = NULL; + int ulproto; + +- if (ac != 2 && ac != 3) { +- errno = EINVAL; +- return NULL; +- } ++ if (ac < 2) ++ goto bad_args; + + if (get_comindex(*av, &p_name, &p_port, &p_prefs) == -1) + goto bad; +@@ -901,13 +899,34 @@ + + av++; + ac--; +- if(ac){ ++ if (ac) { + ulproto = get_ulproto(*av); + if (ulproto == -1) + goto bad; +- }else ++ av++; ++ ac--; ++ } else + ulproto=0; + ++ if (ac == 2 && strcmp(av[0], "grekey") == 0) { ++ int a, b, c, d; ++ unsigned long u; ++ ++ if (sscanf(av[1], "%d.%d.%d.%d", &a, &b, &c, &d) == 4) { ++ set_port(src, (a << 8) + b); ++ set_port(dst, (c << 8) + d); ++ } else if (sscanf(av[1], "%lu", &u) == 1) { ++ set_port(src, u >> 16); ++ set_port(dst, u & 0xffff); ++ } else ++ goto bad_args; ++ av += 2; ++ ac -= 2; ++ } ++ ++ if (ac != 0) ++ goto bad_args; ++ + ci = (struct admin_com_indexes *)buf->v; + if(p_prefs) + ci->prefs = (u_int8_t)atoi(p_prefs); /* XXX should be handled error. */ +@@ -926,7 +945,9 @@ + + return buf; + +- bad: ++bad_args: ++ errno = EINVAL; ++bad: + if (p_name) + racoon_free(p_name); + if (p_port) +Index: ipsec-tools-cvs-HEAD/src/racoon/admin.c +=================================================================== +--- ipsec-tools-cvs-HEAD.orig/src/racoon/admin.c 2011-03-03 19:28:29.000000000 +0200 ++++ ipsec-tools-cvs-HEAD/src/racoon/admin.c 2011-03-03 21:16:47.000000000 +0200 +@@ -444,7 +444,7 @@ + + /* search appropreate configuration */ + if (name == NULL) +- rmconf = getrmconf(dst, 0); ++ rmconf = getrmconf(dst, 0, 0); + else + rmconf = getrmconf_by_name(name); + if (rmconf == NULL) { +@@ -536,6 +536,16 @@ + spidx.prefs = ndx->prefd; + spidx.prefd = ndx->prefs; + spidx.ul_proto = ndx->ul_proto; ++ switch (ndx->ul_proto) { ++ case IPPROTO_ICMP: ++ case IPPROTO_ICMPV6: ++ case IPPROTO_GRE: ++ /* Ports are UL specific data, and should ++ * not get swapped */ ++ set_port((struct sockaddr *) &spidx.src, extract_port(src)); ++ set_port((struct sockaddr *) &spidx.dst, extract_port(dst)); ++ break; ++ } + + sp_in = getsp_r(&spidx); + if (sp_in) { +Index: ipsec-tools-cvs-HEAD/src/racoon/cftoken.l +=================================================================== +--- ipsec-tools-cvs-HEAD.orig/src/racoon/cftoken.l 2011-03-03 19:57:26.000000000 +0200 ++++ ipsec-tools-cvs-HEAD/src/racoon/cftoken.l 2011-03-04 13:07:03.000000000 +0200 +@@ -288,6 +288,7 @@ + any { YYD; return(ANY); } + from { YYD; return(FROM); } + group { YYD; return(GROUP); } ++grekey { YYD; return(GREKEY); } + /* sainfo spec */ + {bcl} { BEGIN S_SAINFS; return(BOC); } + {semi} { BEGIN S_INI; return(EOS); } +Index: ipsec-tools-cvs-HEAD/src/racoon/cfparse.y +=================================================================== +--- ipsec-tools-cvs-HEAD.orig/src/racoon/cfparse.y 2011-03-03 19:57:30.000000000 +0200 ++++ ipsec-tools-cvs-HEAD/src/racoon/cfparse.y 2011-03-04 13:09:01.000000000 +0200 +@@ -213,7 +213,7 @@ + /* algorithm */ + %token ALGORITHM_CLASS ALGORITHMTYPE STRENGTHTYPE + /* sainfo */ +-%token SAINFO FROM ++%token SAINFO FROM GREKEY + /* remote */ + %token REMOTE ANONYMOUS CLIENTADDR INHERIT REMOTE_ADDRESS + %token EXCHANGE_MODE EXCHANGETYPE DOI DOITYPE SITUATION SITUATIONTYPE +@@ -1301,6 +1301,35 @@ + cur_sainfo->idsrc = $1; + cur_sainfo->iddst = $2; + } ++ | sainfo_id sainfo_id GREKEY ADDRSTRING ++ { ++ int a, b, c, d; ++ ++ if (sscanf($4->v, "%d.%d.%d.%d", &a, &b, &c, &d) == 4) { ++ a = ipsecdoi_fixup_id_uldata( ++ $1, $2, IPPROTO_GRE, ++ (a << 8) + b, (c << 8) + d); ++ } else { ++ yyerror("grekey format unrecognized."); ++ return -1; ++ } ++ if (a != 0) { ++ yyerror("ul_proto needs to be 'gre' to use grekey."); ++ return -1; ++ } ++ cur_sainfo->idsrc = $1; ++ cur_sainfo->iddst = $2; ++ } ++ | sainfo_id sainfo_id GREKEY NUMBER ++ { ++ if (ipsecdoi_fixup_id_uldata($1, $2, IPPROTO_GRE, ++ ($4) >> 16, ($4) & 0xffff) != 0) { ++ yyerror("ul_proto needs to be 'gre' to use grekey."); ++ return -1; ++ } ++ cur_sainfo->idsrc = $1; ++ cur_sainfo->iddst = $2; ++ } + ; + sainfo_id + : IDENTIFIERTYPE ADDRSTRING prefix port ul_proto +@@ -1667,7 +1696,7 @@ + { + struct remoteconf *from, *new; + +- from = getrmconf($4, GETRMCONF_F_NO_ANONYMOUS); ++ from = getrmconf($4, GETRMCONF_F_NO_ANONYMOUS, 0); + if (from == NULL) { + yyerror("failed to get remoteconf for %s.", + saddr2str($4)); +Index: ipsec-tools-cvs-HEAD/src/racoon/ipsec_doi.h +=================================================================== +--- ipsec-tools-cvs-HEAD.orig/src/racoon/ipsec_doi.h 2011-03-03 20:19:23.000000000 +0200 ++++ ipsec-tools-cvs-HEAD/src/racoon/ipsec_doi.h 2011-03-03 20:42:35.000000000 +0200 +@@ -227,6 +227,9 @@ + extern int set_identifier_qual __P((vchar_t **, int, vchar_t *, int)); + extern int ipsecdoi_setid2 __P((struct ph2handle *)); + extern vchar_t *ipsecdoi_sockaddr2id __P((struct sockaddr *, u_int, u_int)); ++extern int ipsecdoi_fixup_id_uldata __P((vchar_t *, vchar_t *, u_int16_t, u_int16_t, u_int16_t)); ++extern int ipsecdoi_id_has_port __P((vchar_t *)); ++ + extern int ipsecdoi_id2sockaddr __P((vchar_t *, struct sockaddr *, + u_int8_t *, u_int16_t *)); + extern char *ipsecdoi_id2str __P((const vchar_t *)); +Index: ipsec-tools-cvs-HEAD/src/racoon/ipsec_doi.c +=================================================================== +--- ipsec-tools-cvs-HEAD.orig/src/racoon/ipsec_doi.c 2011-03-03 20:19:23.000000000 +0200 ++++ ipsec-tools-cvs-HEAD/src/racoon/ipsec_doi.c 2011-03-03 21:01:16.000000000 +0200 +@@ -3371,6 +3371,7 @@ + vchar_t ident_t; + vchar_t ident_s; + int result; ++ int check_ports = 0; + + /* handle wildcard IDs */ + +@@ -3460,6 +3461,7 @@ + + case IPSECDOI_ID_IPV4_ADDR: + /* validate lengths */ ++ check_ports = 1; + if ((ident_t.l != sizeof(struct in_addr))|| + (ident_s.l != sizeof(struct in_addr))) + goto cmpid_invalid; +@@ -3468,6 +3470,7 @@ + case IPSECDOI_ID_IPV4_ADDR_SUBNET: + case IPSECDOI_ID_IPV4_ADDR_RANGE: + /* validate lengths */ ++ check_ports = 1; + if ((ident_t.l != (sizeof(struct in_addr)*2))|| + (ident_s.l != (sizeof(struct in_addr)*2))) + goto cmpid_invalid; +@@ -3476,6 +3479,7 @@ + #ifdef INET6 + case IPSECDOI_ID_IPV6_ADDR: + /* validate lengths */ ++ check_ports = 1; + if ((ident_t.l != sizeof(struct in6_addr))|| + (ident_s.l != sizeof(struct in6_addr))) + goto cmpid_invalid; +@@ -3484,6 +3488,7 @@ + case IPSECDOI_ID_IPV6_ADDR_SUBNET: + case IPSECDOI_ID_IPV6_ADDR_RANGE: + /* validate lengths */ ++ check_ports = 1; + if ((ident_t.l != (sizeof(struct in6_addr)*2))|| + (ident_s.l != (sizeof(struct in6_addr)*2))) + goto cmpid_invalid; +@@ -3502,10 +3507,15 @@ + } + + /* validate matching data and length */ +- if (ident_t.l == ident_s.l) +- result = memcmp(ident_t.v,ident_s.v,ident_t.l); +- else ++ if (check_ports && ++ (id_bt->port != id_bs->port && id_bs->port != 0)) ++ /* if target is wildcard, source should be too, otherwise ++ * specific rule matches wildcard request */ + result = 1; ++ else if (ident_t.l != ident_s.l) ++ result = 1; ++ else ++ result = memcmp(ident_t.v,ident_s.v,ident_t.l); + + cmpid_result: + +@@ -4089,6 +4099,44 @@ + return new; + } + ++int ipsecdoi_fixup_id_uldata(srcid, dstid, ul_proto, ul_data1, ul_data2) ++ vchar_t *srcid, *dstid; ++ u_int16_t ul_proto; ++ u_int16_t ul_data1, ul_data2; ++{ ++ struct ipsecdoi_id_b *src = (struct ipsecdoi_id_b *) srcid->v; ++ struct ipsecdoi_id_b *dst = (struct ipsecdoi_id_b *) dstid->v; ++ ++ if (src->proto_id != ul_proto || ++ dst->proto_id != ul_proto) ++ return -1; ++ ++ src->port = htons(ul_data1); ++ dst->port = htons(ul_data2); ++ ++ return 0; ++} ++ ++int ipsecdoi_id_has_port(id) ++ vchar_t *id; ++{ ++ struct ipsecdoi_id_b *id_b = (struct ipsecdoi_id_b *) id->v; ++ ++ switch (id_b->type) { ++ case IPSECDOI_ID_IPV4_ADDR: ++ case IPSECDOI_ID_IPV4_ADDR_SUBNET: ++ case IPSECDOI_ID_IPV4_ADDR_RANGE: ++ case IPSECDOI_ID_IPV6_ADDR: ++ case IPSECDOI_ID_IPV6_ADDR_SUBNET: ++ case IPSECDOI_ID_IPV6_ADDR_RANGE: ++ if (ntohs(id_b->port) != 0) ++ return 1; ++ break; ++ } ++ return 0; ++} ++ ++ + vchar_t * + ipsecdoi_sockrange2id(laddr, haddr, ul_proto) + struct sockaddr *laddr, *haddr; +@@ -4318,7 +4366,7 @@ + saddr.sa.sa_len = sizeof(struct sockaddr_in); + #endif + saddr.sa.sa_family = AF_INET; +- saddr.sin.sin_port = IPSEC_PORT_ANY; ++ saddr.sin.sin_port = id_b->port; + memcpy(&saddr.sin.sin_addr, + id->v + sizeof(*id_b), sizeof(struct in_addr)); + break; +@@ -4331,7 +4379,7 @@ + saddr.sa.sa_len = sizeof(struct sockaddr_in6); + #endif + saddr.sa.sa_family = AF_INET6; +- saddr.sin6.sin6_port = IPSEC_PORT_ANY; ++ saddr.sin6.sin6_port = id_b->port; + memcpy(&saddr.sin6.sin6_addr, + id->v + sizeof(*id_b), sizeof(struct in6_addr)); + saddr.sin6.sin6_scope_id = +@@ -4347,7 +4395,7 @@ + #ifdef INET6 + case IPSECDOI_ID_IPV6_ADDR: + #endif +- len = snprintf( buf, BUFLEN, "%s", saddrwop2str(&saddr.sa)); ++ len = snprintf( buf, BUFLEN, "%s", saddr2str(&saddr.sa)); + break; + + case IPSECDOI_ID_IPV4_ADDR_SUBNET: +@@ -4403,7 +4451,9 @@ + plen += l; + } + +- len = snprintf( buf, BUFLEN, "%s/%i", saddrwop2str(&saddr.sa), plen); ++ len = snprintf(buf, BUFLEN, "%s/%i[%d]", ++ saddrwop2str(&saddr.sa), plen, ++ ntohs(id_b->port)); + } + break; + +@@ -4415,12 +4465,12 @@ + saddr.sa.sa_len = sizeof(struct sockaddr_in); + #endif + saddr.sa.sa_family = AF_INET; +- saddr.sin.sin_port = IPSEC_PORT_ANY; ++ saddr.sin.sin_port = id_b->port; + memcpy(&saddr.sin.sin_addr, + id->v + sizeof(*id_b) + sizeof(struct in_addr), + sizeof(struct in_addr)); + +- len += snprintf(buf + len, BUFLEN - len, "%s", saddrwop2str(&saddr.sa)); ++ len += snprintf(buf + len, BUFLEN - len, "%s", saddr2str(&saddr.sa)); + break; + + #ifdef INET6 +@@ -4431,7 +4481,7 @@ + saddr.sa.sa_len = sizeof(struct sockaddr_in6); + #endif + saddr.sa.sa_family = AF_INET6; +- saddr.sin6.sin6_port = IPSEC_PORT_ANY; ++ saddr.sin6.sin6_port = id_b->port; + memcpy(&saddr.sin6.sin6_addr, + id->v + sizeof(*id_b) + sizeof(struct in6_addr), + sizeof(struct in6_addr)); +@@ -4440,7 +4490,7 @@ + ? ((struct sockaddr_in6 *)id_b)->sin6_scope_id + : 0); + +- len += snprintf(buf + len, BUFLEN - len, "%s", saddrwop2str(&saddr.sa)); ++ len += snprintf(buf + len, BUFLEN - len, "%s", saddr2str(&saddr.sa)); + break; + #endif + +Index: ipsec-tools-cvs-HEAD/src/racoon/sainfo.c +=================================================================== +--- ipsec-tools-cvs-HEAD.orig/src/racoon/sainfo.c 2011-03-03 20:07:44.000000000 +0200 ++++ ipsec-tools-cvs-HEAD/src/racoon/sainfo.c 2011-03-03 20:55:02.000000000 +0200 +@@ -124,7 +124,7 @@ + plog(LLV_DEBUG, LOCATION, NULL, + "evaluating sainfo: %s\n", sainfostr); + +- if(s->remoteid != remoteid) { ++ if (remoteid != -1 && s->remoteid != remoteid) { + plog(LLV_DEBUG, LOCATION, NULL, + "remoteid mismatch: %u != %u\n", + s->remoteid, remoteid); +@@ -234,16 +234,22 @@ + int pri = 0; + + if(s->remoteid) +- pri += 3; ++ pri += 7; + + if(s->id_i) +- pri += 3; ++ pri += 7; + +- if(s->idsrc) ++ if(s->idsrc) { + pri++; ++ if (ipsecdoi_id_has_port(s->idsrc)) ++ pri += 2; ++ } + +- if(s->iddst) ++ if(s->iddst) { + pri++; ++ if (ipsecdoi_id_has_port(s->iddst)) ++ pri += 2; ++ } + + return pri; + } +Index: ipsec-tools-cvs-HEAD/src/racoon/isakmp.c +=================================================================== +--- ipsec-tools-cvs-HEAD.orig/src/racoon/isakmp.c 2011-03-03 20:55:57.000000000 +0200 ++++ ipsec-tools-cvs-HEAD/src/racoon/isakmp.c 2011-03-03 21:14:13.000000000 +0200 +@@ -2170,7 +2170,15 @@ + * so no need to bother yet. --arno */ + + if (iph1hint == NULL || iph1hint->rmconf == NULL) { +- rmconf = getrmconf(iph2->dst, nopassive ? GETRMCONF_F_NO_PASSIVE : 0); ++ int flags = 0; ++ uint32_t remoteid; ++ if (nopassive) ++ flags |= GETRMCONF_F_NO_PASSIVE; ++ if (iph2->sainfo != NULL) { ++ flags |= GETRMCONF_F_HAS_REMOTEID; ++ remoteid = iph2->sainfo->remoteid; ++ } ++ rmconf = getrmconf(iph2->dst, flags, remoteid); + if (rmconf == NULL) { + plog(LLV_ERROR, LOCATION, NULL, + "no configuration found for %s.\n", +@@ -2246,7 +2254,7 @@ + struct secpolicy *sp_out, *sp_in; + { + struct remoteconf *conf; +- uint32_t remoteid = 0; ++ uint32_t remoteid = -1; + + plog(LLV_DEBUG, LOCATION, NULL, + "new acquire %s\n", spidx2str(&sp_out->spidx)); +@@ -2273,7 +2281,7 @@ + return -1; + } + +- conf = getrmconf(iph2->dst, 0); ++ conf = getrmconf(iph2->dst, 0, 0); + if (conf != NULL) + remoteid = conf->ph1id; + else +Index: ipsec-tools-cvs-HEAD/src/racoon/remoteconf.c +=================================================================== +--- ipsec-tools-cvs-HEAD.orig/src/racoon/remoteconf.c 2011-03-03 21:06:03.000000000 +0200 ++++ ipsec-tools-cvs-HEAD/src/racoon/remoteconf.c 2011-03-03 21:17:09.000000000 +0200 +@@ -217,6 +217,13 @@ + return MATCH_NONE; + } + ++ if ((rmsel->flags & GETRMCONF_F_HAS_REMOTEID) && ++ rmsel->remoteid != rmconf->ph1id){ ++ plog(LLV_DEBUG2, LOCATION, rmsel->remote, ++ "Not matched: remote_id did not match.\n"); ++ return MATCH_NONE; ++ } ++ + ret |= MATCH_BASIC; + + /* Check address */ +@@ -387,9 +394,10 @@ + */ + + struct remoteconf * +-getrmconf(remote, flags) ++getrmconf(remote, flags, remoteid) + struct sockaddr *remote; + int flags; ++ uint32_t remoteid; + { + struct rmconf_find_context ctx; + int n = 0; +@@ -397,6 +405,7 @@ + memset(&ctx, 0, sizeof(ctx)); + ctx.sel.flags = flags; + ctx.sel.remote = remote; ++ ctx.sel.remoteid = remoteid; + + if (enumrmconf(&ctx.sel, rmconf_find, &ctx) != 0) { + plog(LLV_ERROR, LOCATION, remote, +Index: ipsec-tools-cvs-HEAD/src/racoon/remoteconf.h +=================================================================== +--- ipsec-tools-cvs-HEAD.orig/src/racoon/remoteconf.h 2011-03-03 21:06:03.000000000 +0200 ++++ ipsec-tools-cvs-HEAD/src/racoon/remoteconf.h 2011-03-03 21:10:53.000000000 +0200 +@@ -178,6 +178,7 @@ + int flags; + struct sockaddr *remote; + int etype; ++ uint32_t remoteid; + struct isakmpsa *approval; + vchar_t *identity; + vchar_t *certificate_request; +@@ -191,12 +192,13 @@ + + #define GETRMCONF_F_NO_ANONYMOUS 0x0001 + #define GETRMCONF_F_NO_PASSIVE 0x0002 ++#define GETRMCONF_F_HAS_REMOTEID 0x0004 + + #define RMCONF_ERR_MULTIPLE ((struct remoteconf *) -1) + + extern int rmconf_match_identity __P((struct remoteconf *rmconf, + vchar_t *id_p)); +-extern struct remoteconf *getrmconf __P((struct sockaddr *remote, int flags)); ++extern struct remoteconf *getrmconf __P((struct sockaddr *remote, int flags, uint32_t remoteid)); + extern struct remoteconf *getrmconf_by_ph1 __P((struct ph1handle *iph1)); + extern struct remoteconf *getrmconf_by_name __P((const char *name)); + +Index: ipsec-tools-cvs-HEAD/src/racoon/pfkey.c +=================================================================== +--- ipsec-tools-cvs-HEAD.orig/src/racoon/pfkey.c 2011-03-03 21:14:45.000000000 +0200 ++++ ipsec-tools-cvs-HEAD/src/racoon/pfkey.c 2011-03-03 21:16:17.000000000 +0200 +@@ -2898,7 +2898,7 @@ + + /* If we are not acting as initiator, let's just leave and + * let the remote peer handle the restart */ +- rmconf = getrmconf(ma->remote, 0); ++ rmconf = getrmconf(ma->remote, 0, 0); + if (rmconf == NULL || !rmconf->passive) { + iph1->status = PHASE1ST_EXPIRED; + sched_schedule(&iph1->sce, 1, isakmp_ph1delete_stub); +@@ -3068,8 +3068,10 @@ + + if (iph2->ph1 && iph2->ph1->rmconf) + rmconf = iph2->ph1->rmconf; ++ else if (iph2->sainfo != NULL) ++ rmconf = getrmconf(iph2->dst, GETRMCONF_F_HAS_REMOTEID, iph2->sainfo->remoteid); + else +- rmconf = getrmconf(iph2->dst, 0); ++ rmconf = getrmconf(iph2->dst, 0, 0); + + if (rmconf && !rmconf->passive) { + struct ph1handle *iph1hint; +Index: ipsec-tools-cvs-HEAD/src/setkey/setkey.8 +=================================================================== +--- ipsec-tools-cvs-HEAD.orig/src/setkey/setkey.8 2011-03-04 11:48:30.000000000 +0200 ++++ ipsec-tools-cvs-HEAD/src/setkey/setkey.8 2011-03-04 11:48:56.000000000 +0200 +@@ -453,7 +453,7 @@ + .Pp + A second example of requiring transport mode encryption of specific + GRE tunnel: +-.Dl spdadd 0.0.0.0 0.0.0.0 gre 1234 ipsec esp/transport//require ; ++.Dl spdadd 0.0.0.0 0.0.0.0 gre 1234 -P in ipsec esp/transport//require ; + .Pp + .Em Note : + .Ar upperspec +Index: ipsec-tools-cvs-HEAD/src/racoon/racoon.conf.5 +=================================================================== +--- ipsec-tools-cvs-HEAD.orig/src/racoon/racoon.conf.5 2011-03-04 11:57:36.000000000 +0200 ++++ ipsec-tools-cvs-HEAD/src/racoon/racoon.conf.5 2011-03-04 12:01:13.000000000 +0200 +@@ -981,6 +981,7 @@ + .Bl -tag -width Ds -compact + .It Ic sainfo Po Ar local_id | Ic anonymous Pc \ + Po Ar remote_id | Ic clientaddr | Ic anonymous Pc \ ++Bo Ic grekey Ar key Bc \ + Bo Ic from Ar idtype Bo Ar string Bc Bc Bo Ic group Ar string Bc \ + Ic { Ar statements Ic } + Defines the parameters of the IKE phase 2 (IPsec-SA establishment). +@@ -1026,6 +1027,15 @@ + to restrict policy generation when racoon is acting as a client gateway + for peers with dynamic ip addresses. + .Pp ++If both ++.Ar local_id ++and ++.Ar remote_id ++are specified with GRE as upper layer protocol, the upper layer GRE ++key match can be specified with ++.Ic grekey ++.Ar key . ++.Pp + The + .Ic from + keyword allows an sainfo to only match for peers that use a specific phase1 +Index: ipsec-tools-cvs-HEAD/src/setkey/parse.y +=================================================================== +--- ipsec-tools-cvs-HEAD.orig/src/setkey/parse.y 2011-03-04 13:04:05.000000000 +0200 ++++ ipsec-tools-cvs-HEAD/src/setkey/parse.y 2011-03-04 13:04:09.000000000 +0200 +@@ -856,6 +856,17 @@ + } + $$.len = strlen($$.buf); + } ++ | DECSTRING ++ { ++ char tmp[16]; ++ sprintf(tmp, "%lu", $1); ++ $$.buf = strdup(tmp); ++ if (!$$.buf) { ++ yyerror("insufficient memory"); ++ return -1; ++ } ++ $$.len = strlen(tmp); ++ } + ; + + context_spec -- cgit v1.2.3