From bd8f65387673e29f46136a4ed172097035002c23 Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Sun, 3 Aug 2014 18:45:07 +0200 Subject: [PATCH 1/1] networkd: add and expose per-link LLMNR config option --- man/systemd.network.xml | 9 ++ src/network/networkd-link.c | 54 +----------- src/network/networkd-network-gperf.gperf | 1 + src/network/networkd-network.c | 106 +++++++++++++++++++++++ src/network/networkd.h | 19 ++++ src/network/sd-network.c | 19 ++++ src/systemd/sd-network.h | 6 ++ 7 files changed, 162 insertions(+), 52 deletions(-) diff --git a/man/systemd.network.xml b/man/systemd.network.xml index c01bffd52..3af199e84 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -224,6 +224,15 @@ + + LLMNR= + + A boolean or resolve. When true, enables + Link-Local Multicast Name Resolution on the link, when set to + resolve only resolution is enabled, but not + announcement. Defaults to true. + + Address= diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 172be64a7..e674b3b12 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -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; -} diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 3a58a4043..e5e666451 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -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 diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index c99dab809..056e063f2 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -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; +} diff --git a/src/network/networkd.h b/src/network/networkd.h index 5d7a08be0..d5c229cf4 100644 --- a/src/network/networkd.h +++ b/src/network/networkd.h @@ -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); diff --git a/src/network/sd-network.c b/src/network/sd-network.c index bfb8321c8..a0f147e02 100644 --- a/src/network/sd-network.c +++ b/src/network/sd-network.c @@ -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; diff --git a/src/systemd/sd-network.h b/src/systemd/sd-network.h index ec01e07e8..4d04616d8 100644 --- a/src/systemd/sd-network.h +++ b/src/systemd/sd-network.h @@ -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); -- 2.30.2