]> git.ozlabs.org Git - petitboot/blobdiff - discover/network.c
discover/network: Ensure dns config buffer contains a trailling nul
[petitboot] / discover / network.c
index 28e3a29cb2b3621beb3c7ea69c6a06927fc86fe0..edb7358b5c36618cc6ee46d94cb7e1fb2f789483 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <log/log.h>
 #include <list/list.h>
+#include <types/types.h>
 #include <talloc/talloc.h>
 #include <waiter/waiter.h>
 #include <pb-config/pb-config.h>
@@ -19,6 +20,8 @@
 
 #include "file.h"
 #include "network.h"
+#include "sysinfo.h"
+#include "device-handler.h"
 
 #define HWADDR_SIZE    6
 #define PIDFILE_BASE   (LOCAL_STATE_DIR "/petitboot/")
@@ -47,14 +50,16 @@ struct interface {
 
        struct list_item list;
        struct process *udhcpc_process;
+       struct discover_device *dev;
 };
 
 struct network {
-       struct list     interfaces;
-       struct waiter   *waiter;
-       int             netlink_sd;
-       bool            manual_config;
-       bool            dry_run;
+       struct list             interfaces;
+       struct device_handler   *handler;
+       struct waiter           *waiter;
+       int                     netlink_sd;
+       bool                    manual_config;
+       bool                    dry_run;
 };
 
 static const struct interface_config *find_config_by_hwaddr(
@@ -138,6 +143,24 @@ static int network_send_link_query(struct network *network)
        return 0;
 }
 
+static void add_interface(struct network *network,
+               struct interface *interface)
+{
+       list_add(&network->interfaces, &interface->list);
+       interface->dev = discover_device_create(network->handler,
+                                       interface->name);
+       interface->dev->device->type = DEVICE_TYPE_NETWORK;
+       device_handler_add_device(network->handler, interface->dev);
+}
+
+static void remove_interface(struct network *network,
+               struct interface *interface)
+{
+       device_handler_remove(network->handler, interface->dev);
+       list_remove(&interface->list);
+       talloc_free(interface);
+}
+
 static int interface_change(struct interface *interface, bool up)
 {
        const char *statestr = up ? "up" : "down";
@@ -325,6 +348,7 @@ static int network_handle_nlmsg(struct network *network, struct nlmsghdr *nlmsg)
        struct interface *interface;
        struct ifinfomsg *info;
        struct rtattr *attr;
+       unsigned int mtu;
        uint8_t ifaddr[6];
        char ifname[IFNAMSIZ+1];
        int attrlen, type;
@@ -355,19 +379,22 @@ static int network_handle_nlmsg(struct network *network, struct nlmsghdr *nlmsg)
                        strncpy(ifname, data, IFNAMSIZ);
                        have_ifname = true;
                        break;
+
+               case IFLA_MTU:
+                       mtu = *(unsigned int *)data;
+                       break;
                }
        }
 
        if (!have_ifaddr || !have_ifname)
                return -1;
 
-       if (type == RTM_DELLINK) {
+       if (type == RTM_DELLINK || mtu == 0) {
                interface = find_interface_by_ifindex(network, info->ifi_index);
                if (!interface)
                        return 0;
                pb_log("network: interface %s removed\n", interface->name);
-               list_remove(&interface->list);
-               talloc_free(interface);
+               remove_interface(network, interface);
                return 0;
        }
 
@@ -379,6 +406,13 @@ static int network_handle_nlmsg(struct network *network, struct nlmsghdr *nlmsg)
                interface->state = IFSTATE_NEW;
                memcpy(interface->hwaddr, ifaddr, sizeof(interface->hwaddr));
                strncpy(interface->name, ifname, sizeof(interface->name) - 1);
+               add_interface(network, interface);
+
+               /* tell the sysinfo code about this interface */
+               if (strcmp(interface->name, "lo"))
+                       system_info_register_interface(
+                                       sizeof(interface->hwaddr),
+                                       interface->hwaddr, interface->name);
        }
 
        configure_interface(network, interface,
@@ -446,9 +480,10 @@ static void network_init_dns(struct network *network)
                }
 
                dns_conf_len = strlen(dns_conf);
-               buf = talloc_realloc(network, buf, char, len + dns_conf_len);
+               buf = talloc_realloc(network, buf, char, len + dns_conf_len + 1);
                memcpy(buf + len, dns_conf, dns_conf_len);
                len += dns_conf_len;
+               buf[len - 1] = '\0';
                modified = true;
 
                talloc_free(dns_conf);
@@ -464,13 +499,15 @@ static void network_init_dns(struct network *network)
        talloc_free(buf);
 }
 
-struct network *network_init(void *ctx, struct waitset *waitset, bool dry_run)
+struct network *network_init(struct device_handler *handler,
+               struct waitset *waitset, bool dry_run)
 {
        struct network *network;
        int rc;
 
-       network = talloc(ctx, struct network);
+       network = talloc(handler, struct network);
        list_init(&network->interfaces);
+       network->handler = handler;
        network->manual_config = false;
        network->dry_run = dry_run;