l3.c (67196B)
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: bcmx/l3.c 8 * Purpose: BCMX L3 APIs 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 #include <bcmx/switch.h> 21 22 #include "bcmx_int.h" 23 24 #ifdef INCLUDE_L3 25 26 #define BCMX_L3_INIT_CHECK BCMX_READY_CHECK 27 28 #define BCMX_L3_ERROR_CHECK(_unit, _check, _rv) \ 29 BCMX_ERROR_CHECK(_unit, _check, _rv) 30 31 #define BCMX_L3_SET_ERROR_CHECK(_unit, _check, _rv) \ 32 BCMX_SET_ERROR_CHECK(_unit, _check, _rv) 33 34 #define BCMX_L3_DELETE_ERROR_CHECK(_unit, _check, _rv) \ 35 BCMX_DELETE_ERROR_CHECK(_unit, _check, _rv) 36 37 #define BCMX_L3_GET_IS_VALID(_unit, _rv) \ 38 BCMX_ERROR_IS_VALID(_unit, _rv) 39 40 41 #define BCMX_L3_SOURCE_BIND_T_PTR_TO_BCM(_info) \ 42 ((bcm_l3_source_bind_t *)(_info)) 43 44 #define BCMX_L3_INGRESS_T_PTR_TO_BCM(_ingress) \ 45 ((bcm_l3_ingress_t *)(_ingress)) 46 47 /* 48 * Function: 49 * _bcmx_bcm_l3_dest 50 * Purpose: 51 * Internal destination conversion routine to handle bcmx to/from bcm 52 * and check for egress mode to ignore invalid destinations (when indicated) 53 * Parameters: 54 * dest_bcmx - BCMX destination object to convert 55 * dest_bcm - BCM destination object to convert 56 * flags - Conversion flags 57 * to_bcm - Indicates whether to convert destination 58 * bcmx 'to' or 'from' bcm. 59 * egress_check - Indicates whether to ignore invalid destination 60 * conversion when in L3 egress mode 61 * Returns: 62 * BCM_E_NONE - Success 63 * BCM_E_xxx - Failure 64 */ 65 STATIC INLINE int 66 _bcmx_bcm_l3_dest(_bcmx_dest_bcmx_t *dest_bcmx, _bcmx_dest_bcm_t *dest_bcm, 67 uint32 *flags, int to_bcm, int egress_check) 68 { 69 int rv; 70 71 /* Convert */ 72 if (to_bcm) { 73 rv = _bcmx_dest_to_bcm(dest_bcmx, dest_bcm, flags); 74 } else { 75 rv = _bcmx_dest_from_bcm(dest_bcmx, dest_bcm, flags); 76 } 77 78 /* Ignore invalid destination conversion when in L3 egress mode */ 79 if (BCM_FAILURE(rv) && egress_check) { 80 int l3_egress; 81 82 if (BCM_SUCCESS(bcmx_switch_control_get(bcmSwitchL3EgressMode, 83 &l3_egress))) { 84 if (l3_egress) { 85 rv = BCM_E_NONE; 86 } 87 } 88 } 89 90 return rv; 91 } 92 93 STATIC INLINE int 94 _bcmx_l3ip_to_bcm(bcmx_l3_host_t *l3xip, bcm_l3_host_t *l3ip, int convert_port) 95 { 96 int rv = BCM_E_NONE; 97 uint32 flags = BCMX_DEST_CONVERT_DEFAULT; 98 _bcmx_dest_bcm_t to_bcm; 99 _bcmx_dest_bcmx_t from_bcmx; 100 101 bcm_l3_host_t_init(l3ip); 102 l3ip->l3a_flags = l3xip->l3a_flags; 103 104 if (convert_port) { 105 /* 106 * Convert destination data 107 */ 108 _bcmx_dest_bcmx_t_init(&from_bcmx); 109 110 /* Set flags and data to convert */ 111 if (l3xip->l3a_flags & BCM_L3_TGID) { 112 flags |= BCMX_DEST_TRUNK; 113 } 114 from_bcmx.port = l3xip->l3a_lport; 115 from_bcmx.trunk = l3xip->l3a_trunk; 116 117 /* Convert */ 118 /* Indicate to check egress mode in case of invalid destination */ 119 rv = _bcmx_bcm_l3_dest(&from_bcmx, &to_bcm, &flags, 1, 1); 120 121 /* Set converted flags and data */ 122 if (flags & BCMX_DEST_TRUNK) { 123 l3ip->l3a_flags |= BCM_L3_TGID; 124 l3ip->l3a_port_tgid = to_bcm.trunk; 125 } else if (flags & BCMX_DEST_DISCARD) { 126 l3ip->l3a_flags |= BCM_L3_DST_DISCARD; 127 } else { 128 l3ip->l3a_modid = to_bcm.module_id; 129 l3ip->l3a_port_tgid = to_bcm.module_port; 130 } 131 } 132 133 134 /* Set remaining fields */ 135 l3ip->l3a_ip_addr = l3xip->l3a_ip_addr; 136 l3ip->l3a_intf = l3xip->l3a_intf; 137 l3ip->l3a_vrf = l3xip->l3a_vrf; 138 sal_memcpy(l3ip->l3a_ip6_addr, l3xip->l3a_ip6_addr, 139 sizeof(bcm_ip6_t)); 140 sal_memcpy(l3ip->l3a_nexthop_mac, l3xip->l3a_nexthop_mac, 141 sizeof(bcm_mac_t)); 142 l3ip->l3a_ipmc_ptr = l3xip->l3a_ipmc_ptr; 143 l3ip->l3a_pri = l3xip->l3a_pri; 144 l3ip->l3a_lookup_class = l3xip->l3a_lookup_class; 145 146 return rv; 147 } 148 149 STATIC INLINE int 150 _bcmx_l3ip_from_bcm(bcmx_l3_host_t *l3xip, bcm_l3_host_t *l3ip) 151 { 152 int rv = BCM_E_NONE; 153 uint32 flags = BCMX_DEST_CONVERT_DEFAULT; 154 _bcmx_dest_bcm_t from_bcm; 155 _bcmx_dest_bcmx_t to_bcmx; 156 157 158 bcmx_l3_host_t_init(l3xip); 159 l3xip->l3a_flags = l3ip->l3a_flags; 160 161 /* 162 * Convert destination data 163 */ 164 _bcmx_dest_bcm_t_init(&from_bcm); 165 166 /* Set flags and data to convert */ 167 if (l3ip->l3a_flags & BCM_L3_TGID) { 168 flags |= BCMX_DEST_TRUNK; 169 } 170 from_bcm.module_id = l3ip->l3a_modid; 171 from_bcm.module_port = l3ip->l3a_port_tgid; 172 from_bcm.trunk = l3ip->l3a_port_tgid; 173 174 /* Convert */ 175 /* Indicate to check egress mode in case of invalid destination */ 176 rv = _bcmx_bcm_l3_dest(&to_bcmx, &from_bcm, &flags, 0, 1); 177 178 /* Set converted flags and data */ 179 if (flags & BCMX_DEST_TRUNK) { 180 l3xip->l3a_flags |= BCM_L3_TGID; 181 } else if (flags & BCMX_DEST_DISCARD) { 182 l3xip->l3a_flags |= BCM_L3_DST_DISCARD; 183 } 184 l3xip->l3a_lport = to_bcmx.port; 185 l3xip->l3a_trunk = to_bcmx.trunk; 186 187 188 /* Set remaining fields */ 189 l3xip->l3a_ip_addr = l3ip->l3a_ip_addr; 190 l3xip->l3a_intf = l3ip->l3a_intf; 191 l3xip->l3a_vrf = l3ip->l3a_vrf; 192 sal_memcpy(l3xip->l3a_ip6_addr, l3ip->l3a_ip6_addr, 193 sizeof(bcm_ip6_t)); 194 sal_memcpy(l3xip->l3a_nexthop_mac, l3ip->l3a_nexthop_mac, 195 sizeof(bcm_mac_t)); 196 l3xip->l3a_ipmc_ptr = l3ip->l3a_ipmc_ptr; 197 l3xip->l3a_pri = l3ip->l3a_pri; 198 l3xip->l3a_lookup_class = l3ip->l3a_lookup_class; 199 200 return rv; 201 } 202 203 STATIC INLINE int 204 _bcmx_l3egress_to_bcm(bcmx_l3_egress_t *l3xegr, bcm_l3_egress_t *l3egr) 205 { 206 uint32 flags = BCMX_DEST_CONVERT_DEFAULT; 207 _bcmx_dest_bcm_t to_bcm; 208 _bcmx_dest_bcmx_t from_bcmx; 209 210 bcm_l3_egress_t_init(l3egr); 211 l3egr->flags = l3xegr->flags; 212 213 /* 214 * Convert destination data 215 */ 216 _bcmx_dest_bcmx_t_init(&from_bcmx); 217 218 /* Set flags and data to convert */ 219 if (l3xegr->flags & BCM_L3_TGID) { 220 flags |= BCMX_DEST_TRUNK; 221 } 222 from_bcmx.port = l3xegr->lport; 223 from_bcmx.trunk = l3xegr->trunk; 224 225 /* Convert */ 226 /* Return on invalid destination conversion since egress object 227 * needs to always have a valid destination. 228 */ 229 BCM_IF_ERROR_RETURN(_bcmx_bcm_l3_dest(&from_bcmx, &to_bcm, &flags, 1, 0)); 230 231 /* Set converted flags and data */ 232 if (flags & BCMX_DEST_TRUNK) { 233 l3egr->flags |= BCM_L3_TGID; 234 } else if (flags & BCMX_DEST_DISCARD) { 235 l3egr->flags |= BCM_L3_DST_DISCARD; 236 } 237 l3egr->module = to_bcm.module_id; 238 l3egr->port = to_bcm.module_port; 239 l3egr->trunk = to_bcm.trunk; 240 241 242 /* Set remaining fields */ 243 l3egr->intf = l3xegr->intf; 244 sal_memcpy(l3egr->mac_addr, l3xegr->mac_addr, sizeof(bcm_mac_t)); 245 l3egr->vlan = l3xegr->vlan; 246 l3egr->mpls_flags = l3xegr->mpls_flags; 247 l3egr->mpls_label = l3xegr->mpls_label; 248 l3egr->mpls_qos_map_id = l3xegr->mpls_qos_map_id; 249 l3egr->mpls_ttl = l3xegr->mpls_ttl; 250 l3egr->mpls_pkt_pri = l3xegr->mpls_pkt_pri; 251 l3egr->mpls_pkt_cfi = l3xegr->mpls_pkt_cfi; 252 l3egr->mpls_exp = l3xegr->mpls_exp; 253 l3egr->encap_id = l3xegr->encap_id; 254 l3egr->failover_id = l3xegr->failover_id; 255 l3egr->failover_if_id = l3xegr->failover_if_id; 256 257 return BCM_E_NONE; 258 } 259 260 STATIC INLINE int 261 _bcmx_l3egress_from_bcm(bcmx_l3_egress_t *l3xegr, bcm_l3_egress_t *l3egr) 262 { 263 uint32 flags = BCMX_DEST_CONVERT_DEFAULT; 264 _bcmx_dest_bcm_t from_bcm; 265 _bcmx_dest_bcmx_t to_bcmx; 266 267 bcmx_l3_egress_t_init(l3xegr); 268 l3xegr->flags = l3egr->flags; 269 270 /* 271 * Convert destination data 272 */ 273 _bcmx_dest_bcm_t_init(&from_bcm); 274 275 /* Set flags and data to convert */ 276 if (l3egr->flags & BCM_L3_TGID) { 277 flags |= BCMX_DEST_TRUNK; 278 } 279 from_bcm.module_id = l3egr->module; 280 from_bcm.module_port = l3egr->port; 281 from_bcm.trunk = l3egr->trunk; 282 283 /* Convert */ 284 /* Return on invalid destination conversion since egress object 285 * needs to always have a valid destination. 286 */ 287 BCM_IF_ERROR_RETURN(_bcmx_bcm_l3_dest(&to_bcmx, &from_bcm, &flags, 0, 0)); 288 289 /* Set converted flags and data */ 290 if (flags & BCMX_DEST_TRUNK) { 291 l3xegr->flags |= BCM_L3_TGID; 292 } else if (flags & BCMX_DEST_DISCARD) { 293 l3xegr->flags |= BCM_L3_DST_DISCARD; 294 } 295 l3xegr->lport = to_bcmx.port; 296 l3xegr->trunk = to_bcmx.trunk; 297 298 299 /* Set remaining fields */ 300 l3xegr->intf = l3egr->intf; 301 sal_memcpy(l3xegr->mac_addr, l3egr->mac_addr, sizeof(bcm_mac_t)); 302 l3xegr->vlan = l3egr->vlan; 303 l3xegr->mpls_flags = l3egr->mpls_flags; 304 l3xegr->mpls_label = l3egr->mpls_label; 305 l3xegr->mpls_qos_map_id = l3egr->mpls_qos_map_id; 306 l3xegr->mpls_ttl = l3egr->mpls_ttl; 307 l3xegr->mpls_pkt_pri = l3egr->mpls_pkt_pri; 308 l3xegr->mpls_pkt_cfi = l3egr->mpls_pkt_cfi; 309 l3xegr->mpls_exp = l3egr->mpls_exp; 310 l3xegr->encap_id = l3egr->encap_id; 311 l3xegr->failover_id = l3egr->failover_id; 312 l3xegr->failover_if_id = l3egr->failover_if_id; 313 314 return BCM_E_NONE; 315 } 316 317 318 STATIC INLINE int 319 _bcmx_l3route_to_bcm(bcmx_l3_route_t *l3xrt, bcm_l3_route_t *l3rt, 320 int convert_port) 321 { 322 int rv = BCM_E_NONE; 323 uint32 flags = BCMX_DEST_CONVERT_DEFAULT; 324 _bcmx_dest_bcm_t to_bcm; 325 _bcmx_dest_bcmx_t from_bcmx; 326 327 bcm_l3_route_t_init(l3rt); 328 l3rt->l3a_flags = l3xrt->l3a_flags; 329 330 if (convert_port) { 331 /* 332 * Convert destination data 333 */ 334 _bcmx_dest_bcmx_t_init(&from_bcmx); 335 336 /* Set flags and data to convert */ 337 if (l3xrt->l3a_flags & BCM_L3_TGID) { 338 flags |= BCMX_DEST_TRUNK; 339 } 340 from_bcmx.port = l3xrt->l3a_lport; 341 from_bcmx.trunk = l3xrt->l3a_trunk; 342 343 /* Convert */ 344 /* Indicate to check egress mode in case of invalid destination */ 345 rv = _bcmx_bcm_l3_dest(&from_bcmx, &to_bcm, &flags, 1, 1); 346 347 /* Set converted flags and data */ 348 if (flags & BCMX_DEST_TRUNK) { 349 l3rt->l3a_flags |= BCM_L3_TGID; 350 l3rt->l3a_port_tgid = to_bcm.trunk; 351 } else if (flags & BCMX_DEST_DISCARD) { 352 l3rt->l3a_flags |= BCM_L3_DST_DISCARD; 353 } else { 354 l3rt->l3a_modid = to_bcm.module_id; 355 l3rt->l3a_port_tgid = to_bcm.module_port; 356 } 357 } 358 359 /* Set remaining fields */ 360 l3rt->l3a_stack_port = 0; 361 l3rt->l3a_subnet = l3xrt->l3a_subnet; 362 l3rt->l3a_ip_mask = l3xrt->l3a_ip_mask; 363 l3rt->l3a_intf = l3xrt->l3a_intf; 364 l3rt->l3a_vrf = l3xrt->l3a_vrf; 365 sal_memcpy(l3rt->l3a_ip6_net, l3xrt->l3a_ip6_net, 366 sizeof(bcm_ip6_t)); 367 sal_memcpy(l3rt->l3a_ip6_mask, l3xrt->l3a_ip6_mask, 368 sizeof(bcm_ip6_t)); 369 sal_memcpy(l3rt->l3a_nexthop_mac, l3xrt->l3a_nexthop_mac, 370 sizeof(bcm_mac_t)); 371 l3rt->l3a_nexthop_ip = l3xrt->l3a_nexthop_ip; 372 l3rt->l3a_vid = l3xrt->l3a_vid; 373 l3rt->l3a_pri = l3xrt->l3a_pri; 374 l3rt->l3a_tunnel_option = l3xrt->l3a_tunnel_option; 375 l3rt->l3a_mpls_label = l3xrt->l3a_mpls_label; 376 l3rt->l3a_lookup_class = l3xrt->l3a_lookup_class; 377 378 return rv; 379 } 380 381 STATIC INLINE int 382 _bcmx_l3route_from_bcm(bcmx_l3_route_t *l3xrt, bcm_l3_route_t *l3rt) 383 { 384 int rv = BCM_E_NONE; 385 uint32 flags = BCMX_DEST_CONVERT_DEFAULT; 386 _bcmx_dest_bcm_t from_bcm; 387 _bcmx_dest_bcmx_t to_bcmx; 388 389 bcmx_l3_route_t_init(l3xrt); 390 l3xrt->l3a_flags = l3rt->l3a_flags; 391 392 /* 393 * Convert destination data 394 */ 395 _bcmx_dest_bcm_t_init(&from_bcm); 396 397 /* Set flags and data to convert */ 398 if (l3rt->l3a_flags & BCM_L3_TGID) { 399 flags |= BCMX_DEST_TRUNK; 400 } 401 from_bcm.module_id = l3rt->l3a_modid; 402 from_bcm.module_port = l3rt->l3a_port_tgid; 403 from_bcm.trunk = l3rt->l3a_port_tgid; 404 405 /* Convert */ 406 /* Indicate to check egress mode in case of invalid destination */ 407 rv = _bcmx_bcm_l3_dest(&to_bcmx, &from_bcm, &flags, 0, 1); 408 409 /* Set converted flags and data */ 410 if (flags & BCMX_DEST_TRUNK) { 411 l3xrt->l3a_flags |= BCM_L3_TGID; 412 } else if (flags & BCMX_DEST_DISCARD) { 413 l3xrt->l3a_flags |= BCM_L3_DST_DISCARD; 414 } 415 l3xrt->l3a_lport = to_bcmx.port; 416 l3xrt->l3a_trunk = to_bcmx.trunk; 417 418 419 /* Set remaining fields */ 420 l3xrt->l3a_subnet = l3rt->l3a_subnet; 421 l3xrt->l3a_ip_mask = l3rt->l3a_ip_mask; 422 l3xrt->l3a_intf = l3rt->l3a_intf; 423 l3xrt->l3a_vrf = l3rt->l3a_vrf; 424 sal_memcpy(l3xrt->l3a_ip6_net, l3rt->l3a_ip6_net, 425 sizeof(bcm_ip6_t)); 426 sal_memcpy(l3xrt->l3a_ip6_mask, l3rt->l3a_ip6_mask, 427 sizeof(bcm_ip6_t)); 428 sal_memcpy(l3xrt->l3a_nexthop_mac, l3rt->l3a_nexthop_mac, 429 sizeof(bcm_mac_t)); 430 l3xrt->l3a_nexthop_ip = l3rt->l3a_nexthop_ip; 431 l3xrt->l3a_vid = l3rt->l3a_vid; 432 l3xrt->l3a_pri = l3rt->l3a_pri; 433 l3xrt->l3a_tunnel_option = l3rt->l3a_tunnel_option; 434 l3xrt->l3a_mpls_label = l3rt->l3a_mpls_label; 435 l3xrt->l3a_lookup_class = l3rt->l3a_lookup_class; 436 437 return rv; 438 } 439 440 441 /* 442 * Initialize a L3 IP struct 443 */ 444 int 445 bcmx_l3_host_t_init(bcmx_l3_host_t *ip) 446 { 447 if (ip != NULL) { 448 sal_memset(ip, 0, sizeof(bcmx_l3_host_t)); 449 ip->l3a_vrf = BCM_L3_VRF_DEFAULT; 450 } 451 452 return BCM_E_NONE; 453 } 454 455 /* 456 * Initialize a L3 route struct 457 */ 458 int 459 bcmx_l3_route_t_init(bcmx_l3_route_t *route) 460 { 461 if (route != NULL) { 462 sal_memset(route, 0, sizeof(bcmx_l3_route_t)); 463 route->l3a_vrf = BCM_L3_VRF_DEFAULT; 464 } 465 466 return BCM_E_NONE; 467 } 468 469 /* 470 * Initialize a L3 interface struct 471 */ 472 int 473 bcmx_l3_intf_t_init(bcmx_l3_intf_t *intf) 474 { 475 if (intf != NULL) { 476 sal_memset(intf, 0, sizeof(bcmx_l3_intf_t)); 477 intf->l3a_vrf = BCM_L3_VRF_DEFAULT; 478 } 479 480 return BCM_E_NONE; 481 } 482 483 /* 484 * Initialize a L3 egress object struct 485 */ 486 void 487 bcmx_l3_egress_t_init(bcmx_l3_egress_t *egr) 488 { 489 if (egr != NULL) { 490 sal_memset(egr, 0, sizeof(bcmx_l3_egress_t)); 491 egr->mpls_label = BCM_MPLS_LABEL_INVALID; 492 } 493 } 494 495 /* 496 * Initialize a L3 source bind object struct 497 */ 498 void bcmx_l3_source_bind_t_init(bcmx_l3_source_bind_t *info) 499 { 500 if (info != NULL) { 501 bcm_l3_source_bind_t_init 502 (BCMX_L3_SOURCE_BIND_T_PTR_TO_BCM(info)); 503 } 504 } 505 506 /* 507 * Initialize a L3 ingress object struct 508 */ 509 void 510 bcmx_l3_ingress_t_init(bcmx_l3_ingress_t *ing_intf) 511 { 512 if (ing_intf != NULL) { 513 bcm_l3_ingress_t_init(BCMX_L3_INGRESS_T_PTR_TO_BCM(ing_intf)); 514 } 515 } 516 517 518 /* 519 * Function: 520 * bcmx_l3_init 521 */ 522 523 int 524 bcmx_l3_init(void) 525 { 526 int rv = BCM_E_UNAVAIL, tmp_rv; 527 int i, bcm_unit; 528 529 BCMX_L3_INIT_CHECK; 530 531 BCMX_UNIT_ITER(bcm_unit, i) { 532 tmp_rv = bcm_l3_init(bcm_unit); 533 BCM_IF_ERROR_RETURN(BCMX_L3_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 534 } 535 536 return rv; 537 } 538 539 540 /* 541 * Function: 542 * bcmx_l3_cleanup 543 */ 544 545 int 546 bcmx_l3_cleanup(void) 547 { 548 int rv = BCM_E_UNAVAIL, tmp_rv; 549 int i, bcm_unit; 550 551 BCMX_L3_INIT_CHECK; 552 553 BCMX_UNIT_ITER(bcm_unit, i) { 554 tmp_rv = bcm_l3_cleanup(bcm_unit); 555 BCM_IF_ERROR_RETURN(BCMX_L3_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 556 } 557 558 return rv; 559 } 560 561 562 /* 563 * Function: 564 * bcmx_l3_enable_set 565 */ 566 567 int 568 bcmx_l3_enable_set(int enable) 569 { 570 int rv = BCM_E_UNAVAIL, tmp_rv; 571 int i, bcm_unit; 572 573 BCMX_L3_INIT_CHECK; 574 575 BCMX_UNIT_ITER(bcm_unit, i) { 576 tmp_rv = bcm_l3_enable_set(bcm_unit, enable); 577 BCM_IF_ERROR_RETURN(BCMX_L3_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 578 } 579 580 return rv; 581 } 582 583 584 /* 585 * Function: 586 * bcmx_l3_info 587 */ 588 589 int 590 bcmx_l3_info(bcm_l3_info_t *l3info) 591 { 592 int rv = BCM_E_UNAVAIL, tmp_rv; 593 int i, bcm_unit; 594 bcm_l3_info_t tmp_l3info; 595 int first = TRUE; 596 597 BCMX_L3_INIT_CHECK; 598 599 BCMX_PARAM_NULL_CHECK(l3info); 600 601 BCMX_UNIT_ITER(bcm_unit, i) { 602 tmp_rv = bcm_l3_info(bcm_unit, &tmp_l3info); 603 604 if (BCMX_L3_GET_IS_VALID(bcm_unit, tmp_rv)) { 605 rv = tmp_rv; 606 607 BCM_IF_ERROR_RETURN(rv); 608 609 if (first) { 610 *l3info = tmp_l3info; 611 first = FALSE; 612 continue; 613 } 614 615 /* Set the minimum for 'max' members */ 616 if (tmp_l3info.l3info_max_vrf < l3info->l3info_max_vrf) { 617 l3info->l3info_max_vrf = tmp_l3info.l3info_max_vrf; 618 } 619 if (tmp_l3info.l3info_max_intf < l3info->l3info_max_intf) { 620 l3info->l3info_max_intf = tmp_l3info.l3info_max_intf; 621 } 622 if (tmp_l3info.l3info_max_intf_group < l3info->l3info_max_intf_group) { 623 l3info->l3info_max_intf_group = tmp_l3info.l3info_max_intf_group; 624 } 625 if (tmp_l3info.l3info_max_host < l3info->l3info_max_host) { 626 l3info->l3info_max_host = tmp_l3info.l3info_max_host; 627 } 628 if (tmp_l3info.l3info_max_route < l3info->l3info_max_route) { 629 l3info->l3info_max_route = tmp_l3info.l3info_max_route; 630 } 631 if (tmp_l3info.l3info_max_ecmp < l3info->l3info_max_ecmp) { 632 l3info->l3info_max_ecmp = tmp_l3info.l3info_max_ecmp; 633 } 634 635 if (tmp_l3info.l3info_max_lpm_block < l3info->l3info_max_lpm_block) { 636 l3info->l3info_max_lpm_block = tmp_l3info.l3info_max_lpm_block; 637 } 638 if (tmp_l3info.l3info_max_l3 < l3info->l3info_max_l3) { 639 l3info->l3info_max_l3 = tmp_l3info.l3info_max_l3; 640 } 641 if (tmp_l3info.l3info_max_defip < l3info->l3info_max_defip) { 642 l3info->l3info_max_defip = tmp_l3info.l3info_max_defip; 643 } 644 645 if (tmp_l3info.l3info_max_nexthop < l3info->l3info_max_nexthop) { 646 l3info->l3info_max_nexthop = tmp_l3info.l3info_max_nexthop; 647 } 648 if (tmp_l3info.l3info_max_tunnel_init < l3info->l3info_max_tunnel_init) { 649 l3info->l3info_max_tunnel_init = tmp_l3info.l3info_max_tunnel_init; 650 } 651 if (tmp_l3info.l3info_max_tunnel_term < l3info->l3info_max_tunnel_term) { 652 l3info->l3info_max_tunnel_term = tmp_l3info.l3info_max_tunnel_term; 653 } 654 } 655 } 656 657 return rv; 658 } 659 660 661 /************************************************************** 662 * bcmx_l3_intf_xxx 663 */ 664 665 /* 666 * Function: 667 * bcmx_l3_intf_create 668 */ 669 670 int 671 bcmx_l3_intf_create(bcmx_l3_intf_t *intf) 672 { 673 int rv = BCM_E_UNAVAIL, tmp_rv; 674 int i, bcm_unit; 675 676 BCMX_L3_INIT_CHECK; 677 678 BCMX_PARAM_NULL_CHECK(intf); 679 680 BCMX_UNIT_ITER(bcm_unit, i) { 681 tmp_rv = bcm_l3_intf_create(bcm_unit, intf); 682 BCM_IF_ERROR_RETURN(BCMX_L3_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 683 } 684 685 return rv; 686 } 687 688 /* 689 * Function: 690 * bcmx_l3_intf_delete 691 */ 692 693 int 694 bcmx_l3_intf_delete(bcmx_l3_intf_t *intf) 695 { 696 int rv = BCM_E_UNAVAIL, tmp_rv; 697 int i, bcm_unit; 698 699 BCMX_L3_INIT_CHECK; 700 701 BCMX_PARAM_NULL_CHECK(intf); 702 703 BCMX_UNIT_ITER(bcm_unit, i) { 704 tmp_rv = bcm_l3_intf_delete(bcm_unit, intf); 705 BCM_IF_ERROR_RETURN(BCMX_L3_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 706 } 707 708 return rv; 709 } 710 711 /* 712 * Function: 713 * bcmx_l3_intf_delete_all 714 */ 715 716 int 717 bcmx_l3_intf_delete_all(void) 718 { 719 int rv = BCM_E_UNAVAIL, tmp_rv; 720 int i, bcm_unit; 721 722 BCMX_L3_INIT_CHECK; 723 724 BCMX_UNIT_ITER(bcm_unit, i) { 725 tmp_rv = bcm_l3_intf_delete_all(bcm_unit); 726 BCM_IF_ERROR_RETURN(BCMX_L3_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 727 } 728 729 return rv; 730 } 731 732 /* 733 * Function: 734 * bcmx_l3_intf_find 735 */ 736 737 int 738 bcmx_l3_intf_find(bcmx_l3_intf_t *intf) 739 { 740 int rv; 741 int i, bcm_unit; 742 743 BCMX_L3_INIT_CHECK; 744 745 BCMX_PARAM_NULL_CHECK(intf); 746 747 BCMX_UNIT_ITER(bcm_unit, i) { 748 rv = bcm_l3_intf_find(bcm_unit, intf); 749 if (BCMX_L3_GET_IS_VALID(bcm_unit, rv)) { 750 return rv; 751 } 752 } 753 754 return BCM_E_UNAVAIL; 755 } 756 757 /* 758 * Function: 759 * bcmx_l3_intf_find_vlan 760 */ 761 762 int 763 bcmx_l3_intf_find_vlan(bcm_l3_intf_t *intf) 764 { 765 int rv; 766 int i, bcm_unit; 767 768 BCMX_L3_INIT_CHECK; 769 770 BCMX_PARAM_NULL_CHECK(intf); 771 772 BCMX_UNIT_ITER(bcm_unit, i) { 773 rv = bcm_l3_intf_find_vlan(bcm_unit, intf); 774 if (BCMX_L3_GET_IS_VALID(bcm_unit, rv)) { 775 return rv; 776 } 777 } 778 779 return BCM_E_UNAVAIL; 780 } 781 782 /* 783 * Function: 784 * bcmx_l3_intf_get 785 */ 786 787 int 788 bcmx_l3_intf_get(bcm_l3_intf_t *intf) 789 { 790 int rv; 791 int i, bcm_unit; 792 793 BCMX_L3_INIT_CHECK; 794 795 BCMX_PARAM_NULL_CHECK(intf); 796 797 BCMX_UNIT_ITER(bcm_unit, i) { 798 rv = bcm_l3_intf_get(bcm_unit, intf); 799 if (BCMX_L3_GET_IS_VALID(bcm_unit, rv)) { 800 return rv; 801 } 802 } 803 804 return BCM_E_UNAVAIL; 805 } 806 807 /************************************************************** 808 * bcmx_l3_egress_xxx 809 */ 810 int 811 bcmx_l3_egress_create(uint32 flags, bcmx_l3_egress_t *egr, bcm_if_t *intf) 812 { 813 int rv = BCM_E_UNAVAIL; /* Overall operation result. */ 814 int tmp_rv; /* Unit operation result. */ 815 int unit_cntr; /* Number of devices counter. */ 816 int bcm_unit; /* bcm device iterator. */ 817 bcm_l3_egress_t bcm_egr; /* Egress object. */ 818 int map_local_cpu; /* Is local CPU port mapping required? */ 819 bcmx_lport_t cpu_lport; /* Cpu logical port. */ 820 821 BCMX_L3_INIT_CHECK; 822 823 BCMX_PARAM_NULL_CHECK(egr); 824 BCMX_PARAM_NULL_CHECK(intf); 825 826 map_local_cpu = ((!(egr->flags & BCM_L3_TGID)) && 827 (egr->lport == BCMX_LPORT_LOCAL_CPU)); 828 829 BCM_IF_ERROR_RETURN(_bcmx_l3egress_to_bcm(egr, &bcm_egr)); 830 831 if ((!map_local_cpu) && 832 (!(egr->flags & BCM_L3_TGID) && (bcm_egr.module < 0)) && 833 (!BCM_GPORT_IS_SET(bcm_egr.port))) { 834 return (BCM_E_PORT); 835 } 836 837 BCMX_UNIT_ITER(bcm_unit, unit_cntr) { 838 if (map_local_cpu) { 839 cpu_lport = BCMX_LPORT_LOCAL_CPU_GET(bcm_unit); 840 if (BCM_FAILURE 841 (_bcmx_dest_to_modid_port(cpu_lport, 842 &bcm_egr.module, 843 &bcm_egr.port, 844 BCMX_DEST_CONVERT_DEFAULT))) { 845 /* Skip if can't find local CPU port */ 846 continue; 847 } 848 } 849 tmp_rv = bcm_l3_egress_create(bcm_unit, flags, &bcm_egr, intf); 850 BCM_IF_ERROR_RETURN(BCMX_L3_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 851 } 852 853 return rv; 854 } 855 856 int 857 bcmx_l3_egress_destroy(bcm_if_t intf) 858 { 859 int rv = BCM_E_UNAVAIL; /* Overall operation result. */ 860 int tmp_rv; /* Unit operation result. */ 861 int unit_cntr; /* Number of devices counter. */ 862 int bcm_unit; /* bcm device iterator. */ 863 864 BCMX_L3_INIT_CHECK; 865 866 BCMX_UNIT_ITER(bcm_unit, unit_cntr) { 867 tmp_rv = bcm_l3_egress_destroy(bcm_unit, intf); 868 BCM_IF_ERROR_RETURN(BCMX_L3_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 869 } 870 871 return rv; 872 } 873 874 int 875 bcmx_l3_egress_get(bcm_if_t intf, bcmx_l3_egress_t *egr) 876 { 877 int unit_cntr; /* Number of devices counter. */ 878 int bcm_unit; /* bcm device iterator. */ 879 bcm_l3_egress_t bcm_egr; /* Egress object. */ 880 int rv; /* Overall operation result. */ 881 882 BCMX_L3_INIT_CHECK; 883 884 BCMX_PARAM_NULL_CHECK(egr); 885 886 BCMX_UNIT_ITER(bcm_unit, unit_cntr) { 887 rv = bcm_l3_egress_get(bcm_unit, intf, &bcm_egr); 888 if (BCMX_L3_GET_IS_VALID(bcm_unit, rv)) { 889 if (BCM_SUCCESS(rv)) { 890 rv = _bcmx_l3egress_from_bcm(egr, &bcm_egr); 891 } 892 return rv; 893 } 894 } 895 896 return BCM_E_UNAVAIL; 897 } 898 899 int 900 bcmx_l3_egress_find(bcmx_l3_egress_t *egr, bcm_if_t *intf) 901 { 902 int unit_cntr; /* Number of devices counter. */ 903 int bcm_unit; /* bcm device iterator. */ 904 bcm_l3_egress_t bcm_egr; /* Egress object. */ 905 int map_local_cpu; /* Is local CPU port mapping required? */ 906 bcmx_lport_t cpu_lport; /* Cpu logical port. */ 907 int rv; /* Overall operation result. */ 908 909 BCMX_L3_INIT_CHECK; 910 911 BCMX_PARAM_NULL_CHECK(egr); 912 BCMX_PARAM_NULL_CHECK(intf); 913 914 map_local_cpu = ((!(egr->flags & BCM_L3_TGID)) && 915 (egr->lport == BCMX_LPORT_LOCAL_CPU)); 916 917 BCM_IF_ERROR_RETURN(_bcmx_l3egress_to_bcm(egr, &bcm_egr)); 918 919 if ((!map_local_cpu) && 920 (!(egr->flags & BCM_L3_TGID) && (bcm_egr.module < 0))) { 921 return (BCM_E_PORT); 922 } 923 924 BCMX_UNIT_ITER(bcm_unit, unit_cntr) { 925 if (map_local_cpu) { 926 cpu_lport = BCMX_LPORT_LOCAL_CPU_GET(bcm_unit); 927 if (BCM_FAILURE 928 (_bcmx_dest_to_modid_port(cpu_lport, 929 &bcm_egr.module, 930 &bcm_egr.port, 931 BCMX_DEST_CONVERT_DEFAULT))) { 932 /* Skip if can't find local CPU port */ 933 continue; 934 } 935 } 936 rv = bcm_l3_egress_find(bcm_unit, &bcm_egr, intf); 937 if (BCMX_L3_GET_IS_VALID(bcm_unit, rv)) { 938 return rv; 939 } 940 } 941 942 return BCM_E_UNAVAIL; 943 } 944 945 int 946 bcmx_l3_egress_traverse(bcm_l3_egress_traverse_cb trav_fn, void *user_data) 947 { 948 int unit_cntr; /* Number of devices counter. */ 949 int bcm_unit; /* bcm device iterator. */ 950 int rv; /* Overall operation result. */ 951 952 BCMX_L3_INIT_CHECK; 953 954 BCMX_LOCAL_UNIT_ITER(bcm_unit, unit_cntr) { 955 rv = bcm_l3_egress_traverse(bcm_unit, trav_fn, user_data); 956 if (BCMX_L3_GET_IS_VALID(bcm_unit, rv)) { 957 return rv; 958 } 959 } 960 961 return BCM_E_UNAVAIL; 962 } 963 964 int 965 bcmx_l3_egress_multipath_create(uint32 flags, int intf_count, 966 bcm_if_t *intf_array, bcm_if_t *mpintf) 967 { 968 int rv = BCM_E_UNAVAIL; /* Overall operation result. */ 969 int tmp_rv; /* Unit operation result. */ 970 int unit_cntr; /* Number of devices counter. */ 971 int bcm_unit; /* bcm device iterator. */ 972 973 BCMX_L3_INIT_CHECK; 974 975 BCMX_PARAM_ARRAY_NULL_CHECK(intf_count, intf_array); 976 BCMX_PARAM_NULL_CHECK(mpintf); 977 978 BCMX_UNIT_ITER(bcm_unit, unit_cntr) { 979 tmp_rv = bcm_l3_egress_multipath_create(bcm_unit, flags, intf_count, 980 intf_array, mpintf); 981 BCM_IF_ERROR_RETURN(BCMX_L3_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 982 } 983 984 return rv; 985 } 986 987 int 988 bcmx_l3_egress_multipath_max_create(uint32 flags, 989 int max_paths, int intf_count, 990 bcm_if_t *intf_array, bcm_if_t *mpintf) 991 { 992 int rv = BCM_E_UNAVAIL, tmp_rv; 993 int i, bcm_unit; 994 995 BCMX_L3_INIT_CHECK; 996 997 BCMX_PARAM_ARRAY_NULL_CHECK(intf_count, intf_array); 998 BCMX_PARAM_NULL_CHECK(mpintf); 999 1000 BCMX_UNIT_ITER(bcm_unit, i) { 1001 tmp_rv = bcm_l3_egress_multipath_max_create(bcm_unit, flags, 1002 max_paths, intf_count, 1003 intf_array, mpintf); 1004 BCM_IF_ERROR_RETURN(BCMX_L3_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 1005 } 1006 1007 return rv; 1008 } 1009 1010 int 1011 bcmx_l3_egress_multipath_destroy(bcm_if_t mpintf) 1012 { 1013 int rv = BCM_E_UNAVAIL; /* Overall operation result. */ 1014 int tmp_rv; /* Unit operation result. */ 1015 int unit_cntr; /* Number of devices counter. */ 1016 int bcm_unit; /* bcm device iterator. */ 1017 1018 BCMX_L3_INIT_CHECK; 1019 1020 BCMX_UNIT_ITER(bcm_unit, unit_cntr) { 1021 tmp_rv = bcm_l3_egress_multipath_destroy(bcm_unit, mpintf); 1022 BCM_IF_ERROR_RETURN(BCMX_L3_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 1023 } 1024 1025 return rv; 1026 } 1027 1028 int 1029 bcmx_l3_egress_multipath_get(bcm_if_t mpintf, int intf_size, 1030 bcm_if_t *intf_array, int *intf_count) 1031 { 1032 int unit_cntr; /* Number of devices counter. */ 1033 int bcm_unit; /* bcm device iterator. */ 1034 int rv; /* Overall operation result. */ 1035 1036 BCMX_L3_INIT_CHECK; 1037 1038 BCMX_PARAM_ARRAY_NULL_CHECK(intf_size, intf_array); 1039 BCMX_PARAM_NULL_CHECK(intf_count); 1040 1041 BCMX_UNIT_ITER(bcm_unit, unit_cntr) { 1042 rv = bcm_l3_egress_multipath_get(bcm_unit, mpintf, intf_size, 1043 intf_array, intf_count); 1044 if (BCMX_L3_GET_IS_VALID(bcm_unit, rv)) { 1045 return rv; 1046 } 1047 } 1048 1049 return BCM_E_UNAVAIL; 1050 } 1051 1052 int 1053 bcmx_l3_egress_multipath_add(bcm_if_t mpintf, bcm_if_t intf) 1054 { 1055 int rv = BCM_E_UNAVAIL; /* Overall operation result. */ 1056 int tmp_rv; /* Unit operation result. */ 1057 int unit_cntr; /* Number of devices counter. */ 1058 int bcm_unit; /* bcm device iterator. */ 1059 1060 BCMX_L3_INIT_CHECK; 1061 1062 BCMX_UNIT_ITER(bcm_unit, unit_cntr) { 1063 tmp_rv = bcm_l3_egress_multipath_add(bcm_unit, mpintf, intf); 1064 BCM_IF_ERROR_RETURN(BCMX_L3_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 1065 } 1066 1067 return rv; 1068 } 1069 1070 int 1071 bcmx_l3_egress_multipath_delete(bcm_if_t mpintf, bcm_if_t intf) 1072 { 1073 int rv = BCM_E_UNAVAIL; /* Overall operation result. */ 1074 int tmp_rv; /* Unit operation result. */ 1075 int unit_cntr; /* Number of devices counter. */ 1076 int bcm_unit; /* bcm device iterator. */ 1077 1078 BCMX_L3_INIT_CHECK; 1079 1080 BCMX_UNIT_ITER(bcm_unit, unit_cntr) { 1081 tmp_rv = bcm_l3_egress_multipath_delete(bcm_unit, mpintf, intf); 1082 BCM_IF_ERROR_RETURN(BCMX_L3_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 1083 } 1084 1085 return rv; 1086 } 1087 1088 int 1089 bcmx_l3_egress_multipath_find(int intf_count, bcm_if_t *intf_array, 1090 bcm_if_t *mpintf) 1091 { 1092 int unit_cntr; /* Number of devices counter. */ 1093 int bcm_unit; /* bcm device iterator. */ 1094 int rv; /* Overall operation result. */ 1095 1096 BCMX_L3_INIT_CHECK; 1097 1098 BCMX_PARAM_ARRAY_NULL_CHECK(intf_count, intf_array); 1099 BCMX_PARAM_NULL_CHECK(mpintf); 1100 1101 BCMX_UNIT_ITER(bcm_unit, unit_cntr) { 1102 rv = bcm_l3_egress_multipath_find(bcm_unit, intf_count, 1103 intf_array, mpintf); 1104 if (BCMX_L3_GET_IS_VALID(bcm_unit, rv)) { 1105 return rv; 1106 } 1107 } 1108 1109 return BCM_E_UNAVAIL; 1110 } 1111 1112 int 1113 bcmx_l3_egress_multipath_traverse(bcm_l3_egress_multipath_traverse_cb trav_fn, 1114 void *user_data) 1115 { 1116 int unit_cntr; /* Number of devices counter. */ 1117 int bcm_unit; /* bcm device iterator. */ 1118 int rv; /* Overall operation result. */ 1119 1120 BCMX_L3_INIT_CHECK; 1121 1122 BCMX_LOCAL_UNIT_ITER(bcm_unit, unit_cntr) { 1123 rv = bcm_l3_egress_multipath_traverse(bcm_unit, trav_fn, user_data); 1124 if (BCMX_L3_GET_IS_VALID(bcm_unit, rv)) { 1125 return rv; 1126 } 1127 } 1128 1129 return BCM_E_UNAVAIL; 1130 } 1131 1132 1133 /************************************************************** 1134 * bcmx_l3_ingress_xxx 1135 */ 1136 /* 1137 * Function: 1138 * bcmx_l3_ingress_create 1139 * Purpose: 1140 * Create an Ingress Interface object. 1141 * Parameters: 1142 * ing_intf - Ingress Interface information. 1143 * intf_id - (IN/OUT) L3 Ingress interface id pointing to Ingress object. 1144 * This is an IN argument if either BCM_L3_INGRESS_REPLACE 1145 * or BCM_L3_INGRESS_WITH_ID are given in flags. 1146 * Returns: 1147 * BCM_E_XXX 1148 */ 1149 int 1150 bcmx_l3_ingress_create(bcmx_l3_ingress_t *ing_intf, bcm_if_t *intf_id) 1151 { 1152 int rv = BCM_E_UNAVAIL, tmp_rv; 1153 int i, bcm_unit; 1154 bcmx_l3_ingress_t tmp_ing_intf; 1155 1156 BCMX_L3_INIT_CHECK; 1157 1158 BCMX_PARAM_NULL_CHECK(ing_intf); 1159 BCMX_PARAM_NULL_CHECK(intf_id); 1160 1161 tmp_ing_intf = *ing_intf; 1162 BCMX_UNIT_ITER(bcm_unit, i) { 1163 1164 tmp_rv = bcm_l3_ingress_create(bcm_unit, 1165 BCMX_L3_INGRESS_T_PTR_TO_BCM 1166 (&tmp_ing_intf), 1167 intf_id); 1168 BCM_IF_ERROR_RETURN(BCMX_L3_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 1169 1170 /* 1171 * Use the ID from first successful 'create' if group ID 1172 * is not specified. 1173 */ 1174 if (!(tmp_ing_intf.flags & BCM_L3_INGRESS_WITH_ID)) { 1175 if (BCM_SUCCESS(tmp_rv)) { 1176 tmp_ing_intf.flags |= BCM_L3_INGRESS_WITH_ID; 1177 } 1178 } 1179 } 1180 1181 return rv; 1182 } 1183 1184 /* 1185 * Function: 1186 * bcmx_l3_ingress_destroy 1187 * Purpose: 1188 * Destroy an Ingress Interface object. 1189 * Parameters: 1190 * intf_id - L3 Ingress interface id pointing to Ingress object. 1191 * Returns: 1192 * BCM_E_XXX 1193 */ 1194 int 1195 bcmx_l3_ingress_destroy(bcm_if_t intf_id) 1196 { 1197 int rv = BCM_E_UNAVAIL, tmp_rv; 1198 int i, bcm_unit; 1199 1200 BCMX_L3_INIT_CHECK; 1201 1202 BCMX_UNIT_ITER(bcm_unit, i) { 1203 tmp_rv = bcm_l3_ingress_destroy(bcm_unit, intf_id); 1204 BCM_IF_ERROR_RETURN(BCMX_L3_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 1205 } 1206 1207 return rv; 1208 } 1209 1210 /* 1211 * Function: 1212 * bcmx_l3_ingress_get 1213 * Purpose: 1214 * Get an Ingress Interface object. 1215 * Parameters: 1216 * intf_id - L3 Ingress interface id pointing to Ingress object. 1217 * ing_intf - (OUT) Ingress Interface object properties. 1218 * Returns: 1219 * BCM_E_XXX 1220 */ 1221 int 1222 bcmx_l3_ingress_get(bcm_if_t intf, bcmx_l3_ingress_t *ing_intf) 1223 { 1224 int rv; 1225 int i, bcm_unit; 1226 1227 BCMX_L3_INIT_CHECK; 1228 1229 BCMX_PARAM_NULL_CHECK(ing_intf); 1230 1231 BCMX_UNIT_ITER(bcm_unit, i) { 1232 rv = bcm_l3_ingress_get(bcm_unit, intf, 1233 BCMX_L3_INGRESS_T_PTR_TO_BCM(ing_intf)); 1234 if (BCMX_L3_GET_IS_VALID(bcm_unit, rv)) { 1235 return rv; 1236 } 1237 } 1238 1239 return BCM_E_UNAVAIL; 1240 } 1241 1242 /* 1243 * Function: 1244 * bcmx_l3_ingress_find 1245 * Purpose: 1246 * Find the Ingress interface id. 1247 * Parameters: 1248 * ing_intf - Ingress Interface information. 1249 * intf_id - (OUT) L3 Ingress interface id pointing to Ingress object. 1250 * Returns: 1251 * BCM_E_XXX 1252 */ 1253 int 1254 bcmx_l3_ingress_find(bcmx_l3_ingress_t *ing_intf, bcm_if_t *intf_id) 1255 { 1256 int rv; 1257 int i, bcm_unit; 1258 1259 BCMX_L3_INIT_CHECK; 1260 1261 BCMX_PARAM_NULL_CHECK(ing_intf); 1262 BCMX_PARAM_NULL_CHECK(intf_id); 1263 1264 BCMX_UNIT_ITER(bcm_unit, i) { 1265 rv = bcm_l3_ingress_find(bcm_unit, 1266 BCMX_L3_INGRESS_T_PTR_TO_BCM(ing_intf), 1267 intf_id); 1268 if (BCMX_L3_GET_IS_VALID(bcm_unit, rv)) { 1269 return rv; 1270 } 1271 } 1272 1273 return BCM_E_UNAVAIL; 1274 } 1275 1276 1277 /* 1278 * IPv6 prefix map APIs. 1279 */ 1280 /************************************************************** 1281 * bcmx_l3_ip6_prefix_map APIs 1282 */ 1283 int bcmx_l3_ip6_prefix_map_get(int map_size, 1284 bcm_ip6_t *ip6_array, int *ip6_count) 1285 { 1286 int unit_cntr; /* Number of devices counter. */ 1287 int bcm_unit; /* bcm device iterator. */ 1288 int rv; /* Overall operation result. */ 1289 1290 BCMX_L3_INIT_CHECK; 1291 1292 BCMX_PARAM_ARRAY_NULL_CHECK(map_size, ip6_array); 1293 BCMX_PARAM_NULL_CHECK(ip6_count); 1294 1295 BCMX_LOCAL_UNIT_ITER(bcm_unit, unit_cntr) { 1296 rv = bcm_l3_ip6_prefix_map_get(bcm_unit, map_size, 1297 ip6_array, ip6_count); 1298 if (BCMX_L3_GET_IS_VALID(bcm_unit, rv)) { 1299 return rv; 1300 } 1301 } 1302 1303 return BCM_E_UNAVAIL; 1304 } 1305 1306 int bcmx_l3_ip6_prefix_map_add(bcm_ip6_t ip6_addr) 1307 { 1308 int rv = BCM_E_UNAVAIL; /* Overall operation result. */ 1309 int tmp_rv; /* Unit operation result. */ 1310 int unit_cntr; /* Number of devices counter. */ 1311 int bcm_unit; /* bcm device iterator. */ 1312 1313 BCMX_L3_INIT_CHECK; 1314 1315 BCMX_LOCAL_UNIT_ITER(bcm_unit, unit_cntr) { 1316 tmp_rv = bcm_l3_ip6_prefix_map_add(bcm_unit, ip6_addr); 1317 BCM_IF_ERROR_RETURN(BCMX_L3_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 1318 } 1319 1320 return rv; 1321 } 1322 1323 int bcmx_l3_ip6_prefix_map_delete(bcm_ip6_t ip6_addr) 1324 { 1325 int rv = BCM_E_UNAVAIL; /* Overall operation result. */ 1326 int tmp_rv; /* Unit operation result. */ 1327 int unit_cntr; /* Number of devices counter. */ 1328 int bcm_unit; /* bcm device iterator. */ 1329 1330 BCMX_L3_INIT_CHECK; 1331 1332 BCMX_LOCAL_UNIT_ITER(bcm_unit, unit_cntr) { 1333 tmp_rv = bcm_l3_ip6_prefix_map_delete(bcm_unit, ip6_addr); 1334 BCM_IF_ERROR_RETURN(BCMX_L3_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 1335 } 1336 1337 return rv; 1338 } 1339 1340 int bcmx_l3_ip6_prefix_map_delete_all(void) 1341 { 1342 int rv = BCM_E_UNAVAIL; /* Overall operation result. */ 1343 int tmp_rv; /* Unit operation result. */ 1344 int unit_cntr; /* Number of devices counter. */ 1345 int bcm_unit; /* bcm device iterator. */ 1346 1347 BCMX_L3_INIT_CHECK; 1348 1349 BCMX_LOCAL_UNIT_ITER(bcm_unit, unit_cntr) { 1350 tmp_rv = bcm_l3_ip6_prefix_map_delete_all(bcm_unit); 1351 BCM_IF_ERROR_RETURN(BCMX_L3_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 1352 } 1353 1354 return rv; 1355 } 1356 1357 /************************************************************** 1358 * bcmx_l3_host_xxx 1359 */ 1360 1361 /* 1362 * Function: 1363 * bcmx_l3_host_find 1364 */ 1365 1366 int 1367 bcmx_l3_host_find(bcmx_l3_host_t *info) 1368 { 1369 int rv = BCM_E_UNAVAIL, tmp_rv; 1370 int i, bcm_unit; 1371 bcm_l3_host_t bcm_l3; 1372 uint32 merged_flags = 0; 1373 1374 BCMX_L3_INIT_CHECK; 1375 1376 BCMX_PARAM_NULL_CHECK(info); 1377 1378 BCM_IF_ERROR_RETURN(_bcmx_l3ip_to_bcm(info, &bcm_l3, FALSE)); 1379 1380 BCMX_UNIT_ITER(bcm_unit, i) { 1381 tmp_rv = bcm_l3_host_find(bcm_unit, &bcm_l3); 1382 if (BCMX_L3_GET_IS_VALID(bcm_unit, tmp_rv)) { 1383 rv = tmp_rv; 1384 if (BCM_SUCCESS(rv)) { 1385 merged_flags |= bcm_l3.l3a_flags; 1386 } else { 1387 break; 1388 } 1389 } 1390 /* bcm_l3_host_find() may overwrite input flags */ 1391 bcm_l3.l3a_flags = info->l3a_flags; 1392 } 1393 1394 if (BCM_SUCCESS(rv)) { 1395 bcm_l3.l3a_flags |= merged_flags; 1396 BCM_IF_ERROR_RETURN(_bcmx_l3ip_from_bcm(info, &bcm_l3)); 1397 } 1398 1399 return rv; 1400 } 1401 1402 /* 1403 * Function: 1404 * bcmx_l3_host_add 1405 */ 1406 1407 int 1408 bcmx_l3_host_add(bcmx_l3_host_t *info) 1409 { 1410 int rv = BCM_E_UNAVAIL, tmp_rv; 1411 int i, bcm_unit; 1412 bcm_l3_host_t bcm_l3; 1413 int map_local_cpu; /* Is local CPU port mapping required? */ 1414 bcmx_lport_t cpu_lport; 1415 1416 BCMX_L3_INIT_CHECK; 1417 1418 BCMX_PARAM_NULL_CHECK(info); 1419 1420 map_local_cpu = ((!(info->l3a_flags & BCM_L3_TGID)) && 1421 (info->l3a_lport == BCMX_LPORT_LOCAL_CPU)); 1422 BCM_IF_ERROR_RETURN(_bcmx_l3ip_to_bcm(info, &bcm_l3, TRUE)); 1423 1424 BCMX_UNIT_ITER(bcm_unit, i) { 1425 if (map_local_cpu) { 1426 cpu_lport = BCMX_LPORT_LOCAL_CPU_GET(bcm_unit); 1427 if (BCM_FAILURE 1428 (_bcmx_dest_to_modid_port(cpu_lport, 1429 &bcm_l3.l3a_modid, 1430 &bcm_l3.l3a_port_tgid, 1431 BCMX_DEST_CONVERT_DEFAULT))) { 1432 /* Skip if can't find local CPU port */ 1433 continue; 1434 } 1435 } 1436 tmp_rv = bcm_l3_host_add(bcm_unit, &bcm_l3); 1437 BCM_IF_ERROR_RETURN(BCMX_L3_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 1438 } 1439 1440 return rv; 1441 } 1442 1443 /* 1444 * Function: 1445 * bcmx_l3_host_delete 1446 */ 1447 1448 int 1449 bcmx_l3_host_delete(bcmx_l3_host_t *ip_addr) 1450 { 1451 int rv = BCM_E_UNAVAIL, tmp_rv; 1452 int i, bcm_unit; 1453 bcm_l3_host_t bcm_l3; 1454 1455 BCMX_L3_INIT_CHECK; 1456 1457 BCMX_PARAM_NULL_CHECK(ip_addr); 1458 1459 BCM_IF_ERROR_RETURN(_bcmx_l3ip_to_bcm(ip_addr, &bcm_l3, FALSE)); 1460 1461 BCMX_UNIT_ITER(bcm_unit, i) { 1462 tmp_rv = bcm_l3_host_delete(bcm_unit, &bcm_l3); 1463 BCM_IF_ERROR_RETURN(BCMX_L3_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 1464 } 1465 1466 return rv; 1467 } 1468 1469 /* 1470 * Function: 1471 * bcmx_l3_host_delete_by_network 1472 */ 1473 1474 int 1475 bcmx_l3_host_delete_by_network(bcmx_l3_route_t *route) 1476 { 1477 int rv = BCM_E_UNAVAIL, tmp_rv; 1478 int i, bcm_unit; 1479 bcm_l3_route_t l3_route; 1480 1481 BCMX_L3_INIT_CHECK; 1482 1483 BCMX_PARAM_NULL_CHECK(route); 1484 1485 BCM_IF_ERROR_RETURN(_bcmx_l3route_to_bcm(route, &l3_route, FALSE)); 1486 1487 BCMX_UNIT_ITER(bcm_unit, i) { 1488 tmp_rv = bcm_l3_host_delete_by_network(bcm_unit, &l3_route); 1489 BCM_IF_ERROR_RETURN(BCMX_L3_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 1490 } 1491 1492 return rv; 1493 } 1494 1495 /* 1496 * Function: 1497 * bcmx_l3_host_delete_by_interface 1498 */ 1499 1500 int 1501 bcmx_l3_host_delete_by_interface(bcmx_l3_host_t *info) 1502 { 1503 int rv = BCM_E_UNAVAIL, tmp_rv; 1504 int i, bcm_unit; 1505 bcm_l3_host_t bcm_l3; 1506 1507 BCMX_L3_INIT_CHECK; 1508 1509 BCMX_PARAM_NULL_CHECK(info); 1510 1511 BCM_IF_ERROR_RETURN(_bcmx_l3ip_to_bcm(info, &bcm_l3, FALSE)); 1512 1513 BCMX_UNIT_ITER(bcm_unit, i) { 1514 tmp_rv = bcm_l3_host_delete_by_interface(bcm_unit, &bcm_l3); 1515 BCM_IF_ERROR_RETURN(BCMX_L3_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 1516 } 1517 1518 return rv; 1519 } 1520 1521 /* 1522 * Function: 1523 * bcmx_l3_host_delete_all 1524 */ 1525 1526 int 1527 bcmx_l3_host_delete_all(bcmx_l3_host_t *info) 1528 { 1529 int rv = BCM_E_UNAVAIL, tmp_rv; 1530 int i, bcm_unit; 1531 bcm_l3_host_t bcm_l3; 1532 1533 BCMX_L3_INIT_CHECK; 1534 1535 BCMX_PARAM_NULL_CHECK(info); 1536 1537 BCM_IF_ERROR_RETURN(_bcmx_l3ip_to_bcm(info, &bcm_l3, FALSE)); 1538 1539 BCMX_UNIT_ITER(bcm_unit, i) { 1540 tmp_rv = bcm_l3_host_delete_all(bcm_unit, &bcm_l3); 1541 BCM_IF_ERROR_RETURN(BCMX_L3_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 1542 } 1543 1544 return rv; 1545 } 1546 1547 /* 1548 * Function: 1549 * bcmx_l3_host_conflict_get 1550 */ 1551 1552 int 1553 bcmx_l3_host_conflict_get(bcm_l3_key_t *ipkey, 1554 bcm_l3_key_t *cf_array, 1555 int cf_max, 1556 int *cf_count) 1557 { 1558 int rv; 1559 int i, bcm_unit; 1560 1561 BCMX_L3_INIT_CHECK; 1562 1563 BCMX_PARAM_NULL_CHECK(ipkey); 1564 BCMX_PARAM_NULL_CHECK(cf_count); 1565 BCMX_PARAM_ARRAY_NULL_CHECK(cf_max, cf_array); 1566 1567 BCMX_UNIT_ITER(bcm_unit, i) { 1568 rv = bcm_l3_host_conflict_get(bcm_unit, ipkey, 1569 cf_array, cf_max, cf_count); 1570 if (BCMX_L3_GET_IS_VALID(bcm_unit, rv)) { 1571 return rv; 1572 } 1573 } 1574 1575 return BCM_E_UNAVAIL; 1576 } 1577 1578 /* 1579 * Function: 1580 * bcmx_l3_host_age 1581 */ 1582 1583 int 1584 bcmx_l3_host_age(uint32 flags, 1585 bcm_l3_host_traverse_cb age_cb, 1586 void *user_data) 1587 { 1588 return BCM_E_UNAVAIL; 1589 } 1590 1591 /* 1592 * Function: 1593 * bcmx_l3_host_traverse 1594 */ 1595 1596 int 1597 bcmx_l3_host_traverse(uint32 flags, 1598 uint32 start, 1599 uint32 end, 1600 bcm_l3_host_traverse_cb cb, 1601 void *user_data) 1602 { 1603 int rv; 1604 int i, bcm_unit; 1605 1606 BCMX_L3_INIT_CHECK; 1607 1608 BCMX_LOCAL_UNIT_ITER(bcm_unit, i) { 1609 rv = bcm_l3_host_traverse(bcm_unit, 1610 flags, start, end, 1611 cb, user_data); 1612 if (BCMX_L3_GET_IS_VALID(bcm_unit, rv)) { 1613 return rv; 1614 } 1615 } 1616 1617 return BCM_E_UNAVAIL; 1618 } 1619 1620 /* 1621 * Function: 1622 * bcmx_l3_host_invalidate_entry 1623 */ 1624 1625 int 1626 bcmx_l3_host_invalidate_entry(bcm_ip_t info) 1627 { 1628 int rv = BCM_E_UNAVAIL, tmp_rv; 1629 int i, bcm_unit; 1630 1631 BCMX_L3_INIT_CHECK; 1632 1633 BCMX_UNIT_ITER(bcm_unit, i) { 1634 tmp_rv = bcm_l3_host_invalidate_entry(bcm_unit, info); 1635 BCM_IF_ERROR_RETURN(BCMX_L3_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 1636 } 1637 1638 return rv; 1639 } 1640 1641 /* 1642 * Function: 1643 * bcmx_l3_host_validate_entry 1644 */ 1645 1646 int 1647 bcmx_l3_host_validate_entry(bcm_ip_t info) 1648 { 1649 int rv = BCM_E_UNAVAIL, tmp_rv; 1650 int i, bcm_unit; 1651 1652 BCMX_L3_INIT_CHECK; 1653 1654 BCMX_UNIT_ITER(bcm_unit, i) { 1655 tmp_rv = bcm_l3_host_validate_entry(bcm_unit, info); 1656 BCM_IF_ERROR_RETURN(BCMX_L3_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 1657 } 1658 1659 return rv; 1660 } 1661 1662 /************************************************************** 1663 * bcmx_l3_route_xxx 1664 */ 1665 1666 /* 1667 * Function: 1668 * bcmx_l3_route_add 1669 */ 1670 1671 int 1672 bcmx_l3_route_add(bcmx_l3_route_t *info) 1673 { 1674 int rv = BCM_E_UNAVAIL, tmp_rv; 1675 int i, bcm_unit; 1676 bcm_l3_route_t l3_route; 1677 int map_local_cpu; /* Is local CPU port mapping required? */ 1678 bcmx_lport_t cpu_lport; 1679 1680 BCMX_L3_INIT_CHECK; 1681 1682 BCMX_PARAM_NULL_CHECK(info); 1683 1684 map_local_cpu = ((!(info->l3a_flags & BCM_L3_TGID)) && 1685 (info->l3a_lport == BCMX_LPORT_LOCAL_CPU)); 1686 1687 BCM_IF_ERROR_RETURN(_bcmx_l3route_to_bcm(info, &l3_route, TRUE)); 1688 1689 BCMX_UNIT_ITER(bcm_unit, i) { 1690 if (map_local_cpu) { 1691 cpu_lport = BCMX_LPORT_LOCAL_CPU_GET(bcm_unit); 1692 if (BCM_FAILURE 1693 (_bcmx_dest_to_modid_port(cpu_lport, 1694 &l3_route.l3a_modid, 1695 &l3_route.l3a_port_tgid, 1696 BCMX_DEST_CONVERT_DEFAULT))) { 1697 /* Skip if can't find local CPU port */ 1698 continue; 1699 } 1700 } 1701 tmp_rv = bcm_l3_route_add(bcm_unit, &l3_route); 1702 BCM_IF_ERROR_RETURN(BCMX_L3_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 1703 } 1704 1705 return rv; 1706 } 1707 1708 /* 1709 * Function: 1710 * bcmx_l3_route_delete 1711 */ 1712 1713 int 1714 bcmx_l3_route_delete(bcmx_l3_route_t *info) 1715 { 1716 int rv = BCM_E_UNAVAIL, tmp_rv; 1717 int i, bcm_unit; 1718 bcm_l3_route_t l3_route; 1719 1720 BCMX_L3_INIT_CHECK; 1721 1722 BCMX_PARAM_NULL_CHECK(info); 1723 1724 /* See bcm_l3_route_delete() 1725 l3a_port_tgid is an input field if BCM_L3_MULTIPATH 1726 is set. */ 1727 BCM_IF_ERROR_RETURN 1728 (_bcmx_l3route_to_bcm(info, &l3_route, 1729 info->l3a_flags & BCM_L3_MULTIPATH)); 1730 1731 BCMX_UNIT_ITER(bcm_unit, i) { 1732 tmp_rv = bcm_l3_route_delete(bcm_unit, &l3_route); 1733 BCM_IF_ERROR_RETURN(BCMX_L3_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 1734 } 1735 1736 return rv; 1737 } 1738 1739 /* 1740 * Function: 1741 * bcmx_l3_route_delete_by_interface 1742 */ 1743 1744 int 1745 bcmx_l3_route_delete_by_interface(bcmx_l3_route_t *info) 1746 { 1747 int rv = BCM_E_UNAVAIL, tmp_rv; 1748 int i, bcm_unit; 1749 bcm_l3_route_t l3_route; 1750 1751 BCMX_L3_INIT_CHECK; 1752 1753 BCMX_PARAM_NULL_CHECK(info); 1754 1755 BCM_IF_ERROR_RETURN(_bcmx_l3route_to_bcm(info, &l3_route, FALSE)); 1756 1757 BCMX_UNIT_ITER(bcm_unit, i) { 1758 tmp_rv = bcm_l3_route_delete_by_interface(bcm_unit, &l3_route); 1759 BCM_IF_ERROR_RETURN(BCMX_L3_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 1760 } 1761 1762 return rv; 1763 } 1764 1765 /* 1766 * Function: 1767 * bcmx_l3_route_delete_all 1768 */ 1769 1770 int 1771 bcmx_l3_route_delete_all(bcmx_l3_route_t *info) 1772 { 1773 int rv = BCM_E_UNAVAIL, tmp_rv; 1774 int i, bcm_unit; 1775 bcm_l3_route_t l3_route; 1776 1777 BCMX_L3_INIT_CHECK; 1778 1779 BCMX_PARAM_NULL_CHECK(info); 1780 1781 BCM_IF_ERROR_RETURN(_bcmx_l3route_to_bcm(info, &l3_route, FALSE)); 1782 1783 BCMX_UNIT_ITER(bcm_unit, i) { 1784 tmp_rv = bcm_l3_route_delete_all(bcm_unit, &l3_route); 1785 BCM_IF_ERROR_RETURN(BCMX_L3_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 1786 } 1787 1788 return rv; 1789 } 1790 1791 /* 1792 * Function: 1793 * bcmx_l3_route_get 1794 */ 1795 1796 int 1797 bcmx_l3_route_get(bcmx_l3_route_t *info) 1798 { 1799 int rv = BCM_E_UNAVAIL, tmp_rv; 1800 int i, bcm_unit; 1801 bcm_l3_route_t l3_route; 1802 uint32 merged_flags = 0; 1803 1804 BCMX_L3_INIT_CHECK; 1805 1806 BCMX_PARAM_NULL_CHECK(info); 1807 1808 BCM_IF_ERROR_RETURN(_bcmx_l3route_to_bcm(info, &l3_route, FALSE)); 1809 1810 BCMX_UNIT_ITER(bcm_unit, i) { 1811 tmp_rv = bcm_l3_route_get(bcm_unit, &l3_route); 1812 if (BCMX_L3_GET_IS_VALID(bcm_unit, tmp_rv)) { 1813 rv = tmp_rv; 1814 if (BCM_SUCCESS(tmp_rv)) { 1815 merged_flags |= l3_route.l3a_flags; 1816 } else { 1817 break; 1818 } 1819 } 1820 /* bcm_l3_route_get() may overwrite input flags */ 1821 l3_route.l3a_flags = info->l3a_flags; 1822 } 1823 1824 if (BCM_SUCCESS(rv)) { 1825 l3_route.l3a_flags |= merged_flags; 1826 BCM_IF_ERROR_RETURN(_bcmx_l3route_from_bcm(info, &l3_route)); 1827 } 1828 1829 return rv; 1830 } 1831 1832 /* 1833 * Function: 1834 * bcmx_l3_route_multipath_get 1835 */ 1836 1837 int 1838 bcmx_l3_route_multipath_get(bcmx_l3_route_t *the_route, 1839 bcmx_l3_route_t *path_array, 1840 int max_path, 1841 int *path_count) 1842 { 1843 int rv = BCM_E_UNAVAIL, tmp_rv; 1844 int i, bcm_unit; 1845 bcm_l3_route_t l3_route, *l3_route_array, *l3p; 1846 int num_bcm_path = 0; 1847 1848 BCMX_L3_INIT_CHECK; 1849 1850 BCMX_PARAM_NULL_CHECK(the_route); 1851 BCMX_PARAM_NULL_CHECK(path_count); 1852 BCMX_PARAM_ARRAY_NULL_CHECK(max_path, path_array); 1853 1854 BCM_IF_ERROR_RETURN(_bcmx_l3route_to_bcm(the_route, &l3_route, FALSE)); 1855 1856 l3_route_array = sal_alloc(sizeof(bcm_l3_route_t) * max_path, 1857 "BCMX_L3_RGAP"); 1858 if (l3_route_array == NULL) { 1859 return BCM_E_MEMORY; 1860 } 1861 1862 /* Init route array structs */ 1863 for (i=0; i<max_path; i++ ) { 1864 bcm_l3_route_t_init(l3_route_array + i); 1865 } 1866 1867 l3p = l3_route_array; 1868 1869 BCMX_UNIT_ITER(bcm_unit, i) { 1870 tmp_rv = bcm_l3_route_multipath_get(bcm_unit, &l3_route, 1871 l3p, 1872 max_path, 1873 &num_bcm_path); 1874 if (BCMX_L3_GET_IS_VALID(bcm_unit, tmp_rv)) { 1875 rv = tmp_rv; 1876 break; 1877 } 1878 } 1879 1880 if (BCM_SUCCESS(rv)) { 1881 /* Convert bcm routes to bcmx */ 1882 for (i=0, l3p=l3_route_array; i<num_bcm_path; i++) { 1883 rv = _bcmx_l3route_from_bcm(path_array+i, l3p+i); 1884 } 1885 } else { 1886 num_bcm_path = 0; 1887 } 1888 1889 *path_count = num_bcm_path; 1890 sal_free(l3_route_array); 1891 1892 return rv; 1893 } 1894 1895 /* 1896 * Function: 1897 * bcmx_l3_route_age 1898 */ 1899 1900 int 1901 bcmx_l3_route_age(uint32 flags, 1902 bcm_l3_route_traverse_cb age_out, 1903 void *user_data) 1904 { 1905 return BCM_E_UNAVAIL; 1906 } 1907 1908 /* 1909 * Function: 1910 * bcmx_l3_route_traverse 1911 */ 1912 1913 int 1914 bcmx_l3_route_traverse(uint32 flags, 1915 uint32 start, 1916 uint32 end, 1917 bcm_l3_route_traverse_cb trav_fn, 1918 void *user_data) 1919 { 1920 int rv; 1921 int i, bcm_unit; 1922 1923 BCMX_L3_INIT_CHECK; 1924 1925 BCMX_LOCAL_UNIT_ITER(bcm_unit, i) { 1926 rv = bcm_l3_route_traverse(bcm_unit, 1927 flags, start, end, 1928 trav_fn, user_data); 1929 if (BCMX_L3_GET_IS_VALID(bcm_unit, rv)) { 1930 return rv; 1931 } 1932 } 1933 1934 return BCM_E_UNAVAIL; 1935 } 1936 1937 /* 1938 * Function: 1939 * bcmx_l3_route_max_ecmp_set 1940 */ 1941 1942 int 1943 bcmx_l3_route_max_ecmp_set(int max) 1944 { 1945 int rv = BCM_E_UNAVAIL, tmp_rv; 1946 int i, bcm_unit; 1947 1948 BCMX_L3_INIT_CHECK; 1949 1950 BCMX_UNIT_ITER(bcm_unit, i) { 1951 tmp_rv = bcm_l3_route_max_ecmp_set(bcm_unit, max); 1952 BCM_IF_ERROR_RETURN(BCMX_L3_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 1953 } 1954 1955 return rv; 1956 } 1957 1958 /* 1959 * Function: 1960 * bcmx_l3_route_max_ecmp_get 1961 */ 1962 1963 int 1964 bcmx_l3_route_max_ecmp_get(int *max) 1965 { 1966 int rv = BCM_E_UNAVAIL, tmp_rv; 1967 int i, bcm_unit; 1968 int tmp_max; 1969 1970 BCMX_L3_INIT_CHECK; 1971 1972 BCMX_PARAM_NULL_CHECK(max); 1973 1974 /* Get the minimum value of all units */ 1975 *max = 0; 1976 BCMX_UNIT_ITER(bcm_unit, i) { 1977 tmp_rv = bcm_l3_route_max_ecmp_get(bcm_unit, &tmp_max); 1978 1979 if (BCMX_L3_GET_IS_VALID(bcm_unit, tmp_rv)) { 1980 rv = tmp_rv; 1981 BCM_IF_ERROR_RETURN(rv); 1982 if ((*max == 0) || (tmp_max < *max)) { 1983 *max = tmp_max; 1984 } 1985 } 1986 } 1987 1988 return rv; 1989 } 1990 1991 /************************************************************** 1992 * bcmx_l3_defip_xxx (superseded by bcmx_l3_route_xxx) 1993 */ 1994 1995 1996 /* 1997 * Function: 1998 * bcmx_l3_vrf_stat_enable_set 1999 * Purpose: 2000 * Enable/disable packet and byte counters for the selected VRF. 2001 * Parameters: 2002 * vrf - Virtual router instance 2003 * enable - Non-zero to enable counter collection, zero to disable 2004 * Returns: 2005 * BCM_E_XXX 2006 * Notes: 2007 */ 2008 int 2009 bcmx_l3_vrf_stat_enable_set(bcm_vrf_t vrf, int enable) 2010 { 2011 int rv = BCM_E_UNAVAIL, tmp_rv; 2012 int i, bcm_unit; 2013 2014 BCMX_L3_INIT_CHECK; 2015 2016 BCMX_UNIT_ITER(bcm_unit, i) { 2017 tmp_rv = bcm_l3_vrf_stat_enable_set(bcm_unit, vrf, enable); 2018 BCM_IF_ERROR_RETURN(BCMX_L3_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 2019 } 2020 2021 return rv; 2022 } 2023 2024 /* 2025 * Function: 2026 * bcmx_l3_vrf_stat_get 2027 * Purpose: 2028 * Get 64-bit counter value for specified VRF statistic type. 2029 * Parameters: 2030 * vrf - Virtual router instance 2031 * stat - Type of the counter to retrieve 2032 * val - (OUT) Pointer to a counter value 2033 * Returns: 2034 * BCM_E_XXX 2035 * Notes: 2036 */ 2037 int 2038 bcmx_l3_vrf_stat_get(bcm_vrf_t vrf, bcm_l3_vrf_stat_t stat, uint64 *val) 2039 { 2040 int rv = BCM_E_UNAVAIL, tmp_rv; 2041 int i, bcm_unit; 2042 uint64 tmp_val; 2043 2044 BCMX_L3_INIT_CHECK; 2045 2046 BCMX_PARAM_NULL_CHECK(val); 2047 2048 COMPILER_64_ZERO(*val); 2049 BCMX_UNIT_ITER(bcm_unit, i) { 2050 tmp_rv = bcm_l3_vrf_stat_get(bcm_unit, vrf, stat, &tmp_val); 2051 2052 if (BCMX_L3_GET_IS_VALID(bcm_unit, tmp_rv)) { 2053 rv = tmp_rv; 2054 if (BCM_SUCCESS(tmp_rv)) { 2055 COMPILER_64_ADD_64(*val, tmp_val); 2056 } else { 2057 break; 2058 } 2059 } 2060 } 2061 2062 return rv; 2063 } 2064 2065 /* 2066 * Function: 2067 * bcmx_l3_vrf_stat_get32 2068 * Purpose: 2069 * Get lower 32-bit counter value for specified VRF statistic 2070 * type. 2071 * Parameters: 2072 * vrf - Virtual router instance 2073 * stat - Type of the counter to retrieve 2074 * val - (OUT) Pointer to a counter value 2075 * Returns: 2076 * BCM_E_XXX 2077 * Notes: 2078 */ 2079 int 2080 bcmx_l3_vrf_stat_get32(bcm_vrf_t vrf, bcm_l3_vrf_stat_t stat, uint32 *val) 2081 { 2082 int rv = BCM_E_UNAVAIL, tmp_rv; 2083 int i, bcm_unit; 2084 uint32 tmp_val; 2085 2086 BCMX_L3_INIT_CHECK; 2087 2088 BCMX_PARAM_NULL_CHECK(val); 2089 2090 *val = 0; 2091 BCMX_UNIT_ITER(bcm_unit, i) { 2092 tmp_rv = bcm_l3_vrf_stat_get32(bcm_unit, vrf, stat, &tmp_val); 2093 2094 if (BCMX_L3_GET_IS_VALID(bcm_unit, tmp_rv)) { 2095 rv = tmp_rv; 2096 if (BCM_SUCCESS(tmp_rv)) { 2097 *val += tmp_val; 2098 } else { 2099 break; 2100 } 2101 } 2102 } 2103 2104 return rv; 2105 } 2106 2107 /* 2108 * Function: 2109 * bcmx_l3_vrf_stat_set 2110 * Purpose: 2111 * Set 64-bit counter value for specified VRF statistic type. 2112 * Parameters: 2113 * vrf - Virtual router instance 2114 * stat - Type of the counter to set 2115 * val - New counter value 2116 * Returns: 2117 * BCM_E_XXX 2118 * Notes: 2119 */ 2120 int 2121 bcmx_l3_vrf_stat_set(bcm_vrf_t vrf, bcm_l3_vrf_stat_t stat, uint64 val) 2122 { 2123 int rv = BCM_E_UNAVAIL, tmp_rv; 2124 int i, bcm_unit; 2125 2126 BCMX_L3_INIT_CHECK; 2127 2128 BCMX_UNIT_ITER(bcm_unit, i) { 2129 tmp_rv = bcm_l3_vrf_stat_set(bcm_unit, vrf, stat, val); 2130 BCM_IF_ERROR_RETURN(BCMX_L3_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 2131 } 2132 2133 return rv; 2134 } 2135 2136 /* 2137 * Function: 2138 * bcmx_l3_vrf_stat_set32 2139 * Purpose: 2140 * Set 32-bit counter value for specified VRF statistic type. 2141 * Parameters: 2142 * vrf - Virtual router instance 2143 * stat - Type of the counter to set 2144 * val - New counter value 2145 * Returns: 2146 * BCM_E_XXX 2147 * Notes: 2148 */ 2149 int 2150 bcmx_l3_vrf_stat_set32(bcm_vrf_t vrf, bcm_l3_vrf_stat_t stat, uint32 val) 2151 { 2152 int rv = BCM_E_UNAVAIL, tmp_rv; 2153 int i, bcm_unit; 2154 2155 BCMX_L3_INIT_CHECK; 2156 2157 BCMX_UNIT_ITER(bcm_unit, i) { 2158 tmp_rv = bcm_l3_vrf_stat_set32(bcm_unit, vrf, stat, val); 2159 BCM_IF_ERROR_RETURN(BCMX_L3_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 2160 } 2161 2162 return rv; 2163 } 2164 2165 /* 2166 * Function: 2167 * bcmx_l3_vrf_stat_multi_get 2168 * Purpose: 2169 * Get 64-bit counter value for multiple VRF statistic types. 2170 * Parameters: 2171 * vrf - Virtual router instance 2172 * nstat - Number of elements in stat array 2173 * stat_arr - Collected statistics descriptors array 2174 * value_arr - (OUT) Collected counters values 2175 * Returns: 2176 * BCM_E_XXX 2177 * Notes: 2178 */ 2179 int 2180 bcmx_l3_vrf_stat_multi_get(bcm_vrf_t vrf, int nstat, 2181 bcm_l3_vrf_stat_t *stat_arr, uint64 *value_arr) 2182 { 2183 int rv = BCM_E_UNAVAIL, tmp_rv; 2184 int i, bcm_unit; 2185 uint64 *tmp_val; 2186 2187 BCMX_L3_INIT_CHECK; 2188 2189 BCMX_PARAM_ARRAY_NULL_CHECK(nstat, stat_arr); 2190 BCMX_PARAM_ARRAY_NULL_CHECK(nstat, value_arr); 2191 2192 tmp_val = sal_alloc(sizeof(uint64) * nstat, "bcmx l3 vrf stat"); 2193 if (tmp_val == NULL) { 2194 return BCM_E_MEMORY; 2195 } 2196 2197 for (i = 0; i < nstat; i++) { 2198 COMPILER_64_ZERO(value_arr[i]); 2199 } 2200 BCMX_UNIT_ITER(bcm_unit, i) { 2201 tmp_rv = bcm_l3_vrf_stat_multi_get(bcm_unit, vrf, nstat, 2202 stat_arr, tmp_val); 2203 if (BCMX_L3_GET_IS_VALID(bcm_unit, tmp_rv)) { 2204 rv = tmp_rv; 2205 if (BCM_SUCCESS(tmp_rv)) { 2206 for (i = 0; i < nstat; i++) { 2207 COMPILER_64_ADD_64(value_arr[i], tmp_val[i]); 2208 } 2209 } else { 2210 break; 2211 } 2212 } 2213 } 2214 2215 sal_free(tmp_val); 2216 2217 return rv; 2218 } 2219 2220 /* 2221 * Function: 2222 * bcmx_l3_vrf_stat_multi_get32 2223 * Purpose: 2224 * Get lower 32-bit counter value for multiple VRF statistic types. 2225 * Parameters: 2226 * vrf - Virtual router instance 2227 * nstat - Number of elements in stat array 2228 * stat_arr - Collected statistics descriptors array 2229 * value_arr - (OUT) Collected counters values 2230 * Returns: 2231 * BCM_E_XXX 2232 * Notes: 2233 */ 2234 int 2235 bcmx_l3_vrf_stat_multi_get32(bcm_vrf_t vrf, int nstat, 2236 bcm_l3_vrf_stat_t *stat_arr, uint32 *value_arr) 2237 { 2238 int rv = BCM_E_UNAVAIL, tmp_rv; 2239 int i, bcm_unit; 2240 uint32 *tmp_val; 2241 2242 BCMX_L3_INIT_CHECK; 2243 2244 BCMX_PARAM_ARRAY_NULL_CHECK(nstat, stat_arr); 2245 BCMX_PARAM_ARRAY_NULL_CHECK(nstat, value_arr); 2246 2247 tmp_val = sal_alloc(sizeof(uint32) * nstat, "bcmx l3 vrf stat"); 2248 if (tmp_val == NULL) { 2249 return BCM_E_MEMORY; 2250 } 2251 2252 for (i = 0; i < nstat; i++) { 2253 value_arr[i] = 0; 2254 } 2255 BCMX_UNIT_ITER(bcm_unit, i) { 2256 tmp_rv = bcm_l3_vrf_stat_multi_get32(bcm_unit, vrf, nstat, 2257 stat_arr, tmp_val); 2258 if (BCMX_L3_GET_IS_VALID(bcm_unit, tmp_rv)) { 2259 rv = tmp_rv; 2260 if (BCM_SUCCESS(tmp_rv)) { 2261 for (i = 0; i < nstat; i++) { 2262 value_arr[i] += tmp_val[i]; 2263 } 2264 } else { 2265 break; 2266 } 2267 } 2268 } 2269 2270 sal_free(tmp_val); 2271 2272 return rv; 2273 } 2274 2275 /* 2276 * Function: 2277 * bcmx_l3_vrf_stat_multi_set 2278 * Purpose: 2279 * Set 64-bit counter value for multiple VRF statistic types. 2280 * Parameters: 2281 * vrf - Virtual router instance 2282 * nstat - Number of elements in stat array 2283 * stat_arr - New statistics descriptors array 2284 * value_arr - New counters values to set 2285 * Returns: 2286 * BCM_E_XXX 2287 * Notes: 2288 */ 2289 int 2290 bcmx_l3_vrf_stat_multi_set(bcm_vrf_t vrf, int nstat, 2291 bcm_l3_vrf_stat_t *stat_arr, uint64 *value_arr) 2292 { 2293 int rv = BCM_E_UNAVAIL, tmp_rv; 2294 int i, bcm_unit; 2295 2296 BCMX_L3_INIT_CHECK; 2297 2298 BCMX_PARAM_ARRAY_NULL_CHECK(nstat, stat_arr); 2299 BCMX_PARAM_ARRAY_NULL_CHECK(nstat, value_arr); 2300 2301 BCMX_UNIT_ITER(bcm_unit, i) { 2302 tmp_rv = bcm_l3_vrf_stat_multi_set(bcm_unit, vrf, nstat, 2303 stat_arr, value_arr); 2304 BCM_IF_ERROR_RETURN(BCMX_L3_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 2305 } 2306 2307 return rv; 2308 } 2309 2310 /* 2311 * Function: 2312 * bcmx_l3_vrf_stat_multi_set32 2313 * Purpose: 2314 * Set lower 32-bit counter value for multiple VRF statistic types. 2315 * Parameters: 2316 * vrf - Virtual router instance 2317 * nstat - Number of elements in stat array 2318 * stat_arr - New statistics descriptors array 2319 * value_arr - New counters values to set 2320 * Returns: 2321 * BCM_E_XXX 2322 * Notes: 2323 */ 2324 int 2325 bcmx_l3_vrf_stat_multi_set32(bcm_vrf_t vrf, int nstat, 2326 bcm_l3_vrf_stat_t *stat_arr, uint32 *value_arr) 2327 { 2328 int rv = BCM_E_UNAVAIL, tmp_rv; 2329 int i, bcm_unit; 2330 2331 BCMX_L3_INIT_CHECK; 2332 2333 BCMX_PARAM_ARRAY_NULL_CHECK(nstat, stat_arr); 2334 BCMX_PARAM_ARRAY_NULL_CHECK(nstat, value_arr); 2335 2336 BCMX_UNIT_ITER(bcm_unit, i) { 2337 tmp_rv = bcm_l3_vrf_stat_multi_set32(bcm_unit, vrf, nstat, 2338 stat_arr, value_arr); 2339 BCM_IF_ERROR_RETURN(BCMX_L3_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 2340 } 2341 2342 return rv; 2343 } 2344 2345 2346 /* 2347 * Function: 2348 * bcmx_l3_source_bind_enable_set 2349 * Purpose: 2350 * Enable or disable l3 source binding checks on an ingress port. 2351 * Parameters: 2352 * port - Packet ingress logical port 2353 * enable - Non-zero to enable l3 source binding checks, 2354 * zero to disable. 2355 * Returns: 2356 * BCM_E_XXX 2357 * Notes: 2358 */ 2359 int 2360 bcmx_l3_source_bind_enable_set(bcm_gport_t port, int enable) 2361 { 2362 int bcm_unit; 2363 bcm_port_t bcm_port; 2364 2365 BCMX_L3_INIT_CHECK; 2366 2367 BCM_IF_ERROR_RETURN 2368 (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port, 2369 BCMX_DEST_CONVERT_DEFAULT)); 2370 2371 return bcm_l3_source_bind_enable_set(bcm_unit, port, enable); 2372 } 2373 2374 /* 2375 * Function: 2376 * bcmx_l3_source_bind_enable_get 2377 * Purpose: 2378 * Retrieve whether l3 source binding checks are performed on an 2379 * ingress port. 2380 * Parameters: 2381 * port - Packet ingress port. 2382 * enable - (OUT) Non-zero if l3 source binding checks are enabled, 2383 * zero if disabled. 2384 * Returns: 2385 * BCM_E_XXX 2386 * Notes: 2387 */ 2388 int 2389 bcmx_l3_source_bind_enable_get(bcm_gport_t port, int *enable) 2390 { 2391 int bcm_unit; 2392 bcm_port_t bcm_port; 2393 2394 BCMX_L3_INIT_CHECK; 2395 2396 BCMX_PARAM_NULL_CHECK(enable); 2397 2398 BCM_IF_ERROR_RETURN 2399 (_bcmx_dest_to_unit_port(port, &bcm_unit, &bcm_port, 2400 BCMX_DEST_CONVERT_DEFAULT)); 2401 2402 return bcm_l3_source_bind_enable_get(bcm_unit, port, enable); 2403 } 2404 2405 /* 2406 * Function: 2407 * bcmx_l3_source_bind_add 2408 * Purpose: 2409 * Add or replace an L3 source binding. 2410 * Parameters: 2411 * info - L3 source binding information 2412 * Returns: 2413 * BCM_E_XXX 2414 * Notes: 2415 */ 2416 int 2417 bcmx_l3_source_bind_add(bcmx_l3_source_bind_t *info) 2418 { 2419 int rv = BCM_E_UNAVAIL, tmp_rv; 2420 int i, bcm_unit; 2421 2422 BCMX_L3_INIT_CHECK; 2423 2424 BCMX_PARAM_NULL_CHECK(info); 2425 2426 BCMX_UNIT_ITER(bcm_unit, i) { 2427 tmp_rv = bcm_l3_source_bind_add(bcm_unit, info); 2428 BCM_IF_ERROR_RETURN(BCMX_L3_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 2429 } 2430 2431 return rv; 2432 } 2433 2434 /* 2435 * Function: 2436 * bcmx_l3_source_bind_delete 2437 * Purpose: 2438 * Remove an existing L3 source binding. 2439 * Parameters: 2440 * info - L3 source binding information 2441 * Returns: 2442 * BCM_E_XXX 2443 * Notes: 2444 */ 2445 int 2446 bcmx_l3_source_bind_delete(bcmx_l3_source_bind_t *info) 2447 { 2448 int rv = BCM_E_UNAVAIL, tmp_rv; 2449 int i, bcm_unit; 2450 2451 BCMX_L3_INIT_CHECK; 2452 2453 BCMX_PARAM_NULL_CHECK(info); 2454 2455 BCMX_UNIT_ITER(bcm_unit, i) { 2456 tmp_rv = bcm_l3_source_bind_delete(bcm_unit, info); 2457 BCM_IF_ERROR_RETURN(BCMX_L3_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 2458 } 2459 2460 return rv; 2461 } 2462 2463 /* 2464 * Function: 2465 * bcmx_l3_source_bind_delete_all 2466 * Purpose: 2467 * Remove all existing L3 source bindings. 2468 * Parameters: 2469 * none 2470 * Returns: 2471 * BCM_E_XXX 2472 * Notes: 2473 */ 2474 int 2475 bcmx_l3_source_bind_delete_all(void) 2476 { 2477 int rv = BCM_E_UNAVAIL, tmp_rv; 2478 int i, bcm_unit; 2479 2480 BCMX_L3_INIT_CHECK; 2481 2482 BCMX_UNIT_ITER(bcm_unit, i) { 2483 tmp_rv = bcm_l3_source_bind_delete_all(bcm_unit); 2484 BCM_IF_ERROR_RETURN(BCMX_L3_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 2485 } 2486 2487 return rv; 2488 } 2489 2490 /* 2491 * Function: 2492 * bcmx_l3_source_bind_get 2493 * Purpose: 2494 * Retrieve the details of an existing L3 source binding. 2495 * Parameters: 2496 * info - (IN/OUT) L3 source binding information 2497 * Returns: 2498 * BCM_E_XXX 2499 * Notes: 2500 * Returns data from first successful call. 2501 */ 2502 int 2503 bcmx_l3_source_bind_get(bcmx_l3_source_bind_t *info) 2504 { 2505 int rv; 2506 int i, bcm_unit; 2507 2508 BCMX_L3_INIT_CHECK; 2509 2510 BCMX_PARAM_NULL_CHECK(info); 2511 2512 BCMX_UNIT_ITER(bcm_unit, i) { 2513 rv = bcm_l3_source_bind_get(bcm_unit, 2514 BCMX_L3_SOURCE_BIND_T_PTR_TO_BCM(info)); 2515 if (BCMX_L3_GET_IS_VALID(bcm_unit, rv)) { 2516 return rv; 2517 } 2518 } 2519 2520 return BCM_E_UNAVAIL; 2521 } 2522 2523 /* 2524 * Function: 2525 * bcmx_l3_vrrp_add 2526 * Purpose: 2527 * Add VRID for the given VSI. Adding a VRID using this API means 2528 * the physical node has become the master for the virtual router. 2529 * Parameters: 2530 * vlan - VLAN/VSI 2531 * vrid - VRID Virtual router ID to be added 2532 * Returns: 2533 * BCM_E_XXX 2534 */ 2535 int 2536 bcmx_l3_vrrp_add(bcm_vlan_t vlan, uint32 vrid) 2537 { 2538 int rv = BCM_E_UNAVAIL, tmp_rv; 2539 int i, bcm_unit; 2540 2541 BCMX_L3_INIT_CHECK; 2542 2543 BCMX_UNIT_ITER(bcm_unit, i) { 2544 tmp_rv = bcm_l3_vrrp_add(bcm_unit, vlan, vrid); 2545 BCM_IF_ERROR_RETURN(BCMX_L3_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 2546 } 2547 2548 return rv; 2549 } 2550 2551 /* 2552 * Function: 2553 * bcmx_l3_vrrp_delete 2554 * Purpose: 2555 * Delete VRID for a particulat VLAN/VSI. 2556 * Parameters: 2557 * vlan - VLAN/VSI 2558 * vrid - VRID Virtual router ID to be deleted 2559 * Returns: 2560 * BCM_E_XXX 2561 */ 2562 int 2563 bcmx_l3_vrrp_delete(bcm_vlan_t vlan, uint32 vrid) 2564 { 2565 int rv = BCM_E_UNAVAIL, tmp_rv; 2566 int i, bcm_unit; 2567 2568 BCMX_L3_INIT_CHECK; 2569 2570 BCMX_UNIT_ITER(bcm_unit, i) { 2571 tmp_rv = bcm_l3_vrrp_delete(bcm_unit, vlan, vrid); 2572 BCM_IF_ERROR_RETURN(BCMX_L3_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 2573 } 2574 2575 return rv; 2576 } 2577 2578 /* 2579 * Function: 2580 * bcmx_l3_vrrp_delete_all 2581 * Purpose: 2582 * Delete all the VRIDs for a particular VLAN/VSI. 2583 * Parameters: 2584 * vlan - VLAN/VSI 2585 * Returns: 2586 * BCM_E_XXX 2587 */ 2588 int 2589 bcmx_l3_vrrp_delete_all(bcm_vlan_t vlan) 2590 { 2591 int rv = BCM_E_UNAVAIL, tmp_rv; 2592 int i, bcm_unit; 2593 2594 BCMX_L3_INIT_CHECK; 2595 2596 BCMX_UNIT_ITER(bcm_unit, i) { 2597 tmp_rv = bcm_l3_vrrp_delete_all(bcm_unit, vlan); 2598 BCM_IF_ERROR_RETURN(BCMX_L3_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv)); 2599 } 2600 2601 return rv; 2602 } 2603 2604 /* 2605 * Function: 2606 * bcmx_l3_vrrp_get 2607 * Purpose: 2608 * Get all the VRIDs for which the physical node is master for 2609 * the virtual routers on the given VLAN/VSI. 2610 * Parameters: 2611 * vlan - VLAN/VSI 2612 * alloc_size - Size of vrid_array 2613 * vrid_array - (OUT) Pointer to the array to which the VRIDs will be copied 2614 * count - (OUT) Number of VRIDs returned 2615 * Returns: 2616 * BCM_E_XXX 2617 */ 2618 int 2619 bcmx_l3_vrrp_get(bcm_vlan_t vlan, int alloc_size, int *vrid_array, int *count) 2620 { 2621 int rv; 2622 int i, bcm_unit; 2623 2624 BCMX_L3_INIT_CHECK; 2625 2626 BCMX_PARAM_ARRAY_NULL_CHECK(alloc_size, vrid_array); 2627 BCMX_PARAM_NULL_CHECK(count); 2628 2629 BCMX_UNIT_ITER(bcm_unit, i) { 2630 rv = bcm_l3_vrrp_get(bcm_unit, vlan, alloc_size, vrid_array, count); 2631 if (BCMX_L3_GET_IS_VALID(bcm_unit, rv)) { 2632 return rv; 2633 } 2634 } 2635 2636 return BCM_E_UNAVAIL; 2637 } 2638 2639 #endif /* INCLUDE_L3 */