From: Selva Nair <selva.n...@gmail.com> - Set RL_DID_LOCAL only if the corresponding route addition succeeds. This is needed to preserve when the direct route to the vpn server preexists.
- Ensure net_route_v4/v6_add/del() functions using iproute2 return error when route addition fails. Return value follows the same logic as corresponding functions using netlink though all failure reasons get the same error code of -1. NOTE: delete_route_connected_v6_net() is called even if the corresponding addition fails. This looks harder to fix, but also less critical. Signed-off-by: Selva Nair <selva.n...@gmail.com> --- This anticipates two other cases of wrongly deleted routes to be fixed by https://patchwork.openvpn.net/project/openvpn2/patch/20230111160848.22906-1-g...@greenie.muc.de/ src/openvpn/networking_iproute2.c | 32 +++++++++++++++++++++++-------- src/openvpn/route.c | 26 ++++++++++++++----------- src/openvpn/route.h | 8 ++++---- 3 files changed, 43 insertions(+), 23 deletions(-) diff --git a/src/openvpn/networking_iproute2.c b/src/openvpn/networking_iproute2.c index f93756d6..0efeed0f 100644 --- a/src/openvpn/networking_iproute2.c +++ b/src/openvpn/networking_iproute2.c @@ -267,6 +267,7 @@ net_route_v4_add(openvpn_net_ctx_t *ctx, const in_addr_t *dst, int prefixlen, { struct argv argv = argv_new(); const char *dst_str = print_in_addr_t(*dst, 0, &ctx->gc); + int ret = 0; argv_printf(&argv, "%s route add %s/%d", iproute_path, dst_str, prefixlen); @@ -288,11 +289,14 @@ net_route_v4_add(openvpn_net_ctx_t *ctx, const in_addr_t *dst, int prefixlen, } argv_msg(D_ROUTE, &argv); - openvpn_execve_check(&argv, ctx->es, 0, "ERROR: Linux route add command failed"); + if (!openvpn_execve_check(&argv, ctx->es, 0, "ERROR: Linux route add command failed")) + { + ret = -1; + } argv_free(&argv); - return 0; + return ret; } int @@ -302,6 +306,7 @@ net_route_v6_add(openvpn_net_ctx_t *ctx, const struct in6_addr *dst, { struct argv argv = argv_new(); char *dst_str = (char *)print_in6_addr(*dst, 0, &ctx->gc); + int ret = 0; argv_printf(&argv, "%s -6 route add %s/%d dev %s", iproute_path, dst_str, prefixlen, iface); @@ -319,11 +324,14 @@ net_route_v6_add(openvpn_net_ctx_t *ctx, const struct in6_addr *dst, } argv_msg(D_ROUTE, &argv); - openvpn_execve_check(&argv, ctx->es, 0, "ERROR: Linux route -6 add command failed"); + if (!openvpn_execve_check(&argv, ctx->es, 0, "ERROR: Linux route -6 add command failed")) + { + ret = -1; + } argv_free(&argv); - return 0; + return ret; } int @@ -333,6 +341,7 @@ net_route_v4_del(openvpn_net_ctx_t *ctx, const in_addr_t *dst, int prefixlen, { struct argv argv = argv_new(); const char *dst_str = print_in_addr_t(*dst, 0, &ctx->gc); + int ret = 0; argv_printf(&argv, "%s route del %s/%d", iproute_path, dst_str, prefixlen); @@ -342,11 +351,14 @@ net_route_v4_del(openvpn_net_ctx_t *ctx, const in_addr_t *dst, int prefixlen, } argv_msg(D_ROUTE, &argv); - openvpn_execve_check(&argv, ctx->es, 0, "ERROR: Linux route delete command failed"); + if (!openvpn_execve_check(&argv, ctx->es, 0, "ERROR: Linux route delete command failed")) + { + ret = -1; + } argv_free(&argv); - return 0; + return ret; } int @@ -356,6 +368,7 @@ net_route_v6_del(openvpn_net_ctx_t *ctx, const struct in6_addr *dst, { struct argv argv = argv_new(); char *dst_str = (char *)print_in6_addr(*dst, 0, &ctx->gc); + int ret = 0; argv_printf(&argv, "%s -6 route del %s/%d dev %s", iproute_path, dst_str, prefixlen, iface); @@ -373,11 +386,14 @@ net_route_v6_del(openvpn_net_ctx_t *ctx, const struct in6_addr *dst, } argv_msg(D_ROUTE, &argv); - openvpn_execve_check(&argv, ctx->es, 0, "ERROR: Linux route -6 del command failed"); + if (!openvpn_execve_check(&argv, ctx->es, 0, "ERROR: Linux route -6 del command failed")) + { + ret = -1; + } argv_free(&argv); - return 0; + return ret; } int diff --git a/src/openvpn/route.c b/src/openvpn/route.c index 3a978cb4..20dacb5e 100644 --- a/src/openvpn/route.c +++ b/src/openvpn/route.c @@ -912,7 +912,7 @@ init_route_ipv6_list(struct route_ipv6_list *rl6, return ret; } -static bool +static int add_route3(in_addr_t network, in_addr_t netmask, in_addr_t gateway, @@ -1050,10 +1050,14 @@ redirect_default_route_to_vpn(struct route_list *rl, const struct tuntap *tt, if ((rl->spec.flags & RTSA_REMOTE_HOST) && rl->spec.remote_host != IPV4_INVALID_ADDR) { - ret = add_route3(rl->spec.remote_host, IPV4_NETMASK_HOST, - rl->rgi.gateway.addr, tt, flags | ROUTE_REF_GW, - &rl->rgi, es, ctx); - rl->iflags |= RL_DID_LOCAL; + int status = add_route3(rl->spec.remote_host, IPV4_NETMASK_HOST, + rl->rgi.gateway.addr, tt, flags | ROUTE_REF_GW, + &rl->rgi, es, ctx); + if (status == RTA_SUCCESS) + { + rl->iflags |= RL_DID_LOCAL; + } + ret = (status != RTA_ERROR); } else { @@ -1551,7 +1555,7 @@ is_on_link(const int is_local_route, const unsigned int flags, const struct rout return rgi && (is_local_route == LR_MATCH || ((flags & ROUTE_REF_GW) && (rgi->flags & RGI_ON_LINK))); } -bool +int add_route(struct route_ipv4 *r, const struct tuntap *tt, unsigned int flags, @@ -1564,7 +1568,7 @@ add_route(struct route_ipv4 *r, if (!(r->flags & RT_DEFINED)) { - return true; /* no error */ + return RTA_SUCCESS; /* no error */ } struct argv argv = argv_new(); @@ -1858,7 +1862,7 @@ done: /* release resources potentially allocated during route setup */ net_ctx_reset(ctx); - return (status != RTA_ERROR); + return status; } @@ -1885,7 +1889,7 @@ route_ipv6_clear_host_bits( struct route_ipv6 *r6 ) } } -bool +int add_route_ipv6(struct route_ipv6 *r6, const struct tuntap *tt, unsigned int flags, const struct env_set *es, openvpn_net_ctx_t *ctx) @@ -1895,7 +1899,7 @@ add_route_ipv6(struct route_ipv6 *r6, const struct tuntap *tt, if (!(r6->flags & RT_DEFINED) ) { - return true; /* no error */ + return RTA_SUCCESS; /* no error */ } struct argv argv = argv_new(); @@ -2131,7 +2135,7 @@ done: /* release resources potentially allocated during route setup */ net_ctx_reset(ctx); - return (status != RTA_ERROR); + return status; } static void diff --git a/src/openvpn/route.h b/src/openvpn/route.h index 71b4cf4e..1e110911 100644 --- a/src/openvpn/route.h +++ b/src/openvpn/route.h @@ -259,13 +259,13 @@ void copy_route_ipv6_option_list(struct route_ipv6_option_list *dest, 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); +int 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, 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); +int 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); void add_route_to_option_list(struct route_option_list *l, const char *network, -- 2.34.1 _______________________________________________ Openvpn-devel mailing list Openvpn-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openvpn-devel