]> git.ozlabs.org Git - petitboot/blobdiff - discover/device-handler.c
discover: Support IPv6 addresses
[petitboot] / discover / device-handler.c
index b8e933088b28f5c7eb3aed788287af48ab0df365..69bc050c7241925a215d2b28d2c77c26ff740e19 100644 (file)
@@ -935,13 +935,38 @@ static void set_default(struct device_handler *handler,
        default_timeout(handler);
 }
 
+static char *autoboot_option_desc(void *ctx, const struct autoboot_option *opt)
+{
+       const char *type, *val;
+
+       if (opt->boot_type == BOOT_DEVICE_TYPE) {
+               type = _("device type");
+               val = device_type_display_name(opt->type);
+       } else if (opt->boot_type == BOOT_DEVICE_UUID) {
+               type = _("device UUID");
+               val = opt->uuid;
+       } else {
+               type = _("unknown specifier");
+               val = NULL;
+       }
+
+       return talloc_asprintf(ctx, "%s = %s", type, val);
+}
+
 void device_handler_apply_temp_autoboot(struct device_handler *handler,
                struct autoboot_option *opt)
 {
        unsigned int i;
+       char *desc;
 
        handler->temp_autoboot = talloc_steal(handler, opt);
 
+       desc = autoboot_option_desc(handler, opt);
+       device_handler_status_info(handler,
+                       _("Applying temporary autoboot override: %s"),
+                       desc);
+       talloc_free(desc);
+
        if (!handler->autoboot_enabled)
                return;
 
@@ -1349,10 +1374,15 @@ int device_handler_dhcp(struct device_handler *handler,
                struct discover_device *dev, struct event *event)
 {
        struct discover_context *ctx;
+       const char *ip;
+
+       if (event_get_param(event, "ipv6"))
+               ip = event_get_param(event, "ipv6");
+       else
+               ip = event_get_param(event, "ip");
 
        device_handler_status_dev_info(handler, dev,
-                       _("Processing DHCP lease response (ip: %s)"),
-                       event_get_param(event, "ip"));
+                       _("Processing DHCP lease response (ip: %s)"), ip);
 
        pending_network_jobs_start();
 
@@ -1450,32 +1480,44 @@ void device_handler_update_config(struct device_handler *handler,
 static char *device_from_addr(void *ctx, struct pb_url *url)
 {
        char *ipaddr, *buf, *tok, *dev = NULL;
+       bool ipv6_route;
        const char *delim = " ";
-       struct sockaddr_in *ip;
-       struct sockaddr_in si;
+       struct sockaddr_in *ipv4;
+       struct sockaddr_in6 *ipv6;
        struct addrinfo *res;
        struct process *p;
        int rc;
 
-       /* Note: IPv4 only */
-       rc = inet_pton(AF_INET, url->host, &(si.sin_addr));
-       if (rc > 0) {
-               ipaddr = url->host;
-       } else {
-               /* need to turn hostname into a valid IP */
-               rc = getaddrinfo(url->host, NULL, NULL, &res);
-               if (rc) {
-                       pb_debug("%s: Invalid URL\n",__func__);
-                       return NULL;
-               }
+       /* Confirm url->host is either a valid hostname, or a
+        * valid IPv4 or IPv6 address */
+       rc = getaddrinfo(url->host, NULL, NULL, &res);
+       if (rc) {
+               pb_debug("%s: Invalid URL\n",__func__);
+               return NULL;
+       }
+
+       switch (res->ai_family) {
+       case AF_INET:   /* ipv4 */
                ipaddr = talloc_array(ctx,char,INET_ADDRSTRLEN);
-               ip = (struct sockaddr_in *) res->ai_addr;
-               inet_ntop(AF_INET, &(ip->sin_addr), ipaddr, INET_ADDRSTRLEN);
+               ipv4 = (struct sockaddr_in *) res->ai_addr;
+               inet_ntop(AF_INET, &(ipv4->sin_addr), ipaddr, INET_ADDRSTRLEN);
+               ipv6_route = false;
+               break;
+       case AF_INET6:  /* ipv6 */
+               ipaddr = talloc_array(ctx,char,INET6_ADDRSTRLEN);
+               ipv6 = (struct sockaddr_in6 *) res->ai_addr;
+               inet_ntop(AF_INET6, &(ipv6->sin6_addr), ipaddr, INET6_ADDRSTRLEN);
+               ipv6_route = true;
+               break;
+       default:        /* error */
                freeaddrinfo(res);
+               return NULL;
        }
+       freeaddrinfo(res);
 
        const char *argv[] = {
                pb_system_apps.ip,
+               ipv6_route ? "-6" : "-4",
                "route", "show", "to", "match",
                ipaddr,
                NULL