diff options
-rw-r--r-- | Documentation/networking/bonding.txt | 8 | ||||
-rw-r--r-- | drivers/net/bonding/bond_main.c | 15 | ||||
-rw-r--r-- | drivers/net/bonding/bond_sysfs.c | 44 | ||||
-rw-r--r-- | drivers/net/bonding/bonding.h | 2 | ||||
-rw-r--r-- | include/linux/if_bonding.h | 3 |
5 files changed, 72 insertions, 0 deletions
diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt index d2b62b71b617..5dc638791d97 100644 --- a/Documentation/networking/bonding.txt +++ b/Documentation/networking/bonding.txt | |||
@@ -765,6 +765,14 @@ xmit_hash_policy | |||
765 | does not exist, and the layer2 policy is the only policy. The | 765 | does not exist, and the layer2 policy is the only policy. The |
766 | layer2+3 value was added for bonding version 3.2.2. | 766 | layer2+3 value was added for bonding version 3.2.2. |
767 | 767 | ||
768 | resend_igmp | ||
769 | |||
770 | Specifies the number of IGMP membership reports to be issued after | ||
771 | a failover event. One membership report is issued immediately after | ||
772 | the failover, subsequent packets are sent in each 200ms interval. | ||
773 | |||
774 | The valid range is 0 - 255; the default value is 1. This option | ||
775 | was added for bonding version 3.7.0. | ||
768 | 776 | ||
769 | 3. Configuring Bonding Devices | 777 | 3. Configuring Bonding Devices |
770 | ============================== | 778 | ============================== |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index ad6386671f28..6f5e6b453da6 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -109,6 +109,7 @@ static char *arp_validate; | |||
109 | static char *fail_over_mac; | 109 | static char *fail_over_mac; |
110 | static int all_slaves_active = 0; | 110 | static int all_slaves_active = 0; |
111 | static struct bond_params bonding_defaults; | 111 | static struct bond_params bonding_defaults; |
112 | static int resend_igmp = BOND_DEFAULT_RESEND_IGMP; | ||
112 | 113 | ||
113 | module_param(max_bonds, int, 0); | 114 | module_param(max_bonds, int, 0); |
114 | MODULE_PARM_DESC(max_bonds, "Max number of bonded devices"); | 115 | MODULE_PARM_DESC(max_bonds, "Max number of bonded devices"); |
@@ -163,6 +164,8 @@ module_param(all_slaves_active, int, 0); | |||
163 | MODULE_PARM_DESC(all_slaves_active, "Keep all frames received on an interface" | 164 | MODULE_PARM_DESC(all_slaves_active, "Keep all frames received on an interface" |
164 | "by setting active flag for all slaves. " | 165 | "by setting active flag for all slaves. " |
165 | "0 for never (default), 1 for always."); | 166 | "0 for never (default), 1 for always."); |
167 | module_param(resend_igmp, int, 0); | ||
168 | MODULE_PARM_DESC(resend_igmp, "Number of IGMP membership reports to send on link failure"); | ||
166 | 169 | ||
167 | /*----------------------------- Global variables ----------------------------*/ | 170 | /*----------------------------- Global variables ----------------------------*/ |
168 | 171 | ||
@@ -905,6 +908,9 @@ static void bond_resend_igmp_join_requests(struct bonding *bond) | |||
905 | } | 908 | } |
906 | } | 909 | } |
907 | 910 | ||
911 | if (--bond->igmp_retrans > 0) | ||
912 | queue_delayed_work(bond->wq, &bond->mcast_work, HZ/5); | ||
913 | |||
908 | read_unlock(&bond->lock); | 914 | read_unlock(&bond->lock); |
909 | } | 915 | } |
910 | 916 | ||
@@ -1213,6 +1219,7 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) | |||
1213 | * all were sent on curr_active_slave */ | 1219 | * all were sent on curr_active_slave */ |
1214 | if ((USES_PRIMARY(bond->params.mode) && new_active) || | 1220 | if ((USES_PRIMARY(bond->params.mode) && new_active) || |
1215 | bond->params.mode == BOND_MODE_ROUNDROBIN) { | 1221 | bond->params.mode == BOND_MODE_ROUNDROBIN) { |
1222 | bond->igmp_retrans = bond->params.resend_igmp; | ||
1216 | queue_delayed_work(bond->wq, &bond->mcast_work, 0); | 1223 | queue_delayed_work(bond->wq, &bond->mcast_work, 0); |
1217 | } | 1224 | } |
1218 | } | 1225 | } |
@@ -4933,6 +4940,13 @@ static int bond_check_params(struct bond_params *params) | |||
4933 | all_slaves_active = 0; | 4940 | all_slaves_active = 0; |
4934 | } | 4941 | } |
4935 | 4942 | ||
4943 | if (resend_igmp < 0 || resend_igmp > 255) { | ||
4944 | pr_warning("Warning: resend_igmp (%d) should be between " | ||
4945 | "0 and 255, resetting to %d\n", | ||
4946 | resend_igmp, BOND_DEFAULT_RESEND_IGMP); | ||
4947 | resend_igmp = BOND_DEFAULT_RESEND_IGMP; | ||
4948 | } | ||
4949 | |||
4936 | /* reset values for TLB/ALB */ | 4950 | /* reset values for TLB/ALB */ |
4937 | if ((bond_mode == BOND_MODE_TLB) || | 4951 | if ((bond_mode == BOND_MODE_TLB) || |
4938 | (bond_mode == BOND_MODE_ALB)) { | 4952 | (bond_mode == BOND_MODE_ALB)) { |
@@ -5105,6 +5119,7 @@ static int bond_check_params(struct bond_params *params) | |||
5105 | params->fail_over_mac = fail_over_mac_value; | 5119 | params->fail_over_mac = fail_over_mac_value; |
5106 | params->tx_queues = tx_queues; | 5120 | params->tx_queues = tx_queues; |
5107 | params->all_slaves_active = all_slaves_active; | 5121 | params->all_slaves_active = all_slaves_active; |
5122 | params->resend_igmp = resend_igmp; | ||
5108 | 5123 | ||
5109 | if (primary) { | 5124 | if (primary) { |
5110 | strncpy(params->primary, primary, IFNAMSIZ); | 5125 | strncpy(params->primary, primary, IFNAMSIZ); |
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index c311aed9bd02..01b4c3f5d9e7 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
@@ -1592,6 +1592,49 @@ out: | |||
1592 | static DEVICE_ATTR(all_slaves_active, S_IRUGO | S_IWUSR, | 1592 | static DEVICE_ATTR(all_slaves_active, S_IRUGO | S_IWUSR, |
1593 | bonding_show_slaves_active, bonding_store_slaves_active); | 1593 | bonding_show_slaves_active, bonding_store_slaves_active); |
1594 | 1594 | ||
1595 | /* | ||
1596 | * Show and set the number of IGMP membership reports to send on link failure | ||
1597 | */ | ||
1598 | static ssize_t bonding_show_resend_igmp(struct device *d, | ||
1599 | struct device_attribute *attr, | ||
1600 | char *buf) | ||
1601 | { | ||
1602 | struct bonding *bond = to_bond(d); | ||
1603 | |||
1604 | return sprintf(buf, "%d\n", bond->params.resend_igmp); | ||
1605 | } | ||
1606 | |||
1607 | static ssize_t bonding_store_resend_igmp(struct device *d, | ||
1608 | struct device_attribute *attr, | ||
1609 | const char *buf, size_t count) | ||
1610 | { | ||
1611 | int new_value, ret = count; | ||
1612 | struct bonding *bond = to_bond(d); | ||
1613 | |||
1614 | if (sscanf(buf, "%d", &new_value) != 1) { | ||
1615 | pr_err("%s: no resend_igmp value specified.\n", | ||
1616 | bond->dev->name); | ||
1617 | ret = -EINVAL; | ||
1618 | goto out; | ||
1619 | } | ||
1620 | |||
1621 | if (new_value < 0) { | ||
1622 | pr_err("%s: Invalid resend_igmp value %d not in range 0-255; rejected.\n", | ||
1623 | bond->dev->name, new_value); | ||
1624 | ret = -EINVAL; | ||
1625 | goto out; | ||
1626 | } | ||
1627 | |||
1628 | pr_info("%s: Setting resend_igmp to %d.\n", | ||
1629 | bond->dev->name, new_value); | ||
1630 | bond->params.resend_igmp = new_value; | ||
1631 | out: | ||
1632 | return ret; | ||
1633 | } | ||
1634 | |||
1635 | static DEVICE_ATTR(resend_igmp, S_IRUGO | S_IWUSR, | ||
1636 | bonding_show_resend_igmp, bonding_store_resend_igmp); | ||
1637 | |||
1595 | static struct attribute *per_bond_attrs[] = { | 1638 | static struct attribute *per_bond_attrs[] = { |
1596 | &dev_attr_slaves.attr, | 1639 | &dev_attr_slaves.attr, |
1597 | &dev_attr_mode.attr, | 1640 | &dev_attr_mode.attr, |
@@ -1619,6 +1662,7 @@ static struct attribute *per_bond_attrs[] = { | |||
1619 | &dev_attr_ad_partner_mac.attr, | 1662 | &dev_attr_ad_partner_mac.attr, |
1620 | &dev_attr_queue_id.attr, | 1663 | &dev_attr_queue_id.attr, |
1621 | &dev_attr_all_slaves_active.attr, | 1664 | &dev_attr_all_slaves_active.attr, |
1665 | &dev_attr_resend_igmp.attr, | ||
1622 | NULL, | 1666 | NULL, |
1623 | }; | 1667 | }; |
1624 | 1668 | ||
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 308ed10dca90..c15f21347486 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
@@ -136,6 +136,7 @@ struct bond_params { | |||
136 | __be32 arp_targets[BOND_MAX_ARP_TARGETS]; | 136 | __be32 arp_targets[BOND_MAX_ARP_TARGETS]; |
137 | int tx_queues; | 137 | int tx_queues; |
138 | int all_slaves_active; | 138 | int all_slaves_active; |
139 | int resend_igmp; | ||
139 | }; | 140 | }; |
140 | 141 | ||
141 | struct bond_parm_tbl { | 142 | struct bond_parm_tbl { |
@@ -202,6 +203,7 @@ struct bonding { | |||
202 | s8 send_grat_arp; | 203 | s8 send_grat_arp; |
203 | s8 send_unsol_na; | 204 | s8 send_unsol_na; |
204 | s8 setup_by_slave; | 205 | s8 setup_by_slave; |
206 | s8 igmp_retrans; | ||
205 | #ifdef CONFIG_PROC_FS | 207 | #ifdef CONFIG_PROC_FS |
206 | struct proc_dir_entry *proc_entry; | 208 | struct proc_dir_entry *proc_entry; |
207 | char proc_file_name[IFNAMSIZ]; | 209 | char proc_file_name[IFNAMSIZ]; |
diff --git a/include/linux/if_bonding.h b/include/linux/if_bonding.h index 2c7994372bde..a17edda8a781 100644 --- a/include/linux/if_bonding.h +++ b/include/linux/if_bonding.h | |||
@@ -84,6 +84,9 @@ | |||
84 | #define BOND_DEFAULT_MAX_BONDS 1 /* Default maximum number of devices to support */ | 84 | #define BOND_DEFAULT_MAX_BONDS 1 /* Default maximum number of devices to support */ |
85 | 85 | ||
86 | #define BOND_DEFAULT_TX_QUEUES 16 /* Default number of tx queues per device */ | 86 | #define BOND_DEFAULT_TX_QUEUES 16 /* Default number of tx queues per device */ |
87 | |||
88 | #define BOND_DEFAULT_RESEND_IGMP 1 /* Default number of IGMP membership reports */ | ||
89 | |||
87 | /* hashing types */ | 90 | /* hashing types */ |
88 | #define BOND_XMIT_POLICY_LAYER2 0 /* layer 2 (MAC only), default */ | 91 | #define BOND_XMIT_POLICY_LAYER2 0 /* layer 2 (MAC only), default */ |
89 | #define BOND_XMIT_POLICY_LAYER34 1 /* layer 3+4 (IP ^ (TCP || UDP)) */ | 92 | #define BOND_XMIT_POLICY_LAYER34 1 /* layer 3+4 (IP ^ (TCP || UDP)) */ |