netconfig: Install search domains obtained from DHCPv6

This commit is contained in:
Denis Kenzior 2020-11-18 12:00:17 -06:00
parent 9e541fe7e8
commit 3890431090
3 changed files with 105 additions and 51 deletions

View File

@ -222,6 +222,65 @@ static int netconfig_set_dns(struct netconfig *netconfig)
return 0; return 0;
} }
static void append_domain(char **domains, unsigned int *n_domains,
size_t max, char *domain)
{
unsigned int i;
if (*n_domains == max)
return;
for (i = 0; i < *n_domains; i++)
if (!strcmp(domains[i], domain))
return;
domains[*n_domains] = domain;
*n_domains += 1;
}
static int netconfig_set_domains(struct netconfig *netconfig)
{
char *domains[31];
unsigned int n_domains = 0;
char *v4_domain = NULL;
char **v6_domains = NULL;
char **p;
memset(domains, 0, sizeof(domains));
/* Allow to override the DHCP domain name with setting entry. */
v4_domain = l_settings_get_string(netconfig->active_settings,
"IPv4", "DomainName");
if (!v4_domain && netconfig->rtm_protocol == RTPROT_DHCP) {
const struct l_dhcp_lease *lease =
l_dhcp_client_get_lease(netconfig->dhcp_client);
if (lease)
v4_domain = l_dhcp_lease_get_domain_name(lease);
}
append_domain(domains, &n_domains,
L_ARRAY_SIZE(domains) - 1, v4_domain);
if (netconfig->rtm_v6_protocol == RTPROT_DHCP) {
const struct l_dhcp6_lease *lease =
l_dhcp6_client_get_lease(netconfig->dhcp6_client);
if (lease)
v6_domains = l_dhcp6_lease_get_domains(lease);
}
for (p = v6_domains; p && *p; p++)
append_domain(domains, &n_domains,
L_ARRAY_SIZE(domains) - 1, *p);
resolve_set_domains(netconfig->resolve, domains);
l_strv_free(v6_domains);
l_free(v4_domain);
return 0;
}
static struct netconfig_ifaddr *netconfig_ipv4_get_ifaddr( static struct netconfig_ifaddr *netconfig_ipv4_get_ifaddr(
struct netconfig *netconfig, struct netconfig *netconfig,
uint8_t proto) uint8_t proto)
@ -333,28 +392,6 @@ static char *netconfig_ipv4_get_gateway(struct netconfig *netconfig)
return NULL; return NULL;
} }
static char *netconfig_ipv4_get_domain_name(struct netconfig *netconfig,
uint8_t proto)
{
const struct l_dhcp_lease *lease;
char *domain_name;
domain_name = l_settings_get_string(netconfig->active_settings,
"IPv4", "DomainName");
if (domain_name)
/* Allow to override the DHCP domain name with setting entry. */
return domain_name;
if (proto != RTPROT_DHCP)
return NULL;
lease = l_dhcp_client_get_lease(netconfig->dhcp_client);
if (!lease)
return NULL;
return l_dhcp_lease_get_domain_name(lease);
}
static struct netconfig_ifaddr *netconfig_ipv6_get_ifaddr( static struct netconfig_ifaddr *netconfig_ipv6_get_ifaddr(
struct netconfig *netconfig, struct netconfig *netconfig,
uint8_t proto) uint8_t proto)
@ -775,7 +812,6 @@ static void netconfig_ipv4_ifaddr_add_cmd_cb(int error, uint16_t type,
{ {
struct netconfig *netconfig = user_data; struct netconfig *netconfig = user_data;
struct netconfig_ifaddr *ifaddr; struct netconfig_ifaddr *ifaddr;
char *domain_name;
if (error && error != -EEXIST) { if (error && error != -EEXIST) {
l_error("netconfig: Failed to add IP address. " l_error("netconfig: Failed to add IP address. "
@ -798,14 +834,7 @@ static void netconfig_ipv4_ifaddr_add_cmd_cb(int error, uint16_t type,
} }
netconfig_set_dns(netconfig); netconfig_set_dns(netconfig);
netconfig_set_domains(netconfig);
domain_name = netconfig_ipv4_get_domain_name(netconfig,
netconfig->rtm_protocol);
if (!domain_name)
goto done;
resolve_add_domain_name(netconfig->resolve, domain_name);
l_free(domain_name);
done: done:
netconfig_ifaddr_destroy(ifaddr); netconfig_ifaddr_destroy(ifaddr);

View File

@ -39,8 +39,7 @@
struct resolve_ops { struct resolve_ops {
void (*set_dns)(struct resolve *resolve, char **dns_list); void (*set_dns)(struct resolve *resolve, char **dns_list);
void (*add_domain_name)(struct resolve *resolve, void (*set_domains)(struct resolve *resolve, char **domain_list);
const char *domain_name);
void (*revert)(struct resolve *resolve); void (*revert)(struct resolve *resolve);
void (*destroy)(struct resolve *resolve); void (*destroy)(struct resolve *resolve);
}; };
@ -68,15 +67,15 @@ void resolve_set_dns(struct resolve *resolve, char **dns_list)
resolve->ops->set_dns(resolve, dns_list); resolve->ops->set_dns(resolve, dns_list);
} }
void resolve_add_domain_name(struct resolve *resolve, const char *domain_name) void resolve_set_domains(struct resolve *resolve, char **domain_list)
{ {
if (!domain_name) if (!domain_list)
return; return;
if (!resolve->ops->add_domain_name) if (!resolve->ops->set_domains)
return; return;
resolve->ops->add_domain_name(resolve, domain_name); resolve->ops->set_domains(resolve, domain_list);
} }
void resolve_revert(struct resolve *resolve) void resolve_revert(struct resolve *resolve)
@ -210,7 +209,7 @@ static void resolve_systemd_set_dns(struct resolve *resolve, char **dns_list)
NULL, NULL); NULL, NULL);
} }
static void systemd_link_add_domains_reply(struct l_dbus_message *message, static void systemd_set_link_domains_reply(struct l_dbus_message *message,
void *user_data) void *user_data)
{ {
const char *name; const char *name;
@ -225,10 +224,12 @@ static void systemd_link_add_domains_reply(struct l_dbus_message *message,
name, text); name, text);
} }
static void resolve_systemd_add_domain_name(struct resolve *resolve, static void resolve_systemd_set_domains(struct resolve *resolve,
const char *domain_name) char **domain_list)
{ {
struct l_dbus_message *message; struct l_dbus_message *message;
struct l_dbus_message_builder *builder;
bool f = false;
l_debug("ifindex: %u", resolve->ifindex); l_debug("ifindex: %u", resolve->ifindex);
@ -244,11 +245,29 @@ static void resolve_systemd_add_domain_name(struct resolve *resolve,
if (!message) if (!message)
return; return;
l_dbus_message_set_arguments(message, "ia(sb)", resolve->ifindex, builder = l_dbus_message_builder_new(message);
1, domain_name, false); if (!builder) {
l_dbus_message_unref(message);
return;
}
l_dbus_message_builder_append_basic(builder, 'i', &resolve->ifindex);
l_dbus_message_builder_enter_array(builder, "(sb)");
for (; *domain_list; domain_list++) {
l_dbus_message_builder_enter_struct(builder, "sb");
l_dbus_message_builder_append_basic(builder, 's', *domain_list);
l_dbus_message_builder_append_basic(builder, 'b', &f);
l_dbus_message_builder_leave_struct(builder);
}
l_dbus_message_builder_leave_array(builder);
l_dbus_message_builder_finalize(builder);
l_dbus_message_builder_destroy(builder);
l_dbus_send_with_reply(dbus_get_bus(), message, l_dbus_send_with_reply(dbus_get_bus(), message,
systemd_link_add_domains_reply, NULL, NULL); systemd_set_link_domains_reply, NULL, NULL);
} }
static void resolve_systemd_revert(struct resolve *resolve) static void resolve_systemd_revert(struct resolve *resolve)
@ -282,7 +301,7 @@ static void resolve_systemd_destroy(struct resolve *resolve)
static const struct resolve_ops systemd_ops = { static const struct resolve_ops systemd_ops = {
.set_dns = resolve_systemd_set_dns, .set_dns = resolve_systemd_set_dns,
.add_domain_name = resolve_systemd_add_domain_name, .set_domains = resolve_systemd_set_domains,
.revert = resolve_systemd_revert, .revert = resolve_systemd_revert,
.destroy = resolve_systemd_destroy, .destroy = resolve_systemd_destroy,
}; };
@ -398,19 +417,25 @@ static void resolve_resolvconf_set_dns(struct resolve *resolve, char **dns_list)
rc->have_dns = true; rc->have_dns = true;
} }
static void resolve_resolvconf_add_domain_name(struct resolve *resolve, static void resolve_resolvconf_set_domains(struct resolve *resolve,
const char *domain_name) char **domain_list)
{ {
struct resolvconf *rc = struct resolvconf *rc =
l_container_of(resolve, struct resolvconf, super); l_container_of(resolve, struct resolvconf, super);
L_AUTO_FREE_VAR(char *, domain_str) = NULL; struct l_string *content;
L_AUTO_FREE_VAR(char *, str) = NULL;
if (L_WARN_ON(!resolvconf_path)) if (L_WARN_ON(!resolvconf_path))
return; return;
domain_str = l_strdup_printf("search %s\n", domain_name); content = l_string_new(0);
if (resolvconf_invoke(rc->ifname, "domain", domain_str)) for (; *domain_list; domain_list++)
l_string_append_printf(content, "search %s\n", *domain_list);
str = l_string_unwrap(content);
if (resolvconf_invoke(rc->ifname, "domain", str))
rc->have_domain = true; rc->have_domain = true;
} }
@ -440,7 +465,7 @@ static void resolve_resolvconf_destroy(struct resolve *resolve)
static struct resolve_ops resolvconf_ops = { static struct resolve_ops resolvconf_ops = {
.set_dns = resolve_resolvconf_set_dns, .set_dns = resolve_resolvconf_set_dns,
.add_domain_name = resolve_resolvconf_add_domain_name, .set_domains = resolve_resolvconf_set_domains,
.revert = resolve_resolvconf_revert, .revert = resolve_resolvconf_revert,
.destroy = resolve_resolvconf_destroy, .destroy = resolve_resolvconf_destroy,
}; };

View File

@ -22,6 +22,6 @@
struct resolve *resolve_new(uint32_t ifindex); struct resolve *resolve_new(uint32_t ifindex);
void resolve_set_dns(struct resolve *resolve, char **dns_list); void resolve_set_dns(struct resolve *resolve, char **dns_list);
void resolve_add_domain_name(struct resolve *resolve, const char *domain_name); void resolve_set_domains(struct resolve *resolve, char **domain_list);
void resolve_revert(struct resolve *resolve); void resolve_revert(struct resolve *resolve);
void resolve_free(struct resolve *resolve); void resolve_free(struct resolve *resolve);