diff options
-rw-r--r-- | src/config.c | 5 | ||||
-rw-r--r-- | src/odhcpd.h | 2 | ||||
-rw-r--r-- | src/ubus.c | 42 |
3 files changed, 30 insertions, 19 deletions
diff --git a/src/config.c b/src/config.c index bc85603..6ae219a 100644 --- a/src/config.c +++ b/src/config.c @@ -252,9 +252,8 @@ err: } -int config_parse_interface(struct blob_attr *b, const char *name) +int config_parse_interface(struct blob_attr *b, const char *name, bool overwrite) { - bool overwrite = !!name; struct blob_attr *tb[IFACE_ATTR_MAX], *c; blobmsg_parse(iface_attrs, IFACE_ATTR_MAX, tb, blob_data(b), blob_len(b)); @@ -457,7 +456,7 @@ static int set_interface(struct uci_section *s) { blob_buf_init(&b, 0); uci_to_blob(&b, s, &interface_attr_list); - return config_parse_interface(b.head, s->e.name); + return config_parse_interface(b.head, s->e.name, true); } diff --git a/src/odhcpd.h b/src/odhcpd.h index 5608fa9..be8baeb 100644 --- a/src/odhcpd.h +++ b/src/odhcpd.h @@ -186,7 +186,7 @@ time_t odhcpd_time(void); ssize_t odhcpd_unhexlify(uint8_t *dst, size_t len, const char *src); void odhcpd_hexlify(char *dst, const uint8_t *src, size_t len); -int config_parse_interface(struct blob_attr *b, const char *iname); +int config_parse_interface(struct blob_attr *b, const char *iname, bool overwrite); const char* ubus_get_ifname(const char *name); void ubus_apply_network(void); @@ -184,7 +184,9 @@ static void handle_dump(_unused struct ubus_request *req, _unused int type, stru } -static struct interface* find_interface(struct blob_attr *msg) +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) { struct blob_attr *tb[IFACE_ATTR_MAX]; blobmsg_parse(iface_attrs, IFACE_ATTR_MAX, tb, blob_data(msg), blob_len(msg)); @@ -194,20 +196,11 @@ static struct interface* find_interface(struct blob_attr *msg) const char *ifname = (tb[IFACE_ATTR_IFNAME]) ? blobmsg_get_string(tb[IFACE_ATTR_IFNAME]) : ""; - struct interface *c; + struct interface *c, *iface = NULL; list_for_each_entry(c, &interfaces, head) if (!strcmp(interface, c->name) || !strcmp(ifname, c->ifname)) - return c; - - return NULL; -} - + iface = c; -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) -{ - struct interface *iface = find_interface(msg); if (iface && iface->ignore) return 0; @@ -233,9 +226,28 @@ void ubus_apply_network(void) return; blobmsg_for_each_attr(c, dump, rem) { - struct interface *iface = find_interface(c); - if (!iface || !iface->ignore) - config_parse_interface(c, NULL); + struct blob_attr *tb[IFACE_ATTR_MAX]; + blobmsg_parse(iface_attrs, IFACE_ATTR_MAX, tb, blob_data(c), blob_len(c)); + + if (!tb[IFACE_ATTR_INTERFACE] || !tb[IFACE_ATTR_DATA]) + continue; + + const char *interface = (tb[IFACE_ATTR_INTERFACE]) ? + blobmsg_get_string(tb[IFACE_ATTR_INTERFACE]) : ""; + const char *ifname = (tb[IFACE_ATTR_IFNAME]) ? + blobmsg_get_string(tb[IFACE_ATTR_IFNAME]) : ""; + + struct interface *c; + list_for_each_entry(c, &interfaces, head) { + char *f = memmem(c->upstream, c->upstream_len, + interface, strlen(interface) + 1); + if (strcmp(interface, c->name) && strcmp(ifname, c->ifname) && + (!f || (f != c->upstream && f[-1] != 0))) + continue; + + if (!c || !c->ignore) + config_parse_interface(tb[IFACE_ATTR_DATA], interface, false); + } } } |