chiark / gitweb /
networkd: add and expose per-link LLMNR config option
authorTom Gundersen <teg@jklm.no>
Sun, 3 Aug 2014 16:45:07 +0000 (18:45 +0200)
committerTom Gundersen <teg@jklm.no>
Mon, 4 Aug 2014 14:56:34 +0000 (16:56 +0200)
man/systemd.network.xml
src/network/networkd-link.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd.h
src/network/sd-network.c
src/systemd/sd-network.h

index c01bffd52cc4cc3e8ead483c6134bc753d53e214..3af199e84ac9b0d88614f0448c99b3e59f7e57fd 100644 (file)
                                                 </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>
index 172be64a7eb99e59128882b1f2a9fe79a59c6c34..e674b3b12c76070dafe56aa9d31dfa63bd26a1e5 100644 (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;
-}
index 3a58a4043bf016f7b51c3b209a296f6f11816ee7..e5e666451a4f885a4eb648b3e3dcbdf8236be426 100644 (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
index c99dab809b71054d27196710e41fb28d18e9dcd0..056e063f26a79a2e9b9e272dd8a6fbc868519eb1 100644 (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;
+}
index 5d7a08be0cf672bf56aa630958ccbacdc80b84f6..d5c229cf4620b361f384643739d9bbde64a1a7a5 100644 (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);
index bfb8321c879ae9b4a99634fdb5579726f072612c..a0f147e02316b9720ed33f21ec18f90bd9c9fa97 100644 (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;
index ec01e07e85ba28e14ef415d53d846905c5a99306..4d04616d8852b8b138632f699344bff5729915c3 100644 (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);