aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding/bond_main.c
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/net/bonding/bond_main.c
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/net/bonding/bond_main.c')
-rw-r--r--drivers/net/bonding/bond_main.c182
1 files changed, 176 insertions, 6 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;