X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fnetifd.git;a=blobdiff_plain;f=interface.c;h=848990eae5b5a305d120192fe5fe9b377116e11e;hp=ef70deab590224f96b710a087b79fb4b8b5561a1;hb=8795f9ef89626cd658f615c78c6a17e990c0dcaa;hpb=f4f4f0b8d905231655b2a6fa20af4cc8b092d91e diff --git a/interface.c b/interface.c index ef70dea..848990e 100644 --- a/interface.c +++ b/interface.c @@ -74,6 +74,9 @@ const struct uci_blob_param_list interface_attr_list = { }; static void +set_config_state(struct interface *iface, enum interface_config_state s); + +static void interface_error_flush(struct interface *iface) { struct interface_error *error, *tmp; @@ -139,7 +142,7 @@ void interface_add_error(struct interface *iface, const char *subsystem, memcpy(dest, data[i], datalen[i]); dest += datalen[i]; } - error->data[n_data++] = NULL; + error->data[n_data] = NULL; if (subsystem) error->subsystem = strcpy(d_subsys, subsystem); @@ -256,9 +259,6 @@ __interface_set_down(struct interface *iface, bool force) interface_proto_event(iface->proto, PROTO_CMD_TEARDOWN, force); if (force) interface_flush_state(iface); - - if (iface->dynamic) - vlist_delete(&interfaces, &iface->node); break; case IFS_DOWN: @@ -333,14 +333,14 @@ interface_set_link_state(struct interface *iface, bool new_state) } static void -interface_ext_cb(struct device_user *dep, enum device_event ev) +interface_ext_dev_cb(struct device_user *dep, enum device_event ev) { if (ev == DEV_EVENT_REMOVE) device_remove_user(dep); } static void -interface_cb(struct device_user *dep, enum device_event ev) +interface_main_dev_cb(struct device_user *dep, enum device_event ev) { struct interface *iface; bool new_state = false; @@ -372,6 +372,24 @@ interface_cb(struct device_user *dep, enum device_event ev) } } +static void +interface_l3_dev_cb(struct device_user *dep, enum device_event ev) +{ + struct interface *iface; + + iface = container_of(dep, struct interface, l3_dev); + if (iface->l3_dev.dev == iface->main_dev.dev) + return; + + switch (ev) { + case DEV_EVENT_LINK_DOWN: + interface_proto_event(iface->proto, PROTO_CMD_TEARDOWN, false); + break; + default: + break; + } +} + void interface_set_available(struct interface *iface, bool new_state) { @@ -626,6 +644,8 @@ interface_handle_config_change(struct interface *iface) } if (iface->autostart && iface->available) interface_set_up(iface); + else if (iface->dynamic) + set_config_state(iface, IFC_REMOVE); } static void @@ -712,8 +732,9 @@ interface_alloc(const char *name, struct blob_attr *config) avl_init(&iface->data, avl_strcmp, false, NULL); iface->config_ip.enabled = false; - iface->main_dev.cb = interface_cb; - iface->ext_dev.cb = interface_ext_cb; + iface->main_dev.cb = interface_main_dev_cb; + iface->l3_dev.cb = interface_l3_dev_cb; + iface->ext_dev.cb = interface_ext_dev_cb; blobmsg_parse(iface_attrs, IFACE_ATTR_MAX, tb, blob_data(config), blob_len(config)); @@ -822,7 +843,6 @@ static bool __interface_add(struct interface *iface, struct blob_attr *config, b iface->ifname = blobmsg_data(cur); } - iface->config = config; vlist_add(&interfaces, &iface->node, iface->name); return true;