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:
@@ -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,
|
||||
|
@@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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__ */
|
||||
|
@@ -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);
|
||||
|
@@ -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();
|
||||
}
|
||||
|
Reference in New Issue
Block a user