diff options
| author | Steven Whitehouse <swhiteho@redhat.com> | 2006-09-28 08:29:59 -0400 |
|---|---|---|
| committer | Steven Whitehouse <swhiteho@redhat.com> | 2006-09-28 08:29:59 -0400 |
| commit | 185a257f2f73bcd89050ad02da5bedbc28fc43fa (patch) | |
| tree | 5e32586114534ed3f2165614cba3d578f5d87307 /drivers/net/bonding | |
| parent | 3f1a9aaeffd8d1cbc5ab9776c45cbd66af1c9699 (diff) | |
| parent | a77c64c1a641950626181b4857abb701d8f38ccc (diff) | |
Merge branch 'master' into gfs2
Diffstat (limited to 'drivers/net/bonding')
| -rw-r--r-- | drivers/net/bonding/bond_3ad.c | 70 | ||||
| -rw-r--r-- | drivers/net/bonding/bond_main.c | 228 | ||||
| -rw-r--r-- | drivers/net/bonding/bond_sysfs.c | 56 | ||||
| -rw-r--r-- | drivers/net/bonding/bonding.h | 34 |
4 files changed, 318 insertions, 70 deletions
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 6a407070c2e8..3fb354d9c515 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c | |||
| @@ -85,6 +85,7 @@ | |||
| 85 | #define AD_LINK_SPEED_BITMASK_10MBPS 0x2 | 85 | #define AD_LINK_SPEED_BITMASK_10MBPS 0x2 |
| 86 | #define AD_LINK_SPEED_BITMASK_100MBPS 0x4 | 86 | #define AD_LINK_SPEED_BITMASK_100MBPS 0x4 |
| 87 | #define AD_LINK_SPEED_BITMASK_1000MBPS 0x8 | 87 | #define AD_LINK_SPEED_BITMASK_1000MBPS 0x8 |
| 88 | #define AD_LINK_SPEED_BITMASK_10000MBPS 0x10 | ||
| 88 | //endalloun | 89 | //endalloun |
| 89 | 90 | ||
| 90 | // compare MAC addresses | 91 | // compare MAC addresses |
| @@ -99,7 +100,7 @@ static u16 __get_link_speed(struct port *port); | |||
| 99 | static u8 __get_duplex(struct port *port); | 100 | static u8 __get_duplex(struct port *port); |
| 100 | static inline void __initialize_port_locks(struct port *port); | 101 | static inline void __initialize_port_locks(struct port *port); |
| 101 | //conversions | 102 | //conversions |
| 102 | static void __ntohs_lacpdu(struct lacpdu *lacpdu); | 103 | static void __htons_lacpdu(struct lacpdu *lacpdu); |
| 103 | static u16 __ad_timer_to_ticks(u16 timer_type, u16 Par); | 104 | static u16 __ad_timer_to_ticks(u16 timer_type, u16 Par); |
| 104 | 105 | ||
| 105 | 106 | ||
| @@ -330,7 +331,8 @@ static inline void __release_rx_machine_lock(struct port *port) | |||
| 330 | * 0, | 331 | * 0, |
| 331 | * %AD_LINK_SPEED_BITMASK_10MBPS, | 332 | * %AD_LINK_SPEED_BITMASK_10MBPS, |
| 332 | * %AD_LINK_SPEED_BITMASK_100MBPS, | 333 | * %AD_LINK_SPEED_BITMASK_100MBPS, |
| 333 | * %AD_LINK_SPEED_BITMASK_1000MBPS | 334 | * %AD_LINK_SPEED_BITMASK_1000MBPS, |
| 335 | * %AD_LINK_SPEED_BITMASK_10000MBPS | ||
| 334 | */ | 336 | */ |
| 335 | static u16 __get_link_speed(struct port *port) | 337 | static u16 __get_link_speed(struct port *port) |
| 336 | { | 338 | { |
| @@ -357,6 +359,10 @@ static u16 __get_link_speed(struct port *port) | |||
| 357 | speed = AD_LINK_SPEED_BITMASK_1000MBPS; | 359 | speed = AD_LINK_SPEED_BITMASK_1000MBPS; |
| 358 | break; | 360 | break; |
| 359 | 361 | ||
| 362 | case SPEED_10000: | ||
| 363 | speed = AD_LINK_SPEED_BITMASK_10000MBPS; | ||
| 364 | break; | ||
| 365 | |||
| 360 | default: | 366 | default: |
| 361 | speed = 0; // unknown speed value from ethtool. shouldn't happen | 367 | speed = 0; // unknown speed value from ethtool. shouldn't happen |
| 362 | break; | 368 | break; |
| @@ -414,23 +420,23 @@ static inline void __initialize_port_locks(struct port *port) | |||
| 414 | 420 | ||
| 415 | //conversions | 421 | //conversions |
| 416 | /** | 422 | /** |
| 417 | * __ntohs_lacpdu - convert the contents of a LACPDU to host byte order | 423 | * __htons_lacpdu - convert the contents of a LACPDU to network byte order |
| 418 | * @lacpdu: the speicifed lacpdu | 424 | * @lacpdu: the speicifed lacpdu |
| 419 | * | 425 | * |
| 420 | * For each multi-byte field in the lacpdu, convert its content | 426 | * For each multi-byte field in the lacpdu, convert its content |
| 421 | */ | 427 | */ |
| 422 | static void __ntohs_lacpdu(struct lacpdu *lacpdu) | 428 | static void __htons_lacpdu(struct lacpdu *lacpdu) |
| 423 | { | 429 | { |
| 424 | if (lacpdu) { | 430 | if (lacpdu) { |
| 425 | lacpdu->actor_system_priority = ntohs(lacpdu->actor_system_priority); | 431 | lacpdu->actor_system_priority = htons(lacpdu->actor_system_priority); |
| 426 | lacpdu->actor_key = ntohs(lacpdu->actor_key); | 432 | lacpdu->actor_key = htons(lacpdu->actor_key); |
| 427 | lacpdu->actor_port_priority = ntohs(lacpdu->actor_port_priority); | 433 | lacpdu->actor_port_priority = htons(lacpdu->actor_port_priority); |
| 428 | lacpdu->actor_port = ntohs(lacpdu->actor_port); | 434 | lacpdu->actor_port = htons(lacpdu->actor_port); |
| 429 | lacpdu->partner_system_priority = ntohs(lacpdu->partner_system_priority); | 435 | lacpdu->partner_system_priority = htons(lacpdu->partner_system_priority); |
| 430 | lacpdu->partner_key = ntohs(lacpdu->partner_key); | 436 | lacpdu->partner_key = htons(lacpdu->partner_key); |
| 431 | lacpdu->partner_port_priority = ntohs(lacpdu->partner_port_priority); | 437 | lacpdu->partner_port_priority = htons(lacpdu->partner_port_priority); |
| 432 | lacpdu->partner_port = ntohs(lacpdu->partner_port); | 438 | lacpdu->partner_port = htons(lacpdu->partner_port); |
| 433 | lacpdu->collector_max_delay = ntohs(lacpdu->collector_max_delay); | 439 | lacpdu->collector_max_delay = htons(lacpdu->collector_max_delay); |
| 434 | } | 440 | } |
| 435 | } | 441 | } |
| 436 | 442 | ||
| @@ -490,11 +496,11 @@ static void __record_pdu(struct lacpdu *lacpdu, struct port *port) | |||
| 490 | // validate lacpdu and port | 496 | // validate lacpdu and port |
| 491 | if (lacpdu && port) { | 497 | if (lacpdu && port) { |
| 492 | // record the new parameter values for the partner operational | 498 | // record the new parameter values for the partner operational |
| 493 | port->partner_oper_port_number = lacpdu->actor_port; | 499 | port->partner_oper_port_number = ntohs(lacpdu->actor_port); |
| 494 | port->partner_oper_port_priority = lacpdu->actor_port_priority; | 500 | port->partner_oper_port_priority = ntohs(lacpdu->actor_port_priority); |
| 495 | port->partner_oper_system = lacpdu->actor_system; | 501 | port->partner_oper_system = lacpdu->actor_system; |
| 496 | port->partner_oper_system_priority = lacpdu->actor_system_priority; | 502 | port->partner_oper_system_priority = ntohs(lacpdu->actor_system_priority); |
| 497 | port->partner_oper_key = lacpdu->actor_key; | 503 | port->partner_oper_key = ntohs(lacpdu->actor_key); |
| 498 | // zero partener's lase states | 504 | // zero partener's lase states |
| 499 | port->partner_oper_port_state = 0; | 505 | port->partner_oper_port_state = 0; |
| 500 | port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_LACP_ACTIVITY); | 506 | port->partner_oper_port_state |= (lacpdu->actor_state & AD_STATE_LACP_ACTIVITY); |
| @@ -561,11 +567,11 @@ static void __update_selected(struct lacpdu *lacpdu, struct port *port) | |||
| 561 | // validate lacpdu and port | 567 | // validate lacpdu and port |
| 562 | if (lacpdu && port) { | 568 | if (lacpdu && port) { |
| 563 | // check if any parameter is different | 569 | // check if any parameter is different |
| 564 | if ((lacpdu->actor_port != port->partner_oper_port_number) || | 570 | if ((ntohs(lacpdu->actor_port) != port->partner_oper_port_number) || |
| 565 | (lacpdu->actor_port_priority != port->partner_oper_port_priority) || | 571 | (ntohs(lacpdu->actor_port_priority) != port->partner_oper_port_priority) || |
| 566 | MAC_ADDRESS_COMPARE(&(lacpdu->actor_system), &(port->partner_oper_system)) || | 572 | MAC_ADDRESS_COMPARE(&(lacpdu->actor_system), &(port->partner_oper_system)) || |
| 567 | (lacpdu->actor_system_priority != port->partner_oper_system_priority) || | 573 | (ntohs(lacpdu->actor_system_priority) != port->partner_oper_system_priority) || |
| 568 | (lacpdu->actor_key != port->partner_oper_key) || | 574 | (ntohs(lacpdu->actor_key) != port->partner_oper_key) || |
| 569 | ((lacpdu->actor_state & AD_STATE_AGGREGATION) != (port->partner_oper_port_state & AD_STATE_AGGREGATION)) | 575 | ((lacpdu->actor_state & AD_STATE_AGGREGATION) != (port->partner_oper_port_state & AD_STATE_AGGREGATION)) |
| 570 | ) { | 576 | ) { |
| 571 | // update the state machine Selected variable | 577 | // update the state machine Selected variable |
| @@ -628,11 +634,11 @@ static void __choose_matched(struct lacpdu *lacpdu, struct port *port) | |||
| 628 | // validate lacpdu and port | 634 | // validate lacpdu and port |
| 629 | if (lacpdu && port) { | 635 | if (lacpdu && port) { |
| 630 | // check if all parameters are alike | 636 | // check if all parameters are alike |
| 631 | if (((lacpdu->partner_port == port->actor_port_number) && | 637 | if (((ntohs(lacpdu->partner_port) == port->actor_port_number) && |
| 632 | (lacpdu->partner_port_priority == port->actor_port_priority) && | 638 | (ntohs(lacpdu->partner_port_priority) == port->actor_port_priority) && |
| 633 | !MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) && | 639 | !MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) && |
| 634 | (lacpdu->partner_system_priority == port->actor_system_priority) && | 640 | (ntohs(lacpdu->partner_system_priority) == port->actor_system_priority) && |
| 635 | (lacpdu->partner_key == port->actor_oper_port_key) && | 641 | (ntohs(lacpdu->partner_key) == port->actor_oper_port_key) && |
| 636 | ((lacpdu->partner_state & AD_STATE_AGGREGATION) == (port->actor_oper_port_state & AD_STATE_AGGREGATION))) || | 642 | ((lacpdu->partner_state & AD_STATE_AGGREGATION) == (port->actor_oper_port_state & AD_STATE_AGGREGATION))) || |
| 637 | // or this is individual link(aggregation == FALSE) | 643 | // or this is individual link(aggregation == FALSE) |
| 638 | ((lacpdu->actor_state & AD_STATE_AGGREGATION) == 0) | 644 | ((lacpdu->actor_state & AD_STATE_AGGREGATION) == 0) |
| @@ -662,11 +668,11 @@ static void __update_ntt(struct lacpdu *lacpdu, struct port *port) | |||
| 662 | // validate lacpdu and port | 668 | // validate lacpdu and port |
| 663 | if (lacpdu && port) { | 669 | if (lacpdu && port) { |
| 664 | // check if any parameter is different | 670 | // check if any parameter is different |
| 665 | if ((lacpdu->partner_port != port->actor_port_number) || | 671 | if ((ntohs(lacpdu->partner_port) != port->actor_port_number) || |
| 666 | (lacpdu->partner_port_priority != port->actor_port_priority) || | 672 | (ntohs(lacpdu->partner_port_priority) != port->actor_port_priority) || |
| 667 | MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) || | 673 | MAC_ADDRESS_COMPARE(&(lacpdu->partner_system), &(port->actor_system)) || |
| 668 | (lacpdu->partner_system_priority != port->actor_system_priority) || | 674 | (ntohs(lacpdu->partner_system_priority) != port->actor_system_priority) || |
| 669 | (lacpdu->partner_key != port->actor_oper_port_key) || | 675 | (ntohs(lacpdu->partner_key) != port->actor_oper_port_key) || |
| 670 | ((lacpdu->partner_state & AD_STATE_LACP_ACTIVITY) != (port->actor_oper_port_state & AD_STATE_LACP_ACTIVITY)) || | 676 | ((lacpdu->partner_state & AD_STATE_LACP_ACTIVITY) != (port->actor_oper_port_state & AD_STATE_LACP_ACTIVITY)) || |
| 671 | ((lacpdu->partner_state & AD_STATE_LACP_TIMEOUT) != (port->actor_oper_port_state & AD_STATE_LACP_TIMEOUT)) || | 677 | ((lacpdu->partner_state & AD_STATE_LACP_TIMEOUT) != (port->actor_oper_port_state & AD_STATE_LACP_TIMEOUT)) || |
| 672 | ((lacpdu->partner_state & AD_STATE_SYNCHRONIZATION) != (port->actor_oper_port_state & AD_STATE_SYNCHRONIZATION)) || | 678 | ((lacpdu->partner_state & AD_STATE_SYNCHRONIZATION) != (port->actor_oper_port_state & AD_STATE_SYNCHRONIZATION)) || |
| @@ -775,6 +781,9 @@ static u32 __get_agg_bandwidth(struct aggregator *aggregator) | |||
| 775 | case AD_LINK_SPEED_BITMASK_1000MBPS: | 781 | case AD_LINK_SPEED_BITMASK_1000MBPS: |
| 776 | bandwidth = aggregator->num_of_ports * 1000; | 782 | bandwidth = aggregator->num_of_ports * 1000; |
| 777 | break; | 783 | break; |
| 784 | case AD_LINK_SPEED_BITMASK_10000MBPS: | ||
| 785 | bandwidth = aggregator->num_of_ports * 10000; | ||
| 786 | break; | ||
| 778 | default: | 787 | default: |
| 779 | bandwidth=0; // to silent the compilor .... | 788 | bandwidth=0; // to silent the compilor .... |
| 780 | } | 789 | } |
| @@ -847,7 +856,7 @@ static inline void __update_lacpdu_from_port(struct port *port) | |||
| 847 | */ | 856 | */ |
| 848 | 857 | ||
| 849 | /* Convert all non u8 parameters to Big Endian for transmit */ | 858 | /* Convert all non u8 parameters to Big Endian for transmit */ |
| 850 | __ntohs_lacpdu(lacpdu); | 859 | __htons_lacpdu(lacpdu); |
| 851 | } | 860 | } |
| 852 | 861 | ||
| 853 | ////////////////////////////////////////////////////////////////////////////////////// | 862 | ////////////////////////////////////////////////////////////////////////////////////// |
| @@ -2171,7 +2180,6 @@ static void bond_3ad_rx_indication(struct lacpdu *lacpdu, struct slave *slave, u | |||
| 2171 | 2180 | ||
| 2172 | switch (lacpdu->subtype) { | 2181 | switch (lacpdu->subtype) { |
| 2173 | case AD_TYPE_LACPDU: | 2182 | case AD_TYPE_LACPDU: |
| 2174 | __ntohs_lacpdu(lacpdu); | ||
| 2175 | dprintk("Received LACPDU on port %d\n", port->actor_port_number); | 2183 | dprintk("Received LACPDU on port %d\n", port->actor_port_number); |
| 2176 | ad_rx_machine(lacpdu, port); | 2184 | ad_rx_machine(lacpdu, port); |
| 2177 | break; | 2185 | break; |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 850aae21a2fe..0fb5f653d3ce 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
| @@ -96,6 +96,7 @@ static char *lacp_rate = NULL; | |||
| 96 | static char *xmit_hash_policy = NULL; | 96 | static char *xmit_hash_policy = NULL; |
| 97 | static int arp_interval = BOND_LINK_ARP_INTERV; | 97 | static int arp_interval = BOND_LINK_ARP_INTERV; |
| 98 | static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, }; | 98 | static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, }; |
| 99 | static char *arp_validate = NULL; | ||
| 99 | struct bond_params bonding_defaults; | 100 | struct bond_params bonding_defaults; |
| 100 | 101 | ||
| 101 | module_param(max_bonds, int, 0); | 102 | module_param(max_bonds, int, 0); |
| @@ -127,6 +128,8 @@ module_param(arp_interval, int, 0); | |||
| 127 | MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds"); | 128 | MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds"); |
| 128 | module_param_array(arp_ip_target, charp, NULL, 0); | 129 | module_param_array(arp_ip_target, charp, NULL, 0); |
| 129 | MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form"); | 130 | MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form"); |
| 131 | module_param(arp_validate, charp, 0); | ||
| 132 | MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes: none (default), active, backup or all"); | ||
| 130 | 133 | ||
| 131 | /*----------------------------- Global variables ----------------------------*/ | 134 | /*----------------------------- Global variables ----------------------------*/ |
| 132 | 135 | ||
| @@ -170,6 +173,14 @@ struct bond_parm_tbl xmit_hashtype_tbl[] = { | |||
| 170 | { NULL, -1}, | 173 | { NULL, -1}, |
| 171 | }; | 174 | }; |
| 172 | 175 | ||
| 176 | struct bond_parm_tbl arp_validate_tbl[] = { | ||
| 177 | { "none", BOND_ARP_VALIDATE_NONE}, | ||
| 178 | { "active", BOND_ARP_VALIDATE_ACTIVE}, | ||
| 179 | { "backup", BOND_ARP_VALIDATE_BACKUP}, | ||
| 180 | { "all", BOND_ARP_VALIDATE_ALL}, | ||
| 181 | { NULL, -1}, | ||
| 182 | }; | ||
| 183 | |||
| 173 | /*-------------------------- Forward declarations ---------------------------*/ | 184 | /*-------------------------- Forward declarations ---------------------------*/ |
| 174 | 185 | ||
| 175 | static void bond_send_gratuitous_arp(struct bonding *bond); | 186 | static void bond_send_gratuitous_arp(struct bonding *bond); |
| @@ -638,6 +649,7 @@ verify: | |||
| 638 | case SPEED_10: | 649 | case SPEED_10: |
| 639 | case SPEED_100: | 650 | case SPEED_100: |
| 640 | case SPEED_1000: | 651 | case SPEED_1000: |
| 652 | case SPEED_10000: | ||
| 641 | break; | 653 | break; |
| 642 | default: | 654 | default: |
| 643 | return -1; | 655 | return -1; |
| @@ -1210,10 +1222,14 @@ static int bond_compute_features(struct bonding *bond) | |||
| 1210 | unsigned long features = BOND_INTERSECT_FEATURES; | 1222 | unsigned long features = BOND_INTERSECT_FEATURES; |
| 1211 | struct slave *slave; | 1223 | struct slave *slave; |
| 1212 | struct net_device *bond_dev = bond->dev; | 1224 | struct net_device *bond_dev = bond->dev; |
| 1225 | unsigned short max_hard_header_len = ETH_HLEN; | ||
| 1213 | int i; | 1226 | int i; |
| 1214 | 1227 | ||
| 1215 | bond_for_each_slave(bond, slave, i) | 1228 | bond_for_each_slave(bond, slave, i) { |
| 1216 | features &= (slave->dev->features & BOND_INTERSECT_FEATURES); | 1229 | features &= (slave->dev->features & BOND_INTERSECT_FEATURES); |
| 1230 | if (slave->dev->hard_header_len > max_hard_header_len) | ||
| 1231 | max_hard_header_len = slave->dev->hard_header_len; | ||
| 1232 | } | ||
| 1217 | 1233 | ||
| 1218 | if ((features & NETIF_F_SG) && | 1234 | if ((features & NETIF_F_SG) && |
| 1219 | !(features & NETIF_F_ALL_CSUM)) | 1235 | !(features & NETIF_F_ALL_CSUM)) |
| @@ -1231,6 +1247,7 @@ static int bond_compute_features(struct bonding *bond) | |||
| 1231 | 1247 | ||
| 1232 | features |= (bond_dev->features & ~BOND_INTERSECT_FEATURES); | 1248 | features |= (bond_dev->features & ~BOND_INTERSECT_FEATURES); |
| 1233 | bond_dev->features = features; | 1249 | bond_dev->features = features; |
| 1250 | bond_dev->hard_header_len = max_hard_header_len; | ||
| 1234 | 1251 | ||
| 1235 | return 0; | 1252 | return 0; |
| 1236 | } | 1253 | } |
| @@ -1365,6 +1382,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
| 1365 | } | 1382 | } |
| 1366 | 1383 | ||
| 1367 | new_slave->dev = slave_dev; | 1384 | new_slave->dev = slave_dev; |
| 1385 | slave_dev->priv_flags |= IFF_BONDING; | ||
| 1368 | 1386 | ||
| 1369 | if ((bond->params.mode == BOND_MODE_TLB) || | 1387 | if ((bond->params.mode == BOND_MODE_TLB) || |
| 1370 | (bond->params.mode == BOND_MODE_ALB)) { | 1388 | (bond->params.mode == BOND_MODE_ALB)) { |
| @@ -1417,6 +1435,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
| 1417 | 1435 | ||
| 1418 | bond_compute_features(bond); | 1436 | bond_compute_features(bond); |
| 1419 | 1437 | ||
| 1438 | new_slave->last_arp_rx = jiffies; | ||
| 1439 | |||
| 1420 | if (bond->params.miimon && !bond->params.use_carrier) { | 1440 | if (bond->params.miimon && !bond->params.use_carrier) { |
| 1421 | link_reporting = bond_check_dev_link(bond, slave_dev, 1); | 1441 | link_reporting = bond_check_dev_link(bond, slave_dev, 1); |
| 1422 | 1442 | ||
| @@ -1493,29 +1513,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
| 1493 | 1513 | ||
| 1494 | switch (bond->params.mode) { | 1514 | switch (bond->params.mode) { |
| 1495 | case BOND_MODE_ACTIVEBACKUP: | 1515 | case BOND_MODE_ACTIVEBACKUP: |
| 1496 | /* if we're in active-backup mode, we need one and | 1516 | bond_set_slave_inactive_flags(new_slave); |
| 1497 | * only one active interface. The backup interfaces | 1517 | bond_select_active_slave(bond); |
| 1498 | * will have their SLAVE_INACTIVE flag set because we | ||
| 1499 | * need them to be drop all packets. Thus, since we | ||
| 1500 | * guarantee that curr_active_slave always point to | ||
| 1501 | * the last usable interface, we just have to verify | ||
| 1502 | * this interface's flag. | ||
| 1503 | */ | ||
| 1504 | if (((!bond->curr_active_slave) || | ||
| 1505 | (bond->curr_active_slave->dev->priv_flags & IFF_SLAVE_INACTIVE)) && | ||
| 1506 | (new_slave->link != BOND_LINK_DOWN)) { | ||
| 1507 | /* first slave or no active slave yet, and this link | ||
| 1508 | is OK, so make this interface the active one */ | ||
| 1509 | bond_change_active_slave(bond, new_slave); | ||
| 1510 | printk(KERN_INFO DRV_NAME | ||
| 1511 | ": %s: first active interface up!\n", | ||
| 1512 | bond->dev->name); | ||
| 1513 | netif_carrier_on(bond->dev); | ||
| 1514 | |||
| 1515 | } else { | ||
| 1516 | dprintk("This is just a backup slave\n"); | ||
| 1517 | bond_set_slave_inactive_flags(new_slave); | ||
| 1518 | } | ||
| 1519 | break; | 1518 | break; |
| 1520 | case BOND_MODE_8023AD: | 1519 | case BOND_MODE_8023AD: |
| 1521 | /* in 802.3ad mode, the internal mechanism | 1520 | /* in 802.3ad mode, the internal mechanism |
| @@ -1778,7 +1777,8 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev) | |||
| 1778 | dev_set_mac_address(slave_dev, &addr); | 1777 | dev_set_mac_address(slave_dev, &addr); |
| 1779 | 1778 | ||
| 1780 | slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB | | 1779 | slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB | |
| 1781 | IFF_SLAVE_INACTIVE); | 1780 | IFF_SLAVE_INACTIVE | IFF_BONDING | |
| 1781 | IFF_SLAVE_NEEDARP); | ||
| 1782 | 1782 | ||
| 1783 | kfree(slave); | 1783 | kfree(slave); |
| 1784 | 1784 | ||
| @@ -2291,6 +2291,25 @@ static int bond_has_ip(struct bonding *bond) | |||
| 2291 | return 0; | 2291 | return 0; |
| 2292 | } | 2292 | } |
| 2293 | 2293 | ||
| 2294 | static int bond_has_this_ip(struct bonding *bond, u32 ip) | ||
| 2295 | { | ||
| 2296 | struct vlan_entry *vlan, *vlan_next; | ||
| 2297 | |||
| 2298 | if (ip == bond->master_ip) | ||
| 2299 | return 1; | ||
| 2300 | |||
| 2301 | if (list_empty(&bond->vlan_list)) | ||
| 2302 | return 0; | ||
| 2303 | |||
| 2304 | list_for_each_entry_safe(vlan, vlan_next, &bond->vlan_list, | ||
| 2305 | vlan_list) { | ||
| 2306 | if (ip == vlan->vlan_ip) | ||
| 2307 | return 1; | ||
| 2308 | } | ||
| 2309 | |||
| 2310 | return 0; | ||
| 2311 | } | ||
| 2312 | |||
| 2294 | /* | 2313 | /* |
| 2295 | * We go to the (large) trouble of VLAN tagging ARP frames because | 2314 | * We go to the (large) trouble of VLAN tagging ARP frames because |
| 2296 | * switches in VLAN mode (especially if ports are configured as | 2315 | * switches in VLAN mode (especially if ports are configured as |
| @@ -2429,6 +2448,93 @@ static void bond_send_gratuitous_arp(struct bonding *bond) | |||
| 2429 | } | 2448 | } |
| 2430 | } | 2449 | } |
| 2431 | 2450 | ||
| 2451 | static void bond_validate_arp(struct bonding *bond, struct slave *slave, u32 sip, u32 tip) | ||
| 2452 | { | ||
| 2453 | int i; | ||
| 2454 | u32 *targets = bond->params.arp_targets; | ||
| 2455 | |||
| 2456 | targets = bond->params.arp_targets; | ||
| 2457 | for (i = 0; (i < BOND_MAX_ARP_TARGETS) && targets[i]; i++) { | ||
| 2458 | dprintk("bva: sip %u.%u.%u.%u tip %u.%u.%u.%u t[%d] " | ||
| 2459 | "%u.%u.%u.%u bhti(tip) %d\n", | ||
| 2460 | NIPQUAD(sip), NIPQUAD(tip), i, NIPQUAD(targets[i]), | ||
| 2461 | bond_has_this_ip(bond, tip)); | ||
| 2462 | if (sip == targets[i]) { | ||
| 2463 | if (bond_has_this_ip(bond, tip)) | ||
| 2464 | slave->last_arp_rx = jiffies; | ||
| 2465 | return; | ||
| 2466 | } | ||
| 2467 | } | ||
| 2468 | } | ||
| 2469 | |||
| 2470 | static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev) | ||
| 2471 | { | ||
| 2472 | struct arphdr *arp; | ||
| 2473 | struct slave *slave; | ||
| 2474 | struct bonding *bond; | ||
| 2475 | unsigned char *arp_ptr; | ||
| 2476 | u32 sip, tip; | ||
| 2477 | |||
| 2478 | if (!(dev->priv_flags & IFF_BONDING) || !(dev->flags & IFF_MASTER)) | ||
| 2479 | goto out; | ||
| 2480 | |||
| 2481 | bond = dev->priv; | ||
| 2482 | read_lock(&bond->lock); | ||
| 2483 | |||
| 2484 | dprintk("bond_arp_rcv: bond %s skb->dev %s orig_dev %s\n", | ||
| 2485 | bond->dev->name, skb->dev ? skb->dev->name : "NULL", | ||
| 2486 | orig_dev ? orig_dev->name : "NULL"); | ||
| 2487 | |||
| 2488 | slave = bond_get_slave_by_dev(bond, orig_dev); | ||
| 2489 | if (!slave || !slave_do_arp_validate(bond, slave)) | ||
| 2490 | goto out_unlock; | ||
| 2491 | |||
| 2492 | /* ARP header, plus 2 device addresses, plus 2 IP addresses. */ | ||
| 2493 | if (!pskb_may_pull(skb, (sizeof(struct arphdr) + | ||
| 2494 | (2 * dev->addr_len) + | ||
| 2495 | (2 * sizeof(u32))))) | ||
| 2496 | goto out_unlock; | ||
| 2497 | |||
| 2498 | arp = skb->nh.arph; | ||
| 2499 | if (arp->ar_hln != dev->addr_len || | ||
| 2500 | skb->pkt_type == PACKET_OTHERHOST || | ||
| 2501 | skb->pkt_type == PACKET_LOOPBACK || | ||
| 2502 | arp->ar_hrd != htons(ARPHRD_ETHER) || | ||
| 2503 | arp->ar_pro != htons(ETH_P_IP) || | ||
| 2504 | arp->ar_pln != 4) | ||
| 2505 | goto out_unlock; | ||
| 2506 | |||
| 2507 | arp_ptr = (unsigned char *)(arp + 1); | ||
| 2508 | arp_ptr += dev->addr_len; | ||
| 2509 | memcpy(&sip, arp_ptr, 4); | ||
| 2510 | arp_ptr += 4 + dev->addr_len; | ||
| 2511 | memcpy(&tip, arp_ptr, 4); | ||
| 2512 | |||
| 2513 | dprintk("bond_arp_rcv: %s %s/%d av %d sv %d sip %u.%u.%u.%u" | ||
| 2514 | " tip %u.%u.%u.%u\n", bond->dev->name, slave->dev->name, | ||
| 2515 | slave->state, bond->params.arp_validate, | ||
| 2516 | slave_do_arp_validate(bond, slave), NIPQUAD(sip), NIPQUAD(tip)); | ||
| 2517 | |||
| 2518 | /* | ||
| 2519 | * Backup slaves won't see the ARP reply, but do come through | ||
| 2520 | * here for each ARP probe (so we swap the sip/tip to validate | ||
| 2521 | * the probe). In a "redundant switch, common router" type of | ||
| 2522 | * configuration, the ARP probe will (hopefully) travel from | ||
| 2523 | * the active, through one switch, the router, then the other | ||
| 2524 | * switch before reaching the backup. | ||
| 2525 | */ | ||
| 2526 | if (slave->state == BOND_STATE_ACTIVE) | ||
| 2527 | bond_validate_arp(bond, slave, sip, tip); | ||
| 2528 | else | ||
| 2529 | bond_validate_arp(bond, slave, tip, sip); | ||
| 2530 | |||
| 2531 | out_unlock: | ||
| 2532 | read_unlock(&bond->lock); | ||
| 2533 | out: | ||
| 2534 | dev_kfree_skb(skb); | ||
| 2535 | return NET_RX_SUCCESS; | ||
| 2536 | } | ||
| 2537 | |||
| 2432 | /* | 2538 | /* |
| 2433 | * this function is called regularly to monitor each slave's link | 2539 | * this function is called regularly to monitor each slave's link |
| 2434 | * ensuring that traffic is being sent and received when arp monitoring | 2540 | * ensuring that traffic is being sent and received when arp monitoring |
| @@ -2593,7 +2699,8 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev) | |||
| 2593 | */ | 2699 | */ |
| 2594 | bond_for_each_slave(bond, slave, i) { | 2700 | bond_for_each_slave(bond, slave, i) { |
| 2595 | if (slave->link != BOND_LINK_UP) { | 2701 | if (slave->link != BOND_LINK_UP) { |
| 2596 | if ((jiffies - slave->dev->last_rx) <= delta_in_ticks) { | 2702 | if ((jiffies - slave_last_rx(bond, slave)) <= |
| 2703 | delta_in_ticks) { | ||
| 2597 | 2704 | ||
| 2598 | slave->link = BOND_LINK_UP; | 2705 | slave->link = BOND_LINK_UP; |
| 2599 | 2706 | ||
| @@ -2638,7 +2745,7 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev) | |||
| 2638 | 2745 | ||
| 2639 | if ((slave != bond->curr_active_slave) && | 2746 | if ((slave != bond->curr_active_slave) && |
| 2640 | (!bond->current_arp_slave) && | 2747 | (!bond->current_arp_slave) && |
| 2641 | (((jiffies - slave->dev->last_rx) >= 3*delta_in_ticks) && | 2748 | (((jiffies - slave_last_rx(bond, slave)) >= 3*delta_in_ticks) && |
| 2642 | bond_has_ip(bond))) { | 2749 | bond_has_ip(bond))) { |
| 2643 | /* a backup slave has gone down; three times | 2750 | /* a backup slave has gone down; three times |
| 2644 | * the delta allows the current slave to be | 2751 | * the delta allows the current slave to be |
| @@ -2685,7 +2792,7 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev) | |||
| 2685 | * if it is up and needs to take over as the curr_active_slave | 2792 | * if it is up and needs to take over as the curr_active_slave |
| 2686 | */ | 2793 | */ |
| 2687 | if ((((jiffies - slave->dev->trans_start) >= (2*delta_in_ticks)) || | 2794 | if ((((jiffies - slave->dev->trans_start) >= (2*delta_in_ticks)) || |
| 2688 | (((jiffies - slave->dev->last_rx) >= (2*delta_in_ticks)) && | 2795 | (((jiffies - slave_last_rx(bond, slave)) >= (2*delta_in_ticks)) && |
| 2689 | bond_has_ip(bond))) && | 2796 | bond_has_ip(bond))) && |
| 2690 | ((jiffies - slave->jiffies) >= 2*delta_in_ticks)) { | 2797 | ((jiffies - slave->jiffies) >= 2*delta_in_ticks)) { |
| 2691 | 2798 | ||
| @@ -2950,7 +3057,7 @@ static void bond_info_show_slave(struct seq_file *seq, const struct slave *slave | |||
| 2950 | seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name); | 3057 | seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name); |
| 2951 | seq_printf(seq, "MII Status: %s\n", | 3058 | seq_printf(seq, "MII Status: %s\n", |
| 2952 | (slave->link == BOND_LINK_UP) ? "up" : "down"); | 3059 | (slave->link == BOND_LINK_UP) ? "up" : "down"); |
| 2953 | seq_printf(seq, "Link Failure Count: %d\n", | 3060 | seq_printf(seq, "Link Failure Count: %u\n", |
| 2954 | slave->link_failure_count); | 3061 | slave->link_failure_count); |
| 2955 | 3062 | ||
| 2956 | seq_printf(seq, | 3063 | seq_printf(seq, |
| @@ -3210,6 +3317,9 @@ static int bond_netdev_event(struct notifier_block *this, unsigned long event, v | |||
| 3210 | (event_dev ? event_dev->name : "None"), | 3317 | (event_dev ? event_dev->name : "None"), |
| 3211 | event); | 3318 | event); |
| 3212 | 3319 | ||
| 3320 | if (!(event_dev->priv_flags & IFF_BONDING)) | ||
| 3321 | return NOTIFY_DONE; | ||
| 3322 | |||
| 3213 | if (event_dev->flags & IFF_MASTER) { | 3323 | if (event_dev->flags & IFF_MASTER) { |
| 3214 | dprintk("IFF_MASTER\n"); | 3324 | dprintk("IFF_MASTER\n"); |
| 3215 | return bond_master_netdev_event(event, event_dev); | 3325 | return bond_master_netdev_event(event, event_dev); |
| @@ -3305,6 +3415,21 @@ static void bond_unregister_lacpdu(struct bonding *bond) | |||
| 3305 | dev_remove_pack(&(BOND_AD_INFO(bond).ad_pkt_type)); | 3415 | dev_remove_pack(&(BOND_AD_INFO(bond).ad_pkt_type)); |
| 3306 | } | 3416 | } |
| 3307 | 3417 | ||
| 3418 | void bond_register_arp(struct bonding *bond) | ||
| 3419 | { | ||
| 3420 | struct packet_type *pt = &bond->arp_mon_pt; | ||
| 3421 | |||
| 3422 | pt->type = htons(ETH_P_ARP); | ||
| 3423 | pt->dev = NULL; /*bond->dev;XXX*/ | ||
| 3424 | pt->func = bond_arp_rcv; | ||
| 3425 | dev_add_pack(pt); | ||
| 3426 | } | ||
| 3427 | |||
| 3428 | void bond_unregister_arp(struct bonding *bond) | ||
| 3429 | { | ||
| 3430 | dev_remove_pack(&bond->arp_mon_pt); | ||
| 3431 | } | ||
| 3432 | |||
| 3308 | /*---------------------------- Hashing Policies -----------------------------*/ | 3433 | /*---------------------------- Hashing Policies -----------------------------*/ |
| 3309 | 3434 | ||
| 3310 | /* | 3435 | /* |
| @@ -3391,6 +3516,9 @@ static int bond_open(struct net_device *bond_dev) | |||
| 3391 | } else { | 3516 | } else { |
| 3392 | arp_timer->function = (void *)&bond_loadbalance_arp_mon; | 3517 | arp_timer->function = (void *)&bond_loadbalance_arp_mon; |
| 3393 | } | 3518 | } |
| 3519 | if (bond->params.arp_validate) | ||
| 3520 | bond_register_arp(bond); | ||
| 3521 | |||
| 3394 | add_timer(arp_timer); | 3522 | add_timer(arp_timer); |
| 3395 | } | 3523 | } |
| 3396 | 3524 | ||
| @@ -3418,9 +3546,11 @@ static int bond_close(struct net_device *bond_dev) | |||
| 3418 | bond_unregister_lacpdu(bond); | 3546 | bond_unregister_lacpdu(bond); |
| 3419 | } | 3547 | } |
| 3420 | 3548 | ||
| 3549 | if (bond->params.arp_validate) | ||
| 3550 | bond_unregister_arp(bond); | ||
| 3551 | |||
| 3421 | write_lock_bh(&bond->lock); | 3552 | write_lock_bh(&bond->lock); |
| 3422 | 3553 | ||
| 3423 | bond_mc_list_destroy(bond); | ||
| 3424 | 3554 | ||
| 3425 | /* signal timers not to re-arm */ | 3555 | /* signal timers not to re-arm */ |
| 3426 | bond->kill_timers = 1; | 3556 | bond->kill_timers = 1; |
| @@ -3451,8 +3581,6 @@ static int bond_close(struct net_device *bond_dev) | |||
| 3451 | break; | 3581 | break; |
| 3452 | } | 3582 | } |
| 3453 | 3583 | ||
| 3454 | /* Release the bonded slaves */ | ||
| 3455 | bond_release_all(bond_dev); | ||
| 3456 | 3584 | ||
| 3457 | if ((bond->params.mode == BOND_MODE_TLB) || | 3585 | if ((bond->params.mode == BOND_MODE_TLB) || |
| 3458 | (bond->params.mode == BOND_MODE_ALB)) { | 3586 | (bond->params.mode == BOND_MODE_ALB)) { |
| @@ -4179,6 +4307,7 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params) | |||
| 4179 | /* Initialize the device options */ | 4307 | /* Initialize the device options */ |
| 4180 | bond_dev->tx_queue_len = 0; | 4308 | bond_dev->tx_queue_len = 0; |
| 4181 | bond_dev->flags |= IFF_MASTER|IFF_MULTICAST; | 4309 | bond_dev->flags |= IFF_MASTER|IFF_MULTICAST; |
| 4310 | bond_dev->priv_flags |= IFF_BONDING; | ||
| 4182 | 4311 | ||
| 4183 | /* At first, we block adding VLANs. That's the only way to | 4312 | /* At first, we block adding VLANs. That's the only way to |
| 4184 | * prevent problems that occur when adding VLANs over an | 4313 | * prevent problems that occur when adding VLANs over an |
| @@ -4237,6 +4366,9 @@ static void bond_free_all(void) | |||
| 4237 | list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) { | 4366 | list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) { |
| 4238 | struct net_device *bond_dev = bond->dev; | 4367 | struct net_device *bond_dev = bond->dev; |
| 4239 | 4368 | ||
| 4369 | bond_mc_list_destroy(bond); | ||
| 4370 | /* Release the bonded slaves */ | ||
| 4371 | bond_release_all(bond_dev); | ||
| 4240 | unregister_netdevice(bond_dev); | 4372 | unregister_netdevice(bond_dev); |
| 4241 | bond_deinit(bond_dev); | 4373 | bond_deinit(bond_dev); |
| 4242 | } | 4374 | } |
| @@ -4270,6 +4402,8 @@ int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl) | |||
| 4270 | 4402 | ||
| 4271 | static int bond_check_params(struct bond_params *params) | 4403 | static int bond_check_params(struct bond_params *params) |
| 4272 | { | 4404 | { |
| 4405 | int arp_validate_value; | ||
| 4406 | |||
| 4273 | /* | 4407 | /* |
| 4274 | * Convert string parameters. | 4408 | * Convert string parameters. |
| 4275 | */ | 4409 | */ |
| @@ -4473,6 +4607,29 @@ static int bond_check_params(struct bond_params *params) | |||
| 4473 | arp_interval = 0; | 4607 | arp_interval = 0; |
| 4474 | } | 4608 | } |
| 4475 | 4609 | ||
| 4610 | if (arp_validate) { | ||
| 4611 | if (bond_mode != BOND_MODE_ACTIVEBACKUP) { | ||
| 4612 | printk(KERN_ERR DRV_NAME | ||
| 4613 | ": arp_validate only supported in active-backup mode\n"); | ||
| 4614 | return -EINVAL; | ||
| 4615 | } | ||
| 4616 | if (!arp_interval) { | ||
| 4617 | printk(KERN_ERR DRV_NAME | ||
| 4618 | ": arp_validate requires arp_interval\n"); | ||
| 4619 | return -EINVAL; | ||
| 4620 | } | ||
| 4621 | |||
| 4622 | arp_validate_value = bond_parse_parm(arp_validate, | ||
| 4623 | arp_validate_tbl); | ||
| 4624 | if (arp_validate_value == -1) { | ||
| 4625 | printk(KERN_ERR DRV_NAME | ||
| 4626 | ": Error: invalid arp_validate \"%s\"\n", | ||
| 4627 | arp_validate == NULL ? "NULL" : arp_validate); | ||
| 4628 | return -EINVAL; | ||
| 4629 | } | ||
| 4630 | } else | ||
| 4631 | arp_validate_value = 0; | ||
| 4632 | |||
| 4476 | if (miimon) { | 4633 | if (miimon) { |
| 4477 | printk(KERN_INFO DRV_NAME | 4634 | printk(KERN_INFO DRV_NAME |
| 4478 | ": MII link monitoring set to %d ms\n", | 4635 | ": MII link monitoring set to %d ms\n", |
| @@ -4481,8 +4638,10 @@ static int bond_check_params(struct bond_params *params) | |||
| 4481 | int i; | 4638 | int i; |
| 4482 | 4639 | ||
| 4483 | printk(KERN_INFO DRV_NAME | 4640 | printk(KERN_INFO DRV_NAME |
| 4484 | ": ARP monitoring set to %d ms with %d target(s):", | 4641 | ": ARP monitoring set to %d ms, validate %s, with %d target(s):", |
| 4485 | arp_interval, arp_ip_count); | 4642 | arp_interval, |
| 4643 | arp_validate_tbl[arp_validate_value].modename, | ||
| 4644 | arp_ip_count); | ||
| 4486 | 4645 | ||
| 4487 | for (i = 0; i < arp_ip_count; i++) | 4646 | for (i = 0; i < arp_ip_count; i++) |
| 4488 | printk (" %s", arp_ip_target[i]); | 4647 | printk (" %s", arp_ip_target[i]); |
| @@ -4516,6 +4675,7 @@ static int bond_check_params(struct bond_params *params) | |||
| 4516 | params->xmit_policy = xmit_hashtype; | 4675 | params->xmit_policy = xmit_hashtype; |
| 4517 | params->miimon = miimon; | 4676 | params->miimon = miimon; |
| 4518 | params->arp_interval = arp_interval; | 4677 | params->arp_interval = arp_interval; |
| 4678 | params->arp_validate = arp_validate_value; | ||
| 4519 | params->updelay = updelay; | 4679 | params->updelay = updelay; |
| 4520 | params->downdelay = downdelay; | 4680 | params->downdelay = downdelay; |
| 4521 | params->use_carrier = use_carrier; | 4681 | params->use_carrier = use_carrier; |
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index cfe4dc3a93a3..ced9ed8f995a 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
| @@ -51,6 +51,7 @@ extern struct bond_params bonding_defaults; | |||
| 51 | extern struct bond_parm_tbl bond_mode_tbl[]; | 51 | extern struct bond_parm_tbl bond_mode_tbl[]; |
| 52 | extern struct bond_parm_tbl bond_lacp_tbl[]; | 52 | extern struct bond_parm_tbl bond_lacp_tbl[]; |
| 53 | extern struct bond_parm_tbl xmit_hashtype_tbl[]; | 53 | extern struct bond_parm_tbl xmit_hashtype_tbl[]; |
| 54 | extern struct bond_parm_tbl arp_validate_tbl[]; | ||
| 54 | 55 | ||
| 55 | static int expected_refcount = -1; | 56 | static int expected_refcount = -1; |
| 56 | static struct class *netdev_class; | 57 | static struct class *netdev_class; |
| @@ -503,6 +504,53 @@ out: | |||
| 503 | static CLASS_DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR, bonding_show_xmit_hash, bonding_store_xmit_hash); | 504 | static CLASS_DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR, bonding_show_xmit_hash, bonding_store_xmit_hash); |
| 504 | 505 | ||
| 505 | /* | 506 | /* |
| 507 | * Show and set arp_validate. | ||
| 508 | */ | ||
| 509 | static ssize_t bonding_show_arp_validate(struct class_device *cd, char *buf) | ||
| 510 | { | ||
| 511 | struct bonding *bond = to_bond(cd); | ||
| 512 | |||
| 513 | return sprintf(buf, "%s %d\n", | ||
| 514 | arp_validate_tbl[bond->params.arp_validate].modename, | ||
| 515 | bond->params.arp_validate) + 1; | ||
| 516 | } | ||
| 517 | |||
| 518 | static ssize_t bonding_store_arp_validate(struct class_device *cd, const char *buf, size_t count) | ||
| 519 | { | ||
| 520 | int new_value; | ||
| 521 | struct bonding *bond = to_bond(cd); | ||
| 522 | |||
| 523 | new_value = bond_parse_parm((char *)buf, arp_validate_tbl); | ||
| 524 | if (new_value < 0) { | ||
| 525 | printk(KERN_ERR DRV_NAME | ||
| 526 | ": %s: Ignoring invalid arp_validate value %s\n", | ||
| 527 | bond->dev->name, buf); | ||
| 528 | return -EINVAL; | ||
| 529 | } | ||
| 530 | if (new_value && (bond->params.mode != BOND_MODE_ACTIVEBACKUP)) { | ||
| 531 | printk(KERN_ERR DRV_NAME | ||
| 532 | ": %s: arp_validate only supported in active-backup mode.\n", | ||
| 533 | bond->dev->name); | ||
| 534 | return -EINVAL; | ||
| 535 | } | ||
| 536 | printk(KERN_INFO DRV_NAME ": %s: setting arp_validate to %s (%d).\n", | ||
| 537 | bond->dev->name, arp_validate_tbl[new_value].modename, | ||
| 538 | new_value); | ||
| 539 | |||
| 540 | if (!bond->params.arp_validate && new_value) { | ||
| 541 | bond_register_arp(bond); | ||
| 542 | } else if (bond->params.arp_validate && !new_value) { | ||
| 543 | bond_unregister_arp(bond); | ||
| 544 | } | ||
| 545 | |||
| 546 | bond->params.arp_validate = new_value; | ||
| 547 | |||
| 548 | return count; | ||
| 549 | } | ||
| 550 | |||
| 551 | static CLASS_DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate, bonding_store_arp_validate); | ||
| 552 | |||
| 553 | /* | ||
| 506 | * Show and set the arp timer interval. There are two tricky bits | 554 | * Show and set the arp timer interval. There are two tricky bits |
| 507 | * here. First, if ARP monitoring is activated, then we must disable | 555 | * here. First, if ARP monitoring is activated, then we must disable |
| 508 | * MII monitoring. Second, if the ARP timer isn't running, we must | 556 | * MII monitoring. Second, if the ARP timer isn't running, we must |
| @@ -914,6 +962,11 @@ static ssize_t bonding_store_miimon(struct class_device *cd, const char *buf, si | |||
| 914 | "ARP monitoring. Disabling ARP monitoring...\n", | 962 | "ARP monitoring. Disabling ARP monitoring...\n", |
| 915 | bond->dev->name); | 963 | bond->dev->name); |
| 916 | bond->params.arp_interval = 0; | 964 | bond->params.arp_interval = 0; |
| 965 | if (bond->params.arp_validate) { | ||
| 966 | bond_unregister_arp(bond); | ||
| 967 | bond->params.arp_validate = | ||
| 968 | BOND_ARP_VALIDATE_NONE; | ||
| 969 | } | ||
| 917 | /* Kill ARP timer, else it brings bond's link down */ | 970 | /* Kill ARP timer, else it brings bond's link down */ |
| 918 | if (bond->mii_timer.function) { | 971 | if (bond->mii_timer.function) { |
| 919 | printk(KERN_INFO DRV_NAME | 972 | printk(KERN_INFO DRV_NAME |
| @@ -1093,7 +1146,7 @@ static ssize_t bonding_store_active_slave(struct class_device *cd, const char *b | |||
| 1093 | strlen(slave->dev->name)) == 0) { | 1146 | strlen(slave->dev->name)) == 0) { |
| 1094 | old_active = bond->curr_active_slave; | 1147 | old_active = bond->curr_active_slave; |
| 1095 | new_active = slave; | 1148 | new_active = slave; |
| 1096 | if (new_active && (new_active == old_active)) { | 1149 | if (new_active == old_active) { |
| 1097 | /* do nothing */ | 1150 | /* do nothing */ |
| 1098 | printk(KERN_INFO DRV_NAME | 1151 | printk(KERN_INFO DRV_NAME |
| 1099 | ": %s: %s is already the current active slave.\n", | 1152 | ": %s: %s is already the current active slave.\n", |
| @@ -1273,6 +1326,7 @@ static CLASS_DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, N | |||
| 1273 | static struct attribute *per_bond_attrs[] = { | 1326 | static struct attribute *per_bond_attrs[] = { |
| 1274 | &class_device_attr_slaves.attr, | 1327 | &class_device_attr_slaves.attr, |
| 1275 | &class_device_attr_mode.attr, | 1328 | &class_device_attr_mode.attr, |
| 1329 | &class_device_attr_arp_validate.attr, | ||
| 1276 | &class_device_attr_arp_interval.attr, | 1330 | &class_device_attr_arp_interval.attr, |
| 1277 | &class_device_attr_arp_ip_target.attr, | 1331 | &class_device_attr_arp_ip_target.attr, |
| 1278 | &class_device_attr_downdelay.attr, | 1332 | &class_device_attr_downdelay.attr, |
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 0bdfe2c71453..dc434fb6da85 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
| @@ -22,8 +22,8 @@ | |||
| 22 | #include "bond_3ad.h" | 22 | #include "bond_3ad.h" |
| 23 | #include "bond_alb.h" | 23 | #include "bond_alb.h" |
| 24 | 24 | ||
| 25 | #define DRV_VERSION "3.0.3" | 25 | #define DRV_VERSION "3.1.1" |
| 26 | #define DRV_RELDATE "March 23, 2006" | 26 | #define DRV_RELDATE "September 26, 2006" |
| 27 | #define DRV_NAME "bonding" | 27 | #define DRV_NAME "bonding" |
| 28 | #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" | 28 | #define DRV_DESCRIPTION "Ethernet Channel Bonding Driver" |
| 29 | 29 | ||
| @@ -126,6 +126,7 @@ struct bond_params { | |||
| 126 | int xmit_policy; | 126 | int xmit_policy; |
| 127 | int miimon; | 127 | int miimon; |
| 128 | int arp_interval; | 128 | int arp_interval; |
| 129 | int arp_validate; | ||
| 129 | int use_carrier; | 130 | int use_carrier; |
| 130 | int updelay; | 131 | int updelay; |
| 131 | int downdelay; | 132 | int downdelay; |
| @@ -149,8 +150,9 @@ struct slave { | |||
| 149 | struct net_device *dev; /* first - useful for panic debug */ | 150 | struct net_device *dev; /* first - useful for panic debug */ |
| 150 | struct slave *next; | 151 | struct slave *next; |
| 151 | struct slave *prev; | 152 | struct slave *prev; |
| 152 | s16 delay; | 153 | int delay; |
| 153 | u32 jiffies; | 154 | u32 jiffies; |
| 155 | u32 last_arp_rx; | ||
| 154 | s8 link; /* one of BOND_LINK_XXXX */ | 156 | s8 link; /* one of BOND_LINK_XXXX */ |
| 155 | s8 state; /* one of BOND_STATE_XXXX */ | 157 | s8 state; /* one of BOND_STATE_XXXX */ |
| 156 | u32 original_flags; | 158 | u32 original_flags; |
| @@ -198,6 +200,7 @@ struct bonding { | |||
| 198 | struct bond_params params; | 200 | struct bond_params params; |
| 199 | struct list_head vlan_list; | 201 | struct list_head vlan_list; |
| 200 | struct vlan_group *vlgrp; | 202 | struct vlan_group *vlgrp; |
| 203 | struct packet_type arp_mon_pt; | ||
| 201 | }; | 204 | }; |
| 202 | 205 | ||
| 203 | /** | 206 | /** |
| @@ -228,6 +231,25 @@ static inline struct bonding *bond_get_bond_by_slave(struct slave *slave) | |||
| 228 | return (struct bonding *)slave->dev->master->priv; | 231 | return (struct bonding *)slave->dev->master->priv; |
| 229 | } | 232 | } |
| 230 | 233 | ||
| 234 | #define BOND_ARP_VALIDATE_NONE 0 | ||
| 235 | #define BOND_ARP_VALIDATE_ACTIVE (1 << BOND_STATE_ACTIVE) | ||
| 236 | #define BOND_ARP_VALIDATE_BACKUP (1 << BOND_STATE_BACKUP) | ||
| 237 | #define BOND_ARP_VALIDATE_ALL (BOND_ARP_VALIDATE_ACTIVE | \ | ||
| 238 | BOND_ARP_VALIDATE_BACKUP) | ||
| 239 | |||
| 240 | extern inline int slave_do_arp_validate(struct bonding *bond, struct slave *slave) | ||
| 241 | { | ||
| 242 | return bond->params.arp_validate & (1 << slave->state); | ||
| 243 | } | ||
| 244 | |||
| 245 | extern inline u32 slave_last_rx(struct bonding *bond, struct slave *slave) | ||
| 246 | { | ||
| 247 | if (slave_do_arp_validate(bond, slave)) | ||
| 248 | return slave->last_arp_rx; | ||
| 249 | |||
| 250 | return slave->dev->last_rx; | ||
| 251 | } | ||
| 252 | |||
| 231 | static inline void bond_set_slave_inactive_flags(struct slave *slave) | 253 | static inline void bond_set_slave_inactive_flags(struct slave *slave) |
| 232 | { | 254 | { |
| 233 | struct bonding *bond = slave->dev->master->priv; | 255 | struct bonding *bond = slave->dev->master->priv; |
| @@ -235,12 +257,14 @@ static inline void bond_set_slave_inactive_flags(struct slave *slave) | |||
| 235 | bond->params.mode != BOND_MODE_ALB) | 257 | bond->params.mode != BOND_MODE_ALB) |
| 236 | slave->state = BOND_STATE_BACKUP; | 258 | slave->state = BOND_STATE_BACKUP; |
| 237 | slave->dev->priv_flags |= IFF_SLAVE_INACTIVE; | 259 | slave->dev->priv_flags |= IFF_SLAVE_INACTIVE; |
| 260 | if (slave_do_arp_validate(bond, slave)) | ||
| 261 | slave->dev->priv_flags |= IFF_SLAVE_NEEDARP; | ||
| 238 | } | 262 | } |
| 239 | 263 | ||
| 240 | static inline void bond_set_slave_active_flags(struct slave *slave) | 264 | static inline void bond_set_slave_active_flags(struct slave *slave) |
| 241 | { | 265 | { |
| 242 | slave->state = BOND_STATE_ACTIVE; | 266 | slave->state = BOND_STATE_ACTIVE; |
| 243 | slave->dev->priv_flags &= ~IFF_SLAVE_INACTIVE; | 267 | slave->dev->priv_flags &= ~(IFF_SLAVE_INACTIVE | IFF_SLAVE_NEEDARP); |
| 244 | } | 268 | } |
| 245 | 269 | ||
| 246 | static inline void bond_set_master_3ad_flags(struct bonding *bond) | 270 | static inline void bond_set_master_3ad_flags(struct bonding *bond) |
| @@ -284,6 +308,8 @@ int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl); | |||
| 284 | const char *bond_mode_name(int mode); | 308 | const char *bond_mode_name(int mode); |
| 285 | void bond_select_active_slave(struct bonding *bond); | 309 | void bond_select_active_slave(struct bonding *bond); |
| 286 | void bond_change_active_slave(struct bonding *bond, struct slave *new_active); | 310 | void bond_change_active_slave(struct bonding *bond, struct slave *new_active); |
| 311 | void bond_register_arp(struct bonding *); | ||
| 312 | void bond_unregister_arp(struct bonding *); | ||
| 287 | 313 | ||
| 288 | #endif /* _LINUX_BONDING_H */ | 314 | #endif /* _LINUX_BONDING_H */ |
| 289 | 315 | ||
