device: Fix dotted vlan interface staying down
[project/netifd.git] / device.c
index 0e07615..fa3d00f 100644 (file)
--- a/device.c
+++ b/device.c
@@ -45,6 +45,7 @@ static const struct blobmsg_policy dev_attrs[__DEV_ATTR_MAX] = {
        [DEV_ATTR_IGMPVERSION] = { .name = "igmpversion", .type = BLOBMSG_TYPE_INT32 },
        [DEV_ATTR_MLDVERSION] = { .name = "mldversion", .type = BLOBMSG_TYPE_INT32 },
        [DEV_ATTR_NEIGHREACHABLETIME] = { .name = "neighreachabletime", .type = BLOBMSG_TYPE_INT32 },
+       [DEV_ATTR_NEIGHGCSTALETIME] = { .name = "neighgcstaletime", .type = BLOBMSG_TYPE_INT32 },
        [DEV_ATTR_RPS] = { .name = "rps", .type = BLOBMSG_TYPE_BOOL },
        [DEV_ATTR_XPS] = { .name = "xps", .type = BLOBMSG_TYPE_BOOL },
        [DEV_ATTR_DADTRANSMITS] = { .name = "dadtransmits", .type = BLOBMSG_TYPE_INT32 },
@@ -173,6 +174,10 @@ device_merge_settings(struct device *dev, struct device_settings *n)
                s->neigh4reachabletime : os->neigh4reachabletime;
        n->neigh6reachabletime = s->flags & DEV_OPT_NEIGHREACHABLETIME ?
                s->neigh6reachabletime : os->neigh6reachabletime;
+       n->neigh4gcstaletime = s->flags & DEV_OPT_NEIGHGCSTALETIME ?
+               s->neigh4gcstaletime : os->neigh4gcstaletime;
+       n->neigh6gcstaletime = s->flags & DEV_OPT_NEIGHGCSTALETIME ?
+               s->neigh6gcstaletime : os->neigh6gcstaletime;
        n->dadtransmits = s->flags & DEV_OPT_DADTRANSMITS ?
                s->dadtransmits : os->dadtransmits;
        n->multicast = s->flags & DEV_OPT_MULTICAST ?
@@ -262,6 +267,11 @@ device_init_settings(struct device *dev, struct blob_attr **tb)
                s->flags |= DEV_OPT_NEIGHREACHABLETIME;
        }
 
+       if ((cur = tb[DEV_ATTR_NEIGHGCSTALETIME])) {
+               s->neigh6gcstaletime = s->neigh4gcstaletime = blobmsg_get_u32(cur);
+               s->flags |= DEV_OPT_NEIGHGCSTALETIME;
+       }
+
        if ((cur = tb[DEV_ATTR_RPS])) {
                s->rps = blobmsg_get_bool(cur);
                s->flags |= DEV_OPT_RPS;
@@ -412,14 +422,14 @@ void device_init_virtual(struct device *dev, const struct device_type *type, con
        assert(dev);
        assert(type);
 
-       if (name)
-               strncpy(dev->ifname, name, IFNAMSIZ);
-
-       D(DEVICE, "Initialize device '%s'\n", dev->ifname);
+       D(DEVICE, "Initialize device '%s'\n", name ? name : "");
        INIT_SAFE_LIST(&dev->users);
        INIT_SAFE_LIST(&dev->aliases);
        dev->type = type;
 
+       if (name)
+               device_set_ifname(dev, name);
+
        if (!dev->set_state)
                dev->set_state = set_device_state;
 }
@@ -467,6 +477,14 @@ device_create_default(const char *name, bool external)
 }
 
 struct device *
+device_find(const char *name)
+{
+       struct device *dev;
+
+       return avl_find_element(&devices, name, dev, avl);
+}
+
+struct device *
 device_get(const char *name, int create)
 {
        struct device *dev;
@@ -572,6 +590,27 @@ void device_set_ifindex(struct device *dev, int ifindex)
        device_broadcast_event(dev, DEV_EVENT_UPDATE_IFINDEX);
 }
 
+int device_set_ifname(struct device *dev, const char *name)
+{
+       int ret = 0;
+
+       if (!strcmp(dev->ifname, name))
+               return 0;
+
+       if (dev->avl.key)
+               avl_delete(&devices, &dev->avl);
+
+       strncpy(dev->ifname, name, IFNAMSIZ);
+
+       if (dev->avl.key)
+               ret = avl_insert(&devices, &dev->avl);
+
+       if (ret == 0)
+               device_broadcast_event(dev, DEV_EVENT_UPDATE_IFNAME);
+
+       return ret;
+}
+
 static int device_refcount(struct device *dev)
 {
        struct list_head *list;
@@ -945,6 +984,10 @@ device_dump_status(struct blob_buf *b, struct device *dev)
                        blobmsg_add_u32(b, "neigh4reachabletime", st.neigh4reachabletime);
                        blobmsg_add_u32(b, "neigh6reachabletime", st.neigh6reachabletime);
                }
+               if (st.flags & DEV_OPT_NEIGHGCSTALETIME) {
+                       blobmsg_add_u32(b, "neigh4gcstaletime", st.neigh4gcstaletime);
+                       blobmsg_add_u32(b, "neigh6gcstaletime", st.neigh6gcstaletime);
+               }
                if (st.flags & DEV_OPT_DADTRANSMITS)
                        blobmsg_add_u32(b, "dadtransmits", st.dadtransmits);
                if (st.flags & DEV_OPT_MULTICAST_TO_UNICAST)