stg.c (6458B)
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 * STG CLI commands 8 */ 9 10 #include <appl/diag/system.h> 11 #include <appl/diag/parse.h> 12 #include <appl/diag/diag.h> 13 #include <appl/diag/dport.h> 14 #include <shared/bsl.h> 15 #include <bcm/error.h> 16 #include <bcm/stg.h> 17 #include <bcm/debug.h> 18 19 20 STATIC int 21 do_show_stg_vlans(int unit, bcm_stg_t stg) 22 { 23 vlan_id_t *list; 24 int count, i, r; 25 int first = 1; 26 27 if ((r = bcm_stg_vlan_list(unit, stg, &list, &count)) < 0) { 28 cli_out("Error listing STG %d: %s\n", stg, bcm_errmsg(r)); 29 return r; 30 } 31 32 cli_out("STG %d: contains %d VLAN%s%s", 33 stg, count, (count == 1) ? "" : "s", (count == 0) ? "" : " ("); 34 35 for (i = 0; i < count; i++) { 36 int span; 37 38 cli_out("%s%d", first ? "" : ",", list[i]); 39 first = 0; 40 41 for (span = 1; i < count - 1 && list[i + 1] == list[i] + 1; span++) { 42 i++; 43 } 44 45 if (span > 1) { 46 cli_out("-%d", list[i]); 47 } 48 } 49 50 cli_out("%s\n", (count == 0) ? "" : ")"); 51 52 bcm_stg_vlan_list_destroy(unit, list, count); 53 54 return BCM_E_NONE; 55 } 56 57 STATIC int 58 do_show_stg_stp(int unit, bcm_stg_t stg) 59 { 60 bcm_pbmp_t pbmps[BCM_STG_STP_COUNT]; 61 char buf[FORMAT_PBMP_MAX]; 62 int state, r; 63 soc_port_t port, dport; 64 bcm_port_config_t *pcfg = NULL; 65 66 sal_memset(pbmps, 0, sizeof (pbmps)); 67 pcfg = sal_alloc(sizeof(bcm_port_config_t), "bcm port config"); 68 if (NULL == pcfg) { 69 cli_out("ERROR: %s\n", bcm_errmsg(BCM_E_MEMORY)); 70 return CMD_FAIL; 71 } 72 BCM_IF_ERROR_RETURN(bcm_port_config_get(unit, pcfg)); 73 74 /* coverity[overrun-local] */ 75 DPORT_BCM_PBMP_ITER(unit, pcfg->port, dport, port) { 76 if ((r = bcm_stg_stp_get(unit, stg, port, &state)) < 0) { 77 sal_free(pcfg); 78 return r; 79 } 80 81 /* coverity[overrun-local] */ 82 BCM_PBMP_PORT_ADD(pbmps[state], port); 83 } 84 85 /* In current chips, LISTEN is not distinguished from BLOCK. */ 86 87 for (state = 0; state < BCM_STG_STP_COUNT; state++) { 88 if (!(BCM_PBMP_IS_NULL(pbmps[state]))) { 89 format_bcm_pbmp(unit, buf, sizeof (buf), pbmps[state]); 90 cli_out(" %7s: %s\n", FORWARD_MODE(state), buf); 91 } 92 } 93 94 sal_free(pcfg); 95 return BCM_E_NONE; 96 } 97 98 cmd_result_t 99 if_esw_stg(int unit, args_t *a) 100 { 101 char *subcmd, *c; 102 int r; 103 bcm_stg_t stg = BCM_STG_INVALID; 104 vlan_id_t vid; 105 int state; 106 pbmp_t pbmp; 107 bcm_port_config_t pcfg; 108 soc_port_t port, dport; 109 110 if (! sh_check_attached(ARG_CMD(a), unit)) { 111 return CMD_FAIL; 112 } 113 114 if ((subcmd = ARG_GET(a)) == NULL) { 115 return CMD_USAGE; 116 } 117 118 if (sal_strcasecmp(subcmd, "create") == 0) { 119 120 if ((c = ARG_GET(a)) != NULL) { 121 stg = parse_integer(c); 122 } 123 124 if (stg == BCM_STG_INVALID) { 125 r = bcm_stg_create(unit, &stg); 126 cli_out("Created spanning tree group %d\n", stg); 127 } else { 128 r = bcm_stg_create_id(unit, stg); 129 } 130 131 if (r < 0) { 132 goto bcm_err; 133 } 134 135 return CMD_OK; 136 } 137 138 if (sal_strcasecmp(subcmd, "destroy") == 0) { 139 140 if ((c = ARG_GET(a)) == NULL) { 141 return CMD_USAGE; 142 } 143 144 stg = parse_integer(c); 145 146 if ((r = bcm_stg_destroy(unit, stg)) < 0) { 147 goto bcm_err; 148 } 149 150 return CMD_OK; 151 } 152 153 if (sal_strcasecmp(subcmd, "show") == 0) { 154 155 bcm_stg_t *list; 156 int count, i; 157 158 if ((c = ARG_GET(a)) != NULL) { 159 stg = parse_integer(c); 160 } 161 162 if (stg != BCM_STG_INVALID) { 163 return do_show_stg_vlans(unit, stg); 164 } 165 166 if ((r = bcm_stg_list(unit, &list, &count)) < 0) { 167 goto bcm_err; 168 } 169 170 /* Force print STG 0 */ 171 do_show_stg_vlans(unit, 0); 172 do_show_stg_stp(unit, 0); 173 174 for (i = 0; i < count; i++) { 175 if ((r = do_show_stg_vlans(unit, list[i])) < 0) { 176 bcm_stg_list_destroy(unit, list, count); 177 goto bcm_err; 178 } 179 180 if ((r = do_show_stg_stp(unit, list[i])) < 0) { 181 bcm_stg_list_destroy(unit, list, count); 182 goto bcm_err; 183 } 184 } 185 186 bcm_stg_list_destroy(unit, list, count); 187 188 return CMD_OK; 189 } 190 191 if (sal_strcasecmp(subcmd, "add") == 0) { 192 193 if ((c = ARG_GET(a)) == NULL) { 194 return CMD_USAGE; 195 } 196 197 stg = parse_integer(c); 198 199 while ((c = ARG_GET(a)) != NULL) { 200 vid = parse_integer(c); 201 202 if ((r = bcm_stg_vlan_add(unit, stg, vid)) < 0) { 203 goto bcm_err; 204 } 205 } 206 207 return CMD_OK; 208 } 209 210 if (sal_strcasecmp(subcmd, "remove") == 0) { 211 212 if ((c = ARG_GET(a)) == NULL) { 213 return CMD_USAGE; 214 } 215 216 stg = parse_integer(c); 217 218 while ((c = ARG_GET(a)) != NULL) { 219 vid = parse_integer(c); 220 221 if ((r = bcm_stg_vlan_remove(unit, stg, vid)) < 0) { 222 goto bcm_err; 223 } 224 } 225 226 return CMD_OK; 227 } 228 229 if (sal_strcasecmp(subcmd, "stp") == 0) { 230 if ((c = ARG_GET(a)) == NULL) { 231 bcm_stg_t *list; 232 int count, i; 233 234 if ((r = bcm_stg_list(unit, &list, &count)) < 0) { 235 goto bcm_err; 236 } 237 238 for (i = 0; i < count; i++) { 239 cli_out("STG %d:\n", list[i]); 240 241 if ((r = do_show_stg_stp(unit, list[i])) < 0) { 242 bcm_stg_list_destroy(unit, list, count); 243 goto bcm_err; 244 } 245 } 246 247 bcm_stg_list_destroy(unit, list, count); 248 249 return CMD_OK; 250 } 251 252 stg = parse_integer(c); 253 254 if ((c = ARG_GET(a)) == NULL) { 255 cli_out("STG %d:\n", stg); 256 257 if ((r = do_show_stg_stp(unit, stg)) < 0) { 258 goto bcm_err; 259 } 260 261 return CMD_OK; 262 } 263 264 if (parse_bcm_pbmp(unit, c, &pbmp) < 0) { 265 return CMD_USAGE; 266 } 267 268 if ((c = ARG_GET(a)) == NULL) { 269 return CMD_USAGE; 270 } 271 272 for (state = 0; state < BCM_STG_STP_COUNT; state++) { 273 if (parse_cmp(forward_mode[state], c, '\0')) { 274 break; 275 } 276 } 277 278 if (state == BCM_STG_STP_COUNT) { 279 return CMD_USAGE; 280 } 281 282 BCM_IF_ERROR_RETURN(bcm_port_config_get(unit, &pcfg)); 283 284 BCM_PBMP_AND(pbmp, pcfg.port); 285 286 /* coverity[overrun-local] */ 287 DPORT_BCM_PBMP_ITER(unit, pbmp, dport, port) { 288 if ((r = bcm_stg_stp_set(unit, stg, port, state)) < 0) { 289 goto bcm_err; 290 } 291 } 292 293 return CMD_OK; 294 } 295 296 if (sal_strcasecmp(subcmd, "default") == 0) { 297 298 if ((c = ARG_GET(a)) != NULL) { 299 stg = parse_integer(c); 300 } 301 302 if (stg == BCM_STG_INVALID) { 303 if ((r = bcm_stg_default_get(unit, &stg)) < 0) { 304 goto bcm_err; 305 } 306 307 cli_out("Default STG is %d\n", stg); 308 } else { 309 if ((r = bcm_stg_default_set(unit, stg)) < 0) { 310 goto bcm_err; 311 } 312 313 cli_out("Default STG set to %d\n", stg); 314 } 315 316 return CMD_OK; 317 } 318 319 return CMD_USAGE; 320 321 bcm_err: 322 cli_out("%s: ERROR: %s\n", ARG_CMD(a), bcm_errmsg(r)); 323 return CMD_FAIL; 324 }