From: its_Giaan (C. Review) <ge...@op...> - 2024-02-15 14:53:00
|
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/+/524?usp=email to review the following change. Change subject: Route: add support for user defined routing table ...................................................................... Route: add support for user defined routing table 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. Fixes: Trac #1399 Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Signed-off-by: Gianmarco De Gregori <gia...@ma...> --- M doc/man-sections/vpn-network-options.rst M src/openvpn/helper.c M src/openvpn/init.c M src/openvpn/options.c M src/openvpn/options.h M src/openvpn/route.c M src/openvpn/route.h 7 files changed, 201 insertions(+), 16 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/24/524/1 diff --git a/doc/man-sections/vpn-network-options.rst b/doc/man-sections/vpn-network-options.rst index 41d367b..75da049 100644 --- a/doc/man-sections/vpn-network-options.rst +++ b/doc/man-sections/vpn-network-options.rst @@ -367,6 +367,14 @@ 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 @@ 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 @@ ``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 @@ 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 fa011ff..758160d 100644 --- a/src/openvpn/helper.c +++ b/src/openvpn/helper.c @@ -118,6 +118,7 @@ print_in_addr_t(network, 0, &o->gc), print_in_addr_t(netmask, 0, &o->gc), NULL, + NULL, NULL); } diff --git a/src/openvpn/init.c b/src/openvpn/init.c index c5cc154..c24e736 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -1481,6 +1481,7 @@ const char *gw = NULL; int dev = dev_type_enum(options->dev, options->dev_type); int metric = 0; + int 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 @@ -1499,6 +1500,10 @@ { 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; @@ -1508,6 +1513,7 @@ options->routes, gw, metric, + table_id, link_socket_current_remote(link_socket_info), es, ctx)) @@ -1526,6 +1532,7 @@ { const char *gw = NULL; int metric = -1; /* no metric set */ + int table_id = 0; /* unspec table */ /* see explanation in do_init_route_list() */ if (dco_enabled(options)) @@ -1544,6 +1551,11 @@ metric = options->route_default_metric; } + if (options->route_default_table_id) + { + table_id = options->route_default_table_id; + } + /* redirect (IPv6) gateway to VPN? if yes, add a few more specifics */ if (options->routes_ipv6->flags & RG_REROUTE_GW) @@ -1555,7 +1567,7 @@ { add_route_ipv6_to_option_list( options->routes_ipv6, string_alloc(opt_list[i], options->routes_ipv6->gc), - NULL, NULL ); + NULL, NULL, NULL ); } } @@ -1563,6 +1575,7 @@ options->routes_ipv6, gw, metric, + table_id, link_socket_current_remote_ipv6(link_socket_info), es, ctx)) diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 2c79a1e..e35cf9a 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -201,6 +201,10 @@ " pass --ifconfig parms by environment to scripts.\n" "--ifconfig-nowarn : Don't warn if the --ifconfig option on this side of the\n" " connection doesn't match the remote side.\n" +#ifdef TARGET_LINUX + "--route-table [table_id] : Specify a custom routing table for use with --route(-ipv6).\n" + " If not specified, the id of the default routing table will be used.\n" +#endif "--route network [netmask] [gateway] [metric] :\n" " Add route to routing table after connection\n" " is established. Multiple routes can be specified.\n" @@ -1909,6 +1913,7 @@ SHOW_STR(route_script); SHOW_STR(route_default_gateway); SHOW_INT(route_default_metric); + SHOW_INT(route_default_table_id); SHOW_BOOL(route_noexec); SHOW_INT(route_delay); SHOW_INT(route_delay_window); @@ -6981,7 +6986,16 @@ cnol_check_alloc(options); add_client_nat_to_option_list(options->client_nat, p[1], p[2], p[3], p[4], msglevel); } - else if (streq(p[0], "route") && p[1] && !p[5]) + else if (streq(p[0], "route-table") && p[1] && !p[2]) + { +#ifndef ENABLE_SITNL + msg(M_WARN, "NOTE: --route-table specified, but not supported on this platform"); +#endif + VERIFY_PERMISSION(OPT_P_ROUTE_TABLE); + options->route_default_table_id = positive_atoi(p[1]); + + } + else if (streq(p[0], "route") && p[1] && !p[6]) { VERIFY_PERMISSION(OPT_P_ROUTE); rol_check_alloc(options); @@ -7002,10 +7016,31 @@ msg(msglevel, "route parameter gateway '%s' must be a valid address", p[3]); goto err; } + /* p[4] is metric, if specified */ + + /* discard pulled routing table_id from server + * since this must be an entirely local choice */ + if (p[5]) + { + p[5] = NULL; + } } - add_route_to_option_list(options->routes, p[1], p[2], p[3], p[4]); + /* at the moment the routing table id is supported only by Linux/SITNL */ +#ifndef ENABLE_SITNL + if (p[5]) + { + static bool route_table_warned = false; + + if (!route_table_warned) + { + msg(M_WARN, "NOTE: table specified for --route, but not supported on this platform"); + route_table_warned = true; + } + } +#endif + add_route_to_option_list(options->routes, p[1], p[2], p[3], p[4], p[5]); } - else if (streq(p[0], "route-ipv6") && p[1] && !p[4]) + else if (streq(p[0], "route-ipv6") && p[1] && !p[5]) { VERIFY_PERMISSION(OPT_P_ROUTE); rol6_check_alloc(options); @@ -7021,9 +7056,31 @@ msg(msglevel, "route-ipv6 parameter gateway '%s' must be a valid address", p[2]); goto err; } - /* p[3] is metric, if present */ + /* p[3] is metric, if specified */ + + /* discard pulled routing table_id from server + * since this must be an entirely local choice */ + if (p[4]) + { + p[4] = NULL; + } } - add_route_ipv6_to_option_list(options->routes_ipv6, p[1], p[2], p[3]); + + /* at the moment the routing table id is supported only by Linux/SITNL */ +#ifndef ENABLE_SITNL + if (p[4]) + { + static bool route6_table_warned = false; + + if (!route6_table_warned) + { + msg(M_WARN, "NOTE: table specified for --route-ipv6, but not supported on this platform"); + route6_table_warned = true; + } + } +#endif + + add_route_ipv6_to_option_list(options->routes_ipv6, p[1], p[2], p[3], p[4]); } else if (streq(p[0], "max-routes") && !p[2]) { diff --git a/src/openvpn/options.h b/src/openvpn/options.h index 85de887..dced452 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -411,6 +411,7 @@ const char *route_predown_script; const char *route_default_gateway; const char *route_ipv6_default_gateway; + int route_default_table_id; int route_default_metric; bool route_noexec; int route_delay; @@ -741,6 +742,7 @@ #define OPT_P_PEER_ID (1<<28) #define OPT_P_INLINE (1<<29) #define OPT_P_PUSH_MTU (1<<30) +#define OPT_P_ROUTE_TABLE (1<<31) #define OPT_P_DEFAULT (~(OPT_P_INSTANCE|OPT_P_PULL_MODE)) diff --git a/src/openvpn/route.c b/src/openvpn/route.c index 6c027d9..e02c28a 100644 --- a/src/openvpn/route.c +++ b/src/openvpn/route.c @@ -325,7 +325,6 @@ CLEAR(*r); r->option = ro; - /* network */ if (!is_route_parm_defined(ro->network)) @@ -439,6 +438,27 @@ r->flags |= RT_DEFINED; + /* routing table id */ + + r->table_id = 0; + if (ro->table_id) + { + r->table_id = atoi(ro->table_id); + if (r->table_id < 0) + { + msg(M_WARN, PACKAGE_NAME "ROUTE: routing table id for network %s (%s) must be >= 0", + ro->network, + ro->table_id); + goto fail; + } + r->flags |= RT_TABLE_DEFINED; + } + else if (rl->spec.flags & RTSA_DEFAULT_TABLE_ID) + { + r->table_id = rl->spec.table_id; + r->flags |= RT_TABLE_DEFINED; + } + return true; fail: @@ -495,6 +515,27 @@ r6->flags |= RT_DEFINED; + /* routing table id */ + + r6->table_id = 0; + if (r6o->table_id) + { + r6->table_id = atoi(r6o->table_id); + if (r6->table_id < 0) + { + msg(M_WARN, PACKAGE_NAME "ROUTE: routing table id for network %s (%s) must be >= 0", + r6o->prefix, + r6o->table_id); + goto fail; + } + r6->flags |= RT_TABLE_DEFINED; + } + else if (rl6->spec_flags & RTSA_DEFAULT_TABLE_ID) + { + r6->table_id = rl6->default_route_table_id; + r6->flags |= RT_TABLE_DEFINED; + } + return true; fail: @@ -508,7 +549,8 @@ const char *network, const char *netmask, const char *gateway, - const char *metric) + const char *metric, + const char *table_id) { struct route_option *ro; ALLOC_OBJ_GC(ro, struct route_option, l->gc); @@ -516,6 +558,7 @@ ro->netmask = netmask; ro->gateway = gateway; ro->metric = metric; + ro->table_id = table_id; ro->next = l->routes; l->routes = ro; @@ -525,13 +568,15 @@ add_route_ipv6_to_option_list(struct route_ipv6_option_list *l, const char *prefix, const char *gateway, - const char *metric) + const char *metric, + const char *table_id) { struct route_ipv6_option *ro; ALLOC_OBJ_GC(ro, struct route_ipv6_option, l->gc); ro->prefix = prefix; ro->gateway = gateway; ro->metric = metric; + ro->table_id = table_id; ro->next = l->routes_ipv6; l->routes_ipv6 = ro; } @@ -630,6 +675,7 @@ const struct route_option_list *opt, const char *remote_endpoint, int default_metric, + int table_id, in_addr_t remote_host, struct env_set *es, openvpn_net_ctx_t *ctx) @@ -653,6 +699,12 @@ rl->spec.flags |= RTSA_DEFAULT_METRIC; } + if (table_id) + { + rl->spec.table_id = table_id; + rl->spec.flags |= RTSA_DEFAULT_TABLE_ID; + } + get_default_gateway(&rl->rgi, ctx); if (rl->rgi.flags & RGI_ADDR_DEFINED) { @@ -786,6 +838,7 @@ const struct route_ipv6_option_list *opt6, const char *remote_endpoint, int default_metric, + int table_id, const struct in6_addr *remote_host_ipv6, struct env_set *es, openvpn_net_ctx_t *ctx) @@ -810,6 +863,12 @@ rl6->spec_flags |= RTSA_DEFAULT_METRIC; } + if (table_id) + { + rl6->default_route_table_id = table_id; + rl6->spec_flags |= RTSA_DEFAULT_TABLE_ID; + } + msg(D_ROUTE, "GDG6: remote_host_ipv6=%s", remote_host_ipv6 ? print_in6_addr(*remote_host_ipv6, 0, &gc) : "n/a" ); @@ -1602,9 +1661,15 @@ metric = r->metric; } + int table_id = 0; + if (r->flags & RT_TABLE_DEFINED) + { + table_id = r->table_id; + } + status = RTA_SUCCESS; int ret = net_route_v4_add(ctx, &r->network, netmask_to_netbits2(r->netmask), - &r->gateway, iface, 0, metric); + &r->gateway, iface, table_id, metric); if (ret == -EEXIST) { msg(D_ROUTE, "NOTE: Linux route add command failed because route exists"); @@ -1982,10 +2047,16 @@ metric = r6->metric; } + int table_id = 0; + if ((r6->flags & RT_TABLE_DEFINED) && (r6->table_id > 0)) + { + table_id = r6->table_id; + } + status = RTA_SUCCESS; int ret = net_route_v6_add(ctx, &r6->network, r6->netbits, gateway_needed ? &r6->gateway : NULL, - device, 0, metric); + device, table_id, metric); if (ret == -EEXIST) { msg(D_ROUTE, "NOTE: Linux route add command failed because route exists"); @@ -2190,8 +2261,14 @@ metric = r->metric; } + int table_id = 0; + if (r->flags & RT_TABLE_DEFINED) + { + table_id = r->table_id; + } + if (net_route_v4_del(ctx, &r->network, netmask_to_netbits2(r->netmask), - &r->gateway, NULL, 0, metric) < 0) + &r->gateway, NULL, table_id, metric) < 0) { msg(M_WARN, "ERROR: Linux route delete command failed"); } @@ -2403,8 +2480,16 @@ metric = r6->metric; } + int table_id = 0; + if (r6->flags & RT_TABLE_DEFINED) + { + table_id = r6->table_id; + } + + + if (net_route_v6_del(ctx, &r6->network, r6->netbits, - gateway_needed ? &r6->gateway : NULL, device, 0, + gateway_needed ? &r6->gateway : NULL, device, table_id, metric) < 0) { msg(M_WARN, "ERROR: Linux route v6 delete command failed"); diff --git a/src/openvpn/route.h b/src/openvpn/route.h index 71b4cf4..ab7eaa4 100644 --- a/src/openvpn/route.h +++ b/src/openvpn/route.h @@ -63,12 +63,14 @@ #define RTSA_REMOTE_ENDPOINT (1<<0) #define RTSA_REMOTE_HOST (1<<1) #define RTSA_DEFAULT_METRIC (1<<2) +#define RTSA_DEFAULT_TABLE_ID (1<<3) unsigned int flags; in_addr_t remote_endpoint; in_addr_t remote_host; int remote_host_local; /* TLA_x value */ struct route_bypass bypass; + int table_id; int default_metric; }; @@ -77,6 +79,7 @@ const char *network; const char *netmask; const char *gateway; + const char *table_id; const char *metric; }; @@ -92,6 +95,7 @@ struct route_option_list { unsigned int flags; /* RG_x flags */ + struct route_option *routes; struct gc_arena *gc; }; @@ -101,6 +105,7 @@ const char *prefix; /* e.g. "2001:db8:1::/64" */ const char *gateway; /* e.g. "2001:db8:0::2" */ const char *metric; /* e.g. "5" */ + const char *table_id; }; struct route_ipv6_option_list { @@ -113,12 +118,14 @@ #define RT_DEFINED (1<<0) #define RT_ADDED (1<<1) #define RT_METRIC_DEFINED (1<<2) +#define RT_TABLE_DEFINED (1<<3) struct route_ipv4 *next; unsigned int flags; const struct route_option *option; in_addr_t network; in_addr_t netmask; in_addr_t gateway; + int table_id; int metric; }; @@ -129,6 +136,7 @@ unsigned int netbits; struct in6_addr gateway; int metric; + int table_id; /* gateway interface */ #ifdef _WIN32 DWORD adapter_index; /* interface or ~0 if undefined */ @@ -223,6 +231,7 @@ struct in6_addr remote_endpoint_ipv6; /* inside tun */ struct in6_addr remote_host_ipv6; /* --remote address */ int default_metric; + int default_route_table_id; struct route_ipv6_gateway_info rgi6; unsigned int flags; /* RG_x flags, see route_option_list */ @@ -271,17 +280,20 @@ const char *network, const char *netmask, const char *gateway, - const char *metric); + const char *metric, + const char *table_id); void add_route_ipv6_to_option_list(struct route_ipv6_option_list *l, const char *prefix, const char *gateway, - const char *metric); + const char *metric, + const char *table_id); bool init_route_list(struct route_list *rl, const struct route_option_list *opt, const char *remote_endpoint, int default_metric, + int table_id, in_addr_t remote_host, struct env_set *es, openvpn_net_ctx_t *ctx); @@ -290,6 +302,7 @@ const struct route_ipv6_option_list *opt6, const char *remote_endpoint, int default_metric, + int table_id, const struct in6_addr *remote_host, struct env_set *es, openvpn_net_ctx_t *ctx); -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/524?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Gerrit-Change-Number: 524 Gerrit-PatchSet: 1 Gerrit-Owner: its_Giaan <gia...@ma...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-Reviewer: plaisthos <arn...@rf...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: plaisthos <arn...@rf...> Gerrit-Attention: flichtenheld <fr...@li...> Gerrit-MessageType: newchange |
From: flichtenheld (C. Review) <ge...@op...> - 2024-02-16 16:35:27
|
Attention is currently required from: its_Giaan, plaisthos. flichtenheld has posted comments on this change. ( http://gerrit.openvpn.net/c/openvpn/+/524?usp=email ) Change subject: Route: add support for user defined routing table ...................................................................... Patch Set 1: Code-Review-1 (7 comments) Patchset: PS1: Functionality might be fine, but could use some polish File doc/man-sections/vpn-network-options.rst: http://gerrit.openvpn.net/c/openvpn/+/524/comment/22a0a3ac_de6d8584 : PS1, Line 407: default taken from ``--route-table`` if set, otherwise :code:`0`. Please change tab to spaces http://gerrit.openvpn.net/c/openvpn/+/524/comment/f27813f8_b24586f4 : PS1, Line 408: Should document that table-id can't be pushed. http://gerrit.openvpn.net/c/openvpn/+/524/comment/a3b9a424_093b4876 : PS1, Line 464: might be a good opportunity to make the description of --route-ipv6 more consistent with --route? Currently the descriptions are of a very different format and verbosity even though the options are very similar File src/openvpn/options.h: http://gerrit.openvpn.net/c/openvpn/+/524/comment/f5eb20b0_42a87049 : PS1, Line 745: #define OPT_P_ROUTE_TABLE (1<<31) it is not clear to my why you need a separate permission entry here? Should maybe add a comment about this. File src/openvpn/options.c: http://gerrit.openvpn.net/c/openvpn/+/524/comment/ca4f68fc_2a1a10c0 : PS1, Line 205: "--route-table [table_id] : Specify a custom routing table for use with --route(-ipv6).\n" table_id is not optional, so don't use brackets here http://gerrit.openvpn.net/c/openvpn/+/524/comment/a60bb82d_c3d5db58 : PS1, Line 6992: msg(M_WARN, "NOTE: --route-table specified, but not supported on this platform"); This warning would be confusing with a Linux build with --enable-iproute2. Maybe those should be two separate warnings? -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/524?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Gerrit-Change-Number: 524 Gerrit-PatchSet: 1 Gerrit-Owner: its_Giaan <gia...@ma...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-Reviewer: plaisthos <arn...@rf...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: plaisthos <arn...@rf...> Gerrit-Attention: its_Giaan <gia...@ma...> Gerrit-Comment-Date: Fri, 16 Feb 2024 16:35:10 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: Yes Gerrit-MessageType: comment |
From: its_Giaan (C. Review) <ge...@op...> - 2024-02-19 15:53:07
|
Attention is currently required from: flichtenheld, plaisthos. its_Giaan has posted comments on this change. ( http://gerrit.openvpn.net/c/openvpn/+/524?usp=email ) Change subject: Route: add support for user defined routing table ...................................................................... Patch Set 1: (2 comments) Patchset: PS1: I defined it but not set it to make sure that when retrieving the whitelist of pullable options in pull_permission_mask() the pull were not allowed but rather it printed an options error. File src/openvpn/options.h: http://gerrit.openvpn.net/c/openvpn/+/524/comment/81e9279e_e04fe802 : PS1, Line 745: #define OPT_P_ROUTE_TABLE (1<<31) > it is not clear to my why you need a separate permission entry here? Should maybe add a comment abou […] Acknowledged -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/524?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Gerrit-Change-Number: 524 Gerrit-PatchSet: 1 Gerrit-Owner: its_Giaan <gia...@ma...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-Reviewer: plaisthos <arn...@rf...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: plaisthos <arn...@rf...> Gerrit-Attention: flichtenheld <fr...@li...> Gerrit-Comment-Date: Mon, 19 Feb 2024 15:52:50 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: No Comment-In-Reply-To: flichtenheld <fr...@li...> Gerrit-MessageType: comment |
From: its_Giaan (C. Review) <ge...@op...> - 2024-02-20 13:33:30
|
Attention is currently required from: flichtenheld, plaisthos. its_Giaan has posted comments on this change. ( http://gerrit.openvpn.net/c/openvpn/+/524?usp=email ) Change subject: Route: add support for user defined routing table ...................................................................... Patch Set 1: (2 comments) Patchset: PS1: What about "Table_id is supported only on Linux when SITNL is built-in" so we know that in case we're on Linux but there's not SITNL -> "SITNL is required", on the other hand if we're not on Linux -> "this is Linux only" File src/openvpn/options.c: http://gerrit.openvpn.net/c/openvpn/+/524/comment/d372a561_90367367 : PS1, Line 6992: msg(M_WARN, "NOTE: --route-table specified, but not supported on this platform"); > This warning would be confusing with a Linux build with --enable-iproute2. […] What about "Table_id is supported only on Linux when SITNL is built-in" so we know that in case we're on Linux but there's not SITNL -> "SITNL is required", on the other hand if we're not on Linux -> "this is Linux only" -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/524?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Gerrit-Change-Number: 524 Gerrit-PatchSet: 1 Gerrit-Owner: its_Giaan <gia...@ma...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-Reviewer: plaisthos <arn...@rf...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: plaisthos <arn...@rf...> Gerrit-Attention: flichtenheld <fr...@li...> Gerrit-Comment-Date: Tue, 20 Feb 2024 13:33:18 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: No Comment-In-Reply-To: flichtenheld <fr...@li...> Gerrit-MessageType: comment |
From: flichtenheld (C. Review) <ge...@op...> - 2024-02-20 13:44:50
|
Attention is currently required from: its_Giaan, plaisthos. flichtenheld has posted comments on this change. ( http://gerrit.openvpn.net/c/openvpn/+/524?usp=email ) Change subject: Route: add support for user defined routing table ...................................................................... Patch Set 1: (1 comment) File src/openvpn/options.c: http://gerrit.openvpn.net/c/openvpn/+/524/comment/3d97c488_535a77ac : PS1, Line 6992: msg(M_WARN, "NOTE: --route-table specified, but not supported on this platform"); > What about "Table_id is supported only on Linux when SITNL is built-in" so we know that in case we'r […] Sounds good to me. -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/524?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Gerrit-Change-Number: 524 Gerrit-PatchSet: 1 Gerrit-Owner: its_Giaan <gia...@ma...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-Reviewer: plaisthos <arn...@rf...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: plaisthos <arn...@rf...> Gerrit-Attention: its_Giaan <gia...@ma...> Gerrit-Comment-Date: Tue, 20 Feb 2024 13:44:42 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: No Comment-In-Reply-To: its_Giaan <gia...@ma...> Comment-In-Reply-To: flichtenheld <fr...@li...> Gerrit-MessageType: comment |
From: its_Giaan (C. Review) <ge...@op...> - 2024-02-20 13:57:37
|
Attention is currently required from: flichtenheld, its_Giaan, plaisthos. Hello flichtenheld, plaisthos, I'd like you to reexamine a change. Please visit http://gerrit.openvpn.net/c/openvpn/+/524?usp=email to look at the new patch set (#2). The following approvals got outdated and were removed: Code-Review-1 by flichtenheld Change subject: Route: add support for user defined routing table ...................................................................... Route: add support for user defined routing table 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. Fixes: Trac #1399 Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Signed-off-by: Gianmarco De Gregori <gia...@ma...> --- M doc/man-sections/vpn-network-options.rst M src/openvpn/helper.c M src/openvpn/init.c M src/openvpn/options.c M src/openvpn/options.h M src/openvpn/route.c M src/openvpn/route.h 7 files changed, 214 insertions(+), 19 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/24/524/2 diff --git a/doc/man-sections/vpn-network-options.rst b/doc/man-sections/vpn-network-options.rst index 41d367b..9a7ba02 100644 --- a/doc/man-sections/vpn-network-options.rst +++ b/doc/man-sections/vpn-network-options.rst @@ -367,6 +367,14 @@ 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 @@ 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,10 @@ ``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). + Since this option must be an entirely local choice, won't be pushable. + 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`. @@ -441,14 +454,25 @@ Setup IPv6 routing in the system to send the specified IPv6 network into OpenVPN's *tun*. - Valid syntax: + Valid syntaxes: :: + route-ipv6 ipv6addr/bits + route-ipv6 ipv6addr/bits [gateway] route-ipv6 ipv6addr/bits [gateway] [metric] + route-ipv6 ipv6addr/bits [gateway] [metric] [table-id] + + ``gateway`` + Only used for IPv6 routes across *tap* devices, + and if missing, the ``ipv6remote`` field from ``--ifconfig-ipv6`` or + ``--route-ipv6-gateway`` is used. - 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. + ``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). + Since this option must be an entirely local choice, won't be pushable. + default taken from ``--route-table`` if set, otherwise :code:`0`. --route-gateway arg Specify a default *gateway* for use with ``--route``. diff --git a/src/openvpn/helper.c b/src/openvpn/helper.c index fa011ff..758160d 100644 --- a/src/openvpn/helper.c +++ b/src/openvpn/helper.c @@ -118,6 +118,7 @@ print_in_addr_t(network, 0, &o->gc), print_in_addr_t(netmask, 0, &o->gc), NULL, + NULL, NULL); } diff --git a/src/openvpn/init.c b/src/openvpn/init.c index c5cc154..c24e736 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -1481,6 +1481,7 @@ const char *gw = NULL; int dev = dev_type_enum(options->dev, options->dev_type); int metric = 0; + int 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 @@ -1499,6 +1500,10 @@ { 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; @@ -1508,6 +1513,7 @@ options->routes, gw, metric, + table_id, link_socket_current_remote(link_socket_info), es, ctx)) @@ -1526,6 +1532,7 @@ { const char *gw = NULL; int metric = -1; /* no metric set */ + int table_id = 0; /* unspec table */ /* see explanation in do_init_route_list() */ if (dco_enabled(options)) @@ -1544,6 +1551,11 @@ metric = options->route_default_metric; } + if (options->route_default_table_id) + { + table_id = options->route_default_table_id; + } + /* redirect (IPv6) gateway to VPN? if yes, add a few more specifics */ if (options->routes_ipv6->flags & RG_REROUTE_GW) @@ -1555,7 +1567,7 @@ { add_route_ipv6_to_option_list( options->routes_ipv6, string_alloc(opt_list[i], options->routes_ipv6->gc), - NULL, NULL ); + NULL, NULL, NULL ); } } @@ -1563,6 +1575,7 @@ options->routes_ipv6, gw, metric, + table_id, link_socket_current_remote_ipv6(link_socket_info), es, ctx)) diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 2c79a1e..0fe4595 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -201,6 +201,10 @@ " pass --ifconfig parms by environment to scripts.\n" "--ifconfig-nowarn : Don't warn if the --ifconfig option on this side of the\n" " connection doesn't match the remote side.\n" +#ifdef TARGET_LINUX + "--route-table table_id : Specify a custom routing table for use with --route(-ipv6).\n" + " If not specified, the id of the default routing table will be used.\n" +#endif "--route network [netmask] [gateway] [metric] :\n" " Add route to routing table after connection\n" " is established. Multiple routes can be specified.\n" @@ -1909,6 +1913,7 @@ SHOW_STR(route_script); SHOW_STR(route_default_gateway); SHOW_INT(route_default_metric); + SHOW_INT(route_default_table_id); SHOW_BOOL(route_noexec); SHOW_INT(route_delay); SHOW_INT(route_delay_window); @@ -6981,7 +6986,16 @@ cnol_check_alloc(options); add_client_nat_to_option_list(options->client_nat, p[1], p[2], p[3], p[4], msglevel); } - else if (streq(p[0], "route") && p[1] && !p[5]) + else if (streq(p[0], "route-table") && p[1] && !p[2]) + { +#ifndef ENABLE_SITNL + msg(M_WARN, "NOTE: --route-table is supported only on Linux when SITNL is built-in"); +#endif + VERIFY_PERMISSION(OPT_P_ROUTE_TABLE); + options->route_default_table_id = positive_atoi(p[1]); + + } + else if (streq(p[0], "route") && p[1] && !p[6]) { VERIFY_PERMISSION(OPT_P_ROUTE); rol_check_alloc(options); @@ -7002,10 +7016,31 @@ msg(msglevel, "route parameter gateway '%s' must be a valid address", p[3]); goto err; } + /* p[4] is metric, if specified */ + + /* discard pulled routing table_id from server + * since this must be an entirely local choice */ + if (p[5]) + { + p[5] = NULL; + } } - add_route_to_option_list(options->routes, p[1], p[2], p[3], p[4]); + /* at the moment the routing table id is supported only by Linux/SITNL */ +#ifndef ENABLE_SITNL + if (p[5]) + { + static bool route_table_warned = false; + + if (!route_table_warned) + { + msg(M_WARN, "NOTE: table specified for --route, but not supported on this platform"); + route_table_warned = true; + } + } +#endif + add_route_to_option_list(options->routes, p[1], p[2], p[3], p[4], p[5]); } - else if (streq(p[0], "route-ipv6") && p[1] && !p[4]) + else if (streq(p[0], "route-ipv6") && p[1] && !p[5]) { VERIFY_PERMISSION(OPT_P_ROUTE); rol6_check_alloc(options); @@ -7021,9 +7056,31 @@ msg(msglevel, "route-ipv6 parameter gateway '%s' must be a valid address", p[2]); goto err; } - /* p[3] is metric, if present */ + /* p[3] is metric, if specified */ + + /* discard pulled routing table_id from server + * since this must be an entirely local choice */ + if (p[4]) + { + p[4] = NULL; + } } - add_route_ipv6_to_option_list(options->routes_ipv6, p[1], p[2], p[3]); + + /* at the moment the routing table id is supported only by Linux/SITNL */ +#ifndef ENABLE_SITNL + if (p[4]) + { + static bool route6_table_warned = false; + + if (!route6_table_warned) + { + msg(M_WARN, "NOTE: table specified for --route-ipv6, but not supported on this platform"); + route6_table_warned = true; + } + } +#endif + + add_route_ipv6_to_option_list(options->routes_ipv6, p[1], p[2], p[3], p[4]); } else if (streq(p[0], "max-routes") && !p[2]) { diff --git a/src/openvpn/options.h b/src/openvpn/options.h index 85de887..dced452 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -411,6 +411,7 @@ const char *route_predown_script; const char *route_default_gateway; const char *route_ipv6_default_gateway; + int route_default_table_id; int route_default_metric; bool route_noexec; int route_delay; @@ -741,6 +742,7 @@ #define OPT_P_PEER_ID (1<<28) #define OPT_P_INLINE (1<<29) #define OPT_P_PUSH_MTU (1<<30) +#define OPT_P_ROUTE_TABLE (1<<31) #define OPT_P_DEFAULT (~(OPT_P_INSTANCE|OPT_P_PULL_MODE)) diff --git a/src/openvpn/route.c b/src/openvpn/route.c index 6c027d9..e02c28a 100644 --- a/src/openvpn/route.c +++ b/src/openvpn/route.c @@ -325,7 +325,6 @@ CLEAR(*r); r->option = ro; - /* network */ if (!is_route_parm_defined(ro->network)) @@ -439,6 +438,27 @@ r->flags |= RT_DEFINED; + /* routing table id */ + + r->table_id = 0; + if (ro->table_id) + { + r->table_id = atoi(ro->table_id); + if (r->table_id < 0) + { + msg(M_WARN, PACKAGE_NAME "ROUTE: routing table id for network %s (%s) must be >= 0", + ro->network, + ro->table_id); + goto fail; + } + r->flags |= RT_TABLE_DEFINED; + } + else if (rl->spec.flags & RTSA_DEFAULT_TABLE_ID) + { + r->table_id = rl->spec.table_id; + r->flags |= RT_TABLE_DEFINED; + } + return true; fail: @@ -495,6 +515,27 @@ r6->flags |= RT_DEFINED; + /* routing table id */ + + r6->table_id = 0; + if (r6o->table_id) + { + r6->table_id = atoi(r6o->table_id); + if (r6->table_id < 0) + { + msg(M_WARN, PACKAGE_NAME "ROUTE: routing table id for network %s (%s) must be >= 0", + r6o->prefix, + r6o->table_id); + goto fail; + } + r6->flags |= RT_TABLE_DEFINED; + } + else if (rl6->spec_flags & RTSA_DEFAULT_TABLE_ID) + { + r6->table_id = rl6->default_route_table_id; + r6->flags |= RT_TABLE_DEFINED; + } + return true; fail: @@ -508,7 +549,8 @@ const char *network, const char *netmask, const char *gateway, - const char *metric) + const char *metric, + const char *table_id) { struct route_option *ro; ALLOC_OBJ_GC(ro, struct route_option, l->gc); @@ -516,6 +558,7 @@ ro->netmask = netmask; ro->gateway = gateway; ro->metric = metric; + ro->table_id = table_id; ro->next = l->routes; l->routes = ro; @@ -525,13 +568,15 @@ add_route_ipv6_to_option_list(struct route_ipv6_option_list *l, const char *prefix, const char *gateway, - const char *metric) + const char *metric, + const char *table_id) { struct route_ipv6_option *ro; ALLOC_OBJ_GC(ro, struct route_ipv6_option, l->gc); ro->prefix = prefix; ro->gateway = gateway; ro->metric = metric; + ro->table_id = table_id; ro->next = l->routes_ipv6; l->routes_ipv6 = ro; } @@ -630,6 +675,7 @@ const struct route_option_list *opt, const char *remote_endpoint, int default_metric, + int table_id, in_addr_t remote_host, struct env_set *es, openvpn_net_ctx_t *ctx) @@ -653,6 +699,12 @@ rl->spec.flags |= RTSA_DEFAULT_METRIC; } + if (table_id) + { + rl->spec.table_id = table_id; + rl->spec.flags |= RTSA_DEFAULT_TABLE_ID; + } + get_default_gateway(&rl->rgi, ctx); if (rl->rgi.flags & RGI_ADDR_DEFINED) { @@ -786,6 +838,7 @@ const struct route_ipv6_option_list *opt6, const char *remote_endpoint, int default_metric, + int table_id, const struct in6_addr *remote_host_ipv6, struct env_set *es, openvpn_net_ctx_t *ctx) @@ -810,6 +863,12 @@ rl6->spec_flags |= RTSA_DEFAULT_METRIC; } + if (table_id) + { + rl6->default_route_table_id = table_id; + rl6->spec_flags |= RTSA_DEFAULT_TABLE_ID; + } + msg(D_ROUTE, "GDG6: remote_host_ipv6=%s", remote_host_ipv6 ? print_in6_addr(*remote_host_ipv6, 0, &gc) : "n/a" ); @@ -1602,9 +1661,15 @@ metric = r->metric; } + int table_id = 0; + if (r->flags & RT_TABLE_DEFINED) + { + table_id = r->table_id; + } + status = RTA_SUCCESS; int ret = net_route_v4_add(ctx, &r->network, netmask_to_netbits2(r->netmask), - &r->gateway, iface, 0, metric); + &r->gateway, iface, table_id, metric); if (ret == -EEXIST) { msg(D_ROUTE, "NOTE: Linux route add command failed because route exists"); @@ -1982,10 +2047,16 @@ metric = r6->metric; } + int table_id = 0; + if ((r6->flags & RT_TABLE_DEFINED) && (r6->table_id > 0)) + { + table_id = r6->table_id; + } + status = RTA_SUCCESS; int ret = net_route_v6_add(ctx, &r6->network, r6->netbits, gateway_needed ? &r6->gateway : NULL, - device, 0, metric); + device, table_id, metric); if (ret == -EEXIST) { msg(D_ROUTE, "NOTE: Linux route add command failed because route exists"); @@ -2190,8 +2261,14 @@ metric = r->metric; } + int table_id = 0; + if (r->flags & RT_TABLE_DEFINED) + { + table_id = r->table_id; + } + if (net_route_v4_del(ctx, &r->network, netmask_to_netbits2(r->netmask), - &r->gateway, NULL, 0, metric) < 0) + &r->gateway, NULL, table_id, metric) < 0) { msg(M_WARN, "ERROR: Linux route delete command failed"); } @@ -2403,8 +2480,16 @@ metric = r6->metric; } + int table_id = 0; + if (r6->flags & RT_TABLE_DEFINED) + { + table_id = r6->table_id; + } + + + if (net_route_v6_del(ctx, &r6->network, r6->netbits, - gateway_needed ? &r6->gateway : NULL, device, 0, + gateway_needed ? &r6->gateway : NULL, device, table_id, metric) < 0) { msg(M_WARN, "ERROR: Linux route v6 delete command failed"); diff --git a/src/openvpn/route.h b/src/openvpn/route.h index 71b4cf4..ab7eaa4 100644 --- a/src/openvpn/route.h +++ b/src/openvpn/route.h @@ -63,12 +63,14 @@ #define RTSA_REMOTE_ENDPOINT (1<<0) #define RTSA_REMOTE_HOST (1<<1) #define RTSA_DEFAULT_METRIC (1<<2) +#define RTSA_DEFAULT_TABLE_ID (1<<3) unsigned int flags; in_addr_t remote_endpoint; in_addr_t remote_host; int remote_host_local; /* TLA_x value */ struct route_bypass bypass; + int table_id; int default_metric; }; @@ -77,6 +79,7 @@ const char *network; const char *netmask; const char *gateway; + const char *table_id; const char *metric; }; @@ -92,6 +95,7 @@ struct route_option_list { unsigned int flags; /* RG_x flags */ + struct route_option *routes; struct gc_arena *gc; }; @@ -101,6 +105,7 @@ const char *prefix; /* e.g. "2001:db8:1::/64" */ const char *gateway; /* e.g. "2001:db8:0::2" */ const char *metric; /* e.g. "5" */ + const char *table_id; }; struct route_ipv6_option_list { @@ -113,12 +118,14 @@ #define RT_DEFINED (1<<0) #define RT_ADDED (1<<1) #define RT_METRIC_DEFINED (1<<2) +#define RT_TABLE_DEFINED (1<<3) struct route_ipv4 *next; unsigned int flags; const struct route_option *option; in_addr_t network; in_addr_t netmask; in_addr_t gateway; + int table_id; int metric; }; @@ -129,6 +136,7 @@ unsigned int netbits; struct in6_addr gateway; int metric; + int table_id; /* gateway interface */ #ifdef _WIN32 DWORD adapter_index; /* interface or ~0 if undefined */ @@ -223,6 +231,7 @@ struct in6_addr remote_endpoint_ipv6; /* inside tun */ struct in6_addr remote_host_ipv6; /* --remote address */ int default_metric; + int default_route_table_id; struct route_ipv6_gateway_info rgi6; unsigned int flags; /* RG_x flags, see route_option_list */ @@ -271,17 +280,20 @@ const char *network, const char *netmask, const char *gateway, - const char *metric); + const char *metric, + const char *table_id); void add_route_ipv6_to_option_list(struct route_ipv6_option_list *l, const char *prefix, const char *gateway, - const char *metric); + const char *metric, + const char *table_id); bool init_route_list(struct route_list *rl, const struct route_option_list *opt, const char *remote_endpoint, int default_metric, + int table_id, in_addr_t remote_host, struct env_set *es, openvpn_net_ctx_t *ctx); @@ -290,6 +302,7 @@ const struct route_ipv6_option_list *opt6, const char *remote_endpoint, int default_metric, + int table_id, const struct in6_addr *remote_host, struct env_set *es, openvpn_net_ctx_t *ctx); -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/524?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Gerrit-Change-Number: 524 Gerrit-PatchSet: 2 Gerrit-Owner: its_Giaan <gia...@ma...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-Reviewer: plaisthos <arn...@rf...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: plaisthos <arn...@rf...> Gerrit-Attention: its_Giaan <gia...@ma...> Gerrit-Attention: flichtenheld <fr...@li...> Gerrit-MessageType: newpatchset |
From: its_Giaan (C. Review) <ge...@op...> - 2024-02-20 13:58:20
|
Attention is currently required from: flichtenheld, plaisthos. its_Giaan has posted comments on this change. ( http://gerrit.openvpn.net/c/openvpn/+/524?usp=email ) Change subject: Route: add support for user defined routing table ...................................................................... Patch Set 2: (5 comments) File doc/man-sections/vpn-network-options.rst: http://gerrit.openvpn.net/c/openvpn/+/524/comment/8ef327d5_482e958e : PS1, Line 407: default taken from ``--route-table`` if set, otherwise :code:`0`. > Please change tab to spaces Done http://gerrit.openvpn.net/c/openvpn/+/524/comment/9c8be01e_92c07a0f : PS1, Line 408: > Should document that table-id can't be pushed. Done http://gerrit.openvpn.net/c/openvpn/+/524/comment/2891fff7_f030a0a0 : PS1, Line 464: > might be a good opportunity to make the description of --route-ipv6 more consistent with --route? Cu […] Done File src/openvpn/options.c: http://gerrit.openvpn.net/c/openvpn/+/524/comment/0ca031f1_18cfb87a : PS1, Line 205: "--route-table [table_id] : Specify a custom routing table for use with --route(-ipv6).\n" > table_id is not optional, so don't use brackets here Done http://gerrit.openvpn.net/c/openvpn/+/524/comment/e912ffc8_22f4e21d : PS1, Line 6992: msg(M_WARN, "NOTE: --route-table specified, but not supported on this platform"); > Sounds good to me. Done -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/524?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Gerrit-Change-Number: 524 Gerrit-PatchSet: 2 Gerrit-Owner: its_Giaan <gia...@ma...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-Reviewer: plaisthos <arn...@rf...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: plaisthos <arn...@rf...> Gerrit-Attention: flichtenheld <fr...@li...> Gerrit-Comment-Date: Tue, 20 Feb 2024 13:58:11 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: No Comment-In-Reply-To: its_Giaan <gia...@ma...> Comment-In-Reply-To: flichtenheld <fr...@li...> Gerrit-MessageType: comment |
From: flichtenheld (C. Review) <ge...@op...> - 2024-03-12 17:11:43
|
Attention is currently required from: its_Giaan, plaisthos. flichtenheld has posted comments on this change. ( http://gerrit.openvpn.net/c/openvpn/+/524?usp=email ) Change subject: Route: add support for user defined routing table ...................................................................... Patch Set 3: Code-Review-1 (7 comments) File doc/man-sections/vpn-network-options.rst: http://gerrit.openvpn.net/c/openvpn/+/524/comment/29fafc4d_019065e1 : PS3, Line 374: a user defined routing table can be used instead. "an user" http://gerrit.openvpn.net/c/openvpn/+/524/comment/cfaf208a_43bb3e07 : PS3, Line 407: Since this option must be an entirely local choice, won't be pushable. Time seems weird to me, would change to "it isn't pushable" http://gerrit.openvpn.net/c/openvpn/+/524/comment/c5dce9cb_c194c9e8 : PS3, Line 408: default taken from ``--route-table`` if set, otherwise :code:`0`. please change tab to space http://gerrit.openvpn.net/c/openvpn/+/524/comment/186800fb_289c2ebc : PS3, Line 461: route-ipv6 ipv6addr/bits [gateway] when listing all possible choices, you can leave off the "[" optional markers http://gerrit.openvpn.net/c/openvpn/+/524/comment/dc32db5a_b03f8605 : PS3, Line 464: trailing whitespace http://gerrit.openvpn.net/c/openvpn/+/524/comment/c7665500_392297ff : PS3, Line 475: default taken from ``--route-table`` if set, otherwise :code:`0`. same comments apply here as for --route (tab, won't->it isn't) File src/openvpn/route.h: http://gerrit.openvpn.net/c/openvpn/+/524/comment/f42523ea_da5a7db8 : PS3, Line 98: spurious whitespace? -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/524?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Gerrit-Change-Number: 524 Gerrit-PatchSet: 3 Gerrit-Owner: its_Giaan <gia...@ma...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-Reviewer: plaisthos <arn...@rf...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: plaisthos <arn...@rf...> Gerrit-Attention: its_Giaan <gia...@ma...> Gerrit-Comment-Date: Tue, 12 Mar 2024 17:11:24 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: Yes Gerrit-MessageType: comment |
From: its_Giaan (C. Review) <ge...@op...> - 2024-03-13 08:38:24
|
Attention is currently required from: flichtenheld, plaisthos. its_Giaan has posted comments on this change. ( http://gerrit.openvpn.net/c/openvpn/+/524?usp=email ) Change subject: Route: add support for user defined routing table ...................................................................... Patch Set 3: (7 comments) File doc/man-sections/vpn-network-options.rst: http://gerrit.openvpn.net/c/openvpn/+/524/comment/28a9b0d7_797a7b8f : PS3, Line 374: a user defined routing table can be used instead. > "an user" Since "user" begins with a consonant sound "y" (as in "you"), "a" is the appropriate article to use. You would say "a unicorn" instead of "an unicorn" imho. http://gerrit.openvpn.net/c/openvpn/+/524/comment/fc3149bd_56ee7cdc : PS3, Line 407: Since this option must be an entirely local choice, won't be pushable. > Time seems weird to me, would change to "it isn't pushable" Done http://gerrit.openvpn.net/c/openvpn/+/524/comment/293941ea_2c34e0eb : PS3, Line 408: default taken from ``--route-table`` if set, otherwise :code:`0`. > please change tab to space Done http://gerrit.openvpn.net/c/openvpn/+/524/comment/d10bebfd_142729b1 : PS3, Line 461: route-ipv6 ipv6addr/bits [gateway] > when listing all possible choices, you can leave off the "[" optional markers Done http://gerrit.openvpn.net/c/openvpn/+/524/comment/a4df0975_2ea65b9f : PS3, Line 464: > trailing whitespace Done http://gerrit.openvpn.net/c/openvpn/+/524/comment/1d25817b_bf7cb0e6 : PS3, Line 475: default taken from ``--route-table`` if set, otherwise :code:`0`. > same comments apply here as for --route (tab, won't->it isn't) Done File src/openvpn/route.h: http://gerrit.openvpn.net/c/openvpn/+/524/comment/4897ce61_2c46962d : PS3, Line 98: > spurious whitespace? Done -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/524?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Gerrit-Change-Number: 524 Gerrit-PatchSet: 3 Gerrit-Owner: its_Giaan <gia...@ma...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-Reviewer: plaisthos <arn...@rf...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: plaisthos <arn...@rf...> Gerrit-Attention: flichtenheld <fr...@li...> Gerrit-Comment-Date: Wed, 13 Mar 2024 08:38:05 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: No Comment-In-Reply-To: flichtenheld <fr...@li...> Gerrit-MessageType: comment |
From: its_Giaan (C. Review) <ge...@op...> - 2024-03-13 08:39:31
|
Attention is currently required from: flichtenheld, plaisthos. Hello flichtenheld, plaisthos, I'd like you to reexamine a change. Please visit http://gerrit.openvpn.net/c/openvpn/+/524?usp=email to look at the new patch set (#4). The following approvals got outdated and were removed: Code-Review-1 by flichtenheld Change subject: Route: add support for user defined routing table ...................................................................... Route: add support for user defined routing table 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. Fixes: Trac #1399 Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Signed-off-by: Gianmarco De Gregori <gia...@ma...> --- M doc/man-sections/vpn-network-options.rst M src/openvpn/helper.c M src/openvpn/init.c M src/openvpn/options.c M src/openvpn/options.h M src/openvpn/route.c M src/openvpn/route.h 7 files changed, 214 insertions(+), 20 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/24/524/4 diff --git a/doc/man-sections/vpn-network-options.rst b/doc/man-sections/vpn-network-options.rst index abe474f..3e3b365 100644 --- a/doc/man-sections/vpn-network-options.rst +++ b/doc/man-sections/vpn-network-options.rst @@ -367,6 +367,14 @@ 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 @@ 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,10 @@ ``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). + Since this option must be an entirely local choice, it isn't pushable. + 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`. @@ -441,14 +454,25 @@ Setup IPv6 routing in the system to send the specified IPv6 network into OpenVPN's *tun*. - Valid syntax: + Valid syntaxes: :: - route-ipv6 ipv6addr/bits [gateway] [metric] + route-ipv6 ipv6addr/bits + route-ipv6 ipv6addr/bits gateway + 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. + ``gateway`` + Only used for IPv6 routes across *tap* devices, + and if missing, the ``ipv6remote`` field from ``--ifconfig-ipv6`` or + ``--route-ipv6-gateway`` is used. + + ``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). + Since this option must be an entirely local choice, it isn't pushable. + default taken from ``--route-table`` if set, otherwise :code:`0`. --route-gateway arg Specify a default *gateway* for use with ``--route``. diff --git a/src/openvpn/helper.c b/src/openvpn/helper.c index fa011ff..758160d 100644 --- a/src/openvpn/helper.c +++ b/src/openvpn/helper.c @@ -118,6 +118,7 @@ print_in_addr_t(network, 0, &o->gc), print_in_addr_t(netmask, 0, &o->gc), NULL, + NULL, NULL); } diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 52b3931..5a24899 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -1476,6 +1476,7 @@ const char *gw = NULL; int dev = dev_type_enum(options->dev, options->dev_type); int metric = 0; + int 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 @@ -1494,6 +1495,10 @@ { 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; @@ -1503,6 +1508,7 @@ options->routes, gw, metric, + table_id, link_socket_current_remote(link_socket_info), es, ctx)) @@ -1521,6 +1527,7 @@ { const char *gw = NULL; int metric = -1; /* no metric set */ + int table_id = 0; /* unspec table */ /* see explanation in do_init_route_list() */ if (dco_enabled(options)) @@ -1539,6 +1546,11 @@ metric = options->route_default_metric; } + if (options->route_default_table_id) + { + table_id = options->route_default_table_id; + } + /* redirect (IPv6) gateway to VPN? if yes, add a few more specifics */ if (options->routes_ipv6->flags & RG_REROUTE_GW) @@ -1550,7 +1562,7 @@ { add_route_ipv6_to_option_list( options->routes_ipv6, string_alloc(opt_list[i], options->routes_ipv6->gc), - NULL, NULL ); + NULL, NULL, NULL ); } } @@ -1558,6 +1570,7 @@ options->routes_ipv6, gw, metric, + table_id, link_socket_current_remote_ipv6(link_socket_info), es, ctx)) diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 94a88f9..159bb4c 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -201,6 +201,10 @@ " pass --ifconfig parms by environment to scripts.\n" "--ifconfig-nowarn : Don't warn if the --ifconfig option on this side of the\n" " connection doesn't match the remote side.\n" +#ifdef TARGET_LINUX + "--route-table table_id : Specify a custom routing table for use with --route(-ipv6).\n" + " If not specified, the id of the default routing table will be used.\n" +#endif "--route network [netmask] [gateway] [metric] :\n" " Add route to routing table after connection\n" " is established. Multiple routes can be specified.\n" @@ -1907,6 +1911,7 @@ SHOW_STR(route_script); SHOW_STR(route_default_gateway); SHOW_INT(route_default_metric); + SHOW_INT(route_default_table_id); SHOW_BOOL(route_noexec); SHOW_INT(route_delay); SHOW_INT(route_delay_window); @@ -6978,7 +6983,16 @@ cnol_check_alloc(options); add_client_nat_to_option_list(options->client_nat, p[1], p[2], p[3], p[4], msglevel); } - else if (streq(p[0], "route") && p[1] && !p[5]) + else if (streq(p[0], "route-table") && p[1] && !p[2]) + { +#ifndef ENABLE_SITNL + msg(M_WARN, "NOTE: --route-table is supported only on Linux when SITNL is built-in"); +#endif + VERIFY_PERMISSION(OPT_P_ROUTE_TABLE); + options->route_default_table_id = positive_atoi(p[1]); + + } + else if (streq(p[0], "route") && p[1] && !p[6]) { VERIFY_PERMISSION(OPT_P_ROUTE); rol_check_alloc(options); @@ -6999,10 +7013,31 @@ msg(msglevel, "route parameter gateway '%s' must be a valid address", p[3]); goto err; } + /* p[4] is metric, if specified */ + + /* discard pulled routing table_id from server + * since this must be an entirely local choice */ + if (p[5]) + { + p[5] = NULL; + } } - add_route_to_option_list(options->routes, p[1], p[2], p[3], p[4]); + /* at the moment the routing table id is supported only by Linux/SITNL */ +#ifndef ENABLE_SITNL + if (p[5]) + { + static bool route_table_warned = false; + + if (!route_table_warned) + { + msg(M_WARN, "NOTE: table specified for --route, but not supported on this platform"); + route_table_warned = true; + } + } +#endif + add_route_to_option_list(options->routes, p[1], p[2], p[3], p[4], p[5]); } - else if (streq(p[0], "route-ipv6") && p[1] && !p[4]) + else if (streq(p[0], "route-ipv6") && p[1] && !p[5]) { VERIFY_PERMISSION(OPT_P_ROUTE); rol6_check_alloc(options); @@ -7018,9 +7053,31 @@ msg(msglevel, "route-ipv6 parameter gateway '%s' must be a valid address", p[2]); goto err; } - /* p[3] is metric, if present */ + /* p[3] is metric, if specified */ + + /* discard pulled routing table_id from server + * since this must be an entirely local choice */ + if (p[4]) + { + p[4] = NULL; + } } - add_route_ipv6_to_option_list(options->routes_ipv6, p[1], p[2], p[3]); + + /* at the moment the routing table id is supported only by Linux/SITNL */ +#ifndef ENABLE_SITNL + if (p[4]) + { + static bool route6_table_warned = false; + + if (!route6_table_warned) + { + msg(M_WARN, "NOTE: table specified for --route-ipv6, but not supported on this platform"); + route6_table_warned = true; + } + } +#endif + + add_route_ipv6_to_option_list(options->routes_ipv6, p[1], p[2], p[3], p[4]); } else if (streq(p[0], "max-routes") && !p[2]) { diff --git a/src/openvpn/options.h b/src/openvpn/options.h index 2b37d1f..6a57813 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -410,6 +410,7 @@ const char *route_predown_script; const char *route_default_gateway; const char *route_ipv6_default_gateway; + int route_default_table_id; int route_default_metric; bool route_noexec; int route_delay; @@ -740,6 +741,7 @@ #define OPT_P_PEER_ID (1<<28) #define OPT_P_INLINE (1<<29) #define OPT_P_PUSH_MTU (1<<30) +#define OPT_P_ROUTE_TABLE (1<<31) #define OPT_P_DEFAULT (~(OPT_P_INSTANCE|OPT_P_PULL_MODE)) diff --git a/src/openvpn/route.c b/src/openvpn/route.c index 6c027d9..e02c28a 100644 --- a/src/openvpn/route.c +++ b/src/openvpn/route.c @@ -325,7 +325,6 @@ CLEAR(*r); r->option = ro; - /* network */ if (!is_route_parm_defined(ro->network)) @@ -439,6 +438,27 @@ r->flags |= RT_DEFINED; + /* routing table id */ + + r->table_id = 0; + if (ro->table_id) + { + r->table_id = atoi(ro->table_id); + if (r->table_id < 0) + { + msg(M_WARN, PACKAGE_NAME "ROUTE: routing table id for network %s (%s) must be >= 0", + ro->network, + ro->table_id); + goto fail; + } + r->flags |= RT_TABLE_DEFINED; + } + else if (rl->spec.flags & RTSA_DEFAULT_TABLE_ID) + { + r->table_id = rl->spec.table_id; + r->flags |= RT_TABLE_DEFINED; + } + return true; fail: @@ -495,6 +515,27 @@ r6->flags |= RT_DEFINED; + /* routing table id */ + + r6->table_id = 0; + if (r6o->table_id) + { + r6->table_id = atoi(r6o->table_id); + if (r6->table_id < 0) + { + msg(M_WARN, PACKAGE_NAME "ROUTE: routing table id for network %s (%s) must be >= 0", + r6o->prefix, + r6o->table_id); + goto fail; + } + r6->flags |= RT_TABLE_DEFINED; + } + else if (rl6->spec_flags & RTSA_DEFAULT_TABLE_ID) + { + r6->table_id = rl6->default_route_table_id; + r6->flags |= RT_TABLE_DEFINED; + } + return true; fail: @@ -508,7 +549,8 @@ const char *network, const char *netmask, const char *gateway, - const char *metric) + const char *metric, + const char *table_id) { struct route_option *ro; ALLOC_OBJ_GC(ro, struct route_option, l->gc); @@ -516,6 +558,7 @@ ro->netmask = netmask; ro->gateway = gateway; ro->metric = metric; + ro->table_id = table_id; ro->next = l->routes; l->routes = ro; @@ -525,13 +568,15 @@ add_route_ipv6_to_option_list(struct route_ipv6_option_list *l, const char *prefix, const char *gateway, - const char *metric) + const char *metric, + const char *table_id) { struct route_ipv6_option *ro; ALLOC_OBJ_GC(ro, struct route_ipv6_option, l->gc); ro->prefix = prefix; ro->gateway = gateway; ro->metric = metric; + ro->table_id = table_id; ro->next = l->routes_ipv6; l->routes_ipv6 = ro; } @@ -630,6 +675,7 @@ const struct route_option_list *opt, const char *remote_endpoint, int default_metric, + int table_id, in_addr_t remote_host, struct env_set *es, openvpn_net_ctx_t *ctx) @@ -653,6 +699,12 @@ rl->spec.flags |= RTSA_DEFAULT_METRIC; } + if (table_id) + { + rl->spec.table_id = table_id; + rl->spec.flags |= RTSA_DEFAULT_TABLE_ID; + } + get_default_gateway(&rl->rgi, ctx); if (rl->rgi.flags & RGI_ADDR_DEFINED) { @@ -786,6 +838,7 @@ const struct route_ipv6_option_list *opt6, const char *remote_endpoint, int default_metric, + int table_id, const struct in6_addr *remote_host_ipv6, struct env_set *es, openvpn_net_ctx_t *ctx) @@ -810,6 +863,12 @@ rl6->spec_flags |= RTSA_DEFAULT_METRIC; } + if (table_id) + { + rl6->default_route_table_id = table_id; + rl6->spec_flags |= RTSA_DEFAULT_TABLE_ID; + } + msg(D_ROUTE, "GDG6: remote_host_ipv6=%s", remote_host_ipv6 ? print_in6_addr(*remote_host_ipv6, 0, &gc) : "n/a" ); @@ -1602,9 +1661,15 @@ metric = r->metric; } + int table_id = 0; + if (r->flags & RT_TABLE_DEFINED) + { + table_id = r->table_id; + } + status = RTA_SUCCESS; int ret = net_route_v4_add(ctx, &r->network, netmask_to_netbits2(r->netmask), - &r->gateway, iface, 0, metric); + &r->gateway, iface, table_id, metric); if (ret == -EEXIST) { msg(D_ROUTE, "NOTE: Linux route add command failed because route exists"); @@ -1982,10 +2047,16 @@ metric = r6->metric; } + int table_id = 0; + if ((r6->flags & RT_TABLE_DEFINED) && (r6->table_id > 0)) + { + table_id = r6->table_id; + } + status = RTA_SUCCESS; int ret = net_route_v6_add(ctx, &r6->network, r6->netbits, gateway_needed ? &r6->gateway : NULL, - device, 0, metric); + device, table_id, metric); if (ret == -EEXIST) { msg(D_ROUTE, "NOTE: Linux route add command failed because route exists"); @@ -2190,8 +2261,14 @@ metric = r->metric; } + int table_id = 0; + if (r->flags & RT_TABLE_DEFINED) + { + table_id = r->table_id; + } + if (net_route_v4_del(ctx, &r->network, netmask_to_netbits2(r->netmask), - &r->gateway, NULL, 0, metric) < 0) + &r->gateway, NULL, table_id, metric) < 0) { msg(M_WARN, "ERROR: Linux route delete command failed"); } @@ -2403,8 +2480,16 @@ metric = r6->metric; } + int table_id = 0; + if (r6->flags & RT_TABLE_DEFINED) + { + table_id = r6->table_id; + } + + + if (net_route_v6_del(ctx, &r6->network, r6->netbits, - gateway_needed ? &r6->gateway : NULL, device, 0, + gateway_needed ? &r6->gateway : NULL, device, table_id, metric) < 0) { msg(M_WARN, "ERROR: Linux route v6 delete command failed"); diff --git a/src/openvpn/route.h b/src/openvpn/route.h index 71b4cf4..50883c0 100644 --- a/src/openvpn/route.h +++ b/src/openvpn/route.h @@ -63,12 +63,14 @@ #define RTSA_REMOTE_ENDPOINT (1<<0) #define RTSA_REMOTE_HOST (1<<1) #define RTSA_DEFAULT_METRIC (1<<2) +#define RTSA_DEFAULT_TABLE_ID (1<<3) unsigned int flags; in_addr_t remote_endpoint; in_addr_t remote_host; int remote_host_local; /* TLA_x value */ struct route_bypass bypass; + int table_id; int default_metric; }; @@ -77,6 +79,7 @@ const char *network; const char *netmask; const char *gateway; + const char *table_id; const char *metric; }; @@ -101,6 +104,7 @@ const char *prefix; /* e.g. "2001:db8:1::/64" */ const char *gateway; /* e.g. "2001:db8:0::2" */ const char *metric; /* e.g. "5" */ + const char *table_id; }; struct route_ipv6_option_list { @@ -113,12 +117,14 @@ #define RT_DEFINED (1<<0) #define RT_ADDED (1<<1) #define RT_METRIC_DEFINED (1<<2) +#define RT_TABLE_DEFINED (1<<3) struct route_ipv4 *next; unsigned int flags; const struct route_option *option; in_addr_t network; in_addr_t netmask; in_addr_t gateway; + int table_id; int metric; }; @@ -129,6 +135,7 @@ unsigned int netbits; struct in6_addr gateway; int metric; + int table_id; /* gateway interface */ #ifdef _WIN32 DWORD adapter_index; /* interface or ~0 if undefined */ @@ -223,6 +230,7 @@ struct in6_addr remote_endpoint_ipv6; /* inside tun */ struct in6_addr remote_host_ipv6; /* --remote address */ int default_metric; + int default_route_table_id; struct route_ipv6_gateway_info rgi6; unsigned int flags; /* RG_x flags, see route_option_list */ @@ -271,17 +279,20 @@ const char *network, const char *netmask, const char *gateway, - const char *metric); + const char *metric, + const char *table_id); void add_route_ipv6_to_option_list(struct route_ipv6_option_list *l, const char *prefix, const char *gateway, - const char *metric); + const char *metric, + const char *table_id); bool init_route_list(struct route_list *rl, const struct route_option_list *opt, const char *remote_endpoint, int default_metric, + int table_id, in_addr_t remote_host, struct env_set *es, openvpn_net_ctx_t *ctx); @@ -290,6 +301,7 @@ const struct route_ipv6_option_list *opt6, const char *remote_endpoint, int default_metric, + int table_id, const struct in6_addr *remote_host, struct env_set *es, openvpn_net_ctx_t *ctx); -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/524?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Gerrit-Change-Number: 524 Gerrit-PatchSet: 4 Gerrit-Owner: its_Giaan <gia...@ma...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-Reviewer: plaisthos <arn...@rf...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: plaisthos <arn...@rf...> Gerrit-Attention: flichtenheld <fr...@li...> Gerrit-MessageType: newpatchset |
From: flichtenheld (C. Review) <ge...@op...> - 2024-03-13 10:26:02
|
Attention is currently required from: its_Giaan, plaisthos. flichtenheld has posted comments on this change. ( http://gerrit.openvpn.net/c/openvpn/+/524?usp=email ) Change subject: Route: add support for user defined routing table ...................................................................... Patch Set 4: (1 comment) File doc/man-sections/vpn-network-options.rst: http://gerrit.openvpn.net/c/openvpn/+/524/comment/07a1a344_6d18a9c3 : PS3, Line 374: a user defined routing table can be used instead. > Since "user" begins with a consonant sound "y" (as in "you"), "a" is the appropriate article to use. […] Acknowledged -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/524?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Gerrit-Change-Number: 524 Gerrit-PatchSet: 4 Gerrit-Owner: its_Giaan <gia...@ma...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-Reviewer: plaisthos <arn...@rf...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: plaisthos <arn...@rf...> Gerrit-Attention: its_Giaan <gia...@ma...> Gerrit-Comment-Date: Wed, 13 Mar 2024 10:25:43 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: No Comment-In-Reply-To: its_Giaan <gia...@ma...> Comment-In-Reply-To: flichtenheld <fr...@li...> Gerrit-MessageType: comment |
From: flichtenheld (C. Review) <ge...@op...> - 2024-03-13 13:09:02
|
Attention is currently required from: its_Giaan, plaisthos. flichtenheld has posted comments on this change. ( http://gerrit.openvpn.net/c/openvpn/+/524?usp=email ) Change subject: Route: add support for user defined routing table ...................................................................... Patch Set 4: Code-Review+2 (1 comment) Patchset: PS4: Tested --route-table 42 and --route-table 0 for full t_client suite) (don't forget ip rule) Tested t_client 2a with --route-ipv6 fd00:abcd:194::/48 default default 42 -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/524?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Gerrit-Change-Number: 524 Gerrit-PatchSet: 4 Gerrit-Owner: its_Giaan <gia...@ma...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-Reviewer: plaisthos <arn...@rf...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: plaisthos <arn...@rf...> Gerrit-Attention: its_Giaan <gia...@ma...> Gerrit-Comment-Date: Wed, 13 Mar 2024 13:08:44 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: Yes Gerrit-MessageType: comment |
From: <gia...@ma...> - 2024-03-13 15:04:11
|
From: Gianmarco De Gregori <gia...@ma...> 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. Fixes: Trac #1399 Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Signed-off-by: Gianmarco De Gregori <gia...@ma...> Acked-by: Frank Lichtenheld <fr...@li...> --- This change was reviewed on Gerrit and approved by at least one developer. I request to merge it to master. Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/524 This mail reflects revision 4 of this Change. Acked-by according to Gerrit (reflected above): Frank Lichtenheld <fr...@li...> diff --git a/doc/man-sections/vpn-network-options.rst b/doc/man-sections/vpn-network-options.rst index abe474f..3e3b365 100644 --- a/doc/man-sections/vpn-network-options.rst +++ b/doc/man-sections/vpn-network-options.rst @@ -367,6 +367,14 @@ 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 @@ 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,10 @@ ``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). + Since this option must be an entirely local choice, it isn't pushable. + 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`. @@ -441,14 +454,25 @@ Setup IPv6 routing in the system to send the specified IPv6 network into OpenVPN's *tun*. - Valid syntax: + Valid syntaxes: :: - route-ipv6 ipv6addr/bits [gateway] [metric] + route-ipv6 ipv6addr/bits + route-ipv6 ipv6addr/bits gateway + 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. + ``gateway`` + Only used for IPv6 routes across *tap* devices, + and if missing, the ``ipv6remote`` field from ``--ifconfig-ipv6`` or + ``--route-ipv6-gateway`` is used. + + ``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). + Since this option must be an entirely local choice, it isn't pushable. + default taken from ``--route-table`` if set, otherwise :code:`0`. --route-gateway arg Specify a default *gateway* for use with ``--route``. diff --git a/src/openvpn/helper.c b/src/openvpn/helper.c index fa011ff..758160d 100644 --- a/src/openvpn/helper.c +++ b/src/openvpn/helper.c @@ -118,6 +118,7 @@ print_in_addr_t(network, 0, &o->gc), print_in_addr_t(netmask, 0, &o->gc), NULL, + NULL, NULL); } diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 52b3931..5a24899 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -1476,6 +1476,7 @@ const char *gw = NULL; int dev = dev_type_enum(options->dev, options->dev_type); int metric = 0; + int 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 @@ -1494,6 +1495,10 @@ { 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; @@ -1503,6 +1508,7 @@ options->routes, gw, metric, + table_id, link_socket_current_remote(link_socket_info), es, ctx)) @@ -1521,6 +1527,7 @@ { const char *gw = NULL; int metric = -1; /* no metric set */ + int table_id = 0; /* unspec table */ /* see explanation in do_init_route_list() */ if (dco_enabled(options)) @@ -1539,6 +1546,11 @@ metric = options->route_default_metric; } + if (options->route_default_table_id) + { + table_id = options->route_default_table_id; + } + /* redirect (IPv6) gateway to VPN? if yes, add a few more specifics */ if (options->routes_ipv6->flags & RG_REROUTE_GW) @@ -1550,7 +1562,7 @@ { add_route_ipv6_to_option_list( options->routes_ipv6, string_alloc(opt_list[i], options->routes_ipv6->gc), - NULL, NULL ); + NULL, NULL, NULL ); } } @@ -1558,6 +1570,7 @@ options->routes_ipv6, gw, metric, + table_id, link_socket_current_remote_ipv6(link_socket_info), es, ctx)) diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 94a88f9..159bb4c 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -201,6 +201,10 @@ " pass --ifconfig parms by environment to scripts.\n" "--ifconfig-nowarn : Don't warn if the --ifconfig option on this side of the\n" " connection doesn't match the remote side.\n" +#ifdef TARGET_LINUX + "--route-table table_id : Specify a custom routing table for use with --route(-ipv6).\n" + " If not specified, the id of the default routing table will be used.\n" +#endif "--route network [netmask] [gateway] [metric] :\n" " Add route to routing table after connection\n" " is established. Multiple routes can be specified.\n" @@ -1907,6 +1911,7 @@ SHOW_STR(route_script); SHOW_STR(route_default_gateway); SHOW_INT(route_default_metric); + SHOW_INT(route_default_table_id); SHOW_BOOL(route_noexec); SHOW_INT(route_delay); SHOW_INT(route_delay_window); @@ -6978,7 +6983,16 @@ cnol_check_alloc(options); add_client_nat_to_option_list(options->client_nat, p[1], p[2], p[3], p[4], msglevel); } - else if (streq(p[0], "route") && p[1] && !p[5]) + else if (streq(p[0], "route-table") && p[1] && !p[2]) + { +#ifndef ENABLE_SITNL + msg(M_WARN, "NOTE: --route-table is supported only on Linux when SITNL is built-in"); +#endif + VERIFY_PERMISSION(OPT_P_ROUTE_TABLE); + options->route_default_table_id = positive_atoi(p[1]); + + } + else if (streq(p[0], "route") && p[1] && !p[6]) { VERIFY_PERMISSION(OPT_P_ROUTE); rol_check_alloc(options); @@ -6999,10 +7013,31 @@ msg(msglevel, "route parameter gateway '%s' must be a valid address", p[3]); goto err; } + /* p[4] is metric, if specified */ + + /* discard pulled routing table_id from server + * since this must be an entirely local choice */ + if (p[5]) + { + p[5] = NULL; + } } - add_route_to_option_list(options->routes, p[1], p[2], p[3], p[4]); + /* at the moment the routing table id is supported only by Linux/SITNL */ +#ifndef ENABLE_SITNL + if (p[5]) + { + static bool route_table_warned = false; + + if (!route_table_warned) + { + msg(M_WARN, "NOTE: table specified for --route, but not supported on this platform"); + route_table_warned = true; + } + } +#endif + add_route_to_option_list(options->routes, p[1], p[2], p[3], p[4], p[5]); } - else if (streq(p[0], "route-ipv6") && p[1] && !p[4]) + else if (streq(p[0], "route-ipv6") && p[1] && !p[5]) { VERIFY_PERMISSION(OPT_P_ROUTE); rol6_check_alloc(options); @@ -7018,9 +7053,31 @@ msg(msglevel, "route-ipv6 parameter gateway '%s' must be a valid address", p[2]); goto err; } - /* p[3] is metric, if present */ + /* p[3] is metric, if specified */ + + /* discard pulled routing table_id from server + * since this must be an entirely local choice */ + if (p[4]) + { + p[4] = NULL; + } } - add_route_ipv6_to_option_list(options->routes_ipv6, p[1], p[2], p[3]); + + /* at the moment the routing table id is supported only by Linux/SITNL */ +#ifndef ENABLE_SITNL + if (p[4]) + { + static bool route6_table_warned = false; + + if (!route6_table_warned) + { + msg(M_WARN, "NOTE: table specified for --route-ipv6, but not supported on this platform"); + route6_table_warned = true; + } + } +#endif + + add_route_ipv6_to_option_list(options->routes_ipv6, p[1], p[2], p[3], p[4]); } else if (streq(p[0], "max-routes") && !p[2]) { diff --git a/src/openvpn/options.h b/src/openvpn/options.h index 2b37d1f..6a57813 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -410,6 +410,7 @@ const char *route_predown_script; const char *route_default_gateway; const char *route_ipv6_default_gateway; + int route_default_table_id; int route_default_metric; bool route_noexec; int route_delay; @@ -740,6 +741,7 @@ #define OPT_P_PEER_ID (1<<28) #define OPT_P_INLINE (1<<29) #define OPT_P_PUSH_MTU (1<<30) +#define OPT_P_ROUTE_TABLE (1<<31) #define OPT_P_DEFAULT (~(OPT_P_INSTANCE|OPT_P_PULL_MODE)) diff --git a/src/openvpn/route.c b/src/openvpn/route.c index 6c027d9..e02c28a 100644 --- a/src/openvpn/route.c +++ b/src/openvpn/route.c @@ -325,7 +325,6 @@ CLEAR(*r); r->option = ro; - /* network */ if (!is_route_parm_defined(ro->network)) @@ -439,6 +438,27 @@ r->flags |= RT_DEFINED; + /* routing table id */ + + r->table_id = 0; + if (ro->table_id) + { + r->table_id = atoi(ro->table_id); + if (r->table_id < 0) + { + msg(M_WARN, PACKAGE_NAME "ROUTE: routing table id for network %s (%s) must be >= 0", + ro->network, + ro->table_id); + goto fail; + } + r->flags |= RT_TABLE_DEFINED; + } + else if (rl->spec.flags & RTSA_DEFAULT_TABLE_ID) + { + r->table_id = rl->spec.table_id; + r->flags |= RT_TABLE_DEFINED; + } + return true; fail: @@ -495,6 +515,27 @@ r6->flags |= RT_DEFINED; + /* routing table id */ + + r6->table_id = 0; + if (r6o->table_id) + { + r6->table_id = atoi(r6o->table_id); + if (r6->table_id < 0) + { + msg(M_WARN, PACKAGE_NAME "ROUTE: routing table id for network %s (%s) must be >= 0", + r6o->prefix, + r6o->table_id); + goto fail; + } + r6->flags |= RT_TABLE_DEFINED; + } + else if (rl6->spec_flags & RTSA_DEFAULT_TABLE_ID) + { + r6->table_id = rl6->default_route_table_id; + r6->flags |= RT_TABLE_DEFINED; + } + return true; fail: @@ -508,7 +549,8 @@ const char *network, const char *netmask, const char *gateway, - const char *metric) + const char *metric, + const char *table_id) { struct route_option *ro; ALLOC_OBJ_GC(ro, struct route_option, l->gc); @@ -516,6 +558,7 @@ ro->netmask = netmask; ro->gateway = gateway; ro->metric = metric; + ro->table_id = table_id; ro->next = l->routes; l->routes = ro; @@ -525,13 +568,15 @@ add_route_ipv6_to_option_list(struct route_ipv6_option_list *l, const char *prefix, const char *gateway, - const char *metric) + const char *metric, + const char *table_id) { struct route_ipv6_option *ro; ALLOC_OBJ_GC(ro, struct route_ipv6_option, l->gc); ro->prefix = prefix; ro->gateway = gateway; ro->metric = metric; + ro->table_id = table_id; ro->next = l->routes_ipv6; l->routes_ipv6 = ro; } @@ -630,6 +675,7 @@ const struct route_option_list *opt, const char *remote_endpoint, int default_metric, + int table_id, in_addr_t remote_host, struct env_set *es, openvpn_net_ctx_t *ctx) @@ -653,6 +699,12 @@ rl->spec.flags |= RTSA_DEFAULT_METRIC; } + if (table_id) + { + rl->spec.table_id = table_id; + rl->spec.flags |= RTSA_DEFAULT_TABLE_ID; + } + get_default_gateway(&rl->rgi, ctx); if (rl->rgi.flags & RGI_ADDR_DEFINED) { @@ -786,6 +838,7 @@ const struct route_ipv6_option_list *opt6, const char *remote_endpoint, int default_metric, + int table_id, const struct in6_addr *remote_host_ipv6, struct env_set *es, openvpn_net_ctx_t *ctx) @@ -810,6 +863,12 @@ rl6->spec_flags |= RTSA_DEFAULT_METRIC; } + if (table_id) + { + rl6->default_route_table_id = table_id; + rl6->spec_flags |= RTSA_DEFAULT_TABLE_ID; + } + msg(D_ROUTE, "GDG6: remote_host_ipv6=%s", remote_host_ipv6 ? print_in6_addr(*remote_host_ipv6, 0, &gc) : "n/a" ); @@ -1602,9 +1661,15 @@ metric = r->metric; } + int table_id = 0; + if (r->flags & RT_TABLE_DEFINED) + { + table_id = r->table_id; + } + status = RTA_SUCCESS; int ret = net_route_v4_add(ctx, &r->network, netmask_to_netbits2(r->netmask), - &r->gateway, iface, 0, metric); + &r->gateway, iface, table_id, metric); if (ret == -EEXIST) { msg(D_ROUTE, "NOTE: Linux route add command failed because route exists"); @@ -1982,10 +2047,16 @@ metric = r6->metric; } + int table_id = 0; + if ((r6->flags & RT_TABLE_DEFINED) && (r6->table_id > 0)) + { + table_id = r6->table_id; + } + status = RTA_SUCCESS; int ret = net_route_v6_add(ctx, &r6->network, r6->netbits, gateway_needed ? &r6->gateway : NULL, - device, 0, metric); + device, table_id, metric); if (ret == -EEXIST) { msg(D_ROUTE, "NOTE: Linux route add command failed because route exists"); @@ -2190,8 +2261,14 @@ metric = r->metric; } + int table_id = 0; + if (r->flags & RT_TABLE_DEFINED) + { + table_id = r->table_id; + } + if (net_route_v4_del(ctx, &r->network, netmask_to_netbits2(r->netmask), - &r->gateway, NULL, 0, metric) < 0) + &r->gateway, NULL, table_id, metric) < 0) { msg(M_WARN, "ERROR: Linux route delete command failed"); } @@ -2403,8 +2480,16 @@ metric = r6->metric; } + int table_id = 0; + if (r6->flags & RT_TABLE_DEFINED) + { + table_id = r6->table_id; + } + + + if (net_route_v6_del(ctx, &r6->network, r6->netbits, - gateway_needed ? &r6->gateway : NULL, device, 0, + gateway_needed ? &r6->gateway : NULL, device, table_id, metric) < 0) { msg(M_WARN, "ERROR: Linux route v6 delete command failed"); diff --git a/src/openvpn/route.h b/src/openvpn/route.h index 71b4cf4..50883c0 100644 --- a/src/openvpn/route.h +++ b/src/openvpn/route.h @@ -63,12 +63,14 @@ #define RTSA_REMOTE_ENDPOINT (1<<0) #define RTSA_REMOTE_HOST (1<<1) #define RTSA_DEFAULT_METRIC (1<<2) +#define RTSA_DEFAULT_TABLE_ID (1<<3) unsigned int flags; in_addr_t remote_endpoint; in_addr_t remote_host; int remote_host_local; /* TLA_x value */ struct route_bypass bypass; + int table_id; int default_metric; }; @@ -77,6 +79,7 @@ const char *network; const char *netmask; const char *gateway; + const char *table_id; const char *metric; }; @@ -101,6 +104,7 @@ const char *prefix; /* e.g. "2001:db8:1::/64" */ const char *gateway; /* e.g. "2001:db8:0::2" */ const char *metric; /* e.g. "5" */ + const char *table_id; }; struct route_ipv6_option_list { @@ -113,12 +117,14 @@ #define RT_DEFINED (1<<0) #define RT_ADDED (1<<1) #define RT_METRIC_DEFINED (1<<2) +#define RT_TABLE_DEFINED (1<<3) struct route_ipv4 *next; unsigned int flags; const struct route_option *option; in_addr_t network; in_addr_t netmask; in_addr_t gateway; + int table_id; int metric; }; @@ -129,6 +135,7 @@ unsigned int netbits; struct in6_addr gateway; int metric; + int table_id; /* gateway interface */ #ifdef _WIN32 DWORD adapter_index; /* interface or ~0 if undefined */ @@ -223,6 +230,7 @@ struct in6_addr remote_endpoint_ipv6; /* inside tun */ struct in6_addr remote_host_ipv6; /* --remote address */ int default_metric; + int default_route_table_id; struct route_ipv6_gateway_info rgi6; unsigned int flags; /* RG_x flags, see route_option_list */ @@ -271,17 +279,20 @@ const char *network, const char *netmask, const char *gateway, - const char *metric); + const char *metric, + const char *table_id); void add_route_ipv6_to_option_list(struct route_ipv6_option_list *l, const char *prefix, const char *gateway, - const char *metric); + const char *metric, + const char *table_id); bool init_route_list(struct route_list *rl, const struct route_option_list *opt, const char *remote_endpoint, int default_metric, + int table_id, in_addr_t remote_host, struct env_set *es, openvpn_net_ctx_t *ctx); @@ -290,6 +301,7 @@ const struct route_ipv6_option_list *opt6, const char *remote_endpoint, int default_metric, + int table_id, const struct in6_addr *remote_host, struct env_set *es, openvpn_net_ctx_t *ctx); |
From: cron2 (C. Review) <ge...@op...> - 2024-06-19 09:13:34
|
Attention is currently required from: its_Giaan, plaisthos. cron2 has posted comments on this change. ( http://gerrit.openvpn.net/c/openvpn/+/524?usp=email ) Change subject: Route: add support for user defined routing table ...................................................................... Patch Set 4: Code-Review-1 (1 comment) Patchset: PS4: Sorry for being late to the party - I have looked at it, and while the general code works, I find it a bit excessive in lines of code. Namely, I would opt for "do not support route-table as an extra argument to `route`", as this + the checks really makes up half the code - for little value. Since it's not supposed to be pushable, routes-with-table need to be in the client config, and in that case, I could just put ``` route-table 123 route route route-table 456 route route route-table 999 # for everything that comes in pushed ``` into my config. If I ever really need more than 1-2 route tables. Also, we shouldn't have `#ifdef ENABLE_SITNL` in the parser for `route` and `route-ipv6`... Further, the hunk ``` + int table_id = 0; /* unspec table */ ... + if (options->route_default_table_id) + { + table_id = options->route_default_table_id; + } ``` is sort of semi-useful - if route_default_table_id is 0, we do not assign it to table_id, which is also 0. Why bother with an extra variable here that will have the same value as the `options` variable, at all times? I'd just pass `options->route_default_table_id` downwards, and be done with it. The `do_init_route_ipv6_list()` code also does the `table_id = ...` dance, but then passes NULL towards `add_route_ipv6_to_option_list()`, which does not look intentional... -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/524?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Gerrit-Change-Number: 524 Gerrit-PatchSet: 4 Gerrit-Owner: its_Giaan <gia...@ma...> Gerrit-Reviewer: cron2 <ge...@gr...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-Reviewer: plaisthos <arn...@rf...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: plaisthos <arn...@rf...> Gerrit-Attention: its_Giaan <gia...@ma...> Gerrit-Comment-Date: Wed, 19 Jun 2024 09:13:14 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: Yes Gerrit-MessageType: comment |
From: its_Giaan (C. Review) <ge...@op...> - 2024-07-02 13:50:33
|
Attention is currently required from: cron2, flichtenheld, its_Giaan, plaisthos. Hello cron2, flichtenheld, plaisthos, I'd like you to reexamine a change. Please visit http://gerrit.openvpn.net/c/openvpn/+/524?usp=email to look at the new patch set (#5). The following approvals got outdated and were removed: Code-Review+2 by flichtenheld, Code-Review-1 by cron2 The change is no longer submittable: Code-Review and checks~ChecksSubmitRule are unsatisfied now. Change subject: Route: add support for user defined routing table ...................................................................... Route: add support for user defined routing table 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). Please note: this feature is currently supported only by Linux/SITNL. Support for other platforms should be added in related backends. Fixes: Trac #1399 Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Signed-off-by: Gianmarco De Gregori <gia...@ma...> --- M doc/man-sections/vpn-network-options.rst M src/openvpn/helper.c M src/openvpn/init.c M src/openvpn/options.c M src/openvpn/options.h M src/openvpn/route.c M src/openvpn/route.h 7 files changed, 153 insertions(+), 19 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/24/524/5 diff --git a/doc/man-sections/vpn-network-options.rst b/doc/man-sections/vpn-network-options.rst index 84d4273..9d4235b 100644 --- a/doc/man-sections/vpn-network-options.rst +++ b/doc/man-sections/vpn-network-options.rst @@ -371,6 +371,14 @@ 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 @@ -445,14 +453,20 @@ Setup IPv6 routing in the system to send the specified IPv6 network into OpenVPN's *tun*. - Valid syntax: + Valid syntaxes: :: - route-ipv6 ipv6addr/bits [gateway] [metric] + route-ipv6 ipv6addr/bits + route-ipv6 ipv6addr/bits gateway + route-ipv6 ipv6addr/bits gateway metric - 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. + ``gateway`` + Only used for IPv6 routes across *tap* devices, + and if missing, the ``ipv6remote`` field from ``--ifconfig-ipv6`` or + ``--route-ipv6-gateway`` is used. + + ``metric`` + default taken from ``--route-metric`` if set, otherwise :code:`0`. --route-gateway arg Specify a default *gateway* for use with ``--route``. diff --git a/src/openvpn/helper.c b/src/openvpn/helper.c index bbdbc04..2306760 100644 --- a/src/openvpn/helper.c +++ b/src/openvpn/helper.c @@ -118,7 +118,8 @@ print_in_addr_t(network, 0, &o->gc), print_in_addr_t(netmask, 0, &o->gc), NULL, - NULL); + NULL, + o->route_default_table_id); } static void diff --git a/src/openvpn/init.c b/src/openvpn/init.c index a49e563..8a1038b 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -1499,6 +1499,7 @@ options->routes, gw, metric, + options->route_default_table_id, link_socket_current_remote(link_socket_info), es, ctx)) @@ -1546,7 +1547,7 @@ { add_route_ipv6_to_option_list( options->routes_ipv6, string_alloc(opt_list[i], options->routes_ipv6->gc), - NULL, NULL ); + NULL, NULL, options->route_default_table_id); } } @@ -1554,6 +1555,7 @@ options->routes_ipv6, gw, metric, + options->route_default_table_id, link_socket_current_remote_ipv6(link_socket_info), es, ctx)) diff --git a/src/openvpn/options.c b/src/openvpn/options.c index dbe1425..0214735 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -201,6 +201,10 @@ " pass --ifconfig parms by environment to scripts.\n" "--ifconfig-nowarn : Don't warn if the --ifconfig option on this side of the\n" " connection doesn't match the remote side.\n" +#ifdef TARGET_LINUX + "--route-table table_id : Specify a custom routing table for use with --route(-ipv6).\n" + " If not specified, the id of the default routing table will be used.\n" +#endif "--route network [netmask] [gateway] [metric] :\n" " Add route to routing table after connection\n" " is established. Multiple routes can be specified.\n" @@ -817,6 +821,7 @@ o->ce.mssfix = 0; o->ce.mssfix_default = true; o->ce.mssfix_encap = true; + o->route_default_table_id = 0; o->route_delay_window = 30; o->resolve_retry_seconds = RESOLV_RETRY_INFINITE; o->resolve_in_advance = false; @@ -1908,6 +1913,7 @@ SHOW_STR(route_script); SHOW_STR(route_default_gateway); SHOW_INT(route_default_metric); + SHOW_INT(route_default_table_id); SHOW_BOOL(route_noexec); SHOW_INT(route_delay); SHOW_INT(route_delay_window); @@ -6987,6 +6993,15 @@ cnol_check_alloc(options); add_client_nat_to_option_list(options->client_nat, p[1], p[2], p[3], p[4], msglevel); } + else if (streq(p[0], "route-table") && p[1] && !p[2]) + { +#ifndef ENABLE_SITNL + msg(M_WARN, "NOTE: --route-table is supported only on Linux when SITNL is built-in"); +#endif + VERIFY_PERMISSION(OPT_P_ROUTE_TABLE); + options->route_default_table_id = positive_atoi(p[1]); + + } else if (streq(p[0], "route") && p[1] && !p[5]) { VERIFY_PERMISSION(OPT_P_ROUTE); @@ -7008,8 +7023,10 @@ msg(msglevel, "route parameter gateway '%s' must be a valid address", p[3]); goto err; } + /* p[4] is metric, if specified */ } - add_route_to_option_list(options->routes, p[1], p[2], p[3], p[4]); + + add_route_to_option_list(options->routes, p[1], p[2], p[3], p[4], options->route_default_table_id); } else if (streq(p[0], "route-ipv6") && p[1] && !p[4]) { @@ -7027,9 +7044,10 @@ msg(msglevel, "route-ipv6 parameter gateway '%s' must be a valid address", p[2]); goto err; } - /* p[3] is metric, if present */ + /* p[3] is metric, if specified */ } - add_route_ipv6_to_option_list(options->routes_ipv6, p[1], p[2], p[3]); + + add_route_ipv6_to_option_list(options->routes_ipv6, p[1], p[2], p[3], options->route_default_table_id); } else if (streq(p[0], "max-routes") && !p[2]) { diff --git a/src/openvpn/options.h b/src/openvpn/options.h index f608cb8..d3a8141 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -410,6 +410,7 @@ const char *route_predown_script; const char *route_default_gateway; const char *route_ipv6_default_gateway; + int route_default_table_id; int route_default_metric; bool route_noexec; int route_delay; @@ -740,6 +741,7 @@ #define OPT_P_PEER_ID (1<<28) #define OPT_P_INLINE (1<<29) #define OPT_P_PUSH_MTU (1<<30) +#define OPT_P_ROUTE_TABLE (1<<31) #define OPT_P_DEFAULT (~(OPT_P_INSTANCE|OPT_P_PULL_MODE)) diff --git a/src/openvpn/route.c b/src/openvpn/route.c index 91f2032..4b61ea1 100644 --- a/src/openvpn/route.c +++ b/src/openvpn/route.c @@ -328,7 +328,6 @@ CLEAR(*r); r->option = ro; - /* network */ if (!is_route_parm_defined(ro->network)) @@ -442,6 +441,27 @@ r->flags |= RT_DEFINED; + /* routing table id */ + + r->table_id = 0; + if (ro->table_id) + { + r->table_id = ro->table_id; + if (r->table_id < 0) + { + msg(M_WARN, PACKAGE_NAME "ROUTE: routing table id for network %s (%d) must be >= 0", + ro->network, + ro->table_id); + goto fail; + } + r->flags |= RT_TABLE_DEFINED; + } + else if (rl->spec.flags & RTSA_DEFAULT_TABLE_ID) + { + r->table_id = rl->spec.table_id; + r->flags |= RT_TABLE_DEFINED; + } + return true; fail: @@ -498,6 +518,27 @@ r6->flags |= RT_DEFINED; + /* routing table id */ + + r6->table_id = 0; + if (r6o->table_id) + { + r6->table_id = r6o->table_id; + if (r6->table_id < 0) + { + msg(M_WARN, PACKAGE_NAME "ROUTE: routing table id for network %s (%d) must be >= 0", + r6o->prefix, + r6o->table_id); + goto fail; + } + r6->flags |= RT_TABLE_DEFINED; + } + else if (rl6->spec_flags & RTSA_DEFAULT_TABLE_ID) + { + r6->table_id = rl6->default_route_table_id; + r6->flags |= RT_TABLE_DEFINED; + } + return true; fail: @@ -511,7 +552,8 @@ const char *network, const char *netmask, const char *gateway, - const char *metric) + const char *metric, + int table_id) { struct route_option *ro; ALLOC_OBJ_GC(ro, struct route_option, l->gc); @@ -519,6 +561,7 @@ ro->netmask = netmask; ro->gateway = gateway; ro->metric = metric; + ro->table_id = table_id; ro->next = l->routes; l->routes = ro; @@ -528,13 +571,15 @@ add_route_ipv6_to_option_list(struct route_ipv6_option_list *l, const char *prefix, const char *gateway, - const char *metric) + const char *metric, + int table_id) { struct route_ipv6_option *ro; ALLOC_OBJ_GC(ro, struct route_ipv6_option, l->gc); ro->prefix = prefix; ro->gateway = gateway; ro->metric = metric; + ro->table_id = table_id; ro->next = l->routes_ipv6; l->routes_ipv6 = ro; } @@ -632,6 +677,7 @@ const struct route_option_list *opt, const char *remote_endpoint, int default_metric, + int table_id, in_addr_t remote_host, struct env_set *es, openvpn_net_ctx_t *ctx) @@ -655,6 +701,12 @@ rl->spec.flags |= RTSA_DEFAULT_METRIC; } + if (table_id) + { + rl->spec.table_id = table_id; + rl->spec.flags |= RTSA_DEFAULT_TABLE_ID; + } + get_default_gateway(&rl->rgi, ctx); if (rl->rgi.flags & RGI_ADDR_DEFINED) { @@ -791,6 +843,7 @@ const struct route_ipv6_option_list *opt6, const char *remote_endpoint, int default_metric, + int table_id, const struct in6_addr *remote_host_ipv6, struct env_set *es, openvpn_net_ctx_t *ctx) @@ -815,6 +868,12 @@ rl6->spec_flags |= RTSA_DEFAULT_METRIC; } + if (table_id) + { + rl6->default_route_table_id = table_id; + rl6->spec_flags |= RTSA_DEFAULT_TABLE_ID; + } + msg(D_ROUTE, "GDG6: remote_host_ipv6=%s", remote_host_ipv6 ? print_in6_addr(*remote_host_ipv6, 0, &gc) : "n/a" ); @@ -1608,9 +1667,15 @@ metric = r->metric; } + int table_id = 0; + if (r->flags & RT_TABLE_DEFINED) + { + table_id = r->table_id; + } + status = RTA_SUCCESS; int ret = net_route_v4_add(ctx, &r->network, netmask_to_netbits2(r->netmask), - &r->gateway, iface, 0, metric); + &r->gateway, iface, table_id, metric); if (ret == -EEXIST) { msg(D_ROUTE, "NOTE: Linux route add command failed because route exists"); @@ -1988,10 +2053,16 @@ metric = r6->metric; } + int table_id = 0; + if ((r6->flags & RT_TABLE_DEFINED) && (r6->table_id > 0)) + { + table_id = r6->table_id; + } + status = RTA_SUCCESS; int ret = net_route_v6_add(ctx, &r6->network, r6->netbits, gateway_needed ? &r6->gateway : NULL, - device, 0, metric); + device, table_id, metric); if (ret == -EEXIST) { msg(D_ROUTE, "NOTE: Linux route add command failed because route exists"); @@ -2196,8 +2267,14 @@ metric = r->metric; } + int table_id = 0; + if (r->flags & RT_TABLE_DEFINED) + { + table_id = r->table_id; + } + if (net_route_v4_del(ctx, &r->network, netmask_to_netbits2(r->netmask), - &r->gateway, NULL, 0, metric) < 0) + &r->gateway, NULL, table_id, metric) < 0) { msg(M_WARN, "ERROR: Linux route delete command failed"); } @@ -2409,8 +2486,16 @@ metric = r6->metric; } + int table_id = 0; + if (r6->flags & RT_TABLE_DEFINED) + { + table_id = r6->table_id; + } + + + if (net_route_v6_del(ctx, &r6->network, r6->netbits, - gateway_needed ? &r6->gateway : NULL, device, 0, + gateway_needed ? &r6->gateway : NULL, device, table_id, metric) < 0) { msg(M_WARN, "ERROR: Linux route v6 delete command failed"); diff --git a/src/openvpn/route.h b/src/openvpn/route.h index 421e7d2..815aea6 100644 --- a/src/openvpn/route.h +++ b/src/openvpn/route.h @@ -63,12 +63,14 @@ #define RTSA_REMOTE_ENDPOINT (1<<0) #define RTSA_REMOTE_HOST (1<<1) #define RTSA_DEFAULT_METRIC (1<<2) +#define RTSA_DEFAULT_TABLE_ID (1<<3) unsigned int flags; in_addr_t remote_endpoint; in_addr_t remote_host; int remote_host_local; /* TLA_x value */ struct route_bypass bypass; + int table_id; int default_metric; }; @@ -77,6 +79,7 @@ const char *network; const char *netmask; const char *gateway; + int table_id; const char *metric; }; @@ -101,6 +104,7 @@ const char *prefix; /* e.g. "2001:db8:1::/64" */ const char *gateway; /* e.g. "2001:db8:0::2" */ const char *metric; /* e.g. "5" */ + int table_id; }; struct route_ipv6_option_list { @@ -113,12 +117,14 @@ #define RT_DEFINED (1<<0) #define RT_ADDED (1<<1) #define RT_METRIC_DEFINED (1<<2) +#define RT_TABLE_DEFINED (1<<3) struct route_ipv4 *next; unsigned int flags; const struct route_option *option; in_addr_t network; in_addr_t netmask; in_addr_t gateway; + int table_id; int metric; }; @@ -129,6 +135,7 @@ unsigned int netbits; struct in6_addr gateway; int metric; + int table_id; /* gateway interface */ #ifdef _WIN32 DWORD adapter_index; /* interface or ~0 if undefined */ @@ -223,6 +230,7 @@ struct in6_addr remote_endpoint_ipv6; /* inside tun */ struct in6_addr remote_host_ipv6; /* --remote address */ int default_metric; + int default_route_table_id; struct route_ipv6_gateway_info rgi6; unsigned int flags; /* RG_x flags, see route_option_list */ @@ -283,17 +291,20 @@ const char *network, const char *netmask, const char *gateway, - const char *metric); + const char *metric, + int table_id); void add_route_ipv6_to_option_list(struct route_ipv6_option_list *l, const char *prefix, const char *gateway, - const char *metric); + const char *metric, + int table_id); bool init_route_list(struct route_list *rl, const struct route_option_list *opt, const char *remote_endpoint, int default_metric, + int table_id, in_addr_t remote_host, struct env_set *es, openvpn_net_ctx_t *ctx); @@ -302,6 +313,7 @@ const struct route_ipv6_option_list *opt6, const char *remote_endpoint, int default_metric, + int table_id, const struct in6_addr *remote_host, struct env_set *es, openvpn_net_ctx_t *ctx); -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/524?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Gerrit-Change-Number: 524 Gerrit-PatchSet: 5 Gerrit-Owner: its_Giaan <gia...@ma...> Gerrit-Reviewer: cron2 <ge...@gr...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-Reviewer: plaisthos <arn...@rf...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: plaisthos <arn...@rf...> Gerrit-Attention: cron2 <ge...@gr...> Gerrit-Attention: its_Giaan <gia...@ma...> Gerrit-Attention: flichtenheld <fr...@li...> Gerrit-MessageType: newpatchset |
From: flichtenheld (C. Review) <ge...@op...> - 2024-07-19 13:43:29
|
Attention is currently required from: cron2, its_Giaan, plaisthos. flichtenheld has posted comments on this change. ( http://gerrit.openvpn.net/c/openvpn/+/524?usp=email ) Change subject: Route: add support for user defined routing table ...................................................................... Patch Set 6: Code-Review+2 (1 comment) Patchset: PS6: Retested with tclient, LGTM -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/524?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Gerrit-Change-Number: 524 Gerrit-PatchSet: 6 Gerrit-Owner: its_Giaan <gia...@ma...> Gerrit-Reviewer: cron2 <ge...@gr...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-Reviewer: plaisthos <arn...@rf...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: plaisthos <arn...@rf...> Gerrit-Attention: cron2 <ge...@gr...> Gerrit-Attention: its_Giaan <gia...@ma...> Gerrit-Comment-Date: Fri, 19 Jul 2024 13:43:19 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: Yes Gerrit-MessageType: comment |
From: cron2 (C. Review) <ge...@op...> - 2024-09-19 10:40:16
|
Attention is currently required from: its_Giaan, plaisthos. cron2 has posted comments on this change. ( http://gerrit.openvpn.net/c/openvpn/+/524?usp=email ) Change subject: Route: add support for user defined routing table ...................................................................... Patch Set 6: Code-Review-1 (1 comment) Patchset: PS6: Still not there - I think the code in `route.c` is much more complex than it needs to be. So with the new patch to `options.c`, we pass the to-be-used routing table ID to `add_route_to_option_list()`, so every route option always(!) has a routing-table to be used (or 0). This should be sufficient. But then, we have a default table_id added in `init_route()`, a number of extra flags (`RT_TABLE_DEFINED` for `r->flags`) etc., which is all not used in the end because even without the flag, `table_id` would become 0 in `add_route()` (by means of `r->table_id` being 0)...? So.. can we do this with half the code? Getting rid of all new DEFINEs, all new arguments and flags to `route_list` things, just storing the table id in `struct route_ipv4` and `struct route_ipv6`)= -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/524?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Gerrit-Change-Number: 524 Gerrit-PatchSet: 6 Gerrit-Owner: its_Giaan <gia...@ma...> Gerrit-Reviewer: cron2 <ge...@gr...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-Reviewer: plaisthos <arn...@rf...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: plaisthos <arn...@rf...> Gerrit-Attention: its_Giaan <gia...@ma...> Gerrit-Comment-Date: Thu, 19 Sep 2024 10:40:05 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: Yes Gerrit-MessageType: comment |
From: its_Giaan (C. Review) <ge...@op...> - 2024-09-23 19:14:58
|
Attention is currently required from: cron2, flichtenheld, its_Giaan, plaisthos. Hello cron2, flichtenheld, plaisthos, I'd like you to reexamine a change. Please visit http://gerrit.openvpn.net/c/openvpn/+/524?usp=email to look at the new patch set (#7). The following approvals got outdated and were removed: Code-Review+2 by flichtenheld, Code-Review-1 by cron2 The change is no longer submittable: Code-Review and checks~ChecksSubmitRule are unsatisfied now. Change subject: Route: add support for user defined routing table ...................................................................... Route: add support for user defined routing table 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). Please note: this feature is currently supported only by Linux/SITNL. Support for other platforms should be added in related backends. Trac #1399 Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Signed-off-by: Gianmarco De Gregori <gia...@ma...> --- M doc/man-sections/vpn-network-options.rst M src/openvpn/helper.c M src/openvpn/init.c M src/openvpn/options.c M src/openvpn/options.h M src/openvpn/route.c M src/openvpn/route.h 7 files changed, 76 insertions(+), 19 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/24/524/7 diff --git a/doc/man-sections/vpn-network-options.rst b/doc/man-sections/vpn-network-options.rst index 84d4273..9d4235b 100644 --- a/doc/man-sections/vpn-network-options.rst +++ b/doc/man-sections/vpn-network-options.rst @@ -371,6 +371,14 @@ 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 @@ -445,14 +453,20 @@ Setup IPv6 routing in the system to send the specified IPv6 network into OpenVPN's *tun*. - Valid syntax: + Valid syntaxes: :: - route-ipv6 ipv6addr/bits [gateway] [metric] + route-ipv6 ipv6addr/bits + route-ipv6 ipv6addr/bits gateway + route-ipv6 ipv6addr/bits gateway metric - 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. + ``gateway`` + Only used for IPv6 routes across *tap* devices, + and if missing, the ``ipv6remote`` field from ``--ifconfig-ipv6`` or + ``--route-ipv6-gateway`` is used. + + ``metric`` + default taken from ``--route-metric`` if set, otherwise :code:`0`. --route-gateway arg Specify a default *gateway* for use with ``--route``. diff --git a/src/openvpn/helper.c b/src/openvpn/helper.c index bbdbc04..2306760 100644 --- a/src/openvpn/helper.c +++ b/src/openvpn/helper.c @@ -118,7 +118,8 @@ print_in_addr_t(network, 0, &o->gc), print_in_addr_t(netmask, 0, &o->gc), NULL, - NULL); + NULL, + o->route_default_table_id); } static void diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 83cc670..d32b903 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -1499,6 +1499,7 @@ options->routes, gw, metric, + options->route_default_table_id, link_socket_current_remote(link_socket_info), es, ctx)) @@ -1546,7 +1547,7 @@ { add_route_ipv6_to_option_list( options->routes_ipv6, string_alloc(opt_list[i], options->routes_ipv6->gc), - NULL, NULL ); + NULL, NULL, options->route_default_table_id); } } @@ -1554,6 +1555,7 @@ options->routes_ipv6, gw, metric, + options->route_default_table_id, link_socket_current_remote_ipv6(link_socket_info), es, ctx)) diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 61f6285..4516a58 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -201,6 +201,10 @@ " pass --ifconfig parms by environment to scripts.\n" "--ifconfig-nowarn : Don't warn if the --ifconfig option on this side of the\n" " connection doesn't match the remote side.\n" +#ifdef TARGET_LINUX + "--route-table table_id : Specify a custom routing table for use with --route(-ipv6).\n" + " If not specified, the id of the default routing table will be used.\n" +#endif "--route network [netmask] [gateway] [metric] :\n" " Add route to routing table after connection\n" " is established. Multiple routes can be specified.\n" @@ -819,6 +823,7 @@ o->ce.mssfix = 0; o->ce.mssfix_default = true; o->ce.mssfix_encap = true; + o->route_default_table_id = 0; o->route_delay_window = 30; o->resolve_retry_seconds = RESOLV_RETRY_INFINITE; o->resolve_in_advance = false; @@ -1910,6 +1915,7 @@ SHOW_STR(route_script); SHOW_STR(route_default_gateway); SHOW_INT(route_default_metric); + SHOW_INT(route_default_table_id); SHOW_BOOL(route_noexec); SHOW_INT(route_delay); SHOW_INT(route_delay_window); @@ -7005,6 +7011,14 @@ cnol_check_alloc(options); add_client_nat_to_option_list(options->client_nat, p[1], p[2], p[3], p[4], msglevel); } + else if (streq(p[0], "route-table") && p[1] && !p[2]) + { +#ifndef ENABLE_SITNL + msg(M_WARN, "NOTE: --route-table is supported only on Linux when SITNL is built-in"); +#endif + VERIFY_PERMISSION(OPT_P_ROUTE_TABLE); + options->route_default_table_id = positive_atoi(p[1]); + } else if (streq(p[0], "route") && p[1] && !p[5]) { VERIFY_PERMISSION(OPT_P_ROUTE); @@ -7026,8 +7040,10 @@ msg(msglevel, "route parameter gateway '%s' must be a valid address", p[3]); goto err; } + /* p[4] is metric, if specified */ } - add_route_to_option_list(options->routes, p[1], p[2], p[3], p[4]); + + add_route_to_option_list(options->routes, p[1], p[2], p[3], p[4], options->route_default_table_id); } else if (streq(p[0], "route-ipv6") && p[1] && !p[4]) { @@ -7045,9 +7061,10 @@ msg(msglevel, "route-ipv6 parameter gateway '%s' must be a valid address", p[2]); goto err; } - /* p[3] is metric, if present */ + /* p[3] is metric, if specified */ } - add_route_ipv6_to_option_list(options->routes_ipv6, p[1], p[2], p[3]); + + add_route_ipv6_to_option_list(options->routes_ipv6, p[1], p[2], p[3], options->route_default_table_id); } else if (streq(p[0], "max-routes") && !p[2]) { diff --git a/src/openvpn/options.h b/src/openvpn/options.h index ee39dbb..bc41988 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -413,6 +413,7 @@ const char *route_predown_script; const char *route_default_gateway; const char *route_ipv6_default_gateway; + int route_default_table_id; int route_default_metric; bool route_noexec; int route_delay; @@ -743,6 +744,7 @@ #define OPT_P_PEER_ID (1<<28) #define OPT_P_INLINE (1<<29) #define OPT_P_PUSH_MTU (1<<30) +#define OPT_P_ROUTE_TABLE (1<<31) #define OPT_P_DEFAULT (~(OPT_P_INSTANCE|OPT_P_PULL_MODE)) diff --git a/src/openvpn/route.c b/src/openvpn/route.c index 2e584c7..3d1d6bb 100644 --- a/src/openvpn/route.c +++ b/src/openvpn/route.c @@ -328,7 +328,6 @@ CLEAR(*r); r->option = ro; - /* network */ if (!is_route_parm_defined(ro->network)) @@ -442,6 +441,9 @@ r->flags |= RT_DEFINED; + /* routing table id */ + r->table_id = ro->table_id; + return true; fail: @@ -498,6 +500,9 @@ r6->flags |= RT_DEFINED; + /* routing table id */ + r6->table_id = r6o->table_id; + return true; fail: @@ -511,7 +516,8 @@ const char *network, const char *netmask, const char *gateway, - const char *metric) + const char *metric, + int table_id) { struct route_option *ro; ALLOC_OBJ_GC(ro, struct route_option, l->gc); @@ -519,6 +525,7 @@ ro->netmask = netmask; ro->gateway = gateway; ro->metric = metric; + ro->table_id = table_id; ro->next = l->routes; l->routes = ro; @@ -528,13 +535,15 @@ add_route_ipv6_to_option_list(struct route_ipv6_option_list *l, const char *prefix, const char *gateway, - const char *metric) + const char *metric, + int table_id) { struct route_ipv6_option *ro; ALLOC_OBJ_GC(ro, struct route_ipv6_option, l->gc); ro->prefix = prefix; ro->gateway = gateway; ro->metric = metric; + ro->table_id = table_id; ro->next = l->routes_ipv6; l->routes_ipv6 = ro; } @@ -632,6 +641,7 @@ const struct route_option_list *opt, const char *remote_endpoint, int default_metric, + int table_id, in_addr_t remote_host, struct env_set *es, openvpn_net_ctx_t *ctx) @@ -791,6 +801,7 @@ const struct route_ipv6_option_list *opt6, const char *remote_endpoint, int default_metric, + int table_id, const struct in6_addr *remote_host_ipv6, struct env_set *es, openvpn_net_ctx_t *ctx) @@ -1611,9 +1622,10 @@ metric = r->metric; } + status = RTA_SUCCESS; int ret = net_route_v4_add(ctx, &r->network, netmask_to_netbits2(r->netmask), - &r->gateway, iface, 0, metric); + &r->gateway, iface, r->table_id, metric); if (ret == -EEXIST) { msg(D_ROUTE, "NOTE: Linux route add command failed because route exists"); @@ -1994,7 +2006,7 @@ status = RTA_SUCCESS; int ret = net_route_v6_add(ctx, &r6->network, r6->netbits, gateway_needed ? &r6->gateway : NULL, - device, 0, metric); + device, r6->table_id, metric); if (ret == -EEXIST) { msg(D_ROUTE, "NOTE: Linux route add command failed because route exists"); @@ -2200,7 +2212,7 @@ } if (net_route_v4_del(ctx, &r->network, netmask_to_netbits2(r->netmask), - &r->gateway, NULL, 0, metric) < 0) + &r->gateway, NULL, r->table_id, metric) < 0) { msg(M_WARN, "ERROR: Linux route delete command failed"); } @@ -2413,7 +2425,7 @@ } if (net_route_v6_del(ctx, &r6->network, r6->netbits, - gateway_needed ? &r6->gateway : NULL, device, 0, + gateway_needed ? &r6->gateway : NULL, device, r6->table_id, metric) < 0) { msg(M_WARN, "ERROR: Linux route v6 delete command failed"); diff --git a/src/openvpn/route.h b/src/openvpn/route.h index 421e7d2..fb2b311 100644 --- a/src/openvpn/route.h +++ b/src/openvpn/route.h @@ -69,6 +69,7 @@ in_addr_t remote_host; int remote_host_local; /* TLA_x value */ struct route_bypass bypass; + int table_id; int default_metric; }; @@ -77,6 +78,7 @@ const char *network; const char *netmask; const char *gateway; + int table_id; const char *metric; }; @@ -101,6 +103,7 @@ const char *prefix; /* e.g. "2001:db8:1::/64" */ const char *gateway; /* e.g. "2001:db8:0::2" */ const char *metric; /* e.g. "5" */ + int table_id; }; struct route_ipv6_option_list { @@ -119,6 +122,7 @@ in_addr_t network; in_addr_t netmask; in_addr_t gateway; + int table_id; int metric; }; @@ -129,6 +133,7 @@ unsigned int netbits; struct in6_addr gateway; int metric; + int table_id; /* gateway interface */ #ifdef _WIN32 DWORD adapter_index; /* interface or ~0 if undefined */ @@ -283,17 +288,20 @@ const char *network, const char *netmask, const char *gateway, - const char *metric); + const char *metric, + int table_id); void add_route_ipv6_to_option_list(struct route_ipv6_option_list *l, const char *prefix, const char *gateway, - const char *metric); + const char *metric, + int table_id); bool init_route_list(struct route_list *rl, const struct route_option_list *opt, const char *remote_endpoint, int default_metric, + int table_id, in_addr_t remote_host, struct env_set *es, openvpn_net_ctx_t *ctx); @@ -302,6 +310,7 @@ const struct route_ipv6_option_list *opt6, const char *remote_endpoint, int default_metric, + int table_id, const struct in6_addr *remote_host, struct env_set *es, openvpn_net_ctx_t *ctx); -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/524?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Gerrit-Change-Number: 524 Gerrit-PatchSet: 7 Gerrit-Owner: its_Giaan <gia...@ma...> Gerrit-Reviewer: cron2 <ge...@gr...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-Reviewer: plaisthos <arn...@rf...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: plaisthos <arn...@rf...> Gerrit-Attention: cron2 <ge...@gr...> Gerrit-Attention: its_Giaan <gia...@ma...> Gerrit-Attention: flichtenheld <fr...@li...> Gerrit-MessageType: newpatchset |
From: its_Giaan (C. Review) <ge...@op...> - 2024-09-24 06:50:23
|
Attention is currently required from: cron2, flichtenheld, its_Giaan, plaisthos. Hello cron2, flichtenheld, plaisthos, I'd like you to reexamine a change. Please visit http://gerrit.openvpn.net/c/openvpn/+/524?usp=email to look at the new patch set (#8). Change subject: Route: add support for user defined routing table ...................................................................... Route: add support for user defined routing table 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). Please note: this feature is currently supported only by Linux/SITNL. Support for other platforms should be added in related backends. Trac #1399 Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Signed-off-by: Gianmarco De Gregori <gia...@ma...> --- M doc/man-sections/vpn-network-options.rst M src/openvpn/helper.c M src/openvpn/init.c M src/openvpn/options.c M src/openvpn/options.h M src/openvpn/route.c M src/openvpn/route.h 7 files changed, 70 insertions(+), 19 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/24/524/8 diff --git a/doc/man-sections/vpn-network-options.rst b/doc/man-sections/vpn-network-options.rst index 84d4273..9d4235b 100644 --- a/doc/man-sections/vpn-network-options.rst +++ b/doc/man-sections/vpn-network-options.rst @@ -371,6 +371,14 @@ 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 @@ -445,14 +453,20 @@ Setup IPv6 routing in the system to send the specified IPv6 network into OpenVPN's *tun*. - Valid syntax: + Valid syntaxes: :: - route-ipv6 ipv6addr/bits [gateway] [metric] + route-ipv6 ipv6addr/bits + route-ipv6 ipv6addr/bits gateway + route-ipv6 ipv6addr/bits gateway metric - 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. + ``gateway`` + Only used for IPv6 routes across *tap* devices, + and if missing, the ``ipv6remote`` field from ``--ifconfig-ipv6`` or + ``--route-ipv6-gateway`` is used. + + ``metric`` + default taken from ``--route-metric`` if set, otherwise :code:`0`. --route-gateway arg Specify a default *gateway* for use with ``--route``. diff --git a/src/openvpn/helper.c b/src/openvpn/helper.c index bbdbc04..2306760 100644 --- a/src/openvpn/helper.c +++ b/src/openvpn/helper.c @@ -118,7 +118,8 @@ print_in_addr_t(network, 0, &o->gc), print_in_addr_t(netmask, 0, &o->gc), NULL, - NULL); + NULL, + o->route_default_table_id); } static void diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 83cc670..5db6304 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -1546,7 +1546,7 @@ { add_route_ipv6_to_option_list( options->routes_ipv6, string_alloc(opt_list[i], options->routes_ipv6->gc), - NULL, NULL ); + NULL, NULL, options->route_default_table_id); } } diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 61f6285..4516a58 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -201,6 +201,10 @@ " pass --ifconfig parms by environment to scripts.\n" "--ifconfig-nowarn : Don't warn if the --ifconfig option on this side of the\n" " connection doesn't match the remote side.\n" +#ifdef TARGET_LINUX + "--route-table table_id : Specify a custom routing table for use with --route(-ipv6).\n" + " If not specified, the id of the default routing table will be used.\n" +#endif "--route network [netmask] [gateway] [metric] :\n" " Add route to routing table after connection\n" " is established. Multiple routes can be specified.\n" @@ -819,6 +823,7 @@ o->ce.mssfix = 0; o->ce.mssfix_default = true; o->ce.mssfix_encap = true; + o->route_default_table_id = 0; o->route_delay_window = 30; o->resolve_retry_seconds = RESOLV_RETRY_INFINITE; o->resolve_in_advance = false; @@ -1910,6 +1915,7 @@ SHOW_STR(route_script); SHOW_STR(route_default_gateway); SHOW_INT(route_default_metric); + SHOW_INT(route_default_table_id); SHOW_BOOL(route_noexec); SHOW_INT(route_delay); SHOW_INT(route_delay_window); @@ -7005,6 +7011,14 @@ cnol_check_alloc(options); add_client_nat_to_option_list(options->client_nat, p[1], p[2], p[3], p[4], msglevel); } + else if (streq(p[0], "route-table") && p[1] && !p[2]) + { +#ifndef ENABLE_SITNL + msg(M_WARN, "NOTE: --route-table is supported only on Linux when SITNL is built-in"); +#endif + VERIFY_PERMISSION(OPT_P_ROUTE_TABLE); + options->route_default_table_id = positive_atoi(p[1]); + } else if (streq(p[0], "route") && p[1] && !p[5]) { VERIFY_PERMISSION(OPT_P_ROUTE); @@ -7026,8 +7040,10 @@ msg(msglevel, "route parameter gateway '%s' must be a valid address", p[3]); goto err; } + /* p[4] is metric, if specified */ } - add_route_to_option_list(options->routes, p[1], p[2], p[3], p[4]); + + add_route_to_option_list(options->routes, p[1], p[2], p[3], p[4], options->route_default_table_id); } else if (streq(p[0], "route-ipv6") && p[1] && !p[4]) { @@ -7045,9 +7061,10 @@ msg(msglevel, "route-ipv6 parameter gateway '%s' must be a valid address", p[2]); goto err; } - /* p[3] is metric, if present */ + /* p[3] is metric, if specified */ } - add_route_ipv6_to_option_list(options->routes_ipv6, p[1], p[2], p[3]); + + add_route_ipv6_to_option_list(options->routes_ipv6, p[1], p[2], p[3], options->route_default_table_id); } else if (streq(p[0], "max-routes") && !p[2]) { diff --git a/src/openvpn/options.h b/src/openvpn/options.h index ee39dbb..bc41988 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -413,6 +413,7 @@ const char *route_predown_script; const char *route_default_gateway; const char *route_ipv6_default_gateway; + int route_default_table_id; int route_default_metric; bool route_noexec; int route_delay; @@ -743,6 +744,7 @@ #define OPT_P_PEER_ID (1<<28) #define OPT_P_INLINE (1<<29) #define OPT_P_PUSH_MTU (1<<30) +#define OPT_P_ROUTE_TABLE (1<<31) #define OPT_P_DEFAULT (~(OPT_P_INSTANCE|OPT_P_PULL_MODE)) diff --git a/src/openvpn/route.c b/src/openvpn/route.c index 2e584c7..4e8bae4 100644 --- a/src/openvpn/route.c +++ b/src/openvpn/route.c @@ -328,7 +328,6 @@ CLEAR(*r); r->option = ro; - /* network */ if (!is_route_parm_defined(ro->network)) @@ -442,6 +441,9 @@ r->flags |= RT_DEFINED; + /* routing table id */ + r->table_id = ro->table_id; + return true; fail: @@ -498,6 +500,9 @@ r6->flags |= RT_DEFINED; + /* routing table id */ + r6->table_id = r6o->table_id; + return true; fail: @@ -511,7 +516,8 @@ const char *network, const char *netmask, const char *gateway, - const char *metric) + const char *metric, + int table_id) { struct route_option *ro; ALLOC_OBJ_GC(ro, struct route_option, l->gc); @@ -519,6 +525,7 @@ ro->netmask = netmask; ro->gateway = gateway; ro->metric = metric; + ro->table_id = table_id; ro->next = l->routes; l->routes = ro; @@ -528,13 +535,15 @@ add_route_ipv6_to_option_list(struct route_ipv6_option_list *l, const char *prefix, const char *gateway, - const char *metric) + const char *metric, + int table_id) { struct route_ipv6_option *ro; ALLOC_OBJ_GC(ro, struct route_ipv6_option, l->gc); ro->prefix = prefix; ro->gateway = gateway; ro->metric = metric; + ro->table_id = table_id; ro->next = l->routes_ipv6; l->routes_ipv6 = ro; } @@ -1611,9 +1620,10 @@ metric = r->metric; } + status = RTA_SUCCESS; int ret = net_route_v4_add(ctx, &r->network, netmask_to_netbits2(r->netmask), - &r->gateway, iface, 0, metric); + &r->gateway, iface, r->table_id, metric); if (ret == -EEXIST) { msg(D_ROUTE, "NOTE: Linux route add command failed because route exists"); @@ -1994,7 +2004,7 @@ status = RTA_SUCCESS; int ret = net_route_v6_add(ctx, &r6->network, r6->netbits, gateway_needed ? &r6->gateway : NULL, - device, 0, metric); + device, r6->table_id, metric); if (ret == -EEXIST) { msg(D_ROUTE, "NOTE: Linux route add command failed because route exists"); @@ -2200,7 +2210,7 @@ } if (net_route_v4_del(ctx, &r->network, netmask_to_netbits2(r->netmask), - &r->gateway, NULL, 0, metric) < 0) + &r->gateway, NULL, r->table_id, metric) < 0) { msg(M_WARN, "ERROR: Linux route delete command failed"); } @@ -2413,7 +2423,7 @@ } if (net_route_v6_del(ctx, &r6->network, r6->netbits, - gateway_needed ? &r6->gateway : NULL, device, 0, + gateway_needed ? &r6->gateway : NULL, device, r6->table_id, metric) < 0) { msg(M_WARN, "ERROR: Linux route v6 delete command failed"); diff --git a/src/openvpn/route.h b/src/openvpn/route.h index 421e7d2..48faada 100644 --- a/src/openvpn/route.h +++ b/src/openvpn/route.h @@ -69,6 +69,7 @@ in_addr_t remote_host; int remote_host_local; /* TLA_x value */ struct route_bypass bypass; + int table_id; int default_metric; }; @@ -77,6 +78,7 @@ const char *network; const char *netmask; const char *gateway; + int table_id; const char *metric; }; @@ -101,6 +103,7 @@ const char *prefix; /* e.g. "2001:db8:1::/64" */ const char *gateway; /* e.g. "2001:db8:0::2" */ const char *metric; /* e.g. "5" */ + int table_id; }; struct route_ipv6_option_list { @@ -119,6 +122,7 @@ in_addr_t network; in_addr_t netmask; in_addr_t gateway; + int table_id; int metric; }; @@ -129,6 +133,7 @@ unsigned int netbits; struct in6_addr gateway; int metric; + int table_id; /* gateway interface */ #ifdef _WIN32 DWORD adapter_index; /* interface or ~0 if undefined */ @@ -283,12 +288,14 @@ const char *network, const char *netmask, const char *gateway, - const char *metric); + const char *metric, + int table_id); void add_route_ipv6_to_option_list(struct route_ipv6_option_list *l, const char *prefix, const char *gateway, - const char *metric); + const char *metric, + int table_id); bool init_route_list(struct route_list *rl, const struct route_option_list *opt, -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/524?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Gerrit-Change-Number: 524 Gerrit-PatchSet: 8 Gerrit-Owner: its_Giaan <gia...@ma...> Gerrit-Reviewer: cron2 <ge...@gr...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-Reviewer: plaisthos <arn...@rf...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: plaisthos <arn...@rf...> Gerrit-Attention: cron2 <ge...@gr...> Gerrit-Attention: its_Giaan <gia...@ma...> Gerrit-Attention: flichtenheld <fr...@li...> Gerrit-MessageType: newpatchset |
From: cron2 (C. Review) <ge...@op...> - 2025-06-18 16:28:48
|
Attention is currently required from: flichtenheld, its_Giaan, plaisthos. cron2 has posted comments on this change. ( http://gerrit.openvpn.net/c/openvpn/+/524?usp=email ) Change subject: Route: add support for user defined routing table ...................................................................... Patch Set 8: Code-Review-1 (3 comments) Patchset: PS8: Got left out in the sun too long, so now it needs polish... (sorry) File src/openvpn/options.c: http://gerrit.openvpn.net/c/openvpn/+/524/comment/5ca01c93_caaa3aa2 : PS8, Line 7020: options->route_default_table_id = positive_atoi(p[1]); Unfortunately, `positive_atoi()` now wants 2 arguments... (`msglevel`). So this needs a rebase & fixup. File src/openvpn/route.c: http://gerrit.openvpn.net/c/openvpn/+/524/comment/2f114621_8e4ffe35 : PS8, Line 332: /* network */ spurious blank line removal... if you want to remove one, I think removing the one after the `/* network */` comment makes more sense, and maybe one of the 2 blank lines further down (337). But removing this one does no good. -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/524?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Gerrit-Change-Number: 524 Gerrit-PatchSet: 8 Gerrit-Owner: its_Giaan <gia...@ma...> Gerrit-Reviewer: cron2 <ge...@gr...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-Reviewer: plaisthos <arn...@rf...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: plaisthos <arn...@rf...> Gerrit-Attention: its_Giaan <gia...@ma...> Gerrit-Attention: flichtenheld <fr...@li...> Gerrit-Comment-Date: Wed, 18 Jun 2025 16:28:34 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: Yes Gerrit-MessageType: comment |
From: its_Giaan (C. Review) <ge...@op...> - 2025-06-19 16:04:07
|
Attention is currently required from: cron2, flichtenheld, its_Giaan, plaisthos. Hello cron2, flichtenheld, plaisthos, I'd like you to reexamine a change. Please visit http://gerrit.openvpn.net/c/openvpn/+/524?usp=email to look at the new patch set (#9). The following approvals got outdated and were removed: Code-Review-1 by cron2 Change subject: Route: add support for user defined routing table ...................................................................... Route: add support for user defined routing table 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). Please note: this feature is currently supported only by Linux/SITNL. Support for other platforms should be added in related backends. Trac #1399 Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Signed-off-by: Gianmarco De Gregori <gia...@ma...> --- M doc/man-sections/vpn-network-options.rst M src/openvpn/helper.c M src/openvpn/init.c M src/openvpn/options.c M src/openvpn/options.h M src/openvpn/route.c M src/openvpn/route.h 7 files changed, 68 insertions(+), 20 deletions(-) git pull ssh://gerrit.openvpn.net:29418/openvpn refs/changes/24/524/9 diff --git a/doc/man-sections/vpn-network-options.rst b/doc/man-sections/vpn-network-options.rst index 40b8c19..4a64e8d 100644 --- a/doc/man-sections/vpn-network-options.rst +++ b/doc/man-sections/vpn-network-options.rst @@ -389,6 +389,14 @@ 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 @@ -463,14 +471,20 @@ Setup IPv6 routing in the system to send the specified IPv6 network into OpenVPN's *tun*. - Valid syntax: + Valid syntaxes: :: - route-ipv6 ipv6addr/bits [gateway] [metric] + route-ipv6 ipv6addr/bits + route-ipv6 ipv6addr/bits gateway + route-ipv6 ipv6addr/bits gateway metric - 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. + ``gateway`` + Only used for IPv6 routes across *tap* devices, + and if missing, the ``ipv6remote`` field from ``--ifconfig-ipv6`` or + ``--route-ipv6-gateway`` is used. + + ``metric`` + default taken from ``--route-metric`` if set, otherwise :code:`0`. --route-gateway arg Specify a default *gateway* for use with ``--route``. diff --git a/src/openvpn/helper.c b/src/openvpn/helper.c index 8761826..7cef9db 100644 --- a/src/openvpn/helper.c +++ b/src/openvpn/helper.c @@ -118,7 +118,8 @@ print_in_addr_t(network, 0, &o->gc), print_in_addr_t(netmask, 0, &o->gc), NULL, - NULL); + NULL, + o->route_default_table_id); } static void diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 7d4eb85..77747a2 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -1566,7 +1566,7 @@ { add_route_ipv6_to_option_list( options->routes_ipv6, string_alloc(opt_list[i], options->routes_ipv6->gc), - NULL, NULL ); + NULL, NULL, options->route_default_table_id); } } diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 3cf8c2a..7e26069 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -213,6 +213,10 @@ " pass --ifconfig parms by environment to scripts.\n" "--ifconfig-nowarn : Don't warn if the --ifconfig option on this side of the\n" " connection doesn't match the remote side.\n" +#ifdef TARGET_LINUX + "--route-table table_id : Specify a custom routing table for use with --route(-ipv6).\n" + " If not specified, the id of the default routing table will be used.\n" +#endif "--route network [netmask] [gateway] [metric] :\n" " Add route to routing table after connection\n" " is established. Multiple routes can be specified.\n" @@ -829,6 +833,7 @@ o->ce.mssfix = 0; o->ce.mssfix_default = true; o->ce.mssfix_encap = true; + o->route_default_table_id = 0; o->route_delay_window = 30; o->resolve_retry_seconds = RESOLV_RETRY_INFINITE; o->resolve_in_advance = false; @@ -1799,6 +1804,7 @@ SHOW_STR(route_script); SHOW_STR(route_default_gateway); SHOW_INT(route_default_metric); + SHOW_INT(route_default_table_id); SHOW_BOOL(route_noexec); SHOW_INT(route_delay); SHOW_INT(route_delay_window); @@ -7064,6 +7070,14 @@ cnol_check_alloc(options); add_client_nat_to_option_list(options->client_nat, p[1], p[2], p[3], p[4], msglevel); } + else if (streq(p[0], "route-table") && p[1] && !p[2]) + { +#ifndef ENABLE_SITNL + msg(M_WARN, "NOTE: --route-table is supported only on Linux when SITNL is built-in"); +#endif + VERIFY_PERMISSION(OPT_P_ROUTE_TABLE); + options->route_default_table_id = positive_atoi(p[1], msglevel); + } else if (streq(p[0], "route") && p[1] && !p[5]) { VERIFY_PERMISSION(OPT_P_ROUTE); @@ -7085,8 +7099,9 @@ msg(msglevel, "route parameter gateway '%s' must be a valid address", p[3]); goto err; } + /* p[4] is metric, if specified */ } - add_route_to_option_list(options->routes, p[1], p[2], p[3], p[4]); + add_route_to_option_list(options->routes, p[1], p[2], p[3], p[4], options->route_default_table_id); } else if (streq(p[0], "route-ipv6") && p[1] && !p[4]) { @@ -7104,9 +7119,9 @@ msg(msglevel, "route-ipv6 parameter gateway '%s' must be a valid address", p[2]); goto err; } - /* p[3] is metric, if present */ + /* p[3] is metric, if specified */ } - add_route_ipv6_to_option_list(options->routes_ipv6, p[1], p[2], p[3]); + add_route_ipv6_to_option_list(options->routes_ipv6, p[1], p[2], p[3], options->route_default_table_id); } else if (streq(p[0], "max-routes") && !p[2]) { diff --git a/src/openvpn/options.h b/src/openvpn/options.h index 46ec32b..56e85d7 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -427,6 +427,7 @@ const char *route_predown_script; const char *route_default_gateway; const char *route_ipv6_default_gateway; + int route_default_table_id; int route_default_metric; bool route_noexec; int route_delay; @@ -758,6 +759,7 @@ #define OPT_P_PEER_ID (1<<28) #define OPT_P_INLINE (1<<29) #define OPT_P_PUSH_MTU (1<<30) +#define OPT_P_ROUTE_TABLE (1<<31) #define OPT_P_DEFAULT (~(OPT_P_INSTANCE|OPT_P_PULL_MODE)) diff --git a/src/openvpn/route.c b/src/openvpn/route.c index bd79a28..156262a 100644 --- a/src/openvpn/route.c +++ b/src/openvpn/route.c @@ -330,13 +330,11 @@ r->option = ro; /* network */ - if (!is_route_parm_defined(ro->network)) { goto fail; } - /* get_special_addr replaces specialaddr with a special ip addr * like gw. getaddrinfo is called to convert a a addrinfo struct */ @@ -442,6 +440,9 @@ r->flags |= RT_DEFINED; + /* routing table id */ + r->table_id = ro->table_id; + return true; fail: @@ -498,6 +499,9 @@ r6->flags |= RT_DEFINED; + /* routing table id */ + r6->table_id = r6o->table_id; + return true; fail: @@ -511,7 +515,8 @@ const char *network, const char *netmask, const char *gateway, - const char *metric) + const char *metric, + int table_id) { struct route_option *ro; ALLOC_OBJ_GC(ro, struct route_option, l->gc); @@ -519,6 +524,7 @@ ro->netmask = netmask; ro->gateway = gateway; ro->metric = metric; + ro->table_id = table_id; ro->next = l->routes; l->routes = ro; @@ -528,13 +534,15 @@ add_route_ipv6_to_option_list(struct route_ipv6_option_list *l, const char *prefix, const char *gateway, - const char *metric) + const char *metric, + int table_id) { struct route_ipv6_option *ro; ALLOC_OBJ_GC(ro, struct route_ipv6_option, l->gc); ro->prefix = prefix; ro->gateway = gateway; ro->metric = metric; + ro->table_id = table_id; ro->next = l->routes_ipv6; l->routes_ipv6 = ro; } @@ -1610,9 +1618,10 @@ metric = r->metric; } + status = RTA_SUCCESS; int ret = net_route_v4_add(ctx, &r->network, netmask_to_netbits2(r->netmask), - &r->gateway, iface, 0, metric); + &r->gateway, iface, r->table_id, metric); if (ret == -EEXIST) { msg(D_ROUTE, "NOTE: Linux route add command failed because route exists"); @@ -2007,7 +2016,7 @@ status = RTA_SUCCESS; int ret = net_route_v6_add(ctx, &r6->network, r6->netbits, gateway_needed ? &r6->gateway : NULL, - device, 0, metric); + device, r6->table_id, metric); if (ret == -EEXIST) { msg(D_ROUTE, "NOTE: Linux route add command failed because route exists"); @@ -2227,7 +2236,7 @@ } if (net_route_v4_del(ctx, &r->network, netmask_to_netbits2(r->netmask), - &r->gateway, NULL, 0, metric) < 0) + &r->gateway, NULL, r->table_id, metric) < 0) { msg(M_WARN, "ERROR: Linux route delete command failed"); } @@ -2452,7 +2461,7 @@ } if (net_route_v6_del(ctx, &r6->network, r6->netbits, - gateway_needed ? &r6->gateway : NULL, device, 0, + gateway_needed ? &r6->gateway : NULL, device, r6->table_id, metric) < 0) { msg(M_WARN, "ERROR: Linux route v6 delete command failed"); diff --git a/src/openvpn/route.h b/src/openvpn/route.h index aa3114c..237375c 100644 --- a/src/openvpn/route.h +++ b/src/openvpn/route.h @@ -69,6 +69,7 @@ in_addr_t remote_host; int remote_host_local; /* TLA_x value */ struct route_bypass bypass; + int table_id; int default_metric; }; @@ -77,6 +78,7 @@ const char *network; const char *netmask; const char *gateway; + int table_id; const char *metric; }; @@ -101,6 +103,7 @@ const char *prefix; /* e.g. "2001:db8:1::/64" */ const char *gateway; /* e.g. "2001:db8:0::2" */ const char *metric; /* e.g. "5" */ + int table_id; }; struct route_ipv6_option_list { @@ -119,6 +122,7 @@ in_addr_t network; in_addr_t netmask; in_addr_t gateway; + int table_id; int metric; }; @@ -129,6 +133,7 @@ unsigned int netbits; struct in6_addr gateway; int metric; + int table_id; /* gateway interface */ #ifdef _WIN32 DWORD adapter_index; /* interface or ~0 if undefined */ @@ -290,12 +295,14 @@ const char *network, const char *netmask, const char *gateway, - const char *metric); + const char *metric, + int table_id); void add_route_ipv6_to_option_list(struct route_ipv6_option_list *l, const char *prefix, const char *gateway, - const char *metric); + const char *metric, + int table_id); bool init_route_list(struct route_list *rl, const struct route_option_list *opt, -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/524?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Gerrit-Change-Number: 524 Gerrit-PatchSet: 9 Gerrit-Owner: its_Giaan <gia...@ma...> Gerrit-Reviewer: cron2 <ge...@gr...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-Reviewer: plaisthos <arn...@rf...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: plaisthos <arn...@rf...> Gerrit-Attention: cron2 <ge...@gr...> Gerrit-Attention: its_Giaan <gia...@ma...> Gerrit-Attention: flichtenheld <fr...@li...> Gerrit-MessageType: newpatchset |
From: its_Giaan (C. Review) <ge...@op...> - 2025-06-19 16:04:51
|
Attention is currently required from: cron2, flichtenheld, plaisthos. its_Giaan has posted comments on this change. ( http://gerrit.openvpn.net/c/openvpn/+/524?usp=email ) Change subject: Route: add support for user defined routing table ...................................................................... Patch Set 9: (2 comments) File src/openvpn/options.c: http://gerrit.openvpn.net/c/openvpn/+/524/comment/4a43f18d_49c13bde : PS8, Line 7020: options->route_default_table_id = positive_atoi(p[1]); > Unfortunately, `positive_atoi()` now wants 2 arguments... (`msglevel`). […] Done File src/openvpn/route.c: http://gerrit.openvpn.net/c/openvpn/+/524/comment/c62432ad_b77f46d7 : PS8, Line 332: /* network */ > spurious blank line removal... […] Done -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/524?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Gerrit-Change-Number: 524 Gerrit-PatchSet: 9 Gerrit-Owner: its_Giaan <gia...@ma...> Gerrit-Reviewer: cron2 <ge...@gr...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-Reviewer: plaisthos <arn...@rf...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: plaisthos <arn...@rf...> Gerrit-Attention: cron2 <ge...@gr...> Gerrit-Attention: flichtenheld <fr...@li...> Gerrit-Comment-Date: Thu, 19 Jun 2025 16:04:36 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: No Comment-In-Reply-To: cron2 <ge...@gr...> Gerrit-MessageType: comment |
From: cron2 (C. Review) <ge...@op...> - 2025-06-22 11:00:52
|
Attention is currently required from: flichtenheld, its_Giaan, plaisthos. cron2 has posted comments on this change. ( http://gerrit.openvpn.net/c/openvpn/+/524?usp=email ) Change subject: Route: add support for user defined routing table ...................................................................... Patch Set 9: Code-Review+2 -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/524?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Gerrit-Change-Number: 524 Gerrit-PatchSet: 9 Gerrit-Owner: its_Giaan <gia...@ma...> Gerrit-Reviewer: cron2 <ge...@gr...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-Reviewer: plaisthos <arn...@rf...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: plaisthos <arn...@rf...> Gerrit-Attention: its_Giaan <gia...@ma...> Gerrit-Attention: flichtenheld <fr...@li...> Gerrit-Comment-Date: Sun, 22 Jun 2025 11:00:37 +0000 Gerrit-HasComments: No Gerrit-Has-Labels: Yes Gerrit-MessageType: comment |
From: cron2 (C. Review) <ge...@op...> - 2025-06-22 11:03:06
|
Attention is currently required from: flichtenheld, its_Giaan, plaisthos. cron2 has posted comments on this change. ( http://gerrit.openvpn.net/c/openvpn/+/524?usp=email ) Change subject: Route: add support for user defined routing table ...................................................................... Patch Set 9: (1 comment) Patchset: PS9: Tested this on gentoo, with ```... --client --route-table 77 --route 10.195.0.0 255.255.0.0 --route-table 78``` which does what I expected - 10.195.0.0/16 shows up in table 77, and all pushed routes show up in table 78 ``` 2025-06-22 13:00:15 net_route_v4_del: 10.195.0.0/16 via 10.194.2.169 dev [NULL] table 77 metric -1 2025-06-22 13:00:15 net_route_v4_del: 10.194.0.0/16 via 10.194.2.169 dev [NULL] table 78 metric -1 2025-06-22 13:00:15 net_route_v4_del: 10.194.2.1/32 via 10.194.2.169 dev [NULL] table 78 metric -1 ``` (and "ip route list table 77 / 78" confirms that). It claims to do the right thing for IPv6 ``` 2025-06-22 13:00:15 net_route_v6_del: fd00:abcd:194::/48 via :: dev tun8 table 78 metric -1 ``` but `ip route -6 list` shows no table (but the same holds for ipv6 routes added via `ip route add -6 ... table 78` so this looks more like a linux weirdness than an OpenVPN/SITNL issue to me). -- To view, visit http://gerrit.openvpn.net/c/openvpn/+/524?usp=email To unsubscribe, or for help writing mail filters, visit http://gerrit.openvpn.net/settings Gerrit-Project: openvpn Gerrit-Branch: master Gerrit-Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Gerrit-Change-Number: 524 Gerrit-PatchSet: 9 Gerrit-Owner: its_Giaan <gia...@ma...> Gerrit-Reviewer: cron2 <ge...@gr...> Gerrit-Reviewer: flichtenheld <fr...@li...> Gerrit-Reviewer: plaisthos <arn...@rf...> Gerrit-CC: openvpn-devel <ope...@li...> Gerrit-Attention: plaisthos <arn...@rf...> Gerrit-Attention: its_Giaan <gia...@ma...> Gerrit-Attention: flichtenheld <fr...@li...> Gerrit-Comment-Date: Sun, 22 Jun 2025 11:02:51 +0000 Gerrit-HasComments: Yes Gerrit-Has-Labels: No Gerrit-MessageType: comment |
From: Gert D. <ge...@gr...> - 2025-06-22 11:03:24
|
From: Gianmarco De Gregori <gia...@ma...> 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). Please note: this feature is currently supported only by Linux/SITNL. Support for other platforms should be added in related backends. Trac #1399 Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 Signed-off-by: Gianmarco De Gregori <gia...@ma...> Acked-by: Gert Doering <ge...@gr...> --- This change was reviewed on Gerrit and approved by at least one developer. I request to merge it to master. Gerrit URL: https://gerrit.openvpn.net/c/openvpn/+/524 This mail reflects revision 9 of this Change. Acked-by according to Gerrit (reflected above): Gert Doering <ge...@gr...> diff --git a/doc/man-sections/vpn-network-options.rst b/doc/man-sections/vpn-network-options.rst index 40b8c19..4a64e8d 100644 --- a/doc/man-sections/vpn-network-options.rst +++ b/doc/man-sections/vpn-network-options.rst @@ -389,6 +389,14 @@ 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 @@ -463,14 +471,20 @@ Setup IPv6 routing in the system to send the specified IPv6 network into OpenVPN's *tun*. - Valid syntax: + Valid syntaxes: :: - route-ipv6 ipv6addr/bits [gateway] [metric] + route-ipv6 ipv6addr/bits + route-ipv6 ipv6addr/bits gateway + route-ipv6 ipv6addr/bits gateway metric - 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. + ``gateway`` + Only used for IPv6 routes across *tap* devices, + and if missing, the ``ipv6remote`` field from ``--ifconfig-ipv6`` or + ``--route-ipv6-gateway`` is used. + + ``metric`` + default taken from ``--route-metric`` if set, otherwise :code:`0`. --route-gateway arg Specify a default *gateway* for use with ``--route``. diff --git a/src/openvpn/helper.c b/src/openvpn/helper.c index 8761826..7cef9db 100644 --- a/src/openvpn/helper.c +++ b/src/openvpn/helper.c @@ -118,7 +118,8 @@ print_in_addr_t(network, 0, &o->gc), print_in_addr_t(netmask, 0, &o->gc), NULL, - NULL); + NULL, + o->route_default_table_id); } static void diff --git a/src/openvpn/init.c b/src/openvpn/init.c index 7d4eb85..77747a2 100644 --- a/src/openvpn/init.c +++ b/src/openvpn/init.c @@ -1566,7 +1566,7 @@ { add_route_ipv6_to_option_list( options->routes_ipv6, string_alloc(opt_list[i], options->routes_ipv6->gc), - NULL, NULL ); + NULL, NULL, options->route_default_table_id); } } diff --git a/src/openvpn/options.c b/src/openvpn/options.c index 3cf8c2a..7e26069 100644 --- a/src/openvpn/options.c +++ b/src/openvpn/options.c @@ -213,6 +213,10 @@ " pass --ifconfig parms by environment to scripts.\n" "--ifconfig-nowarn : Don't warn if the --ifconfig option on this side of the\n" " connection doesn't match the remote side.\n" +#ifdef TARGET_LINUX + "--route-table table_id : Specify a custom routing table for use with --route(-ipv6).\n" + " If not specified, the id of the default routing table will be used.\n" +#endif "--route network [netmask] [gateway] [metric] :\n" " Add route to routing table after connection\n" " is established. Multiple routes can be specified.\n" @@ -829,6 +833,7 @@ o->ce.mssfix = 0; o->ce.mssfix_default = true; o->ce.mssfix_encap = true; + o->route_default_table_id = 0; o->route_delay_window = 30; o->resolve_retry_seconds = RESOLV_RETRY_INFINITE; o->resolve_in_advance = false; @@ -1799,6 +1804,7 @@ SHOW_STR(route_script); SHOW_STR(route_default_gateway); SHOW_INT(route_default_metric); + SHOW_INT(route_default_table_id); SHOW_BOOL(route_noexec); SHOW_INT(route_delay); SHOW_INT(route_delay_window); @@ -7064,6 +7070,14 @@ cnol_check_alloc(options); add_client_nat_to_option_list(options->client_nat, p[1], p[2], p[3], p[4], msglevel); } + else if (streq(p[0], "route-table") && p[1] && !p[2]) + { +#ifndef ENABLE_SITNL + msg(M_WARN, "NOTE: --route-table is supported only on Linux when SITNL is built-in"); +#endif + VERIFY_PERMISSION(OPT_P_ROUTE_TABLE); + options->route_default_table_id = positive_atoi(p[1], msglevel); + } else if (streq(p[0], "route") && p[1] && !p[5]) { VERIFY_PERMISSION(OPT_P_ROUTE); @@ -7085,8 +7099,9 @@ msg(msglevel, "route parameter gateway '%s' must be a valid address", p[3]); goto err; } + /* p[4] is metric, if specified */ } - add_route_to_option_list(options->routes, p[1], p[2], p[3], p[4]); + add_route_to_option_list(options->routes, p[1], p[2], p[3], p[4], options->route_default_table_id); } else if (streq(p[0], "route-ipv6") && p[1] && !p[4]) { @@ -7104,9 +7119,9 @@ msg(msglevel, "route-ipv6 parameter gateway '%s' must be a valid address", p[2]); goto err; } - /* p[3] is metric, if present */ + /* p[3] is metric, if specified */ } - add_route_ipv6_to_option_list(options->routes_ipv6, p[1], p[2], p[3]); + add_route_ipv6_to_option_list(options->routes_ipv6, p[1], p[2], p[3], options->route_default_table_id); } else if (streq(p[0], "max-routes") && !p[2]) { diff --git a/src/openvpn/options.h b/src/openvpn/options.h index 46ec32b..56e85d7 100644 --- a/src/openvpn/options.h +++ b/src/openvpn/options.h @@ -427,6 +427,7 @@ const char *route_predown_script; const char *route_default_gateway; const char *route_ipv6_default_gateway; + int route_default_table_id; int route_default_metric; bool route_noexec; int route_delay; @@ -758,6 +759,7 @@ #define OPT_P_PEER_ID (1<<28) #define OPT_P_INLINE (1<<29) #define OPT_P_PUSH_MTU (1<<30) +#define OPT_P_ROUTE_TABLE (1<<31) #define OPT_P_DEFAULT (~(OPT_P_INSTANCE|OPT_P_PULL_MODE)) diff --git a/src/openvpn/route.c b/src/openvpn/route.c index bd79a28..156262a 100644 --- a/src/openvpn/route.c +++ b/src/openvpn/route.c @@ -330,13 +330,11 @@ r->option = ro; /* network */ - if (!is_route_parm_defined(ro->network)) { goto fail; } - /* get_special_addr replaces specialaddr with a special ip addr * like gw. getaddrinfo is called to convert a a addrinfo struct */ @@ -442,6 +440,9 @@ r->flags |= RT_DEFINED; + /* routing table id */ + r->table_id = ro->table_id; + return true; fail: @@ -498,6 +499,9 @@ r6->flags |= RT_DEFINED; + /* routing table id */ + r6->table_id = r6o->table_id; + return true; fail: @@ -511,7 +515,8 @@ const char *network, const char *netmask, const char *gateway, - const char *metric) + const char *metric, + int table_id) { struct route_option *ro; ALLOC_OBJ_GC(ro, struct route_option, l->gc); @@ -519,6 +524,7 @@ ro->netmask = netmask; ro->gateway = gateway; ro->metric = metric; + ro->table_id = table_id; ro->next = l->routes; l->routes = ro; @@ -528,13 +534,15 @@ add_route_ipv6_to_option_list(struct route_ipv6_option_list *l, const char *prefix, const char *gateway, - const char *metric) + const char *metric, + int table_id) { struct route_ipv6_option *ro; ALLOC_OBJ_GC(ro, struct route_ipv6_option, l->gc); ro->prefix = prefix; ro->gateway = gateway; ro->metric = metric; + ro->table_id = table_id; ro->next = l->routes_ipv6; l->routes_ipv6 = ro; } @@ -1610,9 +1618,10 @@ metric = r->metric; } + status = RTA_SUCCESS; int ret = net_route_v4_add(ctx, &r->network, netmask_to_netbits2(r->netmask), - &r->gateway, iface, 0, metric); + &r->gateway, iface, r->table_id, metric); if (ret == -EEXIST) { msg(D_ROUTE, "NOTE: Linux route add command failed because route exists"); @@ -2007,7 +2016,7 @@ status = RTA_SUCCESS; int ret = net_route_v6_add(ctx, &r6->network, r6->netbits, gateway_needed ? &r6->gateway : NULL, - device, 0, metric); + device, r6->table_id, metric); if (ret == -EEXIST) { msg(D_ROUTE, "NOTE: Linux route add command failed because route exists"); @@ -2227,7 +2236,7 @@ } if (net_route_v4_del(ctx, &r->network, netmask_to_netbits2(r->netmask), - &r->gateway, NULL, 0, metric) < 0) + &r->gateway, NULL, r->table_id, metric) < 0) { msg(M_WARN, "ERROR: Linux route delete command failed"); } @@ -2452,7 +2461,7 @@ } if (net_route_v6_del(ctx, &r6->network, r6->netbits, - gateway_needed ? &r6->gateway : NULL, device, 0, + gateway_needed ? &r6->gateway : NULL, device, r6->table_id, metric) < 0) { msg(M_WARN, "ERROR: Linux route v6 delete command failed"); diff --git a/src/openvpn/route.h b/src/openvpn/route.h index aa3114c..237375c 100644 --- a/src/openvpn/route.h +++ b/src/openvpn/route.h @@ -69,6 +69,7 @@ in_addr_t remote_host; int remote_host_local; /* TLA_x value */ struct route_bypass bypass; + int table_id; int default_metric; }; @@ -77,6 +78,7 @@ const char *network; const char *netmask; const char *gateway; + int table_id; const char *metric; }; @@ -101,6 +103,7 @@ const char *prefix; /* e.g. "2001:db8:1::/64" */ const char *gateway; /* e.g. "2001:db8:0::2" */ const char *metric; /* e.g. "5" */ + int table_id; }; struct route_ipv6_option_list { @@ -119,6 +122,7 @@ in_addr_t network; in_addr_t netmask; in_addr_t gateway; + int table_id; int metric; }; @@ -129,6 +133,7 @@ unsigned int netbits; struct in6_addr gateway; int metric; + int table_id; /* gateway interface */ #ifdef _WIN32 DWORD adapter_index; /* interface or ~0 if undefined */ @@ -290,12 +295,14 @@ const char *network, const char *netmask, const char *gateway, - const char *metric); + const char *metric, + int table_id); void add_route_ipv6_to_option_list(struct route_ipv6_option_list *l, const char *prefix, const char *gateway, - const char *metric); + const char *metric, + int table_id); bool init_route_list(struct route_list *rl, const struct route_option_list *opt, |