bridge: add a debug message when a device could not be added
[project/netifd.git] / bridge.c
index 86787c7..1cafad8 100644 (file)
--- a/bridge.c
+++ b/bridge.c
@@ -76,6 +76,7 @@ struct bridge_member {
        struct bridge_state *bst;
        struct device_user dev;
        bool present;
+       char name[];
 };
 
 static int
@@ -106,8 +107,10 @@ bridge_enable_member(struct bridge_member *bm)
                goto error;
 
        ret = system_bridge_addif(&bst->dev, bm->dev.dev);
-       if (ret < 0)
+       if (ret < 0) {
+               D(DEVICE, "Bridge device %s could not be added\n", bm->dev.dev->ifname);
                goto error;
+       }
 
        return 0;
 
@@ -155,12 +158,12 @@ bridge_member_cb(struct device_user *dev, enum device_event ev)
 
                break;
        case DEV_EVENT_REMOVE:
-               if (!bm->present)
+               if (dev->hotplug) {
+                       vlist_delete(&bst->members, &bm->node);
                        return;
+               }
 
-               if (dev->hotplug)
-                       vlist_delete(&bst->members, &bm->node);
-               else
+               if (bm->present)
                        bridge_remove_member(bm);
 
                break;
@@ -232,17 +235,14 @@ static struct bridge_member *
 bridge_create_member(struct bridge_state *bst, struct device *dev, bool hotplug)
 {
        struct bridge_member *bm;
-       char *name;
 
        bm = calloc(1, sizeof(*bm) + strlen(dev->ifname) + 1);
        bm->bst = bst;
        bm->dev.cb = bridge_member_cb;
        bm->dev.hotplug = hotplug;
-       name = (char *) (bm + 1);
-       strcpy(name, dev->ifname);
-       vlist_add(&bst->members, &bm->node, name);
-
-       device_add_user(&bm->dev, dev);
+       strcpy(bm->name, dev->ifname);
+       bm->dev.dev = dev;
+       vlist_add(&bst->members, &bm->node, bm->name);
 
        return bm;
 }
@@ -252,9 +252,21 @@ bridge_member_update(struct vlist_tree *tree, struct vlist_node *node_new,
                     struct vlist_node *node_old)
 {
        struct bridge_member *bm;
+       struct device *dev;
+
+       if (node_new) {
+               bm = container_of(node_new, struct bridge_member, node);
+
+               if (node_old) {
+                       free(bm);
+                       return;
+               }
+
+               dev = bm->dev.dev;
+               bm->dev.dev = NULL;
+               device_add_user(&bm->dev, dev);
+       }
 
-       if (node_new && node_old)
-               return;
 
        if (node_old) {
                bm = container_of(node_old, struct bridge_member, node);
@@ -262,10 +274,6 @@ bridge_member_update(struct vlist_tree *tree, struct vlist_node *node_new,
                device_remove_user(&bm->dev);
                free(bm);
        }
-
-       if (node_new) {
-               bm = container_of(node_new, struct bridge_member, node);
-       }
 }
 
 
@@ -435,6 +443,7 @@ bridge_create(const char *name, struct blob_attr *attr)
        dev->hotplug_ops = &bridge_ops;
 
        vlist_init(&bst->members, avl_strcmp, bridge_member_update);
+       bst->members.keep_old = true;
 
        return dev;
 }