summaryrefslogtreecommitdiff
path: root/drivers/infiniband/core
diff options
context:
space:
mode:
authorLeon Romanovsky <leonro@nvidia.com>2026-10-18 07:59:38 -0400
committerLeon Romanovsky <leonro@nvidia.com>2026-10-18 07:59:38 -0400
commitfdfd099222d9de9e2f1b8d69e94494c5489272cc (patch)
treeba62b9ab86d176f82054e5223517c0ddc58cc86e /drivers/infiniband/core
parentd74bdcfa89fa45d3a506cddc37b3bf1b76cea0ce (diff)
RDMA/core: Reject LAG selection when source MAC lookup fails
GID deletion can clear the source device association after LAG lookup retains the bonding master. Ignoring the resulting L2 lookup failure copies uninitialized source MAC bytes into the synthetic hash packet. Read the source MAC before allocating the packet and propagate lookup errors to the caller, so failed lookups cannot influence slave selection. Fixes: bd3920eac133 ("RDMA/core: Add LAG functionality") Link: https://patch.msgid.link/20261015-ib-core-fixes-v1-3-60f6da3ddec3@nvidia.com Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
Diffstat (limited to 'drivers/infiniband/core')
-rw-r--r--drivers/infiniband/core/lag.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/drivers/infiniband/core/lag.c b/drivers/infiniband/core/lag.c
index 88aac911e8ee..651c868aa04e 100644
--- a/drivers/infiniband/core/lag.c
+++ b/drivers/infiniband/core/lag.c
@@ -19,6 +19,11 @@ static struct sk_buff *rdma_build_skb(struct net_device *netdev,
u8 smac[ETH_ALEN];
bool is_ipv4;
int hdr_len;
+ int ret;
+
+ ret = rdma_read_gid_l2_fields(ah_attr->grh.sgid_attr, NULL, smac);
+ if (ret)
+ return ERR_PTR(ret);
is_ipv4 = ipv6_addr_v4mapped((struct in6_addr *)ah_attr->grh.dgid.raw);
hdr_len = ETH_HLEN + sizeof(struct udphdr) + LL_RESERVED_SPACE(netdev);
@@ -26,7 +31,7 @@ static struct sk_buff *rdma_build_skb(struct net_device *netdev,
skb = alloc_skb(hdr_len, flags);
if (!skb)
- return NULL;
+ return ERR_PTR(-ENOMEM);
skb->dev = netdev;
skb_reserve(skb, hdr_len);
@@ -70,7 +75,6 @@ static struct sk_buff *rdma_build_skb(struct net_device *netdev,
skb_reset_mac_header(skb);
eth = eth_hdr(skb);
skb->protocol = eth->h_proto = htons(is_ipv4 ? ETH_P_IP : ETH_P_IPV6);
- rdma_read_gid_l2_fields(ah_attr->grh.sgid_attr, NULL, smac);
memcpy(eth->h_source, smac, ETH_ALEN);
memcpy(eth->h_dest, ah_attr->roce.dmac, ETH_ALEN);
@@ -86,8 +90,8 @@ static struct net_device *rdma_get_xmit_slave_udp(struct ib_device *device,
struct sk_buff *skb;
skb = rdma_build_skb(master, ah_attr, flags);
- if (!skb)
- return ERR_PTR(-ENOMEM);
+ if (IS_ERR(skb))
+ return ERR_CAST(skb);
rcu_read_lock();
slave = netdev_get_xmit_slave(master, skb,