summaryrefslogtreecommitdiffhomepage
path: root/proto-shell.c
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2014-07-26 03:46:39 +0200
committerFelix Fietkau <nbd@openwrt.org>2014-07-26 03:47:03 +0200
commitc430d3278b91369204c83cd135673a5d5cded699 (patch)
tree269d91f785c2c1e3ff5ed28db4bd5002203c6850 /proto-shell.c
parente46cbd2f89f0be8e4a2423c065cf6b2e6ebcfea3 (diff)
proto-shell: fix setup/renew race condition
If a renew event arrives before the setup event has been processed, the renew event needs to be deferred, otherwise interfaces can get stuck Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Diffstat (limited to 'proto-shell.c')
-rw-r--r--proto-shell.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/proto-shell.c b/proto-shell.c
index d85a8d7..5f2224b 100644
--- a/proto-shell.c
+++ b/proto-shell.c
@@ -71,6 +71,7 @@ struct proto_shell_state {
enum proto_shell_sm sm;
bool proto_task_killed;
+ bool renew_pending;
int last_error;
@@ -162,11 +163,18 @@ proto_shell_handler(struct interface_proto_state *proto,
} else if (cmd == PROTO_CMD_RENEW) {
if (!(handler->proto.flags & PROTO_FLAG_RENEW_AVAILABLE))
return 0;
+
+ if (state->script_task.uloop.pending) {
+ state->renew_pending = true;
+ return 0;
+ }
+
action = "renew";
} else {
if (state->sm == S_TEARDOWN)
return 0;
+ state->renew_pending = false;
if (state->script_task.uloop.pending) {
if (state->sm != S_SETUP_ABORT) {
uloop_timeout_set(&state->teardown_timeout, 1000);
@@ -256,6 +264,9 @@ proto_shell_task_finish(struct proto_shell_state *state,
if (task == &state->proto_task)
proto_shell_handler(&state->proto, PROTO_CMD_TEARDOWN,
false);
+ if (task == &state->script_task && state->renew_pending)
+ proto_shell_handler(&state->proto, PROTO_CMD_RENEW,
+ false);
break;
case S_SETUP_ABORT: