From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-23.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,MENTIONS_GIT_HOSTING,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EB665C2B9F4 for ; Tue, 22 Jun 2021 15:03:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CF711611CE for ; Tue, 22 Jun 2021 15:03:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232058AbhFVPFx (ORCPT ); Tue, 22 Jun 2021 11:05:53 -0400 Received: from relay.sw.ru ([185.231.240.75]:36996 "EHLO relay.sw.ru" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232041AbhFVPFw (ORCPT ); Tue, 22 Jun 2021 11:05:52 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=virtuozzo.com; s=relay; h=MIME-Version:Message-Id:Date:Subject:From: Content-Type; bh=LHN/A6/uHngVCHbpw/dXJ0ZtSnqexhxmHe2KDAmFumo=; b=kzP65ye8U1jg oVL9zNzsVjU6lDV0XtO7UYpesDM0hAzkD3UuXKK20GzH0yxH2rQoAhm5Xf99cSiyod536/BIXkmKp 2mY95HZ3Z3Oh/E/lTJ1w/cZ3w4vB91BFbL5lny/HZNPsJl7lftHa1Rty9+ziMwcGVVU5g4UQCppYr A9Mu0=; Received: from [192.168.15.244] (helo=mikhalitsyn-laptop.lan) by relay.sw.ru with esmtps (TLS1.3) tls TLS_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1lVOzN-001UCU-L0; Tue, 22 Jun 2021 18:03:34 +0300 From: Alexander Mikhalitsyn To: netdev@vger.kernel.org Cc: Alexander Mikhalitsyn , David Ahern , Stephen Hemminger , Andrei Vagin , Alexander Mikhalitsyn Subject: [PATCH iproute2] ip route: ignore ENOENT during save if RT_TABLE_MAIN is being dumped Date: Tue, 22 Jun 2021 18:03:30 +0300 Message-Id: <20210622150330.28014-1-alexander.mikhalitsyn@virtuozzo.com> X-Mailer: git-send-email 2.31.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org We started to use in-kernel filtering feature which allows to get only needed tables (see iproute_dump_filter()). From the kernel side it's implemented in net/ipv4/fib_frontend.c (inet_dump_fib), net/ipv6/ip6_fib.c (inet6_dump_fib). The problem here is that behaviour of "ip route save" was changed after c7e6371bc ("ip route: Add protocol, table id and device to dump request"). If filters are used, then kernel returns ENOENT error if requested table is absent, but in newly created net namespace even RT_TABLE_MAIN table doesn't exist. It is really allocated, for instance, after issuing "ip l set lo up". Reproducer is fairly simple: $ unshare -n ip route save > dump Error: ipv4: FIB table does not exist. Dump terminated Expected result here is to get empty dump file (as it was before this change). This affects on CRIU [1] because we use ip route save in dump process, to workaround problem in tests we just put loopback interface up in each net namespace. Other users also met this problem [2]. Links: [1] https://github.com/checkpoint-restore/criu/issues/747 [2] https://www.spinics.net/lists/netdev/msg559739.html Fixes: c7e6371bc ("ip route: Add protocol, table id and device to dump request") Cc: David Ahern Cc: Stephen Hemminger Cc: Andrei Vagin Cc: Alexander Mikhalitsyn Signed-off-by: Alexander Mikhalitsyn --- ip/iproute.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ip/iproute.c b/ip/iproute.c index 5853f026..b70acc00 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -1734,6 +1734,7 @@ static int iproute_list_flush_or_save(int argc, char **argv, int action) char *od = NULL; unsigned int mark = 0; rtnl_filter_t filter_fn; + int ret; if (action == IPROUTE_SAVE) { if (save_route_prep()) @@ -1939,7 +1940,11 @@ static int iproute_list_flush_or_save(int argc, char **argv, int action) new_json_obj(json); - if (rtnl_dump_filter(&rth, filter_fn, stdout) < 0) { + ret = rtnl_dump_filter(&rth, filter_fn, stdout); + + /* Let's ignore ENOENT error if we want to dump RT_TABLE_MAIN table */ + if (ret < 0 && + !(errno == ENOENT && filter.tb == RT_TABLE_MAIN)) { fprintf(stderr, "Dump terminated\n"); return -2; } -- 2.31.1