Support GRE key in selectors
This commit is contained in:
258
0004-Support-GRE-key-in-selectors.patch
Normal file
258
0004-Support-GRE-key-in-selectors.patch
Normal file
@@ -0,0 +1,258 @@
|
|||||||
|
From 027c90f6808d451f3bbcd4b2dc4b8ad04806dc64 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zoran=20Peri=C4=8Di=C4=87?= <zoran.pericic@infomaas.com>
|
||||||
|
Date: Sun, 21 Jan 2024 03:11:32 +0100
|
||||||
|
Subject: [PATCH 4/4] Support GRE key in selectors.
|
||||||
|
|
||||||
|
---
|
||||||
|
.../kernel_netlink/kernel_netlink_ipsec.c | 12 +++++++++++
|
||||||
|
.../plugins/load_tester/load_tester_config.c | 16 ++++++++++++++
|
||||||
|
src/libcharon/plugins/stroke/stroke_config.c | 15 +++++++++++++
|
||||||
|
src/libcharon/plugins/vici/vici_config.c | 21 ++++++++++++++++++-
|
||||||
|
.../selectors/traffic_selector.c | 20 ++++++++++++++++++
|
||||||
|
.../selectors/traffic_selector.h | 12 +++++++++++
|
||||||
|
src/starter/confread.c | 18 ++++++++++++++++
|
||||||
|
7 files changed, 113 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c
|
||||||
|
index 7596f0c18..fdfc9d51e 100644
|
||||||
|
--- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c
|
||||||
|
+++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_ipsec.c
|
||||||
|
@@ -864,6 +864,7 @@ static struct xfrm_selector ts2selector(traffic_selector_t *src,
|
||||||
|
{
|
||||||
|
struct xfrm_selector sel;
|
||||||
|
uint16_t port;
|
||||||
|
+ uint32_t gre_key;
|
||||||
|
|
||||||
|
memset(&sel, 0, sizeof(sel));
|
||||||
|
sel.family = (src->get_type(src) == TS_IPV4_ADDR_RANGE) ? AF_INET : AF_INET6;
|
||||||
|
@@ -884,6 +885,17 @@ static struct xfrm_selector ts2selector(traffic_selector_t *src,
|
||||||
|
sel.dport = htons(traffic_selector_icmp_code(port));
|
||||||
|
sel.dport_mask = sel.dport ? ~0 : 0;
|
||||||
|
}
|
||||||
|
+ if (sel.proto == IPPROTO_GRE)
|
||||||
|
+ {
|
||||||
|
+ /* the kernel expects the GRE key in the source and destination
|
||||||
|
+ * port fields, respectively. */
|
||||||
|
+ gre_key = htons(traffic_selector_gre_key(dst->get_from_port(dst), dst->get_to_port(dst)));
|
||||||
|
+ DBG2(DBG_KNL, "Policy GRE key: %d (%d-%d) %d", gre_key, dst->get_from_port(dst), dst->get_to_port(dst), traffic_selector_gre_key(dst->get_from_port(dst), dst->get_to_port(dst)));
|
||||||
|
+ sel.sport = gre_key >> 16;
|
||||||
|
+ sel.sport_mask = ~0;
|
||||||
|
+ sel.dport = gre_key & 0xffff;
|
||||||
|
+ sel.dport_mask = ~0;
|
||||||
|
+ }
|
||||||
|
sel.ifindex = interface ? if_nametoindex(interface) : 0;
|
||||||
|
sel.user = 0;
|
||||||
|
|
||||||
|
diff --git a/src/libcharon/plugins/load_tester/load_tester_config.c b/src/libcharon/plugins/load_tester/load_tester_config.c
|
||||||
|
index 58e1cd98a..436116361 100644
|
||||||
|
--- a/src/libcharon/plugins/load_tester/load_tester_config.c
|
||||||
|
+++ b/src/libcharon/plugins/load_tester/load_tester_config.c
|
||||||
|
@@ -16,6 +16,8 @@
|
||||||
|
|
||||||
|
#include "load_tester_config.h"
|
||||||
|
|
||||||
|
+#include <utils/utils.h>
|
||||||
|
+
|
||||||
|
#include <netdb.h>
|
||||||
|
|
||||||
|
#include <daemon.h>
|
||||||
|
@@ -512,6 +514,20 @@ static bool parse_protoport(char *token, uint16_t *from_port,
|
||||||
|
{
|
||||||
|
*from_port = *to_port = 0;
|
||||||
|
}
|
||||||
|
+ else if (*port && *protocol == IPPROTO_GRE)
|
||||||
|
+ {
|
||||||
|
+ p = strtol(port, &endptr, 0);
|
||||||
|
+ if (p < 0 || p > 0xffffffff)
|
||||||
|
+ {
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+ end->from_port = (p >> 16) & 0xffff;
|
||||||
|
+ end->to_port = p & 0xffff;
|
||||||
|
+ if (*endptr)
|
||||||
|
+ {
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
else if (*port)
|
||||||
|
{
|
||||||
|
svc = getservbyname(port, NULL);
|
||||||
|
diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c
|
||||||
|
index 55db379ff..9ee4c6463 100644
|
||||||
|
--- a/src/libcharon/plugins/stroke/stroke_config.c
|
||||||
|
+++ b/src/libcharon/plugins/stroke/stroke_config.c
|
||||||
|
@@ -20,6 +20,7 @@
|
||||||
|
#include <daemon.h>
|
||||||
|
#include <threading/mutex.h>
|
||||||
|
#include <utils/lexparser.h>
|
||||||
|
+#include <utils/utils.h>
|
||||||
|
|
||||||
|
#include <netdb.h>
|
||||||
|
|
||||||
|
@@ -937,6 +938,20 @@ 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);
|
||||||
|
+ if (p < 0 || p > 0xffffffff)
|
||||||
|
+ {
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+ *from_port = (p >> 16) & 0xffff;
|
||||||
|
+ *to_port = p & 0xffff;
|
||||||
|
+ if (*endptr)
|
||||||
|
+ {
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
else if (*port)
|
||||||
|
{
|
||||||
|
svc = getservbyname(port, NULL);
|
||||||
|
diff --git a/src/libcharon/plugins/vici/vici_config.c b/src/libcharon/plugins/vici/vici_config.c
|
||||||
|
index b1486e337..35c4df1b0 100644
|
||||||
|
--- a/src/libcharon/plugins/vici/vici_config.c
|
||||||
|
+++ b/src/libcharon/plugins/vici/vici_config.c
|
||||||
|
@@ -718,7 +718,25 @@ CALLBACK(parse_ts, bool,
|
||||||
|
from = 0xffff;
|
||||||
|
to = 0;
|
||||||
|
}
|
||||||
|
- else if (*port && !streq(port, "any"))
|
||||||
|
+ else if (*port && !streq(port, "any") && proto == IPPROTO_GRE)
|
||||||
|
+ {
|
||||||
|
+ DBG2(DBG_CFG, " GRE key %s", port);
|
||||||
|
+ p = strtol(port, &end, 0);
|
||||||
|
+ if (p < 0 || p > 0xffffffff)
|
||||||
|
+ {
|
||||||
|
+ DBG2(DBG_CFG, " Invalid GRE key %s", port);
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+ from = (p >> 16) & 0xffff;
|
||||||
|
+ to = p & 0xffff;
|
||||||
|
+ DBG2(DBG_CFG, " Parsed GRE key %d-%d(%d)", from, to, p);
|
||||||
|
+ if (*end)
|
||||||
|
+ {
|
||||||
|
+ DBG2(DBG_CFG, " Invalid GRE key %s", port);
|
||||||
|
+ return FALSE;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ else if (*port && !streq(port, "any") && proto != IPPROTO_GRE)
|
||||||
|
{
|
||||||
|
svc = getservbyname(port, NULL);
|
||||||
|
if (svc)
|
||||||
|
@@ -752,6 +770,7 @@ CALLBACK(parse_ts, bool,
|
||||||
|
}
|
||||||
|
if (streq(buf, "dynamic"))
|
||||||
|
{
|
||||||
|
+ DBG2(DBG_CFG, " Create dynamic selector GRE key proto=%d, from_port=%d, to_port=%d", proto, from, to);
|
||||||
|
ts = traffic_selector_create_dynamic(proto, from, to);
|
||||||
|
}
|
||||||
|
else if (strchr(buf, '-'))
|
||||||
|
diff --git a/src/libstrongswan/selectors/traffic_selector.c b/src/libstrongswan/selectors/traffic_selector.c
|
||||||
|
index fe61e3768..29ffbffbd 100644
|
||||||
|
--- a/src/libstrongswan/selectors/traffic_selector.c
|
||||||
|
+++ b/src/libstrongswan/selectors/traffic_selector.c
|
||||||
|
@@ -205,6 +205,18 @@ static int print_icmp(printf_hook_data_t *data, uint16_t port)
|
||||||
|
return print_in_hook(data, "%d", type);
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * Print GRE key
|
||||||
|
+ */
|
||||||
|
+static int print_gre(printf_hook_data_t *data, uint16_t from_port, uint16_t to_port)
|
||||||
|
+{
|
||||||
|
+ uint32_t gre_key;
|
||||||
|
+
|
||||||
|
+ gre_key = traffic_selector_gre_key(from_port, to_port);
|
||||||
|
+
|
||||||
|
+ return print_in_hook(data, "%d", gre_key);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* Described in header.
|
||||||
|
*/
|
||||||
|
@@ -319,6 +331,10 @@ int traffic_selector_printf_hook(printf_hook_data_t *data,
|
||||||
|
{
|
||||||
|
written += print_icmp(data, this->from_port);
|
||||||
|
}
|
||||||
|
+ else if (this->protocol == IPPROTO_GRE)
|
||||||
|
+ {
|
||||||
|
+ written += print_gre(data, this->from_port, this->to_port);
|
||||||
|
+ }
|
||||||
|
else
|
||||||
|
{
|
||||||
|
serv = getservbyport(htons(this->from_port), serv_proto);
|
||||||
|
@@ -343,6 +359,10 @@ int traffic_selector_printf_hook(printf_hook_data_t *data,
|
||||||
|
written += print_in_hook(data, "-");
|
||||||
|
written += print_icmp(data, this->to_port);
|
||||||
|
}
|
||||||
|
+ else if (this->protocol == IPPROTO_GRE)
|
||||||
|
+ {
|
||||||
|
+ written += print_gre(data, this->from_port, this->to_port);
|
||||||
|
+ }
|
||||||
|
else
|
||||||
|
{
|
||||||
|
written += print_in_hook(data, "%d-%d",
|
||||||
|
diff --git a/src/libstrongswan/selectors/traffic_selector.h b/src/libstrongswan/selectors/traffic_selector.h
|
||||||
|
index 367b4fff9..b7010e4a7 100644
|
||||||
|
--- a/src/libstrongswan/selectors/traffic_selector.h
|
||||||
|
+++ b/src/libstrongswan/selectors/traffic_selector.h
|
||||||
|
@@ -272,6 +272,18 @@ static inline uint8_t traffic_selector_icmp_code(uint16_t port)
|
||||||
|
return port & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * Extract the GRE key from a source and destination port in host order
|
||||||
|
+ *
|
||||||
|
+ * @param from_port port number in host order
|
||||||
|
+ * @param to_port port number in host order
|
||||||
|
+ * @return GRE key
|
||||||
|
+ */
|
||||||
|
+static inline uint8_t traffic_selector_gre_key(uint16_t from_port, uint16_t to_port)
|
||||||
|
+{
|
||||||
|
+ return (from_port & 0xffff) << 16 | (to_port & 0xffff);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/**
|
||||||
|
* Compare two traffic selectors, usable as sort function
|
||||||
|
*
|
||||||
|
diff --git a/src/starter/confread.c b/src/starter/confread.c
|
||||||
|
index 5065bc369..e2c03694d 100644
|
||||||
|
--- a/src/starter/confread.c
|
||||||
|
+++ b/src/starter/confread.c
|
||||||
|
@@ -25,6 +25,7 @@
|
||||||
|
|
||||||
|
#include <library.h>
|
||||||
|
#include <utils/debug.h>
|
||||||
|
+#include <utils/utils.h>
|
||||||
|
|
||||||
|
#include "keywords.h"
|
||||||
|
#include "confread.h"
|
||||||
|
@@ -335,6 +336,23 @@ static void kw_end(starter_conn_t *conn, starter_end_t *end, kw_token_t token,
|
||||||
|
end->from_port = 0xffff;
|
||||||
|
end->to_port = 0;
|
||||||
|
}
|
||||||
|
+ else if (*port && end->protocol == IPPROTO_GRE)
|
||||||
|
+ {
|
||||||
|
+ DBG1(DBG_APP, "# GRE key: %s=%s", key, port);
|
||||||
|
+ p = strtol(port, &endptr, 0);
|
||||||
|
+ if (p < 0 || p > 0xffffffff)
|
||||||
|
+ {
|
||||||
|
+ DBG1(DBG_APP, "# bad GRE key: %s=%s", key, port);
|
||||||
|
+ goto err;
|
||||||
|
+ }
|
||||||
|
+ end->from_port = (p >> 16) & 0xffff;
|
||||||
|
+ end->to_port = p & 0xffff;
|
||||||
|
+ if (*endptr)
|
||||||
|
+ {
|
||||||
|
+ DBG1(DBG_APP, "# bad GRE key: %s=%s", key, port);
|
||||||
|
+ goto err;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
else if (*port)
|
||||||
|
{
|
||||||
|
svc = getservbyname(port, NULL);
|
||||||
|
--
|
||||||
|
2.43.0
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
%global _hardened_build 1
|
%global _hardened_build 1
|
||||||
#%%define prerelease dr1
|
#%%define prerelease dr1
|
||||||
%global dist .nhrp.9%{?dist}
|
%global dist .nhrp.11%{?dist}
|
||||||
|
|
||||||
%bcond_without python3
|
%bcond_without python3
|
||||||
%bcond_without perl
|
%bcond_without perl
|
||||||
@@ -34,6 +34,7 @@ Patch1: strongswan-5.9.7-error-no-format.patch
|
|||||||
Patch10: 0001-charon-add-optional-source-and-remote-overrides-for-.patch
|
Patch10: 0001-charon-add-optional-source-and-remote-overrides-for-.patch
|
||||||
Patch11: 0002-vici-send-certificates-for-ike-sa-events.patch
|
Patch11: 0002-vici-send-certificates-for-ike-sa-events.patch
|
||||||
Patch12: 0003-vici-add-support-for-individual-sa-state-changes.patch
|
Patch12: 0003-vici-add-support-for-individual-sa-state-changes.patch
|
||||||
|
Patch13: 0004-Support-GRE-key-in-selectors.patch
|
||||||
|
|
||||||
BuildRequires: autoconf
|
BuildRequires: autoconf
|
||||||
BuildRequires: automake
|
BuildRequires: automake
|
||||||
|
|||||||
Reference in New Issue
Block a user