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

mcast.c (12054B)


      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:        mcast.c
      8  * Purpose:
      9  * Requires:
     10  */
     11 
     12 #include <bcm/types.h>
     13 #include <bcm/error.h>
     14 #include <shared/bsl.h>
     15 #include <bcmx/mcast.h>
     16 
     17 #include <appl/diag/parse.h>
     18 #include <appl/diag/shell.h>
     19 #include <appl/diag/system.h>
     20 #include "bcmx.h"
     21 
     22 char bcmx_cmd_mcast_usage[] =
     23     "Usages:\n"
     24 #ifdef COMPILER_STRING_CONST_LIMIT
     25     "  mcast init | add | del | padd | pdel | lookup\n"
     26     "  mcast test add | del\n"
     27 #else
     28     "  mcast init\n"
     29     "         - Initialize BMCX mcast stuff\n"
     30     "  mcast add [Ports=<user-port-list>] [UntagPorts=<user-port-list>]\n"
     31     "         [MACaddress=<mac>] [Vlanid=<id>] [CosDst=<COS Value>]\n"
     32     "        - Add L2 Multicast address & associated with port(s)\n"
     33     "  mcast del [MACaddress=<mac>] [Vlanid=<id>]\n"
     34     "        - Delete the given L2 Multicast Address\n"
     35     "  mcast padd [Ports=<user-port-list>] [UntagPorts=<user-port-list>]\n"
     36     "          [MACaddress=<mac>] [Vlanid=<id>] [CosDst=<COS Value>]\n"
     37     "        - Add ports to an existing L2 Multicast address\n"
     38     "  mcast pdel [Ports=<user-port-list>] [MACaddress=<mac>] [Vlanid=<id>]\n"
     39     "        - Delete ports from an existing L2 Multicast Address\n"
     40     "  mcast lookup MACaddress=<mac> Vlanid=<id>\n"
     41     "        - Lookup an l2 Mcast Address entry\n"
     42     "  mcast test add|del Ports=<Max. number of ports in the system>\n"
     43     "        - add -> Adds 256 mc incremental addresses\n"
     44     "        - del -> Deletes 256 mc incremental addresses\n"
     45 #endif
     46     ;
     47 
     48 cmd_result_t
     49 bcmx_cmd_mcast(int unit, args_t *args)
     50 {
     51     char                *subcmd = NULL;
     52     static int          initted = 0;
     53     static sal_mac_addr_t arg_macaddr;
     54     static int          arg_cos_dst=0,
     55                         arg_vlan=VLAN_ID_DEFAULT;
     56     int                 rv = CMD_OK;
     57     int                 i;
     58     int                 arg_max_ports;
     59     int                 u_port_num;
     60     parse_table_t       pt;
     61     char                *plist_str;
     62     char                *puntag_list_str;
     63     bcmx_mcast_addr_t   mcxaddr;
     64     char                port_list[256];
     65     bcmx_lport_t        lport;
     66     int                 count;
     67 
     68     /*
     69      * Initialize MAC address field for the user to the first real
     70      * address which does not conflict
     71      */
     72     if (! initted) {
     73         arg_macaddr[0] = 0;
     74         arg_macaddr[1] = 0;
     75         arg_macaddr[2] = 0;
     76         arg_macaddr[3] = 0;
     77         arg_macaddr[4] = 0;
     78         arg_macaddr[5] = 0;
     79     }
     80 
     81     if ((subcmd = ARG_GET(args)) == NULL) {
     82         return CMD_USAGE;
     83     }
     84 
     85     if (! sal_strcasecmp(subcmd, "init")) {
     86 	rv = bcmx_mcast_init();
     87 
     88 	if (rv < 0) {
     89             cli_out("ERROR: %s\n", bcm_errmsg(rv));
     90             return CMD_FAIL;
     91 	}
     92         return CMD_OK;
     93     }
     94     else if (! sal_strcasecmp(subcmd, "add")) {
     95 
     96         parse_table_init(unit, &pt);
     97         parse_table_add(&pt, "Ports",      PQ_STRING,
     98                     0, &plist_str, NULL);
     99         parse_table_add(&pt, "UntagPorts",      PQ_STRING,
    100                     0, &puntag_list_str, NULL);
    101         parse_table_add(&pt, "MACaddress",      PQ_DFL|PQ_MAC,
    102                     0, &arg_macaddr,NULL);
    103         parse_table_add(&pt, "Vlanid",          PQ_DFL|PQ_HEX,
    104                     0, &arg_vlan,       NULL);
    105         parse_table_add(&pt, "CosDst",       PQ_DFL|PQ_INT,
    106                     0, &arg_cos_dst,        NULL);
    107 
    108         if (parse_arg_eq(args, &pt) < 0) {
    109             cli_out("%s ERROR: parsing arguments\n", ARG_CMD(args));
    110 	    parse_arg_eq_done(&pt);
    111             return CMD_FAIL;
    112         }
    113 
    114         bcmx_mcast_addr_t_init(&mcxaddr, arg_macaddr, arg_vlan);
    115 
    116         bcmx_lplist_clear(&mcxaddr.ports);
    117 
    118         if (bcmx_lplist_parse(&mcxaddr.ports, plist_str) < 0) {
    119             sal_printf("%s: Error: could not parse portlist: %s\n",
    120                          ARG_CMD(args), plist_str);
    121 	    parse_arg_eq_done(&pt);
    122 	    bcmx_mcast_addr_t_free(&mcxaddr);
    123             return CMD_FAIL;
    124         }
    125 
    126         bcmx_lplist_clear(&mcxaddr.untag_ports);
    127 
    128         if (bcmx_lplist_parse(&mcxaddr.untag_ports, puntag_list_str) < 0) {
    129             sal_printf("%s: Error: could not parse untag portlist: %s\n",
    130                          ARG_CMD(args), puntag_list_str);
    131 	    parse_arg_eq_done(&pt);
    132 	    bcmx_mcast_addr_t_free(&mcxaddr);
    133             return CMD_FAIL;
    134         }
    135 	parse_arg_eq_done(&pt);
    136 
    137 	rv = bcmx_mcast_addr_add(&mcxaddr);
    138 	bcmx_mcast_addr_t_free(&mcxaddr);
    139 
    140 	if (rv < 0) {
    141             cli_out("ERROR: %s\n", bcm_errmsg(rv));
    142             return CMD_FAIL;
    143 	}
    144         return CMD_OK;
    145     }
    146     else if (! sal_strcasecmp(subcmd, "padd")) {
    147 
    148         parse_table_init(unit, &pt);
    149         parse_table_add(&pt, "Ports",      PQ_STRING,
    150                     0, &plist_str, NULL);
    151         parse_table_add(&pt, "UntagPorts",      PQ_STRING,
    152                     0, &puntag_list_str, NULL);
    153         parse_table_add(&pt, "MACaddress",      PQ_DFL|PQ_MAC,
    154                     0, &arg_macaddr,NULL);
    155         parse_table_add(&pt, "Vlanid",          PQ_DFL|PQ_HEX,
    156                     0, &arg_vlan,       NULL);
    157         parse_table_add(&pt, "CosDst",       PQ_DFL|PQ_INT,
    158                     0, &arg_cos_dst,        NULL);
    159 
    160         if (parse_arg_eq(args, &pt) < 0) {
    161             cli_out("%s ERROR: parsing arguments\n", ARG_CMD(args));
    162 	    parse_arg_eq_done(&pt);
    163             return CMD_FAIL;
    164         }
    165 
    166 	bcmx_mcast_addr_t_init(&mcxaddr, arg_macaddr, arg_vlan);
    167 
    168         bcmx_lplist_clear(&mcxaddr.ports);
    169 
    170         if (bcmx_lplist_parse(&mcxaddr.ports, plist_str) < 0) {
    171             sal_printf("%s: Error: could not parse portlist: %s\n",
    172                          ARG_CMD(args), plist_str);
    173 	    parse_arg_eq_done(&pt);
    174 	    bcmx_mcast_addr_t_free(&mcxaddr);
    175             return CMD_FAIL;
    176         }
    177 
    178         bcmx_lplist_clear(&mcxaddr.untag_ports);
    179 
    180         if (bcmx_lplist_parse(&mcxaddr.untag_ports, puntag_list_str) < 0) {
    181             sal_printf("%s: Error: could not parse untag portlist: %s\n",
    182                          ARG_CMD(args), puntag_list_str);
    183 	    parse_arg_eq_done(&pt);
    184 	    bcmx_mcast_addr_t_free(&mcxaddr);
    185             return CMD_FAIL;
    186         }
    187 	parse_arg_eq_done(&pt);
    188 
    189 	rv = bcmx_mcast_port_add(&mcxaddr);
    190 	bcmx_mcast_addr_t_free(&mcxaddr);
    191 
    192 	if (rv < 0) {
    193             cli_out("ERROR: %s\n", bcm_errmsg(rv));
    194             return CMD_FAIL;
    195 	}
    196         return CMD_OK;
    197     }
    198 
    199     else if (! sal_strcasecmp(subcmd, "del")) {
    200 
    201         parse_table_init(unit, &pt);
    202         parse_table_add(&pt, "MACaddress",      PQ_DFL|PQ_MAC,
    203                     0, &arg_macaddr,NULL);
    204         parse_table_add(&pt, "Vlanid",          PQ_DFL|PQ_HEX,
    205                     0, &arg_vlan,       NULL);
    206 
    207         if (parse_arg_eq(args, &pt) < 0) {
    208             cli_out("%s ERROR: parsing arguments\n", ARG_CMD(args));
    209 	    parse_arg_eq_done(&pt);
    210             return CMD_FAIL;
    211         }
    212 	parse_arg_eq_done(&pt);
    213 
    214 	rv = bcmx_mcast_addr_remove(arg_macaddr, arg_vlan);
    215 
    216 	if (rv < 0) {
    217             cli_out("ERROR: %s\n", bcm_errmsg(rv));
    218             return CMD_FAIL;
    219 	}
    220 
    221         return CMD_OK;
    222     }
    223 
    224     else if (! sal_strcasecmp(subcmd, "pdel")) {
    225 
    226         parse_table_init(unit, &pt);
    227         parse_table_add(&pt, "Ports",      PQ_STRING,
    228                     0, &plist_str, NULL);
    229         parse_table_add(&pt, "MACaddress",      PQ_DFL|PQ_MAC,
    230                     0, &arg_macaddr,NULL);
    231         parse_table_add(&pt, "Vlanid",          PQ_DFL|PQ_HEX,
    232                     0, &arg_vlan,       NULL);
    233 
    234         if (parse_arg_eq(args, &pt) < 0) {
    235             cli_out("%s ERROR: parsing arguments\n", ARG_CMD(args));
    236 	    parse_arg_eq_done(&pt);
    237             return CMD_FAIL;
    238         }
    239 
    240 	bcmx_mcast_addr_t_init(&mcxaddr, arg_macaddr, arg_vlan);
    241 
    242         bcmx_lplist_clear(&mcxaddr.ports);
    243 
    244         if (bcmx_lplist_parse(&mcxaddr.ports, plist_str) < 0) {
    245             sal_printf("%s: Error: could not parse portlist: %s\n",
    246                          ARG_CMD(args), plist_str);
    247 	    parse_arg_eq_done(&pt);
    248 	    bcmx_mcast_addr_t_free(&mcxaddr);
    249             return CMD_FAIL;
    250         }
    251 	parse_arg_eq_done(&pt);
    252 
    253 	rv = bcmx_mcast_port_remove(&mcxaddr);
    254 	bcmx_mcast_addr_t_free(&mcxaddr);
    255 
    256 	if (rv < 0) {
    257             cli_out("ERROR: %s\n", bcm_errmsg(rv));
    258             return CMD_FAIL;
    259 	}
    260 
    261         return CMD_OK;
    262     }
    263 
    264     else if (! sal_strcasecmp(subcmd, "lookup") || ! sal_strcasecmp(subcmd, "lkup")) {
    265 
    266         /*
    267          * Lookup an arl entry
    268          */
    269         parse_table_init(unit, &pt);
    270         parse_table_add(&pt, "MACaddress",      PQ_DFL|PQ_MAC,
    271                     0, &arg_macaddr,NULL);
    272         parse_table_add(&pt, "Vlanid",          PQ_DFL|PQ_HEX,
    273                     0, &arg_vlan,       NULL);
    274 
    275         if (parse_arg_eq(args, &pt) < 0) {
    276             cli_out("%s ERROR: parsing arguments\n", ARG_CMD(args));
    277 	    parse_arg_eq_done(&pt);
    278             return CMD_FAIL;
    279         }
    280 	parse_arg_eq_done(&pt);
    281 
    282 	bcmx_mcast_addr_t_init(&mcxaddr, arg_macaddr, arg_vlan);
    283 
    284         rv = bcmx_mcast_port_get(arg_macaddr, arg_vlan, &mcxaddr);
    285 
    286         if (rv < 0) {
    287             cli_out("ERROR: %s\n", bcm_errmsg(rv));
    288 	    bcmx_mcast_addr_t_free(&mcxaddr);
    289             return CMD_FAIL;
    290         } else { /* Found it.  Display. */
    291 	    cli_out("mcast addr %02x.%02x.%02x.%02x.%02x.%02x vlan %d COS %d\n",
    292                     mcxaddr.mac[0], mcxaddr.mac[1], mcxaddr.mac[2],
    293                     mcxaddr.mac[3], mcxaddr.mac[4], mcxaddr.mac[5],
    294                     mcxaddr.vid, mcxaddr.cos_dst);
    295 	    cli_out("uports:");
    296 	    BCMX_LPLIST_ITER(mcxaddr.ports, lport, count) {
    297             cli_out(" %s", bcmx_lport_to_uport_str(lport));
    298 	    }
    299 	    cli_out("\n");
    300 	    cli_out("untag uports:");
    301 	    BCMX_LPLIST_ITER(mcxaddr.untag_ports, lport, count) {
    302             cli_out(" %s", bcmx_lport_to_uport_str(lport));
    303 	    }
    304 	    cli_out("\n");
    305 	    bcmx_mcast_addr_t_free(&mcxaddr);
    306             return CMD_OK;
    307         }
    308     }
    309 
    310     else if (! sal_strcasecmp(subcmd, "test")) {
    311 
    312 	if ((subcmd = ARG_GET(args)) == NULL) {
    313 	    return CMD_USAGE;
    314 	}
    315 	if (! sal_strcasecmp(subcmd, "add")) {
    316 
    317 	    parse_table_init(unit, &pt);
    318 	    parse_table_add(&pt, "Ports",      PQ_DFL|PQ_INT,
    319 			    0, &arg_max_ports,NULL);
    320 	    if (parse_arg_eq(args, &pt) < 0) {
    321 		cli_out("%s ERROR: parsing arguments\n", ARG_CMD(args));
    322 		parse_arg_eq_done(&pt);
    323 		return CMD_FAIL;
    324 	    }
    325 	    parse_arg_eq_done(&pt);
    326 
    327 	    arg_macaddr[1] = 1;
    328 
    329 	    for (i=0; i<256; i++) {
    330 
    331 		memset(port_list, 0, sizeof(port_list));
    332 		u_port_num = i % arg_max_ports;
    333 		sal_sprintf(port_list,"%d,%d,%d,%d",(u_port_num%arg_max_ports)+1,
    334 			((u_port_num+1)%arg_max_ports)+1,
    335 			((u_port_num+2)%arg_max_ports)+1,
    336 			((u_port_num+3)%arg_max_ports)+1);
    337 
    338 		arg_vlan = 2;
    339 
    340 		bcmx_mcast_addr_t_init(&mcxaddr, arg_macaddr, arg_vlan);
    341 
    342 		bcmx_lplist_clear(&mcxaddr.ports);
    343 		bcmx_lplist_clear(&mcxaddr.untag_ports);
    344 
    345 		if (bcmx_lplist_parse(&mcxaddr.ports, port_list) < 0) {
    346 		    sal_printf("%s: Error: could not parse portlist: %s\n",
    347 			       ARG_CMD(args), port_list);
    348 		    bcmx_mcast_addr_t_free(&mcxaddr);
    349 		    return CMD_FAIL;
    350 		}
    351 
    352 		rv = bcmx_mcast_addr_add(&mcxaddr);
    353 		bcmx_mcast_addr_t_free(&mcxaddr);
    354 
    355 		if (rv < 0) {
    356 		    cli_out("ERROR: %s\n", bcm_errmsg(rv));
    357 		    return CMD_FAIL;
    358 		}
    359 
    360 		increment_macaddr(arg_macaddr, 1);
    361 	    }
    362 
    363 	} else  if (! sal_strcasecmp(subcmd, "del")) {
    364 	    parse_table_init(unit, &pt);
    365 	    parse_table_add(&pt, "Ports",      PQ_DFL|PQ_INT,
    366 			    0, &arg_max_ports,NULL);
    367 	    if (parse_arg_eq(args, &pt) < 0) {
    368 		cli_out("%s ERROR: parsing arguments\n", ARG_CMD(args));
    369 		parse_arg_eq_done(&pt);
    370 		return CMD_FAIL;
    371 	    }
    372 	    parse_arg_eq_done(&pt);
    373 
    374 	    arg_macaddr[1] = 1;
    375 
    376 	    for (i=0; i<256; i++) {
    377 
    378 		arg_vlan = 2;
    379 
    380 		rv = bcmx_mcast_addr_remove(arg_macaddr, arg_vlan);
    381 
    382 		if (rv < 0) {
    383 		    cli_out("ERROR: %s for mac = %d\n", bcm_errmsg(rv),i);
    384 		    return CMD_FAIL;
    385 		}
    386 
    387 		increment_macaddr(arg_macaddr, 1);
    388 	    }
    389 	}
    390 	return CMD_OK;
    391     }
    392 
    393     return CMD_USAGE;
    394 }