aboutsummaryrefslogtreecommitdiff
path: root/security/openvpn/files/patch-src_openvpn_dco__freebsd.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/openvpn/files/patch-src_openvpn_dco__freebsd.c')
-rw-r--r--security/openvpn/files/patch-src_openvpn_dco__freebsd.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/security/openvpn/files/patch-src_openvpn_dco__freebsd.c b/security/openvpn/files/patch-src_openvpn_dco__freebsd.c
new file mode 100644
index 000000000000..686fc6584be7
--- /dev/null
+++ b/security/openvpn/files/patch-src_openvpn_dco__freebsd.c
@@ -0,0 +1,90 @@
+--- src/openvpn/dco_freebsd.c.orig 2025-04-02 06:53:10 UTC
++++ src/openvpn/dco_freebsd.c
+@@ -72,6 +72,61 @@ sockaddr_to_nvlist(const struct sockaddr *sa)
+ return (nvl);
+ }
+
++static bool
++nvlist_to_sockaddr(const nvlist_t *nvl, struct sockaddr_storage *ss)
++{
++ if (!nvlist_exists_number(nvl, "af"))
++ {
++ return (false);
++ }
++ if (!nvlist_exists_binary(nvl, "address"))
++ {
++ return (false);
++ }
++ if (!nvlist_exists_number(nvl, "port"))
++ {
++ return (false);
++ }
++
++ ss->ss_family = nvlist_get_number(nvl, "af");
++
++ switch (ss->ss_family)
++ {
++ case AF_INET:
++ {
++ struct sockaddr_in *in = (struct sockaddr_in *)ss;
++ const void *data;
++ size_t len;
++
++ in->sin_len = sizeof(*in);
++ data = nvlist_get_binary(nvl, "address", &len);
++ ASSERT(len == sizeof(in->sin_addr));
++ memcpy(&in->sin_addr, data, sizeof(in->sin_addr));
++ in->sin_port = nvlist_get_number(nvl, "port");
++ break;
++ }
++
++ case AF_INET6:
++ {
++ struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)ss;
++ const void *data;
++ size_t len;
++
++ in6->sin6_len = sizeof(*in6);
++ data = nvlist_get_binary(nvl, "address", &len);
++ ASSERT(len == sizeof(in6->sin6_addr));
++ memcpy(&in6->sin6_addr, data, sizeof(in6->sin6_addr));
++ in6->sin6_port = nvlist_get_number(nvl, "port");
++ break;
++ }
++
++ default:
++ return (false);
++ }
++
++ return (true);
++}
++
+ int
+ dco_new_peer(dco_context_t *dco, unsigned int peerid, int sd,
+ struct sockaddr *localaddr, struct sockaddr *remoteaddr,
+@@ -570,6 +625,25 @@ dco_do_read(dco_context_t *dco)
+ case OVPN_NOTIF_ROTATE_KEY:
+ dco->dco_message_type = OVPN_CMD_SWAP_KEYS;
+ break;
++
++ case OVPN_NOTIF_FLOAT: {
++ const nvlist_t *address;
++
++ if (!nvlist_exists_nvlist(nvl, "address"))
++ {
++ msg(M_WARN, "Float notification without address");
++ break;
++ }
++
++ address = nvlist_get_nvlist(nvl, "address");
++ if (!nvlist_to_sockaddr(address, &dco->dco_float_peer_ss))
++ {
++ msg(M_WARN, "Failed to parse float notification");
++ break;
++ }
++ dco->dco_message_type = OVPN_CMD_FLOAT_PEER;
++ break;
++ }
+
+ default:
+ msg(M_WARN, "Unknown kernel notification %d", type);