From patchwork Thu Feb 15 14:52:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "plaisthos (Code Review)" X-Patchwork-Id: 3618 Return-Path: Delivered-To: patchwork@openvpn.net Received: by 2002:a05:7000:a042:b0:554:adf7:68e6 with SMTP id bi2csp449171mab; Thu, 15 Feb 2024 06:53:39 -0800 (PST) X-Forwarded-Encrypted: i=2; AJvYcCU7C02dGLH6MDuubUJFHvp8WGIzx71qpZhkhgcNk6lhHwMezb51vtMlQO11jKyWFdfSgbmvDwXwJaBkCcskf374lj9PvDs= X-Google-Smtp-Source: AGHT+IHOyo7S65lvxtaKOH22PjFetQkelBo4ObOHZ/nfkfmjGB9plo9HEhN8FYC30A7Ar514nqES X-Received: by 2002:a05:6a00:9383:b0:6e0:e2f8:cf39 with SMTP id ka3-20020a056a00938300b006e0e2f8cf39mr2302280pfb.1.1708008819154; Thu, 15 Feb 2024 06:53:39 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1708008819; cv=none; d=google.com; s=arc-20160816; b=cZEUR1W5ZTRcBxPT7QFpsLk0gkW3cmLwtzCdI5uv2RBqrxXlC+jcFucjr1DgI+BN7q xEKh1EJmkB0rTCujX7hjH07JghWneqKb8HktoIgCWW/UX7NGrDiMpcwwB0TUiBfSGoih hTFmZ108hgJp40L4ItplB2pZXek3zuTLOTMgY9FgP7DZcL32XPQ5dUKDbLcJ6tM7GsCF 5uwBB8K/rA9yxW/z0jZJ927tT78YWLCeErbZG/MCBw4YMFhgt7FTH0GqH3PST7MMZDaQ TRAns3Zd4+1uPIvPgnjITEsIngDY1NhzMvHR588A62HycrO9CAWgMroJd9gCQyaeV30P M/uw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:cc:reply-to:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence:subject:user-agent :mime-version:message-id:references:auto-submitted:to:date:from :dkim-signature:dkim-signature:dkim-signature; bh=SkcI845CgBjUlJwMOxAkjn8LrIWe9WlK5/4yqdUjVQU=; fh=U7wEyxtwz2o5+UdevFSA47vNeG9knhWH0KV//QhD5a0=; b=cbZ1xud+Kodekx+pgXnb6LLJhlOgeNKvlV5BfEP+8+qzYCHXQc0S9K4j+rq317Ywkt VAqn5DseWHqqXxNHapJQN7odmrxHD+tKGJk8/lztvS8z0XOc2bBdwyRBguOGirjinnHs l5xKEyfymOTrpxLn3dJoMhIgIAE5hqxokhM5rS/Wu0wHv0uxAabu2fXKCKo/jNzdfki5 d8Qms5P2UjGKkYVWmrbjIylvGGR/DXKowT3/FquqzvgZOAQ7dqMiAs1nyi/yuhu4iiLR fHI1BpKGXC6jgQuh6+SR//mUIjVolq6F0JWqq9L/LWJrNkS/lhCF4babs4k7zB5iSs+k vRzw==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b="Dj//z6s9"; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b="a9c+SWN/"; dkim=neutral (body hash did not verify) header.i=@openvpn.net header.s=google header.b=CrxrVgTl; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=openvpn.net Received: from lists.sourceforge.net (lists.sourceforge.net. [216.105.38.7]) by mx.google.com with ESMTPS id w5-20020a636205000000b005dc87643cd1si1222355pgb.138.2024.02.15.06.53.38 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Thu, 15 Feb 2024 06:53:39 -0800 (PST) Received-SPF: pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) client-ip=216.105.38.7; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@sourceforge.net header.s=x header.b="Dj//z6s9"; dkim=neutral (body hash did not verify) header.i=@sf.net header.s=x header.b="a9c+SWN/"; dkim=neutral (body hash did not verify) header.i=@openvpn.net header.s=google header.b=CrxrVgTl; spf=pass (google.com: domain of openvpn-devel-bounces@lists.sourceforge.net designates 216.105.38.7 as permitted sender) smtp.mailfrom=openvpn-devel-bounces@lists.sourceforge.net; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=openvpn.net Received: from [127.0.0.1] (helo=sfs-ml-1.v29.lw.sourceforge.com) by sfs-ml-1.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1rad6i-0000Pp-Ve; Thu, 15 Feb 2024 14:53:01 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1rad6h-0000PZ-GU for openvpn-devel@lists.sourceforge.net; Thu, 15 Feb 2024 14:53:00 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Type:Content-Transfer-Encoding:MIME-Version :Message-ID:Reply-To:References:Subject:List-Unsubscribe:List-Id:Cc:To:Date: From:Sender:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:List-Help: List-Subscribe:List-Post:List-Owner:List-Archive; bh=PrkibM/4NF2woh41QBX5uzSDUmFMDOOstK4N6HYukHU=; b=Dj//z6s93k7VS/0hZU+M27NPur GgSqnC+XdS4fYb5q5r99hUjUN3NvtfZ5AA8r1pEzr8tUHnmxvz5Tz+8G+PHnB1pQNHsK6GYV/ZFeL itoyl7WXiqQbDmz894daMZDbJItExwksDoJ7I2hIiQ2ezuToQnWUvwJ4AKm4io1V/N/k=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Type:Content-Transfer-Encoding:MIME-Version:Message-ID:Reply-To: References:Subject:List-Unsubscribe:List-Id:Cc:To:Date:From:Sender:Content-ID :Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To: Resent-Cc:Resent-Message-ID:In-Reply-To:List-Help:List-Subscribe:List-Post: List-Owner:List-Archive; bh=PrkibM/4NF2woh41QBX5uzSDUmFMDOOstK4N6HYukHU=; b=a 9c+SWN/HmyXbThq0qLPOWPEGsnmaqpQ2+IQvHXQGVHAghWy+0h8DkSwlh3tId21WI+xLsADQdL045 WxHjVdmKemHChTKqJ8JEJGzCR0ntcYQGKBbPD9BU5OdmvNwhyVDX5w9JfXqG8aRz2M3kXpynNfc/7 k0AHxVTI5e/3PYfc=; Received: from mail-wm1-f42.google.com ([209.85.128.42]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.95) id 1rad6d-0006R4-KY for openvpn-devel@lists.sourceforge.net; Thu, 15 Feb 2024 14:52:59 +0000 Received: by mail-wm1-f42.google.com with SMTP id 5b1f17b1804b1-412078e983aso7628865e9.1 for ; Thu, 15 Feb 2024 06:52:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=openvpn.net; s=google; t=1708008764; x=1708613564; darn=lists.sourceforge.net; h=user-agent:content-disposition:content-transfer-encoding :mime-version:message-id:reply-to:references:subject :list-unsubscribe:list-id:auto-submitted:cc:to:date:from:from:to:cc :subject:date:message-id:reply-to; bh=PrkibM/4NF2woh41QBX5uzSDUmFMDOOstK4N6HYukHU=; b=CrxrVgTln4BnoY80XI6Xq9AzuzGBWr6GGZ6coiJ3KEqTxxjvOjPYT7x9DafZ9GJ/2K NYNP9HQ5pNX/89JXP1Y+BSIOBllrHxpToK0gzqRqZJ0sd+dCSN0h0Ilp15vjIriv53Ay BeL14N+6FJuwYhjgNCO11gHA4yOzvtE5sfXHDRl5ZEYycQfKiXuZwjN6tDolqM7fYJBL wkheV0jp58JQuhfL98o8UxvFPKymr9utIFKEQQ/NBj19WBkXrXqtv5wA0pHlh7QRG1on KRcd8uuCG1LkW6f3l4v/6m9eHKExHWwHFH/4WJZJ0aCI/iaXBa6YY1lr88uWmhL/RI7t SiXg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1708008764; x=1708613564; h=user-agent:content-disposition:content-transfer-encoding :mime-version:message-id:reply-to:references:subject :list-unsubscribe:list-id:auto-submitted:cc:to:date:from :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=PrkibM/4NF2woh41QBX5uzSDUmFMDOOstK4N6HYukHU=; b=aityuwqe4bHATfChDPHXELOaza2n6JJ42P9f5/pRAvo8S9BKBw89c58zuMGZYTHht8 kUkq6TAR6+fpF40blOsL30KRrv86cMONn9DqsM+fvkO7Vh9Enu7A4Lleohg7RIlgRG2F g1amiTfs6UiXiF8FelZI8dBg/AZ4b1Sr/pKcFHya11EYt9gCWf2bCD7cRFW+4QMyBwM1 SSchycz2TsIWFGDmGOR0KwKtBcp6g0+KwXS3mOVsTjzNGfPxnv8Qxy524KjAdEuQiXpB cha8R4iMgS/NdcNd31c5pO/KgBzVdZPK/XIUT3k2rDZNAo2MKTMmTwvrFUmSSsSZS+xD HkMQ== X-Gm-Message-State: AOJu0YxrQTcHFm+xA3AyntKGKYHn8TPqOsSLlWyv65qM8dhoKmjV62GU hfrge9YQMjjE4B2kziv2ZNPl0zBkUoLjBLvKFH850ICjShRDvxbEgQLzheOPxeI= X-Received: by 2002:a5d:6dad:0:b0:33b:75d0:9b4b with SMTP id u13-20020a5d6dad000000b0033b75d09b4bmr1983386wrs.50.1708008763529; Thu, 15 Feb 2024 06:52:43 -0800 (PST) Received: from gerrit.openvpn.in (ec2-18-159-0-78.eu-central-1.compute.amazonaws.com. [18.159.0.78]) by smtp.gmail.com with ESMTPSA id e30-20020a5d595e000000b0033b2276e71csm1977137wri.62.2024.02.15.06.52.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 15 Feb 2024 06:52:42 -0800 (PST) From: "its_Giaan (Code Review)" X-Google-Original-From: "its_Giaan (Code Review)" X-Gerrit-PatchSet: 1 Date: Thu, 15 Feb 2024 14:52:42 +0000 To: plaisthos , flichtenheld Auto-Submitted: auto-generated X-Gerrit-MessageType: newchange X-Gerrit-Change-Id: I3e4ebef484d2a04a383a65ede5617ee98bf218a7 X-Gerrit-Change-Number: 524 X-Gerrit-Project: openvpn X-Gerrit-ChangeURL: X-Gerrit-Commit: 29e2c24f556de8e0c83907ba483ee2af149514e6 References: Message-ID: <8738adedc06e1ff9a2cabed71838bf35bcb92068-HTML@gerrit.openvpn.net> MIME-Version: 1.0 User-Agent: Gerrit/3.8.2 X-Spam-Score: -0.2 (/) X-Spam-Report: Spam detection software, running on the system "util-spamd-1.v13.lw.sourceforge.com", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: Attention is currently required from: flichtenheld, plaisthos. Hello plaisthos, flichtenheld, I'd like you to do a code review. Please visit Content analysis details: (-0.2 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.128.42 listed in wl.mailspike.net] -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [209.85.128.42 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record 0.0 WEIRD_PORT URI: Uses non-standard port number for HTTP 0.0 HTML_MESSAGE BODY: HTML included in message 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.0 T_KAM_HTML_FONT_INVALID Test for Invalidly Named or Formatted Colors in HTML -0.0 T_SCC_BODY_TEXT_LINE No description available. X-Headers-End: 1rad6d-0006R4-KY Subject: [Openvpn-devel] [M] Change in openvpn[master]: Route: add support for user defined routing table X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: gianmarco@mandelbit.com, arne-openvpn@rfc2549.org, openvpn-devel@lists.sourceforge.net, frank@lichtenheld.com Cc: openvpn-devel Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox X-GMAIL-THRID: =?utf-8?q?1790977055299257940?= X-GMAIL-MSGID: =?utf-8?q?1790977055299257940?= X-getmail-filter-classifier: gerrit message type newchange 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 --- 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);