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

This page was automatically generated by LXR 0.3.1.  •  OpenWrt