interface: proto_ip: order by address index first
[project/netifd.git] / bridge.c
1 /*
2 * netifd - network interface daemon
3 * Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2
7 * as published by the Free Software Foundation
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14 #include <string.h>
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <assert.h>
18 #include <errno.h>
19
20 #include "netifd.h"
21 #include "device.h"
22 #include "interface.h"
23 #include "system.h"
24
25 enum {
26 BRIDGE_ATTR_IFNAME,
27 BRIDGE_ATTR_STP,
28 BRIDGE_ATTR_FORWARD_DELAY,
29 BRIDGE_ATTR_PRIORITY,
30 BRIDGE_ATTR_IGMP_SNOOP,
31 BRIDGE_ATTR_AGEING_TIME,
32 BRIDGE_ATTR_HELLO_TIME,
33 BRIDGE_ATTR_MAX_AGE,
34 BRIDGE_ATTR_BRIDGE_EMPTY,
35 BRIDGE_ATTR_MULTICAST_QUERIER,
36 BRIDGE_ATTR_HASH_MAX,
37 BRIDGE_ATTR_ROBUSTNESS,
38 BRIDGE_ATTR_QUERY_INTERVAL,
39 BRIDGE_ATTR_QUERY_RESPONSE_INTERVAL,
40 BRIDGE_ATTR_LAST_MEMBER_INTERVAL,
41 BRIDGE_ATTR_VLAN_FILTERING,
42 __BRIDGE_ATTR_MAX
43 };
44
45 static const struct blobmsg_policy bridge_attrs[__BRIDGE_ATTR_MAX] = {
46 [BRIDGE_ATTR_IFNAME] = { "ifname", BLOBMSG_TYPE_ARRAY },
47 [BRIDGE_ATTR_STP] = { "stp", BLOBMSG_TYPE_BOOL },
48 [BRIDGE_ATTR_FORWARD_DELAY] = { "forward_delay", BLOBMSG_TYPE_INT32 },
49 [BRIDGE_ATTR_PRIORITY] = { "priority", BLOBMSG_TYPE_INT32 },
50 [BRIDGE_ATTR_AGEING_TIME] = { "ageing_time", BLOBMSG_TYPE_INT32 },
51 [BRIDGE_ATTR_HELLO_TIME] = { "hello_time", BLOBMSG_TYPE_INT32 },
52 [BRIDGE_ATTR_MAX_AGE] = { "max_age", BLOBMSG_TYPE_INT32 },
53 [BRIDGE_ATTR_IGMP_SNOOP] = { "igmp_snooping", BLOBMSG_TYPE_BOOL },
54 [BRIDGE_ATTR_BRIDGE_EMPTY] = { "bridge_empty", BLOBMSG_TYPE_BOOL },
55 [BRIDGE_ATTR_MULTICAST_QUERIER] = { "multicast_querier", BLOBMSG_TYPE_BOOL },
56 [BRIDGE_ATTR_HASH_MAX] = { "hash_max", BLOBMSG_TYPE_INT32 },
57 [BRIDGE_ATTR_ROBUSTNESS] = { "robustness", BLOBMSG_TYPE_INT32 },
58 [BRIDGE_ATTR_QUERY_INTERVAL] = { "query_interval", BLOBMSG_TYPE_INT32 },
59 [BRIDGE_ATTR_QUERY_RESPONSE_INTERVAL] = { "query_response_interval", BLOBMSG_TYPE_INT32 },
60 [BRIDGE_ATTR_LAST_MEMBER_INTERVAL] = { "last_member_interval", BLOBMSG_TYPE_INT32 },
61 [BRIDGE_ATTR_VLAN_FILTERING] = { "vlan_filtering", BLOBMSG_TYPE_BOOL },
62 };
63
64 static const struct uci_blob_param_info bridge_attr_info[__BRIDGE_ATTR_MAX] = {
65 [BRIDGE_ATTR_IFNAME] = { .type = BLOBMSG_TYPE_STRING },
66 };
67
68 static const struct uci_blob_param_list bridge_attr_list = {
69 .n_params = __BRIDGE_ATTR_MAX,
70 .params = bridge_attrs,
71 .info = bridge_attr_info,
72
73 .n_next = 1,
74 .next = { &device_attr_list },
75 };
76
77 static struct device *bridge_create(const char *name, struct device_type *devtype,
78 struct blob_attr *attr);
79 static void bridge_config_init(struct device *dev);
80 static void bridge_free(struct device *dev);
81 static void bridge_dump_info(struct device *dev, struct blob_buf *b);
82 static enum dev_change_type
83 bridge_reload(struct device *dev, struct blob_attr *attr);
84
85 static struct device_type bridge_device_type = {
86 .name = "bridge",
87 .config_params = &bridge_attr_list,
88
89 .bridge_capability = true,
90 .name_prefix = "br",
91
92 .create = bridge_create,
93 .config_init = bridge_config_init,
94 .reload = bridge_reload,
95 .free = bridge_free,
96 .dump_info = bridge_dump_info,
97 };
98
99 struct bridge_state {
100 struct device dev;
101 device_state_cb set_state;
102
103 struct blob_attr *config_data;
104 struct bridge_config config;
105 struct blob_attr *ifnames;
106 bool active;
107 bool force_active;
108
109 struct uloop_timeout retry;
110 struct bridge_member *primary_port;
111 struct vlist_tree members;
112 int n_present;
113 int n_failed;
114 };
115
116 struct bridge_member {
117 struct vlist_node node;
118 struct bridge_state *bst;
119 struct device_user dev;
120 uint16_t pvid;
121 bool present;
122 char name[];
123 };
124
125 static void
126 bridge_reset_primary(struct bridge_state *bst)
127 {
128 struct bridge_member *bm;
129
130 if (!bst->primary_port &&
131 (bst->dev.settings.flags & DEV_OPT_MACADDR))
132 return;
133
134 bst->primary_port = NULL;
135 bst->dev.settings.flags &= ~DEV_OPT_MACADDR;
136 vlist_for_each_element(&bst->members, bm, node) {
137 uint8_t *macaddr;
138
139 if (!bm->present)
140 continue;
141
142 bst->primary_port = bm;
143 if (bm->dev.dev->settings.flags & DEV_OPT_MACADDR)
144 macaddr = bm->dev.dev->settings.macaddr;
145 else
146 macaddr = bm->dev.dev->orig_settings.macaddr;
147 memcpy(bst->dev.settings.macaddr, macaddr, 6);
148 bst->dev.settings.flags |= DEV_OPT_MACADDR;
149 return;
150 }
151 }
152
153 static struct bridge_vlan_port *
154 bridge_find_vlan_member_port(struct bridge_member *bm, struct bridge_vlan *vlan)
155 {
156 const char *ifname = bm->dev.dev->ifname;
157 int i;
158
159 for (i = 0; i < vlan->n_ports; i++) {
160 if (strcmp(vlan->ports[i].ifname, ifname) != 0)
161 continue;
162
163 return &vlan->ports[i];
164 }
165
166 return NULL;
167 }
168
169 static bool
170 bridge_member_vlan_is_pvid(struct bridge_member *bm, struct bridge_vlan_port *port)
171 {
172 return (!bm->pvid && (port->flags & BRVLAN_F_UNTAGGED)) ||
173 (port->flags & BRVLAN_F_PVID);
174 }
175
176 static void
177 __bridge_set_member_vlan(struct bridge_member *bm, struct bridge_vlan *vlan,
178 struct bridge_vlan_port *port, bool add)
179 {
180 uint16_t flags;
181
182 flags = port->flags;
183 if (bm->pvid == vlan->vid)
184 flags |= BRVLAN_F_PVID;
185
186 system_bridge_vlan(port->ifname, vlan->vid, add, flags);
187 }
188
189 static void
190 bridge_set_member_vlan(struct bridge_member *bm, struct bridge_vlan *vlan, bool add)
191 {
192 struct bridge_vlan_port *port;
193
194 if (!bm->present)
195 return;
196
197 port = bridge_find_vlan_member_port(bm, vlan);
198 if (!port)
199 return;
200
201 if (bridge_member_vlan_is_pvid(bm, port))
202 bm->pvid = vlan->vid;
203
204 __bridge_set_member_vlan(bm, vlan, port, add);
205 }
206
207 static void
208 brigde_set_local_vlan(struct bridge_state *bst, struct bridge_vlan *vlan, bool add)
209 {
210 if (!vlan->local && add)
211 return;
212
213 system_bridge_vlan(bst->dev.ifname, vlan->vid, add, BRVLAN_F_SELF);
214 }
215
216 static void
217 bridge_set_local_vlans(struct bridge_state *bst, bool add)
218 {
219 struct bridge_vlan *vlan;
220
221 vlist_for_each_element(&bst->dev.vlans, vlan, node)
222 brigde_set_local_vlan(bst, vlan, add);
223 }
224
225 static struct bridge_vlan *
226 bridge_recalc_member_pvid(struct bridge_member *bm)
227 {
228 struct bridge_state *bst = bm->bst;
229 struct bridge_vlan_port *port;
230 struct bridge_vlan *vlan, *ret = NULL;
231
232 vlist_for_each_element(&bst->dev.vlans, vlan, node) {
233 port = bridge_find_vlan_member_port(bm, vlan);
234 if (!port)
235 continue;
236
237 if (!bridge_member_vlan_is_pvid(bm, port))
238 continue;
239
240 ret = vlan;
241 if (port->flags & BRVLAN_F_PVID)
242 break;
243 }
244
245 return ret;
246 }
247
248 static void
249 bridge_set_vlan_state(struct bridge_state *bst, struct bridge_vlan *vlan, bool add)
250 {
251 struct bridge_member *bm;
252 struct bridge_vlan *vlan2;
253
254 brigde_set_local_vlan(bst, vlan, add);
255
256 vlist_for_each_element(&bst->members, bm, node) {
257 struct bridge_vlan_port *port;
258 int new_pvid = -1;
259
260 port = bridge_find_vlan_member_port(bm, vlan);
261 if (!port)
262 continue;
263
264 if (add) {
265 if (bridge_member_vlan_is_pvid(bm, port))
266 bm->pvid = vlan->vid;
267 } else if (bm->pvid == vlan->vid) {
268 vlan2 = bridge_recalc_member_pvid(bm);
269 if (vlan2 && vlan2->vid != vlan->vid) {
270 bridge_set_member_vlan(bm, vlan2, false);
271 bridge_set_member_vlan(bm, vlan2, true);
272 }
273 new_pvid = vlan2 ? vlan2->vid : 0;
274 }
275
276 if (!bm->present)
277 continue;
278
279 __bridge_set_member_vlan(bm, vlan, port, add);
280 if (new_pvid >= 0)
281 bm->pvid = new_pvid;
282 }
283 }
284
285 static int
286 bridge_disable_member(struct bridge_member *bm)
287 {
288 struct bridge_state *bst = bm->bst;
289 struct bridge_vlan *vlan;
290
291 if (!bm->present)
292 return 0;
293
294 vlist_for_each_element(&bst->dev.vlans, vlan, node)
295 bridge_set_member_vlan(bm, vlan, false);
296
297 system_bridge_delif(&bst->dev, bm->dev.dev);
298 device_release(&bm->dev);
299
300 device_broadcast_event(&bst->dev, DEV_EVENT_TOPO_CHANGE);
301
302 return 0;
303 }
304
305 static int
306 bridge_enable_interface(struct bridge_state *bst)
307 {
308 int ret;
309
310 if (bst->active)
311 return 0;
312
313 ret = system_bridge_addbr(&bst->dev, &bst->config);
314 if (ret < 0)
315 return ret;
316
317 if (bst->config.vlan_filtering) {
318 /* delete default VLAN 1 */
319 system_bridge_vlan(bst->dev.ifname, 1, false, BRVLAN_F_SELF);
320
321 bridge_set_local_vlans(bst, true);
322 }
323
324 bst->active = true;
325 return 0;
326 }
327
328 static void
329 bridge_disable_interface(struct bridge_state *bst)
330 {
331 if (!bst->active)
332 return;
333
334 system_bridge_delbr(&bst->dev);
335 bst->active = false;
336 }
337
338 static int
339 bridge_enable_member(struct bridge_member *bm)
340 {
341 struct bridge_state *bst = bm->bst;
342 struct bridge_vlan *vlan;
343 int ret;
344
345 if (!bm->present)
346 return 0;
347
348 ret = bridge_enable_interface(bst);
349 if (ret)
350 goto error;
351
352 /* Disable IPv6 for bridge members */
353 if (!(bm->dev.dev->settings.flags & DEV_OPT_IPV6)) {
354 bm->dev.dev->settings.ipv6 = 0;
355 bm->dev.dev->settings.flags |= DEV_OPT_IPV6;
356 }
357
358 ret = device_claim(&bm->dev);
359 if (ret < 0)
360 goto error;
361
362 ret = system_bridge_addif(&bst->dev, bm->dev.dev);
363 if (ret < 0) {
364 D(DEVICE, "Bridge device %s could not be added\n", bm->dev.dev->ifname);
365 goto error;
366 }
367
368 if (bst->config.vlan_filtering) {
369 /* delete default VLAN 1 */
370 system_bridge_vlan(bm->dev.dev->ifname, 1, false, 0);
371
372 vlist_for_each_element(&bst->dev.vlans, vlan, node)
373 bridge_set_member_vlan(bm, vlan, true);
374 }
375
376 device_set_present(&bst->dev, true);
377 device_broadcast_event(&bst->dev, DEV_EVENT_TOPO_CHANGE);
378
379 return 0;
380
381 error:
382 bst->n_failed++;
383 bm->present = false;
384 bst->n_present--;
385 device_release(&bm->dev);
386
387 return ret;
388 }
389
390 static void
391 bridge_remove_member(struct bridge_member *bm)
392 {
393 struct bridge_state *bst = bm->bst;
394
395 if (!bm->present)
396 return;
397
398 if (bst->dev.active)
399 bridge_disable_member(bm);
400
401 bm->present = false;
402 bm->bst->n_present--;
403
404 if (bm == bst->primary_port)
405 bridge_reset_primary(bst);
406
407 if (bst->config.bridge_empty)
408 return;
409
410 bst->force_active = false;
411 if (bst->n_present == 0)
412 device_set_present(&bst->dev, false);
413 }
414
415 static void
416 bridge_free_member(struct bridge_member *bm)
417 {
418 struct device *dev = bm->dev.dev;
419
420 bridge_remove_member(bm);
421 device_remove_user(&bm->dev);
422
423 /*
424 * When reloading the config and moving a device from one bridge to
425 * another, the other bridge may have tried to claim this device
426 * before it was removed here.
427 * Ensure that claiming the device is retried by toggling its present
428 * state
429 */
430 if (dev->present) {
431 device_set_present(dev, false);
432 device_set_present(dev, true);
433 }
434
435 free(bm);
436 }
437
438 static void
439 bridge_check_retry(struct bridge_state *bst)
440 {
441 if (!bst->n_failed)
442 return;
443
444 uloop_timeout_set(&bst->retry, 100);
445 }
446
447 static void
448 bridge_member_cb(struct device_user *dev, enum device_event ev)
449 {
450 struct bridge_member *bm = container_of(dev, struct bridge_member, dev);
451 struct bridge_state *bst = bm->bst;
452
453 switch (ev) {
454 case DEV_EVENT_ADD:
455 assert(!bm->present);
456
457 bm->present = true;
458 bst->n_present++;
459
460 if (bst->n_present == 1)
461 device_set_present(&bst->dev, true);
462 if (bst->dev.active && !bridge_enable_member(bm)) {
463 /*
464 * Adding a bridge member can overwrite the bridge mtu
465 * in the kernel, apply the bridge settings in case the
466 * bridge mtu is set
467 */
468 system_if_apply_settings(&bst->dev, &bst->dev.settings,
469 DEV_OPT_MTU | DEV_OPT_MTU6);
470 }
471
472 break;
473 case DEV_EVENT_REMOVE:
474 if (dev->hotplug) {
475 vlist_delete(&bst->members, &bm->node);
476 return;
477 }
478
479 if (bm->present)
480 bridge_remove_member(bm);
481
482 break;
483 default:
484 return;
485 }
486 }
487
488 static int
489 bridge_set_down(struct bridge_state *bst)
490 {
491 struct bridge_member *bm;
492
493 bst->set_state(&bst->dev, false);
494
495 vlist_for_each_element(&bst->members, bm, node)
496 bridge_disable_member(bm);
497
498 bridge_disable_interface(bst);
499
500 return 0;
501 }
502
503 static int
504 bridge_set_up(struct bridge_state *bst)
505 {
506 struct bridge_member *bm;
507 int ret;
508
509 if (!bst->n_present) {
510 if (!bst->force_active)
511 return -ENOENT;
512
513 ret = bridge_enable_interface(bst);
514 if (ret)
515 return ret;
516 }
517
518 bst->n_failed = 0;
519 vlist_for_each_element(&bst->members, bm, node)
520 bridge_enable_member(bm);
521 bridge_check_retry(bst);
522
523 if (!bst->force_active && !bst->n_present) {
524 /* initialization of all member interfaces failed */
525 bridge_disable_interface(bst);
526 device_set_present(&bst->dev, false);
527 return -ENOENT;
528 }
529
530 bridge_reset_primary(bst);
531 ret = bst->set_state(&bst->dev, true);
532 if (ret < 0)
533 bridge_set_down(bst);
534
535 return ret;
536 }
537
538 static int
539 bridge_set_state(struct device *dev, bool up)
540 {
541 struct bridge_state *bst;
542
543 bst = container_of(dev, struct bridge_state, dev);
544
545 if (up)
546 return bridge_set_up(bst);
547 else
548 return bridge_set_down(bst);
549 }
550
551 static struct bridge_member *
552 bridge_create_member(struct bridge_state *bst, const char *name,
553 struct device *dev, bool hotplug)
554 {
555 struct bridge_member *bm;
556
557 bm = calloc(1, sizeof(*bm) + strlen(name) + 1);
558 if (!bm)
559 return NULL;
560
561 bm->bst = bst;
562 bm->dev.cb = bridge_member_cb;
563 bm->dev.hotplug = hotplug;
564 strcpy(bm->name, name);
565 bm->dev.dev = dev;
566 vlist_add(&bst->members, &bm->node, bm->name);
567 /*
568 * Need to look up the bridge member again as the above
569 * created pointer will be freed in case the bridge member
570 * already existed
571 */
572 bm = vlist_find(&bst->members, name, bm, node);
573 if (hotplug && bm)
574 bm->node.version = -1;
575
576 return bm;
577 }
578
579 static void
580 bridge_member_update(struct vlist_tree *tree, struct vlist_node *node_new,
581 struct vlist_node *node_old)
582 {
583 struct bridge_member *bm;
584 struct device *dev;
585
586 if (node_new) {
587 bm = container_of(node_new, struct bridge_member, node);
588
589 if (node_old) {
590 free(bm);
591 return;
592 }
593
594 dev = bm->dev.dev;
595 bm->dev.dev = NULL;
596 device_add_user(&bm->dev, dev);
597 }
598
599
600 if (node_old) {
601 bm = container_of(node_old, struct bridge_member, node);
602 bridge_free_member(bm);
603 }
604 }
605
606
607 static void
608 bridge_add_member(struct bridge_state *bst, const char *name)
609 {
610 struct device *dev;
611
612 dev = device_get(name, true);
613 if (!dev)
614 return;
615
616 bridge_create_member(bst, name, dev, false);
617 }
618
619 static int
620 bridge_hotplug_add(struct device *dev, struct device *member)
621 {
622 struct bridge_state *bst = container_of(dev, struct bridge_state, dev);
623
624 bridge_create_member(bst, member->ifname, member, true);
625
626 return 0;
627 }
628
629 static int
630 bridge_hotplug_del(struct device *dev, struct device *member)
631 {
632 struct bridge_state *bst = container_of(dev, struct bridge_state, dev);
633 struct bridge_member *bm;
634
635 bm = vlist_find(&bst->members, member->ifname, bm, node);
636 if (!bm)
637 return UBUS_STATUS_NOT_FOUND;
638
639 vlist_delete(&bst->members, &bm->node);
640 return 0;
641 }
642
643 static int
644 bridge_hotplug_prepare(struct device *dev)
645 {
646 struct bridge_state *bst;
647
648 bst = container_of(dev, struct bridge_state, dev);
649 bst->force_active = true;
650 device_set_present(&bst->dev, true);
651
652 return 0;
653 }
654
655 static const struct device_hotplug_ops bridge_ops = {
656 .prepare = bridge_hotplug_prepare,
657 .add = bridge_hotplug_add,
658 .del = bridge_hotplug_del
659 };
660
661 static void
662 bridge_free(struct device *dev)
663 {
664 struct bridge_state *bst;
665
666 bst = container_of(dev, struct bridge_state, dev);
667 vlist_flush_all(&bst->members);
668 vlist_flush_all(&dev->vlans);
669 free(bst->config_data);
670 free(bst);
671 }
672
673 static void
674 bridge_dump_info(struct device *dev, struct blob_buf *b)
675 {
676 struct bridge_state *bst;
677 struct bridge_member *bm;
678 void *list;
679
680 bst = container_of(dev, struct bridge_state, dev);
681
682 system_if_dump_info(dev, b);
683 list = blobmsg_open_array(b, "bridge-members");
684
685 vlist_for_each_element(&bst->members, bm, node) {
686 if (bm->dev.dev->hidden)
687 continue;
688
689 blobmsg_add_string(b, NULL, bm->dev.dev->ifname);
690 }
691
692 blobmsg_close_array(b, list);
693 }
694
695 static void
696 bridge_config_init(struct device *dev)
697 {
698 struct bridge_state *bst;
699 struct bridge_vlan *vlan;
700 struct blob_attr *cur;
701 int i, rem;
702
703 bst = container_of(dev, struct bridge_state, dev);
704
705 if (bst->config.bridge_empty) {
706 bst->force_active = true;
707 device_set_present(&bst->dev, true);
708 }
709
710 bst->n_failed = 0;
711 vlist_update(&bst->members);
712 if (bst->ifnames) {
713 blobmsg_for_each_attr(cur, bst->ifnames, rem) {
714 bridge_add_member(bst, blobmsg_data(cur));
715 }
716 }
717
718 vlist_for_each_element(&bst->dev.vlans, vlan, node)
719 for (i = 0; i < vlan->n_ports; i++)
720 bridge_add_member(bst, vlan->ports[i].ifname);
721
722 vlist_flush(&bst->members);
723 bridge_check_retry(bst);
724 }
725
726 static void
727 bridge_apply_settings(struct bridge_state *bst, struct blob_attr **tb)
728 {
729 struct bridge_config *cfg = &bst->config;
730 struct blob_attr *cur;
731
732 /* defaults */
733 cfg->stp = false;
734 cfg->forward_delay = 2;
735 cfg->robustness = 2;
736 cfg->query_interval = 12500;
737 cfg->query_response_interval = 1000;
738 cfg->last_member_interval = 100;
739 cfg->hash_max = 512;
740 cfg->bridge_empty = false;
741 cfg->priority = 0x7FFF;
742 cfg->vlan_filtering = false;
743
744 if ((cur = tb[BRIDGE_ATTR_STP]))
745 cfg->stp = blobmsg_get_bool(cur);
746
747 if ((cur = tb[BRIDGE_ATTR_FORWARD_DELAY]))
748 cfg->forward_delay = blobmsg_get_u32(cur);
749
750 if ((cur = tb[BRIDGE_ATTR_PRIORITY]))
751 cfg->priority = blobmsg_get_u32(cur);
752
753 if ((cur = tb[BRIDGE_ATTR_IGMP_SNOOP]))
754 cfg->multicast_querier = cfg->igmp_snoop = blobmsg_get_bool(cur);
755
756 if ((cur = tb[BRIDGE_ATTR_MULTICAST_QUERIER]))
757 cfg->multicast_querier = blobmsg_get_bool(cur);
758
759 if ((cur = tb[BRIDGE_ATTR_HASH_MAX]))
760 cfg->hash_max = blobmsg_get_u32(cur);
761
762 if ((cur = tb[BRIDGE_ATTR_ROBUSTNESS])) {
763 cfg->robustness = blobmsg_get_u32(cur);
764 cfg->flags |= BRIDGE_OPT_ROBUSTNESS;
765 }
766
767 if ((cur = tb[BRIDGE_ATTR_QUERY_INTERVAL])) {
768 cfg->query_interval = blobmsg_get_u32(cur);
769 cfg->flags |= BRIDGE_OPT_QUERY_INTERVAL;
770 }
771
772 if ((cur = tb[BRIDGE_ATTR_QUERY_RESPONSE_INTERVAL])) {
773 cfg->query_response_interval = blobmsg_get_u32(cur);
774 cfg->flags |= BRIDGE_OPT_QUERY_RESPONSE_INTERVAL;
775 }
776
777 if ((cur = tb[BRIDGE_ATTR_LAST_MEMBER_INTERVAL])) {
778 cfg->last_member_interval = blobmsg_get_u32(cur);
779 cfg->flags |= BRIDGE_OPT_LAST_MEMBER_INTERVAL;
780 }
781
782 if ((cur = tb[BRIDGE_ATTR_AGEING_TIME])) {
783 cfg->ageing_time = blobmsg_get_u32(cur);
784 cfg->flags |= BRIDGE_OPT_AGEING_TIME;
785 }
786
787 if ((cur = tb[BRIDGE_ATTR_HELLO_TIME])) {
788 cfg->hello_time = blobmsg_get_u32(cur);
789 cfg->flags |= BRIDGE_OPT_HELLO_TIME;
790 }
791
792 if ((cur = tb[BRIDGE_ATTR_MAX_AGE])) {
793 cfg->max_age = blobmsg_get_u32(cur);
794 cfg->flags |= BRIDGE_OPT_MAX_AGE;
795 }
796
797 if ((cur = tb[BRIDGE_ATTR_BRIDGE_EMPTY]))
798 cfg->bridge_empty = blobmsg_get_bool(cur);
799
800 if ((cur = tb[BRIDGE_ATTR_VLAN_FILTERING]))
801 cfg->vlan_filtering = blobmsg_get_bool(cur);
802 }
803
804 static enum dev_change_type
805 bridge_reload(struct device *dev, struct blob_attr *attr)
806 {
807 struct blob_attr *tb_dev[__DEV_ATTR_MAX];
808 struct blob_attr *tb_br[__BRIDGE_ATTR_MAX];
809 enum dev_change_type ret = DEV_CONFIG_APPLIED;
810 unsigned long diff;
811 struct bridge_state *bst;
812
813 BUILD_BUG_ON(sizeof(diff) < __BRIDGE_ATTR_MAX / 8);
814 BUILD_BUG_ON(sizeof(diff) < __DEV_ATTR_MAX / 8);
815
816 bst = container_of(dev, struct bridge_state, dev);
817 attr = blob_memdup(attr);
818
819 blobmsg_parse(device_attr_list.params, __DEV_ATTR_MAX, tb_dev,
820 blob_data(attr), blob_len(attr));
821 blobmsg_parse(bridge_attrs, __BRIDGE_ATTR_MAX, tb_br,
822 blob_data(attr), blob_len(attr));
823
824 if (tb_dev[DEV_ATTR_MACADDR])
825 bst->primary_port = NULL;
826
827 bst->ifnames = tb_br[BRIDGE_ATTR_IFNAME];
828 device_init_settings(dev, tb_dev);
829 bridge_apply_settings(bst, tb_br);
830
831 if (bst->config_data) {
832 struct blob_attr *otb_dev[__DEV_ATTR_MAX];
833 struct blob_attr *otb_br[__BRIDGE_ATTR_MAX];
834
835 blobmsg_parse(device_attr_list.params, __DEV_ATTR_MAX, otb_dev,
836 blob_data(bst->config_data), blob_len(bst->config_data));
837
838 diff = 0;
839 uci_blob_diff(tb_dev, otb_dev, &device_attr_list, &diff);
840 if (diff)
841 ret = DEV_CONFIG_RESTART;
842
843 blobmsg_parse(bridge_attrs, __BRIDGE_ATTR_MAX, otb_br,
844 blob_data(bst->config_data), blob_len(bst->config_data));
845
846 diff = 0;
847 uci_blob_diff(tb_br, otb_br, &bridge_attr_list, &diff);
848 if (diff & ~(1 << BRIDGE_ATTR_IFNAME))
849 ret = DEV_CONFIG_RESTART;
850
851 bridge_config_init(dev);
852 }
853
854 free(bst->config_data);
855 bst->config_data = attr;
856 return ret;
857 }
858
859 static void
860 bridge_retry_members(struct uloop_timeout *timeout)
861 {
862 struct bridge_state *bst = container_of(timeout, struct bridge_state, retry);
863 struct bridge_member *bm;
864
865 bst->n_failed = 0;
866 vlist_for_each_element(&bst->members, bm, node) {
867 if (bm->present)
868 continue;
869
870 if (!bm->dev.dev->present)
871 continue;
872
873 bm->present = true;
874 bst->n_present++;
875 bridge_enable_member(bm);
876 }
877 }
878
879 static int bridge_avl_cmp_u16(const void *k1, const void *k2, void *ptr)
880 {
881 const uint16_t *i1 = k1, *i2 = k2;
882
883 return *i1 - *i2;
884 }
885
886 static bool
887 bridge_vlan_equal(struct bridge_vlan *v1, struct bridge_vlan *v2)
888 {
889 int i;
890
891 if (v1->n_ports != v2->n_ports)
892 return false;
893
894 for (i = 0; i < v1->n_ports; i++)
895 if (v1->ports[i].flags != v2->ports[i].flags ||
896 strcmp(v1->ports[i].ifname, v2->ports[i].ifname) != 0)
897 return false;
898
899 return true;
900 }
901
902 static void
903 bridge_vlan_update(struct vlist_tree *tree, struct vlist_node *node_new,
904 struct vlist_node *node_old)
905 {
906 struct bridge_state *bst = container_of(tree, struct bridge_state, dev.vlans);
907 struct bridge_vlan *vlan_new = NULL, *vlan_old = NULL;
908
909 if (!bst->config.vlan_filtering || !bst->active)
910 goto out;
911
912 if (node_old)
913 vlan_old = container_of(node_old, struct bridge_vlan, node);
914 if (node_new)
915 vlan_new = container_of(node_new, struct bridge_vlan, node);
916
917 if (node_new && node_old && bridge_vlan_equal(vlan_old, vlan_new))
918 goto out;
919
920 if (node_old)
921 bridge_set_vlan_state(bst, vlan_old, false);
922
923 if (node_new)
924 bridge_set_vlan_state(bst, vlan_new, true);
925
926 bst->dev.config_pending = true;
927
928 out:
929 free(vlan_old);
930 }
931
932 static struct device *
933 bridge_create(const char *name, struct device_type *devtype,
934 struct blob_attr *attr)
935 {
936 struct bridge_state *bst;
937 struct device *dev = NULL;
938
939 bst = calloc(1, sizeof(*bst));
940 if (!bst)
941 return NULL;
942
943 dev = &bst->dev;
944
945 if (device_init(dev, devtype, name) < 0) {
946 device_cleanup(dev);
947 free(bst);
948 return NULL;
949 }
950
951 dev->config_pending = true;
952 bst->retry.cb = bridge_retry_members;
953
954 bst->set_state = dev->set_state;
955 dev->set_state = bridge_set_state;
956
957 dev->hotplug_ops = &bridge_ops;
958
959 vlist_init(&bst->members, avl_strcmp, bridge_member_update);
960 bst->members.keep_old = true;
961
962 vlist_init(&dev->vlans, bridge_avl_cmp_u16, bridge_vlan_update);
963
964 bridge_reload(dev, attr);
965
966 return dev;
967 }
968
969 static void __init bridge_device_type_init(void)
970 {
971 device_type_add(&bridge_device_type);
972 }