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