1321936Shselasky%{
2321936Shselasky/*
3321936Shselasky * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved.
4321936Shselasky * Copyright (c) 2002-2008 Mellanox Technologies LTD. All rights reserved.
5321936Shselasky * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
6321936Shselasky * Copyright (c) 2008 HNR Consulting. All rights reserved.
7321936Shselasky *
8321936Shselasky * This software is available to you under a choice of one of two
9321936Shselasky * licenses.  You may choose to be licensed under the terms of the GNU
10321936Shselasky * General Public License (GPL) Version 2, available from the file
11321936Shselasky * COPYING in the main directory of this source tree, or the
12321936Shselasky * OpenIB.org BSD license below:
13321936Shselasky *
14321936Shselasky *     Redistribution and use in source and binary forms, with or
15321936Shselasky *     without modification, are permitted provided that the following
16321936Shselasky *     conditions are met:
17321936Shselasky *
18321936Shselasky *      - Redistributions of source code must retain the above
19321936Shselasky *        copyright notice, this list of conditions and the following
20321936Shselasky *        disclaimer.
21321936Shselasky *
22321936Shselasky *      - Redistributions in binary form must reproduce the above
23321936Shselasky *        copyright notice, this list of conditions and the following
24321936Shselasky *        disclaimer in the documentation and/or other materials
25321936Shselasky *        provided with the distribution.
26321936Shselasky *
27321936Shselasky * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28321936Shselasky * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29321936Shselasky * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30321936Shselasky * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
31321936Shselasky * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
32321936Shselasky * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
33321936Shselasky * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
34321936Shselasky * SOFTWARE.
35321936Shselasky *
36321936Shselasky */
37321936Shselasky
38321936Shselasky/*
39321936Shselasky * Abstract:
40321936Shselasky *    Grammar of OSM QoS parser.
41321936Shselasky *
42321936Shselasky * Environment:
43321936Shselasky *    Linux User Mode
44321936Shselasky *
45321936Shselasky * Author:
46321936Shselasky *    Yevgeny Kliteynik, Mellanox
47321936Shselasky */
48321936Shselasky
49321936Shselasky#include <stdio.h>
50321936Shselasky#include <assert.h>
51321936Shselasky#include <stdarg.h>
52321936Shselasky#include <stdlib.h>
53321936Shselasky#include <string.h>
54321936Shselasky#include <ctype.h>
55321936Shselasky#include <errno.h>
56321936Shselasky#include <opensm/osm_file_ids.h>
57321936Shselasky#define FILE_ID OSM_FILE_QOS_PARSER_Y_Y
58321936Shselasky#include <opensm/osm_opensm.h>
59321936Shselasky#include <opensm/osm_qos_policy.h>
60321936Shselasky
61321936Shselasky#define OSM_QOS_POLICY_MAX_LINE_LEN         1024*10
62321936Shselasky#define OSM_QOS_POLICY_SL2VL_TABLE_LEN      IB_MAX_NUM_VLS
63321936Shselasky#define OSM_QOS_POLICY_MAX_VL_NUM           IB_MAX_NUM_VLS
64321936Shselasky#define OSM_QOS_POLICY_MAX_RATE             IB_MAX_RATE
65321936Shselasky#define OSM_QOS_POLICY_MIN_RATE             IB_MIN_RATE
66321936Shselasky#define OSM_QOS_POLICY_MAX_MTU              IB_MAX_MTU
67321936Shselasky#define OSM_QOS_POLICY_MIN_MTU              IB_MIN_MTU
68321936Shselasky
69321936Shselaskytypedef struct tmp_parser_struct_t_ {
70321936Shselasky    char       str[OSM_QOS_POLICY_MAX_LINE_LEN];
71321936Shselasky    uint64_t   num_pair[2];
72321936Shselasky    cl_list_t  str_list;
73321936Shselasky    cl_list_t  num_list;
74321936Shselasky    cl_list_t  num_pair_list;
75321936Shselasky} tmp_parser_struct_t;
76321936Shselasky
77321936Shselaskystatic void __parser_tmp_struct_init();
78321936Shselaskystatic void __parser_tmp_struct_reset();
79321936Shselaskystatic void __parser_tmp_struct_destroy();
80321936Shselasky
81321936Shselaskystatic char * __parser_strip_white(char * str);
82321936Shselasky
83321936Shselaskystatic void __parser_str2uint64(uint64_t * p_val, char * str);
84321936Shselasky
85321936Shselaskystatic void __parser_port_group_start();
86321936Shselaskystatic int __parser_port_group_end();
87321936Shselasky
88321936Shselaskystatic void __parser_sl2vl_scope_start();
89321936Shselaskystatic int __parser_sl2vl_scope_end();
90321936Shselasky
91321936Shselaskystatic void __parser_vlarb_scope_start();
92321936Shselaskystatic int __parser_vlarb_scope_end();
93321936Shselasky
94321936Shselaskystatic void __parser_qos_level_start();
95321936Shselaskystatic int __parser_qos_level_end();
96321936Shselasky
97321936Shselaskystatic void __parser_match_rule_start();
98321936Shselaskystatic int __parser_match_rule_end();
99321936Shselasky
100321936Shselaskystatic void __parser_ulp_match_rule_start();
101321936Shselaskystatic int __parser_ulp_match_rule_end();
102321936Shselasky
103321936Shselaskystatic void __pkey_rangelist2rangearr(
104321936Shselasky    cl_list_t    * p_list,
105321936Shselasky    uint64_t  ** * p_arr,
106321936Shselasky    unsigned     * p_arr_len);
107321936Shselasky
108321936Shselaskystatic void __rangelist2rangearr(
109321936Shselasky    cl_list_t    * p_list,
110321936Shselasky    uint64_t  ** * p_arr,
111321936Shselasky    unsigned     * p_arr_len);
112321936Shselasky
113321936Shselaskystatic void __merge_rangearr(
114321936Shselasky    uint64_t  **   range_arr_1,
115321936Shselasky    unsigned       range_len_1,
116321936Shselasky    uint64_t  **   range_arr_2,
117321936Shselasky    unsigned       range_len_2,
118321936Shselasky    uint64_t  ** * p_arr,
119321936Shselasky    unsigned     * p_arr_len );
120321936Shselasky
121321936Shselaskystatic void __parser_add_port_to_port_map(
122321936Shselasky    cl_qmap_t   * p_map,
123321936Shselasky    osm_physp_t * p_physp);
124321936Shselasky
125321936Shselaskystatic void __parser_add_guid_range_to_port_map(
126321936Shselasky    cl_qmap_t  * p_map,
127321936Shselasky    uint64_t  ** range_arr,
128321936Shselasky    unsigned     range_len);
129321936Shselasky
130321936Shselaskystatic void __parser_add_pkey_range_to_port_map(
131321936Shselasky    cl_qmap_t  * p_map,
132321936Shselasky    uint64_t  ** range_arr,
133321936Shselasky    unsigned     range_len);
134321936Shselasky
135321936Shselaskystatic void __parser_add_partition_list_to_port_map(
136321936Shselasky    cl_qmap_t  * p_map,
137321936Shselasky    cl_list_t  * p_list);
138321936Shselasky
139321936Shselaskystatic void __parser_add_map_to_port_map(
140321936Shselasky    cl_qmap_t * p_dmap,
141321936Shselasky    cl_map_t  * p_smap);
142321936Shselasky
143321936Shselaskystatic int __validate_pkeys(
144321936Shselasky    uint64_t ** range_arr,
145321936Shselasky    unsigned    range_len,
146321936Shselasky    boolean_t   is_ipoib);
147321936Shselasky
148321936Shselaskystatic void __setup_simple_qos_levels();
149321936Shselaskystatic void __clear_simple_qos_levels();
150321936Shselaskystatic void __setup_ulp_match_rules();
151321936Shselaskystatic void __process_ulp_match_rules();
152321936Shselaskystatic void yyerror(const char *format, ...);
153321936Shselasky
154321936Shselaskyextern char * yytext;
155321936Shselaskyextern int yylex (void);
156321936Shselaskyextern FILE * yyin;
157321936Shselaskyextern int errno;
158321936Shselaskyextern void yyrestart(FILE *input_file);
159321936Shselaskyint yyparse();
160321936Shselasky
161321936Shselasky#define RESET_BUFFER  __parser_tmp_struct_reset()
162321936Shselasky
163321936Shselaskytmp_parser_struct_t tmp_parser_struct;
164321936Shselasky
165321936Shselaskyint column_num;
166321936Shselaskyint line_num;
167321936Shselasky
168321936Shselaskyosm_qos_policy_t       * p_qos_policy = NULL;
169321936Shselaskyosm_qos_port_group_t   * p_current_port_group = NULL;
170321936Shselaskyosm_qos_sl2vl_scope_t  * p_current_sl2vl_scope = NULL;
171321936Shselaskyosm_qos_vlarb_scope_t  * p_current_vlarb_scope = NULL;
172321936Shselaskyosm_qos_level_t        * p_current_qos_level = NULL;
173321936Shselaskyosm_qos_match_rule_t   * p_current_qos_match_rule = NULL;
174321936Shselaskyosm_log_t              * p_qos_parser_osm_log;
175321936Shselasky
176321936Shselasky/* 16 Simple QoS Levels - one for each SL */
177321936Shselaskystatic osm_qos_level_t osm_qos_policy_simple_qos_levels[16];
178321936Shselasky
179321936Shselasky/* Default Simple QoS Level */
180321936Shselaskyosm_qos_level_t __default_simple_qos_level;
181321936Shselasky
182321936Shselasky/*
183321936Shselasky * List of match rules that will be generated by the
184321936Shselasky * qos-ulp section. These rules are concatenated to
185321936Shselasky * the end of the usual matching rules list at the
186321936Shselasky * end of parsing.
187321936Shselasky */
188321936Shselaskystatic cl_list_t __ulp_match_rules;
189321936Shselasky
190321936Shselasky/***************************************************/
191321936Shselasky
192321936Shselasky%}
193321936Shselasky
194321936Shselasky%token TK_NUMBER
195321936Shselasky%token TK_DASH
196321936Shselasky%token TK_DOTDOT
197321936Shselasky%token TK_COMMA
198321936Shselasky%token TK_ASTERISK
199321936Shselasky%token TK_TEXT
200321936Shselasky
201321936Shselasky%token TK_QOS_ULPS_START
202321936Shselasky%token TK_QOS_ULPS_END
203321936Shselasky
204321936Shselasky%token TK_PORT_GROUPS_START
205321936Shselasky%token TK_PORT_GROUPS_END
206321936Shselasky%token TK_PORT_GROUP_START
207321936Shselasky%token TK_PORT_GROUP_END
208321936Shselasky
209321936Shselasky%token TK_QOS_SETUP_START
210321936Shselasky%token TK_QOS_SETUP_END
211321936Shselasky%token TK_VLARB_TABLES_START
212321936Shselasky%token TK_VLARB_TABLES_END
213321936Shselasky%token TK_VLARB_SCOPE_START
214321936Shselasky%token TK_VLARB_SCOPE_END
215321936Shselasky
216321936Shselasky%token TK_SL2VL_TABLES_START
217321936Shselasky%token TK_SL2VL_TABLES_END
218321936Shselasky%token TK_SL2VL_SCOPE_START
219321936Shselasky%token TK_SL2VL_SCOPE_END
220321936Shselasky
221321936Shselasky%token TK_QOS_LEVELS_START
222321936Shselasky%token TK_QOS_LEVELS_END
223321936Shselasky%token TK_QOS_LEVEL_START
224321936Shselasky%token TK_QOS_LEVEL_END
225321936Shselasky
226321936Shselasky%token TK_QOS_MATCH_RULES_START
227321936Shselasky%token TK_QOS_MATCH_RULES_END
228321936Shselasky%token TK_QOS_MATCH_RULE_START
229321936Shselasky%token TK_QOS_MATCH_RULE_END
230321936Shselasky
231321936Shselasky%token TK_NAME
232321936Shselasky%token TK_USE
233321936Shselasky%token TK_PORT_GUID
234321936Shselasky%token TK_PORT_NAME
235321936Shselasky%token TK_PARTITION
236321936Shselasky%token TK_NODE_TYPE
237321936Shselasky%token TK_GROUP
238321936Shselasky%token TK_ACROSS
239321936Shselasky%token TK_VLARB_HIGH
240321936Shselasky%token TK_VLARB_LOW
241321936Shselasky%token TK_VLARB_HIGH_LIMIT
242321936Shselasky%token TK_TO
243321936Shselasky%token TK_FROM
244321936Shselasky%token TK_ACROSS_TO
245321936Shselasky%token TK_ACROSS_FROM
246321936Shselasky%token TK_SL2VL_TABLE
247321936Shselasky%token TK_SL
248321936Shselasky%token TK_MTU_LIMIT
249321936Shselasky%token TK_RATE_LIMIT
250321936Shselasky%token TK_PACKET_LIFE
251321936Shselasky%token TK_PATH_BITS
252321936Shselasky%token TK_QOS_CLASS
253321936Shselasky%token TK_SOURCE
254321936Shselasky%token TK_DESTINATION
255321936Shselasky%token TK_SERVICE_ID
256321936Shselasky%token TK_QOS_LEVEL_NAME
257321936Shselasky%token TK_PKEY
258321936Shselasky
259321936Shselasky%token TK_NODE_TYPE_ROUTER
260321936Shselasky%token TK_NODE_TYPE_CA
261321936Shselasky%token TK_NODE_TYPE_SWITCH
262321936Shselasky%token TK_NODE_TYPE_SELF
263321936Shselasky%token TK_NODE_TYPE_ALL
264321936Shselasky
265321936Shselasky%token TK_ULP_DEFAULT
266321936Shselasky%token TK_ULP_ANY_SERVICE_ID
267321936Shselasky%token TK_ULP_ANY_PKEY
268321936Shselasky%token TK_ULP_ANY_TARGET_PORT_GUID
269321936Shselasky%token TK_ULP_ANY_SOURCE_PORT_GUID
270321936Shselasky%token TK_ULP_ANY_SOURCE_TARGET_PORT_GUID
271321936Shselasky%token TK_ULP_SDP_DEFAULT
272321936Shselasky%token TK_ULP_SDP_PORT
273321936Shselasky%token TK_ULP_RDS_DEFAULT
274321936Shselasky%token TK_ULP_RDS_PORT
275321936Shselasky%token TK_ULP_ISER_DEFAULT
276321936Shselasky%token TK_ULP_ISER_PORT
277321936Shselasky%token TK_ULP_SRP_GUID
278321936Shselasky%token TK_ULP_IPOIB_DEFAULT
279321936Shselasky%token TK_ULP_IPOIB_PKEY
280321936Shselasky
281321936Shselasky%start head
282321936Shselasky
283321936Shselasky%%
284321936Shselasky
285321936Shselaskyhead:               qos_policy_entries
286321936Shselasky                    ;
287321936Shselasky
288321936Shselaskyqos_policy_entries: /* empty */
289321936Shselasky                    | qos_policy_entries qos_policy_entry
290321936Shselasky                    ;
291321936Shselasky
292321936Shselaskyqos_policy_entry:     qos_ulps_section
293321936Shselasky                    | port_groups_section
294321936Shselasky                    | qos_setup_section
295321936Shselasky                    | qos_levels_section
296321936Shselasky                    | qos_match_rules_section
297321936Shselasky                    ;
298321936Shselasky
299321936Shselasky    /*
300321936Shselasky     * Parsing qos-ulps:
301321936Shselasky     * -------------------
302321936Shselasky     *  qos-ulps
303321936Shselasky     *      default                       : 0 #default SL
304321936Shselasky     *      sdp, port-num 30000           : 1 #SL for SDP when destination port is 30000
305321936Shselasky     *      sdp, port-num 10000-20000     : 2
306321936Shselasky     *      sdp                           : 0 #default SL for SDP
307321936Shselasky     *      srp, target-port-guid 0x1234  : 2
308321936Shselasky     *      rds, port-num 25000           : 2 #SL for RDS when destination port is 25000
309321936Shselasky     *      rds,                          : 0 #default SL for RDS
310321936Shselasky     *      iser, port-num 900            : 5 #SL for iSER where target port is 900
311321936Shselasky     *      iser                          : 4 #default SL for iSER
312321936Shselasky     *      ipoib, pkey 0x0001            : 5 #SL for IPoIB on partition with pkey 0x0001
313321936Shselasky     *      ipoib                         : 6 #default IPoIB partition - pkey=0x7FFF
314321936Shselasky     *      any, service-id 0x6234        : 2
315321936Shselasky     *      any, pkey 0x0ABC              : 3
316321936Shselasky     *      any, target-port-guid 0x0ABC-0xFFFFF : 6
317321936Shselasky     *      any, source-port-guid 0x1234  : 7
318321936Shselasky     *      any, source-target-port-guid 0x5678 : 8
319321936Shselasky     *  end-qos-ulps
320321936Shselasky     */
321321936Shselasky
322321936Shselaskyqos_ulps_section: TK_QOS_ULPS_START qos_ulps TK_QOS_ULPS_END
323321936Shselasky                     ;
324321936Shselasky
325321936Shselaskyqos_ulps:             qos_ulp
326321936Shselasky                    | qos_ulps qos_ulp
327321936Shselasky                    ;
328321936Shselasky
329321936Shselasky    /*
330321936Shselasky     * Parsing port groups:
331321936Shselasky     * -------------------
332321936Shselasky     *  port-groups
333321936Shselasky     *       port-group
334321936Shselasky     *          name: Storage
335321936Shselasky     *          use: our SRP storage targets
336321936Shselasky     *          port-guid: 0x1000000000000001,0x1000000000000002
337321936Shselasky     *          ...
338321936Shselasky     *          port-name: vs1 HCA-1/P1
339321936Shselasky     *          port-name: node_description/P2
340321936Shselasky     *          ...
341321936Shselasky     *          pkey: 0x00FF-0x0FFF
342321936Shselasky     *          ...
343321936Shselasky     *          partition: Part1
344321936Shselasky     *          ...
345321936Shselasky     *          node-type: ROUTER,CA,SWITCH,SELF,ALL
346321936Shselasky     *          ...
347321936Shselasky     *      end-port-group
348321936Shselasky     *      port-group
349321936Shselasky     *          ...
350321936Shselasky     *      end-port-group
351321936Shselasky     *  end-port-groups
352321936Shselasky     */
353321936Shselasky
354321936Shselasky
355321936Shselaskyport_groups_section: TK_PORT_GROUPS_START port_groups TK_PORT_GROUPS_END
356321936Shselasky                     ;
357321936Shselasky
358321936Shselaskyport_groups:        port_group
359321936Shselasky                    | port_groups port_group
360321936Shselasky                    ;
361321936Shselasky
362321936Shselaskyport_group:         port_group_start port_group_entries port_group_end
363321936Shselasky                    ;
364321936Shselasky
365321936Shselaskyport_group_start:   TK_PORT_GROUP_START {
366321936Shselasky                        __parser_port_group_start();
367321936Shselasky                    }
368321936Shselasky                    ;
369321936Shselasky
370321936Shselaskyport_group_end:     TK_PORT_GROUP_END {
371321936Shselasky                        if ( __parser_port_group_end() )
372321936Shselasky                            return 1;
373321936Shselasky                    }
374321936Shselasky                    ;
375321936Shselasky
376321936Shselaskyport_group_entries: /* empty */
377321936Shselasky                    | port_group_entries port_group_entry
378321936Shselasky                    ;
379321936Shselasky
380321936Shselaskyport_group_entry:     port_group_name
381321936Shselasky                    | port_group_use
382321936Shselasky                    | port_group_port_guid
383321936Shselasky                    | port_group_port_name
384321936Shselasky                    | port_group_pkey
385321936Shselasky                    | port_group_partition
386321936Shselasky                    | port_group_node_type
387321936Shselasky                    ;
388321936Shselasky
389321936Shselasky
390321936Shselasky    /*
391321936Shselasky     * Parsing qos setup:
392321936Shselasky     * -----------------
393321936Shselasky     *  qos-setup
394321936Shselasky     *      vlarb-tables
395321936Shselasky     *          vlarb-scope
396321936Shselasky     *              ...
397321936Shselasky     *          end-vlarb-scope
398321936Shselasky     *          vlarb-scope
399321936Shselasky     *              ...
400321936Shselasky     *          end-vlarb-scope
401321936Shselasky     *     end-vlarb-tables
402321936Shselasky     *     sl2vl-tables
403321936Shselasky     *          sl2vl-scope
404321936Shselasky     *              ...
405321936Shselasky     *         end-sl2vl-scope
406321936Shselasky     *         sl2vl-scope
407321936Shselasky     *              ...
408321936Shselasky     *          end-sl2vl-scope
409321936Shselasky     *     end-sl2vl-tables
410321936Shselasky     *  end-qos-setup
411321936Shselasky     */
412321936Shselasky
413321936Shselaskyqos_setup_section:  TK_QOS_SETUP_START qos_setup_items TK_QOS_SETUP_END
414321936Shselasky                    ;
415321936Shselasky
416321936Shselaskyqos_setup_items:    /* empty */
417321936Shselasky                    | qos_setup_items vlarb_tables
418321936Shselasky                    | qos_setup_items sl2vl_tables
419321936Shselasky                    ;
420321936Shselasky
421321936Shselasky    /* Parsing vlarb-tables */
422321936Shselasky
423321936Shselaskyvlarb_tables:       TK_VLARB_TABLES_START vlarb_scope_items TK_VLARB_TABLES_END
424321936Shselasky                    ;
425321936Shselasky
426321936Shselaskyvlarb_scope_items:  /* empty */
427321936Shselasky                    | vlarb_scope_items vlarb_scope
428321936Shselasky                    ;
429321936Shselasky
430321936Shselaskyvlarb_scope:        vlarb_scope_start vlarb_scope_entries vlarb_scope_end
431321936Shselasky                    ;
432321936Shselasky
433321936Shselaskyvlarb_scope_start:  TK_VLARB_SCOPE_START {
434321936Shselasky                        __parser_vlarb_scope_start();
435321936Shselasky                    }
436321936Shselasky                    ;
437321936Shselasky
438321936Shselaskyvlarb_scope_end:    TK_VLARB_SCOPE_END {
439321936Shselasky                        if ( __parser_vlarb_scope_end() )
440321936Shselasky                            return 1;
441321936Shselasky                    }
442321936Shselasky                    ;
443321936Shselasky
444321936Shselaskyvlarb_scope_entries:/* empty */
445321936Shselasky                    | vlarb_scope_entries vlarb_scope_entry
446321936Shselasky                    ;
447321936Shselasky
448321936Shselasky    /*
449321936Shselasky     *          vlarb-scope
450321936Shselasky     *              group: Storage
451321936Shselasky     *              ...
452321936Shselasky     *              across: Storage
453321936Shselasky     *              ...
454321936Shselasky     *              vlarb-high: 0:255,1:127,2:63,3:31,4:15,5:7,6:3,7:1
455321936Shselasky     *              vlarb-low: 8:255,9:127,10:63,11:31,12:15,13:7,14:3
456321936Shselasky     *              vl-high-limit: 10
457321936Shselasky     *          end-vlarb-scope
458321936Shselasky     */
459321936Shselasky
460321936Shselaskyvlarb_scope_entry:    vlarb_scope_group
461321936Shselasky                    | vlarb_scope_across
462321936Shselasky                    | vlarb_scope_vlarb_high
463321936Shselasky                    | vlarb_scope_vlarb_low
464321936Shselasky                    | vlarb_scope_vlarb_high_limit
465321936Shselasky                    ;
466321936Shselasky
467321936Shselasky    /* Parsing sl2vl-tables */
468321936Shselasky
469321936Shselaskysl2vl_tables:       TK_SL2VL_TABLES_START sl2vl_scope_items TK_SL2VL_TABLES_END
470321936Shselasky                    ;
471321936Shselasky
472321936Shselaskysl2vl_scope_items:  /* empty */
473321936Shselasky                    | sl2vl_scope_items sl2vl_scope
474321936Shselasky                    ;
475321936Shselasky
476321936Shselaskysl2vl_scope:        sl2vl_scope_start sl2vl_scope_entries sl2vl_scope_end
477321936Shselasky                    ;
478321936Shselasky
479321936Shselaskysl2vl_scope_start:  TK_SL2VL_SCOPE_START {
480321936Shselasky                        __parser_sl2vl_scope_start();
481321936Shselasky                    }
482321936Shselasky                    ;
483321936Shselasky
484321936Shselaskysl2vl_scope_end:    TK_SL2VL_SCOPE_END {
485321936Shselasky                        if ( __parser_sl2vl_scope_end() )
486321936Shselasky                            return 1;
487321936Shselasky                    }
488321936Shselasky                    ;
489321936Shselasky
490321936Shselaskysl2vl_scope_entries:/* empty */
491321936Shselasky                    | sl2vl_scope_entries sl2vl_scope_entry
492321936Shselasky                    ;
493321936Shselasky
494321936Shselasky    /*
495321936Shselasky     *          sl2vl-scope
496321936Shselasky     *              group: Part1
497321936Shselasky     *              ...
498321936Shselasky     *              from: *
499321936Shselasky     *              ...
500321936Shselasky     *              to: *
501321936Shselasky     *              ...
502321936Shselasky     *              across-to: Storage2
503321936Shselasky     *              ...
504321936Shselasky     *              across-from: Storage1
505321936Shselasky     *              ...
506321936Shselasky     *              sl2vl-table: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,7
507321936Shselasky     *          end-sl2vl-scope
508321936Shselasky     */
509321936Shselasky
510321936Shselaskysl2vl_scope_entry:    sl2vl_scope_group
511321936Shselasky                    | sl2vl_scope_across
512321936Shselasky                    | sl2vl_scope_across_from
513321936Shselasky                    | sl2vl_scope_across_to
514321936Shselasky                    | sl2vl_scope_from
515321936Shselasky                    | sl2vl_scope_to
516321936Shselasky                    | sl2vl_scope_sl2vl_table
517321936Shselasky                    ;
518321936Shselasky
519321936Shselasky    /*
520321936Shselasky     * Parsing qos-levels:
521321936Shselasky     * ------------------
522321936Shselasky     *  qos-levels
523321936Shselasky     *      qos-level
524321936Shselasky     *          name: qos_level_1
525321936Shselasky     *          use: for the lowest priority communication
526321936Shselasky     *          sl: 15
527321936Shselasky     *          mtu-limit: 1
528321936Shselasky     *          rate-limit: 1
529321936Shselasky     *          packet-life: 12
530321936Shselasky     *          path-bits: 2,4,8-32
531321936Shselasky     *          pkey: 0x00FF-0x0FFF
532321936Shselasky     *      end-qos-level
533321936Shselasky     *          ...
534321936Shselasky     *      qos-level
535321936Shselasky     *    end-qos-level
536321936Shselasky     *  end-qos-levels
537321936Shselasky     */
538321936Shselasky
539321936Shselasky
540321936Shselaskyqos_levels_section: TK_QOS_LEVELS_START qos_levels TK_QOS_LEVELS_END
541321936Shselasky                    ;
542321936Shselasky
543321936Shselaskyqos_levels:         /* empty */
544321936Shselasky                    | qos_levels qos_level
545321936Shselasky                    ;
546321936Shselasky
547321936Shselaskyqos_level:          qos_level_start qos_level_entries qos_level_end
548321936Shselasky                    ;
549321936Shselasky
550321936Shselaskyqos_level_start:    TK_QOS_LEVEL_START {
551321936Shselasky                        __parser_qos_level_start();
552321936Shselasky                    }
553321936Shselasky                    ;
554321936Shselasky
555321936Shselaskyqos_level_end:      TK_QOS_LEVEL_END {
556321936Shselasky                        if ( __parser_qos_level_end() )
557321936Shselasky                            return 1;
558321936Shselasky                    }
559321936Shselasky                    ;
560321936Shselasky
561321936Shselaskyqos_level_entries:  /* empty */
562321936Shselasky                    | qos_level_entries qos_level_entry
563321936Shselasky                    ;
564321936Shselasky
565321936Shselaskyqos_level_entry:      qos_level_name
566321936Shselasky                    | qos_level_use
567321936Shselasky                    | qos_level_sl
568321936Shselasky                    | qos_level_mtu_limit
569321936Shselasky                    | qos_level_rate_limit
570321936Shselasky                    | qos_level_packet_life
571321936Shselasky                    | qos_level_path_bits
572321936Shselasky                    | qos_level_pkey
573321936Shselasky                    ;
574321936Shselasky
575321936Shselasky    /*
576321936Shselasky     * Parsing qos-match-rules:
577321936Shselasky     * -----------------------
578321936Shselasky     *  qos-match-rules
579321936Shselasky     *      qos-match-rule
580321936Shselasky     *          use: low latency by class 7-9 or 11 and bla bla
581321936Shselasky     *          qos-class: 7-9,11
582321936Shselasky     *          qos-level-name: default
583321936Shselasky     *          source: Storage
584321936Shselasky     *          destination: Storage
585321936Shselasky     *          service-id: 22,4719-5000
586321936Shselasky     *          pkey: 0x00FF-0x0FFF
587321936Shselasky     *      end-qos-match-rule
588321936Shselasky     *      qos-match-rule
589321936Shselasky     *          ...
590321936Shselasky     *      end-qos-match-rule
591321936Shselasky     *  end-qos-match-rules
592321936Shselasky     */
593321936Shselasky
594321936Shselaskyqos_match_rules_section: TK_QOS_MATCH_RULES_START qos_match_rules TK_QOS_MATCH_RULES_END
595321936Shselasky                    ;
596321936Shselasky
597321936Shselaskyqos_match_rules:    /* empty */
598321936Shselasky                    | qos_match_rules qos_match_rule
599321936Shselasky                    ;
600321936Shselasky
601321936Shselaskyqos_match_rule:     qos_match_rule_start qos_match_rule_entries qos_match_rule_end
602321936Shselasky                    ;
603321936Shselasky
604321936Shselaskyqos_match_rule_start: TK_QOS_MATCH_RULE_START {
605321936Shselasky                        __parser_match_rule_start();
606321936Shselasky                    }
607321936Shselasky                    ;
608321936Shselasky
609321936Shselaskyqos_match_rule_end: TK_QOS_MATCH_RULE_END {
610321936Shselasky                        if ( __parser_match_rule_end() )
611321936Shselasky                            return 1;
612321936Shselasky                    }
613321936Shselasky                    ;
614321936Shselasky
615321936Shselaskyqos_match_rule_entries: /* empty */
616321936Shselasky                    | qos_match_rule_entries qos_match_rule_entry
617321936Shselasky                    ;
618321936Shselasky
619321936Shselaskyqos_match_rule_entry: qos_match_rule_use
620321936Shselasky                    | qos_match_rule_qos_class
621321936Shselasky                    | qos_match_rule_qos_level_name
622321936Shselasky                    | qos_match_rule_source
623321936Shselasky                    | qos_match_rule_destination
624321936Shselasky                    | qos_match_rule_service_id
625321936Shselasky                    | qos_match_rule_pkey
626321936Shselasky                    ;
627321936Shselasky
628321936Shselasky
629321936Shselasky    /*
630321936Shselasky     * Parsing qos-ulps:
631321936Shselasky     * -----------------
632321936Shselasky     *   default
633321936Shselasky     *   sdp
634321936Shselasky     *   sdp with port-num
635321936Shselasky     *   rds
636321936Shselasky     *   rds with port-num
637321936Shselasky     *   srp with target-port-guid
638321936Shselasky     *   iser
639321936Shselasky     *   iser with port-num
640321936Shselasky     *   ipoib
641321936Shselasky     *   ipoib with pkey
642321936Shselasky     *   any with service-id
643321936Shselasky     *   any with pkey
644321936Shselasky     *   any with target-port-guid
645321936Shselasky     *   any with source-port-guid
646321936Shselasky     *   any with source-target-port-guid
647321936Shselasky     */
648321936Shselasky
649321936Shselaskyqos_ulp:            TK_ULP_DEFAULT single_number {
650321936Shselasky                        /* parsing default ulp rule: "default: num" */
651321936Shselasky                        cl_list_iterator_t    list_iterator;
652321936Shselasky                        uint64_t            * p_tmp_num;
653321936Shselasky
654321936Shselasky                        list_iterator = cl_list_head(&tmp_parser_struct.num_list);
655321936Shselasky                        p_tmp_num = (uint64_t*)cl_list_obj(list_iterator);
656321936Shselasky                        if (*p_tmp_num > 15)
657321936Shselasky                        {
658321936Shselasky                            yyerror("illegal SL value");
659321936Shselasky                            return 1;
660321936Shselasky                        }
661321936Shselasky                        __default_simple_qos_level.sl = (uint8_t)(*p_tmp_num);
662321936Shselasky                        __default_simple_qos_level.sl_set = TRUE;
663321936Shselasky                        free(p_tmp_num);
664321936Shselasky                        cl_list_remove_all(&tmp_parser_struct.num_list);
665321936Shselasky                    }
666321936Shselasky
667321936Shselasky                    | qos_ulp_type_any_service list_of_ranges TK_DOTDOT {
668321936Shselasky                        /* "any, service-id ... : sl" - one instance of list of ranges */
669321936Shselasky                        uint64_t ** range_arr;
670321936Shselasky                        unsigned    range_len;
671321936Shselasky
672321936Shselasky                        if (!cl_list_count(&tmp_parser_struct.num_pair_list))
673321936Shselasky                        {
674321936Shselasky                            yyerror("ULP rule doesn't have service ids");
675321936Shselasky                            return 1;
676321936Shselasky                        }
677321936Shselasky
678321936Shselasky                        /* get all the service id ranges */
679321936Shselasky                        __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
680321936Shselasky                                              &range_arr,
681321936Shselasky                                              &range_len );
682321936Shselasky
683321936Shselasky                        p_current_qos_match_rule->service_id_range_arr = range_arr;
684321936Shselasky                        p_current_qos_match_rule->service_id_range_len = range_len;
685321936Shselasky
686321936Shselasky                    } qos_ulp_sl
687321936Shselasky
688321936Shselasky                    | qos_ulp_type_any_pkey list_of_ranges TK_DOTDOT {
689321936Shselasky                        /* "any, pkey ... : sl" - one instance of list of ranges */
690321936Shselasky                        uint64_t ** range_arr;
691321936Shselasky                        unsigned    range_len;
692321936Shselasky
693321936Shselasky                        if (!cl_list_count(&tmp_parser_struct.num_pair_list))
694321936Shselasky                        {
695321936Shselasky                            yyerror("ULP rule doesn't have pkeys");
696321936Shselasky                            return 1;
697321936Shselasky                        }
698321936Shselasky
699321936Shselasky                        /* get all the pkey ranges */
700321936Shselasky                        __pkey_rangelist2rangearr( &tmp_parser_struct.num_pair_list,
701321936Shselasky                                              &range_arr,
702321936Shselasky                                              &range_len );
703321936Shselasky
704321936Shselasky                        p_current_qos_match_rule->pkey_range_arr = range_arr;
705321936Shselasky                        p_current_qos_match_rule->pkey_range_len = range_len;
706321936Shselasky
707321936Shselasky                    } qos_ulp_sl
708321936Shselasky
709321936Shselasky                    | qos_ulp_type_any_target_port_guid list_of_ranges TK_DOTDOT {
710321936Shselasky                        /* any, target-port-guid ... : sl */
711321936Shselasky                        uint64_t ** range_arr;
712321936Shselasky                        unsigned    range_len;
713321936Shselasky
714321936Shselasky                        if (!cl_list_count(&tmp_parser_struct.num_pair_list))
715321936Shselasky                        {
716321936Shselasky                            yyerror("ULP rule doesn't have port guids");
717321936Shselasky                            return 1;
718321936Shselasky                        }
719321936Shselasky
720321936Shselasky                        /* create a new port group with these ports */
721321936Shselasky                        __parser_port_group_start();
722321936Shselasky
723321936Shselasky                        p_current_port_group->name = strdup("_ULP_Targets_");
724321936Shselasky                        p_current_port_group->use = strdup("Generated from ULP rules");
725321936Shselasky
726321936Shselasky                        __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
727321936Shselasky                                              &range_arr,
728321936Shselasky                                              &range_len );
729321936Shselasky
730321936Shselasky                        __parser_add_guid_range_to_port_map(
731321936Shselasky                                              &p_current_port_group->port_map,
732321936Shselasky                                              range_arr,
733321936Shselasky                                              range_len);
734321936Shselasky
735321936Shselasky                        /* add this port group to the destination
736321936Shselasky                           groups of the current match rule */
737321936Shselasky                        cl_list_insert_tail(&p_current_qos_match_rule->destination_group_list,
738321936Shselasky                                            p_current_port_group);
739321936Shselasky
740321936Shselasky                        __parser_port_group_end();
741321936Shselasky
742321936Shselasky                    } qos_ulp_sl
743321936Shselasky
744321936Shselasky		    | qos_ulp_type_any_source_port_guid list_of_ranges TK_DOTDOT {
745321936Shselasky			/* any, source-port-guid ... : sl */
746321936Shselasky			uint64_t ** range_arr;
747321936Shselasky			unsigned    range_len;
748321936Shselasky
749321936Shselasky			if (!cl_list_count(&tmp_parser_struct.num_pair_list))
750321936Shselasky			{
751321936Shselasky				yyerror("ULP rule doesn't have port guids");
752321936Shselasky				return 1;
753321936Shselasky			}
754321936Shselasky
755321936Shselasky                        /* create a new port group with these ports */
756321936Shselasky                        __parser_port_group_start();
757321936Shselasky
758321936Shselasky                        p_current_port_group->name = strdup("_ULP_Sources_");
759321936Shselasky                        p_current_port_group->use = strdup("Generated from ULP rules");
760321936Shselasky
761321936Shselasky                        __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
762321936Shselasky                                              &range_arr,
763321936Shselasky                                              &range_len );
764321936Shselasky
765321936Shselasky                        __parser_add_guid_range_to_port_map(
766321936Shselasky                                              &p_current_port_group->port_map,
767321936Shselasky                                              range_arr,
768321936Shselasky                                              range_len);
769321936Shselasky
770321936Shselasky                        /* add this port group to the source
771321936Shselasky                           groups of the current match rule */
772321936Shselasky                        cl_list_insert_tail(&p_current_qos_match_rule->source_group_list,
773321936Shselasky                                            p_current_port_group);
774321936Shselasky
775321936Shselasky                        __parser_port_group_end();
776321936Shselasky
777321936Shselasky		    } qos_ulp_sl
778321936Shselasky
779321936Shselasky		    | qos_ulp_type_any_source_target_port_guid list_of_ranges TK_DOTDOT {
780321936Shselasky			/* any, source-target-port-guid ... : sl */
781321936Shselasky			uint64_t ** range_arr;
782321936Shselasky			unsigned    range_len;
783321936Shselasky
784321936Shselasky			if (!cl_list_count(&tmp_parser_struct.num_pair_list))
785321936Shselasky			{
786321936Shselasky				yyerror("ULP rule doesn't have port guids");
787321936Shselasky				return 1;
788321936Shselasky			}
789321936Shselasky
790321936Shselasky                        /* create a new port group with these ports */
791321936Shselasky                        __parser_port_group_start();
792321936Shselasky
793321936Shselasky                        p_current_port_group->name = strdup("_ULP_Sources_Targets_");
794321936Shselasky                        p_current_port_group->use = strdup("Generated from ULP rules");
795321936Shselasky
796321936Shselasky                        __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
797321936Shselasky                                              &range_arr,
798321936Shselasky                                              &range_len );
799321936Shselasky
800321936Shselasky                        __parser_add_guid_range_to_port_map(
801321936Shselasky                                              &p_current_port_group->port_map,
802321936Shselasky                                              range_arr,
803321936Shselasky                                              range_len);
804321936Shselasky
805321936Shselasky                        /* add this port group to the source and destination
806321936Shselasky                           groups of the current match rule */
807321936Shselasky                        cl_list_insert_tail(&p_current_qos_match_rule->source_group_list,
808321936Shselasky                                            p_current_port_group);
809321936Shselasky
810321936Shselasky                        cl_list_insert_tail(&p_current_qos_match_rule->destination_group_list,
811321936Shselasky                                            p_current_port_group);
812321936Shselasky
813321936Shselasky                        __parser_port_group_end();
814321936Shselasky
815321936Shselasky		    } qos_ulp_sl
816321936Shselasky
817321936Shselasky                    | qos_ulp_type_sdp_default {
818321936Shselasky                        /* "sdp : sl" - default SL for SDP */
819321936Shselasky                        uint64_t ** range_arr =
820321936Shselasky                               (uint64_t **)malloc(sizeof(uint64_t *));
821321936Shselasky                        range_arr[0] = (uint64_t *)malloc(2*sizeof(uint64_t));
822321936Shselasky                        range_arr[0][0] = OSM_QOS_POLICY_ULP_SDP_SERVICE_ID;
823321936Shselasky                        range_arr[0][1] = OSM_QOS_POLICY_ULP_SDP_SERVICE_ID + 0xFFFF;
824321936Shselasky
825321936Shselasky                        p_current_qos_match_rule->service_id_range_arr = range_arr;
826321936Shselasky                        p_current_qos_match_rule->service_id_range_len = 1;
827321936Shselasky
828321936Shselasky                    } qos_ulp_sl
829321936Shselasky
830321936Shselasky                    | qos_ulp_type_sdp_port list_of_ranges TK_DOTDOT {
831321936Shselasky                        /* sdp with port numbers */
832321936Shselasky                        uint64_t ** range_arr;
833321936Shselasky                        unsigned    range_len;
834321936Shselasky                        unsigned    i;
835321936Shselasky
836321936Shselasky                        if (!cl_list_count(&tmp_parser_struct.num_pair_list))
837321936Shselasky                        {
838321936Shselasky                            yyerror("SDP ULP rule doesn't have port numbers");
839321936Shselasky                            return 1;
840321936Shselasky                        }
841321936Shselasky
842321936Shselasky                        /* get all the port ranges */
843321936Shselasky                        __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
844321936Shselasky                                              &range_arr,
845321936Shselasky                                              &range_len );
846321936Shselasky                        /* now translate these port numbers into service ids */
847321936Shselasky                        for (i = 0; i < range_len; i++)
848321936Shselasky                        {
849321936Shselasky                            if (range_arr[i][0] > 0xFFFF || range_arr[i][1] > 0xFFFF)
850321936Shselasky                            {
851321936Shselasky                                yyerror("SDP port number out of range");
852321936Shselasky				free(range_arr);
853321936Shselasky                                return 1;
854321936Shselasky                            }
855321936Shselasky                            range_arr[i][0] += OSM_QOS_POLICY_ULP_SDP_SERVICE_ID;
856321936Shselasky                            range_arr[i][1] += OSM_QOS_POLICY_ULP_SDP_SERVICE_ID;
857321936Shselasky                        }
858321936Shselasky
859321936Shselasky                        p_current_qos_match_rule->service_id_range_arr = range_arr;
860321936Shselasky                        p_current_qos_match_rule->service_id_range_len = range_len;
861321936Shselasky
862321936Shselasky                    } qos_ulp_sl
863321936Shselasky
864321936Shselasky                    | qos_ulp_type_rds_default {
865321936Shselasky                        /* "rds : sl" - default SL for RDS */
866321936Shselasky                        uint64_t ** range_arr =
867321936Shselasky                               (uint64_t **)malloc(sizeof(uint64_t *));
868321936Shselasky                        range_arr[0] = (uint64_t *)malloc(2*sizeof(uint64_t));
869321936Shselasky                        range_arr[0][0] = range_arr[0][1] =
870321936Shselasky                           OSM_QOS_POLICY_ULP_RDS_SERVICE_ID + OSM_QOS_POLICY_ULP_RDS_PORT;
871321936Shselasky
872321936Shselasky                        p_current_qos_match_rule->service_id_range_arr = range_arr;
873321936Shselasky                        p_current_qos_match_rule->service_id_range_len = 1;
874321936Shselasky
875321936Shselasky                    } qos_ulp_sl
876321936Shselasky
877321936Shselasky                    | qos_ulp_type_rds_port list_of_ranges TK_DOTDOT {
878321936Shselasky                        /* rds with port numbers */
879321936Shselasky                        uint64_t ** range_arr;
880321936Shselasky                        unsigned    range_len;
881321936Shselasky                        unsigned    i;
882321936Shselasky
883321936Shselasky                        if (!cl_list_count(&tmp_parser_struct.num_pair_list))
884321936Shselasky                        {
885321936Shselasky                            yyerror("RDS ULP rule doesn't have port numbers");
886321936Shselasky                            return 1;
887321936Shselasky                        }
888321936Shselasky
889321936Shselasky                        /* get all the port ranges */
890321936Shselasky                        __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
891321936Shselasky                                              &range_arr,
892321936Shselasky                                              &range_len );
893321936Shselasky                        /* now translate these port numbers into service ids */
894321936Shselasky                        for (i = 0; i < range_len; i++)
895321936Shselasky                        {
896321936Shselasky                            if (range_arr[i][0] > 0xFFFF || range_arr[i][1] > 0xFFFF)
897321936Shselasky                            {
898321936Shselasky                                yyerror("SDP port number out of range");
899321936Shselasky				free(range_arr);
900321936Shselasky                                return 1;
901321936Shselasky                            }
902321936Shselasky                            range_arr[i][0] += OSM_QOS_POLICY_ULP_RDS_SERVICE_ID;
903321936Shselasky                            range_arr[i][1] += OSM_QOS_POLICY_ULP_RDS_SERVICE_ID;
904321936Shselasky                        }
905321936Shselasky
906321936Shselasky                        p_current_qos_match_rule->service_id_range_arr = range_arr;
907321936Shselasky                        p_current_qos_match_rule->service_id_range_len = range_len;
908321936Shselasky
909321936Shselasky                    } qos_ulp_sl
910321936Shselasky
911321936Shselasky                    | qos_ulp_type_iser_default {
912321936Shselasky                        /* "iSER : sl" - default SL for iSER */
913321936Shselasky                        uint64_t ** range_arr =
914321936Shselasky                               (uint64_t **)malloc(sizeof(uint64_t *));
915321936Shselasky                        range_arr[0] = (uint64_t *)malloc(2*sizeof(uint64_t));
916321936Shselasky                        range_arr[0][0] = range_arr[0][1] =
917321936Shselasky                           OSM_QOS_POLICY_ULP_ISER_SERVICE_ID + OSM_QOS_POLICY_ULP_ISER_PORT;
918321936Shselasky
919321936Shselasky                        p_current_qos_match_rule->service_id_range_arr = range_arr;
920321936Shselasky                        p_current_qos_match_rule->service_id_range_len = 1;
921321936Shselasky
922321936Shselasky                    } qos_ulp_sl
923321936Shselasky
924321936Shselasky                    | qos_ulp_type_iser_port list_of_ranges TK_DOTDOT {
925321936Shselasky                        /* iser with port numbers */
926321936Shselasky                        uint64_t ** range_arr;
927321936Shselasky                        unsigned    range_len;
928321936Shselasky                        unsigned    i;
929321936Shselasky
930321936Shselasky                        if (!cl_list_count(&tmp_parser_struct.num_pair_list))
931321936Shselasky                        {
932321936Shselasky                            yyerror("iSER ULP rule doesn't have port numbers");
933321936Shselasky                            return 1;
934321936Shselasky                        }
935321936Shselasky
936321936Shselasky                        /* get all the port ranges */
937321936Shselasky                        __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
938321936Shselasky                                              &range_arr,
939321936Shselasky                                              &range_len );
940321936Shselasky                        /* now translate these port numbers into service ids */
941321936Shselasky                        for (i = 0; i < range_len; i++)
942321936Shselasky                        {
943321936Shselasky                            if (range_arr[i][0] > 0xFFFF || range_arr[i][1] > 0xFFFF)
944321936Shselasky                            {
945321936Shselasky                                yyerror("SDP port number out of range");
946321936Shselasky				free(range_arr);
947321936Shselasky                                return 1;
948321936Shselasky                            }
949321936Shselasky                            range_arr[i][0] += OSM_QOS_POLICY_ULP_ISER_SERVICE_ID;
950321936Shselasky                            range_arr[i][1] += OSM_QOS_POLICY_ULP_ISER_SERVICE_ID;
951321936Shselasky                        }
952321936Shselasky
953321936Shselasky                        p_current_qos_match_rule->service_id_range_arr = range_arr;
954321936Shselasky                        p_current_qos_match_rule->service_id_range_len = range_len;
955321936Shselasky
956321936Shselasky                    } qos_ulp_sl
957321936Shselasky
958321936Shselasky                    | qos_ulp_type_srp_guid list_of_ranges TK_DOTDOT {
959321936Shselasky                        /* srp with target guids - this rule is similar
960321936Shselasky                           to writing 'any' ulp with target port guids */
961321936Shselasky                        uint64_t ** range_arr;
962321936Shselasky                        unsigned    range_len;
963321936Shselasky
964321936Shselasky                        if (!cl_list_count(&tmp_parser_struct.num_pair_list))
965321936Shselasky                        {
966321936Shselasky                            yyerror("SRP ULP rule doesn't have port guids");
967321936Shselasky                            return 1;
968321936Shselasky                        }
969321936Shselasky
970321936Shselasky                        /* create a new port group with these ports */
971321936Shselasky                        __parser_port_group_start();
972321936Shselasky
973321936Shselasky                        p_current_port_group->name = strdup("_SRP_Targets_");
974321936Shselasky                        p_current_port_group->use = strdup("Generated from ULP rules");
975321936Shselasky
976321936Shselasky                        __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
977321936Shselasky                                              &range_arr,
978321936Shselasky                                              &range_len );
979321936Shselasky
980321936Shselasky                        __parser_add_guid_range_to_port_map(
981321936Shselasky                                              &p_current_port_group->port_map,
982321936Shselasky                                              range_arr,
983321936Shselasky                                              range_len);
984321936Shselasky
985321936Shselasky                        /* add this port group to the destination
986321936Shselasky                           groups of the current match rule */
987321936Shselasky                        cl_list_insert_tail(&p_current_qos_match_rule->destination_group_list,
988321936Shselasky                                            p_current_port_group);
989321936Shselasky
990321936Shselasky                        __parser_port_group_end();
991321936Shselasky
992321936Shselasky                    } qos_ulp_sl
993321936Shselasky
994321936Shselasky                    | qos_ulp_type_ipoib_default {
995321936Shselasky                        /* ipoib w/o any pkeys (default pkey) */
996321936Shselasky                        uint64_t ** range_arr =
997321936Shselasky                               (uint64_t **)malloc(sizeof(uint64_t *));
998321936Shselasky                        range_arr[0] = (uint64_t *)malloc(2*sizeof(uint64_t));
999321936Shselasky                        range_arr[0][0] = range_arr[0][1] = 0x7fff;
1000321936Shselasky
1001321936Shselasky                        /*
1002321936Shselasky                         * Although we know that the default partition exists,
1003321936Shselasky                         * we still need to validate it by checking that it has
1004321936Shselasky                         * at least two full members. Otherwise IPoIB won't work.
1005321936Shselasky                         */
1006321936Shselasky                        if (__validate_pkeys(range_arr, 1, TRUE))
1007321936Shselasky                            return 1;
1008321936Shselasky
1009321936Shselasky                        p_current_qos_match_rule->pkey_range_arr = range_arr;
1010321936Shselasky                        p_current_qos_match_rule->pkey_range_len = 1;
1011321936Shselasky
1012321936Shselasky                    } qos_ulp_sl
1013321936Shselasky
1014321936Shselasky                    | qos_ulp_type_ipoib_pkey list_of_ranges TK_DOTDOT {
1015321936Shselasky                        /* ipoib with pkeys */
1016321936Shselasky                        uint64_t ** range_arr;
1017321936Shselasky                        unsigned    range_len;
1018321936Shselasky
1019321936Shselasky                        if (!cl_list_count(&tmp_parser_struct.num_pair_list))
1020321936Shselasky                        {
1021321936Shselasky                            yyerror("IPoIB ULP rule doesn't have pkeys");
1022321936Shselasky                            return 1;
1023321936Shselasky                        }
1024321936Shselasky
1025321936Shselasky                        /* get all the pkey ranges */
1026321936Shselasky                        __pkey_rangelist2rangearr( &tmp_parser_struct.num_pair_list,
1027321936Shselasky                                              &range_arr,
1028321936Shselasky                                              &range_len );
1029321936Shselasky
1030321936Shselasky                        /*
1031321936Shselasky                         * Validate pkeys.
1032321936Shselasky                         * For IPoIB pkeys the validation is strict.
1033321936Shselasky                         * If some problem would be found, parsing will
1034321936Shselasky                         * be aborted with a proper error messages.
1035321936Shselasky                         */
1036321936Shselasky			if (__validate_pkeys(range_arr, range_len, TRUE)) {
1037321936Shselasky			    free(range_arr);
1038321936Shselasky                            return 1;
1039321936Shselasky			}
1040321936Shselasky
1041321936Shselasky                        p_current_qos_match_rule->pkey_range_arr = range_arr;
1042321936Shselasky                        p_current_qos_match_rule->pkey_range_len = range_len;
1043321936Shselasky
1044321936Shselasky                    } qos_ulp_sl
1045321936Shselasky                    ;
1046321936Shselasky
1047321936Shselaskyqos_ulp_type_any_service: TK_ULP_ANY_SERVICE_ID
1048321936Shselasky                    { __parser_ulp_match_rule_start(); };
1049321936Shselasky
1050321936Shselaskyqos_ulp_type_any_pkey: TK_ULP_ANY_PKEY
1051321936Shselasky                    { __parser_ulp_match_rule_start(); };
1052321936Shselasky
1053321936Shselaskyqos_ulp_type_any_target_port_guid: TK_ULP_ANY_TARGET_PORT_GUID
1054321936Shselasky                    { __parser_ulp_match_rule_start(); };
1055321936Shselasky
1056321936Shselaskyqos_ulp_type_any_source_port_guid: TK_ULP_ANY_SOURCE_PORT_GUID
1057321936Shselasky                    { __parser_ulp_match_rule_start(); };
1058321936Shselasky
1059321936Shselaskyqos_ulp_type_any_source_target_port_guid: TK_ULP_ANY_SOURCE_TARGET_PORT_GUID
1060321936Shselasky                    { __parser_ulp_match_rule_start(); };
1061321936Shselasky
1062321936Shselaskyqos_ulp_type_sdp_default: TK_ULP_SDP_DEFAULT
1063321936Shselasky                    { __parser_ulp_match_rule_start(); };
1064321936Shselasky
1065321936Shselaskyqos_ulp_type_sdp_port: TK_ULP_SDP_PORT
1066321936Shselasky                    { __parser_ulp_match_rule_start(); };
1067321936Shselasky
1068321936Shselaskyqos_ulp_type_rds_default: TK_ULP_RDS_DEFAULT
1069321936Shselasky                    { __parser_ulp_match_rule_start(); };
1070321936Shselasky
1071321936Shselaskyqos_ulp_type_rds_port: TK_ULP_RDS_PORT
1072321936Shselasky                    { __parser_ulp_match_rule_start(); };
1073321936Shselasky
1074321936Shselaskyqos_ulp_type_iser_default: TK_ULP_ISER_DEFAULT
1075321936Shselasky                    { __parser_ulp_match_rule_start(); };
1076321936Shselasky
1077321936Shselaskyqos_ulp_type_iser_port: TK_ULP_ISER_PORT
1078321936Shselasky                    { __parser_ulp_match_rule_start(); };
1079321936Shselasky
1080321936Shselaskyqos_ulp_type_srp_guid: TK_ULP_SRP_GUID
1081321936Shselasky                    { __parser_ulp_match_rule_start(); };
1082321936Shselasky
1083321936Shselaskyqos_ulp_type_ipoib_default: TK_ULP_IPOIB_DEFAULT
1084321936Shselasky                    { __parser_ulp_match_rule_start(); };
1085321936Shselasky
1086321936Shselaskyqos_ulp_type_ipoib_pkey: TK_ULP_IPOIB_PKEY
1087321936Shselasky                    { __parser_ulp_match_rule_start(); };
1088321936Shselasky
1089321936Shselasky
1090321936Shselaskyqos_ulp_sl:   single_number {
1091321936Shselasky                        /* get the SL for ULP rules */
1092321936Shselasky                        cl_list_iterator_t  list_iterator;
1093321936Shselasky                        uint64_t          * p_tmp_num;
1094321936Shselasky                        uint8_t             sl;
1095321936Shselasky
1096321936Shselasky                        list_iterator = cl_list_head(&tmp_parser_struct.num_list);
1097321936Shselasky                        p_tmp_num = (uint64_t*)cl_list_obj(list_iterator);
1098321936Shselasky                        if (*p_tmp_num > 15)
1099321936Shselasky                        {
1100321936Shselasky                            yyerror("illegal SL value");
1101321936Shselasky                            return 1;
1102321936Shselasky                        }
1103321936Shselasky
1104321936Shselasky                        sl = (uint8_t)(*p_tmp_num);
1105321936Shselasky                        free(p_tmp_num);
1106321936Shselasky                        cl_list_remove_all(&tmp_parser_struct.num_list);
1107321936Shselasky
1108321936Shselasky                        p_current_qos_match_rule->p_qos_level =
1109321936Shselasky                                 &osm_qos_policy_simple_qos_levels[sl];
1110321936Shselasky                        p_current_qos_match_rule->qos_level_name =
1111321936Shselasky                                 strdup(osm_qos_policy_simple_qos_levels[sl].name);
1112321936Shselasky
1113321936Shselasky                        if (__parser_ulp_match_rule_end())
1114321936Shselasky                            return 1;
1115321936Shselasky                    }
1116321936Shselasky                    ;
1117321936Shselasky
1118321936Shselasky    /*
1119321936Shselasky     *  port_group_entry values:
1120321936Shselasky     *      port_group_name
1121321936Shselasky     *      port_group_use
1122321936Shselasky     *      port_group_port_guid
1123321936Shselasky     *      port_group_port_name
1124321936Shselasky     *      port_group_pkey
1125321936Shselasky     *      port_group_partition
1126321936Shselasky     *      port_group_node_type
1127321936Shselasky     */
1128321936Shselasky
1129321936Shselaskyport_group_name:        port_group_name_start single_string {
1130321936Shselasky                            /* 'name' of 'port-group' - one instance */
1131321936Shselasky                            cl_list_iterator_t    list_iterator;
1132321936Shselasky                            char                * tmp_str;
1133321936Shselasky
1134321936Shselasky                            if (p_current_port_group->name)
1135321936Shselasky                            {
1136321936Shselasky                                yyerror("port-group has multiple 'name' tags");
1137321936Shselasky                                cl_list_remove_all(&tmp_parser_struct.str_list);
1138321936Shselasky                                return 1;
1139321936Shselasky                            }
1140321936Shselasky
1141321936Shselasky                            list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1142321936Shselasky                            if ( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1143321936Shselasky                            {
1144321936Shselasky                                tmp_str = (char*)cl_list_obj(list_iterator);
1145321936Shselasky                                if (tmp_str)
1146321936Shselasky                                    p_current_port_group->name = tmp_str;
1147321936Shselasky                            }
1148321936Shselasky                            cl_list_remove_all(&tmp_parser_struct.str_list);
1149321936Shselasky                        }
1150321936Shselasky                        ;
1151321936Shselasky
1152321936Shselaskyport_group_name_start:  TK_NAME {
1153321936Shselasky                            RESET_BUFFER;
1154321936Shselasky                        }
1155321936Shselasky                        ;
1156321936Shselasky
1157321936Shselaskyport_group_use:         port_group_use_start single_string {
1158321936Shselasky                            /* 'use' of 'port-group' - one instance */
1159321936Shselasky                            cl_list_iterator_t    list_iterator;
1160321936Shselasky                            char                * tmp_str;
1161321936Shselasky
1162321936Shselasky                            if (p_current_port_group->use)
1163321936Shselasky                            {
1164321936Shselasky                                yyerror("port-group has multiple 'use' tags");
1165321936Shselasky                                cl_list_remove_all(&tmp_parser_struct.str_list);
1166321936Shselasky                                return 1;
1167321936Shselasky                            }
1168321936Shselasky
1169321936Shselasky                            list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1170321936Shselasky                            if ( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1171321936Shselasky                            {
1172321936Shselasky                                tmp_str = (char*)cl_list_obj(list_iterator);
1173321936Shselasky                                if (tmp_str)
1174321936Shselasky                                    p_current_port_group->use = tmp_str;
1175321936Shselasky                            }
1176321936Shselasky                            cl_list_remove_all(&tmp_parser_struct.str_list);
1177321936Shselasky                        }
1178321936Shselasky                        ;
1179321936Shselasky
1180321936Shselaskyport_group_use_start:   TK_USE {
1181321936Shselasky                            RESET_BUFFER;
1182321936Shselasky                        }
1183321936Shselasky                        ;
1184321936Shselasky
1185321936Shselaskyport_group_port_name:   port_group_port_name_start string_list {
1186321936Shselasky                            /* 'port-name' in 'port-group' - any num of instances */
1187321936Shselasky                            cl_list_iterator_t list_iterator;
1188321936Shselasky                            osm_node_t * p_node;
1189321936Shselasky                            osm_physp_t * p_physp;
1190321936Shselasky                            unsigned port_num;
1191321936Shselasky                            char * tmp_str;
1192321936Shselasky                            char * port_str;
1193321936Shselasky
1194321936Shselasky                            /* parsing port name strings */
1195321936Shselasky                            for (list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1196321936Shselasky                                 list_iterator != cl_list_end(&tmp_parser_struct.str_list);
1197321936Shselasky                                 list_iterator = cl_list_next(list_iterator))
1198321936Shselasky                            {
1199321936Shselasky                                tmp_str = (char*)cl_list_obj(list_iterator);
1200321936Shselasky                                if (tmp_str)
1201321936Shselasky                                {
1202321936Shselasky                                    /* last slash in port name string is a separator
1203321936Shselasky                                       between node name and port number */
1204321936Shselasky                                    port_str = strrchr(tmp_str, '/');
1205321936Shselasky                                    if (!port_str || (strlen(port_str) < 3) ||
1206321936Shselasky                                        (port_str[1] != 'p' && port_str[1] != 'P')) {
1207321936Shselasky                                        yyerror("'%s' - illegal port name",
1208321936Shselasky                                                           tmp_str);
1209321936Shselasky                                        free(tmp_str);
1210321936Shselasky                                        cl_list_remove_all(&tmp_parser_struct.str_list);
1211321936Shselasky                                        return 1;
1212321936Shselasky                                    }
1213321936Shselasky
1214321936Shselasky                                    if (!(port_num = strtoul(&port_str[2],NULL,0))) {
1215321936Shselasky                                        yyerror(
1216321936Shselasky                                               "'%s' - illegal port number in port name",
1217321936Shselasky                                               tmp_str);
1218321936Shselasky                                        free(tmp_str);
1219321936Shselasky                                        cl_list_remove_all(&tmp_parser_struct.str_list);
1220321936Shselasky                                        return 1;
1221321936Shselasky                                    }
1222321936Shselasky
1223321936Shselasky                                    /* separate node name from port number */
1224321936Shselasky                                    port_str[0] = '\0';
1225321936Shselasky
1226321936Shselasky                                    if (st_lookup(p_qos_policy->p_node_hash,
1227321936Shselasky                                                  (st_data_t)tmp_str,
1228321936Shselasky                                                  (void *)&p_node))
1229321936Shselasky                                    {
1230321936Shselasky                                        /* we found the node, now get the right port */
1231321936Shselasky                                        p_physp = osm_node_get_physp_ptr(p_node, port_num);
1232321936Shselasky                                        if (!p_physp) {
1233321936Shselasky                                            yyerror(
1234321936Shselasky                                                   "'%s' - port number out of range in port name",
1235321936Shselasky                                                   tmp_str);
1236321936Shselasky                                            free(tmp_str);
1237321936Shselasky                                            cl_list_remove_all(&tmp_parser_struct.str_list);
1238321936Shselasky                                            return 1;
1239321936Shselasky                                        }
1240321936Shselasky                                        /* we found the port, now add it to guid table */
1241321936Shselasky                                        __parser_add_port_to_port_map(&p_current_port_group->port_map,
1242321936Shselasky                                                                      p_physp);
1243321936Shselasky                                    }
1244321936Shselasky                                    free(tmp_str);
1245321936Shselasky                                }
1246321936Shselasky                            }
1247321936Shselasky                            cl_list_remove_all(&tmp_parser_struct.str_list);
1248321936Shselasky                        }
1249321936Shselasky                        ;
1250321936Shselasky
1251321936Shselaskyport_group_port_name_start: TK_PORT_NAME {
1252321936Shselasky                            RESET_BUFFER;
1253321936Shselasky                        }
1254321936Shselasky                        ;
1255321936Shselasky
1256321936Shselaskyport_group_port_guid:   port_group_port_guid_start list_of_ranges {
1257321936Shselasky                            /* 'port-guid' in 'port-group' - any num of instances */
1258321936Shselasky                            /* list of guid ranges */
1259321936Shselasky                            if (cl_list_count(&tmp_parser_struct.num_pair_list))
1260321936Shselasky                            {
1261321936Shselasky                                uint64_t ** range_arr;
1262321936Shselasky                                unsigned range_len;
1263321936Shselasky
1264321936Shselasky                                __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
1265321936Shselasky                                                      &range_arr,
1266321936Shselasky                                                      &range_len );
1267321936Shselasky
1268321936Shselasky                                __parser_add_guid_range_to_port_map(
1269321936Shselasky                                                      &p_current_port_group->port_map,
1270321936Shselasky                                                      range_arr,
1271321936Shselasky                                                      range_len);
1272321936Shselasky                            }
1273321936Shselasky                        }
1274321936Shselasky                        ;
1275321936Shselasky
1276321936Shselaskyport_group_port_guid_start: TK_PORT_GUID {
1277321936Shselasky                            RESET_BUFFER;
1278321936Shselasky                        }
1279321936Shselasky                        ;
1280321936Shselasky
1281321936Shselaskyport_group_pkey:        port_group_pkey_start list_of_ranges {
1282321936Shselasky                            /* 'pkey' in 'port-group' - any num of instances */
1283321936Shselasky                            /* list of pkey ranges */
1284321936Shselasky                            if (cl_list_count(&tmp_parser_struct.num_pair_list))
1285321936Shselasky                            {
1286321936Shselasky                                uint64_t ** range_arr;
1287321936Shselasky                                unsigned range_len;
1288321936Shselasky
1289321936Shselasky                                __pkey_rangelist2rangearr( &tmp_parser_struct.num_pair_list,
1290321936Shselasky                                                      &range_arr,
1291321936Shselasky                                                      &range_len );
1292321936Shselasky
1293321936Shselasky                                __parser_add_pkey_range_to_port_map(
1294321936Shselasky                                                      &p_current_port_group->port_map,
1295321936Shselasky                                                      range_arr,
1296321936Shselasky                                                      range_len);
1297321936Shselasky                            }
1298321936Shselasky                        }
1299321936Shselasky                        ;
1300321936Shselasky
1301321936Shselaskyport_group_pkey_start:  TK_PKEY {
1302321936Shselasky                            RESET_BUFFER;
1303321936Shselasky                        }
1304321936Shselasky                        ;
1305321936Shselasky
1306321936Shselaskyport_group_partition:  port_group_partition_start string_list {
1307321936Shselasky                            /* 'partition' in 'port-group' - any num of instances */
1308321936Shselasky                            __parser_add_partition_list_to_port_map(
1309321936Shselasky                                               &p_current_port_group->port_map,
1310321936Shselasky                                               &tmp_parser_struct.str_list);
1311321936Shselasky                        }
1312321936Shselasky                        ;
1313321936Shselasky
1314321936Shselaskyport_group_partition_start: TK_PARTITION {
1315321936Shselasky                            RESET_BUFFER;
1316321936Shselasky                        }
1317321936Shselasky                        ;
1318321936Shselasky
1319321936Shselaskyport_group_node_type:   port_group_node_type_start port_group_node_type_list {
1320321936Shselasky                            /* 'node-type' in 'port-group' - any num of instances */
1321321936Shselasky                        }
1322321936Shselasky                        ;
1323321936Shselasky
1324321936Shselaskyport_group_node_type_start: TK_NODE_TYPE {
1325321936Shselasky                            RESET_BUFFER;
1326321936Shselasky                        }
1327321936Shselasky                        ;
1328321936Shselasky
1329321936Shselaskyport_group_node_type_list:  node_type_item
1330321936Shselasky                        |   port_group_node_type_list TK_COMMA node_type_item
1331321936Shselasky                        ;
1332321936Shselasky
1333321936Shselaskynode_type_item:           node_type_ca
1334321936Shselasky                        | node_type_switch
1335321936Shselasky                        | node_type_router
1336321936Shselasky                        | node_type_all
1337321936Shselasky                        | node_type_self
1338321936Shselasky                        ;
1339321936Shselasky
1340321936Shselaskynode_type_ca:           TK_NODE_TYPE_CA {
1341321936Shselasky                            p_current_port_group->node_types |=
1342321936Shselasky                               OSM_QOS_POLICY_NODE_TYPE_CA;
1343321936Shselasky                        }
1344321936Shselasky                        ;
1345321936Shselasky
1346321936Shselaskynode_type_switch:       TK_NODE_TYPE_SWITCH {
1347321936Shselasky                            p_current_port_group->node_types |=
1348321936Shselasky                               OSM_QOS_POLICY_NODE_TYPE_SWITCH;
1349321936Shselasky                        }
1350321936Shselasky                        ;
1351321936Shselasky
1352321936Shselaskynode_type_router:       TK_NODE_TYPE_ROUTER {
1353321936Shselasky                            p_current_port_group->node_types |=
1354321936Shselasky                               OSM_QOS_POLICY_NODE_TYPE_ROUTER;
1355321936Shselasky                        }
1356321936Shselasky                        ;
1357321936Shselasky
1358321936Shselaskynode_type_all:          TK_NODE_TYPE_ALL {
1359321936Shselasky                            p_current_port_group->node_types |=
1360321936Shselasky                               (OSM_QOS_POLICY_NODE_TYPE_CA |
1361321936Shselasky                                OSM_QOS_POLICY_NODE_TYPE_SWITCH |
1362321936Shselasky                                OSM_QOS_POLICY_NODE_TYPE_ROUTER);
1363321936Shselasky                        }
1364321936Shselasky                        ;
1365321936Shselasky
1366321936Shselaskynode_type_self:         TK_NODE_TYPE_SELF {
1367321936Shselasky                            osm_port_t * p_osm_port =
1368321936Shselasky                                osm_get_port_by_guid(p_qos_policy->p_subn,
1369321936Shselasky                                     p_qos_policy->p_subn->sm_port_guid);
1370321936Shselasky                            if (p_osm_port)
1371321936Shselasky                                __parser_add_port_to_port_map(
1372321936Shselasky                                   &p_current_port_group->port_map,
1373321936Shselasky                                   p_osm_port->p_physp);
1374321936Shselasky                        }
1375321936Shselasky                        ;
1376321936Shselasky
1377321936Shselasky    /*
1378321936Shselasky     *  vlarb_scope_entry values:
1379321936Shselasky     *      vlarb_scope_group
1380321936Shselasky     *      vlarb_scope_across
1381321936Shselasky     *      vlarb_scope_vlarb_high
1382321936Shselasky     *      vlarb_scope_vlarb_low
1383321936Shselasky     *      vlarb_scope_vlarb_high_limit
1384321936Shselasky     */
1385321936Shselasky
1386321936Shselasky
1387321936Shselasky
1388321936Shselaskyvlarb_scope_group:      vlarb_scope_group_start string_list {
1389321936Shselasky                            /* 'group' in 'vlarb-scope' - any num of instances */
1390321936Shselasky                            cl_list_iterator_t    list_iterator;
1391321936Shselasky                            char                * tmp_str;
1392321936Shselasky
1393321936Shselasky                            list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1394321936Shselasky                            while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1395321936Shselasky                            {
1396321936Shselasky                                tmp_str = (char*)cl_list_obj(list_iterator);
1397321936Shselasky                                if (tmp_str)
1398321936Shselasky                                    cl_list_insert_tail(&p_current_vlarb_scope->group_list,tmp_str);
1399321936Shselasky                                list_iterator = cl_list_next(list_iterator);
1400321936Shselasky                            }
1401321936Shselasky                            cl_list_remove_all(&tmp_parser_struct.str_list);
1402321936Shselasky                        }
1403321936Shselasky                        ;
1404321936Shselasky
1405321936Shselaskyvlarb_scope_group_start: TK_GROUP {
1406321936Shselasky                            RESET_BUFFER;
1407321936Shselasky                        }
1408321936Shselasky                        ;
1409321936Shselasky
1410321936Shselaskyvlarb_scope_across: vlarb_scope_across_start string_list {
1411321936Shselasky                            /* 'across' in 'vlarb-scope' - any num of instances */
1412321936Shselasky                            cl_list_iterator_t    list_iterator;
1413321936Shselasky                            char                * tmp_str;
1414321936Shselasky
1415321936Shselasky                            list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1416321936Shselasky                            while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1417321936Shselasky                            {
1418321936Shselasky                                tmp_str = (char*)cl_list_obj(list_iterator);
1419321936Shselasky                                if (tmp_str)
1420321936Shselasky                                    cl_list_insert_tail(&p_current_vlarb_scope->across_list,tmp_str);
1421321936Shselasky                                list_iterator = cl_list_next(list_iterator);
1422321936Shselasky                            }
1423321936Shselasky                            cl_list_remove_all(&tmp_parser_struct.str_list);
1424321936Shselasky                        }
1425321936Shselasky                        ;
1426321936Shselasky
1427321936Shselaskyvlarb_scope_across_start: TK_ACROSS {
1428321936Shselasky                            RESET_BUFFER;
1429321936Shselasky                        }
1430321936Shselasky                        ;
1431321936Shselasky
1432321936Shselaskyvlarb_scope_vlarb_high_limit:  vlarb_scope_vlarb_high_limit_start single_number {
1433321936Shselasky                            /* 'vl-high-limit' in 'vlarb-scope' - one instance of one number */
1434321936Shselasky                            cl_list_iterator_t    list_iterator;
1435321936Shselasky                            uint64_t            * p_tmp_num;
1436321936Shselasky
1437321936Shselasky                            list_iterator = cl_list_head(&tmp_parser_struct.num_list);
1438321936Shselasky                            p_tmp_num = (uint64_t*)cl_list_obj(list_iterator);
1439321936Shselasky                            if (p_tmp_num)
1440321936Shselasky                            {
1441321936Shselasky                                p_current_vlarb_scope->vl_high_limit = (uint32_t)(*p_tmp_num);
1442321936Shselasky                                p_current_vlarb_scope->vl_high_limit_set = TRUE;
1443321936Shselasky                                free(p_tmp_num);
1444321936Shselasky                            }
1445321936Shselasky
1446321936Shselasky                            cl_list_remove_all(&tmp_parser_struct.num_list);
1447321936Shselasky                        }
1448321936Shselasky                        ;
1449321936Shselasky
1450321936Shselaskyvlarb_scope_vlarb_high_limit_start: TK_VLARB_HIGH_LIMIT {
1451321936Shselasky                            RESET_BUFFER;
1452321936Shselasky                        }
1453321936Shselasky                        ;
1454321936Shselasky
1455321936Shselaskyvlarb_scope_vlarb_high: vlarb_scope_vlarb_high_start num_list_with_dotdot {
1456321936Shselasky                            /* 'vlarb-high' in 'vlarb-scope' - list of pairs of numbers with ':' and ',' */
1457321936Shselasky                            cl_list_iterator_t    list_iterator;
1458321936Shselasky                            uint64_t            * num_pair;
1459321936Shselasky
1460321936Shselasky                            list_iterator = cl_list_head(&tmp_parser_struct.num_pair_list);
1461321936Shselasky                            while( list_iterator != cl_list_end(&tmp_parser_struct.num_pair_list) )
1462321936Shselasky                            {
1463321936Shselasky                                num_pair = (uint64_t*)cl_list_obj(list_iterator);
1464321936Shselasky                                if (num_pair)
1465321936Shselasky                                    cl_list_insert_tail(&p_current_vlarb_scope->vlarb_high_list,num_pair);
1466321936Shselasky                                list_iterator = cl_list_next(list_iterator);
1467321936Shselasky                            }
1468321936Shselasky                            cl_list_remove_all(&tmp_parser_struct.num_pair_list);
1469321936Shselasky                        }
1470321936Shselasky                        ;
1471321936Shselasky
1472321936Shselaskyvlarb_scope_vlarb_high_start: TK_VLARB_HIGH {
1473321936Shselasky                            RESET_BUFFER;
1474321936Shselasky                        }
1475321936Shselasky                        ;
1476321936Shselasky
1477321936Shselaskyvlarb_scope_vlarb_low:  vlarb_scope_vlarb_low_start num_list_with_dotdot {
1478321936Shselasky                            /* 'vlarb-low' in 'vlarb-scope' - list of pairs of numbers with ':' and ',' */
1479321936Shselasky                            cl_list_iterator_t    list_iterator;
1480321936Shselasky                            uint64_t            * num_pair;
1481321936Shselasky
1482321936Shselasky                            list_iterator = cl_list_head(&tmp_parser_struct.num_pair_list);
1483321936Shselasky                            while( list_iterator != cl_list_end(&tmp_parser_struct.num_pair_list) )
1484321936Shselasky                            {
1485321936Shselasky                                num_pair = (uint64_t*)cl_list_obj(list_iterator);
1486321936Shselasky                                if (num_pair)
1487321936Shselasky                                    cl_list_insert_tail(&p_current_vlarb_scope->vlarb_low_list,num_pair);
1488321936Shselasky                                list_iterator = cl_list_next(list_iterator);
1489321936Shselasky                            }
1490321936Shselasky                            cl_list_remove_all(&tmp_parser_struct.num_pair_list);
1491321936Shselasky                        }
1492321936Shselasky                        ;
1493321936Shselasky
1494321936Shselaskyvlarb_scope_vlarb_low_start: TK_VLARB_LOW {
1495321936Shselasky                            RESET_BUFFER;
1496321936Shselasky                        }
1497321936Shselasky                        ;
1498321936Shselasky
1499321936Shselasky    /*
1500321936Shselasky     *  sl2vl_scope_entry values:
1501321936Shselasky     *      sl2vl_scope_group
1502321936Shselasky     *      sl2vl_scope_across
1503321936Shselasky     *      sl2vl_scope_across_from
1504321936Shselasky     *      sl2vl_scope_across_to
1505321936Shselasky     *      sl2vl_scope_from
1506321936Shselasky     *      sl2vl_scope_to
1507321936Shselasky     *      sl2vl_scope_sl2vl_table
1508321936Shselasky     */
1509321936Shselasky
1510321936Shselaskysl2vl_scope_group:      sl2vl_scope_group_start string_list {
1511321936Shselasky                            /* 'group' in 'sl2vl-scope' - any num of instances */
1512321936Shselasky                            cl_list_iterator_t    list_iterator;
1513321936Shselasky                            char                * tmp_str;
1514321936Shselasky
1515321936Shselasky                            list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1516321936Shselasky                            while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1517321936Shselasky                            {
1518321936Shselasky                                tmp_str = (char*)cl_list_obj(list_iterator);
1519321936Shselasky                                if (tmp_str)
1520321936Shselasky                                    cl_list_insert_tail(&p_current_sl2vl_scope->group_list,tmp_str);
1521321936Shselasky                                list_iterator = cl_list_next(list_iterator);
1522321936Shselasky                            }
1523321936Shselasky                            cl_list_remove_all(&tmp_parser_struct.str_list);
1524321936Shselasky                        }
1525321936Shselasky                        ;
1526321936Shselasky
1527321936Shselaskysl2vl_scope_group_start: TK_GROUP {
1528321936Shselasky                            RESET_BUFFER;
1529321936Shselasky                        }
1530321936Shselasky                        ;
1531321936Shselasky
1532321936Shselaskysl2vl_scope_across:     sl2vl_scope_across_start string_list {
1533321936Shselasky                            /* 'across' in 'sl2vl-scope' - any num of instances */
1534321936Shselasky                            cl_list_iterator_t    list_iterator;
1535321936Shselasky                            char                * tmp_str;
1536321936Shselasky
1537321936Shselasky                            list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1538321936Shselasky                            while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1539321936Shselasky                            {
1540321936Shselasky                                tmp_str = (char*)cl_list_obj(list_iterator);
1541321936Shselasky                                if (tmp_str) {
1542321936Shselasky                                    cl_list_insert_tail(&p_current_sl2vl_scope->across_from_list,tmp_str);
1543321936Shselasky                                    cl_list_insert_tail(&p_current_sl2vl_scope->across_to_list,strdup(tmp_str));
1544321936Shselasky                                }
1545321936Shselasky                                list_iterator = cl_list_next(list_iterator);
1546321936Shselasky                            }
1547321936Shselasky                            cl_list_remove_all(&tmp_parser_struct.str_list);
1548321936Shselasky                        }
1549321936Shselasky                        ;
1550321936Shselasky
1551321936Shselaskysl2vl_scope_across_start: TK_ACROSS {
1552321936Shselasky                            RESET_BUFFER;
1553321936Shselasky                        }
1554321936Shselasky                        ;
1555321936Shselasky
1556321936Shselaskysl2vl_scope_across_from:  sl2vl_scope_across_from_start string_list {
1557321936Shselasky                            /* 'across-from' in 'sl2vl-scope' - any num of instances */
1558321936Shselasky                            cl_list_iterator_t    list_iterator;
1559321936Shselasky                            char                * tmp_str;
1560321936Shselasky
1561321936Shselasky                            list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1562321936Shselasky                            while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1563321936Shselasky                            {
1564321936Shselasky                                tmp_str = (char*)cl_list_obj(list_iterator);
1565321936Shselasky                                if (tmp_str)
1566321936Shselasky                                    cl_list_insert_tail(&p_current_sl2vl_scope->across_from_list,tmp_str);
1567321936Shselasky                                list_iterator = cl_list_next(list_iterator);
1568321936Shselasky                            }
1569321936Shselasky                            cl_list_remove_all(&tmp_parser_struct.str_list);
1570321936Shselasky                        }
1571321936Shselasky                        ;
1572321936Shselasky
1573321936Shselaskysl2vl_scope_across_from_start: TK_ACROSS_FROM {
1574321936Shselasky                            RESET_BUFFER;
1575321936Shselasky                        }
1576321936Shselasky                        ;
1577321936Shselasky
1578321936Shselaskysl2vl_scope_across_to:  sl2vl_scope_across_to_start string_list {
1579321936Shselasky                            /* 'across-to' in 'sl2vl-scope' - any num of instances */
1580321936Shselasky                            cl_list_iterator_t    list_iterator;
1581321936Shselasky                            char                * tmp_str;
1582321936Shselasky
1583321936Shselasky                            list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1584321936Shselasky                            while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1585321936Shselasky                            {
1586321936Shselasky                                tmp_str = (char*)cl_list_obj(list_iterator);
1587321936Shselasky                                if (tmp_str) {
1588321936Shselasky                                    cl_list_insert_tail(&p_current_sl2vl_scope->across_to_list,tmp_str);
1589321936Shselasky                                }
1590321936Shselasky                                list_iterator = cl_list_next(list_iterator);
1591321936Shselasky                            }
1592321936Shselasky                            cl_list_remove_all(&tmp_parser_struct.str_list);
1593321936Shselasky                        }
1594321936Shselasky                        ;
1595321936Shselasky
1596321936Shselaskysl2vl_scope_across_to_start: TK_ACROSS_TO {
1597321936Shselasky                            RESET_BUFFER;
1598321936Shselasky                        }
1599321936Shselasky                        ;
1600321936Shselasky
1601321936Shselaskysl2vl_scope_from:       sl2vl_scope_from_start sl2vl_scope_from_list_or_asterisk {
1602321936Shselasky                            /* 'from' in 'sl2vl-scope' - any num of instances */
1603321936Shselasky                        }
1604321936Shselasky                        ;
1605321936Shselasky
1606321936Shselaskysl2vl_scope_from_start: TK_FROM {
1607321936Shselasky                            RESET_BUFFER;
1608321936Shselasky                        }
1609321936Shselasky                        ;
1610321936Shselasky
1611321936Shselaskysl2vl_scope_to:         sl2vl_scope_to_start sl2vl_scope_to_list_or_asterisk {
1612321936Shselasky                            /* 'to' in 'sl2vl-scope' - any num of instances */
1613321936Shselasky                        }
1614321936Shselasky                        ;
1615321936Shselasky
1616321936Shselaskysl2vl_scope_to_start:   TK_TO {
1617321936Shselasky                            RESET_BUFFER;
1618321936Shselasky                        }
1619321936Shselasky                        ;
1620321936Shselasky
1621321936Shselaskysl2vl_scope_from_list_or_asterisk:  sl2vl_scope_from_asterisk
1622321936Shselasky                                  | sl2vl_scope_from_list_of_ranges
1623321936Shselasky                                  ;
1624321936Shselasky
1625321936Shselaskysl2vl_scope_from_asterisk: TK_ASTERISK {
1626321936Shselasky                            int i;
1627321936Shselasky                            for (i = 0; i < OSM_QOS_POLICY_MAX_PORTS_ON_SWITCH; i++)
1628321936Shselasky                                p_current_sl2vl_scope->from[i] = TRUE;
1629321936Shselasky                        }
1630321936Shselasky                        ;
1631321936Shselasky
1632321936Shselaskysl2vl_scope_to_list_or_asterisk:  sl2vl_scope_to_asterisk
1633321936Shselasky                                | sl2vl_scope_to_list_of_ranges
1634321936Shselasky                                  ;
1635321936Shselasky
1636321936Shselaskysl2vl_scope_to_asterisk: TK_ASTERISK {
1637321936Shselasky                            int i;
1638321936Shselasky                            for (i = 0; i < OSM_QOS_POLICY_MAX_PORTS_ON_SWITCH; i++)
1639321936Shselasky                                p_current_sl2vl_scope->to[i] = TRUE;
1640321936Shselasky                        }
1641321936Shselasky                        ;
1642321936Shselasky
1643321936Shselaskysl2vl_scope_from_list_of_ranges: list_of_ranges {
1644321936Shselasky                            int i;
1645321936Shselasky                            cl_list_iterator_t    list_iterator;
1646321936Shselasky                            uint64_t            * num_pair;
1647321936Shselasky                            uint8_t               num1, num2;
1648321936Shselasky
1649321936Shselasky                            list_iterator = cl_list_head(&tmp_parser_struct.num_pair_list);
1650321936Shselasky                            while( list_iterator != cl_list_end(&tmp_parser_struct.num_pair_list) )
1651321936Shselasky                            {
1652321936Shselasky                                num_pair = (uint64_t*)cl_list_obj(list_iterator);
1653321936Shselasky                                if (num_pair)
1654321936Shselasky                                {
1655321936Shselasky                                    if ( num_pair[1] >= OSM_QOS_POLICY_MAX_PORTS_ON_SWITCH )
1656321936Shselasky                                    {
1657321936Shselasky                                        yyerror("port number out of range 'from' list");
1658321936Shselasky                                        free(num_pair);
1659321936Shselasky                                        cl_list_remove_all(&tmp_parser_struct.num_pair_list);
1660321936Shselasky                                        return 1;
1661321936Shselasky                                    }
1662321936Shselasky                                    num1 = (uint8_t)num_pair[0];
1663321936Shselasky                                    num2 = (uint8_t)num_pair[1];
1664321936Shselasky                                    free(num_pair);
1665321936Shselasky                                    for (i = num1; i <= num2; i++)
1666321936Shselasky                                        p_current_sl2vl_scope->from[i] = TRUE;
1667321936Shselasky                                }
1668321936Shselasky                                list_iterator = cl_list_next(list_iterator);
1669321936Shselasky                            }
1670321936Shselasky                            cl_list_remove_all(&tmp_parser_struct.num_pair_list);
1671321936Shselasky                        }
1672321936Shselasky                        ;
1673321936Shselasky
1674321936Shselaskysl2vl_scope_to_list_of_ranges: list_of_ranges {
1675321936Shselasky                            int i;
1676321936Shselasky                            cl_list_iterator_t    list_iterator;
1677321936Shselasky                            uint64_t            * num_pair;
1678321936Shselasky                            uint8_t               num1, num2;
1679321936Shselasky
1680321936Shselasky                            list_iterator = cl_list_head(&tmp_parser_struct.num_pair_list);
1681321936Shselasky                            while( list_iterator != cl_list_end(&tmp_parser_struct.num_pair_list) )
1682321936Shselasky                            {
1683321936Shselasky                                num_pair = (uint64_t*)cl_list_obj(list_iterator);
1684321936Shselasky                                if (num_pair)
1685321936Shselasky                                {
1686321936Shselasky                                    if ( num_pair[1] >= OSM_QOS_POLICY_MAX_PORTS_ON_SWITCH )
1687321936Shselasky                                    {
1688321936Shselasky                                        yyerror("port number out of range 'to' list");
1689321936Shselasky                                        free(num_pair);
1690321936Shselasky                                        cl_list_remove_all(&tmp_parser_struct.num_pair_list);
1691321936Shselasky                                        return 1;
1692321936Shselasky                                    }
1693321936Shselasky                                    num1 = (uint8_t)num_pair[0];
1694321936Shselasky                                    num2 = (uint8_t)num_pair[1];
1695321936Shselasky                                    free(num_pair);
1696321936Shselasky                                    for (i = num1; i <= num2; i++)
1697321936Shselasky                                        p_current_sl2vl_scope->to[i] = TRUE;
1698321936Shselasky                                }
1699321936Shselasky                                list_iterator = cl_list_next(list_iterator);
1700321936Shselasky                            }
1701321936Shselasky                            cl_list_remove_all(&tmp_parser_struct.num_pair_list);
1702321936Shselasky                        }
1703321936Shselasky                        ;
1704321936Shselasky
1705321936Shselasky
1706321936Shselaskysl2vl_scope_sl2vl_table:  sl2vl_scope_sl2vl_table_start num_list {
1707321936Shselasky                            /* 'sl2vl-table' - one instance of exactly
1708321936Shselasky                               OSM_QOS_POLICY_SL2VL_TABLE_LEN numbers */
1709321936Shselasky                            cl_list_iterator_t    list_iterator;
1710321936Shselasky                            uint64_t              num;
1711321936Shselasky                            uint64_t            * p_num;
1712321936Shselasky                            int                   i = 0;
1713321936Shselasky
1714321936Shselasky                            if (p_current_sl2vl_scope->sl2vl_table_set)
1715321936Shselasky                            {
1716321936Shselasky                                yyerror("sl2vl-scope has more than one sl2vl-table");
1717321936Shselasky                                cl_list_remove_all(&tmp_parser_struct.num_list);
1718321936Shselasky                                return 1;
1719321936Shselasky                            }
1720321936Shselasky
1721321936Shselasky                            if (cl_list_count(&tmp_parser_struct.num_list) != OSM_QOS_POLICY_SL2VL_TABLE_LEN)
1722321936Shselasky                            {
1723321936Shselasky                                yyerror("wrong number of values in 'sl2vl-table' (should be 16)");
1724321936Shselasky                                cl_list_remove_all(&tmp_parser_struct.num_list);
1725321936Shselasky                                return 1;
1726321936Shselasky                            }
1727321936Shselasky
1728321936Shselasky                            list_iterator = cl_list_head(&tmp_parser_struct.num_list);
1729321936Shselasky                            while( list_iterator != cl_list_end(&tmp_parser_struct.num_list) )
1730321936Shselasky                            {
1731321936Shselasky                                p_num = (uint64_t*)cl_list_obj(list_iterator);
1732321936Shselasky                                num = *p_num;
1733321936Shselasky                                free(p_num);
1734321936Shselasky                                if (num >= OSM_QOS_POLICY_MAX_VL_NUM)
1735321936Shselasky                                {
1736321936Shselasky                                    yyerror("wrong VL value in 'sl2vl-table' (should be 0 to 15)");
1737321936Shselasky                                    cl_list_remove_all(&tmp_parser_struct.num_list);
1738321936Shselasky                                    return 1;
1739321936Shselasky                                }
1740321936Shselasky
1741321936Shselasky                                p_current_sl2vl_scope->sl2vl_table[i++] = (uint8_t)num;
1742321936Shselasky                                list_iterator = cl_list_next(list_iterator);
1743321936Shselasky                            }
1744321936Shselasky                            p_current_sl2vl_scope->sl2vl_table_set = TRUE;
1745321936Shselasky                            cl_list_remove_all(&tmp_parser_struct.num_list);
1746321936Shselasky                        }
1747321936Shselasky                        ;
1748321936Shselasky
1749321936Shselaskysl2vl_scope_sl2vl_table_start: TK_SL2VL_TABLE {
1750321936Shselasky                            RESET_BUFFER;
1751321936Shselasky                        }
1752321936Shselasky                        ;
1753321936Shselasky
1754321936Shselasky    /*
1755321936Shselasky     *  qos_level_entry values:
1756321936Shselasky     *      qos_level_name
1757321936Shselasky     *      qos_level_use
1758321936Shselasky     *      qos_level_sl
1759321936Shselasky     *      qos_level_mtu_limit
1760321936Shselasky     *      qos_level_rate_limit
1761321936Shselasky     *      qos_level_packet_life
1762321936Shselasky     *      qos_level_path_bits
1763321936Shselasky     *      qos_level_pkey
1764321936Shselasky     */
1765321936Shselasky
1766321936Shselaskyqos_level_name:         qos_level_name_start single_string {
1767321936Shselasky                            /* 'name' of 'qos-level' - one instance */
1768321936Shselasky                            cl_list_iterator_t    list_iterator;
1769321936Shselasky                            char                * tmp_str;
1770321936Shselasky
1771321936Shselasky                            if (p_current_qos_level->name)
1772321936Shselasky                            {
1773321936Shselasky                                yyerror("qos-level has multiple 'name' tags");
1774321936Shselasky                                cl_list_remove_all(&tmp_parser_struct.str_list);
1775321936Shselasky                                return 1;
1776321936Shselasky                            }
1777321936Shselasky
1778321936Shselasky                            list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1779321936Shselasky                            if ( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1780321936Shselasky                            {
1781321936Shselasky                                tmp_str = (char*)cl_list_obj(list_iterator);
1782321936Shselasky                                if (tmp_str)
1783321936Shselasky                                    p_current_qos_level->name = tmp_str;
1784321936Shselasky                            }
1785321936Shselasky                            cl_list_remove_all(&tmp_parser_struct.str_list);
1786321936Shselasky                        }
1787321936Shselasky                        ;
1788321936Shselasky
1789321936Shselaskyqos_level_name_start:   TK_NAME {
1790321936Shselasky                            RESET_BUFFER;
1791321936Shselasky                        }
1792321936Shselasky                        ;
1793321936Shselasky
1794321936Shselaskyqos_level_use:          qos_level_use_start single_string {
1795321936Shselasky                            /* 'use' of 'qos-level' - one instance */
1796321936Shselasky                            cl_list_iterator_t    list_iterator;
1797321936Shselasky                            char                * tmp_str;
1798321936Shselasky
1799321936Shselasky                            if (p_current_qos_level->use)
1800321936Shselasky                            {
1801321936Shselasky                                yyerror("qos-level has multiple 'use' tags");
1802321936Shselasky                                cl_list_remove_all(&tmp_parser_struct.str_list);
1803321936Shselasky                                return 1;
1804321936Shselasky                            }
1805321936Shselasky
1806321936Shselasky                            list_iterator = cl_list_head(&tmp_parser_struct.str_list);
1807321936Shselasky                            if ( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
1808321936Shselasky                            {
1809321936Shselasky                                tmp_str = (char*)cl_list_obj(list_iterator);
1810321936Shselasky                                if (tmp_str)
1811321936Shselasky                                    p_current_qos_level->use = tmp_str;
1812321936Shselasky                            }
1813321936Shselasky                            cl_list_remove_all(&tmp_parser_struct.str_list);
1814321936Shselasky                        }
1815321936Shselasky                        ;
1816321936Shselasky
1817321936Shselaskyqos_level_use_start:    TK_USE {
1818321936Shselasky                            RESET_BUFFER;
1819321936Shselasky                        }
1820321936Shselasky                        ;
1821321936Shselasky
1822321936Shselaskyqos_level_sl:           qos_level_sl_start single_number {
1823321936Shselasky                            /* 'sl' in 'qos-level' - one instance */
1824321936Shselasky                            cl_list_iterator_t   list_iterator;
1825321936Shselasky                            uint64_t           * p_num;
1826321936Shselasky
1827321936Shselasky                            if (p_current_qos_level->sl_set)
1828321936Shselasky                            {
1829321936Shselasky                                yyerror("'qos-level' has multiple 'sl' tags");
1830321936Shselasky                                cl_list_remove_all(&tmp_parser_struct.num_list);
1831321936Shselasky                                return 1;
1832321936Shselasky                            }
1833321936Shselasky                            list_iterator = cl_list_head(&tmp_parser_struct.num_list);
1834321936Shselasky                            p_num = (uint64_t*)cl_list_obj(list_iterator);
1835321936Shselasky                            p_current_qos_level->sl = (uint8_t)(*p_num);
1836321936Shselasky                            free(p_num);
1837321936Shselasky                            p_current_qos_level->sl_set = TRUE;
1838321936Shselasky                            cl_list_remove_all(&tmp_parser_struct.num_list);
1839321936Shselasky                        }
1840321936Shselasky                        ;
1841321936Shselasky
1842321936Shselaskyqos_level_sl_start:     TK_SL {
1843321936Shselasky                            RESET_BUFFER;
1844321936Shselasky                        }
1845321936Shselasky                        ;
1846321936Shselasky
1847321936Shselaskyqos_level_mtu_limit:    qos_level_mtu_limit_start single_number {
1848321936Shselasky                            /* 'mtu-limit' in 'qos-level' - one instance */
1849321936Shselasky                            cl_list_iterator_t   list_iterator;
1850321936Shselasky                            uint64_t           * p_num;
1851321936Shselasky
1852321936Shselasky                            if (p_current_qos_level->mtu_limit_set)
1853321936Shselasky                            {
1854321936Shselasky                                yyerror("'qos-level' has multiple 'mtu-limit' tags");
1855321936Shselasky                                cl_list_remove_all(&tmp_parser_struct.num_list);
1856321936Shselasky                                return 1;
1857321936Shselasky                            }
1858321936Shselasky                            list_iterator = cl_list_head(&tmp_parser_struct.num_list);
1859321936Shselasky                            p_num = (uint64_t*)cl_list_obj(list_iterator);
1860321936Shselasky                            if (*p_num > OSM_QOS_POLICY_MAX_MTU || *p_num < OSM_QOS_POLICY_MIN_MTU)
1861321936Shselasky                            {
1862321936Shselasky                                yyerror("mtu limit is out of range, value: %d", *p_num);
1863321936Shselasky                                free(p_num);
1864321936Shselasky                                cl_list_remove_all(&tmp_parser_struct.num_list);
1865321936Shselasky                                return 1;
1866321936Shselasky                            }
1867321936Shselasky                            p_current_qos_level->mtu_limit = (uint8_t)(*p_num);
1868321936Shselasky                            free(p_num);
1869321936Shselasky                            p_current_qos_level->mtu_limit_set = TRUE;
1870321936Shselasky                            cl_list_remove_all(&tmp_parser_struct.num_list);
1871321936Shselasky                        }
1872321936Shselasky                        ;
1873321936Shselasky
1874321936Shselaskyqos_level_mtu_limit_start: TK_MTU_LIMIT {
1875321936Shselasky                            /* 'mtu-limit' in 'qos-level' - one instance */
1876321936Shselasky                            RESET_BUFFER;
1877321936Shselasky                        }
1878321936Shselasky                        ;
1879321936Shselasky
1880321936Shselaskyqos_level_rate_limit:    qos_level_rate_limit_start single_number {
1881321936Shselasky                            /* 'rate-limit' in 'qos-level' - one instance */
1882321936Shselasky                            cl_list_iterator_t   list_iterator;
1883321936Shselasky                            uint64_t           * p_num;
1884321936Shselasky
1885321936Shselasky                            if (p_current_qos_level->rate_limit_set)
1886321936Shselasky                            {
1887321936Shselasky                                yyerror("'qos-level' has multiple 'rate-limit' tags");
1888321936Shselasky                                cl_list_remove_all(&tmp_parser_struct.num_list);
1889321936Shselasky                                return 1;
1890321936Shselasky                            }
1891321936Shselasky                            list_iterator = cl_list_head(&tmp_parser_struct.num_list);
1892321936Shselasky                            p_num = (uint64_t*)cl_list_obj(list_iterator);
1893321936Shselasky                            if (*p_num > OSM_QOS_POLICY_MAX_RATE || *p_num < OSM_QOS_POLICY_MIN_RATE)
1894321936Shselasky                            {
1895321936Shselasky                                yyerror("rate limit is out of range, value: %d", *p_num);
1896321936Shselasky                                free(p_num);
1897321936Shselasky                                cl_list_remove_all(&tmp_parser_struct.num_list);
1898321936Shselasky                                return 1;
1899321936Shselasky                            }
1900321936Shselasky                            p_current_qos_level->rate_limit = (uint8_t)(*p_num);
1901321936Shselasky                            free(p_num);
1902321936Shselasky                            p_current_qos_level->rate_limit_set = TRUE;
1903321936Shselasky                            cl_list_remove_all(&tmp_parser_struct.num_list);
1904321936Shselasky                        }
1905321936Shselasky                        ;
1906321936Shselasky
1907321936Shselaskyqos_level_rate_limit_start: TK_RATE_LIMIT {
1908321936Shselasky                            /* 'rate-limit' in 'qos-level' - one instance */
1909321936Shselasky                            RESET_BUFFER;
1910321936Shselasky                        }
1911321936Shselasky                        ;
1912321936Shselasky
1913321936Shselaskyqos_level_packet_life:  qos_level_packet_life_start single_number {
1914321936Shselasky                            /* 'packet-life' in 'qos-level' - one instance */
1915321936Shselasky                            cl_list_iterator_t   list_iterator;
1916321936Shselasky                            uint64_t           * p_num;
1917321936Shselasky
1918321936Shselasky                            if (p_current_qos_level->pkt_life_set)
1919321936Shselasky                            {
1920321936Shselasky                                yyerror("'qos-level' has multiple 'packet-life' tags");
1921321936Shselasky                                cl_list_remove_all(&tmp_parser_struct.num_list);
1922321936Shselasky                                return 1;
1923321936Shselasky                            }
1924321936Shselasky                            list_iterator = cl_list_head(&tmp_parser_struct.num_list);
1925321936Shselasky                            p_num = (uint64_t*)cl_list_obj(list_iterator);
1926321936Shselasky                            p_current_qos_level->pkt_life = (uint8_t)(*p_num);
1927321936Shselasky                            free(p_num);
1928321936Shselasky                            p_current_qos_level->pkt_life_set= TRUE;
1929321936Shselasky                            cl_list_remove_all(&tmp_parser_struct.num_list);
1930321936Shselasky                        }
1931321936Shselasky                        ;
1932321936Shselasky
1933321936Shselaskyqos_level_packet_life_start: TK_PACKET_LIFE {
1934321936Shselasky                            /* 'packet-life' in 'qos-level' - one instance */
1935321936Shselasky                            RESET_BUFFER;
1936321936Shselasky                        }
1937321936Shselasky                        ;
1938321936Shselasky
1939321936Shselaskyqos_level_path_bits:    qos_level_path_bits_start list_of_ranges {
1940321936Shselasky                            /* 'path-bits' in 'qos-level' - any num of instances */
1941321936Shselasky                            /* list of path bit ranges */
1942321936Shselasky
1943321936Shselasky                            if (cl_list_count(&tmp_parser_struct.num_pair_list))
1944321936Shselasky                            {
1945321936Shselasky                                uint64_t ** range_arr;
1946321936Shselasky                                unsigned range_len;
1947321936Shselasky
1948321936Shselasky                                __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
1949321936Shselasky                                                      &range_arr,
1950321936Shselasky                                                      &range_len );
1951321936Shselasky
1952321936Shselasky                                if ( !p_current_qos_level->path_bits_range_len )
1953321936Shselasky                                {
1954321936Shselasky                                    p_current_qos_level->path_bits_range_arr = range_arr;
1955321936Shselasky                                    p_current_qos_level->path_bits_range_len = range_len;
1956321936Shselasky                                }
1957321936Shselasky                                else
1958321936Shselasky                                {
1959321936Shselasky                                    uint64_t ** new_range_arr;
1960321936Shselasky                                    unsigned new_range_len;
1961321936Shselasky                                    __merge_rangearr( p_current_qos_level->path_bits_range_arr,
1962321936Shselasky                                                      p_current_qos_level->path_bits_range_len,
1963321936Shselasky                                                      range_arr,
1964321936Shselasky                                                      range_len,
1965321936Shselasky                                                      &new_range_arr,
1966321936Shselasky                                                      &new_range_len );
1967321936Shselasky                                    p_current_qos_level->path_bits_range_arr = new_range_arr;
1968321936Shselasky                                    p_current_qos_level->path_bits_range_len = new_range_len;
1969321936Shselasky                                }
1970321936Shselasky                            }
1971321936Shselasky                        }
1972321936Shselasky                        ;
1973321936Shselasky
1974321936Shselaskyqos_level_path_bits_start: TK_PATH_BITS {
1975321936Shselasky                            RESET_BUFFER;
1976321936Shselasky                        }
1977321936Shselasky                        ;
1978321936Shselasky
1979321936Shselaskyqos_level_pkey:         qos_level_pkey_start list_of_ranges {
1980321936Shselasky                            /* 'pkey' in 'qos-level' - num of instances of list of ranges */
1981321936Shselasky                            if (cl_list_count(&tmp_parser_struct.num_pair_list))
1982321936Shselasky                            {
1983321936Shselasky                                uint64_t ** range_arr;
1984321936Shselasky                                unsigned range_len;
1985321936Shselasky
1986321936Shselasky                                __pkey_rangelist2rangearr( &tmp_parser_struct.num_pair_list,
1987321936Shselasky                                                      &range_arr,
1988321936Shselasky                                                      &range_len );
1989321936Shselasky
1990321936Shselasky                                if ( !p_current_qos_level->pkey_range_len )
1991321936Shselasky                                {
1992321936Shselasky                                    p_current_qos_level->pkey_range_arr = range_arr;
1993321936Shselasky                                    p_current_qos_level->pkey_range_len = range_len;
1994321936Shselasky                                }
1995321936Shselasky                                else
1996321936Shselasky                                {
1997321936Shselasky                                    uint64_t ** new_range_arr;
1998321936Shselasky                                    unsigned new_range_len;
1999321936Shselasky                                    __merge_rangearr( p_current_qos_level->pkey_range_arr,
2000321936Shselasky                                                      p_current_qos_level->pkey_range_len,
2001321936Shselasky                                                      range_arr,
2002321936Shselasky                                                      range_len,
2003321936Shselasky                                                      &new_range_arr,
2004321936Shselasky                                                      &new_range_len );
2005321936Shselasky                                    p_current_qos_level->pkey_range_arr = new_range_arr;
2006321936Shselasky                                    p_current_qos_level->pkey_range_len = new_range_len;
2007321936Shselasky                                }
2008321936Shselasky                            }
2009321936Shselasky                        }
2010321936Shselasky                        ;
2011321936Shselasky
2012321936Shselaskyqos_level_pkey_start:   TK_PKEY {
2013321936Shselasky                            RESET_BUFFER;
2014321936Shselasky                        }
2015321936Shselasky                        ;
2016321936Shselasky
2017321936Shselasky    /*
2018321936Shselasky     *  qos_match_rule_entry values:
2019321936Shselasky     *      qos_match_rule_use
2020321936Shselasky     *      qos_match_rule_qos_class
2021321936Shselasky     *      qos_match_rule_qos_level_name
2022321936Shselasky     *      qos_match_rule_source
2023321936Shselasky     *      qos_match_rule_destination
2024321936Shselasky     *      qos_match_rule_service_id
2025321936Shselasky     *      qos_match_rule_pkey
2026321936Shselasky     */
2027321936Shselasky
2028321936Shselasky
2029321936Shselaskyqos_match_rule_use:     qos_match_rule_use_start single_string {
2030321936Shselasky                            /* 'use' of 'qos-match-rule' - one instance */
2031321936Shselasky                            cl_list_iterator_t    list_iterator;
2032321936Shselasky                            char                * tmp_str;
2033321936Shselasky
2034321936Shselasky                            if (p_current_qos_match_rule->use)
2035321936Shselasky                            {
2036321936Shselasky                                yyerror("'qos-match-rule' has multiple 'use' tags");
2037321936Shselasky                                cl_list_remove_all(&tmp_parser_struct.str_list);
2038321936Shselasky                                return 1;
2039321936Shselasky                            }
2040321936Shselasky
2041321936Shselasky                            list_iterator = cl_list_head(&tmp_parser_struct.str_list);
2042321936Shselasky                            if ( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
2043321936Shselasky                            {
2044321936Shselasky                                tmp_str = (char*)cl_list_obj(list_iterator);
2045321936Shselasky                                if (tmp_str)
2046321936Shselasky                                    p_current_qos_match_rule->use = tmp_str;
2047321936Shselasky                            }
2048321936Shselasky                            cl_list_remove_all(&tmp_parser_struct.str_list);
2049321936Shselasky                        }
2050321936Shselasky                        ;
2051321936Shselasky
2052321936Shselaskyqos_match_rule_use_start: TK_USE {
2053321936Shselasky                            RESET_BUFFER;
2054321936Shselasky                        }
2055321936Shselasky                        ;
2056321936Shselasky
2057321936Shselaskyqos_match_rule_qos_class: qos_match_rule_qos_class_start list_of_ranges {
2058321936Shselasky                            /* 'qos-class' in 'qos-match-rule' - num of instances of list of ranges */
2059321936Shselasky                            /* list of class ranges (QoS Class is 12-bit value) */
2060321936Shselasky                            if (cl_list_count(&tmp_parser_struct.num_pair_list))
2061321936Shselasky                            {
2062321936Shselasky                                uint64_t ** range_arr;
2063321936Shselasky                                unsigned range_len;
2064321936Shselasky
2065321936Shselasky                                __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
2066321936Shselasky                                                      &range_arr,
2067321936Shselasky                                                      &range_len );
2068321936Shselasky
2069321936Shselasky                                if ( !p_current_qos_match_rule->qos_class_range_len )
2070321936Shselasky                                {
2071321936Shselasky                                    p_current_qos_match_rule->qos_class_range_arr = range_arr;
2072321936Shselasky                                    p_current_qos_match_rule->qos_class_range_len = range_len;
2073321936Shselasky                                }
2074321936Shselasky                                else
2075321936Shselasky                                {
2076321936Shselasky                                    uint64_t ** new_range_arr;
2077321936Shselasky                                    unsigned new_range_len;
2078321936Shselasky                                    __merge_rangearr( p_current_qos_match_rule->qos_class_range_arr,
2079321936Shselasky                                                      p_current_qos_match_rule->qos_class_range_len,
2080321936Shselasky                                                      range_arr,
2081321936Shselasky                                                      range_len,
2082321936Shselasky                                                      &new_range_arr,
2083321936Shselasky                                                      &new_range_len );
2084321936Shselasky                                    p_current_qos_match_rule->qos_class_range_arr = new_range_arr;
2085321936Shselasky                                    p_current_qos_match_rule->qos_class_range_len = new_range_len;
2086321936Shselasky                                }
2087321936Shselasky                            }
2088321936Shselasky                        }
2089321936Shselasky                        ;
2090321936Shselasky
2091321936Shselaskyqos_match_rule_qos_class_start: TK_QOS_CLASS {
2092321936Shselasky                            RESET_BUFFER;
2093321936Shselasky                        }
2094321936Shselasky                        ;
2095321936Shselasky
2096321936Shselaskyqos_match_rule_source:  qos_match_rule_source_start string_list {
2097321936Shselasky                            /* 'source' in 'qos-match-rule' - text */
2098321936Shselasky                            cl_list_iterator_t    list_iterator;
2099321936Shselasky                            char                * tmp_str;
2100321936Shselasky
2101321936Shselasky                            list_iterator = cl_list_head(&tmp_parser_struct.str_list);
2102321936Shselasky                            while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
2103321936Shselasky                            {
2104321936Shselasky                                tmp_str = (char*)cl_list_obj(list_iterator);
2105321936Shselasky                                if (tmp_str)
2106321936Shselasky                                    cl_list_insert_tail(&p_current_qos_match_rule->source_list,tmp_str);
2107321936Shselasky                                list_iterator = cl_list_next(list_iterator);
2108321936Shselasky                            }
2109321936Shselasky                            cl_list_remove_all(&tmp_parser_struct.str_list);
2110321936Shselasky                        }
2111321936Shselasky                        ;
2112321936Shselasky
2113321936Shselaskyqos_match_rule_source_start: TK_SOURCE {
2114321936Shselasky                            RESET_BUFFER;
2115321936Shselasky                        }
2116321936Shselasky                        ;
2117321936Shselasky
2118321936Shselaskyqos_match_rule_destination: qos_match_rule_destination_start string_list {
2119321936Shselasky                            /* 'destination' in 'qos-match-rule' - text */
2120321936Shselasky                            cl_list_iterator_t    list_iterator;
2121321936Shselasky                            char                * tmp_str;
2122321936Shselasky
2123321936Shselasky                            list_iterator = cl_list_head(&tmp_parser_struct.str_list);
2124321936Shselasky                            while( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
2125321936Shselasky                            {
2126321936Shselasky                                tmp_str = (char*)cl_list_obj(list_iterator);
2127321936Shselasky                                if (tmp_str)
2128321936Shselasky                                    cl_list_insert_tail(&p_current_qos_match_rule->destination_list,tmp_str);
2129321936Shselasky                                list_iterator = cl_list_next(list_iterator);
2130321936Shselasky                            }
2131321936Shselasky                            cl_list_remove_all(&tmp_parser_struct.str_list);
2132321936Shselasky                        }
2133321936Shselasky                        ;
2134321936Shselasky
2135321936Shselaskyqos_match_rule_destination_start: TK_DESTINATION {
2136321936Shselasky                            RESET_BUFFER;
2137321936Shselasky                        }
2138321936Shselasky                        ;
2139321936Shselasky
2140321936Shselaskyqos_match_rule_qos_level_name:  qos_match_rule_qos_level_name_start single_string {
2141321936Shselasky                            /* 'qos-level-name' in 'qos-match-rule' - single string */
2142321936Shselasky                            cl_list_iterator_t   list_iterator;
2143321936Shselasky                            char               * tmp_str;
2144321936Shselasky
2145321936Shselasky                            if (p_current_qos_match_rule->qos_level_name)
2146321936Shselasky                            {
2147321936Shselasky                                yyerror("qos-match-rule has multiple 'qos-level-name' tags");
2148321936Shselasky                                cl_list_remove_all(&tmp_parser_struct.num_list);
2149321936Shselasky                                return 1;
2150321936Shselasky                            }
2151321936Shselasky
2152321936Shselasky                            list_iterator = cl_list_head(&tmp_parser_struct.str_list);
2153321936Shselasky                            if ( list_iterator != cl_list_end(&tmp_parser_struct.str_list) )
2154321936Shselasky                            {
2155321936Shselasky                                tmp_str = (char*)cl_list_obj(list_iterator);
2156321936Shselasky                                if (tmp_str)
2157321936Shselasky                                    p_current_qos_match_rule->qos_level_name = tmp_str;
2158321936Shselasky                            }
2159321936Shselasky                            cl_list_remove_all(&tmp_parser_struct.str_list);
2160321936Shselasky                        }
2161321936Shselasky                        ;
2162321936Shselasky
2163321936Shselaskyqos_match_rule_qos_level_name_start: TK_QOS_LEVEL_NAME {
2164321936Shselasky                            RESET_BUFFER;
2165321936Shselasky                        }
2166321936Shselasky                        ;
2167321936Shselasky
2168321936Shselaskyqos_match_rule_service_id: qos_match_rule_service_id_start list_of_ranges {
2169321936Shselasky                            /* 'service-id' in 'qos-match-rule' - num of instances of list of ranges */
2170321936Shselasky                            if (cl_list_count(&tmp_parser_struct.num_pair_list))
2171321936Shselasky                            {
2172321936Shselasky                                uint64_t ** range_arr;
2173321936Shselasky                                unsigned range_len;
2174321936Shselasky
2175321936Shselasky                                __rangelist2rangearr( &tmp_parser_struct.num_pair_list,
2176321936Shselasky                                                      &range_arr,
2177321936Shselasky                                                      &range_len );
2178321936Shselasky
2179321936Shselasky                                if ( !p_current_qos_match_rule->service_id_range_len )
2180321936Shselasky                                {
2181321936Shselasky                                    p_current_qos_match_rule->service_id_range_arr = range_arr;
2182321936Shselasky                                    p_current_qos_match_rule->service_id_range_len = range_len;
2183321936Shselasky                                }
2184321936Shselasky                                else
2185321936Shselasky                                {
2186321936Shselasky                                    uint64_t ** new_range_arr;
2187321936Shselasky                                    unsigned new_range_len;
2188321936Shselasky                                    __merge_rangearr( p_current_qos_match_rule->service_id_range_arr,
2189321936Shselasky                                                      p_current_qos_match_rule->service_id_range_len,
2190321936Shselasky                                                      range_arr,
2191321936Shselasky                                                      range_len,
2192321936Shselasky                                                      &new_range_arr,
2193321936Shselasky                                                      &new_range_len );
2194321936Shselasky                                    p_current_qos_match_rule->service_id_range_arr = new_range_arr;
2195321936Shselasky                                    p_current_qos_match_rule->service_id_range_len = new_range_len;
2196321936Shselasky                                }
2197321936Shselasky                            }
2198321936Shselasky                        }
2199321936Shselasky                        ;
2200321936Shselasky
2201321936Shselaskyqos_match_rule_service_id_start: TK_SERVICE_ID {
2202321936Shselasky                            RESET_BUFFER;
2203321936Shselasky                        }
2204321936Shselasky                        ;
2205321936Shselasky
2206321936Shselaskyqos_match_rule_pkey:    qos_match_rule_pkey_start list_of_ranges {
2207321936Shselasky                            /* 'pkey' in 'qos-match-rule' - num of instances of list of ranges */
2208321936Shselasky                            if (cl_list_count(&tmp_parser_struct.num_pair_list))
2209321936Shselasky                            {
2210321936Shselasky                                uint64_t ** range_arr;
2211321936Shselasky                                unsigned range_len;
2212321936Shselasky
2213321936Shselasky                                __pkey_rangelist2rangearr( &tmp_parser_struct.num_pair_list,
2214321936Shselasky                                                      &range_arr,
2215321936Shselasky                                                      &range_len );
2216321936Shselasky
2217321936Shselasky                                if ( !p_current_qos_match_rule->pkey_range_len )
2218321936Shselasky                                {
2219321936Shselasky                                    p_current_qos_match_rule->pkey_range_arr = range_arr;
2220321936Shselasky                                    p_current_qos_match_rule->pkey_range_len = range_len;
2221321936Shselasky                                }
2222321936Shselasky                                else
2223321936Shselasky                                {
2224321936Shselasky                                    uint64_t ** new_range_arr;
2225321936Shselasky                                    unsigned new_range_len;
2226321936Shselasky                                    __merge_rangearr( p_current_qos_match_rule->pkey_range_arr,
2227321936Shselasky                                                      p_current_qos_match_rule->pkey_range_len,
2228321936Shselasky                                                      range_arr,
2229321936Shselasky                                                      range_len,
2230321936Shselasky                                                      &new_range_arr,
2231321936Shselasky                                                      &new_range_len );
2232321936Shselasky                                    p_current_qos_match_rule->pkey_range_arr = new_range_arr;
2233321936Shselasky                                    p_current_qos_match_rule->pkey_range_len = new_range_len;
2234321936Shselasky                                }
2235321936Shselasky                            }
2236321936Shselasky                        }
2237321936Shselasky                        ;
2238321936Shselasky
2239321936Shselaskyqos_match_rule_pkey_start: TK_PKEY {
2240321936Shselasky                            RESET_BUFFER;
2241321936Shselasky                        }
2242321936Shselasky                        ;
2243321936Shselasky
2244321936Shselasky
2245321936Shselasky    /*
2246321936Shselasky     * Common part
2247321936Shselasky     */
2248321936Shselasky
2249321936Shselasky
2250321936Shselaskysingle_string:      single_string_elems {
2251321936Shselasky                        cl_list_insert_tail(&tmp_parser_struct.str_list,
2252321936Shselasky                                            strdup(__parser_strip_white(tmp_parser_struct.str)));
2253321936Shselasky                        tmp_parser_struct.str[0] = '\0';
2254321936Shselasky                    }
2255321936Shselasky                    ;
2256321936Shselasky
2257321936Shselaskysingle_string_elems:  single_string_element
2258321936Shselasky                    | single_string_elems single_string_element
2259321936Shselasky                    ;
2260321936Shselasky
2261321936Shselaskysingle_string_element: TK_TEXT {
2262321936Shselasky                        strcat(tmp_parser_struct.str,$1);
2263321936Shselasky                        free($1);
2264321936Shselasky                    }
2265321936Shselasky                    ;
2266321936Shselasky
2267321936Shselasky
2268321936Shselaskystring_list:        single_string
2269321936Shselasky                    | string_list TK_COMMA single_string
2270321936Shselasky                    ;
2271321936Shselasky
2272321936Shselasky
2273321936Shselasky
2274321936Shselaskysingle_number:      number
2275321936Shselasky                    ;
2276321936Shselasky
2277321936Shselaskynum_list:             number
2278321936Shselasky                    | num_list TK_COMMA number
2279321936Shselasky                    ;
2280321936Shselasky
2281321936Shselaskynumber:             TK_NUMBER {
2282321936Shselasky                        uint64_t * p_num = (uint64_t*)malloc(sizeof(uint64_t));
2283321936Shselasky                        __parser_str2uint64(p_num,$1);
2284321936Shselasky                        free($1);
2285321936Shselasky                        cl_list_insert_tail(&tmp_parser_struct.num_list, p_num);
2286321936Shselasky                    }
2287321936Shselasky                    ;
2288321936Shselasky
2289321936Shselaskynum_list_with_dotdot: number_from_pair_1 TK_DOTDOT number_from_pair_2 {
2290321936Shselasky                        uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
2291321936Shselasky                        num_pair[0] = tmp_parser_struct.num_pair[0];
2292321936Shselasky                        num_pair[1] = tmp_parser_struct.num_pair[1];
2293321936Shselasky                        cl_list_insert_tail(&tmp_parser_struct.num_pair_list, num_pair);
2294321936Shselasky                    }
2295321936Shselasky                    | num_list_with_dotdot TK_COMMA number_from_pair_1 TK_DOTDOT number_from_pair_2 {
2296321936Shselasky                        uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
2297321936Shselasky                        num_pair[0] = tmp_parser_struct.num_pair[0];
2298321936Shselasky                        num_pair[1] = tmp_parser_struct.num_pair[1];
2299321936Shselasky                        cl_list_insert_tail(&tmp_parser_struct.num_pair_list, num_pair);
2300321936Shselasky                    }
2301321936Shselasky                    ;
2302321936Shselasky
2303321936Shselaskynumber_from_pair_1:   TK_NUMBER {
2304321936Shselasky                        __parser_str2uint64(&tmp_parser_struct.num_pair[0],$1);
2305321936Shselasky                        free($1);
2306321936Shselasky                    }
2307321936Shselasky                    ;
2308321936Shselasky
2309321936Shselaskynumber_from_pair_2:   TK_NUMBER {
2310321936Shselasky                        __parser_str2uint64(&tmp_parser_struct.num_pair[1],$1);
2311321936Shselasky                        free($1);
2312321936Shselasky                    }
2313321936Shselasky                    ;
2314321936Shselasky
2315321936Shselaskylist_of_ranges:     num_list_with_dash
2316321936Shselasky                    ;
2317321936Shselasky
2318321936Shselaskynum_list_with_dash:   single_number_from_range {
2319321936Shselasky                        uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
2320321936Shselasky                        num_pair[0] = tmp_parser_struct.num_pair[0];
2321321936Shselasky                        num_pair[1] = tmp_parser_struct.num_pair[1];
2322321936Shselasky                        cl_list_insert_tail(&tmp_parser_struct.num_pair_list, num_pair);
2323321936Shselasky                    }
2324321936Shselasky                    | number_from_range_1 TK_DASH number_from_range_2 {
2325321936Shselasky                        uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
2326321936Shselasky                        if (tmp_parser_struct.num_pair[0] <= tmp_parser_struct.num_pair[1]) {
2327321936Shselasky                            num_pair[0] = tmp_parser_struct.num_pair[0];
2328321936Shselasky                            num_pair[1] = tmp_parser_struct.num_pair[1];
2329321936Shselasky                        }
2330321936Shselasky                        else {
2331321936Shselasky                            num_pair[1] = tmp_parser_struct.num_pair[0];
2332321936Shselasky                            num_pair[0] = tmp_parser_struct.num_pair[1];
2333321936Shselasky                        }
2334321936Shselasky                        cl_list_insert_tail(&tmp_parser_struct.num_pair_list, num_pair);
2335321936Shselasky                    }
2336321936Shselasky                    | num_list_with_dash TK_COMMA number_from_range_1 TK_DASH number_from_range_2 {
2337321936Shselasky                        uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
2338321936Shselasky                        if (tmp_parser_struct.num_pair[0] <= tmp_parser_struct.num_pair[1]) {
2339321936Shselasky                            num_pair[0] = tmp_parser_struct.num_pair[0];
2340321936Shselasky                            num_pair[1] = tmp_parser_struct.num_pair[1];
2341321936Shselasky                        }
2342321936Shselasky                        else {
2343321936Shselasky                            num_pair[1] = tmp_parser_struct.num_pair[0];
2344321936Shselasky                            num_pair[0] = tmp_parser_struct.num_pair[1];
2345321936Shselasky                        }
2346321936Shselasky                        cl_list_insert_tail(&tmp_parser_struct.num_pair_list, num_pair);
2347321936Shselasky                    }
2348321936Shselasky                    | num_list_with_dash TK_COMMA single_number_from_range {
2349321936Shselasky                        uint64_t * num_pair = (uint64_t*)malloc(sizeof(uint64_t)*2);
2350321936Shselasky                        num_pair[0] = tmp_parser_struct.num_pair[0];
2351321936Shselasky                        num_pair[1] = tmp_parser_struct.num_pair[1];
2352321936Shselasky                        cl_list_insert_tail(&tmp_parser_struct.num_pair_list, num_pair);
2353321936Shselasky                    }
2354321936Shselasky                    ;
2355321936Shselasky
2356321936Shselaskysingle_number_from_range:  TK_NUMBER {
2357321936Shselasky                        __parser_str2uint64(&tmp_parser_struct.num_pair[0],$1);
2358321936Shselasky                        __parser_str2uint64(&tmp_parser_struct.num_pair[1],$1);
2359321936Shselasky                        free($1);
2360321936Shselasky                    }
2361321936Shselasky                    ;
2362321936Shselasky
2363321936Shselaskynumber_from_range_1:  TK_NUMBER {
2364321936Shselasky                        __parser_str2uint64(&tmp_parser_struct.num_pair[0],$1);
2365321936Shselasky                        free($1);
2366321936Shselasky                    }
2367321936Shselasky                    ;
2368321936Shselasky
2369321936Shselaskynumber_from_range_2:  TK_NUMBER {
2370321936Shselasky                        __parser_str2uint64(&tmp_parser_struct.num_pair[1],$1);
2371321936Shselasky                        free($1);
2372321936Shselasky                    }
2373321936Shselasky                    ;
2374321936Shselasky
2375321936Shselasky%%
2376321936Shselasky
2377321936Shselasky/***************************************************
2378321936Shselasky ***************************************************/
2379321936Shselasky
2380321936Shselaskyint osm_qos_parse_policy_file(IN osm_subn_t * p_subn)
2381321936Shselasky{
2382321936Shselasky    int res = 0;
2383321936Shselasky    static boolean_t first_time = TRUE;
2384321936Shselasky    p_qos_parser_osm_log = &p_subn->p_osm->log;
2385321936Shselasky
2386321936Shselasky    OSM_LOG_ENTER(p_qos_parser_osm_log);
2387321936Shselasky
2388321936Shselasky    osm_qos_policy_destroy(p_subn->p_qos_policy);
2389321936Shselasky    p_subn->p_qos_policy = NULL;
2390321936Shselasky
2391321936Shselasky    yyin = fopen (p_subn->opt.qos_policy_file, "r");
2392321936Shselasky    if (!yyin)
2393321936Shselasky    {
2394321936Shselasky        if (strcmp(p_subn->opt.qos_policy_file,OSM_DEFAULT_QOS_POLICY_FILE)) {
2395321936Shselasky            OSM_LOG(p_qos_parser_osm_log, OSM_LOG_ERROR, "ERR AC01: "
2396321936Shselasky                    "Failed opening QoS policy file %s - %s\n",
2397321936Shselasky                    p_subn->opt.qos_policy_file, strerror(errno));
2398321936Shselasky            res = 1;
2399321936Shselasky        }
2400321936Shselasky        else
2401321936Shselasky            OSM_LOG(p_qos_parser_osm_log, OSM_LOG_VERBOSE,
2402321936Shselasky                    "QoS policy file not found (%s)\n",
2403321936Shselasky                    p_subn->opt.qos_policy_file);
2404321936Shselasky
2405321936Shselasky        goto Exit;
2406321936Shselasky    }
2407321936Shselasky
2408321936Shselasky    if (first_time)
2409321936Shselasky    {
2410321936Shselasky        first_time = FALSE;
2411321936Shselasky        __setup_simple_qos_levels();
2412321936Shselasky        __setup_ulp_match_rules();
2413321936Shselasky        OSM_LOG(p_qos_parser_osm_log, OSM_LOG_INFO,
2414321936Shselasky		"Loading QoS policy file (%s)\n",
2415321936Shselasky                p_subn->opt.qos_policy_file);
2416321936Shselasky    }
2417321936Shselasky    else
2418321936Shselasky        /*
2419321936Shselasky         * ULP match rules list was emptied at the end of
2420321936Shselasky         * previous parsing iteration.
2421321936Shselasky         * What's left is to clear simple QoS levels.
2422321936Shselasky         */
2423321936Shselasky        __clear_simple_qos_levels();
2424321936Shselasky
2425321936Shselasky    column_num = 1;
2426321936Shselasky    line_num = 1;
2427321936Shselasky
2428321936Shselasky    p_subn->p_qos_policy = osm_qos_policy_create(p_subn);
2429321936Shselasky
2430321936Shselasky    __parser_tmp_struct_init();
2431321936Shselasky    p_qos_policy = p_subn->p_qos_policy;
2432321936Shselasky
2433321936Shselasky    res = yyparse();
2434321936Shselasky
2435321936Shselasky    __parser_tmp_struct_destroy();
2436321936Shselasky
2437321936Shselasky    if (res != 0)
2438321936Shselasky    {
2439321936Shselasky        OSM_LOG(p_qos_parser_osm_log, OSM_LOG_ERROR, "ERR AC03: "
2440321936Shselasky                "Failed parsing QoS policy file (%s)\n",
2441321936Shselasky                p_subn->opt.qos_policy_file);
2442321936Shselasky        osm_qos_policy_destroy(p_subn->p_qos_policy);
2443321936Shselasky        p_subn->p_qos_policy = NULL;
2444321936Shselasky        res = 1;
2445321936Shselasky        goto Exit;
2446321936Shselasky    }
2447321936Shselasky
2448321936Shselasky    /* add generated ULP match rules to the usual match rules */
2449321936Shselasky    __process_ulp_match_rules();
2450321936Shselasky
2451321936Shselasky    if (osm_qos_policy_validate(p_subn->p_qos_policy,p_qos_parser_osm_log))
2452321936Shselasky    {
2453321936Shselasky        OSM_LOG(p_qos_parser_osm_log, OSM_LOG_ERROR, "ERR AC04: "
2454321936Shselasky                "Error(s) in QoS policy file (%s)\n",
2455321936Shselasky                p_subn->opt.qos_policy_file);
2456321936Shselasky        fprintf(stderr, "Error(s) in QoS policy file (%s)\n",
2457321936Shselasky                p_subn->opt.qos_policy_file);
2458321936Shselasky        osm_qos_policy_destroy(p_subn->p_qos_policy);
2459321936Shselasky        p_subn->p_qos_policy = NULL;
2460321936Shselasky        res = 1;
2461321936Shselasky        goto Exit;
2462321936Shselasky    }
2463321936Shselasky
2464321936Shselasky  Exit:
2465321936Shselasky    if (yyin)
2466321936Shselasky    {
2467321936Shselasky        yyrestart(yyin);
2468321936Shselasky        fclose(yyin);
2469321936Shselasky    }
2470321936Shselasky    OSM_LOG_EXIT(p_qos_parser_osm_log);
2471321936Shselasky    return res;
2472321936Shselasky}
2473321936Shselasky
2474321936Shselasky/***************************************************
2475321936Shselasky ***************************************************/
2476321936Shselasky
2477321936Shselaskyint yywrap()
2478321936Shselasky{
2479321936Shselasky    return(1);
2480321936Shselasky}
2481321936Shselasky
2482321936Shselasky/***************************************************
2483321936Shselasky ***************************************************/
2484321936Shselasky
2485321936Shselaskystatic void yyerror(const char *format, ...)
2486321936Shselasky{
2487321936Shselasky    char s[256];
2488321936Shselasky    va_list pvar;
2489321936Shselasky
2490321936Shselasky    OSM_LOG_ENTER(p_qos_parser_osm_log);
2491321936Shselasky
2492321936Shselasky    va_start(pvar, format);
2493321936Shselasky    vsnprintf(s, sizeof(s), format, pvar);
2494321936Shselasky    va_end(pvar);
2495321936Shselasky
2496321936Shselasky    OSM_LOG(p_qos_parser_osm_log, OSM_LOG_ERROR, "ERR AC05: "
2497321936Shselasky            "Syntax error (line %d:%d): %s\n",
2498321936Shselasky            line_num, column_num, s);
2499321936Shselasky    fprintf(stderr, "Error in QoS Policy File (line %d:%d): %s.\n",
2500321936Shselasky            line_num, column_num, s);
2501321936Shselasky    OSM_LOG_EXIT(p_qos_parser_osm_log);
2502321936Shselasky}
2503321936Shselasky
2504321936Shselasky/***************************************************
2505321936Shselasky ***************************************************/
2506321936Shselasky
2507321936Shselaskystatic char * __parser_strip_white(char * str)
2508321936Shselasky{
2509321936Shselasky	char *p;
2510321936Shselasky
2511321936Shselasky	while (isspace(*str))
2512321936Shselasky		str++;
2513321936Shselasky	if (!*str)
2514321936Shselasky		return str;
2515321936Shselasky	p = str + strlen(str) - 1;
2516321936Shselasky	while (isspace(*p))
2517321936Shselasky		*p-- = '\0';
2518321936Shselasky
2519321936Shselasky	return str;
2520321936Shselasky}
2521321936Shselasky
2522321936Shselasky/***************************************************
2523321936Shselasky ***************************************************/
2524321936Shselasky
2525321936Shselaskystatic void __parser_str2uint64(uint64_t * p_val, char * str)
2526321936Shselasky{
2527321936Shselasky   *p_val = strtoull(str, NULL, 0);
2528321936Shselasky}
2529321936Shselasky
2530321936Shselasky/***************************************************
2531321936Shselasky ***************************************************/
2532321936Shselasky
2533321936Shselaskystatic void __parser_port_group_start()
2534321936Shselasky{
2535321936Shselasky    p_current_port_group = osm_qos_policy_port_group_create();
2536321936Shselasky}
2537321936Shselasky
2538321936Shselasky/***************************************************
2539321936Shselasky ***************************************************/
2540321936Shselasky
2541321936Shselaskystatic int __parser_port_group_end()
2542321936Shselasky{
2543321936Shselasky    if(!p_current_port_group->name)
2544321936Shselasky    {
2545321936Shselasky        yyerror("port-group validation failed - no port group name specified");
2546321936Shselasky        return -1;
2547321936Shselasky    }
2548321936Shselasky
2549321936Shselasky    cl_list_insert_tail(&p_qos_policy->port_groups,
2550321936Shselasky                        p_current_port_group);
2551321936Shselasky    p_current_port_group = NULL;
2552321936Shselasky    return 0;
2553321936Shselasky}
2554321936Shselasky
2555321936Shselasky/***************************************************
2556321936Shselasky ***************************************************/
2557321936Shselasky
2558321936Shselaskystatic void __parser_vlarb_scope_start()
2559321936Shselasky{
2560321936Shselasky    p_current_vlarb_scope = osm_qos_policy_vlarb_scope_create();
2561321936Shselasky}
2562321936Shselasky
2563321936Shselasky/***************************************************
2564321936Shselasky ***************************************************/
2565321936Shselasky
2566321936Shselaskystatic int __parser_vlarb_scope_end()
2567321936Shselasky{
2568321936Shselasky    if ( !cl_list_count(&p_current_vlarb_scope->group_list) &&
2569321936Shselasky         !cl_list_count(&p_current_vlarb_scope->across_list) )
2570321936Shselasky    {
2571321936Shselasky        yyerror("vlarb-scope validation failed - no port groups specified by 'group' or by 'across'");
2572321936Shselasky        return -1;
2573321936Shselasky    }
2574321936Shselasky
2575321936Shselasky    cl_list_insert_tail(&p_qos_policy->vlarb_tables,
2576321936Shselasky                        p_current_vlarb_scope);
2577321936Shselasky    p_current_vlarb_scope = NULL;
2578321936Shselasky    return 0;
2579321936Shselasky}
2580321936Shselasky
2581321936Shselasky/***************************************************
2582321936Shselasky ***************************************************/
2583321936Shselasky
2584321936Shselaskystatic void __parser_sl2vl_scope_start()
2585321936Shselasky{
2586321936Shselasky    p_current_sl2vl_scope = osm_qos_policy_sl2vl_scope_create();
2587321936Shselasky}
2588321936Shselasky
2589321936Shselasky/***************************************************
2590321936Shselasky ***************************************************/
2591321936Shselasky
2592321936Shselaskystatic int __parser_sl2vl_scope_end()
2593321936Shselasky{
2594321936Shselasky    if (!p_current_sl2vl_scope->sl2vl_table_set)
2595321936Shselasky    {
2596321936Shselasky        yyerror("sl2vl-scope validation failed - no sl2vl table specified");
2597321936Shselasky        return -1;
2598321936Shselasky    }
2599321936Shselasky    if ( !cl_list_count(&p_current_sl2vl_scope->group_list) &&
2600321936Shselasky         !cl_list_count(&p_current_sl2vl_scope->across_to_list) &&
2601321936Shselasky         !cl_list_count(&p_current_sl2vl_scope->across_from_list) )
2602321936Shselasky    {
2603321936Shselasky        yyerror("sl2vl-scope validation failed - no port groups specified by 'group', 'across-to' or 'across-from'");
2604321936Shselasky        return -1;
2605321936Shselasky    }
2606321936Shselasky
2607321936Shselasky    cl_list_insert_tail(&p_qos_policy->sl2vl_tables,
2608321936Shselasky                        p_current_sl2vl_scope);
2609321936Shselasky    p_current_sl2vl_scope = NULL;
2610321936Shselasky    return 0;
2611321936Shselasky}
2612321936Shselasky
2613321936Shselasky/***************************************************
2614321936Shselasky ***************************************************/
2615321936Shselasky
2616321936Shselaskystatic void __parser_qos_level_start()
2617321936Shselasky{
2618321936Shselasky    p_current_qos_level = osm_qos_policy_qos_level_create();
2619321936Shselasky}
2620321936Shselasky
2621321936Shselasky/***************************************************
2622321936Shselasky ***************************************************/
2623321936Shselasky
2624321936Shselaskystatic int __parser_qos_level_end()
2625321936Shselasky{
2626321936Shselasky    if (!p_current_qos_level->sl_set)
2627321936Shselasky    {
2628321936Shselasky        yyerror("qos-level validation failed - no 'sl' specified");
2629321936Shselasky        return -1;
2630321936Shselasky    }
2631321936Shselasky    if (!p_current_qos_level->name)
2632321936Shselasky    {
2633321936Shselasky        yyerror("qos-level validation failed - no 'name' specified");
2634321936Shselasky        return -1;
2635321936Shselasky    }
2636321936Shselasky
2637321936Shselasky    cl_list_insert_tail(&p_qos_policy->qos_levels,
2638321936Shselasky                        p_current_qos_level);
2639321936Shselasky    p_current_qos_level = NULL;
2640321936Shselasky    return 0;
2641321936Shselasky}
2642321936Shselasky
2643321936Shselasky/***************************************************
2644321936Shselasky ***************************************************/
2645321936Shselasky
2646321936Shselaskystatic void __parser_match_rule_start()
2647321936Shselasky{
2648321936Shselasky    p_current_qos_match_rule = osm_qos_policy_match_rule_create();
2649321936Shselasky}
2650321936Shselasky
2651321936Shselasky/***************************************************
2652321936Shselasky ***************************************************/
2653321936Shselasky
2654321936Shselaskystatic int __parser_match_rule_end()
2655321936Shselasky{
2656321936Shselasky    if (!p_current_qos_match_rule->qos_level_name)
2657321936Shselasky    {
2658321936Shselasky        yyerror("match-rule validation failed - no 'qos-level-name' specified");
2659321936Shselasky        return -1;
2660321936Shselasky    }
2661321936Shselasky
2662321936Shselasky    cl_list_insert_tail(&p_qos_policy->qos_match_rules,
2663321936Shselasky                        p_current_qos_match_rule);
2664321936Shselasky    p_current_qos_match_rule = NULL;
2665321936Shselasky    return 0;
2666321936Shselasky}
2667321936Shselasky
2668321936Shselasky/***************************************************
2669321936Shselasky ***************************************************/
2670321936Shselasky
2671321936Shselaskystatic void __parser_ulp_match_rule_start()
2672321936Shselasky{
2673321936Shselasky    p_current_qos_match_rule = osm_qos_policy_match_rule_create();
2674321936Shselasky}
2675321936Shselasky
2676321936Shselasky/***************************************************
2677321936Shselasky ***************************************************/
2678321936Shselasky
2679321936Shselaskystatic int __parser_ulp_match_rule_end()
2680321936Shselasky{
2681321936Shselasky    CL_ASSERT(p_current_qos_match_rule->p_qos_level);
2682321936Shselasky    cl_list_insert_tail(&__ulp_match_rules,
2683321936Shselasky                        p_current_qos_match_rule);
2684321936Shselasky    p_current_qos_match_rule = NULL;
2685321936Shselasky    return 0;
2686321936Shselasky}
2687321936Shselasky
2688321936Shselasky/***************************************************
2689321936Shselasky ***************************************************/
2690321936Shselasky
2691321936Shselaskystatic void __parser_tmp_struct_init()
2692321936Shselasky{
2693321936Shselasky    tmp_parser_struct.str[0] = '\0';
2694321936Shselasky    cl_list_construct(&tmp_parser_struct.str_list);
2695321936Shselasky    cl_list_init(&tmp_parser_struct.str_list, 10);
2696321936Shselasky    cl_list_construct(&tmp_parser_struct.num_list);
2697321936Shselasky    cl_list_init(&tmp_parser_struct.num_list, 10);
2698321936Shselasky    cl_list_construct(&tmp_parser_struct.num_pair_list);
2699321936Shselasky    cl_list_init(&tmp_parser_struct.num_pair_list, 10);
2700321936Shselasky}
2701321936Shselasky
2702321936Shselasky/***************************************************
2703321936Shselasky ***************************************************/
2704321936Shselasky
2705321936Shselasky/*
2706321936Shselasky * Do NOT free objects from the temp struct.
2707321936Shselasky * Either they are inserted into the parse tree data
2708321936Shselasky * structure, or they are already freed when copying
2709321936Shselasky * their values to the parse tree data structure.
2710321936Shselasky */
2711321936Shselaskystatic void __parser_tmp_struct_reset()
2712321936Shselasky{
2713321936Shselasky    tmp_parser_struct.str[0] = '\0';
2714321936Shselasky    cl_list_remove_all(&tmp_parser_struct.str_list);
2715321936Shselasky    cl_list_remove_all(&tmp_parser_struct.num_list);
2716321936Shselasky    cl_list_remove_all(&tmp_parser_struct.num_pair_list);
2717321936Shselasky}
2718321936Shselasky
2719321936Shselasky/***************************************************
2720321936Shselasky ***************************************************/
2721321936Shselasky
2722321936Shselaskystatic void __parser_tmp_struct_destroy()
2723321936Shselasky{
2724321936Shselasky    __parser_tmp_struct_reset();
2725321936Shselasky    cl_list_destroy(&tmp_parser_struct.str_list);
2726321936Shselasky    cl_list_destroy(&tmp_parser_struct.num_list);
2727321936Shselasky    cl_list_destroy(&tmp_parser_struct.num_pair_list);
2728321936Shselasky}
2729321936Shselasky
2730321936Shselasky/***************************************************
2731321936Shselasky ***************************************************/
2732321936Shselasky
2733321936Shselasky#define __SIMPLE_QOS_LEVEL_NAME "SimpleQoSLevel_SL"
2734321936Shselasky#define __SIMPLE_QOS_LEVEL_DEFAULT_NAME "SimpleQoSLevel_DEFAULT"
2735321936Shselasky
2736321936Shselaskystatic void __setup_simple_qos_levels()
2737321936Shselasky{
2738321936Shselasky    uint8_t i;
2739321936Shselasky    char tmp_buf[30];
2740321936Shselasky    memset(osm_qos_policy_simple_qos_levels, 0,
2741321936Shselasky           sizeof(osm_qos_policy_simple_qos_levels));
2742321936Shselasky    for (i = 0; i < 16; i++)
2743321936Shselasky    {
2744321936Shselasky        osm_qos_policy_simple_qos_levels[i].sl = i;
2745321936Shselasky        osm_qos_policy_simple_qos_levels[i].sl_set = TRUE;
2746321936Shselasky        sprintf(tmp_buf, "%s%u", __SIMPLE_QOS_LEVEL_NAME, i);
2747321936Shselasky        osm_qos_policy_simple_qos_levels[i].name = strdup(tmp_buf);
2748321936Shselasky    }
2749321936Shselasky
2750321936Shselasky    memset(&__default_simple_qos_level, 0,
2751321936Shselasky           sizeof(__default_simple_qos_level));
2752321936Shselasky    __default_simple_qos_level.name =
2753321936Shselasky           strdup(__SIMPLE_QOS_LEVEL_DEFAULT_NAME);
2754321936Shselasky}
2755321936Shselasky
2756321936Shselasky/***************************************************
2757321936Shselasky ***************************************************/
2758321936Shselasky
2759321936Shselaskystatic void __clear_simple_qos_levels()
2760321936Shselasky{
2761321936Shselasky    /*
2762321936Shselasky     * Simple QoS levels are static.
2763321936Shselasky     * What's left is to invalidate default simple QoS level.
2764321936Shselasky     */
2765321936Shselasky    __default_simple_qos_level.sl_set = FALSE;
2766321936Shselasky}
2767321936Shselasky
2768321936Shselasky/***************************************************
2769321936Shselasky ***************************************************/
2770321936Shselasky
2771321936Shselaskystatic void __setup_ulp_match_rules()
2772321936Shselasky{
2773321936Shselasky    cl_list_construct(&__ulp_match_rules);
2774321936Shselasky    cl_list_init(&__ulp_match_rules, 10);
2775321936Shselasky}
2776321936Shselasky
2777321936Shselasky/***************************************************
2778321936Shselasky ***************************************************/
2779321936Shselasky
2780321936Shselaskystatic void __process_ulp_match_rules()
2781321936Shselasky{
2782321936Shselasky    cl_list_iterator_t list_iterator;
2783321936Shselasky    osm_qos_match_rule_t *p_qos_match_rule = NULL;
2784321936Shselasky
2785321936Shselasky    list_iterator = cl_list_head(&__ulp_match_rules);
2786321936Shselasky    while (list_iterator != cl_list_end(&__ulp_match_rules))
2787321936Shselasky    {
2788321936Shselasky        p_qos_match_rule = (osm_qos_match_rule_t *) cl_list_obj(list_iterator);
2789321936Shselasky        if (p_qos_match_rule)
2790321936Shselasky            cl_list_insert_tail(&p_qos_policy->qos_match_rules,
2791321936Shselasky                                p_qos_match_rule);
2792321936Shselasky        list_iterator = cl_list_next(list_iterator);
2793321936Shselasky    }
2794321936Shselasky    cl_list_remove_all(&__ulp_match_rules);
2795321936Shselasky}
2796321936Shselasky
2797321936Shselasky/***************************************************
2798321936Shselasky ***************************************************/
2799321936Shselasky
2800321936Shselaskystatic int __cmp_num_range(const void * p1, const void * p2)
2801321936Shselasky{
2802321936Shselasky    uint64_t * pair1 = *((uint64_t **)p1);
2803321936Shselasky    uint64_t * pair2 = *((uint64_t **)p2);
2804321936Shselasky
2805321936Shselasky    if (pair1[0] < pair2[0])
2806321936Shselasky        return -1;
2807321936Shselasky    if (pair1[0] > pair2[0])
2808321936Shselasky        return 1;
2809321936Shselasky
2810321936Shselasky    if (pair1[1] < pair2[1])
2811321936Shselasky        return -1;
2812321936Shselasky    if (pair1[1] > pair2[1])
2813321936Shselasky        return 1;
2814321936Shselasky
2815321936Shselasky    return 0;
2816321936Shselasky}
2817321936Shselasky
2818321936Shselasky/***************************************************
2819321936Shselasky ***************************************************/
2820321936Shselasky
2821321936Shselaskystatic void __sort_reduce_rangearr(
2822321936Shselasky    uint64_t  **   arr,
2823321936Shselasky    unsigned       arr_len,
2824321936Shselasky    uint64_t  ** * p_res_arr,
2825321936Shselasky    unsigned     * p_res_arr_len )
2826321936Shselasky{
2827321936Shselasky    unsigned i = 0;
2828321936Shselasky    unsigned j = 0;
2829321936Shselasky    unsigned last_valid_ind = 0;
2830321936Shselasky    unsigned valid_cnt = 0;
2831321936Shselasky    uint64_t ** res_arr;
2832321936Shselasky    boolean_t * is_valid_arr;
2833321936Shselasky
2834321936Shselasky    *p_res_arr = NULL;
2835321936Shselasky    *p_res_arr_len = 0;
2836321936Shselasky
2837321936Shselasky    qsort(arr, arr_len, sizeof(uint64_t*), __cmp_num_range);
2838321936Shselasky
2839321936Shselasky    is_valid_arr = (boolean_t *)malloc(arr_len * sizeof(boolean_t));
2840321936Shselasky    is_valid_arr[last_valid_ind] = TRUE;
2841321936Shselasky    valid_cnt++;
2842321936Shselasky    for (i = 1; i < arr_len; i++)
2843321936Shselasky    {
2844321936Shselasky        if (arr[i][0] <= arr[last_valid_ind][1])
2845321936Shselasky        {
2846321936Shselasky            if (arr[i][1] > arr[last_valid_ind][1])
2847321936Shselasky                arr[last_valid_ind][1] = arr[i][1];
2848321936Shselasky            free(arr[i]);
2849321936Shselasky            arr[i] = NULL;
2850321936Shselasky            is_valid_arr[i] = FALSE;
2851321936Shselasky        }
2852321936Shselasky        else if ((arr[i][0] - 1) == arr[last_valid_ind][1])
2853321936Shselasky        {
2854321936Shselasky            arr[last_valid_ind][1] = arr[i][1];
2855321936Shselasky            free(arr[i]);
2856321936Shselasky            arr[i] = NULL;
2857321936Shselasky            is_valid_arr[i] = FALSE;
2858321936Shselasky        }
2859321936Shselasky        else
2860321936Shselasky        {
2861321936Shselasky            is_valid_arr[i] = TRUE;
2862321936Shselasky            last_valid_ind = i;
2863321936Shselasky            valid_cnt++;
2864321936Shselasky        }
2865321936Shselasky    }
2866321936Shselasky
2867321936Shselasky    res_arr = (uint64_t **)malloc(valid_cnt * sizeof(uint64_t *));
2868321936Shselasky    for (i = 0; i < arr_len; i++)
2869321936Shselasky    {
2870321936Shselasky        if (is_valid_arr[i])
2871321936Shselasky            res_arr[j++] = arr[i];
2872321936Shselasky    }
2873321936Shselasky    free(is_valid_arr);
2874321936Shselasky    free(arr);
2875321936Shselasky
2876321936Shselasky    *p_res_arr = res_arr;
2877321936Shselasky    *p_res_arr_len = valid_cnt;
2878321936Shselasky}
2879321936Shselasky
2880321936Shselasky/***************************************************
2881321936Shselasky ***************************************************/
2882321936Shselasky
2883321936Shselaskystatic void __pkey_rangelist2rangearr(
2884321936Shselasky    cl_list_t    * p_list,
2885321936Shselasky    uint64_t  ** * p_arr,
2886321936Shselasky    unsigned     * p_arr_len)
2887321936Shselasky{
2888321936Shselasky    uint64_t   tmp_pkey;
2889321936Shselasky    uint64_t * p_pkeys;
2890321936Shselasky    cl_list_iterator_t list_iterator;
2891321936Shselasky
2892321936Shselasky    list_iterator= cl_list_head(p_list);
2893321936Shselasky    while( list_iterator != cl_list_end(p_list) )
2894321936Shselasky    {
2895321936Shselasky       p_pkeys = (uint64_t *)cl_list_obj(list_iterator);
2896321936Shselasky       p_pkeys[0] &= 0x7fff;
2897321936Shselasky       p_pkeys[1] &= 0x7fff;
2898321936Shselasky       if (p_pkeys[0] > p_pkeys[1])
2899321936Shselasky       {
2900321936Shselasky           tmp_pkey = p_pkeys[1];
2901321936Shselasky           p_pkeys[1] = p_pkeys[0];
2902321936Shselasky           p_pkeys[0] = tmp_pkey;
2903321936Shselasky       }
2904321936Shselasky       list_iterator = cl_list_next(list_iterator);
2905321936Shselasky    }
2906321936Shselasky
2907321936Shselasky    __rangelist2rangearr(p_list, p_arr, p_arr_len);
2908321936Shselasky}
2909321936Shselasky
2910321936Shselasky/***************************************************
2911321936Shselasky ***************************************************/
2912321936Shselasky
2913321936Shselaskystatic void __rangelist2rangearr(
2914321936Shselasky    cl_list_t    * p_list,
2915321936Shselasky    uint64_t  ** * p_arr,
2916321936Shselasky    unsigned     * p_arr_len)
2917321936Shselasky{
2918321936Shselasky    cl_list_iterator_t list_iterator;
2919321936Shselasky    unsigned len = cl_list_count(p_list);
2920321936Shselasky    unsigned i = 0;
2921321936Shselasky    uint64_t ** tmp_arr;
2922321936Shselasky    uint64_t ** res_arr = NULL;
2923321936Shselasky    unsigned res_arr_len = 0;
2924321936Shselasky
2925321936Shselasky    tmp_arr = (uint64_t **)malloc(len * sizeof(uint64_t *));
2926321936Shselasky
2927321936Shselasky    list_iterator = cl_list_head(p_list);
2928321936Shselasky    while( list_iterator != cl_list_end(p_list) )
2929321936Shselasky    {
2930321936Shselasky       tmp_arr[i++] = (uint64_t *)cl_list_obj(list_iterator);
2931321936Shselasky       list_iterator = cl_list_next(list_iterator);
2932321936Shselasky    }
2933321936Shselasky    cl_list_remove_all(p_list);
2934321936Shselasky
2935321936Shselasky    __sort_reduce_rangearr( tmp_arr,
2936321936Shselasky                            len,
2937321936Shselasky                            &res_arr,
2938321936Shselasky                            &res_arr_len );
2939321936Shselasky    *p_arr = res_arr;
2940321936Shselasky    *p_arr_len = res_arr_len;
2941321936Shselasky}
2942321936Shselasky
2943321936Shselasky/***************************************************
2944321936Shselasky ***************************************************/
2945321936Shselasky
2946321936Shselaskystatic void __merge_rangearr(
2947321936Shselasky    uint64_t  **   range_arr_1,
2948321936Shselasky    unsigned       range_len_1,
2949321936Shselasky    uint64_t  **   range_arr_2,
2950321936Shselasky    unsigned       range_len_2,
2951321936Shselasky    uint64_t  ** * p_arr,
2952321936Shselasky    unsigned     * p_arr_len )
2953321936Shselasky{
2954321936Shselasky    unsigned i = 0;
2955321936Shselasky    unsigned j = 0;
2956321936Shselasky    unsigned len = range_len_1 + range_len_2;
2957321936Shselasky    uint64_t ** tmp_arr;
2958321936Shselasky    uint64_t ** res_arr = NULL;
2959321936Shselasky    unsigned res_arr_len = 0;
2960321936Shselasky
2961321936Shselasky    *p_arr = NULL;
2962321936Shselasky    *p_arr_len = 0;
2963321936Shselasky
2964321936Shselasky    tmp_arr = (uint64_t **)malloc(len * sizeof(uint64_t *));
2965321936Shselasky
2966321936Shselasky    for (i = 0; i < range_len_1; i++)
2967321936Shselasky       tmp_arr[j++] = range_arr_1[i];
2968321936Shselasky    for (i = 0; i < range_len_2; i++)
2969321936Shselasky       tmp_arr[j++] = range_arr_2[i];
2970321936Shselasky    free(range_arr_1);
2971321936Shselasky    free(range_arr_2);
2972321936Shselasky
2973321936Shselasky    __sort_reduce_rangearr( tmp_arr,
2974321936Shselasky                            len,
2975321936Shselasky                            &res_arr,
2976321936Shselasky                            &res_arr_len );
2977321936Shselasky    *p_arr = res_arr;
2978321936Shselasky    *p_arr_len = res_arr_len;
2979321936Shselasky}
2980321936Shselasky
2981321936Shselasky/***************************************************
2982321936Shselasky ***************************************************/
2983321936Shselasky
2984321936Shselaskystatic void __parser_add_port_to_port_map(
2985321936Shselasky    cl_qmap_t   * p_map,
2986321936Shselasky    osm_physp_t * p_physp)
2987321936Shselasky{
2988321936Shselasky    if (cl_qmap_get(p_map, cl_ntoh64(osm_physp_get_port_guid(p_physp))) ==
2989321936Shselasky        cl_qmap_end(p_map))
2990321936Shselasky    {
2991321936Shselasky        osm_qos_port_t * p_port = osm_qos_policy_port_create(p_physp);
2992321936Shselasky        if (p_port)
2993321936Shselasky            cl_qmap_insert(p_map,
2994321936Shselasky                           cl_ntoh64(osm_physp_get_port_guid(p_physp)),
2995321936Shselasky                           &p_port->map_item);
2996321936Shselasky    }
2997321936Shselasky}
2998321936Shselasky
2999321936Shselasky/***************************************************
3000321936Shselasky ***************************************************/
3001321936Shselasky
3002321936Shselaskystatic void __parser_add_guid_range_to_port_map(
3003321936Shselasky    cl_qmap_t  * p_map,
3004321936Shselasky    uint64_t  ** range_arr,
3005321936Shselasky    unsigned     range_len)
3006321936Shselasky{
3007321936Shselasky    unsigned i;
3008321936Shselasky    uint64_t guid_ho;
3009321936Shselasky    osm_port_t * p_osm_port;
3010321936Shselasky
3011321936Shselasky    if (!range_arr || !range_len)
3012321936Shselasky        return;
3013321936Shselasky
3014321936Shselasky    for (i = 0; i < range_len; i++) {
3015321936Shselasky         for (guid_ho = range_arr[i][0]; guid_ho <= range_arr[i][1]; guid_ho++) {
3016321936Shselasky             p_osm_port =
3017321936Shselasky                osm_get_port_by_guid(p_qos_policy->p_subn, cl_hton64(guid_ho));
3018321936Shselasky             if (p_osm_port)
3019321936Shselasky                 __parser_add_port_to_port_map(p_map, p_osm_port->p_physp);
3020321936Shselasky         }
3021321936Shselasky         free(range_arr[i]);
3022321936Shselasky    }
3023321936Shselasky    free(range_arr);
3024321936Shselasky}
3025321936Shselasky
3026321936Shselasky/***************************************************
3027321936Shselasky ***************************************************/
3028321936Shselasky
3029321936Shselaskystatic void __parser_add_pkey_range_to_port_map(
3030321936Shselasky    cl_qmap_t  * p_map,
3031321936Shselasky    uint64_t  ** range_arr,
3032321936Shselasky    unsigned     range_len)
3033321936Shselasky{
3034321936Shselasky    unsigned i;
3035321936Shselasky    uint64_t pkey_64;
3036321936Shselasky    ib_net16_t pkey;
3037321936Shselasky    osm_prtn_t * p_prtn;
3038321936Shselasky
3039321936Shselasky    if (!range_arr || !range_len)
3040321936Shselasky        return;
3041321936Shselasky
3042321936Shselasky    for (i = 0; i < range_len; i++) {
3043321936Shselasky         for (pkey_64 = range_arr[i][0]; pkey_64 <= range_arr[i][1]; pkey_64++) {
3044321936Shselasky             pkey = cl_hton16((uint16_t)(pkey_64 & 0x7fff));
3045321936Shselasky             p_prtn = (osm_prtn_t *)
3046321936Shselasky                 cl_qmap_get(&p_qos_policy->p_subn->prtn_pkey_tbl, pkey);
3047321936Shselasky             if (p_prtn != (osm_prtn_t *)cl_qmap_end(
3048321936Shselasky                   &p_qos_policy->p_subn->prtn_pkey_tbl)) {
3049321936Shselasky                 __parser_add_map_to_port_map(p_map, &p_prtn->part_guid_tbl);
3050321936Shselasky                 __parser_add_map_to_port_map(p_map, &p_prtn->full_guid_tbl);
3051321936Shselasky             }
3052321936Shselasky         }
3053321936Shselasky         free(range_arr[i]);
3054321936Shselasky    }
3055321936Shselasky    free(range_arr);
3056321936Shselasky}
3057321936Shselasky
3058321936Shselasky/***************************************************
3059321936Shselasky ***************************************************/
3060321936Shselasky
3061321936Shselaskystatic void __parser_add_partition_list_to_port_map(
3062321936Shselasky    cl_qmap_t  * p_map,
3063321936Shselasky    cl_list_t  * p_list)
3064321936Shselasky{
3065321936Shselasky    cl_list_iterator_t    list_iterator;
3066321936Shselasky    char                * tmp_str;
3067321936Shselasky    osm_prtn_t          * p_prtn;
3068321936Shselasky
3069321936Shselasky    /* extract all the ports from the partition
3070321936Shselasky       to the port map of this port group */
3071321936Shselasky    list_iterator = cl_list_head(p_list);
3072321936Shselasky    while(list_iterator != cl_list_end(p_list)) {
3073321936Shselasky        tmp_str = (char*)cl_list_obj(list_iterator);
3074321936Shselasky        if (tmp_str) {
3075321936Shselasky            p_prtn = osm_prtn_find_by_name(p_qos_policy->p_subn, tmp_str);
3076321936Shselasky            if (p_prtn) {
3077321936Shselasky                __parser_add_map_to_port_map(p_map, &p_prtn->part_guid_tbl);
3078321936Shselasky                __parser_add_map_to_port_map(p_map, &p_prtn->full_guid_tbl);
3079321936Shselasky            }
3080321936Shselasky            free(tmp_str);
3081321936Shselasky        }
3082321936Shselasky        list_iterator = cl_list_next(list_iterator);
3083321936Shselasky    }
3084321936Shselasky    cl_list_remove_all(p_list);
3085321936Shselasky}
3086321936Shselasky
3087321936Shselasky/***************************************************
3088321936Shselasky ***************************************************/
3089321936Shselasky
3090321936Shselaskystatic void __parser_add_map_to_port_map(
3091321936Shselasky    cl_qmap_t * p_dmap,
3092321936Shselasky    cl_map_t  * p_smap)
3093321936Shselasky{
3094321936Shselasky    cl_map_iterator_t map_iterator;
3095321936Shselasky    osm_physp_t * p_physp;
3096321936Shselasky
3097321936Shselasky    if (!p_dmap || !p_smap)
3098321936Shselasky        return;
3099321936Shselasky
3100321936Shselasky    map_iterator = cl_map_head(p_smap);
3101321936Shselasky    while (map_iterator != cl_map_end(p_smap)) {
3102321936Shselasky        p_physp = (osm_physp_t*)cl_map_obj(map_iterator);
3103321936Shselasky        __parser_add_port_to_port_map(p_dmap, p_physp);
3104321936Shselasky        map_iterator = cl_map_next(map_iterator);
3105321936Shselasky    }
3106321936Shselasky}
3107321936Shselasky
3108321936Shselasky/***************************************************
3109321936Shselasky ***************************************************/
3110321936Shselasky
3111321936Shselaskystatic int __validate_pkeys( uint64_t ** range_arr,
3112321936Shselasky                             unsigned    range_len,
3113321936Shselasky                             boolean_t   is_ipoib)
3114321936Shselasky{
3115321936Shselasky    unsigned i;
3116321936Shselasky    uint64_t pkey_64;
3117321936Shselasky    ib_net16_t pkey;
3118321936Shselasky    osm_prtn_t * p_prtn;
3119321936Shselasky
3120321936Shselasky    if (!range_arr || !range_len)
3121321936Shselasky        return 0;
3122321936Shselasky
3123321936Shselasky    for (i = 0; i < range_len; i++) {
3124321936Shselasky        for (pkey_64 = range_arr[i][0]; pkey_64 <= range_arr[i][1]; pkey_64++) {
3125321936Shselasky            pkey = cl_hton16((uint16_t)(pkey_64 & 0x7fff));
3126321936Shselasky            p_prtn = (osm_prtn_t *)
3127321936Shselasky                cl_qmap_get(&p_qos_policy->p_subn->prtn_pkey_tbl, pkey);
3128321936Shselasky
3129321936Shselasky            if (p_prtn == (osm_prtn_t *)cl_qmap_end(
3130321936Shselasky                  &p_qos_policy->p_subn->prtn_pkey_tbl))
3131321936Shselasky                p_prtn = NULL;
3132321936Shselasky
3133321936Shselasky            if (is_ipoib) {
3134321936Shselasky                /*
3135321936Shselasky                 * Be very strict for IPoIB partition:
3136321936Shselasky                 *  - the partition for the pkey have to exist
3137321936Shselasky                 *  - it has to have at least 2 full members
3138321936Shselasky                 */
3139321936Shselasky                if (!p_prtn) {
3140321936Shselasky                    yyerror("IPoIB partition, pkey 0x%04X - "
3141321936Shselasky                                       "partition doesn't exist",
3142321936Shselasky                                       cl_ntoh16(pkey));
3143321936Shselasky                    return 1;
3144321936Shselasky                }
3145321936Shselasky                else if (cl_map_count(&p_prtn->full_guid_tbl) < 2) {
3146321936Shselasky                    yyerror("IPoIB partition, pkey 0x%04X - "
3147321936Shselasky                                       "partition has less than two full members",
3148321936Shselasky                                       cl_ntoh16(pkey));
3149321936Shselasky                    return 1;
3150321936Shselasky                }
3151321936Shselasky            }
3152321936Shselasky            else if (!p_prtn) {
3153321936Shselasky                /*
3154321936Shselasky                 * For non-IPoIB pkey we just want to check that
3155321936Shselasky                 * the relevant partition exists.
3156321936Shselasky                 * And even if it doesn't, don't exit - just print
3157321936Shselasky                 * error message and continue.
3158321936Shselasky                 */
3159321936Shselasky                 OSM_LOG(p_qos_parser_osm_log, OSM_LOG_ERROR, "ERR AC02: "
3160321936Shselasky			 "pkey 0x%04X - partition doesn't exist",
3161321936Shselasky                         cl_ntoh16(pkey));
3162321936Shselasky            }
3163321936Shselasky        }
3164321936Shselasky    }
3165321936Shselasky    return 0;
3166321936Shselasky}
3167321936Shselasky
3168321936Shselasky/***************************************************
3169321936Shselasky ***************************************************/
3170