Fix bonding failover in the case poth peers have failover and gratuitous arp
is lost.
In that case, ipoib sender side will create ipoib_neigh and issue a path request
with the old gid first. When skb->dst->neighbour->ha changes due to arp refresh,
ipoib_neigh will not be added to the path->list of the path of the new mgid,
because ipoib_neigh already exists. It will not have an ah either, because of
sender-side failover. Therefore, it will not get an ah when the path is 
resolved.

The solution here is to compare gids even if neigh->ah is invalid, also
initiallize neigh->dgid.raw to have value to compare with.

Signed-off-by: Yossi Etigin <[EMAIL PROTECTED]>
---

Fix bugzilla 1286.

drivers/infiniband/ulp/ipoib/ipoib_main.c |   40 +++++++++++++++---------------
1 file changed, 21 insertions(+), 19 deletions(-)

Index: b/drivers/infiniband/ulp/ipoib/ipoib_main.c
===================================================================
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c 2008-10-31 19:17:42.000000000 
+0200
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c 2008-10-31 19:24:52.000000000 
+0200
@@ -584,6 +584,8 @@ static void neigh_add_path(struct sk_buf
                        ipoib_send(dev, skb, path->ah, 
IPOIB_QPN(skb->dst->neighbour->ha));
        } else {
                neigh->ah  = NULL;
+               memcpy(&neigh->dgid.raw, skb->dst->neighbour->ha + 4,
+                      sizeof(union ib_gid));

                if (!path->query && path_rec_start(dev, path))
                        goto err_list;
@@ -687,26 +689,26 @@ static int ipoib_start_xmit(struct sk_bu

                neigh = *to_ipoib_neigh(skb->dst->neighbour);

-               if (neigh->ah)
-                       if (unlikely((memcmp(&neigh->dgid.raw,
-                                           skb->dst->neighbour->ha + 4,
-                                           sizeof(union ib_gid))) ||
-                                        (neigh->dev != dev))) {
-                               spin_lock_irqsave(&priv->lock, flags);
-                               /*
-                                * It's safe to call ipoib_put_ah() inside
-                                * priv->lock here, because we know that
-                                * path->ah will always hold one more reference,
-                                * so ipoib_put_ah() will never do more than
-                                * decrement the ref count.
-                                */
+               if (unlikely((memcmp(&neigh->dgid.raw,
+                                    skb->dst->neighbour->ha + 4,
+                                    sizeof(union ib_gid))) ||
+                            (neigh->dev != dev))) {
+                       spin_lock_irqsave(&priv->lock, flags);
+                       /*
+                        * It's safe to call ipoib_put_ah() inside
+                        * priv->lock here, because we know that
+                        * path->ah will always hold one more reference,
+                        * so ipoib_put_ah() will never do more than
+                        * decrement the ref count.
+                        */
+                       if (neigh->ah)
                                ipoib_put_ah(neigh->ah);
-                               list_del(&neigh->list);
-                               ipoib_neigh_free(dev, neigh);
-                               spin_unlock_irqrestore(&priv->lock, flags);
-                               ipoib_path_lookup(skb, dev);
-                               return NETDEV_TX_OK;
-                       }
+                       list_del(&neigh->list);
+                       ipoib_neigh_free(dev, neigh);
+                       spin_unlock_irqrestore(&priv->lock, flags);
+                       ipoib_path_lookup(skb, dev);
+                       return NETDEV_TX_OK;
+               }

                if (ipoib_cm_get(neigh)) {
                        if (ipoib_cm_up(neigh)) {
--
--Yossi
_______________________________________________
general mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to