From patchwork Tue Sep 8 02:36:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladislav Grishenko X-Patchwork-Id: 1423 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director7.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id KLx9Gzl7V184PQAAIUCqbw (envelope-from ) for ; Tue, 08 Sep 2020 08:38:17 -0400 Received: from proxy5.mail.ord1d.rsapps.net ([172.30.191.6]) by director7.mail.ord1d.rsapps.net with LMTP id kA09Gzl7V18lGQAAovjBpQ (envelope-from ) for ; Tue, 08 Sep 2020 08:38:17 -0400 Received: from smtp8.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy5.mail.ord1d.rsapps.net with LMTPS id KFwQGzl7V19bPgAA8Zzt7w (envelope-from ) for ; Tue, 08 Sep 2020 08:38:17 -0400 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp8.gate.ord1d.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dkim=fail (signature verification failed) header.d=yandex-team.ru; dmarc=fail (p=none; dis=none) header.from=yandex-team.ru X-Suspicious-Flag: YES X-Classification-ID: 2aa3a718-f1d0-11ea-ab64-5254001e5a60-1-1 Received: from [216.105.38.7] ([216.105.38.7:59896] helo=lists.sourceforge.net) by smtp8.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id FD/87-32677-83B775F5; Tue, 08 Sep 2020 08:38:16 -0400 Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1kFcrt-0004C0-V0; Tue, 08 Sep 2020 12:37:01 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kFcrs-0004Bj-KT for openvpn-devel@lists.sourceforge.net; Tue, 08 Sep 2020 12:37:00 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=References:In-Reply-To:Message-Id:Date:Subject:To: From:Sender:Reply-To:Cc:MIME-Version:Content-Type:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=oVHtdjg6XurNnZ6rrRRvBB8SO1315sItvBLhxksm0YY=; b=EBmpceLFR2+ntl9tfDbk2Zh73r TP43P4zk6URSRrAEYG1fW8+dI73LwODfk0tpz0+ny/9FsNVIx+y3afPlbgtg+sa5ds21sZszSzt1Z pLHndfwUb6nxus1vWjSWViSXMZKmAh7zi1l+kwjKCezKQypa97IVXrvjeCqWLz6WqAdM=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=References:In-Reply-To:Message-Id:Date:Subject:To:From:Sender:Reply-To:Cc :MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=oVHtdjg6XurNnZ6rrRRvBB8SO1315sItvBLhxksm0YY=; b=OPFvPLWBQ6/Chax1dESobO7r06 cxGlCH9x1q9fvy5TG+OSVsiHtFZ0YkNXgTeeyv3SkP7R3A0quEBhBrdXmqbDEP5uL28bC1KxMoEwp NbL8vzjaDAxJYHmL9zUiNOH32hfeZ58wnuXMWpLdMoLs8asp66V47bg3Ak21KCtP/qN4=; Received: from forwardcorp1o.mail.yandex.net ([95.108.205.193]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1kFcre-00Gmyr-M7 for openvpn-devel@lists.sourceforge.net; Tue, 08 Sep 2020 12:37:00 +0000 Received: from iva8-d077482f1536.qloud-c.yandex.net (iva8-d077482f1536.qloud-c.yandex.net [IPv6:2a02:6b8:c0c:2f26:0:640:d077:482f]) by forwardcorp1o.mail.yandex.net (Yandex) with ESMTP id 4F51B2E0993 for ; Tue, 8 Sep 2020 15:36:35 +0300 (MSK) Received: from iva4-7c3d9abce76c.qloud-c.yandex.net (iva4-7c3d9abce76c.qloud-c.yandex.net [2a02:6b8:c0c:4e8e:0:640:7c3d:9abc]) by iva8-d077482f1536.qloud-c.yandex.net (mxbackcorp/Yandex) with ESMTP id OZiLSbmbDS-aZw0RVVc; Tue, 08 Sep 2020 15:36:35 +0300 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.ru; s=default; t=1599568595; bh=oVHtdjg6XurNnZ6rrRRvBB8SO1315sItvBLhxksm0YY=; h=In-Reply-To:Message-Id:References:Date:Subject:To:From; b=Q8TiTwak3uiO56lHMh6h8TwxF3GlmMkfEEuRJwFy6qvjaD4R4F5auC55/DQgMBMoQ 3lZbLJq647LD3WheMKY48GGFLL1M7nU11Zzwf0H20omSOVjGZkgeQfxPP3jbpmM68s mD3legK5TwYAF4UF0TPtTOVGc/YoU1d79zbNfj9k= Received: from unknown (unknown [178.154.185.136]) by iva4-7c3d9abce76c.qloud-c.yandex.net (smtpcorp/Yandex) with ESMTPSA id a6FbleKstx-aZmSTa7n; Tue, 08 Sep 2020 15:36:35 +0300 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (Client certificate not present) From: Vladislav Grishenko To: openvpn-devel@lists.sourceforge.net Date: Tue, 8 Sep 2020 17:36:25 +0500 Message-Id: <20200908123625.23179-1-themiron@yandex-team.ru> X-Mailer: git-send-email 2.17.1 In-Reply-To: <011701d6858cyandex-team.ru> References: <011701d6858cyandex-team.ru> X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-Headers-End: 1kFcre-00Gmyr-M7 Subject: [Openvpn-devel] [PATCH v3] Fix best gateway selection over netlink 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: , MIME-Version: 1.0 Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox Netlink route request with NLM_F_DUMP flag set means to return all entries matching criteria passed in message content - matching supplied family & dst address in our case. So, gateway from the first ipv4 route was always used. On kernels earlier than 2.6.38 default routes are the last ones, so arbitrary host/net route w/o gateway is likely be returned as first, causing gateway to be invalid or empty. After refactoring in 2.6.38 kernel default routes are on top, so the problem with older kernels was hidden. Fix this behavior by selecting first 0.0.0.0/0 if dst was not set or empty. For IPv6, no behavior is changed - request ::/128 route, so just clarify the sizes via netlink route api. Tested on 5.4.0, 4.1.51, 2.6.36 and 2.6.22 kernels. Signed-off-by: Vladislav Grishenko Acked-by: Antonio Quartulli --- doc/man-sections/advanced-options.rst | 7 +++-- src/openvpn/networking_sitnl.c | 44 ++++++++++++++++++++++++--- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/doc/man-sections/advanced-options.rst b/doc/man-sections/advanced-options.rst index 9b96e406..bedc8841 100644 --- a/doc/man-sections/advanced-options.rst +++ b/doc/man-sections/advanced-options.rst @@ -11,8 +11,11 @@ Standalone Debug Options --show-gateway --show-gateway IPv6-target - If an IPv6 target address is passed as argument, the IPv6 route for this - host is reported. + For IPv6 this queries the route towards ::/128, or the specified IPv6 + target address if passed as argument. + For IPv4 on Linux, Windows, MacOS and BSD it looks for a 0.0.0.0/0 route. + If there are more specific routes, the result will not always be matching + the route of the IPv4 packets to the VPN gateway. Advanced Expert Options diff --git a/src/openvpn/networking_sitnl.c b/src/openvpn/networking_sitnl.c index 713a213a..2bc70a50 100644 --- a/src/openvpn/networking_sitnl.c +++ b/src/openvpn/networking_sitnl.c @@ -345,6 +345,13 @@ sitnl_send(struct nlmsghdr *payload, pid_t peer, unsigned int groups, * continue; * } */ + + if (h->nlmsg_type == NLMSG_DONE) + { + ret = 0; + goto out; + } + if (h->nlmsg_type == NLMSG_ERROR) { err = (struct nlmsgerr *)NLMSG_DATA(h); @@ -360,7 +367,11 @@ sitnl_send(struct nlmsghdr *payload, pid_t peer, unsigned int groups, ret = 0; if (cb) { - ret = cb(h, arg_cb); + int r = cb(h, arg_cb); + if (r <= 0) + { + ret = r; + } } } else @@ -375,8 +386,12 @@ sitnl_send(struct nlmsghdr *payload, pid_t peer, unsigned int groups, if (cb) { - ret = cb(h, arg_cb); - goto out; + int r = cb(h, arg_cb); + if (r <= 0) + { + ret = r; + goto out; + } } else { @@ -410,6 +425,7 @@ typedef struct { int addr_size; inet_address_t gw; char iface[IFNAMSIZ]; + bool default_only; } route_res_t; static int @@ -421,6 +437,12 @@ sitnl_route_save(struct nlmsghdr *n, void *arg) int len = n->nlmsg_len - NLMSG_LENGTH(sizeof(*r)); unsigned int ifindex = 0; + /* filter-out non-zero dst prefixes */ + if (res->default_only && r->rtm_dst_len != 0) + { + return 1; + } + while (RTA_OK(rta, len)) { switch (rta->rta_type) @@ -477,11 +499,25 @@ sitnl_route_best_gw(sa_family_t af_family, const inet_address_t *dst, { case AF_INET: res.addr_size = sizeof(in_addr_t); - req.n.nlmsg_flags |= NLM_F_DUMP; + /* + * kernel can't return 0.0.0.0/8 host route, dump all + * the routes and filter for 0.0.0.0/0 in cb() + */ + if (!dst || !dst->ipv4) + { + req.n.nlmsg_flags |= NLM_F_DUMP; + res.default_only = true; + } + else + { + req.r.rtm_dst_len = 32; + } break; case AF_INET6: res.addr_size = sizeof(struct in6_addr); + /* kernel can return ::/128 host route */ + req.r.rtm_dst_len = 128; break; default: