Commit be1d325a authored by Noa Osherovich's avatar Noa Osherovich Committed by Doug Ledford

IB/core: Set RoCEv2 MGID according to spec

RoCEv2 Annex states that for RoCEv2 over IPv4, the corresponding
IPv4 address is encoded into the GID according to the following rule:
GID= :ffff:<IPv4 address>

Remove the 0xff0e prefix for RoCEv2 packets with IPv4 and leave it
zeroed and change rdma_is_multicast_addr() to consider the new logic.
Signed-off-by: default avatarNoa Osherovich <noaos@mellanox.com>
Reviewed-by: default avatarMoni Shoua <monis@mellanox.com>
Signed-off-by: default avatarLeon Romanovsky <leon@kernel.org>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent 52363335
...@@ -3998,7 +3998,8 @@ static void iboe_mcast_work_handler(struct work_struct *work) ...@@ -3998,7 +3998,8 @@ static void iboe_mcast_work_handler(struct work_struct *work)
kfree(mw); kfree(mw);
} }
static void cma_iboe_set_mgid(struct sockaddr *addr, union ib_gid *mgid) static void cma_iboe_set_mgid(struct sockaddr *addr, union ib_gid *mgid,
enum ib_gid_type gid_type)
{ {
struct sockaddr_in *sin = (struct sockaddr_in *)addr; struct sockaddr_in *sin = (struct sockaddr_in *)addr;
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr; struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
...@@ -4008,8 +4009,8 @@ static void cma_iboe_set_mgid(struct sockaddr *addr, union ib_gid *mgid) ...@@ -4008,8 +4009,8 @@ static void cma_iboe_set_mgid(struct sockaddr *addr, union ib_gid *mgid)
} else if (addr->sa_family == AF_INET6) { } else if (addr->sa_family == AF_INET6) {
memcpy(mgid, &sin6->sin6_addr, sizeof *mgid); memcpy(mgid, &sin6->sin6_addr, sizeof *mgid);
} else { } else {
mgid->raw[0] = 0xff; mgid->raw[0] = (gid_type == IB_GID_TYPE_IB) ? 0xff : 0;
mgid->raw[1] = 0x0e; mgid->raw[1] = (gid_type == IB_GID_TYPE_IB) ? 0x0e : 0;
mgid->raw[2] = 0; mgid->raw[2] = 0;
mgid->raw[3] = 0; mgid->raw[3] = 0;
mgid->raw[4] = 0; mgid->raw[4] = 0;
...@@ -4050,7 +4051,9 @@ static int cma_iboe_join_multicast(struct rdma_id_private *id_priv, ...@@ -4050,7 +4051,9 @@ static int cma_iboe_join_multicast(struct rdma_id_private *id_priv,
goto out1; goto out1;
} }
cma_iboe_set_mgid(addr, &mc->multicast.ib->rec.mgid); gid_type = id_priv->cma_dev->default_gid_type[id_priv->id.port_num -
rdma_start_port(id_priv->cma_dev->device)];
cma_iboe_set_mgid(addr, &mc->multicast.ib->rec.mgid, gid_type);
mc->multicast.ib->rec.pkey = cpu_to_be16(0xffff); mc->multicast.ib->rec.pkey = cpu_to_be16(0xffff);
if (id_priv->id.ps == RDMA_PS_UDP) if (id_priv->id.ps == RDMA_PS_UDP)
...@@ -4066,8 +4069,6 @@ static int cma_iboe_join_multicast(struct rdma_id_private *id_priv, ...@@ -4066,8 +4069,6 @@ static int cma_iboe_join_multicast(struct rdma_id_private *id_priv,
mc->multicast.ib->rec.hop_limit = 1; mc->multicast.ib->rec.hop_limit = 1;
mc->multicast.ib->rec.mtu = iboe_get_mtu(ndev->mtu); mc->multicast.ib->rec.mtu = iboe_get_mtu(ndev->mtu);
gid_type = id_priv->cma_dev->default_gid_type[id_priv->id.port_num -
rdma_start_port(id_priv->cma_dev->device)];
if (addr->sa_family == AF_INET) { if (addr->sa_family == AF_INET) {
if (gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP) { if (gid_type == IB_GID_TYPE_ROCE_UDP_ENCAP) {
mc->multicast.ib->rec.hop_limit = IPV6_DEFAULT_HOPLIMIT; mc->multicast.ib->rec.hop_limit = IPV6_DEFAULT_HOPLIMIT;
......
...@@ -1613,8 +1613,9 @@ int ib_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid) ...@@ -1613,8 +1613,9 @@ int ib_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
if (!qp->device->attach_mcast) if (!qp->device->attach_mcast)
return -ENOSYS; return -ENOSYS;
if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD ||
!is_valid_mcast_lid(qp, lid)) if (!rdma_is_multicast_addr((struct in6_addr *)gid->raw) ||
qp->qp_type != IB_QPT_UD || !is_valid_mcast_lid(qp, lid))
return -EINVAL; return -EINVAL;
ret = qp->device->attach_mcast(qp, gid, lid); ret = qp->device->attach_mcast(qp, gid, lid);
...@@ -1630,8 +1631,9 @@ int ib_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid) ...@@ -1630,8 +1631,9 @@ int ib_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
if (!qp->device->detach_mcast) if (!qp->device->detach_mcast)
return -ENOSYS; return -ENOSYS;
if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD ||
!is_valid_mcast_lid(qp, lid)) if (!rdma_is_multicast_addr((struct in6_addr *)gid->raw) ||
qp->qp_type != IB_QPT_UD || !is_valid_mcast_lid(qp, lid))
return -EINVAL; return -EINVAL;
ret = qp->device->detach_mcast(qp, gid, lid); ret = qp->device->detach_mcast(qp, gid, lid);
......
...@@ -304,7 +304,13 @@ static inline void rdma_get_ll_mac(struct in6_addr *addr, u8 *mac) ...@@ -304,7 +304,13 @@ static inline void rdma_get_ll_mac(struct in6_addr *addr, u8 *mac)
static inline int rdma_is_multicast_addr(struct in6_addr *addr) static inline int rdma_is_multicast_addr(struct in6_addr *addr)
{ {
return addr->s6_addr[0] == 0xff; u32 ipv4_addr;
if (addr->s6_addr[0] == 0xff)
return 1;
memcpy(&ipv4_addr, addr->s6_addr + 12, 4);
return (ipv6_addr_v4mapped(addr) && ipv4_is_multicast(ipv4_addr));
} }
static inline void rdma_get_mcast_mac(struct in6_addr *addr, u8 *mac) static inline void rdma_get_mcast_mac(struct in6_addr *addr, u8 *mac)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment