1321936Shselasky/* 2321936Shselasky * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved. 3321936Shselasky * Copyright (c) 2002-2015 Mellanox Technologies LTD. All rights reserved. 4321936Shselasky * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. 5321936Shselasky * Copyright (c) 2009 HNR Consulting. All rights reserved. 6321936Shselasky * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. 7321936Shselasky * 8321936Shselasky * This software is available to you under a choice of one of two 9321936Shselasky * licenses. You may choose to be licensed under the terms of the GNU 10321936Shselasky * General Public License (GPL) Version 2, available from the file 11321936Shselasky * COPYING in the main directory of this source tree, or the 12321936Shselasky * OpenIB.org BSD license below: 13321936Shselasky * 14321936Shselasky * Redistribution and use in source and binary forms, with or 15321936Shselasky * without modification, are permitted provided that the following 16321936Shselasky * conditions are met: 17321936Shselasky * 18321936Shselasky * - Redistributions of source code must retain the above 19321936Shselasky * copyright notice, this list of conditions and the following 20321936Shselasky * disclaimer. 21321936Shselasky * 22321936Shselasky * - Redistributions in binary form must reproduce the above 23321936Shselasky * copyright notice, this list of conditions and the following 24321936Shselasky * disclaimer in the documentation and/or other materials 25321936Shselasky * provided with the distribution. 26321936Shselasky * 27321936Shselasky * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 28321936Shselasky * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 29321936Shselasky * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 30321936Shselasky * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 31321936Shselasky * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 32321936Shselasky * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 33321936Shselasky * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 34321936Shselasky * SOFTWARE. 35321936Shselasky * 36321936Shselasky */ 37321936Shselasky 38321936Shselasky/* 39321936Shselasky * Abstract: 40321936Shselasky * Implementation of inform record functions. 41321936Shselasky */ 42321936Shselasky 43321936Shselasky#if HAVE_CONFIG_H 44321936Shselasky# include <config.h> 45321936Shselasky#endif /* HAVE_CONFIG_H */ 46321936Shselasky 47321936Shselasky#include <stdlib.h> 48321936Shselasky#include <string.h> 49321936Shselasky#include <arpa/inet.h> 50321936Shselasky#include <sys/socket.h> 51321936Shselasky#include <complib/cl_debug.h> 52321936Shselasky#include <opensm/osm_file_ids.h> 53321936Shselasky#define FILE_ID OSM_FILE_INFORM_C 54321936Shselasky#include <opensm/osm_helper.h> 55321936Shselasky#include <opensm/osm_inform.h> 56321936Shselasky#include <vendor/osm_vendor_api.h> 57321936Shselasky#include <opensm/osm_pkey.h> 58321936Shselasky#include <opensm/osm_sa.h> 59321936Shselasky#include <opensm/osm_opensm.h> 60321936Shselasky 61321936Shselaskytypedef struct osm_infr_match_ctxt { 62321936Shselasky cl_list_t *p_remove_infr_list; 63321936Shselasky ib_mad_notice_attr_t *p_ntc; 64321936Shselasky} osm_infr_match_ctxt_t; 65321936Shselasky 66321936Shselaskyvoid osm_infr_delete(IN osm_infr_t * p_infr) 67321936Shselasky{ 68321936Shselasky free(p_infr); 69321936Shselasky} 70321936Shselasky 71321936Shselaskyosm_infr_t *osm_infr_new(IN const osm_infr_t * p_infr_rec) 72321936Shselasky{ 73321936Shselasky osm_infr_t *p_infr; 74321936Shselasky 75321936Shselasky CL_ASSERT(p_infr_rec); 76321936Shselasky 77321936Shselasky p_infr = (osm_infr_t *) malloc(sizeof(osm_infr_t)); 78321936Shselasky if (p_infr) 79321936Shselasky memcpy(p_infr, p_infr_rec, sizeof(osm_infr_t)); 80321936Shselasky 81321936Shselasky return p_infr; 82321936Shselasky} 83321936Shselasky 84321936Shselaskystatic void dump_all_informs(IN const osm_subn_t * p_subn, IN osm_log_t * p_log) 85321936Shselasky{ 86321936Shselasky cl_list_item_t *p_list_item; 87321936Shselasky 88321936Shselasky if (!OSM_LOG_IS_ACTIVE_V2(p_log, OSM_LOG_DEBUG)) 89321936Shselasky return; 90321936Shselasky 91321936Shselasky p_list_item = cl_qlist_head(&p_subn->sa_infr_list); 92321936Shselasky while (p_list_item != cl_qlist_end(&p_subn->sa_infr_list)) { 93321936Shselasky osm_dump_inform_info_v2(p_log, 94321936Shselasky &((osm_infr_t *) p_list_item)-> 95321936Shselasky inform_record.inform_info, FILE_ID, OSM_LOG_DEBUG); 96321936Shselasky p_list_item = cl_qlist_next(p_list_item); 97321936Shselasky } 98321936Shselasky} 99321936Shselasky 100321936Shselasky/********************************************************************** 101321936Shselasky * Match an infr by the InformInfo and Address vector 102321936Shselasky **********************************************************************/ 103321936Shselaskystatic cl_status_t match_inf_rec(IN const cl_list_item_t * p_list_item, 104321936Shselasky IN void *context) 105321936Shselasky{ 106321936Shselasky osm_infr_t *p_infr_rec = (osm_infr_t *) context; 107321936Shselasky osm_infr_t *p_infr = (osm_infr_t *) p_list_item; 108321936Shselasky ib_inform_info_t *p_ii_rec = &p_infr_rec->inform_record.inform_info; 109321936Shselasky ib_inform_info_t *p_ii = &p_infr->inform_record.inform_info; 110321936Shselasky osm_log_t *p_log = p_infr_rec->sa->p_log; 111321936Shselasky cl_status_t status = CL_NOT_FOUND; 112321936Shselasky 113321936Shselasky OSM_LOG_ENTER(p_log); 114321936Shselasky 115321936Shselasky if (memcmp(&p_infr->report_addr, &p_infr_rec->report_addr, 116321936Shselasky sizeof(p_infr_rec->report_addr))) { 117321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, "Differ by Address\n"); 118321936Shselasky goto Exit; 119321936Shselasky } 120321936Shselasky 121321936Shselasky /* if inform_info.gid is not zero, ignore lid range */ 122321936Shselasky if (ib_gid_is_notzero(&p_ii_rec->gid)) { 123321936Shselasky if (memcmp(&p_ii->gid, &p_ii_rec->gid, sizeof(p_ii->gid))) { 124321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, 125321936Shselasky "Differ by InformInfo.gid\n"); 126321936Shselasky goto Exit; 127321936Shselasky } 128321936Shselasky } else { 129321936Shselasky if ((p_ii->lid_range_begin != p_ii_rec->lid_range_begin) || 130321936Shselasky (p_ii->lid_range_end != p_ii_rec->lid_range_end)) { 131321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, 132321936Shselasky "Differ by InformInfo.LIDRange\n"); 133321936Shselasky goto Exit; 134321936Shselasky } 135321936Shselasky } 136321936Shselasky 137321936Shselasky if (p_ii->trap_type != p_ii_rec->trap_type) { 138321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, 139321936Shselasky "Differ by InformInfo.TrapType\n"); 140321936Shselasky goto Exit; 141321936Shselasky } 142321936Shselasky 143321936Shselasky if (p_ii->is_generic != p_ii_rec->is_generic) { 144321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, 145321936Shselasky "Differ by InformInfo.IsGeneric\n"); 146321936Shselasky goto Exit; 147321936Shselasky } 148321936Shselasky 149321936Shselasky if (p_ii->is_generic) { 150321936Shselasky if (p_ii->g_or_v.generic.trap_num != 151321936Shselasky p_ii_rec->g_or_v.generic.trap_num) 152321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, 153321936Shselasky "Differ by InformInfo.Generic.TrapNumber\n"); 154321936Shselasky else if (p_ii->g_or_v.generic.qpn_resp_time_val != 155321936Shselasky p_ii_rec->g_or_v.generic.qpn_resp_time_val) 156321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, 157321936Shselasky "Differ by InformInfo.Generic.QPNRespTimeVal\n"); 158321936Shselasky else if (p_ii->g_or_v.generic.node_type_msb != 159321936Shselasky p_ii_rec->g_or_v.generic.node_type_msb) 160321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, 161321936Shselasky "Differ by InformInfo.Generic.NodeTypeMSB\n"); 162321936Shselasky else if (p_ii->g_or_v.generic.node_type_lsb != 163321936Shselasky p_ii_rec->g_or_v.generic.node_type_lsb) 164321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, 165321936Shselasky "Differ by InformInfo.Generic.NodeTypeLSB\n"); 166321936Shselasky else 167321936Shselasky status = CL_SUCCESS; 168321936Shselasky } else { 169321936Shselasky if (p_ii->g_or_v.vend.dev_id != p_ii_rec->g_or_v.vend.dev_id) 170321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, 171321936Shselasky "Differ by InformInfo.Vendor.DeviceID\n"); 172321936Shselasky else if (p_ii->g_or_v.vend.qpn_resp_time_val != 173321936Shselasky p_ii_rec->g_or_v.vend.qpn_resp_time_val) 174321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, 175321936Shselasky "Differ by InformInfo.Vendor.QPNRespTimeVal\n"); 176321936Shselasky else if (p_ii->g_or_v.vend.vendor_id_msb != 177321936Shselasky p_ii_rec->g_or_v.vend.vendor_id_msb) 178321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, 179321936Shselasky "Differ by InformInfo.Vendor.VendorIdMSB\n"); 180321936Shselasky else if (p_ii->g_or_v.vend.vendor_id_lsb != 181321936Shselasky p_ii_rec->g_or_v.vend.vendor_id_lsb) 182321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, 183321936Shselasky "Differ by InformInfo.Vendor.VendorIdLSB\n"); 184321936Shselasky else 185321936Shselasky status = CL_SUCCESS; 186321936Shselasky } 187321936Shselasky 188321936ShselaskyExit: 189321936Shselasky OSM_LOG_EXIT(p_log); 190321936Shselasky return status; 191321936Shselasky} 192321936Shselasky 193321936Shselaskyosm_infr_t *osm_infr_get_by_rec(IN osm_subn_t const *p_subn, 194321936Shselasky IN osm_log_t * p_log, 195321936Shselasky IN osm_infr_t * p_infr_rec) 196321936Shselasky{ 197321936Shselasky cl_list_item_t *p_list_item; 198321936Shselasky 199321936Shselasky OSM_LOG_ENTER(p_log); 200321936Shselasky 201321936Shselasky dump_all_informs(p_subn, p_log); 202321936Shselasky 203321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, "Looking for Inform Record\n"); 204321936Shselasky osm_dump_inform_info_v2(p_log, &(p_infr_rec->inform_record.inform_info), 205321936Shselasky FILE_ID, OSM_LOG_DEBUG); 206321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, "InformInfo list size %d\n", 207321936Shselasky cl_qlist_count(&p_subn->sa_infr_list)); 208321936Shselasky 209321936Shselasky p_list_item = cl_qlist_find_from_head(&p_subn->sa_infr_list, 210321936Shselasky match_inf_rec, p_infr_rec); 211321936Shselasky 212321936Shselasky if (p_list_item == cl_qlist_end(&p_subn->sa_infr_list)) 213321936Shselasky p_list_item = NULL; 214321936Shselasky 215321936Shselasky OSM_LOG_EXIT(p_log); 216321936Shselasky return (osm_infr_t *) p_list_item; 217321936Shselasky} 218321936Shselasky 219321936Shselaskyvoid osm_infr_insert_to_db(IN osm_subn_t * p_subn, IN osm_log_t * p_log, 220321936Shselasky IN osm_infr_t * p_infr) 221321936Shselasky{ 222321936Shselasky OSM_LOG_ENTER(p_log); 223321936Shselasky 224321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, 225321936Shselasky "Inserting new InformInfo Record into Database\n"); 226321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, "Dump before insertion (size %d)\n", 227321936Shselasky cl_qlist_count(&p_subn->sa_infr_list)); 228321936Shselasky dump_all_informs(p_subn, p_log); 229321936Shselasky 230321936Shselasky#if 0 231321936Shselasky osm_dump_inform_info_v2(p_log, 232321936Shselasky &(p_infr->inform_record.inform_info), 233321936Shselasky FILE_ID, OSM_LOG_DEBUG); 234321936Shselasky#endif 235321936Shselasky 236321936Shselasky cl_qlist_insert_head(&p_subn->sa_infr_list, &p_infr->list_item); 237321936Shselasky p_subn->p_osm->sa.dirty = TRUE; 238321936Shselasky 239321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, "Dump after insertion (size %d)\n", 240321936Shselasky cl_qlist_count(&p_subn->sa_infr_list)); 241321936Shselasky dump_all_informs(p_subn, p_log); 242321936Shselasky OSM_LOG_EXIT(p_log); 243321936Shselasky} 244321936Shselasky 245321936Shselaskyvoid osm_infr_remove_from_db(IN osm_subn_t * p_subn, IN osm_log_t * p_log, 246321936Shselasky IN osm_infr_t * p_infr) 247321936Shselasky{ 248321936Shselasky char gid_str[INET6_ADDRSTRLEN]; 249321936Shselasky OSM_LOG_ENTER(p_log); 250321936Shselasky 251321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, "Removing InformInfo Subscribing GID:%s" 252321936Shselasky " Enum:0x%X from Database\n", 253321936Shselasky inet_ntop(AF_INET6, p_infr->inform_record.subscriber_gid.raw, 254321936Shselasky gid_str, sizeof gid_str), 255321936Shselasky p_infr->inform_record.subscriber_enum); 256321936Shselasky 257321936Shselasky osm_dump_inform_info_v2(p_log, &(p_infr->inform_record.inform_info), 258321936Shselasky FILE_ID, OSM_LOG_DEBUG); 259321936Shselasky 260321936Shselasky cl_qlist_remove_item(&p_subn->sa_infr_list, &p_infr->list_item); 261321936Shselasky p_subn->p_osm->sa.dirty = TRUE; 262321936Shselasky 263321936Shselasky osm_infr_delete(p_infr); 264321936Shselasky 265321936Shselasky OSM_LOG_EXIT(p_log); 266321936Shselasky} 267321936Shselasky 268321936Shselaskyib_api_status_t osm_infr_remove_subscriptions(IN osm_subn_t * p_subn, 269321936Shselasky IN osm_log_t * p_log, 270321936Shselasky IN ib_net64_t port_guid) 271321936Shselasky{ 272321936Shselasky cl_list_item_t *p_list_item; 273321936Shselasky osm_infr_t *p_infr; 274321936Shselasky ib_api_status_t status = CL_NOT_FOUND; 275321936Shselasky 276321936Shselasky OSM_LOG_ENTER(p_log); 277321936Shselasky 278321936Shselasky /* go over all inform info available at the subnet */ 279321936Shselasky /* match to the given GID and delete subscriptions if match */ 280321936Shselasky p_list_item = cl_qlist_head(&p_subn->sa_infr_list); 281321936Shselasky while (p_list_item != cl_qlist_end(&p_subn->sa_infr_list)) { 282321936Shselasky 283321936Shselasky p_infr = (osm_infr_t *)p_list_item; 284321936Shselasky p_list_item = cl_qlist_next(p_list_item); 285321936Shselasky 286321936Shselasky if (port_guid != p_infr->inform_record.subscriber_gid.unicast.interface_id) 287321936Shselasky continue; 288321936Shselasky 289321936Shselasky /* Remove this event subscription */ 290321936Shselasky osm_infr_remove_from_db(p_subn, p_log, p_infr); 291321936Shselasky 292321936Shselasky status = CL_SUCCESS; 293321936Shselasky } 294321936Shselasky 295321936Shselasky OSM_LOG_EXIT(p_log); 296321936Shselasky return (status); 297321936Shselasky} 298321936Shselasky 299321936Shselasky/********************************************************************** 300321936Shselasky * Send a report: 301321936Shselasky * Given a target address to send to and the notice. 302321936Shselasky * We need to send SubnAdmReport 303321936Shselasky **********************************************************************/ 304321936Shselaskystatic ib_api_status_t send_report(IN osm_infr_t * p_infr_rec, /* the informinfo */ 305321936Shselasky IN ib_mad_notice_attr_t * p_ntc /* notice to send */ 306321936Shselasky ) 307321936Shselasky{ 308321936Shselasky osm_madw_t *p_report_madw; 309321936Shselasky ib_mad_notice_attr_t *p_report_ntc; 310321936Shselasky ib_mad_t *p_mad; 311321936Shselasky ib_sa_mad_t *p_sa_mad; 312321936Shselasky static atomic32_t trap_fwd_trans_id = 0x02DAB000; 313321936Shselasky ib_api_status_t status = IB_SUCCESS; 314321936Shselasky osm_log_t *p_log = p_infr_rec->sa->p_log; 315321936Shselasky ib_net64_t tid; 316321936Shselasky 317321936Shselasky OSM_LOG_ENTER(p_log); 318321936Shselasky 319321936Shselasky /* HACK: who switches or uses the src and dest GIDs in the grh_info ?? */ 320321936Shselasky 321321936Shselasky /* it is better to use LIDs since the GIDs might not be there for SMI traps */ 322321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, "Forwarding Notice Event from LID %u" 323321936Shselasky " to InformInfo LID %u GUID 0x%" PRIx64 ", TID 0x%X\n", 324321936Shselasky cl_ntoh16(p_ntc->issuer_lid), 325321936Shselasky cl_ntoh16(p_infr_rec->report_addr.dest_lid), 326321936Shselasky cl_ntoh64(p_infr_rec->inform_record.subscriber_gid.unicast.interface_id), 327321936Shselasky trap_fwd_trans_id); 328321936Shselasky 329321936Shselasky /* get the MAD to send */ 330321936Shselasky p_report_madw = osm_mad_pool_get(p_infr_rec->sa->p_mad_pool, 331321936Shselasky p_infr_rec->h_bind, MAD_BLOCK_SIZE, 332321936Shselasky &(p_infr_rec->report_addr)); 333321936Shselasky 334321936Shselasky if (!p_report_madw) { 335321936Shselasky OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0203: " 336321936Shselasky "Cannot send report to LID %u, osm_mad_pool_get failed\n", 337321936Shselasky cl_ntoh16(p_infr_rec->report_addr.dest_lid)); 338321936Shselasky status = IB_ERROR; 339321936Shselasky goto Exit; 340321936Shselasky } 341321936Shselasky 342321936Shselasky p_report_madw->resp_expected = TRUE; 343321936Shselasky 344321936Shselasky /* advance trap trans id (cant simply ++ on some systems inside ntoh) */ 345321936Shselasky tid = cl_hton64((uint64_t) cl_atomic_inc(&trap_fwd_trans_id) & 346321936Shselasky (uint64_t) (0xFFFFFFFF)); 347321936Shselasky if (trap_fwd_trans_id == 0) 348321936Shselasky tid = cl_hton64((uint64_t) cl_atomic_inc(&trap_fwd_trans_id) & 349321936Shselasky (uint64_t) (0xFFFFFFFF)); 350321936Shselasky p_mad = osm_madw_get_mad_ptr(p_report_madw); 351321936Shselasky ib_mad_init_new(p_mad, IB_MCLASS_SUBN_ADM, 2, IB_MAD_METHOD_REPORT, 352321936Shselasky tid, IB_MAD_ATTR_NOTICE, 0); 353321936Shselasky 354321936Shselasky p_sa_mad = osm_madw_get_sa_mad_ptr(p_report_madw); 355321936Shselasky 356321936Shselasky p_report_ntc = (ib_mad_notice_attr_t *) & (p_sa_mad->data); 357321936Shselasky 358321936Shselasky /* copy the notice */ 359321936Shselasky *p_report_ntc = *p_ntc; 360321936Shselasky 361321936Shselasky /* The TRUE is for: response is expected */ 362321936Shselasky osm_sa_send(p_infr_rec->sa, p_report_madw, TRUE); 363321936Shselasky 364321936ShselaskyExit: 365321936Shselasky OSM_LOG_EXIT(p_log); 366321936Shselasky return status; 367321936Shselasky} 368321936Shselasky 369321936Shselaskystatic int is_access_permitted(osm_infr_t *p_infr_rec, 370321936Shselasky osm_infr_match_ctxt_t *p_infr_match ) 371321936Shselasky{ 372321936Shselasky cl_list_t *p_infr_to_remove_list = p_infr_match->p_remove_infr_list; 373321936Shselasky ib_inform_info_t *p_ii = &(p_infr_rec->inform_record.inform_info); 374321936Shselasky ib_mad_notice_attr_t *p_ntc = p_infr_match->p_ntc; 375321936Shselasky uint16_t trap_num = cl_ntoh16(p_ntc->g_or_v.generic.trap_num); 376321936Shselasky osm_subn_t *p_subn = p_infr_rec->sa->p_subn; 377321936Shselasky osm_log_t *p_log = p_infr_rec->sa->p_log; 378321936Shselasky osm_mgrp_t *p_mgrp; 379321936Shselasky ib_gid_t source_gid; 380321936Shselasky osm_port_t *p_src_port; 381321936Shselasky osm_port_t *p_dest_port; 382321936Shselasky 383321936Shselasky /* In case of SM_GID_IN_SERVICE_TRAP(64) or SM_GID_OUT_OF_SERVICE_TRAP(65) traps 384321936Shselasky the source gid comparison should be done on the trap source (saved 385321936Shselasky as the gid in the data details field). 386321936Shselasky For traps SM_MGID_CREATED_TRAP(66) or SM_MGID_DESTROYED_TRAP(67) 387321936Shselasky the data details gid is the MGID. 388321936Shselasky We need to check whether the subscriber has a compatible 389321936Shselasky pkey with MC group. 390321936Shselasky In all other cases the issuer gid is the trap source. 391321936Shselasky */ 392321936Shselasky if (trap_num >= SM_GID_IN_SERVICE_TRAP && 393321936Shselasky trap_num <= SM_MGID_DESTROYED_TRAP) 394321936Shselasky /* The issuer of these traps is the SM so source_gid 395321936Shselasky is the gid saved on the data details */ 396321936Shselasky source_gid = p_ntc->data_details.ntc_64_67.gid; 397321936Shselasky else 398321936Shselasky source_gid = p_ntc->issuer_gid; 399321936Shselasky 400321936Shselasky p_dest_port = osm_get_port_by_lid(p_subn, 401321936Shselasky p_infr_rec->report_addr.dest_lid); 402321936Shselasky if (!p_dest_port) { 403321936Shselasky OSM_LOG(p_log, OSM_LOG_INFO, 404321936Shselasky "Cannot find destination port with LID:%u\n", 405321936Shselasky cl_ntoh16(p_infr_rec->report_addr.dest_lid)); 406321936Shselasky goto Exit; 407321936Shselasky } 408321936Shselasky 409321936Shselasky /* Check if there is a pkey match. o13-17.1.1 */ 410321936Shselasky switch (trap_num) { 411321936Shselasky case SM_MGID_CREATED_TRAP: 412321936Shselasky case SM_MGID_DESTROYED_TRAP: 413321936Shselasky p_mgrp = osm_get_mgrp_by_mgid(p_subn, &source_gid); 414321936Shselasky if (!p_mgrp) { 415321936Shselasky char gid_str[INET6_ADDRSTRLEN]; 416321936Shselasky OSM_LOG(p_log, OSM_LOG_INFO, 417321936Shselasky "Cannot find MGID %s\n", 418321936Shselasky inet_ntop(AF_INET6, source_gid.raw, gid_str, sizeof gid_str)); 419321936Shselasky goto Exit; 420321936Shselasky } 421321936Shselasky 422321936Shselasky if (!osm_physp_has_pkey(p_log, 423321936Shselasky p_mgrp->mcmember_rec.pkey, 424321936Shselasky p_dest_port->p_physp)) { 425321936Shselasky char gid_str[INET6_ADDRSTRLEN]; 426321936Shselasky OSM_LOG(p_log, OSM_LOG_INFO, 427321936Shselasky "MGID %s and port GUID:0x%016" PRIx64 " do not share same pkey\n", 428321936Shselasky inet_ntop(AF_INET6, source_gid.raw, gid_str, sizeof gid_str), 429321936Shselasky cl_ntoh64(p_dest_port->guid)); 430321936Shselasky goto Exit; 431321936Shselasky } 432321936Shselasky break; 433321936Shselasky 434321936Shselasky default: 435321936Shselasky p_src_port = 436321936Shselasky osm_get_port_by_guid(p_subn, source_gid.unicast.interface_id); 437321936Shselasky if (!p_src_port) { 438321936Shselasky OSM_LOG(p_log, OSM_LOG_INFO, 439321936Shselasky "Cannot find source port with GUID:0x%016" PRIx64 "\n", 440321936Shselasky cl_ntoh64(source_gid.unicast.interface_id)); 441321936Shselasky goto Exit; 442321936Shselasky } 443321936Shselasky 444321936Shselasky 445321936Shselasky if (osm_port_share_pkey(p_log, p_src_port, p_dest_port, 446321936Shselasky p_subn->opt.allow_both_pkeys) == FALSE) { 447321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, "Mismatch by Pkey\n"); 448321936Shselasky /* According to o13-17.1.2 - If this informInfo 449321936Shselasky does not have lid_range_begin of 0xFFFF, 450321936Shselasky then this informInfo request should be 451321936Shselasky removed from database */ 452321936Shselasky if (p_ii->lid_range_begin != 0xFFFF) { 453321936Shselasky OSM_LOG(p_log, OSM_LOG_VERBOSE, 454321936Shselasky "Pkey mismatch on lid_range_begin != 0xFFFF. " 455321936Shselasky "Need to remove this informInfo from db\n"); 456321936Shselasky /* add the informInfo record to the remove_infr list */ 457321936Shselasky cl_list_insert_tail(p_infr_to_remove_list, p_infr_rec); 458321936Shselasky } 459321936Shselasky goto Exit; 460321936Shselasky } 461321936Shselasky break; 462321936Shselasky } 463321936Shselasky 464321936Shselasky return 1; 465321936ShselaskyExit: 466321936Shselasky return 0; 467321936Shselasky} 468321936Shselasky 469321936Shselasky 470321936Shselasky/********************************************************************** 471321936Shselasky * This routine compares a given Notice and a ListItem of InformInfo type. 472321936Shselasky * PREREQUISITE: 473321936Shselasky * The Notice.GID should be pre-filled with the trap generator GID 474321936Shselasky **********************************************************************/ 475321936Shselaskystatic void match_notice_to_inf_rec(IN cl_list_item_t * p_list_item, 476321936Shselasky IN void *context) 477321936Shselasky{ 478321936Shselasky osm_infr_match_ctxt_t *p_infr_match = (osm_infr_match_ctxt_t *) context; 479321936Shselasky ib_mad_notice_attr_t *p_ntc = p_infr_match->p_ntc; 480321936Shselasky osm_infr_t *p_infr_rec = (osm_infr_t *) p_list_item; 481321936Shselasky ib_inform_info_t *p_ii = &(p_infr_rec->inform_record.inform_info); 482321936Shselasky osm_log_t *p_log = p_infr_rec->sa->p_log; 483321936Shselasky 484321936Shselasky OSM_LOG_ENTER(p_log); 485321936Shselasky 486321936Shselasky /* matching rules 487321936Shselasky * InformInfo Notice 488321936Shselasky * GID IssuerGID if non zero must match the trap 489321936Shselasky * LIDRange IssuerLID apply only if GID=0 490321936Shselasky * IsGeneric IsGeneric is compulsory and must match the trap 491321936Shselasky * Type Type if not 0xFFFF must match 492321936Shselasky * TrapNumber TrapNumber if not 0xFFFF must match 493321936Shselasky * DeviceId DeviceID if not 0xFFFF must match 494321936Shselasky * QPN dont care 495321936Shselasky * ProducerType ProducerType match or 0xFFFFFF // EZ: actually my interpretation 496321936Shselasky * VendorID VendorID match or 0xFFFFFF 497321936Shselasky */ 498321936Shselasky 499321936Shselasky /* GID IssuerGID if non zero must match the trap */ 500321936Shselasky if (p_ii->gid.unicast.prefix != 0 501321936Shselasky || p_ii->gid.unicast.interface_id != 0) { 502321936Shselasky /* match by GID */ 503321936Shselasky if (memcmp(&(p_ii->gid), &(p_ntc->issuer_gid), 504321936Shselasky sizeof(ib_gid_t))) { 505321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, "Mismatch by GID\n"); 506321936Shselasky goto Exit; 507321936Shselasky } 508321936Shselasky } else { 509321936Shselasky /* LIDRange IssuerLID apply only if GID=0 */ 510321936Shselasky /* If lid_range_begin of the informInfo is 0xFFFF - then it should be ignored. */ 511321936Shselasky if (p_ii->lid_range_begin != 0xFFFF) { 512321936Shselasky /* a real lid range is given - check it */ 513321936Shselasky if ((cl_hton16(p_ii->lid_range_begin) > 514321936Shselasky cl_hton16(p_ntc->issuer_lid)) 515321936Shselasky || (cl_hton16(p_ntc->issuer_lid) > 516321936Shselasky cl_hton16(p_ii->lid_range_end))) { 517321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, 518321936Shselasky "Mismatch by LID Range. Needed: %u <= %u <= %u\n", 519321936Shselasky cl_hton16(p_ii->lid_range_begin), 520321936Shselasky cl_hton16(p_ntc->issuer_lid), 521321936Shselasky cl_hton16(p_ii->lid_range_end)); 522321936Shselasky goto Exit; 523321936Shselasky } 524321936Shselasky } 525321936Shselasky } 526321936Shselasky 527321936Shselasky /* IsGeneric IsGeneric is compulsory and must match the trap */ 528321936Shselasky if ((p_ii->is_generic && !ib_notice_is_generic(p_ntc)) || 529321936Shselasky (!p_ii->is_generic && ib_notice_is_generic(p_ntc))) { 530321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, "Mismatch by Generic/Vendor\n"); 531321936Shselasky goto Exit; 532321936Shselasky } 533321936Shselasky 534321936Shselasky /* Type Type if not 0xFFFF must match */ 535321936Shselasky if ((p_ii->trap_type != 0xFFFF) && 536321936Shselasky (cl_ntoh16(p_ii->trap_type) != ib_notice_get_type(p_ntc))) { 537321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, "Mismatch by Type\n"); 538321936Shselasky goto Exit; 539321936Shselasky } 540321936Shselasky 541321936Shselasky /* based on generic type */ 542321936Shselasky if (p_ii->is_generic) { 543321936Shselasky /* TrapNumber TrapNumber if not 0xFFFF must match */ 544321936Shselasky if ((p_ii->g_or_v.generic.trap_num != 0xFFFF) && 545321936Shselasky (p_ii->g_or_v.generic.trap_num != 546321936Shselasky p_ntc->g_or_v.generic.trap_num)) { 547321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, "Mismatch by Trap Num\n"); 548321936Shselasky goto Exit; 549321936Shselasky } 550321936Shselasky 551321936Shselasky /* ProducerType ProducerType match or 0xFFFFFF */ 552321936Shselasky if ((cl_ntoh32(ib_inform_info_get_prod_type(p_ii)) != 0xFFFFFF) 553321936Shselasky && (ib_inform_info_get_prod_type(p_ii) != 554321936Shselasky ib_notice_get_prod_type(p_ntc))) { 555321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, 556321936Shselasky "Mismatch by Node Type: II=0x%06X (%s) Trap=0x%06X (%s)\n", 557321936Shselasky cl_ntoh32(ib_inform_info_get_prod_type(p_ii)), 558321936Shselasky ib_get_producer_type_str 559321936Shselasky (ib_inform_info_get_prod_type(p_ii)), 560321936Shselasky cl_ntoh32(ib_notice_get_prod_type(p_ntc)), 561321936Shselasky ib_get_producer_type_str(ib_notice_get_prod_type 562321936Shselasky (p_ntc))); 563321936Shselasky goto Exit; 564321936Shselasky } 565321936Shselasky } else { 566321936Shselasky /* DeviceId DeviceID if not 0xFFFF must match */ 567321936Shselasky if ((p_ii->g_or_v.vend.dev_id != 0xFFFF) && 568321936Shselasky (p_ii->g_or_v.vend.dev_id != p_ntc->g_or_v.vend.dev_id)) { 569321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, "Mismatch by Dev Id\n"); 570321936Shselasky goto Exit; 571321936Shselasky } 572321936Shselasky 573321936Shselasky /* VendorID VendorID match or 0xFFFFFF */ 574321936Shselasky if ((ib_inform_info_get_vend_id(p_ii) != CL_HTON32(0xFFFFFF)) && 575321936Shselasky (ib_inform_info_get_vend_id(p_ii) != 576321936Shselasky ib_notice_get_vend_id(p_ntc))) { 577321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, 578321936Shselasky "Mismatch by Vendor ID\n"); 579321936Shselasky goto Exit; 580321936Shselasky } 581321936Shselasky } 582321936Shselasky 583321936Shselasky if (!is_access_permitted(p_infr_rec, p_infr_match)) 584321936Shselasky goto Exit; 585321936Shselasky 586321936Shselasky /* send the report to the address provided in the inform record */ 587321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, "MATCH! Sending Report...\n"); 588321936Shselasky send_report(p_infr_rec, p_ntc); 589321936Shselasky 590321936ShselaskyExit: 591321936Shselasky OSM_LOG_EXIT(p_log); 592321936Shselasky} 593321936Shselasky 594321936Shselasky/********************************************************************** 595321936Shselasky * Once a Trap was received by osm_trap_rcv, or a Trap sourced by 596321936Shselasky * the SM was sent (Traps 64-67), this routine is called with a copy of 597321936Shselasky * the notice data. 598321936Shselasky * Given a notice attribute - compare and see if it matches the InformInfo 599321936Shselasky * element and if it does - call the Report(Notice) for the 600321936Shselasky * target QP registered by the address stored in the InformInfo element 601321936Shselasky **********************************************************************/ 602321936Shselaskystatic void log_notice(osm_log_t * log, osm_log_level_t level, 603321936Shselasky ib_mad_notice_attr_t * ntc) 604321936Shselasky{ 605321936Shselasky char gid_str[INET6_ADDRSTRLEN], gid_str2[INET6_ADDRSTRLEN]; 606321936Shselasky ib_gid_t *gid; 607321936Shselasky ib_gid_t *gid1, *gid2; 608321936Shselasky 609321936Shselasky /* an official Event information log */ 610321936Shselasky if (ib_notice_is_generic(ntc)) { 611321936Shselasky if ((ntc->g_or_v.generic.trap_num == CL_HTON16(SM_GID_IN_SERVICE_TRAP)) || 612321936Shselasky (ntc->g_or_v.generic.trap_num == CL_HTON16(SM_GID_OUT_OF_SERVICE_TRAP)) || 613321936Shselasky (ntc->g_or_v.generic.trap_num == CL_HTON16(SM_MGID_CREATED_TRAP)) || 614321936Shselasky (ntc->g_or_v.generic.trap_num == CL_HTON16(SM_MGID_DESTROYED_TRAP))) 615321936Shselasky gid = &ntc->data_details.ntc_64_67.gid; 616321936Shselasky else 617321936Shselasky gid = &ntc->issuer_gid; 618321936Shselasky 619321936Shselasky switch (cl_ntoh16(ntc->g_or_v.generic.trap_num)) { 620321936Shselasky case SM_GID_IN_SERVICE_TRAP: 621321936Shselasky case SM_GID_OUT_OF_SERVICE_TRAP: 622321936Shselasky OSM_LOG(log, level, 623321936Shselasky "Reporting Informational Notice \"%s\", GID:%s\n", 624321936Shselasky ib_get_trap_str(ntc->g_or_v.generic.trap_num), 625321936Shselasky inet_ntop(AF_INET6, gid->raw, gid_str, sizeof gid_str)); 626321936Shselasky break; 627321936Shselasky case SM_MGID_CREATED_TRAP: 628321936Shselasky case SM_MGID_DESTROYED_TRAP: 629321936Shselasky OSM_LOG(log, level, 630321936Shselasky "Reporting Informational Notice \"%s\", MGID:%s\n", 631321936Shselasky ib_get_trap_str(ntc->g_or_v.generic.trap_num), 632321936Shselasky inet_ntop(AF_INET6, gid->raw, gid_str, sizeof gid_str)); 633321936Shselasky break; 634321936Shselasky case SM_UNPATH_TRAP: 635321936Shselasky case SM_REPATH_TRAP: 636321936Shselasky /* TODO: Fill in details once SM starts to use these traps */ 637321936Shselasky OSM_LOG(log, level, 638321936Shselasky "Reporting Informational Notice \"%s\"n", 639321936Shselasky ib_get_trap_str(ntc->g_or_v.generic.trap_num)); 640321936Shselasky break; 641321936Shselasky case SM_LINK_STATE_CHANGED_TRAP: 642321936Shselasky OSM_LOG(log, level, 643321936Shselasky "Reporting Urgent Notice \"%s\" from switch LID %u, " 644321936Shselasky "GUID 0x%016" PRIx64 "\n", 645321936Shselasky ib_get_trap_str(ntc->g_or_v.generic.trap_num), 646321936Shselasky cl_ntoh16(ntc->issuer_lid), 647321936Shselasky cl_ntoh64(gid->unicast.interface_id)); 648321936Shselasky break; 649321936Shselasky case SM_LINK_INTEGRITY_THRESHOLD_TRAP: 650321936Shselasky case SM_BUFFER_OVERRUN_THRESHOLD_TRAP: 651321936Shselasky case SM_WATCHDOG_TIMER_EXPIRED_TRAP: 652321936Shselasky OSM_LOG(log, level, 653321936Shselasky "Reporting Urgent Notice \"%s\" from LID %u, " 654321936Shselasky "GUID 0x%016" PRIx64 ", port %u\n", 655321936Shselasky ib_get_trap_str(ntc->g_or_v.generic.trap_num), 656321936Shselasky cl_ntoh16(ntc->issuer_lid), 657321936Shselasky cl_ntoh64(gid->unicast.interface_id), 658321936Shselasky ntc->data_details.ntc_129_131.port_num); 659321936Shselasky break; 660321936Shselasky case SM_LOCAL_CHANGES_TRAP: 661321936Shselasky if (ntc->data_details.ntc_144.local_changes == 1) 662321936Shselasky OSM_LOG(log, level, 663321936Shselasky "Reporting Informational Notice \"%s\" from LID %u, " 664321936Shselasky "GUID 0x%016" PRIx64 ", ChangeFlags 0x%04x, " 665321936Shselasky "CapabilityMask2 0x%04x\n", 666321936Shselasky ib_get_trap_str(ntc->g_or_v.generic.trap_num), 667321936Shselasky cl_ntoh16(ntc->issuer_lid), 668321936Shselasky cl_ntoh64(gid->unicast.interface_id), 669321936Shselasky cl_ntoh16(ntc->data_details.ntc_144.change_flgs), 670321936Shselasky cl_ntoh16(ntc->data_details.ntc_144.cap_mask2)); 671321936Shselasky else 672321936Shselasky OSM_LOG(log, level, 673321936Shselasky "Reporting Informational Notice \"%s\" from LID %u, " 674321936Shselasky "GUID 0x%016" PRIx64 ", new CapabilityMask 0x%08x\n", 675321936Shselasky ib_get_trap_str(ntc->g_or_v.generic.trap_num), 676321936Shselasky cl_ntoh16(ntc->issuer_lid), 677321936Shselasky cl_ntoh64(gid->unicast.interface_id), 678321936Shselasky cl_ntoh32(ntc->data_details.ntc_144.new_cap_mask)); 679321936Shselasky break; 680321936Shselasky case SM_SYS_IMG_GUID_CHANGED_TRAP: 681321936Shselasky OSM_LOG(log, level, 682321936Shselasky "Reporting Informational Notice \"%s\" from LID %u, " 683321936Shselasky "GUID 0x%016" PRIx64 ", new SysImageGUID 0x%016" PRIx64 "\n", 684321936Shselasky ib_get_trap_str(ntc->g_or_v.generic.trap_num), 685321936Shselasky cl_ntoh16(ntc->issuer_lid), 686321936Shselasky cl_ntoh64(gid->unicast.interface_id), 687321936Shselasky cl_ntoh64(ntc->data_details.ntc_145.new_sys_guid)); 688321936Shselasky break; 689321936Shselasky case SM_BAD_MKEY_TRAP: 690321936Shselasky OSM_LOG(log, level, 691321936Shselasky "Reporting Security Notice \"%s\" from LID %u, " 692321936Shselasky "GUID 0x%016" PRIx64 ", Method 0x%x, Attribute 0x%x, " 693321936Shselasky "AttrMod 0x%x, M_Key 0x%016" PRIx64 "\n", 694321936Shselasky ib_get_trap_str(ntc->g_or_v.generic.trap_num), 695321936Shselasky cl_ntoh16(ntc->issuer_lid), 696321936Shselasky cl_ntoh64(gid->unicast.interface_id), 697321936Shselasky ntc->data_details.ntc_256.method, 698321936Shselasky cl_ntoh16(ntc->data_details.ntc_256.attr_id), 699321936Shselasky cl_ntoh32(ntc->data_details.ntc_256.attr_mod), 700321936Shselasky cl_ntoh64(ntc->data_details.ntc_256.mkey)); 701321936Shselasky break; 702321936Shselasky case SM_BAD_PKEY_TRAP: 703321936Shselasky case SM_BAD_QKEY_TRAP: 704321936Shselasky gid1 = &ntc->data_details.ntc_257_258.gid1; 705321936Shselasky gid2 = &ntc->data_details.ntc_257_258.gid2; 706321936Shselasky OSM_LOG(log, level, 707321936Shselasky "Reporting Security Notice \"%s\" from LID %u, " 708321936Shselasky "GUID 0x%016" PRIx64 " : LID1 %u, LID2 %u, %s 0x%x, " 709321936Shselasky "SL %d, QP1 0x%x, QP2 0x%x, GID1 %s, GID2 %s\n", 710321936Shselasky ib_get_trap_str(ntc->g_or_v.generic.trap_num), 711321936Shselasky cl_ntoh16(ntc->issuer_lid), 712321936Shselasky cl_ntoh64(gid->unicast.interface_id), 713321936Shselasky cl_ntoh16(ntc->data_details.ntc_257_258.lid1), 714321936Shselasky cl_ntoh16(ntc->data_details.ntc_257_258.lid2), 715321936Shselasky cl_ntoh16(ntc->g_or_v.generic.trap_num) == SM_BAD_QKEY_TRAP ? 716321936Shselasky "Q_Key" : "P_Key", 717321936Shselasky cl_ntoh32(ntc->data_details.ntc_257_258.key), 718321936Shselasky cl_ntoh32(ntc->data_details.ntc_257_258.qp1) >> 28, 719321936Shselasky cl_ntoh32(ntc->data_details.ntc_257_258.qp1) & 0xffffff, 720321936Shselasky cl_ntoh32(ntc->data_details.ntc_257_258.qp2) & 0xffffff, 721321936Shselasky inet_ntop(AF_INET6, gid1->raw, gid_str, sizeof gid_str), 722321936Shselasky inet_ntop(AF_INET6, gid2->raw, gid_str2, sizeof gid_str2)); 723321936Shselasky break; 724321936Shselasky case SM_BAD_SWITCH_PKEY_TRAP: 725321936Shselasky gid1 = &ntc->data_details.ntc_259.gid1; 726321936Shselasky gid2 = &ntc->data_details.ntc_259.gid2; 727321936Shselasky OSM_LOG(log, level, 728321936Shselasky "Reporting Security Notice \"%s\" from switch LID %u, " 729321936Shselasky "GUID 0x%016" PRIx64 " port %d : data_valid 0x%04x, " 730321936Shselasky "LID1 %u, LID2 %u, PKey 0x%04x, " 731321936Shselasky "SL %d, QP1 0x%x, QP2 0x%x, GID1 %s, GID2 %s\n", 732321936Shselasky ib_get_trap_str(ntc->g_or_v.generic.trap_num), 733321936Shselasky cl_ntoh16(ntc->issuer_lid), 734321936Shselasky cl_ntoh64(gid->unicast.interface_id), 735321936Shselasky ntc->data_details.ntc_259.port_no, 736321936Shselasky cl_ntoh16(ntc->data_details.ntc_259.data_valid), 737321936Shselasky cl_ntoh16(ntc->data_details.ntc_259.lid1), 738321936Shselasky cl_ntoh16(ntc->data_details.ntc_259.lid2), 739321936Shselasky cl_ntoh16(ntc->data_details.ntc_257_258.key), 740321936Shselasky cl_ntoh32(ntc->data_details.ntc_259.sl_qp1) >> 28, 741321936Shselasky cl_ntoh32(ntc->data_details.ntc_259.sl_qp1) & 0xffffff, 742321936Shselasky cl_ntoh32(ntc->data_details.ntc_259.qp2), 743321936Shselasky inet_ntop(AF_INET6, gid1->raw, gid_str, sizeof gid_str), 744321936Shselasky inet_ntop(AF_INET6, gid2->raw, gid_str2, sizeof gid_str2)); 745321936Shselasky break; 746321936Shselasky default: 747321936Shselasky OSM_LOG(log, level, 748321936Shselasky "Reporting Generic Notice type:%u num:%u (%s)" 749321936Shselasky " from LID:%u GID:%s\n", 750321936Shselasky ib_notice_get_type(ntc), 751321936Shselasky cl_ntoh16(ntc->g_or_v.generic.trap_num), 752321936Shselasky ib_get_trap_str(ntc->g_or_v.generic.trap_num), 753321936Shselasky cl_ntoh16(ntc->issuer_lid), 754321936Shselasky inet_ntop(AF_INET6, gid->raw, gid_str, sizeof gid_str)); 755321936Shselasky break; 756321936Shselasky } 757321936Shselasky } else 758321936Shselasky OSM_LOG(log, level, 759321936Shselasky "Reporting Vendor Notice type:%u vend:%u dev:%u" 760321936Shselasky " from LID:%u GID:%s\n", 761321936Shselasky ib_notice_get_type(ntc), 762321936Shselasky cl_ntoh32(ib_notice_get_vend_id(ntc)), 763321936Shselasky cl_ntoh16(ntc->g_or_v.vend.dev_id), 764321936Shselasky cl_ntoh16(ntc->issuer_lid), 765321936Shselasky inet_ntop(AF_INET6, ntc->issuer_gid.raw, gid_str, 766321936Shselasky sizeof gid_str)); 767321936Shselasky} 768321936Shselasky 769321936Shselaskyib_api_status_t osm_report_notice(IN osm_log_t * p_log, IN osm_subn_t * p_subn, 770321936Shselasky IN ib_mad_notice_attr_t * p_ntc) 771321936Shselasky{ 772321936Shselasky osm_infr_match_ctxt_t context; 773321936Shselasky cl_list_t infr_to_remove_list; 774321936Shselasky osm_infr_t *p_infr_rec; 775321936Shselasky osm_infr_t *p_next_infr_rec; 776321936Shselasky 777321936Shselasky OSM_LOG_ENTER(p_log); 778321936Shselasky 779321936Shselasky /* 780321936Shselasky * we must make sure we are ready for this... 781321936Shselasky * note that the trap receivers might be initialized before 782321936Shselasky * the osm_infr_init call is performed. 783321936Shselasky */ 784321936Shselasky if (p_subn->sa_infr_list.state != CL_INITIALIZED) { 785321936Shselasky OSM_LOG(p_log, OSM_LOG_DEBUG, 786321936Shselasky "Ignoring Notice Reports since Inform List is not initialized yet!\n"); 787321936Shselasky return IB_ERROR; 788321936Shselasky } 789321936Shselasky 790321936Shselasky if (OSM_LOG_IS_ACTIVE_V2(p_log, OSM_LOG_INFO)) 791321936Shselasky log_notice(p_log, OSM_LOG_INFO, p_ntc); 792321936Shselasky 793321936Shselasky /* Create a list that will hold all the infr records that should 794321936Shselasky be removed due to violation. o13-17.1.2 */ 795321936Shselasky cl_list_construct(&infr_to_remove_list); 796321936Shselasky cl_list_init(&infr_to_remove_list, 5); 797321936Shselasky context.p_remove_infr_list = &infr_to_remove_list; 798321936Shselasky context.p_ntc = p_ntc; 799321936Shselasky 800321936Shselasky /* go over all inform info available at the subnet */ 801321936Shselasky /* try match to the given notice and send if match */ 802321936Shselasky cl_qlist_apply_func(&p_subn->sa_infr_list, match_notice_to_inf_rec, 803321936Shselasky &context); 804321936Shselasky 805321936Shselasky /* If we inserted items into the infr_to_remove_list - we need to 806321936Shselasky remove them */ 807321936Shselasky p_infr_rec = (osm_infr_t *) cl_list_remove_head(&infr_to_remove_list); 808321936Shselasky while (p_infr_rec != NULL) { 809321936Shselasky p_next_infr_rec = 810321936Shselasky (osm_infr_t *) cl_list_remove_head(&infr_to_remove_list); 811321936Shselasky osm_infr_remove_from_db(p_subn, p_log, p_infr_rec); 812321936Shselasky p_infr_rec = p_next_infr_rec; 813321936Shselasky } 814321936Shselasky cl_list_destroy(&infr_to_remove_list); 815321936Shselasky 816321936Shselasky /* report IB traps to plugin */ 817321936Shselasky osm_opensm_report_event(p_subn->p_osm, OSM_EVENT_ID_TRAP, p_ntc); 818321936Shselasky 819321936Shselasky OSM_LOG_EXIT(p_log); 820321936Shselasky 821321936Shselasky return IB_SUCCESS; 822321936Shselasky} 823