From patchwork Mon Apr 29 16:36:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Beh=C3=BAn?= X-Patchwork-Id: 13647363 X-Patchwork-Delegate: kuba@kernel.org Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CD43685646 for ; Mon, 29 Apr 2024 16:36:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714408593; cv=none; b=Rf8ELFdIJNTcCC/nJdahEgcEetWZnlzFjSsMMkVd4fEO7udjeEBvxLoI99Duw/4/9WyzRM71RZ62GkW/FT/8Z9/qsIj1as/WL9Zvbw4nMWKN/DbLSoELS3DzG4j0zn+EpP1O6BpsEz6Kz7Fyx35HjCPMxtn0QOt7PPGON3+wUmY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714408593; c=relaxed/simple; bh=9azVaDYx8Hf2BII3OMntXoB0smdteY8jXBXkGincjrg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=nmQBhjXrdeQWdT4GaBqk1XlEaG8OKyywVaPIiARrXuVGYGRWFtmfSRiJfA4lSCDFCQR2QTzBEozTwPQwcaRgEECiu4ZlNishqM+8ht8OeWo8ityW0fzIlmNJojC9DIBerdETllAS8ynyMWLJJZ8Zw4Jjxx+NdE2K2ntJeZ6xJWQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Q82rt5/6; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Q82rt5/6" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3F2C1C4AF14; Mon, 29 Apr 2024 16:36:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1714408593; bh=9azVaDYx8Hf2BII3OMntXoB0smdteY8jXBXkGincjrg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Q82rt5/6fDT8dgtzdWaROZnaOLBgBVPDpbRG1S9lxmD7ryF3xP+Wbht7wcBIHQtZ2 zhKomV67KouCj806er/AmOaDDKRX0m7eKxeltkKwEJU+YY7pPq5EVZAdVzbDDkcwMD oH8szbq4Bj4MJDihbe8wWKwFXFNiPXcpNoQA1EREMXvShjhTuAkewKnSNoBRjHWVRu FLhLxlMHB6U4g/YTO5nMWsjGbyc3ILQ54aDKVOlePj+YCGH4LDqRLi/KFRYa7nOfl5 dRKPGG7x8PK0EjYMvf0slZ45TR5MkGczox0oUU7jRQJq+xRe+NRCCxsChJoTQq41AL 9DqZ+kbSrtmkQ== From: =?utf-8?q?Marek_Beh=C3=BAn?= To: netdev@vger.kernel.org, Andrew Lunn , Florian Fainelli , Vladimir Oltean Cc: =?utf-8?q?Marek_Beh=C3=BAn?= Subject: [PATCH net-next 1/2] net: dsa: Deduplicate code adding / deleting the port address to fdb Date: Mon, 29 Apr 2024 18:36:26 +0200 Message-ID: <20240429163627.16031-2-kabel@kernel.org> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240429163627.16031-1-kabel@kernel.org> References: <20240429163627.16031-1-kabel@kernel.org> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org The sequence if (dsa_switch_supports_uc_filtering(ds)) dsa_port_standalone_host_fdb_add(dp, addr, 0); if (!ether_addr_equal(addr, conduit->dev_addr)) dev_uc_add(conduit, addr); is executed both in dsa_user_open() and dsa_user_set_mac_addr(). Its reverse is executed both in dsa_user_close() and dsa_user_set_mac_addr(). Refactor these sequences into new functions dsa_user_host_uc_install() and dsa_user_host_uc_uninstall(). Signed-off-by: Marek BehĂșn --- net/dsa/user.c | 91 ++++++++++++++++++++++++++------------------------ 1 file changed, 47 insertions(+), 44 deletions(-) diff --git a/net/dsa/user.c b/net/dsa/user.c index c94b868855aa..b1d8d1827f91 100644 --- a/net/dsa/user.c +++ b/net/dsa/user.c @@ -355,60 +355,82 @@ static int dsa_user_get_iflink(const struct net_device *dev) return READ_ONCE(dsa_user_to_conduit(dev)->ifindex); } -static int dsa_user_open(struct net_device *dev) +static int dsa_user_host_uc_install(struct net_device *dev, const u8 *addr) { struct net_device *conduit = dsa_user_to_conduit(dev); struct dsa_port *dp = dsa_user_to_port(dev); struct dsa_switch *ds = dp->ds; int err; - err = dev_open(conduit, NULL); - if (err < 0) { - netdev_err(dev, "failed to open conduit %s\n", conduit->name); - goto out; - } - if (dsa_switch_supports_uc_filtering(ds)) { - err = dsa_port_standalone_host_fdb_add(dp, dev->dev_addr, 0); + err = dsa_port_standalone_host_fdb_add(dp, addr, 0); if (err) goto out; } - if (!ether_addr_equal(dev->dev_addr, conduit->dev_addr)) { - err = dev_uc_add(conduit, dev->dev_addr); + if (!ether_addr_equal(addr, conduit->dev_addr)) { + err = dev_uc_add(conduit, addr); if (err < 0) goto del_host_addr; } - err = dsa_port_enable_rt(dp, dev->phydev); - if (err) - goto del_unicast; - return 0; -del_unicast: - if (!ether_addr_equal(dev->dev_addr, conduit->dev_addr)) - dev_uc_del(conduit, dev->dev_addr); del_host_addr: if (dsa_switch_supports_uc_filtering(ds)) - dsa_port_standalone_host_fdb_del(dp, dev->dev_addr, 0); + dsa_port_standalone_host_fdb_del(dp, addr, 0); out: return err; } -static int dsa_user_close(struct net_device *dev) +static void dsa_user_host_uc_uninstall(struct net_device *dev) { struct net_device *conduit = dsa_user_to_conduit(dev); struct dsa_port *dp = dsa_user_to_port(dev); struct dsa_switch *ds = dp->ds; - dsa_port_disable_rt(dp); - if (!ether_addr_equal(dev->dev_addr, conduit->dev_addr)) dev_uc_del(conduit, dev->dev_addr); if (dsa_switch_supports_uc_filtering(ds)) dsa_port_standalone_host_fdb_del(dp, dev->dev_addr, 0); +} + +static int dsa_user_open(struct net_device *dev) +{ + struct net_device *conduit = dsa_user_to_conduit(dev); + struct dsa_port *dp = dsa_user_to_port(dev); + int err; + + err = dev_open(conduit, NULL); + if (err < 0) { + netdev_err(dev, "failed to open conduit %s\n", conduit->name); + goto out; + } + + err = dsa_user_host_uc_install(dev, dev->dev_addr); + if (err) + goto out; + + err = dsa_port_enable_rt(dp, dev->phydev); + if (err) + goto out_del_host_uc; + + return 0; + +out_del_host_uc: + dsa_user_host_uc_uninstall(dev); +out: + return err; +} + +static int dsa_user_close(struct net_device *dev) +{ + struct dsa_port *dp = dsa_user_to_port(dev); + + dsa_port_disable_rt(dp); + + dsa_user_host_uc_uninstall(dev); return 0; } @@ -448,7 +470,6 @@ static void dsa_user_set_rx_mode(struct net_device *dev) static int dsa_user_set_mac_address(struct net_device *dev, void *a) { - struct net_device *conduit = dsa_user_to_conduit(dev); struct dsa_port *dp = dsa_user_to_port(dev); struct dsa_switch *ds = dp->ds; struct sockaddr *addr = a; @@ -470,34 +491,16 @@ static int dsa_user_set_mac_address(struct net_device *dev, void *a) if (!(dev->flags & IFF_UP)) goto out_change_dev_addr; - if (dsa_switch_supports_uc_filtering(ds)) { - err = dsa_port_standalone_host_fdb_add(dp, addr->sa_data, 0); - if (err) - return err; - } - - if (!ether_addr_equal(addr->sa_data, conduit->dev_addr)) { - err = dev_uc_add(conduit, addr->sa_data); - if (err < 0) - goto del_unicast; - } - - if (!ether_addr_equal(dev->dev_addr, conduit->dev_addr)) - dev_uc_del(conduit, dev->dev_addr); + err = dsa_user_host_uc_install(dev, addr->sa_data); + if (err) + return err; - if (dsa_switch_supports_uc_filtering(ds)) - dsa_port_standalone_host_fdb_del(dp, dev->dev_addr, 0); + dsa_user_host_uc_uninstall(dev); out_change_dev_addr: eth_hw_addr_set(dev, addr->sa_data); return 0; - -del_unicast: - if (dsa_switch_supports_uc_filtering(ds)) - dsa_port_standalone_host_fdb_del(dp, addr->sa_data, 0); - - return err; } struct dsa_user_dump_ctx { From patchwork Mon Apr 29 16:36:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marek_Beh=C3=BAn?= X-Patchwork-Id: 13647364 X-Patchwork-Delegate: kuba@kernel.org Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3B3C71DA23 for ; Mon, 29 Apr 2024 16:36:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714408595; cv=none; b=btUxaM+TLulncY/Mi8E+uX4zePNvzNZTFkgtBqCxrGf+fXxdUTsfit5bqQr1KR1oftSImOQPI8k5PtqnKNpsLtfLw2+rIi2Sld6rsVveAH2ttstsAh3axTS0TZ/jfGaiscROF7VrsePV+HouQj/6acR9x04sBRsO9Wbquwx6aGg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1714408595; c=relaxed/simple; bh=WYvfWnsRpu0RLSxmTgg+qqm5H1A6I0HfRFjKBasBoFw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=QdryU8iaK/+88Yg/v6pGWuK4a73AYG0+ZMJGhHSecNf3HZ/vDeO1fDzV1nDiBBJldPvK7s6sbcSOt/5r2neFd4BZYaMBdrWK8sLR9A4rjiXhK5SpxHZB7xd4w3pis/tUexoQdAcQvUmLFha2kmKLCKgd7qYxUQWSqWn75CUiIPo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=NhL5vx+7; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="NhL5vx+7" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D00E4C113CD; Mon, 29 Apr 2024 16:36:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1714408595; bh=WYvfWnsRpu0RLSxmTgg+qqm5H1A6I0HfRFjKBasBoFw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NhL5vx+7+iFM8jtr2hzWosvjiPdS79Y4VRbMlvAx57bK8Ez9KLT5NxtJv2oBBzjoX 9UvNupF2K1DA38KkPuwIxuWTC2gPD0TNZAKyZPA6ogMj+v8hJFyGIzNxqNkoWdcTRH AxywmiZTi9RHliu4fbJmbB7/xjlyGvuwGsilvvaQ2bgdlMTVCfezSDPXLa6FeqCdXO d3oi7GoOnPNlO7sNweB85/0Ac/MyCmBuqqvejoXVHW63OTQ2gFYD//L0TSbFsZCDrN 1BGyFyaBqqqbSRVXBm2yG3OamJLQ6+PxQc7/ciyX50F6DyjPCSgjxIrCkgvJQFv4SD 3K7Ihb+Gvd75w== From: =?utf-8?q?Marek_Beh=C3=BAn?= To: netdev@vger.kernel.org, Andrew Lunn , Florian Fainelli , Vladimir Oltean Cc: =?utf-8?q?Marek_Beh=C3=BAn?= Subject: [PATCH net-next 2/2] net: dsa: update the unicast MAC address when changing conduit Date: Mon, 29 Apr 2024 18:36:27 +0200 Message-ID: <20240429163627.16031-3-kabel@kernel.org> X-Mailer: git-send-email 2.43.2 In-Reply-To: <20240429163627.16031-1-kabel@kernel.org> References: <20240429163627.16031-1-kabel@kernel.org> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org DSA exhibits different behavior regarding the primary unicast MAC address stored in port standalone FDB and the conduit device UC database while the interface is down vs up. If we put a switch port down while changing the conduit with ip link set sw0p0 down ip link set sw0p0 type dsa conduit conduit1 ip link set sw0p0 up we delete the address in dsa_user_close() and install the (possibly different) address dsa_user_open(). But when changing the conduit on the fly, the old address is not deleted and the new one is not installed. Since we explicitly want to support live-changing the conduit, uninstall the old address before the dsa_port_change_conduit() call and install the (possibly different) new one afterwards. Because the dsa_user_change_conduit() call tries to smoothly restore the old conduit if anything fails while setting new one (except the MTU change), this leaves us with the question about what to do if the installation of the new address fails. Since we have already deleted the old address, we can expect that restoring the old address would also fail, and thus we can't revert the conduit change correctly. I have therefore decided to treat it as a fatal error printed into the kernel log. Fixes: 95f510d0b792 ("net: dsa: allow the DSA master to be seen and changed through rtnetlink") Signed-off-by: Marek BehĂșn --- net/dsa/user.c | 45 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/net/dsa/user.c b/net/dsa/user.c index b1d8d1827f91..70d7be1b6a79 100644 --- a/net/dsa/user.c +++ b/net/dsa/user.c @@ -2767,9 +2767,37 @@ int dsa_user_change_conduit(struct net_device *dev, struct net_device *conduit, if (err) goto out_revert_old_conduit_unlink; + /* If live-changing, we also need to uninstall the user device address + * from the port FDB and the conduit interface. This has to be done + * before the conduit is changed. + */ + if (dev->flags & IFF_UP) + dsa_user_host_uc_uninstall(dev); + err = dsa_port_change_conduit(dp, conduit, extack); if (err) - goto out_revert_conduit_link; + goto out_revert_host_address; + + /* If the port doesn't have its own MAC address and relies on the DSA + * conduit's one, inherit it again from the new DSA conduit. + */ + if (is_zero_ether_addr(dp->mac)) + eth_hw_addr_inherit(dev, conduit); + + /* If live-changing, we need to install the user device address to the + * port FDB and the conduit interface. Since the device address needs to + * be installed towards the new conduit in the port FDB, this needs to + * be done after the conduit is changed. + */ + if (dev->flags & IFF_UP) { + err = dsa_user_host_uc_install(dev, dev->dev_addr); + if (err) { + netdev_err(dev, + "fatal error installing new host address: %pe\n", + ERR_PTR(err)); + return err; + } + } /* Update the MTU of the new CPU port through cross-chip notifiers */ err = dsa_user_change_mtu(dev, dev->mtu); @@ -2779,15 +2807,16 @@ int dsa_user_change_conduit(struct net_device *dev, struct net_device *conduit, ERR_PTR(err)); } - /* If the port doesn't have its own MAC address and relies on the DSA - * conduit's one, inherit it again from the new DSA conduit. - */ - if (is_zero_ether_addr(dp->mac)) - eth_hw_addr_inherit(dev, conduit); - return 0; -out_revert_conduit_link: +out_revert_host_address: + if (dev->flags & IFF_UP) { + err = dsa_user_host_uc_install(dev, dev->dev_addr); + if (err) + netdev_err(dev, + "fatal error restoring old host address: %pe\n", + ERR_PTR(err)); + } netdev_upper_dev_unlink(conduit, dev); out_revert_old_conduit_unlink: netdev_upper_dev_link(old_conduit, dev, NULL);