xref: /freebsd/contrib/ofed/opensm/opensm/osm_sminfo_rcv.c (revision 87181516ef48be852d5e5fee53c6e0dbfc62f21e)
1*d6b92ffaSHans Petter Selasky /*
2*d6b92ffaSHans Petter Selasky  * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
3*d6b92ffaSHans Petter Selasky  * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
4*d6b92ffaSHans Petter Selasky  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
5*d6b92ffaSHans Petter Selasky  * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
6*d6b92ffaSHans Petter Selasky  *
7*d6b92ffaSHans Petter Selasky  * This software is available to you under a choice of one of two
8*d6b92ffaSHans Petter Selasky  * licenses.  You may choose to be licensed under the terms of the GNU
9*d6b92ffaSHans Petter Selasky  * General Public License (GPL) Version 2, available from the file
10*d6b92ffaSHans Petter Selasky  * COPYING in the main directory of this source tree, or the
11*d6b92ffaSHans Petter Selasky  * OpenIB.org BSD license below:
12*d6b92ffaSHans Petter Selasky  *
13*d6b92ffaSHans Petter Selasky  *     Redistribution and use in source and binary forms, with or
14*d6b92ffaSHans Petter Selasky  *     without modification, are permitted provided that the following
15*d6b92ffaSHans Petter Selasky  *     conditions are met:
16*d6b92ffaSHans Petter Selasky  *
17*d6b92ffaSHans Petter Selasky  *      - Redistributions of source code must retain the above
18*d6b92ffaSHans Petter Selasky  *        copyright notice, this list of conditions and the following
19*d6b92ffaSHans Petter Selasky  *        disclaimer.
20*d6b92ffaSHans Petter Selasky  *
21*d6b92ffaSHans Petter Selasky  *      - Redistributions in binary form must reproduce the above
22*d6b92ffaSHans Petter Selasky  *        copyright notice, this list of conditions and the following
23*d6b92ffaSHans Petter Selasky  *        disclaimer in the documentation and/or other materials
24*d6b92ffaSHans Petter Selasky  *        provided with the distribution.
25*d6b92ffaSHans Petter Selasky  *
26*d6b92ffaSHans Petter Selasky  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27*d6b92ffaSHans Petter Selasky  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28*d6b92ffaSHans Petter Selasky  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29*d6b92ffaSHans Petter Selasky  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
30*d6b92ffaSHans Petter Selasky  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
31*d6b92ffaSHans Petter Selasky  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
32*d6b92ffaSHans Petter Selasky  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33*d6b92ffaSHans Petter Selasky  * SOFTWARE.
34*d6b92ffaSHans Petter Selasky  *
35*d6b92ffaSHans Petter Selasky  */
36*d6b92ffaSHans Petter Selasky 
37*d6b92ffaSHans Petter Selasky /*
38*d6b92ffaSHans Petter Selasky  * Abstract:
39*d6b92ffaSHans Petter Selasky  *    Implementation of osm_sminfo_rcv_t.
40*d6b92ffaSHans Petter Selasky  * This object represents the SMInfo Receiver object.
41*d6b92ffaSHans Petter Selasky  * This object is part of the opensm family of objects.
42*d6b92ffaSHans Petter Selasky  */
43*d6b92ffaSHans Petter Selasky 
44*d6b92ffaSHans Petter Selasky #if HAVE_CONFIG_H
45*d6b92ffaSHans Petter Selasky #  include <config.h>
46*d6b92ffaSHans Petter Selasky #endif				/* HAVE_CONFIG_H */
47*d6b92ffaSHans Petter Selasky 
48*d6b92ffaSHans Petter Selasky #include <stdlib.h>
49*d6b92ffaSHans Petter Selasky #include <string.h>
50*d6b92ffaSHans Petter Selasky #include <iba/ib_types.h>
51*d6b92ffaSHans Petter Selasky #include <complib/cl_qmap.h>
52*d6b92ffaSHans Petter Selasky #include <complib/cl_passivelock.h>
53*d6b92ffaSHans Petter Selasky #include <complib/cl_debug.h>
54*d6b92ffaSHans Petter Selasky #include <opensm/osm_file_ids.h>
55*d6b92ffaSHans Petter Selasky #define FILE_ID OSM_FILE_SMINFO_RCV_C
56*d6b92ffaSHans Petter Selasky #include <opensm/osm_madw.h>
57*d6b92ffaSHans Petter Selasky #include <opensm/osm_log.h>
58*d6b92ffaSHans Petter Selasky #include <opensm/osm_node.h>
59*d6b92ffaSHans Petter Selasky #include <opensm/osm_helper.h>
60*d6b92ffaSHans Petter Selasky #include <opensm/osm_subnet.h>
61*d6b92ffaSHans Petter Selasky #include <opensm/osm_sm.h>
62*d6b92ffaSHans Petter Selasky #include <opensm/osm_opensm.h>
63*d6b92ffaSHans Petter Selasky 
64*d6b92ffaSHans Petter Selasky /**********************************************************************
65*d6b92ffaSHans Petter Selasky  Return TRUE if the remote sm given (by ib_sm_info_t) is higher,
66*d6b92ffaSHans Petter Selasky  return FALSE otherwise.
67*d6b92ffaSHans Petter Selasky  By higher - we mean: SM with higher priority or with same priority
68*d6b92ffaSHans Petter Selasky  and lower GUID.
69*d6b92ffaSHans Petter Selasky **********************************************************************/
smi_rcv_remote_sm_is_higher(IN osm_sm_t * sm,IN const ib_sm_info_t * p_rem_smi)70*d6b92ffaSHans Petter Selasky static boolean_t smi_rcv_remote_sm_is_higher(IN osm_sm_t * sm,
71*d6b92ffaSHans Petter Selasky 					     IN const ib_sm_info_t * p_rem_smi)
72*d6b92ffaSHans Petter Selasky {
73*d6b92ffaSHans Petter Selasky 	return osm_sm_is_greater_than(ib_sminfo_get_priority(p_rem_smi),
74*d6b92ffaSHans Petter Selasky 				      p_rem_smi->guid,
75*d6b92ffaSHans Petter Selasky 				      sm->p_subn->opt.sm_priority,
76*d6b92ffaSHans Petter Selasky 				      sm->p_subn->sm_port_guid);
77*d6b92ffaSHans Petter Selasky 
78*d6b92ffaSHans Petter Selasky }
79*d6b92ffaSHans Petter Selasky 
smi_rcv_process_get_request(IN osm_sm_t * sm,IN const osm_madw_t * p_madw,IN boolean_t fill_sm_key)80*d6b92ffaSHans Petter Selasky static void smi_rcv_process_get_request(IN osm_sm_t * sm,
81*d6b92ffaSHans Petter Selasky 					IN const osm_madw_t * p_madw,
82*d6b92ffaSHans Petter Selasky 					IN boolean_t fill_sm_key)
83*d6b92ffaSHans Petter Selasky {
84*d6b92ffaSHans Petter Selasky 	uint8_t payload[IB_SMP_DATA_SIZE];
85*d6b92ffaSHans Petter Selasky 	ib_sm_info_t *p_smi = (ib_sm_info_t *) payload;
86*d6b92ffaSHans Petter Selasky 	ib_api_status_t status;
87*d6b92ffaSHans Petter Selasky 
88*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(sm->p_log);
89*d6b92ffaSHans Petter Selasky 
90*d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_madw);
91*d6b92ffaSHans Petter Selasky 
92*d6b92ffaSHans Petter Selasky 	/* No real need to grab the lock for this function. */
93*d6b92ffaSHans Petter Selasky 	memset(payload, 0, sizeof(payload));
94*d6b92ffaSHans Petter Selasky 
95*d6b92ffaSHans Petter Selasky 	CL_ASSERT(osm_madw_get_smp_ptr(p_madw)->method == IB_MAD_METHOD_GET);
96*d6b92ffaSHans Petter Selasky 
97*d6b92ffaSHans Petter Selasky 	p_smi->guid = sm->p_subn->sm_port_guid;
98*d6b92ffaSHans Petter Selasky 	p_smi->act_count = cl_hton32(sm->p_subn->p_osm->stats.qp0_mads_sent);
99*d6b92ffaSHans Petter Selasky 	p_smi->pri_state = (uint8_t) (sm->p_subn->sm_state |
100*d6b92ffaSHans Petter Selasky 				      sm->p_subn->opt.sm_priority << 4);
101*d6b92ffaSHans Petter Selasky 	p_smi->sm_key = fill_sm_key ? sm->p_subn->opt.sm_key : 0;
102*d6b92ffaSHans Petter Selasky 
103*d6b92ffaSHans Petter Selasky 	status = osm_resp_send(sm, p_madw, 0, payload);
104*d6b92ffaSHans Petter Selasky 	if (status != IB_SUCCESS) {
105*d6b92ffaSHans Petter Selasky 		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 2F02: "
106*d6b92ffaSHans Petter Selasky 			"Error sending SMInfo response (%s)\n",
107*d6b92ffaSHans Petter Selasky 			ib_get_err_str(status));
108*d6b92ffaSHans Petter Selasky 		goto Exit;
109*d6b92ffaSHans Petter Selasky 	}
110*d6b92ffaSHans Petter Selasky 
111*d6b92ffaSHans Petter Selasky Exit:
112*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(sm->p_log);
113*d6b92ffaSHans Petter Selasky }
114*d6b92ffaSHans Petter Selasky 
115*d6b92ffaSHans Petter Selasky /**********************************************************************
116*d6b92ffaSHans Petter Selasky  * Check if the p_smp received is legal.
117*d6b92ffaSHans Petter Selasky  * Current checks:
118*d6b92ffaSHans Petter Selasky  *   MADHeader:AttributeModifier of ACKNOWLEDGE that was not sent by a
119*d6b92ffaSHans Petter Selasky  *             Standby SM.
120*d6b92ffaSHans Petter Selasky  *   MADHeader:AttributeModifiers of HANDOVER/DISABLE/STANDBY/DISCOVER
121*d6b92ffaSHans Petter Selasky  *             that was not sent by a Master SM.
122*d6b92ffaSHans Petter Selasky  * FUTURE - TO DO:
123*d6b92ffaSHans Petter Selasky  *   Check that the SM_Key matches.
124*d6b92ffaSHans Petter Selasky  **********************************************************************/
smi_rcv_check_set_req_legality(IN const ib_smp_t * p_smp)125*d6b92ffaSHans Petter Selasky static ib_api_status_t smi_rcv_check_set_req_legality(IN const ib_smp_t * p_smp)
126*d6b92ffaSHans Petter Selasky {
127*d6b92ffaSHans Petter Selasky 	ib_sm_info_t *p_smi;
128*d6b92ffaSHans Petter Selasky 
129*d6b92ffaSHans Petter Selasky 	p_smi = ib_smp_get_payload_ptr(p_smp);
130*d6b92ffaSHans Petter Selasky 
131*d6b92ffaSHans Petter Selasky 	if (p_smp->attr_mod == IB_SMINFO_ATTR_MOD_ACKNOWLEDGE) {
132*d6b92ffaSHans Petter Selasky 		if (ib_sminfo_get_state(p_smi) == IB_SMINFO_STATE_STANDBY)
133*d6b92ffaSHans Petter Selasky 			return IB_SUCCESS;
134*d6b92ffaSHans Petter Selasky 	} else if (p_smp->attr_mod == IB_SMINFO_ATTR_MOD_HANDOVER ||
135*d6b92ffaSHans Petter Selasky 		   p_smp->attr_mod == IB_SMINFO_ATTR_MOD_DISABLE ||
136*d6b92ffaSHans Petter Selasky 		   p_smp->attr_mod == IB_SMINFO_ATTR_MOD_STANDBY ||
137*d6b92ffaSHans Petter Selasky 		   p_smp->attr_mod == IB_SMINFO_ATTR_MOD_DISCOVER) {
138*d6b92ffaSHans Petter Selasky 		if (ib_sminfo_get_state(p_smi) == IB_SMINFO_STATE_MASTER)
139*d6b92ffaSHans Petter Selasky 			return IB_SUCCESS;
140*d6b92ffaSHans Petter Selasky 	}
141*d6b92ffaSHans Petter Selasky 
142*d6b92ffaSHans Petter Selasky 	return IB_INVALID_PARAMETER;
143*d6b92ffaSHans Petter Selasky }
144*d6b92ffaSHans Petter Selasky 
smi_rcv_process_set_request(IN osm_sm_t * sm,IN const osm_madw_t * p_madw)145*d6b92ffaSHans Petter Selasky static void smi_rcv_process_set_request(IN osm_sm_t * sm,
146*d6b92ffaSHans Petter Selasky 					IN const osm_madw_t * p_madw)
147*d6b92ffaSHans Petter Selasky {
148*d6b92ffaSHans Petter Selasky 	uint8_t payload[IB_SMP_DATA_SIZE];
149*d6b92ffaSHans Petter Selasky 	ib_smp_t *p_smp;
150*d6b92ffaSHans Petter Selasky 	ib_sm_info_t *p_smi = (ib_sm_info_t *) payload;
151*d6b92ffaSHans Petter Selasky 	ib_sm_info_t *sm_smi;
152*d6b92ffaSHans Petter Selasky 	ib_api_status_t status;
153*d6b92ffaSHans Petter Selasky 	osm_sm_signal_t sm_signal;
154*d6b92ffaSHans Petter Selasky 
155*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(sm->p_log);
156*d6b92ffaSHans Petter Selasky 
157*d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_madw);
158*d6b92ffaSHans Petter Selasky 
159*d6b92ffaSHans Petter Selasky 	memset(payload, 0, sizeof(payload));
160*d6b92ffaSHans Petter Selasky 
161*d6b92ffaSHans Petter Selasky 	p_smp = osm_madw_get_smp_ptr(p_madw);
162*d6b92ffaSHans Petter Selasky 	sm_smi = ib_smp_get_payload_ptr(p_smp);
163*d6b92ffaSHans Petter Selasky 
164*d6b92ffaSHans Petter Selasky 	if (p_smp->method != IB_MAD_METHOD_SET) {
165*d6b92ffaSHans Petter Selasky 		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 2F03: "
166*d6b92ffaSHans Petter Selasky 			"Unsupported set method 0x%X\n", p_smp->method);
167*d6b92ffaSHans Petter Selasky 		goto Exit;
168*d6b92ffaSHans Petter Selasky 	}
169*d6b92ffaSHans Petter Selasky 
170*d6b92ffaSHans Petter Selasky 	CL_PLOCK_ACQUIRE(sm->p_lock);
171*d6b92ffaSHans Petter Selasky 
172*d6b92ffaSHans Petter Selasky 	p_smi->guid = sm->p_subn->sm_port_guid;
173*d6b92ffaSHans Petter Selasky 	p_smi->act_count = cl_hton32(sm->p_subn->p_osm->stats.qp0_mads_sent);
174*d6b92ffaSHans Petter Selasky 	p_smi->pri_state = (uint8_t) (sm->p_subn->sm_state |
175*d6b92ffaSHans Petter Selasky 				      sm->p_subn->opt.sm_priority << 4);
176*d6b92ffaSHans Petter Selasky 	p_smi->sm_key = sm->p_subn->opt.sm_key;
177*d6b92ffaSHans Petter Selasky 
178*d6b92ffaSHans Petter Selasky 	/* Check the legality of the packet */
179*d6b92ffaSHans Petter Selasky 	status = smi_rcv_check_set_req_legality(p_smp);
180*d6b92ffaSHans Petter Selasky 	if (status != IB_SUCCESS) {
181*d6b92ffaSHans Petter Selasky 		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 2F04: "
182*d6b92ffaSHans Petter Selasky 			"Check legality failed. AttributeModifier:0x%X RemoteState:%s\n",
183*d6b92ffaSHans Petter Selasky 			p_smp->attr_mod,
184*d6b92ffaSHans Petter Selasky 			osm_get_sm_mgr_state_str(ib_sminfo_get_state(sm_smi)));
185*d6b92ffaSHans Petter Selasky 		status = osm_resp_send(sm, p_madw, 7, payload);
186*d6b92ffaSHans Petter Selasky 		if (status != IB_SUCCESS)
187*d6b92ffaSHans Petter Selasky 			OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 2F05: "
188*d6b92ffaSHans Petter Selasky 				"Error sending SMInfo response (%s)\n",
189*d6b92ffaSHans Petter Selasky 				ib_get_err_str(status));
190*d6b92ffaSHans Petter Selasky 		CL_PLOCK_RELEASE(sm->p_lock);
191*d6b92ffaSHans Petter Selasky 		goto Exit;
192*d6b92ffaSHans Petter Selasky 	}
193*d6b92ffaSHans Petter Selasky 
194*d6b92ffaSHans Petter Selasky 	/* translate from IB_SMINFO_ATTR to OSM_SM_SIGNAL */
195*d6b92ffaSHans Petter Selasky 	switch (p_smp->attr_mod) {
196*d6b92ffaSHans Petter Selasky 	case IB_SMINFO_ATTR_MOD_HANDOVER:
197*d6b92ffaSHans Petter Selasky 		sm_signal = OSM_SM_SIGNAL_HANDOVER;
198*d6b92ffaSHans Petter Selasky 		break;
199*d6b92ffaSHans Petter Selasky 	case IB_SMINFO_ATTR_MOD_ACKNOWLEDGE:
200*d6b92ffaSHans Petter Selasky 		sm_signal = OSM_SM_SIGNAL_ACKNOWLEDGE;
201*d6b92ffaSHans Petter Selasky 		break;
202*d6b92ffaSHans Petter Selasky 	case IB_SMINFO_ATTR_MOD_DISABLE:
203*d6b92ffaSHans Petter Selasky 		sm_signal = OSM_SM_SIGNAL_DISABLE;
204*d6b92ffaSHans Petter Selasky 		break;
205*d6b92ffaSHans Petter Selasky 	case IB_SMINFO_ATTR_MOD_STANDBY:
206*d6b92ffaSHans Petter Selasky 		sm_signal = OSM_SM_SIGNAL_STANDBY;
207*d6b92ffaSHans Petter Selasky 		break;
208*d6b92ffaSHans Petter Selasky 	case IB_SMINFO_ATTR_MOD_DISCOVER:
209*d6b92ffaSHans Petter Selasky 		sm_signal = OSM_SM_SIGNAL_DISCOVER;
210*d6b92ffaSHans Petter Selasky 		break;
211*d6b92ffaSHans Petter Selasky 	default:
212*d6b92ffaSHans Petter Selasky 		/*
213*d6b92ffaSHans Petter Selasky 		   This code shouldn't be reached - checked in the
214*d6b92ffaSHans Petter Selasky 		   check legality
215*d6b92ffaSHans Petter Selasky 		 */
216*d6b92ffaSHans Petter Selasky 		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 2F06: "
217*d6b92ffaSHans Petter Selasky 			"THIS CODE SHOULD NOT BE REACHED!!\n");
218*d6b92ffaSHans Petter Selasky 		CL_PLOCK_RELEASE(sm->p_lock);
219*d6b92ffaSHans Petter Selasky 		goto Exit;
220*d6b92ffaSHans Petter Selasky 	}
221*d6b92ffaSHans Petter Selasky 
222*d6b92ffaSHans Petter Selasky 	CL_PLOCK_RELEASE(sm->p_lock);
223*d6b92ffaSHans Petter Selasky 
224*d6b92ffaSHans Petter Selasky 	/* check legality of the needed transition in the SM state machine */
225*d6b92ffaSHans Petter Selasky 	status = osm_sm_state_mgr_check_legality(sm, sm_signal);
226*d6b92ffaSHans Petter Selasky 	if (status != IB_SUCCESS) {
227*d6b92ffaSHans Petter Selasky 		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 2F07: "
228*d6b92ffaSHans Petter Selasky 			"Failed check of legality of needed SM transition. "
229*d6b92ffaSHans Petter Selasky 			"AttributeModifier:0x%X RemoteState:%s\n",
230*d6b92ffaSHans Petter Selasky 			p_smp->attr_mod,
231*d6b92ffaSHans Petter Selasky 			osm_get_sm_mgr_state_str(ib_sminfo_get_state(sm_smi)));
232*d6b92ffaSHans Petter Selasky 		status = osm_resp_send(sm, p_madw, 7, payload);
233*d6b92ffaSHans Petter Selasky 		if (status != IB_SUCCESS)
234*d6b92ffaSHans Petter Selasky 			OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 2F08: "
235*d6b92ffaSHans Petter Selasky 				"Error sending SMInfo response (%s)\n",
236*d6b92ffaSHans Petter Selasky 				ib_get_err_str(status));
237*d6b92ffaSHans Petter Selasky 		goto Exit;
238*d6b92ffaSHans Petter Selasky 	}
239*d6b92ffaSHans Petter Selasky 
240*d6b92ffaSHans Petter Selasky 	/* the SubnSet(SMInfo) command is ok. Send a response. */
241*d6b92ffaSHans Petter Selasky 	status = osm_resp_send(sm, p_madw, 0, payload);
242*d6b92ffaSHans Petter Selasky 	if (status != IB_SUCCESS)
243*d6b92ffaSHans Petter Selasky 		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 2F09: "
244*d6b92ffaSHans Petter Selasky 			"Error sending SMInfo response (%s)\n",
245*d6b92ffaSHans Petter Selasky 			ib_get_err_str(status));
246*d6b92ffaSHans Petter Selasky 
247*d6b92ffaSHans Petter Selasky 	/* it is a legal packet - act according to it */
248*d6b92ffaSHans Petter Selasky 
249*d6b92ffaSHans Petter Selasky 	/* if the AttributeModifier is STANDBY - need to save on the sm in */
250*d6b92ffaSHans Petter Selasky 	/* the master_sm_guid variable - the guid of the current master. */
251*d6b92ffaSHans Petter Selasky 	if (p_smp->attr_mod == IB_SMINFO_ATTR_MOD_STANDBY) {
252*d6b92ffaSHans Petter Selasky 		OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
253*d6b92ffaSHans Petter Selasky 			"Received a STANDBY signal. Updating "
254*d6b92ffaSHans Petter Selasky 			"sm_state_mgr master_guid: 0x%016" PRIx64 "\n",
255*d6b92ffaSHans Petter Selasky 			cl_ntoh64(sm_smi->guid));
256*d6b92ffaSHans Petter Selasky 		CL_PLOCK_EXCL_ACQUIRE(sm->p_lock);
257*d6b92ffaSHans Petter Selasky 		sm->master_sm_guid = sm_smi->guid;
258*d6b92ffaSHans Petter Selasky 		CL_PLOCK_RELEASE(sm->p_lock);
259*d6b92ffaSHans Petter Selasky 	}
260*d6b92ffaSHans Petter Selasky 
261*d6b92ffaSHans Petter Selasky 	status = osm_sm_state_mgr_process(sm, sm_signal);
262*d6b92ffaSHans Petter Selasky 
263*d6b92ffaSHans Petter Selasky 	if (status != IB_SUCCESS)
264*d6b92ffaSHans Petter Selasky 		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 2F10: "
265*d6b92ffaSHans Petter Selasky 			"Error in SM state transition (%s)\n",
266*d6b92ffaSHans Petter Selasky 			ib_get_err_str(status));
267*d6b92ffaSHans Petter Selasky 
268*d6b92ffaSHans Petter Selasky Exit:
269*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(sm->p_log);
270*d6b92ffaSHans Petter Selasky }
271*d6b92ffaSHans Petter Selasky 
smi_rcv_process_get_sm(IN osm_sm_t * sm,IN const osm_remote_sm_t * p_sm,boolean_t light_sweep)272*d6b92ffaSHans Petter Selasky static void smi_rcv_process_get_sm(IN osm_sm_t * sm,
273*d6b92ffaSHans Petter Selasky 				   IN const osm_remote_sm_t * p_sm,
274*d6b92ffaSHans Petter Selasky 				   boolean_t light_sweep)
275*d6b92ffaSHans Petter Selasky {
276*d6b92ffaSHans Petter Selasky 	const ib_sm_info_t *p_smi;
277*d6b92ffaSHans Petter Selasky 
278*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(sm->p_log);
279*d6b92ffaSHans Petter Selasky 
280*d6b92ffaSHans Petter Selasky 	p_smi = &p_sm->smi;
281*d6b92ffaSHans Petter Selasky 
282*d6b92ffaSHans Petter Selasky 	OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
283*d6b92ffaSHans Petter Selasky 		"Detected SM 0x%016" PRIx64 " in state %u (%s)\n",
284*d6b92ffaSHans Petter Selasky 		cl_ntoh64(p_smi->guid), ib_sminfo_get_state(p_smi),
285*d6b92ffaSHans Petter Selasky 		osm_get_sm_mgr_state_str(ib_sminfo_get_state(p_smi)));
286*d6b92ffaSHans Petter Selasky 
287*d6b92ffaSHans Petter Selasky 	/* Check the state of this SM vs. our own. */
288*d6b92ffaSHans Petter Selasky 	switch (sm->p_subn->sm_state) {
289*d6b92ffaSHans Petter Selasky 	case IB_SMINFO_STATE_NOTACTIVE:
290*d6b92ffaSHans Petter Selasky 		break;
291*d6b92ffaSHans Petter Selasky 
292*d6b92ffaSHans Petter Selasky 	case IB_SMINFO_STATE_DISCOVERING:
293*d6b92ffaSHans Petter Selasky 		switch (ib_sminfo_get_state(p_smi)) {
294*d6b92ffaSHans Petter Selasky 		case IB_SMINFO_STATE_NOTACTIVE:
295*d6b92ffaSHans Petter Selasky 			break;
296*d6b92ffaSHans Petter Selasky 		case IB_SMINFO_STATE_MASTER:
297*d6b92ffaSHans Petter Selasky 			sm->master_sm_found = 1;
298*d6b92ffaSHans Petter Selasky 			/* save on the sm the guid of the current master. */
299*d6b92ffaSHans Petter Selasky 			OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
300*d6b92ffaSHans Petter Selasky 				"Found master SM. Updating sm_state_mgr master_guid: 0x%016"
301*d6b92ffaSHans Petter Selasky 				PRIx64 "\n", cl_ntoh64(p_smi->guid));
302*d6b92ffaSHans Petter Selasky 			sm->master_sm_guid = p_smi->guid;
303*d6b92ffaSHans Petter Selasky 			break;
304*d6b92ffaSHans Petter Selasky 		case IB_SMINFO_STATE_DISCOVERING:
305*d6b92ffaSHans Petter Selasky 		case IB_SMINFO_STATE_STANDBY:
306*d6b92ffaSHans Petter Selasky 			if (smi_rcv_remote_sm_is_higher(sm, p_smi)) {
307*d6b92ffaSHans Petter Selasky 				/* the remote is a higher sm - need to stop sweeping */
308*d6b92ffaSHans Petter Selasky 				sm->master_sm_found = 1;
309*d6b92ffaSHans Petter Selasky 				/* save on the sm the guid of the higher SM we found - */
310*d6b92ffaSHans Petter Selasky 				/* we will poll it - as long as it lives - we should be in Standby. */
311*d6b92ffaSHans Petter Selasky 				OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
312*d6b92ffaSHans Petter Selasky 					"Found higher SM. Updating sm_state_mgr master_guid:"
313*d6b92ffaSHans Petter Selasky 					" 0x%016" PRIx64 "\n",
314*d6b92ffaSHans Petter Selasky 					cl_ntoh64(p_smi->guid));
315*d6b92ffaSHans Petter Selasky 				sm->master_sm_guid = p_smi->guid;
316*d6b92ffaSHans Petter Selasky 			}
317*d6b92ffaSHans Petter Selasky 			break;
318*d6b92ffaSHans Petter Selasky 		default:
319*d6b92ffaSHans Petter Selasky 			break;
320*d6b92ffaSHans Petter Selasky 		}
321*d6b92ffaSHans Petter Selasky 		break;
322*d6b92ffaSHans Petter Selasky 
323*d6b92ffaSHans Petter Selasky 	case IB_SMINFO_STATE_STANDBY:
324*d6b92ffaSHans Petter Selasky 		/* if the guid of the SM that sent us this response is equal to the */
325*d6b92ffaSHans Petter Selasky 		/* p_sm_mgr->master_guid - then this is a signal that the polling */
326*d6b92ffaSHans Petter Selasky 		switch (ib_sminfo_get_state(p_smi)) {
327*d6b92ffaSHans Petter Selasky 		case IB_SMINFO_STATE_MASTER:
328*d6b92ffaSHans Petter Selasky 			/* This means the master is alive */
329*d6b92ffaSHans Petter Selasky 			/* Signal that to the SM state mgr */
330*d6b92ffaSHans Petter Selasky 			osm_sm_state_mgr_signal_master_is_alive(sm);
331*d6b92ffaSHans Petter Selasky 
332*d6b92ffaSHans Petter Selasky 			if (!smi_rcv_remote_sm_is_higher(sm, p_smi))
333*d6b92ffaSHans Petter Selasky 				osm_send_trap144(sm,
334*d6b92ffaSHans Petter Selasky 						 TRAP_144_MASK_SM_PRIORITY_CHANGE);
335*d6b92ffaSHans Petter Selasky 			break;
336*d6b92ffaSHans Petter Selasky 		case IB_SMINFO_STATE_STANDBY:
337*d6b92ffaSHans Petter Selasky 			/* This should be the response from the sm we are polling. */
338*d6b92ffaSHans Petter Selasky 			/* If it is - then signal master is alive */
339*d6b92ffaSHans Petter Selasky 			if (sm->master_sm_guid == p_sm->smi.guid) {
340*d6b92ffaSHans Petter Selasky 				/* Make sure that it is an SM with higher priority than us.
341*d6b92ffaSHans Petter Selasky 				   If we started polling it when it was master, and it moved
342*d6b92ffaSHans Petter Selasky 				   to standby - then it might be with a lower priority than
343*d6b92ffaSHans Petter Selasky 				   us - and then we don't want to continue polling it. */
344*d6b92ffaSHans Petter Selasky 				if (smi_rcv_remote_sm_is_higher(sm, p_smi))
345*d6b92ffaSHans Petter Selasky 					osm_sm_state_mgr_signal_master_is_alive
346*d6b92ffaSHans Petter Selasky 					    (sm);
347*d6b92ffaSHans Petter Selasky 			}
348*d6b92ffaSHans Petter Selasky 			break;
349*d6b92ffaSHans Petter Selasky 		default:
350*d6b92ffaSHans Petter Selasky 			/* any other state - do nothing */
351*d6b92ffaSHans Petter Selasky 			break;
352*d6b92ffaSHans Petter Selasky 		}
353*d6b92ffaSHans Petter Selasky 		break;
354*d6b92ffaSHans Petter Selasky 
355*d6b92ffaSHans Petter Selasky 	case IB_SMINFO_STATE_MASTER:
356*d6b92ffaSHans Petter Selasky 		switch (ib_sminfo_get_state(p_smi)) {
357*d6b92ffaSHans Petter Selasky 		case IB_SMINFO_STATE_MASTER:
358*d6b92ffaSHans Petter Selasky 			/* If this is a response due to our polling, this means that we are
359*d6b92ffaSHans Petter Selasky 			 * waiting for a handover from this SM, and it is still alive -
360*d6b92ffaSHans Petter Selasky 			 * signal that. If we detected the remote SM with higher priority
361*d6b92ffaSHans Petter Selasky 			 * we should init a heavy sweep in order to go STANDBY. If we
362*d6b92ffaSHans Petter Selasky 			 * detected a remote SM with lower priority, we should resend trap144
363*d6b92ffaSHans Petter Selasky 			 * as it might not get it and we don't want to wait for a HANDOVER
364*d6b92ffaSHans Petter Selasky 			 * forever.
365*d6b92ffaSHans Petter Selasky 			 */
366*d6b92ffaSHans Petter Selasky 			if (sm->polling_sm_guid) {
367*d6b92ffaSHans Petter Selasky 				if (smi_rcv_remote_sm_is_higher(sm, p_smi))
368*d6b92ffaSHans Petter Selasky 					sm->p_subn->force_heavy_sweep = TRUE;
369*d6b92ffaSHans Petter Selasky 				else {
370*d6b92ffaSHans Petter Selasky 					/* Update master_sm_guid to the GUID of the newly
371*d6b92ffaSHans Petter Selasky 					 * found MASTER SM and send trap 144 to it.
372*d6b92ffaSHans Petter Selasky 					 */
373*d6b92ffaSHans Petter Selasky 					sm->master_sm_guid = sm->polling_sm_guid;
374*d6b92ffaSHans Petter Selasky 					osm_send_trap144(sm, TRAP_144_MASK_SM_PRIORITY_CHANGE);
375*d6b92ffaSHans Petter Selasky 				}
376*d6b92ffaSHans Petter Selasky 				osm_sm_state_mgr_signal_master_is_alive(sm);
377*d6b92ffaSHans Petter Selasky 			} else {
378*d6b92ffaSHans Petter Selasky 				/* This is a response we got while sweeping the subnet.
379*d6b92ffaSHans Petter Selasky 				 *
380*d6b92ffaSHans Petter Selasky 				 * If this is during a heavy sweep, we will handle a case of
381*d6b92ffaSHans Petter Selasky 				 * handover needed later on, when the sweep is done and all
382*d6b92ffaSHans Petter Selasky 				 * SMs are recognized.
383*d6b92ffaSHans Petter Selasky 				 *
384*d6b92ffaSHans Petter Selasky 				 * If this is during a light sweep, initiate a heavy sweep
385*d6b92ffaSHans Petter Selasky 				 * to initiate handover scenarios.
386*d6b92ffaSHans Petter Selasky 				 *
387*d6b92ffaSHans Petter Selasky 				 * Note that it does not matter if the remote SM is lower
388*d6b92ffaSHans Petter Selasky 				 * or higher priority.  If it is lower priority, we must
389*d6b92ffaSHans Petter Selasky 				 * wait for it HANDOVER.  If it is higher priority, we need
390*d6b92ffaSHans Petter Selasky 				 * to HANDOVER to it.  Both cases are handled after doing
391*d6b92ffaSHans Petter Selasky 				 * a heavy sweep.
392*d6b92ffaSHans Petter Selasky 				 */
393*d6b92ffaSHans Petter Selasky 				if (light_sweep)
394*d6b92ffaSHans Petter Selasky 					sm->p_subn->force_heavy_sweep = TRUE;
395*d6b92ffaSHans Petter Selasky 			}
396*d6b92ffaSHans Petter Selasky 			break;
397*d6b92ffaSHans Petter Selasky 		case IB_SMINFO_STATE_STANDBY:
398*d6b92ffaSHans Petter Selasky 			if (light_sweep &&
399*d6b92ffaSHans Petter Selasky 			    smi_rcv_remote_sm_is_higher(sm, p_smi))
400*d6b92ffaSHans Petter Selasky 				sm->p_subn->force_heavy_sweep = TRUE;
401*d6b92ffaSHans Petter Selasky 			break;
402*d6b92ffaSHans Petter Selasky 		default:
403*d6b92ffaSHans Petter Selasky 			/* any other state - do nothing */
404*d6b92ffaSHans Petter Selasky 			break;
405*d6b92ffaSHans Petter Selasky 		}
406*d6b92ffaSHans Petter Selasky 		break;
407*d6b92ffaSHans Petter Selasky 
408*d6b92ffaSHans Petter Selasky 	default:
409*d6b92ffaSHans Petter Selasky 		break;
410*d6b92ffaSHans Petter Selasky 	}
411*d6b92ffaSHans Petter Selasky 
412*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(sm->p_log);
413*d6b92ffaSHans Petter Selasky }
414*d6b92ffaSHans Petter Selasky 
smi_rcv_process_get_response(IN osm_sm_t * sm,IN const osm_madw_t * p_madw)415*d6b92ffaSHans Petter Selasky static void smi_rcv_process_get_response(IN osm_sm_t * sm,
416*d6b92ffaSHans Petter Selasky 					 IN const osm_madw_t * p_madw)
417*d6b92ffaSHans Petter Selasky {
418*d6b92ffaSHans Petter Selasky 	const ib_smp_t *p_smp;
419*d6b92ffaSHans Petter Selasky 	const ib_sm_info_t *p_smi;
420*d6b92ffaSHans Petter Selasky 	cl_qmap_t *p_sm_tbl;
421*d6b92ffaSHans Petter Selasky 	osm_port_t *p_port;
422*d6b92ffaSHans Petter Selasky 	ib_net64_t port_guid;
423*d6b92ffaSHans Petter Selasky 	osm_remote_sm_t *p_sm;
424*d6b92ffaSHans Petter Selasky 	char buf[256];
425*d6b92ffaSHans Petter Selasky 
426*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(sm->p_log);
427*d6b92ffaSHans Petter Selasky 
428*d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_madw);
429*d6b92ffaSHans Petter Selasky 
430*d6b92ffaSHans Petter Selasky 	p_smp = osm_madw_get_smp_ptr(p_madw);
431*d6b92ffaSHans Petter Selasky 
432*d6b92ffaSHans Petter Selasky 	if (p_smp->method != IB_MAD_METHOD_GET_RESP) {
433*d6b92ffaSHans Petter Selasky 		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 2F11: "
434*d6b92ffaSHans Petter Selasky 			"Unsupported response method 0x%X\n", p_smp->method);
435*d6b92ffaSHans Petter Selasky 		goto Exit;
436*d6b92ffaSHans Petter Selasky 	}
437*d6b92ffaSHans Petter Selasky 
438*d6b92ffaSHans Petter Selasky 	p_smi = ib_smp_get_payload_ptr(p_smp);
439*d6b92ffaSHans Petter Selasky 	p_sm_tbl = &sm->p_subn->sm_guid_tbl;
440*d6b92ffaSHans Petter Selasky 	port_guid = p_smi->guid;
441*d6b92ffaSHans Petter Selasky 
442*d6b92ffaSHans Petter Selasky 	osm_dump_sm_info_v2(sm->p_log, p_smi, FILE_ID, OSM_LOG_DEBUG);
443*d6b92ffaSHans Petter Selasky 
444*d6b92ffaSHans Petter Selasky 	/* Check that the sm_key of the found SM is the same as ours,
445*d6b92ffaSHans Petter Selasky 	   or is zero. If not - OpenSM should ignore this SM */
446*d6b92ffaSHans Petter Selasky 	if (sm->p_subn->opt.sm_key != 0 && p_smi->sm_key != sm->p_subn->opt.sm_key) {
447*d6b92ffaSHans Petter Selasky 		if (p_smp->mgmt_class == IB_MCLASS_SUBN_DIR)
448*d6b92ffaSHans Petter Selasky 			sprint_uint8_arr(buf, sizeof(buf),
449*d6b92ffaSHans Petter Selasky 				p_smp->initial_path, p_smp->hop_count + 1);
450*d6b92ffaSHans Petter Selasky 		else
451*d6b92ffaSHans Petter Selasky 			sprintf(buf, "LID %u",
452*d6b92ffaSHans Petter Selasky 				cl_ntoh16(p_madw->mad_addr.addr_type.smi.source_lid));
453*d6b92ffaSHans Petter Selasky 		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 2F18: "
454*d6b92ffaSHans Petter Selasky 			"Got SM (%s) with sm_key 0x%016" PRIx64 " that doesn't match our "
455*d6b92ffaSHans Petter Selasky 			"local sm_key. Ignoring SMInfo\n", buf, cl_ntoh64(p_smi->sm_key));
456*d6b92ffaSHans Petter Selasky 		osm_log_v2(sm->p_log, OSM_LOG_SYS, FILE_ID,
457*d6b92ffaSHans Petter Selasky 			   "Found remote SM (%s) with non-matching sm_key\n", buf);
458*d6b92ffaSHans Petter Selasky 		goto Exit;
459*d6b92ffaSHans Petter Selasky 	}
460*d6b92ffaSHans Petter Selasky 
461*d6b92ffaSHans Petter Selasky 	/* Determine if we already have another SM object for this SM. */
462*d6b92ffaSHans Petter Selasky 	CL_PLOCK_EXCL_ACQUIRE(sm->p_lock);
463*d6b92ffaSHans Petter Selasky 
464*d6b92ffaSHans Petter Selasky 	p_port = osm_get_port_by_guid(sm->p_subn, port_guid);
465*d6b92ffaSHans Petter Selasky 	if (!p_port) {
466*d6b92ffaSHans Petter Selasky 		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 2F12: "
467*d6b92ffaSHans Petter Selasky 			"No port object for this SM\n");
468*d6b92ffaSHans Petter Selasky 		goto _unlock_and_exit;
469*d6b92ffaSHans Petter Selasky 	}
470*d6b92ffaSHans Petter Selasky 
471*d6b92ffaSHans Petter Selasky 	if (osm_port_get_guid(p_port) != p_smi->guid) {
472*d6b92ffaSHans Petter Selasky 		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 2F13: "
473*d6b92ffaSHans Petter Selasky 			"Bogus SM port GUID, Expected 0x%016" PRIx64
474*d6b92ffaSHans Petter Selasky 			", Received 0x%016" PRIx64 "\n",
475*d6b92ffaSHans Petter Selasky 			cl_ntoh64(osm_port_get_guid(p_port)),
476*d6b92ffaSHans Petter Selasky 			cl_ntoh64(p_smi->guid));
477*d6b92ffaSHans Petter Selasky 		goto _unlock_and_exit;
478*d6b92ffaSHans Petter Selasky 	}
479*d6b92ffaSHans Petter Selasky 
480*d6b92ffaSHans Petter Selasky 	if (port_guid == sm->p_subn->sm_port_guid) {
481*d6b92ffaSHans Petter Selasky 		OSM_LOG(sm->p_log, OSM_LOG_VERBOSE,
482*d6b92ffaSHans Petter Selasky 			"Self query response received - SM port 0x%016" PRIx64
483*d6b92ffaSHans Petter Selasky 			"\n", cl_ntoh64(port_guid));
484*d6b92ffaSHans Petter Selasky 		goto _unlock_and_exit;
485*d6b92ffaSHans Petter Selasky 	}
486*d6b92ffaSHans Petter Selasky 
487*d6b92ffaSHans Petter Selasky 	p_sm = (osm_remote_sm_t *) cl_qmap_get(p_sm_tbl, port_guid);
488*d6b92ffaSHans Petter Selasky 	if (p_sm == (osm_remote_sm_t *) cl_qmap_end(p_sm_tbl)) {
489*d6b92ffaSHans Petter Selasky 		p_sm = malloc(sizeof(*p_sm));
490*d6b92ffaSHans Petter Selasky 		if (p_sm == NULL) {
491*d6b92ffaSHans Petter Selasky 			OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 2F14: "
492*d6b92ffaSHans Petter Selasky 				"Unable to allocate SM object\n");
493*d6b92ffaSHans Petter Selasky 			goto _unlock_and_exit;
494*d6b92ffaSHans Petter Selasky 		}
495*d6b92ffaSHans Petter Selasky 
496*d6b92ffaSHans Petter Selasky 		osm_remote_sm_init(p_sm, p_smi);
497*d6b92ffaSHans Petter Selasky 
498*d6b92ffaSHans Petter Selasky 		cl_qmap_insert(p_sm_tbl, port_guid, &p_sm->map_item);
499*d6b92ffaSHans Petter Selasky 	} else
500*d6b92ffaSHans Petter Selasky 		/* We already know this SM. Update the SMInfo attribute. */
501*d6b92ffaSHans Petter Selasky 		p_sm->smi = *p_smi;
502*d6b92ffaSHans Petter Selasky 
503*d6b92ffaSHans Petter Selasky 	smi_rcv_process_get_sm(sm, p_sm,
504*d6b92ffaSHans Petter Selasky 			       osm_madw_get_smi_context_ptr(p_madw)->
505*d6b92ffaSHans Petter Selasky 			       light_sweep);
506*d6b92ffaSHans Petter Selasky 
507*d6b92ffaSHans Petter Selasky _unlock_and_exit:
508*d6b92ffaSHans Petter Selasky 	CL_PLOCK_RELEASE(sm->p_lock);
509*d6b92ffaSHans Petter Selasky 
510*d6b92ffaSHans Petter Selasky Exit:
511*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(sm->p_log);
512*d6b92ffaSHans Petter Selasky }
513*d6b92ffaSHans Petter Selasky 
smi_rcv_process_set_response(IN osm_sm_t * sm,IN const osm_madw_t * p_madw)514*d6b92ffaSHans Petter Selasky static void smi_rcv_process_set_response(IN osm_sm_t * sm,
515*d6b92ffaSHans Petter Selasky 					 IN const osm_madw_t * p_madw)
516*d6b92ffaSHans Petter Selasky {
517*d6b92ffaSHans Petter Selasky 	const ib_smp_t *p_smp;
518*d6b92ffaSHans Petter Selasky 	const ib_sm_info_t *p_smi;
519*d6b92ffaSHans Petter Selasky 
520*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(sm->p_log);
521*d6b92ffaSHans Petter Selasky 
522*d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_madw);
523*d6b92ffaSHans Petter Selasky 
524*d6b92ffaSHans Petter Selasky 	p_smp = osm_madw_get_smp_ptr(p_madw);
525*d6b92ffaSHans Petter Selasky 	if (ib_smp_get_status(p_smp)) {
526*d6b92ffaSHans Petter Selasky 		OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
527*d6b92ffaSHans Petter Selasky 			"MAD status 0x%x received\n",
528*d6b92ffaSHans Petter Selasky 			cl_ntoh16(ib_smp_get_status(p_smp)));
529*d6b92ffaSHans Petter Selasky 		goto Exit;
530*d6b92ffaSHans Petter Selasky 	}
531*d6b92ffaSHans Petter Selasky 
532*d6b92ffaSHans Petter Selasky 	if (p_smp->method != IB_MAD_METHOD_GET_RESP) {
533*d6b92ffaSHans Petter Selasky 		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 2F16: "
534*d6b92ffaSHans Petter Selasky 			"Unsupported response method 0x%X\n", p_smp->method);
535*d6b92ffaSHans Petter Selasky 		goto Exit;
536*d6b92ffaSHans Petter Selasky 	}
537*d6b92ffaSHans Petter Selasky 
538*d6b92ffaSHans Petter Selasky 	p_smi = ib_smp_get_payload_ptr(p_smp);
539*d6b92ffaSHans Petter Selasky 	osm_dump_sm_info_v2(sm->p_log, p_smi, FILE_ID, OSM_LOG_DEBUG);
540*d6b92ffaSHans Petter Selasky 
541*d6b92ffaSHans Petter Selasky 	/* Check the AttributeModifier */
542*d6b92ffaSHans Petter Selasky 	if (p_smp->attr_mod != IB_SMINFO_ATTR_MOD_HANDOVER) {
543*d6b92ffaSHans Petter Selasky 		OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 2F17: "
544*d6b92ffaSHans Petter Selasky 			"Unsupported attribute modifier 0x%X, "
545*d6b92ffaSHans Petter Selasky 			"expected ATTR_MOD_HANDOVER\n",
546*d6b92ffaSHans Petter Selasky 			p_smp->attr_mod);
547*d6b92ffaSHans Petter Selasky 		goto Exit;
548*d6b92ffaSHans Petter Selasky 	}
549*d6b92ffaSHans Petter Selasky 
550*d6b92ffaSHans Petter Selasky 	/* This is a response on a HANDOVER request - Nothing to do. */
551*d6b92ffaSHans Petter Selasky 
552*d6b92ffaSHans Petter Selasky Exit:
553*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(sm->p_log);
554*d6b92ffaSHans Petter Selasky }
555*d6b92ffaSHans Petter Selasky 
osm_sminfo_rcv_process(IN void * context,IN void * data)556*d6b92ffaSHans Petter Selasky void osm_sminfo_rcv_process(IN void *context, IN void *data)
557*d6b92ffaSHans Petter Selasky {
558*d6b92ffaSHans Petter Selasky 	osm_sm_t *sm = context;
559*d6b92ffaSHans Petter Selasky 	osm_madw_t *p_madw = data;
560*d6b92ffaSHans Petter Selasky 	ib_smp_t *p_smp;
561*d6b92ffaSHans Petter Selasky 	osm_smi_context_t *p_smi_context;
562*d6b92ffaSHans Petter Selasky 
563*d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(sm->p_log);
564*d6b92ffaSHans Petter Selasky 
565*d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_madw);
566*d6b92ffaSHans Petter Selasky 
567*d6b92ffaSHans Petter Selasky 	p_smp = osm_madw_get_smp_ptr(p_madw);
568*d6b92ffaSHans Petter Selasky 	if (ib_smp_get_status(p_smp)) {
569*d6b92ffaSHans Petter Selasky 		OSM_LOG(sm->p_log, OSM_LOG_DEBUG,
570*d6b92ffaSHans Petter Selasky 			"MAD status 0x%x received\n",
571*d6b92ffaSHans Petter Selasky 			cl_ntoh16(ib_smp_get_status(p_smp)));
572*d6b92ffaSHans Petter Selasky 		goto Exit;
573*d6b92ffaSHans Petter Selasky 	}
574*d6b92ffaSHans Petter Selasky 
575*d6b92ffaSHans Petter Selasky 	/* Determine if this is a request for our own SMInfo or if
576*d6b92ffaSHans Petter Selasky 	   this is a response to our request for another SM's SMInfo. */
577*d6b92ffaSHans Petter Selasky 	if (ib_smp_is_response(p_smp)) {
578*d6b92ffaSHans Petter Selasky 		const ib_sm_info_t *p_smi = ib_smp_get_payload_ptr(p_smp);
579*d6b92ffaSHans Petter Selasky 
580*d6b92ffaSHans Petter Selasky 		/* Get the context - to see if this is a response to a Get or Set method */
581*d6b92ffaSHans Petter Selasky 		p_smi_context = osm_madw_get_smi_context_ptr(p_madw);
582*d6b92ffaSHans Petter Selasky 
583*d6b92ffaSHans Petter Selasky 		/* Verify that response is from expected port and there is
584*d6b92ffaSHans Petter Selasky 		   no port moving issue. */
585*d6b92ffaSHans Petter Selasky 		if (p_smi_context->port_guid != p_smi->guid) {
586*d6b92ffaSHans Petter Selasky 			OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 2F19: "
587*d6b92ffaSHans Petter Selasky 				"Unexpected SM port GUID in response"
588*d6b92ffaSHans Petter Selasky 				", Expected 0x%016" PRIx64
589*d6b92ffaSHans Petter Selasky 				", Received 0x%016" PRIx64 "\n",
590*d6b92ffaSHans Petter Selasky 				cl_ntoh64(p_smi_context->port_guid),
591*d6b92ffaSHans Petter Selasky 				cl_ntoh64(p_smi->guid));
592*d6b92ffaSHans Petter Selasky 			goto Exit;
593*d6b92ffaSHans Petter Selasky 		}
594*d6b92ffaSHans Petter Selasky 
595*d6b92ffaSHans Petter Selasky 		if (p_smi_context->set_method == FALSE)
596*d6b92ffaSHans Petter Selasky 			/* this is a response to a Get method */
597*d6b92ffaSHans Petter Selasky 			smi_rcv_process_get_response(sm, p_madw);
598*d6b92ffaSHans Petter Selasky 		else
599*d6b92ffaSHans Petter Selasky 			/* this is a response to a Set method */
600*d6b92ffaSHans Petter Selasky 			smi_rcv_process_set_response(sm, p_madw);
601*d6b92ffaSHans Petter Selasky 	} else {
602*d6b92ffaSHans Petter Selasky 		osm_port_t * p_port;
603*d6b92ffaSHans Petter Selasky 		ib_net64_t my_mkey;
604*d6b92ffaSHans Petter Selasky 		uint8_t mpb;
605*d6b92ffaSHans Petter Selasky 		char buf[256];
606*d6b92ffaSHans Petter Selasky 
607*d6b92ffaSHans Petter Selasky 		if(!(p_port = osm_get_port_by_guid(sm->p_subn,
608*d6b92ffaSHans Petter Selasky 						   sm->p_subn->sm_port_guid)))
609*d6b92ffaSHans Petter Selasky 			goto Exit;
610*d6b92ffaSHans Petter Selasky 
611*d6b92ffaSHans Petter Selasky 		if (!p_port->p_physp)
612*d6b92ffaSHans Petter Selasky 			goto Exit;
613*d6b92ffaSHans Petter Selasky 
614*d6b92ffaSHans Petter Selasky 		my_mkey = ib_port_info_get_m_key(&p_port->p_physp->port_info);
615*d6b92ffaSHans Petter Selasky 		mpb = my_mkey ? ib_port_info_get_mpb(&p_port->p_physp->port_info) : 0;
616*d6b92ffaSHans Petter Selasky 
617*d6b92ffaSHans Petter Selasky 		if (p_smp->method == IB_MAD_METHOD_GET) {
618*d6b92ffaSHans Petter Selasky 			/* M-Key Authentication */
619*d6b92ffaSHans Petter Selasky 			if (my_mkey && mpb > 1 && my_mkey != p_smp->m_key) {
620*d6b92ffaSHans Petter Selasky 				if (p_smp->mgmt_class == IB_MCLASS_SUBN_DIR)
621*d6b92ffaSHans Petter Selasky 					sprint_uint8_arr(buf, sizeof(buf),
622*d6b92ffaSHans Petter Selasky 					      p_smp->return_path, p_smp->hop_count + 1);
623*d6b92ffaSHans Petter Selasky 				else
624*d6b92ffaSHans Petter Selasky 					sprintf(buf, "LID %u",
625*d6b92ffaSHans Petter Selasky 						cl_ntoh16(p_madw->mad_addr.addr_type.smi.source_lid));
626*d6b92ffaSHans Petter Selasky 				OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 2F1A: "
627*d6b92ffaSHans Petter Selasky 					"SMInfo(GET) sender (%s) authentication failure."
628*d6b92ffaSHans Petter Selasky 					"Ignoring SMInfo\n", buf);
629*d6b92ffaSHans Petter Selasky 				goto Exit;
630*d6b92ffaSHans Petter Selasky 			}
631*d6b92ffaSHans Petter Selasky 			/* If protection bits == 1 but MKEY mismatch, return SM-KEY = 0 */
632*d6b92ffaSHans Petter Selasky 			if (my_mkey && mpb == 1 && my_mkey != p_smp->m_key)
633*d6b92ffaSHans Petter Selasky 				smi_rcv_process_get_request(sm, p_madw, FALSE);
634*d6b92ffaSHans Petter Selasky 			else
635*d6b92ffaSHans Petter Selasky 				smi_rcv_process_get_request(sm, p_madw, TRUE);
636*d6b92ffaSHans Petter Selasky 		} else {
637*d6b92ffaSHans Petter Selasky 			/* M-Key Authentication */
638*d6b92ffaSHans Petter Selasky 			if (my_mkey && my_mkey != p_smp->m_key) {
639*d6b92ffaSHans Petter Selasky 				if (p_smp->mgmt_class == IB_MCLASS_SUBN_DIR)
640*d6b92ffaSHans Petter Selasky 					sprint_uint8_arr(buf, sizeof(buf),
641*d6b92ffaSHans Petter Selasky 					      p_smp->return_path, p_smp->hop_count + 1);
642*d6b92ffaSHans Petter Selasky 				else
643*d6b92ffaSHans Petter Selasky 					sprintf(buf, "LID %u",
644*d6b92ffaSHans Petter Selasky 						cl_ntoh16(p_madw->mad_addr.addr_type.smi.source_lid));
645*d6b92ffaSHans Petter Selasky 				OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 2F1B: "
646*d6b92ffaSHans Petter Selasky 					"SMInfo(SET) sender (%s) authentication failure."
647*d6b92ffaSHans Petter Selasky 					"Ignoring SMInfo\n", buf);
648*d6b92ffaSHans Petter Selasky 				goto Exit;
649*d6b92ffaSHans Petter Selasky 			}
650*d6b92ffaSHans Petter Selasky 			/* This should be a SubnSet request */
651*d6b92ffaSHans Petter Selasky 			smi_rcv_process_set_request(sm, p_madw);
652*d6b92ffaSHans Petter Selasky 		}
653*d6b92ffaSHans Petter Selasky 	}
654*d6b92ffaSHans Petter Selasky 
655*d6b92ffaSHans Petter Selasky Exit:
656*d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(sm->p_log);
657*d6b92ffaSHans Petter Selasky }
658