aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding
diff options
context:
space:
mode:
authorJiri Pirko <jpirko@redhat.com>2011-02-23 04:05:42 -0500
committerDavid S. Miller <davem@davemloft.net>2011-02-28 02:29:01 -0500
commit5b2c4dd2ec12cf0e53b2bd2926f0fe2d1fbb4eda (patch)
tree281cf5e006d738d5121153c564d9b1f48171a366 /drivers/net/bonding
parente3dfa389fd2c79526b4bbf295726b66d21001664 (diff)
net: convert bonding to use rx_handler
This patch converts bonding to use rx_handler. Results in cleaner __netif_receive_skb() with much less exceptions needed. Also bond-specific work is moved into bond code. Did performance test using pktgen and counting incoming packets by iptables. No regression noted. Signed-off-by: Jiri Pirko <jpirko@redhat.com> Reviewed-by: Nicolas de Pesloüan <nicolas.2p.debian@free.fr> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r--drivers/net/bonding/bond_main.c74
1 files changed, 73 insertions, 1 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index c75126ddc646..584f97b73060 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1466,6 +1466,67 @@ static void bond_setup_by_slave(struct net_device *bond_dev,
1466 bond->setup_by_slave = 1; 1466 bond->setup_by_slave = 1;
1467} 1467}
1468 1468
1469/* On bonding slaves other than the currently active slave, suppress
1470 * duplicates except for 802.3ad ETH_P_SLOW, alb non-mcast/bcast, and
1471 * ARP on active-backup slaves with arp_validate enabled.
1472 */
1473static bool bond_should_deliver_exact_match(struct sk_buff *skb,
1474 struct net_device *slave_dev,
1475 struct net_device *bond_dev)
1476{
1477 if (slave_dev->priv_flags & IFF_SLAVE_INACTIVE) {
1478 if (slave_dev->priv_flags & IFF_SLAVE_NEEDARP &&
1479 skb->protocol == __cpu_to_be16(ETH_P_ARP))
1480 return false;
1481
1482 if (bond_dev->priv_flags & IFF_MASTER_ALB &&
1483 skb->pkt_type != PACKET_BROADCAST &&
1484 skb->pkt_type != PACKET_MULTICAST)
1485 return false;
1486
1487 if (bond_dev->priv_flags & IFF_MASTER_8023AD &&
1488 skb->protocol == __cpu_to_be16(ETH_P_SLOW))
1489 return false;
1490
1491 return true;
1492 }
1493 return false;
1494}
1495
1496static struct sk_buff *bond_handle_frame(struct sk_buff *skb)
1497{
1498 struct net_device *slave_dev;
1499 struct net_device *bond_dev;
1500
1501 skb = skb_share_check(skb, GFP_ATOMIC);
1502 if (unlikely(!skb))
1503 return NULL;
1504 slave_dev = skb->dev;
1505 bond_dev = ACCESS_ONCE(slave_dev->master);
1506 if (unlikely(!bond_dev))
1507 return skb;
1508
1509 if (bond_dev->priv_flags & IFF_MASTER_ARPMON)
1510 slave_dev->last_rx = jiffies;
1511
1512 if (bond_should_deliver_exact_match(skb, slave_dev, bond_dev)) {
1513 skb->deliver_no_wcard = 1;
1514 return skb;
1515 }
1516
1517 skb->dev = bond_dev;
1518
1519 if (bond_dev->priv_flags & IFF_MASTER_ALB &&
1520 bond_dev->priv_flags & IFF_BRIDGE_PORT &&
1521 skb->pkt_type == PACKET_HOST) {
1522 u16 *dest = (u16 *) eth_hdr(skb)->h_dest;
1523
1524 memcpy(dest, bond_dev->dev_addr, ETH_ALEN);
1525 }
1526
1527 return skb;
1528}
1529
1469/* enslave device <slave> to bond device <master> */ 1530/* enslave device <slave> to bond device <master> */
1470int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) 1531int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1471{ 1532{
@@ -1642,11 +1703,17 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1642 pr_debug("Error %d calling netdev_set_bond_master\n", res); 1703 pr_debug("Error %d calling netdev_set_bond_master\n", res);
1643 goto err_restore_mac; 1704 goto err_restore_mac;
1644 } 1705 }
1706 res = netdev_rx_handler_register(slave_dev, bond_handle_frame, NULL);
1707 if (res) {
1708 pr_debug("Error %d calling netdev_rx_handler_register\n", res);
1709 goto err_unset_master;
1710 }
1711
1645 /* open the slave since the application closed it */ 1712 /* open the slave since the application closed it */
1646 res = dev_open(slave_dev); 1713 res = dev_open(slave_dev);
1647 if (res) { 1714 if (res) {
1648 pr_debug("Opening slave %s failed\n", slave_dev->name); 1715 pr_debug("Opening slave %s failed\n", slave_dev->name);
1649 goto err_unset_master; 1716 goto err_unreg_rxhandler;
1650 } 1717 }
1651 1718
1652 new_slave->dev = slave_dev; 1719 new_slave->dev = slave_dev;
@@ -1856,6 +1923,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1856err_close: 1923err_close:
1857 dev_close(slave_dev); 1924 dev_close(slave_dev);
1858 1925
1926err_unreg_rxhandler:
1927 netdev_rx_handler_unregister(slave_dev);
1928
1859err_unset_master: 1929err_unset_master:
1860 netdev_set_bond_master(slave_dev, NULL); 1930 netdev_set_bond_master(slave_dev, NULL);
1861 1931
@@ -2037,6 +2107,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
2037 netif_addr_unlock_bh(bond_dev); 2107 netif_addr_unlock_bh(bond_dev);
2038 } 2108 }
2039 2109
2110 netdev_rx_handler_unregister(slave_dev);
2040 netdev_set_bond_master(slave_dev, NULL); 2111 netdev_set_bond_master(slave_dev, NULL);
2041 2112
2042 slave_disable_netpoll(slave); 2113 slave_disable_netpoll(slave);
@@ -2150,6 +2221,7 @@ static int bond_release_all(struct net_device *bond_dev)
2150 netif_addr_unlock_bh(bond_dev); 2221 netif_addr_unlock_bh(bond_dev);
2151 } 2222 }
2152 2223
2224 netdev_rx_handler_unregister(slave_dev);
2153 netdev_set_bond_master(slave_dev, NULL); 2225 netdev_set_bond_master(slave_dev, NULL);
2154 2226
2155 slave_disable_netpoll(slave); 2227 slave_disable_netpoll(slave);