1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #include <sys/types.h>
27 #include <sys/kmem.h>
28 #include <sys/sunddi.h>
29 #include <sys/ib/mgt/ibmf/ibmf_saa_impl.h>
30 #include <sys/ib/mgt/ibmf/ibmf_saa_utils.h>
31
32 #define IBMF_SAA_HDR_SIZE 20
33 #define IBMF_SAA_DEFAULT_RID_SIZE 4
34 #define IBMF_SAA_PARTITION_RID_SIZE 5
35 #define IBMF_SAA_INFORMINFO_RID_SIZE 18
36
37 #define IB_MAD_NOTICE_SIZE 80
38 #define IB_MAD_CLASSPORTINFO_SIZE 72
39 #define IB_MAD_INFORMINFO_SIZE 36
40
41 #define SM_TRAP_DATA_DETAILS_SIZE 54
42 #define SM_NODEINFO_SIZE 40
43 #define SM_NODEDESC_SIZE 64
44 #define SM_PORTINFO_SIZE 54
45 #define SM_SLTOVL_SIZE 8
46 #define SM_SWITCHINFO_SIZE 17
47 #define SM_LINEARFDB_SIZE 64
48 #define SM_RANDOMFDB_SIZE 64
49 #define SM_MULTICASTFDB_SIZE 64
50 #define SM_SMINFO_SIZE 21
51 #define SM_GUIDINFO_SIZE 64
52 #define SM_PARTITION_SIZE 64
53 #define SM_VLARB_SIZE 64
54
55 #define IBMF_SAA_NODE_RECORD_SIZE 108
56 #define IBMF_SAA_PORTINFO_RECORD_SIZE 58
57 #define IBMF_SAA_SLTOVL_RECORD_SIZE 16
58 #define IBMF_SAA_SWITCHINFO_RECORD_SIZE 21
59 #define IBMF_SAA_LINEARFDB_RECORD_SIZE 72
60 #define IBMF_SAA_RANDOMFDB_RECORD_SIZE 72
61 #define IBMF_SAA_MULTICASTFDB_RECORD_SIZE 72
62 #define IBMF_SAA_SMINFO_RECORD_SIZE 25
63 #define IBMF_SAA_INFORMINFO_RECORD_SIZE 60
64 #define IBMF_SAA_LINK_RECORD_SIZE 6
65 #define IBMF_SAA_GUIDINFO_RECORD_SIZE 72
66 #define IBMF_SAA_SERVICE_RECORD_SIZE 176
67 #define IBMF_SAA_PARTITION_RECORD_SIZE 72
68 #define IBMF_SAA_PATH_RECORD_SIZE 64
69 #define IBMF_SAA_VLARB_RECORD_SIZE 72
70 #define IBMF_SAA_MCMEMBER_RECORD_SIZE 52
71 #define IBMF_SAA_TRACE_RECORD_SIZE 46
72 #define IBMF_SAA_MULTIPATH_RECORD_SIZE 24
73 #define IBMF_SAA_SERVICEASSN_RECORD_SIZE 80
74
75 extern int ibmf_trace_level;
76
77 /* These functions have only been tested on a big-endian system */
78 static void ibmf_saa_classportinfo_parse_buffer(uchar_t *buffer, void *record);
79 static void ibmf_saa_notice_parse_buffer(uchar_t *buffer, void *record);
80 static void ibmf_saa_informinfo_parse_buffer(uchar_t *buffer, void *record);
81 static void ibmf_saa_node_record_parse_buffer(uchar_t *buffer, void *record);
82 static void ibmf_saa_portinfo_record_parse_buffer(uchar_t *buffer,
83 void *record);
84 static void ibmf_saa_SLtoVLmapping_record_parse_buffer(uchar_t *buffer,
85 void *record);
86 static void ibmf_saa_switchinfo_record_parse_buffer(uchar_t *buffer,
87 void *record);
88 static void ibmf_saa_linearft_record_parse_buffer(uchar_t *buffer,
89 void *record);
90 static void ibmf_saa_randomft_record_parse_buffer(uchar_t *buffer,
91 void *record);
92 static void ibmf_saa_multicastft_record_parse_buffer(uchar_t *buffer,
93 void *record);
94 static void ibmf_saa_sminfo_record_parse_buffer(uchar_t *buffer, void *record);
95 static void ibmf_saa_informinfo_record_parse_buffer(uchar_t *buffer,
96 void *record);
97 static void ibmf_saa_link_record_parse_buffer(uchar_t *buffer, void *record);
98 static void ibmf_saa_guidinfo_record_parse_buffer(uchar_t *buffer,
99 void *record);
100 static void ibmf_saa_service_record_parse_buffer(uchar_t *buffer, void *record);
101 static void ibmf_saa_partition_record_parse_buffer(uchar_t *buffer,
102 void *record);
103 static void ibmf_saa_path_record_parse_buffer(uchar_t *buffer, void *record);
104 static void ibmf_saa_vlarb_record_parse_buffer(uchar_t *buffer, void *record);
105 static void ibmf_saa_mcmember_record_parse_buffer(uchar_t *buffer,
106 void *record);
107 static void ibmf_saa_trace_record_parse_buffer(uchar_t *buffer, void *record);
108 static void ibmf_saa_multipath_record_parse_buffer(uchar_t *buffer,
109 void *record);
110 static void ibmf_saa_service_assn_record_parse_buffer(uchar_t *buffer,
111 void *record);
112
113 static void ibmf_saa_classportinfo_to_buf(void *record, uchar_t *buffer);
114 static void ibmf_saa_notice_to_buf(void *record, uchar_t *buffer);
115 static void ibmf_saa_informinfo_to_buf(void *record, uchar_t *buffer);
116 static void ibmf_saa_node_record_to_buf(void *record, uchar_t *buffer);
117 static void ibmf_saa_portinfo_record_to_buf(void *record, uchar_t *buffer);
118 static void ibmf_saa_SLtoVLmapping_record_to_buf(void *record, uchar_t *buffer);
119 static void ibmf_saa_switchinfo_record_to_buf(void *record, uchar_t *buffer);
120 static void ibmf_saa_linearft_record_to_buf(void *record, uchar_t *buffer);
121 static void ibmf_saa_randomft_record_to_buf(void *record, uchar_t *buffer);
122 static void ibmf_saa_multicastft_record_to_buf(void *record, uchar_t *buffer);
123 static void ibmf_saa_sminfo_record_to_buf(void *record, uchar_t *buffer);
124 static void ibmf_saa_informinfo_record_to_buf(void *record, uchar_t *buffer);
125 static void ibmf_saa_link_record_to_buf(void *record, uchar_t *buffer);
126 static void ibmf_saa_guidinfo_record_to_buf(void *record, uchar_t *buffer);
127 static void ibmf_saa_service_record_to_buf(void *record, uchar_t *buffer);
128 static void ibmf_saa_partition_record_to_buf(void *record, uchar_t *buffer);
129 static void ibmf_saa_path_record_to_buf(void *record, uchar_t *buffer);
130 static void ibmf_saa_vlarb_record_to_buf(void *record, uchar_t *buffer);
131 static void ibmf_saa_mcmember_record_to_buf(void *record, uchar_t *buffer);
132 static void ibmf_saa_multipath_record_to_buf(void *record, uchar_t *buffer);
133 static void ibmf_saa_service_assn_record_to_buf(void *record, uchar_t *buffer);
134
135 /*
136 * *_record_parse_buffer functions:
137 *
138 * Each of these functions parses a buffer containing a single SA record.
139 * The function copies the buffer into a structure taking care of any padding
140 * and byte-endianness issues. There is one function for each of the 22
141 * attributes (Table 155).
142 *
143 * ibmf_utils_unpack_data() must be called for each structure in the structure
144 * since Solaris will align the internal structure on a 64-bit boundary, even if
145 * the first element is a 32-bit value.
146 *
147 * Input Arguments
148 * buffer pointer character array containing raw data
149 *
150 * Output Arguments
151 * record pointer to the SA attribute structure
152 *
153 * Returns void
154 */
155
156 static void
ibmf_saa_classportinfo_parse_buffer(uchar_t * buffer,void * record)157 ibmf_saa_classportinfo_parse_buffer(uchar_t *buffer, void *record)
158 {
159 ib_mad_classportinfo_t *cpi = (ib_mad_classportinfo_t *)record;
160
161 ibmf_utils_unpack_data("2csl2Ll2s2l2Ll2s2l", buffer,
162 IB_MAD_CLASSPORTINFO_SIZE, cpi, sizeof (ib_mad_classportinfo_t));
163 }
164
165 static void
ibmf_saa_notice_parse_buffer(uchar_t * buffer,void * record)166 ibmf_saa_notice_parse_buffer(uchar_t *buffer, void *record)
167 {
168 ib_mad_notice_t *notice = (ib_mad_notice_t *)record;
169
170 ibmf_utils_unpack_data("4c3s54c2L", buffer, IB_MAD_NOTICE_SIZE,
171 notice, sizeof (ib_mad_notice_t));
172 }
173
174 static void
ibmf_saa_informinfo_parse_buffer(uchar_t * buffer,void * record)175 ibmf_saa_informinfo_parse_buffer(uchar_t *buffer, void *record)
176 {
177 ib_mad_informinfo_t *informinfo = (ib_mad_informinfo_t *)record;
178
179 ibmf_utils_unpack_data("2L3s2c2s2l", buffer, IB_MAD_INFORMINFO_SIZE,
180 informinfo, sizeof (ib_mad_informinfo_t));
181 }
182
183 static void
ibmf_saa_node_record_parse_buffer(uchar_t * buffer,void * record)184 ibmf_saa_node_record_parse_buffer(uchar_t *buffer, void *record)
185 {
186 sa_node_record_t *node_record = (sa_node_record_t *)record;
187
188 /* first get record identifier information */
189 ibmf_utils_unpack_data("2s", buffer, IBMF_SAA_DEFAULT_RID_SIZE,
190 node_record, 4);
191
192 buffer += IBMF_SAA_DEFAULT_RID_SIZE;
193
194 /* next get node info */
195 ibmf_utils_unpack_data("4c3L2s2l", buffer, SM_NODEINFO_SIZE,
196 &node_record->NodeInfo, sizeof (sm_nodeinfo_t));
197
198 buffer += SM_NODEINFO_SIZE;
199
200 ibmf_utils_unpack_data("64c", buffer, SM_NODEDESC_SIZE,
201 &node_record->NodeDescription, sizeof (sm_nodedesc_t));
202 }
203
204 static void
ibmf_saa_portinfo_record_parse_buffer(uchar_t * buffer,void * record)205 ibmf_saa_portinfo_record_parse_buffer(uchar_t *buffer, void *record)
206 {
207
208 sa_portinfo_record_t *portinfo_record =
209 (sa_portinfo_record_t *)record;
210
211 /* first get record identifier information */
212 ibmf_utils_unpack_data("s2c", buffer, IBMF_SAA_DEFAULT_RID_SIZE,
213 portinfo_record, 4);
214
215 buffer += IBMF_SAA_DEFAULT_RID_SIZE;
216
217 /* next get portinfo info */
218 ibmf_utils_unpack_data("LLsslss16c3s4c", buffer, SM_PORTINFO_SIZE,
219 &portinfo_record->PortInfo, sizeof (sm_portinfo_t));
220 }
221
222 static void
ibmf_saa_SLtoVLmapping_record_parse_buffer(uchar_t * buffer,void * record)223 ibmf_saa_SLtoVLmapping_record_parse_buffer(uchar_t *buffer, void *record)
224 {
225
226 sa_SLtoVLmapping_record_t *SLtoVLmapping_record =
227 (sa_SLtoVLmapping_record_t *)record;
228
229 /* first get record identifier information (plus 4 bytes reserved) */
230 ibmf_utils_unpack_data("s2cl", buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4,
231 SLtoVLmapping_record, 8);
232
233 /* SLtoVL mapping has 4 reserved bytes between RID and attribute */
234 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4;
235
236 /* next get SLtoVLmapping info */
237 ibmf_utils_unpack_data("8c", buffer, SM_SLTOVL_SIZE,
238 &SLtoVLmapping_record->SLtoVLMappingTable,
239 sizeof (sm_SLtoVL_mapping_table_t));
240 }
241
242 static void
ibmf_saa_switchinfo_record_parse_buffer(uchar_t * buffer,void * record)243 ibmf_saa_switchinfo_record_parse_buffer(uchar_t *buffer, void *record)
244 {
245
246 sa_switchinfo_record_t *switchinfo_record =
247 (sa_switchinfo_record_t *)record;
248
249 /* first get record identifier information */
250 ibmf_utils_unpack_data("2s", buffer, IBMF_SAA_DEFAULT_RID_SIZE,
251 switchinfo_record, 4);
252
253 buffer += IBMF_SAA_DEFAULT_RID_SIZE;
254
255 /* next get switchinfo info */
256 ibmf_utils_unpack_data("4s4c2sc", buffer, SM_SWITCHINFO_SIZE,
257 &switchinfo_record->SwitchInfo, sizeof (sm_switchinfo_t));
258
259 }
260
261 static void
ibmf_saa_linearft_record_parse_buffer(uchar_t * buffer,void * record)262 ibmf_saa_linearft_record_parse_buffer(uchar_t *buffer, void *record)
263 {
264
265 sa_linearft_record_t *linearft_record =
266 (sa_linearft_record_t *)record;
267
268 /* first get record identifier information (plus 4 bytes reserved) */
269 ibmf_utils_unpack_data("2sl", buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4,
270 linearft_record, 8);
271
272 /* LFT has 4 reserved bytes between RID and attribute */
273 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4;
274
275 /* next get linearft info */
276 ibmf_utils_unpack_data("64c", buffer, SM_LINEARFDB_SIZE,
277 &linearft_record->LinearFT, sizeof (sm_linear_forwarding_table_t));
278 }
279
280 static void
ibmf_saa_randomft_record_parse_buffer(uchar_t * buffer,void * record)281 ibmf_saa_randomft_record_parse_buffer(uchar_t *buffer, void *record)
282 {
283
284 sa_randomft_record_t *randomft_record =
285 (sa_randomft_record_t *)record;
286
287 /* first get record identifier information (plus 4 bytes reserved) */
288 ibmf_utils_unpack_data("2sl", buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4,
289 randomft_record, 8);
290
291 /* RFT has 4 reserved bytes between RID and attribute */
292 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4;
293
294 /* next get randomft info */
295 ibmf_utils_unpack_data("64c", buffer, SM_RANDOMFDB_SIZE,
296 &randomft_record->RandomFT, sizeof (sm_random_forwarding_table_t));
297 }
298
299 static void
ibmf_saa_multicastft_record_parse_buffer(uchar_t * buffer,void * record)300 ibmf_saa_multicastft_record_parse_buffer(uchar_t *buffer, void *record)
301 {
302
303 sa_multicastft_record_t *multicastft_record =
304 (sa_multicastft_record_t *)record;
305
306 /* first get record identifier information (plus 4 bytes reserved) */
307 ibmf_utils_unpack_data("2sl", buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4,
308 multicastft_record, 8);
309
310 /* MFT has 4 reserved bytes between RID and attribute */
311 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4;
312
313 /* next get multicastft info */
314 ibmf_utils_unpack_data("32s", buffer, SM_MULTICASTFDB_SIZE,
315 &multicastft_record->MulticastFT,
316 sizeof (sm_multicast_forwarding_table_t));
317 }
318
319 static void
ibmf_saa_sminfo_record_parse_buffer(uchar_t * buffer,void * record)320 ibmf_saa_sminfo_record_parse_buffer(uchar_t *buffer, void *record)
321 {
322
323 sa_sminfo_record_t *sminfo_record =
324 (sa_sminfo_record_t *)record;
325
326 /* first get record identifier information */
327 ibmf_utils_unpack_data("2s", buffer, IBMF_SAA_DEFAULT_RID_SIZE,
328 sminfo_record, 4);
329
330 buffer += IBMF_SAA_DEFAULT_RID_SIZE;
331
332 /* next get sminfo info */
333 ibmf_utils_unpack_data("2Llc", buffer, SM_SMINFO_SIZE,
334 &sminfo_record->SMInfo,
335 sizeof (sm_sminfo_t));
336 }
337
338 static void
ibmf_saa_informinfo_record_parse_buffer(uchar_t * buffer,void * record)339 ibmf_saa_informinfo_record_parse_buffer(uchar_t *buffer, void *record)
340 {
341
342 sa_informinfo_record_t *informinfo_record =
343 (sa_informinfo_record_t *)record;
344
345 /* first get record identifier information */
346 ibmf_utils_unpack_data("2Ls", buffer, IBMF_SAA_INFORMINFO_RID_SIZE,
347 informinfo_record, 18);
348
349 /* InformInfo has 6 reserved bytes between RID and attribute */
350 buffer += IBMF_SAA_INFORMINFO_RID_SIZE + 6;
351
352 /* next get informinfo info */
353 ibmf_utils_unpack_data("2L3s2c2s2l", buffer, IB_MAD_INFORMINFO_SIZE,
354 &informinfo_record->InformInfo,
355 sizeof (ib_mad_informinfo_t));
356 }
357
358 static void
ibmf_saa_link_record_parse_buffer(uchar_t * buffer,void * record)359 ibmf_saa_link_record_parse_buffer(uchar_t *buffer, void *record)
360 {
361
362 sa_link_record_t *link_record = (sa_link_record_t *)record;
363
364 ibmf_utils_unpack_data("s2cs", buffer, IBMF_SAA_LINK_RECORD_SIZE,
365 link_record, sizeof (sa_link_record_t));
366 }
367
368 static void
ibmf_saa_guidinfo_record_parse_buffer(uchar_t * buffer,void * record)369 ibmf_saa_guidinfo_record_parse_buffer(uchar_t *buffer, void *record)
370 {
371
372 sa_guidinfo_record_t *guidinfo_record =
373 (sa_guidinfo_record_t *)record;
374
375 /* first get record identifier information (plus 4 bytes reserved) */
376 ibmf_utils_unpack_data("s2cl", buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4,
377 guidinfo_record, 8);
378
379 /* GUIDInfo has 4 reserved bytes between RID and attribute */
380 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4;
381
382 /* next get guidinfo info */
383 ibmf_utils_unpack_data("8L", buffer, SM_GUIDINFO_SIZE,
384 &guidinfo_record->GUIDInfo, sizeof (sm_guidinfo_t));
385 }
386
387 static void
ibmf_saa_service_record_parse_buffer(uchar_t * buffer,void * record)388 ibmf_saa_service_record_parse_buffer(uchar_t *buffer, void *record)
389 {
390
391 sa_service_record_t *service_record = (sa_service_record_t *)record;
392
393 ibmf_utils_unpack_data("3L2sl2L64c16c8s4l2L", buffer,
394 IBMF_SAA_SERVICE_RECORD_SIZE, service_record,
395 sizeof (sa_service_record_t));
396 }
397
398 static void
ibmf_saa_partition_record_parse_buffer(uchar_t * buffer,void * record)399 ibmf_saa_partition_record_parse_buffer(uchar_t *buffer, void *record)
400 {
401
402 sa_pkey_table_record_t *partition_record =
403 (sa_pkey_table_record_t *)record;
404
405 /* first get record identifier information (plus 4 bytes reserved) */
406 ibmf_utils_unpack_data("2s4c", buffer, IBMF_SAA_PARTITION_RID_SIZE + 3,
407 partition_record, 8);
408
409 /* Partition record has 3 reserved bytes between RID and attribute */
410 buffer += IBMF_SAA_PARTITION_RID_SIZE + 3;
411
412 /* next get partition info */
413 ibmf_utils_unpack_data("32s", buffer, SM_PARTITION_SIZE,
414 &partition_record->P_KeyTable, sizeof (sm_pkey_table_t));
415 }
416
417 static void
ibmf_saa_path_record_parse_buffer(uchar_t * buffer,void * record)418 ibmf_saa_path_record_parse_buffer(uchar_t *buffer, void *record)
419 {
420
421 sa_path_record_t *path_record = (sa_path_record_t *)record;
422
423 ibmf_utils_unpack_data("2l4L2sl2c2s4c", buffer,
424 IBMF_SAA_PATH_RECORD_SIZE, path_record, sizeof (sa_path_record_t));
425 }
426
427 static void
ibmf_saa_vlarb_record_parse_buffer(uchar_t * buffer,void * record)428 ibmf_saa_vlarb_record_parse_buffer(uchar_t *buffer, void *record)
429 {
430
431 sa_VLarb_table_record_t *VLarb_table_record =
432 (sa_VLarb_table_record_t *)record;
433
434 /* first get record identifier information (plus 4 bytes reserved) */
435 ibmf_utils_unpack_data("s2c", buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4,
436 VLarb_table_record, 8);
437
438 /* VLarb record has 4 reserved bytes between RID and attribute */
439 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4;
440
441 /* next get VLarb_table info */
442 ibmf_utils_unpack_data("64c", buffer, SM_VLARB_SIZE,
443 &VLarb_table_record->VLArbTable,
444 sizeof (sm_VLarb_table_t));
445 }
446
447 static void
ibmf_saa_mcmember_record_parse_buffer(uchar_t * buffer,void * record)448 ibmf_saa_mcmember_record_parse_buffer(uchar_t *buffer, void *record)
449 {
450
451 sa_mcmember_record_t *mcmember_record =
452 (sa_mcmember_record_t *)record;
453
454 ibmf_utils_unpack_data("4Lls2cs2c2l", buffer,
455 IBMF_SAA_MCMEMBER_RECORD_SIZE,
456 mcmember_record, sizeof (sa_mcmember_record_t));
457 }
458
459 static void
ibmf_saa_trace_record_parse_buffer(uchar_t * buffer,void * record)460 ibmf_saa_trace_record_parse_buffer(uchar_t *buffer, void *record)
461 {
462
463 sa_trace_record_t *trace_record =
464 (sa_trace_record_t *)record;
465
466 ibmf_utils_unpack_data("Ls2c4L2c", buffer,
467 IBMF_SAA_TRACE_RECORD_SIZE,
468 trace_record, sizeof (sa_trace_record_t));
469 }
470
471 /*
472 * ibmf_saa_multipath_record_parse_buffer:
473 *
474 * First unpack the standard part of the multipath record. Then find the number
475 * of gids and unpack those. This function will probably never be called as the
476 * ibmf_saa should not receive any multipath records. It's in here for
477 * completeness.
478 */
ibmf_saa_multipath_record_parse_buffer(uchar_t * buffer,void * record)479 static void ibmf_saa_multipath_record_parse_buffer(uchar_t *buffer,
480 void *record)
481 {
482 char gid_str[20];
483 uint16_t num_gids;
484
485 sa_multipath_record_t *multipath_record =
486 (sa_multipath_record_t *)record;
487
488 ibmf_utils_unpack_data("l2c2s14c", buffer,
489 IBMF_SAA_MULTIPATH_RECORD_SIZE, multipath_record,
490 sizeof (sa_multipath_record_t));
491
492 num_gids = multipath_record->SGIDCount + multipath_record->DGIDCount;
493
494 (void) sprintf(gid_str, "%dL", 2 * num_gids);
495
496 ibmf_utils_unpack_data(gid_str, buffer + IBMF_SAA_MULTIPATH_RECORD_SIZE,
497 sizeof (ib_gid_t) * num_gids,
498 multipath_record + sizeof (sa_multipath_record_t),
499 sizeof (ib_gid_t) * num_gids);
500
501 }
502
503 static void
ibmf_saa_service_assn_record_parse_buffer(uchar_t * buffer,void * record)504 ibmf_saa_service_assn_record_parse_buffer(uchar_t *buffer, void *record)
505 {
506
507 sa_service_assn_record_t *service_assn_record =
508 (sa_service_assn_record_t *)record;
509
510 ibmf_utils_unpack_data("2L64c", buffer,
511 IBMF_SAA_SERVICEASSN_RECORD_SIZE,
512 service_assn_record, sizeof (sa_service_assn_record_t));
513 }
514
515 void
ibmf_saa_gid_trap_parse_buffer(uchar_t * buffer,sm_trap_64_t * sm_trap_64)516 ibmf_saa_gid_trap_parse_buffer(uchar_t *buffer, sm_trap_64_t *sm_trap_64)
517 {
518
519 ibmf_utils_unpack_data("6c2L32c", buffer, SM_TRAP_DATA_DETAILS_SIZE,
520 sm_trap_64, sizeof (sm_trap_64_t));
521 }
522
523 void
ibmf_saa_capmask_chg_trap_parse_buffer(uchar_t * buffer,sm_trap_144_t * sm_trap_144)524 ibmf_saa_capmask_chg_trap_parse_buffer(uchar_t *buffer,
525 sm_trap_144_t *sm_trap_144)
526 {
527
528 ibmf_utils_unpack_data("2cs2cl44c", buffer, SM_TRAP_DATA_DETAILS_SIZE,
529 sm_trap_144, sizeof (sm_trap_144_t));
530 }
531
532 void
ibmf_saa_sysimg_guid_chg_trap_parse_buffer(uchar_t * buffer,sm_trap_145_t * sm_trap_145)533 ibmf_saa_sysimg_guid_chg_trap_parse_buffer(uchar_t *buffer,
534 sm_trap_145_t *sm_trap_145)
535 {
536
537 ibmf_utils_unpack_data("2cs2cL44c", buffer, SM_TRAP_DATA_DETAILS_SIZE,
538 sm_trap_145, sizeof (sm_trap_145_t));
539 }
540
541 /*
542 * *_record_to_buf functions:
543 *
544 * Each of these functions copies a single SA record out of a structure and into
545 * a buffer for sending on the wire. The function will take care of any padding
546 * and byte-endianness isues. There is one function for each of the 22
547 * attributes (Table 155).
548 *
549 * ibmf_utils_pack_data() must be called for each structure in the structure
550 * since Solaris will align the internal structure on a 64-bit boundary, even if
551 * the first element is a 32-bit value.
552 *
553 * Input Arguments
554 * record pointer to the structure to be parsed
555 *
556 * Output Arguments
557 * buffer pointer to array to place the data in (allocated by caller)
558 *
559 * Returns void
560 */
561
562 static void
ibmf_saa_classportinfo_to_buf(void * record,uchar_t * buffer)563 ibmf_saa_classportinfo_to_buf(void *record, uchar_t *buffer)
564 {
565 ib_mad_classportinfo_t *cpi = (ib_mad_classportinfo_t *)record;
566
567 ibmf_utils_pack_data("2csl2Ll2s2l2Ll2s2l",
568 cpi, sizeof (ib_mad_classportinfo_t),
569 buffer, IB_MAD_CLASSPORTINFO_SIZE);
570 }
571
572 static void
ibmf_saa_notice_to_buf(void * record,uchar_t * buffer)573 ibmf_saa_notice_to_buf(void *record, uchar_t *buffer)
574 {
575 ib_mad_notice_t *notice = (ib_mad_notice_t *)record;
576
577 ibmf_utils_pack_data("4c3s54c2L", notice, sizeof (ib_mad_notice_t),
578 buffer, IB_MAD_NOTICE_SIZE);
579 }
580
581 static void
ibmf_saa_informinfo_to_buf(void * record,uchar_t * buffer)582 ibmf_saa_informinfo_to_buf(void *record, uchar_t *buffer)
583 {
584 ib_mad_informinfo_t *informinfo = (ib_mad_informinfo_t *)record;
585
586 ibmf_utils_pack_data("2L3s2c2s2l", informinfo,
587 sizeof (ib_mad_informinfo_t), buffer, IB_MAD_INFORMINFO_SIZE);
588 }
589
590 static void
ibmf_saa_node_record_to_buf(void * record,uchar_t * buffer)591 ibmf_saa_node_record_to_buf(void *record, uchar_t *buffer)
592 {
593
594 sa_node_record_t *node_record = (sa_node_record_t *)record;
595
596 /* first get record identifier information */
597 ibmf_utils_pack_data("2s", node_record, 4, buffer,
598 IBMF_SAA_DEFAULT_RID_SIZE);
599
600 buffer += IBMF_SAA_DEFAULT_RID_SIZE;
601
602 /* next get node info */
603 ibmf_utils_pack_data("4c3L2s2l", &node_record->NodeInfo,
604 sizeof (sm_nodeinfo_t), buffer, SM_NODEINFO_SIZE);
605
606 buffer += SM_NODEINFO_SIZE;
607
608 /* next get node description */
609 ibmf_utils_pack_data("64c", &node_record->NodeDescription,
610 sizeof (sm_nodedesc_t), buffer, SM_NODEDESC_SIZE);
611
612 }
613
614 static void
ibmf_saa_portinfo_record_to_buf(void * record,uchar_t * buffer)615 ibmf_saa_portinfo_record_to_buf(void *record, uchar_t *buffer)
616 {
617
618 sa_portinfo_record_t *portinfo_record =
619 (sa_portinfo_record_t *)record;
620
621 /* first get record identifier information */
622 ibmf_utils_pack_data("s2c", portinfo_record, 4, buffer,
623 IBMF_SAA_DEFAULT_RID_SIZE);
624
625 buffer += IBMF_SAA_DEFAULT_RID_SIZE;
626
627 /* next get portinfo info */
628 ibmf_utils_pack_data("LLsslss16c3s4c",
629 &portinfo_record->PortInfo, sizeof (sm_portinfo_t), buffer,
630 SM_PORTINFO_SIZE);
631
632 }
633
634 static void
ibmf_saa_SLtoVLmapping_record_to_buf(void * record,uchar_t * buffer)635 ibmf_saa_SLtoVLmapping_record_to_buf(void *record, uchar_t *buffer)
636 {
637
638 sa_SLtoVLmapping_record_t *SLtoVLmapping_record =
639 (sa_SLtoVLmapping_record_t *)record;
640
641 /* first get record identifier information (plus 4 bytes reserved) */
642 ibmf_utils_pack_data("s2cl", SLtoVLmapping_record, 8, buffer,
643 IBMF_SAA_DEFAULT_RID_SIZE + 4);
644
645 /* SLtoVL mapping has 4 reserved bytes between RID and attribute */
646 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4;
647
648 /* next get SLtoVLmapping info */
649 ibmf_utils_pack_data("8c", &SLtoVLmapping_record->SLtoVLMappingTable,
650 sizeof (sm_SLtoVL_mapping_table_t), buffer, SM_SLTOVL_SIZE);
651 }
652
653 static void
ibmf_saa_switchinfo_record_to_buf(void * record,uchar_t * buffer)654 ibmf_saa_switchinfo_record_to_buf(void *record, uchar_t *buffer)
655 {
656
657 sa_switchinfo_record_t *switchinfo_record =
658 (sa_switchinfo_record_t *)record;
659
660 /* first get record identifier information */
661 ibmf_utils_pack_data("2s", switchinfo_record, 4, buffer,
662 IBMF_SAA_DEFAULT_RID_SIZE);
663
664 buffer += IBMF_SAA_DEFAULT_RID_SIZE;
665
666 /* next get switchinfo info */
667 ibmf_utils_pack_data("4s4c2sc", &switchinfo_record->SwitchInfo,
668 sizeof (sm_switchinfo_t), buffer, SM_SWITCHINFO_SIZE);
669
670 }
671
672 static void
ibmf_saa_linearft_record_to_buf(void * record,uchar_t * buffer)673 ibmf_saa_linearft_record_to_buf(void *record, uchar_t *buffer)
674 {
675
676 sa_linearft_record_t *linearft_record =
677 (sa_linearft_record_t *)record;
678
679 /* first get record identifier information (plus 4 bytes reserved) */
680 ibmf_utils_pack_data("2sl", linearft_record, 8, buffer,
681 IBMF_SAA_DEFAULT_RID_SIZE + 4);
682
683 /* LFT has 4 reserved bytes between RID and attribute */
684 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4;
685
686 /* next get linearft info */
687 ibmf_utils_pack_data("64c", &linearft_record->LinearFT,
688 sizeof (sm_linear_forwarding_table_t), buffer, SM_LINEARFDB_SIZE);
689 }
690
691 static void
ibmf_saa_randomft_record_to_buf(void * record,uchar_t * buffer)692 ibmf_saa_randomft_record_to_buf(void *record, uchar_t *buffer)
693 {
694
695 sa_randomft_record_t *randomft_record =
696 (sa_randomft_record_t *)record;
697
698 /* first get record identifier information (plus 4 bytes reserved) */
699 ibmf_utils_pack_data("2sl", randomft_record, 8, buffer,
700 IBMF_SAA_DEFAULT_RID_SIZE + 4);
701
702 /* RFT has 4 reserved bytes between RID and attribute */
703 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4;
704
705 /* next get randomft info */
706 ibmf_utils_pack_data("64c", &randomft_record->RandomFT,
707 sizeof (sm_random_forwarding_table_t), buffer, SM_RANDOMFDB_SIZE);
708 }
709
710 static void
ibmf_saa_multicastft_record_to_buf(void * record,uchar_t * buffer)711 ibmf_saa_multicastft_record_to_buf(void *record, uchar_t *buffer)
712 {
713
714 sa_multicastft_record_t *multicastft_record =
715 (sa_multicastft_record_t *)record;
716
717 /* first get record identifier information (plus 4 bytes reserved) */
718 ibmf_utils_pack_data("2sl", multicastft_record, 8, buffer,
719 IBMF_SAA_DEFAULT_RID_SIZE + 4);
720
721 /* MFT has 4 reserved bytes between RID and attribute */
722 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4;
723
724 /* next get multicastft info */
725 ibmf_utils_pack_data("32s", &multicastft_record->MulticastFT,
726 sizeof (sm_multicast_forwarding_table_t), buffer,
727 SM_MULTICASTFDB_SIZE);
728 }
729
730 static void
ibmf_saa_sminfo_record_to_buf(void * record,uchar_t * buffer)731 ibmf_saa_sminfo_record_to_buf(void *record, uchar_t *buffer)
732 {
733
734 sa_sminfo_record_t *sminfo_record =
735 (sa_sminfo_record_t *)record;
736
737 /* first get record identifier information */
738 ibmf_utils_pack_data("2s", sminfo_record, 4, buffer,
739 IBMF_SAA_DEFAULT_RID_SIZE);
740
741 buffer += IBMF_SAA_DEFAULT_RID_SIZE;
742
743 /* next get sminfo info */
744 ibmf_utils_pack_data("2Llc", &sminfo_record->SMInfo,
745 sizeof (sm_sminfo_t), buffer, SM_SMINFO_SIZE);
746 }
747
748 static void
ibmf_saa_informinfo_record_to_buf(void * record,uchar_t * buffer)749 ibmf_saa_informinfo_record_to_buf(void *record, uchar_t *buffer)
750 {
751
752 sa_informinfo_record_t *informinfo_record =
753 (sa_informinfo_record_t *)record;
754
755 /* first get record identifier information */
756 ibmf_utils_pack_data("2Ls", informinfo_record, 18, buffer,
757 IBMF_SAA_INFORMINFO_RID_SIZE);
758
759 /* InformInfo has 6 reserved bytes between RID and attribute */
760 buffer += IBMF_SAA_INFORMINFO_RID_SIZE + 6;
761
762 /* next get informinfo info */
763 ibmf_utils_pack_data("2L3s2c2s2l", &informinfo_record->InformInfo,
764 sizeof (ib_mad_informinfo_t), buffer, IB_MAD_INFORMINFO_SIZE);
765 }
766
767 static void
ibmf_saa_link_record_to_buf(void * record,uchar_t * buffer)768 ibmf_saa_link_record_to_buf(void *record, uchar_t *buffer)
769 {
770
771 sa_link_record_t *link_record = (sa_link_record_t *)record;
772
773 ibmf_utils_pack_data("s2cs", link_record,
774 sizeof (sa_link_record_t), buffer, IBMF_SAA_LINK_RECORD_SIZE);
775 }
776
777 static void
ibmf_saa_guidinfo_record_to_buf(void * record,uchar_t * buffer)778 ibmf_saa_guidinfo_record_to_buf(void *record, uchar_t *buffer)
779 {
780
781 sa_guidinfo_record_t *guidinfo_record =
782 (sa_guidinfo_record_t *)record;
783
784 /* first get record identifier information (plus 4 bytes reserved) */
785 ibmf_utils_pack_data("s2cl", guidinfo_record,
786 8, buffer, IBMF_SAA_DEFAULT_RID_SIZE + 4);
787
788 /* GUIDInfo has 4 reserved bytes between RID and attribute */
789 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4;
790
791 /* next get guidinfo info */
792 ibmf_utils_pack_data("8L", &guidinfo_record->GUIDInfo,
793 sizeof (sm_guidinfo_t), buffer, SM_GUIDINFO_SIZE);
794 }
795
796 static void
ibmf_saa_service_record_to_buf(void * record,uchar_t * buffer)797 ibmf_saa_service_record_to_buf(void *record, uchar_t *buffer)
798 {
799
800 sa_service_record_t *service_record = (sa_service_record_t *)record;
801
802 ibmf_utils_pack_data("3L2sl2L64c16c8s4l2L", service_record,
803 sizeof (sa_service_record_t), buffer, IBMF_SAA_SERVICE_RECORD_SIZE);
804 }
805
806 static void
ibmf_saa_partition_record_to_buf(void * record,uchar_t * buffer)807 ibmf_saa_partition_record_to_buf(void *record, uchar_t *buffer)
808 {
809
810 sa_pkey_table_record_t *partition_record =
811 (sa_pkey_table_record_t *)record;
812
813 /* first get record identifier information (plus 4 bytes reserved) */
814 ibmf_utils_pack_data("2s4c", partition_record, 8, buffer,
815 IBMF_SAA_PARTITION_RID_SIZE + 3);
816
817 /* Partition record has 3 reserved bytes between RID and attribute */
818 buffer += IBMF_SAA_PARTITION_RID_SIZE + 3;
819
820 /* next get partition info */
821 ibmf_utils_pack_data("32s", &partition_record->P_KeyTable,
822 sizeof (sm_pkey_table_t), buffer, SM_PARTITION_SIZE);
823 }
824
825 static void
ibmf_saa_path_record_to_buf(void * record,uchar_t * buffer)826 ibmf_saa_path_record_to_buf(void *record, uchar_t *buffer)
827 {
828
829 sa_path_record_t *path_record = (sa_path_record_t *)record;
830
831 ibmf_utils_pack_data("2l4L2sl2c2s4c", path_record,
832 sizeof (sa_path_record_t), buffer, IBMF_SAA_PATH_RECORD_SIZE);
833 }
834
835 static void
ibmf_saa_vlarb_record_to_buf(void * record,uchar_t * buffer)836 ibmf_saa_vlarb_record_to_buf(void *record, uchar_t *buffer)
837 {
838
839 sa_VLarb_table_record_t *VLarb_table_record =
840 (sa_VLarb_table_record_t *)record;
841
842 /* first get record identifier information (plus 4 bytes reserved) */
843 ibmf_utils_pack_data("s2c", VLarb_table_record, 8, buffer,
844 IBMF_SAA_DEFAULT_RID_SIZE + 4);
845
846 /* VLarb record has 4 reserved bytes between RID and attribute */
847 buffer += IBMF_SAA_DEFAULT_RID_SIZE + 4;
848
849 /* next get VLarb_table info */
850 ibmf_utils_pack_data("64c", &VLarb_table_record->VLArbTable,
851 sizeof (sm_VLarb_table_t), buffer, SM_VLARB_SIZE);
852 }
853
854
855 static void
ibmf_saa_mcmember_record_to_buf(void * record,uchar_t * buffer)856 ibmf_saa_mcmember_record_to_buf(void *record, uchar_t *buffer)
857 {
858
859 sa_mcmember_record_t *mcmember_record =
860 (sa_mcmember_record_t *)record;
861
862 ibmf_utils_pack_data("4Lls2cs2c2l", mcmember_record,
863 sizeof (sa_mcmember_record_t),
864 buffer, IBMF_SAA_MCMEMBER_RECORD_SIZE);
865 }
866
ibmf_saa_multipath_record_to_buf(void * record,uchar_t * buffer)867 static void ibmf_saa_multipath_record_to_buf(void *record, uchar_t *buffer)
868 {
869 char gid_str[20];
870 uint16_t num_gids;
871 sa_multipath_record_t *multipath_record =
872 (sa_multipath_record_t *)record;
873
874 num_gids = multipath_record->SGIDCount + multipath_record->DGIDCount;
875
876 (void) sprintf(gid_str, "l2c2s14c%dL", 2 * num_gids);
877
878 ibmf_utils_pack_data(gid_str, multipath_record,
879 sizeof (sa_multipath_record_t) + sizeof (ib_gid_t) * num_gids,
880 buffer,
881 IBMF_SAA_MULTIPATH_RECORD_SIZE + sizeof (ib_gid_t) * num_gids);
882 }
883
884 static void
ibmf_saa_service_assn_record_to_buf(void * record,uchar_t * buffer)885 ibmf_saa_service_assn_record_to_buf(void *record, uchar_t *buffer)
886 {
887
888 sa_service_assn_record_t *service_assn_record =
889 (sa_service_assn_record_t *)record;
890
891 ibmf_utils_pack_data("2L64c", service_assn_record,
892 sizeof (sa_service_assn_record_t),
893 buffer, IBMF_SAA_SERVICEASSN_RECORD_SIZE);
894 }
895
896 int
ibmf_saa_utils_pack_sa_hdr(ib_sa_hdr_t * sa_hdr,void ** packed_class_hdr,size_t * packed_class_hdr_len,int km_sleep_flag)897 ibmf_saa_utils_pack_sa_hdr(ib_sa_hdr_t *sa_hdr, void **packed_class_hdr,
898 size_t *packed_class_hdr_len, int km_sleep_flag)
899 {
900
901 *packed_class_hdr = kmem_zalloc(IBMF_SAA_HDR_SIZE, km_sleep_flag);
902 if (*packed_class_hdr == NULL) {
903
904 IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L1,
905 ibmf_saa_utils_pack_sa_hdr_err,
906 IBMF_TNF_ERROR, "", "ibmf_saa_utils_pack_sa_hdr: "
907 "could not allocate memory for header\n");
908
909 return (IBMF_NO_MEMORY);
910 }
911
912 ibmf_utils_pack_data("LssL", sa_hdr, sizeof (ib_sa_hdr_t),
913 (uchar_t *)*packed_class_hdr, IBMF_SAA_HDR_SIZE);
914
915 *packed_class_hdr_len = IBMF_SAA_HDR_SIZE;
916
917 return (IBMF_SUCCESS);
918 }
919
920 int
ibmf_saa_utils_unpack_sa_hdr(void * packed_class_hdr,size_t packed_class_hdr_len,ib_sa_hdr_t ** sa_hdr,int km_sleep_flag)921 ibmf_saa_utils_unpack_sa_hdr(void *packed_class_hdr,
922 size_t packed_class_hdr_len, ib_sa_hdr_t **sa_hdr, int km_sleep_flag)
923 {
924 if (packed_class_hdr_len != IBMF_SAA_HDR_SIZE) {
925
926 IBMF_TRACE_3(IBMF_TNF_DEBUG, DPRINT_L1,
927 ibmf_saa_utils_unpack_sa_hdr_err,
928 IBMF_TNF_ERROR, "", "ibmf_saa_utils_unpack_sa_hdr: %s,"
929 " sa_class_hdr_len = %d, pkt_class_hdr_len = %d\n",
930 tnf_string, msg, "invalid class hdr length for SA packet",
931 tnf_int, sa_class_hdr_len, IBMF_SAA_HDR_SIZE,
932 tnf_int, pkt_class_hdr_len, packed_class_hdr_len);
933
934 return (IBMF_REQ_INVALID);
935 }
936
937 *sa_hdr = kmem_zalloc(sizeof (ib_sa_hdr_t), km_sleep_flag);
938 if (*sa_hdr == NULL) {
939
940 IBMF_TRACE_0(IBMF_TNF_DEBUG, DPRINT_L1,
941 ibmf_saa_utils_unpack_sa_hdr_err,
942 IBMF_TNF_ERROR, "", "ibmf_saa_utils_unpack_sa_hdr: "
943 "could not allocate memory for header\n");
944
945 return (IBMF_NO_MEMORY);
946 }
947
948 ibmf_utils_unpack_data("LssL", (uchar_t *)packed_class_hdr,
949 IBMF_SAA_HDR_SIZE, *sa_hdr, sizeof (ib_sa_hdr_t));
950
951 return (IBMF_SUCCESS);
952 }
953
954 /*
955 * ibmf_saa_utils_pack_payload:
956 *
957 * Takes a pointer to an array of sa record structures. For each element packs
958 * the structure into a character buffer removing any padding and account for
959 * endianness issues.
960 *
961 */
962 int
ibmf_saa_utils_pack_payload(uchar_t * structs_payload,size_t structs_payload_length,uint16_t attr_id,void ** buf_payloadp,size_t * buf_payload_lengthp,int km_sleep_flag)963 ibmf_saa_utils_pack_payload(uchar_t *structs_payload, size_t
964 structs_payload_length, uint16_t attr_id, void **buf_payloadp,
965 size_t *buf_payload_lengthp, int km_sleep_flag)
966 {
967
968 int i;
969 int struct_size, buf_size;
970 int num_records;
971 void (*pack_data_fn)(void *, uchar_t *);
972
973 if (structs_payload_length == 0) {
974
975 *buf_payload_lengthp = 0;
976 *buf_payloadp = NULL;
977
978 return (IBMF_SUCCESS);
979 }
980
981 ASSERT(structs_payload != NULL);
982
983 /* trace records should never be sent (or packed) by ibmf_saa */
984 ASSERT(attr_id != SA_TRACERECORD_ATTRID);
985
986 switch (attr_id) {
987 case SA_CLASSPORTINFO_ATTRID:
988 struct_size = sizeof (ib_mad_classportinfo_t);
989 buf_size = IB_MAD_CLASSPORTINFO_SIZE;
990 pack_data_fn = ibmf_saa_classportinfo_to_buf;
991 break;
992 case SA_NOTICE_ATTRID:
993 struct_size = sizeof (ib_mad_notice_t);
994 buf_size = IB_MAD_NOTICE_SIZE;
995 pack_data_fn = ibmf_saa_notice_to_buf;
996 break;
997 case SA_INFORMINFO_ATTRID:
998 struct_size = sizeof (ib_mad_informinfo_t);
999 buf_size = IB_MAD_INFORMINFO_SIZE;
1000 pack_data_fn = ibmf_saa_informinfo_to_buf;
1001 break;
1002 case SA_NODERECORD_ATTRID:
1003 struct_size = sizeof (sa_node_record_t);
1004 buf_size = IBMF_SAA_NODE_RECORD_SIZE;
1005 pack_data_fn = ibmf_saa_node_record_to_buf;
1006 break;
1007 case SA_PORTINFORECORD_ATTRID:
1008 struct_size = sizeof (sa_portinfo_record_t);
1009 buf_size = IBMF_SAA_PORTINFO_RECORD_SIZE;
1010 pack_data_fn = ibmf_saa_portinfo_record_to_buf;
1011 break;
1012 case SA_SLTOVLRECORD_ATTRID:
1013 struct_size = sizeof (sa_SLtoVLmapping_record_t);
1014 buf_size = IBMF_SAA_SLTOVL_RECORD_SIZE;
1015 pack_data_fn = ibmf_saa_SLtoVLmapping_record_to_buf;
1016 break;
1017 case SA_SWITCHINFORECORD_ATTRID:
1018 struct_size = sizeof (sa_switchinfo_record_t);
1019 buf_size = IBMF_SAA_SWITCHINFO_RECORD_SIZE;
1020 pack_data_fn = ibmf_saa_switchinfo_record_to_buf;
1021 break;
1022 case SA_LINEARFDBRECORD_ATTRID:
1023 struct_size = sizeof (sa_linearft_record_t);
1024 buf_size = IBMF_SAA_LINEARFDB_RECORD_SIZE;
1025 pack_data_fn = ibmf_saa_linearft_record_to_buf;
1026 break;
1027 case SA_RANDOMFDBRECORD_ATTRID:
1028 struct_size = sizeof (sa_randomft_record_t);
1029 buf_size = IBMF_SAA_RANDOMFDB_RECORD_SIZE;
1030 pack_data_fn = ibmf_saa_randomft_record_to_buf;
1031 break;
1032 case SA_MULTICASTFDBRECORD_ATTRID:
1033 struct_size = sizeof (sa_multicastft_record_t);
1034 buf_size = IBMF_SAA_MULTICASTFDB_RECORD_SIZE;
1035 pack_data_fn = ibmf_saa_multicastft_record_to_buf;
1036 break;
1037 case SA_SMINFORECORD_ATTRID:
1038 struct_size = sizeof (sa_sminfo_record_t);
1039 buf_size = IBMF_SAA_SMINFO_RECORD_SIZE;
1040 pack_data_fn = ibmf_saa_sminfo_record_to_buf;
1041 break;
1042 case SA_INFORMINFORECORD_ATTRID:
1043 struct_size = sizeof (sa_informinfo_record_t);
1044 buf_size = IBMF_SAA_INFORMINFO_RECORD_SIZE;
1045 pack_data_fn = ibmf_saa_informinfo_record_to_buf;
1046 break;
1047 case SA_LINKRECORD_ATTRID:
1048 struct_size = sizeof (sa_link_record_t);
1049 buf_size = IBMF_SAA_LINK_RECORD_SIZE;
1050 pack_data_fn = ibmf_saa_link_record_to_buf;
1051 break;
1052 case SA_GUIDINFORECORD_ATTRID:
1053 struct_size = sizeof (sa_guidinfo_record_t);
1054 buf_size = IBMF_SAA_GUIDINFO_RECORD_SIZE;
1055 pack_data_fn = ibmf_saa_guidinfo_record_to_buf;
1056 break;
1057 case SA_SERVICERECORD_ATTRID:
1058 struct_size = sizeof (sa_service_record_t);
1059 buf_size = IBMF_SAA_SERVICE_RECORD_SIZE;
1060 pack_data_fn = ibmf_saa_service_record_to_buf;
1061 break;
1062 case SA_PARTITIONRECORD_ATTRID:
1063 struct_size = sizeof (sa_pkey_table_record_t);
1064 buf_size = IBMF_SAA_PARTITION_RECORD_SIZE;
1065 pack_data_fn = ibmf_saa_partition_record_to_buf;
1066 break;
1067 case SA_PATHRECORD_ATTRID:
1068 struct_size = sizeof (sa_path_record_t);
1069 buf_size = IBMF_SAA_PATH_RECORD_SIZE;
1070 pack_data_fn = ibmf_saa_path_record_to_buf;
1071 break;
1072 case SA_VLARBRECORD_ATTRID:
1073 struct_size = sizeof (sa_VLarb_table_record_t);
1074 buf_size = IBMF_SAA_VLARB_RECORD_SIZE;
1075 pack_data_fn = ibmf_saa_vlarb_record_to_buf;
1076 break;
1077 case SA_MCMEMBERRECORD_ATTRID:
1078 struct_size = sizeof (sa_mcmember_record_t);
1079 buf_size = IBMF_SAA_MCMEMBER_RECORD_SIZE;
1080 pack_data_fn = ibmf_saa_mcmember_record_to_buf;
1081 break;
1082 case SA_MULTIPATHRECORD_ATTRID:
1083 /*
1084 * array is of size 1 since multipath can be request
1085 * only; data size greater than multipath_record_t
1086 * size is due to gids at the end
1087 */
1088 struct_size = structs_payload_length;
1089 buf_size = IBMF_SAA_MULTIPATH_RECORD_SIZE +
1090 struct_size - sizeof (sa_multipath_record_t);
1091 pack_data_fn = ibmf_saa_multipath_record_to_buf;
1092 break;
1093 case SA_SERVICEASSNRECORD_ATTRID:
1094 struct_size = sizeof (sa_service_assn_record_t);
1095 buf_size = IBMF_SAA_SERVICEASSN_RECORD_SIZE;
1096 pack_data_fn = ibmf_saa_service_assn_record_to_buf;
1097 break;
1098 default:
1099
1100 /* don't know about structure; do bcopy */
1101 *buf_payload_lengthp = structs_payload_length;
1102 *buf_payloadp = kmem_zalloc(*buf_payload_lengthp,
1103 km_sleep_flag);
1104 if (*buf_payloadp == NULL) {
1105
1106 *buf_payload_lengthp = 0;
1107 return (IBMF_NO_MEMORY);
1108 }
1109
1110 bcopy(structs_payload, *buf_payloadp,
1111 *buf_payload_lengthp);
1112
1113 return (IBMF_SUCCESS);
1114 }
1115
1116 *buf_payload_lengthp = structs_payload_length / struct_size * buf_size;
1117 num_records = structs_payload_length / struct_size;
1118 *buf_payloadp = kmem_zalloc(*buf_payload_lengthp, km_sleep_flag);
1119 if (*buf_payloadp == NULL) {
1120
1121 IBMF_TRACE_2(IBMF_TNF_DEBUG, DPRINT_L1,
1122 ibmf_saa_utils_pack_payload_err,
1123 IBMF_TNF_ERROR, "", "ibmf_saa_utils_pack_payload: %s,"
1124 " size = %d\n",
1125 tnf_string, msg, "could not allocate memory for payload",
1126 tnf_int, size, *buf_payload_lengthp);
1127
1128 *buf_payload_lengthp = 0;
1129 return (IBMF_NO_MEMORY);
1130 }
1131
1132 for (i = 0; i < num_records; i++) {
1133
1134 pack_data_fn(
1135 (void *)((uchar_t *)structs_payload + i * struct_size),
1136 ((uchar_t *)*buf_payloadp + i * buf_size));
1137 }
1138
1139 return (IBMF_SUCCESS);
1140 }
1141
1142
1143 /*
1144 * ibmf_saa_utils_unpack_payload:
1145 *
1146 * Unpacks a buffer of data received over the wire and places into an array of
1147 * structure in host format.
1148 *
1149 * for getResp() ibmf always reports payload length as 200 bytes
1150 * (MAD_SIZE - headers). To keep the client from having to determine the actual
1151 * length of the one attribute (since we do it here) the is_get_resp parameter
1152 * indicates that there is one attribute in the buffer.
1153 */
1154 int
ibmf_saa_utils_unpack_payload(uchar_t * buf_payload,size_t buf_payload_length,uint16_t attr_id,void ** structs_payloadp,size_t * structs_payload_lengthp,uint16_t attr_offset,boolean_t is_get_resp,int km_sleep_flag)1155 ibmf_saa_utils_unpack_payload(uchar_t *buf_payload, size_t buf_payload_length,
1156 uint16_t attr_id, void **structs_payloadp, size_t *structs_payload_lengthp,
1157 uint16_t attr_offset, boolean_t is_get_resp, int km_sleep_flag)
1158 {
1159
1160 int i;
1161 int struct_size, buf_size;
1162 int num_records;
1163 void (*unpack_data_fn)(uchar_t *, void *);
1164 int bytes_between_recs;
1165
1166 if (buf_payload_length == 0) {
1167
1168 *structs_payload_lengthp = 0;
1169 *structs_payloadp = NULL;
1170
1171 return (IBMF_SUCCESS);
1172 }
1173
1174 switch (attr_id) {
1175 case SA_CLASSPORTINFO_ATTRID:
1176 struct_size = sizeof (ib_mad_classportinfo_t);
1177 buf_size = IB_MAD_CLASSPORTINFO_SIZE;
1178 unpack_data_fn = ibmf_saa_classportinfo_parse_buffer;
1179 break;
1180 case SA_NOTICE_ATTRID:
1181 struct_size = sizeof (ib_mad_notice_t);
1182 buf_size = IB_MAD_NOTICE_SIZE;
1183 unpack_data_fn = ibmf_saa_notice_parse_buffer;
1184 break;
1185 case SA_INFORMINFO_ATTRID:
1186 struct_size = sizeof (ib_mad_informinfo_t);
1187 buf_size = IB_MAD_INFORMINFO_SIZE;
1188 unpack_data_fn = ibmf_saa_informinfo_parse_buffer;
1189 break;
1190 case SA_NODERECORD_ATTRID:
1191 struct_size = sizeof (sa_node_record_t);
1192 buf_size = IBMF_SAA_NODE_RECORD_SIZE;
1193 unpack_data_fn = ibmf_saa_node_record_parse_buffer;
1194 break;
1195 case SA_PORTINFORECORD_ATTRID:
1196 struct_size = sizeof (sa_portinfo_record_t);
1197 buf_size = IBMF_SAA_PORTINFO_RECORD_SIZE;
1198 unpack_data_fn = ibmf_saa_portinfo_record_parse_buffer;
1199 break;
1200 case SA_SLTOVLRECORD_ATTRID:
1201 struct_size = sizeof (sa_SLtoVLmapping_record_t);
1202 buf_size = IBMF_SAA_SLTOVL_RECORD_SIZE;
1203 unpack_data_fn =
1204 ibmf_saa_SLtoVLmapping_record_parse_buffer;
1205 break;
1206 case SA_SWITCHINFORECORD_ATTRID:
1207 struct_size = sizeof (sa_switchinfo_record_t);
1208 buf_size = IBMF_SAA_SWITCHINFO_RECORD_SIZE;
1209 unpack_data_fn =
1210 ibmf_saa_switchinfo_record_parse_buffer;
1211 break;
1212 case SA_LINEARFDBRECORD_ATTRID:
1213 struct_size = sizeof (sa_linearft_record_t);
1214 buf_size = IBMF_SAA_LINEARFDB_RECORD_SIZE;
1215 unpack_data_fn = ibmf_saa_linearft_record_parse_buffer;
1216 break;
1217 case SA_RANDOMFDBRECORD_ATTRID:
1218 struct_size = sizeof (sa_randomft_record_t);
1219 buf_size = IBMF_SAA_RANDOMFDB_RECORD_SIZE;
1220 unpack_data_fn = ibmf_saa_randomft_record_parse_buffer;
1221 break;
1222 case SA_MULTICASTFDBRECORD_ATTRID:
1223 struct_size = sizeof (sa_multicastft_record_t);
1224 buf_size = IBMF_SAA_MULTICASTFDB_RECORD_SIZE;
1225 unpack_data_fn =
1226 ibmf_saa_multicastft_record_parse_buffer;
1227 break;
1228 case SA_SMINFORECORD_ATTRID:
1229 struct_size = sizeof (sa_sminfo_record_t);
1230 buf_size = IBMF_SAA_SMINFO_RECORD_SIZE;
1231 unpack_data_fn = ibmf_saa_sminfo_record_parse_buffer;
1232 break;
1233 case SA_INFORMINFORECORD_ATTRID:
1234 struct_size = sizeof (sa_informinfo_record_t);
1235 buf_size = IBMF_SAA_INFORMINFO_RECORD_SIZE;
1236 unpack_data_fn =
1237 ibmf_saa_informinfo_record_parse_buffer;
1238 break;
1239 case SA_LINKRECORD_ATTRID:
1240 struct_size = sizeof (sa_link_record_t);
1241 buf_size = IBMF_SAA_LINK_RECORD_SIZE;
1242 unpack_data_fn = ibmf_saa_link_record_parse_buffer;
1243 break;
1244 case SA_GUIDINFORECORD_ATTRID:
1245 struct_size = sizeof (sa_guidinfo_record_t);
1246 buf_size = IBMF_SAA_GUIDINFO_RECORD_SIZE;
1247 unpack_data_fn = ibmf_saa_guidinfo_record_parse_buffer;
1248 break;
1249 case SA_SERVICERECORD_ATTRID:
1250 struct_size = sizeof (sa_service_record_t);
1251 buf_size = IBMF_SAA_SERVICE_RECORD_SIZE;
1252 unpack_data_fn = ibmf_saa_service_record_parse_buffer;
1253 break;
1254 case SA_PARTITIONRECORD_ATTRID:
1255 struct_size = sizeof (sa_pkey_table_record_t);
1256 buf_size = IBMF_SAA_PARTITION_RECORD_SIZE;
1257 unpack_data_fn =
1258 ibmf_saa_partition_record_parse_buffer;
1259 break;
1260 case SA_PATHRECORD_ATTRID:
1261 struct_size = sizeof (sa_path_record_t);
1262 buf_size = IBMF_SAA_PATH_RECORD_SIZE;
1263 unpack_data_fn = ibmf_saa_path_record_parse_buffer;
1264 break;
1265 case SA_VLARBRECORD_ATTRID:
1266 struct_size = sizeof (sa_VLarb_table_record_t);
1267 buf_size = IBMF_SAA_VLARB_RECORD_SIZE;
1268 unpack_data_fn = ibmf_saa_vlarb_record_parse_buffer;
1269 break;
1270 case SA_MCMEMBERRECORD_ATTRID:
1271 struct_size = sizeof (sa_mcmember_record_t);
1272 buf_size = IBMF_SAA_MCMEMBER_RECORD_SIZE;
1273 unpack_data_fn = ibmf_saa_mcmember_record_parse_buffer;
1274 break;
1275 case SA_TRACERECORD_ATTRID:
1276 struct_size = sizeof (sa_trace_record_t);
1277 buf_size = IBMF_SAA_TRACE_RECORD_SIZE;
1278 unpack_data_fn = ibmf_saa_trace_record_parse_buffer;
1279 break;
1280 case SA_MULTIPATHRECORD_ATTRID:
1281 /*
1282 * array is of size 1 since multipath can be request
1283 * only; data size greater than multipath_record_t
1284 * size is due to gids at the end
1285 */
1286 buf_size = buf_payload_length;
1287 struct_size = sizeof (sa_multipath_record_t) +
1288 buf_size - IBMF_SAA_MULTIPATH_RECORD_SIZE;
1289 unpack_data_fn = ibmf_saa_multipath_record_parse_buffer;
1290 break;
1291 case SA_SERVICEASSNRECORD_ATTRID:
1292 struct_size = sizeof (sa_service_assn_record_t);
1293 buf_size = IBMF_SAA_SERVICEASSN_RECORD_SIZE;
1294 unpack_data_fn =
1295 ibmf_saa_service_assn_record_parse_buffer;
1296 break;
1297 default:
1298 /* don't know about structure; do bcopy */
1299
1300 *structs_payload_lengthp = buf_payload_length;
1301 *structs_payloadp = kmem_zalloc(
1302 *structs_payload_lengthp, km_sleep_flag);
1303 if (*structs_payloadp == NULL) {
1304
1305 *structs_payload_lengthp = 0;
1306 return (IBMF_NO_MEMORY);
1307 }
1308
1309 bcopy(buf_payload, *structs_payloadp,
1310 *structs_payload_lengthp);
1311
1312 return (IBMF_SUCCESS);
1313 }
1314
1315 /* compute distance between successive records */
1316 if (attr_offset > 0) {
1317
1318 if ((attr_offset * 8) < buf_size) {
1319
1320 IBMF_TRACE_3(IBMF_TNF_DEBUG, DPRINT_L1,
1321 ibmf_saa_utils_unpack_payload, IBMF_TNF_ERROR, "",
1322 "ibmf_saa_utils_unpack_payload: %s, attr_offset = "
1323 "%d, attr_size = %d\n",
1324 tnf_string, msg, "attribute offset times 8 is less"
1325 " than attribute size",
1326 tnf_int, attr_offset, attr_offset,
1327 tnf_int, attr_size, buf_size);
1328
1329 return (IBMF_TRANS_FAILURE);
1330 }
1331
1332 bytes_between_recs = attr_offset * 8;
1333 } else {
1334 bytes_between_recs = buf_size;
1335 }
1336
1337 if (is_get_resp == B_TRUE) {
1338
1339 buf_payload_length = buf_size;
1340 num_records = 1;
1341 } else {
1342
1343 num_records = buf_payload_length / bytes_between_recs;
1344 }
1345
1346 *structs_payload_lengthp = num_records * struct_size;
1347
1348 *structs_payloadp = kmem_zalloc(*structs_payload_lengthp,
1349 km_sleep_flag);
1350 if (*structs_payloadp == NULL) {
1351
1352 IBMF_TRACE_2(IBMF_TNF_DEBUG, DPRINT_L1,
1353 ibmf_saa_utils_unpack_payload_err,
1354 IBMF_TNF_ERROR, "", "ibmf_saa_utils_unpack_payload: %s,"
1355 " size = %d\n",
1356 tnf_string, msg, "could not allocate memory for payload",
1357 tnf_int, size, *structs_payload_lengthp);
1358
1359 *structs_payload_lengthp = 0;
1360 return (IBMF_NO_MEMORY);
1361 }
1362
1363
1364 for (i = 0; i < num_records; i++) {
1365
1366 unpack_data_fn(
1367 (uchar_t *)buf_payload + (i * bytes_between_recs),
1368 (void *)((uchar_t *)*structs_payloadp + i *
1369 struct_size));
1370 }
1371
1372 return (IBMF_SUCCESS);
1373 }
1374