diff options
author | Chad Dupuis <chad.dupuis@cavium.com> | 2017-06-26 08:59:32 -0700 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2017-06-27 21:39:09 -0400 |
commit | 56ffd3a0500e3b0c133da451036074fd0a8c3f1c (patch) | |
tree | e689caac5ae7c7b56b2b880e52e596d1511151d6 /drivers/scsi | |
parent | 5c279bd9e40624f4ab6e688671026d6005b066fa (diff) |
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.c | 35 |
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; |