interface-ip: set prefix indicator flag when IPv6 prefix lifetime changes
[project/netifd.git] / bridge.c
index 0c538ba..c46d44e 100644 (file)
--- a/bridge.c
+++ b/bridge.c
@@ -80,10 +80,13 @@ static void bridge_dump_info(struct device *dev, struct blob_buf *b);
 enum dev_change_type
 bridge_reload(struct device *dev, struct blob_attr *attr);
 
-struct device_type bridge_device_type = {
+static struct device_type bridge_device_type = {
        .name = "bridge",
        .config_params = &bridge_attr_list,
 
+       .bridge_capability = true,
+       .name_prefix = "br",
+
        .create = bridge_create,
        .config_init = bridge_config_init,
        .reload = bridge_reload,
@@ -391,24 +394,25 @@ bridge_set_state(struct device *dev, bool up)
 }
 
 static struct bridge_member *
-bridge_create_member(struct bridge_state *bst, struct device *dev, bool hotplug)
+bridge_create_member(struct bridge_state *bst, const char *name,
+                    struct device *dev, bool hotplug)
 {
        struct bridge_member *bm;
 
-       bm = calloc(1, sizeof(*bm) + strlen(dev->ifname) + 1);
+       bm = calloc(1, sizeof(*bm) + strlen(name) + 1);
        if (!bm)
                return NULL;
 
        bm->bst = bst;
        bm->dev.cb = bridge_member_cb;
        bm->dev.hotplug = hotplug;
-       strcpy(bm->name, dev->ifname);
+       strcpy(bm->name, name);
        bm->dev.dev = dev;
        vlist_add(&bst->members, &bm->node, bm->name);
        // Need to look up the bridge member again as the above
        // created pointer will be freed in case the bridge member
        // already existed
-       bm = vlist_find(&bst->members, dev->ifname, bm, node);
+       bm = vlist_find(&bst->members, name, bm, node);
        if (hotplug && bm)
                bm->node.version = -1;
 
@@ -452,7 +456,7 @@ bridge_add_member(struct bridge_state *bst, const char *name)
        if (!dev)
                return;
 
-       bridge_create_member(bst, dev, false);
+       bridge_create_member(bst, name, dev, false);
 }
 
 static int
@@ -460,7 +464,7 @@ bridge_hotplug_add(struct device *dev, struct device *member)
 {
        struct bridge_state *bst = container_of(dev, struct bridge_state, dev);
 
-       bridge_create_member(bst, member, true);
+       bridge_create_member(bst, member->ifname, member, true);
 
        return 0;
 }
@@ -520,8 +524,12 @@ bridge_dump_info(struct device *dev, struct blob_buf *b)
        system_if_dump_info(dev, b);
        list = blobmsg_open_array(b, "bridge-members");
 
-       vlist_for_each_element(&bst->members, bm, node)
+       vlist_for_each_element(&bst->members, bm, node) {
+               if (bm->dev.dev->hidden)
+                       continue;
+
                blobmsg_add_string(b, NULL, bm->dev.dev->ifname);
+       }
 
        blobmsg_close_array(b, list);
 }
@@ -560,8 +568,6 @@ bridge_apply_settings(struct bridge_state *bst, struct blob_attr **tb)
        /* defaults */
        cfg->stp = false;
        cfg->forward_delay = 2;
-       cfg->igmp_snoop = true;
-       cfg->multicast_querier = true;
        cfg->robustness = 2;
        cfg->query_interval = 12500;
        cfg->query_response_interval = 1000;
@@ -647,6 +653,9 @@ bridge_reload(struct device *dev, struct blob_attr *attr)
        blobmsg_parse(bridge_attrs, __BRIDGE_ATTR_MAX, tb_br,
                blob_data(attr), blob_len(attr));
 
+       if (tb_dev[DEV_ATTR_MACADDR])
+               bst->primary_port = NULL;
+
        bst->ifnames = tb_br[BRIDGE_ATTR_IFNAME];
        device_init_settings(dev, tb_dev);
        bridge_apply_settings(bst, tb_br);
@@ -726,3 +735,8 @@ bridge_create(const char *name, struct device_type *devtype,
 
        return dev;
 }
+
+static void __init bridge_device_type_init(void)
+{
+       device_type_add(&bridge_device_type);
+}