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