vlan.c (90678B)
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 * VLAN CLI commands 8 */ 9 10 #include <appl/diag/system.h> 11 #include <appl/diag/parse.h> 12 #include <appl/diag/dport.h> 13 #include <shared/bsl.h> 14 #include <bcm/error.h> 15 #include <bcm/vlan.h> 16 #include <bcm/l3.h> 17 #include <bcm/debug.h> 18 #include <bcm_int/esw/port.h> 19 20 21 #define VLAN_IF_ERROR_RETURN(op) \ 22 do { \ 23 int __rv__; \ 24 if ((__rv__ = (op)) < 0) { \ 25 cli_out("Error: %s\n", bcm_errmsg(__rv__)); \ 26 return CMD_FAIL; \ 27 } \ 28 } while (0) 29 30 31 32 /* 33 * Structure used internally to get vlan action arguments. 34 * This structure corresponds to bcm_vlan_action_t but 35 * has the action name strings obtained from user input. 36 */ 37 typedef struct ivlan_action_set_s { 38 int new_outer_vlan; 39 int new_inner_vlan; 40 int priority; 41 char *dt_outer; 42 char *dt_outer_prio; 43 char *dt_inner; 44 char *dt_inner_prio; 45 char *ot_outer; 46 char *ot_outer_prio; 47 char *ot_inner; 48 char *it_outer; 49 char *it_inner; 50 char *it_inner_prio; 51 char *ut_outer; 52 char *ut_inner; 53 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 54 int policer; 55 #endif 56 } ivlan_action_set_t; 57 58 59 static struct vlan_action_names { 60 char *name; 61 bcm_vlan_action_t action; 62 } vlan_action_names[] = { 63 { "None", bcmVlanActionNone }, 64 { "Add", bcmVlanActionAdd }, 65 { "Replace", bcmVlanActionReplace }, 66 { "Delete", bcmVlanActionDelete } 67 }; 68 69 static struct vlan_key_type_names { 70 char *name; 71 bcm_vlan_translate_key_t key; 72 } vlan_key_type_names[] = { 73 { "", bcmVlanTranslateKeyInvalid }, 74 { "Double", bcmVlanTranslateKeyDouble }, 75 { "Outer", bcmVlanTranslateKeyOuter }, 76 { "Inner", bcmVlanTranslateKeyInner }, 77 { "OuterTag", bcmVlanTranslateKeyOuterTag }, 78 { "InnerTag", bcmVlanTranslateKeyInnerTag }, 79 { "OuterPri", bcmVlanTranslateKeyOuterPri }, 80 { "PortDouble", bcmVlanTranslateKeyPortDouble }, 81 { "PortOuter", bcmVlanTranslateKeyPortOuter }, 82 { "PortInner", bcmVlanTranslateKeyPortInner }, 83 { "PortOuterTag", bcmVlanTranslateKeyPortOuterTag }, 84 { "PortInnerTag", bcmVlanTranslateKeyPortInnerTag }, 85 { "PortOuterPri", bcmVlanTranslateKeyPortOuterPri } 86 }; 87 88 STATIC void 89 _ivlan_action_set_t_init(ivlan_action_set_t *data) 90 { 91 if (data != NULL) { 92 sal_memset(data, 0, sizeof(ivlan_action_set_t)); 93 } 94 } 95 96 STATIC INLINE void 97 _parse_table_vlan_action_set_add(parse_table_t *pt, ivlan_action_set_t *act) 98 { 99 if (pt == NULL || act == NULL) { 100 return; 101 } 102 parse_table_add(pt, "OuterVlan", PQ_HEX, 0, 103 &(act->new_outer_vlan), NULL); 104 parse_table_add(pt, "InnerVlan", PQ_HEX, 0, 105 &(act->new_inner_vlan), NULL); 106 parse_table_add(pt, "Prio", PQ_INT, 0, 107 &(act->priority), NULL); 108 parse_table_add(pt, "DtOuter", PQ_STRING, "None", 109 &(act->dt_outer), NULL); 110 parse_table_add(pt, "DtOuterPrio", PQ_STRING, "None", 111 &(act->dt_outer_prio), NULL); 112 parse_table_add(pt, "DtInner", PQ_STRING, "None", 113 &(act->dt_inner), NULL); 114 parse_table_add(pt, "DtInnerPrio", PQ_STRING, "None", 115 &(act->dt_inner_prio), NULL); 116 parse_table_add(pt, "OtOuter", PQ_STRING, "None", 117 &(act->ot_outer), NULL); 118 parse_table_add(pt, "OtOuterPrio", PQ_STRING, "None", 119 &(act->ot_outer_prio), NULL); 120 parse_table_add(pt, "OtInner", PQ_STRING, "None", 121 &(act->ot_inner), NULL); 122 parse_table_add(pt, "ItOuter", PQ_STRING, "None", 123 &(act->it_outer), NULL); 124 parse_table_add(pt, "ItInner", PQ_STRING, "None", 125 &(act->it_inner), NULL); 126 parse_table_add(pt, "ItInnerPrio", PQ_STRING, "None", 127 &(act->it_inner_prio), NULL); 128 parse_table_add(pt, "UtOuter", PQ_STRING, "None", 129 &(act->ut_outer), NULL); 130 parse_table_add(pt, "UtInner", PQ_STRING, "None", 131 &(act->ut_inner), NULL); 132 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 133 parse_table_add(pt, "Policer", PQ_HEX, 0, 134 &(act->policer), NULL); 135 #endif 136 } 137 138 /* 139 * Return bcm_vlan_action_t action from action name string 140 */ 141 STATIC int 142 _vlan_action_get(const char *action_name) 143 { 144 int i, names; 145 146 if (action_name == NULL || *action_name == '\0') { 147 return 0; 148 } 149 150 names = sizeof(vlan_action_names) / sizeof(struct vlan_action_names); 151 for (i = 0; i < names; i++) { 152 if (sal_strcasecmp(action_name, vlan_action_names[i].name) == 0) { 153 return vlan_action_names[i].action; 154 } 155 } 156 cli_out("Invalid action <%s>. Valid actions are:\n ", action_name); 157 for (i = 0; i < names; i++) { 158 cli_out("%s ", vlan_action_names[i].name); 159 } 160 cli_out("\n"); 161 return -1; 162 } 163 164 /* 165 * Return the action name string from bcm_vlan_action_t action 166 */ 167 static INLINE char * 168 _vlan_action_name_get(bcm_vlan_action_t action) 169 { 170 int names = sizeof(vlan_action_names) / sizeof(struct vlan_action_names); 171 return ((action >= 0 && action < names) ? vlan_action_names[action].name : 172 "Invalid action"); 173 } 174 175 static INLINE void 176 _vlan_action_set_print(const bcm_vlan_action_set_t *action) 177 { 178 if (action == NULL) { 179 return; 180 } 181 cli_out(" DT: Outer=%-7s OuterPrio=%-7s Inner=%-7s InnerPrio=%-7s\n", 182 _vlan_action_name_get(action->dt_outer), 183 _vlan_action_name_get(action->dt_outer_prio), 184 _vlan_action_name_get(action->dt_inner), 185 _vlan_action_name_get(action->dt_inner_prio)); 186 cli_out(" OT: Outer=%-7s OuterPrio=%-7s Inner=%-7s\n", 187 _vlan_action_name_get(action->ot_outer), 188 _vlan_action_name_get(action->ot_outer_prio), 189 _vlan_action_name_get(action->ot_inner)); 190 cli_out(" IT: Outer=%-7s Inner=%-7s InnerPrio=%-7s\n", 191 _vlan_action_name_get(action->it_outer), 192 _vlan_action_name_get(action->it_inner), 193 _vlan_action_name_get(action->it_inner_prio)); 194 cli_out(" UT: Outer=%-7s Inner=%-7s\n", 195 _vlan_action_name_get(action->ut_outer), 196 _vlan_action_name_get(action->ut_inner)); 197 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 198 cli_out(" Policer=0x%x\n", action->policer_id); 199 #endif 200 } 201 202 STATIC int 203 _vlan_translate_egress_action_print(int unit, int port_class, 204 bcm_vlan_t outer_vlan, 205 bcm_vlan_t inner_vlan, 206 bcm_vlan_action_set_t *action, 207 void *user_data) 208 { 209 cli_out("PortClass=%d, OldOuterVlan=%d, OldInnerVlan=%d\n", 210 port_class, outer_vlan, inner_vlan); 211 _vlan_action_set_print(action); 212 213 return CMD_OK; 214 } 215 216 #define VLAN_IF_BAD_ACTION_RETURN(a, op) \ 217 if (((a = (op)) == -1)) { return CMD_FAIL; } 218 219 STATIC cmd_result_t 220 _ivlan_to_vlan_action_set(bcm_vlan_action_set_t *action, ivlan_action_set_t *act) 221 { 222 if (action == NULL || act == NULL) { 223 return CMD_FAIL; 224 } 225 action->new_outer_vlan = act->new_outer_vlan; 226 action->new_inner_vlan = act->new_inner_vlan; 227 action->priority = act->priority; 228 VLAN_IF_BAD_ACTION_RETURN(action->dt_outer, 229 _vlan_action_get(act->dt_outer)); 230 VLAN_IF_BAD_ACTION_RETURN(action->dt_outer_prio, 231 _vlan_action_get(act->dt_outer_prio)); 232 VLAN_IF_BAD_ACTION_RETURN(action->dt_inner, 233 _vlan_action_get(act->dt_inner)); 234 VLAN_IF_BAD_ACTION_RETURN(action->dt_inner_prio, 235 _vlan_action_get(act->dt_inner_prio)); 236 VLAN_IF_BAD_ACTION_RETURN(action->ot_outer, 237 _vlan_action_get(act->ot_outer)); 238 VLAN_IF_BAD_ACTION_RETURN(action->ot_outer_prio, 239 _vlan_action_get(act->ot_outer_prio)); 240 VLAN_IF_BAD_ACTION_RETURN(action->ot_inner, 241 _vlan_action_get(act->ot_inner)); 242 VLAN_IF_BAD_ACTION_RETURN(action->it_outer, 243 _vlan_action_get(act->it_outer)); 244 VLAN_IF_BAD_ACTION_RETURN(action->it_inner, 245 _vlan_action_get(act->it_inner)); 246 VLAN_IF_BAD_ACTION_RETURN(action->it_inner_prio, 247 _vlan_action_get(act->it_inner_prio)); 248 VLAN_IF_BAD_ACTION_RETURN(action->ut_outer, 249 _vlan_action_get(act->ut_outer)); 250 VLAN_IF_BAD_ACTION_RETURN(action->ut_inner, 251 _vlan_action_get(act->ut_inner)); 252 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 253 action->policer_id = act->policer; 254 #endif 255 return CMD_OK; 256 } 257 258 STATIC cmd_result_t 259 _vlan_action_port(int unit, args_t *a) 260 { 261 char *subcmd; 262 int egress = 0; 263 264 if ((subcmd = ARG_GET(a)) == NULL) { 265 return CMD_USAGE; 266 } 267 if (sal_strcasecmp(subcmd, "egress") == 0) { 268 if ((subcmd = ARG_GET(a)) == NULL) { 269 return CMD_USAGE; 270 } 271 egress = 1; 272 } 273 274 if (sal_strcasecmp(subcmd, "default") == 0) { 275 if ((subcmd = ARG_GET(a)) == NULL) { 276 return CMD_USAGE; 277 } 278 if (sal_strcasecmp(subcmd, "add") == 0) { 279 int port; 280 parse_table_t pt; 281 cmd_result_t r; 282 bcm_vlan_action_set_t action; 283 ivlan_action_set_t act; 284 285 _ivlan_action_set_t_init(&act); 286 parse_table_init(unit, &pt); 287 parse_table_add(&pt, "Port", PQ_PORT, 0, &port, NULL); 288 _parse_table_vlan_action_set_add(&pt, &act); 289 if (parse_arg_eq(a, &pt) < 0) { 290 cli_out("Error: Invalid option %s\n", ARG_CUR(a)); 291 parse_arg_eq_done(&pt); 292 return CMD_USAGE; 293 } 294 bcm_vlan_action_set_t_init(&action); 295 r = _ivlan_to_vlan_action_set(&action, &act); 296 parse_arg_eq_done(&pt); 297 if (r != CMD_OK) { 298 cli_out("Error: invalid action\n"); 299 return r; 300 } 301 302 if (egress == 0) { 303 VLAN_IF_ERROR_RETURN( 304 bcm_vlan_port_default_action_set(unit, port, &action)); 305 } else { 306 VLAN_IF_ERROR_RETURN( 307 bcm_vlan_port_egress_default_action_set(unit, port, 308 &action)); 309 } 310 return CMD_OK; 311 312 } else if (sal_strcasecmp(subcmd, "get") == 0) { 313 int port = 1; 314 parse_table_t pt; 315 cmd_result_t r; 316 bcm_vlan_action_set_t action; 317 318 parse_table_init(unit, &pt); 319 parse_table_add(&pt, "Port", PQ_PORT, 0, &port, NULL); 320 if (!parseEndOk( a, &pt, &r)) { 321 return r; 322 } 323 324 if (egress == 0) { 325 VLAN_IF_ERROR_RETURN( 326 bcm_vlan_port_default_action_get(unit, port, &action)); 327 } else { 328 VLAN_IF_ERROR_RETURN( 329 bcm_vlan_port_egress_default_action_get(unit, port, 330 &action)); 331 } 332 cli_out("Port %d: New OVLAN=%d, New IVLAN=%d, New Prio=%d\n", 333 port, action.new_outer_vlan, action.new_inner_vlan, 334 action.priority); 335 _vlan_action_set_print(&action); 336 return CMD_OK; 337 } 338 } 339 340 return CMD_USAGE; 341 } 342 343 STATIC cmd_result_t 344 _vlan_action_mac(int unit, args_t *a) 345 { 346 char *subcmd; 347 348 if ((subcmd = ARG_GET(a)) == NULL) { 349 return CMD_USAGE; 350 } 351 if (sal_strcasecmp(subcmd, "add") == 0) { 352 parse_table_t pt; 353 bcm_mac_t mac; 354 ivlan_action_set_t act; 355 cmd_result_t r; 356 bcm_vlan_action_set_t action; 357 358 _ivlan_action_set_t_init(&act); 359 parse_table_init(unit, &pt); 360 parse_table_add(&pt, "MACaddress", PQ_MAC, 0, &mac, NULL); 361 _parse_table_vlan_action_set_add(&pt, &act); 362 if (parse_arg_eq(a, &pt) < 0) { 363 cli_out("Error: Invalid option %s\n", ARG_CUR(a)); 364 parse_arg_eq_done(&pt); 365 return CMD_USAGE; 366 } 367 bcm_vlan_action_set_t_init(&action); 368 r = _ivlan_to_vlan_action_set(&action, &act); 369 parse_arg_eq_done(&pt); 370 if (r != CMD_OK) { 371 cli_out("Error: Invalid action\n"); 372 return r; 373 } 374 VLAN_IF_ERROR_RETURN(bcm_vlan_mac_action_add(unit, mac, &action)); 375 return CMD_OK; 376 377 } else if (sal_strcasecmp(subcmd, "get") == 0) { 378 parse_table_t pt; 379 bcm_mac_t mac; 380 cmd_result_t r; 381 bcm_vlan_action_set_t action; 382 383 parse_table_init(unit, &pt); 384 parse_table_add(&pt, "MACaddress", PQ_MAC, 0, &mac, NULL); 385 if (!parseEndOk( a, &pt, &r)) { 386 return r; 387 } 388 VLAN_IF_ERROR_RETURN(bcm_vlan_mac_action_get(unit, mac, &action)); 389 cli_out("MAC=%02x:%02x:%02x:%02x:%02x:%02x\n", 390 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 391 _vlan_action_set_print(&action); 392 return CMD_OK; 393 394 } else if (sal_strcasecmp(subcmd, "delete") == 0) { 395 parse_table_t pt; 396 bcm_mac_t mac; 397 cmd_result_t r; 398 399 parse_table_init(unit, &pt); 400 parse_table_add(&pt, "MACaddress", PQ_MAC, 0, &mac, NULL); 401 if (!parseEndOk( a, &pt, &r)) { 402 return r; 403 } 404 VLAN_IF_ERROR_RETURN(bcm_vlan_mac_action_delete(unit, mac)); 405 return CMD_OK; 406 407 } else if (sal_strcasecmp(subcmd, "clear") == 0) { 408 VLAN_IF_ERROR_RETURN(bcm_vlan_mac_action_delete_all(unit)); 409 return CMD_OK; 410 } 411 412 return CMD_USAGE; 413 } 414 415 STATIC cmd_result_t 416 _vlan_action_protocol(int unit, args_t *a) 417 { 418 char *subcmd; 419 420 if ((subcmd = ARG_GET(a)) == NULL) { 421 return CMD_USAGE; 422 } 423 424 if (sal_strcasecmp(subcmd, "add") == 0) { 425 parse_table_t pt; 426 ivlan_action_set_t act; 427 cmd_result_t r; 428 bcm_pbmp_t pbmp; 429 bcm_port_t port, dport; 430 int frame, ether; 431 bcm_vlan_action_set_t action; 432 433 _ivlan_action_set_t_init(&act); 434 parse_table_init(unit, &pt); 435 parse_table_add(&pt, "PortBitMap", PQ_PBMP|PQ_BCM, 0, &pbmp, NULL); 436 parse_table_add(&pt, "Frame", PQ_INT, 0, &frame, NULL); 437 parse_table_add(&pt, "Ether", PQ_HEX, 0, ðer, NULL); 438 _parse_table_vlan_action_set_add(&pt, &act); 439 if (parse_arg_eq(a, &pt) < 0) { 440 cli_out("Error: invalid option: %s\n", ARG_CUR(a)); 441 parse_arg_eq_done(&pt); 442 return CMD_USAGE; 443 } 444 445 bcm_vlan_action_set_t_init(&action); 446 r = _ivlan_to_vlan_action_set(&action, &act); 447 parse_arg_eq_done(&pt); 448 if (r != CMD_OK) { 449 cli_out("Error: invalid action\n"); 450 return r; 451 } 452 453 /* coverity[overrun-local] */ 454 DPORT_BCM_PBMP_ITER(unit, pbmp, dport, port) { 455 /* convert to gport? */ 456 VLAN_IF_ERROR_RETURN( 457 bcm_vlan_port_protocol_action_add(unit, port, frame, ether, 458 &action)); 459 } 460 return CMD_OK; 461 } 462 463 return CMD_USAGE; 464 } 465 466 STATIC cmd_result_t 467 _vlan_action_ip(int unit, args_t *a, int ip6) 468 { 469 char *subcmd; 470 471 if ((subcmd = ARG_GET(a)) == NULL) { 472 return CMD_USAGE; 473 } 474 475 if (sal_strcasecmp(subcmd, "add") == 0) { 476 parse_table_t pt; 477 ivlan_action_set_t act; 478 cmd_result_t r; 479 bcm_vlan_ip_t vlan_ip; 480 bcm_vlan_action_set_t action; 481 482 _ivlan_action_set_t_init(&act); 483 bcm_vlan_ip_t_init(&vlan_ip); 484 parse_table_init(unit, &pt); 485 if (ip6) { 486 vlan_ip.flags = BCM_VLAN_SUBNET_IP6; 487 parse_table_add(&pt, "IPaddr", PQ_IP6, 0, &vlan_ip.ip6, NULL); 488 parse_table_add(&pt, "prefiX", PQ_INT, 0, &vlan_ip.prefix, NULL); 489 } else { 490 parse_table_add(&pt, "IPaddr", PQ_IP, 0, &vlan_ip.ip4, NULL); 491 parse_table_add(&pt, "NetMask", PQ_IP, 0, &vlan_ip.mask, NULL); 492 } 493 _parse_table_vlan_action_set_add(&pt, &act); 494 if (parse_arg_eq(a, &pt) < 0) { 495 cli_out("Error: invalid option: %s\n", ARG_CUR(a)); 496 parse_arg_eq_done(&pt); 497 return CMD_USAGE; 498 } 499 500 bcm_vlan_action_set_t_init(&action); 501 r = _ivlan_to_vlan_action_set(&action, &act); 502 parse_arg_eq_done(&pt); 503 if (r != CMD_OK) { 504 cli_out("Error: invalid action\n"); 505 return r; 506 } 507 508 VLAN_IF_ERROR_RETURN(bcm_vlan_ip_action_add(unit, &vlan_ip, &action)); 509 return CMD_OK; 510 } 511 512 return CMD_USAGE; 513 } 514 515 516 STATIC cmd_result_t 517 _vlan_action_translate_egress(int unit, args_t *a) 518 { 519 char *subcmd; 520 521 if ((subcmd = ARG_GET(a)) == NULL) { 522 return CMD_USAGE; 523 } 524 525 if (sal_strcasecmp(subcmd, "add") == 0) { 526 parse_table_t pt; 527 cmd_result_t r; 528 int old_outer_vlan, old_inner_vlan, port_class = 0; 529 ivlan_action_set_t act; 530 bcm_vlan_action_set_t action; 531 532 _ivlan_action_set_t_init(&act); 533 parse_table_init(unit, &pt); 534 /* 535 * The bcmPortClassVlanTranslateEgress port class is created with 536 * bcm_port_class_set(). The default bcmPortClassVlanTransateEgress 537 * class for a port is its own port number. 538 */ 539 parse_table_add(&pt, "PortClass", PQ_INT, 0, &port_class, NULL); 540 parse_table_add(&pt, "OldOuterVLan", PQ_INT, 0, &old_outer_vlan, NULL); 541 parse_table_add(&pt, "OldInnerVLan", PQ_INT, 0, &old_inner_vlan, NULL); 542 _parse_table_vlan_action_set_add(&pt, &act); 543 if (parse_arg_eq(a, &pt) < 0) { 544 cli_out("Error: invalid option %s\n", 545 ARG_CUR(a)); 546 parse_arg_eq_done(&pt); 547 return CMD_USAGE; 548 } 549 550 bcm_vlan_action_set_t_init(&action); 551 r = _ivlan_to_vlan_action_set(&action, &act); 552 if (r != CMD_OK) { 553 parse_arg_eq_done(&pt); 554 cli_out("Error: invalid action\n"); 555 return r; 556 } 557 /* Done with string parameters */ 558 parse_arg_eq_done(&pt); 559 VLAN_IF_ERROR_RETURN( 560 bcm_vlan_translate_egress_action_add(unit, port_class, 561 old_outer_vlan, 562 old_inner_vlan, 563 &action)); 564 return CMD_OK; 565 566 } else if ((sal_strcasecmp(subcmd, "delete") == 0) || 567 (sal_strcasecmp(subcmd, "get") == 0)) { 568 parse_table_t pt; 569 cmd_result_t r; 570 int old_outer_vlan, old_inner_vlan, port_class = 0; 571 572 parse_table_init(unit, &pt); 573 parse_table_add(&pt, "PortClass", PQ_INT, 0, &port_class, NULL); 574 parse_table_add(&pt, "OldOuterVLan", PQ_INT, 0, &old_outer_vlan, NULL); 575 parse_table_add(&pt, "OldInnerVLan", PQ_INT, 0, &old_inner_vlan, NULL); 576 if (!parseEndOk( a, &pt, &r)) { 577 return r; 578 } 579 if (sal_strcasecmp(subcmd, "delete") == 0) { 580 VLAN_IF_ERROR_RETURN( 581 bcm_vlan_translate_egress_action_delete(unit, port_class, 582 old_outer_vlan, 583 old_inner_vlan)); 584 return CMD_OK; 585 } else { /* get */ 586 bcm_vlan_action_set_t action; 587 VLAN_IF_ERROR_RETURN( 588 bcm_vlan_translate_egress_action_get(unit, port_class, 589 old_outer_vlan, 590 old_inner_vlan, 591 &action)); 592 _vlan_translate_egress_action_print(unit, port_class, 593 old_outer_vlan, 594 old_inner_vlan, &action, NULL); 595 return CMD_OK; 596 } 597 } else if (sal_strcasecmp(subcmd, "show") == 0) { 598 VLAN_IF_ERROR_RETURN( 599 bcm_vlan_translate_egress_action_traverse(unit, 600 _vlan_translate_egress_action_print, 601 NULL)); 602 return CMD_OK; 603 } 604 605 return CMD_USAGE; 606 } 607 608 609 STATIC int 610 _vlan_translate_range_action_print(int unit, bcm_gport_t gport, 611 bcm_vlan_t outer_vlan_lo, 612 bcm_vlan_t outer_vlan_hi, 613 bcm_vlan_t inner_vlan_lo, 614 bcm_vlan_t inner_vlan_hi, 615 bcm_vlan_action_set_t *action, 616 void *user_data) 617 { 618 int id; 619 bcm_port_t port; 620 bcm_module_t modid; 621 bcm_trunk_t trunk; 622 623 if (action == NULL) { 624 return CMD_FAIL; 625 } 626 627 VLAN_IF_ERROR_RETURN( 628 _bcm_esw_gport_resolve(unit, gport, &modid, &port, &trunk, &id)); 629 if (BCM_GPORT_IS_TRUNK(gport)) { 630 cli_out("TGID=%d, ", trunk); 631 } else { 632 cli_out("Port=%d, Modid=%d, ", port, modid); 633 } 634 cli_out("OuterVlanLo=%d, OuterVlanHi=%d, InnerVlanLo=%d, " 635 "InnerVlanHi=%d\n", outer_vlan_lo, outer_vlan_hi, 636 inner_vlan_lo, inner_vlan_hi); 637 _vlan_action_set_print(action); 638 639 return CMD_OK; 640 } 641 642 STATIC cmd_result_t 643 _vlan_action_translate_range(int unit, args_t *a) 644 { 645 char *subcmd; 646 647 if ((subcmd = ARG_GET(a)) == NULL) { 648 return CMD_USAGE; 649 } 650 651 if (sal_strcasecmp(subcmd, "add") == 0) { 652 parse_table_t pt; 653 cmd_result_t r; 654 bcm_gport_t gport; 655 int port, 656 outer_vlan_lo = BCM_VLAN_INVALID, 657 outer_vlan_hi = BCM_VLAN_INVALID, 658 inner_vlan_lo = BCM_VLAN_INVALID, 659 inner_vlan_hi = BCM_VLAN_INVALID; 660 ivlan_action_set_t act; 661 bcm_vlan_action_set_t action; 662 663 _ivlan_action_set_t_init(&act); 664 parse_table_init(unit, &pt); 665 parse_table_add(&pt, "Port", PQ_PORT, 0, &port, NULL); 666 parse_table_add(&pt, "OuterVLanLo", PQ_DFL | PQ_INT, 0, 667 &outer_vlan_lo, NULL); 668 parse_table_add(&pt, "OuterVLanHi", PQ_DFL | PQ_INT, 0, 669 &outer_vlan_hi, NULL); 670 parse_table_add(&pt, "InnerVLanLo", PQ_DFL | PQ_INT, 0, 671 &inner_vlan_lo, NULL); 672 parse_table_add(&pt, "InnerVLanHi", PQ_DFL | PQ_INT, 0, 673 &inner_vlan_hi, NULL); 674 _parse_table_vlan_action_set_add(&pt, &act); 675 if (parse_arg_eq(a, &pt) < 0) { 676 cli_out("Error: invalid option %s\n", 677 ARG_CUR(a)); 678 parse_arg_eq_done(&pt); 679 return CMD_USAGE; 680 } 681 682 bcm_vlan_action_set_t_init(&action); 683 r = _ivlan_to_vlan_action_set(&action, &act); 684 if (r != CMD_OK) { 685 parse_arg_eq_done(&pt); 686 cli_out("Error: invalid action\n"); 687 return r; 688 } 689 /* Done with string parameters */ 690 parse_arg_eq_done(&pt); 691 BCM_GPORT_LOCAL_SET(gport, port); 692 VLAN_IF_ERROR_RETURN( 693 bcm_vlan_translate_action_range_add(unit, gport, 694 outer_vlan_lo, 695 outer_vlan_hi, 696 inner_vlan_lo, 697 inner_vlan_hi, 698 &action)); 699 return CMD_OK; 700 701 } else if ((sal_strcasecmp(subcmd, "delete") == 0) || 702 (sal_strcasecmp(subcmd, "get") == 0)) { 703 parse_table_t pt; 704 cmd_result_t r; 705 bcm_gport_t gport; 706 int port = 0, 707 outer_vlan_lo = BCM_VLAN_INVALID, 708 outer_vlan_hi = BCM_VLAN_INVALID, 709 inner_vlan_lo = BCM_VLAN_INVALID, 710 inner_vlan_hi = BCM_VLAN_INVALID; 711 712 parse_table_init(unit, &pt); 713 parse_table_add(&pt, "Port", PQ_PORT, 0, &port, NULL); 714 parse_table_add(&pt, "OuterVLanLo", PQ_DFL | PQ_INT, 0, 715 &outer_vlan_lo, NULL); 716 parse_table_add(&pt, "OuterVLanHi", PQ_DFL | PQ_INT, 0, 717 &outer_vlan_hi, NULL); 718 parse_table_add(&pt, "InnerVLanLo", PQ_DFL | PQ_INT, 0, 719 &inner_vlan_lo, NULL); 720 parse_table_add(&pt, "InnerVLanHi", PQ_DFL | PQ_INT, 0, 721 &inner_vlan_hi, NULL); 722 if (!parseEndOk( a, &pt, &r)) { 723 return r; 724 } 725 BCM_GPORT_LOCAL_SET(gport, port); 726 if (sal_strcasecmp(subcmd, "delete") == 0) { 727 VLAN_IF_ERROR_RETURN( 728 bcm_vlan_translate_action_range_delete(unit, gport, 729 outer_vlan_lo, 730 outer_vlan_hi, 731 inner_vlan_lo, 732 inner_vlan_hi)); 733 734 return CMD_OK; 735 736 } else { /* get */ 737 bcm_vlan_action_set_t action; 738 VLAN_IF_ERROR_RETURN( 739 bcm_vlan_translate_action_range_get(unit, gport, 740 outer_vlan_lo, 741 outer_vlan_hi, 742 inner_vlan_lo, 743 inner_vlan_hi, 744 &action)); 745 cli_out("Port=%d, OuterVlanLo=%d, OuterVlanHi=%d, InnerVlanLo=%d, " 746 "InnerVlanHi=%d\n", port, outer_vlan_lo, outer_vlan_hi, 747 inner_vlan_lo, inner_vlan_hi); 748 _vlan_action_set_print(&action); 749 return CMD_OK; 750 } 751 } else if (sal_strcasecmp(subcmd, "show") == 0) { 752 VLAN_IF_ERROR_RETURN( 753 bcm_vlan_translate_action_range_traverse(unit, 754 _vlan_translate_range_action_print, 755 NULL)); 756 return CMD_OK; 757 } else if (sal_strcasecmp(subcmd, "clear") == 0) { 758 VLAN_IF_ERROR_RETURN( 759 bcm_vlan_translate_action_range_delete_all(unit)); 760 return CMD_OK; 761 } 762 763 return CMD_USAGE; 764 } 765 766 STATIC int 767 _vlan_action_translate_key_get(const char *key_str) 768 { 769 int i, names; 770 771 names = sizeof(vlan_key_type_names) / sizeof(struct vlan_key_type_names); 772 773 /* Get bcm_vlan_translate_key_t key type from key type string */ 774 for (i = 1; i < names; i++) { 775 if (key_str && 776 (sal_strcasecmp(key_str, vlan_key_type_names[i].name) == 0)) { 777 return vlan_key_type_names[i].key; 778 } 779 } 780 cli_out("Invalid key type <%s>. Valid key types are:\n ", 781 key_str ? key_str : ""); 782 for (i = 1; i < names; i++) { 783 cli_out("%s ", vlan_key_type_names[i].name); 784 if (i % 7 == 0) { 785 cli_out("\n "); 786 } 787 } 788 cli_out("\n"); 789 return bcmVlanTranslateKeyInvalid; 790 } 791 792 static INLINE char * 793 _vlan_action_translate_key_name_get(bcm_vlan_translate_key_t key_type) 794 { 795 int names = sizeof(vlan_key_type_names) / sizeof(struct vlan_key_type_names); 796 return (key_type >= names ? vlan_key_type_names[0].name : 797 vlan_key_type_names[key_type].name); 798 } 799 800 STATIC int 801 _vlan_translate_action_print(int unit, bcm_gport_t gport, 802 bcm_vlan_translate_key_t key_type, 803 bcm_vlan_t outer_vlan, 804 bcm_vlan_t inner_vlan, 805 bcm_vlan_action_set_t *action, 806 void *user_data) 807 { 808 int id; 809 bcm_port_t port; 810 bcm_module_t modid; 811 bcm_trunk_t trunk; 812 813 if (action == NULL) { 814 return CMD_FAIL; 815 } 816 817 if (key_type >= bcmVlanTranslateKeyPortDouble) { 818 /* Port information only valid with Port+VID keys */ 819 VLAN_IF_ERROR_RETURN( 820 _bcm_esw_gport_resolve(unit, gport, &modid, &port, &trunk, &id)); 821 if (BCM_GPORT_IS_TRUNK(gport)) { 822 cli_out("TGID=%d, ", trunk); 823 } else { 824 cli_out("Port=%d, Modid=%d, ", port, modid); 825 } 826 } 827 cli_out("KeyType=%s, ",_vlan_action_translate_key_name_get(key_type)); 828 if (outer_vlan == BCM_VLAN_INVALID) { 829 cli_out("OldOuterVlan=--, "); 830 } else { 831 cli_out("OldOuterVlan=%d, ", outer_vlan); 832 } 833 if (inner_vlan == BCM_VLAN_INVALID) { 834 cli_out("OldInnerVlan=--\n"); 835 } else { 836 cli_out("OldInnerVlan=%d\n", inner_vlan); 837 } 838 _vlan_action_set_print(action); 839 840 return CMD_OK; 841 } 842 843 844 STATIC cmd_result_t 845 _vlan_action_translate(int unit, args_t *a) 846 { 847 char *subcmd; 848 849 if ((subcmd = ARG_GET(a)) == NULL) { 850 return CMD_USAGE; 851 } 852 853 if (sal_strcasecmp(subcmd, "egress") == 0) { 854 return _vlan_action_translate_egress(unit, a); 855 } 856 if (sal_strcasecmp(subcmd, "range") == 0) { 857 return _vlan_action_translate_range(unit, a); 858 } 859 860 861 if (sal_strcasecmp(subcmd, "add") == 0) { 862 parse_table_t pt; 863 cmd_result_t r; 864 int old_outer_vlan, old_inner_vlan, port = 0; 865 bcm_gport_t gport; 866 char *key_str = NULL; 867 bcm_vlan_translate_key_t key_type; 868 ivlan_action_set_t act; 869 bcm_vlan_action_set_t action; 870 871 _ivlan_action_set_t_init(&act); 872 parse_table_init(unit, &pt); 873 parse_table_add(&pt, "Port", PQ_PORT, 0, &port, NULL); 874 parse_table_add(&pt, "KeyType", PQ_STRING, 0, &key_str, NULL); 875 parse_table_add(&pt, "OldOuterVLan", PQ_INT, 0, &old_outer_vlan, NULL); 876 parse_table_add(&pt, "OldInnerVLan", PQ_INT, 0, &old_inner_vlan, NULL); 877 _parse_table_vlan_action_set_add(&pt, &act); 878 if (parse_arg_eq(a, &pt) < 0) { 879 cli_out("Error: invalid option %s\n", ARG_CUR(a)); 880 parse_arg_eq_done(&pt); 881 return CMD_USAGE; 882 } 883 bcm_vlan_action_set_t_init(&action); 884 r = _ivlan_to_vlan_action_set(&action, &act); 885 if (r != CMD_OK) { 886 parse_arg_eq_done(&pt); 887 cli_out("Error: invalid action\n"); 888 return r; 889 } 890 key_type = _vlan_action_translate_key_get(key_str); 891 parse_arg_eq_done(&pt); 892 if (key_type == bcmVlanTranslateKeyInvalid) { 893 cli_out("Error: invalid key\n"); 894 return CMD_FAIL; 895 } 896 897 BCM_GPORT_LOCAL_SET(gport, port); 898 VLAN_IF_ERROR_RETURN( 899 bcm_vlan_translate_action_add(unit, gport, key_type, 900 old_outer_vlan, 901 old_inner_vlan, &action)); 902 return CMD_OK; 903 904 } else if ((sal_strcasecmp(subcmd, "delete") == 0) || 905 (sal_strcasecmp(subcmd, "get") == 0)) { 906 parse_table_t pt; 907 int old_outer_vlan, old_inner_vlan, port = 0; 908 char *key_str = NULL; 909 bcm_gport_t gport; 910 bcm_vlan_translate_key_t key_type; 911 912 parse_table_init(unit, &pt); 913 parse_table_add(&pt, "Port", PQ_PORT, 0, &port, NULL); 914 parse_table_add(&pt, "KeyType", PQ_STRING, 0, &key_str, NULL); 915 parse_table_add(&pt, "OldOuterVLan", PQ_INT, 0, &old_outer_vlan, NULL); 916 parse_table_add(&pt, "OldInnerVLan", PQ_INT, 0, &old_inner_vlan, NULL); 917 if (parse_arg_eq(a, &pt) < 0) { 918 cli_out("Error: invalid option %s\n", ARG_CUR(a)); 919 parse_arg_eq_done(&pt); 920 return CMD_USAGE; 921 } 922 key_type = _vlan_action_translate_key_get(key_str); 923 parse_arg_eq_done(&pt); 924 if (key_type == bcmVlanTranslateKeyInvalid) { 925 cli_out("Error: invalid key\n"); 926 return CMD_FAIL; 927 } 928 BCM_GPORT_LOCAL_SET(gport, port); 929 if (sal_strcasecmp(subcmd, "delete") == 0) { 930 VLAN_IF_ERROR_RETURN( 931 bcm_vlan_translate_action_delete(unit, gport, key_type, 932 old_outer_vlan, 933 old_inner_vlan)); 934 return CMD_OK; 935 936 } else { 937 bcm_vlan_action_set_t action; 938 VLAN_IF_ERROR_RETURN( 939 bcm_vlan_translate_action_get(unit, gport, key_type, 940 old_outer_vlan, 941 old_inner_vlan, 942 &action)); 943 cli_out("Port=%d, KeyType=%s, OldOuterVlan=%d, OldInnerVlan=%d\n", 944 port, key_str, old_outer_vlan, old_inner_vlan); 945 _vlan_action_set_print(&action); 946 return CMD_OK; 947 } 948 949 } else if (sal_strcasecmp(subcmd, "show") == 0) { 950 VLAN_IF_ERROR_RETURN( 951 bcm_vlan_translate_action_traverse(unit, 952 _vlan_translate_action_print, 953 NULL)); 954 return CMD_OK; 955 } 956 return CMD_USAGE; 957 } 958 959 960 cmd_result_t 961 if_esw_pvlan(int u, args_t *a) 962 { 963 char *subcmd, *argpbm, *argvid; 964 vlan_id_t vid = BCM_VLAN_INVALID; 965 soc_port_t port, dport; 966 int rv; 967 bcm_pbmp_t pbmp_port_all; 968 bcm_pbmp_t pbm; 969 970 UNSUPPORTED_COMMAND(u, SOC_CHIP_BCM5670, a); 971 972 if (!sh_check_attached(ARG_CMD(a), u)) { 973 return CMD_FAIL; 974 } 975 976 BCM_PBMP_ASSIGN(pbmp_port_all, PBMP_PORT_ALL(u)); 977 978 if ((subcmd = ARG_GET(a)) == NULL) { 979 subcmd = "show"; 980 } 981 982 if ((argpbm = ARG_GET(a)) == NULL) { 983 BCM_PBMP_ASSIGN(pbm, pbmp_port_all); 984 } else { 985 if (parse_bcm_pbmp(u, argpbm, &pbm) < 0) { 986 cli_out("%s: ERROR: unrecognized port bitmap: %s\n", 987 ARG_CMD(a), argpbm); 988 return CMD_FAIL; 989 } 990 991 BCM_PBMP_AND(pbm, pbmp_port_all); 992 } 993 994 if (sal_strcasecmp(subcmd, "show") == 0) { 995 rv = BCM_E_NONE; 996 997 /* coverity[overrun-local] */ 998 DPORT_BCM_PBMP_ITER(u, pbm, dport, port) { 999 if ((rv = bcm_port_untagged_vlan_get(u, port, &vid)) < 0) { 1000 cli_out("Error retrieving info for port %s: %s\n", 1001 BCM_PORT_NAME(u, port), bcm_errmsg(rv)); 1002 break; 1003 } 1004 1005 cli_out("Port %s default VLAN is %d\n", 1006 BCM_PORT_NAME(u, port), vid); 1007 } 1008 1009 return (rv < 0) ? CMD_FAIL : CMD_OK; 1010 } else if (sal_strcasecmp(subcmd, "set") == 0) { 1011 if ((argvid = ARG_GET(a)) == NULL) { 1012 cli_out("Missing VID for set.\n"); 1013 return CMD_USAGE; 1014 } 1015 1016 vid = sal_ctoi(argvid, 0); 1017 } else { 1018 return CMD_USAGE; 1019 } 1020 1021 /* Set default VLAN as indicated */ 1022 1023 rv = BCM_E_NONE; 1024 1025 DPORT_BCM_PBMP_ITER(u, pbm, dport, port) { 1026 if ((rv = bcm_port_untagged_vlan_set(u, port, vid)) < 0) { 1027 cli_out("Error setting port %s default VLAN to %d: %s\n", 1028 BCM_PORT_NAME(u, port), vid, bcm_errmsg(rv)); 1029 1030 if ((rv == BCM_E_NOT_FOUND) || 1031 (rv == BCM_E_CONFIG)) { 1032 cli_out("VLAN %d must be created and contain the ports " 1033 "before being used for port default VLAN.\n", vid); 1034 } 1035 1036 break; 1037 } 1038 } 1039 1040 return CMD_OK; 1041 } 1042 1043 1044 1045 STATIC int 1046 _vlan_translate_print(int unit, bcm_port_t gport, bcm_vlan_t old_vid, 1047 bcm_vlan_t new_vid, int prio, void *user_data) 1048 { 1049 int rv, id; 1050 bcm_port_t port; 1051 bcm_module_t modid; 1052 bcm_trunk_t trunk; 1053 1054 rv = _bcm_esw_gport_resolve(unit, gport, &modid, &port, &trunk, &id); 1055 if (BCM_FAILURE(rv)) { 1056 cli_out("ERROR: Invalid gport =0x%x\n", gport); 1057 return CMD_FAIL; 1058 } 1059 if (BCM_GPORT_IS_TRUNK(gport)) { 1060 cli_out("u = %d, tgid = %d, old_vid = %d, new_vid = %d, prio = %d \n", 1061 unit, trunk, old_vid, new_vid, prio); 1062 } else { 1063 cli_out("u = %d, modid = %d port = %d, old_vid = %d, new_vid = %d, prio = %d \n", 1064 unit, modid, port, old_vid, new_vid, prio); 1065 } 1066 1067 return CMD_OK; 1068 } 1069 1070 STATIC int 1071 _vlan_translate_range_print(int unit, bcm_port_t gport, bcm_vlan_t old_vid_lo, 1072 bcm_vlan_t old_vid_hi, bcm_vlan_t new_vid, 1073 int prio, void *user_data) 1074 { 1075 int rv, id; 1076 bcm_port_t port; 1077 bcm_module_t modid; 1078 bcm_trunk_t trunk; 1079 1080 rv = _bcm_esw_gport_resolve(unit, gport, &modid, &port, &trunk, &id); 1081 if (BCM_FAILURE(rv)) { 1082 cli_out("ERROR: Invalid gport =0x%x\n", gport); 1083 return CMD_FAIL; 1084 } 1085 if (BCM_GPORT_IS_TRUNK(gport)) { 1086 cli_out("u = %d, tgid = %d, old_vid_lo = %d, old_vid_hi = %d, new_vid = %d, prio = %d \n", 1087 unit, trunk, old_vid_lo, old_vid_hi, new_vid, prio); 1088 } else { 1089 cli_out("u = %d, modid = %d port = %d, old_vid_lo = %d, old_vid_hi = %d, new_vid = %d, prio = %d \n", 1090 unit, modid, port, old_vid_lo, old_vid_hi, new_vid, prio); 1091 } 1092 1093 return CMD_OK; 1094 } 1095 1096 1097 cmd_result_t 1098 if_esw_vlan(int unit, args_t *a) 1099 { 1100 char *subcmd, *c; 1101 int is_untagged = 0; 1102 int r = 0; 1103 vlan_id_t id = VLAN_ID_INVALID; 1104 bcm_pbmp_t arg_ubmp; 1105 bcm_pbmp_t arg_pbmp; 1106 bcm_pbmp_t pbmp_port_all; 1107 parse_table_t pt; 1108 cmd_result_t retCode; 1109 bcm_gport_t gport = BCM_GPORT_INVALID; 1110 static char 1111 *bcm_vlan_mcast_flood_str[] = BCM_VLAN_MCAST_FLOOD_STR; 1112 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 1113 bcm_policer_t policer; 1114 #endif 1115 1116 BCM_PBMP_CLEAR(arg_ubmp); 1117 BCM_PBMP_CLEAR(arg_pbmp); 1118 1119 if (!sh_check_attached(ARG_CMD(a), unit)) { 1120 return CMD_FAIL; 1121 } 1122 1123 /* This was previously a call to bcm_port_config_get, but which was 1124 * used both to verify the port module init and to get this 1125 * port bitmap. But the port config now has 18 pbmp's in it, 1126 * which is just too many to toss on the stack. 1127 */ 1128 BCM_PBMP_ASSIGN(pbmp_port_all, PBMP_PORT_ALL(unit)); 1129 1130 if ((subcmd = ARG_GET(a)) == NULL) { 1131 return CMD_USAGE; 1132 } 1133 1134 if (sal_strcasecmp(subcmd, "create") == 0) { 1135 if ((c = ARG_GET(a)) == NULL) { 1136 return CMD_USAGE; 1137 } 1138 1139 if (!isint(c)) { 1140 cli_out("ERROR: Malformed VLAN ID \"%s\"\n", c); 1141 return CMD_FAIL; 1142 } 1143 1144 id = parse_integer(c); 1145 1146 parse_table_init(unit, &pt); 1147 parse_table_add(&pt, "PortBitMap", PQ_DFL|PQ_PBMP|PQ_BCM, 1148 (void *)(0), &arg_pbmp, NULL); 1149 parse_table_add(&pt, "UntagBitMap", PQ_DFL|PQ_PBMP|PQ_BCM, 1150 (void *)(0), &arg_ubmp, NULL); 1151 1152 if (parse_arg_eq(a, &pt) < 0 || ARG_CNT(a) > 0) { 1153 cli_out("%s: ERROR: Unknown option: %s\n", 1154 ARG_CMD(a), ARG_CUR(a)); 1155 parse_arg_eq_done(&pt); 1156 return CMD_FAIL; 1157 } 1158 parse_arg_eq_done(&pt); 1159 1160 if ((r = bcm_vlan_create(unit, id)) < 0) { 1161 goto bcm_err; 1162 } 1163 1164 if ((r = bcm_vlan_port_add(unit, id, arg_pbmp, arg_ubmp)) < 0) { 1165 goto bcm_err; 1166 } 1167 1168 return CMD_OK; 1169 } 1170 1171 if (sal_strcasecmp(subcmd, "destroy") == 0) { 1172 if ((c = ARG_GET(a)) == NULL) 1173 return CMD_USAGE; 1174 1175 id = parse_integer(c); 1176 1177 if ((r = bcm_vlan_destroy(unit, id)) < 0) 1178 goto bcm_err; 1179 1180 return CMD_OK; 1181 } 1182 1183 if (sal_strcasecmp(subcmd, "clear") == 0) { 1184 if ((r = bcm_vlan_destroy_all(unit)) < 0) { 1185 goto bcm_err; 1186 } 1187 1188 return CMD_OK; 1189 } 1190 1191 if (sal_strcasecmp(subcmd, "add") == 0 || 1192 sal_strcasecmp(subcmd, "remove") == 0) { 1193 if ((c = ARG_GET(a)) == NULL) { 1194 return CMD_USAGE; 1195 } 1196 1197 id = parse_integer(c); 1198 1199 parse_table_init(unit, &pt); 1200 parse_table_add(&pt, "PortBitMap", PQ_DFL|PQ_PBMP|PQ_BCM, 1201 (void *)(0), &arg_pbmp, NULL); 1202 if (sal_strcasecmp(subcmd, "add") == 0) { 1203 parse_table_add(&pt, "UntagBitMap", PQ_DFL|PQ_PBMP|PQ_BCM, 1204 (void *)(0), &arg_ubmp, NULL); 1205 } 1206 1207 if (!parseEndOk( a, &pt, &retCode)) { 1208 return retCode; 1209 } 1210 1211 if (sal_strcasecmp(subcmd, "remove") == 0) { 1212 if ((r = bcm_vlan_port_remove(unit, id, arg_pbmp)) < 0) { 1213 goto bcm_err; 1214 } 1215 } else { 1216 if ((r = bcm_vlan_port_add(unit, id, arg_pbmp, arg_ubmp)) < 0) { 1217 goto bcm_err; 1218 } 1219 } 1220 1221 return CMD_OK; 1222 } 1223 1224 if (sal_strcasecmp(subcmd, "gport") == 0) { 1225 subcmd = ARG_GET(a); 1226 if (subcmd == NULL) { 1227 cli_out("%s: ERROR: Missing gport subcommand\n", ARG_CMD(a)); 1228 return CMD_FAIL; 1229 } 1230 /* Check against all valid "vlan gport" subcommands. */ 1231 if ((sal_strcasecmp(subcmd, "delete") != 0) && 1232 (sal_strcasecmp(subcmd, "add") != 0) && 1233 (sal_strcasecmp(subcmd, "get") != 0) && 1234 (sal_strcasecmp(subcmd, "clear") != 0) && 1235 (sal_strcasecmp(subcmd, "show") != 0)) { 1236 cli_out("%s: ERROR: Invalid gport subcommand\n", ARG_CMD(a)); 1237 return CMD_FAIL; 1238 } 1239 1240 /* Fetch next argument, the VLAN id */ 1241 if ((c = ARG_GET(a)) == NULL) { 1242 return CMD_USAGE; 1243 } 1244 1245 /* "id" gets the vlan ID */ 1246 id = parse_integer(c); 1247 1248 if ((sal_strcasecmp(subcmd, "clear") != 0) && 1249 (sal_strcasecmp(subcmd, "show") != 0)) { 1250 /* "clear" and "show" do not need a gport parameter, the others do */ 1251 gport = 0; 1252 parse_table_init(unit, &pt); 1253 parse_table_add(&pt, "PortID", PQ_DFL | PQ_PORT, 1254 (void *) (0), &gport, NULL); 1255 1256 if (!parseEndOk(a, &pt, &retCode)) { 1257 return retCode; 1258 } 1259 } 1260 1261 if (sal_strcasecmp(subcmd, "delete") == 0) { 1262 if ((r = bcm_vlan_gport_delete(unit, id, gport)) < 0) { 1263 goto bcm_err; 1264 } 1265 } else if (sal_strcasecmp(subcmd, "add") == 0) { 1266 if ((r = bcm_vlan_gport_add(unit, id, gport, 0)) < 0) { 1267 goto bcm_err; 1268 } 1269 } else if (sal_strcasecmp(subcmd, "get") == 0) { 1270 if ((r = bcm_vlan_gport_get(unit, id, gport, &is_untagged)) < 0) { 1271 goto bcm_err; 1272 } 1273 } else if (sal_strcasecmp(subcmd, "clear") == 0) { 1274 if ((r = bcm_vlan_gport_delete_all(unit, id)) < 0) { 1275 goto bcm_err; 1276 } 1277 } else if (sal_strcasecmp(subcmd, "show") == 0) { 1278 const int max = BCM_PBMP_PORT_MAX; 1279 int i, count, alloc_size; 1280 bcm_gport_t *port_array; 1281 int *is_untagged_array; 1282 1283 /* Don't put giant port arrays on the stack */ 1284 alloc_size = BCM_PBMP_PORT_MAX * sizeof(*port_array); 1285 port_array = sal_alloc(alloc_size, "CLI VLAN show ports"); 1286 if (NULL == port_array) { 1287 r = BCM_E_MEMORY; 1288 goto bcm_err; 1289 } 1290 1291 alloc_size = BCM_PBMP_PORT_MAX * sizeof(*is_untagged_array); 1292 is_untagged_array = sal_alloc(alloc_size, 1293 "CLI VLAN show untagged ports"); 1294 if (NULL == is_untagged_array) { 1295 sal_free(port_array); 1296 r = BCM_E_MEMORY; 1297 goto bcm_err; 1298 } 1299 1300 /* Get all virtual and physical ports from the specified VLAN */ 1301 r = bcm_vlan_gport_get_all(unit, id, max, port_array, 1302 is_untagged_array, &count); 1303 1304 if (0 <= r) { 1305 /* 1306 * Count will always be non-zero 1307 * (BCM_E_NOT_FOUND returned when 1308 * VLAN is valid but has no associated ports). 1309 */ 1310 cli_out("Virtual and physical ports defined for VLAN: %d\n", 1311 id); 1312 for (i = 0; i < count; i++) { 1313 /* port name is empty string if port is not local */ 1314 const char *port_name = mod_port_name(unit, -1, 1315 port_array[i]); 1316 1317 if (*port_name) { 1318 cli_out(" %4s (%stagged)\n", port_name, 1319 is_untagged_array[i] ? "un" : ""); 1320 } 1321 } 1322 } 1323 1324 sal_free(port_array); 1325 sal_free(is_untagged_array); 1326 if (r < 0) { 1327 goto bcm_err; 1328 } 1329 } 1330 return CMD_OK; 1331 } 1332 1333 if (sal_strcasecmp(subcmd, "MulticastFlood") == 0) { 1334 bcm_vlan_mcast_flood_t mode; 1335 if ((c = ARG_GET(a)) == NULL) { 1336 return CMD_USAGE; 1337 } 1338 1339 id = parse_integer(c); 1340 if ((c = ARG_GET(a)) == NULL) { 1341 if ((r = bcm_vlan_mcast_flood_get(unit, id, &mode)) < 0) { 1342 goto bcm_err; 1343 } 1344 cli_out("vlan %d Multicast Flood Mode is %s\n", 1345 id, bcm_vlan_mcast_flood_str[mode]); 1346 return CMD_OK; 1347 } 1348 mode = parse_integer(c); 1349 if ((r = bcm_vlan_mcast_flood_set(unit, id, mode)) < 0) { 1350 goto bcm_err; 1351 } 1352 return CMD_OK; 1353 } 1354 1355 if (sal_strcasecmp(subcmd, "show") == 0) { 1356 bcm_vlan_data_t *list; 1357 int count, i, alloc_bufp, alloc_pfmtp; 1358 char *bufp = NULL; 1359 char *pfmtp = NULL; 1360 1361 if ((c = ARG_GET(a)) != NULL) { 1362 id = parse_integer(c); 1363 } 1364 1365 if ((r = bcm_vlan_list(unit, &list, &count)) < 0) { 1366 goto bcm_err; 1367 } 1368 1369 /* Don't put giant port arrays on the stack */ 1370 alloc_bufp = FORMAT_PBMP_MAX * sizeof(*bufp); 1371 bufp = sal_alloc(alloc_bufp, "CLI VLAN show port format"); 1372 if (NULL == bufp) { 1373 r = BCM_E_MEMORY; 1374 } 1375 1376 if (BCM_SUCCESS(r)) { 1377 alloc_pfmtp = SOC_PBMP_FMT_LEN * sizeof(*pfmtp); 1378 pfmtp = sal_alloc(alloc_pfmtp, "CLI VLAN show pbmp format"); 1379 if (NULL == pfmtp) { 1380 r = BCM_E_MEMORY; 1381 } 1382 } 1383 1384 if (BCM_SUCCESS(r)) { 1385 for (i = 0; i < count; i++) { 1386 if (id == VLAN_ID_INVALID || list[i].vlan_tag == id) { 1387 bcm_vlan_mcast_flood_t mode; 1388 if ((r = bcm_vlan_mcast_flood_get(unit, 1389 list[i].vlan_tag, 1390 &mode)) < 0) { 1391 if (r == BCM_E_UNAVAIL) { 1392 mode = BCM_VLAN_MCAST_FLOOD_COUNT; 1393 r = BCM_E_NONE; 1394 } else { 1395 break; 1396 } 1397 } 1398 format_bcm_pbmp(unit, bufp, alloc_bufp, 1399 list[i].port_bitmap); 1400 cli_out("vlan %d\tports %s (%s), ", 1401 list[i].vlan_tag, 1402 bufp, SOC_PBMP_FMT(list[i].port_bitmap, pfmtp)); 1403 1404 format_bcm_pbmp(unit, bufp, alloc_bufp, 1405 list[i].ut_port_bitmap); 1406 cli_out("untagged %s (%s) %s\n", 1407 bufp, SOC_PBMP_FMT(list[i].ut_port_bitmap, pfmtp), 1408 bcm_vlan_mcast_flood_str[mode]); 1409 } 1410 } 1411 } 1412 1413 if (NULL != pfmtp) { 1414 sal_free(pfmtp); 1415 } 1416 if (NULL != bufp) { 1417 sal_free(bufp); 1418 } 1419 bcm_vlan_list_destroy(unit, list, count); 1420 if (BCM_FAILURE(r)) { 1421 goto bcm_err; 1422 } 1423 1424 return CMD_OK; 1425 } 1426 1427 if (sal_strcasecmp(subcmd, "default") == 0) { 1428 if ((c = ARG_GET(a)) != NULL) { 1429 id = parse_integer(c); 1430 } 1431 1432 if (id == VLAN_ID_INVALID) { 1433 if ((r = bcm_vlan_default_get(unit, &id)) < 0) { 1434 goto bcm_err; 1435 } 1436 1437 cli_out("Default VLAN ID is %d\n", id); 1438 } else { 1439 if ((r = bcm_vlan_default_set(unit, id)) < 0) { 1440 goto bcm_err; 1441 } 1442 1443 cli_out("Default VLAN ID set to %d\n", id); 1444 } 1445 1446 return CMD_OK; 1447 } 1448 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 1449 if (sal_strcasecmp(subcmd, "policer") == 0) { 1450 subcmd = ARG_GET(a); 1451 if (subcmd == NULL) { 1452 cli_out("%s: ERROR: missing policer subcommand\n", ARG_CMD(a)); 1453 return CMD_FAIL; 1454 } 1455 1456 if (sal_strcasecmp(subcmd, "set") == 0) { 1457 if ((c = ARG_GET(a)) != NULL) { 1458 id = parse_integer(c); 1459 } else { 1460 return CMD_FAIL; 1461 } 1462 parse_table_init(unit, &pt); 1463 parse_table_add(&pt, "POLICER", PQ_HEX, 0, &policer, NULL); 1464 if (!parseEndOk( a, &pt, &retCode)) { 1465 cli_out("Usages: vlan policer set <id> POLICER=<policer>\n"); 1466 return retCode; 1467 } 1468 r = bcm_vlan_policer_set(unit, id, policer); 1469 if( 0 == r) { 1470 cli_out(" Policer id=%x is set to Vlan %x\n", policer,id); 1471 } else { 1472 cli_out(" Policer id=%x set to Vlan %x failed\n", policer,id); 1473 } 1474 return CMD_OK; 1475 } 1476 if (sal_strcasecmp(subcmd, "get") == 0) { 1477 if ((c = ARG_GET(a)) != NULL) { 1478 id = parse_integer(c); 1479 } else { 1480 return CMD_FAIL; 1481 } 1482 r = bcm_vlan_policer_get(unit, id, &policer); 1483 if(0 == r) { 1484 cli_out(" Policer id=%x is set in Vlan %x\n", policer,id); 1485 } else { 1486 cli_out(" Get Policer from Vlan %x failed\n", id); 1487 } 1488 return CMD_OK; 1489 } 1490 1491 cli_out("%s: ERROR: unknown policer subcommand: %s\n", 1492 ARG_CMD(a), subcmd); 1493 1494 return CMD_FAIL; 1495 } 1496 1497 1498 #endif 1499 1500 /* Protocol vlan selection */ 1501 if (sal_strcasecmp(subcmd, "protocol") == 0 || 1502 sal_strcasecmp(subcmd, "proto") == 0) { 1503 1504 subcmd = ARG_GET(a); 1505 if (subcmd == NULL) { 1506 cli_out("%s: ERROR: missing protocol subcommand\n", ARG_CMD(a)); 1507 return CMD_FAIL; 1508 } 1509 1510 if (sal_strcasecmp(subcmd, "add") == 0) { 1511 bcm_pbmp_t pbmp; 1512 bcm_port_t port, dport; 1513 int frame, ether, vlan, prio; 1514 1515 parse_table_init(unit, &pt); 1516 parse_table_add(&pt, "PortBitMap", PQ_PBMP|PQ_BCM, 0, &pbmp, NULL); 1517 parse_table_add(&pt, "Frame", PQ_INT, 0, &frame, NULL); 1518 parse_table_add(&pt, "Ether", PQ_HEX, 0, ðer, NULL); 1519 parse_table_add(&pt, "VLan", PQ_INT, 0, &vlan, NULL); 1520 parse_table_add(&pt, "Prio", PQ_INT, 0, &prio, NULL); 1521 if (!parseEndOk( a, &pt, &retCode)) { 1522 return retCode; 1523 } 1524 1525 DPORT_BCM_PBMP_ITER(unit, pbmp, dport, port) { 1526 if ((r = bcm_port_protocol_vlan_add(unit, port, frame, 1527 ether, vlan)) < 0) { 1528 goto bcm_err; 1529 } 1530 } 1531 return CMD_OK; 1532 } 1533 1534 if (sal_strcasecmp(subcmd, "delete") == 0) { 1535 bcm_pbmp_t pbmp; 1536 bcm_port_t port, dport; 1537 int frame, ether; 1538 1539 parse_table_init(unit, &pt); 1540 parse_table_add(&pt, "PortBitMap", PQ_PBMP|PQ_BCM, 0, &pbmp, NULL); 1541 parse_table_add(&pt, "Frame", PQ_INT, 0, &frame, NULL); 1542 parse_table_add(&pt, "Ether", PQ_HEX, 0, ðer, NULL); 1543 if (!parseEndOk( a, &pt, &retCode)) { 1544 return retCode; 1545 } 1546 1547 DPORT_BCM_PBMP_ITER(unit, pbmp, dport, port) { 1548 if ((r = bcm_port_protocol_vlan_delete(unit, port, frame, 1549 ether)) < 0) { 1550 goto bcm_err; 1551 } 1552 } 1553 return CMD_OK; 1554 } 1555 1556 if (sal_strcasecmp(subcmd, "clear") == 0) { 1557 bcm_pbmp_t pbmp; 1558 bcm_port_t port, dport; 1559 1560 parse_table_init(unit, &pt); 1561 parse_table_add(&pt, "PortBitMap", PQ_PBMP|PQ_BCM, 0, &pbmp, NULL); 1562 if (!parseEndOk( a, &pt, &retCode)) { 1563 cli_out("Usages: vlan protocol clear PortBitMap=<pbmp>\n"); 1564 return retCode; 1565 } 1566 1567 /* coverity[overrun-local] */ 1568 DPORT_BCM_PBMP_ITER(unit, pbmp, dport, port) { 1569 if ((r = bcm_port_protocol_vlan_delete_all(unit, 1570 port)) < 0) { 1571 goto bcm_err; 1572 } 1573 } 1574 return CMD_OK; 1575 } 1576 1577 cli_out("%s: ERROR: unknown protocol subcommand: %s\n", 1578 ARG_CMD(a), subcmd); 1579 1580 return CMD_FAIL; 1581 } 1582 1583 /* MAC address vlan selection */ 1584 if (sal_strcasecmp(subcmd, "mac") == 0) { 1585 subcmd = ARG_GET(a); 1586 if (subcmd == NULL) { 1587 cli_out("%s: ERROR: missing mac subcommand\n", ARG_CMD(a)); 1588 return CMD_FAIL; 1589 } 1590 1591 if (sal_strcasecmp(subcmd, "add") == 0) { 1592 bcm_mac_t mac; 1593 int vlan, prio, cng; 1594 1595 parse_table_init(unit, &pt); 1596 parse_table_add(&pt, "MACaddress", PQ_MAC, 0, &mac, NULL); 1597 parse_table_add(&pt, "VLan", PQ_INT, 0, &vlan, NULL); 1598 parse_table_add(&pt, "Prio", PQ_INT, 0, &prio, NULL); 1599 parse_table_add(&pt, "Cng", PQ_INT, 0, &cng, NULL); 1600 1601 if (!parseEndOk( a, &pt, &retCode)) { 1602 return retCode; 1603 } 1604 1605 if (cng) { 1606 prio |= BCM_PRIO_DROP_FIRST; 1607 } 1608 1609 if ((r = bcm_vlan_mac_add(unit, mac, vlan, prio)) < 0) { 1610 goto bcm_err; 1611 } 1612 1613 return CMD_OK; 1614 } 1615 1616 if (sal_strcasecmp(subcmd, "delete") == 0) { 1617 bcm_mac_t mac; 1618 1619 parse_table_init(unit, &pt); 1620 parse_table_add(&pt, "MACaddress", PQ_MAC, 0, &mac, NULL); 1621 1622 if (!parseEndOk( a, &pt, &retCode)) { 1623 return retCode; 1624 } 1625 1626 if ((r = bcm_vlan_mac_delete(unit, mac)) < 0) { 1627 goto bcm_err; 1628 } 1629 1630 return CMD_OK; 1631 } 1632 1633 if (sal_strcasecmp(subcmd, "clear") == 0) { 1634 if ((r = bcm_vlan_mac_delete_all(unit)) < 0) { 1635 goto bcm_err; 1636 } 1637 1638 return CMD_OK; 1639 } 1640 1641 cli_out("%s: ERROR: Unknown MAC subcommand: %s\n", ARG_CMD(a), subcmd); 1642 1643 return CMD_FAIL; 1644 } 1645 1646 /* VLAN translate selection */ 1647 if (sal_strcasecmp(subcmd, "translate") == 0) { 1648 subcmd = ARG_GET(a); 1649 if (subcmd == NULL) { 1650 cli_out("%s: ERROR: Missing translate subcommand\n", ARG_CMD(a)); 1651 return CMD_FAIL; 1652 } 1653 1654 if (sal_strcasecmp(subcmd, "On") == 0) { 1655 if ((r = bcm_vlan_control_set(unit, bcmVlanTranslate, 1656 TRUE)) < 0) { 1657 goto bcm_err; 1658 } 1659 1660 return CMD_OK; 1661 } 1662 1663 if (sal_strcasecmp(subcmd, "Off") == 0) { 1664 if ((r = bcm_vlan_control_set(unit, bcmVlanTranslate, 1665 FALSE)) < 0) { 1666 goto bcm_err; 1667 } 1668 1669 return CMD_OK; 1670 } 1671 1672 if (sal_strcasecmp(subcmd, "add") == 0) { 1673 int port = 0, old_vlan = 1, new_vlan = 1, prio = 0, cng = 0; 1674 1675 parse_table_init(unit, &pt); 1676 parse_table_add(&pt, "Port", PQ_PORT, 0, &port, NULL); 1677 parse_table_add(&pt, "OldVLan", PQ_INT, 0, &old_vlan, NULL); 1678 parse_table_add(&pt, "NewVLan", PQ_INT, 0, &new_vlan, NULL); 1679 parse_table_add(&pt, "Prio", PQ_INT, 0, &prio, NULL); 1680 parse_table_add(&pt, "Cng", PQ_INT, 0, &cng, NULL); 1681 1682 if (!parseEndOk( a, &pt, &retCode)) { 1683 return retCode; 1684 } 1685 1686 if (cng) { 1687 prio |= BCM_PRIO_DROP_FIRST; 1688 } 1689 1690 if ((r = bcm_vlan_translate_add(unit, port, 1691 old_vlan, new_vlan, prio)) < 0) { 1692 goto bcm_err; 1693 } 1694 1695 return CMD_OK; 1696 } 1697 1698 if (sal_strcasecmp(subcmd, "get") == 0) { 1699 int port = 0, prio = 0; 1700 int old_vlan = 1; 1701 bcm_vlan_t new_vlan = 1; 1702 1703 parse_table_init(unit, &pt); 1704 parse_table_add(&pt, "Port", PQ_PORT, 0, &port, NULL); 1705 parse_table_add(&pt, "OldVlan", PQ_INT, 0, &old_vlan, NULL); 1706 1707 if (!parseEndOk( a, &pt, &retCode)) { 1708 return retCode; 1709 } 1710 1711 if (!BCM_VLAN_VALID(old_vlan)) { 1712 goto bcm_err; 1713 } 1714 if ((r = bcm_vlan_translate_get(unit, port, 1715 (bcm_vlan_t)old_vlan, 1716 &new_vlan, 1717 &prio)) < 0) { 1718 goto bcm_err; 1719 } 1720 1721 cli_out("New Vlan ID = %d, Priority = %d\n", new_vlan, prio); 1722 return CMD_OK; 1723 } 1724 1725 if (sal_strcasecmp(subcmd, "show") == 0) { 1726 1727 parse_table_init(unit, &pt); 1728 1729 if ((r = bcm_vlan_translate_traverse(unit, _vlan_translate_print, 1730 NULL)) < 0) { 1731 goto bcm_err; 1732 } 1733 return CMD_OK; 1734 } 1735 1736 if (sal_strcasecmp(subcmd, "delete") == 0) { 1737 int port = 0, old_vlan = 1; 1738 1739 parse_table_init(unit, &pt); 1740 parse_table_add(&pt, "Port", PQ_PORT, 0, &port, NULL); 1741 parse_table_add(&pt, "OldVLan", PQ_INT, 0, &old_vlan, NULL); 1742 1743 if (!parseEndOk( a, &pt, &retCode)) { 1744 return retCode; 1745 } 1746 1747 if ((r = bcm_vlan_translate_delete(unit, port, old_vlan)) < 0) { 1748 goto bcm_err; 1749 } 1750 1751 return CMD_OK; 1752 } 1753 1754 if (sal_strcasecmp(subcmd, "clear") == 0) { 1755 if ((r = bcm_vlan_translate_delete_all(unit)) < 0) { 1756 goto bcm_err; 1757 } 1758 1759 return CMD_OK; 1760 } 1761 1762 if (sal_strcasecmp(subcmd, "egress") == 0) { 1763 char * subsubcmd = ARG_GET(a); 1764 if (subsubcmd == NULL) { 1765 cli_out("%s: ERROR: Missing translate egress subcommand\n", 1766 ARG_CMD(a)); 1767 return CMD_FAIL; 1768 } 1769 1770 if (sal_strcasecmp(subsubcmd, "add") == 0) { 1771 int port = 0, old_vlan = 1, new_vlan = 1, prio = 0, cng = 0; 1772 1773 parse_table_init(unit, &pt); 1774 parse_table_add(&pt, "Port", PQ_PORT, 0, &port, NULL); 1775 parse_table_add(&pt, "OldVLan", PQ_INT, 0, &old_vlan, NULL); 1776 parse_table_add(&pt, "NewVLan", PQ_INT, 0, &new_vlan, NULL); 1777 parse_table_add(&pt, "Prio", PQ_INT, 0, &prio, NULL); 1778 parse_table_add(&pt, "Cng", PQ_INT, 0, &cng, NULL); 1779 1780 if (!parseEndOk( a, &pt, &retCode)) { 1781 return retCode; 1782 } 1783 1784 if (cng) { 1785 prio |= BCM_PRIO_DROP_FIRST; 1786 } 1787 1788 if ((r = bcm_vlan_translate_egress_add(unit, port, 1789 old_vlan, new_vlan, prio)) < 0) { 1790 goto bcm_err; 1791 } 1792 1793 return CMD_OK; 1794 } 1795 if (sal_strcasecmp(subsubcmd, "get") == 0) { 1796 int port = 0, prio = 0; 1797 int old_vlan = 1; 1798 bcm_vlan_t new_vlan = 1; 1799 1800 parse_table_init(unit, &pt); 1801 parse_table_add(&pt, "Port", PQ_PORT, 0, &port, NULL); 1802 parse_table_add(&pt, "OldVLan", PQ_INT, 0, &old_vlan, NULL); 1803 1804 if (!parseEndOk( a, &pt, &retCode)) { 1805 return retCode; 1806 } 1807 1808 if (!BCM_VLAN_VALID(old_vlan)) { 1809 goto bcm_err; 1810 } 1811 if ((r = bcm_vlan_translate_egress_get(unit, port, 1812 (bcm_vlan_t)old_vlan, 1813 &new_vlan, 1814 &prio)) < 0) { 1815 goto bcm_err; 1816 } 1817 1818 cli_out("New Vlan ID = %d, Priority = %d\n", new_vlan, prio); 1819 return CMD_OK; 1820 } 1821 1822 if (sal_strcasecmp(subsubcmd, "show") == 0) { 1823 1824 parse_table_init(unit, &pt); 1825 1826 if ((r = bcm_vlan_translate_egress_traverse(unit, 1827 _vlan_translate_print, 1828 NULL)) < 0) { 1829 goto bcm_err; 1830 } 1831 return CMD_OK; 1832 } 1833 1834 if (sal_strcasecmp(subsubcmd, "delete") == 0) { 1835 int port = 0, old_vlan = 1; 1836 1837 parse_table_init(unit, &pt); 1838 parse_table_add(&pt, "Port", PQ_PORT, 0, &port, NULL); 1839 parse_table_add(&pt, "OldVLan", PQ_INT, 0, &old_vlan, NULL); 1840 1841 if (!parseEndOk( a, &pt, &retCode)) { 1842 return retCode; 1843 } 1844 1845 if ((r = bcm_vlan_translate_egress_delete(unit, port, 1846 old_vlan)) < 0) { 1847 goto bcm_err; 1848 } 1849 1850 return CMD_OK; 1851 } 1852 1853 if (sal_strcasecmp(subsubcmd, "clear") == 0) { 1854 if ((r = bcm_vlan_translate_egress_delete_all(unit)) < 0) { 1855 goto bcm_err; 1856 } 1857 1858 return CMD_OK; 1859 } 1860 } 1861 1862 if (sal_strcasecmp(subcmd, "dtag") == 0) { 1863 char * subsubcmd = ARG_GET(a); 1864 if (subsubcmd == NULL) { 1865 cli_out("%s: ERROR: Missing translate dtag subcommand\n", 1866 ARG_CMD(a)); 1867 return CMD_FAIL; 1868 } 1869 1870 if (sal_strcasecmp(subsubcmd, "add") == 0) { 1871 int port = 0, old_vlan = 1, new_vlan = 1, prio = 0, cng = 0; 1872 1873 parse_table_init(unit, &pt); 1874 parse_table_add(&pt, "Port", PQ_PORT, 0, &port, NULL); 1875 parse_table_add(&pt, "OldVLan", PQ_INT, 0, &old_vlan, NULL); 1876 parse_table_add(&pt, "NewVLan", PQ_INT, 0, &new_vlan, NULL); 1877 parse_table_add(&pt, "Prio", PQ_INT, 0, &prio, NULL); 1878 parse_table_add(&pt, "Cng", PQ_INT, 0, &cng, NULL); 1879 1880 if (!parseEndOk( a, &pt, &retCode)) { 1881 return retCode; 1882 } 1883 1884 if (cng) { 1885 prio |= BCM_PRIO_DROP_FIRST; 1886 } 1887 1888 if ((r = bcm_vlan_dtag_add(unit, port, 1889 old_vlan, new_vlan, prio)) < 0) { 1890 goto bcm_err; 1891 } 1892 1893 return CMD_OK; 1894 } 1895 1896 if (sal_strcasecmp(subsubcmd, "get") == 0) { 1897 int port = 0, prio = 0; 1898 int old_vlan = 1; 1899 bcm_vlan_t new_vlan = 1; 1900 1901 parse_table_init(unit, &pt); 1902 parse_table_add(&pt, "Port", PQ_PORT, 0, &port, NULL); 1903 parse_table_add(&pt, "OldVLan", PQ_INT, 0, &old_vlan, NULL); 1904 1905 if (!parseEndOk( a, &pt, &retCode)) { 1906 return retCode; 1907 } 1908 1909 if (!BCM_VLAN_VALID(old_vlan)) { 1910 goto bcm_err; 1911 } 1912 if ((r = bcm_vlan_dtag_get(unit, port, (bcm_vlan_t)old_vlan, 1913 &new_vlan, &prio)) < 0) { 1914 goto bcm_err; 1915 } 1916 1917 cli_out("New Vlan ID = %d, Priority = %d\n", new_vlan, prio); 1918 return CMD_OK; 1919 } 1920 1921 if (sal_strcasecmp(subsubcmd, "show") == 0) { 1922 1923 parse_table_init(unit, &pt); 1924 1925 if ((r = bcm_vlan_dtag_traverse(unit, _vlan_translate_print, 1926 NULL)) < 0) { 1927 goto bcm_err; 1928 } 1929 return CMD_OK; 1930 } 1931 if (sal_strcasecmp(subsubcmd, "delete") == 0) { 1932 int port=0, old_vlan=1; 1933 1934 parse_table_init(unit, &pt); 1935 parse_table_add(&pt, "Port", PQ_PORT, 0, &port, NULL); 1936 parse_table_add(&pt, "OldVLan", PQ_INT, 0, &old_vlan, NULL); 1937 1938 if (!parseEndOk( a, &pt, &retCode)) { 1939 return retCode; 1940 } 1941 1942 if ((r = bcm_vlan_dtag_delete(unit, port, old_vlan)) < 0) { 1943 goto bcm_err; 1944 } 1945 1946 return CMD_OK; 1947 } 1948 1949 if (sal_strcasecmp(subsubcmd, "clear") == 0) { 1950 if ((r = bcm_vlan_dtag_delete_all(unit)) < 0) { 1951 goto bcm_err; 1952 } 1953 1954 return CMD_OK; 1955 } 1956 } 1957 1958 1959 if (sal_strcasecmp(subcmd, "range") == 0) { 1960 char * subsubcmd = ARG_GET(a); 1961 if (subsubcmd == NULL) { 1962 cli_out("%s: ERROR: Missing translate range subcommand\n", 1963 ARG_CMD(a)); 1964 return CMD_FAIL; 1965 } 1966 1967 if (sal_strcasecmp(subsubcmd, "add") == 0) { 1968 int old_vlan_lo = 1, old_vlan_hi = 1; 1969 int port = 0, new_vlan = 1, prio = 0, cng = 0; 1970 1971 parse_table_init(unit, &pt); 1972 parse_table_add(&pt, "Port", PQ_PORT, 0, &port, NULL); 1973 parse_table_add(&pt, "OldVLanLo", PQ_INT, 0, &old_vlan_lo, NULL); 1974 parse_table_add(&pt, "OldVLanHi", PQ_INT, 0, &old_vlan_hi, NULL); 1975 parse_table_add(&pt, "NewVLan", PQ_INT, 0, &new_vlan, NULL); 1976 parse_table_add(&pt, "Prio", PQ_INT, 0, &prio, NULL); 1977 parse_table_add(&pt, "Cng", PQ_INT, 0, &cng, NULL); 1978 1979 if (!parseEndOk( a, &pt, &retCode)) { 1980 return retCode; 1981 } 1982 1983 if (cng) { 1984 prio |= BCM_PRIO_DROP_FIRST; 1985 } 1986 1987 if (!BCM_VLAN_VALID(old_vlan_lo) || 1988 !BCM_VLAN_VALID(old_vlan_hi) || 1989 !BCM_VLAN_VALID(new_vlan)) { 1990 goto bcm_err; 1991 } 1992 1993 if ((r = bcm_vlan_translate_range_add(unit, port, old_vlan_lo, 1994 old_vlan_hi, new_vlan, 1995 prio)) < 0) { 1996 goto bcm_err; 1997 } 1998 1999 return CMD_OK; 2000 } 2001 2002 if (sal_strcasecmp(subsubcmd, "get") == 0) { 2003 int port = 0, prio = 0; 2004 int old_vlan_lo = 1, old_vlan_hi = 1; 2005 bcm_vlan_t new_vlan = 1; 2006 2007 parse_table_init(unit, &pt); 2008 parse_table_add(&pt, "Port", PQ_PORT, 0, &port, NULL); 2009 parse_table_add(&pt, "OldVLanLo", PQ_INT, 0, &old_vlan_lo, NULL); 2010 parse_table_add(&pt, "OldVLanHi", PQ_INT, 0, &old_vlan_hi, NULL); 2011 2012 if (!parseEndOk( a, &pt, &retCode)) { 2013 return retCode; 2014 } 2015 2016 if (!BCM_VLAN_VALID(old_vlan_lo) || 2017 !BCM_VLAN_VALID(old_vlan_hi)) { 2018 goto bcm_err; 2019 } 2020 if ((r = bcm_vlan_translate_range_get(unit, port, 2021 (bcm_vlan_t)old_vlan_lo, 2022 (bcm_vlan_t)old_vlan_hi, 2023 &new_vlan, &prio)) < 0) { 2024 goto bcm_err; 2025 } 2026 2027 cli_out("New Vlan ID = %d, Priority = %d\n", new_vlan, prio); 2028 return CMD_OK; 2029 } 2030 2031 if (sal_strcasecmp(subsubcmd, "show") == 0) { 2032 if ((r = bcm_vlan_translate_range_traverse(unit, 2033 _vlan_translate_range_print, 2034 NULL)) < 0) { 2035 goto bcm_err; 2036 } 2037 return CMD_OK; 2038 } 2039 2040 if (sal_strcasecmp(subsubcmd, "delete") == 0) { 2041 int port = 0, old_vlan_lo = 1, old_vlan_hi = 1; 2042 2043 parse_table_init(unit, &pt); 2044 parse_table_add(&pt, "Port", PQ_PORT, 0, &port, NULL); 2045 parse_table_add(&pt, "OldVLanLo", PQ_INT, 0, &old_vlan_lo, NULL); 2046 parse_table_add(&pt, "OldVLanHi", PQ_INT, 0, &old_vlan_hi, NULL); 2047 2048 if (!parseEndOk( a, &pt, &retCode)) { 2049 return retCode; 2050 } 2051 2052 if (!BCM_VLAN_VALID(old_vlan_lo) || 2053 !BCM_VLAN_VALID(old_vlan_hi)) { 2054 goto bcm_err; 2055 } 2056 2057 if ((r = bcm_vlan_translate_range_delete(unit, port, old_vlan_lo, 2058 old_vlan_hi)) < 0) { 2059 goto bcm_err; 2060 } 2061 2062 return CMD_OK; 2063 } 2064 2065 if (sal_strcasecmp(subsubcmd, "clear") == 0) { 2066 if ((r = bcm_vlan_translate_range_delete_all(unit)) < 0) { 2067 goto bcm_err; 2068 } 2069 2070 return CMD_OK; 2071 } 2072 } 2073 2074 /**************************************************************************************************/ 2075 2076 cli_out("%s: ERROR: Unknown translate subcommand: %s\n", 2077 ARG_CMD(a), subcmd); 2078 2079 return CMD_FAIL; 2080 } 2081 2082 /* IP4 subnet based vlan selection */ 2083 if (sal_strcasecmp(subcmd, "ip4") == 0 || 2084 sal_strcasecmp(subcmd, "ip") == 0) { 2085 subcmd = ARG_GET(a); 2086 if (subcmd == NULL) { 2087 cli_out("%s: ERROR: missing ip4 subcommand\n", ARG_CMD(a)); 2088 return CMD_FAIL; 2089 } 2090 2091 if (sal_strcasecmp(subcmd, "add") == 0) { 2092 bcm_ip_t ipaddr, subnet; 2093 int vlan, prio, cng; 2094 bcm_vlan_ip_t vlan_ip; 2095 2096 parse_table_init(unit, &pt); 2097 parse_table_add(&pt, "IPaddr", PQ_IP, 0, &ipaddr, NULL); 2098 parse_table_add(&pt, "NetMask", PQ_IP, 0, &subnet, NULL); 2099 parse_table_add(&pt, "VLan", PQ_INT, 0, &vlan, NULL); 2100 parse_table_add(&pt, "Prio", PQ_INT, 0, &prio, NULL); 2101 parse_table_add(&pt, "Cng", PQ_INT, 0, &cng, NULL); 2102 2103 if (!parseEndOk( a, &pt, &retCode)) { 2104 return retCode; 2105 } 2106 if (cng) { 2107 prio |= BCM_PRIO_DROP_FIRST; 2108 } 2109 2110 bcm_vlan_ip_t_init(&vlan_ip); 2111 vlan_ip.ip4 = ipaddr; 2112 vlan_ip.mask = subnet; 2113 vlan_ip.vid = vlan; 2114 vlan_ip.prio = prio; 2115 2116 if ((r = bcm_vlan_ip_add(unit, &vlan_ip)) < 0) { 2117 goto bcm_err; 2118 } 2119 2120 return CMD_OK; 2121 } 2122 2123 if (sal_strcasecmp(subcmd, "delete") == 0) { 2124 bcm_ip_t ipaddr, subnet; 2125 bcm_vlan_ip_t vlan_ip; 2126 2127 parse_table_init(unit, &pt); 2128 parse_table_add(&pt, "IPaddr", PQ_IP, 0, &ipaddr, NULL); 2129 parse_table_add(&pt, "NetMask", PQ_IP, 0, &subnet, NULL); 2130 2131 if (!parseEndOk( a, &pt, &retCode)) { 2132 return retCode; 2133 } 2134 2135 bcm_vlan_ip_t_init(&vlan_ip); 2136 vlan_ip.ip4 = ipaddr; 2137 vlan_ip.mask = subnet; 2138 2139 if ((r = bcm_vlan_ip_delete(unit, &vlan_ip)) < 0) { 2140 goto bcm_err; 2141 } 2142 2143 return CMD_OK; 2144 } 2145 2146 if (sal_strcasecmp(subcmd, "clear") == 0) { 2147 if ((r = bcm_vlan_ip_delete_all(unit)) < 0) { 2148 goto bcm_err; 2149 } 2150 2151 return CMD_OK; 2152 } 2153 2154 cli_out("%s: ERROR: Unknown ip4 subcommand: %s\n", ARG_CMD(a), subcmd); 2155 2156 return CMD_FAIL; 2157 } 2158 2159 if (sal_strcasecmp(subcmd, "ip6") == 0) { 2160 subcmd = ARG_GET(a); 2161 if (subcmd == NULL) { 2162 cli_out("%s: ERROR: missing ip6 subcommand\n", ARG_CMD(a)); 2163 return CMD_FAIL; 2164 } 2165 2166 if (sal_strcasecmp(subcmd, "add") == 0) { 2167 bcm_vlan_ip_t ipaddr; 2168 2169 parse_table_init(unit, &pt); 2170 parse_table_add(&pt, "IPaddr", PQ_IP6, 0, &ipaddr.ip6, NULL); 2171 parse_table_add(&pt, "prefiX", PQ_INT, 0, &ipaddr.prefix, NULL); 2172 parse_table_add(&pt, "VLan", PQ_INT, 0, &ipaddr.vid, NULL); 2173 parse_table_add(&pt, "Prio", PQ_INT, 0, &ipaddr.prio, NULL); 2174 2175 if (!parseEndOk( a, &pt, &retCode)) { 2176 return retCode; 2177 } 2178 ipaddr.flags = BCM_VLAN_SUBNET_IP6; 2179 if ((r = bcm_vlan_ip_add(unit, &ipaddr)) < 0) { 2180 goto bcm_err; 2181 } 2182 2183 return CMD_OK; 2184 } 2185 2186 if (sal_strcasecmp(subcmd, "delete") == 0) { 2187 bcm_vlan_ip_t ipaddr; 2188 2189 parse_table_init(unit, &pt); 2190 parse_table_add(&pt, "IPaddr", PQ_IP6, 0, &ipaddr.ip6, NULL); 2191 parse_table_add(&pt, "prefiX", PQ_INT, 0, &ipaddr.prefix, NULL); 2192 2193 if (!parseEndOk( a, &pt, &retCode)) { 2194 return retCode; 2195 } 2196 2197 ipaddr.flags = BCM_VLAN_SUBNET_IP6; 2198 if ((r = bcm_vlan_ip_delete(unit, &ipaddr)) < 0) { 2199 goto bcm_err; 2200 } 2201 2202 return CMD_OK; 2203 } 2204 2205 if (sal_strcasecmp(subcmd, "clear") == 0) { 2206 if ((r = bcm_vlan_ip_delete_all(unit)) < 0) { 2207 goto bcm_err; 2208 } 2209 2210 return CMD_OK; 2211 } 2212 2213 cli_out("%s: ERROR: Unknown ip6 subcommand: %s\n", ARG_CMD(a), subcmd); 2214 2215 return CMD_FAIL; 2216 } 2217 2218 /* Vlan control */ 2219 if (sal_strcasecmp(subcmd, "control") == 0 || 2220 sal_strcasecmp(subcmd, "ctrl") == 0) { 2221 char *value, *tname; 2222 int ttype, i, varg, matched; 2223 2224 static struct { /* match enum from bcm/vlan.h */ 2225 int type; 2226 char *name; 2227 } typenames[] = { 2228 { bcmVlanDropUnknown, "dropunknown" }, 2229 { bcmVlanPreferIP4, "preferip4" }, 2230 { bcmVlanPreferMAC, "prefermac" }, 2231 { bcmVlanShared, "shared" }, 2232 { bcmVlanSharedID, "sharedid" }, 2233 { bcmVlanPreferEgressTranslate, "preferegresstranslate" }, 2234 { 0, NULL } /* LAST ENTRY */ 2235 }; 2236 2237 subcmd = ARG_GET(a); 2238 value = ARG_GET(a); 2239 2240 matched = 0; 2241 2242 for (i = 0; typenames[i].name != NULL; i++) { 2243 tname = typenames[i].name; 2244 if (subcmd == NULL || sal_strcasecmp(subcmd, tname) == 0) { 2245 matched += 1; 2246 ttype = typenames[i].type; 2247 if (value == NULL) { 2248 r = bcm_vlan_control_get(unit, ttype, &varg); 2249 if (r < 0) { 2250 cli_out("%-20s-\t%s\n", tname, bcm_errmsg(r)); 2251 } else { 2252 cli_out("%-20s%d\n", tname, varg); 2253 } 2254 } else { 2255 varg = parse_integer(value); 2256 r = bcm_vlan_control_set(unit, ttype, varg); 2257 if (r < 0) { 2258 cli_out("%s\tERROR: %s\n", tname, bcm_errmsg(r)); 2259 } 2260 } 2261 } 2262 } 2263 2264 if (matched == 0) { 2265 cli_out("%s: ERROR: Unknown control name\n", subcmd); 2266 return CMD_FAIL; 2267 } 2268 2269 return CMD_OK; 2270 } 2271 2272 /* Vlan port control */ 2273 if (sal_strcasecmp(subcmd, "port") == 0) { 2274 char *value, *tname; 2275 int ttype, i, varg, matched; 2276 bcm_port_t port, dport; 2277 pbmp_t pbm; 2278 static struct { /* match enum from bcm/vlan.h */ 2279 int type; 2280 char *name; 2281 } typenames[] = { 2282 { bcmVlanPortPreferIP4, "preferip4" }, 2283 { bcmVlanPortPreferMAC, "prefermac" }, 2284 { bcmVlanTranslateIngressEnable, "translateingress" }, 2285 { bcmVlanTranslateIngressMissDrop, "translateingressmissdrop" }, 2286 { bcmVlanTranslateEgressEnable, "translateegress" }, 2287 { bcmVlanTranslateEgressMissDrop, "translateegressmissdrop" }, 2288 { bcmVlanTranslateEgressMissUntaggedDrop, "translateegressmissuntagdrop" }, 2289 { bcmVlanTranslateEgressMissUntag, "translateegressmissuntag"}, 2290 { bcmVlanLookupMACEnable, "lookupmac" }, 2291 { bcmVlanLookupIPEnable, "lookupip" }, 2292 { bcmVlanPortUseInnerPri, "useinnerpri" }, 2293 { bcmVlanPortUseOuterPri, "useouterpri" }, 2294 { bcmVlanPortVerifyOuterTpid, "verifyoutertpid" }, 2295 { bcmVlanPortOuterTpidSelect, "outertpidselect"}, 2296 { bcmVlanPortTranslateKeyFirst, "translatekeyfirst"}, 2297 { bcmVlanPortTranslateKeySecond, "translatekeysecond"}, 2298 { 0, NULL } /* LAST ENTRY */ 2299 }; 2300 2301 if ((c = ARG_GET(a)) == NULL) { 2302 BCM_PBMP_ASSIGN(pbm, pbmp_port_all); 2303 } else if (parse_bcm_pbmp(unit, c, &pbm) < 0) { 2304 cli_out("%s: Error: unrecognized port bitmap: %s\n", 2305 ARG_CMD(a), c); 2306 return CMD_FAIL; 2307 } 2308 2309 BCM_PBMP_AND(pbm, pbmp_port_all); 2310 if (BCM_PBMP_IS_NULL(pbm)) { 2311 cli_out("No ports specified.\n"); 2312 return CMD_OK; 2313 } 2314 2315 subcmd = ARG_GET(a); 2316 value = ARG_GET(a); 2317 2318 matched = 0; 2319 2320 DPORT_BCM_PBMP_ITER(unit, pbm, dport, port) { 2321 cli_out("\nVlan Control on Port=%s\n", BCM_PORT_NAME(unit, port)); 2322 for (i = 0; typenames[i].name != NULL; i++) { 2323 tname = typenames[i].name; 2324 if (subcmd == NULL || sal_strcasecmp(subcmd, tname) == 0) { 2325 matched += 1; 2326 ttype = typenames[i].type; 2327 if (value == NULL) { 2328 r = bcm_vlan_control_port_get(unit, port, 2329 ttype, &varg); 2330 if (r < 0) { 2331 cli_out("%-30s-\t%s\n", tname, bcm_errmsg(r)); 2332 } else { 2333 cli_out("%-30s%d\n", tname, varg); 2334 } 2335 } else { 2336 varg = parse_integer(value); 2337 r = bcm_vlan_control_port_set(unit, port, 2338 ttype, varg); 2339 if (r < 0) { 2340 cli_out("%s\tERROR: %s\n", tname, bcm_errmsg(r)); 2341 } 2342 } 2343 } 2344 } 2345 } 2346 2347 if (matched == 0) { 2348 cli_out("%s: ERROR: Unknown port control name\n", subcmd); 2349 return CMD_FAIL; 2350 } 2351 2352 return CMD_OK; 2353 } 2354 2355 2356 /* Vlan inner tag */ 2357 if (sal_strcasecmp(subcmd, "innertag") == 0) { 2358 int priority, cfi; 2359 int vid; 2360 bcm_port_t port, dport; 2361 uint16 innertag; 2362 pbmp_t pbm; 2363 2364 if ((c = ARG_GET(a)) == NULL) { 2365 BCM_PBMP_ASSIGN(pbm, pbmp_port_all); 2366 } else if (parse_bcm_pbmp(unit, c, &pbm) < 0) { 2367 cli_out("%s: Error: unrecognized port bitmap: %s\n", 2368 ARG_CMD(a), c); 2369 return CMD_FAIL; 2370 } 2371 2372 BCM_PBMP_AND(pbm, pbmp_port_all); 2373 if (BCM_PBMP_IS_NULL(pbm)) { 2374 cli_out("No ports specified.\n"); 2375 return CMD_OK; 2376 } 2377 2378 priority = -1; 2379 cfi = -1; 2380 vid = -1; 2381 parse_table_init(unit, &pt); 2382 parse_table_add(&pt, "Cfi", PQ_INT | PQ_DFL, 0, &cfi, NULL); 2383 parse_table_add(&pt, "Vlan", PQ_INT | PQ_DFL, 0, &vid, NULL); 2384 parse_table_add(&pt, "Priority", PQ_INT | PQ_DFL, 0, &priority, NULL); 2385 2386 if (0 > parse_arg_eq(a, &pt)) { 2387 cli_out("%s: Error: Invalid option: %s\n", ARG_CMD(a), ARG_CUR(a)); 2388 parse_arg_eq_done(&pt); 2389 return (CMD_FAIL); 2390 } 2391 parse_arg_eq_done(&pt); 2392 2393 if (priority == -1 || cfi == -1 || vid == -1) { 2394 /* coverity[overrun-local] */ 2395 DPORT_BCM_PBMP_ITER(unit, pbm, dport, port) { 2396 if ((r = bcm_port_vlan_inner_tag_get(unit, port, &innertag)) 2397 < 0) { 2398 goto bcm_err; 2399 } 2400 cli_out("Port=%s, Priority=%d, CFI=%d, VLAN=%d\n", 2401 BCM_PORT_NAME(unit, port), 2402 BCM_VLAN_CTRL_PRIO(innertag), 2403 BCM_VLAN_CTRL_CFI(innertag), 2404 BCM_VLAN_CTRL_ID(innertag)); 2405 } 2406 } else { 2407 innertag = BCM_VLAN_CTRL(priority, cfi, vid); 2408 2409 DPORT_BCM_PBMP_ITER(unit, pbm, dport, port) { 2410 if ((r = bcm_port_vlan_inner_tag_set(unit, port, innertag)) 2411 < 0) { 2412 goto bcm_err; 2413 } 2414 } 2415 } 2416 return CMD_OK; 2417 } 2418 2419 /* Vlan action */ 2420 if (sal_strcasecmp(subcmd, "action") == 0) { 2421 subcmd = ARG_GET(a); 2422 if (subcmd == NULL) { 2423 return CMD_USAGE; 2424 } 2425 if (sal_strcasecmp(subcmd, "port") == 0) { 2426 return _vlan_action_port(unit, a); 2427 } 2428 if (sal_strcasecmp(subcmd, "translate") == 0) { 2429 return _vlan_action_translate(unit, a); 2430 } 2431 if (sal_strcasecmp(subcmd, "mac") == 0) { 2432 return _vlan_action_mac(unit, a); 2433 } 2434 if (sal_strcasecmp(subcmd, "protocol") == 0 || 2435 sal_strcasecmp(subcmd, "proto") == 0) { 2436 return _vlan_action_protocol(unit, a); 2437 } 2438 if (sal_strcasecmp(subcmd, "ip4") == 0 || 2439 sal_strcasecmp(subcmd, "ip") == 0) { 2440 return _vlan_action_ip(unit, a, 0); 2441 } 2442 if (sal_strcasecmp(subcmd, "ip6") == 0) { 2443 return _vlan_action_ip(unit, a, BCM_VLAN_SUBNET_IP6); 2444 } 2445 return CMD_USAGE; 2446 } 2447 2448 2449 /* Set per Vlan property (Must be the last)*/ 2450 { 2451 bcm_vlan_control_vlan_t vlan_control, default_control; 2452 int outer_tpid, learn_disable, unknown_ip6_mcast_to_cpu; 2453 int def_outer_tpid, def_learn_disable, def_unknown_ip6_mcast_to_cpu; 2454 int unknown_ip4_mcast_to_cpu, def_unknown_ip4_mcast_to_cpu; 2455 int def_ip4_disable, ip4_disable; 2456 int def_ip6_disable, ip6_disable; 2457 int def_ip4_mcast_disable, ip4_mcast_disable; 2458 int def_ip6_mcast_disable, ip6_mcast_disable; 2459 int def_ip4_mcast_l2_disable, ip4_mcast_l2_disable; 2460 int def_ip6_mcast_l2_disable, ip6_mcast_l2_disable; 2461 int def_mpls_disable, mpls_disable; 2462 int def_cosq_enable, cosq_enable; 2463 int def_l3_vrf_global_disable, l3_vrf_global_disable; 2464 int def_mim_term_disable, mim_term_disable; 2465 bcm_cos_queue_t def_cosq, cosq; 2466 2467 id = parse_integer(subcmd); 2468 2469 2470 if (VLAN_ID_VALID(id)) { 2471 r = bcm_vlan_control_vlan_get(unit, id, &default_control); 2472 if (r < 0) { 2473 goto bcm_err; 2474 } 2475 2476 sal_memcpy(&vlan_control, &default_control, sizeof(vlan_control)); 2477 2478 def_outer_tpid = default_control.outer_tpid; 2479 outer_tpid = def_outer_tpid; 2480 2481 def_learn_disable = (default_control.flags & 2482 BCM_VLAN_LEARN_DISABLE) ? 1 : 0; 2483 learn_disable = def_learn_disable; 2484 2485 def_unknown_ip6_mcast_to_cpu = (default_control.flags & 2486 BCM_VLAN_UNKNOWN_IP6_MCAST_TOCPU) ? 1 : 0; 2487 unknown_ip6_mcast_to_cpu = def_unknown_ip6_mcast_to_cpu; 2488 2489 def_unknown_ip4_mcast_to_cpu = (default_control.flags & 2490 BCM_VLAN_UNKNOWN_IP4_MCAST_TOCPU) ? 1 : 0; 2491 unknown_ip4_mcast_to_cpu = def_unknown_ip4_mcast_to_cpu; 2492 2493 def_ip4_disable = (default_control.flags & 2494 BCM_VLAN_IP4_DISABLE) ? 1 : 0; 2495 ip4_disable = def_ip4_disable; 2496 2497 def_ip6_disable = (default_control.flags & 2498 BCM_VLAN_IP6_DISABLE) ? 1 : 0; 2499 ip6_disable = def_ip6_disable; 2500 2501 def_ip4_mcast_disable = (default_control.flags & 2502 BCM_VLAN_IP4_MCAST_DISABLE) ? 1 : 0; 2503 ip4_mcast_disable = def_ip4_mcast_disable; 2504 2505 def_ip6_mcast_disable = (default_control.flags & 2506 BCM_VLAN_IP6_MCAST_DISABLE) ? 1 : 0; 2507 ip6_mcast_disable = def_ip6_mcast_disable; 2508 2509 def_l3_vrf_global_disable = (default_control.flags & 2510 BCM_VLAN_L3_VRF_GLOBAL_DISABLE) ? 1 : 0; 2511 l3_vrf_global_disable = def_l3_vrf_global_disable; 2512 2513 def_ip4_mcast_l2_disable = (default_control.flags & 2514 BCM_VLAN_IP4_MCAST_L2_DISABLE) ? 1 : 0; 2515 ip4_mcast_l2_disable = def_ip4_mcast_l2_disable; 2516 2517 def_ip6_mcast_l2_disable = (default_control.flags & 2518 BCM_VLAN_IP6_MCAST_L2_DISABLE) ? 1 : 0; 2519 ip6_mcast_l2_disable = def_ip6_mcast_l2_disable; 2520 2521 def_mpls_disable = (default_control.flags & 2522 BCM_VLAN_MPLS_DISABLE) ? 1 : 0; 2523 mpls_disable = def_mpls_disable; 2524 2525 def_mim_term_disable = (default_control.flags & 2526 BCM_VLAN_MIM_TERM_DISABLE) ? 1 : 0; 2527 mim_term_disable = def_mim_term_disable; 2528 2529 def_cosq_enable = (default_control.flags & 2530 BCM_VLAN_COSQ_ENABLE) ? 1 : 0; 2531 cosq_enable = def_cosq_enable; 2532 2533 def_cosq = default_control.cosq; 2534 cosq = def_cosq; 2535 2536 parse_table_init(unit, &pt); 2537 parse_table_add(&pt, "VRF", PQ_INT | PQ_DFL, &default_control.vrf, 2538 &vlan_control.vrf, NULL); 2539 parse_table_add(&pt, "OuterTPID", PQ_HEX | PQ_DFL, &def_outer_tpid, 2540 &outer_tpid, NULL); 2541 parse_table_add(&pt, "LearnDisable", PQ_INT | PQ_DFL, 2542 &def_learn_disable, &learn_disable, NULL); 2543 parse_table_add(&pt, "UnknownIp6McastToCpu", PQ_INT | PQ_DFL, 2544 &def_unknown_ip6_mcast_to_cpu, 2545 &unknown_ip6_mcast_to_cpu, NULL); 2546 parse_table_add(&pt, "UnknownIp4McastToCpu", PQ_INT | PQ_DFL, 2547 &def_unknown_ip4_mcast_to_cpu, 2548 &unknown_ip4_mcast_to_cpu, NULL); 2549 parse_table_add(&pt, "Ip4Disable", PQ_INT | PQ_DFL, 2550 &def_ip4_disable, &ip4_disable, NULL); 2551 parse_table_add(&pt, "Ip6Disable", PQ_INT | PQ_DFL, 2552 &def_ip6_disable, &ip6_disable, NULL); 2553 parse_table_add(&pt, "Ip4McastDisable", PQ_INT | PQ_DFL, 2554 &def_ip4_mcast_disable, &ip4_mcast_disable, NULL); 2555 parse_table_add(&pt, "Ip6McastDisable", PQ_INT | PQ_DFL, 2556 &def_ip6_mcast_disable, &ip6_mcast_disable, NULL); 2557 parse_table_add(&pt, "Ip4McastL2Disable", PQ_INT | PQ_DFL, 2558 &def_ip4_mcast_l2_disable, &ip4_mcast_l2_disable, NULL); 2559 parse_table_add(&pt, "Ip6McastL2Disable", PQ_INT | PQ_DFL, 2560 &def_ip6_mcast_l2_disable, &ip6_mcast_l2_disable, NULL); 2561 parse_table_add(&pt, "L3VrfGlobalDisable", PQ_INT | PQ_DFL, 2562 &def_l3_vrf_global_disable, &l3_vrf_global_disable, NULL); 2563 parse_table_add(&pt, "MplsDisable", PQ_INT | PQ_DFL, 2564 &def_mpls_disable, &mpls_disable, NULL); 2565 parse_table_add(&pt, "CosqEnable", PQ_INT | PQ_DFL, 2566 &def_cosq_enable, &cosq_enable, NULL); 2567 parse_table_add(&pt, "MiMTermDisable", PQ_INT | PQ_DFL, 2568 &def_mim_term_disable, &mim_term_disable, NULL); 2569 parse_table_add(&pt, "Cosq", PQ_INT | PQ_DFL, 2570 &def_cosq, &cosq, NULL); 2571 parse_table_add(&pt, "Ip6McastFloodMode", PQ_MULTI | PQ_DFL, 2572 &default_control.ip6_mcast_flood_mode, 2573 &vlan_control.ip6_mcast_flood_mode, 2574 bcm_vlan_mcast_flood_str); 2575 parse_table_add(&pt, "Ip4McastFloodMode", PQ_MULTI | PQ_DFL, 2576 &default_control.ip4_mcast_flood_mode, 2577 &vlan_control.ip4_mcast_flood_mode, 2578 bcm_vlan_mcast_flood_str); 2579 parse_table_add(&pt, "L2McastFloodMode", PQ_MULTI | PQ_DFL, 2580 &default_control.l2_mcast_flood_mode, 2581 &vlan_control.l2_mcast_flood_mode, 2582 bcm_vlan_mcast_flood_str); 2583 parse_table_add(&pt, "IfClass", PQ_INT | PQ_DFL, 2584 &default_control.if_class, 2585 &vlan_control.if_class, NULL); 2586 2587 if (!parseEndOk( a, &pt, &retCode)) { 2588 return retCode; 2589 } 2590 2591 vlan_control.outer_tpid = (uint16) outer_tpid; 2592 vlan_control.cosq = cosq; 2593 vlan_control.flags = (learn_disable ? 2594 BCM_VLAN_LEARN_DISABLE : 0); 2595 vlan_control.flags |= (unknown_ip6_mcast_to_cpu ? 2596 BCM_VLAN_UNKNOWN_IP6_MCAST_TOCPU : 0); 2597 vlan_control.flags |= (unknown_ip4_mcast_to_cpu? 2598 BCM_VLAN_UNKNOWN_IP4_MCAST_TOCPU : 0); 2599 vlan_control.flags |= (ip4_disable ? 2600 BCM_VLAN_IP4_DISABLE : 0); 2601 vlan_control.flags |= (ip6_disable ? 2602 BCM_VLAN_IP6_DISABLE : 0); 2603 vlan_control.flags |= (ip4_mcast_disable ? 2604 BCM_VLAN_IP4_MCAST_DISABLE : 0); 2605 vlan_control.flags |= (ip6_mcast_disable ? 2606 BCM_VLAN_IP6_MCAST_DISABLE : 0); 2607 vlan_control.flags |= (l3_vrf_global_disable ? 2608 BCM_VLAN_L3_VRF_GLOBAL_DISABLE : 0); 2609 vlan_control.flags |= (ip4_mcast_l2_disable ? 2610 BCM_VLAN_IP4_MCAST_L2_DISABLE : 0); 2611 vlan_control.flags |= (ip6_mcast_l2_disable ? 2612 BCM_VLAN_IP6_MCAST_L2_DISABLE : 0); 2613 vlan_control.flags |= (mpls_disable ? 2614 BCM_VLAN_MPLS_DISABLE : 0); 2615 vlan_control.flags |= (cosq_enable ? 2616 BCM_VLAN_COSQ_ENABLE : 0); 2617 vlan_control.flags |= (mim_term_disable ? 2618 BCM_VLAN_MIM_TERM_DISABLE : 0); 2619 2620 if ((r = bcm_vlan_control_vlan_set(unit, id, vlan_control)) < 0) { 2621 goto bcm_err; 2622 } 2623 2624 return CMD_OK; 2625 } 2626 } 2627 2628 2629 return CMD_USAGE; 2630 2631 bcm_err: 2632 2633 cli_out("%s: ERROR: %s\n", ARG_CMD(a), bcm_errmsg(r)); 2634 2635 return CMD_FAIL; 2636 } 2637