openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

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, &ether, 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, &ether, 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, &ether, 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