]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/ofed/management/opensm/opensm/osm_inform.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / ofed / management / opensm / opensm / osm_inform.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 inform record functions.
39  */
40
41 #if HAVE_CONFIG_H
42 #  include <config.h>
43 #endif                          /* HAVE_CONFIG_H */
44
45 #include <stdlib.h>
46 #include <string.h>
47 #include <arpa/inet.h>
48 #include <complib/cl_debug.h>
49 #include <opensm/osm_helper.h>
50 #include <opensm/osm_inform.h>
51 #include <vendor/osm_vendor_api.h>
52 #include <opensm/osm_pkey.h>
53 #include <opensm/osm_sa.h>
54 #include <sys/socket.h>
55
56 typedef struct osm_infr_match_ctxt {
57         cl_list_t *p_remove_infr_list;
58         ib_mad_notice_attr_t *p_ntc;
59 } osm_infr_match_ctxt_t;
60
61 /**********************************************************************
62  **********************************************************************/
63 void osm_infr_delete(IN osm_infr_t * const p_infr)
64 {
65         free(p_infr);
66 }
67
68 /**********************************************************************
69  **********************************************************************/
70 osm_infr_t *osm_infr_new(IN const osm_infr_t * p_infr_rec)
71 {
72         osm_infr_t *p_infr;
73
74         CL_ASSERT(p_infr_rec);
75
76         p_infr = (osm_infr_t *) malloc(sizeof(osm_infr_t));
77         if (p_infr)
78                 memcpy(p_infr, p_infr_rec, sizeof(osm_infr_t));
79
80         return (p_infr);
81 }
82
83 /**********************************************************************
84  **********************************************************************/
85 static void dump_all_informs(IN osm_subn_t const *p_subn, IN osm_log_t * p_log)
86 {
87         cl_list_item_t *p_list_item;
88
89         if (!osm_log_is_active(p_log, OSM_LOG_DEBUG))
90                 return;
91
92         p_list_item = cl_qlist_head(&p_subn->sa_infr_list);
93         while (p_list_item != cl_qlist_end(&p_subn->sa_infr_list)) {
94                 osm_dump_inform_info(p_log,
95                                      &((osm_infr_t *) p_list_item)->
96                                      inform_record.inform_info, OSM_LOG_DEBUG);
97                 p_list_item = cl_qlist_next(p_list_item);
98         }
99 }
100
101 /**********************************************************************
102  * Match an infr by the InformInfo and Address vector
103  **********************************************************************/
104 static cl_status_t
105 __match_inf_rec(IN const cl_list_item_t * const p_list_item, IN void *context)
106 {
107         osm_infr_t *p_infr_rec = (osm_infr_t *) context;
108         osm_infr_t *p_infr = (osm_infr_t *) p_list_item;
109         osm_log_t *p_log = p_infr_rec->sa->p_log;
110         cl_status_t status = CL_NOT_FOUND;
111         ib_gid_t all_zero_gid;
112
113         OSM_LOG_ENTER(p_log);
114
115         if (memcmp(&p_infr->report_addr, &p_infr_rec->report_addr,
116                    sizeof(p_infr_rec->report_addr))) {
117                 OSM_LOG(p_log, OSM_LOG_DEBUG, "Differ by Address\n");
118                 goto Exit;
119         }
120
121         memset(&all_zero_gid, 0, sizeof(ib_gid_t));
122
123         /* if inform_info.gid is not zero, ignore lid range */
124         if (!memcmp(&p_infr_rec->inform_record.inform_info.gid, &all_zero_gid,
125                     sizeof(p_infr_rec->inform_record.inform_info.gid))) {
126                 if (memcmp(&p_infr->inform_record.inform_info.gid,
127                            &p_infr_rec->inform_record.inform_info.gid,
128                            sizeof(p_infr->inform_record.inform_info.gid))) {
129                         OSM_LOG(p_log, OSM_LOG_DEBUG,
130                                 "Differ by InformInfo.gid\n");
131                         goto Exit;
132                 }
133         } else {
134                 if ((p_infr->inform_record.inform_info.lid_range_begin !=
135                      p_infr_rec->inform_record.inform_info.lid_range_begin) ||
136                     (p_infr->inform_record.inform_info.lid_range_end !=
137                      p_infr_rec->inform_record.inform_info.lid_range_end)) {
138                         OSM_LOG(p_log, OSM_LOG_DEBUG,
139                                 "Differ by InformInfo.LIDRange\n");
140                         goto Exit;
141                 }
142         }
143
144         if (p_infr->inform_record.inform_info.trap_type !=
145             p_infr_rec->inform_record.inform_info.trap_type) {
146                 OSM_LOG(p_log, OSM_LOG_DEBUG,
147                         "Differ by InformInfo.TrapType\n");
148                 goto Exit;
149         }
150
151         if (p_infr->inform_record.inform_info.is_generic !=
152             p_infr_rec->inform_record.inform_info.is_generic) {
153                 OSM_LOG(p_log, OSM_LOG_DEBUG,
154                         "Differ by InformInfo.IsGeneric\n");
155                 goto Exit;
156         }
157
158         if (p_infr->inform_record.inform_info.is_generic) {
159                 if (p_infr->inform_record.inform_info.g_or_v.generic.trap_num !=
160                     p_infr_rec->inform_record.inform_info.g_or_v.generic.
161                     trap_num)
162                         OSM_LOG(p_log, OSM_LOG_DEBUG,
163                                 "Differ by InformInfo.Generic.TrapNumber\n");
164                 else if (p_infr->inform_record.inform_info.g_or_v.generic.
165                          qpn_resp_time_val !=
166                          p_infr_rec->inform_record.inform_info.g_or_v.generic.
167                          qpn_resp_time_val)
168                         OSM_LOG(p_log, OSM_LOG_DEBUG,
169                                 "Differ by InformInfo.Generic.QPNRespTimeVal\n");
170                 else if (p_infr->inform_record.inform_info.g_or_v.generic.
171                          node_type_msb !=
172                          p_infr_rec->inform_record.inform_info.g_or_v.generic.
173                          node_type_msb)
174                         OSM_LOG(p_log, OSM_LOG_DEBUG,
175                                 "Differ by InformInfo.Generic.NodeTypeMSB\n");
176                 else if (p_infr->inform_record.inform_info.g_or_v.generic.
177                          node_type_lsb !=
178                          p_infr_rec->inform_record.inform_info.g_or_v.generic.
179                          node_type_lsb)
180                         OSM_LOG(p_log, OSM_LOG_DEBUG,
181                                 "Differ by InformInfo.Generic.NodeTypeLSB\n");
182                 else
183                         status = CL_SUCCESS;
184         } else {
185                 if (p_infr->inform_record.inform_info.g_or_v.vend.dev_id !=
186                     p_infr_rec->inform_record.inform_info.g_or_v.vend.dev_id)
187                         OSM_LOG(p_log, OSM_LOG_DEBUG,
188                                 "Differ by InformInfo.Vendor.DeviceID\n");
189                 else if (p_infr->inform_record.inform_info.g_or_v.vend.
190                          qpn_resp_time_val !=
191                          p_infr_rec->inform_record.inform_info.g_or_v.vend.
192                          qpn_resp_time_val)
193                         OSM_LOG(p_log, OSM_LOG_DEBUG,
194                                 "Differ by InformInfo.Vendor.QPNRespTimeVal\n");
195                 else if (p_infr->inform_record.inform_info.g_or_v.vend.
196                          vendor_id_msb !=
197                          p_infr_rec->inform_record.inform_info.g_or_v.vend.
198                          vendor_id_msb)
199                         OSM_LOG(p_log, OSM_LOG_DEBUG,
200                                 "Differ by InformInfo.Vendor.VendorIdMSB\n");
201                 else if (p_infr->inform_record.inform_info.g_or_v.vend.
202                          vendor_id_lsb !=
203                          p_infr_rec->inform_record.inform_info.g_or_v.vend.
204                          vendor_id_lsb)
205                         OSM_LOG(p_log, OSM_LOG_DEBUG,
206                                 "Differ by InformInfo.Vendor.VendorIdLSB\n");
207                 else
208                         status = CL_SUCCESS;
209         }
210
211 Exit:
212         OSM_LOG_EXIT(p_log);
213         return status;
214 }
215
216 /**********************************************************************
217  **********************************************************************/
218 osm_infr_t *osm_infr_get_by_rec(IN osm_subn_t const *p_subn,
219                                 IN osm_log_t * p_log,
220                                 IN osm_infr_t * const p_infr_rec)
221 {
222         cl_list_item_t *p_list_item;
223
224         OSM_LOG_ENTER(p_log);
225
226         dump_all_informs(p_subn, p_log);
227
228         OSM_LOG(p_log, OSM_LOG_DEBUG, "Looking for Inform Record\n");
229         osm_dump_inform_info(p_log, &(p_infr_rec->inform_record.inform_info),
230                              OSM_LOG_DEBUG);
231         OSM_LOG(p_log, OSM_LOG_DEBUG, "InformInfo list size %d\n",
232                 cl_qlist_count(&p_subn->sa_infr_list));
233
234         p_list_item = cl_qlist_find_from_head(&p_subn->sa_infr_list,
235                                               __match_inf_rec, p_infr_rec);
236
237         if (p_list_item == cl_qlist_end(&p_subn->sa_infr_list))
238                 p_list_item = NULL;
239
240         OSM_LOG_EXIT(p_log);
241         return (osm_infr_t *) p_list_item;
242 }
243
244 /**********************************************************************
245  **********************************************************************/
246 void
247 osm_infr_insert_to_db(IN osm_subn_t * p_subn,
248                       IN osm_log_t * p_log, IN osm_infr_t * p_infr)
249 {
250         OSM_LOG_ENTER(p_log);
251
252         OSM_LOG(p_log, OSM_LOG_DEBUG,
253                 "Inserting new InformInfo Record into Database\n");
254         OSM_LOG(p_log, OSM_LOG_DEBUG, "Dump before insertion (size %d)\n",
255                 cl_qlist_count(&p_subn->sa_infr_list));
256         dump_all_informs(p_subn, p_log);
257
258 #if 0
259         osm_dump_inform_info(p_log,
260                              &(p_infr->inform_record.inform_info),
261                              OSM_LOG_DEBUG);
262 #endif
263
264         cl_qlist_insert_head(&p_subn->sa_infr_list, &p_infr->list_item);
265
266         OSM_LOG(p_log, OSM_LOG_DEBUG, "Dump after insertion (size %d)\n",
267                 cl_qlist_count(&p_subn->sa_infr_list));
268         dump_all_informs(p_subn, p_log);
269         OSM_LOG_EXIT(p_log);
270 }
271
272 /**********************************************************************
273  **********************************************************************/
274 void
275 osm_infr_remove_from_db(IN osm_subn_t * p_subn,
276                         IN osm_log_t * p_log, IN osm_infr_t * p_infr)
277 {
278         char gid_str[INET6_ADDRSTRLEN];
279         OSM_LOG_ENTER(p_log);
280
281         OSM_LOG(p_log, OSM_LOG_DEBUG, "Removing InformInfo Subscribing GID:%s"
282                 " Enum:0x%X from Database\n",
283                 inet_ntop(AF_INET6, p_infr->inform_record.subscriber_gid.raw,
284                         gid_str, sizeof gid_str),
285                 p_infr->inform_record.subscriber_enum);
286
287         osm_dump_inform_info(p_log, &(p_infr->inform_record.inform_info),
288                              OSM_LOG_DEBUG);
289
290         cl_qlist_remove_item(&p_subn->sa_infr_list, &p_infr->list_item);
291
292         osm_infr_delete(p_infr);
293
294         OSM_LOG_EXIT(p_log);
295 }
296
297 /**********************************************************************
298  * Send a report:
299  * Given a target address to send to and the notice.
300  * We need to send SubnAdmReport
301  **********************************************************************/
302 static ib_api_status_t __osm_send_report(IN osm_infr_t * p_infr_rec,    /* the informinfo */
303                                          IN ib_mad_notice_attr_t * p_ntc        /* notice to send */
304     )
305 {
306         osm_madw_t *p_report_madw;
307         ib_mad_notice_attr_t *p_report_ntc;
308         ib_mad_t *p_mad;
309         ib_sa_mad_t *p_sa_mad;
310         static atomic32_t trap_fwd_trans_id = 0x02DAB000;
311         ib_api_status_t status = IB_SUCCESS;
312         osm_log_t *p_log = p_infr_rec->sa->p_log;
313
314         OSM_LOG_ENTER(p_log);
315
316         /* HACK: who switches or uses the src and dest GIDs in the grh_info ?? */
317
318         /* it is better to use LIDs since the GIDs might not be there for SMI traps */
319         OSM_LOG(p_log, OSM_LOG_DEBUG, "Forwarding Notice Event from LID:%u"
320                 " to InformInfo LID: %u TID:0x%X\n",
321                 cl_ntoh16(p_ntc->issuer_lid),
322                 cl_ntoh16(p_infr_rec->report_addr.dest_lid), trap_fwd_trans_id);
323
324         /* get the MAD to send */
325         p_report_madw = osm_mad_pool_get(p_infr_rec->sa->p_mad_pool,
326                                          p_infr_rec->h_bind, MAD_BLOCK_SIZE,
327                                          &(p_infr_rec->report_addr));
328
329         p_report_madw->resp_expected = TRUE;
330
331         if (!p_report_madw) {
332                 OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0203"
333                         "osm_mad_pool_get failed\n");
334                 status = IB_ERROR;
335                 goto Exit;
336         }
337
338         /* advance trap trans id (cant simply ++ on some systems inside ntoh) */
339         p_mad = osm_madw_get_mad_ptr(p_report_madw);
340         ib_mad_init_new(p_mad, IB_MCLASS_SUBN_ADM, 2, IB_MAD_METHOD_REPORT,
341                         cl_hton64((uint64_t) cl_atomic_inc(&trap_fwd_trans_id)),
342                         IB_MAD_ATTR_NOTICE, 0);
343
344         p_sa_mad = osm_madw_get_sa_mad_ptr(p_report_madw);
345
346         p_report_ntc = (ib_mad_notice_attr_t *) & (p_sa_mad->data);
347
348         /* copy the notice */
349         *p_report_ntc = *p_ntc;
350
351         /* The TRUE is for: response is expected */
352         osm_sa_send(p_infr_rec->sa, p_report_madw, TRUE);
353
354 Exit:
355         OSM_LOG_EXIT(p_log);
356         return (status);
357 }
358
359 /**********************************************************************
360  * This routine compares a given Notice and a ListItem of InformInfo type.
361  * PREREQUISITE:
362  * The Notice.GID should be pre-filled with the trap generator GID
363  **********************************************************************/
364 static void
365 __match_notice_to_inf_rec(IN cl_list_item_t * const p_list_item,
366                           IN void *context)
367 {
368         osm_infr_match_ctxt_t *p_infr_match = (osm_infr_match_ctxt_t *) context;
369         ib_mad_notice_attr_t *p_ntc = p_infr_match->p_ntc;
370         cl_list_t *p_infr_to_remove_list = p_infr_match->p_remove_infr_list;
371         osm_infr_t *p_infr_rec = (osm_infr_t *) p_list_item;
372         ib_inform_info_t *p_ii = &(p_infr_rec->inform_record.inform_info);
373         cl_status_t status = CL_NOT_FOUND;
374         osm_log_t *p_log = p_infr_rec->sa->p_log;
375         osm_subn_t *p_subn = p_infr_rec->sa->p_subn;
376         ib_gid_t source_gid;
377         osm_port_t *p_src_port;
378         osm_port_t *p_dest_port;
379
380         OSM_LOG_ENTER(p_log);
381
382         /* matching rules
383          * InformInfo   Notice
384          * GID          IssuerGID    if non zero must match the trap
385          * LIDRange     IssuerLID    apply only if GID=0
386          * IsGeneric    IsGeneric    is compulsory and must match the trap
387          * Type         Type         if not 0xFFFF must match
388          * TrapNumber   TrapNumber   if not 0xFFFF must match
389          * DeviceId     DeviceID     if not 0xFFFF must match
390          * QPN dont care
391          * ProducerType ProducerType match or 0xFFFFFF // EZ: actually my interpretation
392          * VendorID     VendorID     match or 0xFFFFFF
393          */
394
395         /* GID          IssuerGID    if non zero must match the trap  */
396         if (p_ii->gid.unicast.prefix != 0
397             || p_ii->gid.unicast.interface_id != 0) {
398                 /* match by GID */
399                 if (memcmp(&(p_ii->gid), &(p_ntc->issuer_gid),
400                            sizeof(ib_gid_t))) {
401                         OSM_LOG(p_log, OSM_LOG_DEBUG, "Mismatch by GID\n");
402                         goto Exit;
403                 }
404         } else {
405                 /* LIDRange     IssuerLID    apply only if GID=0 */
406                 /* If lid_range_begin of the informInfo is 0xFFFF - then it should be ignored. */
407                 if (p_ii->lid_range_begin != 0xFFFF) {
408                         /* a real lid range is given - check it */
409                         if ((cl_hton16(p_ii->lid_range_begin) >
410                              cl_hton16(p_ntc->issuer_lid))
411                             || (cl_hton16(p_ntc->issuer_lid) >
412                                 cl_hton16(p_ii->lid_range_end))) {
413                                 OSM_LOG(p_log, OSM_LOG_DEBUG,
414                                         "Mismatch by LID Range. Needed: %u <= %u <= %u\n",
415                                         cl_hton16(p_ii->lid_range_begin),
416                                         cl_hton16(p_ntc->issuer_lid),
417                                         cl_hton16(p_ii->lid_range_end));
418                                 goto Exit;
419                         }
420                 }
421         }
422
423         /* IsGeneric    IsGeneric    is compulsory and must match the trap  */
424         if ((p_ii->is_generic && !ib_notice_is_generic(p_ntc)) ||
425             (!p_ii->is_generic && ib_notice_is_generic(p_ntc))) {
426                 OSM_LOG(p_log, OSM_LOG_DEBUG, "Mismatch by Generic/Vendor\n");
427                 goto Exit;
428         }
429
430         /* Type         Type         if not 0xFFFF must match */
431         if ((p_ii->trap_type != 0xFFFF) &&
432             (cl_ntoh16(p_ii->trap_type) != ib_notice_get_type(p_ntc))) {
433                 OSM_LOG(p_log, OSM_LOG_DEBUG, "Mismatch by Type\n");
434                 goto Exit;
435         }
436
437         /* based on generic type */
438         if (p_ii->is_generic) {
439                 /* TrapNumber   TrapNumber   if not 0xFFFF must match */
440                 if ((p_ii->g_or_v.generic.trap_num != 0xFFFF) &&
441                     (p_ii->g_or_v.generic.trap_num !=
442                      p_ntc->g_or_v.generic.trap_num)) {
443                         OSM_LOG(p_log, OSM_LOG_DEBUG, "Mismatch by Trap Num\n");
444                         goto Exit;
445                 }
446
447                 /* ProducerType ProducerType match or 0xFFFFFF  */
448                 if ((cl_ntoh32(ib_inform_info_get_prod_type(p_ii)) != 0xFFFFFF)
449                     && (ib_inform_info_get_prod_type(p_ii) !=
450                         ib_notice_get_prod_type(p_ntc))) {
451                         OSM_LOG(p_log, OSM_LOG_DEBUG,
452                                 "Mismatch by Node Type: II=0x%06X (%s) Trap=0x%06X (%s)\n",
453                                 cl_ntoh32(ib_inform_info_get_prod_type(p_ii)),
454                                 ib_get_producer_type_str
455                                 (ib_inform_info_get_prod_type(p_ii)),
456                                 cl_ntoh32(ib_notice_get_prod_type(p_ntc)),
457                                 ib_get_producer_type_str(ib_notice_get_prod_type
458                                                          (p_ntc)));
459                         goto Exit;
460                 }
461         } else {
462                 /* DeviceId     DeviceID     if not 0xFFFF must match */
463                 if ((p_ii->g_or_v.vend.dev_id != 0xFFFF) &&
464                     (p_ii->g_or_v.vend.dev_id != p_ntc->g_or_v.vend.dev_id)) {
465                         OSM_LOG(p_log, OSM_LOG_DEBUG, "Mismatch by Dev Id\n");
466                         goto Exit;
467                 }
468
469                 /* VendorID     VendorID     match or 0xFFFFFF  */
470                 if ((ib_inform_info_get_vend_id(p_ii) != CL_HTON32(0xFFFFFF)) &&
471                     (ib_inform_info_get_vend_id(p_ii) !=
472                      ib_notice_get_vend_id(p_ntc))) {
473                         OSM_LOG(p_log, OSM_LOG_DEBUG, "Mismatch by Vendor ID\n");
474                         goto Exit;
475                 }
476         }
477
478         /* Check if there is a pkey match. o13-17.1.1 */
479         /* Check if the issuer of the trap is the SM. If it is, then the gid
480            comparison should be done on the trap source (saved as the gid in the
481            data details field).
482            If the issuer gid is not the SM - then it is the guid of the trap
483            source */
484         if ((cl_ntoh64(p_ntc->issuer_gid.unicast.prefix) ==
485              p_subn->opt.subnet_prefix)
486             && (cl_ntoh64(p_ntc->issuer_gid.unicast.interface_id) ==
487                 p_subn->sm_port_guid))
488                 /* The issuer is the SM then this is trap 64-67 - compare the gid
489                    with the gid saved on the data details */
490                 source_gid = p_ntc->data_details.ntc_64_67.gid;
491         else
492                 source_gid = p_ntc->issuer_gid;
493
494         p_src_port =
495             osm_get_port_by_guid(p_subn, source_gid.unicast.interface_id);
496         if (!p_src_port) {
497                 OSM_LOG(p_log, OSM_LOG_INFO,
498                         "Cannot find source port with GUID:0x%016" PRIx64 "\n",
499                         cl_ntoh64(source_gid.unicast.interface_id));
500                 goto Exit;
501         }
502
503         p_dest_port =
504             cl_ptr_vector_get(&p_subn->port_lid_tbl,
505                               cl_ntoh16(p_infr_rec->report_addr.dest_lid));
506         if (!p_dest_port) {
507                 OSM_LOG(p_log, OSM_LOG_INFO,
508                         "Cannot find destination port with LID:%u\n",
509                         cl_ntoh16(p_infr_rec->report_addr.dest_lid));
510                 goto Exit;
511         }
512
513         if (osm_port_share_pkey(p_log, p_src_port, p_dest_port) == FALSE) {
514                 OSM_LOG(p_log, OSM_LOG_DEBUG, "Mismatch by Pkey\n");
515                 /* According to o13-17.1.2 - If this informInfo does not have
516                    lid_range_begin of 0xFFFF, then this informInfo request
517                    should be removed from database */
518                 if (p_ii->lid_range_begin != 0xFFFF) {
519                         OSM_LOG(p_log, OSM_LOG_VERBOSE,
520                                 "Pkey mismatch on lid_range_begin != 0xFFFF. "
521                                 "Need to remove this informInfo from db\n");
522                         /* add the informInfo record to the remove_infr list */
523                         cl_list_insert_tail(p_infr_to_remove_list, p_infr_rec);
524                 }
525                 goto Exit;
526         }
527
528         /* send the report to the address provided in the inform record */
529         OSM_LOG(p_log, OSM_LOG_DEBUG, "MATCH! Sending Report...\n");
530         __osm_send_report(p_infr_rec, p_ntc);
531         status = CL_SUCCESS;
532
533 Exit:
534         OSM_LOG_EXIT(p_log);
535 }
536
537 /**********************************************************************
538  * Once a Trap was received by osm_trap_rcv, or a Trap sourced by
539  * the SM was sent (Traps 64-67), this routine is called with a copy of
540  * the notice data.
541  * Given a notice attribute - compare and see if it matches the InformInfo
542  * element and if it does - call the Report(Notice) for the
543  * target QP registered by the address stored in the InformInfo element
544  **********************************************************************/
545 ib_api_status_t
546 osm_report_notice(IN osm_log_t * const p_log,
547                   IN osm_subn_t * p_subn, IN ib_mad_notice_attr_t * p_ntc)
548 {
549         char gid_str[INET6_ADDRSTRLEN];
550         osm_infr_match_ctxt_t context;
551         cl_list_t infr_to_remove_list;
552         osm_infr_t *p_infr_rec;
553         osm_infr_t *p_next_infr_rec;
554
555         OSM_LOG_ENTER(p_log);
556
557         /*
558          * we must make sure we are ready for this...
559          * note that the trap receivers might be initialized before
560          * the osm_infr_init call is performed.
561          */
562         if (p_subn->sa_infr_list.state != CL_INITIALIZED) {
563                 OSM_LOG(p_log, OSM_LOG_DEBUG,
564                         "Ignoring Notice Reports since Inform List is not initialized yet!\n");
565                 return (IB_ERROR);
566         }
567
568         /* an official Event information log */
569         if (ib_notice_is_generic(p_ntc))
570                 OSM_LOG(p_log, OSM_LOG_INFO,
571                         "Reporting Generic Notice type:%u num:%u (%s)"
572                         " from LID:%u GID:%s\n",
573                         ib_notice_get_type(p_ntc),
574                         cl_ntoh16(p_ntc->g_or_v.generic.trap_num),
575                         ib_get_trap_str(p_ntc->g_or_v.generic.trap_num),
576                         cl_ntoh16(p_ntc->issuer_lid),
577                         inet_ntop(AF_INET6, p_ntc->issuer_gid.raw, gid_str,
578                                 sizeof gid_str));
579         else
580                 OSM_LOG(p_log, OSM_LOG_INFO,
581                         "Reporting Vendor Notice type:%u vend:%u dev:%u"
582                         " from LID:%u GID:%s\n",
583                         ib_notice_get_type(p_ntc),
584                         cl_ntoh32(ib_notice_get_vend_id(p_ntc)),
585                         cl_ntoh16(p_ntc->g_or_v.vend.dev_id),
586                         cl_ntoh16(p_ntc->issuer_lid),
587                         inet_ntop(AF_INET6, p_ntc->issuer_gid.raw, gid_str,
588                                 sizeof gid_str));
589
590         /* Create a list that will hold all the infr records that should
591            be removed due to violation. o13-17.1.2 */
592         cl_list_construct(&infr_to_remove_list);
593         cl_list_init(&infr_to_remove_list, 5);
594         context.p_remove_infr_list = &infr_to_remove_list;
595         context.p_ntc = p_ntc;
596
597         /* go over all inform info available at the subnet */
598         /* try match to the given notice and send if match */
599         cl_qlist_apply_func(&(p_subn->sa_infr_list),
600                             __match_notice_to_inf_rec, &context);
601
602         /* If we inserted items into the infr_to_remove_list - we need to
603            remove them */
604         p_infr_rec = (osm_infr_t *) cl_list_remove_head(&infr_to_remove_list);
605         while (p_infr_rec != NULL) {
606                 p_next_infr_rec =
607                     (osm_infr_t *) cl_list_remove_head(&infr_to_remove_list);
608                 osm_infr_remove_from_db(p_subn, p_log, p_infr_rec);
609                 p_infr_rec = p_next_infr_rec;
610         }
611         cl_list_destroy(&infr_to_remove_list);
612
613         OSM_LOG_EXIT(p_log);
614
615         return (IB_SUCCESS);
616 }