summaryrefslogtreecommitdiff
path: root/drivers/scsi/qedf/qedf_main.c
diff options
context:
space:
mode:
authorChad Dupuis <chad.dupuis@cavium.com>2017-05-31 16:33:57 +0300
committerMartin K. Petersen <martin.petersen@oracle.com>2017-06-13 03:48:06 +0300
commit384d5a9b412ea0fb60f999c13d39a1f007d87730 (patch)
tree128fc4e8cfe24c0824f530d1ce3d6db32054b4b8 /drivers/scsi/qedf/qedf_main.c
parentb09fdc3aac6acc20587713e306692b12d31a2008 (diff)
downloadlinux-384d5a9b412ea0fb60f999c13d39a1f007d87730.tar.xz
scsi: qedf: Add non-offload receive filters.
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>
Diffstat (limited to 'drivers/scsi/qedf/qedf_main.c')
-rw-r--r--drivers/scsi/qedf/qedf_main.c43
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c
index ef0dc566d70f..b7d17e177cf0 100644
--- a/drivers/scsi/qedf/qedf_main.c
+++ b/drivers/scsi/qedf/qedf_main.c
@@ -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