@@ -88,6 +88,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 \
@@ -591,7 +591,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;
@@ -634,13 +634,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;
@@ -673,7 +673,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) */
@@ -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;
@@ -31,6 +31,9 @@ struct context;
#include "networking_sitnl.h"
#elif ENABLE_IPROUTE
#include "networking_iproute2.h"
+#elif defined(TARGET_FREEBSD)
+typedef void *openvpn_net_ctx_t;
+typedef char openvpn_net_iface_t;
#else
/* define mock types to ensure code builds on any platform */
typedef void *openvpn_net_ctx_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
new file mode 100644
@@ -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