aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding/bond_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r--drivers/net/bonding/bond_main.c55
1 files changed, 50 insertions, 5 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index a141f406cb98..4dd5ee2a34cc 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -79,6 +79,7 @@
79#include <net/pkt_sched.h> 79#include <net/pkt_sched.h>
80#include <linux/rculist.h> 80#include <linux/rculist.h>
81#include <net/flow_keys.h> 81#include <net/flow_keys.h>
82#include <linux/reciprocal_div.h>
82#include "bonding.h" 83#include "bonding.h"
83#include "bond_3ad.h" 84#include "bond_3ad.h"
84#include "bond_alb.h" 85#include "bond_alb.h"
@@ -111,6 +112,7 @@ static char *fail_over_mac;
111static int all_slaves_active; 112static int all_slaves_active;
112static struct bond_params bonding_defaults; 113static struct bond_params bonding_defaults;
113static int resend_igmp = BOND_DEFAULT_RESEND_IGMP; 114static int resend_igmp = BOND_DEFAULT_RESEND_IGMP;
115static int packets_per_slave = 1;
114 116
115module_param(max_bonds, int, 0); 117module_param(max_bonds, int, 0);
116MODULE_PARM_DESC(max_bonds, "Max number of bonded devices"); 118MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
@@ -183,6 +185,10 @@ MODULE_PARM_DESC(all_slaves_active, "Keep all frames received on an interface"
183module_param(resend_igmp, int, 0); 185module_param(resend_igmp, int, 0);
184MODULE_PARM_DESC(resend_igmp, "Number of IGMP membership reports to send on " 186MODULE_PARM_DESC(resend_igmp, "Number of IGMP membership reports to send on "
185 "link failure"); 187 "link failure");
188module_param(packets_per_slave, int, 0);
189MODULE_PARM_DESC(packets_per_slave, "Packets to send per slave in balance-rr "
190 "mode; 0 for a random slave, 1 packet per "
191 "slave (default), >1 packets per slave.");
186 192
187/*----------------------------- Global variables ----------------------------*/ 193/*----------------------------- Global variables ----------------------------*/
188 194
@@ -3574,14 +3580,44 @@ void bond_xmit_slave_id(struct bonding *bond, struct sk_buff *skb, int slave_id)
3574 kfree_skb(skb); 3580 kfree_skb(skb);
3575} 3581}
3576 3582
3583/**
3584 * bond_rr_gen_slave_id - generate slave id based on packets_per_slave
3585 * @bond: bonding device to use
3586 *
3587 * Based on the value of the bonding device's packets_per_slave parameter
3588 * this function generates a slave id, which is usually used as the next
3589 * slave to transmit through.
3590 */
3591static u32 bond_rr_gen_slave_id(struct bonding *bond)
3592{
3593 int packets_per_slave = bond->params.packets_per_slave;
3594 u32 slave_id;
3595
3596 switch (packets_per_slave) {
3597 case 0:
3598 slave_id = prandom_u32();
3599 break;
3600 case 1:
3601 slave_id = bond->rr_tx_counter;
3602 break;
3603 default:
3604 slave_id = reciprocal_divide(bond->rr_tx_counter,
3605 packets_per_slave);
3606 break;
3607 }
3608 bond->rr_tx_counter++;
3609
3610 return slave_id;
3611}
3612
3577static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev) 3613static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev)
3578{ 3614{
3579 struct bonding *bond = netdev_priv(bond_dev); 3615 struct bonding *bond = netdev_priv(bond_dev);
3580 struct iphdr *iph = ip_hdr(skb); 3616 struct iphdr *iph = ip_hdr(skb);
3581 struct slave *slave; 3617 struct slave *slave;
3618 u32 slave_id;
3582 3619
3583 /* 3620 /* Start with the curr_active_slave that joined the bond as the
3584 * Start with the curr_active_slave that joined the bond as the
3585 * default for sending IGMP traffic. For failover purposes one 3621 * default for sending IGMP traffic. For failover purposes one
3586 * needs to maintain some consistency for the interface that will 3622 * needs to maintain some consistency for the interface that will
3587 * send the join/membership reports. The curr_active_slave found 3623 * send the join/membership reports. The curr_active_slave found
@@ -3594,8 +3630,8 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev
3594 else 3630 else
3595 bond_xmit_slave_id(bond, skb, 0); 3631 bond_xmit_slave_id(bond, skb, 0);
3596 } else { 3632 } else {
3597 bond_xmit_slave_id(bond, skb, 3633 slave_id = bond_rr_gen_slave_id(bond);
3598 bond->rr_tx_counter++ % bond->slave_cnt); 3634 bond_xmit_slave_id(bond, skb, slave_id % bond->slave_cnt);
3599 } 3635 }
3600 3636
3601 return NETDEV_TX_OK; 3637 return NETDEV_TX_OK;
@@ -4099,6 +4135,12 @@ static int bond_check_params(struct bond_params *params)
4099 resend_igmp = BOND_DEFAULT_RESEND_IGMP; 4135 resend_igmp = BOND_DEFAULT_RESEND_IGMP;
4100 } 4136 }
4101 4137
4138 if (packets_per_slave < 0 || packets_per_slave > USHRT_MAX) {
4139 pr_warn("Warning: packets_per_slave (%d) should be between 0 and %u resetting to 1\n",
4140 packets_per_slave, USHRT_MAX);
4141 packets_per_slave = 1;
4142 }
4143
4102 /* reset values for TLB/ALB */ 4144 /* reset values for TLB/ALB */
4103 if ((bond_mode == BOND_MODE_TLB) || 4145 if ((bond_mode == BOND_MODE_TLB) ||
4104 (bond_mode == BOND_MODE_ALB)) { 4146 (bond_mode == BOND_MODE_ALB)) {
@@ -4288,7 +4330,10 @@ static int bond_check_params(struct bond_params *params)
4288 params->resend_igmp = resend_igmp; 4330 params->resend_igmp = resend_igmp;
4289 params->min_links = min_links; 4331 params->min_links = min_links;
4290 params->lp_interval = BOND_ALB_DEFAULT_LP_INTERVAL; 4332 params->lp_interval = BOND_ALB_DEFAULT_LP_INTERVAL;
4291 4333 if (packets_per_slave > 1)
4334 params->packets_per_slave = reciprocal_value(packets_per_slave);
4335 else
4336 params->packets_per_slave = packets_per_slave;
4292 if (primary) { 4337 if (primary) {
4293 strncpy(params->primary, primary, IFNAMSIZ); 4338 strncpy(params->primary, primary, IFNAMSIZ);
4294 params->primary[IFNAMSIZ - 1] = 0; 4339 params->primary[IFNAMSIZ - 1] = 0;