struct bridge_state *bst;
struct device_user dev;
bool present;
+ char name[];
};
static int
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;
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;
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;
}
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);
device_remove_user(&bm->dev);
free(bm);
}
-
- if (node_new) {
- bm = container_of(node_new, struct bridge_member, node);
- }
}
dev->hotplug_ops = &bridge_ops;
vlist_init(&bst->members, avl_strcmp, bridge_member_update);
+ bst->members.keep_old = true;
return dev;
}