};
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;
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);
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:
}
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;
}
}
+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)
{
}
if (iface->autostart && iface->available)
interface_set_up(iface);
+ else if (iface->dynamic)
+ set_config_state(iface, IFC_REMOVE);
}
static void
-interface_proto_cb(struct interface_proto_state *state, enum interface_proto_event ev)
+interface_proto_event_cb(struct interface_proto_state *state, enum interface_proto_event ev)
{
struct interface *iface = state->iface;
if (!state)
return;
- state->proto_event = interface_proto_cb;
+ state->proto_event = interface_proto_event_cb;
state->iface = iface;
}
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));
iface->ifname = blobmsg_data(cur);
}
-
iface->config = config;
vlist_add(&interfaces, &iface->node, iface->name);
return true;