networkd: add and expose per-link LLMNR config option

This commit is contained in:
Tom Gundersen 2014-08-03 18:45:07 +02:00
parent 9ccde88c5a
commit bd8f653876
7 changed files with 162 additions and 52 deletions

View File

@ -224,6 +224,15 @@
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>LLMNR=</varname></term>
<listitem>
<para>A boolean or <literal>resolve</literal>. When true, enables
Link-Local Multicast Name Resolution on the link, when set to
<literal>resolve</literal> only resolution is enabled, but not
announcement. Defaults to true.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>Address=</varname></term>
<listitem>

View File

@ -2385,6 +2385,8 @@ int link_save(Link *link) {
(address + 1 ? " " : ""));
fputs("\n", f);
fprintf(f, "LLMNR=%s\n", llmnr_support_to_string(link->network->llmnr));
}
if (link->dhcp_lease) {
@ -2437,55 +2439,3 @@ static const char* const link_operstate_table[_LINK_OPERSTATE_MAX] = {
};
DEFINE_STRING_TABLE_LOOKUP(link_operstate, LinkOperationalState);
static const char* const dhcp_support_table[_DHCP_SUPPORT_MAX] = {
[DHCP_SUPPORT_NONE] = "none",
[DHCP_SUPPORT_BOTH] = "both",
[DHCP_SUPPORT_V4] = "v4",
[DHCP_SUPPORT_V6] = "v6",
};
DEFINE_STRING_TABLE_LOOKUP(dhcp_support, DHCPSupport);
int config_parse_dhcp(
const char* unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
DHCPSupport *dhcp = data;
int k;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
/* Our enum shall be a superset of booleans, hence first try
* to parse as boolean, and then as enum */
k = parse_boolean(rvalue);
if (k > 0)
*dhcp = DHCP_SUPPORT_BOTH;
else if (k == 0)
*dhcp = DHCP_SUPPORT_NONE;
else {
DHCPSupport s;
s = dhcp_support_from_string(rvalue);
if (s < 0){
log_syntax(unit, LOG_ERR, filename, line, -s, "Failed to parse DHCP option, ignoring: %s", rvalue);
return 0;
}
*dhcp = s;
}
return 0;
}

View File

@ -38,6 +38,7 @@ Network.IPv4LLRoute, config_parse_bool, 0,
Network.Address, config_parse_address, 0, 0
Network.Gateway, config_parse_gateway, 0, 0
Network.DNS, config_parse_strv, 0, offsetof(Network, dns)
Network.LLMNR, config_parse_llmnr, 0, offsetof(Network, llmnr)
Network.NTP, config_parse_strv, 0, offsetof(Network, ntp)
Address.Address, config_parse_address, 0, 0
Address.Peer, config_parse_address, 0, 0

View File

@ -80,6 +80,7 @@ static int network_load_one(Manager *manager, const char *filename) {
network->ipv4ll_route = true;
network->dhcp = DHCP_SUPPORT_NONE;
network->dhcp_ntp = true;
network->dhcp_dns = true;
network->dhcp_hostname = true;
@ -87,6 +88,8 @@ static int network_load_one(Manager *manager, const char *filename) {
network->dhcp_routes = true;
network->dhcp_sendhost = true;
network->llmnr = LLMNR_SUPPORT_YES;
r = config_parse(NULL, filename, file,
"Match\0Network\0Address\0Route\0DHCP\0DHCPv4\0",
config_item_perf_lookup, network_network_gperf_lookup,
@ -387,3 +390,106 @@ int config_parse_tunnel(const char *unit,
return 0;
}
static const char* const dhcp_support_table[_DHCP_SUPPORT_MAX] = {
[DHCP_SUPPORT_NONE] = "none",
[DHCP_SUPPORT_BOTH] = "both",
[DHCP_SUPPORT_V4] = "v4",
[DHCP_SUPPORT_V6] = "v6",
};
DEFINE_STRING_TABLE_LOOKUP(dhcp_support, DHCPSupport);
int config_parse_dhcp(
const char* unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
DHCPSupport *dhcp = data;
int k;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
/* Our enum shall be a superset of booleans, hence first try
* to parse as boolean, and then as enum */
k = parse_boolean(rvalue);
if (k > 0)
*dhcp = DHCP_SUPPORT_BOTH;
else if (k == 0)
*dhcp = DHCP_SUPPORT_NONE;
else {
DHCPSupport s;
s = dhcp_support_from_string(rvalue);
if (s < 0){
log_syntax(unit, LOG_ERR, filename, line, -s, "Failed to parse DHCP option, ignoring: %s", rvalue);
return 0;
}
*dhcp = s;
}
return 0;
}
static const char* const llmnr_support_table[_LLMNR_SUPPORT_MAX] = {
[LLMNR_SUPPORT_NO] = "no",
[LLMNR_SUPPORT_YES] = "yes",
[LLMNR_SUPPORT_RESOLVE] = "resolve",
};
DEFINE_STRING_TABLE_LOOKUP(llmnr_support, LLMNRSupport);
int config_parse_llmnr(
const char* unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
LLMNRSupport *llmnr = data;
int k;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
/* Our enum shall be a superset of booleans, hence first try
* to parse as boolean, and then as enum */
k = parse_boolean(rvalue);
if (k > 0)
*llmnr = LLMNR_SUPPORT_YES;
else if (k == 0)
*llmnr = LLMNR_SUPPORT_NO;
else {
LLMNRSupport s;
s = llmnr_support_from_string(rvalue);
if (s < 0){
log_syntax(unit, LOG_ERR, filename, line, -s, "Failed to parse LLMNR option, ignoring: %s", rvalue);
return 0;
}
*llmnr = s;
}
return 0;
}

View File

@ -61,6 +61,14 @@ typedef enum DHCPSupport {
_DHCP_SUPPORT_INVALID = -1,
} DHCPSupport;
typedef enum LLMNRSupport {
LLMNR_SUPPORT_NO,
LLMNR_SUPPORT_YES,
LLMNR_SUPPORT_RESOLVE,
_LLMNR_SUPPORT_MAX,
_LLMNR_SUPPORT_INVALID = -1,
} LLMNRSupport;
struct Network {
Manager *manager;
@ -105,6 +113,8 @@ struct Network {
char **dns, **ntp;
LLMNRSupport llmnr;
LIST_FIELDS(Network, networks);
};
@ -383,6 +393,15 @@ int config_parse_dhcp(const char *unit, const char *filename, unsigned line,
const char *section, unsigned section_line, const char *lvalue,
int ltype, const char *rvalue, void *data, void *userdata);
/* LLMNR support */
const char* llmnr_support_to_string(LLMNRSupport i) _const_;
LLMNRSupport llmnr_support_from_string(const char *s) _pure_;
int config_parse_llmnr(const char *unit, const char *filename, unsigned line,
const char *section, unsigned section_line, const char *lvalue,
int ltype, const char *rvalue, void *data, void *userdata);
/* Address Pool */
int address_pool_new(Manager *m, AddressPool **ret, int family, const union in_addr_union *u, unsigned prefixlen);

View File

@ -107,6 +107,25 @@ _public_ int sd_network_get_link_operational_state(int ifindex, char **state) {
return 0;
}
_public_ int sd_network_get_llmnr(int ifindex, char **llmnr) {
_cleanup_free_ char *s = NULL, *p = NULL;
int r;
assert_return(ifindex > 0, -EINVAL);
assert_return(llmnr, -EINVAL);
r = parse_env_file(p, NEWLINE, "LLMNR", &s, NULL);
if (r == -ENOENT)
return -ENODATA;
else if (r < 0)
return r;
*llmnr = s;
s = NULL;
return 0;
}
_public_ int sd_network_get_dhcp_lease(int ifindex, sd_dhcp_lease **ret) {
_cleanup_free_ char *p = NULL, *s = NULL;
sd_dhcp_lease *lease = NULL;

View File

@ -76,6 +76,12 @@ int sd_network_get_operational_state(char **state);
/* Get DHCPv4 lease from ifindex. */
int sd_network_get_dhcp_lease(int ifindex, sd_dhcp_lease **ret);
/* Indicates whether or not LLMNR should be enabled for the link
* Possible levels of support: yes, no, resolve
* Possible return codes:
* -ENODATA: networkd is not aware of the link*/
int sd_network_get_llmnr(int ifindex, char **llmnr);
/* Get DNS entries for a given link. These are string representations of
* IP addresses */
int sd_network_get_dns(int ifindex, char ***addr);