|
@@ -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
|
|
|
- * and bond_vlan_rx_kill_vid, We don't protect the slave list iteration with a
|
|
|
- * lock because:
|
|
|
+ * In the following 2 functions, bond_vlan_rx_add_vid and bond_vlan_rx_kill_vid,
|
|
|
+ * We don't protect the slave list iteration with a lock because:
|
|
|
* a. This operation is performed in IOCTL context,
|
|
|
* 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
|
|
@@ -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.
|
|
|
*/
|
|
|
|
|
|
-/**
|
|
|
- * 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_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 slave *slave;
|
|
|
- struct net_device *vlan_dev;
|
|
|
int i, res;
|
|
|
|
|
|
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) &&
|
|
|
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);
|
|
|
- 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;
|
|
|
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) ||
|
|
|
!(slave_ops->ndo_vlan_rx_add_vid))
|
|
|
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;
|
|
|
struct vlan_entry *vlan;
|
|
|
- struct net_device *vlan_dev;
|
|
|
-
|
|
|
- if (!bond->vlgrp)
|
|
|
- return;
|
|
|
|
|
|
if (!(slave_dev->features & NETIF_F_HW_VLAN_FILTER) ||
|
|
|
!(slave_ops->ndo_vlan_rx_kill_vid))
|
|
|
- goto unreg;
|
|
|
+ return;
|
|
|
|
|
|
list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
|
|
|
if (!vlan->vlan_id)
|
|
|
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);
|
|
|
- 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 -------------------------------*/
|
|
@@ -836,13 +781,13 @@ static void bond_resend_igmp_join_requests(struct bonding *bond)
|
|
|
__bond_resend_igmp_join_requests(bond->dev);
|
|
|
|
|
|
/* rejoin all groups on vlan devices */
|
|
|
- if (bond->vlgrp) {
|
|
|
- list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
|
|
|
- vlan_dev = vlan_group_get_device(bond->vlgrp,
|
|
|
- vlan->vlan_id);
|
|
|
- if (vlan_dev)
|
|
|
- __bond_resend_igmp_join_requests(vlan_dev);
|
|
|
- }
|
|
|
+ list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
|
|
|
+ rcu_read_lock();
|
|
|
+ vlan_dev = __vlan_find_dev_deep(bond->dev,
|
|
|
+ vlan->vlan_id);
|
|
|
+ rcu_read_unlock();
|
|
|
+ if (vlan_dev)
|
|
|
+ __bond_resend_igmp_join_requests(vlan_dev);
|
|
|
}
|
|
|
|
|
|
if (--bond->igmp_retrans > 0)
|
|
@@ -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 */
|
|
|
if (slave_dev->features & NETIF_F_VLAN_CHALLENGED) {
|
|
|
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",
|
|
|
bond_dev->name, slave_dev->name, bond_dev->name);
|
|
|
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);
|
|
|
|
|
|
- if (bond->vlgrp) {
|
|
|
+ if (bond_vlan_used(bond)) {
|
|
|
pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n",
|
|
|
bond_dev->name, bond_dev->name);
|
|
|
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);
|
|
|
|
|
|
- if (bond->vlgrp) {
|
|
|
+ if (bond_vlan_used(bond)) {
|
|
|
pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n",
|
|
|
bond_dev->name, bond_dev->name);
|
|
|
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])
|
|
|
break;
|
|
|
pr_debug("basa: target %x\n", targets[i]);
|
|
|
- if (!bond->vlgrp) {
|
|
|
+ if (!bond_vlan_used(bond)) {
|
|
|
pr_debug("basa: empty vlan: arp_send\n");
|
|
|
bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i],
|
|
|
bond->master_ip, 0);
|
|
@@ -2720,7 +2665,10 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
|
|
|
|
|
|
vlan_id = 0;
|
|
|
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) {
|
|
|
vlan_id = vlan->vlan_id;
|
|
|
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) {
|
|
|
- if (!bond->vlgrp)
|
|
|
- continue;
|
|
|
- vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id);
|
|
|
+ vlan_dev = __vlan_find_dev_deep(bond->dev,
|
|
|
+ vlan->vlan_id);
|
|
|
if (vlan_dev == event_dev) {
|
|
|
switch (event) {
|
|
|
case NETDEV_UP:
|
|
@@ -4335,10 +4282,9 @@ static const struct net_device_ops bond_netdev_ops = {
|
|
|
.ndo_do_ioctl = bond_do_ioctl,
|
|
|
.ndo_set_multicast_list = bond_set_multicast_list,
|
|
|
.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_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,
|
|
|
#ifdef CONFIG_NET_POLL_CONTROLLER
|
|
|
.ndo_netpoll_setup = bond_netpoll_setup,
|