]> git.ipfire.org Git - people/amarx/ipfire-3.x.git/blob - mstpd/patches/add-del-bridge-commands.patch0
5f3e5926cc0dadc71f180da2a3bb7d229dc1d40f
[people/amarx/ipfire-3.x.git] / mstpd / patches / add-del-bridge-commands.patch0
1 Index: bridge_ctl.h
2 ===================================================================
3 --- bridge_ctl.h (revision 22)
4 +++ bridge_ctl.h (revision 27)
5 @@ -37,7 +37,7 @@
6 __u8 macaddr[ETH_ALEN];
7 char name[IFNAMSIZ];
8
9 - bool up, stp_up;
10 + bool up;
11 } sysdep_br_data_t;
12
13 typedef struct
14 Index: bridge-stp
15 ===================================================================
16 --- bridge-stp (revision 22)
17 +++ bridge-stp (revision 27)
18 @@ -44,12 +44,12 @@
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
24 fi
25 done
26 exit 1 ;;
27 stop)
28 - exec /sbin/mstpctl notify-daemon-that-stp-is-off $bridge
29 + exec /sbin/mstpctl delbridge $bridge
30 ;;
31 *)
32 echo "Unknown action:" $2
33 Index: ctl_functions.h
34 ===================================================================
35 --- ctl_functions.h (revision 22)
36 +++ ctl_functions.h (revision 27)
37 @@ -448,23 +448,16 @@
38 #define set_fids2mstids_CALL (in->br_index, in->fids2mstids)
39 CTL_DECLARE(set_fids2mstids);
40
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
45 -{
46 - int br_index;
47 - bool on;
48 -};
49 -struct stp_mode_notification_OUT
50 -{
51 -};
52 -#define stp_mode_notification_COPY_IN ({ in->br_index = br_index; \
53 - in->on = on; })
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);
57 +/* add bridges */
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);
61
62 +/* delete 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);
66 +
67 /* General case part in ctl command server switch */
68 #define SERVER_MESSAGE_CASE(name) \
69 case CMD_CODE_ ## name : do \
70 Index: bridge_track.c
71 ===================================================================
72 --- bridge_track.c (revision 22)
73 +++ bridge_track.c (revision 27)
74 @@ -175,27 +175,11 @@
75 }
76 }
77
78 -static bool stp_enabled(bridge_t * br)
79 +static void set_br_up(bridge_t * br, bool up)
80 {
81 - char path[40 + IFNAMSIZ];
82 - sprintf(path, "/sys/class/net/%s/bridge/stp_state", br->sysdeps.name);
83 - FILE *f = fopen(path, "r");
84 - int enabled = 0;
85 - if(!f || (1 != fscanf(f, "%d", &enabled)))
86 - ERROR("Can't read from %s", path);
87 - fclose(f);
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");
91
92 - return enabled == 2; /* ie user mode STP */
93 -}
94 -
95 -static void set_br_up(bridge_t * br, bool up, bool stp_up)
96 -{
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");
101 -
102 bool changed = false;
103
104 if(up != br->sysdeps.up)
105 @@ -204,12 +188,6 @@
106 changed = true;
107 }
108
109 - if(br->sysdeps.stp_up != stp_up)
110 - {
111 - br->sysdeps.stp_up = stp_up;
112 - changed = true;
113 - }
114 -
115 if(check_mac_address(br->sysdeps.name, br->sysdeps.macaddr))
116 {
117 /* MAC address changed */
118 @@ -218,7 +196,7 @@
119 }
120
121 if(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);
124 }
125
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))
129 {
130 if(!(br = find_br(br_index)))
131 - br = create_br(br_index);
132 - if(!br)
133 - {
134 - ERROR("Couldn't create data for bridge interface %d", br_index);
135 - return -1;
136 - }
137 + return -2; /* bridge not in list */
138 int br_flags = get_flags(br->sysdeps.name);
139 if(br_flags >= 0)
140 - set_br_up(br, !!(br_flags & IFF_UP), stp_enabled(br));
141 + set_br_up(br, !!(br_flags & IFF_UP));
142 }
143
144 if(br)
145 @@ -358,15 +331,8 @@
146 if(br_index == if_index)
147 {
148 if(!(br = find_br(br_index)))
149 - {
150 - if(!(br = create_br(br_index)))
151 - {
152 - ERROR("Couldn't create data for bridge interface %d",
153 - br_index);
154 - return -1;
155 - }
156 - }
157 - set_br_up(br, up, stp_enabled(br));
158 + return -2; /* bridge not in list */
159 + set_br_up(br, up);
160 }
161 }
162 }
163 @@ -412,8 +378,6 @@
164 /* sanity checks */
165 TST(br == ifc->bridge,);
166 TST(ifc->sysdeps.up,);
167 - if(!br->sysdeps.stp_up)
168 - return;
169
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;
174 }
175
176 -int CTL_stp_mode_notification(int br_index, bool on)
177 +int CTL_add_bridges(int *br_array, int* *ifaces_lists)
178 {
179 - int br_flags;
180 - CTL_CHECK_BRIDGE;
181 - if(0 > (br_flags = get_flags(br->sysdeps.name)))
182 - return br_flags;
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;
186 + port_t *ifc, *nxt;
187 + int br_flags, if_flags;
188 + int *if_array;
189 + bool found;
190 +
191 + for(i = 1; i <= brcount; ++i)
192 + {
193 + if(NULL == (br = find_br(br_array[i])))
194 + {
195 + if(NULL == (br = create_br(br_array[i])))
196 + {
197 + ERROR("Couldn't create data for bridge interface %d",
198 + br_array[i]);
199 + return -1;
200 + }
201 + if(0 <= (br_flags = get_flags(br->sysdeps.name)))
202 + set_br_up(br, !!(br_flags & IFF_UP));
203 + }
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)
208 + {
209 + found = false;
210 + for(j = 1; j <= ifcount; ++j)
211 + {
212 + if(ifc->sysdeps.if_index == if_array[j])
213 + {
214 + found = true;
215 + break;
216 + }
217 + }
218 + if(!found)
219 + delete_if(ifc);
220 + }
221 + /* add all new interfaces from the list */
222 + for(j = 1; j <= ifcount; ++j)
223 + {
224 + if(NULL != find_if(br, if_array[j]))
225 + continue;
226 + /* Check if this interface is slave of another bridge */
227 + list_for_each_entry(other_br, &bridges, list)
228 + {
229 + if(other_br != br)
230 + if(delete_if_byindex(other_br, if_array[j]))
231 + {
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);
236 + break;
237 + }
238 + }
239 + if(NULL == (ifc = create_if(br, if_array[j])))
240 + {
241 + INFO("Couldn't create data for interface %d (master %s)",
242 + if_array[j], br->sysdeps.name);
243 + continue;
244 + }
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))
248 + );
249 + }
250 + }
251 +
252 return 0;
253 }
254 +
255 +int CTL_del_bridges(int *br_array)
256 +{
257 + int i, brcount = br_array[0];
258 +
259 + for(i = 1; i <= brcount; ++i)
260 + delete_br_byindex(br_array[i]);
261 +
262 + return 0;
263 +}
264 Index: ctl_socket_server.c
265 ===================================================================
266 --- ctl_socket_server.c (revision 22)
267 +++ ctl_socket_server.c (revision 27)
268 @@ -82,8 +82,92 @@
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);
273
274 + case CMD_CODE_add_bridges:
275 + {
276 + if(0 != lout)
277 + {
278 + LOG("Bad sizes: lout %d != 0", lout);
279 + return -1;
280 + }
281 + if(sizeof(int) > lin)
282 + {
283 + LOG("Bad sizes: lin == 0");
284 + return -1;
285 + }
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)))
290 + {
291 +bad_lin1: LOG("Bad sizes: lin %d < %d", lin,
292 + (serialized_data_count + 1) * sizeof(int));
293 + return -1;
294 + }
295 + for(i = 0; i < brcount; ++i)
296 + {
297 + serialized_data_count += (chunk_count = *ptr + 1);
298 + if(i < (brcount - 1))
299 + {
300 + if(lin < ((serialized_data_count + 1) * sizeof(int)))
301 + goto bad_lin1;
302 + ptr += chunk_count;
303 + }
304 + else
305 + {
306 + if(lin != (serialized_data_count * sizeof(int)))
307 + {
308 + LOG("Bad sizes: lin %d != %d", lin,
309 + serialized_data_count * sizeof(int));
310 + return -1;
311 + }
312 + }
313 + }
314 + int* *ifaces_lists = malloc(brcount * sizeof(int*));
315 + if(NULL == ifaces_lists)
316 + {
317 + LOG("out of memory, brcount = %d\n", brcount);
318 + return -1;
319 + }
320 + ptr = br_array + (brcount + 1);
321 + for(i = 0; i < brcount; ++i)
322 + {
323 + ifaces_lists[i] = ptr;
324 + ptr += ifaces_lists[i][0] + 1;
325 + }
326 + int r = CTL_add_bridges(br_array, ifaces_lists);
327 + free(ifaces_lists);
328 + if(r)
329 + return r;
330 + return r;
331 + }
332 +
333 + case CMD_CODE_del_bridges:
334 + {
335 + if(0 != lout)
336 + {
337 + LOG("Bad sizes: lout %d != 0", lout);
338 + return -1;
339 + }
340 + if(sizeof(int) > lin)
341 + {
342 + LOG("Bad sizes: lin == 0");
343 + return -1;
344 + }
345 + int *br_array = inbuf;
346 + int brcount = br_array[0];
347 + if(((brcount + 1) * sizeof(int)) != lin)
348 + {
349 + LOG("Bad sizes: lin %d != %d", lin,
350 + (brcount + 1) * sizeof(int));
351 + return -1;
352 + }
353 + int r = CTL_del_bridges(br_array);
354 + if(r)
355 + return r;
356 + return r;
357 + }
358 +
359 default:
360 ERROR("CTL: Unknown command %d", cmd);
361 return -1;
362 Index: mstp.c
363 ===================================================================
364 --- mstp.c (revision 22)
365 +++ mstp.c (revision 27)
366 @@ -206,7 +206,6 @@
367 return false;
368 list_add_tail(&cist->bridge_list, &br->trees);
369
370 - br_state_machines_begin(br);
371 return true;
372 }
373
374 Index: ctl_main.c
375 ===================================================================
376 --- ctl_main.c (revision 22)
377 +++ ctl_main.c (revision 27)
378 @@ -636,6 +636,18 @@
379 return !('.' == n[0] && (0 == n[1] || ('.' == n[1] && 0 == n[2])));
380 }
381
382 +static int get_port_list(const char *br_ifname, struct dirent ***namelist)
383 +{
384 + int res;
385 + char buf[SYSFS_PATH_MAX];
386 +
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",
390 + br_ifname);
391 + return res;
392 +}
393 +
394 static int cmd_showport(int argc, char *const *argv)
395 {
396 int r = 0;
397 @@ -666,15 +678,8 @@
398 }
399 else
400 {
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);
404 - if(0 > count)
405 - {
406 - fprintf(stderr, "Error getting list of all ports of bridge %s\n",
407 - argv[1]);
408 - return -1;
409 - }
410 + if(0 > (count = get_port_list(argv[1], &namelist)))
411 + return count;
412 }
413
414 for(i = 0; i < count; ++i)
415 @@ -740,6 +745,91 @@
416 return 0;
417 }
418
419 +static int cmd_addbridge(int argc, char *const *argv)
420 +{
421 + int i, j, res, ifcount, brcount = argc - 1;
422 + int *br_array;
423 + int* *ifaces_lists;
424 +
425 + if(NULL == (br_array = malloc((brcount + 1) * sizeof(int))))
426 + {
427 +out_of_memory_exit:
428 + fprintf(stderr, "out of memory, brcount = %d\n", brcount);
429 + return -1;
430 + }
431 + if(NULL == (ifaces_lists = malloc(brcount * sizeof(int*))))
432 + {
433 + free(br_array);
434 + goto out_of_memory_exit;
435 + }
436 +
437 + br_array[0] = brcount;
438 + for(i = 1; i <= brcount; ++i)
439 + {
440 + struct dirent **namelist;
441 +
442 + br_array[i] = get_index(argv[i], "bridge");
443 +
444 + if(0 > (ifcount = get_port_list(argv[i], &namelist)))
445 + {
446 +ifaces_error_exit:
447 + for(i -= 2; i >= 0; --i)
448 + free(ifaces_lists[i]);
449 + free(ifaces_lists);
450 + free(br_array);
451 + return ifcount;
452 + }
453 +
454 + if(NULL == (ifaces_lists[i - 1] = malloc((ifcount + 1) * sizeof(int))))
455 + {
456 + fprintf(stderr, "out of memory, bridge %s, ifcount = %d\n",
457 + argv[i], ifcount);
458 + for(j = 0; j < ifcount; ++j)
459 + free(namelist[j]);
460 + free(namelist);
461 + ifcount = -1;
462 + goto ifaces_error_exit;
463 + }
464 +
465 + ifaces_lists[i - 1][0] = ifcount;
466 + for(j = 1; j <= ifcount; ++j)
467 + {
468 + ifaces_lists[i - 1][j] = get_index(namelist[j - 1]->d_name, "port");
469 + free(namelist[j - 1]);
470 + }
471 + free(namelist);
472 + }
473 +
474 + res = CTL_add_bridges(br_array, ifaces_lists);
475 +
476 + for(i = 0; i < brcount; ++i)
477 + free(ifaces_lists[i]);
478 + free(ifaces_lists);
479 + free(br_array);
480 + return res;
481 +}
482 +
483 +static int cmd_delbridge(int argc, char *const *argv)
484 +{
485 + int i, res, brcount = argc - 1;
486 + int *br_array;
487 +
488 + if(NULL == (br_array = malloc((brcount + 1) * sizeof(int))))
489 + {
490 + fprintf(stderr, "out of memory, brcount = %d\n", brcount);
491 + return -1;
492 + }
493 +
494 + br_array[0] = brcount;
495 + for(i = 1; i <= brcount; ++i)
496 + br_array[i] = get_index(argv[i], "bridge");
497 +
498 + res = CTL_del_bridges(br_array);
499 +
500 + free(br_array);
501 + return res;
502 +}
503 +
504 static unsigned int getuint(const char *s)
505 {
506 char *end;
507 @@ -1191,23 +1281,6 @@
508 return CTL_set_fid2mstid(br_index, fid, mstid);
509 }
510
511 -static int cmd_stp_mode_notification(int argc, char *const *argv, bool on)
512 -{
513 - int br_index;
514 - /* Because this command has special handling,
515 - * argc was not checked earlier
516 - */
517 - if(2 > argc)
518 - {
519 - fprintf(stderr,
520 - "Incorrect number of arguments for notification command\n");
521 - exit(1);
522 - }
523 - if(0 > (br_index = get_index(argv[1], "bridge")))
524 - return br_index;
525 - return CTL_stp_mode_notification(br_index, on);
526 -}
527 -
528 struct command
529 {
530 int nargs;
531 @@ -1220,6 +1293,12 @@
532
533 static const struct command commands[] =
534 {
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"},
540 +
541 /* Show global bridge */
542 {0, 32, "showbridge", cmd_showbridge,
543 "[<bridge> ... [param]]", "Show bridge state for the CIST"},
544 @@ -1370,12 +1449,6 @@
545 argv += optind;
546 if(NULL == (cmd = command_lookup(argv[0])))
547 {
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);
553 -
554 fprintf(stderr, "never heard of command [%s]\n", argv[0]);
555 goto help;
556 }
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)
562
563 +CTL_DECLARE(add_bridges)
564 +{
565 + int res = 0;
566 + LogString log = { .buf = "" };
567 + int i, chunk_count, brcount, serialized_data_count;
568 + int *serialized_data, *ptr;
569 +
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))))
574 + {
575 + LOG("out of memory, serialized_data_count = %d",
576 + serialized_data_count);
577 + return -1;
578 + }
579 + memcpy(serialized_data, br_array, chunk_count * sizeof(int));
580 + ptr = serialized_data + chunk_count;
581 + for(i = 0; i < brcount; ++i)
582 + {
583 + chunk_count = ifaces_lists[i][0] + 1;
584 + memcpy(ptr, ifaces_lists[i], chunk_count * sizeof(int));
585 + ptr += chunk_count;
586 + }
587 +
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);
592 + if(r || res)
593 + LOG("Got return code %d, %d\n%s", r, res, log.buf);
594 + if(r)
595 + return r;
596 + if(res)
597 + return res;
598 + return 0;
599 +}
600 +
601 +CTL_DECLARE(del_bridges)
602 +{
603 + int res = 0;
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);
608 + if(r || res)
609 + LOG("Got return code %d, %d\n%s", r, res, log.buf);
610 + if(r)
611 + return r;
612 + if(res)
613 + return res;
614 + return 0;
615 +}
616 +
617 /*********************** Logging *********************/
618
619 void Dprintf(int level, const char *fmt, ...)