diff options
author | Yousong Zhou <yszhou4tech@gmail.com> | 2015-05-19 20:38:33 +0800 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2015-05-23 16:44:46 +0200 |
commit | c68587663ef18fa87841be0a5281264361fab411 (patch) | |
tree | e560c34e6bd2a0fc53d8129847c252ae2080e26f /interface.c | |
parent | edb414294c06fb9d275c9f3be2282283453a46d0 (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.c | 28 |
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; |