summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2016-05-04 11:31:59 +0200
committerLennart Poettering <lennart@poettering.net>2016-05-04 11:31:59 +0200
commit5119d304ffe4d1bcac27626c842413f5f2defe0d (patch)
tree885cf6798f613b967fe2c0acd387af9cc371761a
parentf8e2f4d6a0c6bcb5a03abe580d657b932cdb9798 (diff)
parent7c285c74190e827c18a336f882cf4d9dcf4ee02a (diff)
Merge pull request #3156 from keszybz/duid-settings
Rework DUID setting
-rw-r--r--.gitignore1
-rw-r--r--Makefile.am7
-rw-r--r--man/networkd.conf.xml81
-rw-r--r--man/systemd.network.xml33
-rw-r--r--src/libsystemd-network/dhcp-identifier.c31
-rw-r--r--src/libsystemd-network/dhcp-identifier.h42
-rw-r--r--src/libsystemd-network/sd-dhcp-client.c181
-rw-r--r--src/libsystemd-network/sd-dhcp6-client.c58
-rw-r--r--src/network/networkd-address-pool.h4
-rw-r--r--src/network/networkd-address.h4
-rw-r--r--src/network/networkd-conf.c88
-rw-r--r--src/network/networkd-conf.h29
-rw-r--r--src/network/networkd-dhcp4.c26
-rw-r--r--src/network/networkd-dhcp6.c18
-rw-r--r--src/network/networkd-fdb.h8
-rw-r--r--src/network/networkd-gperf.gperf4
-rw-r--r--src/network/networkd-ipv4ll.c2
-rw-r--r--src/network/networkd-link.c38
-rw-r--r--src/network/networkd-link.h15
-rw-r--r--src/network/networkd-lldp-tx.c5
-rw-r--r--src/network/networkd-manager.c2
-rw-r--r--src/network/networkd-ndisc.c2
-rw-r--r--src/network/networkd-netdev-bond.c1
-rw-r--r--src/network/networkd-netdev-bond.h8
-rw-r--r--src/network/networkd-netdev-bridge.c1
-rw-r--r--src/network/networkd-netdev-bridge.h7
-rw-r--r--src/network/networkd-netdev-dummy.h7
-rw-r--r--src/network/networkd-netdev-gperf.gperf12
-rw-r--r--src/network/networkd-netdev-ipvlan.h7
-rw-r--r--src/network/networkd-netdev-macvlan.h2
-rw-r--r--src/network/networkd-netdev-tunnel.h17
-rw-r--r--src/network/networkd-netdev-tuntap.c7
-rw-r--r--src/network/networkd-netdev-tuntap.h2
-rw-r--r--src/network/networkd-netdev-veth.h1
-rw-r--r--src/network/networkd-netdev-vlan.h1
-rw-r--r--src/network/networkd-netdev-vxlan.c2
-rw-r--r--src/network/networkd-netdev-vxlan.h1
-rw-r--r--src/network/networkd-netdev.h55
-rw-r--r--src/network/networkd-network-gperf.gperf4
-rw-r--r--src/network/networkd-network.c2
-rw-r--r--src/network/networkd-network.h26
-rw-r--r--src/network/networkd-route.h1
-rw-r--r--src/network/networkd.h35
-rw-r--r--src/network/test-networkd-conf.c89
-rw-r--r--src/systemd/sd-dhcp-client.h78
-rw-r--r--src/systemd/sd-dhcp6-client.h61
46 files changed, 671 insertions, 435 deletions
diff --git a/.gitignore b/.gitignore
index c7eb14452d..c17f79224b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -235,6 +235,7 @@
/test-ndisc-rs
/test-netlink
/test-netlink-manual
+/test-netword-conf
/test-network
/test-network-tables
/test-ns
diff --git a/Makefile.am b/Makefile.am
index a05c7ce4db..cf4e75996d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -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
diff --git a/man/networkd.conf.xml b/man/networkd.conf.xml
index 5166e05cbc..4bfc4f773a 100644
--- a/man/networkd.conf.xml
+++ b/man/networkd.conf.xml
@@ -58,14 +58,14 @@
<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
@@ -73,28 +73,71 @@
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>
diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index 5e287faa6e..3ee80a64a0 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -832,6 +832,7 @@
false.</para>
</listitem>
</varlistentry>
+
<varlistentry>
<term><varname>ClientIdentifier=</varname></term>
<listitem>
@@ -839,6 +840,7 @@
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>
@@ -846,25 +848,25 @@
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>
@@ -876,6 +878,7 @@
networks where broadcasts are filtered out.</para>
</listitem>
</varlistentry>
+
<varlistentry>
<term><varname>RouteMetric=</varname></term>
<listitem>
diff --git a/src/libsystemd-network/dhcp-identifier.c b/src/libsystemd-network/dhcp-identifier.c
index 4f7d4d8bf2..a21efc4d06 100644
--- a/src/libsystemd-network/dhcp-identifier.c
+++ b/src/libsystemd-network/dhcp-identifier.c
@@ -31,6 +31,37 @@
#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;
diff --git a/src/libsystemd-network/dhcp-identifier.h b/src/libsystemd-network/dhcp-identifier.h
index e6486b78f8..1cc0f9fb71 100644
--- a/src/libsystemd-network/dhcp-identifier.h
+++ b/src/libsystemd-network/dhcp-identifier.h
@@ -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;
-}
diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index 287b6e26fa..3846cf7476 100644
--- a/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/libsystemd-network/sd-dhcp-client.c
@@ -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))];
diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c
index ee4fb4fc1e..4adb053a57 100644
--- a/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/libsystemd-network/sd-dhcp6-client.c
@@ -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;
diff --git a/src/network/networkd-address-pool.h b/src/network/networkd-address-pool.h
index 8e1378ff40..af30decfe0 100644
--- a/src/network/networkd-address-pool.h
+++ b/src/network/networkd-address-pool.h
@@ -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;
diff --git a/src/network/networkd-address.h b/src/network/networkd-address.h
index 3c81978fb1..784ab18b27 100644
--- a/src/network/networkd-address.h
+++ b/src/network/networkd-address.h
@@ -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;
diff --git a/src/network/networkd-conf.c b/src/network/networkd-conf.c
index 70f0121d6d..6072c1e2de 100644
--- a/src/network/networkd-conf.c
+++ b/src/network/networkd-conf.c
@@ -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;
}
diff --git a/src/network/networkd-conf.h b/src/network/networkd-conf.h
index 671e656d7b..c7bfb42a72 100644
--- a/src/network/networkd-conf.h
+++ b/src/network/networkd-conf.h
@@ -21,14 +21,29 @@
#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);
diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c
index c5b61abc9e..89926e8a7e 100644
--- a/src/network/networkd-dhcp4.c
+++ b/src/network/networkd-dhcp4.c
@@ -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;
diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c
index d4b2fbfc57..ccca4e9522 100644
--- a/src/network/networkd-dhcp6.c
+++ b/src/network/networkd-dhcp6.c
@@ -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;
diff --git a/src/network/networkd-fdb.h b/src/network/networkd-fdb.h
index 89b3e29405..84410714f5 100644
--- a/src/network/networkd-fdb.h
+++ b/src/network/networkd-fdb.h
@@ -19,10 +19,12 @@
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;
diff --git a/src/network/networkd-gperf.gperf b/src/network/networkd-gperf.gperf
index afc71b4cb8..3fdfe74955 100644
--- a/src/network/networkd-gperf.gperf
+++ b/src/network/networkd-gperf.gperf
@@ -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)
diff --git a/src/network/networkd-ipv4ll.c b/src/network/networkd-ipv4ll.c
index e05fd3eea7..35c9b06473 100644
--- a/src/network/networkd-ipv4ll.c
+++ b/src/network/networkd-ipv4ll.c
@@ -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;
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 5fc513bfda..c646af1f1a 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -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");
}
diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h
index f2a64ca9b5..86139be557 100644
--- a/src/network/networkd-link.h
+++ b/src/network/networkd-link.h
@@ -21,14 +21,17 @@
#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);
diff --git a/src/network/networkd-lldp-tx.c b/src/network/networkd-lldp-tx.c
index 6bde04bc32..03b694c3f1 100644
--- a/src/network/networkd-lldp-tx.c
+++ b/src/network/networkd-lldp-tx.c
@@ -21,15 +21,18 @@
#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 */
diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c
index d355aaa19c..5dcd4df536 100644
--- a/src/network/networkd-manager.c
+++ b/src/network/networkd-manager.c
@@ -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;
diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c
index 4577292e44..b22c58bfe5 100644
--- a/src/network/networkd-ndisc.c
+++ b/src/network/networkd-ndisc.c
@@ -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;
diff --git a/src/network/networkd-netdev-bond.c b/src/network/networkd-netdev-bond.c
index 6b9cbcded6..7913b0088e 100644
--- a/src/network/networkd-netdev-bond.c
+++ b/src/network/networkd-netdev-bond.c
@@ -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"
diff --git a/src/network/networkd-netdev-bond.h b/src/network/networkd-netdev-bond.h
index cb6baea24f..b941edb344 100644
--- a/src/network/networkd-netdev-bond.h
+++ b/src/network/networkd-netdev-bond.h
@@ -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_;
diff --git a/src/network/networkd-netdev-bridge.c b/src/network/networkd-netdev-bridge.c
index 3f91b2eaea..3e44dd7960 100644
--- a/src/network/networkd-netdev-bridge.c
+++ b/src/network/networkd-netdev-bridge.c
@@ -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 */
diff --git a/src/network/networkd-netdev-bridge.h b/src/network/networkd-netdev-bridge.h
index 3f6f1d0502..b921439f02 100644
--- a/src/network/networkd-netdev-bridge.h
+++ b/src/network/networkd-netdev-bridge.h
@@ -19,11 +19,9 @@
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;
diff --git a/src/network/networkd-netdev-dummy.h b/src/network/networkd-netdev-dummy.h
index 42da62ebe4..efe302267e 100644
--- a/src/network/networkd-netdev-dummy.h
+++ b/src/network/networkd-netdev-dummy.h
@@ -19,12 +19,11 @@
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;
diff --git a/src/network/networkd-netdev-gperf.gperf b/src/network/networkd-netdev-gperf.gperf
index 15a787a9e3..1ebd0fdf20 100644
--- a/src/network/networkd-netdev-gperf.gperf
+++ b/src/network/networkd-netdev-gperf.gperf
@@ -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
diff --git a/src/network/networkd-netdev-ipvlan.h b/src/network/networkd-netdev-ipvlan.h
index 4bd0b67866..10d4079844 100644
--- a/src/network/networkd-netdev-ipvlan.h
+++ b/src/network/networkd-netdev-ipvlan.h
@@ -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_;
diff --git a/src/network/networkd-netdev-macvlan.h b/src/network/networkd-netdev-macvlan.h
index 622ef9ef53..3663f4f051 100644
--- a/src/network/networkd-netdev-macvlan.h
+++ b/src/network/networkd-netdev-macvlan.h
@@ -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;
diff --git a/src/network/networkd-netdev-tunnel.h b/src/network/networkd-netdev-tunnel.h
index 0d41f80a3c..7d31e7b687 100644
--- a/src/network/networkd-netdev-tunnel.h
+++ b/src/network/networkd-netdev-tunnel.h
@@ -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;
diff --git a/src/network/networkd-netdev-tuntap.c b/src/network/networkd-netdev-tuntap.c
index 32917fe6d5..088a4d8d32 100644
--- a/src/network/networkd-netdev-tuntap.c
+++ b/src/network/networkd-netdev-tuntap.c
@@ -17,10 +17,13 @@
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"
diff --git a/src/network/networkd-netdev-tuntap.h b/src/network/networkd-netdev-tuntap.h
index cbb7ee05a6..120f00a353 100644
--- a/src/network/networkd-netdev-tuntap.h
+++ b/src/network/networkd-netdev-tuntap.h
@@ -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;
diff --git a/src/network/networkd-netdev-veth.h b/src/network/networkd-netdev-veth.h
index ae5785783c..e69bfbc8f0 100644
--- a/src/network/networkd-netdev-veth.h
+++ b/src/network/networkd-netdev-veth.h
@@ -30,4 +30,5 @@ struct Veth {
struct ether_addr *mac_peer;
};
+DEFINE_NETDEV_CAST(VETH, Veth);
extern const NetDevVTable veth_vtable;
diff --git a/src/network/networkd-netdev-vlan.h b/src/network/networkd-netdev-vlan.h
index 1de6a1cc36..73aacf4a0f 100644
--- a/src/network/networkd-netdev-vlan.h
+++ b/src/network/networkd-netdev-vlan.h
@@ -31,4 +31,5 @@ struct VLan {
uint64_t id;
};
+DEFINE_NETDEV_CAST(VLAN, VLan);
extern const NetDevVTable vlan_vtable;
diff --git a/src/network/networkd-netdev-vxlan.c b/src/network/networkd-netdev-vxlan.c
index dabbd97c87..724f9861be 100644
--- a/src/network/networkd-netdev-vxlan.c
+++ b/src/network/networkd-netdev-vxlan.c
@@ -23,8 +23,10 @@
#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"
diff --git a/src/network/networkd-netdev-vxlan.h b/src/network/networkd-netdev-vxlan.h
index a4bb44635a..4614c66fd1 100644
--- a/src/network/networkd-netdev-vxlan.h
+++ b/src/network/networkd-netdev-vxlan.h
@@ -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,
diff --git a/src/network/networkd-netdev.h b/src/network/networkd-netdev.h
index 7ea825fcb4..20244c0309 100644
--- a/src/network/networkd-netdev.h
+++ b/src/network/networkd-netdev.h
@@ -19,15 +19,13 @@
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);
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index 550b5e5240..51e750b299 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -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)
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 2ebcdfa744..206c270e50 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -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,
diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
index 15417f4828..ff2414efdd 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -19,18 +19,19 @@
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 */
diff --git a/src/network/networkd-route.h b/src/network/networkd-route.h
index 3ddeea96b7..84d74992c9 100644
--- a/src/network/networkd-route.h
+++ b/src/network/networkd-route.h
@@ -22,7 +22,6 @@
typedef struct Route Route;
#include "networkd-network.h"
-#include "networkd.h"
struct Route {
Network *network;
diff --git a/src/network/networkd.h b/src/network/networkd.h
index 72a2438ac8..26d9e7d6e0 100644
--- a/src/network/networkd.h
+++ b/src/network/networkd.h
@@ -24,19 +24,30 @@
#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
index 0000000000..8a62a2a567
--- /dev/null
+++ b/src/network/test-networkd-conf.c
@@ -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;
+}
diff --git a/src/systemd/sd-dhcp-client.h b/src/systemd/sd-dhcp-client.h
index 374ff8774e..20b8c2873f 100644
--- a/src/systemd/sd-dhcp-client.h
+++ b/src/systemd/sd-dhcp-client.h
@@ -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);
diff --git a/src/systemd/sd-dhcp6-client.h b/src/systemd/sd-dhcp6-client.h
index 4604cb6382..90f62eaca4 100644
--- a/src/systemd/sd-dhcp6-client.h
+++ b/src/systemd/sd-dhcp6-client.h
@@ -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);