diff options
author | Timo Teräs <timo.teras@iki.fi> | 2015-09-21 13:42:18 +0300 |
---|---|---|
committer | Timo Teräs <timo.teras@iki.fi> | 2017-11-20 10:44:40 +0200 |
commit | 78368225baa57342645a88f06b416185a7c85b01 (patch) | |
tree | 07a1f07b7b844a5db96c8968c06985c1b5a606c8 /src/libcharon/plugins | |
parent | 941ec20df80cbe0f0287742d06859d80fb343736 (diff) | |
download | strongswan-tteras.tar.bz2 strongswan-tteras.tar.xz |
support gre key in ikev1tteras
this implements gre key negotiation in ikev1 similarly to the
ipsec-tools patch in alpine.
the from/to port pair is internally used as gre key for gre
protocol traffic selectors. since from/to pairs 0/0xffff and
0xffff/0 have special meaning, the gre keys 0xffff and 0xffff0000
will not work.
this is not standard compliant, and should probably not be upstreamed
or used widely, but it is applied for interoperability with alpine
racoon for the time being.
Diffstat (limited to 'src/libcharon/plugins')
-rw-r--r-- | src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c | 40 | ||||
-rw-r--r-- | src/libcharon/plugins/stroke/stroke_config.c | 5 | ||||
-rw-r--r-- | src/libcharon/plugins/unity/unity_narrow.c | 2 | ||||
-rw-r--r-- | src/libcharon/plugins/vici/vici_config.c | 9 |
4 files changed, 45 insertions, 11 deletions
diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c index 4e79dfced..27ea824ee 100644 --- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c +++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c @@ -824,7 +824,18 @@ static struct xfrm_selector ts2selector(traffic_selector_t *src, ts2subnet(src, &sel.saddr, &sel.prefixlen_s); ts2ports(dst, &sel.dport, &sel.dport_mask); ts2ports(src, &sel.sport, &sel.sport_mask); - if ((sel.proto == IPPROTO_ICMP || sel.proto == IPPROTO_ICMPV6) && + if (sel.proto == IPPROTO_GRE) + { + sel.sport = htons(src->get_from_port(src)); + sel.dport = htons(src->get_to_port(src)); + sel.sport_mask = ~0; + sel.dport_mask = ~0; + if (sel.sport == htons(0) && sel.dport == htons(0xffff)) + { + sel.sport = sel.dport = sel.sport_mask = sel.dport_mask = 0; + } + } + else if ((sel.proto == IPPROTO_ICMP || sel.proto == IPPROTO_ICMPV6) && (sel.dport || sel.sport)) { /* the kernel expects the ICMP type and code in the source and @@ -848,7 +859,7 @@ static traffic_selector_t* selector2ts(struct xfrm_selector *sel, bool src) { u_char *addr; uint8_t prefixlen; - uint16_t port = 0; + uint16_t from_port = 0, to_port = 65535; host_t *host = NULL; if (src) @@ -857,7 +868,7 @@ static traffic_selector_t* selector2ts(struct xfrm_selector *sel, bool src) prefixlen = sel->prefixlen_s; if (sel->sport_mask) { - port = ntohs(sel->sport); + from_port = to_port = ntohs(sel->sport); } } else @@ -866,14 +877,27 @@ static traffic_selector_t* selector2ts(struct xfrm_selector *sel, bool src) prefixlen = sel->prefixlen_d; if (sel->dport_mask) { - port = ntohs(sel->dport); + from_port = to_port = ntohs(sel->dport); + } + } + if (sel->proto == IPPROTO_GRE) + { + if (sel->sport_mask) + { + from_port = ntohs(sel->sport); + to_port = ntohs(sel->dport); + } + else + { + from_port = 0; + to_port = 0xffff; } } - if (sel->proto == IPPROTO_ICMP || sel->proto == IPPROTO_ICMPV6) + else if (sel->proto == IPPROTO_ICMP || sel->proto == IPPROTO_ICMPV6) { /* convert ICMP[v6] message type and code as supplied by the kernel in * source and destination ports (both in network order) */ - port = (sel->sport >> 8) | (sel->dport & 0xff00); - port = ntohs(port); + from_port = (sel->sport >> 8) | (sel->dport & 0xff00); + from_port = to_port = ntohs(from_port); } /* The Linux 2.6 kernel does not set the selector's family field, * so as a kludge we additionally test the prefix length. @@ -890,7 +914,7 @@ static traffic_selector_t* selector2ts(struct xfrm_selector *sel, bool src) if (host) { return traffic_selector_create_from_subnet(host, prefixlen, - sel->proto, port, port ?: 65535); + sel->proto, from_port, to_port); } return NULL; } diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c index ac0129210..b2060e2eb 100644 --- a/src/libcharon/plugins/stroke/stroke_config.c +++ b/src/libcharon/plugins/stroke/stroke_config.c @@ -936,6 +936,11 @@ static bool parse_protoport(char *token, uint16_t *from_port, *from_port = 0xffff; *to_port = 0; } + else if (*port && *protocol == IPPROTO_GRE) + { + p = strtol(port, &endptr, 0); + traffic_selector_split_grekey(p, from_port, to_port); + } else if (*port) { svc = getservbyname(port, NULL); diff --git a/src/libcharon/plugins/unity/unity_narrow.c b/src/libcharon/plugins/unity/unity_narrow.c index 227d24be8..7749d8c2c 100644 --- a/src/libcharon/plugins/unity/unity_narrow.c +++ b/src/libcharon/plugins/unity/unity_narrow.c @@ -247,7 +247,7 @@ METHOD(listener_t, message, bool, if (!first) { id_payload = (id_payload_t*)payload; - tsr = id_payload->get_ts(id_payload); + tsr = id_payload->get_ts(id_payload, NULL, FALSE); break; } first = FALSE; diff --git a/src/libcharon/plugins/vici/vici_config.c b/src/libcharon/plugins/vici/vici_config.c index b3e835f59..710b57994 100644 --- a/src/libcharon/plugins/vici/vici_config.c +++ b/src/libcharon/plugins/vici/vici_config.c @@ -680,8 +680,13 @@ CALLBACK(parse_ts, bool, } else if (*port && !streq(port, "any")) { - svc = getservbyname(port, NULL); - if (svc) + if (proto == IPPROTO_GRE) + { + p = strtol(port, &end, 0); + if (*end) return FALSE; + traffic_selector_split_grekey(p, &from, &to); + } + else if ((svc = getservbyname(port, NULL)) != NULL) { from = to = ntohs(svc->s_port); } |