Attention is currently required from: Arne Schwabe.

Hello Arne Schwabe,

I'd like you to do a code review.
Please visit

    https://gerrit.openvpn.net/c/openvpn/+/2154?usp=email

to review the following change.


Change subject: route: use the net_ API for routes on FreeBSD and DragonFly
......................................................................

route: use the net_ API for routes on FreeBSD and DragonFly

Add and delete IPv4 and IPv6 routes through net_route_v4/v6_add/del()
on FreeBSD and DragonFly, as on Linux, instead of running route(8)
from route.c. Build networking_freebsd.c for DragonFly as well; -fib
is only passed on FreeBSD.

--route-table stays Linux only. A non-contiguous IPv4 netmask now gets
an error instead of an invalid prefix length. networking_freebsd.c
logs route commands at D_ROUTE, as route.c did. The shared error
messages lose their "Linux" prefix.

Change-Id: I601454a511c9aac4f37d8629b1692266cdbd6885
Signed-off-by: Razvan Cojocaru <[email protected]>
---
M src/openvpn/networking.h
M src/openvpn/networking_freebsd.c
M src/openvpn/route.c
3 files changed, 73 insertions(+), 128 deletions(-)



  git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/54/2154/1

diff --git a/src/openvpn/networking.h b/src/openvpn/networking.h
index 7ad6e2e..4b30092 100644
--- a/src/openvpn/networking.h
+++ b/src/openvpn/networking.h
@@ -30,7 +30,7 @@
 #include "networking_sitnl.h"
 #elif ENABLE_IPROUTE
 #include "networking_iproute2.h"
-#elif defined(TARGET_FREEBSD)
+#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
 typedef void *openvpn_net_ctx_t;
 typedef char openvpn_net_iface_t;
 #else  /* ifdef ENABLE_SITNL */
@@ -236,7 +236,8 @@

 #endif /* ENABLE_SITNL || ENABLE_IPROUTE */

-#if defined(ENABLE_SITNL) || defined(ENABLE_IPROUTE) || defined(TARGET_FREEBSD)
+#if defined(ENABLE_SITNL) || defined(ENABLE_IPROUTE) || 
defined(TARGET_FREEBSD) \
+    || defined(TARGET_DRAGONFLY)
 /**
  * Add a route for an IPv4 address/network
  *
@@ -309,7 +310,7 @@
                      const struct in6_addr *gw, const openvpn_net_iface_t 
*iface, uint32_t table,
                      int metric);

-#endif /* ENABLE_SITNL || ENABLE_IPROUTE || TARGET_FREEBSD */
+#endif /* ENABLE_SITNL || ENABLE_IPROUTE || TARGET_FREEBSD || TARGET_DRAGONFLY 
*/

 #if defined(ENABLE_SITNL) || defined(ENABLE_IPROUTE)

diff --git a/src/openvpn/networking_freebsd.c b/src/openvpn/networking_freebsd.c
index e3697d4..0b2b225 100644
--- a/src/openvpn/networking_freebsd.c
+++ b/src/openvpn/networking_freebsd.c
@@ -6,7 +6,7 @@
 #include "run_command.h"
 #include "networking.h"

-#if defined(TARGET_FREEBSD)
+#if defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)

 static int
 net_route_v4(const char *op, const in_addr_t *dst, int prefixlen, const 
in_addr_t *gw,
@@ -26,6 +26,7 @@
      */
     argv_printf(&argv, "%s %s -net %s/%d", ROUTE_PATH, op,
                 inet_ntop(AF_INET, &_dst, buf1, sizeof(buf1)), prefixlen);
+    /* FIXME -- add on-link support: iface is ignored when gw is set */
     if (gw)
     {
         _gw = ntohl(*gw);
@@ -35,14 +36,22 @@
     {
         argv_printf_cat(&argv, "-iface %s", iface);
     }
+#if 0
+    if (metric >= 0)
+    {
+        argv_printf_cat(&argv, "-rtt %d", metric);
+    }
+#endif
+#if defined(TARGET_FREEBSD)
     /* without -fib, route(8) uses the FIB of the process */
     if (table)
     {
         argv_printf_cat(&argv, "-fib %u", table);
     }
+#endif

-    argv_msg(M_INFO, &argv);
-    bool status = openvpn_execve_check(&argv, NULL, 0, "ERROR: FreeBSD route 
command failed");
+    argv_msg(D_ROUTE, &argv);
+    bool status = openvpn_execve_check(&argv, NULL, 0, "ERROR: route command 
failed");

     argv_free(&argv);

@@ -77,13 +86,15 @@
     {
         argv_printf_cat(&argv, "-iface %s", iface);
     }
+#if defined(TARGET_FREEBSD)
     if (table)
     {
         argv_printf_cat(&argv, "-fib %u", table);
     }
+#endif

-    argv_msg(M_INFO, &argv);
-    bool status = openvpn_execve_check(&argv, NULL, 0, "ERROR: FreeBSD route 
command failed");
+    argv_msg(D_ROUTE, &argv);
+    bool status = openvpn_execve_check(&argv, NULL, 0, "ERROR: route command 
failed");

     argv_free(&argv);

@@ -118,4 +129,4 @@
     return net_route_v6("delete", dst, prefixlen, gw, iface, table, metric);
 }

-#endif /* if defined(TARGET_FREEBSD) */
+#endif /* if defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) */
diff --git a/src/openvpn/route.c b/src/openvpn/route.c
index 53550c4..abf6152 100644
--- a/src/openvpn/route.c
+++ b/src/openvpn/route.c
@@ -103,6 +103,18 @@
 #define RTA_SUCCESS 1 /* route addition succeeded */
 #define RTA_EEXIST  2 /* route not added as it already exists */

+/* Platforms that add and delete routes through the net_ API (networking.h) */
+#if defined(TARGET_LINUX) || defined(TARGET_FREEBSD) || 
defined(TARGET_DRAGONFLY)
+#define ROUTE_NET_API
+#endif
+
+/* --route-table is supported only on Linux */
+#if defined(TARGET_LINUX)
+#define ROUTE_TABLE_ID(id) (id)
+#else
+#define ROUTE_TABLE_ID(id) 0
+#endif
+
 #ifndef TARGET_ANDROID
 static bool
 add_bypass_address(struct route_bypass *rb, const in_addr_t a)
@@ -1436,7 +1448,7 @@

 /* Return true if the "on-link" form of the route should be used.  This is 
when the gateway for
  * a route is specified as an interface rather than an address. */
-#if defined(TARGET_LINUX) || defined(_WIN32) || defined(TARGET_DARWIN)
+#if defined(ROUTE_NET_API) || defined(_WIN32) || defined(TARGET_DARWIN)
 static inline bool
 is_on_link(const int is_local_route, const unsigned int flags, const struct 
route_gateway_info *rgi)
 {
@@ -1462,7 +1474,7 @@
     struct argv argv = argv_new();
     struct gc_arena gc = gc_new();

-#if !defined(TARGET_LINUX)
+#if !defined(ROUTE_NET_API)
     const char *network = print_in_addr_t(r->network, 0, &gc);
 #if !defined(TARGET_AIX)
     const char *netmask = print_in_addr_t(r->netmask, 0, &gc);
@@ -1476,7 +1488,7 @@
         goto done;
     }

-#if defined(TARGET_LINUX)
+#if defined(ROUTE_NET_API)
     const char *iface = NULL;
     int metric = -1;

@@ -1490,18 +1502,26 @@
         metric = r->metric;
     }

+    const int netbits = netmask_to_netbits2(r->netmask);
+    if (netbits < 0)
+    {
+        msg(M_WARN, "ERROR: cannot add route with non-contiguous netmask %s",
+            print_in_addr_t(r->netmask, 0, &gc));
+        status = RTA_ERROR;
+        goto done;
+    }

     status = RTA_SUCCESS;
-    int ret = net_route_v4_add(ctx, &r->network, 
netmask_to_netbits2(r->netmask), &r->gateway,
-                               iface, r->table_id, metric);
+    int ret = net_route_v4_add(ctx, &r->network, netbits, &r->gateway, iface,
+                               ROUTE_TABLE_ID(r->table_id), metric);
     if (ret == -EEXIST)
     {
-        msg(D_ROUTE, "NOTE: Linux route add command failed because route 
exists");
+        msg(D_ROUTE, "NOTE: route add command failed because route exists");
         status = RTA_EEXIST;
     }
     else if (ret < 0)
     {
-        msg(M_WARN, "ERROR: Linux route add command failed");
+        msg(M_WARN, "ERROR: route add command failed");
         status = RTA_ERROR;
     }

@@ -1605,44 +1625,6 @@
     bool ret = openvpn_execve_check(&argv, es, 0, "ERROR: Solaris route add 
command failed");
     status = ret ? RTA_SUCCESS : RTA_ERROR;

-#elif defined(TARGET_FREEBSD)
-
-    argv_printf(&argv, "%s add", ROUTE_PATH);
-
-#if 0
-    if (r->flags & RT_METRIC_DEFINED)
-    {
-        argv_printf_cat(&argv, "-rtt %d", r->metric);
-    }
-#endif
-
-    argv_printf_cat(&argv, "-net %s %s %s", network, gateway, netmask);
-
-    /* FIXME -- add on-link support for FreeBSD */
-
-    argv_msg(D_ROUTE, &argv);
-    bool ret = openvpn_execve_check(&argv, es, 0, "ERROR: FreeBSD route add 
command failed");
-    status = ret ? RTA_SUCCESS : RTA_ERROR;
-
-#elif defined(TARGET_DRAGONFLY)
-
-    argv_printf(&argv, "%s add", ROUTE_PATH);
-
-#if 0
-    if (r->flags & RT_METRIC_DEFINED)
-    {
-        argv_printf_cat(&argv, "-rtt %d", r->metric);
-    }
-#endif
-
-    argv_printf_cat(&argv, "-net %s %s %s", network, gateway, netmask);
-
-    /* FIXME -- add on-link support for Dragonfly */
-
-    argv_msg(D_ROUTE, &argv);
-    bool ret = openvpn_execve_check(&argv, es, 0, "ERROR: DragonFly route add 
command failed");
-    status = ret ? RTA_SUCCESS : RTA_ERROR;
-
 #elif defined(TARGET_DARWIN)

     argv_printf(&argv, "%s add", ROUTE_PATH);
@@ -1708,10 +1690,10 @@
     bool ret = openvpn_execve_check(&argv, es, 0, "ERROR: Haiku inet route add 
command failed");
     status = ret ? RTA_SUCCESS : RTA_ERROR;

-#else  /* if defined(TARGET_LINUX) */
+#else  /* if defined(ROUTE_NET_API) */
     msg(M_FATAL,
         "Sorry, but I don't know how to do 'route' commands on this operating 
system.  Try putting your routes in a --route-up script");
-#endif /* if defined(TARGET_LINUX) */
+#endif /* if defined(ROUTE_NET_API) */

 done:
     if (status == RTA_SUCCESS)
@@ -1786,8 +1768,7 @@
     const char *network = print_in6_addr(r6->network, 0, &gc);
     const char *gateway = print_in6_addr(r6->gateway, 0, &gc);

-#if defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) || 
defined(TARGET_DRAGONFLY) \
-    || defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
+#if defined(TARGET_DARWIN) || defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)

     /* the BSD platforms cannot specify gateway and interface independently,
      * but for link-local destinations, we MUST specify the interface, so
@@ -1839,7 +1820,7 @@
         goto done;
     }

-#if defined(TARGET_LINUX)
+#if defined(ROUTE_NET_API)
     int metric = -1;
     if ((r6->flags & RT_METRIC_DEFINED) && (r6->metric > 0))
     {
@@ -1848,15 +1829,15 @@

     status = RTA_SUCCESS;
     int ret = net_route_v6_add(ctx, &r6->network, r6->netbits, gateway_needed 
? &r6->gateway : NULL,
-                               device, r6->table_id, metric);
+                               device, ROUTE_TABLE_ID(r6->table_id), metric);
     if (ret == -EEXIST)
     {
-        msg(D_ROUTE, "NOTE: Linux route add command failed because route 
exists");
+        msg(D_ROUTE, "NOTE: route add command failed because route exists");
         status = RTA_EEXIST;
     }
     else if (ret < 0)
     {
-        msg(M_WARN, "ERROR: Linux route add command failed");
+        msg(M_WARN, "ERROR: route add command failed");
         status = RTA_ERROR;
     }

@@ -1902,23 +1883,6 @@
     bool ret = openvpn_execve_check(&argv, es, 0, "ERROR: Solaris route add 
-inet6 command failed");
     status = ret ? RTA_SUCCESS : RTA_ERROR;

-#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
-
-    argv_printf(&argv, "%s add -inet6 %s/%d", ROUTE_PATH, network, 
r6->netbits);
-
-    if (gateway_needed)
-    {
-        argv_printf_cat(&argv, "%s", gateway);
-    }
-    else
-    {
-        argv_printf_cat(&argv, "-iface %s", device);
-    }
-
-    argv_msg(D_ROUTE, &argv);
-    bool ret = openvpn_execve_check(&argv, es, 0, "ERROR: *BSD route add 
-inet6 command failed");
-    status = ret ? RTA_SUCCESS : RTA_ERROR;
-
 #elif defined(TARGET_DARWIN)

     argv_printf(&argv, "%s add -inet6 %s -prefixlen %d", ROUTE_PATH, network, 
r6->netbits);
@@ -1969,10 +1933,10 @@
     bool ret = openvpn_execve_check(&argv, es, 0, "ERROR: Haiku inet6 route 
add command failed");
     status = ret ? RTA_SUCCESS : RTA_ERROR;

-#else  /* if defined(TARGET_LINUX) */
+#else  /* if defined(ROUTE_NET_API) */
     msg(M_FATAL,
         "Sorry, but I don't know how to do 'route ipv6' commands on this 
operating system.  Try putting your routes in a --route-up script");
-#endif /* if defined(TARGET_LINUX) */
+#endif /* if defined(ROUTE_NET_API) */

 done:
     if (status == RTA_SUCCESS)
@@ -1995,13 +1959,13 @@
 delete_route(struct route_ipv4 *r, const struct tuntap *tt, unsigned int flags,
              const struct route_gateway_info *rgi, const struct env_set *es, 
openvpn_net_ctx_t *ctx)
 {
-#if !defined(TARGET_LINUX)
+#if !defined(ROUTE_NET_API)
     const char *network;
 #if !defined(TARGET_AIX)
     const char *netmask;
 #endif
     const char *gateway;
-#else /* if !defined(TARGET_LINUX) */
+#else /* if !defined(ROUTE_NET_API) */
     int metric;
 #endif
     int is_local_route;
@@ -2014,7 +1978,7 @@
     struct gc_arena gc = gc_new();
     struct argv argv = argv_new();

-#if !defined(TARGET_LINUX)
+#if !defined(ROUTE_NET_API)
     network = print_in_addr_t(r->network, 0, &gc);
 #if !defined(TARGET_AIX)
     netmask = print_in_addr_t(r->netmask, 0, &gc);
@@ -2028,7 +1992,7 @@
         goto done;
     }

-#if defined(TARGET_LINUX)
+#if defined(ROUTE_NET_API)
     metric = -1;
     if (r->flags & RT_METRIC_DEFINED)
     {
@@ -2036,10 +2000,10 @@
     }

     if (net_route_v4_del(ctx, &r->network, netmask_to_netbits2(r->netmask), 
&r->gateway, NULL,
-                         r->table_id, metric)
+                         ROUTE_TABLE_ID(r->table_id), metric)
         < 0)
     {
-        msg(M_WARN, "ERROR: Linux route delete command failed");
+        msg(M_WARN, "ERROR: route delete command failed");
     }
 #elif defined(_WIN32)

@@ -2089,20 +2053,6 @@
     argv_msg(D_ROUTE, &argv);
     openvpn_execve_check(&argv, es, 0, "ERROR: Solaris route delete command 
failed");

-#elif defined(TARGET_FREEBSD)
-
-    argv_printf(&argv, "%s delete -net %s %s %s", ROUTE_PATH, network, 
gateway, netmask);
-
-    argv_msg(D_ROUTE, &argv);
-    openvpn_execve_check(&argv, es, 0, "ERROR: FreeBSD route delete command 
failed");
-
-#elif defined(TARGET_DRAGONFLY)
-
-    argv_printf(&argv, "%s delete -net %s %s %s", ROUTE_PATH, network, 
gateway, netmask);
-
-    argv_msg(D_ROUTE, &argv);
-    openvpn_execve_check(&argv, es, 0, "ERROR: DragonFly route delete command 
failed");
-
 #elif defined(TARGET_DARWIN)

     if (is_on_link(is_local_route, flags, rgi))
@@ -2150,10 +2100,10 @@
     argv_msg(D_ROUTE, &argv);
     openvpn_execve_check(&argv, es, 0, "ERROR: Haiku inet route delete command 
failed");

-#else  /* if defined(TARGET_LINUX) */
+#else  /* if defined(ROUTE_NET_API) */
     msg(M_FATAL,
         "Sorry, but I don't know how to do 'route' commands on this operating 
system.  Try putting your routes in a --route-up script");
-#endif /* if defined(TARGET_LINUX) */
+#endif /* if defined(ROUTE_NET_API) */

 done:
     r->flags &= ~RT_ADDED;
@@ -2175,7 +2125,7 @@
     }

 #if !defined(_WIN32)
-#if !defined(TARGET_LINUX)
+#if !defined(ROUTE_NET_API)
     const char *gateway;
 #endif
 #if !defined(TARGET_SOLARIS)
@@ -2202,12 +2152,11 @@
     struct argv argv = argv_new();

     network = print_in6_addr(r6->network, 0, &gc);
-#if !defined(TARGET_LINUX) && !defined(_WIN32)
+#if !defined(ROUTE_NET_API) && !defined(_WIN32)
     gateway = print_in6_addr(r6->gateway, 0, &gc);
 #endif

-#if defined(TARGET_DARWIN) || defined(TARGET_FREEBSD) || 
defined(TARGET_DRAGONFLY) \
-    || defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
+#if defined(TARGET_DARWIN) || defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)

     /* the BSD platforms cannot specify gateway and interface independently,
      * but for link-local destinations, we MUST specify the interface, so
@@ -2225,7 +2174,7 @@

     msg(D_ROUTE, "delete_route_ipv6(%s/%u)", network, r6->netbits);

-#if defined(TARGET_LINUX)
+#if defined(ROUTE_NET_API)
     int metric = -1;
     if ((r6->flags & RT_METRIC_DEFINED) && (r6->metric > 0))
     {
@@ -2233,10 +2182,10 @@
     }

     if (net_route_v6_del(ctx, &r6->network, r6->netbits, gateway_needed ? 
&r6->gateway : NULL,
-                         device, r6->table_id, metric)
+                         device, ROUTE_TABLE_ID(r6->table_id), metric)
         < 0)
     {
-        msg(M_WARN, "ERROR: Linux route v6 delete command failed");
+        msg(M_WARN, "ERROR: route v6 delete command failed");
     }

 #elif defined(_WIN32)
@@ -2258,22 +2207,6 @@
     argv_msg(D_ROUTE, &argv);
     openvpn_execve_check(&argv, es, 0, "ERROR: Solaris route delete -inet6 
command failed");

-#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
-
-    argv_printf(&argv, "%s delete -inet6 %s/%d", ROUTE_PATH, network, 
r6->netbits);
-
-    if (gateway_needed)
-    {
-        argv_printf_cat(&argv, "%s", gateway);
-    }
-    else
-    {
-        argv_printf_cat(&argv, "-iface %s", device);
-    }
-
-    argv_msg(D_ROUTE, &argv);
-    openvpn_execve_check(&argv, es, 0, "ERROR: *BSD route delete -inet6 
command failed");
-
 #elif defined(TARGET_DARWIN)

     argv_printf(&argv, "%s delete -inet6 %s -prefixlen %d", ROUTE_PATH, 
network, r6->netbits);
@@ -2326,10 +2259,10 @@
     argv_msg(D_ROUTE, &argv);
     openvpn_execve_check(&argv, es, 0, "ERROR: Haiku inet6 route delete 
command failed");

-#else  /* if defined(TARGET_LINUX) */
+#else  /* if defined(ROUTE_NET_API) */
     msg(M_FATAL,
         "Sorry, but I don't know how to do 'route ipv6' commands on this 
operating system.  Try putting your routes in a --route-down script");
-#endif /* if defined(TARGET_LINUX) */
+#endif /* if defined(ROUTE_NET_API) */

     argv_free(&argv);
     gc_free(&gc);

--
To view, visit https://gerrit.openvpn.net/c/openvpn/+/2154?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.openvpn.net/settings?usp=email

Gerrit-MessageType: newchange
Gerrit-Project: openvpn
Gerrit-Branch: master
Gerrit-Change-Id: I601454a511c9aac4f37d8629b1692266cdbd6885
Gerrit-Change-Number: 2154
Gerrit-PatchSet: 1
Gerrit-Owner: Răzvan Cojocaru <[email protected]>
Gerrit-Reviewer: Arne Schwabe <[email protected]>
Gerrit-CC: openvpn-devel <[email protected]>
Gerrit-Attention: Arne Schwabe <[email protected]>
_______________________________________________
Openvpn-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel

Reply via email to