[systemd-commits] 4 commits - man/systemd.network.xml network/80-container-host0.network network/80-container-ve.network src/libsystemd src/network

Tom Gundersen tomegun at kemper.freedesktop.org
Mon Feb 9 03:20:35 PST 2015


 man/systemd.network.xml                  |    8 +--
 network/80-container-host0.network       |    2 
 network/80-container-ve.network          |    2 
 src/libsystemd/sd-rtnl/rtnl-types.c      |   19 ++++---
 src/network/networkd-ipv4ll.c            |    2 
 src/network/networkd-link-bus.c          |   15 +++++
 src/network/networkd-link.c              |   56 +++++++++++++++++++++-
 src/network/networkd-link.h              |    1 
 src/network/networkd-network-gperf.gperf |    4 +
 src/network/networkd-network.c           |   78 ++++++++++++++++++++++++++++++-
 src/network/networkd.h                   |   14 +++++
 11 files changed, 179 insertions(+), 22 deletions(-)

New commits:
commit c8f5edeab0b007081cf89aeb1d23d428382c2a4f
Author: Tom Gundersen <teg at jklm.no>
Date:   Mon Feb 9 12:00:33 2015 +0100

    networkd: bus - switch to properly escaped object paths

diff --git a/src/network/networkd-link-bus.c b/src/network/networkd-link-bus.c
index 7c4f473..370707c 100644
--- a/src/network/networkd-link-bus.c
+++ b/src/network/networkd-link-bus.c
@@ -38,12 +38,18 @@ const sd_bus_vtable link_vtable[] = {
 };
 
 static char *link_bus_path(Link *link) {
+        _cleanup_free_ char *ifindex = NULL;
         char *p;
+        int r;
 
         assert(link);
         assert(link->ifindex > 0);
 
-        if (asprintf(&p, "/org/freedesktop/network1/link/_%d", link->ifindex) < 0)
+        if (asprintf(&ifindex, "%d", link->ifindex) < 0)
+                return NULL;
+
+        r = sd_bus_path_encode("/org/freedesktop/network1/link", ifindex, &p);
+        if (r < 0)
                 return NULL;
 
         return p;
@@ -80,6 +86,7 @@ int link_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***
 }
 
 int link_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
+        _cleanup_free_ char *identifier = NULL;
         Manager *m = userdata;
         Link *link;
         int ifindex, r;
@@ -90,7 +97,11 @@ int link_object_find(sd_bus *bus, const char *path, const char *interface, void
         assert(m);
         assert(found);
 
-        if (sscanf(path, "/org/freedesktop/network1/link/_%d", &ifindex) != 1)
+        r = sd_bus_path_decode(path, "/org/freedesktop/network1/link", &identifier);
+        if (r < 0)
+                return 0;
+
+        if (sscanf(identifier, "%d", &ifindex) != 1)
                 return 0;
 
         r = link_get(m, ifindex, &link);

commit 7f77697a1744f8df2089848b9d718faf7ba6c665
Author: Tom Gundersen <teg at jklm.no>
Date:   Sun Feb 8 23:20:56 2015 +0100

    networkd: add support for IPv6 tokens
    
    This allows the admin to set the host-specific part of IPv6 addresses, but still
    receive the prefix via SLAAC.
    
    .network file snippet:
    
    [Network]
    IPv6Token=::12
    
    gives:
    
    $ ip token
    token ::12 dev eth0
    
    This closes https://bugs.freedesktop.org/show_bug.cgi?id=81177.

diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 3b9881d..1f96c63 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -1097,36 +1097,44 @@ static int link_up(Link *link) {
                 }
         }
 
-        if (!link_ipv6ll_enabled(link)) {
-                r = sd_rtnl_message_open_container(req, IFLA_AF_SPEC);
-                if (r < 0) {
-                        log_link_error(link, "Could not open IFLA_AF_SPEC container: %s", strerror(-r));
-                        return r;
-                }
+        r = sd_rtnl_message_open_container(req, IFLA_AF_SPEC);
+        if (r < 0) {
+                log_link_error(link, "Could not open IFLA_AF_SPEC container: %s", strerror(-r));
+                return r;
+        }
 
-                r = sd_rtnl_message_open_container(req, AF_INET6);
-                if (r < 0) {
-                        log_link_error(link, "Could not open AF_INET6 container: %s", strerror(-r));
-                        return r;
-                }
+        r = sd_rtnl_message_open_container(req, AF_INET6);
+        if (r < 0) {
+                log_link_error(link, "Could not open AF_INET6 container: %s", strerror(-r));
+                return r;
+        }
 
+        if (!link_ipv6ll_enabled(link)) {
                 r = sd_rtnl_message_append_u8(req, IFLA_INET6_ADDR_GEN_MODE, IN6_ADDR_GEN_MODE_NONE);
                 if (r < 0) {
                         log_link_error(link, "Could not append IFLA_INET6_ADDR_GEN_MODE: %s", strerror(-r));
                         return r;
                 }
+        }
 
-                r = sd_rtnl_message_close_container(req);
+        if (!in_addr_is_null(AF_INET6, &link->network->ipv6_token)) {
+                r = sd_rtnl_message_append_in6_addr(req, IFLA_INET6_TOKEN, &link->network->ipv6_token.in6);
                 if (r < 0) {
-                        log_link_error(link, "Could not close AF_INET6 contaire: %s", strerror(-r));
+                        log_link_error(link, "Could not append IFLA_INET6_TOKEN: %s", strerror(-r));
                         return r;
                 }
+        }
 
-                r = sd_rtnl_message_close_container(req);
-                if (r < 0) {
-                        log_link_error(link, "Could not close IFLA_AF_SPEC contaire: %s", strerror(-r));
-                        return r;
-                }
+        r = sd_rtnl_message_close_container(req);
+        if (r < 0) {
+                log_link_error(link, "Could not close AF_INET6 container: %s", strerror(-r));
+                return r;
+        }
+
+        r = sd_rtnl_message_close_container(req);
+        if (r < 0) {
+                log_link_error(link, "Could not close IFLA_AF_SPEC contaire: %s", strerror(-r));
+                return r;
         }
 
         r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link,
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index 525f2ba..6f29548 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -38,6 +38,7 @@ Network.DHCP,                config_parse_dhcp,                  0,
 Network.DHCPServer,          config_parse_bool,                  0,                             offsetof(Network, dhcp_server)
 Network.LinkLocal,           config_parse_address_family_boolean,0,                             offsetof(Network, link_local)
 Network.IPv4LLRoute,         config_parse_bool,                  0,                             offsetof(Network, ipv4ll_route)
+Network.IPv6Token,           config_parse_token,                 0,                             offsetof(Network, ipv6_token)
 Network.LLDP,                config_parse_bool,                  0,                             offsetof(Network, lldp)
 Network.Address,             config_parse_address,               0,                             0
 Network.Gateway,             config_parse_gateway,               0,                             0
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index c39ba6d..9ebc2d1 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -626,7 +626,7 @@ int config_parse_llmnr(
         assert(filename);
         assert(lvalue);
         assert(rvalue);
-        assert(data);
+        assert(llmnr);
 
         /* Our enum shall be a superset of booleans, hence first try
          * to parse as boolean, and then as enum */
@@ -650,3 +650,46 @@ int config_parse_llmnr(
 
         return 0;
 }
+
+int config_parse_token(
+                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) {
+
+        union in_addr_union buffer;
+        struct in6_addr *token = data;
+        int r;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(token);
+
+        r = in_addr_from_string(AF_INET6, rvalue, &buffer);
+        if (r < 0) {
+                log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to parse IPv6 token, ignoring: %s", rvalue);
+                return 0;
+        }
+
+        r = in_addr_is_null(AF_INET6, &buffer);
+        if (r < 0) {
+                log_syntax(unit, LOG_ERR, filename, line, -r, "IPv6 token canno t be the ANY address, ignoring: %s", rvalue);
+                return 0;
+        }
+
+        if ((buffer.in6.s6_addr32[0] | buffer.in6.s6_addr32[1]) != 0) {
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL, "IPv6 token canno t be longer than 64 bits, ignoring: %s", rvalue);
+                return 0;
+        }
+
+        *token = buffer.in6;
+
+        return 0;
+}
diff --git a/src/network/networkd.h b/src/network/networkd.h
index 4f3bcf3..6fb920b 100644
--- a/src/network/networkd.h
+++ b/src/network/networkd.h
@@ -128,6 +128,7 @@ struct Network {
         unsigned dhcp_route_metric;
         AddressFamilyBoolean link_local;
         bool ipv4ll_route;
+        union in_addr_union ipv6_token;
 
         bool dhcp_server;
 
@@ -405,6 +406,11 @@ int config_parse_ipv4ll(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);
 
+/* IPv6 support */
+int config_parse_token(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_;

commit d0d6a4cd70477970812bff0a37e70f66208d7c14
Author: Tom Gundersen <teg at jklm.no>
Date:   Sun Feb 8 22:27:15 2015 +0100

    networkd: generalize IPv4LL to LinkLocal
    
    This allows both IPv4 and IPv6 link-local addresses to be enabled or disabled. By default
    we still enable IPv6LL and disable IPv4LL. The old config option is kept for backwards
    compatibility, but removed from the documentation.

diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index b8facdc..6c137e1 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -236,10 +236,12 @@
           </listitem>
         </varlistentry>
         <varlistentry>
-          <term><varname>IPv4LL=</varname></term>
+          <term><varname>LinkLocal=</varname></term>
           <listitem>
-            <para>A boolean. When true, enables IPv4 link-local support.
-            </para>
+            <para>Enables link-local address autoconfiguration. Accepts
+            <literal>yes</literal>, <literal>no</literal>,
+            <literal>ipv4</literal>, or <literal>ipv6</literal>. Defaults to
+            <literal>ipv6</literal>.</para>
           </listitem>
         </varlistentry>
         <varlistentry>
diff --git a/network/80-container-host0.network b/network/80-container-host0.network
index 8d9293f..4e68c3d 100644
--- a/network/80-container-host0.network
+++ b/network/80-container-host0.network
@@ -11,4 +11,4 @@ Name=host0
 
 [Network]
 DHCP=yes
-IPv4LL=yes
+LinkLocal=yes
diff --git a/network/80-container-ve.network b/network/80-container-ve.network
index 7bde1d4..cac436d 100644
--- a/network/80-container-ve.network
+++ b/network/80-container-ve.network
@@ -12,6 +12,6 @@ Driver=veth
 [Network]
 # Default to using a /28 prefix, giving up to 13 addresses per container.
 Address=0.0.0.0/28
-IPv4LL=yes
+LinkLocal=yes
 DHCPServer=yes
 IPMasquerade=yes
diff --git a/src/network/networkd-ipv4ll.c b/src/network/networkd-ipv4ll.c
index 339bf4d..8050801 100644
--- a/src/network/networkd-ipv4ll.c
+++ b/src/network/networkd-ipv4ll.c
@@ -209,7 +209,7 @@ int ipv4ll_configure(Link *link) {
 
         assert(link);
         assert(link->network);
-        assert(link->network->ipv4ll);
+        assert(IN_SET(link->network->link_local, ADDRESS_FAMILY_IPV4, ADDRESS_FAMILY_YES));
 
         r = sd_ipv4ll_new(&link->ipv4ll);
         if (r < 0)
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index eff1ce9..3b9881d 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -72,7 +72,17 @@ bool link_ipv4ll_enabled(Link *link) {
         if (!link->network)
                 return false;
 
-        return link->network->ipv4ll;
+        return IN_SET(link->network->link_local, ADDRESS_FAMILY_IPV4, ADDRESS_FAMILY_YES);
+}
+
+bool link_ipv6ll_enabled(Link *link) {
+        if (link->flags & IFF_LOOPBACK)
+                return false;
+
+        if (!link->network)
+                return false;
+
+        return IN_SET(link->network->link_local, ADDRESS_FAMILY_IPV6, ADDRESS_FAMILY_YES);
 }
 
 bool link_lldp_enabled(Link *link) {
@@ -1087,6 +1097,38 @@ static int link_up(Link *link) {
                 }
         }
 
+        if (!link_ipv6ll_enabled(link)) {
+                r = sd_rtnl_message_open_container(req, IFLA_AF_SPEC);
+                if (r < 0) {
+                        log_link_error(link, "Could not open IFLA_AF_SPEC container: %s", strerror(-r));
+                        return r;
+                }
+
+                r = sd_rtnl_message_open_container(req, AF_INET6);
+                if (r < 0) {
+                        log_link_error(link, "Could not open AF_INET6 container: %s", strerror(-r));
+                        return r;
+                }
+
+                r = sd_rtnl_message_append_u8(req, IFLA_INET6_ADDR_GEN_MODE, IN6_ADDR_GEN_MODE_NONE);
+                if (r < 0) {
+                        log_link_error(link, "Could not append IFLA_INET6_ADDR_GEN_MODE: %s", strerror(-r));
+                        return r;
+                }
+
+                r = sd_rtnl_message_close_container(req);
+                if (r < 0) {
+                        log_link_error(link, "Could not close AF_INET6 contaire: %s", strerror(-r));
+                        return r;
+                }
+
+                r = sd_rtnl_message_close_container(req);
+                if (r < 0) {
+                        log_link_error(link, "Could not close IFLA_AF_SPEC contaire: %s", strerror(-r));
+                        return r;
+                }
+        }
+
         r = sd_rtnl_call_async(link->manager->rtnl, req, link_up_handler, link,
                                0, NULL);
         if (r < 0) {
@@ -1391,8 +1433,8 @@ static int link_initialized_and_synced(sd_rtnl *rtnl, sd_rtnl_message *m,
                 return r;
 
         if (link->flags & IFF_LOOPBACK) {
-                if (network->ipv4ll)
-                        log_link_debug(link, "ignoring IPv4LL for loopback link");
+                if (network->link_local != ADDRESS_FAMILY_NO)
+                        log_link_debug(link, "ignoring link-local autoconfiguration for loopback link");
 
                 if (network->dhcp != ADDRESS_FAMILY_NO)
                         log_link_debug(link, "ignoring DHCP clients for loopback link");
diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h
index ce83f24..449dbc8 100644
--- a/src/network/networkd-link.h
+++ b/src/network/networkd-link.h
@@ -116,6 +116,7 @@ int icmp6_configure(Link *link);
 
 bool link_lldp_enabled(Link *link);
 bool link_ipv4ll_enabled(Link *link);
+bool link_ipv6ll_enabled(Link *link);
 bool link_dhcp4_server_enabled(Link *link);
 bool link_dhcp4_enabled(Link *link);
 bool link_dhcp6_enabled(Link *link);
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index 26fce97..525f2ba 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -36,7 +36,7 @@ Network.VXLAN,               config_parse_netdev,                0,
 Network.Tunnel,              config_parse_tunnel,                0,                             0
 Network.DHCP,                config_parse_dhcp,                  0,                             offsetof(Network, dhcp)
 Network.DHCPServer,          config_parse_bool,                  0,                             offsetof(Network, dhcp_server)
-Network.IPv4LL,              config_parse_bool,                  0,                             offsetof(Network, ipv4ll)
+Network.LinkLocal,           config_parse_address_family_boolean,0,                             offsetof(Network, link_local)
 Network.IPv4LLRoute,         config_parse_bool,                  0,                             offsetof(Network, ipv4ll_route)
 Network.LLDP,                config_parse_bool,                  0,                             offsetof(Network, lldp)
 Network.Address,             config_parse_address,               0,                             0
@@ -69,6 +69,7 @@ Bridge.Cost,                 config_parse_unsigned,              0,
 BridgeFDB.MACAddress,        config_parse_fdb_hwaddr,            0,                             0
 BridgeFDB.VLANId,            config_parse_fdb_vlan_id,           0,                             0
 /* backwards compatibility: do not add new entries to this section */
+Network.IPv4LL,              config_parse_ipv4ll,                0,                             offsetof(Network, link_local)
 DHCPv4.UseDNS,               config_parse_bool,                  0,                             offsetof(Network, dhcp_dns)
 DHCPv4.UseMTU,               config_parse_bool,                  0,                             offsetof(Network, dhcp_mtu)
 DHCPv4.UseHostname,          config_parse_bool,                  0,                             offsetof(Network, dhcp_hostname)
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 504419c..c39ba6d 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -107,6 +107,8 @@ static int network_load_one(Manager *manager, const char *filename) {
 
         network->llmnr = LLMNR_SUPPORT_YES;
 
+        network->link_local = ADDRESS_FAMILY_IPV6;
+
         r = config_parse(NULL, filename, file,
                          "Match\0"
                          "Link\0"
@@ -520,6 +522,37 @@ int config_parse_tunnel(const char *unit,
         return 0;
 }
 
+int config_parse_ipv4ll(
+                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) {
+
+        AddressFamilyBoolean *link_local = data;
+
+        assert(filename);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        /* Note that this is mostly like
+         * config_parse_address_family_boolean(), except that it
+         * applies only to IPv4 */
+
+        if (parse_boolean(rvalue))
+                *link_local |= ADDRESS_FAMILY_IPV4;
+        else
+                *link_local &= ~ADDRESS_FAMILY_IPV4;
+
+        return 0;
+}
+
 int config_parse_dhcp(
                 const char* unit,
                 const char *filename,
diff --git a/src/network/networkd.h b/src/network/networkd.h
index 147b21a..4f3bcf3 100644
--- a/src/network/networkd.h
+++ b/src/network/networkd.h
@@ -126,7 +126,7 @@ struct Network {
         bool dhcp_critical;
         bool dhcp_routes;
         unsigned dhcp_route_metric;
-        bool ipv4ll;
+        AddressFamilyBoolean link_local;
         bool ipv4ll_route;
 
         bool dhcp_server;
@@ -399,6 +399,12 @@ 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);
 
+/* IPv4LL support (legacy) */
+
+int config_parse_ipv4ll(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_;

commit 73cb1c149dc05abef5ad2814d6193cc33a991082
Author: Tom Gundersen <teg at jklm.no>
Date:   Sun Feb 8 22:34:53 2015 +0100

    sd-rtnl: fix typesystem for IFLA_AF_SPEC
    
    Got this one wrong, it is not a union, just a nested container.

diff --git a/src/libsystemd/sd-rtnl/rtnl-types.c b/src/libsystemd/sd-rtnl/rtnl-types.c
index f2d5c8d..a4c71f3 100644
--- a/src/libsystemd/sd-rtnl/rtnl-types.c
+++ b/src/libsystemd/sd-rtnl/rtnl-types.c
@@ -278,15 +278,18 @@ static const struct NLType rtnl_af_spec_inet6_types[IFLA_INET6_MAX + 1] = {
         [IFLA_INET6_ADDR_GEN_MODE]      = { .type = NLA_U8 },
 };
 
-static const NLTypeSystem rtnl_af_spec_type_systems[AF_MAX] = {
-        [AF_INET6] =    { .max = ELEMENTSOF(rtnl_af_spec_inet6_types) - 1,
-                          .types = rtnl_af_spec_inet6_types },
+static const NLTypeSystem rtnl_af_spec_inet6_type_system = {
+        .max = ELEMENTSOF(rtnl_af_spec_inet6_types) - 1,
+        .types = rtnl_af_spec_inet6_types,
 };
 
-static const NLTypeSystemUnion rtnl_af_spec_type_system_union = {
-        .num = AF_MAX,
-        .type_systems = rtnl_af_spec_type_systems,
-        .match_type = NL_MATCH_PROTOCOL,
+static const NLType rtnl_af_spec_types[AF_MAX + 1] = {
+        [AF_INET6] =    { .type = NLA_NESTED, .type_system = &rtnl_af_spec_inet6_type_system },
+};
+
+static const NLTypeSystem rtnl_af_spec_type_system = {
+        .max = ELEMENTSOF(rtnl_af_spec_types) - 1,
+        .types = rtnl_af_spec_types,
 };
 
 static const NLType rtnl_link_types[IFLA_MAX + 1 ] = {
@@ -323,7 +326,7 @@ static const NLType rtnl_link_types[IFLA_MAX + 1 ] = {
         [IFLA_VF_PORTS]         = { .type = NLA_NESTED },
         [IFLA_PORT_SELF]        = { .type = NLA_NESTED },
 */
-        [IFLA_AF_SPEC]          = { .type = NLA_NESTED, .type_system_union = &rtnl_af_spec_type_system_union },
+        [IFLA_AF_SPEC]          = { .type = NLA_NESTED, .type_system = &rtnl_af_spec_type_system },
 /*
         [IFLA_VF_PORTS],
         [IFLA_PORT_SELF],



More information about the systemd-commits mailing list