1
0
mirror of https://github.com/systemd/systemd synced 2025-10-09 05:34:45 +02:00

Compare commits

...

18 Commits

Author SHA1 Message Date
Zbigniew Jędrzejewski-Szmek
7feb1dd654
Merge pull request #19387 from poettering/discoverable-part-fix
minor doc fixes
2021-04-21 23:10:48 +02:00
Igor Zhbanov
4c54768c97 journald: Retry if posix_fallocate returned -1 (EINTR)
On some conditions (particularly when mobile CPUs are going to sleep),
the posix_fallocate(), which is called when a new journal file is allocated,
can return -1 (EINTR). This is counted as a fatal error. So the journald
closes both old and journals, and simply throwing away further incoming
events, because of no log files open.

Introduce posix_fallocate_loop() that restarts the function in the case
of EINTR. Also let's make code base more uniform by returning negative
values on error.

Fix assert in test-sigbus.c that incorrectly counted positive values as
success. After changing the function return values, that will actually work.

Fixes: #19041

Signed-off-by: Igor Zhbanov <i.zhbanov@omprussia.ru>
2021-04-21 23:08:35 +02:00
Lennart Poettering
eb3c3a89c9 doc: slightly reorder/improve partition type table
Let's put swap and generic linux data partitions next to each other, and
clarify they predated this spec.
2021-04-21 22:25:10 +02:00
Lennart Poettering
1d6ca0a219 doc: verity partitions may only contain Verity data (fix copypasta) 2021-04-21 22:25:08 +02:00
Lennart Poettering
60c6c2101c man: --add was renamed --copy-to when it was merged, fix man page reference to it 2021-04-21 22:24:38 +02:00
Lennart Poettering
6f4a5f25fc
Merge pull request #19271 from yuwata/dhcp-duid-uuid
network: fix issues arround DHCP DUID-UUID
2021-04-21 21:59:35 +02:00
Lennart Poettering
e19479aa7d
Merge pull request #19365 from keszybz/sd_id128_equals
Add sd_id128_in_set()
2021-04-21 21:45:14 +02:00
Lennart Poettering
192b31f28f update TODO 2021-04-21 21:44:02 +02:00
Zbigniew Jędrzejewski-Szmek
da1af43dc1 repart: reword log message
The UUID does not exist, a partion with the UUID exists. So let's
say that the UUID is "already used" for clarity.
2021-04-21 17:51:24 +02:00
Zbigniew Jędrzejewski-Szmek
580f48cc02 partition,shared/gpt: use sd_id128_in_set()
I was worried that the text size will grow, but apparently that's not the
case:
With --optimization=2:
$ size build/src/shared/libsystemd-shared-248.a.p/gpt.c.o*
   text	   data	    bss	    dec	    hex	filename
   3674	   1104	      0	   4778	   12aa	build/src/shared/libsystemd-shared-248.a.p/gpt.c.o.old
   3085	   1104	      0	   4189	   105d	build/src/shared/libsystemd-shared-248.a.p/gpt.c.o

(I don't understand the generated assembly, even though it seems to work:

Disassembly of section .text.gpt_partition_type_is_usr_verity:

0000000000000000 <gpt_partition_type_is_usr_verity>:

bool gpt_partition_type_is_usr_verity(sd_id128_t id) {
   0:   48 83 ec 08             sub    $0x8,%rsp
        return sd_id128_in_set(id,
   4:   4c 8b 05 00 00 00 00    mov    0x0(%rip),%r8        # b <gpt_partition_type_is_usr_verity+0xb>
   b:   31 c0                   xor    %eax,%eax
   d:   4c 8b 0d 00 00 00 00    mov    0x0(%rip),%r9        # 14 <gpt_partition_type_is_usr_verity+0x14>
  14:   48 8b 15 00 00 00 00    mov    0x0(%rip),%rdx        # 1b <gpt_partition_type_is_usr_verity+0x1b>
  1b:   48 8b 0d 00 00 00 00    mov    0x0(%rip),%rcx        # 22 <gpt_partition_type_is_usr_verity+0x22>
  22:   6a 00                   pushq  $0x0
  24:   6a 00                   pushq  $0x0
  26:   ff 35 00 00 00 00       pushq  0x0(%rip)        # 2c <gpt_partition_type_is_usr_verity+0x2c>
  2c:   ff 35 00 00 00 00       pushq  0x0(%rip)        # 32 <gpt_partition_type_is_usr_verity+0x32>
  32:   ff 35 00 00 00 00       pushq  0x0(%rip)        # 38 <gpt_partition_type_is_usr_verity+0x38>
  38:   ff 35 00 00 00 00       pushq  0x0(%rip)        # 3e <gpt_partition_type_is_usr_verity+0x3e>
  3e:   ff 35 00 00 00 00       pushq  0x0(%rip)        # 44 <gpt_partition_type_is_usr_verity+0x44>
  44:   ff 35 00 00 00 00       pushq  0x0(%rip)        # 4a <gpt_partition_type_is_usr_verity+0x4a>
  4a:   ff 35 00 00 00 00       pushq  0x0(%rip)        # 50 <gpt_partition_type_is_usr_verity+0x50>
  50:   ff 35 00 00 00 00       pushq  0x0(%rip)        # 56 <gpt_partition_type_is_usr_verity+0x56>
  56:   ff 35 00 00 00 00       pushq  0x0(%rip)        # 5c <gpt_partition_type_is_usr_verity+0x5c>
  5c:   ff 35 00 00 00 00       pushq  0x0(%rip)        # 62 <gpt_partition_type_is_usr_verity+0x62>
  62:   e8 00 00 00 00          callq  67 <gpt_partition_type_is_usr_verity+0x67>
  67:   85 c0                   test   %eax,%eax
  69:   0f 95 c0                setne  %al
                               GPT_USR_ARM_VERITY,
                               GPT_USR_ARM_64_VERITY,
                               GPT_USR_IA64_VERITY,
                               GPT_USR_RISCV32_VERITY,
                               GPT_USR_RISCV64_VERITY);
}
  6c:   48 83 c4 68             add    $0x68,%rsp
  70:   c3                      retq
)
2021-04-21 17:51:24 +02:00
Zbigniew Jędrzejewski-Szmek
64b21afc72 sd-id128: add convenience functions to compare multiple sd_id128_t
Similar to sd_bus_error_has_names() that was added in
2b07ec316a0e25a3e10c270c7f6baee9e0187bf8.

It is made inline in the hope that the compiler will be able to optimize
all the va_args boilerplate away, and do an efficient comparison when
the arguments are all constants.
2021-04-21 17:51:24 +02:00
Yu Watanabe
28f9667d05 network: dhcp: constify link_get_duid() 2021-04-21 21:00:45 +09:00
Yu Watanabe
8c72f5c077 network: dhcp: introduce duid_needs_product_uuid() helper function 2021-04-21 21:00:45 +09:00
Yu Watanabe
294f129b0d network: configure non-dhcp configs earlier even DUID-UUID is used by DHCP clients
Previously, if DUID-UUID is used, all configurations are configured
after networkd gets product uuid of machine.

This makes only DHCP clients are delayed, and other configs are
configured earlier.
2021-04-21 21:00:45 +09:00
Yu Watanabe
4e26a5baa0 network: make IAID and DUID for DHCPv6 configurable explicitly
Closes #18996.
2021-04-21 21:00:11 +09:00
Yu Watanabe
cde74a65c1 network: move dhcp related conf parsers to networkd-dhcp-common.c 2021-04-21 20:56:58 +09:00
Zbigniew Jędrzejewski-Szmek
78aa5b6f59 man: mention sd_id128_is_allf(), SD_ID128_ALLF
It was added in 670814387ba8973245c08123e7240669f51a55a8, but not
mentioned in the man pages.
2021-04-21 08:45:05 +02:00
Zbigniew Jędrzejewski-Szmek
e0a41aa4c6 man: dedent examples in sd-id128 to 2 columns
In man pages, horizontal space it at premium, and everything should
generally be indented with 2 spaces to make it more likely that the
examples fit on a user's screen.

C.f. 798d3a524ea57aaf40cb53858aaa45ec702f012d.
2021-04-21 08:45:05 +02:00
35 changed files with 717 additions and 417 deletions

11
TODO
View File

@ -225,13 +225,6 @@ Features:
* Add service setting to run a service within the specified VRF. i.e. do the * Add service setting to run a service within the specified VRF. i.e. do the
equivalent of "ip vrf exec". equivalent of "ip vrf exec".
* Add root=gpt-auto-late support or so, that is like root=gpt-auto but
initially mounts a tmpfs to /sysroot, and then revisits later after
systemd-repart ran. Usecase: let's ship images with only /usr partition, then
on first boot create the root partition. In this case we want to read the
repart data from /usr before the root partition exists. Add usr=gpt-auto that
automatically finds a /usr partition.
* change SwitchRoot() implementation in PID 1 to use pivot_root(".", "."), as * change SwitchRoot() implementation in PID 1 to use pivot_root(".", "."), as
documented in the pivot_root(2) man page, so that we can drop the /oldroot documented in the pivot_root(2) man page, so that we can drop the /oldroot
temporary dir. temporary dir.
@ -837,10 +830,6 @@ Features:
"systemd-gdb" for attaching to the start-up of any system service in its "systemd-gdb" for attaching to the start-up of any system service in its
natural habitat. natural habitat.
* gpt-auto logic: related to the above, maybe support a "secondary" root
partition, that is mounted to / and is writable, and where the actual root's
/usr is mounted into.
* gpt-auto logic: support encrypted swap, add kernel cmdline option to force it, and honour a gpt bit about it, plus maybe a configuration file * gpt-auto logic: support encrypted swap, add kernel cmdline option to force it, and honour a gpt bit about it, plus maybe a configuration file
* drop nss-myhostname in favour of nss-resolve? * drop nss-myhostname in favour of nss-resolve?

View File

@ -62,7 +62,7 @@ Interface](https://systemd.io/BOOT_LOADER_INTERFACE).
| `4301d2a6-4e3b-4b2a-bb94-9e0b2c4225ea` | _`/usr/` Partition (Itanium/IA-64)_ | ditto | ditto | | `4301d2a6-4e3b-4b2a-bb94-9e0b2c4225ea` | _`/usr/` Partition (Itanium/IA-64)_ | ditto | ditto |
| `b933fb22-5c3f-4f91-af90-e2bb0fa50702` | _`/usr/` Partition (RISC-V 32-bit)_ | ditto | ditto | | `b933fb22-5c3f-4f91-af90-e2bb0fa50702` | _`/usr/` Partition (RISC-V 32-bit)_ | ditto | ditto |
| `beaec34b-8442-439b-a40b-984381ed097d` | _`/usr/` Partition (RISC-V 64-bit)_ | ditto | ditto | | `beaec34b-8442-439b-a40b-984381ed097d` | _`/usr/` Partition (RISC-V 64-bit)_ | ditto | ditto |
| `8f461b0d-14ee-4e81-9aa9-049b6fb97abd` | _`/usr/` Verity Partition (x86)_ | Any native, optionally in LUKS | Similar semantics to root Verity partition, but just for the `/usr/` partition. | | `8f461b0d-14ee-4e81-9aa9-049b6fb97abd` | _`/usr/` Verity Partition (x86)_ | A dm-verity superblock followed by hash data | Similar semantics to root Verity partition, but just for the `/usr/` partition. |
| `77ff5f63-e7b6-4633-acf4-1565b864c0e6` | _`/usr/` Verity Partition (x86-64)_ | ditto | ditto | | `77ff5f63-e7b6-4633-acf4-1565b864c0e6` | _`/usr/` Verity Partition (x86-64)_ | ditto | ditto |
| `c215d751-7bcd-4649-be90-6627490a4c05` | _`/usr/` Verity Partition (32-bit ARM)_ | ditto | ditto | | `c215d751-7bcd-4649-be90-6627490a4c05` | _`/usr/` Verity Partition (32-bit ARM)_ | ditto | ditto |
| `6e11a4e7-fbca-4ded-b9e9-e1a512bb664e` | _`/usr/` Verity Partition (64-bit ARM/AArch64)_ | ditto | ditto | | `6e11a4e7-fbca-4ded-b9e9-e1a512bb664e` | _`/usr/` Verity Partition (64-bit ARM/AArch64)_ | ditto | ditto |
@ -73,10 +73,10 @@ Interface](https://systemd.io/BOOT_LOADER_INTERFACE).
| `3b8f8425-20e0-4f3b-907f-1a25a76f98e8` | _Server Data Partition_ | Any native, optionally in LUKS | The first partition with this type UUID on the disk containing the root partition is automatically mounted to `/srv/`. If the partition is encrypted with LUKS, the device mapper file will be named `/dev/mapper/srv`. | | `3b8f8425-20e0-4f3b-907f-1a25a76f98e8` | _Server Data Partition_ | Any native, optionally in LUKS | The first partition with this type UUID on the disk containing the root partition is automatically mounted to `/srv/`. If the partition is encrypted with LUKS, the device mapper file will be named `/dev/mapper/srv`. |
| `4d21b016-b534-45c2-a9fb-5c16e091fd2d` | _Variable Data Partition_ | Any native, optionally in LUKS | The first partition with this type UUID on the disk containing the root partition is automatically mounted to `/var/` — under the condition that its partition UUID matches the first 128 bit of `HMAC-SHA256(machine-id, 0x4d21b016b53445c2a9fb5c16e091fd2d)` (i.e. the SHA256 HMAC hash of the binary type UUID keyed by the machine ID as read from [`/etc/machine-id`](https://www.freedesktop.org/software/systemd/man/machine-id.html). This special requirement is made because `/var/` (unlike the other partition types listed here) is inherently private to a specific installation and cannot possibly be shared between multiple OS installations on the same disk, and thus should be bound to a specific instance of the OS, identified by its machine ID. If the partition is encrypted with LUKS, the device mapper file will be named `/dev/mapper/var`. | | `4d21b016-b534-45c2-a9fb-5c16e091fd2d` | _Variable Data Partition_ | Any native, optionally in LUKS | The first partition with this type UUID on the disk containing the root partition is automatically mounted to `/var/` — under the condition that its partition UUID matches the first 128 bit of `HMAC-SHA256(machine-id, 0x4d21b016b53445c2a9fb5c16e091fd2d)` (i.e. the SHA256 HMAC hash of the binary type UUID keyed by the machine ID as read from [`/etc/machine-id`](https://www.freedesktop.org/software/systemd/man/machine-id.html). This special requirement is made because `/var/` (unlike the other partition types listed here) is inherently private to a specific installation and cannot possibly be shared between multiple OS installations on the same disk, and thus should be bound to a specific instance of the OS, identified by its machine ID. If the partition is encrypted with LUKS, the device mapper file will be named `/dev/mapper/var`. |
| `7ec6f557-3bc5-4aca-b293-16ef5df639d1` | _Temporary Data Partition_ | Any native, optionally in LUKS | The first partition with this type UUID on the disk containing the root partition is automatically mounted to `/var/tmp/`. If the partition is encrypted with LUKS, the device mapper file will be named `/dev/mapper/tmp`. Note that the intended mount point is indeed `/var/tmp/`, not `/tmp/`. The latter is typically maintained in memory via <tt>tmpfs</tt> and does not require a partition on disk. In some cases it might be desirable to make `/tmp/` persistent too, in which case it is recommended to make it a symlink or bind mount to `/var/tmp/`, thus not requiring its own partition type UUID. | | `7ec6f557-3bc5-4aca-b293-16ef5df639d1` | _Temporary Data Partition_ | Any native, optionally in LUKS | The first partition with this type UUID on the disk containing the root partition is automatically mounted to `/var/tmp/`. If the partition is encrypted with LUKS, the device mapper file will be named `/dev/mapper/tmp`. Note that the intended mount point is indeed `/var/tmp/`, not `/tmp/`. The latter is typically maintained in memory via <tt>tmpfs</tt> and does not require a partition on disk. In some cases it might be desirable to make `/tmp/` persistent too, in which case it is recommended to make it a symlink or bind mount to `/var/tmp/`, thus not requiring its own partition type UUID. |
| `0657fd6d-a4ab-43c4-84e5-0933c84b4f4f` | _Swap_ | Swap | All swap partitions on the disk containing the root partition are automatically enabled. | | `0657fd6d-a4ab-43c4-84e5-0933c84b4f4f` | _Swap_ | Swap | All swap partitions on the disk containing the root partition are automatically enabled. This partition type predates the Discoverable Partitions Specification. |
| `0fc63daf-8483-4772-8e79-3d69d8477de4` | _Generic Linux Data Partitions_ | Any native, optionally in LUKS | No automatic mounting takes place for other Linux data partitions. This partition type should be used for all partitions that carry Linux file systems. The installer needs to mount them explicitly via entries in <tt>/etc/fstab</tt>. Optionally, these partitions may be encrypted with LUKS. This partition type predates the Discoverable Partitions Specification. |
| `c12a7328-f81f-11d2-ba4b-00a0c93ec93b` | _EFI System Partition_ | VFAT | The ESP used for the current boot is automatically mounted to `/efi/` (or `/boot/` as fallback), unless a different partition is mounted there (possibly via `/etc/fstab`, or because the Extended Boot Loader Partition — see below — exists) or the directory is non-empty on the root disk. This partition type is defined by the [UEFI Specification](http://www.uefi.org/specifications). | | `c12a7328-f81f-11d2-ba4b-00a0c93ec93b` | _EFI System Partition_ | VFAT | The ESP used for the current boot is automatically mounted to `/efi/` (or `/boot/` as fallback), unless a different partition is mounted there (possibly via `/etc/fstab`, or because the Extended Boot Loader Partition — see below — exists) or the directory is non-empty on the root disk. This partition type is defined by the [UEFI Specification](http://www.uefi.org/specifications). |
| `bc13c2ff-59e6-4262-a352-b275fd6f7172` | _Extended Boot Loader Partition_ | Typically VFAT | The Extended Boot Loader Partition (XBOOTLDR) used for the current boot is automatically mounted to <tt>/boot/</tt>, unless a different partition is mounted there (possibly via <tt>/etc/fstab</tt>) or the directory is non-empty on the root disk. This partition type is defined by the [Boot Loader Specification](https://systemd.io/BOOT_LOADER_SPECIFICATION). | | `bc13c2ff-59e6-4262-a352-b275fd6f7172` | _Extended Boot Loader Partition_ | Typically VFAT | The Extended Boot Loader Partition (XBOOTLDR) used for the current boot is automatically mounted to <tt>/boot/</tt>, unless a different partition is mounted there (possibly via <tt>/etc/fstab</tt>) or the directory is non-empty on the root disk. This partition type is defined by the [Boot Loader Specification](https://systemd.io/BOOT_LOADER_SPECIFICATION). |
| `0fc63daf-8483-4772-8e79-3d69d8477de4` | _Other Data Partitions_ | Any native, optionally in LUKS | No automatic mounting takes place for other Linux data partitions. This partition type should be used for all partitions that carry Linux file systems. The installer needs to mount them explicitly via entries in <tt>/etc/fstab</tt>. Optionally, these partitions may be encrypted with LUKS. |
Other GPT type IDs might be used on Linux, for example to mark software RAID or Other GPT type IDs might be used on Linux, for example to mark software RAID or
LVM partitions. The definitions of those GPT types is outside of the scope of LVM partitions. The definitions of those GPT types is outside of the scope of

View File

@ -98,15 +98,12 @@
</refsect1> </refsect1>
<refsect1> <refsect1>
<title>[DHCP] Section Options</title> <title>[DHCPv4] Section Options</title>
<para>This section configures the DHCP Unique Identifier (DUID) value used by DHCP <para>This section configures the DHCP Unique Identifier (DUID) value used by DHCP protocol. DHCPv4
protocol. DHCPv6 client protocol sends the DHCP Unique Identifier and the interface client protocol sends IAID and DUID to the DHCP server when acquiring a dynamic IPv4 address if
Identity Association Identifier (IAID) to a DHCP server when acquiring a dynamic IPv6 <option>ClientIdentifier=duid</option>. IAID and DUID allows a DHCP server to uniquely identify the
address. DHCPv4 client protocol sends IAID and DUID to the DHCP server when acquiring machine and the interface requesting a DHCP IP address. To configure IAID and ClientIdentifier, see
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>. <citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
</para> </para>
@ -188,6 +185,28 @@ DUIDRawData=00:00:ab:11:f9:2a:c2:77:29:f9:5c:00</programlisting>
</variablelist> </variablelist>
</refsect1> </refsect1>
<refsect1>
<title>[DHCPv6] Section Options</title>
<para>This section configures the DHCP Unique Identifier (DUID) value used by DHCPv6 protocol.
DHCPv6 client protocol sends the DHCP Unique Identifier and the interface Identity Association
Identifier (IAID) to a DHCPv6 server when acquiring a dynamic IPv6 address. IAID and DUID allows a
DHCPv6 server to uniquely identify the machine and the interface requesting a DHCP IP address. To
configure IAID, see
<citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
</para>
<para>The following options are understood:</para>
<variablelist class='network-directives'>
<varlistentry>
<term><varname>DUIDType=</varname></term>
<term><varname>DUIDRawData=</varname></term>
<listitem><para>As in the [DHCPv4] section.</para></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1> <refsect1>
<title>See Also</title> <title>See Also</title>
<para> <para>

View File

@ -119,7 +119,8 @@ manpages = [
['sd-hwdb', '3', [], ''], ['sd-hwdb', '3', [], ''],
['sd-id128', ['sd-id128',
'3', '3',
['SD_ID128_CONST_STR', ['SD_ID128_ALLF',
'SD_ID128_CONST_STR',
'SD_ID128_FORMAT_STR', 'SD_ID128_FORMAT_STR',
'SD_ID128_FORMAT_VAL', 'SD_ID128_FORMAT_VAL',
'SD_ID128_MAKE', 'SD_ID128_MAKE',
@ -127,6 +128,10 @@ manpages = [
'SD_ID128_NULL', 'SD_ID128_NULL',
'SD_ID128_UUID_FORMAT_STR', 'SD_ID128_UUID_FORMAT_STR',
'sd_id128_equal', 'sd_id128_equal',
'sd_id128_in_set',
'sd_id128_in_set_sentinel',
'sd_id128_in_setv',
'sd_id128_is_allf',
'sd_id128_is_null', 'sd_id128_is_null',
'sd_id128_t'], 'sd_id128_t'],
''], ''],

View File

@ -18,16 +18,21 @@
<refnamediv> <refnamediv>
<refname>sd-id128</refname> <refname>sd-id128</refname>
<refname>sd_id128_t</refname> <refname>SD_ID128_ALLF</refname>
<refname>SD_ID128_CONST_STR</refname>
<refname>SD_ID128_FORMAT_STR</refname>
<refname>SD_ID128_FORMAT_VAL</refname>
<refname>SD_ID128_MAKE</refname> <refname>SD_ID128_MAKE</refname>
<refname>SD_ID128_MAKE_STR</refname> <refname>SD_ID128_MAKE_STR</refname>
<refname>SD_ID128_NULL</refname> <refname>SD_ID128_NULL</refname>
<refname>SD_ID128_CONST_STR</refname>
<refname>SD_ID128_FORMAT_STR</refname>
<refname>SD_ID128_UUID_FORMAT_STR</refname> <refname>SD_ID128_UUID_FORMAT_STR</refname>
<refname>SD_ID128_FORMAT_VAL</refname>
<refname>sd_id128_equal</refname> <refname>sd_id128_equal</refname>
<refname>sd_id128_in_set</refname>
<refname>sd_id128_in_set_sentinel</refname>
<refname>sd_id128_in_setv</refname>
<refname>sd_id128_is_allf</refname>
<refname>sd_id128_is_null</refname> <refname>sd_id128_is_null</refname>
<refname>sd_id128_t</refname>
<refpurpose>APIs for processing 128-bit IDs</refpurpose> <refpurpose>APIs for processing 128-bit IDs</refpurpose>
</refnamediv> </refnamediv>
@ -65,8 +70,8 @@
union type:</para> union type:</para>
<programlisting>typedef union sd_id128 { <programlisting>typedef union sd_id128 {
uint8_t bytes[16]; uint8_t bytes[16];
uint64_t qwords[2]; uint64_t qwords[2];
} sd_id128_t;</programlisting> } sd_id128_t;</programlisting>
<para>This union type allows accessing the 128-bit ID as 16 <para>This union type allows accessing the 128-bit ID as 16
@ -85,7 +90,7 @@
<programlisting>#define SD_MESSAGE_COREDUMP SD_ID128_MAKE(fc,2e,22,bc,6e,e6,47,b6,b9,07,29,ab,34,a2,50,b1)</programlisting> <programlisting>#define SD_MESSAGE_COREDUMP SD_ID128_MAKE(fc,2e,22,bc,6e,e6,47,b6,b9,07,29,ab,34,a2,50,b1)</programlisting>
<para><constant>SD_ID128_NULL</constant> may be used to refer to the 128bit ID consisting of only <para><constant>SD_ID128_NULL</constant> may be used to refer to the 128-bit ID consisting of only
<constant>NUL</constant> bytes.</para> <constant>NUL</constant> bytes.</para>
<para><function>SD_ID128_MAKE_STR()</function> is similar to <function>SD_ID128_MAKE()</function>, but creates a <para><function>SD_ID128_MAKE_STR()</function> is similar to <function>SD_ID128_MAKE()</function>, but creates a
@ -95,7 +100,7 @@
#define SD_MESSAGE_COREDUMP_STR SD_ID128_MAKE_STR(fc,2e,22,bc,6e,e6,47,b6,b9,07,29,ab,34,a2,50,b1) #define SD_MESSAGE_COREDUMP_STR SD_ID128_MAKE_STR(fc,2e,22,bc,6e,e6,47,b6,b9,07,29,ab,34,a2,50,b1)
int main(int argc, char **argv) { int main(int argc, char **argv) {
puts("Match for coredumps: MESSAGE_ID=" SD_MESSAGE_COREDUMP_STR); puts("Match for coredumps: MESSAGE_ID=" SD_MESSAGE_COREDUMP_STR);
} }
</programlisting> </programlisting>
@ -104,7 +109,7 @@ int main(int argc, char **argv) {
following example code will output the string following example code will output the string
"fc2e22bc6ee647b6b90729ab34a250b1":</para> "fc2e22bc6ee647b6b90729ab34a250b1":</para>
<programlisting>int main(int argc, char *argv[]) { <programlisting>int main(int argc, char *argv[]) {
puts("Match for coredumps: %s", SD_ID128_CONST_STR(SD_MESSAGE_COREDUMP)); puts("Match for coredumps: %s", SD_ID128_CONST_STR(SD_MESSAGE_COREDUMP));
}</programlisting> }</programlisting>
<para><constant>SD_ID128_FORMAT_STR</constant> and <function>SD_ID128_FORMAT_VAL()</function> may <para><constant>SD_ID128_FORMAT_STR</constant> and <function>SD_ID128_FORMAT_VAL()</function> may
@ -113,10 +118,10 @@ int main(int argc, char **argv) {
format string, as shown in the following example:</para> format string, as shown in the following example:</para>
<programlisting>int main(int argc, char *argv[]) { <programlisting>int main(int argc, char *argv[]) {
sd_id128_t id; sd_id128_t id;
id = SD_ID128_MAKE(ee,89,be,71,bd,6e,43,d6,91,e6,c5,5d,eb,03,02,07); id = SD_ID128_MAKE(ee,89,be,71,bd,6e,43,d6,91,e6,c5,5d,eb,03,02,07);
printf("The ID encoded in this C file is " SD_ID128_FORMAT_STR ".\n", SD_ID128_FORMAT_VAL(id)); printf("The ID encoded in this C file is " SD_ID128_FORMAT_STR ".\n", SD_ID128_FORMAT_VAL(id));
return 0; return 0;
}</programlisting> }</programlisting>
<para><constant>SD_ID128_UUID_FORMAT_STR</constant> is similar to <para><constant>SD_ID128_UUID_FORMAT_STR</constant> is similar to
@ -127,21 +132,50 @@ int main(int argc, char **argv) {
<para>Use <function>sd_id128_equal()</function> to compare two 128-bit IDs:</para> <para>Use <function>sd_id128_equal()</function> to compare two 128-bit IDs:</para>
<programlisting>int main(int argc, char *argv[]) { <programlisting>int main(int argc, char *argv[]) {
sd_id128_t a, b, c; sd_id128_t a, b, c;
a = SD_ID128_MAKE(ee,89,be,71,bd,6e,43,d6,91,e6,c5,5d,eb,03,02,07); a = SD_ID128_MAKE(ee,89,be,71,bd,6e,43,d6,91,e6,c5,5d,eb,03,02,07);
b = SD_ID128_MAKE(f2,28,88,9c,5f,09,44,15,9d,d7,04,77,58,cb,e7,3e); b = SD_ID128_MAKE(f2,28,88,9c,5f,09,44,15,9d,d7,04,77,58,cb,e7,3e);
c = a; c = a;
assert(sd_id128_equal(a, c)); assert(sd_id128_equal(a, c));
assert(!sd_id128_equal(a, b)); assert(!sd_id128_equal(a, b));
return 0; return 0;
}</programlisting> }</programlisting>
<para>Use <function>sd_id128_is_null()</function> to check if an 128bit ID consists of only <para>Use <function>sd_id128_is_null()</function> to check if an 128-bit ID consists of only
<constant>NUL</constant> bytes:</para> <constant>NUL</constant> bytes:</para>
<programlisting>assert(sd_id128_is_null(SD_ID128_NULL));</programlisting>
<para>Similarly, use <function>sd_id128_is_allf()</function> to check if an 128-bit ID consists of only
<constant>0xFF</constant> bytes (all bits on):</para>
<programlisting>assert(sd_id128_is_allf(SD_ID128_ALLF));</programlisting>
<para>For convenience, <function>sd_id128_in_set()</function> takes a list of IDs and
returns true if any are equal to the first argument:</para>
<programlisting>int main(int argc, char *argv[]) { <programlisting>int main(int argc, char *argv[]) {
assert(sd_id128_is_null(SD_ID128_NULL)); sd_id12_t a = SD_ID128_MAKE(ee,89,be,71,bd,6e,43,d6,91,e6,c5,5d,eb,03,02,07);
}</programlisting> assert(sd_id128_in_set(a, a));
assert(sd_id128_in_set(a, a, a));
assert(!sd_id128_in_set(a));
assert(!sd_id128_in_set(a,
SD_ID128_MAKE(f2,28,88,9c,5f,09,44,15,9d,d7,04,77,58,cb,e7,3e)
SD_ID128_MAKE(2f,88,28,5f,9c,44,09,9d,d7,15,77,04,bc,85,7e,e3)
SD_ID128_ALLF));
return 0;
}
</programlisting>
<para><function>sd_id128_in_set()</function> is defined as a macro over
<function>sd_id128_in_set_sentinel()</function>, adding the <constant>SD_ID128_NULL</constant>
sentinel. Since <function>sd_id128_in_set_sentinel()</function> uses <constant>SD_ID128_NULL</constant>
as the sentinel, <constant>SD_ID128_NULL</constant> cannot be otherwise placed in the argument list.
</para>
<para><function>sd_id128_in_setv()</function> is similar to
<function>sd_id128_in_set_sentinel()</function>, but takes a <structname>struct varargs</structname>
argument.</para>
<para>Note that new, randomized IDs may be generated with <para>Note that new, randomized IDs may be generated with
<citerefentry><refentrytitle>systemd-id128</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s <citerefentry><refentrytitle>systemd-id128</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s

View File

@ -187,8 +187,8 @@
<term><option>--fsck=no</option></term> <term><option>--fsck=no</option></term>
<listitem><para>Turn off automatic file system checking. By default when an image is accessed for <listitem><para>Turn off automatic file system checking. By default when an image is accessed for
writing (by <option>--mount</option> or <option>--add</option>) the file systems contained in the OS writing (by <option>--mount</option> or <option>--copy-to</option>) the file systems contained in the
image are automatically checked using the appropriate <citerefentry OS image are automatically checked using the appropriate <citerefentry
project='man-pages'><refentrytitle>fsck</refentrytitle><manvolnum>8</manvolnum></citerefentry> project='man-pages'><refentrytitle>fsck</refentrytitle><manvolnum>8</manvolnum></citerefentry>
command, in automatic fixing mode. This behavior may be switched off using command, in automatic fixing mode. This behavior may be switched off using
<option>--fsck=no</option>.</para></listitem> <option>--fsck=no</option>.</para></listitem>

View File

@ -1983,6 +1983,9 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
<term><varname>UseNTP=</varname></term> <term><varname>UseNTP=</varname></term>
<term><varname>UseHostname=</varname></term> <term><varname>UseHostname=</varname></term>
<term><varname>UseDomains=</varname></term> <term><varname>UseDomains=</varname></term>
<term><varname>IAID=</varname></term>
<term><varname>DUIDType=</varname></term>
<term><varname>DUIDRawData=</varname></term>
<listitem> <listitem>
<para>As in the [DHCPv4] section.</para> <para>As in the [DHCPv4] section.</para>
</listitem> </listitem>

View File

@ -24,6 +24,7 @@
#include "path-util.h" #include "path-util.h"
#include "process-util.h" #include "process-util.h"
#include "random-util.h" #include "random-util.h"
#include "ratelimit.h"
#include "stat-util.h" #include "stat-util.h"
#include "stdio-util.h" #include "stdio-util.h"
#include "string-util.h" #include "string-util.h"
@ -1715,3 +1716,23 @@ do_rename:
return 1; return 1;
} }
int posix_fallocate_loop(int fd, uint64_t offset, uint64_t size) {
RateLimit rl;
int r;
r = posix_fallocate(fd, offset, size); /* returns positive errnos on error */
if (r != EINTR)
return -r; /* Let's return negative errnos, like common in our codebase */
/* On EINTR try a couple of times more, but protect against busy looping
* (not more than 16 times per 10s) */
rl = (RateLimit) { 10 * USEC_PER_SEC, 16 };
while (ratelimit_below(&rl)) {
r = posix_fallocate(fd, offset, size);
if (r != EINTR)
return -r;
}
return -EINTR;
}

View File

@ -146,3 +146,5 @@ int conservative_renameat(int olddirfd, const char *oldpath, int newdirfd, const
static inline int conservative_rename(const char *oldpath, const char *newpath) { static inline int conservative_rename(const char *oldpath, const char *newpath) {
return conservative_renameat(AT_FDCWD, oldpath, AT_FDCWD, newpath); return conservative_renameat(AT_FDCWD, oldpath, AT_FDCWD, newpath);
} }
int posix_fallocate_loop(int fd, uint64_t offset, uint64_t size);

View File

@ -14,6 +14,7 @@
#include "escape.h" #include "escape.h"
#include "fd-util.h" #include "fd-util.h"
#include "format-util.h" #include "format-util.h"
#include "fs-util.h"
#include "io-util.h" #include "io-util.h"
#include "journald-kmsg.h" #include "journald-kmsg.h"
#include "journald-server.h" #include "journald-server.h"
@ -436,8 +437,8 @@ int server_open_kernel_seqnum(Server *s) {
return 0; return 0;
} }
r = posix_fallocate(fd, 0, sizeof(uint64_t)); r = posix_fallocate_loop(fd, 0, sizeof(uint64_t));
if (r != 0) { if (r < 0) {
log_error_errno(r, "Failed to allocate sequential number file, ignoring: %m"); log_error_errno(r, "Failed to allocate sequential number file, ignoring: %m");
return 0; return 0;
} }

View File

@ -707,9 +707,9 @@ static int journal_file_allocate(JournalFile *f, uint64_t offset, uint64_t size)
/* Note that the glibc fallocate() fallback is very /* Note that the glibc fallocate() fallback is very
inefficient, hence we try to minimize the allocation area inefficient, hence we try to minimize the allocation area
as we can. */ as we can. */
r = posix_fallocate(f->fd, old_size, new_size - old_size); r = posix_fallocate_loop(f->fd, old_size, new_size - old_size);
if (r != 0) if (r < 0)
return -r; return r;
f->header->arena_size = htole64(new_size - old_header_size); f->header->arena_size = htole64(new_size - old_header_size);

View File

@ -3,20 +3,11 @@
Copyright © 2014 Vinay Kulkarni <kulkarniv@vmware.com> Copyright © 2014 Vinay Kulkarni <kulkarniv@vmware.com>
***/ ***/
#include <ctype.h>
#include <netinet/ip.h>
#include "conf-parser.h" #include "conf-parser.h"
#include "def.h" #include "def.h"
#include "dhcp-identifier.h"
#include "extract-word.h"
#include "hexdecoct.h"
#include "networkd-conf.h" #include "networkd-conf.h"
#include "networkd-manager.h" #include "networkd-manager.h"
#include "networkd-network.h"
#include "networkd-speed-meter.h" #include "networkd-speed-meter.h"
#include "networkd-dhcp4.h"
#include "string-table.h"
int manager_parse_config_file(Manager *m) { int manager_parse_config_file(Manager *m) {
int r; int r;
@ -45,147 +36,3 @@ int manager_parse_config_file(Manager *m) {
return 0; return 0;
} }
static const char* const duid_type_table[_DUID_TYPE_MAX] = {
[DUID_TYPE_LLT] = "link-layer-time",
[DUID_TYPE_EN] = "vendor",
[DUID_TYPE_LL] = "link-layer",
[DUID_TYPE_UUID] = "uuid",
};
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(duid_type, DUIDType);
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) {
_cleanup_free_ char *type_string = NULL;
const char *p = rvalue;
DUID *duid = data;
DUIDType type;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(duid);
r = extract_first_word(&p, &type_string, ":", 0);
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Invalid syntax, ignoring: %s", rvalue);
return 0;
}
if (r == 0) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Failed to extract DUID type from '%s', ignoring.", rvalue);
return 0;
}
type = duid_type_from_string(type_string);
if (type < 0) {
log_syntax(unit, LOG_WARNING, filename, line, type,
"Failed to parse DUID type '%s', ignoring.", type_string);
return 0;
}
if (!isempty(p)) {
usec_t u;
if (type != DUID_TYPE_LLT) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Invalid syntax, ignoring: %s", rvalue);
return 0;
}
r = parse_timestamp(p, &u);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse timestamp, ignoring: %s", p);
return 0;
}
duid->llt_time = u;
}
duid->type = type;
return 0;
}
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) {
DUID *ret = data;
uint8_t raw_data[MAX_DUID_LEN];
unsigned count = 0;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(ret);
/* RawData contains DUID in format "NN:NN:NN..." */
for (const char *p = rvalue;;) {
int n1, n2, len, r;
uint32_t byte;
_cleanup_free_ char *cbyte = NULL;
r = extract_first_word(&p, &cbyte, ":", 0);
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to read DUID, ignoring assignment: %s.", rvalue);
return 0;
}
if (r == 0)
break;
if (count >= MAX_DUID_LEN) {
log_syntax(unit, LOG_WARNING, filename, line, 0, "Max DUID length exceeded, ignoring assignment: %s.", rvalue);
return 0;
}
len = strlen(cbyte);
if (!IN_SET(len, 1, 2)) {
log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid length - DUID byte: %s, ignoring assignment: %s.", cbyte, rvalue);
return 0;
}
n1 = unhexchar(cbyte[0]);
if (len == 2)
n2 = unhexchar(cbyte[1]);
else
n2 = 0;
if (n1 < 0 || n2 < 0) {
log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid DUID byte: %s. Ignoring assignment: %s.", cbyte, rvalue);
return 0;
}
byte = ((uint8_t) n1 << (4 * (len-1))) | (uint8_t) n2;
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;
}

View File

@ -12,6 +12,3 @@ typedef struct Manager Manager;
int manager_parse_config_file(Manager *m); int manager_parse_config_file(Manager *m);
const struct ConfigPerfItem* networkd_gperf_lookup(const char *key, GPERF_LEN_TYPE length); const struct ConfigPerfItem* networkd_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
CONFIG_PARSER_PROTOTYPE(config_parse_duid_type);
CONFIG_PARSER_PROTOTYPE(config_parse_duid_rawdata);

View File

@ -4,9 +4,11 @@
#include <linux/if_arp.h> #include <linux/if_arp.h>
#include "bus-error.h" #include "bus-error.h"
#include "dhcp-identifier.h"
#include "dhcp-internal.h" #include "dhcp-internal.h"
#include "dhcp6-internal.h" #include "dhcp6-internal.h"
#include "escape.h" #include "escape.h"
#include "hexdecoct.h"
#include "in-addr-util.h" #include "in-addr-util.h"
#include "networkd-dhcp-common.h" #include "networkd-dhcp-common.h"
#include "networkd-link.h" #include "networkd-link.h"
@ -61,31 +63,75 @@ void network_adjust_dhcp(Network *network) {
network_adjust_dhcp4(network); network_adjust_dhcp4(network);
} }
static struct DUID fallback_duid = { .type = DUID_TYPE_EN }; static bool duid_needs_product_uuid(const DUID *duid) {
DUID* link_get_duid(Link *link) { assert(duid);
if (link->network->duid.type != _DUID_TYPE_INVALID)
return &link->network->duid; return duid->type == DUID_TYPE_UUID && duid->raw_data_len == 0;
else if (link->hw_addr.length == 0 && IN_SET(link->manager->duid.type, DUID_TYPE_LLT, DUID_TYPE_LL)) }
static const struct DUID fallback_duid = { .type = DUID_TYPE_EN };
const DUID *link_get_duid(Link *link, int family) {
const DUID *duid;
assert(link);
assert(IN_SET(family, AF_INET, AF_INET6));
if (link->network) {
duid = family == AF_INET ? &link->network->dhcp_duid : &link->network->dhcp6_duid;
if (duid->type != _DUID_TYPE_INVALID) {
if (duid_needs_product_uuid(duid))
return &link->manager->duid_product_uuid;
else
return duid;
}
}
duid = family == AF_INET ? &link->manager->dhcp_duid : &link->manager->dhcp6_duid;
if (link->hw_addr.length == 0 && IN_SET(duid->type, DUID_TYPE_LLT, DUID_TYPE_LL))
/* Fallback to DUID that works without MAC address. /* Fallback to DUID that works without MAC address.
* This is useful for tunnel devices without MAC address. */ * This is useful for tunnel devices without MAC address. */
return &fallback_duid; return &fallback_duid;
else
return &link->manager->duid; return duid;
} }
static int duid_set_uuid(DUID *duid, sd_id128_t uuid) { static int link_configure_and_start_dhcp_delayed(Link *link) {
assert(duid); int r;
if (duid->raw_data_len > 0) assert(link);
if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
return 0; return 0;
if (duid->type != DUID_TYPE_UUID) if (!link->dhcp_client) {
return -EINVAL; r = dhcp4_configure(link);
if (r < 0)
return r;
}
memcpy(&duid->raw_data, &uuid, sizeof(sd_id128_t)); if (!link->dhcp6_client) {
duid->raw_data_len = sizeof(sd_id128_t); r = dhcp6_configure(link);
if (r < 0)
return r;
}
return 1; if (!link_has_carrier(link))
return 0;
r = dhcp4_start(link);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to start DHCPv4 client: %m");
r = ndisc_start(link);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to start IPv6 Router Discovery: %m");
r = dhcp6_start(link);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to start DHCPv6 client: %m");
return 0;
} }
static int get_product_uuid_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { static int get_product_uuid_handler(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
@ -93,7 +139,6 @@ static int get_product_uuid_handler(sd_bus_message *m, void *userdata, sd_bus_er
const sd_bus_error *e; const sd_bus_error *e;
const void *a; const void *a;
size_t sz; size_t sz;
DUID *duid;
Link *link; Link *link;
int r; int r;
@ -119,56 +164,37 @@ static int get_product_uuid_handler(sd_bus_message *m, void *userdata, sd_bus_er
goto configure; goto configure;
} }
memcpy(&manager->product_uuid, a, sz); memcpy(&manager->duid_product_uuid.raw_data, a, sz);
while ((duid = set_steal_first(manager->duids_requesting_uuid))) manager->duid_product_uuid.raw_data_len = sz;
(void) duid_set_uuid(duid, manager->product_uuid);
manager->duids_requesting_uuid = set_free(manager->duids_requesting_uuid);
configure: configure:
while ((link = set_steal_first(manager->links_requesting_uuid))) {
link_unref(link);
r = link_configure(link);
if (r < 0)
link_enter_failed(link);
}
manager->links_requesting_uuid = set_free(manager->links_requesting_uuid);
/* To avoid calling GetProductUUID() bus method so frequently, set the flag below /* To avoid calling GetProductUUID() bus method so frequently, set the flag below
* even if the method fails. */ * even if the method fails. */
manager->has_product_uuid = true; manager->has_product_uuid = true;
while ((link = set_steal_first(manager->links_requesting_uuid))) {
r = link_configure_and_start_dhcp_delayed(link);
if (r < 0)
link_enter_failed(link);
link_unref(link);
}
manager->links_requesting_uuid = set_free(manager->links_requesting_uuid);
return 1; return 1;
} }
int manager_request_product_uuid(Manager *m, Link *link) { int manager_request_product_uuid(Manager *m) {
int r; int r;
assert(m); assert(m);
if (m->has_product_uuid) if (m->product_uuid_requested)
return 0; return 0;
log_debug("Requesting product UUID"); log_debug("Requesting product UUID");
if (link) {
DUID *duid;
assert_se(duid = link_get_duid(link));
r = set_ensure_put(&m->links_requesting_uuid, NULL, link);
if (r < 0)
return log_oom();
if (r > 0)
link_ref(link);
r = set_ensure_put(&m->duids_requesting_uuid, NULL, duid);
if (r < 0)
return log_oom();
}
if (sd_bus_is_ready(m->bus) <= 0) { if (sd_bus_is_ready(m->bus) <= 0) {
log_debug("Not connected to system bus, requesting product UUID later."); log_debug("Not connected to system bus, requesting product UUID later.");
return 0; return 0;
@ -188,70 +214,39 @@ int manager_request_product_uuid(Manager *m, Link *link) {
if (r < 0) if (r < 0)
return log_warning_errno(r, "Failed to get product UUID: %m"); return log_warning_errno(r, "Failed to get product UUID: %m");
m->product_uuid_requested = true;
return 0; return 0;
} }
static bool link_requires_uuid(Link *link) { int dhcp_configure_duid(Link *link, const DUID *duid) {
const DUID *duid;
assert(link);
assert(link->manager);
assert(link->network);
duid = link_get_duid(link);
if (duid->type != DUID_TYPE_UUID || duid->raw_data_len != 0)
return false;
if (link_dhcp4_enabled(link) && IN_SET(link->network->dhcp_client_identifier, DHCP_CLIENT_ID_DUID, DHCP_CLIENT_ID_DUID_ONLY))
return true;
if (link_dhcp6_enabled(link) || link_ipv6_accept_ra_enabled(link))
return true;
return false;
}
int link_configure_duid(Link *link) {
Manager *m; Manager *m;
DUID *duid;
int r; int r;
assert(link); assert(link);
assert(link->manager); assert(link->manager);
assert(link->network); assert(duid);
m = link->manager; m = link->manager;
duid = link_get_duid(link);
if (!link_requires_uuid(link)) if (!duid_needs_product_uuid(duid))
return 1; return 1;
if (m->has_product_uuid) { if (m->has_product_uuid)
(void) duid_set_uuid(duid, m->product_uuid); return 1;
r = manager_request_product_uuid(m);
if (r < 0) {
log_link_warning_errno(link, r,
"Failed to get product UUID. Falling back to use machine-app-specific ID as DUID-UUID: %m");
return 1; return 1;
} }
if (!m->links_requesting_uuid) { r = set_ensure_put(&m->links_requesting_uuid, NULL, link);
r = manager_request_product_uuid(m, link); if (r < 0)
if (r < 0) { return log_oom();
if (r == -ENOMEM) if (r > 0)
return r; link_ref(link);
log_link_warning_errno(link, r,
"Failed to get product UUID. Falling back to use machine-app-specific ID as DUID-UUID: %m");
return 1;
}
} else {
r = set_put(m->links_requesting_uuid, link);
if (r < 0)
return log_oom();
if (r > 0)
link_ref(link);
r = set_put(m->duids_requesting_uuid, duid);
if (r < 0)
return log_oom();
}
return 0; return 0;
} }
@ -523,6 +518,7 @@ int config_parse_iaid(const char *unit,
const char *rvalue, const char *rvalue,
void *data, void *data,
void *userdata) { void *userdata) {
Network *network = userdata; Network *network = userdata;
uint32_t iaid; uint32_t iaid;
int r; int r;
@ -531,6 +527,7 @@ int config_parse_iaid(const char *unit,
assert(lvalue); assert(lvalue);
assert(rvalue); assert(rvalue);
assert(network); assert(network);
assert(IN_SET(ltype, AF_INET, AF_INET6));
r = safe_atou32(rvalue, &iaid); r = safe_atou32(rvalue, &iaid);
if (r < 0) { if (r < 0) {
@ -539,8 +536,21 @@ int config_parse_iaid(const char *unit,
return 0; return 0;
} }
network->iaid = iaid; if (ltype == AF_INET) {
network->iaid_set = true; network->dhcp_iaid = iaid;
network->dhcp_iaid_set = true;
if (!network->dhcp6_iaid_set_explicitly) {
/* Backward compatibility. Previously, IAID is shared by DHCP4 and DHCP6.
* If DHCP6 IAID is not specified explicitly, then use DHCP4 IAID for DHCP6. */
network->dhcp6_iaid = iaid;
network->dhcp6_iaid_set = true;
}
} else {
assert(ltype == AF_INET6);
network->dhcp6_iaid = iaid;
network->dhcp6_iaid_set = true;
network->dhcp6_iaid_set_explicitly = true;
}
return 0; return 0;
} }
@ -924,3 +934,260 @@ static const char * const dhcp_option_data_type_table[_DHCP_OPTION_DATA_MAX] = {
}; };
DEFINE_STRING_TABLE_LOOKUP(dhcp_option_data_type, DHCPOptionDataType); DEFINE_STRING_TABLE_LOOKUP(dhcp_option_data_type, DHCPOptionDataType);
static const char* const duid_type_table[_DUID_TYPE_MAX] = {
[DUID_TYPE_LLT] = "link-layer-time",
[DUID_TYPE_EN] = "vendor",
[DUID_TYPE_LL] = "link-layer",
[DUID_TYPE_UUID] = "uuid",
};
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(duid_type, DUIDType);
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) {
_cleanup_free_ char *type_string = NULL;
const char *p = rvalue;
bool force = ltype;
DUID *duid = data;
DUIDType type;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(duid);
if (!force && duid->set)
return 0;
r = extract_first_word(&p, &type_string, ":", 0);
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Invalid syntax, ignoring: %s", rvalue);
return 0;
}
if (r == 0) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Failed to extract DUID type from '%s', ignoring.", rvalue);
return 0;
}
type = duid_type_from_string(type_string);
if (type < 0) {
log_syntax(unit, LOG_WARNING, filename, line, type,
"Failed to parse DUID type '%s', ignoring.", type_string);
return 0;
}
if (!isempty(p)) {
usec_t u;
if (type != DUID_TYPE_LLT) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Invalid syntax, ignoring: %s", rvalue);
return 0;
}
r = parse_timestamp(p, &u);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse timestamp, ignoring: %s", p);
return 0;
}
duid->llt_time = u;
}
duid->type = type;
duid->set = force;
return 0;
}
int config_parse_manager_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) {
Manager *manager = userdata;
int r;
assert(manager);
/* For backward compatibility. Setting both DHCP4 and DHCP6 DUID if they are not specified explicitly. */
r = config_parse_duid_type(unit, filename, line, section, section_line, lvalue, false, rvalue, &manager->dhcp_duid, manager);
if (r < 0)
return r;
return config_parse_duid_type(unit, filename, line, section, section_line, lvalue, false, rvalue, &manager->dhcp6_duid, manager);
}
int config_parse_network_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) {
Network *network = userdata;
int r;
assert(network);
r = config_parse_duid_type(unit, filename, line, section, section_line, lvalue, true, rvalue, &network->dhcp_duid, network);
if (r < 0)
return r;
/* For backward compatibility, also set DHCP6 DUID if not specified explicitly. */
return config_parse_duid_type(unit, filename, line, section, section_line, lvalue, false, rvalue, &network->dhcp6_duid, network);
}
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) {
uint8_t raw_data[MAX_DUID_LEN];
unsigned count = 0;
bool force = ltype;
DUID *duid = data;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(duid);
if (!force && duid->set)
return 0;
/* RawData contains DUID in format "NN:NN:NN..." */
for (const char *p = rvalue;;) {
int n1, n2, len, r;
uint32_t byte;
_cleanup_free_ char *cbyte = NULL;
r = extract_first_word(&p, &cbyte, ":", 0);
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to read DUID, ignoring assignment: %s.", rvalue);
return 0;
}
if (r == 0)
break;
if (count >= MAX_DUID_LEN) {
log_syntax(unit, LOG_WARNING, filename, line, 0, "Max DUID length exceeded, ignoring assignment: %s.", rvalue);
return 0;
}
len = strlen(cbyte);
if (!IN_SET(len, 1, 2)) {
log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid length - DUID byte: %s, ignoring assignment: %s.", cbyte, rvalue);
return 0;
}
n1 = unhexchar(cbyte[0]);
if (len == 2)
n2 = unhexchar(cbyte[1]);
else
n2 = 0;
if (n1 < 0 || n2 < 0) {
log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid DUID byte: %s. Ignoring assignment: %s.", cbyte, rvalue);
return 0;
}
byte = ((uint8_t) n1 << (4 * (len-1))) | (uint8_t) n2;
raw_data[count++] = byte;
}
assert_cc(sizeof(raw_data) == sizeof(duid->raw_data));
memcpy(duid->raw_data, raw_data, count);
duid->raw_data_len = count;
duid->set = force;
return 0;
}
int config_parse_manager_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) {
Manager *manager = userdata;
int r;
assert(manager);
/* For backward compatibility. Setting both DHCP4 and DHCP6 DUID if they are not specified explicitly. */
r = config_parse_duid_rawdata(unit, filename, line, section, section_line, lvalue, false, rvalue, &manager->dhcp_duid, manager);
if (r < 0)
return r;
return config_parse_duid_rawdata(unit, filename, line, section, section_line, lvalue, false, rvalue, &manager->dhcp6_duid, manager);
}
int config_parse_network_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) {
Network *network = userdata;
int r;
assert(network);
r = config_parse_duid_rawdata(unit, filename, line, section, section_line, lvalue, true, rvalue, &network->dhcp_duid, network);
if (r < 0)
return r;
/* For backward compatibility, also set DHCP6 DUID if not specified explicitly. */
return config_parse_duid_rawdata(unit, filename, line, section, section_line, lvalue, false, rvalue, &network->dhcp6_duid, network);
}

View File

@ -1,6 +1,8 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */ /* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once #pragma once
#include <netinet/in.h>
#include "conf-parser.h" #include "conf-parser.h"
#include "dhcp-identifier.h" #include "dhcp-identifier.h"
#include "time-util.h" #include "time-util.h"
@ -37,6 +39,7 @@ typedef struct DUID {
uint8_t raw_data_len; uint8_t raw_data_len;
uint8_t raw_data[MAX_DUID_LEN]; uint8_t raw_data[MAX_DUID_LEN];
usec_t llt_time; usec_t llt_time;
bool set;
} DUID; } DUID;
bool link_dhcp_enabled(Link *link, int family); bool link_dhcp_enabled(Link *link, int family);
@ -49,9 +52,16 @@ static inline bool link_dhcp6_enabled(Link *link) {
void network_adjust_dhcp(Network *network); void network_adjust_dhcp(Network *network);
DUID* link_get_duid(Link *link); const DUID *link_get_duid(Link *link, int family);
int link_configure_duid(Link *link); static inline const DUID *link_get_dhcp4_duid(Link *link) {
int manager_request_product_uuid(Manager *m, Link *link); return link_get_duid(link, AF_INET);
}
static inline const DUID *link_get_dhcp6_duid(Link *link) {
return link_get_duid(link, AF_INET6);
}
int dhcp_configure_duid(Link *link, const DUID *duid);
int manager_request_product_uuid(Manager *m);
const char* dhcp_use_domains_to_string(DHCPUseDomains p) _const_; const char* dhcp_use_domains_to_string(DHCPUseDomains p) _const_;
DHCPUseDomains dhcp_use_domains_from_string(const char *s) _pure_; DHCPUseDomains dhcp_use_domains_from_string(const char *s) _pure_;
@ -69,3 +79,9 @@ CONFIG_PARSER_PROTOTYPE(config_parse_section_route_table);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_user_or_vendor_class); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_user_or_vendor_class);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_send_option); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_send_option);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_request_options); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_request_options);
CONFIG_PARSER_PROTOTYPE(config_parse_duid_type);
CONFIG_PARSER_PROTOTYPE(config_parse_manager_duid_type);
CONFIG_PARSER_PROTOTYPE(config_parse_network_duid_type);
CONFIG_PARSER_PROTOTYPE(config_parse_duid_rawdata);
CONFIG_PARSER_PROTOTYPE(config_parse_manager_duid_rawdata);
CONFIG_PARSER_PROTOTYPE(config_parse_network_duid_rawdata);

View File

@ -1225,17 +1225,17 @@ static int dhcp4_set_client_identifier(Link *link) {
switch (link->network->dhcp_client_identifier) { switch (link->network->dhcp_client_identifier) {
case DHCP_CLIENT_ID_DUID: { case DHCP_CLIENT_ID_DUID: {
/* If configured, apply user specified DUID and IAID */ /* If configured, apply user specified DUID and IAID */
const DUID *duid = link_get_duid(link); const DUID *duid = link_get_dhcp4_duid(link);
if (duid->type == DUID_TYPE_LLT && duid->raw_data_len == 0) if (duid->type == DUID_TYPE_LLT && duid->raw_data_len == 0)
r = sd_dhcp_client_set_iaid_duid_llt(link->dhcp_client, r = sd_dhcp_client_set_iaid_duid_llt(link->dhcp_client,
link->network->iaid_set, link->network->dhcp_iaid_set,
link->network->iaid, link->network->dhcp_iaid,
duid->llt_time); duid->llt_time);
else else
r = sd_dhcp_client_set_iaid_duid(link->dhcp_client, r = sd_dhcp_client_set_iaid_duid(link->dhcp_client,
link->network->iaid_set, link->network->dhcp_iaid_set,
link->network->iaid, link->network->dhcp_iaid,
duid->type, duid->type,
duid->raw_data_len > 0 ? duid->raw_data : NULL, duid->raw_data_len > 0 ? duid->raw_data : NULL,
duid->raw_data_len); duid->raw_data_len);
@ -1245,7 +1245,7 @@ static int dhcp4_set_client_identifier(Link *link) {
} }
case DHCP_CLIENT_ID_DUID_ONLY: { case DHCP_CLIENT_ID_DUID_ONLY: {
/* If configured, apply user specified DUID */ /* If configured, apply user specified DUID */
const DUID *duid = link_get_duid(link); const DUID *duid = link_get_dhcp4_duid(link);
if (duid->type == DUID_TYPE_LLT && duid->raw_data_len == 0) if (duid->type == DUID_TYPE_LLT && duid->raw_data_len == 0)
r = sd_dhcp_client_set_duid_llt(link->dhcp_client, r = sd_dhcp_client_set_duid_llt(link->dhcp_client,
@ -1284,6 +1284,15 @@ static int dhcp4_set_client_identifier(Link *link) {
return 0; return 0;
} }
static int dhcp4_configure_duid(Link *link) {
assert(link);
if (!IN_SET(link->network->dhcp_client_identifier, DHCP_CLIENT_ID_DUID, DHCP_CLIENT_ID_DUID_ONLY))
return 1;
return dhcp_configure_duid(link, link_get_dhcp4_duid(link));
}
static int dhcp4_set_request_address(Link *link) { static int dhcp4_set_request_address(Link *link) {
Address *a; Address *a;
@ -1323,6 +1332,10 @@ int dhcp4_configure(Link *link) {
if (link->dhcp_client) if (link->dhcp_client)
return -EBUSY; /* Already configured. */ return -EBUSY; /* Already configured. */
r = dhcp4_configure_duid(link);
if (r <= 0)
return r;
r = sd_dhcp_client_new(&link->dhcp_client, link->network->dhcp_anonymize); r = sd_dhcp_client_new(&link->dhcp_client, link->network->dhcp_anonymize);
if (r < 0) if (r < 0)
return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to allocate DHCP4 client: %m"); return log_link_warning_errno(link, r, "DHCP4 CLIENT: Failed to allocate DHCP4 client: %m");
@ -1505,6 +1518,20 @@ int dhcp4_update_mac(Link *link) {
return 0; return 0;
} }
int dhcp4_start(Link *link) {
assert(link);
if (!link->dhcp_client)
return 0;
if (sd_dhcp_client_is_running(link->dhcp_client) > 0)
return 0;
log_link_debug(link, "Acquiring DHCPv4 lease");
return sd_dhcp_client_start(link->dhcp_client);
}
int config_parse_dhcp_max_attempts( int config_parse_dhcp_max_attempts(
const char *unit, const char *unit,
const char *filename, const char *filename,

View File

@ -20,6 +20,7 @@ typedef enum DHCPClientIdentifier {
void network_adjust_dhcp4(Network *network); void network_adjust_dhcp4(Network *network);
int dhcp4_configure(Link *link); int dhcp4_configure(Link *link);
int dhcp4_update_mac(Link *link); int dhcp4_update_mac(Link *link);
int dhcp4_start(Link *link);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_client_identifier); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_client_identifier);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_acl_ip_address); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_acl_ip_address);

View File

@ -1354,6 +1354,31 @@ int dhcp6_request_address(Link *link, int ir) {
return 0; return 0;
} }
int dhcp6_start(Link *link) {
assert(link);
if (!link->dhcp6_client)
return 0;
if (!link_dhcp6_enabled(link))
return 0;
if (link->network->dhcp6_without_ra == DHCP6_CLIENT_START_MODE_NO)
return 0;
if (!in6_addr_is_link_local(&link->ipv6ll_address)) {
log_link_debug(link, "IPv6 link-local address is not set, delaying to start DHCPv6 client.");
return 0;
}
if (sd_dhcp6_client_is_running(link->dhcp6_client) > 0)
return 0;
log_link_debug(link, "Acquiring DHCPv6 lease");
return dhcp6_request_address(link, link->network->dhcp6_without_ra == DHCP6_CLIENT_START_MODE_INFORMATION_REQUEST);
}
int dhcp6_request_prefix_delegation(Link *link) { int dhcp6_request_prefix_delegation(Link *link) {
Link *l; Link *l;
@ -1488,13 +1513,13 @@ static int dhcp6_set_identifier(Link *link, sd_dhcp6_client *client) {
if (r < 0) if (r < 0)
return r; return r;
if (link->network->iaid_set) { if (link->network->dhcp6_iaid_set) {
r = sd_dhcp6_client_set_iaid(client, link->network->iaid); r = sd_dhcp6_client_set_iaid(client, link->network->dhcp6_iaid);
if (r < 0) if (r < 0)
return r; return r;
} }
duid = link_get_duid(link); duid = link_get_dhcp6_duid(link);
if (duid->type == DUID_TYPE_LLT && duid->raw_data_len == 0) if (duid->type == DUID_TYPE_LLT && duid->raw_data_len == 0)
r = sd_dhcp6_client_set_duid_llt(client, duid->llt_time); r = sd_dhcp6_client_set_duid_llt(client, duid->llt_time);
else else
@ -1524,6 +1549,10 @@ int dhcp6_configure(Link *link) {
if (link->dhcp6_client) if (link->dhcp6_client)
return -EBUSY; return -EBUSY;
r = dhcp_configure_duid(link, link_get_dhcp6_duid(link));
if (r <= 0)
return r;
r = sd_dhcp6_client_new(&client); r = sd_dhcp6_client_new(&client);
if (r == -ENOMEM) if (r == -ENOMEM)
return log_oom(); return log_oom();

View File

@ -31,6 +31,7 @@ bool link_dhcp6_pd_is_enabled(Link *link);
int dhcp6_pd_remove(Link *link); int dhcp6_pd_remove(Link *link);
int dhcp6_configure(Link *link); int dhcp6_configure(Link *link);
int dhcp6_update_mac(Link *link); int dhcp6_update_mac(Link *link);
int dhcp6_start(Link *link);
int dhcp6_request_address(Link *link, int ir); int dhcp6_request_address(Link *link, int ir);
int dhcp6_request_prefix_delegation(Link *link); int dhcp6_request_prefix_delegation(Link *link);

View File

@ -6,6 +6,7 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
#include <stddef.h> #include <stddef.h>
#include "conf-parser.h" #include "conf-parser.h"
#include "networkd-conf.h" #include "networkd-conf.h"
#include "networkd-dhcp-common.h"
#include "networkd-manager.h" #include "networkd-manager.h"
#include "networkd-route.h" #include "networkd-route.h"
%} %}
@ -25,5 +26,10 @@ Network.SpeedMeterIntervalSec, config_parse_sec,
Network.ManageForeignRoutingPolicyRules, config_parse_bool, 0, offsetof(Manager, manage_foreign_rules) Network.ManageForeignRoutingPolicyRules, config_parse_bool, 0, offsetof(Manager, manage_foreign_rules)
Network.ManageForeignRoutes, config_parse_bool, 0, offsetof(Manager, manage_foreign_routes) Network.ManageForeignRoutes, config_parse_bool, 0, offsetof(Manager, manage_foreign_routes)
Network.RouteTable, config_parse_route_table_names, 0, 0 Network.RouteTable, config_parse_route_table_names, 0, 0
DHCP.DUIDType, config_parse_duid_type, 0, offsetof(Manager, duid) DHCPv4.DUIDType, config_parse_duid_type, 0, offsetof(Manager, dhcp_duid)
DHCP.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Manager, duid) DHCPv4.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Manager, dhcp_duid)
DHCPv6.DUIDType, config_parse_duid_type, 0, offsetof(Manager, dhcp6_duid)
DHCPv6.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Manager, dhcp6_duid)
/* Deprecated */
DHCP.DUIDType, config_parse_manager_duid_type, 0, 0
DHCP.DUIDRawData, config_parse_manager_duid_rawdata, 0, 0

View File

@ -1179,14 +1179,6 @@ static int link_acquire_ipv6_conf(Link *link) {
assert(link); assert(link);
if (link->ndisc) {
log_link_debug(link, "Discovering IPv6 routers");
r = sd_ndisc_start(link->ndisc);
if (r < 0 && r != -EBUSY)
return log_link_warning_errno(link, r, "Could not start IPv6 Router Discovery: %m");
}
if (link->radv) { if (link->radv) {
assert(link->radv); assert(link->radv);
assert(in6_addr_is_link_local(&link->ipv6ll_address)); assert(in6_addr_is_link_local(&link->ipv6ll_address));
@ -1202,18 +1194,13 @@ static int link_acquire_ipv6_conf(Link *link) {
return log_link_warning_errno(link, r, "Could not start IPv6 Router Advertisement: %m"); return log_link_warning_errno(link, r, "Could not start IPv6 Router Advertisement: %m");
} }
if (link_dhcp6_enabled(link) && IN_SET(link->network->dhcp6_without_ra, r = ndisc_start(link);
DHCP6_CLIENT_START_MODE_INFORMATION_REQUEST, if (r < 0)
DHCP6_CLIENT_START_MODE_SOLICIT)) { return log_link_warning_errno(link, r, "Failed to start IPv6 Router Discovery: %m");
assert(link->dhcp6_client);
assert(in6_addr_is_link_local(&link->ipv6ll_address));
r = dhcp6_request_address(link, link->network->dhcp6_without_ra == DHCP6_CLIENT_START_MODE_INFORMATION_REQUEST); r = dhcp6_start(link);
if (r < 0 && r != -EBUSY) if (r < 0)
return log_link_warning_errno(link, r, "Could not acquire DHCPv6 lease: %m"); return log_link_warning_errno(link, r, "Failed to start DHCPv6 client: %m");
else
log_link_debug(link, "Acquiring DHCPv6 lease");
}
r = dhcp6_request_prefix_delegation(link); r = dhcp6_request_prefix_delegation(link);
if (r < 0) if (r < 0)
@ -1230,11 +1217,9 @@ static int link_acquire_ipv4_conf(Link *link) {
assert(link->manager->event); assert(link->manager->event);
if (link->dhcp_client) { if (link->dhcp_client) {
log_link_debug(link, "Acquiring DHCPv4 lease"); r = dhcp4_start(link);
r = sd_dhcp_client_start(link->dhcp_client);
if (r < 0) if (r < 0)
return log_link_warning_errno(link, r, "Could not acquire DHCPv4 lease: %m"); return log_link_warning_errno(link, r, "Failed to start DHCPv4 client: %m");
} else if (link->ipv4ll) { } else if (link->ipv4ll) {
log_link_debug(link, "Acquiring IPv4 link-local address"); log_link_debug(link, "Acquiring IPv4 link-local address");
@ -2254,12 +2239,6 @@ static int link_reconfigure_internal(Link *link, sd_netlink_message *m, bool for
link_set_state(link, LINK_STATE_INITIALIZED); link_set_state(link, LINK_STATE_INITIALIZED);
link->activated = false; link->activated = false;
/* link_configure_duid() returns 0 if it requests product UUID. In that case,
* link_configure() is called later asynchronously. */
r = link_configure_duid(link);
if (r <= 0)
return r;
r = link_configure(link); r = link_configure(link);
if (r < 0) if (r < 0)
return r; return r;
@ -2374,12 +2353,6 @@ static int link_initialized_and_synced(Link *link) {
if (r < 0) if (r < 0)
return r; return r;
/* link_configure_duid() returns 0 if it requests product UUID. In that case,
* link_configure() is called later asynchronously. */
r = link_configure_duid(link);
if (r <= 0)
return r;
r = link_configure(link); r = link_configure(link);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -100,8 +100,8 @@ static int on_connected(sd_bus_message *message, void *userdata, sd_bus_error *r
(void) manager_set_hostname(m, m->dynamic_hostname); (void) manager_set_hostname(m, m->dynamic_hostname);
if (m->dynamic_timezone) if (m->dynamic_timezone)
(void) manager_set_timezone(m, m->dynamic_timezone); (void) manager_set_timezone(m, m->dynamic_timezone);
if (m->links_requesting_uuid) if (!set_isempty(m->links_requesting_uuid))
(void) manager_request_product_uuid(m, NULL); (void) manager_request_product_uuid(m);
return 0; return 0;
} }
@ -382,6 +382,9 @@ int manager_new(Manager **ret) {
.manage_foreign_routes = true, .manage_foreign_routes = true,
.manage_foreign_rules = true, .manage_foreign_rules = true,
.ethtool_fd = -1, .ethtool_fd = -1,
.dhcp_duid.type = DUID_TYPE_EN,
.dhcp6_duid.type = DUID_TYPE_EN,
.duid_product_uuid.type = DUID_TYPE_UUID,
}; };
m->state_file = strdup("/run/systemd/netif/state"); m->state_file = strdup("/run/systemd/netif/state");
@ -427,8 +430,6 @@ int manager_new(Manager **ret) {
if (r < 0) if (r < 0)
return r; return r;
m->duid.type = DUID_TYPE_EN;
*ret = TAKE_PTR(m); *ret = TAKE_PTR(m);
return 0; return 0;
@ -452,7 +453,6 @@ Manager* manager_free(Manager *m) {
m->links_requesting_uuid = set_free_with_destructor(m->links_requesting_uuid, link_unref); m->links_requesting_uuid = set_free_with_destructor(m->links_requesting_uuid, link_unref);
m->links = hashmap_free_with_destructor(m->links, link_unref); m->links = hashmap_free_with_destructor(m->links, link_unref);
m->duids_requesting_uuid = set_free(m->duids_requesting_uuid);
m->networks = ordered_hashmap_free_with_destructor(m->networks, network_unref); m->networks = ordered_hashmap_free_with_destructor(m->networks, network_unref);
m->netdevs = hashmap_free_with_destructor(m->netdevs, netdev_unref); m->netdevs = hashmap_free_with_destructor(m->netdevs, netdev_unref);

View File

@ -52,11 +52,12 @@ struct Manager {
usec_t network_dirs_ts_usec; usec_t network_dirs_ts_usec;
DUID duid; DUID dhcp_duid;
sd_id128_t product_uuid; DUID dhcp6_duid;
DUID duid_product_uuid;
bool has_product_uuid; bool has_product_uuid;
bool product_uuid_requested;
Set *links_requesting_uuid; Set *links_requesting_uuid;
Set *duids_requesting_uuid;
char* dynamic_hostname; char* dynamic_hostname;
char* dynamic_timezone; char* dynamic_timezone;

View File

@ -1341,6 +1341,17 @@ int ndisc_configure(Link *link) {
return 0; return 0;
} }
int ndisc_start(Link *link) {
assert(link);
if (!link->ndisc || !link->dhcp6_client)
return 0;
log_link_debug(link, "Discovering IPv6 routers");
return sd_ndisc_start(link->ndisc);
}
void ndisc_vacuum(Link *link) { void ndisc_vacuum(Link *link) {
NDiscRDNSS *r; NDiscRDNSS *r;
NDiscDNSSL *d; NDiscDNSSL *d;

View File

@ -73,6 +73,7 @@ bool link_ipv6_accept_ra_enabled(Link *link);
void network_adjust_ipv6_accept_ra(Network *network); void network_adjust_ipv6_accept_ra(Network *network);
int ndisc_configure(Link *link); int ndisc_configure(Link *link);
int ndisc_start(Link *link);
void ndisc_vacuum(Link *link); void ndisc_vacuum(Link *link);
void ndisc_flush(Link *link); void ndisc_flush(Link *link);

View File

@ -10,7 +10,6 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
#include "networkd-address-label.h" #include "networkd-address-label.h"
#include "networkd-address.h" #include "networkd-address.h"
#include "networkd-can.h" #include "networkd-can.h"
#include "networkd-conf.h"
#include "networkd-dhcp-common.h" #include "networkd-dhcp-common.h"
#include "networkd-dhcp-server.h" #include "networkd-dhcp-server.h"
#include "networkd-dhcp4.h" #include "networkd-dhcp4.h"
@ -213,12 +212,12 @@ DHCPv4.VendorClassIdentifier, config_parse_string,
DHCPv4.MUDURL, config_parse_dhcp_mud_url, 0, 0 DHCPv4.MUDURL, config_parse_dhcp_mud_url, 0, 0
DHCPv4.MaxAttempts, config_parse_dhcp_max_attempts, 0, 0 DHCPv4.MaxAttempts, config_parse_dhcp_max_attempts, 0, 0
DHCPv4.UserClass, config_parse_dhcp_user_or_vendor_class, AF_INET, offsetof(Network, dhcp_user_class) DHCPv4.UserClass, config_parse_dhcp_user_or_vendor_class, AF_INET, offsetof(Network, dhcp_user_class)
DHCPv4.DUIDType, config_parse_duid_type, 0, offsetof(Network, duid) DHCPv4.IAID, config_parse_iaid, AF_INET, 0
DHCPv4.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Network, duid) DHCPv4.DUIDType, config_parse_network_duid_type, 0, 0
DHCPv4.DUIDRawData, config_parse_network_duid_rawdata, 0, 0
DHCPv4.RouteMetric, config_parse_dhcp_route_metric, 0, 0 DHCPv4.RouteMetric, config_parse_dhcp_route_metric, 0, 0
DHCPv4.RouteTable, config_parse_section_route_table, 0, 0 DHCPv4.RouteTable, config_parse_section_route_table, 0, 0
DHCPv4.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_use_timezone) DHCPv4.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_use_timezone)
DHCPv4.IAID, config_parse_iaid, 0, 0
DHCPv4.ListenPort, config_parse_uint16, 0, offsetof(Network, dhcp_client_port) DHCPv4.ListenPort, config_parse_uint16, 0, offsetof(Network, dhcp_client_port)
DHCPv4.SendRelease, config_parse_bool, 0, offsetof(Network, dhcp_send_release) DHCPv4.SendRelease, config_parse_bool, 0, offsetof(Network, dhcp_send_release)
DHCPv4.SendDecline, config_parse_bool, 0, offsetof(Network, dhcp_send_decline) DHCPv4.SendDecline, config_parse_bool, 0, offsetof(Network, dhcp_send_decline)
@ -244,6 +243,9 @@ DHCPv6.ForceDHCPv6PDOtherInformation, config_parse_bool,
DHCPv6.PrefixDelegationHint, config_parse_dhcp6_pd_hint, 0, 0 DHCPv6.PrefixDelegationHint, config_parse_dhcp6_pd_hint, 0, 0
DHCPv6.WithoutRA, config_parse_dhcp6_client_start_mode, 0, offsetof(Network, dhcp6_without_ra) DHCPv6.WithoutRA, config_parse_dhcp6_client_start_mode, 0, offsetof(Network, dhcp6_without_ra)
DHCPv6.SendOption, config_parse_dhcp_send_option, AF_INET6, offsetof(Network, dhcp6_client_send_options) DHCPv6.SendOption, config_parse_dhcp_send_option, AF_INET6, offsetof(Network, dhcp6_client_send_options)
DHCPv6.IAID, config_parse_iaid, AF_INET6, 0
DHCPv6.DUIDType, config_parse_duid_type, 0, offsetof(Network, dhcp6_duid)
DHCPv6.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Network, dhcp6_duid)
IPv6AcceptRA.UseAutonomousPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_autonomous_prefix) IPv6AcceptRA.UseAutonomousPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_autonomous_prefix)
IPv6AcceptRA.UseOnLinkPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_onlink_prefix) IPv6AcceptRA.UseOnLinkPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_onlink_prefix)
IPv6AcceptRA.UseDNS, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_dns) IPv6AcceptRA.UseDNS, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_dns)
@ -483,12 +485,12 @@ DHCP.RequestBroadcast, config_parse_bool,
DHCP.CriticalConnection, config_parse_tristate, 0, offsetof(Network, dhcp_critical) DHCP.CriticalConnection, config_parse_tristate, 0, offsetof(Network, dhcp_critical)
DHCP.VendorClassIdentifier, config_parse_string, 0, offsetof(Network, dhcp_vendor_class_identifier) DHCP.VendorClassIdentifier, config_parse_string, 0, offsetof(Network, dhcp_vendor_class_identifier)
DHCP.UserClass, config_parse_dhcp_user_or_vendor_class, AF_INET, offsetof(Network, dhcp_user_class) DHCP.UserClass, config_parse_dhcp_user_or_vendor_class, AF_INET, offsetof(Network, dhcp_user_class)
DHCP.DUIDType, config_parse_duid_type, 0, offsetof(Network, duid) DHCP.IAID, config_parse_iaid, AF_INET, 0
DHCP.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Network, duid) DHCP.DUIDType, config_parse_network_duid_type, 0, 0
DHCP.DUIDRawData, config_parse_network_duid_rawdata, 0, 0
DHCP.RouteMetric, config_parse_dhcp_route_metric, 0, 0 DHCP.RouteMetric, config_parse_dhcp_route_metric, 0, 0
DHCP.RouteTable, config_parse_section_route_table, 0, 0 DHCP.RouteTable, config_parse_section_route_table, 0, 0
DHCP.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_use_timezone) DHCP.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_use_timezone)
DHCP.IAID, config_parse_iaid, 0, 0
DHCP.ListenPort, config_parse_uint16, 0, offsetof(Network, dhcp_client_port) DHCP.ListenPort, config_parse_uint16, 0, offsetof(Network, dhcp_client_port)
DHCP.RapidCommit, config_parse_bool, 0, offsetof(Network, dhcp6_rapid_commit) DHCP.RapidCommit, config_parse_bool, 0, offsetof(Network, dhcp6_rapid_commit)
DHCP.ForceDHCPv6PDOtherInformation, config_parse_bool, 0, offsetof(Network, dhcp6_force_pd_other_information) DHCP.ForceDHCPv6PDOtherInformation, config_parse_bool, 0, offsetof(Network, dhcp6_force_pd_other_information)

View File

@ -301,7 +301,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.ignore_carrier_loss = -1, .ignore_carrier_loss = -1,
.keep_configuration = _KEEP_CONFIGURATION_INVALID, .keep_configuration = _KEEP_CONFIGURATION_INVALID,
.duid.type = _DUID_TYPE_INVALID, .dhcp_duid.type = _DUID_TYPE_INVALID,
.dhcp_critical = -1, .dhcp_critical = -1,
.dhcp_use_ntp = true, .dhcp_use_ntp = true,
.dhcp_use_sip = true, .dhcp_use_sip = true,
@ -321,6 +321,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.dhcp6_use_hostname = true, .dhcp6_use_hostname = true,
.dhcp6_use_ntp = true, .dhcp6_use_ntp = true,
.dhcp6_rapid_commit = true, .dhcp6_rapid_commit = true,
.dhcp6_duid.type = _DUID_TYPE_INVALID,
.dhcp6_pd = -1, .dhcp6_pd = -1,
.dhcp6_pd_announce = true, .dhcp6_pd_announce = true,
@ -599,10 +600,6 @@ static Network *network_free(Network *network) {
ordered_hashmap_free_with_destructor(network->sr_iov_by_section, sr_iov_free); ordered_hashmap_free_with_destructor(network->sr_iov_by_section, sr_iov_free);
ordered_hashmap_free_with_destructor(network->tc_by_section, traffic_control_free); ordered_hashmap_free_with_destructor(network->tc_by_section, traffic_control_free);
if (network->manager &&
network->manager->duids_requesting_uuid)
set_remove(network->manager->duids_requesting_uuid, &network->duid);
free(network->name); free(network->name);
free(network->dhcp_server_timezone); free(network->dhcp_server_timezone);

View File

@ -118,9 +118,9 @@ struct Network {
/* DHCP Client Support */ /* DHCP Client Support */
AddressFamily dhcp; AddressFamily dhcp;
DHCPClientIdentifier dhcp_client_identifier; DHCPClientIdentifier dhcp_client_identifier;
DUID duid; DUID dhcp_duid;
uint32_t iaid; uint32_t dhcp_iaid;
bool iaid_set; bool dhcp_iaid_set;
char *dhcp_vendor_class_identifier; char *dhcp_vendor_class_identifier;
char *dhcp_mudurl; char *dhcp_mudurl;
char **dhcp_user_class; char **dhcp_user_class;
@ -169,6 +169,10 @@ struct Network {
bool dhcp6_rapid_commit; bool dhcp6_rapid_commit;
DHCPUseDomains dhcp6_use_domains; DHCPUseDomains dhcp6_use_domains;
bool dhcp6_use_domains_set; bool dhcp6_use_domains_set;
uint32_t dhcp6_iaid;
bool dhcp6_iaid_set;
bool dhcp6_iaid_set_explicitly;
DUID dhcp6_duid;
uint8_t dhcp6_pd_length; uint8_t dhcp6_pd_length;
char *dhcp6_mudurl; char *dhcp6_mudurl;
char **dhcp6_user_class; char **dhcp6_user_class;

View File

@ -19,6 +19,10 @@
#ManageForeignRoutes=yes #ManageForeignRoutes=yes
#RouteTable= #RouteTable=
[DHCP] [DHCPv4]
#DUIDType=vendor
#DUIDRawData=
[DHCPv6]
#DUIDType=vendor #DUIDType=vendor
#DUIDRawData= #DUIDRawData=

View File

@ -3115,9 +3115,8 @@ static int partition_acquire_uuid(Context *context, Partition *p, sd_id128_t *re
if (p == q) if (p == q)
continue; continue;
if (sd_id128_equal(q->current_uuid, result.id) || if (sd_id128_in_set(result.id, q->current_uuid, q->new_uuid)) {
sd_id128_equal(q->new_uuid, result.id)) { log_warning("Partition UUID calculated from seed for partition %" PRIu64 " already used, reverting to randomized UUID.", p->partno);
log_warning("Partition UUID calculated from seed for partition %" PRIu64 " exists already, reverting to randomized UUID.", p->partno);
r = sd_id128_randomize(&result.id); r = sd_id128_randomize(&result.id);
if (r < 0) if (r < 0)

View File

@ -108,52 +108,57 @@ int gpt_partition_label_valid(const char *s) {
} }
bool gpt_partition_type_is_root(sd_id128_t id) { bool gpt_partition_type_is_root(sd_id128_t id) {
return sd_id128_equal(id, GPT_ROOT_X86) || return sd_id128_in_set(id,
sd_id128_equal(id, GPT_ROOT_X86_64) || GPT_ROOT_X86,
sd_id128_equal(id, GPT_ROOT_ARM) || GPT_ROOT_X86_64,
sd_id128_equal(id, GPT_ROOT_ARM_64) || GPT_ROOT_ARM,
sd_id128_equal(id, GPT_ROOT_IA64) || GPT_ROOT_ARM_64,
sd_id128_equal(id, GPT_ROOT_RISCV32) || GPT_ROOT_IA64,
sd_id128_equal(id, GPT_ROOT_RISCV64); GPT_ROOT_RISCV32,
GPT_ROOT_RISCV64);
} }
bool gpt_partition_type_is_root_verity(sd_id128_t id) { bool gpt_partition_type_is_root_verity(sd_id128_t id) {
return sd_id128_equal(id, GPT_ROOT_X86_VERITY) || return sd_id128_in_set(id,
sd_id128_equal(id, GPT_ROOT_X86_64_VERITY) || GPT_ROOT_X86_VERITY,
sd_id128_equal(id, GPT_ROOT_ARM_VERITY) || GPT_ROOT_X86_64_VERITY,
sd_id128_equal(id, GPT_ROOT_ARM_64_VERITY) || GPT_ROOT_ARM_VERITY,
sd_id128_equal(id, GPT_ROOT_IA64_VERITY) || GPT_ROOT_ARM_64_VERITY,
sd_id128_equal(id, GPT_ROOT_RISCV32_VERITY) || GPT_ROOT_IA64_VERITY,
sd_id128_equal(id, GPT_ROOT_RISCV64_VERITY); GPT_ROOT_RISCV32_VERITY,
GPT_ROOT_RISCV64_VERITY);
} }
bool gpt_partition_type_is_usr(sd_id128_t id) { bool gpt_partition_type_is_usr(sd_id128_t id) {
return sd_id128_equal(id, GPT_USR_X86) || return sd_id128_in_set(id,
sd_id128_equal(id, GPT_USR_X86_64) || GPT_USR_X86,
sd_id128_equal(id, GPT_USR_ARM) || GPT_USR_X86_64,
sd_id128_equal(id, GPT_USR_ARM_64) || GPT_USR_ARM,
sd_id128_equal(id, GPT_USR_IA64) || GPT_USR_ARM_64,
sd_id128_equal(id, GPT_USR_RISCV32) || GPT_USR_IA64,
sd_id128_equal(id, GPT_USR_RISCV64); GPT_USR_RISCV32,
GPT_USR_RISCV64);
} }
bool gpt_partition_type_is_usr_verity(sd_id128_t id) { bool gpt_partition_type_is_usr_verity(sd_id128_t id) {
return sd_id128_equal(id, GPT_USR_X86_VERITY) || return sd_id128_in_set(id,
sd_id128_equal(id, GPT_USR_X86_64_VERITY) || GPT_USR_X86_VERITY,
sd_id128_equal(id, GPT_USR_ARM_VERITY) || GPT_USR_X86_64_VERITY,
sd_id128_equal(id, GPT_USR_ARM_64_VERITY) || GPT_USR_ARM_VERITY,
sd_id128_equal(id, GPT_USR_IA64_VERITY) || GPT_USR_ARM_64_VERITY,
sd_id128_equal(id, GPT_USR_RISCV32_VERITY) || GPT_USR_IA64_VERITY,
sd_id128_equal(id, GPT_USR_RISCV64_VERITY); GPT_USR_RISCV32_VERITY,
GPT_USR_RISCV64_VERITY);
} }
bool gpt_partition_type_knows_read_only(sd_id128_t id) { bool gpt_partition_type_knows_read_only(sd_id128_t id) {
return gpt_partition_type_is_root(id) || return gpt_partition_type_is_root(id) ||
gpt_partition_type_is_usr(id) || gpt_partition_type_is_usr(id) ||
sd_id128_equal(id, GPT_HOME) || sd_id128_in_set(id,
sd_id128_equal(id, GPT_SRV) || GPT_HOME,
sd_id128_equal(id, GPT_VAR) || GPT_SRV,
sd_id128_equal(id, GPT_TMP) || GPT_VAR,
GPT_TMP) ||
gpt_partition_type_is_root_verity(id) || /* pretty much implied, but let's set the bit to make things really clear */ gpt_partition_type_is_root_verity(id) || /* pretty much implied, but let's set the bit to make things really clear */
gpt_partition_type_is_usr_verity(id); /* ditto */ gpt_partition_type_is_usr_verity(id); /* ditto */
} }

View File

@ -18,6 +18,7 @@
***/ ***/
#include <inttypes.h> #include <inttypes.h>
#include <stdarg.h>
#include <string.h> #include <string.h>
#include "_sd-common.h" #include "_sd-common.h"
@ -119,6 +120,32 @@ _sd_pure_ static __inline__ int sd_id128_is_allf(sd_id128_t a) {
#define SD_ID128_NULL ((const sd_id128_t) { .qwords = { 0, 0 }}) #define SD_ID128_NULL ((const sd_id128_t) { .qwords = { 0, 0 }})
#define SD_ID128_ALLF ((const sd_id128_t) { .qwords = { UINT64_C(0xFFFFFFFFFFFFFFFF), UINT64_C(0xFFFFFFFFFFFFFFFF) }}) #define SD_ID128_ALLF ((const sd_id128_t) { .qwords = { UINT64_C(0xFFFFFFFFFFFFFFFF), UINT64_C(0xFFFFFFFFFFFFFFFF) }})
_sd_pure_ static __inline__ int sd_id128_in_setv(sd_id128_t a, va_list ap) {
for (;;) {
sd_id128_t b = va_arg(ap, sd_id128_t);
if (sd_id128_is_null(b))
return 0;
if (sd_id128_equal(a, b))
return 1;
}
}
_sd_pure_ static __inline__ int sd_id128_in_set_sentinel(sd_id128_t a, ...) {
va_list ap;
int r;
va_start(ap, a);
r = sd_id128_in_setv(a, ap);
va_end(ap);
return r;
}
#define sd_id128_in_set(a, ...) \
sd_id128_in_set_sentinel(a, ##__VA_ARGS__, SD_ID128_NULL)
_SD_END_DECLARATIONS; _SD_END_DECLARATIONS;
#endif #endif

View File

@ -31,6 +31,13 @@ int main(int argc, char *argv[]) {
assert_se(sd_id128_from_string(t, &id2) == 0); assert_se(sd_id128_from_string(t, &id2) == 0);
assert_se(sd_id128_equal(id, id2)); assert_se(sd_id128_equal(id, id2));
assert_se(sd_id128_in_set(id, id));
assert_se(sd_id128_in_set(id, id2));
assert_se(sd_id128_in_set(id, id2, id));
assert_se(sd_id128_in_set(id, ID128_WALDI, id));
assert_se(!sd_id128_in_set(id));
assert_se(!sd_id128_in_set(id, ID128_WALDI));
assert_se(!sd_id128_in_set(id, ID128_WALDI, ID128_WALDI));
if (sd_booted() > 0) { if (sd_booted() > 0) {
assert_se(sd_id128_get_machine(&id) == 0); assert_se(sd_id128_get_machine(&id) == 0);

View File

@ -9,6 +9,7 @@
#endif #endif
#include "fd-util.h" #include "fd-util.h"
#include "fs-util.h"
#include "memory-util.h" #include "memory-util.h"
#include "sigbus.h" #include "sigbus.h"
#include "tests.h" #include "tests.h"
@ -35,7 +36,7 @@ int main(int argc, char *argv[]) {
assert_se((fd = mkostemp(template, O_RDWR|O_CREAT|O_EXCL)) >= 0); assert_se((fd = mkostemp(template, O_RDWR|O_CREAT|O_EXCL)) >= 0);
assert_se(unlink(template) >= 0); assert_se(unlink(template) >= 0);
assert_se(posix_fallocate(fd, 0, page_size() * 8) >= 0); assert_se(posix_fallocate_loop(fd, 0, page_size() * 8) >= 0);
p = mmap(NULL, page_size() * 16, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); p = mmap(NULL, page_size() * 16, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
assert_se(p != MAP_FAILED); assert_se(p != MAP_FAILED);

View File

@ -141,6 +141,9 @@ UserClass=
VendorClass= VendorClass=
SendVendorOption= SendVendorOption=
RouteMetric= RouteMetric=
IAID=
DUIDType=
DUIDRawData=
[DHCPv6PrefixDelegation] [DHCPv6PrefixDelegation]
SubnetId= SubnetId=
Announce= Announce=