interface: fix removal of dynamic interfaces
authorHans Dedecker <dedeckeh@gmail.com>
Fri, 16 Nov 2018 15:25:41 +0000 (16:25 +0100)
committerHans Dedecker <dedeckeh@gmail.com>
Fri, 16 Nov 2018 17:50:14 +0000 (18:50 +0100)
Set config state to remove for dynamic interfaces in the following cases :
-interface is set as not available
-interface is set as down
-interface is set as having no link state
This will trigger an interface delete upon the next call of interface_handle_config_change

Before this change you could end up with lingering inactive dynamic
interfaces in case the aliased interface went down as before a dynamic
interface was only removed when set down via ubus

Signed-off-by: Hans Dedecker <dedeckeh@gmail.com>
interface.c

index 36f5480abd5fe8d352a3b212916596b8815c3198..4a09a220f79f460abedeb9ba6848df1e7cb8093f 100644 (file)
@@ -284,6 +284,12 @@ mark_interface_down(struct interface *iface)
        system_flush_routes();
 }
 
+static inline void
+__set_config_state(struct interface *iface, enum interface_config_state s)
+{
+       iface->config_state = s;
+}
+
 static void
 __interface_set_down(struct interface *iface, bool force)
 {
@@ -292,6 +298,9 @@ __interface_set_down(struct interface *iface, bool force)
        case IFS_UP:
        case IFS_SETUP:
                iface->state = IFS_TEARDOWN;
+               if (iface->dynamic)
+                       __set_config_state(iface, IFC_REMOVE);
+
                if (state == IFS_UP)
                        interface_event(iface, IFEV_DOWN);
 
@@ -334,6 +343,9 @@ interface_check_state(struct interface *iface)
        case IFS_SETUP:
                if (!iface->enabled || !link_state) {
                        interface_proto_event(iface->proto, PROTO_CMD_TEARDOWN, false);
+                       if (iface->dynamic)
+                               __set_config_state(iface, IFC_REMOVE);
+
                        mark_interface_down(iface);
                }
                break;
@@ -697,8 +709,6 @@ interface_handle_config_change(struct interface *iface)
        }
        if (iface->autostart)
                interface_set_up(iface);
-       else if (iface->dynamic)
-               set_config_state(iface, IFC_REMOVE);
 }
 
 static void
@@ -1120,7 +1130,7 @@ interface_start_pending(void)
 static void
 set_config_state(struct interface *iface, enum interface_config_state s)
 {
-       iface->config_state = s;
+       __set_config_state(iface, s);
        if (iface->state == IFS_DOWN)
                interface_handle_config_change(iface);
        else