proto-shell: allow protocol handlers to add interface error messages and block interf...
authorFelix Fietkau <nbd@openwrt.org>
Thu, 20 Oct 2011 23:44:26 +0000 (01:44 +0200)
committerFelix Fietkau <nbd@openwrt.org>
Thu, 20 Oct 2011 23:44:26 +0000 (01:44 +0200)
dummy/netifd-proto.sh
dummy/proto/ppp.sh
proto-shell.c

index 3ab69d8..c27d562 100755 (executable)
@@ -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
index f78933c..6f5dfcc 100755 (executable)
@@ -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
 }
index 726977a..fc16f76 100644 (file)
@@ -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;
        }