fix error checking of asprintf
[project/netifd.git] / ubus.c
diff --git a/ubus.c b/ubus.c
index 2f0019c..d6d4188 100644 (file)
--- a/ubus.c
+++ b/ubus.c
@@ -25,7 +25,6 @@
 
 static struct ubus_context *ctx = NULL;
 static struct blob_buf b;
-static struct netifd_fd ubus_fd;
 static const char *ubus_path;
 
 /* global object */
@@ -258,8 +257,7 @@ static void
 netifd_ubus_add_fd(void)
 {
        ubus_add_uloop(ctx);
-       ubus_fd.fd = ctx->sock.fd;
-       netifd_fd_add(&ubus_fd);
+       system_fd_set_cloexec(ctx->sock.fd);
 }
 
 static void
@@ -283,7 +281,6 @@ netifd_ubus_reconnect_timer(struct uloop_timeout *timeout)
 static void
 netifd_ubus_connection_lost(struct ubus_context *ctx)
 {
-       netifd_fd_delete(&ubus_fd);
        netifd_ubus_reconnect_timer(NULL);
 }
 
@@ -376,7 +373,8 @@ netifd_add_interface_errors(struct blob_buf *b, struct interface *iface)
 }
 
 static void
-interface_ip_dump_address_list(struct interface_ip_settings *ip, bool v6)
+interface_ip_dump_address_list(struct interface_ip_settings *ip, bool v6,
+                               bool enabled)
 {
        struct device_addr *addr;
        char *buf;
@@ -385,6 +383,9 @@ interface_ip_dump_address_list(struct interface_ip_settings *ip, bool v6)
        int af;
 
        vlist_for_each_element(&ip->addr, addr, node) {
+               if (addr->enabled != enabled)
+                       continue;
+
                if ((addr->flags & DEVADDR_FAMILY) == DEVADDR_INET4)
                        af = AF_INET;
                else
@@ -406,7 +407,7 @@ interface_ip_dump_address_list(struct interface_ip_settings *ip, bool v6)
 }
 
 static void
-interface_ip_dump_route_list(struct interface_ip_settings *ip)
+interface_ip_dump_route_list(struct interface_ip_settings *ip, bool enabled)
 {
        struct device_route *route;
        int buflen = 128;
@@ -415,6 +416,9 @@ interface_ip_dump_route_list(struct interface_ip_settings *ip)
        int af;
 
        vlist_for_each_element(&ip->route, route, node) {
+               if (route->enabled != enabled)
+                       continue;
+
                if ((route->flags & DEVADDR_FAMILY) == DEVADDR_INET4)
                        af = AF_INET;
                else
@@ -438,20 +442,22 @@ interface_ip_dump_route_list(struct interface_ip_settings *ip)
                if (route->flags & DEVROUTE_METRIC)
                        blobmsg_add_u32(&b, "metric", route->metric);
 
-               blobmsg_add_u8(&b, "enabled", route->enabled);
-
                blobmsg_close_table(&b, r);
        }
 }
 
 static void
-interface_ip_dump_dns_server_list(struct interface_ip_settings *ip)
+interface_ip_dump_dns_server_list(struct interface_ip_settings *ip,
+                                  bool enabled)
 {
        struct dns_server *dns;
        int buflen = 128;
        char *buf;
 
        vlist_simple_for_each_element(&ip->dns_servers, dns, node) {
+               if (ip->no_dns == enabled)
+                       continue;
+
                buf = blobmsg_alloc_string_buffer(&b, NULL, buflen);
                inet_ntop(dns->af, &dns->addr, buf, buflen);
                blobmsg_add_string_buffer(&b);
@@ -459,11 +465,15 @@ interface_ip_dump_dns_server_list(struct interface_ip_settings *ip)
 }
 
 static void
-interface_ip_dump_dns_search_list(struct interface_ip_settings *ip)
+interface_ip_dump_dns_search_list(struct interface_ip_settings *ip,
+                                  bool enabled)
 {
        struct dns_search_domain *dns;
 
        vlist_simple_for_each_element(&ip->dns_search, dns, node) {
+               if (ip->no_dns == enabled)
+                       continue;
+
                blobmsg_add_string(&b, NULL, dns->name);
        }
 }
@@ -476,7 +486,7 @@ netifd_handle_status(struct ubus_context *ctx, struct ubus_object *obj,
        struct interface *iface;
        struct interface_data *data;
        struct device *dev;
-       void *a;
+       void *a, *inactive;
 
        iface = container_of(obj, struct interface, ubus);
 
@@ -496,31 +506,55 @@ netifd_handle_status(struct ubus_context *ctx, struct ubus_object *obj,
                blobmsg_add_string(&b, "proto", iface->proto_handler->name);
 
        dev = iface->main_dev.dev;
-       if (dev && !(iface->proto_handler->flags & PROTO_FLAG_NODEV))
+       if (dev && !dev->hidden &&
+           !(iface->proto_handler->flags & PROTO_FLAG_NODEV))
                blobmsg_add_string(&b, "device", dev->ifname);
 
        if (iface->state == IFS_UP) {
                blobmsg_add_u32(&b, "metric", iface->metric);
                a = blobmsg_open_array(&b, "ipv4-address");
-               interface_ip_dump_address_list(&iface->config_ip, false);
-               interface_ip_dump_address_list(&iface->proto_ip, false);
+               interface_ip_dump_address_list(&iface->config_ip, false, true);
+               interface_ip_dump_address_list(&iface->proto_ip, false, true);
                blobmsg_close_array(&b, a);
                a = blobmsg_open_array(&b, "ipv6-address");
-               interface_ip_dump_address_list(&iface->config_ip, true);
-               interface_ip_dump_address_list(&iface->proto_ip, true);
+               interface_ip_dump_address_list(&iface->config_ip, true, true);
+               interface_ip_dump_address_list(&iface->proto_ip, true, true);
                blobmsg_close_array(&b, a);
                a = blobmsg_open_array(&b, "route");
-               interface_ip_dump_route_list(&iface->config_ip);
-               interface_ip_dump_route_list(&iface->proto_ip);
+               interface_ip_dump_route_list(&iface->config_ip, true);
+               interface_ip_dump_route_list(&iface->proto_ip, true);
                blobmsg_close_array(&b, a);
                a = blobmsg_open_array(&b, "dns-server");
-               interface_ip_dump_dns_server_list(&iface->config_ip);
-               interface_ip_dump_dns_server_list(&iface->proto_ip);
+               interface_ip_dump_dns_server_list(&iface->config_ip, true);
+               interface_ip_dump_dns_server_list(&iface->proto_ip, true);
                blobmsg_close_array(&b, a);
                a = blobmsg_open_array(&b, "dns-search");
-               interface_ip_dump_dns_search_list(&iface->config_ip);
-               interface_ip_dump_dns_search_list(&iface->proto_ip);
+               interface_ip_dump_dns_search_list(&iface->config_ip, true);
+               interface_ip_dump_dns_search_list(&iface->proto_ip, true);
                blobmsg_close_array(&b, a);
+
+               inactive = blobmsg_open_table(&b, "inactive");
+               a = blobmsg_open_array(&b, "ipv4-address");
+               interface_ip_dump_address_list(&iface->config_ip, false, false);
+               interface_ip_dump_address_list(&iface->proto_ip, false, false);
+               blobmsg_close_array(&b, a);
+               a = blobmsg_open_array(&b, "ipv6-address");
+               interface_ip_dump_address_list(&iface->config_ip, true, false);
+               interface_ip_dump_address_list(&iface->proto_ip, true, false);
+               blobmsg_close_array(&b, a);
+               a = blobmsg_open_array(&b, "route");
+               interface_ip_dump_route_list(&iface->config_ip, false);
+               interface_ip_dump_route_list(&iface->proto_ip, false);
+               blobmsg_close_array(&b, a);
+               a = blobmsg_open_array(&b, "dns-server");
+               interface_ip_dump_dns_server_list(&iface->config_ip, false);
+               interface_ip_dump_dns_server_list(&iface->proto_ip, false);
+               blobmsg_close_array(&b, a);
+               a = blobmsg_open_array(&b, "dns-search");
+               interface_ip_dump_dns_search_list(&iface->config_ip, false);
+               interface_ip_dump_dns_search_list(&iface->proto_ip, false);
+               blobmsg_close_array(&b, a);
+               blobmsg_close_table(&b, inactive);
        }
 
        a = blobmsg_open_table(&b, "data");
@@ -558,14 +592,23 @@ netifd_iface_handle_device(struct ubus_context *ctx, struct ubus_object *obj,
        device_lock();
 
        dev = device_get(blobmsg_data(tb[DEV_NAME]), add ? 2 : 0);
-       if (add && !dev)
-               return UBUS_STATUS_NOT_FOUND;
+       if (add && !dev) {
+               ret = UBUS_STATUS_NOT_FOUND;
+               goto out;
+       }
 
-       if (add)
-               return interface_add_link(iface, dev);
-       else
-               return interface_remove_link(iface, dev);
+       if (add) {
+               device_set_present(dev, true);
+               if (iface->device_config)
+                       device_set_config(dev, &simple_device_type, iface->config);
 
+               system_if_apply_settings(dev, &dev->settings);
+               ret = interface_add_link(iface, dev);
+       } else {
+               ret = interface_remove_link(iface, dev);
+       }
+
+out:
        device_unlock();
 
        return ret;
@@ -684,8 +727,7 @@ netifd_ubus_add_interface(struct interface *iface)
        struct ubus_object *obj = &iface->ubus;
        char *name = NULL;
 
-       asprintf(&name, "%s.interface.%s", main_object.name, iface->name);
-       if (!name)
+       if (asprintf(&name, "%s.interface.%s", main_object.name, iface->name) == -1)
                return;
 
        obj->name = name;