diff options
author | Jiri Pirko <jpirko@redhat.com> | 2011-02-23 04:05:42 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-02-28 02:29:01 -0500 |
commit | 5b2c4dd2ec12cf0e53b2bd2926f0fe2d1fbb4eda (patch) | |
tree | 281cf5e006d738d5121153c564d9b1f48171a366 /drivers/net/bonding/bond_main.c | |
parent | e3dfa389fd2c79526b4bbf295726b66d21001664 (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/bond_main.c')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 74 |
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 | */ | ||
1473 | static 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 | |||
1496 | static 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> */ |
1470 | int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | 1531 | int 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) | |||
1856 | err_close: | 1923 | err_close: |
1857 | dev_close(slave_dev); | 1924 | dev_close(slave_dev); |
1858 | 1925 | ||
1926 | err_unreg_rxhandler: | ||
1927 | netdev_rx_handler_unregister(slave_dev); | ||
1928 | |||
1859 | err_unset_master: | 1929 | err_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); |