summaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorChad Dupuis <chad.dupuis@cavium.com>2017-06-26 17:59:32 +0200
committerMartin K. Petersen <martin.petersen@oracle.com>2017-06-28 03:39:09 +0200
commit56ffd3a0500e3b0c133da451036074fd0a8c3f1c (patch)
treee689caac5ae7c7b56b2b880e52e596d1511151d6 /drivers/scsi
parentscsi: default to scsi-mq (diff)
downloadlinux-56ffd3a0500e3b0c133da451036074fd0a8c3f1c.tar.xz
linux-56ffd3a0500e3b0c133da451036074fd0a8c3f1c.zip
scsi: bnx2fc: Add filters to the non-offload FCoE receive path.
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>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/bnx2fc/bnx2fc_fcoe.c35
1 files changed, 34 insertions, 1 deletions
diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
index 902722dc4ce3..342a316d9341 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;