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