fix ifname for alias+vlan chains
authorFelix Fietkau <nbd@openwrt.org>
Thu, 5 Jul 2012 12:18:04 +0000 (14:18 +0200)
committerFelix Fietkau <nbd@openwrt.org>
Thu, 5 Jul 2012 13:10:43 +0000 (15:10 +0200)
device.c
device.h
ubus.c
vlan.c

index 017fe03..cc41b20 100644 (file)
--- a/device.c
+++ b/device.c
@@ -163,6 +163,7 @@ alias_device_create(const char *name, struct blob_attr *attr)
        alias = calloc(1, sizeof(*alias) + strlen(name) + 1);
        strcpy(alias->name, name);
        alias->dev.set_state = alias_device_set_state;
+       alias->dev.hidden = true;
        device_init_virtual(&alias->dev, &alias_device_type, NULL);
        alias->avl.key = alias->name;
        avl_insert(&aliases, &alias->avl);
@@ -269,13 +270,19 @@ alias_notify_device(const char *name, struct device *dev)
                        device_remove_user(&alias->dep);
                        strcpy(alias->dev.ifname, dev->ifname);
                        device_add_user(&alias->dep, dev);
+                       alias->dev.hidden = false;
+                       device_broadcast_event(&alias->dev, DEV_EVENT_UPDATE_IFNAME);
                }
        }
 
        device_set_present(&alias->dev, !!dev);
 
-       if (!dev && alias->dep.dev && !alias->dep.dev->active)
+       if (!dev && alias->dep.dev && !alias->dep.dev->active) {
                device_remove_user(&alias->dep);
+               alias->dev.hidden = true;
+               alias->dev.ifname[0] = 0;
+               device_broadcast_event(&alias->dev, DEV_EVENT_UPDATE_IFNAME);
+       }
 
        device_unlock();
 }
index 3f8dc37..108d383 100644 (file)
--- a/device.h
+++ b/device.h
@@ -66,6 +66,8 @@ enum device_event {
        DEV_EVENT_ADD,
        DEV_EVENT_REMOVE,
 
+       DEV_EVENT_UPDATE_IFNAME,
+
        DEV_EVENT_SETUP,
        DEV_EVENT_TEARDOWN,
        DEV_EVENT_UP,
@@ -113,9 +115,11 @@ struct device {
        bool sys_present;
        bool present;
        int active;
+
        bool external;
        bool disabled;
        bool deferred;
+       bool hidden;
 
        bool current_config;
        bool default_config;
diff --git a/ubus.c b/ubus.c
index 2f0019c..ee4b031 100644 (file)
--- a/ubus.c
+++ b/ubus.c
@@ -496,7 +496,8 @@ netifd_handle_status(struct ubus_context *ctx, struct ubus_object *obj,
                blobmsg_add_string(&b, "proto", iface->proto_handler->name);
 
        dev = iface->main_dev.dev;
-       if (dev && !(iface->proto_handler->flags & PROTO_FLAG_NODEV))
+       if (dev && !dev->hidden &&
+           !(iface->proto_handler->flags & PROTO_FLAG_NODEV))
                blobmsg_add_string(&b, "device", dev->ifname);
 
        if (iface->state == IFS_UP) {
diff --git a/vlan.c b/vlan.c
index d1fb70b..ee0652f 100644 (file)
--- a/vlan.c
+++ b/vlan.c
@@ -61,6 +61,12 @@ static int vlan_set_device_state(struct device *dev, bool up)
        return ret;
 }
 
+static void vlan_dev_set_name(struct vlan_device *vldev, struct device *dev)
+{
+       vldev->dev.hidden = dev->hidden;
+       snprintf(vldev->dev.ifname, IFNAMSIZ, "%s.%d", dev->ifname, vldev->id);
+}
+
 static void vlan_dev_cb(struct device_user *dep, enum device_event ev)
 {
        struct vlan_device *vldev;
@@ -73,6 +79,10 @@ static void vlan_dev_cb(struct device_user *dep, enum device_event ev)
        case DEV_EVENT_REMOVE:
                device_set_present(&vldev->dev, false);
                break;
+       case DEV_EVENT_UPDATE_IFNAME:
+               vlan_dev_set_name(vldev, dep->dev);
+               device_broadcast_event(&vldev->dev, ev);
+               break;
        default:
                break;
        }
@@ -104,7 +114,6 @@ static struct device *get_vlan_device(struct device *dev, int id, bool create)
                return NULL;
 
        vldev = calloc(1, sizeof(*vldev));
-       snprintf(vldev->dev.ifname, IFNAMSIZ, "%s.%d", dev->ifname, id);
 
        device_init_virtual(&vldev->dev, &vlan_type, NULL);
        vldev->dev.default_config = true;
@@ -113,6 +122,7 @@ static struct device *get_vlan_device(struct device *dev, int id, bool create)
        vldev->dev.set_state = vlan_set_device_state;
 
        vldev->id = id;
+       vlan_dev_set_name(vldev, dev);
 
        vldev->dep.cb = vlan_dev_cb;
        device_add_user(&vldev->dep, dev);