From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-f66.google.com ([74.125.82.66]:35236 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S935101AbeCEN2q (ORCPT ); Mon, 5 Mar 2018 08:28:46 -0500 Received: by mail-wm0-f66.google.com with SMTP id x7so15442504wmc.0 for ; Mon, 05 Mar 2018 05:28:45 -0800 (PST) From: John Hurley To: netdev@vger.kernel.org Cc: jiri@mellanox.com, ogerlitz@mellanox.com, jakub.kicinski@netronome.com, simon.horman@netronome.com, John Hurley Subject: [RFC net-next 3/6] drivers: net: bonding: restrict bond mods when rules are offloaded Date: Mon, 5 Mar 2018 13:28:31 +0000 Message-Id: <1520256514-27885-4-git-send-email-john.hurley@netronome.com> In-Reply-To: <1520256514-27885-1-git-send-email-john.hurley@netronome.com> References: <1520256514-27885-1-git-send-email-john.hurley@netronome.com> Sender: netdev-owner@vger.kernel.org List-ID: When a bond has tc rules offloaded to its slaves, prevent new slaves being added. To remove a slave from a bond, the offloaded rules must first be deleted. For the case where a slave port on a bond is unregistered from the kernel, flush all offloaded rules and destroy the bond. Signed-off-by: John Hurley --- drivers/net/bonding/bond_main.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index d9e41cf..4c146b1 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1607,6 +1607,15 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev, return -EPERM; } + /* check for TC offloaded */ + if (bond_get_offload_cnt(bond)) { + NL_SET_ERR_MSG(extack, + "Cannot enslave - bond has offloaded rules."); + netdev_err(bond_dev, + "cannot enslave - bond has offloaded rules.\n"); + return -EPERM; + } + /* vlan challenged mutual exclusion */ /* no need to lock since we're protected by rtnl_lock */ if (slave_dev->features & NETIF_F_VLAN_CHALLENGED) { @@ -2237,6 +2246,13 @@ static int __bond_release_one(struct net_device *bond_dev, /* A wrapper used because of ndo_del_link */ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) { + if (bond_get_offload_cnt(netdev_priv(bond_dev))) { + netdev_err(bond_dev, + "cannot release %s - has offloaded rules.\n", + slave_dev->name); + return -EPERM; + } + return __bond_release_one(bond_dev, slave_dev, false, false); } @@ -3325,6 +3341,8 @@ static int bond_slave_netdev_event(unsigned long event, case NETDEV_UNREGISTER: if (bond_dev->type != ARPHRD_ETHER) bond_release_and_destroy(bond_dev, slave_dev); + else if (bond_get_offload_cnt(bond)) + unregister_netdevice_queue(bond_dev, NULL); else __bond_release_one(bond_dev, slave_dev, false, true); break; -- 2.7.4