]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #12555 from ssahani/route-properties
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 14 May 2019 07:03:52 +0000 (09:03 +0200)
committerGitHub <noreply@github.com>
Tue, 14 May 2019 07:03:52 +0000 (09:03 +0200)
 networkd: route add support to configure fastopen_no_cookie

15 files changed:
.travis.yml
man/systemd.network.xml
man/systemd.unit.xml
src/libsystemd-network/sd-dhcp-client.c
src/network/networkd-dhcp4.c
src/network/networkd-fdb.c
src/network/networkd-fdb.h
src/network/networkd-link.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.h
src/systemd/sd-dhcp-client.h
test/fuzz/fuzz-network-parser/directives.network
test/test-network/conf/dhcp-client-ipv6-only.network
test/test-network/systemd-networkd-tests.py
tmpfiles.d/meson.build

index 1dfdc5b799c540b10ada720116441c1951863e37..a2c300062e97ece102760a113215788c0c03808e 100644 (file)
@@ -91,13 +91,6 @@ jobs:
           after_script:
               - $CI_MANAGERS/debian.sh CLEANUP
 
-        - name: Ubuntu Xenial
-          language: bash
-          script:
-              - set -e
-              - sudo $CI_MANAGERS/xenial.sh
-              - set +e
-
         - name: FuzzBuzz
           language: bash
           script:
index 0395f2c330582757728ac957fb3db848c4f3e1f2..2ce7c7096e4e36cf22671bd6c6dc8568f0780ebc 100644 (file)
           </listitem>
         </varlistentry>
 
+        <varlistentry>
+          <term><varname>SendRelease=</varname></term>
+          <listitem>
+            <para>When true, the DHCPv4 client sends a DHCP release packet when it stops.
+            Defaults to false.</para>
+          </listitem>
+        </varlistentry>
+
         <varlistentry>
           <term><varname>RapidCommit=</varname></term>
           <listitem>
             Defaults to unset.</para>
           </listitem>
         </varlistentry>
+        <varlistentry>
+          <term><varname>AssociatedWith=</varname></term>
+          <listitem>
+            <para>Specifies where the address is associated with. Takes one of <literal>use</literal>,
+            <literal>self</literal>, <literal>master</literal> or <literal>router</literal>.
+            <literal>use</literal> means the address is in use. User space can use this option to
+            indicate to the kernel that the fdb entry is in use. <literal>self</literal> means
+            the address is associated with the port drivers fdb. Usually hardware. <literal>master</literal>
+            means the address is associated with master devices fdb. <literal>router</literal> means
+            the destination address is associated with a router. Note that it's valid if the referenced
+            device is a VXLAN type device and has route shortcircuit enabled. Defaults to <literal>self</literal>.</para>
+          </listitem>
+        </varlistentry>
       </variablelist>
   </refsect1>
 
index 4b283880c3d31901d7a62f66a35ceb47cbc3a496..84af5109b82a546fe24684e4f74336dc3e2561ff 100644 (file)
         or runtime environment doesn't require their functionality. Use the various
         <varname>AssertArchitecture=</varname>, <varname>AssertVirtualization=</varname>, … options for a similar
         mechanism that causes the job to fail (instead of being skipped) and results in logging about the failed check
-        (instead of being silently processed). For details about assertion conditions see below.</para>
+        (instead of being silently processed). For details about assertion conditions see below. Units with failed
+        conditions are considered to be in a clean state and will be garbage collected if they are not referenced.
+        This means, that when queried, the condition failure may or may not show up in the state of the unit.</para>
 
         <para><varname>ConditionArchitecture=</varname> may be used to
         check whether the system is running on a specific
index 84ce8e0da8196be4e5ff0ed51c4214a82d7285fa..6e077c0860c543857b918b7fd811ecc7b0fe701b 100644 (file)
@@ -606,7 +606,7 @@ static int client_message_init(
         assert(ret);
         assert(_optlen);
         assert(_optoffset);
-        assert(IN_SET(type, DHCP_DISCOVER, DHCP_REQUEST));
+        assert(IN_SET(type, DHCP_DISCOVER, DHCP_REQUEST, DHCP_RELEASE));
 
         optlen = DHCP_MIN_OPTIONS_SIZE;
         size = sizeof(DHCPPacket) + optlen;
@@ -697,7 +697,7 @@ static int client_message_init(
            MAY contain the Parameter Request List option. */
         /* NOTE: in case that there would be an option to do not send
          * any PRL at all, the size should be checked before sending */
-        if (client->req_opts_size > 0) {
+        if (client->req_opts_size > 0 && type != DHCP_RELEASE) {
                 r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
                                        SD_DHCP_OPTION_PARAMETER_REQUEST_LIST,
                                        client->req_opts_size, client->req_opts);
@@ -729,7 +729,7 @@ static int client_message_init(
          */
         /* RFC7844 section 3:
            SHOULD NOT contain any other option. */
-        if (!client->anonymize) {
+        if (!client->anonymize && type != DHCP_RELEASE) {
                 max_size = htobe16(size);
                 r = dhcp_option_append(&packet->dhcp, client->mtu, &optoffset, 0,
                                        SD_DHCP_OPTION_MAXIMUM_MESSAGE_SIZE,
@@ -861,6 +861,41 @@ static int client_send_discover(sd_dhcp_client *client) {
         return 0;
 }
 
+static int client_send_release(sd_dhcp_client *client) {
+        _cleanup_free_ DHCPPacket *release = NULL;
+        size_t optoffset, optlen;
+        int r;
+
+        assert(client);
+        assert(!IN_SET(client->state, DHCP_STATE_STOPPED));
+
+        r = client_message_init(client, &release, DHCP_RELEASE,
+                                &optlen, &optoffset);
+        if (r < 0)
+                return r;
+
+        /* Fill up release IP and MAC */
+        release->dhcp.ciaddr = client->lease->address;
+        memcpy(&release->dhcp.chaddr, &client->mac_addr, client->mac_addr_len);
+
+        r = dhcp_option_append(&release->dhcp, optlen, &optoffset, 0,
+                               SD_DHCP_OPTION_END, 0, NULL);
+        if (r < 0)
+                return r;
+
+        r = dhcp_network_send_udp_socket(client->fd,
+                                         client->lease->server_address,
+                                         DHCP_PORT_SERVER,
+                                         &release->dhcp,
+                                         sizeof(DHCPMessage) + optoffset);
+        if (r < 0)
+                return r;
+
+        log_dhcp_client(client, "RELEASE");
+
+        return 0;
+}
+
 static int client_send_request(sd_dhcp_client *client) {
         _cleanup_free_ DHCPPacket *request = NULL;
         size_t optoffset, optlen;
@@ -1858,6 +1893,14 @@ int sd_dhcp_client_start(sd_dhcp_client *client) {
         return r;
 }
 
+int sd_dhcp_client_send_release(sd_dhcp_client *client) {
+        assert_return(client, -EINVAL);
+
+        client_send_release(client);
+
+        return 0;
+}
+
 int sd_dhcp_client_stop(sd_dhcp_client *client) {
         DHCP_CLIENT_DONT_DESTROY(client);
 
index 85e088e204c55c1b893732df30246cddd68e99ec..81c694822c11c7b896a3241c6b8777084088b34b 100644 (file)
@@ -564,6 +564,9 @@ static int dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) {
                                         return log_link_warning_errno(link, r, "Could not acquire IPv4 link-local address: %m");
                         }
 
+                        if (link->network->dhcp_send_release)
+                                (void) sd_dhcp_client_send_release(client);
+
                         _fallthrough_;
                 case SD_DHCP_CLIENT_EVENT_EXPIRED:
                 case SD_DHCP_CLIENT_EVENT_IP_CHANGE:
index fdac574d74fce76abbb247f49776b35610ed51ce..4ae511fc7aeb3f9a3f4bfe5148d0af5d69f1c512 100644 (file)
 #include "networkd-manager.h"
 #include "parse-util.h"
 #include "string-util.h"
+#include "string-table.h"
 #include "util.h"
 #include "vlan-util.h"
 
 #define STATIC_FDB_ENTRIES_PER_NETWORK_MAX 1024U
 
+static const char* const fdb_ntf_flags_table[_NEIGHBOR_CACHE_ENTRY_FLAGS_MAX] = {
+        [NEIGHBOR_CACHE_ENTRY_FLAGS_USE] = "use",
+        [NEIGHBOR_CACHE_ENTRY_FLAGS_SELF] = "self",
+        [NEIGHBOR_CACHE_ENTRY_FLAGS_MASTER] = "master",
+        [NEIGHBOR_CACHE_ENTRY_FLAGS_ROUTER] = "router",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(fdb_ntf_flags, NeighborCacheEntryFlags);
+
 /* create a new FDB entry or get an existing one. */
 static int fdb_entry_new_static(
                 Network *network,
@@ -68,6 +78,7 @@ static int fdb_entry_new_static(
                 .network = network,
                 .mac_addr = TAKE_PTR(mac_addr),
                 .vni = VXLAN_VID_MAX + 1,
+                .fdb_ntf_flags = NEIGHBOR_CACHE_ENTRY_FLAGS_SELF,
         };
 
         LIST_PREPEND(static_fdb_entries, network->static_fdb_entries, fdb_entry);
@@ -106,9 +117,6 @@ static int set_fdb_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link)
 /* send a request to the kernel to add a FDB entry in its static MAC table. */
 int fdb_entry_configure(Link *link, FdbEntry *fdb_entry) {
         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
-        sd_netlink *rtnl;
-        Bridge *bridge;
-        uint8_t flags;
         int r;
 
         assert(link);
@@ -116,20 +124,12 @@ int fdb_entry_configure(Link *link, FdbEntry *fdb_entry) {
         assert(link->manager);
         assert(fdb_entry);
 
-        rtnl = link->manager->rtnl;
-        bridge = BRIDGE(link->network->bridge);
-
         /* create new RTM message */
-        r = sd_rtnl_message_new_neigh(rtnl, &req, RTM_NEWNEIGH, link->ifindex, PF_BRIDGE);
+        r = sd_rtnl_message_new_neigh(link->manager->rtnl, &req, RTM_NEWNEIGH, link->ifindex, PF_BRIDGE);
         if (r < 0)
                 return rtnl_log_create_error(r);
 
-        if (bridge)
-                flags = NTF_MASTER;
-        else
-                flags = NTF_SELF;
-
-        r = sd_rtnl_message_neigh_set_flags(req, flags);
+        r = sd_rtnl_message_neigh_set_flags(req, fdb_entry->fdb_ntf_flags);
         if (r < 0)
                 return rtnl_log_create_error(r);
 
@@ -162,7 +162,7 @@ int fdb_entry_configure(Link *link, FdbEntry *fdb_entry) {
         }
 
         /* send message to the kernel to update its internal static MAC table. */
-        r = netlink_call_async(rtnl, NULL, req, set_fdb_handler,
+        r = netlink_call_async(link->manager->rtnl, NULL, req, set_fdb_handler,
                                link_netlink_destroy_callback, link);
         if (r < 0)
                 return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
@@ -359,3 +359,45 @@ int config_parse_fdb_vxlan_vni(
 
         return 0;
 }
+
+
+int config_parse_fdb_ntf_flags(
+                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) {
+
+        _cleanup_(fdb_entry_free_or_set_invalidp) FdbEntry *fdb_entry = NULL;
+        Network *network = userdata;
+        NeighborCacheEntryFlags f;
+        int r;
+
+        assert(filename);
+        assert(section);
+        assert(lvalue);
+        assert(rvalue);
+        assert(data);
+
+        r = fdb_entry_new_static(network, filename, section_line, &fdb_entry);
+        if (r < 0)
+                return log_oom();
+
+        f = fdb_ntf_flags_from_string(rvalue);
+        if (f < 0) {
+                log_syntax(unit, LOG_ERR, filename, line, 0,
+                           "FDB failed to parse AssociatedWith=, ignoring assignment: %s",
+                           rvalue);
+                return 0;
+        }
+
+        fdb_entry->fdb_ntf_flags = f;
+        fdb_entry = NULL;
+
+        return 0;
+}
index 6954e555fa413186d4cfc24b1244e3a280e6c252..bcdd8ce3cb241ab21ed262352c5e31f002c4d9a3 100644 (file)
@@ -5,6 +5,8 @@
   Copyright © 2014 Intel Corporation. All rights reserved.
 ***/
 
+#include <linux/neighbour.h>
+
 #include "conf-parser.h"
 #include "list.h"
 #include "macro.h"
@@ -15,6 +17,15 @@ typedef struct FdbEntry FdbEntry;
 typedef struct Link Link;
 typedef struct NetworkConfigSection NetworkConfigSection;
 
+typedef enum NeighborCacheEntryFlags {
+        NEIGHBOR_CACHE_ENTRY_FLAGS_USE = NTF_USE,
+        NEIGHBOR_CACHE_ENTRY_FLAGS_SELF = NTF_SELF,
+        NEIGHBOR_CACHE_ENTRY_FLAGS_MASTER = NTF_MASTER,
+        NEIGHBOR_CACHE_ENTRY_FLAGS_ROUTER = NTF_ROUTER,
+        _NEIGHBOR_CACHE_ENTRY_FLAGS_MAX,
+        _NEIGHBOR_CACHE_ENTRY_FLAGS_INVALID = -1,
+} NeighborCacheEntryFlags;
+
 struct FdbEntry {
         Network *network;
         NetworkConfigSection *section;
@@ -26,6 +37,7 @@ struct FdbEntry {
 
         struct ether_addr *mac_addr;
         union in_addr_union destination_addr;
+        NeighborCacheEntryFlags fdb_ntf_flags;
 
         LIST_FIELDS(FdbEntry, static_fdb_entries);
 };
@@ -35,7 +47,11 @@ int fdb_entry_configure(Link *link, FdbEntry *fdb_entry);
 
 DEFINE_NETWORK_SECTION_FUNCTIONS(FdbEntry, fdb_entry_free);
 
+const char* fdb_ntf_flags_to_string(NeighborCacheEntryFlags i) _const_;
+NeighborCacheEntryFlags fdb_ntf_flags_from_string(const char *s) _pure_;
+
 CONFIG_PARSER_PROTOTYPE(config_parse_fdb_hwaddr);
 CONFIG_PARSER_PROTOTYPE(config_parse_fdb_vlan_id);
 CONFIG_PARSER_PROTOTYPE(config_parse_fdb_destination);
 CONFIG_PARSER_PROTOTYPE(config_parse_fdb_vxlan_vni);
+CONFIG_PARSER_PROTOTYPE(config_parse_fdb_ntf_flags);
index bdf0a0a7348d137baac7dc55a97f9173a6f8ebe6..cd1b0325e8e527fb1b6c5912f9f42ec913ba27ea 100644 (file)
@@ -1625,6 +1625,9 @@ static int link_configure_addrgen_mode(Link *link) {
         assert(link->manager);
         assert(link->manager->rtnl);
 
+        if (!socket_ipv6_is_supported())
+                return 0;
+
         log_link_debug(link, "Setting address genmode for link");
 
         r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
@@ -1718,46 +1721,6 @@ static int link_up(Link *link) {
                         return log_link_error_errno(link, r, "Could not set MAC address: %m");
         }
 
-        if (link_ipv6_enabled(link)) {
-                uint8_t ipv6ll_mode;
-
-                r = sd_netlink_message_open_container(req, IFLA_AF_SPEC);
-                if (r < 0)
-                        return log_link_error_errno(link, r, "Could not open IFLA_AF_SPEC container: %m");
-
-                /* if the kernel lacks ipv6 support setting IFF_UP fails if any ipv6 options are passed */
-                r = sd_netlink_message_open_container(req, AF_INET6);
-                if (r < 0)
-                        return log_link_error_errno(link, r, "Could not open AF_INET6 container: %m");
-
-                if (!in_addr_is_null(AF_INET6, &link->network->ipv6_token)) {
-                        r = sd_netlink_message_append_in6_addr(req, IFLA_INET6_TOKEN, &link->network->ipv6_token.in6);
-                        if (r < 0)
-                                return log_link_error_errno(link, r, "Could not append IFLA_INET6_TOKEN: %m");
-                }
-
-                if (!link_ipv6ll_enabled(link))
-                        ipv6ll_mode = IN6_ADDR_GEN_MODE_NONE;
-                else if (sysctl_read_ip_property(AF_INET6, link->ifname, "stable_secret", NULL) < 0)
-                        /* The file may not exist. And event if it exists, when stable_secret is unset,
-                         * reading the file fails with EIO. */
-                        ipv6ll_mode = IN6_ADDR_GEN_MODE_EUI64;
-                else
-                        ipv6ll_mode = IN6_ADDR_GEN_MODE_STABLE_PRIVACY;
-
-                r = sd_netlink_message_append_u8(req, IFLA_INET6_ADDR_GEN_MODE, ipv6ll_mode);
-                if (r < 0)
-                        return log_link_error_errno(link, r, "Could not append IFLA_INET6_ADDR_GEN_MODE: %m");
-
-                r = sd_netlink_message_close_container(req);
-                if (r < 0)
-                        return log_link_error_errno(link, r, "Could not close AF_INET6 container: %m");
-
-                r = sd_netlink_message_close_container(req);
-                if (r < 0)
-                        return log_link_error_errno(link, r, "Could not close IFLA_AF_SPEC container: %m");
-        }
-
         r = netlink_call_async(link->manager->rtnl, NULL, req, link_up_handler,
                                link_netlink_destroy_callback, link);
         if (r < 0)
@@ -2675,11 +2638,9 @@ static int link_configure(Link *link) {
         if (r < 0)
                 return r;
 
-        if (socket_ipv6_is_supported()) {
-                r = link_configure_addrgen_mode(link);
-                if (r < 0)
-                        return r;
-        }
+        r = link_configure_addrgen_mode(link);
+        if (r < 0)
+                return r;
 
         return link_configure_after_setting_mtu(link);
 }
index e8e228092cd5b7ec8e6d28acffad6ad982b384e3..f87d7def44c7ba28735c85eba05a4e89bb431b3c 100644 (file)
@@ -150,6 +150,7 @@ DHCP.RouteTable,                        config_parse_section_route_table,
 DHCP.UseTimezone,                       config_parse_bool,                               0,                             offsetof(Network, dhcp_use_timezone)
 DHCP.IAID,                              config_parse_iaid,                               0,                             0
 DHCP.ListenPort,                        config_parse_uint16,                             0,                             offsetof(Network, dhcp_client_port)
+DHCP.SendRelease,                       config_parse_bool,                               0,                             offsetof(Network, dhcp_send_release)
 DHCP.RapidCommit,                       config_parse_bool,                               0,                             offsetof(Network, rapid_commit)
 DHCP.BlackList,                         config_parse_dhcp_black_listed_ip_address,       0,                             0
 DHCP.ForceDHCPv6PDOtherInformation,     config_parse_bool,                               0,                             offsetof(Network, dhcp6_force_pd_other_information)
@@ -187,6 +188,7 @@ BridgeFDB.MACAddress,                   config_parse_fdb_hwaddr,
 BridgeFDB.VLANId,                       config_parse_fdb_vlan_id,                        0,                             0
 BridgeFDB.Destination,                  config_parse_fdb_destination,                    0,                             0
 BridgeFDB.VNI,                          config_parse_fdb_vxlan_vni,                      0,                             0
+BridgeFDB.AssociatedWith,               config_parse_fdb_ntf_flags,                      0,                             0
 BridgeVLAN.PVID,                        config_parse_brvlan_pvid,                        0,                             0
 BridgeVLAN.VLAN,                        config_parse_brvlan_vlan,                        0,                             0
 BridgeVLAN.EgressUntagged,              config_parse_brvlan_untagged,                    0,                             0
index 9217e838d2a124cc732fdd8203cb2610a99f452a..d00062fe5999b55feb9f0d7bdab4cd9461b18908 100644 (file)
@@ -128,6 +128,7 @@ struct Network {
         bool rapid_commit;
         bool dhcp_use_hostname;
         bool dhcp_route_table_set;
+        bool dhcp_send_release;
         DHCPUseDomains dhcp_use_domains;
         Set *dhcp_black_listed_ip;
 
index 5dbfe8e4a1272b34bd528f74706b279bb99bb876..ab62368e9cee0cee1e0d55a0f0e856259b2165ef 100644 (file)
@@ -176,6 +176,7 @@ int sd_dhcp_client_get_lease(
 
 int sd_dhcp_client_stop(sd_dhcp_client *client);
 int sd_dhcp_client_start(sd_dhcp_client *client);
+int sd_dhcp_client_send_release(sd_dhcp_client *client);
 
 sd_dhcp_client *sd_dhcp_client_ref(sd_dhcp_client *client);
 sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client);
index 3c4a16bc39bd032a9e425aba87330dae9ab3f7e0..06813c29fe33095f36325c6cbdd085ca3790d11b 100644 (file)
@@ -37,6 +37,7 @@ VLANId=
 MACAddress=
 Destination=
 VNI=
+AssociatedWith=
 [DHCP]
 UseDomains=
 UseRoutes=
@@ -63,6 +64,7 @@ ListenPort=
 UseTimezone=
 RouteTable=
 BlackList=
+SendRelease=
 [Route]
 Destination=
 Protocol=
index 1f70c3b86d60ed3dcb9417fd4b1c6a100ffc7c31..8b2e934f7fbf94fe5df1d7f6f21bc9651b42fabc 100644 (file)
@@ -3,3 +3,4 @@ Name=veth99
 
 [Network]
 DHCP=ipv6
+IPv6Token=::1a:2b:3c:4d
index 4301f8c5dc73b36fe625596249309fd1bed45c1b..e65897561be6cf29b396b4427dc3cb694f75071b 100755 (executable)
@@ -1900,17 +1900,22 @@ class NetworkdNetworkDHCPClientTests(unittest.TestCase, Utilities):
 
     def test_dhcp_client_ipv6_only(self):
         self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-only.network')
-        self.start_networkd()
-
-        self.assertTrue(self.link_exits('veth99'))
 
+        self.start_networkd(0)
+        self.wait_online(['veth-peer:carrier'])
         self.start_dnsmasq()
+        self.wait_online(['veth99:routable', 'veth-peer:routable'])
 
         output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
         print(output)
         self.assertRegex(output, '2600::')
         self.assertNotRegex(output, '192.168.5')
 
+        # Confirm that ipv6 token is not set in the kernel
+        output = subprocess.check_output(['ip', 'token', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
+        print(output)
+        self.assertRegex(output, 'token :: dev veth99')
+
     def test_dhcp_client_ipv4_only(self):
         self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv4-only-ipv6-disabled.network')
         self.start_networkd()
index b94a9d0f47711d40a8a1b6c519e099afff0d5809..f14b4fc6dffc6e2291a8b5b42709304eef50055a 100644 (file)
@@ -4,7 +4,7 @@ enable_tmpfiles = conf.get('ENABLE_TMPFILES') == 1
 
 tmpfiles = [['home.conf',            ''],
             ['journal-nocow.conf',   ''],
-            ['systemd-nologin.conf', ''],
+            ['systemd-nologin.conf', 'HAVE_PAM'],
             ['systemd-nspawn.conf',  'ENABLE_MACHINED'],
             ['systemd-tmp.conf',     ''],
             ['portables.conf',       'ENABLE_PORTABLED'],