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

mirror.c (8907B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  *
      7  * File:    mirror.c
      8  * Purpose: BCMX mirroring CLI commands
      9  */
     10 
     11 #include <bcm/mirror.h>
     12 #include <bcm/error.h>
     13 #include <bcmx/bcmx.h>
     14 #include <bcmx/mirror.h>
     15 
     16 #include <sal/appl/io.h>
     17 
     18 #include <appl/diag/shell.h>
     19 #include <appl/diag/system.h>
     20 #include <appl/diag/parse.h>
     21 
     22 #include "bcmx.h"
     23 #include <appl/diag/diag.h>
     24 
     25 char bcmx_cmd_mirror_usage[] =
     26     "Get/set mirroring configuration.  \nSyntax:\n"
     27     "  mirror                      -- Show the mirror mode and dest port\n"
     28     "  mirror [init | disable | enable <options>]\n"
     29     "                              -- Set the mirroring configuration\n"
     30 #ifndef COMPILER_STRING_CONST_LIMIT
     31     "Enable Options:\n"                  
     32     "  Mode=[L2|L3|Off]              -- Set the mirror mode\n"
     33     "  DESTport=<user-port>          -- Set the mirror destination port\n"
     34     "  IngressPorts=<user-port-list> -- Enable/disable ingress mirroring\n"
     35     "  EgressPorts=<user-port-list>  -- Enable/disable egress mirroring\n"
     36 #endif
     37     "\nNote:  Not all modes are supported in all systems\n";
     38 
     39 cmd_result_t
     40 bcmx_cmd_mirror(int unit, args_t *args)
     41 {
     42     parse_table_t pt;
     43     int mode;
     44     int enable = 1;   /* Should ports listed have mirroring enabled or dis */
     45     char *iport;
     46     char *eport;
     47     char *dport;
     48     bcmx_lplist_t ports;
     49     bcmx_lport_t lport;
     50     int count;
     51     cmd_result_t cmd_rv = CMD_OK;
     52     int rv;
     53     char                *subcmd = NULL;
     54     int mirror_mode;
     55     bcmx_uport_t uport;
     56 
     57     static char *modeList[] = {"L2", "L3", "Off", NULL};
     58 
     59     if ((subcmd = ARG_GET(args)) == NULL) {
     60         int first;
     61         int val;
     62 
     63         bcmx_mirror_mode_get(&mirror_mode);
     64         bcmx_mirror_to_get(&lport);
     65 
     66         if (mirror_mode == BCM_MIRROR_DISABLE) {
     67             sal_printf("Mirroring is currently disabled.\n");
     68         } else {
     69             sal_printf("Current mirror mode is:  %s.\n",
     70                 mirror_mode == BCM_MIRROR_L2 ? "L2" : "L3");
     71             if (!BCMX_LPORT_VALID(lport)) {
     72                 sal_printf("Warning:  mirror to port is invalid\n");
     73             }
     74         }
     75         if (BCMX_LPORT_VALID(lport)) {
     76             sal_printf("Current mirror to uport is %s (lport 0x%x).\n",
     77                        bcmx_lport_to_uport_str(lport), lport);
     78         }
     79         first = TRUE;
     80         BCMX_FOREACH_LPORT(lport) {
     81             if (bcmx_mirror_ingress_get(lport, &val) == BCM_E_NONE) {
     82                 if (val) {
     83                     if (first) {
     84                         sal_printf("    Ingress uport: %s",
     85                                    bcmx_lport_to_uport_str(lport));
     86                         first = FALSE;
     87                     } else {
     88                         sal_printf(" %s", bcmx_lport_to_uport_str(lport));
     89                     }
     90                 }
     91             }
     92         }
     93         if (!first) {
     94             sal_printf("\n");
     95         }
     96         first = TRUE;
     97         BCMX_FOREACH_LPORT(lport) {
     98             if (bcmx_mirror_egress_get(lport, &val) == BCM_E_NONE) {
     99                 if (val) {
    100                     if (first) {
    101                         sal_printf("    Egress uport: %s",
    102                                    bcmx_lport_to_uport_str(lport));
    103                         first = FALSE;
    104                     } else {
    105                         sal_printf(" %s", bcmx_lport_to_uport_str(lport));
    106                     }
    107 
    108                 }
    109             }
    110         }
    111         if (!first) {
    112             sal_printf("\n");
    113         }
    114 
    115         return CMD_OK;
    116     }
    117 
    118     if (! sal_strcasecmp(subcmd, "init")) {
    119         sal_printf("Mirror init returns %d\n", bcmx_mirror_init());
    120         return CMD_OK;
    121     } else if (! sal_strcasecmp(subcmd, "disable")) {
    122         sal_printf("Mirror mode(disable) returns %d\n",
    123                    bcmx_mirror_mode_set(BCM_MIRROR_DISABLE));
    124     } else if (! sal_strcasecmp(subcmd, "enable")) {
    125 
    126         parse_table_init(unit, &pt);
    127         parse_table_add(&pt, "Mode", PQ_NO_EQ_OPT | PQ_MULTI,
    128                         0, &mode, modeList);
    129         parse_table_add(&pt, "DESTport", PQ_NO_EQ_OPT | PQ_STRING,
    130                         0, &dport, NULL);
    131         parse_table_add(&pt, "IngressPorts", PQ_NO_EQ_OPT | PQ_STRING,
    132                         0, &iport, NULL);
    133         parse_table_add(&pt, "EgressPorts", PQ_NO_EQ_OPT | PQ_STRING,
    134                         0, &eport, NULL);
    135 
    136         /*
    137          * Check for each operation indicated and carry out sequentially 
    138          * Be careful about memory leaks with lplist.  Each segment should
    139          * init and free the list consistently.
    140          */
    141 
    142         if (parse_arg_eq(args, &pt) < 0) {
    143             sal_printf("%s: Error: Unknown option: %s\n", ARG_CMD(args),
    144                        ARG_CUR(args));
    145             parse_arg_eq_done(&pt);
    146             return(CMD_FAIL);
    147         }
    148 
    149         /* Set dest port first to make things happen right */
    150 
    151         if (pt.pt_entries[1].pq_type & PQ_PARSED) { /* Destination port given */
    152             uport = bcmx_uport_parse(dport, NULL);
    153             lport = bcmx_uport_to_lport(uport);
    154             if (lport == BCMX_NO_SUCH_LPORT) {
    155                 sal_printf("%s: bad destination port given: %s\n",
    156                            ARG_CMD(args), dport);
    157                 parse_arg_eq_done(&pt);
    158                 return CMD_FAIL;
    159             }
    160             rv = bcmx_mirror_to_set(lport);
    161             if (rv < 0) {
    162                 sal_printf("%s: bcmx_mirror_to_set failed, %d: %s\n",
    163                            ARG_CMD(args), rv, bcm_errmsg(rv));
    164                 parse_arg_eq_done(&pt);
    165                 return(CMD_FAIL);
    166             }
    167         }
    168 
    169         if (pt.pt_entries[2].pq_type & PQ_PARSED) { /* Ingress ports given */
    170             if (bcmx_lplist_init(&ports, 0, 0) < 0) {
    171                 sal_printf("%s: Could not init port list\n",
    172                            ARG_CMD(args));
    173                 parse_arg_eq_done(&pt);
    174                 return CMD_FAIL;
    175             }
    176 
    177             if (bcmx_lplist_parse(&ports, iport) < 0) {
    178                 sal_printf("%s: Could not parse user port list: %s\n",
    179                            ARG_CMD(args), iport);
    180                 cmd_rv = CMD_FAIL;
    181             } else {
    182                 BCMX_LPLIST_ITER(ports, lport, count) {
    183                     rv = bcmx_mirror_ingress_set(lport, enable);
    184                     if (rv < 0) {
    185                         sal_printf("%s: Could not %s ingress mirroring for %s\n",
    186                                    ARG_CMD(args),
    187                                    "enable", 
    188                                    bcmx_lport_to_uport_str(lport));
    189                         cmd_rv = CMD_FAIL;
    190                         break;
    191                     }
    192                 }
    193             }
    194 
    195             bcmx_lplist_free(&ports);
    196         }
    197 
    198         if ((cmd_rv == CMD_OK) && (pt.pt_entries[3].pq_type & PQ_PARSED)) {
    199             /* Engress ports given */
    200             if (bcmx_lplist_init(&ports, 0, 0) < 0) {
    201                 sal_printf("%s: Could not init port list\n",
    202                            ARG_CMD(args));
    203                 parse_arg_eq_done(&pt);
    204                 return CMD_FAIL;
    205             }
    206 
    207             if (bcmx_lplist_parse(&ports, eport) < 0) {
    208                 sal_printf("Could not parse user port list: %s\n", eport);
    209                 cmd_rv = CMD_FAIL;
    210             } else {
    211                 BCMX_LPLIST_ITER(ports, lport, count) {
    212                     rv = bcmx_mirror_egress_set(lport, enable);
    213                     if (rv < 0) {
    214                         sal_printf("%s: Could not %s egress mirroring for %s\n",
    215                                    ARG_CMD(args),
    216                                    "enable",
    217                                    bcmx_lport_to_uport_str(lport));
    218                         cmd_rv = CMD_FAIL;
    219                         break;
    220                     }
    221                 }
    222             }
    223 
    224             bcmx_lplist_free(&ports);
    225         }
    226 
    227         if (pt.pt_entries[0].pq_type & PQ_PARSED) { /* Mode given */
    228             switch (mode) {
    229             case 0: mode = BCM_MIRROR_L2; break;
    230             case 1: mode = BCM_MIRROR_L2_L3; break;
    231             case 2: mode = BCM_MIRROR_DISABLE; break;
    232             default:
    233                 sal_printf("%s: Unknown mode, %d.\n", ARG_CMD(args), mode);
    234                 parse_arg_eq_done(&pt);
    235                 return CMD_FAIL;
    236             }
    237 
    238             rv = bcmx_mirror_mode_set(mode);
    239             if (rv < 0) {
    240                 sal_printf("%s: bcmx_mirror_mode_set failed, %d: %s\n",
    241                            ARG_CMD(args), rv, bcm_errmsg(rv));
    242                 parse_arg_eq_done(&pt);
    243                 return CMD_FAIL;
    244             }
    245         }
    246 
    247         parse_arg_eq_done(&pt);
    248 
    249     } else {
    250         sal_printf("Unknown mirror subcommand: %s\n", subcmd);
    251         return CMD_USAGE;
    252     }
    253     return cmd_rv;
    254 }
    255