mpls.c (22072B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: mpls.c 8 * Purpose: Manages MPLS functionality at a system level 9 */ 10 11 #include <sal/core/libc.h> 12 #include <shared/alloc.h> 13 14 #include <bcm/types.h> 15 16 #include <bcmx/l3.h> 17 #include <bcmx/lport.h> 18 #include <bcmx/bcmx.h> 19 #include <bcmx/lplist.h> 20 21 #include "bcmx_int.h" 22 23 24 #include <bcmx/mpls.h> 25 26 #ifdef INCLUDE_L3 27 28 #define BCMX_MPLS_INIT_CHECK BCMX_READY_CHECK 29 30 #define BCMX_MPLS_ERROR_CHECK(_unit, _check, _rv) \ 31 BCMX_ERROR_CHECK(_unit, _check, _rv) 32 33 #define BCMX_MPLS_SET_ERROR_CHECK(_unit, _check, _rv) \ 34 BCMX_SET_ERROR_CHECK(_unit, _check, _rv) 35 36 #define BCMX_MPLS_DELETE_ERROR_CHECK(_unit, _check, _rv) \ 37 BCMX_DELETE_ERROR_CHECK(_unit, _check, _rv) 38 39 #define BCMX_MPLS_GET_IS_VALID(_unit, _rv) \ 40 BCMX_ERROR_IS_VALID(_unit, _rv) 41 42 43 #define BCMX_MPLS_VPN_CONFIG_T_PTR_TO_BCM(_info) \ 44 ((bcm_mpls_vpn_config_t *)(_info)) 45 46 #define BCMX_MPLS_PORT_T_PTR_TO_BCM(_mpls_port) \ 47 ((bcm_mpls_port_t *)(_mpls_port)) 48 49 #define BCMX_MPLS_EGRESS_LABEL_T_PTR_TO_BCM(_label) \ 50 ((bcm_mpls_egress_label_t *)(_label)) 51 52 #define BCMX_MPLS_TUNNEL_SWITCH_T_PTR_TO_BCM(_info) \ 53 ((bcm_mpls_tunnel_switch_t *)(_info)) 54 55 56 /* 57 * Function: 58 * bcmx_mpls_vpn_config_t_init 59 * Purpose: 60 * Initialize the MPLS VPN config structure. 61 * Parameters: 62 * info - Pointer to the struct to be initialized 63 * Returns: 64 * None 65 */ 66 void 67 bcmx_mpls_vpn_config_t_init(bcmx_mpls_vpn_config_t *info) 68 { 69 if (info != NULL) { 70 bcm_mpls_vpn_config_t_init(BCMX_MPLS_VPN_CONFIG_T_PTR_TO_BCM(info)); 71 } 72 } 73 74 /* 75 * Function: 76 * bcmx_mpls_port_t_init 77 * Purpose: 78 * Initialize the MPLS port structure 79 * Parameters: 80 * mpls_port - Pointer to the struct to be initialized 81 * Returns: 82 * None 83 */ 84 void 85 bcmx_mpls_port_t_init(bcmx_mpls_port_t *mpls_port) 86 { 87 if (mpls_port != NULL) { 88 bcm_mpls_port_t_init(BCMX_MPLS_PORT_T_PTR_TO_BCM(mpls_port)); 89 } 90 } 91 92 /* 93 * Function: 94 * bcmx_mpls_egress_label_t_init 95 * Purpose: 96 * Initialize the MPLS egress label structure 97 * Parameters: 98 * label - Pointer to the struct to be initialized 99 * Returns: 100 * None 101 */ 102 void 103 bcmx_mpls_egress_label_t_init(bcmx_mpls_egress_label_t *label) 104 { 105 if (label != NULL) { 106 bcm_mpls_egress_label_t_init(BCMX_MPLS_EGRESS_LABEL_T_PTR_TO_BCM 107 (label)); 108 } 109 } 110 111 /* 112 * Function: 113 * bcmx_mpls_tunnel_switch_t_init 114 * Purpose: 115 * Initialize the MPLS tunnel switch structure 116 * Parameters: 117 * info - Pointer to the struct to be initialized 118 * Returns: 119 * None 120 */ 121 void 122 bcmx_mpls_tunnel_switch_t_init(bcmx_mpls_tunnel_switch_t *info) 123 { 124 if (info != NULL) { 125 bcm_mpls_tunnel_switch_t_init(BCMX_MPLS_TUNNEL_SWITCH_T_PTR_TO_BCM 126 (info)); 127 } 128 } 129 130 /* 131 * Function: 132 * bcmx_mpls_init 133 * Purpose: 134 * Initialize MPLS module system-wide 135 * Parameters: 136 * None 137 * Returns: 138 * BCM_E_XXX 139 */ 140 int 141 bcmx_mpls_init(void) 142 { 143 int rv = BCM_E_UNAVAIL, tmp_rv; 144 int i, bcm_unit; 145 146 BCMX_MPLS_INIT_CHECK; 147 148 BCMX_UNIT_ITER(bcm_unit, i) { 149 tmp_rv = bcm_mpls_init(bcm_unit); 150 BCM_IF_ERROR_RETURN(BCMX_MPLS_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 151 } 152 153 return rv; 154 } 155 156 /* 157 * Function: 158 * bcmx_mpls_cleanup 159 * Purpose: 160 * Disable MPLS system-wide 161 * Parameters: 162 * None 163 * Returns: 164 * BCM_E_XXX 165 */ 166 int 167 bcmx_mpls_cleanup(void) 168 { 169 int rv = BCM_E_UNAVAIL, tmp_rv; 170 int i, bcm_unit; 171 172 BCMX_MPLS_INIT_CHECK; 173 174 BCMX_UNIT_ITER(bcm_unit, i) { 175 tmp_rv = bcm_mpls_cleanup(bcm_unit); 176 BCM_IF_ERROR_RETURN(BCMX_MPLS_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 177 } 178 179 return rv; 180 } 181 182 /* 183 * Function: 184 * bcmx_mpls_exp_map_create 185 * Purpose: 186 * Create an MPLS EXP map instance. 187 * Parameters: 188 * flags - (IN) MPLS flags 189 * exp_map_id - (OUT) Allocated EXP map ID 190 * Returns: 191 * BCM_E_XXX 192 */ 193 int 194 bcmx_mpls_exp_map_create(uint32 flags, int *exp_map_id) 195 { 196 int rv = BCM_E_UNAVAIL, tmp_rv; 197 int i, bcm_unit; 198 199 BCMX_MPLS_INIT_CHECK; 200 201 BCMX_PARAM_NULL_CHECK(exp_map_id); 202 203 BCMX_UNIT_ITER(bcm_unit, i) { 204 tmp_rv = bcm_mpls_exp_map_create(bcm_unit, flags, exp_map_id); 205 BCM_IF_ERROR_RETURN(BCMX_MPLS_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 206 } 207 208 return rv; 209 } 210 211 /* 212 * Function: 213 * bcmx_mpls_exp_map_destroy 214 * Purpose: 215 * Destroy an existing MPLS EXP map instance. 216 * Parameters: 217 * exp_map_id - (IN) EXP map ID 218 * Returns: 219 * BCM_E_XXX 220 */ 221 int 222 bcmx_mpls_exp_map_destroy(int exp_map_id) 223 { 224 int rv = BCM_E_UNAVAIL, tmp_rv; 225 int i, bcm_unit; 226 227 BCMX_MPLS_INIT_CHECK; 228 229 BCMX_UNIT_ITER(bcm_unit, i) { 230 tmp_rv = bcm_mpls_exp_map_destroy(bcm_unit, exp_map_id); 231 BCM_IF_ERROR_RETURN 232 (BCMX_MPLS_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 233 } 234 235 return rv; 236 } 237 238 239 /* 240 * Function: 241 * bcmx_mpls_exp_map_set 242 * Purpose: 243 * Set the mapping of { internal priority, color } 244 * to a EXP value for MPLS headers 245 * in the specified EXP map instance. 246 * Parameters: 247 * exp_map_id - (IN) EXP map ID 248 * exp_map - (IN) EXP map info 249 * Returns: 250 * BCM_E_XXX 251 */ 252 int 253 bcmx_mpls_exp_map_set(int exp_map_id, 254 bcm_mpls_exp_map_t *exp_map) 255 { 256 int rv = BCM_E_UNAVAIL, tmp_rv; 257 int i, bcm_unit; 258 259 BCMX_MPLS_INIT_CHECK; 260 261 BCMX_PARAM_NULL_CHECK(exp_map); 262 263 BCMX_UNIT_ITER(bcm_unit, i) { 264 tmp_rv = bcm_mpls_exp_map_set(bcm_unit, exp_map_id, exp_map); 265 BCM_IF_ERROR_RETURN(BCMX_MPLS_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 266 } 267 268 return rv; 269 } 270 271 272 /* 273 * Function: 274 * bcmx_mpls_exp_map_get 275 * Purpose: 276 * Get the EXP map information for the specified EXP map instance. 277 * Parameters: 278 * exp_map_id - (IN) EXP map ID 279 * exp_map - (OUT) Returning EXP map info 280 * Returns: 281 * BCM_E_XXX 282 */ 283 int 284 bcmx_mpls_exp_map_get(int exp_map_id, 285 bcm_mpls_exp_map_t *exp_map) 286 { 287 int rv; 288 int i, bcm_unit; 289 290 BCMX_MPLS_INIT_CHECK; 291 292 BCMX_UNIT_ITER(bcm_unit, i) { 293 rv = bcm_mpls_exp_map_get(bcm_unit, exp_map_id, exp_map); 294 if (BCMX_MPLS_GET_IS_VALID(bcm_unit, rv)) { 295 return rv; 296 } 297 } 298 299 return BCM_E_UNAVAIL; 300 } 301 302 /* 303 * Function: 304 * bcmx_mpls_vpn_id_create 305 */ 306 int 307 bcmx_mpls_vpn_id_create(bcmx_mpls_vpn_config_t *info) 308 { 309 int rv = BCM_E_UNAVAIL, tmp_rv; 310 int i; 311 int bcm_unit; 312 uint32 flags_orig; 313 314 BCMX_MPLS_INIT_CHECK; 315 316 BCMX_PARAM_NULL_CHECK(info); 317 318 /* Store original 'xxx_WITH_ID' flag bit */ 319 flags_orig = info->flags & BCM_MPLS_VPN_WITH_ID; 320 321 BCMX_UNIT_ITER(bcm_unit, i) { 322 tmp_rv = bcm_mpls_vpn_id_create(bcm_unit, 323 BCMX_MPLS_VPN_CONFIG_T_PTR_TO_BCM 324 (info)); 325 if (BCM_FAILURE(BCMX_MPLS_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv))) { 326 break; 327 } 328 329 /* 330 * If vpn id is not specified, use returned id from 331 * first successful 'create' for remaining units. 332 */ 333 if (!(info->flags & BCM_MPLS_VPN_WITH_ID)) { 334 if (BCM_SUCCESS(tmp_rv)) { 335 info->flags |= BCM_MPLS_VPN_WITH_ID; 336 } 337 } 338 } 339 340 /* Restore 'xxx_WITH_ID' flag bit */ 341 info->flags &= ~BCM_MPLS_VPN_WITH_ID; 342 info->flags |= flags_orig; 343 344 return rv; 345 } 346 347 /* 348 * Function: 349 * bcmx_mpls_vpn_id_destroy 350 */ 351 int 352 bcmx_mpls_vpn_id_destroy(bcm_vpn_t vpn) 353 { 354 int rv = BCM_E_UNAVAIL, tmp_rv; 355 int i; 356 int bcm_unit; 357 358 BCMX_MPLS_INIT_CHECK; 359 360 BCMX_UNIT_ITER(bcm_unit, i) { 361 tmp_rv = bcm_mpls_vpn_id_destroy(bcm_unit, vpn); 362 BCM_IF_ERROR_RETURN 363 (BCMX_MPLS_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 364 } 365 366 return rv; 367 } 368 369 /* 370 * Function: 371 * bcmx_mpls_vpn_id_destroy_all 372 */ 373 int 374 bcmx_mpls_vpn_id_destroy_all(void) 375 { 376 int rv = BCM_E_UNAVAIL, tmp_rv; 377 int i; 378 int bcm_unit; 379 380 BCMX_MPLS_INIT_CHECK; 381 382 BCMX_UNIT_ITER(bcm_unit, i) { 383 tmp_rv = bcm_mpls_vpn_id_destroy_all(bcm_unit); 384 BCM_IF_ERROR_RETURN 385 (BCMX_MPLS_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 386 } 387 388 return rv; 389 } 390 391 /* 392 * Function: 393 * bcmx_mpls_vpn_id_get 394 */ 395 int 396 bcmx_mpls_vpn_id_get(bcm_vpn_t vpn, bcmx_mpls_vpn_config_t *info) 397 { 398 int rv; 399 int i, bcm_unit; 400 401 BCMX_MPLS_INIT_CHECK; 402 403 BCMX_PARAM_NULL_CHECK(info); 404 405 BCMX_UNIT_ITER(bcm_unit, i) { 406 rv = bcm_mpls_vpn_id_get(bcm_unit, vpn, 407 BCMX_MPLS_VPN_CONFIG_T_PTR_TO_BCM(info)); 408 if (BCMX_MPLS_GET_IS_VALID(bcm_unit, rv)) { 409 return rv; 410 } 411 } 412 413 return BCM_E_UNAVAIL; 414 } 415 416 /* 417 * Function: 418 * bcmx_mpls_port_add 419 */ 420 int 421 bcmx_mpls_port_add(bcm_vpn_t vpn, bcmx_mpls_port_t *mpls_port) 422 { 423 int rv = BCM_E_UNAVAIL, tmp_rv; 424 int i; 425 int bcm_unit; 426 uint32 flags_orig; 427 428 BCMX_MPLS_INIT_CHECK; 429 430 BCMX_PARAM_NULL_CHECK(mpls_port); 431 432 /* Store original 'xxx_WITH_ID' flag bit */ 433 flags_orig = mpls_port->flags & BCM_MPLS_PORT_WITH_ID; 434 435 /* 436 * Use returned 'mpls_port_id' from first success 'add' 437 * to set rest of the units. 438 */ 439 BCMX_UNIT_ITER(bcm_unit, i) { 440 tmp_rv = bcm_mpls_port_add(bcm_unit, vpn, 441 BCMX_MPLS_PORT_T_PTR_TO_BCM(mpls_port)); 442 if (BCM_FAILURE(BCMX_MPLS_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv))) { 443 break; 444 } 445 446 /* 447 * If mpls id is not specified, use returned id from 448 * first successful 'add' for remaining units. 449 */ 450 if (!(mpls_port->flags & BCM_MPLS_PORT_WITH_ID)) { 451 if (BCM_SUCCESS(tmp_rv)) { 452 mpls_port->flags |= BCM_MPLS_PORT_WITH_ID; 453 } 454 } 455 } 456 457 /* Restore 'xxx_WITH_ID' flag bit */ 458 mpls_port->flags &= ~BCM_MPLS_PORT_WITH_ID; 459 mpls_port->flags |= flags_orig; 460 461 return rv; 462 } 463 464 /* 465 * Function: 466 * bcmx_mpls_port_delete 467 */ 468 int 469 bcmx_mpls_port_delete(bcm_vpn_t vpn, bcm_gport_t mpls_port_id) 470 { 471 int rv = BCM_E_UNAVAIL, tmp_rv; 472 int i; 473 int bcm_unit; 474 475 BCMX_MPLS_INIT_CHECK; 476 477 BCMX_UNIT_ITER(bcm_unit, i) { 478 tmp_rv = bcm_mpls_port_delete(bcm_unit, vpn, mpls_port_id); 479 BCM_IF_ERROR_RETURN 480 (BCMX_MPLS_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 481 } 482 483 return rv; 484 } 485 486 /* 487 * Function: 488 * bcmx_mpls_port_delete_all 489 */ 490 int 491 bcmx_mpls_port_delete_all(bcm_vpn_t vpn) 492 { 493 int rv = BCM_E_UNAVAIL, tmp_rv; 494 int i; 495 int bcm_unit; 496 497 BCMX_MPLS_INIT_CHECK; 498 499 BCMX_UNIT_ITER(bcm_unit, i) { 500 tmp_rv = bcm_mpls_port_delete_all(bcm_unit, vpn); 501 BCM_IF_ERROR_RETURN 502 (BCMX_MPLS_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 503 } 504 505 return rv; 506 } 507 508 /* 509 * Function: 510 * bcmx_mpls_port_get 511 */ 512 int 513 bcmx_mpls_port_get(bcm_vpn_t vpn, bcmx_mpls_port_t *mpls_port) 514 { 515 int rv; 516 int i, bcm_unit; 517 518 BCMX_MPLS_INIT_CHECK; 519 520 BCMX_PARAM_NULL_CHECK(mpls_port); 521 522 BCMX_UNIT_ITER(bcm_unit, i) { 523 rv = bcm_mpls_port_get(bcm_unit, vpn, 524 BCMX_MPLS_PORT_T_PTR_TO_BCM(mpls_port)); 525 if (BCMX_MPLS_GET_IS_VALID(bcm_unit, rv)) { 526 return rv; 527 } 528 } 529 530 return BCM_E_UNAVAIL; 531 } 532 533 /* 534 * Function: 535 * bcmx_mpls_port_get_all 536 */ 537 int 538 bcmx_mpls_port_get_all(bcm_vpn_t vpn, int port_max, 539 bcmx_mpls_port_t *port_array, int *port_count) 540 { 541 int rv; 542 int i, bcm_unit; 543 544 BCMX_MPLS_INIT_CHECK; 545 546 BCMX_PARAM_ARRAY_NULL_CHECK(port_max, port_array); 547 BCMX_PARAM_NULL_CHECK(port_count); 548 549 BCMX_UNIT_ITER(bcm_unit, i) { 550 rv = bcm_mpls_port_get_all(bcm_unit, vpn, port_max, 551 BCMX_MPLS_PORT_T_PTR_TO_BCM(port_array), 552 port_count); 553 if (BCMX_MPLS_GET_IS_VALID(bcm_unit, rv)) { 554 return rv; 555 } 556 } 557 558 return BCM_E_UNAVAIL; 559 } 560 561 /* 562 * Function: 563 * bcmx_mpls_tunnel_initiator_set 564 */ 565 int 566 bcmx_mpls_tunnel_initiator_set(bcm_if_t intf, int num_labels, 567 bcmx_mpls_egress_label_t *label_array) 568 { 569 int rv = BCM_E_UNAVAIL, tmp_rv; 570 int i; 571 int bcm_unit; 572 573 BCMX_MPLS_INIT_CHECK; 574 575 BCMX_PARAM_NULL_CHECK(label_array); 576 577 BCMX_UNIT_ITER(bcm_unit, i) { 578 tmp_rv = bcm_mpls_tunnel_initiator_set(bcm_unit, intf, num_labels, 579 BCMX_MPLS_EGRESS_LABEL_T_PTR_TO_BCM 580 (label_array)); 581 BCM_IF_ERROR_RETURN(BCMX_MPLS_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 582 } 583 584 return rv; 585 } 586 587 /* 588 * Function: 589 * bcmx_mpls_tunnel_initiator_get 590 */ 591 int 592 bcmx_mpls_tunnel_initiator_get(bcm_if_t intf, int label_max, 593 bcmx_mpls_egress_label_t *label_array, 594 int *label_count) 595 { 596 int rv; 597 int i, bcm_unit; 598 599 BCMX_MPLS_INIT_CHECK; 600 601 BCMX_PARAM_ARRAY_NULL_CHECK(label_max, label_array); 602 BCMX_PARAM_NULL_CHECK(label_count); 603 604 BCMX_UNIT_ITER(bcm_unit, i) { 605 rv = bcm_mpls_tunnel_initiator_get(bcm_unit, intf, label_max, 606 BCMX_MPLS_EGRESS_LABEL_T_PTR_TO_BCM 607 (label_array), 608 label_count); 609 if (BCMX_MPLS_GET_IS_VALID(bcm_unit, rv)) { 610 return rv; 611 } 612 } 613 614 return BCM_E_UNAVAIL; 615 } 616 617 /* 618 * Function: 619 * bcmx_mpls_tunnel_initiator_clear 620 */ 621 int 622 bcmx_mpls_tunnel_initiator_clear(bcm_if_t intf) 623 { 624 int rv = BCM_E_UNAVAIL, tmp_rv; 625 int i; 626 int bcm_unit; 627 628 BCMX_MPLS_INIT_CHECK; 629 630 BCMX_UNIT_ITER(bcm_unit, i) { 631 tmp_rv = bcm_mpls_tunnel_initiator_clear(bcm_unit, intf); 632 BCM_IF_ERROR_RETURN 633 (BCMX_MPLS_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 634 } 635 636 return rv; 637 } 638 639 /* 640 * Function: 641 * bcmx_mpls_tunnel_initiator_clear_all 642 */ 643 int 644 bcmx_mpls_tunnel_initiator_clear_all(void) 645 { 646 int rv = BCM_E_UNAVAIL, tmp_rv; 647 int i; 648 int bcm_unit; 649 650 BCMX_MPLS_INIT_CHECK; 651 652 BCMX_UNIT_ITER(bcm_unit, i) { 653 tmp_rv = bcm_mpls_tunnel_initiator_clear_all(bcm_unit); 654 BCM_IF_ERROR_RETURN 655 (BCMX_MPLS_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 656 } 657 658 return rv; 659 } 660 661 /* 662 * Function: 663 * bcmx_mpls_tunnel_switch_add 664 */ 665 int 666 bcmx_mpls_tunnel_switch_add(bcmx_mpls_tunnel_switch_t *info) 667 { 668 int rv = BCM_E_UNAVAIL, tmp_rv; 669 int i; 670 int bcm_unit; 671 bcm_port_t bcm_port; 672 673 BCMX_MPLS_INIT_CHECK; 674 675 BCMX_PARAM_NULL_CHECK(info); 676 677 /* 678 * If 'port' member is a valid BCMX logical port, then port 679 * refers to a specific physical port (mod/port or dev/port). 680 * Else, 'port' is a system-wide value. 681 */ 682 if (BCM_SUCCESS(_bcmx_dest_to_unit_port(info->port, 683 &bcm_unit, &bcm_port, 684 BCMX_DEST_CONVERT_DEFAULT))) { 685 return bcm_mpls_tunnel_switch_add(bcm_unit, 686 BCMX_MPLS_TUNNEL_SWITCH_T_PTR_TO_BCM 687 (info)); 688 } 689 690 BCMX_UNIT_ITER(bcm_unit, i) { 691 tmp_rv = bcm_mpls_tunnel_switch_add(bcm_unit, 692 BCMX_MPLS_TUNNEL_SWITCH_T_PTR_TO_BCM 693 (info)); 694 BCM_IF_ERROR_RETURN(BCMX_MPLS_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 695 } 696 697 return rv; 698 } 699 700 /* 701 * Function: 702 * bcmx_mpls_tunnel_switch_delete 703 */ 704 int 705 bcmx_mpls_tunnel_switch_delete(bcmx_mpls_tunnel_switch_t *info) 706 { 707 int rv = BCM_E_UNAVAIL, tmp_rv; 708 int i; 709 int bcm_unit; 710 bcm_port_t bcm_port; 711 712 BCMX_MPLS_INIT_CHECK; 713 714 BCMX_PARAM_NULL_CHECK(info); 715 716 /* 717 * If 'port' member is a valid BCMX logical port, then port 718 * refers to a specific physical port (mod/port or dev/port). 719 * Else, 'port' is a system-wide value. 720 */ 721 if (BCM_SUCCESS(_bcmx_dest_to_unit_port(info->port, 722 &bcm_unit, &bcm_port, 723 BCMX_DEST_CONVERT_DEFAULT))) { 724 return bcm_mpls_tunnel_switch_delete(bcm_unit, 725 BCMX_MPLS_TUNNEL_SWITCH_T_PTR_TO_BCM 726 (info)); 727 } 728 729 BCMX_UNIT_ITER(bcm_unit, i) { 730 tmp_rv = bcm_mpls_tunnel_switch_delete(bcm_unit, 731 BCMX_MPLS_TUNNEL_SWITCH_T_PTR_TO_BCM 732 (info)); 733 BCM_IF_ERROR_RETURN 734 (BCMX_MPLS_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 735 } 736 737 return rv; 738 } 739 740 /* 741 * Function: 742 * bcmx_mpls_tunnel_switch_delete_all 743 */ 744 int 745 bcmx_mpls_tunnel_switch_delete_all(void) 746 { 747 int rv = BCM_E_UNAVAIL, tmp_rv; 748 int i; 749 int bcm_unit; 750 751 BCMX_MPLS_INIT_CHECK; 752 753 BCMX_UNIT_ITER(bcm_unit, i) { 754 tmp_rv = bcm_mpls_tunnel_switch_delete_all(bcm_unit); 755 BCM_IF_ERROR_RETURN 756 (BCMX_MPLS_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 757 } 758 759 return rv; 760 } 761 762 /* 763 * Function: 764 * bcmx_mpls_tunnel_switch_get 765 */ 766 int 767 bcmx_mpls_tunnel_switch_get(bcmx_mpls_tunnel_switch_t *info) 768 { 769 int rv; 770 int i; 771 int bcm_unit; 772 bcm_port_t bcm_port; 773 774 BCMX_MPLS_INIT_CHECK; 775 776 BCMX_PARAM_NULL_CHECK(info); 777 778 /* 779 * If 'port' member is a valid BCMX logical port, then port 780 * refers to a specific physical port (mod/port or dev/port). 781 * Else, 'port' is a system-wide value. 782 */ 783 if (BCM_SUCCESS(_bcmx_dest_to_unit_port(info->port, 784 &bcm_unit, &bcm_port, 785 BCMX_DEST_CONVERT_DEFAULT))) { 786 return bcm_mpls_tunnel_switch_get(bcm_unit, 787 BCMX_MPLS_TUNNEL_SWITCH_T_PTR_TO_BCM 788 (info)); 789 } 790 791 BCMX_UNIT_ITER(bcm_unit, i) { 792 rv = bcm_mpls_tunnel_switch_get(bcm_unit, 793 BCMX_MPLS_TUNNEL_SWITCH_T_PTR_TO_BCM 794 (info)); 795 if (BCMX_MPLS_GET_IS_VALID(bcm_unit, rv)) { 796 return rv; 797 } 798 } 799 800 return BCM_E_UNAVAIL; 801 } 802 803 /* 804 * Function: 805 * bcmx_mpls_label_stat_get 806 */ 807 int 808 bcmx_mpls_label_stat_get(bcm_mpls_label_t label, bcm_gport_t port, 809 bcm_mpls_stat_t stat, uint64 *val) 810 { 811 int rv = BCM_E_UNAVAIL, tmp_rv; 812 int i; 813 int bcm_unit; 814 bcm_port_t bcm_port; 815 uint64 tmp_val; 816 817 BCMX_MPLS_INIT_CHECK; 818 819 BCMX_PARAM_NULL_CHECK(val); 820 821 /* 822 * If gport is a valid BCMX logical port, then gport refers to 823 * a specific physical port (mod/port or dev/port). 824 * Else, gport is a system-wide value, gather stats from all units. 825 */ 826 if (BCM_SUCCESS(_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port, 827 BCMX_DEST_CONVERT_DEFAULT))) { 828 return bcm_mpls_label_stat_get(bcm_unit, label, port, stat, val); 829 } 830 831 COMPILER_64_ZERO(*val); 832 BCMX_UNIT_ITER(bcm_unit, i) { 833 tmp_rv = bcm_mpls_label_stat_get(bcm_unit, label, port, stat, 834 &tmp_val); 835 if (BCMX_MPLS_GET_IS_VALID(bcm_unit, tmp_rv)) { 836 rv = tmp_rv; 837 if (BCM_SUCCESS(tmp_rv)) { 838 COMPILER_64_ADD_64(*val, tmp_val); 839 } else { 840 break; 841 } 842 } 843 } 844 845 return rv; 846 } 847 848 /* 849 * Function: 850 * bcmx_mpls_label_stat_get32 851 */ 852 int 853 bcmx_mpls_label_stat_get32(bcm_mpls_label_t label, bcm_gport_t port, 854 bcm_mpls_stat_t stat, uint32 *val) 855 { 856 int rv = BCM_E_UNAVAIL, tmp_rv; 857 int i; 858 int bcm_unit; 859 bcm_port_t bcm_port; 860 uint32 tmp_val; 861 862 BCMX_MPLS_INIT_CHECK; 863 864 BCMX_PARAM_NULL_CHECK(val); 865 866 /* 867 * If gport is a valid BCMX logical port, then gport refers to 868 * a specific physical port (mod/port or dev/port). 869 * Else, gport is a system-wide value, gather stats from all units. 870 */ 871 if (BCM_SUCCESS(_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port, 872 BCMX_DEST_CONVERT_DEFAULT))) { 873 return bcm_mpls_label_stat_get32(bcm_unit, label, port, stat, val); 874 } 875 876 *val = 0; 877 BCMX_UNIT_ITER(bcm_unit, i) { 878 tmp_rv = bcm_mpls_label_stat_get32(bcm_unit, label, port, stat, 879 &tmp_val); 880 if (BCMX_MPLS_GET_IS_VALID(bcm_unit, tmp_rv)) { 881 rv = tmp_rv; 882 if (BCM_SUCCESS(tmp_rv)) { 883 *val += tmp_val; 884 } else { 885 break; 886 } 887 } 888 } 889 890 return rv; 891 } 892 893 /* 894 * Function: 895 * bcmx_mpls_label_stat_clear 896 */ 897 int 898 bcmx_mpls_label_stat_clear(bcm_mpls_label_t label, bcm_gport_t port, 899 bcm_mpls_stat_t stat) 900 { 901 int rv = BCM_E_UNAVAIL, tmp_rv; 902 int i; 903 int bcm_unit; 904 bcm_port_t bcm_port; 905 906 BCMX_MPLS_INIT_CHECK; 907 908 /* 909 * If gport is a valid BCMX logical port, then gport refers to 910 * a specific physical port (mod/port or dev/port). 911 * Else, gport is a system-wide value. 912 */ 913 if (BCM_SUCCESS(_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port, 914 BCMX_DEST_CONVERT_DEFAULT))) { 915 return bcm_mpls_label_stat_clear(bcm_unit, label, port, stat); 916 } 917 918 BCMX_UNIT_ITER(bcm_unit, i) { 919 tmp_rv = bcm_mpls_label_stat_clear(bcm_unit, label, port, stat); 920 BCM_IF_ERROR_RETURN 921 (BCMX_MPLS_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 922 } 923 924 return rv; 925 } 926 927 #endif /* INCLUDE_L3 */ 928 929