ipoib assumes that high (reserved) octet in hardware address is 0, and copies
it into the QPN.  This violates RFC 4391 (which requires that the high 8 bits
are ignored on receive), and will result in invalid QPN passed to hardware when
inter-operating with IPoIB connected mode.

Signed-off-by: Michael S. Tsirkin <[EMAIL PROTECTED]>

diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c 
b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 1eaf00e..cdc98b1 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -49,6 +49,8 @@ #include <linux/in.h>
 
 #include <net/dst.h>
 
+#define IPOIB_QPN(ha) (be32_to_cpup((__be32 *) ha) & 0xffffff)
+
 MODULE_AUTHOR("Roland Dreier");
 MODULE_DESCRIPTION("IP-over-InfiniBand net driver");
 MODULE_LICENSE("Dual BSD/GPL");
@@ -517,6 +516,5 @@ static void neigh_add_path(struct sk_buf
 
-               ipoib_send(dev, skb, path->ah,
-                          be32_to_cpup((__be32 *) skb->dst->neighbour->ha));
+               ipoib_send(dev, skb, path->ah, 
IPOIB_QPN(skb->dst->neighbour->ha));
        } else {
                neigh->ah  = NULL;
                __skb_queue_tail(&neigh->queue, skb);
@@ -599,8 +594,7 @@ static void unicast_arp_send(struct sk_b
                ipoib_dbg(priv, "Send unicast ARP to %04x\n",
                          be16_to_cpu(path->pathrec.dlid));
 
-               ipoib_send(dev, skb, path->ah,
-                          be32_to_cpup((__be32 *) phdr->hwaddr));
+               ipoib_send(dev, skb, path->ah, IPOIB_QPN(phdr->hwaddr));
        } else if ((path->query || !path_rec_start(dev, path)) &&
                   skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) {
                /* put pseudoheader back on for next time */
@@ -661,8 +655,7 @@ static int ipoib_start_xmit(struct sk_bu
                                goto out;
                        }
 
-                       ipoib_send(dev, skb, neigh->ah,
-                                  be32_to_cpup((__be32 *) 
skb->dst->neighbour->ha));
+                       ipoib_send(dev, skb, neigh->ah, 
IPOIB_QPN(skb->dst->neighbour->ha));
                        goto out;
                }
 
@@ -694,7 +687,7 @@ static int ipoib_start_xmit(struct sk_bu
                                           IPOIB_GID_FMT "\n",
                                           skb->dst ? "neigh" : "dst",
                                           be16_to_cpup((__be16 *) skb->data),
-                                          be32_to_cpup((__be32 *) 
phdr->hwaddr),
+                                          IPOIB_QPN(phdr->hwaddr),
                                           IPOIB_GID_RAW_ARG(phdr->hwaddr + 4));
                                dev_kfree_skb_any(skb);
                                ++priv->stats.tx_dropped;
@@ -777,7 +770,7 @@ static void ipoib_neigh_destructor(struc
 
        ipoib_dbg(priv,
                  "neigh_destructor for %06x " IPOIB_GID_FMT "\n",
-                 be32_to_cpup((__be32 *) n->ha),
+                 IPOIB_QPN(n->ha),
                  IPOIB_GID_RAW_ARG(n->ha + 4));
 
        spin_lock_irqsave(&priv->lock, flags);

-- 
MST

_______________________________________________
openib-general mailing list
[email protected]
http://openib.org/mailman/listinfo/openib-general

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

Reply via email to