aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/bonding/bond_main.c185
-rw-r--r--drivers/net/bonding/bond_sysfs.c36
-rw-r--r--drivers/net/bonding/bonding.h4
3 files changed, 165 insertions, 60 deletions
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 51e0f2de42c6..5b4af3cc2a44 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -100,7 +100,7 @@ static char *xmit_hash_policy = NULL;
100static int arp_interval = BOND_LINK_ARP_INTERV; 100static int arp_interval = BOND_LINK_ARP_INTERV;
101static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, }; 101static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, };
102static char *arp_validate = NULL; 102static char *arp_validate = NULL;
103static int fail_over_mac = 0; 103static char *fail_over_mac = NULL;
104struct bond_params bonding_defaults; 104struct bond_params bonding_defaults;
105 105
106module_param(max_bonds, int, 0); 106module_param(max_bonds, int, 0);
@@ -136,8 +136,8 @@ module_param_array(arp_ip_target, charp, NULL, 0);
136MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form"); 136MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form");
137module_param(arp_validate, charp, 0); 137module_param(arp_validate, charp, 0);
138MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes: none (default), active, backup or all"); 138MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes: none (default), active, backup or all");
139module_param(fail_over_mac, int, 0); 139module_param(fail_over_mac, charp, 0);
140MODULE_PARM_DESC(fail_over_mac, "For active-backup, do not set all slaves to the same MAC. 0 of off (default), 1 for on."); 140MODULE_PARM_DESC(fail_over_mac, "For active-backup, do not set all slaves to the same MAC. none (default), active or follow");
141 141
142/*----------------------------- Global variables ----------------------------*/ 142/*----------------------------- Global variables ----------------------------*/
143 143
@@ -190,6 +190,13 @@ struct bond_parm_tbl arp_validate_tbl[] = {
190{ NULL, -1}, 190{ NULL, -1},
191}; 191};
192 192
193struct bond_parm_tbl fail_over_mac_tbl[] = {
194{ "none", BOND_FOM_NONE},
195{ "active", BOND_FOM_ACTIVE},
196{ "follow", BOND_FOM_FOLLOW},
197{ NULL, -1},
198};
199
193/*-------------------------- Forward declarations ---------------------------*/ 200/*-------------------------- Forward declarations ---------------------------*/
194 201
195static void bond_send_gratuitous_arp(struct bonding *bond); 202static void bond_send_gratuitous_arp(struct bonding *bond);
@@ -973,6 +980,82 @@ static void bond_mc_swap(struct bonding *bond, struct slave *new_active, struct
973 } 980 }
974} 981}
975 982
983/*
984 * bond_do_fail_over_mac
985 *
986 * Perform special MAC address swapping for fail_over_mac settings
987 *
988 * Called with RTNL, bond->lock for read, curr_slave_lock for write_bh.
989 */
990static void bond_do_fail_over_mac(struct bonding *bond,
991 struct slave *new_active,
992 struct slave *old_active)
993{
994 u8 tmp_mac[ETH_ALEN];
995 struct sockaddr saddr;
996 int rv;
997
998 switch (bond->params.fail_over_mac) {
999 case BOND_FOM_ACTIVE:
1000 if (new_active)
1001 memcpy(bond->dev->dev_addr, new_active->dev->dev_addr,
1002 new_active->dev->addr_len);
1003 break;
1004 case BOND_FOM_FOLLOW:
1005 /*
1006 * if new_active && old_active, swap them
1007 * if just old_active, do nothing (going to no active slave)
1008 * if just new_active, set new_active to bond's MAC
1009 */
1010 if (!new_active)
1011 return;
1012
1013 write_unlock_bh(&bond->curr_slave_lock);
1014 read_unlock(&bond->lock);
1015
1016 if (old_active) {
1017 memcpy(tmp_mac, new_active->dev->dev_addr, ETH_ALEN);
1018 memcpy(saddr.sa_data, old_active->dev->dev_addr,
1019 ETH_ALEN);
1020 saddr.sa_family = new_active->dev->type;
1021 } else {
1022 memcpy(saddr.sa_data, bond->dev->dev_addr, ETH_ALEN);
1023 saddr.sa_family = bond->dev->type;
1024 }
1025
1026 rv = dev_set_mac_address(new_active->dev, &saddr);
1027 if (rv) {
1028 printk(KERN_ERR DRV_NAME
1029 ": %s: Error %d setting MAC of slave %s\n",
1030 bond->dev->name, -rv, new_active->dev->name);
1031 goto out;
1032 }
1033
1034 if (!old_active)
1035 goto out;
1036
1037 memcpy(saddr.sa_data, tmp_mac, ETH_ALEN);
1038 saddr.sa_family = old_active->dev->type;
1039
1040 rv = dev_set_mac_address(old_active->dev, &saddr);
1041 if (rv)
1042 printk(KERN_ERR DRV_NAME
1043 ": %s: Error %d setting MAC of slave %s\n",
1044 bond->dev->name, -rv, new_active->dev->name);
1045out:
1046 read_lock(&bond->lock);
1047 write_lock_bh(&bond->curr_slave_lock);
1048 break;
1049 default:
1050 printk(KERN_ERR DRV_NAME
1051 ": %s: bond_do_fail_over_mac impossible: bad policy %d\n",
1052 bond->dev->name, bond->params.fail_over_mac);
1053 break;
1054 }
1055
1056}
1057
1058
976/** 1059/**
977 * find_best_interface - select the best available slave to be the active one 1060 * find_best_interface - select the best available slave to be the active one
978 * @bond: our bonding struct 1061 * @bond: our bonding struct
@@ -1040,7 +1123,8 @@ static struct slave *bond_find_best_slave(struct bonding *bond)
1040 * because it is apparently the best available slave we have, even though its 1123 * because it is apparently the best available slave we have, even though its
1041 * updelay hasn't timed out yet. 1124 * updelay hasn't timed out yet.
1042 * 1125 *
1043 * Warning: Caller must hold curr_slave_lock for writing. 1126 * If new_active is not NULL, caller must hold bond->lock for read and
1127 * curr_slave_lock for write_bh.
1044 */ 1128 */
1045void bond_change_active_slave(struct bonding *bond, struct slave *new_active) 1129void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
1046{ 1130{
@@ -1107,12 +1191,9 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
1107 bond_set_slave_active_flags(new_active); 1191 bond_set_slave_active_flags(new_active);
1108 } 1192 }
1109 1193
1110 /* when bonding does not set the slave MAC address, the bond MAC
1111 * address is the one of the active slave.
1112 */
1113 if (new_active && bond->params.fail_over_mac) 1194 if (new_active && bond->params.fail_over_mac)
1114 memcpy(bond->dev->dev_addr, new_active->dev->dev_addr, 1195 bond_do_fail_over_mac(bond, new_active, old_active);
1115 new_active->dev->addr_len); 1196
1116 bond->send_grat_arp = bond->params.num_grat_arp; 1197 bond->send_grat_arp = bond->params.num_grat_arp;
1117 if (bond->curr_active_slave && 1198 if (bond->curr_active_slave &&
1118 test_bit(__LINK_STATE_LINKWATCH_PENDING, 1199 test_bit(__LINK_STATE_LINKWATCH_PENDING,
@@ -1137,7 +1218,7 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
1137 * - The primary_slave has got its link back. 1218 * - The primary_slave has got its link back.
1138 * - A slave has got its link back and there's no old curr_active_slave. 1219 * - A slave has got its link back and there's no old curr_active_slave.
1139 * 1220 *
1140 * Warning: Caller must hold curr_slave_lock for writing. 1221 * Caller must hold bond->lock for read and curr_slave_lock for write_bh.
1141 */ 1222 */
1142void bond_select_active_slave(struct bonding *bond) 1223void bond_select_active_slave(struct bonding *bond)
1143{ 1224{
@@ -1384,14 +1465,14 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1384 printk(KERN_WARNING DRV_NAME 1465 printk(KERN_WARNING DRV_NAME
1385 ": %s: Warning: The first slave device " 1466 ": %s: Warning: The first slave device "
1386 "specified does not support setting the MAC " 1467 "specified does not support setting the MAC "
1387 "address. Enabling the fail_over_mac option.", 1468 "address. Setting fail_over_mac to active.",
1388 bond_dev->name); 1469 bond_dev->name);
1389 bond->params.fail_over_mac = 1; 1470 bond->params.fail_over_mac = BOND_FOM_ACTIVE;
1390 } else if (!bond->params.fail_over_mac) { 1471 } else if (bond->params.fail_over_mac != BOND_FOM_ACTIVE) {
1391 printk(KERN_ERR DRV_NAME 1472 printk(KERN_ERR DRV_NAME
1392 ": %s: Error: The slave device specified " 1473 ": %s: Error: The slave device specified "
1393 "does not support setting the MAC address, " 1474 "does not support setting the MAC address, "
1394 "but fail_over_mac is not enabled.\n" 1475 "but fail_over_mac is not set to active.\n"
1395 , bond_dev->name); 1476 , bond_dev->name);
1396 res = -EOPNOTSUPP; 1477 res = -EOPNOTSUPP;
1397 goto err_undo_flags; 1478 goto err_undo_flags;
@@ -1498,6 +1579,10 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1498 1579
1499 bond_compute_features(bond); 1580 bond_compute_features(bond);
1500 1581
1582 write_unlock_bh(&bond->lock);
1583
1584 read_lock(&bond->lock);
1585
1501 new_slave->last_arp_rx = jiffies; 1586 new_slave->last_arp_rx = jiffies;
1502 1587
1503 if (bond->params.miimon && !bond->params.use_carrier) { 1588 if (bond->params.miimon && !bond->params.use_carrier) {
@@ -1574,6 +1659,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1574 } 1659 }
1575 } 1660 }
1576 1661
1662 write_lock_bh(&bond->curr_slave_lock);
1663
1577 switch (bond->params.mode) { 1664 switch (bond->params.mode) {
1578 case BOND_MODE_ACTIVEBACKUP: 1665 case BOND_MODE_ACTIVEBACKUP:
1579 bond_set_slave_inactive_flags(new_slave); 1666 bond_set_slave_inactive_flags(new_slave);
@@ -1621,9 +1708,11 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
1621 break; 1708 break;
1622 } /* switch(bond_mode) */ 1709 } /* switch(bond_mode) */
1623 1710
1711 write_unlock_bh(&bond->curr_slave_lock);
1712
1624 bond_set_carrier(bond); 1713 bond_set_carrier(bond);
1625 1714
1626 write_unlock_bh(&bond->lock); 1715 read_unlock(&bond->lock);
1627 1716
1628 res = bond_create_slave_symlinks(bond_dev, slave_dev); 1717 res = bond_create_slave_symlinks(bond_dev, slave_dev);
1629 if (res) 1718 if (res)
@@ -1647,6 +1736,10 @@ err_unset_master:
1647 1736
1648err_restore_mac: 1737err_restore_mac:
1649 if (!bond->params.fail_over_mac) { 1738 if (!bond->params.fail_over_mac) {
1739 /* XXX TODO - fom follow mode needs to change master's
1740 * MAC if this slave's MAC is in use by the bond, or at
1741 * least print a warning.
1742 */
1650 memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN); 1743 memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN);
1651 addr.sa_family = slave_dev->type; 1744 addr.sa_family = slave_dev->type;
1652 dev_set_mac_address(slave_dev, &addr); 1745 dev_set_mac_address(slave_dev, &addr);
@@ -1701,20 +1794,18 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
1701 return -EINVAL; 1794 return -EINVAL;
1702 } 1795 }
1703 1796
1704 mac_addr_differ = memcmp(bond_dev->dev_addr, 1797 if (!bond->params.fail_over_mac) {
1705 slave->perm_hwaddr, 1798 mac_addr_differ = memcmp(bond_dev->dev_addr, slave->perm_hwaddr,
1706 ETH_ALEN); 1799 ETH_ALEN);
1707 if (!mac_addr_differ && (bond->slave_cnt > 1)) { 1800 if (!mac_addr_differ && (bond->slave_cnt > 1))
1708 printk(KERN_WARNING DRV_NAME 1801 printk(KERN_WARNING DRV_NAME
1709 ": %s: Warning: the permanent HWaddr of %s - " 1802 ": %s: Warning: the permanent HWaddr of %s - "
1710 "%s - is still in use by %s. " 1803 "%s - is still in use by %s. "
1711 "Set the HWaddr of %s to a different address " 1804 "Set the HWaddr of %s to a different address "
1712 "to avoid conflicts.\n", 1805 "to avoid conflicts.\n",
1713 bond_dev->name, 1806 bond_dev->name, slave_dev->name,
1714 slave_dev->name, 1807 print_mac(mac, slave->perm_hwaddr),
1715 print_mac(mac, slave->perm_hwaddr), 1808 bond_dev->name, slave_dev->name);
1716 bond_dev->name,
1717 slave_dev->name);
1718 } 1809 }
1719 1810
1720 /* Inform AD package of unbinding of slave. */ 1811 /* Inform AD package of unbinding of slave. */
@@ -1841,7 +1932,7 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
1841 /* close slave before restoring its mac address */ 1932 /* close slave before restoring its mac address */
1842 dev_close(slave_dev); 1933 dev_close(slave_dev);
1843 1934
1844 if (!bond->params.fail_over_mac) { 1935 if (bond->params.fail_over_mac != BOND_FOM_ACTIVE) {
1845 /* restore original ("permanent") mac address */ 1936 /* restore original ("permanent") mac address */
1846 memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN); 1937 memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
1847 addr.sa_family = slave_dev->type; 1938 addr.sa_family = slave_dev->type;
@@ -3164,7 +3255,8 @@ static void bond_info_show_master(struct seq_file *seq)
3164 3255
3165 if (bond->params.mode == BOND_MODE_ACTIVEBACKUP && 3256 if (bond->params.mode == BOND_MODE_ACTIVEBACKUP &&
3166 bond->params.fail_over_mac) 3257 bond->params.fail_over_mac)
3167 seq_printf(seq, " (fail_over_mac)"); 3258 seq_printf(seq, " (fail_over_mac %s)",
3259 fail_over_mac_tbl[bond->params.fail_over_mac].modename);
3168 3260
3169 seq_printf(seq, "\n"); 3261 seq_printf(seq, "\n");
3170 3262
@@ -4092,10 +4184,10 @@ static int bond_set_mac_address(struct net_device *bond_dev, void *addr)
4092 dprintk("bond=%p, name=%s\n", bond, (bond_dev ? bond_dev->name : "None")); 4184 dprintk("bond=%p, name=%s\n", bond, (bond_dev ? bond_dev->name : "None"));
4093 4185
4094 /* 4186 /*
4095 * If fail_over_mac is enabled, do nothing and return success. 4187 * If fail_over_mac is set to active, do nothing and return
4096 * Returning an error causes ifenslave to fail. 4188 * success. Returning an error causes ifenslave to fail.
4097 */ 4189 */
4098 if (bond->params.fail_over_mac) 4190 if (bond->params.fail_over_mac == BOND_FOM_ACTIVE)
4099 return 0; 4191 return 0;
4100 4192
4101 if (!is_valid_ether_addr(sa->sa_data)) { 4193 if (!is_valid_ether_addr(sa->sa_data)) {
@@ -4600,7 +4692,7 @@ int bond_parse_parm(const char *buf, struct bond_parm_tbl *tbl)
4600 4692
4601static int bond_check_params(struct bond_params *params) 4693static int bond_check_params(struct bond_params *params)
4602{ 4694{
4603 int arp_validate_value; 4695 int arp_validate_value, fail_over_mac_value;
4604 4696
4605 /* 4697 /*
4606 * Convert string parameters. 4698 * Convert string parameters.
@@ -4875,10 +4967,23 @@ static int bond_check_params(struct bond_params *params)
4875 primary = NULL; 4967 primary = NULL;
4876 } 4968 }
4877 4969
4878 if (fail_over_mac && (bond_mode != BOND_MODE_ACTIVEBACKUP)) 4970 if (fail_over_mac) {
4879 printk(KERN_WARNING DRV_NAME 4971 fail_over_mac_value = bond_parse_parm(fail_over_mac,
4880 ": Warning: fail_over_mac only affects " 4972 fail_over_mac_tbl);
4881 "active-backup mode.\n"); 4973 if (fail_over_mac_value == -1) {
4974 printk(KERN_ERR DRV_NAME
4975 ": Error: invalid fail_over_mac \"%s\"\n",
4976 arp_validate == NULL ? "NULL" : arp_validate);
4977 return -EINVAL;
4978 }
4979
4980 if (bond_mode != BOND_MODE_ACTIVEBACKUP)
4981 printk(KERN_WARNING DRV_NAME
4982 ": Warning: fail_over_mac only affects "
4983 "active-backup mode.\n");
4984 } else {
4985 fail_over_mac_value = BOND_FOM_NONE;
4986 }
4882 4987
4883 /* fill params struct with the proper values */ 4988 /* fill params struct with the proper values */
4884 params->mode = bond_mode; 4989 params->mode = bond_mode;
@@ -4892,7 +4997,7 @@ static int bond_check_params(struct bond_params *params)
4892 params->use_carrier = use_carrier; 4997 params->use_carrier = use_carrier;
4893 params->lacp_fast = lacp_fast; 4998 params->lacp_fast = lacp_fast;
4894 params->primary[0] = 0; 4999 params->primary[0] = 0;
4895 params->fail_over_mac = fail_over_mac; 5000 params->fail_over_mac = fail_over_mac_value;
4896 5001
4897 if (primary) { 5002 if (primary) {
4898 strncpy(params->primary, primary, IFNAMSIZ); 5003 strncpy(params->primary, primary, IFNAMSIZ);
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 7a61e9a14386..dd265c69b0df 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -50,6 +50,7 @@ extern struct bond_parm_tbl bond_mode_tbl[];
50extern struct bond_parm_tbl bond_lacp_tbl[]; 50extern struct bond_parm_tbl bond_lacp_tbl[];
51extern struct bond_parm_tbl xmit_hashtype_tbl[]; 51extern struct bond_parm_tbl xmit_hashtype_tbl[];
52extern struct bond_parm_tbl arp_validate_tbl[]; 52extern struct bond_parm_tbl arp_validate_tbl[];
53extern struct bond_parm_tbl fail_over_mac_tbl[];
53 54
54static int expected_refcount = -1; 55static int expected_refcount = -1;
55static struct class *netdev_class; 56static struct class *netdev_class;
@@ -547,42 +548,37 @@ static ssize_t bonding_show_fail_over_mac(struct device *d, struct device_attrib
547{ 548{
548 struct bonding *bond = to_bond(d); 549 struct bonding *bond = to_bond(d);
549 550
550 return sprintf(buf, "%d\n", bond->params.fail_over_mac) + 1; 551 return sprintf(buf, "%s %d\n",
552 fail_over_mac_tbl[bond->params.fail_over_mac].modename,
553 bond->params.fail_over_mac);
551} 554}
552 555
553static ssize_t bonding_store_fail_over_mac(struct device *d, struct device_attribute *attr, const char *buf, size_t count) 556static ssize_t bonding_store_fail_over_mac(struct device *d, struct device_attribute *attr, const char *buf, size_t count)
554{ 557{
555 int new_value; 558 int new_value;
556 int ret = count;
557 struct bonding *bond = to_bond(d); 559 struct bonding *bond = to_bond(d);
558 560
559 if (bond->slave_cnt != 0) { 561 if (bond->slave_cnt != 0) {
560 printk(KERN_ERR DRV_NAME 562 printk(KERN_ERR DRV_NAME
561 ": %s: Can't alter fail_over_mac with slaves in bond.\n", 563 ": %s: Can't alter fail_over_mac with slaves in bond.\n",
562 bond->dev->name); 564 bond->dev->name);
563 ret = -EPERM; 565 return -EPERM;
564 goto out;
565 } 566 }
566 567
567 if (sscanf(buf, "%d", &new_value) != 1) { 568 new_value = bond_parse_parm(buf, fail_over_mac_tbl);
569 if (new_value < 0) {
568 printk(KERN_ERR DRV_NAME 570 printk(KERN_ERR DRV_NAME
569 ": %s: no fail_over_mac value specified.\n", 571 ": %s: Ignoring invalid fail_over_mac value %s.\n",
570 bond->dev->name); 572 bond->dev->name, buf);
571 ret = -EINVAL; 573 return -EINVAL;
572 goto out;
573 } 574 }
574 575
575 if ((new_value == 0) || (new_value == 1)) { 576 bond->params.fail_over_mac = new_value;
576 bond->params.fail_over_mac = new_value; 577 printk(KERN_INFO DRV_NAME ": %s: Setting fail_over_mac to %s (%d).\n",
577 printk(KERN_INFO DRV_NAME ": %s: Setting fail_over_mac to %d.\n", 578 bond->dev->name, fail_over_mac_tbl[new_value].modename,
578 bond->dev->name, new_value); 579 new_value);
579 } else { 580
580 printk(KERN_INFO DRV_NAME 581 return count;
581 ": %s: Ignoring invalid fail_over_mac value %d.\n",
582 bond->dev->name, new_value);
583 }
584out:
585 return ret;
586} 582}
587 583
588static DEVICE_ATTR(fail_over_mac, S_IRUGO | S_IWUSR, bonding_show_fail_over_mac, bonding_store_fail_over_mac); 584static DEVICE_ATTR(fail_over_mac, S_IRUGO | S_IWUSR, bonding_show_fail_over_mac, bonding_store_fail_over_mac);
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 8766b1213690..89fd9963db7a 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -248,6 +248,10 @@ static inline struct bonding *bond_get_bond_by_slave(struct slave *slave)
248 return (struct bonding *)slave->dev->master->priv; 248 return (struct bonding *)slave->dev->master->priv;
249} 249}
250 250
251#define BOND_FOM_NONE 0
252#define BOND_FOM_ACTIVE 1
253#define BOND_FOM_FOLLOW 2
254
251#define BOND_ARP_VALIDATE_NONE 0 255#define BOND_ARP_VALIDATE_NONE 0
252#define BOND_ARP_VALIDATE_ACTIVE (1 << BOND_STATE_ACTIVE) 256#define BOND_ARP_VALIDATE_ACTIVE (1 << BOND_STATE_ACTIVE)
253#define BOND_ARP_VALIDATE_BACKUP (1 << BOND_STATE_BACKUP) 257#define BOND_ARP_VALIDATE_BACKUP (1 << BOND_STATE_BACKUP)