3 * Copyright (c) 2004-2006 Voltaire, Inc. All rights reserved.
4 * Copyright (c) 2002-2005 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.
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:
14 * Redistribution and use in source and binary forms, with or
15 * without modification, are permitted provided that the following
18 * - Redistributions of source code must retain the above
19 * copyright notice, this list of conditions and the following
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.
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
40 * Grammar of OSM QoS parser.
46 * Yevgeny Kliteynik, Mellanox
56 #include <opensm/osm_opensm.h>
57 #include <opensm/osm_qos_policy.h>
59 #define OSM_QOS_POLICY_MAX_LINE_LEN 1024*10
60 #define OSM_QOS_POLICY_SL2VL_TABLE_LEN IB_MAX_NUM_VLS
61 #define OSM_QOS_POLICY_MAX_VL_NUM IB_MAX_NUM_VLS
63 typedef struct tmp_parser_struct_t_ {
64 char str[OSM_QOS_POLICY_MAX_LINE_LEN];
68 cl_list_t num_pair_list;
69 } tmp_parser_struct_t;
71 static void __parser_tmp_struct_init();
72 static void __parser_tmp_struct_reset();
73 static void __parser_tmp_struct_destroy();
75 static char * __parser_strip_white(char * str);
77 static void __parser_str2uint64(uint64_t * p_val, char * str);
79 static void __parser_port_group_start();
80 static int __parser_port_group_end();
82 static void __parser_sl2vl_scope_start();
83 static int __parser_sl2vl_scope_end();
85 static void __parser_vlarb_scope_start();
86 static int __parser_vlarb_scope_end();
88 static void __parser_qos_level_start();
89 static int __parser_qos_level_end();
91 static void __parser_match_rule_start();
92 static int __parser_match_rule_end();
94 static void __parser_ulp_match_rule_start();
95 static int __parser_ulp_match_rule_end();
97 static void __pkey_rangelist2rangearr(
100 unsigned * p_arr_len);
102 static void __rangelist2rangearr(
105 unsigned * p_arr_len);
107 static void __merge_rangearr(
108 uint64_t ** range_arr_1,
109 unsigned range_len_1,
110 uint64_t ** range_arr_2,
111 unsigned range_len_2,
113 unsigned * p_arr_len );
115 static void __parser_add_port_to_port_map(
117 osm_physp_t * p_physp);
119 static void __parser_add_guid_range_to_port_map(
121 uint64_t ** range_arr,
124 static void __parser_add_pkey_range_to_port_map(
126 uint64_t ** range_arr,
129 static void __parser_add_partition_list_to_port_map(
133 static void __parser_add_map_to_port_map(
137 static int __validate_pkeys(
138 uint64_t ** range_arr,
142 static void __setup_simple_qos_levels();
143 static void __clear_simple_qos_levels();
144 static void __setup_ulp_match_rules();
145 static void __process_ulp_match_rules();
146 static void yyerror(const char *format, ...);
148 extern char * yytext;
149 extern int yylex (void);
154 #define RESET_BUFFER __parser_tmp_struct_reset()
156 tmp_parser_struct_t tmp_parser_struct;
161 osm_qos_policy_t * p_qos_policy = NULL;
162 osm_qos_port_group_t * p_current_port_group = NULL;
163 osm_qos_sl2vl_scope_t * p_current_sl2vl_scope = NULL;
164 osm_qos_vlarb_scope_t * p_current_vlarb_scope = NULL;
165 osm_qos_level_t * p_current_qos_level = NULL;
166 osm_qos_match_rule_t * p_current_qos_match_rule = NULL;
167 osm_log_t * p_qos_parser_osm_log;
169 /* 16 Simple QoS Levels - one for each SL */
170 static osm_qos_level_t osm_qos_policy_simple_qos_levels[16];
172 /* Default Simple QoS Level */
173 osm_qos_level_t __default_simple_qos_level;
176 * List of match rules that will be generated by the
177 * qos-ulp section. These rules are concatenated to
178 * the end of the usual matching rules list at the
181 static cl_list_t __ulp_match_rules;
183 /***************************************************/
194 %token TK_QOS_ULPS_START
195 %token TK_QOS_ULPS_END
197 %token TK_PORT_GROUPS_START
198 %token TK_PORT_GROUPS_END
199 %token TK_PORT_GROUP_START
200 %token TK_PORT_GROUP_END
202 %token TK_QOS_SETUP_START
203 %token TK_QOS_SETUP_END
204 %token TK_VLARB_TABLES_START
205 %token TK_VLARB_TABLES_END
206 %token TK_VLARB_SCOPE_START
207 %token TK_VLARB_SCOPE_END
209 %token TK_SL2VL_TABLES_START
210 %token TK_SL2VL_TABLES_END
211 %token TK_SL2VL_SCOPE_START
212 %token TK_SL2VL_SCOPE_END
214 %token TK_QOS_LEVELS_START
215 %token TK_QOS_LEVELS_END
216 %token TK_QOS_LEVEL_START
217 %token TK_QOS_LEVEL_END
219 %token TK_QOS_MATCH_RULES_START
220 %token TK_QOS_MATCH_RULES_END
221 %token TK_QOS_MATCH_RULE_START
222 %token TK_QOS_MATCH_RULE_END
234 %token TK_VLARB_HIGH_LIMIT
238 %token TK_ACROSS_FROM
239 %token TK_SL2VL_TABLE
243 %token TK_PACKET_LIFE
247 %token TK_DESTINATION
249 %token TK_QOS_LEVEL_NAME
252 %token TK_NODE_TYPE_ROUTER
253 %token TK_NODE_TYPE_CA
254 %token TK_NODE_TYPE_SWITCH
255 %token TK_NODE_TYPE_SELF
256 %token TK_NODE_TYPE_ALL
258 %token TK_ULP_DEFAULT
259 %token TK_ULP_ANY_SERVICE_ID
260 %token TK_ULP_ANY_PKEY
261 %token TK_ULP_ANY_TARGET_PORT_GUID
262 %token TK_ULP_SDP_DEFAULT
263 %token TK_ULP_SDP_PORT
264 %token TK_ULP_RDS_DEFAULT
265 %token TK_ULP_RDS_PORT
266 %token TK_ULP_ISER_DEFAULT
267 %token TK_ULP_ISER_PORT
268 %token TK_ULP_SRP_GUID
269 %token TK_ULP_IPOIB_DEFAULT
270 %token TK_ULP_IPOIB_PKEY
276 head: qos_policy_entries
279 qos_policy_entries: /* empty */
280 | qos_policy_entries qos_policy_entry
283 qos_policy_entry: qos_ulps_section
284 | port_groups_section
287 | qos_match_rules_section
292 * -------------------
294 * default : 0 #default SL
295 * sdp, port-num 30000 : 1 #SL for SDP when destination port is 30000
296 * sdp, port-num 10000-20000 : 2
297 * sdp : 0 #default SL for SDP
298 * srp, target-port-guid 0x1234 : 2
299 * rds, port-num 25000 : 2 #SL for RDS when destination port is 25000
300 * rds, : 0 #default SL for RDS
301 * iser, port-num 900 : 5 #SL for iSER where target port is 900
302 * iser : 4 #default SL for iSER
303 * ipoib, pkey 0x0001 : 5 #SL for IPoIB on partition with pkey 0x0001
304 * ipoib : 6 #default IPoIB partition - pkey=0x7FFF
305 * any, service-id 0x6234 : 2
306 * any, pkey 0x0ABC : 3
307 * any, target-port-guid 0x0ABC-0xFFFFF : 6
311 qos_ulps_section: TK_QOS_ULPS_START qos_ulps TK_QOS_ULPS_END
319 * Parsing port groups:
320 * -------------------
324 * use: our SRP storage targets
325 * port-guid: 0x1000000000000001,0x1000000000000002
327 * port-name: vs1 HCA-1/P1
328 * port-name: node_description/P2
330 * pkey: 0x00FF-0x0FFF
334 * node-type: ROUTER,CA,SWITCH,SELF,ALL
344 port_groups_section: TK_PORT_GROUPS_START port_groups TK_PORT_GROUPS_END
347 port_groups: port_group
348 | port_groups port_group
351 port_group: port_group_start port_group_entries port_group_end
354 port_group_start: TK_PORT_GROUP_START {
355 __parser_port_group_start();
359 port_group_end: TK_PORT_GROUP_END {
360 if ( __parser_port_group_end() )
365 port_group_entries: /* empty */
366 | port_group_entries port_group_entry
369 port_group_entry: port_group_name
371 | port_group_port_guid
372 | port_group_port_name
374 | port_group_partition
375 | port_group_node_type
402 qos_setup_section: TK_QOS_SETUP_START qos_setup_items TK_QOS_SETUP_END
405 qos_setup_items: /* empty */
406 | qos_setup_items vlarb_tables
407 | qos_setup_items sl2vl_tables
410 /* Parsing vlarb-tables */
412 vlarb_tables: TK_VLARB_TABLES_START vlarb_scope_items TK_VLARB_TABLES_END
415 vlarb_scope_items: /* empty */
416 | vlarb_scope_items vlarb_scope
419 vlarb_scope: vlarb_scope_start vlarb_scope_entries vlarb_scope_end
422 vlarb_scope_start: TK_VLARB_SCOPE_START {
423 __parser_vlarb_scope_start();
427 vlarb_scope_end: TK_VLARB_SCOPE_END {
428 if ( __parser_vlarb_scope_end() )
433 vlarb_scope_entries:/* empty */
434 | vlarb_scope_entries vlarb_scope_entry
443 * vlarb-high: 0:255,1:127,2:63,3:31,4:15,5:7,6:3,7:1
444 * vlarb-low: 8:255,9:127,10:63,11:31,12:15,13:7,14:3
449 vlarb_scope_entry: vlarb_scope_group
451 | vlarb_scope_vlarb_high
452 | vlarb_scope_vlarb_low
453 | vlarb_scope_vlarb_high_limit
456 /* Parsing sl2vl-tables */
458 sl2vl_tables: TK_SL2VL_TABLES_START sl2vl_scope_items TK_SL2VL_TABLES_END
461 sl2vl_scope_items: /* empty */
462 | sl2vl_scope_items sl2vl_scope
465 sl2vl_scope: sl2vl_scope_start sl2vl_scope_entries sl2vl_scope_end
468 sl2vl_scope_start: TK_SL2VL_SCOPE_START {
469 __parser_sl2vl_scope_start();
473 sl2vl_scope_end: TK_SL2VL_SCOPE_END {
474 if ( __parser_sl2vl_scope_end() )
479 sl2vl_scope_entries:/* empty */
480 | sl2vl_scope_entries sl2vl_scope_entry
491 * across-to: Storage2
493 * across-from: Storage1
495 * sl2vl-table: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,7
499 sl2vl_scope_entry: sl2vl_scope_group
501 | sl2vl_scope_across_from
502 | sl2vl_scope_across_to
505 | sl2vl_scope_sl2vl_table
509 * Parsing qos-levels:
514 * use: for the lowest priority communication
519 * path-bits: 2,4,8-32
520 * pkey: 0x00FF-0x0FFF
529 qos_levels_section: TK_QOS_LEVELS_START qos_levels TK_QOS_LEVELS_END
532 qos_levels: /* empty */
533 | qos_levels qos_level
536 qos_level: qos_level_start qos_level_entries qos_level_end
539 qos_level_start: TK_QOS_LEVEL_START {
540 __parser_qos_level_start();
544 qos_level_end: TK_QOS_LEVEL_END {
545 if ( __parser_qos_level_end() )
550 qos_level_entries: /* empty */
551 | qos_level_entries qos_level_entry
554 qos_level_entry: qos_level_name
557 | qos_level_mtu_limit
558 | qos_level_rate_limit
559 | qos_level_packet_life
560 | qos_level_path_bits
565 * Parsing qos-match-rules:
566 * -----------------------
569 * use: low latency by class 7-9 or 11 and bla bla
571 * qos-level-name: default
573 * destination: Storage
574 * service-id: 22,4719-5000
575 * pkey: 0x00FF-0x0FFF
580 * end-qos-match-rules
583 qos_match_rules_section: TK_QOS_MATCH_RULES_START qos_match_rules TK_QOS_MATCH_RULES_END
586 qos_match_rules: /* empty */
587 | qos_match_rules qos_match_rule
590 qos_match_rule: qos_match_rule_start qos_match_rule_entries qos_match_rule_end
593 qos_match_rule_start: TK_QOS_MATCH_RULE_START {
594 __parser_match_rule_start();
598 qos_match_rule_end: TK_QOS_MATCH_RULE_END {
599 if ( __parser_match_rule_end() )
604 qos_match_rule_entries: /* empty */
605 | qos_match_rule_entries qos_match_rule_entry
608 qos_match_rule_entry: qos_match_rule_use
609 | qos_match_rule_qos_class
610 | qos_match_rule_qos_level_name
611 | qos_match_rule_source
612 | qos_match_rule_destination
613 | qos_match_rule_service_id
614 | qos_match_rule_pkey
631 * any with service-id
633 * any with target-port-guid
636 qos_ulp: TK_ULP_DEFAULT single_number {
637 /* parsing default ulp rule: "default: num" */
638 cl_list_iterator_t list_iterator;
639 uint64_t * p_tmp_num;
641 list_iterator = cl_list_head(&tmp_parser_struct.num_list);
642 p_tmp_num = (uint64_t*)cl_list_obj(list_iterator);
645 yyerror("illegal SL value");
648 __default_simple_qos_level.sl = (uint8_t)(*p_tmp_num);
649 __default_simple_qos_level.sl_set = TRUE;
651 cl_list_remove_all(&tmp_parser_struct.num_list);
654 | qos_ulp_type_any_service list_of_ranges TK_DOTDOT {
655 /* "any, service-id ... : sl" - one instance of list of ranges */
656 uint64_t ** range_arr;
659 if (!cl_list_count(&tmp_parser_struct.num_pair_list))
661 yyerror("ULP rule doesn't have service ids");
665 /* get all the service id ranges */
666 __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
670 p_current_qos_match_rule->service_id_range_arr = range_arr;
671 p_current_qos_match_rule->service_id_range_len = range_len;
675 | qos_ulp_type_any_pkey list_of_ranges TK_DOTDOT {
676 /* "any, pkey ... : sl" - one instance of list of ranges */
677 uint64_t ** range_arr;
680 if (!cl_list_count(&tmp_parser_struct.num_pair_list))
682 yyerror("ULP rule doesn't have pkeys");
686 /* get all the pkey ranges */
687 __pkey_rangelist2rangearr( &tmp_parser_struct.num_pair_list,
691 p_current_qos_match_rule->pkey_range_arr = range_arr;
692 p_current_qos_match_rule->pkey_range_len = range_len;
696 | qos_ulp_type_any_target_port_guid list_of_ranges TK_DOTDOT {
697 /* any, target-port-guid ... : sl */
698 uint64_t ** range_arr;
701 if (!cl_list_count(&tmp_parser_struct.num_pair_list))
703 yyerror("ULP rule doesn't have port guids");
707 /* create a new port group with these ports */
708 __parser_port_group_start();
710 p_current_port_group->name = strdup("_ULP_Targets_");
711 p_current_port_group->use = strdup("Generated from ULP rules");
713 __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
717 __parser_add_guid_range_to_port_map(
718 &p_current_port_group->port_map,
722 /* add this port group to the destination
723 groups of the current match rule */
724 cl_list_insert_tail(&p_current_qos_match_rule->destination_group_list,
725 p_current_port_group);
727 __parser_port_group_end();
731 | qos_ulp_type_sdp_default {
732 /* "sdp : sl" - default SL for SDP */
733 uint64_t ** range_arr =
734 (uint64_t **)malloc(sizeof(uint64_t *));
735 range_arr[0] = (uint64_t *)malloc(2*sizeof(uint64_t));
736 range_arr[0][0] = OSM_QOS_POLICY_ULP_SDP_SERVICE_ID;
737 range_arr[0][1] = OSM_QOS_POLICY_ULP_SDP_SERVICE_ID + 0xFFFF;
739 p_current_qos_match_rule->service_id_range_arr = range_arr;
740 p_current_qos_match_rule->service_id_range_len = 1;
744 | qos_ulp_type_sdp_port list_of_ranges TK_DOTDOT {
745 /* sdp with port numbers */
746 uint64_t ** range_arr;
750 if (!cl_list_count(&tmp_parser_struct.num_pair_list))
752 yyerror("SDP ULP rule doesn't have port numbers");
756 /* get all the port ranges */
757 __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
760 /* now translate these port numbers into service ids */
761 for (i = 0; i < range_len; i++)
763 if (range_arr[i][0] > 0xFFFF || range_arr[i][1] > 0xFFFF)
765 yyerror("SDP port number out of range");
768 range_arr[i][0] += OSM_QOS_POLICY_ULP_SDP_SERVICE_ID;
769 range_arr[i][1] += OSM_QOS_POLICY_ULP_SDP_SERVICE_ID;
772 p_current_qos_match_rule->service_id_range_arr = range_arr;
773 p_current_qos_match_rule->service_id_range_len = range_len;
777 | qos_ulp_type_rds_default {
778 /* "rds : sl" - default SL for RDS */
779 uint64_t ** range_arr =
780 (uint64_t **)malloc(sizeof(uint64_t *));
781 range_arr[0] = (uint64_t *)malloc(2*sizeof(uint64_t));
782 range_arr[0][0] = range_arr[0][1] =
783 OSM_QOS_POLICY_ULP_RDS_SERVICE_ID + OSM_QOS_POLICY_ULP_RDS_PORT;
785 p_current_qos_match_rule->service_id_range_arr = range_arr;
786 p_current_qos_match_rule->service_id_range_len = 1;
790 | qos_ulp_type_rds_port list_of_ranges TK_DOTDOT {
791 /* rds with port numbers */
792 uint64_t ** range_arr;
796 if (!cl_list_count(&tmp_parser_struct.num_pair_list))
798 yyerror("RDS ULP rule doesn't have port numbers");
802 /* get all the port ranges */
803 __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
806 /* now translate these port numbers into service ids */
807 for (i = 0; i < range_len; i++)
809 if (range_arr[i][0] > 0xFFFF || range_arr[i][1] > 0xFFFF)
811 yyerror("SDP port number out of range");
814 range_arr[i][0] += OSM_QOS_POLICY_ULP_RDS_SERVICE_ID;
815 range_arr[i][1] += OSM_QOS_POLICY_ULP_RDS_SERVICE_ID;
818 p_current_qos_match_rule->service_id_range_arr = range_arr;
819 p_current_qos_match_rule->service_id_range_len = range_len;
823 | qos_ulp_type_iser_default {
824 /* "iSER : sl" - default SL for iSER */
825 uint64_t ** range_arr =
826 (uint64_t **)malloc(sizeof(uint64_t *));
827 range_arr[0] = (uint64_t *)malloc(2*sizeof(uint64_t));
828 range_arr[0][0] = range_arr[0][1] =
829 OSM_QOS_POLICY_ULP_ISER_SERVICE_ID + OSM_QOS_POLICY_ULP_ISER_PORT;
831 p_current_qos_match_rule->service_id_range_arr = range_arr;
832 p_current_qos_match_rule->service_id_range_len = 1;
836 | qos_ulp_type_iser_port list_of_ranges TK_DOTDOT {
837 /* iser with port numbers */
838 uint64_t ** range_arr;
842 if (!cl_list_count(&tmp_parser_struct.num_pair_list))
844 yyerror("iSER ULP rule doesn't have port numbers");
848 /* get all the port ranges */
849 __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
852 /* now translate these port numbers into service ids */
853 for (i = 0; i < range_len; i++)
855 if (range_arr[i][0] > 0xFFFF || range_arr[i][1] > 0xFFFF)
857 yyerror("SDP port number out of range");
860 range_arr[i][0] += OSM_QOS_POLICY_ULP_ISER_SERVICE_ID;
861 range_arr[i][1] += OSM_QOS_POLICY_ULP_ISER_SERVICE_ID;
864 p_current_qos_match_rule->service_id_range_arr = range_arr;
865 p_current_qos_match_rule->service_id_range_len = range_len;
869 | qos_ulp_type_srp_guid list_of_ranges TK_DOTDOT {
870 /* srp with target guids - this rule is similar
871 to writing 'any' ulp with target port guids */
872 uint64_t ** range_arr;
875 if (!cl_list_count(&tmp_parser_struct.num_pair_list))
877 yyerror("SRP ULP rule doesn't have port guids");
881 /* create a new port group with these ports */
882 __parser_port_group_start();
884 p_current_port_group->name = strdup("_SRP_Targets_");
885 p_current_port_group->use = strdup("Generated from ULP rules");
887 __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
891 __parser_add_guid_range_to_port_map(
892 &p_current_port_group->port_map,
896 /* add this port group to the destination
897 groups of the current match rule */
898 cl_list_insert_tail(&p_current_qos_match_rule->destination_group_list,
899 p_current_port_group);
901 __parser_port_group_end();
905 | qos_ulp_type_ipoib_default {
906 /* ipoib w/o any pkeys (default pkey) */
907 uint64_t ** range_arr =
908 (uint64_t **)malloc(sizeof(uint64_t *));
909 range_arr[0] = (uint64_t *)malloc(2*sizeof(uint64_t));
910 range_arr[0][0] = range_arr[0][1] = 0x7fff;
913 * Although we know that the default partition exists,
914 * we still need to validate it by checking that it has
915 * at least two full members. Otherwise IPoIB won't work.
917 if (__validate_pkeys(range_arr, 1, TRUE))
920 p_current_qos_match_rule->pkey_range_arr = range_arr;
921 p_current_qos_match_rule->pkey_range_len = 1;
925 | qos_ulp_type_ipoib_pkey list_of_ranges TK_DOTDOT {
926 /* ipoib with pkeys */
927 uint64_t ** range_arr;
930 if (!cl_list_count(&tmp_parser_struct.num_pair_list))
932 yyerror("IPoIB ULP rule doesn't have pkeys");
936 /* get all the pkey ranges */
937 __pkey_rangelist2rangearr( &tmp_parser_struct.num_pair_list,
943 * For IPoIB pkeys the validation is strict.
944 * If some problem would be found, parsing will
945 * be aborted with a proper error messages.
947 if (__validate_pkeys(range_arr, range_len, TRUE))
950 p_current_qos_match_rule->pkey_range_arr = range_arr;
951 p_current_qos_match_rule->pkey_range_len = range_len;
956 qos_ulp_type_any_service: TK_ULP_ANY_SERVICE_ID
957 { __parser_ulp_match_rule_start(); };
959 qos_ulp_type_any_pkey: TK_ULP_ANY_PKEY
960 { __parser_ulp_match_rule_start(); };
962 qos_ulp_type_any_target_port_guid: TK_ULP_ANY_TARGET_PORT_GUID
963 { __parser_ulp_match_rule_start(); };
965 qos_ulp_type_sdp_default: TK_ULP_SDP_DEFAULT
966 { __parser_ulp_match_rule_start(); };
968 qos_ulp_type_sdp_port: TK_ULP_SDP_PORT
969 { __parser_ulp_match_rule_start(); };
971 qos_ulp_type_rds_default: TK_ULP_RDS_DEFAULT
972 { __parser_ulp_match_rule_start(); };
974 qos_ulp_type_rds_port: TK_ULP_RDS_PORT
975 { __parser_ulp_match_rule_start(); };
977 qos_ulp_type_iser_default: TK_ULP_ISER_DEFAULT
978 { __parser_ulp_match_rule_start(); };
980 qos_ulp_type_iser_port: TK_ULP_ISER_PORT
981 { __parser_ulp_match_rule_start(); };
983 qos_ulp_type_srp_guid: TK_ULP_SRP_GUID
984 { __parser_ulp_match_rule_start(); };
986 qos_ulp_type_ipoib_default: TK_ULP_IPOIB_DEFAULT
987 { __parser_ulp_match_rule_start(); };
989 qos_ulp_type_ipoib_pkey: TK_ULP_IPOIB_PKEY
990 { __parser_ulp_match_rule_start(); };
993 qos_ulp_sl: single_number {
994 /* get the SL for ULP rules */
995 cl_list_iterator_t list_iterator;
996 uint64_t * p_tmp_num;
999 list_iterator = cl_list_head(&tmp_parser_struct.num_list);
1000 p_tmp_num = (uint64_t*)cl_list_obj(list_iterator);
1001 if (*p_tmp_num > 15)
1003 yyerror("illegal SL value");
1007 sl = (uint8_t)(*p_tmp_num);
1009 cl_list_remove_all(&tmp_parser_struct.num_list);
1011 p_current_qos_match_rule->p_qos_level =
1012 &osm_qos_policy_simple_qos_levels[sl];
1013 p_current_qos_match_rule->qos_level_name =
1014 strdup(osm_qos_policy_simple_qos_levels[sl].name);
1016 if (__parser_ulp_match_rule_end())
1022 * port_group_entry values:
1025 * port_group_port_guid
1026 * port_group_port_name
1028 * port_group_partition
1029 * port_group_node_type
1032 port_group_name: port_group_name_start single_string {
1033 /* 'name' of 'port-group' - one instance */
1034 cl_list_iterator_t list_iterator;
1037 if (p_current_port_group->name)
1039 yyerror("port-group has multiple 'name' tags");
1040 cl_list_remove_all(&tmp_parser_struct.str_list);
1044 list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1045 if ( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1047 tmp_str = (char*)cl_list_obj(list_iterator);
1049 p_current_port_group->name = tmp_str;
1051 cl_list_remove_all(&tmp_parser_struct.str_list);
1055 port_group_name_start: TK_NAME {
1060 port_group_use: port_group_use_start single_string {
1061 /* 'use' of 'port-group' - one instance */
1062 cl_list_iterator_t list_iterator;
1065 if (p_current_port_group->use)
1067 yyerror("port-group has multiple 'use' tags");
1068 cl_list_remove_all(&tmp_parser_struct.str_list);
1072 list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1073 if ( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1075 tmp_str = (char*)cl_list_obj(list_iterator);
1077 p_current_port_group->use = tmp_str;
1079 cl_list_remove_all(&tmp_parser_struct.str_list);
1083 port_group_use_start: TK_USE {
1088 port_group_port_name: port_group_port_name_start string_list {
1089 /* 'port-name' in 'port-group' - any num of instances */
1090 cl_list_iterator_t list_iterator;
1091 osm_node_t * p_node;
1092 osm_physp_t * p_physp;
1097 /* parsing port name strings */
1098 for (list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1099 list_iterator != cl_list_end(&tmp_parser_struct.str_list);
1100 list_iterator = cl_list_next(list_iterator))
1102 tmp_str = (char*)cl_list_obj(list_iterator);
1105 /* last slash in port name string is a separator
1106 between node name and port number */
1107 port_str = strrchr(tmp_str, '/');
1108 if (!port_str || (strlen(port_str) < 3) ||
1109 (port_str[1] != 'p' && port_str[1] != 'P')) {
1110 yyerror("'%s' - illegal port name",
1113 cl_list_remove_all(&tmp_parser_struct.str_list);
1117 if (!(port_num = strtoul(&port_str[2],NULL,0))) {
1119 "'%s' - illegal port number in port name",
1122 cl_list_remove_all(&tmp_parser_struct.str_list);
1126 /* separate node name from port number */
1129 if (st_lookup(p_qos_policy->p_node_hash,
1133 /* we found the node, now get the right port */
1134 p_physp = osm_node_get_physp_ptr(p_node, port_num);
1137 "'%s' - port number out of range in port name",
1140 cl_list_remove_all(&tmp_parser_struct.str_list);
1143 /* we found the port, now add it to guid table */
1144 __parser_add_port_to_port_map(&p_current_port_group->port_map,
1150 cl_list_remove_all(&tmp_parser_struct.str_list);
1154 port_group_port_name_start: TK_PORT_NAME {
1159 port_group_port_guid: port_group_port_guid_start list_of_ranges {
1160 /* 'port-guid' in 'port-group' - any num of instances */
1161 /* list of guid ranges */
1162 if (cl_list_count(&tmp_parser_struct.num_pair_list))
1164 uint64_t ** range_arr;
1167 __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
1171 __parser_add_guid_range_to_port_map(
1172 &p_current_port_group->port_map,
1179 port_group_port_guid_start: TK_PORT_GUID {
1184 port_group_pkey: port_group_pkey_start list_of_ranges {
1185 /* 'pkey' in 'port-group' - any num of instances */
1186 /* list of pkey ranges */
1187 if (cl_list_count(&tmp_parser_struct.num_pair_list))
1189 uint64_t ** range_arr;
1192 __pkey_rangelist2rangearr( &tmp_parser_struct.num_pair_list,
1196 __parser_add_pkey_range_to_port_map(
1197 &p_current_port_group->port_map,
1204 port_group_pkey_start: TK_PKEY {
1209 port_group_partition: port_group_partition_start string_list {
1210 /* 'partition' in 'port-group' - any num of instances */
1211 __parser_add_partition_list_to_port_map(
1212 &p_current_port_group->port_map,
1213 &tmp_parser_struct.str_list);
1217 port_group_partition_start: TK_PARTITION {
1222 port_group_node_type: port_group_node_type_start port_group_node_type_list {
1223 /* 'node-type' in 'port-group' - any num of instances */
1227 port_group_node_type_start: TK_NODE_TYPE {
1232 port_group_node_type_list: node_type_item
1233 | port_group_node_type_list TK_COMMA node_type_item
1236 node_type_item: node_type_ca
1243 node_type_ca: TK_NODE_TYPE_CA {
1244 p_current_port_group->node_types |=
1245 OSM_QOS_POLICY_NODE_TYPE_CA;
1249 node_type_switch: TK_NODE_TYPE_SWITCH {
1250 p_current_port_group->node_types |=
1251 OSM_QOS_POLICY_NODE_TYPE_SWITCH;
1255 node_type_router: TK_NODE_TYPE_ROUTER {
1256 p_current_port_group->node_types |=
1257 OSM_QOS_POLICY_NODE_TYPE_ROUTER;
1261 node_type_all: TK_NODE_TYPE_ALL {
1262 p_current_port_group->node_types |=
1263 (OSM_QOS_POLICY_NODE_TYPE_CA |
1264 OSM_QOS_POLICY_NODE_TYPE_SWITCH |
1265 OSM_QOS_POLICY_NODE_TYPE_ROUTER);
1269 node_type_self: TK_NODE_TYPE_SELF {
1270 osm_port_t * p_osm_port =
1271 osm_get_port_by_guid(p_qos_policy->p_subn,
1272 p_qos_policy->p_subn->sm_port_guid);
1274 __parser_add_port_to_port_map(
1275 &p_current_port_group->port_map,
1276 p_osm_port->p_physp);
1281 * vlarb_scope_entry values:
1283 * vlarb_scope_across
1284 * vlarb_scope_vlarb_high
1285 * vlarb_scope_vlarb_low
1286 * vlarb_scope_vlarb_high_limit
1291 vlarb_scope_group: vlarb_scope_group_start string_list {
1292 /* 'group' in 'vlarb-scope' - any num of instances */
1293 cl_list_iterator_t list_iterator;
1296 list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1297 while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1299 tmp_str = (char*)cl_list_obj(list_iterator);
1301 cl_list_insert_tail(&p_current_vlarb_scope->group_list,tmp_str);
1302 list_iterator = cl_list_next(list_iterator);
1304 cl_list_remove_all(&tmp_parser_struct.str_list);
1308 vlarb_scope_group_start: TK_GROUP {
1313 vlarb_scope_across: vlarb_scope_across_start string_list {
1314 /* 'across' in 'vlarb-scope' - any num of instances */
1315 cl_list_iterator_t list_iterator;
1318 list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1319 while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1321 tmp_str = (char*)cl_list_obj(list_iterator);
1323 cl_list_insert_tail(&p_current_vlarb_scope->across_list,tmp_str);
1324 list_iterator = cl_list_next(list_iterator);
1326 cl_list_remove_all(&tmp_parser_struct.str_list);
1330 vlarb_scope_across_start: TK_ACROSS {
1335 vlarb_scope_vlarb_high_limit: vlarb_scope_vlarb_high_limit_start single_number {
1336 /* 'vl-high-limit' in 'vlarb-scope' - one instance of one number */
1337 cl_list_iterator_t list_iterator;
1338 uint64_t * p_tmp_num;
1340 list_iterator = cl_list_head(&tmp_parser_struct.num_list);
1341 p_tmp_num = (uint64_t*)cl_list_obj(list_iterator);
1344 p_current_vlarb_scope->vl_high_limit = (uint32_t)(*p_tmp_num);
1345 p_current_vlarb_scope->vl_high_limit_set = TRUE;
1349 cl_list_remove_all(&tmp_parser_struct.num_list);
1353 vlarb_scope_vlarb_high_limit_start: TK_VLARB_HIGH_LIMIT {
1358 vlarb_scope_vlarb_high: vlarb_scope_vlarb_high_start num_list_with_dotdot {
1359 /* 'vlarb-high' in 'vlarb-scope' - list of pairs of numbers with ':' and ',' */
1360 cl_list_iterator_t list_iterator;
1361 uint64_t * num_pair;
1363 list_iterator = cl_list_head(&tmp_parser_struct.num_pair_list);
1364 while( list_iterator != cl_list_end(&tmp_parser_struct.num_pair_list) )
1366 num_pair = (uint64_t*)cl_list_obj(list_iterator);
1368 cl_list_insert_tail(&p_current_vlarb_scope->vlarb_high_list,num_pair);
1369 list_iterator = cl_list_next(list_iterator);
1371 cl_list_remove_all(&tmp_parser_struct.num_pair_list);
1375 vlarb_scope_vlarb_high_start: TK_VLARB_HIGH {
1380 vlarb_scope_vlarb_low: vlarb_scope_vlarb_low_start num_list_with_dotdot {
1381 /* 'vlarb-low' in 'vlarb-scope' - list of pairs of numbers with ':' and ',' */
1382 cl_list_iterator_t list_iterator;
1383 uint64_t * num_pair;
1385 list_iterator = cl_list_head(&tmp_parser_struct.num_pair_list);
1386 while( list_iterator != cl_list_end(&tmp_parser_struct.num_pair_list) )
1388 num_pair = (uint64_t*)cl_list_obj(list_iterator);
1390 cl_list_insert_tail(&p_current_vlarb_scope->vlarb_low_list,num_pair);
1391 list_iterator = cl_list_next(list_iterator);
1393 cl_list_remove_all(&tmp_parser_struct.num_pair_list);
1397 vlarb_scope_vlarb_low_start: TK_VLARB_LOW {
1403 * sl2vl_scope_entry values:
1405 * sl2vl_scope_across
1406 * sl2vl_scope_across_from
1407 * sl2vl_scope_across_to
1410 * sl2vl_scope_sl2vl_table
1413 sl2vl_scope_group: sl2vl_scope_group_start string_list {
1414 /* 'group' in 'sl2vl-scope' - any num of instances */
1415 cl_list_iterator_t list_iterator;
1418 list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1419 while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1421 tmp_str = (char*)cl_list_obj(list_iterator);
1423 cl_list_insert_tail(&p_current_sl2vl_scope->group_list,tmp_str);
1424 list_iterator = cl_list_next(list_iterator);
1426 cl_list_remove_all(&tmp_parser_struct.str_list);
1430 sl2vl_scope_group_start: TK_GROUP {
1435 sl2vl_scope_across: sl2vl_scope_across_start string_list {
1436 /* 'across' in 'sl2vl-scope' - any num of instances */
1437 cl_list_iterator_t list_iterator;
1440 list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1441 while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1443 tmp_str = (char*)cl_list_obj(list_iterator);
1445 cl_list_insert_tail(&p_current_sl2vl_scope->across_from_list,tmp_str);
1446 cl_list_insert_tail(&p_current_sl2vl_scope->across_to_list,strdup(tmp_str));
1448 list_iterator = cl_list_next(list_iterator);
1450 cl_list_remove_all(&tmp_parser_struct.str_list);
1454 sl2vl_scope_across_start: TK_ACROSS {
1459 sl2vl_scope_across_from: sl2vl_scope_across_from_start string_list {
1460 /* 'across-from' in 'sl2vl-scope' - any num of instances */
1461 cl_list_iterator_t list_iterator;
1464 list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1465 while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1467 tmp_str = (char*)cl_list_obj(list_iterator);
1469 cl_list_insert_tail(&p_current_sl2vl_scope->across_from_list,tmp_str);
1470 list_iterator = cl_list_next(list_iterator);
1472 cl_list_remove_all(&tmp_parser_struct.str_list);
1476 sl2vl_scope_across_from_start: TK_ACROSS_FROM {
1481 sl2vl_scope_across_to: sl2vl_scope_across_to_start string_list {
1482 /* 'across-to' in 'sl2vl-scope' - any num of instances */
1483 cl_list_iterator_t list_iterator;
1486 list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1487 while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1489 tmp_str = (char*)cl_list_obj(list_iterator);
1491 cl_list_insert_tail(&p_current_sl2vl_scope->across_to_list,tmp_str);
1493 list_iterator = cl_list_next(list_iterator);
1495 cl_list_remove_all(&tmp_parser_struct.str_list);
1499 sl2vl_scope_across_to_start: TK_ACROSS_TO {
1504 sl2vl_scope_from: sl2vl_scope_from_start sl2vl_scope_from_list_or_asterisk {
1505 /* 'from' in 'sl2vl-scope' - any num of instances */
1509 sl2vl_scope_from_start: TK_FROM {
1514 sl2vl_scope_to: sl2vl_scope_to_start sl2vl_scope_to_list_or_asterisk {
1515 /* 'to' in 'sl2vl-scope' - any num of instances */
1519 sl2vl_scope_to_start: TK_TO {
1524 sl2vl_scope_from_list_or_asterisk: sl2vl_scope_from_asterisk
1525 | sl2vl_scope_from_list_of_ranges
1528 sl2vl_scope_from_asterisk: TK_ASTERISK {
1530 for (i = 0; i < OSM_QOS_POLICY_MAX_PORTS_ON_SWITCH; i++)
1531 p_current_sl2vl_scope->from[i] = TRUE;
1535 sl2vl_scope_to_list_or_asterisk: sl2vl_scope_to_asterisk
1536 | sl2vl_scope_to_list_of_ranges
1539 sl2vl_scope_to_asterisk: TK_ASTERISK {
1541 for (i = 0; i < OSM_QOS_POLICY_MAX_PORTS_ON_SWITCH; i++)
1542 p_current_sl2vl_scope->to[i] = TRUE;
1546 sl2vl_scope_from_list_of_ranges: list_of_ranges {
1548 cl_list_iterator_t list_iterator;
1549 uint64_t * num_pair;
1552 list_iterator = cl_list_head(&tmp_parser_struct.num_pair_list);
1553 while( list_iterator != cl_list_end(&tmp_parser_struct.num_pair_list) )
1555 num_pair = (uint64_t*)cl_list_obj(list_iterator);
1558 if ( num_pair[0] < 0 ||
1559 num_pair[1] >= OSM_QOS_POLICY_MAX_PORTS_ON_SWITCH )
1561 yyerror("port number out of range 'from' list");
1563 cl_list_remove_all(&tmp_parser_struct.num_pair_list);
1566 num1 = (uint8_t)num_pair[0];
1567 num2 = (uint8_t)num_pair[1];
1569 for (i = num1; i <= num2; i++)
1570 p_current_sl2vl_scope->from[i] = TRUE;
1572 list_iterator = cl_list_next(list_iterator);
1574 cl_list_remove_all(&tmp_parser_struct.num_pair_list);
1578 sl2vl_scope_to_list_of_ranges: list_of_ranges {
1580 cl_list_iterator_t list_iterator;
1581 uint64_t * num_pair;
1584 list_iterator = cl_list_head(&tmp_parser_struct.num_pair_list);
1585 while( list_iterator != cl_list_end(&tmp_parser_struct.num_pair_list) )
1587 num_pair = (uint64_t*)cl_list_obj(list_iterator);
1590 if ( num_pair[0] < 0 ||
1591 num_pair[1] >= OSM_QOS_POLICY_MAX_PORTS_ON_SWITCH )
1593 yyerror("port number out of range 'to' list");
1595 cl_list_remove_all(&tmp_parser_struct.num_pair_list);
1598 num1 = (uint8_t)num_pair[0];
1599 num2 = (uint8_t)num_pair[1];
1601 for (i = num1; i <= num2; i++)
1602 p_current_sl2vl_scope->to[i] = TRUE;
1604 list_iterator = cl_list_next(list_iterator);
1606 cl_list_remove_all(&tmp_parser_struct.num_pair_list);
1611 sl2vl_scope_sl2vl_table: sl2vl_scope_sl2vl_table_start num_list {
1612 /* 'sl2vl-table' - one instance of exactly
1613 OSM_QOS_POLICY_SL2VL_TABLE_LEN numbers */
1614 cl_list_iterator_t list_iterator;
1619 if (p_current_sl2vl_scope->sl2vl_table_set)
1621 yyerror("sl2vl-scope has more than one sl2vl-table");
1622 cl_list_remove_all(&tmp_parser_struct.num_list);
1626 if (cl_list_count(&tmp_parser_struct.num_list) != OSM_QOS_POLICY_SL2VL_TABLE_LEN)
1628 yyerror("wrong number of values in 'sl2vl-table' (should be 16)");
1629 cl_list_remove_all(&tmp_parser_struct.num_list);
1633 list_iterator = cl_list_head(&tmp_parser_struct.num_list);
1634 while( list_iterator != cl_list_end(&tmp_parser_struct.num_list) )
1636 p_num = (uint64_t*)cl_list_obj(list_iterator);
1639 if (num >= OSM_QOS_POLICY_MAX_VL_NUM)
1641 yyerror("wrong VL value in 'sl2vl-table' (should be 0 to 15)");
1642 cl_list_remove_all(&tmp_parser_struct.num_list);
1646 p_current_sl2vl_scope->sl2vl_table[i++] = (uint8_t)num;
1647 list_iterator = cl_list_next(list_iterator);
1649 p_current_sl2vl_scope->sl2vl_table_set = TRUE;
1650 cl_list_remove_all(&tmp_parser_struct.num_list);
1654 sl2vl_scope_sl2vl_table_start: TK_SL2VL_TABLE {
1660 * qos_level_entry values:
1664 * qos_level_mtu_limit
1665 * qos_level_rate_limit
1666 * qos_level_packet_life
1667 * qos_level_path_bits
1671 qos_level_name: qos_level_name_start single_string {
1672 /* 'name' of 'qos-level' - one instance */
1673 cl_list_iterator_t list_iterator;
1676 if (p_current_qos_level->name)
1678 yyerror("qos-level has multiple 'name' tags");
1679 cl_list_remove_all(&tmp_parser_struct.str_list);
1683 list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1684 if ( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1686 tmp_str = (char*)cl_list_obj(list_iterator);
1688 p_current_qos_level->name = tmp_str;
1690 cl_list_remove_all(&tmp_parser_struct.str_list);
1694 qos_level_name_start: TK_NAME {
1699 qos_level_use: qos_level_use_start single_string {
1700 /* 'use' of 'qos-level' - one instance */
1701 cl_list_iterator_t list_iterator;
1704 if (p_current_qos_level->use)
1706 yyerror("qos-level has multiple 'use' tags");
1707 cl_list_remove_all(&tmp_parser_struct.str_list);
1711 list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1712 if ( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1714 tmp_str = (char*)cl_list_obj(list_iterator);
1716 p_current_qos_level->use = tmp_str;
1718 cl_list_remove_all(&tmp_parser_struct.str_list);
1722 qos_level_use_start: TK_USE {
1727 qos_level_sl: qos_level_sl_start single_number {
1728 /* 'sl' in 'qos-level' - one instance */
1729 cl_list_iterator_t list_iterator;
1732 if (p_current_qos_level->sl_set)
1734 yyerror("'qos-level' has multiple 'sl' tags");
1735 cl_list_remove_all(&tmp_parser_struct.num_list);
1738 list_iterator = cl_list_head(&tmp_parser_struct.num_list);
1739 p_num = (uint64_t*)cl_list_obj(list_iterator);
1740 p_current_qos_level->sl = (uint8_t)(*p_num);
1742 p_current_qos_level->sl_set = TRUE;
1743 cl_list_remove_all(&tmp_parser_struct.num_list);
1747 qos_level_sl_start: TK_SL {
1752 qos_level_mtu_limit: qos_level_mtu_limit_start single_number {
1753 /* 'mtu-limit' in 'qos-level' - one instance */
1754 cl_list_iterator_t list_iterator;
1757 if (p_current_qos_level->mtu_limit_set)
1759 yyerror("'qos-level' has multiple 'mtu-limit' tags");
1760 cl_list_remove_all(&tmp_parser_struct.num_list);
1763 list_iterator = cl_list_head(&tmp_parser_struct.num_list);
1764 p_num = (uint64_t*)cl_list_obj(list_iterator);
1765 p_current_qos_level->mtu_limit = (uint8_t)(*p_num);
1767 p_current_qos_level->mtu_limit_set = TRUE;
1768 cl_list_remove_all(&tmp_parser_struct.num_list);
1772 qos_level_mtu_limit_start: TK_MTU_LIMIT {
1773 /* 'mtu-limit' in 'qos-level' - one instance */
1778 qos_level_rate_limit: qos_level_rate_limit_start single_number {
1779 /* 'rate-limit' in 'qos-level' - one instance */
1780 cl_list_iterator_t list_iterator;
1783 if (p_current_qos_level->rate_limit_set)
1785 yyerror("'qos-level' has multiple 'rate-limit' tags");
1786 cl_list_remove_all(&tmp_parser_struct.num_list);
1789 list_iterator = cl_list_head(&tmp_parser_struct.num_list);
1790 p_num = (uint64_t*)cl_list_obj(list_iterator);
1791 p_current_qos_level->rate_limit = (uint8_t)(*p_num);
1793 p_current_qos_level->rate_limit_set = TRUE;
1794 cl_list_remove_all(&tmp_parser_struct.num_list);
1798 qos_level_rate_limit_start: TK_RATE_LIMIT {
1799 /* 'rate-limit' in 'qos-level' - one instance */
1804 qos_level_packet_life: qos_level_packet_life_start single_number {
1805 /* 'packet-life' in 'qos-level' - one instance */
1806 cl_list_iterator_t list_iterator;
1809 if (p_current_qos_level->pkt_life_set)
1811 yyerror("'qos-level' has multiple 'packet-life' tags");
1812 cl_list_remove_all(&tmp_parser_struct.num_list);
1815 list_iterator = cl_list_head(&tmp_parser_struct.num_list);
1816 p_num = (uint64_t*)cl_list_obj(list_iterator);
1817 p_current_qos_level->pkt_life = (uint8_t)(*p_num);
1819 p_current_qos_level->pkt_life_set= TRUE;
1820 cl_list_remove_all(&tmp_parser_struct.num_list);
1824 qos_level_packet_life_start: TK_PACKET_LIFE {
1825 /* 'packet-life' in 'qos-level' - one instance */
1830 qos_level_path_bits: qos_level_path_bits_start list_of_ranges {
1831 /* 'path-bits' in 'qos-level' - any num of instances */
1832 /* list of path bit ranges */
1834 if (cl_list_count(&tmp_parser_struct.num_pair_list))
1836 uint64_t ** range_arr;
1839 __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
1843 if ( !p_current_qos_level->path_bits_range_len )
1845 p_current_qos_level->path_bits_range_arr = range_arr;
1846 p_current_qos_level->path_bits_range_len = range_len;
1850 uint64_t ** new_range_arr;
1851 unsigned new_range_len;
1852 __merge_rangearr( p_current_qos_level->path_bits_range_arr,
1853 p_current_qos_level->path_bits_range_len,
1858 p_current_qos_level->path_bits_range_arr = new_range_arr;
1859 p_current_qos_level->path_bits_range_len = new_range_len;
1865 qos_level_path_bits_start: TK_PATH_BITS {
1870 qos_level_pkey: qos_level_pkey_start list_of_ranges {
1871 /* 'pkey' in 'qos-level' - num of instances of list of ranges */
1872 if (cl_list_count(&tmp_parser_struct.num_pair_list))
1874 uint64_t ** range_arr;
1877 __pkey_rangelist2rangearr( &tmp_parser_struct.num_pair_list,
1881 if ( !p_current_qos_level->pkey_range_len )
1883 p_current_qos_level->pkey_range_arr = range_arr;
1884 p_current_qos_level->pkey_range_len = range_len;
1888 uint64_t ** new_range_arr;
1889 unsigned new_range_len;
1890 __merge_rangearr( p_current_qos_level->pkey_range_arr,
1891 p_current_qos_level->pkey_range_len,
1896 p_current_qos_level->pkey_range_arr = new_range_arr;
1897 p_current_qos_level->pkey_range_len = new_range_len;
1903 qos_level_pkey_start: TK_PKEY {
1909 * qos_match_rule_entry values:
1910 * qos_match_rule_use
1911 * qos_match_rule_qos_class
1912 * qos_match_rule_qos_level_name
1913 * qos_match_rule_source
1914 * qos_match_rule_destination
1915 * qos_match_rule_service_id
1916 * qos_match_rule_pkey
1920 qos_match_rule_use: qos_match_rule_use_start single_string {
1921 /* 'use' of 'qos-match-rule' - one instance */
1922 cl_list_iterator_t list_iterator;
1925 if (p_current_qos_match_rule->use)
1927 yyerror("'qos-match-rule' has multiple 'use' tags");
1928 cl_list_remove_all(&tmp_parser_struct.str_list);
1932 list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1933 if ( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1935 tmp_str = (char*)cl_list_obj(list_iterator);
1937 p_current_qos_match_rule->use = tmp_str;
1939 cl_list_remove_all(&tmp_parser_struct.str_list);
1943 qos_match_rule_use_start: TK_USE {
1948 qos_match_rule_qos_class: qos_match_rule_qos_class_start list_of_ranges {
1949 /* 'qos-class' in 'qos-match-rule' - num of instances of list of ranges */
1950 /* list of class ranges (QoS Class is 12-bit value) */
1951 if (cl_list_count(&tmp_parser_struct.num_pair_list))
1953 uint64_t ** range_arr;
1956 __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
1960 if ( !p_current_qos_match_rule->qos_class_range_len )
1962 p_current_qos_match_rule->qos_class_range_arr = range_arr;
1963 p_current_qos_match_rule->qos_class_range_len = range_len;
1967 uint64_t ** new_range_arr;
1968 unsigned new_range_len;
1969 __merge_rangearr( p_current_qos_match_rule->qos_class_range_arr,
1970 p_current_qos_match_rule->qos_class_range_len,
1975 p_current_qos_match_rule->qos_class_range_arr = new_range_arr;
1976 p_current_qos_match_rule->qos_class_range_len = new_range_len;
1982 qos_match_rule_qos_class_start: TK_QOS_CLASS {
1987 qos_match_rule_source: qos_match_rule_source_start string_list {
1988 /* 'source' in 'qos-match-rule' - text */
1989 cl_list_iterator_t list_iterator;
1992 list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1993 while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1995 tmp_str = (char*)cl_list_obj(list_iterator);
1997 cl_list_insert_tail(&p_current_qos_match_rule->source_list,tmp_str);
1998 list_iterator = cl_list_next(list_iterator);
2000 cl_list_remove_all(&tmp_parser_struct.str_list);
2004 qos_match_rule_source_start: TK_SOURCE {
2009 qos_match_rule_destination: qos_match_rule_destination_start string_list {
2010 /* 'destination' in 'qos-match-rule' - text */
2011 cl_list_iterator_t list_iterator;
2014 list_iterator = cl_list_head(&tmp_parser_struct.str_list);
2015 while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
2017 tmp_str = (char*)cl_list_obj(list_iterator);
2019 cl_list_insert_tail(&p_current_qos_match_rule->destination_list,tmp_str);
2020 list_iterator = cl_list_next(list_iterator);
2022 cl_list_remove_all(&tmp_parser_struct.str_list);
2026 qos_match_rule_destination_start: TK_DESTINATION {
2031 qos_match_rule_qos_level_name: qos_match_rule_qos_level_name_start single_string {
2032 /* 'qos-level-name' in 'qos-match-rule' - single string */
2033 cl_list_iterator_t list_iterator;
2036 if (p_current_qos_match_rule->qos_level_name)
2038 yyerror("qos-match-rule has multiple 'qos-level-name' tags");
2039 cl_list_remove_all(&tmp_parser_struct.num_list);
2043 list_iterator = cl_list_head(&tmp_parser_struct.str_list);
2044 if ( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
2046 tmp_str = (char*)cl_list_obj(list_iterator);
2048 p_current_qos_match_rule->qos_level_name = tmp_str;
2050 cl_list_remove_all(&tmp_parser_struct.str_list);
2054 qos_match_rule_qos_level_name_start: TK_QOS_LEVEL_NAME {
2059 qos_match_rule_service_id: qos_match_rule_service_id_start list_of_ranges {
2060 /* 'service-id' in 'qos-match-rule' - num of instances of list of ranges */
2061 if (cl_list_count(&tmp_parser_struct.num_pair_list))
2063 uint64_t ** range_arr;
2066 __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
2070 if ( !p_current_qos_match_rule->service_id_range_len )
2072 p_current_qos_match_rule->service_id_range_arr = range_arr;
2073 p_current_qos_match_rule->service_id_range_len = range_len;
2077 uint64_t ** new_range_arr;
2078 unsigned new_range_len;
2079 __merge_rangearr( p_current_qos_match_rule->service_id_range_arr,
2080 p_current_qos_match_rule->service_id_range_len,
2085 p_current_qos_match_rule->service_id_range_arr = new_range_arr;
2086 p_current_qos_match_rule->service_id_range_len = new_range_len;
2092 qos_match_rule_service_id_start: TK_SERVICE_ID {
2097 qos_match_rule_pkey: qos_match_rule_pkey_start list_of_ranges {
2098 /* 'pkey' in 'qos-match-rule' - num of instances of list of ranges */
2099 if (cl_list_count(&tmp_parser_struct.num_pair_list))
2101 uint64_t ** range_arr;
2104 __pkey_rangelist2rangearr( &tmp_parser_struct.num_pair_list,
2108 if ( !p_current_qos_match_rule->pkey_range_len )
2110 p_current_qos_match_rule->pkey_range_arr = range_arr;
2111 p_current_qos_match_rule->pkey_range_len = range_len;
2115 uint64_t ** new_range_arr;
2116 unsigned new_range_len;
2117 __merge_rangearr( p_current_qos_match_rule->pkey_range_arr,
2118 p_current_qos_match_rule->pkey_range_len,
2123 p_current_qos_match_rule->pkey_range_arr = new_range_arr;
2124 p_current_qos_match_rule->pkey_range_len = new_range_len;
2130 qos_match_rule_pkey_start: TK_PKEY {
2141 single_string: single_string_elems {
2142 cl_list_insert_tail(&tmp_parser_struct.str_list,
2143 strdup(__parser_strip_white(tmp_parser_struct.str)));
2144 tmp_parser_struct.str[0] = '\0';
2148 single_string_elems: single_string_element
2149 | single_string_elems single_string_element
2152 single_string_element: TK_TEXT {
2153 strcat(tmp_parser_struct.str,$1);
2159 string_list: single_string
2160 | string_list TK_COMMA single_string
2165 single_number: number
2169 | num_list TK_COMMA number
2173 uint64_t * p_num = (uint64_t*)malloc(sizeof(uint64_t));
2174 __parser_str2uint64(p_num,$1);
2176 cl_list_insert_tail(&tmp_parser_struct.num_list, p_num);
2180 num_list_with_dotdot: number_from_pair_1 TK_DOTDOT number_from_pair_2 {
2181 uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
2182 num_pair[0] = tmp_parser_struct.num_pair[0];
2183 num_pair[1] = tmp_parser_struct.num_pair[1];
2184 cl_list_insert_tail(&tmp_parser_struct.num_pair_list, num_pair);
2186 | num_list_with_dotdot TK_COMMA number_from_pair_1 TK_DOTDOT number_from_pair_2 {
2187 uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
2188 num_pair[0] = tmp_parser_struct.num_pair[0];
2189 num_pair[1] = tmp_parser_struct.num_pair[1];
2190 cl_list_insert_tail(&tmp_parser_struct.num_pair_list, num_pair);
2194 number_from_pair_1: TK_NUMBER {
2195 __parser_str2uint64(&tmp_parser_struct.num_pair[0],$1);
2200 number_from_pair_2: TK_NUMBER {
2201 __parser_str2uint64(&tmp_parser_struct.num_pair[1],$1);
2206 list_of_ranges: num_list_with_dash
2209 num_list_with_dash: single_number_from_range {
2210 uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
2211 num_pair[0] = tmp_parser_struct.num_pair[0];
2212 num_pair[1] = tmp_parser_struct.num_pair[1];
2213 cl_list_insert_tail(&tmp_parser_struct.num_pair_list, num_pair);
2215 | number_from_range_1 TK_DASH number_from_range_2 {
2216 uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
2217 if (tmp_parser_struct.num_pair[0] <= tmp_parser_struct.num_pair[1]) {
2218 num_pair[0] = tmp_parser_struct.num_pair[0];
2219 num_pair[1] = tmp_parser_struct.num_pair[1];
2222 num_pair[1] = tmp_parser_struct.num_pair[0];
2223 num_pair[0] = tmp_parser_struct.num_pair[1];
2225 cl_list_insert_tail(&tmp_parser_struct.num_pair_list, num_pair);
2227 | num_list_with_dash TK_COMMA number_from_range_1 TK_DASH number_from_range_2 {
2228 uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
2229 if (tmp_parser_struct.num_pair[0] <= tmp_parser_struct.num_pair[1]) {
2230 num_pair[0] = tmp_parser_struct.num_pair[0];
2231 num_pair[1] = tmp_parser_struct.num_pair[1];
2234 num_pair[1] = tmp_parser_struct.num_pair[0];
2235 num_pair[0] = tmp_parser_struct.num_pair[1];
2237 cl_list_insert_tail(&tmp_parser_struct.num_pair_list, num_pair);
2239 | num_list_with_dash TK_COMMA single_number_from_range {
2240 uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
2241 num_pair[0] = tmp_parser_struct.num_pair[0];
2242 num_pair[1] = tmp_parser_struct.num_pair[1];
2243 cl_list_insert_tail(&tmp_parser_struct.num_pair_list, num_pair);
2247 single_number_from_range: TK_NUMBER {
2248 __parser_str2uint64(&tmp_parser_struct.num_pair[0],$1);
2249 __parser_str2uint64(&tmp_parser_struct.num_pair[1],$1);
2254 number_from_range_1: TK_NUMBER {
2255 __parser_str2uint64(&tmp_parser_struct.num_pair[0],$1);
2260 number_from_range_2: TK_NUMBER {
2261 __parser_str2uint64(&tmp_parser_struct.num_pair[1],$1);
2268 /***************************************************
2269 ***************************************************/
2271 int osm_qos_parse_policy_file(IN osm_subn_t * const p_subn)
2274 static boolean_t first_time = TRUE;
2275 p_qos_parser_osm_log = &p_subn->p_osm->log;
2277 OSM_LOG_ENTER(p_qos_parser_osm_log);
2279 osm_qos_policy_destroy(p_subn->p_qos_policy);
2280 p_subn->p_qos_policy = NULL;
2282 yyin = fopen (p_subn->opt.qos_policy_file, "r");
2285 if (strcmp(p_subn->opt.qos_policy_file,OSM_DEFAULT_QOS_POLICY_FILE)) {
2286 OSM_LOG(p_qos_parser_osm_log, OSM_LOG_ERROR, "ERR AC01: "
2287 "Failed opening QoS policy file %s - %s\n",
2288 p_subn->opt.qos_policy_file, strerror(errno));
2292 OSM_LOG(p_qos_parser_osm_log, OSM_LOG_VERBOSE,
2293 "QoS policy file not found (%s)\n",
2294 p_subn->opt.qos_policy_file);
2302 __setup_simple_qos_levels();
2303 __setup_ulp_match_rules();
2304 OSM_LOG(p_qos_parser_osm_log, OSM_LOG_INFO,
2305 "Loading QoS policy file (%s)\n",
2306 p_subn->opt.qos_policy_file);
2310 * ULP match rules list was emptied at the end of
2311 * previous parsing iteration.
2312 * What's left is to clear simple QoS levels.
2314 __clear_simple_qos_levels();
2319 p_subn->p_qos_policy = osm_qos_policy_create(p_subn);
2321 __parser_tmp_struct_init();
2322 p_qos_policy = p_subn->p_qos_policy;
2326 __parser_tmp_struct_destroy();
2330 OSM_LOG(p_qos_parser_osm_log, OSM_LOG_ERROR, "ERR AC03: "
2331 "Failed parsing QoS policy file (%s)\n",
2332 p_subn->opt.qos_policy_file);
2333 osm_qos_policy_destroy(p_subn->p_qos_policy);
2334 p_subn->p_qos_policy = NULL;
2339 /* add generated ULP match rules to the usual match rules */
2340 __process_ulp_match_rules();
2342 if (osm_qos_policy_validate(p_subn->p_qos_policy,p_qos_parser_osm_log))
2344 OSM_LOG(p_qos_parser_osm_log, OSM_LOG_ERROR, "ERR AC04: "
2345 "Error(s) in QoS policy file (%s)\n",
2346 p_subn->opt.qos_policy_file);
2347 fprintf(stderr, "Error(s) in QoS policy file (%s)\n",
2348 p_subn->opt.qos_policy_file);
2349 osm_qos_policy_destroy(p_subn->p_qos_policy);
2350 p_subn->p_qos_policy = NULL;
2358 OSM_LOG_EXIT(p_qos_parser_osm_log);
2362 /***************************************************
2363 ***************************************************/
2370 /***************************************************
2371 ***************************************************/
2373 static void yyerror(const char *format, ...)
2378 OSM_LOG_ENTER(p_qos_parser_osm_log);
2380 va_start(pvar, format);
2381 vsnprintf(s, sizeof(s), format, pvar);
2384 OSM_LOG(p_qos_parser_osm_log, OSM_LOG_ERROR, "ERR AC05: "
2385 "Syntax error (line %d:%d): %s\n",
2386 line_num, column_num, s);
2387 fprintf(stderr, "Error in QoS Policy File (line %d:%d): %s.\n",
2388 line_num, column_num, s);
2389 OSM_LOG_EXIT(p_qos_parser_osm_log);
2392 /***************************************************
2393 ***************************************************/
2395 static char * __parser_strip_white(char * str)
2398 for (i = (strlen(str)-1); i >= 0; i--)
2400 if (isspace(str[i]))
2405 for (i = 0; i < strlen(str); i++)
2407 if (!isspace(str[i]))
2413 /***************************************************
2414 ***************************************************/
2416 static void __parser_str2uint64(uint64_t * p_val, char * str)
2418 *p_val = strtoull(str, NULL, 0);
2421 /***************************************************
2422 ***************************************************/
2424 static void __parser_port_group_start()
2426 p_current_port_group = osm_qos_policy_port_group_create();
2429 /***************************************************
2430 ***************************************************/
2432 static int __parser_port_group_end()
2434 if(!p_current_port_group->name)
2436 yyerror("port-group validation failed - no port group name specified");
2440 cl_list_insert_tail(&p_qos_policy->port_groups,
2441 p_current_port_group);
2442 p_current_port_group = NULL;
2446 /***************************************************
2447 ***************************************************/
2449 static void __parser_vlarb_scope_start()
2451 p_current_vlarb_scope = osm_qos_policy_vlarb_scope_create();
2454 /***************************************************
2455 ***************************************************/
2457 static int __parser_vlarb_scope_end()
2459 if ( !cl_list_count(&p_current_vlarb_scope->group_list) &&
2460 !cl_list_count(&p_current_vlarb_scope->across_list) )
2462 yyerror("vlarb-scope validation failed - no port groups specified by 'group' or by 'across'");
2466 cl_list_insert_tail(&p_qos_policy->vlarb_tables,
2467 p_current_vlarb_scope);
2468 p_current_vlarb_scope = NULL;
2472 /***************************************************
2473 ***************************************************/
2475 static void __parser_sl2vl_scope_start()
2477 p_current_sl2vl_scope = osm_qos_policy_sl2vl_scope_create();
2480 /***************************************************
2481 ***************************************************/
2483 static int __parser_sl2vl_scope_end()
2485 if (!p_current_sl2vl_scope->sl2vl_table_set)
2487 yyerror("sl2vl-scope validation failed - no sl2vl table specified");
2490 if ( !cl_list_count(&p_current_sl2vl_scope->group_list) &&
2491 !cl_list_count(&p_current_sl2vl_scope->across_to_list) &&
2492 !cl_list_count(&p_current_sl2vl_scope->across_from_list) )
2494 yyerror("sl2vl-scope validation failed - no port groups specified by 'group', 'across-to' or 'across-from'");
2498 cl_list_insert_tail(&p_qos_policy->sl2vl_tables,
2499 p_current_sl2vl_scope);
2500 p_current_sl2vl_scope = NULL;
2504 /***************************************************
2505 ***************************************************/
2507 static void __parser_qos_level_start()
2509 p_current_qos_level = osm_qos_policy_qos_level_create();
2512 /***************************************************
2513 ***************************************************/
2515 static int __parser_qos_level_end()
2517 if (!p_current_qos_level->sl_set)
2519 yyerror("qos-level validation failed - no 'sl' specified");
2522 if (!p_current_qos_level->name)
2524 yyerror("qos-level validation failed - no 'name' specified");
2528 cl_list_insert_tail(&p_qos_policy->qos_levels,
2529 p_current_qos_level);
2530 p_current_qos_level = NULL;
2534 /***************************************************
2535 ***************************************************/
2537 static void __parser_match_rule_start()
2539 p_current_qos_match_rule = osm_qos_policy_match_rule_create();
2542 /***************************************************
2543 ***************************************************/
2545 static int __parser_match_rule_end()
2547 if (!p_current_qos_match_rule->qos_level_name)
2549 yyerror("match-rule validation failed - no 'qos-level-name' specified");
2553 cl_list_insert_tail(&p_qos_policy->qos_match_rules,
2554 p_current_qos_match_rule);
2555 p_current_qos_match_rule = NULL;
2559 /***************************************************
2560 ***************************************************/
2562 static void __parser_ulp_match_rule_start()
2564 p_current_qos_match_rule = osm_qos_policy_match_rule_create();
2567 /***************************************************
2568 ***************************************************/
2570 static int __parser_ulp_match_rule_end()
2572 CL_ASSERT(p_current_qos_match_rule->p_qos_level);
2573 cl_list_insert_tail(&__ulp_match_rules,
2574 p_current_qos_match_rule);
2575 p_current_qos_match_rule = NULL;
2579 /***************************************************
2580 ***************************************************/
2582 static void __parser_tmp_struct_init()
2584 tmp_parser_struct.str[0] = '\0';
2585 cl_list_construct(&tmp_parser_struct.str_list);
2586 cl_list_init(&tmp_parser_struct.str_list, 10);
2587 cl_list_construct(&tmp_parser_struct.num_list);
2588 cl_list_init(&tmp_parser_struct.num_list, 10);
2589 cl_list_construct(&tmp_parser_struct.num_pair_list);
2590 cl_list_init(&tmp_parser_struct.num_pair_list, 10);
2593 /***************************************************
2594 ***************************************************/
2597 * Do NOT free objects from the temp struct.
2598 * Either they are inserted into the parse tree data
2599 * structure, or they are already freed when copying
2600 * their values to the parse tree data structure.
2602 static void __parser_tmp_struct_reset()
2604 tmp_parser_struct.str[0] = '\0';
2605 cl_list_remove_all(&tmp_parser_struct.str_list);
2606 cl_list_remove_all(&tmp_parser_struct.num_list);
2607 cl_list_remove_all(&tmp_parser_struct.num_pair_list);
2610 /***************************************************
2611 ***************************************************/
2613 static void __parser_tmp_struct_destroy()
2615 __parser_tmp_struct_reset();
2616 cl_list_destroy(&tmp_parser_struct.str_list);
2617 cl_list_destroy(&tmp_parser_struct.num_list);
2618 cl_list_destroy(&tmp_parser_struct.num_pair_list);
2621 /***************************************************
2622 ***************************************************/
2624 #define __SIMPLE_QOS_LEVEL_NAME "SimpleQoSLevel_SL"
2625 #define __SIMPLE_QOS_LEVEL_DEFAULT_NAME "SimpleQoSLevel_DEFAULT"
2627 static void __setup_simple_qos_levels()
2631 memset(osm_qos_policy_simple_qos_levels, 0,
2632 sizeof(osm_qos_policy_simple_qos_levels));
2633 for (i = 0; i < 16; i++)
2635 osm_qos_policy_simple_qos_levels[i].sl = i;
2636 osm_qos_policy_simple_qos_levels[i].sl_set = TRUE;
2637 sprintf(tmp_buf, "%s%u", __SIMPLE_QOS_LEVEL_NAME, i);
2638 osm_qos_policy_simple_qos_levels[i].name = strdup(tmp_buf);
2641 memset(&__default_simple_qos_level, 0,
2642 sizeof(__default_simple_qos_level));
2643 __default_simple_qos_level.name =
2644 strdup(__SIMPLE_QOS_LEVEL_DEFAULT_NAME);
2647 /***************************************************
2648 ***************************************************/
2650 static void __clear_simple_qos_levels()
2653 * Simple QoS levels are static.
2654 * What's left is to invalidate default simple QoS level.
2656 __default_simple_qos_level.sl_set = FALSE;
2659 /***************************************************
2660 ***************************************************/
2662 static void __setup_ulp_match_rules()
2664 cl_list_construct(&__ulp_match_rules);
2665 cl_list_init(&__ulp_match_rules, 10);
2668 /***************************************************
2669 ***************************************************/
2671 static void __process_ulp_match_rules()
2673 cl_list_iterator_t list_iterator;
2674 osm_qos_match_rule_t *p_qos_match_rule = NULL;
2676 list_iterator = cl_list_head(&__ulp_match_rules);
2677 while (list_iterator != cl_list_end(&__ulp_match_rules))
2679 p_qos_match_rule = (osm_qos_match_rule_t *) cl_list_obj(list_iterator);
2680 if (p_qos_match_rule)
2681 cl_list_insert_tail(&p_qos_policy->qos_match_rules,
2683 list_iterator = cl_list_next(list_iterator);
2685 cl_list_remove_all(&__ulp_match_rules);
2688 /***************************************************
2689 ***************************************************/
2691 static int OSM_CDECL
2696 uint64_t * pair1 = *((uint64_t **)p1);
2697 uint64_t * pair2 = *((uint64_t **)p2);
2699 if (pair1[0] < pair2[0])
2701 if (pair1[0] > pair2[0])
2704 if (pair1[1] < pair2[1])
2706 if (pair1[1] > pair2[1])
2712 /***************************************************
2713 ***************************************************/
2715 static void __sort_reduce_rangearr(
2718 uint64_t ** * p_res_arr,
2719 unsigned * p_res_arr_len )
2723 unsigned last_valid_ind = 0;
2724 unsigned valid_cnt = 0;
2725 uint64_t ** res_arr;
2726 boolean_t * is_valid_arr;
2731 qsort(arr, arr_len, sizeof(uint64_t*), __cmp_num_range);
2733 is_valid_arr = (boolean_t *)malloc(arr_len * sizeof(boolean_t));
2734 is_valid_arr[last_valid_ind] = TRUE;
2736 for (i = 1; i < arr_len; i++)
2738 if (arr[i][0] <= arr[last_valid_ind][1])
2740 if (arr[i][1] > arr[last_valid_ind][1])
2741 arr[last_valid_ind][1] = arr[i][1];
2744 is_valid_arr[i] = FALSE;
2746 else if ((arr[i][0] - 1) == arr[last_valid_ind][1])
2748 arr[last_valid_ind][1] = arr[i][1];
2751 is_valid_arr[i] = FALSE;
2755 is_valid_arr[i] = TRUE;
2761 res_arr = (uint64_t **)malloc(valid_cnt * sizeof(uint64_t *));
2762 for (i = 0; i < arr_len; i++)
2764 if (is_valid_arr[i])
2765 res_arr[j++] = arr[i];
2770 *p_res_arr = res_arr;
2771 *p_res_arr_len = valid_cnt;
2774 /***************************************************
2775 ***************************************************/
2777 static void __pkey_rangelist2rangearr(
2779 uint64_t ** * p_arr,
2780 unsigned * p_arr_len)
2784 cl_list_iterator_t list_iterator;
2786 list_iterator= cl_list_head(p_list);
2787 while( list_iterator != cl_list_end(p_list) )
2789 p_pkeys = (uint64_t *)cl_list_obj(list_iterator);
2790 p_pkeys[0] &= 0x7fff;
2791 p_pkeys[1] &= 0x7fff;
2792 if (p_pkeys[0] > p_pkeys[1])
2794 tmp_pkey = p_pkeys[1];
2795 p_pkeys[1] = p_pkeys[0];
2796 p_pkeys[0] = tmp_pkey;
2798 list_iterator = cl_list_next(list_iterator);
2801 __rangelist2rangearr(p_list, p_arr, p_arr_len);
2804 /***************************************************
2805 ***************************************************/
2807 static void __rangelist2rangearr(
2809 uint64_t ** * p_arr,
2810 unsigned * p_arr_len)
2812 cl_list_iterator_t list_iterator;
2813 unsigned len = cl_list_count(p_list);
2815 uint64_t ** tmp_arr;
2816 uint64_t ** res_arr = NULL;
2817 unsigned res_arr_len = 0;
2819 tmp_arr = (uint64_t **)malloc(len * sizeof(uint64_t *));
2821 list_iterator = cl_list_head(p_list);
2822 while( list_iterator != cl_list_end(p_list) )
2824 tmp_arr[i++] = (uint64_t *)cl_list_obj(list_iterator);
2825 list_iterator = cl_list_next(list_iterator);
2827 cl_list_remove_all(p_list);
2829 __sort_reduce_rangearr( tmp_arr,
2834 *p_arr_len = res_arr_len;
2837 /***************************************************
2838 ***************************************************/
2840 static void __merge_rangearr(
2841 uint64_t ** range_arr_1,
2842 unsigned range_len_1,
2843 uint64_t ** range_arr_2,
2844 unsigned range_len_2,
2845 uint64_t ** * p_arr,
2846 unsigned * p_arr_len )
2850 unsigned len = range_len_1 + range_len_2;
2851 uint64_t ** tmp_arr;
2852 uint64_t ** res_arr = NULL;
2853 unsigned res_arr_len = 0;
2858 tmp_arr = (uint64_t **)malloc(len * sizeof(uint64_t *));
2860 for (i = 0; i < range_len_1; i++)
2861 tmp_arr[j++] = range_arr_1[i];
2862 for (i = 0; i < range_len_2; i++)
2863 tmp_arr[j++] = range_arr_2[i];
2867 __sort_reduce_rangearr( tmp_arr,
2872 *p_arr_len = res_arr_len;
2875 /***************************************************
2876 ***************************************************/
2878 static void __parser_add_port_to_port_map(
2880 osm_physp_t * p_physp)
2882 if (cl_qmap_get(p_map, cl_ntoh64(osm_physp_get_port_guid(p_physp))) ==
2885 osm_qos_port_t * p_port = osm_qos_policy_port_create(p_physp);
2887 cl_qmap_insert(p_map,
2888 cl_ntoh64(osm_physp_get_port_guid(p_physp)),
2893 /***************************************************
2894 ***************************************************/
2896 static void __parser_add_guid_range_to_port_map(
2898 uint64_t ** range_arr,
2903 osm_port_t * p_osm_port;
2905 if (!range_arr || !range_len)
2908 for (i = 0; i < range_len; i++) {
2909 for (guid_ho = range_arr[i][0]; guid_ho <= range_arr[i][1]; guid_ho++) {
2911 osm_get_port_by_guid(p_qos_policy->p_subn, cl_hton64(guid_ho));
2913 __parser_add_port_to_port_map(p_map, p_osm_port->p_physp);
2920 /***************************************************
2921 ***************************************************/
2923 static void __parser_add_pkey_range_to_port_map(
2925 uint64_t ** range_arr,
2931 osm_prtn_t * p_prtn;
2933 if (!range_arr || !range_len)
2936 for (i = 0; i < range_len; i++) {
2937 for (pkey_64 = range_arr[i][0]; pkey_64 <= range_arr[i][1]; pkey_64++) {
2938 pkey = cl_hton16((uint16_t)(pkey_64 & 0x7fff));
2939 p_prtn = (osm_prtn_t *)
2940 cl_qmap_get(&p_qos_policy->p_subn->prtn_pkey_tbl, pkey);
2941 if (p_prtn != (osm_prtn_t *)cl_qmap_end(
2942 &p_qos_policy->p_subn->prtn_pkey_tbl)) {
2943 __parser_add_map_to_port_map(p_map, &p_prtn->part_guid_tbl);
2944 __parser_add_map_to_port_map(p_map, &p_prtn->full_guid_tbl);
2952 /***************************************************
2953 ***************************************************/
2955 static void __parser_add_partition_list_to_port_map(
2959 cl_list_iterator_t list_iterator;
2961 osm_prtn_t * p_prtn;
2963 /* extract all the ports from the partition
2964 to the port map of this port group */
2965 list_iterator = cl_list_head(p_list);
2966 while(list_iterator != cl_list_end(p_list)) {
2967 tmp_str = (char*)cl_list_obj(list_iterator);
2969 p_prtn = osm_prtn_find_by_name(p_qos_policy->p_subn, tmp_str);
2971 __parser_add_map_to_port_map(p_map, &p_prtn->part_guid_tbl);
2972 __parser_add_map_to_port_map(p_map, &p_prtn->full_guid_tbl);
2976 list_iterator = cl_list_next(list_iterator);
2978 cl_list_remove_all(p_list);
2981 /***************************************************
2982 ***************************************************/
2984 static void __parser_add_map_to_port_map(
2988 cl_map_iterator_t map_iterator;
2989 osm_physp_t * p_physp;
2991 if (!p_dmap || !p_smap)
2994 map_iterator = cl_map_head(p_smap);
2995 while (map_iterator != cl_map_end(p_smap)) {
2996 p_physp = (osm_physp_t*)cl_map_obj(map_iterator);
2997 __parser_add_port_to_port_map(p_dmap, p_physp);
2998 map_iterator = cl_map_next(map_iterator);
3002 /***************************************************
3003 ***************************************************/
3005 static int __validate_pkeys( uint64_t ** range_arr,
3012 osm_prtn_t * p_prtn;
3014 if (!range_arr || !range_len)
3017 for (i = 0; i < range_len; i++) {
3018 for (pkey_64 = range_arr[i][0]; pkey_64 <= range_arr[i][1]; pkey_64++) {
3019 pkey = cl_hton16((uint16_t)(pkey_64 & 0x7fff));
3020 p_prtn = (osm_prtn_t *)
3021 cl_qmap_get(&p_qos_policy->p_subn->prtn_pkey_tbl, pkey);
3023 if (p_prtn == (osm_prtn_t *)cl_qmap_end(
3024 &p_qos_policy->p_subn->prtn_pkey_tbl))
3029 * Be very strict for IPoIB partition:
3030 * - the partition for the pkey have to exist
3031 * - it has to have at least 2 full members
3034 yyerror("IPoIB partition, pkey 0x%04X - "
3035 "partition doesn't exist",
3039 else if (cl_map_count(&p_prtn->full_guid_tbl) < 2) {
3040 yyerror("IPoIB partition, pkey 0x%04X - "
3041 "partition has less than two full members",
3048 * For non-IPoIB pkey we just want to check that
3049 * the relevant partition exists.
3050 * And even if it doesn't, don't exit - just print
3051 * error message and continue.
3053 OSM_LOG(p_qos_parser_osm_log, OSM_LOG_ERROR, "ERR AC02: "
3054 "pkey 0x%04X - partition doesn't exist",
3062 /***************************************************
3063 ***************************************************/