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

policer.c (26433B)


      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  * Service meter(global meters) CLI commands
      8  */
      9 
     10 #include <appl/diag/system.h>
     11 #include <appl/diag/parse.h>
     12 #include <shared/bsl.h>
     13 #include <soc/debug.h>
     14 #include <soc/hash.h>
     15 
     16 #include <bcm/error.h>
     17 #include <bcm/debug.h>
     18 #include <bcm/policer.h>
     19 #include <bcm_int/esw/policer.h>
     20 
     21 /*
     22  * SVC METER command catagory
     23  */
     24 enum _svc_meter_cmd_t {
     25     GLOBAL_METER_MODE_CREATE = 1,
     26     GLOBAL_METER_MODE_DELETE,
     27     GLOBAL_METER_ACTION_CREATE,
     28     GLOBAL_METER_ACTION_DESTROY,
     29     GLOBAL_METER_ACTION_ADD,
     30     GLOBAL_METER_ACTION_GET,
     31     GLOBAL_METER_ACTION_ATTACH,
     32     GLOBAL_METER_ACTION_DETACH,
     33     GLOBAL_METER_ACTION_ATTACH_GET,
     34     GLOBAL_METER_POLICER_GROUP_CREATE,
     35     GLOBAL_METER_POLICER_ENVELOP_CREATE,
     36     GLOBAL_METER_POLICER_DESTROY,
     37     GLOBAL_METER_POLICER_DESTROY_ALL,
     38     GLOBAL_METER_POLICER_SET,
     39     GLOBAL_METER_POLICER_GET,
     40     GLOBAL_METER_POLICER_TRAVERSE
     41 };
     42 
     43 
     44 static struct policer_group_type_names {
     45     char                     *name;
     46     bcm_policer_group_mode_t  mode;
     47 } policer_group_type_names[] = {
     48     { "Single",        bcmPolicerGroupModeSingle                    },
     49     { "TrafficType",   bcmPolicerGroupModeTrafficType               },
     50     { "DlfAll",        bcmPolicerGroupModeDlfAll                    },
     51     { "DlfIntPri",     bcmPolicerGroupModeDlfIntPri                 },
     52     { "Typed",         bcmPolicerGroupModeTyped                     },
     53     { "TypedAll",      bcmPolicerGroupModeTypedAll                  },
     54     { "TypedIntPri",   bcmPolicerGroupModeTypedIntPri               },
     55     { "SingleWithControl", bcmPolicerGroupModeSingleWithControl     },
     56     { "TrafficTypeWithControl", bcmPolicerGroupModeTrafficTypeWithControl},
     57     { "DlfAllWithControl",      bcmPolicerGroupModeDlfAllWithControl     },
     58     { "DlfIntPriWithControl",   bcmPolicerGroupModeDlfIntPriWithControl  },
     59     { "TypedWithControl",       bcmPolicerGroupModeTypedWithControl      },
     60     { "TypedAllWithControl",    bcmPolicerGroupModeTypedAllWithControl   },
     61     { "TypedIntPriWithControl", bcmPolicerGroupModeTypedIntPriWithControl},
     62     { "Dot1P",                  bcmPolicerGroupModeDot1P                 },
     63     { "IntPri",                 bcmPolicerGroupModeIntPri                },
     64     { "IntPriCng",              bcmPolicerGroupModeIntPriCng             },
     65     { "SvpType",                bcmPolicerGroupModeSvpType               },
     66     { "Dscp",                   bcmPolicerGroupModeDscp                  },
     67     { "Cascade",                bcmPolicerGroupModeCascade               },
     68     { "CascadeWithCoupling",    bcmPolicerGroupModeCascadeWithCoupling   },
     69     { "InnerDot1P",             bcmPolicerGroupModeInnerDot1P            },
     70     { "IntPriCascade",          bcmPolicerGroupModeIntPriCascade         },
     71     { "IntPriCascadeWithCoupling", bcmPolicerGroupModeIntPriCascadeWithCoupling}
     72 };
     73 
     74 static struct policer_type_names {
     75     char                     *name;
     76     bcm_policer_mode_t       mode;
     77 } policer_type_names[] = {
     78     { "SrTcm",                bcmPolicerModeSrTcm               },
     79     { "Committed",            bcmPolicerModeCommitted           }, 
     80     { "Peak",                 bcmPolicerModePeak                }, 
     81     { "TrTcm",                bcmPolicerModeTrTcm               },
     82     { "TrTcmDs",              bcmPolicerModeTrTcmDs             },          
     83     { "Green",                bcmPolicerModeGreen               }, 
     84     { "PassThrough",          bcmPolicerModePassThrough         }, 
     85     { "SrTcmModified",        bcmPolicerModeSrTcmModified       }, 
     86     { "CoupledTrTcmDs",       bcmPolicerModeCoupledTrTcmDs      }, 
     87     { "Cascade",              bcmPolicerModeCascade             }, 
     88     { "CoupledCascade",       bcmPolicerModeCoupledCascade      },
     89     { "SrTcmTsn",             bcmPolicerModeSrTcmTsn            }
     90 };
     91 
     92 static struct policer_action_names {
     93     char                     *name;
     94     bcm_policer_action_t     action;
     95 } policer_action_names[] = {
     96     { "GpDrop",                bcmPolicerActionGpDrop            },
     97     { "GpDscpNew",             bcmPolicerActionGpDscpNew         },     
     98     { "GpEcnNew",              bcmPolicerActionGpEcnNew          },       
     99     { "GpPrioIntNew",          bcmPolicerActionGpPrioIntNew      },   
    100     { "GpCngNew",              bcmPolicerActionGpCngNew          },       
    101     { "GpVlanPrioNew",         bcmPolicerActionGpVlanPrioNew     },  
    102     { "YpDrop",                bcmPolicerActionYpDrop            },         
    103     { "YpDscpNew",             bcmPolicerActionYpDscpNew         },      
    104     { "YpEcnNew",              bcmPolicerActionYpEcnNew          },       
    105     { "YpPrioIntNew",          bcmPolicerActionYpPrioIntNew      },   
    106     { "YpCngNew",              bcmPolicerActionYpCngNew          },       
    107     { "YpVlanPrioNew",         bcmPolicerActionYpVlanPrioNew     },  
    108     { "RpDrop",                bcmPolicerActionRpDrop            },         
    109     { "RpDscpNew",             bcmPolicerActionRpDscpNew         },      
    110     { "RpEcnNew",              bcmPolicerActionRpEcnNew          },       
    111     { "RpPrioIntNew",          bcmPolicerActionRpPrioIntNew      },   
    112     { "RpCngNew",              bcmPolicerActionRpCngNew          },      
    113     { "RpVlanPrioNew",         bcmPolicerActionRpVlanPrioNew     }
    114 };
    115 
    116 static int _bcm_esw_handle_policer_commands(int unit, args_t *a);   
    117 
    118 char cmd_esw_policer_global_meter_usage[] =
    119     "Usages:\n\t"
    120 #ifdef COMPILER_STRING_CONST_LIMIT
    121     "  GlobalMeter [args...]\n"
    122 #else
    123     "  GlobalMeter Policer CreateGroup <GROUP>=<group_name>\n\t"
    124     "              - Create global meter policers with given group\n\t"
    125     "  GlobalMeter Policer CreateEnvelop <Flag>=<1/2> \n\t" 
    126     "              -           <MacroMeterPolicer> = <policer>\n\t"
    127     "              - Create micro/macro meter policer \n\t"
    128     "  GlobalMeter Policer Destroy <POLICER>=<policer_id>\n\t"
    129     "              - Destroy global meter policers given base policer id \n\t"
    130     "  GlobalMeter Policer DestroyAll \n\t"
    131     "              - Destroy all global meter policers \n\t"
    132     "  GlobalMeter Policer Set <POLICER>=<policer_id> \n\t"
    133     "              -           <POLICER_TYPE>=<policer_type> <FLAG>=<flag> \n\t"
    134     "              -           [<CommittedRate>=<committed_rate>]\n\t"
    135     "              -           [<CommittedBurst>=<committed_burst_rate>]\n\t"
    136     "              -           [<PeakRate>=<Peak_rate>]\n\t"
    137     "              -           [<PeakBurst>=<Peak_burst_rate>]\n\t"
    138     "              -           [<ActionId>=<action_id>]\n\t"
    139     "              -           [<SharingMode>=<sharing_mode>]\n\t"
    140     "              - Set parameters of the policer \n\t"
    141     "  GlobalMeter Policer Get <POLICER>=<policer_id> \n\t"
    142     "              - Get parameters of the policer \n\t"
    143     "  GlobalMeter Policer Traverse \n\t"
    144     "              - Traverse through all the policers \n\t"
    145     "  GlobalMeter Policer Action ATtach <POLICER>=<policer_id> \n\t"
    146     "              -                     <ACTION_ID>=<action_id> \n\t"
    147     "              - Attach policer action to policer specified \n\t"
    148     "  GlobalMeter Policer Action Detach <POLICER>=<policer_id> \n\t"
    149     "              - Detach policer action from policer specified \n\t"
    150     "  GlobalMeter Policer Action AttachGet <POLICER>=<policer_id> \n\t"
    151     "              - Get the policer action index associated with policer \n\t"
    152     "  GlobalMeter Policer Action Create \n\t"
    153     "              - Create an  policer action entry \n\t"
    154     "  GlobalMeter Policer Action Destroy <ACTION_ID>=<action_id> \n\t"
    155     "              - Destroy an policer action entry \n\t"
    156     "  GlobalMeter Policer Action Add <ACTION_ID>=<action_id><ACTION>=<action> \n\t"
    157     "              -           [<PARAM>=<action_param>]\n\t"
    158     "              - Add an action to policer action entry specified \n\t"
    159     "  GlobalMeter Policer Action Get <ACTION_ID>=<action_id> <ACTION>=<action> \n\t"
    160     "              - Get parameter associated with an action entry action \n\t"
    161 #endif
    162     ;
    163 
    164 STATIC int
    165 _bcm_esw_policer_traverse_print(int unit, bcm_policer_t policer_id,
    166                                     bcm_policer_config_t *cfg,
    167                                     void *user_data)
    168 {
    169     cli_out("Policer with id %x configuration params are \n",policer_id);
    170     cli_out("Policer Type =%d \n",cfg->mode);
    171     cli_out("Flag =%d \n",cfg->flags);
    172     cli_out("Committed rate =%d \n",cfg->ckbits_sec);
    173     cli_out("Committed Burst =%d \n",cfg->ckbits_burst);
    174     cli_out("Peak rate =%d \n",cfg->pkbits_sec);
    175     cli_out("Peak Burst =%d \n",cfg->pkbits_burst);
    176     cli_out("Action ID =%d \n",cfg->action_id);
    177     cli_out("Sharing Mode =%d \n",cfg->sharing_mode);
    178 
    179     return CMD_OK;
    180 }
    181 
    182 STATIC int
    183 _policer_group_mode_get(const char *mode_str, bcm_policer_group_mode_t *mode)
    184 {
    185     int  i, names;
    186     names = sizeof(policer_group_type_names) /  \
    187                         sizeof(struct policer_group_type_names);
    188     /* Get bcm_policer_group_mode from mode type string */
    189     for (i = 0; i < names; i++) {
    190         if (mode_str &&
    191             (sal_strcasecmp(mode_str, policer_group_type_names[i].name) == 0)) {
    192             *mode = policer_group_type_names[i].mode;
    193             return BCM_E_NONE;
    194         }
    195     }
    196     cli_out("Invalid group mode type <%s>. Valid key types are:\n   ",
    197             mode_str ? mode_str : "");
    198     for (i = 0;  i < names; i++) {
    199         cli_out("%s ", policer_group_type_names[i].name);
    200         if (i % 7 == 0) {
    201             cli_out("\n   ");
    202         }
    203     }
    204     cli_out("\n");
    205     return BCM_E_PARAM;
    206 }
    207 
    208 STATIC int
    209 _policer_mode_get(const char *mode_str, bcm_policer_mode_t *mode)
    210 {
    211     int  i, names;
    212     names = sizeof(policer_type_names) /  \
    213                         sizeof(struct policer_type_names);
    214     /* Get bcm_policer_mode from mode type string */
    215     for (i = 0; i < names; i++) {
    216         if (mode_str &&
    217             (sal_strcasecmp(mode_str, policer_type_names[i].name) == 0)) {
    218             *mode = policer_type_names[i].mode;
    219             return BCM_E_NONE;
    220         }
    221     }
    222     cli_out("Invalid group mode type <%s>. Valid key types are:\n   ",
    223             mode_str ? mode_str : "");
    224     for (i = 0;  i < names; i++) {
    225         cli_out("%s ", policer_type_names[i].name);
    226         if (i % 7 == 0) {
    227             cli_out("\n   ");
    228         }
    229     }
    230     cli_out("\n");
    231     return BCM_E_PARAM;
    232 }
    233 
    234 static INLINE int
    235 _policer_mode_name_get(bcm_policer_mode_t key_type, char *mode_str)
    236 {
    237     int names = sizeof(policer_type_names) / sizeof(struct policer_type_names);
    238     if (key_type >= names) {
    239         return BCM_E_INTERNAL;
    240     }
    241 
    242     /* coverity[secure_coding] */
    243     strcpy(mode_str, policer_type_names[key_type].name);
    244     return BCM_E_NONE;
    245 }
    246 
    247 STATIC int
    248 _policer_action_get(const char *action_str, bcm_policer_action_t *action)
    249 {
    250     int  i, names;
    251     names = sizeof(policer_action_names) /  \
    252                         sizeof(struct policer_action_names);
    253     /* Get bcm_policer_group_mode from mode type string */
    254     for (i = 0; i < names; i++) {
    255         if (action_str &&
    256             (sal_strcasecmp(action_str, policer_action_names[i].name) == 0)) {
    257             *action = policer_action_names[i].action;
    258             return BCM_E_NONE;
    259         }
    260     }
    261     cli_out("Invalid action type <%s>. Valid types are:\n   ",
    262             action_str ? action_str : "");
    263     for (i = 0;  i < names; i++) {
    264         cli_out("%s ", policer_action_names[i].name);
    265         if (i % 7 == 0) {
    266             cli_out("\n   ");
    267         }
    268     }
    269     cli_out("\n");
    270     return BCM_E_PARAM;
    271 }
    272 
    273 cmd_result_t
    274 cmd_esw_policer_global_meter(int unit, args_t *a)
    275 {
    276     char *cmd;
    277 
    278     /* Check valid device to operation on ...*/
    279     if (! sh_check_attached(ARG_CMD(a), unit)) {
    280 	return CMD_FAIL;
    281     }
    282 
    283     if ((cmd = ARG_GET(a)) == NULL) {
    284 	return CMD_USAGE;
    285     }
    286 
    287     if (sal_strcasecmp(cmd, "policer") == 0) {
    288         return(_bcm_esw_handle_policer_commands(unit, a));   
    289     } else {
    290 	return CMD_USAGE;
    291     }
    292 }
    293 
    294 static int _bcm_esw_handle_policer_action_commands(int unit, args_t *a)
    295 {
    296     char *subcmd_s;
    297     int subcmd = 0;
    298     int rv=0;
    299     parse_table_t   pt;
    300     cmd_result_t    retCode;
    301     uint32 action_id;
    302     bcm_policer_t policer_id;
    303     char *action_str = NULL;
    304     bcm_policer_action_t action;
    305     uint32 param=0;
    306 
    307     if ((subcmd_s = ARG_GET(a)) == NULL) {
    308         return CMD_USAGE;
    309     }
    310     if (sal_strcasecmp(subcmd_s, "create") == 0) {
    311         subcmd = GLOBAL_METER_ACTION_CREATE;
    312     }
    313     if (sal_strcasecmp(subcmd_s, "destroy") == 0) {
    314         subcmd = GLOBAL_METER_ACTION_DESTROY;
    315     }
    316     if (sal_strcasecmp(subcmd_s, "add") == 0) {
    317         subcmd = GLOBAL_METER_ACTION_ADD;
    318     }
    319     if (sal_strcasecmp(subcmd_s, "get") == 0) {
    320         subcmd = GLOBAL_METER_ACTION_GET;
    321     }
    322     if (sal_strcasecmp(subcmd_s, "attach") == 0) {
    323         subcmd = GLOBAL_METER_ACTION_ATTACH;
    324     }
    325     if (sal_strcasecmp(subcmd_s, "detach") == 0) {
    326         subcmd = GLOBAL_METER_ACTION_DETACH;
    327     }
    328     if (sal_strcasecmp(subcmd_s, "attachget") == 0) {
    329         subcmd = GLOBAL_METER_ACTION_ATTACH_GET;
    330     }
    331 
    332     parse_table_init(unit, &pt);
    333     switch (subcmd) {
    334 	case GLOBAL_METER_ACTION_CREATE:
    335             rv = bcm_policer_action_create(unit, &action_id); 
    336             if (rv == BCM_E_NONE) {
    337                 cli_out("Created METER ACtion with ID %x\n",action_id);
    338             } else {
    339                 cli_out("%s Creation of METER action failed with error \
    340                         %s\n",ARG_CMD(a),bcm_errmsg(rv));
    341             }
    342             break;
    343 
    344 	case GLOBAL_METER_ACTION_DESTROY:
    345             parse_table_add(&pt, "ACTION_ID", PQ_HEX, 0, &action_id, 0);
    346 	    if (!parseEndOk(a, &pt, &retCode)) {
    347 	        return retCode;
    348             }
    349             rv = bcm_policer_action_destroy(unit, action_id); 
    350             if (rv == BCM_E_NONE) {
    351                 cli_out("Destroy METER ACtion with ID %x SUCCESS\n",action_id);
    352             } else {
    353                 cli_out("%s Destroy of METER action failed with error \
    354                         %s\n",ARG_CMD(a),bcm_errmsg(rv));
    355             }
    356             break;
    357 
    358 	case GLOBAL_METER_ACTION_ADD:
    359             parse_table_add(&pt, "ACTION_ID", PQ_HEX, 0, &action_id, 0);
    360             parse_table_add(&pt, "ACTION", PQ_STRING, 0, &action_str, NULL);
    361             parse_table_add(&pt, "PARAM", PQ_INT, 0, &param, 0);
    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             if (action_str != NULL) {
    368                 rv = _policer_action_get(action_str, &action);
    369                 if (rv != BCM_E_NONE) {
    370                     parse_arg_eq_done(&pt);
    371                     return CMD_FAIL;
    372                 }
    373             } else {
    374                 parse_arg_eq_done(&pt);
    375                 return CMD_FAIL;
    376             } 
    377             rv = bcm_policer_action_add(unit, action_id, action, param); 
    378             if (rv == BCM_E_NONE) {
    379                 cli_out("Added action %s to action id %x\n",action_str,action_id);
    380             } else {
    381                 cli_out("%s Addition of action to action_id %x failed with error \
    382                         %s\n",ARG_CMD(a),action_id,bcm_errmsg(rv));
    383             }
    384             parse_arg_eq_done(&pt);
    385             break;
    386 
    387 	case GLOBAL_METER_ACTION_GET:
    388             parse_table_add(&pt, "ACTION_ID", PQ_HEX, 0, &action_id, 0);
    389             parse_table_add(&pt, "ACTION", PQ_STRING, 0, &action_str, NULL);
    390             if (parse_arg_eq(a, &pt) < 0) {
    391                 cli_out("Error: invalid option %s\n", ARG_CUR(a));
    392                 parse_arg_eq_done(&pt);
    393                 return CMD_USAGE;
    394             }
    395             if(action_str != NULL) {
    396                 rv = _policer_action_get(action_str, &action);
    397                 if (rv != BCM_E_NONE) {
    398                     parse_arg_eq_done(&pt);
    399                     return CMD_FAIL;
    400                 }
    401             } else {
    402                 parse_arg_eq_done(&pt);
    403                 return CMD_FAIL;
    404             }
    405             rv = bcm_policer_action_get(unit, action_id, action, &param); 
    406             if (rv == BCM_E_NONE) {
    407                 cli_out("Param for Action %s of action_id %x is %d SUCCESS\n", 
    408                         action_str, action_id, param);
    409             } else {
    410                 cli_out("%s  Action get failed with error \
    411                         %s\n",ARG_CMD(a),bcm_errmsg(rv));
    412             }
    413             parse_arg_eq_done(&pt);
    414             break;
    415 
    416 	case GLOBAL_METER_ACTION_ATTACH:
    417             parse_table_add(&pt, "POLICER", PQ_HEX, 0, &policer_id, 0);
    418             parse_table_add(&pt, "ACTION_ID", PQ_HEX, 0, &action_id, 0);
    419 	    if (!parseEndOk( a, &pt, &retCode)) {
    420 	        return retCode;
    421             }
    422             rv = bcm_policer_action_attach(unit, policer_id, action_id); 
    423             if (rv == BCM_E_NONE) {
    424                 cli_out("Attach action id %x to policer %x SUCCESS\n", 
    425                         action_id, policer_id);
    426             } else {
    427                 cli_out("%s Attach action_id %x failed with error \
    428                         %s\n",ARG_CMD(a),action_id,bcm_errmsg(rv));
    429             }
    430             break;
    431 
    432 	case GLOBAL_METER_ACTION_DETACH:
    433             parse_table_add(&pt, "POLICER", PQ_HEX, 0, &policer_id, 0);
    434             parse_table_add(&pt, "ACTION_ID", PQ_HEX, 0, &action_id, 0);
    435 	    if (!parseEndOk( a, &pt, &retCode)) {
    436 	        return retCode;
    437             }
    438             rv = bcm_policer_action_detach(unit, policer_id, action_id); 
    439             if (rv == BCM_E_NONE) {
    440                 cli_out("Detach action id %x from policer %x SUCCESS\n",
    441                         action_id, policer_id);
    442             } else {
    443                 cli_out("%s detach action_id %x failed with error \
    444                         %s\n", ARG_CMD(a), action_id, bcm_errmsg(rv));
    445             }
    446 	    break;
    447 
    448 	case GLOBAL_METER_ACTION_ATTACH_GET:
    449             parse_table_add(&pt, "POLICER", PQ_HEX, 0, &policer_id, 0);
    450 	    if (!parseEndOk( a, &pt, &retCode)) {
    451 	        return retCode;
    452             }
    453             rv = bcm_policer_action_attach_get(unit, policer_id, &action_id); 
    454             if (rv == BCM_E_NONE) {
    455                 cli_out("Action id associated with policer id %x is %x \n",
    456                         policer_id, action_id);
    457             } else {
    458                 cli_out("%s action Attach get failed with error \
    459                         %s\n",ARG_CMD(a),bcm_errmsg(rv));
    460             }
    461 	    break;
    462 
    463 	default:
    464 	    return CMD_USAGE;
    465 	    break;
    466     }
    467     return CMD_OK;
    468 }
    469 
    470 static int _bcm_esw_handle_policer_commands(int unit, args_t *a)   
    471 {
    472     char *subcmd_s;
    473     int subcmd = 0;
    474     char *mode_str = NULL;
    475     char mode_name[20];
    476     bcm_policer_group_mode_t mode = 0;
    477     bcm_policer_t policer_id = 0;
    478     bcm_policer_t macro_meter_policer = 0;
    479     int flag = 0;
    480     int numbers = 0;
    481     int rv = 0;
    482     parse_table_t   pt;
    483     cmd_result_t    retCode;
    484 
    485     bcm_policer_config_t pol_cfg;
    486 
    487     if ((subcmd_s = ARG_GET(a)) == NULL) {
    488         return CMD_USAGE;
    489     }
    490     if (sal_strcasecmp(subcmd_s, "action") == 0) {
    491         return(_bcm_esw_handle_policer_action_commands(unit, a));
    492     }
    493     if (sal_strcasecmp(subcmd_s, "creategroup") == 0) {
    494         subcmd = GLOBAL_METER_POLICER_GROUP_CREATE;
    495 
    496     }
    497     if (sal_strcasecmp(subcmd_s, "CreateEnvelop") == 0) {
    498         subcmd = GLOBAL_METER_POLICER_ENVELOP_CREATE;
    499     }
    500 
    501     if (sal_strcasecmp(subcmd_s, "set") == 0) {
    502         subcmd = GLOBAL_METER_POLICER_SET;
    503 
    504     }
    505     if (sal_strcasecmp(subcmd_s, "get") == 0) {
    506         subcmd = GLOBAL_METER_POLICER_GET;
    507     }
    508     if (sal_strcasecmp(subcmd_s, "Destroy") == 0) {
    509         subcmd = GLOBAL_METER_POLICER_DESTROY;
    510     }
    511     if (sal_strcasecmp(subcmd_s, "DestroyAll") == 0) {
    512         subcmd = GLOBAL_METER_POLICER_DESTROY_ALL;
    513     }
    514     if (sal_strcasecmp(subcmd_s, "Traverse") == 0) {
    515         subcmd = GLOBAL_METER_POLICER_TRAVERSE;
    516     }
    517     parse_table_init(unit, &pt);
    518 
    519     switch (subcmd) {
    520 	case GLOBAL_METER_POLICER_GROUP_CREATE:
    521             parse_table_add(&pt, "GROUP", PQ_STRING, 0, &mode_str, NULL);
    522             parse_table_add(&pt, "NUM", PQ_INT, 0, &numbers, 0);
    523 
    524             if (parse_arg_eq(a, &pt) < 0) {
    525                 cli_out("Error: invalid option %s\n", ARG_CUR(a));
    526                 parse_arg_eq_done(&pt);
    527                 return CMD_USAGE;
    528             }
    529             if (mode_str != NULL) {
    530                 rv = _policer_group_mode_get(mode_str, &mode);
    531                 if (rv != BCM_E_NONE) {
    532                     parse_arg_eq_done(&pt);
    533                     return CMD_FAIL;
    534                 }
    535             } 
    536             parse_arg_eq_done(&pt);
    537             rv = bcm_policer_group_create(unit, mode, &policer_id, &numbers); 
    538             if (rv == BCM_E_NONE) {
    539                 cli_out("Created policer group with %d policers and Base policer \
    540                         ID %x\n",numbers,policer_id);
    541             } else {
    542                 cli_out("%s Creation of policer group failed with error \
    543                         %s\n",ARG_CMD(a),bcm_errmsg(rv));
    544             }
    545             break;
    546 
    547 	case GLOBAL_METER_POLICER_ENVELOP_CREATE:
    548             parse_table_add(&pt, "Flag", PQ_INT, 0, &flag, 0);
    549             parse_table_add(&pt, "MacroMeterPolicer", PQ_INT, 0, &macro_meter_policer, 0);
    550 	    if (!parseEndOk( a, &pt, &retCode)) {
    551 	        return retCode;
    552             }
    553             rv = bcm_policer_envelop_create(unit, flag, macro_meter_policer, &policer_id); 
    554             if (rv == BCM_E_NONE) {
    555                 cli_out("Created Envelop policer of type %d with ID %x\n", flag, policer_id);
    556             } else {
    557                 cli_out("%s Creation of envelop policer falied with error \
    558                         %s\n",ARG_CMD(a),bcm_errmsg(rv));
    559             }
    560             break;
    561 
    562 	case GLOBAL_METER_POLICER_DESTROY:
    563             parse_table_add(&pt, "POLICER", PQ_HEX, 0, &policer_id, 0);
    564 	    if (!parseEndOk( a, &pt, &retCode)) {
    565 	        return retCode;
    566             }
    567             rv = bcm_policer_destroy(unit, policer_id); 
    568             if (rv == BCM_E_NONE) {
    569                 cli_out("Destroy policer group with Base policer \
    570                         ID %x SUCCESS\n",policer_id);
    571             } else {
    572                 cli_out("%s Destroy policer group failed with error \
    573                         %s\n",ARG_CMD(a),bcm_errmsg(rv));
    574             }
    575             break;
    576 
    577 	case GLOBAL_METER_POLICER_DESTROY_ALL:
    578             rv = bcm_policer_destroy_all(unit); 
    579             if (rv == BCM_E_NONE) {
    580                 cli_out("Destroy ALL policer SUCCESS\n");
    581             } else {
    582                 cli_out("%s Destroy ALL Failed with error \
    583                         %s\n",ARG_CMD(a),bcm_errmsg(rv));
    584             }
    585             break;
    586 
    587 	case GLOBAL_METER_POLICER_SET:
    588             parse_table_add(&pt, "POLICER", PQ_HEX, 0, &policer_id, 0);
    589             parse_table_add(&pt, "POLICER_TYPE", PQ_STRING, 0, &mode_str, NULL);
    590             parse_table_add(&pt, "FLAG", PQ_INT, 0, &(pol_cfg.flags), 0);
    591             parse_table_add(&pt, "CommittedRate", 
    592                                           PQ_INT, 0, &(pol_cfg.ckbits_sec), 0);
    593             parse_table_add(&pt, "CommittedBurst", 
    594                                         PQ_INT, 0, &(pol_cfg.ckbits_burst), 0);
    595             parse_table_add(&pt, "PeakRate", 
    596                                           PQ_INT, 0, &(pol_cfg.pkbits_sec), 0);
    597             parse_table_add(&pt, "PeakBurst", 
    598                                         PQ_INT, 0, &(pol_cfg.pkbits_burst), 0);
    599             parse_table_add(&pt, "ACTION_ID", 
    600                                            PQ_INT, 0, &(pol_cfg.action_id), 0);
    601             parse_table_add(&pt, "SharingMode", 
    602                                         PQ_INT, 0, &(pol_cfg.sharing_mode), 0);
    603 
    604             if (parse_arg_eq(a, &pt) < 0) {
    605                 cli_out("Error: invalid option %s\n", ARG_CUR(a));
    606                 parse_arg_eq_done(&pt);
    607                 return CMD_USAGE;
    608             }
    609             if(mode_str != NULL) {
    610                 rv = _policer_mode_get(mode_str, &(pol_cfg.mode));
    611                 if (rv != BCM_E_NONE) {
    612                     parse_arg_eq_done(&pt);
    613                     return CMD_FAIL;
    614                 }
    615             } 
    616             parse_arg_eq_done(&pt);
    617             rv = bcm_policer_set(unit, policer_id, &pol_cfg); 
    618             if (rv == BCM_E_NONE) {
    619                 cli_out("Configured policer with id %x \n",policer_id);
    620             } else {
    621                 cli_out("%s Configure policer failed with error \
    622                         %s\n",ARG_CMD(a),bcm_errmsg(rv));
    623             }
    624 	    break;
    625 
    626 	case GLOBAL_METER_POLICER_GET:
    627             parse_table_add(&pt, "POLICER", PQ_HEX, 0, &policer_id, 0);
    628 	    if (!parseEndOk(a, &pt, &retCode)) {
    629 	        return retCode;
    630             }
    631 
    632             rv = bcm_policer_get(unit, policer_id, &pol_cfg); 
    633             if (rv == BCM_E_NONE) {
    634                 cli_out("Policer with id %x configuration params are \n",
    635                         policer_id);
    636                 rv = _policer_mode_name_get(pol_cfg.mode, &mode_name[0]);
    637                 if (rv == BCM_E_NONE) {
    638                     cli_out("Policer Type =%s \n",mode_name);
    639                 }
    640                 cli_out("Flag =%d \n", pol_cfg.flags);
    641                 cli_out("Committed rate =%d \n", pol_cfg.ckbits_sec);
    642                 cli_out("Committed Burst =%d \n", pol_cfg.ckbits_burst);
    643                 cli_out("Peak rate =%d \n", pol_cfg.pkbits_sec);
    644                 cli_out("Peak Burst =%d \n", pol_cfg.pkbits_burst);
    645                 cli_out("Action ID =%d \n", pol_cfg.action_id);
    646                 cli_out("Sharing Mode =%d \n", pol_cfg.sharing_mode);
    647             } else {
    648                 cli_out("%s Configure policer failed with error \
    649                         %s\n",ARG_CMD(a), bcm_errmsg(rv));
    650             }
    651             break;
    652 
    653 	case GLOBAL_METER_POLICER_TRAVERSE:
    654             rv = bcm_policer_traverse(unit, 
    655                                     _bcm_esw_policer_traverse_print, NULL); 
    656             if (rv == BCM_E_NONE) {
    657                 cli_out("policer traverse SUCCESS\n");
    658             } else {
    659                 cli_out("%s Destroy ALL Failed with error \
    660                         %s\n",ARG_CMD(a), bcm_errmsg(rv));
    661             }
    662             break;
    663 
    664 	default:
    665 	    return CMD_USAGE;
    666 	    break;
    667     }
    668     return CMD_OK;
    669 }
    670