diff options
-rw-r--r-- | Documentation/networking/bonding.txt | 84 | ||||
-rw-r--r-- | drivers/net/bonding/bond_main.c | 75 | ||||
-rw-r--r-- | drivers/net/bonding/bond_sysfs.c | 116 | ||||
-rw-r--r-- | drivers/net/bonding/bonding.h | 9 | ||||
-rw-r--r-- | include/linux/if_bonding.h | 1 |
5 files changed, 278 insertions, 7 deletions
diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt index 61f516b135b4..d0914781830e 100644 --- a/Documentation/networking/bonding.txt +++ b/Documentation/networking/bonding.txt | |||
@@ -49,6 +49,7 @@ Table of Contents | |||
49 | 3.3 Configuring Bonding Manually with Ifenslave | 49 | 3.3 Configuring Bonding Manually with Ifenslave |
50 | 3.3.1 Configuring Multiple Bonds Manually | 50 | 3.3.1 Configuring Multiple Bonds Manually |
51 | 3.4 Configuring Bonding Manually via Sysfs | 51 | 3.4 Configuring Bonding Manually via Sysfs |
52 | 3.5 Overriding Configuration for Special Cases | ||
52 | 53 | ||
53 | 4. Querying Bonding Configuration | 54 | 4. Querying Bonding Configuration |
54 | 4.1 Bonding Configuration | 55 | 4.1 Bonding Configuration |
@@ -1318,8 +1319,87 @@ echo 2000 > /sys/class/net/bond1/bonding/arp_interval | |||
1318 | echo +eth2 > /sys/class/net/bond1/bonding/slaves | 1319 | echo +eth2 > /sys/class/net/bond1/bonding/slaves |
1319 | echo +eth3 > /sys/class/net/bond1/bonding/slaves | 1320 | echo +eth3 > /sys/class/net/bond1/bonding/slaves |
1320 | 1321 | ||
1321 | 1322 | 3.5 Overriding Configuration for Special Cases | |
1322 | 4. Querying Bonding Configuration | 1323 | ---------------------------------------------- |
1324 | When using the bonding driver, the physical port which transmits a frame is | ||
1325 | typically selected by the bonding driver, and is not relevant to the user or | ||
1326 | system administrator. The output port is simply selected using the policies of | ||
1327 | the selected bonding mode. On occasion however, it is helpful to direct certain | ||
1328 | classes of traffic to certain physical interfaces on output to implement | ||
1329 | slightly more complex policies. For example, to reach a web server over a | ||
1330 | bonded interface in which eth0 connects to a private network, while eth1 | ||
1331 | connects via a public network, it may be desirous to bias the bond to send said | ||
1332 | traffic over eth0 first, using eth1 only as a fall back, while all other traffic | ||
1333 | can safely be sent over either interface. Such configurations may be achieved | ||
1334 | using the traffic control utilities inherent in linux. | ||
1335 | |||
1336 | By default the bonding driver is multiqueue aware and 16 queues are created | ||
1337 | when the driver initializes (see Documentation/networking/multiqueue.txt | ||
1338 | for details). If more or less queues are desired the module parameter | ||
1339 | tx_queues can be used to change this value. There is no sysfs parameter | ||
1340 | available as the allocation is done at module init time. | ||
1341 | |||
1342 | The output of the file /proc/net/bonding/bondX has changed so the output Queue | ||
1343 | ID is now printed for each slave: | ||
1344 | |||
1345 | Bonding Mode: fault-tolerance (active-backup) | ||
1346 | Primary Slave: None | ||
1347 | Currently Active Slave: eth0 | ||
1348 | MII Status: up | ||
1349 | MII Polling Interval (ms): 0 | ||
1350 | Up Delay (ms): 0 | ||
1351 | Down Delay (ms): 0 | ||
1352 | |||
1353 | Slave Interface: eth0 | ||
1354 | MII Status: up | ||
1355 | Link Failure Count: 0 | ||
1356 | Permanent HW addr: 00:1a:a0:12:8f:cb | ||
1357 | Slave queue ID: 0 | ||
1358 | |||
1359 | Slave Interface: eth1 | ||
1360 | MII Status: up | ||
1361 | Link Failure Count: 0 | ||
1362 | Permanent HW addr: 00:1a:a0:12:8f:cc | ||
1363 | Slave queue ID: 2 | ||
1364 | |||
1365 | The queue_id for a slave can be set using the command: | ||
1366 | |||
1367 | # echo "eth1:2" > /sys/class/net/bond0/bonding/queue_id | ||
1368 | |||
1369 | Any interface that needs a queue_id set should set it with multiple calls | ||
1370 | like the one above until proper priorities are set for all interfaces. On | ||
1371 | distributions that allow configuration via initscripts, multiple 'queue_id' | ||
1372 | arguments can be added to BONDING_OPTS to set all needed slave queues. | ||
1373 | |||
1374 | These queue id's can be used in conjunction with the tc utility to configure | ||
1375 | a multiqueue qdisc and filters to bias certain traffic to transmit on certain | ||
1376 | slave devices. For instance, say we wanted, in the above configuration to | ||
1377 | force all traffic bound to 192.168.1.100 to use eth1 in the bond as its output | ||
1378 | device. The following commands would accomplish this: | ||
1379 | |||
1380 | # tc qdisc add dev bond0 handle 1 root multiq | ||
1381 | |||
1382 | # tc filter add dev bond0 protocol ip parent 1: prio 1 u32 match ip dst \ | ||
1383 | 192.168.1.100 action skbedit queue_mapping 2 | ||
1384 | |||
1385 | These commands tell the kernel to attach a multiqueue queue discipline to the | ||
1386 | bond0 interface and filter traffic enqueued to it, such that packets with a dst | ||
1387 | ip of 192.168.1.100 have their output queue mapping value overwritten to 2. | ||
1388 | This value is then passed into the driver, causing the normal output path | ||
1389 | selection policy to be overridden, selecting instead qid 2, which maps to eth1. | ||
1390 | |||
1391 | Note that qid values begin at 1. Qid 0 is reserved to initiate to the driver | ||
1392 | that normal output policy selection should take place. One benefit to simply | ||
1393 | leaving the qid for a slave to 0 is the multiqueue awareness in the bonding | ||
1394 | driver that is now present. This awareness allows tc filters to be placed on | ||
1395 | slave devices as well as bond devices and the bonding driver will simply act as | ||
1396 | a pass-through for selecting output queues on the slave device rather than | ||
1397 | output port selection. | ||
1398 | |||
1399 | This feature first appeared in bonding driver version 3.7.0 and support for | ||
1400 | output slave selection was limited to round-robin and active-backup modes. | ||
1401 | |||
1402 | 4 Querying Bonding Configuration | ||
1323 | ================================= | 1403 | ================================= |
1324 | 1404 | ||
1325 | 4.1 Bonding Configuration | 1405 | 4.1 Bonding Configuration |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index f22f6bf43858..1b19276cff12 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; |
@@ -111,6 +112,8 @@ static struct bond_params bonding_defaults; | |||
111 | 112 | ||
112 | module_param(max_bonds, int, 0); | 113 | module_param(max_bonds, int, 0); |
113 | 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)"); | ||
114 | module_param(num_grat_arp, int, 0644); | 117 | module_param(num_grat_arp, int, 0644); |
115 | 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"); |
116 | module_param(num_unsol_na, int, 0644); | 119 | module_param(num_unsol_na, int, 0644); |
@@ -1540,6 +1543,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1540 | goto err_undo_flags; | 1543 | goto err_undo_flags; |
1541 | } | 1544 | } |
1542 | 1545 | ||
1546 | /* | ||
1547 | * Set the new_slave's queue_id to be zero. Queue ID mapping | ||
1548 | * is set via sysfs or module option if desired. | ||
1549 | */ | ||
1550 | new_slave->queue_id = 0; | ||
1551 | |||
1543 | /* Save slave's original mtu and then set it to match the bond */ | 1552 | /* Save slave's original mtu and then set it to match the bond */ |
1544 | new_slave->original_mtu = slave_dev->mtu; | 1553 | new_slave->original_mtu = slave_dev->mtu; |
1545 | res = dev_set_mtu(slave_dev, bond->dev->mtu); | 1554 | res = dev_set_mtu(slave_dev, bond->dev->mtu); |
@@ -3285,6 +3294,7 @@ static void bond_info_show_slave(struct seq_file *seq, | |||
3285 | else | 3294 | else |
3286 | seq_puts(seq, "Aggregator ID: N/A\n"); | 3295 | seq_puts(seq, "Aggregator ID: N/A\n"); |
3287 | } | 3296 | } |
3297 | seq_printf(seq, "Slave queue ID: %d\n", slave->queue_id); | ||
3288 | } | 3298 | } |
3289 | 3299 | ||
3290 | 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) |
@@ -4421,9 +4431,59 @@ static void bond_set_xmit_hash_policy(struct bonding *bond) | |||
4421 | } | 4431 | } |
4422 | } | 4432 | } |
4423 | 4433 | ||
4434 | /* | ||
4435 | * Lookup the slave that corresponds to a qid | ||
4436 | */ | ||
4437 | static inline int bond_slave_override(struct bonding *bond, | ||
4438 | struct sk_buff *skb) | ||
4439 | { | ||
4440 | int i, res = 1; | ||
4441 | struct slave *slave = NULL; | ||
4442 | struct slave *check_slave; | ||
4443 | |||
4444 | read_lock(&bond->lock); | ||
4445 | |||
4446 | if (!BOND_IS_OK(bond) || !skb->queue_mapping) | ||
4447 | goto out; | ||
4448 | |||
4449 | /* Find out if any slaves have the same mapping as this skb. */ | ||
4450 | bond_for_each_slave(bond, check_slave, i) { | ||
4451 | if (check_slave->queue_id == skb->queue_mapping) { | ||
4452 | slave = check_slave; | ||
4453 | break; | ||
4454 | } | ||
4455 | } | ||
4456 | |||
4457 | /* If the slave isn't UP, use default transmit policy. */ | ||
4458 | if (slave && slave->queue_id && IS_UP(slave->dev) && | ||
4459 | (slave->link == BOND_LINK_UP)) { | ||
4460 | res = bond_dev_queue_xmit(bond, skb, slave->dev); | ||
4461 | } | ||
4462 | |||
4463 | out: | ||
4464 | read_unlock(&bond->lock); | ||
4465 | return res; | ||
4466 | } | ||
4467 | |||
4468 | static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb) | ||
4469 | { | ||
4470 | /* | ||
4471 | * This helper function exists to help dev_pick_tx get the correct | ||
4472 | * destination queue. Using a helper function skips the a call to | ||
4473 | * skb_tx_hash and will put the skbs in the queue we expect on their | ||
4474 | * way down to the bonding driver. | ||
4475 | */ | ||
4476 | return skb->queue_mapping; | ||
4477 | } | ||
4478 | |||
4424 | static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev) | 4479 | static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev) |
4425 | { | 4480 | { |
4426 | const struct bonding *bond = netdev_priv(dev); | 4481 | struct bonding *bond = netdev_priv(dev); |
4482 | |||
4483 | if (TX_QUEUE_OVERRIDE(bond->params.mode)) { | ||
4484 | if (!bond_slave_override(bond, skb)) | ||
4485 | return NETDEV_TX_OK; | ||
4486 | } | ||
4427 | 4487 | ||
4428 | switch (bond->params.mode) { | 4488 | switch (bond->params.mode) { |
4429 | case BOND_MODE_ROUNDROBIN: | 4489 | case BOND_MODE_ROUNDROBIN: |
@@ -4508,6 +4568,7 @@ static const struct net_device_ops bond_netdev_ops = { | |||
4508 | .ndo_open = bond_open, | 4568 | .ndo_open = bond_open, |
4509 | .ndo_stop = bond_close, | 4569 | .ndo_stop = bond_close, |
4510 | .ndo_start_xmit = bond_start_xmit, | 4570 | .ndo_start_xmit = bond_start_xmit, |
4571 | .ndo_select_queue = bond_select_queue, | ||
4511 | .ndo_get_stats = bond_get_stats, | 4572 | .ndo_get_stats = bond_get_stats, |
4512 | .ndo_do_ioctl = bond_do_ioctl, | 4573 | .ndo_do_ioctl = bond_do_ioctl, |
4513 | .ndo_set_multicast_list = bond_set_multicast_list, | 4574 | .ndo_set_multicast_list = bond_set_multicast_list, |
@@ -4776,6 +4837,13 @@ static int bond_check_params(struct bond_params *params) | |||
4776 | } | 4837 | } |
4777 | } | 4838 | } |
4778 | 4839 | ||
4840 | if (tx_queues < 1 || tx_queues > 255) { | ||
4841 | pr_warning("Warning: tx_queues (%d) should be between " | ||
4842 | "1 and 255, resetting to %d\n", | ||
4843 | tx_queues, BOND_DEFAULT_TX_QUEUES); | ||
4844 | tx_queues = BOND_DEFAULT_TX_QUEUES; | ||
4845 | } | ||
4846 | |||
4779 | if ((all_slaves_active != 0) && (all_slaves_active != 1)) { | 4847 | if ((all_slaves_active != 0) && (all_slaves_active != 1)) { |
4780 | pr_warning("Warning: all_slaves_active module parameter (%d), " | 4848 | pr_warning("Warning: all_slaves_active module parameter (%d), " |
4781 | "not of valid value (0/1), so it was set to " | 4849 | "not of valid value (0/1), so it was set to " |
@@ -4953,6 +5021,7 @@ static int bond_check_params(struct bond_params *params) | |||
4953 | params->primary[0] = 0; | 5021 | params->primary[0] = 0; |
4954 | params->primary_reselect = primary_reselect_value; | 5022 | params->primary_reselect = primary_reselect_value; |
4955 | params->fail_over_mac = fail_over_mac_value; | 5023 | params->fail_over_mac = fail_over_mac_value; |
5024 | params->tx_queues = tx_queues; | ||
4956 | params->all_slaves_active = all_slaves_active; | 5025 | params->all_slaves_active = all_slaves_active; |
4957 | 5026 | ||
4958 | if (primary) { | 5027 | if (primary) { |
@@ -5040,8 +5109,8 @@ int bond_create(struct net *net, const char *name) | |||
5040 | 5109 | ||
5041 | rtnl_lock(); | 5110 | rtnl_lock(); |
5042 | 5111 | ||
5043 | bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "", | 5112 | bond_dev = alloc_netdev_mq(sizeof(struct bonding), name ? name : "", |
5044 | bond_setup); | 5113 | bond_setup, tx_queues); |
5045 | if (!bond_dev) { | 5114 | if (!bond_dev) { |
5046 | pr_err("%s: eek! can't alloc netdev!\n", name); | 5115 | pr_err("%s: eek! can't alloc netdev!\n", name); |
5047 | rtnl_unlock(); | 5116 | rtnl_unlock(); |
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 066311a5e084..f9a034361a8e 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
@@ -1412,6 +1412,121 @@ static ssize_t bonding_show_ad_partner_mac(struct device *d, | |||
1412 | static DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL); | 1412 | static DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL); |
1413 | 1413 | ||
1414 | /* | 1414 | /* |
1415 | * Show the queue_ids of the slaves in the current bond. | ||
1416 | */ | ||
1417 | static ssize_t bonding_show_queue_id(struct device *d, | ||
1418 | struct device_attribute *attr, | ||
1419 | char *buf) | ||
1420 | { | ||
1421 | struct slave *slave; | ||
1422 | int i, res = 0; | ||
1423 | struct bonding *bond = to_bond(d); | ||
1424 | |||
1425 | if (!rtnl_trylock()) | ||
1426 | return restart_syscall(); | ||
1427 | |||
1428 | read_lock(&bond->lock); | ||
1429 | bond_for_each_slave(bond, slave, i) { | ||
1430 | if (res > (PAGE_SIZE - 6)) { | ||
1431 | /* not enough space for another interface name */ | ||
1432 | if ((PAGE_SIZE - res) > 10) | ||
1433 | res = PAGE_SIZE - 10; | ||
1434 | res += sprintf(buf + res, "++more++ "); | ||
1435 | break; | ||
1436 | } | ||
1437 | res += sprintf(buf + res, "%s:%d ", | ||
1438 | slave->dev->name, slave->queue_id); | ||
1439 | } | ||
1440 | read_unlock(&bond->lock); | ||
1441 | if (res) | ||
1442 | buf[res-1] = '\n'; /* eat the leftover space */ | ||
1443 | rtnl_unlock(); | ||
1444 | return res; | ||
1445 | } | ||
1446 | |||
1447 | /* | ||
1448 | * Set the queue_ids of the slaves in the current bond. The bond | ||
1449 | * interface must be enslaved for this to work. | ||
1450 | */ | ||
1451 | static ssize_t bonding_store_queue_id(struct device *d, | ||
1452 | struct device_attribute *attr, | ||
1453 | const char *buffer, size_t count) | ||
1454 | { | ||
1455 | struct slave *slave, *update_slave; | ||
1456 | struct bonding *bond = to_bond(d); | ||
1457 | u16 qid; | ||
1458 | int i, ret = count; | ||
1459 | char *delim; | ||
1460 | struct net_device *sdev = NULL; | ||
1461 | |||
1462 | if (!rtnl_trylock()) | ||
1463 | return restart_syscall(); | ||
1464 | |||
1465 | /* delim will point to queue id if successful */ | ||
1466 | delim = strchr(buffer, ':'); | ||
1467 | if (!delim) | ||
1468 | goto err_no_cmd; | ||
1469 | |||
1470 | /* | ||
1471 | * Terminate string that points to device name and bump it | ||
1472 | * up one, so we can read the queue id there. | ||
1473 | */ | ||
1474 | *delim = '\0'; | ||
1475 | if (sscanf(++delim, "%hd\n", &qid) != 1) | ||
1476 | goto err_no_cmd; | ||
1477 | |||
1478 | /* Check buffer length, valid ifname and queue id */ | ||
1479 | if (strlen(buffer) > IFNAMSIZ || | ||
1480 | !dev_valid_name(buffer) || | ||
1481 | qid > bond->params.tx_queues) | ||
1482 | goto err_no_cmd; | ||
1483 | |||
1484 | /* Get the pointer to that interface if it exists */ | ||
1485 | sdev = __dev_get_by_name(dev_net(bond->dev), buffer); | ||
1486 | if (!sdev) | ||
1487 | goto err_no_cmd; | ||
1488 | |||
1489 | read_lock(&bond->lock); | ||
1490 | |||
1491 | /* Search for thes slave and check for duplicate qids */ | ||
1492 | update_slave = NULL; | ||
1493 | bond_for_each_slave(bond, slave, i) { | ||
1494 | if (sdev == slave->dev) | ||
1495 | /* | ||
1496 | * We don't need to check the matching | ||
1497 | * slave for dups, since we're overwriting it | ||
1498 | */ | ||
1499 | update_slave = slave; | ||
1500 | else if (qid && qid == slave->queue_id) { | ||
1501 | goto err_no_cmd_unlock; | ||
1502 | } | ||
1503 | } | ||
1504 | |||
1505 | if (!update_slave) | ||
1506 | goto err_no_cmd_unlock; | ||
1507 | |||
1508 | /* Actually set the qids for the slave */ | ||
1509 | update_slave->queue_id = qid; | ||
1510 | |||
1511 | read_unlock(&bond->lock); | ||
1512 | out: | ||
1513 | rtnl_unlock(); | ||
1514 | return ret; | ||
1515 | |||
1516 | err_no_cmd_unlock: | ||
1517 | read_unlock(&bond->lock); | ||
1518 | err_no_cmd: | ||
1519 | pr_info("invalid input for queue_id set for %s.\n", | ||
1520 | bond->dev->name); | ||
1521 | ret = -EPERM; | ||
1522 | goto out; | ||
1523 | } | ||
1524 | |||
1525 | static DEVICE_ATTR(queue_id, S_IRUGO | S_IWUSR, bonding_show_queue_id, | ||
1526 | bonding_store_queue_id); | ||
1527 | |||
1528 | |||
1529 | /* | ||
1415 | * Show and set the all_slaves_active flag. | 1530 | * Show and set the all_slaves_active flag. |
1416 | */ | 1531 | */ |
1417 | static ssize_t bonding_show_slaves_active(struct device *d, | 1532 | static ssize_t bonding_show_slaves_active(struct device *d, |
@@ -1489,6 +1604,7 @@ static struct attribute *per_bond_attrs[] = { | |||
1489 | &dev_attr_ad_actor_key.attr, | 1604 | &dev_attr_ad_actor_key.attr, |
1490 | &dev_attr_ad_partner_key.attr, | 1605 | &dev_attr_ad_partner_key.attr, |
1491 | &dev_attr_ad_partner_mac.attr, | 1606 | &dev_attr_ad_partner_mac.attr, |
1607 | &dev_attr_queue_id.attr, | ||
1492 | &dev_attr_all_slaves_active.attr, | 1608 | &dev_attr_all_slaves_active.attr, |
1493 | NULL, | 1609 | NULL, |
1494 | }; | 1610 | }; |
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index cecdea2a629f..c6fdd851579a 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
@@ -23,8 +23,8 @@ | |||
23 | #include "bond_3ad.h" | 23 | #include "bond_3ad.h" |
24 | #include "bond_alb.h" | 24 | #include "bond_alb.h" |
25 | 25 | ||
26 | #define DRV_VERSION "3.6.0" | 26 | #define DRV_VERSION "3.7.0" |
27 | #define DRV_RELDATE "September 26, 2009" | 27 | #define DRV_RELDATE "June 2, 2010" |
28 | #define DRV_NAME "bonding" | 28 | #define DRV_NAME "bonding" |
29 | #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" | 29 | #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" |
30 | 30 | ||
@@ -60,6 +60,9 @@ | |||
60 | ((mode) == BOND_MODE_TLB) || \ | 60 | ((mode) == BOND_MODE_TLB) || \ |
61 | ((mode) == BOND_MODE_ALB)) | 61 | ((mode) == BOND_MODE_ALB)) |
62 | 62 | ||
63 | #define TX_QUEUE_OVERRIDE(mode) \ | ||
64 | (((mode) == BOND_MODE_ACTIVEBACKUP) || \ | ||
65 | ((mode) == BOND_MODE_ROUNDROBIN)) | ||
63 | /* | 66 | /* |
64 | * Less bad way to call ioctl from within the kernel; this needs to be | 67 | * Less bad way to call ioctl from within the kernel; this needs to be |
65 | * done some other way to get the call out of interrupt context. | 68 | * done some other way to get the call out of interrupt context. |
@@ -131,6 +134,7 @@ struct bond_params { | |||
131 | char primary[IFNAMSIZ]; | 134 | char primary[IFNAMSIZ]; |
132 | int primary_reselect; | 135 | int primary_reselect; |
133 | __be32 arp_targets[BOND_MAX_ARP_TARGETS]; | 136 | __be32 arp_targets[BOND_MAX_ARP_TARGETS]; |
137 | int tx_queues; | ||
134 | int all_slaves_active; | 138 | int all_slaves_active; |
135 | }; | 139 | }; |
136 | 140 | ||
@@ -165,6 +169,7 @@ struct slave { | |||
165 | u8 perm_hwaddr[ETH_ALEN]; | 169 | u8 perm_hwaddr[ETH_ALEN]; |
166 | u16 speed; | 170 | u16 speed; |
167 | u8 duplex; | 171 | u8 duplex; |
172 | u16 queue_id; | ||
168 | struct ad_slave_info ad_info; /* HUGE - better to dynamically alloc */ | 173 | struct ad_slave_info ad_info; /* HUGE - better to dynamically alloc */ |
169 | struct tlb_slave_info tlb_info; | 174 | struct tlb_slave_info tlb_info; |
170 | }; | 175 | }; |
diff --git a/include/linux/if_bonding.h b/include/linux/if_bonding.h index cd525fae3c98..2c7994372bde 100644 --- a/include/linux/if_bonding.h +++ b/include/linux/if_bonding.h | |||
@@ -83,6 +83,7 @@ | |||
83 | 83 | ||
84 | #define BOND_DEFAULT_MAX_BONDS 1 /* Default maximum number of devices to support */ | 84 | #define BOND_DEFAULT_MAX_BONDS 1 /* Default maximum number of devices to support */ |
85 | 85 | ||
86 | #define BOND_DEFAULT_TX_QUEUES 16 /* Default number of tx queues per device */ | ||
86 | /* hashing types */ | 87 | /* hashing types */ |
87 | #define BOND_XMIT_POLICY_LAYER2 0 /* layer 2 (MAC only), default */ | 88 | #define BOND_XMIT_POLICY_LAYER2 0 /* layer 2 (MAC only), default */ |
88 | #define BOND_XMIT_POLICY_LAYER34 1 /* layer 3+4 (IP ^ (TCP || UDP)) */ | 89 | #define BOND_XMIT_POLICY_LAYER34 1 /* layer 3+4 (IP ^ (TCP || UDP)) */ |