diff options
-rw-r--r-- | bridge.c | 24 | ||||
-rw-r--r-- | config.c | 1 | ||||
-rw-r--r-- | device.c | 20 | ||||
-rw-r--r-- | device.h | 3 | ||||
-rw-r--r-- | vlan.c | 14 |
5 files changed, 49 insertions, 13 deletions
@@ -34,6 +34,7 @@ static const struct config_param_list bridge_attr_list = { }; static struct device *bridge_create(struct blob_attr *attr); +static void bridge_config_init(struct device *dev); static void bridge_free(struct device *dev); static void bridge_dump_status(struct device *dev, struct blob_buf *b); @@ -42,6 +43,7 @@ const struct device_type bridge_device_type = { .config_params = &bridge_attr_list, .create = bridge_create, + .config_init = bridge_config_init, .free = bridge_free, .dump_status = bridge_dump_status, }; @@ -50,6 +52,7 @@ struct bridge_state { struct device dev; device_state_cb set_state; + struct blob_attr *ifnames; bool active; struct list_head members; @@ -306,16 +309,27 @@ bridge_dump_status(struct device *dev, struct blob_buf *b) blobmsg_close_array(b, list); } +static void +bridge_config_init(struct device *dev) +{ + struct bridge_state *bst; + struct blob_attr *cur; + int rem; + + bst = container_of(dev, struct bridge_state, dev); + blobmsg_for_each_attr(cur, bst->ifnames, rem) { + bridge_add_member(bst, blobmsg_data(cur)); + } +} + static struct device * bridge_create(struct blob_attr *attr) { struct blob_attr *tb_dev[__DEV_ATTR_MAX]; struct blob_attr *tb_br[__BRIDGE_ATTR_MAX]; - struct blob_attr *cur; struct bridge_state *bst; struct device *dev = NULL; const char *name; - int rem; blobmsg_parse(device_attr_list.params, __DEV_ATTR_MAX, tb_dev, blob_data(attr), blob_len(attr)); @@ -337,6 +351,8 @@ bridge_create(struct blob_attr *attr) dev = &bst->dev; device_init(dev, &bridge_device_type, name); device_init_settings(dev, tb_dev); + dev->config_pending = true; + bst->ifnames = tb_br[BRIDGE_ATTR_IFNAME]; bst->set_state = dev->set_state; dev->set_state = bridge_set_state; @@ -345,10 +361,6 @@ bridge_create(struct blob_attr *attr) INIT_LIST_HEAD(&bst->members); - blobmsg_for_each_attr(cur, tb_br[BRIDGE_ATTR_IFNAME], rem) { - bridge_add_member(bst, blobmsg_data(cur)); - } - return dev; } @@ -343,5 +343,6 @@ config_init_interfaces(const char *name) device_free_unused(NULL); config_init = false; + device_init_pending(); interface_start_pending(); } @@ -298,6 +298,20 @@ device_free_unused(struct device *dev) __device_free_unused(dev); } +void +device_init_pending(void) +{ + struct device *dev, *tmp; + + avl_for_each_element_safe(&devices, dev, avl, tmp) { + if (!dev->config_pending) + continue; + + dev->type->config_init(dev); + dev->config_pending = false; + } +} + enum dev_change_type device_reload_config(struct device *dev, struct blob_attr *attr) { @@ -379,9 +393,15 @@ device_create(const char *name, const struct device_type *type, } dev = type->create(config); + if (!dev) + return NULL; + dev->config = config; if (odev) device_replace(dev, odev); + if (!config_init && dev->config_pending) + type->config_init(dev); + return dev; } @@ -32,6 +32,7 @@ struct device_type { const struct config_param_list *config_params; struct device *(*create)(struct blob_attr *attr); + void (*config_init)(struct device *); enum dev_change_type (*reload)(struct device *, struct blob_attr *); void (*dump_status)(struct device *, struct blob_buf *buf); int (*check_state)(struct device *); @@ -58,6 +59,7 @@ struct device { int ifindex; struct blob_attr *config; + bool config_pending; bool present; int active; @@ -111,6 +113,7 @@ extern const struct device_type bridge_device_type; struct device *device_create(const char *name, const struct device_type *type, struct blob_attr *config); void device_init_settings(struct device *dev, struct blob_attr **tb); +void device_init_pending(void); void device_init_virtual(struct device *dev, const struct device_type *type, const char *name); int device_init(struct device *iface, const struct device_type *type, const char *ifname); @@ -120,7 +120,7 @@ out: struct device *get_vlan_device_chain(const char *ifname, bool create) { - struct device *iface = NULL; + struct device *dev = NULL; char *buf, *s, *next, *err = NULL; int id; @@ -129,8 +129,8 @@ struct device *get_vlan_device_chain(const char *ifname, bool create) return NULL; s = split_vlan(buf); - iface = device_get(buf, create); - if (!iface && !create) + dev = device_get(buf, create); + if (!dev && !create) goto error; do { @@ -139,8 +139,8 @@ struct device *get_vlan_device_chain(const char *ifname, bool create) if (err && *err) goto error; - iface = get_vlan_device(iface, id, create); - if (!iface) + dev = get_vlan_device(dev, id, create); + if (!dev) goto error; s = next; @@ -149,8 +149,8 @@ struct device *get_vlan_device_chain(const char *ifname, bool create) } while (1); error: - iface = NULL; + dev = NULL; out: free(buf); - return iface; + return dev; } |