1 %{
2 /*
3 * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
4 * Copyright (c) 2002-2008 Mellanox Technologies LTD. All rights reserved.
5 * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
6 * Copyright (c) 2008 HNR Consulting. All rights reserved.
7 *
8 * This software is available to you under a choice of one of two
9 * licenses. You may choose to be licensed under the terms of the GNU
10 * General Public License (GPL) Version 2, available from the file
11 * COPYING in the main directory of this source tree, or the
12 * OpenIB.org BSD license below:
13 *
14 * Redistribution and use in source and binary forms, with or
15 * without modification, are permitted provided that the following
16 * conditions are met:
17 *
18 * - Redistributions of source code must retain the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer.
21 *
22 * - Redistributions in binary form must reproduce the above
23 * copyright notice, this list of conditions and the following
24 * disclaimer in the documentation and/or other materials
25 * provided with the distribution.
26 *
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
31 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
32 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
33 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
34 * SOFTWARE.
35 *
36 */
37
38 /*
39 * Abstract:
40 * Grammar of OSM QoS parser.
41 *
42 * Environment:
43 * Linux User Mode
44 *
45 * Author:
46 * Yevgeny Kliteynik, Mellanox
47 */
48
49 #include <stdio.h>
50 #include <assert.h>
51 #include <stdarg.h>
52 #include <stdlib.h>
53 #include <string.h>
54 #include <ctype.h>
55 #include <errno.h>
56 #include <opensm/osm_file_ids.h>
57 #define FILE_ID OSM_FILE_QOS_PARSER_Y_Y
58 #include <opensm/osm_opensm.h>
59 #include <opensm/osm_qos_policy.h>
60
61 #define OSM_QOS_POLICY_MAX_LINE_LEN 1024*10
62 #define OSM_QOS_POLICY_SL2VL_TABLE_LEN IB_MAX_NUM_VLS
63 #define OSM_QOS_POLICY_MAX_VL_NUM IB_MAX_NUM_VLS
64 #define OSM_QOS_POLICY_MAX_RATE IB_MAX_RATE
65 #define OSM_QOS_POLICY_MIN_RATE IB_MIN_RATE
66 #define OSM_QOS_POLICY_MAX_MTU IB_MAX_MTU
67 #define OSM_QOS_POLICY_MIN_MTU IB_MIN_MTU
68
69 typedef struct tmp_parser_struct_t_ {
70 char str[OSM_QOS_POLICY_MAX_LINE_LEN];
71 uint64_t num_pair[2];
72 cl_list_t str_list;
73 cl_list_t num_list;
74 cl_list_t num_pair_list;
75 } tmp_parser_struct_t;
76
77 static void __parser_tmp_struct_init();
78 static void __parser_tmp_struct_reset();
79 static void __parser_tmp_struct_destroy();
80
81 static char * __parser_strip_white(char * str);
82
83 static void __parser_str2uint64(uint64_t * p_val, char * str);
84
85 static void __parser_port_group_start();
86 static int __parser_port_group_end();
87
88 static void __parser_sl2vl_scope_start();
89 static int __parser_sl2vl_scope_end();
90
91 static void __parser_vlarb_scope_start();
92 static int __parser_vlarb_scope_end();
93
94 static void __parser_qos_level_start();
95 static int __parser_qos_level_end();
96
97 static void __parser_match_rule_start();
98 static int __parser_match_rule_end();
99
100 static void __parser_ulp_match_rule_start();
101 static int __parser_ulp_match_rule_end();
102
103 static void __pkey_rangelist2rangearr(
104 cl_list_t * p_list,
105 uint64_t ** * p_arr,
106 unsigned * p_arr_len);
107
108 static void __rangelist2rangearr(
109 cl_list_t * p_list,
110 uint64_t ** * p_arr,
111 unsigned * p_arr_len);
112
113 static void __merge_rangearr(
114 uint64_t ** range_arr_1,
115 unsigned range_len_1,
116 uint64_t ** range_arr_2,
117 unsigned range_len_2,
118 uint64_t ** * p_arr,
119 unsigned * p_arr_len );
120
121 static void __parser_add_port_to_port_map(
122 cl_qmap_t * p_map,
123 osm_physp_t * p_physp);
124
125 static void __parser_add_guid_range_to_port_map(
126 cl_qmap_t * p_map,
127 uint64_t ** range_arr,
128 unsigned range_len);
129
130 static void __parser_add_pkey_range_to_port_map(
131 cl_qmap_t * p_map,
132 uint64_t ** range_arr,
133 unsigned range_len);
134
135 static void __parser_add_partition_list_to_port_map(
136 cl_qmap_t * p_map,
137 cl_list_t * p_list);
138
139 static void __parser_add_map_to_port_map(
140 cl_qmap_t * p_dmap,
141 cl_map_t * p_smap);
142
143 static int __validate_pkeys(
144 uint64_t ** range_arr,
145 unsigned range_len,
146 boolean_t is_ipoib);
147
148 static void __setup_simple_qos_levels();
149 static void __clear_simple_qos_levels();
150 static void __setup_ulp_match_rules();
151 static void __process_ulp_match_rules();
152 static void yyerror(const char *format, ...);
153
154 extern char * yytext;
155 extern int yylex (void);
156 extern FILE * yyin;
157 extern int errno;
158 extern void yyrestart(FILE *input_file);
159 int yyparse();
160
161 #define RESET_BUFFER __parser_tmp_struct_reset()
162
163 tmp_parser_struct_t tmp_parser_struct;
164
165 int column_num;
166 int line_num;
167
168 osm_qos_policy_t * p_qos_policy = NULL;
169 osm_qos_port_group_t * p_current_port_group = NULL;
170 osm_qos_sl2vl_scope_t * p_current_sl2vl_scope = NULL;
171 osm_qos_vlarb_scope_t * p_current_vlarb_scope = NULL;
172 osm_qos_level_t * p_current_qos_level = NULL;
173 osm_qos_match_rule_t * p_current_qos_match_rule = NULL;
174 osm_log_t * p_qos_parser_osm_log;
175
176 /* 16 Simple QoS Levels - one for each SL */
177 static osm_qos_level_t osm_qos_policy_simple_qos_levels[16];
178
179 /* Default Simple QoS Level */
180 osm_qos_level_t __default_simple_qos_level;
181
182 /*
183 * List of match rules that will be generated by the
184 * qos-ulp section. These rules are concatenated to
185 * the end of the usual matching rules list at the
186 * end of parsing.
187 */
188 static cl_list_t __ulp_match_rules;
189
190 /***************************************************/
191
192 %}
193
194 %token TK_NUMBER
195 %token TK_DASH
196 %token TK_DOTDOT
197 %token TK_COMMA
198 %token TK_ASTERISK
199 %token TK_TEXT
200
201 %token TK_QOS_ULPS_START
202 %token TK_QOS_ULPS_END
203
204 %token TK_PORT_GROUPS_START
205 %token TK_PORT_GROUPS_END
206 %token TK_PORT_GROUP_START
207 %token TK_PORT_GROUP_END
208
209 %token TK_QOS_SETUP_START
210 %token TK_QOS_SETUP_END
211 %token TK_VLARB_TABLES_START
212 %token TK_VLARB_TABLES_END
213 %token TK_VLARB_SCOPE_START
214 %token TK_VLARB_SCOPE_END
215
216 %token TK_SL2VL_TABLES_START
217 %token TK_SL2VL_TABLES_END
218 %token TK_SL2VL_SCOPE_START
219 %token TK_SL2VL_SCOPE_END
220
221 %token TK_QOS_LEVELS_START
222 %token TK_QOS_LEVELS_END
223 %token TK_QOS_LEVEL_START
224 %token TK_QOS_LEVEL_END
225
226 %token TK_QOS_MATCH_RULES_START
227 %token TK_QOS_MATCH_RULES_END
228 %token TK_QOS_MATCH_RULE_START
229 %token TK_QOS_MATCH_RULE_END
230
231 %token TK_NAME
232 %token TK_USE
233 %token TK_PORT_GUID
234 %token TK_PORT_NAME
235 %token TK_PARTITION
236 %token TK_NODE_TYPE
237 %token TK_GROUP
238 %token TK_ACROSS
239 %token TK_VLARB_HIGH
240 %token TK_VLARB_LOW
241 %token TK_VLARB_HIGH_LIMIT
242 %token TK_TO
243 %token TK_FROM
244 %token TK_ACROSS_TO
245 %token TK_ACROSS_FROM
246 %token TK_SL2VL_TABLE
247 %token TK_SL
248 %token TK_MTU_LIMIT
249 %token TK_RATE_LIMIT
250 %token TK_PACKET_LIFE
251 %token TK_PATH_BITS
252 %token TK_QOS_CLASS
253 %token TK_SOURCE
254 %token TK_DESTINATION
255 %token TK_SERVICE_ID
256 %token TK_QOS_LEVEL_NAME
257 %token TK_PKEY
258
259 %token TK_NODE_TYPE_ROUTER
260 %token TK_NODE_TYPE_CA
261 %token TK_NODE_TYPE_SWITCH
262 %token TK_NODE_TYPE_SELF
263 %token TK_NODE_TYPE_ALL
264
265 %token TK_ULP_DEFAULT
266 %token TK_ULP_ANY_SERVICE_ID
267 %token TK_ULP_ANY_PKEY
268 %token TK_ULP_ANY_TARGET_PORT_GUID
269 %token TK_ULP_ANY_SOURCE_PORT_GUID
270 %token TK_ULP_ANY_SOURCE_TARGET_PORT_GUID
271 %token TK_ULP_SDP_DEFAULT
272 %token TK_ULP_SDP_PORT
273 %token TK_ULP_RDS_DEFAULT
274 %token TK_ULP_RDS_PORT
275 %token TK_ULP_ISER_DEFAULT
276 %token TK_ULP_ISER_PORT
277 %token TK_ULP_SRP_GUID
278 %token TK_ULP_IPOIB_DEFAULT
279 %token TK_ULP_IPOIB_PKEY
280
281 %start head
282
283 %%
284
285 head: qos_policy_entries
286 ;
287
288 qos_policy_entries: /* empty */
289 | qos_policy_entries qos_policy_entry
290 ;
291
292 qos_policy_entry: qos_ulps_section
293 | port_groups_section
294 | qos_setup_section
295 | qos_levels_section
296 | qos_match_rules_section
297 ;
298
299 /*
300 * Parsing qos-ulps:
301 * -------------------
302 * qos-ulps
303 * default : 0 #default SL
304 * sdp, port-num 30000 : 1 #SL for SDP when destination port is 30000
305 * sdp, port-num 10000-20000 : 2
306 * sdp : 0 #default SL for SDP
307 * srp, target-port-guid 0x1234 : 2
308 * rds, port-num 25000 : 2 #SL for RDS when destination port is 25000
309 * rds, : 0 #default SL for RDS
310 * iser, port-num 900 : 5 #SL for iSER where target port is 900
311 * iser : 4 #default SL for iSER
312 * ipoib, pkey 0x0001 : 5 #SL for IPoIB on partition with pkey 0x0001
313 * ipoib : 6 #default IPoIB partition - pkey=0x7FFF
314 * any, service-id 0x6234 : 2
315 * any, pkey 0x0ABC : 3
316 * any, target-port-guid 0x0ABC-0xFFFFF : 6
317 * any, source-port-guid 0x1234 : 7
318 * any, source-target-port-guid 0x5678 : 8
319 * end-qos-ulps
320 */
321
322 qos_ulps_section: TK_QOS_ULPS_START qos_ulps TK_QOS_ULPS_END
323 ;
324
325 qos_ulps: qos_ulp
326 | qos_ulps qos_ulp
327 ;
328
329 /*
330 * Parsing port groups:
331 * -------------------
332 * port-groups
333 * port-group
334 * name: Storage
335 * use: our SRP storage targets
336 * port-guid: 0x1000000000000001,0x1000000000000002
337 * ...
338 * port-name: vs1 HCA-1/P1
339 * port-name: node_description/P2
340 * ...
341 * pkey: 0x00FF-0x0FFF
342 * ...
343 * partition: Part1
344 * ...
345 * node-type: ROUTER,CA,SWITCH,SELF,ALL
346 * ...
347 * end-port-group
348 * port-group
349 * ...
350 * end-port-group
351 * end-port-groups
352 */
353
354
355 port_groups_section: TK_PORT_GROUPS_START port_groups TK_PORT_GROUPS_END
356 ;
357
358 port_groups: port_group
359 | port_groups port_group
360 ;
361
362 port_group: port_group_start port_group_entries port_group_end
363 ;
364
365 port_group_start: TK_PORT_GROUP_START {
366 __parser_port_group_start();
367 }
368 ;
369
370 port_group_end: TK_PORT_GROUP_END {
371 if ( __parser_port_group_end() )
372 return 1;
373 }
374 ;
375
376 port_group_entries: /* empty */
377 | port_group_entries port_group_entry
378 ;
379
380 port_group_entry: port_group_name
381 | port_group_use
382 | port_group_port_guid
383 | port_group_port_name
384 | port_group_pkey
385 | port_group_partition
386 | port_group_node_type
387 ;
388
389
390 /*
391 * Parsing qos setup:
392 * -----------------
393 * qos-setup
394 * vlarb-tables
395 * vlarb-scope
396 * ...
397 * end-vlarb-scope
398 * vlarb-scope
399 * ...
400 * end-vlarb-scope
401 * end-vlarb-tables
402 * sl2vl-tables
403 * sl2vl-scope
404 * ...
405 * end-sl2vl-scope
406 * sl2vl-scope
407 * ...
408 * end-sl2vl-scope
409 * end-sl2vl-tables
410 * end-qos-setup
411 */
412
413 qos_setup_section: TK_QOS_SETUP_START qos_setup_items TK_QOS_SETUP_END
414 ;
415
416 qos_setup_items: /* empty */
417 | qos_setup_items vlarb_tables
418 | qos_setup_items sl2vl_tables
419 ;
420
421 /* Parsing vlarb-tables */
422
423 vlarb_tables: TK_VLARB_TABLES_START vlarb_scope_items TK_VLARB_TABLES_END
424 ;
425
426 vlarb_scope_items: /* empty */
427 | vlarb_scope_items vlarb_scope
428 ;
429
430 vlarb_scope: vlarb_scope_start vlarb_scope_entries vlarb_scope_end
431 ;
432
433 vlarb_scope_start: TK_VLARB_SCOPE_START {
434 __parser_vlarb_scope_start();
435 }
436 ;
437
438 vlarb_scope_end: TK_VLARB_SCOPE_END {
439 if ( __parser_vlarb_scope_end() )
440 return 1;
441 }
442 ;
443
444 vlarb_scope_entries:/* empty */
445 | vlarb_scope_entries vlarb_scope_entry
446 ;
447
448 /*
449 * vlarb-scope
450 * group: Storage
451 * ...
452 * across: Storage
453 * ...
454 * vlarb-high: 0:255,1:127,2:63,3:31,4:15,5:7,6:3,7:1
455 * vlarb-low: 8:255,9:127,10:63,11:31,12:15,13:7,14:3
456 * vl-high-limit: 10
457 * end-vlarb-scope
458 */
459
460 vlarb_scope_entry: vlarb_scope_group
461 | vlarb_scope_across
462 | vlarb_scope_vlarb_high
463 | vlarb_scope_vlarb_low
464 | vlarb_scope_vlarb_high_limit
465 ;
466
467 /* Parsing sl2vl-tables */
468
469 sl2vl_tables: TK_SL2VL_TABLES_START sl2vl_scope_items TK_SL2VL_TABLES_END
470 ;
471
472 sl2vl_scope_items: /* empty */
473 | sl2vl_scope_items sl2vl_scope
474 ;
475
476 sl2vl_scope: sl2vl_scope_start sl2vl_scope_entries sl2vl_scope_end
477 ;
478
479 sl2vl_scope_start: TK_SL2VL_SCOPE_START {
480 __parser_sl2vl_scope_start();
481 }
482 ;
483
484 sl2vl_scope_end: TK_SL2VL_SCOPE_END {
485 if ( __parser_sl2vl_scope_end() )
486 return 1;
487 }
488 ;
489
490 sl2vl_scope_entries:/* empty */
491 | sl2vl_scope_entries sl2vl_scope_entry
492 ;
493
494 /*
495 * sl2vl-scope
496 * group: Part1
497 * ...
498 * from: *
499 * ...
500 * to: *
501 * ...
502 * across-to: Storage2
503 * ...
504 * across-from: Storage1
505 * ...
506 * sl2vl-table: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,7
507 * end-sl2vl-scope
508 */
509
510 sl2vl_scope_entry: sl2vl_scope_group
511 | sl2vl_scope_across
512 | sl2vl_scope_across_from
513 | sl2vl_scope_across_to
514 | sl2vl_scope_from
515 | sl2vl_scope_to
516 | sl2vl_scope_sl2vl_table
517 ;
518
519 /*
520 * Parsing qos-levels:
521 * ------------------
522 * qos-levels
523 * qos-level
524 * name: qos_level_1
525 * use: for the lowest priority communication
526 * sl: 15
527 * mtu-limit: 1
528 * rate-limit: 1
529 * packet-life: 12
530 * path-bits: 2,4,8-32
531 * pkey: 0x00FF-0x0FFF
532 * end-qos-level
533 * ...
534 * qos-level
535 * end-qos-level
536 * end-qos-levels
537 */
538
539
540 qos_levels_section: TK_QOS_LEVELS_START qos_levels TK_QOS_LEVELS_END
541 ;
542
543 qos_levels: /* empty */
544 | qos_levels qos_level
545 ;
546
547 qos_level: qos_level_start qos_level_entries qos_level_end
548 ;
549
550 qos_level_start: TK_QOS_LEVEL_START {
551 __parser_qos_level_start();
552 }
553 ;
554
555 qos_level_end: TK_QOS_LEVEL_END {
556 if ( __parser_qos_level_end() )
557 return 1;
558 }
559 ;
560
561 qos_level_entries: /* empty */
562 | qos_level_entries qos_level_entry
563 ;
564
565 qos_level_entry: qos_level_name
566 | qos_level_use
567 | qos_level_sl
568 | qos_level_mtu_limit
569 | qos_level_rate_limit
570 | qos_level_packet_life
571 | qos_level_path_bits
572 | qos_level_pkey
573 ;
574
575 /*
576 * Parsing qos-match-rules:
577 * -----------------------
578 * qos-match-rules
579 * qos-match-rule
580 * use: low latency by class 7-9 or 11 and bla bla
581 * qos-class: 7-9,11
582 * qos-level-name: default
583 * source: Storage
584 * destination: Storage
585 * service-id: 22,4719-5000
586 * pkey: 0x00FF-0x0FFF
587 * end-qos-match-rule
588 * qos-match-rule
589 * ...
590 * end-qos-match-rule
591 * end-qos-match-rules
592 */
593
594 qos_match_rules_section: TK_QOS_MATCH_RULES_START qos_match_rules TK_QOS_MATCH_RULES_END
595 ;
596
597 qos_match_rules: /* empty */
598 | qos_match_rules qos_match_rule
599 ;
600
601 qos_match_rule: qos_match_rule_start qos_match_rule_entries qos_match_rule_end
602 ;
603
604 qos_match_rule_start: TK_QOS_MATCH_RULE_START {
605 __parser_match_rule_start();
606 }
607 ;
608
609 qos_match_rule_end: TK_QOS_MATCH_RULE_END {
610 if ( __parser_match_rule_end() )
611 return 1;
612 }
613 ;
614
615 qos_match_rule_entries: /* empty */
616 | qos_match_rule_entries qos_match_rule_entry
617 ;
618
619 qos_match_rule_entry: qos_match_rule_use
620 | qos_match_rule_qos_class
621 | qos_match_rule_qos_level_name
622 | qos_match_rule_source
623 | qos_match_rule_destination
624 | qos_match_rule_service_id
625 | qos_match_rule_pkey
626 ;
627
628
629 /*
630 * Parsing qos-ulps:
631 * -----------------
632 * default
633 * sdp
634 * sdp with port-num
635 * rds
636 * rds with port-num
637 * srp with target-port-guid
638 * iser
639 * iser with port-num
640 * ipoib
641 * ipoib with pkey
642 * any with service-id
643 * any with pkey
644 * any with target-port-guid
645 * any with source-port-guid
646 * any with source-target-port-guid
647 */
648
649 qos_ulp: TK_ULP_DEFAULT single_number {
650 /* parsing default ulp rule: "default: num" */
651 cl_list_iterator_t list_iterator;
652 uint64_t * p_tmp_num;
653
654 list_iterator = cl_list_head(&tmp_parser_struct.num_list);
655 p_tmp_num = (uint64_t*)cl_list_obj(list_iterator);
656 if (*p_tmp_num > 15)
657 {
658 yyerror("illegal SL value");
659 return 1;
660 }
661 __default_simple_qos_level.sl = (uint8_t)(*p_tmp_num);
662 __default_simple_qos_level.sl_set = TRUE;
663 free(p_tmp_num);
664 cl_list_remove_all(&tmp_parser_struct.num_list);
665 }
666
667 | qos_ulp_type_any_service list_of_ranges TK_DOTDOT {
668 /* "any, service-id ... : sl" - one instance of list of ranges */
669 uint64_t ** range_arr;
670 unsigned range_len;
671
672 if (!cl_list_count(&tmp_parser_struct.num_pair_list))
673 {
674 yyerror("ULP rule doesn't have service ids");
675 return 1;
676 }
677
678 /* get all the service id ranges */
679 __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
680 &range_arr,
681 &range_len );
682
683 p_current_qos_match_rule->service_id_range_arr = range_arr;
684 p_current_qos_match_rule->service_id_range_len = range_len;
685
686 } qos_ulp_sl
687
688 | qos_ulp_type_any_pkey list_of_ranges TK_DOTDOT {
689 /* "any, pkey ... : sl" - one instance of list of ranges */
690 uint64_t ** range_arr;
691 unsigned range_len;
692
693 if (!cl_list_count(&tmp_parser_struct.num_pair_list))
694 {
695 yyerror("ULP rule doesn't have pkeys");
696 return 1;
697 }
698
699 /* get all the pkey ranges */
700 __pkey_rangelist2rangearr( &tmp_parser_struct.num_pair_list,
701 &range_arr,
702 &range_len );
703
704 p_current_qos_match_rule->pkey_range_arr = range_arr;
705 p_current_qos_match_rule->pkey_range_len = range_len;
706
707 } qos_ulp_sl
708
709 | qos_ulp_type_any_target_port_guid list_of_ranges TK_DOTDOT {
710 /* any, target-port-guid ... : sl */
711 uint64_t ** range_arr;
712 unsigned range_len;
713
714 if (!cl_list_count(&tmp_parser_struct.num_pair_list))
715 {
716 yyerror("ULP rule doesn't have port guids");
717 return 1;
718 }
719
720 /* create a new port group with these ports */
721 __parser_port_group_start();
722
723 p_current_port_group->name = strdup("_ULP_Targets_");
724 p_current_port_group->use = strdup("Generated from ULP rules");
725
726 __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
727 &range_arr,
728 &range_len );
729
730 __parser_add_guid_range_to_port_map(
731 &p_current_port_group->port_map,
732 range_arr,
733 range_len);
734
735 /* add this port group to the destination
736 groups of the current match rule */
737 cl_list_insert_tail(&p_current_qos_match_rule->destination_group_list,
738 p_current_port_group);
739
740 __parser_port_group_end();
741
742 } qos_ulp_sl
743
744 | qos_ulp_type_any_source_port_guid list_of_ranges TK_DOTDOT {
745 /* any, source-port-guid ... : sl */
746 uint64_t ** range_arr;
747 unsigned range_len;
748
749 if (!cl_list_count(&tmp_parser_struct.num_pair_list))
750 {
751 yyerror("ULP rule doesn't have port guids");
752 return 1;
753 }
754
755 /* create a new port group with these ports */
756 __parser_port_group_start();
757
758 p_current_port_group->name = strdup("_ULP_Sources_");
759 p_current_port_group->use = strdup("Generated from ULP rules");
760
761 __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
762 &range_arr,
763 &range_len );
764
765 __parser_add_guid_range_to_port_map(
766 &p_current_port_group->port_map,
767 range_arr,
768 range_len);
769
770 /* add this port group to the source
771 groups of the current match rule */
772 cl_list_insert_tail(&p_current_qos_match_rule->source_group_list,
773 p_current_port_group);
774
775 __parser_port_group_end();
776
777 } qos_ulp_sl
778
779 | qos_ulp_type_any_source_target_port_guid list_of_ranges TK_DOTDOT {
780 /* any, source-target-port-guid ... : sl */
781 uint64_t ** range_arr;
782 unsigned range_len;
783
784 if (!cl_list_count(&tmp_parser_struct.num_pair_list))
785 {
786 yyerror("ULP rule doesn't have port guids");
787 return 1;
788 }
789
790 /* create a new port group with these ports */
791 __parser_port_group_start();
792
793 p_current_port_group->name = strdup("_ULP_Sources_Targets_");
794 p_current_port_group->use = strdup("Generated from ULP rules");
795
796 __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
797 &range_arr,
798 &range_len );
799
800 __parser_add_guid_range_to_port_map(
801 &p_current_port_group->port_map,
802 range_arr,
803 range_len);
804
805 /* add this port group to the source and destination
806 groups of the current match rule */
807 cl_list_insert_tail(&p_current_qos_match_rule->source_group_list,
808 p_current_port_group);
809
810 cl_list_insert_tail(&p_current_qos_match_rule->destination_group_list,
811 p_current_port_group);
812
813 __parser_port_group_end();
814
815 } qos_ulp_sl
816
817 | qos_ulp_type_sdp_default {
818 /* "sdp : sl" - default SL for SDP */
819 uint64_t ** range_arr =
820 (uint64_t **)malloc(sizeof(uint64_t *));
821 range_arr[0] = (uint64_t *)malloc(2*sizeof(uint64_t));
822 range_arr[0][0] = OSM_QOS_POLICY_ULP_SDP_SERVICE_ID;
823 range_arr[0][1] = OSM_QOS_POLICY_ULP_SDP_SERVICE_ID + 0xFFFF;
824
825 p_current_qos_match_rule->service_id_range_arr = range_arr;
826 p_current_qos_match_rule->service_id_range_len = 1;
827
828 } qos_ulp_sl
829
830 | qos_ulp_type_sdp_port list_of_ranges TK_DOTDOT {
831 /* sdp with port numbers */
832 uint64_t ** range_arr;
833 unsigned range_len;
834 unsigned i;
835
836 if (!cl_list_count(&tmp_parser_struct.num_pair_list))
837 {
838 yyerror("SDP ULP rule doesn't have port numbers");
839 return 1;
840 }
841
842 /* get all the port ranges */
843 __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
844 &range_arr,
845 &range_len );
846 /* now translate these port numbers into service ids */
847 for (i = 0; i < range_len; i++)
848 {
849 if (range_arr[i][0] > 0xFFFF || range_arr[i][1] > 0xFFFF)
850 {
851 yyerror("SDP port number out of range");
852 free(range_arr);
853 return 1;
854 }
855 range_arr[i][0] += OSM_QOS_POLICY_ULP_SDP_SERVICE_ID;
856 range_arr[i][1] += OSM_QOS_POLICY_ULP_SDP_SERVICE_ID;
857 }
858
859 p_current_qos_match_rule->service_id_range_arr = range_arr;
860 p_current_qos_match_rule->service_id_range_len = range_len;
861
862 } qos_ulp_sl
863
864 | qos_ulp_type_rds_default {
865 /* "rds : sl" - default SL for RDS */
866 uint64_t ** range_arr =
867 (uint64_t **)malloc(sizeof(uint64_t *));
868 range_arr[0] = (uint64_t *)malloc(2*sizeof(uint64_t));
869 range_arr[0][0] = range_arr[0][1] =
870 OSM_QOS_POLICY_ULP_RDS_SERVICE_ID + OSM_QOS_POLICY_ULP_RDS_PORT;
871
872 p_current_qos_match_rule->service_id_range_arr = range_arr;
873 p_current_qos_match_rule->service_id_range_len = 1;
874
875 } qos_ulp_sl
876
877 | qos_ulp_type_rds_port list_of_ranges TK_DOTDOT {
878 /* rds with port numbers */
879 uint64_t ** range_arr;
880 unsigned range_len;
881 unsigned i;
882
883 if (!cl_list_count(&tmp_parser_struct.num_pair_list))
884 {
885 yyerror("RDS ULP rule doesn't have port numbers");
886 return 1;
887 }
888
889 /* get all the port ranges */
890 __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
891 &range_arr,
892 &range_len );
893 /* now translate these port numbers into service ids */
894 for (i = 0; i < range_len; i++)
895 {
896 if (range_arr[i][0] > 0xFFFF || range_arr[i][1] > 0xFFFF)
897 {
898 yyerror("SDP port number out of range");
899 free(range_arr);
900 return 1;
901 }
902 range_arr[i][0] += OSM_QOS_POLICY_ULP_RDS_SERVICE_ID;
903 range_arr[i][1] += OSM_QOS_POLICY_ULP_RDS_SERVICE_ID;
904 }
905
906 p_current_qos_match_rule->service_id_range_arr = range_arr;
907 p_current_qos_match_rule->service_id_range_len = range_len;
908
909 } qos_ulp_sl
910
911 | qos_ulp_type_iser_default {
912 /* "iSER : sl" - default SL for iSER */
913 uint64_t ** range_arr =
914 (uint64_t **)malloc(sizeof(uint64_t *));
915 range_arr[0] = (uint64_t *)malloc(2*sizeof(uint64_t));
916 range_arr[0][0] = range_arr[0][1] =
917 OSM_QOS_POLICY_ULP_ISER_SERVICE_ID + OSM_QOS_POLICY_ULP_ISER_PORT;
918
919 p_current_qos_match_rule->service_id_range_arr = range_arr;
920 p_current_qos_match_rule->service_id_range_len = 1;
921
922 } qos_ulp_sl
923
924 | qos_ulp_type_iser_port list_of_ranges TK_DOTDOT {
925 /* iser with port numbers */
926 uint64_t ** range_arr;
927 unsigned range_len;
928 unsigned i;
929
930 if (!cl_list_count(&tmp_parser_struct.num_pair_list))
931 {
932 yyerror("iSER ULP rule doesn't have port numbers");
933 return 1;
934 }
935
936 /* get all the port ranges */
937 __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
938 &range_arr,
939 &range_len );
940 /* now translate these port numbers into service ids */
941 for (i = 0; i < range_len; i++)
942 {
943 if (range_arr[i][0] > 0xFFFF || range_arr[i][1] > 0xFFFF)
944 {
945 yyerror("SDP port number out of range");
946 free(range_arr);
947 return 1;
948 }
949 range_arr[i][0] += OSM_QOS_POLICY_ULP_ISER_SERVICE_ID;
950 range_arr[i][1] += OSM_QOS_POLICY_ULP_ISER_SERVICE_ID;
951 }
952
953 p_current_qos_match_rule->service_id_range_arr = range_arr;
954 p_current_qos_match_rule->service_id_range_len = range_len;
955
956 } qos_ulp_sl
957
958 | qos_ulp_type_srp_guid list_of_ranges TK_DOTDOT {
959 /* srp with target guids - this rule is similar
960 to writing 'any' ulp with target port guids */
961 uint64_t ** range_arr;
962 unsigned range_len;
963
964 if (!cl_list_count(&tmp_parser_struct.num_pair_list))
965 {
966 yyerror("SRP ULP rule doesn't have port guids");
967 return 1;
968 }
969
970 /* create a new port group with these ports */
971 __parser_port_group_start();
972
973 p_current_port_group->name = strdup("_SRP_Targets_");
974 p_current_port_group->use = strdup("Generated from ULP rules");
975
976 __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
977 &range_arr,
978 &range_len );
979
980 __parser_add_guid_range_to_port_map(
981 &p_current_port_group->port_map,
982 range_arr,
983 range_len);
984
985 /* add this port group to the destination
986 groups of the current match rule */
987 cl_list_insert_tail(&p_current_qos_match_rule->destination_group_list,
988 p_current_port_group);
989
990 __parser_port_group_end();
991
992 } qos_ulp_sl
993
994 | qos_ulp_type_ipoib_default {
995 /* ipoib w/o any pkeys (default pkey) */
996 uint64_t ** range_arr =
997 (uint64_t **)malloc(sizeof(uint64_t *));
998 range_arr[0] = (uint64_t *)malloc(2*sizeof(uint64_t));
999 range_arr[0][0] = range_arr[0][1] = 0x7fff;
1000
1001 /*
1002 * Although we know that the default partition exists,
1003 * we still need to validate it by checking that it has
1004 * at least two full members. Otherwise IPoIB won't work.
1005 */
1006 if (__validate_pkeys(range_arr, 1, TRUE))
1007 return 1;
1008
1009 p_current_qos_match_rule->pkey_range_arr = range_arr;
1010 p_current_qos_match_rule->pkey_range_len = 1;
1011
1012 } qos_ulp_sl
1013
1014 | qos_ulp_type_ipoib_pkey list_of_ranges TK_DOTDOT {
1015 /* ipoib with pkeys */
1016 uint64_t ** range_arr;
1017 unsigned range_len;
1018
1019 if (!cl_list_count(&tmp_parser_struct.num_pair_list))
1020 {
1021 yyerror("IPoIB ULP rule doesn't have pkeys");
1022 return 1;
1023 }
1024
1025 /* get all the pkey ranges */
1026 __pkey_rangelist2rangearr( &tmp_parser_struct.num_pair_list,
1027 &range_arr,
1028 &range_len );
1029
1030 /*
1031 * Validate pkeys.
1032 * For IPoIB pkeys the validation is strict.
1033 * If some problem would be found, parsing will
1034 * be aborted with a proper error messages.
1035 */
1036 if (__validate_pkeys(range_arr, range_len, TRUE)) {
1037 free(range_arr);
1038 return 1;
1039 }
1040
1041 p_current_qos_match_rule->pkey_range_arr = range_arr;
1042 p_current_qos_match_rule->pkey_range_len = range_len;
1043
1044 } qos_ulp_sl
1045 ;
1046
1047 qos_ulp_type_any_service: TK_ULP_ANY_SERVICE_ID
1048 { __parser_ulp_match_rule_start(); };
1049
1050 qos_ulp_type_any_pkey: TK_ULP_ANY_PKEY
1051 { __parser_ulp_match_rule_start(); };
1052
1053 qos_ulp_type_any_target_port_guid: TK_ULP_ANY_TARGET_PORT_GUID
1054 { __parser_ulp_match_rule_start(); };
1055
1056 qos_ulp_type_any_source_port_guid: TK_ULP_ANY_SOURCE_PORT_GUID
1057 { __parser_ulp_match_rule_start(); };
1058
1059 qos_ulp_type_any_source_target_port_guid: TK_ULP_ANY_SOURCE_TARGET_PORT_GUID
1060 { __parser_ulp_match_rule_start(); };
1061
1062 qos_ulp_type_sdp_default: TK_ULP_SDP_DEFAULT
1063 { __parser_ulp_match_rule_start(); };
1064
1065 qos_ulp_type_sdp_port: TK_ULP_SDP_PORT
1066 { __parser_ulp_match_rule_start(); };
1067
1068 qos_ulp_type_rds_default: TK_ULP_RDS_DEFAULT
1069 { __parser_ulp_match_rule_start(); };
1070
1071 qos_ulp_type_rds_port: TK_ULP_RDS_PORT
1072 { __parser_ulp_match_rule_start(); };
1073
1074 qos_ulp_type_iser_default: TK_ULP_ISER_DEFAULT
1075 { __parser_ulp_match_rule_start(); };
1076
1077 qos_ulp_type_iser_port: TK_ULP_ISER_PORT
1078 { __parser_ulp_match_rule_start(); };
1079
1080 qos_ulp_type_srp_guid: TK_ULP_SRP_GUID
1081 { __parser_ulp_match_rule_start(); };
1082
1083 qos_ulp_type_ipoib_default: TK_ULP_IPOIB_DEFAULT
1084 { __parser_ulp_match_rule_start(); };
1085
1086 qos_ulp_type_ipoib_pkey: TK_ULP_IPOIB_PKEY
1087 { __parser_ulp_match_rule_start(); };
1088
1089
1090 qos_ulp_sl: single_number {
1091 /* get the SL for ULP rules */
1092 cl_list_iterator_t list_iterator;
1093 uint64_t * p_tmp_num;
1094 uint8_t sl;
1095
1096 list_iterator = cl_list_head(&tmp_parser_struct.num_list);
1097 p_tmp_num = (uint64_t*)cl_list_obj(list_iterator);
1098 if (*p_tmp_num > 15)
1099 {
1100 yyerror("illegal SL value");
1101 return 1;
1102 }
1103
1104 sl = (uint8_t)(*p_tmp_num);
1105 free(p_tmp_num);
1106 cl_list_remove_all(&tmp_parser_struct.num_list);
1107
1108 p_current_qos_match_rule->p_qos_level =
1109 &osm_qos_policy_simple_qos_levels[sl];
1110 p_current_qos_match_rule->qos_level_name =
1111 strdup(osm_qos_policy_simple_qos_levels[sl].name);
1112
1113 if (__parser_ulp_match_rule_end())
1114 return 1;
1115 }
1116 ;
1117
1118 /*
1119 * port_group_entry values:
1120 * port_group_name
1121 * port_group_use
1122 * port_group_port_guid
1123 * port_group_port_name
1124 * port_group_pkey
1125 * port_group_partition
1126 * port_group_node_type
1127 */
1128
1129 port_group_name: port_group_name_start single_string {
1130 /* 'name' of 'port-group' - one instance */
1131 cl_list_iterator_t list_iterator;
1132 char * tmp_str;
1133
1134 if (p_current_port_group->name)
1135 {
1136 yyerror("port-group has multiple 'name' tags");
1137 cl_list_remove_all(&tmp_parser_struct.str_list);
1138 return 1;
1139 }
1140
1141 list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1142 if ( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1143 {
1144 tmp_str = (char*)cl_list_obj(list_iterator);
1145 if (tmp_str)
1146 p_current_port_group->name = tmp_str;
1147 }
1148 cl_list_remove_all(&tmp_parser_struct.str_list);
1149 }
1150 ;
1151
1152 port_group_name_start: TK_NAME {
1153 RESET_BUFFER;
1154 }
1155 ;
1156
1157 port_group_use: port_group_use_start single_string {
1158 /* 'use' of 'port-group' - one instance */
1159 cl_list_iterator_t list_iterator;
1160 char * tmp_str;
1161
1162 if (p_current_port_group->use)
1163 {
1164 yyerror("port-group has multiple 'use' tags");
1165 cl_list_remove_all(&tmp_parser_struct.str_list);
1166 return 1;
1167 }
1168
1169 list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1170 if ( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1171 {
1172 tmp_str = (char*)cl_list_obj(list_iterator);
1173 if (tmp_str)
1174 p_current_port_group->use = tmp_str;
1175 }
1176 cl_list_remove_all(&tmp_parser_struct.str_list);
1177 }
1178 ;
1179
1180 port_group_use_start: TK_USE {
1181 RESET_BUFFER;
1182 }
1183 ;
1184
1185 port_group_port_name: port_group_port_name_start string_list {
1186 /* 'port-name' in 'port-group' - any num of instances */
1187 cl_list_iterator_t list_iterator;
1188 osm_node_t * p_node;
1189 osm_physp_t * p_physp;
1190 unsigned port_num;
1191 char * tmp_str;
1192 char * port_str;
1193
1194 /* parsing port name strings */
1195 for (list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1196 list_iterator != cl_list_end(&tmp_parser_struct.str_list);
1197 list_iterator = cl_list_next(list_iterator))
1198 {
1199 tmp_str = (char*)cl_list_obj(list_iterator);
1200 if (tmp_str)
1201 {
1202 /* last slash in port name string is a separator
1203 between node name and port number */
1204 port_str = strrchr(tmp_str, '/');
1205 if (!port_str || (strlen(port_str) < 3) ||
1206 (port_str[1] != 'p' && port_str[1] != 'P')) {
1207 yyerror("'%s' - illegal port name",
1208 tmp_str);
1209 free(tmp_str);
1210 cl_list_remove_all(&tmp_parser_struct.str_list);
1211 return 1;
1212 }
1213
1214 if (!(port_num = strtoul(&port_str[2],NULL,0))) {
1215 yyerror(
1216 "'%s' - illegal port number in port name",
1217 tmp_str);
1218 free(tmp_str);
1219 cl_list_remove_all(&tmp_parser_struct.str_list);
1220 return 1;
1221 }
1222
1223 /* separate node name from port number */
1224 port_str[0] = '\0';
1225
1226 if (st_lookup(p_qos_policy->p_node_hash,
1227 (st_data_t)tmp_str,
1228 (void *)&p_node))
1229 {
1230 /* we found the node, now get the right port */
1231 p_physp = osm_node_get_physp_ptr(p_node, port_num);
1232 if (!p_physp) {
1233 yyerror(
1234 "'%s' - port number out of range in port name",
1235 tmp_str);
1236 free(tmp_str);
1237 cl_list_remove_all(&tmp_parser_struct.str_list);
1238 return 1;
1239 }
1240 /* we found the port, now add it to guid table */
1241 __parser_add_port_to_port_map(&p_current_port_group->port_map,
1242 p_physp);
1243 }
1244 free(tmp_str);
1245 }
1246 }
1247 cl_list_remove_all(&tmp_parser_struct.str_list);
1248 }
1249 ;
1250
1251 port_group_port_name_start: TK_PORT_NAME {
1252 RESET_BUFFER;
1253 }
1254 ;
1255
1256 port_group_port_guid: port_group_port_guid_start list_of_ranges {
1257 /* 'port-guid' in 'port-group' - any num of instances */
1258 /* list of guid ranges */
1259 if (cl_list_count(&tmp_parser_struct.num_pair_list))
1260 {
1261 uint64_t ** range_arr;
1262 unsigned range_len;
1263
1264 __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
1265 &range_arr,
1266 &range_len );
1267
1268 __parser_add_guid_range_to_port_map(
1269 &p_current_port_group->port_map,
1270 range_arr,
1271 range_len);
1272 }
1273 }
1274 ;
1275
1276 port_group_port_guid_start: TK_PORT_GUID {
1277 RESET_BUFFER;
1278 }
1279 ;
1280
1281 port_group_pkey: port_group_pkey_start list_of_ranges {
1282 /* 'pkey' in 'port-group' - any num of instances */
1283 /* list of pkey ranges */
1284 if (cl_list_count(&tmp_parser_struct.num_pair_list))
1285 {
1286 uint64_t ** range_arr;
1287 unsigned range_len;
1288
1289 __pkey_rangelist2rangearr( &tmp_parser_struct.num_pair_list,
1290 &range_arr,
1291 &range_len );
1292
1293 __parser_add_pkey_range_to_port_map(
1294 &p_current_port_group->port_map,
1295 range_arr,
1296 range_len);
1297 }
1298 }
1299 ;
1300
1301 port_group_pkey_start: TK_PKEY {
1302 RESET_BUFFER;
1303 }
1304 ;
1305
1306 port_group_partition: port_group_partition_start string_list {
1307 /* 'partition' in 'port-group' - any num of instances */
1308 __parser_add_partition_list_to_port_map(
1309 &p_current_port_group->port_map,
1310 &tmp_parser_struct.str_list);
1311 }
1312 ;
1313
1314 port_group_partition_start: TK_PARTITION {
1315 RESET_BUFFER;
1316 }
1317 ;
1318
1319 port_group_node_type: port_group_node_type_start port_group_node_type_list {
1320 /* 'node-type' in 'port-group' - any num of instances */
1321 }
1322 ;
1323
1324 port_group_node_type_start: TK_NODE_TYPE {
1325 RESET_BUFFER;
1326 }
1327 ;
1328
1329 port_group_node_type_list: node_type_item
1330 | port_group_node_type_list TK_COMMA node_type_item
1331 ;
1332
1333 node_type_item: node_type_ca
1334 | node_type_switch
1335 | node_type_router
1336 | node_type_all
1337 | node_type_self
1338 ;
1339
1340 node_type_ca: TK_NODE_TYPE_CA {
1341 p_current_port_group->node_types |=
1342 OSM_QOS_POLICY_NODE_TYPE_CA;
1343 }
1344 ;
1345
1346 node_type_switch: TK_NODE_TYPE_SWITCH {
1347 p_current_port_group->node_types |=
1348 OSM_QOS_POLICY_NODE_TYPE_SWITCH;
1349 }
1350 ;
1351
1352 node_type_router: TK_NODE_TYPE_ROUTER {
1353 p_current_port_group->node_types |=
1354 OSM_QOS_POLICY_NODE_TYPE_ROUTER;
1355 }
1356 ;
1357
1358 node_type_all: TK_NODE_TYPE_ALL {
1359 p_current_port_group->node_types |=
1360 (OSM_QOS_POLICY_NODE_TYPE_CA |
1361 OSM_QOS_POLICY_NODE_TYPE_SWITCH |
1362 OSM_QOS_POLICY_NODE_TYPE_ROUTER);
1363 }
1364 ;
1365
1366 node_type_self: TK_NODE_TYPE_SELF {
1367 osm_port_t * p_osm_port =
1368 osm_get_port_by_guid(p_qos_policy->p_subn,
1369 p_qos_policy->p_subn->sm_port_guid);
1370 if (p_osm_port)
1371 __parser_add_port_to_port_map(
1372 &p_current_port_group->port_map,
1373 p_osm_port->p_physp);
1374 }
1375 ;
1376
1377 /*
1378 * vlarb_scope_entry values:
1379 * vlarb_scope_group
1380 * vlarb_scope_across
1381 * vlarb_scope_vlarb_high
1382 * vlarb_scope_vlarb_low
1383 * vlarb_scope_vlarb_high_limit
1384 */
1385
1386
1387
1388 vlarb_scope_group: vlarb_scope_group_start string_list {
1389 /* 'group' in 'vlarb-scope' - any num of instances */
1390 cl_list_iterator_t list_iterator;
1391 char * tmp_str;
1392
1393 list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1394 while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1395 {
1396 tmp_str = (char*)cl_list_obj(list_iterator);
1397 if (tmp_str)
1398 cl_list_insert_tail(&p_current_vlarb_scope->group_list,tmp_str);
1399 list_iterator = cl_list_next(list_iterator);
1400 }
1401 cl_list_remove_all(&tmp_parser_struct.str_list);
1402 }
1403 ;
1404
1405 vlarb_scope_group_start: TK_GROUP {
1406 RESET_BUFFER;
1407 }
1408 ;
1409
1410 vlarb_scope_across: vlarb_scope_across_start string_list {
1411 /* 'across' in 'vlarb-scope' - any num of instances */
1412 cl_list_iterator_t list_iterator;
1413 char * tmp_str;
1414
1415 list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1416 while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1417 {
1418 tmp_str = (char*)cl_list_obj(list_iterator);
1419 if (tmp_str)
1420 cl_list_insert_tail(&p_current_vlarb_scope->across_list,tmp_str);
1421 list_iterator = cl_list_next(list_iterator);
1422 }
1423 cl_list_remove_all(&tmp_parser_struct.str_list);
1424 }
1425 ;
1426
1427 vlarb_scope_across_start: TK_ACROSS {
1428 RESET_BUFFER;
1429 }
1430 ;
1431
1432 vlarb_scope_vlarb_high_limit: vlarb_scope_vlarb_high_limit_start single_number {
1433 /* 'vl-high-limit' in 'vlarb-scope' - one instance of one number */
1434 cl_list_iterator_t list_iterator;
1435 uint64_t * p_tmp_num;
1436
1437 list_iterator = cl_list_head(&tmp_parser_struct.num_list);
1438 p_tmp_num = (uint64_t*)cl_list_obj(list_iterator);
1439 if (p_tmp_num)
1440 {
1441 p_current_vlarb_scope->vl_high_limit = (uint32_t)(*p_tmp_num);
1442 p_current_vlarb_scope->vl_high_limit_set = TRUE;
1443 free(p_tmp_num);
1444 }
1445
1446 cl_list_remove_all(&tmp_parser_struct.num_list);
1447 }
1448 ;
1449
1450 vlarb_scope_vlarb_high_limit_start: TK_VLARB_HIGH_LIMIT {
1451 RESET_BUFFER;
1452 }
1453 ;
1454
1455 vlarb_scope_vlarb_high: vlarb_scope_vlarb_high_start num_list_with_dotdot {
1456 /* 'vlarb-high' in 'vlarb-scope' - list of pairs of numbers with ':' and ',' */
1457 cl_list_iterator_t list_iterator;
1458 uint64_t * num_pair;
1459
1460 list_iterator = cl_list_head(&tmp_parser_struct.num_pair_list);
1461 while( list_iterator != cl_list_end(&tmp_parser_struct.num_pair_list) )
1462 {
1463 num_pair = (uint64_t*)cl_list_obj(list_iterator);
1464 if (num_pair)
1465 cl_list_insert_tail(&p_current_vlarb_scope->vlarb_high_list,num_pair);
1466 list_iterator = cl_list_next(list_iterator);
1467 }
1468 cl_list_remove_all(&tmp_parser_struct.num_pair_list);
1469 }
1470 ;
1471
1472 vlarb_scope_vlarb_high_start: TK_VLARB_HIGH {
1473 RESET_BUFFER;
1474 }
1475 ;
1476
1477 vlarb_scope_vlarb_low: vlarb_scope_vlarb_low_start num_list_with_dotdot {
1478 /* 'vlarb-low' in 'vlarb-scope' - list of pairs of numbers with ':' and ',' */
1479 cl_list_iterator_t list_iterator;
1480 uint64_t * num_pair;
1481
1482 list_iterator = cl_list_head(&tmp_parser_struct.num_pair_list);
1483 while( list_iterator != cl_list_end(&tmp_parser_struct.num_pair_list) )
1484 {
1485 num_pair = (uint64_t*)cl_list_obj(list_iterator);
1486 if (num_pair)
1487 cl_list_insert_tail(&p_current_vlarb_scope->vlarb_low_list,num_pair);
1488 list_iterator = cl_list_next(list_iterator);
1489 }
1490 cl_list_remove_all(&tmp_parser_struct.num_pair_list);
1491 }
1492 ;
1493
1494 vlarb_scope_vlarb_low_start: TK_VLARB_LOW {
1495 RESET_BUFFER;
1496 }
1497 ;
1498
1499 /*
1500 * sl2vl_scope_entry values:
1501 * sl2vl_scope_group
1502 * sl2vl_scope_across
1503 * sl2vl_scope_across_from
1504 * sl2vl_scope_across_to
1505 * sl2vl_scope_from
1506 * sl2vl_scope_to
1507 * sl2vl_scope_sl2vl_table
1508 */
1509
1510 sl2vl_scope_group: sl2vl_scope_group_start string_list {
1511 /* 'group' in 'sl2vl-scope' - any num of instances */
1512 cl_list_iterator_t list_iterator;
1513 char * tmp_str;
1514
1515 list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1516 while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1517 {
1518 tmp_str = (char*)cl_list_obj(list_iterator);
1519 if (tmp_str)
1520 cl_list_insert_tail(&p_current_sl2vl_scope->group_list,tmp_str);
1521 list_iterator = cl_list_next(list_iterator);
1522 }
1523 cl_list_remove_all(&tmp_parser_struct.str_list);
1524 }
1525 ;
1526
1527 sl2vl_scope_group_start: TK_GROUP {
1528 RESET_BUFFER;
1529 }
1530 ;
1531
1532 sl2vl_scope_across: sl2vl_scope_across_start string_list {
1533 /* 'across' in 'sl2vl-scope' - any num of instances */
1534 cl_list_iterator_t list_iterator;
1535 char * tmp_str;
1536
1537 list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1538 while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1539 {
1540 tmp_str = (char*)cl_list_obj(list_iterator);
1541 if (tmp_str) {
1542 cl_list_insert_tail(&p_current_sl2vl_scope->across_from_list,tmp_str);
1543 cl_list_insert_tail(&p_current_sl2vl_scope->across_to_list,strdup(tmp_str));
1544 }
1545 list_iterator = cl_list_next(list_iterator);
1546 }
1547 cl_list_remove_all(&tmp_parser_struct.str_list);
1548 }
1549 ;
1550
1551 sl2vl_scope_across_start: TK_ACROSS {
1552 RESET_BUFFER;
1553 }
1554 ;
1555
1556 sl2vl_scope_across_from: sl2vl_scope_across_from_start string_list {
1557 /* 'across-from' in 'sl2vl-scope' - any num of instances */
1558 cl_list_iterator_t list_iterator;
1559 char * tmp_str;
1560
1561 list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1562 while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1563 {
1564 tmp_str = (char*)cl_list_obj(list_iterator);
1565 if (tmp_str)
1566 cl_list_insert_tail(&p_current_sl2vl_scope->across_from_list,tmp_str);
1567 list_iterator = cl_list_next(list_iterator);
1568 }
1569 cl_list_remove_all(&tmp_parser_struct.str_list);
1570 }
1571 ;
1572
1573 sl2vl_scope_across_from_start: TK_ACROSS_FROM {
1574 RESET_BUFFER;
1575 }
1576 ;
1577
1578 sl2vl_scope_across_to: sl2vl_scope_across_to_start string_list {
1579 /* 'across-to' in 'sl2vl-scope' - any num of instances */
1580 cl_list_iterator_t list_iterator;
1581 char * tmp_str;
1582
1583 list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1584 while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1585 {
1586 tmp_str = (char*)cl_list_obj(list_iterator);
1587 if (tmp_str) {
1588 cl_list_insert_tail(&p_current_sl2vl_scope->across_to_list,tmp_str);
1589 }
1590 list_iterator = cl_list_next(list_iterator);
1591 }
1592 cl_list_remove_all(&tmp_parser_struct.str_list);
1593 }
1594 ;
1595
1596 sl2vl_scope_across_to_start: TK_ACROSS_TO {
1597 RESET_BUFFER;
1598 }
1599 ;
1600
1601 sl2vl_scope_from: sl2vl_scope_from_start sl2vl_scope_from_list_or_asterisk {
1602 /* 'from' in 'sl2vl-scope' - any num of instances */
1603 }
1604 ;
1605
1606 sl2vl_scope_from_start: TK_FROM {
1607 RESET_BUFFER;
1608 }
1609 ;
1610
1611 sl2vl_scope_to: sl2vl_scope_to_start sl2vl_scope_to_list_or_asterisk {
1612 /* 'to' in 'sl2vl-scope' - any num of instances */
1613 }
1614 ;
1615
1616 sl2vl_scope_to_start: TK_TO {
1617 RESET_BUFFER;
1618 }
1619 ;
1620
1621 sl2vl_scope_from_list_or_asterisk: sl2vl_scope_from_asterisk
1622 | sl2vl_scope_from_list_of_ranges
1623 ;
1624
1625 sl2vl_scope_from_asterisk: TK_ASTERISK {
1626 int i;
1627 for (i = 0; i < OSM_QOS_POLICY_MAX_PORTS_ON_SWITCH; i++)
1628 p_current_sl2vl_scope->from[i] = TRUE;
1629 }
1630 ;
1631
1632 sl2vl_scope_to_list_or_asterisk: sl2vl_scope_to_asterisk
1633 | sl2vl_scope_to_list_of_ranges
1634 ;
1635
1636 sl2vl_scope_to_asterisk: TK_ASTERISK {
1637 int i;
1638 for (i = 0; i < OSM_QOS_POLICY_MAX_PORTS_ON_SWITCH; i++)
1639 p_current_sl2vl_scope->to[i] = TRUE;
1640 }
1641 ;
1642
1643 sl2vl_scope_from_list_of_ranges: list_of_ranges {
1644 int i;
1645 cl_list_iterator_t list_iterator;
1646 uint64_t * num_pair;
1647 uint8_t num1, num2;
1648
1649 list_iterator = cl_list_head(&tmp_parser_struct.num_pair_list);
1650 while( list_iterator != cl_list_end(&tmp_parser_struct.num_pair_list) )
1651 {
1652 num_pair = (uint64_t*)cl_list_obj(list_iterator);
1653 if (num_pair)
1654 {
1655 if ( num_pair[1] >= OSM_QOS_POLICY_MAX_PORTS_ON_SWITCH )
1656 {
1657 yyerror("port number out of range 'from' list");
1658 free(num_pair);
1659 cl_list_remove_all(&tmp_parser_struct.num_pair_list);
1660 return 1;
1661 }
1662 num1 = (uint8_t)num_pair[0];
1663 num2 = (uint8_t)num_pair[1];
1664 free(num_pair);
1665 for (i = num1; i <= num2; i++)
1666 p_current_sl2vl_scope->from[i] = TRUE;
1667 }
1668 list_iterator = cl_list_next(list_iterator);
1669 }
1670 cl_list_remove_all(&tmp_parser_struct.num_pair_list);
1671 }
1672 ;
1673
1674 sl2vl_scope_to_list_of_ranges: list_of_ranges {
1675 int i;
1676 cl_list_iterator_t list_iterator;
1677 uint64_t * num_pair;
1678 uint8_t num1, num2;
1679
1680 list_iterator = cl_list_head(&tmp_parser_struct.num_pair_list);
1681 while( list_iterator != cl_list_end(&tmp_parser_struct.num_pair_list) )
1682 {
1683 num_pair = (uint64_t*)cl_list_obj(list_iterator);
1684 if (num_pair)
1685 {
1686 if ( num_pair[1] >= OSM_QOS_POLICY_MAX_PORTS_ON_SWITCH )
1687 {
1688 yyerror("port number out of range 'to' list");
1689 free(num_pair);
1690 cl_list_remove_all(&tmp_parser_struct.num_pair_list);
1691 return 1;
1692 }
1693 num1 = (uint8_t)num_pair[0];
1694 num2 = (uint8_t)num_pair[1];
1695 free(num_pair);
1696 for (i = num1; i <= num2; i++)
1697 p_current_sl2vl_scope->to[i] = TRUE;
1698 }
1699 list_iterator = cl_list_next(list_iterator);
1700 }
1701 cl_list_remove_all(&tmp_parser_struct.num_pair_list);
1702 }
1703 ;
1704
1705
1706 sl2vl_scope_sl2vl_table: sl2vl_scope_sl2vl_table_start num_list {
1707 /* 'sl2vl-table' - one instance of exactly
1708 OSM_QOS_POLICY_SL2VL_TABLE_LEN numbers */
1709 cl_list_iterator_t list_iterator;
1710 uint64_t num;
1711 uint64_t * p_num;
1712 int i = 0;
1713
1714 if (p_current_sl2vl_scope->sl2vl_table_set)
1715 {
1716 yyerror("sl2vl-scope has more than one sl2vl-table");
1717 cl_list_remove_all(&tmp_parser_struct.num_list);
1718 return 1;
1719 }
1720
1721 if (cl_list_count(&tmp_parser_struct.num_list) != OSM_QOS_POLICY_SL2VL_TABLE_LEN)
1722 {
1723 yyerror("wrong number of values in 'sl2vl-table' (should be 16)");
1724 cl_list_remove_all(&tmp_parser_struct.num_list);
1725 return 1;
1726 }
1727
1728 list_iterator = cl_list_head(&tmp_parser_struct.num_list);
1729 while( list_iterator != cl_list_end(&tmp_parser_struct.num_list) )
1730 {
1731 p_num = (uint64_t*)cl_list_obj(list_iterator);
1732 num = *p_num;
1733 free(p_num);
1734 if (num >= OSM_QOS_POLICY_MAX_VL_NUM)
1735 {
1736 yyerror("wrong VL value in 'sl2vl-table' (should be 0 to 15)");
1737 cl_list_remove_all(&tmp_parser_struct.num_list);
1738 return 1;
1739 }
1740
1741 p_current_sl2vl_scope->sl2vl_table[i++] = (uint8_t)num;
1742 list_iterator = cl_list_next(list_iterator);
1743 }
1744 p_current_sl2vl_scope->sl2vl_table_set = TRUE;
1745 cl_list_remove_all(&tmp_parser_struct.num_list);
1746 }
1747 ;
1748
1749 sl2vl_scope_sl2vl_table_start: TK_SL2VL_TABLE {
1750 RESET_BUFFER;
1751 }
1752 ;
1753
1754 /*
1755 * qos_level_entry values:
1756 * qos_level_name
1757 * qos_level_use
1758 * qos_level_sl
1759 * qos_level_mtu_limit
1760 * qos_level_rate_limit
1761 * qos_level_packet_life
1762 * qos_level_path_bits
1763 * qos_level_pkey
1764 */
1765
1766 qos_level_name: qos_level_name_start single_string {
1767 /* 'name' of 'qos-level' - one instance */
1768 cl_list_iterator_t list_iterator;
1769 char * tmp_str;
1770
1771 if (p_current_qos_level->name)
1772 {
1773 yyerror("qos-level has multiple 'name' tags");
1774 cl_list_remove_all(&tmp_parser_struct.str_list);
1775 return 1;
1776 }
1777
1778 list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1779 if ( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1780 {
1781 tmp_str = (char*)cl_list_obj(list_iterator);
1782 if (tmp_str)
1783 p_current_qos_level->name = tmp_str;
1784 }
1785 cl_list_remove_all(&tmp_parser_struct.str_list);
1786 }
1787 ;
1788
1789 qos_level_name_start: TK_NAME {
1790 RESET_BUFFER;
1791 }
1792 ;
1793
1794 qos_level_use: qos_level_use_start single_string {
1795 /* 'use' of 'qos-level' - one instance */
1796 cl_list_iterator_t list_iterator;
1797 char * tmp_str;
1798
1799 if (p_current_qos_level->use)
1800 {
1801 yyerror("qos-level has multiple 'use' tags");
1802 cl_list_remove_all(&tmp_parser_struct.str_list);
1803 return 1;
1804 }
1805
1806 list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1807 if ( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1808 {
1809 tmp_str = (char*)cl_list_obj(list_iterator);
1810 if (tmp_str)
1811 p_current_qos_level->use = tmp_str;
1812 }
1813 cl_list_remove_all(&tmp_parser_struct.str_list);
1814 }
1815 ;
1816
1817 qos_level_use_start: TK_USE {
1818 RESET_BUFFER;
1819 }
1820 ;
1821
1822 qos_level_sl: qos_level_sl_start single_number {
1823 /* 'sl' in 'qos-level' - one instance */
1824 cl_list_iterator_t list_iterator;
1825 uint64_t * p_num;
1826
1827 if (p_current_qos_level->sl_set)
1828 {
1829 yyerror("'qos-level' has multiple 'sl' tags");
1830 cl_list_remove_all(&tmp_parser_struct.num_list);
1831 return 1;
1832 }
1833 list_iterator = cl_list_head(&tmp_parser_struct.num_list);
1834 p_num = (uint64_t*)cl_list_obj(list_iterator);
1835 p_current_qos_level->sl = (uint8_t)(*p_num);
1836 free(p_num);
1837 p_current_qos_level->sl_set = TRUE;
1838 cl_list_remove_all(&tmp_parser_struct.num_list);
1839 }
1840 ;
1841
1842 qos_level_sl_start: TK_SL {
1843 RESET_BUFFER;
1844 }
1845 ;
1846
1847 qos_level_mtu_limit: qos_level_mtu_limit_start single_number {
1848 /* 'mtu-limit' in 'qos-level' - one instance */
1849 cl_list_iterator_t list_iterator;
1850 uint64_t * p_num;
1851
1852 if (p_current_qos_level->mtu_limit_set)
1853 {
1854 yyerror("'qos-level' has multiple 'mtu-limit' tags");
1855 cl_list_remove_all(&tmp_parser_struct.num_list);
1856 return 1;
1857 }
1858 list_iterator = cl_list_head(&tmp_parser_struct.num_list);
1859 p_num = (uint64_t*)cl_list_obj(list_iterator);
1860 if (*p_num > OSM_QOS_POLICY_MAX_MTU || *p_num < OSM_QOS_POLICY_MIN_MTU)
1861 {
1862 yyerror("mtu limit is out of range, value: %d", *p_num);
1863 free(p_num);
1864 cl_list_remove_all(&tmp_parser_struct.num_list);
1865 return 1;
1866 }
1867 p_current_qos_level->mtu_limit = (uint8_t)(*p_num);
1868 free(p_num);
1869 p_current_qos_level->mtu_limit_set = TRUE;
1870 cl_list_remove_all(&tmp_parser_struct.num_list);
1871 }
1872 ;
1873
1874 qos_level_mtu_limit_start: TK_MTU_LIMIT {
1875 /* 'mtu-limit' in 'qos-level' - one instance */
1876 RESET_BUFFER;
1877 }
1878 ;
1879
1880 qos_level_rate_limit: qos_level_rate_limit_start single_number {
1881 /* 'rate-limit' in 'qos-level' - one instance */
1882 cl_list_iterator_t list_iterator;
1883 uint64_t * p_num;
1884
1885 if (p_current_qos_level->rate_limit_set)
1886 {
1887 yyerror("'qos-level' has multiple 'rate-limit' tags");
1888 cl_list_remove_all(&tmp_parser_struct.num_list);
1889 return 1;
1890 }
1891 list_iterator = cl_list_head(&tmp_parser_struct.num_list);
1892 p_num = (uint64_t*)cl_list_obj(list_iterator);
1893 if (*p_num > OSM_QOS_POLICY_MAX_RATE || *p_num < OSM_QOS_POLICY_MIN_RATE)
1894 {
1895 yyerror("rate limit is out of range, value: %d", *p_num);
1896 free(p_num);
1897 cl_list_remove_all(&tmp_parser_struct.num_list);
1898 return 1;
1899 }
1900 p_current_qos_level->rate_limit = (uint8_t)(*p_num);
1901 free(p_num);
1902 p_current_qos_level->rate_limit_set = TRUE;
1903 cl_list_remove_all(&tmp_parser_struct.num_list);
1904 }
1905 ;
1906
1907 qos_level_rate_limit_start: TK_RATE_LIMIT {
1908 /* 'rate-limit' in 'qos-level' - one instance */
1909 RESET_BUFFER;
1910 }
1911 ;
1912
1913 qos_level_packet_life: qos_level_packet_life_start single_number {
1914 /* 'packet-life' in 'qos-level' - one instance */
1915 cl_list_iterator_t list_iterator;
1916 uint64_t * p_num;
1917
1918 if (p_current_qos_level->pkt_life_set)
1919 {
1920 yyerror("'qos-level' has multiple 'packet-life' tags");
1921 cl_list_remove_all(&tmp_parser_struct.num_list);
1922 return 1;
1923 }
1924 list_iterator = cl_list_head(&tmp_parser_struct.num_list);
1925 p_num = (uint64_t*)cl_list_obj(list_iterator);
1926 p_current_qos_level->pkt_life = (uint8_t)(*p_num);
1927 free(p_num);
1928 p_current_qos_level->pkt_life_set= TRUE;
1929 cl_list_remove_all(&tmp_parser_struct.num_list);
1930 }
1931 ;
1932
1933 qos_level_packet_life_start: TK_PACKET_LIFE {
1934 /* 'packet-life' in 'qos-level' - one instance */
1935 RESET_BUFFER;
1936 }
1937 ;
1938
1939 qos_level_path_bits: qos_level_path_bits_start list_of_ranges {
1940 /* 'path-bits' in 'qos-level' - any num of instances */
1941 /* list of path bit ranges */
1942
1943 if (cl_list_count(&tmp_parser_struct.num_pair_list))
1944 {
1945 uint64_t ** range_arr;
1946 unsigned range_len;
1947
1948 __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
1949 &range_arr,
1950 &range_len );
1951
1952 if ( !p_current_qos_level->path_bits_range_len )
1953 {
1954 p_current_qos_level->path_bits_range_arr = range_arr;
1955 p_current_qos_level->path_bits_range_len = range_len;
1956 }
1957 else
1958 {
1959 uint64_t ** new_range_arr;
1960 unsigned new_range_len;
1961 __merge_rangearr( p_current_qos_level->path_bits_range_arr,
1962 p_current_qos_level->path_bits_range_len,
1963 range_arr,
1964 range_len,
1965 &new_range_arr,
1966 &new_range_len );
1967 p_current_qos_level->path_bits_range_arr = new_range_arr;
1968 p_current_qos_level->path_bits_range_len = new_range_len;
1969 }
1970 }
1971 }
1972 ;
1973
1974 qos_level_path_bits_start: TK_PATH_BITS {
1975 RESET_BUFFER;
1976 }
1977 ;
1978
1979 qos_level_pkey: qos_level_pkey_start list_of_ranges {
1980 /* 'pkey' in 'qos-level' - num of instances of list of ranges */
1981 if (cl_list_count(&tmp_parser_struct.num_pair_list))
1982 {
1983 uint64_t ** range_arr;
1984 unsigned range_len;
1985
1986 __pkey_rangelist2rangearr( &tmp_parser_struct.num_pair_list,
1987 &range_arr,
1988 &range_len );
1989
1990 if ( !p_current_qos_level->pkey_range_len )
1991 {
1992 p_current_qos_level->pkey_range_arr = range_arr;
1993 p_current_qos_level->pkey_range_len = range_len;
1994 }
1995 else
1996 {
1997 uint64_t ** new_range_arr;
1998 unsigned new_range_len;
1999 __merge_rangearr( p_current_qos_level->pkey_range_arr,
2000 p_current_qos_level->pkey_range_len,
2001 range_arr,
2002 range_len,
2003 &new_range_arr,
2004 &new_range_len );
2005 p_current_qos_level->pkey_range_arr = new_range_arr;
2006 p_current_qos_level->pkey_range_len = new_range_len;
2007 }
2008 }
2009 }
2010 ;
2011
2012 qos_level_pkey_start: TK_PKEY {
2013 RESET_BUFFER;
2014 }
2015 ;
2016
2017 /*
2018 * qos_match_rule_entry values:
2019 * qos_match_rule_use
2020 * qos_match_rule_qos_class
2021 * qos_match_rule_qos_level_name
2022 * qos_match_rule_source
2023 * qos_match_rule_destination
2024 * qos_match_rule_service_id
2025 * qos_match_rule_pkey
2026 */
2027
2028
2029 qos_match_rule_use: qos_match_rule_use_start single_string {
2030 /* 'use' of 'qos-match-rule' - one instance */
2031 cl_list_iterator_t list_iterator;
2032 char * tmp_str;
2033
2034 if (p_current_qos_match_rule->use)
2035 {
2036 yyerror("'qos-match-rule' has multiple 'use' tags");
2037 cl_list_remove_all(&tmp_parser_struct.str_list);
2038 return 1;
2039 }
2040
2041 list_iterator = cl_list_head(&tmp_parser_struct.str_list);
2042 if ( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
2043 {
2044 tmp_str = (char*)cl_list_obj(list_iterator);
2045 if (tmp_str)
2046 p_current_qos_match_rule->use = tmp_str;
2047 }
2048 cl_list_remove_all(&tmp_parser_struct.str_list);
2049 }
2050 ;
2051
2052 qos_match_rule_use_start: TK_USE {
2053 RESET_BUFFER;
2054 }
2055 ;
2056
2057 qos_match_rule_qos_class: qos_match_rule_qos_class_start list_of_ranges {
2058 /* 'qos-class' in 'qos-match-rule' - num of instances of list of ranges */
2059 /* list of class ranges (QoS Class is 12-bit value) */
2060 if (cl_list_count(&tmp_parser_struct.num_pair_list))
2061 {
2062 uint64_t ** range_arr;
2063 unsigned range_len;
2064
2065 __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
2066 &range_arr,
2067 &range_len );
2068
2069 if ( !p_current_qos_match_rule->qos_class_range_len )
2070 {
2071 p_current_qos_match_rule->qos_class_range_arr = range_arr;
2072 p_current_qos_match_rule->qos_class_range_len = range_len;
2073 }
2074 else
2075 {
2076 uint64_t ** new_range_arr;
2077 unsigned new_range_len;
2078 __merge_rangearr( p_current_qos_match_rule->qos_class_range_arr,
2079 p_current_qos_match_rule->qos_class_range_len,
2080 range_arr,
2081 range_len,
2082 &new_range_arr,
2083 &new_range_len );
2084 p_current_qos_match_rule->qos_class_range_arr = new_range_arr;
2085 p_current_qos_match_rule->qos_class_range_len = new_range_len;
2086 }
2087 }
2088 }
2089 ;
2090
2091 qos_match_rule_qos_class_start: TK_QOS_CLASS {
2092 RESET_BUFFER;
2093 }
2094 ;
2095
2096 qos_match_rule_source: qos_match_rule_source_start string_list {
2097 /* 'source' in 'qos-match-rule' - text */
2098 cl_list_iterator_t list_iterator;
2099 char * tmp_str;
2100
2101 list_iterator = cl_list_head(&tmp_parser_struct.str_list);
2102 while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
2103 {
2104 tmp_str = (char*)cl_list_obj(list_iterator);
2105 if (tmp_str)
2106 cl_list_insert_tail(&p_current_qos_match_rule->source_list,tmp_str);
2107 list_iterator = cl_list_next(list_iterator);
2108 }
2109 cl_list_remove_all(&tmp_parser_struct.str_list);
2110 }
2111 ;
2112
2113 qos_match_rule_source_start: TK_SOURCE {
2114 RESET_BUFFER;
2115 }
2116 ;
2117
2118 qos_match_rule_destination: qos_match_rule_destination_start string_list {
2119 /* 'destination' in 'qos-match-rule' - text */
2120 cl_list_iterator_t list_iterator;
2121 char * tmp_str;
2122
2123 list_iterator = cl_list_head(&tmp_parser_struct.str_list);
2124 while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
2125 {
2126 tmp_str = (char*)cl_list_obj(list_iterator);
2127 if (tmp_str)
2128 cl_list_insert_tail(&p_current_qos_match_rule->destination_list,tmp_str);
2129 list_iterator = cl_list_next(list_iterator);
2130 }
2131 cl_list_remove_all(&tmp_parser_struct.str_list);
2132 }
2133 ;
2134
2135 qos_match_rule_destination_start: TK_DESTINATION {
2136 RESET_BUFFER;
2137 }
2138 ;
2139
2140 qos_match_rule_qos_level_name: qos_match_rule_qos_level_name_start single_string {
2141 /* 'qos-level-name' in 'qos-match-rule' - single string */
2142 cl_list_iterator_t list_iterator;
2143 char * tmp_str;
2144
2145 if (p_current_qos_match_rule->qos_level_name)
2146 {
2147 yyerror("qos-match-rule has multiple 'qos-level-name' tags");
2148 cl_list_remove_all(&tmp_parser_struct.num_list);
2149 return 1;
2150 }
2151
2152 list_iterator = cl_list_head(&tmp_parser_struct.str_list);
2153 if ( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
2154 {
2155 tmp_str = (char*)cl_list_obj(list_iterator);
2156 if (tmp_str)
2157 p_current_qos_match_rule->qos_level_name = tmp_str;
2158 }
2159 cl_list_remove_all(&tmp_parser_struct.str_list);
2160 }
2161 ;
2162
2163 qos_match_rule_qos_level_name_start: TK_QOS_LEVEL_NAME {
2164 RESET_BUFFER;
2165 }
2166 ;
2167
2168 qos_match_rule_service_id: qos_match_rule_service_id_start list_of_ranges {
2169 /* 'service-id' in 'qos-match-rule' - num of instances of list of ranges */
2170 if (cl_list_count(&tmp_parser_struct.num_pair_list))
2171 {
2172 uint64_t ** range_arr;
2173 unsigned range_len;
2174
2175 __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
2176 &range_arr,
2177 &range_len );
2178
2179 if ( !p_current_qos_match_rule->service_id_range_len )
2180 {
2181 p_current_qos_match_rule->service_id_range_arr = range_arr;
2182 p_current_qos_match_rule->service_id_range_len = range_len;
2183 }
2184 else
2185 {
2186 uint64_t ** new_range_arr;
2187 unsigned new_range_len;
2188 __merge_rangearr( p_current_qos_match_rule->service_id_range_arr,
2189 p_current_qos_match_rule->service_id_range_len,
2190 range_arr,
2191 range_len,
2192 &new_range_arr,
2193 &new_range_len );
2194 p_current_qos_match_rule->service_id_range_arr = new_range_arr;
2195 p_current_qos_match_rule->service_id_range_len = new_range_len;
2196 }
2197 }
2198 }
2199 ;
2200
2201 qos_match_rule_service_id_start: TK_SERVICE_ID {
2202 RESET_BUFFER;
2203 }
2204 ;
2205
2206 qos_match_rule_pkey: qos_match_rule_pkey_start list_of_ranges {
2207 /* 'pkey' in 'qos-match-rule' - num of instances of list of ranges */
2208 if (cl_list_count(&tmp_parser_struct.num_pair_list))
2209 {
2210 uint64_t ** range_arr;
2211 unsigned range_len;
2212
2213 __pkey_rangelist2rangearr( &tmp_parser_struct.num_pair_list,
2214 &range_arr,
2215 &range_len );
2216
2217 if ( !p_current_qos_match_rule->pkey_range_len )
2218 {
2219 p_current_qos_match_rule->pkey_range_arr = range_arr;
2220 p_current_qos_match_rule->pkey_range_len = range_len;
2221 }
2222 else
2223 {
2224 uint64_t ** new_range_arr;
2225 unsigned new_range_len;
2226 __merge_rangearr( p_current_qos_match_rule->pkey_range_arr,
2227 p_current_qos_match_rule->pkey_range_len,
2228 range_arr,
2229 range_len,
2230 &new_range_arr,
2231 &new_range_len );
2232 p_current_qos_match_rule->pkey_range_arr = new_range_arr;
2233 p_current_qos_match_rule->pkey_range_len = new_range_len;
2234 }
2235 }
2236 }
2237 ;
2238
2239 qos_match_rule_pkey_start: TK_PKEY {
2240 RESET_BUFFER;
2241 }
2242 ;
2243
2244
2245 /*
2246 * Common part
2247 */
2248
2249
2250 single_string: single_string_elems {
2251 cl_list_insert_tail(&tmp_parser_struct.str_list,
2252 strdup(__parser_strip_white(tmp_parser_struct.str)));
2253 tmp_parser_struct.str[0] = '\0';
2254 }
2255 ;
2256
2257 single_string_elems: single_string_element
2258 | single_string_elems single_string_element
2259 ;
2260
2261 single_string_element: TK_TEXT {
2262 strcat(tmp_parser_struct.str,$1);
2263 free($1);
2264 }
2265 ;
2266
2267
2268 string_list: single_string
2269 | string_list TK_COMMA single_string
2270 ;
2271
2272
2273
2274 single_number: number
2275 ;
2276
2277 num_list: number
2278 | num_list TK_COMMA number
2279 ;
2280
2281 number: TK_NUMBER {
2282 uint64_t * p_num = (uint64_t*)malloc(sizeof(uint64_t));
2283 __parser_str2uint64(p_num,$1);
2284 free($1);
2285 cl_list_insert_tail(&tmp_parser_struct.num_list, p_num);
2286 }
2287 ;
2288
2289 num_list_with_dotdot: number_from_pair_1 TK_DOTDOT number_from_pair_2 {
2290 uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
2291 num_pair[0] = tmp_parser_struct.num_pair[0];
2292 num_pair[1] = tmp_parser_struct.num_pair[1];
2293 cl_list_insert_tail(&tmp_parser_struct.num_pair_list, num_pair);
2294 }
2295 | num_list_with_dotdot TK_COMMA number_from_pair_1 TK_DOTDOT number_from_pair_2 {
2296 uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
2297 num_pair[0] = tmp_parser_struct.num_pair[0];
2298 num_pair[1] = tmp_parser_struct.num_pair[1];
2299 cl_list_insert_tail(&tmp_parser_struct.num_pair_list, num_pair);
2300 }
2301 ;
2302
2303 number_from_pair_1: TK_NUMBER {
2304 __parser_str2uint64(&tmp_parser_struct.num_pair[0],$1);
2305 free($1);
2306 }
2307 ;
2308
2309 number_from_pair_2: TK_NUMBER {
2310 __parser_str2uint64(&tmp_parser_struct.num_pair[1],$1);
2311 free($1);
2312 }
2313 ;
2314
2315 list_of_ranges: num_list_with_dash
2316 ;
2317
2318 num_list_with_dash: single_number_from_range {
2319 uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
2320 num_pair[0] = tmp_parser_struct.num_pair[0];
2321 num_pair[1] = tmp_parser_struct.num_pair[1];
2322 cl_list_insert_tail(&tmp_parser_struct.num_pair_list, num_pair);
2323 }
2324 | number_from_range_1 TK_DASH number_from_range_2 {
2325 uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
2326 if (tmp_parser_struct.num_pair[0] <= tmp_parser_struct.num_pair[1]) {
2327 num_pair[0] = tmp_parser_struct.num_pair[0];
2328 num_pair[1] = tmp_parser_struct.num_pair[1];
2329 }
2330 else {
2331 num_pair[1] = tmp_parser_struct.num_pair[0];
2332 num_pair[0] = tmp_parser_struct.num_pair[1];
2333 }
2334 cl_list_insert_tail(&tmp_parser_struct.num_pair_list, num_pair);
2335 }
2336 | num_list_with_dash TK_COMMA number_from_range_1 TK_DASH number_from_range_2 {
2337 uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
2338 if (tmp_parser_struct.num_pair[0] <= tmp_parser_struct.num_pair[1]) {
2339 num_pair[0] = tmp_parser_struct.num_pair[0];
2340 num_pair[1] = tmp_parser_struct.num_pair[1];
2341 }
2342 else {
2343 num_pair[1] = tmp_parser_struct.num_pair[0];
2344 num_pair[0] = tmp_parser_struct.num_pair[1];
2345 }
2346 cl_list_insert_tail(&tmp_parser_struct.num_pair_list, num_pair);
2347 }
2348 | num_list_with_dash TK_COMMA single_number_from_range {
2349 uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
2350 num_pair[0] = tmp_parser_struct.num_pair[0];
2351 num_pair[1] = tmp_parser_struct.num_pair[1];
2352 cl_list_insert_tail(&tmp_parser_struct.num_pair_list, num_pair);
2353 }
2354 ;
2355
2356 single_number_from_range: TK_NUMBER {
2357 __parser_str2uint64(&tmp_parser_struct.num_pair[0],$1);
2358 __parser_str2uint64(&tmp_parser_struct.num_pair[1],$1);
2359 free($1);
2360 }
2361 ;
2362
2363 number_from_range_1: TK_NUMBER {
2364 __parser_str2uint64(&tmp_parser_struct.num_pair[0],$1);
2365 free($1);
2366 }
2367 ;
2368
2369 number_from_range_2: TK_NUMBER {
2370 __parser_str2uint64(&tmp_parser_struct.num_pair[1],$1);
2371 free($1);
2372 }
2373 ;
2374
2375 %%
2376
2377 /***************************************************
2378 ***************************************************/
2379
2380 int osm_qos_parse_policy_file(IN osm_subn_t * p_subn)
2381 {
2382 int res = 0;
2383 static boolean_t first_time = TRUE;
2384 p_qos_parser_osm_log = &p_subn->p_osm->log;
2385
2386 OSM_LOG_ENTER(p_qos_parser_osm_log);
2387
2388 osm_qos_policy_destroy(p_subn->p_qos_policy);
2389 p_subn->p_qos_policy = NULL;
2390
2391 yyin = fopen (p_subn->opt.qos_policy_file, "r");
2392 if (!yyin)
2393 {
2394 if (strcmp(p_subn->opt.qos_policy_file,OSM_DEFAULT_QOS_POLICY_FILE)) {
2395 OSM_LOG(p_qos_parser_osm_log, OSM_LOG_ERROR, "ERR AC01: "
2396 "Failed opening QoS policy file %s - %s\n",
2397 p_subn->opt.qos_policy_file, strerror(errno));
2398 res = 1;
2399 }
2400 else
2401 OSM_LOG(p_qos_parser_osm_log, OSM_LOG_VERBOSE,
2402 "QoS policy file not found (%s)\n",
2403 p_subn->opt.qos_policy_file);
2404
2405 goto Exit;
2406 }
2407
2408 if (first_time)
2409 {
2410 first_time = FALSE;
2411 __setup_simple_qos_levels();
2412 __setup_ulp_match_rules();
2413 OSM_LOG(p_qos_parser_osm_log, OSM_LOG_INFO,
2414 "Loading QoS policy file (%s)\n",
2415 p_subn->opt.qos_policy_file);
2416 }
2417 else
2418 /*
2419 * ULP match rules list was emptied at the end of
2420 * previous parsing iteration.
2421 * What's left is to clear simple QoS levels.
2422 */
2423 __clear_simple_qos_levels();
2424
2425 column_num = 1;
2426 line_num = 1;
2427
2428 p_subn->p_qos_policy = osm_qos_policy_create(p_subn);
2429
2430 __parser_tmp_struct_init();
2431 p_qos_policy = p_subn->p_qos_policy;
2432
2433 res = yyparse();
2434
2435 __parser_tmp_struct_destroy();
2436
2437 if (res != 0)
2438 {
2439 OSM_LOG(p_qos_parser_osm_log, OSM_LOG_ERROR, "ERR AC03: "
2440 "Failed parsing QoS policy file (%s)\n",
2441 p_subn->opt.qos_policy_file);
2442 osm_qos_policy_destroy(p_subn->p_qos_policy);
2443 p_subn->p_qos_policy = NULL;
2444 res = 1;
2445 goto Exit;
2446 }
2447
2448 /* add generated ULP match rules to the usual match rules */
2449 __process_ulp_match_rules();
2450
2451 if (osm_qos_policy_validate(p_subn->p_qos_policy,p_qos_parser_osm_log))
2452 {
2453 OSM_LOG(p_qos_parser_osm_log, OSM_LOG_ERROR, "ERR AC04: "
2454 "Error(s) in QoS policy file (%s)\n",
2455 p_subn->opt.qos_policy_file);
2456 fprintf(stderr, "Error(s) in QoS policy file (%s)\n",
2457 p_subn->opt.qos_policy_file);
2458 osm_qos_policy_destroy(p_subn->p_qos_policy);
2459 p_subn->p_qos_policy = NULL;
2460 res = 1;
2461 goto Exit;
2462 }
2463
2464 Exit:
2465 if (yyin)
2466 {
2467 yyrestart(yyin);
2468 fclose(yyin);
2469 }
2470 OSM_LOG_EXIT(p_qos_parser_osm_log);
2471 return res;
2472 }
2473
2474 /***************************************************
2475 ***************************************************/
2476
yywrap()2477 int yywrap()
2478 {
2479 return(1);
2480 }
2481
2482 /***************************************************
2483 ***************************************************/
2484
yyerror(const char * format,...)2485 static void yyerror(const char *format, ...)
2486 {
2487 char s[256];
2488 va_list pvar;
2489
2490 OSM_LOG_ENTER(p_qos_parser_osm_log);
2491
2492 va_start(pvar, format);
2493 vsnprintf(s, sizeof(s), format, pvar);
2494 va_end(pvar);
2495
2496 OSM_LOG(p_qos_parser_osm_log, OSM_LOG_ERROR, "ERR AC05: "
2497 "Syntax error (line %d:%d): %s\n",
2498 line_num, column_num, s);
2499 fprintf(stderr, "Error in QoS Policy File (line %d:%d): %s.\n",
2500 line_num, column_num, s);
2501 OSM_LOG_EXIT(p_qos_parser_osm_log);
2502 }
2503
2504 /***************************************************
2505 ***************************************************/
2506
__parser_strip_white(char * str)2507 static char * __parser_strip_white(char * str)
2508 {
2509 char *p;
2510
2511 while (isspace(*str))
2512 str++;
2513 if (!*str)
2514 return str;
2515 p = str + strlen(str) - 1;
2516 while (isspace(*p))
2517 *p-- = '\0';
2518
2519 return str;
2520 }
2521
2522 /***************************************************
2523 ***************************************************/
2524
__parser_str2uint64(uint64_t * p_val,char * str)2525 static void __parser_str2uint64(uint64_t * p_val, char * str)
2526 {
2527 *p_val = strtoull(str, NULL, 0);
2528 }
2529
2530 /***************************************************
2531 ***************************************************/
2532
__parser_port_group_start()2533 static void __parser_port_group_start()
2534 {
2535 p_current_port_group = osm_qos_policy_port_group_create();
2536 }
2537
2538 /***************************************************
2539 ***************************************************/
2540
__parser_port_group_end()2541 static int __parser_port_group_end()
2542 {
2543 if(!p_current_port_group->name)
2544 {
2545 yyerror("port-group validation failed - no port group name specified");
2546 return -1;
2547 }
2548
2549 cl_list_insert_tail(&p_qos_policy->port_groups,
2550 p_current_port_group);
2551 p_current_port_group = NULL;
2552 return 0;
2553 }
2554
2555 /***************************************************
2556 ***************************************************/
2557
__parser_vlarb_scope_start()2558 static void __parser_vlarb_scope_start()
2559 {
2560 p_current_vlarb_scope = osm_qos_policy_vlarb_scope_create();
2561 }
2562
2563 /***************************************************
2564 ***************************************************/
2565
__parser_vlarb_scope_end()2566 static int __parser_vlarb_scope_end()
2567 {
2568 if ( !cl_list_count(&p_current_vlarb_scope->group_list) &&
2569 !cl_list_count(&p_current_vlarb_scope->across_list) )
2570 {
2571 yyerror("vlarb-scope validation failed - no port groups specified by 'group' or by 'across'");
2572 return -1;
2573 }
2574
2575 cl_list_insert_tail(&p_qos_policy->vlarb_tables,
2576 p_current_vlarb_scope);
2577 p_current_vlarb_scope = NULL;
2578 return 0;
2579 }
2580
2581 /***************************************************
2582 ***************************************************/
2583
__parser_sl2vl_scope_start()2584 static void __parser_sl2vl_scope_start()
2585 {
2586 p_current_sl2vl_scope = osm_qos_policy_sl2vl_scope_create();
2587 }
2588
2589 /***************************************************
2590 ***************************************************/
2591
__parser_sl2vl_scope_end()2592 static int __parser_sl2vl_scope_end()
2593 {
2594 if (!p_current_sl2vl_scope->sl2vl_table_set)
2595 {
2596 yyerror("sl2vl-scope validation failed - no sl2vl table specified");
2597 return -1;
2598 }
2599 if ( !cl_list_count(&p_current_sl2vl_scope->group_list) &&
2600 !cl_list_count(&p_current_sl2vl_scope->across_to_list) &&
2601 !cl_list_count(&p_current_sl2vl_scope->across_from_list) )
2602 {
2603 yyerror("sl2vl-scope validation failed - no port groups specified by 'group', 'across-to' or 'across-from'");
2604 return -1;
2605 }
2606
2607 cl_list_insert_tail(&p_qos_policy->sl2vl_tables,
2608 p_current_sl2vl_scope);
2609 p_current_sl2vl_scope = NULL;
2610 return 0;
2611 }
2612
2613 /***************************************************
2614 ***************************************************/
2615
__parser_qos_level_start()2616 static void __parser_qos_level_start()
2617 {
2618 p_current_qos_level = osm_qos_policy_qos_level_create();
2619 }
2620
2621 /***************************************************
2622 ***************************************************/
2623
__parser_qos_level_end()2624 static int __parser_qos_level_end()
2625 {
2626 if (!p_current_qos_level->sl_set)
2627 {
2628 yyerror("qos-level validation failed - no 'sl' specified");
2629 return -1;
2630 }
2631 if (!p_current_qos_level->name)
2632 {
2633 yyerror("qos-level validation failed - no 'name' specified");
2634 return -1;
2635 }
2636
2637 cl_list_insert_tail(&p_qos_policy->qos_levels,
2638 p_current_qos_level);
2639 p_current_qos_level = NULL;
2640 return 0;
2641 }
2642
2643 /***************************************************
2644 ***************************************************/
2645
__parser_match_rule_start()2646 static void __parser_match_rule_start()
2647 {
2648 p_current_qos_match_rule = osm_qos_policy_match_rule_create();
2649 }
2650
2651 /***************************************************
2652 ***************************************************/
2653
__parser_match_rule_end()2654 static int __parser_match_rule_end()
2655 {
2656 if (!p_current_qos_match_rule->qos_level_name)
2657 {
2658 yyerror("match-rule validation failed - no 'qos-level-name' specified");
2659 return -1;
2660 }
2661
2662 cl_list_insert_tail(&p_qos_policy->qos_match_rules,
2663 p_current_qos_match_rule);
2664 p_current_qos_match_rule = NULL;
2665 return 0;
2666 }
2667
2668 /***************************************************
2669 ***************************************************/
2670
__parser_ulp_match_rule_start()2671 static void __parser_ulp_match_rule_start()
2672 {
2673 p_current_qos_match_rule = osm_qos_policy_match_rule_create();
2674 }
2675
2676 /***************************************************
2677 ***************************************************/
2678
__parser_ulp_match_rule_end()2679 static int __parser_ulp_match_rule_end()
2680 {
2681 CL_ASSERT(p_current_qos_match_rule->p_qos_level);
2682 cl_list_insert_tail(&__ulp_match_rules,
2683 p_current_qos_match_rule);
2684 p_current_qos_match_rule = NULL;
2685 return 0;
2686 }
2687
2688 /***************************************************
2689 ***************************************************/
2690
__parser_tmp_struct_init()2691 static void __parser_tmp_struct_init()
2692 {
2693 tmp_parser_struct.str[0] = '\0';
2694 cl_list_construct(&tmp_parser_struct.str_list);
2695 cl_list_init(&tmp_parser_struct.str_list, 10);
2696 cl_list_construct(&tmp_parser_struct.num_list);
2697 cl_list_init(&tmp_parser_struct.num_list, 10);
2698 cl_list_construct(&tmp_parser_struct.num_pair_list);
2699 cl_list_init(&tmp_parser_struct.num_pair_list, 10);
2700 }
2701
2702 /***************************************************
2703 ***************************************************/
2704
2705 /*
2706 * Do NOT free objects from the temp struct.
2707 * Either they are inserted into the parse tree data
2708 * structure, or they are already freed when copying
2709 * their values to the parse tree data structure.
2710 */
__parser_tmp_struct_reset()2711 static void __parser_tmp_struct_reset()
2712 {
2713 tmp_parser_struct.str[0] = '\0';
2714 cl_list_remove_all(&tmp_parser_struct.str_list);
2715 cl_list_remove_all(&tmp_parser_struct.num_list);
2716 cl_list_remove_all(&tmp_parser_struct.num_pair_list);
2717 }
2718
2719 /***************************************************
2720 ***************************************************/
2721
__parser_tmp_struct_destroy()2722 static void __parser_tmp_struct_destroy()
2723 {
2724 __parser_tmp_struct_reset();
2725 cl_list_destroy(&tmp_parser_struct.str_list);
2726 cl_list_destroy(&tmp_parser_struct.num_list);
2727 cl_list_destroy(&tmp_parser_struct.num_pair_list);
2728 }
2729
2730 /***************************************************
2731 ***************************************************/
2732
2733 #define __SIMPLE_QOS_LEVEL_NAME "SimpleQoSLevel_SL"
2734 #define __SIMPLE_QOS_LEVEL_DEFAULT_NAME "SimpleQoSLevel_DEFAULT"
2735
__setup_simple_qos_levels()2736 static void __setup_simple_qos_levels()
2737 {
2738 uint8_t i;
2739 char tmp_buf[30];
2740 memset(osm_qos_policy_simple_qos_levels, 0,
2741 sizeof(osm_qos_policy_simple_qos_levels));
2742 for (i = 0; i < 16; i++)
2743 {
2744 osm_qos_policy_simple_qos_levels[i].sl = i;
2745 osm_qos_policy_simple_qos_levels[i].sl_set = TRUE;
2746 sprintf(tmp_buf, "%s%u", __SIMPLE_QOS_LEVEL_NAME, i);
2747 osm_qos_policy_simple_qos_levels[i].name = strdup(tmp_buf);
2748 }
2749
2750 memset(&__default_simple_qos_level, 0,
2751 sizeof(__default_simple_qos_level));
2752 __default_simple_qos_level.name =
2753 strdup(__SIMPLE_QOS_LEVEL_DEFAULT_NAME);
2754 }
2755
2756 /***************************************************
2757 ***************************************************/
2758
__clear_simple_qos_levels()2759 static void __clear_simple_qos_levels()
2760 {
2761 /*
2762 * Simple QoS levels are static.
2763 * What's left is to invalidate default simple QoS level.
2764 */
2765 __default_simple_qos_level.sl_set = FALSE;
2766 }
2767
2768 /***************************************************
2769 ***************************************************/
2770
__setup_ulp_match_rules()2771 static void __setup_ulp_match_rules()
2772 {
2773 cl_list_construct(&__ulp_match_rules);
2774 cl_list_init(&__ulp_match_rules, 10);
2775 }
2776
2777 /***************************************************
2778 ***************************************************/
2779
__process_ulp_match_rules()2780 static void __process_ulp_match_rules()
2781 {
2782 cl_list_iterator_t list_iterator;
2783 osm_qos_match_rule_t *p_qos_match_rule = NULL;
2784
2785 list_iterator = cl_list_head(&__ulp_match_rules);
2786 while (list_iterator != cl_list_end(&__ulp_match_rules))
2787 {
2788 p_qos_match_rule = (osm_qos_match_rule_t *) cl_list_obj(list_iterator);
2789 if (p_qos_match_rule)
2790 cl_list_insert_tail(&p_qos_policy->qos_match_rules,
2791 p_qos_match_rule);
2792 list_iterator = cl_list_next(list_iterator);
2793 }
2794 cl_list_remove_all(&__ulp_match_rules);
2795 }
2796
2797 /***************************************************
2798 ***************************************************/
2799
__cmp_num_range(const void * p1,const void * p2)2800 static int __cmp_num_range(const void * p1, const void * p2)
2801 {
2802 uint64_t * pair1 = *((uint64_t **)p1);
2803 uint64_t * pair2 = *((uint64_t **)p2);
2804
2805 if (pair1[0] < pair2[0])
2806 return -1;
2807 if (pair1[0] > pair2[0])
2808 return 1;
2809
2810 if (pair1[1] < pair2[1])
2811 return -1;
2812 if (pair1[1] > pair2[1])
2813 return 1;
2814
2815 return 0;
2816 }
2817
2818 /***************************************************
2819 ***************************************************/
2820
__sort_reduce_rangearr(uint64_t ** arr,unsigned arr_len,uint64_t *** p_res_arr,unsigned * p_res_arr_len)2821 static void __sort_reduce_rangearr(
2822 uint64_t ** arr,
2823 unsigned arr_len,
2824 uint64_t ** * p_res_arr,
2825 unsigned * p_res_arr_len )
2826 {
2827 unsigned i = 0;
2828 unsigned j = 0;
2829 unsigned last_valid_ind = 0;
2830 unsigned valid_cnt = 0;
2831 uint64_t ** res_arr;
2832 boolean_t * is_valid_arr;
2833
2834 *p_res_arr = NULL;
2835 *p_res_arr_len = 0;
2836
2837 qsort(arr, arr_len, sizeof(uint64_t*), __cmp_num_range);
2838
2839 is_valid_arr = (boolean_t *)malloc(arr_len * sizeof(boolean_t));
2840 is_valid_arr[last_valid_ind] = TRUE;
2841 valid_cnt++;
2842 for (i = 1; i < arr_len; i++)
2843 {
2844 if (arr[i][0] <= arr[last_valid_ind][1])
2845 {
2846 if (arr[i][1] > arr[last_valid_ind][1])
2847 arr[last_valid_ind][1] = arr[i][1];
2848 free(arr[i]);
2849 arr[i] = NULL;
2850 is_valid_arr[i] = FALSE;
2851 }
2852 else if ((arr[i][0] - 1) == arr[last_valid_ind][1])
2853 {
2854 arr[last_valid_ind][1] = arr[i][1];
2855 free(arr[i]);
2856 arr[i] = NULL;
2857 is_valid_arr[i] = FALSE;
2858 }
2859 else
2860 {
2861 is_valid_arr[i] = TRUE;
2862 last_valid_ind = i;
2863 valid_cnt++;
2864 }
2865 }
2866
2867 res_arr = (uint64_t **)malloc(valid_cnt * sizeof(uint64_t *));
2868 for (i = 0; i < arr_len; i++)
2869 {
2870 if (is_valid_arr[i])
2871 res_arr[j++] = arr[i];
2872 }
2873 free(is_valid_arr);
2874 free(arr);
2875
2876 *p_res_arr = res_arr;
2877 *p_res_arr_len = valid_cnt;
2878 }
2879
2880 /***************************************************
2881 ***************************************************/
2882
__pkey_rangelist2rangearr(cl_list_t * p_list,uint64_t *** p_arr,unsigned * p_arr_len)2883 static void __pkey_rangelist2rangearr(
2884 cl_list_t * p_list,
2885 uint64_t ** * p_arr,
2886 unsigned * p_arr_len)
2887 {
2888 uint64_t tmp_pkey;
2889 uint64_t * p_pkeys;
2890 cl_list_iterator_t list_iterator;
2891
2892 list_iterator= cl_list_head(p_list);
2893 while( list_iterator != cl_list_end(p_list) )
2894 {
2895 p_pkeys = (uint64_t *)cl_list_obj(list_iterator);
2896 p_pkeys[0] &= 0x7fff;
2897 p_pkeys[1] &= 0x7fff;
2898 if (p_pkeys[0] > p_pkeys[1])
2899 {
2900 tmp_pkey = p_pkeys[1];
2901 p_pkeys[1] = p_pkeys[0];
2902 p_pkeys[0] = tmp_pkey;
2903 }
2904 list_iterator = cl_list_next(list_iterator);
2905 }
2906
2907 __rangelist2rangearr(p_list, p_arr, p_arr_len);
2908 }
2909
2910 /***************************************************
2911 ***************************************************/
2912
__rangelist2rangearr(cl_list_t * p_list,uint64_t *** p_arr,unsigned * p_arr_len)2913 static void __rangelist2rangearr(
2914 cl_list_t * p_list,
2915 uint64_t ** * p_arr,
2916 unsigned * p_arr_len)
2917 {
2918 cl_list_iterator_t list_iterator;
2919 unsigned len = cl_list_count(p_list);
2920 unsigned i = 0;
2921 uint64_t ** tmp_arr;
2922 uint64_t ** res_arr = NULL;
2923 unsigned res_arr_len = 0;
2924
2925 tmp_arr = (uint64_t **)malloc(len * sizeof(uint64_t *));
2926
2927 list_iterator = cl_list_head(p_list);
2928 while( list_iterator != cl_list_end(p_list) )
2929 {
2930 tmp_arr[i++] = (uint64_t *)cl_list_obj(list_iterator);
2931 list_iterator = cl_list_next(list_iterator);
2932 }
2933 cl_list_remove_all(p_list);
2934
2935 __sort_reduce_rangearr( tmp_arr,
2936 len,
2937 &res_arr,
2938 &res_arr_len );
2939 *p_arr = res_arr;
2940 *p_arr_len = res_arr_len;
2941 }
2942
2943 /***************************************************
2944 ***************************************************/
2945
__merge_rangearr(uint64_t ** range_arr_1,unsigned range_len_1,uint64_t ** range_arr_2,unsigned range_len_2,uint64_t *** p_arr,unsigned * p_arr_len)2946 static void __merge_rangearr(
2947 uint64_t ** range_arr_1,
2948 unsigned range_len_1,
2949 uint64_t ** range_arr_2,
2950 unsigned range_len_2,
2951 uint64_t ** * p_arr,
2952 unsigned * p_arr_len )
2953 {
2954 unsigned i = 0;
2955 unsigned j = 0;
2956 unsigned len = range_len_1 + range_len_2;
2957 uint64_t ** tmp_arr;
2958 uint64_t ** res_arr = NULL;
2959 unsigned res_arr_len = 0;
2960
2961 *p_arr = NULL;
2962 *p_arr_len = 0;
2963
2964 tmp_arr = (uint64_t **)malloc(len * sizeof(uint64_t *));
2965
2966 for (i = 0; i < range_len_1; i++)
2967 tmp_arr[j++] = range_arr_1[i];
2968 for (i = 0; i < range_len_2; i++)
2969 tmp_arr[j++] = range_arr_2[i];
2970 free(range_arr_1);
2971 free(range_arr_2);
2972
2973 __sort_reduce_rangearr( tmp_arr,
2974 len,
2975 &res_arr,
2976 &res_arr_len );
2977 *p_arr = res_arr;
2978 *p_arr_len = res_arr_len;
2979 }
2980
2981 /***************************************************
2982 ***************************************************/
2983
__parser_add_port_to_port_map(cl_qmap_t * p_map,osm_physp_t * p_physp)2984 static void __parser_add_port_to_port_map(
2985 cl_qmap_t * p_map,
2986 osm_physp_t * p_physp)
2987 {
2988 if (cl_qmap_get(p_map, cl_ntoh64(osm_physp_get_port_guid(p_physp))) ==
2989 cl_qmap_end(p_map))
2990 {
2991 osm_qos_port_t * p_port = osm_qos_policy_port_create(p_physp);
2992 if (p_port)
2993 cl_qmap_insert(p_map,
2994 cl_ntoh64(osm_physp_get_port_guid(p_physp)),
2995 &p_port->map_item);
2996 }
2997 }
2998
2999 /***************************************************
3000 ***************************************************/
3001
__parser_add_guid_range_to_port_map(cl_qmap_t * p_map,uint64_t ** range_arr,unsigned range_len)3002 static void __parser_add_guid_range_to_port_map(
3003 cl_qmap_t * p_map,
3004 uint64_t ** range_arr,
3005 unsigned range_len)
3006 {
3007 unsigned i;
3008 uint64_t guid_ho;
3009 osm_port_t * p_osm_port;
3010
3011 if (!range_arr || !range_len)
3012 return;
3013
3014 for (i = 0; i < range_len; i++) {
3015 for (guid_ho = range_arr[i][0]; guid_ho <= range_arr[i][1]; guid_ho++) {
3016 p_osm_port =
3017 osm_get_port_by_guid(p_qos_policy->p_subn, cl_hton64(guid_ho));
3018 if (p_osm_port)
3019 __parser_add_port_to_port_map(p_map, p_osm_port->p_physp);
3020 }
3021 free(range_arr[i]);
3022 }
3023 free(range_arr);
3024 }
3025
3026 /***************************************************
3027 ***************************************************/
3028
__parser_add_pkey_range_to_port_map(cl_qmap_t * p_map,uint64_t ** range_arr,unsigned range_len)3029 static void __parser_add_pkey_range_to_port_map(
3030 cl_qmap_t * p_map,
3031 uint64_t ** range_arr,
3032 unsigned range_len)
3033 {
3034 unsigned i;
3035 uint64_t pkey_64;
3036 ib_net16_t pkey;
3037 osm_prtn_t * p_prtn;
3038
3039 if (!range_arr || !range_len)
3040 return;
3041
3042 for (i = 0; i < range_len; i++) {
3043 for (pkey_64 = range_arr[i][0]; pkey_64 <= range_arr[i][1]; pkey_64++) {
3044 pkey = cl_hton16((uint16_t)(pkey_64 & 0x7fff));
3045 p_prtn = (osm_prtn_t *)
3046 cl_qmap_get(&p_qos_policy->p_subn->prtn_pkey_tbl, pkey);
3047 if (p_prtn != (osm_prtn_t *)cl_qmap_end(
3048 &p_qos_policy->p_subn->prtn_pkey_tbl)) {
3049 __parser_add_map_to_port_map(p_map, &p_prtn->part_guid_tbl);
3050 __parser_add_map_to_port_map(p_map, &p_prtn->full_guid_tbl);
3051 }
3052 }
3053 free(range_arr[i]);
3054 }
3055 free(range_arr);
3056 }
3057
3058 /***************************************************
3059 ***************************************************/
3060
__parser_add_partition_list_to_port_map(cl_qmap_t * p_map,cl_list_t * p_list)3061 static void __parser_add_partition_list_to_port_map(
3062 cl_qmap_t * p_map,
3063 cl_list_t * p_list)
3064 {
3065 cl_list_iterator_t list_iterator;
3066 char * tmp_str;
3067 osm_prtn_t * p_prtn;
3068
3069 /* extract all the ports from the partition
3070 to the port map of this port group */
3071 list_iterator = cl_list_head(p_list);
3072 while(list_iterator != cl_list_end(p_list)) {
3073 tmp_str = (char*)cl_list_obj(list_iterator);
3074 if (tmp_str) {
3075 p_prtn = osm_prtn_find_by_name(p_qos_policy->p_subn, tmp_str);
3076 if (p_prtn) {
3077 __parser_add_map_to_port_map(p_map, &p_prtn->part_guid_tbl);
3078 __parser_add_map_to_port_map(p_map, &p_prtn->full_guid_tbl);
3079 }
3080 free(tmp_str);
3081 }
3082 list_iterator = cl_list_next(list_iterator);
3083 }
3084 cl_list_remove_all(p_list);
3085 }
3086
3087 /***************************************************
3088 ***************************************************/
3089
__parser_add_map_to_port_map(cl_qmap_t * p_dmap,cl_map_t * p_smap)3090 static void __parser_add_map_to_port_map(
3091 cl_qmap_t * p_dmap,
3092 cl_map_t * p_smap)
3093 {
3094 cl_map_iterator_t map_iterator;
3095 osm_physp_t * p_physp;
3096
3097 if (!p_dmap || !p_smap)
3098 return;
3099
3100 map_iterator = cl_map_head(p_smap);
3101 while (map_iterator != cl_map_end(p_smap)) {
3102 p_physp = (osm_physp_t*)cl_map_obj(map_iterator);
3103 __parser_add_port_to_port_map(p_dmap, p_physp);
3104 map_iterator = cl_map_next(map_iterator);
3105 }
3106 }
3107
3108 /***************************************************
3109 ***************************************************/
3110
__validate_pkeys(uint64_t ** range_arr,unsigned range_len,boolean_t is_ipoib)3111 static int __validate_pkeys( uint64_t ** range_arr,
3112 unsigned range_len,
3113 boolean_t is_ipoib)
3114 {
3115 unsigned i;
3116 uint64_t pkey_64;
3117 ib_net16_t pkey;
3118 osm_prtn_t * p_prtn;
3119
3120 if (!range_arr || !range_len)
3121 return 0;
3122
3123 for (i = 0; i < range_len; i++) {
3124 for (pkey_64 = range_arr[i][0]; pkey_64 <= range_arr[i][1]; pkey_64++) {
3125 pkey = cl_hton16((uint16_t)(pkey_64 & 0x7fff));
3126 p_prtn = (osm_prtn_t *)
3127 cl_qmap_get(&p_qos_policy->p_subn->prtn_pkey_tbl, pkey);
3128
3129 if (p_prtn == (osm_prtn_t *)cl_qmap_end(
3130 &p_qos_policy->p_subn->prtn_pkey_tbl))
3131 p_prtn = NULL;
3132
3133 if (is_ipoib) {
3134 /*
3135 * Be very strict for IPoIB partition:
3136 * - the partition for the pkey have to exist
3137 * - it has to have at least 2 full members
3138 */
3139 if (!p_prtn) {
3140 yyerror("IPoIB partition, pkey 0x%04X - "
3141 "partition doesn't exist",
3142 cl_ntoh16(pkey));
3143 return 1;
3144 }
3145 else if (cl_map_count(&p_prtn->full_guid_tbl) < 2) {
3146 yyerror("IPoIB partition, pkey 0x%04X - "
3147 "partition has less than two full members",
3148 cl_ntoh16(pkey));
3149 return 1;
3150 }
3151 }
3152 else if (!p_prtn) {
3153 /*
3154 * For non-IPoIB pkey we just want to check that
3155 * the relevant partition exists.
3156 * And even if it doesn't, don't exit - just print
3157 * error message and continue.
3158 */
3159 OSM_LOG(p_qos_parser_osm_log, OSM_LOG_ERROR, "ERR AC02: "
3160 "pkey 0x%04X - partition doesn't exist",
3161 cl_ntoh16(pkey));
3162 }
3163 }
3164 }
3165 return 0;
3166 }
3167
3168 /***************************************************
3169 ***************************************************/
3170