[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20220412135012.czcmfurp5w2t2ocl@skbuf>
Date: Tue, 12 Apr 2022 16:50:12 +0300
From: Vladimir Oltean <olteanv@...il.com>
To: Mattias Forsblad <mattias.forsblad@...il.com>
Cc: netdev@...r.kernel.org, Andrew Lunn <andrew@...n.ch>,
Vivien Didelot <vivien.didelot@...il.com>,
Florian Fainelli <f.fainelli@...il.com>,
"David S . Miller" <davem@...emloft.net>,
Jakub Kicinski <kuba@...nel.org>,
Paolo Abeni <pabeni@...hat.com>,
Tobias Waldekranz <tobias@...dekranz.com>
Subject: Re: [PATCH v4 net-next 1/3] net: dsa: track whetever bridges have
foreign interfaces in them
On Mon, Apr 11, 2022 at 02:06:31PM +0200, Mattias Forsblad wrote:
> Track if a bridge stack has any foreign interfaces in them.
>
> This patch is based on work done by Vlodimir Oltean.
Originally these were 2 patches which were squashed (and they were 2
patches for a reason), they're missing proper authorship (mine, my sign
off, your sign off), and my name is misspelled.
>
> Signed-off-by: Mattias Forsblad <mattias.forsblad@...il.com>
> ---
> include/net/dsa.h | 1 +
> net/dsa/dsa_priv.h | 1 +
> net/dsa/slave.c | 88 +++++++++++++++++++++++++++++++++++++++++-----
> 3 files changed, 81 insertions(+), 9 deletions(-)
>
> diff --git a/include/net/dsa.h b/include/net/dsa.h
> index 934958fda962..52b6da7d45b3 100644
> --- a/include/net/dsa.h
> +++ b/include/net/dsa.h
> @@ -242,6 +242,7 @@ struct dsa_bridge {
> unsigned int num;
> bool tx_fwd_offload;
> refcount_t refcount;
> + u8 have_foreign:1;
> };
>
> struct dsa_port {
> diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
> index 5d3f4a67dce1..d610776ecd76 100644
> --- a/net/dsa/dsa_priv.h
> +++ b/net/dsa/dsa_priv.h
> @@ -320,6 +320,7 @@ void dsa_slave_setup_tagger(struct net_device *slave);
> int dsa_slave_change_mtu(struct net_device *dev, int new_mtu);
> int dsa_slave_manage_vlan_filtering(struct net_device *dev,
> bool vlan_filtering);
> +int dsa_bridge_foreign_dev_update(struct net_device *bridge_dev);
>
> static inline struct dsa_port *dsa_slave_to_port(const struct net_device *dev)
> {
> diff --git a/net/dsa/slave.c b/net/dsa/slave.c
> index 41c69a6e7854..feaf64564c6e 100644
> --- a/net/dsa/slave.c
> +++ b/net/dsa/slave.c
> @@ -2485,6 +2485,9 @@ static int dsa_slave_changeupper(struct net_device *dev,
> struct netlink_ext_ack *extack;
> int err = NOTIFY_DONE;
>
> + if (!dsa_slave_dev_check(dev))
> + return err;
> +
> extack = netdev_notifier_info_to_extack(&info->info);
>
> if (netif_is_bridge_master(info->upper_dev)) {
> @@ -2539,6 +2542,9 @@ static int dsa_slave_prechangeupper(struct net_device *dev,
> {
> struct dsa_port *dp = dsa_slave_to_port(dev);
>
> + if (!dsa_slave_dev_check(dev))
> + return NOTIFY_DONE;
> +
> if (netif_is_bridge_master(info->upper_dev) && !info->linking)
> dsa_port_pre_bridge_leave(dp, info->upper_dev);
> else if (netif_is_lag_master(info->upper_dev) && !info->linking)
> @@ -2559,6 +2565,9 @@ dsa_slave_lag_changeupper(struct net_device *dev,
> int err = NOTIFY_DONE;
> struct dsa_port *dp;
>
> + if (!netif_is_lag_master(dev))
> + return err;
> +
> netdev_for_each_lower_dev(dev, lower, iter) {
> if (!dsa_slave_dev_check(lower))
> continue;
> @@ -2588,6 +2597,9 @@ dsa_slave_lag_prechangeupper(struct net_device *dev,
> int err = NOTIFY_DONE;
> struct dsa_port *dp;
>
> + if (!netif_is_lag_master(dev))
> + return err;
> +
> netdev_for_each_lower_dev(dev, lower, iter) {
> if (!dsa_slave_dev_check(lower))
> continue;
> @@ -2605,6 +2617,18 @@ dsa_slave_lag_prechangeupper(struct net_device *dev,
> return err;
> }
>
> +static int dsa_bridge_changelower(struct net_device *dev,
> + struct netdev_notifier_changeupper_info *info)
> +{
> + int err;
> +
> + if (!netif_is_bridge_master(info->upper_dev))
> + return NOTIFY_DONE;
> +
> + err = dsa_bridge_foreign_dev_update(info->upper_dev);
> + return notifier_from_errno(err);
> +}
> +
> static int
> dsa_prevent_bridging_8021q_upper(struct net_device *dev,
> struct netdev_notifier_changeupper_info *info)
> @@ -2709,22 +2733,33 @@ static int dsa_slave_netdevice_event(struct notifier_block *nb,
> if (err != NOTIFY_DONE)
> return err;
>
> - if (dsa_slave_dev_check(dev))
> - return dsa_slave_prechangeupper(dev, ptr);
> + err = dsa_slave_prechangeupper(dev, ptr);
> + if (notifier_to_errno(err))
> + return err;
>
> - if (netif_is_lag_master(dev))
> - return dsa_slave_lag_prechangeupper(dev, ptr);
> + err = dsa_slave_lag_prechangeupper(dev, ptr);
> + if (notifier_to_errno(err))
> + return err;
>
> break;
> }
> - case NETDEV_CHANGEUPPER:
> - if (dsa_slave_dev_check(dev))
> - return dsa_slave_changeupper(dev, ptr);
> + case NETDEV_CHANGEUPPER: {
> + int err;
>
> - if (netif_is_lag_master(dev))
> - return dsa_slave_lag_changeupper(dev, ptr);
> + err = dsa_slave_changeupper(dev, ptr);
> + if (notifier_to_errno(err))
> + return err;
> +
> + err = dsa_slave_lag_changeupper(dev, ptr);
> + if (notifier_to_errno(err))
> + return err;
> +
> + err = dsa_bridge_changelower(dev, ptr);
> + if (notifier_to_errno(err))
> + return err;
>
> break;
> + }
> case NETDEV_CHANGELOWERSTATE: {
> struct netdev_notifier_changelowerstate_info *info = ptr;
> struct dsa_port *dp;
> @@ -2877,6 +2912,41 @@ static bool dsa_foreign_dev_check(const struct net_device *dev,
> return true;
> }
>
> +int dsa_bridge_foreign_dev_update(struct net_device *bridge_dev)
> +{
> + struct net_device *first_slave, *lower;
> + struct dsa_bridge *bridge = NULL;
> + struct dsa_switch_tree *dst;
> + bool have_foreign = false;
> + struct list_head *iter;
> + struct dsa_port *dp;
> +
> + list_for_each_entry(dst, &dsa_tree_list, list) {
> + dsa_tree_for_each_user_port(dp, dst) {
> + if (dsa_port_offloads_bridge_dev(dp, bridge_dev)) {
> + bridge = dp->bridge;
> + first_slave = dp->slave;
> + break;
> + }
> + }
> + }
> +
> + /* Bridge with no DSA interface in it */
> + if (!bridge)
> + return 0;
> +
> + netdev_for_each_lower_dev(bridge_dev, lower, iter) {
> + if (dsa_foreign_dev_check(first_slave, lower)) {
> + have_foreign = true;
> + break;
> + }
> + }
> +
> + bridge->have_foreign = have_foreign;
> +
> + return 0;
> +}
> +
> static int dsa_slave_fdb_event(struct net_device *dev,
> struct net_device *orig_dev,
> unsigned long event, const void *ctx,
> --
> 2.25.1
>
Powered by blists - more mailing lists