1d6b92ffaSHans Petter Selasky /*
2d6b92ffaSHans Petter Selasky  * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
3d6b92ffaSHans Petter Selasky  * Copyright (c) 2002-2011 Mellanox Technologies LTD. All rights reserved.
4d6b92ffaSHans Petter Selasky  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
5d6b92ffaSHans Petter Selasky  * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
6d6b92ffaSHans Petter Selasky  *
7d6b92ffaSHans Petter Selasky  * This software is available to you under a choice of one of two
8d6b92ffaSHans Petter Selasky  * licenses.  You may choose to be licensed under the terms of the GNU
9d6b92ffaSHans Petter Selasky  * General Public License (GPL) Version 2, available from the file
10d6b92ffaSHans Petter Selasky  * COPYING in the main directory of this source tree, or the
11d6b92ffaSHans Petter Selasky  * OpenIB.org BSD license below:
12d6b92ffaSHans Petter Selasky  *
13d6b92ffaSHans Petter Selasky  *     Redistribution and use in source and binary forms, with or
14d6b92ffaSHans Petter Selasky  *     without modification, are permitted provided that the following
15d6b92ffaSHans Petter Selasky  *     conditions are met:
16d6b92ffaSHans Petter Selasky  *
17d6b92ffaSHans Petter Selasky  *      - Redistributions of source code must retain the above
18d6b92ffaSHans Petter Selasky  *        copyright notice, this list of conditions and the following
19d6b92ffaSHans Petter Selasky  *        disclaimer.
20d6b92ffaSHans Petter Selasky  *
21d6b92ffaSHans Petter Selasky  *      - Redistributions in binary form must reproduce the above
22d6b92ffaSHans Petter Selasky  *        copyright notice, this list of conditions and the following
23d6b92ffaSHans Petter Selasky  *        disclaimer in the documentation and/or other materials
24d6b92ffaSHans Petter Selasky  *        provided with the distribution.
25d6b92ffaSHans Petter Selasky  *
26d6b92ffaSHans Petter Selasky  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27d6b92ffaSHans Petter Selasky  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28d6b92ffaSHans Petter Selasky  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29d6b92ffaSHans Petter Selasky  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
30d6b92ffaSHans Petter Selasky  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
31d6b92ffaSHans Petter Selasky  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
32d6b92ffaSHans Petter Selasky  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33d6b92ffaSHans Petter Selasky  * SOFTWARE.
34d6b92ffaSHans Petter Selasky  *
35d6b92ffaSHans Petter Selasky  */
36d6b92ffaSHans Petter Selasky 
37d6b92ffaSHans Petter Selasky /*
38d6b92ffaSHans Petter Selasky  * Abstract:
39d6b92ffaSHans Petter Selasky  *    Implementation of osm_sr_rcv_t.
40d6b92ffaSHans Petter Selasky  * This object represents the ServiceRecord Receiver object.
41d6b92ffaSHans Petter Selasky  * This object is part of the opensm family of objects.
42d6b92ffaSHans Petter Selasky  */
43d6b92ffaSHans Petter Selasky 
44d6b92ffaSHans Petter Selasky #if HAVE_CONFIG_H
45d6b92ffaSHans Petter Selasky #  include <config.h>
46d6b92ffaSHans Petter Selasky #endif				/* HAVE_CONFIG_H */
47d6b92ffaSHans Petter Selasky 
48d6b92ffaSHans Petter Selasky #include <string.h>
49d6b92ffaSHans Petter Selasky #include <iba/ib_types.h>
50d6b92ffaSHans Petter Selasky #include <complib/cl_qmap.h>
51d6b92ffaSHans Petter Selasky #include <complib/cl_passivelock.h>
52d6b92ffaSHans Petter Selasky #include <complib/cl_debug.h>
53d6b92ffaSHans Petter Selasky #include <complib/cl_qlist.h>
54d6b92ffaSHans Petter Selasky #include <opensm/osm_file_ids.h>
55d6b92ffaSHans Petter Selasky #define FILE_ID OSM_FILE_SA_SERVICE_RECORD_C
56d6b92ffaSHans Petter Selasky #include <vendor/osm_vendor_api.h>
57d6b92ffaSHans Petter Selasky #include <opensm/osm_port.h>
58d6b92ffaSHans Petter Selasky #include <opensm/osm_node.h>
59d6b92ffaSHans Petter Selasky #include <opensm/osm_switch.h>
60d6b92ffaSHans Petter Selasky #include <opensm/osm_helper.h>
61d6b92ffaSHans Petter Selasky #include <opensm/osm_sa.h>
62d6b92ffaSHans Petter Selasky #include <opensm/osm_service.h>
63d6b92ffaSHans Petter Selasky #include <opensm/osm_pkey.h>
64d6b92ffaSHans Petter Selasky 
65d6b92ffaSHans Petter Selasky #define SA_SR_RESP_SIZE SA_ITEM_RESP_SIZE(service_rec)
66d6b92ffaSHans Petter Selasky 
67d6b92ffaSHans Petter Selasky typedef struct osm_sr_match_item {
68d6b92ffaSHans Petter Selasky 	cl_qlist_t sr_list;
69d6b92ffaSHans Petter Selasky 	ib_service_record_t *p_service_rec;
70d6b92ffaSHans Petter Selasky 	ib_net64_t comp_mask;
71d6b92ffaSHans Petter Selasky 	osm_sa_t *sa;
72d6b92ffaSHans Petter Selasky } osm_sr_match_item_t;
73d6b92ffaSHans Petter Selasky 
74d6b92ffaSHans Petter Selasky typedef struct osm_sr_search_ctxt {
75d6b92ffaSHans Petter Selasky 	osm_sr_match_item_t *p_sr_item;
76d6b92ffaSHans Petter Selasky 	const osm_physp_t *p_req_physp;
77d6b92ffaSHans Petter Selasky } osm_sr_search_ctxt_t;
78d6b92ffaSHans Petter Selasky 
79d6b92ffaSHans Petter Selasky static boolean_t
match_service_pkey_with_ports_pkey(IN osm_sa_t * sa,IN const osm_madw_t * p_madw,ib_service_record_t * p_service_rec,ib_net64_t const comp_mask)80d6b92ffaSHans Petter Selasky match_service_pkey_with_ports_pkey(IN osm_sa_t * sa,
81d6b92ffaSHans Petter Selasky 				   IN const osm_madw_t * p_madw,
82d6b92ffaSHans Petter Selasky 				   ib_service_record_t * p_service_rec,
83d6b92ffaSHans Petter Selasky 				   ib_net64_t const comp_mask)
84d6b92ffaSHans Petter Selasky {
85d6b92ffaSHans Petter Selasky 	boolean_t valid = TRUE;
86d6b92ffaSHans Petter Selasky 	osm_physp_t *p_req_physp;
87d6b92ffaSHans Petter Selasky 	ib_net64_t service_guid;
88d6b92ffaSHans Petter Selasky 	osm_port_t *service_port;
89d6b92ffaSHans Petter Selasky 
90d6b92ffaSHans Petter Selasky 	/* update the requester physical port */
91d6b92ffaSHans Petter Selasky 	p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn,
92d6b92ffaSHans Petter Selasky 						osm_madw_get_mad_addr_ptr
93d6b92ffaSHans Petter Selasky 						(p_madw));
94d6b92ffaSHans Petter Selasky 	if (p_req_physp == NULL) {
95d6b92ffaSHans Petter Selasky 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2404: "
96d6b92ffaSHans Petter Selasky 			"Cannot find requester physical port\n");
97d6b92ffaSHans Petter Selasky 		valid = FALSE;
98d6b92ffaSHans Petter Selasky 		goto Exit;
99d6b92ffaSHans Petter Selasky 	}
100d6b92ffaSHans Petter Selasky 	OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
101d6b92ffaSHans Petter Selasky 		"Requester port GUID 0x%" PRIx64 "\n",
102d6b92ffaSHans Petter Selasky 		cl_ntoh64(osm_physp_get_port_guid(p_req_physp)));
103d6b92ffaSHans Petter Selasky 
104d6b92ffaSHans Petter Selasky 	if ((comp_mask & IB_SR_COMPMASK_SPKEY) == IB_SR_COMPMASK_SPKEY) {
105d6b92ffaSHans Petter Selasky 		/* We have a ServiceP_Key - check matching on requester port,
106d6b92ffaSHans Petter Selasky 		   and ServiceGid port (if such exists) */
107d6b92ffaSHans Petter Selasky 		/* Make sure it matches the p_req_physp */
108d6b92ffaSHans Petter Selasky 		if (!osm_physp_has_pkey
109d6b92ffaSHans Petter Selasky 		    (sa->p_log, p_service_rec->service_pkey, p_req_physp)) {
110d6b92ffaSHans Petter Selasky 			valid = FALSE;
111d6b92ffaSHans Petter Selasky 			goto Exit;
112d6b92ffaSHans Petter Selasky 		}
113d6b92ffaSHans Petter Selasky 
114d6b92ffaSHans Petter Selasky 		/* If unicast, make sure it matches the port of the ServiceGid */
115d6b92ffaSHans Petter Selasky 		if (comp_mask & IB_SR_COMPMASK_SGID &&
116d6b92ffaSHans Petter Selasky 		    !ib_gid_is_multicast(&p_service_rec->service_gid)) {
117d6b92ffaSHans Petter Selasky 			service_guid =
118d6b92ffaSHans Petter Selasky 			    p_service_rec->service_gid.unicast.interface_id;
119d6b92ffaSHans Petter Selasky 			service_port =
120d6b92ffaSHans Petter Selasky 			    osm_get_port_by_alias_guid(sa->p_subn, service_guid);
121d6b92ffaSHans Petter Selasky 			if (!service_port) {
122d6b92ffaSHans Petter Selasky 				OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2405: "
123d6b92ffaSHans Petter Selasky 					"No port object for port 0x%016" PRIx64
124d6b92ffaSHans Petter Selasky 					"\n", cl_ntoh64(service_guid));
125d6b92ffaSHans Petter Selasky 				valid = FALSE;
126d6b92ffaSHans Petter Selasky 				goto Exit;
127d6b92ffaSHans Petter Selasky 			}
128d6b92ffaSHans Petter Selasky 			/* check on the table of the default physical port of the service port */
129d6b92ffaSHans Petter Selasky 			if (!osm_physp_has_pkey(sa->p_log,
130d6b92ffaSHans Petter Selasky 						p_service_rec->service_pkey,
131d6b92ffaSHans Petter Selasky 						service_port->p_physp)) {
132d6b92ffaSHans Petter Selasky 				valid = FALSE;
133d6b92ffaSHans Petter Selasky 				goto Exit;
134d6b92ffaSHans Petter Selasky 			}
135d6b92ffaSHans Petter Selasky 		}
136d6b92ffaSHans Petter Selasky 	}
137d6b92ffaSHans Petter Selasky 
138d6b92ffaSHans Petter Selasky Exit:
139d6b92ffaSHans Petter Selasky 	return valid;
140d6b92ffaSHans Petter Selasky }
141d6b92ffaSHans Petter Selasky 
142d6b92ffaSHans Petter Selasky static boolean_t
match_name_to_key_association(IN osm_sa_t * sa,ib_service_record_t * p_service_rec,ib_net64_t comp_mask)143d6b92ffaSHans Petter Selasky match_name_to_key_association(IN osm_sa_t * sa,
144d6b92ffaSHans Petter Selasky 			      ib_service_record_t * p_service_rec,
145d6b92ffaSHans Petter Selasky 			      ib_net64_t comp_mask)
146d6b92ffaSHans Petter Selasky {
147d6b92ffaSHans Petter Selasky 	UNUSED_PARAM(p_service_rec);
148d6b92ffaSHans Petter Selasky 	UNUSED_PARAM(sa);
149d6b92ffaSHans Petter Selasky 
150d6b92ffaSHans Petter Selasky 	if ((comp_mask & (IB_SR_COMPMASK_SKEY | IB_SR_COMPMASK_SNAME)) ==
151d6b92ffaSHans Petter Selasky 	    (IB_SR_COMPMASK_SKEY | IB_SR_COMPMASK_SNAME)) {
152d6b92ffaSHans Petter Selasky 		/* For now, we are not maintaining the ServiceAssociation record
153d6b92ffaSHans Petter Selasky 		 * so just return TRUE
154d6b92ffaSHans Petter Selasky 		 */
155d6b92ffaSHans Petter Selasky 		return TRUE;
156d6b92ffaSHans Petter Selasky 	}
157d6b92ffaSHans Petter Selasky 
158d6b92ffaSHans Petter Selasky 	return TRUE;
159d6b92ffaSHans Petter Selasky }
160d6b92ffaSHans Petter Selasky 
validate_sr(IN osm_sa_t * sa,IN const osm_madw_t * p_madw)161d6b92ffaSHans Petter Selasky static boolean_t validate_sr(IN osm_sa_t * sa, IN const osm_madw_t * p_madw)
162d6b92ffaSHans Petter Selasky {
163d6b92ffaSHans Petter Selasky 	boolean_t valid = TRUE;
164d6b92ffaSHans Petter Selasky 	ib_sa_mad_t *p_sa_mad;
165d6b92ffaSHans Petter Selasky 	ib_service_record_t *p_recvd_service_rec;
166d6b92ffaSHans Petter Selasky 
167d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(sa->p_log);
168d6b92ffaSHans Petter Selasky 
169d6b92ffaSHans Petter Selasky 	p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
170d6b92ffaSHans Petter Selasky 	p_recvd_service_rec =
171d6b92ffaSHans Petter Selasky 	    (ib_service_record_t *) ib_sa_mad_get_payload_ptr(p_sa_mad);
172d6b92ffaSHans Petter Selasky 
173d6b92ffaSHans Petter Selasky 	valid = match_service_pkey_with_ports_pkey(sa, p_madw,
174d6b92ffaSHans Petter Selasky 						   p_recvd_service_rec,
175d6b92ffaSHans Petter Selasky 						   p_sa_mad->comp_mask);
176d6b92ffaSHans Petter Selasky 	if (!valid) {
177d6b92ffaSHans Petter Selasky 		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
178d6b92ffaSHans Petter Selasky 			"No Match for Service Pkey\n");
179d6b92ffaSHans Petter Selasky 		valid = FALSE;
180d6b92ffaSHans Petter Selasky 		goto Exit;
181d6b92ffaSHans Petter Selasky 	}
182d6b92ffaSHans Petter Selasky 
183d6b92ffaSHans Petter Selasky 	valid = match_name_to_key_association(sa, p_recvd_service_rec,
184d6b92ffaSHans Petter Selasky 					      p_sa_mad->comp_mask);
185d6b92ffaSHans Petter Selasky 	if (!valid) {
186d6b92ffaSHans Petter Selasky 		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
187d6b92ffaSHans Petter Selasky 			"Service Record Name to key matching failed\n");
188d6b92ffaSHans Petter Selasky 		valid = FALSE;
189d6b92ffaSHans Petter Selasky 		goto Exit;
190d6b92ffaSHans Petter Selasky 	}
191d6b92ffaSHans Petter Selasky 
192d6b92ffaSHans Petter Selasky Exit:
193d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(sa->p_log);
194d6b92ffaSHans Petter Selasky 	return valid;
195d6b92ffaSHans Petter Selasky }
196d6b92ffaSHans Petter Selasky 
sr_rcv_respond(IN osm_sa_t * sa,IN osm_madw_t * p_madw,IN cl_qlist_t * p_list)197d6b92ffaSHans Petter Selasky static void sr_rcv_respond(IN osm_sa_t * sa, IN osm_madw_t * p_madw,
198d6b92ffaSHans Petter Selasky 			   IN cl_qlist_t * p_list)
199d6b92ffaSHans Petter Selasky {
200d6b92ffaSHans Petter Selasky 	/* p923 - The ServiceKey shall be set to 0, except in the case of
201d6b92ffaSHans Petter Selasky 	   a trusted request.
202d6b92ffaSHans Petter Selasky 	   Note: In the mad controller we check that the SM_Key received on
203d6b92ffaSHans Petter Selasky 	   the mad is valid. Meaning - is either zero or equal to the local
204d6b92ffaSHans Petter Selasky 	   sm_key.
205d6b92ffaSHans Petter Selasky 	 */
206d6b92ffaSHans Petter Selasky 	if (!osm_madw_get_sa_mad_ptr(p_madw)->sm_key) {
207d6b92ffaSHans Petter Selasky 		osm_sa_item_t *item;
208d6b92ffaSHans Petter Selasky 		for (item = (osm_sa_item_t *) cl_qlist_head(p_list);
209d6b92ffaSHans Petter Selasky 		     item != (osm_sa_item_t *) cl_qlist_end(p_list);
210d6b92ffaSHans Petter Selasky 		     item = (osm_sa_item_t *) cl_qlist_next(&item->list_item))
211d6b92ffaSHans Petter Selasky 			memset(item->resp.service_rec.service_key, 0,
212d6b92ffaSHans Petter Selasky 			       sizeof(item->resp.service_rec.service_key));
213d6b92ffaSHans Petter Selasky 	}
214d6b92ffaSHans Petter Selasky 
215d6b92ffaSHans Petter Selasky 	osm_sa_respond(sa, p_madw, sizeof(ib_service_record_t), p_list);
216d6b92ffaSHans Petter Selasky }
217d6b92ffaSHans Petter Selasky 
get_matching_sr(IN cl_list_item_t * p_list_item,IN void * context)218d6b92ffaSHans Petter Selasky static void get_matching_sr(IN cl_list_item_t * p_list_item, IN void *context)
219d6b92ffaSHans Petter Selasky {
220d6b92ffaSHans Petter Selasky 	osm_sr_search_ctxt_t *p_ctxt = context;
221d6b92ffaSHans Petter Selasky 	osm_svcr_t *p_svcr = (osm_svcr_t *) p_list_item;
222d6b92ffaSHans Petter Selasky 	osm_sa_item_t *p_sr_pool_item;
223d6b92ffaSHans Petter Selasky 	osm_sr_match_item_t *p_sr_item = p_ctxt->p_sr_item;
224d6b92ffaSHans Petter Selasky 	ib_net64_t comp_mask = p_sr_item->comp_mask;
225d6b92ffaSHans Petter Selasky 	const osm_physp_t *p_req_physp = p_ctxt->p_req_physp;
226d6b92ffaSHans Petter Selasky 
227d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SID) {
228d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_id !=
229d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_id)
230d6b92ffaSHans Petter Selasky 			return;
231d6b92ffaSHans Petter Selasky 	}
232d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SGID) {
233d6b92ffaSHans Petter Selasky 		if (memcmp(&p_sr_item->p_service_rec->service_gid,
234d6b92ffaSHans Petter Selasky 			   &p_svcr->service_record.service_gid,
235d6b92ffaSHans Petter Selasky 			   sizeof(p_svcr->service_record.service_gid)) != 0)
236d6b92ffaSHans Petter Selasky 			return;
237d6b92ffaSHans Petter Selasky 	}
238d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SPKEY) {
239d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_pkey !=
240d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_pkey)
241d6b92ffaSHans Petter Selasky 			return;
242d6b92ffaSHans Petter Selasky 	}
243d6b92ffaSHans Petter Selasky 
244d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SKEY) {
245d6b92ffaSHans Petter Selasky 		if (memcmp(p_sr_item->p_service_rec->service_key,
246d6b92ffaSHans Petter Selasky 			   p_svcr->service_record.service_key,
247d6b92ffaSHans Petter Selasky 			   16 * sizeof(uint8_t)))
248d6b92ffaSHans Petter Selasky 			return;
249d6b92ffaSHans Petter Selasky 	}
250d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SNAME) {
251d6b92ffaSHans Petter Selasky 		if (memcmp(p_sr_item->p_service_rec->service_name,
252d6b92ffaSHans Petter Selasky 			   p_svcr->service_record.service_name,
253d6b92ffaSHans Petter Selasky 			   sizeof(p_svcr->service_record.service_name)) != 0)
254d6b92ffaSHans Petter Selasky 			return;
255d6b92ffaSHans Petter Selasky 	}
256d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA8_0) {
257d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data8[0] !=
258d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data8[0])
259d6b92ffaSHans Petter Selasky 			return;
260d6b92ffaSHans Petter Selasky 	}
261d6b92ffaSHans Petter Selasky 
262d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA8_1) {
263d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data8[1] !=
264d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data8[1])
265d6b92ffaSHans Petter Selasky 			return;
266d6b92ffaSHans Petter Selasky 	}
267d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA8_2) {
268d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data8[2] !=
269d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data8[2])
270d6b92ffaSHans Petter Selasky 			return;
271d6b92ffaSHans Petter Selasky 	}
272d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA8_3) {
273d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data8[3] !=
274d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data8[3])
275d6b92ffaSHans Petter Selasky 			return;
276d6b92ffaSHans Petter Selasky 	}
277d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA8_4) {
278d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data8[4] !=
279d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data8[4])
280d6b92ffaSHans Petter Selasky 			return;
281d6b92ffaSHans Petter Selasky 	}
282d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA8_5) {
283d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data8[5] !=
284d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data8[5])
285d6b92ffaSHans Petter Selasky 			return;
286d6b92ffaSHans Petter Selasky 	}
287d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA8_6) {
288d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data8[6] !=
289d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data8[6])
290d6b92ffaSHans Petter Selasky 			return;
291d6b92ffaSHans Petter Selasky 	}
292d6b92ffaSHans Petter Selasky 
293d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA8_7) {
294d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data8[7] !=
295d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data8[7])
296d6b92ffaSHans Petter Selasky 			return;
297d6b92ffaSHans Petter Selasky 	}
298d6b92ffaSHans Petter Selasky 
299d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA8_8) {
300d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data8[8] !=
301d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data8[8])
302d6b92ffaSHans Petter Selasky 			return;
303d6b92ffaSHans Petter Selasky 	}
304d6b92ffaSHans Petter Selasky 
305d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA8_9) {
306d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data8[9] !=
307d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data8[9])
308d6b92ffaSHans Petter Selasky 			return;
309d6b92ffaSHans Petter Selasky 	}
310d6b92ffaSHans Petter Selasky 
311d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA8_10) {
312d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data8[10] !=
313d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data8[10])
314d6b92ffaSHans Petter Selasky 			return;
315d6b92ffaSHans Petter Selasky 	}
316d6b92ffaSHans Petter Selasky 
317d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA8_11) {
318d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data8[11] !=
319d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data8[11])
320d6b92ffaSHans Petter Selasky 			return;
321d6b92ffaSHans Petter Selasky 	}
322d6b92ffaSHans Petter Selasky 
323d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA8_12) {
324d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data8[12] !=
325d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data8[12])
326d6b92ffaSHans Petter Selasky 			return;
327d6b92ffaSHans Petter Selasky 	}
328d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA8_13) {
329d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data8[13] !=
330d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data8[13])
331d6b92ffaSHans Petter Selasky 			return;
332d6b92ffaSHans Petter Selasky 	}
333d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA8_14) {
334d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data8[14] !=
335d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data8[14])
336d6b92ffaSHans Petter Selasky 			return;
337d6b92ffaSHans Petter Selasky 	}
338d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA8_15) {
339d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data8[15] !=
340d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data8[15])
341d6b92ffaSHans Petter Selasky 			return;
342d6b92ffaSHans Petter Selasky 	}
343d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA16_0) {
344d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data16[0] !=
345d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data16[0])
346d6b92ffaSHans Petter Selasky 			return;
347d6b92ffaSHans Petter Selasky 	}
348d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA16_1) {
349d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data16[1] !=
350d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data16[1])
351d6b92ffaSHans Petter Selasky 			return;
352d6b92ffaSHans Petter Selasky 	}
353d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA16_2) {
354d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data16[2] !=
355d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data16[2])
356d6b92ffaSHans Petter Selasky 			return;
357d6b92ffaSHans Petter Selasky 	}
358d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA16_3) {
359d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data16[3] !=
360d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data16[3])
361d6b92ffaSHans Petter Selasky 			return;
362d6b92ffaSHans Petter Selasky 	}
363d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA16_4) {
364d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data16[4] !=
365d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data16[4])
366d6b92ffaSHans Petter Selasky 			return;
367d6b92ffaSHans Petter Selasky 	}
368d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA16_5) {
369d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data16[5] !=
370d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data16[5])
371d6b92ffaSHans Petter Selasky 			return;
372d6b92ffaSHans Petter Selasky 	}
373d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA16_6) {
374d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data16[6] !=
375d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data16[6])
376d6b92ffaSHans Petter Selasky 			return;
377d6b92ffaSHans Petter Selasky 	}
378d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA16_7) {
379d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data16[7] !=
380d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data16[7])
381d6b92ffaSHans Petter Selasky 			return;
382d6b92ffaSHans Petter Selasky 	}
383d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA32_0) {
384d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data32[0] !=
385d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data32[0])
386d6b92ffaSHans Petter Selasky 			return;
387d6b92ffaSHans Petter Selasky 	}
388d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA32_1) {
389d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data32[1] !=
390d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data32[1])
391d6b92ffaSHans Petter Selasky 			return;
392d6b92ffaSHans Petter Selasky 	}
393d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA32_2) {
394d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data32[2] !=
395d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data32[2])
396d6b92ffaSHans Petter Selasky 			return;
397d6b92ffaSHans Petter Selasky 	}
398d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA32_3) {
399d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data32[3] !=
400d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data32[3])
401d6b92ffaSHans Petter Selasky 			return;
402d6b92ffaSHans Petter Selasky 	}
403d6b92ffaSHans Petter Selasky 
404d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA64_0) {
405d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data64[0] !=
406d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data64[0])
407d6b92ffaSHans Petter Selasky 			return;
408d6b92ffaSHans Petter Selasky 	}
409d6b92ffaSHans Petter Selasky 	if (comp_mask & IB_SR_COMPMASK_SDATA64_1) {
410d6b92ffaSHans Petter Selasky 		if (p_sr_item->p_service_rec->service_data64[1] !=
411d6b92ffaSHans Petter Selasky 		    p_svcr->service_record.service_data64[1])
412d6b92ffaSHans Petter Selasky 			return;
413d6b92ffaSHans Petter Selasky 	}
414d6b92ffaSHans Petter Selasky 
415d6b92ffaSHans Petter Selasky 	/* Check that the requester port has the pkey which is the service_pkey.
416d6b92ffaSHans Petter Selasky 	   If not - then it cannot receive this ServiceRecord. */
417d6b92ffaSHans Petter Selasky 	/* The check is relevant only if the service_pkey is valid */
418d6b92ffaSHans Petter Selasky 	if (!ib_pkey_is_invalid(p_svcr->service_record.service_pkey)) {
419d6b92ffaSHans Petter Selasky 		if (!osm_physp_has_pkey(p_sr_item->sa->p_log,
420d6b92ffaSHans Petter Selasky 					p_svcr->service_record.service_pkey,
421d6b92ffaSHans Petter Selasky 					p_req_physp)) {
422d6b92ffaSHans Petter Selasky 			OSM_LOG(p_sr_item->sa->p_log, OSM_LOG_VERBOSE,
423d6b92ffaSHans Petter Selasky 				"requester port doesn't have the service_pkey: 0x%X\n",
424d6b92ffaSHans Petter Selasky 				cl_ntoh16(p_svcr->service_record.service_pkey));
425d6b92ffaSHans Petter Selasky 			return;
426d6b92ffaSHans Petter Selasky 		}
427d6b92ffaSHans Petter Selasky 	}
428d6b92ffaSHans Petter Selasky 
429d6b92ffaSHans Petter Selasky 	p_sr_pool_item = malloc(SA_SR_RESP_SIZE);
430d6b92ffaSHans Petter Selasky 	if (p_sr_pool_item == NULL) {
431d6b92ffaSHans Petter Selasky 		OSM_LOG(p_sr_item->sa->p_log, OSM_LOG_ERROR, "ERR 2408: "
432d6b92ffaSHans Petter Selasky 			"Unable to acquire Service Record from pool\n");
433d6b92ffaSHans Petter Selasky 		goto Exit;
434d6b92ffaSHans Petter Selasky 	}
435d6b92ffaSHans Petter Selasky 
436d6b92ffaSHans Petter Selasky 	p_sr_pool_item->resp.service_rec = p_svcr->service_record;
437d6b92ffaSHans Petter Selasky 
438d6b92ffaSHans Petter Selasky 	cl_qlist_insert_tail(&p_sr_item->sr_list, &p_sr_pool_item->list_item);
439d6b92ffaSHans Petter Selasky 
440d6b92ffaSHans Petter Selasky Exit:
441d6b92ffaSHans Petter Selasky 	return;
442d6b92ffaSHans Petter Selasky }
443d6b92ffaSHans Petter Selasky 
sr_rcv_process_get_method(osm_sa_t * sa,IN osm_madw_t * p_madw)444d6b92ffaSHans Petter Selasky static void sr_rcv_process_get_method(osm_sa_t * sa, IN osm_madw_t * p_madw)
445d6b92ffaSHans Petter Selasky {
446d6b92ffaSHans Petter Selasky 	ib_sa_mad_t *p_sa_mad;
447d6b92ffaSHans Petter Selasky 	ib_service_record_t *p_recvd_service_rec;
448d6b92ffaSHans Petter Selasky 	osm_sr_match_item_t sr_match_item;
449d6b92ffaSHans Petter Selasky 	osm_sr_search_ctxt_t context;
450d6b92ffaSHans Petter Selasky 	osm_physp_t *p_req_physp;
451d6b92ffaSHans Petter Selasky 
452d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(sa->p_log);
453d6b92ffaSHans Petter Selasky 
454d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_madw);
455d6b92ffaSHans Petter Selasky 
456d6b92ffaSHans Petter Selasky 	/* Grab the lock */
457d6b92ffaSHans Petter Selasky 	cl_plock_acquire(sa->p_lock);
458d6b92ffaSHans Petter Selasky 
459d6b92ffaSHans Petter Selasky 	/* update the requester physical port */
460d6b92ffaSHans Petter Selasky 	p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn,
461d6b92ffaSHans Petter Selasky 						osm_madw_get_mad_addr_ptr
462d6b92ffaSHans Petter Selasky 						(p_madw));
463d6b92ffaSHans Petter Selasky 	if (p_req_physp == NULL) {
464d6b92ffaSHans Petter Selasky 		cl_plock_release(sa->p_lock);
465d6b92ffaSHans Petter Selasky 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2409: "
466d6b92ffaSHans Petter Selasky 			"Cannot find requester physical port\n");
467d6b92ffaSHans Petter Selasky 		goto Exit;
468d6b92ffaSHans Petter Selasky 	}
469d6b92ffaSHans Petter Selasky 
470d6b92ffaSHans Petter Selasky 	p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
471d6b92ffaSHans Petter Selasky 	p_recvd_service_rec =
472d6b92ffaSHans Petter Selasky 	    (ib_service_record_t *) ib_sa_mad_get_payload_ptr(p_sa_mad);
473d6b92ffaSHans Petter Selasky 
474d6b92ffaSHans Petter Selasky 	if (OSM_LOG_IS_ACTIVE_V2(sa->p_log, OSM_LOG_DEBUG)) {
475d6b92ffaSHans Petter Selasky 		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
476d6b92ffaSHans Petter Selasky 			"Requester port GUID 0x%" PRIx64 "\n",
477d6b92ffaSHans Petter Selasky 			cl_ntoh64(osm_physp_get_port_guid(p_req_physp)));
478d6b92ffaSHans Petter Selasky 		osm_dump_service_record_v2(sa->p_log, p_recvd_service_rec,
479d6b92ffaSHans Petter Selasky 					   FILE_ID, OSM_LOG_DEBUG);
480d6b92ffaSHans Petter Selasky 	}
481d6b92ffaSHans Petter Selasky 
482d6b92ffaSHans Petter Selasky 	cl_qlist_init(&sr_match_item.sr_list);
483d6b92ffaSHans Petter Selasky 	sr_match_item.p_service_rec = p_recvd_service_rec;
484d6b92ffaSHans Petter Selasky 	sr_match_item.comp_mask = p_sa_mad->comp_mask;
485d6b92ffaSHans Petter Selasky 	sr_match_item.sa = sa;
486d6b92ffaSHans Petter Selasky 
487d6b92ffaSHans Petter Selasky 	context.p_sr_item = &sr_match_item;
488d6b92ffaSHans Petter Selasky 	context.p_req_physp = p_req_physp;
489d6b92ffaSHans Petter Selasky 
490d6b92ffaSHans Petter Selasky 	cl_qlist_apply_func(&sa->p_subn->sa_sr_list, get_matching_sr, &context);
491d6b92ffaSHans Petter Selasky 
492d6b92ffaSHans Petter Selasky 	cl_plock_release(sa->p_lock);
493d6b92ffaSHans Petter Selasky 
494d6b92ffaSHans Petter Selasky 	if (p_sa_mad->method == IB_MAD_METHOD_GET &&
495d6b92ffaSHans Petter Selasky 	    cl_qlist_count(&sr_match_item.sr_list) == 0) {
496d6b92ffaSHans Petter Selasky 		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
497d6b92ffaSHans Petter Selasky 			"No records matched the Service Record query\n");
498d6b92ffaSHans Petter Selasky 		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RECORDS);
499d6b92ffaSHans Petter Selasky 		goto Exit;
500d6b92ffaSHans Petter Selasky 	}
501d6b92ffaSHans Petter Selasky 
502d6b92ffaSHans Petter Selasky 	sr_rcv_respond(sa, p_madw, &sr_match_item.sr_list);
503d6b92ffaSHans Petter Selasky 
504d6b92ffaSHans Petter Selasky Exit:
505d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(sa->p_log);
506d6b92ffaSHans Petter Selasky 	return;
507d6b92ffaSHans Petter Selasky }
508d6b92ffaSHans Petter Selasky 
sr_rcv_process_set_method(osm_sa_t * sa,IN osm_madw_t * p_madw)509d6b92ffaSHans Petter Selasky static void sr_rcv_process_set_method(osm_sa_t * sa, IN osm_madw_t * p_madw)
510d6b92ffaSHans Petter Selasky {
511d6b92ffaSHans Petter Selasky 	ib_sa_mad_t *p_sa_mad;
512d6b92ffaSHans Petter Selasky 	ib_service_record_t *p_recvd_service_rec;
513d6b92ffaSHans Petter Selasky 	ib_net64_t comp_mask;
514d6b92ffaSHans Petter Selasky 	osm_svcr_t *p_svcr;
515d6b92ffaSHans Petter Selasky 	osm_sa_item_t *p_sr_item;
516d6b92ffaSHans Petter Selasky 	cl_qlist_t sr_list;
517d6b92ffaSHans Petter Selasky 
518d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(sa->p_log);
519d6b92ffaSHans Petter Selasky 
520d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_madw);
521d6b92ffaSHans Petter Selasky 
522d6b92ffaSHans Petter Selasky 	p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
523d6b92ffaSHans Petter Selasky 	p_recvd_service_rec =
524d6b92ffaSHans Petter Selasky 	    (ib_service_record_t *) ib_sa_mad_get_payload_ptr(p_sa_mad);
525d6b92ffaSHans Petter Selasky 
526d6b92ffaSHans Petter Selasky 	comp_mask = p_sa_mad->comp_mask;
527d6b92ffaSHans Petter Selasky 
528d6b92ffaSHans Petter Selasky 	if (OSM_LOG_IS_ACTIVE_V2(sa->p_log, OSM_LOG_DEBUG))
529d6b92ffaSHans Petter Selasky 		osm_dump_service_record_v2(sa->p_log, p_recvd_service_rec,
530d6b92ffaSHans Petter Selasky 					   FILE_ID, OSM_LOG_DEBUG);
531d6b92ffaSHans Petter Selasky 
532d6b92ffaSHans Petter Selasky 	if ((comp_mask & (IB_SR_COMPMASK_SID | IB_SR_COMPMASK_SGID)) !=
533d6b92ffaSHans Petter Selasky 	    (IB_SR_COMPMASK_SID | IB_SR_COMPMASK_SGID)) {
534d6b92ffaSHans Petter Selasky 		cl_plock_release(sa->p_lock);
535d6b92ffaSHans Petter Selasky 		OSM_LOG(sa->p_log, OSM_LOG_VERBOSE,
536d6b92ffaSHans Petter Selasky 			"Component Mask RID check failed for METHOD_SET\n");
537d6b92ffaSHans Petter Selasky 		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID);
538d6b92ffaSHans Petter Selasky 		goto Exit;
539d6b92ffaSHans Petter Selasky 	}
540d6b92ffaSHans Petter Selasky 
541d6b92ffaSHans Petter Selasky 	/* if we were not provided with a service lease make it infinite */
542d6b92ffaSHans Petter Selasky 	if (!(comp_mask & IB_SR_COMPMASK_SLEASE)) {
543d6b92ffaSHans Petter Selasky 		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
544d6b92ffaSHans Petter Selasky 			"ServiceLease Component Mask not set - using infinite lease\n");
545d6b92ffaSHans Petter Selasky 		p_recvd_service_rec->service_lease = 0xFFFFFFFF;
546d6b92ffaSHans Petter Selasky 	}
547d6b92ffaSHans Petter Selasky 
548d6b92ffaSHans Petter Selasky 	/* If Record exists with matching RID */
549d6b92ffaSHans Petter Selasky 	p_svcr = osm_svcr_get_by_rid(sa->p_subn, sa->p_log,
550d6b92ffaSHans Petter Selasky 				     p_recvd_service_rec);
551d6b92ffaSHans Petter Selasky 
552d6b92ffaSHans Petter Selasky 	if (p_svcr == NULL) {
553d6b92ffaSHans Petter Selasky 		/* Create the instance of the osm_svcr_t object */
554d6b92ffaSHans Petter Selasky 		p_svcr = osm_svcr_new(p_recvd_service_rec);
555d6b92ffaSHans Petter Selasky 		if (p_svcr == NULL) {
556d6b92ffaSHans Petter Selasky 			cl_plock_release(sa->p_lock);
557d6b92ffaSHans Petter Selasky 			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2411: "
558d6b92ffaSHans Petter Selasky 				"Failed to create new service record\n");
559d6b92ffaSHans Petter Selasky 
560d6b92ffaSHans Petter Selasky 			osm_sa_send_error(sa, p_madw,
561d6b92ffaSHans Petter Selasky 					  IB_SA_MAD_STATUS_NO_RESOURCES);
562d6b92ffaSHans Petter Selasky 			goto Exit;
563d6b92ffaSHans Petter Selasky 		}
564d6b92ffaSHans Petter Selasky 
565d6b92ffaSHans Petter Selasky 		/* Add this new osm_svcr_t object to subnet object */
566d6b92ffaSHans Petter Selasky 		osm_svcr_insert_to_db(sa->p_subn, sa->p_log, p_svcr);
567d6b92ffaSHans Petter Selasky 
568d6b92ffaSHans Petter Selasky 	} else			/* Update the old instance of the osm_svcr_t object */
569d6b92ffaSHans Petter Selasky 		osm_svcr_init(p_svcr, p_recvd_service_rec);
570d6b92ffaSHans Petter Selasky 
571d6b92ffaSHans Petter Selasky 	cl_plock_release(sa->p_lock);
572d6b92ffaSHans Petter Selasky 
573d6b92ffaSHans Petter Selasky 	if (p_recvd_service_rec->service_lease != 0xFFFFFFFF) {
574d6b92ffaSHans Petter Selasky #if 0
575d6b92ffaSHans Petter Selasky 		cl_timer_trim(&sa->sr_timer,
576d6b92ffaSHans Petter Selasky 			      p_recvd_service_rec->service_lease * 1000);
577d6b92ffaSHans Petter Selasky #endif
578d6b92ffaSHans Petter Selasky 		/*  This was a bug since no check was made to see if too long */
579d6b92ffaSHans Petter Selasky 		/*  just make sure the timer works - get a call back within a second */
580d6b92ffaSHans Petter Selasky 		cl_timer_trim(&sa->sr_timer, 1000);
581d6b92ffaSHans Petter Selasky 		p_svcr->modified_time = cl_get_time_stamp_sec();
582d6b92ffaSHans Petter Selasky 	}
583d6b92ffaSHans Petter Selasky 
584d6b92ffaSHans Petter Selasky 	p_sr_item = malloc(SA_SR_RESP_SIZE);
585d6b92ffaSHans Petter Selasky 	if (p_sr_item == NULL) {
586d6b92ffaSHans Petter Selasky 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2412: "
587d6b92ffaSHans Petter Selasky 			"Unable to acquire Service record\n");
588d6b92ffaSHans Petter Selasky 		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RESOURCES);
589d6b92ffaSHans Petter Selasky 		goto Exit;
590d6b92ffaSHans Petter Selasky 	}
591d6b92ffaSHans Petter Selasky 
592d6b92ffaSHans Petter Selasky 	if ((comp_mask & IB_SR_COMPMASK_SPKEY) != IB_SR_COMPMASK_SPKEY)
593d6b92ffaSHans Petter Selasky 		/* Set the Default Service P_Key in the response */
594d6b92ffaSHans Petter Selasky 		p_recvd_service_rec->service_pkey = IB_DEFAULT_PKEY;
595d6b92ffaSHans Petter Selasky 
596d6b92ffaSHans Petter Selasky 	p_sr_item->resp.service_rec = *p_recvd_service_rec;
597d6b92ffaSHans Petter Selasky 	cl_qlist_init(&sr_list);
598d6b92ffaSHans Petter Selasky 
599d6b92ffaSHans Petter Selasky 	cl_qlist_insert_tail(&sr_list, &p_sr_item->list_item);
600d6b92ffaSHans Petter Selasky 
601d6b92ffaSHans Petter Selasky 	sr_rcv_respond(sa, p_madw, &sr_list);
602d6b92ffaSHans Petter Selasky 
603d6b92ffaSHans Petter Selasky Exit:
604d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(sa->p_log);
605d6b92ffaSHans Petter Selasky }
606d6b92ffaSHans Petter Selasky 
sr_rcv_process_delete_method(osm_sa_t * sa,IN osm_madw_t * p_madw)607d6b92ffaSHans Petter Selasky static void sr_rcv_process_delete_method(osm_sa_t * sa, IN osm_madw_t * p_madw)
608d6b92ffaSHans Petter Selasky {
609d6b92ffaSHans Petter Selasky 	ib_sa_mad_t *p_sa_mad;
610d6b92ffaSHans Petter Selasky 	ib_service_record_t *p_recvd_service_rec;
611d6b92ffaSHans Petter Selasky 	osm_svcr_t *p_svcr;
612d6b92ffaSHans Petter Selasky 	osm_sa_item_t *p_sr_item;
613d6b92ffaSHans Petter Selasky 	cl_qlist_t sr_list;
614d6b92ffaSHans Petter Selasky 
615d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(sa->p_log);
616d6b92ffaSHans Petter Selasky 
617d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_madw);
618d6b92ffaSHans Petter Selasky 
619d6b92ffaSHans Petter Selasky 	p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
620d6b92ffaSHans Petter Selasky 	p_recvd_service_rec =
621d6b92ffaSHans Petter Selasky 	    (ib_service_record_t *) ib_sa_mad_get_payload_ptr(p_sa_mad);
622d6b92ffaSHans Petter Selasky 
623d6b92ffaSHans Petter Selasky 	if (OSM_LOG_IS_ACTIVE_V2(sa->p_log, OSM_LOG_DEBUG))
624d6b92ffaSHans Petter Selasky 		osm_dump_service_record_v2(sa->p_log, p_recvd_service_rec,
625d6b92ffaSHans Petter Selasky 					   FILE_ID, OSM_LOG_DEBUG);
626d6b92ffaSHans Petter Selasky 
627d6b92ffaSHans Petter Selasky 	/* If Record exists with matching RID */
628d6b92ffaSHans Petter Selasky 	p_svcr = osm_svcr_get_by_rid(sa->p_subn, sa->p_log,
629d6b92ffaSHans Petter Selasky 				     p_recvd_service_rec);
630d6b92ffaSHans Petter Selasky 
631d6b92ffaSHans Petter Selasky 	if (p_svcr == NULL) {
632d6b92ffaSHans Petter Selasky 		cl_plock_release(sa->p_lock);
633d6b92ffaSHans Petter Selasky 		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
634d6b92ffaSHans Petter Selasky 			"No records matched the RID\n");
635d6b92ffaSHans Petter Selasky 		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RECORDS);
636d6b92ffaSHans Petter Selasky 		goto Exit;
637d6b92ffaSHans Petter Selasky 	}
638d6b92ffaSHans Petter Selasky 
639d6b92ffaSHans Petter Selasky 	osm_svcr_remove_from_db(sa->p_subn, sa->p_log, p_svcr);
640d6b92ffaSHans Petter Selasky 	cl_plock_release(sa->p_lock);
641d6b92ffaSHans Petter Selasky 
642d6b92ffaSHans Petter Selasky 	p_sr_item = malloc(SA_SR_RESP_SIZE);
643d6b92ffaSHans Petter Selasky 	if (p_sr_item == NULL) {
644d6b92ffaSHans Petter Selasky 		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2413: "
645d6b92ffaSHans Petter Selasky 			"Unable to acquire Service record\n");
646d6b92ffaSHans Petter Selasky 		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_NO_RESOURCES);
647d6b92ffaSHans Petter Selasky 		osm_svcr_delete(p_svcr);
648d6b92ffaSHans Petter Selasky 		goto Exit;
649d6b92ffaSHans Petter Selasky 	}
650d6b92ffaSHans Petter Selasky 
651d6b92ffaSHans Petter Selasky 	/* provide back the copy of the record */
652d6b92ffaSHans Petter Selasky 	p_sr_item->resp.service_rec = p_svcr->service_record;
653d6b92ffaSHans Petter Selasky 	cl_qlist_init(&sr_list);
654d6b92ffaSHans Petter Selasky 
655d6b92ffaSHans Petter Selasky 	cl_qlist_insert_tail(&sr_list, &p_sr_item->list_item);
656d6b92ffaSHans Petter Selasky 
657d6b92ffaSHans Petter Selasky 	osm_svcr_delete(p_svcr);
658d6b92ffaSHans Petter Selasky 
659d6b92ffaSHans Petter Selasky 	sr_rcv_respond(sa, p_madw, &sr_list);
660d6b92ffaSHans Petter Selasky 
661d6b92ffaSHans Petter Selasky Exit:
662d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(sa->p_log);
663d6b92ffaSHans Petter Selasky 	return;
664d6b92ffaSHans Petter Selasky }
665d6b92ffaSHans Petter Selasky 
osm_sr_rcv_process(IN void * context,IN void * data)666d6b92ffaSHans Petter Selasky void osm_sr_rcv_process(IN void *context, IN void *data)
667d6b92ffaSHans Petter Selasky {
668d6b92ffaSHans Petter Selasky 	osm_sa_t *sa = context;
669d6b92ffaSHans Petter Selasky 	osm_madw_t *p_madw = data;
670d6b92ffaSHans Petter Selasky 	ib_sa_mad_t *p_sa_mad;
671d6b92ffaSHans Petter Selasky 	boolean_t valid;
672d6b92ffaSHans Petter Selasky 
673d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(sa->p_log);
674d6b92ffaSHans Petter Selasky 
675d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_madw);
676d6b92ffaSHans Petter Selasky 
677d6b92ffaSHans Petter Selasky 	p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
678d6b92ffaSHans Petter Selasky 
679d6b92ffaSHans Petter Selasky 	CL_ASSERT(p_sa_mad->attr_id == IB_MAD_ATTR_SERVICE_RECORD);
680d6b92ffaSHans Petter Selasky 
681d6b92ffaSHans Petter Selasky 	switch (p_sa_mad->method) {
682d6b92ffaSHans Petter Selasky 	case IB_MAD_METHOD_SET:
683d6b92ffaSHans Petter Selasky 		cl_plock_excl_acquire(sa->p_lock);
684d6b92ffaSHans Petter Selasky 		valid = validate_sr(sa, p_madw);
685d6b92ffaSHans Petter Selasky 		if (!valid) {
686d6b92ffaSHans Petter Selasky 			cl_plock_release(sa->p_lock);
687d6b92ffaSHans Petter Selasky 			OSM_LOG(sa->p_log, OSM_LOG_VERBOSE,
688d6b92ffaSHans Petter Selasky 				"Component Mask check failed for set request\n");
689d6b92ffaSHans Petter Selasky 			osm_sa_send_error(sa, p_madw,
690d6b92ffaSHans Petter Selasky 					  IB_SA_MAD_STATUS_REQ_INVALID);
691d6b92ffaSHans Petter Selasky 			goto Exit;
692d6b92ffaSHans Petter Selasky 		}
693d6b92ffaSHans Petter Selasky 		sr_rcv_process_set_method(sa, p_madw);
694d6b92ffaSHans Petter Selasky 		break;
695d6b92ffaSHans Petter Selasky 	case IB_MAD_METHOD_DELETE:
696d6b92ffaSHans Petter Selasky 		cl_plock_excl_acquire(sa->p_lock);
697d6b92ffaSHans Petter Selasky 		valid = validate_sr(sa, p_madw);
698d6b92ffaSHans Petter Selasky 		if (!valid) {
699d6b92ffaSHans Petter Selasky 			cl_plock_release(sa->p_lock);
700d6b92ffaSHans Petter Selasky 			OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
701d6b92ffaSHans Petter Selasky 				"Component Mask check failed for delete request\n");
702d6b92ffaSHans Petter Selasky 			osm_sa_send_error(sa, p_madw,
703d6b92ffaSHans Petter Selasky 					  IB_SA_MAD_STATUS_REQ_INVALID);
704d6b92ffaSHans Petter Selasky 			goto Exit;
705d6b92ffaSHans Petter Selasky 		}
706d6b92ffaSHans Petter Selasky 		sr_rcv_process_delete_method(sa, p_madw);
707d6b92ffaSHans Petter Selasky 		break;
708d6b92ffaSHans Petter Selasky 	case IB_MAD_METHOD_GET:
709d6b92ffaSHans Petter Selasky 	case IB_MAD_METHOD_GETTABLE:
710d6b92ffaSHans Petter Selasky 		sr_rcv_process_get_method(sa, p_madw);
711d6b92ffaSHans Petter Selasky 		break;
712d6b92ffaSHans Petter Selasky 	default:
713d6b92ffaSHans Petter Selasky 		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
714d6b92ffaSHans Petter Selasky 			"Unsupported Method (%s) for ServiceRecord request\n",
715d6b92ffaSHans Petter Selasky 			ib_get_sa_method_str(p_sa_mad->method));
716d6b92ffaSHans Petter Selasky 		osm_sa_send_error(sa, p_madw, IB_MAD_STATUS_UNSUP_METHOD_ATTR);
717d6b92ffaSHans Petter Selasky 		break;
718d6b92ffaSHans Petter Selasky 	}
719d6b92ffaSHans Petter Selasky 
720d6b92ffaSHans Petter Selasky Exit:
721d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(sa->p_log);
722d6b92ffaSHans Petter Selasky }
723d6b92ffaSHans Petter Selasky 
osm_sr_rcv_lease_cb(IN void * context)724d6b92ffaSHans Petter Selasky void osm_sr_rcv_lease_cb(IN void *context)
725d6b92ffaSHans Petter Selasky {
726d6b92ffaSHans Petter Selasky 	osm_sa_t *sa = context;
727d6b92ffaSHans Petter Selasky 	cl_list_item_t *p_list_item;
728d6b92ffaSHans Petter Selasky 	cl_list_item_t *p_next_list_item;
729d6b92ffaSHans Petter Selasky 	osm_svcr_t *p_svcr;
730d6b92ffaSHans Petter Selasky 	uint32_t curr_time;
731d6b92ffaSHans Petter Selasky 	uint32_t elapsed_time;
732d6b92ffaSHans Petter Selasky 	uint32_t trim_time = 20;	/*  maxiaml timer refresh is 20 seconds */
733d6b92ffaSHans Petter Selasky 
734d6b92ffaSHans Petter Selasky 	OSM_LOG_ENTER(sa->p_log);
735d6b92ffaSHans Petter Selasky 
736d6b92ffaSHans Petter Selasky 	cl_plock_excl_acquire(sa->p_lock);
737d6b92ffaSHans Petter Selasky 
738d6b92ffaSHans Petter Selasky 	p_list_item = cl_qlist_head(&sa->p_subn->sa_sr_list);
739d6b92ffaSHans Petter Selasky 
740d6b92ffaSHans Petter Selasky 	while (p_list_item != cl_qlist_end(&sa->p_subn->sa_sr_list)) {
741d6b92ffaSHans Petter Selasky 		p_svcr = (osm_svcr_t *) p_list_item;
742d6b92ffaSHans Petter Selasky 
743d6b92ffaSHans Petter Selasky 		if (p_svcr->service_record.service_lease == 0xFFFFFFFF) {
744d6b92ffaSHans Petter Selasky 			p_list_item = cl_qlist_next(p_list_item);
745d6b92ffaSHans Petter Selasky 			continue;
746d6b92ffaSHans Petter Selasky 		}
747d6b92ffaSHans Petter Selasky 
748d6b92ffaSHans Petter Selasky 		/* current time in seconds */
749d6b92ffaSHans Petter Selasky 		curr_time = cl_get_time_stamp_sec();
750d6b92ffaSHans Petter Selasky 		/* elapsed time from last modify */
751d6b92ffaSHans Petter Selasky 		elapsed_time = curr_time - p_svcr->modified_time;
752d6b92ffaSHans Petter Selasky 		/* but it can not be less then 1 */
753d6b92ffaSHans Petter Selasky 		if (elapsed_time < 1)
754d6b92ffaSHans Petter Selasky 			elapsed_time = 1;
755d6b92ffaSHans Petter Selasky 
756d6b92ffaSHans Petter Selasky 		if (elapsed_time < p_svcr->lease_period) {
757d6b92ffaSHans Petter Selasky 			/*
758d6b92ffaSHans Petter Selasky 			   Just update the service lease period
759d6b92ffaSHans Petter Selasky 			   note: for simplicity we work with a uint32_t field
760d6b92ffaSHans Petter Selasky 			   external to the network order lease_period of the MAD
761d6b92ffaSHans Petter Selasky 			 */
762d6b92ffaSHans Petter Selasky 			p_svcr->lease_period -= elapsed_time;
763d6b92ffaSHans Petter Selasky 
764d6b92ffaSHans Petter Selasky 			OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
765d6b92ffaSHans Petter Selasky 				"Remaining time for Service Name:%s is:0x%X\n",
766d6b92ffaSHans Petter Selasky 				p_svcr->service_record.service_name,
767d6b92ffaSHans Petter Selasky 				p_svcr->lease_period);
768d6b92ffaSHans Petter Selasky 
769d6b92ffaSHans Petter Selasky 			p_svcr->modified_time = curr_time;
770d6b92ffaSHans Petter Selasky 
771d6b92ffaSHans Petter Selasky 			/* Update the trim timer */
772d6b92ffaSHans Petter Selasky 			if (trim_time > p_svcr->lease_period) {
773d6b92ffaSHans Petter Selasky 				trim_time = p_svcr->lease_period;
774d6b92ffaSHans Petter Selasky 				if (trim_time < 1)
775d6b92ffaSHans Petter Selasky 					trim_time = 1;
776d6b92ffaSHans Petter Selasky 			}
777d6b92ffaSHans Petter Selasky 
778d6b92ffaSHans Petter Selasky 			p_list_item = cl_qlist_next(p_list_item);
779d6b92ffaSHans Petter Selasky 			continue;
780d6b92ffaSHans Petter Selasky 
781d6b92ffaSHans Petter Selasky 		} else {
782d6b92ffaSHans Petter Selasky 			p_next_list_item = cl_qlist_next(p_list_item);
783d6b92ffaSHans Petter Selasky 
784d6b92ffaSHans Petter Selasky 			/* Remove the service Record */
785d6b92ffaSHans Petter Selasky 			osm_svcr_remove_from_db(sa->p_subn, sa->p_log, p_svcr);
786d6b92ffaSHans Petter Selasky 
787d6b92ffaSHans Petter Selasky 			osm_svcr_delete(p_svcr);
788d6b92ffaSHans Petter Selasky 
789d6b92ffaSHans Petter Selasky 			p_list_item = p_next_list_item;
790d6b92ffaSHans Petter Selasky 			continue;
791d6b92ffaSHans Petter Selasky 		}
792d6b92ffaSHans Petter Selasky 	}
793d6b92ffaSHans Petter Selasky 
794d6b92ffaSHans Petter Selasky 	/* Release the Lock */
795d6b92ffaSHans Petter Selasky 	cl_plock_release(sa->p_lock);
796d6b92ffaSHans Petter Selasky 
797d6b92ffaSHans Petter Selasky 	if (trim_time != 0xFFFFFFFF) {
798d6b92ffaSHans Petter Selasky 		cl_timer_trim(&sa->sr_timer, trim_time * 1000);	/* Convert to milli seconds */
799d6b92ffaSHans Petter Selasky 	}
800d6b92ffaSHans Petter Selasky 
801d6b92ffaSHans Petter Selasky 	OSM_LOG_EXIT(sa->p_log);
802d6b92ffaSHans Petter Selasky }
803