X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fodhcpd.git;a=blobdiff_plain;f=src%2Fubus.c;h=fbe7e1af6e8f630424c395f90e9bf49c1a9ca11b;hp=317a9c1919edc5a2ed56565931d2be69758313d0;hb=b461334ab277b6e8fd1622ab7c8a655363bd3f6c;hpb=d02dc222e61e2464bf850a629030c8a8b9b57ee8 diff --git a/src/ubus.c b/src/ubus.c index 317a9c1..fbe7e1a 100644 --- a/src/ubus.c +++ b/src/ubus.c @@ -13,6 +13,7 @@ static struct ubus_subscriber netifd; static struct blob_buf b; static struct blob_attr *dump = NULL; static uint32_t objid = 0; +static struct ubus_request req_dump = { .list = LIST_HEAD_INIT(req_dump.list) }; static int handle_dhcpv4_leases(struct ubus_context *ctx, _unused struct ubus_object *obj, @@ -176,7 +177,7 @@ static const struct blobmsg_policy iface_attrs[IFACE_ATTR_MAX] = { static void handle_dump(_unused struct ubus_request *req, _unused int type, struct blob_attr *msg) { - struct blob_attr *tb[DUMP_ATTR_INTERFACE]; + struct blob_attr *tb[DUMP_ATTR_MAX]; blobmsg_parse(dump_attrs, DUMP_ATTR_MAX, tb, blob_data(msg), blob_len(msg)); if (!tb[DUMP_ATTR_INTERFACE]) @@ -188,6 +189,19 @@ static void handle_dump(_unused struct ubus_request *req, _unused int type, stru } +static void update_netifd(bool subscribe) +{ + if (subscribe) + ubus_subscribe(ubus, &netifd, objid); + + ubus_abort_request(ubus, &req_dump); + if (!ubus_invoke_async(ubus, objid, "dump", NULL, &req_dump)) { + req_dump.data_cb = handle_dump; + ubus_complete_request_async(ubus, &req_dump); + } +} + + static int handle_update(_unused struct ubus_context *ctx, _unused struct ubus_object *obj, _unused struct ubus_request_data *req, _unused const char *method, struct blob_attr *msg) @@ -208,29 +222,22 @@ static int handle_update(_unused struct ubus_context *ctx, _unused struct ubus_o if (iface && iface->ignore) return 0; - ubus_invoke(ubus, objid, "dump", NULL, handle_dump, NULL, 0); + update_netifd(false); return 0; } -static void subscribe_netifd(void) -{ - ubus_subscribe(ubus, &netifd, objid); - ubus_invoke(ubus, objid, "dump", NULL, handle_dump, NULL, 0); -} - - void ubus_apply_network(void) { - struct blob_attr *c; + struct blob_attr *a; unsigned rem; if (!dump) return; - blobmsg_for_each_attr(c, dump, rem) { + blobmsg_for_each_attr(a, dump, rem) { struct blob_attr *tb[IFACE_ATTR_MAX]; - blobmsg_parse(iface_attrs, IFACE_ATTR_MAX, tb, blobmsg_data(c), blobmsg_data_len(c)); + blobmsg_parse(iface_attrs, IFACE_ATTR_MAX, tb, blobmsg_data(a), blobmsg_data_len(a)); if (!tb[IFACE_ATTR_INTERFACE] || !tb[IFACE_ATTR_DATA]) continue; @@ -241,8 +248,8 @@ void ubus_apply_network(void) blobmsg_get_string(tb[IFACE_ATTR_IFNAME]) : ""; bool matched = false; - struct interface *c; - list_for_each_entry(c, &interfaces, head) { + struct interface *c, *n; + list_for_each_entry_safe(c, n, &interfaces, head) { char *f = memmem(c->upstream, c->upstream_len, interface, strlen(interface) + 1); bool cmatched = !strcmp(interface, c->name) || !strcmp(ifname, c->ifname); @@ -288,7 +295,7 @@ static void handle_event(_unused struct ubus_context *ctx, _unused struct ubus_e return; objid = blobmsg_get_u32(tb[OBJ_ATTR_ID]); - subscribe_netifd(); + update_netifd(true); } static struct ubus_event_handler event_handler = { .cb = handle_event }; @@ -364,13 +371,13 @@ static const struct blobmsg_policy addr_attrs[ADDR_ATTR_MAX] = { [ADDR_ATTR_CLASS] = { .name = "class", .type = BLOBMSG_TYPE_STRING }, }; -uint16_t ubus_get_class(const char *ifname, const struct in6_addr *addr) +bool ubus_get_class(const char *ifname, const struct in6_addr *addr, uint16_t *pclass) { struct blob_attr *c, *cur; unsigned rem; if (!dump) - return 0; + return false; blobmsg_for_each_attr(c, dump, rem) { struct blob_attr *tb[IFACE_ATTR_MAX]; @@ -401,15 +408,17 @@ uint16_t ubus_get_class(const char *ifname, const struct in6_addr *addr) struct in6_addr ip6addr; inet_pton(AF_INET6, addrs, &ip6addr); - if (IN6_ARE_ADDR_EQUAL(&ip6addr, addr)) - return atoi(class); + if (IN6_ARE_ADDR_EQUAL(&ip6addr, addr)) { + *pclass = atoi(class); + return true; + } } } - return 0; + return false; } - return 0; + return false; } @@ -427,7 +436,7 @@ int init_ubus(void) ubus_add_object(ubus, &main_object); ubus_register_event_handler(ubus, &event_handler, "ubus.object.add"); if (!ubus_lookup_id(ubus, "network.interface", &objid)) - subscribe_netifd(); + update_netifd(true); return 0; }