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.dup...@cavium.com>
---
 drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 35 ++++++++++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c 
b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
index b025ee5..2025510 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
@@ -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;
-- 
1.8.5.6

Reply via email to