summary refs log tree commit diff
path: root/src/nm-iface-helper.c
diff options
context:
space:
mode:
authorMichael Biebl <biebl@debian.org>2020-10-05 22:27:18 +0200
committerMichael Biebl <biebl@debian.org>2020-10-05 22:27:18 +0200
commitaafc1dbe4712c86189bbc1d4d54ad8cb4c69be7e (patch)
treea2a9bb4d007339a0b1304540388230ccedac32bd /src/nm-iface-helper.c
parente7b44ef4c80907346ec7492a09c45277459924fc (diff)
New upstream version 1.27.90 upstream/1.27.90
Diffstat (limited to 'src/nm-iface-helper.c')
-rw-r--r--src/nm-iface-helper.c1266
1 files changed, 708 insertions, 558 deletions
diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c
index c7d65d2a..e5d85967 100644
--- a/src/nm-iface-helper.c
+++ b/src/nm-iface-helper.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+/* SPDX-License-Identifier: GPL-2.0+ */
 /*
  * Copyright (C) 2014 Red Hat, Inc.
  */
@@ -31,7 +31,7 @@
 #include "systemd/nm-sd.h"
 
 #if !defined(NM_DIST_VERSION)
-# define NM_DIST_VERSION VERSION
+    #define NM_DIST_VERSION VERSION
 #endif
 
 #define NMIH_PID_FILE_FMT NMRUNDIR "/nm-iface-helper-%d.pid"
@@ -39,584 +39,738 @@
 /*****************************************************************************/
 
 static struct {
-	GMainLoop *main_loop;
-	int ifindex;
-	gboolean is_vrf_device;
-
-	guint dad_failed_id;
-	CList dad_failed_lst_head;
-} gl/*obal*/ = {
-	.ifindex = -1,
-	.is_vrf_device = FALSE,
+    GMainLoop *main_loop;
+    int        ifindex;
+    gboolean   is_vrf_device;
+
+    guint dad_failed_id;
+    CList dad_failed_lst_head;
+} gl /*obal*/ = {
+    .ifindex       = -1,
+    .is_vrf_device = FALSE,
 };
 
 static struct {
-	gboolean slaac;
-	gboolean show_version;
-	gboolean become_daemon;
-	gboolean debug;
-	gboolean g_fatal_warnings;
-	gboolean slaac_required;
-	gboolean dhcp4_required;
-	int tempaddr;
-	char *ifname;
-	char *uuid;
-	char *stable_id;
-	char *dhcp4_address;
-	char *dhcp4_clientid;
-	char *dhcp4_hostname;
-	char *dhcp4_fqdn;
-	char *mud_url;
-	char *iid_str;
-	NMSettingIP6ConfigAddrGenMode addr_gen_mode;
-	char *logging_backend;
-	char *opt_log_level;
-	char *opt_log_domains;
-	guint32 priority_v4;
-	guint32 priority_v6;
+    gboolean                      slaac;
+    gboolean                      show_version;
+    gboolean                      become_daemon;
+    gboolean                      debug;
+    gboolean                      g_fatal_warnings;
+    gboolean                      slaac_required;
+    gboolean                      dhcp4_required;
+    int                           tempaddr;
+    char *                        ifname;
+    char *                        uuid;
+    char *                        stable_id;
+    char *                        dhcp4_address;
+    char *                        dhcp4_clientid;
+    char *                        dhcp4_hostname;
+    char *                        dhcp4_fqdn;
+    char *                        mud_url;
+    char *                        iid_str;
+    NMSettingIP6ConfigAddrGenMode addr_gen_mode;
+    char *                        logging_backend;
+    char *                        opt_log_level;
+    char *                        opt_log_domains;
+    guint32                       priority_v4;
+    guint32                       priority_v6;
 } global_opt = {
-	.tempaddr = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN,
-	.priority_v4 = NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP4,
-	.priority_v6 = NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP6,
+    .tempaddr    = NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN,
+    .priority_v4 = NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP4,
+    .priority_v6 = NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP6,
 };
 
 /*****************************************************************************/
 
-#define _NMLOG_PREFIX_NAME      "nm-iface-helper"
+#define _NMLOG_PREFIX_NAME "nm-iface-helper"
 #define _NMLOG(level, domain, ...) \
-    nm_log ((level), (domain), global_opt.ifname, NULL, \
-            "iface-helper: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__) \
-            _NM_UTILS_MACRO_REST (__VA_ARGS__))
+    nm_log((level),                \
+           (domain),               \
+           global_opt.ifname,      \
+           NULL,                   \
+           "iface-helper: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__) _NM_UTILS_MACRO_REST(__VA_ARGS__))
 
 /*****************************************************************************/
 
 static void
-dhcp4_state_changed (NMDhcpClient *client,
-                     NMDhcpState state,
-                     NMIP4Config *ip4_config,
-                     GHashTable *options,
-                     const char *event_id,
-                     gpointer user_data)
+dhcp4_state_changed(NMDhcpClient *client,
+                    NMDhcpState   state,
+                    NMIP4Config * ip4_config,
+                    GHashTable *  options,
+                    gpointer      user_data)
 {
-	static NMIP4Config *last_config = NULL;
-	NMIP4Config *existing;
-	gs_unref_ptrarray GPtrArray *ip4_dev_route_blacklist = NULL;
-	gs_free_error GError *error = NULL;
-
-	g_return_if_fail (!ip4_config || NM_IS_IP4_CONFIG (ip4_config));
-
-	_LOGD (LOGD_DHCP4, "new DHCPv4 client state %d", state);
-
-	switch (state) {
-	case NM_DHCP_STATE_BOUND:
-	case NM_DHCP_STATE_EXTENDED:
-		g_assert (ip4_config);
-		g_assert (nm_ip4_config_get_ifindex (ip4_config) == gl.ifindex);
-
-		existing = nm_ip4_config_capture (nm_platform_get_multi_idx (NM_PLATFORM_GET),
-		                                  NM_PLATFORM_GET, gl.ifindex);
-		if (last_config)
-			nm_ip4_config_subtract (existing, last_config, 0);
-
-		nm_ip4_config_merge (existing, ip4_config, NM_IP_CONFIG_MERGE_DEFAULT, 0);
-		nm_ip4_config_add_dependent_routes (existing,
-		                                    RT_TABLE_MAIN,
-		                                    global_opt.priority_v4,
-		                                    gl.is_vrf_device,
-		                                    &ip4_dev_route_blacklist);
-		if (!nm_ip4_config_commit (existing,
-		                           NM_PLATFORM_GET,
-		                           NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN))
-			_LOGW (LOGD_DHCP4, "failed to apply DHCPv4 config");
-
-		if (!last_config && !nm_dhcp_client_accept (client, &error))
-			_LOGW (LOGD_DHCP4, "failed to accept lease: %s", error->message);
-
-		nm_platform_ip4_dev_route_blacklist_set (NM_PLATFORM_GET,
-		                                         gl.ifindex,
-		                                         ip4_dev_route_blacklist);
-
-		if (last_config)
-			g_object_unref (last_config);
-		last_config = nm_ip4_config_new (nm_platform_get_multi_idx (NM_PLATFORM_GET),
-		                                 nm_dhcp_client_get_ifindex (client));
-		nm_ip4_config_replace (last_config, ip4_config, NULL);
-		break;
-	case NM_DHCP_STATE_TIMEOUT:
-	case NM_DHCP_STATE_DONE:
-	case NM_DHCP_STATE_FAIL:
-		if (global_opt.dhcp4_required) {
-			_LOGW (LOGD_DHCP4, "DHCPv4 timed out or failed, quitting...");
-			g_main_loop_quit (gl.main_loop);
-		} else
-			_LOGW (LOGD_DHCP4, "DHCPv4 timed out or failed");
-		break;
-	default:
-		break;
-	}
+    static NMIP4Config *last_config = NULL;
+    NMIP4Config *       existing;
+    gs_unref_ptrarray GPtrArray *ip4_dev_route_blacklist = NULL;
+    gs_free_error GError *error                          = NULL;
+
+    g_return_if_fail(!ip4_config || NM_IS_IP4_CONFIG(ip4_config));
+
+    _LOGD(LOGD_DHCP4, "new DHCPv4 client state %d", state);
+
+    switch (state) {
+    case NM_DHCP_STATE_BOUND:
+    case NM_DHCP_STATE_EXTENDED:
+        g_assert(ip4_config);
+        g_assert(nm_ip4_config_get_ifindex(ip4_config) == gl.ifindex);
+
+        existing = nm_ip4_config_capture(nm_platform_get_multi_idx(NM_PLATFORM_GET),
+                                         NM_PLATFORM_GET,
+                                         gl.ifindex);
+        if (last_config)
+            nm_ip4_config_subtract(existing, last_config, 0);
+
+        nm_ip4_config_merge(existing, ip4_config, NM_IP_CONFIG_MERGE_DEFAULT, 0);
+        nm_ip4_config_add_dependent_routes(existing,
+                                           RT_TABLE_MAIN,
+                                           global_opt.priority_v4,
+                                           gl.is_vrf_device,
+                                           &ip4_dev_route_blacklist);
+        if (!nm_ip4_config_commit(existing, NM_PLATFORM_GET, NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN))
+            _LOGW(LOGD_DHCP4, "failed to apply DHCPv4 config");
+
+        if (!last_config && !nm_dhcp_client_accept(client, &error))
+            _LOGW(LOGD_DHCP4, "failed to accept lease: %s", error->message);
+
+        nm_platform_ip4_dev_route_blacklist_set(NM_PLATFORM_GET,
+                                                gl.ifindex,
+                                                ip4_dev_route_blacklist);
+
+        if (last_config)
+            g_object_unref(last_config);
+        last_config = nm_ip4_config_new(nm_platform_get_multi_idx(NM_PLATFORM_GET),
+                                        nm_dhcp_client_get_ifindex(client));
+        nm_ip4_config_replace(last_config, ip4_config, NULL);
+        break;
+    case NM_DHCP_STATE_TIMEOUT:
+    case NM_DHCP_STATE_DONE:
+    case NM_DHCP_STATE_FAIL:
+        if (global_opt.dhcp4_required) {
+            _LOGW(LOGD_DHCP4, "DHCPv4 timed out or failed, quitting...");
+            g_main_loop_quit(gl.main_loop);
+        } else
+            _LOGW(LOGD_DHCP4, "DHCPv4 timed out or failed");
+        break;
+    default:
+        break;
+    }
 }
 
 static void
-ndisc_config_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_int, gpointer user_data)
+ndisc_config_changed(NMNDisc *          ndisc,
+                     const NMNDiscData *rdata,
+                     guint              changed_int,
+                     gpointer           user_data)
 {
-	NMNDiscConfigMap changed = changed_int;
-	static NMIP6Config *ndisc_config = NULL;
-	NMIP6Config *existing;
-
-	existing = nm_ip6_config_capture (nm_platform_get_multi_idx (NM_PLATFORM_GET),
-	                                  NM_PLATFORM_GET, gl.ifindex, global_opt.tempaddr);
-	if (ndisc_config)
-		nm_ip6_config_subtract (existing, ndisc_config, 0);
-	else {
-		ndisc_config = nm_ip6_config_new (nm_platform_get_multi_idx (NM_PLATFORM_GET),
-		                                  gl.ifindex);
-	}
-
-	if (changed & NM_NDISC_CONFIG_ADDRESSES) {
-		guint8 plen;
-		guint32 ifa_flags;
-
-		/* Check, whether kernel is recent enough to help user space handling RA.
-		 * If it's not supported, we have no ipv6-privacy and must add autoconf
-		 * addresses as /128. The reason for the /128 is to prevent the kernel
-		 * from adding a prefix route for this address. */
-		ifa_flags = 0;
-		if (nm_platform_kernel_support_get (NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS)) {
-			ifa_flags |= IFA_F_NOPREFIXROUTE;
-			if (NM_IN_SET (global_opt.tempaddr, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR,
-			                                    NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR))
-				ifa_flags |= IFA_F_MANAGETEMPADDR;
-			plen = 64;
-		} else
-			plen = 128;
-
-		nm_ip6_config_reset_addresses_ndisc (ndisc_config,
-		                                     rdata->addresses,
-		                                     rdata->addresses_n,
-		                                     plen,
-		                                     ifa_flags);
-	}
-
-	if (NM_FLAGS_ANY (changed,  NM_NDISC_CONFIG_ROUTES
-	                          | NM_NDISC_CONFIG_GATEWAYS)) {
-		nm_ip6_config_reset_routes_ndisc (ndisc_config,
-		                                  rdata->gateways,
-		                                  rdata->gateways_n,
-		                                  rdata->routes,
-		                                  rdata->routes_n,
-		                                  RT_TABLE_MAIN,
-		                                  global_opt.priority_v6,
-		                                  nm_platform_kernel_support_get (NM_PLATFORM_KERNEL_SUPPORT_TYPE_RTA_PREF));
-	}
-
-	if (changed & NM_NDISC_CONFIG_DHCP_LEVEL) {
-		/* Unsupported until systemd DHCPv6 is ready */
-	}
-
-	if (changed & NM_NDISC_CONFIG_HOP_LIMIT)
-		nm_platform_sysctl_ip_conf_set_ipv6_hop_limit_safe (NM_PLATFORM_GET, global_opt.ifname, rdata->hop_limit);
-
-	if (changed & NM_NDISC_CONFIG_REACHABLE_TIME) {
-		nm_platform_sysctl_ip_neigh_set_ipv6_reachable_time (NM_PLATFORM_GET,
-		                                                     global_opt.ifname,
-		                                                     rdata->reachable_time_ms);
-	}
-
-	if (changed & NM_NDISC_CONFIG_RETRANS_TIMER) {
-		nm_platform_sysctl_ip_neigh_set_ipv6_retrans_time (NM_PLATFORM_GET,
-		                                                   global_opt.ifname,
-		                                                   rdata->retrans_timer_ms);
-	}
-
-	if (changed & NM_NDISC_CONFIG_MTU) {
-		nm_platform_sysctl_ip_conf_set_int64 (NM_PLATFORM_GET,
-		                                      AF_INET6,
-		                                      global_opt.ifname,
-		                                      "mtu",
-		                                      rdata->mtu);
-	}
-
-	nm_ip6_config_merge (existing, ndisc_config, NM_IP_CONFIG_MERGE_DEFAULT, 0);
-	nm_ip6_config_add_dependent_routes (existing,
-	                                    RT_TABLE_MAIN,
-	                                    global_opt.priority_v6,
-	                                    gl.is_vrf_device);
-	if (!nm_ip6_config_commit (existing,
-	                           NM_PLATFORM_GET,
-	                           NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN,
-	                           NULL))
-		_LOGW (LOGD_IP6, "failed to apply IPv6 config");
+    NMNDiscConfigMap    changed      = changed_int;
+    static NMIP6Config *ndisc_config = NULL;
+    NMIP6Config *       existing;
+
+    existing = nm_ip6_config_capture(nm_platform_get_multi_idx(NM_PLATFORM_GET),
+                                     NM_PLATFORM_GET,
+                                     gl.ifindex,
+                                     global_opt.tempaddr);
+    if (ndisc_config)
+        nm_ip6_config_subtract(existing, ndisc_config, 0);
+    else {
+        ndisc_config = nm_ip6_config_new(nm_platform_get_multi_idx(NM_PLATFORM_GET), gl.ifindex);
+    }
+
+    if (changed & NM_NDISC_CONFIG_ADDRESSES) {
+        guint8  plen;
+        guint32 ifa_flags;
+
+        /* Check, whether kernel is recent enough to help user space handling RA.
+         * If it's not supported, we have no ipv6-privacy and must add autoconf
+         * addresses as /128. The reason for the /128 is to prevent the kernel
+         * from adding a prefix route for this address. */
+        ifa_flags = 0;
+        if (nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_EXTENDED_IFA_FLAGS)) {
+            ifa_flags |= IFA_F_NOPREFIXROUTE;
+            if (NM_IN_SET(global_opt.tempaddr,
+                          NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR,
+                          NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR))
+                ifa_flags |= IFA_F_MANAGETEMPADDR;
+            plen = 64;
+        } else
+            plen = 128;
+
+        nm_ip6_config_reset_addresses_ndisc(ndisc_config,
+                                            rdata->addresses,
+                                            rdata->addresses_n,
+                                            plen,
+                                            ifa_flags);
+    }
+
+    if (NM_FLAGS_ANY(changed, NM_NDISC_CONFIG_ROUTES | NM_NDISC_CONFIG_GATEWAYS)) {
+        nm_ip6_config_reset_routes_ndisc(
+            ndisc_config,
+            rdata->gateways,
+            rdata->gateways_n,
+            rdata->routes,
+            rdata->routes_n,
+            RT_TABLE_MAIN,
+            global_opt.priority_v6,
+            nm_platform_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_RTA_PREF));
+    }
+
+    if (changed & NM_NDISC_CONFIG_DHCP_LEVEL) {
+        /* Unsupported until systemd DHCPv6 is ready */
+    }
+
+    if (changed & NM_NDISC_CONFIG_HOP_LIMIT)
+        nm_platform_sysctl_ip_conf_set_ipv6_hop_limit_safe(NM_PLATFORM_GET,
+                                                           global_opt.ifname,
+                                                           rdata->hop_limit);
+
+    if (changed & NM_NDISC_CONFIG_REACHABLE_TIME) {
+        nm_platform_sysctl_ip_neigh_set_ipv6_reachable_time(NM_PLATFORM_GET,
+                                                            global_opt.ifname,
+                                                            rdata->reachable_time_ms);
+    }
+
+    if (changed & NM_NDISC_CONFIG_RETRANS_TIMER) {
+        nm_platform_sysctl_ip_neigh_set_ipv6_retrans_time(NM_PLATFORM_GET,
+                                                          global_opt.ifname,
+                                                          rdata->retrans_timer_ms);
+    }
+
+    if (changed & NM_NDISC_CONFIG_MTU) {
+        nm_platform_sysctl_ip_conf_set_int64(NM_PLATFORM_GET,
+                                             AF_INET6,
+                                             global_opt.ifname,
+                                             "mtu",
+                                             rdata->mtu);
+    }
+
+    nm_ip6_config_merge(existing, ndisc_config, NM_IP_CONFIG_MERGE_DEFAULT, 0);
+    nm_ip6_config_add_dependent_routes(existing,
+                                       RT_TABLE_MAIN,
+                                       global_opt.priority_v6,
+                                       gl.is_vrf_device);
+    if (!nm_ip6_config_commit(existing, NM_PLATFORM_GET, NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN, NULL))
+        _LOGW(LOGD_IP6, "failed to apply IPv6 config");
 }
 
 static void
-ndisc_ra_timeout (NMNDisc *ndisc, gpointer user_data)
+ndisc_ra_timeout(NMNDisc *ndisc, gpointer user_data)
 {
-	if (global_opt.slaac_required) {
-		_LOGW (LOGD_IP6, "IPv6 timed out or failed, quitting...");
-		g_main_loop_quit (gl.main_loop);
-	} else
-		_LOGW (LOGD_IP6, "IPv6 timed out or failed");
+    if (global_opt.slaac_required) {
+        _LOGW(LOGD_IP6, "IPv6 timed out or failed, quitting...");
+        g_main_loop_quit(gl.main_loop);
+    } else
+        _LOGW(LOGD_IP6, "IPv6 timed out or failed");
 }
 
 static gboolean
-quit_handler (gpointer user_data)
+quit_handler(gpointer user_data)
 {
-	g_main_loop_quit (gl.main_loop);
-	return G_SOURCE_REMOVE;
+    g_main_loop_quit(gl.main_loop);
+    return G_SOURCE_REMOVE;
 }
 
 static void
-setup_signals (void)
+setup_signals(void)
 {
-	signal (SIGPIPE, SIG_IGN);
-	g_unix_signal_add (SIGINT, quit_handler, NULL);
-	g_unix_signal_add (SIGTERM, quit_handler, NULL);
+    signal(SIGPIPE, SIG_IGN);
+    g_unix_signal_add(SIGINT, quit_handler, NULL);
+    g_unix_signal_add(SIGTERM, quit_handler, NULL);
 }
 
 static gboolean
-do_early_setup (int *argc, char **argv[])
+do_early_setup(int *argc, char **argv[])
 {
-	gint64 priority64_v4 = -1;
-	gint64 priority64_v6 = -1;
-	GOptionEntry options[] = {
-		/* Interface/IP config */
-		{ "ifname", 'i', 0, G_OPTION_ARG_STRING, &global_opt.ifname, N_("The interface to manage"), "eth0" },
-		{ "uuid", 'u', 0, G_OPTION_ARG_STRING, &global_opt.uuid, N_("Connection UUID"),  "661e8cd0-b618-46b8-9dc9-31a52baaa16b" },
-		{ "stable-id", '\0', 0, G_OPTION_ARG_STRING, &global_opt.stable_id, N_("Connection Token for Stable IDs"),  "eth" },
-		{ "slaac", 's', 0, G_OPTION_ARG_NONE, &global_opt.slaac, N_("Whether to manage IPv6 SLAAC"), NULL },
-		{ "slaac-required", '6', 0, G_OPTION_ARG_NONE, &global_opt.slaac_required, N_("Whether SLAAC must be successful"), NULL },
-		{ "slaac-tempaddr", 't', 0, G_OPTION_ARG_INT, &global_opt.tempaddr, N_("Use an IPv6 temporary privacy address"), NULL },
-		{ "dhcp4", 'd', 0, G_OPTION_ARG_STRING, &global_opt.dhcp4_address, N_("Current DHCPv4 address"), NULL },
-		{ "dhcp4-required", '4', 0, G_OPTION_ARG_NONE, &global_opt.dhcp4_required, N_("Whether DHCPv4 must be successful"), NULL },
-		{ "dhcp4-clientid", 'c', 0, G_OPTION_ARG_STRING, &global_opt.dhcp4_clientid, N_("Hex-encoded DHCPv4 client ID"), NULL },
-		{ "dhcp4-hostname", 'h', 0, G_OPTION_ARG_STRING, &global_opt.dhcp4_hostname, N_("Hostname to send to DHCP server"), N_("barbar") },
-		{ "dhcp4-fqdn",     'F', 0, G_OPTION_ARG_STRING, &global_opt.dhcp4_fqdn, N_("FQDN to send to DHCP server"), N_("host.domain.org") },
-		{ "priority4", '\0', 0, G_OPTION_ARG_INT64, &priority64_v4, N_("Route priority for IPv4"), N_("0") },
-		{ "priority6", '\0', 0, G_OPTION_ARG_INT64, &priority64_v6, N_("Route priority for IPv6"), N_("1024") },
-		{ "iid", 'e', 0, G_OPTION_ARG_STRING, &global_opt.iid_str, N_("Hex-encoded Interface Identifier"), "" },
-		{ "addr-gen-mode", 'e', 0, G_OPTION_ARG_INT, &global_opt.addr_gen_mode, N_("IPv6 SLAAC address generation mode"), "eui64" },
-		{ "logging-backend", '\0', 0, G_OPTION_ARG_STRING, &global_opt.logging_backend, N_("The logging backend configuration value. See logging.backend in NetworkManager.conf"), NULL },
-
-		/* Logging/debugging */
-		{ "version", 'V', 0, G_OPTION_ARG_NONE, &global_opt.show_version, N_("Print NetworkManager version and exit"), NULL },
-		{ "no-daemon", 'n', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &global_opt.become_daemon, N_("Don't become a daemon"), NULL },
-		{ "debug", 'b', 0, G_OPTION_ARG_NONE, &global_opt.debug, N_("Don't become a daemon, and log to stderr"), NULL },
-		{ "log-level", 0, 0, G_OPTION_ARG_STRING, &global_opt.opt_log_level, N_("Log level: one of [%s]"), "INFO" },
-		{ "log-domains", 0, 0, G_OPTION_ARG_STRING, &global_opt.opt_log_domains,
-		  N_("Log domains separated by ',': any combination of [%s]"),
-		  "PLATFORM,RFKILL,WIFI" },
-		{ "g-fatal-warnings", 0, 0, G_OPTION_ARG_NONE, &global_opt.g_fatal_warnings, N_("Make all warnings fatal"), NULL },
-		{NULL}
-	};
-
-	if (!nm_main_utils_early_setup ("nm-iface-helper",
-	                                argc,
-	                                argv,
-	                                options,
-	                                NULL,
-	                                NULL,
-	                                _("nm-iface-helper is a small, standalone process that manages a single network interface.")))
-		return FALSE;
-
-	if (priority64_v4 >= 0 && priority64_v4 <= G_MAXUINT32)
-		global_opt.priority_v4 = (guint32) priority64_v4;
-	if (priority64_v6 >= 0 && priority64_v6 <= G_MAXUINT32)
-		global_opt.priority_v6 = (guint32) priority64_v6;
-	return TRUE;
+    gint64       priority64_v4 = -1;
+    gint64       priority64_v6 = -1;
+    GOptionEntry options[]     = {
+        /* Interface/IP config */
+        {"ifname",
+         'i',
+         0,
+         G_OPTION_ARG_STRING,
+         &global_opt.ifname,
+         N_("The interface to manage"),
+         "eth0"},
+        {"uuid",
+         'u',
+         0,
+         G_OPTION_ARG_STRING,
+         &global_opt.uuid,
+         N_("Connection UUID"),
+         "661e8cd0-b618-46b8-9dc9-31a52baaa16b"},
+        {"stable-id",
+         '\0',
+         0,
+         G_OPTION_ARG_STRING,
+         &global_opt.stable_id,
+         N_("Connection Token for Stable IDs"),
+         "eth"},
+        {"slaac",
+         's',
+         0,
+         G_OPTION_ARG_NONE,
+         &global_opt.slaac,
+         N_("Whether to manage IPv6 SLAAC"),
+         NULL},
+        {"slaac-required",
+         '6',
+         0,
+         G_OPTION_ARG_NONE,
+         &global_opt.slaac_required,
+         N_("Whether SLAAC must be successful"),
+         NULL},
+        {"slaac-tempaddr",
+         't',
+         0,
+         G_OPTION_ARG_INT,
+         &global_opt.tempaddr,
+         N_("Use an IPv6 temporary privacy address"),
+         NULL},
+        {"dhcp4",
+         'd',
+         0,
+         G_OPTION_ARG_STRING,
+         &global_opt.dhcp4_address,
+         N_("Current DHCPv4 address"),
+         NULL},
+        {"dhcp4-required",
+         '4',
+         0,
+         G_OPTION_ARG_NONE,
+         &global_opt.dhcp4_required,
+         N_("Whether DHCPv4 must be successful"),
+         NULL},
+        {"dhcp4-clientid",
+         'c',
+         0,
+         G_OPTION_ARG_STRING,
+         &global_opt.dhcp4_clientid,
+         N_("Hex-encoded DHCPv4 client ID"),
+         NULL},
+        {"dhcp4-hostname",
+         'h',
+         0,
+         G_OPTION_ARG_STRING,
+         &global_opt.dhcp4_hostname,
+         N_("Hostname to send to DHCP server"),
+         N_("barbar")},
+        {"dhcp4-fqdn",
+         'F',
+         0,
+         G_OPTION_ARG_STRING,
+         &global_opt.dhcp4_fqdn,
+         N_("FQDN to send to DHCP server"),
+         N_("host.domain.org")},
+        {"priority4",
+         '\0',
+         0,
+         G_OPTION_ARG_INT64,
+         &priority64_v4,
+         N_("Route priority for IPv4"),
+         N_("0")},
+        {"priority6",
+         '\0',
+         0,
+         G_OPTION_ARG_INT64,
+         &priority64_v6,
+         N_("Route priority for IPv6"),
+         N_("1024")},
+        {"iid",
+         'e',
+         0,
+         G_OPTION_ARG_STRING,
+         &global_opt.iid_str,
+         N_("Hex-encoded Interface Identifier"),
+         ""},
+        {"addr-gen-mode",
+         'e',
+         0,
+         G_OPTION_ARG_INT,
+         &global_opt.addr_gen_mode,
+         N_("IPv6 SLAAC address generation mode"),
+         "eui64"},
+        {"logging-backend",
+         '\0',
+         0,
+         G_OPTION_ARG_STRING,
+         &global_opt.logging_backend,
+         N_("The logging backend configuration value. See logging.backend in NetworkManager.conf"),
+         NULL},
+
+        /* Logging/debugging */
+        {"version",
+         'V',
+         0,
+         G_OPTION_ARG_NONE,
+         &global_opt.show_version,
+         N_("Print NetworkManager version and exit"),
+         NULL},
+        {"no-daemon",
+         'n',
+         G_OPTION_FLAG_REVERSE,
+         G_OPTION_ARG_NONE,
+         &global_opt.become_daemon,
+         N_("Don't become a daemon"),
+         NULL},
+        {"debug",
+         'b',
+         0,
+         G_OPTION_ARG_NONE,
+         &global_opt.debug,
+         N_("Don't become a daemon, and log to stderr"),
+         NULL},
+        {"log-level",
+         0,
+         0,
+         G_OPTION_ARG_STRING,
+         &global_opt.opt_log_level,
+         N_("Log level: one of [%s]"),
+         "INFO"},
+        {"log-domains",
+         0,
+         0,
+         G_OPTION_ARG_STRING,
+         &global_opt.opt_log_domains,
+         N_("Log domains separated by ',': any combination of [%s]"),
+         "PLATFORM,RFKILL,WIFI"},
+        {"g-fatal-warnings",
+         0,
+         0,
+         G_OPTION_ARG_NONE,
+         &global_opt.g_fatal_warnings,
+         N_("Make all warnings fatal"),
+         NULL},
+        {NULL}};
+
+    if (!nm_main_utils_early_setup("nm-iface-helper",
+                                   argc,
+                                   argv,
+                                   options,
+                                   NULL,
+                                   NULL,
+                                   _("nm-iface-helper is a small, standalone process that manages "
+                                     "a single network interface.")))
+        return FALSE;
+
+    if (priority64_v4 >= 0 && priority64_v4 <= G_MAXUINT32)
+        global_opt.priority_v4 = (guint32) priority64_v4;
+    if (priority64_v6 >= 0 && priority64_v6 <= G_MAXUINT32)
+        global_opt.priority_v6 = (guint32) priority64_v6;
+    return TRUE;
 }
 
 typedef struct {
-	NMPlatform *platform;
-	NMNDisc *ndisc;
+    NMPlatform *platform;
+    NMNDisc *   ndisc;
 } DadFailedHandleData;
 
 static gboolean
-dad_failed_handle_idle (gpointer user_data)
+dad_failed_handle_idle(gpointer user_data)
 {
-	DadFailedHandleData *data = user_data;
-	NMCListElem *elem;
+    DadFailedHandleData *data = user_data;
+    NMCListElem *        elem;
 
-	while ((elem = c_list_first_entry (&gl.dad_failed_lst_head, NMCListElem, lst))) {
-		nm_auto_nmpobj const NMPObject *obj = elem->data;
+    while ((elem = c_list_first_entry(&gl.dad_failed_lst_head, NMCListElem, lst))) {
+        nm_auto_nmpobj const NMPObject *obj = elem->data;
 
-		nm_c_list_elem_free (elem);
+        nm_c_list_elem_free(elem);
 
-		if (nm_ndisc_dad_addr_is_fail_candidate (data->platform, obj)) {
-			nm_ndisc_dad_failed (data->ndisc,
-			                     &NMP_OBJECT_CAST_IP6_ADDRESS (obj)->address,
-			                     TRUE);
-		}
-	}
+        if (nm_ndisc_dad_addr_is_fail_candidate(data->platform, obj)) {
+            nm_ndisc_dad_failed(data->ndisc, &NMP_OBJECT_CAST_IP6_ADDRESS(obj)->address, TRUE);
+        }
+    }
 
-	gl.dad_failed_id = 0;
-	return G_SOURCE_REMOVE;
+    gl.dad_failed_id = 0;
+    return G_SOURCE_REMOVE;
 }
 
 static void
-ip6_address_changed (NMPlatform *platform,
-                     int obj_type_i,
-                     int iface,
-                     const NMPlatformIP6Address *addr,
-                     int change_type_i,
-                     NMNDisc *ndisc)
+ip6_address_changed(NMPlatform *                platform,
+                    int                         obj_type_i,
+                    int                         iface,
+                    const NMPlatformIP6Address *addr,
+                    int                         change_type_i,
+                    NMNDisc *                   ndisc)
 {
-	const NMPlatformSignalChangeType change_type = change_type_i;
-	DadFailedHandleData *data;
-
-	if (!nm_ndisc_dad_addr_is_fail_candidate_event (change_type, addr))
-		return;
-
-	c_list_link_tail (&gl.dad_failed_lst_head,
-	                  &nm_c_list_elem_new_stale ((gpointer) nmp_object_ref (NMP_OBJECT_UP_CAST (addr)))->lst);
-	if (gl.dad_failed_id)
-		return;
-
-	data = g_slice_new (DadFailedHandleData);
-	data->platform = platform;
-	data->ndisc = ndisc;
-	gl.dad_failed_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
-	                                    dad_failed_handle_idle,
-	                                    data,
-	                                    nm_g_slice_free_fcn (DadFailedHandleData));
+    const NMPlatformSignalChangeType change_type = change_type_i;
+    DadFailedHandleData *            data;
+
+    if (!nm_ndisc_dad_addr_is_fail_candidate_event(change_type, addr))
+        return;
+
+    c_list_link_tail(
+        &gl.dad_failed_lst_head,
+        &nm_c_list_elem_new_stale((gpointer) nmp_object_ref(NMP_OBJECT_UP_CAST(addr)))->lst);
+    if (gl.dad_failed_id)
+        return;
+
+    data             = g_slice_new(DadFailedHandleData);
+    data->platform   = platform;
+    data->ndisc      = ndisc;
+    gl.dad_failed_id = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,
+                                       dad_failed_handle_idle,
+                                       data,
+                                       nm_g_slice_free_fcn(DadFailedHandleData));
 }
 
 int
-main (int argc, char *argv[])
+main(int argc, char *argv[])
 {
-	char *bad_domains = NULL;
-	gs_free_error GError *error = NULL;
-	gboolean wrote_pidfile = FALSE;
-	gs_free char *pidfile = NULL;
-	gs_unref_object NMDhcpClient *dhcp4_client = NULL;
-	gs_unref_object NMNDisc *ndisc = NULL;
-	gs_unref_bytes GBytes *hwaddr = NULL;
-	gs_unref_bytes GBytes *bcast_hwaddr = NULL;
-	gs_unref_bytes GBytes *client_id = NULL;
-	gs_free NMUtilsIPv6IfaceId *iid = NULL;
-	const NMPlatformLink *pllink;
-	guint sd_id;
-	int errsv;
-
-	c_list_init (&gl.dad_failed_lst_head);
-
-	setpgid (getpid (), getpid ());
-
-	if (!do_early_setup (&argc, &argv))
-		return 1;
-
-	nm_logging_init_pre ("nm-iface-helper",
-	                     g_strdup_printf ("%s[%ld] (%s): ",
-	                                      _NMLOG_PREFIX_NAME,
-	                                      (long) getpid (),
-	                                      global_opt.ifname ?: "???"));
-
-	if (global_opt.g_fatal_warnings) {
-		GLogLevelFlags fatal_mask;
-
-		fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
-		fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
-		g_log_set_always_fatal (fatal_mask);
-	}
-
-	if (global_opt.show_version) {
-		fprintf (stdout, NM_DIST_VERSION "\n");
-		return 0;
-	}
-
-	nm_main_utils_ensure_root ();
-
-	if (!global_opt.ifname || !global_opt.uuid) {
-		fprintf (stderr, _("An interface name and UUID are required\n"));
-		return 1;
-	}
-
-	gl.ifindex = nmp_utils_if_nametoindex (global_opt.ifname);
-	if (gl.ifindex <= 0) {
-		errsv = errno;
-		fprintf (stderr, _("Failed to find interface index for %s (%s)\n"), global_opt.ifname, nm_strerror_native (errsv));
-		return 1;
-	}
-	pidfile = g_strdup_printf (NMIH_PID_FILE_FMT, gl.ifindex);
-	nm_main_utils_ensure_not_running_pidfile (pidfile);
-
-	nm_main_utils_ensure_rundir ();
-
-	if (!nm_logging_setup (global_opt.opt_log_level,
-	                       global_opt.opt_log_domains,
-	                       &bad_domains,
-	                       &error)) {
-		fprintf (stderr,
-		         _("%s.  Please use --help to see a list of valid options.\n"),
-		         error->message);
-		return 1;
-	} else if (bad_domains) {
-		fprintf (stderr,
-		         _("Ignoring unrecognized log domain(s) '%s' passed on command line.\n"),
-		         bad_domains);
-		nm_clear_g_free (&bad_domains);
-	}
-
-	if (global_opt.become_daemon && !global_opt.debug) {
-		if (daemon (0, 0) < 0) {
-			errsv = errno;
-			fprintf (stderr, _("Could not daemonize: %s [error %u]\n"),
-			         nm_strerror_native (errsv),
-			         errsv);
-			return 1;
-		}
-		if (nm_main_utils_write_pidfile (pidfile))
-			wrote_pidfile = TRUE;
-	}
-
-	/* Set up unix signal handling - before creating threads, but after daemonizing! */
-	gl.main_loop = g_main_loop_new (NULL, FALSE);
-	setup_signals ();
-
-	nm_logging_init (global_opt.logging_backend,
-	                 global_opt.debug);
-
-	_LOGI (LOGD_CORE, "nm-iface-helper (version " NM_DIST_VERSION ") is starting...");
-
-	/* Set up platform interaction layer */
-	nm_linux_platform_setup ();
-
-	pllink = nm_platform_link_get (NM_PLATFORM_GET, gl.ifindex);
-	if (pllink) {
-		hwaddr = nmp_link_address_get_as_bytes (&pllink->l_address);
-		bcast_hwaddr = nmp_link_address_get_as_bytes (&pllink->l_broadcast);
-
-		if (pllink->master > 0) {
-			gl.is_vrf_device
-			    = nm_platform_link_get_type (NM_PLATFORM_GET, pllink->master) == NM_LINK_TYPE_VRF;
-		}
-	}
-
-	if (global_opt.iid_str) {
-		GBytes *bytes;
-		gsize ignored = 0;
-
-		bytes = nm_utils_hexstr2bin (global_opt.iid_str);
-		if (!bytes || g_bytes_get_size (bytes) != sizeof (*iid)) {
-			fprintf (stderr, _("(%s): Invalid IID %s\n"), global_opt.ifname, global_opt.iid_str);
-			return 1;
-		}
-		iid = g_bytes_unref_to_data (bytes, &ignored);
-	}
-
-	if (global_opt.dhcp4_clientid) {
-		/* this string is just a plain hex-string. Unlike ipv4.dhcp-client-id, which
-		 * is parsed via nm_dhcp_utils_client_id_string_to_bytes(). */
-		client_id = nm_utils_hexstr2bin (global_opt.dhcp4_clientid);
-		if (!client_id || g_bytes_get_size (client_id) < 2) {
-			fprintf (stderr, _("(%s): Invalid DHCP client-id %s\n"), global_opt.ifname, global_opt.dhcp4_clientid);
-			return 1;
-		}
-	}
-
-	if (global_opt.dhcp4_address) {
-		nm_platform_sysctl_ip_conf_set (NM_PLATFORM_GET,
-		                                AF_INET,
-		                                global_opt.ifname,
-		                                "promote_secondaries",
-		                                "1");
-
-		dhcp4_client = nm_dhcp_manager_start_ip4 (nm_dhcp_manager_get (),
-		                                          nm_platform_get_multi_idx (NM_PLATFORM_GET),
-		                                          global_opt.ifname,
-		                                          gl.ifindex,
-		                                          hwaddr,
-		                                          bcast_hwaddr,
-		                                          global_opt.uuid,
-		                                          RT_TABLE_MAIN,
-		                                          global_opt.priority_v4,
-		                                          !!global_opt.dhcp4_hostname,
-		                                          global_opt.dhcp4_hostname,
-		                                          global_opt.dhcp4_fqdn,
-		                                          NM_DHCP_HOSTNAME_FLAGS_FQDN_DEFAULT_IP4,
-		                                          global_opt.mud_url,
-		                                          client_id,
-		                                          NM_DHCP_TIMEOUT_DEFAULT,
-		                                          NULL,
-		                                          global_opt.dhcp4_address,
-		                                          &error);
-		if (!dhcp4_client)
-			g_error ("failure to start DHCP: %s", error->message);
-
-		g_signal_connect (dhcp4_client,
-		                  NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED,
-		                  G_CALLBACK (dhcp4_state_changed),
-		                  NULL);
-	}
-
-	if (global_opt.slaac) {
-		NMUtilsStableType stable_type = NM_UTILS_STABLE_TYPE_UUID;
-		const char *stable_id = global_opt.uuid;
-
-		nm_platform_link_set_user_ipv6ll_enabled (NM_PLATFORM_GET, gl.ifindex, TRUE);
-
-		if (   global_opt.stable_id
-		    && (global_opt.stable_id[0] >= '0' && global_opt.stable_id[0] <= '9')
-		    && global_opt.stable_id[1] == ' ') {
-			/* strict parsing of --stable-id, which is the numeric stable-type
-			 * and the ID, joined with one space. For now, only support stable-types
-			 * from 0 to 9. */
-			stable_type = (global_opt.stable_id[0] - '0');
-			stable_id = &global_opt.stable_id[2];
-		}
-		ndisc = nm_lndp_ndisc_new (NM_PLATFORM_GET,
-		                           gl.ifindex,
-		                           global_opt.ifname,
-		                           stable_type,
-		                           stable_id,
-		                           global_opt.addr_gen_mode,
-		                           NM_NDISC_NODE_TYPE_HOST,
-		                           NM_RA_TIMEOUT_DEFAULT,
-		                           NULL);
-		g_assert (ndisc);
-
-		if (iid)
-			nm_ndisc_set_iid (ndisc, *iid);
-
-		nm_platform_sysctl_ip_conf_set (NM_PLATFORM_GET, AF_INET6, global_opt.ifname, "accept_ra", "0");
-
-		g_signal_connect (NM_PLATFORM_GET,
-		                  NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED,
-		                  G_CALLBACK (ip6_address_changed),
-		                  ndisc);
-		g_signal_connect (ndisc,
-		                  NM_NDISC_CONFIG_RECEIVED,
-		                  G_CALLBACK (ndisc_config_changed),
-		                  NULL);
-		g_signal_connect (ndisc,
-		                  NM_NDISC_RA_TIMEOUT_SIGNAL,
-		                  G_CALLBACK (ndisc_ra_timeout),
-		                  NULL);
-		nm_ndisc_start (ndisc);
-	}
-
-	sd_id = nm_sd_event_attach_default ();
-
-	g_main_loop_run (gl.main_loop);
-
-	nm_clear_g_source (&gl.dad_failed_id);
-	nm_c_list_elem_free_all (&gl.dad_failed_lst_head, (GDestroyNotify) nmp_object_unref);
-
-	if (pidfile && wrote_pidfile)
-		unlink (pidfile);
-
-	_LOGI (LOGD_CORE, "exiting");
-
-	nm_clear_g_source (&sd_id);
-	nm_clear_pointer (&gl.main_loop, g_main_loop_unref);
-	return 0;
+    char *        bad_domains                  = NULL;
+    gs_free_error GError *error                = NULL;
+    gboolean              wrote_pidfile        = FALSE;
+    gs_free char *        pidfile              = NULL;
+    gs_unref_object NMDhcpClient *dhcp4_client = NULL;
+    gs_unref_object NMNDisc *ndisc             = NULL;
+    gs_unref_bytes GBytes *hwaddr              = NULL;
+    gs_unref_bytes GBytes *bcast_hwaddr        = NULL;
+    gs_unref_bytes GBytes *client_id           = NULL;
+    gs_free NMUtilsIPv6IfaceId *iid            = NULL;
+    const NMPlatformLink *      pllink;
+    guint                       sd_id;
+    int                         errsv;
+
+    c_list_init(&gl.dad_failed_lst_head);
+
+    setpgid(getpid(), getpid());
+
+    if (!do_early_setup(&argc, &argv))
+        return 1;
+
+    nm_logging_init_pre("nm-iface-helper",
+                        g_strdup_printf("%s[%ld] (%s): ",
+                                        _NMLOG_PREFIX_NAME,
+                                        (long) getpid(),
+                                        global_opt.ifname ?: "???"));
+
+    if (global_opt.g_fatal_warnings) {
+        GLogLevelFlags fatal_mask;
+
+        fatal_mask = g_log_set_always_fatal(G_LOG_FATAL_MASK);
+        fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
+        g_log_set_always_fatal(fatal_mask);
+    }
+
+    if (global_opt.show_version) {
+        fprintf(stdout, NM_DIST_VERSION "\n");
+        return 0;
+    }
+
+    nm_main_utils_ensure_root();
+
+    if (!global_opt.ifname || !global_opt.uuid) {
+        fprintf(stderr, _("An interface name and UUID are required\n"));
+        return 1;
+    }
+
+    gl.ifindex = nmp_utils_if_nametoindex(global_opt.ifname);
+    if (gl.ifindex <= 0) {
+        errsv = errno;
+        fprintf(stderr,
+                _("Failed to find interface index for %s (%s)\n"),
+                global_opt.ifname,
+                nm_strerror_native(errsv));
+        return 1;
+    }
+    pidfile = g_strdup_printf(NMIH_PID_FILE_FMT, gl.ifindex);
+    nm_main_utils_ensure_not_running_pidfile(pidfile);
+
+    nm_main_utils_ensure_rundir();
+
+    if (!nm_logging_setup(global_opt.opt_log_level,
+                          global_opt.opt_log_domains,
+                          &bad_domains,
+                          &error)) {
+        fprintf(stderr,
+                _("%s.  Please use --help to see a list of valid options.\n"),
+                error->message);
+        return 1;
+    } else if (bad_domains) {
+        fprintf(stderr,
+                _("Ignoring unrecognized log domain(s) '%s' passed on command line.\n"),
+                bad_domains);
+        nm_clear_g_free(&bad_domains);
+    }
+
+    if (global_opt.become_daemon && !global_opt.debug) {
+        if (daemon(0, 0) < 0) {
+            errsv = errno;
+            fprintf(stderr,
+                    _("Could not daemonize: %s [error %u]\n"),
+                    nm_strerror_native(errsv),
+                    errsv);
+            return 1;
+        }
+        if (nm_main_utils_write_pidfile(pidfile))
+            wrote_pidfile = TRUE;
+    }
+
+    /* Set up unix signal handling - before creating threads, but after daemonizing! */
+    gl.main_loop = g_main_loop_new(NULL, FALSE);
+    setup_signals();
+
+    nm_logging_init(global_opt.logging_backend, global_opt.debug);
+
+    _LOGI(LOGD_CORE, "nm-iface-helper (version " NM_DIST_VERSION ") is starting...");
+
+    /* Set up platform interaction layer */
+    nm_linux_platform_setup();
+
+    pllink = nm_platform_link_get(NM_PLATFORM_GET, gl.ifindex);
+    if (pllink) {
+        hwaddr       = nmp_link_address_get_as_bytes(&pllink->l_address);
+        bcast_hwaddr = nmp_link_address_get_as_bytes(&pllink->l_broadcast);
+
+        if (pllink->master > 0) {
+            gl.is_vrf_device =
+                nm_platform_link_get_type(NM_PLATFORM_GET, pllink->master) == NM_LINK_TYPE_VRF;
+        }
+    }
+
+    if (global_opt.iid_str) {
+        GBytes *bytes;
+        gsize   ignored = 0;
+
+        bytes = nm_utils_hexstr2bin(global_opt.iid_str);
+        if (!bytes || g_bytes_get_size(bytes) != sizeof(*iid)) {
+            fprintf(stderr, _("(%s): Invalid IID %s\n"), global_opt.ifname, global_opt.iid_str);
+            return 1;
+        }
+        iid = g_bytes_unref_to_data(bytes, &ignored);
+    }
+
+    if (global_opt.dhcp4_clientid) {
+        /* this string is just a plain hex-string. Unlike ipv4.dhcp-client-id, which
+         * is parsed via nm_dhcp_utils_client_id_string_to_bytes(). */
+        client_id = nm_utils_hexstr2bin(global_opt.dhcp4_clientid);
+        if (!client_id || g_bytes_get_size(client_id) < 2) {
+            fprintf(stderr,
+                    _("(%s): Invalid DHCP client-id %s\n"),
+                    global_opt.ifname,
+                    global_opt.dhcp4_clientid);
+            return 1;
+        }
+    }
+
+    if (global_opt.dhcp4_address) {
+        nm_platform_sysctl_ip_conf_set(NM_PLATFORM_GET,
+                                       AF_INET,
+                                       global_opt.ifname,
+                                       "promote_secondaries",
+                                       "1");
+
+        dhcp4_client = nm_dhcp_manager_start_ip4(nm_dhcp_manager_get(),
+                                                 nm_platform_get_multi_idx(NM_PLATFORM_GET),
+                                                 global_opt.ifname,
+                                                 gl.ifindex,
+                                                 hwaddr,
+                                                 bcast_hwaddr,
+                                                 global_opt.uuid,
+                                                 RT_TABLE_MAIN,
+                                                 global_opt.priority_v4,
+                                                 !!global_opt.dhcp4_hostname,
+                                                 global_opt.dhcp4_hostname,
+                                                 global_opt.dhcp4_fqdn,
+                                                 NM_DHCP_HOSTNAME_FLAGS_FQDN_DEFAULT_IP4,
+                                                 global_opt.mud_url,
+                                                 client_id,
+                                                 NM_DHCP_TIMEOUT_DEFAULT,
+                                                 NULL,
+                                                 global_opt.dhcp4_address,
+                                                 NULL,
+                                                 NULL,
+                                                 &error);
+        if (!dhcp4_client)
+            g_error("failure to start DHCP: %s", error->message);
+
+        g_signal_connect(dhcp4_client,
+                         NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED,
+                         G_CALLBACK(dhcp4_state_changed),
+                         NULL);
+    }
+
+    if (global_opt.slaac) {
+        NMUtilsStableType stable_type = NM_UTILS_STABLE_TYPE_UUID;
+        const char *      stable_id   = global_opt.uuid;
+        int               router_solicitation_interval;
+        int               router_solicitations;
+        guint32           default_ra_timeout;
+        int               max_addresses;
+
+        nm_platform_link_set_user_ipv6ll_enabled(NM_PLATFORM_GET, gl.ifindex, TRUE);
+
+        if (global_opt.stable_id
+            && (global_opt.stable_id[0] >= '0' && global_opt.stable_id[0] <= '9')
+            && global_opt.stable_id[1] == ' ') {
+            /* strict parsing of --stable-id, which is the numeric stable-type
+             * and the ID, joined with one space. For now, only support stable-types
+             * from 0 to 9. */
+            stable_type = (global_opt.stable_id[0] - '0');
+            stable_id   = &global_opt.stable_id[2];
+        }
+
+        nm_lndp_ndisc_get_sysctl(NM_PLATFORM_GET,
+                                 global_opt.ifname,
+                                 &max_addresses,
+                                 &router_solicitations,
+                                 &router_solicitation_interval,
+                                 &default_ra_timeout);
+
+        ndisc = nm_lndp_ndisc_new(NM_PLATFORM_GET,
+                                  gl.ifindex,
+                                  global_opt.ifname,
+                                  stable_type,
+                                  stable_id,
+                                  global_opt.addr_gen_mode,
+                                  NM_NDISC_NODE_TYPE_HOST,
+                                  max_addresses,
+                                  router_solicitations,
+                                  router_solicitation_interval,
+                                  default_ra_timeout,
+                                  NULL);
+        g_assert(ndisc);
+
+        if (iid)
+            nm_ndisc_set_iid(ndisc, *iid);
+
+        nm_platform_sysctl_ip_conf_set(NM_PLATFORM_GET,
+                                       AF_INET6,
+                                       global_opt.ifname,
+                                       "accept_ra",
+                                       "0");
+
+        g_signal_connect(NM_PLATFORM_GET,
+                         NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED,
+                         G_CALLBACK(ip6_address_changed),
+                         ndisc);
+        g_signal_connect(ndisc, NM_NDISC_CONFIG_RECEIVED, G_CALLBACK(ndisc_config_changed), NULL);
+        g_signal_connect(ndisc, NM_NDISC_RA_TIMEOUT_SIGNAL, G_CALLBACK(ndisc_ra_timeout), NULL);
+        nm_ndisc_start(ndisc);
+    }
+
+    sd_id = nm_sd_event_attach_default();
+
+    g_main_loop_run(gl.main_loop);
+
+    nm_clear_g_source(&gl.dad_failed_id);
+    nm_c_list_elem_free_all(&gl.dad_failed_lst_head, (GDestroyNotify) nmp_object_unref);
+
+    if (pidfile && wrote_pidfile)
+        unlink(pidfile);
+
+    _LOGI(LOGD_CORE, "exiting");
+
+    nm_clear_g_source(&sd_id);
+    nm_clear_pointer(&gl.main_loop, g_main_loop_unref);
+    return 0;
 }
 
 /*****************************************************************************/
 
 const NMDhcpClientFactory *const _nm_dhcp_manager_factories[6] = {
-	/* For nm-iface-helper there is no option to choose a DHCP plugin.
-	 * It just uses the "internal" one. */
-	&_nm_dhcp_client_factory_internal,
+    /* For nm-iface-helper there is no option to choose a DHCP plugin.
+     * It just uses the "internal" one. */
+    &_nm_dhcp_client_factory_internal,
 };
 
 /*****************************************************************************/
@@ -628,81 +782,77 @@ const NMDhcpClientFactory *const _nm_dhcp_manager_factories[6] = {
 #include "nm-dbus-manager.h"
 
 void
-nm_main_config_reload (int signal)
+nm_main_config_reload(int signal)
 {
-	_LOGI (LOGD_CORE, "reloading configuration not supported");
+    _LOGI(LOGD_CORE, "reloading configuration not supported");
 }
 
 NMConfig *
-nm_config_get (void)
+nm_config_get(void)
 {
-	return GUINT_TO_POINTER (1);
+    return GUINT_TO_POINTER(1);
 }
 
 NMConfigData *
-nm_config_get_data_orig (NMConfig *config)
+nm_config_get_data_orig(NMConfig *config)
 {
-	return GUINT_TO_POINTER (1);
+    return GUINT_TO_POINTER(1);
 }
 
 char *
-nm_config_data_get_value (const NMConfigData *config_data, const char *group, const char *key, NMConfigGetValueFlags flags)
+nm_config_data_get_value(const NMConfigData *  config_data,
+                         const char *          group,
+                         const char *          key,
+                         NMConfigGetValueFlags flags)
 {
-	return NULL;
+    return NULL;
 }
 
 NMConfigConfigureAndQuitType
-nm_config_get_configure_and_quit (NMConfig *config)
+nm_config_get_configure_and_quit(NMConfig *config)
 {
-	return NM_CONFIG_CONFIGURE_AND_QUIT_ENABLED;
+    return NM_CONFIG_CONFIGURE_AND_QUIT_ENABLED;
 }
 
 NMDBusManager *
-nm_dbus_manager_get (void)
+nm_dbus_manager_get(void)
 {
-	return NULL;
+    return NULL;
 }
 
 gboolean
-nm_dbus_manager_is_stopping (NMDBusManager *self)
+nm_dbus_manager_is_stopping(NMDBusManager *self)
 {
-	return FALSE;
+    return FALSE;
 }
 
 void
-_nm_dbus_manager_obj_export (NMDBusObject *obj)
-{
-}
+_nm_dbus_manager_obj_export(NMDBusObject *obj)
+{}
 
 void
-_nm_dbus_manager_obj_unexport (NMDBusObject *obj)
-{
-}
+_nm_dbus_manager_obj_unexport(NMDBusObject *obj)
+{}
 
 void
-_nm_dbus_manager_obj_notify (NMDBusObject *obj,
-                             guint n_pspecs,
-                             const GParamSpec *const*pspecs)
-{
-}
+_nm_dbus_manager_obj_notify(NMDBusObject *obj, guint n_pspecs, const GParamSpec *const *pspecs)
+{}
 
 void
-_nm_dbus_manager_obj_emit_signal (NMDBusObject *obj,
-                                  const NMDBusInterfaceInfoExtended *interface_info,
-                                  const GDBusSignalInfo *signal_info,
-                                  GVariant *args)
-{
-}
+_nm_dbus_manager_obj_emit_signal(NMDBusObject *                     obj,
+                                 const NMDBusInterfaceInfoExtended *interface_info,
+                                 const GDBusSignalInfo *            signal_info,
+                                 GVariant *                         args)
+{}
 
 GType
-nm_device_get_type (void)
+nm_device_get_type(void)
 {
-	g_return_val_if_reached (0);
+    g_return_val_if_reached(0);
 }
 
 GType
-nm_active_connection_get_type (void)
+nm_active_connection_get_type(void)
 {
-	g_return_val_if_reached (0);
+    g_return_val_if_reached(0);
 }
-