X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fnetifd.git;a=blobdiff_plain;f=interface.c;h=0032e57c1b2808721fa29c626b89412e7b181699;hp=5649324d44bc50a57c4acfffdc2ed69f9ad7ca1a;hb=1418ef786f275b8458462ee3494573524ca0042c;hpb=6843870670b8a68c98528faf638c6b3938cab55d diff --git a/interface.c b/interface.c index 5649324..0032e57 100644 --- a/interface.c +++ b/interface.c @@ -151,15 +151,23 @@ interface_add_data(struct interface *iface, const struct blob_attr *data) if (!blobmsg_check_attr(data, true)) return UBUS_STATUS_INVALID_ARGUMENT; - n = calloc(1, sizeof(*n) + blob_pad_len(data)); - memcpy(n->data, data, blob_pad_len(data)); - n->node.key = blobmsg_name(n->data); + const char *name = blobmsg_name(data); + unsigned len = blob_pad_len(data); + + o = avl_find_element(&iface->data, name, o, node); + if (o) { + if (blob_pad_len(o->data) == len && !memcmp(o->data, data, len)) + return 0; - o = avl_find_element(&iface->data, n->node.key, o, node); - if (o) interface_data_del(iface, o); + } + n = calloc(1, sizeof(*n) + len); + memcpy(n->data, data, len); + n->node.key = blobmsg_name(n->data); avl_insert(&iface->data, &n->node); + + iface->updated |= IUF_DATA; return 0; } @@ -746,6 +754,37 @@ interface_add_link(struct interface *iface, struct device *dev) } int +interface_handle_link(struct interface *iface, const char *name, bool add) +{ + struct device *dev; + int ret; + + device_lock(); + + dev = device_get(name, add ? 2 : 0); + if (!dev) { + ret = UBUS_STATUS_NOT_FOUND; + goto out; + } + + if (add) { + device_set_present(dev, true); + if (iface->device_config) + device_set_config(dev, &simple_device_type, iface->config); + + system_if_apply_settings(dev, &dev->settings); + ret = interface_add_link(iface, dev); + } else { + ret = interface_remove_link(iface, dev); + } + +out: + device_unlock(); + + return ret; +} + +int interface_set_up(struct interface *iface) { int ret; @@ -815,6 +854,7 @@ set_config_state(struct interface *iface, enum interface_config_state s) void interface_update_start(struct interface *iface) { + iface->updated = 0; interface_ip_update_start(&iface->proto_ip); } @@ -887,7 +927,7 @@ interface_change_config(struct interface *if_old, struct interface *if_new) #undef UPDATE if (reload) { - D(INTERFACE, "Reload interface '%s because of config changes\n", + D(INTERFACE, "Reload interface '%s' because of config changes\n", if_old->name); interface_clear_errors(if_old); set_config_state(if_old, IFC_RELOAD);