[Openvpn-devel] [PATCH v3] Route: add support for user defined routing table

2023-04-04 Thread Gianmarco De Gregori
Add the ability for users to specify a custom
routing table where routes should be installed in.
As of now routes are always installed in the main
routing table of the operating system, however,
with the new --route-table option it is possibile
to specify the ID of the default routing table
to be used by --route(-ipv6).

The --route(-ipv6) directives have been extended
with an additional argument (5th for --route)
(4th for --route-ipv6) so that each of them
can possibly use an independent routing table.

Please note: this feature is currently supported
only by Linux/SITNL.
Support for other platforms should be added in related backends.

Signed-off-by: Gianmarco De Gregori 
---
Changes from v1:
* Fixed parameters (metric and table_id) order in init_route_list() call in 
init.c : 1535.

Changes from v2:
* Add route_default_table_id to show_settings() in options.c : 1800.

 doc/man-sections/vpn-network-options.rst |  16 +++-
 src/openvpn/helper.c |   1 +
 src/openvpn/init.c   |  15 +++-
 src/openvpn/options.c|  45 +-
 src/openvpn/options.h|   1 +
 src/openvpn/route.c  | 101 +--
 src/openvpn/route.h  |  17 +++-
 7 files changed, 180 insertions(+), 16 deletions(-)

diff --git a/doc/man-sections/vpn-network-options.rst 
b/doc/man-sections/vpn-network-options.rst
index 8e3c92ee..c25bbf31 100644
--- a/doc/man-sections/vpn-network-options.rst
+++ b/doc/man-sections/vpn-network-options.rst
@@ -367,6 +367,14 @@ routing.
   Like ``--redirect-gateway``, but omit actually changing the default gateway.
   Useful when pushing private subnets.
 
+--route-table id
+  Specify a default table id for use with --route.
+  By default, OpenVPN installs routes in the main routing
+  table of the operating system, but with this option,
+  a user defined routing table can be used instead.
+
+  (Supported on Linux only, on other platforms this is a no-op).
+
 --route args
   Add route to routing table after connection is established. Multiple
   routes can be specified. Routes will be automatically torn down in
@@ -379,6 +387,7 @@ routing.
   route network/IP netmask
   route network/IP netmask gateway
   route network/IP netmask gateway metric
+  route network/IP netmask gateway metric table-id
 
   This option is intended as a convenience proxy for the ``route``\(8)
   shell command, while at the same time providing portable semantics
@@ -394,6 +403,9 @@ routing.
   ``metric``
 default taken from ``--route-metric`` if set, otherwise :code:`0`.
 
+  ``table-id`` (Supported on Linux only, on other platforms this is a no-op).
+   default taken from ``--route-table`` if set, otherwise :code:`0`.
+
   The default can be specified by leaving an option blank or setting it to
   :code:`default`.
 
@@ -444,12 +456,14 @@ routing.
   Valid syntax:
   ::
 
- route-ipv6 ipv6addr/bits [gateway] [metric]
+ route-ipv6 ipv6addr/bits [gateway] [metric] [table-id]
 
   The gateway parameter is only used for IPv6 routes across *tap* devices,
   and if missing, the ``ipv6remote`` field from ``--ifconfig-ipv6`` or
   ``--route-ipv6-gateway`` is used.
 
+  (table-id supported on Linux only, on other platforms this is a no-op).
+
 --route-gateway arg
   Specify a default *gateway* for use with ``--route``.
 
diff --git a/src/openvpn/helper.c b/src/openvpn/helper.c
index 7c219fdf..4a0e0d85 100644
--- a/src/openvpn/helper.c
+++ b/src/openvpn/helper.c
@@ -120,6 +120,7 @@ helper_add_route(const in_addr_t network, const in_addr_t 
netmask, struct option
  print_in_addr_t(network, 0, >gc),
  print_in_addr_t(netmask, 0, >gc),
  NULL,
+ NULL,
  NULL);
 }
 
diff --git a/src/openvpn/init.c b/src/openvpn/init.c
index d358ad00..00caa283 100644
--- a/src/openvpn/init.c
+++ b/src/openvpn/init.c
@@ -1504,6 +1504,7 @@ do_init_route_list(const struct options *options,
 const char *gw = NULL;
 int dev = dev_type_enum(options->dev, options->dev_type);
 int metric = 0;
+uint32_t table_id = 0; /* unspec table */
 
 /* if DCO is enabled we have both regular routes and iroutes in the system
  * routing table, and normal routes must have a higher metric for that to
@@ -1522,6 +1523,10 @@ do_init_route_list(const struct options *options,
 {
 gw = options->route_default_gateway;
 }
+if (options->route_default_table_id)
+{
+table_id = options->route_default_table_id;
+}
 if (options->route_default_metric)
 {
 metric = options->route_default_metric;
@@ -1531,6 +1536,7 @@ do_init_route_list(const struct options *options,
 options->routes,
 gw,
 metric,
+table_id,
 

[Openvpn-devel] [PATCH] Support of DNS domain for DHCP-less drivers

2023-04-04 Thread Lev Stipakov
From: Lev Stipakov 

We set DNS domain either via interactve service or DHCP.
When interactive service is not used, for example,
when profiles are started by OpenVPNService, this option
is not working for DCO and wintun.

This implements setting DNS domain via WMIC command,
similar to implementation in interactive service.
This is done when:

 - interactive service is not used
 - ip_win32_type is either METSH or IPAPI, which is
the case for DCO and wintun.

Fixes https://github.com/OpenVPN/openvpn/issues/306

Change-Id: I9ab51bf1c0774564204c75ecce9ebfb818db2f5b
---
 src/openvpn/options.c |  8 ++---
 src/openvpn/tun.c | 72 ++-
 src/openvpn/tun.h |  6 
 src/openvpn/win32.h   |  1 +
 4 files changed, 67 insertions(+), 20 deletions(-)

diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index 2680f268..36d54ceb 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -3396,11 +3396,11 @@ options_postprocess_mutate_invariant(struct options 
*options)
 #ifdef _WIN32
 const int dev = dev_type_enum(options->dev, options->dev_type);
 
+const bool dhcp = tuntap_maybe_dhcp(>tuntap_options);
+
 /* when using wintun/ovpn-dco, kernel doesn't send DHCP requests, so don't 
use it */
 if ((options->windows_driver == WINDOWS_DRIVER_WINTUN
- || options->windows_driver == WINDOWS_DRIVER_DCO)
-&& (options->tuntap_options.ip_win32_type == IPW32_SET_DHCP_MASQ
-|| options->tuntap_options.ip_win32_type == IPW32_SET_ADAPTIVE))
+ || options->windows_driver == WINDOWS_DRIVER_DCO) && dhcp)
 {
 options->tuntap_options.ip_win32_type = IPW32_SET_NETSH;
 }
@@ -3408,8 +3408,6 @@ options_postprocess_mutate_invariant(struct options 
*options)
 if ((dev == DEV_TYPE_TUN || dev == DEV_TYPE_TAP) && 
!options->route_delay_defined)
 {
 /* delay may only be necessary when we perform DHCP handshake */
-const bool dhcp = (options->tuntap_options.ip_win32_type == 
IPW32_SET_DHCP_MASQ)
-  || (options->tuntap_options.ip_win32_type == 
IPW32_SET_ADAPTIVE);
 if ((options->mode == MODE_POINT_TO_POINT) && dhcp)
 {
 options->route_delay_defined = true;
diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c
index 2ebe4809..c2cc7e26 100644
--- a/src/openvpn/tun.c
+++ b/src/openvpn/tun.c
@@ -84,6 +84,8 @@ static void netsh_set_dns6_servers(const struct in6_addr 
*addr_list,
 
 static void netsh_command(const struct argv *a, int n, int msglevel);
 
+static void exec_command(const char *prefix, const struct argv *a, int n, int 
msglevel);
+
 static const char *netsh_get_id(const char *dev_node, struct gc_arena *gc);
 
 static bool
@@ -324,6 +326,22 @@ out:
 return ret;
 }
 
+static void
+wmic_do_dns_domain(bool add, const struct tuntap *tt)
+{
+if (!tt->options.domain)
+{
+return;
+}
+
+struct argv argv = argv_new();
+argv_printf(, "%s%s nicconfig where (InterfaceIndex=%ld) call 
SetDNSDomain %s",
+get_win_sys_path(), WMIC_PATH_SUFFIX, tt->adapter_index, add ? 
tt->options.domain : "");
+exec_command("WMIC", , 1, M_WARN);
+
+argv_free();
+}
+
 #endif /* ifdef _WIN32 */
 
 #ifdef TARGET_SOLARIS
@@ -1190,6 +1208,11 @@ do_ifconfig_ipv6(struct tuntap *tt, const char *ifname, 
int tun_mtu,
 /* set ipv6 dns servers if any are specified */
 netsh_set_dns6_servers(tt->options.dns6, tt->options.dns6_len, 
tt->adapter_index);
 windows_set_mtu(tt->adapter_index, AF_INET6, tun_mtu);
+
+if (!tt->did_ifconfig_setup && !tuntap_maybe_dhcp(>options))
+{
+wmic_do_dns_domain(true, tt);
+}
 }
 #else /* platforms we have no IPv6 code for */
 msg(M_FATAL, "Sorry, but I don't know how to do IPv6 'ifconfig' commands 
on this operating system.  You should ifconfig your TUN/TAP device manually or 
use an --up script.");
@@ -1525,7 +1548,7 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, 
int tun_mtu,
 ifname, ifconfig_local,
 ifconfig_remote_netmask);
 }
-else if (tt->options.ip_win32_type == IPW32_SET_DHCP_MASQ || 
tt->options.ip_win32_type == IPW32_SET_ADAPTIVE)
+else if (tuntap_maybe_dhcp(>options))
 {
 /* Let the DHCP configure the interface. */
 }
@@ -1535,11 +1558,18 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, 
int tun_mtu,
 do_dns_service(true, AF_INET, tt);
 do_dns_domain_service(true, tt);
 }
-else if (tt->options.ip_win32_type == IPW32_SET_NETSH)
+else
 {
-netsh_ifconfig(>options, tt->adapter_index, tt->local,
-   tt->adapter_netmask, NI_IP_NETMASK|NI_OPTIONS);
+if (tt->options.ip_win32_type == IPW32_SET_NETSH)
+{
+netsh_ifconfig(>options, tt->adapter_index, tt->local,
+   tt->adapter_netmask, NI_IP_NETMASK | NI_OPTIONS);
+}
+
+