Signed-off-by: Kristof Provost <kprovost@netgate.com>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <20250723083816.71604-2-kprovost@netgate.com>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg32282.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
| ... | ... |
@@ -848,6 +848,15 @@ if test "$enable_dco" != "no"; then |
| 848 | 848 |
else |
| 849 | 849 |
AC_MSG_ERROR([DCO support can't be enabled]) |
| 850 | 850 |
fi |
| 851 |
+ else |
|
| 852 |
+ AC_CHECK_DECLS( |
|
| 853 |
+ [OVPN_NOTIF_FLOAT], |
|
| 854 |
+ [AC_DEFINE([ENABLE_DCO_FLOAT_FREEBSD], [1], [We have DCO float notifications on FreeBSD])], |
|
| 855 |
+ , |
|
| 856 |
+ [[ |
|
| 857 |
+ #include <net/if_ovpn.h> |
|
| 858 |
+ ]] |
|
| 859 |
+ ) |
|
| 851 | 860 |
fi |
| 852 | 861 |
;; |
| 853 | 862 |
*-mingw*) |
| ... | ... |
@@ -72,6 +72,63 @@ sockaddr_to_nvlist(const struct sockaddr *sa) |
| 72 | 72 |
return (nvl); |
| 73 | 73 |
} |
| 74 | 74 |
|
| 75 |
+#ifdef ENABLE_DCO_FLOAT_FREEBSD |
|
| 76 |
+static bool |
|
| 77 |
+nvlist_to_sockaddr(const nvlist_t *nvl, struct sockaddr_storage *ss) |
|
| 78 |
+{
|
|
| 79 |
+ if (!nvlist_exists_number(nvl, "af")) |
|
| 80 |
+ {
|
|
| 81 |
+ return (false); |
|
| 82 |
+ } |
|
| 83 |
+ if (!nvlist_exists_binary(nvl, "address")) |
|
| 84 |
+ {
|
|
| 85 |
+ return (false); |
|
| 86 |
+ } |
|
| 87 |
+ if (!nvlist_exists_number(nvl, "port")) |
|
| 88 |
+ {
|
|
| 89 |
+ return (false); |
|
| 90 |
+ } |
|
| 91 |
+ |
|
| 92 |
+ ss->ss_family = nvlist_get_number(nvl, "af"); |
|
| 93 |
+ |
|
| 94 |
+ switch (ss->ss_family) |
|
| 95 |
+ {
|
|
| 96 |
+ case AF_INET: |
|
| 97 |
+ {
|
|
| 98 |
+ struct sockaddr_in *in = (struct sockaddr_in *)ss; |
|
| 99 |
+ const void *data; |
|
| 100 |
+ size_t len; |
|
| 101 |
+ |
|
| 102 |
+ in->sin_len = sizeof(*in); |
|
| 103 |
+ data = nvlist_get_binary(nvl, "address", &len); |
|
| 104 |
+ assert(len == sizeof(in->sin_addr)); |
|
| 105 |
+ memcpy(&in->sin_addr, data, sizeof(in->sin_addr)); |
|
| 106 |
+ in->sin_port = nvlist_get_number(nvl, "port"); |
|
| 107 |
+ break; |
|
| 108 |
+ } |
|
| 109 |
+ |
|
| 110 |
+ case AF_INET6: |
|
| 111 |
+ {
|
|
| 112 |
+ struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)ss; |
|
| 113 |
+ const void *data; |
|
| 114 |
+ size_t len; |
|
| 115 |
+ |
|
| 116 |
+ in6->sin6_len = sizeof(*in6); |
|
| 117 |
+ data = nvlist_get_binary(nvl, "address", &len); |
|
| 118 |
+ assert(len == sizeof(in6->sin6_addr)); |
|
| 119 |
+ memcpy(&in6->sin6_addr, data, sizeof(in6->sin6_addr)); |
|
| 120 |
+ in6->sin6_port = nvlist_get_number(nvl, "port"); |
|
| 121 |
+ break; |
|
| 122 |
+ } |
|
| 123 |
+ |
|
| 124 |
+ default: |
|
| 125 |
+ return (false); |
|
| 126 |
+ } |
|
| 127 |
+ |
|
| 128 |
+ return (true); |
|
| 129 |
+} |
|
| 130 |
+#endif /* ifdef ENABLE_DCO_FLOAT_FREEBSD */ |
|
| 131 |
+ |
|
| 75 | 132 |
int |
| 76 | 133 |
dco_new_peer(dco_context_t *dco, unsigned int peerid, int sd, |
| 77 | 134 |
struct sockaddr *localaddr, struct sockaddr *remoteaddr, |
| ... | ... |
@@ -573,6 +630,27 @@ dco_do_read(dco_context_t *dco) |
| 573 | 573 |
dco->dco_message_type = OVPN_CMD_SWAP_KEYS; |
| 574 | 574 |
break; |
| 575 | 575 |
|
| 576 |
+#ifdef ENABLE_DCO_FLOAT_FREEBSD |
|
| 577 |
+ case OVPN_NOTIF_FLOAT: {
|
|
| 578 |
+ const nvlist_t *address; |
|
| 579 |
+ |
|
| 580 |
+ if (!nvlist_exists_nvlist(nvl, "address")) |
|
| 581 |
+ {
|
|
| 582 |
+ msg(M_WARN, "Float notification without address"); |
|
| 583 |
+ break; |
|
| 584 |
+ } |
|
| 585 |
+ |
|
| 586 |
+ address = nvlist_get_nvlist(nvl, "address"); |
|
| 587 |
+ if (!nvlist_to_sockaddr(address, &dco->dco_float_peer_ss)) |
|
| 588 |
+ {
|
|
| 589 |
+ msg(M_WARN, "Failed to parse float notification"); |
|
| 590 |
+ break; |
|
| 591 |
+ } |
|
| 592 |
+ dco->dco_message_type = OVPN_CMD_FLOAT_PEER; |
|
| 593 |
+ break; |
|
| 594 |
+ } |
|
| 595 |
+#endif |
|
| 596 |
+ |
|
| 576 | 597 |
default: |
| 577 | 598 |
msg(M_WARN, "Unknown kernel notification %d", type); |
| 578 | 599 |
break; |
| ... | ... |
@@ -36,6 +36,7 @@ enum ovpn_message_type_t {
|
| 36 | 36 |
OVPN_CMD_DEL_PEER, |
| 37 | 37 |
OVPN_CMD_PACKET, |
| 38 | 38 |
OVPN_CMD_SWAP_KEYS, |
| 39 |
+ OVPN_CMD_FLOAT_PEER, |
|
| 39 | 40 |
}; |
| 40 | 41 |
|
| 41 | 42 |
enum ovpn_del_reason_t {
|
| ... | ... |
@@ -55,6 +56,7 @@ typedef struct dco_context {
|
| 55 | 55 |
int dco_message_type; |
| 56 | 56 |
int dco_message_peer_id; |
| 57 | 57 |
int dco_del_peer_reason; |
| 58 |
+ struct sockaddr_storage dco_float_peer_ss; |
|
| 58 | 59 |
uint64_t dco_read_bytes; |
| 59 | 60 |
uint64_t dco_write_bytes; |
| 60 | 61 |
|
| ... | ... |
@@ -3409,7 +3409,7 @@ multi_process_incoming_dco(struct multi_context *m) |
| 3409 | 3409 |
{
|
| 3410 | 3410 |
process_incoming_del_peer(m, mi, dco); |
| 3411 | 3411 |
} |
| 3412 |
-#if defined(TARGET_LINUX) || defined(TARGET_WIN32) |
|
| 3412 |
+#if defined(TARGET_LINUX) || defined(TARGET_WIN32) || defined(TARGET_FREEBSD) |
|
| 3413 | 3413 |
else if (dco->dco_message_type == OVPN_CMD_FLOAT_PEER) |
| 3414 | 3414 |
{
|
| 3415 | 3415 |
ASSERT(mi->context.c2.link_sockets[0]); |