diff options
author | Jeff Garzik <jeff@garzik.org> | 2006-09-27 18:16:47 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-09-27 18:16:47 -0400 |
commit | 3b9f6cb8a1ec791be79c6c7595fea922f12d1e64 (patch) | |
tree | 2393a448add846e6c2ed12f68106c3018b72c6a9 /drivers/net/bonding/bond_main.c | |
parent | c38778c3a9aeadcd1ee319cfc8ea5a9cbf8cdafa (diff) | |
parent | a77c64c1a641950626181b4857abb701d8f38ccc (diff) |
Merge branch 'master' into upstream
Diffstat (limited to 'drivers/net/bonding/bond_main.c')
-rw-r--r-- | drivers/net/bonding/bond_main.c | 228 |
1 files changed, 194 insertions, 34 deletions
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; |