From patchwork Sat Mar 20 22:34:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 12152705 X-Patchwork-Delegate: kuba@kernel.org 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=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 2D522C433E2 for ; Sat, 20 Mar 2021 22:36:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F156161937 for ; Sat, 20 Mar 2021 22:36:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229933AbhCTWf2 (ORCPT ); Sat, 20 Mar 2021 18:35:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44032 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229805AbhCTWfW (ORCPT ); Sat, 20 Mar 2021 18:35:22 -0400 Received: from mail-ed1-x52c.google.com (mail-ed1-x52c.google.com [IPv6:2a00:1450:4864:20::52c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 08173C061574; Sat, 20 Mar 2021 15:35:22 -0700 (PDT) Received: by mail-ed1-x52c.google.com with SMTP id h13so14959554eds.5; Sat, 20 Mar 2021 15:35:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=rw+kglmFcQnryQjzxMm2RqClK1crzr9d9kBr/GNKjX4=; b=neLfK1xDeWrLSdFFdduHV9nQShTeuPxiwxACh93SZIIqdSYfnc6JSNXXhLQGd8Tron R5m4p4OYU+yKoiv+Qd6jWaLHoSVwJUzYjUfS2gYRvCLA8c/LHkD1s23eGbpU3UYrpPYb HmLMdc3e7ZBkui38R8OY2eCoK4FXbtzOlrYlMwx7a5PvXeUd39kc5fPvX6/wE3+qldHd lNBusAVAZAVjX4wApkjEqQZ7oVJDyW7LdcWKIRA3przQ0VIHuB/GTK3tUyHA8YkevKUn pa+px6wr95gSEmpUsiWMxvk6/FUihzRY5aKWSx9c7k6GhP08ULQHqnhKFxRfpvBXScgK TjEA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=rw+kglmFcQnryQjzxMm2RqClK1crzr9d9kBr/GNKjX4=; b=RfIS5RJA1i4MglIEpjxbCpr9SvCAPADowng89mwxFlKG9KGmk618jBz9ecxid8tXEZ NCPY7x17yrvsxS+ELPsdi5j4erbNmIchheG9W/n9d751J74S5k/1ldUs11P1GRTd+hmP QbQlbXDBaCa//MISMmhB675G/tSJSylCeIHYcJSHT+OUYiWR+7vhJqv6KDRYEjeve4zP tY5fdEbC7gbwJs0cReDBMwRjnGd5GLbMRXxo//QqT35t6QEXe96KqEYvTMesiDYlHtXA h6X/VYXG0EFKx9w2yGgAFYyDXc5jHodYJMHJ9NE9E6YOcREFtADwYv7p+1ao5yk+iGag /Y0A== X-Gm-Message-State: AOAM5313ioZhkMZxnj8T6N3zpvzhustcXfd8oLlCD5lQMAlnZX6LHQE7 xfxj3KgybujPoS3SphZ9vKo= X-Google-Smtp-Source: ABdhPJxJ0FRWJboeCx54HGNCYeYOxE65AzmJ3ANIpTr4IgXa51k+WSaQaVHnnzUGvsWUFro03YttPA== X-Received: by 2002:a05:6402:27d3:: with SMTP id c19mr17773003ede.129.1616279720799; Sat, 20 Mar 2021 15:35:20 -0700 (PDT) Received: from localhost.localdomain (5-12-16-165.residential.rdsnet.ro. [5.12.16.165]) by smtp.gmail.com with ESMTPSA id n2sm6090850ejl.1.2021.03.20.15.35.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 20 Mar 2021 15:35:20 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" Cc: Andrew Lunn , Vivien Didelot , Florian Fainelli , Tobias Waldekranz , Claudiu Manoil , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Roopa Prabhu , Nikolay Aleksandrov , Jiri Pirko , Ido Schimmel , Alexandre Belloni , UNGLinuxDriver@microchip.com, Ivan Vecera , linux-omap@vger.kernel.org, Vladimir Oltean Subject: [PATCH v3 net-next 01/12] net: dsa: call dsa_port_bridge_join when joining a LAG that is already in a bridge Date: Sun, 21 Mar 2021 00:34:37 +0200 Message-Id: <20210320223448.2452869-2-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210320223448.2452869-1-olteanv@gmail.com> References: <20210320223448.2452869-1-olteanv@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org From: Vladimir Oltean DSA can properly detect and offload this sequence of operations: ip link add br0 type bridge ip link add bond0 type bond ip link set swp0 master bond0 ip link set bond0 master br0 But not this one: ip link add br0 type bridge ip link add bond0 type bond ip link set bond0 master br0 ip link set swp0 master bond0 Actually the second one is more complicated, due to the elapsed time between the enslavement of bond0 and the offloading of it via swp0, a lot of things could have happened to the bond0 bridge port in terms of switchdev objects (host MDBs, VLANs, altered STP state etc). So this is a bit of a can of worms, and making sure that the DSA port's state is in sync with this already existing bridge port is handled in the next patches. Signed-off-by: Vladimir Oltean Reviewed-by: Florian Fainelli --- Changes in v3: None. net/dsa/port.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/net/dsa/port.c b/net/dsa/port.c index c9c6d7ab3f47..d39262a9fe0e 100644 --- a/net/dsa/port.c +++ b/net/dsa/port.c @@ -249,17 +249,31 @@ int dsa_port_lag_join(struct dsa_port *dp, struct net_device *lag, .lag = lag, .info = uinfo, }; + struct net_device *bridge_dev; int err; dsa_lag_map(dp->ds->dst, lag); dp->lag_dev = lag; err = dsa_port_notify(dp, DSA_NOTIFIER_LAG_JOIN, &info); - if (err) { - dp->lag_dev = NULL; - dsa_lag_unmap(dp->ds->dst, lag); - } + if (err) + goto err_lag_join; + bridge_dev = netdev_master_upper_dev_get(lag); + if (!bridge_dev || !netif_is_bridge_master(bridge_dev)) + return 0; + + err = dsa_port_bridge_join(dp, bridge_dev); + if (err) + goto err_bridge_join; + + return 0; + +err_bridge_join: + dsa_port_notify(dp, DSA_NOTIFIER_LAG_LEAVE, &info); +err_lag_join: + dp->lag_dev = NULL; + dsa_lag_unmap(dp->ds->dst, lag); return err; } From patchwork Sat Mar 20 22:34:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 12152707 X-Patchwork-Delegate: kuba@kernel.org 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=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 56EA9C433E8 for ; Sat, 20 Mar 2021 22:36:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3D4D661937 for ; Sat, 20 Mar 2021 22:36:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229972AbhCTWf3 (ORCPT ); Sat, 20 Mar 2021 18:35:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44048 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229815AbhCTWfX (ORCPT ); Sat, 20 Mar 2021 18:35:23 -0400 Received: from mail-ej1-x62a.google.com (mail-ej1-x62a.google.com [IPv6:2a00:1450:4864:20::62a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 55E0AC061574; Sat, 20 Mar 2021 15:35:23 -0700 (PDT) Received: by mail-ej1-x62a.google.com with SMTP id k10so15306840ejg.0; Sat, 20 Mar 2021 15:35:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=RUGlH2C/m3NuHZvHEgwn1gs0Ssb5YYPGSM/24Rpcs0w=; b=eZjuYKWgoCGA4mx3ZSrvp3+wjDfhngpVLwrmL7TiGCtVkUyLnLIYKKaO9MChAW4g0q TEbkvONJ5VXqV9EjLSx/iagvzwlvI54cZVIHKR/9IVvefRI7wtJ1N6B+eB5i9SDSJ5nb HF4xw2CQNs/1qFHzelbptHoynzgQ/EJNeYVUHABuUu8lXE5dGKDOG6RiGSJFmNILu+Cc rq2bv4vKKxllkgzsDmHnKXJ0MWh8LF4clYj91pjPZhfWn4r8nhlCInr3gNjHQiSQr62o Q4nY3HscKNcOYaTTLtc8+tgJqAMp0nYZeLbSlpZJH/HNctfi0pHCl7ANJGLOEx/cYXfw w87A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=RUGlH2C/m3NuHZvHEgwn1gs0Ssb5YYPGSM/24Rpcs0w=; b=n0YDK6ORQqTbtie5A2KndacpfiDtCwjpOIvyOsMCaXNlNCtZHhwJ07Mof53aGYlneK ioxIMiwnmebRYmKnp3qHC64dNcdZHEJNOFxCXgx3nCVtW6JSgQPuYqSSj8kymczNgbXI ZnR1Rk8YTOSuxkYf8YkETbeMGTMD3bRQ1uAFI1bEakohh7CYVsRe9g2mEKEDUBrtOodf o0/w3cwxrHgA45H6EWGtvsF01VL/yvkmS2ItCY08EYkEIZoFcqMndTRXAhN8hCn9OHKh 5EY1NeFVwkjiigrzFVgVbefB17C+OYegTFz7oovYpKvB2XdSvbBKlJ2nxjIM1rtBbumI XwCg== X-Gm-Message-State: AOAM533QnK6PDSLY4nfTiq8v7SjPMG34ZUmvVXg+rmTb6fREd3oOuPVO mhCCtVFrjPrQFaKsaZv8tmQ= X-Google-Smtp-Source: ABdhPJyOQCaRUtehiroXYVa0ftRRJkMrgX2YeJ3Gj5kH9ulTp7B/WxkLrqTZuZXGzIp/szqi1C+PsQ== X-Received: by 2002:a17:906:1a16:: with SMTP id i22mr11789473ejf.522.1616279722081; Sat, 20 Mar 2021 15:35:22 -0700 (PDT) Received: from localhost.localdomain (5-12-16-165.residential.rdsnet.ro. [5.12.16.165]) by smtp.gmail.com with ESMTPSA id n2sm6090850ejl.1.2021.03.20.15.35.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 20 Mar 2021 15:35:21 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" Cc: Andrew Lunn , Vivien Didelot , Florian Fainelli , Tobias Waldekranz , Claudiu Manoil , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Roopa Prabhu , Nikolay Aleksandrov , Jiri Pirko , Ido Schimmel , Alexandre Belloni , UNGLinuxDriver@microchip.com, Ivan Vecera , linux-omap@vger.kernel.org, Vladimir Oltean Subject: [PATCH v3 net-next 02/12] net: dsa: pass extack to dsa_port_{bridge,lag}_join Date: Sun, 21 Mar 2021 00:34:38 +0200 Message-Id: <20210320223448.2452869-3-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210320223448.2452869-1-olteanv@gmail.com> References: <20210320223448.2452869-1-olteanv@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org From: Vladimir Oltean This is a pretty noisy change that was broken out of the larger change for replaying switchdev attributes and objects at bridge join time, which is when these extack objects are actually used. Signed-off-by: Vladimir Oltean Reviewed-by: Florian Fainelli --- Changes in v3: None. net/dsa/dsa_priv.h | 6 ++++-- net/dsa/port.c | 8 +++++--- net/dsa/slave.c | 7 +++++-- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h index 4c43c5406834..b8778c5d8529 100644 --- a/net/dsa/dsa_priv.h +++ b/net/dsa/dsa_priv.h @@ -181,12 +181,14 @@ int dsa_port_enable_rt(struct dsa_port *dp, struct phy_device *phy); int dsa_port_enable(struct dsa_port *dp, struct phy_device *phy); void dsa_port_disable_rt(struct dsa_port *dp); void dsa_port_disable(struct dsa_port *dp); -int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br); +int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br, + struct netlink_ext_ack *extack); void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br); int dsa_port_lag_change(struct dsa_port *dp, struct netdev_lag_lower_state_info *linfo); int dsa_port_lag_join(struct dsa_port *dp, struct net_device *lag_dev, - struct netdev_lag_upper_info *uinfo); + struct netdev_lag_upper_info *uinfo, + struct netlink_ext_ack *extack); void dsa_port_lag_leave(struct dsa_port *dp, struct net_device *lag_dev); int dsa_port_vlan_filtering(struct dsa_port *dp, bool vlan_filtering, struct netlink_ext_ack *extack); diff --git a/net/dsa/port.c b/net/dsa/port.c index d39262a9fe0e..fcbe5b1545b8 100644 --- a/net/dsa/port.c +++ b/net/dsa/port.c @@ -144,7 +144,8 @@ static void dsa_port_change_brport_flags(struct dsa_port *dp, } } -int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br) +int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br, + struct netlink_ext_ack *extack) { struct dsa_notifier_bridge_info info = { .tree_index = dp->ds->dst->index, @@ -241,7 +242,8 @@ int dsa_port_lag_change(struct dsa_port *dp, } int dsa_port_lag_join(struct dsa_port *dp, struct net_device *lag, - struct netdev_lag_upper_info *uinfo) + struct netdev_lag_upper_info *uinfo, + struct netlink_ext_ack *extack) { struct dsa_notifier_lag_info info = { .sw_index = dp->ds->index, @@ -263,7 +265,7 @@ int dsa_port_lag_join(struct dsa_port *dp, struct net_device *lag, if (!bridge_dev || !netif_is_bridge_master(bridge_dev)) return 0; - err = dsa_port_bridge_join(dp, bridge_dev); + err = dsa_port_bridge_join(dp, bridge_dev, extack); if (err) goto err_bridge_join; diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 992fcab4b552..1ff48be476bb 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -1976,11 +1976,14 @@ static int dsa_slave_changeupper(struct net_device *dev, struct netdev_notifier_changeupper_info *info) { struct dsa_port *dp = dsa_slave_to_port(dev); + struct netlink_ext_ack *extack; int err = NOTIFY_DONE; + extack = netdev_notifier_info_to_extack(&info->info); + if (netif_is_bridge_master(info->upper_dev)) { if (info->linking) { - err = dsa_port_bridge_join(dp, info->upper_dev); + err = dsa_port_bridge_join(dp, info->upper_dev, extack); if (!err) dsa_bridge_mtu_normalization(dp); err = notifier_from_errno(err); @@ -1991,7 +1994,7 @@ static int dsa_slave_changeupper(struct net_device *dev, } else if (netif_is_lag_master(info->upper_dev)) { if (info->linking) { err = dsa_port_lag_join(dp, info->upper_dev, - info->upper_info); + info->upper_info, extack); if (err == -EOPNOTSUPP) { NL_SET_ERR_MSG_MOD(info->info.extack, "Offloading not supported"); From patchwork Sat Mar 20 22:34:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 12152709 X-Patchwork-Delegate: kuba@kernel.org 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=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 C8A5EC433EA for ; Sat, 20 Mar 2021 22:36:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 925456193D for ; Sat, 20 Mar 2021 22:36:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230002AbhCTWfg (ORCPT ); Sat, 20 Mar 2021 18:35:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44060 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229817AbhCTWfZ (ORCPT ); Sat, 20 Mar 2021 18:35:25 -0400 Received: from mail-ed1-x52b.google.com (mail-ed1-x52b.google.com [IPv6:2a00:1450:4864:20::52b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9EF06C061574; Sat, 20 Mar 2021 15:35:24 -0700 (PDT) Received: by mail-ed1-x52b.google.com with SMTP id y6so14983525eds.1; Sat, 20 Mar 2021 15:35:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=609vYmEBQlG9DIOzYR2UIfsCPKO7cez08yFjDbHyHrQ=; b=iDjVW0d4wIhntmW1WqjPYPeoJKWfA0uny+pd9ZFRkdlP2pJs5V26l52Top7p21yJDl DNdA+amzqMmLMk4dUrjt4ErVXXvr1UzGeL0TEQKLbyr4Ula0A7S8hL6SP8SMwK8Q8Mw6 t7G24o72zcBqrhZDjgYrtlVtkHWJFPl0BqA1uHyQ8YzvdipVU6GecuhwusLVl9MpT2eY mfx/NO5PjoL2BmlGtEU+nhkkkwSkPSr9+mmF4t9ZtD6u+AynfdRWBQr1afgSxbxAVVSQ RqEgR/5R+nTuz9zZSWPO+ZQXWtGadtXJAWX35mZ4Wy58K5zQJAeMMHy4UVuMecD2qyhc iFWA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=609vYmEBQlG9DIOzYR2UIfsCPKO7cez08yFjDbHyHrQ=; b=hx0BFye2+nGxu3clLqxMHu9n7Ul+U/zm61wEwZJF28H7XSWa1T8KzZWOPUYIDhMxYx AK5BaY18RERtBqxEqCkwuMUnR/Vpj9Pqm4lemizARMXMZH4sy2G52iULeu1Q5z5XQrdF sFFbNkhnUQe+vHCJFWQOPzIYZdPpPpgqZd7rfXlmK3J/VJGq9ur25qgw7mAGQC9Wo5o1 Z4ZXC9S51SjUXghTAAw/xFtxcB/tmXobE+egdqLafMVzrMz75hJHQyPTuQMi64XA1dJc CzxvnFfANPdL2XFIEhVeZd2nPe3idLjOghCdVjDiqjCCeZCCSuVgkzQPpiSpfiPpgRHV guFw== X-Gm-Message-State: AOAM5338NbDcY3RIewzKVOJk/4LhF6ohMyLQeZOD+tgYdwg2b0mDd5Qe n/a37IWmLsuLhR3/PiIPJgs= X-Google-Smtp-Source: ABdhPJzvqEvaEivhnNPt7T8XkPrV2l7CH72BZMyQZ2hxG5PM0Gkapc7vz/LC8V0Lm9SB7aeqK087Mg== X-Received: by 2002:a50:d753:: with SMTP id i19mr17580294edj.43.1616279723369; Sat, 20 Mar 2021 15:35:23 -0700 (PDT) Received: from localhost.localdomain (5-12-16-165.residential.rdsnet.ro. [5.12.16.165]) by smtp.gmail.com with ESMTPSA id n2sm6090850ejl.1.2021.03.20.15.35.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 20 Mar 2021 15:35:23 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" Cc: Andrew Lunn , Vivien Didelot , Florian Fainelli , Tobias Waldekranz , Claudiu Manoil , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Roopa Prabhu , Nikolay Aleksandrov , Jiri Pirko , Ido Schimmel , Alexandre Belloni , UNGLinuxDriver@microchip.com, Ivan Vecera , linux-omap@vger.kernel.org, Vladimir Oltean Subject: [PATCH v3 net-next 03/12] net: dsa: inherit the actual bridge port flags at join time Date: Sun, 21 Mar 2021 00:34:39 +0200 Message-Id: <20210320223448.2452869-4-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210320223448.2452869-1-olteanv@gmail.com> References: <20210320223448.2452869-1-olteanv@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org From: Vladimir Oltean DSA currently assumes that the bridge port starts off with this constellation of bridge port flags: - learning on - unicast flooding on - multicast flooding on - broadcast flooding on just by virtue of code copy-pasta from the bridge layer (new_nbp). This was a simple enough strategy thus far, because the 'bridge join' moment always coincided with the 'bridge port creation' moment. But with sandwiched interfaces, such as: br0 | bond0 | swp0 it may happen that the user has had time to change the bridge port flags of bond0 before enslaving swp0 to it. In that case, swp0 will falsely assume that the bridge port flags are those determined by new_nbp, when in fact this can happen: ip link add br0 type bridge ip link add bond0 type bond ip link set bond0 master br0 ip link set bond0 type bridge_slave learning off ip link set swp0 master br0 Now swp0 has learning enabled, bond0 has learning disabled. Not nice. Fix this by "dumpster diving" through the actual bridge port flags with br_port_flag_is_set, at bridge join time. We use this opportunity to split dsa_port_change_brport_flags into two distinct functions called dsa_port_inherit_brport_flags and dsa_port_clear_brport_flags, now that the implementation for the two cases is no longer similar. Signed-off-by: Vladimir Oltean Reported-by: kernel test robot Reported-by: kernel test robot --- Changes in v3: Rewrote dsa_port_clear_brport_flags to at least catch errors, and to use the same "for" loop structure as dsa_port_inherit_brport_flags. net/dsa/port.c | 125 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 83 insertions(+), 42 deletions(-) diff --git a/net/dsa/port.c b/net/dsa/port.c index fcbe5b1545b8..8dbc6e0db30c 100644 --- a/net/dsa/port.c +++ b/net/dsa/port.c @@ -122,26 +122,82 @@ void dsa_port_disable(struct dsa_port *dp) rtnl_unlock(); } -static void dsa_port_change_brport_flags(struct dsa_port *dp, - bool bridge_offload) +static int dsa_port_inherit_brport_flags(struct dsa_port *dp, + struct netlink_ext_ack *extack) { - struct switchdev_brport_flags flags; - int flag; + const unsigned long mask = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | + BR_BCAST_FLOOD; + struct net_device *brport_dev = dsa_port_to_bridge_port(dp); + int flag, err; - flags.mask = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD; - if (bridge_offload) - flags.val = flags.mask; - else - flags.val = flags.mask & ~BR_LEARNING; + for_each_set_bit(flag, &mask, 32) { + struct switchdev_brport_flags flags = {0}; - for_each_set_bit(flag, &flags.mask, 32) { - struct switchdev_brport_flags tmp; + flags.mask = BIT(flag); - tmp.val = flags.val & BIT(flag); - tmp.mask = BIT(flag); + if (br_port_flag_is_set(brport_dev, BIT(flag))) + flags.val = BIT(flag); - dsa_port_bridge_flags(dp, tmp, NULL); + err = dsa_port_bridge_flags(dp, flags, extack); + if (err && err != -EOPNOTSUPP) + return err; } + + return 0; +} + +static void dsa_port_clear_brport_flags(struct dsa_port *dp, + struct netlink_ext_ack *extack) +{ + const unsigned long val = BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD; + const unsigned long mask = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | + BR_BCAST_FLOOD; + int flag, err; + + for_each_set_bit(flag, &mask, 32) { + struct switchdev_brport_flags flags = {0}; + + flags.mask = BIT(flag); + flags.val = val & BIT(flag); + + err = dsa_port_bridge_flags(dp, flags, extack); + if (err && err != -EOPNOTSUPP) + dev_err(dp->ds->dev, + "failed to clear bridge port flag %d: %d (%pe)\n", + flags.val, err, ERR_PTR(err)); + } +} + +static int dsa_port_switchdev_sync(struct dsa_port *dp, + struct netlink_ext_ack *extack) +{ + int err; + + err = dsa_port_inherit_brport_flags(dp, extack); + if (err) + return err; + + return 0; +} + +/* Configure the port for standalone mode (no address learning, flood + * everything, BR_STATE_FORWARDING, etc). + * The bridge only emits SWITCHDEV_ATTR_ID_PORT_* events when the user + * requests it through netlink or sysfs, but not automatically at port + * join or leave, so we need to handle resetting the brport flags ourselves. + * But we even prefer it that way, because otherwise, some setups might never + * get the notification they need, for example, when a port leaves a LAG that + * offloads the bridge, it becomes standalone, but as far as the bridge is + * concerned, no port ever left. + */ +static void dsa_port_switchdev_unsync(struct dsa_port *dp) +{ + dsa_port_clear_brport_flags(dp, NULL); + + /* Port left the bridge, put in BR_STATE_DISABLED by the bridge layer, + * so allow it to be in BR_STATE_FORWARDING to be kept functional + */ + dsa_port_set_state_now(dp, BR_STATE_FORWARDING); } int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br, @@ -155,24 +211,25 @@ int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br, }; int err; - /* Notify the port driver to set its configurable flags in a way that - * matches the initial settings of a bridge port. - */ - dsa_port_change_brport_flags(dp, true); - /* Here the interface is already bridged. Reflect the current * configuration so that drivers can program their chips accordingly. */ dp->bridge_dev = br; err = dsa_broadcast(DSA_NOTIFIER_BRIDGE_JOIN, &info); + if (err) + goto out_rollback; - /* The bridging is rolled back on error */ - if (err) { - dsa_port_change_brport_flags(dp, false); - dp->bridge_dev = NULL; - } + err = dsa_port_switchdev_sync(dp, extack); + if (err) + goto out_rollback_unbridge; + return 0; + +out_rollback_unbridge: + dsa_broadcast(DSA_NOTIFIER_BRIDGE_LEAVE, &info); +out_rollback: + dp->bridge_dev = NULL; return err; } @@ -186,6 +243,8 @@ void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br) }; int err; + dsa_port_switchdev_unsync(dp); + /* Here the port is already unbridged. Reflect the current configuration * so that drivers can program their chips accordingly. */ @@ -194,24 +253,6 @@ void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br) err = dsa_broadcast(DSA_NOTIFIER_BRIDGE_LEAVE, &info); if (err) pr_err("DSA: failed to notify DSA_NOTIFIER_BRIDGE_LEAVE\n"); - - /* Configure the port for standalone mode (no address learning, - * flood everything). - * The bridge only emits SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS events - * when the user requests it through netlink or sysfs, but not - * automatically at port join or leave, so we need to handle resetting - * the brport flags ourselves. But we even prefer it that way, because - * otherwise, some setups might never get the notification they need, - * for example, when a port leaves a LAG that offloads the bridge, - * it becomes standalone, but as far as the bridge is concerned, no - * port ever left. - */ - dsa_port_change_brport_flags(dp, false); - - /* Port left the bridge, put in BR_STATE_DISABLED by the bridge layer, - * so allow it to be in BR_STATE_FORWARDING to be kept functional - */ - dsa_port_set_state_now(dp, BR_STATE_FORWARDING); } int dsa_port_lag_change(struct dsa_port *dp, From patchwork Sat Mar 20 22:34:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 12152749 X-Patchwork-Delegate: kuba@kernel.org 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=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 25140C433E0 for ; Sat, 20 Mar 2021 22:37:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F261C61937 for ; Sat, 20 Mar 2021 22:37:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230051AbhCTWgA (ORCPT ); Sat, 20 Mar 2021 18:36:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44070 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229835AbhCTWf0 (ORCPT ); Sat, 20 Mar 2021 18:35:26 -0400 Received: from mail-ej1-x636.google.com (mail-ej1-x636.google.com [IPv6:2a00:1450:4864:20::636]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D6D1FC061574; Sat, 20 Mar 2021 15:35:25 -0700 (PDT) Received: by mail-ej1-x636.google.com with SMTP id a7so15286005ejs.3; Sat, 20 Mar 2021 15:35:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=uoAitKxY6Wm3fAUsNhRpFwI+ektVXceRmnN56H84oYw=; b=TwxUm1ebl6brytJbAJCTLrZWGI266T/DszMJZ+5RUe9AgtE+WcoclaxTaz9cJKJUEQ 7+8JQfQOgglsCk77eP7Qjx0u2e0MYjtFxrqWki6WFIu/RTIsME6MMdtI124da56OA/at Gf7HkRUmjmphUs0jdlayZQA+HSJsSyTV5KydjCxerJgGoQdSwJj+kjwxOc7trxWkhsSh B/nnUdFyEDMpcklyp19QGSR8otPGUgiMpV/Z5Nv4xXh8E1YEPeopXsGFf2ePm9N3ioMi rJgtB7BiMG0M7FSjT+aTXIy2eUAtl1U6N1LCQYpjkCwZffsI2NYLz4d9ztqYnStvYwz1 9anw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=uoAitKxY6Wm3fAUsNhRpFwI+ektVXceRmnN56H84oYw=; b=mS1uFO/ban3bvmgtT2S9/f0EH1hyweJyxVBiO69SDG2Nvuywp9Ld1E27Lzygbwdj2X 5UKtEMM1kBu6UEzIBgHZ660cqS0W7WtgRx2SvTw8shb/UuwbBdrm8oCZFYyDeysMuHqd FActButYZ1DOGeb4DP3QbG8orf8PHkre/CI5errEC5jya0mGadbDNb/kwNrzh05d/gDv OWhjlT2AABI1eH0PnSYCzlNCu53XvR3d47k4lssIN3V0j1aGdk04ijDJJbEcqeZc4qfP lE2MCSpCZKRcq6NKUCk5hFd/9dXIgDzrRNDCAtMe4MRQzzwjfSxOw2G0BbigtZ3OgGFj kkxA== X-Gm-Message-State: AOAM532RLpLY+Fa4asEMROzvLjp0BYrLlaXSfn3wUOod9GHj2wYNPknV aSvrP9UldgEG7YQCJCUPUsc= X-Google-Smtp-Source: ABdhPJwZ+qANVk5Dz01q9updiuAD0xK8qCumTxArrh9EmyN1EUfBkR2yHqXYQ/9I4uqAYnwYdgv7gg== X-Received: by 2002:a17:906:a3d1:: with SMTP id ca17mr11728884ejb.92.1616279724641; Sat, 20 Mar 2021 15:35:24 -0700 (PDT) Received: from localhost.localdomain (5-12-16-165.residential.rdsnet.ro. [5.12.16.165]) by smtp.gmail.com with ESMTPSA id n2sm6090850ejl.1.2021.03.20.15.35.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 20 Mar 2021 15:35:24 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" Cc: Andrew Lunn , Vivien Didelot , Florian Fainelli , Tobias Waldekranz , Claudiu Manoil , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Roopa Prabhu , Nikolay Aleksandrov , Jiri Pirko , Ido Schimmel , Alexandre Belloni , UNGLinuxDriver@microchip.com, Ivan Vecera , linux-omap@vger.kernel.org, Vladimir Oltean Subject: [PATCH v3 net-next 04/12] net: dsa: sync up with bridge port's STP state when joining Date: Sun, 21 Mar 2021 00:34:40 +0200 Message-Id: <20210320223448.2452869-5-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210320223448.2452869-1-olteanv@gmail.com> References: <20210320223448.2452869-1-olteanv@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org From: Vladimir Oltean It may happen that we have the following topology: ip link add br0 type bridge stp_state 1 ip link add bond0 type bond ip link set bond0 master br0 ip link set swp0 master bond0 ip link set swp1 master bond0 STP decides that it should put bond0 into the BLOCKING state, and that's that. The ports that are actively listening for the switchdev port attributes emitted for the bond0 bridge port (because they are offloading it) and have the honor of seeing that switchdev port attribute can react to it, so we can program swp0 and swp1 into the BLOCKING state. But if then we do: ip link set swp2 master bond0 then as far as the bridge is concerned, nothing has changed: it still has one bridge port. But this new bridge port will not see any STP state change notification and will remain FORWARDING, which is how the standalone code leaves it in. Add a function to the bridge which retrieves the current STP state, such that drivers can synchronize to it when they may have missed switchdev events. Signed-off-by: Vladimir Oltean Reviewed-by: Florian Fainelli --- Changes in v3: None. include/linux/if_bridge.h | 6 ++++++ net/bridge/br_stp.c | 14 ++++++++++++++ net/dsa/port.c | 7 +++++++ 3 files changed, 27 insertions(+) diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h index b979005ea39c..920d3a02cc68 100644 --- a/include/linux/if_bridge.h +++ b/include/linux/if_bridge.h @@ -136,6 +136,7 @@ struct net_device *br_fdb_find_port(const struct net_device *br_dev, __u16 vid); void br_fdb_clear_offload(const struct net_device *dev, u16 vid); bool br_port_flag_is_set(const struct net_device *dev, unsigned long flag); +u8 br_port_get_stp_state(const struct net_device *dev); #else static inline struct net_device * br_fdb_find_port(const struct net_device *br_dev, @@ -154,6 +155,11 @@ br_port_flag_is_set(const struct net_device *dev, unsigned long flag) { return false; } + +static inline u8 br_port_get_stp_state(const struct net_device *dev) +{ + return BR_STATE_DISABLED; +} #endif #endif diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c index 21c6781906aa..86b5e05d3f21 100644 --- a/net/bridge/br_stp.c +++ b/net/bridge/br_stp.c @@ -64,6 +64,20 @@ void br_set_state(struct net_bridge_port *p, unsigned int state) } } +u8 br_port_get_stp_state(const struct net_device *dev) +{ + struct net_bridge_port *p; + + ASSERT_RTNL(); + + p = br_port_get_rtnl(dev); + if (!p) + return BR_STATE_DISABLED; + + return p->state; +} +EXPORT_SYMBOL_GPL(br_port_get_stp_state); + /* called under bridge lock */ struct net_bridge_port *br_get_port(struct net_bridge *br, u16 port_no) { diff --git a/net/dsa/port.c b/net/dsa/port.c index 8dbc6e0db30c..2ecdc824ea66 100644 --- a/net/dsa/port.c +++ b/net/dsa/port.c @@ -171,12 +171,19 @@ static void dsa_port_clear_brport_flags(struct dsa_port *dp, static int dsa_port_switchdev_sync(struct dsa_port *dp, struct netlink_ext_ack *extack) { + struct net_device *brport_dev = dsa_port_to_bridge_port(dp); + u8 stp_state; int err; err = dsa_port_inherit_brport_flags(dp, extack); if (err) return err; + stp_state = br_port_get_stp_state(brport_dev); + err = dsa_port_set_state(dp, stp_state); + if (err && err != -EOPNOTSUPP) + return err; + return 0; } From patchwork Sat Mar 20 22:34:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 12152751 X-Patchwork-Delegate: kuba@kernel.org 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=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 5F44DC433E5 for ; Sat, 20 Mar 2021 22:37:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 44DF66146D for ; Sat, 20 Mar 2021 22:37:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230080AbhCTWgD (ORCPT ); Sat, 20 Mar 2021 18:36:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44076 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229772AbhCTWf1 (ORCPT ); Sat, 20 Mar 2021 18:35:27 -0400 Received: from mail-ej1-x630.google.com (mail-ej1-x630.google.com [IPv6:2a00:1450:4864:20::630]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 210DEC061574; Sat, 20 Mar 2021 15:35:27 -0700 (PDT) Received: by mail-ej1-x630.google.com with SMTP id b9so15301428ejc.11; Sat, 20 Mar 2021 15:35:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=FX/gpTHurZv94BWIowZaJ3czNzkfeitN+oQL7QnMW9c=; b=tL4oFig3Pkr6OVUSg/g0NtF9GTJ4U4F6h/XL2uRANZ/LskhtE+ul50rXwwL8FpU8WV hD/0JX9LbH36w4dxToBWM1Ufq6TSiYphYRu4qakOynWMGHineNodCHu22xZvhWwOuKC3 OHLGNf0GmoVjaCJiE38UBVAgFTEfDcuV5wZKxJvpAJlnNHGM8DOJ6KShTDadEqvhV/Ya /4EIUrSUTEvqDkLE1E1pItVN7KISOBh5rDsMZPFuqBH8JjLyEOzMT8qREWf+pvFOBjTQ YGM9RdFl2nciNbW2IrZ43oqCa/tlytLWMdfUBA9GzZnv7WRrPwQhCgRq+lYV6VqFCb4s fluw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=FX/gpTHurZv94BWIowZaJ3czNzkfeitN+oQL7QnMW9c=; b=ToRpBza+VTfDFAEG9KXJ6AwEr+bcX+pNSoBQQbVvfOKTm8ZZzk6EuyawBgdGz0Ooc3 WcTb2E2n0nGxaTuRwmnL9bTJrHYqO7liJk7lHTWsIEvNMOpa22NStkbJhetmddrC0K7v UPjfwh08fAo4Gpmg0t/Ec5u9HeajFThj8uUV3d29+bzJGSVLTGDgc927lMC/HipJ6Z58 HCzE0hHymoknZ++4q9QtO9uD0nUJK5V18ba2+fwJdCKbFvpk3WpSV4JGcAyGvTCpFbSg OjLHhaF02ypEKgSUhMHTcQs0fIimi4eH1EbAwZ5Pmo+Ml0lzYt33lNnaJ+AeA7ZrCDRU xbpQ== X-Gm-Message-State: AOAM532OLx5o5w5ntBIxG6iNX5bdPCKFXNFRBB3ivAPtg3AXQn7tRH+A ndj4RZmo+vK++a58KltGTqo= X-Google-Smtp-Source: ABdhPJy0rzK1nxpNTmRU/uDFvHDZ1kuicf8drxlE3WopPx6BeZiz+yqfB2jE8PfHRD8xK4EaP8uE/w== X-Received: by 2002:a17:906:19d9:: with SMTP id h25mr12087622ejd.453.1616279725936; Sat, 20 Mar 2021 15:35:25 -0700 (PDT) Received: from localhost.localdomain (5-12-16-165.residential.rdsnet.ro. [5.12.16.165]) by smtp.gmail.com with ESMTPSA id n2sm6090850ejl.1.2021.03.20.15.35.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 20 Mar 2021 15:35:25 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" Cc: Andrew Lunn , Vivien Didelot , Florian Fainelli , Tobias Waldekranz , Claudiu Manoil , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Roopa Prabhu , Nikolay Aleksandrov , Jiri Pirko , Ido Schimmel , Alexandre Belloni , UNGLinuxDriver@microchip.com, Ivan Vecera , linux-omap@vger.kernel.org, Vladimir Oltean Subject: [PATCH v3 net-next 05/12] net: dsa: sync up VLAN filtering state when joining the bridge Date: Sun, 21 Mar 2021 00:34:41 +0200 Message-Id: <20210320223448.2452869-6-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210320223448.2452869-1-olteanv@gmail.com> References: <20210320223448.2452869-1-olteanv@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org From: Vladimir Oltean This is the same situation as for other switchdev port attributes: if we join an already-created bridge port, such as a bond master interface, then we can miss the initial switchdev notification emitted by the bridge for this port. Signed-off-by: Vladimir Oltean Reviewed-by: Florian Fainelli --- Changes in v3: None. net/dsa/port.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/net/dsa/port.c b/net/dsa/port.c index 2ecdc824ea66..3f938c253c99 100644 --- a/net/dsa/port.c +++ b/net/dsa/port.c @@ -172,6 +172,7 @@ static int dsa_port_switchdev_sync(struct dsa_port *dp, struct netlink_ext_ack *extack) { struct net_device *brport_dev = dsa_port_to_bridge_port(dp); + struct net_device *br = dp->bridge_dev; u8 stp_state; int err; @@ -184,6 +185,10 @@ static int dsa_port_switchdev_sync(struct dsa_port *dp, if (err && err != -EOPNOTSUPP) return err; + err = dsa_port_vlan_filtering(dp, br, extack); + if (err && err != -EOPNOTSUPP) + return err; + return 0; } @@ -205,6 +210,8 @@ static void dsa_port_switchdev_unsync(struct dsa_port *dp) * so allow it to be in BR_STATE_FORWARDING to be kept functional */ dsa_port_set_state_now(dp, BR_STATE_FORWARDING); + + /* VLAN filtering is handled by dsa_switch_bridge_leave */ } int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br, From patchwork Sat Mar 20 22:34:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 12152753 X-Patchwork-Delegate: kuba@kernel.org 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=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 B414AC433E9 for ; Sat, 20 Mar 2021 22:37:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9D24561933 for ; Sat, 20 Mar 2021 22:37:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230105AbhCTWgG (ORCPT ); Sat, 20 Mar 2021 18:36:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44090 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229946AbhCTWf2 (ORCPT ); Sat, 20 Mar 2021 18:35:28 -0400 Received: from mail-ed1-x52e.google.com (mail-ed1-x52e.google.com [IPv6:2a00:1450:4864:20::52e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 64403C061574; Sat, 20 Mar 2021 15:35:28 -0700 (PDT) Received: by mail-ed1-x52e.google.com with SMTP id j3so14928294edp.11; Sat, 20 Mar 2021 15:35:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=UUgWwEswye+b4aK+2bQLBIyYwXBiDuUTJA+VOwNWdDg=; b=PDRmZMcSgapKHhYZ7/XzOm2AZoQBVGGqPPm+7Men9VPsp3L4NRNrAbOfhffpStXFgF ao31aEDiX4VkFAfJAVaYu/IJD5jhNxWXkoD274Wte4ccHVA14P3+2KZNA5je7plX9L2y Fetf4eoAmR8/O2PwdyOr+/DElxS6irjZh7y1UrtzcVbVxLfax3PI15q7wPvjfpzLos6R NKFQ/F7R4hX4w8Rl/2vcBI6vtX0zomXt8tyRjq4NVv2K1sLU7QVeClPV6mgqoUM46e5W NHh8/mvaWbzajoQAbWUvVVRK7LuAI+xcfY1p1ks0blYVBky5z12vb889cPlgCXEHWsnb eYqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=UUgWwEswye+b4aK+2bQLBIyYwXBiDuUTJA+VOwNWdDg=; b=gUK0mZaYuyD5qM5daYTXrxxJ3mgVN5F4zrSIa1vv03j8+/foLWZKHUWICpIyp9Vn1x tDjgFd1PMHvIlKyAOFCisxflxU592yGtYb70lWiGdStVmQtuOnmJSiDZvxjXAbQTraO2 O4C6/3vFLV7zLenjyJ0tHGxXAyOUp2UlvgAvGsMNR/aRoEl0aVhqpflRKRW4i7QA2Sbn wZqZQnExxAYOlaa+PDBZZRdJni6PTczKJhs5KrwwTmeOApymTM3KYC+CWv8cXeQX9INj OnYa7kBQL3O7sGX5r++poXbOXoq+2T4LAV8mCjJW5//f7Qj+pStizqVz3xLP9/OrOEhx fnxw== X-Gm-Message-State: AOAM5307FJszvozu+lbX3H2zKLlZLWHGdf+ZPjmGUdPdhApt/B1qX0YQ n74/jIh7dT5VeKkp1Vc3v7xggE0lz8k= X-Google-Smtp-Source: ABdhPJxzcRf3pELkQzpNwfHINX/b43Q36CdVMrCXgNpOQfOOUIe31YLIA8EWHOST5LxVIKOS+CgPUg== X-Received: by 2002:aa7:da46:: with SMTP id w6mr17838479eds.40.1616279727186; Sat, 20 Mar 2021 15:35:27 -0700 (PDT) Received: from localhost.localdomain (5-12-16-165.residential.rdsnet.ro. [5.12.16.165]) by smtp.gmail.com with ESMTPSA id n2sm6090850ejl.1.2021.03.20.15.35.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 20 Mar 2021 15:35:26 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" Cc: Andrew Lunn , Vivien Didelot , Florian Fainelli , Tobias Waldekranz , Claudiu Manoil , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Roopa Prabhu , Nikolay Aleksandrov , Jiri Pirko , Ido Schimmel , Alexandre Belloni , UNGLinuxDriver@microchip.com, Ivan Vecera , linux-omap@vger.kernel.org, Vladimir Oltean Subject: [PATCH v3 net-next 06/12] net: dsa: sync multicast router state when joining the bridge Date: Sun, 21 Mar 2021 00:34:42 +0200 Message-Id: <20210320223448.2452869-7-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210320223448.2452869-1-olteanv@gmail.com> References: <20210320223448.2452869-1-olteanv@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org From: Vladimir Oltean Make sure that the multicast router setting of the bridge is picked up correctly by DSA when joining, regardless of whether there are sandwiched interfaces or not. The SWITCHDEV_ATTR_ID_BRIDGE_MROUTER port attribute is only emitted from br_mc_router_state_change. Signed-off-by: Vladimir Oltean Reviewed-by: Florian Fainelli --- Changes in v3: None. net/dsa/port.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/net/dsa/port.c b/net/dsa/port.c index 3f938c253c99..124f8bb21204 100644 --- a/net/dsa/port.c +++ b/net/dsa/port.c @@ -189,6 +189,10 @@ static int dsa_port_switchdev_sync(struct dsa_port *dp, if (err && err != -EOPNOTSUPP) return err; + err = dsa_port_mrouter(dp->cpu_dp, br_multicast_router(br), extack); + if (err && err != -EOPNOTSUPP) + return err; + return 0; } @@ -212,6 +216,12 @@ static void dsa_port_switchdev_unsync(struct dsa_port *dp) dsa_port_set_state_now(dp, BR_STATE_FORWARDING); /* VLAN filtering is handled by dsa_switch_bridge_leave */ + + /* Some drivers treat the notification for having a local multicast + * router by allowing multicast to be flooded to the CPU, so we should + * allow this in standalone mode too. + */ + dsa_port_mrouter(dp->cpu_dp, true, NULL); } int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br, From patchwork Sat Mar 20 22:34:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 12152755 X-Patchwork-Delegate: kuba@kernel.org 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=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 0F24AC433F1 for ; Sat, 20 Mar 2021 22:37:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DA9006146D for ; Sat, 20 Mar 2021 22:37:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230119AbhCTWgJ (ORCPT ); Sat, 20 Mar 2021 18:36:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44096 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229973AbhCTWfa (ORCPT ); Sat, 20 Mar 2021 18:35:30 -0400 Received: from mail-ej1-x635.google.com (mail-ej1-x635.google.com [IPv6:2a00:1450:4864:20::635]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9E313C061574; Sat, 20 Mar 2021 15:35:29 -0700 (PDT) Received: by mail-ej1-x635.google.com with SMTP id w3so15294214ejc.4; Sat, 20 Mar 2021 15:35:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=+w2V4CrXrr28bS/NRzU+Y8EJ/yXppRLpxb1GjTO73/I=; b=iphxnX1ZrOLj5/YdIZ0aKTSnUEeubyNIZ4hZHfDFzhEJ9qqzB35qJOq3ZseWdtRjqD NPS+gyUYgOH5T4bVAtHHzeGndNJxEu2wxtHKxMC9AuhrTtFZ9k0ERQ1oACRsH47lrOSK aOs/DZu9mYMsMVs4EQOfUXSfVRILJi6StlnJICXUXZNp5MjCbYCgXLuZtArq5Azngoq4 WYEb0Ck4WJA1ht6JmaHlGudFmgVOUO8EJBweobneuT3/OCHQya0umNNQ3KnuuTbN5F+A T4qaqkRd4YORnQV3zxPl+WsDzhbRf9nCPwtTM1wa3DVSUMzsAkETjqkXTHorF/LjPBFa cU+g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=+w2V4CrXrr28bS/NRzU+Y8EJ/yXppRLpxb1GjTO73/I=; b=LeKXuQrmUHfVvY6fx01dltZrHPN9A+YGDP7vN94LPT0ZcNtWFvfD1F5tygC9qSWzZ3 59YMYt2crCxLzg6oaeWnHrMqe7ZPtkjNxJ4GggnTVv5VrREZa7M5vFvi7L4DGnM8UsoX QmZa7c8LhkiHD+Q4uHYm5/h/7nGn+rHj4wiYDvoLwvyTwAxn042NG6+tE0VQM//Nozk2 tEphBjc2ktQy5DyMzCMFFNh0b/0TrPEeOSyg1UdFoF8MnJS74ocv3PI/EWOrWTeAy2p8 flMfbIlayfAMS01mDKEdZQhzuceV5fnMnhpM+A8VRgWeMgBooJRmP6JjTDYgOuIlrluE 5RiQ== X-Gm-Message-State: AOAM532BZut2+H4f5fWpCii1RwifC2TfGeM1TOpn6jmDSZoGvLyqo0Ee 2oM7L6CF8wB7/SQZUhCA2kA= X-Google-Smtp-Source: ABdhPJw5s5cjzrjbNOKfNNzuyHbiBwu6TiIvMhrfInX/00aZJWlYvRChC+pCJuwb+oOoBDrRKsaUgg== X-Received: by 2002:a17:906:a413:: with SMTP id l19mr11676480ejz.421.1616279728454; Sat, 20 Mar 2021 15:35:28 -0700 (PDT) Received: from localhost.localdomain (5-12-16-165.residential.rdsnet.ro. [5.12.16.165]) by smtp.gmail.com with ESMTPSA id n2sm6090850ejl.1.2021.03.20.15.35.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 20 Mar 2021 15:35:28 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" Cc: Andrew Lunn , Vivien Didelot , Florian Fainelli , Tobias Waldekranz , Claudiu Manoil , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Roopa Prabhu , Nikolay Aleksandrov , Jiri Pirko , Ido Schimmel , Alexandre Belloni , UNGLinuxDriver@microchip.com, Ivan Vecera , linux-omap@vger.kernel.org, Vladimir Oltean Subject: [PATCH v3 net-next 07/12] net: dsa: sync ageing time when joining the bridge Date: Sun, 21 Mar 2021 00:34:43 +0200 Message-Id: <20210320223448.2452869-8-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210320223448.2452869-1-olteanv@gmail.com> References: <20210320223448.2452869-1-olteanv@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org From: Vladimir Oltean The SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME attribute is only emitted from: sysfs/ioctl/netlink -> br_set_ageing_time -> __set_ageing_time therefore not at bridge port creation time, so: (a) drivers had to hardcode the initial value for the address ageing time, because they didn't get any notification (b) that hardcoded value can be out of sync, if the user changes the ageing time before enslaving the port to the bridge Signed-off-by: Vladimir Oltean Reviewed-by: Florian Fainelli --- Changes in v3: None. include/linux/if_bridge.h | 6 ++++++ net/bridge/br_stp.c | 13 +++++++++++++ net/dsa/port.c | 10 ++++++++++ 3 files changed, 29 insertions(+) diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h index 920d3a02cc68..ebd16495459c 100644 --- a/include/linux/if_bridge.h +++ b/include/linux/if_bridge.h @@ -137,6 +137,7 @@ struct net_device *br_fdb_find_port(const struct net_device *br_dev, void br_fdb_clear_offload(const struct net_device *dev, u16 vid); bool br_port_flag_is_set(const struct net_device *dev, unsigned long flag); u8 br_port_get_stp_state(const struct net_device *dev); +clock_t br_get_ageing_time(struct net_device *br_dev); #else static inline struct net_device * br_fdb_find_port(const struct net_device *br_dev, @@ -160,6 +161,11 @@ static inline u8 br_port_get_stp_state(const struct net_device *dev) { return BR_STATE_DISABLED; } + +static inline clock_t br_get_ageing_time(struct net_device *br_dev) +{ + return 0; +} #endif #endif diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c index 86b5e05d3f21..3dafb6143cff 100644 --- a/net/bridge/br_stp.c +++ b/net/bridge/br_stp.c @@ -639,6 +639,19 @@ int br_set_ageing_time(struct net_bridge *br, clock_t ageing_time) return 0; } +clock_t br_get_ageing_time(struct net_device *br_dev) +{ + struct net_bridge *br; + + if (!netif_is_bridge_master(br_dev)) + return 0; + + br = netdev_priv(br_dev); + + return jiffies_to_clock_t(br->ageing_time); +} +EXPORT_SYMBOL_GPL(br_get_ageing_time); + /* called under bridge lock */ void __br_set_topology_change(struct net_bridge *br, unsigned char val) { diff --git a/net/dsa/port.c b/net/dsa/port.c index 124f8bb21204..95e6f2861290 100644 --- a/net/dsa/port.c +++ b/net/dsa/port.c @@ -173,6 +173,7 @@ static int dsa_port_switchdev_sync(struct dsa_port *dp, { struct net_device *brport_dev = dsa_port_to_bridge_port(dp); struct net_device *br = dp->bridge_dev; + clock_t ageing_time; u8 stp_state; int err; @@ -193,6 +194,11 @@ static int dsa_port_switchdev_sync(struct dsa_port *dp, if (err && err != -EOPNOTSUPP) return err; + ageing_time = br_get_ageing_time(br); + err = dsa_port_ageing_time(dp, ageing_time); + if (err && err != -EOPNOTSUPP) + return err; + return 0; } @@ -222,6 +228,10 @@ static void dsa_port_switchdev_unsync(struct dsa_port *dp) * allow this in standalone mode too. */ dsa_port_mrouter(dp->cpu_dp, true, NULL); + + /* Ageing time may be global to the switch chip, so don't change it + * here because we have no good reason (or value) to change it to. + */ } int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br, From patchwork Sat Mar 20 22:34:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 12152757 X-Patchwork-Delegate: kuba@kernel.org 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=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 2B22DC433F2 for ; Sat, 20 Mar 2021 22:37:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0C30961937 for ; Sat, 20 Mar 2021 22:37:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229946AbhCTWgN (ORCPT ); Sat, 20 Mar 2021 18:36:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44104 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229986AbhCTWfb (ORCPT ); Sat, 20 Mar 2021 18:35:31 -0400 Received: from mail-ed1-x52f.google.com (mail-ed1-x52f.google.com [IPv6:2a00:1450:4864:20::52f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0BC93C061574; Sat, 20 Mar 2021 15:35:31 -0700 (PDT) Received: by mail-ed1-x52f.google.com with SMTP id w18so15012539edc.0; Sat, 20 Mar 2021 15:35:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=nhlOQ59araspQoyg2IoS80KsG4FClPd2yFkVhKlApp4=; b=hBM5aa2Ii67NCc2E2XLh9QI2/zRXiKrL9nVD+C/d26f7tuqLn5R+DNaJdyME3ZrauX BjVfWulUZ/3+Fisn6j+q/AxYueSuaPorqGbcvSkznxR4vbs3QozxsfzYDifMoxOOWiBj 8nlNrAf4ZrOpol8jnnmPcHr9mhtVXIDzgsKUWyBUrv0IKCuuPCZEX+hVNYq+PnxbQ2U/ CdsUWjbdCUSgFgdsB5BuWRkjwkKYu3pwz/Ri0q4mf/fUyH7Jw+sN6ekLRqLZcOl3demY 3TnN5LKVSwgnzW6iL0XUNU0oqMTaFtj9aIsSdad359iLlrwTi/JcIGI1UYLNpGqJ3aPw s8DQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=nhlOQ59araspQoyg2IoS80KsG4FClPd2yFkVhKlApp4=; b=qJD3uxSw/WpSjq0WOMigX2qMvZ98yFo5znKGGMLqjhmFLU3tHdZ0yHE4WhXzltPhht hSvQndwY9oROFjZaAYP1t93S3Dn8PP9VWwdk+mU8Vmc98RsRrxEohlhRDh564ukeOQMV S3LD1VElE59OHb3KrW629xEOJh7XYoMRWFLxL3zNUIk3kxerz2kr3YFanUelZoMPWRr3 Q6JRglrVzq85197hFPG3S99xmHRo2lSovjspOlmHXEiVjQhmiNUgcU3bXYkhIWxodyKI OxpM4F00R5VoOQBQx0fWHQqok/otydahfLkCz49Y7rqL4tBiyiq+gGfnfGrTHwZwYH2K nHDg== X-Gm-Message-State: AOAM530tXEBLiBjB7ybYgYF94V6DKgkl9IWRrZhGX5NYJL28+qm7/P5X 6V8tMjjEC+HkPH8XiberGXU= X-Google-Smtp-Source: ABdhPJw/E/RHWgd603Os5zGoJgYkLZc80gojimMxTvLiIntiPDHwmfxxfgNlXwJ+7dWwdRMBccrmVg== X-Received: by 2002:a05:6402:17d6:: with SMTP id s22mr17440526edy.232.1616279729731; Sat, 20 Mar 2021 15:35:29 -0700 (PDT) Received: from localhost.localdomain (5-12-16-165.residential.rdsnet.ro. [5.12.16.165]) by smtp.gmail.com with ESMTPSA id n2sm6090850ejl.1.2021.03.20.15.35.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 20 Mar 2021 15:35:29 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" Cc: Andrew Lunn , Vivien Didelot , Florian Fainelli , Tobias Waldekranz , Claudiu Manoil , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Roopa Prabhu , Nikolay Aleksandrov , Jiri Pirko , Ido Schimmel , Alexandre Belloni , UNGLinuxDriver@microchip.com, Ivan Vecera , linux-omap@vger.kernel.org, Vladimir Oltean Subject: [PATCH v3 net-next 08/12] net: dsa: replay port and host-joined mdb entries when joining the bridge Date: Sun, 21 Mar 2021 00:34:44 +0200 Message-Id: <20210320223448.2452869-9-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210320223448.2452869-1-olteanv@gmail.com> References: <20210320223448.2452869-1-olteanv@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org From: Vladimir Oltean I have udhcpcd in my system and this is configured to bring interfaces up as soon as they are created. I create a bridge as follows: ip link add br0 type bridge As soon as I create the bridge and udhcpcd brings it up, I also have avahi which automatically starts sending IPv6 packets to advertise some local services, and because of that, the br0 bridge joins the following IPv6 groups due to the code path detailed below: 33:33:ff:6d:c1:9c vid 0 33:33:00:00:00:6a vid 0 33:33:00:00:00:fb vid 0 br_dev_xmit -> br_multicast_rcv -> br_ip6_multicast_add_group -> __br_multicast_add_group -> br_multicast_host_join -> br_mdb_notify This is all fine, but inside br_mdb_notify we have br_mdb_switchdev_host hooked up, and switchdev will attempt to offload the host joined groups to an empty list of ports. Of course nobody offloads them. Then when we add a port to br0: ip link set swp0 master br0 the bridge doesn't replay the host-joined MDB entries from br_add_if, and eventually the host joined addresses expire, and a switchdev notification for deleting it is emitted, but surprise, the original addition was already completely missed. The strategy to address this problem is to replay the MDB entries (both the port ones and the host joined ones) when the new port joins the bridge, similar to what vxlan_fdb_replay does (in that case, its FDB can be populated and only then attached to a bridge that you offload). However there are 2 possibilities: the addresses can be 'pushed' by the bridge into the port, or the port can 'pull' them from the bridge. Considering that in the general case, the new port can be really late to the party, and there may have been many other switchdev ports that already received the initial notification, we would like to avoid delivering duplicate events to them, since they might misbehave. And currently, the bridge calls the entire switchdev notifier chain, whereas for replaying it should just call the notifier block of the new guy. But the bridge doesn't know what is the new guy's notifier block, it just knows where the switchdev notifier chain is. So for simplification, we make this a driver-initiated pull for now, and the notifier block is passed as an argument. To emulate the calling context for mdb objects (deferred and put on the blocking notifier chain), we must iterate under RCU protection through the bridge's mdb entries, queue them, and only call them once we're out of the RCU read-side critical section. Suggested-by: Ido Schimmel Signed-off-by: Vladimir Oltean --- Changes in v3: - Removed the implication that avahi is crap from the commit message. - Made the br_mdb_replay shim return -EOPNOTSUPP. include/linux/if_bridge.h | 9 +++++ net/bridge/br_mdb.c | 84 +++++++++++++++++++++++++++++++++++++++ net/dsa/dsa_priv.h | 2 + net/dsa/port.c | 6 +++ net/dsa/slave.c | 2 +- 5 files changed, 102 insertions(+), 1 deletion(-) diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h index ebd16495459c..f6472969bb44 100644 --- a/include/linux/if_bridge.h +++ b/include/linux/if_bridge.h @@ -69,6 +69,8 @@ bool br_multicast_has_querier_anywhere(struct net_device *dev, int proto); bool br_multicast_has_querier_adjacent(struct net_device *dev, int proto); bool br_multicast_enabled(const struct net_device *dev); bool br_multicast_router(const struct net_device *dev); +int br_mdb_replay(struct net_device *br_dev, struct net_device *dev, + struct notifier_block *nb, struct netlink_ext_ack *extack); #else static inline int br_multicast_list_adjacent(struct net_device *dev, struct list_head *br_ip_list) @@ -93,6 +95,13 @@ static inline bool br_multicast_router(const struct net_device *dev) { return false; } +static inline int br_mdb_replay(struct net_device *br_dev, + struct net_device *dev, + struct notifier_block *nb, + struct netlink_ext_ack *extack) +{ + return -EOPNOTSUPP; +} #endif #if IS_ENABLED(CONFIG_BRIDGE) && IS_ENABLED(CONFIG_BRIDGE_VLAN_FILTERING) diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c index 8846c5bcd075..23973186094c 100644 --- a/net/bridge/br_mdb.c +++ b/net/bridge/br_mdb.c @@ -506,6 +506,90 @@ static void br_mdb_complete(struct net_device *dev, int err, void *priv) kfree(priv); } +static int br_mdb_replay_one(struct notifier_block *nb, struct net_device *dev, + struct net_bridge_mdb_entry *mp, int obj_id, + struct net_device *orig_dev, + struct netlink_ext_ack *extack) +{ + struct switchdev_notifier_port_obj_info obj_info = { + .info = { + .dev = dev, + .extack = extack, + }, + }; + struct switchdev_obj_port_mdb mdb = { + .obj = { + .orig_dev = orig_dev, + .id = obj_id, + }, + .vid = mp->addr.vid, + }; + int err; + + if (mp->addr.proto == htons(ETH_P_IP)) + ip_eth_mc_map(mp->addr.dst.ip4, mdb.addr); +#if IS_ENABLED(CONFIG_IPV6) + else if (mp->addr.proto == htons(ETH_P_IPV6)) + ipv6_eth_mc_map(&mp->addr.dst.ip6, mdb.addr); +#endif + else + ether_addr_copy(mdb.addr, mp->addr.dst.mac_addr); + + obj_info.obj = &mdb.obj; + + err = nb->notifier_call(nb, SWITCHDEV_PORT_OBJ_ADD, &obj_info); + return notifier_to_errno(err); +} + +int br_mdb_replay(struct net_device *br_dev, struct net_device *dev, + struct notifier_block *nb, struct netlink_ext_ack *extack) +{ + struct net_bridge_mdb_entry *mp; + struct list_head mdb_list; + struct net_bridge *br; + int err = 0; + + ASSERT_RTNL(); + + INIT_LIST_HEAD(&mdb_list); + + if (!netif_is_bridge_master(br_dev) || !netif_is_bridge_port(dev)) + return -EINVAL; + + br = netdev_priv(br_dev); + + if (!br_opt_get(br, BROPT_MULTICAST_ENABLED)) + return 0; + + hlist_for_each_entry(mp, &br->mdb_list, mdb_node) { + struct net_bridge_port_group __rcu **pp; + struct net_bridge_port_group *p; + + if (mp->host_joined) { + err = br_mdb_replay_one(nb, dev, mp, + SWITCHDEV_OBJ_ID_HOST_MDB, + br_dev, extack); + if (err) + return err; + } + + for (pp = &mp->ports; (p = rtnl_dereference(*pp)) != NULL; + pp = &p->next) { + if (p->key.port->dev != dev) + continue; + + err = br_mdb_replay_one(nb, dev, mp, + SWITCHDEV_OBJ_ID_PORT_MDB, + dev, extack); + if (err) + return err; + } + } + + return 0; +} +EXPORT_SYMBOL(br_mdb_replay); + static void br_mdb_switchdev_host_port(struct net_device *dev, struct net_device *lower_dev, struct net_bridge_mdb_entry *mp, diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h index b8778c5d8529..b14c43cb88bb 100644 --- a/net/dsa/dsa_priv.h +++ b/net/dsa/dsa_priv.h @@ -262,6 +262,8 @@ static inline bool dsa_tree_offloads_bridge_port(struct dsa_switch_tree *dst, /* slave.c */ extern const struct dsa_device_ops notag_netdev_ops; +extern struct notifier_block dsa_slave_switchdev_blocking_notifier; + void dsa_slave_mii_bus_init(struct dsa_switch *ds); int dsa_slave_create(struct dsa_port *dp); void dsa_slave_destroy(struct net_device *slave_dev); diff --git a/net/dsa/port.c b/net/dsa/port.c index 95e6f2861290..3e61e9e6675c 100644 --- a/net/dsa/port.c +++ b/net/dsa/port.c @@ -199,6 +199,12 @@ static int dsa_port_switchdev_sync(struct dsa_port *dp, if (err && err != -EOPNOTSUPP) return err; + err = br_mdb_replay(br, brport_dev, + &dsa_slave_switchdev_blocking_notifier, + extack); + if (err && err != -EOPNOTSUPP) + return err; + return 0; } diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 1ff48be476bb..b974d8f84a2e 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -2396,7 +2396,7 @@ static struct notifier_block dsa_slave_switchdev_notifier = { .notifier_call = dsa_slave_switchdev_event, }; -static struct notifier_block dsa_slave_switchdev_blocking_notifier = { +struct notifier_block dsa_slave_switchdev_blocking_notifier = { .notifier_call = dsa_slave_switchdev_blocking_event, }; From patchwork Sat Mar 20 22:34:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 12152765 X-Patchwork-Delegate: kuba@kernel.org 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=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 32473C433F7 for ; Sat, 20 Mar 2021 22:37:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1CA0C6146D for ; Sat, 20 Mar 2021 22:37:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230150AbhCTWgP (ORCPT ); Sat, 20 Mar 2021 18:36:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44110 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229995AbhCTWfd (ORCPT ); Sat, 20 Mar 2021 18:35:33 -0400 Received: from mail-ed1-x536.google.com (mail-ed1-x536.google.com [IPv6:2a00:1450:4864:20::536]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 473DFC061762; Sat, 20 Mar 2021 15:35:32 -0700 (PDT) Received: by mail-ed1-x536.google.com with SMTP id e7so14915584edu.10; Sat, 20 Mar 2021 15:35:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=rdhnORVBljkLlBmOFb1qXswODCW9VE34U0BQWvSpPzM=; b=cTtvO3vGE5XTHNu6BESTy8ndYfaZyHBiorgventHSX3pCZFcScsk2w6ulodSkp1NYH dP2g6kwMaKfth3O9Zn2xZW4kWvDudH7uUm5g5247qAmXCe3zhXoZeSDRMtJvAZABo3lX fNE9JCYldb026yPQvjAEQuPliK6z9GKjzA07myRMl3KXl2XNFMuLhffEPe0LByWFIO8R ZxWQsL6U+Zi2sVGt8rsSHkiLL7bNXdnTbfX1cPEiSzQc9bzTFbq8grWQqbLe25F8j49C 9taJ+S+l2ilWKEDa5SwQuwVSxCwuCitwvz5dDy5I3QWK3oSPaVSqPhEZPKjFTn3obRrT sYIg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=rdhnORVBljkLlBmOFb1qXswODCW9VE34U0BQWvSpPzM=; b=V+bo02rS7zz6M9B4yShx6Igpm01S66rveZ3scZEfmKtqcdWV1gn3v9ny1KTdlBsY6s e8A8Zb9w6Vs+bdDmvcKhxmhe1HDShylnKAHX2+D3VrbJibto4HVVuqPtyr5lNZ1z1FsB pPkax2RGkQm+HVYNAbavoy8MsAqoRswMVTjpugmusnFWRHc4wDJlRY7iM974T1bYswok Da/m7jOkE5TWR/oLkcPZSIdE4laj1ltvZzTqjH800ZqiOUEifJ9gx1HFT77BKHEOK1nz YDnTCPSDR9czfqAe0luRbyka5foQeDJPbctdCaZ6S/lv6LwWw3YPXd4TAtDq3SJ6SQjW mPAg== X-Gm-Message-State: AOAM531ZZRTJe2koxsBJu9RaqrYey0SMTjm7e3ppCXRRqxxLZ9PJsVKU bg11qOIWYbN254KkZy0rP98= X-Google-Smtp-Source: ABdhPJz92p+6UfZgsbFiQbVQTQZEV2GnD4km6Gy6TTwrN5bBt+GbSnz0bHpYZk1OvW4YfVplQJMQCA== X-Received: by 2002:a05:6402:3096:: with SMTP id de22mr17588802edb.141.1616279731061; Sat, 20 Mar 2021 15:35:31 -0700 (PDT) Received: from localhost.localdomain (5-12-16-165.residential.rdsnet.ro. [5.12.16.165]) by smtp.gmail.com with ESMTPSA id n2sm6090850ejl.1.2021.03.20.15.35.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 20 Mar 2021 15:35:30 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" Cc: Andrew Lunn , Vivien Didelot , Florian Fainelli , Tobias Waldekranz , Claudiu Manoil , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Roopa Prabhu , Nikolay Aleksandrov , Jiri Pirko , Ido Schimmel , Alexandre Belloni , UNGLinuxDriver@microchip.com, Ivan Vecera , linux-omap@vger.kernel.org, Vladimir Oltean Subject: [PATCH v3 net-next 09/12] net: dsa: replay port and local fdb entries when joining the bridge Date: Sun, 21 Mar 2021 00:34:45 +0200 Message-Id: <20210320223448.2452869-10-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210320223448.2452869-1-olteanv@gmail.com> References: <20210320223448.2452869-1-olteanv@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org From: Vladimir Oltean When a DSA port joins a LAG that already had an FDB entry pointing to it: ip link set bond0 master br0 bridge fdb add dev bond0 00:01:02:03:04:05 master static ip link set swp0 master bond0 the DSA port will have no idea that this FDB entry is there, because it missed the switchdev event emitted at its creation. Ido Schimmel pointed this out during a discussion about challenges with switchdev offloading of stacked interfaces between the physical port and the bridge, and recommended to just catch that condition and deny the CHANGEUPPER event: https://lore.kernel.org/netdev/20210210105949.GB287766@shredder.lan/ But in fact, we might need to deal with the hard thing anyway, which is to replay all FDB addresses relevant to this port, because it isn't just static FDB entries, but also local addresses (ones that are not forwarded but terminated by the bridge). There, we can't just say 'oh yeah, there was an upper already so I'm not joining that'. So, similar to the logic for replaying MDB entries, add a function that must be called by individual switchdev drivers and replays local FDB entries as well as ones pointing towards a bridge port. This time, we use the atomic switchdev notifier block, since that's what FDB entries expect for some reason. Reported-by: Ido Schimmel Signed-off-by: Vladimir Oltean --- Changes in v3: Made the br_fdb_replay shim return -EOPNOTSUPP. include/linux/if_bridge.h | 9 +++++++ include/net/switchdev.h | 1 + net/bridge/br_fdb.c | 52 +++++++++++++++++++++++++++++++++++++++ net/dsa/dsa_priv.h | 1 + net/dsa/port.c | 4 +++ net/dsa/slave.c | 2 +- 6 files changed, 68 insertions(+), 1 deletion(-) diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h index f6472969bb44..b564c4486a45 100644 --- a/include/linux/if_bridge.h +++ b/include/linux/if_bridge.h @@ -147,6 +147,8 @@ void br_fdb_clear_offload(const struct net_device *dev, u16 vid); bool br_port_flag_is_set(const struct net_device *dev, unsigned long flag); u8 br_port_get_stp_state(const struct net_device *dev); clock_t br_get_ageing_time(struct net_device *br_dev); +int br_fdb_replay(struct net_device *br_dev, struct net_device *dev, + struct notifier_block *nb); #else static inline struct net_device * br_fdb_find_port(const struct net_device *br_dev, @@ -175,6 +177,13 @@ static inline clock_t br_get_ageing_time(struct net_device *br_dev) { return 0; } + +static inline int br_fdb_replay(struct net_device *br_dev, + struct net_device *dev, + struct notifier_block *nb) +{ + return -EOPNOTSUPP; +} #endif #endif diff --git a/include/net/switchdev.h b/include/net/switchdev.h index b7fc7d0f54e2..7688ec572757 100644 --- a/include/net/switchdev.h +++ b/include/net/switchdev.h @@ -205,6 +205,7 @@ struct switchdev_notifier_info { struct switchdev_notifier_fdb_info { struct switchdev_notifier_info info; /* must be first */ + struct list_head list; const unsigned char *addr; u16 vid; u8 added_by_user:1, diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index b7490237f3fc..49125cc196ac 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c @@ -726,6 +726,58 @@ static inline size_t fdb_nlmsg_size(void) + nla_total_size(sizeof(u8)); /* NFEA_ACTIVITY_NOTIFY */ } +static int br_fdb_replay_one(struct notifier_block *nb, + struct net_bridge_fdb_entry *fdb, + struct net_device *dev) +{ + struct switchdev_notifier_fdb_info item; + int err; + + item.addr = fdb->key.addr.addr; + item.vid = fdb->key.vlan_id; + item.added_by_user = test_bit(BR_FDB_ADDED_BY_USER, &fdb->flags); + item.offloaded = test_bit(BR_FDB_OFFLOADED, &fdb->flags); + item.info.dev = dev; + + err = nb->notifier_call(nb, SWITCHDEV_FDB_ADD_TO_DEVICE, &item); + return notifier_to_errno(err); +} + +int br_fdb_replay(struct net_device *br_dev, struct net_device *dev, + struct notifier_block *nb) +{ + struct net_bridge_fdb_entry *fdb; + struct net_bridge *br; + int err = 0; + + if (!netif_is_bridge_master(br_dev)) + return -EINVAL; + + if (!netif_is_bridge_port(dev)) + return -EINVAL; + + br = netdev_priv(br_dev); + + rcu_read_lock(); + + hlist_for_each_entry_rcu(fdb, &br->fdb_list, fdb_node) { + struct net_device *dst_dev; + + dst_dev = fdb->dst ? fdb->dst->dev : br->dev; + if (dst_dev != br_dev && dst_dev != dev) + continue; + + err = br_fdb_replay_one(nb, fdb, dst_dev); + if (err) + break; + } + + rcu_read_unlock(); + + return err; +} +EXPORT_SYMBOL(br_fdb_replay); + static void fdb_notify(struct net_bridge *br, const struct net_bridge_fdb_entry *fdb, int type, bool swdev_notify) diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h index b14c43cb88bb..92282de54230 100644 --- a/net/dsa/dsa_priv.h +++ b/net/dsa/dsa_priv.h @@ -262,6 +262,7 @@ static inline bool dsa_tree_offloads_bridge_port(struct dsa_switch_tree *dst, /* slave.c */ extern const struct dsa_device_ops notag_netdev_ops; +extern struct notifier_block dsa_slave_switchdev_notifier; extern struct notifier_block dsa_slave_switchdev_blocking_notifier; void dsa_slave_mii_bus_init(struct dsa_switch *ds); diff --git a/net/dsa/port.c b/net/dsa/port.c index 3e61e9e6675c..d21a511f1e16 100644 --- a/net/dsa/port.c +++ b/net/dsa/port.c @@ -205,6 +205,10 @@ static int dsa_port_switchdev_sync(struct dsa_port *dp, if (err && err != -EOPNOTSUPP) return err; + err = br_fdb_replay(br, brport_dev, &dsa_slave_switchdev_notifier); + if (err && err != -EOPNOTSUPP) + return err; + return 0; } diff --git a/net/dsa/slave.c b/net/dsa/slave.c index b974d8f84a2e..c51e52418a62 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -2392,7 +2392,7 @@ static struct notifier_block dsa_slave_nb __read_mostly = { .notifier_call = dsa_slave_netdevice_event, }; -static struct notifier_block dsa_slave_switchdev_notifier = { +struct notifier_block dsa_slave_switchdev_notifier = { .notifier_call = dsa_slave_switchdev_event, }; From patchwork Sat Mar 20 22:34:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 12152763 X-Patchwork-Delegate: kuba@kernel.org 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=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 7CF99C43381 for ; Sat, 20 Mar 2021 22:37:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6BA526146D for ; Sat, 20 Mar 2021 22:37:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230179AbhCTWgU (ORCPT ); Sat, 20 Mar 2021 18:36:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44122 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229999AbhCTWfg (ORCPT ); Sat, 20 Mar 2021 18:35:36 -0400 Received: from mail-ed1-x52d.google.com (mail-ed1-x52d.google.com [IPv6:2a00:1450:4864:20::52d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8CA96C061574; Sat, 20 Mar 2021 15:35:33 -0700 (PDT) Received: by mail-ed1-x52d.google.com with SMTP id z1so14979419edb.8; Sat, 20 Mar 2021 15:35:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=xWcQ7RaEO5zW7dzwffFPpzvRes4Xyw0t8vNMvTuHyTA=; b=hK4qF18kD0P7ssMqzZnhjI8G1voEfGMsHAARj6Jwbyg44ogdrcaCggY30HkPYfyLja CmBDW0jIY0wlfvgTe5Pu6GUCJYMSEOaNxdubPgGE+N2SclPQTZO/8kpiR2aAG6oDD0O0 wHJPbshs6Patjly1uXSa/gSmhmM8Y8qcRceBRZpgeqmyvoTqUFoZR6O7mLfBGO1TissO JFD+IZPG8K8jGNsgZ9HToTbU/XFNucJunOct7USMPz0e9BNOBLnkYyuQgIAXBYd2r67j nxOAZOEWGbAkisLHxmVccX7fc1WBMVqe/1/dbqSsyA7/5Yuv43kfSohBXUUkBQ+fg8iE EHGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=xWcQ7RaEO5zW7dzwffFPpzvRes4Xyw0t8vNMvTuHyTA=; b=ecjlWpqOQVpma5fZ4erkI8zpydhFWyq0uC5ZuB8qntHhEptLHdUXslzAy56HuMnrsc Pj7xRVWeAlBAOJD9AU3gxmcqRcFzmbuJSoaNl20kTexNz0PGAHRVmnJSKbBjS8jiLiES o5MWMrTvhQZS6w8k5DDiytBHvAYrASlPi3yAsWloyOA8n8vl+9qpAfrJJUbGTRDmYeEM N5D98au6Ud9PIV1ymq4JU8xq45rcuhCxllKQwzK1ik8XPDyjPQ1BDSZ75UWKi2/Ul7LC UmP/BxnRr4/yEIkl3zGQDQ1l9lbMvnKkGnnPq+++8JvptM3rXXCX3f/iptJBugqpJQAO Yzbw== X-Gm-Message-State: AOAM531cz0aaT4D1KUOES6DydjUbZHiU2+a0Y+E/lKSg7By1rbfKerj7 W/A+2xFMXnsWz7qfs2eKOvg= X-Google-Smtp-Source: ABdhPJwWSxX4TIvV2zSoRNHcGqjJnQP1Qq4/RIe1QanUPFARL6ufUDUz9HyOol/LRUoISrptmBQkJg== X-Received: by 2002:aa7:c3c1:: with SMTP id l1mr17763729edr.208.1616279732359; Sat, 20 Mar 2021 15:35:32 -0700 (PDT) Received: from localhost.localdomain (5-12-16-165.residential.rdsnet.ro. [5.12.16.165]) by smtp.gmail.com with ESMTPSA id n2sm6090850ejl.1.2021.03.20.15.35.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 20 Mar 2021 15:35:32 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" Cc: Andrew Lunn , Vivien Didelot , Florian Fainelli , Tobias Waldekranz , Claudiu Manoil , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Roopa Prabhu , Nikolay Aleksandrov , Jiri Pirko , Ido Schimmel , Alexandre Belloni , UNGLinuxDriver@microchip.com, Ivan Vecera , linux-omap@vger.kernel.org, Vladimir Oltean Subject: [PATCH v3 net-next 10/12] net: dsa: replay VLANs installed on port when joining the bridge Date: Sun, 21 Mar 2021 00:34:46 +0200 Message-Id: <20210320223448.2452869-11-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210320223448.2452869-1-olteanv@gmail.com> References: <20210320223448.2452869-1-olteanv@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org From: Vladimir Oltean Currently this simple setup: ip link add br0 type bridge vlan_filtering 1 ip link add bond0 type bond ip link set bond0 master br0 ip link set swp0 master bond0 will not work because the bridge has created the PVID in br_add_if -> nbp_vlan_init, and it has notified switchdev of the existence of VLAN 1, but that was too early, since swp0 was not yet a lower of bond0, so it had no reason to act upon that notification. Signed-off-by: Vladimir Oltean Reported-by: kernel test robot --- Changes in v3: Made the br_vlan_replay shim return -EOPNOTSUPP. include/linux/if_bridge.h | 10 ++++++ net/bridge/br_vlan.c | 71 +++++++++++++++++++++++++++++++++++++++ net/dsa/port.c | 6 ++++ 3 files changed, 87 insertions(+) diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h index b564c4486a45..2cc35038a8ca 100644 --- a/include/linux/if_bridge.h +++ b/include/linux/if_bridge.h @@ -111,6 +111,8 @@ int br_vlan_get_pvid_rcu(const struct net_device *dev, u16 *p_pvid); int br_vlan_get_proto(const struct net_device *dev, u16 *p_proto); int br_vlan_get_info(const struct net_device *dev, u16 vid, struct bridge_vlan_info *p_vinfo); +int br_vlan_replay(struct net_device *br_dev, struct net_device *dev, + struct notifier_block *nb, struct netlink_ext_ack *extack); #else static inline bool br_vlan_enabled(const struct net_device *dev) { @@ -137,6 +139,14 @@ static inline int br_vlan_get_info(const struct net_device *dev, u16 vid, { return -EINVAL; } + +static inline int br_vlan_replay(struct net_device *br_dev, + struct net_device *dev, + struct notifier_block *nb, + struct netlink_ext_ack *extack) +{ + return -EOPNOTSUPP; +} #endif #if IS_ENABLED(CONFIG_BRIDGE) diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c index 8829f621b8ec..45a4eac1b217 100644 --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c @@ -1751,6 +1751,77 @@ void br_vlan_notify(const struct net_bridge *br, kfree_skb(skb); } +static int br_vlan_replay_one(struct notifier_block *nb, + struct net_device *dev, + struct switchdev_obj_port_vlan *vlan, + struct netlink_ext_ack *extack) +{ + struct switchdev_notifier_port_obj_info obj_info = { + .info = { + .dev = dev, + .extack = extack, + }, + .obj = &vlan->obj, + }; + int err; + + err = nb->notifier_call(nb, SWITCHDEV_PORT_OBJ_ADD, &obj_info); + return notifier_to_errno(err); +} + +int br_vlan_replay(struct net_device *br_dev, struct net_device *dev, + struct notifier_block *nb, struct netlink_ext_ack *extack) +{ + struct net_bridge_vlan_group *vg; + struct net_bridge_vlan *v; + struct net_bridge_port *p; + struct net_bridge *br; + int err = 0; + u16 pvid; + + ASSERT_RTNL(); + + if (!netif_is_bridge_master(br_dev)) + return -EINVAL; + + if (!netif_is_bridge_master(dev) && !netif_is_bridge_port(dev)) + return -EINVAL; + + if (netif_is_bridge_master(dev)) { + br = netdev_priv(dev); + vg = br_vlan_group(br); + p = NULL; + } else { + p = br_port_get_rtnl(dev); + if (WARN_ON(!p)) + return -EINVAL; + vg = nbp_vlan_group(p); + br = p->br; + } + + if (!vg) + return 0; + + pvid = br_get_pvid(vg); + + list_for_each_entry(v, &vg->vlan_list, vlist) { + struct switchdev_obj_port_vlan vlan = { + .obj.orig_dev = dev, + .obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN, + .flags = br_vlan_flags(v, pvid), + .vid = v->vid, + }; + + if (!br_vlan_should_use(v)) + continue; + + br_vlan_replay_one(nb, dev, &vlan, extack); + if (err) + return err; + } + + return err; +} /* check if v_curr can enter a range ending in range_end */ bool br_vlan_can_enter_range(const struct net_bridge_vlan *v_curr, const struct net_bridge_vlan *range_end) diff --git a/net/dsa/port.c b/net/dsa/port.c index d21a511f1e16..84775e253ee8 100644 --- a/net/dsa/port.c +++ b/net/dsa/port.c @@ -209,6 +209,12 @@ static int dsa_port_switchdev_sync(struct dsa_port *dp, if (err && err != -EOPNOTSUPP) return err; + err = br_vlan_replay(br, brport_dev, + &dsa_slave_switchdev_blocking_notifier, + extack); + if (err && err != -EOPNOTSUPP) + return err; + return 0; } From patchwork Sat Mar 20 22:34:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 12152759 X-Patchwork-Delegate: kuba@kernel.org 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=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 64327C433FB for ; Sat, 20 Mar 2021 22:37:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 45FDD61933 for ; Sat, 20 Mar 2021 22:37:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230159AbhCTWgS (ORCPT ); Sat, 20 Mar 2021 18:36:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44124 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230001AbhCTWfg (ORCPT ); Sat, 20 Mar 2021 18:35:36 -0400 Received: from mail-ej1-x62b.google.com (mail-ej1-x62b.google.com [IPv6:2a00:1450:4864:20::62b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D767AC061762; Sat, 20 Mar 2021 15:35:34 -0700 (PDT) Received: by mail-ej1-x62b.google.com with SMTP id hq27so15290994ejc.9; Sat, 20 Mar 2021 15:35:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=SoiJi9I8+4T7GzSieCrgTmk0ey5FdI/Q8mWfB1Ye++w=; b=UnW4cJHToksyV98Tyk1saDsRdTk2upOzwgjGjPSagA8F+cBmKTMBT315m9Lc93Mupr f91ZUIXknIOvlxpdIYzCRFqJps6oWl1/OSFAQP7lTEIhOHe7acuiUqv5L+tH/XHNA5Lk VB+mO2Xo48RZTmmIaiUsYak19WlumxKzaG9VfMTt+HBcZDoqmSxstyJsFmmwy4zMfz1L Gq08B4hAQ6K00FpWkrYRakavT65B332VERVZPjgqi7Abfap4ltpabjEN6unkN3NZFZ2J bBUDTookXurLZjYjDROcZPAM8QZR1BGRIF183beVq1Gb2RI//nSBCWIy01sB/C2bL+iQ mOcQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=SoiJi9I8+4T7GzSieCrgTmk0ey5FdI/Q8mWfB1Ye++w=; b=NU+1tBcM7E92Y0bzVwbI45nlmyME8Bx/jsy8QTGzWwMmeFAU/bp4QP5CiHDrmF/VpT B945AOdTA85qMrrNHYJnF6Ilot2J8iuqFTUXwz2vOD4t1MM0wvk9njYKiMutwxdwuMSR sLQdKOZFiafFC2S3ks7nxHVei4WCoIEVFPlGucZPdm3LDezRCK0rsyZzNEXYKdp5a5so gfDpJus/x5n5waG3sgl1v6erbNUbxdSdv0MkF4OEiZomv+iZ73wMrIy6p6WsxcPVzhIw us3d+pYC6WkrEZrDCbiomkgg1agBEf2TEpp9UaOodvT9Ps8xg+NjigmuPBbzJFBHUlkR jeEA== X-Gm-Message-State: AOAM5300nOTe2Coj+eLcTh9JT8M41ti2DOuFnzFz8TjLFc81I1ldamJG kqZlRVmq8vH9PmvzmMAdq6Q= X-Google-Smtp-Source: ABdhPJz+0ZiFFy9XNFb1oGGwhYDjnkw39hzlLyf5EdDFjVQK9YRucWN4mcsc3ueFuPi4mQvf1dz1gQ== X-Received: by 2002:a17:906:7f01:: with SMTP id d1mr11913739ejr.136.1616279733638; Sat, 20 Mar 2021 15:35:33 -0700 (PDT) Received: from localhost.localdomain (5-12-16-165.residential.rdsnet.ro. [5.12.16.165]) by smtp.gmail.com with ESMTPSA id n2sm6090850ejl.1.2021.03.20.15.35.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 20 Mar 2021 15:35:33 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" Cc: Andrew Lunn , Vivien Didelot , Florian Fainelli , Tobias Waldekranz , Claudiu Manoil , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Roopa Prabhu , Nikolay Aleksandrov , Jiri Pirko , Ido Schimmel , Alexandre Belloni , UNGLinuxDriver@microchip.com, Ivan Vecera , linux-omap@vger.kernel.org, Vladimir Oltean Subject: [PATCH v3 net-next 11/12] net: ocelot: call ocelot_netdevice_bridge_join when joining a bridged LAG Date: Sun, 21 Mar 2021 00:34:47 +0200 Message-Id: <20210320223448.2452869-12-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210320223448.2452869-1-olteanv@gmail.com> References: <20210320223448.2452869-1-olteanv@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org From: Vladimir Oltean Similar to the DSA situation, ocelot supports LAG offload but treats this scenario improperly: ip link add br0 type bridge ip link add bond0 type bond ip link set bond0 master br0 ip link set swp0 master bond0 We do the same thing as we do there, which is to simulate a 'bridge join' on 'lag join', if we detect that the bonding upper has a bridge upper. Again, same as DSA, ocelot supports software fallback for LAG, and in that case, we should avoid calling ocelot_netdevice_changeupper. Signed-off-by: Vladimir Oltean --- Changes in v3: None. drivers/net/ethernet/mscc/ocelot_net.c | 111 +++++++++++++++++++------ 1 file changed, 86 insertions(+), 25 deletions(-) diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index c08164cd88f4..d1376f7b34fd 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -1117,10 +1117,15 @@ static int ocelot_port_obj_del(struct net_device *dev, return ret; } -static int ocelot_netdevice_bridge_join(struct ocelot *ocelot, int port, - struct net_device *bridge) +static int ocelot_netdevice_bridge_join(struct net_device *dev, + struct net_device *bridge, + struct netlink_ext_ack *extack) { + struct ocelot_port_private *priv = netdev_priv(dev); + struct ocelot_port *ocelot_port = &priv->port; + struct ocelot *ocelot = ocelot_port->ocelot; struct switchdev_brport_flags flags; + int port = priv->chip_port; int err; flags.mask = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD; @@ -1135,10 +1140,14 @@ static int ocelot_netdevice_bridge_join(struct ocelot *ocelot, int port, return 0; } -static int ocelot_netdevice_bridge_leave(struct ocelot *ocelot, int port, +static int ocelot_netdevice_bridge_leave(struct net_device *dev, struct net_device *bridge) { + struct ocelot_port_private *priv = netdev_priv(dev); + struct ocelot_port *ocelot_port = &priv->port; + struct ocelot *ocelot = ocelot_port->ocelot; struct switchdev_brport_flags flags; + int port = priv->chip_port; int err; flags.mask = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD; @@ -1151,43 +1160,89 @@ static int ocelot_netdevice_bridge_leave(struct ocelot *ocelot, int port, return err; } -static int ocelot_netdevice_changeupper(struct net_device *dev, - struct netdev_notifier_changeupper_info *info) +static int ocelot_netdevice_lag_join(struct net_device *dev, + struct net_device *bond, + struct netdev_lag_upper_info *info, + struct netlink_ext_ack *extack) { struct ocelot_port_private *priv = netdev_priv(dev); struct ocelot_port *ocelot_port = &priv->port; struct ocelot *ocelot = ocelot_port->ocelot; + struct net_device *bridge_dev; int port = priv->chip_port; + int err; + + err = ocelot_port_lag_join(ocelot, port, bond, info); + if (err == -EOPNOTSUPP) { + NL_SET_ERR_MSG_MOD(extack, "Offloading not supported"); + return 0; + } + + bridge_dev = netdev_master_upper_dev_get(bond); + if (!bridge_dev || !netif_is_bridge_master(bridge_dev)) + return 0; + + err = ocelot_netdevice_bridge_join(dev, bridge_dev, extack); + if (err) + goto err_bridge_join; + + return 0; + +err_bridge_join: + ocelot_port_lag_leave(ocelot, port, bond); + return err; +} + +static int ocelot_netdevice_lag_leave(struct net_device *dev, + struct net_device *bond) +{ + struct ocelot_port_private *priv = netdev_priv(dev); + struct ocelot_port *ocelot_port = &priv->port; + struct ocelot *ocelot = ocelot_port->ocelot; + struct net_device *bridge_dev; + int port = priv->chip_port; + + ocelot_port_lag_leave(ocelot, port, bond); + + bridge_dev = netdev_master_upper_dev_get(bond); + if (!bridge_dev || !netif_is_bridge_master(bridge_dev)) + return 0; + + return ocelot_netdevice_bridge_leave(dev, bridge_dev); +} + +static int ocelot_netdevice_changeupper(struct net_device *dev, + struct netdev_notifier_changeupper_info *info) +{ + struct netlink_ext_ack *extack; int err = 0; + extack = netdev_notifier_info_to_extack(&info->info); + if (netif_is_bridge_master(info->upper_dev)) { - if (info->linking) { - err = ocelot_netdevice_bridge_join(ocelot, port, - info->upper_dev); - } else { - err = ocelot_netdevice_bridge_leave(ocelot, port, - info->upper_dev); - } + if (info->linking) + err = ocelot_netdevice_bridge_join(dev, info->upper_dev, + extack); + else + err = ocelot_netdevice_bridge_leave(dev, info->upper_dev); } if (netif_is_lag_master(info->upper_dev)) { - if (info->linking) { - err = ocelot_port_lag_join(ocelot, port, - info->upper_dev, - info->upper_info); - if (err == -EOPNOTSUPP) { - NL_SET_ERR_MSG_MOD(info->info.extack, - "Offloading not supported"); - err = 0; - } - } else { - ocelot_port_lag_leave(ocelot, port, - info->upper_dev); - } + if (info->linking) + err = ocelot_netdevice_lag_join(dev, info->upper_dev, + info->upper_info, extack); + else + ocelot_netdevice_lag_leave(dev, info->upper_dev); } return notifier_from_errno(err); } +/* Treat CHANGEUPPER events on an offloaded LAG as individual CHANGEUPPER + * events for the lower physical ports of the LAG. + * If the LAG upper isn't offloaded, ignore its CHANGEUPPER events. + * In case the LAG joined a bridge, notify that we are offloading it and can do + * forwarding in hardware towards it. + */ static int ocelot_netdevice_lag_changeupper(struct net_device *dev, struct netdev_notifier_changeupper_info *info) @@ -1197,6 +1252,12 @@ ocelot_netdevice_lag_changeupper(struct net_device *dev, int err = NOTIFY_DONE; netdev_for_each_lower_dev(dev, lower, iter) { + struct ocelot_port_private *priv = netdev_priv(lower); + struct ocelot_port *ocelot_port = &priv->port; + + if (ocelot_port->bond != dev) + return NOTIFY_OK; + err = ocelot_netdevice_changeupper(lower, info); if (err) return notifier_from_errno(err); From patchwork Sat Mar 20 22:34:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 12152761 X-Patchwork-Delegate: kuba@kernel.org 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=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable 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 A0E27C433FC for ; Sat, 20 Mar 2021 22:37:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 80D1261933 for ; Sat, 20 Mar 2021 22:37:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230192AbhCTWgW (ORCPT ); Sat, 20 Mar 2021 18:36:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44126 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230008AbhCTWfg (ORCPT ); Sat, 20 Mar 2021 18:35:36 -0400 Received: from mail-ej1-x62c.google.com (mail-ej1-x62c.google.com [IPv6:2a00:1450:4864:20::62c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 30A73C061763; Sat, 20 Mar 2021 15:35:36 -0700 (PDT) Received: by mail-ej1-x62c.google.com with SMTP id hq27so15291045ejc.9; Sat, 20 Mar 2021 15:35:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=J8YAC1uwHCk1hgPlMm7HJR85SXBcUjAUNou54XaHHWg=; b=CA4ejeTPH2NE9n/9ESnAbxdLzYntzEpNAqiiftwOTlz3qFpgMsUn7xMLMjN1M8nBPx 4JXcuaTLZcA/4vs+N/w2nFmRFm8vU3sm/0cNH4gDCn/TCFZpsB11A4pO4BeGgnNMJh9V 21cuyyfgiQ318F3IVSUdA4B3D3uQfJE8cDFu5bDYfpCNzsK8q61krWww+9zFjkPvNSBu ljuLK/bazed3oBT8qgDuX5ceGsyjFtNqBpBOmfAhbY68xiWSW8RfPGQxcnx+DqOQ+C9U Cum97rJtXahtXKZHmclXxBpwAdQjVvxkjbm580vpsnc6FYsReOmBDTG29QBMXZQDJlFi dr3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=J8YAC1uwHCk1hgPlMm7HJR85SXBcUjAUNou54XaHHWg=; b=lLh5odEVw7BE01dKa0hKxeQ4ubN09o1H04QPV+IipOIV1SxFkvAbWNaFyulGZ26Ty+ 3Ajv+dTLXycO7dLxHGObmCOE8FhDDEu6thj+g+5yDByjHom8ff852WGSEk1TprlK7Qn3 uTSMC0K3Uo4hXzElWQDotdFkn0721TafQQPdm26vJvSu/OhzmsfFD8IfH3+bPbBbc5hB SvKZHOPORf3kCqmKrEIx6j8nTf4n968gXkR8L7f2hrAZZ/sMkdH9zkUZP/R+n025+eZP 8MHdIYVawUEDgkGrKr+XzVuW4EBY8DoIStXZRFlFJmu5k9i0hPOSGHNJ+XokXAmhd07A oGyg== X-Gm-Message-State: AOAM5321zDy1WE3kV8WImAu+MimO42Giqx8JD9SrgNs+whllFVuaxLXD WTXJ7xMj0MU8Sn2m3k2GnmU= X-Google-Smtp-Source: ABdhPJy2TyyM+QxGYlqcAih/GvwKcA0n570zBSjsue6GZNy0Det6lf098mRkYVycGCAiXwX8MVGTig== X-Received: by 2002:a17:906:1c98:: with SMTP id g24mr11708378ejh.51.1616279734918; Sat, 20 Mar 2021 15:35:34 -0700 (PDT) Received: from localhost.localdomain (5-12-16-165.residential.rdsnet.ro. [5.12.16.165]) by smtp.gmail.com with ESMTPSA id n2sm6090850ejl.1.2021.03.20.15.35.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 20 Mar 2021 15:35:34 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" Cc: Andrew Lunn , Vivien Didelot , Florian Fainelli , Tobias Waldekranz , Claudiu Manoil , netdev@vger.kernel.org, linux-kernel@vger.kernel.org, Roopa Prabhu , Nikolay Aleksandrov , Jiri Pirko , Ido Schimmel , Alexandre Belloni , UNGLinuxDriver@microchip.com, Ivan Vecera , linux-omap@vger.kernel.org, Vladimir Oltean Subject: [PATCH v3 net-next 12/12] net: ocelot: replay switchdev events when joining bridge Date: Sun, 21 Mar 2021 00:34:48 +0200 Message-Id: <20210320223448.2452869-13-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210320223448.2452869-1-olteanv@gmail.com> References: <20210320223448.2452869-1-olteanv@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org From: Vladimir Oltean The premise of this change is that the switchdev port attributes and objects offloaded by ocelot might have been missed when we are joining an already existing bridge port, such as a bonding interface. The patch pulls these switchdev attributes and objects from the bridge, on behalf of the 'bridge port' net device which might be either the ocelot switch interface, or the bonding upper interface. The ocelot_net.c belongs strictly to the switchdev ocelot driver, while ocelot.c is part of a library shared with the DSA felix driver. The ocelot_port_bridge_leave function (part of the common library) used to call ocelot_port_vlan_filtering(false), something which is not necessary for DSA, since the framework deals with that already there. So we move this function to ocelot_switchdev_unsync, which is specific to the switchdev driver. The code movement described above makes ocelot_port_bridge_leave no longer return an error code, so we change its type from int to void. Signed-off-by: Vladimir Oltean Reported-by: kernel test robot --- Changes in v3: Added -EOPNOTSUPP to br_mdb_replay and br_vlan_replay, which can be compiled out. drivers/net/dsa/ocelot/felix.c | 4 +- drivers/net/ethernet/mscc/ocelot.c | 18 ++-- drivers/net/ethernet/mscc/ocelot_net.c | 117 +++++++++++++++++++++---- include/soc/mscc/ocelot.h | 6 +- 4 files changed, 111 insertions(+), 34 deletions(-) diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c index 628afb47b579..6b5442be0230 100644 --- a/drivers/net/dsa/ocelot/felix.c +++ b/drivers/net/dsa/ocelot/felix.c @@ -719,7 +719,9 @@ static int felix_bridge_join(struct dsa_switch *ds, int port, { struct ocelot *ocelot = ds->priv; - return ocelot_port_bridge_join(ocelot, port, br); + ocelot_port_bridge_join(ocelot, port, br); + + return 0; } static void felix_bridge_leave(struct dsa_switch *ds, int port, diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c index ce57929ba3d1..1a36b416fd9b 100644 --- a/drivers/net/ethernet/mscc/ocelot.c +++ b/drivers/net/ethernet/mscc/ocelot.c @@ -1514,34 +1514,28 @@ int ocelot_port_mdb_del(struct ocelot *ocelot, int port, } EXPORT_SYMBOL(ocelot_port_mdb_del); -int ocelot_port_bridge_join(struct ocelot *ocelot, int port, - struct net_device *bridge) +void ocelot_port_bridge_join(struct ocelot *ocelot, int port, + struct net_device *bridge) { struct ocelot_port *ocelot_port = ocelot->ports[port]; ocelot_port->bridge = bridge; - return 0; + ocelot_apply_bridge_fwd_mask(ocelot); } EXPORT_SYMBOL(ocelot_port_bridge_join); -int ocelot_port_bridge_leave(struct ocelot *ocelot, int port, - struct net_device *bridge) +void ocelot_port_bridge_leave(struct ocelot *ocelot, int port, + struct net_device *bridge) { struct ocelot_port *ocelot_port = ocelot->ports[port]; struct ocelot_vlan pvid = {0}, native_vlan = {0}; - int ret; ocelot_port->bridge = NULL; - ret = ocelot_port_vlan_filtering(ocelot, port, false); - if (ret) - return ret; - ocelot_port_set_pvid(ocelot, port, pvid); ocelot_port_set_native_vlan(ocelot, port, native_vlan); - - return 0; + ocelot_apply_bridge_fwd_mask(ocelot); } EXPORT_SYMBOL(ocelot_port_bridge_leave); diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c index d1376f7b34fd..36f32a4d9b0f 100644 --- a/drivers/net/ethernet/mscc/ocelot_net.c +++ b/drivers/net/ethernet/mscc/ocelot_net.c @@ -1117,47 +1117,126 @@ static int ocelot_port_obj_del(struct net_device *dev, return ret; } +static void ocelot_inherit_brport_flags(struct ocelot *ocelot, int port, + struct net_device *brport_dev) +{ + struct switchdev_brport_flags flags = {0}; + int flag; + + flags.mask = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD; + + for_each_set_bit(flag, &flags.mask, 32) + if (br_port_flag_is_set(brport_dev, BIT(flag))) + flags.val |= BIT(flag); + + ocelot_port_bridge_flags(ocelot, port, flags); +} + +static void ocelot_clear_brport_flags(struct ocelot *ocelot, int port) +{ + struct switchdev_brport_flags flags; + + flags.mask = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD; + flags.val = flags.mask & ~BR_LEARNING; + + ocelot_port_bridge_flags(ocelot, port, flags); +} + +static int ocelot_switchdev_sync(struct ocelot *ocelot, int port, + struct net_device *brport_dev, + struct net_device *bridge_dev, + struct netlink_ext_ack *extack) +{ + clock_t ageing_time; + u8 stp_state; + int err; + + ocelot_inherit_brport_flags(ocelot, port, brport_dev); + + stp_state = br_port_get_stp_state(brport_dev); + ocelot_bridge_stp_state_set(ocelot, port, stp_state); + + err = ocelot_port_vlan_filtering(ocelot, port, + br_vlan_enabled(bridge_dev)); + if (err) + return err; + + ageing_time = br_get_ageing_time(bridge_dev); + ocelot_port_attr_ageing_set(ocelot, port, ageing_time); + + err = br_mdb_replay(bridge_dev, brport_dev, + &ocelot_switchdev_blocking_nb, extack); + if (err && err != -EOPNOTSUPP) + return err; + + err = br_fdb_replay(bridge_dev, brport_dev, &ocelot_switchdev_nb); + if (err) + return err; + + err = br_vlan_replay(bridge_dev, brport_dev, + &ocelot_switchdev_blocking_nb, extack); + if (err && err != -EOPNOTSUPP) + return err; + + return 0; +} + +static int ocelot_switchdev_unsync(struct ocelot *ocelot, int port) +{ + int err; + + err = ocelot_port_vlan_filtering(ocelot, port, false); + if (err) + return err; + + ocelot_clear_brport_flags(ocelot, port); + + ocelot_bridge_stp_state_set(ocelot, port, BR_STATE_FORWARDING); + + return 0; +} + static int ocelot_netdevice_bridge_join(struct net_device *dev, + struct net_device *brport_dev, struct net_device *bridge, struct netlink_ext_ack *extack) { struct ocelot_port_private *priv = netdev_priv(dev); struct ocelot_port *ocelot_port = &priv->port; struct ocelot *ocelot = ocelot_port->ocelot; - struct switchdev_brport_flags flags; int port = priv->chip_port; int err; - flags.mask = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD; - flags.val = flags.mask; + ocelot_port_bridge_join(ocelot, port, bridge); - err = ocelot_port_bridge_join(ocelot, port, bridge); + err = ocelot_switchdev_sync(ocelot, port, brport_dev, bridge, extack); if (err) - return err; - - ocelot_port_bridge_flags(ocelot, port, flags); + goto err_switchdev_sync; return 0; + +err_switchdev_sync: + ocelot_port_bridge_leave(ocelot, port, bridge); + return err; } static int ocelot_netdevice_bridge_leave(struct net_device *dev, + struct net_device *brport_dev, struct net_device *bridge) { struct ocelot_port_private *priv = netdev_priv(dev); struct ocelot_port *ocelot_port = &priv->port; struct ocelot *ocelot = ocelot_port->ocelot; - struct switchdev_brport_flags flags; int port = priv->chip_port; int err; - flags.mask = BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD | BR_BCAST_FLOOD; - flags.val = flags.mask & ~BR_LEARNING; + err = ocelot_switchdev_unsync(ocelot, port); + if (err) + return err; - err = ocelot_port_bridge_leave(ocelot, port, bridge); + ocelot_port_bridge_leave(ocelot, port, bridge); - ocelot_port_bridge_flags(ocelot, port, flags); - - return err; + return 0; } static int ocelot_netdevice_lag_join(struct net_device *dev, @@ -1182,7 +1261,7 @@ static int ocelot_netdevice_lag_join(struct net_device *dev, if (!bridge_dev || !netif_is_bridge_master(bridge_dev)) return 0; - err = ocelot_netdevice_bridge_join(dev, bridge_dev, extack); + err = ocelot_netdevice_bridge_join(dev, bond, bridge_dev, extack); if (err) goto err_bridge_join; @@ -1208,7 +1287,7 @@ static int ocelot_netdevice_lag_leave(struct net_device *dev, if (!bridge_dev || !netif_is_bridge_master(bridge_dev)) return 0; - return ocelot_netdevice_bridge_leave(dev, bridge_dev); + return ocelot_netdevice_bridge_leave(dev, bond, bridge_dev); } static int ocelot_netdevice_changeupper(struct net_device *dev, @@ -1221,10 +1300,12 @@ static int ocelot_netdevice_changeupper(struct net_device *dev, if (netif_is_bridge_master(info->upper_dev)) { if (info->linking) - err = ocelot_netdevice_bridge_join(dev, info->upper_dev, + err = ocelot_netdevice_bridge_join(dev, dev, + info->upper_dev, extack); else - err = ocelot_netdevice_bridge_leave(dev, info->upper_dev); + err = ocelot_netdevice_bridge_leave(dev, dev, + info->upper_dev); } if (netif_is_lag_master(info->upper_dev)) { if (info->linking) diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h index ce7e5c1bd90d..68cdc7ceaf4d 100644 --- a/include/soc/mscc/ocelot.h +++ b/include/soc/mscc/ocelot.h @@ -803,10 +803,10 @@ int ocelot_port_pre_bridge_flags(struct ocelot *ocelot, int port, struct switchdev_brport_flags val); void ocelot_port_bridge_flags(struct ocelot *ocelot, int port, struct switchdev_brport_flags val); -int ocelot_port_bridge_join(struct ocelot *ocelot, int port, - struct net_device *bridge); -int ocelot_port_bridge_leave(struct ocelot *ocelot, int port, +void ocelot_port_bridge_join(struct ocelot *ocelot, int port, struct net_device *bridge); +void ocelot_port_bridge_leave(struct ocelot *ocelot, int port, + struct net_device *bridge); int ocelot_fdb_dump(struct ocelot *ocelot, int port, dsa_fdb_dump_cb_t *cb, void *data); int ocelot_fdb_add(struct ocelot *ocelot, int port,