Add indicator-flags to ubus and hotplug update-events
authorSteven Barth <steven@midlink.org>
Thu, 16 Jan 2014 23:39:40 +0000 (00:39 +0100)
committerSteven Barth <steven@midlink.org>
Thu, 16 Jan 2014 23:39:40 +0000 (00:39 +0100)
interface-event.c
interface-ip.c
interface.c
interface.h
proto-shell.c
ubus.c

index 3b0d1faca391bf0b89c1909f5477e2c08db18b45..c524ee28442f8c468b14748609d3ea64edb51513 100644 (file)
@@ -32,7 +32,8 @@ static struct uloop_process task = {
 };
 
 static void
-run_cmd(const char *ifname, const char *device, enum interface_event event)
+run_cmd(const char *ifname, const char *device, enum interface_event event,
+               enum interface_update_flags updated)
 {
        char *argv[3];
        int pid;
@@ -52,6 +53,18 @@ run_cmd(const char *ifname, const char *device, enum interface_event event)
        setenv("INTERFACE", ifname, 1);
        if (device)
                setenv("DEVICE", device, 1);
+
+       if (event == IFEV_UPDATE) {
+               if (updated & IUF_ADDRESS)
+                       setenv("IFUPDATE_ADDRESSES", "1", 1);
+               if (updated & IUF_ROUTE)
+                       setenv("IFUPDATE_ROUTES", "1", 1);
+               if (updated & IUF_PREFIX)
+                       setenv("IFUPDATE_PREFIXES", "1", 1);
+               if (updated & IUF_DATA)
+                       setenv("IFUPDATE_DATA", "1", 1);
+       }
+
        argv[0] = hotplug_cmd_path;
        argv[1] = "iface";
        argv[2] = NULL;
@@ -74,7 +87,7 @@ call_hotplug(void)
                device = current->l3_dev.dev->ifname;
 
        D(SYSTEM, "Call hotplug handler for interface '%s' (%s)\n", current->name, device ? device : "none");
-       run_cmd(current->name, device, current_ev);
+       run_cmd(current->name, device, current_ev, current->updated);
 }
 
 static void
index 3771b5d99b1093d2b7d6c68f38bba60295ce385f..a6a7dca3189b0e15dc2a2ab03b61ad28b021bf46 100644 (file)
@@ -457,6 +457,9 @@ interface_update_proto_addr(struct vlist_tree *tree,
        iface = ip->iface;
        dev = iface->l3_dev.dev;
 
+       if (!node_new || !node_old)
+               iface->updated |= IUF_ADDRESS;
+
        if (node_new) {
                a_new = container_of(node_new, struct device_addr, node);
 
@@ -559,6 +562,9 @@ interface_update_proto_route(struct vlist_tree *tree,
        iface = ip->iface;
        dev = iface->l3_dev.dev;
 
+       if (!node_new || !node_old)
+               iface->updated |= IUF_ROUTE;
+
        route_old = container_of(node_old, struct device_route, node);
        route_new = container_of(node_new, struct device_route, node);
 
@@ -829,6 +835,10 @@ interface_update_prefix(struct vlist_tree *tree,
        prefix_old = container_of(node_old, struct device_prefix, node);
        prefix_new = container_of(node_new, struct device_prefix, node);
 
+       struct interface_ip_settings *ip = container_of(tree, struct interface_ip_settings, prefix);
+       if (tree && (!node_new || !node_old))
+               ip->iface->updated |= IUF_PREFIX;
+
        struct device_route route;
        memset(&route, 0, sizeof(route));
        route.flags = DEVADDR_INET6;
index 9c208a283e40a2da7716651922aaa0b0a4e44b58..0032e57c1b2808721fa29c626b89412e7b181699 100644 (file)
@@ -151,15 +151,23 @@ interface_add_data(struct interface *iface, const struct blob_attr *data)
        if (!blobmsg_check_attr(data, true))
                return UBUS_STATUS_INVALID_ARGUMENT;
 
-       n = calloc(1, sizeof(*n) + blob_pad_len(data));
-       memcpy(n->data, data, blob_pad_len(data));
-       n->node.key = blobmsg_name(n->data);
+       const char *name = blobmsg_name(data);
+       unsigned len = blob_pad_len(data);
+
+       o = avl_find_element(&iface->data, name, o, node);
+       if (o) {
+               if (blob_pad_len(o->data) == len && !memcmp(o->data, data, len))
+                       return 0;
 
-       o = avl_find_element(&iface->data, n->node.key, o, node);
-       if (o)
                interface_data_del(iface, o);
+       }
 
+       n = calloc(1, sizeof(*n) + len);
+       memcpy(n->data, data, len);
+       n->node.key = blobmsg_name(n->data);
        avl_insert(&iface->data, &n->node);
+
+       iface->updated |= IUF_DATA;
        return 0;
 }
 
@@ -846,6 +854,7 @@ set_config_state(struct interface *iface, enum interface_config_state s)
 void
 interface_update_start(struct interface *iface)
 {
+       iface->updated = 0;
        interface_ip_update_start(&iface->proto_ip);
 }
 
index 4b7de5997d3055e1e85938230d3017f0356fa433..c3a43799b949ed9aa7731b27957c717878efaa8b 100644 (file)
@@ -41,6 +41,13 @@ enum interface_config_state {
        IFC_REMOVE
 };
 
+enum interface_update_flags {
+       IUF_ADDRESS     = (1 << 0),
+       IUF_ROUTE       = (1 << 1),
+       IUF_PREFIX      = (1 << 2),
+       IUF_DATA        = (1 << 3),
+};
+
 struct interface_error {
        struct list_head list;
 
@@ -100,6 +107,7 @@ struct interface {
        time_t start_time;
        enum interface_state state;
        enum interface_config_state config_state;
+       enum interface_update_flags updated;
 
        struct list_head users;
 
index 6bbfe10ea6696f13607c23ca731d36dd1b9b5dd6..1a69c1901c7524cf93053fb16c8760fd6000f14e 100644 (file)
@@ -479,15 +479,15 @@ proto_shell_update_link(struct proto_shell_state *state, struct blob_attr *data,
        if ((cur = tb[NOTIFY_DNS_SEARCH]))
                interface_add_dns_search_list(&iface->proto_ip, cur);
 
+       if ((cur = tb[NOTIFY_DATA]))
+               proto_shell_parse_data(state->proto.iface, cur);
+
        interface_update_complete(state->proto.iface);
 
        if (!keep)
                state->proto.proto_event(&state->proto, IFPEV_UP);
        state->sm = S_IDLE;
 
-       if ((cur = tb[NOTIFY_DATA]))
-               proto_shell_parse_data(state->proto.iface, cur);
-
        return 0;
 }
 
diff --git a/ubus.c b/ubus.c
index 399d46b8d881733d2c03a01cc2b478ce01d46daa..22b75e4073b24a1cf6d504c1199eaa04c8b58f50 100644 (file)
--- a/ubus.c
+++ b/ubus.c
@@ -662,6 +662,21 @@ netifd_dump_status(struct interface *iface)
                blobmsg_add_string(&b, "device", dev->ifname);
 
        if (iface->state == IFS_UP) {
+               if (iface->updated) {
+                       a = blobmsg_open_array(&b, "updated");
+
+                       if (iface->updated & IUF_ADDRESS)
+                               blobmsg_add_string(&b, NULL, "addresses");
+                       if (iface->updated & IUF_ROUTE)
+                               blobmsg_add_string(&b, NULL, "routes");
+                       if (iface->updated & IUF_PREFIX)
+                               blobmsg_add_string(&b, NULL, "prefixes");
+                       if (iface->updated & IUF_DATA)
+                               blobmsg_add_string(&b, NULL, "data");
+
+                       blobmsg_close_array(&b, a);
+               }
+
                if (iface->ip4table)
                        blobmsg_add_u32(&b, "ip4table", iface->ip4table);
                if (iface->ip6table)