[PATCH 6/7] discover: Support IPv6 addresses
Samuel Mendoza-Jonas
sam at mendozajonas.com
Wed May 9 15:37:04 AEST 2018
Support handling IPv6 addresses from user events and call the udhcpc6
client if configured to use IPv6 addresses.
Signed-off-by: Samuel Mendoza-Jonas <sam at mendozajonas.com>
---
discover/device-handler.c | 51 ++++++++++++++++++++++++++-------------
discover/network.c | 40 ++++++++++++++++++++++++------
discover/user-event.c | 8 ++++--
3 files changed, 73 insertions(+), 26 deletions(-)
diff --git a/discover/device-handler.c b/discover/device-handler.c
index 569e652..4164409 100644
--- a/discover/device-handler.c
+++ b/discover/device-handler.c
@@ -1167,10 +1167,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();
@@ -1265,32 +1270,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
diff --git a/discover/network.c b/discover/network.c
index e2cae91..c81c5e6 100644
--- a/discover/network.c
+++ b/discover/network.c
@@ -322,10 +322,11 @@ static void configure_interface_dhcp(struct network *network,
struct interface *interface)
{
const struct platform *platform;
+ const struct config *config = config_get();
char pidfile[256], id[10];
struct process *process;
int rc;
- const char *argv[] = {
+ const char *argv_ipv4[] = {
pb_system_apps.udhcpc,
"-R",
"-f",
@@ -337,6 +338,20 @@ static void configure_interface_dhcp(struct network *network,
NULL,
};
+ const char *argv_ipv6[] = {
+ pb_system_apps.udhcpc6,
+ "-R",
+ "-f",
+ "-O", "bootfile_url",
+ "-O", "bootfile_param",
+ "-O", "pxeconffile",
+ "-O", "pxepathprefix",
+ "-p", pidfile,
+ "-i", interface->name,
+ "-x", id, /* [15,16] - dhcp client identifier */
+ NULL,
+ };
+
device_handler_status_dev_info(network->handler, interface->dev,
_("Configuring with DHCP"));
@@ -344,15 +359,26 @@ static void configure_interface_dhcp(struct network *network,
PIDFILE_BASE, interface->name);
platform = platform_get();
- if (platform && platform->dhcp_arch_id != 0xffff)
- snprintf(id, sizeof(id), "0x5d:%04x", platform->dhcp_arch_id);
- else
- argv[11] = NULL;
+ if (platform && platform->dhcp_arch_id != 0xffff) {
+ if (config->network.addr_type == ADDR_IPV6)
+ snprintf(id, sizeof(id), "0x3d:%04x",
+ platform->dhcp_arch_id);
+ else
+ snprintf(id, sizeof(id), "0x5d:%04x",
+ platform->dhcp_arch_id);
+ } else {
+ argv_ipv4[11] = argv_ipv6[15] = NULL;
+ }
process = process_create(interface);
- process->path = pb_system_apps.udhcpc;
- process->argv = argv;
+ if (config->network.addr_type == ADDR_IPV6) {
+ process->path = pb_system_apps.udhcpc6;
+ process->argv = argv_ipv6;
+ } else {
+ process->path = pb_system_apps.udhcpc;
+ process->argv = argv_ipv4;
+ }
process->exit_cb = udhcpc_process_exit;
process->data = interface;
diff --git a/discover/user-event.c b/discover/user-event.c
index 77d28c1..59e0717 100644
--- a/discover/user-event.c
+++ b/discover/user-event.c
@@ -395,8 +395,12 @@ static int user_event_dhcp(struct user_event *uev, struct event *event)
hwaddr, hwaddr + 1, hwaddr + 2,
hwaddr + 3, hwaddr + 4, hwaddr + 5);
- system_info_set_interface_address(sizeof(hwaddr), hwaddr,
- event_get_param(event, "ip"));
+ if (event_get_param(event, "ipv6"))
+ system_info_set_interface_address(sizeof(hwaddr), hwaddr,
+ event_get_param(event, "ipv6"));
+ else
+ system_info_set_interface_address(sizeof(hwaddr), hwaddr,
+ event_get_param(event, "ip"));
dev = discover_device_create(handler, event_get_param(event, "mac"),
event->device);
--
2.17.0
More information about the Petitboot
mailing list