aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding
diff options
context:
space:
mode:
authorJiri Pirko <jpirko@redhat.com>2011-12-07 23:11:17 -0500
committerDavid S. Miller <davem@davemloft.net>2011-12-08 19:52:42 -0500
commit87002b03baabd2b8f6281ab6411ed88d24958de1 (patch)
tree0e5730c0d1ba887488ba420d4ea89a230f272c51 /drivers/net/bonding
parent8e586137e6b63af1e881b328466ab5ffbe562510 (diff)
net: introduce vlan_vid_[add/del] and use them instead of direct [add/kill]_vid ndo calls
This patch adds wrapper for ndo_vlan_rx_add_vid/ndo_vlan_rx_kill_vid functions. Check for NETIF_F_HW_VLAN_FILTER feature is done in this wrapper. Signed-off-by: Jiri Pirko <jpirko@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r--drivers/net/bonding/bond_main.c53
1 files changed, 23 insertions, 30 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index d72c37f03e50..0c0dacba1f51 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -431,17 +431,13 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb,
431static int bond_vlan_rx_add_vid(struct net_device *bond_dev, uint16_t vid) 431static int bond_vlan_rx_add_vid(struct net_device *bond_dev, uint16_t vid)
432{ 432{
433 struct bonding *bond = netdev_priv(bond_dev); 433 struct bonding *bond = netdev_priv(bond_dev);
434 struct slave *slave; 434 struct slave *slave, *stop_at;
435 int i, res; 435 int i, res;
436 436
437 bond_for_each_slave(bond, slave, i) { 437 bond_for_each_slave(bond, slave, i) {
438 struct net_device *slave_dev = slave->dev; 438 res = vlan_vid_add(slave->dev, vid);
439 const struct net_device_ops *slave_ops = slave_dev->netdev_ops; 439 if (res)
440 440 goto unwind;
441 if ((slave_dev->features & NETIF_F_HW_VLAN_FILTER) &&
442 slave_ops->ndo_vlan_rx_add_vid) {
443 slave_ops->ndo_vlan_rx_add_vid(slave_dev, vid);
444 }
445 } 441 }
446 442
447 res = bond_add_vlan(bond, vid); 443 res = bond_add_vlan(bond, vid);
@@ -452,6 +448,14 @@ static int bond_vlan_rx_add_vid(struct net_device *bond_dev, uint16_t vid)
452 } 448 }
453 449
454 return 0; 450 return 0;
451
452unwind:
453 /* unwind from head to the slave that failed */
454 stop_at = slave;
455 bond_for_each_slave_from_to(bond, slave, i, bond->first_slave, stop_at)
456 vlan_vid_del(slave->dev, vid);
457
458 return res;
455} 459}
456 460
457/** 461/**
@@ -465,15 +469,8 @@ static int bond_vlan_rx_kill_vid(struct net_device *bond_dev, uint16_t vid)
465 struct slave *slave; 469 struct slave *slave;
466 int i, res; 470 int i, res;
467 471
468 bond_for_each_slave(bond, slave, i) { 472 bond_for_each_slave(bond, slave, i)
469 struct net_device *slave_dev = slave->dev; 473 vlan_vid_del(slave->dev, vid);
470 const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
471
472 if ((slave_dev->features & NETIF_F_HW_VLAN_FILTER) &&
473 slave_ops->ndo_vlan_rx_kill_vid) {
474 slave_ops->ndo_vlan_rx_kill_vid(slave_dev, vid);
475 }
476 }
477 474
478 res = bond_del_vlan(bond, vid); 475 res = bond_del_vlan(bond, vid);
479 if (res) { 476 if (res) {
@@ -488,30 +485,26 @@ static int bond_vlan_rx_kill_vid(struct net_device *bond_dev, uint16_t vid)
488static void bond_add_vlans_on_slave(struct bonding *bond, struct net_device *slave_dev) 485static void bond_add_vlans_on_slave(struct bonding *bond, struct net_device *slave_dev)
489{ 486{
490 struct vlan_entry *vlan; 487 struct vlan_entry *vlan;
491 const struct net_device_ops *slave_ops = slave_dev->netdev_ops; 488 int res;
492
493 if (!(slave_dev->features & NETIF_F_HW_VLAN_FILTER) ||
494 !(slave_ops->ndo_vlan_rx_add_vid))
495 return;
496 489
497 list_for_each_entry(vlan, &bond->vlan_list, vlan_list) 490 list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
498 slave_ops->ndo_vlan_rx_add_vid(slave_dev, vlan->vlan_id); 491 res = vlan_vid_add(slave_dev, vlan->vlan_id);
492 if (res)
493 pr_warning("%s: Failed to add vlan id %d to device %s\n",
494 bond->dev->name, vlan->vlan_id,
495 slave_dev->name);
496 }
499} 497}
500 498
501static void bond_del_vlans_from_slave(struct bonding *bond, 499static void bond_del_vlans_from_slave(struct bonding *bond,
502 struct net_device *slave_dev) 500 struct net_device *slave_dev)
503{ 501{
504 const struct net_device_ops *slave_ops = slave_dev->netdev_ops;
505 struct vlan_entry *vlan; 502 struct vlan_entry *vlan;
506 503
507 if (!(slave_dev->features & NETIF_F_HW_VLAN_FILTER) ||
508 !(slave_ops->ndo_vlan_rx_kill_vid))
509 return;
510
511 list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { 504 list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
512 if (!vlan->vlan_id) 505 if (!vlan->vlan_id)
513 continue; 506 continue;
514 slave_ops->ndo_vlan_rx_kill_vid(slave_dev, vlan->vlan_id); 507 vlan_vid_del(slave_dev, vlan->vlan_id);
515 } 508 }
516} 509}
517 510