networkd: add and expose per-link LLMNR config option
This commit is contained in:
parent
9ccde88c5a
commit
bd8f653876
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue