[openib-general] [PATCH 1/2] OpenSM: Add support for SA InformInfoRecord
Hal Rosenstock
halr at voltaire.com
Tue Dec 5 07:02:03 PST 2006
OpenSM: Add support for SA InformInfoRecord
The following patch adds initial SA InformInfoRecord support into
OpenSM.
Signed-off-by: Hal Rosenstock <halr at voltaire.com>
diff --git a/osm/include/opensm/osm_inform.h b/osm/include/opensm/osm_inform.h
index 40fec93..0bc8810 100644
--- a/osm/include/opensm/osm_inform.h
+++ b/osm/include/opensm/osm_inform.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2005 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2004-2006 Voltaire, Inc. All rights reserved.
* Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
* Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
*
@@ -254,6 +254,72 @@ osm_infr_get_by_rid(
* Inform Record, osm_infr_construct, osm_infr_destroy
*********/
+/****f* OpenSM: Inform Record/osm_infr_get_by_gid
+* NAME
+* osm_infr_get_by_gid
+*
+* DESCRIPTION
+* Find a matching osm_infr_t in the subnet DB by inform_info_record
+* subscriber GID
+*
+* SYNOPSIS
+*/
+osm_infr_t*
+osm_infr_get_by_gid(
+ IN osm_subn_t const *p_subn,
+ IN osm_log_t *p_log,
+ IN ib_inform_info_record_t* const p_inf_rec );
+/*
+* PARAMETERS
+* p_subn
+* [in] Pointer to the subnet object
+*
+* p_log
+* [in] Pointer to the log object
+*
+* p_inf_rec
+* [in] Pointer to an inform_info record with the search
+* subscriber GID
+*
+* RETURN
+* The matching osm_infr_t
+* SEE ALSO
+* Inform Record, osm_infr_construct, osm_infr_destroy
+*********/
+
+/****f* OpenSM: Inform Record/osm_infr_get_by_enum
+* NAME
+* osm_infr_get_by_enum
+*
+* DESCRIPTION
+* Find a matching osm_infr_t in the subnet DB by inform_info_record
+* subscriber enum
+*
+* SYNOPSIS
+*/
+osm_infr_t*
+osm_infr_get_by_enum(
+ IN osm_subn_t const *p_subn,
+ IN osm_log_t *p_log,
+ IN ib_inform_info_record_t* const p_inf_rec );
+/*
+* PARAMETERS
+* p_subn
+* [in] Pointer to the subnet object
+*
+* p_log
+* [in] Pointer to the log object
+*
+* p_inf_rec
+* [in] Pointer to an inform_info record with the search
+* subscriber enum
+*
+* RETURN
+* The matching osm_infr_t
+* SEE ALSO
+* Inform Record, osm_infr_construct, osm_infr_destroy
+*********/
+
/****f* OpenSM: Inform Record/osm_infr_get_by_rec
* NAME
* osm_infr_get_by_rec
diff --git a/osm/include/opensm/osm_msgdef.h b/osm/include/opensm/osm_msgdef.h
index 4439339..73af838 100644
--- a/osm/include/opensm/osm_msgdef.h
+++ b/osm/include/opensm/osm_msgdef.h
@@ -191,6 +191,7 @@ enum
OSM_MSG_MAD_VL_ARB,
OSM_MSG_MAD_SLVL,
OSM_MSG_MAD_GUIDINFO_RECORD,
+ OSM_MSG_MAD_INFORM_INFO_RECORD,
#if defined (VENDOR_RMPP_SUPPORT) && defined (DUAL_SIDED_RMPP)
OSM_MSG_MAD_MULTIPATH_RECORD,
#endif
diff --git a/osm/include/opensm/osm_sa_informinfo.h b/osm/include/opensm/osm_sa_informinfo.h
index 2e57f43..c22c1eb 100644
--- a/osm/include/opensm/osm_sa_informinfo.h
+++ b/osm/include/opensm/osm_sa_informinfo.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2005 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2004-2006 Voltaire, Inc. All rights reserved.
* Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
* Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
*
@@ -33,7 +33,6 @@
*
*/
-
/*
* Abstract:
* Declaration of osm_infr_rcv_t.
@@ -108,6 +107,7 @@ typedef struct _osm_infr_rcv
osm_mad_pool_t *p_mad_pool;
osm_log_t *p_log;
cl_plock_t *p_lock;
+ cl_qlock_pool_t pool;
} osm_infr_rcv_t;
/*
* FIELDS
@@ -123,6 +123,10 @@ typedef struct _osm_infr_rcv
* p_lock
* Pointer to the serializing lock.
*
+* pool
+* Pool of linkable InformInfo Record objects used to
+* generate the query response.
+*
* SEE ALSO
* InformInfo Receiver object
*********/
@@ -262,6 +266,34 @@ osm_infr_rcv_process(
* InformInfo Receiver
*********/
+/****f* OpenSM: InformInfo Record Receiver/osm_infir_rcv_process
+* NAME
+* osm_infir_rcv_process
+*
+* DESCRIPTION
+* Process the InformInfo Record request.
+*
+* SYNOPSIS
+*/
+void
+osm_infir_rcv_process(
+ IN osm_infr_rcv_t* const p_rcv,
+ IN const osm_madw_t* const p_madw );
+/*
+* PARAMETERS
+* p_rcv
+* [in] Pointer to an osm_infr_rcv_t object.
+*
+* p_madw
+* [in] Pointer to the MAD Wrapper containing the MAD
+* that contains the node's InformInfo Record attribute.
+* NOTES
+* This function processes a InformInfo Record attribute.
+*
+* SEE ALSO
+* InformInfo Receiver
+*********/
+
END_C_DECLS
#endif /* _OSM_SA_INFR_H_ */
diff --git a/osm/include/opensm/osm_sa_informinfo_ctrl.h b/osm/include/opensm/osm_sa_informinfo_ctrl.h
index 21dd0a7..a14c5b4 100644
--- a/osm/include/opensm/osm_sa_informinfo_ctrl.h
+++ b/osm/include/opensm/osm_sa_informinfo_ctrl.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2005 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2004-2006 Voltaire, Inc. All rights reserved.
* Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
* Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
*
@@ -103,6 +103,7 @@ typedef struct _osm_infr_rcv_ctrl
osm_log_t *p_log;
cl_dispatcher_t *p_disp;
cl_disp_reg_handle_t h_disp;
+ cl_disp_reg_handle_t h_disp2;
} osm_infr_rcv_ctrl_t;
/*
* FIELDS
diff --git a/osm/opensm/osm_inform.c b/osm/opensm/osm_inform.c
index 178dba2..92647ef 100644
--- a/osm/opensm/osm_inform.c
+++ b/osm/opensm/osm_inform.c
@@ -94,7 +94,7 @@ osm_infr_init(
/* what else do we need in the inform_record ??? */
/* copy the contents of the provided informinfo */
- memcpy(p_infr,p_infr_rec, sizeof(osm_infr_t));
+ memcpy(p_infr, p_infr_rec, sizeof(osm_infr_t));
}
/**********************************************************************
@@ -143,6 +143,54 @@ __match_rid_of_inf_rec(
}
/**********************************************************************
+ * Match an infr by the subscriber GID of the stored inform_info_record
+ **********************************************************************/
+static
+cl_status_t
+__match_gid_of_inf_rec(
+ IN const cl_list_item_t* const p_list_item,
+ IN void* context )
+{
+ ib_inform_info_record_t* p_infr_rec = (ib_inform_info_record_t *)context;
+ osm_infr_t* p_infr = (osm_infr_t*)p_list_item;
+ int32_t count;
+
+ count = memcmp(
+ &p_infr->inform_record,
+ p_infr_rec,
+ sizeof(p_infr_rec->subscriber_gid) );
+
+ if(count == 0)
+ return CL_SUCCESS;
+ else
+ return CL_NOT_FOUND;
+}
+
+/**********************************************************************
+ * Match an infr by the subscriber enum of the stored inform_info_record
+ **********************************************************************/
+static
+cl_status_t
+__match_enum_of_inf_rec(
+ IN const cl_list_item_t* const p_list_item,
+ IN void* context )
+{
+ ib_inform_info_record_t* p_infr_rec = (ib_inform_info_record_t *)context;
+ osm_infr_t* p_infr = (osm_infr_t*)p_list_item;
+ int32_t count;
+
+ count = memcmp(
+ &p_infr->inform_record.subscriber_enum,
+ &p_infr_rec->subscriber_enum,
+ sizeof(p_infr_rec->subscriber_enum) );
+
+ if(count == 0)
+ return CL_SUCCESS;
+ else
+ return CL_NOT_FOUND;
+}
+
+/**********************************************************************
**********************************************************************/
osm_infr_t*
osm_infr_get_by_rid(
@@ -168,6 +216,54 @@ osm_infr_get_by_rid(
/**********************************************************************
**********************************************************************/
+osm_infr_t*
+osm_infr_get_by_gid(
+ IN osm_subn_t const *p_subn,
+ IN osm_log_t *p_log,
+ IN ib_inform_info_record_t* const p_infr_rec )
+{
+ cl_list_item_t* p_list_item;
+
+ OSM_LOG_ENTER( p_log, osm_infr_get_by_gid );
+
+ p_list_item = cl_qlist_find_from_head(
+ &p_subn->sa_infr_list,
+ __match_gid_of_inf_rec,
+ p_infr_rec );
+
+ if( p_list_item == cl_qlist_end( &p_subn->sa_infr_list ) )
+ p_list_item = NULL;
+
+ OSM_LOG_EXIT( p_log );
+ return (osm_infr_t*)p_list_item;
+}
+
+/**********************************************************************
+ **********************************************************************/
+osm_infr_t*
+osm_infr_get_by_enum(
+ IN osm_subn_t const *p_subn,
+ IN osm_log_t *p_log,
+ IN ib_inform_info_record_t* const p_infr_rec )
+{
+ cl_list_item_t* p_list_item;
+
+ OSM_LOG_ENTER( p_log, osm_infr_get_by_enum );
+
+ p_list_item = cl_qlist_find_from_head(
+ &p_subn->sa_infr_list,
+ __match_enum_of_inf_rec,
+ p_infr_rec );
+
+ if( p_list_item == cl_qlist_end( &p_subn->sa_infr_list ) )
+ p_list_item = NULL;
+
+ OSM_LOG_EXIT( p_log );
+ return (osm_infr_t*)p_list_item;
+}
+
+/**********************************************************************
+ **********************************************************************/
void
__dump_all_informs(
IN osm_subn_t const *p_subn,
diff --git a/osm/opensm/osm_sa_informinfo.c b/osm/opensm/osm_sa_informinfo.c
index c979365..2667e49 100644
--- a/osm/opensm/osm_sa_informinfo.c
+++ b/osm/opensm/osm_sa_informinfo.c
@@ -33,7 +33,6 @@
*
*/
-
/*
* Abstract:
* Implementation of osm_infr_rcv_t.
@@ -67,6 +66,26 @@
#include <opensm/osm_inform.h>
#include <opensm/osm_pkey.h>
+#define OSM_IIR_RCV_POOL_MIN_SIZE 32
+#define OSM_IIR_RCV_POOL_GROW_SIZE 32
+
+typedef struct _osm_iir_item
+{
+ cl_pool_item_t pool_item;
+ ib_inform_info_record_t rec;
+} osm_iir_item_t;
+
+typedef struct _osm_iir_search_ctxt
+{
+ const ib_inform_info_record_t* p_rcvd_rec;
+ ib_net64_t comp_mask;
+ cl_qlist_t* p_list;
+ ib_gid_t subscriber_gid;
+ ib_net16_t subscriber_enum;
+ osm_infr_rcv_t* p_rcv;
+ osm_physp_t* p_req_physp;
+} osm_iir_search_ctxt_t;
+
/**********************************************************************
**********************************************************************/
void
@@ -74,6 +93,7 @@ osm_infr_rcv_construct(
IN osm_infr_rcv_t* const p_rcv )
{
memset( p_rcv, 0, sizeof(*p_rcv) );
+ cl_qlock_pool_construct( &p_rcv->pool );
}
/**********************************************************************
@@ -85,7 +105,7 @@ osm_infr_rcv_destroy(
CL_ASSERT( p_rcv );
OSM_LOG_ENTER( p_rcv->p_log, osm_infr_rcv_destroy );
-
+ cl_qlock_pool_destroy( &p_rcv->pool );
OSM_LOG_EXIT( p_rcv->p_log );
}
@@ -112,7 +132,12 @@ osm_infr_rcv_init(
p_rcv->p_resp = p_resp;
p_rcv->p_mad_pool = p_mad_pool;
- status = IB_SUCCESS;
+ status = cl_qlock_pool_init( &p_rcv->pool,
+ OSM_IIR_RCV_POOL_MIN_SIZE,
+ 0,
+ OSM_IIR_RCV_POOL_GROW_SIZE,
+ sizeof(osm_iir_item_t),
+ NULL, NULL, NULL );
OSM_LOG_EXIT( p_rcv->p_log );
return( status );
@@ -333,6 +358,339 @@ __osm_infr_rcv_respond(
}
/**********************************************************************
+ **********************************************************************/
+static void
+__osm_sa_inform_info_rec_by_comp_mask(
+ IN osm_infr_rcv_t* const p_rcv,
+ IN const osm_infr_t* const p_infr,
+ osm_iir_search_ctxt_t* const p_ctxt )
+{
+ const ib_inform_info_record_t* p_rcvd_rec = NULL;
+ ib_net64_t comp_mask;
+ ib_net64_t portguid;
+ osm_port_t * p_subscriber_port;
+ osm_physp_t * p_subscriber_physp;
+ const osm_physp_t* p_req_physp;
+ osm_infr_t* p_infr_rec = NULL;
+ ib_inform_info_record_t inform_info_rec;
+ osm_iir_item_t* p_rec_item;
+
+ OSM_LOG_ENTER( p_rcv->p_log, __osm_sa_inform_info_rec_by_comp_mask );
+
+ p_rcvd_rec = p_ctxt->p_rcvd_rec;
+ comp_mask = p_ctxt->comp_mask;
+ p_req_physp = p_ctxt->p_req_physp;
+
+ /* Both subscriber GID and enum specified */
+ if ((comp_mask & IB_IIR_COMPMASK_SUBSCRIBERGID) &&
+ (comp_mask & IB_IIR_COMPMASK_ENUM))
+ {
+ inform_info_rec.subscriber_gid = p_ctxt->subscriber_gid;
+ inform_info_rec.subscriber_enum = p_ctxt->subscriber_enum;
+ p_infr_rec = osm_infr_get_by_rid(p_rcv->p_subn, p_rcv->p_log, &inform_info_rec);
+ goto Done;
+ }
+
+ if (comp_mask & IB_IIR_COMPMASK_SUBSCRIBERGID)
+ {
+ inform_info_rec.subscriber_gid = p_ctxt->subscriber_gid;
+ p_infr_rec = osm_infr_get_by_gid(p_rcv->p_subn, p_rcv->p_log, &inform_info_rec);
+ goto Done;
+ }
+
+ if (comp_mask & IB_IIR_COMPMASK_ENUM)
+ {
+ inform_info_rec.subscriber_enum = p_ctxt->subscriber_enum;
+ p_infr_rec = osm_infr_get_by_enum(p_rcv->p_subn, p_rcv->p_log, &inform_info_rec);
+ goto Done;
+ }
+
+ /* Implement any other needed search cases */
+
+Done:
+ if (p_infr_rec)
+ {
+ /* Ensure pkey is shared before returning any records */
+ portguid = p_infr_rec->inform_record.subscriber_gid.unicast.interface_id;
+ p_subscriber_port = osm_get_port_by_guid( p_rcv->p_subn, portguid);
+ if ( p_subscriber_port == NULL )
+ {
+ osm_log( p_rcv->p_log, OSM_LOG_ERROR,
+ "__osm_sa_inform_info_rec_by_comp_mask: ERR 430D: "
+ "Invalid subscriber port guid: 0x%016" PRIx64 "\n",
+ cl_ntoh64(portguid) );
+ goto Exit;
+ }
+
+ /* get the subscriber InformInfo physical port */
+ p_subscriber_physp = osm_port_get_default_phys_ptr(p_subscriber_port);
+ /* make sure that the requester and subscriber port can access each other
+ according to the current partitioning. */
+ if (! osm_physp_share_pkey( p_rcv->p_log, p_req_physp, p_subscriber_physp))
+ {
+ osm_log( p_rcv->p_log, OSM_LOG_DEBUG,
+ "__osm_sa_inform_info_rec_by_comp_mask: "
+ "requester and subscriber ports don't share pkey\n" );
+ goto Exit;
+ }
+
+ p_rec_item = (osm_iir_item_t*)cl_qlock_pool_get( &p_rcv->pool );
+ if( p_rec_item == NULL )
+ {
+ osm_log( p_rcv->p_log, OSM_LOG_ERROR,
+ "__osm_sa_inform_info_rec_by_comp_mask: ERR 430E: "
+ "cl_qlock_pool_get failed\n" );
+ goto Exit;
+ }
+
+ memcpy((void *)&p_rec_item->rec, (void *)&p_infr_rec->inform_record, sizeof(ib_inform_info_record_t));
+ cl_qlist_insert_tail( p_ctxt->p_list, (cl_list_item_t*)&p_rec_item->pool_item );
+ }
+
+Exit:
+ OSM_LOG_EXIT( p_rcv->p_log );
+}
+
+/**********************************************************************
+ **********************************************************************/
+static void
+__osm_sa_inform_info_rec_by_comp_mask_cb(
+ IN cl_list_item_t* const p_list_item,
+ IN void* context )
+{
+ const osm_infr_t* const p_infr = (osm_infr_t *)p_list_item;
+ osm_iir_search_ctxt_t* const p_ctxt = (osm_iir_search_ctxt_t *)context;
+
+ __osm_sa_inform_info_rec_by_comp_mask( p_ctxt->p_rcv, p_infr, p_ctxt );
+}
+
+/**********************************************************************
+Received a Get(InformInfoRecord) or GetTable(InformInfoRecord) MAD
+**********************************************************************/
+static void
+osm_infr_rcv_process_get_method(
+ IN osm_infr_rcv_t* const p_rcv,
+ IN const osm_madw_t* const p_madw )
+{
+ ib_sa_mad_t* p_rcvd_mad;
+ const ib_inform_info_record_t* p_rcvd_rec;
+ ib_inform_info_record_t* p_resp_rec;
+ cl_qlist_t rec_list;
+ osm_madw_t* p_resp_madw;
+ ib_sa_mad_t* p_resp_sa_mad;
+ uint32_t num_rec, pre_trim_num_rec;
+#ifndef VENDOR_RMPP_SUPPORT
+ uint32_t trim_num_rec;
+#endif
+ uint32_t i, j;
+ osm_iir_search_ctxt_t context;
+ osm_iir_item_t* p_rec_item;
+ ib_api_status_t status = IB_SUCCESS;
+ osm_physp_t* p_req_physp;
+
+ OSM_LOG_ENTER( p_rcv->p_log, osm_infr_rcv_process_get_method );
+
+ CL_ASSERT( p_madw );
+ p_rcvd_mad = osm_madw_get_sa_mad_ptr( p_madw );
+ p_rcvd_rec =
+ (ib_inform_info_record_t*)ib_sa_mad_get_payload_ptr( p_rcvd_mad );
+
+ /* update the requester physical port. */
+ p_req_physp = osm_get_physp_by_mad_addr(p_rcv->p_log,
+ p_rcv->p_subn,
+ osm_madw_get_mad_addr_ptr(p_madw) );
+ if (p_req_physp == NULL)
+ {
+ osm_log( p_rcv->p_log, OSM_LOG_ERROR,
+ "osm_infr_rcv_process_get_method: ERR 4309: "
+ "Cannot find requester physical port\n" );
+ goto Exit;
+ }
+
+ if( osm_log_is_active( p_rcv->p_log, OSM_LOG_DEBUG ) )
+ osm_dump_inform_info_record( p_rcv->p_log, p_rcvd_rec, OSM_LOG_DEBUG );
+
+ cl_qlist_init( &rec_list );
+
+ context.p_rcvd_rec = p_rcvd_rec;
+ context.p_list = &rec_list;
+ context.comp_mask = p_rcvd_mad->comp_mask;
+ context.subscriber_gid = p_rcvd_rec->subscriber_gid;
+ context.subscriber_enum = p_rcvd_rec->subscriber_enum;
+ context.p_rcv = p_rcv;
+ context.p_req_physp = p_req_physp;
+
+ osm_log( p_rcv->p_log, OSM_LOG_DEBUG,
+ "osm_infr_rcv_process_get_method: "
+ "Query Subscriber GID:0x%016" PRIx64 " : 0x%016" PRIx64 "(%02X) Enum:0x%X(%02X)\n",
+ cl_ntoh64(p_rcvd_rec->subscriber_gid.unicast.prefix),
+ cl_ntoh64(p_rcvd_rec->subscriber_gid.unicast.interface_id),
+ (p_rcvd_mad->comp_mask & IB_IIR_COMPMASK_SUBSCRIBERGID) != 0,
+ cl_ntoh16(p_rcvd_rec->subscriber_enum),
+ (p_rcvd_mad->comp_mask & IB_IIR_COMPMASK_ENUM) != 0 );
+
+ /* Only Enum 0 is supported currently!!! */
+ if (((p_rcvd_mad->comp_mask & IB_IIR_COMPMASK_ENUM) == 0) || (p_rcvd_rec->subscriber_enum == 0))
+ {
+ cl_plock_acquire( p_rcv->p_lock );
+
+ cl_qlist_apply_func( &p_rcv->p_subn->sa_infr_list,
+ __osm_sa_inform_info_rec_by_comp_mask_cb,
+ &context );
+
+ cl_plock_release( p_rcv->p_lock );
+ }
+ else
+ {
+ osm_log( p_rcv->p_log, OSM_LOG_DEBUG,
+ "osm_infr_rcv_process_get_method: "
+ "Non-zero Enum is not currently supported\n" );
+ }
+
+ num_rec = cl_qlist_count( &rec_list );
+
+ /*
+ * C15-0.1.30:
+ * If we do a SubnAdmGet and got more than one record it is an error !
+ */
+ if (p_rcvd_mad->method == IB_MAD_METHOD_GET)
+ {
+ if (num_rec == 0)
+ {
+ osm_sa_send_error( p_rcv->p_resp, p_madw, IB_SA_MAD_STATUS_NO_RECORDS );
+ goto Exit;
+ }
+ if (num_rec > 1)
+ {
+ osm_log( p_rcv->p_log, OSM_LOG_ERROR,
+ "osm_infr_rcv_process_get_method: ERR 430A: "
+ "More than one record for SubnAdmGet (%u)\n",
+ num_rec );
+ osm_sa_send_error( p_rcv->p_resp, p_madw,
+ IB_SA_MAD_STATUS_TOO_MANY_RECORDS);
+
+ /* need to set the mem free ... */
+ p_rec_item = (osm_iir_item_t*)cl_qlist_remove_head( &rec_list );
+ while( p_rec_item != (osm_iir_item_t*)cl_qlist_end( &rec_list ) )
+ {
+ cl_qlock_pool_put( &p_rcv->pool, &p_rec_item->pool_item );
+ p_rec_item = (osm_iir_item_t*)cl_qlist_remove_head( &rec_list );
+ }
+
+ goto Exit;
+ }
+ }
+
+ pre_trim_num_rec = num_rec;
+#ifndef VENDOR_RMPP_SUPPORT
+ /* we limit the number of records to a single packet */
+ trim_num_rec = (MAD_BLOCK_SIZE - IB_SA_MAD_HDR_SIZE) / sizeof(ib_inform_info_record_t);
+ if (trim_num_rec < num_rec)
+ {
+ osm_log( p_rcv->p_log, OSM_LOG_VERBOSE,
+ "osm_infr_rcv_process_get_method: "
+ "Number of records:%u trimmed to:%u to fit in one MAD\n",
+ num_rec, trim_num_rec );
+ num_rec = trim_num_rec;
+ }
+#endif
+
+ osm_log( p_rcv->p_log, OSM_LOG_DEBUG,
+ "osm_infr_rcv_process_get_method: "
+ "Returning %u records\n", num_rec );
+
+ /*
+ * Get a MAD to reply. Address of Mad is in the received mad_wrapper
+ */
+ p_resp_madw = osm_mad_pool_get( p_rcv->p_mad_pool,
+ p_madw->h_bind,
+ num_rec * sizeof(ib_inform_info_record_t) + IB_SA_MAD_HDR_SIZE,
+ &p_madw->mad_addr );
+
+ if( !p_resp_madw )
+ {
+ osm_log(p_rcv->p_log, OSM_LOG_ERROR,
+ "osm_infr_rcv_process_get_method: ERR 430B: "
+ "osm_mad_pool_get failed\n" );
+
+ for( i = 0; i < num_rec; i++ )
+ {
+ p_rec_item = (osm_iir_item_t*)cl_qlist_remove_head( &rec_list );
+ cl_qlock_pool_put( &p_rcv->pool, &p_rec_item->pool_item );
+ }
+
+ osm_sa_send_error( p_rcv->p_resp, p_madw,
+ IB_SA_MAD_STATUS_NO_RESOURCES );
+
+ goto Exit;
+ }
+
+ p_resp_sa_mad = osm_madw_get_sa_mad_ptr( p_resp_madw );
+
+ /*
+ Copy the MAD header back into the response mad.
+ Set the 'R' bit and the payload length,
+ Then copy all records from the list into the response payload.
+ */
+
+ memcpy( p_resp_sa_mad, p_rcvd_mad, IB_SA_MAD_HDR_SIZE );
+ p_resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK;
+ /* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) */
+ p_resp_sa_mad->sm_key = 0;
+ /* Fill in the offset (paylen will be done by the rmpp SAR) */
+ p_resp_sa_mad->attr_offset =
+ ib_get_attr_offset( sizeof(ib_inform_info_record_t) );
+
+ p_resp_rec = (ib_inform_info_record_t*)ib_sa_mad_get_payload_ptr( p_resp_sa_mad );
+
+#ifndef VENDOR_RMPP_SUPPORT
+ /* we support only one packet RMPP - so we will set the first and
+ last flags for gettable */
+ if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP)
+ {
+ p_resp_sa_mad->rmpp_type = IB_RMPP_TYPE_DATA;
+ p_resp_sa_mad->rmpp_flags = IB_RMPP_FLAG_FIRST | IB_RMPP_FLAG_LAST | IB_RMPP_FLAG_ACTIVE;
+ }
+#else
+ /* forcefully define the packet as RMPP one */
+ if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP)
+ p_resp_sa_mad->rmpp_flags = IB_RMPP_FLAG_ACTIVE;
+#endif
+
+ for( i = 0; i < pre_trim_num_rec; i++ )
+ {
+ p_rec_item = (osm_iir_item_t*)cl_qlist_remove_head( &rec_list );
+ /* copy only if not trimmed */
+ if (i < num_rec)
+ {
+ *p_resp_rec = p_rec_item->rec;
+ /* clear reserved and pad fields in InformInfoRecord */
+ for (j = 0; j < 6; j++)
+ p_resp_rec->reserved[j] = 0;
+ for (j = 0; j < 4; j++)
+ p_resp_rec->pad[j] = 0;
+ }
+ cl_qlock_pool_put( &p_rcv->pool, &p_rec_item->pool_item );
+ p_resp_rec++;
+ }
+
+ CL_ASSERT( cl_is_qlist_empty( &rec_list ) );
+
+ status = osm_vendor_send( p_resp_madw->h_bind, p_resp_madw, FALSE );
+ if (status != IB_SUCCESS)
+ {
+ osm_log(p_rcv->p_log, OSM_LOG_ERROR,
+ "osm_infr_rcv_process_get_method: ERR 430C: "
+ "osm_vendor_send status = %s\n",
+ ib_get_err_str(status));
+ goto Exit;
+ }
+
+ Exit:
+ OSM_LOG_EXIT( p_rcv->p_log );
+}
+
+/*********************************************************************
Received a Set(InformInfo) MAD
**********************************************************************/
static void
@@ -395,6 +753,12 @@ osm_infr_rcv_process_set_method(
osm_sa_send_error( p_rcv->p_resp, p_madw, IB_SA_MAD_STATUS_REQ_INVALID );
goto Exit;
}
+osm_log( p_rcv->p_log, OSM_LOG_ERROR,
+ "osm_infr_rcv_process_set_method: "
+ "LID 0x%04X GID 0x%016" PRIx64 " : 0x%016" PRIx64"\n",
+ cl_ntoh16(p_madw->mad_addr.dest_lid),
+ cl_ntoh64(inform_info_rec.inform_record.subscriber_gid.unicast.prefix),
+ cl_ntoh64(inform_info_rec.inform_record.subscriber_gid.unicast.interface_id));
/*
* MODIFICATIONS DONE ON INCOMING REQUEST:
@@ -472,7 +836,6 @@ osm_infr_rcv_process_set_method(
/* Add this new osm_infr_t object to subnet object */
osm_infr_insert_to_db( p_rcv->p_subn, p_rcv->p_log, p_infr );
-
}
else
{
@@ -513,6 +876,8 @@ osm_infr_rcv_process_set_method(
OSM_LOG_EXIT( p_rcv->p_log );
}
+/*********************************************************************
+**********************************************************************/
void
osm_infr_rcv_process(
IN osm_infr_rcv_t* const p_rcv,
@@ -543,3 +908,37 @@ osm_infr_rcv_process(
Exit:
OSM_LOG_EXIT( p_rcv->p_log );
}
+
+/*********************************************************************
+**********************************************************************/
+void
+osm_infir_rcv_process(
+ IN osm_infr_rcv_t* const p_rcv,
+ IN const osm_madw_t* const p_madw )
+{
+ ib_sa_mad_t *p_sa_mad;
+
+ OSM_LOG_ENTER( p_rcv->p_log, osm_infr_rcv_process );
+
+ CL_ASSERT( p_madw );
+
+ p_sa_mad = osm_madw_get_sa_mad_ptr( p_madw );
+
+ CL_ASSERT( p_sa_mad->attr_id == IB_MAD_ATTR_INFORM_INFO_RECORD );
+
+ if ( (p_sa_mad->method != IB_MAD_METHOD_GET) &&
+ (p_sa_mad->method != IB_MAD_METHOD_GETTABLE) )
+ {
+ osm_log( p_rcv->p_log, OSM_LOG_DEBUG,
+ "osm_infir_rcv_process: "
+ "Unsupported Method (%s)\n",
+ ib_get_sa_method_str( p_sa_mad->method ) );
+ osm_sa_send_error( p_rcv->p_resp, p_madw, IB_MAD_STATUS_UNSUP_METHOD_ATTR );
+ goto Exit;
+ }
+
+ osm_infr_rcv_process_get_method( p_rcv, p_madw );
+
+ Exit:
+ OSM_LOG_EXIT( p_rcv->p_log );
+}
diff --git a/osm/opensm/osm_sa_informinfo_ctrl.c b/osm/opensm/osm_sa_informinfo_ctrl.c
index 76fc402..1637155 100644
--- a/osm/opensm/osm_sa_informinfo_ctrl.c
+++ b/osm/opensm/osm_sa_informinfo_ctrl.c
@@ -33,7 +33,6 @@
*
*/
-
/*
* Abstract:
* Implementation of osm_infr_rcv_ctrl_t.
@@ -68,12 +67,25 @@ __osm_infr_rcv_ctrl_disp_callback(
/**********************************************************************
**********************************************************************/
+static void
+__osm_infir_rcv_ctrl_disp_callback(
+ IN void *context,
+ IN void *p_data )
+{
+ /* ignore return status when invoked via the dispatcher */
+ osm_infir_rcv_process( ((osm_infr_rcv_ctrl_t*)context)->p_rcv,
+ (osm_madw_t*)p_data );
+}
+
+/**********************************************************************
+ **********************************************************************/
void
osm_infr_rcv_ctrl_construct(
IN osm_infr_rcv_ctrl_t* const p_ctrl )
{
memset( p_ctrl, 0, sizeof(*p_ctrl) );
p_ctrl->h_disp = CL_DISP_INVALID_HANDLE;
+ p_ctrl->h_disp2 = CL_DISP_INVALID_HANDLE;
}
/**********************************************************************
@@ -83,6 +95,7 @@ osm_infr_rcv_ctrl_destroy(
IN osm_infr_rcv_ctrl_t* const p_ctrl )
{
CL_ASSERT( p_ctrl );
+ cl_disp_unregister( p_ctrl->h_disp2 );
cl_disp_unregister( p_ctrl->h_disp );
}
@@ -119,6 +132,22 @@ osm_infr_rcv_ctrl_init(
goto Exit;
}
+ p_ctrl->h_disp2 = cl_disp_register(
+ p_disp,
+ OSM_MSG_MAD_INFORM_INFO_RECORD,
+ __osm_infir_rcv_ctrl_disp_callback,
+ p_ctrl );
+
+ if( p_ctrl->h_disp2 == CL_DISP_INVALID_HANDLE )
+ {
+ osm_log( p_log, OSM_LOG_ERROR,
+ "osm_infr_rcv_ctrl_init: ERR 1702: "
+ "Dispatcher registration failed\n" );
+ cl_disp_unregister( p_ctrl->h_disp );
+ status = IB_INSUFFICIENT_RESOURCES;
+ goto Exit;
+ }
+
Exit:
OSM_LOG_EXIT( p_log );
return( status );
diff --git a/osm/opensm/osm_sa_mad_ctrl.c b/osm/opensm/osm_sa_mad_ctrl.c
index 56386b1..2605fbf 100644
--- a/osm/opensm/osm_sa_mad_ctrl.c
+++ b/osm/opensm/osm_sa_mad_ctrl.c
@@ -208,6 +208,10 @@ __osm_sa_mad_ctrl_process(
msg_id = OSM_MSG_MAD_GUIDINFO_RECORD;
break;
+ case IB_MAD_ATTR_INFORM_INFO_RECORD:
+ msg_id = OSM_MSG_MAD_INFORM_INFO_RECORD;
+ break;
+
#if defined (VENDOR_RMPP_SUPPORT) && defined (DUAL_SIDED_RMPP)
case IB_MAD_ATTR_MULTIPATH_RECORD:
msg_id = OSM_MSG_MAD_MULTIPATH_RECORD;
More information about the general
mailing list