bonding: do vlan cleanup

Now when all devices are cleaned up, bond can be cleaned up as well

- remove bond->vlgrp
- remove bond_vlan_rx_register
- substitute necessary occurences of vlan_group_get_device

Signed-off-by: Jiri Pirko <jpirko@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Jiri Pirko 2011-07-20 04:54:46 +00:00 committed by David S. Miller
parent 9d846fec22
commit cc0e407006
4 changed files with 33 additions and 83 deletions

View File

@ -635,7 +635,7 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon
client_info->ntt = 0; client_info->ntt = 0;
} }
if (bond->vlgrp) { if (bond_vlan_used(bond)) {
if (!vlan_get_tag(skb, &client_info->vlan_id)) if (!vlan_get_tag(skb, &client_info->vlan_id))
client_info->tag = 1; client_info->tag = 1;
} }
@ -847,7 +847,7 @@ static void alb_send_learning_packets(struct slave *slave, u8 mac_addr[])
skb->priority = TC_PRIO_CONTROL; skb->priority = TC_PRIO_CONTROL;
skb->dev = slave->dev; skb->dev = slave->dev;
if (bond->vlgrp) { if (bond_vlan_used(bond)) {
struct vlan_entry *vlan; struct vlan_entry *vlan;
vlan = bond_next_vlan(bond, vlan = bond_next_vlan(bond,

View File

@ -183,10 +183,10 @@ static int bond_inet6addr_event(struct notifier_block *this,
} }
list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
if (!bond->vlgrp) rcu_read_lock();
continue; vlan_dev = __vlan_find_dev_deep(bond->dev,
vlan_dev = vlan_group_get_device(bond->vlgrp,
vlan->vlan_id); vlan->vlan_id);
rcu_read_unlock();
if (vlan_dev == event_dev) { if (vlan_dev == event_dev) {
switch (event) { switch (event) {
case NETDEV_UP: case NETDEV_UP:

View File

@ -408,9 +408,8 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
} }
/* /*
* In the following 3 functions, bond_vlan_rx_register(), bond_vlan_rx_add_vid * In the following 2 functions, bond_vlan_rx_add_vid and bond_vlan_rx_kill_vid,
* and bond_vlan_rx_kill_vid, We don't protect the slave list iteration with a * We don't protect the slave list iteration with a lock because:
* lock because:
* a. This operation is performed in IOCTL context, * a. This operation is performed in IOCTL context,
* b. The operation is protected by the RTNL semaphore in the 8021q code, * b. The operation is protected by the RTNL semaphore in the 8021q code,
* c. Holding a lock with BH disabled while directly calling a base driver * c. Holding a lock with BH disabled while directly calling a base driver
@ -425,33 +424,6 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
* worse, and if it works for regular VLAN usage it will work here too. * worse, and if it works for regular VLAN usage it will work here too.
*/ */
/**
* bond_vlan_rx_register - Propagates registration to slaves
* @bond_dev: bonding net device that got called
* @grp: vlan group being registered
*/
static void bond_vlan_rx_register(struct net_device *bond_dev,
struct vlan_group *grp)
{
struct bonding *bond = netdev_priv(bond_dev);
struct slave *slave;
int i;
write_lock_bh(&bond->lock);
bond->vlgrp = grp;
write_unlock_bh(&bond->lock);
bond_for_each_slave(bond, slave, i) {
struct net_device *slave_dev = slave->dev;
const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
if ((slave_dev->features & NETIF_F_HW_VLAN_RX) &&
slave_ops->ndo_vlan_rx_register) {
slave_ops->ndo_vlan_rx_register(slave_dev, grp);
}
}
}
/** /**
* bond_vlan_rx_add_vid - Propagates adding an id to slaves * bond_vlan_rx_add_vid - Propagates adding an id to slaves
* @bond_dev: bonding net device that got called * @bond_dev: bonding net device that got called
@ -489,7 +461,6 @@ static void bond_vlan_rx_kill_vid(struct net_device *bond_dev, uint16_t vid)
{ {
struct bonding *bond = netdev_priv(bond_dev); struct bonding *bond = netdev_priv(bond_dev);
struct slave *slave; struct slave *slave;
struct net_device *vlan_dev;
int i, res; int i, res;
bond_for_each_slave(bond, slave, i) { bond_for_each_slave(bond, slave, i) {
@ -498,12 +469,7 @@ static void bond_vlan_rx_kill_vid(struct net_device *bond_dev, uint16_t vid)
if ((slave_dev->features & NETIF_F_HW_VLAN_FILTER) && if ((slave_dev->features & NETIF_F_HW_VLAN_FILTER) &&
slave_ops->ndo_vlan_rx_kill_vid) { slave_ops->ndo_vlan_rx_kill_vid) {
/* Save and then restore vlan_dev in the grp array,
* since the slave's driver might clear it.
*/
vlan_dev = vlan_group_get_device(bond->vlgrp, vid);
slave_ops->ndo_vlan_rx_kill_vid(slave_dev, vid); slave_ops->ndo_vlan_rx_kill_vid(slave_dev, vid);
vlan_group_set_device(bond->vlgrp, vid, vlan_dev);
} }
} }
@ -519,13 +485,6 @@ static void bond_add_vlans_on_slave(struct bonding *bond, struct net_device *sla
struct vlan_entry *vlan; struct vlan_entry *vlan;
const struct net_device_ops *slave_ops = slave_dev->netdev_ops; const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
if (!bond->vlgrp)
return;
if ((slave_dev->features & NETIF_F_HW_VLAN_RX) &&
slave_ops->ndo_vlan_rx_register)
slave_ops->ndo_vlan_rx_register(slave_dev, bond->vlgrp);
if (!(slave_dev->features & NETIF_F_HW_VLAN_FILTER) || if (!(slave_dev->features & NETIF_F_HW_VLAN_FILTER) ||
!(slave_ops->ndo_vlan_rx_add_vid)) !(slave_ops->ndo_vlan_rx_add_vid))
return; return;
@ -539,30 +498,16 @@ static void bond_del_vlans_from_slave(struct bonding *bond,
{ {
const struct net_device_ops *slave_ops = slave_dev->netdev_ops; const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
struct vlan_entry *vlan; struct vlan_entry *vlan;
struct net_device *vlan_dev;
if (!bond->vlgrp)
return;
if (!(slave_dev->features & NETIF_F_HW_VLAN_FILTER) || if (!(slave_dev->features & NETIF_F_HW_VLAN_FILTER) ||
!(slave_ops->ndo_vlan_rx_kill_vid)) !(slave_ops->ndo_vlan_rx_kill_vid))
goto unreg; return;
list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
if (!vlan->vlan_id) if (!vlan->vlan_id)
continue; continue;
/* Save and then restore vlan_dev in the grp array,
* since the slave's driver might clear it.
*/
vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id);
slave_ops->ndo_vlan_rx_kill_vid(slave_dev, vlan->vlan_id); slave_ops->ndo_vlan_rx_kill_vid(slave_dev, vlan->vlan_id);
vlan_group_set_device(bond->vlgrp, vlan->vlan_id, vlan_dev);
} }
unreg:
if ((slave_dev->features & NETIF_F_HW_VLAN_RX) &&
slave_ops->ndo_vlan_rx_register)
slave_ops->ndo_vlan_rx_register(slave_dev, NULL);
} }
/*------------------------------- Link status -------------------------------*/ /*------------------------------- Link status -------------------------------*/
@ -836,14 +781,14 @@ static void bond_resend_igmp_join_requests(struct bonding *bond)
__bond_resend_igmp_join_requests(bond->dev); __bond_resend_igmp_join_requests(bond->dev);
/* rejoin all groups on vlan devices */ /* rejoin all groups on vlan devices */
if (bond->vlgrp) {
list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
vlan_dev = vlan_group_get_device(bond->vlgrp, rcu_read_lock();
vlan_dev = __vlan_find_dev_deep(bond->dev,
vlan->vlan_id); vlan->vlan_id);
rcu_read_unlock();
if (vlan_dev) if (vlan_dev)
__bond_resend_igmp_join_requests(vlan_dev); __bond_resend_igmp_join_requests(vlan_dev);
} }
}
if (--bond->igmp_retrans > 0) if (--bond->igmp_retrans > 0)
queue_delayed_work(bond->wq, &bond->mcast_work, HZ/5); queue_delayed_work(bond->wq, &bond->mcast_work, HZ/5);
@ -1557,7 +1502,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
/* no need to lock since we're protected by rtnl_lock */ /* no need to lock since we're protected by rtnl_lock */
if (slave_dev->features & NETIF_F_VLAN_CHALLENGED) { if (slave_dev->features & NETIF_F_VLAN_CHALLENGED) {
pr_debug("%s: NETIF_F_VLAN_CHALLENGED\n", slave_dev->name); pr_debug("%s: NETIF_F_VLAN_CHALLENGED\n", slave_dev->name);
if (bond->vlgrp) { if (bond_vlan_used(bond)) {
pr_err("%s: Error: cannot enslave VLAN challenged slave %s on VLAN enabled bond %s\n", pr_err("%s: Error: cannot enslave VLAN challenged slave %s on VLAN enabled bond %s\n",
bond_dev->name, slave_dev->name, bond_dev->name); bond_dev->name, slave_dev->name, bond_dev->name);
return -EPERM; return -EPERM;
@ -2065,7 +2010,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
*/ */
memset(bond_dev->dev_addr, 0, bond_dev->addr_len); memset(bond_dev->dev_addr, 0, bond_dev->addr_len);
if (bond->vlgrp) { if (bond_vlan_used(bond)) {
pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n", pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n",
bond_dev->name, bond_dev->name); bond_dev->name, bond_dev->name);
pr_warning("%s: When re-adding slaves, make sure the bond's HW address matches its VLANs'.\n", pr_warning("%s: When re-adding slaves, make sure the bond's HW address matches its VLANs'.\n",
@ -2247,7 +2192,7 @@ static int bond_release_all(struct net_device *bond_dev)
*/ */
memset(bond_dev->dev_addr, 0, bond_dev->addr_len); memset(bond_dev->dev_addr, 0, bond_dev->addr_len);
if (bond->vlgrp) { if (bond_vlan_used(bond)) {
pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n", pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n",
bond_dev->name, bond_dev->name); bond_dev->name, bond_dev->name);
pr_warning("%s: When re-adding slaves, make sure the bond's HW address matches its VLANs'.\n", pr_warning("%s: When re-adding slaves, make sure the bond's HW address matches its VLANs'.\n",
@ -2685,7 +2630,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
if (!targets[i]) if (!targets[i])
break; break;
pr_debug("basa: target %x\n", targets[i]); pr_debug("basa: target %x\n", targets[i]);
if (!bond->vlgrp) { if (!bond_vlan_used(bond)) {
pr_debug("basa: empty vlan: arp_send\n"); pr_debug("basa: empty vlan: arp_send\n");
bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i],
bond->master_ip, 0); bond->master_ip, 0);
@ -2720,7 +2665,10 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
vlan_id = 0; vlan_id = 0;
list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id); rcu_read_lock();
vlan_dev = __vlan_find_dev_deep(bond->dev,
vlan->vlan_id);
rcu_read_unlock();
if (vlan_dev == rt->dst.dev) { if (vlan_dev == rt->dst.dev) {
vlan_id = vlan->vlan_id; vlan_id = vlan->vlan_id;
pr_debug("basa: vlan match on %s %d\n", pr_debug("basa: vlan match on %s %d\n",
@ -3381,9 +3329,8 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event,
} }
list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
if (!bond->vlgrp) vlan_dev = __vlan_find_dev_deep(bond->dev,
continue; vlan->vlan_id);
vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id);
if (vlan_dev == event_dev) { if (vlan_dev == event_dev) {
switch (event) { switch (event) {
case NETDEV_UP: case NETDEV_UP:
@ -4337,7 +4284,6 @@ static const struct net_device_ops bond_netdev_ops = {
.ndo_change_mtu = bond_change_mtu, .ndo_change_mtu = bond_change_mtu,
.ndo_set_mac_address = bond_set_mac_address, .ndo_set_mac_address = bond_set_mac_address,
.ndo_neigh_setup = bond_neigh_setup, .ndo_neigh_setup = bond_neigh_setup,
.ndo_vlan_rx_register = bond_vlan_rx_register,
.ndo_vlan_rx_add_vid = bond_vlan_rx_add_vid, .ndo_vlan_rx_add_vid = bond_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = bond_vlan_rx_kill_vid, .ndo_vlan_rx_kill_vid = bond_vlan_rx_kill_vid,
#ifdef CONFIG_NET_POLL_CONTROLLER #ifdef CONFIG_NET_POLL_CONTROLLER

View File

@ -240,7 +240,6 @@ struct bonding {
struct alb_bond_info alb_info; struct alb_bond_info alb_info;
struct bond_params params; struct bond_params params;
struct list_head vlan_list; struct list_head vlan_list;
struct vlan_group *vlgrp;
struct workqueue_struct *wq; struct workqueue_struct *wq;
struct delayed_work mii_work; struct delayed_work mii_work;
struct delayed_work arp_work; struct delayed_work arp_work;
@ -253,6 +252,11 @@ struct bonding {
#endif /* CONFIG_DEBUG_FS */ #endif /* CONFIG_DEBUG_FS */
}; };
static inline bool bond_vlan_used(struct bonding *bond)
{
return !list_empty(&bond->vlan_list);
}
#define bond_slave_get_rcu(dev) \ #define bond_slave_get_rcu(dev) \
((struct slave *) rcu_dereference(dev->rx_handler_data)) ((struct slave *) rcu_dereference(dev->rx_handler_data))