/test-ndisc-rs
/test-netlink
/test-netlink-manual
+/test-netword-conf
/test-network
/test-network-tables
/test-ns
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
endif
tests += \
+ test-networkd-conf \
test-network \
test-network-tables
<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>
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>
#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;
#include "unaligned.h"
typedef enum DUIDType {
- DUID_TYPE_RAW = 0,
DUID_TYPE_LLT = 1,
DUID_TYPE_EN = 2,
DUID_TYPE_LL = 3,
*/
#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 {
};
} _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;
-}
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;
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);
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;
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);
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;
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. */
} 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)) {
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);
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);
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;
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;
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);
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;
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);
}
-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);
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);
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);
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;
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);
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;
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;
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 } };
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))];
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;
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);
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;
}
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);
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);
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;
(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;
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;
typedef struct AddressPool AddressPool;
#include "in-addr-util.h"
-#include "networkd.h"
+#include "list.h"
+
+typedef struct Manager Manager;
struct AddressPool {
Manager *manager;
#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;
}
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");
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;
}
}
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;
}
#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);
#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) {
}
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;
#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);
int dhcp6_configure(Link *link) {
sd_dhcp6_client *client = NULL;
int r;
+ const DUID *duid;
assert(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;
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;
%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)
#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;
#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"
}
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),
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),
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");
}
#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,
_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;
Hashmap *bound_by_links;
Hashmap *bound_to_links;
-};
+} Link;
Link *link_unref(Link *link);
Link *link_ref(Link *link);
#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 */
if (r < 0)
return r;
- m->duid_type = _DUID_TYPE_INVALID;
+ m->duid.type = DUID_TYPE_EN;
*ret = m;
m = NULL;
#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;
#include "alloc-util.h"
#include "conf-parser.h"
+#include "extract-word.h"
#include "missing.h"
#include "networkd-netdev-bond.h"
#include "string-table.h"
***/
#include "in-addr-util.h"
-
-typedef struct Bond Bond;
+#include "list.h"
#include "networkd-netdev.h"
LIST_FIELDS(struct ArpIpTarget, arp_ip_target);
} ArpIpTarget;
-struct Bond {
+typedef struct Bond {
NetDev meta;
BondMode mode;
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_;
#include "missing.h"
#include "netlink-util.h"
+#include "networkd.h"
#include "networkd-netdev-bridge.h"
/* callback for brige netdev's parameter set */
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;
usec_t forward_delay;
usec_t hello_time;
usec_t max_age;
-};
+} Bridge;
+DEFINE_NETDEV_CAST(BRIDGE, Bridge);
extern const NetDevVTable bridge_vtable;
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;
%{
#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
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-typedef struct IPVlan IPVlan;
-
#include "missing.h"
#include "networkd-netdev.h"
_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_;
MacVlanMode mode;
};
+DEFINE_NETDEV_CAST(MACVLAN, MacVlan);
+DEFINE_NETDEV_CAST(MACVTAP, MacVlan);
extern const NetDevVTable macvlan_vtable;
extern const NetDevVTable macvtap_vtable;
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-typedef struct Tunnel Tunnel;
+#include "in-addr-util.h"
#include "networkd-netdev.h"
_NETDEV_IPV6_FLOWLABEL_INVALID = -1,
} IPv6FlowLabel;
-struct Tunnel {
+typedef struct Tunnel {
NetDev meta;
uint8_t encap_limit;
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;
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"
bool vnet_hdr;
};
+DEFINE_NETDEV_CAST(TUN, TunTap);
+DEFINE_NETDEV_CAST(TAP, TunTap);
extern const NetDevVTable tun_vtable;
extern const NetDevVTable tap_vtable;
struct ether_addr *mac_peer;
};
+DEFINE_NETDEV_CAST(VETH, Veth);
extern const NetDevVTable veth_vtable;
uint64_t id;
};
+DEFINE_NETDEV_CAST(VLAN, VLan);
extern const NetDevVTable vlan_vtable;
#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"
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,
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;
_NETDEV_CREATE_INVALID = -1,
} NetDevCreateType;
-struct NetDev {
+typedef struct Manager Manager;
+typedef struct Condition Condition;
+
+typedef struct NetDev {
Manager *manager;
int n_ref;
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;
/* 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; \
/* 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);
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)
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,
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
_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;
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 */
typedef struct Route Route;
#include "networkd-network.h"
-#include "networkd.h"
struct Route {
Network *network;
#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;
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[];
--- /dev/null
+/***
+ 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;
+}
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);
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);
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);