aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJay Vosburgh <fubar@us.ibm.com>2006-09-23 00:54:53 -0400
committerJeff Garzik <jeff@garzik.org>2006-09-25 20:08:09 -0400
commitf5b2b966f032f22d3a289045a5afd4afa09f09c6 (patch)
treecb3c505d8f444438bed09353788f6c96150f68ad /drivers
parent70298705bb29fb7982b85089adf17cd37b94baa7 (diff)
[PATCH] bonding: Validate probe replies in ARP monitor
Add logic to check ARP request / reply packets used for ARP monitor link integrity checking. The current method simply examines the slave device to see if it has sent and received traffic; this can be fooled by extraneous traffic. For example, if multiple hosts running bonding are behind a common switch, the probe traffic from the multiple instances of bonding will update the tx/rx times on each other's slave devices. Signed-off-by: Jay Vosburgh <fubar@us.ibm.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/bonding/bond_main.c182
-rw-r--r--drivers/net/bonding/bond_sysfs.c54
-rw-r--r--drivers/net/bonding/bonding.h32
3 files changed, 259 insertions, 9 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index bafe62f7c9b7..fd521b05db83 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -96,6 +96,7 @@ static char *lacp_rate = NULL;
96static char *xmit_hash_policy = NULL; 96static char *xmit_hash_policy = NULL;
97static int arp_interval = BOND_LINK_ARP_INTERV; 97static int arp_interval = BOND_LINK_ARP_INTERV;
98static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, }; 98static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, };
99static char *arp_validate = NULL;
99struct bond_params bonding_defaults; 100struct bond_params bonding_defaults;
100 101
101module_param(max_bonds, int, 0); 102module_param(max_bonds, int, 0);
@@ -127,6 +128,8 @@ module_param(arp_interval, int, 0);
127MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds"); 128MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds");
128module_param_array(arp_ip_target, charp, NULL, 0); 129module_param_array(arp_ip_target, charp, NULL, 0);
129MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form"); 130MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form");
131module_param(arp_validate, charp, 0);
132MODULE_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
176struct 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
175static void bond_send_gratuitous_arp(struct bonding *bond); 186static void bond_send_gratuitous_arp(struct bonding *bond);
@@ -1424,6 +1435,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1424 1435
1425 bond_compute_features(bond); 1436 bond_compute_features(bond);
1426 1437
1438 new_slave->last_arp_rx = jiffies;
1439
1427 if (bond->params.miimon && !bond->params.use_carrier) { 1440 if (bond->params.miimon && !bond->params.use_carrier) {
1428 link_reporting = bond_check_dev_link(bond, slave_dev, 1); 1441 link_reporting = bond_check_dev_link(bond, slave_dev, 1);
1429 1442
@@ -1785,7 +1798,8 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
1785 dev_set_mac_address(slave_dev, &addr); 1798 dev_set_mac_address(slave_dev, &addr);
1786 1799
1787 slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB | 1800 slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB |
1788 IFF_SLAVE_INACTIVE | IFF_BONDING); 1801 IFF_SLAVE_INACTIVE | IFF_BONDING |
1802 IFF_SLAVE_NEEDARP);
1789 1803
1790 kfree(slave); 1804 kfree(slave);
1791 1805
@@ -2298,6 +2312,25 @@ static int bond_has_ip(struct bonding *bond)
2298 return 0; 2312 return 0;
2299} 2313}
2300 2314
2315static int bond_has_this_ip(struct bonding *bond, u32 ip)
2316{
2317 struct vlan_entry *vlan, *vlan_next;
2318
2319 if (ip == bond->master_ip)
2320 return 1;
2321
2322 if (list_empty(&bond->vlan_list))
2323 return 0;
2324
2325 list_for_each_entry_safe(vlan, vlan_next, &bond->vlan_list,
2326 vlan_list) {
2327 if (ip == vlan->vlan_ip)
2328 return 1;
2329 }
2330
2331 return 0;
2332}
2333
2301/* 2334/*
2302 * We go to the (large) trouble of VLAN tagging ARP frames because 2335 * We go to the (large) trouble of VLAN tagging ARP frames because
2303 * switches in VLAN mode (especially if ports are configured as 2336 * switches in VLAN mode (especially if ports are configured as
@@ -2436,6 +2469,93 @@ static void bond_send_gratuitous_arp(struct bonding *bond)
2436 } 2469 }
2437} 2470}
2438 2471
2472static void bond_validate_arp(struct bonding *bond, struct slave *slave, u32 sip, u32 tip)
2473{
2474 int i;
2475 u32 *targets = bond->params.arp_targets;
2476
2477 targets = bond->params.arp_targets;
2478 for (i = 0; (i < BOND_MAX_ARP_TARGETS) && targets[i]; i++) {
2479 dprintk("bva: sip %u.%u.%u.%u tip %u.%u.%u.%u t[%d] "
2480 "%u.%u.%u.%u bhti(tip) %d\n",
2481 NIPQUAD(sip), NIPQUAD(tip), i, NIPQUAD(targets[i]),
2482 bond_has_this_ip(bond, tip));
2483 if (sip == targets[i]) {
2484 if (bond_has_this_ip(bond, tip))
2485 slave->last_arp_rx = jiffies;
2486 return;
2487 }
2488 }
2489}
2490
2491static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
2492{
2493 struct arphdr *arp;
2494 struct slave *slave;
2495 struct bonding *bond;
2496 unsigned char *arp_ptr;
2497 u32 sip, tip;
2498
2499 if (!(dev->priv_flags & IFF_BONDING) || !(dev->flags & IFF_MASTER))
2500 goto out;
2501
2502 bond = dev->priv;
2503 read_lock(&bond->lock);
2504
2505 dprintk("bond_arp_rcv: bond %s skb->dev %s orig_dev %s\n",
2506 bond->dev->name, skb->dev ? skb->dev->name : "NULL",
2507 orig_dev ? orig_dev->name : "NULL");
2508
2509 slave = bond_get_slave_by_dev(bond, orig_dev);
2510 if (!slave || !slave_do_arp_validate(bond, slave))
2511 goto out_unlock;
2512
2513 /* ARP header, plus 2 device addresses, plus 2 IP addresses. */
2514 if (!pskb_may_pull(skb, (sizeof(struct arphdr) +
2515 (2 * dev->addr_len) +
2516 (2 * sizeof(u32)))))
2517 goto out_unlock;
2518
2519 arp = skb->nh.arph;
2520 if (arp->ar_hln != dev->addr_len ||
2521 skb->pkt_type == PACKET_OTHERHOST ||
2522 skb->pkt_type == PACKET_LOOPBACK ||
2523 arp->ar_hrd != htons(ARPHRD_ETHER) ||
2524 arp->ar_pro != htons(ETH_P_IP) ||
2525 arp->ar_pln != 4)
2526 goto out_unlock;
2527
2528 arp_ptr = (unsigned char *)(arp + 1);
2529 arp_ptr += dev->addr_len;
2530 memcpy(&sip, arp_ptr, 4);
2531 arp_ptr += 4 + dev->addr_len;
2532 memcpy(&tip, arp_ptr, 4);
2533
2534 dprintk("bond_arp_rcv: %s %s/%d av %d sv %d sip %u.%u.%u.%u"
2535 " tip %u.%u.%u.%u\n", bond->dev->name, slave->dev->name,
2536 slave->state, bond->params.arp_validate,
2537 slave_do_arp_validate(bond, slave), NIPQUAD(sip), NIPQUAD(tip));
2538
2539 /*
2540 * Backup slaves won't see the ARP reply, but do come through
2541 * here for each ARP probe (so we swap the sip/tip to validate
2542 * the probe). In a "redundant switch, common router" type of
2543 * configuration, the ARP probe will (hopefully) travel from
2544 * the active, through one switch, the router, then the other
2545 * switch before reaching the backup.
2546 */
2547 if (slave->state == BOND_STATE_ACTIVE)
2548 bond_validate_arp(bond, slave, sip, tip);
2549 else
2550 bond_validate_arp(bond, slave, tip, sip);
2551
2552out_unlock:
2553 read_unlock(&bond->lock);
2554out:
2555 dev_kfree_skb(skb);
2556 return NET_RX_SUCCESS;
2557}
2558
2439/* 2559/*
2440 * this function is called regularly to monitor each slave's link 2560 * this function is called regularly to monitor each slave's link
2441 * ensuring that traffic is being sent and received when arp monitoring 2561 * ensuring that traffic is being sent and received when arp monitoring
@@ -2600,7 +2720,8 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev)
2600 */ 2720 */
2601 bond_for_each_slave(bond, slave, i) { 2721 bond_for_each_slave(bond, slave, i) {
2602 if (slave->link != BOND_LINK_UP) { 2722 if (slave->link != BOND_LINK_UP) {
2603 if ((jiffies - slave->dev->last_rx) <= delta_in_ticks) { 2723 if ((jiffies - slave_last_rx(bond, slave)) <=
2724 delta_in_ticks) {
2604 2725
2605 slave->link = BOND_LINK_UP; 2726 slave->link = BOND_LINK_UP;
2606 2727
@@ -2645,7 +2766,7 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev)
2645 2766
2646 if ((slave != bond->curr_active_slave) && 2767 if ((slave != bond->curr_active_slave) &&
2647 (!bond->current_arp_slave) && 2768 (!bond->current_arp_slave) &&
2648 (((jiffies - slave->dev->last_rx) >= 3*delta_in_ticks) && 2769 (((jiffies - slave_last_rx(bond, slave)) >= 3*delta_in_ticks) &&
2649 bond_has_ip(bond))) { 2770 bond_has_ip(bond))) {
2650 /* a backup slave has gone down; three times 2771 /* a backup slave has gone down; three times
2651 * the delta allows the current slave to be 2772 * the delta allows the current slave to be
@@ -2692,7 +2813,7 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev)
2692 * if it is up and needs to take over as the curr_active_slave 2813 * if it is up and needs to take over as the curr_active_slave
2693 */ 2814 */
2694 if ((((jiffies - slave->dev->trans_start) >= (2*delta_in_ticks)) || 2815 if ((((jiffies - slave->dev->trans_start) >= (2*delta_in_ticks)) ||
2695 (((jiffies - slave->dev->last_rx) >= (2*delta_in_ticks)) && 2816 (((jiffies - slave_last_rx(bond, slave)) >= (2*delta_in_ticks)) &&
2696 bond_has_ip(bond))) && 2817 bond_has_ip(bond))) &&
2697 ((jiffies - slave->jiffies) >= 2*delta_in_ticks)) { 2818 ((jiffies - slave->jiffies) >= 2*delta_in_ticks)) {
2698 2819
@@ -3315,6 +3436,21 @@ static void bond_unregister_lacpdu(struct bonding *bond)
3315 dev_remove_pack(&(BOND_AD_INFO(bond).ad_pkt_type)); 3436 dev_remove_pack(&(BOND_AD_INFO(bond).ad_pkt_type));
3316} 3437}
3317 3438
3439void bond_register_arp(struct bonding *bond)
3440{
3441 struct packet_type *pt = &bond->arp_mon_pt;
3442
3443 pt->type = htons(ETH_P_ARP);
3444 pt->dev = NULL; /*bond->dev;XXX*/
3445 pt->func = bond_arp_rcv;
3446 dev_add_pack(pt);
3447}
3448
3449void bond_unregister_arp(struct bonding *bond)
3450{
3451 dev_remove_pack(&bond->arp_mon_pt);
3452}
3453
3318/*---------------------------- Hashing Policies -----------------------------*/ 3454/*---------------------------- Hashing Policies -----------------------------*/
3319 3455
3320/* 3456/*
@@ -3401,6 +3537,9 @@ static int bond_open(struct net_device *bond_dev)
3401 } else { 3537 } else {
3402 arp_timer->function = (void *)&bond_loadbalance_arp_mon; 3538 arp_timer->function = (void *)&bond_loadbalance_arp_mon;
3403 } 3539 }
3540 if (bond->params.arp_validate)
3541 bond_register_arp(bond);
3542
3404 add_timer(arp_timer); 3543 add_timer(arp_timer);
3405 } 3544 }
3406 3545
@@ -3428,6 +3567,9 @@ static int bond_close(struct net_device *bond_dev)
3428 bond_unregister_lacpdu(bond); 3567 bond_unregister_lacpdu(bond);
3429 } 3568 }
3430 3569
3570 if (bond->params.arp_validate)
3571 bond_unregister_arp(bond);
3572
3431 write_lock_bh(&bond->lock); 3573 write_lock_bh(&bond->lock);
3432 3574
3433 3575
@@ -4281,6 +4423,8 @@ int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl)
4281 4423
4282static int bond_check_params(struct bond_params *params) 4424static int bond_check_params(struct bond_params *params)
4283{ 4425{
4426 int arp_validate_value;
4427
4284 /* 4428 /*
4285 * Convert string parameters. 4429 * Convert string parameters.
4286 */ 4430 */
@@ -4484,6 +4628,29 @@ static int bond_check_params(struct bond_params *params)
4484 arp_interval = 0; 4628 arp_interval = 0;
4485 } 4629 }
4486 4630
4631 if (arp_validate) {
4632 if (bond_mode != BOND_MODE_ACTIVEBACKUP) {
4633 printk(KERN_ERR DRV_NAME
4634 ": arp_validate only supported in active-backup mode\n");
4635 return -EINVAL;
4636 }
4637 if (!arp_interval) {
4638 printk(KERN_ERR DRV_NAME
4639 ": arp_validate requires arp_interval\n");
4640 return -EINVAL;
4641 }
4642
4643 arp_validate_value = bond_parse_parm(arp_validate,
4644 arp_validate_tbl);
4645 if (arp_validate_value == -1) {
4646 printk(KERN_ERR DRV_NAME
4647 ": Error: invalid arp_validate \"%s\"\n",
4648 arp_validate == NULL ? "NULL" : arp_validate);
4649 return -EINVAL;
4650 }
4651 } else
4652 arp_validate_value = 0;
4653
4487 if (miimon) { 4654 if (miimon) {
4488 printk(KERN_INFO DRV_NAME 4655 printk(KERN_INFO DRV_NAME
4489 ": MII link monitoring set to %d ms\n", 4656 ": MII link monitoring set to %d ms\n",
@@ -4492,8 +4659,10 @@ static int bond_check_params(struct bond_params *params)
4492 int i; 4659 int i;
4493 4660
4494 printk(KERN_INFO DRV_NAME 4661 printk(KERN_INFO DRV_NAME
4495 ": ARP monitoring set to %d ms with %d target(s):", 4662 ": ARP monitoring set to %d ms, validate %s, with %d target(s):",
4496 arp_interval, arp_ip_count); 4663 arp_interval,
4664 arp_validate_tbl[arp_validate_value].modename,
4665 arp_ip_count);
4497 4666
4498 for (i = 0; i < arp_ip_count; i++) 4667 for (i = 0; i < arp_ip_count; i++)
4499 printk (" %s", arp_ip_target[i]); 4668 printk (" %s", arp_ip_target[i]);
@@ -4527,6 +4696,7 @@ static int bond_check_params(struct bond_params *params)
4527 params->xmit_policy = xmit_hashtype; 4696 params->xmit_policy = xmit_hashtype;
4528 params->miimon = miimon; 4697 params->miimon = miimon;
4529 params->arp_interval = arp_interval; 4698 params->arp_interval = arp_interval;
4699 params->arp_validate = arp_validate_value;
4530 params->updelay = updelay; 4700 params->updelay = updelay;
4531 params->downdelay = downdelay; 4701 params->downdelay = downdelay;
4532 params->use_carrier = use_carrier; 4702 params->use_carrier = use_carrier;
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 15b6a29bb4d4..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;
51extern struct bond_parm_tbl bond_mode_tbl[]; 51extern struct bond_parm_tbl bond_mode_tbl[];
52extern struct bond_parm_tbl bond_lacp_tbl[]; 52extern struct bond_parm_tbl bond_lacp_tbl[];
53extern struct bond_parm_tbl xmit_hashtype_tbl[]; 53extern struct bond_parm_tbl xmit_hashtype_tbl[];
54extern struct bond_parm_tbl arp_validate_tbl[];
54 55
55static int expected_refcount = -1; 56static int expected_refcount = -1;
56static struct class *netdev_class; 57static struct class *netdev_class;
@@ -503,6 +504,53 @@ out:
503static CLASS_DEVICE_ATTR(xmit_hash_policy, S_IRUGO | S_IWUSR, bonding_show_xmit_hash, bonding_store_xmit_hash); 504static 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 */
509static 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
518static 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
551static 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
@@ -1273,6 +1326,7 @@ static CLASS_DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, N
1273static struct attribute *per_bond_attrs[] = { 1326static 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 17caafe58247..db16fee40a5f 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.0-test"
26#define DRV_RELDATE "March 23, 2006" 26#define DRV_RELDATE "September 9, 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;
@@ -151,6 +152,7 @@ struct slave {
151 struct slave *prev; 152 struct slave *prev;
152 int 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
240extern inline int slave_do_arp_validate(struct bonding *bond, struct slave *slave)
241{
242 return bond->params.arp_validate & (1 << slave->state);
243}
244
245extern 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
231static inline void bond_set_slave_inactive_flags(struct slave *slave) 253static 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
240static inline void bond_set_slave_active_flags(struct slave *slave) 264static 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
246static inline void bond_set_master_3ad_flags(struct bonding *bond) 270static 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);
284const char *bond_mode_name(int mode); 308const char *bond_mode_name(int mode);
285void bond_select_active_slave(struct bonding *bond); 309void bond_select_active_slave(struct bonding *bond);
286void bond_change_active_slave(struct bonding *bond, struct slave *new_active); 310void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
311void bond_register_arp(struct bonding *);
312void bond_unregister_arp(struct bonding *);
287 313
288#endif /* _LINUX_BONDING_H */ 314#endif /* _LINUX_BONDING_H */
289 315