From patchwork Thu Mar 31 11:01:35 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?TWljaGHFgiBNaXJvc8WCYXc=?= X-Patchwork-Id: 89061 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 9CF76B6F77 for ; Thu, 31 Mar 2011 22:01:57 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1757308Ab1CaLBk (ORCPT ); Thu, 31 Mar 2011 07:01:40 -0400 Received: from rere.qmqm.pl ([89.167.52.164]:50957 "EHLO rere.qmqm.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1757294Ab1CaLBi (ORCPT ); Thu, 31 Mar 2011 07:01:38 -0400 Received: by rere.qmqm.pl (Postfix, from userid 1000) id 2088713A65; Thu, 31 Mar 2011 13:01:35 +0200 (CEST) From: =?UTF-8?q?Micha=C5=82=20Miros=C5=82aw?= Subject: [RFC PATCH] bonding: convert bond_compute_features() to ndo_fix/set_features MIME-Version: 1.0 To: netdev@vger.kernel.org Cc: Jay Vosburgh , Andy Gospodarek , "David S. Miller" , Jiri Pirko , Neil Horman Message-Id: <20110331110135.2088713A65@rere.qmqm.pl> Date: Thu, 31 Mar 2011 13:01:35 +0200 (CEST) Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Note: Updating of vlan_features is and was broken, as its not propagated to vlan devices already created ontop of the bond. Signed-off-by: Michał Mirosław --- drivers/net/bonding/bond_main.c | 45 +++++++++++++++++++++++++------------- 1 files changed, 29 insertions(+), 16 deletions(-) diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 16d6fe9..73d2661 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1396,29 +1396,42 @@ static int bond_sethwaddr(struct net_device *bond_dev, * feature bits are managed elsewhere, so preserve those feature bits * on the master device. */ -static int bond_compute_features(struct bonding *bond) +static u32 bond_fix_features(struct net_device *bond_dev, u32 features) { + struct bonding *bond = netdev_priv(bond_dev); struct slave *slave; - struct net_device *bond_dev = bond->dev; - u32 features = bond_dev->features; - u32 vlan_features = 0; - unsigned short max_hard_header_len = max((u16)ETH_HLEN, - bond_dev->hard_header_len); int i; features &= ~(NETIF_F_ALL_CSUM | BOND_VLAN_FEATURES); features |= NETIF_F_GSO_MASK | NETIF_F_NO_CSUM; if (!bond->first_slave) - goto done; + return features; features &= ~NETIF_F_ONE_FOR_ALL; - vlan_features = bond->first_slave->dev->vlan_features; bond_for_each_slave(bond, slave, i) { features = netdev_increment_features(features, slave->dev->features, NETIF_F_ONE_FOR_ALL); + } + + return features; +} + +static int bond_set_features(struct net_device *bond_dev, u32 features) +{ + struct bonding *bond = netdev_priv(bond_dev); + struct slave *slave; + unsigned short max_hard_header_len = ETH_HLEN; + u32 vlan_features = 0; + int i; + + if (!bond->first_slave) + return 0; + + vlan_features = bond->first_slave->dev->vlan_features; + bond_for_each_slave(bond, slave, i) { vlan_features = netdev_increment_features(vlan_features, slave->dev->vlan_features, NETIF_F_ONE_FOR_ALL); @@ -1426,10 +1439,8 @@ static int bond_compute_features(struct bonding *bond) max_hard_header_len = slave->dev->hard_header_len; } -done: - features |= (bond_dev->features & BOND_VLAN_FEATURES); - bond_dev->features = netdev_fix_features(bond_dev, features); - bond_dev->vlan_features = netdev_fix_features(bond_dev, vlan_features); + /* vlan_features will be trimmed by vlan devices */ + bond_dev->vlan_features = vlan_features; bond_dev->hard_header_len = max_hard_header_len; return 0; @@ -1757,7 +1768,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) new_slave->delay = 0; new_slave->link_failure_count = 0; - bond_compute_features(bond); + netdev_update_features(bond_dev); write_unlock_bh(&bond->lock); @@ -2021,7 +2032,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) /* release the slave from its bond */ bond_detach_slave(bond, slave); - bond_compute_features(bond); + netdev_update_features(bond_dev); if (bond->primary_slave == slave) bond->primary_slave = NULL; @@ -2201,7 +2212,7 @@ static int bond_release_all(struct net_device *bond_dev) bond_alb_deinit_slave(bond, slave); } - bond_compute_features(bond); + netdev_update_features(bond_dev); bond_destroy_slave_symlinks(bond_dev, slave_dev); bond_del_vlans_from_slave(bond, slave_dev); @@ -3380,7 +3391,7 @@ static int bond_slave_netdev_event(unsigned long event, */ break; case NETDEV_FEAT_CHANGE: - bond_compute_features(bond); + netdev_update_features(bond_dev); break; default: break; @@ -4478,6 +4489,8 @@ static const struct net_device_ops bond_netdev_ops = { #endif .ndo_add_slave = bond_enslave, .ndo_del_slave = bond_release, + .ndo_fix_features = bond_fix_features, + .ndo_set_features = bond_set_features, }; static void bond_destructor(struct net_device *bond_dev)