aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bonding/bonding.h
diff options
context:
space:
mode:
authorVeaceslav Falico <vfalico@redhat.com>2013-06-24 05:49:34 -0400
committerDavid S. Miller <davem@davemloft.net>2013-06-25 19:58:38 -0400
commit8599b52e14a1611dcb563289421bee76751f1d53 (patch)
tree0eddf2fc812131c8fc9f00451ef6ec24ae0f06d1 /drivers/net/bonding/bonding.h
parentd7d35c681fb4eae1fab3d93698e26a106ca7e79e (diff)
bonding: add an option to fail when any of arp_ip_target is inaccessible
Currently, we fail only when all of the ips in arp_ip_target are gone. However, in some situations we might need to fail if even one host from arp_ip_target becomes unavailable. All situations, obviously, rely on the idea that we need *completely* functional network, with all interfaces/addresses working correctly. One real world example might be: vlans on top on bond (hybrid port). If bond and vlans have ips assigned and we have their peers monitored via arp_ip_target - in case of switch misconfiguration (trunk/access port), slave driver malfunction or tagged/untagged traffic dropped on the way - we will be able to switch to another slave. Though any other configuration needs that if we need to have access to all arp_ip_targets. This patch adds this possibility by adding a new parameter - arp_all_targets (both as a module parameter and as a sysfs knob). It can be set to: 0 or any (the default) - which works exactly as it's working now - the slave is up if any of the arp_ip_targets are up. 1 or all - the slave is up if all of the arp_ip_targets are up. This parameter can be changed on the fly (via sysfs), and requires the mode to be active-backup and arp_validate to be enabled (it obeys the arp_validate config on which slaves to validate). Internally it's done through: 1) Add target_last_arp_rx[BOND_MAX_ARP_TARGETS] array to slave struct. It's an array of jiffies, meaning that slave->target_last_arp_rx[i] is the last time we've received arp from bond->params.arp_targets[i] on this slave. 2) If we successfully validate an arp from bond->params.arp_targets[i] in bond_validate_arp() - update the slave->target_last_arp_rx[i] with the current jiffies value. 3) When getting slave's last_rx via slave_last_rx(), we return the oldest time when we've received an arp from any address in bond->params.arp_targets[]. If the value of arp_all_targets == 0 - we still work the same way as before. Also, update the documentation to reflect the new parameter. v3->v4: Kill the forgotten rtnl_unlock(), rephrase the documentation part to be more clear, don't fail setting arp_all_targets if arp_validate is not set - it has no effect anyway but can be easier to set up. Also, print a warning if the last arp_ip_target is removed while the arp_interval is on, but not the arp_validate. v2->v3: Use _bh spinlock, remove useless rtnl_lock() and use jiffies for new arp_ip_target last arp, instead of slave_last_rx(). On bond_enslave(), use the same initialization value for target_last_arp_rx[] as is used for the default last_arp_rx, to avoid useless interface flaps. Also, instead of failing to remove the last arp_ip_target just print a warning - otherwise it might break existing scripts. v1->v2: Correctly handle adding/removing hosts in arp_ip_target - we need to shift/initialize all slave's target_last_arp_rx. Also, don't fail module loading on arp_all_targets misconfiguration, just disable it, and some minor style fixes. Signed-off-by: Veaceslav Falico <vfalico@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bonding/bonding.h')
-rw-r--r--drivers/net/bonding/bonding.h30
1 files changed, 28 insertions, 2 deletions
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 486e532f77e4..3fb73cc8c34a 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -144,6 +144,7 @@ struct bond_params {
144 u8 num_peer_notif; 144 u8 num_peer_notif;
145 int arp_interval; 145 int arp_interval;
146 int arp_validate; 146 int arp_validate;
147 int arp_all_targets;
147 int use_carrier; 148 int use_carrier;
148 int fail_over_mac; 149 int fail_over_mac;
149 int updelay; 150 int updelay;
@@ -179,6 +180,7 @@ struct slave {
179 int delay; 180 int delay;
180 unsigned long jiffies; 181 unsigned long jiffies;
181 unsigned long last_arp_rx; 182 unsigned long last_arp_rx;
183 unsigned long target_last_arp_rx[BOND_MAX_ARP_TARGETS];
182 s8 link; /* one of BOND_LINK_XXXX */ 184 s8 link; /* one of BOND_LINK_XXXX */
183 s8 new_link; 185 s8 new_link;
184 u8 backup:1, /* indicates backup slave. Value corresponds with 186 u8 backup:1, /* indicates backup slave. Value corresponds with
@@ -322,6 +324,9 @@ static inline bool bond_is_active_slave(struct slave *slave)
322#define BOND_FOM_ACTIVE 1 324#define BOND_FOM_ACTIVE 1
323#define BOND_FOM_FOLLOW 2 325#define BOND_FOM_FOLLOW 2
324 326
327#define BOND_ARP_TARGETS_ANY 0
328#define BOND_ARP_TARGETS_ALL 1
329
325#define BOND_ARP_VALIDATE_NONE 0 330#define BOND_ARP_VALIDATE_NONE 0
326#define BOND_ARP_VALIDATE_ACTIVE (1 << BOND_STATE_ACTIVE) 331#define BOND_ARP_VALIDATE_ACTIVE (1 << BOND_STATE_ACTIVE)
327#define BOND_ARP_VALIDATE_BACKUP (1 << BOND_STATE_BACKUP) 332#define BOND_ARP_VALIDATE_BACKUP (1 << BOND_STATE_BACKUP)
@@ -334,11 +339,31 @@ static inline int slave_do_arp_validate(struct bonding *bond,
334 return bond->params.arp_validate & (1 << bond_slave_state(slave)); 339 return bond->params.arp_validate & (1 << bond_slave_state(slave));
335} 340}
336 341
342/* Get the oldest arp which we've received on this slave for bond's
343 * arp_targets.
344 */
345static inline unsigned long slave_oldest_target_arp_rx(struct bonding *bond,
346 struct slave *slave)
347{
348 int i = 1;
349 unsigned long ret = slave->target_last_arp_rx[0];
350
351 for (; (i < BOND_MAX_ARP_TARGETS) && bond->params.arp_targets[i]; i++)
352 if (time_before(slave->target_last_arp_rx[i], ret))
353 ret = slave->target_last_arp_rx[i];
354
355 return ret;
356}
357
337static inline unsigned long slave_last_rx(struct bonding *bond, 358static inline unsigned long slave_last_rx(struct bonding *bond,
338 struct slave *slave) 359 struct slave *slave)
339{ 360{
340 if (slave_do_arp_validate(bond, slave)) 361 if (slave_do_arp_validate(bond, slave)) {
341 return slave->last_arp_rx; 362 if (bond->params.arp_all_targets == BOND_ARP_TARGETS_ALL)
363 return slave_oldest_target_arp_rx(bond, slave);
364 else
365 return slave->last_arp_rx;
366 }
342 367
343 return slave->dev->last_rx; 368 return slave->dev->last_rx;
344} 369}
@@ -486,6 +511,7 @@ extern const struct bond_parm_tbl bond_lacp_tbl[];
486extern const struct bond_parm_tbl bond_mode_tbl[]; 511extern const struct bond_parm_tbl bond_mode_tbl[];
487extern const struct bond_parm_tbl xmit_hashtype_tbl[]; 512extern const struct bond_parm_tbl xmit_hashtype_tbl[];
488extern const struct bond_parm_tbl arp_validate_tbl[]; 513extern const struct bond_parm_tbl arp_validate_tbl[];
514extern const struct bond_parm_tbl arp_all_targets_tbl[];
489extern const struct bond_parm_tbl fail_over_mac_tbl[]; 515extern const struct bond_parm_tbl fail_over_mac_tbl[];
490extern const struct bond_parm_tbl pri_reselect_tbl[]; 516extern const struct bond_parm_tbl pri_reselect_tbl[];
491extern struct bond_parm_tbl ad_select_tbl[]; 517extern struct bond_parm_tbl ad_select_tbl[];