summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--interface-ip.c15
-rw-r--r--interface-ip.h4
-rw-r--r--proto-shell.c30
-rw-r--r--utils.h5
4 files changed, 42 insertions, 12 deletions
diff --git a/interface-ip.c b/interface-ip.c
index 8dae80d..28c608a 100644
--- a/interface-ip.c
+++ b/interface-ip.c
@@ -196,6 +196,21 @@ interface_write_resolv_conf(void)
}
void
+interface_ip_update_start(struct interface *iface)
+{
+ interface_clear_dns(iface);
+ vlist_update(&iface->proto_route);
+ vlist_update(&iface->proto_addr);
+}
+
+void
+interface_ip_update_complete(struct interface *iface)
+{
+ vlist_flush(&iface->proto_route);
+ vlist_flush(&iface->proto_addr);
+}
+
+void
interface_ip_init(struct interface *iface)
{
vlist_init(&iface->proto_route, route_cmp, interface_update_proto_route,
diff --git a/interface-ip.h b/interface-ip.h
index 91703a1..6049d14 100644
--- a/interface-ip.h
+++ b/interface-ip.h
@@ -60,4 +60,8 @@ void interface_add_dns_server_list(struct interface *iface, struct blob_attr *li
void interface_clear_dns(struct interface *iface);
void interface_write_resolv_conf(void);
+void interface_ip_update_start(struct interface *iface);
+void interface_ip_update_complete(struct interface *iface);
+
+
#endif
diff --git a/proto-shell.c b/proto-shell.c
index 3ed4b8e..3dcfb69 100644
--- a/proto-shell.c
+++ b/proto-shell.c
@@ -331,21 +331,23 @@ proto_shell_update_link(struct proto_shell_state *state, struct blob_attr **tb)
return UBUS_STATUS_INVALID_ARGUMENT;
up = blobmsg_get_bool(tb[NOTIFY_LINK_UP]);
- if (up) {
- if (!tb[NOTIFY_IFNAME])
- return UBUS_STATUS_INVALID_ARGUMENT;
-
- if (!state->l3_dev.dev) {
- device_add_user(&state->l3_dev,
- device_get(blobmsg_data(tb[NOTIFY_IFNAME]), true));
- device_claim(&state->l3_dev);
- state->proto.iface->l3_dev = &state->l3_dev;
- }
- state->proto.proto_event(&state->proto, IFPEV_UP);
- } else {
+ if (!up) {
state->proto.proto_event(&state->proto, IFPEV_LINK_LOST);
+ return 0;
}
+ if (!tb[NOTIFY_IFNAME])
+ return UBUS_STATUS_INVALID_ARGUMENT;
+
+ if (!state->l3_dev.dev) {
+ device_add_user(&state->l3_dev,
+ device_get(blobmsg_data(tb[NOTIFY_IFNAME]), true));
+ device_claim(&state->l3_dev);
+ state->proto.iface->l3_dev = &state->l3_dev;
+ }
+
+ interface_ip_update_start(state->proto.iface);
+
if ((cur = tb[NOTIFY_ADDR_EXT]) != NULL)
addr_ext = blobmsg_get_bool(cur);
@@ -364,6 +366,10 @@ proto_shell_update_link(struct proto_shell_state *state, struct blob_attr **tb)
if ((cur = tb[NOTIFY_DNS]) != NULL)
interface_add_dns_server_list(state->proto.iface, cur);
+ interface_ip_update_complete(state->proto.iface);
+
+ state->proto.proto_event(&state->proto, IFPEV_UP);
+
return 0;
}
diff --git a/utils.h b/utils.h
index 85d7dc6..6500fdf 100644
--- a/utils.h
+++ b/utils.h
@@ -34,6 +34,11 @@ void __vlist_init(struct vlist_tree *tree, avl_tree_comp cmp, vlist_update_cb up
#define vlist_init(tree, cmp, update, type, node, key) \
__vlist_init(tree, cmp, update, offsetof(type, key) - offsetof(type, node))
+static inline void vlist_update(struct vlist_tree *tree)
+{
+ tree->version++;
+}
+
void vlist_add(struct vlist_tree *tree, struct vlist_node *node);
void vlist_delete(struct vlist_tree *tree, struct vlist_node *node);
void vlist_flush(struct vlist_tree *tree);