summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2011-10-21 01:44:26 +0200
committerFelix Fietkau <nbd@openwrt.org>2011-10-21 01:44:26 +0200
commit14f7651a6e61ccd870be78dd6b303057ea982414 (patch)
tree1aae026f8806f4d89d4c0291e15fc7eea402a14d
parent31e8b6e9a4c0db86d27f6bdb21678bb48735a8a1 (diff)
proto-shell: allow protocol handlers to add interface error messages and block interface restart
-rwxr-xr-xdummy/netifd-proto.sh22
-rwxr-xr-xdummy/proto/ppp.sh4
-rw-r--r--proto-shell.c49
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;
}