1219820Sjeff%{
2219820Sjeff/*
3219820Sjeff * Copyright (c) 2004-2006 Voltaire, Inc. All rights reserved.
4219820Sjeff * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
5219820Sjeff * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
6219820Sjeff * Copyright (c) 2008 HNR Consulting. All rights reserved.
7219820Sjeff *
8219820Sjeff * This software is available to you under a choice of one of two
9219820Sjeff * licenses.  You may choose to be licensed under the terms of the GNU
10219820Sjeff * General Public License (GPL) Version 2, available from the file
11219820Sjeff * COPYING in the main directory of this source tree, or the
12219820Sjeff * OpenIB.org BSD license below:
13219820Sjeff *
14219820Sjeff *     Redistribution and use in source and binary forms, with or
15219820Sjeff *     without modification, are permitted provided that the following
16219820Sjeff *     conditions are met:
17219820Sjeff *
18219820Sjeff *      - Redistributions of source code must retain the above
19219820Sjeff *        copyright notice, this list of conditions and the following
20219820Sjeff *        disclaimer.
21219820Sjeff *
22219820Sjeff *      - Redistributions in binary form must reproduce the above
23219820Sjeff *        copyright notice, this list of conditions and the following
24219820Sjeff *        disclaimer in the documentation and/or other materials
25219820Sjeff *        provided with the distribution.
26219820Sjeff *
27219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
31219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
32219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
33219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
34219820Sjeff * SOFTWARE.
35219820Sjeff *
36219820Sjeff */
37219820Sjeff
38219820Sjeff/*
39219820Sjeff * Abstract:
40219820Sjeff *    Grammar of OSM QoS parser.
41219820Sjeff *
42219820Sjeff * Environment:
43219820Sjeff *    Linux User Mode
44219820Sjeff *
45219820Sjeff * Author:
46219820Sjeff *    Yevgeny Kliteynik, Mellanox
47219820Sjeff */
48219820Sjeff
49219820Sjeff#include <stdio.h>
50219820Sjeff#include <assert.h>
51219820Sjeff#include <stdarg.h>
52219820Sjeff#include <stdlib.h>
53219820Sjeff#include <string.h>
54219820Sjeff#include <ctype.h>
55219820Sjeff#include <errno.h>
56219820Sjeff#include <opensm/osm_opensm.h>
57219820Sjeff#include <opensm/osm_qos_policy.h>
58219820Sjeff
59219820Sjeff#define OSM_QOS_POLICY_MAX_LINE_LEN         1024*10
60219820Sjeff#define OSM_QOS_POLICY_SL2VL_TABLE_LEN      IB_MAX_NUM_VLS
61219820Sjeff#define OSM_QOS_POLICY_MAX_VL_NUM           IB_MAX_NUM_VLS
62219820Sjeff
63219820Sjefftypedef struct tmp_parser_struct_t_ {
64219820Sjeff    char       str[OSM_QOS_POLICY_MAX_LINE_LEN];
65219820Sjeff    uint64_t   num_pair[2];
66219820Sjeff    cl_list_t  str_list;
67219820Sjeff    cl_list_t  num_list;
68219820Sjeff    cl_list_t  num_pair_list;
69219820Sjeff} tmp_parser_struct_t;
70219820Sjeff
71219820Sjeffstatic void __parser_tmp_struct_init();
72219820Sjeffstatic void __parser_tmp_struct_reset();
73219820Sjeffstatic void __parser_tmp_struct_destroy();
74219820Sjeff
75219820Sjeffstatic char * __parser_strip_white(char * str);
76219820Sjeff
77219820Sjeffstatic void __parser_str2uint64(uint64_t * p_val, char * str);
78219820Sjeff
79219820Sjeffstatic void __parser_port_group_start();
80219820Sjeffstatic int __parser_port_group_end();
81219820Sjeff
82219820Sjeffstatic void __parser_sl2vl_scope_start();
83219820Sjeffstatic int __parser_sl2vl_scope_end();
84219820Sjeff
85219820Sjeffstatic void __parser_vlarb_scope_start();
86219820Sjeffstatic int __parser_vlarb_scope_end();
87219820Sjeff
88219820Sjeffstatic void __parser_qos_level_start();
89219820Sjeffstatic int __parser_qos_level_end();
90219820Sjeff
91219820Sjeffstatic void __parser_match_rule_start();
92219820Sjeffstatic int __parser_match_rule_end();
93219820Sjeff
94219820Sjeffstatic void __parser_ulp_match_rule_start();
95219820Sjeffstatic int __parser_ulp_match_rule_end();
96219820Sjeff
97219820Sjeffstatic void __pkey_rangelist2rangearr(
98219820Sjeff    cl_list_t    * p_list,
99219820Sjeff    uint64_t  ** * p_arr,
100219820Sjeff    unsigned     * p_arr_len);
101219820Sjeff
102219820Sjeffstatic void __rangelist2rangearr(
103219820Sjeff    cl_list_t    * p_list,
104219820Sjeff    uint64_t  ** * p_arr,
105219820Sjeff    unsigned     * p_arr_len);
106219820Sjeff
107219820Sjeffstatic void __merge_rangearr(
108219820Sjeff    uint64_t  **   range_arr_1,
109219820Sjeff    unsigned       range_len_1,
110219820Sjeff    uint64_t  **   range_arr_2,
111219820Sjeff    unsigned       range_len_2,
112219820Sjeff    uint64_t  ** * p_arr,
113219820Sjeff    unsigned     * p_arr_len );
114219820Sjeff
115219820Sjeffstatic void __parser_add_port_to_port_map(
116219820Sjeff    cl_qmap_t   * p_map,
117219820Sjeff    osm_physp_t * p_physp);
118219820Sjeff
119219820Sjeffstatic void __parser_add_guid_range_to_port_map(
120219820Sjeff    cl_qmap_t  * p_map,
121219820Sjeff    uint64_t  ** range_arr,
122219820Sjeff    unsigned     range_len);
123219820Sjeff
124219820Sjeffstatic void __parser_add_pkey_range_to_port_map(
125219820Sjeff    cl_qmap_t  * p_map,
126219820Sjeff    uint64_t  ** range_arr,
127219820Sjeff    unsigned     range_len);
128219820Sjeff
129219820Sjeffstatic void __parser_add_partition_list_to_port_map(
130219820Sjeff    cl_qmap_t  * p_map,
131219820Sjeff    cl_list_t  * p_list);
132219820Sjeff
133219820Sjeffstatic void __parser_add_map_to_port_map(
134219820Sjeff    cl_qmap_t * p_dmap,
135219820Sjeff    cl_map_t  * p_smap);
136219820Sjeff
137219820Sjeffstatic int __validate_pkeys(
138219820Sjeff    uint64_t ** range_arr,
139219820Sjeff    unsigned    range_len,
140219820Sjeff    boolean_t   is_ipoib);
141219820Sjeff
142219820Sjeffstatic void __setup_simple_qos_levels();
143219820Sjeffstatic void __clear_simple_qos_levels();
144219820Sjeffstatic void __setup_ulp_match_rules();
145219820Sjeffstatic void __process_ulp_match_rules();
146219820Sjeffstatic void yyerror(const char *format, ...);
147219820Sjeff
148219820Sjeffextern char * yytext;
149219820Sjeffextern int yylex (void);
150219820Sjeffextern FILE * yyin;
151219820Sjeffextern int errno;
152219820Sjeffint yyparse();
153219820Sjeff
154219820Sjeff#define RESET_BUFFER  __parser_tmp_struct_reset()
155219820Sjeff
156219820Sjefftmp_parser_struct_t tmp_parser_struct;
157219820Sjeff
158219820Sjeffint column_num;
159219820Sjeffint line_num;
160219820Sjeff
161219820Sjeffosm_qos_policy_t       * p_qos_policy = NULL;
162219820Sjeffosm_qos_port_group_t   * p_current_port_group = NULL;
163219820Sjeffosm_qos_sl2vl_scope_t  * p_current_sl2vl_scope = NULL;
164219820Sjeffosm_qos_vlarb_scope_t  * p_current_vlarb_scope = NULL;
165219820Sjeffosm_qos_level_t        * p_current_qos_level = NULL;
166219820Sjeffosm_qos_match_rule_t   * p_current_qos_match_rule = NULL;
167219820Sjeffosm_log_t              * p_qos_parser_osm_log;
168219820Sjeff
169219820Sjeff/* 16 Simple QoS Levels - one for each SL */
170219820Sjeffstatic osm_qos_level_t osm_qos_policy_simple_qos_levels[16];
171219820Sjeff
172219820Sjeff/* Default Simple QoS Level */
173219820Sjeffosm_qos_level_t __default_simple_qos_level;
174219820Sjeff
175219820Sjeff/*
176219820Sjeff * List of match rules that will be generated by the
177219820Sjeff * qos-ulp section. These rules are concatenated to
178219820Sjeff * the end of the usual matching rules list at the
179219820Sjeff * end of parsing.
180219820Sjeff */
181219820Sjeffstatic cl_list_t __ulp_match_rules;
182219820Sjeff
183219820Sjeff/***************************************************/
184219820Sjeff
185219820Sjeff%}
186219820Sjeff
187219820Sjeff%token TK_NUMBER
188219820Sjeff%token TK_DASH
189219820Sjeff%token TK_DOTDOT
190219820Sjeff%token TK_COMMA
191219820Sjeff%token TK_ASTERISK
192219820Sjeff%token TK_TEXT
193219820Sjeff
194219820Sjeff%token TK_QOS_ULPS_START
195219820Sjeff%token TK_QOS_ULPS_END
196219820Sjeff
197219820Sjeff%token TK_PORT_GROUPS_START
198219820Sjeff%token TK_PORT_GROUPS_END
199219820Sjeff%token TK_PORT_GROUP_START
200219820Sjeff%token TK_PORT_GROUP_END
201219820Sjeff
202219820Sjeff%token TK_QOS_SETUP_START
203219820Sjeff%token TK_QOS_SETUP_END
204219820Sjeff%token TK_VLARB_TABLES_START
205219820Sjeff%token TK_VLARB_TABLES_END
206219820Sjeff%token TK_VLARB_SCOPE_START
207219820Sjeff%token TK_VLARB_SCOPE_END
208219820Sjeff
209219820Sjeff%token TK_SL2VL_TABLES_START
210219820Sjeff%token TK_SL2VL_TABLES_END
211219820Sjeff%token TK_SL2VL_SCOPE_START
212219820Sjeff%token TK_SL2VL_SCOPE_END
213219820Sjeff
214219820Sjeff%token TK_QOS_LEVELS_START
215219820Sjeff%token TK_QOS_LEVELS_END
216219820Sjeff%token TK_QOS_LEVEL_START
217219820Sjeff%token TK_QOS_LEVEL_END
218219820Sjeff
219219820Sjeff%token TK_QOS_MATCH_RULES_START
220219820Sjeff%token TK_QOS_MATCH_RULES_END
221219820Sjeff%token TK_QOS_MATCH_RULE_START
222219820Sjeff%token TK_QOS_MATCH_RULE_END
223219820Sjeff
224219820Sjeff%token TK_NAME
225219820Sjeff%token TK_USE
226219820Sjeff%token TK_PORT_GUID
227219820Sjeff%token TK_PORT_NAME
228219820Sjeff%token TK_PARTITION
229219820Sjeff%token TK_NODE_TYPE
230219820Sjeff%token TK_GROUP
231219820Sjeff%token TK_ACROSS
232219820Sjeff%token TK_VLARB_HIGH
233219820Sjeff%token TK_VLARB_LOW
234219820Sjeff%token TK_VLARB_HIGH_LIMIT
235219820Sjeff%token TK_TO
236219820Sjeff%token TK_FROM
237219820Sjeff%token TK_ACROSS_TO
238219820Sjeff%token TK_ACROSS_FROM
239219820Sjeff%token TK_SL2VL_TABLE
240219820Sjeff%token TK_SL
241219820Sjeff%token TK_MTU_LIMIT
242219820Sjeff%token TK_RATE_LIMIT
243219820Sjeff%token TK_PACKET_LIFE
244219820Sjeff%token TK_PATH_BITS
245219820Sjeff%token TK_QOS_CLASS
246219820Sjeff%token TK_SOURCE
247219820Sjeff%token TK_DESTINATION
248219820Sjeff%token TK_SERVICE_ID
249219820Sjeff%token TK_QOS_LEVEL_NAME
250219820Sjeff%token TK_PKEY
251219820Sjeff
252219820Sjeff%token TK_NODE_TYPE_ROUTER
253219820Sjeff%token TK_NODE_TYPE_CA
254219820Sjeff%token TK_NODE_TYPE_SWITCH
255219820Sjeff%token TK_NODE_TYPE_SELF
256219820Sjeff%token TK_NODE_TYPE_ALL
257219820Sjeff
258219820Sjeff%token TK_ULP_DEFAULT
259219820Sjeff%token TK_ULP_ANY_SERVICE_ID
260219820Sjeff%token TK_ULP_ANY_PKEY
261219820Sjeff%token TK_ULP_ANY_TARGET_PORT_GUID
262219820Sjeff%token TK_ULP_SDP_DEFAULT
263219820Sjeff%token TK_ULP_SDP_PORT
264219820Sjeff%token TK_ULP_RDS_DEFAULT
265219820Sjeff%token TK_ULP_RDS_PORT
266219820Sjeff%token TK_ULP_ISER_DEFAULT
267219820Sjeff%token TK_ULP_ISER_PORT
268219820Sjeff%token TK_ULP_SRP_GUID
269219820Sjeff%token TK_ULP_IPOIB_DEFAULT
270219820Sjeff%token TK_ULP_IPOIB_PKEY
271219820Sjeff
272219820Sjeff%start head
273219820Sjeff
274219820Sjeff%%
275219820Sjeff
276219820Sjeffhead:               qos_policy_entries
277219820Sjeff                    ;
278219820Sjeff
279219820Sjeffqos_policy_entries: /* empty */
280219820Sjeff                    | qos_policy_entries qos_policy_entry
281219820Sjeff                    ;
282219820Sjeff
283219820Sjeffqos_policy_entry:     qos_ulps_section
284219820Sjeff                    | port_groups_section
285219820Sjeff                    | qos_setup_section
286219820Sjeff                    | qos_levels_section
287219820Sjeff                    | qos_match_rules_section
288219820Sjeff                    ;
289219820Sjeff
290219820Sjeff    /*
291219820Sjeff     * Parsing qos-ulps:
292219820Sjeff     * -------------------
293219820Sjeff     *  qos-ulps
294219820Sjeff     *      default                       : 0 #default SL
295219820Sjeff     *      sdp, port-num 30000           : 1 #SL for SDP when destination port is 30000
296219820Sjeff     *      sdp, port-num 10000-20000     : 2
297219820Sjeff     *      sdp                           : 0 #default SL for SDP
298219820Sjeff     *      srp, target-port-guid 0x1234  : 2
299219820Sjeff     *      rds, port-num 25000           : 2 #SL for RDS when destination port is 25000
300219820Sjeff     *      rds,                          : 0 #default SL for RDS
301219820Sjeff     *      iser, port-num 900            : 5 #SL for iSER where target port is 900
302219820Sjeff     *      iser                          : 4 #default SL for iSER
303219820Sjeff     *      ipoib, pkey 0x0001            : 5 #SL for IPoIB on partition with pkey 0x0001
304219820Sjeff     *      ipoib                         : 6 #default IPoIB partition - pkey=0x7FFF
305219820Sjeff     *      any, service-id 0x6234        : 2
306219820Sjeff     *      any, pkey 0x0ABC              : 3
307219820Sjeff     *      any, target-port-guid 0x0ABC-0xFFFFF : 6
308219820Sjeff     *  end-qos-ulps
309219820Sjeff     */
310219820Sjeff
311219820Sjeffqos_ulps_section: TK_QOS_ULPS_START qos_ulps TK_QOS_ULPS_END
312219820Sjeff                     ;
313219820Sjeff
314219820Sjeffqos_ulps:             qos_ulp
315219820Sjeff                    | qos_ulps qos_ulp
316219820Sjeff                    ;
317219820Sjeff
318219820Sjeff    /*
319219820Sjeff     * Parsing port groups:
320219820Sjeff     * -------------------
321219820Sjeff     *  port-groups
322219820Sjeff     *       port-group
323219820Sjeff     *          name: Storage
324219820Sjeff     *          use: our SRP storage targets
325219820Sjeff     *          port-guid: 0x1000000000000001,0x1000000000000002
326219820Sjeff     *          ...
327219820Sjeff     *          port-name: vs1 HCA-1/P1
328219820Sjeff     *          port-name: node_description/P2
329219820Sjeff     *          ...
330219820Sjeff     *          pkey: 0x00FF-0x0FFF
331219820Sjeff     *          ...
332219820Sjeff     *          partition: Part1
333219820Sjeff     *          ...
334219820Sjeff     *          node-type: ROUTER,CA,SWITCH,SELF,ALL
335219820Sjeff     *          ...
336219820Sjeff     *      end-port-group
337219820Sjeff     *      port-group
338219820Sjeff     *          ...
339219820Sjeff     *      end-port-group
340219820Sjeff     *  end-port-groups
341219820Sjeff     */
342219820Sjeff
343219820Sjeff
344219820Sjeffport_groups_section: TK_PORT_GROUPS_START port_groups TK_PORT_GROUPS_END
345219820Sjeff                     ;
346219820Sjeff
347219820Sjeffport_groups:        port_group
348219820Sjeff                    | port_groups port_group
349219820Sjeff                    ;
350219820Sjeff
351219820Sjeffport_group:         port_group_start port_group_entries port_group_end
352219820Sjeff                    ;
353219820Sjeff
354219820Sjeffport_group_start:   TK_PORT_GROUP_START {
355219820Sjeff                        __parser_port_group_start();
356219820Sjeff                    }
357219820Sjeff                    ;
358219820Sjeff
359219820Sjeffport_group_end:     TK_PORT_GROUP_END {
360219820Sjeff                        if ( __parser_port_group_end() )
361219820Sjeff                            return 1;
362219820Sjeff                    }
363219820Sjeff                    ;
364219820Sjeff
365219820Sjeffport_group_entries: /* empty */
366219820Sjeff                    | port_group_entries port_group_entry
367219820Sjeff                    ;
368219820Sjeff
369219820Sjeffport_group_entry:     port_group_name
370219820Sjeff                    | port_group_use
371219820Sjeff                    | port_group_port_guid
372219820Sjeff                    | port_group_port_name
373219820Sjeff                    | port_group_pkey
374219820Sjeff                    | port_group_partition
375219820Sjeff                    | port_group_node_type
376219820Sjeff                    ;
377219820Sjeff
378219820Sjeff
379219820Sjeff    /*
380219820Sjeff     * Parsing qos setup:
381219820Sjeff     * -----------------
382219820Sjeff     *  qos-setup
383219820Sjeff     *      vlarb-tables
384219820Sjeff     *          vlarb-scope
385219820Sjeff     *              ...
386219820Sjeff     *          end-vlarb-scope
387219820Sjeff     *          vlarb-scope
388219820Sjeff     *              ...
389219820Sjeff     *          end-vlarb-scope
390219820Sjeff     *     end-vlarb-tables
391219820Sjeff     *     sl2vl-tables
392219820Sjeff     *          sl2vl-scope
393219820Sjeff     *              ...
394219820Sjeff     *         end-sl2vl-scope
395219820Sjeff     *         sl2vl-scope
396219820Sjeff     *              ...
397219820Sjeff     *          end-sl2vl-scope
398219820Sjeff     *     end-sl2vl-tables
399219820Sjeff     *  end-qos-setup
400219820Sjeff     */
401219820Sjeff
402219820Sjeffqos_setup_section:  TK_QOS_SETUP_START qos_setup_items TK_QOS_SETUP_END
403219820Sjeff                    ;
404219820Sjeff
405219820Sjeffqos_setup_items:    /* empty */
406219820Sjeff                    | qos_setup_items vlarb_tables
407219820Sjeff                    | qos_setup_items sl2vl_tables
408219820Sjeff                    ;
409219820Sjeff
410219820Sjeff    /* Parsing vlarb-tables */
411219820Sjeff
412219820Sjeffvlarb_tables:       TK_VLARB_TABLES_START vlarb_scope_items TK_VLARB_TABLES_END
413219820Sjeff                    ;
414219820Sjeff
415219820Sjeffvlarb_scope_items:  /* empty */
416219820Sjeff                    | vlarb_scope_items vlarb_scope
417219820Sjeff                    ;
418219820Sjeff
419219820Sjeffvlarb_scope:        vlarb_scope_start vlarb_scope_entries vlarb_scope_end
420219820Sjeff                    ;
421219820Sjeff
422219820Sjeffvlarb_scope_start:  TK_VLARB_SCOPE_START {
423219820Sjeff                        __parser_vlarb_scope_start();
424219820Sjeff                    }
425219820Sjeff                    ;
426219820Sjeff
427219820Sjeffvlarb_scope_end:    TK_VLARB_SCOPE_END {
428219820Sjeff                        if ( __parser_vlarb_scope_end() )
429219820Sjeff                            return 1;
430219820Sjeff                    }
431219820Sjeff                    ;
432219820Sjeff
433219820Sjeffvlarb_scope_entries:/* empty */
434219820Sjeff                    | vlarb_scope_entries vlarb_scope_entry
435219820Sjeff                    ;
436219820Sjeff
437219820Sjeff    /*
438219820Sjeff     *          vlarb-scope
439219820Sjeff     *              group: Storage
440219820Sjeff     *              ...
441219820Sjeff     *              across: Storage
442219820Sjeff     *              ...
443219820Sjeff     *              vlarb-high: 0:255,1:127,2:63,3:31,4:15,5:7,6:3,7:1
444219820Sjeff     *              vlarb-low: 8:255,9:127,10:63,11:31,12:15,13:7,14:3
445219820Sjeff     *              vl-high-limit: 10
446219820Sjeff     *          end-vlarb-scope
447219820Sjeff     */
448219820Sjeff
449219820Sjeffvlarb_scope_entry:    vlarb_scope_group
450219820Sjeff                    | vlarb_scope_across
451219820Sjeff                    | vlarb_scope_vlarb_high
452219820Sjeff                    | vlarb_scope_vlarb_low
453219820Sjeff                    | vlarb_scope_vlarb_high_limit
454219820Sjeff                    ;
455219820Sjeff
456219820Sjeff    /* Parsing sl2vl-tables */
457219820Sjeff
458219820Sjeffsl2vl_tables:       TK_SL2VL_TABLES_START sl2vl_scope_items TK_SL2VL_TABLES_END
459219820Sjeff                    ;
460219820Sjeff
461219820Sjeffsl2vl_scope_items:  /* empty */
462219820Sjeff                    | sl2vl_scope_items sl2vl_scope
463219820Sjeff                    ;
464219820Sjeff
465219820Sjeffsl2vl_scope:        sl2vl_scope_start sl2vl_scope_entries sl2vl_scope_end
466219820Sjeff                    ;
467219820Sjeff
468219820Sjeffsl2vl_scope_start:  TK_SL2VL_SCOPE_START {
469219820Sjeff                        __parser_sl2vl_scope_start();
470219820Sjeff                    }
471219820Sjeff                    ;
472219820Sjeff
473219820Sjeffsl2vl_scope_end:    TK_SL2VL_SCOPE_END {
474219820Sjeff                        if ( __parser_sl2vl_scope_end() )
475219820Sjeff                            return 1;
476219820Sjeff                    }
477219820Sjeff                    ;
478219820Sjeff
479219820Sjeffsl2vl_scope_entries:/* empty */
480219820Sjeff                    | sl2vl_scope_entries sl2vl_scope_entry
481219820Sjeff                    ;
482219820Sjeff
483219820Sjeff    /*
484219820Sjeff     *          sl2vl-scope
485219820Sjeff     *              group: Part1
486219820Sjeff     *              ...
487219820Sjeff     *              from: *
488219820Sjeff     *              ...
489219820Sjeff     *              to: *
490219820Sjeff     *              ...
491219820Sjeff     *              across-to: Storage2
492219820Sjeff     *              ...
493219820Sjeff     *              across-from: Storage1
494219820Sjeff     *              ...
495219820Sjeff     *              sl2vl-table: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,7
496219820Sjeff     *          end-sl2vl-scope
497219820Sjeff     */
498219820Sjeff
499219820Sjeffsl2vl_scope_entry:    sl2vl_scope_group
500219820Sjeff                    | sl2vl_scope_across
501219820Sjeff                    | sl2vl_scope_across_from
502219820Sjeff                    | sl2vl_scope_across_to
503219820Sjeff                    | sl2vl_scope_from
504219820Sjeff                    | sl2vl_scope_to
505219820Sjeff                    | sl2vl_scope_sl2vl_table
506219820Sjeff                    ;
507219820Sjeff
508219820Sjeff    /*
509219820Sjeff     * Parsing qos-levels:
510219820Sjeff     * ------------------
511219820Sjeff     *  qos-levels
512219820Sjeff     *      qos-level
513219820Sjeff     *          name: qos_level_1
514219820Sjeff     *          use: for the lowest priority communication
515219820Sjeff     *          sl: 15
516219820Sjeff     *          mtu-limit: 1
517219820Sjeff     *          rate-limit: 1
518219820Sjeff     *          packet-life: 12
519219820Sjeff     *          path-bits: 2,4,8-32
520219820Sjeff     *          pkey: 0x00FF-0x0FFF
521219820Sjeff     *      end-qos-level
522219820Sjeff     *          ...
523219820Sjeff     *      qos-level
524219820Sjeff     *    end-qos-level
525219820Sjeff     *  end-qos-levels
526219820Sjeff     */
527219820Sjeff
528219820Sjeff
529219820Sjeffqos_levels_section: TK_QOS_LEVELS_START qos_levels TK_QOS_LEVELS_END
530219820Sjeff                    ;
531219820Sjeff
532219820Sjeffqos_levels:         /* empty */
533219820Sjeff                    | qos_levels qos_level
534219820Sjeff                    ;
535219820Sjeff
536219820Sjeffqos_level:          qos_level_start qos_level_entries qos_level_end
537219820Sjeff                    ;
538219820Sjeff
539219820Sjeffqos_level_start:    TK_QOS_LEVEL_START {
540219820Sjeff                        __parser_qos_level_start();
541219820Sjeff                    }
542219820Sjeff                    ;
543219820Sjeff
544219820Sjeffqos_level_end:      TK_QOS_LEVEL_END {
545219820Sjeff                        if ( __parser_qos_level_end() )
546219820Sjeff                            return 1;
547219820Sjeff                    }
548219820Sjeff                    ;
549219820Sjeff
550219820Sjeffqos_level_entries:  /* empty */
551219820Sjeff                    | qos_level_entries qos_level_entry
552219820Sjeff                    ;
553219820Sjeff
554219820Sjeffqos_level_entry:      qos_level_name
555219820Sjeff                    | qos_level_use
556219820Sjeff                    | qos_level_sl
557219820Sjeff                    | qos_level_mtu_limit
558219820Sjeff                    | qos_level_rate_limit
559219820Sjeff                    | qos_level_packet_life
560219820Sjeff                    | qos_level_path_bits
561219820Sjeff                    | qos_level_pkey
562219820Sjeff                    ;
563219820Sjeff
564219820Sjeff    /*
565219820Sjeff     * Parsing qos-match-rules:
566219820Sjeff     * -----------------------
567219820Sjeff     *  qos-match-rules
568219820Sjeff     *      qos-match-rule
569219820Sjeff     *          use: low latency by class 7-9 or 11 and bla bla
570219820Sjeff     *          qos-class: 7-9,11
571219820Sjeff     *          qos-level-name: default
572219820Sjeff     *          source: Storage
573219820Sjeff     *          destination: Storage
574219820Sjeff     *          service-id: 22,4719-5000
575219820Sjeff     *          pkey: 0x00FF-0x0FFF
576219820Sjeff     *      end-qos-match-rule
577219820Sjeff     *      qos-match-rule
578219820Sjeff     *          ...
579219820Sjeff     *      end-qos-match-rule
580219820Sjeff     *  end-qos-match-rules
581219820Sjeff     */
582219820Sjeff
583219820Sjeffqos_match_rules_section: TK_QOS_MATCH_RULES_START qos_match_rules TK_QOS_MATCH_RULES_END
584219820Sjeff                    ;
585219820Sjeff
586219820Sjeffqos_match_rules:    /* empty */
587219820Sjeff                    | qos_match_rules qos_match_rule
588219820Sjeff                    ;
589219820Sjeff
590219820Sjeffqos_match_rule:     qos_match_rule_start qos_match_rule_entries qos_match_rule_end
591219820Sjeff                    ;
592219820Sjeff
593219820Sjeffqos_match_rule_start: TK_QOS_MATCH_RULE_START {
594219820Sjeff                        __parser_match_rule_start();
595219820Sjeff                    }
596219820Sjeff                    ;
597219820Sjeff
598219820Sjeffqos_match_rule_end: TK_QOS_MATCH_RULE_END {
599219820Sjeff                        if ( __parser_match_rule_end() )
600219820Sjeff                            return 1;
601219820Sjeff                    }
602219820Sjeff                    ;
603219820Sjeff
604219820Sjeffqos_match_rule_entries: /* empty */
605219820Sjeff                    | qos_match_rule_entries qos_match_rule_entry
606219820Sjeff                    ;
607219820Sjeff
608219820Sjeffqos_match_rule_entry: qos_match_rule_use
609219820Sjeff                    | qos_match_rule_qos_class
610219820Sjeff                    | qos_match_rule_qos_level_name
611219820Sjeff                    | qos_match_rule_source
612219820Sjeff                    | qos_match_rule_destination
613219820Sjeff                    | qos_match_rule_service_id
614219820Sjeff                    | qos_match_rule_pkey
615219820Sjeff                    ;
616219820Sjeff
617219820Sjeff
618219820Sjeff    /*
619219820Sjeff     * Parsing qos-ulps:
620219820Sjeff     * -----------------
621219820Sjeff     *   default
622219820Sjeff     *   sdp
623219820Sjeff     *   sdp with port-num
624219820Sjeff     *   rds
625219820Sjeff     *   rds with port-num
626219820Sjeff     *   srp with port-guid
627219820Sjeff     *   iser
628219820Sjeff     *   iser with port-num
629219820Sjeff     *   ipoib
630219820Sjeff     *   ipoib with pkey
631219820Sjeff     *   any with service-id
632219820Sjeff     *   any with pkey
633219820Sjeff     *   any with target-port-guid
634219820Sjeff     */
635219820Sjeff
636219820Sjeffqos_ulp:            TK_ULP_DEFAULT single_number {
637219820Sjeff                        /* parsing default ulp rule: "default: num" */
638219820Sjeff                        cl_list_iterator_t    list_iterator;
639219820Sjeff                        uint64_t            * p_tmp_num;
640219820Sjeff
641219820Sjeff                        list_iterator = cl_list_head(&tmp_parser_struct.num_list);
642219820Sjeff                        p_tmp_num = (uint64_t*)cl_list_obj(list_iterator);
643219820Sjeff                        if (*p_tmp_num > 15)
644219820Sjeff                        {
645219820Sjeff                            yyerror("illegal SL value");
646219820Sjeff                            return 1;
647219820Sjeff                        }
648219820Sjeff                        __default_simple_qos_level.sl = (uint8_t)(*p_tmp_num);
649219820Sjeff                        __default_simple_qos_level.sl_set = TRUE;
650219820Sjeff                        free(p_tmp_num);
651219820Sjeff                        cl_list_remove_all(&tmp_parser_struct.num_list);
652219820Sjeff                    }
653219820Sjeff
654219820Sjeff                    | qos_ulp_type_any_service list_of_ranges TK_DOTDOT {
655219820Sjeff                        /* "any, service-id ... : sl" - one instance of list of ranges */
656219820Sjeff                        uint64_t ** range_arr;
657219820Sjeff                        unsigned    range_len;
658219820Sjeff
659219820Sjeff                        if (!cl_list_count(&tmp_parser_struct.num_pair_list))
660219820Sjeff                        {
661219820Sjeff                            yyerror("ULP rule doesn't have service ids");
662219820Sjeff                            return 1;
663219820Sjeff                        }
664219820Sjeff
665219820Sjeff                        /* get all the service id ranges */
666219820Sjeff                        __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
667219820Sjeff                                              &range_arr,
668219820Sjeff                                              &range_len );
669219820Sjeff
670219820Sjeff                        p_current_qos_match_rule->service_id_range_arr = range_arr;
671219820Sjeff                        p_current_qos_match_rule->service_id_range_len = range_len;
672219820Sjeff
673219820Sjeff                    } qos_ulp_sl
674219820Sjeff
675219820Sjeff                    | qos_ulp_type_any_pkey list_of_ranges TK_DOTDOT {
676219820Sjeff                        /* "any, pkey ... : sl" - one instance of list of ranges */
677219820Sjeff                        uint64_t ** range_arr;
678219820Sjeff                        unsigned    range_len;
679219820Sjeff
680219820Sjeff                        if (!cl_list_count(&tmp_parser_struct.num_pair_list))
681219820Sjeff                        {
682219820Sjeff                            yyerror("ULP rule doesn't have pkeys");
683219820Sjeff                            return 1;
684219820Sjeff                        }
685219820Sjeff
686219820Sjeff                        /* get all the pkey ranges */
687219820Sjeff                        __pkey_rangelist2rangearr( &tmp_parser_struct.num_pair_list,
688219820Sjeff                                              &range_arr,
689219820Sjeff                                              &range_len );
690219820Sjeff
691219820Sjeff                        p_current_qos_match_rule->pkey_range_arr = range_arr;
692219820Sjeff                        p_current_qos_match_rule->pkey_range_len = range_len;
693219820Sjeff
694219820Sjeff                    } qos_ulp_sl
695219820Sjeff
696219820Sjeff                    | qos_ulp_type_any_target_port_guid list_of_ranges TK_DOTDOT {
697219820Sjeff                        /* any, target-port-guid ... : sl */
698219820Sjeff                        uint64_t ** range_arr;
699219820Sjeff                        unsigned    range_len;
700219820Sjeff
701219820Sjeff                        if (!cl_list_count(&tmp_parser_struct.num_pair_list))
702219820Sjeff                        {
703219820Sjeff                            yyerror("ULP rule doesn't have port guids");
704219820Sjeff                            return 1;
705219820Sjeff                        }
706219820Sjeff
707219820Sjeff                        /* create a new port group with these ports */
708219820Sjeff                        __parser_port_group_start();
709219820Sjeff
710219820Sjeff                        p_current_port_group->name = strdup("_ULP_Targets_");
711219820Sjeff                        p_current_port_group->use = strdup("Generated from ULP rules");
712219820Sjeff
713219820Sjeff                        __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
714219820Sjeff                                              &range_arr,
715219820Sjeff                                              &range_len );
716219820Sjeff
717219820Sjeff                        __parser_add_guid_range_to_port_map(
718219820Sjeff                                              &p_current_port_group->port_map,
719219820Sjeff                                              range_arr,
720219820Sjeff                                              range_len);
721219820Sjeff
722219820Sjeff                        /* add this port group to the destination
723219820Sjeff                           groups of the current match rule */
724219820Sjeff                        cl_list_insert_tail(&p_current_qos_match_rule->destination_group_list,
725219820Sjeff                                            p_current_port_group);
726219820Sjeff
727219820Sjeff                        __parser_port_group_end();
728219820Sjeff
729219820Sjeff                    } qos_ulp_sl
730219820Sjeff
731219820Sjeff                    | qos_ulp_type_sdp_default {
732219820Sjeff                        /* "sdp : sl" - default SL for SDP */
733219820Sjeff                        uint64_t ** range_arr =
734219820Sjeff                               (uint64_t **)malloc(sizeof(uint64_t *));
735219820Sjeff                        range_arr[0] = (uint64_t *)malloc(2*sizeof(uint64_t));
736219820Sjeff                        range_arr[0][0] = OSM_QOS_POLICY_ULP_SDP_SERVICE_ID;
737219820Sjeff                        range_arr[0][1] = OSM_QOS_POLICY_ULP_SDP_SERVICE_ID + 0xFFFF;
738219820Sjeff
739219820Sjeff                        p_current_qos_match_rule->service_id_range_arr = range_arr;
740219820Sjeff                        p_current_qos_match_rule->service_id_range_len = 1;
741219820Sjeff
742219820Sjeff                    } qos_ulp_sl
743219820Sjeff
744219820Sjeff                    | qos_ulp_type_sdp_port list_of_ranges TK_DOTDOT {
745219820Sjeff                        /* sdp with port numbers */
746219820Sjeff                        uint64_t ** range_arr;
747219820Sjeff                        unsigned    range_len;
748219820Sjeff                        unsigned    i;
749219820Sjeff
750219820Sjeff                        if (!cl_list_count(&tmp_parser_struct.num_pair_list))
751219820Sjeff                        {
752219820Sjeff                            yyerror("SDP ULP rule doesn't have port numbers");
753219820Sjeff                            return 1;
754219820Sjeff                        }
755219820Sjeff
756219820Sjeff                        /* get all the port ranges */
757219820Sjeff                        __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
758219820Sjeff                                              &range_arr,
759219820Sjeff                                              &range_len );
760219820Sjeff                        /* now translate these port numbers into service ids */
761219820Sjeff                        for (i = 0; i < range_len; i++)
762219820Sjeff                        {
763219820Sjeff                            if (range_arr[i][0] > 0xFFFF || range_arr[i][1] > 0xFFFF)
764219820Sjeff                            {
765219820Sjeff                                yyerror("SDP port number out of range");
766219820Sjeff                                return 1;
767219820Sjeff                            }
768219820Sjeff                            range_arr[i][0] += OSM_QOS_POLICY_ULP_SDP_SERVICE_ID;
769219820Sjeff                            range_arr[i][1] += OSM_QOS_POLICY_ULP_SDP_SERVICE_ID;
770219820Sjeff                        }
771219820Sjeff
772219820Sjeff                        p_current_qos_match_rule->service_id_range_arr = range_arr;
773219820Sjeff                        p_current_qos_match_rule->service_id_range_len = range_len;
774219820Sjeff
775219820Sjeff                    } qos_ulp_sl
776219820Sjeff
777219820Sjeff                    | qos_ulp_type_rds_default {
778219820Sjeff                        /* "rds : sl" - default SL for RDS */
779219820Sjeff                        uint64_t ** range_arr =
780219820Sjeff                               (uint64_t **)malloc(sizeof(uint64_t *));
781219820Sjeff                        range_arr[0] = (uint64_t *)malloc(2*sizeof(uint64_t));
782219820Sjeff                        range_arr[0][0] = range_arr[0][1] =
783219820Sjeff                           OSM_QOS_POLICY_ULP_RDS_SERVICE_ID + OSM_QOS_POLICY_ULP_RDS_PORT;
784219820Sjeff
785219820Sjeff                        p_current_qos_match_rule->service_id_range_arr = range_arr;
786219820Sjeff                        p_current_qos_match_rule->service_id_range_len = 1;
787219820Sjeff
788219820Sjeff                    } qos_ulp_sl
789219820Sjeff
790219820Sjeff                    | qos_ulp_type_rds_port list_of_ranges TK_DOTDOT {
791219820Sjeff                        /* rds with port numbers */
792219820Sjeff                        uint64_t ** range_arr;
793219820Sjeff                        unsigned    range_len;
794219820Sjeff                        unsigned    i;
795219820Sjeff
796219820Sjeff                        if (!cl_list_count(&tmp_parser_struct.num_pair_list))
797219820Sjeff                        {
798219820Sjeff                            yyerror("RDS ULP rule doesn't have port numbers");
799219820Sjeff                            return 1;
800219820Sjeff                        }
801219820Sjeff
802219820Sjeff                        /* get all the port ranges */
803219820Sjeff                        __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
804219820Sjeff                                              &range_arr,
805219820Sjeff                                              &range_len );
806219820Sjeff                        /* now translate these port numbers into service ids */
807219820Sjeff                        for (i = 0; i < range_len; i++)
808219820Sjeff                        {
809219820Sjeff                            if (range_arr[i][0] > 0xFFFF || range_arr[i][1] > 0xFFFF)
810219820Sjeff                            {
811219820Sjeff                                yyerror("SDP port number out of range");
812219820Sjeff                                return 1;
813219820Sjeff                            }
814219820Sjeff                            range_arr[i][0] += OSM_QOS_POLICY_ULP_RDS_SERVICE_ID;
815219820Sjeff                            range_arr[i][1] += OSM_QOS_POLICY_ULP_RDS_SERVICE_ID;
816219820Sjeff                        }
817219820Sjeff
818219820Sjeff                        p_current_qos_match_rule->service_id_range_arr = range_arr;
819219820Sjeff                        p_current_qos_match_rule->service_id_range_len = range_len;
820219820Sjeff
821219820Sjeff                    } qos_ulp_sl
822219820Sjeff
823219820Sjeff                    | qos_ulp_type_iser_default {
824219820Sjeff                        /* "iSER : sl" - default SL for iSER */
825219820Sjeff                        uint64_t ** range_arr =
826219820Sjeff                               (uint64_t **)malloc(sizeof(uint64_t *));
827219820Sjeff                        range_arr[0] = (uint64_t *)malloc(2*sizeof(uint64_t));
828219820Sjeff                        range_arr[0][0] = range_arr[0][1] =
829219820Sjeff                           OSM_QOS_POLICY_ULP_ISER_SERVICE_ID + OSM_QOS_POLICY_ULP_ISER_PORT;
830219820Sjeff
831219820Sjeff                        p_current_qos_match_rule->service_id_range_arr = range_arr;
832219820Sjeff                        p_current_qos_match_rule->service_id_range_len = 1;
833219820Sjeff
834219820Sjeff                    } qos_ulp_sl
835219820Sjeff
836219820Sjeff                    | qos_ulp_type_iser_port list_of_ranges TK_DOTDOT {
837219820Sjeff                        /* iser with port numbers */
838219820Sjeff                        uint64_t ** range_arr;
839219820Sjeff                        unsigned    range_len;
840219820Sjeff                        unsigned    i;
841219820Sjeff
842219820Sjeff                        if (!cl_list_count(&tmp_parser_struct.num_pair_list))
843219820Sjeff                        {
844219820Sjeff                            yyerror("iSER ULP rule doesn't have port numbers");
845219820Sjeff                            return 1;
846219820Sjeff                        }
847219820Sjeff
848219820Sjeff                        /* get all the port ranges */
849219820Sjeff                        __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
850219820Sjeff                                              &range_arr,
851219820Sjeff                                              &range_len );
852219820Sjeff                        /* now translate these port numbers into service ids */
853219820Sjeff                        for (i = 0; i < range_len; i++)
854219820Sjeff                        {
855219820Sjeff                            if (range_arr[i][0] > 0xFFFF || range_arr[i][1] > 0xFFFF)
856219820Sjeff                            {
857219820Sjeff                                yyerror("SDP port number out of range");
858219820Sjeff                                return 1;
859219820Sjeff                            }
860219820Sjeff                            range_arr[i][0] += OSM_QOS_POLICY_ULP_ISER_SERVICE_ID;
861219820Sjeff                            range_arr[i][1] += OSM_QOS_POLICY_ULP_ISER_SERVICE_ID;
862219820Sjeff                        }
863219820Sjeff
864219820Sjeff                        p_current_qos_match_rule->service_id_range_arr = range_arr;
865219820Sjeff                        p_current_qos_match_rule->service_id_range_len = range_len;
866219820Sjeff
867219820Sjeff                    } qos_ulp_sl
868219820Sjeff
869219820Sjeff                    | qos_ulp_type_srp_guid list_of_ranges TK_DOTDOT {
870219820Sjeff                        /* srp with target guids - this rule is similar
871219820Sjeff                           to writing 'any' ulp with target port guids */
872219820Sjeff                        uint64_t ** range_arr;
873219820Sjeff                        unsigned    range_len;
874219820Sjeff
875219820Sjeff                        if (!cl_list_count(&tmp_parser_struct.num_pair_list))
876219820Sjeff                        {
877219820Sjeff                            yyerror("SRP ULP rule doesn't have port guids");
878219820Sjeff                            return 1;
879219820Sjeff                        }
880219820Sjeff
881219820Sjeff                        /* create a new port group with these ports */
882219820Sjeff                        __parser_port_group_start();
883219820Sjeff
884219820Sjeff                        p_current_port_group->name = strdup("_SRP_Targets_");
885219820Sjeff                        p_current_port_group->use = strdup("Generated from ULP rules");
886219820Sjeff
887219820Sjeff                        __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
888219820Sjeff                                              &range_arr,
889219820Sjeff                                              &range_len );
890219820Sjeff
891219820Sjeff                        __parser_add_guid_range_to_port_map(
892219820Sjeff                                              &p_current_port_group->port_map,
893219820Sjeff                                              range_arr,
894219820Sjeff                                              range_len);
895219820Sjeff
896219820Sjeff                        /* add this port group to the destination
897219820Sjeff                           groups of the current match rule */
898219820Sjeff                        cl_list_insert_tail(&p_current_qos_match_rule->destination_group_list,
899219820Sjeff                                            p_current_port_group);
900219820Sjeff
901219820Sjeff                        __parser_port_group_end();
902219820Sjeff
903219820Sjeff                    } qos_ulp_sl
904219820Sjeff
905219820Sjeff                    | qos_ulp_type_ipoib_default {
906219820Sjeff                        /* ipoib w/o any pkeys (default pkey) */
907219820Sjeff                        uint64_t ** range_arr =
908219820Sjeff                               (uint64_t **)malloc(sizeof(uint64_t *));
909219820Sjeff                        range_arr[0] = (uint64_t *)malloc(2*sizeof(uint64_t));
910219820Sjeff                        range_arr[0][0] = range_arr[0][1] = 0x7fff;
911219820Sjeff
912219820Sjeff                        /*
913219820Sjeff                         * Although we know that the default partition exists,
914219820Sjeff                         * we still need to validate it by checking that it has
915219820Sjeff                         * at least two full members. Otherwise IPoIB won't work.
916219820Sjeff                         */
917219820Sjeff                        if (__validate_pkeys(range_arr, 1, TRUE))
918219820Sjeff                            return 1;
919219820Sjeff
920219820Sjeff                        p_current_qos_match_rule->pkey_range_arr = range_arr;
921219820Sjeff                        p_current_qos_match_rule->pkey_range_len = 1;
922219820Sjeff
923219820Sjeff                    } qos_ulp_sl
924219820Sjeff
925219820Sjeff                    | qos_ulp_type_ipoib_pkey list_of_ranges TK_DOTDOT {
926219820Sjeff                        /* ipoib with pkeys */
927219820Sjeff                        uint64_t ** range_arr;
928219820Sjeff                        unsigned    range_len;
929219820Sjeff
930219820Sjeff                        if (!cl_list_count(&tmp_parser_struct.num_pair_list))
931219820Sjeff                        {
932219820Sjeff                            yyerror("IPoIB ULP rule doesn't have pkeys");
933219820Sjeff                            return 1;
934219820Sjeff                        }
935219820Sjeff
936219820Sjeff                        /* get all the pkey ranges */
937219820Sjeff                        __pkey_rangelist2rangearr( &tmp_parser_struct.num_pair_list,
938219820Sjeff                                              &range_arr,
939219820Sjeff                                              &range_len );
940219820Sjeff
941219820Sjeff                        /*
942219820Sjeff                         * Validate pkeys.
943219820Sjeff                         * For IPoIB pkeys the validation is strict.
944219820Sjeff                         * If some problem would be found, parsing will
945219820Sjeff                         * be aborted with a proper error messages.
946219820Sjeff                         */
947219820Sjeff                        if (__validate_pkeys(range_arr, range_len, TRUE))
948219820Sjeff                            return 1;
949219820Sjeff
950219820Sjeff                        p_current_qos_match_rule->pkey_range_arr = range_arr;
951219820Sjeff                        p_current_qos_match_rule->pkey_range_len = range_len;
952219820Sjeff
953219820Sjeff                    } qos_ulp_sl
954219820Sjeff                    ;
955219820Sjeff
956219820Sjeffqos_ulp_type_any_service: TK_ULP_ANY_SERVICE_ID
957219820Sjeff                    { __parser_ulp_match_rule_start(); };
958219820Sjeff
959219820Sjeffqos_ulp_type_any_pkey: TK_ULP_ANY_PKEY
960219820Sjeff                    { __parser_ulp_match_rule_start(); };
961219820Sjeff
962219820Sjeffqos_ulp_type_any_target_port_guid: TK_ULP_ANY_TARGET_PORT_GUID
963219820Sjeff                    { __parser_ulp_match_rule_start(); };
964219820Sjeff
965219820Sjeffqos_ulp_type_sdp_default: TK_ULP_SDP_DEFAULT
966219820Sjeff                    { __parser_ulp_match_rule_start(); };
967219820Sjeff
968219820Sjeffqos_ulp_type_sdp_port: TK_ULP_SDP_PORT
969219820Sjeff                    { __parser_ulp_match_rule_start(); };
970219820Sjeff
971219820Sjeffqos_ulp_type_rds_default: TK_ULP_RDS_DEFAULT
972219820Sjeff                    { __parser_ulp_match_rule_start(); };
973219820Sjeff
974219820Sjeffqos_ulp_type_rds_port: TK_ULP_RDS_PORT
975219820Sjeff                    { __parser_ulp_match_rule_start(); };
976219820Sjeff
977219820Sjeffqos_ulp_type_iser_default: TK_ULP_ISER_DEFAULT
978219820Sjeff                    { __parser_ulp_match_rule_start(); };
979219820Sjeff
980219820Sjeffqos_ulp_type_iser_port: TK_ULP_ISER_PORT
981219820Sjeff                    { __parser_ulp_match_rule_start(); };
982219820Sjeff
983219820Sjeffqos_ulp_type_srp_guid: TK_ULP_SRP_GUID
984219820Sjeff                    { __parser_ulp_match_rule_start(); };
985219820Sjeff
986219820Sjeffqos_ulp_type_ipoib_default: TK_ULP_IPOIB_DEFAULT
987219820Sjeff                    { __parser_ulp_match_rule_start(); };
988219820Sjeff
989219820Sjeffqos_ulp_type_ipoib_pkey: TK_ULP_IPOIB_PKEY
990219820Sjeff                    { __parser_ulp_match_rule_start(); };
991219820Sjeff
992219820Sjeff
993219820Sjeffqos_ulp_sl:   single_number {
994219820Sjeff                        /* get the SL for ULP rules */
995219820Sjeff                        cl_list_iterator_t  list_iterator;
996219820Sjeff                        uint64_t          * p_tmp_num;
997219820Sjeff                        uint8_t             sl;
998219820Sjeff
999219820Sjeff                        list_iterator = cl_list_head(&tmp_parser_struct.num_list);
1000219820Sjeff                        p_tmp_num = (uint64_t*)cl_list_obj(list_iterator);
1001219820Sjeff                        if (*p_tmp_num > 15)
1002219820Sjeff                        {
1003219820Sjeff                            yyerror("illegal SL value");
1004219820Sjeff                            return 1;
1005219820Sjeff                        }
1006219820Sjeff
1007219820Sjeff                        sl = (uint8_t)(*p_tmp_num);
1008219820Sjeff                        free(p_tmp_num);
1009219820Sjeff                        cl_list_remove_all(&tmp_parser_struct.num_list);
1010219820Sjeff
1011219820Sjeff                        p_current_qos_match_rule->p_qos_level =
1012219820Sjeff                                 &osm_qos_policy_simple_qos_levels[sl];
1013219820Sjeff                        p_current_qos_match_rule->qos_level_name =
1014219820Sjeff                                 strdup(osm_qos_policy_simple_qos_levels[sl].name);
1015219820Sjeff
1016219820Sjeff                        if (__parser_ulp_match_rule_end())
1017219820Sjeff                            return 1;
1018219820Sjeff                    }
1019219820Sjeff                    ;
1020219820Sjeff
1021219820Sjeff    /*
1022219820Sjeff     *  port_group_entry values:
1023219820Sjeff     *      port_group_name
1024219820Sjeff     *      port_group_use
1025219820Sjeff     *      port_group_port_guid
1026219820Sjeff     *      port_group_port_name
1027219820Sjeff     *      port_group_pkey
1028219820Sjeff     *      port_group_partition
1029219820Sjeff     *      port_group_node_type
1030219820Sjeff     */
1031219820Sjeff
1032219820Sjeffport_group_name:        port_group_name_start single_string {
1033219820Sjeff                            /* 'name' of 'port-group' - one instance */
1034219820Sjeff                            cl_list_iterator_t    list_iterator;
1035219820Sjeff                            char                * tmp_str;
1036219820Sjeff
1037219820Sjeff                            if (p_current_port_group->name)
1038219820Sjeff                            {
1039219820Sjeff                                yyerror("port-group has multiple 'name' tags");
1040219820Sjeff                                cl_list_remove_all(&tmp_parser_struct.str_list);
1041219820Sjeff                                return 1;
1042219820Sjeff                            }
1043219820Sjeff
1044219820Sjeff                            list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1045219820Sjeff                            if ( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1046219820Sjeff                            {
1047219820Sjeff                                tmp_str = (char*)cl_list_obj(list_iterator);
1048219820Sjeff                                if (tmp_str)
1049219820Sjeff                                    p_current_port_group->name = tmp_str;
1050219820Sjeff                            }
1051219820Sjeff                            cl_list_remove_all(&tmp_parser_struct.str_list);
1052219820Sjeff                        }
1053219820Sjeff                        ;
1054219820Sjeff
1055219820Sjeffport_group_name_start:  TK_NAME {
1056219820Sjeff                            RESET_BUFFER;
1057219820Sjeff                        }
1058219820Sjeff                        ;
1059219820Sjeff
1060219820Sjeffport_group_use:         port_group_use_start single_string {
1061219820Sjeff                            /* 'use' of 'port-group' - one instance */
1062219820Sjeff                            cl_list_iterator_t    list_iterator;
1063219820Sjeff                            char                * tmp_str;
1064219820Sjeff
1065219820Sjeff                            if (p_current_port_group->use)
1066219820Sjeff                            {
1067219820Sjeff                                yyerror("port-group has multiple 'use' tags");
1068219820Sjeff                                cl_list_remove_all(&tmp_parser_struct.str_list);
1069219820Sjeff                                return 1;
1070219820Sjeff                            }
1071219820Sjeff
1072219820Sjeff                            list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1073219820Sjeff                            if ( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1074219820Sjeff                            {
1075219820Sjeff                                tmp_str = (char*)cl_list_obj(list_iterator);
1076219820Sjeff                                if (tmp_str)
1077219820Sjeff                                    p_current_port_group->use = tmp_str;
1078219820Sjeff                            }
1079219820Sjeff                            cl_list_remove_all(&tmp_parser_struct.str_list);
1080219820Sjeff                        }
1081219820Sjeff                        ;
1082219820Sjeff
1083219820Sjeffport_group_use_start:   TK_USE {
1084219820Sjeff                            RESET_BUFFER;
1085219820Sjeff                        }
1086219820Sjeff                        ;
1087219820Sjeff
1088219820Sjeffport_group_port_name:   port_group_port_name_start string_list {
1089219820Sjeff                            /* 'port-name' in 'port-group' - any num of instances */
1090219820Sjeff                            cl_list_iterator_t list_iterator;
1091219820Sjeff                            osm_node_t * p_node;
1092219820Sjeff                            osm_physp_t * p_physp;
1093219820Sjeff                            unsigned port_num;
1094219820Sjeff                            char * tmp_str;
1095219820Sjeff                            char * port_str;
1096219820Sjeff
1097219820Sjeff                            /* parsing port name strings */
1098219820Sjeff                            for (list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1099219820Sjeff                                 list_iterator != cl_list_end(&tmp_parser_struct.str_list);
1100219820Sjeff                                 list_iterator = cl_list_next(list_iterator))
1101219820Sjeff                            {
1102219820Sjeff                                tmp_str = (char*)cl_list_obj(list_iterator);
1103219820Sjeff                                if (tmp_str)
1104219820Sjeff                                {
1105219820Sjeff                                    /* last slash in port name string is a separator
1106219820Sjeff                                       between node name and port number */
1107219820Sjeff                                    port_str = strrchr(tmp_str, '/');
1108219820Sjeff                                    if (!port_str || (strlen(port_str) < 3) ||
1109219820Sjeff                                        (port_str[1] != 'p' && port_str[1] != 'P')) {
1110219820Sjeff                                        yyerror("'%s' - illegal port name",
1111219820Sjeff                                                           tmp_str);
1112219820Sjeff                                        free(tmp_str);
1113219820Sjeff                                        cl_list_remove_all(&tmp_parser_struct.str_list);
1114219820Sjeff                                        return 1;
1115219820Sjeff                                    }
1116219820Sjeff
1117219820Sjeff                                    if (!(port_num = strtoul(&port_str[2],NULL,0))) {
1118219820Sjeff                                        yyerror(
1119219820Sjeff                                               "'%s' - illegal port number in port name",
1120219820Sjeff                                               tmp_str);
1121219820Sjeff                                        free(tmp_str);
1122219820Sjeff                                        cl_list_remove_all(&tmp_parser_struct.str_list);
1123219820Sjeff                                        return 1;
1124219820Sjeff                                    }
1125219820Sjeff
1126219820Sjeff                                    /* separate node name from port number */
1127219820Sjeff                                    port_str[0] = '\0';
1128219820Sjeff
1129219820Sjeff                                    if (st_lookup(p_qos_policy->p_node_hash,
1130219820Sjeff                                                  (st_data_t)tmp_str,
1131219820Sjeff                                                  (void *)&p_node))
1132219820Sjeff                                    {
1133219820Sjeff                                        /* we found the node, now get the right port */
1134219820Sjeff                                        p_physp = osm_node_get_physp_ptr(p_node, port_num);
1135219820Sjeff                                        if (!p_physp) {
1136219820Sjeff                                            yyerror(
1137219820Sjeff                                                   "'%s' - port number out of range in port name",
1138219820Sjeff                                                   tmp_str);
1139219820Sjeff                                            free(tmp_str);
1140219820Sjeff                                            cl_list_remove_all(&tmp_parser_struct.str_list);
1141219820Sjeff                                            return 1;
1142219820Sjeff                                        }
1143219820Sjeff                                        /* we found the port, now add it to guid table */
1144219820Sjeff                                        __parser_add_port_to_port_map(&p_current_port_group->port_map,
1145219820Sjeff                                                                      p_physp);
1146219820Sjeff                                    }
1147219820Sjeff                                    free(tmp_str);
1148219820Sjeff                                }
1149219820Sjeff                            }
1150219820Sjeff                            cl_list_remove_all(&tmp_parser_struct.str_list);
1151219820Sjeff                        }
1152219820Sjeff                        ;
1153219820Sjeff
1154219820Sjeffport_group_port_name_start: TK_PORT_NAME {
1155219820Sjeff                            RESET_BUFFER;
1156219820Sjeff                        }
1157219820Sjeff                        ;
1158219820Sjeff
1159219820Sjeffport_group_port_guid:   port_group_port_guid_start list_of_ranges {
1160219820Sjeff                            /* 'port-guid' in 'port-group' - any num of instances */
1161219820Sjeff                            /* list of guid ranges */
1162219820Sjeff                            if (cl_list_count(&tmp_parser_struct.num_pair_list))
1163219820Sjeff                            {
1164219820Sjeff                                uint64_t ** range_arr;
1165219820Sjeff                                unsigned range_len;
1166219820Sjeff
1167219820Sjeff                                __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
1168219820Sjeff                                                      &range_arr,
1169219820Sjeff                                                      &range_len );
1170219820Sjeff
1171219820Sjeff                                __parser_add_guid_range_to_port_map(
1172219820Sjeff                                                      &p_current_port_group->port_map,
1173219820Sjeff                                                      range_arr,
1174219820Sjeff                                                      range_len);
1175219820Sjeff                            }
1176219820Sjeff                        }
1177219820Sjeff                        ;
1178219820Sjeff
1179219820Sjeffport_group_port_guid_start: TK_PORT_GUID {
1180219820Sjeff                            RESET_BUFFER;
1181219820Sjeff                        }
1182219820Sjeff                        ;
1183219820Sjeff
1184219820Sjeffport_group_pkey:        port_group_pkey_start list_of_ranges {
1185219820Sjeff                            /* 'pkey' in 'port-group' - any num of instances */
1186219820Sjeff                            /* list of pkey ranges */
1187219820Sjeff                            if (cl_list_count(&tmp_parser_struct.num_pair_list))
1188219820Sjeff                            {
1189219820Sjeff                                uint64_t ** range_arr;
1190219820Sjeff                                unsigned range_len;
1191219820Sjeff
1192219820Sjeff                                __pkey_rangelist2rangearr( &tmp_parser_struct.num_pair_list,
1193219820Sjeff                                                      &range_arr,
1194219820Sjeff                                                      &range_len );
1195219820Sjeff
1196219820Sjeff                                __parser_add_pkey_range_to_port_map(
1197219820Sjeff                                                      &p_current_port_group->port_map,
1198219820Sjeff                                                      range_arr,
1199219820Sjeff                                                      range_len);
1200219820Sjeff                            }
1201219820Sjeff                        }
1202219820Sjeff                        ;
1203219820Sjeff
1204219820Sjeffport_group_pkey_start:  TK_PKEY {
1205219820Sjeff                            RESET_BUFFER;
1206219820Sjeff                        }
1207219820Sjeff                        ;
1208219820Sjeff
1209219820Sjeffport_group_partition:  port_group_partition_start string_list {
1210219820Sjeff                            /* 'partition' in 'port-group' - any num of instances */
1211219820Sjeff                            __parser_add_partition_list_to_port_map(
1212219820Sjeff                                               &p_current_port_group->port_map,
1213219820Sjeff                                               &tmp_parser_struct.str_list);
1214219820Sjeff                        }
1215219820Sjeff                        ;
1216219820Sjeff
1217219820Sjeffport_group_partition_start: TK_PARTITION {
1218219820Sjeff                            RESET_BUFFER;
1219219820Sjeff                        }
1220219820Sjeff                        ;
1221219820Sjeff
1222219820Sjeffport_group_node_type:   port_group_node_type_start port_group_node_type_list {
1223219820Sjeff                            /* 'node-type' in 'port-group' - any num of instances */
1224219820Sjeff                        }
1225219820Sjeff                        ;
1226219820Sjeff
1227219820Sjeffport_group_node_type_start: TK_NODE_TYPE {
1228219820Sjeff                            RESET_BUFFER;
1229219820Sjeff                        }
1230219820Sjeff                        ;
1231219820Sjeff
1232219820Sjeffport_group_node_type_list:  node_type_item
1233219820Sjeff                        |   port_group_node_type_list TK_COMMA node_type_item
1234219820Sjeff                        ;
1235219820Sjeff
1236219820Sjeffnode_type_item:           node_type_ca
1237219820Sjeff                        | node_type_switch
1238219820Sjeff                        | node_type_router
1239219820Sjeff                        | node_type_all
1240219820Sjeff                        | node_type_self
1241219820Sjeff                        ;
1242219820Sjeff
1243219820Sjeffnode_type_ca:           TK_NODE_TYPE_CA {
1244219820Sjeff                            p_current_port_group->node_types |=
1245219820Sjeff                               OSM_QOS_POLICY_NODE_TYPE_CA;
1246219820Sjeff                        }
1247219820Sjeff                        ;
1248219820Sjeff
1249219820Sjeffnode_type_switch:       TK_NODE_TYPE_SWITCH {
1250219820Sjeff                            p_current_port_group->node_types |=
1251219820Sjeff                               OSM_QOS_POLICY_NODE_TYPE_SWITCH;
1252219820Sjeff                        }
1253219820Sjeff                        ;
1254219820Sjeff
1255219820Sjeffnode_type_router:       TK_NODE_TYPE_ROUTER {
1256219820Sjeff                            p_current_port_group->node_types |=
1257219820Sjeff                               OSM_QOS_POLICY_NODE_TYPE_ROUTER;
1258219820Sjeff                        }
1259219820Sjeff                        ;
1260219820Sjeff
1261219820Sjeffnode_type_all:          TK_NODE_TYPE_ALL {
1262219820Sjeff                            p_current_port_group->node_types |=
1263219820Sjeff                               (OSM_QOS_POLICY_NODE_TYPE_CA |
1264219820Sjeff                                OSM_QOS_POLICY_NODE_TYPE_SWITCH |
1265219820Sjeff                                OSM_QOS_POLICY_NODE_TYPE_ROUTER);
1266219820Sjeff                        }
1267219820Sjeff                        ;
1268219820Sjeff
1269219820Sjeffnode_type_self:         TK_NODE_TYPE_SELF {
1270219820Sjeff                            osm_port_t * p_osm_port =
1271219820Sjeff                                osm_get_port_by_guid(p_qos_policy->p_subn,
1272219820Sjeff                                     p_qos_policy->p_subn->sm_port_guid);
1273219820Sjeff                            if (p_osm_port)
1274219820Sjeff                                __parser_add_port_to_port_map(
1275219820Sjeff                                   &p_current_port_group->port_map,
1276219820Sjeff                                   p_osm_port->p_physp);
1277219820Sjeff                        }
1278219820Sjeff                        ;
1279219820Sjeff
1280219820Sjeff    /*
1281219820Sjeff     *  vlarb_scope_entry values:
1282219820Sjeff     *      vlarb_scope_group
1283219820Sjeff     *      vlarb_scope_across
1284219820Sjeff     *      vlarb_scope_vlarb_high
1285219820Sjeff     *      vlarb_scope_vlarb_low
1286219820Sjeff     *      vlarb_scope_vlarb_high_limit
1287219820Sjeff     */
1288219820Sjeff
1289219820Sjeff
1290219820Sjeff
1291219820Sjeffvlarb_scope_group:      vlarb_scope_group_start string_list {
1292219820Sjeff                            /* 'group' in 'vlarb-scope' - any num of instances */
1293219820Sjeff                            cl_list_iterator_t    list_iterator;
1294219820Sjeff                            char                * tmp_str;
1295219820Sjeff
1296219820Sjeff                            list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1297219820Sjeff                            while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1298219820Sjeff                            {
1299219820Sjeff                                tmp_str = (char*)cl_list_obj(list_iterator);
1300219820Sjeff                                if (tmp_str)
1301219820Sjeff                                    cl_list_insert_tail(&p_current_vlarb_scope->group_list,tmp_str);
1302219820Sjeff                                list_iterator = cl_list_next(list_iterator);
1303219820Sjeff                            }
1304219820Sjeff                            cl_list_remove_all(&tmp_parser_struct.str_list);
1305219820Sjeff                        }
1306219820Sjeff                        ;
1307219820Sjeff
1308219820Sjeffvlarb_scope_group_start: TK_GROUP {
1309219820Sjeff                            RESET_BUFFER;
1310219820Sjeff                        }
1311219820Sjeff                        ;
1312219820Sjeff
1313219820Sjeffvlarb_scope_across: vlarb_scope_across_start string_list {
1314219820Sjeff                            /* 'across' in 'vlarb-scope' - any num of instances */
1315219820Sjeff                            cl_list_iterator_t    list_iterator;
1316219820Sjeff                            char                * tmp_str;
1317219820Sjeff
1318219820Sjeff                            list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1319219820Sjeff                            while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1320219820Sjeff                            {
1321219820Sjeff                                tmp_str = (char*)cl_list_obj(list_iterator);
1322219820Sjeff                                if (tmp_str)
1323219820Sjeff                                    cl_list_insert_tail(&p_current_vlarb_scope->across_list,tmp_str);
1324219820Sjeff                                list_iterator = cl_list_next(list_iterator);
1325219820Sjeff                            }
1326219820Sjeff                            cl_list_remove_all(&tmp_parser_struct.str_list);
1327219820Sjeff                        }
1328219820Sjeff                        ;
1329219820Sjeff
1330219820Sjeffvlarb_scope_across_start: TK_ACROSS {
1331219820Sjeff                            RESET_BUFFER;
1332219820Sjeff                        }
1333219820Sjeff                        ;
1334219820Sjeff
1335219820Sjeffvlarb_scope_vlarb_high_limit:  vlarb_scope_vlarb_high_limit_start single_number {
1336219820Sjeff                            /* 'vl-high-limit' in 'vlarb-scope' - one instance of one number */
1337219820Sjeff                            cl_list_iterator_t    list_iterator;
1338219820Sjeff                            uint64_t            * p_tmp_num;
1339219820Sjeff
1340219820Sjeff                            list_iterator = cl_list_head(&tmp_parser_struct.num_list);
1341219820Sjeff                            p_tmp_num = (uint64_t*)cl_list_obj(list_iterator);
1342219820Sjeff                            if (p_tmp_num)
1343219820Sjeff                            {
1344219820Sjeff                                p_current_vlarb_scope->vl_high_limit = (uint32_t)(*p_tmp_num);
1345219820Sjeff                                p_current_vlarb_scope->vl_high_limit_set = TRUE;
1346219820Sjeff                                free(p_tmp_num);
1347219820Sjeff                            }
1348219820Sjeff
1349219820Sjeff                            cl_list_remove_all(&tmp_parser_struct.num_list);
1350219820Sjeff                        }
1351219820Sjeff                        ;
1352219820Sjeff
1353219820Sjeffvlarb_scope_vlarb_high_limit_start: TK_VLARB_HIGH_LIMIT {
1354219820Sjeff                            RESET_BUFFER;
1355219820Sjeff                        }
1356219820Sjeff                        ;
1357219820Sjeff
1358219820Sjeffvlarb_scope_vlarb_high: vlarb_scope_vlarb_high_start num_list_with_dotdot {
1359219820Sjeff                            /* 'vlarb-high' in 'vlarb-scope' - list of pairs of numbers with ':' and ',' */
1360219820Sjeff                            cl_list_iterator_t    list_iterator;
1361219820Sjeff                            uint64_t            * num_pair;
1362219820Sjeff
1363219820Sjeff                            list_iterator = cl_list_head(&tmp_parser_struct.num_pair_list);
1364219820Sjeff                            while( list_iterator != cl_list_end(&tmp_parser_struct.num_pair_list) )
1365219820Sjeff                            {
1366219820Sjeff                                num_pair = (uint64_t*)cl_list_obj(list_iterator);
1367219820Sjeff                                if (num_pair)
1368219820Sjeff                                    cl_list_insert_tail(&p_current_vlarb_scope->vlarb_high_list,num_pair);
1369219820Sjeff                                list_iterator = cl_list_next(list_iterator);
1370219820Sjeff                            }
1371219820Sjeff                            cl_list_remove_all(&tmp_parser_struct.num_pair_list);
1372219820Sjeff                        }
1373219820Sjeff                        ;
1374219820Sjeff
1375219820Sjeffvlarb_scope_vlarb_high_start: TK_VLARB_HIGH {
1376219820Sjeff                            RESET_BUFFER;
1377219820Sjeff                        }
1378219820Sjeff                        ;
1379219820Sjeff
1380219820Sjeffvlarb_scope_vlarb_low:  vlarb_scope_vlarb_low_start num_list_with_dotdot {
1381219820Sjeff                            /* 'vlarb-low' in 'vlarb-scope' - list of pairs of numbers with ':' and ',' */
1382219820Sjeff                            cl_list_iterator_t    list_iterator;
1383219820Sjeff                            uint64_t            * num_pair;
1384219820Sjeff
1385219820Sjeff                            list_iterator = cl_list_head(&tmp_parser_struct.num_pair_list);
1386219820Sjeff                            while( list_iterator != cl_list_end(&tmp_parser_struct.num_pair_list) )
1387219820Sjeff                            {
1388219820Sjeff                                num_pair = (uint64_t*)cl_list_obj(list_iterator);
1389219820Sjeff                                if (num_pair)
1390219820Sjeff                                    cl_list_insert_tail(&p_current_vlarb_scope->vlarb_low_list,num_pair);
1391219820Sjeff                                list_iterator = cl_list_next(list_iterator);
1392219820Sjeff                            }
1393219820Sjeff                            cl_list_remove_all(&tmp_parser_struct.num_pair_list);
1394219820Sjeff                        }
1395219820Sjeff                        ;
1396219820Sjeff
1397219820Sjeffvlarb_scope_vlarb_low_start: TK_VLARB_LOW {
1398219820Sjeff                            RESET_BUFFER;
1399219820Sjeff                        }
1400219820Sjeff                        ;
1401219820Sjeff
1402219820Sjeff    /*
1403219820Sjeff     *  sl2vl_scope_entry values:
1404219820Sjeff     *      sl2vl_scope_group
1405219820Sjeff     *      sl2vl_scope_across
1406219820Sjeff     *      sl2vl_scope_across_from
1407219820Sjeff     *      sl2vl_scope_across_to
1408219820Sjeff     *      sl2vl_scope_from
1409219820Sjeff     *      sl2vl_scope_to
1410219820Sjeff     *      sl2vl_scope_sl2vl_table
1411219820Sjeff     */
1412219820Sjeff
1413219820Sjeffsl2vl_scope_group:      sl2vl_scope_group_start string_list {
1414219820Sjeff                            /* 'group' in 'sl2vl-scope' - any num of instances */
1415219820Sjeff                            cl_list_iterator_t    list_iterator;
1416219820Sjeff                            char                * tmp_str;
1417219820Sjeff
1418219820Sjeff                            list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1419219820Sjeff                            while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1420219820Sjeff                            {
1421219820Sjeff                                tmp_str = (char*)cl_list_obj(list_iterator);
1422219820Sjeff                                if (tmp_str)
1423219820Sjeff                                    cl_list_insert_tail(&p_current_sl2vl_scope->group_list,tmp_str);
1424219820Sjeff                                list_iterator = cl_list_next(list_iterator);
1425219820Sjeff                            }
1426219820Sjeff                            cl_list_remove_all(&tmp_parser_struct.str_list);
1427219820Sjeff                        }
1428219820Sjeff                        ;
1429219820Sjeff
1430219820Sjeffsl2vl_scope_group_start: TK_GROUP {
1431219820Sjeff                            RESET_BUFFER;
1432219820Sjeff                        }
1433219820Sjeff                        ;
1434219820Sjeff
1435219820Sjeffsl2vl_scope_across:     sl2vl_scope_across_start string_list {
1436219820Sjeff                            /* 'across' in 'sl2vl-scope' - any num of instances */
1437219820Sjeff                            cl_list_iterator_t    list_iterator;
1438219820Sjeff                            char                * tmp_str;
1439219820Sjeff
1440219820Sjeff                            list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1441219820Sjeff                            while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1442219820Sjeff                            {
1443219820Sjeff                                tmp_str = (char*)cl_list_obj(list_iterator);
1444219820Sjeff                                if (tmp_str) {
1445219820Sjeff                                    cl_list_insert_tail(&p_current_sl2vl_scope->across_from_list,tmp_str);
1446219820Sjeff                                    cl_list_insert_tail(&p_current_sl2vl_scope->across_to_list,strdup(tmp_str));
1447219820Sjeff                                }
1448219820Sjeff                                list_iterator = cl_list_next(list_iterator);
1449219820Sjeff                            }
1450219820Sjeff                            cl_list_remove_all(&tmp_parser_struct.str_list);
1451219820Sjeff                        }
1452219820Sjeff                        ;
1453219820Sjeff
1454219820Sjeffsl2vl_scope_across_start: TK_ACROSS {
1455219820Sjeff                            RESET_BUFFER;
1456219820Sjeff                        }
1457219820Sjeff                        ;
1458219820Sjeff
1459219820Sjeffsl2vl_scope_across_from:  sl2vl_scope_across_from_start string_list {
1460219820Sjeff                            /* 'across-from' in 'sl2vl-scope' - any num of instances */
1461219820Sjeff                            cl_list_iterator_t    list_iterator;
1462219820Sjeff                            char                * tmp_str;
1463219820Sjeff
1464219820Sjeff                            list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1465219820Sjeff                            while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1466219820Sjeff                            {
1467219820Sjeff                                tmp_str = (char*)cl_list_obj(list_iterator);
1468219820Sjeff                                if (tmp_str)
1469219820Sjeff                                    cl_list_insert_tail(&p_current_sl2vl_scope->across_from_list,tmp_str);
1470219820Sjeff                                list_iterator = cl_list_next(list_iterator);
1471219820Sjeff                            }
1472219820Sjeff                            cl_list_remove_all(&tmp_parser_struct.str_list);
1473219820Sjeff                        }
1474219820Sjeff                        ;
1475219820Sjeff
1476219820Sjeffsl2vl_scope_across_from_start: TK_ACROSS_FROM {
1477219820Sjeff                            RESET_BUFFER;
1478219820Sjeff                        }
1479219820Sjeff                        ;
1480219820Sjeff
1481219820Sjeffsl2vl_scope_across_to:  sl2vl_scope_across_to_start string_list {
1482219820Sjeff                            /* 'across-to' in 'sl2vl-scope' - any num of instances */
1483219820Sjeff                            cl_list_iterator_t    list_iterator;
1484219820Sjeff                            char                * tmp_str;
1485219820Sjeff
1486219820Sjeff                            list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1487219820Sjeff                            while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1488219820Sjeff                            {
1489219820Sjeff                                tmp_str = (char*)cl_list_obj(list_iterator);
1490219820Sjeff                                if (tmp_str) {
1491219820Sjeff                                    cl_list_insert_tail(&p_current_sl2vl_scope->across_to_list,tmp_str);
1492219820Sjeff                                }
1493219820Sjeff                                list_iterator = cl_list_next(list_iterator);
1494219820Sjeff                            }
1495219820Sjeff                            cl_list_remove_all(&tmp_parser_struct.str_list);
1496219820Sjeff                        }
1497219820Sjeff                        ;
1498219820Sjeff
1499219820Sjeffsl2vl_scope_across_to_start: TK_ACROSS_TO {
1500219820Sjeff                            RESET_BUFFER;
1501219820Sjeff                        }
1502219820Sjeff                        ;
1503219820Sjeff
1504219820Sjeffsl2vl_scope_from:       sl2vl_scope_from_start sl2vl_scope_from_list_or_asterisk {
1505219820Sjeff                            /* 'from' in 'sl2vl-scope' - any num of instances */
1506219820Sjeff                        }
1507219820Sjeff                        ;
1508219820Sjeff
1509219820Sjeffsl2vl_scope_from_start: TK_FROM {
1510219820Sjeff                            RESET_BUFFER;
1511219820Sjeff                        }
1512219820Sjeff                        ;
1513219820Sjeff
1514219820Sjeffsl2vl_scope_to:         sl2vl_scope_to_start sl2vl_scope_to_list_or_asterisk {
1515219820Sjeff                            /* 'to' in 'sl2vl-scope' - any num of instances */
1516219820Sjeff                        }
1517219820Sjeff                        ;
1518219820Sjeff
1519219820Sjeffsl2vl_scope_to_start:   TK_TO {
1520219820Sjeff                            RESET_BUFFER;
1521219820Sjeff                        }
1522219820Sjeff                        ;
1523219820Sjeff
1524219820Sjeffsl2vl_scope_from_list_or_asterisk:  sl2vl_scope_from_asterisk
1525219820Sjeff                                  | sl2vl_scope_from_list_of_ranges
1526219820Sjeff                                  ;
1527219820Sjeff
1528219820Sjeffsl2vl_scope_from_asterisk: TK_ASTERISK {
1529219820Sjeff                            int i;
1530219820Sjeff                            for (i = 0; i < OSM_QOS_POLICY_MAX_PORTS_ON_SWITCH; i++)
1531219820Sjeff                                p_current_sl2vl_scope->from[i] = TRUE;
1532219820Sjeff                        }
1533219820Sjeff                        ;
1534219820Sjeff
1535219820Sjeffsl2vl_scope_to_list_or_asterisk:  sl2vl_scope_to_asterisk
1536219820Sjeff                                | sl2vl_scope_to_list_of_ranges
1537219820Sjeff                                  ;
1538219820Sjeff
1539219820Sjeffsl2vl_scope_to_asterisk: TK_ASTERISK {
1540219820Sjeff                            int i;
1541219820Sjeff                            for (i = 0; i < OSM_QOS_POLICY_MAX_PORTS_ON_SWITCH; i++)
1542219820Sjeff                                p_current_sl2vl_scope->to[i] = TRUE;
1543219820Sjeff                        }
1544219820Sjeff                        ;
1545219820Sjeff
1546219820Sjeffsl2vl_scope_from_list_of_ranges: list_of_ranges {
1547219820Sjeff                            int i;
1548219820Sjeff                            cl_list_iterator_t    list_iterator;
1549219820Sjeff                            uint64_t            * num_pair;
1550219820Sjeff                            uint8_t               num1, num2;
1551219820Sjeff
1552219820Sjeff                            list_iterator = cl_list_head(&tmp_parser_struct.num_pair_list);
1553219820Sjeff                            while( list_iterator != cl_list_end(&tmp_parser_struct.num_pair_list) )
1554219820Sjeff                            {
1555219820Sjeff                                num_pair = (uint64_t*)cl_list_obj(list_iterator);
1556219820Sjeff                                if (num_pair)
1557219820Sjeff                                {
1558219820Sjeff                                    if ( num_pair[0] < 0 ||
1559219820Sjeff                                         num_pair[1] >= OSM_QOS_POLICY_MAX_PORTS_ON_SWITCH )
1560219820Sjeff                                    {
1561219820Sjeff                                        yyerror("port number out of range 'from' list");
1562219820Sjeff                                        free(num_pair);
1563219820Sjeff                                        cl_list_remove_all(&tmp_parser_struct.num_pair_list);
1564219820Sjeff                                        return 1;
1565219820Sjeff                                    }
1566219820Sjeff                                    num1 = (uint8_t)num_pair[0];
1567219820Sjeff                                    num2 = (uint8_t)num_pair[1];
1568219820Sjeff                                    free(num_pair);
1569219820Sjeff                                    for (i = num1; i <= num2; i++)
1570219820Sjeff                                        p_current_sl2vl_scope->from[i] = TRUE;
1571219820Sjeff                                }
1572219820Sjeff                                list_iterator = cl_list_next(list_iterator);
1573219820Sjeff                            }
1574219820Sjeff                            cl_list_remove_all(&tmp_parser_struct.num_pair_list);
1575219820Sjeff                        }
1576219820Sjeff                        ;
1577219820Sjeff
1578219820Sjeffsl2vl_scope_to_list_of_ranges: list_of_ranges {
1579219820Sjeff                            int i;
1580219820Sjeff                            cl_list_iterator_t    list_iterator;
1581219820Sjeff                            uint64_t            * num_pair;
1582219820Sjeff                            uint8_t               num1, num2;
1583219820Sjeff
1584219820Sjeff                            list_iterator = cl_list_head(&tmp_parser_struct.num_pair_list);
1585219820Sjeff                            while( list_iterator != cl_list_end(&tmp_parser_struct.num_pair_list) )
1586219820Sjeff                            {
1587219820Sjeff                                num_pair = (uint64_t*)cl_list_obj(list_iterator);
1588219820Sjeff                                if (num_pair)
1589219820Sjeff                                {
1590219820Sjeff                                    if ( num_pair[0] < 0 ||
1591219820Sjeff                                         num_pair[1] >= OSM_QOS_POLICY_MAX_PORTS_ON_SWITCH )
1592219820Sjeff                                    {
1593219820Sjeff                                        yyerror("port number out of range 'to' list");
1594219820Sjeff                                        free(num_pair);
1595219820Sjeff                                        cl_list_remove_all(&tmp_parser_struct.num_pair_list);
1596219820Sjeff                                        return 1;
1597219820Sjeff                                    }
1598219820Sjeff                                    num1 = (uint8_t)num_pair[0];
1599219820Sjeff                                    num2 = (uint8_t)num_pair[1];
1600219820Sjeff                                    free(num_pair);
1601219820Sjeff                                    for (i = num1; i <= num2; i++)
1602219820Sjeff                                        p_current_sl2vl_scope->to[i] = TRUE;
1603219820Sjeff                                }
1604219820Sjeff                                list_iterator = cl_list_next(list_iterator);
1605219820Sjeff                            }
1606219820Sjeff                            cl_list_remove_all(&tmp_parser_struct.num_pair_list);
1607219820Sjeff                        }
1608219820Sjeff                        ;
1609219820Sjeff
1610219820Sjeff
1611219820Sjeffsl2vl_scope_sl2vl_table:  sl2vl_scope_sl2vl_table_start num_list {
1612219820Sjeff                            /* 'sl2vl-table' - one instance of exactly
1613219820Sjeff                               OSM_QOS_POLICY_SL2VL_TABLE_LEN numbers */
1614219820Sjeff                            cl_list_iterator_t    list_iterator;
1615219820Sjeff                            uint64_t              num;
1616219820Sjeff                            uint64_t            * p_num;
1617219820Sjeff                            int                   i = 0;
1618219820Sjeff
1619219820Sjeff                            if (p_current_sl2vl_scope->sl2vl_table_set)
1620219820Sjeff                            {
1621219820Sjeff                                yyerror("sl2vl-scope has more than one sl2vl-table");
1622219820Sjeff                                cl_list_remove_all(&tmp_parser_struct.num_list);
1623219820Sjeff                                return 1;
1624219820Sjeff                            }
1625219820Sjeff
1626219820Sjeff                            if (cl_list_count(&tmp_parser_struct.num_list) != OSM_QOS_POLICY_SL2VL_TABLE_LEN)
1627219820Sjeff                            {
1628219820Sjeff                                yyerror("wrong number of values in 'sl2vl-table' (should be 16)");
1629219820Sjeff                                cl_list_remove_all(&tmp_parser_struct.num_list);
1630219820Sjeff                                return 1;
1631219820Sjeff                            }
1632219820Sjeff
1633219820Sjeff                            list_iterator = cl_list_head(&tmp_parser_struct.num_list);
1634219820Sjeff                            while( list_iterator != cl_list_end(&tmp_parser_struct.num_list) )
1635219820Sjeff                            {
1636219820Sjeff                                p_num = (uint64_t*)cl_list_obj(list_iterator);
1637219820Sjeff                                num = *p_num;
1638219820Sjeff                                free(p_num);
1639219820Sjeff                                if (num >= OSM_QOS_POLICY_MAX_VL_NUM)
1640219820Sjeff                                {
1641219820Sjeff                                    yyerror("wrong VL value in 'sl2vl-table' (should be 0 to 15)");
1642219820Sjeff                                    cl_list_remove_all(&tmp_parser_struct.num_list);
1643219820Sjeff                                    return 1;
1644219820Sjeff                                }
1645219820Sjeff
1646219820Sjeff                                p_current_sl2vl_scope->sl2vl_table[i++] = (uint8_t)num;
1647219820Sjeff                                list_iterator = cl_list_next(list_iterator);
1648219820Sjeff                            }
1649219820Sjeff                            p_current_sl2vl_scope->sl2vl_table_set = TRUE;
1650219820Sjeff                            cl_list_remove_all(&tmp_parser_struct.num_list);
1651219820Sjeff                        }
1652219820Sjeff                        ;
1653219820Sjeff
1654219820Sjeffsl2vl_scope_sl2vl_table_start: TK_SL2VL_TABLE {
1655219820Sjeff                            RESET_BUFFER;
1656219820Sjeff                        }
1657219820Sjeff                        ;
1658219820Sjeff
1659219820Sjeff    /*
1660219820Sjeff     *  qos_level_entry values:
1661219820Sjeff     *      qos_level_name
1662219820Sjeff     *      qos_level_use
1663219820Sjeff     *      qos_level_sl
1664219820Sjeff     *      qos_level_mtu_limit
1665219820Sjeff     *      qos_level_rate_limit
1666219820Sjeff     *      qos_level_packet_life
1667219820Sjeff     *      qos_level_path_bits
1668219820Sjeff     *      qos_level_pkey
1669219820Sjeff     */
1670219820Sjeff
1671219820Sjeffqos_level_name:         qos_level_name_start single_string {
1672219820Sjeff                            /* 'name' of 'qos-level' - one instance */
1673219820Sjeff                            cl_list_iterator_t    list_iterator;
1674219820Sjeff                            char                * tmp_str;
1675219820Sjeff
1676219820Sjeff                            if (p_current_qos_level->name)
1677219820Sjeff                            {
1678219820Sjeff                                yyerror("qos-level has multiple 'name' tags");
1679219820Sjeff                                cl_list_remove_all(&tmp_parser_struct.str_list);
1680219820Sjeff                                return 1;
1681219820Sjeff                            }
1682219820Sjeff
1683219820Sjeff                            list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1684219820Sjeff                            if ( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1685219820Sjeff                            {
1686219820Sjeff                                tmp_str = (char*)cl_list_obj(list_iterator);
1687219820Sjeff                                if (tmp_str)
1688219820Sjeff                                    p_current_qos_level->name = tmp_str;
1689219820Sjeff                            }
1690219820Sjeff                            cl_list_remove_all(&tmp_parser_struct.str_list);
1691219820Sjeff                        }
1692219820Sjeff                        ;
1693219820Sjeff
1694219820Sjeffqos_level_name_start:   TK_NAME {
1695219820Sjeff                            RESET_BUFFER;
1696219820Sjeff                        }
1697219820Sjeff                        ;
1698219820Sjeff
1699219820Sjeffqos_level_use:          qos_level_use_start single_string {
1700219820Sjeff                            /* 'use' of 'qos-level' - one instance */
1701219820Sjeff                            cl_list_iterator_t    list_iterator;
1702219820Sjeff                            char                * tmp_str;
1703219820Sjeff
1704219820Sjeff                            if (p_current_qos_level->use)
1705219820Sjeff                            {
1706219820Sjeff                                yyerror("qos-level has multiple 'use' tags");
1707219820Sjeff                                cl_list_remove_all(&tmp_parser_struct.str_list);
1708219820Sjeff                                return 1;
1709219820Sjeff                            }
1710219820Sjeff
1711219820Sjeff                            list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1712219820Sjeff                            if ( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1713219820Sjeff                            {
1714219820Sjeff                                tmp_str = (char*)cl_list_obj(list_iterator);
1715219820Sjeff                                if (tmp_str)
1716219820Sjeff                                    p_current_qos_level->use = tmp_str;
1717219820Sjeff                            }
1718219820Sjeff                            cl_list_remove_all(&tmp_parser_struct.str_list);
1719219820Sjeff                        }
1720219820Sjeff                        ;
1721219820Sjeff
1722219820Sjeffqos_level_use_start:    TK_USE {
1723219820Sjeff                            RESET_BUFFER;
1724219820Sjeff                        }
1725219820Sjeff                        ;
1726219820Sjeff
1727219820Sjeffqos_level_sl:           qos_level_sl_start single_number {
1728219820Sjeff                            /* 'sl' in 'qos-level' - one instance */
1729219820Sjeff                            cl_list_iterator_t   list_iterator;
1730219820Sjeff                            uint64_t           * p_num;
1731219820Sjeff
1732219820Sjeff                            if (p_current_qos_level->sl_set)
1733219820Sjeff                            {
1734219820Sjeff                                yyerror("'qos-level' has multiple 'sl' tags");
1735219820Sjeff                                cl_list_remove_all(&tmp_parser_struct.num_list);
1736219820Sjeff                                return 1;
1737219820Sjeff                            }
1738219820Sjeff                            list_iterator = cl_list_head(&tmp_parser_struct.num_list);
1739219820Sjeff                            p_num = (uint64_t*)cl_list_obj(list_iterator);
1740219820Sjeff                            p_current_qos_level->sl = (uint8_t)(*p_num);
1741219820Sjeff                            free(p_num);
1742219820Sjeff                            p_current_qos_level->sl_set = TRUE;
1743219820Sjeff                            cl_list_remove_all(&tmp_parser_struct.num_list);
1744219820Sjeff                        }
1745219820Sjeff                        ;
1746219820Sjeff
1747219820Sjeffqos_level_sl_start:     TK_SL {
1748219820Sjeff                            RESET_BUFFER;
1749219820Sjeff                        }
1750219820Sjeff                        ;
1751219820Sjeff
1752219820Sjeffqos_level_mtu_limit:    qos_level_mtu_limit_start single_number {
1753219820Sjeff                            /* 'mtu-limit' in 'qos-level' - one instance */
1754219820Sjeff                            cl_list_iterator_t   list_iterator;
1755219820Sjeff                            uint64_t           * p_num;
1756219820Sjeff
1757219820Sjeff                            if (p_current_qos_level->mtu_limit_set)
1758219820Sjeff                            {
1759219820Sjeff                                yyerror("'qos-level' has multiple 'mtu-limit' tags");
1760219820Sjeff                                cl_list_remove_all(&tmp_parser_struct.num_list);
1761219820Sjeff                                return 1;
1762219820Sjeff                            }
1763219820Sjeff                            list_iterator = cl_list_head(&tmp_parser_struct.num_list);
1764219820Sjeff                            p_num = (uint64_t*)cl_list_obj(list_iterator);
1765219820Sjeff                            p_current_qos_level->mtu_limit = (uint8_t)(*p_num);
1766219820Sjeff                            free(p_num);
1767219820Sjeff                            p_current_qos_level->mtu_limit_set = TRUE;
1768219820Sjeff                            cl_list_remove_all(&tmp_parser_struct.num_list);
1769219820Sjeff                        }
1770219820Sjeff                        ;
1771219820Sjeff
1772219820Sjeffqos_level_mtu_limit_start: TK_MTU_LIMIT {
1773219820Sjeff                            /* 'mtu-limit' in 'qos-level' - one instance */
1774219820Sjeff                            RESET_BUFFER;
1775219820Sjeff                        }
1776219820Sjeff                        ;
1777219820Sjeff
1778219820Sjeffqos_level_rate_limit:    qos_level_rate_limit_start single_number {
1779219820Sjeff                            /* 'rate-limit' in 'qos-level' - one instance */
1780219820Sjeff                            cl_list_iterator_t   list_iterator;
1781219820Sjeff                            uint64_t           * p_num;
1782219820Sjeff
1783219820Sjeff                            if (p_current_qos_level->rate_limit_set)
1784219820Sjeff                            {
1785219820Sjeff                                yyerror("'qos-level' has multiple 'rate-limit' tags");
1786219820Sjeff                                cl_list_remove_all(&tmp_parser_struct.num_list);
1787219820Sjeff                                return 1;
1788219820Sjeff                            }
1789219820Sjeff                            list_iterator = cl_list_head(&tmp_parser_struct.num_list);
1790219820Sjeff                            p_num = (uint64_t*)cl_list_obj(list_iterator);
1791219820Sjeff                            p_current_qos_level->rate_limit = (uint8_t)(*p_num);
1792219820Sjeff                            free(p_num);
1793219820Sjeff                            p_current_qos_level->rate_limit_set = TRUE;
1794219820Sjeff                            cl_list_remove_all(&tmp_parser_struct.num_list);
1795219820Sjeff                        }
1796219820Sjeff                        ;
1797219820Sjeff
1798219820Sjeffqos_level_rate_limit_start: TK_RATE_LIMIT {
1799219820Sjeff                            /* 'rate-limit' in 'qos-level' - one instance */
1800219820Sjeff                            RESET_BUFFER;
1801219820Sjeff                        }
1802219820Sjeff                        ;
1803219820Sjeff
1804219820Sjeffqos_level_packet_life:  qos_level_packet_life_start single_number {
1805219820Sjeff                            /* 'packet-life' in 'qos-level' - one instance */
1806219820Sjeff                            cl_list_iterator_t   list_iterator;
1807219820Sjeff                            uint64_t           * p_num;
1808219820Sjeff
1809219820Sjeff                            if (p_current_qos_level->pkt_life_set)
1810219820Sjeff                            {
1811219820Sjeff                                yyerror("'qos-level' has multiple 'packet-life' tags");
1812219820Sjeff                                cl_list_remove_all(&tmp_parser_struct.num_list);
1813219820Sjeff                                return 1;
1814219820Sjeff                            }
1815219820Sjeff                            list_iterator = cl_list_head(&tmp_parser_struct.num_list);
1816219820Sjeff                            p_num = (uint64_t*)cl_list_obj(list_iterator);
1817219820Sjeff                            p_current_qos_level->pkt_life = (uint8_t)(*p_num);
1818219820Sjeff                            free(p_num);
1819219820Sjeff                            p_current_qos_level->pkt_life_set= TRUE;
1820219820Sjeff                            cl_list_remove_all(&tmp_parser_struct.num_list);
1821219820Sjeff                        }
1822219820Sjeff                        ;
1823219820Sjeff
1824219820Sjeffqos_level_packet_life_start: TK_PACKET_LIFE {
1825219820Sjeff                            /* 'packet-life' in 'qos-level' - one instance */
1826219820Sjeff                            RESET_BUFFER;
1827219820Sjeff                        }
1828219820Sjeff                        ;
1829219820Sjeff
1830219820Sjeffqos_level_path_bits:    qos_level_path_bits_start list_of_ranges {
1831219820Sjeff                            /* 'path-bits' in 'qos-level' - any num of instances */
1832219820Sjeff                            /* list of path bit ranges */
1833219820Sjeff
1834219820Sjeff                            if (cl_list_count(&tmp_parser_struct.num_pair_list))
1835219820Sjeff                            {
1836219820Sjeff                                uint64_t ** range_arr;
1837219820Sjeff                                unsigned range_len;
1838219820Sjeff
1839219820Sjeff                                __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
1840219820Sjeff                                                      &range_arr,
1841219820Sjeff                                                      &range_len );
1842219820Sjeff
1843219820Sjeff                                if ( !p_current_qos_level->path_bits_range_len )
1844219820Sjeff                                {
1845219820Sjeff                                    p_current_qos_level->path_bits_range_arr = range_arr;
1846219820Sjeff                                    p_current_qos_level->path_bits_range_len = range_len;
1847219820Sjeff                                }
1848219820Sjeff                                else
1849219820Sjeff                                {
1850219820Sjeff                                    uint64_t ** new_range_arr;
1851219820Sjeff                                    unsigned new_range_len;
1852219820Sjeff                                    __merge_rangearr( p_current_qos_level->path_bits_range_arr,
1853219820Sjeff                                                      p_current_qos_level->path_bits_range_len,
1854219820Sjeff                                                      range_arr,
1855219820Sjeff                                                      range_len,
1856219820Sjeff                                                      &new_range_arr,
1857219820Sjeff                                                      &new_range_len );
1858219820Sjeff                                    p_current_qos_level->path_bits_range_arr = new_range_arr;
1859219820Sjeff                                    p_current_qos_level->path_bits_range_len = new_range_len;
1860219820Sjeff                                }
1861219820Sjeff                            }
1862219820Sjeff                        }
1863219820Sjeff                        ;
1864219820Sjeff
1865219820Sjeffqos_level_path_bits_start: TK_PATH_BITS {
1866219820Sjeff                            RESET_BUFFER;
1867219820Sjeff                        }
1868219820Sjeff                        ;
1869219820Sjeff
1870219820Sjeffqos_level_pkey:         qos_level_pkey_start list_of_ranges {
1871219820Sjeff                            /* 'pkey' in 'qos-level' - num of instances of list of ranges */
1872219820Sjeff                            if (cl_list_count(&tmp_parser_struct.num_pair_list))
1873219820Sjeff                            {
1874219820Sjeff                                uint64_t ** range_arr;
1875219820Sjeff                                unsigned range_len;
1876219820Sjeff
1877219820Sjeff                                __pkey_rangelist2rangearr( &tmp_parser_struct.num_pair_list,
1878219820Sjeff                                                      &range_arr,
1879219820Sjeff                                                      &range_len );
1880219820Sjeff
1881219820Sjeff                                if ( !p_current_qos_level->pkey_range_len )
1882219820Sjeff                                {
1883219820Sjeff                                    p_current_qos_level->pkey_range_arr = range_arr;
1884219820Sjeff                                    p_current_qos_level->pkey_range_len = range_len;
1885219820Sjeff                                }
1886219820Sjeff                                else
1887219820Sjeff                                {
1888219820Sjeff                                    uint64_t ** new_range_arr;
1889219820Sjeff                                    unsigned new_range_len;
1890219820Sjeff                                    __merge_rangearr( p_current_qos_level->pkey_range_arr,
1891219820Sjeff                                                      p_current_qos_level->pkey_range_len,
1892219820Sjeff                                                      range_arr,
1893219820Sjeff                                                      range_len,
1894219820Sjeff                                                      &new_range_arr,
1895219820Sjeff                                                      &new_range_len );
1896219820Sjeff                                    p_current_qos_level->pkey_range_arr = new_range_arr;
1897219820Sjeff                                    p_current_qos_level->pkey_range_len = new_range_len;
1898219820Sjeff                                }
1899219820Sjeff                            }
1900219820Sjeff                        }
1901219820Sjeff                        ;
1902219820Sjeff
1903219820Sjeffqos_level_pkey_start:   TK_PKEY {
1904219820Sjeff                            RESET_BUFFER;
1905219820Sjeff                        }
1906219820Sjeff                        ;
1907219820Sjeff
1908219820Sjeff    /*
1909219820Sjeff     *  qos_match_rule_entry values:
1910219820Sjeff     *      qos_match_rule_use
1911219820Sjeff     *      qos_match_rule_qos_class
1912219820Sjeff     *      qos_match_rule_qos_level_name
1913219820Sjeff     *      qos_match_rule_source
1914219820Sjeff     *      qos_match_rule_destination
1915219820Sjeff     *      qos_match_rule_service_id
1916219820Sjeff     *      qos_match_rule_pkey
1917219820Sjeff     */
1918219820Sjeff
1919219820Sjeff
1920219820Sjeffqos_match_rule_use:     qos_match_rule_use_start single_string {
1921219820Sjeff                            /* 'use' of 'qos-match-rule' - one instance */
1922219820Sjeff                            cl_list_iterator_t    list_iterator;
1923219820Sjeff                            char                * tmp_str;
1924219820Sjeff
1925219820Sjeff                            if (p_current_qos_match_rule->use)
1926219820Sjeff                            {
1927219820Sjeff                                yyerror("'qos-match-rule' has multiple 'use' tags");
1928219820Sjeff                                cl_list_remove_all(&tmp_parser_struct.str_list);
1929219820Sjeff                                return 1;
1930219820Sjeff                            }
1931219820Sjeff
1932219820Sjeff                            list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1933219820Sjeff                            if ( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1934219820Sjeff                            {
1935219820Sjeff                                tmp_str = (char*)cl_list_obj(list_iterator);
1936219820Sjeff                                if (tmp_str)
1937219820Sjeff                                    p_current_qos_match_rule->use = tmp_str;
1938219820Sjeff                            }
1939219820Sjeff                            cl_list_remove_all(&tmp_parser_struct.str_list);
1940219820Sjeff                        }
1941219820Sjeff                        ;
1942219820Sjeff
1943219820Sjeffqos_match_rule_use_start: TK_USE {
1944219820Sjeff                            RESET_BUFFER;
1945219820Sjeff                        }
1946219820Sjeff                        ;
1947219820Sjeff
1948219820Sjeffqos_match_rule_qos_class: qos_match_rule_qos_class_start list_of_ranges {
1949219820Sjeff                            /* 'qos-class' in 'qos-match-rule' - num of instances of list of ranges */
1950219820Sjeff                            /* list of class ranges (QoS Class is 12-bit value) */
1951219820Sjeff                            if (cl_list_count(&tmp_parser_struct.num_pair_list))
1952219820Sjeff                            {
1953219820Sjeff                                uint64_t ** range_arr;
1954219820Sjeff                                unsigned range_len;
1955219820Sjeff
1956219820Sjeff                                __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
1957219820Sjeff                                                      &range_arr,
1958219820Sjeff                                                      &range_len );
1959219820Sjeff
1960219820Sjeff                                if ( !p_current_qos_match_rule->qos_class_range_len )
1961219820Sjeff                                {
1962219820Sjeff                                    p_current_qos_match_rule->qos_class_range_arr = range_arr;
1963219820Sjeff                                    p_current_qos_match_rule->qos_class_range_len = range_len;
1964219820Sjeff                                }
1965219820Sjeff                                else
1966219820Sjeff                                {
1967219820Sjeff                                    uint64_t ** new_range_arr;
1968219820Sjeff                                    unsigned new_range_len;
1969219820Sjeff                                    __merge_rangearr( p_current_qos_match_rule->qos_class_range_arr,
1970219820Sjeff                                                      p_current_qos_match_rule->qos_class_range_len,
1971219820Sjeff                                                      range_arr,
1972219820Sjeff                                                      range_len,
1973219820Sjeff                                                      &new_range_arr,
1974219820Sjeff                                                      &new_range_len );
1975219820Sjeff                                    p_current_qos_match_rule->qos_class_range_arr = new_range_arr;
1976219820Sjeff                                    p_current_qos_match_rule->qos_class_range_len = new_range_len;
1977219820Sjeff                                }
1978219820Sjeff                            }
1979219820Sjeff                        }
1980219820Sjeff                        ;
1981219820Sjeff
1982219820Sjeffqos_match_rule_qos_class_start: TK_QOS_CLASS {
1983219820Sjeff                            RESET_BUFFER;
1984219820Sjeff                        }
1985219820Sjeff                        ;
1986219820Sjeff
1987219820Sjeffqos_match_rule_source:  qos_match_rule_source_start string_list {
1988219820Sjeff                            /* 'source' in 'qos-match-rule' - text */
1989219820Sjeff                            cl_list_iterator_t    list_iterator;
1990219820Sjeff                            char                * tmp_str;
1991219820Sjeff
1992219820Sjeff                            list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1993219820Sjeff                            while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1994219820Sjeff                            {
1995219820Sjeff                                tmp_str = (char*)cl_list_obj(list_iterator);
1996219820Sjeff                                if (tmp_str)
1997219820Sjeff                                    cl_list_insert_tail(&p_current_qos_match_rule->source_list,tmp_str);
1998219820Sjeff                                list_iterator = cl_list_next(list_iterator);
1999219820Sjeff                            }
2000219820Sjeff                            cl_list_remove_all(&tmp_parser_struct.str_list);
2001219820Sjeff                        }
2002219820Sjeff                        ;
2003219820Sjeff
2004219820Sjeffqos_match_rule_source_start: TK_SOURCE {
2005219820Sjeff                            RESET_BUFFER;
2006219820Sjeff                        }
2007219820Sjeff                        ;
2008219820Sjeff
2009219820Sjeffqos_match_rule_destination: qos_match_rule_destination_start string_list {
2010219820Sjeff                            /* 'destination' in 'qos-match-rule' - text */
2011219820Sjeff                            cl_list_iterator_t    list_iterator;
2012219820Sjeff                            char                * tmp_str;
2013219820Sjeff
2014219820Sjeff                            list_iterator = cl_list_head(&tmp_parser_struct.str_list);
2015219820Sjeff                            while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
2016219820Sjeff                            {
2017219820Sjeff                                tmp_str = (char*)cl_list_obj(list_iterator);
2018219820Sjeff                                if (tmp_str)
2019219820Sjeff                                    cl_list_insert_tail(&p_current_qos_match_rule->destination_list,tmp_str);
2020219820Sjeff                                list_iterator = cl_list_next(list_iterator);
2021219820Sjeff                            }
2022219820Sjeff                            cl_list_remove_all(&tmp_parser_struct.str_list);
2023219820Sjeff                        }
2024219820Sjeff                        ;
2025219820Sjeff
2026219820Sjeffqos_match_rule_destination_start: TK_DESTINATION {
2027219820Sjeff                            RESET_BUFFER;
2028219820Sjeff                        }
2029219820Sjeff                        ;
2030219820Sjeff
2031219820Sjeffqos_match_rule_qos_level_name:  qos_match_rule_qos_level_name_start single_string {
2032219820Sjeff                            /* 'qos-level-name' in 'qos-match-rule' - single string */
2033219820Sjeff                            cl_list_iterator_t   list_iterator;
2034219820Sjeff                            char               * tmp_str;
2035219820Sjeff
2036219820Sjeff                            if (p_current_qos_match_rule->qos_level_name)
2037219820Sjeff                            {
2038219820Sjeff                                yyerror("qos-match-rule has multiple 'qos-level-name' tags");
2039219820Sjeff                                cl_list_remove_all(&tmp_parser_struct.num_list);
2040219820Sjeff                                return 1;
2041219820Sjeff                            }
2042219820Sjeff
2043219820Sjeff                            list_iterator = cl_list_head(&tmp_parser_struct.str_list);
2044219820Sjeff                            if ( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
2045219820Sjeff                            {
2046219820Sjeff                                tmp_str = (char*)cl_list_obj(list_iterator);
2047219820Sjeff                                if (tmp_str)
2048219820Sjeff                                    p_current_qos_match_rule->qos_level_name = tmp_str;
2049219820Sjeff                            }
2050219820Sjeff                            cl_list_remove_all(&tmp_parser_struct.str_list);
2051219820Sjeff                        }
2052219820Sjeff                        ;
2053219820Sjeff
2054219820Sjeffqos_match_rule_qos_level_name_start: TK_QOS_LEVEL_NAME {
2055219820Sjeff                            RESET_BUFFER;
2056219820Sjeff                        }
2057219820Sjeff                        ;
2058219820Sjeff
2059219820Sjeffqos_match_rule_service_id: qos_match_rule_service_id_start list_of_ranges {
2060219820Sjeff                            /* 'service-id' in 'qos-match-rule' - num of instances of list of ranges */
2061219820Sjeff                            if (cl_list_count(&tmp_parser_struct.num_pair_list))
2062219820Sjeff                            {
2063219820Sjeff                                uint64_t ** range_arr;
2064219820Sjeff                                unsigned range_len;
2065219820Sjeff
2066219820Sjeff                                __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
2067219820Sjeff                                                      &range_arr,
2068219820Sjeff                                                      &range_len );
2069219820Sjeff
2070219820Sjeff                                if ( !p_current_qos_match_rule->service_id_range_len )
2071219820Sjeff                                {
2072219820Sjeff                                    p_current_qos_match_rule->service_id_range_arr = range_arr;
2073219820Sjeff                                    p_current_qos_match_rule->service_id_range_len = range_len;
2074219820Sjeff                                }
2075219820Sjeff                                else
2076219820Sjeff                                {
2077219820Sjeff                                    uint64_t ** new_range_arr;
2078219820Sjeff                                    unsigned new_range_len;
2079219820Sjeff                                    __merge_rangearr( p_current_qos_match_rule->service_id_range_arr,
2080219820Sjeff                                                      p_current_qos_match_rule->service_id_range_len,
2081219820Sjeff                                                      range_arr,
2082219820Sjeff                                                      range_len,
2083219820Sjeff                                                      &new_range_arr,
2084219820Sjeff                                                      &new_range_len );
2085219820Sjeff                                    p_current_qos_match_rule->service_id_range_arr = new_range_arr;
2086219820Sjeff                                    p_current_qos_match_rule->service_id_range_len = new_range_len;
2087219820Sjeff                                }
2088219820Sjeff                            }
2089219820Sjeff                        }
2090219820Sjeff                        ;
2091219820Sjeff
2092219820Sjeffqos_match_rule_service_id_start: TK_SERVICE_ID {
2093219820Sjeff                            RESET_BUFFER;
2094219820Sjeff                        }
2095219820Sjeff                        ;
2096219820Sjeff
2097219820Sjeffqos_match_rule_pkey:    qos_match_rule_pkey_start list_of_ranges {
2098219820Sjeff                            /* 'pkey' in 'qos-match-rule' - num of instances of list of ranges */
2099219820Sjeff                            if (cl_list_count(&tmp_parser_struct.num_pair_list))
2100219820Sjeff                            {
2101219820Sjeff                                uint64_t ** range_arr;
2102219820Sjeff                                unsigned range_len;
2103219820Sjeff
2104219820Sjeff                                __pkey_rangelist2rangearr( &tmp_parser_struct.num_pair_list,
2105219820Sjeff                                                      &range_arr,
2106219820Sjeff                                                      &range_len );
2107219820Sjeff
2108219820Sjeff                                if ( !p_current_qos_match_rule->pkey_range_len )
2109219820Sjeff                                {
2110219820Sjeff                                    p_current_qos_match_rule->pkey_range_arr = range_arr;
2111219820Sjeff                                    p_current_qos_match_rule->pkey_range_len = range_len;
2112219820Sjeff                                }
2113219820Sjeff                                else
2114219820Sjeff                                {
2115219820Sjeff                                    uint64_t ** new_range_arr;
2116219820Sjeff                                    unsigned new_range_len;
2117219820Sjeff                                    __merge_rangearr( p_current_qos_match_rule->pkey_range_arr,
2118219820Sjeff                                                      p_current_qos_match_rule->pkey_range_len,
2119219820Sjeff                                                      range_arr,
2120219820Sjeff                                                      range_len,
2121219820Sjeff                                                      &new_range_arr,
2122219820Sjeff                                                      &new_range_len );
2123219820Sjeff                                    p_current_qos_match_rule->pkey_range_arr = new_range_arr;
2124219820Sjeff                                    p_current_qos_match_rule->pkey_range_len = new_range_len;
2125219820Sjeff                                }
2126219820Sjeff                            }
2127219820Sjeff                        }
2128219820Sjeff                        ;
2129219820Sjeff
2130219820Sjeffqos_match_rule_pkey_start: TK_PKEY {
2131219820Sjeff                            RESET_BUFFER;
2132219820Sjeff                        }
2133219820Sjeff                        ;
2134219820Sjeff
2135219820Sjeff
2136219820Sjeff    /*
2137219820Sjeff     * Common part
2138219820Sjeff     */
2139219820Sjeff
2140219820Sjeff
2141219820Sjeffsingle_string:      single_string_elems {
2142219820Sjeff                        cl_list_insert_tail(&tmp_parser_struct.str_list,
2143219820Sjeff                                            strdup(__parser_strip_white(tmp_parser_struct.str)));
2144219820Sjeff                        tmp_parser_struct.str[0] = '\0';
2145219820Sjeff                    }
2146219820Sjeff                    ;
2147219820Sjeff
2148219820Sjeffsingle_string_elems:  single_string_element
2149219820Sjeff                    | single_string_elems single_string_element
2150219820Sjeff                    ;
2151219820Sjeff
2152219820Sjeffsingle_string_element: TK_TEXT {
2153219820Sjeff                        strcat(tmp_parser_struct.str,$1);
2154219820Sjeff                        free($1);
2155219820Sjeff                    }
2156219820Sjeff                    ;
2157219820Sjeff
2158219820Sjeff
2159219820Sjeffstring_list:        single_string
2160219820Sjeff                    | string_list TK_COMMA single_string
2161219820Sjeff                    ;
2162219820Sjeff
2163219820Sjeff
2164219820Sjeff
2165219820Sjeffsingle_number:      number
2166219820Sjeff                    ;
2167219820Sjeff
2168219820Sjeffnum_list:             number
2169219820Sjeff                    | num_list TK_COMMA number
2170219820Sjeff                    ;
2171219820Sjeff
2172219820Sjeffnumber:             TK_NUMBER {
2173219820Sjeff                        uint64_t * p_num = (uint64_t*)malloc(sizeof(uint64_t));
2174219820Sjeff                        __parser_str2uint64(p_num,$1);
2175219820Sjeff                        free($1);
2176219820Sjeff                        cl_list_insert_tail(&tmp_parser_struct.num_list, p_num);
2177219820Sjeff                    }
2178219820Sjeff                    ;
2179219820Sjeff
2180219820Sjeffnum_list_with_dotdot: number_from_pair_1 TK_DOTDOT number_from_pair_2 {
2181219820Sjeff                        uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
2182219820Sjeff                        num_pair[0] = tmp_parser_struct.num_pair[0];
2183219820Sjeff                        num_pair[1] = tmp_parser_struct.num_pair[1];
2184219820Sjeff                        cl_list_insert_tail(&tmp_parser_struct.num_pair_list, num_pair);
2185219820Sjeff                    }
2186219820Sjeff                    | num_list_with_dotdot TK_COMMA number_from_pair_1 TK_DOTDOT number_from_pair_2 {
2187219820Sjeff                        uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
2188219820Sjeff                        num_pair[0] = tmp_parser_struct.num_pair[0];
2189219820Sjeff                        num_pair[1] = tmp_parser_struct.num_pair[1];
2190219820Sjeff                        cl_list_insert_tail(&tmp_parser_struct.num_pair_list, num_pair);
2191219820Sjeff                    }
2192219820Sjeff                    ;
2193219820Sjeff
2194219820Sjeffnumber_from_pair_1:   TK_NUMBER {
2195219820Sjeff                        __parser_str2uint64(&tmp_parser_struct.num_pair[0],$1);
2196219820Sjeff                        free($1);
2197219820Sjeff                    }
2198219820Sjeff                    ;
2199219820Sjeff
2200219820Sjeffnumber_from_pair_2:   TK_NUMBER {
2201219820Sjeff                        __parser_str2uint64(&tmp_parser_struct.num_pair[1],$1);
2202219820Sjeff                        free($1);
2203219820Sjeff                    }
2204219820Sjeff                    ;
2205219820Sjeff
2206219820Sjefflist_of_ranges:     num_list_with_dash
2207219820Sjeff                    ;
2208219820Sjeff
2209219820Sjeffnum_list_with_dash:   single_number_from_range {
2210219820Sjeff                        uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
2211219820Sjeff                        num_pair[0] = tmp_parser_struct.num_pair[0];
2212219820Sjeff                        num_pair[1] = tmp_parser_struct.num_pair[1];
2213219820Sjeff                        cl_list_insert_tail(&tmp_parser_struct.num_pair_list, num_pair);
2214219820Sjeff                    }
2215219820Sjeff                    | number_from_range_1 TK_DASH number_from_range_2 {
2216219820Sjeff                        uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
2217219820Sjeff                        if (tmp_parser_struct.num_pair[0] <= tmp_parser_struct.num_pair[1]) {
2218219820Sjeff                            num_pair[0] = tmp_parser_struct.num_pair[0];
2219219820Sjeff                            num_pair[1] = tmp_parser_struct.num_pair[1];
2220219820Sjeff                        }
2221219820Sjeff                        else {
2222219820Sjeff                            num_pair[1] = tmp_parser_struct.num_pair[0];
2223219820Sjeff                            num_pair[0] = tmp_parser_struct.num_pair[1];
2224219820Sjeff                        }
2225219820Sjeff                        cl_list_insert_tail(&tmp_parser_struct.num_pair_list, num_pair);
2226219820Sjeff                    }
2227219820Sjeff                    | num_list_with_dash TK_COMMA number_from_range_1 TK_DASH number_from_range_2 {
2228219820Sjeff                        uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
2229219820Sjeff                        if (tmp_parser_struct.num_pair[0] <= tmp_parser_struct.num_pair[1]) {
2230219820Sjeff                            num_pair[0] = tmp_parser_struct.num_pair[0];
2231219820Sjeff                            num_pair[1] = tmp_parser_struct.num_pair[1];
2232219820Sjeff                        }
2233219820Sjeff                        else {
2234219820Sjeff                            num_pair[1] = tmp_parser_struct.num_pair[0];
2235219820Sjeff                            num_pair[0] = tmp_parser_struct.num_pair[1];
2236219820Sjeff                        }
2237219820Sjeff                        cl_list_insert_tail(&tmp_parser_struct.num_pair_list, num_pair);
2238219820Sjeff                    }
2239219820Sjeff                    | num_list_with_dash TK_COMMA single_number_from_range {
2240219820Sjeff                        uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
2241219820Sjeff                        num_pair[0] = tmp_parser_struct.num_pair[0];
2242219820Sjeff                        num_pair[1] = tmp_parser_struct.num_pair[1];
2243219820Sjeff                        cl_list_insert_tail(&tmp_parser_struct.num_pair_list, num_pair);
2244219820Sjeff                    }
2245219820Sjeff                    ;
2246219820Sjeff
2247219820Sjeffsingle_number_from_range:  TK_NUMBER {
2248219820Sjeff                        __parser_str2uint64(&tmp_parser_struct.num_pair[0],$1);
2249219820Sjeff                        __parser_str2uint64(&tmp_parser_struct.num_pair[1],$1);
2250219820Sjeff                        free($1);
2251219820Sjeff                    }
2252219820Sjeff                    ;
2253219820Sjeff
2254219820Sjeffnumber_from_range_1:  TK_NUMBER {
2255219820Sjeff                        __parser_str2uint64(&tmp_parser_struct.num_pair[0],$1);
2256219820Sjeff                        free($1);
2257219820Sjeff                    }
2258219820Sjeff                    ;
2259219820Sjeff
2260219820Sjeffnumber_from_range_2:  TK_NUMBER {
2261219820Sjeff                        __parser_str2uint64(&tmp_parser_struct.num_pair[1],$1);
2262219820Sjeff                        free($1);
2263219820Sjeff                    }
2264219820Sjeff                    ;
2265219820Sjeff
2266219820Sjeff%%
2267219820Sjeff
2268219820Sjeff/***************************************************
2269219820Sjeff ***************************************************/
2270219820Sjeff
2271219820Sjeffint osm_qos_parse_policy_file(IN osm_subn_t * const p_subn)
2272219820Sjeff{
2273219820Sjeff    int res = 0;
2274219820Sjeff    static boolean_t first_time = TRUE;
2275219820Sjeff    p_qos_parser_osm_log = &p_subn->p_osm->log;
2276219820Sjeff
2277219820Sjeff    OSM_LOG_ENTER(p_qos_parser_osm_log);
2278219820Sjeff
2279219820Sjeff    osm_qos_policy_destroy(p_subn->p_qos_policy);
2280219820Sjeff    p_subn->p_qos_policy = NULL;
2281219820Sjeff
2282219820Sjeff    yyin = fopen (p_subn->opt.qos_policy_file, "r");
2283219820Sjeff    if (!yyin)
2284219820Sjeff    {
2285219820Sjeff        if (strcmp(p_subn->opt.qos_policy_file,OSM_DEFAULT_QOS_POLICY_FILE)) {
2286219820Sjeff            OSM_LOG(p_qos_parser_osm_log, OSM_LOG_ERROR, "ERR AC01: "
2287219820Sjeff                    "Failed opening QoS policy file %s - %s\n",
2288219820Sjeff                    p_subn->opt.qos_policy_file, strerror(errno));
2289219820Sjeff            res = 1;
2290219820Sjeff        }
2291219820Sjeff        else
2292219820Sjeff            OSM_LOG(p_qos_parser_osm_log, OSM_LOG_VERBOSE,
2293219820Sjeff                    "QoS policy file not found (%s)\n",
2294219820Sjeff                    p_subn->opt.qos_policy_file);
2295219820Sjeff
2296219820Sjeff        goto Exit;
2297219820Sjeff    }
2298219820Sjeff
2299219820Sjeff    if (first_time)
2300219820Sjeff    {
2301219820Sjeff        first_time = FALSE;
2302219820Sjeff        __setup_simple_qos_levels();
2303219820Sjeff        __setup_ulp_match_rules();
2304219820Sjeff        OSM_LOG(p_qos_parser_osm_log, OSM_LOG_INFO,
2305219820Sjeff		"Loading QoS policy file (%s)\n",
2306219820Sjeff                p_subn->opt.qos_policy_file);
2307219820Sjeff    }
2308219820Sjeff    else
2309219820Sjeff        /*
2310219820Sjeff         * ULP match rules list was emptied at the end of
2311219820Sjeff         * previous parsing iteration.
2312219820Sjeff         * What's left is to clear simple QoS levels.
2313219820Sjeff         */
2314219820Sjeff        __clear_simple_qos_levels();
2315219820Sjeff
2316219820Sjeff    column_num = 1;
2317219820Sjeff    line_num = 1;
2318219820Sjeff
2319219820Sjeff    p_subn->p_qos_policy = osm_qos_policy_create(p_subn);
2320219820Sjeff
2321219820Sjeff    __parser_tmp_struct_init();
2322219820Sjeff    p_qos_policy = p_subn->p_qos_policy;
2323219820Sjeff
2324219820Sjeff    res = yyparse();
2325219820Sjeff
2326219820Sjeff    __parser_tmp_struct_destroy();
2327219820Sjeff
2328219820Sjeff    if (res != 0)
2329219820Sjeff    {
2330219820Sjeff        OSM_LOG(p_qos_parser_osm_log, OSM_LOG_ERROR, "ERR AC03: "
2331219820Sjeff                "Failed parsing QoS policy file (%s)\n",
2332219820Sjeff                p_subn->opt.qos_policy_file);
2333219820Sjeff        osm_qos_policy_destroy(p_subn->p_qos_policy);
2334219820Sjeff        p_subn->p_qos_policy = NULL;
2335219820Sjeff        res = 1;
2336219820Sjeff        goto Exit;
2337219820Sjeff    }
2338219820Sjeff
2339219820Sjeff    /* add generated ULP match rules to the usual match rules */
2340219820Sjeff    __process_ulp_match_rules();
2341219820Sjeff
2342219820Sjeff    if (osm_qos_policy_validate(p_subn->p_qos_policy,p_qos_parser_osm_log))
2343219820Sjeff    {
2344219820Sjeff        OSM_LOG(p_qos_parser_osm_log, OSM_LOG_ERROR, "ERR AC04: "
2345219820Sjeff                "Error(s) in QoS policy file (%s)\n",
2346219820Sjeff                p_subn->opt.qos_policy_file);
2347219820Sjeff        fprintf(stderr, "Error(s) in QoS policy file (%s)\n",
2348219820Sjeff                p_subn->opt.qos_policy_file);
2349219820Sjeff        osm_qos_policy_destroy(p_subn->p_qos_policy);
2350219820Sjeff        p_subn->p_qos_policy = NULL;
2351219820Sjeff        res = 1;
2352219820Sjeff        goto Exit;
2353219820Sjeff    }
2354219820Sjeff
2355219820Sjeff  Exit:
2356219820Sjeff    if (yyin)
2357219820Sjeff        fclose(yyin);
2358219820Sjeff    OSM_LOG_EXIT(p_qos_parser_osm_log);
2359219820Sjeff    return res;
2360219820Sjeff}
2361219820Sjeff
2362219820Sjeff/***************************************************
2363219820Sjeff ***************************************************/
2364219820Sjeff
2365219820Sjeffint yywrap()
2366219820Sjeff{
2367219820Sjeff    return(1);
2368219820Sjeff}
2369219820Sjeff
2370219820Sjeff/***************************************************
2371219820Sjeff ***************************************************/
2372219820Sjeff
2373219820Sjeffstatic void yyerror(const char *format, ...)
2374219820Sjeff{
2375219820Sjeff    char s[256];
2376219820Sjeff    va_list pvar;
2377219820Sjeff
2378219820Sjeff    OSM_LOG_ENTER(p_qos_parser_osm_log);
2379219820Sjeff
2380219820Sjeff    va_start(pvar, format);
2381219820Sjeff    vsnprintf(s, sizeof(s), format, pvar);
2382219820Sjeff    va_end(pvar);
2383219820Sjeff
2384219820Sjeff    OSM_LOG(p_qos_parser_osm_log, OSM_LOG_ERROR, "ERR AC05: "
2385219820Sjeff            "Syntax error (line %d:%d): %s\n",
2386219820Sjeff            line_num, column_num, s);
2387219820Sjeff    fprintf(stderr, "Error in QoS Policy File (line %d:%d): %s.\n",
2388219820Sjeff            line_num, column_num, s);
2389219820Sjeff    OSM_LOG_EXIT(p_qos_parser_osm_log);
2390219820Sjeff}
2391219820Sjeff
2392219820Sjeff/***************************************************
2393219820Sjeff ***************************************************/
2394219820Sjeff
2395219820Sjeffstatic char * __parser_strip_white(char * str)
2396219820Sjeff{
2397219820Sjeff   int i;
2398219820Sjeff   for (i = (strlen(str)-1); i >= 0; i--)
2399219820Sjeff   {
2400219820Sjeff      if (isspace(str[i]))
2401219820Sjeff          str[i] = '\0';
2402219820Sjeff      else
2403219820Sjeff         break;
2404219820Sjeff   }
2405219820Sjeff   for (i = 0; i < strlen(str); i++)
2406219820Sjeff   {
2407219820Sjeff      if (!isspace(str[i]))
2408219820Sjeff         break;
2409219820Sjeff   }
2410219820Sjeff   return &(str[i]);
2411219820Sjeff}
2412219820Sjeff
2413219820Sjeff/***************************************************
2414219820Sjeff ***************************************************/
2415219820Sjeff
2416219820Sjeffstatic void __parser_str2uint64(uint64_t * p_val, char * str)
2417219820Sjeff{
2418219820Sjeff   *p_val = strtoull(str, NULL, 0);
2419219820Sjeff}
2420219820Sjeff
2421219820Sjeff/***************************************************
2422219820Sjeff ***************************************************/
2423219820Sjeff
2424219820Sjeffstatic void __parser_port_group_start()
2425219820Sjeff{
2426219820Sjeff    p_current_port_group = osm_qos_policy_port_group_create();
2427219820Sjeff}
2428219820Sjeff
2429219820Sjeff/***************************************************
2430219820Sjeff ***************************************************/
2431219820Sjeff
2432219820Sjeffstatic int __parser_port_group_end()
2433219820Sjeff{
2434219820Sjeff    if(!p_current_port_group->name)
2435219820Sjeff    {
2436219820Sjeff        yyerror("port-group validation failed - no port group name specified");
2437219820Sjeff        return -1;
2438219820Sjeff    }
2439219820Sjeff
2440219820Sjeff    cl_list_insert_tail(&p_qos_policy->port_groups,
2441219820Sjeff                        p_current_port_group);
2442219820Sjeff    p_current_port_group = NULL;
2443219820Sjeff    return 0;
2444219820Sjeff}
2445219820Sjeff
2446219820Sjeff/***************************************************
2447219820Sjeff ***************************************************/
2448219820Sjeff
2449219820Sjeffstatic void __parser_vlarb_scope_start()
2450219820Sjeff{
2451219820Sjeff    p_current_vlarb_scope = osm_qos_policy_vlarb_scope_create();
2452219820Sjeff}
2453219820Sjeff
2454219820Sjeff/***************************************************
2455219820Sjeff ***************************************************/
2456219820Sjeff
2457219820Sjeffstatic int __parser_vlarb_scope_end()
2458219820Sjeff{
2459219820Sjeff    if ( !cl_list_count(&p_current_vlarb_scope->group_list) &&
2460219820Sjeff         !cl_list_count(&p_current_vlarb_scope->across_list) )
2461219820Sjeff    {
2462219820Sjeff        yyerror("vlarb-scope validation failed - no port groups specified by 'group' or by 'across'");
2463219820Sjeff        return -1;
2464219820Sjeff    }
2465219820Sjeff
2466219820Sjeff    cl_list_insert_tail(&p_qos_policy->vlarb_tables,
2467219820Sjeff                        p_current_vlarb_scope);
2468219820Sjeff    p_current_vlarb_scope = NULL;
2469219820Sjeff    return 0;
2470219820Sjeff}
2471219820Sjeff
2472219820Sjeff/***************************************************
2473219820Sjeff ***************************************************/
2474219820Sjeff
2475219820Sjeffstatic void __parser_sl2vl_scope_start()
2476219820Sjeff{
2477219820Sjeff    p_current_sl2vl_scope = osm_qos_policy_sl2vl_scope_create();
2478219820Sjeff}
2479219820Sjeff
2480219820Sjeff/***************************************************
2481219820Sjeff ***************************************************/
2482219820Sjeff
2483219820Sjeffstatic int __parser_sl2vl_scope_end()
2484219820Sjeff{
2485219820Sjeff    if (!p_current_sl2vl_scope->sl2vl_table_set)
2486219820Sjeff    {
2487219820Sjeff        yyerror("sl2vl-scope validation failed - no sl2vl table specified");
2488219820Sjeff        return -1;
2489219820Sjeff    }
2490219820Sjeff    if ( !cl_list_count(&p_current_sl2vl_scope->group_list) &&
2491219820Sjeff         !cl_list_count(&p_current_sl2vl_scope->across_to_list) &&
2492219820Sjeff         !cl_list_count(&p_current_sl2vl_scope->across_from_list) )
2493219820Sjeff    {
2494219820Sjeff        yyerror("sl2vl-scope validation failed - no port groups specified by 'group', 'across-to' or 'across-from'");
2495219820Sjeff        return -1;
2496219820Sjeff    }
2497219820Sjeff
2498219820Sjeff    cl_list_insert_tail(&p_qos_policy->sl2vl_tables,
2499219820Sjeff                        p_current_sl2vl_scope);
2500219820Sjeff    p_current_sl2vl_scope = NULL;
2501219820Sjeff    return 0;
2502219820Sjeff}
2503219820Sjeff
2504219820Sjeff/***************************************************
2505219820Sjeff ***************************************************/
2506219820Sjeff
2507219820Sjeffstatic void __parser_qos_level_start()
2508219820Sjeff{
2509219820Sjeff    p_current_qos_level = osm_qos_policy_qos_level_create();
2510219820Sjeff}
2511219820Sjeff
2512219820Sjeff/***************************************************
2513219820Sjeff ***************************************************/
2514219820Sjeff
2515219820Sjeffstatic int __parser_qos_level_end()
2516219820Sjeff{
2517219820Sjeff    if (!p_current_qos_level->sl_set)
2518219820Sjeff    {
2519219820Sjeff        yyerror("qos-level validation failed - no 'sl' specified");
2520219820Sjeff        return -1;
2521219820Sjeff    }
2522219820Sjeff    if (!p_current_qos_level->name)
2523219820Sjeff    {
2524219820Sjeff        yyerror("qos-level validation failed - no 'name' specified");
2525219820Sjeff        return -1;
2526219820Sjeff    }
2527219820Sjeff
2528219820Sjeff    cl_list_insert_tail(&p_qos_policy->qos_levels,
2529219820Sjeff                        p_current_qos_level);
2530219820Sjeff    p_current_qos_level = NULL;
2531219820Sjeff    return 0;
2532219820Sjeff}
2533219820Sjeff
2534219820Sjeff/***************************************************
2535219820Sjeff ***************************************************/
2536219820Sjeff
2537219820Sjeffstatic void __parser_match_rule_start()
2538219820Sjeff{
2539219820Sjeff    p_current_qos_match_rule = osm_qos_policy_match_rule_create();
2540219820Sjeff}
2541219820Sjeff
2542219820Sjeff/***************************************************
2543219820Sjeff ***************************************************/
2544219820Sjeff
2545219820Sjeffstatic int __parser_match_rule_end()
2546219820Sjeff{
2547219820Sjeff    if (!p_current_qos_match_rule->qos_level_name)
2548219820Sjeff    {
2549219820Sjeff        yyerror("match-rule validation failed - no 'qos-level-name' specified");
2550219820Sjeff        return -1;
2551219820Sjeff    }
2552219820Sjeff
2553219820Sjeff    cl_list_insert_tail(&p_qos_policy->qos_match_rules,
2554219820Sjeff                        p_current_qos_match_rule);
2555219820Sjeff    p_current_qos_match_rule = NULL;
2556219820Sjeff    return 0;
2557219820Sjeff}
2558219820Sjeff
2559219820Sjeff/***************************************************
2560219820Sjeff ***************************************************/
2561219820Sjeff
2562219820Sjeffstatic void __parser_ulp_match_rule_start()
2563219820Sjeff{
2564219820Sjeff    p_current_qos_match_rule = osm_qos_policy_match_rule_create();
2565219820Sjeff}
2566219820Sjeff
2567219820Sjeff/***************************************************
2568219820Sjeff ***************************************************/
2569219820Sjeff
2570219820Sjeffstatic int __parser_ulp_match_rule_end()
2571219820Sjeff{
2572219820Sjeff    CL_ASSERT(p_current_qos_match_rule->p_qos_level);
2573219820Sjeff    cl_list_insert_tail(&__ulp_match_rules,
2574219820Sjeff                        p_current_qos_match_rule);
2575219820Sjeff    p_current_qos_match_rule = NULL;
2576219820Sjeff    return 0;
2577219820Sjeff}
2578219820Sjeff
2579219820Sjeff/***************************************************
2580219820Sjeff ***************************************************/
2581219820Sjeff
2582219820Sjeffstatic void __parser_tmp_struct_init()
2583219820Sjeff{
2584219820Sjeff    tmp_parser_struct.str[0] = '\0';
2585219820Sjeff    cl_list_construct(&tmp_parser_struct.str_list);
2586219820Sjeff    cl_list_init(&tmp_parser_struct.str_list, 10);
2587219820Sjeff    cl_list_construct(&tmp_parser_struct.num_list);
2588219820Sjeff    cl_list_init(&tmp_parser_struct.num_list, 10);
2589219820Sjeff    cl_list_construct(&tmp_parser_struct.num_pair_list);
2590219820Sjeff    cl_list_init(&tmp_parser_struct.num_pair_list, 10);
2591219820Sjeff}
2592219820Sjeff
2593219820Sjeff/***************************************************
2594219820Sjeff ***************************************************/
2595219820Sjeff
2596219820Sjeff/*
2597219820Sjeff * Do NOT free objects from the temp struct.
2598219820Sjeff * Either they are inserted into the parse tree data
2599219820Sjeff * structure, or they are already freed when copying
2600219820Sjeff * their values to the parse tree data structure.
2601219820Sjeff */
2602219820Sjeffstatic void __parser_tmp_struct_reset()
2603219820Sjeff{
2604219820Sjeff    tmp_parser_struct.str[0] = '\0';
2605219820Sjeff    cl_list_remove_all(&tmp_parser_struct.str_list);
2606219820Sjeff    cl_list_remove_all(&tmp_parser_struct.num_list);
2607219820Sjeff    cl_list_remove_all(&tmp_parser_struct.num_pair_list);
2608219820Sjeff}
2609219820Sjeff
2610219820Sjeff/***************************************************
2611219820Sjeff ***************************************************/
2612219820Sjeff
2613219820Sjeffstatic void __parser_tmp_struct_destroy()
2614219820Sjeff{
2615219820Sjeff    __parser_tmp_struct_reset();
2616219820Sjeff    cl_list_destroy(&tmp_parser_struct.str_list);
2617219820Sjeff    cl_list_destroy(&tmp_parser_struct.num_list);
2618219820Sjeff    cl_list_destroy(&tmp_parser_struct.num_pair_list);
2619219820Sjeff}
2620219820Sjeff
2621219820Sjeff/***************************************************
2622219820Sjeff ***************************************************/
2623219820Sjeff
2624219820Sjeff#define __SIMPLE_QOS_LEVEL_NAME "SimpleQoSLevel_SL"
2625219820Sjeff#define __SIMPLE_QOS_LEVEL_DEFAULT_NAME "SimpleQoSLevel_DEFAULT"
2626219820Sjeff
2627219820Sjeffstatic void __setup_simple_qos_levels()
2628219820Sjeff{
2629219820Sjeff    uint8_t i;
2630219820Sjeff    char tmp_buf[30];
2631219820Sjeff    memset(osm_qos_policy_simple_qos_levels, 0,
2632219820Sjeff           sizeof(osm_qos_policy_simple_qos_levels));
2633219820Sjeff    for (i = 0; i < 16; i++)
2634219820Sjeff    {
2635219820Sjeff        osm_qos_policy_simple_qos_levels[i].sl = i;
2636219820Sjeff        osm_qos_policy_simple_qos_levels[i].sl_set = TRUE;
2637219820Sjeff        sprintf(tmp_buf, "%s%u", __SIMPLE_QOS_LEVEL_NAME, i);
2638219820Sjeff        osm_qos_policy_simple_qos_levels[i].name = strdup(tmp_buf);
2639219820Sjeff    }
2640219820Sjeff
2641219820Sjeff    memset(&__default_simple_qos_level, 0,
2642219820Sjeff           sizeof(__default_simple_qos_level));
2643219820Sjeff    __default_simple_qos_level.name =
2644219820Sjeff           strdup(__SIMPLE_QOS_LEVEL_DEFAULT_NAME);
2645219820Sjeff}
2646219820Sjeff
2647219820Sjeff/***************************************************
2648219820Sjeff ***************************************************/
2649219820Sjeff
2650219820Sjeffstatic void __clear_simple_qos_levels()
2651219820Sjeff{
2652219820Sjeff    /*
2653219820Sjeff     * Simple QoS levels are static.
2654219820Sjeff     * What's left is to invalidate default simple QoS level.
2655219820Sjeff     */
2656219820Sjeff    __default_simple_qos_level.sl_set = FALSE;
2657219820Sjeff}
2658219820Sjeff
2659219820Sjeff/***************************************************
2660219820Sjeff ***************************************************/
2661219820Sjeff
2662219820Sjeffstatic void __setup_ulp_match_rules()
2663219820Sjeff{
2664219820Sjeff    cl_list_construct(&__ulp_match_rules);
2665219820Sjeff    cl_list_init(&__ulp_match_rules, 10);
2666219820Sjeff}
2667219820Sjeff
2668219820Sjeff/***************************************************
2669219820Sjeff ***************************************************/
2670219820Sjeff
2671219820Sjeffstatic void __process_ulp_match_rules()
2672219820Sjeff{
2673219820Sjeff    cl_list_iterator_t list_iterator;
2674219820Sjeff    osm_qos_match_rule_t *p_qos_match_rule = NULL;
2675219820Sjeff
2676219820Sjeff    list_iterator = cl_list_head(&__ulp_match_rules);
2677219820Sjeff    while (list_iterator != cl_list_end(&__ulp_match_rules))
2678219820Sjeff    {
2679219820Sjeff        p_qos_match_rule = (osm_qos_match_rule_t *) cl_list_obj(list_iterator);
2680219820Sjeff        if (p_qos_match_rule)
2681219820Sjeff            cl_list_insert_tail(&p_qos_policy->qos_match_rules,
2682219820Sjeff                                p_qos_match_rule);
2683219820Sjeff        list_iterator = cl_list_next(list_iterator);
2684219820Sjeff    }
2685219820Sjeff    cl_list_remove_all(&__ulp_match_rules);
2686219820Sjeff}
2687219820Sjeff
2688219820Sjeff/***************************************************
2689219820Sjeff ***************************************************/
2690219820Sjeff
2691219820Sjeffstatic int OSM_CDECL
2692219820Sjeff__cmp_num_range(
2693219820Sjeff    const void * p1,
2694219820Sjeff    const void * p2)
2695219820Sjeff{
2696219820Sjeff    uint64_t * pair1 = *((uint64_t **)p1);
2697219820Sjeff    uint64_t * pair2 = *((uint64_t **)p2);
2698219820Sjeff
2699219820Sjeff    if (pair1[0] < pair2[0])
2700219820Sjeff        return -1;
2701219820Sjeff    if (pair1[0] > pair2[0])
2702219820Sjeff        return 1;
2703219820Sjeff
2704219820Sjeff    if (pair1[1] < pair2[1])
2705219820Sjeff        return -1;
2706219820Sjeff    if (pair1[1] > pair2[1])
2707219820Sjeff        return 1;
2708219820Sjeff
2709219820Sjeff    return 0;
2710219820Sjeff}
2711219820Sjeff
2712219820Sjeff/***************************************************
2713219820Sjeff ***************************************************/
2714219820Sjeff
2715219820Sjeffstatic void __sort_reduce_rangearr(
2716219820Sjeff    uint64_t  **   arr,
2717219820Sjeff    unsigned       arr_len,
2718219820Sjeff    uint64_t  ** * p_res_arr,
2719219820Sjeff    unsigned     * p_res_arr_len )
2720219820Sjeff{
2721219820Sjeff    unsigned i = 0;
2722219820Sjeff    unsigned j = 0;
2723219820Sjeff    unsigned last_valid_ind = 0;
2724219820Sjeff    unsigned valid_cnt = 0;
2725219820Sjeff    uint64_t ** res_arr;
2726219820Sjeff    boolean_t * is_valid_arr;
2727219820Sjeff
2728219820Sjeff    *p_res_arr = NULL;
2729219820Sjeff    *p_res_arr_len = 0;
2730219820Sjeff
2731219820Sjeff    qsort(arr, arr_len, sizeof(uint64_t*), __cmp_num_range);
2732219820Sjeff
2733219820Sjeff    is_valid_arr = (boolean_t *)malloc(arr_len * sizeof(boolean_t));
2734219820Sjeff    is_valid_arr[last_valid_ind] = TRUE;
2735219820Sjeff    valid_cnt++;
2736219820Sjeff    for (i = 1; i < arr_len; i++)
2737219820Sjeff    {
2738219820Sjeff        if (arr[i][0] <= arr[last_valid_ind][1])
2739219820Sjeff        {
2740219820Sjeff            if (arr[i][1] > arr[last_valid_ind][1])
2741219820Sjeff                arr[last_valid_ind][1] = arr[i][1];
2742219820Sjeff            free(arr[i]);
2743219820Sjeff            arr[i] = NULL;
2744219820Sjeff            is_valid_arr[i] = FALSE;
2745219820Sjeff        }
2746219820Sjeff        else if ((arr[i][0] - 1) == arr[last_valid_ind][1])
2747219820Sjeff        {
2748219820Sjeff            arr[last_valid_ind][1] = arr[i][1];
2749219820Sjeff            free(arr[i]);
2750219820Sjeff            arr[i] = NULL;
2751219820Sjeff            is_valid_arr[i] = FALSE;
2752219820Sjeff        }
2753219820Sjeff        else
2754219820Sjeff        {
2755219820Sjeff            is_valid_arr[i] = TRUE;
2756219820Sjeff            last_valid_ind = i;
2757219820Sjeff            valid_cnt++;
2758219820Sjeff        }
2759219820Sjeff    }
2760219820Sjeff
2761219820Sjeff    res_arr = (uint64_t **)malloc(valid_cnt * sizeof(uint64_t *));
2762219820Sjeff    for (i = 0; i < arr_len; i++)
2763219820Sjeff    {
2764219820Sjeff        if (is_valid_arr[i])
2765219820Sjeff            res_arr[j++] = arr[i];
2766219820Sjeff    }
2767219820Sjeff    free(is_valid_arr);
2768219820Sjeff    free(arr);
2769219820Sjeff
2770219820Sjeff    *p_res_arr = res_arr;
2771219820Sjeff    *p_res_arr_len = valid_cnt;
2772219820Sjeff}
2773219820Sjeff
2774219820Sjeff/***************************************************
2775219820Sjeff ***************************************************/
2776219820Sjeff
2777219820Sjeffstatic void __pkey_rangelist2rangearr(
2778219820Sjeff    cl_list_t    * p_list,
2779219820Sjeff    uint64_t  ** * p_arr,
2780219820Sjeff    unsigned     * p_arr_len)
2781219820Sjeff{
2782219820Sjeff    uint64_t   tmp_pkey;
2783219820Sjeff    uint64_t * p_pkeys;
2784219820Sjeff    cl_list_iterator_t list_iterator;
2785219820Sjeff
2786219820Sjeff    list_iterator= cl_list_head(p_list);
2787219820Sjeff    while( list_iterator != cl_list_end(p_list) )
2788219820Sjeff    {
2789219820Sjeff       p_pkeys = (uint64_t *)cl_list_obj(list_iterator);
2790219820Sjeff       p_pkeys[0] &= 0x7fff;
2791219820Sjeff       p_pkeys[1] &= 0x7fff;
2792219820Sjeff       if (p_pkeys[0] > p_pkeys[1])
2793219820Sjeff       {
2794219820Sjeff           tmp_pkey = p_pkeys[1];
2795219820Sjeff           p_pkeys[1] = p_pkeys[0];
2796219820Sjeff           p_pkeys[0] = tmp_pkey;
2797219820Sjeff       }
2798219820Sjeff       list_iterator = cl_list_next(list_iterator);
2799219820Sjeff    }
2800219820Sjeff
2801219820Sjeff    __rangelist2rangearr(p_list, p_arr, p_arr_len);
2802219820Sjeff}
2803219820Sjeff
2804219820Sjeff/***************************************************
2805219820Sjeff ***************************************************/
2806219820Sjeff
2807219820Sjeffstatic void __rangelist2rangearr(
2808219820Sjeff    cl_list_t    * p_list,
2809219820Sjeff    uint64_t  ** * p_arr,
2810219820Sjeff    unsigned     * p_arr_len)
2811219820Sjeff{
2812219820Sjeff    cl_list_iterator_t list_iterator;
2813219820Sjeff    unsigned len = cl_list_count(p_list);
2814219820Sjeff    unsigned i = 0;
2815219820Sjeff    uint64_t ** tmp_arr;
2816219820Sjeff    uint64_t ** res_arr = NULL;
2817219820Sjeff    unsigned res_arr_len = 0;
2818219820Sjeff
2819219820Sjeff    tmp_arr = (uint64_t **)malloc(len * sizeof(uint64_t *));
2820219820Sjeff
2821219820Sjeff    list_iterator = cl_list_head(p_list);
2822219820Sjeff    while( list_iterator != cl_list_end(p_list) )
2823219820Sjeff    {
2824219820Sjeff       tmp_arr[i++] = (uint64_t *)cl_list_obj(list_iterator);
2825219820Sjeff       list_iterator = cl_list_next(list_iterator);
2826219820Sjeff    }
2827219820Sjeff    cl_list_remove_all(p_list);
2828219820Sjeff
2829219820Sjeff    __sort_reduce_rangearr( tmp_arr,
2830219820Sjeff                            len,
2831219820Sjeff                            &res_arr,
2832219820Sjeff                            &res_arr_len );
2833219820Sjeff    *p_arr = res_arr;
2834219820Sjeff    *p_arr_len = res_arr_len;
2835219820Sjeff}
2836219820Sjeff
2837219820Sjeff/***************************************************
2838219820Sjeff ***************************************************/
2839219820Sjeff
2840219820Sjeffstatic void __merge_rangearr(
2841219820Sjeff    uint64_t  **   range_arr_1,
2842219820Sjeff    unsigned       range_len_1,
2843219820Sjeff    uint64_t  **   range_arr_2,
2844219820Sjeff    unsigned       range_len_2,
2845219820Sjeff    uint64_t  ** * p_arr,
2846219820Sjeff    unsigned     * p_arr_len )
2847219820Sjeff{
2848219820Sjeff    unsigned i = 0;
2849219820Sjeff    unsigned j = 0;
2850219820Sjeff    unsigned len = range_len_1 + range_len_2;
2851219820Sjeff    uint64_t ** tmp_arr;
2852219820Sjeff    uint64_t ** res_arr = NULL;
2853219820Sjeff    unsigned res_arr_len = 0;
2854219820Sjeff
2855219820Sjeff    *p_arr = NULL;
2856219820Sjeff    *p_arr_len = 0;
2857219820Sjeff
2858219820Sjeff    tmp_arr = (uint64_t **)malloc(len * sizeof(uint64_t *));
2859219820Sjeff
2860219820Sjeff    for (i = 0; i < range_len_1; i++)
2861219820Sjeff       tmp_arr[j++] = range_arr_1[i];
2862219820Sjeff    for (i = 0; i < range_len_2; i++)
2863219820Sjeff       tmp_arr[j++] = range_arr_2[i];
2864219820Sjeff    free(range_arr_1);
2865219820Sjeff    free(range_arr_2);
2866219820Sjeff
2867219820Sjeff    __sort_reduce_rangearr( tmp_arr,
2868219820Sjeff                            len,
2869219820Sjeff                            &res_arr,
2870219820Sjeff                            &res_arr_len );
2871219820Sjeff    *p_arr = res_arr;
2872219820Sjeff    *p_arr_len = res_arr_len;
2873219820Sjeff}
2874219820Sjeff
2875219820Sjeff/***************************************************
2876219820Sjeff ***************************************************/
2877219820Sjeff
2878219820Sjeffstatic void __parser_add_port_to_port_map(
2879219820Sjeff    cl_qmap_t   * p_map,
2880219820Sjeff    osm_physp_t * p_physp)
2881219820Sjeff{
2882219820Sjeff    if (cl_qmap_get(p_map, cl_ntoh64(osm_physp_get_port_guid(p_physp))) ==
2883219820Sjeff        cl_qmap_end(p_map))
2884219820Sjeff    {
2885219820Sjeff        osm_qos_port_t * p_port = osm_qos_policy_port_create(p_physp);
2886219820Sjeff        if (p_port)
2887219820Sjeff            cl_qmap_insert(p_map,
2888219820Sjeff                           cl_ntoh64(osm_physp_get_port_guid(p_physp)),
2889219820Sjeff                           &p_port->map_item);
2890219820Sjeff    }
2891219820Sjeff}
2892219820Sjeff
2893219820Sjeff/***************************************************
2894219820Sjeff ***************************************************/
2895219820Sjeff
2896219820Sjeffstatic void __parser_add_guid_range_to_port_map(
2897219820Sjeff    cl_qmap_t  * p_map,
2898219820Sjeff    uint64_t  ** range_arr,
2899219820Sjeff    unsigned     range_len)
2900219820Sjeff{
2901219820Sjeff    unsigned i;
2902219820Sjeff    uint64_t guid_ho;
2903219820Sjeff    osm_port_t * p_osm_port;
2904219820Sjeff
2905219820Sjeff    if (!range_arr || !range_len)
2906219820Sjeff        return;
2907219820Sjeff
2908219820Sjeff    for (i = 0; i < range_len; i++) {
2909219820Sjeff         for (guid_ho = range_arr[i][0]; guid_ho <= range_arr[i][1]; guid_ho++) {
2910219820Sjeff             p_osm_port =
2911219820Sjeff                osm_get_port_by_guid(p_qos_policy->p_subn, cl_hton64(guid_ho));
2912219820Sjeff             if (p_osm_port)
2913219820Sjeff                 __parser_add_port_to_port_map(p_map, p_osm_port->p_physp);
2914219820Sjeff         }
2915219820Sjeff         free(range_arr[i]);
2916219820Sjeff    }
2917219820Sjeff    free(range_arr);
2918219820Sjeff}
2919219820Sjeff
2920219820Sjeff/***************************************************
2921219820Sjeff ***************************************************/
2922219820Sjeff
2923219820Sjeffstatic void __parser_add_pkey_range_to_port_map(
2924219820Sjeff    cl_qmap_t  * p_map,
2925219820Sjeff    uint64_t  ** range_arr,
2926219820Sjeff    unsigned     range_len)
2927219820Sjeff{
2928219820Sjeff    unsigned i;
2929219820Sjeff    uint64_t pkey_64;
2930219820Sjeff    ib_net16_t pkey;
2931219820Sjeff    osm_prtn_t * p_prtn;
2932219820Sjeff
2933219820Sjeff    if (!range_arr || !range_len)
2934219820Sjeff        return;
2935219820Sjeff
2936219820Sjeff    for (i = 0; i < range_len; i++) {
2937219820Sjeff         for (pkey_64 = range_arr[i][0]; pkey_64 <= range_arr[i][1]; pkey_64++) {
2938219820Sjeff             pkey = cl_hton16((uint16_t)(pkey_64 & 0x7fff));
2939219820Sjeff             p_prtn = (osm_prtn_t *)
2940219820Sjeff                 cl_qmap_get(&p_qos_policy->p_subn->prtn_pkey_tbl, pkey);
2941219820Sjeff             if (p_prtn != (osm_prtn_t *)cl_qmap_end(
2942219820Sjeff                   &p_qos_policy->p_subn->prtn_pkey_tbl)) {
2943219820Sjeff                 __parser_add_map_to_port_map(p_map, &p_prtn->part_guid_tbl);
2944219820Sjeff                 __parser_add_map_to_port_map(p_map, &p_prtn->full_guid_tbl);
2945219820Sjeff             }
2946219820Sjeff         }
2947219820Sjeff         free(range_arr[i]);
2948219820Sjeff    }
2949219820Sjeff    free(range_arr);
2950219820Sjeff}
2951219820Sjeff
2952219820Sjeff/***************************************************
2953219820Sjeff ***************************************************/
2954219820Sjeff
2955219820Sjeffstatic void __parser_add_partition_list_to_port_map(
2956219820Sjeff    cl_qmap_t  * p_map,
2957219820Sjeff    cl_list_t  * p_list)
2958219820Sjeff{
2959219820Sjeff    cl_list_iterator_t    list_iterator;
2960219820Sjeff    char                * tmp_str;
2961219820Sjeff    osm_prtn_t          * p_prtn;
2962219820Sjeff
2963219820Sjeff    /* extract all the ports from the partition
2964219820Sjeff       to the port map of this port group */
2965219820Sjeff    list_iterator = cl_list_head(p_list);
2966219820Sjeff    while(list_iterator != cl_list_end(p_list)) {
2967219820Sjeff        tmp_str = (char*)cl_list_obj(list_iterator);
2968219820Sjeff        if (tmp_str) {
2969219820Sjeff            p_prtn = osm_prtn_find_by_name(p_qos_policy->p_subn, tmp_str);
2970219820Sjeff            if (p_prtn) {
2971219820Sjeff                __parser_add_map_to_port_map(p_map, &p_prtn->part_guid_tbl);
2972219820Sjeff                __parser_add_map_to_port_map(p_map, &p_prtn->full_guid_tbl);
2973219820Sjeff            }
2974219820Sjeff            free(tmp_str);
2975219820Sjeff        }
2976219820Sjeff        list_iterator = cl_list_next(list_iterator);
2977219820Sjeff    }
2978219820Sjeff    cl_list_remove_all(p_list);
2979219820Sjeff}
2980219820Sjeff
2981219820Sjeff/***************************************************
2982219820Sjeff ***************************************************/
2983219820Sjeff
2984219820Sjeffstatic void __parser_add_map_to_port_map(
2985219820Sjeff    cl_qmap_t * p_dmap,
2986219820Sjeff    cl_map_t  * p_smap)
2987219820Sjeff{
2988219820Sjeff    cl_map_iterator_t map_iterator;
2989219820Sjeff    osm_physp_t * p_physp;
2990219820Sjeff
2991219820Sjeff    if (!p_dmap || !p_smap)
2992219820Sjeff        return;
2993219820Sjeff
2994219820Sjeff    map_iterator = cl_map_head(p_smap);
2995219820Sjeff    while (map_iterator != cl_map_end(p_smap)) {
2996219820Sjeff        p_physp = (osm_physp_t*)cl_map_obj(map_iterator);
2997219820Sjeff        __parser_add_port_to_port_map(p_dmap, p_physp);
2998219820Sjeff        map_iterator = cl_map_next(map_iterator);
2999219820Sjeff    }
3000219820Sjeff}
3001219820Sjeff
3002219820Sjeff/***************************************************
3003219820Sjeff ***************************************************/
3004219820Sjeff
3005219820Sjeffstatic int __validate_pkeys( uint64_t ** range_arr,
3006219820Sjeff                             unsigned    range_len,
3007219820Sjeff                             boolean_t   is_ipoib)
3008219820Sjeff{
3009219820Sjeff    unsigned i;
3010219820Sjeff    uint64_t pkey_64;
3011219820Sjeff    ib_net16_t pkey;
3012219820Sjeff    osm_prtn_t * p_prtn;
3013219820Sjeff
3014219820Sjeff    if (!range_arr || !range_len)
3015219820Sjeff        return 0;
3016219820Sjeff
3017219820Sjeff    for (i = 0; i < range_len; i++) {
3018219820Sjeff        for (pkey_64 = range_arr[i][0]; pkey_64 <= range_arr[i][1]; pkey_64++) {
3019219820Sjeff            pkey = cl_hton16((uint16_t)(pkey_64 & 0x7fff));
3020219820Sjeff            p_prtn = (osm_prtn_t *)
3021219820Sjeff                cl_qmap_get(&p_qos_policy->p_subn->prtn_pkey_tbl, pkey);
3022219820Sjeff
3023219820Sjeff            if (p_prtn == (osm_prtn_t *)cl_qmap_end(
3024219820Sjeff                  &p_qos_policy->p_subn->prtn_pkey_tbl))
3025219820Sjeff                p_prtn = NULL;
3026219820Sjeff
3027219820Sjeff            if (is_ipoib) {
3028219820Sjeff                /*
3029219820Sjeff                 * Be very strict for IPoIB partition:
3030219820Sjeff                 *  - the partition for the pkey have to exist
3031219820Sjeff                 *  - it has to have at least 2 full members
3032219820Sjeff                 */
3033219820Sjeff                if (!p_prtn) {
3034219820Sjeff                    yyerror("IPoIB partition, pkey 0x%04X - "
3035219820Sjeff                                       "partition doesn't exist",
3036219820Sjeff                                       cl_ntoh16(pkey));
3037219820Sjeff                    return 1;
3038219820Sjeff                }
3039219820Sjeff                else if (cl_map_count(&p_prtn->full_guid_tbl) < 2) {
3040219820Sjeff                    yyerror("IPoIB partition, pkey 0x%04X - "
3041219820Sjeff                                       "partition has less than two full members",
3042219820Sjeff                                       cl_ntoh16(pkey));
3043219820Sjeff                    return 1;
3044219820Sjeff                }
3045219820Sjeff            }
3046219820Sjeff            else if (!p_prtn) {
3047219820Sjeff                /*
3048219820Sjeff                 * For non-IPoIB pkey we just want to check that
3049219820Sjeff                 * the relevant partition exists.
3050219820Sjeff                 * And even if it doesn't, don't exit - just print
3051219820Sjeff                 * error message and continue.
3052219820Sjeff                 */
3053219820Sjeff                 OSM_LOG(p_qos_parser_osm_log, OSM_LOG_ERROR, "ERR AC02: "
3054219820Sjeff			 "pkey 0x%04X - partition doesn't exist",
3055219820Sjeff                         cl_ntoh16(pkey));
3056219820Sjeff            }
3057219820Sjeff        }
3058219820Sjeff    }
3059219820Sjeff    return 0;
3060219820Sjeff}
3061219820Sjeff
3062219820Sjeff/***************************************************
3063219820Sjeff ***************************************************/
3064