device: make link status detection optional for vlan devices
authorFelix Fietkau <nbd@openwrt.org>
Mon, 20 Oct 2014 20:07:18 +0000 (22:07 +0200)
committerFelix Fietkau <nbd@openwrt.org>
Mon, 20 Oct 2014 20:07:20 +0000 (22:07 +0200)
Fixes a race condition that triggers endless link loss / detect calls
when VLAN devices are created.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
device.h
macvlan.c
system-linux.c
vlan.c
vlandev.c

index 73b26564e47981080a893661cbb5c3c66150a94d..adf72c5e1632f18edd61ac0bd7650864a5588c0b 100644 (file)
--- a/device.h
+++ b/device.h
@@ -47,6 +47,8 @@ struct device_type {
        struct list_head list;
        const char *name;
 
+       bool keep_link_status;
+
        const struct uci_blob_param_list *config_params;
 
        struct device *(*create)(const char *name, struct blob_attr *attr);
index e5a4891e136e0353b51c30b13b4450ba9a6e8dab..019a7ffedce6db4f353f38c19275fcceb9ed0f09 100644 (file)
--- a/macvlan.c
+++ b/macvlan.c
@@ -258,6 +258,7 @@ macvlan_create(const char *name, struct blob_attr *attr)
 const struct device_type macvlan_device_type = {
        .name = "MAC VLAN",
        .config_params = &macvlan_attr_list,
+       .keep_link_status = true,
 
        .create = macvlan_create,
        .config_init = macvlan_config_init,
index 7955cec5547d38360c3bfc0dc841206f606ca65f..7ae9e27c92f16d96776f1af2bcd2f94452d3acdf 100644 (file)
@@ -322,7 +322,8 @@ static int cb_rtnl_event(struct nl_msg *msg, void *arg)
                goto out;
 
        device_set_ifindex(dev, ifi->ifi_index);
-       device_set_link(dev, ifi->ifi_flags & IFF_LOWER_UP ? true : false);
+       if (!dev->type->keep_link_status)
+               device_set_link(dev, ifi->ifi_flags & IFF_LOWER_UP ? true : false);
 
 out:
        return 0;
diff --git a/vlan.c b/vlan.c
index 28b14417819b9c2a37ca84e273b5a36497379d31..354e12f661d662bcf1d37200239d2caeb6b255b2 100644 (file)
--- a/vlan.c
+++ b/vlan.c
@@ -102,6 +102,7 @@ static struct device *get_vlan_device(struct device *dev, int id, bool create)
        static const struct device_type vlan_type = {
                .name = "VLAN",
                .config_params = &device_attr_list,
+               .keep_link_status = true,
                .free = free_vlan_if,
        };
        struct vlan_device *vldev;
index 36a5c63204935d70de66054f0092c7bc7eb23666..7b2038e93019b5f89207591c64c88b3721fffbc5 100644 (file)
--- a/vlandev.c
+++ b/vlandev.c
@@ -246,6 +246,7 @@ vlandev_create(const char *name, struct blob_attr *attr)
 const struct device_type vlandev_device_type = {
        .name = "VLANDEV",
        .config_params = &vlandev_attr_list,
+       .keep_link_status = true,
 
        .create = vlandev_create,
        .config_init = vlandev_config_init,