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