Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e0335f67 authored by Mark Rustad's avatar Mark Rustad Committed by Robert Love
Browse files

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: default avatarMark Rustad <mark.d.rustad@intel.com>
Reviewed-by: default avatarYi Zou <yi.zou@intel.com>
Tested-by: default avatarJack Morgan <jack.morgan@intel.com>
Signed-off-by: default avatarRobert Love <robert.w.love@intel.com>
parent 8bb495e3
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -926,6 +926,20 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp,
	kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy);
}

static bool
fc_rport_compatible_roles(struct fc_lport *lport, struct fc_rport_priv *rdata)
{
	if (rdata->ids.roles == FC_PORT_ROLE_UNKNOWN)
		return true;
	if ((rdata->ids.roles & FC_PORT_ROLE_FCP_TARGET) &&
	    (lport->service_params & FCP_SPPF_INIT_FCN))
		return true;
	if ((rdata->ids.roles & FC_PORT_ROLE_FCP_INITIATOR) &&
	    (lport->service_params & FCP_SPPF_TARG_FCN))
		return true;
	return false;
}

/**
 * fc_rport_enter_plogi() - Send Port Login (PLOGI) request
 * @rdata: The remote port to send a PLOGI to
@@ -938,6 +952,12 @@ static void fc_rport_enter_plogi(struct fc_rport_priv *rdata)
	struct fc_lport *lport = rdata->local_port;
	struct fc_frame *fp;

	if (!fc_rport_compatible_roles(lport, rdata)) {
		FC_RPORT_DBG(rdata, "PLOGI suppressed for incompatible role\n");
		fc_rport_state_enter(rdata, RPORT_ST_PLOGI_WAIT);
		return;
	}

	FC_RPORT_DBG(rdata, "Port entered PLOGI state from %s state\n",
		     fc_rport_state(rdata));

@@ -1646,6 +1666,13 @@ static void fc_rport_recv_plogi_req(struct fc_lport *lport,
		rjt_data.explan = ELS_EXPL_NONE;
		goto reject;
	}
	if (!fc_rport_compatible_roles(lport, rdata)) {
		FC_RPORT_DBG(rdata, "Received PLOGI for incompatible role\n");
		mutex_unlock(&rdata->rp_mutex);
		rjt_data.reason = ELS_RJT_LOGIC;
		rjt_data.explan = ELS_EXPL_NONE;
		goto reject;
	}

	/*
	 * Get session payload size from incoming PLOGI.