netifd: Fix possible hotplug race conditions
authorHans Dedecker <dedeckeh@gmail.com>
Thu, 12 Feb 2015 16:41:15 +0000 (17:41 +0100)
committerSteven Barth <steven@midlink.org>
Tue, 17 Feb 2015 14:12:02 +0000 (15:12 +0100)
Don't drop ifup/ifdown events in case an interface event is cached
as it leads to possible race conditions (eg firewall not being
reloaded as ifup is dropped) when multiple interface events are fired
in a short timeframe (eg multiple PPP link flaps).
Always overwrite the cached interface event except for the
interface update event so the hotplug scripts are launched
with the last known status.

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

index 24af8f57ef67e76001ca819b1085e1bab7070950..cfbc15c2bd5bcf3008a798949b08804e79e2e799 100644 (file)
@@ -120,22 +120,11 @@ interface_queue_event(struct interface *iface, enum interface_event ev)
        if (current == iface) {
                /* an event for iface is being processed */
                if (!list_empty(&iface->hotplug_list)) {
-                       /* an additional event for iface is pending */
-                       if ((ev != current_ev || ev == IFEV_UPDATE) &&
-                       !(iface->hotplug_ev == IFEV_UP && ev == IFEV_UPDATE)) {
-                               /* if incoming event is different from the one
-                                * being handled or if it is an update,
-                                * overwrite pending event, but never
-                                * overwrite an ifup with an ifupdate */
+                       /* an additional event for iface is pending   */
+                       /* overwrite pending event if it differs from */
+                       /* an update                                  */
+                       if (ev != IFEV_UPDATE)
                                iface->hotplug_ev = ev;
-                       }
-                       else if (ev == current_ev && ev != IFEV_UPDATE) {
-                               /* if incoming event is not an ifupdate
-                                * and is the same as the one that is
-                                * being handled, remove it from the
-                                * pending list */
-                               list_del_init(&iface->hotplug_list);
-                       }
                }
                else {
                        /* no additional event for iface is pending */