static int test_client_basic(sd_event *e) { sd_dhcp6_client *client; if (verbose) printf("* %s\n", __FUNCTION__); assert_se(sd_dhcp6_client_new(&client) >= 0); assert_se(client); assert_se(sd_dhcp6_client_attach_event(client, e, 0) >= 0); assert_se(sd_dhcp6_client_set_index(client, 15) == 0); assert_se(sd_dhcp6_client_set_index(client, -42) == -EINVAL); assert_se(sd_dhcp6_client_set_index(client, -1) == 0); assert_se(sd_dhcp6_client_set_index(client, 42) >= 0); assert_se(sd_dhcp6_client_set_mac(client, (const uint8_t *) &mac_addr, sizeof (mac_addr), ARPHRD_ETHER) >= 0); assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_CLIENTID) == -EINVAL); assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DNS_SERVERS) == -EEXIST); assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_NTP_SERVER) == -EEXIST); assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_SNTP_SERVERS) == -EEXIST); assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DOMAIN_LIST) == -EEXIST); assert_se(sd_dhcp6_client_set_request_option(client, 10) == -EINVAL); assert_se(sd_dhcp6_client_set_callback(client, NULL, NULL) >= 0); assert_se(sd_dhcp6_client_detach_event(client) >= 0); assert_se(!sd_dhcp6_client_unref(client)); return 0; }
int dhcp6_configure(Link *link) { sd_dhcp6_client *client = NULL; int r; assert(link); if (link->dhcp6_client) return 0; r = sd_dhcp6_client_new(&client); if (r < 0) return r; r = sd_dhcp6_client_attach_event(client, NULL, 0); if (r < 0) goto error; r = sd_dhcp6_client_set_information_request(client, true); if (r < 0) goto error; r = sd_dhcp6_client_set_mac(client, (const uint8_t *) &link->mac, sizeof (link->mac), ARPHRD_ETHER); if (r < 0) goto error; r = sd_dhcp6_client_set_iaid(client, link->network->iaid); if (r < 0) goto error; if (link->network->duid_type != _DUID_TYPE_INVALID) r = sd_dhcp6_client_set_duid(client, link->network->dhcp_duid_type, link->network->dhcp_duid, link->network->dhcp_duid_len); else r = sd_dhcp6_client_set_duid(client, link->manager->dhcp_duid_type, link->manager->dhcp_duid, link->manager->dhcp_duid_len); if (r < 0) goto error; r = sd_dhcp6_client_set_index(client, link->ifindex); if (r < 0) goto error; r = sd_dhcp6_client_set_callback(client, dhcp6_handler, link); if (r < 0) goto error; link->dhcp6_client = client; return 0; error: sd_dhcp6_client_unref(client); return r; }
int dhcp6_configure(Link *link) { sd_dhcp6_client *client = NULL; int r; const DUID *duid; assert(link); if (link->dhcp6_client) return 0; r = sd_dhcp6_client_new(&client); if (r < 0) return r; r = sd_dhcp6_client_attach_event(client, NULL, 0); if (r < 0) goto error; r = sd_dhcp6_client_set_mac(client, (const uint8_t *) &link->mac, sizeof (link->mac), ARPHRD_ETHER); if (r < 0) goto error; r = sd_dhcp6_client_set_iaid(client, link->network->iaid); if (r < 0) goto error; duid = link_duid(link); r = sd_dhcp6_client_set_duid(client, duid->type, duid->raw_data_len > 0 ? duid->raw_data : NULL, duid->raw_data_len); if (r < 0) goto error; r = dhcp6_set_hostname(client, link); if (r < 0) goto error; r = sd_dhcp6_client_set_ifindex(client, link->ifindex); if (r < 0) goto error; r = sd_dhcp6_client_set_callback(client, dhcp6_handler, link); if (r < 0) goto error; link->dhcp6_client = client; return 0; error: sd_dhcp6_client_unref(client); return r; }
static int test_client_solicit(sd_event *e) { sd_dhcp6_client *client; usec_t time_now = now(clock_boottime_or_monotonic()); struct in6_addr address = { { { 0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01 } } }; int val; if (verbose) printf("* %s\n", __FUNCTION__); assert_se(sd_dhcp6_client_new(&client) >= 0); assert_se(client); assert_se(sd_dhcp6_client_attach_event(client, e, 0) >= 0); assert_se(sd_dhcp6_client_set_ifindex(client, test_index) == 0); assert_se(sd_dhcp6_client_set_mac(client, (const uint8_t *) &mac_addr, sizeof (mac_addr), ARPHRD_ETHER) >= 0); assert_se(sd_dhcp6_client_set_fqdn(client, "host.lab.intra") == 1); assert_se(sd_dhcp6_client_get_information_request(client, &val) >= 0); assert_se(val == 0); assert_se(sd_dhcp6_client_set_information_request(client, 42) >= 0); assert_se(sd_dhcp6_client_get_information_request(client, &val) >= 0); assert_se(val); assert_se(sd_dhcp6_client_set_callback(client, test_client_information_cb, e) >= 0); assert_se(sd_event_add_time(e, &hangcheck, clock_boottime_or_monotonic(), time_now + 2 * USEC_PER_SEC, 0, test_hangcheck, NULL) >= 0); assert_se(sd_dhcp6_client_set_local_address(client, &address) >= 0); assert_se(sd_dhcp6_client_start(client) >= 0); sd_event_loop(e); hangcheck = sd_event_source_unref(hangcheck); assert_se(!sd_dhcp6_client_unref(client)); test_dhcp_fd[1] = safe_close(test_dhcp_fd[1]); return 0; }
static void dispose (GObject *object) { NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (object); g_clear_pointer (&priv->lease_file, g_free); if (priv->client4) { sd_dhcp_client_stop (priv->client4); sd_dhcp_client_unref (priv->client4); priv->client4 = NULL; } if (priv->client6) { sd_dhcp6_client_stop (priv->client6); sd_dhcp6_client_unref (priv->client6); priv->client6 = NULL; } G_OBJECT_CLASS (nm_dhcp_systemd_parent_class)->dispose (object); }
static int dhcp6_configure(Link *link, int event) { int r; bool information_request; assert_return(link, -EINVAL); assert_return(IN_SET(event, SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_TIMEOUT, SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_OTHER, SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_MANAGED), -EINVAL); link->dhcp6_configured = false; if (link->dhcp6_client) { r = sd_dhcp6_client_get_information_request(link->dhcp6_client, &information_request); if (r < 0) { log_link_warning_errno(link, r, "Could not get DHCPv6 Information request setting: %m"); goto error; } if (information_request && event != SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_OTHER) { r = sd_dhcp6_client_stop(link->dhcp6_client); if (r < 0) { log_link_warning_errno(link, r, "Could not stop DHCPv6 while setting Managed mode: %m"); goto error; } r = sd_dhcp6_client_set_information_request(link->dhcp6_client, false); if (r < 0) { log_link_warning_errno(link, r, "Could not unset DHCPv6 Information request: %m"); goto error; } } r = sd_dhcp6_client_start(link->dhcp6_client); if (r < 0 && r != -EALREADY) { log_link_warning_errno(link, r, "Could not restart DHCPv6: %m"); goto error; } if (r == -EALREADY) link->dhcp6_configured = true; return r; } r = sd_dhcp6_client_new(&link->dhcp6_client); if (r < 0) goto error; r = sd_dhcp6_client_attach_event(link->dhcp6_client, NULL, 0); if (r < 0) goto error; r = sd_dhcp6_client_set_mac(link->dhcp6_client, (const uint8_t *) &link->mac, sizeof (link->mac), ARPHRD_ETHER); if (r < 0) goto error; r = sd_dhcp6_client_set_index(link->dhcp6_client, link->ifindex); if (r < 0) goto error; r = sd_dhcp6_client_set_callback(link->dhcp6_client, dhcp6_handler, link); if (r < 0) goto error; if (event == SD_ICMP6_ND_EVENT_ROUTER_ADVERTISMENT_OTHER) { r = sd_dhcp6_client_set_information_request(link->dhcp6_client, true); if (r < 0) goto error; } r = sd_dhcp6_client_start(link->dhcp6_client); if (r < 0) goto error; return r; error: link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client); return r; }
static gboolean ip6_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const struct in6_addr *ll_addr, gboolean info_only, NMSettingIP6ConfigPrivacy privacy, const GByteArray *duid) { NMDhcpSystemd *self = NM_DHCP_SYSTEMD (client); NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (self); const char *iface = nm_dhcp_client_get_iface (client); const GByteArray *hwaddr; int r, i; g_assert (priv->client4 == NULL); g_assert (priv->client6 == NULL); g_return_val_if_fail (duid != NULL, FALSE); g_free (priv->lease_file); priv->lease_file = get_leasefile_path (iface, nm_dhcp_client_get_uuid (client), TRUE); priv->info_only = info_only; r = sd_dhcp6_client_new (&priv->client6); if (r < 0) { _LOGW ("failed to create client (%d)", r); return FALSE; } _LOGT ("dhcp-client6: set %p", priv->client4); if (info_only) sd_dhcp6_client_set_information_request (priv->client6, 1); /* NM stores the entire DUID which includes the uint16 "type", while systemd * wants the type passed separately from the following data. */ r = sd_dhcp6_client_set_duid (priv->client6, ntohs (((const guint16 *) duid->data)[0]), duid->data + 2, duid->len - 2); if (r < 0) { _LOGW ("failed to set DUID (%d)", r); return FALSE; } r = sd_dhcp6_client_attach_event (priv->client6, NULL, 0); if (r < 0) { _LOGW ("failed to attach event (%d)", r); goto error; } hwaddr = nm_dhcp_client_get_hw_addr (client); if (hwaddr) { r = sd_dhcp6_client_set_mac (priv->client6, hwaddr->data, hwaddr->len, get_arp_type (hwaddr)); if (r < 0) { _LOGW ("failed to set MAC address (%d)", r); goto error; } } r = sd_dhcp6_client_set_index (priv->client6, nm_dhcp_client_get_ifindex (client)); if (r < 0) { _LOGW ("failed to set ifindex (%d)", r); goto error; } r = sd_dhcp6_client_set_callback (priv->client6, dhcp6_event_cb, client); if (r < 0) { _LOGW ("failed to set callback (%d)", r); goto error; } /* Add requested options */ for (i = 0; dhcp6_requests[i].name; i++) { if (dhcp6_requests[i].include) sd_dhcp6_client_set_request_option (priv->client6, dhcp6_requests[i].num); } r = sd_dhcp6_client_set_local_address (priv->client6, ll_addr); if (r < 0) { _LOGW ("failed to set local address (%d)", r); goto error; } r = sd_dhcp6_client_start (priv->client6); if (r < 0) { _LOGW ("failed to start client (%d)", r); goto error; } return TRUE; error: sd_dhcp6_client_unref (priv->client6); priv->client6 = NULL; return FALSE; }
static int dhcp6_configure(Link *link, int event) { int r; bool information_request; assert_return(link, -EINVAL); if (link->dhcp6_client) { if (event != ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED) return 0; r = sd_dhcp6_client_get_information_request(link->dhcp6_client, &information_request); if (r < 0) { log_link_warning(link, "Could not get DHCPv6 Information request setting: %s", strerror(-r)); link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client); return r; } if (!information_request) return r; r = sd_dhcp6_client_set_information_request(link->dhcp6_client, false); if (r < 0) { log_link_warning(link, "Could not unset DHCPv6 Information request: %s", strerror(-r)); link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client); return r; } r = sd_dhcp6_client_start(link->dhcp6_client); if (r < 0) { log_link_warning(link, "Could not restart DHCPv6 after enabling Information request: %s", strerror(-r)); link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client); return r; } return r; } r = sd_dhcp6_client_new(&link->dhcp6_client); if (r < 0) return r; r = sd_dhcp6_client_attach_event(link->dhcp6_client, NULL, 0); if (r < 0) { link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client); return r; } r = sd_dhcp6_client_set_mac(link->dhcp6_client, (const uint8_t *) &link->mac, sizeof (link->mac), ARPHRD_ETHER); if (r < 0) { link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client); return r; } r = sd_dhcp6_client_set_index(link->dhcp6_client, link->ifindex); if (r < 0) { link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client); return r; } r = sd_dhcp6_client_set_callback(link->dhcp6_client, dhcp6_handler, link); if (r < 0) { link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client); return r; } if (event == ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER) { r = sd_dhcp6_client_set_information_request(link->dhcp6_client, true); if (r < 0) { link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client); return r; } } r = sd_dhcp6_client_start(link->dhcp6_client); if (r < 0) link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client); return r; }
static int test_client_basic(sd_event *e) { sd_dhcp6_client *client; int v; if (verbose) printf("* %s\n", __FUNCTION__); assert_se(sd_dhcp6_client_new(&client) >= 0); assert_se(client); assert_se(sd_dhcp6_client_attach_event(client, e, 0) >= 0); assert_se(sd_dhcp6_client_set_ifindex(client, 15) == 0); assert_se(sd_dhcp6_client_set_ifindex(client, -42) == -EINVAL); assert_se(sd_dhcp6_client_set_ifindex(client, -1) == 0); assert_se(sd_dhcp6_client_set_ifindex(client, 42) >= 0); assert_se(sd_dhcp6_client_set_mac(client, (const uint8_t *) &mac_addr, sizeof (mac_addr), ARPHRD_ETHER) >= 0); assert_se(sd_dhcp6_client_set_fqdn(client, "host") == 1); assert_se(sd_dhcp6_client_set_fqdn(client, "host.domain") == 1); assert_se(sd_dhcp6_client_set_fqdn(client, NULL) == 1); assert_se(sd_dhcp6_client_set_fqdn(client, "~host") == -EINVAL); assert_se(sd_dhcp6_client_set_fqdn(client, "~host.domain") == -EINVAL); assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_CLIENTID) == -EINVAL); assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DNS_SERVERS) == -EEXIST); assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_NTP_SERVER) == -EEXIST); assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_SNTP_SERVERS) == -EEXIST); assert_se(sd_dhcp6_client_set_request_option(client, SD_DHCP6_OPTION_DOMAIN_LIST) == -EEXIST); assert_se(sd_dhcp6_client_set_request_option(client, 10) == -EINVAL); assert_se(sd_dhcp6_client_set_information_request(client, 1) >= 0); v = 0; assert_se(sd_dhcp6_client_get_information_request(client, &v) >= 0); assert_se(v); assert_se(sd_dhcp6_client_set_information_request(client, 0) >= 0); v = 42; assert_se(sd_dhcp6_client_get_information_request(client, &v) >= 0); assert_se(v == 0); v = 0; assert_se(sd_dhcp6_client_get_address_request(client, &v) >= 0); assert_se(v); v = 0; assert_se(sd_dhcp6_client_set_address_request(client, 1) >= 0); assert_se(sd_dhcp6_client_get_address_request(client, &v) >= 0); assert_se(v); v = 42; assert_se(sd_dhcp6_client_set_address_request(client, 1) >= 0); assert_se(sd_dhcp6_client_get_address_request(client, &v) >= 0); assert_se(v); assert_se(sd_dhcp6_client_set_address_request(client, 1) >= 0); assert_se(sd_dhcp6_client_set_prefix_delegation(client, 1) >= 0); v = 0; assert_se(sd_dhcp6_client_get_address_request(client, &v) >= 0); assert_se(v); v = 0; assert_se(sd_dhcp6_client_get_prefix_delegation(client, &v) >= 0); assert_se(v); assert_se(sd_dhcp6_client_set_callback(client, NULL, NULL) >= 0); assert_se(sd_dhcp6_client_detach_event(client) >= 0); assert_se(!sd_dhcp6_client_unref(client)); return 0; }