]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Support creating iroute route entries on FreeBSD
authorKristof Provost <kp@FreeBSD.org>
Fri, 12 Aug 2022 13:41:54 +0000 (15:41 +0200)
committerGert Doering <gert@greenie.muc.de>
Sat, 20 Aug 2022 10:27:05 +0000 (12:27 +0200)
Signed-off-by: Kristof Provost <kprovost@netgate.com>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <20220812134154.16729-3-kprovost@netgate.com>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg24895.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
src/openvpn/Makefile.am
src/openvpn/dco.c
src/openvpn/dco_freebsd.h
src/openvpn/networking.h
src/openvpn/networking_freebsd.c [new file with mode: 0644]

index 936d038c763c18d838054d8242638b8d6601a16c..5dbff4c6cf334c8db13077047d5d93c433533a77 100644 (file)
@@ -90,6 +90,7 @@ openvpn_SOURCES = \
        mtu.c mtu.h \
        mudp.c mudp.h \
        multi.c multi.h \
+       networking_freebsd.c \
        networking_iproute2.c networking_iproute2.h \
        networking_sitnl.c networking_sitnl.h \
        networking.h \
index 4190747ad1c3d6f63bbe30212708d791a00a2e9c..99b544a5f69336262167eb25247e8feb246b0a29 100644 (file)
@@ -583,7 +583,7 @@ void
 dco_install_iroute(struct multi_context *m, struct multi_instance *mi,
                    struct mroute_addr *addr)
 {
-#if defined(TARGET_LINUX)
+#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
     if (!dco_enabled(&m->top.options))
     {
         return;
@@ -626,13 +626,13 @@ dco_install_iroute(struct multi_context *m, struct multi_instance *mi,
                          &mi->context.c2.push_ifconfig_local, dev, 0,
                          DCO_IROUTE_METRIC);
     }
-#endif /* if defined(TARGET_LINUX) */
+#endif /* if defined(TARGET_LINUX) || defined(TARGET_FREEBSD) */
 }
 
 void
 dco_delete_iroutes(struct multi_context *m, struct multi_instance *mi)
 {
-#if defined(TARGET_LINUX)
+#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD)
     if (!dco_enabled(&m->top.options))
     {
         return;
@@ -665,7 +665,7 @@ dco_delete_iroutes(struct multi_context *m, struct multi_instance *mi)
                              0, DCO_IROUTE_METRIC);
         }
     }
-#endif /* if defined(TARGET_LINUX) */
+#endif /* if defined(TARGET_LINUX) || defined(TARGET_FREEBSD) */
 }
 
 #endif /* defined(ENABLE_DCO) */
index 3594f22923742a486a928a64f8990fe60b0c60d9..7de1169734d119222251e176bb4d2a5f2408fb7b 100644 (file)
@@ -27,6 +27,8 @@
 
 #include "ovpn_dco_freebsd.h"
 
+#define DCO_IROUTE_METRIC   100
+
 typedef enum ovpn_key_slot dco_key_slot_t;
 typedef enum ovpn_key_cipher dco_cipher_t;
 
index cf6d39acb30030de8f357625dc4734e22e73a852..225cfaee29f45adc02d7b59dc97a16eeea5786fd 100644 (file)
@@ -31,7 +31,10 @@ struct context;
 #include "networking_sitnl.h"
 #elif ENABLE_IPROUTE
 #include "networking_iproute2.h"
-#else
+#elif defined(TARGET_FREEBSD)
+typedef void *openvpn_net_ctx_t;
+typedef char openvpn_net_iface_t;
+#else  /* ifdef ENABLE_SITNL */
 /* define mock types to ensure code builds on any platform */
 typedef void *openvpn_net_ctx_t;
 typedef void *openvpn_net_iface_t;
@@ -238,7 +241,9 @@ int net_addr_ptp_v4_del(openvpn_net_ctx_t *ctx,
                         const openvpn_net_iface_t *iface,
                         const in_addr_t *local, const in_addr_t *remote);
 
+#endif /* ENABLE_SITNL || ENABLE_IPROUTE */
 
+#if defined(ENABLE_SITNL) || defined(ENABLE_IPROUTE) || defined(TARGET_FREEBSD)
 /**
  * Add a route for an IPv4 address/network
  *
@@ -315,6 +320,10 @@ int net_route_v6_del(openvpn_net_ctx_t *ctx, const struct in6_addr *dst,
                      const openvpn_net_iface_t *iface,
                      uint32_t table, int metric);
 
+#endif /* ENABLE_SITNL || ENABLE_IPROUTE || TARGET_FREEBSD */
+
+#if defined(ENABLE_SITNL) || defined(ENABLE_IPROUTE)
+
 /**
  * Retrieve the gateway and outgoing interface for the specified IPv4
  * address/network
diff --git a/src/openvpn/networking_freebsd.c b/src/openvpn/networking_freebsd.c
new file mode 100644 (file)
index 0000000..5fcb738
--- /dev/null
@@ -0,0 +1,101 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#elif defined(_MSC_VER)
+#include "config-msvc.h"
+#endif
+#include "syshead.h"
+#include "errlevel.h"
+#include "run_command.h"
+#include "networking.h"
+
+#if defined(TARGET_FREEBSD)
+
+static int
+net_route_v4(const char *op, const in_addr_t *dst, int prefixlen,
+             const in_addr_t *gw, const char *iface, uint32_t table,
+             int metric)
+{
+    char buf1[16], buf2[16];
+    in_addr_t _dst, _gw;
+    struct argv argv = argv_new();
+    bool status;
+
+    _dst = ntohl(*dst);
+    _gw = ntohl(*gw);
+
+    argv_printf(&argv, "%s %s",
+                ROUTE_PATH, op);
+    argv_printf_cat(&argv, "-net %s/%d %s -fib %d",
+                    inet_ntop(AF_INET, &_dst, buf1, sizeof(buf1)),
+                    prefixlen,
+                    inet_ntop(AF_INET, &_gw, buf2, sizeof(buf2)),
+                    table);
+
+    argv_msg(M_INFO, &argv);
+    status = openvpn_execve_check(&argv, NULL, 0,
+                                  "ERROR: FreeBSD route add command failed");
+
+    argv_free(&argv);
+
+    return (!status);
+}
+
+static int
+net_route_v6(const char *op, const struct in6_addr *dst,
+             int prefixlen, const struct in6_addr *gw, const char *iface,
+             uint32_t table, int metric)
+{
+    char buf1[64], buf2[64];
+    struct argv argv = argv_new();
+    bool status;
+
+    argv_printf(&argv, "%s -6 %s",
+                ROUTE_PATH, op);
+    argv_printf_cat(&argv, "-net %s/%d %s -fib %d",
+                    inet_ntop(AF_INET6, dst, buf1, sizeof(buf1)),
+                    prefixlen,
+                    inet_ntop(AF_INET6, gw, buf2, sizeof(buf2)),
+                    table);
+
+    argv_msg(M_INFO, &argv);
+    status = openvpn_execve_check(&argv, NULL, 0,
+                                  "ERROR: FreeBSD route add command failed");
+
+    argv_free(&argv);
+
+    return (!status);
+}
+
+int
+net_route_v4_add(openvpn_net_ctx_t *ctx, const in_addr_t *dst, int prefixlen,
+                 const in_addr_t *gw, const char *iface, uint32_t table,
+                 int metric)
+{
+    return net_route_v4("add", dst, prefixlen, gw, iface, table, metric);
+}
+
+int
+net_route_v6_add(openvpn_net_ctx_t *ctx, const struct in6_addr *dst,
+                 int prefixlen, const struct in6_addr *gw, const char *iface,
+                 uint32_t table, int metric)
+{
+    return net_route_v6("add", dst, prefixlen, gw, iface, table, metric);
+}
+
+int
+net_route_v4_del(openvpn_net_ctx_t *ctx, const in_addr_t *dst, int prefixlen,
+                 const in_addr_t *gw, const char *iface, uint32_t table,
+                 int metric)
+{
+    return net_route_v4("del", dst, prefixlen, gw, iface, table, metric);
+}
+
+int
+net_route_v6_del(openvpn_net_ctx_t *ctx, const struct in6_addr *dst,
+                 int prefixlen, const struct in6_addr *gw, const char *iface,
+                 uint32_t table, int metric)
+{
+    return net_route_v6("del", dst, prefixlen, gw, iface, table, metric);
+}
+
+#endif /* if defined(TARGET_FREEBSD) */