]>
Commit | Line | Data |
---|---|---|
ad02a0eb SH |
1 | /************************************************************************ |
2 | * RSTP library - Rapid Spanning Tree (802.1t, 802.1w) | |
3 | * Copyright (C) 2001-2003 Optical Access | |
4 | * Author: Alex Rozin | |
5 | * | |
6 | * This file is part of RSTP library. | |
7 | * | |
8 | * RSTP library is free software; you can redistribute it and/or modify it | |
9 | * under the terms of the GNU Lesser General Public License as published by the | |
10 | * Free Software Foundation; version 2.1 | |
11 | * | |
12 | * RSTP library is distributed in the hope that it will be useful, but | |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser | |
15 | * General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU Lesser General Public License | |
18 | * along with RSTP library; see the file COPYING. If not, write to the Free | |
19 | * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | |
20 | * 02111-1307, USA. | |
21 | **********************************************************************/ | |
22 | ||
23 | #include <stdlib.h> | |
24 | #include <stdio.h> | |
25 | #include <string.h> | |
26 | #include <ctype.h> | |
27 | #include <sys/types.h> | |
28 | #include <netinet/in.h> | |
29 | #include <arpa/inet.h> | |
30 | #include <unistd.h> | |
31 | ||
32 | #include "cli.h" | |
33 | #include "stp_cli.h" | |
34 | #include "bitmap.h" | |
35 | #include "uid_stp.h" | |
36 | #include "stp_in.h" | |
37 | #include "stp_to.h" | |
38 | ||
39 | int I_am_a_stupid_hub = 0; | |
40 | ||
41 | static void | |
42 | print_bridge_id (UID_BRIDGE_ID_T *bridge_id, unsigned char cr) | |
43 | { | |
44 | printf("%04lX-%02x%02x%02x%02x%02x%02x", | |
45 | (unsigned long) bridge_id->prio, | |
46 | (unsigned char) bridge_id->addr[0], | |
47 | (unsigned char) bridge_id->addr[1], | |
48 | (unsigned char) bridge_id->addr[2], | |
49 | (unsigned char) bridge_id->addr[3], | |
50 | (unsigned char) bridge_id->addr[4], | |
51 | (unsigned char) bridge_id->addr[5]); | |
52 | if (cr) | |
53 | printf("\n"); | |
54 | } | |
55 | ||
56 | static char * | |
57 | stp_state2str (RSTP_PORT_STATE stp_port_state, int detail) | |
58 | { | |
59 | if (detail) { | |
60 | switch (stp_port_state) { | |
61 | case UID_PORT_DISABLED: return "Disabled"; | |
62 | case UID_PORT_DISCARDING: return "Discarding"; | |
63 | case UID_PORT_LEARNING: return "Learning"; | |
64 | case UID_PORT_FORWARDING: return "Forwarding"; | |
65 | case UID_PORT_NON_STP: return "NoStp"; | |
66 | default: return "Unknown"; | |
67 | } | |
68 | } | |
69 | ||
70 | switch (stp_port_state) { | |
71 | case UID_PORT_DISABLED: return "Dis"; | |
72 | case UID_PORT_DISCARDING: return "Blk"; | |
73 | case UID_PORT_LEARNING: return "Lrn"; | |
74 | case UID_PORT_FORWARDING: return "Fwd"; | |
75 | case UID_PORT_NON_STP: return "Non"; | |
76 | default: return "Unk"; | |
77 | } | |
78 | } | |
79 | ||
80 | static void CLI_out_port_id (int port, unsigned char cr) | |
81 | { | |
82 | printf ("%s", STP_OUT_get_port_name (port)); | |
83 | if (cr) | |
84 | printf("\n"); | |
85 | } | |
86 | ||
87 | static int cli_enable (int argc, char** argv) | |
88 | { | |
89 | UID_STP_CFG_T uid_cfg; | |
90 | int rc; | |
91 | ||
92 | uid_cfg.field_mask = BR_CFG_STATE; | |
93 | uid_cfg.stp_enabled = STP_ENABLED; | |
94 | rc = STP_IN_stpm_set_cfg (0, NULL, &uid_cfg); | |
95 | if (rc) { | |
96 | printf ("can't enable: %s\n", STP_IN_get_error_explanation (rc)); | |
97 | } else | |
98 | I_am_a_stupid_hub = 0; | |
99 | ||
100 | return 0; | |
101 | } | |
102 | ||
103 | static int cli_disable (int argc, char** argv) | |
104 | { | |
105 | UID_STP_CFG_T uid_cfg; | |
106 | int rc; | |
107 | ||
108 | uid_cfg.field_mask = BR_CFG_STATE; | |
109 | uid_cfg.stp_enabled = STP_DISABLED; | |
110 | rc = STP_IN_stpm_set_cfg (0, NULL, &uid_cfg); | |
111 | if (rc) { | |
112 | printf ("can't disable: %s\n", STP_IN_get_error_explanation (rc)); | |
113 | } else | |
114 | I_am_a_stupid_hub = 1; | |
115 | ||
116 | return 0; | |
117 | } | |
118 | ||
119 | static int cli_br_get_cfg (int argc, char** argv) | |
120 | { | |
121 | UID_STP_STATE_T uid_state; | |
122 | UID_STP_CFG_T uid_cfg; | |
123 | int rc; | |
124 | ||
125 | rc = STP_IN_stpm_get_state (0, &uid_state); | |
126 | if (rc) { | |
127 | printf ("can't get rstp bridge state: %s\n", STP_IN_get_error_explanation (rc)); | |
128 | return 0; | |
129 | } | |
130 | rc = STP_IN_stpm_get_cfg (0, &uid_cfg); | |
131 | if (rc) { | |
132 | printf ("can't get rstp bridge configuration: %s\n", STP_IN_get_error_explanation (rc)); | |
133 | return 0; | |
134 | } | |
135 | ||
136 | ||
137 | #if 0 | |
138 | printf("Interface: %-7s (tag:%d) State: ", | |
139 | uid_state.vlan_name, (int) uid_state.vlan_id); | |
140 | #else | |
141 | printf("Bridge: %-7s State:", | |
142 | uid_state.vlan_name); | |
143 | #endif | |
144 | switch (uid_state.stp_enabled) { | |
145 | case STP_ENABLED: printf("enabled\n"); break; | |
146 | case STP_DISABLED: printf("disabled\n");break; | |
147 | default: printf("unknown\n"); return 0; | |
148 | } | |
149 | ||
150 | printf("BridgeId: "); print_bridge_id (&uid_state.bridge_id, 0); | |
151 | printf(" Bridge Proirity: %lu (0x%lX)\n", | |
152 | (unsigned long) uid_state.bridge_id.prio, (unsigned long) uid_state.bridge_id.prio); | |
153 | if (uid_cfg.force_version < 2) | |
154 | printf("Force Version: stp\n"); | |
155 | ||
156 | printf("Designated Root: "); print_bridge_id (&uid_state.designated_root, 1); | |
157 | if (uid_state.root_port) { | |
158 | printf("Root Port: %04lx (", (unsigned long) uid_state.root_port); | |
159 | CLI_out_port_id (uid_state.root_port & 0xfff, False); | |
160 | printf("), Root Cost: %-lu\n", (unsigned long) uid_state.root_path_cost); | |
161 | } else { | |
162 | printf("Root Port: none\n"); | |
163 | } | |
164 | ||
165 | if (uid_state.Topo_Change) | |
166 | printf ("Topology Change Count: %lu\n", uid_state.Topo_Change_Count); | |
167 | else | |
168 | printf ("Time Since Topology Change: %lu\n", uid_state.timeSince_Topo_Change); | |
169 | ||
170 | printf ("Max Age: %2d Bridge Max Age: %-2d\n", | |
171 | (int) uid_state.max_age, (int) uid_cfg.max_age); | |
172 | printf ("Hello Time: %2d Bridge Hello Time: %-2d\n", | |
173 | (int) uid_state.hello_time, (int) uid_cfg.hello_time); | |
174 | printf ("Forward Delay: %2d Bridge Forward Delay: %-2d\n", | |
175 | (int) uid_state.forward_delay, (int) uid_cfg.forward_delay); | |
176 | printf ("Hold Time: %2d\n", (int) uid_cfg.hold_time); | |
177 | ||
178 | return 0; | |
179 | } | |
180 | ||
181 | static void | |
182 | show_rstp_port (BITMAP_T* ports_bitmap, int detail) | |
183 | { | |
184 | UID_STP_STATE_T uid_state; | |
185 | UID_STP_PORT_STATE_T uid_port; | |
186 | UID_STP_PORT_CFG_T uid_cfg; | |
187 | int port_index; | |
188 | int rc; | |
189 | ||
190 | rc = STP_IN_stpm_get_state (0, &uid_state); | |
191 | if (rc) { | |
192 | printf ("can't get rstp bridge state: %s\n", STP_IN_get_error_explanation (rc)); | |
193 | } else if (! detail) { | |
194 | printf (" BridgeId: "); print_bridge_id (&uid_state.bridge_id, 0); | |
195 | printf (" RootId: "); print_bridge_id (&uid_state.designated_root, 1); | |
196 | } | |
197 | ||
198 | for (port_index = 0; port_index <= NUMBER_OF_PORTS; port_index++) { | |
199 | if (! BitmapGetBit(ports_bitmap, port_index - 1)) continue; | |
200 | uid_port.port_no = port_index; | |
201 | rc = STP_IN_port_get_state (0, &uid_port); | |
202 | if (rc) { | |
203 | printf ("can't get rstp port state: %s\n", STP_IN_get_error_explanation (rc)); | |
204 | continue; | |
205 | } | |
206 | memset (&uid_cfg, 0, sizeof (UID_STP_PORT_CFG_T)); | |
207 | rc = STP_IN_port_get_cfg (0, uid_port.port_no, &uid_cfg); | |
208 | if (rc) { | |
209 | printf ("can't get rstp port config: %s\n", STP_IN_get_error_explanation (rc)); | |
210 | continue; | |
211 | } | |
212 | ||
213 | if (detail) { | |
214 | printf("Stp Port "); CLI_out_port_id (port_index, False); | |
215 | #if 0 | |
216 | printf(": PortId: %04lx in vlan '%s' with tag %d:\n", | |
217 | (unsigned long) uid_port.port_id, uid_state.vlan_name, (int) uid_state.vlan_id); | |
218 | #else | |
219 | printf(": PortId: %04lx in Bridge '%s':\n", | |
220 | (unsigned long) uid_port.port_id, uid_state.vlan_name); | |
221 | #endif | |
222 | printf ("Priority: %-d\n", (int) (uid_port.port_id >> 8)); | |
223 | printf ("State: %-16s", stp_state2str (uid_port.state, 1)); | |
224 | printf (" Uptime: %-9lu\n", uid_port.uptime); | |
225 | printf ("PortPathCost: admin: "); | |
226 | if (ADMIN_PORT_PATH_COST_AUTO == uid_cfg.admin_port_path_cost) | |
227 | printf ("%-9s", "Auto"); | |
228 | else | |
229 | printf ("%-9lu", uid_cfg.admin_port_path_cost); | |
230 | printf (" oper: %-9lu\n", uid_port.oper_port_path_cost); | |
231 | ||
232 | printf ("Point2Point: admin: "); | |
233 | switch (uid_cfg.admin_point2point) { | |
234 | case P2P_FORCE_TRUE: | |
235 | printf ("%-9s", "ForceYes"); | |
236 | break; | |
237 | case P2P_FORCE_FALSE: | |
238 | printf ("%-9s", "ForceNo"); | |
239 | break; | |
240 | case P2P_AUTO: | |
241 | printf ("%-9s", "Auto"); | |
242 | break; | |
243 | } | |
244 | printf (" oper: %-9s\n", uid_port.oper_point2point ? "Yes" : "No"); | |
245 | printf ("Edge: admin: %-9s oper: %-9s\n", | |
246 | uid_cfg.admin_edge ? "Y" : "N", | |
247 | uid_port.oper_edge ? "Y" : "N"); | |
248 | printf ("Partner: oper: %-9s\n", | |
249 | uid_port.oper_stp_neigb ? "Slow" : "Rapid"); | |
250 | ||
251 | if (' ' != uid_port.role) { | |
252 | if ('-' != uid_port.role) { | |
253 | printf("PathCost: %-lu\n", (unsigned long) (uid_port.path_cost)); | |
254 | printf("Designated Root: "); print_bridge_id (&uid_port.designated_root, 1); | |
255 | printf("Designated Cost: %-ld\n", (unsigned long) uid_port.designated_cost); | |
256 | printf("Designated Bridge: "); print_bridge_id (&uid_port.designated_bridge, 1); | |
257 | printf("Designated Port: %-4lx\n\r", (unsigned long) uid_port.designated_port); | |
258 | } | |
259 | printf("Role: "); | |
260 | switch (uid_port.role) { | |
261 | case 'A': printf("Alternate\n"); break; | |
262 | case 'B': printf("Backup\n"); break; | |
263 | case 'R': printf("Root\n"); break; | |
264 | case 'D': printf("Designated\n"); break; | |
265 | case '-': printf("NonStp\n"); break; | |
266 | default: printf("Unknown(%c)\n", uid_port.role); break; | |
267 | } | |
268 | ||
269 | if ('R' == uid_port.role || 'D' == uid_port.role) { | |
270 | /* printf("Tc: %c ", uid_port.tc ? 'Y' : 'n'); */ | |
271 | printf("TcAck: %c ", | |
272 | uid_port.top_change_ack ? 'Y' : 'N'); | |
273 | printf("TcWhile: %3d\n", (int) uid_port.tcWhile); | |
274 | } | |
275 | } | |
276 | ||
277 | if (UID_PORT_DISABLED == uid_port.state || '-' == uid_port.role) { | |
278 | #if 0 | |
279 | printf("helloWhen: %3d ", (int) uid_port.helloWhen); | |
280 | printf("lnkWhile: %3d\n", (int) uid_port.lnkWhile); | |
281 | printf("fdWhile: %3d\n", (int) uid_port.fdWhile); | |
282 | #endif | |
283 | } else if ('-' != uid_port.role) { | |
284 | printf("fdWhile: %3d ", (int) uid_port.fdWhile); | |
285 | printf("rcvdInfoWhile: %3d\n", (int) uid_port.rcvdInfoWhile); | |
286 | printf("rbWhile: %3d ", (int) uid_port.rbWhile); | |
287 | printf("rrWhile: %3d\n", (int) uid_port.rrWhile); | |
288 | #if 0 | |
289 | printf("mdelayWhile: %3d ", (int) uid_port.mdelayWhile); | |
290 | printf("lnkWhile: %3d\n", (int) uid_port.lnkWhile); | |
291 | printf("helloWhen: %3d ", (int) uid_port.helloWhen); | |
292 | printf("txCount: %3d\n", (int) uid_port.txCount); | |
293 | #endif | |
294 | } | |
295 | ||
296 | printf("RSTP BPDU rx: %lu\n", (unsigned long) uid_port.rx_rstp_bpdu_cnt); | |
297 | printf("CONFIG BPDU rx: %lu\n", (unsigned long) uid_port.rx_cfg_bpdu_cnt); | |
298 | printf("TCN BPDU rx: %lu\n", (unsigned long) uid_port.rx_tcn_bpdu_cnt); | |
299 | } else { | |
300 | printf("%c%c%c ", | |
301 | (uid_port.oper_point2point) ? ' ' : '*', | |
302 | (uid_port.oper_edge) ? 'E' : ' ', | |
303 | (uid_port.oper_stp_neigb) ? 's' : ' '); | |
304 | CLI_out_port_id (port_index, False); | |
305 | printf(" %04lx %3s ", (unsigned long) uid_port.port_id, | |
306 | stp_state2str (uid_port.state, 0)); | |
307 | printf (" "); | |
308 | print_bridge_id (&uid_port.designated_root, 0); | |
309 | printf(" "); | |
310 | print_bridge_id (&uid_port.designated_bridge, 0); | |
311 | printf(" %4lx %c", (unsigned long) uid_port.designated_port, uid_port.role); | |
312 | printf ("\n"); | |
313 | } | |
314 | } | |
315 | } | |
316 | ||
317 | static int cli_pr_get_cfg (int argc, char** argv) | |
318 | { | |
319 | BITMAP_T ports_bitmap; | |
320 | int port_index; | |
321 | char detail; | |
322 | ||
323 | if ('a' == argv[1][0]) { | |
324 | BitmapSetAllBits(&ports_bitmap); | |
325 | detail = 0; | |
326 | } else { | |
327 | port_index = strtoul(argv[1], 0, 10); | |
328 | BitmapClear(&ports_bitmap); | |
329 | BitmapSetBit(&ports_bitmap, port_index - 1); | |
330 | detail = 1; | |
331 | } | |
332 | ||
333 | show_rstp_port (&ports_bitmap, detail); | |
334 | ||
335 | return 0; | |
336 | } | |
337 | ||
338 | static void | |
339 | set_bridge_cfg_value (unsigned long value, unsigned long val_mask) | |
340 | { | |
341 | UID_STP_CFG_T uid_cfg; | |
342 | char* val_name; | |
343 | int rc; | |
344 | ||
345 | uid_cfg.field_mask = val_mask; | |
346 | switch (val_mask) { | |
347 | case BR_CFG_STATE: | |
348 | uid_cfg.stp_enabled = value; | |
349 | val_name = "state"; | |
350 | break; | |
351 | case BR_CFG_PRIO: | |
352 | uid_cfg.bridge_priority = value; | |
353 | val_name = "priority"; | |
354 | break; | |
355 | case BR_CFG_AGE: | |
356 | uid_cfg.max_age = value; | |
357 | val_name = "max_age"; | |
358 | break; | |
359 | case BR_CFG_HELLO: | |
360 | uid_cfg.hello_time = value; | |
361 | val_name = "hello_time"; | |
362 | break; | |
363 | case BR_CFG_DELAY: | |
364 | uid_cfg.forward_delay = value; | |
365 | val_name = "forward_delay"; | |
366 | break; | |
367 | case BR_CFG_FORCE_VER: | |
368 | uid_cfg.force_version = value; | |
369 | val_name = "force_version"; | |
370 | break; | |
371 | case BR_CFG_AGE_MODE: | |
372 | case BR_CFG_AGE_TIME: | |
373 | default: printf ("Invalid value mask 0X%lx\n", val_mask); return; | |
374 | break; | |
375 | } | |
376 | ||
377 | rc = STP_IN_stpm_set_cfg (0, NULL, &uid_cfg); | |
378 | ||
379 | if (0 != rc) { | |
380 | printf ("Can't change rstp bridge %s:%s", val_name, STP_IN_get_error_explanation (rc)); | |
381 | } else { | |
382 | printf ("Changed rstp bridge %s\n", val_name); | |
383 | } | |
384 | } | |
385 | ||
386 | static int cli_br_prio (int argc, char** argv) | |
387 | { | |
388 | long br_prio = 32768L; | |
389 | ||
390 | if (strlen (argv[1]) > 2 && | |
391 | (! strncmp (argv[1], "0x", 2) || ! strncmp (argv[1], "0X", 2))) { | |
392 | br_prio = strtoul(argv[1] + 2, 0, 16); | |
393 | } else { | |
394 | br_prio = strtoul(argv[1], 0, 10); | |
395 | } | |
396 | ||
397 | if (! br_prio) { | |
398 | printf ("Warning: newPriority=0, are you sure ?\n"); | |
399 | } | |
400 | ||
401 | set_bridge_cfg_value (br_prio, BR_CFG_PRIO); | |
402 | ||
403 | return 0; | |
404 | } | |
405 | ||
406 | static int cli_br_maxage (int argc, char** argv) | |
407 | { | |
408 | long value = 20L; | |
409 | ||
410 | value = strtoul(argv[1], 0, 10); | |
411 | set_bridge_cfg_value (value, BR_CFG_AGE); | |
412 | return 0; | |
413 | } | |
414 | ||
415 | static int cli_br_fdelay (int argc, char** argv) | |
416 | { | |
417 | long value = 15L; | |
418 | ||
419 | value = strtoul(argv[1], 0, 10); | |
420 | set_bridge_cfg_value (value, BR_CFG_DELAY); | |
421 | return 0; | |
422 | } | |
423 | ||
424 | static int cli_br_fvers (int argc, char** argv) | |
425 | { | |
426 | long value = 2L; | |
427 | ||
428 | switch (argv[1][0]) { | |
429 | case '0': | |
430 | case '1': | |
431 | case 'f': | |
432 | case 'F': | |
433 | value = 0L; | |
434 | printf ("Accepted 'force_slow'\n"); | |
435 | break; | |
436 | case '2': | |
437 | case 'r': | |
438 | case 'R': | |
439 | printf ("Accepted 'rapid'\n"); | |
440 | value = 2L; | |
441 | break; | |
442 | default: | |
443 | printf ("Invalid argument '%s'\n", argv[1]); | |
444 | return 0; | |
445 | } | |
446 | ||
447 | set_bridge_cfg_value (value, BR_CFG_FORCE_VER); | |
448 | return 0; | |
449 | } | |
450 | ||
451 | static void | |
452 | set_rstp_port_cfg_value (int port_index, | |
453 | unsigned long value, | |
454 | unsigned long val_mask) | |
455 | { | |
456 | UID_STP_PORT_CFG_T uid_cfg; | |
457 | int rc, detail; | |
458 | char *val_name; | |
459 | ||
460 | if (port_index > 0) { | |
461 | BitmapClear(&uid_cfg.port_bmp); | |
462 | BitmapSetBit(&uid_cfg.port_bmp, port_index - 1); | |
463 | detail = 1; | |
464 | } else { | |
465 | BitmapSetAllBits(&uid_cfg.port_bmp); | |
466 | detail = 0; | |
467 | } | |
468 | ||
469 | uid_cfg.field_mask = val_mask; | |
470 | switch (val_mask) { | |
471 | case PT_CFG_MCHECK: | |
472 | val_name = "mcheck"; | |
473 | break; | |
474 | case PT_CFG_COST: | |
475 | uid_cfg.admin_port_path_cost = value; | |
476 | val_name = "path cost"; | |
477 | break; | |
478 | case PT_CFG_PRIO: | |
479 | uid_cfg.port_priority = value; | |
480 | val_name = "priority"; | |
481 | break; | |
482 | case PT_CFG_P2P: | |
483 | uid_cfg.admin_point2point = (ADMIN_P2P_T) value; | |
484 | val_name = "p2p flag"; | |
485 | break; | |
486 | case PT_CFG_EDGE: | |
487 | uid_cfg.admin_edge = value; | |
488 | val_name = "adminEdge"; | |
489 | break; | |
490 | case PT_CFG_NON_STP: | |
491 | uid_cfg.admin_non_stp = value; | |
492 | val_name = "adminNonStp"; | |
493 | break; | |
494 | #ifdef STP_DBG | |
495 | case PT_CFG_DBG_SKIP_TX: | |
496 | uid_cfg.skip_tx = value; | |
497 | val_name = "skip tx"; | |
498 | break; | |
499 | case PT_CFG_DBG_SKIP_RX: | |
500 | uid_cfg.skip_rx = value; | |
501 | val_name = "skip rx"; | |
502 | break; | |
503 | #endif | |
504 | case PT_CFG_STATE: | |
505 | default: | |
506 | printf ("Invalid value mask 0X%lx\n", val_mask); | |
507 | return; | |
508 | } | |
509 | ||
510 | rc = STP_IN_set_port_cfg (0, &uid_cfg); | |
511 | if (0 != rc) { | |
512 | printf ("can't change rstp port[s] %s: %s\n", | |
513 | val_name, STP_IN_get_error_explanation (rc)); | |
514 | } else { | |
515 | printf ("changed rstp port[s] %s\n", val_name); | |
516 | } | |
517 | ||
518 | /* show_rstp_port (&uid_cfg.port_bmp, 0); */ | |
519 | } | |
520 | ||
521 | static int cli_prt_prio (int argc, char** argv) | |
522 | { | |
523 | int port_index = 0; | |
524 | unsigned long value = 128; | |
525 | ||
526 | if ('a' != argv[1][0]) | |
527 | port_index = strtoul(argv[1], 0, 10); | |
528 | ||
529 | value = strtoul(argv[2], 0, 10); | |
530 | set_rstp_port_cfg_value (port_index, value, PT_CFG_PRIO); | |
531 | return 0; | |
532 | } | |
533 | ||
534 | static int cli_prt_pcost (int argc, char** argv) | |
535 | { | |
536 | int port_index = 0; | |
537 | unsigned long value = 0; | |
538 | ||
539 | if ('a' != argv[1][0]) | |
540 | port_index = strtoul(argv[1], 0, 10); | |
541 | ||
542 | value = strtoul(argv[2], 0, 10); | |
543 | set_rstp_port_cfg_value (port_index, value, PT_CFG_COST); | |
544 | return 0; | |
545 | } | |
546 | ||
547 | static int cli_prt_mcheck (int argc, char** argv) | |
548 | { | |
549 | int port_index = 0; | |
550 | ||
551 | if ('a' != argv[1][0]) | |
552 | port_index = strtoul(argv[1], 0, 10); | |
553 | set_rstp_port_cfg_value (port_index, 0, PT_CFG_MCHECK); | |
554 | return 0; | |
555 | } | |
556 | ||
557 | static int get_bool_arg (int narg, int argc, char** argv, | |
558 | unsigned long* value) | |
559 | { | |
560 | switch (argv[narg][0]) { | |
561 | case 'y': | |
562 | case 'Y': | |
563 | *value = 1; | |
564 | break; | |
565 | case 'n': | |
566 | case 'N': | |
567 | *value = 0; | |
568 | break; | |
569 | default: | |
570 | printf ("Invalid Bollean parameter '%s'\n", argv[narg]); | |
571 | return -1; | |
572 | } | |
573 | return 0; | |
574 | } | |
575 | ||
576 | static int cli_prt_edge (int argc, char** argv) | |
577 | { | |
578 | int port_index = 0; | |
579 | unsigned long value = 1; | |
580 | ||
581 | if ('a' != argv[1][0]) | |
582 | port_index = strtoul(argv[1], 0, 10); | |
583 | ||
584 | if (0 != get_bool_arg (2, argc, argv, &value)) | |
585 | return 0; | |
586 | ||
587 | set_rstp_port_cfg_value (port_index, value, PT_CFG_EDGE); | |
588 | return 0; | |
589 | } | |
590 | ||
591 | static int cli_prt_non_stp (int argc, char** argv) | |
592 | { | |
593 | int port_index = 0; | |
594 | unsigned long value = 0; | |
595 | ||
596 | if ('a' != argv[1][0]) | |
597 | port_index = strtoul(argv[1], 0, 10); | |
598 | ||
599 | if (0 != get_bool_arg (2, argc, argv, &value)) | |
600 | return 0; | |
601 | ||
602 | set_rstp_port_cfg_value (port_index, value, PT_CFG_NON_STP); | |
603 | return 0; | |
604 | } | |
605 | ||
606 | static int cli_prt_p2p (int argc, char** argv) | |
607 | { | |
608 | int port_index = 0; | |
609 | unsigned long value = P2P_FORCE_TRUE; | |
610 | ||
611 | if ('a' != argv[1][0]) | |
612 | port_index = strtoul(argv[1], 0, 10); | |
613 | ||
614 | switch (argv[2][0]) { | |
615 | case 'y': | |
616 | case 'Y': | |
617 | value = P2P_FORCE_TRUE; | |
618 | break; | |
619 | case 'n': | |
620 | case 'N': | |
621 | value = P2P_FORCE_FALSE; | |
622 | break; | |
623 | case 'a': | |
624 | case 'A': | |
625 | value = P2P_AUTO; | |
626 | break; | |
627 | default: | |
628 | printf ("Invalid parameter '%s'\n", argv[2]); | |
629 | return 0; | |
630 | } | |
631 | ||
632 | set_rstp_port_cfg_value (port_index, (ADMIN_P2P_T) value, PT_CFG_P2P); | |
633 | return 0; | |
634 | } | |
635 | ||
636 | #ifdef STP_DBG | |
637 | static int cli_trace (int argc, char** argv) | |
638 | { | |
639 | BITMAP_T ports_bitmap; | |
640 | int port_index; | |
641 | ||
642 | if ('a' == argv[1][0]) { | |
643 | BitmapSetAllBits(&ports_bitmap); | |
644 | } else { | |
645 | port_index = strtoul(argv[1], 0, 10); | |
646 | BitmapClear(&ports_bitmap); | |
647 | BitmapSetBit(&ports_bitmap, port_index - 1); | |
648 | } | |
649 | ||
650 | STP_IN_dbg_set_port_trace (argv[2], | |
651 | argv[3][0] != 'n' && argv[3][0] != 'N', | |
652 | 0, &ports_bitmap, | |
653 | 1); | |
654 | return 0; | |
655 | } | |
656 | ||
657 | /**** | |
658 | PARAM_NUMBER("port number", 1, NUMBER_OF_PORTS, "all") | |
659 | PARAM_ENUM("receive or/and transmit") | |
660 | PARAM_ENUM_SEL("rx", "receive") | |
661 | PARAM_ENUM_SEL("tx", "transmit") | |
662 | PARAM_ENUM_DEFAULT("all") | |
663 | PARAM_NUMBER("number of BPDU to skip", 0, 10000, "1") | |
664 | ****/ | |
665 | static int cli_skip (int argc, char** argv) | |
666 | { | |
667 | int port_index = 0, to_skip; | |
668 | ||
669 | if ('a' != argv[1][0]) | |
670 | port_index = strtoul(argv[1], 0, 10); | |
671 | ||
672 | to_skip = atoi (argv[3]); | |
673 | ||
674 | if ('a' == argv[2][0] || 'r' == argv[2][0]) { | |
675 | set_rstp_port_cfg_value (port_index, to_skip, PT_CFG_DBG_SKIP_RX); | |
676 | } | |
677 | ||
678 | if ('a' == argv[2][0] || 't' == argv[2][0]) { | |
679 | set_rstp_port_cfg_value (port_index, to_skip, PT_CFG_DBG_SKIP_TX); | |
680 | } | |
681 | return 0; | |
682 | } | |
683 | ||
684 | static int cli_sleep (int argc, char** argv) | |
685 | { | |
686 | int delay = atoi (argv[1]); | |
687 | sleep (delay); | |
688 | return 0; | |
689 | } | |
690 | ||
691 | #endif | |
692 | ||
693 | static CMD_DSCR_T lang[] = { | |
694 | THE_COMMAND("enable", "enable rstp") | |
695 | THE_FUNC(cli_enable) | |
696 | ||
697 | THE_COMMAND("disable", "disable rstp") | |
698 | THE_FUNC(cli_disable) | |
699 | ||
700 | THE_COMMAND("show bridge", "get bridge config") | |
701 | THE_FUNC(cli_br_get_cfg) | |
702 | ||
703 | THE_COMMAND("show port", "get port config") | |
704 | PARAM_NUMBER("port number on bridge", 1, NUMBER_OF_PORTS, "all") | |
705 | THE_FUNC(cli_pr_get_cfg) | |
706 | ||
707 | THE_COMMAND("bridge priority", "set bridge priority") | |
708 | PARAM_NUMBER("priority", MIN_BR_PRIO, MAX_BR_PRIO, "0x8000") | |
709 | THE_FUNC(cli_br_prio) | |
710 | ||
711 | THE_COMMAND("bridge maxage", "set bridge maxAge") | |
712 | PARAM_NUMBER("maxAge", MIN_BR_MAXAGE, MAX_BR_MAXAGE, "20") | |
713 | THE_FUNC(cli_br_maxage) | |
714 | ||
715 | THE_COMMAND("bridge fdelay", "set bridge forwardDelay") | |
716 | PARAM_NUMBER("forwardDelay", MIN_BR_FWDELAY, MAX_BR_FWDELAY, "15") | |
717 | THE_FUNC(cli_br_fdelay) | |
718 | ||
719 | THE_COMMAND("bridge forseVersion", "set bridge forseVersion") | |
720 | PARAM_BOOL("forseVersion", "forse slow", "regular", "no") | |
721 | THE_FUNC(cli_br_fvers) | |
722 | ||
723 | THE_COMMAND("port priority", "set port priority") | |
724 | PARAM_NUMBER("port number", 1, NUMBER_OF_PORTS, "all") | |
725 | PARAM_NUMBER("priority", MIN_PORT_PRIO, MAX_PORT_PRIO, "128") | |
726 | THE_FUNC(cli_prt_prio) | |
727 | ||
728 | THE_COMMAND("port pcost", "set port path cost") | |
729 | PARAM_NUMBER("port number", 1, NUMBER_OF_PORTS, "all") | |
730 | PARAM_NUMBER("path cost (0- for auto)", 0, 200000000, 0) | |
731 | THE_FUNC(cli_prt_pcost) | |
732 | ||
733 | THE_COMMAND("port mcheck", "set port mcheck") | |
734 | PARAM_NUMBER("port number", 1, NUMBER_OF_PORTS, "all") | |
735 | THE_FUNC(cli_prt_mcheck) | |
736 | ||
737 | THE_COMMAND("port edge", "set port adminEdge") | |
738 | PARAM_NUMBER("port number", 1, NUMBER_OF_PORTS, "all") | |
739 | PARAM_BOOL("adminEdge", "Edge", "noEdge", "Y") | |
740 | THE_FUNC(cli_prt_edge) | |
741 | ||
742 | THE_COMMAND("port nonStp", "set port adminNonStp") | |
743 | PARAM_NUMBER("port number", 1, NUMBER_OF_PORTS, "all") | |
744 | PARAM_BOOL("adminEdge", "Doesn't participate", "Paricipates", "n") | |
745 | THE_FUNC(cli_prt_non_stp) | |
746 | ||
747 | THE_COMMAND("port p2p", "set port adminPoit2Point") | |
748 | PARAM_NUMBER("port number", 1, NUMBER_OF_PORTS, "all") | |
749 | PARAM_ENUM("adminPoit2Point") | |
750 | PARAM_ENUM_SEL("y", "forcePointToPoint") | |
751 | PARAM_ENUM_SEL("n", "forcePointToMultiPoint") | |
752 | PARAM_ENUM_SEL("a", "autoPointToPoint") | |
753 | PARAM_ENUM_DEFAULT("a") | |
754 | THE_FUNC(cli_prt_p2p) | |
755 | ||
756 | #ifdef STP_DBG | |
757 | THE_COMMAND("trace", "set port trace") | |
758 | PARAM_NUMBER("port number", 1, NUMBER_OF_PORTS, "all") | |
759 | PARAM_ENUM("state machine name") | |
760 | PARAM_ENUM_SEL("info", "info") | |
761 | PARAM_ENUM_SEL("roletrns", "roletrns") | |
762 | PARAM_ENUM_SEL("sttrans", "sttrans") | |
763 | PARAM_ENUM_SEL("topoch", "topoch") | |
764 | PARAM_ENUM_SEL("migrate", "migrate") | |
765 | PARAM_ENUM_SEL("transmit", "transmit") | |
766 | PARAM_ENUM_SEL("p2p", "p2p") | |
767 | PARAM_ENUM_SEL("edge", "edge") | |
768 | PARAM_ENUM_SEL("pcost", "pcost") | |
769 | PARAM_ENUM_DEFAULT("all") | |
770 | PARAM_BOOL("enable/disable", "trace it", "don't trace it", "n") | |
771 | THE_FUNC(cli_trace) | |
772 | ||
773 | THE_COMMAND("skip", "skip BPDU processing") | |
774 | PARAM_NUMBER("port number", 1, NUMBER_OF_PORTS, "all") | |
775 | PARAM_ENUM("receive or/and transmit") | |
776 | PARAM_ENUM_SEL("rx", "receive") | |
777 | PARAM_ENUM_SEL("tx", "transmit") | |
778 | PARAM_ENUM_DEFAULT("all") | |
779 | PARAM_NUMBER("number of BPDU to skip", 0, 10000, "1") | |
780 | THE_FUNC(cli_skip) | |
781 | ||
782 | THE_COMMAND("sleep", "sleep") | |
783 | PARAM_NUMBER("delay in sec.", 1, 4000, "4") | |
784 | THE_FUNC(cli_sleep) | |
785 | #endif | |
786 | ||
787 | END_OF_LANG | |
788 | }; | |
789 | ||
790 | int stp_cli_init (void) | |
791 | { | |
792 | I_am_a_stupid_hub = 0; | |
793 | cli_register_language (lang); | |
794 | return 0; | |
795 | } | |
796 |