multicast.c (21418B)
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: multicast.c 8 * Purpose: Multicast CLI commands 9 */ 10 11 #include <appl/diag/system.h> 12 #include <appl/diag/parse.h> 13 #include <shared/bsl.h> 14 #include <bcm/error.h> 15 16 #include <bcm/multicast.h> 17 #include <bcm_int/common/multicast.h> 18 #include <bcm_int/esw/multicast.h> 19 20 char cmd_multicast_usage[] = 21 "Usages:\n" 22 "\tcreate Type=L2|L3|VPLS|SUBPORT|MIN|WLAN|TRILL [Group=<num>]\n" 23 "\tdestroy Group=<num>\n" 24 "\tl3encap Group=<num> Port=<num> Intf=<num>\n" 25 "\tl2encap Group=<num> Port=<num> Vlan=<num>\n" 26 "\tvplsencap Group=<num> Port=<num> MplsPortId=<num>\n" 27 "\tsubportencap Group=<num> Port=<num> SubPort=<num>\n" 28 "\tmimencap Group=<num> Port=<num> MimPortId=<num>\n" 29 "\twlanencap Group=<num> Port=<num> WlanPortId=<num>\n" 30 "\tadd Group=<num> Port=<num> EncapId=<num>\n" 31 "\tdelete Group=<num> [Port=<num> EncapId=<num>]\n" 32 "\tshow [Group=<num>]\n"; 33 34 const char *cmd_multicast_parse_type[] = { 35 "NONE", 36 "L2", 37 "L3", 38 "VPLS", 39 "SUBPORT", 40 "MIM", 41 "WLAN", 42 "VLAN", 43 "TRILL", 44 "NIV", 45 "EGRESS_OBJECT", 46 "L2GRE", 47 "VXLAN", 48 "PORTS_GROUP", 49 "EXTENDER" 50 }; 51 52 int 53 _cmd_multicast_traverse_cb(int unit, bcm_multicast_t group, uint32 flags, 54 void *user_data) 55 { 56 int rv, i, port_count; 57 bcm_gport_t *port_array = NULL; 58 bcm_if_t *encap_id_array = NULL; 59 int port_max = 0; 60 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 61 bcm_gport_t *q_array = NULL; 62 #endif 63 64 /* first, get the port count. 65 * port_max = 0, port_array & encap_id_array = NULL 66 */ 67 rv = bcm_multicast_egress_get(unit, group, port_max, port_array, 68 encap_id_array, &port_count); 69 if (rv < 0) { 70 cli_out("%s ERROR: egress port count get failed - %s\n", 71 ARG_CMD((args_t *)user_data), bcm_errmsg(rv)); 72 return rv; 73 } 74 if (port_count) { 75 /* allocate proper size port_array & encap_id_array */ 76 port_array = (bcm_gport_t *)sal_alloc 77 (sizeof(bcm_gport_t) * port_count, 78 "_cmd_multicast_traverse_cb : port_array"); 79 if (port_array == NULL) { 80 cli_out("%s ERROR: port_array mem alloc failed\n", 81 ARG_CMD((args_t *)user_data)); 82 return BCM_E_MEMORY; 83 } 84 encap_id_array = (bcm_if_t *)sal_alloc( 85 sizeof(bcm_if_t) *port_count, 86 "_cmd_multicast_traverse_cb : encap_id_array"); 87 if (encap_id_array == NULL) { 88 cli_out("%s ERROR: encap_id_array mem alloc failed\n", 89 ARG_CMD((args_t *)user_data)); 90 sal_free(port_array); 91 return BCM_E_MEMORY; 92 } 93 94 rv = bcm_multicast_egress_get(unit, group, port_count, 95 port_array, encap_id_array, 96 &port_count); 97 if (rv < 0) { 98 cli_out("%s ERROR: egress get failure - %s\n", 99 ARG_CMD((args_t *)user_data), bcm_errmsg(rv)); 100 sal_free(port_array); 101 sal_free(encap_id_array); 102 return rv; 103 } 104 if (_BCM_MULTICAST_TYPE_GET(group) >= 105 COUNTOF(cmd_multicast_parse_type)) { 106 cli_out("Group 0x%x (%s)\n", group, 107 "UNKNOWN"); 108 } else { 109 cli_out("Group 0x%x (%s)\n", group, 110 cmd_multicast_parse_type[_BCM_MULTICAST_TYPE_GET(group)]); 111 } 112 for (i = 0; i < port_count; i++) { 113 cli_out("\tport %s, encap id %d\n", 114 mod_port_name(unit, -1, port_array[i]), encap_id_array[i]); 115 } 116 117 sal_free(port_array); 118 sal_free(encap_id_array); 119 } 120 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 121 if (SOC_IS_KATANAX(unit)) { 122 /* Subscrber replications 123 */ 124 port_max = BCM_MULTICAST_PORT_MAX; 125 port_count = 0; 126 port_array = sal_alloc(port_max * sizeof(bcm_gport_t), 127 "mcast port array"); 128 if (port_array == NULL) { 129 return BCM_E_MEMORY; 130 } 131 encap_id_array = sal_alloc(port_max * sizeof(bcm_if_t), 132 "mcast encap array"); 133 if (encap_id_array == NULL) { 134 sal_free (port_array); 135 return BCM_E_MEMORY; 136 } 137 q_array = sal_alloc(port_max * sizeof(bcm_if_t), 138 "mcast q array"); 139 if (q_array == NULL) { 140 sal_free (port_array); 141 sal_free (encap_id_array); 142 return BCM_E_MEMORY; 143 } 144 sal_memset(q_array, 0, (port_max * sizeof(bcm_if_t))); 145 146 rv = bcm_multicast_egress_subscriber_get(unit, group, 147 port_max, port_array, 148 encap_id_array, q_array, &port_count); 149 if (rv < 0) { 150 cli_out("%s ERROR: egress port count get failed - ?%s\n", 151 ARG_CMD((args_t *)user_data), bcm_errmsg(rv)); 152 sal_free(port_array); 153 sal_free(encap_id_array); 154 sal_free(q_array); 155 return rv; 156 } 157 if (port_count == 0) { 158 sal_free(port_array); 159 sal_free(encap_id_array); 160 sal_free(q_array); 161 return BCM_E_NONE; 162 } 163 if (_BCM_MULTICAST_TYPE_GET(group) >= 164 COUNTOF(cmd_multicast_parse_type)) { 165 cli_out("Group 0x%x (%s)\n", group, 166 "UNKNOWN"); 167 } else { 168 cli_out("Group 0x%x (%s)\n", group, 169 cmd_multicast_parse_type[_BCM_MULTICAST_TYPE_GET(group)]); 170 } 171 for (i = 0; i < port_count; i++) { 172 cli_out("\tport %s, encap id %d replication queue id %d\n", 173 mod_port_name(unit, -1, port_array[i]), 174 encap_id_array[i],q_array[i]); 175 } 176 177 sal_free(port_array); 178 sal_free(encap_id_array); 179 sal_free(q_array); 180 } 181 #endif 182 return BCM_E_NONE; 183 } 184 185 cmd_result_t 186 cmd_multicast(int unit, args_t *a) 187 { 188 char *subcmd = NULL; 189 parse_table_t pt; 190 int rv, type; 191 uint32 flags; 192 bcm_multicast_t group; 193 bcm_gport_t port; 194 bcm_if_t intf; /* for l3_encap_get */ 195 bcm_vlan_t vlan; /* for l2_encap_get */ 196 bcm_gport_t mpls_port_id; /* for vpls_encap_get */ 197 bcm_gport_t subport; /* for subport_encap_get */ 198 bcm_gport_t mim_port_id; /* for mim_encap_get */ 199 bcm_gport_t wlan_port_id; /* for wlan_encap_get */ 200 bcm_if_t encap_id; 201 char buf[20]; 202 203 subcmd = ARG_GET(a); 204 if (subcmd == NULL) { 205 return CMD_USAGE; 206 } 207 208 if (!sal_strcasecmp(subcmd, "create")) { 209 parse_table_init(unit, &pt); 210 parse_table_add(&pt, "Type", PQ_MULTI, 0, &type, 211 cmd_multicast_parse_type); 212 parse_table_add(&pt, "Group", PQ_INT, (void *)-1, &group, 0); 213 if (parse_arg_eq(a, &pt) < 0) { 214 cli_out("%s: Invalid argument: %s\n", ARG_CMD(a), ARG_CUR(a)); 215 parse_arg_eq_done(&pt); 216 return CMD_FAIL; 217 } 218 parse_arg_eq_done(&pt); 219 220 switch (type) { 221 case _BCM_MULTICAST_TYPE_L2: 222 flags = BCM_MULTICAST_TYPE_L2; 223 break; 224 case _BCM_MULTICAST_TYPE_L3: 225 flags = BCM_MULTICAST_TYPE_L3; 226 break; 227 case _BCM_MULTICAST_TYPE_VPLS: 228 flags = BCM_MULTICAST_TYPE_VPLS; 229 break; 230 case _BCM_MULTICAST_TYPE_SUBPORT: 231 flags = BCM_MULTICAST_TYPE_SUBPORT; 232 break; 233 case _BCM_MULTICAST_TYPE_MIM: 234 flags = BCM_MULTICAST_TYPE_MIM; 235 break; 236 case _BCM_MULTICAST_TYPE_WLAN: 237 flags = BCM_MULTICAST_TYPE_WLAN; 238 break; 239 case _BCM_MULTICAST_TYPE_TRILL: 240 flags = BCM_MULTICAST_TYPE_TRILL; 241 break; 242 default: 243 return CMD_FAIL; 244 } 245 if (group != -1) { 246 flags |= BCM_MULTICAST_WITH_ID; 247 if (!_BCM_MULTICAST_IS_SET(group)) { 248 /* Encode the group properly for the selected type */ 249 _BCM_MULTICAST_GROUP_SET(group, type, group); 250 } 251 } 252 rv = bcm_multicast_create(unit, flags, &group); 253 if (rv < 0) { 254 cli_out("%s ERROR: fail to create %s group - %s\n", 255 ARG_CMD(a), cmd_multicast_parse_type[type], 256 bcm_errmsg(rv)); 257 return CMD_FAIL; 258 } 259 260 cli_out("group id 0x%x\n", group); 261 sal_sprintf(buf, "0x%x", group); 262 var_set("multicast_group", buf, TRUE, FALSE); 263 return CMD_OK; 264 } 265 266 if (!sal_strcasecmp(subcmd, "destroy")) { 267 parse_table_init(unit, &pt); 268 parse_table_add(&pt, "Group", PQ_INT, (void *)-1, &group, 0); 269 if (parse_arg_eq(a, &pt) < 0 || group == -1) { 270 cli_out("%s: Invalid argument: %s\n", ARG_CMD(a), ARG_CUR(a)); 271 parse_arg_eq_done(&pt); 272 return CMD_FAIL; 273 } 274 parse_arg_eq_done(&pt); 275 276 rv = bcm_multicast_destroy(unit, group); 277 if (rv < 0) { 278 cli_out("%s ERROR: fail to destroy group %d - %s\n", 279 ARG_CMD(a), group, bcm_errmsg(rv)); 280 return CMD_FAIL; 281 } 282 return CMD_OK; 283 } 284 285 if (!sal_strcasecmp(subcmd, "l3encap")) { 286 parse_table_init(unit, &pt); 287 parse_table_add(&pt, "Group", PQ_INT, (void *)-1, &group, 0); 288 parse_table_add(&pt, "Port", PQ_PORT, (void *)BCM_GPORT_INVALID, &port, 289 0); 290 parse_table_add(&pt, "Intf", PQ_INT, (void *)-1, &intf, 0); 291 if (parse_arg_eq(a, &pt) < 0) { 292 cli_out("%s: Invalid argument: %s\n", ARG_CMD(a), ARG_CUR(a)); 293 parse_arg_eq_done(&pt); 294 return CMD_FAIL; 295 } 296 parse_arg_eq_done(&pt); 297 298 if (intf == -1) { 299 cli_out("%s: Interface not specified\n", ARG_CMD(a)); 300 return CMD_FAIL; 301 } 302 303 if (!BCM_GPORT_IS_SET(port)) { 304 BCM_GPORT_LOCAL_SET(port, port); 305 } 306 rv = bcm_multicast_l3_encap_get(unit, group, port, intf, &encap_id); 307 if (rv < 0) { 308 cli_out("%s ERROR: fail to get L3 encap - %s\n", 309 ARG_CMD(a), bcm_errmsg(rv)); 310 return CMD_FAIL; 311 } 312 cli_out("Encap ID %d\n", encap_id); 313 return CMD_OK; 314 } 315 316 if (!sal_strcasecmp(subcmd, "l2encap")) { 317 parse_table_init(unit, &pt); 318 parse_table_add(&pt, "Group", PQ_INT, (void *)-1, &group, 0); 319 parse_table_add(&pt, "Port", PQ_PORT, (void *)BCM_GPORT_INVALID, &port, 320 0); 321 parse_table_add(&pt, "Vlan", PQ_INT, (void *)BCM_VLAN_INVALID, &vlan, 322 0); 323 if (parse_arg_eq(a, &pt) < 0) { 324 cli_out("%s: Invalid argument: %s\n", ARG_CMD(a), ARG_CUR(a)); 325 parse_arg_eq_done(&pt); 326 return CMD_FAIL; 327 } 328 parse_arg_eq_done(&pt); 329 330 if (!BCM_GPORT_IS_SET(port)) { 331 BCM_GPORT_LOCAL_SET(port, port); 332 } 333 rv = bcm_multicast_l2_encap_get(unit, group, port, vlan, &encap_id); 334 if (rv < 0) { 335 cli_out("%s ERROR: fail to get L2 encap - %s\n", 336 ARG_CMD(a), bcm_errmsg(rv)); 337 return CMD_FAIL; 338 } 339 cli_out("Encap ID %d\n", encap_id); 340 return CMD_OK; 341 } 342 343 if (!sal_strcasecmp(subcmd, "vplsencap")) { 344 parse_table_init(unit, &pt); 345 parse_table_add(&pt, "Group", PQ_INT, (void *)-1, &group, 0); 346 parse_table_add(&pt, "Port", PQ_PORT, (void *)BCM_GPORT_INVALID, &port, 347 0); 348 parse_table_add(&pt, "MplsPortId", PQ_INT, (void *)BCM_GPORT_INVALID, 349 &mpls_port_id, 0); 350 if (parse_arg_eq(a, &pt) < 0) { 351 cli_out("%s: Invalid argument: %s\n", ARG_CMD(a), ARG_CUR(a)); 352 parse_arg_eq_done(&pt); 353 return CMD_FAIL; 354 } 355 parse_arg_eq_done(&pt); 356 357 if (group < 0) { 358 cli_out("%s: Group not specified\n", ARG_CMD(a)); 359 return CMD_FAIL; 360 } 361 if (port == BCM_GPORT_INVALID) { 362 cli_out("%s: Port not specified\n", ARG_CMD(a)); 363 return CMD_FAIL; 364 } 365 if (mpls_port_id == BCM_GPORT_INVALID) { 366 cli_out("%s: MplsPortId not specified\n", ARG_CMD(a)); 367 return CMD_FAIL; 368 } 369 370 if (!BCM_GPORT_IS_SET(port)) { 371 BCM_GPORT_LOCAL_SET(port, port); 372 } 373 if (!BCM_GPORT_IS_SET(mpls_port_id)) { 374 BCM_GPORT_MPLS_PORT_ID_SET(mpls_port_id, mpls_port_id); 375 } 376 rv = bcm_multicast_vpls_encap_get(unit, group, port, mpls_port_id, 377 &encap_id); 378 if (rv < 0) { 379 cli_out("%s ERROR: fail to get VPLS encap - %s\n", 380 ARG_CMD(a), bcm_errmsg(rv)); 381 return CMD_FAIL; 382 } 383 cli_out("Encap ID %d\n", encap_id); 384 return CMD_OK; 385 } 386 387 if (!sal_strcasecmp(subcmd, "subportEncap")) { 388 parse_table_init(unit, &pt); 389 parse_table_add(&pt, "Group", PQ_INT, (void *)-1, &group, 0); 390 parse_table_add(&pt, "Port", PQ_PORT, (void *)BCM_GPORT_INVALID, &port, 391 0); 392 parse_table_add(&pt, "SubPort", PQ_INT, (void *)BCM_GPORT_INVALID, 393 &subport, 0); 394 if (parse_arg_eq(a, &pt) < 0) { 395 cli_out("%s: Invalid argument: %s\n", ARG_CMD(a), ARG_CUR(a)); 396 parse_arg_eq_done(&pt); 397 return CMD_FAIL; 398 } 399 parse_arg_eq_done(&pt); 400 401 if (group < 0) { 402 cli_out("%s: Group not specified\n", ARG_CMD(a)); 403 return CMD_FAIL; 404 } 405 if (port == BCM_GPORT_INVALID) { 406 cli_out("%s: Port not specified\n", ARG_CMD(a)); 407 return CMD_FAIL; 408 } 409 if (subport == BCM_GPORT_INVALID) { 410 cli_out("%s: SubPort not specified\n", ARG_CMD(a)); 411 return CMD_FAIL; 412 } 413 414 if (!BCM_GPORT_IS_SET(port)) { 415 BCM_GPORT_LOCAL_SET(port, port); 416 } 417 if (!BCM_GPORT_IS_SET(subport)) { 418 BCM_GPORT_SUBPORT_PORT_SET(subport, subport); 419 } 420 rv = bcm_multicast_subport_encap_get(unit, group, port, subport, 421 &encap_id); 422 if (rv < 0) { 423 cli_out("%s ERROR: fail to get subport encap - %s\n", 424 ARG_CMD(a), bcm_errmsg(rv)); 425 return CMD_FAIL; 426 } 427 cli_out("Encap ID %d\n", encap_id); 428 return CMD_OK; 429 } 430 431 if (!sal_strcasecmp(subcmd, "mimencap")) { 432 parse_table_init(unit, &pt); 433 parse_table_add(&pt, "Group", PQ_INT, (void *)-1, &group, 0); 434 parse_table_add(&pt, "Port", PQ_PORT, (void *)BCM_GPORT_INVALID, &port, 435 0); 436 parse_table_add(&pt, "MimPortId", PQ_INT, (void *)BCM_GPORT_INVALID, 437 &mim_port_id, 0); 438 if (parse_arg_eq(a, &pt) < 0) { 439 cli_out("%s: Invalid argument: %s\n", ARG_CMD(a), ARG_CUR(a)); 440 parse_arg_eq_done(&pt); 441 return CMD_FAIL; 442 } 443 parse_arg_eq_done(&pt); 444 445 if (group < 0) { 446 cli_out("%s: Group not specified\n", ARG_CMD(a)); 447 return CMD_FAIL; 448 } 449 if (port == BCM_GPORT_INVALID) { 450 cli_out("%s: Port not specified\n", ARG_CMD(a)); 451 return CMD_FAIL; 452 } 453 if (mim_port_id == BCM_GPORT_INVALID) { 454 cli_out("%s: MimPortId not specified\n", ARG_CMD(a)); 455 return CMD_FAIL; 456 } 457 458 if (!BCM_GPORT_IS_SET(port)) { 459 BCM_GPORT_LOCAL_SET(port, port); 460 } 461 if (!BCM_GPORT_IS_SET(mim_port_id)) { 462 BCM_GPORT_MIM_PORT_ID_SET(mim_port_id, mim_port_id); 463 } 464 rv = bcm_multicast_mim_encap_get(unit, group, port, mim_port_id, 465 &encap_id); 466 if (rv < 0) { 467 cli_out("%s ERROR: fail to get MIM encap - %s\n", 468 ARG_CMD(a), bcm_errmsg(rv)); 469 return CMD_FAIL; 470 } 471 cli_out("Encap ID %d\n", encap_id); 472 return CMD_OK; 473 } 474 475 if (!sal_strcasecmp(subcmd, "wlanencap")) { 476 parse_table_init(unit, &pt); 477 parse_table_add(&pt, "Group", PQ_INT, (void *)-1, &group, 0); 478 parse_table_add(&pt, "Port", PQ_PORT, (void *)BCM_GPORT_INVALID, &port, 479 0); 480 parse_table_add(&pt, "WlanPortId", PQ_INT, (void *)BCM_GPORT_INVALID, 481 &wlan_port_id, 0); 482 if (parse_arg_eq(a, &pt) < 0) { 483 cli_out("%s: Invalid argument: %s\n", ARG_CMD(a), ARG_CUR(a)); 484 parse_arg_eq_done(&pt); 485 return CMD_FAIL; 486 } 487 parse_arg_eq_done(&pt); 488 489 if (group < 0) { 490 cli_out("%s: Group not specified\n", ARG_CMD(a)); 491 return CMD_FAIL; 492 } 493 if (port == BCM_GPORT_INVALID) { 494 cli_out("%s: Port not specified\n", ARG_CMD(a)); 495 return CMD_FAIL; 496 } 497 if (wlan_port_id == BCM_GPORT_INVALID) { 498 cli_out("%s: WlanPortId not specified\n", ARG_CMD(a)); 499 return CMD_FAIL; 500 } 501 502 if (!BCM_GPORT_IS_SET(port)) { 503 BCM_GPORT_LOCAL_SET(port, port); 504 } 505 if (!BCM_GPORT_IS_SET(wlan_port_id)) { 506 BCM_GPORT_WLAN_PORT_ID_SET(wlan_port_id, wlan_port_id); 507 } 508 rv = bcm_multicast_wlan_encap_get(unit, group, port, wlan_port_id, 509 &encap_id); 510 if (rv < 0) { 511 cli_out("%s ERROR: fail to get WLAN encap - %s\n", 512 ARG_CMD(a), bcm_errmsg(rv)); 513 return CMD_FAIL; 514 } 515 cli_out("Encap ID %d\n", encap_id); 516 return CMD_OK; 517 } 518 519 if (!sal_strcasecmp(subcmd, "add")) { 520 parse_table_init(unit, &pt); 521 parse_table_add(&pt, "Group", PQ_INT, (void *)-1, &group, 0); 522 parse_table_add(&pt, "Port", PQ_PORT, (void *)BCM_GPORT_INVALID, &port, 523 0); 524 parse_table_add(&pt, "EncapId", PQ_INT, (void *)BCM_IF_INVALID, 525 &encap_id, 0); 526 527 if (parse_arg_eq(a, &pt) < 0 || group < 0 || 528 port == BCM_GPORT_INVALID) { 529 cli_out("%s: Invalid argument: %s\n", ARG_CMD(a), ARG_CUR(a)); 530 parse_arg_eq_done(&pt); 531 return CMD_FAIL; 532 } 533 parse_arg_eq_done(&pt); 534 535 if (!BCM_GPORT_IS_SET(port)) { 536 BCM_GPORT_LOCAL_SET(port, port); 537 } 538 rv = bcm_multicast_egress_add(unit, group, port, encap_id); 539 if (rv < 0) { 540 cli_out("%s ERROR: egress add failure - %s\n", 541 ARG_CMD(a), bcm_errmsg(rv)); 542 return CMD_FAIL; 543 } 544 return CMD_OK; 545 } 546 547 if (!sal_strcasecmp(subcmd, "delete")) { 548 parse_table_init(unit, &pt); 549 parse_table_add(&pt, "Group", PQ_INT, (void *)-1, &group, 0); 550 parse_table_add(&pt, "Port", PQ_PORT, (void *)BCM_GPORT_INVALID, &port, 551 0); 552 parse_table_add(&pt, "EncapId", PQ_INT, (void *)BCM_IF_INVALID, 553 &encap_id, 0); 554 if (parse_arg_eq(a, &pt) < 0 || group < 0) { 555 cli_out("%s: Invalid argument: %s\n", ARG_CMD(a), ARG_CUR(a)); 556 parse_arg_eq_done(&pt); 557 return CMD_FAIL; 558 } 559 parse_arg_eq_done(&pt); 560 561 if (port == BCM_GPORT_INVALID && encap_id == BCM_IF_INVALID) { 562 rv = bcm_multicast_egress_delete_all(unit, group); 563 if (rv < 0) { 564 cli_out("%s ERROR: egress delete all failure - %s\n", 565 ARG_CMD(a), bcm_errmsg(rv)); 566 return CMD_FAIL; 567 } 568 } else { 569 if (port == BCM_GPORT_INVALID) { 570 return CMD_FAIL; 571 } 572 if (!BCM_GPORT_IS_SET(port)) { 573 BCM_GPORT_LOCAL_SET(port, port); 574 } 575 rv = bcm_multicast_egress_delete(unit, group, port, encap_id); 576 if (rv < 0) { 577 cli_out("%s ERROR: egress delete failure - %s\n", 578 ARG_CMD(a), bcm_errmsg(rv)); 579 return CMD_FAIL; 580 } 581 } 582 return CMD_OK; 583 } 584 585 if (!sal_strcasecmp(subcmd, "show")) { 586 parse_table_init(unit, &pt); 587 parse_table_add(&pt, "Group", PQ_INT, (void *)-1, &group, 0); 588 if (parse_arg_eq(a, &pt) < 0) { 589 cli_out("%s: Invalid argument: %s\n", ARG_CMD(a), ARG_CUR(a)); 590 parse_arg_eq_done(&pt); 591 return CMD_FAIL; 592 } 593 parse_arg_eq_done(&pt); 594 595 596 if (group < 0) { 597 rv = bcm_multicast_group_traverse(unit, 598 &_cmd_multicast_traverse_cb, 599 BCM_MULTICAST_TYPE_MASK, a); 600 } else { 601 rv = _cmd_multicast_traverse_cb(unit, group, 0, a); 602 } 603 604 if (BCM_FAILURE(rv)) { 605 return CMD_FAIL; 606 } 607 608 return CMD_OK; 609 } 610 611 return CMD_USAGE; 612 }