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

This page was automatically generated by LXR 0.3.1.  •  OpenWrt