2 ===================================================================
3 --- bridge_ctl.h (revision 22)
4 +++ bridge_ctl.h (revision 27)
6 __u8 macaddr[ETH_ALEN];
15 ===================================================================
16 --- bridge-stp (revision 22)
17 +++ bridge-stp (revision 27)
19 checkpid $pid_file || exit 1
20 for b in $MSTP_BRIDGES; do
21 if [ "$bridge" == "$b" ]; then
22 - exec /sbin/mstpctl notify-daemon-that-stp-is-on $bridge
23 + exec /sbin/mstpctl addbridge $bridge
28 - exec /sbin/mstpctl notify-daemon-that-stp-is-off $bridge
29 + exec /sbin/mstpctl delbridge $bridge
32 echo "Unknown action:" $2
33 Index: ctl_functions.h
34 ===================================================================
35 --- ctl_functions.h (revision 22)
36 +++ ctl_functions.h (revision 27)
38 #define set_fids2mstids_CALL (in->br_index, in->fids2mstids)
39 CTL_DECLARE(set_fids2mstids);
41 -/* stp_mode_notification */
42 -#define CMD_CODE_stp_mode_notification (122 | RESPONSE_FIRST_HANDLE_LATER)
43 -#define stp_mode_notification_ARGS (int br_index, bool on)
44 -struct stp_mode_notification_IN
49 -struct stp_mode_notification_OUT
52 -#define stp_mode_notification_COPY_IN ({ in->br_index = br_index; \
54 -#define stp_mode_notification_COPY_OUT ({ (void)0; })
55 -#define stp_mode_notification_CALL (in->br_index, in->on)
56 -CTL_DECLARE(stp_mode_notification);
58 +#define CMD_CODE_add_bridges (122 | RESPONSE_FIRST_HANDLE_LATER)
59 +#define add_bridges_ARGS (int *br_array, int* *ifaces_lists)
60 +CTL_DECLARE(add_bridges);
63 +#define CMD_CODE_del_bridges (123 | RESPONSE_FIRST_HANDLE_LATER)
64 +#define del_bridges_ARGS (int *br_array)
65 +CTL_DECLARE(del_bridges);
67 /* General case part in ctl command server switch */
68 #define SERVER_MESSAGE_CASE(name) \
69 case CMD_CODE_ ## name : do \
71 ===================================================================
72 --- bridge_track.c (revision 22)
73 +++ bridge_track.c (revision 27)
78 -static bool stp_enabled(bridge_t * br)
79 +static void set_br_up(bridge_t * br, bool up)
81 - char path[40 + IFNAMSIZ];
82 - sprintf(path, "/sys/class/net/%s/bridge/stp_state", br->sysdeps.name);
83 - FILE *f = fopen(path, "r");
85 - if(!f || (1 != fscanf(f, "%d", &enabled)))
86 - ERROR("Can't read from %s", path);
88 - INFO("STP on %s state %d", br->sysdeps.name, enabled);
89 + INFO("%s was %s", br->sysdeps.name, br->sysdeps.up ? "up" : "down");
90 + INFO("Set bridge %s %s", br->sysdeps.name, up ? "up" : "down");
92 - return enabled == 2; /* ie user mode STP */
95 -static void set_br_up(bridge_t * br, bool up, bool stp_up)
97 - INFO("%s was %s stp was %s", br->sysdeps.name,
98 - br->sysdeps.up ? "up" : "down", br->sysdeps.stp_up ? "up" : "down");
99 - INFO("Set bridge %s %s stp %s" , br->sysdeps.name,
100 - up ? "up" : "down", stp_up ? "up" : "down");
102 bool changed = false;
104 if(up != br->sysdeps.up)
109 - if(br->sysdeps.stp_up != stp_up)
111 - br->sysdeps.stp_up = stp_up;
115 if(check_mac_address(br->sysdeps.name, br->sysdeps.macaddr))
117 /* MAC address changed */
122 - MSTP_IN_set_bridge_enable(br, br->sysdeps.up && br->sysdeps.stp_up);
123 + MSTP_IN_set_bridge_enable(br, br->sysdeps.up);
126 static void set_if_up(port_t * ifc, bool up)
127 @@ -291,15 +269,10 @@
128 if((br_index >= 0) && (br_index != if_index))
130 if(!(br = find_br(br_index)))
131 - br = create_br(br_index);
134 - ERROR("Couldn't create data for bridge interface %d", br_index);
137 + return -2; /* bridge not in list */
138 int br_flags = get_flags(br->sysdeps.name);
140 - set_br_up(br, !!(br_flags & IFF_UP), stp_enabled(br));
141 + set_br_up(br, !!(br_flags & IFF_UP));
146 if(br_index == if_index)
148 if(!(br = find_br(br_index)))
150 - if(!(br = create_br(br_index)))
152 - ERROR("Couldn't create data for bridge interface %d",
157 - set_br_up(br, up, stp_enabled(br));
158 + return -2; /* bridge not in list */
165 TST(br == ifc->bridge,);
166 TST(ifc->sysdeps.up,);
167 - if(!br->sysdeps.stp_up)
170 /* Validate Ethernet and LLC header,
171 * maybe we can skip this check thanks to Berkeley filter in packet socket?
172 @@ -840,12 +804,85 @@
173 return MSTP_IN_set_all_fids2mstids(br, fids2mstids) ? 0 : -1;
176 -int CTL_stp_mode_notification(int br_index, bool on)
177 +int CTL_add_bridges(int *br_array, int* *ifaces_lists)
181 - if(0 > (br_flags = get_flags(br->sysdeps.name)))
183 - set_br_up(br, !!(br_flags & IFF_UP), on);
184 + int i, j, ifcount, brcount = br_array[0];
185 + bridge_t *br, *other_br;
187 + int br_flags, if_flags;
191 + for(i = 1; i <= brcount; ++i)
193 + if(NULL == (br = find_br(br_array[i])))
195 + if(NULL == (br = create_br(br_array[i])))
197 + ERROR("Couldn't create data for bridge interface %d",
201 + if(0 <= (br_flags = get_flags(br->sysdeps.name)))
202 + set_br_up(br, !!(br_flags & IFF_UP));
204 + if_array = ifaces_lists[i - 1];
205 + ifcount = if_array[0];
206 + /* delete all interfaces which are not in list */
207 + list_for_each_entry_safe(ifc, nxt, &br->ports, br_list)
210 + for(j = 1; j <= ifcount; ++j)
212 + if(ifc->sysdeps.if_index == if_array[j])
221 + /* add all new interfaces from the list */
222 + for(j = 1; j <= ifcount; ++j)
224 + if(NULL != find_if(br, if_array[j]))
226 + /* Check if this interface is slave of another bridge */
227 + list_for_each_entry(other_br, &bridges, list)
230 + if(delete_if_byindex(other_br, if_array[j]))
232 + INFO("Device %d has come to bridge %s. "
233 + "Missed notify for deletion from bridge %s",
234 + if_array[j], br->sysdeps.name,
235 + other_br->sysdeps.name);
239 + if(NULL == (ifc = create_if(br, if_array[j])))
241 + INFO("Couldn't create data for interface %d (master %s)",
242 + if_array[j], br->sysdeps.name);
245 + if(0 <= (if_flags = get_flags(ifc->sysdeps.name)))
246 + set_if_up(ifc, (IFF_UP | IFF_RUNNING) ==
247 + (if_flags & (IFF_UP | IFF_RUNNING))
255 +int CTL_del_bridges(int *br_array)
257 + int i, brcount = br_array[0];
259 + for(i = 1; i <= brcount; ++i)
260 + delete_br_byindex(br_array[i]);
264 Index: ctl_socket_server.c
265 ===================================================================
266 --- ctl_socket_server.c (revision 22)
267 +++ ctl_socket_server.c (revision 27)
269 SERVER_MESSAGE_CASE(set_fid2mstid);
270 SERVER_MESSAGE_CASE(set_vids2fids);
271 SERVER_MESSAGE_CASE(set_fids2mstids);
272 - SERVER_MESSAGE_CASE(stp_mode_notification);
274 + case CMD_CODE_add_bridges:
278 + LOG("Bad sizes: lout %d != 0", lout);
281 + if(sizeof(int) > lin)
283 + LOG("Bad sizes: lin == 0");
286 + int *br_array = inbuf;
287 + int i, serialized_data_count, chunk_count, brcount = br_array[0];
288 + int *ptr = br_array + (serialized_data_count = (brcount + 1));
289 + if(lin < ((serialized_data_count + 1) * sizeof(int)))
291 +bad_lin1: LOG("Bad sizes: lin %d < %d", lin,
292 + (serialized_data_count + 1) * sizeof(int));
295 + for(i = 0; i < brcount; ++i)
297 + serialized_data_count += (chunk_count = *ptr + 1);
298 + if(i < (brcount - 1))
300 + if(lin < ((serialized_data_count + 1) * sizeof(int)))
302 + ptr += chunk_count;
306 + if(lin != (serialized_data_count * sizeof(int)))
308 + LOG("Bad sizes: lin %d != %d", lin,
309 + serialized_data_count * sizeof(int));
314 + int* *ifaces_lists = malloc(brcount * sizeof(int*));
315 + if(NULL == ifaces_lists)
317 + LOG("out of memory, brcount = %d\n", brcount);
320 + ptr = br_array + (brcount + 1);
321 + for(i = 0; i < brcount; ++i)
323 + ifaces_lists[i] = ptr;
324 + ptr += ifaces_lists[i][0] + 1;
326 + int r = CTL_add_bridges(br_array, ifaces_lists);
327 + free(ifaces_lists);
333 + case CMD_CODE_del_bridges:
337 + LOG("Bad sizes: lout %d != 0", lout);
340 + if(sizeof(int) > lin)
342 + LOG("Bad sizes: lin == 0");
345 + int *br_array = inbuf;
346 + int brcount = br_array[0];
347 + if(((brcount + 1) * sizeof(int)) != lin)
349 + LOG("Bad sizes: lin %d != %d", lin,
350 + (brcount + 1) * sizeof(int));
353 + int r = CTL_del_bridges(br_array);
360 ERROR("CTL: Unknown command %d", cmd);
363 ===================================================================
364 --- mstp.c (revision 22)
365 +++ mstp.c (revision 27)
368 list_add_tail(&cist->bridge_list, &br->trees);
370 - br_state_machines_begin(br);
375 ===================================================================
376 --- ctl_main.c (revision 22)
377 +++ ctl_main.c (revision 27)
379 return !('.' == n[0] && (0 == n[1] || ('.' == n[1] && 0 == n[2])));
382 +static int get_port_list(const char *br_ifname, struct dirent ***namelist)
385 + char buf[SYSFS_PATH_MAX];
387 + snprintf(buf, sizeof(buf), SYSFS_CLASS_NET "/%s/brif", br_ifname);
388 + if(0 > (res = scandir(buf, namelist, not_dot_dotdot, sorting_func)))
389 + fprintf(stderr, "Error getting list of all ports of bridge %s\n",
394 static int cmd_showport(int argc, char *const *argv)
401 - char buf[SYSFS_PATH_MAX];
402 - snprintf(buf, sizeof(buf), SYSFS_CLASS_NET "/%s/brif", argv[1]);
403 - count = scandir(buf, &namelist, not_dot_dotdot, sorting_func);
406 - fprintf(stderr, "Error getting list of all ports of bridge %s\n",
410 + if(0 > (count = get_port_list(argv[1], &namelist)))
414 for(i = 0; i < count; ++i)
419 +static int cmd_addbridge(int argc, char *const *argv)
421 + int i, j, res, ifcount, brcount = argc - 1;
423 + int* *ifaces_lists;
425 + if(NULL == (br_array = malloc((brcount + 1) * sizeof(int))))
428 + fprintf(stderr, "out of memory, brcount = %d\n", brcount);
431 + if(NULL == (ifaces_lists = malloc(brcount * sizeof(int*))))
434 + goto out_of_memory_exit;
437 + br_array[0] = brcount;
438 + for(i = 1; i <= brcount; ++i)
440 + struct dirent **namelist;
442 + br_array[i] = get_index(argv[i], "bridge");
444 + if(0 > (ifcount = get_port_list(argv[i], &namelist)))
447 + for(i -= 2; i >= 0; --i)
448 + free(ifaces_lists[i]);
449 + free(ifaces_lists);
454 + if(NULL == (ifaces_lists[i - 1] = malloc((ifcount + 1) * sizeof(int))))
456 + fprintf(stderr, "out of memory, bridge %s, ifcount = %d\n",
458 + for(j = 0; j < ifcount; ++j)
462 + goto ifaces_error_exit;
465 + ifaces_lists[i - 1][0] = ifcount;
466 + for(j = 1; j <= ifcount; ++j)
468 + ifaces_lists[i - 1][j] = get_index(namelist[j - 1]->d_name, "port");
469 + free(namelist[j - 1]);
474 + res = CTL_add_bridges(br_array, ifaces_lists);
476 + for(i = 0; i < brcount; ++i)
477 + free(ifaces_lists[i]);
478 + free(ifaces_lists);
483 +static int cmd_delbridge(int argc, char *const *argv)
485 + int i, res, brcount = argc - 1;
488 + if(NULL == (br_array = malloc((brcount + 1) * sizeof(int))))
490 + fprintf(stderr, "out of memory, brcount = %d\n", brcount);
494 + br_array[0] = brcount;
495 + for(i = 1; i <= brcount; ++i)
496 + br_array[i] = get_index(argv[i], "bridge");
498 + res = CTL_del_bridges(br_array);
504 static unsigned int getuint(const char *s)
507 @@ -1191,23 +1281,6 @@
508 return CTL_set_fid2mstid(br_index, fid, mstid);
511 -static int cmd_stp_mode_notification(int argc, char *const *argv, bool on)
514 - /* Because this command has special handling,
515 - * argc was not checked earlier
520 - "Incorrect number of arguments for notification command\n");
523 - if(0 > (br_index = get_index(argv[1], "bridge")))
525 - return CTL_stp_mode_notification(br_index, on);
531 @@ -1220,6 +1293,12 @@
533 static const struct command commands[] =
535 + /* Add/delete bridges */
536 + {1, 32, "addbridge", cmd_addbridge,
537 + "<bridge> [<bridge> ...]", "Add bridges to the mstpd's list"},
538 + {1, 32, "delbridge", cmd_delbridge,
539 + "<bridge> [<bridge> ...]", "Remove bridges from the mstpd's list"},
541 /* Show global bridge */
542 {0, 32, "showbridge", cmd_showbridge,
543 "[<bridge> ... [param]]", "Show bridge state for the CIST"},
544 @@ -1370,12 +1449,6 @@
546 if(NULL == (cmd = command_lookup(argv[0])))
548 - /* Two special commands not intended for interactive use */
549 - if(!strcmp(argv[0], "notify-daemon-that-stp-is-on"))
550 - return cmd_stp_mode_notification(argc, argv, true);
551 - if(!strcmp(argv[0], "notify-daemon-that-stp-is-off"))
552 - return cmd_stp_mode_notification(argc, argv, false);
554 fprintf(stderr, "never heard of command [%s]\n", argv[0]);
557 @@ -1417,8 +1490,61 @@
558 CLIENT_SIDE_FUNCTION(set_fid2mstid)
559 CLIENT_SIDE_FUNCTION(set_vids2fids)
560 CLIENT_SIDE_FUNCTION(set_fids2mstids)
561 -CLIENT_SIDE_FUNCTION(stp_mode_notification)
563 +CTL_DECLARE(add_bridges)
566 + LogString log = { .buf = "" };
567 + int i, chunk_count, brcount, serialized_data_count;
568 + int *serialized_data, *ptr;
570 + chunk_count = serialized_data_count = (brcount = br_array[0]) + 1;
571 + for(i = 0; i < brcount; ++i)
572 + serialized_data_count += ifaces_lists[i][0] + 1;
573 + if(NULL == (serialized_data = malloc(serialized_data_count * sizeof(int))))
575 + LOG("out of memory, serialized_data_count = %d",
576 + serialized_data_count);
579 + memcpy(serialized_data, br_array, chunk_count * sizeof(int));
580 + ptr = serialized_data + chunk_count;
581 + for(i = 0; i < brcount; ++i)
583 + chunk_count = ifaces_lists[i][0] + 1;
584 + memcpy(ptr, ifaces_lists[i], chunk_count * sizeof(int));
585 + ptr += chunk_count;
588 + int r = send_ctl_message(CMD_CODE_add_bridges, serialized_data,
589 + serialized_data_count * sizeof(int),
590 + NULL, 0, &log, &res);
591 + free(serialized_data);
593 + LOG("Got return code %d, %d\n%s", r, res, log.buf);
601 +CTL_DECLARE(del_bridges)
604 + LogString log = { .buf = "" };
605 + int r = send_ctl_message(CMD_CODE_del_bridges,
606 + br_array, (br_array[0] + 1) * sizeof(int),
607 + NULL, 0, &log, &res);
609 + LOG("Got return code %d, %d\n%s", r, res, log.buf);
617 /*********************** Logging *********************/
619 void Dprintf(int level, const char *fmt, ...)