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

Commit 77d8e1ef authored by Michael S. Tsirkin's avatar Michael S. Tsirkin Committed by Roland Dreier
Browse files

IB/ipoib: Fix thinko in packet length checks

The packet length checks in ipoib are broken: we add 4 bytes (IPoIB
encapsulation header) when sending a packet, not 20 bytes (hardware
address length) to each packet.  Therefore, if connected mode is
enabled so that the interface MTU is larger than the multicast MTU,
IPoIB may end up trying to send too-long multicast packets.  For
example, multicast is broken if a message of size 2048 bytes is sent
on an interface with UD MTU 2048, because 2048 is bigger than the real
limit of 2044 but the code tests against the wrong limit of 2060.

This patch fixes <https://bugs.openfabrics.org/show_bug.cgi?id=418

>,
submitted by Scott Weitzenkamp <sweitzen@cisco.com>.

Signed-off-by: default avatarMichael S. Tsirkin <mst@dev.mellanox.co.il>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent d04d01b1
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -452,7 +452,7 @@ void ipoib_cm_send(struct net_device *dev, struct sk_buff *skb, struct ipoib_cm_
			   skb->len, tx->mtu);
			   skb->len, tx->mtu);
		++priv->stats.tx_dropped;
		++priv->stats.tx_dropped;
		++priv->stats.tx_errors;
		++priv->stats.tx_errors;
		ipoib_cm_skb_too_long(dev, skb, tx->mtu - INFINIBAND_ALEN);
		ipoib_cm_skb_too_long(dev, skb, tx->mtu - IPOIB_ENCAP_LEN);
		return;
		return;
	}
	}


+2 −2
Original line number Original line Diff line number Diff line
@@ -328,9 +328,9 @@ void ipoib_send(struct net_device *dev, struct sk_buff *skb,
	struct ipoib_tx_buf *tx_req;
	struct ipoib_tx_buf *tx_req;
	u64 addr;
	u64 addr;


	if (unlikely(skb->len > priv->mcast_mtu + INFINIBAND_ALEN)) {
	if (unlikely(skb->len > priv->mcast_mtu + IPOIB_ENCAP_LEN)) {
		ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n",
		ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n",
			   skb->len, priv->mcast_mtu + INFINIBAND_ALEN);
			   skb->len, priv->mcast_mtu + IPOIB_ENCAP_LEN);
		++priv->stats.tx_dropped;
		++priv->stats.tx_dropped;
		++priv->stats.tx_errors;
		++priv->stats.tx_errors;
		ipoib_cm_skb_too_long(dev, skb, priv->mcast_mtu);
		ipoib_cm_skb_too_long(dev, skb, priv->mcast_mtu);