• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/netifd/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 #include "ubus.h"
 25 
 26 enum {
 27         BRIDGE_ATTR_PORTS,
 28         BRIDGE_ATTR_STP,
 29         BRIDGE_ATTR_FORWARD_DELAY,
 30         BRIDGE_ATTR_PRIORITY,
 31         BRIDGE_ATTR_IGMP_SNOOP,
 32         BRIDGE_ATTR_AGEING_TIME,
 33         BRIDGE_ATTR_HELLO_TIME,
 34         BRIDGE_ATTR_MAX_AGE,
 35         BRIDGE_ATTR_BRIDGE_EMPTY,
 36         BRIDGE_ATTR_MULTICAST_QUERIER,
 37         BRIDGE_ATTR_HASH_MAX,
 38         BRIDGE_ATTR_ROBUSTNESS,
 39         BRIDGE_ATTR_QUERY_INTERVAL,
 40         BRIDGE_ATTR_QUERY_RESPONSE_INTERVAL,
 41         BRIDGE_ATTR_LAST_MEMBER_INTERVAL,
 42         BRIDGE_ATTR_VLAN_FILTERING,
 43         BRIDGE_ATTR_HAS_VLANS,
 44         BRIDGE_ATTR_STP_KERNEL,
 45         BRIDGE_ATTR_STP_PROTO,
 46         __BRIDGE_ATTR_MAX
 47 };
 48 
 49 static const struct blobmsg_policy bridge_attrs[__BRIDGE_ATTR_MAX] = {
 50         [BRIDGE_ATTR_PORTS] = { "ports", BLOBMSG_TYPE_ARRAY },
 51         [BRIDGE_ATTR_STP] = { "stp", BLOBMSG_TYPE_BOOL },
 52         [BRIDGE_ATTR_FORWARD_DELAY] = { "forward_delay", BLOBMSG_TYPE_INT32 },
 53         [BRIDGE_ATTR_PRIORITY] = { "priority", BLOBMSG_TYPE_INT32 },
 54         [BRIDGE_ATTR_AGEING_TIME] = { "ageing_time", BLOBMSG_TYPE_INT32 },
 55         [BRIDGE_ATTR_HELLO_TIME] = { "hello_time", BLOBMSG_TYPE_INT32 },
 56         [BRIDGE_ATTR_MAX_AGE] = { "max_age", BLOBMSG_TYPE_INT32 },
 57         [BRIDGE_ATTR_IGMP_SNOOP] = { "igmp_snooping", BLOBMSG_TYPE_BOOL },
 58         [BRIDGE_ATTR_BRIDGE_EMPTY] = { "bridge_empty", BLOBMSG_TYPE_BOOL },
 59         [BRIDGE_ATTR_MULTICAST_QUERIER] = { "multicast_querier", BLOBMSG_TYPE_BOOL },
 60         [BRIDGE_ATTR_HASH_MAX] = { "hash_max", BLOBMSG_TYPE_INT32 },
 61         [BRIDGE_ATTR_ROBUSTNESS] = { "robustness", BLOBMSG_TYPE_INT32 },
 62         [BRIDGE_ATTR_QUERY_INTERVAL] = { "query_interval", BLOBMSG_TYPE_INT32 },
 63         [BRIDGE_ATTR_QUERY_RESPONSE_INTERVAL] = { "query_response_interval", BLOBMSG_TYPE_INT32 },
 64         [BRIDGE_ATTR_LAST_MEMBER_INTERVAL] = { "last_member_interval", BLOBMSG_TYPE_INT32 },
 65         [BRIDGE_ATTR_VLAN_FILTERING] = { "vlan_filtering", BLOBMSG_TYPE_BOOL },
 66         [BRIDGE_ATTR_HAS_VLANS] = { "__has_vlans", BLOBMSG_TYPE_BOOL }, /* internal */
 67         [BRIDGE_ATTR_STP_KERNEL] = { "stp_kernel", BLOBMSG_TYPE_BOOL },
 68         [BRIDGE_ATTR_STP_PROTO] = { "stp_proto", BLOBMSG_TYPE_STRING },
 69 };
 70 
 71 static const struct uci_blob_param_info bridge_attr_info[__BRIDGE_ATTR_MAX] = {
 72         [BRIDGE_ATTR_PORTS] = { .type = BLOBMSG_TYPE_STRING },
 73 };
 74 
 75 static const struct uci_blob_param_list bridge_attr_list = {
 76         .n_params = __BRIDGE_ATTR_MAX,
 77         .params = bridge_attrs,
 78         .info = bridge_attr_info,
 79 
 80         .n_next = 1,
 81         .next = { &device_attr_list },
 82 };
 83 
 84 static struct blob_buf b;
 85 static struct device *bridge_create(const char *name, struct device_type *devtype,
 86         struct blob_attr *attr);
 87 static void bridge_config_init(struct device *dev);
 88 static void bridge_dev_vlan_update(struct device *dev);
 89 static void bridge_free(struct device *dev);
 90 static void bridge_stp_init(struct device *dev);
 91 static void bridge_dump_info(struct device *dev, struct blob_buf *b);
 92 static enum dev_change_type
 93 bridge_reload(struct device *dev, struct blob_attr *attr);
 94 
 95 static struct device_type bridge_device_type = {
 96         .name = "bridge",
 97         .config_params = &bridge_attr_list,
 98 
 99         .bridge_capability = true,
100         .name_prefix = "br",
101 
102         .create = bridge_create,
103         .config_init = bridge_config_init,
104         .vlan_update = bridge_dev_vlan_update,
105         .reload = bridge_reload,
106         .free = bridge_free,
107         .dump_info = bridge_dump_info,
108         .stp_init = bridge_stp_init,
109 };
110 
111 struct bridge_state {
112         struct device dev;
113         device_state_cb set_state;
114 
115         struct blob_attr *config_data;
116         struct bridge_config config;
117         struct blob_attr *ports;
118         bool active;
119         bool force_active;
120         bool has_vlans;
121 
122         struct uloop_timeout retry;
123         struct bridge_member *primary_port;
124         struct vlist_tree members;
125         int n_present;
126         int n_failed;
127 };
128 
129 struct bridge_member {
130         struct vlist_node node;
131         struct bridge_state *bst;
132         struct device_user dev;
133         struct uloop_timeout check_timer;
134         struct device_vlan_range *extra_vlan;
135         int n_extra_vlan;
136         uint16_t pvid;
137         bool present;
138         bool active;
139         char name[];
140 };
141 
142 static void
143 bridge_reset_primary(struct bridge_state *bst)
144 {
145         struct bridge_member *bm;
146 
147         if (!bst->primary_port &&
148             (bst->dev.settings.flags & DEV_OPT_MACADDR))
149                 return;
150 
151         bst->primary_port = NULL;
152         bst->dev.settings.flags &= ~DEV_OPT_MACADDR;
153         vlist_for_each_element(&bst->members, bm, node) {
154                 uint8_t *macaddr;
155 
156                 if (!bm->present)
157                         continue;
158 
159                 bst->primary_port = bm;
160                 if (bm->dev.dev->settings.flags & DEV_OPT_MACADDR)
161                         macaddr = bm->dev.dev->settings.macaddr;
162                 else
163                         macaddr = bm->dev.dev->orig_settings.macaddr;
164                 memcpy(bst->dev.settings.macaddr, macaddr, 6);
165                 bst->dev.settings.flags |= DEV_OPT_MACADDR;
166                 return;
167         }
168 }
169 
170 static struct bridge_vlan_port *
171 bridge_find_vlan_member_port(struct bridge_member *bm, struct bridge_vlan *vlan)
172 {
173         struct bridge_vlan_hotplug_port *port;
174         const char *ifname = bm->dev.dev->ifname;
175         int i;
176 
177         for (i = 0; i < vlan->n_ports; i++) {
178                 if (strcmp(vlan->ports[i].ifname, ifname) != 0)
179                         continue;
180 
181                 return &vlan->ports[i];
182         }
183 
184         list_for_each_entry(port, &vlan->hotplug_ports, list) {
185                 if (strcmp(port->port.ifname, ifname) != 0)
186                         continue;
187 
188                 return &port->port;
189         }
190 
191         return NULL;
192 }
193 
194 static bool
195 bridge_member_vlan_is_pvid(struct bridge_member *bm, struct bridge_vlan_port *port)
196 {
197         return (!bm->pvid && (port->flags & BRVLAN_F_UNTAGGED)) ||
198                (port->flags & BRVLAN_F_PVID);
199 }
200 
201 static void
202 __bridge_set_member_vlan(struct bridge_member *bm, struct bridge_vlan *vlan,
203                          struct bridge_vlan_port *port, bool add)
204 {
205         uint16_t flags;
206 
207         flags = port->flags;
208         if (bm->pvid == vlan->vid)
209                 flags |= BRVLAN_F_PVID;
210 
211         system_bridge_vlan(port->ifname, vlan->vid, -1, add, flags);
212 }
213 
214 static void
215 bridge_set_member_vlan(struct bridge_member *bm, struct bridge_vlan *vlan, bool add)
216 {
217         struct bridge_vlan_port *port;
218 
219         if (!bm->present)
220                 return;
221 
222         port = bridge_find_vlan_member_port(bm, vlan);
223         if (!port)
224                 return;
225 
226         if (!add && bm->pvid == vlan->vid)
227                 bm->pvid = 0;
228         else if (add && bridge_member_vlan_is_pvid(bm, port))
229                 bm->pvid = vlan->vid;
230 
231         __bridge_set_member_vlan(bm, vlan, port, add);
232 }
233 
234 static void
235 bridge_set_local_vlan(struct bridge_state *bst, struct bridge_vlan *vlan, bool add)
236 {
237         if (!vlan->local && add)
238                 return;
239 
240         system_bridge_vlan(bst->dev.ifname, vlan->vid, -1, add, BRVLAN_F_SELF);
241 }
242 
243 static void
244 bridge_set_local_vlans(struct bridge_state *bst, bool add)
245 {
246         struct bridge_vlan *vlan;
247 
248         vlist_for_each_element(&bst->dev.vlans, vlan, node)
249                 bridge_set_local_vlan(bst, vlan, add);
250 }
251 
252 static struct bridge_vlan *
253 bridge_recalc_member_pvid(struct bridge_member *bm)
254 {
255         struct bridge_state *bst = bm->bst;
256         struct bridge_vlan_port *port;
257         struct bridge_vlan *vlan, *ret = NULL;
258 
259         vlist_for_each_element(&bst->dev.vlans, vlan, node) {
260                 port = bridge_find_vlan_member_port(bm, vlan);
261                 if (!port)
262                         continue;
263 
264                 if (!bridge_member_vlan_is_pvid(bm, port))
265                         continue;
266 
267                 ret = vlan;
268                 if (port->flags & BRVLAN_F_PVID)
269                         break;
270         }
271 
272         return ret;
273 }
274 
275 static void
276 bridge_set_vlan_state(struct bridge_state *bst, struct bridge_vlan *vlan, bool add)
277 {
278         struct bridge_member *bm;
279         struct bridge_vlan *vlan2;
280         bool clear_pvid = false;
281 
282         bridge_set_local_vlan(bst, vlan, add);
283 
284         vlist_for_each_element(&bst->members, bm, node) {
285                 struct bridge_vlan_port *port;
286 
287                 port = bridge_find_vlan_member_port(bm, vlan);
288                 if (!port)
289                         continue;
290 
291                 if (add) {
292                         if (bridge_member_vlan_is_pvid(bm, port))
293                                 bm->pvid = vlan->vid;
294                 } else if (bm->pvid == vlan->vid) {
295                         vlan2 = bridge_recalc_member_pvid(bm);
296                         if (vlan2 && vlan2->vid != vlan->vid) {
297                                 bridge_set_member_vlan(bm, vlan2, false);
298                                 bm->pvid = vlan2->vid;
299                                 bridge_set_member_vlan(bm, vlan2, true);
300                         } else if (!vlan2) {
301                                 clear_pvid = true;
302                         }
303                 }
304 
305                 if (bm->present)
306                         __bridge_set_member_vlan(bm, vlan, port, add);
307 
308                 if (clear_pvid)
309                         bm->pvid = 0;
310         }
311 }
312 
313 static int
314 bridge_disable_member(struct bridge_member *bm, bool keep_dev)
315 {
316         struct bridge_state *bst = bm->bst;
317         struct bridge_vlan *vlan;
318 
319         if (!bm->present || !bm->active)
320                 return 0;
321 
322         bm->active = false;
323         vlist_for_each_element(&bst->dev.vlans, vlan, node)
324                 bridge_set_member_vlan(bm, vlan, false);
325 
326         system_bridge_delif(&bst->dev, bm->dev.dev);
327         if (!keep_dev)
328                 device_release(&bm->dev);
329 
330         if (bm->dev.dev->settings.flags & DEV_OPT_IPV6) {
331                 bm->dev.dev->settings.ipv6 = 1;
332                 bm->dev.dev->settings.flags &= ~DEV_OPT_IPV6;
333         }
334 
335         device_broadcast_event(&bst->dev, DEV_EVENT_TOPO_CHANGE);
336 
337         return 0;
338 }
339 
340 static void bridge_stp_notify(struct bridge_state *bst)
341 {
342         struct bridge_config *cfg = &bst->config;
343 
344         if (!cfg->stp || cfg->stp_kernel)
345                 return;
346 
347         blob_buf_init(&b, 0);
348         blobmsg_add_string(&b, "name", bst->dev.ifname);
349         if (cfg->stp_proto)
350                 blobmsg_add_string(&b, "proto", cfg->stp_proto);
351         blobmsg_add_u32(&b, "forward_delay", cfg->forward_delay);
352         blobmsg_add_u32(&b, "hello_time", cfg->hello_time);
353         blobmsg_add_u32(&b, "max_age", cfg->max_age);
354         if (cfg->flags & BRIDGE_OPT_AGEING_TIME)
355                 blobmsg_add_u32(&b, "ageing_time", cfg->ageing_time);
356         netifd_ubus_device_notify("stp_init", b.head, 1000);
357 }
358 
359 static int
360 bridge_enable_interface(struct bridge_state *bst)
361 {
362         struct device *dev = &bst->dev;
363         int i, ret;
364 
365         if (bst->active)
366                 return 0;
367 
368         bridge_stp_notify(bst);
369         ret = system_bridge_addbr(dev, &bst->config);
370         if (ret < 0)
371                 return ret;
372 
373         if (bst->has_vlans) {
374                 /* delete default VLAN 1 */
375                 system_bridge_vlan(bst->dev.ifname, 1, -1, false, BRVLAN_F_SELF);
376 
377                 bridge_set_local_vlans(bst, true);
378         }
379 
380         for (i = 0; i < dev->n_extra_vlan; i++)
381                 system_bridge_vlan(dev->ifname, dev->extra_vlan[i].start,
382                                    dev->extra_vlan[i].end, true, BRVLAN_F_SELF);
383 
384         bst->active = true;
385         return 0;
386 }
387 
388 static void
389 bridge_stp_init(struct device *dev)
390 {
391         struct bridge_state *bst;
392 
393         bst = container_of(dev, struct bridge_state, dev);
394         if (!bst->config.stp || !bst->active)
395                 return;
396 
397         bridge_stp_notify(bst);
398         system_bridge_set_stp_state(&bst->dev, false);
399         system_bridge_set_stp_state(&bst->dev, true);
400 }
401 
402 static void
403 bridge_disable_interface(struct bridge_state *bst)
404 {
405         if (!bst->active)
406                 return;
407 
408         system_bridge_delbr(&bst->dev);
409         bst->active = false;
410 }
411 
412 static struct bridge_vlan *
413 bridge_hotplug_get_vlan(struct bridge_state *bst, uint16_t vid, bool create)
414 {
415         struct bridge_vlan *vlan;
416 
417         vlan = vlist_find(&bst->dev.vlans, &vid, vlan, node);
418         if (vlan || !create)
419                 return vlan;
420 
421         vlan = calloc(1, sizeof(*vlan));
422         vlan->vid = vid;
423         vlan->local = true;
424         INIT_LIST_HEAD(&vlan->hotplug_ports);
425         vlist_add(&bst->dev.vlans, &vlan->node, &vlan->vid);
426         vlan->node.version = -1;
427 
428         return vlan;
429 }
430 
431 static struct bridge_vlan_hotplug_port *
432 bridge_hotplug_get_vlan_port(struct bridge_vlan *vlan, const char *ifname)
433 {
434         struct bridge_vlan_hotplug_port *port;
435 
436         list_for_each_entry(port, &vlan->hotplug_ports, list)
437                 if (!strcmp(port->port.ifname, ifname))
438                         return port;
439 
440         return NULL;
441 }
442 
443 static void
444 bridge_hotplug_set_member_vlans(struct bridge_state *bst, struct blob_attr *vlans,
445                                 struct bridge_member *bm, bool add, bool untracked)
446 {
447         const char *ifname = bm->name;
448         struct device_vlan_range *r;
449         struct bridge_vlan *vlan;
450         struct blob_attr *cur;
451         int n_vlans;
452         size_t rem;
453 
454         if (!vlans)
455                 return;
456 
457         if (add) {
458                 bm->n_extra_vlan = 0;
459                 n_vlans = blobmsg_check_array(vlans, BLOBMSG_TYPE_STRING);
460                 if (n_vlans < 1)
461                         return;
462 
463                 bm->extra_vlan = realloc(bm->extra_vlan, n_vlans * sizeof(*bm->extra_vlan));
464         }
465 
466         blobmsg_for_each_attr(cur, vlans, rem) {
467                 struct bridge_vlan_hotplug_port *port;
468                 unsigned int vid, vid_end;
469                 uint16_t flags = 0;
470                 char *name_buf;
471                 char *end;
472 
473                 if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING)
474                         continue;
475 
476                 vid = strtoul(blobmsg_get_string(cur), &end, 0);
477                 vid_end = vid;
478                 if (!vid || vid > 4095)
479                         continue;
480 
481                 if (*end == '-') {
482                         vid_end = strtoul(end + 1, &end, 0);
483                         if (vid_end < vid)
484                                 continue;
485                 }
486 
487                 if (end && *end) {
488                         if (*end != ':')
489                                 continue;
490 
491                         for (end++; *end; end++) {
492                                 switch (*end) {
493                                 case 'u':
494                                         flags |= BRVLAN_F_UNTAGGED;
495                                         fallthrough;
496                                 case '*':
497                                         flags |= BRVLAN_F_PVID;
498                                         break;
499                                 }
500                         }
501                 }
502 
503                 vlan = bridge_hotplug_get_vlan(bst, vid, !!flags);
504                 if (!vlan || vid_end > vid || untracked) {
505                         if (add) {
506                                 if (!untracked) {
507                                         r = &bm->extra_vlan[bm->n_extra_vlan++];
508                                         r->start = vid;
509                                         r->end = vid_end;
510                                 }
511                                 if (bm->active)
512                                         system_bridge_vlan(ifname, vid, vid_end, true, flags);
513                         } else if (bm->active) {
514                                 system_bridge_vlan(ifname, vid, vid_end, false, 0);
515                         }
516                         continue;
517                 }
518 
519                 if (vlan->pending) {
520                         vlan->pending = false;
521                         bridge_set_vlan_state(bst, vlan, true);
522                 }
523 
524                 port = bridge_hotplug_get_vlan_port(vlan, ifname);
525                 if (!add) {
526                         if (!port)
527                                 continue;
528 
529                         __bridge_set_member_vlan(bm, vlan, &port->port, false);
530                         list_del(&port->list);
531                         free(port);
532                         continue;
533                 }
534 
535                 if (port) {
536                         if (port->port.flags == flags)
537                                 continue;
538 
539                         __bridge_set_member_vlan(bm, vlan, &port->port, false);
540                         port->port.flags = flags;
541                         __bridge_set_member_vlan(bm, vlan, &port->port, true);
542                         continue;
543                 }
544 
545                 port = calloc_a(sizeof(*port), &name_buf, strlen(ifname) + 1);
546                 if (!port)
547                         continue;
548 
549                 port->port.flags = flags;
550                 port->port.ifname = strcpy(name_buf, ifname);
551                 list_add_tail(&port->list, &vlan->hotplug_ports);
552 
553                 if (!bm)
554                         continue;
555 
556                 __bridge_set_member_vlan(bm, vlan, &port->port, true);
557         }
558 }
559 
560 
561 static void
562 bridge_member_add_extra_vlans(struct bridge_member *bm)
563 {
564         struct device *dev = bm->dev.dev;
565         int i;
566 
567         for (i = 0; i < dev->n_extra_vlan; i++)
568                 system_bridge_vlan(dev->ifname, dev->extra_vlan[i].start,
569                                    dev->extra_vlan[i].end, true, 0);
570         for (i = 0; i < bm->n_extra_vlan; i++)
571                 system_bridge_vlan(dev->ifname, bm->extra_vlan[i].start,
572                                    bm->extra_vlan[i].end, true, 0);
573 }
574 
575 static void
576 bridge_member_enable_vlans(struct bridge_member *bm)
577 {
578         struct bridge_state *bst = bm->bst;
579         struct device *dev = bm->dev.dev;
580         struct bridge_vlan *vlan;
581 
582         if (dev->settings.auth) {
583                 bridge_hotplug_set_member_vlans(bst, dev->config_auth_vlans, bm,
584                                                 !dev->auth_status, true);
585                 bridge_hotplug_set_member_vlans(bst, dev->auth_vlans, bm,
586                                                 dev->auth_status, true);
587         }
588 
589         if (dev->settings.auth && !dev->auth_status)
590                 return;
591 
592         bridge_member_add_extra_vlans(bm);
593         vlist_for_each_element(&bst->dev.vlans, vlan, node)
594                 bridge_set_member_vlan(bm, vlan, true);
595 }
596 
597 static int
598 bridge_enable_member(struct bridge_member *bm)
599 {
600         struct bridge_state *bst = bm->bst;
601         struct device *dev;
602         int ret;
603 
604         if (!bm->present)
605                 return 0;
606 
607         ret = bridge_enable_interface(bst);
608         if (ret)
609                 goto error;
610 
611         /* Disable IPv6 for bridge members */
612         if (!(bm->dev.dev->settings.flags & DEV_OPT_IPV6)) {
613                 bm->dev.dev->settings.ipv6 = 0;
614                 bm->dev.dev->settings.flags |= DEV_OPT_IPV6;
615         }
616 
617         ret = device_claim(&bm->dev);
618         if (ret < 0)
619                 goto error;
620 
621         dev = bm->dev.dev;
622         if (dev->settings.auth && !bst->has_vlans && !dev->auth_status)
623                 return -1;
624 
625         if (!bm->active) {
626                 ret = system_bridge_addif(&bst->dev, bm->dev.dev);
627                 if (ret < 0) {
628                         D(DEVICE, "Bridge device %s could not be added", bm->dev.dev->ifname);
629                         goto error;
630                 }
631 
632                 bm->active = true;
633         }
634 
635         if (bst->has_vlans) {
636                 /* delete default VLAN 1 */
637                 system_bridge_vlan(bm->dev.dev->ifname, 1, -1, false, 0);
638 
639                 bridge_member_enable_vlans(bm);
640         }
641 
642         device_set_present(&bst->dev, true);
643         if (!dev->settings.auth || dev->auth_status)
644                 device_broadcast_event(&bst->dev, DEV_EVENT_TOPO_CHANGE);
645 
646         return 0;
647 
648 error:
649         bst->n_failed++;
650         bm->present = false;
651         bst->n_present--;
652         device_release(&bm->dev);
653 
654         return ret;
655 }
656 
657 static void
658 bridge_remove_member(struct bridge_member *bm)
659 {
660         struct bridge_state *bst = bm->bst;
661 
662         if (!bm->present)
663                 return;
664 
665         if (bst->dev.active)
666                 bridge_disable_member(bm, false);
667 
668         bm->present = false;
669         bm->bst->n_present--;
670 
671         if (bm == bst->primary_port)
672                 bridge_reset_primary(bst);
673 
674         if (bst->config.bridge_empty)
675                 return;
676 
677         bst->force_active = false;
678         if (bst->n_present == 0)
679                 device_set_present(&bst->dev, false);
680 }
681 
682 static void
683 bridge_free_member(struct bridge_member *bm)
684 {
685         struct bridge_state *bst = bm->bst;
686         struct device *dev = bm->dev.dev;
687         const char *ifname = dev->ifname;
688         struct bridge_vlan *vlan;
689 
690         bridge_remove_member(bm);
691 
692 restart:
693         vlist_for_each_element(&bst->dev.vlans, vlan, node) {
694                 struct bridge_vlan_hotplug_port *port, *tmp;
695                 bool free_port = false;
696 
697                 list_for_each_entry_safe(port, tmp, &vlan->hotplug_ports, list) {
698                         if (strcmp(port->port.ifname, ifname) != 0)
699                                 continue;
700 
701                         list_del(&port->list);
702                         free(port);
703                         free_port = true;
704                 }
705 
706                 if (!free_port || !list_empty(&vlan->hotplug_ports) ||
707                     vlan->n_ports || vlan->node.version != -1)
708                         continue;
709 
710                 vlist_delete(&bst->dev.vlans, &vlan->node);
711                 goto restart;
712         }
713 
714         device_remove_user(&bm->dev);
715         uloop_timeout_cancel(&bm->check_timer);
716 
717         /*
718          * When reloading the config and moving a device from one bridge to
719          * another, the other bridge may have tried to claim this device
720          * before it was removed here.
721          * Ensure that claiming the device is retried by toggling its present
722          * state
723          */
724         if (dev->present) {
725                 device_set_present(dev, false);
726                 device_set_present(dev, true);
727         }
728 
729         free(bm);
730 }
731 
732 static void
733 bridge_check_retry(struct bridge_state *bst)
734 {
735         if (!bst->n_failed)
736                 return;
737 
738         uloop_timeout_set(&bst->retry, 100);
739 }
740 
741 static void
742 bridge_member_check_cb(struct uloop_timeout *t)
743 {
744         struct bridge_member *bm;
745         struct bridge_state *bst;
746 
747         bm = container_of(t, struct bridge_member, check_timer);
748         bst = bm->bst;
749 
750         if (system_bridge_vlan_check(&bst->dev, bm->dev.dev->ifname) <= 0)
751                 return;
752 
753         bridge_disable_member(bm, true);
754         bridge_enable_member(bm);
755 }
756 
757 static void
758 bridge_member_cb(struct device_user *dep, enum device_event ev)
759 {
760         struct bridge_member *bm = container_of(dep, struct bridge_member, dev);
761         struct bridge_state *bst = bm->bst;
762         struct device *dev = dep->dev;
763 
764         switch (ev) {
765         case DEV_EVENT_ADD:
766                 assert(!bm->present);
767 
768                 bm->present = true;
769                 bst->n_present++;
770 
771                 if (bst->n_present == 1)
772                         device_set_present(&bst->dev, true);
773                 fallthrough;
774         case DEV_EVENT_AUTH_UP:
775                 if (!bst->dev.active)
776                         break;
777 
778                 if (bridge_enable_member(bm))
779                         break;
780 
781                 /*
782                  * Adding a bridge member can overwrite the bridge mtu
783                  * in the kernel, apply the bridge settings in case the
784                  * bridge mtu is set
785                  */
786                 system_if_apply_settings(&bst->dev, &bst->dev.settings,
787                                          DEV_OPT_MTU | DEV_OPT_MTU6);
788                 break;
789         case DEV_EVENT_LINK_UP:
790                 if (!bst->has_vlans)
791                         break;
792 
793                 if (dev->settings.auth)
794                         bridge_enable_member(bm);
795 
796                 uloop_timeout_set(&bm->check_timer, 1000);
797                 break;
798         case DEV_EVENT_LINK_DOWN:
799                 if (!dev->settings.auth)
800                         break;
801 
802                 bridge_disable_member(bm, true);
803                 break;
804         case DEV_EVENT_REMOVE:
805                 if (dep->hotplug && !dev->sys_present) {
806                         vlist_delete(&bst->members, &bm->node);
807                         return;
808                 }
809 
810                 if (bm->present)
811                         bridge_remove_member(bm);
812 
813                 break;
814         default:
815                 return;
816         }
817 }
818 
819 static int
820 bridge_set_down(struct bridge_state *bst)
821 {
822         struct bridge_member *bm;
823 
824         bst->set_state(&bst->dev, false);
825 
826         vlist_for_each_element(&bst->members, bm, node)
827                 bridge_disable_member(bm, false);
828 
829         bridge_disable_interface(bst);
830 
831         return 0;
832 }
833 
834 static int
835 bridge_set_up(struct bridge_state *bst)
836 {
837         struct bridge_member *bm;
838         int ret;
839 
840         bst->has_vlans = !avl_is_empty(&bst->dev.vlans.avl);
841         if (!bst->n_present) {
842                 if (!bst->force_active)
843                         return -ENOENT;
844 
845                 ret = bridge_enable_interface(bst);
846                 if (ret)
847                         return ret;
848         }
849 
850         bst->n_failed = 0;
851         vlist_for_each_element(&bst->members, bm, node)
852                 bridge_enable_member(bm);
853         bridge_check_retry(bst);
854 
855         if (!bst->force_active && !bst->n_present) {
856                 /* initialization of all member interfaces failed */
857                 bridge_disable_interface(bst);
858                 device_set_present(&bst->dev, false);
859                 return -ENOENT;
860         }
861 
862         bridge_reset_primary(bst);
863         ret = bst->set_state(&bst->dev, true);
864         if (ret < 0)
865                 bridge_set_down(bst);
866 
867         return ret;
868 }
869 
870 static int
871 bridge_set_state(struct device *dev, bool up)
872 {
873         struct bridge_state *bst;
874 
875         bst = container_of(dev, struct bridge_state, dev);
876 
877         if (up)
878                 return bridge_set_up(bst);
879         else
880                 return bridge_set_down(bst);
881 }
882 
883 static struct bridge_member *
884 bridge_alloc_member(struct bridge_state *bst, const char *name,
885                     struct device *dev, bool hotplug)
886 {
887         struct bridge_member *bm;
888 
889         bm = calloc(1, sizeof(*bm) + strlen(name) + 1);
890         if (!bm)
891                 return NULL;
892 
893         bm->bst = bst;
894         bm->dev.cb = bridge_member_cb;
895         bm->dev.hotplug = hotplug;
896         bm->check_timer.cb = bridge_member_check_cb;
897         strcpy(bm->name, name);
898         bm->dev.dev = dev;
899 
900         return bm;
901 }
902 
903 static void bridge_insert_member(struct bridge_member *bm, const char *name)
904 {
905         struct bridge_state *bst = bm->bst;
906         bool hotplug = bm->dev.hotplug;
907 
908         vlist_add(&bst->members, &bm->node, bm->name);
909         /*
910          * Need to look up the bridge member again as the above
911          * created pointer will be freed in case the bridge member
912          * already existed
913          */
914         bm = vlist_find(&bst->members, name, bm, node);
915         if (hotplug && bm)
916                 bm->node.version = -1;
917 }
918 
919 static void
920 bridge_create_member(struct bridge_state *bst, const char *name,
921                      struct device *dev, bool hotplug)
922 {
923         struct bridge_member *bm;
924 
925         bm = bridge_alloc_member(bst, name, dev, hotplug);
926         if (bm)
927                 bridge_insert_member(bm, name);
928 }
929 
930 static void
931 bridge_member_update(struct vlist_tree *tree, struct vlist_node *node_new,
932                      struct vlist_node *node_old)
933 {
934         struct bridge_member *bm;
935         struct device *dev;
936 
937         if (node_new) {
938                 bm = container_of(node_new, struct bridge_member, node);
939 
940                 if (node_old) {
941                         free(bm);
942                         return;
943                 }
944 
945                 dev = bm->dev.dev;
946                 bm->dev.dev = NULL;
947                 device_add_user(&bm->dev, dev);
948         }
949 
950 
951         if (node_old) {
952                 bm = container_of(node_old, struct bridge_member, node);
953                 bridge_free_member(bm);
954         }
955 }
956 
957 
958 static void
959 bridge_add_member(struct bridge_state *bst, const char *name)
960 {
961         struct device *dev;
962 
963         dev = device_get(name, true);
964         if (!dev)
965                 return;
966 
967         bridge_create_member(bst, name, dev, false);
968 }
969 
970 static int
971 bridge_hotplug_add(struct device *dev, struct device *member, struct blob_attr *vlan)
972 {
973         struct bridge_state *bst = container_of(dev, struct bridge_state, dev);
974         struct bridge_member *bm;
975         bool new_entry = false;
976 
977         bm = vlist_find(&bst->members, member->ifname, bm, node);
978         if (!bm) {
979             new_entry = true;
980             bm = bridge_alloc_member(bst, member->ifname, member, true);
981         }
982         bridge_hotplug_set_member_vlans(bst, vlan, bm, true, false);
983         if (new_entry)
984                 bridge_insert_member(bm, member->ifname);
985 
986         return 0;
987 }
988 
989 static int
990 bridge_hotplug_del(struct device *dev, struct device *member, struct blob_attr *vlan)
991 {
992         struct bridge_state *bst = container_of(dev, struct bridge_state, dev);
993         struct bridge_member *bm;
994 
995         bm = vlist_find(&bst->members, member->ifname, bm, node);
996         if (!bm)
997                 return UBUS_STATUS_NOT_FOUND;
998 
999         bridge_hotplug_set_member_vlans(bst, vlan, bm, false, false);
1000         if (!bm->dev.hotplug)
1001                 return 0;
1002 
1003         vlist_delete(&bst->members, &bm->node);
1004         return 0;
1005 }
1006 
1007 static int
1008 bridge_hotplug_prepare(struct device *dev, struct device **bridge_dev)
1009 {
1010         struct bridge_state *bst;
1011 
1012         if (bridge_dev)
1013                 *bridge_dev = dev;
1014 
1015         bst = container_of(dev, struct bridge_state, dev);
1016         bst->force_active = true;
1017         device_set_present(&bst->dev, true);
1018 
1019         return 0;
1020 }
1021 
1022 static const struct device_hotplug_ops bridge_ops = {
1023         .prepare = bridge_hotplug_prepare,
1024         .add = bridge_hotplug_add,
1025         .del = bridge_hotplug_del
1026 };
1027 
1028 static void
1029 bridge_free(struct device *dev)
1030 {
1031         struct bridge_state *bst;
1032 
1033         bst = container_of(dev, struct bridge_state, dev);
1034         vlist_flush_all(&bst->members);
1035         vlist_flush_all(&dev->vlans);
1036         kvlist_free(&dev->vlan_aliases);
1037         free(bst->config_data);
1038         free(bst);
1039 }
1040 
1041 static void
1042 bridge_dump_port(struct blob_buf *b, struct bridge_vlan_port *port)
1043 {
1044         bool tagged = !(port->flags & BRVLAN_F_UNTAGGED);
1045         bool pvid = (port->flags & BRVLAN_F_PVID);
1046 
1047         blobmsg_printf(b, NULL, "%s%s%s%s", port->ifname,
1048                 tagged || pvid ? ":" : "",
1049                 tagged ? "t" : "",
1050                 pvid ? "*" : "");
1051 }
1052 
1053 static void
1054 bridge_dump_vlan(struct blob_buf *b, struct bridge_vlan *vlan)
1055 {
1056         struct bridge_vlan_hotplug_port *port;
1057         void *c, *p;
1058         int i;
1059 
1060         c = blobmsg_open_table(b, NULL);
1061 
1062         blobmsg_add_u32(b, "id", vlan->vid);
1063         blobmsg_add_u8(b, "local", vlan->local);
1064 
1065         p = blobmsg_open_array(b, "ports");
1066 
1067         for (i = 0; i < vlan->n_ports; i++)
1068             bridge_dump_port(b, &vlan->ports[i]);
1069 
1070         list_for_each_entry(port, &vlan->hotplug_ports, list)
1071                 bridge_dump_port(b, &port->port);
1072 
1073         blobmsg_close_array(b, p);
1074 
1075         blobmsg_close_table(b, c);
1076 }
1077 
1078 static void
1079 bridge_dump_info(struct device *dev, struct blob_buf *b)
1080 {
1081         struct bridge_config *cfg;
1082         struct bridge_state *bst;
1083         struct bridge_member *bm;
1084         struct bridge_vlan *vlan;
1085         void *list;
1086         void *c;
1087 
1088         bst = container_of(dev, struct bridge_state, dev);
1089         cfg = &bst->config;
1090 
1091         system_if_dump_info(dev, b);
1092         list = blobmsg_open_array(b, "bridge-members");
1093 
1094         vlist_for_each_element(&bst->members, bm, node) {
1095                 if (bm->dev.dev->hidden)
1096                         continue;
1097 
1098                 blobmsg_add_string(b, NULL, bm->dev.dev->ifname);
1099         }
1100 
1101         blobmsg_close_array(b, list);
1102 
1103         c = blobmsg_open_table(b, "bridge-attributes");
1104 
1105         blobmsg_add_u8(b, "stp", cfg->stp);
1106         blobmsg_add_u32(b, "forward_delay", cfg->forward_delay);
1107         blobmsg_add_u32(b, "priority", cfg->priority);
1108         blobmsg_add_u32(b, "ageing_time", cfg->ageing_time);
1109         blobmsg_add_u32(b, "hello_time", cfg->hello_time);
1110         blobmsg_add_u32(b, "max_age", cfg->max_age);
1111         blobmsg_add_u8(b, "igmp_snooping", cfg->igmp_snoop);
1112         blobmsg_add_u8(b, "bridge_empty", cfg->bridge_empty);
1113         blobmsg_add_u8(b, "multicast_querier", cfg->multicast_querier);
1114         blobmsg_add_u32(b, "hash_max", cfg->hash_max);
1115         blobmsg_add_u32(b, "robustness", cfg->robustness);
1116         blobmsg_add_u32(b, "query_interval", cfg->query_interval);
1117         blobmsg_add_u32(b, "query_response_interval", cfg->query_response_interval);
1118         blobmsg_add_u32(b, "last_member_interval", cfg->last_member_interval);
1119         blobmsg_add_u8(b, "vlan_filtering", cfg->vlan_filtering);
1120         blobmsg_add_u8(b, "stp_kernel", cfg->stp_kernel);
1121         if (cfg->stp_proto)
1122                 blobmsg_add_string(b, "stp_proto", cfg->stp_proto);
1123 
1124         blobmsg_close_table(b, c);
1125 
1126         if (avl_is_empty(&dev->vlans.avl))
1127                 return;
1128 
1129         list = blobmsg_open_array(b, "bridge-vlans");
1130 
1131         vlist_for_each_element(&bst->dev.vlans, vlan, node)
1132                 bridge_dump_vlan(b, vlan);
1133 
1134         blobmsg_close_array(b, list);
1135 }
1136 
1137 static void
1138 bridge_config_init(struct device *dev)
1139 {
1140         struct bridge_state *bst;
1141         struct bridge_vlan *vlan;
1142         struct blob_attr *cur;
1143         size_t rem;
1144         int i;
1145 
1146         bst = container_of(dev, struct bridge_state, dev);
1147 
1148         if (bst->config.bridge_empty) {
1149                 bst->force_active = true;
1150                 device_set_present(&bst->dev, true);
1151         }
1152 
1153         bst->n_failed = 0;
1154         vlist_update(&bst->members);
1155         if (bst->ports) {
1156                 blobmsg_for_each_attr(cur, bst->ports, rem) {
1157                         bridge_add_member(bst, blobmsg_data(cur));
1158                 }
1159         }
1160 
1161         vlist_for_each_element(&bst->dev.vlans, vlan, node)
1162                 for (i = 0; i < vlan->n_ports; i++)
1163                         bridge_add_member(bst, vlan->ports[i].ifname);
1164 
1165         vlist_flush(&bst->members);
1166         bridge_check_retry(bst);
1167 }
1168 
1169 static void
1170 bridge_apply_settings(struct bridge_state *bst, struct blob_attr **tb)
1171 {
1172         struct bridge_config *cfg = &bst->config;
1173         struct blob_attr *cur;
1174 
1175         /* defaults */
1176         memset(cfg, 0, sizeof(*cfg));
1177         cfg->stp = false;
1178         cfg->stp_kernel = false;
1179         cfg->robustness = 2;
1180         cfg->igmp_snoop = false;
1181         cfg->multicast_querier = false;
1182         cfg->query_interval = 12500;
1183         cfg->query_response_interval = 1000;
1184         cfg->last_member_interval = 100;
1185         cfg->hash_max = 512;
1186         cfg->bridge_empty = false;
1187         cfg->priority = 0x7FFF;
1188         cfg->vlan_filtering = false;
1189 
1190         cfg->forward_delay = 8;
1191         cfg->max_age = 10;
1192         cfg->hello_time = 1;
1193 
1194         if ((cur = tb[BRIDGE_ATTR_STP]))
1195                 cfg->stp = blobmsg_get_bool(cur);
1196 
1197         if ((cur = tb[BRIDGE_ATTR_STP_KERNEL]))
1198                 cfg->stp = blobmsg_get_bool(cur);
1199 
1200         if ((cur = tb[BRIDGE_ATTR_STP_PROTO]))
1201                 cfg->stp_proto = blobmsg_get_string(cur);
1202 
1203         if ((cur = tb[BRIDGE_ATTR_FORWARD_DELAY]))
1204                 cfg->forward_delay = blobmsg_get_u32(cur);
1205 
1206         if ((cur = tb[BRIDGE_ATTR_PRIORITY]))
1207                 cfg->priority = blobmsg_get_u32(cur);
1208 
1209         if ((cur = tb[BRIDGE_ATTR_IGMP_SNOOP]))
1210                 cfg->multicast_querier = cfg->igmp_snoop = blobmsg_get_bool(cur);
1211 
1212         if ((cur = tb[BRIDGE_ATTR_MULTICAST_QUERIER]))
1213                 cfg->multicast_querier = blobmsg_get_bool(cur);
1214 
1215         if ((cur = tb[BRIDGE_ATTR_HASH_MAX]))
1216                 cfg->hash_max = blobmsg_get_u32(cur);
1217 
1218         if ((cur = tb[BRIDGE_ATTR_ROBUSTNESS])) {
1219                 cfg->robustness = blobmsg_get_u32(cur);
1220                 cfg->flags |= BRIDGE_OPT_ROBUSTNESS;
1221         }
1222 
1223         if ((cur = tb[BRIDGE_ATTR_QUERY_INTERVAL])) {
1224                 cfg->query_interval = blobmsg_get_u32(cur);
1225                 cfg->flags |= BRIDGE_OPT_QUERY_INTERVAL;
1226         }
1227 
1228         if ((cur = tb[BRIDGE_ATTR_QUERY_RESPONSE_INTERVAL])) {
1229                 cfg->query_response_interval = blobmsg_get_u32(cur);
1230                 cfg->flags |= BRIDGE_OPT_QUERY_RESPONSE_INTERVAL;
1231         }
1232 
1233         if ((cur = tb[BRIDGE_ATTR_LAST_MEMBER_INTERVAL])) {
1234                 cfg->last_member_interval = blobmsg_get_u32(cur);
1235                 cfg->flags |= BRIDGE_OPT_LAST_MEMBER_INTERVAL;
1236         }
1237 
1238         if ((cur = tb[BRIDGE_ATTR_AGEING_TIME])) {
1239                 cfg->ageing_time = blobmsg_get_u32(cur);
1240                 cfg->flags |= BRIDGE_OPT_AGEING_TIME;
1241         }
1242 
1243         if ((cur = tb[BRIDGE_ATTR_HELLO_TIME]))
1244                 cfg->hello_time = blobmsg_get_u32(cur);
1245 
1246         if ((cur = tb[BRIDGE_ATTR_MAX_AGE]))
1247                 cfg->max_age = blobmsg_get_u32(cur);
1248 
1249         if ((cur = tb[BRIDGE_ATTR_BRIDGE_EMPTY]))
1250                 cfg->bridge_empty = blobmsg_get_bool(cur);
1251 
1252         if ((cur = tb[BRIDGE_ATTR_VLAN_FILTERING]))
1253                 cfg->vlan_filtering = blobmsg_get_bool(cur);
1254 }
1255 
1256 static enum dev_change_type
1257 bridge_reload(struct device *dev, struct blob_attr *attr)
1258 {
1259         struct blob_attr *tb_dev[__DEV_ATTR_MAX];
1260         struct blob_attr *tb_br[__BRIDGE_ATTR_MAX];
1261         enum dev_change_type ret = DEV_CONFIG_APPLIED;
1262         struct bridge_state *bst;
1263         unsigned long diff[2] = {};
1264 
1265         BUILD_BUG_ON(sizeof(diff) < __BRIDGE_ATTR_MAX / BITS_PER_LONG);
1266         BUILD_BUG_ON(sizeof(diff) < __DEV_ATTR_MAX / BITS_PER_LONG);
1267 
1268         bst = container_of(dev, struct bridge_state, dev);
1269         attr = blob_memdup(attr);
1270 
1271         blobmsg_parse(device_attr_list.params, __DEV_ATTR_MAX, tb_dev,
1272                 blob_data(attr), blob_len(attr));
1273         blobmsg_parse(bridge_attrs, __BRIDGE_ATTR_MAX, tb_br,
1274                 blob_data(attr), blob_len(attr));
1275 
1276         if (tb_dev[DEV_ATTR_MACADDR])
1277                 bst->primary_port = NULL;
1278 
1279         bst->ports = tb_br[BRIDGE_ATTR_PORTS];
1280         device_init_settings(dev, tb_dev);
1281         bridge_apply_settings(bst, tb_br);
1282 
1283         if (bst->config_data) {
1284                 struct blob_attr *otb_dev[__DEV_ATTR_MAX];
1285                 struct blob_attr *otb_br[__BRIDGE_ATTR_MAX];
1286 
1287                 blobmsg_parse(device_attr_list.params, __DEV_ATTR_MAX, otb_dev,
1288                         blob_data(bst->config_data), blob_len(bst->config_data));
1289 
1290                 uci_blob_diff(tb_dev, otb_dev, &device_attr_list, diff);
1291                 if (diff[0] | diff[1]) {
1292                         ret = DEV_CONFIG_RESTART;
1293                         D(DEVICE, "Bridge %s device attributes have changed, diff=[%lx %lx]",
1294                           dev->ifname, diff[1], diff[0]);
1295                 }
1296 
1297                 blobmsg_parse(bridge_attrs, __BRIDGE_ATTR_MAX, otb_br,
1298                         blob_data(bst->config_data), blob_len(bst->config_data));
1299 
1300                 diff[0] = diff[1] = 0;
1301                 uci_blob_diff(tb_br, otb_br, &bridge_attr_list, diff);
1302                 if (diff[0] & ~(1 << BRIDGE_ATTR_PORTS)) {
1303                         ret = DEV_CONFIG_RESTART;
1304                         D(DEVICE, "Bridge %s attributes have changed, diff=[%lx %lx]",
1305                           dev->ifname, diff[1], diff[0]);
1306                 }
1307 
1308                 bridge_config_init(dev);
1309         }
1310 
1311         free(bst->config_data);
1312         bst->config_data = attr;
1313         return ret;
1314 }
1315 
1316 static void
1317 bridge_retry_members(struct uloop_timeout *timeout)
1318 {
1319         struct bridge_state *bst = container_of(timeout, struct bridge_state, retry);
1320         struct bridge_member *bm;
1321 
1322         bst->n_failed = 0;
1323         vlist_for_each_element(&bst->members, bm, node) {
1324                 if (bm->present)
1325                         continue;
1326 
1327                 if (!bm->dev.dev->present)
1328                         continue;
1329 
1330                 bm->present = true;
1331                 bst->n_present++;
1332                 bridge_enable_member(bm);
1333         }
1334 }
1335 
1336 static int bridge_avl_cmp_u16(const void *k1, const void *k2, void *ptr)
1337 {
1338         const uint16_t *i1 = k1, *i2 = k2;
1339 
1340         return *i1 - *i2;
1341 }
1342 
1343 static bool
1344 bridge_vlan_equal(struct bridge_vlan *v1, struct bridge_vlan *v2)
1345 {
1346         int i;
1347 
1348         if (v1->n_ports != v2->n_ports)
1349                 return false;
1350 
1351         for (i = 0; i < v1->n_ports; i++)
1352                 if (v1->ports[i].flags != v2->ports[i].flags ||
1353                     strcmp(v1->ports[i].ifname, v2->ports[i].ifname) != 0)
1354                         return false;
1355 
1356         return true;
1357 }
1358 
1359 static void
1360 bridge_vlan_free(struct bridge_vlan *vlan)
1361 {
1362         struct bridge_vlan_hotplug_port *port, *tmp;
1363 
1364         if (!vlan)
1365                 return;
1366 
1367         list_for_each_entry_safe(port, tmp, &vlan->hotplug_ports, list)
1368                 free(port);
1369 
1370         free(vlan);
1371 }
1372 
1373 static void
1374 bridge_vlan_update(struct vlist_tree *tree, struct vlist_node *node_new,
1375                    struct vlist_node *node_old)
1376 {
1377         struct bridge_state *bst = container_of(tree, struct bridge_state, dev.vlans);
1378         struct bridge_vlan *vlan_new = NULL, *vlan_old = NULL;
1379 
1380         if (node_old)
1381                 vlan_old = container_of(node_old, struct bridge_vlan, node);
1382         if (node_new)
1383                 vlan_new = container_of(node_new, struct bridge_vlan, node);
1384 
1385         if (!bst->has_vlans || !bst->active)
1386                 goto out;
1387 
1388         if (node_new && node_old && bridge_vlan_equal(vlan_old, vlan_new)) {
1389                 list_splice_init(&vlan_old->hotplug_ports, &vlan_new->hotplug_ports);
1390                 goto out;
1391         }
1392 
1393         if (node_old)
1394                 bridge_set_vlan_state(bst, vlan_old, false);
1395 
1396         if (node_old && node_new)
1397                 list_splice_init(&vlan_old->hotplug_ports, &vlan_new->hotplug_ports);
1398 
1399         if (node_new)
1400                 vlan_new->pending = true;
1401 
1402 out:
1403         bst->dev.config_pending = true;
1404         bridge_vlan_free(vlan_old);
1405 }
1406 
1407 static void
1408 bridge_dev_vlan_update(struct device *dev)
1409 {
1410         struct bridge_state *bst = container_of(dev, struct bridge_state, dev);
1411         struct bridge_vlan *vlan;
1412 
1413         vlist_for_each_element(&dev->vlans, vlan, node) {
1414                 if (!vlan->pending)
1415                         continue;
1416 
1417                 vlan->pending = false;
1418                 bridge_set_vlan_state(bst, vlan, true);
1419         }
1420 }
1421 
1422 static struct device *
1423 bridge_create(const char *name, struct device_type *devtype,
1424         struct blob_attr *attr)
1425 {
1426         struct bridge_state *bst;
1427         struct device *dev = NULL;
1428 
1429         bst = calloc(1, sizeof(*bst));
1430         if (!bst)
1431                 return NULL;
1432 
1433         dev = &bst->dev;
1434 
1435         if (device_init(dev, devtype, name) < 0) {
1436                 device_cleanup(dev);
1437                 free(bst);
1438                 return NULL;
1439         }
1440 
1441         dev->config_pending = true;
1442         bst->retry.cb = bridge_retry_members;
1443 
1444         bst->set_state = dev->set_state;
1445         dev->set_state = bridge_set_state;
1446 
1447         dev->hotplug_ops = &bridge_ops;
1448 
1449         vlist_init(&bst->members, avl_strcmp, bridge_member_update);
1450         bst->members.keep_old = true;
1451 
1452         vlist_init(&dev->vlans, bridge_avl_cmp_u16, bridge_vlan_update);
1453 
1454         bridge_reload(dev, attr);
1455 
1456         return dev;
1457 }
1458 
1459 static void __init bridge_device_type_init(void)
1460 {
1461         device_type_add(&bridge_device_type);
1462 }
1463 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt