[openib-general] [PATCH] OpenSM/osm_sa_link_record.c: Fix LMC > 0 handling

Hal Rosenstock halr at voltaire.com
Mon Jun 19 09:39:54 PDT 2006


OpenSM/osm_sa_link_record.c: Fix LMC > 0 handling

In osm_sa_link_record.c, properly handle non base LID requests
per C15-0.1.11: Query responses shall contain a port's base LID in
any LID component of a RID. So when LMC is non 0, the only records that
appear are those with the base LID and not with any masked LIDs.
Furthermore, if a query comes in on a non base LID, the LID in the RID
returned is only with the base LID.

To do this, added new routine osm_get_port_by_base_lid in osm_port.c for
use by other SA records.

Also, fixed some error handling for SA GetTable LinkRecord requests.

Also, added more SA LinkRecord test cases to osmtest/osmtest.c

Signed-off-by: Hal Rosenstock <halr at voltaire.com>

Index: include/opensm/osm_port.h
===================================================================
--- include/opensm/osm_port.h	(revision 8108)
+++ include/opensm/osm_port.h	(working copy)
@@ -1737,6 +1737,42 @@ osm_port_get_lid_range_ho(
 *	Port
 *********/
 
+/****f* OpenSM: Port/osm_get_port_by_base_lid
+* NAME
+*	osm_get_port_by_base_lid
+*
+* DESCRIPTION
+*	Returns a status on whether a Port was able to be 
+*	determined based on the LID supplied and if so, return the Port.
+*
+* SYNOPSIS
+*/
+ib_api_status_t
+osm_get_port_by_base_lid(
+	IN const osm_subn_t*       const p_subn,
+	IN const ib_net16_t        lid,
+	IN OUT const osm_port_t**  const pp_port );
+/*
+* PARAMETERS
+*	p_subn
+*		[in] Pointer to the subnet data structure.
+*
+*	lid
+*		[in] LID requested.
+*
+*	pp_port
+*		[in][out] Pointer to pointer to Port object.
+*
+* RETURN VALUES
+*	IB_SUCCESS
+*	IB_NOT_FOUND 
+*
+* NOTES
+*
+* SEE ALSO
+*       Port
+*********/
+
 /****f* OpenSM: Port/osm_port_add_new_physp
 * NAME
 *	osm_port_add_new_physp
Index: opensm/osm_port.c
===================================================================
--- opensm/osm_port.c	(revision 8108)
+++ opensm/osm_port.c	(working copy)
@@ -266,6 +266,44 @@ osm_port_get_lid_range_ho(
 
 /**********************************************************************
  **********************************************************************/
+ib_api_status_t
+osm_get_port_by_base_lid(
+  IN const osm_subn_t*      const p_subn,
+  IN const ib_net16_t       lid,
+  IN OUT const osm_port_t** const pp_port )
+{
+  ib_api_status_t           status;
+  uint16_t                  base_lid; 
+  uint8_t                   lmc;
+
+  *pp_port = NULL;
+
+  /* Loop on lmc from 0 up through max LMC */
+  for (lmc = 0; lmc <= IB_PORT_LMC_MAX; lmc++)
+  {
+    /* Calculate a base LID assuming this is the real LMC */
+    base_lid = (cl_ntoh16(lid) & ~(1 << lmc));
+
+    /* Look for a match */
+    status = cl_ptr_vector_at( &p_subn->port_lid_tbl,
+                               base_lid,
+                               (void**)pp_port );
+    if ((status == CL_SUCCESS) && (*pp_port != NULL))
+    {
+       /* Determine if base LID "tested" is the real base LID */
+       /* This is true if the LMC "tested" is the port's actual LMC */
+       if (lmc == osm_port_get_lmc( *pp_port ) )
+         goto Found;
+    }
+  }
+  status = IB_NOT_FOUND;
+
+ Found:
+  return status;
+}
+
+/**********************************************************************
+ **********************************************************************/
 void
 osm_port_add_new_physp(
   IN osm_port_t* const p_port,
Index: opensm/osm_sa_link_record.c
===================================================================
--- opensm/osm_sa_link_record.c	(revision 8108)
+++ opensm/osm_sa_link_record.c	(working copy)
@@ -209,7 +209,6 @@ __osm_lr_rcv_get_physp_link(
   ib_net16_t                  from_max_lid_ho;
   ib_net16_t                  to_max_lid_ho;
   ib_net16_t                  to_base_lid_ho;
-  uint16_t                    i, j;
 
   OSM_LOG_ENTER( p_rcv->p_log, __osm_lr_rcv_get_physp_link );
 
@@ -313,30 +312,12 @@ __osm_lr_rcv_get_physp_link(
              dest_port_num );
   }
 
-  if( comp_mask & IB_LR_COMPMASK_FROM_LID )
-  {
-    from_max_lid_ho = from_base_lid_ho = cl_ntoh16(p_lr->from_lid);
-  }
-  else
-  {
-    __get_lid_range(p_src_physp, &from_base_lid_ho, &from_max_lid_ho);
-  }
+  __get_lid_range(p_src_physp, &from_base_lid_ho, &from_max_lid_ho);
+  __get_lid_range(p_dest_physp, &to_base_lid_ho, &to_max_lid_ho);
 
-  if( comp_mask & IB_LR_COMPMASK_TO_LID )
-  {
-    to_max_lid_ho = to_base_lid_ho = cl_ntoh16(p_lr->to_lid);
-  }
-  else
-  {
-    __get_lid_range(p_dest_physp, &to_base_lid_ho, &to_max_lid_ho);
-  }
-
-  for (i = from_base_lid_ho; i <= from_max_lid_ho; i++)
-  {
-    for(j = to_base_lid_ho; j <= to_max_lid_ho; j++)
-      __osm_lr_rcv_build_physp_link(p_rcv, cl_ntoh16(i), cl_ntoh16(j),
-                                    src_port_num, dest_port_num, p_list);
-  }
+  __osm_lr_rcv_build_physp_link(p_rcv, cl_ntoh16(from_base_lid_ho),
+                                cl_ntoh16(to_base_lid_ho),
+                                src_port_num, dest_port_num, p_list);
 
  Exit:
   OSM_LOG_EXIT( p_rcv->p_log );
@@ -515,12 +496,11 @@ __osm_lr_rcv_get_end_points(
 
   if( p_sa_mad->comp_mask & IB_LR_COMPMASK_FROM_LID )
   {
-    status = cl_ptr_vector_at( &p_rcv->p_subn->port_lid_tbl,
-                               cl_ntoh16(p_lr->from_lid),
-                               (void**)pp_src_port );
+    status = osm_get_port_by_base_lid( p_rcv->p_subn,
+                                       p_lr->from_lid,
+                                       pp_src_port );
 
-    if( ( (status != CL_SUCCESS) || (*pp_src_port == NULL) ) &&
-          (p_sa_mad->method == IB_MAD_METHOD_GET) )
+    if( (status != CL_SUCCESS) || (*pp_src_port == NULL) )
     {
       /*
         This 'error' is the client's fault (bad lid) so
@@ -539,12 +519,11 @@ __osm_lr_rcv_get_end_points(
 
   if( p_sa_mad->comp_mask & IB_LR_COMPMASK_TO_LID )
   {
-    status = cl_ptr_vector_at( &p_rcv->p_subn->port_lid_tbl,
-                               cl_ntoh16(p_lr->to_lid),
-                               (void**)pp_dest_port );
+    status = osm_get_port_by_base_lid( p_rcv->p_subn,
+                                       p_lr->to_lid,
+                                       pp_dest_port );
 
-    if( ( (status != CL_SUCCESS) || (*pp_dest_port == NULL) ) &&
-          (p_sa_mad->method == IB_MAD_METHOD_GET) )
+    if( (status != CL_SUCCESS) || (*pp_dest_port == NULL) )
     {
       /*
         This 'error' is the client's fault (bad lid) so
@@ -732,8 +711,8 @@ osm_lr_rcv_process(
 {
   const ib_link_record_t*  p_lr;
   const ib_sa_mad_t*       p_sa_mad;
-  const osm_port_t*        p_src_port = NULL;
-  const osm_port_t*        p_dest_port = NULL;
+  const osm_port_t*        p_src_port;
+  const osm_port_t*        p_dest_port;
   cl_qlist_t               lr_list;
   ib_net16_t               sa_status;
   osm_physp_t*             p_req_physp;
@@ -784,16 +763,12 @@ osm_lr_rcv_process(
   sa_status = __osm_lr_rcv_get_end_points( p_rcv, p_madw,
                                            &p_src_port, &p_dest_port );
 
-  if( sa_status != IB_SA_MAD_STATUS_SUCCESS )
+  if( sa_status == IB_SA_MAD_STATUS_SUCCESS )
   {
-    cl_plock_release( p_rcv->p_lock );
-    osm_sa_send_error( p_rcv->p_resp, p_madw, sa_status );
-    goto Exit;
+    __osm_lr_rcv_get_port_links( p_rcv, p_lr, p_src_port, p_dest_port,
+                                 p_sa_mad->comp_mask, &lr_list, p_req_physp );
   }
 
-  __osm_lr_rcv_get_port_links( p_rcv, p_lr, p_src_port, p_dest_port,
-                               p_sa_mad->comp_mask, &lr_list, p_req_physp );
-
   cl_plock_release( p_rcv->p_lock );
 
   if( (cl_qlist_count( &lr_list ) == 0) &&
Index: osmtest/osmtest.c
===================================================================
--- osmtest/osmtest.c	(revision 8109)
+++ osmtest/osmtest.c	(working copy)
@@ -4309,6 +4309,99 @@ osmtest_validate_all_path_recs( IN osmte
   OSM_LOG_EXIT( &p_osmt->log );
   return ( status );
 }
+
+/**********************************************************************
+ * Get link record by LID
+ **********************************************************************/
+ib_api_status_t
+osmtest_get_link_rec_by_lid( IN osmtest_t * const p_osmt,
+                             IN ib_net16_t const  from_lid,
+                             IN ib_net16_t const  to_lid,
+                             IN OUT osmtest_req_context_t * const p_context )
+{
+  ib_api_status_t status = IB_SUCCESS;
+  osmv_user_query_t user;
+  osmv_query_req_t req;
+  ib_link_record_t record;
+  ib_mad_t *p_mad;
+
+  OSM_LOG_ENTER( &p_osmt->log, osmtest_get_link_rec_by_lid );
+
+  if( osm_log_is_active( &p_osmt->log, OSM_LOG_VERBOSE ) )
+  {
+    osm_log( &p_osmt->log, OSM_LOG_VERBOSE,
+             "osmtest_get_link_rec_by_lid: "
+             "Getting link record from LID 0x%02X to LID 0x%02X\n",
+             cl_ntoh16( from_lid ), cl_ntoh16( to_lid ) );
+  }
+
+  /*
+   * Do a blocking query for this record in the subnet.
+   * The result is returned in the result field of the caller's
+   * context structure.
+   *
+   * The query structures are locals.
+   */
+  memset( &req, 0, sizeof( req ) );
+  memset( &user, 0, sizeof( user ) );
+  memset( &record, 0, sizeof( record ) );
+
+  record.from_lid = from_lid;
+  record.to_lid = to_lid;
+  p_context->p_osmt = p_osmt;
+  if (from_lid)
+    user.comp_mask |= IB_LR_COMPMASK_FROM_LID;
+  if (to_lid)
+    user.comp_mask |= IB_LR_COMPMASK_TO_LID;
+  user.attr_id = IB_MAD_ATTR_LINK_RECORD;
+  user.attr_offset = cl_ntoh16( ( uint16_t ) ( sizeof( record ) >> 3 ) );
+  user.p_attr = &record;
+
+  req.query_type = OSMV_QUERY_USER_DEFINED;
+  req.timeout_ms = p_osmt->opt.transaction_timeout;
+  req.retry_cnt = p_osmt->opt.retry_count;
+  req.flags = OSM_SA_FLAGS_SYNC;
+  req.query_context = p_context;
+  req.pfn_query_cb = osmtest_query_res_cb;
+  req.p_query_input = &user;
+  req.sm_key = 0;
+
+  status = osmv_query_sa( p_osmt->h_bind, &req );
+  if( status != IB_SUCCESS )
+  {
+    osm_log( &p_osmt->log, OSM_LOG_ERROR,
+             "osmtest_get_link_rec_by_lid: ERR 007A: "
+             "ib_query failed (%s)\n", ib_get_err_str( status ) );
+    goto Exit;
+  }
+
+  status = p_context->result.status;
+
+  if( status != IB_SUCCESS )
+  {
+    if (status != IB_INVALID_PARAMETER)
+    {
+      osm_log( &p_osmt->log, OSM_LOG_ERROR,
+               "osmtest_get_link_rec_by_lid: ERR 007B: "
+               "ib_query failed (%s)\n", ib_get_err_str( status ) );
+    }
+    if( status == IB_REMOTE_ERROR )
+    {
+      p_mad = osm_madw_get_mad_ptr( p_context->result.p_result_madw );
+      osm_log( &p_osmt->log, OSM_LOG_ERROR,
+               "osmtest_get_link_rec_by_lid: "
+               "Remote error = %s\n",
+               ib_get_mad_status_str( p_mad ));
+
+      status = (ib_net16_t) (p_mad->status & IB_SMP_STATUS_MASK );
+    }
+    goto Exit;
+  }
+
+ Exit:
+  OSM_LOG_EXIT( &p_osmt->log );
+  return ( status );
+}
 #endif
 
 /**********************************************************************
@@ -4891,9 +4984,10 @@ osmtest_validate_against_db( IN osmtest_
 {
   ib_api_status_t status = IB_SUCCESS;
 #ifdef VENDOR_RMPP_SUPPORT
+  ib_net16_t test_lid;
   uint8_t lmc;
-#ifdef DUAL_SIDED_RMPP
   osmtest_req_context_t context;
+#ifdef DUAL_SIDED_RMPP
   osmv_multipath_req_t request;
 #endif
 #endif
@@ -5003,6 +5097,7 @@ osmtest_validate_against_db( IN osmtest_
 #endif
 
 #ifdef VENDOR_RMPP_SUPPORT
+  /* GUIDInfoRecords */
   status = osmtest_validate_all_guidinfo_recs( p_osmt );
   if( status != IB_SUCCESS )
     goto Exit;
@@ -5019,6 +5114,43 @@ osmtest_validate_against_db( IN osmtest_
       goto Exit;
   }
 
+  /* Some LinkRecord tests */
+  test_lid = cl_ntoh16( p_osmt->local_port.lid );
+  /* FromLID */
+  memset( &context, 0, sizeof( context ) );
+  status = osmtest_get_link_rec_by_lid( p_osmt, test_lid, 0, &context );
+  if ( status != IB_SUCCESS )
+    goto Exit;
+
+  /* ToLID */
+  memset( &context, 0, sizeof( context ) );
+  status = osmtest_get_link_rec_by_lid( p_osmt, 0, test_lid, &context );
+  if ( status != IB_SUCCESS )
+    goto Exit;
+
+  /* FromLID & ToLID */
+  memset( &context, 0, sizeof( context ) );
+  status = osmtest_get_link_rec_by_lid( p_osmt, test_lid, test_lid, &context );
+  if ( status != IB_SUCCESS )
+    goto Exit;
+
+  if (lmc != 0)
+  {
+    test_lid = cl_ntoh16( p_osmt->local_port.lid + 1 );
+    /* FromLID */
+    memset( &context, 0, sizeof( context ) );
+    status = osmtest_get_link_rec_by_lid( p_osmt, test_lid, 0, &context );
+    if ( status != IB_SUCCESS )
+      goto Exit;
+
+    /* ToLID */
+    memset( &context, 0, sizeof( context ) );
+    status = osmtest_get_link_rec_by_lid( p_osmt, 0, test_lid, &context );
+    if ( status != IB_SUCCESS )
+      goto Exit;
+  }
+
+  /* PathRecords */
   if (! p_osmt->opt.ignore_path_records)
   {
     status = osmtest_validate_all_path_recs( p_osmt );








More information about the general mailing list