diff options
Diffstat (limited to '')
-rw-r--r-- | options.c | 10 | ||||
-rw-r--r-- | route.c | 138 | ||||
-rw-r--r-- | route.h | 1 |
3 files changed, 80 insertions, 69 deletions
@@ -182,7 +182,7 @@ static const char usage_message[] = " by server EXCEPT for routes.\n" "--allow-pull-fqdn : Allow client to pull DNS names from server for\n" " --ifconfig, --route, and --route-gateway.\n" - "--redirect-gateway [flags]: (Experimental) Automatically execute routing\n" + "--redirect-gateway [flags]: Automatically execute routing\n" " commands to redirect all outgoing IP traffic through the\n" " VPN. Add 'local' flag if both " PACKAGE_NAME " servers are directly\n" " connected via a common subnet, such as with WiFi.\n" @@ -190,6 +190,8 @@ static const char usage_message[] = " and 128.0.0.0/1 rather than 0.0.0.0/0. Add 'bypass-dhcp'\n" " flag to add a direct route to DHCP server, bypassing tunnel.\n" " Add 'bypass-dns' flag to similarly bypass tunnel for DNS.\n" + "--redirect-private [flags]: Like --redirect-gateway, but omit actually changing\n" + " the default gateway. Useful when pushing private subnets.\n" "--setenv name value : Set a custom environmental variable to pass to script.\n" "--setenv FORWARD_COMPATIBLE 1 : Relax config file syntax checking to allow\n" " directives for future OpenVPN versions to be ignored.\n" @@ -4391,13 +4393,15 @@ add_option (struct options *options, VERIFY_PERMISSION (OPT_P_GENERAL); options->allow_pull_fqdn = true; } - else if (streq (p[0], "redirect-gateway")) + else if (streq (p[0], "redirect-gateway") || streq (p[0], "redirect-private")) { int j; VERIFY_PERMISSION (OPT_P_ROUTE); rol_check_alloc (options); for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j) { + if (streq (p[0], "redirect-gateway")) + options->routes->flags |= RG_REROUTE_GW; if (streq (p[j], "local")) options->routes->flags |= RG_LOCAL; else if (streq (p[j], "def1")) @@ -4408,7 +4412,7 @@ add_option (struct options *options, options->routes->flags |= RG_BYPASS_DNS; else { - msg (msglevel, "unknown --redirect-gateway flag: %s", p[j]); + msg (msglevel, "unknown --%s flag: %s", p[0], p[j]); goto err; } } @@ -543,18 +543,83 @@ redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, u /* route DHCP/DNS server traffic through original default gateway */ add_bypass_routes (&rl->spec.bypass, rl->spec.net_gateway, tt, flags, es); + if (rl->flags & RG_REROUTE_GW) + { + if (rl->flags & RG_DEF1) + { + /* add new default route (1st component) */ + add_route3 (0x00000000, + 0x80000000, + rl->spec.remote_endpoint, + tt, + flags, + es); + + /* add new default route (2nd component) */ + add_route3 (0x80000000, + 0x80000000, + rl->spec.remote_endpoint, + tt, + flags, + es); + } + else + { + /* delete default route */ + del_route3 (0, + 0, + rl->spec.net_gateway, + tt, + flags, + es); + + /* add new default route */ + add_route3 (0, + 0, + rl->spec.remote_endpoint, + tt, + flags, + es); + } + } + + /* set a flag so we can undo later */ + rl->did_redirect_default_gateway = true; + } + } +} + +static void +undo_redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, unsigned int flags, const struct env_set *es) +{ + if (rl->did_redirect_default_gateway) + { + /* delete remote host route */ + if (!(rl->flags & RG_LOCAL)) + del_route3 (rl->spec.remote_host, + ~0, + rl->spec.net_gateway, + tt, + flags, + es); + + /* delete special DHCP/DNS bypass route */ + del_bypass_routes (&rl->spec.bypass, rl->spec.net_gateway, tt, flags, es); + + if (rl->flags & RG_REROUTE_GW) + { if (rl->flags & RG_DEF1) { - /* add new default route (1st component) */ - add_route3 (0x00000000, + /* delete default route (1st component) */ + del_route3 (0x00000000, 0x80000000, rl->spec.remote_endpoint, tt, flags, es); - /* add new default route (2nd component) */ - add_route3 (0x80000000, + /* delete default route (2nd component) */ + del_route3 (0x80000000, 0x80000000, rl->spec.remote_endpoint, tt, @@ -566,78 +631,19 @@ redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, u /* delete default route */ del_route3 (0, 0, - rl->spec.net_gateway, + rl->spec.remote_endpoint, tt, flags, es); - /* add new default route */ + /* restore original default route */ add_route3 (0, 0, - rl->spec.remote_endpoint, + rl->spec.net_gateway, tt, flags, es); } - - /* set a flag so we can undo later */ - rl->did_redirect_default_gateway = true; - } - } -} - -static void -undo_redirect_default_route_to_vpn (struct route_list *rl, const struct tuntap *tt, unsigned int flags, const struct env_set *es) -{ - if (rl->did_redirect_default_gateway) - { - /* delete remote host route */ - if (!(rl->flags & RG_LOCAL)) - del_route3 (rl->spec.remote_host, - ~0, - rl->spec.net_gateway, - tt, - flags, - es); - - /* delete special DHCP/DNS bypass route */ - del_bypass_routes (&rl->spec.bypass, rl->spec.net_gateway, tt, flags, es); - - if (rl->flags & RG_DEF1) - { - /* delete default route (1st component) */ - del_route3 (0x00000000, - 0x80000000, - rl->spec.remote_endpoint, - tt, - flags, - es); - - /* delete default route (2nd component) */ - del_route3 (0x80000000, - 0x80000000, - rl->spec.remote_endpoint, - tt, - flags, - es); - } - else - { - /* delete default route */ - del_route3 (0, - 0, - rl->spec.remote_endpoint, - tt, - flags, - es); - - /* restore original default route */ - add_route3 (0, - 0, - rl->spec.net_gateway, - tt, - flags, - es); } rl->did_redirect_default_gateway = false; @@ -82,6 +82,7 @@ struct route_option { #define RG_DEF1 (1<<2) #define RG_BYPASS_DHCP (1<<3) #define RG_BYPASS_DNS (1<<4) +#define RG_REROUTE_GW (1<<5) struct route_option_list { int n; |