X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fnetifd.git;a=blobdiff_plain;f=proto-shell.c;h=3e13d0fbab9c1af0b6cdbf00c3a2e16efeabb24f;hp=2a5eda0144d37f3a2327af015ab4d595265b4d66;hb=f8d894ad5974c29471cfef6679a819ab5a7e4ef8;hpb=c173c610044890c539584f3beb927e71ff83c198 diff --git a/proto-shell.c b/proto-shell.c index 2a5eda0..3e13d0f 100644 --- a/proto-shell.c +++ b/proto-shell.c @@ -44,7 +44,7 @@ enum proto_shell_sm { struct proto_shell_handler { struct list_head list; struct proto_handler proto; - struct config_param_list config; + struct uci_blob_param_list config; char *config_buf; bool init_available; char script_name[]; @@ -58,6 +58,8 @@ struct proto_shell_dependency { union if_addr host; bool v6; + + char interface[]; }; struct proto_shell_state { @@ -105,12 +107,15 @@ proto_shell_if_down_cb(struct interface_user *dep, struct interface *iface, static void proto_shell_update_host_dep(struct proto_shell_dependency *dep) { - struct interface *iface; + struct interface *iface = NULL; if (dep->dep.iface) goto out; - iface = interface_ip_add_target_route(&dep->host, dep->v6); + if (dep->interface[0]) + iface = vlist_find(&interfaces, dep->interface, iface, node); + + iface = interface_ip_add_target_route(&dep->host, dep->v6, iface); if (!iface) goto out; @@ -206,7 +211,7 @@ proto_shell_if_up_cb(struct interface_user *dep, struct interface *iface, { struct proto_shell_dependency *pdep; - if (ev != IFEV_UP) + if (ev != IFEV_UP && ev != IFEV_UPDATE) return; pdep = container_of(dep, struct proto_shell_dependency, dep); @@ -220,7 +225,7 @@ proto_shell_if_down_cb(struct interface_user *dep, struct interface *iface, struct proto_shell_dependency *pdep; struct proto_shell_state *state; - if (ev == IFEV_UP) + if (ev == IFEV_UP || ev == IFEV_UPDATE) return; pdep = container_of(dep, struct proto_shell_dependency, dep); @@ -317,6 +322,7 @@ proto_shell_free(struct interface_proto_state *proto) struct proto_shell_state *state; state = container_of(proto, struct proto_shell_state, proto); + uloop_timeout_cancel(&state->teardown_timeout); proto_shell_clear_host_dep(state); netifd_kill_process(&state->script_task); netifd_kill_process(&state->proto_task); @@ -615,17 +621,28 @@ proto_shell_add_host_dependency(struct proto_shell_state *state, struct blob_att { struct proto_shell_dependency *dep; struct blob_attr *host = tb[NOTIFY_HOST]; + struct blob_attr *ifname = tb[NOTIFY_IFNAME]; + size_t ifnamelen = (ifname) ? blobmsg_data_len(ifname) : 1; if (!host) return UBUS_STATUS_INVALID_ARGUMENT; - dep = calloc(1, sizeof(*dep)); - if (!inet_pton(AF_INET, blobmsg_data(host), &dep->host)) { - free(dep); - return UBUS_STATUS_INVALID_ARGUMENT; + dep = calloc(1, sizeof(*dep) + ifnamelen); + if (inet_pton(AF_INET, blobmsg_data(host), &dep->host) < 1) { + if (inet_pton(AF_INET6, blobmsg_data(host), &dep->host) < 1) { + free(dep); + return UBUS_STATUS_INVALID_ARGUMENT; + } else { + dep->v6 = true; + } } dep->proto = state; + if (ifname) + memcpy(dep->interface, blobmsg_data(ifname), ifnamelen); + else + dep->interface[0] = 0; + dep->dep.cb = proto_shell_if_up_cb; interface_add_user(&dep->dep, NULL); list_add(&dep->list, &state->deps); @@ -738,7 +755,7 @@ get_field(json_object *obj, const char *name, json_type type) } static char * -proto_shell_parse_config(struct config_param_list *config, json_object *obj) +proto_shell_parse_config(struct uci_blob_param_list *config, json_object *obj) { struct blobmsg_policy *attrs; char *str_buf, *str_cur; @@ -812,15 +829,12 @@ proto_shell_add_handler(const char *script, json_object *obj) name = json_object_get_string(tmp); - handler = calloc(1, sizeof(*handler) + - strlen(script) + 1 + - strlen(name) + 1); + handler = calloc_a(sizeof(*handler) + strlen(script) + 1, + &str, strlen(name) + 1); if (!handler) return; strcpy(handler->script_name, script); - - str = handler->script_name + strlen(handler->script_name) + 1; strcpy(str, name); proto = &handler->proto;