summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/systemd.network.xml9
-rw-r--r--src/network/networkd-link.c54
-rw-r--r--src/network/networkd-network-gperf.gperf1
-rw-r--r--src/network/networkd-network.c106
-rw-r--r--src/network/networkd.h19
-rw-r--r--src/network/sd-network.c19
-rw-r--r--src/systemd/sd-network.h6
7 files changed, 162 insertions, 52 deletions
diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index c01bffd52c..3af199e84a 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -225,6 +225,15 @@
</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>
<para>A static IPv4 or IPv6 address and its prefix length,
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 172be64a7e..e674b3b12c 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 3a58a4043b..e5e666451a 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 c99dab809b..056e063f26 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 5d7a08be0c..d5c229cf46 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 bfb8321c87..a0f147e023 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 ec01e07e85..4d04616d88 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);