]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
bonding: If IP route look-up to send an ARP fails, mark in bonding structure as no...
authorRama Nichanamatlu <rama.nichanamatlu@oracle.com>
Tue, 15 Sep 2015 19:34:46 +0000 (12:34 -0700)
committerSantosh Shilimkar <santosh.shilimkar@oracle.com>
Thu, 17 Sep 2015 16:23:18 +0000 (09:23 -0700)
During the creation of VLAN's atop bonding the underlying interfaces are
made part of VLAN's, and at the same bonding driver gets aware of that
VLAN's exists above it and hence would consult IP routing for every ARP to
be sent to determine the route which tells bonding driver the correct VLAN
tag to attach to the outgoing ARP packet. But, during the VLAN creation
when vlan driver puts the underlying interface into default vlan and actual
vlan in-between this if bonding driver consults the IP for a route, IP fails
to provide a correct route and upon which bonding driver drops the ARP
packet. ARP monitor when it comes aroung next time, sees no ARP response
and fails-over to the next available slave. To prevent this false fail-over,
when bonding dirver fails to send an ARP out it marks in its private
structure, bonding{}, not to expect an ARP response, and when ARP monitor
comes around next time ARP sending will be tried again.

(this is same as commit 7cdd940ee8d9e25c942f5479410a7d2d6ac38d09)

Orabug: 21844825

Signed-off-by: Rama Nichanamatlu <rama.nichanamatlu@oracle.com>
Signed-off-by: Venkat Venkatsubra <venkat.x.venkatsubra@oracle.com>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
drivers/net/bonding/bond_main.c
include/net/bonding.h

index d5fe5d5f490f3efa70e022fdac9b64bd89311e22..e76898705f1e3120c8fa54917cf5cd5b4ddbf69d 100644 (file)
@@ -2202,8 +2202,8 @@ static bool bond_has_this_ip(struct bonding *bond, __be32 ip)
  * switches in VLAN mode (especially if ports are configured as
  * "native" to a VLAN) might not pass non-tagged frames.
  */
-static void bond_arp_send(struct net_device *slave_dev, int arp_op,
-                         __be32 dest_ip, __be32 src_ip,
+static void bond_arp_send(struct bonding *bond, struct net_device *slave_dev, 
+                         int arp_op, __be32 dest_ip, __be32 src_ip,
                          struct bond_vlan_tag *tags)
 {
        struct sk_buff *skb;
@@ -2253,6 +2253,7 @@ static void bond_arp_send(struct net_device *slave_dev, int arp_op,
 
 xmit:
        arp_xmit(skb);
+       bond->arp_sent = true;
 }
 
 /* Validate the device path between the @start_dev and the @end_dev.
@@ -2317,7 +2318,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
                                net_warn_ratelimited("%s: no route to arp_ip_target %pI4 and arp_validate is set\n",
                                                     bond->dev->name,
                                                     &targets[i]);
-                       bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i],
+                       bond_arp_send(bond, slave->dev, ARPOP_REQUEST, targets[i],
                                      0, tags);
                        continue;
                }
@@ -2343,7 +2344,7 @@ static void bond_arp_send_all(struct bonding *bond, struct slave *slave)
 found:
                addr = bond_confirm_addr(rt->dst.dev, targets[i], 0);
                ip_rt_put(rt);
-               bond_arp_send(slave->dev, ARPOP_REQUEST, targets[i],
+               bond_arp_send(bond, slave->dev, ARPOP_REQUEST, targets[i],
                              addr, tags);
                kfree(tags);
        }
@@ -2821,7 +2822,7 @@ static void bond_activebackup_arp_mon(struct work_struct *work)
 
        should_notify_peers = bond_should_notify_peers(bond);
 
-       if (bond_ab_arp_inspect(bond)) {
+       if (bond->arp_sent && bond_ab_arp_inspect(bond)) {
                rcu_read_unlock();
 
                /* Race avoidance with bond_close flush of workqueue */
@@ -2838,6 +2839,7 @@ static void bond_activebackup_arp_mon(struct work_struct *work)
        }
 
        should_notify_rtnl = bond_ab_arp_probe(bond);
+       bond->arp_sent = false;
        rcu_read_unlock();
 
 re_arm:
@@ -4102,6 +4104,7 @@ void bond_setup(struct net_device *bond_dev)
        bond_dev->hw_features &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_HW_CSUM);
        bond_dev->hw_features |= NETIF_F_GSO_ENCAP_ALL;
        bond_dev->features |= bond_dev->hw_features;
+       bond->arp_sent = false;
 }
 
 /* Destroy a bonding device.
index 78ed135e9dea6a9971d15e3b786a64de170b310c..b3921c130f3a61fd27c6289500fa7f40c1663042 100644 (file)
@@ -234,6 +234,7 @@ struct bonding {
        struct   dentry *debug_dir;
 #endif /* CONFIG_DEBUG_FS */
        struct rtnl_link_stats64 bond_stats;
+       bool arp_sent;
 };
 
 #define bond_slave_get_rcu(dev) \