merge: branch 'bg/dhcp-filename-rh1979387'

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/929
This commit is contained in:
Beniamino Galvani 2021-07-27 09:42:29 +02:00
commit eaacfd249c
9 changed files with 109 additions and 19 deletions

View file

@ -694,12 +694,40 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
/* https://tools.ietf.org/html/rfc2132#section-8.1 */
v_str = nm_utils_buf_utf8safe_escape((char *) l_data, l_data_len, 0, &to_free);
v_str = nm_utils_buf_utf8safe_escape((char *) l_data,
l_data_len,
NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL,
&to_free);
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 ?: "");
}
r = n_dhcp4_client_lease_get_file(lease, &v_str);
if (r == 0) {
gs_free char *to_free = NULL;
v_str = nm_utils_buf_utf8safe_escape(v_str,
-1,
NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL,
&to_free);
nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_NM_FILENAME, v_str ?: "");
}
r = _client_lease_query(lease, NM_DHCP_OPTION_DHCP4_BOOTFILE_NAME, &l_data, &l_data_len);
if (r == 0 && nm_dhcp_lease_data_parse_cstr(l_data, l_data_len, &l_data_len)) {
gs_free char *to_free = NULL;
v_str = nm_utils_buf_utf8safe_escape((char *) l_data,
l_data_len,
NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL,
&to_free);
nm_dhcp_option_add_option(options,
AF_INET,
NM_DHCP_OPTION_DHCP4_BOOTFILE_NAME,
v_str ?: "");
}
lease_parse_address_list(lease, ip4_config, NM_DHCP_OPTION_DHCP4_NIS_SERVERS, options, &sbuf);
lease_parse_address_list(lease,

View file

@ -169,6 +169,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),
REQ(NM_DHCP_OPTION_DHCP4_NM_FILENAME, "filename", FALSE),
};
static const NMDhcpOption *const _sorted_options_4[G_N_ELEMENTS(_nm_dhcp_option_dhcp4_options)] = {
@ -184,7 +185,7 @@ static const NMDhcpOption *const _sorted_options_4[G_N_ELEMENTS(_nm_dhcp_option_
A(98), A(99), A(100), A(101), A(102), A(103), A(104), A(105), A(106), A(107), A(108), A(109),
A(110), A(111), A(112), A(113), A(114), A(115), A(116), A(117), A(118), A(119), A(120), A(121),
A(122), A(123), A(124), A(125), A(126), A(127), A(128), A(129), A(130), A(131), A(132), A(133),
A(134), A(15), A(135), A(136), A(16), A(137), A(138), A(139), A(140), A(141),
A(134), A(15), A(135), A(136), A(16), A(137), A(138), A(139), A(140), A(141), A(142),
#undef A
};
@ -404,7 +405,10 @@ nm_dhcp_option_add_option_utf8safe_escape(GHashTable * options,
gs_free char *to_free = NULL;
const char * escaped;
escaped = nm_utils_buf_utf8safe_escape((char *) data, n_data, 0, &to_free);
escaped = nm_utils_buf_utf8safe_escape((char *) data,
n_data,
NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL,
&to_free);
nm_dhcp_option_add_option(options, addr_family, option, escaped ?: "");
}

View file

@ -153,6 +153,7 @@ typedef enum {
NM_DHCP_OPTION_DHCP4_NM_IP_ADDRESS = 1024,
NM_DHCP_OPTION_DHCP4_NM_EXPIRY = 1025,
NM_DHCP_OPTION_DHCP4_NM_NEXT_SERVER = 1026,
NM_DHCP_OPTION_DHCP4_NM_FILENAME = 1027, /* 'file' DHCP header */
} NMDhcpOptionDhcp4Options;
typedef enum {
@ -185,7 +186,7 @@ typedef struct {
bool include;
} NMDhcpOption;
extern const NMDhcpOption _nm_dhcp_option_dhcp4_options[142];
extern const NMDhcpOption _nm_dhcp_option_dhcp4_options[143];
extern const NMDhcpOption _nm_dhcp_option_dhcp6_options[16];
static inline const char *

View file

@ -2343,8 +2343,9 @@ _nm_config_state_set(NMConfig *self, gboolean allow_persist, gboolean force_pers
"route-metric-default-aspired"
#define DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_ROUTE_METRIC_DEFAULT_EFFECTIVE \
"route-metric-default-effective"
#define DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_ROOT_PATH "root-path"
#define DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_NEXT_SERVER "next-server"
#define DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_ROOT_PATH "root-path"
#define DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_NEXT_SERVER "next-server"
#define DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_DHCP_BOOTFILE "dhcp-bootfile"
static NM_UTILS_LOOKUP_STR_DEFINE(
_device_state_managed_type_to_str,
@ -2565,7 +2566,8 @@ nm_config_device_state_write(int ifindex,
guint32 route_metric_default_aspired,
guint32 route_metric_default_effective,
const char * next_server,
const char * root_path)
const char * root_path,
const char * dhcp_bootfile)
{
char path[NM_STRLEN(NM_CONFIG_DEVICE_STATE_DIR "/") + DEVICE_STATE_FILENAME_LEN_MAX + 1];
GError *local = NULL;
@ -2632,6 +2634,12 @@ nm_config_device_state_write(int ifindex,
DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_ROOT_PATH,
root_path);
}
if (dhcp_bootfile) {
g_key_file_set_string(kf,
DEVICE_RUN_STATE_KEYFILE_GROUP_DEVICE,
DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_DHCP_BOOTFILE,
dhcp_bootfile);
}
if (!g_key_file_save_to_file(kf, path, &local)) {
_LOGW("device-state: write #%d (%s) failed: %s", ifindex, path, local->message);
@ -2639,7 +2647,9 @@ nm_config_device_state_write(int ifindex,
return FALSE;
}
_LOGT("device-state: write #%d (%s); managed=%s%s%s%s%s%s%s, "
"route-metric-default=%" G_GUINT32_FORMAT "-%" G_GUINT32_FORMAT "%s%s%s%s%s%s",
"route-metric-default=%" G_GUINT32_FORMAT "-%" G_GUINT32_FORMAT "%s%s%s"
"%s%s%s"
"%s%s%s",
ifindex,
path,
_device_state_managed_type_to_str(managed),
@ -2648,7 +2658,8 @@ nm_config_device_state_write(int ifindex,
route_metric_default_aspired,
route_metric_default_effective,
NM_PRINT_FMT_QUOTED(next_server, ", next-server=", next_server, "", ""),
NM_PRINT_FMT_QUOTED(root_path, ", root-path=", root_path, "", ""));
NM_PRINT_FMT_QUOTED(root_path, ", root-path=", root_path, "", ""),
NM_PRINT_FMT_QUOTED(dhcp_bootfile, ", dhcp-bootfile=", dhcp_bootfile, "", ""));
return TRUE;
}

View file

@ -185,7 +185,8 @@ gboolean nm_config_device_state_write(int
guint32 route_metric_default_aspired,
guint32 route_metric_default_effective,
const char * next_server,
const char * root_path);
const char * root_path,
const char * dhcp_bootfile);
void nm_config_device_state_prune_stale(GHashTable *preserve_ifindexes,
NMPlatform *preserve_in_platform);

View file

@ -6803,8 +6803,9 @@ nm_manager_write_device_state(NMManager *self, NMDevice *device, int *out_ifinde
guint32 route_metric_default_effective;
NMTernary nm_owned;
NMDhcpConfig * dhcp_config;
const char * next_server = NULL;
const char * root_path = NULL;
const char * next_server = NULL;
const char * root_path = NULL;
const char * dhcp_bootfile = NULL;
NM_SET_OUT(out_ifindex, 0);
@ -6848,8 +6849,11 @@ nm_manager_write_device_state(NMManager *self, NMDevice *device, int *out_ifinde
dhcp_config = nm_device_get_dhcp_config(device, AF_INET);
if (dhcp_config) {
root_path = nm_dhcp_config_get_option(dhcp_config, "root_path");
next_server = nm_dhcp_config_get_option(dhcp_config, "next_server");
root_path = nm_dhcp_config_get_option(dhcp_config, "root_path");
next_server = nm_dhcp_config_get_option(dhcp_config, "next_server");
dhcp_bootfile = nm_dhcp_config_get_option(dhcp_config, "filename");
if (!dhcp_bootfile)
dhcp_bootfile = nm_dhcp_config_get_option(dhcp_config, "bootfile_name");
}
if (!nm_config_device_state_write(ifindex,
@ -6860,7 +6864,8 @@ nm_manager_write_device_state(NMManager *self, NMDevice *device, int *out_ifinde
route_metric_default_aspired,
route_metric_default_effective,
next_server,
root_path))
root_path,
dhcp_bootfile))
return FALSE;
NM_SET_OUT(out_ifindex, ifindex);

View file

@ -37,6 +37,7 @@ global:
n_dhcp4_client_lease_get_siaddr;
n_dhcp4_client_lease_get_lifetime;
n_dhcp4_client_lease_get_server_identifier;
n_dhcp4_client_lease_get_file;
n_dhcp4_client_lease_query;
n_dhcp4_client_lease_select;
n_dhcp4_client_lease_accept;

View file

@ -249,9 +249,11 @@ _c_public_ void n_dhcp4_client_lease_get_lifetime(NDhcp4ClientLease *lease, uint
* Gets the address contained in the server-identifier DHCP option, in network
* byte order.
*
* Return: 0 on success, negative error code on failure.
* Return: 0 on success,
* N_DHCP4_E_UNSET if the lease doesn't contain a server-identifier, or
* N_DCHP4_E_INTERNAL if the server-identifier is not valid.
*/
_c_public_ int n_dhcp4_client_lease_get_server_identifier (NDhcp4ClientLease *lease, struct in_addr *addr) {
_c_public_ int n_dhcp4_client_lease_get_server_identifier(NDhcp4ClientLease *lease, struct in_addr *addr) {
uint8_t *data;
size_t n_data;
int r;
@ -260,13 +262,49 @@ _c_public_ int n_dhcp4_client_lease_get_server_identifier (NDhcp4ClientLease *le
if (r)
return r;
if (n_data < sizeof(struct in_addr))
return N_DHCP4_E_MALFORMED;
return N_DHCP4_E_INTERNAL;
memcpy(addr, data, sizeof(struct in_addr));
return 0;
}
/**
* n_dhcp4_client_lease_get_file() - query the lease for the boot file name
* @lease: the lease to operate on
* @file: return argument for the file name
*
* Query the lease for the boot file name from the DHCP header. The file name
* is returned as a NULL-terminated string.
*
* Return: 0 on success,
* N_DHCP4_E_UNSET if the lease does not contain a file name, or
* N_DCHP4_E_INTERNAL if the file name is invalid.
*/
_c_public_ int n_dhcp4_client_lease_get_file(NDhcp4ClientLease *lease, const char **file) {
NDhcp4Message *message;
if (lease->message->options[N_DHCP4_OPTION_OVERLOAD].size > 0
&& ((*lease->message->options[N_DHCP4_OPTION_OVERLOAD].value) & N_DHCP4_OVERLOAD_FILE)) {
/* The field is overloaded to contain other options */
return N_DHCP4_E_UNSET;
}
message = &lease->message->message;
if (message->file[0] == '\0')
return N_DHCP4_E_UNSET;
if (!memchr(message->file, '\0', sizeof(message->file))) {
/* The field is NULL-terminated (RFC 2131 section 2) */
return N_DHCP4_E_INTERNAL;
}
*file = (const char *) message->file;
return 0;
}
/**
* n_dhcp4_client_lease_query() - query the lease for an option
* @lease: the lease to operate on

View file

@ -171,7 +171,8 @@ void n_dhcp4_client_lease_get_siaddr(NDhcp4ClientLease *lease, struct in_addr *s
void n_dhcp4_client_lease_get_basetime(NDhcp4ClientLease *lease, uint64_t *ns_basetimep);
void n_dhcp4_client_lease_get_lifetime(NDhcp4ClientLease *lease, uint64_t *ns_lifetimep);
int n_dhcp4_client_lease_query(NDhcp4ClientLease *lease, uint8_t option, uint8_t **datap, size_t *n_datap);
int n_dhcp4_client_lease_get_server_identifier (NDhcp4ClientLease *lease, struct in_addr *addr);
int n_dhcp4_client_lease_get_server_identifier(NDhcp4ClientLease *lease, struct in_addr *addr);
int n_dhcp4_client_lease_get_file(NDhcp4ClientLease *lease, const char **file);
int n_dhcp4_client_lease_select(NDhcp4ClientLease *lease);
int n_dhcp4_client_lease_accept(NDhcp4ClientLease *lease);