From patchwork Sat Dec 9 01:18:05 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Smart X-Patchwork-Id: 10103483 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id E94F960223 for ; Sat, 9 Dec 2017 01:18:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DD36A28FFE for ; Sat, 9 Dec 2017 01:18:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D21E82900D; Sat, 9 Dec 2017 01:18:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4E6C328FFE for ; Sat, 9 Dec 2017 01:18:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753453AbdLIBS2 (ORCPT ); Fri, 8 Dec 2017 20:18:28 -0500 Received: from mail-qk0-f193.google.com ([209.85.220.193]:41769 "EHLO mail-qk0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752240AbdLIBS0 (ORCPT ); Fri, 8 Dec 2017 20:18:26 -0500 Received: by mail-qk0-f193.google.com with SMTP id 84so1024759qks.8 for ; Fri, 08 Dec 2017 17:18:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=eMTYdvfsjn89y0Kn77/wsUtVI8EhZ5lTigxmeGgwn+U=; b=s1Lz7HHLPbbO/jWdWm84f3rVaMi8f+uYzuiJZDDRyBNsfMiYO/4ixW9VHKvUYdxo/m O6Q7NLWacr5C9ih5IrDYCjSE8QL+HoM7JIdh7XQ7eClC+ZApN+Vx7egYLJiHzV3QyHSk 2LB0l3CZRJKncWvDH2qjFM4paUFjaXpfa3AN4jaqlv0XDmpGPkooi7eAsAqbkJz843jj 4Dab3tPloJzCMu7FyI0eVNGpJU3kyzlCYSkmg6iEadyC0XyDitFSN9CIezEIL89GdOl7 qVVZ/ED0Qu18b+E7uzwC7S4Yl5jtsqinI4blvnDiWKwSxjUoA0ETMLFpsEflUtEksgqR US9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=eMTYdvfsjn89y0Kn77/wsUtVI8EhZ5lTigxmeGgwn+U=; b=X5oqISDxXEUNzC9ZQDTY0Mt3CFGGUXJmUIQW0euhbW8pQ5Ism7OLBZJxV+VU3sidBt AaYI5fYqgLKO0JluXgTKOKs13rcQhVBl9kqQxYhJ5lu/Yr6ysjsdCE6I+Ue2ZlwWmG0l yW5IwCRkfMTD4IRFmwQwsQ6h0HBrU0hU8K5WRfu768TPN4d/kjk8IlyM1eTTQmPoexaI aglTOMzcWnxwi/EQsawHPVzI2Kz+ZF5xNyKSjgrAIG7WfxC1WR0gckjY07UkCD3Ce9UA kR18p6+pRD2wkA3ZVLBEnY50u4hToYZc+k3ClNDighD48gYbwQvTs9ySZw24AhxXsz6J aNwQ== X-Gm-Message-State: AKGB3mJno1ojHigcOFeBLTRR2ZbyKEdEQ8LuYQTjlesLmhv2ri6i68QY 23zcILL2Gu9MnsMJkUxPJgUfmw== X-Google-Smtp-Source: AGs4zMYdF0S05FcE69E9YTSurgM87bInuBHEnCay92YwiMzoYQEizv6gj6ZLRavclXtUxYk/dldPjA== X-Received: by 10.55.188.6 with SMTP id m6mr38889565qkf.75.1512782305576; Fri, 08 Dec 2017 17:18:25 -0800 (PST) Received: from pallmd1.broadcom.com ([192.19.228.250]) by smtp.gmail.com with ESMTPSA id k1sm922511qtf.11.2017.12.08.17.18.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 08 Dec 2017 17:18:25 -0800 (PST) From: James Smart To: linux-scsi@vger.kernel.org Cc: James Smart , Dick Kennedy , James Smart Subject: [PATCH 3/9] lpfc: Fix receive PRLI handling Date: Fri, 8 Dec 2017 17:18:05 -0800 Message-Id: <20171209011811.23421-4-jsmart2021@gmail.com> X-Mailer: git-send-email 2.13.1 In-Reply-To: <20171209011811.23421-1-jsmart2021@gmail.com> References: <20171209011811.23421-1-jsmart2021@gmail.com> Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Handling a rcv'ed PRLI incorrectly can cause the ndlp to end up in the wrong state or the driver to ACC and PRLI when it should send LS_RJT. The cause was due to the driver not properly looking at the PRLI type and taking the multiple protocol support into consideration. Resolved by adding checks in the various PRLI receive points to validate PRLI type and reject if not valid for the enabled protocols and mode (host vs target). Signed-off-by: Dick Kennedy Signed-off-by: James Smart Reviewed-by: Hannes Reinecke --- drivers/scsi/lpfc/lpfc_els.c | 7 ----- drivers/scsi/lpfc/lpfc_nportdisc.c | 54 +++++++++++++++++++++++++++++++++----- 2 files changed, 47 insertions(+), 14 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 4a14f3c82a07..6ffd65a935c4 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -8063,13 +8063,6 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, rjt_exp = LSEXP_NOTHING_MORE; break; } - - /* NVMET accepts NVME PRLI only. Reject FCP PRLI */ - if (cmd == ELS_CMD_PRLI && phba->nvmet_support) { - rjt_err = LSRJT_CMD_UNSUPPORTED; - rjt_exp = LSEXP_REQ_UNSUPPORTED; - break; - } lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_PRLI); break; case ELS_CMD_LIRR: diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index b6957d944b9a..df050b211e0b 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -727,6 +727,41 @@ lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, return 0; } +static uint32_t +lpfc_rcv_prli_support_check(struct lpfc_vport *vport, + struct lpfc_nodelist *ndlp, + struct lpfc_iocbq *cmdiocb) +{ + struct ls_rjt stat; + uint32_t *payload; + uint32_t cmd; + + payload = ((struct lpfc_dmabuf *)cmdiocb->context2)->virt; + cmd = *payload; + if (vport->phba->nvmet_support) { + /* Must be a NVME PRLI */ + if (cmd == ELS_CMD_PRLI) + goto out; + } else { + /* Initiator mode. */ + if (!vport->nvmei_support && (cmd == ELS_CMD_NVMEPRLI)) + goto out; + } + return 1; +out: + lpfc_printf_vlog(vport, KERN_WARNING, LOG_NVME_DISC, + "6115 Rcv PRLI (%x) check failed: ndlp rpi %d " + "state x%x flags x%x\n", + cmd, ndlp->nlp_rpi, ndlp->nlp_state, + ndlp->nlp_flag); + memset(&stat, 0, sizeof(struct ls_rjt)); + stat.un.b.lsRjtRsnCode = LSRJT_CMD_UNSUPPORTED; + stat.un.b.lsRjtRsnCodeExp = LSEXP_REQ_UNSUPPORTED; + lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, + ndlp, NULL); + return 0; +} + static void lpfc_rcv_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, struct lpfc_iocbq *cmdiocb) @@ -1373,7 +1408,8 @@ lpfc_rcv_prli_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, { struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; - lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp); + if (lpfc_rcv_prli_support_check(vport, ndlp, cmdiocb)) + lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp); return ndlp->nlp_state; } @@ -1544,6 +1580,9 @@ lpfc_rcv_prli_reglogin_issue(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; struct ls_rjt stat; + if (!lpfc_rcv_prli_support_check(vport, ndlp, cmdiocb)) { + return ndlp->nlp_state; + } if (vport->phba->nvmet_support) { /* NVME Target mode. Handle and respond to the PRLI and * transition to UNMAPPED provided the RPI has completed @@ -1558,11 +1597,6 @@ lpfc_rcv_prli_reglogin_issue(struct lpfc_vport *vport, * to prevent an illegal state transition when the * rpi registration does complete. */ - lpfc_printf_vlog(vport, KERN_WARNING, LOG_NVME_DISC, - "6115 NVMET ndlp rpi %d state " - "unknown, state x%x flags x%08x\n", - ndlp->nlp_rpi, ndlp->nlp_state, - ndlp->nlp_flag); memset(&stat, 0, sizeof(struct ls_rjt)); stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; stat.un.b.lsRjtRsnCodeExp = LSEXP_CMD_IN_PROGRESS; @@ -1573,7 +1607,6 @@ lpfc_rcv_prli_reglogin_issue(struct lpfc_vport *vport, /* Initiator mode. */ lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp); } - return ndlp->nlp_state; } @@ -1819,6 +1852,8 @@ lpfc_rcv_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, { struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; + if (!lpfc_rcv_prli_support_check(vport, ndlp, cmdiocb)) + return ndlp->nlp_state; lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp); return ndlp->nlp_state; } @@ -2241,6 +2276,9 @@ lpfc_rcv_prli_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, { struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; + if (!lpfc_rcv_prli_support_check(vport, ndlp, cmdiocb)) + return ndlp->nlp_state; + lpfc_rcv_prli(vport, ndlp, cmdiocb); lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp); return ndlp->nlp_state; @@ -2310,6 +2348,8 @@ lpfc_rcv_prli_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, { struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg; + if (!lpfc_rcv_prli_support_check(vport, ndlp, cmdiocb)) + return ndlp->nlp_state; lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp); return ndlp->nlp_state; }