diff options
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 130 |
1 files changed, 114 insertions, 16 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 5e12462a9d5e..a95a41b74b4e 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -90,6 +90,7 @@ | |||
90 | #define BOND_LINK_ARP_INTERV 0 | 90 | #define BOND_LINK_ARP_INTERV 0 |
91 | 91 | ||
92 | static int max_bonds = BOND_DEFAULT_MAX_BONDS; | 92 | static int max_bonds = BOND_DEFAULT_MAX_BONDS; |
93 | static int tx_queues = BOND_DEFAULT_TX_QUEUES; | ||
93 | static int num_grat_arp = 1; | 94 | static int num_grat_arp = 1; |
94 | static int num_unsol_na = 1; | 95 | static int num_unsol_na = 1; |
95 | static int miimon = BOND_LINK_MON_INTERV; | 96 | static int miimon = BOND_LINK_MON_INTERV; |
@@ -106,10 +107,13 @@ static int arp_interval = BOND_LINK_ARP_INTERV; | |||
106 | static char *arp_ip_target[BOND_MAX_ARP_TARGETS]; | 107 | static char *arp_ip_target[BOND_MAX_ARP_TARGETS]; |
107 | static char *arp_validate; | 108 | static char *arp_validate; |
108 | static char *fail_over_mac; | 109 | static char *fail_over_mac; |
110 | static int all_slaves_active = 0; | ||
109 | static struct bond_params bonding_defaults; | 111 | static struct bond_params bonding_defaults; |
110 | 112 | ||
111 | module_param(max_bonds, int, 0); | 113 | module_param(max_bonds, int, 0); |
112 | MODULE_PARM_DESC(max_bonds, "Max number of bonded devices"); | 114 | MODULE_PARM_DESC(max_bonds, "Max number of bonded devices"); |
115 | module_param(tx_queues, int, 0); | ||
116 | MODULE_PARM_DESC(tx_queues, "Max number of transmit queues (default = 16)"); | ||
113 | module_param(num_grat_arp, int, 0644); | 117 | module_param(num_grat_arp, int, 0644); |
114 | MODULE_PARM_DESC(num_grat_arp, "Number of gratuitous ARP packets to send on failover event"); | 118 | MODULE_PARM_DESC(num_grat_arp, "Number of gratuitous ARP packets to send on failover event"); |
115 | module_param(num_unsol_na, int, 0644); | 119 | module_param(num_unsol_na, int, 0644); |
@@ -155,6 +159,10 @@ module_param(arp_validate, charp, 0); | |||
155 | MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes: none (default), active, backup or all"); | 159 | MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes: none (default), active, backup or all"); |
156 | module_param(fail_over_mac, charp, 0); | 160 | module_param(fail_over_mac, charp, 0); |
157 | MODULE_PARM_DESC(fail_over_mac, "For active-backup, do not set all slaves to the same MAC. none (default), active or follow"); | 161 | MODULE_PARM_DESC(fail_over_mac, "For active-backup, do not set all slaves to the same MAC. none (default), active or follow"); |
162 | module_param(all_slaves_active, int, 0); | ||
163 | MODULE_PARM_DESC(all_slaves_active, "Keep all frames received on an interface" | ||
164 | "by setting active flag for all slaves. " | ||
165 | "0 for never (default), 1 for always."); | ||
158 | 166 | ||
159 | /*----------------------------- Global variables ----------------------------*/ | 167 | /*----------------------------- Global variables ----------------------------*/ |
160 | 168 | ||
@@ -1522,16 +1530,32 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1522 | } | 1530 | } |
1523 | } | 1531 | } |
1524 | 1532 | ||
1533 | /* If this is the first slave, then we need to set the master's hardware | ||
1534 | * address to be the same as the slave's. */ | ||
1535 | if (bond->slave_cnt == 0) | ||
1536 | memcpy(bond->dev->dev_addr, slave_dev->dev_addr, | ||
1537 | slave_dev->addr_len); | ||
1538 | |||
1539 | |||
1525 | new_slave = kzalloc(sizeof(struct slave), GFP_KERNEL); | 1540 | new_slave = kzalloc(sizeof(struct slave), GFP_KERNEL); |
1526 | if (!new_slave) { | 1541 | if (!new_slave) { |
1527 | res = -ENOMEM; | 1542 | res = -ENOMEM; |
1528 | goto err_undo_flags; | 1543 | goto err_undo_flags; |
1529 | } | 1544 | } |
1530 | 1545 | ||
1531 | /* save slave's original flags before calling | 1546 | /* |
1532 | * netdev_set_master and dev_open | 1547 | * Set the new_slave's queue_id to be zero. Queue ID mapping |
1548 | * is set via sysfs or module option if desired. | ||
1533 | */ | 1549 | */ |
1534 | new_slave->original_flags = slave_dev->flags; | 1550 | new_slave->queue_id = 0; |
1551 | |||
1552 | /* Save slave's original mtu and then set it to match the bond */ | ||
1553 | new_slave->original_mtu = slave_dev->mtu; | ||
1554 | res = dev_set_mtu(slave_dev, bond->dev->mtu); | ||
1555 | if (res) { | ||
1556 | pr_debug("Error %d calling dev_set_mtu\n", res); | ||
1557 | goto err_free; | ||
1558 | } | ||
1535 | 1559 | ||
1536 | /* | 1560 | /* |
1537 | * Save slave's original ("permanent") mac address for modes | 1561 | * Save slave's original ("permanent") mac address for modes |
@@ -1550,7 +1574,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1550 | res = dev_set_mac_address(slave_dev, &addr); | 1574 | res = dev_set_mac_address(slave_dev, &addr); |
1551 | if (res) { | 1575 | if (res) { |
1552 | pr_debug("Error %d calling set_mac_address\n", res); | 1576 | pr_debug("Error %d calling set_mac_address\n", res); |
1553 | goto err_free; | 1577 | goto err_restore_mtu; |
1554 | } | 1578 | } |
1555 | } | 1579 | } |
1556 | 1580 | ||
@@ -1785,6 +1809,9 @@ err_restore_mac: | |||
1785 | dev_set_mac_address(slave_dev, &addr); | 1809 | dev_set_mac_address(slave_dev, &addr); |
1786 | } | 1810 | } |
1787 | 1811 | ||
1812 | err_restore_mtu: | ||
1813 | dev_set_mtu(slave_dev, new_slave->original_mtu); | ||
1814 | |||
1788 | err_free: | 1815 | err_free: |
1789 | kfree(new_slave); | 1816 | kfree(new_slave); |
1790 | 1817 | ||
@@ -1969,6 +1996,8 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1969 | dev_set_mac_address(slave_dev, &addr); | 1996 | dev_set_mac_address(slave_dev, &addr); |
1970 | } | 1997 | } |
1971 | 1998 | ||
1999 | dev_set_mtu(slave_dev, slave->original_mtu); | ||
2000 | |||
1972 | slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB | | 2001 | slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB | |
1973 | IFF_SLAVE_INACTIVE | IFF_BONDING | | 2002 | IFF_SLAVE_INACTIVE | IFF_BONDING | |
1974 | IFF_SLAVE_NEEDARP); | 2003 | IFF_SLAVE_NEEDARP); |
@@ -2555,7 +2584,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) | |||
2555 | /* | 2584 | /* |
2556 | * This target is not on a VLAN | 2585 | * This target is not on a VLAN |
2557 | */ | 2586 | */ |
2558 | if (rt->u.dst.dev == bond->dev) { | 2587 | if (rt->dst.dev == bond->dev) { |
2559 | ip_rt_put(rt); | 2588 | ip_rt_put(rt); |
2560 | pr_debug("basa: rtdev == bond->dev: arp_send\n"); | 2589 | pr_debug("basa: rtdev == bond->dev: arp_send\n"); |
2561 | bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], | 2590 | bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i], |
@@ -2566,7 +2595,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) | |||
2566 | vlan_id = 0; | 2595 | vlan_id = 0; |
2567 | list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { | 2596 | list_for_each_entry(vlan, &bond->vlan_list, vlan_list) { |
2568 | vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id); | 2597 | vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id); |
2569 | if (vlan_dev == rt->u.dst.dev) { | 2598 | if (vlan_dev == rt->dst.dev) { |
2570 | vlan_id = vlan->vlan_id; | 2599 | vlan_id = vlan->vlan_id; |
2571 | pr_debug("basa: vlan match on %s %d\n", | 2600 | pr_debug("basa: vlan match on %s %d\n", |
2572 | vlan_dev->name, vlan_id); | 2601 | vlan_dev->name, vlan_id); |
@@ -2584,7 +2613,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave) | |||
2584 | if (net_ratelimit()) { | 2613 | if (net_ratelimit()) { |
2585 | pr_warning("%s: no path to arp_ip_target %pI4 via rt.dev %s\n", | 2614 | pr_warning("%s: no path to arp_ip_target %pI4 via rt.dev %s\n", |
2586 | bond->dev->name, &fl.fl4_dst, | 2615 | bond->dev->name, &fl.fl4_dst, |
2587 | rt->u.dst.dev ? rt->u.dst.dev->name : "NULL"); | 2616 | rt->dst.dev ? rt->dst.dev->name : "NULL"); |
2588 | } | 2617 | } |
2589 | ip_rt_put(rt); | 2618 | ip_rt_put(rt); |
2590 | } | 2619 | } |
@@ -3265,6 +3294,7 @@ static void bond_info_show_slave(struct seq_file *seq, | |||
3265 | else | 3294 | else |
3266 | seq_puts(seq, "Aggregator ID: N/A\n"); | 3295 | seq_puts(seq, "Aggregator ID: N/A\n"); |
3267 | } | 3296 | } |
3297 | seq_printf(seq, "Slave queue ID: %d\n", slave->queue_id); | ||
3268 | } | 3298 | } |
3269 | 3299 | ||
3270 | static int bond_info_seq_show(struct seq_file *seq, void *v) | 3300 | static int bond_info_seq_show(struct seq_file *seq, void *v) |
@@ -3774,20 +3804,21 @@ static int bond_close(struct net_device *bond_dev) | |||
3774 | return 0; | 3804 | return 0; |
3775 | } | 3805 | } |
3776 | 3806 | ||
3777 | static struct net_device_stats *bond_get_stats(struct net_device *bond_dev) | 3807 | static struct rtnl_link_stats64 *bond_get_stats(struct net_device *bond_dev) |
3778 | { | 3808 | { |
3779 | struct bonding *bond = netdev_priv(bond_dev); | 3809 | struct bonding *bond = netdev_priv(bond_dev); |
3780 | struct net_device_stats *stats = &bond_dev->stats; | 3810 | struct rtnl_link_stats64 *stats = &bond_dev->stats64; |
3781 | struct net_device_stats local_stats; | 3811 | struct rtnl_link_stats64 local_stats; |
3782 | struct slave *slave; | 3812 | struct slave *slave; |
3783 | int i; | 3813 | int i; |
3784 | 3814 | ||
3785 | memset(&local_stats, 0, sizeof(struct net_device_stats)); | 3815 | memset(&local_stats, 0, sizeof(local_stats)); |
3786 | 3816 | ||
3787 | read_lock_bh(&bond->lock); | 3817 | read_lock_bh(&bond->lock); |
3788 | 3818 | ||
3789 | bond_for_each_slave(bond, slave, i) { | 3819 | bond_for_each_slave(bond, slave, i) { |
3790 | const struct net_device_stats *sstats = dev_get_stats(slave->dev); | 3820 | const struct rtnl_link_stats64 *sstats = |
3821 | dev_get_stats(slave->dev); | ||
3791 | 3822 | ||
3792 | local_stats.rx_packets += sstats->rx_packets; | 3823 | local_stats.rx_packets += sstats->rx_packets; |
3793 | local_stats.rx_bytes += sstats->rx_bytes; | 3824 | local_stats.rx_bytes += sstats->rx_bytes; |
@@ -4401,9 +4432,59 @@ static void bond_set_xmit_hash_policy(struct bonding *bond) | |||
4401 | } | 4432 | } |
4402 | } | 4433 | } |
4403 | 4434 | ||
4435 | /* | ||
4436 | * Lookup the slave that corresponds to a qid | ||
4437 | */ | ||
4438 | static inline int bond_slave_override(struct bonding *bond, | ||
4439 | struct sk_buff *skb) | ||
4440 | { | ||
4441 | int i, res = 1; | ||
4442 | struct slave *slave = NULL; | ||
4443 | struct slave *check_slave; | ||
4444 | |||
4445 | read_lock(&bond->lock); | ||
4446 | |||
4447 | if (!BOND_IS_OK(bond) || !skb->queue_mapping) | ||
4448 | goto out; | ||
4449 | |||
4450 | /* Find out if any slaves have the same mapping as this skb. */ | ||
4451 | bond_for_each_slave(bond, check_slave, i) { | ||
4452 | if (check_slave->queue_id == skb->queue_mapping) { | ||
4453 | slave = check_slave; | ||
4454 | break; | ||
4455 | } | ||
4456 | } | ||
4457 | |||
4458 | /* If the slave isn't UP, use default transmit policy. */ | ||
4459 | if (slave && slave->queue_id && IS_UP(slave->dev) && | ||
4460 | (slave->link == BOND_LINK_UP)) { | ||
4461 | res = bond_dev_queue_xmit(bond, skb, slave->dev); | ||
4462 | } | ||
4463 | |||
4464 | out: | ||
4465 | read_unlock(&bond->lock); | ||
4466 | return res; | ||
4467 | } | ||
4468 | |||
4469 | static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb) | ||
4470 | { | ||
4471 | /* | ||
4472 | * This helper function exists to help dev_pick_tx get the correct | ||
4473 | * destination queue. Using a helper function skips the a call to | ||
4474 | * skb_tx_hash and will put the skbs in the queue we expect on their | ||
4475 | * way down to the bonding driver. | ||
4476 | */ | ||
4477 | return skb->queue_mapping; | ||
4478 | } | ||
4479 | |||
4404 | static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev) | 4480 | static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev) |
4405 | { | 4481 | { |
4406 | const struct bonding *bond = netdev_priv(dev); | 4482 | struct bonding *bond = netdev_priv(dev); |
4483 | |||
4484 | if (TX_QUEUE_OVERRIDE(bond->params.mode)) { | ||
4485 | if (!bond_slave_override(bond, skb)) | ||
4486 | return NETDEV_TX_OK; | ||
4487 | } | ||
4407 | 4488 | ||
4408 | switch (bond->params.mode) { | 4489 | switch (bond->params.mode) { |
4409 | case BOND_MODE_ROUNDROBIN: | 4490 | case BOND_MODE_ROUNDROBIN: |
@@ -4488,7 +4569,8 @@ static const struct net_device_ops bond_netdev_ops = { | |||
4488 | .ndo_open = bond_open, | 4569 | .ndo_open = bond_open, |
4489 | .ndo_stop = bond_close, | 4570 | .ndo_stop = bond_close, |
4490 | .ndo_start_xmit = bond_start_xmit, | 4571 | .ndo_start_xmit = bond_start_xmit, |
4491 | .ndo_get_stats = bond_get_stats, | 4572 | .ndo_select_queue = bond_select_queue, |
4573 | .ndo_get_stats64 = bond_get_stats, | ||
4492 | .ndo_do_ioctl = bond_do_ioctl, | 4574 | .ndo_do_ioctl = bond_do_ioctl, |
4493 | .ndo_set_multicast_list = bond_set_multicast_list, | 4575 | .ndo_set_multicast_list = bond_set_multicast_list, |
4494 | .ndo_change_mtu = bond_change_mtu, | 4576 | .ndo_change_mtu = bond_change_mtu, |
@@ -4756,6 +4838,20 @@ static int bond_check_params(struct bond_params *params) | |||
4756 | } | 4838 | } |
4757 | } | 4839 | } |
4758 | 4840 | ||
4841 | if (tx_queues < 1 || tx_queues > 255) { | ||
4842 | pr_warning("Warning: tx_queues (%d) should be between " | ||
4843 | "1 and 255, resetting to %d\n", | ||
4844 | tx_queues, BOND_DEFAULT_TX_QUEUES); | ||
4845 | tx_queues = BOND_DEFAULT_TX_QUEUES; | ||
4846 | } | ||
4847 | |||
4848 | if ((all_slaves_active != 0) && (all_slaves_active != 1)) { | ||
4849 | pr_warning("Warning: all_slaves_active module parameter (%d), " | ||
4850 | "not of valid value (0/1), so it was set to " | ||
4851 | "0\n", all_slaves_active); | ||
4852 | all_slaves_active = 0; | ||
4853 | } | ||
4854 | |||
4759 | /* reset values for TLB/ALB */ | 4855 | /* reset values for TLB/ALB */ |
4760 | if ((bond_mode == BOND_MODE_TLB) || | 4856 | if ((bond_mode == BOND_MODE_TLB) || |
4761 | (bond_mode == BOND_MODE_ALB)) { | 4857 | (bond_mode == BOND_MODE_ALB)) { |
@@ -4926,6 +5022,8 @@ static int bond_check_params(struct bond_params *params) | |||
4926 | params->primary[0] = 0; | 5022 | params->primary[0] = 0; |
4927 | params->primary_reselect = primary_reselect_value; | 5023 | params->primary_reselect = primary_reselect_value; |
4928 | params->fail_over_mac = fail_over_mac_value; | 5024 | params->fail_over_mac = fail_over_mac_value; |
5025 | params->tx_queues = tx_queues; | ||
5026 | params->all_slaves_active = all_slaves_active; | ||
4929 | 5027 | ||
4930 | if (primary) { | 5028 | if (primary) { |
4931 | strncpy(params->primary, primary, IFNAMSIZ); | 5029 | strncpy(params->primary, primary, IFNAMSIZ); |
@@ -5012,8 +5110,8 @@ int bond_create(struct net *net, const char *name) | |||
5012 | 5110 | ||
5013 | rtnl_lock(); | 5111 | rtnl_lock(); |
5014 | 5112 | ||
5015 | bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "", | 5113 | bond_dev = alloc_netdev_mq(sizeof(struct bonding), name ? name : "", |
5016 | bond_setup); | 5114 | bond_setup, tx_queues); |
5017 | if (!bond_dev) { | 5115 | if (!bond_dev) { |
5018 | pr_err("%s: eek! can't alloc netdev!\n", name); | 5116 | pr_err("%s: eek! can't alloc netdev!\n", name); |
5019 | rtnl_unlock(); | 5117 | rtnl_unlock(); |