X-Git-Url: https://git.archive.openwrt.org/?a=blobdiff_plain;f=proto-shell.c;h=86933b026efd22680d51041016e83127b778fd64;hb=069b6b830492109f3e880063f7f52ce2329cb9b6;hp=9fad3a0a581f038c703da42348084084d1110198;hpb=5d655d1d3f6880b53ea5bafda159c02da038548f;p=project%2Fnetifd.git diff --git a/proto-shell.c b/proto-shell.c index 9fad3a0..86933b0 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; @@ -155,18 +156,38 @@ proto_shell_handler(struct interface_proto_state *proto, proc = &state->script_task; if (cmd == PROTO_CMD_SETUP) { - action = "setup"; - state->last_error = -1; - proto_shell_clear_host_dep(state); - state->sm = S_SETUP; + switch (state->sm) { + case S_IDLE: + action = "setup"; + state->last_error = -1; + proto_shell_clear_host_dep(state); + state->sm = S_SETUP; + break; + + case S_SETUP_ABORT: + case S_TEARDOWN: + case S_SETUP: + return 0; + + default: + return -1; + } } 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; + } + + state->renew_pending = false; 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); @@ -187,6 +208,7 @@ proto_shell_handler(struct interface_proto_state *proto, uloop_timeout_set(&state->teardown_timeout, 5000); } + D(INTERFACE, "run %s for interface '%s'\n", action, proto->iface->name); config = blobmsg_format_json(state->config, true); if (!config) return -1; @@ -255,6 +277,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: @@ -427,6 +452,9 @@ proto_shell_update_link(struct proto_shell_state *state, struct blob_attr *data, bool keep = false; bool up; + if (state->sm == S_TEARDOWN || state->sm == S_SETUP_ABORT) + return UBUS_STATUS_PERMISSION_DENIED; + if (!tb[NOTIFY_LINK_UP]) return UBUS_STATUS_INVALID_ARGUMENT; @@ -490,9 +518,11 @@ proto_shell_update_link(struct proto_shell_state *state, struct blob_attr *data, interface_update_complete(state->proto.iface); - if (!keep) - state->proto.proto_event(&state->proto, IFPEV_UP); - state->sm = S_IDLE; + if ((state->sm != S_SETUP_ABORT) && (state->sm != S_TEARDOWN)) { + if (!keep) + state->proto.proto_event(&state->proto, IFPEV_UP); + state->sm = S_IDLE; + } return 0; } @@ -530,6 +560,9 @@ proto_shell_run_command(struct proto_shell_state *state, struct blob_attr **tb) static char *argv[64]; static char *env[32]; + if (state->sm == S_TEARDOWN || state->sm == S_SETUP_ABORT) + return UBUS_STATUS_PERMISSION_DENIED; + if (!tb[NOTIFY_COMMAND]) goto error; @@ -559,7 +592,8 @@ proto_shell_kill_command(struct proto_shell_state *state, struct blob_attr **tb) signal = SIGTERM; if (state->proto_task.uloop.pending) { - state->proto_task_killed = true; + if (signal == SIGTERM || signal == SIGKILL) + state->proto_task_killed = true; kill(state->proto_task.uloop.pid, signal); } @@ -628,6 +662,9 @@ proto_shell_add_host_dependency(struct proto_shell_state *state, struct blob_att const char *ifname_str = ifname_a ? blobmsg_data(ifname_a) : ""; char *ifname; + if (state->sm == S_TEARDOWN || state->sm == S_SETUP_ABORT) + return UBUS_STATUS_PERMISSION_DENIED; + if (!host) return UBUS_STATUS_INVALID_ARGUMENT; @@ -657,6 +694,8 @@ proto_shell_add_host_dependency(struct proto_shell_state *state, struct blob_att static int proto_shell_setup_failed(struct proto_shell_state *state) { + int ret = 0; + switch (state->sm) { case S_IDLE: state->proto.proto_event(&state->proto, IFPEV_LINK_LOST); @@ -664,10 +703,13 @@ proto_shell_setup_failed(struct proto_shell_state *state) case S_SETUP: proto_shell_handler(&state->proto, PROTO_CMD_TEARDOWN, false); break; + case S_SETUP_ABORT: + case S_TEARDOWN: default: + ret = UBUS_STATUS_PERMISSION_DENIED; break; } - return 0; + return ret; } static int