osmt_multicast.c revision 276976
1/*
2 * Copyright (c) 2006-2008 Voltaire, Inc. All rights reserved.
3 * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
4 * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
5 *
6 * This software is available to you under a choice of one of two
7 * licenses.  You may choose to be licensed under the terms of the GNU
8 * General Public License (GPL) Version 2, available from the file
9 * COPYING in the main directory of this source tree, or the
10 * OpenIB.org BSD license below:
11 *
12 *     Redistribution and use in source and binary forms, with or
13 *     without modification, are permitted provided that the following
14 *     conditions are met:
15 *
16 *      - Redistributions of source code must retain the above
17 *        copyright notice, this list of conditions and the following
18 *        disclaimer.
19 *
20 *      - Redistributions in binary form must reproduce the above
21 *        copyright notice, this list of conditions and the following
22 *        disclaimer in the documentation and/or other materials
23 *        provided with the distribution.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 * SOFTWARE.
33 *
34 */
35
36/*
37 * Abstract:
38 * 	Implementation of Multicast Member testing flow..
39 *
40 */
41
42#ifndef __WIN__
43#include <unistd.h>
44#endif
45#include <sys/socket.h>
46#include <stdio.h>
47#include <stdlib.h>
48#include <string.h>
49#include <arpa/inet.h>
50#include <complib/cl_debug.h>
51#include <complib/cl_map.h>
52#include <complib/cl_list.h>
53#include "osmtest.h"
54
55/**********************************************************************
56 **********************************************************************/
57
58static void __osmt_print_all_multicast_records(IN osmtest_t * const p_osmt)
59{
60	uint32_t i;
61	ib_api_status_t status;
62	osmv_query_req_t req;
63	osmv_user_query_t user;
64	osmtest_req_context_t context;
65	ib_member_rec_t *mcast_record;
66
67	memset(&context, 0, sizeof(context));
68	memset(&req, 0, sizeof(req));
69	memset(&user, 0, sizeof(user));
70
71	user.attr_id = IB_MAD_ATTR_MCMEMBER_RECORD;
72	user.attr_offset = ib_get_attr_offset(sizeof(*mcast_record));
73
74	req.query_type = OSMV_QUERY_USER_DEFINED;
75	req.timeout_ms = p_osmt->opt.transaction_timeout;
76	req.retry_cnt = 1;
77	req.flags = OSM_SA_FLAGS_SYNC;
78	context.p_osmt = p_osmt;
79	req.query_context = &context;
80	req.pfn_query_cb = osmtest_query_res_cb;
81	req.p_query_input = &user;
82
83	/* UnTrusted (SMKey of 0)  - get the multicast groups */
84	status = osmv_query_sa(p_osmt->h_bind, &req);
85
86	if (status != IB_SUCCESS || context.result.status != IB_SUCCESS) {
87		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02B5: "
88			"Failed getting the multicast groups records - %s/%s\n",
89			ib_get_err_str(status),
90			ib_get_err_str(context.result.status));
91		return;
92	}
93
94	osm_log(&p_osmt->log, OSM_LOG_INFO,
95		"\n                    |------------------------------------------|"
96		"\n                    |        Remaining Multicast Groups        |"
97		"\n                    |------------------------------------------|\n");
98
99	for (i = 0; i < context.result.result_cnt; i++) {
100		mcast_record =
101		    osmv_get_query_mc_rec(context.result.p_result_madw, i);
102		osm_dump_mc_record(&p_osmt->log, mcast_record, OSM_LOG_INFO);
103	}
104
105	/* Trusted - now get the multicast group members */
106	req.sm_key = OSM_DEFAULT_SM_KEY;
107	status = osmv_query_sa(p_osmt->h_bind, &req);
108
109	if (status != IB_SUCCESS || context.result.status != IB_SUCCESS) {
110		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02B6: "
111			"Failed getting the multicast group members records - %s/%s\n",
112			ib_get_err_str(status),
113			ib_get_err_str(context.result.status));
114		return;
115	}
116
117	osm_log(&p_osmt->log, OSM_LOG_INFO,
118		"\n                    |--------------------------------------------------|"
119		"\n                    |        Remaining Multicast Group Members        |"
120		"\n                    |--------------------------------------------------|\n");
121
122	for (i = 0; i < context.result.result_cnt; i++) {
123		mcast_record =
124		    osmv_get_query_mc_rec(context.result.p_result_madw, i);
125		osm_dump_mc_record(&p_osmt->log, mcast_record, OSM_LOG_INFO);
126	}
127
128}
129
130/**********************************************************************
131 **********************************************************************/
132
133static cl_status_t
134__match_mgids(IN const void *const p_object, IN void *context)
135{
136	ib_gid_t *p_mgid_context = (ib_gid_t *) context;
137	ib_gid_t *p_mgid_list_item = (ib_gid_t *) p_object;
138	int32_t count;
139
140	count = memcmp(p_mgid_context, p_mgid_list_item, sizeof(ib_gid_t));
141	if (count == 0)
142		return CL_SUCCESS;
143	else
144		return CL_NOT_FOUND;
145}
146
147/**********************************************************************
148 **********************************************************************/
149
150ib_api_status_t osmt_query_mcast(IN osmtest_t * const p_osmt)
151{
152	ib_api_status_t status = IB_SUCCESS;
153	osmv_user_query_t user;
154	osmv_query_req_t req;
155	osmtest_req_context_t context;
156	ib_member_rec_t *p_rec;
157	uint32_t i, num_recs = 0;
158	cl_list_t mgids_list;
159	cl_list_t *p_mgids_list;
160	cl_list_iterator_t p_mgids_res;
161	cl_status_t cl_status;
162	cl_map_item_t *p_item, *p_next_item;
163	osmtest_mgrp_t *p_mgrp;
164
165	OSM_LOG_ENTER(&p_osmt->log);
166
167	/*
168	 * Do a blocking query for all Multicast Records in the subnet.
169	 * The result is returned in the result field of the caller's
170	 * context structure.
171	 *
172	 * The query structures are locals.
173	 */
174
175	memset(&req, 0, sizeof(req));
176	memset(&user, 0, sizeof(user));
177
178	context.p_osmt = p_osmt;
179	user.attr_id = IB_MAD_ATTR_MCMEMBER_RECORD;
180	user.attr_offset = ib_get_attr_offset(sizeof(ib_member_rec_t));
181
182	req.query_type = OSMV_QUERY_USER_DEFINED;
183	req.timeout_ms = p_osmt->opt.transaction_timeout;
184	req.retry_cnt = p_osmt->opt.retry_count;
185	req.flags = OSM_SA_FLAGS_SYNC;
186	req.query_context = &context;
187	req.pfn_query_cb = osmtest_query_res_cb;
188	req.p_query_input = &user;
189
190	status = osmv_query_sa(p_osmt->h_bind, &req);
191
192	if (status != IB_SUCCESS) {
193		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0203: "
194			"ib_query failed (%s)\n", ib_get_err_str(status));
195		goto Exit;
196	}
197
198	status = context.result.status;
199
200	if (status != IB_SUCCESS) {
201		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0264: "
202			"ib_query failed (%s)\n", ib_get_err_str(status));
203		if (status == IB_REMOTE_ERROR) {
204			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
205				"Remote error = %s.\n",
206				ib_get_mad_status_str(osm_madw_get_mad_ptr
207						      (context.result.
208						       p_result_madw)));
209		}
210		goto Exit;
211	}
212
213	/* ok we have got something */
214	/* First Delete the old MGID Table */
215	p_next_item = cl_qmap_head(&p_osmt->exp_subn.mgrp_mlid_tbl);
216	while (p_next_item != cl_qmap_end(&p_osmt->exp_subn.mgrp_mlid_tbl)) {
217		p_item = p_next_item;
218		p_next_item = cl_qmap_next(p_item);
219		cl_qmap_remove_item(&p_osmt->exp_subn.mgrp_mlid_tbl, p_item);
220		free(p_item);
221
222	}
223
224	cl_list_construct(&mgids_list);
225	cl_list_init(&mgids_list, num_recs);
226	p_mgids_list = &mgids_list;
227	num_recs = context.result.result_cnt;
228	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Received %u records\n",
229		num_recs);
230
231	for (i = 0; i < num_recs; i++) {
232		p_rec = osmv_get_query_result(context.result.p_result_madw, i);
233		p_mgids_res =
234		    cl_list_find_from_head(p_mgids_list, __match_mgids,
235					   &(p_rec->mgid));
236		/* If returns iterator other than end of list, same mgid exists already */
237		if (p_mgids_res != cl_list_end(p_mgids_list)) {
238			char gid_str[INET6_ADDRSTRLEN];
239			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0265: "
240				"MCG MGIDs are the same - invalid MGID : %s\n",
241				inet_ntop(AF_INET6, p_rec->mgid.raw, gid_str,
242					  sizeof gid_str));
243			status = IB_ERROR;
244			goto Exit;
245
246		}
247		osm_dump_mc_record(&p_osmt->log, p_rec, OSM_LOG_VERBOSE);
248		cl_status = cl_list_insert_head(p_mgids_list, &(p_rec->mgid));
249		if (cl_status) {
250			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0205: "
251				"Could not add MGID to cl_list\n");
252			status = IB_ERROR;
253			goto Exit;
254		}
255		p_mgrp = (osmtest_mgrp_t *) malloc(sizeof(*p_mgrp));
256		if (!p_mgrp) {
257			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0204: "
258				"Could not allocate new MCG\n");
259			status = IB_ERROR;
260			goto Exit;
261		}
262		memcpy(&p_mgrp->mcmember_rec, p_rec,
263		       sizeof(p_mgrp->mcmember_rec));
264		cl_qmap_insert(&p_osmt->exp_subn.mgrp_mlid_tbl,
265			       cl_ntoh16(p_rec->mlid), &p_mgrp->map_item);
266	}
267
268Exit:
269	if (context.result.p_result_madw != NULL) {
270		osm_mad_pool_put(&p_osmt->mad_pool,
271				 context.result.p_result_madw);
272		context.result.p_result_madw = NULL;
273	}
274
275	OSM_LOG_EXIT(&p_osmt->log);
276	return (status);
277}
278
279/**********************************************************************
280 **********************************************************************/
281
282/* given a multicast request send and wait for response. */
283ib_api_status_t
284osmt_send_mcast_request(IN osmtest_t * const p_osmt,
285			IN uint8_t is_set,
286			IN ib_member_rec_t * p_mc_req,
287			IN uint64_t comp_mask, OUT ib_sa_mad_t * p_res)
288{
289	osmtest_req_context_t context;
290	ib_api_status_t status = IB_SUCCESS;
291	osmv_user_query_t user;
292	osmv_query_req_t req;
293
294	OSM_LOG_ENTER(&p_osmt->log);
295
296	/*
297	 * Do a blocking query for this record in the subnet.
298	 *
299	 * The query structures are locals.
300	 */
301	memset(&req, 0, sizeof(req));
302	memset(&user, 0, sizeof(user));
303	memset(&context, 0, sizeof(context));
304	memset(p_res, 0, sizeof(ib_sa_mad_t));
305
306	context.p_osmt = p_osmt;
307
308	user.p_attr = p_mc_req;
309	user.comp_mask = comp_mask;
310
311	if (is_set == 1) {
312		req.query_type = OSMV_QUERY_UD_MULTICAST_SET;
313	} else if (is_set == 0) {
314		req.query_type = OSMV_QUERY_UD_MULTICAST_DELETE;
315	} else if (is_set == 0xee) {
316		OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
317			"Set USER DEFINED QUERY\n");
318		req.query_type = OSMV_QUERY_USER_DEFINED;
319		user.method = IB_MAD_METHOD_GET;
320		user.attr_id = IB_MAD_ATTR_MCMEMBER_RECORD;
321		user.attr_offset = ib_get_attr_offset(sizeof(ib_member_rec_t));
322	} else if (is_set == 0xff) {
323		OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
324			"Set USER DEFINED QUERY\n");
325		req.query_type = OSMV_QUERY_USER_DEFINED;
326		user.method = IB_MAD_METHOD_SET;
327		user.attr_id = IB_MAD_ATTR_MCMEMBER_RECORD;
328		user.attr_offset = ib_get_attr_offset(sizeof(ib_member_rec_t));
329	}
330
331	/* TODO : Check the validity of all user fields in order to use
332	   OSMV_QUERY_USER_DEFINED
333	   p_user_query = ( osmv_user_query_t * ) p_query_req->p_query_input;
334	   if (p_user_query->method) sa_mad_data.method = p_user_query->method;
335	   sa_mad_data.attr_offset = p_user_query->attr_offset;
336	   sa_mad_data.attr_id = p_user_query->attr_id;
337	   sa_mad_data.comp_mask = p_user_query->comp_mask;
338	   sa_mad_data.p_attr = p_user_query->p_attr;
339	 */
340
341	req.timeout_ms = p_osmt->opt.transaction_timeout;
342	req.retry_cnt = p_osmt->opt.retry_count;
343	req.flags = OSM_SA_FLAGS_SYNC;
344	req.query_context = &context;
345	req.pfn_query_cb = osmtest_query_res_cb;
346	req.p_query_input = &user;
347
348	status = osmv_query_sa(p_osmt->h_bind, &req);
349
350	if (status != IB_SUCCESS) {
351		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0206: "
352			"ib_query failed (%s)\n", ib_get_err_str(status));
353		goto Exit;
354	}
355
356	/* ok it worked */
357	memcpy(p_res,
358	       osm_madw_get_mad_ptr(context.result.p_result_madw),
359	       sizeof(ib_sa_mad_t));
360
361	status = context.result.status;
362
363	if (status != IB_SUCCESS) {
364		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0224: "
365			"ib_query failed (%s)\n", ib_get_err_str(status));
366		if (status == IB_REMOTE_ERROR) {
367			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
368				"Remote error = %s\n",
369				ib_get_mad_status_str(osm_madw_get_mad_ptr
370						      (context.result.
371						       p_result_madw)));
372		}
373	}
374
375Exit:
376	/*
377	 * Return the IB query MAD to the pool as necessary.
378	 */
379	if (context.result.p_result_madw != NULL) {
380		osm_mad_pool_put(&p_osmt->mad_pool,
381				 context.result.p_result_madw);
382		context.result.p_result_madw = NULL;
383	}
384
385	OSM_LOG_EXIT(&p_osmt->log);
386	return (status);
387}
388
389/**********************************************************************
390 **********************************************************************/
391
392void
393osmt_init_mc_query_rec(IN osmtest_t * const p_osmt,
394		       IN OUT ib_member_rec_t * p_mc_req)
395{
396	/* use default values so we can change only what we want later */
397	memset(p_mc_req, 0, sizeof(ib_member_rec_t));
398
399	/* we leave the MGID to the user */
400	memcpy(&p_mc_req->port_gid.unicast.interface_id,
401	       &p_osmt->local_port.port_guid,
402	       sizeof(p_osmt->local_port.port_guid)
403	    );
404
405	/*  use our own subnet prefix: */
406	p_mc_req->port_gid.unicast.prefix = CL_HTON64(0xFE80000000000000ULL);
407
408	/*  ib_net32_t  qkey; */
409	/*  ib_net16_t  mlid; - we keep it zero for upper level to decide. */
410	/*  uint8_t     mtu; - keep it zero means - anything you have please. */
411	/*  uint8_t     tclass; can leave as zero for now (between subnets) */
412	/*  ib_net16_t  pkey; leave as zero */
413	p_mc_req->rate = IB_LINK_WIDTH_ACTIVE_4X;
414	/*  uint8_t     pkt_life; zero means greater than zero ... */
415	/*  ib_net32_t  sl_flow_hop; keep it all zeros */
416	/*  we want to use a link local scope: 0x02 */
417	p_mc_req->scope_state = ib_member_set_scope_state(0x02, 0);
418}
419
420/***********************************************************************
421 * UD Multicast testing flow:
422 * o15.0.1.3:
423 * - Request new MCG with not enough components in comp_mask :
424 *   ERR_INSUFFICIENT_COMPONENTS
425 * o15.0.1.8:
426 * - Request a join with irrelevant RATE and get a ERR_INVALID_REQ
427 * o15.0.1.4:
428 * - Create an MGID by asking for a join with MGID = 0
429 *   providing P_Key, Q_Key, SL, FlowLabel, Tclass.
430 * o15.0.1.5:
431 * - Check the returned MGID is valid. (p 804)
432 * o15.0.1.6:
433 * - Create a new MCG with valid requested MGID.
434 * - Try to create a new MCG with invalid MGID : get back ERR_REQ_INVALID
435 * - Try again with MGID prefix = 0xA01B (maybe 0x1BA0 little or big ?)
436 * - Try to create again the already created group: ERR_REQ_INVALID
437 * o15.0.1.7 - implicitlly checked during the prev steps.
438 * o15.0.1.9
439 * - Create MCG with Invalid JoinState.FullMember != 1 : get ERR_REQ_INVALID
440 * o15.0.1.10 - can't check on a single client .
441 * o15.0.1.11:
442 * - Try to join into a MGID that exists with JoinState=SendOnlyMember -
443 *   see that it updates JoinState. What is the routing change?
444 * - We can not check simple join since we have only one tester (for now)
445 * o15.0.1.12:
446 * - The last join should have a special treatment in the SA (sender only)
447 *   but what is it ?
448 * o15.0.1.13:
449 * - Try joining with wrong rate - ERR_REQ_INVALID
450 * o15.0.1.14:
451 * - Try partial delete - actually updating the join state. check it.
452 * - Register by InformInfo flow to receive trap 67 on MCG delete.
453 * - Try full delete (JoinState and should be 0)
454 * - Wait for trap 67.
455 * - Try joining (not full mem) again to see the group was deleted.
456 *   (should fail - o15.0.1.13)
457 * o15.0.1.15:
458 * - Try deletion of the IPoIB MCG and get: ERR_REQ_INVALID
459 * o15.0.1.16:
460 * - Try GetTable with PortGUID wildcarded and get back some groups.
461 ***********************************************************************/
462
463/* The following macro can be used only within the osmt_run_mcast_flow() function */
464#define IS_IPOIB_MGID(p_mgid) \
465           ( !memcmp(&osm_ipoib_good_mgid,    (p_mgid), sizeof(osm_ipoib_good_mgid)) || \
466             !memcmp(&osm_ts_ipoib_good_mgid, (p_mgid), sizeof(osm_ts_ipoib_good_mgid)) )
467
468ib_api_status_t osmt_run_mcast_flow(IN osmtest_t * const p_osmt)
469{
470	char gid_str[INET6_ADDRSTRLEN];
471	char gid_str2[INET6_ADDRSTRLEN];
472	ib_api_status_t status;
473	ib_member_rec_t mc_req_rec;
474	ib_member_rec_t *p_mc_res;
475	ib_sa_mad_t res_sa_mad;
476	uint64_t comp_mask = 0;
477	ib_net64_t remote_port_guid = 0x0;
478	cl_qmap_t *p_mgrp_mlid_tbl;
479	osmtest_mgrp_t *p_mgrp;
480	ib_gid_t special_mgid, tmp_mgid, proxy_mgid;
481	ib_net16_t invalid_mlid = 0x0;
482	ib_net16_t max_mlid = cl_hton16(0xFFFE), tmp_mlid;
483	boolean_t ReachedMlidLimit = FALSE;
484	int start_cnt = 0, cnt, middle_cnt = 0, end_cnt = 0;
485	int start_ipoib_cnt = 0, end_ipoib_cnt = 0;
486	int mcg_outside_test_cnt = 0, fail_to_delete_mcg = 0;
487	osmtest_req_context_t context;
488	ib_node_record_t *p_rec;
489	uint32_t num_recs = 0, i;
490	uint8_t mtu_phys = 0, rate_phys = 0;
491	cl_map_t test_created_mlids;	/* List of all mlids created in this test */
492	ib_member_rec_t *p_recvd_rec;
493	boolean_t got_error = FALSE;
494
495	static ib_gid_t good_mgid = {
496		{
497		 0xFF, 0x12, 0xA0, 0x1C,
498		 0xFE, 0x80, 0x00, 0x00,
499		 0x00, 0x00, 0x00, 0x00,
500		 0x12, 0x34, 0x56, 0x78}
501	};
502	static ib_gid_t osm_ipoib_mgid = {
503		{
504		 0xff,		/* multicast field */
505		 0x12,		/* scope */
506		 0x40, 0x1b,	/* IPv4 signature */
507		 0xff, 0xff,	/* 16 bits of P_Key (to be filled in) */
508		 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* 48 bits of zeros */
509		 0xff, 0xff, 0xff, 0xee,	/* 32 bit IPv4 broadcast address */
510		 },
511	};
512	static ib_gid_t osm_ts_ipoib_good_mgid = {
513		{
514		 0xff,		/* multicast field */
515		 0x12,		/* non-permanent bit,scope */
516		 0x40, 0x1b,	/* IPv4 signature */
517		 0xff, 0xff,	/* 16 bits of P_Key (to be filled in) */
518		 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* 48 bits of zeros */
519		 0x00, 0x00, 0x00, 0x01,	/* 32 bit IPv4 broadcast address */
520		 },
521	};
522	static ib_gid_t osm_ipoib_good_mgid = {
523		{
524		 0xff,		/* multicast field */
525		 0x12,		/* non-permanent bit,scope */
526		 0x40, 0x1b,	/* IPv4 signature */
527		 0xff, 0xff,	/* 16 bits of P_Key (to be filled in) */
528		 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,	/* 48 bits of zeros */
529		 0xff, 0xff, 0xff, 0xff,	/* 32 bit IPv4 broadcast address */
530		 },
531	};
532	static ib_gid_t osm_link_local_mgid = {
533		{
534		 0xFF, 0x02, 0x00, 0x00,
535		 0x00, 0x00, 0x00, 0x00,
536		 0x00, 0x00, 0x00, 0x00,
537		 0x00, 0x00, 0x00, 0x01},
538	};
539
540	OSM_LOG_ENTER(&p_osmt->log);
541
542	OSM_LOG(&p_osmt->log, OSM_LOG_INFO, "GetTable of all current MCGs...\n");
543	status = osmt_query_mcast(p_osmt);
544	if (status != IB_SUCCESS) {
545		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 2FF "
546			"GetTable of all records has failed!\n");
547		goto Exit;
548	}
549
550	/* Initialize the test_created_mgrps map */
551	cl_map_construct(&test_created_mlids);
552	cl_map_init(&test_created_mlids, 1000);
553
554	p_mgrp_mlid_tbl = &p_osmt->exp_subn.mgrp_mlid_tbl;
555	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
556
557	p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
558
559	/* Only when we are on single mode check flow - do the count comparison, otherwise skip */
560	if (p_osmt->opt.mmode == 1 || p_osmt->opt.mmode == 3) {
561		start_cnt = cl_qmap_count(p_mgrp_mlid_tbl);
562		OSM_LOG(&p_osmt->log, OSM_LOG_INFO, "(start): "
563			"Number of MC Records found in SA DB is %d\n",
564			start_cnt);
565	}
566
567	/* This flow is being added due to bug discovered using SilverStorm stack -
568	   The bug was initializing MCast with MTU & RATE min values that do
569	   not match the subnet capability, even though that OpenSM
570	   reponds with the correct value it does not store it in the MCG.
571	   We want the check a join request to already existing group (ipoib)
572	   without using MTU or RATE then getting response from OpenSM with
573	   the correct values then join again with them and get IB_SUCCESS
574	   all the way
575	 */
576
577	/* First validate IPoIB exist in the SA DB */
578	p_mgrp = (osmtest_mgrp_t *) cl_qmap_head(p_mgrp_mlid_tbl);
579	/* scan all available multicast groups in the DB and fill in the table */
580	while (p_mgrp != (osmtest_mgrp_t *) cl_qmap_end(p_mgrp_mlid_tbl)) {
581		/* search for ipoib mgid */
582		if (IS_IPOIB_MGID(&p_mgrp->mcmember_rec.mgid)) {
583			start_ipoib_cnt++;
584		} else {
585			OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
586				"Non-IPoIB MC Groups exist: mgid=%s\n",
587				inet_ntop(AF_INET6,
588					  p_mgrp->mcmember_rec.mgid.raw,
589					  gid_str, sizeof gid_str));
590			mcg_outside_test_cnt++;
591		}
592
593		p_mgrp = (osmtest_mgrp_t *) cl_qmap_next(&p_mgrp->map_item);
594	}
595
596	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
597		"Found %d non-IPoIB MC Groups\n", mcg_outside_test_cnt);
598
599	if (start_ipoib_cnt) {
600		/* o15-0.2.4 - Check a join request to already created MCG */
601		OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
602			"Found IPoIB MC Group, so we run SilverStorm Bug Flow...\n");
603		/* Try to join first like IPoIB of SilverStorm */
604		memcpy(&mc_req_rec.mgid, &osm_ipoib_good_mgid,
605		       sizeof(ib_gid_t));
606		/* Request Join */
607		ib_member_set_join_state(&mc_req_rec,
608					 IB_MC_REC_STATE_FULL_MEMBER);
609		comp_mask =
610		    IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID |
611		    IB_MCR_COMPMASK_JOIN_STATE;
612
613		status = osmt_send_mcast_request(p_osmt, 0xff,	/* User Defined query Set */
614						 &mc_req_rec,
615						 comp_mask, &res_sa_mad);
616
617		OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
618			"Joining an existing IPoIB multicast group\n");
619		OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
620			"Sent Join request with :\n\t\tport_gid=%s, mgid=%s\n"
621			"\t\tjoin state= 0x%x, response is : %s\n",
622			inet_ntop(AF_INET6, mc_req_rec.port_gid.raw,
623				  gid_str, sizeof gid_str),
624			inet_ntop(AF_INET6, mc_req_rec.mgid.raw,
625				  gid_str2, sizeof gid_str2),
626			(mc_req_rec.scope_state & 0x0F),
627			ib_get_err_str(status));
628		if (status != IB_SUCCESS) {
629			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02B3: "
630				"Failed joining existing IPoIB MCGroup - got %s\n",
631				ib_get_err_str(status));
632			goto Exit;
633		}
634		/* Check MTU & Rate Value and resend with SA suggested values */
635		p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
636
637		/* Prepare the mc_req_rec for the rest of the flow */
638		osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
639		/*
640		   We simulate the same situation as in SilverStorm - a response with the
641		   exact RATE & MTU as the SA responded with. Actually the query
642		   has included some more fields but we know that problem was
643		   genereated by the RATE
644		 */
645		OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
646			"Received attributes of MCG : \n\t\tMTU=0x%02X, RATE=0x%02X\n",
647			p_mc_res->mtu, p_mc_res->rate);
648
649		mc_req_rec.mtu = p_mc_res->mtu;
650		mc_req_rec.rate = p_mc_res->rate;
651		/* Set feasible mtu & rate that will allow check the
652		   exact statement of OpenSM */
653		mtu_phys = p_mc_res->mtu;
654		rate_phys = p_mc_res->rate;
655
656		memcpy(&mc_req_rec.mgid, &osm_ipoib_good_mgid,
657		       sizeof(ib_gid_t));
658		/* Request Join */
659		ib_member_set_join_state(&mc_req_rec,
660					 IB_MC_REC_STATE_FULL_MEMBER);
661		comp_mask =
662		    IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID |
663		    IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_MTU_SEL |
664		    IB_MCR_COMPMASK_MTU | IB_MCR_COMPMASK_RATE_SEL |
665		    IB_MCR_COMPMASK_RATE;
666
667		OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
668			"Sending attributes of MCG : \n\t\tMTU=0x%02X, RATE=0x%02X\n",
669			mc_req_rec.mtu, mc_req_rec.rate);
670		status = osmt_send_mcast_request(p_osmt, 0xff,	/* User Defined query */
671						 &mc_req_rec,
672						 comp_mask, &res_sa_mad);
673		OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
674			"Sent Join request using response values, response is : %s\n",
675			ib_get_err_str(status));
676		if (status != IB_SUCCESS) {
677			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02EF: "
678				"Query as Full Member of already existing "
679				"ipoib group gid %s has failed\n",
680				inet_ntop(AF_INET6, mc_req_rec.mgid.raw,
681					  gid_str, sizeof gid_str));
682			goto Exit;
683		}
684		/* We do not want to leave the MCG since its IPoIB */
685	}
686
687  /**************************************************************************/
688	/* Check Get with invalid mlid */
689
690	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
691		"Checking Get with invalid mlid...\n");
692	/* Request Get */
693	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_FULL_MEMBER);
694	mc_req_rec.mlid = invalid_mlid;
695	comp_mask = IB_MCR_COMPMASK_MLID;
696
697	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
698	status = osmt_send_mcast_request(p_osmt, 0xee,	/* User Defined query Get */
699					 &mc_req_rec, comp_mask, &res_sa_mad);
700	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
701
702	if (status == IB_SUCCESS) {
703		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 2E0 "
704			"SubnAdmGet with invalid mlid 0x%x succeeded\n",
705			cl_ntoh16(mc_req_rec.mlid));
706		status = IB_ERROR;
707		goto Exit;
708	}
709
710	/* Prepare the mc_req_rec for the rest of the flow */
711	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
712  /**************************************************************************/
713	/* Check Get with invalid port guid */
714
715	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
716		"Checking Get with invalid port guid (0x0) but valid interface ID : 0x%"
717		PRIx64 "...\n",
718		cl_ntoh64(mc_req_rec.port_gid.unicast.interface_id));
719
720	/* Request Get */
721	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_FULL_MEMBER);
722	memset(&mc_req_rec.port_gid.unicast.interface_id, 0,
723	       sizeof(ib_net64_t));
724	comp_mask = IB_MCR_COMPMASK_GID;
725
726	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
727	status = osmt_send_mcast_request(p_osmt, 0xee,	/* User Defined query Get */
728					 &mc_req_rec, comp_mask, &res_sa_mad);
729	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
730
731	if (status == IB_SUCCESS) {
732		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 2E4 "
733			"SubnAdmGet with invalid port guid succeeded\n");
734		status = IB_ERROR;
735		goto Exit;
736	}
737
738	/* Prepare the mc_req_rec for the rest of the flow */
739	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
740  /**************************************************************************/
741
742	/* o15.0.1.3:  */
743	/* - Request Join with insufficient comp_mask */
744
745	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
746		"Checking Join with insufficient comp mask qkey & pkey (o15.0.1.3)...\n");
747
748	/* no MGID */
749	memset(&mc_req_rec.mgid, 0, sizeof(ib_gid_t));
750	/* Request Join */
751	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_FULL_MEMBER);
752
753	comp_mask = IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID |
754	    /* IB_MCR_COMPMASK_QKEY |  */
755	    /* IB_MCR_COMPMASK_PKEY | intentionaly missed to raise the error */
756	    IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
757	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
758
759	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
760	status = osmt_send_mcast_request(p_osmt, 1,
761					 &mc_req_rec, comp_mask, &res_sa_mad);
762	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
763
764	if (status != IB_REMOTE_ERROR ||
765	    ((ib_net16_t) (res_sa_mad.status & IB_SMP_STATUS_MASK)) !=
766	    IB_SA_MAD_STATUS_INSUF_COMPS) {
767		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02EE: "
768			"Expectedd REMOTE ERROR IB_SA_MAD_STATUS_INSUF_COMPS got:%s/%s\n",
769			ib_get_err_str(status),
770			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
771		status = IB_ERROR;
772		goto Exit;
773	}
774
775	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
776		"Checking Join with insufficient comp mask - sl (15.0.1.3)...\n");
777
778	/* no MGID */
779	memset(&mc_req_rec.mgid, 0, sizeof(ib_gid_t));
780	/* Request Join */
781	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_FULL_MEMBER);
782
783	comp_mask =
784	    IB_MCR_COMPMASK_MGID |
785	    IB_MCR_COMPMASK_PORT_GID |
786	    IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY |
787	    /* IB_MCR_COMPMASK_SL |  */
788	    IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
789	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
790
791	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
792	status = osmt_send_mcast_request(p_osmt, 1,
793					 &mc_req_rec, comp_mask, &res_sa_mad);
794	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
795
796	if (status != IB_REMOTE_ERROR ||
797	    ((ib_net16_t) (res_sa_mad.status & IB_SMP_STATUS_MASK)) !=
798	    IB_SA_MAD_STATUS_INSUF_COMPS) {
799		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02ED: "
800			"Expectedd REMOTE ERROR IB_SA_MAD_STATUS_INSUF_COMPS got:%s/%s\n",
801			ib_get_err_str(status),
802			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
803		status = IB_ERROR;
804		goto Exit;
805	}
806
807	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
808	/* no MGID */
809	memset(&mc_req_rec.mgid, 0, sizeof(ib_gid_t));
810
811	mc_req_rec.mgid.raw[15] = 0x01;
812
813	p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
814
815	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
816		"Checking Join with insufficient comp mask - flow label (o15.0.1.3)...\n");
817
818	/* Request Join */
819	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_FULL_MEMBER);
820
821	comp_mask =
822	    IB_MCR_COMPMASK_MGID |
823	    IB_MCR_COMPMASK_PORT_GID |
824	    IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL |
825	    /* IB_MCR_COMPMASK_FLOW | intentionaly missed to raise the error */
826	    IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
827	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
828
829	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
830	status = osmt_send_mcast_request(p_osmt, 1,
831					 &mc_req_rec, comp_mask, &res_sa_mad);
832	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
833
834	if (status != IB_REMOTE_ERROR ||
835	    ((ib_net16_t) (res_sa_mad.status & IB_SMP_STATUS_MASK)) !=
836	    IB_SA_MAD_STATUS_INSUF_COMPS) {
837		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02EC: "
838			"Expected REMOTE ERROR IB_SA_MAD_STATUS_INSUF_COMPS got:%s/%s\n",
839			ib_get_err_str(status),
840			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
841		status = IB_ERROR;
842		goto Exit;
843	}
844
845	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
846
847	p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
848
849	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
850		"Checking Join with insufficient comp mask - tclass (o15.0.1.3)...\n");
851
852	/* Request Join */
853	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_FULL_MEMBER);
854
855	comp_mask =
856	    IB_MCR_COMPMASK_MGID |
857	    IB_MCR_COMPMASK_PORT_GID |
858	    IB_MCR_COMPMASK_QKEY |
859	    IB_MCR_COMPMASK_PKEY |
860	    IB_MCR_COMPMASK_SL |
861	    IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE |
862	    /* IB_MCR_COMPMASK_TCLASS |  Intentionally missed to raise an error */
863	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
864
865	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
866	status = osmt_send_mcast_request(p_osmt, 1,
867					 &mc_req_rec, comp_mask, &res_sa_mad);
868	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
869
870	if (status != IB_REMOTE_ERROR ||
871	    ((ib_net16_t) (res_sa_mad.status & IB_SMP_STATUS_MASK)) !=
872	    IB_SA_MAD_STATUS_INSUF_COMPS) {
873		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02EA: "
874			"Expected REMOTE ERROR IB_SA_MAD_STATUS_INSUF_COMPS got:%s/%s\n",
875			ib_get_err_str(status),
876			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
877		status = IB_ERROR;
878		goto Exit;
879	}
880
881	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
882
883	p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
884
885	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
886		"Checking Join with insufficient comp mask - tclass qkey (o15.0.1.3)...\n");
887
888	/* no MGID */
889	/* memset(&mc_req_rec.mgid, 0, sizeof(ib_gid_t)); */
890	/* Request Join */
891	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_FULL_MEMBER);
892
893	comp_mask = IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID |
894	    /* IB_MCR_COMPMASK_QKEY | intentionaly missed to raise the error */
895	    IB_MCR_COMPMASK_PKEY |
896	    IB_MCR_COMPMASK_SL |
897	    IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE |
898	    /* IB_MCR_COMPMASK_TCLASS |  intentionaly missed to raise the error */
899	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
900
901	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
902	status = osmt_send_mcast_request(p_osmt, 1,
903					 &mc_req_rec, comp_mask, &res_sa_mad);
904	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
905
906	if (status != IB_REMOTE_ERROR ||
907	    ((ib_net16_t) (res_sa_mad.status & IB_SMP_STATUS_MASK)) !=
908	    IB_SA_MAD_STATUS_INSUF_COMPS) {
909		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02E9: "
910			"Expected REMOTE ERROR IB_SA_MAD_STATUS_INSUF_COMPS got:%s/%s\n",
911			ib_get_err_str(status),
912			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
913		status = IB_ERROR;
914		goto Exit;
915	}
916
917	/* o15.0.1.8: */
918	/* - Request join with irrelevant RATE : get a ERR_INSUFFICIENT_COMPONENTS */
919	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
920		"Checking Join with unrealistic rate (o15.0.1.8)...\n");
921
922	/* impossible requested rate */
923	mc_req_rec.rate =
924	    IB_LINK_WIDTH_ACTIVE_12X | IB_PATH_SELECTOR_GREATER_THAN << 6;
925
926	comp_mask = IB_MCR_COMPMASK_GID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
927	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
928
929	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
930	status = osmt_send_mcast_request(p_osmt, 1,
931					 &mc_req_rec, comp_mask, &res_sa_mad);
932	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
933
934	if (status != IB_REMOTE_ERROR ||
935	    res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID) {
936		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0207: "
937			"Expected REMOTE ERROR IB_SA_MAD_STATUS_REQ_INVALID got:%s/%s\n",
938			ib_get_err_str(status),
939			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
940		status = IB_ERROR;
941		goto Exit;
942	}
943
944	/* Check Valid value which is unreasonable now */
945	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
946		"Checking Join with unrealistic rate 120GB (o15.0.1.8)...\n");
947
948	/* impossible requested rate */
949	mc_req_rec.rate =
950	    IB_PATH_RECORD_RATE_120_GBS | IB_PATH_SELECTOR_GREATER_THAN << 6;
951
952	comp_mask = IB_MCR_COMPMASK_GID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
953	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
954
955	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
956	status = osmt_send_mcast_request(p_osmt, 1,
957					 &mc_req_rec, comp_mask, &res_sa_mad);
958	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
959
960	if (status != IB_REMOTE_ERROR ||
961	    res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID) {
962		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0208: "
963			"Expected REMOTE ERROR IB_SA_MAD_STATUS_REQ_INVALID got:%s/%s\n",
964			ib_get_err_str(status),
965			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
966		status = IB_ERROR;
967		goto Exit;
968	}
969
970	/* Check Valid value which is unreasonable now */
971	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
972		"Checking Join with less than min rate 2.5GB (o15.0.1.8)...\n");
973
974	/* impossible requested rate */
975	mc_req_rec.rate =
976	    IB_PATH_RECORD_RATE_2_5_GBS | IB_PATH_SELECTOR_LESS_THAN << 6;
977
978	comp_mask = IB_MCR_COMPMASK_GID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
979	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
980
981	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
982	status = osmt_send_mcast_request(p_osmt, 1,
983					 &mc_req_rec, comp_mask, &res_sa_mad);
984	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
985
986	if (status != IB_REMOTE_ERROR ||
987	    res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID) {
988		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02AB: "
989			"Expected REMOTE ERROR IB_SA_MAD_STATUS_REQ_INVALID got:%s/%s\n",
990			ib_get_err_str(status),
991			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
992		status = IB_ERROR;
993		goto Exit;
994	}
995
996	/* Checking above max value of MTU which is impossible */
997	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
998		"Checking Join with unrealistic mtu : \n\t\tmore than 4096 -"
999		" max (o15.0.1.8)...\n");
1000
1001	/* impossible requested mtu */
1002	mc_req_rec.mtu = IB_MTU_LEN_4096 | IB_PATH_SELECTOR_GREATER_THAN << 6;
1003
1004	comp_mask = IB_MCR_COMPMASK_GID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
1005	    IB_MCR_COMPMASK_MTU_SEL | IB_MCR_COMPMASK_MTU;
1006
1007	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1008	status = osmt_send_mcast_request(p_osmt, 1,
1009					 &mc_req_rec, comp_mask, &res_sa_mad);
1010	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1011
1012	if (status != IB_REMOTE_ERROR ||
1013	    res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID) {
1014		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02AC: "
1015			"Expected REMOTE ERROR IB_SA_MAD_STATUS_REQ_INVALID got:%s/%s\n",
1016			ib_get_err_str(status),
1017			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad))
1018		    );
1019		status = IB_ERROR;
1020		goto Exit;
1021	}
1022
1023	/* Checking below min value of MTU which is impossible */
1024	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1025		"Checking Join with unrealistic mtu : \n\t\tless than 256 -"
1026		" min (o15.0.1.8)...\n");
1027
1028	/* impossible requested mtu */
1029	mc_req_rec.mtu = IB_MTU_LEN_256 | IB_PATH_SELECTOR_LESS_THAN << 6;
1030
1031	comp_mask = IB_MCR_COMPMASK_GID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
1032	    IB_MCR_COMPMASK_MTU_SEL | IB_MCR_COMPMASK_MTU;
1033
1034	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1035	status = osmt_send_mcast_request(p_osmt, 1,
1036					 &mc_req_rec, comp_mask, &res_sa_mad);
1037	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1038
1039	if (status != IB_REMOTE_ERROR ||
1040	    res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID) {
1041		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02AD: "
1042			"Expected REMOTE ERROR IB_SA_MAD_STATUS_REQ_INVALID got:%s/%s\n",
1043			ib_get_err_str(status),
1044			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1045		status = IB_ERROR;
1046		goto Exit;
1047	}
1048
1049	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1050		"Checking Join with unrealistic mtu (o15.0.1.8)...\n");
1051
1052	/* impossible requested mtu */
1053	mc_req_rec.mtu = 0x6 | IB_PATH_SELECTOR_GREATER_THAN << 6;
1054
1055	comp_mask = IB_MCR_COMPMASK_GID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
1056	    IB_MCR_COMPMASK_MTU_SEL | IB_MCR_COMPMASK_MTU;
1057
1058	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1059	status = osmt_send_mcast_request(p_osmt, 1,
1060					 &mc_req_rec, comp_mask, &res_sa_mad);
1061	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1062
1063	if (status != IB_REMOTE_ERROR ||
1064	    res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID) {
1065		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02AE: "
1066			"Expected REMOTE ERROR IB_SA_MAD_STATUS_REQ_INVALID got:%s/%s\n",
1067			ib_get_err_str(status),
1068			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1069		status = IB_ERROR;
1070		goto Exit;
1071	}
1072#if 0
1073	/* Currently PacketLifeTime isn't checked in opensm */
1074	/* Check PacketLifeTime as 0 */
1075	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1076		"Checking Create with unrealistic packet life value less than 0 (o15.0.1.8)...\n");
1077
1078	/* impossible requested packet life */
1079	mc_req_rec.pkt_life = 0 | IB_PATH_SELECTOR_LESS_THAN << 6;
1080
1081	comp_mask = IB_MCR_COMPMASK_GID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
1082	    IB_MCR_COMPMASK_LIFE | IB_MCR_COMPMASK_LIFE_SEL;
1083
1084	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1085	status = osmt_send_mcast_request(p_osmt, 1,
1086					 &mc_req_rec, comp_mask, &res_sa_mad);
1087	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1088
1089	if (status != IB_REMOTE_ERROR ||
1090	    res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID) {
1091		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02AF: "
1092			"Expected REMOTE ERROR IB_SA_MAD_STATUS_REQ_INVALID got:%s/%s\n",
1093			ib_get_err_str(status),
1094			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1095		status = IB_ERROR;
1096		goto Exit;
1097	}
1098#endif
1099
1100	/* o15.0.1.4:  */
1101	/* - Create an MGID by asking for a join with MGID = 0 */
1102	/*   providing P_Key, Q_Key, SL, FlowLabel, Tclass. */
1103
1104	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1105		"Checking Create given MGID=0 skip service level (o15.0.1.4)...\n");
1106
1107	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
1108
1109	p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
1110
1111	/* no MGID */
1112	memset(&mc_req_rec.mgid, 0, sizeof(ib_gid_t));
1113	/* Request Join */
1114	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_FULL_MEMBER);
1115
1116	comp_mask =
1117	    IB_MCR_COMPMASK_MGID |
1118	    IB_MCR_COMPMASK_PORT_GID |
1119	    IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY |
1120	    /* IB_MCR_COMPMASK_SL | Intentionally missed */
1121	    IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
1122	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
1123
1124	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1125	status = osmt_send_mcast_request(p_osmt, 1,
1126					 &mc_req_rec, comp_mask, &res_sa_mad);
1127	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1128
1129	if (status != IB_REMOTE_ERROR ||
1130	    ((ib_net16_t) (res_sa_mad.status & IB_SMP_STATUS_MASK)) !=
1131	    IB_SA_MAD_STATUS_INSUF_COMPS) {
1132		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02A8: "
1133			"Expected REMOTE ERROR IB_SA_MAD_STATUS_INSUF_COMPS got:%s/%s\n",
1134			ib_get_err_str(status),
1135			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1136		status = IB_ERROR;
1137		goto Exit;
1138	}
1139
1140	/* Check that no same MCG in the SMDB */
1141	status = osmt_query_mcast(p_osmt);
1142
1143	if (status != IB_SUCCESS) {
1144		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02AA: "
1145			"Could not get all MC Records in subnet, got:%s/%s\n",
1146			ib_get_err_str(status),
1147			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1148		goto Exit;
1149	}
1150
1151	/* Only when we are on single mode check flow - do the count comparison, otherwise skip */
1152	if (p_osmt->opt.mmode == 1 || p_osmt->opt.mmode == 3) {
1153		middle_cnt = cl_qmap_count(&p_osmt->exp_subn.mgrp_mlid_tbl);
1154		OSM_LOG(&p_osmt->log, OSM_LOG_INFO, "(post false create): "
1155			"Number of MC Records found in SA DB is %d\n",
1156			middle_cnt);
1157		if (middle_cnt != start_cnt) {
1158			OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1159				"Got different number of records stored in SA DB (before any creation)\n"
1160				"Instead of %d got %d\n", start_cnt,
1161				middle_cnt);
1162		}
1163	}
1164
1165	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1166		"Checking Create given MGID=0 skip Qkey and Pkey (o15.0.1.4)...\n");
1167
1168	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
1169
1170	p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
1171
1172	/* no MGID */
1173	memset(&mc_req_rec.mgid, 0, sizeof(ib_gid_t));
1174	/* Request Join */
1175	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_FULL_MEMBER);
1176
1177	comp_mask = IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID |
1178	    /* IB_MCR_COMPMASK_QKEY | */
1179	    /* IB_MCR_COMPMASK_PKEY | Intentionally missed */
1180	    IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
1181	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
1182
1183	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1184	status = osmt_send_mcast_request(p_osmt, 1,
1185					 &mc_req_rec, comp_mask, &res_sa_mad);
1186	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1187
1188	if (status != IB_REMOTE_ERROR ||
1189	    ((ib_net16_t) (res_sa_mad.status & IB_SMP_STATUS_MASK)) !=
1190	    IB_SA_MAD_STATUS_INSUF_COMPS) {
1191		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02A7: "
1192			"Expected REMOTE ERROR IB_SA_MAD_STATUS_INSUF_COMPS got:%s/%s\n",
1193			ib_get_err_str(status),
1194			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1195		status = IB_ERROR;
1196		goto Exit;
1197	}
1198
1199	/* Bad Query o15.0.1.4 */
1200
1201	status = osmt_query_mcast(p_osmt);
1202
1203	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1204		"Checking Create given MGID=0 skip TClass (o15.0.1.4)...\n");
1205
1206	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
1207
1208	p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
1209
1210	/* no MGID */
1211	memset(&mc_req_rec.mgid, 0, sizeof(ib_gid_t));
1212	/* Request Join */
1213	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_FULL_MEMBER);
1214
1215	comp_mask =
1216	    IB_MCR_COMPMASK_MGID |
1217	    IB_MCR_COMPMASK_PORT_GID |
1218	    IB_MCR_COMPMASK_QKEY |
1219	    IB_MCR_COMPMASK_PKEY |
1220	    IB_MCR_COMPMASK_SL |
1221	    IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE |
1222	    /* IB_MCR_COMPMASK_TCLASS |  Intentionally missed */
1223	    /* all above are required */
1224	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
1225
1226	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1227	status = osmt_send_mcast_request(p_osmt, 1,
1228					 &mc_req_rec, comp_mask, &res_sa_mad);
1229	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1230
1231	if (status != IB_REMOTE_ERROR ||
1232	    ((ib_net16_t) (res_sa_mad.status & IB_SMP_STATUS_MASK)) !=
1233	    IB_SA_MAD_STATUS_INSUF_COMPS) {
1234		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02A6: "
1235			"Expected REMOTE ERROR IB_SA_MAD_STATUS_INSUF_COMPS got:%s/%s\n",
1236			ib_get_err_str(status),
1237			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1238		status = IB_ERROR;
1239		goto Exit;
1240	}
1241
1242	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1243		"Checking Create given MGID=0 valid Set several options :\n\t\t"
1244		"First above min RATE, Second less than max RATE\n\t\t"
1245		"Third above min MTU, Second less than max MTU\n\t\t"
1246		"Fifth exact MTU & RATE feasible, Sixth exact RATE feasible\n\t\t"
1247		"Seventh exact MTU feasible (o15.0.1.4)...\n");
1248
1249	/* Good Flow - mgid is 0 while giving all required fields for join : P_Key, Q_Key, SL, FlowLabel, Tclass */
1250
1251	mc_req_rec.rate =
1252	    IB_LINK_WIDTH_ACTIVE_1X | IB_PATH_SELECTOR_GREATER_THAN << 6;
1253
1254	comp_mask = IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
1255	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
1256
1257	status = osmt_send_mcast_request(p_osmt, 1,
1258					 &mc_req_rec, comp_mask, &res_sa_mad);
1259	if (status != IB_SUCCESS) {
1260		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02A5: "
1261			"Failed to create MCG for MGID=0 with higher than minimum RATE - got %s/%s\n",
1262			ib_get_err_str(status),
1263			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1264		goto Exit;
1265	}
1266
1267	/* Save the mlid created in test_created_mlids map */
1268	p_recvd_rec =
1269	    (ib_member_rec_t *) ib_sa_mad_get_payload_ptr(&res_sa_mad);
1270	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "created MGID:%s MLID:0x%04X\n",
1271		inet_ntop(AF_INET6, p_recvd_rec->mgid.raw, gid_str,
1272			  sizeof gid_str), cl_ntoh16(p_recvd_rec->mlid));
1273	cl_map_insert(&test_created_mlids, cl_ntoh16(p_recvd_rec->mlid),
1274		      p_recvd_rec);
1275
1276	/* Good Flow - mgid is 0 while giving all required fields for join : P_Key, Q_Key, SL, FlowLabel, Tclass */
1277
1278	mc_req_rec.rate =
1279	    IB_LINK_WIDTH_ACTIVE_12X | IB_PATH_SELECTOR_LESS_THAN << 6;
1280
1281	comp_mask = IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
1282	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
1283
1284	status = osmt_send_mcast_request(p_osmt, 1,
1285					 &mc_req_rec, comp_mask, &res_sa_mad);
1286	if (status != IB_SUCCESS) {
1287		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0211: "
1288			"Failed to create MCG for MGID=0 with less than highest RATE - got %s/%s\n",
1289			ib_get_err_str(status),
1290			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1291		goto Exit;
1292	}
1293
1294	/* Save the mlid created in test_created_mlids map */
1295	p_recvd_rec =
1296	    (ib_member_rec_t *) ib_sa_mad_get_payload_ptr(&res_sa_mad);
1297	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Created MGID:%s MLID:0x%04X\n",
1298		inet_ntop(AF_INET6, p_recvd_rec->mgid.raw, gid_str,
1299			  sizeof gid_str), cl_ntoh16(p_recvd_rec->mlid));
1300	cl_map_insert(&test_created_mlids, cl_ntoh16(p_recvd_rec->mlid),
1301		      p_recvd_rec);
1302
1303	/* Good Flow - mgid is 0 while giving all required fields for join : P_Key, Q_Key, SL, FlowLabel, Tclass */
1304
1305	mc_req_rec.mtu = IB_MTU_LEN_4096 | IB_PATH_SELECTOR_LESS_THAN << 6;
1306
1307	comp_mask = IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
1308	    IB_MCR_COMPMASK_MTU_SEL | IB_MCR_COMPMASK_MTU;
1309
1310	status = osmt_send_mcast_request(p_osmt, 1,
1311					 &mc_req_rec, comp_mask, &res_sa_mad);
1312	if (status != IB_SUCCESS) {
1313		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0238: "
1314			"Failed to create MCG for MGID=0 with less than highest MTU - got %s/%s\n",
1315			ib_get_err_str(status),
1316			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1317		goto Exit;
1318	}
1319
1320	/* Save the mlid created in test_created_mlids map */
1321	p_recvd_rec =
1322	    (ib_member_rec_t *) ib_sa_mad_get_payload_ptr(&res_sa_mad);
1323	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Created MGID:%s MLID:0x%04X\n",
1324		inet_ntop(AF_INET6, p_recvd_rec->mgid.raw, gid_str,
1325			  sizeof gid_str), cl_ntoh16(p_recvd_rec->mlid));
1326	cl_map_insert(&test_created_mlids, cl_ntoh16(p_recvd_rec->mlid),
1327		      p_recvd_rec);
1328
1329	/* Good Flow - mgid is 0 while giving all required fields for join : P_Key, Q_Key, SL, FlowLabel, Tclass */
1330	mc_req_rec.mtu = IB_MTU_LEN_256 | IB_PATH_SELECTOR_GREATER_THAN << 6;
1331
1332	comp_mask = IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
1333	    IB_MCR_COMPMASK_MTU_SEL | IB_MCR_COMPMASK_MTU;
1334
1335	status = osmt_send_mcast_request(p_osmt, 1,
1336					 &mc_req_rec, comp_mask, &res_sa_mad);
1337	if (status != IB_SUCCESS) {
1338		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0239: "
1339			"Failed to create MCG for MGID=0 with higher than lowest MTU - got %s/%s\n",
1340			ib_get_err_str(status),
1341			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1342		goto Exit;
1343	}
1344
1345	/* Save the mlid created in test_created_mlids map */
1346	p_recvd_rec =
1347	    (ib_member_rec_t *) ib_sa_mad_get_payload_ptr(&res_sa_mad);
1348	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Created MGID:%s MLID:0x%04X\n",
1349		inet_ntop(AF_INET6, p_recvd_rec->mgid.raw, gid_str,
1350			  sizeof gid_str), cl_ntoh16(p_recvd_rec->mlid));
1351	cl_map_insert(&test_created_mlids, cl_ntoh16(p_recvd_rec->mlid),
1352		      p_recvd_rec);
1353
1354	/* Good Flow - mgid is 0 while giving all required fields for join : P_Key, Q_Key, SL, FlowLabel, Tclass */
1355	/* Using Exact feasible MTU & RATE */
1356
1357	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
1358		"Using Exact feasible MTU & RATE: "
1359		"MTU = 0x%02X, RATE = 0x%02X\n", mtu_phys, rate_phys);
1360
1361	mc_req_rec.mtu = mtu_phys;
1362	mc_req_rec.rate = rate_phys;
1363
1364	comp_mask = IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
1365	    IB_MCR_COMPMASK_MTU_SEL |
1366	    IB_MCR_COMPMASK_MTU |
1367	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
1368
1369	status = osmt_send_mcast_request(p_osmt, 1,
1370					 &mc_req_rec, comp_mask, &res_sa_mad);
1371
1372	if (status != IB_SUCCESS) {
1373		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0240: "
1374			"Failed to create MCG for MGID=0 with exact MTU & RATE - got %s/%s\n",
1375			ib_get_err_str(status),
1376			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1377		goto Exit;
1378	}
1379
1380	/* Save the mlid created in test_created_mlids map */
1381	p_recvd_rec =
1382	    (ib_member_rec_t *) ib_sa_mad_get_payload_ptr(&res_sa_mad);
1383	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Created MGID:%s MLID:0x%04X\n",
1384		inet_ntop(AF_INET6, p_recvd_rec->mgid.raw, gid_str,
1385			  sizeof gid_str), cl_ntoh16(p_recvd_rec->mlid));
1386	cl_map_insert(&test_created_mlids, cl_ntoh16(p_recvd_rec->mlid),
1387		      p_recvd_rec);
1388
1389	/* Good Flow - mgid is 0 while giving all required fields for join : P_Key, Q_Key, SL, FlowLabel, Tclass */
1390	/* Using Exact feasible RATE */
1391
1392	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
1393		"Using Exact feasible RATE: 0x%02X\n", rate_phys);
1394
1395	mc_req_rec.rate = rate_phys;
1396
1397	comp_mask = IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
1398	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
1399
1400	status = osmt_send_mcast_request(p_osmt, 1,
1401					 &mc_req_rec, comp_mask, &res_sa_mad);
1402	if (status != IB_SUCCESS) {
1403		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0241: "
1404			"Failed to create MCG for MGID=0 with exact RATE - got %s/%s\n",
1405			ib_get_err_str(status),
1406			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1407		goto Exit;
1408	}
1409
1410	/* Save the mlid created in test_created_mlids map */
1411	p_recvd_rec =
1412	    (ib_member_rec_t *) ib_sa_mad_get_payload_ptr(&res_sa_mad);
1413	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Created MGID:%s MLID:0x%04X\n",
1414		inet_ntop(AF_INET6, p_recvd_rec->mgid.raw, gid_str,
1415			  sizeof gid_str), cl_ntoh16(p_recvd_rec->mlid));
1416	cl_map_insert(&test_created_mlids, cl_ntoh16(p_recvd_rec->mlid),
1417		      p_recvd_rec);
1418
1419	/* Good Flow - mgid is 0 while giving all required fields for join : P_Key, Q_Key, SL, FlowLabel, Tclass */
1420	/* Using Exact feasible MTU */
1421
1422	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
1423		"Using Exact feasible MTU: 0x%02X\n", mtu_phys);
1424
1425	mc_req_rec.mtu = mtu_phys;
1426
1427	comp_mask = IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
1428	    IB_MCR_COMPMASK_MTU_SEL | IB_MCR_COMPMASK_MTU;
1429
1430	status = osmt_send_mcast_request(p_osmt, 1,
1431					 &mc_req_rec, comp_mask, &res_sa_mad);
1432	if (status != IB_SUCCESS) {
1433		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0242: "
1434			"Failed to create MCG for MGID=0 with exact MTU - got %s/%s\n",
1435			ib_get_err_str(status),
1436			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1437		goto Exit;
1438	}
1439
1440	/* Save the mlid created in test_created_mlids map */
1441	p_recvd_rec =
1442	    (ib_member_rec_t *) ib_sa_mad_get_payload_ptr(&res_sa_mad);
1443	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Created MGID:%s MLID:0x%04X\n",
1444		inet_ntop(AF_INET6, p_recvd_rec->mgid.raw, gid_str,
1445			  sizeof gid_str), cl_ntoh16(p_recvd_rec->mlid));
1446	cl_map_insert(&test_created_mlids, cl_ntoh16(p_recvd_rec->mlid),
1447		      p_recvd_rec);
1448
1449	/* o15.0.1.5: */
1450	/* - Check the returned MGID is valid. (p 804) */
1451	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1452		"Validating resulting MGID (o15.0.1.5)...\n");
1453	/* prefix 0xFF1 Scope 0xA01B */
1454	/* Since we did not directly specified SCOPE in comp mask
1455	   we should get the comp mask that is link-local scope */
1456	if ((p_mc_res->mgid.multicast.header[0] != 0xFF) ||
1457	    (p_mc_res->mgid.multicast.header[1] != 0x12) ||
1458	    (p_mc_res->mgid.multicast.raw_group_id[0] != 0xA0) ||
1459	    (p_mc_res->mgid.multicast.raw_group_id[1] != 0x1B)) {
1460		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0209: "
1461			"Validating MGID failed. MGID:%s\n",
1462			inet_ntop(AF_INET6, p_mc_res->mgid.raw, gid_str,
1463				  sizeof gid_str));
1464		status = IB_ERROR;
1465		goto Exit;
1466	}
1467
1468	/* Good Flow - mgid is 0 while giving all required fields for join : P_Key, Q_Key, SL, FlowLabel, Tclass */
1469	/* Using feasible GREATER_THAN 0 packet lifitime */
1470	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1471		"Checking Create given MGID=0 (o15.0.1.4)...\n");
1472
1473	status = osmt_query_mcast(p_osmt);
1474
1475	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
1476
1477	p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
1478
1479	/* no MGID */
1480	memset(&mc_req_rec.mgid, 0, sizeof(ib_gid_t));
1481	/* Request Join */
1482	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_FULL_MEMBER);
1483
1484	mc_req_rec.pkt_life = 0 | IB_PATH_SELECTOR_GREATER_THAN << 6;
1485
1486	comp_mask = IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
1487	    IB_MCR_COMPMASK_LIFE | IB_MCR_COMPMASK_LIFE_SEL;
1488
1489	status = osmt_send_mcast_request(p_osmt, 1,
1490					 &mc_req_rec, comp_mask, &res_sa_mad);
1491	if (status != IB_SUCCESS) {
1492		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0210: "
1493			"Failed to create MCG for MGID=0 - got %s/%s\n",
1494			ib_get_err_str(status),
1495			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1496		goto Exit;
1497	}
1498
1499	/* Save the mlid created in test_created_mlids map */
1500	p_recvd_rec =
1501	    (ib_member_rec_t *) ib_sa_mad_get_payload_ptr(&res_sa_mad);
1502	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Created MGID:%s MLID:0x%04X\n",
1503		inet_ntop(AF_INET6, p_recvd_rec->mgid.raw, gid_str,
1504			  sizeof gid_str), cl_ntoh16(p_recvd_rec->mlid));
1505	cl_map_insert(&test_created_mlids, cl_ntoh16(p_recvd_rec->mlid),
1506		      p_recvd_rec);
1507
1508	/* o15.0.1.6: */
1509	/* - Create a new MCG with valid requested MGID. */
1510	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
1511	mc_req_rec.mgid = good_mgid;
1512
1513	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1514		"Checking Create given valid MGID=%s (o15.0.1.6)...\n",
1515		inet_ntop(AF_INET6, mc_req_rec.mgid.raw, gid_str,
1516			  sizeof gid_str));
1517
1518	/* Before creation, need to check that this group doesn't exist */
1519	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1520		"Verifying that MCGroup with this MGID doesn't exist by trying to Join it (o15.0.1.13)...\n");
1521
1522	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_NON_MEMBER);
1523
1524	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1525	status = osmt_send_mcast_request(p_osmt, 1,	/* join */
1526					 &mc_req_rec, comp_mask, &res_sa_mad);
1527	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1528
1529	if ((status != IB_REMOTE_ERROR) ||
1530	    (res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID)) {
1531		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0301: "
1532			"Tried joining group that shouldn't have existed - got %s/%s\n",
1533			ib_get_err_str(status),
1534			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1535		status = IB_ERROR;
1536		goto Exit;
1537	}
1538
1539	/* Set State to full member to allow group creation */
1540	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_FULL_MEMBER);
1541
1542	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1543		"Now creating group with given valid MGID=%s (o15.0.1.6)...\n",
1544		inet_ntop(AF_INET6, mc_req_rec.mgid.raw, gid_str,
1545			  sizeof gid_str));
1546
1547	status = osmt_send_mcast_request(p_osmt, 1,
1548					 &mc_req_rec, comp_mask, &res_sa_mad);
1549	if (status != IB_SUCCESS) {
1550		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0211: "
1551			"Failed to create MCG for MGID=%s (o15.0.1.6) - got %s/%s\n",
1552			inet_ntop(AF_INET6, good_mgid.raw, gid_str,
1553				  sizeof gid_str), ib_get_err_str(status),
1554			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1555		goto Exit;
1556	}
1557
1558	/* Save the mlid created in test_created_mlids map */
1559	p_recvd_rec =
1560	    (ib_member_rec_t *) ib_sa_mad_get_payload_ptr(&res_sa_mad);
1561	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Created MGID:%s MLID:0x%04X\n",
1562		inet_ntop(AF_INET6, p_recvd_rec->mgid.raw, gid_str,
1563			  sizeof gid_str), cl_ntoh16(p_recvd_rec->mlid));
1564	cl_map_insert(&test_created_mlids, cl_ntoh16(p_recvd_rec->mlid),
1565		      p_recvd_rec);
1566
1567	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1568		"Validating resulting MGID (o15.0.1.6)...\n");
1569	/* prefix 0xFF1 Scope 0xA01B */
1570	if ((p_mc_res->mgid.multicast.header[0] != 0xFF) || (p_mc_res->mgid.multicast.header[1] != 0x12) ||	/* HACK hardcoded scope = 0x02 */
1571	    (p_mc_res->mgid.multicast.raw_group_id[0] != 0xA0) ||
1572	    (p_mc_res->mgid.multicast.raw_group_id[1] != 0x1C)) {
1573		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0212: "
1574			"Validating MGID failed. MGID:%s\n",
1575			inet_ntop(AF_INET6, p_mc_res->mgid.raw, gid_str,
1576				  sizeof gid_str));
1577		status = IB_ERROR;
1578		goto Exit;
1579	}
1580
1581	/* - Try to create a new MCG with invalid MGID : get back ERR_REQ_INVALID */
1582	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1583		"Checking BAD MGID=0xFA..... (o15.0.1.6)...\n");
1584
1585	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1586
1587	mc_req_rec.mgid.raw[0] = 0xFA;
1588	status = osmt_send_mcast_request(p_osmt, 1,
1589					 &mc_req_rec, comp_mask, &res_sa_mad);
1590	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1591
1592	if ((status != IB_REMOTE_ERROR) ||
1593	    (res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID)) {
1594		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0213: "
1595			"Failed to recognize MGID error for MGID=0xFA - got %s/%s\n",
1596			ib_get_err_str(status),
1597			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1598		status = IB_ERROR;
1599		goto Exit;
1600	}
1601
1602	/* - Try again with MGID prefix = 0xA01B (maybe 0x1BA0 little or big ?) */
1603	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1604		"Checking BAD MGID=0xFF12A01B..... with link-local scope (o15.0.1.6)...\n");
1605
1606	mc_req_rec.mgid.raw[0] = 0xFF;
1607	mc_req_rec.mgid.raw[3] = 0x1B;
1608	comp_mask = comp_mask | IB_MCR_COMPMASK_SCOPE;
1609	mc_req_rec.scope_state = mc_req_rec.scope_state & 0x2F;	/* local scope */
1610	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1611	status = osmt_send_mcast_request(p_osmt, 1,
1612					 &mc_req_rec, comp_mask, &res_sa_mad);
1613	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1614
1615	if ((status != IB_REMOTE_ERROR) ||
1616	    (res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID)) {
1617		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0214: "
1618			"Failed to recognize MGID error for A01B with link-local bit (status %s) (rem status %s)\n",
1619			ib_get_err_str(status),
1620			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1621		status = IB_ERROR;
1622		goto Exit;
1623	}
1624
1625	/* Change the mgid prefix - get back ERR_REQ_INVALID */
1626
1627	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1628		"Checking BAD MGID PREFIX=0xEF... (o15.0.1.6)...\n");
1629
1630	mc_req_rec.mgid = good_mgid;
1631
1632	mc_req_rec.mgid.raw[0] = 0xEF;
1633
1634	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1635	status = osmt_send_mcast_request(p_osmt, 1,
1636					 &mc_req_rec, comp_mask, &res_sa_mad);
1637	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1638
1639	if ((status != IB_REMOTE_ERROR) ||
1640	    (res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID)) {
1641		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0215: "
1642			"Failed to recognize MGID PREFIX error for MGID=0xEF - got %s/%s\n",
1643			ib_get_err_str(status),
1644			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1645		status = IB_ERROR;
1646		goto Exit;
1647	}
1648
1649	/* Change the scope to reserved - get back VALID REQ */
1650
1651	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1652		"Checking local scope with full member \n\t\tand valid mgid %s"
1653		"  ... (o15.0.1.6)...\n",
1654		inet_ntop(AF_INET6, mc_req_rec.mgid.raw, gid_str,
1655			  sizeof gid_str));
1656
1657	mc_req_rec.mgid = good_mgid;
1658
1659	mc_req_rec.mgid.raw[1] = 0x1F;
1660
1661	status = osmt_send_mcast_request(p_osmt, 1,
1662					 &mc_req_rec, comp_mask, &res_sa_mad);
1663	if (status != IB_SUCCESS) {
1664		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0216: "
1665			"Failed to create MCG for MGID=%s - got %s/%s\n",
1666			inet_ntop(AF_INET6, good_mgid.raw, gid_str,
1667				  sizeof gid_str), ib_get_err_str(status),
1668			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1669		goto Exit;
1670	}
1671
1672	/* Save the mlid created in test_created_mlids map */
1673	p_recvd_rec =
1674	    (ib_member_rec_t *) ib_sa_mad_get_payload_ptr(&res_sa_mad);
1675	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Created MGID:%s MLID:0x%04X\n",
1676		inet_ntop(AF_INET6, p_recvd_rec->mgid.raw, gid_str,
1677			  sizeof gid_str), cl_ntoh16(p_recvd_rec->mlid));
1678	cl_map_insert(&test_created_mlids, cl_ntoh16(p_recvd_rec->mlid),
1679		      p_recvd_rec);
1680
1681	/* Change the flags to invalid value 0x2 - get back INVALID REQ */
1682
1683	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1684		"Checking invalid flags=0xFF 22  ... (o15.0.1.6)...\n");
1685
1686	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1687
1688	mc_req_rec.mgid = good_mgid;
1689
1690	mc_req_rec.mgid.raw[1] = 0x22;
1691
1692	status = osmt_send_mcast_request(p_osmt, 1,
1693					 &mc_req_rec, comp_mask, &res_sa_mad);
1694
1695	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1696
1697	if ((status != IB_REMOTE_ERROR) ||
1698	    (res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID)) {
1699		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0217: "
1700			"Failed to recognize create with invalid flags value 0x2 - got %s/%s\n",
1701			ib_get_err_str(status),
1702			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1703		status = IB_ERROR;
1704		goto Exit;
1705	}
1706
1707	/* Change the MGID to link local MGID  - get back VALID REQ */
1708
1709	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1710		"Checking link local MGID 0xFF02:0:0:0:0:0:0:1 (o15.0.1.6)...\n");
1711
1712	mc_req_rec.mgid = osm_link_local_mgid;
1713
1714	status = osmt_send_mcast_request(p_osmt, 1,
1715					 &mc_req_rec, comp_mask, &res_sa_mad);
1716	if (status != IB_SUCCESS) {
1717		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0218: "
1718			"Failed to create MCG for MGID=0xFF02:0:0:0:0:0:0:1 - got %s/%s\n",
1719			ib_get_err_str(status),
1720			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1721		goto Exit;
1722	}
1723
1724	/* Save the mlid created in test_created_mlids map */
1725	p_recvd_rec =
1726	    (ib_member_rec_t *) ib_sa_mad_get_payload_ptr(&res_sa_mad);
1727	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Created MGID:%s MLID:0x%04X\n",
1728		inet_ntop(AF_INET6, p_recvd_rec->mgid.raw, gid_str,
1729			  sizeof gid_str), cl_ntoh16(p_recvd_rec->mlid));
1730	cl_map_insert(&test_created_mlids, cl_ntoh16(p_recvd_rec->mlid),
1731		      p_recvd_rec);
1732
1733	/* o15.0.1.7 - implicitlly checked during the prev steps. */
1734	/* o15.0.1.8 - implicitlly checked during the prev steps. */
1735
1736	/* o15.0.1.9 */
1737	/* - Create MCG with Invalid JoinState.FullMember != 1 : get ERR_REQ_INVALID */
1738
1739	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1740		"Checking new MGID with invalid join state (o15.0.1.9)...\n");
1741
1742	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1743
1744	mc_req_rec.mgid = good_mgid;
1745	mc_req_rec.mgid.raw[12] = 0xFF;
1746	mc_req_rec.scope_state = 0x22;	/* link-local scope, non-member state */
1747
1748	status = osmt_send_mcast_request(p_osmt, 1,
1749					 &mc_req_rec, comp_mask, &res_sa_mad);
1750	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1751
1752	if ((status != IB_REMOTE_ERROR) ||
1753	    (res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID)) {
1754		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0219: "
1755			"Failed to recognize create with JoinState != FullMember - got %s/%s\n",
1756			ib_get_err_str(status),
1757			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1758		status = IB_ERROR;
1759		goto Exit;
1760	}
1761
1762	/* Lets try a valid join scope state */
1763	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1764		"Checking new MGID with valid join state (o15.0.1.9)...\n");
1765
1766	mc_req_rec.mgid = good_mgid;
1767	mc_req_rec.scope_state = 0x23;	/* link-local scope, non member and full member */
1768
1769	status = osmt_send_mcast_request(p_osmt, 1,
1770					 &mc_req_rec, comp_mask, &res_sa_mad);
1771
1772	if (status != IB_SUCCESS) {
1773		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0220: "
1774			"Failed to create MCG with valid join state 0x3 - got %s/%s\n",
1775			ib_get_err_str(status),
1776			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1777		goto Exit;
1778	}
1779
1780	/* Save the mlid created in test_created_mlids map */
1781	p_recvd_rec =
1782	    (ib_member_rec_t *) ib_sa_mad_get_payload_ptr(&res_sa_mad);
1783	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Created MGID:%s MLID:0x%04X\n",
1784		inet_ntop(AF_INET6, p_recvd_rec->mgid.raw, gid_str,
1785			  sizeof gid_str), cl_ntoh16(p_recvd_rec->mlid));
1786	cl_map_insert(&test_created_mlids, cl_ntoh16(p_recvd_rec->mlid),
1787		      p_recvd_rec);
1788
1789	/* Lets try another invalid join scope state */
1790	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1791		"Checking new MGID with invalid join state (o15.0.1.9)...\n");
1792
1793	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1794
1795	/* We have created a new MCG so now we need different mgid when cresting group otherwise it will be counted as join request . */
1796	mc_req_rec.mgid = good_mgid;
1797	mc_req_rec.mgid.raw[12] = 0xFC;
1798
1799	mc_req_rec.scope_state = 0x24;	/* link-local scope, send only member */
1800
1801	status = osmt_send_mcast_request(p_osmt, 1,
1802					 &mc_req_rec, comp_mask, &res_sa_mad);
1803	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1804
1805	if ((status != IB_REMOTE_ERROR) ||
1806	    (res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID)) {
1807		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0221: "
1808			"Failed to recognize create with JoinState != FullMember - got %s/%s\n",
1809			ib_get_err_str(status),
1810			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1811		status = IB_ERROR;
1812		goto Exit;
1813	}
1814
1815	/* Lets try another valid join scope state */
1816	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1817		"Checking new MGID creation with valid join state (o15.0.2.3)...\n");
1818
1819	mc_req_rec.mgid = good_mgid;
1820	mc_req_rec.mgid.raw[12] = 0xFB;
1821	memcpy(&special_mgid, &mc_req_rec.mgid, sizeof(ib_gid_t));
1822	mc_req_rec.scope_state = 0x2F;	/* link-local scope, Full member with all other bits turned on */
1823
1824	status = osmt_send_mcast_request(p_osmt, 1,
1825					 &mc_req_rec, comp_mask, &res_sa_mad);
1826
1827	if (status != IB_SUCCESS) {
1828		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0222: "
1829			"Failed to create MCG with valid join state 0xF - got %s/%s\n",
1830			ib_get_err_str(status),
1831			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1832		goto Exit;
1833	}
1834
1835	/* Save the mlid created in test_created_mlids map */
1836	p_recvd_rec =
1837	    (ib_member_rec_t *) ib_sa_mad_get_payload_ptr(&res_sa_mad);
1838	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Created MGID:%s MLID:0x%04X\n",
1839		inet_ntop(AF_INET6, p_recvd_rec->mgid.raw, gid_str,
1840			  sizeof gid_str), cl_ntoh16(p_recvd_rec->mlid));
1841	cl_map_insert(&test_created_mlids, cl_ntoh16(p_recvd_rec->mlid),
1842		      p_recvd_rec);
1843
1844	/* o15.0.1.10 - can't check on a single client .-- obsolete -
1845	   checked by SilverStorm bug o15-0.2.4, never the less recheck */
1846	/* o15-0.2.4 - Check a join request to already created MCG */
1847	p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
1848	OSM_LOG(&p_osmt->log, OSM_LOG_INFO, "Check o15-0.2.4 statement...\n");
1849	/* Try to join */
1850	memcpy(&mc_req_rec.mgid, &p_mc_res->mgid, sizeof(ib_gid_t));
1851	/* Request Join */
1852	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_NON_MEMBER);
1853	comp_mask =
1854	    IB_MCR_COMPMASK_MGID |
1855	    IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_JOIN_STATE;
1856
1857	status = osmt_send_mcast_request(p_osmt, 0x1,	/* SubnAdmSet */
1858					 &mc_req_rec, comp_mask, &res_sa_mad);
1859	if (status != IB_SUCCESS) {
1860		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02CC: "
1861			"Failed to join MCG with valid req, returned status = %s\n",
1862			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1863		goto Exit;
1864	}
1865
1866	p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
1867	if ((p_mc_res->scope_state & 0x7) != 0x7) {
1868		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02D0: "
1869			"Validating JoinState update failed. "
1870			"Expected 0x27 got 0x%02X\n",
1871			p_mc_res->scope_state);
1872		status = IB_ERROR;
1873		goto Exit;
1874	}
1875
1876	/* o15.0.1.11: */
1877	/* - Try to join into a MGID that exists with JoinState=SendOnlyMember -  */
1878	/*   see that it updates JoinState. What is the routing change? */
1879	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1880		"Checking Retry of existing MGID - See JoinState update (o15.0.1.11)...\n");
1881
1882	mc_req_rec.mgid = good_mgid;
1883
1884	/* first, make sure  that the group exists */
1885	mc_req_rec.scope_state = 0x21;
1886	status = osmt_send_mcast_request(p_osmt, 1,
1887					 &mc_req_rec, comp_mask, &res_sa_mad);
1888	if (status != IB_SUCCESS) {
1889		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02CD: "
1890			"Failed to create/join as full member - got %s/%s\n",
1891			ib_get_err_str(status),
1892			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1893		goto Exit;
1894	}
1895
1896	mc_req_rec.scope_state = 0x22;	/* link-local scope, non-member */
1897	status = osmt_send_mcast_request(p_osmt, 1,
1898					 &mc_req_rec, comp_mask, &res_sa_mad);
1899	if (status != IB_SUCCESS) {
1900		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02D1: "
1901			"Failed to update existing MGID - got %s/%s\n",
1902			ib_get_err_str(status),
1903			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1904		goto Exit;
1905	}
1906
1907	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1908		"Validating Join State update with NonMember (o15.0.1.11)...\n");
1909
1910	if (p_mc_res->scope_state != 0x23) {	/* scope is LSB */
1911		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02CE: "
1912			"Validating JoinState update failed. Expected 0x23 got: 0x%02X\n",
1913			p_mc_res->scope_state);
1914		status = IB_ERROR;
1915		goto Exit;
1916	}
1917
1918	/* Try delete current join state then update it with another value  */
1919	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1920		"Checking JoinState update request should return 0x22 (o15.0.1.11)...\n");
1921
1922	mc_req_rec.rate =
1923	    IB_LINK_WIDTH_ACTIVE_1X | IB_PATH_SELECTOR_GREATER_THAN << 6;
1924	mc_req_rec.mgid = good_mgid;
1925
1926	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1927		"Checking Partially delete JoinState (o15.0.1.14)...\n");
1928
1929	/* link-local scope, both non-member bits,
1930	   so we should not be able to delete) */
1931	mc_req_rec.scope_state = 0x26;
1932	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
1933	status = osmt_send_mcast_request(p_osmt, 0,
1934					 &mc_req_rec, comp_mask, &res_sa_mad);
1935	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
1936
1937	if (status != IB_REMOTE_ERROR) {
1938		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02CF: "
1939			"Expected to fail partially update JoinState, "
1940			"but got %s\n",
1941			ib_get_err_str(status));
1942		status = IB_ERROR;
1943		goto Exit;
1944	}
1945
1946	/* link-local scope, NonMember bit, the FullMember bit should stay */
1947	mc_req_rec.scope_state = 0x22;
1948	status = osmt_send_mcast_request(p_osmt, 0,
1949					 &mc_req_rec, comp_mask, &res_sa_mad);
1950	if (status != IB_SUCCESS) {
1951		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02D3: "
1952			"Failed to partially update JoinState : %s/%s\n",
1953			ib_get_err_str(status),
1954			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1955		status = IB_ERROR;
1956		goto Exit;
1957	}
1958
1959	p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
1960	if (p_mc_res->scope_state != 0x21) {
1961		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02D4: "
1962			"Failed to partially update JoinState : "
1963			"JoinState = 0x%02X, expected 0x%02X\n",
1964			p_mc_res->scope_state, 0x21);
1965		status = IB_ERROR;
1966		goto Exit;
1967	}
1968
1969	/* So far successfully delete state - Now change it */
1970	mc_req_rec.mgid = good_mgid;
1971	mc_req_rec.scope_state = 0x24;	/* link-local scope, send only  member */
1972
1973	status = osmt_send_mcast_request(p_osmt, 1,
1974					 &mc_req_rec, comp_mask, &res_sa_mad);
1975	if (status != IB_SUCCESS) {
1976		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02C0: "
1977			"Failed to update existing MCG - got %s/%s\n",
1978			ib_get_err_str(status),
1979			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
1980		goto Exit;
1981	}
1982
1983	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
1984		"Validating Join State update with Send Only Member (o15.0.1.11)...\n");
1985
1986	if (p_mc_res->scope_state != 0x25) {	/* scope is MSB */
1987		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02C1: "
1988			"Validating JoinState update failed. Expected 0x25 got: 0x%02X\n",
1989			p_mc_res->scope_state);
1990		status = IB_ERROR;
1991		goto Exit;
1992	}
1993	/* Now try to update value of join state */
1994	mc_req_rec.scope_state = 0x21;	/* link-local scope, full member */
1995
1996	status = osmt_send_mcast_request(p_osmt, 1,
1997					 &mc_req_rec, comp_mask, &res_sa_mad);
1998	if (status != IB_SUCCESS) {
1999		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02C2: "
2000			"Failed to update existing MGID - got %s/%s\n",
2001			ib_get_err_str(status),
2002			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
2003		goto Exit;
2004	}
2005
2006	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2007		"Validating Join State update with Full Member\n\t\t"
2008		"to an existing 0x5 state MCG (o15.0.1.11)...\n");
2009
2010	if (p_mc_res->scope_state != 0x25) {	/* scope is LSB */
2011		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02C3: "
2012			"Validating JoinState update failed. Expected 0x25 got: 0x%02X\n",
2013			p_mc_res->scope_state);
2014		status = IB_ERROR;
2015		goto Exit;
2016	}
2017
2018	/* Now try to update value of join state */
2019	mc_req_rec.scope_state = 0x22;	/* link-local scope,non member */
2020
2021	status = osmt_send_mcast_request(p_osmt, 1,
2022					 &mc_req_rec, comp_mask, &res_sa_mad);
2023	if (status != IB_SUCCESS) {
2024		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02C4: "
2025			"Failed to update existing MGID - got %s/%s\n",
2026			ib_get_err_str(status),
2027			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
2028		goto Exit;
2029	}
2030	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2031		"Validating Join State update with Non Member\n\t\t"
2032		"to an existing 0x5 state MCG (o15.0.1.11)...\n");
2033
2034	if (p_mc_res->scope_state != 0x27) {	/* scope is LSB */
2035		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02C5: "
2036			"Validating JoinState update failed. Expected 0x27 got: 0x%02X\n",
2037			p_mc_res->scope_state);
2038		status = IB_ERROR;
2039		goto Exit;
2040	}
2041
2042	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
2043		"DEBUG - Current scope_state value : 0x%02X...\n",
2044		p_mc_res->scope_state);
2045
2046	/* - We can not check simple join since we have only one tester (for now) */
2047
2048	/* o15.0.1.12: Not Supported */
2049	/* - The SendOnlyNonMem join should have a special treatment in the
2050	   SA but what is it ? */
2051
2052	/* o15.0.1.13: */
2053	/* - Try joining with rate that does not exist in any MCG -
2054	   ERR_REQ_INVALID */
2055
2056	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2057		"Checking BAD RATE when connecting to existing MGID (o15.0.1.13)...\n");
2058	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
2059
2060	mc_req_rec.mgid = good_mgid;
2061	mc_req_rec.rate =
2062	    IB_LINK_WIDTH_ACTIVE_1X | IB_PATH_SELECTOR_LESS_THAN << 6;
2063	comp_mask = IB_MCR_COMPMASK_GID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
2064	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
2065
2066	status = osmt_send_mcast_request(p_osmt, 1,
2067					 &mc_req_rec, comp_mask, &res_sa_mad);
2068	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
2069
2070	if ((status != IB_REMOTE_ERROR) ||
2071	    (res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID)) {
2072		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02C6: "
2073			"Failed to catch BAD RATE joining an exiting MGID: %s/%s\n",
2074			ib_get_err_str(status),
2075			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
2076		status = IB_ERROR;
2077		goto Exit;
2078	}
2079
2080	/* Try MTU that does not exist in any MCG */
2081	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2082		"Checking BAD MTU (higher them max) when connecting to "
2083		"existing MGID (o15.0.1.13)...\n");
2084	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
2085
2086	mc_req_rec.mgid = osm_ipoib_mgid;
2087	mc_req_rec.mtu = IB_MTU_LEN_4096 | IB_PATH_SELECTOR_GREATER_THAN << 6;
2088	comp_mask = IB_MCR_COMPMASK_GID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
2089	    IB_MCR_COMPMASK_MTU_SEL | IB_MCR_COMPMASK_MTU;
2090
2091	status = osmt_send_mcast_request(p_osmt, 1,
2092					 &mc_req_rec, comp_mask, &res_sa_mad);
2093	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
2094
2095	if ((status != IB_REMOTE_ERROR) ||
2096	    (res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID)) {
2097		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02C7: "
2098			"Failed to catch BAD RATE (higher them max) joining an exiting MGID: %s/%s\n",
2099			ib_get_err_str(status),
2100			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
2101		status = IB_ERROR;
2102		goto Exit;
2103	}
2104
2105	/* Try another MTU that does not exist in any MCG */
2106	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2107		"Checking BAD MTU (less than min) when connecting "
2108		"to existing MGID (o15.0.1.13)...\n");
2109	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
2110
2111	mc_req_rec.mgid = osm_ipoib_mgid;
2112	mc_req_rec.mtu = IB_MTU_LEN_256 | IB_PATH_SELECTOR_LESS_THAN << 6;
2113	comp_mask = IB_MCR_COMPMASK_GID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
2114	    IB_MCR_COMPMASK_MTU_SEL | IB_MCR_COMPMASK_MTU;
2115
2116	status = osmt_send_mcast_request(p_osmt, 1,
2117					 &mc_req_rec, comp_mask, &res_sa_mad);
2118	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
2119
2120	if ((status != IB_REMOTE_ERROR) ||
2121	    (res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID)) {
2122		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02C8: "
2123			"Failed to catch BAD RATE (less them min) joining an exiting MGID: %s/%s\n",
2124			ib_get_err_str(status),
2125			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
2126		status = IB_ERROR;
2127		goto Exit;
2128	}
2129
2130	/* o15.0.1.14: */
2131	/* - Try partial delete - actually updating the join state. check it. */
2132
2133	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2134		"Checking partial JoinState delete request - removing NonMember (o15.0.1.14)...\n");
2135
2136	mc_req_rec.rate =
2137	    IB_LINK_WIDTH_ACTIVE_1X | IB_PATH_SELECTOR_GREATER_THAN << 6;
2138	mc_req_rec.mgid = good_mgid;
2139	comp_mask = IB_MCR_COMPMASK_GID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
2140	    IB_MCR_COMPMASK_RATE_SEL | IB_MCR_COMPMASK_RATE;
2141	/* link-local scope, non member (so we should not be able to delete) */
2142	/* but the NonMember bit should be gone */
2143	mc_req_rec.scope_state = 0x22;
2144
2145	status = osmt_send_mcast_request(p_osmt, 0,
2146					 &mc_req_rec, comp_mask, &res_sa_mad);
2147
2148	if (status != IB_SUCCESS) {
2149		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02C9: "
2150			"Fail to partially update JoinState during delete: %s/%s\n",
2151			ib_get_err_str(status),
2152			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
2153		status = IB_ERROR;
2154		goto Exit;
2155	}
2156
2157	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2158		"Validating Join State removal of Non Member bit (o15.0.1.14)...\n");
2159	if (p_mc_res->scope_state != 0x25) {	/* scope is MSB - now only the full member & send only member have left */
2160		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02CA: "
2161			"Validating JoinState update failed. Expected 0x25 got: 0x%02X\n",
2162			p_mc_res->scope_state);
2163		status = IB_ERROR;
2164		goto Exit;
2165	}
2166
2167	/* Now use the same scope_state and delete all JoinState - leave multicast group since state is 0x0 */
2168
2169	mc_req_rec.scope_state = 0x25;
2170	status = osmt_send_mcast_request(p_osmt, 0,
2171					 &mc_req_rec, comp_mask, &res_sa_mad);
2172
2173	if (status != IB_SUCCESS) {
2174		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02CB: "
2175			"Failed to update JoinState during delete: %s/%s\n",
2176			ib_get_err_str(status),
2177			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
2178		status = IB_ERROR;
2179		goto Exit;
2180	}
2181
2182	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2183		"Validating Join State update remove (o15.0.1.14)...\n");
2184
2185	if (p_mc_res->scope_state != 0x25) {	/* scope is MSB - now only 0x0 so port is removed from MCG */
2186		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02BF: "
2187			"Validating JoinState update failed. Expected 0x25 got: 0x%02X\n",
2188			p_mc_res->scope_state);
2189		status = IB_ERROR;
2190		goto Exit;
2191	}
2192
2193	/* - Try joining (not full mem) again to see the group was deleted. (should fail) */
2194	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2195		"Checking Delete by trying to Join deleted group (o15.0.1.13)...\n");
2196
2197	mc_req_rec.scope_state = 0x22;	/* use non member - so if no group fail */
2198
2199	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
2200	status = osmt_send_mcast_request(p_osmt, 1,	/* join */
2201					 &mc_req_rec, comp_mask, &res_sa_mad);
2202	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
2203
2204	if (status != IB_REMOTE_ERROR) {
2205		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02BC: "
2206			"Succeeded Joining Deleted Group: %s/%s\n",
2207			ib_get_err_str(status),
2208			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
2209		status = IB_ERROR;
2210		goto Exit;
2211	}
2212
2213	/* - Try deletion of the IPoIB MCG and get: ERR_REQ_INVALID */
2214	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2215		"Checking BAD Delete of Mgid membership (no prev join) (o15.0.1.15)...\n");
2216	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
2217
2218	mc_req_rec.mgid = osm_ipoib_mgid;
2219	mc_req_rec.rate =
2220	    IB_LINK_WIDTH_ACTIVE_1X | IB_PATH_SELECTOR_GREATER_THAN << 6;
2221	mc_req_rec.scope_state = 0x21;	/* delete full member */
2222
2223	status = osmt_send_mcast_request(p_osmt, 0,	/* delete flag */
2224					 &mc_req_rec, comp_mask, &res_sa_mad);
2225	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
2226
2227	if ((status != IB_REMOTE_ERROR) ||
2228	    (res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID)) {
2229		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02BD: "
2230			"Failed to catch BAD delete from IPoIB: %s/%s\n",
2231			ib_get_err_str(status),
2232			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
2233		status = IB_ERROR;
2234		goto Exit;
2235	}
2236
2237	/* Prepare another MCG for the following tests : */
2238	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2239		"Checking Create given MGID=%s\n\t\t(o15.0.1.4)...\n",
2240		inet_ntop(AF_INET6, osm_ipoib_mgid.raw, gid_str,
2241			  sizeof gid_str));
2242
2243	mc_req_rec.mgid = good_mgid;
2244	mc_req_rec.mgid.raw[12] = 0xAA;
2245	mc_req_rec.pkt_life = 0 | IB_PATH_SELECTOR_GREATER_THAN << 6;
2246	mc_req_rec.scope_state = 0x21;	/* Full memeber */
2247	comp_mask = IB_MCR_COMPMASK_GID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
2248	    IB_MCR_COMPMASK_LIFE | IB_MCR_COMPMASK_LIFE_SEL;
2249
2250	status = osmt_send_mcast_request(p_osmt, 1,
2251					 &mc_req_rec, comp_mask, &res_sa_mad);
2252	if (status != IB_SUCCESS) {
2253		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02BE: "
2254			"Failed to create MCG for %s - got %s/%s\n",
2255			inet_ntop(AF_INET6, good_mgid.raw, gid_str,
2256				  sizeof gid_str), ib_get_err_str(status),
2257			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
2258		goto Exit;
2259	}
2260
2261	/* - Try delete with valid join state */
2262	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2263		"Checking Full Delete of a group (o15.0.1.14)...\n");
2264	mc_req_rec.scope_state = 0x21;	/* the FullMember is the current JoinState */
2265	status = osmt_send_mcast_request(p_osmt, 0,
2266					 &mc_req_rec, comp_mask, &res_sa_mad);
2267
2268	if (status != IB_SUCCESS) {
2269		goto Exit;
2270	}
2271
2272	/* o15.0.1.15: */
2273	/* - Try deletion of the IPoIB MCG and get: ERR_REQ_INVALID */
2274	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2275		"Checking BAD Delete of IPoIB membership (no prev join) (o15.0.1.15)...\n");
2276	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
2277
2278	mc_req_rec.mgid = osm_ipoib_mgid;
2279	mc_req_rec.rate =
2280	    IB_LINK_WIDTH_ACTIVE_1X | IB_PATH_SELECTOR_GREATER_THAN << 6;
2281	mc_req_rec.scope_state = 0x21;	/* delete full member */
2282
2283	status = osmt_send_mcast_request(p_osmt, 0,	/* delete flag */
2284					 &mc_req_rec, comp_mask, &res_sa_mad);
2285
2286	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
2287
2288	if ((status != IB_REMOTE_ERROR) ||
2289	    (res_sa_mad.status != IB_SA_MAD_STATUS_REQ_INVALID)) {
2290		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0223: "
2291			"Failed to catch BAD delete from IPoIB: %s/%s\n",
2292			ib_get_err_str(status),
2293			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
2294		status = IB_ERROR;
2295		goto Exit;
2296	}
2297
2298  /**************************************************************************/
2299	/* Checking join with invalid MTU */
2300	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
2301	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2302		"Checking Join with unrealistic mtu : \n"
2303		"\t\tFirst create new MCG than try to join it \n"
2304		"\t\twith unrealistic MTU greater than 4096 (o15.0.1.8)...\n");
2305
2306	/* First create new mgrp */
2307	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_FULL_MEMBER);
2308	mc_req_rec.mtu = IB_MTU_LEN_1024 | IB_PATH_SELECTOR_EXACTLY << 6;
2309	memset(&mc_req_rec.mgid, 0, sizeof(ib_gid_t));
2310	comp_mask = IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
2311	    IB_MCR_COMPMASK_MTU_SEL | IB_MCR_COMPMASK_MTU;
2312
2313	status = osmt_send_mcast_request(p_osmt, 1,
2314					 &mc_req_rec, comp_mask, &res_sa_mad);
2315	p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
2316	if (status != IB_SUCCESS) {
2317		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02EB: "
2318			"Failed to create new mgrp\n");
2319		goto Exit;
2320	}
2321	memcpy(&tmp_mgid, &p_mc_res->mgid, sizeof(ib_gid_t));
2322	osm_dump_mc_record(&p_osmt->log, p_mc_res, OSM_LOG_INFO);
2323	/* tmp_mtu = p_mc_res->mtu & 0x3F; */
2324
2325	/* impossible requested mtu always greater than exist in MCG */
2326	mc_req_rec.mtu = IB_MTU_LEN_4096 | IB_PATH_SELECTOR_GREATER_THAN << 6;
2327	memcpy(&mc_req_rec.mgid, &tmp_mgid, sizeof(ib_gid_t));
2328	ib_member_set_join_state(&mc_req_rec, IB_MC_REC_STATE_FULL_MEMBER);
2329	comp_mask =
2330	    IB_MCR_COMPMASK_GID |
2331	    IB_MCR_COMPMASK_PORT_GID |
2332	    IB_MCR_COMPMASK_JOIN_STATE |
2333	    IB_MCR_COMPMASK_MTU_SEL | IB_MCR_COMPMASK_MTU;
2334
2335	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
2336	status = osmt_send_mcast_request(p_osmt, 1,
2337					 &mc_req_rec, comp_mask, &res_sa_mad);
2338	OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
2339
2340	if (status == IB_SUCCESS) {
2341		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02E4: "
2342			"Expected REMOTE ERROR got:%s/%s\n",
2343			ib_get_err_str(status),
2344			ib_get_mad_status_str((ib_mad_t *) (&res_sa_mad)));
2345		status = IB_ERROR;
2346		goto Exit;
2347	}
2348
2349	/* - Try GetTable with PortGUID wildcarded and get back some groups. */
2350	status = osmt_query_mcast(p_osmt);
2351	cnt = cl_qmap_count(&p_osmt->exp_subn.mgrp_mlid_tbl);
2352	OSM_LOG(&p_osmt->log, OSM_LOG_INFO, "(Before checking Max MCG creation): "
2353		"Number of MC Records found in SA DB is %d\n", cnt);
2354
2355  /**************************************************************************/
2356	/* Checking join on behalf of remote port gid */
2357	OSM_LOG(&p_osmt->log, OSM_LOG_INFO, "Checking Proxy Join...\n");
2358	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
2359	memset(&context, 0, sizeof(context));
2360
2361	/*
2362	 * Do a blocking query for all NodeRecords in the subnet.
2363	 */
2364	status = osmtest_get_all_recs(p_osmt, IB_MAD_ATTR_NODE_RECORD,
2365				      sizeof(*p_rec), &context);
2366
2367	if (status != IB_SUCCESS) {
2368		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02E5: "
2369			"osmtest_get_all_recs failed on getting all node records(%s)\n",
2370			ib_get_err_str(status));
2371		goto Exit;
2372	}
2373
2374	/*
2375	 * Populate the database with the received records.
2376	 */
2377	num_recs = context.result.result_cnt;
2378	OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE, "Received %u records\n", num_recs);
2379
2380	for (i = 0; i < num_recs; i++) {
2381		p_rec =
2382		    osmv_get_query_node_rec(context.result.p_result_madw, i);
2383		if (p_rec->node_info.port_guid != p_osmt->local_port.port_guid
2384		    && p_rec->node_info.node_type == IB_NODE_TYPE_CA) {
2385			OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
2386				"remote port_guid = 0x%" PRIx64 "\n",
2387				cl_ntoh64(p_rec->node_info.port_guid));
2388
2389			remote_port_guid = p_rec->node_info.port_guid;
2390			i = num_recs;
2391			break;
2392		}
2393	}
2394
2395	if (remote_port_guid != 0x0) {
2396		ib_member_set_join_state(&mc_req_rec,
2397					 IB_MC_REC_STATE_FULL_MEMBER);
2398		memset(&mc_req_rec.mgid, 0, sizeof(ib_gid_t));
2399		mc_req_rec.port_gid.unicast.interface_id = remote_port_guid;
2400		comp_mask = IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS;	/* all above are required */
2401
2402		status = osmt_send_mcast_request(p_osmt, 1,
2403						 &mc_req_rec,
2404						 comp_mask, &res_sa_mad);
2405
2406		if (status != IB_SUCCESS) {
2407			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02B4: "
2408				"Could not join on behalf of remote port 0x%016"
2409				PRIx64 " remote status: %s\n",
2410				cl_ntoh64(remote_port_guid),
2411				ib_get_mad_status_str((ib_mad_t
2412						       *) (&res_sa_mad)));
2413			status = IB_ERROR;
2414			goto Exit;
2415		}
2416
2417		p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
2418		memcpy(&proxy_mgid, &p_mc_res->mgid, sizeof(ib_gid_t));
2419
2420		/* First try a bad deletion then good one */
2421
2422		OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2423			"Trying deletion of remote port with local port guid\n");
2424
2425		osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
2426		ib_member_set_join_state(&mc_req_rec,
2427					 IB_MC_REC_STATE_FULL_MEMBER);
2428		comp_mask =
2429		    IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID |
2430		    IB_MCR_COMPMASK_JOIN_STATE;
2431
2432		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_START "\n");
2433
2434		status = osmt_send_mcast_request(p_osmt, 0,	/* delete flag */
2435						 &mc_req_rec,
2436						 comp_mask, &res_sa_mad);
2437
2438		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, EXPECTING_ERRORS_END "\n");
2439
2440		if (status == IB_SUCCESS) {
2441			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02A9: "
2442				"Successful deletion of remote port guid with local one MGID : "
2443				"%s, Got : %s/%s\n",
2444				inet_ntop(AF_INET6,
2445					p_mgrp->mcmember_rec.mgid.raw,
2446					gid_str, sizeof gid_str),
2447				ib_get_err_str(status),
2448				ib_get_mad_status_str((ib_mad_t
2449						       *) (&res_sa_mad)));
2450			status = IB_ERROR;
2451			goto Exit;
2452		}
2453
2454		OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2455			"Trying deletion of remote port with the right port guid\n");
2456
2457		osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
2458		ib_member_set_join_state(&mc_req_rec,
2459					 IB_MC_REC_STATE_FULL_MEMBER);
2460		mc_req_rec.mgid = proxy_mgid;
2461		mc_req_rec.port_gid.unicast.interface_id = remote_port_guid;
2462		comp_mask =
2463		    IB_MCR_COMPMASK_MGID |
2464		    IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_JOIN_STATE;
2465		status = osmt_send_mcast_request(p_osmt, 0,	/* delete flag */
2466						 &mc_req_rec,
2467						 comp_mask, &res_sa_mad);
2468		if (status != IB_SUCCESS) {
2469			OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02B0: "
2470				"Failed to delete mgid with remote port guid MGID : "
2471				"%s, Got : %s/%s\n",
2472				inet_ntop(AF_INET6,
2473					p_mgrp->mcmember_rec.mgid.raw,
2474					gid_str, sizeof gid_str),
2475				ib_get_err_str(status),
2476				ib_get_mad_status_str((ib_mad_t
2477						       *) (&res_sa_mad)));
2478			goto Exit;
2479		}
2480	} else {
2481		OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2482			"Could not check proxy join since could not found remote port, different from local port\n");
2483	}
2484
2485	/* prepare init for next check */
2486	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
2487
2488  /**************************************************************************/
2489	if (p_osmt->opt.mmode > 2) {
2490		/* Check invalid Join with max mlid which is more than the
2491		   Mellanox switches support 0xC000+0x1000 = 0xd000 */
2492		OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2493			"Checking Creation of Maximum avaliable Groups (MulticastFDBCap)...\n");
2494		tmp_mlid = cl_ntoh16(max_mlid) - cnt;
2495
2496		while (tmp_mlid > 0 && !ReachedMlidLimit) {
2497			uint16_t cur_mlid = 0;
2498
2499			/* Request Set */
2500			ib_member_set_join_state(&mc_req_rec,
2501						 IB_MC_REC_STATE_FULL_MEMBER);
2502			/* Good Flow - mgid is 0 while giving all required fields for
2503			   join : P_Key, Q_Key, SL, FlowLabel, Tclass */
2504
2505			mc_req_rec.rate =
2506			    IB_LINK_WIDTH_ACTIVE_1X |
2507			    IB_PATH_SELECTOR_GREATER_THAN << 6;
2508			mc_req_rec.mlid = max_mlid;
2509			memset(&mc_req_rec.mgid, 0, sizeof(ib_gid_t));
2510			comp_mask = IB_MCR_COMPMASK_MGID | IB_MCR_COMPMASK_PORT_GID | IB_MCR_COMPMASK_QKEY | IB_MCR_COMPMASK_PKEY | IB_MCR_COMPMASK_SL | IB_MCR_COMPMASK_FLOW | IB_MCR_COMPMASK_JOIN_STATE | IB_MCR_COMPMASK_TCLASS |	/* all above are required */
2511			    IB_MCR_COMPMASK_MLID;
2512			status = osmt_send_mcast_request(p_osmt, 1,
2513							 &mc_req_rec,
2514							 comp_mask,
2515							 &res_sa_mad);
2516
2517			p_mc_res = ib_sa_mad_get_payload_ptr(&res_sa_mad);
2518			if (status != IB_SUCCESS) {
2519
2520				if (cur_mlid > cl_ntoh16(max_mlid)) {
2521
2522					OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
2523						"ERR 2E1 "
2524						"Successful Join with greater mlid than switches support (MulticastFDBCap) 0x%04X\n",
2525						cur_mlid);
2526					status = IB_ERROR;
2527					osm_dump_mc_record(&p_osmt->log,
2528							   p_mc_res,
2529							   OSM_LOG_VERBOSE);
2530					goto Exit;
2531				} else
2532				    if ((res_sa_mad.
2533					 status & IB_SMP_STATUS_MASK) ==
2534					IB_SA_MAD_STATUS_NO_RESOURCES) {
2535					/* You can quitly exit the loop since no available mlid in SA DB
2536					   i.e. reached the maximum valiad avalable mlid */
2537					ReachedMlidLimit = TRUE;
2538				}
2539			} else {
2540				cur_mlid = cl_ntoh16(p_mc_res->mlid);
2541				/* Save the mlid created in test_created_mlids map */
2542				p_recvd_rec =
2543				    (ib_member_rec_t *)
2544				    ib_sa_mad_get_payload_ptr(&res_sa_mad);
2545				OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
2546					"Created MGID:%s MLID:0x%04X\n",
2547					inet_ntop(AF_INET6,
2548						  p_recvd_rec->mgid.raw,
2549						  gid_str, sizeof gid_str),
2550					cl_ntoh16(p_recvd_rec->mlid));
2551				cl_map_insert(&test_created_mlids,
2552					      cl_ntoh16(p_recvd_rec->mlid),
2553					      p_recvd_rec);
2554			}
2555			tmp_mlid--;
2556		}
2557	}
2558
2559	/* Prepare the mc_req_rec for the rest of the flow */
2560	osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
2561
2562  /**************************************************************************/
2563	/* o15.0.1.16: */
2564	/* - Try GetTable with PortGUID wildcarded and get back some groups. */
2565
2566	status = osmt_query_mcast(p_osmt);
2567	if (status != IB_SUCCESS) {
2568		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02B1: "
2569			"Failed to query multicast groups: %s\n",
2570			ib_get_err_str(status));
2571		goto Exit;
2572	}
2573
2574	cnt = cl_qmap_count(&p_osmt->exp_subn.mgrp_mlid_tbl);
2575	OSM_LOG(&p_osmt->log, OSM_LOG_INFO, "(Before Deletion of all MCG): "
2576		"Number of MC Records found in SA DB is %d\n", cnt);
2577
2578	/* Delete all MCG that are not of IPoIB */
2579	OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2580		"Cleanup all MCG that are not IPoIB...\n");
2581
2582	p_mgrp_mlid_tbl = &p_osmt->exp_subn.mgrp_mlid_tbl;
2583	p_mgrp = (osmtest_mgrp_t *) cl_qmap_head(p_mgrp_mlid_tbl);
2584	/* scan all available multicast groups in the DB and fill in the table */
2585	while (p_mgrp != (osmtest_mgrp_t *) cl_qmap_end(p_mgrp_mlid_tbl)) {
2586		/* Only if different from IPoIB Mgid try to delete */
2587		if (!IS_IPOIB_MGID(&p_mgrp->mcmember_rec.mgid)) {
2588			osmt_init_mc_query_rec(p_osmt, &mc_req_rec);
2589			mc_req_rec.mgid = p_mgrp->mcmember_rec.mgid;
2590
2591			/* o15-0.1.4 - need to specify the oppsite state for a valid delete */
2592			if (!memcmp
2593			    (&special_mgid, &p_mgrp->mcmember_rec.mgid,
2594			     sizeof(special_mgid))) {
2595				mc_req_rec.scope_state = 0x2F;
2596			} else {
2597				mc_req_rec.scope_state = 0x21;
2598			}
2599			comp_mask =
2600			    IB_MCR_COMPMASK_MGID |
2601			    IB_MCR_COMPMASK_PORT_GID |
2602			    IB_MCR_COMPMASK_JOIN_STATE;
2603
2604			OSM_LOG(&p_osmt->log, OSM_LOG_VERBOSE,
2605				"Sending request to delete MGID : %s"
2606				", scope_state : 0x%02X\n",
2607				inet_ntop(AF_INET6, mc_req_rec.mgid.raw,
2608					  gid_str, sizeof gid_str),
2609				mc_req_rec.scope_state);
2610			status = osmt_send_mcast_request(p_osmt, 0,	/* delete flag */
2611							 &mc_req_rec,
2612							 comp_mask,
2613							 &res_sa_mad);
2614			if (status != IB_SUCCESS) {
2615				OSM_LOG(&p_osmt->log, OSM_LOG_ERROR,
2616					"ERR 02FF: Failed to delete MGID : %s"
2617					" ,\n\t\t it is not our MCG, Status : %s/%s\n",
2618					inet_ntop(AF_INET6,
2619						  p_mgrp->mcmember_rec.mgid.raw,
2620						  gid_str, sizeof gid_str),
2621					ib_get_err_str(status),
2622					ib_get_mad_status_str((ib_mad_t *)
2623							      (&res_sa_mad)));
2624				fail_to_delete_mcg++;
2625			}
2626		} else {
2627			end_ipoib_cnt++;
2628		}
2629		p_mgrp = (osmtest_mgrp_t *) cl_qmap_next(&p_mgrp->map_item);
2630	}
2631
2632	status = osmt_query_mcast(p_osmt);
2633
2634	if (status != IB_SUCCESS) {
2635		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02B2 "
2636			"GetTable of all records has failed - got %s\n",
2637			ib_get_err_str(status));
2638		goto Exit;
2639	}
2640
2641	/* If we are in single mode check flow - need to make sure all the multicast groups
2642	   that are left are not ones created during the flow.
2643	 */
2644	if (p_osmt->opt.mmode == 1 || p_osmt->opt.mmode == 3) {
2645		end_cnt = cl_qmap_count(&p_osmt->exp_subn.mgrp_mlid_tbl);
2646
2647		OSM_LOG(&p_osmt->log, OSM_LOG_INFO, "Status of MC Records in SA DB during the test flow:\n" "  Beginning of test\n" "       Unrelated to the test: %d\n" "       IPoIB MC Records     : %d\n" "       Total                : %d\n" "  End of test\n" "       Failed to delete     : %d\n" "       IPoIB MC Records     : %d\n" "       Total                : %d\n", mcg_outside_test_cnt,	/* Non-IPoIB that existed at the beginning */
2648			start_ipoib_cnt,	/* IPoIB records */
2649			start_cnt,	/* Total: IPoIB and MC Records unrelated to the test */
2650			fail_to_delete_mcg,	/* Failed to delete at the end */
2651			end_ipoib_cnt,	/* IPoIB records */
2652			end_cnt);	/* Total MC Records at the end */
2653
2654		/* when we compare num of MCG we should consider an outside source which create other MCGs */
2655		if ((end_cnt - fail_to_delete_mcg - end_ipoib_cnt) !=
2656		    (start_cnt - mcg_outside_test_cnt - start_ipoib_cnt)) {
2657			OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2658				"Got different number of non-IPoIB records stored in SA DB\n\t\t"
2659				"at Start got %d, at End got %d (IPoIB groups only)\n",
2660				(start_cnt - mcg_outside_test_cnt -
2661				 start_ipoib_cnt),
2662				(end_cnt - fail_to_delete_mcg - end_ipoib_cnt));
2663		}
2664
2665		p_mgrp_mlid_tbl = &p_osmt->exp_subn.mgrp_mlid_tbl;
2666		p_mgrp = (osmtest_mgrp_t *) cl_qmap_head(p_mgrp_mlid_tbl);
2667		while (p_mgrp !=
2668		       (osmtest_mgrp_t *) cl_qmap_end(p_mgrp_mlid_tbl)) {
2669			uint16_t mlid =
2670			    (uint16_t) cl_qmap_key((cl_map_item_t *) p_mgrp);
2671
2672			OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2673				"Found MLID:0x%04X\n", mlid);
2674			/* Check if the mlid is in the test_created_mlids. If TRUE, then we
2675			   didn't delete a MCgroup that was created in this flow. */
2676			if (cl_map_get(&test_created_mlids, mlid) != NULL) {
2677				/* This means that we still have an mgrp that we created!! */
2678				OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 02FE: "
2679					"Wasn't able to erase mgrp with MGID:%s"
2680					" MLID:0x%04X\n",
2681					inet_ntop(AF_INET6,
2682						  p_mgrp->mcmember_rec.mgid.raw,
2683						  gid_str, sizeof gid_str),
2684					mlid);
2685				got_error = TRUE;
2686			} else {
2687				OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
2688					"Still exists %s MGID:%s\n",
2689					(IS_IPOIB_MGID
2690					 (&p_mgrp->mcmember_rec.
2691					  mgid)) ? "IPoIB" : "non-IPoIB",
2692					inet_ntop(AF_INET6,
2693						p_mgrp->mcmember_rec.mgid.raw,
2694						gid_str, sizeof gid_str));
2695			}
2696			p_mgrp =
2697			    (osmtest_mgrp_t *) cl_qmap_next(&p_mgrp->map_item);
2698		}
2699
2700		if (got_error) {
2701			__osmt_print_all_multicast_records(p_osmt);
2702			status = IB_ERROR;
2703		}
2704	}
2705Exit:
2706	OSM_LOG_EXIT(&p_osmt->log);
2707	return status;
2708}
2709