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