IPoIB: Clear high octet in QP number

IPoIB assumes that high (reserved) octet in the 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 an
invalid QPN being used when interoperating with IPoIB connected mode.

Signed-off-by: Michael S. Tsirkin <mst@mellanox.co.il>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
This commit is contained in:
Michael S. Tsirkin 2006-11-16 10:59:12 +02:00 committed by Roland Dreier
parent 0f66c08e96
commit 073ae841d6
1 changed files with 7 additions and 8 deletions

View File

@ -49,6 +49,8 @@
#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");
@ -520,8 +522,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
memcpy(&neigh->dgid.raw, &path->pathrec.dgid.raw,
sizeof(union ib_gid));
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 +600,7 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
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 +661,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
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 +693,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
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 +776,7 @@ static void ipoib_neigh_destructor(struct neighbour *n)
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);