@@ -448,7 +448,7 @@
check_add_routes_action(struct context *c, const bool errors)
{
bool route_status = do_route(&c->options, c->c1.route_list, c->c1.route_ipv6_list,
- c->c1.tuntap, c->plugins, c->c2.es, &c->net_ctx);
+ c->c1.tuntap, c->plugins, c->c2.es, &c->net_ctx, c->mode == CM_TOP);
int flags = (errors ? ISC_ERRORS : 0);
flags |= (!route_status ? ISC_ROUTE_ERRORS : 0);
@@ -1689,13 +1689,14 @@
const struct tuntap *tt,
const struct plugin_list *plugins,
struct env_set *es,
- openvpn_net_ctx_t *ctx)
+ openvpn_net_ctx_t *ctx,
+ const bool is_multipoint)
{
bool ret = true;
if (!options->route_noexec && ( route_list || route_ipv6_list ) )
{
ret = add_routes(route_list, route_ipv6_list, tt, ROUTE_OPTION_FLAGS(options),
- es, ctx);
+ es, ctx, is_multipoint);
setenv_int(es, "redirect_gateway", route_did_redirect_default_gateway(route_list));
}
#ifdef ENABLE_MANAGEMENT
@@ -1898,7 +1899,7 @@
c->options.dev_node,
&gc);
do_ifconfig(c->c1.tuntap, guess, c->c2.frame.tun_mtu, c->c2.es,
- &c->net_ctx);
+ &c->net_ctx, c->mode == CM_TOP);
}
/* possibly add routes */
@@ -1906,7 +1907,7 @@
{
/* Ignore route_delay, would cause ROUTE_BEFORE_TUN to be ignored */
bool status = do_route(&c->options, c->c1.route_list, c->c1.route_ipv6_list,
- c->c1.tuntap, c->plugins, c->c2.es, &c->net_ctx);
+ c->c1.tuntap, c->plugins, c->c2.es, &c->net_ctx, c->mode == CM_TOP);
*error_flags |= (status ? 0 : ISC_ROUTE_ERRORS);
}
#ifdef TARGET_ANDROID
@@ -1934,7 +1935,7 @@
&& ifconfig_order() == IFCONFIG_AFTER_TUN_OPEN)
{
do_ifconfig(c->c1.tuntap, c->c1.tuntap->actual_name,
- c->c2.frame.tun_mtu, c->c2.es, &c->net_ctx);
+ c->c2.frame.tun_mtu, c->c2.es, &c->net_ctx, c->mode == CM_TOP);
}
/* run the up script */
@@ -1960,7 +1961,7 @@
if ((route_order() == ROUTE_AFTER_TUN) && (!c->options.route_delay_defined))
{
int status = do_route(&c->options, c->c1.route_list, c->c1.route_ipv6_list,
- c->c1.tuntap, c->plugins, c->c2.es, &c->net_ctx);
+ c->c1.tuntap, c->plugins, c->c2.es, &c->net_ctx, c->mode == CM_TOP);
*error_flags |= (status ? 0 : ISC_ROUTE_ERRORS);
}
@@ -2086,7 +2087,7 @@
delete_routes(c->c1.route_list, c->c1.route_ipv6_list,
c->c1.tuntap, ROUTE_OPTION_FLAGS(&c->options),
- c->c2.es, &c->net_ctx);
+ c->c2.es, &c->net_ctx, c->mode == CM_TOP);
}
/* actually close tun/tap device based on --down-pre flag */
@@ -74,7 +74,7 @@
bool do_route(const struct options *options, struct route_list *route_list,
struct route_ipv6_list *route_ipv6_list, const struct tuntap *tt,
const struct plugin_list *plugins, struct env_set *es,
- openvpn_net_ctx_t *ctx);
+ openvpn_net_ctx_t *ctx, const bool is_multipoint);
void close_instance(struct context *c);
@@ -927,7 +927,8 @@
unsigned int flags,
const struct route_gateway_info *rgi,
const struct env_set *es,
- openvpn_net_ctx_t *ctx)
+ openvpn_net_ctx_t *ctx,
+ const bool is_multipoint)
{
struct route_ipv4 r;
CLEAR(r);
@@ -935,7 +936,7 @@
r.network = network;
r.netmask = netmask;
r.gateway = gateway;
- return add_route(&r, tt, flags, rgi, es, ctx);
+ return add_route(&r, tt, flags, rgi, es, ctx, is_multipoint);
}
static void
@@ -964,7 +965,8 @@
unsigned int flags,
const struct route_gateway_info *rgi,
const struct env_set *es,
- openvpn_net_ctx_t *ctx)
+ openvpn_net_ctx_t *ctx,
+ const bool is_multipoint)
{
int ret = true;
for (int i = 0; i < rb->n_bypass; ++i)
@@ -972,7 +974,7 @@
if (rb->bypass[i])
{
ret = add_route3(rb->bypass[i], IPV4_NETMASK_HOST, gateway, tt,
- flags | ROUTE_REF_GW, rgi, es, ctx) && ret;
+ flags | ROUTE_REF_GW, rgi, es, ctx, is_multipoint) && ret;
}
}
return ret;
@@ -1007,7 +1009,7 @@
static bool
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)
+ openvpn_net_ctx_t *ctx, const bool is_multipoint)
{
const char err[] = "NOTE: unable to redirect IPv4 default gateway --";
bool ret = true;
@@ -1059,7 +1061,7 @@
{
ret = add_route3(rl->spec.remote_host, IPV4_NETMASK_HOST,
rl->rgi.gateway.addr, tt, flags | ROUTE_REF_GW,
- &rl->rgi, es, ctx);
+ &rl->rgi, es, ctx, is_multipoint);
rl->iflags |= RL_DID_LOCAL;
}
else
@@ -1071,7 +1073,7 @@
/* route DHCP/DNS server traffic through original default gateway */
ret = add_bypass_routes(&rl->spec.bypass, rl->rgi.gateway.addr, tt, flags,
- &rl->rgi, es, ctx) && ret;
+ &rl->rgi, es, ctx, is_multipoint) && ret;
if (rl->flags & RG_REROUTE_GW)
{
@@ -1079,11 +1081,11 @@
{
/* add new default route (1st component) */
ret = add_route3(0x00000000, 0x80000000, rl->spec.remote_endpoint,
- tt, flags, &rl->rgi, es, ctx) && ret;
+ tt, flags, &rl->rgi, es, ctx, is_multipoint) && ret;
/* add new default route (2nd component) */
ret = add_route3(0x80000000, 0x80000000, rl->spec.remote_endpoint,
- tt, flags, &rl->rgi, es, ctx) && ret;
+ tt, flags, &rl->rgi, es, ctx, is_multipoint) && ret;
}
else
{
@@ -1097,7 +1099,7 @@
/* add new default route */
ret = add_route3(0, 0, rl->spec.remote_endpoint, tt,
- flags, &rl->rgi, es, ctx) && ret;
+ flags, &rl->rgi, es, ctx, is_multipoint) && ret;
}
}
@@ -1112,7 +1114,8 @@
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)
+ openvpn_net_ctx_t *ctx,
+ const bool is_multipoint)
{
if (rl && rl->iflags & RL_DID_REDIRECT_DEFAULT_GATEWAY)
{
@@ -1173,7 +1176,7 @@
if (rl->rgi.flags & RGI_ADDR_DEFINED)
{
add_route3(0, 0, rl->rgi.gateway.addr, tt,
- flags | ROUTE_REF_GW, &rl->rgi, es, ctx);
+ flags | ROUTE_REF_GW, &rl->rgi, es, ctx, is_multipoint);
}
}
}
@@ -1185,9 +1188,10 @@
bool
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)
+ const struct env_set *es, openvpn_net_ctx_t *ctx,
+ const bool is_multipoint)
{
- bool ret = redirect_default_route_to_vpn(rl, tt, flags, es, ctx);
+ bool ret = redirect_default_route_to_vpn(rl, tt, flags, es, ctx, is_multipoint);
if (rl && !(rl->iflags & RL_ROUTES_ADDED) )
{
struct route_ipv4 *r;
@@ -1220,7 +1224,7 @@
{
delete_route(r, tt, flags, &rl->rgi, es, ctx);
}
- ret = add_route(r, tt, flags, &rl->rgi, es, ctx) && ret;
+ ret = add_route(r, tt, flags, &rl->rgi, es, ctx, is_multipoint) && ret;
}
rl->iflags |= RL_ROUTES_ADDED;
}
@@ -1242,7 +1246,7 @@
{
delete_route_ipv6(r, tt, flags, es, ctx);
}
- ret = add_route_ipv6(r, tt, flags, es, ctx) && ret;
+ ret = add_route_ipv6(r, tt, flags, es, ctx, is_multipoint) && ret;
}
rl6->iflags |= RL_ROUTES_ADDED;
}
@@ -1253,7 +1257,8 @@
void
delete_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)
+ const struct env_set *es, openvpn_net_ctx_t *ctx,
+ const bool is_multipoint)
{
if (rl && rl->iflags & RL_ROUTES_ADDED)
{
@@ -1265,7 +1270,7 @@
rl->iflags &= ~RL_ROUTES_ADDED;
}
- undo_redirect_default_route_to_vpn(rl, tt, flags, es, ctx);
+ undo_redirect_default_route_to_vpn(rl, tt, flags, es, ctx, is_multipoint);
if (rl)
{
@@ -1561,13 +1566,47 @@
}
#endif
+static bool
+is_gateway_needed_ipv4(const struct route_ipv4 *r4,
+ const struct route_gateway_info *rgi,
+ const struct tuntap *tt,
+ const bool is_multipoint)
+{
+
+#ifndef _WIN32
+
+ if (rgi && (rgi->flags & RGI_IFACE_DEFINED) && rgi->iface[0] != 0) /* vpn server special route */
+ {
+ if (rgi->flags & RGI_ADDR_DEFINED && r4->gateway != 0)
+ {
+ return true;
+ }
+ }
+
+#endif
+
+ if (tt->type == DEV_TYPE_TAP
+ && !( (r4->flags & RT_METRIC_DEFINED) && r4->metric == 0 ) )
+ {
+ return true;
+ }
+
+ if (is_multipoint && !tt->options.disable_dco)
+ {
+ return true;
+ }
+
+ return false;
+}
+
bool
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,
- openvpn_net_ctx_t *ctx)
+ openvpn_net_ctx_t *ctx,
+ const bool is_multipoint)
{
int status = 0;
int is_local_route;
@@ -1581,15 +1620,11 @@
struct argv argv = argv_new();
struct gc_arena gc = gc_new();
-#if defined(TARGET_LINUX)
- const char *iface = tt->actual_name;
- if (rgi && rgi->iface[0] != '\0') /* vpn server special route */
+#ifndef _WIN32
+ const char *device = tt->actual_name;
+ if (rgi && (rgi->flags & RGI_IFACE_DEFINED)) /* vpn server special route */
{
- iface = rgi->iface;
- if (r->gateway != 0)
- {
- gateway_needed = true;
- }
+ device = rgi->iface;
}
#endif
@@ -1607,10 +1642,7 @@
goto done;
}
- if (tt->type == DEV_TYPE_TAP && !(r->flags & RT_METRIC_DEFINED && r->metric == 0))
- {
- gateway_needed = true;
- }
+ gateway_needed = is_gateway_needed_ipv4(r, rgi, tt, is_multipoint);
if (gateway_needed && r->gateway == 0)
{
@@ -1627,7 +1659,7 @@
if (is_on_link(is_local_route, flags, rgi))
{
- iface = rgi->iface;
+ device = rgi->iface;
}
if (r->flags & RT_METRIC_DEFINED)
@@ -1638,7 +1670,7 @@
status = RTA_SUCCESS;
int ret = net_route_v4_add(ctx, &r->network, netmask_to_netbits2(r->netmask),
gateway_needed ? &r->gateway : NULL,
- iface, 0, metric);
+ device, 0, metric);
if (ret == -EEXIST)
{
msg(D_ROUTE, "NOTE: Linux route add command failed because route exists");
@@ -1655,7 +1687,7 @@
if (rgi)
{
- snprintf(out, sizeof(out), "%s %s %s dev %s", network, netmask, gateway, rgi->iface);
+ snprintf(out, sizeof(out), "%s %s %s dev %s", network, netmask, gateway, device);
}
else
{
@@ -1759,7 +1791,7 @@
"ERROR: Solaris route add command failed");
status = ret ? RTA_SUCCESS : RTA_ERROR;
-#elif defined(TARGET_FREEBSD)
+#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
argv_printf(&argv, "%s add",
ROUTE_PATH);
@@ -1771,40 +1803,23 @@
}
#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)
+ if (gateway_needed)
{
- argv_printf_cat(&argv, "-rtt %d", r->metric);
+ argv_printf_cat(&argv, "-net %s %s %s",
+ network,
+ gateway,
+ netmask);
}
-#endif
-
- argv_printf_cat(&argv, "-net %s %s %s",
- network,
- gateway,
- netmask);
-
- /* FIXME -- add on-link support for Dragonfly */
+ else
+ {
+ argv_printf_cat(&argv, "-net %s -iface %s",
+ network,
+ device);
+ }
argv_msg(D_ROUTE, &argv);
bool ret = openvpn_execve_check(&argv, es, 0,
- "ERROR: DragonFly route add command failed");
+ "ERROR: BSD route add command failed");
status = ret ? RTA_SUCCESS : RTA_ERROR;
#elif defined(TARGET_DARWIN)
@@ -1830,10 +1845,19 @@
}
else
{
- argv_printf_cat(&argv, "-net %s %s %s",
- network,
- gateway,
- netmask);
+ if (gateway_needed)
+ {
+ argv_printf_cat(&argv, "-net %s %s %s",
+ network,
+ gateway,
+ netmask);
+ }
+ else
+ {
+ argv_printf_cat(&argv, "-net %s -interface %s",
+ network,
+ device);
+ }
}
argv_msg(D_ROUTE, &argv);
@@ -1853,11 +1877,19 @@
}
#endif
- argv_printf_cat(&argv, "-net %s %s -netmask %s",
- network,
- gateway,
- netmask);
-
+ if (gateway_needed)
+ {
+ argv_printf_cat(&argv, "-net %s %s -netmask %s",
+ network,
+ gateway,
+ netmask);
+ }
+ else
+ {
+ argv_printf_cat(&argv, "-net %s -interface %s",
+ network,
+ device);
+ }
/* FIXME -- add on-link support for OpenBSD/NetBSD */
argv_msg(D_ROUTE, &argv);
@@ -1923,10 +1955,98 @@
}
}
+static inline struct in6_addr
+netbits_to_netmask_ipv6(const int netbits)
+{
+ struct in6_addr netmask = {{{0}}};
+
+ if (netbits > 0 && netbits <= 128)
+ {
+ const int full_bytes = netbits / 8;
+ int i;
+ for (i = 0; i < full_bytes; i++)
+ {
+ netmask.s6_addr[i] = 0xFF;
+ }
+ if (netbits % 8)
+ {
+ netmask.s6_addr[i] = (0xFF << (8 - (netbits % 8)));
+ }
+ }
+
+ return netmask;
+}
+
+static bool
+is_gateway_in_vpn_subnet_ipv6(const struct in6_addr *gateway,
+ const struct in6_addr *vpn_subnet,
+ int netbits)
+{
+ struct in6_addr netmask = netbits_to_netmask_ipv6(netbits);
+
+ for (int i = 0; i < 16; i++)
+ {
+ if ((gateway->s6_addr[i] & netmask.s6_addr[i]) != (vpn_subnet->s6_addr[i] & netmask.s6_addr[i]))
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+static bool
+is_gateway_needed_ipv6(const struct route_ipv6 *r6,
+ const struct tuntap *tt,
+ const char *network,
+ const bool is_multipoint)
+{
+
+#ifndef _WIN32
+ if (r6->iface != NULL) /* VPN server special route */
+ {
+ if (!IN6_IS_ADDR_UNSPECIFIED(&r6->gateway))
+ {
+ return true;
+ }
+ }
+#endif
+
+ /*
+ * Filter out routes which are essentially no-ops
+ * (not currently done for IPv6)
+ */
+
+ /* On "tun" interface, we never set a gateway if the operating system
+ * can do "route to interface" - it does not add value, as the target
+ * dev already fully qualifies the route destination on point-to-point
+ * interfaces. OTOH, on "tap" interface, we must always set the
+ * gateway unless the route is to be an on-link network
+ */
+ if (tt->type == DEV_TYPE_TAP
+ && !( (r6->flags & RT_METRIC_DEFINED) && r6->metric == 0 ) )
+ {
+ return true;
+ }
+
+ /* if is server and dco enabled, the gateway is needed*/
+ if (is_multipoint && !tt->options.disable_dco)
+ {
+ return true;
+ }
+
+ if (is_gateway_in_vpn_subnet_ipv6(&r6->gateway, &tt->local_ipv6, tt->netbits_ipv6))
+ {
+ msg(D_ROUTE, "Ignoring gateway in VPN subnet for route %s/%d", network, r6->netbits);
+ return false;
+ }
+
+ return false;
+}
+
bool
add_route_ipv6(struct route_ipv6 *r6, const struct tuntap *tt,
unsigned int flags, const struct env_set *es,
- openvpn_net_ctx_t *ctx)
+ openvpn_net_ctx_t *ctx, const bool is_multipoint)
{
int status = 0;
bool gateway_needed = false;
@@ -1941,13 +2061,9 @@
#ifndef _WIN32
const char *device = tt->actual_name;
- if (r6->iface != NULL) /* vpn server special route */
+ if (r6->iface != NULL)
{
device = r6->iface;
- if (!IN6_IS_ADDR_UNSPECIFIED(&r6->gateway) )
- {
- gateway_needed = true;
- }
}
#endif
@@ -1955,6 +2071,8 @@
const char *network = print_in6_addr( r6->network, 0, &gc);
const char *gateway = print_in6_addr( r6->gateway, 0, &gc);
+ gateway_needed = is_gateway_needed_ipv6(r6, tt, network, is_multipoint);
+
#if defined(TARGET_DARWIN) \
|| defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \
|| defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
@@ -1982,23 +2100,6 @@
r6->adapter_index ? r6->adapter_index : tt->adapter_index);
#endif
- /*
- * Filter out routes which are essentially no-ops
- * (not currently done for IPv6)
- */
-
- /* On "tun" interface, we never set a gateway if the operating system
- * can do "route to interface" - it does not add value, as the target
- * dev already fully qualifies the route destination on point-to-point
- * interfaces. OTOH, on "tap" interface, we must always set the
- * gateway unless the route is to be an on-link network
- */
- if (tt->type == DEV_TYPE_TAP
- && !( (r6->flags & RT_METRIC_DEFINED) && r6->metric == 0 ) )
- {
- gateway_needed = true;
- }
-
if (gateway_needed && IN6_IS_ADDR_UNSPECIFIED(&r6->gateway))
{
msg(M_WARN, "ROUTE6 WARNING: " PACKAGE_NAME " needs a gateway "
@@ -2011,6 +2112,7 @@
#if defined(TARGET_LINUX)
int metric = -1;
+
if ((r6->flags & RT_METRIC_DEFINED) && (r6->metric > 0))
{
metric = r6->metric;
@@ -2121,9 +2223,18 @@
#elif defined(TARGET_OPENBSD)
- argv_printf(&argv, "%s add -inet6 %s -prefixlen %d %s",
+ argv_printf(&argv, "%s add -inet6 %s -prefixlen %d ",
ROUTE_PATH,
- network, r6->netbits, gateway );
+ 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,
@@ -2132,9 +2243,18 @@
#elif defined(TARGET_NETBSD)
- argv_printf(&argv, "%s add -inet6 %s/%d %s",
+ argv_printf(&argv, "%s add -inet6 %s/%d ",
ROUTE_PATH,
- network, r6->netbits, gateway );
+ 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,
@@ -271,13 +271,13 @@
void route_ipv6_clear_host_bits( struct route_ipv6 *r6 );
-bool add_route_ipv6(struct route_ipv6 *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es, openvpn_net_ctx_t *ctx);
+bool add_route_ipv6(struct route_ipv6 *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es, openvpn_net_ctx_t *ctx, const bool is_multipoint);
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);
bool add_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);
+ openvpn_net_ctx_t *ctx, const bool is_multipoint);
void add_route_to_option_list(struct route_option_list *l,
const char *network,
@@ -312,14 +312,16 @@
bool 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);
+ const struct env_set *es, openvpn_net_ctx_t *ctx,
+ const bool is_multipoint);
void delete_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);
+ openvpn_net_ctx_t *ctx,
+ const bool is_multipoint);
void setenv_routes(struct env_set *es, const struct route_list *rl);
@@ -1020,7 +1020,7 @@
*/
static void
add_route_connected_v6_net(struct tuntap *tt,
- const struct env_set *es)
+ const struct env_set *es, const bool is_multipoint)
{
struct route_ipv6 r6;
@@ -1030,7 +1030,7 @@
r6.gateway = tt->local_ipv6;
r6.metric = 0; /* connected route */
r6.flags = RT_DEFINED | RT_METRIC_DEFINED;
- add_route_ipv6(&r6, tt, 0, es, NULL);
+ add_route_ipv6(&r6, tt, 0, es, NULL, is_multipoint);
}
void
@@ -1087,7 +1087,8 @@
*/
static void
do_ifconfig_ipv6(struct tuntap *tt, const char *ifname, int tun_mtu,
- const struct env_set *es, openvpn_net_ctx_t *ctx)
+ const struct env_set *es, openvpn_net_ctx_t *ctx,
+ const bool is_multipoint)
{
#if !defined(TARGET_LINUX)
struct argv argv = argv_new();
@@ -1205,7 +1206,7 @@
#if defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) \
|| defined(TARGET_DARWIN)
/* and, hooray, we explicitly need to add a route... */
- add_route_connected_v6_net(tt, es);
+ add_route_connected_v6_net(tt, es, is_multipoint);
#endif
#elif defined(TARGET_AIX)
argv_printf(&argv, "%s %s inet6 %s/%d mtu %d up", IFCONFIG_PATH, ifname,
@@ -1231,7 +1232,7 @@
do_address_service(true, AF_INET6, tt);
if (tt->type == DEV_TYPE_TUN)
{
- add_route_connected_v6_net(tt, es);
+ add_route_connected_v6_net(tt, es, is_multipoint);
}
do_dns_service(true, AF_INET6, tt);
do_set_mtu_service(tt, AF_INET6, tun_mtu);
@@ -1259,7 +1260,7 @@
netsh_command(&argv, 4, M_FATAL);
if (tt->type == DEV_TYPE_TUN)
{
- add_route_connected_v6_net(tt, es);
+ add_route_connected_v6_net(tt, es, is_multipoint);
}
/* set ipv6 dns servers if any are specified */
netsh_set_dns6_servers(tt->options.dns6, tt->options.dns6_len, tt->adapter_index);
@@ -1291,7 +1292,7 @@
*/
static void
do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu,
- const struct env_set *es, openvpn_net_ctx_t *ctx)
+ const struct env_set *es, openvpn_net_ctx_t *ctx, const bool is_multipoint)
{
#if !defined(_WIN32) && !defined(TARGET_ANDROID)
/*
@@ -1415,7 +1416,7 @@
r.netmask = tt->remote_netmask;
r.gateway = tt->local;
r.metric = 0;
- add_route(&r, tt, 0, NULL, es, NULL);
+ add_route(&r, tt, 0, NULL, es, NULL, is_multipoint);
}
#elif defined(TARGET_OPENBSD)
@@ -1462,7 +1463,7 @@
r.network = tt->local & tt->remote_netmask;
r.netmask = tt->remote_netmask;
r.gateway = remote_end;
- add_route(&r, tt, 0, NULL, es, NULL);
+ add_route(&r, tt, 0, NULL, es, NULL, is_multipoint);
}
#elif defined(TARGET_NETBSD)
@@ -1504,7 +1505,7 @@
r.network = tt->local & tt->remote_netmask;
r.netmask = tt->remote_netmask;
r.gateway = remote_end;
- add_route(&r, tt, 0, NULL, es, NULL);
+ add_route(&r, tt, 0, NULL, es, NULL, is_multipoint);
}
#elif defined(TARGET_DARWIN)
@@ -1554,7 +1555,7 @@
r.network = tt->local & tt->remote_netmask;
r.netmask = tt->remote_netmask;
r.gateway = tt->local;
- add_route(&r, tt, 0, NULL, es, NULL);
+ add_route(&r, tt, 0, NULL, es, NULL, is_multipoint);
}
#elif defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY)
@@ -1648,7 +1649,7 @@
/* execute the ifconfig command through the shell */
void
do_ifconfig(struct tuntap *tt, const char *ifname, int tun_mtu,
- const struct env_set *es, openvpn_net_ctx_t *ctx)
+ const struct env_set *es, openvpn_net_ctx_t *ctx, const bool is_multipoint)
{
msg(D_LOW, "do_ifconfig, ipv4=%d, ipv6=%d", tt->did_ifconfig_setup,
tt->did_ifconfig_ipv6_setup);
@@ -1668,12 +1669,12 @@
if (tt->did_ifconfig_setup)
{
- do_ifconfig_ipv4(tt, ifname, tun_mtu, es, ctx);
+ do_ifconfig_ipv4(tt, ifname, tun_mtu, es, ctx, is_multipoint);
}
if (tt->did_ifconfig_ipv6_setup)
{
- do_ifconfig_ipv6(tt, ifname, tun_mtu, es, ctx);
+ do_ifconfig_ipv6(tt, ifname, tun_mtu, es, ctx, is_multipoint);
}
/* release resources potentially allocated during interface setup */
@@ -319,7 +319,7 @@
* @param ctx the networking API opaque context
*/
void do_ifconfig(struct tuntap *tt, const char *ifname, int tun_mtu,
- const struct env_set *es, openvpn_net_ctx_t *ctx);
+ const struct env_set *es, openvpn_net_ctx_t *ctx, const bool is_multipoint);
/**
* undo_ifconfig - undo configuration of the tunnel interface
@@ -754,6 +754,7 @@
}
const char *tun_stat(const struct tuntap *tt, unsigned int rwflags, struct gc_arena *gc);
+
bool tun_name_is_fixed(const char *dev);
static inline bool
Attention is currently required from: flichtenheld, plaisthos. Hello plaisthos, flichtenheld, I'd like you to do a code review. Please visit http://gerrit.openvpn.net/c/openvpn/+/678?usp=email to review the following change. Change subject: route: extended logic to omit gateway when unnecessary ...................................................................... route: extended logic to omit gateway when unnecessary Extracted and extended the logic behind 'gateway_needed' both in add_route() and add_route_ipv6(). Other than checking the dev-type, special routes and if the gateway is on-link, - set gateway_needed to true if the vpn instance is a multipoint server and DCO is enabled. - set gateway_needed to false if the gateway is in the vpn subnet. Additionally, extended support for these checks and conditions to DARWIN and BSD-based operating systems. These changes ensure that the gateway is only included when necessary, optimizing route configuration and potentially reducing redundant route entries. Change-Id: I3dbd61fef20d683734b55b73e40afe56c3b733e1 Signed-off-by: Marco Baffo <marco@mandelbit.com> --- M src/openvpn/forward.c M src/openvpn/init.c M src/openvpn/init.h M src/openvpn/route.c M src/openvpn/route.h M src/openvpn/tun.c M src/openvpn/tun.h 7 files changed, 253 insertions(+), 128 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/78/678/1