From patchwork Wed Jun 10 03:49:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Ahern X-Patchwork-Id: 1306375 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=default header.b=RjCfiNO+; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 49hY0T3Xvhz9sRh for ; Wed, 10 Jun 2020 13:50:01 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726109AbgFJDt6 (ORCPT ); Tue, 9 Jun 2020 23:49:58 -0400 Received: from mail.kernel.org ([198.145.29.99]:45910 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725999AbgFJDt4 (ORCPT ); Tue, 9 Jun 2020 23:49:56 -0400 Received: from C02YQ0RWLVCF.internal.digitalocean.com (c-73-181-34-237.hsd1.co.comcast.net [73.181.34.237]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id C15932078B; Wed, 10 Jun 2020 03:49:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1591760996; bh=R/vw++/BEhW/50SqjUMC+E131tom92oALsEW/zr2gko=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RjCfiNO+/FLDJUSfKBc1NhxIj5UDVQxk/msw4Br2HTMcMo+3+waXvC6ffijcQcKHg 8w1FCZM2hUX3TZF17YoYuusNRQtik1oQ0gu27M13A5O5ICkdeSFTGmY4rAydB5kADR AhKYxcX4AORCIE9oXcZnyduG3UdsN7kwk8xFBMns= From: David Ahern To: netdev@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, assogba.emery@gmail.com, dsahern@gmail.com, David Ahern Subject: [PATCH RFC net-next 1/8] nexthop: Rename nexthop_free_mpath Date: Tue, 9 Jun 2020 21:49:46 -0600 Message-Id: <20200610034953.28861-2-dsahern@kernel.org> X-Mailer: git-send-email 2.21.1 (Apple Git-122.3) In-Reply-To: <20200610034953.28861-1-dsahern@kernel.org> References: <20200610034953.28861-1-dsahern@kernel.org> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org nexthop_free_mpath really should be nexthop_free_group. Rename it. Signed-off-by: David Ahern --- net/ipv4/nexthop.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c index 400a9f89ebdb..5ebc47d5ec56 100644 --- a/net/ipv4/nexthop.c +++ b/net/ipv4/nexthop.c @@ -69,7 +69,7 @@ static void nexthop_devhash_add(struct net *net, struct nh_info *nhi) hlist_add_head(&nhi->dev_hash, head); } -static void nexthop_free_mpath(struct nexthop *nh) +static void nexthop_free_group(struct nexthop *nh) { struct nh_group *nhg; int i; @@ -109,7 +109,7 @@ void nexthop_free_rcu(struct rcu_head *head) struct nexthop *nh = container_of(head, struct nexthop, rcu); if (nh->is_group) - nexthop_free_mpath(nh); + nexthop_free_group(nh); else nexthop_free_single(nh); From patchwork Wed Jun 10 03:49:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Ahern X-Patchwork-Id: 1306382 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=default header.b=n3iq2vp7; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 49hY0n5Zrhz9sRh for ; Wed, 10 Jun 2020 13:50:17 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726187AbgFJDuQ (ORCPT ); Tue, 9 Jun 2020 23:50:16 -0400 Received: from mail.kernel.org ([198.145.29.99]:45916 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726046AbgFJDt5 (ORCPT ); Tue, 9 Jun 2020 23:49:57 -0400 Received: from C02YQ0RWLVCF.internal.digitalocean.com (c-73-181-34-237.hsd1.co.comcast.net [73.181.34.237]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 4D73F20801; Wed, 10 Jun 2020 03:49:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1591760997; bh=8nLew60rqVawK5XrPse3OrxIm5Na2OW94NQx6PdgsmQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=n3iq2vp7FhegyLGiemUI7y+oueKHHMYwfLWTsJEvxwtmu1OOrAeFgzUS4uQdgPCyY NMVYqUIJKvHDXMj5FBXHHJVAeY/evHo6/3YAxfFHVOAvB3NBNCm7WYi10ZQeEhifEd ZzydUqPKCUEyiEtJfOyxzUuwWY7OrCsTYtYzJek0= From: David Ahern To: netdev@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, assogba.emery@gmail.com, dsahern@gmail.com, David Ahern Subject: [PATCH RFC net-next 2/8] nexthop: Refactor nexthop_select_path Date: Tue, 9 Jun 2020 21:49:47 -0600 Message-Id: <20200610034953.28861-3-dsahern@kernel.org> X-Mailer: git-send-email 2.21.1 (Apple Git-122.3) In-Reply-To: <20200610034953.28861-1-dsahern@kernel.org> References: <20200610034953.28861-1-dsahern@kernel.org> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Move the ipv{4,6}_good_nh calls to a separate helper. Signed-off-by: David Ahern --- net/ipv4/nexthop.c | 47 +++++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c index 5ebc47d5ec56..7d0a170821f3 100644 --- a/net/ipv4/nexthop.c +++ b/net/ipv4/nexthop.c @@ -536,6 +536,29 @@ static bool ipv4_good_nh(const struct fib_nh *nh) return !!(state & NUD_VALID); } +/* nexthops always check if it is good and does + * not rely on a sysctl for this behavior + */ +static bool good_nh(struct nexthop *nh) +{ + struct nh_info *nhi; + bool rc = false; + + nhi = rcu_dereference(nh->nh_info); + switch (nhi->family) { + case AF_INET: + if (ipv4_good_nh(&nhi->fib_nh)) + rc = true; + break; + case AF_INET6: + if (ipv6_good_nh(&nhi->fib6_nh)) + rc = true; + break; + } + + return rc; +} + struct nexthop *nexthop_select_path(struct nexthop *nh, int hash) { struct nexthop *rc = NULL; @@ -548,31 +571,17 @@ struct nexthop *nexthop_select_path(struct nexthop *nh, int hash) nhg = rcu_dereference(nh->nh_grp); for (i = 0; i < nhg->num_nh; ++i) { struct nh_grp_entry *nhge = &nhg->nh_entries[i]; - struct nh_info *nhi; + struct nexthop *nh; if (hash > atomic_read(&nhge->upper_bound)) continue; - if (nhge->nh->is_fdb_nh) - return nhge->nh; - - /* nexthops always check if it is good and does - * not rely on a sysctl for this behavior - */ - nhi = rcu_dereference(nhge->nh->nh_info); - switch (nhi->family) { - case AF_INET: - if (ipv4_good_nh(&nhi->fib_nh)) - return nhge->nh; - break; - case AF_INET6: - if (ipv6_good_nh(&nhi->fib6_nh)) - return nhge->nh; - break; - } + nh = nhge->nh; + if (nh->is_fdb_nh || good_nh(nh)) + return nh; if (!rc) - rc = nhge->nh; + rc = nh; } return rc; From patchwork Wed Jun 10 03:49:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Ahern X-Patchwork-Id: 1306383 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=default header.b=UesMJKY/; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 49hY0p35fTz9sSF for ; Wed, 10 Jun 2020 13:50:18 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726182AbgFJDuP (ORCPT ); Tue, 9 Jun 2020 23:50:15 -0400 Received: from mail.kernel.org ([198.145.29.99]:45928 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726072AbgFJDt6 (ORCPT ); Tue, 9 Jun 2020 23:49:58 -0400 Received: from C02YQ0RWLVCF.internal.digitalocean.com (c-73-181-34-237.hsd1.co.comcast.net [73.181.34.237]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 4C5E820825; Wed, 10 Jun 2020 03:49:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1591760997; bh=iAjlyLGRbgmUdnnlRR3rPb3WPrxkLYirujcaHYWvYi8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=UesMJKY/jFeJJ3gYJos6S1WKSpfiiNAdCNQhGTqHRu/KZ+ClhlWFbufCFzycHfi6y rNcrzDMkGcSMlZmlJXOOcGqom6gK+O5bn8Co4iBAV5pefQQXTWg9XSxktOSieftDVh D7JvN3atuoLFtAlk0BAO4UMopPnS+Vk/zpKfbNQA= From: David Ahern To: netdev@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, assogba.emery@gmail.com, dsahern@gmail.com, David Ahern Subject: [PATCH RFC net-next 3/8] nexthop: Refactor nexthop_for_each_fib6_nh Date: Tue, 9 Jun 2020 21:49:48 -0600 Message-Id: <20200610034953.28861-4-dsahern@kernel.org> X-Mailer: git-send-email 2.21.1 (Apple Git-122.3) In-Reply-To: <20200610034953.28861-1-dsahern@kernel.org> References: <20200610034953.28861-1-dsahern@kernel.org> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Refactor nexthop_for_each_fib6_nh moving standalone and group processing into helpers. Prepatory patch for adding active-backup group. Signed-off-by: David Ahern --- net/ipv4/nexthop.c | 48 +++++++++++++++++++++++++++++++--------------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c index 7d0a170821f3..940f46a7d533 100644 --- a/net/ipv4/nexthop.c +++ b/net/ipv4/nexthop.c @@ -588,34 +588,52 @@ struct nexthop *nexthop_select_path(struct nexthop *nh, int hash) } EXPORT_SYMBOL_GPL(nexthop_select_path); +static int nexthop_fib6_nh_cb(struct nexthop *nh, + int (*cb)(struct fib6_nh *nh, void *arg), + void *arg) +{ + struct nh_info *nhi; + + nhi = rcu_dereference_rtnl(nh->nh_info); + + return cb(&nhi->fib6_nh, arg); +} + +static int nexthop_fib6_nhg_cb(struct nh_group *nhg, + int (*cb)(struct fib6_nh *nh, void *arg), + void *arg) +{ + int err; + int i; + + for (i = 0; i < nhg->num_nh; i++) { + struct nh_grp_entry *nhge = &nhg->nh_entries[i]; + struct nexthop *nh = nhge->nh; + + err = nexthop_fib6_nh_cb(nh, cb, arg); + if (err) + return err; + } + + return 0; +} + int nexthop_for_each_fib6_nh(struct nexthop *nh, int (*cb)(struct fib6_nh *nh, void *arg), void *arg) { - struct nh_info *nhi; int err; if (nh->is_group) { struct nh_group *nhg; - int i; nhg = rcu_dereference_rtnl(nh->nh_grp); - for (i = 0; i < nhg->num_nh; i++) { - struct nh_grp_entry *nhge = &nhg->nh_entries[i]; - - nhi = rcu_dereference_rtnl(nhge->nh->nh_info); - err = cb(&nhi->fib6_nh, arg); - if (err) - return err; - } + err = nexthop_fib6_nhg_cb(nhg, cb, arg); } else { - nhi = rcu_dereference_rtnl(nh->nh_info); - err = cb(&nhi->fib6_nh, arg); - if (err) - return err; + err = nexthop_fib6_nh_cb(nh, cb, arg); } - return 0; + return err; } EXPORT_SYMBOL_GPL(nexthop_for_each_fib6_nh); From patchwork Wed Jun 10 03:49:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Ahern X-Patchwork-Id: 1306376 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=default header.b=TYZX6KD9; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 49hY0W18hqz9sRh for ; Wed, 10 Jun 2020 13:50:03 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726130AbgFJDuB (ORCPT ); Tue, 9 Jun 2020 23:50:01 -0400 Received: from mail.kernel.org ([198.145.29.99]:45950 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726097AbgFJDt7 (ORCPT ); Tue, 9 Jun 2020 23:49:59 -0400 Received: from C02YQ0RWLVCF.internal.digitalocean.com (c-73-181-34-237.hsd1.co.comcast.net [73.181.34.237]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id CDDEC207F9; Wed, 10 Jun 2020 03:49:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1591760998; bh=fcxOL0Sj4+MUDk0ZzFAdZUGB36BlKRnhoZTp9ojcDhY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TYZX6KD9CRJrOM1/Aox4SrY9w4yn3LiL08ln/4LGMOCRBnEsrXNxIRWJZJUMwUT0a gCJM4mlDnpPKZA2fam77OUgpWOxdzyhYM05bERw/J6ze1HWmvpKrJSM94f4L/owvqk 2Ll0YVRn50YsE4C9KpWoNOL03kRLalYkUy6Jvb5M= From: David Ahern To: netdev@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, assogba.emery@gmail.com, dsahern@gmail.com, David Ahern Subject: [PATCH RFC net-next 4/8] nexthop: Move nexthop_get_nhc_lookup to nexthop.c Date: Tue, 9 Jun 2020 21:49:49 -0600 Message-Id: <20200610034953.28861-5-dsahern@kernel.org> X-Mailer: git-send-email 2.21.1 (Apple Git-122.3) In-Reply-To: <20200610034953.28861-1-dsahern@kernel.org> References: <20200610034953.28861-1-dsahern@kernel.org> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org nexthop_get_nhc_lookup is long enough for an inline and the a-b checks are going to make it worse. Move to nexthop.c and in the process refactor so that mpath code reuses single nh lookup. Prepatory patch for adding active-backup group. Signed-off-by: David Ahern --- include/net/nexthop.h | 29 +------------------------ net/ipv4/nexthop.c | 50 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 28 deletions(-) diff --git a/include/net/nexthop.h b/include/net/nexthop.h index e5122ba78efe..e95800798aa5 100644 --- a/include/net/nexthop.h +++ b/include/net/nexthop.h @@ -261,37 +261,10 @@ struct fib_nh_common *nexthop_fib_nhc(struct nexthop *nh, int nhsel) } /* called from fib_table_lookup with rcu_lock */ -static inline struct fib_nh_common *nexthop_get_nhc_lookup(const struct nexthop *nh, int fib_flags, const struct flowi4 *flp, - int *nhsel) -{ - struct nh_info *nhi; - - if (nh->is_group) { - struct nh_group *nhg = rcu_dereference(nh->nh_grp); - int i; - - for (i = 0; i < nhg->num_nh; i++) { - struct nexthop *nhe = nhg->nh_entries[i].nh; - - nhi = rcu_dereference(nhe->nh_info); - if (fib_lookup_good_nhc(&nhi->fib_nhc, fib_flags, flp)) { - *nhsel = i; - return &nhi->fib_nhc; - } - } - } else { - nhi = rcu_dereference(nh->nh_info); - if (fib_lookup_good_nhc(&nhi->fib_nhc, fib_flags, flp)) { - *nhsel = 0; - return &nhi->fib_nhc; - } - } - - return NULL; -} + int *nhsel); static inline bool nexthop_uses_dev(const struct nexthop *nh, const struct net_device *dev) diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c index 940f46a7d533..c58ecc86b7a1 100644 --- a/net/ipv4/nexthop.c +++ b/net/ipv4/nexthop.c @@ -588,6 +588,56 @@ struct nexthop *nexthop_select_path(struct nexthop *nh, int hash) } EXPORT_SYMBOL_GPL(nexthop_select_path); +static struct fib_nh_common *nhc_lookup_single(const struct nexthop *nh, + int fib_flags, + const struct flowi4 *flp, + int *nhsel) +{ + struct nh_info *nhi; + + nhi = rcu_dereference(nh->nh_info); + if (fib_lookup_good_nhc(&nhi->fib_nhc, fib_flags, flp)) { + *nhsel = 0; + return &nhi->fib_nhc; + } + return NULL; +} + +static struct fib_nh_common *nhc_lookup_mpath(const struct nh_group *nhg, + int fib_flags, + const struct flowi4 *flp, + int *nhsel) +{ + struct fib_nh_common *nhc; + int i; + + for (i = 0; i < nhg->num_nh; i++) { + struct nexthop *nhe = nhg->nh_entries[i].nh; + + nhc = nhc_lookup_single(nhe, fib_flags, flp, nhsel); + if (nhc) { + *nhsel = i; + return nhc; + } + } + + return NULL; +} + +struct fib_nh_common *nexthop_get_nhc_lookup(const struct nexthop *nh, + int fib_flags, + const struct flowi4 *flp, + int *nhsel) +{ + if (nh->is_group) { + const struct nh_group *nhg = rcu_dereference(nh->nh_grp); + + return nhc_lookup_mpath(nhg, fib_flags, flp, nhsel); + } + + return nhc_lookup_single(nh, fib_flags, flp, nhsel); +} + static int nexthop_fib6_nh_cb(struct nexthop *nh, int (*cb)(struct fib6_nh *nh, void *arg), void *arg) From patchwork Wed Jun 10 03:49:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Ahern X-Patchwork-Id: 1306377 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=default header.b=jhFlD0By; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 49hY0Y0v6gz9sRh for ; Wed, 10 Jun 2020 13:50:05 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726143AbgFJDuD (ORCPT ); Tue, 9 Jun 2020 23:50:03 -0400 Received: from mail.kernel.org ([198.145.29.99]:45952 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726112AbgFJDt7 (ORCPT ); Tue, 9 Jun 2020 23:49:59 -0400 Received: from C02YQ0RWLVCF.internal.digitalocean.com (c-73-181-34-237.hsd1.co.comcast.net [73.181.34.237]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 584792076A; Wed, 10 Jun 2020 03:49:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1591760998; bh=kOc4BHGGYmoR1yMo/touSA2B2rB1cFGODQyAyEXvq+c=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jhFlD0ByD+9FbQQVxk/QForsSJmlW9G/DOeLGeivEviWvbIthLzsiq7b1HQcCg0Va tnby9zczD9YW5ul4vozoRzrvFEcra1LSI7uy68ImClFqHInE6esdZcM0pO8wRj0k1K NZ4uXRUWoLDeVir1G6jyBao4IS8AfYpHE5tSJcwg= From: David Ahern To: netdev@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, assogba.emery@gmail.com, dsahern@gmail.com, David Ahern Subject: [PATCH RFC net-next 5/8] nexthop: Move nexthop_uses_dev to nexthop.c Date: Tue, 9 Jun 2020 21:49:50 -0600 Message-Id: <20200610034953.28861-6-dsahern@kernel.org> X-Mailer: git-send-email 2.21.1 (Apple Git-122.3) In-Reply-To: <20200610034953.28861-1-dsahern@kernel.org> References: <20200610034953.28861-1-dsahern@kernel.org> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org nexthop_uses_dev is long enough for an inline and the a-b checks are going to make it worse. Move to nexthop.c and in the process refactor so that mpath code reuses single nh lookup. Prepatory patch for adding active-backup group. Signed-off-by: David Ahern --- include/net/nexthop.h | 25 +------------------------ net/ipv4/nexthop.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/include/net/nexthop.h b/include/net/nexthop.h index e95800798aa5..271d2cb92954 100644 --- a/include/net/nexthop.h +++ b/include/net/nexthop.h @@ -266,30 +266,7 @@ struct fib_nh_common *nexthop_get_nhc_lookup(const struct nexthop *nh, const struct flowi4 *flp, int *nhsel); -static inline bool nexthop_uses_dev(const struct nexthop *nh, - const struct net_device *dev) -{ - struct nh_info *nhi; - - if (nh->is_group) { - struct nh_group *nhg = rcu_dereference(nh->nh_grp); - int i; - - for (i = 0; i < nhg->num_nh; i++) { - struct nexthop *nhe = nhg->nh_entries[i].nh; - - nhi = rcu_dereference(nhe->nh_info); - if (nhc_l3mdev_matches_dev(&nhi->fib_nhc, dev)) - return true; - } - } else { - nhi = rcu_dereference(nh->nh_info); - if (nhc_l3mdev_matches_dev(&nhi->fib_nhc, dev)) - return true; - } - - return false; -} +bool nexthop_uses_dev(const struct nexthop *nh, const struct net_device *dev); static inline unsigned int fib_info_num_path(const struct fib_info *fi) { diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c index c58ecc86b7a1..0020ea2ecc9f 100644 --- a/net/ipv4/nexthop.c +++ b/net/ipv4/nexthop.c @@ -638,6 +638,41 @@ struct fib_nh_common *nexthop_get_nhc_lookup(const struct nexthop *nh, return nhc_lookup_single(nh, fib_flags, flp, nhsel); } +static bool nh_uses_dev_single(const struct nexthop *nh, + const struct net_device *dev) +{ + const struct nh_info *nhi; + + nhi = rcu_dereference(nh->nh_info); + return nhc_l3mdev_matches_dev(&nhi->fib_nhc, dev); +} + +static bool nh_uses_dev_mpath(const struct nh_group *nhg, + const struct net_device *dev) +{ + int i; + + for (i = 0; i < nhg->num_nh; i++) { + struct nexthop *nhe = nhg->nh_entries[i].nh; + + if (nh_uses_dev_single(nhe, dev)) + return true; + } + + return false; +} + +bool nexthop_uses_dev(const struct nexthop *nh, const struct net_device *dev) +{ + if (nh->is_group) { + const struct nh_group *nhg = rcu_dereference(nh->nh_grp); + + return nh_uses_dev_mpath(nhg, dev); + } + + return nh_uses_dev_single(nh, dev); +} + static int nexthop_fib6_nh_cb(struct nexthop *nh, int (*cb)(struct fib6_nh *nh, void *arg), void *arg) From patchwork Wed Jun 10 03:49:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Ahern X-Patchwork-Id: 1306380 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=default header.b=00nXjnNi; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 49hY0f3PlJz9sSF for ; Wed, 10 Jun 2020 13:50:10 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726178AbgFJDuJ (ORCPT ); Tue, 9 Jun 2020 23:50:09 -0400 Received: from mail.kernel.org ([198.145.29.99]:45966 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725999AbgFJDuA (ORCPT ); Tue, 9 Jun 2020 23:50:00 -0400 Received: from C02YQ0RWLVCF.internal.digitalocean.com (c-73-181-34-237.hsd1.co.comcast.net [73.181.34.237]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id D7E012081A; Wed, 10 Jun 2020 03:49:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1591760999; bh=MKYGTL2C/vD/hKO8uSqCvwU9lfaCSDRbgwweeX+WrAw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=00nXjnNi/i5BwD0VnkKhCY4w7yxDavYsV8d6bL4uHJauEEYftakudh855TL49Z5n7 ibdE4P8NFKiM4qz42LRfo/MlGVEniY4fyygh1jaZrMO5nM8ZdUA3zADRJXAlp3c5LL hZFhbfBl4OF/aWdTYrhyijq7AAVR8gVdRaSkTtCI= From: David Ahern To: netdev@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, assogba.emery@gmail.com, dsahern@gmail.com, David Ahern Subject: [PATCH RFC net-next 6/8] nexthop: Add primary_only argument to nexthop_for_each_fib6_nh Date: Tue, 9 Jun 2020 21:49:51 -0600 Message-Id: <20200610034953.28861-7-dsahern@kernel.org> X-Mailer: git-send-email 2.21.1 (Apple Git-122.3) In-Reply-To: <20200610034953.28861-1-dsahern@kernel.org> References: <20200610034953.28861-1-dsahern@kernel.org> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Follow on patch adds support for active-backup nexthops. Control planes needs to always analyze all legs of the nexthops, but datapath only wants to consider the primary. Signed-off-by: David Ahern --- include/net/nexthop.h | 2 +- net/ipv4/nexthop.c | 6 +++--- net/ipv6/ip6_fib.c | 4 ++-- net/ipv6/route.c | 37 ++++++++++++++++++++----------------- 4 files changed, 26 insertions(+), 23 deletions(-) diff --git a/include/net/nexthop.h b/include/net/nexthop.h index 271d2cb92954..8cedadb902b6 100644 --- a/include/net/nexthop.h +++ b/include/net/nexthop.h @@ -346,7 +346,7 @@ static inline void nexthop_path_fib6_result(struct fib6_result *res, int hash) } } -int nexthop_for_each_fib6_nh(struct nexthop *nh, +int nexthop_for_each_fib6_nh(struct nexthop *nh, bool primary_only, int (*cb)(struct fib6_nh *nh, void *arg), void *arg); diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c index 0020ea2ecc9f..8984e1e4058b 100644 --- a/net/ipv4/nexthop.c +++ b/net/ipv4/nexthop.c @@ -684,7 +684,7 @@ static int nexthop_fib6_nh_cb(struct nexthop *nh, return cb(&nhi->fib6_nh, arg); } -static int nexthop_fib6_nhg_cb(struct nh_group *nhg, +static int nexthop_fib6_nhg_cb(struct nh_group *nhg, bool primary_only, int (*cb)(struct fib6_nh *nh, void *arg), void *arg) { @@ -703,7 +703,7 @@ static int nexthop_fib6_nhg_cb(struct nh_group *nhg, return 0; } -int nexthop_for_each_fib6_nh(struct nexthop *nh, +int nexthop_for_each_fib6_nh(struct nexthop *nh, bool primary_only, int (*cb)(struct fib6_nh *nh, void *arg), void *arg) { @@ -713,7 +713,7 @@ int nexthop_for_each_fib6_nh(struct nexthop *nh, struct nh_group *nhg; nhg = rcu_dereference_rtnl(nh->nh_grp); - err = nexthop_fib6_nhg_cb(nhg, cb, arg); + err = nexthop_fib6_nhg_cb(nhg, primary_only, cb, arg); } else { err = nexthop_fib6_nh_cb(nh, cb, arg); } diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 49ee89bbcba0..7e593f9d519d 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c @@ -1009,8 +1009,8 @@ static void fib6_drop_pcpu_from(struct fib6_info *f6i, .table = table }; - nexthop_for_each_fib6_nh(f6i->nh, fib6_nh_drop_pcpu_from, - &arg); + nexthop_for_each_fib6_nh(f6i->nh, false, + fib6_nh_drop_pcpu_from, &arg); } else { struct fib6_nh *fib6_nh; diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 82cbb46a2a4f..e2bd3dc7194d 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -526,7 +526,7 @@ static struct fib6_nh *rt6_nh_dev_match(struct net *net, struct nexthop *nh, if (nexthop_is_blackhole(nh)) return NULL; - if (nexthop_for_each_fib6_nh(nh, __rt6_nh_dev_match, &arg)) + if (nexthop_for_each_fib6_nh(nh, true, __rt6_nh_dev_match, &arg)) return arg.nh; return NULL; @@ -827,7 +827,8 @@ static void __find_rr_leaf(struct fib6_info *f6i_start, res->nh = nexthop_fib6_nh(f6i->nh); return; } - if (nexthop_for_each_fib6_nh(f6i->nh, rt6_nh_find_match, + if (nexthop_for_each_fib6_nh(f6i->nh, true, + rt6_nh_find_match, &arg)) { matched = true; nh = arg.nh; @@ -1774,8 +1775,8 @@ static int rt6_nh_flush_exceptions(struct fib6_nh *nh, void *arg) void rt6_flush_exceptions(struct fib6_info *f6i) { if (f6i->nh) - nexthop_for_each_fib6_nh(f6i->nh, rt6_nh_flush_exceptions, - f6i); + nexthop_for_each_fib6_nh(f6i->nh, false, + rt6_nh_flush_exceptions, f6i); else fib6_nh_flush_exceptions(f6i->fib6_nh, f6i); } @@ -1897,7 +1898,7 @@ static int rt6_remove_exception_rt(struct rt6_info *rt) int rc; /* rc = 1 means an entry was found */ - rc = nexthop_for_each_fib6_nh(from->nh, + rc = nexthop_for_each_fib6_nh(from->nh, false, rt6_nh_remove_exception_rt, &arg); return rc ? 0 : -ENOENT; @@ -1973,7 +1974,8 @@ static void rt6_update_exception_stamp_rt(struct rt6_info *rt) .gw = &rt->rt6i_gateway, }; - nexthop_for_each_fib6_nh(from->nh, fib6_nh_find_match, &arg); + nexthop_for_each_fib6_nh(from->nh, false, fib6_nh_find_match, + &arg); if (!arg.match) goto unlock; @@ -2166,8 +2168,8 @@ void rt6_age_exceptions(struct fib6_info *f6i, .now = now }; - nexthop_for_each_fib6_nh(f6i->nh, rt6_nh_age_exceptions, - &arg); + nexthop_for_each_fib6_nh(f6i->nh, false, + rt6_nh_age_exceptions, &arg); } else { fib6_nh_age_exceptions(f6i->fib6_nh, gc_args, now); } @@ -2768,7 +2770,7 @@ static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk, .gw = &rt6->rt6i_gateway, }; - nexthop_for_each_fib6_nh(res.f6i->nh, + nexthop_for_each_fib6_nh(res.f6i->nh, true, fib6_nh_find_match, &arg); /* fib6_info uses a nexthop that does not have fib6_nh @@ -2959,7 +2961,7 @@ static struct rt6_info *__ip6_route_redirect(struct net *net, if (nexthop_is_blackhole(rt->nh)) continue; /* on match, res->nh is filled in and potentially ret */ - if (nexthop_for_each_fib6_nh(rt->nh, + if (nexthop_for_each_fib6_nh(rt->nh, true, fib6_nh_redirect_match, &arg)) goto out; @@ -3906,7 +3908,8 @@ static int ip6_del_cached_rt_nh(struct fib6_config *cfg, struct fib6_info *f6i) .f6i = f6i }; - return nexthop_for_each_fib6_nh(f6i->nh, fib6_nh_del_cached_rt, &arg); + return nexthop_for_each_fib6_nh(f6i->nh, false, + fib6_nh_del_cached_rt, &arg); } static int ip6_route_del(struct fib6_config *cfg, @@ -4096,7 +4099,7 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu .gw = &rt->rt6i_gateway, }; - nexthop_for_each_fib6_nh(res.f6i->nh, + nexthop_for_each_fib6_nh(res.f6i->nh, true, fib6_nh_find_match, &arg); /* fib6_info uses a nexthop that does not have fib6_nh @@ -4835,8 +4838,8 @@ static int rt6_mtu_change_route(struct fib6_info *f6i, void *p_arg) arg->f6i = f6i; if (f6i->nh) { /* fib6_nh_mtu_change only returns 0, so this is safe */ - return nexthop_for_each_fib6_nh(f6i->nh, fib6_nh_mtu_change, - arg); + return nexthop_for_each_fib6_nh(f6i->nh, false, + fib6_nh_mtu_change, arg); } return fib6_nh_mtu_change(f6i->fib6_nh, arg); @@ -5381,7 +5384,7 @@ static size_t rt6_nlmsg_size(struct fib6_info *f6i) if (f6i->nh) { nexthop_len = nla_total_size(4); /* RTA_NH_ID */ - nexthop_for_each_fib6_nh(f6i->nh, rt6_nh_nlmsg_size, + nexthop_for_each_fib6_nh(f6i->nh, false, rt6_nh_nlmsg_size, &nexthop_len); } else { struct fib6_nh *nh = f6i->fib6_nh; @@ -5636,7 +5639,7 @@ static bool fib6_info_uses_dev(const struct fib6_info *f6i, if (f6i->nh) { struct net_device *_dev = (struct net_device *)dev; - return !!nexthop_for_each_fib6_nh(f6i->nh, + return !!nexthop_for_each_fib6_nh(f6i->nh, true, fib6_info_nh_uses_dev, _dev); } @@ -5769,7 +5772,7 @@ int rt6_dump_route(struct fib6_info *rt, void *p_arg, unsigned int skip) rcu_read_lock(); if (rt->nh) { - err = nexthop_for_each_fib6_nh(rt->nh, + err = nexthop_for_each_fib6_nh(rt->nh, false, rt6_nh_dump_exceptions, &w); } else { From patchwork Wed Jun 10 03:49:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Ahern X-Patchwork-Id: 1306378 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=default header.b=XPS0I5Uu; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 49hY0c0WKHz9sSF for ; Wed, 10 Jun 2020 13:50:08 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726155AbgFJDuG (ORCPT ); Tue, 9 Jun 2020 23:50:06 -0400 Received: from mail.kernel.org ([198.145.29.99]:45978 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726115AbgFJDuC (ORCPT ); Tue, 9 Jun 2020 23:50:02 -0400 Received: from C02YQ0RWLVCF.internal.digitalocean.com (c-73-181-34-237.hsd1.co.comcast.net [73.181.34.237]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 6804920829; Wed, 10 Jun 2020 03:49:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1591760999; bh=XNR7jklSCQPwpm5aH7JokTLnhIsh/ZOnoOSS4HOKJoc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=XPS0I5UuEL8L4qaNCp++CXWT9L0zxPs80Rxx9Yji3lWuRftKwc0OQ1Pp8k2g5KHJV k4OyGKlMwytJLp1vwqXDpALAaCtNWz/sJB08Jz60qMzUMjPfIoKmpa1+JLt4KFgMsT FESzHfnB2Se8Cfyy0KandQyiVvcfGkMg8m/SFZK4= From: David Ahern To: netdev@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, assogba.emery@gmail.com, dsahern@gmail.com, David Ahern Subject: [PATCH RFC net-next 7/8] nexthop: Add support for active-backup nexthop type Date: Tue, 9 Jun 2020 21:49:52 -0600 Message-Id: <20200610034953.28861-8-dsahern@kernel.org> X-Mailer: git-send-email 2.21.1 (Apple Git-122.3) In-Reply-To: <20200610034953.28861-1-dsahern@kernel.org> References: <20200610034953.28861-1-dsahern@kernel.org> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Add new active-backup group type. The intent is that the group describes a primary nexthop with a backup option if the primary is not available. Since nexthop code removes entries on carrier or admin down this really means the backup applies when the neighbor entry for the active becomes invalid. In that case the lookup atomically switches to use the backup. Conceptually, the linkage is like this. For single path routes, a FIB entry references a nexthop that is a an active-backup pair: nexthop active { prefix } -> a-b nexthop -< nexthop backup Alternatively, an active-backup nexthop can be one more entries in a multipath route: nexthop active nexthop 1 (ab) -< { prefix } -> mpath nexthop -< ... nexthop backup nexthop N The intent is to provide a fast failover option for routing daemons - the primary goes down, notification is sent to userspace, and the backup takes over until the daemon can adjust the routes. For multipath routes this has the added benefit of providing an option to limit the flows affected by a carrier or admin down event. Currently, flows are hashed over the N-paths of a multipath route. If a path goes dead, the leg is effectively removed and all flows are potentially affected as the hashing consides now N-1 paths. With active-backup nexthops an admin can setup a backup for each leg to minimize the affected flows. Most of this change is updating the group handling to account for the a-b pair, especially in nexthop groups. Datapath lookups should only consider the active nexthop unless it is determined bad. Route notifications and lookups will only show the existence of the active nexthop. Signed-off-by: ASSOGBA Emery Co-developed-by: David Ahern Signed-off-by: David Ahern --- include/net/nexthop.h | 50 ++++++++-- include/uapi/linux/nexthop.h | 1 + net/ipv4/fib_semantics.c | 6 +- net/ipv4/nexthop.c | 186 ++++++++++++++++++++++++++++++++--- 4 files changed, 217 insertions(+), 26 deletions(-) diff --git a/include/net/nexthop.h b/include/net/nexthop.h index 8cedadb902b6..aee870bc8c0e 100644 --- a/include/net/nexthop.h +++ b/include/net/nexthop.h @@ -76,6 +76,7 @@ struct nh_group { struct nh_group *spare; /* spare group for removals */ u16 num_nh; bool mpath; + bool active_backup; bool has_v4; struct nh_grp_entry nh_entries[]; }; @@ -158,6 +159,17 @@ static inline bool nexthop_is_multipath(const struct nexthop *nh) return false; } +static inline bool nexthop_is_active_backup(const struct nexthop *nh) +{ + if (nh->is_group) { + struct nh_group *nh_grp; + + nh_grp = rcu_dereference_rtnl(nh->nh_grp); + return nh_grp->active_backup; + } + return false; +} + struct nexthop *nexthop_select_path(struct nexthop *nh, int hash); static inline unsigned int nexthop_num_path(const struct nexthop *nh) @@ -168,8 +180,7 @@ static inline unsigned int nexthop_num_path(const struct nexthop *nh) struct nh_group *nh_grp; nh_grp = rcu_dereference_rtnl(nh->nh_grp); - if (nh_grp->mpath) - rc = nh_grp->num_nh; + rc = nh_grp->num_nh; } return rc; @@ -196,9 +207,18 @@ int nexthop_mpath_fill_node(struct sk_buff *skb, struct nexthop *nh, for (i = 0; i < nhg->num_nh; i++) { struct nexthop *nhe = nhg->nh_entries[i].nh; - struct nh_info *nhi = rcu_dereference_rtnl(nhe->nh_info); - struct fib_nh_common *nhc = &nhi->fib_nhc; int weight = nhg->nh_entries[i].weight; + struct fib_nh_common *nhc; + struct nh_info *nhi; + + if (nhe->is_group) { + struct nh_group *nhg_ab = rtnl_dereference(nhe->nh_grp); + + /* group in group is active-backup. take primary */ + nhe = nhg_ab->nh_entries[0].nh; + } + nhi = rcu_dereference_rtnl(nhe->nh_info); + nhc = &nhi->fib_nhc; if (fib_add_nexthop(skb, nhc, weight, rt_family) < 0) return -EMSGSIZE; @@ -216,7 +236,7 @@ static inline bool nexthop_is_blackhole(const struct nexthop *nh) struct nh_group *nh_grp; nh_grp = rcu_dereference_rtnl(nh->nh_grp); - if (nh_grp->num_nh > 1) + if (nh_grp->active_backup || nh_grp->num_nh > 1) return false; nh = nh_grp->nh_entries[0].nh; @@ -253,6 +273,16 @@ struct fib_nh_common *nexthop_fib_nhc(struct nexthop *nh, int nhsel) nh = nexthop_mpath_select(nh_grp, nhsel); if (!nh) return NULL; + + /* multipath with a-b path */ + if (nh->is_group) { + nh_grp = rcu_dereference_rtnl(nh->nh_grp); + nh = nh_grp->nh_entries[0].nh; + } + } else if (nh_grp->active_backup) { + if (nhsel > 0) + return NULL; + nh = nh_grp->nh_entries[0].nh; } } @@ -309,9 +339,13 @@ static inline struct fib6_nh *nexthop_fib6_nh(struct nexthop *nh) struct nh_group *nh_grp; nh_grp = rcu_dereference_rtnl(nh->nh_grp); - nh = nexthop_mpath_select(nh_grp, 0); - if (!nh) - return NULL; + nh = nh_grp->nh_entries[0].nh; + + /* mpath with active-backup path */ + if (nh->is_group) { + nh_grp = rcu_dereference_rtnl(nh->nh_grp); + nh = nh_grp->nh_entries[0].nh; + } } nhi = rcu_dereference_rtnl(nh->nh_info); diff --git a/include/uapi/linux/nexthop.h b/include/uapi/linux/nexthop.h index 2d4a1e784cf0..9566e1ac07fe 100644 --- a/include/uapi/linux/nexthop.h +++ b/include/uapi/linux/nexthop.h @@ -22,6 +22,7 @@ struct nexthop_grp { enum { NEXTHOP_GRP_TYPE_MPATH, /* default type if not specified */ + NEXTHOP_GRP_TYPE_ACTIVE_BACKUP, __NEXTHOP_GRP_TYPE_MAX, }; diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index e53871e4a097..a218cd912de9 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -480,10 +480,10 @@ static inline size_t fib_nlmsg_size(struct fib_info *fi) nhsize += 2 * nla_total_size(4); /* grab encap info */ - for (i = 0; i < fib_info_num_path(fi); i++) { + for (i = 0; i < nhs; i++) { struct fib_nh_common *nhc = fib_info_nhc(fi, i); - if (nhc->nhc_lwtstate) { + if (nhc && nhc->nhc_lwtstate) { /* RTA_ENCAP_TYPE */ nh_encapsize += lwtunnel_get_encap_size( nhc->nhc_lwtstate); @@ -1780,6 +1780,8 @@ int fib_dump_info(struct sk_buff *skb, u32 portid, u32 seq, int event, goto nla_put_failure; if (nexthop_is_blackhole(fi->nh)) rtm->rtm_type = RTN_BLACKHOLE; + else if (nexthop_is_active_backup(fi->nh)) + nhs = 1; if (!fi->fib_net->ipv4.sysctl_nexthop_compat_mode) goto offload; } diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c index 8984e1e4058b..e7335a81198f 100644 --- a/net/ipv4/nexthop.c +++ b/net/ipv4/nexthop.c @@ -204,6 +204,9 @@ static int nla_put_nh_group(struct sk_buff *skb, struct nh_group *nhg) if (nhg->mpath) group_type = NEXTHOP_GRP_TYPE_MPATH; + if (nhg->active_backup) + group_type = NEXTHOP_GRP_TYPE_ACTIVE_BACKUP; + if (nla_put_u16(skb, NHA_GROUP_TYPE, group_type)) goto nla_put_failure; @@ -433,6 +436,7 @@ static int nh_check_attr_fdb_group(struct nexthop *nh, u8 *nh_family, } static int nh_check_attr_group(struct net *net, struct nlattr *tb[], + u16 nh_grp_type, struct netlink_ext_ack *extack) { unsigned int len = nla_len(tb[NHA_GROUP]); @@ -451,6 +455,13 @@ static int nh_check_attr_group(struct net *net, struct nlattr *tb[], len /= sizeof(*nhg); nhg = nla_data(tb[NHA_GROUP]); + + if (nh_grp_type == NEXTHOP_GRP_TYPE_ACTIVE_BACKUP && + (len != 2 || nhg[0].weight || nhg[1].weight)) { + NL_SET_ERR_MSG(extack, "Active/backup group must have 2 nexthops and weight can not be set"); + return -EINVAL; + } + for (i = 0; i < len; ++i) { if (nhg[i].resvd1 || nhg[i].resvd2) { NL_SET_ERR_MSG(extack, "Reserved fields in nexthop_grp must be 0"); @@ -468,8 +479,14 @@ static int nh_check_attr_group(struct net *net, struct nlattr *tb[], } } - if (tb[NHA_FDB]) + if (tb[NHA_FDB]) { + if (nh_grp_type == NEXTHOP_GRP_TYPE_ACTIVE_BACKUP) { + NL_SET_ERR_MSG(extack, "Active/backup group not valid with fdb entries"); + return -EINVAL; + } nhg_fdb = 1; + } + nhg = nla_data(tb[NHA_GROUP]); for (i = 0; i < len; ++i) { struct nexthop *nh; @@ -559,16 +576,43 @@ static bool good_nh(struct nexthop *nh) return rc; } -struct nexthop *nexthop_select_path(struct nexthop *nh, int hash) +static struct nexthop *nh_select_path_ab(struct nh_group *nhg, int hash) { struct nexthop *rc = NULL; - struct nh_group *nhg; - int i; + struct nexthop *p, *b; + + switch (nhg->num_nh) { + case 2: + /* if primary is good, use it */ + p = nhg->nh_entries[0].nh; + if (good_nh(p)) { + rc = p; + break; + } - if (!nh->is_group) - return nh; + /* try backup */ + b = nhg->nh_entries[1].nh; + if (good_nh(b)) + rc = b; + break; + case 1: + p = nhg->nh_entries[0].nh; + if (good_nh(p)) + rc = p; + break; + default: + WARN_ON_ONCE(1); + break; + } + + return rc; +} + +static struct nexthop *nh_select_path_mpath(struct nh_group *nhg, int hash) +{ + struct nexthop *rc = NULL; + int i; - nhg = rcu_dereference(nh->nh_grp); for (i = 0; i < nhg->num_nh; ++i) { struct nh_grp_entry *nhge = &nhg->nh_entries[i]; struct nexthop *nh; @@ -577,8 +621,17 @@ struct nexthop *nexthop_select_path(struct nexthop *nh, int hash) continue; nh = nhge->nh; - if (nh->is_fdb_nh || good_nh(nh)) + + /* group in a group; inner one is active/backup pair */ + if (unlikely(nh->is_group)) { + struct nh_group *nhg = rcu_dereference(nh->nh_grp); + + nh = nh_select_path_ab(nhg, hash); + if (nh) + return nh; + } else if (good_nh(nh)) { return nh; + } if (!rc) rc = nh; @@ -586,6 +639,23 @@ struct nexthop *nexthop_select_path(struct nexthop *nh, int hash) return rc; } + +struct nexthop *nexthop_select_path(struct nexthop *nh, int hash) +{ + struct nh_group *nhg; + struct nexthop *rc; + + if (!nh->is_group) + return nh; + + nhg = rcu_dereference(nh->nh_grp); + if (nhg->active_backup) + rc = nh_select_path_ab(nhg, hash); + else + rc = nh_select_path_mpath(nhg, hash); + + return rc; +} EXPORT_SYMBOL_GPL(nexthop_select_path); static struct fib_nh_common *nhc_lookup_single(const struct nexthop *nh, @@ -603,6 +673,17 @@ static struct fib_nh_common *nhc_lookup_single(const struct nexthop *nh, return NULL; } +/* active-backup only looks at primary */ +static struct fib_nh_common *nhc_lookup_ab(const struct nh_group *nhg, + int fib_flags, + const struct flowi4 *flp, + int *nhsel) +{ + struct nexthop *nhe = nhg->nh_entries[0].nh; + + return nhc_lookup_single(nhe, fib_flags, flp, nhsel); +} + static struct fib_nh_common *nhc_lookup_mpath(const struct nh_group *nhg, int fib_flags, const struct flowi4 *flp, @@ -614,7 +695,14 @@ static struct fib_nh_common *nhc_lookup_mpath(const struct nh_group *nhg, for (i = 0; i < nhg->num_nh; i++) { struct nexthop *nhe = nhg->nh_entries[i].nh; - nhc = nhc_lookup_single(nhe, fib_flags, flp, nhsel); + if (nhe->is_group) { + const struct nh_group *nhg_ab; + + nhg_ab = rcu_dereference(nhe->nh_grp); + nhc = nhc_lookup_ab(nhg_ab, fib_flags, flp, nhsel); + } else { + nhc = nhc_lookup_single(nhe, fib_flags, flp, nhsel); + } if (nhc) { *nhsel = i; return nhc; @@ -632,7 +720,10 @@ struct fib_nh_common *nexthop_get_nhc_lookup(const struct nexthop *nh, if (nh->is_group) { const struct nh_group *nhg = rcu_dereference(nh->nh_grp); - return nhc_lookup_mpath(nhg, fib_flags, flp, nhsel); + if (nhg->mpath) + return nhc_lookup_mpath(nhg, fib_flags, flp, nhsel); + + return nhc_lookup_ab(nhg, fib_flags, flp, nhsel); } return nhc_lookup_single(nh, fib_flags, flp, nhsel); @@ -647,6 +738,15 @@ static bool nh_uses_dev_single(const struct nexthop *nh, return nhc_l3mdev_matches_dev(&nhi->fib_nhc, dev); } +/* active-backup only looks at primary */ +static bool nh_uses_dev_ab(const struct nh_group *nhg, + const struct net_device *dev) +{ + struct nexthop *nhe = nhg->nh_entries[0].nh; + + return nh_uses_dev_single(nhe, dev); +} + static bool nh_uses_dev_mpath(const struct nh_group *nhg, const struct net_device *dev) { @@ -655,8 +755,15 @@ static bool nh_uses_dev_mpath(const struct nh_group *nhg, for (i = 0; i < nhg->num_nh; i++) { struct nexthop *nhe = nhg->nh_entries[i].nh; - if (nh_uses_dev_single(nhe, dev)) + if (nhe->is_group) { + const struct nh_group *nhg_ab; + + nhg_ab = rcu_dereference(nhe->nh_grp); + if (nh_uses_dev_ab(nhg_ab, dev)) + return true; + } else if (nh_uses_dev_single(nhe, dev)) { return true; + } } return false; @@ -667,7 +774,9 @@ bool nexthop_uses_dev(const struct nexthop *nh, const struct net_device *dev) if (nh->is_group) { const struct nh_group *nhg = rcu_dereference(nh->nh_grp); - return nh_uses_dev_mpath(nhg, dev); + if (nhg->mpath) + return nh_uses_dev_mpath(nhg, dev); + return nh_uses_dev_ab(nhg, dev); } return nh_uses_dev_single(nh, dev); @@ -684,6 +793,28 @@ static int nexthop_fib6_nh_cb(struct nexthop *nh, return cb(&nhi->fib6_nh, arg); } +static int nexthop_fib6_ab_nhg_cb(struct nh_group *nhg, bool primary_only, + int (*cb)(struct fib6_nh *nh, void *arg), + void *arg) +{ + int err; + int i; + + for (i = 0; i < nhg->num_nh; i++) { + struct nh_grp_entry *nhge = &nhg->nh_entries[i]; + struct nexthop *nh = nhge->nh; + + err = nexthop_fib6_nh_cb(nh, cb, arg); + if (err) + return err; + + if (primary_only) + break; + } + + return 0; +} + static int nexthop_fib6_nhg_cb(struct nh_group *nhg, bool primary_only, int (*cb)(struct fib6_nh *nh, void *arg), void *arg) @@ -695,7 +826,17 @@ static int nexthop_fib6_nhg_cb(struct nh_group *nhg, bool primary_only, struct nh_grp_entry *nhge = &nhg->nh_entries[i]; struct nexthop *nh = nhge->nh; - err = nexthop_fib6_nh_cb(nh, cb, arg); + if (unlikely(nh->is_group)) { + struct nh_group *nhg2; + + nhg2 = rcu_dereference(nh->nh_grp); + /* group in group is active/backup */ + err = nexthop_fib6_ab_nhg_cb(nhg2, primary_only, + cb, arg); + } else { + err = nexthop_fib6_nh_cb(nh, cb, arg); + } + if (err) return err; } @@ -899,6 +1040,7 @@ static void remove_nh_grp_entry(struct net *net, struct nh_grp_entry *nhge, newg->has_v4 = nhg->has_v4; newg->mpath = nhg->mpath; + newg->active_backup = nhg->active_backup; newg->num_nh = nhg->num_nh; /* copy old entries to new except the one getting removed */ @@ -941,7 +1083,8 @@ static void remove_nexthop_from_groups(struct net *net, struct nexthop *nh, synchronize_rcu(); } -static void remove_nexthop_group(struct nexthop *nh, struct nl_info *nlinfo) +static void remove_nexthop_group(struct net *net, struct nexthop *nh, + struct nl_info *nlinfo) { struct nh_group *nhg = rcu_dereference_rtnl(nh->nh_grp); int i, num_nh = nhg->num_nh; @@ -954,6 +1097,9 @@ static void remove_nexthop_group(struct nexthop *nh, struct nl_info *nlinfo) list_del_init(&nhge->nh_list); } + + if (nhg->active_backup) + remove_nexthop_from_groups(net, nh, nlinfo); } /* not called for nexthop replace */ @@ -987,7 +1133,7 @@ static void __remove_nexthop(struct net *net, struct nexthop *nh, __remove_nexthop_fib(net, nh); if (nh->is_group) { - remove_nexthop_group(nh, nlinfo); + remove_nexthop_group(net, nh, nlinfo); } else { struct nh_info *nhi; @@ -1043,6 +1189,11 @@ static int replace_nexthop_grp(struct net *net, struct nexthop *old, oldg = rtnl_dereference(old->nh_grp); newg = rtnl_dereference(new->nh_grp); + if (oldg->active_backup ^ newg->active_backup) { + NL_SET_ERR_MSG(extack, "Can not change group type with replace"); + return -EINVAL; + } + /* update parents - used by nexthop code for cleanup */ for (i = 0; i < newg->num_nh; i++) newg->nh_entries[i].nh_parent = old; @@ -1330,6 +1481,9 @@ static struct nexthop *nexthop_create_group(struct net *net, if (cfg->nh_fdb) nh->is_fdb_nh = 1; + if (cfg->nh_grp_type == NEXTHOP_GRP_TYPE_ACTIVE_BACKUP) + nhg->active_backup = 1; + rcu_assign_pointer(nh->nh_grp, nhg); return nh; @@ -1594,7 +1748,7 @@ static int rtm_to_nh_config(struct net *net, struct sk_buff *skb, NL_SET_ERR_MSG(extack, "Invalid group type"); goto out; } - err = nh_check_attr_group(net, tb, extack); + err = nh_check_attr_group(net, tb, cfg->nh_grp_type, extack); /* no other attributes should be set */ goto out; From patchwork Wed Jun 10 03:49:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Ahern X-Patchwork-Id: 1306379 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=kernel.org header.i=@kernel.org header.a=rsa-sha256 header.s=default header.b=WEiyxKon; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 49hY0d2rcGz9sSF for ; Wed, 10 Jun 2020 13:50:09 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726166AbgFJDuI (ORCPT ); Tue, 9 Jun 2020 23:50:08 -0400 Received: from mail.kernel.org ([198.145.29.99]:45952 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726121AbgFJDuA (ORCPT ); Tue, 9 Jun 2020 23:50:00 -0400 Received: from C02YQ0RWLVCF.internal.digitalocean.com (c-73-181-34-237.hsd1.co.comcast.net [73.181.34.237]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id EFF76207ED; Wed, 10 Jun 2020 03:49:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1591761000; bh=FNKeL/Abtr/Ds1M9hz8iAPAvAFUctIULH8ZIyN6MAF8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WEiyxKonivrf8EOhE75FguWAQti8aHUzrAwJWUe/i25VeNYPvf6x+JoxqCwF4hyRL 3dd/TrQLdWeahMriNvyLXNvanDbdLDB1tWf/ISSBIahfqMBWl1zwTgbcnaV7AAZqcC kVjzDNNEhVhy7rmk3k8Cco9PZYhDyT9jLvHUpKH4= From: David Ahern To: netdev@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, assogba.emery@gmail.com, dsahern@gmail.com, David Ahern Subject: [PATCH RFC net-next 8/8] selftests: Add active-backup nexthop tests Date: Tue, 9 Jun 2020 21:49:53 -0600 Message-Id: <20200610034953.28861-9-dsahern@kernel.org> X-Mailer: git-send-email 2.21.1 (Apple Git-122.3) In-Reply-To: <20200610034953.28861-1-dsahern@kernel.org> References: <20200610034953.28861-1-dsahern@kernel.org> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Signed-off-by: David Ahern --- tools/testing/selftests/net/fib_nexthops.sh | 334 +++++++++++++++++++- 1 file changed, 330 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/net/fib_nexthops.sh b/tools/testing/selftests/net/fib_nexthops.sh index dee567f7576a..4db390438885 100755 --- a/tools/testing/selftests/net/fib_nexthops.sh +++ b/tools/testing/selftests/net/fib_nexthops.sh @@ -5,11 +5,21 @@ # 2001:db8:91::1 | 2001:db8:91::2 | # 172.16.1.1 | 172.16.1.2 | # veth1 <---|---> veth2 | -# | veth5 <--|--> veth6 172.16.101.1 +# | veth6 <--|--> veth5 172.16.101.1 # veth3 <---|---> veth4 | 2001:db8:101::1 # 172.16.2.1 | 172.16.2.2 | # 2001:db8:92::1 | 2001:db8:92::2 | # +# For active/backup testing: +# ns: me | ns: peer2 | ns: remote +# 2001:db8:81::1 | 2001:db8:81::2 | +# 172.16.81.1 | 172.16.81.2 | +# veth21 <---|---> veth22 | +# | veth26 <--|--> veth25 <--> br +# veth23 <---|---> veth24 | +# 172.16.82.1 | 172.16.82.2 | +# 2001:db8:82::1 | 2001:db8:82::2 | +# # This test is for checking IPv4 and IPv6 FIB behavior with nexthop # objects. Device reference counts and network namespace cleanup tested # by use of network namespace for peer. @@ -19,8 +29,8 @@ ret=0 ksft_skip=4 # all tests in this script. Can be overridden with -t option -IPV4_TESTS="ipv4_fcnal ipv4_grp_fcnal ipv4_withv6_fcnal ipv4_fcnal_runtime ipv4_large_grp ipv4_compat_mode ipv4_fdb_grp_fcnal ipv4_torture" -IPV6_TESTS="ipv6_fcnal ipv6_grp_fcnal ipv6_fcnal_runtime ipv6_large_grp ipv6_compat_mode ipv6_fdb_grp_fcnal ipv6_torture" +IPV4_TESTS="ipv4_fcnal ipv4_grp_fcnal ipv4_withv6_fcnal ipv4_fcnal_runtime ipv4_large_grp ipv4_compat_mode ipv4_fdb_grp_fcnal ipv4_torture ipv4_ab_group" +IPV6_TESTS="ipv6_fcnal ipv6_grp_fcnal ipv6_fcnal_runtime ipv6_large_grp ipv6_compat_mode ipv6_fdb_grp_fcnal ipv6_torture ipv6_ab_group" ALL_TESTS="basic ${IPV4_TESTS} ${IPV6_TESTS}" TESTS="${ALL_TESTS}" @@ -179,11 +189,60 @@ setup() set +e } +setup_ab() +{ + create_ns peer2 + + set -e + $IP li add veth21 type veth peer name veth22 + $IP li set veth21 up + $IP addr add 172.16.81.1/24 dev veth21 + $IP -6 addr add 2001:db8:81::1/64 dev veth21 nodad + + $IP li add veth23 type veth peer name veth24 + $IP li set veth23 up + $IP addr add 172.16.82.1/24 dev veth23 + $IP -6 addr add 2001:db8:82::1/64 dev veth23 nodad + + $IP li set veth22 netns peer2 up + ip -netns peer2 addr add 172.16.81.2/24 dev veth22 + ip -netns peer2 -6 addr add 2001:db8:81::2/64 dev veth22 nodad + + $IP li set veth24 netns peer2 up + ip -netns peer2 addr add 172.16.82.2/24 dev veth24 + ip -netns peer2 -6 addr add 2001:db8:82::2/64 dev veth24 nodad + + ip -netns remote li set veth5 down + ip -netns remote addr flush dev veth5 + ip -netns remote li add br0 type bridge + ip -netns remote li add veth25 type veth peer name veth26 + ip -netns remote li set veth25 master br0 up + ip -netns remote li set veth5 master br0 up + ip -netns remote li set br0 up + + ip -netns remote addr add dev br0 172.16.101.1/24 + ip -netns remote -6 addr add dev br0 2001:db8:101::1/64 nodad + + ip -netns remote li set veth26 netns peer2 up + ip -netns peer2 addr add dev veth26 172.16.101.3/24 + ip -netns peer2 -6 addr add dev veth26 2001:db8:101::3/64 nodad + + ip -netns remote ro add 172.16.1.0/24 nexthop via 172.16.101.2 + ip -netns remote ro add 172.16.2.0/24 nexthop via 172.16.101.2 + ip -netns remote ro add 172.16.81.0/24 nexthop via 172.16.101.3 + ip -netns remote ro add 172.16.82.0/24 nexthop via 172.16.101.3 + ip -netns remote -6 ro add 2001:db8:91::/64 nexthop via 2001:db8:101::2 + ip -netns remote -6 ro add 2001:db8:92::/64 nexthop via 2001:db8:101::2 + ip -netns remote -6 ro add 2001:db8:81::/64 nexthop via 2001:db8:101::3 + ip -netns remote -6 ro add 2001:db8:82::/64 nexthop via 2001:db8:101::3 + set +e +} + cleanup() { local ns - for ns in me peer remote; do + for ns in me peer peer2 remote; do ip netns del ${ns} 2>/dev/null done } @@ -335,6 +394,273 @@ stop_ip_monitor() return $rc } +################################################################################ +# active-backup nexthops + +check_nexthop_ab_support() +{ + $IP nexthop help 2>&1 | grep -q active-backup + if [ $? -ne 0 ]; then + echo "SKIP: iproute2 too old, missing active-backup nexthop support" + return $ksft_skip + fi +} + +ipv6_ab_group() +{ + local rc + + echo + echo "IPv6 active-backup groups" + echo "-------------------------" + + check_nexthop_ab_support + if [ $? -eq $ksft_skip ]; then + return $ksft_skip + fi + + setup_ab + + run_cmd "$IP nexthop add id 11 via 2001:db8:91::2 dev veth1" + run_cmd "$IP nexthop add id 12 via 2001:db8:81::2 dev veth21" + run_cmd "$IP nexthop add id 101 group 11/12 active-backup" + check_nexthop "id 101" "id 101 group 11/12 active-backup" + log_test $? 0 "Create active-backup group" + + run_cmd "$IP ro add 2001:db8:101::/64 nhid 101" + check_route6 "2001:db8:101::1" "2001:db8:101::/64 nhid 101 via 2001:db8:91::2 dev veth1 metric 1024" + log_test $? 0 "Route list shows active device" + + $IP -o ro get 2001:db8:101::1 2>/dev/null | grep -q "dev veth1" + log_test $? 0 "Route get shows active device" + + # carrier down or admin down on nexthop device removes that entry + run_cmd "ip -netns peer li set veth2 down" + check_nexthop "id 101" "id 101 group 12 active-backup" + log_test $? 0 "Carrier down removes active" + + $IP -o ro get 2001:db8:101::1 2>/dev/null | grep -q "dev veth21" + log_test $? 0 "Route get shows backup device" + + run_cmd "$IP li set veth21 down" + $IP nexthop sh id 101 2>/dev/null + log_test $? 2 "Link down on backup removes nexthop" + + check_route "2001:db8:101::1" "" + log_test $? 0 "Route removed after a-b nexthop removed" + + # restore device state + run_cmd "ip -netns peer li set veth2 up" + run_cmd "$IP li set veth21 up" + + # a/b with mpath + run_cmd "$IP nexthop flush" + run_cmd "$IP nexthop add id 11 via 2001:db8:91::2 dev veth1" + run_cmd "$IP nexthop add id 12 via 2001:db8:92::2 dev veth3" + run_cmd "$IP nexthop add id 21 via 2001:db8:81::2 dev veth21" + run_cmd "$IP nexthop add id 22 via 2001:db8:82::2 dev veth23" + run_cmd "$IP nexthop add id 101 group 11/21 active-backup" + run_cmd "$IP nexthop add id 102 group 12/22 active-backup" + run_cmd "$IP nexthop add id 103 group 101/102" + log_test $? 0 "Multipath with active-backup paths" + + run_cmd "$IP nexthop ls" + run_cmd "$IP ro add 2001:db8:101::/64 nhid 103" + run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1" + log_test $? 0 "ping with multipath containing active-backup paths" + + run_cmd "ip -netns peer li set veth2 down" + check_nexthop "id 103" "id 103 group 101/102" + log_test $? 0 "Multipath still shows 2 paths after carrier down in a/b" + + run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1" + log_test $? 0 "ping with still works after carrier down" + + run_cmd "ip -netns peer li set veth2 up" + run_cmd "$IP nexthop ls" + run_cmd "$IP -6 ro ls" + + run_cmd "$IP li set veth21 down" + check_nexthop "id 103" "id 103 group 102" + log_test $? 0 "Multipath shows 1 path after admin down on new active" + run_cmd "ip netns exec me ping -c1 -w1 2001:db8:101::1" + log_test $? 0 "ping with still works after mpath loss of a-b path" + + run_cmd "$IP li set veth21 up" + run_cmd "$IP nexthop ls" + run_cmd "$IP -6 ro ls" + + # + # negative tests + # + # active points to invalid gw + run_cmd "$IP nexthop flush" + run_cmd "$IP nexthop add id 11 via 2001:db8:91::3 dev veth1" + run_cmd "$IP nexthop add id 12 via 2001:db8:81::2 dev veth21" + run_cmd "$IP nexthop add id 101 group 11/12 active-backup" + run_cmd "$IP ro add 2001:db8:101::/64 nhid 101" + + # failed neigh for gateway - should fallback to backup + run_cmd "${IP} -6 neigh add 2001:db8:91::3 dev veth1 nud failed" + $IP -o ro get 2001:db8:101::1 2>/dev/null | grep -q "dev veth21" + log_test $? 0 "Route get shows backup device with invalid neigh" + + run_cmd "$IP nexthop flush" + run_cmd "$IP nexthop add id 11 via 2001:db8:91::2 dev veth1" + run_cmd "$IP nexthop add id 12 via 2001:db8:92::2 dev veth3" + run_cmd "$IP nexthop add id 13 blackhole" + run_cmd "$IP nexthop add id 21 via 2001:db8:81::2 dev veth21" + run_cmd "$IP nexthop add id 22 via 2001:db8:82::2 dev veth23" + + # must have 2 entries of equal weight + run_cmd "$IP nexthop add id 101 group 11 active-backup" + log_test $? 2 "Active-backup nexthop can not have 1 entry" + run_cmd "$IP nexthop add id 101 group 11/12/21 active-backup" + log_test $? 2 "Active-backup nexthop can not have more than 2 entries" + run_cmd "$IP nexthop add id 101 group 11,5/21,4 active-backup" + log_test $? 2 "Active-backup nexthops must have equal weight" + run_cmd "$IP nexthop add id 101 group 11,3/21,3 active-backup" + log_test $? 2 "Active-backup nexthops must have default weight" + + # can not replace a/b group with mpath + run_cmd "$IP nexthop add id 101 group 11/21 active-backup" + run_cmd "$IP nexthop replace id 101 group 11/21 mpath" + log_test $? 2 "Can not change group type" + + # a/b group can not have blackhole + run_cmd "$IP nexthop add id 102 group 11/13 active-backup" + log_test $? 2 "Active-backup can use blackhole as a path" +} + +ipv4_ab_group() +{ + local rc + + echo + echo "IPv4 active-backup groups" + echo "-------------------------" + + check_nexthop_ab_support + if [ $? -eq $ksft_skip ]; then + return $ksft_skip + fi + + setup_ab + + run_cmd "$IP nexthop add id 11 via 172.16.1.2 dev veth1" + run_cmd "$IP nexthop add id 12 via 172.16.81.2 dev veth21" + run_cmd "$IP nexthop add id 101 group 11/12 active-backup" + check_nexthop "id 101" "id 101 group 11/12 active-backup" + log_test $? 0 "Create active-backup group" + + run_cmd "$IP ro add 172.16.101.0/24 nhid 101" + check_route "172.16.101.1" "172.16.101.0/24 nhid 101 via 172.16.1.2 dev veth1" + log_test $? 0 "Route list shows active device" + + $IP -o ro get 172.16.101.1 2>/dev/null | grep -q "dev veth1" + log_test $? 0 "Route get shows active device" + + # carrier down or admin down on nexthop device removes that entry + run_cmd "ip -netns peer li set veth2 down" + check_nexthop "id 101" "id 101 group 12 active-backup" + log_test $? 0 "Carrier down removes active" + + $IP -o ro get 172.16.101.1 2>/dev/null | grep -q "dev veth21" + log_test $? 0 "Route get shows backup device" + + run_cmd "$IP li set veth21 down" + $IP nexthop sh id 101 2>/dev/null + log_test $? 2 "Link down on backup removes nexthop" + + check_route "172.16.101.1" "" + log_test $? 0 "Route removed after a-b nexthop removed" + + # restore device state + run_cmd "ip -netns peer li set veth2 up" + run_cmd "$IP li set veth21 up" + + # a/b with mpath + run_cmd "$IP nexthop flush" + run_cmd "$IP nexthop add id 11 via 172.16.1.2 dev veth1" + run_cmd "$IP nexthop add id 12 via 172.16.2.2 dev veth3" + run_cmd "$IP nexthop add id 21 via 172.16.81.2 dev veth21" + run_cmd "$IP nexthop add id 22 via 172.16.82.2 dev veth23" + run_cmd "$IP nexthop add id 101 group 11/21 active-backup" + run_cmd "$IP nexthop add id 102 group 12/22 active-backup" + run_cmd "$IP nexthop add id 103 group 101/102" + log_test $? 0 "Multipath with active-backup paths" + + run_cmd "$IP nexthop ls" + run_cmd "$IP ro add 172.16.101.0/24 nhid 103" + run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" + log_test $? 0 "ping with multipath containing active-backup paths" + + run_cmd "ip -netns peer li set veth2 down" + check_nexthop "id 103" "id 103 group 101/102" + log_test $? 0 "Multipath still shows 2 paths after carrier down in a/b" + + run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" + log_test $? 0 "ping with still works after carrier down" + + run_cmd "ip -netns peer li set veth2 up" + run_cmd "$IP nexthop ls" + run_cmd "$IP ro ls" + + run_cmd "$IP li set veth21 down" + check_nexthop "id 103" "id 103 group 102" + log_test $? 0 "Multipath shows 1 path after admin down on new active" + run_cmd "ip netns exec me ping -c1 -w1 172.16.101.1" + log_test $? 0 "ping with still works after mpath loss of a-b path" + + run_cmd "$IP li set veth21 up" + run_cmd "$IP nexthop ls" + run_cmd "$IP ro ls" + + # + # negative tests + # + # active points to invalid gw + run_cmd "$IP nexthop flush" + run_cmd "$IP nexthop add id 11 via 172.16.1.3 dev veth1" + run_cmd "$IP nexthop add id 12 via 172.16.81.2 dev veth21" + run_cmd "$IP nexthop add id 101 group 11/12 active-backup" + run_cmd "$IP ro add 172.16.101.0/24 nhid 101" + + # failed neigh for gateway - should fallback to backup + run_cmd "${IP} neigh add 172.16.1.3 dev veth1 nud failed" + $IP -o ro get 172.16.101.1 2>/dev/null | grep -q "dev veth21" + log_test $? 0 "Route get shows backup device with invalid neigh" + + run_cmd "$IP nexthop flush" + run_cmd "$IP nexthop add id 11 via 172.16.1.2 dev veth1" + run_cmd "$IP nexthop add id 12 via 172.16.2.2 dev veth3" + run_cmd "$IP nexthop add id 13 blackhole" + run_cmd "$IP nexthop add id 21 via 172.16.81.2 dev veth21" + run_cmd "$IP nexthop add id 22 via 172.16.82.2 dev veth23" + + # must have 2 entries of equal weight + run_cmd "$IP nexthop add id 101 group 11 active-backup" + log_test $? 2 "Active-backup nexthop can not have 1 entry" + run_cmd "$IP nexthop add id 101 group 11/12/21 active-backup" + log_test $? 2 "Active-backup nexthop can not have more than 2 entries" + run_cmd "$IP nexthop add id 101 group 11,5/21,4 active-backup" + log_test $? 2 "Active-backup nexthops must have equal weight" + run_cmd "$IP nexthop add id 101 group 11,3/21,3 active-backup" + log_test $? 2 "Active-backup nexthops must have default weight" + + # can not replace a/b group with mpath + run_cmd "$IP nexthop add id 101 group 11/21 active-backup" + run_cmd "$IP nexthop replace id 101 group 11/21 mpath" + log_test $? 2 "Can not change group type" + + # a/b group can not have blackhole + run_cmd "$IP nexthop add id 102 group 11/13 active-backup" + log_test $? 2 "Active-backup can use blackhole as a path" +} + +################################################################################ +# fdb nexthops + check_nexthop_fdb_support() { $IP nexthop help 2>&1 | grep -q fdb