Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 073ae841 authored by Michael S. Tsirkin's avatar Michael S. Tsirkin Committed by Roland Dreier
Browse files

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: default avatarMichael S. Tsirkin <mst@mellanox.co.il>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent 0f66c08e
Loading
Loading
Loading
Loading
+7 −8
Original line number Diff line number Diff line
@@ -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);