summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorHans Dedecker <dedeckeh@gmail.com>2015-02-12 17:41:15 +0100
committerSteven Barth <steven@midlink.org>2015-02-17 15:12:02 +0100
commit5a0909caaff498d61b5cf17162fd0c5c5b381b8b (patch)
tree57955ecd3bfe1ff08d1ac7f8277915b24432e700
parent2d09cca0e90127d33eed43b8790f5778ba3b943f (diff)
netifd: Fix possible hotplug race conditions
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>
-rw-r--r--interface-event.c19
1 files changed, 4 insertions, 15 deletions
diff --git a/interface-event.c b/interface-event.c
index 24af8f5..cfbc15c 100644
--- a/interface-event.c
+++ b/interface-event.c
@@ -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 */