]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
scsi: bnx2fc: Add filters to the non-offload FCoE receive path.
authorChad Dupuis <chad.dupuis@cavium.com>
Mon, 26 Jun 2017 15:59:32 +0000 (08:59 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 28 Jun 2017 01:39:09 +0000 (21:39 -0400)
Add the following filters to bnx2fc_recv_frame():

1. Filter out invalid packets
    - eth->dest_mac[3] matches FC frame's D_ID
2. Filter out packets that are not from our connected target
    - In FIP_ST_ENABLED mode
    - eth->src_mac matches fcoe_ctlr->dest_addr
3. Filter out packets where if d_id of the packet doesn't belong to
   the device when one is already assigned a port_id, only then this
   packet is dropped

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

index 902722dc4ce3d0d7d1a38d076458a480bc4197ff..342a316d93412ec4edfad0d919d5deef72378188 100644 (file)
@@ -522,10 +522,12 @@ static void bnx2fc_recv_frame(struct sk_buff *skb)
        struct fcoe_crc_eof crc_eof;
        struct fc_frame *fp;
        struct fc_lport *vn_port;
-       struct fcoe_port *port;
+       struct fcoe_port *port, *phys_port;
        u8 *mac = NULL;
        u8 *dest_mac = NULL;
        struct fcoe_hdr *hp;
+       struct bnx2fc_interface *interface;
+       struct fcoe_ctlr *ctlr;
 
        fr = fcoe_dev_from_skb(skb);
        lport = fr->fr_dev;
@@ -561,8 +563,19 @@ static void bnx2fc_recv_frame(struct sk_buff *skb)
                return;
        }
 
+       phys_port = lport_priv(lport);
+       interface = phys_port->priv;
+       ctlr = bnx2fc_to_ctlr(interface);
+
        fh = fc_frame_header_get(fp);
 
+       if (ntoh24(&dest_mac[3]) != ntoh24(fh->fh_d_id)) {
+               BNX2FC_HBA_DBG(lport, "FC frame d_id mismatch with MAC %pM.\n",
+                   dest_mac);
+               kfree_skb(skb);
+               return;
+       }
+
        vn_port = fc_vport_id_lookup(lport, ntoh24(fh->fh_d_id));
        if (vn_port) {
                port = lport_priv(vn_port);
@@ -572,6 +585,14 @@ static void bnx2fc_recv_frame(struct sk_buff *skb)
                        return;
                }
        }
+       if (ctlr->state) {
+               if (!ether_addr_equal(mac, ctlr->dest_addr)) {
+                       BNX2FC_HBA_DBG(lport, "Wrong source address: mac:%pM dest_addr:%pM.\n",
+                           mac, ctlr->dest_addr);
+                       kfree_skb(skb);
+                       return;
+               }
+       }
        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 */
@@ -597,6 +618,18 @@ static void bnx2fc_recv_frame(struct sk_buff *skb)
                return;
        }
 
+       /*
+        * 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) {
+               BNX2FC_HBA_DBG(lport, "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;
+       }
+
        stats = per_cpu_ptr(lport->stats, smp_processor_id());
        stats->RxFrames++;
        stats->RxWords += fr_len / FCOE_WORD_TO_BYTE;