add netlink support for Linux
cover add netlink support for Linux
Hi all,
finally this is the first "real" patchset that introduces native netlink support for the Linux platform.
- Description:
At the moment openvpn operates on the tun interface and on the routing table by directly invoking the "ip" command (or ifconfig/route if nettools is selected at compile time).
With this patchset, openvpn would not need to fork new processes to run the "ip" binary any longer, but would directly talk to the kernel by means of the netlink interface.
This means simpler/cleaner code and, possibly, faster execution.
Another important advantage of this change is that the openvpn process will be in charge of directly working with the kernel, thus it can be granted special capabilities so that interfaces/routes operations can be carried out even when running as non-root.
Christian Hesse is working on a follow-up patch to properly allow the above.
This patchset also offers a first step towards a refactoring of the tun.c and route.c code.
The idea moving forward is to drop nettools support once this patchset is merged, but to retain support for ip and the --ifconfig/route-noexec options.
The last patch implements a little framework to test sitnl functionalities. Some functions are actually tested in the framework, but more should be added in the future.
- Git:
This code can also be found on GitHub (based on latest master) at:
https://github.com/ordex/openvpn/tree/sitnl
Regards,
Antonio Quartulli (8):
implement platform generic networking API
implement networking API for iproute2
tun.c: use new networking API to handle tun interface on Linux route.c: use new networking API to handle routing table on Linux introduce sitnl: Simplified Interface To NetLink
configure: don't check for route/ifconfig on linux route.c: use sitnl to implement get_default_gateway_ipv6() unit tests: implement test for sitnl
configure.ac | 5 +- src/openvpn/Makefile.am | 1 + src/openvpn/errlevel.h | 1 + src/openvpn/networking.h | 225 ++++ src/openvpn/networking_ip.c | 368 ++++++ src/openvpn/networking_sitnl.c | 1206 ++++++++++++++++++++ src/openvpn/route.c | 364 ++---- src/openvpn/sitnl.h | 217 ++++ src/openvpn/tun.c | 199 +--- tests/Makefile.am | 3 +- tests/t_net.sh | 170 +++ tests/unit_tests/openvpn/Makefile.am | 23 +- tests/unit_tests/openvpn/test_networking.c | 217 ++++ 13 files changed, 2559 insertions(+), 440 deletions(-) create mode 100644 src/openvpn/networking.h create mode 100644 src/openvpn/networking_ip.c create mode 100644 src/openvpn/networking_sitnl.c create mode 100644 src/openvpn/sitnl.h create mode 100755 tests/t_net.sh create mode 100644 tests/unit_tests/openvpn/test_networking.c
Signature · 1 line
2.17.0
PATCH 1/8 implement platform generic networking API
tun.c and route.c contain all the code used by openvpn to manage the tun interface and the routing table on all the supported platforms.
Across the years, this resulted in a longer functions and series of ifdefs.
This patch introduces a new "networking API" which aims at creating a simple abstraction between the tun/route logic and the platform dependent code.
The is API expected to be implemented outside of tun.c/route.c by using platform specific functionalities.
--- src/openvpn/Makefile.am | 1 + src/openvpn/networking.h | 225 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 226 insertions(+) create mode 100644 src/openvpn/networking.h
src/openvpn/Makefile.am +1 -0
@@ -80,6 +80,7 @@ openvpn_SOURCES = \ mtu.c mtu.h \ mudp.c mudp.h \ multi.c multi.h \ + networking.h \ ntlm.c ntlm.h \ occ.c occ.h occ-inline.h \ openssl_compat.h \
src/openvpn/networking.h new file +225 -0
225 lines not on this page · raw message
Signature · 1 line
2.17.0
Re: [Openvpn-devel] [PATCH 1/8] implement platform generic networking API
for the records:
the new networking API has been discussed during our latest community meeting and some changes have been suggested by other developers.
A new patchset will be sent soonish.
Cheers,
Quoted 265 lines · Antonio Quartulli
tun.candroute.ccontain all the code used by openvpn to manage the tun interface and the routing table on all the supported platforms.Across the years, this resulted in a longer functions and series of ifdefs.
This patch introduces a new "networking API" which aims at creating a simple abstraction between the tun/route logic and the platform dependent code.
The is API expected to be implemented outside of
tun.c/route.cby using platform specific functionalities.Signed-off-by Antonio Quartulli <[email protected]...>--- src/openvpn/Makefile.am | 1 + src/openvpn/networking.h | 225 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 226 insertions(+) create mode 100644 src/openvpn/networking.hsrc/openvpn/Makefile.am +1
-0@@ -80,6 +80,7 @@ openvpn_SOURCES = \ mtu.c mtu.h \ mudp.c mudp.h \ multi.c multi.h \ + networking.h \ ntlm.c ntlm.h \ occ.c occ.h occ-inline.h \ openssl_compat.h \src/openvpn/networking.h new file +225
-0@@ -0,0 +1,225 @@ +/* +* Generic interface to platform specific networking code +* +* Copyright (C) 2016-2018 Antonio Quartulli <[email protected]...> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 +* as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program (see the file COPYING included with this +* distribution); if not, write to the Free Software Foundation, Inc., +* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef NETWORKING_H_ +#define NETWORKING_H_ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + +#ifdef TARGET_LINUX + +#include <stdbool.h> +#include <netinet/in.h> + +/** +* Bring interface up or down. +* +* @param iface the interface to modify +* @param up true if the interface has to be brought up, false otherwise +* +* @return 0 on success, a negative error code otherwise +*/ +int net_iface_up (const char *iface,bool up); + +/** +* Set the MTU for an interface +* +* @param iface the interface to modify +* @param mtru the new MTU +* +* @return 0 on success, a negative error code otherwise +*/ +int net_iface_mtu_set (const char *iface,uint32_t mtu); + +/** +* Add an IPv4 address to an interface +* +* @param iface the interface where the address has to be added +* @param addr the address to add +* @param prefixlen the prefix length of the network associated with the address +* @param broadcast the broadcast address to configure on the interface +* +* @return 0 on success, a negative error code otherwise +*/ +int net_addr_v4_add (const char *iface,const in_addr_t *addr,int prefixlen, +const in_addr_t *broadcast); + +/** +* Add an IPv6 address to an interface +* +* @param iface the interface where the address has to be added +* @param addr the address to add +* @param prefixlen the prefix length of the network associated with the address +* +* @return 0 on success, a negative error code otherwise +*/ + +int net_addr_v6_add (const char *iface,const struct in6_addr *addr, +int prefixlen); + +/** +* Remove an IPv4 from an interface +* +* @param iface the interface to remove the address from +* @param prefixlen the prefix length of the network associated with the address +* +* @return 0 on success, a negative error code otherwise +*/ +int net_addr_v4_del (const char *iface,const in_addr_t *addr,int prefixlen); + +/** +* Remove an IPv6 from an interface +* +* @param iface the interface to remove the address from +* @param prefixlen the prefix length of the network associated with the address +* +* @return 0 on success, a negative error code otherwise +*/ +int net_addr_v6_del (const char *iface,const struct in6_addr *addr, +int prefixlen); + +/** +* Add a point-to-point IPv4 address to an interface +* +* @param iface the interface where the address has to be added +* @param local the address to add +* @param remote the associated p-t-p remote address +* +* @return 0 on success, a negative error code otherwise +*/ +int net_addr_ptp_v4_add (const char *iface,const in_addr_t *local, +const in_addr_t *remote); + +/** +* Remove a point-to-point IPv4 address from an interface +* +* @param iface the interface to remove the address from +* @param local the address to remove +* @param remote the associated p-t-p remote address +* +* @return 0 on success, a negative error code otherwise +*/ +int net_addr_ptp_v4_del (const char *iface,const in_addr_t *local, +const in_addr_t *remote); + + +/** +* Add a route for an IPv4 address/network +* +* @param dst the destination of the route +* @param prefixlen the length of the prefix of the destination +* @param gw the gateway for this route +* @param iface the interface for this route (can be NULL) +* @param table the table to add this route to (if 0, will be added to the +* main table) +* @param metric the metric associated with the route +* +* @return 0 on success, a negative error code otherwise +*/ +int net_route_v4_add (const in_addr_t *dst,int prefixlen, +const in_addr_t *gw,const char *iface,uint32_t table, +int metric); + +/** +* Add a route for an IPv6 address/network +* +* @param dst the destination of the route +* @param prefixlen the length of the prefix of the destination +* @param gw the gateway for this route +* @param iface the interface for this route (can be NULL) +* @param table the table to add this route to (if 0, will be added to the +* main table) +* @param metric the metric associated with the route +* +* @return 0 on success, a negative error code otherwise +*/ +int net_route_v6_add (const struct in6_addr *dst,int prefixlen, +const struct in6_addr *gw,const char *iface, +uint32_t table,int metric); + +/** +* Delete a route for an IPv4 address/network +* +* @param dst the destination of the route +* @param prefixlen the length of the prefix of the destination +* @param gw the gateway for this route +* @param iface the interface for this route (can be NULL) +* @param table the table to add this route to (if 0, will be added to the +* main table) +* @param metric the metric associated with the route +* +* @return 0 on success, a negative error code otherwise +*/ +int net_route_v4_del (const in_addr_t *dst,int prefixlen, +const in_addr_t *gw,const char *iface,uint32_t table, +int metric); + +/** +* Delete a route for an IPv4 address/network +* +* @param dst the destination of the route +* @param prefixlen the length of the prefix of the destination +* @param gw the gateway for this route +* @param iface the interface for this route (can be NULL) +* @param table the table to add this route to (if 0, will be added to the +* main table) +* @param metric the metric associated with the route +* +* @return 0 on success, a negative error code otherwise +*/ +int net_route_v6_del (const struct in6_addr *dst,int prefixlen, +const struct in6_addr *gw,const char *iface, +uint32_t table,int metric); + +/** +* Retrieve the gateway and outgoing interface for the specified IPv4 +* address/network +* +* @param dst The destination to lookup +* @param prefixlen The length of the prefix of the destination +* @param best_gw Location where the retrieved GW has to be stored +* @param best_iface Location where the retrieved interface has to be stored +* +* @return 0 on success, a negative error code otherwise +*/ +int net_route_v4_best_gw (const in_addr_t *dst,int prefixlen, +in_addr_t *best_gw,char *best_iface); + +/** +* Retrieve the gateway and outgoing interface for the specified IPv6 +* address/network +* +* @param dst The destination to lookup +* @param prefixlen The length of the prefix of the destination +* @param best_gw Location where the retrieved GW has to be stored +* @param best_iface Location where the retrieved interface has to be stored +* +* @return 0 on success, a negative error code otherwise +*/ +int net_route_v6_best_gw (const struct in6_addr *dst,int prefixlen, +struct in6_addr *best_gw,char *best_iface); + +#endif /* TARGET_LINUX */ + +#endif /* NETWORKING_H_ */
Signature · 1 line
Antonio Quartulli
PATCH 2/8 implement networking API for iproute2
In reply to Antonio Quartulliiproute2 is the first user of the new networking API and its one of the two currently supported functionalities on Linux (the other being net-tools).
This patch simply copies the current code from tun.c/route.c to networking_ip.c without introducing any funcional change to the code.
--- src/openvpn/Makefile.am | 2 +- src/openvpn/networking_ip.c | 369 ++++++++++++++++++++++++++++++++++++ 2 files changed, 370 insertions(+), 1 deletion(-) create mode 100644 src/openvpn/networking_ip.c
src/openvpn/Makefile.am +1 -1
@@ -80,7 +80,7 @@ openvpn_SOURCES = \ mtu.c mtu.h \ mudp.c mudp.h \ multi.c multi.h \ - networking.h \ + networking_ip.c networking.h \ ntlm.c ntlm.h \ occ.c occ.h occ-inline.h \ openssl_compat.h \
src/openvpn/networking_ip.c new file +369 -0
369 lines not on this page · raw message
Signature · 1 line
2.17.0
Re: [Openvpn-devel] [PATCH 2/8] implement networking API for iproute2
Hi,
there is one little "open" thing in this patch that I wanted to highlight. See below:
Quoted 2 lines · Antonio Quartulli
(quoted diff) +2
-0+static struct env_set *es = NULL; +
.....
Quoted 1 line
+
openvpn_execve_check(&argv, es, S_FATAL, "Linux ip link set failed");
Right now the code initializing the environment set to be passed to openvpn_execve() with NULL.
This means that not ENV is passed to the iproute commands.
This behaviour does not reflect the original one as in the current code we always pass the complete ENV coming from the openvpn context.
This begs two questions:
1) how can we pass the env_set without making the API dependent on that? (this is really just an iproute thing, unlreated to the networking side of things)
2) do we really need to pass the entire ENV to iproute commands?
I understand it is needed for the scripts, but why passing it to these commands too?
Shouldn't we expect them to work by using only the commandline arguments?
Cheers,
Signature · 1 line
Antonio Quartulli
PATCH 3/8 tun.c: use new networking API to handle tun interface on Linux
In reply to Antonio QuartulliBy switching to the networking API (for Linux) openvpn will now use any of the available implementations to handle the tun interface.
At the moment only iproute2 is implemented.
--- src/openvpn/tun.c | 199 ++++++++++++++-------------------------------- 1 file changed, 58 insertions(+), 141 deletions(-)
src/openvpn/tun.c +58 -141
@@ -46,6 +46,7 @@#include "route.h" #include "win32.h" #include "block_dns.h" +#include "networking.h" #include "memdbg.h"
@@ -883,10 +884,12 @@ do_ifconfig(struct tuntap *tt,if (tt->did_ifconfig_setup) {bool tun = false; +#if !defined(TARGET_LINUX )const char *ifconfig_local =NULL ;const char *ifconfig_remote_netmask =NULL ;const char *ifconfig_broadcast =NULL ;const char *ifconfig_ipv6_local =NULL ; +#endif bool do_ipv6 = false;struct argv argv =argv_new ();
@@ -898,18 +901,23 @@ do_ifconfig(struct tuntap *tt,*/ tun =is_tun_p2p (tt); +#if !defined(TARGET_LINUX )/* * Set ifconfig parameters */ ifconfig_local =print_in_addr_t (tt->local,0 , &gc); ifconfig_remote_netmask =print_in_addr_t (tt->remote_netmask,0 , &gc); +#endif if (tt->did_ifconfig_ipv6_setup) { +#if !defined(TARGET_LINUX ) ifconfig_ipv6_local =print_in6_addr (tt->local_ipv6,0 , &gc); +#endif do_ipv6 = true; } +#if !defined(TARGET_LINUX )/* * If TAP-style device, generate broadcast address. */
@@ -917,6 +925,7 @@ do_ifconfig(struct tuntap *tt, { ifconfig_broadcast =print_in_addr_t (tt->broadcast,0 , &gc); } +#endif #ifdef ENABLE_MANAGEMENT if (management)
@@ -933,102 +942,42 @@ do_ifconfig(struct tuntap *tt,#if defined(TARGET_LINUX ) -#ifdef ENABLE_IPROUTE -/* -* Set the MTU for the device -*/ -argv_printf (&argv, -"%s link set dev %s up mtu %d" , - iproute_path, - actual, - tun_mtu - ); -argv_msg (M_INFO , &argv); -openvpn_execve_check (&argv, es,S_FATAL ,"Linux ip link set failed" ); - -if (tun) - { - -/* -* Set the address for the device -*/ -argv_printf (&argv, -"%s addr add dev %s local %s peer %s" , - iproute_path, - actual, - ifconfig_local, - ifconfig_remote_netmask - ); -argv_msg (M_INFO , &argv); -openvpn_execve_check (&argv, es,S_FATAL ,"Linux ip addr add failed" ); - } -else +if (net_iface_mtu_set (actual, tun_mtu) <0 ) { -argv_printf (&argv, -"%s addr add dev %s %s/%d broadcast %s" , - iproute_path, - actual, - ifconfig_local, -netmask_to_netbits2 (tt->remote_netmask), - ifconfig_broadcast - ); -argv_msg (M_INFO , &argv); -openvpn_execve_check (&argv, es,S_FATAL ,"Linux ip addr add failed" ); +msg (M_FATAL ,"Linux can't set mtu (%d) on %s" , tun_mtu, actual); } -if (do_ipv6) + +if (net_iface_up (actual, true) <0 ) { -argv_printf ( &argv, -"%s -6 addr add %s/%d dev %s" , - iproute_path, - ifconfig_ipv6_local, - tt->netbits_ipv6, - actual - ); -argv_msg (M_INFO , &argv); -openvpn_execve_check (&argv, es,S_FATAL ,"Linux ip -6 addr add failed" ); +msg (M_FATAL ,"Linux can't bring %s up" , actual); } - tt->did_ifconfig = true; -#else /* ifdef ENABLE_IPROUTE */ +if (tun) { -argv_printf (&argv, -"%s %s %s pointopoint %s mtu %d" , -IFCONFIG_PATH , - actual, - ifconfig_local, - ifconfig_remote_netmask, - tun_mtu - ); +if (net_addr_ptp_v4_add (actual, &tt->local, + &tt->remote_netmask) <0 ) + { +msg (M_FATAL ,"Linux can't add IP to TUN interface %s" , actual); + } }else { -argv_printf (&argv, -"%s %s %s netmask %s mtu %d broadcast %s" , -IFCONFIG_PATH , - actual, - ifconfig_local, - ifconfig_remote_netmask, - tun_mtu, - ifconfig_broadcast - ); +if (net_addr_v4_add (actual, &tt->local, +netmask_to_netbits2 (tt->remote_netmask), + &tt->remote_netmask) <0 ) + { +msg (M_FATAL ,"Linux can't add IP to TAP interface %s" , actual); + } } -argv_msg (M_INFO , &argv); -openvpn_execve_check (&argv, es,S_FATAL ,"Linux ifconfig failed" );if (do_ipv6) { -argv_printf (&argv, -"%s %s add %s/%d" , -IFCONFIG_PATH , - actual, - ifconfig_ipv6_local, - tt->netbits_ipv6 - ); -argv_msg (M_INFO , &argv); -openvpn_execve_check (&argv, es,S_FATAL ,"Linux ifconfig inet6 failed" ); +if (net_addr_v6_add (actual, &tt->local_ipv6, tt->netbits_ipv6) <0 ) + { +msg (M_FATAL ,"Linux can't add IPv6 to interface %s" , actual); + } } tt->did_ifconfig = true; -#endif /*ENABLE_IPROUTE*/ #elif defined(TARGET_ANDROID )if (do_ipv6)
@@ -2103,77 +2052,45 @@ tuncfg(const char *dev, const char *dev_type, const char *dev_node, int persist_void close_tun (struct tuntap *tt) { -if (tt) +if (!tt) { -if (tt->type !=DEV_TYPE_NULL && tt->did_ifconfig) - { -struct argv argv =argv_new (); -struct gc_arena gc =gc_new (); +return ; + } -#ifdef ENABLE_IPROUTE -if (is_tun_p2p (tt)) +if (tt->type !=DEV_TYPE_NULL && tt->did_ifconfig) + { +int netbits =netmask_to_netbits2 (tt->remote_netmask); +if (is_tun_p2p (tt)) + { +if (net_addr_ptp_v4_del (tt->actual_name, &tt->local, + &tt->remote_netmask) <0 ) { -argv_printf (&argv, -"%s addr del dev %s local %s peer %s" , - iproute_path, - tt->actual_name, -print_in_addr_t (tt->local,0 , &gc), -print_in_addr_t (tt->remote_netmask,0 , &gc) - ); +msg (M_WARN ,"Linux can't del IP from TUN iface %s" , + tt->actual_name); } -else + } +else + { +if (net_addr_v4_del (tt->actual_name, &tt->local, netbits) <0 ) { -argv_printf (&argv, -"%s addr del dev %s %s/%d" , - iproute_path, - tt->actual_name, -print_in_addr_t (tt->local,0 , &gc), -netmask_to_netbits2 (tt->remote_netmask) - ); +msg (M_WARN ,"Linux can't del IP from TAP iface %s" , + tt->actual_name); } -#else /* ifdef ENABLE_IPROUTE */ -argv_printf (&argv, -"%s %s 0.0.0.0" , -IFCONFIG_PATH , - tt->actual_name - ); -#endif /* ifdef ENABLE_IPROUTE */ - -argv_msg (M_INFO , &argv); -openvpn_execve_check (&argv,NULL ,0 ,"Linux ip addr del failed" ); + } -if (tt->did_ifconfig_ipv6_setup) +if (tt->did_ifconfig_ipv6_setup) + { +if (net_addr_v6_del (tt->actual_name, &tt->local_ipv6, + tt->netbits_ipv6) <0 ) { -const char *ifconfig_ipv6_local =print_in6_addr (tt->local_ipv6,0 , &gc); - -#ifdef ENABLE_IPROUTE -argv_printf (&argv,"%s -6 addr del %s/%d dev %s" , - iproute_path, - ifconfig_ipv6_local, - tt->netbits_ipv6, - tt->actual_name - ); -argv_msg (M_INFO , &argv); -openvpn_execve_check (&argv,NULL ,0 ,"Linux ip -6 addr del failed" ); -#else /* ifdef ENABLE_IPROUTE */ -argv_printf (&argv, -"%s %s del %s/%d" , -IFCONFIG_PATH , - tt->actual_name, - ifconfig_ipv6_local, - tt->netbits_ipv6 - ); -argv_msg (M_INFO , &argv); -openvpn_execve_check (&argv,NULL ,0 ,"Linux ifconfig inet6 del failed" ); -#endif +msg (M_WARN ,"Linux can't del IPv6 from iface %s" , + tt->actual_name); } - -argv_reset (&argv); -gc_free (&gc); } -close_tun_generic (tt); -free (tt); } + +close_tun_generic (tt); +free (tt); }int
Signature · 1 line
2.17.0
PATCH 4/8 route.c: use new networking API to handle routing table on Linux
In reply to Antonio QuartulliBy switching to the networking API (for Linux) openvpn will now use any of the available implementations to handle the routing table.
At the moment only iproute2 is implemented.
--- src/openvpn/networking_ip.c | 1 - src/openvpn/route.c | 214 ++++++++++-------------------------- 2 files changed, 60 insertions(+), 155 deletions(-)
src/openvpn/networking_ip.c +0 -1
@@ -29,7 +29,6 @@#include "syshead.h" #include "networking.h" -#include "networking_ip.h" #include "misc.h" #include "socket.h"
src/openvpn/route.c +60 -154
349 lines not on this page · raw message
Signature · 1 line
2.17.0
PATCH 5/8 introduce sitnl: Simplified Interface To NetLink
In reply to Antonio QuartulliThis patch introduces a tiny netlink interface, optimized for the openvpn use case.
It basically exposes all those operations that are currently handled by directly calling the /sbin/ip command (or even ifconfig/route, if configured).
By using netlink, openvpn won't need to spawn new processes when configuring the tun interface or routes.
This new approach will also allow openvpn to be granted CAP_NET_ADMIN and be able to properly work even though it dropped the root privileges (currently handled via workarounds).
By moving this logic into the sitnl module, tun.c and route.c also benefit from some code simplification
--- src/openvpn/Makefile.am | 2 +- src/openvpn/errlevel.h | 1 + src/openvpn/networking_sitnl.c | 1206 ++++++++++++++++++++++++++++++++ src/openvpn/sitnl.h | 217 ++++++ 4 files changed, 1425 insertions(+), 1 deletion(-) create mode 100644 src/openvpn/networking_sitnl.c create mode 100644 src/openvpn/sitnl.h
src/openvpn/Makefile.am +1 -1
@@ -80,7 +80,7 @@ openvpn_SOURCES = \ mtu.c mtu.h \ mudp.c mudp.h \ multi.c multi.h \ - networking_ip.c networking.h \ + networking_ip.c networking_sitnl.c networking.h \ ntlm.c ntlm.h \ occ.c occ.h occ-inline.h \ openssl_compat.h \
src/openvpn/errlevel.h +1 -0
@@ -109,6 +109,7 @@#define D_LOG_RW LOGLEV(5, 0, 0)/* Print 'R' or 'W' to stdout for read/write */ +#define D_RTNL LOGLEV(6, 68, M_DEBUG)/* show RTNL low level operations */ #define D_LINK_RW LOGLEV(6, 69, M_DEBUG)/* show TCP/UDP reads/writes (terse) */ #define D_TUN_RW LOGLEV(6, 69, M_DEBUG)/* show TUN/TAP reads/writes */ #define D_TAP_WIN_DEBUG LOGLEV(6, 69, M_DEBUG)/* show TAP-Windows driver debug info */
src/openvpn/networking_sitnl.c new file +1206 -0
1,206 lines not on this page · raw message
src/openvpn/sitnl.h new file +217 -0
217 lines not on this page · raw message
Signature · 1 line
2.17.0
PATCH 6/8 configure: don't check for route/ifconfig on linux
In reply to Antonio Quartulli--- configure.ac | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
configure.ac +2 -1
@@ -298,6 +298,7 @@ case "$host" in *-*-linux*) AC_DEFINE([TARGET_LINUX], [1], [Are we running on Linux?]) AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["L"], [Target prefix]) + have_sitnl="yes" ;; *-*-solaris*) AC_DEFINE([TARGET_SOLARIS], [1], [Are we running on Solaris?])
@@ -1254,7 +1255,7 @@ if test "${enable_iproute2}" = "yes"; then test -z "${IPROUTE}" && AC_MSG_ERROR([ip utility is required but missing]) AC_DEFINE([ENABLE_IPROUTE], [1], [enable iproute2 support]) else - if test "${WIN32}" != "yes"; then + if test "${WIN32}" != "yes" -a "${have_sitnl}" != "yes"; then test -z "${ROUTE}" && AC_MSG_ERROR([route utility is required but missing]) test -z "${IFCONFIG}" && AC_MSG_ERROR([ifconfig utility is required but missing]) fi
Signature · 1 line
2.17.0
PATCH 7/8 route.c: use sitnl to implement get_default_gateway_ipv6()
In reply to Antonio Quartulliget_default_gateway_ipv6() has always been implemented using netlink, however, now that we have sitnl, we can re-use the latter and get rid of the netlink code from route.c.
--- src/openvpn/networking_ip.c | 2 +- src/openvpn/route.c | 150 +++--------------------------------- 2 files changed, 12 insertions(+), 140 deletions(-)
src/openvpn/networking_ip.c +1 -1
@@ -358,7 +358,7 @@ net_route_v4_best_gw(const in_addr_t *dst, int prefixlen,/* * The following function is not implemented in the iproute backend as it -* already uses netlink in route.c. +* uses the sitnl implementation from networking_sitnl.c. * * int * net_route_v6_best_gw(const struct in6_addr *dst, int prefixlen,
src/openvpn/route.c +11 -139
173 lines not on this page · raw message
Signature · 1 line
2.17.0
PATCH 8/8 unit tests: implement test for sitnl
In reply to Antonio QuartulliThis patch introduces a new unit test that is not executed by the cmocka framework, but rather used by a new t_net.sh bash script.
The idea behind this test is to ensure that invoking sitnl functions or running iproute commands leads to the same networking (interface and routing table) state.
To achieve this, the t_net.sh script first runs a binary implemented invoking sitnl functions and then takes a "screenshot" of the state. Subsequently a series of iproute commands, expected to mimic exactly the same behaviour as the sitnl functions invoked before, are executed. The final state is then compared with the screenshot previously taken.
If no mismatching is found, the test is passed.
The current unit_test, however, does not cover all the sitnl functionalities and it is expected to be extended in the future.
--- configure.ac | 2 + tests/Makefile.am | 3 +- tests/t_net.sh | 170 ++++++++++++++++ tests/unit_tests/openvpn/Makefile.am | 23 ++- tests/unit_tests/openvpn/test_networking.c | 217 +++++++++++++++++++++ 5 files changed, 410 insertions(+), 5 deletions(-) create mode 100755 tests/t_net.sh create mode 100644 tests/unit_tests/openvpn/test_networking.c
configure.ac +2 -0
@@ -294,9 +294,11 @@ else fi AC_DEFINE_UNQUOTED([TARGET_ALIAS], ["${host}"], [A string representing our host]) +AM_CONDITIONAL([TARGET_LINUX], [false]) case "$host" in *-*-linux*) AC_DEFINE([TARGET_LINUX], [1], [Are we running on Linux?]) + AM_CONDITIONAL([TARGET_LINUX], [true]) AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["L"], [Target prefix]) have_sitnl="yes" ;;
tests/Makefile.am +2 -1
@@ -14,7 +14,8 @@ MAINTAINERCLEANFILES = \ SUBDIRS = unit_tests -test_scripts = t_client.sh +test_scripts = t_net.sh +test_scripts += t_client.sh test_scripts += t_lpback.sh t_cltsrv.sh TESTS_ENVIRONMENT = top_srcdir="$(top_srcdir)"
tests/t_net.sh new file +170 -0
170 lines not on this page · raw message
tests/unit_tests/openvpn/Makefile.am +19 -4
@@ -1,14 +1,19 @@ AUTOMAKE_OPTIONS = foreign -check_PROGRAMS= +test_binaries= if HAVE_LD_WRAP_SUPPORT -check_PROGRAMS += argv_testdriver buffer_testdriver +test_binaries += argv_testdriver buffer_testdriver endif -check_PROGRAMS += packet_id_testdriver tls_crypt_testdriver +test_binaries += packet_id_testdriver tls_crypt_testdriver -TESTS = $(check_PROGRAMS) +TESTS = $(test_binaries) +check_PROGRAMS = $(test_binaries) + +if TARGET_LINUX +check_PROGRAMS += networking_testdriver +endif openvpn_includedir = $(top_srcdir)/include openvpn_srcdir = $(top_srcdir)/src/openvpn
@@ -53,3 +58,13 @@ tls_crypt_testdriver_SOURCES = test_tls_crypt.c mock_msg.c \ $(openvpn_srcdir)/otime.c \ $(openvpn_srcdir)/packet_id.c \ $(openvpn_srcdir)/platform.c + +networking_testdriver_CFLAGS = @TEST_CFLAGS@ \ + -I$(openvpn_includedir) -I$(compat_srcdir) -I$(openvpn_srcdir) \ + $(OPTIONAL_CRYPTO_CFLAGS) +networking_testdriver_LDFLAGS = @TEST_LDFLAGS@ -L$(openvpn_srcdir) \ + $(OPTIONAL_CRYPTO_LIBS) +networking_testdriver_SOURCES = test_networking.c mock_msg.c \ + $(openvpn_srcdir)/networking_sitnl.c \ + $(openvpn_srcdir)/buffer.c \ + $(openvpn_srcdir)/platform.c
tests/unit_tests/openvpn/test_networking.c new file +217 -0
217 lines not on this page · raw message
Signature · 1 line
2.17.0