mirror of
https://github.com/systemd/systemd.git
synced 2024-11-28 04:33:36 +08:00
Merge pull request #3156 from keszybz/duid-settings
Rework DUID setting
This commit is contained in:
commit
5119d304ff
1
.gitignore
vendored
1
.gitignore
vendored
@ -235,6 +235,7 @@
|
||||
/test-ndisc-rs
|
||||
/test-netlink
|
||||
/test-netlink-manual
|
||||
/test-netword-conf
|
||||
/test-network
|
||||
/test-network-tables
|
||||
/test-ns
|
||||
|
@ -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
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
||||
<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>
|
||||
<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>
|
||||
|
||||
<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>
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
assert_return(client, -EINVAL);
|
||||
zero(client->client_id);
|
||||
size_t len;
|
||||
|
||||
assert_return(client, -EINVAL);
|
||||
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))];
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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_;
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -1,11 +1,17 @@
|
||||
%{
|
||||
#include <stddef.h>
|
||||
#include "conf-parser.h"
|
||||
#include "networkd-netdev.h"
|
||||
#include "networkd-netdev-tunnel.h"
|
||||
#include "networkd-netdev-bond.h"
|
||||
#include "networkd-netdev-macvlan.h"
|
||||
#include "network-internal.h"
|
||||
#include "networkd-netdev-bond.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"
|
||||
#include "networkd-netdev-bridge.h"
|
||||
#include "networkd-netdev.h"
|
||||
%}
|
||||
struct ConfigPerfItem;
|
||||
%null_strings
|
||||
|
@ -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_;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
|
@ -30,4 +30,5 @@ struct Veth {
|
||||
struct ether_addr *mac_peer;
|
||||
};
|
||||
|
||||
DEFINE_NETDEV_CAST(VETH, Veth);
|
||||
extern const NetDevVTable veth_vtable;
|
||||
|
@ -31,4 +31,5 @@ struct VLan {
|
||||
uint64_t id;
|
||||
};
|
||||
|
||||
DEFINE_NETDEV_CAST(VLAN, VLan);
|
||||
extern const NetDevVTable vlan_vtable;
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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,
|
||||
|
@ -19,15 +19,13 @@
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include "sd-netlink.h"
|
||||
|
||||
#include "list.h"
|
||||
|
||||
typedef struct NetDev NetDev;
|
||||
typedef struct NetDevVTable NetDevVTable;
|
||||
|
||||
#include "networkd-link.h"
|
||||
#include "networkd.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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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 */
|
||||
|
@ -22,7 +22,6 @@
|
||||
typedef struct Route Route;
|
||||
|
||||
#include "networkd-network.h"
|
||||
#include "networkd.h"
|
||||
|
||||
struct Route {
|
||||
Network *network;
|
||||
|
@ -24,19 +24,30 @@
|
||||
#include "sd-bus.h"
|
||||
#include "sd-event.h"
|
||||
#include "sd-netlink.h"
|
||||
|
||||
#include "hashmap.h"
|
||||
#include "list.h"
|
||||
#include "udev.h"
|
||||
|
||||
typedef struct Manager Manager;
|
||||
|
||||
#include "dhcp-identifier.h"
|
||||
#include "hashmap.h"
|
||||
#include "list.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[];
|
||||
|
||||
|
89
src/network/test-networkd-conf.c
Normal file
89
src/network/test-networkd-conf.c
Normal file
@ -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;
|
||||
}
|
@ -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);
|
||||
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);
|
||||
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);
|
||||
|
||||
|
@ -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);
|
||||
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_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_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);
|
||||
|
Loading…
Reference in New Issue
Block a user