@@ -508,7 +508,7 @@ static void
check_add_routes_action(struct context *c, const bool errors)
{
do_route(&c->options, c->c1.route_list, c->c1.route_ipv6_list,
- c->c1.tuntap, c->plugins, c->c2.es);
+ c->c1.tuntap, c->plugins, c->c2.es, &c->net_ctx);
update_time();
event_timeout_clear(&c->c2.route_wakeup);
event_timeout_clear(&c->c2.route_wakeup_expire);
@@ -1402,7 +1402,8 @@ static void
do_init_route_list(const struct options *options,
struct route_list *route_list,
const struct link_socket_info *link_socket_info,
- struct env_set *es)
+ struct env_set *es,
+ openvpn_net_ctx_t *ctx)
{
const char *gw = NULL;
int dev = dev_type_enum(options->dev, options->dev_type);
@@ -1426,7 +1427,8 @@ do_init_route_list(const struct options *options,
gw,
metric,
link_socket_current_remote(link_socket_info),
- es))
+ es,
+ ctx))
{
/* copy routes to environment */
setenv_routes(es, route_list);
@@ -1611,11 +1613,13 @@ do_route(const struct options *options,
struct route_ipv6_list *route_ipv6_list,
const struct tuntap *tt,
const struct plugin_list *plugins,
- struct env_set *es)
+ struct env_set *es,
+ openvpn_net_ctx_t *ctx)
{
if (!options->route_noexec && ( route_list || route_ipv6_list ) )
{
- add_routes(route_list, route_ipv6_list, tt, ROUTE_OPTION_FLAGS(options), es);
+ add_routes(route_list, route_ipv6_list, tt, ROUTE_OPTION_FLAGS(options),
+ es, ctx);
setenv_int(es, "redirect_gateway", route_did_redirect_default_gateway(route_list));
}
#ifdef ENABLE_MANAGEMENT
@@ -1728,7 +1732,7 @@ do_open_tun(struct context *c)
if (c->options.routes && c->c1.route_list)
{
do_init_route_list(&c->options, c->c1.route_list,
- &c->c2.link_socket->info, c->c2.es);
+ &c->c2.link_socket->info, c->c2.es, &c->net_ctx);
}
if (c->options.routes_ipv6 && c->c1.route_ipv6_list)
{
@@ -1755,7 +1759,7 @@ do_open_tun(struct context *c)
{
/* Ignore route_delay, would cause ROUTE_BEFORE_TUN to be ignored */
do_route(&c->options, c->c1.route_list, c->c1.route_ipv6_list,
- c->c1.tuntap, c->plugins, c->c2.es);
+ c->c1.tuntap, c->plugins, c->c2.es, &c->net_ctx);
}
#ifdef TARGET_ANDROID
/* Store the old fd inside the fd so open_tun can use it */
@@ -1812,7 +1816,7 @@ do_open_tun(struct context *c)
if ((route_order() == ROUTE_AFTER_TUN) && (!c->options.route_delay_defined))
{
do_route(&c->options, c->c1.route_list, c->c1.route_ipv6_list,
- c->c1.tuntap, c->plugins, c->c2.es);
+ c->c1.tuntap, c->plugins, c->c2.es, &c->net_ctx);
}
/*
@@ -1941,7 +1945,8 @@ do_close_tun(struct context *c, bool force)
c->c2.es);
delete_routes(c->c1.route_list, c->c1.route_ipv6_list,
- c->c1.tuntap, ROUTE_OPTION_FLAGS(&c->options), c->c2.es);
+ c->c1.tuntap, ROUTE_OPTION_FLAGS(&c->options),
+ c->c2.es, &c->net_ctx);
}
/* actually close tun/tap device based on --down-pre flag */
@@ -2777,6 +2782,7 @@ do_init_crypto_tls(struct context *c, const unsigned int flags)
to.x509_username_field = X509_USERNAME_FIELD_DEFAULT;
#endif
to.es = c->c2.es;
+ to.net_ctx = &c->net_ctx;
#ifdef ENABLE_DEBUG
to.gremlin = c->options.gremlin;
@@ -3123,7 +3129,7 @@ do_option_warnings(struct context *c)
if (o->tls_server)
{
- warn_on_use_of_common_subnets();
+ warn_on_use_of_common_subnets(&c->net_ctx);
}
if (o->tls_client
&& !o->tls_verify
@@ -76,7 +76,8 @@ void do_route(const struct options *options,
struct route_ipv6_list *route_ipv6_list,
const struct tuntap *tt,
const struct plugin_list *plugins,
- struct env_set *es);
+ struct env_set *es,
+ openvpn_net_ctx_t *ctx);
void close_instance(struct context *c);
@@ -29,7 +29,6 @@
#include "syshead.h"
#include "networking.h"
-#include "networking_ip.h"
#include "misc.h"
#include "openvpn.h"
#include "run_command.h"
@@ -5028,12 +5028,14 @@ add_option(struct options *options,
struct route_gateway_info rgi;
struct route_ipv6_gateway_info rgi6;
struct in6_addr remote = IN6ADDR_ANY_INIT;
+ openvpn_net_ctx_t net_ctx;
VERIFY_PERMISSION(OPT_P_GENERAL);
if (p[1])
{
get_ipv6_addr(p[1], &remote, NULL, M_WARN);
}
- get_default_gateway(&rgi);
+ net_ctx_init(NULL, &net_ctx);
+ get_default_gateway(&rgi, &net_ctx);
get_default_gateway_ipv6(&rgi6, &remote);
print_default_gateway(M_INFO, &rgi, &rgi6);
openvpn_exit(OPENVPN_EXIT_STATUS_GOOD); /* exit point */
@@ -41,6 +41,7 @@
#include "manage.h"
#include "win32.h"
#include "options.h"
+#include "networking.h"
#include "memdbg.h"
@@ -62,7 +63,7 @@ static bool del_route_ipv6_service(const struct route_ipv6 *, const struct tunta
#endif
-static void delete_route(struct route_ipv4 *r, const struct tuntap *tt, unsigned int flags, const struct route_gateway_info *rgi, const struct env_set *es);
+static void 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);
static void get_bypass_addresses(struct route_bypass *rb, const unsigned int flags);
@@ -613,7 +614,8 @@ init_route_list(struct route_list *rl,
const char *remote_endpoint,
int default_metric,
in_addr_t remote_host,
- struct env_set *es)
+ struct env_set *es,
+ openvpn_net_ctx_t *ctx)
{
struct gc_arena gc = gc_new();
bool ret = true;
@@ -634,7 +636,7 @@ init_route_list(struct route_list *rl,
rl->spec.flags |= RTSA_DEFAULT_METRIC;
}
- get_default_gateway(&rl->rgi);
+ get_default_gateway(&rl->rgi, ctx);
if (rl->rgi.flags & RGI_ADDR_DEFINED)
{
setenv_route_addr(es, "net_gateway", rl->rgi.gateway.addr, -1);
@@ -901,7 +903,8 @@ add_route3(in_addr_t network,
const struct tuntap *tt,
unsigned int flags,
const struct route_gateway_info *rgi,
- const struct env_set *es)
+ const struct env_set *es,
+ openvpn_net_ctx_t *ctx)
{
struct route_ipv4 r;
CLEAR(r);
@@ -909,7 +912,7 @@ add_route3(in_addr_t network,
r.network = network;
r.netmask = netmask;
r.gateway = gateway;
- add_route(&r, tt, flags, rgi, es);
+ add_route(&r, tt, flags, rgi, es, ctx);
}
static void
@@ -919,7 +922,8 @@ del_route3(in_addr_t network,
const struct tuntap *tt,
unsigned int flags,
const struct route_gateway_info *rgi,
- const struct env_set *es)
+ const struct env_set *es,
+ openvpn_net_ctx_t *ctx)
{
struct route_ipv4 r;
CLEAR(r);
@@ -927,7 +931,7 @@ del_route3(in_addr_t network,
r.network = network;
r.netmask = netmask;
r.gateway = gateway;
- delete_route(&r, tt, flags, rgi, es);
+ delete_route(&r, tt, flags, rgi, es, ctx);
}
static void
@@ -936,7 +940,8 @@ add_bypass_routes(struct route_bypass *rb,
const struct tuntap *tt,
unsigned int flags,
const struct route_gateway_info *rgi,
- const struct env_set *es)
+ const struct env_set *es,
+ openvpn_net_ctx_t *ctx)
{
int i;
for (i = 0; i < rb->n_bypass; ++i)
@@ -949,7 +954,8 @@ add_bypass_routes(struct route_bypass *rb,
tt,
flags | ROUTE_REF_GW,
rgi,
- es);
+ es,
+ ctx);
}
}
}
@@ -960,7 +966,8 @@ del_bypass_routes(struct route_bypass *rb,
const struct tuntap *tt,
unsigned int flags,
const struct route_gateway_info *rgi,
- const struct env_set *es)
+ const struct env_set *es,
+ openvpn_net_ctx_t *ctx)
{
int i;
for (i = 0; i < rb->n_bypass; ++i)
@@ -973,13 +980,16 @@ del_bypass_routes(struct route_bypass *rb,
tt,
flags | ROUTE_REF_GW,
rgi,
- es);
+ es,
+ ctx);
}
}
}
static void
-redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
+redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *tt,
+ unsigned int flags, const struct env_set *es,
+ openvpn_net_ctx_t *ctx)
{
const char err[] = "NOTE: unable to redirect default gateway --";
@@ -1035,7 +1045,8 @@ redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *tt, un
tt,
flags | ROUTE_REF_GW,
&rl->rgi,
- es);
+ es,
+ ctx);
rl->iflags |= RL_DID_LOCAL;
}
else
@@ -1046,7 +1057,8 @@ redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *tt, un
#endif /* ifndef TARGET_ANDROID */
/* route DHCP/DNS server traffic through original default gateway */
- add_bypass_routes(&rl->spec.bypass, rl->rgi.gateway.addr, tt, flags, &rl->rgi, es);
+ add_bypass_routes(&rl->spec.bypass, rl->rgi.gateway.addr, tt, flags,
+ &rl->rgi, es, ctx);
if (rl->flags & RG_REROUTE_GW)
{
@@ -1059,7 +1071,8 @@ redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *tt, un
tt,
flags,
&rl->rgi,
- es);
+ es,
+ ctx);
/* add new default route (2nd component) */
add_route3(0x80000000,
@@ -1068,7 +1081,8 @@ redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *tt, un
tt,
flags,
&rl->rgi,
- es);
+ es,
+ ctx);
}
else
{
@@ -1077,7 +1091,7 @@ redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *tt, un
{
/* delete default route */
del_route3(0, 0, rl->rgi.gateway.addr, tt,
- flags | ROUTE_REF_GW, &rl->rgi, es);
+ flags | ROUTE_REF_GW, &rl->rgi, es, ctx);
}
/* add new default route */
@@ -1087,7 +1101,8 @@ redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *tt, un
tt,
flags,
&rl->rgi,
- es);
+ es,
+ ctx);
}
}
@@ -1098,7 +1113,10 @@ redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *tt, un
}
static void
-undo_redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
+undo_redirect_default_route_to_vpn(struct route_list *rl,
+ const struct tuntap *tt, unsigned int flags,
+ const struct env_set *es,
+ openvpn_net_ctx_t *ctx)
{
if (rl && rl->iflags & RL_DID_REDIRECT_DEFAULT_GATEWAY)
{
@@ -1111,12 +1129,14 @@ undo_redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *t
tt,
flags | ROUTE_REF_GW,
&rl->rgi,
- es);
+ es,
+ ctx);
rl->iflags &= ~RL_DID_LOCAL;
}
/* delete special DHCP/DNS bypass route */
- del_bypass_routes(&rl->spec.bypass, rl->rgi.gateway.addr, tt, flags, &rl->rgi, es);
+ del_bypass_routes(&rl->spec.bypass, rl->rgi.gateway.addr, tt, flags,
+ &rl->rgi, es, ctx);
if (rl->flags & RG_REROUTE_GW)
{
@@ -1129,7 +1149,8 @@ undo_redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *t
tt,
flags,
&rl->rgi,
- es);
+ es,
+ ctx);
/* delete default route (2nd component) */
del_route3(0x80000000,
@@ -1138,7 +1159,8 @@ undo_redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *t
tt,
flags,
&rl->rgi,
- es);
+ es,
+ ctx);
}
else
{
@@ -1149,12 +1171,13 @@ undo_redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *t
tt,
flags,
&rl->rgi,
- es);
+ es,
+ ctx);
/* restore original default route if there was any */
if (rl->rgi.flags & RGI_ADDR_DEFINED)
{
add_route3(0, 0, rl->rgi.gateway.addr, tt,
- flags | ROUTE_REF_GW, &rl->rgi, es);
+ flags | ROUTE_REF_GW, &rl->rgi, es, ctx);
}
}
}
@@ -1164,9 +1187,11 @@ undo_redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *t
}
void
-add_routes(struct route_list *rl, struct route_ipv6_list *rl6, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
+add_routes(struct route_list *rl, struct route_ipv6_list *rl6,
+ const struct tuntap *tt, unsigned int flags,
+ const struct env_set *es, openvpn_net_ctx_t *ctx)
{
- redirect_default_route_to_vpn(rl, tt, flags, es);
+ redirect_default_route_to_vpn(rl, tt, flags, es, ctx);
if (rl && !(rl->iflags & RL_ROUTES_ADDED) )
{
struct route_ipv4 *r;
@@ -1189,9 +1214,9 @@ add_routes(struct route_list *rl, struct route_ipv6_list *rl6, const struct tunt
check_subnet_conflict(r->network, r->netmask, "route");
if (flags & ROUTE_DELETE_FIRST)
{
- delete_route(r, tt, flags, &rl->rgi, es);
+ delete_route(r, tt, flags, &rl->rgi, es, ctx);
}
- add_route(r, tt, flags, &rl->rgi, es);
+ add_route(r, tt, flags, &rl->rgi, es, ctx);
}
rl->iflags |= RL_ROUTES_ADDED;
}
@@ -1211,9 +1236,9 @@ add_routes(struct route_list *rl, struct route_ipv6_list *rl6, const struct tunt
{
if (flags & ROUTE_DELETE_FIRST)
{
- delete_route_ipv6(r, tt, flags, es);
+ delete_route_ipv6(r, tt, flags, es, ctx);
}
- add_route_ipv6(r, tt, flags, es);
+ add_route_ipv6(r, tt, flags, es, ctx);
}
rl6->iflags |= RL_ROUTES_ADDED;
}
@@ -1221,19 +1246,20 @@ add_routes(struct route_list *rl, struct route_ipv6_list *rl6, const struct tunt
void
delete_routes(struct route_list *rl, struct route_ipv6_list *rl6,
- const struct tuntap *tt, unsigned int flags, const struct env_set *es)
+ const struct tuntap *tt, unsigned int flags,
+ const struct env_set *es, openvpn_net_ctx_t *ctx)
{
if (rl && rl->iflags & RL_ROUTES_ADDED)
{
struct route_ipv4 *r;
for (r = rl->routes; r; r = r->next)
{
- delete_route(r, tt, flags, &rl->rgi, es);
+ delete_route(r, tt, flags, &rl->rgi, es, ctx);
}
rl->iflags &= ~RL_ROUTES_ADDED;
}
- undo_redirect_default_route_to_vpn(rl, tt, flags, es);
+ undo_redirect_default_route_to_vpn(rl, tt, flags, es, ctx);
if (rl)
{
@@ -1245,7 +1271,7 @@ delete_routes(struct route_list *rl, struct route_ipv6_list *rl6,
struct route_ipv6 *r6;
for (r6 = rl6->routes_ipv6; r6; r6 = r6->next)
{
- delete_route_ipv6(r6, tt, flags, es);
+ delete_route_ipv6(r6, tt, flags, es, ctx);
}
rl6->iflags &= ~RL_ROUTES_ADDED;
}
@@ -1525,15 +1551,21 @@ add_route(struct route_ipv4 *r,
const struct tuntap *tt,
unsigned int flags,
const struct route_gateway_info *rgi, /* may be NULL */
- const struct env_set *es)
+ const struct env_set *es,
+ openvpn_net_ctx_t *ctx)
{
struct gc_arena gc;
struct argv argv = argv_new();
+#if !defined(TARGET_LINUX)
const char *network;
#if !defined(ENABLE_IPROUTE) && !defined(TARGET_AIX)
const char *netmask;
#endif
const char *gateway;
+#else
+ const char *iface;
+ int metric;
+#endif
bool status = false;
int is_local_route;
@@ -1544,11 +1576,13 @@ add_route(struct route_ipv4 *r,
gc_init(&gc);
+#if !defined(TARGET_LINUX)
network = print_in_addr_t(r->network, 0, &gc);
#if !defined(ENABLE_IPROUTE) && !defined(TARGET_AIX)
netmask = print_in_addr_t(r->netmask, 0, &gc);
#endif
gateway = print_in_addr_t(r->gateway, 0, &gc);
+#endif
is_local_route = local_route(r->network, r->netmask, r->gateway, rgi);
if (is_local_route == LR_ERROR)
@@ -1557,47 +1591,26 @@ add_route(struct route_ipv4 *r,
}
#if defined(TARGET_LINUX)
-#ifdef ENABLE_IPROUTE
- argv_printf(&argv, "%s route add %s/%d",
- iproute_path,
- network,
- netmask_to_netbits2(r->netmask));
-
- if (r->flags & RT_METRIC_DEFINED)
- {
- argv_printf_cat(&argv, "metric %d", r->metric);
- }
-
+ iface = NULL;
if (is_on_link(is_local_route, flags, rgi))
{
- argv_printf_cat(&argv, "dev %s", rgi->iface);
- }
- else
- {
- argv_printf_cat(&argv, "via %s", gateway);
+ iface = rgi->iface;
}
-#else /* ifdef ENABLE_IPROUTE */
- argv_printf(&argv, "%s add -net %s netmask %s",
- ROUTE_PATH,
- network,
- netmask);
+
+ metric = -1;
if (r->flags & RT_METRIC_DEFINED)
{
- argv_printf_cat(&argv, "metric %d", r->metric);
+ metric = r->metric;
}
- if (is_on_link(is_local_route, flags, rgi))
- {
- argv_printf_cat(&argv, "dev %s", rgi->iface);
- }
- else
+
+ status = true;
+ if (net_route_v4_add(ctx, &r->network, netmask_to_netbits2(r->netmask),
+ &r->gateway, iface, 0, metric) < 0)
{
- argv_printf_cat(&argv, "gw %s", gateway);
+ msg(M_WARN, "ERROR: Linux route add command failed");
+ status = false;
}
-#endif /*ENABLE_IPROUTE*/
- argv_msg(D_ROUTE, &argv);
- status = openvpn_execve_check(&argv, es, 0, "ERROR: Linux route add command failed");
-
#elif defined (TARGET_ANDROID)
char out[128];
@@ -1844,7 +1857,9 @@ route_ipv6_clear_host_bits( struct route_ipv6 *r6 )
}
void
-add_route_ipv6(struct route_ipv6 *r6, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
+add_route_ipv6(struct route_ipv6 *r6, const struct tuntap *tt,
+ unsigned int flags, const struct env_set *es,
+ openvpn_net_ctx_t *ctx)
{
struct gc_arena gc;
struct argv argv = argv_new();
@@ -1853,7 +1868,9 @@ add_route_ipv6(struct route_ipv6 *r6, const struct tuntap *tt, unsigned int flag
const char *gateway;
bool status = false;
const char *device = tt->actual_name;
-
+#if defined(TARGET_LINUX)
+ int metric;
+#endif
bool gateway_needed = false;
if (!(r6->flags & RT_DEFINED) )
@@ -1918,38 +1935,20 @@ add_route_ipv6(struct route_ipv6 *r6, const struct tuntap *tt, unsigned int flag
}
#if defined(TARGET_LINUX)
-#ifdef ENABLE_IPROUTE
- argv_printf(&argv, "%s -6 route add %s/%d dev %s",
- iproute_path,
- network,
- r6->netbits,
- device);
- if (gateway_needed)
- {
- argv_printf_cat(&argv, "via %s", gateway);
- }
- if ( (r6->flags & RT_METRIC_DEFINED) && r6->metric > 0)
+ metric = -1;
+ if ((r6->flags & RT_METRIC_DEFINED) && (r6->metric > 0))
{
- argv_printf_cat(&argv, " metric %d", r6->metric);
+ metric = r6->metric;
}
-#else /* ifdef ENABLE_IPROUTE */
- argv_printf(&argv, "%s -A inet6 add %s/%d dev %s",
- ROUTE_PATH,
- network,
- r6->netbits,
- device);
- if (gateway_needed)
+ status = true;
+ if (net_route_v6_add(ctx, &r6->network, r6->netbits,
+ gateway_needed ? &r6->gateway : NULL, device, 0,
+ metric) < 0)
{
- argv_printf_cat(&argv, "gw %s", gateway);
+ msg(M_WARN, "ERROR: Linux IPv6 route can't be added");
+ status = false;
}
- if ( (r6->flags & RT_METRIC_DEFINED) && r6->metric > 0)
- {
- argv_printf_cat(&argv, " metric %d", r6->metric);
- }
-#endif /*ENABLE_IPROUTE*/
- argv_msg(D_ROUTE, &argv);
- status = openvpn_execve_check(&argv, es, 0, "ERROR: Linux route -6/-A inet6 add command failed");
#elif defined (TARGET_ANDROID)
char out[64];
@@ -2131,16 +2130,21 @@ delete_route(struct route_ipv4 *r,
const struct tuntap *tt,
unsigned int flags,
const struct route_gateway_info *rgi,
- const struct env_set *es)
+ const struct env_set *es,
+ openvpn_net_ctx_t *ctx)
{
struct gc_arena gc;
struct argv argv = argv_new();
+#if !defined(TARGET_LINUX)
const char *network;
#if !defined(ENABLE_IPROUTE) && !defined(TARGET_AIX)
const char *netmask;
#endif
#if !defined(TARGET_LINUX) && !defined(TARGET_ANDROID)
const char *gateway;
+#endif
+#else
+ int metric;
#endif
int is_local_route;
@@ -2151,12 +2155,14 @@ delete_route(struct route_ipv4 *r,
gc_init(&gc);
+#if !defined(TARGET_LINUX)
network = print_in_addr_t(r->network, 0, &gc);
#if !defined(ENABLE_IPROUTE) && !defined(TARGET_AIX)
netmask = print_in_addr_t(r->netmask, 0, &gc);
#endif
#if !defined(TARGET_LINUX) && !defined(TARGET_ANDROID)
gateway = print_in_addr_t(r->gateway, 0, &gc);
+#endif
#endif
is_local_route = local_route(r->network, r->netmask, r->gateway, rgi);
@@ -2166,24 +2172,17 @@ delete_route(struct route_ipv4 *r,
}
#if defined(TARGET_LINUX)
-#ifdef ENABLE_IPROUTE
- argv_printf(&argv, "%s route del %s/%d",
- iproute_path,
- network,
- netmask_to_netbits2(r->netmask));
-#else
- argv_printf(&argv, "%s del -net %s netmask %s",
- ROUTE_PATH,
- network,
- netmask);
-#endif /*ENABLE_IPROUTE*/
+ metric = -1;
if (r->flags & RT_METRIC_DEFINED)
{
- argv_printf_cat(&argv, "metric %d", r->metric);
+ metric = r->metric;
}
- argv_msg(D_ROUTE, &argv);
- openvpn_execve_check(&argv, es, 0, "ERROR: Linux route delete command failed");
+ if (net_route_v4_del(ctx, &r->network, netmask_to_netbits2(r->netmask),
+ &r->gateway, NULL, 0, metric) < 0)
+ {
+ msg(M_WARN, "ERROR: Linux route delete command failed");
+ }
#elif defined (_WIN32)
argv_printf(&argv, "%s%sc DELETE %s MASK %s %s",
@@ -2319,12 +2318,18 @@ done:
}
void
-delete_route_ipv6(const struct route_ipv6 *r6, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
+delete_route_ipv6(const struct route_ipv6 *r6, const struct tuntap *tt,
+ unsigned int flags, const struct env_set *es,
+ openvpn_net_ctx_t *ctx)
{
struct gc_arena gc;
struct argv argv = argv_new();
const char *network;
+#if !defined(TARGET_LINUX)
const char *gateway;
+#else
+ int metric;
+#endif
const char *device = tt->actual_name;
bool gateway_needed = false;
@@ -2344,7 +2349,9 @@ delete_route_ipv6(const struct route_ipv6 *r6, const struct tuntap *tt, unsigned
gc_init(&gc);
network = print_in6_addr( r6->network, 0, &gc);
+#if !defined(TARGET_LINUX)
gateway = print_in6_addr( r6->gateway, 0, &gc);
+#endif
#if defined(TARGET_DARWIN) \
|| defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \
@@ -2375,35 +2382,19 @@ delete_route_ipv6(const struct route_ipv6 *r6, const struct tuntap *tt, unsigned
gateway_needed = true;
}
-
#if defined(TARGET_LINUX)
-#ifdef ENABLE_IPROUTE
- argv_printf(&argv, "%s -6 route del %s/%d dev %s",
- iproute_path,
- network,
- r6->netbits,
- device);
- if (gateway_needed)
+ metric = -1;
+ if ((r6->flags & RT_METRIC_DEFINED) && (r6->metric > 0))
{
- argv_printf_cat(&argv, "via %s", gateway);
+ metric = r6->metric;
}
-#else /* ifdef ENABLE_IPROUTE */
- argv_printf(&argv, "%s -A inet6 del %s/%d dev %s",
- ROUTE_PATH,
- network,
- r6->netbits,
- device);
- if (gateway_needed)
- {
- argv_printf_cat(&argv, "gw %s", gateway);
- }
- if ( (r6->flags & RT_METRIC_DEFINED) && r6->metric > 0)
+
+ if (net_route_v6_del(ctx, &r6->network, r6->netbits,
+ gateway_needed ? &r6->gateway : NULL, device, 0,
+ metric) < 0)
{
- argv_printf_cat(&argv, " metric %d", r6->metric);
+ msg(M_WARN, "ERROR: Linux route v6 delete command failed");
}
-#endif /*ENABLE_IPROUTE*/
- argv_msg(D_ROUTE, &argv);
- openvpn_execve_check(&argv, es, 0, "ERROR: Linux route -6/-A inet6 del command failed");
#elif defined (_WIN32)
@@ -2715,7 +2706,7 @@ get_default_gateway_row(const MIB_IPFORWARDTABLE *routes)
}
void
-get_default_gateway(struct route_gateway_info *rgi)
+get_default_gateway(struct route_gateway_info *rgi, openvpn_net_ctx_t *ctx)
{
struct gc_arena gc = gc_new();
@@ -2802,7 +2793,7 @@ windows_route_find_if_index(const struct route_ipv4 *r, const struct tuntap *tt)
*/
void
get_default_gateway_ipv6(struct route_ipv6_gateway_info *rgi6,
- const struct in6_addr *dest)
+ const struct in6_addr *dest, openvpn_net_ctx_t *ctx)
{
struct gc_arena gc = gc_new();
MIB_IPFORWARD_ROW2 BestRoute;
@@ -3163,72 +3154,23 @@ show_routes(int msglev)
#elif defined(TARGET_LINUX) || defined(TARGET_ANDROID)
void
-get_default_gateway(struct route_gateway_info *rgi)
+get_default_gateway(struct route_gateway_info *rgi, openvpn_net_ctx_t *ctx)
{
struct gc_arena gc = gc_new();
int sd = -1;
- char best_name[16];
- best_name[0] = 0;
+ char best_name[IFNAMSIZ];
CLEAR(*rgi);
+ CLEAR(best_name);
#ifndef TARGET_ANDROID
/* get default gateway IP addr */
+ if (net_route_v4_best_gw(ctx, NULL, 0, &rgi->gateway.addr, best_name) == 0)
{
- FILE *fp = fopen("/proc/net/route", "r");
- if (fp)
+ rgi->flags |= RGI_ADDR_DEFINED;
+ if (!rgi->gateway.addr && best_name[0])
{
- char line[256];
- int count = 0;
- unsigned int lowest_metric = UINT_MAX;
- in_addr_t best_gw = 0;
- bool found = false;
- while (fgets(line, sizeof(line), fp) != NULL)
- {
- if (count)
- {
- unsigned int net_x = 0;
- unsigned int mask_x = 0;
- unsigned int gw_x = 0;
- unsigned int metric = 0;
- unsigned int flags = 0;
- char name[16];
- name[0] = 0;
- const int np = sscanf(line, "%15s\t%x\t%x\t%x\t%*s\t%*s\t%d\t%x",
- name,
- &net_x,
- &gw_x,
- &flags,
- &metric,
- &mask_x);
- if (np == 6 && (flags & IFF_UP))
- {
- const in_addr_t net = ntohl(net_x);
- const in_addr_t mask = ntohl(mask_x);
- const in_addr_t gw = ntohl(gw_x);
-
- if (!net && !mask && metric < lowest_metric)
- {
- found = true;
- best_gw = gw;
- strcpy(best_name, name);
- lowest_metric = metric;
- }
- }
- }
- ++count;
- }
- fclose(fp);
-
- if (found)
- {
- rgi->gateway.addr = best_gw;
- rgi->flags |= RGI_ADDR_DEFINED;
- if (!rgi->gateway.addr && best_name[0])
- {
- rgi->flags |= RGI_ON_LINK;
- }
- }
+ rgi->flags |= RGI_ON_LINK;
}
}
#else /* ifndef TARGET_ANDROID */
@@ -3590,7 +3532,7 @@ struct rtmsg {
#define max(a,b) ((a) > (b) ? (a) : (b))
void
-get_default_gateway(struct route_gateway_info *rgi)
+get_default_gateway(struct route_gateway_info *rgi, openvpn_net_ctx_t *ctx)
{
struct gc_arena gc = gc_new();
struct rtmsg m_rtmsg;
@@ -3990,7 +3932,7 @@ done:
* may be disabled by missing items.
*/
void
-get_default_gateway(struct route_gateway_info *rgi)
+get_default_gateway(struct route_gateway_info *rgi, openvpn_net_ctx_t *ctx)
{
CLEAR(*rgi);
}
@@ -256,15 +256,16 @@ void copy_route_ipv6_option_list(struct route_ipv6_option_list *dest,
void route_ipv6_clear_host_bits( struct route_ipv6 *r6 );
-void add_route_ipv6(struct route_ipv6 *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es);
+void add_route_ipv6(struct route_ipv6 *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es, openvpn_net_ctx_t *ctx);
-void delete_route_ipv6(const struct route_ipv6 *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es);
+void delete_route_ipv6(const struct route_ipv6 *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es, openvpn_net_ctx_t *ctx);
void add_route(struct route_ipv4 *r,
const struct tuntap *tt,
unsigned int flags,
const struct route_gateway_info *rgi,
- const struct env_set *es);
+ const struct env_set *es,
+ openvpn_net_ctx_t *ctx);
void add_route_to_option_list(struct route_option_list *l,
const char *network,
@@ -282,7 +283,8 @@ bool init_route_list(struct route_list *rl,
const char *remote_endpoint,
int default_metric,
in_addr_t remote_host,
- struct env_set *es);
+ struct env_set *es,
+ openvpn_net_ctx_t *ctx);
bool init_route_ipv6_list(struct route_ipv6_list *rl6,
const struct route_ipv6_option_list *opt6,
@@ -299,13 +301,15 @@ void add_routes(struct route_list *rl,
struct route_ipv6_list *rl6,
const struct tuntap *tt,
unsigned int flags,
- const struct env_set *es);
+ const struct env_set *es,
+ openvpn_net_ctx_t *ctx);
void delete_routes(struct route_list *rl,
struct route_ipv6_list *rl6,
const struct tuntap *tt,
unsigned int flags,
- const struct env_set *es);
+ const struct env_set *es,
+ openvpn_net_ctx_t *ctx);
void setenv_routes(struct env_set *es, const struct route_list *rl);
@@ -315,7 +319,8 @@ void setenv_routes_ipv6(struct env_set *es, const struct route_ipv6_list *rl6);
bool is_special_addr(const char *addr_str);
-void get_default_gateway(struct route_gateway_info *rgi);
+void get_default_gateway(struct route_gateway_info *rgi,
+ openvpn_net_ctx_t *ctx);
void get_default_gateway_ipv6(struct route_ipv6_gateway_info *rgi,
const struct in6_addr *dest);
@@ -2282,7 +2282,7 @@ push_peer_info(struct buffer *buf, struct tls_session *session)
{
/* push mac addr */
struct route_gateway_info rgi;
- get_default_gateway(&rgi);
+ get_default_gateway(&rgi, session->opt->net_ctx);
if (rgi.flags & RGI_HWADDR_DEFINED)
{
buf_printf(&out, "IV_HWADDR=%s\n", format_hex_ex(rgi.hwaddr, 6, 0, 1, ":", &gc));
@@ -306,6 +306,7 @@ struct tls_options
/* instance-wide environment variable set */
struct env_set *es;
+ openvpn_net_ctx_t *net_ctx;
const struct plugin_list *plugins;
/* compression parms */
@@ -453,13 +453,13 @@ check_subnet_conflict(const in_addr_t ip,
}
void
-warn_on_use_of_common_subnets(void)
+warn_on_use_of_common_subnets(openvpn_net_ctx_t *ctx)
{
struct gc_arena gc = gc_new();
struct route_gateway_info rgi;
const int needed = (RGI_ADDR_DEFINED|RGI_NETMASK_DEFINED);
- get_default_gateway(&rgi);
+ get_default_gateway(&rgi, ctx);
if ((rgi.flags & needed) == needed)
{
const in_addr_t lan_network = rgi.gateway.addr & rgi.gateway.netmask;
@@ -818,7 +818,7 @@ add_route_connected_v6_net(struct tuntap *tt,
r6.gateway = tt->local_ipv6;
r6.metric = 0; /* connected route */
r6.flags = RT_DEFINED | RT_METRIC_DEFINED;
- add_route_ipv6(&r6, tt, 0, es);
+ add_route_ipv6(&r6, tt, 0, es, NULL);
}
void
@@ -834,7 +834,7 @@ delete_route_connected_v6_net(struct tuntap *tt,
r6.metric = 0; /* connected route */
r6.flags = RT_DEFINED | RT_ADDED | RT_METRIC_DEFINED;
route_ipv6_clear_host_bits(&r6);
- delete_route_ipv6(&r6, tt, 0, es);
+ delete_route_ipv6(&r6, tt, 0, es, NULL);
}
#endif /* if defined(_WIN32) || defined(TARGET_DARWIN) || defined(TARGET_NETBSD) || defined(TARGET_OPENBSD) */
@@ -1170,7 +1170,7 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
r.netmask = tt->remote_netmask;
r.gateway = tt->local;
r.metric = 0;
- add_route(&r, tt, 0, NULL, es);
+ add_route(&r, tt, 0, NULL, es, NULL);
}
#elif defined(TARGET_OPENBSD)
@@ -1217,7 +1217,7 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
r.network = tt->local & tt->remote_netmask;
r.netmask = tt->remote_netmask;
r.gateway = remote_end;
- add_route(&r, tt, 0, NULL, es);
+ add_route(&r, tt, 0, NULL, es, NULL);
}
#elif defined(TARGET_NETBSD)
@@ -1259,7 +1259,7 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
r.network = tt->local & tt->remote_netmask;
r.netmask = tt->remote_netmask;
r.gateway = remote_end;
- add_route(&r, tt, 0, NULL, es);
+ add_route(&r, tt, 0, NULL, es, NULL);
}
#elif defined(TARGET_DARWIN)
@@ -1309,7 +1309,7 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
r.network = tt->local & tt->remote_netmask;
r.netmask = tt->remote_netmask;
r.gateway = tt->local;
- add_route(&r, tt, 0, NULL, es);
+ add_route(&r, tt, 0, NULL, es, NULL);
}
#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
@@ -1348,7 +1348,7 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
r.network = tt->local & tt->remote_netmask;
r.netmask = tt->remote_netmask;
r.gateway = remote_end;
- add_route(&r, tt, 0, NULL, es);
+ add_route(&r, tt, 0, NULL, es, NULL);
}
#elif defined(TARGET_AIX)
@@ -275,7 +275,7 @@ void check_subnet_conflict(const in_addr_t ip,
const in_addr_t netmask,
const char *prefix);
-void warn_on_use_of_common_subnets(void);
+void warn_on_use_of_common_subnets(openvpn_net_ctx_t *ctx);
/*
* Inline functions