diff options
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); |