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 }