device: look up full device name before traversing vlan chain
[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 free(bst->config_data);
669 free(bst);
670 }
671
672 static void
673 bridge_dump_info(struct device *dev, struct blob_buf *b)
674 {
675 struct bridge_state *bst;
676 struct bridge_member *bm;
677 void *list;
678
679 bst = container_of(dev, struct bridge_state, dev);
680
681 system_if_dump_info(dev, b);
682 list = blobmsg_open_array(b, "bridge-members");
683
684 vlist_for_each_element(&bst->members, bm, node) {
685 if (bm->dev.dev->hidden)
686 continue;
687
688 blobmsg_add_string(b, NULL, bm->dev.dev->ifname);
689 }
690
691 blobmsg_close_array(b, list);
692 }
693
694 static void
695 bridge_config_init(struct device *dev)
696 {
697 struct bridge_state *bst;
698 struct bridge_vlan *vlan;
699 struct blob_attr *cur;
700 int i, rem;
701
702 bst = container_of(dev, struct bridge_state, dev);
703
704 if (bst->config.bridge_empty) {
705 bst->force_active = true;
706 device_set_present(&bst->dev, true);
707 }
708
709 bst->n_failed = 0;
710 vlist_update(&bst->members);
711 if (bst->ifnames) {
712 blobmsg_for_each_attr(cur, bst->ifnames, rem) {
713 bridge_add_member(bst, blobmsg_data(cur));
714 }
715 }
716
717 vlist_for_each_element(&bst->dev.vlans, vlan, node)
718 for (i = 0; i < vlan->n_ports; i++)
719 bridge_add_member(bst, vlan->ports[i].ifname);
720
721 vlist_flush(&bst->members);
722 bridge_check_retry(bst);
723 }
724
725 static void
726 bridge_apply_settings(struct bridge_state *bst, struct blob_attr **tb)
727 {
728 struct bridge_config *cfg = &bst->config;
729 struct blob_attr *cur;
730
731 /* defaults */
732 cfg->stp = false;
733 cfg->forward_delay = 2;
734 cfg->robustness = 2;
735 cfg->query_interval = 12500;
736 cfg->query_response_interval = 1000;
737 cfg->last_member_interval = 100;
738 cfg->hash_max = 512;
739 cfg->bridge_empty = false;
740 cfg->priority = 0x7FFF;
741 cfg->vlan_filtering = false;
742
743 if ((cur = tb[BRIDGE_ATTR_STP]))
744 cfg->stp = blobmsg_get_bool(cur);
745
746 if ((cur = tb[BRIDGE_ATTR_FORWARD_DELAY]))
747 cfg->forward_delay = blobmsg_get_u32(cur);
748
749 if ((cur = tb[BRIDGE_ATTR_PRIORITY]))
750 cfg->priority = blobmsg_get_u32(cur);
751
752 if ((cur = tb[BRIDGE_ATTR_IGMP_SNOOP]))
753 cfg->multicast_querier = cfg->igmp_snoop = blobmsg_get_bool(cur);
754
755 if ((cur = tb[BRIDGE_ATTR_MULTICAST_QUERIER]))
756 cfg->multicast_querier = blobmsg_get_bool(cur);
757
758 if ((cur = tb[BRIDGE_ATTR_HASH_MAX]))
759 cfg->hash_max = blobmsg_get_u32(cur);
760
761 if ((cur = tb[BRIDGE_ATTR_ROBUSTNESS])) {
762 cfg->robustness = blobmsg_get_u32(cur);
763 cfg->flags |= BRIDGE_OPT_ROBUSTNESS;
764 }
765
766 if ((cur = tb[BRIDGE_ATTR_QUERY_INTERVAL])) {
767 cfg->query_interval = blobmsg_get_u32(cur);
768 cfg->flags |= BRIDGE_OPT_QUERY_INTERVAL;
769 }
770
771 if ((cur = tb[BRIDGE_ATTR_QUERY_RESPONSE_INTERVAL])) {
772 cfg->query_response_interval = blobmsg_get_u32(cur);
773 cfg->flags |= BRIDGE_OPT_QUERY_RESPONSE_INTERVAL;
774 }
775
776 if ((cur = tb[BRIDGE_ATTR_LAST_MEMBER_INTERVAL])) {
777 cfg->last_member_interval = blobmsg_get_u32(cur);
778 cfg->flags |= BRIDGE_OPT_LAST_MEMBER_INTERVAL;
779 }
780
781 if ((cur = tb[BRIDGE_ATTR_AGEING_TIME])) {
782 cfg->ageing_time = blobmsg_get_u32(cur);
783 cfg->flags |= BRIDGE_OPT_AGEING_TIME;
784 }
785
786 if ((cur = tb[BRIDGE_ATTR_HELLO_TIME])) {
787 cfg->hello_time = blobmsg_get_u32(cur);
788 cfg->flags |= BRIDGE_OPT_HELLO_TIME;
789 }
790
791 if ((cur = tb[BRIDGE_ATTR_MAX_AGE])) {
792 cfg->max_age = blobmsg_get_u32(cur);
793 cfg->flags |= BRIDGE_OPT_MAX_AGE;
794 }
795
796 if ((cur = tb[BRIDGE_ATTR_BRIDGE_EMPTY]))
797 cfg->bridge_empty = blobmsg_get_bool(cur);
798
799 if ((cur = tb[BRIDGE_ATTR_VLAN_FILTERING]))
800 cfg->vlan_filtering = blobmsg_get_bool(cur);
801 }
802
803 static enum dev_change_type
804 bridge_reload(struct device *dev, struct blob_attr *attr)
805 {
806 struct blob_attr *tb_dev[__DEV_ATTR_MAX];
807 struct blob_attr *tb_br[__BRIDGE_ATTR_MAX];
808 enum dev_change_type ret = DEV_CONFIG_APPLIED;
809 unsigned long diff;
810 struct bridge_state *bst;
811
812 BUILD_BUG_ON(sizeof(diff) < __BRIDGE_ATTR_MAX / 8);
813 BUILD_BUG_ON(sizeof(diff) < __DEV_ATTR_MAX / 8);
814
815 bst = container_of(dev, struct bridge_state, dev);
816 attr = blob_memdup(attr);
817
818 blobmsg_parse(device_attr_list.params, __DEV_ATTR_MAX, tb_dev,
819 blob_data(attr), blob_len(attr));
820 blobmsg_parse(bridge_attrs, __BRIDGE_ATTR_MAX, tb_br,
821 blob_data(attr), blob_len(attr));
822
823 if (tb_dev[DEV_ATTR_MACADDR])
824 bst->primary_port = NULL;
825
826 bst->ifnames = tb_br[BRIDGE_ATTR_IFNAME];
827 device_init_settings(dev, tb_dev);
828 bridge_apply_settings(bst, tb_br);
829
830 if (bst->config_data) {
831 struct blob_attr *otb_dev[__DEV_ATTR_MAX];
832 struct blob_attr *otb_br[__BRIDGE_ATTR_MAX];
833
834 blobmsg_parse(device_attr_list.params, __DEV_ATTR_MAX, otb_dev,
835 blob_data(bst->config_data), blob_len(bst->config_data));
836
837 diff = 0;
838 uci_blob_diff(tb_dev, otb_dev, &device_attr_list, &diff);
839 if (diff)
840 ret = DEV_CONFIG_RESTART;
841
842 blobmsg_parse(bridge_attrs, __BRIDGE_ATTR_MAX, otb_br,
843 blob_data(bst->config_data), blob_len(bst->config_data));
844
845 diff = 0;
846 uci_blob_diff(tb_br, otb_br, &bridge_attr_list, &diff);
847 if (diff & ~(1 << BRIDGE_ATTR_IFNAME))
848 ret = DEV_CONFIG_RESTART;
849
850 bridge_config_init(dev);
851 }
852
853 free(bst->config_data);
854 bst->config_data = attr;
855 return ret;
856 }
857
858 static void
859 bridge_retry_members(struct uloop_timeout *timeout)
860 {
861 struct bridge_state *bst = container_of(timeout, struct bridge_state, retry);
862 struct bridge_member *bm;
863
864 bst->n_failed = 0;
865 vlist_for_each_element(&bst->members, bm, node) {
866 if (bm->present)
867 continue;
868
869 if (!bm->dev.dev->present)
870 continue;
871
872 bm->present = true;
873 bst->n_present++;
874 bridge_enable_member(bm);
875 }
876 }
877
878 static int bridge_avl_cmp_u16(const void *k1, const void *k2, void *ptr)
879 {
880 const uint16_t *i1 = k1, *i2 = k2;
881
882 return *i1 - *i2;
883 }
884
885 static bool
886 bridge_vlan_equal(struct bridge_vlan *v1, struct bridge_vlan *v2)
887 {
888 int i;
889
890 if (v1->n_ports != v2->n_ports)
891 return false;
892
893 for (i = 0; i < v1->n_ports; i++)
894 if (v1->ports[i].flags != v2->ports[i].flags ||
895 strcmp(v1->ports[i].ifname, v2->ports[i].ifname) != 0)
896 return false;
897
898 return true;
899 }
900
901 static void
902 bridge_vlan_update(struct vlist_tree *tree, struct vlist_node *node_new,
903 struct vlist_node *node_old)
904 {
905 struct bridge_state *bst = container_of(tree, struct bridge_state, dev.vlans);
906 struct bridge_vlan *vlan_new = NULL, *vlan_old = NULL;
907
908 if (!bst->config.vlan_filtering || !bst->active)
909 goto out;
910
911 if (node_old)
912 vlan_old = container_of(node_old, struct bridge_vlan, node);
913 if (node_new)
914 vlan_new = container_of(node_new, struct bridge_vlan, node);
915
916 if (node_new && node_old && bridge_vlan_equal(vlan_old, vlan_new))
917 goto out;
918
919 if (node_old)
920 bridge_set_vlan_state(bst, vlan_old, false);
921
922 if (node_new)
923 bridge_set_vlan_state(bst, vlan_new, true);
924
925 bst->dev.config_pending = true;
926
927 out:
928 free(vlan_old);
929 }
930
931 static struct device *
932 bridge_create(const char *name, struct device_type *devtype,
933 struct blob_attr *attr)
934 {
935 struct bridge_state *bst;
936 struct device *dev = NULL;
937
938 bst = calloc(1, sizeof(*bst));
939 if (!bst)
940 return NULL;
941
942 dev = &bst->dev;
943
944 if (device_init(dev, devtype, name) < 0) {
945 device_cleanup(dev);
946 free(bst);
947 return NULL;
948 }
949
950 dev->config_pending = true;
951 bst->retry.cb = bridge_retry_members;
952
953 bst->set_state = dev->set_state;
954 dev->set_state = bridge_set_state;
955
956 dev->hotplug_ops = &bridge_ops;
957
958 vlist_init(&bst->members, avl_strcmp, bridge_member_update);
959 bst->members.keep_old = true;
960
961 vlist_init(&dev->vlans, bridge_avl_cmp_u16, bridge_vlan_update);
962
963 bridge_reload(dev, attr);
964
965 return dev;
966 }
967
968 static void __init bridge_device_type_init(void)
969 {
970 device_type_add(&bridge_device_type);
971 }