dhcp: rework DHCP options to not carry around option array

Previously, we would pass around the list of options. However,

- that isn't too nice to read. Also, usually when we want to treat
  IP address families generically, then we have an addr_family argument.
  Having to first resolve the addr_family to another set of variables
  is inconvenient.

- the option array itself doesn't have enough information. For example,
  we don't know how many elements there are, we don't know which address
  family it is (unless we compare it to one of the two well known
  lists).
  For example, I'd like to do a binary search for the option. But that's
  not immediately possible, because the length is unknown.

- in practice, there are only two address families: AF_INET and
  AF_INET6. It is extremely unlikely that we will require a third
  DHCP options list, and even if we had that, the addr_family argument
  still abstracts them nicely.
  We also don't need two different lists for one DHCP type. While that
  would currently be possible (and afterwards not anymore), it would
  be wrong to do.

- also add a new accessor nm_dhcp_option_find() to find the NMDhcpOption
  instance by option number.
This commit is contained in:
Thomas Haller
2021-02-11 10:21:46 +01:00
parent 53f137af6e
commit 1cbe926c20
5 changed files with 185 additions and 196 deletions

View File

@@ -231,30 +231,27 @@ lease_parse_address(NDhcp4ClientLease *lease,
a_plen = nm_utils_ip4_netmask_to_prefix(a_netmask);
nm_dhcp_option_add_option_in_addr(options,
_nm_dhcp_option_dhcp4_options,
AF_INET,
NM_DHCP_OPTION_DHCP4_NM_IP_ADDRESS,
a_address.s_addr);
nm_dhcp_option_add_option_in_addr(options,
_nm_dhcp_option_dhcp4_options,
AF_INET,
NM_DHCP_OPTION_DHCP4_SUBNET_MASK,
a_netmask);
nm_dhcp_option_add_option_u64(options,
_nm_dhcp_option_dhcp4_options,
AF_INET,
NM_DHCP_OPTION_DHCP4_IP_ADDRESS_LEASE_TIME,
(guint64) a_lifetime);
if (a_expiry != G_MAXUINT64) {
nm_dhcp_option_add_option_u64(options,
_nm_dhcp_option_dhcp4_options,
NM_DHCP_OPTION_DHCP4_NM_EXPIRY,
a_expiry);
nm_dhcp_option_add_option_u64(options, AF_INET, NM_DHCP_OPTION_DHCP4_NM_EXPIRY, a_expiry);
}
n_dhcp4_client_lease_get_siaddr(lease, &a_next_server);
if (a_next_server.s_addr != INADDR_ANY) {
nm_dhcp_option_add_option_in_addr(options,
_nm_dhcp_option_dhcp4_options,
AF_INET,
NM_DHCP_OPTION_DHCP4_NM_NEXT_SERVER,
a_next_server.s_addr);
}
@@ -322,10 +319,7 @@ lease_parse_address_list(NDhcp4ClientLease * lease,
}
}
nm_dhcp_option_add_option(options,
_nm_dhcp_option_dhcp4_options,
option,
nm_str_buf_get_str(sbuf));
nm_dhcp_option_add_option(options, AF_INET, option, nm_str_buf_get_str(sbuf));
}
static void
@@ -391,7 +385,7 @@ lease_parse_routes(NDhcp4ClientLease *lease,
}
nm_dhcp_option_add_option(options,
_nm_dhcp_option_dhcp4_options,
AF_INET,
NM_DHCP_OPTION_DHCP4_CLASSLESS_STATIC_ROUTE,
nm_str_buf_get_str(sbuf));
}
@@ -436,7 +430,7 @@ lease_parse_routes(NDhcp4ClientLease *lease,
}
nm_dhcp_option_add_option(options,
_nm_dhcp_option_dhcp4_options,
AF_INET,
NM_DHCP_OPTION_DHCP4_STATIC_ROUTE,
nm_str_buf_get_str(sbuf));
}
@@ -482,7 +476,7 @@ lease_parse_routes(NDhcp4ClientLease *lease,
}
nm_dhcp_option_add_option(options,
_nm_dhcp_option_dhcp4_options,
AF_INET,
NM_DHCP_OPTION_DHCP4_ROUTER,
nm_str_buf_get_str(sbuf));
}
@@ -510,7 +504,7 @@ lease_parse_search_domains(NDhcp4ClientLease *lease, NMIP4Config *ip4_config, GH
nm_ip4_config_add_search(ip4_config, domains[i]);
nm_dhcp_option_take_option(options,
_nm_dhcp_option_dhcp4_options,
AF_INET,
NM_DHCP_OPTION_DHCP4_DOMAIN_SEARCH_LIST,
g_strjoinv(" ", domains));
}
@@ -538,10 +532,7 @@ lease_parse_private_options(NDhcp4ClientLease *lease, GHashTable *options)
continue;
option_string = nm_utils_bin2hexstr_full(l_data, l_data_len, ':', FALSE, NULL);
nm_dhcp_option_take_option(options,
_nm_dhcp_option_dhcp4_options,
i,
g_steal_pointer(&option_string));
nm_dhcp_option_take_option(options, AF_INET, i, g_steal_pointer(&option_string));
}
}
@@ -578,7 +569,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
r = n_dhcp4_client_lease_get_server_identifier(lease, &v_inaddr_s);
if (r == 0) {
nm_dhcp_option_add_option_in_addr(options,
_nm_dhcp_option_dhcp4_options,
AF_INET,
NM_DHCP_OPTION_DHCP4_SERVER_ID,
v_inaddr_s.s_addr);
}
@@ -586,7 +577,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
r = _client_lease_query(lease, NM_DHCP_OPTION_DHCP4_BROADCAST, &l_data, &l_data_len);
if (r == 0 && nm_dhcp_lease_data_parse_in_addr(l_data, l_data_len, &v_inaddr)) {
nm_dhcp_option_add_option_in_addr(options,
_nm_dhcp_option_dhcp4_options,
AF_INET,
NM_DHCP_OPTION_DHCP4_BROADCAST,
v_inaddr);
}
@@ -628,7 +619,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
if (sbuf.len > 0) {
nm_dhcp_option_add_option(options,
_nm_dhcp_option_dhcp4_options,
AF_INET,
NM_DHCP_OPTION_DHCP4_DOMAIN_NAME,
nm_str_buf_get_str(&sbuf));
}
@@ -638,10 +629,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
r = _client_lease_query(lease, NM_DHCP_OPTION_DHCP4_INTERFACE_MTU, &l_data, &l_data_len);
if (r == 0 && nm_dhcp_lease_data_parse_mtu(l_data, l_data_len, &v_u16)) {
nm_dhcp_option_add_option_u64(options,
_nm_dhcp_option_dhcp4_options,
NM_DHCP_OPTION_DHCP4_INTERFACE_MTU,
v_u16);
nm_dhcp_option_add_option_u64(options, AF_INET, NM_DHCP_OPTION_DHCP4_INTERFACE_MTU, v_u16);
nm_ip4_config_set_mtu(ip4_config, v_u16, NM_IP_CONFIG_SOURCE_DHCP);
}
@@ -655,10 +643,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
gs_free char *s = NULL;
if (nm_dhcp_lease_data_parse_domain(l_data, l_data_len, &s)) {
nm_dhcp_option_add_option(options,
_nm_dhcp_option_dhcp4_options,
NM_DHCP_OPTION_DHCP4_HOST_NAME,
s);
nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_HOST_NAME, s);
}
}
@@ -676,7 +661,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
/* "Its minimum length is 1." */
} else {
nm_dhcp_option_add_option_utf8safe_escape(options,
_nm_dhcp_option_dhcp4_options,
AF_INET,
NM_DHCP_OPTION_DHCP4_ROOT_PATH,
l_data,
l_data_len);
@@ -694,7 +679,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
* Otherwise, we allow any encoding and backslash-escape the result to
* UTF-8. */
nm_dhcp_option_add_option_utf8safe_escape(options,
_nm_dhcp_option_dhcp4_options,
AF_INET,
NM_DHCP_OPTION_DHCP4_PRIVATE_PROXY_AUTODISCOVERY,
l_data,
l_data_len);
@@ -708,10 +693,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
v_str = nm_utils_buf_utf8safe_escape((char *) l_data, l_data_len, 0, &to_free);
nm_dhcp_option_add_option(options,
_nm_dhcp_option_dhcp4_options,
NM_DHCP_OPTION_DHCP4_NIS_DOMAIN,
v_str);
nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_NIS_DOMAIN, v_str);
nm_ip4_config_set_nis_domain(ip4_config, v_str);
}
@@ -781,7 +763,7 @@ bound4_handle(NMDhcpNettools *self, NDhcp4ClientLease *lease, gboolean extended)
return;
}
nm_dhcp_option_add_requests_to_options(options, _nm_dhcp_option_dhcp4_options);
nm_dhcp_option_add_requests_to_options(options, AF_INET);
lease_save(self, lease, priv->lease_file);
nm_dhcp_client_set_state(NM_DHCP_CLIENT(self),
@@ -1107,7 +1089,7 @@ ip4_start(NMDhcpClient *client,
}
/* Add requested options */
for (i = 0; _nm_dhcp_option_dhcp4_options[i].name; i++) {
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);
n_dhcp4_client_probe_config_request_option(config,

View File

@@ -7,11 +7,11 @@
#include "nm-dhcp-options.h"
#define REQPREFIX "requested_"
/*****************************************************************************/
#define REQ(_num, _name, _include) \
{ \
.name = REQPREFIX ""_name, .option_num = _num, .include = _include, \
#define REQ(_num, _name, _include) \
{ \
.name = NM_DHCP_OPTION_REQPREFIX ""_name, .option_num = _num, .include = _include, \
}
const NMDhcpOption _nm_dhcp_option_dhcp4_options[] = {
@@ -167,8 +167,7 @@ const NMDhcpOption _nm_dhcp_option_dhcp4_options[] = {
REQ(NM_DHCP_OPTION_DHCP4_NM_IP_ADDRESS, "ip_address", FALSE),
REQ(NM_DHCP_OPTION_DHCP4_NM_EXPIRY, "expiry", FALSE),
REQ(NM_DHCP_OPTION_DHCP4_NM_NEXT_SERVER, "next_server", FALSE),
{0}};
};
const NMDhcpOption _nm_dhcp_option_dhcp6_options[] = {
REQ(NM_DHCP_OPTION_DHCP6_CLIENTID, "dhcp6_client_id", FALSE),
@@ -194,103 +193,102 @@ const NMDhcpOption _nm_dhcp_option_dhcp6_options[] = {
REQ(NM_DHCP_OPTION_DHCP6_NM_RENEW, "renew", FALSE),
REQ(NM_DHCP_OPTION_DHCP6_NM_REBIND, "rebind", FALSE),
REQ(NM_DHCP_OPTION_DHCP6_NM_IAID, "iaid", FALSE),
};
{0}};
#undef REQ
const char *
nm_dhcp_option_request_string(const NMDhcpOption *requests, guint option)
const NMDhcpOption *
nm_dhcp_option_find(int addr_family, guint option)
{
guint i = 0;
const int IS_IPv4 = NM_IS_IPv4(addr_family);
const NMDhcpOption *const options =
IS_IPv4 ? _nm_dhcp_option_dhcp4_options : _nm_dhcp_option_dhcp6_options;
int n_options = IS_IPv4 ? G_N_ELEMENTS(_nm_dhcp_option_dhcp4_options)
: G_N_ELEMENTS(_nm_dhcp_option_dhcp6_options);
int i;
while (requests[i].name) {
if (requests[i].option_num == option)
return requests[i].name + NM_STRLEN(REQPREFIX);
i++;
for (i = 0; i < n_options; i++) {
const NMDhcpOption *opt = &options[i];
if (opt->option_num == option)
return opt;
}
/* Option should always be found */
nm_assert_not_reached();
return NULL;
return nm_assert_unreachable_val(NULL);
}
void
nm_dhcp_option_take_option(GHashTable * options,
const NMDhcpOption *requests,
guint option,
char * value)
nm_dhcp_option_take_option(GHashTable *options, int addr_family, guint option, char *value)
{
nm_assert_addr_family(addr_family);
nm_assert(value);
nm_assert(g_utf8_validate(value, -1, NULL));
if (!options) {
nm_assert_not_reached();
g_free(value);
return;
}
nm_assert(requests);
nm_assert(value);
nm_assert(g_utf8_validate(value, -1, NULL));
g_hash_table_insert(options, (gpointer) nm_dhcp_option_request_string(requests, option), value);
g_hash_table_insert(options,
(gpointer) nm_dhcp_option_request_string(addr_family, option),
value);
}
void
nm_dhcp_option_add_option(GHashTable * options,
const NMDhcpOption *requests,
guint option,
const char * value)
nm_dhcp_option_add_option(GHashTable *options, int addr_family, guint option, const char *value)
{
nm_dhcp_option_take_option(options, requests, option, g_strdup(value));
nm_dhcp_option_take_option(options, addr_family, option, g_strdup(value));
}
void
nm_dhcp_option_add_option_utf8safe_escape(GHashTable * options,
const NMDhcpOption *requests,
guint option,
const guint8 * data,
gsize n_data)
nm_dhcp_option_add_option_utf8safe_escape(GHashTable * options,
int addr_family,
guint option,
const guint8 *data,
gsize n_data)
{
gs_free char *to_free = NULL;
const char * escaped;
escaped = nm_utils_buf_utf8safe_escape((char *) data, n_data, 0, &to_free);
nm_dhcp_option_add_option(options, requests, option, escaped ?: "");
nm_dhcp_option_add_option(options, addr_family, option, escaped ?: "");
}
void
nm_dhcp_option_add_option_u64(GHashTable * options,
const NMDhcpOption *requests,
guint option,
guint64 value)
nm_dhcp_option_add_option_u64(GHashTable *options, int addr_family, guint option, guint64 value)
{
nm_dhcp_option_take_option(options,
requests,
addr_family,
option,
g_strdup_printf("%" G_GUINT64_FORMAT, value));
}
void
nm_dhcp_option_add_option_in_addr(GHashTable * options,
const NMDhcpOption *requests,
guint option,
in_addr_t value)
nm_dhcp_option_add_option_in_addr(GHashTable *options,
int addr_family,
guint option,
in_addr_t value)
{
char sbuf[NM_UTILS_INET_ADDRSTRLEN];
nm_dhcp_option_add_option(options, requests, option, _nm_utils_inet4_ntop(value, sbuf));
nm_dhcp_option_add_option(options, addr_family, option, _nm_utils_inet4_ntop(value, sbuf));
}
void
nm_dhcp_option_add_requests_to_options(GHashTable *options, const NMDhcpOption *requests)
nm_dhcp_option_add_requests_to_options(GHashTable *options, int addr_family)
{
guint i;
const int IS_IPv4 = NM_IS_IPv4(addr_family);
const NMDhcpOption *const all_options =
IS_IPv4 ? _nm_dhcp_option_dhcp4_options : _nm_dhcp_option_dhcp6_options;
int n_options = IS_IPv4 ? G_N_ELEMENTS(_nm_dhcp_option_dhcp4_options)
: G_N_ELEMENTS(_nm_dhcp_option_dhcp6_options);
int i;
if (!options) {
nm_assert_not_reached();
return;
}
for (i = 0; requests[i].name; i++) {
if (requests[i].include)
g_hash_table_insert(options, (gpointer) requests[i].name, g_strdup("1"));
for (i = 0; i < n_options; i++) {
if (all_options[i].include)
g_hash_table_insert(options, (gpointer) all_options[i].name, g_strdup("1"));
}
}

View File

@@ -177,38 +177,50 @@ typedef enum {
} NMDhcpOptionDhcp6Options;
#define NM_DHCP_OPTION_REQPREFIX "requested_"
typedef struct {
const char *name;
uint16_t option_num;
bool include;
} NMDhcpOption;
extern const NMDhcpOption _nm_dhcp_option_dhcp4_options[];
extern const NMDhcpOption _nm_dhcp_option_dhcp6_options[];
extern const NMDhcpOption _nm_dhcp_option_dhcp4_options[142];
extern const NMDhcpOption _nm_dhcp_option_dhcp6_options[16];
const char *nm_dhcp_option_request_string(const NMDhcpOption *requests, guint option);
void nm_dhcp_option_take_option(GHashTable * options,
const NMDhcpOption *requests,
guint option,
char * value);
void nm_dhcp_option_add_option(GHashTable * options,
const NMDhcpOption *requests,
guint option,
const char * value);
void nm_dhcp_option_add_option_utf8safe_escape(GHashTable * options,
const NMDhcpOption *requests,
guint option,
const guint8 * data,
gsize n_data);
void nm_dhcp_option_add_option_in_addr(GHashTable * options,
const NMDhcpOption *requests,
guint option,
in_addr_t value);
void nm_dhcp_option_add_option_u64(GHashTable * options,
const NMDhcpOption *requests,
guint option,
guint64 value);
void nm_dhcp_option_add_requests_to_options(GHashTable *options, const NMDhcpOption *requests);
static inline const char *
nm_dhcp_option_get_name(const NMDhcpOption *option)
{
nm_assert(option);
nm_assert(option->name);
nm_assert(NM_STR_HAS_PREFIX(option->name, NM_DHCP_OPTION_REQPREFIX));
return &option->name[NM_STRLEN(NM_DHCP_OPTION_REQPREFIX)];
}
const NMDhcpOption *nm_dhcp_option_find(int addr_family, guint option);
static inline const char *
nm_dhcp_option_request_string(int addr_family, guint option)
{
return nm_dhcp_option_get_name(nm_dhcp_option_find(addr_family, option));
}
void nm_dhcp_option_take_option(GHashTable *options, int addr_family, guint option, char *value);
void
nm_dhcp_option_add_option(GHashTable *options, int addr_family, guint option, const char *value);
void nm_dhcp_option_add_option_utf8safe_escape(GHashTable * options,
int addr_family,
guint option,
const guint8 *data,
gsize n_data);
void nm_dhcp_option_add_option_in_addr(GHashTable *options,
int addr_family,
guint option,
in_addr_t value);
void
nm_dhcp_option_add_option_u64(GHashTable *options, int addr_family, guint option, guint64 value);
void nm_dhcp_option_add_requests_to_options(GHashTable *options, int addr_family);
GHashTable *nm_dhcp_option_create_options_dict(void);
#endif /* __NM_DHCP_OPTIONS_H__ */

View File

@@ -138,32 +138,26 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
options = out_options ? nm_dhcp_option_create_options_dict() : NULL;
_nm_utils_inet4_ntop(a_address.s_addr, addr_str);
nm_dhcp_option_add_option(options,
_nm_dhcp_option_dhcp4_options,
NM_DHCP_OPTION_DHCP4_NM_IP_ADDRESS,
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,
_nm_dhcp_option_dhcp4_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,
_nm_dhcp_option_dhcp4_options,
AF_INET,
NM_DHCP_OPTION_DHCP4_IP_ADDRESS_LEASE_TIME,
a_lifetime);
nm_dhcp_option_add_option_u64(options,
_nm_dhcp_option_dhcp4_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,
_nm_dhcp_option_dhcp4_options,
NM_DHCP_OPTION_DHCP4_NM_NEXT_SERVER,
addr_str);
nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_NM_NEXT_SERVER, addr_str);
}
nm_ip4_config_add_address(ip4_config,
@@ -179,18 +173,12 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
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,
_nm_dhcp_option_dhcp4_options,
NM_DHCP_OPTION_DHCP4_SERVER_ID,
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,
_nm_dhcp_option_dhcp4_options,
NM_DHCP_OPTION_DHCP4_BROADCAST,
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);
@@ -208,7 +196,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
nm_ip4_config_add_nameserver(ip4_config, addr_list[i].s_addr);
}
nm_dhcp_option_add_option(options,
_nm_dhcp_option_dhcp4_options,
AF_INET,
NM_DHCP_OPTION_DHCP4_DOMAIN_NAME_SERVER,
str->str);
}
@@ -221,7 +209,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
nm_ip4_config_add_search(ip4_config, search_domains[i]);
}
nm_dhcp_option_add_option(options,
_nm_dhcp_option_dhcp4_options,
AF_INET,
NM_DHCP_OPTION_DHCP4_DOMAIN_SEARCH_LIST,
str->str);
}
@@ -230,10 +218,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
gs_strfreev char **domains = NULL;
char ** d;
nm_dhcp_option_add_option(options,
_nm_dhcp_option_dhcp4_options,
NM_DHCP_OPTION_DHCP4_DOMAIN_NAME,
s);
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. */
@@ -243,10 +228,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
}
if (sd_dhcp_lease_get_hostname(lease, &s) >= 0) {
nm_dhcp_option_add_option(options,
_nm_dhcp_option_dhcp4_options,
NM_DHCP_OPTION_DHCP4_HOST_NAME,
s);
nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_HOST_NAME, s);
}
num = sd_dhcp_lease_get_routes(lease, &routes);
@@ -348,12 +330,12 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
if (str_classless && str_classless->len > 0)
nm_dhcp_option_add_option(options,
_nm_dhcp_option_dhcp4_options,
AF_INET,
NM_DHCP_OPTION_DHCP4_CLASSLESS_STATIC_ROUTE,
str_classless->str);
if (str_static && str_static->len > 0)
nm_dhcp_option_add_option(options,
_nm_dhcp_option_dhcp4_options,
AF_INET,
NM_DHCP_OPTION_DHCP4_STATIC_ROUTE,
str_static->str);
}
@@ -400,17 +382,11 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
}),
NULL);
}
nm_dhcp_option_add_option(options,
_nm_dhcp_option_dhcp4_options,
NM_DHCP_OPTION_DHCP4_ROUTER,
str->str);
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,
_nm_dhcp_option_dhcp4_options,
NM_DHCP_OPTION_DHCP4_INTERFACE_MTU,
mtu);
nm_dhcp_option_add_option_u64(options, AF_INET, NM_DHCP_OPTION_DHCP4_INTERFACE_MTU, mtu);
nm_ip4_config_set_mtu(ip4_config, mtu, NM_IP_CONFIG_SOURCE_DHCP);
}
@@ -421,38 +397,29 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
_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,
_nm_dhcp_option_dhcp4_options,
NM_DHCP_OPTION_DHCP4_NTP_SERVER,
str->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,
_nm_dhcp_option_dhcp4_options,
NM_DHCP_OPTION_DHCP4_ROOT_PATH,
s);
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,
_nm_dhcp_option_dhcp4_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,
_nm_dhcp_option_dhcp4_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,
_nm_dhcp_option_dhcp4_options,
NM_DHCP_OPTION_DHCP4_NEW_TZDB_TIMEZONE,
s);
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)
@@ -473,10 +440,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
g_free(option_string);
continue;
}
nm_dhcp_option_take_option(options,
_nm_dhcp_option_dhcp4_options,
private_options[i].code,
option_string);
nm_dhcp_option_take_option(options, AF_INET, private_options[i].code, option_string);
}
}
NM_SET_OUT(out_options, g_steal_pointer(&options));
@@ -518,7 +482,7 @@ bound4_handle(NMDhcpSystemd *self, gboolean extended)
return;
}
nm_dhcp_option_add_requests_to_options(options, _nm_dhcp_option_dhcp4_options);
nm_dhcp_option_add_requests_to_options(options, AF_INET);
dhcp_lease_save(lease, priv->lease_file);
nm_dhcp_client_set_state(NM_DHCP_CLIENT(self),
@@ -702,7 +666,7 @@ ip4_start(NMDhcpClient *client,
}
/* Add requested options */
for (i = 0; _nm_dhcp_option_dhcp4_options[i].name; i++) {
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,
@@ -821,10 +785,7 @@ lease_to_ip6_config(NMDedupMultiIndex *multi_idx,
g_string_append(nm_gstring_add_space_delimiter(str), addr_str);
};
if (str->len)
nm_dhcp_option_add_option(options,
_nm_dhcp_option_dhcp6_options,
NM_DHCP_OPTION_DHCP6_NM_IP_ADDRESS,
str->str);
nm_dhcp_option_add_option(options, AF_INET6, NM_DHCP_OPTION_DHCP6_NM_IP_ADDRESS, str->str);
if (!info_only && nm_ip6_config_get_num_addresses(ip6_config) == 0) {
g_set_error_literal(error,
@@ -842,10 +803,7 @@ lease_to_ip6_config(NMDedupMultiIndex *multi_idx,
g_string_append(nm_gstring_add_space_delimiter(str), addr_str);
nm_ip6_config_add_nameserver(ip6_config, &dns[i]);
}
nm_dhcp_option_add_option(options,
_nm_dhcp_option_dhcp6_options,
NM_DHCP_OPTION_DHCP6_DNS_SERVERS,
str->str);
nm_dhcp_option_add_option(options, AF_INET6, NM_DHCP_OPTION_DHCP6_DNS_SERVERS, str->str);
}
num = sd_dhcp6_lease_get_domains(lease, &domains);
@@ -855,17 +813,11 @@ lease_to_ip6_config(NMDedupMultiIndex *multi_idx,
g_string_append(nm_gstring_add_space_delimiter(str), domains[i]);
nm_ip6_config_add_search(ip6_config, domains[i]);
}
nm_dhcp_option_add_option(options,
_nm_dhcp_option_dhcp6_options,
NM_DHCP_OPTION_DHCP6_DOMAIN_LIST,
str->str);
nm_dhcp_option_add_option(options, AF_INET6, NM_DHCP_OPTION_DHCP6_DOMAIN_LIST, str->str);
}
if (sd_dhcp6_lease_get_fqdn(lease, &s) >= 0) {
nm_dhcp_option_add_option(options,
_nm_dhcp_option_dhcp6_options,
NM_DHCP_OPTION_DHCP6_FQDN,
s);
nm_dhcp_option_add_option(options, AF_INET6, NM_DHCP_OPTION_DHCP6_FQDN, s);
}
NM_SET_OUT(out_options, g_steal_pointer(&options));
@@ -1020,7 +972,7 @@ ip6_start(NMDhcpClient * client,
}
/* Add requested options */
for (i = 0; _nm_dhcp_option_dhcp6_options[i].name; i++) {
for (i = 0; i < (int) G_N_ELEMENTS(_nm_dhcp_option_dhcp6_options); i++) {
if (_nm_dhcp_option_dhcp6_options[i].include) {
r = sd_dhcp6_client_set_request_option(sd_client,
_nm_dhcp_option_dhcp6_options[i].option_num);

View File

@@ -13,10 +13,13 @@
#include "nm-utils.h"
#include "dhcp/nm-dhcp-utils.h"
#include "dhcp/nm-dhcp-options.h"
#include "platform/nm-platform.h"
#include "nm-test-utils-core.h"
/*****************************************************************************/
static NMIP4Config *
_ip4_config_from_options(int ifindex, const char *iface, GHashTable *options, guint32 route_metric)
{
@@ -740,6 +743,46 @@ test_client_id_from_string(void)
COMPARE_ID(endcolon, TRUE, endcolon, strlen(endcolon));
}
/*****************************************************************************/
static void
test_dhcp_opt_list(gconstpointer test_data)
{
const gboolean IS_IPv4 = (GPOINTER_TO_INT(test_data) == 0);
const int addr_family = IS_IPv4 ? AF_INET : AF_INET6;
const NMDhcpOption *const options =
IS_IPv4 ? _nm_dhcp_option_dhcp4_options : _nm_dhcp_option_dhcp6_options;
const guint n = (IS_IPv4 ? G_N_ELEMENTS(_nm_dhcp_option_dhcp4_options)
: G_N_ELEMENTS(_nm_dhcp_option_dhcp6_options));
guint i;
guint j;
g_assert(options);
g_assert(n > 0);
for (i = 0; i < n; i++) {
const NMDhcpOption *const opt = &options[i];
g_assert_cmpstr(opt->name, !=, NULL);
g_assert(NM_STR_HAS_PREFIX(opt->name, NM_DHCP_OPTION_REQPREFIX));
for (j = 0; j < i; j++) {
const NMDhcpOption *const opt2 = &options[j];
g_assert_cmpstr(opt->name, !=, opt2->name);
g_assert_cmpint(opt->option_num, !=, opt2->option_num);
}
}
for (i = 0; i < n; i++) {
const NMDhcpOption *const opt = &options[i];
g_assert(opt == nm_dhcp_option_find(addr_family, opt->option_num));
}
}
/*****************************************************************************/
NMTST_DEFINE();
int
@@ -776,6 +819,8 @@ main(int argc, char **argv)
g_test_add_func("/dhcp/client-id-from-string", test_client_id_from_string);
g_test_add_func("/dhcp/vendor-option-metered", test_vendor_option_metered);
g_test_add_func("/dhcp/parse-search-list", test_parse_search_list);
g_test_add_data_func("/dhcp/test_dhcp_opt_list/IPv4", GINT_TO_POINTER(0), test_dhcp_opt_list);
g_test_add_data_func("/dhcp/test_dhcp_opt_list/IPv6", GINT_TO_POINTER(1), test_dhcp_opt_list);
return g_test_run();
}