diff options
author | Mark Rustad <mark.d.rustad@intel.com> | 2013-05-18 00:01:36 -0400 |
---|---|---|
committer | Robert Love <robert.w.love@intel.com> | 2013-07-09 12:29:14 -0400 |
commit | e0335f67a281cb8eb11868e614ee9390fbbe9b1d (patch) | |
tree | ff3fd672241c138b686bd155917ff21c49f6f60d | |
parent | 8bb495e3f02401ee6f76d1b1d77f3ac9f079e376 (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.c | 27 |
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 | ||
929 | static bool | ||
930 | fc_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. |