]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #3156 from keszybz/duid-settings
authorLennart Poettering <lennart@poettering.net>
Wed, 4 May 2016 09:31:59 +0000 (11:31 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 4 May 2016 09:31:59 +0000 (11:31 +0200)
Rework DUID setting

46 files changed:
.gitignore
Makefile.am
man/networkd.conf.xml
man/systemd.network.xml
src/libsystemd-network/dhcp-identifier.c
src/libsystemd-network/dhcp-identifier.h
src/libsystemd-network/sd-dhcp-client.c
src/libsystemd-network/sd-dhcp6-client.c
src/network/networkd-address-pool.h
src/network/networkd-address.h
src/network/networkd-conf.c
src/network/networkd-conf.h
src/network/networkd-dhcp4.c
src/network/networkd-dhcp6.c
src/network/networkd-fdb.h
src/network/networkd-gperf.gperf
src/network/networkd-ipv4ll.c
src/network/networkd-link.c
src/network/networkd-link.h
src/network/networkd-lldp-tx.c
src/network/networkd-manager.c
src/network/networkd-ndisc.c
src/network/networkd-netdev-bond.c
src/network/networkd-netdev-bond.h
src/network/networkd-netdev-bridge.c
src/network/networkd-netdev-bridge.h
src/network/networkd-netdev-dummy.h
src/network/networkd-netdev-gperf.gperf
src/network/networkd-netdev-ipvlan.h
src/network/networkd-netdev-macvlan.h
src/network/networkd-netdev-tunnel.h
src/network/networkd-netdev-tuntap.c
src/network/networkd-netdev-tuntap.h
src/network/networkd-netdev-veth.h
src/network/networkd-netdev-vlan.h
src/network/networkd-netdev-vxlan.c
src/network/networkd-netdev-vxlan.h
src/network/networkd-netdev.h
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-network.h
src/network/networkd-route.h
src/network/networkd.h
src/network/test-networkd-conf.c [new file with mode: 0644]
src/systemd/sd-dhcp-client.h
src/systemd/sd-dhcp6-client.h

index c7eb14452dba803739aa50332247a84d40761adf..c17f79224bf772cfaa8327b069205cf7e7392a12 100644 (file)
 /test-ndisc-rs
 /test-netlink
 /test-netlink-manual
+/test-netword-conf
 /test-network
 /test-network-tables
 /test-ns
index a05c7ce4db5a86cee6412d087df590f465534c5b..cf4e75996d5790255dd8ef30da3c8c3f107caaae 100644 (file)
@@ -5515,6 +5515,12 @@ networkctl_LDADD = \
 dist_bashcompletion_data += \
        shell-completion/bash/networkctl
 
+test_networkd_conf_SOURCES = \
+       src/network/test-networkd-conf.c
+
+test_networkd_conf_LDADD = \
+       libnetworkd-core.la
+
 test_network_SOURCES = \
        src/network/test-network.c
 
@@ -5540,6 +5546,7 @@ test_network_tables_LDADD += \
 endif
 
 tests += \
+       test-networkd-conf \
        test-network \
        test-network-tables
 
index 5166e05cbc0140e2cd71d85de701569d3f75c8c4..4bfc4f773a3d732d794d80b895c9a419f4ced936 100644 (file)
     <title>Description</title>
 
     <para>These configuration files control global network parameters.
-    For e.g. DHCP Unique Identifier (DUID).</para>
+    Currently the DHCP Unique Identifier (DUID).</para>
 
   </refsect1>
 
   <xi:include href="standard-conf.xml" xpointer="main-conf" />
 
   <refsect1>
-    <title>[DUID] Section Options</title>
+    <title>[DHCP] Section Options</title>
 
     <para>This section configures the DHCP Unique Identifier (DUID) value used by DHCP
     protocol. DHCPv6 client protocol sends the DHCP Unique Identifier and the interface
     address. DHCPv4 client protocol sends IAID and DUID to the DHCP server when acquiring
     a dynamic IPv4 address if <option>ClientIdentifier=duid</option>. IAID and DUID allows
     a DHCP server to uniquely identify the machine and the interface requesting a DHCP IP.
-    To configure IAID and ClientIdentifier, see <citerefentry><refentrytitle>systemd.network
-    </refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+    To configure IAID and ClientIdentifier, see
+    <citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+    </para>
 
-    <para>The DUID value specified here overrides the DUID that systemd-networkd
-    generates using the machine-id from the <filename>/etc/machine-id</filename> file.
-    To configure DUID per-network, see <citerefentry><refentrytitle>systemd.network
-    </refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
-
-    <para>The configured DHCP DUID should conform to the specification in 
-    <ulink url="http://tools.ietf.org/html/rfc3315#section-9">RFC 3315</ulink>,
-    <ulink url="http://tools.ietf.org/html/rfc6355">RFC 6355</ulink>. To configure IAID, see
-    <citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum>
-    </citerefentry>.</para>
-
-    <para>The following options are available in <literal>[DUID]</literal> section:</para>
+    <para>The following options are understood:</para>
 
     <variablelist class='network-directives'>
+      <varlistentry>
+        <term><varname>DUIDType=</varname></term>
+        <listitem><para>Specifies how the DUID should be generated. See
+        <ulink url="https://tools.ietf.org/html/rfc3315#section-9">RFC 3315</ulink>
+        for a description of all the options.</para>
+
+        <para>The following values are understood:
+        <variablelist>
+          <varlistentry>
+            <term><option>vendor</option> </term>
+            <listitem><para>If <literal>DUIDType=vendor</literal>, then the DUID value will be generated using
+            <literal>43793</literal> as the vendor identifier (systemd) and hashed contents of
+            <citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+            This is the default if <varname>DUIDType=</varname> is not specified.
+            </para></listitem>
+          </varlistentry>
+
+          <varlistentry>
+            <term><option>link-layer-time</option> </term>
+            <term><option>link-layer</option> </term>
+            <term><option>uuid</option> </term>
+            <listitem><para>Those values are parsed and can be used to set the DUID type
+            field, but DUID contents must be provided using <varname>DUIDRawData=</varname>.
+            </para></listitem>
+          </varlistentry>
+        </variablelist>
+        </para>
+
+        <para>In all cases, <varname>DUIDRawData=</varname> can be used to override the
+        actual DUID value that is used.</para></listitem>
+      </varlistentry>
 
       <varlistentry>
-        <term><varname>RawData=</varname></term>
-        <listitem><para>Specifies the DUID bytes as a single newline-terminated, hexadecimal
-        string, with each byte separated by a ':'.</para></listitem>
+        <term><varname>DUIDRawData=</varname></term>
+        <listitem><para>Specifies the DHCP DUID value as a single newline-terminated, hexadecimal string, with each
+        byte separated by <literal>:</literal>. The DUID that is sent is composed of the DUID type specified by
+        <varname>DUIDType=</varname> and the value configured here.</para>
+
+        <para>The DUID value specified here overrides the DUID that systemd-networkd generates using the machine-id
+        from the <filename>/etc/machine-id</filename> file. To configure DUID per-network, see
+        <citerefentry><refentrytitle>systemd.network </refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+        The configured DHCP DUID should conform to the specification in
+        <ulink url="http://tools.ietf.org/html/rfc3315#section-9">RFC 3315</ulink>,
+        <ulink url="http://tools.ietf.org/html/rfc6355">RFC 6355</ulink>. To configure IAID, see
+        <citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum>
+        </citerefentry>.</para>
+
+        <example>
+          <title>A <option>DUIDType=vendor</option> with a custom value</title>
+
+          <programlisting>DUIDType=vendor
+DUIDRawData=00:00:ab:11:f9:2a:c2:77:29:f9:5c:00</programlisting>
+
+          <para>This specifies a 14 byte DUID, with the type DUID-EN (<literal>00:02</literal>), enterprise number
+          43793 (<literal>00:00:ab:11</literal>), and identifier value <literal>f9:2a:c2:77:29:f9:5c:00</literal>.
+          </para>
+        </example>
+        </listitem>
       </varlistentry>
     </variablelist>
   </refsect1>
index 5e287faa6e9db738b47a92d1023f329cb0737249..3ee80a64a06c431a55a89026ffd5ada6afba7f41 100644 (file)
             false.</para>
           </listitem>
         </varlistentry>
+
         <varlistentry>
           <term><varname>ClientIdentifier=</varname></term>
           <listitem>
             or <literal>duid</literal> (the default, see below) to use a RFC4361-compliant Client ID.</para>
           </listitem>
         </varlistentry>
+
         <varlistentry>
           <term><varname>VendorClassIdentifier=</varname></term>
           <listitem>
             type and configuration.</para>
           </listitem>
         </varlistentry>
-        <varlistentry>
-          <term><varname>DUIDRawData=</varname></term>
-          <listitem><para>Specifies the DHCP DUID bytes as a single newline-terminated, hexadecimal string, with each
-          byte separated by a ':'.  A DHCPv6 client sends the DHCP Unique Identifier (DUID) and the interface Identity
-          Association Identifier (IAID) to a DHCP server when acquiring a dynamic IPv6 address. Similar, DHCPv4 clients
-          send the IAID and DUID to the DHCP server when acquiring a dynamic IPv4 address if
-          <option>ClientIdentifier=duid</option>. IAID and DUID allows a DHCP server to uniquely identify the machine
-          and the interface requesting a DHCP IP address.</para>
 
-          <para>The DUID value specified here takes precedence over the DUID that systemd-networkd generates
-          using the machine-id from the <filename>/etc/machine-id</filename> file, as well as the
-          global DUID that may be specified in <citerefentry><refentrytitle>networkd.conf
-          </refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+        <varlistentry>
+          <term><varname>DUIDType=</varname></term>
+          <listitem>
+            <para>Override the global <varname>DUIDType</varname> setting for this network. See
+            <citerefentry><refentrytitle>networkd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+            for a description of possible values.</para>
+          </listitem>
+        </varlistentry>
 
-          <para>The configured DHCP DUID should conform to the specification in
-          <ulink url="http://tools.ietf.org/html/rfc3315#section-9">RFC 3315</ulink>,
-          <ulink url="http://tools.ietf.org/html/rfc6355">RFC 6355</ulink>.</para>
+        <varlistentry>
+          <term><varname>DUIDRawData=</varname></term>
+          <listitem>
+            <para>Override the global <varname>DUIDRawData</varname> setting for this network. See
+            <citerefentry><refentrytitle>networkd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+            for a description of possible values.</para>
           </listitem>
         </varlistentry>
+
         <varlistentry>
           <term><varname>RequestBroadcast=</varname></term>
           <listitem>
             networks where broadcasts are filtered out.</para>
           </listitem>
         </varlistentry>
+
         <varlistentry>
           <term><varname>RouteMetric=</varname></term>
           <listitem>
index 4f7d4d8bf2ba6cc31143b9b7591dd80833f9466b..a21efc4d06572863508e48b5123f6cdff5427909 100644 (file)
 #define SYSTEMD_PEN 43793
 #define HASH_KEY SD_ID128_MAKE(80,11,8c,c2,fe,4a,03,ee,3e,d6,0c,6f,36,39,14,09)
 
+int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len) {
+        struct duid d;
+
+        assert_cc(sizeof(d.raw) >= MAX_DUID_LEN);
+        if (duid_len > MAX_DUID_LEN)
+                return -EINVAL;
+
+        switch (duid_type) {
+        case DUID_TYPE_LLT:
+                if (duid_len <= sizeof(d.llt))
+                        return -EINVAL;
+                break;
+        case DUID_TYPE_EN:
+                if (duid_len != sizeof(d.en))
+                        return -EINVAL;
+                break;
+        case DUID_TYPE_LL:
+                if (duid_len <= sizeof(d.ll))
+                        return -EINVAL;
+                break;
+        case DUID_TYPE_UUID:
+                if (duid_len != sizeof(d.uuid))
+                        return -EINVAL;
+                break;
+        default:
+                /* accept unknown type in order to be forward compatible */
+                break;
+        }
+        return 0;
+}
+
 int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len) {
         sd_id128_t machine_id;
         uint64_t hash;
index e6486b78f86489327c2222ab8690b59cf31a1df3..1cc0f9fb711057abc0cd9634cdd05109191b8361 100644 (file)
@@ -26,7 +26,6 @@
 #include "unaligned.h"
 
 typedef enum DUIDType {
-        DUID_TYPE_RAW       = 0,
         DUID_TYPE_LLT       = 1,
         DUID_TYPE_EN        = 2,
         DUID_TYPE_LL        = 3,
@@ -40,27 +39,28 @@ typedef enum DUIDType {
  */
 #define MAX_DUID_LEN 128
 
+/* https://tools.ietf.org/html/rfc3315#section-9.1 */
 struct duid {
         be16_t type;
         union {
                 struct {
-                        /* DHCP6_DUID_LLT */
+                        /* DUID_TYPE_LLT */
                         uint16_t htype;
                         uint32_t time;
                         uint8_t haddr[0];
                 } _packed_ llt;
                 struct {
-                        /* DHCP6_DUID_EN */
+                        /* DUID_TYPE_EN */
                         uint32_t pen;
                         uint8_t id[8];
                 } _packed_ en;
                 struct {
-                        /* DHCP6_DUID_LL */
+                        /* DUID_TYPE_LL */
                         int16_t htype;
                         uint8_t haddr[0];
                 } _packed_ ll;
                 struct {
-                        /* DHCP6_DUID_UUID */
+                        /* DUID_TYPE_UUID */
                         sd_id128_t uuid;
                 } _packed_ uuid;
                 struct {
@@ -69,36 +69,6 @@ struct duid {
         };
 } _packed_;
 
+int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len);
 int dhcp_identifier_set_duid_en(struct duid *duid, size_t *len);
 int dhcp_identifier_set_iaid(int ifindex, uint8_t *mac, size_t mac_len, void *_id);
-
-static inline int dhcp_validate_duid_len(uint16_t duid_type, size_t duid_len) {
-        struct duid d;
-
-        assert(duid_len > 0);
-
-        switch (duid_type) {
-        case DUID_TYPE_LLT:
-                if (duid_len <= sizeof(d.llt))
-                        return -EINVAL;
-                break;
-        case DUID_TYPE_EN:
-                if (duid_len != sizeof(d.en))
-                        return -EINVAL;
-                break;
-        case DUID_TYPE_LL:
-                if (duid_len <= sizeof(d.ll))
-                        return -EINVAL;
-                break;
-        case DUID_TYPE_UUID:
-                if (duid_len != sizeof(d.uuid))
-                        return -EINVAL;
-                break;
-        default:
-                if (duid_len > sizeof(d.raw))
-                        return -EINVAL;
-                /* accept unknown type in order to be forward compatible */
-                break;
-        }
-        return 0;
-}
index 287b6e26fabd93df53345b25c9d23b4281730f90..3846cf74760c8c4cba01bd1ec440d2f85afad1d8 100644 (file)
@@ -115,14 +115,22 @@ static const uint8_t default_req_opts[] = {
         SD_DHCP_OPTION_DOMAIN_NAME_SERVER,
 };
 
-static int client_receive_message_raw(sd_event_source *s, int fd,
-                                      uint32_t revents, void *userdata);
-static int client_receive_message_udp(sd_event_source *s, int fd,
-                                      uint32_t revents, void *userdata);
+static int client_receive_message_raw(
+                sd_event_source *s,
+                int fd,
+                uint32_t revents,
+                void *userdata);
+static int client_receive_message_udp(
+                sd_event_source *s,
+                int fd,
+                uint32_t revents,
+                void *userdata);
 static void client_stop(sd_dhcp_client *client, int error);
 
-int sd_dhcp_client_set_callback(sd_dhcp_client *client, sd_dhcp_client_callback_t cb,
-                                void *userdata) {
+int sd_dhcp_client_set_callback(
+                sd_dhcp_client *client,
+                sd_dhcp_client_callback_t cb,
+                void *userdata) {
         assert_return(client, -EINVAL);
 
         client->cb = cb;
@@ -171,8 +179,9 @@ int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option) {
         return 0;
 }
 
-int sd_dhcp_client_set_request_address(sd_dhcp_client *client,
-                                       const struct in_addr *last_addr) {
+int sd_dhcp_client_set_request_address(
+                sd_dhcp_client *client,
+                const struct in_addr *last_addr) {
         assert_return(client, -EINVAL);
         assert_return (IN_SET(client->state, DHCP_STATE_INIT,
                               DHCP_STATE_STOPPED), -EBUSY);
@@ -196,8 +205,12 @@ int sd_dhcp_client_set_index(sd_dhcp_client *client, int interface_index) {
         return 0;
 }
 
-int sd_dhcp_client_set_mac(sd_dhcp_client *client, const uint8_t *addr,
-                           size_t addr_len, uint16_t arp_type) {
+int sd_dhcp_client_set_mac(
+                sd_dhcp_client *client,
+                const uint8_t *addr,
+                size_t addr_len,
+                uint16_t arp_type) {
+
         DHCP_CLIENT_DONT_DESTROY(client);
         bool need_restart = false;
 
@@ -234,8 +247,11 @@ int sd_dhcp_client_set_mac(sd_dhcp_client *client, const uint8_t *addr,
         return 0;
 }
 
-int sd_dhcp_client_get_client_id(sd_dhcp_client *client, uint8_t *type,
-                                 const uint8_t **data, size_t *data_len) {
+int sd_dhcp_client_get_client_id(
+                sd_dhcp_client *client,
+                uint8_t *type,
+                const uint8_t **data,
+                size_t *data_len) {
 
         assert_return(client, -EINVAL);
         assert_return(type, -EINVAL);
@@ -254,8 +270,12 @@ int sd_dhcp_client_get_client_id(sd_dhcp_client *client, uint8_t *type,
         return 0;
 }
 
-int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type,
-                                 const uint8_t *data, size_t data_len) {
+int sd_dhcp_client_set_client_id(
+                sd_dhcp_client *client,
+                uint8_t type,
+                const uint8_t *data,
+                size_t data_len) {
+
         DHCP_CLIENT_DONT_DESTROY(client);
         bool need_restart = false;
 
@@ -298,13 +318,32 @@ int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type,
         return 0;
 }
 
-int sd_dhcp_client_set_iaid_duid(sd_dhcp_client *client, uint32_t iaid,
-                                 uint16_t duid_type, uint8_t *duid, size_t duid_len) {
+/**
+ * Sets IAID and DUID. If duid is non-null, the DUID is set to duid_type + duid
+ * without further modification. Otherwise, if duid_type is supported, DUID
+ * is set based on that type. Otherwise, an error is returned.
+ */
+int sd_dhcp_client_set_iaid_duid(
+                sd_dhcp_client *client,
+                uint32_t iaid,
+                uint16_t duid_type,
+                const void *duid,
+                size_t duid_len) {
+
         DHCP_CLIENT_DONT_DESTROY(client);
         int r;
+        size_t len;
+
         assert_return(client, -EINVAL);
-        zero(client->client_id);
+        assert_return(duid_len == 0 || duid != NULL, -EINVAL);
+
+        if (duid != NULL) {
+                r = dhcp_validate_duid_len(duid_type, duid_len);
+                if (r < 0)
+                        return r;
+        }
 
+        zero(client->client_id);
         client->client_id.type = 255;
 
         /* If IAID is not configured, generate it. */
@@ -317,22 +356,18 @@ int sd_dhcp_client_set_iaid_duid(sd_dhcp_client *client, uint32_t iaid,
         } else
                 client->client_id.ns.iaid = htobe32(iaid);
 
-        /* If DUID is not configured, generate DUID-EN. */
-        if (duid_len == 0) {
-                r = dhcp_identifier_set_duid_en(&client->client_id.ns.duid,
-                                                &duid_len);
-                if (r < 0)
-                        return r;
-        } else {
-                r = dhcp_validate_duid_len(client->client_id.type, duid_len);
-                if (r < 0)
-                        return r;
+        if (duid != NULL) {
                 client->client_id.ns.duid.type = htobe16(duid_type);
                 memcpy(&client->client_id.ns.duid.raw.data, duid, duid_len);
-                duid_len += sizeof(client->client_id.ns.duid.type);
-        }
+                len = sizeof(client->client_id.ns.duid.type) + duid_len;
+        } else if (duid_type == DUID_TYPE_EN) {
+                r = dhcp_identifier_set_duid_en(&client->client_id.ns.duid, &len);
+                if (r < 0)
+                        return r;
+        } else
+                return -EOPNOTSUPP;
 
-        client->client_id_len = sizeof(client->client_id.type) + duid_len +
+        client->client_id_len = sizeof(client->client_id.type) + len +
                                 sizeof(client->client_id.ns.iaid);
 
         if (!IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED)) {
@@ -344,8 +379,10 @@ int sd_dhcp_client_set_iaid_duid(sd_dhcp_client *client, uint32_t iaid,
         return 0;
 }
 
-int sd_dhcp_client_set_hostname(sd_dhcp_client *client,
-                                const char *hostname) {
+int sd_dhcp_client_set_hostname(
+                sd_dhcp_client *client,
+                const char *hostname) {
+
         char *new_hostname = NULL;
 
         assert_return(client, -EINVAL);
@@ -368,8 +405,10 @@ int sd_dhcp_client_set_hostname(sd_dhcp_client *client,
         return 0;
 }
 
-int sd_dhcp_client_set_vendor_class_identifier(sd_dhcp_client *client,
-                                               const char *vci) {
+int sd_dhcp_client_set_vendor_class_identifier(
+                sd_dhcp_client *client,
+                const char *vci) {
+
         char *new_vci = NULL;
 
         assert_return(client, -EINVAL);
@@ -452,8 +491,13 @@ static void client_stop(sd_dhcp_client *client, int error) {
         client_initialize(client);
 }
 
-static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret,
-                               uint8_t type, size_t *_optlen, size_t *_optoffset) {
+static int client_message_init(
+                sd_dhcp_client *client,
+                DHCPPacket **ret,
+                uint8_t type,
+                size_t *_optlen,
+                size_t *_optoffset) {
+
         _cleanup_free_ DHCPPacket *packet = NULL;
         size_t optlen, optoffset, size;
         be16_t max_size;
@@ -594,8 +638,12 @@ static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret,
         return 0;
 }
 
-static int client_append_fqdn_option(DHCPMessage *message, size_t optlen, size_t *optoffset,
-                                     const char *fqdn) {
+static int client_append_fqdn_option(
+                DHCPMessage *message,
+                size_t optlen,
+                size_t *optoffset,
+                const char *fqdn) {
+
         uint8_t buffer[3 + DHCP_MAX_FQDN_LENGTH];
         int r;
 
@@ -612,8 +660,11 @@ static int client_append_fqdn_option(DHCPMessage *message, size_t optlen, size_t
         return r;
 }
 
-static int dhcp_client_send_raw(sd_dhcp_client *client, DHCPPacket *packet,
-                                size_t len) {
+static int dhcp_client_send_raw(
+                sd_dhcp_client *client,
+                DHCPPacket *packet,
+                size_t len) {
+
         dhcp_packet_append_ip_headers(packet, INADDR_ANY, DHCP_PORT_CLIENT,
                                       INADDR_BROADCAST, DHCP_PORT_SERVER, len);
 
@@ -820,8 +871,11 @@ static int client_send_request(sd_dhcp_client *client) {
 
 static int client_start(sd_dhcp_client *client);
 
-static int client_timeout_resend(sd_event_source *s, uint64_t usec,
-                                 void *userdata) {
+static int client_timeout_resend(
+                sd_event_source *s,
+                uint64_t usec,
+                void *userdata) {
+
         sd_dhcp_client *client = userdata;
         DHCP_CLIENT_DONT_DESTROY(client);
         usec_t next_timeout = 0;
@@ -965,8 +1019,10 @@ error:
         return 0;
 }
 
-static int client_initialize_io_events(sd_dhcp_client *client,
-                                       sd_event_io_handler_t io_callback) {
+static int client_initialize_io_events(
+                sd_dhcp_client *client,
+                sd_event_io_handler_t io_callback) {
+
         int r;
 
         assert(client);
@@ -1033,8 +1089,7 @@ error:
 
 }
 
-static int client_initialize_events(sd_dhcp_client *client,
-                                    sd_event_io_handler_t io_callback) {
+static int client_initialize_events(sd_dhcp_client *client, sd_event_io_handler_t io_callback) {
         client_initialize_io_events(client, io_callback);
         client_initialize_time_events(client);
 
@@ -1074,8 +1129,7 @@ static int client_start(sd_dhcp_client *client) {
         return client_start_delayed(client);
 }
 
-static int client_timeout_expire(sd_event_source *s, uint64_t usec,
-                                 void *userdata) {
+static int client_timeout_expire(sd_event_source *s, uint64_t usec, void *userdata) {
         sd_dhcp_client *client = userdata;
         DHCP_CLIENT_DONT_DESTROY(client);
 
@@ -1115,8 +1169,7 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata)
         return client_initialize_events(client, client_receive_message_raw);
 }
 
-static int client_timeout_t1(sd_event_source *s, uint64_t usec,
-                             void *userdata) {
+static int client_timeout_t1(sd_event_source *s, uint64_t usec, void *userdata) {
         sd_dhcp_client *client = userdata;
         DHCP_CLIENT_DONT_DESTROY(client);
 
@@ -1126,8 +1179,7 @@ static int client_timeout_t1(sd_event_source *s, uint64_t usec,
         return client_initialize_time_events(client);
 }
 
-static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer,
-                               size_t len) {
+static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer, size_t len) {
         _cleanup_(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL;
         int r;
 
@@ -1178,8 +1230,7 @@ static int client_handle_offer(sd_dhcp_client *client, DHCPMessage *offer,
         return 0;
 }
 
-static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force,
-                                    size_t len) {
+static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force, size_t len) {
         int r;
 
         r = dhcp_option_parse(force, len, NULL, NULL, NULL);
@@ -1191,8 +1242,7 @@ static int client_handle_forcerenew(sd_dhcp_client *client, DHCPMessage *force,
         return 0;
 }
 
-static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack,
-                             size_t len) {
+static int client_handle_ack(sd_dhcp_client *client, DHCPMessage *ack, size_t len) {
         _cleanup_(sd_dhcp_lease_unrefp) sd_dhcp_lease *lease = NULL;
         _cleanup_free_ char *error_message = NULL;
         int r;
@@ -1420,8 +1470,7 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) {
         return 0;
 }
 
-static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message,
-                                 int len) {
+static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, int len) {
         DHCP_CLIENT_DONT_DESTROY(client);
         char time_string[FORMAT_TIMESPAN_MAX];
         int r = 0, notify_event = 0;
@@ -1567,8 +1616,12 @@ error:
         return r;
 }
 
-static int client_receive_message_udp(sd_event_source *s, int fd,
-                                      uint32_t revents, void *userdata) {
+static int client_receive_message_udp(
+                sd_event_source *s,
+                int fd,
+                uint32_t revents,
+                void *userdata) {
+
         sd_dhcp_client *client = userdata;
         _cleanup_free_ DHCPMessage *message = NULL;
         const struct ether_addr zero_mac = { { 0, 0, 0, 0, 0, 0 } };
@@ -1645,8 +1698,12 @@ static int client_receive_message_udp(sd_event_source *s, int fd,
         return client_handle_message(client, message, len);
 }
 
-static int client_receive_message_raw(sd_event_source *s, int fd,
-                                      uint32_t revents, void *userdata) {
+static int client_receive_message_raw(
+                sd_event_source *s,
+                int fd,
+                uint32_t revents,
+                void *userdata) {
+
         sd_dhcp_client *client = userdata;
         _cleanup_free_ DHCPPacket *packet = NULL;
         uint8_t cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))];
index ee4fb4fc1edba409fde6528709e4c51380e26ee4..4adb053a57a83f53b520db38d8df86e0eb9d4f42 100644 (file)
@@ -111,7 +111,10 @@ DEFINE_STRING_TABLE_LOOKUP(dhcp6_message_status, int);
 
 static int client_start(sd_dhcp6_client *client, enum DHCP6State state);
 
-int sd_dhcp6_client_set_callback(sd_dhcp6_client *client, sd_dhcp6_client_callback_t cb, void *userdata) {
+int sd_dhcp6_client_set_callback(
+                sd_dhcp6_client *client,
+                sd_dhcp6_client_callback_t cb,
+                void *userdata) {
         assert_return(client, -EINVAL);
 
         client->cb = cb;
@@ -131,7 +134,10 @@ int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index) {
         return 0;
 }
 
-int sd_dhcp6_client_set_local_address(sd_dhcp6_client *client, const struct in6_addr *local_address) {
+int sd_dhcp6_client_set_local_address(
+                sd_dhcp6_client *client,
+                const struct in6_addr *local_address) {
+
         assert_return(client, -EINVAL);
         assert_return(local_address, -EINVAL);
         assert_return(in_addr_is_link_local(AF_INET6, (const union in_addr_union *) local_address) > 0, -EINVAL);
@@ -180,20 +186,38 @@ static int client_ensure_duid(sd_dhcp6_client *client) {
         return dhcp_identifier_set_duid_en(&client->duid, &client->duid_len);
 }
 
-int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint16_t duid_type,
-                             uint8_t *duid, size_t duid_len) {
+/**
+ * Sets DUID. If duid is non-null, the DUID is set to duid_type + duid
+ * without further modification. Otherwise, if duid_type is supported, DUID
+ * is set based on that type. Otherwise, an error is returned.
+ */
+int sd_dhcp6_client_set_duid(
+                sd_dhcp6_client *client,
+                uint16_t duid_type,
+                const void *duid,
+                size_t duid_len) {
+
         int r;
         assert_return(client, -EINVAL);
+        assert_return(duid_len == 0 || duid != NULL, -EINVAL);
         assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
 
-        if (duid_len > 0) {
+        if (duid != NULL) {
                 r = dhcp_validate_duid_len(duid_type, duid_len);
                 if (r < 0)
                         return r;
+        }
+
+        if (duid != NULL) {
                 client->duid.type = htobe16(duid_type);
                 memcpy(&client->duid.raw.data, duid, duid_len);
-                client->duid_len = duid_len + sizeof(client->duid.type);
-        }
+                client->duid_len = sizeof(client->duid.type) + duid_len;
+        } else if (duid_type == DUID_TYPE_EN) {
+                r = dhcp_identifier_set_duid_en(&client->duid, &client->duid_len);
+                if (r < 0)
+                        return r;
+        } else
+                return -EOPNOTSUPP;
 
         return 0;
 }
@@ -427,8 +451,7 @@ static int client_send_message(sd_dhcp6_client *client, usec_t time_now) {
         return 0;
 }
 
-static int client_timeout_t2(sd_event_source *s, uint64_t usec,
-                             void *userdata) {
+static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) {
         sd_dhcp6_client *client = userdata;
 
         assert_return(s, -EINVAL);
@@ -445,8 +468,7 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec,
         return 0;
 }
 
-static int client_timeout_t1(sd_event_source *s, uint64_t usec,
-                             void *userdata) {
+static int client_timeout_t1(sd_event_source *s, uint64_t usec, void *userdata) {
         sd_dhcp6_client *client = userdata;
 
         assert_return(s, -EINVAL);
@@ -463,8 +485,7 @@ static int client_timeout_t1(sd_event_source *s, uint64_t usec,
         return 0;
 }
 
-static int client_timeout_resend_expire(sd_event_source *s, uint64_t usec,
-                                        void *userdata) {
+static int client_timeout_resend_expire(sd_event_source *s, uint64_t usec, void *userdata) {
         sd_dhcp6_client *client = userdata;
         DHCP6_CLIENT_DONT_DESTROY(client);
         enum DHCP6State state;
@@ -490,8 +511,7 @@ static usec_t client_timeout_compute_random(usec_t val) {
                 (random_u32() % (2 * USEC_PER_SEC)) * val / 10 / USEC_PER_SEC;
 }
 
-static int client_timeout_resend(sd_event_source *s, uint64_t usec,
-                                 void *userdata) {
+static int client_timeout_resend(sd_event_source *s, uint64_t usec, void *userdata) {
         int r = 0;
         sd_dhcp6_client *client = userdata;
         usec_t time_now, init_retransmit_time = 0, max_retransmit_time = 0;
@@ -658,9 +678,11 @@ static int client_ensure_iaid(sd_dhcp6_client *client) {
         return 0;
 }
 
-static int client_parse_message(sd_dhcp6_client *client,
-                                DHCP6Message *message, size_t len,
-                                sd_dhcp6_lease *lease) {
+static int client_parse_message(
+                sd_dhcp6_client *client,
+                DHCP6Message *message,
+                size_t len,
+                sd_dhcp6_lease *lease) {
         int r;
         uint8_t *optval, *option, *id = NULL;
         uint16_t optcode, status;
index 8e1378ff4059163733bff7ff72d717a865b77591..af30decfe0373e78db6332cabca42e460ec0853f 100644 (file)
@@ -22,7 +22,9 @@
 typedef struct AddressPool AddressPool;
 
 #include "in-addr-util.h"
-#include "networkd.h"
+#include "list.h"
+
+typedef struct Manager Manager;
 
 struct AddressPool {
         Manager *manager;
index 3c81978fb1b7ee1056f85ce0f59d9d0e4b244f4a..784ab18b27b3399ffa24d21973806d271ce0ba14 100644 (file)
@@ -28,10 +28,12 @@ typedef struct Address Address;
 
 #include "networkd-link.h"
 #include "networkd-network.h"
-#include "networkd.h"
 
 #define CACHE_INFO_INFINITY_LIFE_TIME 0xFFFFFFFFU
 
+typedef struct Network Network;
+typedef struct Link Link;
+
 struct Address {
         Network *network;
         unsigned section;
index 70f0121d6db1d0fb3b2c2473c704916c1ef6ad35..6072c1e2deff3a4268a73a37a777655d49381502 100644 (file)
@@ -37,11 +37,10 @@ int manager_parse_config_file(Manager *m) {
 }
 
 static const char* const duid_type_table[_DUID_TYPE_MAX] = {
-        [DUID_TYPE_RAW]  = "raw",
         [DUID_TYPE_LLT]  = "link-layer-time",
         [DUID_TYPE_EN]   = "vendor",
         [DUID_TYPE_LL]   = "link-layer",
-        [DUID_TYPE_UUID] = "uuid"
+        [DUID_TYPE_UUID] = "uuid",
 };
 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(duid_type, DUIDType);
 DEFINE_CONFIG_PARSE_ENUM(config_parse_duid_type, duid_type, DUIDType, "Failed to parse DUID type");
@@ -58,69 +57,29 @@ int config_parse_duid_rawdata(
                 void *data,
                 void *userdata) {
 
-        int r;
-        char *cbyte;
-        const char *pduid = rvalue;
-        Manager *m = userdata;
-        Network *n = userdata;
-        DUIDType duidtype;
-        uint16_t dhcp_duid_type = 0;
-        uint8_t dhcp_duid[MAX_DUID_LEN];
-        size_t len, count = 0, duid_start_offset = 0, dhcp_duid_len = 0;
+        DUID *ret = data;
+        uint8_t raw_data[MAX_DUID_LEN];
+        unsigned count = 0;
 
         assert(filename);
         assert(lvalue);
         assert(rvalue);
-        assert(userdata);
+        assert(ret);
 
-        duidtype = (ltype == DUID_CONFIG_SOURCE_GLOBAL) ? m->duid_type : n->duid_type;
-
-        if (duidtype == _DUID_TYPE_INVALID)
-                duidtype = DUID_TYPE_RAW;
-
-        switch (duidtype) {
-
-        case DUID_TYPE_LLT:
-                /* RawData contains DUID-LLT link-layer address (offset 6) */
-                duid_start_offset = 6;
-                break;
-
-        case DUID_TYPE_EN:
-                /* RawData contains DUID-EN identifier (offset 4) */
-                duid_start_offset = 4;
-                break;
-
-        case DUID_TYPE_LL:
-                /* RawData contains DUID-LL link-layer address (offset 2) */
-                duid_start_offset = 2;
-                break;
-
-        case DUID_TYPE_UUID:
-                /* RawData specifies UUID (offset 0) - fall thru */
-
-        case DUID_TYPE_RAW:
-                /* First two bytes of RawData is DUID Type - fall thru */
-
-        default:
-                break;
-        }
-
-        if (duidtype != DUID_TYPE_RAW)
-                dhcp_duid_type = (uint16_t) duidtype;
-
-        /* RawData contains DUID in format " NN:NN:NN... " */
+        /* RawData contains DUID in format "NN:NN:NN..." */
         for (;;) {
-                int n1, n2;
+                int n1, n2, len, r;
                 uint32_t byte;
+                char *cbyte;
 
-                r = extract_first_word(&pduid, &cbyte, ":", 0);
+                r = extract_first_word(&rvalue, &cbyte, ":", 0);
                 if (r < 0) {
                         log_syntax(unit, LOG_ERR, filename, line, r, "Failed to read DUID, ignoring assignment: %s.", rvalue);
                         return 0;
                 }
                 if (r == 0)
                         break;
-                if (duid_start_offset + dhcp_duid_len >= MAX_DUID_LEN) {
+                if (count >= MAX_DUID_LEN) {
                         log_syntax(unit, LOG_ERR, filename, line, 0, "Max DUID length exceeded, ignoring assignment: %s.", rvalue);
                         return 0;
                 }
@@ -142,30 +101,11 @@ int config_parse_duid_rawdata(
                 }
 
                 byte = ((uint8_t) n1 << (4 * (len-1))) | (uint8_t) n2;
-
-                /* If DUID_TYPE_RAW, first two bytes hold DHCP DUID type code */
-                if (duidtype == DUID_TYPE_RAW && count < 2) {
-                        dhcp_duid_type |= (byte << (8 * (1 - count)));
-                        count++;
-                        continue;
-                }
-
-                dhcp_duid[duid_start_offset + dhcp_duid_len] = byte;
-                dhcp_duid_len++;
-        }
-
-        if (ltype == DUID_CONFIG_SOURCE_GLOBAL) {
-                m->duid_type = duidtype;
-                m->dhcp_duid_type = dhcp_duid_type;
-                m->dhcp_duid_len = dhcp_duid_len;
-                memcpy(&m->dhcp_duid[duid_start_offset], dhcp_duid, dhcp_duid_len);
-        } else {
-                /* DUID_CONFIG_SOURCE_NETWORK */
-                n->duid_type = duidtype;
-                n->dhcp_duid_type = dhcp_duid_type;
-                n->dhcp_duid_len = dhcp_duid_len;
-                memcpy(&n->dhcp_duid[duid_start_offset], dhcp_duid, dhcp_duid_len);
+                raw_data[count++] = byte;
         }
 
+        assert_cc(sizeof(raw_data) == sizeof(ret->raw_data));
+        memcpy(ret->raw_data, raw_data, count);
+        ret->raw_data_len = count;
         return 0;
 }
index 671e656d7bfed066e815f8b0e3193b7dfa07f56d..c7bfb42a72992348a6f65b5e25e869f96fd2c517 100644 (file)
 
 #include "networkd.h"
 
-typedef enum DuidConfigSource {
-        DUID_CONFIG_SOURCE_GLOBAL = 0,
-        DUID_CONFIG_SOURCE_NETWORK,
-} DuidConfigSource;
-
 int manager_parse_config_file(Manager *m);
 
 const struct ConfigPerfItem* networkd_gperf_lookup(const char *key, unsigned length);
 
-int config_parse_duid_type(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);
-int config_parse_duid_rawdata(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);
+int config_parse_duid_type(
+                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);
+int config_parse_duid_rawdata(
+                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);
index c5b61abc9e58f072463852087bee0b2ba6f960e9..89926e8a7eef54cad332c011b4e56aed97755209 100644 (file)
@@ -24,7 +24,7 @@
 #include "dhcp-lease-internal.h"
 #include "hostname-util.h"
 #include "network-internal.h"
-#include "networkd-link.h"
+#include "networkd.h"
 
 static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m,
                                void *userdata) {
@@ -628,28 +628,24 @@ int dhcp4_configure(Link *link) {
         }
 
         switch (link->network->dhcp_client_identifier) {
-        case DHCP_CLIENT_ID_DUID:
+        case DHCP_CLIENT_ID_DUID: {
                 /* If configured, apply user specified DUID and/or IAID */
-                if (link->network->duid_type != _DUID_TYPE_INVALID)
-                        r = sd_dhcp_client_set_iaid_duid(link->dhcp_client,
-                                                         link->network->iaid,
-                                                         link->network->dhcp_duid_type,
-                                                         link->network->dhcp_duid,
-                                                         link->network->dhcp_duid_len);
-                else
-                        r = sd_dhcp_client_set_iaid_duid(link->dhcp_client,
-                                                         link->network->iaid,
-                                                         link->manager->dhcp_duid_type,
-                                                         link->manager->dhcp_duid,
-                                                         link->manager->dhcp_duid_len);
+                const DUID *duid = link_duid(link);
+
+                r = sd_dhcp_client_set_iaid_duid(link->dhcp_client,
+                                                 link->network->iaid,
+                                                 duid->type,
+                                                 duid->raw_data_len > 0 ? duid->raw_data : NULL,
+                                                 duid->raw_data_len);
                 if (r < 0)
                         return r;
                 break;
+        }
         case DHCP_CLIENT_ID_MAC:
                 r = sd_dhcp_client_set_client_id(link->dhcp_client,
                                                  ARPHRD_ETHER,
                                                  (const uint8_t *) &link->mac,
-                                                 sizeof (link->mac));
+                                                 sizeof(link->mac));
                 if (r < 0)
                         return r;
                 break;
index d4b2fbfc57cdbac939e457a3f3040d97a57a491d..ccca4e9522171e8887ead3394061fe6fde33cf54 100644 (file)
@@ -23,7 +23,7 @@
 #include "sd-dhcp6-client.h"
 
 #include "network-internal.h"
-#include "networkd-link.h"
+#include "networkd.h"
 
 static int dhcp6_lease_address_acquired(sd_dhcp6_client *client, Link *link);
 
@@ -206,6 +206,7 @@ int dhcp6_request_address(Link *link) {
 int dhcp6_configure(Link *link) {
         sd_dhcp6_client *client = NULL;
         int r;
+        const DUID *duid;
 
         assert(link);
 
@@ -234,16 +235,11 @@ int dhcp6_configure(Link *link) {
         if (r < 0)
                 goto error;
 
-        if (link->network->duid_type != _DUID_TYPE_INVALID)
-                r = sd_dhcp6_client_set_duid(client,
-                                             link->network->dhcp_duid_type,
-                                             link->network->dhcp_duid,
-                                             link->network->dhcp_duid_len);
-        else
-                r = sd_dhcp6_client_set_duid(client,
-                                             link->manager->dhcp_duid_type,
-                                             link->manager->dhcp_duid,
-                                             link->manager->dhcp_duid_len);
+        duid = link_duid(link);
+        r = sd_dhcp6_client_set_duid(client,
+                                     duid->type,
+                                     duid->raw_data_len > 0 ? duid->raw_data : NULL,
+                                     duid->raw_data_len);
         if (r < 0)
                 goto error;
 
index 89b3e2940554746c80807fde751be28b151d5ccf..84410714f530da4edde6b8ec0dc9505df6f508c4 100644 (file)
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-typedef struct FdbEntry FdbEntry;
+#include "list.h"
+#include "macro.h"
 
-#include "networkd-network.h"
-#include "networkd.h"
+typedef struct Network Network;
+typedef struct FdbEntry FdbEntry;
+typedef struct Link Link;
 
 struct FdbEntry {
         Network *network;
index afc71b4cb8c8d2788619a9d93ff96c63fa9a5d8a..3fdfe7495548140065688d25b0584d87966b1ee1 100644 (file)
@@ -14,5 +14,5 @@ struct ConfigPerfItem;
 %struct-type
 %includes
 %%
-DHCP.DUIDType,              config_parse_duid_type,                 0,                                  offsetof(Manager, duid_type)
-DHCP.DUIDRawData,           config_parse_duid_rawdata,              DUID_CONFIG_SOURCE_GLOBAL,          offsetof(Manager, dhcp_duid)
+DHCP.DUIDType,              config_parse_duid_type,                 0,          offsetof(Manager, duid.type)
+DHCP.DUIDRawData,           config_parse_duid_rawdata,              0,          offsetof(Manager, duid)
index e05fd3eea7bbbb61b0dc0ddb996de094f339587f..35c9b0647320b6a4304bf5ceeb58c21542cac79b 100644 (file)
@@ -21,7 +21,7 @@
 #include <linux/if.h>
 
 #include "network-internal.h"
-#include "networkd-link.h"
+#include "networkd.h"
 
 static int ipv4ll_address_lost(Link *link) {
         _cleanup_address_free_ Address *address = NULL;
index 5fc513bfdad9906a5eac984aaa2a4cfbfe5baf2a..c646af1f1a67f903045a9b49497c5c540276f0fc 100644 (file)
@@ -28,9 +28,8 @@
 #include "fileio.h"
 #include "netlink-util.h"
 #include "network-internal.h"
-#include "networkd-link.h"
+#include "networkd.h"
 #include "networkd-lldp-tx.h"
-#include "networkd-netdev.h"
 #include "set.h"
 #include "socket-util.h"
 #include "stdio-util.h"
@@ -2880,6 +2879,8 @@ int link_update(Link *link, sd_netlink_message *m) {
                         }
 
                         if (link->dhcp_client) {
+                                const DUID *duid = link_duid(link);
+
                                 r = sd_dhcp_client_set_mac(link->dhcp_client,
                                                            (const uint8_t *) &link->mac,
                                                            sizeof (link->mac),
@@ -2887,23 +2888,18 @@ int link_update(Link *link, sd_netlink_message *m) {
                                 if (r < 0)
                                         return log_link_warning_errno(link, r, "Could not update MAC address in DHCP client: %m");
 
-                                if (link->network->duid_type != _DUID_TYPE_INVALID)
-                                        r = sd_dhcp_client_set_iaid_duid(link->dhcp_client,
-                                                                         link->network->iaid,
-                                                                         link->network->dhcp_duid_type,
-                                                                         link->network->dhcp_duid,
-                                                                         link->network->dhcp_duid_len);
-                                else
-                                        r = sd_dhcp_client_set_iaid_duid(link->dhcp_client,
-                                                                         link->network->iaid,
-                                                                         link->manager->dhcp_duid_type,
-                                                                         link->manager->dhcp_duid,
-                                                                         link->manager->dhcp_duid_len);
+                                r = sd_dhcp_client_set_iaid_duid(link->dhcp_client,
+                                                                 link->network->iaid,
+                                                                 duid->type,
+                                                                 duid->raw_data_len > 0 ? duid->raw_data : NULL,
+                                                                 duid->raw_data_len);
                                 if (r < 0)
                                         return log_link_warning_errno(link, r, "Could not update DUID/IAID in DHCP client: %m");
                         }
 
                         if (link->dhcp6_client) {
+                                const DUID* duid = link_duid(link);
+
                                 r = sd_dhcp6_client_set_mac(link->dhcp6_client,
                                                             (const uint8_t *) &link->mac,
                                                             sizeof (link->mac),
@@ -2916,16 +2912,10 @@ int link_update(Link *link, sd_netlink_message *m) {
                                 if (r < 0)
                                         return log_link_warning_errno(link, r, "Could not update DHCPv6 IAID: %m");
 
-                                if (link->network->duid_type != _DUID_TYPE_INVALID)
-                                        r = sd_dhcp6_client_set_duid(link->dhcp6_client,
-                                                                     link->network->dhcp_duid_type,
-                                                                     link->network->dhcp_duid,
-                                                                     link->network->dhcp_duid_len);
-                                else
-                                        r = sd_dhcp6_client_set_duid(link->dhcp6_client,
-                                                                     link->manager->dhcp_duid_type,
-                                                                     link->manager->dhcp_duid,
-                                                                     link->manager->dhcp_duid_len);
+                                r = sd_dhcp6_client_set_duid(link->dhcp6_client,
+                                                             duid->type,
+                                                             duid->raw_data_len > 0 ? duid->raw_data : NULL,
+                                                             duid->raw_data_len);
                                 if (r < 0)
                                         return log_link_warning_errno(link, r, "Could not update DHCPv6 DUID: %m");
                         }
index f2a64ca9b5a80162b7f143ef87c71f7a0ec2d3f2..86139be55757a9026da13e12ec5990b7bf4ca928 100644 (file)
 
 #include <endian.h>
 
+#include "sd-bus.h"
 #include "sd-dhcp-client.h"
 #include "sd-dhcp-server.h"
 #include "sd-dhcp6-client.h"
 #include "sd-ipv4ll.h"
 #include "sd-lldp.h"
 #include "sd-ndisc.h"
+#include "sd-netlink.h"
 
-typedef struct Link Link;
+#include "list.h"
+#include "set.h"
 
 typedef enum LinkState {
         LINK_STATE_PENDING,
@@ -54,11 +57,11 @@ typedef enum LinkOperationalState {
         _LINK_OPERSTATE_INVALID = -1
 } LinkOperationalState;
 
-#include "networkd-address.h"
-#include "networkd-network.h"
-#include "networkd.h"
+typedef struct Manager Manager;
+typedef struct Network Network;
+typedef struct Address Address;
 
-struct Link {
+typedef struct Link {
         Manager *manager;
 
         int n_ref;
@@ -122,7 +125,7 @@ struct Link {
 
         Hashmap *bound_by_links;
         Hashmap *bound_to_links;
-};
+} Link;
 
 Link *link_unref(Link *link);
 Link *link_ref(Link *link);
index 6bde04bc32300e77f044445de5ebc504a617411a..03b694c3f1c520bdf0430e6a29df1bd70c1eba8c 100644 (file)
 #include <inttypes.h>
 #include <string.h>
 
+#include "alloc-util.h"
 #include "fd-util.h"
 #include "fileio.h"
 #include "hostname-util.h"
-#include "networkd-lldp-tx.h"
 #include "random-util.h"
 #include "socket-util.h"
 #include "string-util.h"
 #include "unaligned.h"
 
+#include "networkd.h"
+#include "networkd-lldp-tx.h"
+
 #define LLDP_MULTICAST_ADDR { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e }
 
 /* The LLDP spec calls this "txFastInit", see 9.2.5.19 */
index d355aaa19c8d598530d8fe9666e1ff0eace43c4d..5dcd4df5361cf4d78a208afbf4b067e572f77b89 100644 (file)
@@ -1037,7 +1037,7 @@ int manager_new(Manager **ret) {
         if (r < 0)
                 return r;
 
-        m->duid_type = _DUID_TYPE_INVALID;
+        m->duid.type = DUID_TYPE_EN;
 
         *ret = m;
         m = NULL;
index 4577292e444b2f3543531a181b4e11bb69912ba3..b22c58bfe530e079639e4310ec24c8b9dd8735fd 100644 (file)
@@ -24,7 +24,7 @@
 
 #include "sd-ndisc.h"
 
-#include "networkd-link.h"
+#include "networkd.h"
 
 static int ndisc_netlink_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
         _cleanup_link_unref_ Link *link = userdata;
index 6b9cbcded6ba7bb4e260256108dd9dc8319b3c1d..7913b0088eb80f30c19d7748a45d434533ce1e2d 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "alloc-util.h"
 #include "conf-parser.h"
+#include "extract-word.h"
 #include "missing.h"
 #include "networkd-netdev-bond.h"
 #include "string-table.h"
index cb6baea24f034685be5a47a06d62ea75b08c1976..b941edb3445da131965a0550802322c64b2a631f 100644 (file)
@@ -20,8 +20,7 @@
 ***/
 
 #include "in-addr-util.h"
-
-typedef struct Bond Bond;
+#include "list.h"
 
 #include "networkd-netdev.h"
 
@@ -106,7 +105,7 @@ typedef struct ArpIpTarget {
         LIST_FIELDS(struct ArpIpTarget, arp_ip_target);
 } ArpIpTarget;
 
-struct Bond {
+typedef struct Bond {
         NetDev meta;
 
         BondMode mode;
@@ -133,8 +132,9 @@ struct Bond {
 
         int n_arp_ip_targets;
         ArpIpTarget *arp_ip_targets;
-};
+} Bond;
 
+DEFINE_NETDEV_CAST(BOND, Bond);
 extern const NetDevVTable bond_vtable;
 
 const char *bond_mode_to_string(BondMode d) _const_;
index 3f91b2eaeab3819f6535002afe5e87b76446cd24..3e44dd7960b29b7988cbae4eb57ad19b5a20b04d 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "missing.h"
 #include "netlink-util.h"
+#include "networkd.h"
 #include "networkd-netdev-bridge.h"
 
 /* callback for brige netdev's parameter set */
index 3f6f1d0502571e791bae55852372833cc00541e7..b921439f02fee421940f45da31c8113d9c2c6195 100644 (file)
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-typedef struct Bridge Bridge;
-
 #include "networkd-netdev.h"
 
-struct Bridge {
+typedef struct Bridge {
         NetDev meta;
 
         int mcast_querier;
@@ -31,6 +29,7 @@ struct Bridge {
         usec_t forward_delay;
         usec_t hello_time;
         usec_t max_age;
-};
+} Bridge;
 
+DEFINE_NETDEV_CAST(BRIDGE, Bridge);
 extern const NetDevVTable bridge_vtable;
index 42da62ebe4b03b454c6984c2e0d6f5f06b136fef..efe302267e00a10f7a98c6d977ca04388f944862 100644 (file)
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-typedef struct Dummy Dummy;
-
 #include "networkd-netdev.h"
 
-struct Dummy {
+typedef struct Dummy {
         NetDev meta;
-};
+} Dummy;
 
+DEFINE_NETDEV_CAST(DUMMY, Dummy);
 extern const NetDevVTable dummy_vtable;
index 15a787a9e3bf1f4b3e035dcd7ad78cfa1478a158..1ebd0fdf2093530060ce449ab1d77c5abeaa7d0c 100644 (file)
@@ -1,11 +1,17 @@
 %{
 #include <stddef.h>
 #include "conf-parser.h"
-#include "networkd-netdev.h"
-#include "networkd-netdev-tunnel.h"
+#include "network-internal.h"
 #include "networkd-netdev-bond.h"
+#include "networkd-netdev-ipvlan.h"
 #include "networkd-netdev-macvlan.h"
-#include "network-internal.h"
+#include "networkd-netdev-tunnel.h"
+#include "networkd-netdev-tuntap.h"
+#include "networkd-netdev-veth.h"
+#include "networkd-netdev-vlan.h"
+#include "networkd-netdev-vxlan.h"
+#include "networkd-netdev-bridge.h"
+#include "networkd-netdev.h"
 %}
 struct ConfigPerfItem;
 %null_strings
index 4bd0b67866ebc51d8b19ccce8fe9a2e8e38678ed..10d407984431459b0cd29be4eccfbb74e5a32552 100644 (file)
@@ -19,8 +19,6 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-typedef struct IPVlan IPVlan;
-
 #include "missing.h"
 #include "networkd-netdev.h"
 
@@ -31,12 +29,13 @@ typedef enum IPVlanMode {
         _NETDEV_IPVLAN_MODE_INVALID = -1
 } IPVlanMode;
 
-struct IPVlan {
+typedef struct IPVlan {
         NetDev meta;
 
         IPVlanMode mode;
-};
+} IPVlan;
 
+DEFINE_NETDEV_CAST(IPVLAN, IPVlan);
 extern const NetDevVTable ipvlan_vtable;
 
 const char *ipvlan_mode_to_string(IPVlanMode d) _const_;
index 622ef9ef53b04ca827e2133f3c9525b51d03fa3b..3663f4f051ad51ad7050f200ba579c75440a9570 100644 (file)
@@ -38,6 +38,8 @@ struct MacVlan {
         MacVlanMode mode;
 };
 
+DEFINE_NETDEV_CAST(MACVLAN, MacVlan);
+DEFINE_NETDEV_CAST(MACVTAP, MacVlan);
 extern const NetDevVTable macvlan_vtable;
 extern const NetDevVTable macvtap_vtable;
 
index 0d41f80a3c22d93b71570814166f7fcc7276719c..7d31e7b68702c2c443bc28b4f4f656f98628db94 100644 (file)
@@ -19,7 +19,7 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-typedef struct Tunnel Tunnel;
+#include "in-addr-util.h"
 
 #include "networkd-netdev.h"
 
@@ -37,7 +37,7 @@ typedef enum IPv6FlowLabel {
         _NETDEV_IPV6_FLOWLABEL_INVALID = -1,
 } IPv6FlowLabel;
 
-struct Tunnel {
+typedef struct Tunnel {
         NetDev meta;
 
         uint8_t encap_limit;
@@ -56,8 +56,17 @@ struct Tunnel {
 
         bool pmtudisc;
         bool copy_dscp;
-};
-
+} Tunnel;
+
+DEFINE_NETDEV_CAST(IPIP, Tunnel);
+DEFINE_NETDEV_CAST(GRE, Tunnel);
+DEFINE_NETDEV_CAST(GRETAP, Tunnel);
+DEFINE_NETDEV_CAST(IP6GRE, Tunnel);
+DEFINE_NETDEV_CAST(IP6GRETAP, Tunnel);
+DEFINE_NETDEV_CAST(SIT, Tunnel);
+DEFINE_NETDEV_CAST(VTI, Tunnel);
+DEFINE_NETDEV_CAST(VTI6, Tunnel);
+DEFINE_NETDEV_CAST(IP6TNL, Tunnel);
 extern const NetDevVTable ipip_vtable;
 extern const NetDevVTable sit_vtable;
 extern const NetDevVTable vti_vtable;
index 32917fe6d5e44282d1b2eb6f3a72ce2a202fc400..088a4d8d321aa5b824d2a7e058c6df0609cbfc92 100644 (file)
     along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-#include <net/if.h>
-#include <sys/ioctl.h>
+#include <fcntl.h>
 #include <linux/if_tun.h>
+#include <net/if.h>
 #include <netinet/if_ether.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
 
 #include "alloc-util.h"
 #include "fd-util.h"
index cbb7ee05a6bc65dab328eaf44e455a329d29a37d..120f00a3539ae19269e7cbaf2eddc8b6f88c8cc7 100644 (file)
@@ -34,5 +34,7 @@ struct TunTap {
         bool vnet_hdr;
 };
 
+DEFINE_NETDEV_CAST(TUN, TunTap);
+DEFINE_NETDEV_CAST(TAP, TunTap);
 extern const NetDevVTable tun_vtable;
 extern const NetDevVTable tap_vtable;
index ae5785783c0c212229e30be56c3f03ea76d3e167..e69bfbc8f03258b9a7b2527377784e0c4ab264e1 100644 (file)
@@ -30,4 +30,5 @@ struct Veth {
         struct ether_addr *mac_peer;
 };
 
+DEFINE_NETDEV_CAST(VETH, Veth);
 extern const NetDevVTable veth_vtable;
index 1de6a1cc36fd41e03fb7523e57ecbc6d8207de31..73aacf4a0f8ae15f1825293d579b9bdc11fac3a6 100644 (file)
@@ -31,4 +31,5 @@ struct VLan {
         uint64_t id;
 };
 
+DEFINE_NETDEV_CAST(VLAN, VLan);
 extern const NetDevVTable vlan_vtable;
index dabbd97c87da24f30aa897abb1942e942178777a..724f9861be11455876045ecd5c02b93c4dcaa417 100644 (file)
 
 #include "conf-parser.h"
 #include "alloc-util.h"
+#include "extract-word.h"
 #include "parse-util.h"
 #include "missing.h"
+
 #include "networkd-link.h"
 #include "networkd-netdev-vxlan.h"
 
index a4bb44635a32d755333fc9996e8284ab5dabb8ad..4614c66fd1e132c4f40cb6ecdba1f157bb842127 100644 (file)
@@ -55,6 +55,7 @@ struct VxLan {
         struct ifla_vxlan_port_range port_range;
 };
 
+DEFINE_NETDEV_CAST(VXLAN, VxLan);
 extern const NetDevVTable vxlan_vtable;
 
 int config_parse_vxlan_group_address(const char *unit,
index 7ea825fcb460f5174b991933e21896fd61feb9b5..20244c03099801f02a1bc9cd2464809d8058b7e4 100644 (file)
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-#include "list.h"
-
-typedef struct NetDev NetDev;
-typedef struct NetDevVTable NetDevVTable;
+#include "sd-netlink.h"
 
-#include "networkd-link.h"
-#include "networkd.h"
+#include "list.h"
+#include "time-util.h"
 
 typedef struct netdev_join_callback netdev_join_callback;
+typedef struct Link Link;
 
 struct netdev_join_callback {
         sd_netlink_message_handler_t callback;
@@ -78,7 +76,10 @@ typedef enum NetDevCreateType {
         _NETDEV_CREATE_INVALID = -1,
 } NetDevCreateType;
 
-struct NetDev {
+typedef struct Manager Manager;
+typedef struct Condition Condition;
+
+typedef struct NetDev {
         Manager *manager;
 
         int n_ref;
@@ -99,20 +100,9 @@ struct NetDev {
         int ifindex;
 
         LIST_HEAD(netdev_join_callback, callbacks);
-};
+} NetDev;
 
-#include "networkd-netdev-bond.h"
-#include "networkd-netdev-bridge.h"
-#include "networkd-netdev-dummy.h"
-#include "networkd-netdev-ipvlan.h"
-#include "networkd-netdev-macvlan.h"
-#include "networkd-netdev-tunnel.h"
-#include "networkd-netdev-tuntap.h"
-#include "networkd-netdev-veth.h"
-#include "networkd-netdev-vlan.h"
-#include "networkd-netdev-vxlan.h"
-
-struct NetDevVTable {
+typedef struct NetDevVTable {
         /* How much memory does an object of this unit type need */
         size_t object_size;
 
@@ -144,14 +134,14 @@ struct NetDevVTable {
 
         /* verify that compulsory configuration options were specified */
         int (*config_verify)(NetDev *netdev, const char *filename);
-};
+} NetDevVTable;
 
 extern const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX];
 
 #define NETDEV_VTABLE(n) netdev_vtable[(n)->kind]
 
 /* For casting a netdev into the various netdev kinds */
-#define DEFINE_CAST(UPPERCASE, MixedCase)                                   \
+#define DEFINE_NETDEV_CAST(UPPERCASE, MixedCase)                            \
         static inline MixedCase* UPPERCASE(NetDev *n) {                     \
                 if (_unlikely_(!n || n->kind != NETDEV_KIND_##UPPERCASE))   \
                         return NULL;                                        \
@@ -162,27 +152,6 @@ extern const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX];
 /* For casting the various netdev kinds into a netdev */
 #define NETDEV(n) (&(n)->meta)
 
-DEFINE_CAST(BRIDGE, Bridge);
-DEFINE_CAST(BOND, Bond);
-DEFINE_CAST(VLAN, VLan);
-DEFINE_CAST(MACVLAN, MacVlan);
-DEFINE_CAST(MACVTAP, MacVlan);
-DEFINE_CAST(IPVLAN, IPVlan);
-DEFINE_CAST(VXLAN, VxLan);
-DEFINE_CAST(IPIP, Tunnel);
-DEFINE_CAST(GRE, Tunnel);
-DEFINE_CAST(GRETAP, Tunnel);
-DEFINE_CAST(IP6GRE, Tunnel);
-DEFINE_CAST(IP6GRETAP, Tunnel);
-DEFINE_CAST(SIT, Tunnel);
-DEFINE_CAST(VTI, Tunnel);
-DEFINE_CAST(VTI6, Tunnel);
-DEFINE_CAST(IP6TNL, Tunnel);
-DEFINE_CAST(VETH, Veth);
-DEFINE_CAST(DUMMY, Dummy);
-DEFINE_CAST(TUN, TunTap);
-DEFINE_CAST(TAP, TunTap);
-
 int netdev_load(Manager *manager);
 void netdev_drop(NetDev *netdev);
 
index 550b5e524014d2f0e78dacebff1b7568d184f937..51e750b299acdd91fa9e78de1a0ab7e025d87be3 100644 (file)
@@ -85,8 +85,8 @@ DHCP.Hostname,                          config_parse_hostname,
 DHCP.RequestBroadcast,                  config_parse_bool,                              0,                             offsetof(Network, dhcp_broadcast)
 DHCP.CriticalConnection,                config_parse_bool,                              0,                             offsetof(Network, dhcp_critical)
 DHCP.VendorClassIdentifier,             config_parse_string,                            0,                             offsetof(Network, dhcp_vendor_class_identifier)
-DHCP.DUIDType,                          config_parse_duid_type,                         0,                             offsetof(Network, duid_type)
-DHCP.DUIDRawData,                       config_parse_duid_rawdata,                      DUID_CONFIG_SOURCE_NETWORK,    offsetof(Network, dhcp_duid)
+DHCP.DUIDType,                          config_parse_duid_type,                         0,                             offsetof(Network, duid.type)
+DHCP.DUIDRawData,                       config_parse_duid_rawdata,                      0,                             offsetof(Network, duid)
 DHCP.RouteMetric,                       config_parse_unsigned,                          0,                             offsetof(Network, dhcp_route_metric)
 DHCP.UseTimezone,                       config_parse_bool,                              0,                             offsetof(Network, dhcp_use_timezone)
 DHCPServer.MaxLeaseTimeSec,             config_parse_sec,                               0,                             offsetof(Network, dhcp_server_max_lease_time_usec)
index 2ebcdfa744b4aef3591486b913c8738031af8d5e..206c270e501b4da198b2df43db28c25a53109d77 100644 (file)
@@ -131,7 +131,7 @@ static int network_load_one(Manager *manager, const char *filename) {
         network->ipv6_accept_ra = -1;
         network->ipv6_dad_transmits = -1;
         network->ipv6_hop_limit = -1;
-        network->duid_type = _DUID_TYPE_INVALID;
+        network->duid.type = _DUID_TYPE_INVALID;
         network->proxy_arp = -1;
 
         r = config_parse(NULL, filename, file,
index 15417f48280f00ef3ab2eaced79b1691143dad79..ff2414efdde5163282d118760ea4385226d71dd7 100644 (file)
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
+#include "sd-bus.h"
+#include "udev.h"
+
 #include "condition.h"
+#include "dhcp-identifier.h"
+#include "hashmap.h"
 #include "resolve-util.h"
 
-typedef struct Network Network;
-
-#include "dhcp-identifier.h"
 #include "networkd-address.h"
 #include "networkd-fdb.h"
 #include "networkd-netdev.h"
 #include "networkd-route.h"
 #include "networkd-util.h"
-#include "networkd.h"
 
 #define DHCP_ROUTE_METRIC 1024
 #define IPV4LL_ROUTE_METRIC 2048
@@ -67,6 +68,16 @@ typedef enum LLDPMode {
         _LLDP_MODE_INVALID = -1,
 } LLDPMode;
 
+typedef struct DUID {
+        /* Value of Type in [DHCP] section */
+        DUIDType type;
+
+        uint8_t raw_data_len;
+        uint8_t raw_data[MAX_DUID_LEN];
+} DUID;
+
+typedef struct Manager Manager;
+
 struct Network {
         Manager *manager;
 
@@ -147,12 +158,7 @@ struct Network {
         struct ether_addr *mac;
         unsigned mtu;
         uint32_t iaid;
-        /* Value of Type in [DUID] section */
-        DUIDType duid_type;
-        /* DUID type code - RFC 3315 */
-        uint16_t dhcp_duid_type;
-        size_t dhcp_duid_len;
-        uint8_t dhcp_duid[MAX_DUID_LEN];
+        DUID duid;
 
         LLDPMode lldp_mode; /* LLDP reception */
         bool lldp_emit;     /* LLDP transmission */
index 3ddeea96b754beb5945fcc9097bd4d3712f5d57c..84d74992c994086df7ee6f428b3d3c8e35ddcd52 100644 (file)
@@ -22,7 +22,6 @@
 typedef struct Route Route;
 
 #include "networkd-network.h"
-#include "networkd.h"
 
 struct Route {
         Network *network;
index 72a2438ac8db5d5f88fffe2c71448f3dffb30d80..26d9e7d6e0829315cc7e1cb5dc1a2d68765bd1c5 100644 (file)
 #include "sd-bus.h"
 #include "sd-event.h"
 #include "sd-netlink.h"
+#include "udev.h"
 
+#include "dhcp-identifier.h"
 #include "hashmap.h"
 #include "list.h"
-#include "udev.h"
 
-typedef struct Manager Manager;
-
-#include "dhcp-identifier.h"
 #include "networkd-address-pool.h"
 #include "networkd-link.h"
+#include "networkd-netdev-bond.h"
+#include "networkd-netdev-bridge.h"
+#include "networkd-netdev-dummy.h"
+#include "networkd-netdev-ipvlan.h"
+#include "networkd-netdev-macvlan.h"
+#include "networkd-netdev-tunnel.h"
+#include "networkd-netdev-tuntap.h"
+#include "networkd-netdev-veth.h"
+#include "networkd-netdev-vlan.h"
+#include "networkd-netdev-vlan.h"
+#include "networkd-netdev-vxlan.h"
 #include "networkd-network.h"
 #include "networkd-util.h"
 
+extern const char* const network_dirs[];
+
 struct Manager {
         sd_netlink *rtnl;
         sd_event *event;
@@ -63,17 +74,15 @@ struct Manager {
 
         usec_t network_dirs_ts_usec;
 
-        /* Value of Type in [DUID] section */
-        DUIDType duid_type;
-        /* DUID type code - RFC 3315 */
-        uint16_t dhcp_duid_type;
-        size_t dhcp_duid_len;
-        uint8_t dhcp_duid[MAX_DUID_LEN];
+        DUID duid;
 };
 
-extern const char* const network_dirs[];
-
-/* Manager */
+static inline const DUID* link_duid(const Link *link) {
+        if (link->network->duid.type != _DUID_TYPE_INVALID)
+                return &link->network->duid;
+        else
+                return &link->manager->duid;
+}
 
 extern const sd_bus_vtable manager_vtable[];
 
diff --git a/src/network/test-networkd-conf.c b/src/network/test-networkd-conf.c
new file mode 100644 (file)
index 0000000..8a62a2a
--- /dev/null
@@ -0,0 +1,89 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2016 Zbigniew Jędrzejewski-Szmek
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "hexdecoct.h"
+#include "log.h"
+#include "macro.h"
+#include "string-util.h"
+
+#include "networkd-conf.h"
+#include "networkd-network.h"
+
+static void test_config_parse_duid_type_one(const char *rvalue, int ret, DUIDType expected) {
+        DUIDType actual = 0;
+        int r;
+
+        r = config_parse_duid_type("network", "filename", 1, "section", 1, "lvalue", 0, rvalue, &actual, NULL);
+        log_info_errno(r, "\"%s\" → %d (%m)", rvalue, actual);
+        assert_se(r == ret);
+        assert_se(expected == actual);
+}
+
+static void test_config_parse_duid_type(void) {
+        test_config_parse_duid_type_one("", 0, 0);
+        test_config_parse_duid_type_one("link-layer-time", 0, DUID_TYPE_LLT);
+        test_config_parse_duid_type_one("vendor", 0, DUID_TYPE_EN);
+        test_config_parse_duid_type_one("link-layer", 0, DUID_TYPE_LL);
+        test_config_parse_duid_type_one("uuid", 0, DUID_TYPE_UUID);
+        test_config_parse_duid_type_one("foo", 0, 0);
+}
+
+static void test_config_parse_duid_rawdata_one(const char *rvalue, int ret, const DUID* expected) {
+        DUID actual = {};
+        int r;
+
+        r = config_parse_duid_rawdata("network", "filename", 1, "section", 1, "lvalue", 0, rvalue, &actual, NULL);
+        log_info_errno(r, "\"%s\" → \"%s\" (%m)",
+                       rvalue, strnull(hexmem(actual.raw_data, actual.raw_data_len)));
+        assert_se(r == ret);
+        if (expected) {
+                assert_se(actual.raw_data_len == expected->raw_data_len);
+                assert_se(memcmp(actual.raw_data, expected->raw_data, expected->raw_data_len) == 0);
+        }
+}
+
+#define BYTES_0_128 "0:1:2:3:4:5:6:7:8:9:a:b:c:d:e:f:10:11:12:13:14:15:16:17:18:19:1a:1b:1c:1d:1e:1f:20:21:22:23:24:25:26:27:28:29:2a:2b:2c:2d:2e:2f:30:31:32:33:34:35:36:37:38:39:3a:3b:3c:3d:3e:3f:40:41:42:43:44:45:46:47:48:49:4a:4b:4c:4d:4e:4f:50:51:52:53:54:55:56:57:58:59:5a:5b:5c:5d:5e:5f:60:61:62:63:64:65:66:67:68:69:6a:6b:6c:6d:6e:6f:70:71:72:73:74:75:76:77:78:79:7a:7b:7c:7d:7e:7f:80"
+
+#define BYTES_1_128 {0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,0xb,0xc,0xd,0xe,0xf,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f,0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,0x80}
+
+static void test_config_parse_duid_rawdata(void) {
+        test_config_parse_duid_rawdata_one("", 0, &(DUID){});
+        test_config_parse_duid_rawdata_one("00:11:22:33:44:55:66:77", 0,
+                                           &(DUID){0, 8, {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77}});
+        test_config_parse_duid_rawdata_one("00:11:22:", 0,
+                                           &(DUID){0, 3, {0x00,0x11,0x22}});
+        test_config_parse_duid_rawdata_one("000:11:22", 0, &(DUID){}); /* error, output is all zeros */
+        test_config_parse_duid_rawdata_one("00:111:22", 0, &(DUID){});
+        test_config_parse_duid_rawdata_one("0:1:2:3:4:5:6:7", 0,
+                                           &(DUID){0, 8, {0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7}});
+        test_config_parse_duid_rawdata_one("11::", 0, &(DUID){0, 1, {0x11}});  /* FIXME: should this be an error? */
+        test_config_parse_duid_rawdata_one("abcdef", 0, &(DUID){});
+        test_config_parse_duid_rawdata_one(BYTES_0_128, 0, &(DUID){});
+        test_config_parse_duid_rawdata_one(BYTES_0_128 + 2, 0, &(DUID){0, 128, BYTES_1_128});
+}
+
+int main(int argc, char **argv) {
+        log_parse_environment();
+        log_open();
+
+        test_config_parse_duid_type();
+        test_config_parse_duid_rawdata();
+
+        return 0;
+}
index 374ff8774e8b8c089690e9fa4a1ac2c3b0ba7e53..20b8c2873f25add3b3773bb810aef170950c55e9 100644 (file)
@@ -84,28 +84,57 @@ enum {
 
 typedef struct sd_dhcp_client sd_dhcp_client;
 
-typedef void (*sd_dhcp_client_callback_t)(sd_dhcp_client *client, int event,
-                                    void *userdata);
-int sd_dhcp_client_set_callback(sd_dhcp_client *client, sd_dhcp_client_callback_t cb,
-                                void *userdata);
-
-int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option);
-int sd_dhcp_client_set_request_address(sd_dhcp_client *client,
-                                       const struct in_addr *last_address);
-int sd_dhcp_client_set_request_broadcast(sd_dhcp_client *client, int broadcast);
-int sd_dhcp_client_set_index(sd_dhcp_client *client, int interface_index);
-int sd_dhcp_client_set_mac(sd_dhcp_client *client, const uint8_t *addr,
-                           size_t addr_len, uint16_t arp_type);
-int sd_dhcp_client_set_client_id(sd_dhcp_client *client, uint8_t type,
-                                 const uint8_t *data, size_t data_len);
-int sd_dhcp_client_set_iaid_duid(sd_dhcp_client *client, uint32_t iaid,
-                                 uint16_t duid_type, uint8_t *duid, size_t duid_len);
-int sd_dhcp_client_get_client_id(sd_dhcp_client *client, uint8_t *type,
-                                 const uint8_t **data, size_t *data_len);
-int sd_dhcp_client_set_mtu(sd_dhcp_client *client, uint32_t mtu);
-int sd_dhcp_client_set_hostname(sd_dhcp_client *client, const char *hostname);
-int sd_dhcp_client_set_vendor_class_identifier(sd_dhcp_client *client, const char *vci);
-int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret);
+typedef void (*sd_dhcp_client_callback_t)(sd_dhcp_client *client, int event, void *userdata);
+int sd_dhcp_client_set_callback(
+                sd_dhcp_client *client,
+                sd_dhcp_client_callback_t cb,
+                void *userdata);
+
+int sd_dhcp_client_set_request_option(
+                sd_dhcp_client *client,
+                uint8_t option);
+int sd_dhcp_client_set_request_address(
+                sd_dhcp_client *client,
+                const struct in_addr *last_address);
+int sd_dhcp_client_set_request_broadcast(
+                sd_dhcp_client *client,
+                int broadcast);
+int sd_dhcp_client_set_index(
+                sd_dhcp_client *client,
+                int interface_index);
+int sd_dhcp_client_set_mac(
+                sd_dhcp_client *client,
+                const uint8_t *addr,
+                size_t addr_len,
+                uint16_t arp_type);
+int sd_dhcp_client_set_client_id(
+                sd_dhcp_client *client,
+                uint8_t type,
+                const uint8_t *data,
+                size_t data_len);
+int sd_dhcp_client_set_iaid_duid(
+                sd_dhcp_client *client,
+                uint32_t iaid,
+                uint16_t duid_type,
+                const void *duid,
+                size_t duid_len);
+int sd_dhcp_client_get_client_id(
+                sd_dhcp_client *client,
+                uint8_t *type,
+                const uint8_t **data,
+                size_t *data_len);
+int sd_dhcp_client_set_mtu(
+                sd_dhcp_client *client,
+                uint32_t mtu);
+int sd_dhcp_client_set_hostname(
+                sd_dhcp_client *client,
+                const char *hostname);
+int sd_dhcp_client_set_vendor_class_identifier(
+                sd_dhcp_client *client,
+                const char *vci);
+int sd_dhcp_client_get_lease(
+                sd_dhcp_client *client,
+                sd_dhcp_lease **ret);
 
 int sd_dhcp_client_stop(sd_dhcp_client *client);
 int sd_dhcp_client_start(sd_dhcp_client *client);
@@ -115,7 +144,10 @@ sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client);
 
 int sd_dhcp_client_new(sd_dhcp_client **ret);
 
-int sd_dhcp_client_attach_event(sd_dhcp_client *client, sd_event *event, int64_t priority);
+int sd_dhcp_client_attach_event(
+                sd_dhcp_client *client,
+                sd_event *event,
+                int64_t priority);
 int sd_dhcp_client_detach_event(sd_dhcp_client *client);
 sd_event *sd_dhcp_client_get_event(sd_dhcp_client *client);
 
index 4604cb6382f0b8e571813f384df8c0aaa7901f17..90f62eaca4e1386e522019039d227f0368822bff 100644 (file)
@@ -76,29 +76,52 @@ enum {
 
 typedef struct sd_dhcp6_client sd_dhcp6_client;
 
-typedef void (*sd_dhcp6_client_callback_t)(sd_dhcp6_client *client, int event,
-                                     void *userdata);
-int sd_dhcp6_client_set_callback(sd_dhcp6_client *client,
-                                 sd_dhcp6_client_callback_t cb, void *userdata);
-
-int sd_dhcp6_client_set_index(sd_dhcp6_client *client, int interface_index);
-int sd_dhcp6_client_set_local_address(sd_dhcp6_client *client, const struct in6_addr *local_address);
-int sd_dhcp6_client_set_mac(sd_dhcp6_client *client, const uint8_t *addr,
-                            size_t addr_len, uint16_t arp_type);
-int sd_dhcp6_client_set_duid(sd_dhcp6_client *client, uint16_t duid_type,
-                             uint8_t *duid, size_t duid_len);
-int sd_dhcp6_client_set_iaid(sd_dhcp6_client *client, uint32_t iaid);
-int sd_dhcp6_client_set_information_request(sd_dhcp6_client *client, int enabled);
-int sd_dhcp6_client_get_information_request(sd_dhcp6_client *client, int *enabled);
-int sd_dhcp6_client_set_request_option(sd_dhcp6_client *client,
-                                       uint16_t option);
-
-int sd_dhcp6_client_get_lease(sd_dhcp6_client *client, sd_dhcp6_lease **ret);
+typedef void (*sd_dhcp6_client_callback_t)(sd_dhcp6_client *client, int event, void *userdata);
+int sd_dhcp6_client_set_callback(
+                sd_dhcp6_client *client,
+                sd_dhcp6_client_callback_t cb,
+                void *userdata);
+
+int sd_dhcp6_client_set_index(
+                sd_dhcp6_client *client,
+                int interface_index);
+int sd_dhcp6_client_set_local_address(
+                sd_dhcp6_client *client,
+                const struct in6_addr *local_address);
+int sd_dhcp6_client_set_mac(
+                sd_dhcp6_client *client,
+                const uint8_t *addr,
+                size_t addr_len,
+                uint16_t arp_type);
+int sd_dhcp6_client_set_duid(
+                sd_dhcp6_client *client,
+                uint16_t duid_type,
+                const void *duid,
+                size_t duid_len);
+int sd_dhcp6_client_set_iaid(
+                sd_dhcp6_client *client,
+                uint32_t iaid);
+int sd_dhcp6_client_set_information_request(
+                sd_dhcp6_client *client,
+                int enabled);
+int sd_dhcp6_client_get_information_request(
+                sd_dhcp6_client *client,
+                int *enabled);
+int sd_dhcp6_client_set_request_option(
+                sd_dhcp6_client *client,
+                uint16_t option);
+
+int sd_dhcp6_client_get_lease(
+                sd_dhcp6_client *client,
+                sd_dhcp6_lease **ret);
 
 int sd_dhcp6_client_stop(sd_dhcp6_client *client);
 int sd_dhcp6_client_start(sd_dhcp6_client *client);
 int sd_dhcp6_client_is_running(sd_dhcp6_client *client);
-int sd_dhcp6_client_attach_event(sd_dhcp6_client *client, sd_event *event, int64_t priority);
+int sd_dhcp6_client_attach_event(
+                sd_dhcp6_client *client,
+                sd_event *event,
+                int64_t priority);
 int sd_dhcp6_client_detach_event(sd_dhcp6_client *client);
 sd_event *sd_dhcp6_client_get_event(sd_dhcp6_client *client);
 sd_dhcp6_client *sd_dhcp6_client_ref(sd_dhcp6_client *client);