diff options
author | Felix Fietkau <nbd@openwrt.org> | 2011-10-21 01:44:26 +0200 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2011-10-21 01:44:26 +0200 |
commit | 14f7651a6e61ccd870be78dd6b303057ea982414 (patch) | |
tree | 1aae026f8806f4d89d4c0291e15fc7eea402a14d | |
parent | 31e8b6e9a4c0db86d27f6bdb21678bb48735a8a1 (diff) |
proto-shell: allow protocol handlers to add interface error messages and block interface restart
-rwxr-xr-x | dummy/netifd-proto.sh | 22 | ||||
-rwxr-xr-x | dummy/proto/ppp.sh | 4 | ||||
-rw-r--r-- | proto-shell.c | 49 |
3 files changed, 75 insertions, 0 deletions
diff --git a/dummy/netifd-proto.sh b/dummy/netifd-proto.sh index 3ab69d8..c27d562 100755 --- a/dummy/netifd-proto.sh +++ b/dummy/netifd-proto.sh @@ -182,6 +182,28 @@ proto_kill_command() { _proto_notify "$interface" } +proto_notify_error() { + local interface="$1"; shift + + json_init + json_add_int action 3 + json_add_array error + while [ $# -gt 0 ]; do + json_add_string "" "$1" + shift + done + json_close_array + _proto_notify "$interface" +} + +proto_block_restart() { + local interface="$1"; shift + + json_init + json_add_int action 4 + _proto_notify "$interface" +} + init_proto() { proto="$1"; shift cmd="$1"; shift diff --git a/dummy/proto/ppp.sh b/dummy/proto/ppp.sh index f78933c..6f5dfcc 100755 --- a/dummy/proto/ppp.sh +++ b/dummy/proto/ppp.sh @@ -47,6 +47,10 @@ pppoe_setup() { } pppoe_teardown() { + [ "$ERROR" = 9 ] && { + proto_notify_error "$interface" PROCESS_KILLED + proto_block_restart "$interface" + } proto_kill_command "$interface" return } diff --git a/proto-shell.c b/proto-shell.c index 726977a..fc16f76 100644 --- a/proto-shell.c +++ b/proto-shell.c @@ -216,6 +216,7 @@ proto_shell_parse_route_list(struct interface *iface, struct blob_attr *attr, enum { NOTIFY_ACTION, + NOTIFY_ERROR, NOTIFY_COMMAND, NOTIFY_ENV, NOTIFY_SIGNAL, @@ -233,6 +234,7 @@ enum { static const struct blobmsg_policy notify_attr[__NOTIFY_LAST] = { [NOTIFY_ACTION] = { .name = "action", .type = BLOBMSG_TYPE_INT32 }, + [NOTIFY_ERROR] = { .name = "error", .type = BLOBMSG_TYPE_ARRAY }, [NOTIFY_COMMAND] = { .name = "command", .type = BLOBMSG_TYPE_ARRAY }, [NOTIFY_ENV] = { .name = "env", .type = BLOBMSG_TYPE_ARRAY }, [NOTIFY_SIGNAL] = { .name = "signal", .type = BLOBMSG_TYPE_INT32 }, @@ -382,6 +384,49 @@ proto_shell_kill_command(struct proto_shell_state *state, struct blob_attr **tb) } static int +proto_shell_notify_error(struct proto_shell_state *state, struct blob_attr **tb) +{ + struct blob_attr *cur; + char *data[16]; + int n_data = 0; + int rem; + + if (!tb[NOTIFY_ERROR]) + return UBUS_STATUS_INVALID_ARGUMENT; + + blobmsg_for_each_attr(cur, tb[NOTIFY_ERROR], rem) { + if (n_data + 1 == ARRAY_SIZE(data)) + goto error; + + if (blobmsg_type(cur) != BLOBMSG_TYPE_STRING) + goto error; + + if (!blobmsg_check_attr(cur, NULL)) + goto error; + + data[n_data++] = blobmsg_data(cur); + } + + if (!n_data) + goto error; + + interface_add_error(state->proto.iface, state->handler->proto.name, + data[0], (const char **) &data[1], n_data - 1); + + return 0; + +error: + return UBUS_STATUS_INVALID_ARGUMENT; +} + +static int +proto_shell_block_restart(struct proto_shell_state *state, struct blob_attr **tb) +{ + state->proto.iface->autostart = false; + return 0; +} + +static int proto_shell_notify(struct interface_proto_state *proto, struct blob_attr *attr) { struct proto_shell_state *state; @@ -400,6 +445,10 @@ proto_shell_notify(struct interface_proto_state *proto, struct blob_attr *attr) return proto_shell_run_command(state, tb); case 2: return proto_shell_kill_command(state, tb); + case 3: + return proto_shell_notify_error(state, tb); + case 4: + return proto_shell_block_restart(state, tb); default: return UBUS_STATUS_INVALID_ARGUMENT; } |