| Message ID | 20210416120708.1532-1-themiron@yandex-team.ru |
|---|---|
| State | Accepted |
| Headers |
Return-Path: <openvpn-devel-bounces@lists.sourceforge.net> Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director8.mail.ord1d.rsapps.net ([172.27.255.59]) by backend30.mail.ord1d.rsapps.net with LMTP id 6IdmFUV+eWANQwAAIUCqbw (envelope-from <openvpn-devel-bounces@lists.sourceforge.net>) for <patchwork@openvpn.net>; Fri, 16 Apr 2021 08:08:37 -0400 Received: from proxy5.mail.iad3a.rsapps.net ([172.27.255.59]) by director8.mail.ord1d.rsapps.net with LMTP id 6I87FUV+eWAjPQAAfY0hYg (envelope-from <openvpn-devel-bounces@lists.sourceforge.net>) for <patchwork@openvpn.net>; Fri, 16 Apr 2021 08:08:37 -0400 Received: from smtp11.gate.iad3a ([172.27.255.59]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy5.mail.iad3a.rsapps.net with LMTPS id MAk7DkV+eWBUSQAAhn5joQ (envelope-from <openvpn-devel-bounces@lists.sourceforge.net>) for <patchwork@openvpn.net>; Fri, 16 Apr 2021 08:08:37 -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: smtp11.gate.iad3a.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: 7823c5ac-9eac-11eb-81ed-5254005eb44a-1-1 Received: from [216.105.38.7] ([216.105.38.7:41808] helo=lists.sourceforge.net) by smtp11.gate.iad3a.rsapps.net (envelope-from <openvpn-devel-bounces@lists.sourceforge.net>) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 61/DD-02931-34E79706; Fri, 16 Apr 2021 08:08:36 -0400 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.90_1) (envelope-from <openvpn-devel-bounces@lists.sourceforge.net>) id 1lXNGB-0003eW-Fa; Fri, 16 Apr 2021 12:07:43 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from <themiron@yandex-team.ru>) id 1lXNG4-0003b7-Si for openvpn-devel@lists.sourceforge.net; Fri, 16 Apr 2021 12:07:36 +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=b6n+IvNlpXiSsrpt7gFbGRXJUhLPBiJiq5hg5Ebrt1A=; b=YFXYNY0JiMoqSoJWnScfX40yXw l4V4+vvgo0Xouthaw059jPevUlF1udn4DA99ZSCqJzW8t0rWqFWBAbcn48UbDNp9CLIySOvaTGoKC zi7z/xXWYhna0lo+mniX/nQmIKMcsZ6m7M5/v9da23rENU5/7sR18rRPKfgp1QdVMiKY=; 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=b6n+IvNlpXiSsrpt7gFbGRXJUhLPBiJiq5hg5Ebrt1A=; b=ZRqO+1I6YBzFLpIM4NcUBnQDI1 p4iSNdrxJrV9yaKymFlbs1mpeKnoYn9lNOj1VBQt7tog/U0p/MPnLtEQSppQahnoh0RDiZmKlUGWh KiC03KoRF1arZ4Lj+24M+z8LqKwbmKBf6KGIZH01z9xHejBpJxLUp5GK0nML7THf0Am0=; Received: from forwardcorp1j.mail.yandex.net ([5.45.199.163]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.3) id 1lXNFx-0004MV-Sh for openvpn-devel@lists.sourceforge.net; Fri, 16 Apr 2021 12:07:36 +0000 Received: from myt5-23f0be3aa648.qloud-c.yandex.net (myt5-23f0be3aa648.qloud-c.yandex.net [IPv6:2a02:6b8:c12:3e29:0:640:23f0:be3a]) by forwardcorp1j.mail.yandex.net (Yandex) with ESMTP id B6E062E1709 for <openvpn-devel@lists.sourceforge.net>; Fri, 16 Apr 2021 15:07:17 +0300 (MSK) Received: from myt6-76f0a6db1a7e.qloud-c.yandex.net (myt6-76f0a6db1a7e.qloud-c.yandex.net [2a02:6b8:c12:422d:0:640:76f0:a6db]) by myt5-23f0be3aa648.qloud-c.yandex.net (mxbackcorp/Yandex) with ESMTP id 65ly9VXjFz-7H0W4uX5; Fri, 16 Apr 2021 15:07:17 +0300 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex-team.ru; s=default; t=1618574837; bh=b6n+IvNlpXiSsrpt7gFbGRXJUhLPBiJiq5hg5Ebrt1A=; h=Message-Id:References:Date:Subject:To:From:In-Reply-To; b=XNCIcULNKSHtsgviHj252e09nFa1Ds73BKX0sizYBIGWNghVqX9tRPsHa9MrYwXFe I7xYK1NhWvGSMpgY3p6yN8P4iydffcJHkdqMTtyQ5ChgTUKnKn1mHESRKwhD35qWWf kDi7V8l8UePOGFpkbMxNdPSTAlMPTPvsHKuU0C5s= Received: from 178.154.162.245-vpn.dhcp.yndx.net (178.154.162.245-vpn.dhcp.yndx.net [178.154.162.245]) by myt6-76f0a6db1a7e.qloud-c.yandex.net (smtpcorp/Yandex) with ESMTPSA id rvb0JLZksa-7Ho0gIaX; Fri, 16 Apr 2021 15:07:17 +0300 (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (Client certificate not present) From: Vladislav Grishenko <themiron@yandex-team.ru> To: openvpn-devel@lists.sourceforge.net Date: Fri, 16 Apr 2021 17:07:07 +0500 Message-Id: <20210416120708.1532-1-themiron@yandex-team.ru> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210415230545.22317-1-themiron@yandex-team.ru> References: <20210415230545.22317-1-themiron@yandex-team.ru> X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. 0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [URIs: yandex-team.ru] -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: 1lXNFx-0004MV-Sh Subject: [Openvpn-devel] [PATCH v3 1/2] Fix IPv4 default gateway with multiple route tables X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: <openvpn-devel.lists.sourceforge.net> List-Unsubscribe: <https://lists.sourceforge.net/lists/options/openvpn-devel>, <mailto:openvpn-devel-request@lists.sourceforge.net?subject=unsubscribe> List-Archive: <http://sourceforge.net/mailarchive/forum.php?forum_name=openvpn-devel> List-Post: <mailto:openvpn-devel@lists.sourceforge.net> List-Help: <mailto:openvpn-devel-request@lists.sourceforge.net?subject=help> List-Subscribe: <https://lists.sourceforge.net/lists/listinfo/openvpn-devel>, <mailto:openvpn-devel-request@lists.sourceforge.net?subject=subscribe> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox |
| Series |
[Openvpn-devel,v3,1/2] Fix IPv4 default gateway with multiple route tables
|
|
Commit Message
Vladislav Grishenko
April 16, 2021, 2:07 a.m. UTC
Current default gateway selection for zero destination address just
dumps and parses all the routing tables. If any of non-main table
with default route comes first, wrong default gateway can be picked.
Since adding/removing routes currently handles only main table,
let's stick to RT_TABLE_MAIN while selecting default route too.
v2: keep gateway address unchanged on lookup error
v3: reduce ammout of gateway address copying
Reported-by: Donald Sharp <donaldsharp72@gmail.com>
Signed-off-by: Vladislav Grishenko <themiron@yandex-team.ru>
---
src/openvpn/networking_sitnl.c | 26 ++++++++++++++++++++++++--
1 file changed, 24 insertions(+), 2 deletions(-)
Comments
Hi, On 16/04/2021 14:07, Vladislav Grishenko wrote: > Current default gateway selection for zero destination address just > dumps and parses all the routing tables. If any of non-main table > with default route comes first, wrong default gateway can be picked. > Since adding/removing routes currently handles only main table, > let's stick to RT_TABLE_MAIN while selecting default route too. > > v2: keep gateway address unchanged on lookup error > v3: reduce ammout of gateway address copying > > Reported-by: Donald Sharp <donaldsharp72@gmail.com> > Signed-off-by: Vladislav Grishenko <themiron@yandex-team.ru> > --- > src/openvpn/networking_sitnl.c | 26 ++++++++++++++++++++++++-- > 1 file changed, 24 insertions(+), 2 deletions(-) > > diff --git a/src/openvpn/networking_sitnl.c b/src/openvpn/networking_sitnl.c > index 2bc70a50..ea1621ed 100644 > --- a/src/openvpn/networking_sitnl.c > +++ b/src/openvpn/networking_sitnl.c > @@ -426,6 +426,7 @@ typedef struct { > inet_address_t gw; > char iface[IFNAMSIZ]; > bool default_only; > + unsigned int table; > } route_res_t; > > static int > @@ -435,7 +436,8 @@ sitnl_route_save(struct nlmsghdr *n, void *arg) > struct rtmsg *r = NLMSG_DATA(n); > struct rtattr *rta = RTM_RTA(r); > int len = n->nlmsg_len - NLMSG_LENGTH(sizeof(*r)); > - unsigned int ifindex = 0; > + unsigned int table, ifindex = 0; > + void *gw = NULL; > > /* filter-out non-zero dst prefixes */ > if (res->default_only && r->rtm_dst_len != 0) > @@ -443,6 +445,9 @@ sitnl_route_save(struct nlmsghdr *n, void *arg) > return 1; > } > > + /* route table, ignored with RTA_TABLE */ > + table = r->rtm_table; > + > while (RTA_OK(rta, len)) > { > switch (rta->rta_type) > @@ -458,13 +463,24 @@ sitnl_route_save(struct nlmsghdr *n, void *arg) > > /* GW for the route */ > case RTA_GATEWAY: > - memcpy(&res->gw, RTA_DATA(rta), res->addr_size); > + gw = RTA_DATA(rta); > + break; > + > + /* route table */ > + case RTA_TABLE: > + table = *(unsigned int *)RTA_DATA(rta); > break; > } > > rta = RTA_NEXT(rta, len); > } > > + /* filter out any route not coming from the selected table */ > + if (res->table && res->table != table) Today I was wondering if 0 could be a meaningful table ID, since this code uses 0 as "no table was selected for filtering" (thus creating a false negative). After checking rtnetlink.h, I could see that 0 is indeed the UNSPEC value (RT_TABLE_UNSPEC=0), therefore your patch is correct. However, to prevent the next casual reader from asking the same question, wouldn't it make sense to change this comparison with: if (res->table != RT_TABLE_UNSPEC && res->table != table) > + { > + return 1; > + } > + > if (!if_indextoname(ifindex, res->iface)) > { > msg(M_WARN | M_ERRNO, "%s: rtnl: can't get ifname for index %d", > @@ -472,6 +488,11 @@ sitnl_route_save(struct nlmsghdr *n, void *arg) > return -1; > } > > + if (gw) > + { > + memcpy(&res->gw, gw, res->addr_size); > + } > + > return 0; > } > > @@ -507,6 +528,7 @@ sitnl_route_best_gw(sa_family_t af_family, const inet_address_t *dst, > { > req.n.nlmsg_flags |= NLM_F_DUMP; > res.default_only = true; > + res.table = RT_TABLE_MAIN; Another question: why restricting the research to the MAIN table only for IPv4 and only when searching a default route? Like you said in the commit message: OpenVPN only operates on the MAIN routing table for the time being, therefore, shouldn't we just set "res.table = RT_TABLE_MAIN" by default *all the time* for now? Otherwise we are fixing this problem only for the ipv4/default search, but the function remains "buggy" for the other cases. > } > else > { > Regards,
Hi, > However, to prevent the next casual reader from asking the same question, > wouldn't it make sense to change this comparison with: > > if (res->table != RT_TABLE_UNSPEC && res->table != table) I don’t think it's necessary for following reasons: 1. Readability. "if (res->table)" reads as "if filter table is set ". Changing it to "if (res->table != RT_TABLE_UNSPEC)" gives the same reading imho. 2. RT_TABLE_UNSPEC was and will be always zero, because zillion of software incl. iproute2 depends on zeroed structs with 0 == UNSPEC 3. Comparing with RT_TABLE_UNSPEC here will require additional code to explicitely init res.table with RT_TABLE_UNSPEC, which in fact is will be noop after CLEAR(res) and have little sense, since there's no chance to have RT_TABLE_UNSPEC != 0. Anyway, if you still thinks it's required, I can do change. > Another question: why restricting the research to the MAIN table only for IPv4 > and only when searching a default route? For real dst, incl ::/128 we do the right thing - perform "ip route get" that will get real gateway for specified dst no matter what table or anything else is. And we performs "ip route show" dump only to get gateway for "0.0.0.0" destination by a reason. Getting default gateway for "0.0.0.0/0" destination is not logically possible at all, for example what is default gateway for this case: 0.0.0.0/1 via a.a.a.a 128.0.0.0/1 via b.b.b.b Therefore for 0.0.0.0/0 case heuristic is used, if there's a default route, if it's in main table and so on, that’s why only dumping needs it. Any other - don't. > Otherwise we are fixing this problem only for the ipv4/default search, but the > function remains "buggy" for the other cases. Buggy here is searching default gateway for 0.0.0.0/0 itself. Other cases are right from the scratch :) -- Best Regards, Vladislav Grishenko > -----Original Message----- > From: Antonio Quartulli <a@unstable.cc> > Sent: Friday, April 16, 2021 7:01 PM > To: Vladislav Grishenko <themiron@yandex-team.ru>; openvpn- > devel@lists.sourceforge.net > Subject: Re: [Openvpn-devel] [PATCH v3 1/2] Fix IPv4 default gateway with > multiple route tables > > Hi, > > On 16/04/2021 14:07, Vladislav Grishenko wrote: > > Current default gateway selection for zero destination address just > > dumps and parses all the routing tables. If any of non-main table with > > default route comes first, wrong default gateway can be picked. > > Since adding/removing routes currently handles only main table, let's > > stick to RT_TABLE_MAIN while selecting default route too. > > > > v2: keep gateway address unchanged on lookup error > > v3: reduce ammout of gateway address copying > > > > Reported-by: Donald Sharp <donaldsharp72@gmail.com> > > Signed-off-by: Vladislav Grishenko <themiron@yandex-team.ru> > > --- > > src/openvpn/networking_sitnl.c | 26 ++++++++++++++++++++++++-- > > 1 file changed, 24 insertions(+), 2 deletions(-) > > > > diff --git a/src/openvpn/networking_sitnl.c > > b/src/openvpn/networking_sitnl.c index 2bc70a50..ea1621ed 100644 > > --- a/src/openvpn/networking_sitnl.c > > +++ b/src/openvpn/networking_sitnl.c > > @@ -426,6 +426,7 @@ typedef struct { > > inet_address_t gw; > > char iface[IFNAMSIZ]; > > bool default_only; > > + unsigned int table; > > } route_res_t; > > > > static int > > @@ -435,7 +436,8 @@ sitnl_route_save(struct nlmsghdr *n, void *arg) > > struct rtmsg *r = NLMSG_DATA(n); > > struct rtattr *rta = RTM_RTA(r); > > int len = n->nlmsg_len - NLMSG_LENGTH(sizeof(*r)); > > - unsigned int ifindex = 0; > > + unsigned int table, ifindex = 0; > > + void *gw = NULL; > > > > /* filter-out non-zero dst prefixes */ > > if (res->default_only && r->rtm_dst_len != 0) @@ -443,6 +445,9 @@ > > sitnl_route_save(struct nlmsghdr *n, void *arg) > > return 1; > > } > > > > + /* route table, ignored with RTA_TABLE */ > > + table = r->rtm_table; > > + > > while (RTA_OK(rta, len)) > > { > > switch (rta->rta_type) > > @@ -458,13 +463,24 @@ sitnl_route_save(struct nlmsghdr *n, void *arg) > > > > /* GW for the route */ > > case RTA_GATEWAY: > > - memcpy(&res->gw, RTA_DATA(rta), res->addr_size); > > + gw = RTA_DATA(rta); > > + break; > > + > > + /* route table */ > > + case RTA_TABLE: > > + table = *(unsigned int *)RTA_DATA(rta); > > break; > > } > > > > rta = RTA_NEXT(rta, len); > > } > > > > + /* filter out any route not coming from the selected table */ > > + if (res->table && res->table != table) > > Today I was wondering if 0 could be a meaningful table ID, since this code uses 0 > as "no table was selected for filtering" (thus creating a false negative). > > After checking rtnetlink.h, I could see that 0 is indeed the UNSPEC value > (RT_TABLE_UNSPEC=0), therefore your patch is correct. > > However, to prevent the next casual reader from asking the same question, > wouldn't it make sense to change this comparison with: > > if (res->table != RT_TABLE_UNSPEC && res->table != table) > > > > + { > > + return 1; > > + } > > + > > if (!if_indextoname(ifindex, res->iface)) > > { > > msg(M_WARN | M_ERRNO, "%s: rtnl: can't get ifname for index > > %d", @@ -472,6 +488,11 @@ sitnl_route_save(struct nlmsghdr *n, void *arg) > > return -1; > > } > > > > + if (gw) > > + { > > + memcpy(&res->gw, gw, res->addr_size); > > + } > > + > > return 0; > > } > > > > @@ -507,6 +528,7 @@ sitnl_route_best_gw(sa_family_t af_family, const > inet_address_t *dst, > > { > > req.n.nlmsg_flags |= NLM_F_DUMP; > > res.default_only = true; > > + res.table = RT_TABLE_MAIN; > > Another question: why restricting the research to the MAIN table only for IPv4 > and only when searching a default route? > > Like you said in the commit message: OpenVPN only operates on the MAIN > routing table for the time being, therefore, shouldn't we just set "res.table = > RT_TABLE_MAIN" by default *all the time* for now? > > Otherwise we are fixing this problem only for the ipv4/default search, but the > function remains "buggy" for the other cases. > > > > } > > else > > { > > > > > Regards, > > -- > Antonio Quartulli
Hi, On 16/04/2021 16:43, Vladislav Grishenko wrote: > Hi, > >> However, to prevent the next casual reader from asking the same question, >> wouldn't it make sense to change this comparison with: >> >> if (res->table != RT_TABLE_UNSPEC && res->table != table) > > I don’t think it's necessary for following reasons: > 1. Readability. "if (res->table)" reads as "if filter table is set ". Changing it to "if (res->table != RT_TABLE_UNSPEC)" gives the same reading imho. > 2. RT_TABLE_UNSPEC was and will be always zero, because zillion of software incl. iproute2 depends on zeroed structs with 0 == UNSPEC > 3. Comparing with RT_TABLE_UNSPEC here will require additional code to explicitely init res.table with RT_TABLE_UNSPEC, which in fact is will be noop after CLEAR(res) and have little sense, since there's no chance to have RT_TABLE_UNSPEC != 0. > Anyway, if you still thinks it's required, I can do change. No, it's ok. You are right that 0 is just assumed to be the UNSPEC filter (i.e. don't filter). Let's keep it as it is. > >> Another question: why restricting the research to the MAIN table only for IPv4 >> and only when searching a default route? > > For real dst, incl ::/128 we do the right thing - perform "ip route get" that will get real gateway for specified dst no matter what table or anything else is. > And we performs "ip route show" dump only to get gateway for "0.0.0.0" destination by a reason. > Getting default gateway for "0.0.0.0/0" destination is not logically possible at all, for example what is default gateway for this case: > 0.0.0.0/1 via a.a.a.a > 128.0.0.0/1 via b.b.b.b > Therefore for 0.0.0.0/0 case heuristic is used, if there's a default route, if it's in main table and so on, that’s why only dumping needs it. > Any other - don't. > >> Otherwise we are fixing this problem only for the ipv4/default search, but the >> function remains "buggy" for the other cases. > > Buggy here is searching default gateway for 0.0.0.0/0 itself. Other cases are right from the scratch :) > Right. The problem I was seeing is simply that we are not providing all info to the kernel as we should. This requires further improvement later, but not as part of this fix :-) So the patch is fine as it is, thanks! Acked-by: Antonio Quartulli <antonio@openvpn.net> @Gert: this should go to 2.5 too. Thanks! Regards,
Code looks reasonable (though I won't claim to understand the nuances
of Netlink :-) ) - took me a bit to remember what is done here with
the callback function for matching, but yeah, seems to do what it says
on the lid. Did some very basic testing on a system with just a single
route table and nothing breaks :-)
Your patch has been applied to the master and release/2.5 branch (bugfix).
commit c7f95891a4a0aabb64e7d4f3200525c1a2fcf433 (master)
commit 48ba0b059138dec7a94d2368375344d39c4e05e9 (release/2.5)
Author: Vladislav Grishenko
Date: Fri Apr 16 17:07:07 2021 +0500
Fix IPv4 default gateway with multiple route tables
Signed-off-by: Vladislav Grishenko <themiron@yandex-team.ru>
Acked-by: Antonio Quartulli <antonio@openvpn.net>
Message-Id: <20210416120708.1532-1-themiron@yandex-team.ru>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg22130.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
--
kind regards,
Gert Doering
diff --git a/src/openvpn/networking_sitnl.c b/src/openvpn/networking_sitnl.c index 2bc70a50..ea1621ed 100644 --- a/src/openvpn/networking_sitnl.c +++ b/src/openvpn/networking_sitnl.c @@ -426,6 +426,7 @@ typedef struct { inet_address_t gw; char iface[IFNAMSIZ]; bool default_only; + unsigned int table; } route_res_t; static int @@ -435,7 +436,8 @@ sitnl_route_save(struct nlmsghdr *n, void *arg) struct rtmsg *r = NLMSG_DATA(n); struct rtattr *rta = RTM_RTA(r); int len = n->nlmsg_len - NLMSG_LENGTH(sizeof(*r)); - unsigned int ifindex = 0; + unsigned int table, ifindex = 0; + void *gw = NULL; /* filter-out non-zero dst prefixes */ if (res->default_only && r->rtm_dst_len != 0) @@ -443,6 +445,9 @@ sitnl_route_save(struct nlmsghdr *n, void *arg) return 1; } + /* route table, ignored with RTA_TABLE */ + table = r->rtm_table; + while (RTA_OK(rta, len)) { switch (rta->rta_type) @@ -458,13 +463,24 @@ sitnl_route_save(struct nlmsghdr *n, void *arg) /* GW for the route */ case RTA_GATEWAY: - memcpy(&res->gw, RTA_DATA(rta), res->addr_size); + gw = RTA_DATA(rta); + break; + + /* route table */ + case RTA_TABLE: + table = *(unsigned int *)RTA_DATA(rta); break; } rta = RTA_NEXT(rta, len); } + /* filter out any route not coming from the selected table */ + if (res->table && res->table != table) + { + return 1; + } + if (!if_indextoname(ifindex, res->iface)) { msg(M_WARN | M_ERRNO, "%s: rtnl: can't get ifname for index %d", @@ -472,6 +488,11 @@ sitnl_route_save(struct nlmsghdr *n, void *arg) return -1; } + if (gw) + { + memcpy(&res->gw, gw, res->addr_size); + } + return 0; } @@ -507,6 +528,7 @@ sitnl_route_best_gw(sa_family_t af_family, const inet_address_t *dst, { req.n.nlmsg_flags |= NLM_F_DUMP; res.default_only = true; + res.table = RT_TABLE_MAIN; } else {