summaryrefslogtreecommitdiffhomepage
path: root/interface.c
diff options
context:
space:
mode:
authorYousong Zhou <yszhou4tech@gmail.com>2015-05-19 20:38:33 +0800
committerFelix Fietkau <nbd@openwrt.org>2015-05-23 16:44:46 +0200
commitc68587663ef18fa87841be0a5281264361fab411 (patch)
treee560c34e6bd2a0fc53d8129847c252ae2080e26f /interface.c
parentedb414294c06fb9d275c9f3be2282283453a46d0 (diff)
interface: teardown on l3_dev link lost.
This is mainly for shell protocols that has no_proto_task so that we can still teardown and setup the interface on l3_dev link lost instead of depending on running state of proto_task. Also rename related callbacks for better clarification. Signed-off-by: Yousong Zhou <yszhou4tech@gmail.com>
Diffstat (limited to 'interface.c')
-rw-r--r--interface.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/interface.c b/interface.c
index a9ecf28..5166c0c 100644
--- a/interface.c
+++ b/interface.c
@@ -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)
{
@@ -712,8 +730,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 +841,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;