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

ipfix.c (19119B)


      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  * Diag CLI IPFIX command
      8  */
      9 
     10 #include <appl/diag/system.h>
     11 #include <appl/diag/parse.h>
     12 #include <shared/bsl.h>
     13 #include <bcm/error.h>
     14 #include <bcm/ipfix.h>
     15 #include <bcm_int/esw/ipfix.h>
     16 
     17 char cmd_ipfix_usage[] =
     18     "Parameters: [report +/-<values>] [set <values>] [stop|start]\n"
     19 #ifndef COMPILER_STRING_CONST_LIMIT
     20     "\t  start  - Start the IPFIX deamon\n"
     21     "\t  stop   - Stop the IPFIX deamon\n"
     22     "\t  report - Configure reporting to the console\n"
     23     "\t      count   - print export entry # only\n"
     24     "\t      decode  - dump decoded export entry\n"
     25     "\t      Prepend + to set, - to clear\n"
     26     "\t  set    - Configure IPFIX for a port\n"
     27     "\t     Port=<port> [Stage=<stage>] [EnableL2=<1/0>] [EnableIp4=<1/0>]\n"
     28     "\t     [EnableIp6=<1/0>] [RecordNonDiscard=<1/0>] [RecordDiscard=<1/0>]\n"
     29     "\t     [CheckFlowEnd=<1/0>] [UseL2ForIp4=<1/0>] [UseL2ForIp6=<1/0>]\n"
     30     "\t     [KeySrcIp=<1/0>] [KeyIpProt=<1/0>] [KeyIpDscp=<1/0>] [KeyIpEcn=<1/0>]\n"
     31     "\t     [KeyDstIp=<1/0>] [KeyIpEcn=<1/0>] [KeyL4SrcPort=<1/0>] [KeyL4DstPort=<1/0>]\n"
     32     "\t     [KeyIp6Flow=<1/0>] [KeyIcmpType=<1/0>] [KeyIcmpCode=<1/0>] [KeyMacDa=<1/0>]\n"
     33     "\t     [KeyMacSa=<1/0>] [KeyVlanId=<1/0>] [KeyVlanPri=<1/0>] [KeyEtherType=<1/0>]\n"
     34     "\t     [KeyVlanTagged=<1/0>] [TunnelIp4SrcMask=<adr>]\n"
     35     "\t     [TunnelIp4DstMask=<adr>] [TunnelIp6SrcMask=<adr>]\n"
     36     "\t     [Ip4SrcMask=<adr>][Ip4DstMask=<adr>]\n"
     37     "\t     [Ip6SrcMask=<adr>][Ip6DstMask=<adr>]\n"
     38     "\t     [DscpMap=zero|identical][Limit=<val>]\n"
     39     "\t     [MaXTime=<val>][MiNTime=<val>]\n"
     40     "\t     [MaxIdletime=<val>][SampleRate=<val>]\n"
     41 #endif
     42 ;
     43 
     44 static int ipfix_report_count[BCM_MAX_NUM_UNITS] = { 0 };
     45 static int ipfix_is_running[BCM_MAX_NUM_UNITS] = { 0 };
     46 static uint32 ipfix_report[BCM_MAX_NUM_UNITS] = { 0 };
     47 
     48 static const char *dscp_names[] = {
     49     "identical",
     50     "zero",
     51     NULL
     52 };
     53 
     54 #define REPORT_COUNT    0x01   /* Report export count */
     55 #define REPORT_DECODE   0x02   /* Report Decoded export data */
     56 
     57 static const parse_pm_t ipfix_report_table[] = {
     58     {"Count",   REPORT_COUNT},
     59     {"Decode",  REPORT_DECODE},
     60     {"@ALL",    ~0},
     61     {"@*",      ~0},
     62     {NULL,      0}
     63 };
     64 
     65 void
     66 _ipfix_callback(int unit, bcm_ipfix_data_t *info, void *userdata)
     67 {
     68     ipfix_report_count[unit]++;
     69 
     70     if (ipfix_report[unit] & REPORT_COUNT) {
     71         cli_out("Export entry #%d.\n", ipfix_report_count[unit]);
     72     }
     73     if (ipfix_report[unit] & REPORT_DECODE) {
     74         bcm_ipfix_dump_export_entry(unit, info);
     75     }
     76 }
     77 
     78 cmd_result_t
     79 cmd_ipfix(int unit, args_t *arg)
     80 {
     81     char *subcmd;
     82     parse_table_t pt;
     83     bcm_ipfix_config_t config;
     84     int rv, i;
     85     int port = 0;
     86     bcm_ip_t src_ip4_mask = 0, dst_ip4_mask = 0;
     87     bcm_ip_t tunnel_src_ip4_mask = 0, tunnel_dst_ip4_mask = 0;
     88     bcm_ip6_t src_ip6_mask, dst_ip6_mask;
     89     bcm_ip6_t tunnel_src_ip6_mask, tunnel_dst_ip6_mask;
     90     int enable_l2 = 0, enable_ip4 = 0, enable_ip6 = 0;
     91     int record_non_discard = 1, record_discard = 0, check_flow_end = 0;
     92     int use_l2_for_ip4 = 0, use_l2_for_ip6 = 0;
     93     int key_src_ip = 0, key_dst_ip = 0; 
     94     int  key_ip_prot = 0, key_ip_dscp = 0, key_ip_ecn = 0;
     95     int key_l4_src_port = 0, key_l4_dst_port = 0, key_ip6_flow = 0;
     96     int key_icmp_type = 0, key_icmp_code = 0, key_macda = 0, key_macsa = 0;
     97     int key_vlan_id = 0, key_vlan_pri = 0, key_ether_type = 0; 
     98     int key_vlan_tagged = 0, key_source_port = 0;
     99     int stage = 0, dscp_idx = 0, entry_limit = 8191;
    100     int min_time = 0, max_time = 0;
    101     int max_idle_time = 32767, sample_rate = 1;
    102     char str[IP6ADDR_STR_LEN];
    103 
    104     if (!ARG_CNT(arg)) {                  /* Nothing passed */
    105         cli_out("IPFIX Deamon Status: %s.\n",
    106                 (ipfix_is_running[unit]) ? "Running" : "Not Running");
    107 
    108         cli_out("Reporting is enabled for: ");
    109         parse_mask_format(80, ipfix_report_table, ipfix_report[unit]);
    110         cli_out("Reporting is disabled for: ");
    111         parse_mask_format(80, ipfix_report_table, ipfix_report[unit] ^ ~0);
    112 
    113         cli_out("Number of records received: %d\n", ipfix_report_count[unit]);
    114         return(CMD_OK);
    115     }
    116 
    117     subcmd = ARG_GET(arg);
    118     if (subcmd == NULL) {
    119         return CMD_USAGE;
    120     }
    121 
    122     rv = BCM_E_NONE;
    123     sal_memset(src_ip6_mask, 0, sizeof(bcm_ip6_t));
    124     sal_memset(dst_ip6_mask, 0, sizeof(bcm_ip6_t));
    125     sal_memset(tunnel_src_ip6_mask, 0, sizeof(bcm_ip6_t));
    126     sal_memset(tunnel_dst_ip6_mask, 0, sizeof(bcm_ip6_t));
    127 
    128     if (!sal_strcasecmp(subcmd, "start")) {
    129         if (ipfix_is_running[unit]) {
    130             cli_out("%s: IPFIX thread already running.\n", ARG_CMD(arg));
    131             return CMD_OK;
    132         }
    133         ipfix_report_count[unit] = 0;
    134         ipfix_is_running[unit] = 1;
    135         rv = bcm_ipfix_export_fifo_control(unit, 1000000);
    136         if (rv < 0) {
    137             cli_out("%s: ERROR: %s\n", ARG_CMD(arg), bcm_errmsg(rv));
    138             return CMD_FAIL;
    139         }
    140         rv = bcm_ipfix_register(unit, _ipfix_callback, NULL);
    141     } else if (!sal_strcasecmp(subcmd, "stop")) {
    142         if (!ipfix_is_running[unit]) {
    143             cli_out("%s: ERROR: IPFIX thread already stopped.\n", ARG_CMD(arg));
    144             return CMD_FAIL;
    145         }
    146         ipfix_is_running[unit] = 0;
    147         rv = bcm_ipfix_export_fifo_control(unit, 0);
    148         if (rv < 0) {
    149             cli_out("%s: ERROR: %s\n", ARG_CMD(arg), bcm_errmsg(rv));
    150             return CMD_FAIL;
    151         }
    152         rv = bcm_ipfix_unregister(unit, _ipfix_callback, NULL);
    153     } else if (!sal_strcasecmp(subcmd, "set")) {
    154         parse_table_init(unit, &pt);
    155         parse_table_add(&pt, "Port", PQ_DFL | PQ_INT, (void *)-1, &port, 0);
    156         parse_table_add(&pt, "Stage", PQ_DFL | PQ_INT, (void *)0, &stage, 0);
    157         parse_table_add(&pt, "EnableL2", PQ_DFL | PQ_INT, (void *)0,
    158                         &enable_l2, 0);
    159         parse_table_add(&pt, "EnableIp4", PQ_DFL | PQ_INT, (void *)0,
    160                         &enable_ip4, 0);
    161         parse_table_add(&pt, "EnableIp6", PQ_DFL | PQ_INT, (void *)0,
    162                         &enable_ip6, 0);
    163         parse_table_add(&pt, "RecordNonDiscard", PQ_DFL | PQ_INT, (void *)0,
    164                         &record_non_discard, 0);
    165         parse_table_add(&pt, "RecordDiscard", PQ_DFL | PQ_INT, (void *)0,
    166                         &record_discard, 0);
    167         parse_table_add(&pt, "CheckFlowEnd", PQ_DFL | PQ_INT, (void *)0,
    168                         &check_flow_end, 0);
    169         parse_table_add(&pt, "UseL2ForIp4", PQ_DFL | PQ_INT, (void *)0,
    170                         &use_l2_for_ip4, 0);
    171         parse_table_add(&pt, "UseL2ForIp6", PQ_DFL | PQ_INT, (void *)0,
    172                         &use_l2_for_ip6, 0);
    173         parse_table_add(&pt, "KeySrcIp", PQ_DFL | PQ_INT, (void *)0,
    174                         &key_src_ip, 0);
    175         parse_table_add(&pt, "KeyIpProt", PQ_DFL | PQ_INT, (void *)0,
    176                         &key_ip_prot, 0);
    177         parse_table_add(&pt, "KeyIpDscp", PQ_DFL | PQ_INT, (void *)0,
    178                         &key_ip_dscp, 0);
    179         parse_table_add(&pt, "KeyIpEcn", PQ_DFL | PQ_INT, (void *)0,
    180                         &key_ip_ecn, 0);
    181         parse_table_add(&pt, "KeyDstIp", PQ_DFL | PQ_INT, (void *)0,
    182                         &key_dst_ip, 0);
    183         parse_table_add(&pt, "KeyIpEcn", PQ_DFL | PQ_INT, (void *)0,
    184                         &key_ip_ecn, 0);
    185         parse_table_add(&pt, "KeyL4SrcPort", PQ_DFL | PQ_INT, (void *)0,
    186                         &key_l4_src_port, 0);
    187         parse_table_add(&pt, "KeyL4DstPort", PQ_DFL | PQ_INT, (void *)0,
    188                         &key_l4_dst_port, 0);
    189         parse_table_add(&pt, "KeyIp6Flow", PQ_DFL | PQ_INT, (void *)0,
    190                         &key_ip6_flow, 0);
    191         parse_table_add(&pt, "KeyIcmpType", PQ_DFL | PQ_INT, (void *)0,
    192                         &key_icmp_type, 0);
    193         parse_table_add(&pt, "KeyIcmpCode", PQ_DFL | PQ_INT, (void *)0,
    194                         &key_icmp_code, 0);
    195         parse_table_add(&pt, "KeyMacDa", PQ_DFL | PQ_INT, (void *)0,
    196                         &key_macda, 0);
    197         parse_table_add(&pt, "KeyMacSa", PQ_DFL | PQ_INT, (void *)0,
    198                         &key_macsa, 0);
    199         parse_table_add(&pt, "KeyVlanId", PQ_DFL | PQ_INT, (void *)0,
    200                         &key_vlan_id, 0);
    201         parse_table_add(&pt, "KeyVlanPri", PQ_DFL | PQ_INT, (void *)0,
    202                         &key_vlan_pri, 0);
    203         parse_table_add(&pt, "KeyEtherType", PQ_DFL | PQ_INT, (void *)0,
    204                         &key_ether_type, 0);
    205         parse_table_add(&pt, "KeyVlanTagged", PQ_DFL | PQ_INT, (void *)0,
    206                         &key_vlan_tagged, 0);
    207         parse_table_add(&pt, "KeySourcePort", PQ_DFL | PQ_INT, (void *)0,
    208                         &key_source_port, 0);
    209         parse_table_add(&pt, "Ip4SrcMask", PQ_DFL | PQ_IP, 0, &src_ip4_mask,
    210                         0);
    211         parse_table_add(&pt, "Ip4DstMask", PQ_DFL | PQ_IP, 0, &dst_ip4_mask,
    212                         0);
    213         parse_table_add(&pt, "TunnelIp4SrcMask", PQ_DFL | PQ_IP, 0,
    214                         &tunnel_src_ip4_mask, 0);
    215         parse_table_add(&pt, "TunnelIp4DstMask", PQ_DFL | PQ_IP, 0,
    216                         &tunnel_dst_ip4_mask, 0);
    217         parse_table_add(&pt, "Ip6SrcMask", PQ_DFL | PQ_IP6, 0, &src_ip6_mask,
    218                         0);
    219         parse_table_add(&pt, "Ip6DstMask", PQ_DFL | PQ_IP6, 0, &dst_ip6_mask,
    220                         0);
    221         parse_table_add(&pt, "TunnelIp6SrcMask", PQ_DFL | PQ_IP6, 0,
    222                         &tunnel_src_ip6_mask, 0);
    223         parse_table_add(&pt, "TunnelIp6DstMask", PQ_DFL | PQ_IP6, 0,
    224                         &tunnel_dst_ip6_mask, 0);
    225         parse_table_add(&pt, "DscpMap", PQ_DFL | PQ_MULTI, 0, &dscp_idx,
    226                         dscp_names);
    227         parse_table_add(&pt, "Limit", PQ_DFL | PQ_INT, (void *)0,
    228                         &entry_limit, 0);
    229         parse_table_add(&pt, "MinTime", PQ_DFL | PQ_INT, (void *)0,
    230                         &min_time, 0);
    231         parse_table_add(&pt, "MaxTime", PQ_DFL | PQ_INT, (void *)0,
    232                         &max_time, 0);
    233         parse_table_add(&pt, "MaxIdleTime", PQ_DFL | PQ_INT, (void *)0,
    234                         &max_idle_time, 0);
    235         parse_table_add(&pt, "SampleRate", PQ_DFL | PQ_INT, (void *)0,
    236                         &sample_rate, 0);
    237 
    238         if (parse_arg_eq(arg, &pt) < 0) {
    239             parse_arg_eq_done(&pt);
    240             return CMD_USAGE;
    241         }
    242         parse_arg_eq_done(&pt);
    243 
    244         sal_memset(&config, 0, sizeof(config));
    245         config.flags |= enable_l2 ? BCM_IPFIX_CONFIG_ENABLE_NON_IP : 0;
    246         config.flags |= enable_ip4 ? BCM_IPFIX_CONFIG_ENABLE_IP4 : 0;
    247         config.flags |= enable_ip6 ? BCM_IPFIX_CONFIG_ENABLE_IP6 : 0;
    248         config.flags |= check_flow_end ? BCM_IPFIX_CONFIG_TCP_END_DETECT : 0;
    249         config.flags |= record_non_discard ?
    250             BCM_IPFIX_CONFIG_RECORD_NON_DISCARD_PKT : 0;
    251         config.flags |= record_discard ?
    252             BCM_IPFIX_CONFIG_RECORD_DISCARD_PKT : 0;
    253         config.flags |= use_l2_for_ip4 ? BCM_IPFIX_CONFIG_KEY_IP4_USE_L2 : 0;
    254         config.flags |= use_l2_for_ip6 ? BCM_IPFIX_CONFIG_KEY_IP6_USE_L2 : 0;
    255         config.flags |= key_src_ip ? BCM_IPFIX_CONFIG_KEY_SRC_IP : 0;
    256         config.flags |= key_dst_ip ? BCM_IPFIX_CONFIG_KEY_DST_IP : 0;
    257         config.flags |= key_ip_prot ? BCM_IPFIX_CONFIG_KEY_IP_PROT : 0;
    258         config.flags |= key_ip_dscp ? BCM_IPFIX_CONFIG_KEY_IP_DSCP : 0;
    259         config.flags |= key_ip_ecn ? BCM_IPFIX_CONFIG_KEY_IP_ECN : 0;
    260         config.flags |= key_l4_src_port ? BCM_IPFIX_CONFIG_KEY_L4_SRC_PORT : 0;
    261         config.flags |= key_l4_dst_port ? BCM_IPFIX_CONFIG_KEY_L4_DST_PORT : 0;
    262         config.flags |= key_ip6_flow ? BCM_IPFIX_CONFIG_KEY_IP6_FLOW : 0;
    263         config.flags |= key_icmp_type ? BCM_IPFIX_CONFIG_KEY_ICMP_TYPE : 0;
    264         config.flags |= key_icmp_code ? BCM_IPFIX_CONFIG_KEY_ICMP_CODE : 0;
    265         config.flags |= key_macda ? BCM_IPFIX_CONFIG_KEY_MACDA : 0;
    266         config.flags |= key_macsa ? BCM_IPFIX_CONFIG_KEY_MACSA : 0;
    267         config.flags |= key_vlan_id ? BCM_IPFIX_CONFIG_KEY_VLAN_ID : 0;
    268         config.flags |= key_vlan_pri ? BCM_IPFIX_CONFIG_KEY_VLAN_PRI : 0;
    269         config.flags |= key_ether_type ? BCM_IPFIX_CONFIG_KEY_ETHER_TYPE : 0;
    270         config.flags |= key_vlan_tagged ? BCM_IPFIX_CONFIG_KEY_VLAN_TAGGED : 0;
    271         config.flags |= key_source_port ?
    272             BCM_IPFIX_CONFIG_KEY_SOURCE_PORT_OR_INTERFACE : 0;
    273 
    274         if (dscp_idx == 0) {
    275             for (i = 0; i < 64; i++) {
    276                 config.dscp_mask[i] = i;
    277             }
    278         } else {
    279             for (i = 0; i < 64; i++) {
    280                 config.dscp_mask[i] = 0;
    281             }
    282         }
    283         config.src_ip4_mask = src_ip4_mask;
    284         config.dst_ip4_mask = dst_ip4_mask;
    285         config.tunnel_src_ip4_mask = tunnel_src_ip4_mask;
    286         config.tunnel_dst_ip4_mask = tunnel_dst_ip4_mask;
    287         SAL_IP6_ADDR_TO_UINT32(src_ip6_mask, (uint32 *)config.src_ip6_mask);
    288         SAL_IP6_ADDR_TO_UINT32(dst_ip6_mask, (uint32 *)config.dst_ip6_mask);
    289         SAL_IP6_ADDR_TO_UINT32(tunnel_src_ip6_mask,
    290                                (uint32 *)config.tunnel_src_ip6_mask);
    291         SAL_IP6_ADDR_TO_UINT32(tunnel_dst_ip6_mask,
    292                                (uint32 *)config.tunnel_dst_ip6_mask);
    293         config.entry_limit = entry_limit;
    294         config.min_time = min_time;
    295         config.max_time = max_time;
    296         config.max_idle_time = max_idle_time;
    297         config.sample_rate = sample_rate;
    298         rv = bcm_ipfix_config_set(unit, stage, port, &config);
    299     } else if (!sal_strcasecmp(subcmd, "get")) {
    300         parse_table_init(unit, &pt);
    301         parse_table_add(&pt, "Port", PQ_DFL | PQ_INT, (void *)-1, &port, 0);
    302         parse_table_add(&pt, "Stage", PQ_DFL | PQ_INT, (void *)0, &stage, 0);
    303         if (parse_arg_eq(arg, &pt) < 0) {
    304             parse_arg_eq_done(&pt);
    305             return CMD_USAGE;
    306         }
    307         parse_arg_eq_done(&pt);
    308 
    309         rv = bcm_ipfix_config_get(unit, stage, port, &config);
    310         if (rv >= 0) {
    311             if (config.flags & BCM_IPFIX_CONFIG_ENABLE_NON_IP) {
    312                 cli_out("BCM_IPFIX_CONFIG_ENABLE_NON_IP\n");
    313             }
    314             if (config.flags & BCM_IPFIX_CONFIG_ENABLE_IP4) {
    315                 cli_out("BCM_IPFIX_CONFIG_ENABLE_IP4\n");
    316             }
    317             if (config.flags & BCM_IPFIX_CONFIG_ENABLE_IP6) {
    318                 cli_out("BCM_IPFIX_CONFIG_ENABLE_IP6\n");
    319             }
    320             if (config.flags & BCM_IPFIX_CONFIG_TCP_END_DETECT) {
    321                 cli_out("BCM_IPFIX_CONFIG_TCP_END_DETECT\n");
    322             }
    323             if (config.flags & BCM_IPFIX_CONFIG_RECORD_NON_DISCARD_PKT) {
    324                 cli_out("BCM_IPFIX_CONFIG_RECORD_NON_DISCARD_PKT\n");
    325             }
    326             if (config.flags & BCM_IPFIX_CONFIG_RECORD_DISCARD_PKT) {
    327                 cli_out("BCM_IPFIX_CONFIG_RECORD_DISCARD_PKT\n");
    328             }
    329             if (config.flags & BCM_IPFIX_CONFIG_KEY_IP4_USE_L2) {
    330                 cli_out("BCM_IPFIX_CONFIG_KEY_IP4_USE_L2\n");
    331             }
    332             if (config.flags & BCM_IPFIX_CONFIG_KEY_IP6_USE_L2) {
    333                 cli_out("BCM_IPFIX_CONFIG_KEY_IP6_USE_L2\n");
    334             }
    335             if (config.flags & BCM_IPFIX_CONFIG_KEY_SRC_IP) {
    336                 cli_out("BCM_IPFIX_CONFIG_KEY_SRC_IP\n");
    337             }
    338             if (config.flags & BCM_IPFIX_CONFIG_KEY_DST_IP) {
    339                 cli_out("BCM_IPFIX_CONFIG_KEY_DST_IP\n");
    340             }
    341             if (config.flags & BCM_IPFIX_CONFIG_KEY_IP_PROT) {
    342                 cli_out("BCM_IPFIX_CONFIG_KEY_IP_PROT\n");
    343             }
    344             if (config.flags & BCM_IPFIX_CONFIG_KEY_IP_DSCP) {
    345                 cli_out("BCM_IPFIX_CONFIG_KEY_IP_DSCP\n");
    346             }
    347             if (config.flags & BCM_IPFIX_CONFIG_KEY_IP_ECN) {
    348                 cli_out("BCM_IPFIX_CONFIG_KEY_IP_ECN\n");
    349             }
    350             if (config.flags & BCM_IPFIX_CONFIG_KEY_L4_SRC_PORT) {
    351                 cli_out("BCM_IPFIX_CONFIG_KEY_L4_SRC_PORT\n");
    352             }
    353             if (config.flags & BCM_IPFIX_CONFIG_KEY_L4_DST_PORT) {
    354                 cli_out("BCM_IPFIX_CONFIG_KEY_L4_DST_PORT\n");
    355             }
    356             if (config.flags & BCM_IPFIX_CONFIG_KEY_IP6_FLOW) {
    357                 cli_out("BCM_IPFIX_CONFIG_KEY_IP6_FLOW\n");
    358             }
    359             if (config.flags & BCM_IPFIX_CONFIG_KEY_ICMP_TYPE) {
    360                 cli_out("BCM_IPFIX_CONFIG_KEY_ICMP_TYPE\n");
    361             }
    362             if (config.flags & BCM_IPFIX_CONFIG_KEY_ICMP_CODE) {
    363                 cli_out("BCM_IPFIX_CONFIG_KEY_ICMP_CODE\n");
    364             }
    365             if (config.flags & BCM_IPFIX_CONFIG_KEY_MACDA) {
    366                 cli_out("BCM_IPFIX_CONFIG_KEY_MACDA\n");
    367             }
    368             if (config.flags & BCM_IPFIX_CONFIG_KEY_MACSA) {
    369                 cli_out("BCM_IPFIX_CONFIG_KEY_MACSA\n");
    370             }
    371             if (config.flags & BCM_IPFIX_CONFIG_KEY_VLAN_ID) {
    372                 cli_out("BCM_IPFIX_CONFIG_KEY_VLAN_ID\n");
    373             }
    374             if (config.flags & BCM_IPFIX_CONFIG_KEY_VLAN_PRI) {
    375                 cli_out("BCM_IPFIX_CONFIG_KEY_VLAN_PRI\n");
    376             }
    377             if (config.flags & BCM_IPFIX_CONFIG_KEY_ETHER_TYPE) {
    378                 cli_out("BCM_IPFIX_CONFIG_KEY_ETHER_TYPE\n");
    379             }
    380             if (config.flags & BCM_IPFIX_CONFIG_KEY_VLAN_TAGGED) {
    381                 cli_out("BCM_IPFIX_CONFIG_KEY_VLAN_TAGGED\n");
    382             }
    383             if (config.flags & BCM_IPFIX_CONFIG_TCP_FLAGS_LAST) {
    384                 cli_out("BCM_IPFIX_CONFIG_TCP_FLAGS_LAST\n");
    385             }
    386             cli_out("entry_limit=%d min_time=%d max_time=%d\n",
    387                     config.entry_limit, config.min_time, config.max_time);
    388             cli_out("max_idle_time=%d sample_rate=%d\n",
    389                     config.max_idle_time, config.sample_rate);
    390             format_ipaddr(str, config.src_ip4_mask);
    391             cli_out("src_ip4_mask %s\n", str);
    392             format_ipaddr(str, config.dst_ip4_mask);
    393             cli_out("dst_ip4_mask %s\n", str);
    394             format_ip6addr(str, config.src_ip6_mask);
    395             cli_out("src_ip6_mask %s\n", str);
    396             format_ip6addr(str, config.dst_ip6_mask);
    397             cli_out("dst_ip6_mask %s\n", str);
    398         }
    399     } else if (!sal_strcasecmp(subcmd, "report")) {
    400         if (ARG_CNT(arg)) {
    401             while ((subcmd = ARG_CUR(arg)) != NULL &&
    402                    !parse_mask(subcmd, ipfix_report_table, &ipfix_report[unit])) {
    403                 ARG_NEXT(arg);        /* Bump arg if matched report */
    404             }
    405         } else {                    /* Print values */
    406             cli_out("IPFIX Reporting on for: ");
    407             parse_mask_format(50, ipfix_report_table, ipfix_report[unit]);
    408             cli_out("IPFIX Reporting off for: ");
    409             parse_mask_format(50, ipfix_report_table, ~ipfix_report[unit]);
    410         }
    411     } else {
    412         return CMD_USAGE;
    413     }
    414 
    415     if (rv < 0) {
    416         cli_out("%s: ERROR: %s\n", ARG_CMD(arg), bcm_errmsg(rv));
    417         return CMD_FAIL;
    418     }
    419 
    420     return CMD_OK;
    421 }