forked from openwrt/packages
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
strongswan: DHCP on lo fixes backport
Fixes openwrt#25801. Adds the following commits to fix DHCP behaviour on Strongswan 5.9.14: - strongswan/strongswan@abbf9d2 - strongswan/strongswan@00d8c36 - strongswan/strongswan@a50ed30 Signed-off-by: Joel Low <joel@joelsplace.sg>
- Loading branch information
Showing
3 changed files
with
165 additions
and
0 deletions.
There are no files selected for viewing
30 changes: 30 additions & 0 deletions
30
net/strongswan/patches/0005-pf-handler-Accept-loopback-interfaces-as-packet-sour.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
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(-) | ||
|
||
Index: strongswan-5.9.14/src/libcharon/network/pf_handler.c | ||
=================================================================== | ||
--- strongswan-5.9.14.orig/src/libcharon/network/pf_handler.c | ||
+++ strongswan-5.9.14/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); | ||
|
65 changes: 65 additions & 0 deletions
65
net/strongswan/patches/0006-pf-handler-Correctly-bind-packet-socket-to-an-interf.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
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(-) | ||
|
||
Index: strongswan-5.9.14/src/libcharon/network/pf_handler.c | ||
=================================================================== | ||
--- strongswan-5.9.14.orig/src/libcharon/network/pf_handler.c | ||
+++ strongswan-5.9.14/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; | ||
} | ||
|
70 changes: 70 additions & 0 deletions
70
net/strongswan/patches/0007-dhcp-Add-option-to-bind-the-receive-socket-to-a-diff.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
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(-) | ||
|
||
Index: strongswan-5.9.14/conf/plugins/dhcp.opt | ||
=================================================================== | ||
--- strongswan-5.9.14.orig/conf/plugins/dhcp.opt | ||
+++ strongswan-5.9.14/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. | ||
Index: strongswan-5.9.14/src/libcharon/plugins/dhcp/dhcp_socket.c | ||
=================================================================== | ||
--- strongswan-5.9.14.orig/src/libcharon/plugins/dhcp/dhcp_socket.c | ||
+++ strongswan-5.9.14/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); |