[Openvpn-devel,v3] Bugfix: Set broadcast address on interface.

Message ID 20250915110507.20557-1-sebastian-git-2016@marsching.com
State New
Headers show
Series [Openvpn-devel,v3] Bugfix: Set broadcast address on interface. | expand

Commit Message

Sebastian Marsching Sept. 15, 2025, 11:05 a.m. UTC
This fixes a problem that was introduced in OpenVPN 2.5. Previously,
the ifconfig utility was used for adding the local address to an
interface. This utility automatically sets the correct broadcast address
based on the given unicast address and netmask.

Due to switching to iproute and Netlink, this does not happen
automatically any longer, which means that applications that rely on
broadcasts do not work correctly.

This patch fixes this issue both when using iproute (by telling iproute
to set the broadcast address based on the local address and prefix) and
when using Netlink (by calculating the correct broadcast address and
setting it).

Signed-off-by: Sebastian Marsching <sebastian-git-2016@marsching.com>
---
 src/openvpn/networking_iproute2.c | 2 +-
 src/openvpn/networking_sitnl.c    | 8 ++++++++
 2 files changed, 9 insertions(+), 1 deletion(-)

Patch

diff --git a/src/openvpn/networking_iproute2.c b/src/openvpn/networking_iproute2.c
index e9be3a45..773571d6 100644
--- a/src/openvpn/networking_iproute2.c
+++ b/src/openvpn/networking_iproute2.c
@@ -150,7 +150,7 @@  net_addr_v4_add(openvpn_net_ctx_t *ctx, const char *iface, const in_addr_t *addr
 
     const char *addr_str = print_in_addr_t(*addr, 0, &ctx->gc);
 
-    argv_printf(&argv, "%s addr add dev %s %s/%d", iproute_path, iface, addr_str, prefixlen);
+    argv_printf(&argv, "%s addr add dev %s %s/%d broadcast +", iproute_path, iface, addr_str, prefixlen);
     argv_msg(M_INFO, &argv);
     openvpn_execve_check(&argv, ctx->es, S_FATAL, "Linux ip addr add failed");
 
diff --git a/src/openvpn/networking_sitnl.c b/src/openvpn/networking_sitnl.c
index 4210e92c..00d61067 100644
--- a/src/openvpn/networking_sitnl.c
+++ b/src/openvpn/networking_sitnl.c
@@ -31,6 +31,7 @@ 
 #include "misc.h"
 #include "networking.h"
 #include "proto.h"
+#include "route.h"
 
 #include <errno.h>
 #include <string.h>
@@ -803,6 +804,13 @@  sitnl_addr_set(int cmd, uint32_t flags, int ifindex, sa_family_t af_family,
         SITNL_ADDATTR(&req.n, sizeof(req), IFA_LOCAL, local, size);
     }
 
+    if (af_family == AF_INET && local && !remote && prefixlen <= 30)
+    {
+        inet_address_t broadcast = *local;
+        broadcast.ipv4 |= htonl(~netbits_to_netmask(prefixlen));
+        SITNL_ADDATTR(&req.n, sizeof(req), IFA_BROADCAST, &broadcast, size);
+    }
+
     ret = sitnl_send(&req.n, 0, 0, NULL, NULL);
     if (ret == -EEXIST)
     {