mirror of
https://github.com/openwrt/packages.git
synced 2026-06-17 17:00:28 +04:00
strongswan: DHCP on lo fixes backport
Fixes #25801. Adds the following commits to fix DHCP behaviour on Strongswan 5.9.14: - https://github.com/strongswan/strongswan/commit/abbf9d28b0032cf80b79bcacea3146a60800a6dd - https://github.com/strongswan/strongswan/commit/00d8c36d6fdf9e8ee99b9f92a64e7e81dbfa4432 - https://github.com/strongswan/strongswan/commit/a50ed3006e8152eb2cf20e9f92f088ecc18081b0 Signed-off-by: Joel Low <joel@joelsplace.sg>
This commit is contained in:
committed by
Philip Prindeville
parent
c591f69b9b
commit
eb91f914b9
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=strongswan
|
||||
PKG_VERSION:=5.9.14
|
||||
PKG_RELEASE:=6
|
||||
PKG_RELEASE:=7
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
|
||||
PKG_SOURCE_URL:=https://download.strongswan.org/ https://download2.strongswan.org/
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
From abbf9d28b0032cf80b79bcacea3146a60800a6dd Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Brunner <tobias@strongswan.org>
|
||||
Date: Mon, 27 Jan 2025 09:40:56 +0100
|
||||
Subject: [PATCH 1/3] pf-handler: Accept loopback interfaces as packet source
|
||||
|
||||
In some setups the responses from the DHCP server are sent via lo, which
|
||||
does not have an address of type `ARPHRD_ETHER` (the address length is
|
||||
the same, though, just all zeros, by default). Note that the dhcp plugin
|
||||
doesn't actually care for the MAC address or interface details, that's
|
||||
only used by the farp plugin.
|
||||
|
||||
Fixes: 187c72d1afdc ("dhcp: Port the plugin to FreeBSD/macOS")
|
||||
---
|
||||
src/libcharon/network/pf_handler.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/src/libcharon/network/pf_handler.c
|
||||
+++ b/src/libcharon/network/pf_handler.c
|
||||
@@ -176,7 +176,8 @@ static cached_iface_t *find_interface(pr
|
||||
|
||||
if (ioctl(fd, SIOCGIFNAME, &req) == 0 &&
|
||||
ioctl(fd, SIOCGIFHWADDR, &req) == 0 &&
|
||||
- req.ifr_hwaddr.sa_family == ARPHRD_ETHER)
|
||||
+ (req.ifr_hwaddr.sa_family == ARPHRD_ETHER ||
|
||||
+ req.ifr_hwaddr.sa_family == ARPHRD_LOOPBACK))
|
||||
{
|
||||
idx = find_least_used_cache_entry(this);
|
||||
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
From 00d8c36d6fdf9e8ee99b9f92a64e7e81dbfa4432 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Brunner <tobias@strongswan.org>
|
||||
Date: Thu, 30 Jan 2025 14:40:33 +0100
|
||||
Subject: [PATCH 2/3] pf-handler: Correctly bind packet socket to an interface
|
||||
|
||||
Binding such sockets via SO_BINDTODEVICE does not work at all. Instead,
|
||||
bind() has to be used, as described in the packet(7) man page.
|
||||
---
|
||||
src/libcharon/network/pf_handler.c | 31 +++++++++++++++++++++++++++---
|
||||
1 file changed, 28 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/src/libcharon/network/pf_handler.c
|
||||
+++ b/src/libcharon/network/pf_handler.c
|
||||
@@ -227,6 +227,30 @@ METHOD(pf_handler_t, destroy, void,
|
||||
}
|
||||
|
||||
/**
|
||||
+ * Bind the given packet socket to the a named device
|
||||
+ */
|
||||
+static bool bind_packet_socket_to_device(int fd, char *iface)
|
||||
+{
|
||||
+ struct sockaddr_ll addr = {
|
||||
+ .sll_family = AF_PACKET,
|
||||
+ .sll_ifindex = if_nametoindex(iface),
|
||||
+ };
|
||||
+
|
||||
+ if (!addr.sll_ifindex)
|
||||
+ {
|
||||
+ DBG1(DBG_CFG, "unable to bind socket to '%s': not found", iface);
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1)
|
||||
+ {
|
||||
+ DBG1(DBG_CFG, "binding socket to '%s' failed: %s",
|
||||
+ iface, strerror(errno));
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
* Setup capturing via AF_PACKET socket
|
||||
*/
|
||||
static bool setup_internal(private_pf_handler_t *this, char *iface,
|
||||
@@ -248,14 +272,15 @@ static bool setup_internal(private_pf_ha
|
||||
this->name, strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
- if (iface && !bind_to_device(this->receive, iface))
|
||||
+ if (iface && iface[0] && !bind_packet_socket_to_device(this->receive, iface))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
lib->watcher->add(lib->watcher, this->receive, WATCHER_READ,
|
||||
receive_packet, this);
|
||||
- DBG2(DBG_NET, "listening for %s (protocol=0x%04x) requests on fd=%d",
|
||||
- this->name, protocol, this->receive);
|
||||
+ DBG2(DBG_NET, "listening for %s (protocol=0x%04x) requests on fd=%d bound "
|
||||
+ "to %s", this->name, protocol, this->receive,
|
||||
+ iface && iface[0] ? iface : "no interface");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
From a50ed3006e8152eb2cf20e9f92f088ecc18081b0 Mon Sep 17 00:00:00 2001
|
||||
From: Tobias Brunner <tobias@strongswan.org>
|
||||
Date: Wed, 29 Jan 2025 17:23:31 +0100
|
||||
Subject: [PATCH 3/3] dhcp: Add option to bind the receive socket to a
|
||||
different interface
|
||||
|
||||
This can be useful if the DHCP server runs on the same server. On Linux,
|
||||
the response is then sent via `lo`, so packets won't be received if both
|
||||
sockets are bound to e.g. a bridge interface.
|
||||
---
|
||||
conf/plugins/dhcp.opt | 10 ++++++++++
|
||||
src/libcharon/plugins/dhcp/dhcp_socket.c | 13 ++++++++-----
|
||||
2 files changed, 18 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/conf/plugins/dhcp.opt
|
||||
+++ b/conf/plugins/dhcp.opt
|
||||
@@ -36,3 +36,13 @@ charon.plugins.dhcp.interface
|
||||
Interface name the plugin uses for address allocation. The default is to
|
||||
bind to any (0.0.0.0) and let the system decide which way to route the
|
||||
packets to the DHCP server.
|
||||
+
|
||||
+charon.plugins.dhcp.interface_receive = charon.plugins.dhcp.interface
|
||||
+ Interface name the plugin uses to bind its receive socket.
|
||||
+
|
||||
+ Interface name the plugin uses to bind its receive socket. The default is
|
||||
+ to use the same interface as the send socket. Set it to the empty string
|
||||
+ to avoid binding the receive socket to any interface while the send socket
|
||||
+ is bound to one. If the server runs on the same host and the send socket is
|
||||
+ bound to an interface, it might be necessary to set this to `lo` or the
|
||||
+ empty string.
|
||||
--- a/src/libcharon/plugins/dhcp/dhcp_socket.c
|
||||
+++ b/src/libcharon/plugins/dhcp/dhcp_socket.c
|
||||
@@ -716,7 +716,7 @@ dhcp_socket_t *dhcp_socket_create()
|
||||
},
|
||||
};
|
||||
socklen_t addr_len;
|
||||
- char *iface;
|
||||
+ char *iface, *iface_receive;
|
||||
int on = 1, rcvbuf = 0;
|
||||
|
||||
#if !defined(__APPLE__) && !defined(__FreeBSD__)
|
||||
@@ -809,8 +809,11 @@ dhcp_socket_t *dhcp_socket_create()
|
||||
this->dst = host_create_from_string(lib->settings->get_str(lib->settings,
|
||||
"%s.plugins.dhcp.server", "255.255.255.255",
|
||||
lib->ns), DHCP_SERVER_PORT);
|
||||
- iface = lib->settings->get_str(lib->settings, "%s.plugins.dhcp.interface",
|
||||
- NULL, lib->ns);
|
||||
+ iface = lib->settings->get_str(lib->settings,
|
||||
+ "%s.plugins.dhcp.interface", NULL, lib->ns);
|
||||
+ iface_receive = lib->settings->get_str(lib->settings,
|
||||
+ "%s.plugins.dhcp.interface_receive", NULL,
|
||||
+ lib->ns) ?: iface;
|
||||
if (!this->dst)
|
||||
{
|
||||
DBG1(DBG_CFG, "configured DHCP server address invalid");
|
||||
@@ -873,8 +876,8 @@ dhcp_socket_t *dhcp_socket_create()
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- this->pf_handler = pf_handler_create("DHCP", iface, receive_dhcp, this,
|
||||
- &dhcp_filter);
|
||||
+ this->pf_handler = pf_handler_create("DHCP", iface_receive, receive_dhcp,
|
||||
+ this, &dhcp_filter);
|
||||
if (!this->pf_handler)
|
||||
{
|
||||
destroy(this);
|
||||
Reference in New Issue
Block a user