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;
}
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(
struct netconfig *netconfig,
uint8_t proto)
@ -333,28 +392,6 @@ static char *netconfig_ipv4_get_gateway(struct netconfig *netconfig)
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(
struct netconfig *netconfig,
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_ifaddr *ifaddr;
char *domain_name;
if (error && error != -EEXIST) {
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);
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);
netconfig_set_domains(netconfig);
done:
netconfig_ifaddr_destroy(ifaddr);

View File

@ -39,8 +39,7 @@
struct resolve_ops {
void (*set_dns)(struct resolve *resolve, char **dns_list);
void (*add_domain_name)(struct resolve *resolve,
const char *domain_name);
void (*set_domains)(struct resolve *resolve, char **domain_list);
void (*revert)(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);
}
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;
if (!resolve->ops->add_domain_name)
if (!resolve->ops->set_domains)
return;
resolve->ops->add_domain_name(resolve, domain_name);
resolve->ops->set_domains(resolve, domain_list);
}
void resolve_revert(struct resolve *resolve)
@ -210,7 +209,7 @@ static void resolve_systemd_set_dns(struct resolve *resolve, char **dns_list)
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)
{
const char *name;
@ -225,10 +224,12 @@ static void systemd_link_add_domains_reply(struct l_dbus_message *message,
name, text);
}
static void resolve_systemd_add_domain_name(struct resolve *resolve,
const char *domain_name)
static void resolve_systemd_set_domains(struct resolve *resolve,
char **domain_list)
{
struct l_dbus_message *message;
struct l_dbus_message_builder *builder;
bool f = false;
l_debug("ifindex: %u", resolve->ifindex);
@ -244,11 +245,29 @@ static void resolve_systemd_add_domain_name(struct resolve *resolve,
if (!message)
return;
l_dbus_message_set_arguments(message, "ia(sb)", resolve->ifindex,
1, domain_name, false);
builder = l_dbus_message_builder_new(message);
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,
systemd_link_add_domains_reply, NULL, NULL);
systemd_set_link_domains_reply, NULL, NULL);
}
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 = {
.set_dns = resolve_systemd_set_dns,
.add_domain_name = resolve_systemd_add_domain_name,
.set_domains = resolve_systemd_set_domains,
.revert = resolve_systemd_revert,
.destroy = resolve_systemd_destroy,
};
@ -398,19 +417,25 @@ static void resolve_resolvconf_set_dns(struct resolve *resolve, char **dns_list)
rc->have_dns = true;
}
static void resolve_resolvconf_add_domain_name(struct resolve *resolve,
const char *domain_name)
static void resolve_resolvconf_set_domains(struct resolve *resolve,
char **domain_list)
{
struct resolvconf *rc =
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))
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;
}
@ -440,7 +465,7 @@ static void resolve_resolvconf_destroy(struct resolve *resolve)
static struct resolve_ops resolvconf_ops = {
.set_dns = resolve_resolvconf_set_dns,
.add_domain_name = resolve_resolvconf_add_domain_name,
.set_domains = resolve_resolvconf_set_domains,
.revert = resolve_resolvconf_revert,
.destroy = resolve_resolvconf_destroy,
};

View File

@ -22,6 +22,6 @@
struct resolve *resolve_new(uint32_t ifindex);
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_free(struct resolve *resolve);