aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Rustad <mark.d.rustad@intel.com>2013-05-18 00:01:36 -0400
committerRobert Love <robert.w.love@intel.com>2013-07-09 12:29:14 -0400
commite0335f67a281cb8eb11868e614ee9390fbbe9b1d (patch)
treeff3fd672241c138b686bd155917ff21c49f6f60d
parent8bb495e3f02401ee6f76d1b1d77f3ac9f079e376 (diff)
libfc: Reject PLOGI from nodes with incompatible role
Reject a PLOGI from a node with an incompatible role, that is, initiator-to-initiator or target-to-target. Signed-off-by: Mark Rustad <mark.d.rustad@intel.com> Reviewed-by: Yi Zou <yi.zou@intel.com> Tested-by: Jack Morgan <jack.morgan@intel.com> Signed-off-by: Robert Love <robert.w.love@intel.com>
-rw-r--r--drivers/scsi/libfc/fc_rport.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index 6bbb9447b75d..c710d908fda6 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -926,6 +926,20 @@ err:
926 kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy); 926 kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy);
927} 927}
928 928
929static bool
930fc_rport_compatible_roles(struct fc_lport *lport, struct fc_rport_priv *rdata)
931{
932 if (rdata->ids.roles == FC_PORT_ROLE_UNKNOWN)
933 return true;
934 if ((rdata->ids.roles & FC_PORT_ROLE_FCP_TARGET) &&
935 (lport->service_params & FCP_SPPF_INIT_FCN))
936 return true;
937 if ((rdata->ids.roles & FC_PORT_ROLE_FCP_INITIATOR) &&
938 (lport->service_params & FCP_SPPF_TARG_FCN))
939 return true;
940 return false;
941}
942
929/** 943/**
930 * fc_rport_enter_plogi() - Send Port Login (PLOGI) request 944 * fc_rport_enter_plogi() - Send Port Login (PLOGI) request
931 * @rdata: The remote port to send a PLOGI to 945 * @rdata: The remote port to send a PLOGI to
@@ -938,6 +952,12 @@ static void fc_rport_enter_plogi(struct fc_rport_priv *rdata)
938 struct fc_lport *lport = rdata->local_port; 952 struct fc_lport *lport = rdata->local_port;
939 struct fc_frame *fp; 953 struct fc_frame *fp;
940 954
955 if (!fc_rport_compatible_roles(lport, rdata)) {
956 FC_RPORT_DBG(rdata, "PLOGI suppressed for incompatible role\n");
957 fc_rport_state_enter(rdata, RPORT_ST_PLOGI_WAIT);
958 return;
959 }
960
941 FC_RPORT_DBG(rdata, "Port entered PLOGI state from %s state\n", 961 FC_RPORT_DBG(rdata, "Port entered PLOGI state from %s state\n",
942 fc_rport_state(rdata)); 962 fc_rport_state(rdata));
943 963
@@ -1646,6 +1666,13 @@ static void fc_rport_recv_plogi_req(struct fc_lport *lport,
1646 rjt_data.explan = ELS_EXPL_NONE; 1666 rjt_data.explan = ELS_EXPL_NONE;
1647 goto reject; 1667 goto reject;
1648 } 1668 }
1669 if (!fc_rport_compatible_roles(lport, rdata)) {
1670 FC_RPORT_DBG(rdata, "Received PLOGI for incompatible role\n");
1671 mutex_unlock(&rdata->rp_mutex);
1672 rjt_data.reason = ELS_RJT_LOGIC;
1673 rjt_data.explan = ELS_EXPL_NONE;
1674 goto reject;
1675 }
1649 1676
1650 /* 1677 /*
1651 * Get session payload size from incoming PLOGI. 1678 * Get session payload size from incoming PLOGI.