From e4fdf69174df1ab0d4760dcb681177b5be1eff44 Mon Sep 17 00:00:00 2001 From: eitan Date: Tue, 4 Apr 2006 08:55:14 +0000 Subject: [PATCH] [OpenSM] - This change fixes the retrieval of the MCMember records according to Errata MGTWG3280. Quoting from MGTWG3280: SA can be queried for multicast groups by sending a SubnAdmGet() or a SubnAdmGetTable() request to it using the SA query mechanism (see 15.4.4 Administration Query Subsystem on page 923). What SA returns in response to a query of multicast groups depends strongly on whether the request is or is not a trusted request; the degree of trust affects both the data returned in each attribute and the set of attributes that are returned. See . o15-0.2.5 is made obsolete. So we need to implement the following descriptive text: SA can be queried for multicast groups by sending a SubnAdmGet() or a SubnAdmGetTable() request to it using the SA query mechanism (see 15.4.4 Administration Query Subsystem on page 923). SA will return one MCMemberRecord per multicast group matching the query, except in cases where trust is specified as indicated in 15.4.1.2 Access Restrictions For Other Attributes on page 922; in that case all the MCMemberRecords associated with the multicast group are returned. The MCMemberRecord will be returned with the PortGID, ProxyJoin, and the JoinState components set to 0, except where trust is specified as indicated above, in that case the actual contents for the above components will be provided. Signed-off-by: Ofer Gigi git-svn-id: svn://openib.tc.cornell.edu/gen1@280 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86 --- .../user/opensm/osm_sa_mcmember_record.c | 170 +++++++++++++----- 1 file changed, 126 insertions(+), 44 deletions(-) diff --git a/trunk/ulp/opensm/user/opensm/osm_sa_mcmember_record.c b/trunk/ulp/opensm/user/opensm/osm_sa_mcmember_record.c index c079e06b..7456999f 100644 --- a/trunk/ulp/opensm/user/opensm/osm_sa_mcmember_record.c +++ b/trunk/ulp/opensm/user/opensm/osm_sa_mcmember_record.c @@ -88,6 +88,7 @@ typedef struct osm_sa_mcmr_search_ctxt { cl_qlist_t *p_list; /* hold results */ ib_net64_t comp_mask; const osm_physp_t* p_req_physp; + boolean_t trusted_req; } osm_sa_mcmr_search_ctxt_t; /********************************************************************** @@ -1213,6 +1214,24 @@ __mgrp_request_is_realizable( return TRUE; } +/********************************************************************** + Call this function to find or create a new mgrp. +**********************************************************************/ +ib_api_status_t +osm_mcmr_rcv_find_or_create_new_mgrp( + IN osm_mcmr_recv_t* const p_rcv, + IN ib_net64_t comp_mask, + IN ib_member_rec_t* const p_recvd_mcmember_rec, + OUT osm_mgrp_t **pp_mgrp) +{ + ib_api_status_t status; + status = __get_mgrp_by_mgid(p_rcv, p_recvd_mcmember_rec, pp_mgrp); + if (status == IB_SUCCESS) + return status; + return osm_mcmr_rcv_create_new_mgrp(p_rcv, comp_mask, + p_recvd_mcmember_rec, NULL, pp_mgrp); +} + /********************************************************************** Call this function to create a new mgrp. **********************************************************************/ @@ -1897,6 +1916,9 @@ __osm_sa_mcm_by_comp_mask_cb( /* will be used for group or port info */ uint8_t scope_state; uint8_t scope_state_mask = 0; + cl_map_item_t *p_item; + ib_gid_t port_gid; + boolean_t proxy_join; OSM_LOG_ENTER( p_rcv->p_log, __osm_sa_mcm_by_comp_mask_cb ); @@ -1917,51 +1939,33 @@ __osm_sa_mcm_by_comp_mask_cb( /* first try to eliminate the group by MGID, MLID, or P_Key */ if ((IB_MCR_COMPMASK_MGID & comp_mask) && - cl_memcmp(&p_rcvd_rec->mgid, &p_mgrp->mcmember_rec.mgid, sizeof(ib_gid_t))) { + cl_memcmp(&p_rcvd_rec->mgid, &p_mgrp->mcmember_rec.mgid, sizeof(ib_gid_t))) goto Exit; - } if ((IB_MCR_COMPMASK_MLID & comp_mask) && - cl_memcmp(&p_rcvd_rec->mlid, &p_mgrp->mcmember_rec.mlid, sizeof(uint16_t))) { - goto Exit; - } - - /* if the requester physical port doesn't have the pkey that is defined for the - group - exit. */ - if (! osm_physp_has_pkey( p_rcv->p_log, p_mgrp->mcmember_rec.pkey, p_req_physp )) + cl_memcmp(&p_rcvd_rec->mlid, &p_mgrp->mcmember_rec.mlid, sizeof(uint16_t))) goto Exit; - /* so did we get the PortGUID mask */ - if (IB_MCR_COMPMASK_PORT_GID & comp_mask) - { - /* try to find this port */ - if (osm_mgrp_is_port_present(p_mgrp, portguid, &p_mcm_port)) - { - scope_state = p_mcm_port->scope_state; - } - else - { - /* port not in group */ + /* if the requester physical port doesn't have the pkey that is defined for + the group - exit. */ + if (! osm_physp_has_pkey( p_rcv->p_log, p_mgrp->mcmember_rec.pkey, + p_req_physp )) goto Exit; - } - } - else - { - /* point to the group information */ - scope_state = p_mgrp->mcmember_rec.scope_state; - } /* now do the rest of the match */ if ((IB_MCR_COMPMASK_QKEY & comp_mask) && - (p_rcvd_rec->qkey != p_mgrp->mcmember_rec.qkey)) goto Exit; + (p_rcvd_rec->qkey != p_mgrp->mcmember_rec.qkey)) + goto Exit; if ((IB_MCR_COMPMASK_PKEY & comp_mask) && - (p_rcvd_rec->pkey != p_mgrp->mcmember_rec.pkey)) goto Exit; + (p_rcvd_rec->pkey != p_mgrp->mcmember_rec.pkey)) + goto Exit; if ((IB_MCR_COMPMASK_TCLASS & comp_mask) && - (p_rcvd_rec->tclass != p_mgrp->mcmember_rec.tclass)) goto Exit; + (p_rcvd_rec->tclass != p_mgrp->mcmember_rec.tclass)) + goto Exit; - /* check SL , Flow and Hop limit */ + /* check SL, Flow, and Hop limit */ { uint8_t mgrp_sl, query_sl; uint32_t mgrp_flow, query_flow; @@ -1974,38 +1978,111 @@ __osm_sa_mcm_by_comp_mask_cb( &mgrp_sl, &mgrp_flow, &mgrp_hop); if (IB_MCR_COMPMASK_SL & comp_mask ) - if (query_sl != mgrp_sl) goto Exit; + if (query_sl != mgrp_sl) + goto Exit; if (IB_MCR_COMPMASK_FLOW & comp_mask) - if (query_flow != mgrp_flow) goto Exit; + if (query_flow != mgrp_flow) + goto Exit; if (IB_MCR_COMPMASK_HOP & comp_mask) - if (query_hop != mgrp_hop) goto Exit; + if (query_hop != mgrp_hop) + goto Exit; } + if ((IB_MCR_COMPMASK_PROXY & comp_mask) && + (p_rcvd_rec->proxy_join != p_mgrp->mcmember_rec.proxy_join)) + goto Exit; + if (IB_MCR_COMPMASK_SCOPE & comp_mask) scope_state_mask = 0xF0; if (IB_MCR_COMPMASK_JOIN_STATE & comp_mask) scope_state_mask = scope_state_mask | 0x0F; - if ((scope_state_mask & p_rcvd_rec->scope_state) != - (scope_state_mask & scope_state)) goto Exit; - - if ((IB_MCR_COMPMASK_PROXY & comp_mask) && - (p_rcvd_rec->proxy_join != p_mgrp->mcmember_rec.proxy_join)) goto Exit; - /* need to validate mtu, rate, and pkt_lifetime fields. */ if (__validate_more_comp_fields( p_rcv->p_log, p_mgrp, p_rcvd_rec, - comp_mask ) == FALSE) goto Exit; + comp_mask ) == FALSE) + goto Exit; + + /* Port specific fields */ + /* so did we get the PortGUID mask */ + if (IB_MCR_COMPMASK_PORT_GID & comp_mask) + { + /* try to find this port */ + if (osm_mgrp_is_port_present(p_mgrp, portguid, &p_mcm_port)) + { + scope_state = p_mcm_port->scope_state; + cl_memcpy(&port_gid, &(p_mcm_port->port_gid), sizeof(ib_gid_t)); + proxy_join = p_mcm_port->proxy_join; + } + else + { + /* port not in group */ + goto Exit; + } + } + else + { + /* point to the group information */ + scope_state = p_mgrp->mcmember_rec.scope_state; + } + + /* Many MC records returned */ + if ( (p_ctxt->trusted_req == TRUE) && !(IB_MCR_COMPMASK_PORT_GID & comp_mask) ) + { + osm_log(p_rcv->p_log, OSM_LOG_DEBUG, + "__osm_sa_mcm_by_comp_mask_cb: " + "trusted req is TRUE and no specific port defined\n"); + + /* return all the ports that match in this MC group */ + p_item = cl_qmap_head(&(p_mgrp->mcm_port_tbl)); + while( p_item != cl_qmap_end(&(p_mgrp->mcm_port_tbl)) ) + { + p_mcm_port=(osm_mcm_port_t *)p_item; + + if ((scope_state_mask & p_rcvd_rec->scope_state) == + (scope_state_mask & p_mcm_port->scope_state)) + { + /* add to the list */ + match_rec = p_mgrp->mcmember_rec; + match_rec.scope_state = p_mcm_port->scope_state; + cl_memcpy( &(match_rec.port_gid), &(p_mcm_port->port_gid), + sizeof(ib_gid_t)); + osm_log(p_rcv->p_log, OSM_LOG_DEBUG, + "__osm_sa_mcm_by_comp_mask_cb: " + "record of port_gid: 0x%016" PRIx64 "0x%016" PRIx64 + " in multicast_lid: 0x%X is returned\n", + cl_ntoh64(match_rec.port_gid.unicast.prefix), + cl_ntoh64(match_rec.port_gid.unicast.interface_id), + cl_ntoh16(p_mgrp->mlid) + ); + + match_rec.proxy_join = (uint8_t)(p_mcm_port->proxy_join); + + __osm_mcmr_rcv_new_mcmr(p_rcv, &match_rec, p_ctxt->p_list); + } + p_item = cl_qmap_next(p_item); + } + } + /* One MC record returned */ + else + { + if ((scope_state_mask & p_rcvd_rec->scope_state) != + (scope_state_mask & scope_state)) + goto Exit; /* add to the list */ match_rec = p_mgrp->mcmember_rec; match_rec.scope_state = scope_state; + cl_memcpy(&(match_rec.port_gid), &port_gid, sizeof(ib_gid_t)); + match_rec.proxy_join = (uint8_t)proxy_join; __osm_mcmr_rcv_new_mcmr(p_rcv, &match_rec, p_ctxt->p_list); + } + Exit: OSM_LOG_EXIT( p_rcv->p_log ); } @@ -2032,7 +2109,7 @@ osm_mcmr_query_mgrp(IN osm_mcmr_recv_t* const p_rcv, ib_api_status_t status; ib_net64_t comp_mask; osm_physp_t* p_req_physp; - boolean_t trusted_req = TRUE; + boolean_t trusted_req; CL_ASSERT( p_rcv ); @@ -2046,6 +2123,12 @@ osm_mcmr_query_mgrp(IN osm_mcmr_recv_t* const p_rcv, CL_ASSERT( p_rcvd_mad->attr_id == IB_MAD_ATTR_MCMEMBER_RECORD ); + /* + if sm_key is not zero and does not match we never get here + see main SA receiver + */ + trusted_req = (p_rcvd_mad->sm_key != 0); + /* update the requester physical port. */ p_req_physp = osm_get_physp_by_mad_addr(p_rcv->p_log, p_rcv->p_subn, @@ -2065,6 +2148,7 @@ osm_mcmr_query_mgrp(IN osm_mcmr_recv_t* const p_rcv, context.comp_mask = p_rcvd_mad->comp_mask; context.p_rcv = p_rcv; context.p_req_physp = p_req_physp; + context.trusted_req = trusted_req; CL_PLOCK_ACQUIRE( p_rcv->p_lock ); @@ -2191,8 +2275,6 @@ osm_mcmr_query_mgrp(IN osm_mcmr_recv_t* const p_rcv, the mad is valid. Meaning - is either zero or equal to the local sm_key. */ - if (p_rcvd_mad->sm_key == 0) - trusted_req = FALSE; for ( i = 0; i < pre_trim_num_rec; i++ ) { -- 2.41.0