scsi: qedf: Add non-offload receive filters.
authorChad Dupuis <chad.dupuis@cavium.com>
Wed, 31 May 2017 13:33:57 +0000 (06:33 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 13 Jun 2017 00:48:06 +0000 (20:48 -0400)
Drop invalid or unexpected FCoE frames that come into the non-offload path
since the FCoE firmware would not do the filtering for us.

Signed-off-by: Chad Dupuis <chad.dupuis@cavium.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/qedf/qedf_main.c

index ef0dc566d70fe1d1842389625abbe01df23825f9..b7d17e177cf0851ae8ef8b8bfba717f7a3d7e030 100644 (file)
@@ -2087,6 +2087,8 @@ static void qedf_recv_frame(struct qedf_ctx *qedf,
        u8 *dest_mac = NULL;
        struct fcoe_hdr *hp;
        struct qedf_rport *fcport;
+       struct fc_lport *vn_port;
+       u32 f_ctl;
 
        lport = qedf->lport;
        if (lport == NULL || lport->state == LPORT_ST_DISABLED) {
@@ -2123,6 +2125,10 @@ static void qedf_recv_frame(struct qedf_ctx *qedf,
 
        fh = fc_frame_header_get(fp);
 
+       /*
+        * Invalid frame filters.
+        */
+
        if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA &&
            fh->fh_type == FC_TYPE_FCP) {
                /* Drop FCP data. We dont this in L2 path */
@@ -2148,6 +2154,43 @@ static void qedf_recv_frame(struct qedf_ctx *qedf,
                return;
        }
 
+       if (ntoh24(&dest_mac[3]) != ntoh24(fh->fh_d_id)) {
+               QEDF_ERR(&(qedf->dbg_ctx), "FC frame d_id mismatch with MAC %pM.\n",
+                   dest_mac);
+               return;
+       }
+
+       if (qedf->ctlr.state) {
+               if (!ether_addr_equal(mac, qedf->ctlr.dest_addr)) {
+                       QEDF_ERR(&(qedf->dbg_ctx), "Wrong source address mac:%pM dest_addr:%pM.\n",
+                           mac, qedf->ctlr.dest_addr);
+                       kfree_skb(skb);
+                       return;
+               }
+       }
+
+       vn_port = fc_vport_id_lookup(lport, ntoh24(fh->fh_d_id));
+
+       /*
+        * If the destination ID from the frame header does not match what we
+        * have on record for lport and the search for a NPIV port came up
+        * empty then this is not addressed to our port so simply drop it.
+        */
+       if (lport->port_id != ntoh24(fh->fh_d_id) && !vn_port) {
+               QEDF_ERR(&(qedf->dbg_ctx), "Dropping frame due to destination mismatch: lport->port_id=%x fh->d_id=%x.\n",
+                   lport->port_id, ntoh24(fh->fh_d_id));
+               kfree_skb(skb);
+               return;
+       }
+
+       f_ctl = ntoh24(fh->fh_f_ctl);
+       if ((fh->fh_type == FC_TYPE_BLS) && (f_ctl & FC_FC_SEQ_CTX) &&
+           (f_ctl & FC_FC_EX_CTX)) {
+               /* Drop incoming ABTS response that has both SEQ/EX CTX set */
+               kfree_skb(skb);
+               return;
+       }
+
        /*
         * If a connection is uploading, drop incoming FCoE frames as there
         * is a small window where we could try to return a frame while libfc