dhcp: drop internal systemd DHCPv4 client

This is long replaced by nettools' n-dhcp4 client.
Drop it.

We still require NMDhcpSystemd for the DHCPv6 client.

Note that "[main].dhcp=systemd" now falls back to the internal client.
But this option was undocumented and internal anyway.
This commit is contained in:
Thomas Haller 2022-04-08 17:37:41 +02:00
parent b1575e814f
commit 54119d4105
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
9 changed files with 10 additions and 776 deletions

View file

@ -2333,8 +2333,6 @@ src_libnm_systemd_core_libnm_systemd_core_la_SOURCES = \
src/libnm-systemd-core/nm-sd-utils-core.h \
src/libnm-systemd-core/nm-sd.c \
src/libnm-systemd-core/nm-sd.h \
src/libnm-systemd-core/nm-sd-utils-dhcp.h \
src/libnm-systemd-core/nm-sd-utils-dhcp.c \
src/libnm-systemd-core/sd-adapt-core/condition.h \
src/libnm-systemd-core/sd-adapt-core/conf-parser.h \
src/libnm-systemd-core/sd-adapt-core/device-util.h \

3
NEWS
View file

@ -8,6 +8,9 @@ subject to change and not guaranteed to be compatible with
the later release.
USE AT YOUR OWN RISK. NOT RECOMMENDED FOR PRODUCTION USE!
* Drop unused, internal systemd DHCPv4 client. This is long
replaced by nettools' n-dhcp4 implementation.
=============================================
NetworkManager-1.38
Overview of changes since NetworkManager-1.36

View file

@ -25,7 +25,6 @@
#include "libnm-platform/nm-platform.h"
#include "nm-dhcp-client-logging.h"
#include "libnm-systemd-core/nm-sd.h"
#include "libnm-systemd-core/nm-sd-utils-dhcp.h"
/*****************************************************************************/
@ -47,7 +46,6 @@ static GType nm_dhcp_systemd_get_type(void);
/*****************************************************************************/
typedef struct {
sd_dhcp_client *client4;
sd_dhcp6_client *client6;
char *lease_file;
@ -69,675 +67,6 @@ G_DEFINE_TYPE(NMDhcpSystemd, nm_dhcp_systemd, NM_TYPE_DHCP_CLIENT)
/*****************************************************************************/
static NML3ConfigData *
lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
const char *iface,
int ifindex,
sd_dhcp_lease *lease,
GError **error)
{
nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
gs_unref_hashtable GHashTable *options = NULL;
const struct in_addr *addr_list;
char addr_str[NM_UTILS_INET_ADDRSTRLEN];
const char *s;
nm_auto_free_gstring GString *str = NULL;
nm_auto_free sd_dhcp_route **routes_static = NULL;
nm_auto_free sd_dhcp_route **routes_classless = NULL;
const char *const *search_domains = NULL;
guint32 default_route_metric_offset;
guint16 mtu;
int i;
int num;
int is_classless;
int n_routes_static;
int n_routes_classless;
const void *data;
gsize data_len;
gboolean has_router_from_classless = FALSE;
const gint32 ts = nm_utils_get_monotonic_timestamp_sec();
gint64 ts_time = time(NULL);
struct in_addr a_address;
struct in_addr a_netmask;
struct in_addr a_next_server;
struct in_addr server_id;
struct in_addr broadcast;
const struct in_addr *a_router;
guint32 a_plen;
guint32 a_lifetime;
guint32 renewal;
guint32 rebinding;
gs_free nm_sd_dhcp_option *private_options = NULL;
nm_assert(lease != NULL);
if (sd_dhcp_lease_get_address(lease, &a_address) < 0) {
nm_utils_error_set_literal(error,
NM_UTILS_ERROR_UNKNOWN,
"could not get address from lease");
return NULL;
}
if (sd_dhcp_lease_get_netmask(lease, &a_netmask) < 0) {
nm_utils_error_set_literal(error,
NM_UTILS_ERROR_UNKNOWN,
"could not get netmask from lease");
return NULL;
}
if (sd_dhcp_lease_get_lifetime(lease, &a_lifetime) < 0) {
nm_utils_error_set_literal(error,
NM_UTILS_ERROR_UNKNOWN,
"could not get lifetime from lease");
return NULL;
}
l3cd = nm_l3_config_data_new(multi_idx, ifindex, NM_IP_CONFIG_SOURCE_DHCP);
options = nm_dhcp_option_create_options_dict();
_nm_utils_inet4_ntop(a_address.s_addr, addr_str);
nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_NM_IP_ADDRESS, addr_str);
a_plen = nm_utils_ip4_netmask_to_prefix(a_netmask.s_addr);
nm_dhcp_option_add_option(options,
AF_INET,
NM_DHCP_OPTION_DHCP4_SUBNET_MASK,
_nm_utils_inet4_ntop(a_netmask.s_addr, addr_str));
nm_dhcp_option_add_option_u64(options,
AF_INET,
NM_DHCP_OPTION_DHCP4_IP_ADDRESS_LEASE_TIME,
a_lifetime);
nm_dhcp_option_add_option_u64(options,
AF_INET,
NM_DHCP_OPTION_DHCP4_NM_EXPIRY,
(guint64) (ts_time + a_lifetime));
if (sd_dhcp_lease_get_next_server(lease, &a_next_server) == 0) {
_nm_utils_inet4_ntop(a_next_server.s_addr, addr_str);
nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_NM_NEXT_SERVER, addr_str);
}
nm_l3_config_data_add_address_4(l3cd,
&((const NMPlatformIP4Address){
.address = a_address.s_addr,
.peer_address = a_address.s_addr,
.plen = a_plen,
.addr_source = NM_IP_CONFIG_SOURCE_DHCP,
.timestamp = ts,
.lifetime = a_lifetime,
.preferred = a_lifetime,
}));
if (sd_dhcp_lease_get_server_identifier(lease, &server_id) >= 0) {
_nm_utils_inet4_ntop(server_id.s_addr, addr_str);
nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_SERVER_ID, addr_str);
}
if (sd_dhcp_lease_get_broadcast(lease, &broadcast) >= 0) {
_nm_utils_inet4_ntop(broadcast.s_addr, addr_str);
nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_BROADCAST, addr_str);
}
num = sd_dhcp_lease_get_dns(lease, &addr_list);
if (num > 0) {
nm_gstring_prepare(&str);
for (i = 0; i < num; i++) {
_nm_utils_inet4_ntop(addr_list[i].s_addr, addr_str);
g_string_append(nm_gstring_add_space_delimiter(str), addr_str);
if (addr_list[i].s_addr == 0 || nm_ip4_addr_is_localhost(addr_list[i].s_addr)) {
/* Skip localhost addresses, like also networkd does.
* See https://github.com/systemd/systemd/issues/4524. */
continue;
}
nm_l3_config_data_add_nameserver(l3cd, AF_INET, &addr_list[i].s_addr);
}
nm_dhcp_option_add_option(options,
AF_INET,
NM_DHCP_OPTION_DHCP4_DOMAIN_NAME_SERVER,
str->str);
}
num = sd_dhcp_lease_get_search_domains(lease, (char ***) &search_domains);
if (num > 0) {
nm_gstring_prepare(&str);
for (i = 0; i < num; i++) {
g_string_append(nm_gstring_add_space_delimiter(str), search_domains[i]);
nm_l3_config_data_add_search(l3cd, AF_INET, search_domains[i]);
}
nm_dhcp_option_add_option(options,
AF_INET,
NM_DHCP_OPTION_DHCP4_DOMAIN_SEARCH_LIST,
str->str);
}
if (sd_dhcp_lease_get_domainname(lease, &s) >= 0) {
gs_strfreev char **domains = NULL;
char **d;
nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_DOMAIN_NAME, s);
/* Multiple domains sometimes stuffed into option 15 "Domain Name".
* As systemd escapes such characters, split them at \\032. */
domains = g_strsplit(s, "\\032", 0);
for (d = domains; *d; d++)
nm_l3_config_data_add_domain(l3cd, AF_INET, *d);
}
if (sd_dhcp_lease_get_hostname(lease, &s) >= 0) {
nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_HOST_NAME, s);
}
default_route_metric_offset = 0;
n_routes_static = sd_dhcp_lease_get_static_routes(lease, &routes_static);
n_routes_classless = sd_dhcp_lease_get_classless_routes(lease, &routes_classless);
for (is_classless = 1; is_classless >= 0; is_classless--) {
int n_routes = (is_classless ? n_routes_classless : n_routes_static);
sd_dhcp_route *const *routes = (is_classless ? routes_classless : routes_static);
if (n_routes <= 0)
continue;
nm_gstring_prepare(&str);
for (i = 0; i < n_routes; i++) {
char network_net_str[NM_UTILS_INET_ADDRSTRLEN];
char gateway_str[NM_UTILS_INET_ADDRSTRLEN];
guint8 r_plen;
struct in_addr r_network;
struct in_addr r_gateway;
in_addr_t network_net;
guint32 m;
if (sd_dhcp_route_get_destination(routes[i], &r_network) < 0)
continue;
if (sd_dhcp_route_get_destination_prefix_length(routes[i], &r_plen) < 0 || r_plen > 32)
continue;
if (sd_dhcp_route_get_gateway(routes[i], &r_gateway) < 0)
continue;
network_net = nm_utils_ip4_address_clear_host_address(r_network.s_addr, r_plen);
_nm_utils_inet4_ntop(network_net, network_net_str);
_nm_utils_inet4_ntop(r_gateway.s_addr, gateway_str);
g_string_append_printf(nm_gstring_add_space_delimiter(str),
"%s/%d %s",
network_net_str,
(int) r_plen,
gateway_str);
if (!is_classless && n_routes_classless > 0) {
/* RFC 3443: if the DHCP server returns both a Classless Static Routes
* option and a Static Routes option, the DHCP client MUST ignore the
* Static Routes option. */
continue;
}
if (r_plen == 0) {
if (!is_classless) {
/* for option 33 (static route), RFC 2132 says:
*
* The default route (0.0.0.0) is an illegal destination for a static
* route. */
continue;
}
/* if there are multiple default routes, we add them with differing
* metrics. */
m = default_route_metric_offset++;
has_router_from_classless = TRUE;
} else
m = 0;
nm_l3_config_data_add_route_4(l3cd,
&((const NMPlatformIP4Route){
.rt_source = NM_IP_CONFIG_SOURCE_DHCP,
.network = network_net,
.plen = r_plen,
.gateway = r_gateway.s_addr,
.pref_src = a_address.s_addr,
.metric_any = TRUE,
.metric = m,
.table_any = TRUE,
.table_coerced = 0,
}));
}
if (str->len > 0) {
nm_dhcp_option_add_option(options,
AF_INET,
is_classless ? NM_DHCP_OPTION_DHCP4_CLASSLESS_STATIC_ROUTE
: NM_DHCP_OPTION_DHCP4_STATIC_ROUTE,
str->str);
}
}
num = sd_dhcp_lease_get_router(lease, &a_router);
if (num > 0) {
default_route_metric_offset = 0;
nm_gstring_prepare(&str);
for (i = 0; i < num; i++) {
guint32 m;
s = _nm_utils_inet4_ntop(a_router[i].s_addr, addr_str);
g_string_append(nm_gstring_add_space_delimiter(str), s);
if (a_router[i].s_addr == 0) {
/* silently skip 0.0.0.0 */
continue;
}
if (has_router_from_classless) {
/* If the DHCP server returns both a Classless Static Routes option and a
* Router option, the DHCP client MUST ignore the Router option [RFC 3442].
*
* Be more lenient and ignore the Router option only if Classless Static
* Routes contain a default gateway (as other DHCP backends do).
*/
continue;
}
/* if there are multiple default routes, we add them with differing
* metrics. */
m = default_route_metric_offset++;
nm_l3_config_data_add_route_4(l3cd,
&((const NMPlatformIP4Route){
.rt_source = NM_IP_CONFIG_SOURCE_DHCP,
.gateway = a_router[i].s_addr,
.pref_src = a_address.s_addr,
.table_any = TRUE,
.table_coerced = 0,
.metric_any = TRUE,
.metric = m,
}));
}
nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_ROUTER, str->str);
}
if (sd_dhcp_lease_get_mtu(lease, &mtu) >= 0 && mtu) {
nm_dhcp_option_add_option_u64(options, AF_INET, NM_DHCP_OPTION_DHCP4_INTERFACE_MTU, mtu);
nm_l3_config_data_set_mtu(l3cd, mtu);
}
num = sd_dhcp_lease_get_ntp(lease, &addr_list);
if (num > 0) {
nm_gstring_prepare(&str);
for (i = 0; i < num; i++) {
_nm_utils_inet4_ntop(addr_list[i].s_addr, addr_str);
g_string_append(nm_gstring_add_space_delimiter(str), addr_str);
}
nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_NTP_SERVER, str->str);
}
if (sd_dhcp_lease_get_root_path(lease, &s) >= 0) {
nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_ROOT_PATH, s);
}
if (sd_dhcp_lease_get_t1(lease, &renewal) >= 0) {
nm_dhcp_option_add_option_u64(options,
AF_INET,
NM_DHCP_OPTION_DHCP4_RENEWAL_T1_TIME,
renewal);
}
if (sd_dhcp_lease_get_t2(lease, &rebinding) >= 0) {
nm_dhcp_option_add_option_u64(options,
AF_INET,
NM_DHCP_OPTION_DHCP4_REBINDING_T2_TIME,
rebinding);
}
if (sd_dhcp_lease_get_timezone(lease, &s) >= 0) {
nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_NEW_TZDB_TIMEZONE, s);
}
if (sd_dhcp_lease_get_vendor_specific(lease, &data, &data_len) >= 0) {
if (!!memmem(data, data_len, "ANDROID_METERED", NM_STRLEN("ANDROID_METERED")))
nm_l3_config_data_set_metered(l3cd, TRUE);
}
num = nm_sd_dhcp_lease_get_private_options(lease, &private_options);
if (num > 0) {
for (i = 0; i < num; i++) {
guint8 code = private_options[i].code;
const guint8 *l_data = private_options[i].data;
gsize l_data_len = private_options[i].data_len;
char *option_string;
if (code == NM_DHCP_OPTION_DHCP4_PRIVATE_PROXY_AUTODISCOVERY) {
if (nm_dhcp_lease_data_parse_cstr(l_data, l_data_len, &l_data_len)) {
gs_free char *to_free = NULL;
const char *escaped;
escaped =
nm_utils_buf_utf8safe_escape((char *) l_data, l_data_len, 0, &to_free);
nm_dhcp_option_add_option(options,
AF_INET,
NM_DHCP_OPTION_DHCP4_PRIVATE_PROXY_AUTODISCOVERY,
escaped ?: "");
nm_l3_config_data_set_proxy_method(l3cd, NM_PROXY_CONFIG_METHOD_AUTO);
nm_l3_config_data_set_proxy_pac_url(l3cd, escaped ?: "");
}
continue;
}
if (code == NM_DHCP_OPTION_DHCP4_PRIVATE_CLASSLESS_STATIC_ROUTE) {
/* nettools and dhclient parse option 249 (Microsoft Classless Static Route)
* as fallback for routes and ignores them from private options.
*
* The systemd plugin does not, and for consistency with nettools we
* also don't expose it as private option either. */
continue;
}
option_string = nm_utils_bin2hexstr_full(l_data, l_data_len, ':', FALSE, NULL);
nm_dhcp_option_take_option(options, AF_INET, code, option_string);
}
}
nm_dhcp_option_add_requests_to_options(options, AF_INET);
nm_l3_config_data_set_dhcp_lease_from_options(l3cd, AF_INET, g_steal_pointer(&options));
return g_steal_pointer(&l3cd);
}
/*****************************************************************************/
static void
bound4_handle(NMDhcpSystemd *self, gboolean extended)
{
NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE(self);
const char *iface = nm_dhcp_client_get_iface(NM_DHCP_CLIENT(self));
nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
sd_dhcp_lease *lease = NULL;
GError *error = NULL;
if (sd_dhcp_client_get_lease(priv->client4, &lease) < 0 || !lease) {
_LOGW("no lease!");
nm_dhcp_client_set_state(NM_DHCP_CLIENT(self), NM_DHCP_STATE_FAIL, NULL);
return;
}
_LOGD("lease available");
l3cd = lease_to_ip4_config(nm_dhcp_client_get_multi_idx(NM_DHCP_CLIENT(self)),
iface,
nm_dhcp_client_get_ifindex(NM_DHCP_CLIENT(self)),
lease,
&error);
if (!l3cd) {
_LOGW("%s", error->message);
g_clear_error(&error);
nm_dhcp_client_set_state(NM_DHCP_CLIENT(self), NM_DHCP_STATE_FAIL, NULL);
return;
}
dhcp_lease_save(lease, priv->lease_file);
nm_dhcp_client_set_state(NM_DHCP_CLIENT(self),
extended ? NM_DHCP_STATE_EXTENDED : NM_DHCP_STATE_BOUND,
l3cd);
}
static int
dhcp_event_cb(sd_dhcp_client *client, int event, gpointer user_data)
{
NMDhcpSystemd *self = NM_DHCP_SYSTEMD(user_data);
NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE(self);
char addr_str[INET_ADDRSTRLEN];
sd_dhcp_lease *lease = NULL;
struct in_addr addr;
int r;
nm_assert(priv->client4 == client);
_LOGD("client event %d", event);
switch (event) {
case SD_DHCP_CLIENT_EVENT_EXPIRED:
nm_dhcp_client_set_state(NM_DHCP_CLIENT(user_data), NM_DHCP_STATE_EXPIRE, NULL);
break;
case SD_DHCP_CLIENT_EVENT_STOP:
nm_dhcp_client_set_state(NM_DHCP_CLIENT(user_data), NM_DHCP_STATE_FAIL, NULL);
break;
case SD_DHCP_CLIENT_EVENT_RENEW:
case SD_DHCP_CLIENT_EVENT_IP_CHANGE:
bound4_handle(self, TRUE);
break;
case SD_DHCP_CLIENT_EVENT_IP_ACQUIRE:
bound4_handle(self, FALSE);
break;
case SD_DHCP_CLIENT_EVENT_SELECTING:
r = sd_dhcp_client_get_lease(priv->client4, &lease);
if (r < 0)
return r;
r = sd_dhcp_lease_get_server_identifier(lease, &addr);
if (r < 0)
return r;
if (nm_dhcp_client_server_id_is_rejected(NM_DHCP_CLIENT(user_data), &addr)) {
_LOGD("server-id %s is in the reject-list, ignoring",
nm_utils_inet_ntop(AF_INET, &addr, addr_str));
return -ENOMSG;
}
break;
case SD_DHCP_CLIENT_EVENT_TRANSIENT_FAILURE:
break;
default:
_LOGW("unhandled DHCP event %d", event);
break;
}
return 0;
}
static gboolean
ip4_start(NMDhcpClient *client, GError **error)
{
nm_auto(sd_dhcp_client_unrefp) sd_dhcp_client *sd_client = NULL;
NMDhcpSystemd *self = NM_DHCP_SYSTEMD(client);
NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE(self);
const NMDhcpClientConfig *client_config;
gs_free char *lease_file = NULL;
GBytes *hwaddr;
const uint8_t *hwaddr_arr;
gsize hwaddr_len;
int arp_type;
GBytes *client_id;
gs_unref_bytes GBytes *client_id_new = NULL;
GBytes *vendor_class_identifier;
const uint8_t *client_id_arr;
size_t client_id_len;
struct in_addr last_addr = {0};
const char *hostname;
const char *mud_url;
int r, i;
GBytes *bcast_hwaddr;
const uint8_t *bcast_hwaddr_arr;
gsize bcast_hwaddr_len;
g_return_val_if_fail(!priv->client4, FALSE);
g_return_val_if_fail(!priv->client6, FALSE);
client_config = nm_dhcp_client_get_config(client);
/* TODO: honor nm_dhcp_client_get_anycast_address() */
r = sd_dhcp_client_new(&sd_client, FALSE);
if (r < 0) {
nm_utils_error_set_errno(error, r, "failed to create dhcp-client: %s");
return FALSE;
}
_LOGT("dhcp-client4: set " NM_HASH_OBFUSCATE_PTR_FMT, NM_HASH_OBFUSCATE_PTR(sd_client));
r = sd_dhcp_client_attach_event(sd_client, NULL, 0);
if (r < 0) {
nm_utils_error_set_errno(error, r, "failed to attach event: %s");
return FALSE;
}
hwaddr = client_config->hwaddr;
if (!hwaddr || !(hwaddr_arr = g_bytes_get_data(hwaddr, &hwaddr_len))
|| (arp_type = nm_utils_arp_type_detect_from_hwaddrlen(hwaddr_len)) < 0) {
nm_utils_error_set_literal(error, NM_UTILS_ERROR_UNKNOWN, "invalid MAC address");
return FALSE;
}
bcast_hwaddr_arr = NULL;
bcast_hwaddr = client_config->bcast_hwaddr;
if (bcast_hwaddr) {
bcast_hwaddr_arr = g_bytes_get_data(bcast_hwaddr, &bcast_hwaddr_len);
if (bcast_hwaddr_len != hwaddr_len)
bcast_hwaddr_arr = NULL;
}
r = sd_dhcp_client_set_mac(sd_client,
hwaddr_arr,
bcast_hwaddr_arr,
hwaddr_len,
(guint16) arp_type);
if (r < 0) {
nm_utils_error_set_errno(error, r, "failed to set MAC address: %s");
return FALSE;
}
r = sd_dhcp_client_set_ifindex(sd_client, nm_dhcp_client_get_ifindex(client));
if (r < 0) {
nm_utils_error_set_errno(error, r, "failed to set ifindex: %s");
return FALSE;
}
nm_dhcp_utils_get_leasefile_path(AF_INET,
"internal",
client_config->iface,
client_config->uuid,
&lease_file);
if (client_config->v4.last_address)
inet_pton(AF_INET, client_config->v4.last_address, &last_addr);
else {
nm_auto(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL;
dhcp_lease_load(&lease, lease_file);
if (lease)
sd_dhcp_lease_get_address(lease, &last_addr);
}
r = sd_dhcp_client_set_request_broadcast(sd_client, client_config->v4.request_broadcast);
nm_assert(r >= 0);
if (last_addr.s_addr) {
r = sd_dhcp_client_set_request_address(sd_client, &last_addr);
if (r < 0) {
nm_utils_error_set_errno(error, r, "failed to set last IPv4 address: %s");
return FALSE;
}
}
client_id = client_config->client_id;
if (!client_id) {
client_id_new = nm_utils_dhcp_client_id_mac(arp_type, hwaddr_arr, hwaddr_len);
client_id = client_id_new;
}
if (!(client_id_arr = g_bytes_get_data(client_id, &client_id_len)) || client_id_len < 2) {
/* invalid client-ids are not expected. */
nm_assert_not_reached();
nm_utils_error_set_literal(error, NM_UTILS_ERROR_UNKNOWN, "no valid IPv4 client-id");
return FALSE;
}
/* Note that we always set a client-id. In particular for infiniband that is necessary,
* see https://tools.ietf.org/html/rfc4390#section-2.1 . */
r = sd_dhcp_client_set_client_id(sd_client,
client_id_arr[0],
client_id_arr + 1,
NM_MIN(client_id_len - 1, _NM_MAX_CLIENT_ID_LEN));
if (r < 0) {
nm_utils_error_set_errno(error, r, "failed to set IPv4 client-id: %s");
return FALSE;
}
/* Add requested options */
for (i = 0; i < (int) G_N_ELEMENTS(_nm_dhcp_option_dhcp4_options); i++) {
if (_nm_dhcp_option_dhcp4_options[i].include) {
nm_assert(_nm_dhcp_option_dhcp4_options[i].option_num <= 255);
r = sd_dhcp_client_set_request_option(sd_client,
_nm_dhcp_option_dhcp4_options[i].option_num);
nm_assert(r >= 0 || r == -EEXIST);
}
}
hostname = client_config->hostname;
if (hostname) {
/* FIXME: sd-dhcp decides which hostname/FQDN option to send (12 or 81)
* only based on whether the hostname has a domain part or not. At the
* moment there is no way to force one or another.
*/
r = sd_dhcp_client_set_hostname(sd_client, hostname);
if (r < 0) {
nm_utils_error_set_errno(error, r, "failed to set DHCP hostname: %s");
return FALSE;
}
}
mud_url = client_config->mud_url;
if (mud_url) {
r = sd_dhcp_client_set_mud_url(sd_client, mud_url);
if (r < 0) {
nm_utils_error_set_errno(error, r, "failed to set DHCP MUDURL: %s");
return FALSE;
}
}
vendor_class_identifier = client_config->vendor_class_identifier;
if (vendor_class_identifier) {
const char *option_data;
gsize len;
option_data = g_bytes_get_data(vendor_class_identifier, &len);
nm_assert(option_data);
nm_assert(len <= 255);
option_data = nm_strndup_a(300, option_data, len, NULL);
r = sd_dhcp_client_set_vendor_class_identifier(sd_client, option_data);
if (r < 0) {
nm_utils_error_set_errno(error, r, "failed to set DHCP vendor class identifier: %s");
return FALSE;
}
}
r = sd_dhcp_client_set_callback(sd_client, dhcp_event_cb, client);
if (r < 0) {
nm_utils_error_set_errno(error, r, "failed to set callback: %s");
return FALSE;
}
priv->client4 = g_steal_pointer(&sd_client);
g_free(priv->lease_file);
priv->lease_file = g_steal_pointer(&lease_file);
nm_dhcp_client_set_effective_client_id(client, client_id);
r = sd_dhcp_client_start(priv->client4);
if (r < 0) {
sd_dhcp_client_set_callback(priv->client4, NULL, NULL);
nm_clear_pointer(&priv->client4, sd_dhcp_client_unref);
nm_utils_error_set_errno(error, r, "failed to start DHCP client: %s");
return FALSE;
}
return TRUE;
}
static NML3ConfigData *
lease_to_ip6_config(NMDedupMultiIndex *multi_idx,
const char *iface,
@ -945,7 +274,6 @@ ip6_start(NMDhcpClient *client, const struct in6_addr *ll_addr, GError **error)
GBytes *duid;
gboolean prefix_delegation;
g_return_val_if_fail(!priv->client4, FALSE);
g_return_val_if_fail(!priv->client6, FALSE);
client_config = nm_dhcp_client_get_config(client);
@ -1073,18 +401,13 @@ stop(NMDhcpClient *client, gboolean release)
NM_DHCP_CLIENT_CLASS(nm_dhcp_systemd_parent_class)->stop(client, release);
_LOGT("dhcp-client%d: stop %p",
priv->client4 ? '4' : '6',
priv->client4 ? (gpointer) priv->client4 : (gpointer) priv->client6);
_LOGT("dhcp-client6: stop");
if (priv->client4) {
sd_dhcp_client_set_callback(priv->client4, NULL, NULL);
r = sd_dhcp_client_stop(priv->client4);
} else if (priv->client6) {
sd_dhcp6_client_set_callback(priv->client6, NULL, NULL);
r = sd_dhcp6_client_stop(priv->client6);
}
if (!priv->client6)
return;
sd_dhcp6_client_set_callback(priv->client6, NULL, NULL);
r = sd_dhcp6_client_stop(priv->client6);
if (r)
_LOGW("failed to stop client (%d)", r);
}
@ -1102,12 +425,6 @@ dispose(GObject *object)
nm_clear_g_free(&priv->lease_file);
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);
@ -1125,14 +442,13 @@ nm_dhcp_systemd_class_init(NMDhcpSystemdClass *sdhcp_class)
object_class->dispose = dispose;
client_class->ip4_start = ip4_start;
client_class->ip6_start = ip6_start;
client_class->stop = stop;
}
const NMDhcpClientFactory _nm_dhcp_client_factory_systemd = {
.name = "systemd",
.get_type_4 = nm_dhcp_systemd_get_type,
.get_type_4 = nm_dhcp_nettools_get_type,
.get_type_6 = nm_dhcp_systemd_get_type,
.undocumented = TRUE,
};

View file

@ -12,27 +12,6 @@
/*****************************************************************************/
static void
test_dhcp_create(void)
{
sd_dhcp_client *client4 = NULL;
int r;
r = sd_dhcp_client_new(&client4, FALSE);
g_assert(r == 0);
g_assert(client4);
if (/* never true */ client4 == (gpointer) &r) {
/* we don't want to call this, but ensure that the linker
* includes all these symbols. */
sd_dhcp_client_start(client4);
}
sd_dhcp_client_unref(client4);
}
/*****************************************************************************/
static void
test_lldp_create(void)
{
@ -261,7 +240,6 @@ main(int argc, char **argv)
{
nmtst_init(&argc, &argv, TRUE);
g_test_add_func("/systemd/dhcp/create", test_dhcp_create);
g_test_add_func("/systemd/lldp/create", test_lldp_create);
g_test_add_func("/systemd/sd-event", test_sd_event);
g_test_add_func("/systemd/test_path_equal", test_path_equal);

View file

@ -26,7 +26,6 @@ libnm_systemd_core = static_library(
'src/libsystemd/sd-id128/sd-id128.c',
'nm-sd.c',
'nm-sd-utils-core.c',
'nm-sd-utils-dhcp.c',
'sd-adapt-core/nm-sd-adapt-core.c',
),
include_directories: [

View file

@ -1,40 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2019 Red Hat, Inc.
*/
#include "libnm-systemd-core/nm-default-systemd-core.h"
#include "nm-sd-utils-dhcp.h"
#include "sd-adapt-core/nm-sd-adapt-core.h"
#include "src/libsystemd-network/dhcp-lease-internal.h"
int
nm_sd_dhcp_lease_get_private_options(sd_dhcp_lease *lease, nm_sd_dhcp_option **out_options)
{
int cnt = 0;
g_return_val_if_fail(lease, -EINVAL);
g_return_val_if_fail(out_options, -EINVAL);
g_return_val_if_fail(*out_options == NULL, -EINVAL);
if (lease->private_options == NULL)
return -ENODATA;
LIST_FOREACH(options, raw_option, lease->private_options)
cnt++;
*out_options = g_new(nm_sd_dhcp_option, cnt);
cnt = 0;
LIST_FOREACH(options, raw_option, lease->private_options)
{
(*out_options)[cnt].code = raw_option->tag;
(*out_options)[cnt].data = raw_option->data;
(*out_options)[cnt].data_len = raw_option->length;
cnt++;
}
return cnt;
}

View file

@ -1,19 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2019 Red Hat, Inc.
*/
#ifndef __NETWORKMANAGER_DHCP_SYSTEMD_UTILS_H__
#define __NETWORKMANAGER_DHCP_SYSTEMD_UTILS_H__
#include "nm-sd.h"
typedef struct {
uint8_t code;
uint8_t data_len;
void *data;
} nm_sd_dhcp_option;
int nm_sd_dhcp_lease_get_private_options(sd_dhcp_lease *lease, nm_sd_dhcp_option **out_options);
#endif /* __NETWORKMANAGER_DHCP_SYSTEMD_UTILS_H__ */

View file

@ -108,6 +108,5 @@ nm_sd_event_attach_default(void)
/* ensure that defines in nm-sd.h correspond to the internal defines. */
#include "nm-sd-adapt-core.h"
#include "dhcp-lease-internal.h"
/*****************************************************************************/

View file

@ -6,7 +6,7 @@
#ifndef __NM_SD_H__
#define __NM_SD_H__
#include "src/systemd/sd-dhcp-client.h"
#include "src/systemd/sd-dhcp-lease.h"
#include "src/systemd/sd-dhcp6-client.h"
#include "src/systemd/sd-lldp-rx.h"