+const struct device_type simple_device_type = {
+ .name = "Network device",
+ .config_params = &device_attr_list,
+
+ .create = simple_device_create,
+ .check_state = system_if_check,
+ .free = simple_device_free,
+};
+
+static int
+alias_device_set_state(struct device *dev, bool state)
+{
+ struct alias_device *alias;
+
+ alias = container_of(dev, struct alias_device, dev);
+ if (!alias->dep.dev)
+ return -1;
+
+ if (state)
+ return device_claim(&alias->dep);
+
+ device_release(&alias->dep);
+ if (alias->cleanup)
+ device_remove_user(&alias->dep);
+ return 0;
+}
+
+static struct device *
+alias_device_create(const char *name, struct blob_attr *attr)
+{
+ struct alias_device *alias;
+
+ alias = calloc(1, sizeof(*alias) + strlen(name) + 1);
+ strcpy(alias->name, name);
+ alias->dev.set_state = alias_device_set_state;
+ device_init_virtual(&alias->dev, &alias_device_type, NULL);
+ alias->avl.key = alias->name;
+ avl_insert(&aliases, &alias->avl);
+
+ return &alias->dev;
+}
+
+static void alias_device_free(struct device *dev)
+{
+ struct alias_device *alias;
+
+ device_cleanup(dev);
+
+ alias = container_of(dev, struct alias_device, dev);
+ avl_delete(&aliases, &alias->avl);
+ free(alias);
+}
+
+static const struct device_type alias_device_type = {
+ .name = "Network alias",
+ .create = alias_device_create,
+ .free = alias_device_free,
+};
+
+void
+device_init_settings(struct device *dev, struct blob_attr **tb)
+{
+ struct blob_attr *cur;
+ struct ether_addr *ea;
+
+ dev->flags = 0;
+
+ if ((cur = tb[DEV_ATTR_MTU])) {
+ dev->mtu = blobmsg_get_u32(cur);
+ dev->flags |= DEV_OPT_MTU;
+ }
+
+ if ((cur = tb[DEV_ATTR_TXQUEUELEN])) {
+ dev->txqueuelen = blobmsg_get_u32(cur);
+ dev->flags |= DEV_OPT_TXQUEUELEN;
+ }
+
+ if ((cur = tb[DEV_ATTR_MACADDR])) {
+ ea = ether_aton(blob_data(cur));
+ if (ea) {
+ memcpy(dev->macaddr, ea, sizeof(dev->macaddr));
+ dev->flags |= DEV_OPT_MACADDR;
+ }
+ }
+}
+
+static void __init dev_init(void)
+{
+ avl_init(&devices, avl_strcmp, true, NULL);
+ avl_init(&aliases, avl_strcmp, false, NULL);
+}
+
+static void device_broadcast_event(struct device *dev, enum device_event ev)