lkml.org 
[lkml]   [2018]   [Nov]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.9 046/171] IB/core: Fix the validations of a multicast LID in attach or detach operations
    Date
    4.9-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    [ Upstream commit 5236333592244557a19694a51337df6ac018f0a7 ]

    RoCE Annex (A16.9.10/11) declares that during attach (detach) QP to a
    multicast group, if the QP is associated with a RoCE port, the
    multicast group MLID is unused and is ignored.

    During attach or detach multicast, when the QP is associated with a
    port, it is enough to check the port's link layer and validate the
    LID only if it is Infiniband. Otherwise, avoid validating the
    multicast LID.

    Fixes: 8561eae60ff9 ("IB/core: For multicast functions, verify that LIDs are multicast LIDs")
    Signed-off-by: Noa Osherovich <noaos@mellanox.com>
    Reviewed-by: Moni Shoua <monis@mellanox.com>
    Signed-off-by: Leon Romanovsky <leon@kernel.org>
    Signed-off-by: Doug Ledford <dledford@redhat.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/infiniband/core/verbs.c | 44 ++++++++++++++++++++++++++++++---
    1 file changed, 40 insertions(+), 4 deletions(-)

    diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
    index 0e64b52af5b2..d28c4cf7c1ee 100644
    --- a/drivers/infiniband/core/verbs.c
    +++ b/drivers/infiniband/core/verbs.c
    @@ -1510,6 +1510,44 @@ EXPORT_SYMBOL(ib_dealloc_fmr);

    /* Multicast groups */

    +static bool is_valid_mcast_lid(struct ib_qp *qp, u16 lid)
    +{
    + struct ib_qp_init_attr init_attr = {};
    + struct ib_qp_attr attr = {};
    + int num_eth_ports = 0;
    + int port;
    +
    + /* If QP state >= init, it is assigned to a port and we can check this
    + * port only.
    + */
    + if (!ib_query_qp(qp, &attr, IB_QP_STATE | IB_QP_PORT, &init_attr)) {
    + if (attr.qp_state >= IB_QPS_INIT) {
    + if (qp->device->get_link_layer(qp->device, attr.port_num) !=
    + IB_LINK_LAYER_INFINIBAND)
    + return true;
    + goto lid_check;
    + }
    + }
    +
    + /* Can't get a quick answer, iterate over all ports */
    + for (port = 0; port < qp->device->phys_port_cnt; port++)
    + if (qp->device->get_link_layer(qp->device, port) !=
    + IB_LINK_LAYER_INFINIBAND)
    + num_eth_ports++;
    +
    + /* If we have at lease one Ethernet port, RoCE annex declares that
    + * multicast LID should be ignored. We can't tell at this step if the
    + * QP belongs to an IB or Ethernet port.
    + */
    + if (num_eth_ports)
    + return true;
    +
    + /* If all the ports are IB, we can check according to IB spec. */
    +lid_check:
    + return !(lid < be16_to_cpu(IB_MULTICAST_LID_BASE) ||
    + lid == be16_to_cpu(IB_LID_PERMISSIVE));
    +}
    +
    int ib_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
    {
    int ret;
    @@ -1517,8 +1555,7 @@ int ib_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
    if (!qp->device->attach_mcast)
    return -ENOSYS;
    if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD ||
    - lid < be16_to_cpu(IB_MULTICAST_LID_BASE) ||
    - lid == be16_to_cpu(IB_LID_PERMISSIVE))
    + !is_valid_mcast_lid(qp, lid))
    return -EINVAL;

    ret = qp->device->attach_mcast(qp, gid, lid);
    @@ -1535,8 +1572,7 @@ int ib_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
    if (!qp->device->detach_mcast)
    return -ENOSYS;
    if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD ||
    - lid < be16_to_cpu(IB_MULTICAST_LID_BASE) ||
    - lid == be16_to_cpu(IB_LID_PERMISSIVE))
    + !is_valid_mcast_lid(qp, lid))
    return -EINVAL;

    ret = qp->device->detach_mcast(qp, gid, lid);
    --
    2.17.1


    \
     
     \ /
      Last update: 2018-11-08 23:05    [W:4.078 / U:0.448 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site