|
@@ -214,6 +214,8 @@ static void bond_uninit(struct net_device *bond_dev);
|
|
|
static struct rtnl_link_stats64 *bond_get_stats(struct net_device *bond_dev,
|
|
|
struct rtnl_link_stats64 *stats);
|
|
|
static void bond_slave_arr_handler(struct work_struct *work);
|
|
|
+static bool bond_time_in_interval(struct bonding *bond, unsigned long last_act,
|
|
|
+ int mod);
|
|
|
|
|
|
/*---------------------------- General routines -----------------------------*/
|
|
|
|
|
@@ -2459,7 +2461,7 @@ int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond,
|
|
|
struct slave *slave)
|
|
|
{
|
|
|
struct arphdr *arp = (struct arphdr *)skb->data;
|
|
|
- struct slave *curr_active_slave;
|
|
|
+ struct slave *curr_active_slave, *curr_arp_slave;
|
|
|
unsigned char *arp_ptr;
|
|
|
__be32 sip, tip;
|
|
|
int alen, is_arp = skb->protocol == __cpu_to_be16(ETH_P_ARP);
|
|
@@ -2506,26 +2508,41 @@ int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond,
|
|
|
&sip, &tip);
|
|
|
|
|
|
curr_active_slave = rcu_dereference(bond->curr_active_slave);
|
|
|
+ curr_arp_slave = rcu_dereference(bond->current_arp_slave);
|
|
|
|
|
|
- /* Backup slaves won't see the ARP reply, but do come through
|
|
|
- * here for each ARP probe (so we swap the sip/tip to validate
|
|
|
- * the probe). In a "redundant switch, common router" type of
|
|
|
- * configuration, the ARP probe will (hopefully) travel from
|
|
|
- * the active, through one switch, the router, then the other
|
|
|
- * switch before reaching the backup.
|
|
|
+ /* We 'trust' the received ARP enough to validate it if:
|
|
|
+ *
|
|
|
+ * (a) the slave receiving the ARP is active (which includes the
|
|
|
+ * current ARP slave, if any), or
|
|
|
+ *
|
|
|
+ * (b) the receiving slave isn't active, but there is a currently
|
|
|
+ * active slave and it received valid arp reply(s) after it became
|
|
|
+ * the currently active slave, or
|
|
|
+ *
|
|
|
+ * (c) there is an ARP slave that sent an ARP during the prior ARP
|
|
|
+ * interval, and we receive an ARP reply on any slave. We accept
|
|
|
+ * these because switch FDB update delays may deliver the ARP
|
|
|
+ * reply to a slave other than the sender of the ARP request.
|
|
|
*
|
|
|
- * We 'trust' the arp requests if there is an active slave and
|
|
|
- * it received valid arp reply(s) after it became active. This
|
|
|
- * is done to avoid endless looping when we can't reach the
|
|
|
+ * Note: for (b), backup slaves are receiving the broadcast ARP
|
|
|
+ * request, not a reply. This request passes from the sending
|
|
|
+ * slave through the L2 switch(es) to the receiving slave. Since
|
|
|
+ * this is checking the request, sip/tip are swapped for
|
|
|
+ * validation.
|
|
|
+ *
|
|
|
+ * This is done to avoid endless looping when we can't reach the
|
|
|
* arp_ip_target and fool ourselves with our own arp requests.
|
|
|
*/
|
|
|
-
|
|
|
if (bond_is_active_slave(slave))
|
|
|
bond_validate_arp(bond, slave, sip, tip);
|
|
|
else if (curr_active_slave &&
|
|
|
time_after(slave_last_rx(bond, curr_active_slave),
|
|
|
curr_active_slave->last_link_up))
|
|
|
bond_validate_arp(bond, slave, tip, sip);
|
|
|
+ else if (curr_arp_slave && (arp->ar_op == htons(ARPOP_REPLY)) &&
|
|
|
+ bond_time_in_interval(bond,
|
|
|
+ dev_trans_start(curr_arp_slave->dev), 1))
|
|
|
+ bond_validate_arp(bond, slave, sip, tip);
|
|
|
|
|
|
out_unlock:
|
|
|
if (arp != (struct arphdr *)skb->data)
|