mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-13 08:30:18 +00:00
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:
parent
0f66c08e96
commit
073ae841d6
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user