Compare commits

...

35 Commits

Author SHA1 Message Date
Thomas Haller e40b4caa1f basic/tmpfile: avoid maybe-uninitialized warning in mkostemp_safe()
The variable is always initialized, but the compiler might not notice
that. With gcc-9.2.1-1.fc31:

    $ CFLAGS='-Werror=maybe-uninitialized -Og' meson build
    $ ninja -C build
    [...]
    ../src/basic/tmpfile-util.c: In function ‘mkostemp_safe’:
    ../src/basic/tmpfile-util.c:76:12: error: ‘fd’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
       76 |         if (fd < 0)
          |            ^
2019-12-16 14:25:31 +01:00
Benjamin Dahlhoff cb180b09fa Added Trekstor Primetab S11B 2019-12-16 11:18:05 +01:00
Yu Watanabe 3771024c24
Merge pull request #14354 from poettering/link-fix
two trivial doc fixes
2019-12-16 18:06:33 +09:00
Lennart Poettering da7667518b docs: CSS files should not be executable 2019-12-16 09:50:02 +01:00
Lennart Poettering 90d81ee966 github: use systemd.io links in issue template 2019-12-16 09:49:51 +01:00
Lennart Poettering c84d9b3b71
Merge pull request #14261 from keszybz/loop-utils-and-efivars
Fixes for networkd, shared/loop-util, basic/efivars
2019-12-16 09:27:46 +01:00
Lennart Poettering 3b5cd25f4d
Merge pull request #14196 from keszybz/gpt-auto-generator-debugging
gpt-auto-generator debugging
2019-12-16 09:24:02 +01:00
Lennart Poettering 32b7cdc14c
Merge pull request #14350 from yuwata/network-udev-altnames-support
network, udev: add altname support
2019-12-16 09:15:23 +01:00
Yu Watanabe 7a2f6fb6f1 test-network: pass environment variables to networkctl 2019-12-16 10:56:02 +09:00
Yu Watanabe 6934ace05d test-network: add a test case for netdev altname 2019-12-16 10:56:02 +09:00
Yu Watanabe 511070ee95 networkctl: show alternative names 2019-12-16 10:56:02 +09:00
Yu Watanabe 572b21d96c network: make Name= in [Match] support alternative names of interfaces 2019-12-16 10:55:56 +09:00
Yu Watanabe a5053a158b udev: support AlternativeName= setting in .link file 2019-12-16 10:52:22 +09:00
Yu Watanabe 4252696aec util: introduce ifname_valid_full() 2019-12-16 10:52:22 +09:00
Yu Watanabe d08d92d5ee test: add a test for sd_netlink_message_{append,read}_strv() 2019-12-16 10:52:22 +09:00
Yu Watanabe 6d725977c4 sd-netlink: introduce sd_netlink_message_append_strv() 2019-12-16 10:52:22 +09:00
Yu Watanabe 8f3c185966 sd-netlink: introduce sd_netlink_message_read_strv()
The combination of sd_netlink_message_enter_container() and
sd_netlink_message_read_string() only reads the last element if the attribute is
duplicated, such a situation easily happens for IFLA_ALT_IFNAME.
The function introduced here reads all matched attributes.
2019-12-16 10:52:17 +09:00
Zbigniew Jędrzejewski-Szmek 0181314861 shared/loop-util: spin on open() returning ENOENT too
https://github.com/systemd/systemd/pull/14261#discussion_r355001559
2019-12-15 21:06:42 +01:00
Zbigniew Jędrzejewski-Szmek 35b9eb0a72 basic/efivars: do not return EIO if an efivar read is shorten than fstat size
On my machine stat returns size 22, but only 20 bytes are read:

openat(AT_FDCWD, "/sys/firmware/efi/efivars/LoaderTimeInitUSec-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f", O_RDONLY|O_NOCTTY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=22, ...}) = 0
read(3, "\6\0\0\0", 4)                  = 4
read(3, "7\0001\0001\0003\0005\0002\0007\0\0\0", 18) = 16
Failed to read LoaderTimeInitUSec: Input/output error

Let's just accept that the kernel is returning inconsistent results.
It seems to happen two only two variables on my machine:
/sys/firmware/efi/efivars/LoaderTimeInitUSec-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
/sys/firmware/efi/efivars/LoaderTimeMenuUSec-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
so it might be related to the way we write them.
2019-12-15 21:06:42 +01:00
Zbigniew Jędrzejewski-Szmek a97abb30e7 shared/efi-loader: add some debugging statements
Should make it easier to figure out why some operations fail...
2019-12-15 21:06:42 +01:00
Zbigniew Jędrzejewski-Szmek f2d9213fee shared/loop-util: spin on LOOP_CTL_REMOVE
If we call LOOP_CLR_FD and LOOP_CTL_REMOVE too rapidly, the kernel cannot deal
with that (5.3.13-300.fc31.x86_64 running on dual core
Intel(R) Core(TM) i7-6500U CPU @ 2.50GHz).

$ sudo strace -eioctl build/test-dissect-image /tmp/foobar3.img
ioctl(3, TCGETS, 0x7ffcee47de20)        = -1 ENOTTY (Inappropriate ioctl for device)
ioctl(4, LOOP_CTL_GET_FREE)             = 9
ioctl(5, LOOP_SET_FD, 3)                = 0
ioctl(5, LOOP_SET_STATUS64, {lo_offset=0, lo_number=0, lo_flags=LO_FLAGS_READ_ONLY|LO_FLAGS_AUTOCLEAR|LO_FLAGS_PARTSCAN, lo_file_name="", ...}) = 0
ioctl(5, BLKGETSIZE64, [299999744])     = 0
ioctl(5, CDROM_GET_CAPABILITY, 0)       = -1 EINVAL (Invalid argument)
ioctl(5, BLKSSZGET, [512])              = 0
Waiting for device (parent + 0 partitions) to appear...
Found root partition, writable of type btrfs at #-1 (/dev/block/7:9)
ioctl(5, LOOP_CLR_FD)                   = 0
ioctl(3, LOOP_CTL_REMOVE, 9)            = -1 EBUSY (Device or resource busy)
Failed to remove loop device: Device or resource busy

This seems to be clear race condition, and attaching strace is generally enough
to "win" the race. But even with strace attached, we will fail occasionally.
Let's wait a bit and retry. With the wait, on my machine, the second attempt
always succeeds:

...
Found root partition, writable of type btrfs at #-1 (/dev/block/7:9)
ioctl(5, LOOP_CLR_FD)                   = 0
ioctl(3, LOOP_CTL_REMOVE, 9)            = -1 EBUSY (Device or resource busy)
ioctl(3, LOOP_CTL_REMOVE, 9)            = 9
+++ exited with 0 +++

Without the wait, all 64 attempts will occasionally fail.
2019-12-15 21:06:42 +01:00
Zbigniew Jędrzejewski-Szmek e8af3bfd63 shared/loop-util: fix error handling in loop_device_make_full()
The function no longer returns the fd. This complicated semantics, because it
wasn't clear what holds the ownership: the return value or the output
parameter.  There were no users of the fd in the return value, so let's
simplify things conceptually and only return the fd once.

Reduce the scope of variables.

LOOP_CLR_FD was called on the wrong fd. Let's use a cleanup function to make
this automatic and reduce chances of a mixup in the future.

CID 1408498.
2019-12-15 21:06:42 +01:00
Yu Watanabe ffeb16f5d8 sd-netlink: support IFLA_PROP_LIST and IFLA_ALT_IFNAME attributes 2019-12-16 04:37:50 +09:00
Yu Watanabe d3678e3a0b linux: update headers 2019-12-16 04:37:50 +09:00
Zbigniew Jędrzejewski-Szmek 6b2a8b80b4 shared/loop-util: drop inline function with one use 2019-12-06 10:56:49 +01:00
Zbigniew Jędrzejewski-Szmek ba5450f411 shared/loop-util: fix leak of fd in error path 2019-12-06 10:40:20 +01:00
Zbigniew Jędrzejewski-Szmek 1163a2e98a shared/loop-util: operate on the right fd
'loop' is always -1 at this point in the code.
2019-12-06 10:39:14 +01:00
Zbigniew Jędrzejewski-Szmek 14bb274d3f networkd: check return value
CID 1408497.
2019-12-05 18:19:06 +01:00
Zbigniew Jędrzejewski-Szmek 3d92aa4596 gpt-auto-generator: rename function for clarity
As requested in
https://github.com/systemd/systemd/pull/14196#discussion_r352036184.
2019-11-30 17:42:13 +01:00
Zbigniew Jędrzejewski-Szmek 46c41478c9 tree-wise: standarize on "auto-detection" spelling 2019-11-30 17:42:13 +01:00
Zbigniew Jędrzejewski-Szmek 607ebf2bd2 bootlctl: show LoaderDevicePartUUID information in status 2019-11-30 17:42:13 +01:00
Zbigniew Jędrzejewski-Szmek b50a3a1565 gpt-auto-generator: make it easier to notice if boot loader support is missing
The docs didn't talk about this, so let's add an explicit mention that the
boot loader must cooperate. And also make the message from the generator
notice level. This should help people who are trying to mix grub and the
gpt auto logic.
2019-11-30 17:42:00 +01:00
Zbigniew Jędrzejewski-Szmek 1fac34b941 gpt-auto-generator: use write_drop_in_format() helper and downgrade failure
If we fail to write the timeout, let's not exit. (This might happen if another
generator writes the same dropin.) No need to make this fatal.

Since this is non-fatal now and the name doesn't need to be unique, let's make
the drop-in name shorter.
2019-11-30 17:33:34 +01:00
Zbigniew Jędrzejewski-Szmek 074cdb953b gpt-auto-generator: improve debug messages a bit
In particular, let's give a hint when we do nothing in the common case of
root= being used.
2019-11-30 17:33:26 +01:00
Zbigniew Jędrzejewski-Szmek 9fe6f5cc16 gpt-auto-generator: move functions around
open_parent_devno() which is a helper is moved out of the main "business logic"
block of various add_*() functions. And parse_proc_cmdline_item() is moved to
the end, near to run() where it is used. No functional change.
2019-11-28 19:43:43 +01:00
55 changed files with 1515 additions and 1039 deletions

View File

@ -8,7 +8,7 @@ about: A report of an error in a recent systemd version
> ...
<!-- **NOTE:** Do not submit bug reports about anything but the two most recently released systemd versions upstream! -->
<!-- For older version please use distribution trackers (see https://github.com/systemd/systemd/blob/master/docs/CONTRIBUTING.md#filing-issues). -->
<!-- For older version please use distribution trackers (see https://systemd.io/CONTRIBUTING#filing-issues). -->
**Used distribution**
> …

2
TODO
View File

@ -234,7 +234,7 @@ Features:
1. add resume_offset support to the resume code (i.e. support swap files
properly)
2. check if swap is on weird storage and refuse if so
3. add autodetection of hibernation images
3. add auto-detection of hibernation images
* cgroups: use inotify to get notified when somebody else modifies cgroups
owned by us, then log a friendly warning.

0
docs/style.css Executable file → Normal file
View File

View File

@ -606,6 +606,7 @@ sensor:modalias:acpi:BMA250*:dmi:*:bvrTREK.G.WI71C.JGBMRBA*:*:svnInsyde:pnST7041
sensor:modalias:acpi:BMA250*:dmi:*:bvrTREK.G.WI71C.JGBMRBA*:*:svnTrekStor:pnSurfTabwintron7.0ST70416-6:*
ACCEL_MOUNT_MATRIX=0, 1, 0; 1, 0, 0; 0, 0, 1
sensor:modalias:acpi:KIOX000A*:dmi:*:svnTREKSTOR*:pnPrimetabS11B:*
sensor:modalias:acpi:KIOX000A*:dmi:*:svnTREKSTOR:pnPrimetabT13B:*
sensor:modalias:acpi:BOSC0200*:dmi:*:svnTrekStor*:pnSurfTabtwin11.6:*
ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1

View File

@ -35,7 +35,7 @@
root, <filename>/home/</filename>, <filename>/srv/</filename>, the EFI System Partition, the Extended
Boot Loader Partition and swap partitions and creates mount and swap units for them, based on the
partition type GUIDs of GUID partition tables (GPT), see <ulink
url="https://uefi.org/specifications">UEFI Specification</ulink>, chapter 5. It implements the <ulink
url="https://uefi.org/specifications">UEFI Specification</ulink>, chapter 5. It implements the <ulink
url="https://www.freedesktop.org/wiki/Specifications/DiscoverablePartitionsSpec/">Discoverable Partitions
Specification</ulink>. Note that this generator has no effect on non-GPT systems, and on specific mount
points that are directories already containing files. Also, on systems where the units are explicitly
@ -44,18 +44,21 @@
units this generator creates are overridden, but additional implicit dependencies might be
created.</para>
<para>This generator will only look for root partitions on the
same physical disk the EFI System Partition (ESP) is located on.
It will only look for the other partitions on the same physical
disk the root file system is located on. These partitions will not
be searched for on systems where the root file system is distributed
on multiple disks, for example via btrfs RAID.</para>
<para>This generator will only look for the root partition on the same physical disk the EFI System
Partition (ESP) is located on. Note that support from the boot loader is required: EFI variable
<varname>LoaderDevicePartUUID-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f</varname> is used to determine from
which partition, and hence the disk from which the system was booted. If the boot loader does not set
this variable, this generator will not be able to autodetect the root partition.</para>
<para><filename>systemd-gpt-auto-generator</filename> is useful
for centralizing file system configuration in the partition table
and making configuration in <filename>/etc/fstab</filename> unnecessary.
<para>Similarly, this generator will only look for the other partitions on the same physical disk as the
root partition. In this case, boot loader support is not required. These partitions will not be searched
for on systems where the root file system is distributed on multiple disks, for example via btrfs RAID.
</para>
<para><filename>systemd-gpt-auto-generator</filename> is useful for centralizing file system
configuration in the partition table and making configuration in <filename>/etc/fstab</filename> or on
the kernel command line unnecessary.</para>
<para>This generator looks for the partitions based on their
partition type GUID. The following partition type GUIDs are
identified:</para>

View File

@ -356,6 +356,14 @@
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>AlternativeName=</varname></term>
<listitem>
<para>The alternative interface name to use. This option can be specified multiple times.
If the empty string is assigned to this option, the list is reset, and all prior assignments
have no effect.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>MTUBytes=</varname></term>
<listitem>

View File

@ -132,10 +132,9 @@
<varlistentry>
<term><varname>Name=</varname></term>
<listitem>
<para>A whitespace-separated list of shell-style globs
matching the device name, as exposed by the udev property
<literal>INTERFACE</literal>. If the list is prefixed
with a "!", the test is inverted.</para>
<para>A whitespace-separated list of shell-style globs matching the device name, as exposed
by the udev property <literal>INTERFACE</literal>, or device's alternative names. If the
list is prefixed with a "!", the test is inverted.</para>
</listitem>
</varlistentry>
<varlistentry>

View File

@ -90,13 +90,14 @@ int efi_get_variable(
n = read(fd, buf, (size_t) st.st_size - 4);
if (n < 0)
return -errno;
if (n != st.st_size - 4)
return -EIO;
assert(n <= st.st_size - 4);
/* Always NUL terminate (2 bytes, to protect UTF-16) */
((char*) buf)[st.st_size - 4] = 0;
((char*) buf)[st.st_size - 4 + 1] = 0;
}
((char*) buf)[n - 4] = 0;
((char*) buf)[n - 4 + 1] = 0;
} else
/* Assume that the reported size is accurate */
n = st.st_size - 4;
/* Note that efivarfs interestingly doesn't require ftruncate() to update an existing EFI variable
* with a smaller value. */
@ -108,7 +109,7 @@ int efi_get_variable(
*ret_value = TAKE_PTR(buf);
if (ret_size)
*ret_size = (size_t) st.st_size - 4;
*ret_size = n;
return 0;
}

View File

@ -270,6 +270,7 @@ struct btrfs_ioctl_fs_info_args {
#define BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA (1ULL << 8)
#define BTRFS_FEATURE_INCOMPAT_NO_HOLES (1ULL << 9)
#define BTRFS_FEATURE_INCOMPAT_METADATA_UUID (1ULL << 10)
#define BTRFS_FEATURE_INCOMPAT_RAID1C34 (1ULL << 11)
struct btrfs_ioctl_feature_flags {
__u64 compat_flags;
@ -665,7 +666,12 @@ struct btrfs_ioctl_get_dev_stats {
/* out values: */
__u64 values[BTRFS_DEV_STAT_VALUES_MAX];
__u64 unused[128 - 2 - BTRFS_DEV_STAT_VALUES_MAX]; /* pad to 1k */
/*
* This pads the struct to 1032 bytes. It was originally meant to pad to
* 1024 bytes, but when adding the flags field, the padding calculation
* was not adjusted.
*/
__u64 unused[128 - 2 - BTRFS_DEV_STAT_VALUES_MAX];
};
#define BTRFS_QUOTA_CTL_ENABLE 1
@ -826,7 +832,9 @@ enum btrfs_err_code {
BTRFS_ERROR_DEV_TGT_REPLACE,
BTRFS_ERROR_DEV_MISSING_NOT_FOUND,
BTRFS_ERROR_DEV_ONLY_WRITABLE,
BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS
BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS,
BTRFS_ERROR_DEV_RAID1C3_MIN_NOT_MET,
BTRFS_ERROR_DEV_RAID1C4_MIN_NOT_MET,
};
#define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
@ -917,10 +925,8 @@ enum btrfs_err_code {
#define BTRFS_IOC_QUOTA_RESCAN_STATUS _IOR(BTRFS_IOCTL_MAGIC, 45, \
struct btrfs_ioctl_quota_rescan_args)
#define BTRFS_IOC_QUOTA_RESCAN_WAIT _IO(BTRFS_IOCTL_MAGIC, 46)
#define BTRFS_IOC_GET_FSLABEL _IOR(BTRFS_IOCTL_MAGIC, 49, \
char[BTRFS_LABEL_SIZE])
#define BTRFS_IOC_SET_FSLABEL _IOW(BTRFS_IOCTL_MAGIC, 50, \
char[BTRFS_LABEL_SIZE])
#define BTRFS_IOC_GET_FSLABEL FS_IOC_GETFSLABEL
#define BTRFS_IOC_SET_FSLABEL FS_IOC_SETFSLABEL
#define BTRFS_IOC_GET_DEV_STATS _IOWR(BTRFS_IOCTL_MAGIC, 52, \
struct btrfs_ioctl_get_dev_stats)
#define BTRFS_IOC_DEV_REPLACE _IOWR(BTRFS_IOCTL_MAGIC, 53, \

View File

@ -300,7 +300,12 @@
#define BTRFS_CSUM_SIZE 32
/* csum types */
#define BTRFS_CSUM_TYPE_CRC32 0
enum btrfs_csum_type {
BTRFS_CSUM_TYPE_CRC32 = 0,
BTRFS_CSUM_TYPE_XXHASH = 1,
BTRFS_CSUM_TYPE_SHA256 = 2,
BTRFS_CSUM_TYPE_BLAKE2 = 3,
};
/*
* flags definitions for directory entry item type
@ -735,10 +740,12 @@ struct btrfs_balance_item {
__le64 unused[4];
} __attribute__ ((__packed__));
#define BTRFS_FILE_EXTENT_INLINE 0
#define BTRFS_FILE_EXTENT_REG 1
#define BTRFS_FILE_EXTENT_PREALLOC 2
#define BTRFS_FILE_EXTENT_TYPES 2
enum {
BTRFS_FILE_EXTENT_INLINE = 0,
BTRFS_FILE_EXTENT_REG = 1,
BTRFS_FILE_EXTENT_PREALLOC = 2,
BTRFS_NR_FILE_EXTENT_TYPES = 3,
};
struct btrfs_file_extent_item {
/*
@ -806,11 +813,6 @@ struct btrfs_dev_stats_item {
#define BTRFS_DEV_REPLACE_ITEM_CONT_READING_FROM_SRCDEV_MODE_ALWAYS 0
#define BTRFS_DEV_REPLACE_ITEM_CONT_READING_FROM_SRCDEV_MODE_AVOID 1
#define BTRFS_DEV_REPLACE_ITEM_STATE_NEVER_STARTED 0
#define BTRFS_DEV_REPLACE_ITEM_STATE_STARTED 1
#define BTRFS_DEV_REPLACE_ITEM_STATE_SUSPENDED 2
#define BTRFS_DEV_REPLACE_ITEM_STATE_FINISHED 3
#define BTRFS_DEV_REPLACE_ITEM_STATE_CANCELED 4
struct btrfs_dev_replace_item {
/*
@ -839,6 +841,8 @@ struct btrfs_dev_replace_item {
#define BTRFS_BLOCK_GROUP_RAID10 (1ULL << 6)
#define BTRFS_BLOCK_GROUP_RAID5 (1ULL << 7)
#define BTRFS_BLOCK_GROUP_RAID6 (1ULL << 8)
#define BTRFS_BLOCK_GROUP_RAID1C3 (1ULL << 9)
#define BTRFS_BLOCK_GROUP_RAID1C4 (1ULL << 10)
#define BTRFS_BLOCK_GROUP_RESERVED (BTRFS_AVAIL_ALLOC_BIT_SINGLE | \
BTRFS_SPACE_INFO_GLOBAL_RSV)
@ -850,6 +854,8 @@ enum btrfs_raid_types {
BTRFS_RAID_SINGLE,
BTRFS_RAID_RAID5,
BTRFS_RAID_RAID6,
BTRFS_RAID_RAID1C3,
BTRFS_RAID_RAID1C4,
BTRFS_NR_RAID_TYPES
};
@ -859,6 +865,8 @@ enum btrfs_raid_types {
#define BTRFS_BLOCK_GROUP_PROFILE_MASK (BTRFS_BLOCK_GROUP_RAID0 | \
BTRFS_BLOCK_GROUP_RAID1 | \
BTRFS_BLOCK_GROUP_RAID1C3 | \
BTRFS_BLOCK_GROUP_RAID1C4 | \
BTRFS_BLOCK_GROUP_RAID5 | \
BTRFS_BLOCK_GROUP_RAID6 | \
BTRFS_BLOCK_GROUP_DUP | \
@ -866,6 +874,10 @@ enum btrfs_raid_types {
#define BTRFS_BLOCK_GROUP_RAID56_MASK (BTRFS_BLOCK_GROUP_RAID5 | \
BTRFS_BLOCK_GROUP_RAID6)
#define BTRFS_BLOCK_GROUP_RAID1_MASK (BTRFS_BLOCK_GROUP_RAID1 | \
BTRFS_BLOCK_GROUP_RAID1C3 | \
BTRFS_BLOCK_GROUP_RAID1C4)
/*
* We need a bit for restriper to be able to tell when chunks of type
* SINGLE are available. This "extended" profile format is used in

View File

@ -1,4 +1,4 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
#ifndef _UAPI_CAN_VXCAN_H
#define _UAPI_CAN_VXCAN_H

View File

@ -32,6 +32,7 @@
#define IFNAMSIZ 16
#endif /* __UAPI_DEF_IF_IFNAMSIZ */
#define IFALIASZ 256
#define ALTIFNAMSIZ 128
#include <linux/hdlc/ioctl.h>
/* For glibc compatibility. An empty enum does not compile. */

View File

@ -237,6 +237,7 @@ struct br_mdb_entry {
#define MDB_PERMANENT 1
__u8 state;
#define MDB_FLAGS_OFFLOAD (1 << 0)
#define MDB_FLAGS_FAST_LEAVE (1 << 1)
__u8 flags;
__u16 vid;
struct {

View File

@ -91,6 +91,7 @@
#define ETH_P_802_EX1 0x88B5 /* 802.1 Local Experimental 1. */
#define ETH_P_PREAUTH 0x88C7 /* 802.11 Preauthentication */
#define ETH_P_TIPC 0x88CA /* TIPC */
#define ETH_P_LLDP 0x88CC /* Link Layer Discovery Protocol */
#define ETH_P_MACSEC 0x88E5 /* 802.1ae MACsec */
#define ETH_P_8021AH 0x88E7 /* 802.1ah Backbone Service Tag */
#define ETH_P_MVRP 0x88F5 /* 802.1Q MVRP */

View File

@ -167,6 +167,8 @@ enum {
IFLA_NEW_IFINDEX,
IFLA_MIN_MTU,
IFLA_MAX_MTU,
IFLA_PROP_LIST,
IFLA_ALT_IFNAME, /* Alternative ifname */
__IFLA_MAX
};
@ -636,6 +638,7 @@ enum {
IFLA_BOND_AD_USER_PORT_KEY,
IFLA_BOND_AD_ACTOR_SYSTEM,
IFLA_BOND_TLB_DYNAMIC_LB,
IFLA_BOND_PEER_NOTIF_DELAY,
__IFLA_BOND_MAX,
};
@ -694,6 +697,7 @@ enum {
IFLA_VF_IB_NODE_GUID, /* VF Infiniband node GUID */
IFLA_VF_IB_PORT_GUID, /* VF Infiniband port GUID */
IFLA_VF_VLAN_LIST, /* nested list of vlans, option for QinQ */
IFLA_VF_BROADCAST, /* VF broadcast */
__IFLA_VF_MAX,
};
@ -704,6 +708,10 @@ struct ifla_vf_mac {
__u8 mac[32]; /* MAX_ADDR_LEN */
};
struct ifla_vf_broadcast {
__u8 broadcast[32];
};
struct ifla_vf_vlan {
__u32 vf;
__u32 vlan; /* 0 - 4095, 0 disables VLAN filter */

View File

@ -1,56 +1,56 @@
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef _LINUX_NEXTHOP_H
#define _LINUX_NEXTHOP_H
#ifndef _UAPI_LINUX_NEXTHOP_H
#define _UAPI_LINUX_NEXTHOP_H
#include <linux/types.h>
struct nhmsg {
unsigned char nh_family;
unsigned char nh_scope; /* return only */
unsigned char nh_protocol; /* Routing protocol that installed nh */
unsigned char resvd;
unsigned int nh_flags; /* RTNH_F flags */
unsigned char nh_family;
unsigned char nh_scope; /* return only */
unsigned char nh_protocol; /* Routing protocol that installed nh */
unsigned char resvd;
unsigned int nh_flags; /* RTNH_F flags */
};
/* entry in a nexthop group */
struct nexthop_grp {
__u32 id; /* nexthop id - must exist */
__u8 weight; /* weight of this nexthop */
__u8 resvd1;
__u16 resvd2;
__u32 id; /* nexthop id - must exist */
__u8 weight; /* weight of this nexthop */
__u8 resvd1;
__u16 resvd2;
};
enum {
NEXTHOP_GRP_TYPE_MPATH, /* default type if not specified */
__NEXTHOP_GRP_TYPE_MAX,
NEXTHOP_GRP_TYPE_MPATH, /* default type if not specified */
__NEXTHOP_GRP_TYPE_MAX,
};
#define NEXTHOP_GRP_TYPE_MAX (__NEXTHOP_GRP_TYPE_MAX - 1)
enum {
NHA_UNSPEC,
NHA_ID, /* u32; id for nexthop. id == 0 means auto-assign */
NHA_UNSPEC,
NHA_ID, /* u32; id for nexthop. id == 0 means auto-assign */
NHA_GROUP, /* array of nexthop_grp */
NHA_GROUP_TYPE, /* u16 one of NEXTHOP_GRP_TYPE */
/* if NHA_GROUP attribute is added, no other attributes can be set */
NHA_GROUP, /* array of nexthop_grp */
NHA_GROUP_TYPE, /* u16 one of NEXTHOP_GRP_TYPE */
/* if NHA_GROUP attribute is added, no other attributes can be set */
NHA_BLACKHOLE, /* flag; nexthop used to blackhole packets */
/* if NHA_BLACKHOLE is added, OIF, GATEWAY, ENCAP can not be set */
NHA_BLACKHOLE, /* flag; nexthop used to blackhole packets */
/* if NHA_BLACKHOLE is added, OIF, GATEWAY, ENCAP can not be set */
NHA_OIF, /* u32; nexthop device */
NHA_GATEWAY, /* be32 (IPv4) or in6_addr (IPv6) gw address */
NHA_ENCAP_TYPE, /* u16; lwt encap type */
NHA_ENCAP, /* lwt encap data */
NHA_OIF, /* u32; nexthop device */
NHA_GATEWAY, /* be32 (IPv4) or in6_addr (IPv6) gw address */
NHA_ENCAP_TYPE, /* u16; lwt encap type */
NHA_ENCAP, /* lwt encap data */
/* NHA_OIF can be appended to dump request to return only
* nexthops using given device
*/
NHA_GROUPS, /* flag; only return nexthop groups in dump */
NHA_MASTER, /* u32; only return nexthops with given master dev */
/* NHA_OIF can be appended to dump request to return only
* nexthops using given device
*/
NHA_GROUPS, /* flag; only return nexthop groups in dump */
NHA_MASTER, /* u32; only return nexthops with given master dev */
__NHA_MAX,
__NHA_MAX,
};
#define NHA_MAX (__NHA_MAX - 1)
#define NHA_MAX (__NHA_MAX - 1)
#endif

File diff suppressed because it is too large Load Diff

View File

@ -157,13 +157,20 @@ enum {
RTM_GETCHAIN,
#define RTM_GETCHAIN RTM_GETCHAIN
RTM_NEWNEXTHOP = 104,
RTM_NEWNEXTHOP = 104,
#define RTM_NEWNEXTHOP RTM_NEWNEXTHOP
RTM_DELNEXTHOP,
RTM_DELNEXTHOP,
#define RTM_DELNEXTHOP RTM_DELNEXTHOP
RTM_GETNEXTHOP,
RTM_GETNEXTHOP,
#define RTM_GETNEXTHOP RTM_GETNEXTHOP
RTM_NEWLINKPROP = 108,
#define RTM_NEWLINKPROP RTM_NEWLINKPROP
RTM_DELLINKPROP,
#define RTM_DELLINKPROP RTM_DELLINKPROP
RTM_GETLINKPROP,
#define RTM_GETLINKPROP RTM_GETLINKPROP
__RTM_MAX,
#define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1)
};
@ -172,7 +179,7 @@ enum {
#define RTM_NR_FAMILIES (RTM_NR_MSGTYPES >> 2)
#define RTM_FAM(cmd) (((cmd) - RTM_BASE) >> 2)
/*
/*
Generic structure for encapsulation of optional route information.
It is reminiscent of sockaddr, but with sa_family replaced
with attribute type.
@ -212,7 +219,7 @@ struct rtmsg {
unsigned char rtm_table; /* Routing table id */
unsigned char rtm_protocol; /* Routing protocol; see below */
unsigned char rtm_scope; /* See below */
unsigned char rtm_scope; /* See below */
unsigned char rtm_type; /* See below */
unsigned rtm_flags;
@ -349,7 +356,7 @@ enum rtattr_type_t {
RTA_IP_PROTO,
RTA_SPORT,
RTA_DPORT,
RTA_NH_ID,
RTA_NH_ID,
__RTA_MAX
};
@ -523,7 +530,7 @@ struct ifinfomsg {
};
/********************************************************************
* prefix information
* prefix information
****/
struct prefixmsg {
@ -537,7 +544,7 @@ struct prefixmsg {
unsigned char prefix_pad3;
};
enum
enum
{
PREFIX_UNSPEC,
PREFIX_ADDRESS,
@ -712,7 +719,7 @@ enum rtnetlink_groups {
#define RTNLGRP_IPV4_MROUTE_R RTNLGRP_IPV4_MROUTE_R
RTNLGRP_IPV6_MROUTE_R,
#define RTNLGRP_IPV6_MROUTE_R RTNLGRP_IPV6_MROUTE_R
RTNLGRP_NEXTHOP,
RTNLGRP_NEXTHOP,
#define RTNLGRP_NEXTHOP RTNLGRP_NEXTHOP
__RTNLGRP_MAX
};

View File

@ -18,30 +18,30 @@
* one but not both of:
*
* WGDEVICE_A_IFINDEX: NLA_U32
* WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMESIZ - 1
* WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMSIZ - 1
*
* The kernel will then return several messages (NLM_F_MULTI) containing the
* following tree of nested items:
*
* WGDEVICE_A_IFINDEX: NLA_U32
* WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMESIZ - 1
* WGDEVICE_A_PRIVATE_KEY: len WG_KEY_LEN
* WGDEVICE_A_PUBLIC_KEY: len WG_KEY_LEN
* WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMSIZ - 1
* WGDEVICE_A_PRIVATE_KEY: NLA_EXACT_LEN, len WG_KEY_LEN
* WGDEVICE_A_PUBLIC_KEY: NLA_EXACT_LEN, len WG_KEY_LEN
* WGDEVICE_A_LISTEN_PORT: NLA_U16
* WGDEVICE_A_FWMARK: NLA_U32
* WGDEVICE_A_PEERS: NLA_NESTED
* 0: NLA_NESTED
* WGPEER_A_PUBLIC_KEY: len WG_KEY_LEN
* WGPEER_A_PRESHARED_KEY: len WG_KEY_LEN
* WGPEER_A_ENDPOINT: struct sockaddr_in or struct sockaddr_in6
* WGPEER_A_PUBLIC_KEY: NLA_EXACT_LEN, len WG_KEY_LEN
* WGPEER_A_PRESHARED_KEY: NLA_EXACT_LEN, len WG_KEY_LEN
* WGPEER_A_ENDPOINT: NLA_MIN_LEN(struct sockaddr), struct sockaddr_in or struct sockaddr_in6
* WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL: NLA_U16
* WGPEER_A_LAST_HANDSHAKE_TIME: struct __kernel_timespec
* WGPEER_A_LAST_HANDSHAKE_TIME: NLA_EXACT_LEN, struct __kernel_timespec
* WGPEER_A_RX_BYTES: NLA_U64
* WGPEER_A_TX_BYTES: NLA_U64
* WGPEER_A_ALLOWEDIPS: NLA_NESTED
* 0: NLA_NESTED
* WGALLOWEDIP_A_FAMILY: NLA_U16
* WGALLOWEDIP_A_IPADDR: struct in_addr or struct in6_addr
* WGALLOWEDIP_A_IPADDR: NLA_MIN_LEN(struct in_addr), struct in_addr or struct in6_addr
* WGALLOWEDIP_A_CIDR_MASK: NLA_U8
* 0: NLA_NESTED
* ...
@ -77,7 +77,7 @@
* WGDEVICE_A_IFINDEX and WGDEVICE_A_IFNAME:
*
* WGDEVICE_A_IFINDEX: NLA_U32
* WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMESIZ - 1
* WGDEVICE_A_IFNAME: NLA_NUL_STRING, maxlen IFNAMSIZ - 1
* WGDEVICE_A_FLAGS: NLA_U32, 0 or WGDEVICE_F_REPLACE_PEERS if all current
* peers should be removed prior to adding the list below.
* WGDEVICE_A_PRIVATE_KEY: len WG_KEY_LEN, all zeros to remove
@ -87,10 +87,12 @@
* 0: NLA_NESTED
* WGPEER_A_PUBLIC_KEY: len WG_KEY_LEN
* WGPEER_A_FLAGS: NLA_U32, 0 and/or WGPEER_F_REMOVE_ME if the
* specified peer should be removed rather than
* added/updated and/or WGPEER_F_REPLACE_ALLOWEDIPS
* if all current allowed IPs of this peer should be
* removed prior to adding the list below.
* specified peer should not exist at the end of the
* operation, rather than added/updated and/or
* WGPEER_F_REPLACE_ALLOWEDIPS if all current allowed
* IPs of this peer should be removed prior to adding
* the list below and/or WGPEER_F_UPDATE_ONLY if the
* peer should only be set if it already exists.
* WGPEER_A_PRESHARED_KEY: len WG_KEY_LEN, all zeros to remove
* WGPEER_A_ENDPOINT: struct sockaddr_in or struct sockaddr_in6
* WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL: NLA_U16, 0 to disable
@ -119,7 +121,7 @@
* filling in information not contained in the prior. Note that if
* WGDEVICE_F_REPLACE_PEERS is specified in the first message, it probably
* should not be specified in fragments that come after, so that the list
* of peers is only cleared the first time but appened after. Likewise for
* of peers is only cleared the first time but appended after. Likewise for
* peers, if WGPEER_F_REPLACE_ALLOWEDIPS is specified in the first message
* of a peer, it likely should not be specified in subsequent fragments.
*
@ -142,7 +144,8 @@ enum wg_cmd {
#define WG_CMD_MAX (__WG_CMD_MAX - 1)
enum wgdevice_flag {
WGDEVICE_F_REPLACE_PEERS = 1U << 0
WGDEVICE_F_REPLACE_PEERS = 1U << 0,
__WGDEVICE_F_ALL = WGDEVICE_F_REPLACE_PEERS
};
enum wgdevice_attribute {
WGDEVICE_A_UNSPEC,
@ -160,7 +163,10 @@ enum wgdevice_attribute {
enum wgpeer_flag {
WGPEER_F_REMOVE_ME = 1U << 0,
WGPEER_F_REPLACE_ALLOWEDIPS = 1U << 1
WGPEER_F_REPLACE_ALLOWEDIPS = 1U << 1,
WGPEER_F_UPDATE_ONLY = 1U << 2,
__WGPEER_F_ALL = WGPEER_F_REMOVE_ME | WGPEER_F_REPLACE_ALLOWEDIPS |
WGPEER_F_UPDATE_ONLY
};
enum wgpeer_attribute {
WGPEER_A_UNSPEC,

View File

@ -13,6 +13,7 @@
#include <stdlib.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <linux/if.h>
#include "alloc-util.h"
#include "errno-util.h"
@ -909,7 +910,7 @@ static const char* const ip_tos_table[] = {
DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
bool ifname_valid(const char *p) {
bool ifname_valid_full(const char *p, bool alternative) {
bool numeric = true;
/* Checks whether a network interface name is valid. This is inspired by dev_valid_name() in the kernel sources
@ -919,8 +920,13 @@ bool ifname_valid(const char *p) {
if (isempty(p))
return false;
if (strlen(p) >= IFNAMSIZ)
return false;
if (alternative) {
if (strlen(p) >= ALTIFNAMSIZ)
return false;
} else {
if (strlen(p) >= IFNAMSIZ)
return false;
}
if (dot_or_dot_dot(p))
return false;

View File

@ -130,7 +130,10 @@ int fd_inc_rcvbuf(int fd, size_t n);
int ip_tos_to_string_alloc(int i, char **s);
int ip_tos_from_string(const char *s);
bool ifname_valid(const char *p);
bool ifname_valid_full(const char *p, bool alternative);
static inline bool ifname_valid(const char *p) {
return ifname_valid_full(p, false);
}
bool address_label_valid(const char *p);
int getpeercred(int fd, struct ucred *ucred);

View File

@ -67,7 +67,7 @@ int fopen_temporary(const char *path, FILE **ret_f, char **ret_temp_path) {
/* This is much like mkostemp() but is subject to umask(). */
int mkostemp_safe(char *pattern) {
int fd;
int fd = -1; /* avoid false maybe-uninitialized warning */
assert(pattern);

View File

@ -1163,6 +1163,15 @@ static void read_loader_efi_var(const char *name, char **var) {
log_warning_errno(r, "Failed to read EFI variable %s: %m", name);
}
static void print_yes_no_line(bool first, bool good, const char *name) {
printf("%s%s%s%s %s\n",
first ? " Features: " : " ",
good ? ansi_highlight_green() : ansi_highlight_red(),
good ? special_glyph(SPECIAL_GLYPH_CHECK_MARK) : special_glyph(SPECIAL_GLYPH_CROSS_MARK),
ansi_normal(),
name);
}
static int verb_status(int argc, char *argv[], void *userdata) {
sd_id128_t esp_uuid = SD_ID128_NULL, xbootldr_uuid = SD_ID128_NULL;
int r, k;
@ -1242,18 +1251,15 @@ static int verb_status(int argc, char *argv[], void *userdata) {
printf("Current Boot Loader:\n");
printf(" Product: %s%s%s\n", ansi_highlight(), strna(loader), ansi_normal());
for (i = 0; i < ELEMENTSOF(flags); i++) {
for (i = 0; i < ELEMENTSOF(flags); i++)
print_yes_no_line(i == 0, FLAGS_SET(loader_features, flags[i].flag), flags[i].name);
if (i == 0)
printf(" Features: ");
else
printf(" ");
sd_id128_t bootloader_esp_uuid;
bool have_bootloader_esp_uuid = efi_loader_get_device_part_uuid(&bootloader_esp_uuid) >= 0;
if (FLAGS_SET(loader_features, flags[i].flag))
printf("%s%s%s %s\n", ansi_highlight_green(), special_glyph(SPECIAL_GLYPH_CHECK_MARK), ansi_normal(), flags[i].name);
else
printf("%s%s%s %s\n", ansi_highlight_red(), special_glyph(SPECIAL_GLYPH_CROSS_MARK), ansi_normal(), flags[i].name);
}
print_yes_no_line(false, have_bootloader_esp_uuid, "Boot loader sets ESP partition information");
if (have_bootloader_esp_uuid && !sd_id128_equal(esp_uuid, bootloader_esp_uuid))
printf("WARNING: The boot loader reports different ESP UUID then detected!\n");
if (stub)
printf(" Stub: %s\n", stub);

View File

@ -13,6 +13,7 @@
#include "device-util.h"
#include "dirent-util.h"
#include "dissect-image.h"
#include "dropin.h"
#include "efi-loader.h"
#include "fd-util.h"
#include "fileio.h"
@ -39,6 +40,70 @@ static bool arg_enabled = true;
static bool arg_root_enabled = true;
static int arg_root_rw = -1;
static int open_parent_block_device(dev_t devnum, int *ret_fd) {
_cleanup_(sd_device_unrefp) sd_device *d = NULL;
const char *name, *devtype, *node;
sd_device *parent;
dev_t pn;
int fd, r;
assert(ret_fd);
r = sd_device_new_from_devnum(&d, 'b', devnum);
if (r < 0)
return log_debug_errno(r, "Failed to open device: %m");
if (sd_device_get_devname(d, &name) < 0) {
r = sd_device_get_syspath(d, &name);
if (r < 0) {
log_device_debug_errno(d, r, "Device %u:%u does not have a name, ignoring: %m",
major(devnum), minor(devnum));
return 0;
}
}
r = sd_device_get_parent(d, &parent);
if (r < 0) {
log_device_debug_errno(d, r, "Not a partitioned device, ignoring: %m");
return 0;
}
/* Does it have a devtype? */
r = sd_device_get_devtype(parent, &devtype);
if (r < 0) {
log_device_debug_errno(parent, r, "Parent doesn't have a device type, ignoring: %m");
return 0;
}
/* Is this a disk or a partition? We only care for disks... */
if (!streq(devtype, "disk")) {
log_device_debug(parent, "Parent isn't a raw disk, ignoring.");
return 0;
}
/* Does it have a device node? */
r = sd_device_get_devname(parent, &node);
if (r < 0) {
log_device_debug_errno(parent, r, "Parent device does not have device node, ignoring: %m");
return 0;
}
log_device_debug(d, "Root device %s.", node);
r = sd_device_get_devnum(parent, &pn);
if (r < 0) {
log_device_debug_errno(parent, r, "Parent device is not a proper block device, ignoring: %m");
return 0;
}
fd = open(node, O_RDONLY|O_CLOEXEC|O_NOCTTY);
if (fd < 0)
return log_error_errno(errno, "Failed to open %s: %m", node);
*ret_fd = fd;
return 1;
}
static int add_cryptsetup(const char *id, const char *what, bool rw, bool require, char **device) {
_cleanup_free_ char *e = NULL, *n = NULL, *d = NULL, *id_escaped = NULL, *what_escaped = NULL;
_cleanup_fclose_ FILE *f = NULL;
@ -103,28 +168,25 @@ static int add_cryptsetup(const char *id, const char *what, bool rw, bool requir
if (r < 0)
return r;
if (require) {
const char *dmname;
const char *dmname;
dmname = strjoina("dev-mapper-", e, ".device");
if (require) {
r = generator_add_symlink(arg_dest, "cryptsetup.target", "requires", n);
if (r < 0)
return r;
dmname = strjoina("dev-mapper-", e, ".device");
r = generator_add_symlink(arg_dest, dmname, "requires", n);
if (r < 0)
return r;
}
p = strjoina(arg_dest, "/dev-mapper-", e, ".device.d/50-job-timeout-sec-0.conf");
mkdir_parents_label(p, 0755);
r = write_string_file(p,
"# Automatically generated by systemd-gpt-auto-generator\n\n"
"[Unit]\n"
"JobTimeoutSec=0\n",
WRITE_STRING_FILE_CREATE); /* the binary handles timeouts anyway */
r = write_drop_in_format(arg_dest, dmname, 50, "job-timeout",
"# Automatically generated by systemd-gpt-auto-generator\n\n"
"[Unit]\n"
"JobTimeoutSec=0"); /* the binary handles timeouts anyway */
if (r < 0)
return log_error_errno(r, "Failed to write device drop-in: %m");
log_warning_errno(r, "Failed to write device timeout drop-in, ignoring: %m");
if (device) {
char *ret;
@ -162,7 +224,7 @@ static int add_mount(
assert(where);
assert(description);
log_debug("Adding %s: %s %s", where, what, strna(fstype));
log_debug("Adding %s: %s fstype=%s", where, what, fstype ?: "(any)");
if (streq_ptr(fstype, "crypto_LUKS")) {
@ -530,67 +592,62 @@ static int add_root_rw(DissectedPartition *p) {
return 0;
}
static int open_parent_devno(dev_t devnum, int *ret) {
_cleanup_(sd_device_unrefp) sd_device *d = NULL;
const char *name, *devtype, *node;
sd_device *parent;
dev_t pn;
int fd, r;
#if ENABLE_EFI
static int add_root_cryptsetup(void) {
assert(ret);
/* If a device /dev/gpt-auto-root-luks appears, then make it pull in systemd-cryptsetup-root.service, which
* sets it up, and causes /dev/gpt-auto-root to appear which is all we are looking for. */
r = sd_device_new_from_devnum(&d, 'b', devnum);
if (r < 0)
return log_debug_errno(r, "Failed to open device: %m");
return add_cryptsetup("root", "/dev/gpt-auto-root-luks", true, false, NULL);
}
#endif
if (sd_device_get_devname(d, &name) < 0) {
r = sd_device_get_syspath(d, &name);
if (r < 0) {
log_device_debug_errno(d, r, "Device %u:%u does not have a name, ignoring: %m", major(devnum), minor(devnum));
static int add_root_mount(void) {
#if ENABLE_EFI
int r;
if (!is_efi_boot()) {
log_debug("Not a EFI boot, not creating root mount.");
return 0;
}
r = efi_loader_get_device_part_uuid(NULL);
if (r == -ENOENT) {
log_notice("EFI loader partition unknown, exiting.\n"
"(The boot loader did not set EFI variable LoaderDevicePartUUID.)");
return 0;
} else if (r < 0)
return log_error_errno(r, "Failed to read ESP partition UUID: %m");
/* OK, we have an ESP partition, this is fantastic, so let's
* wait for a root device to show up. A udev rule will create
* the link for us under the right name. */
if (in_initrd()) {
r = generator_write_initrd_root_device_deps(arg_dest, "/dev/gpt-auto-root");
if (r < 0)
return 0;
}
r = add_root_cryptsetup();
if (r < 0)
return r;
}
r = sd_device_get_parent(d, &parent);
if (r < 0) {
log_device_debug_errno(d, r, "Not a partitioned device, ignoring: %m");
return 0;
}
/* Note that we do not need to enable systemd-remount-fs.service here. If
* /etc/fstab exists, systemd-fstab-generator will pull it in for us. */
/* Does it have a devtype? */
r = sd_device_get_devtype(parent, &devtype);
if (r < 0) {
log_device_debug_errno(parent, r, "Parent doesn't have a device type, ignoring: %m");
return 0;
}
/* Is this a disk or a partition? We only care for disks... */
if (!streq(devtype, "disk")) {
log_device_debug(parent, "Parent isn't a raw disk, ignoring.");
return 0;
}
/* Does it have a device node? */
r = sd_device_get_devname(parent, &node);
if (r < 0) {
log_device_debug_errno(parent, r, "Parent device does not have device node, ignoring: %m");
return 0;
}
log_device_debug(d, "Root device %s.", node);
r = sd_device_get_devnum(parent, &pn);
if (r < 0) {
log_device_debug_errno(parent, r, "Parent device is not a proper block device, ignoring: %m");
return 0;
}
fd = open(node, O_RDONLY|O_CLOEXEC|O_NOCTTY);
if (fd < 0)
return log_error_errno(errno, "Failed to open %s: %m", node);
*ret = fd;
return 1;
return add_mount(
"root",
"/dev/gpt-auto-root",
in_initrd() ? "/sysroot" : "/",
NULL,
arg_root_rw > 0,
NULL,
"Root Partition",
in_initrd() ? SPECIAL_INITRD_ROOT_FS_TARGET : SPECIAL_LOCAL_FS_TARGET);
#else
return 0;
#endif
}
static int enumerate_partitions(dev_t devnum) {
@ -598,7 +655,7 @@ static int enumerate_partitions(dev_t devnum) {
_cleanup_(dissected_image_unrefp) DissectedImage *m = NULL;
int r, k;
r = open_parent_devno(devnum, &fd);
r = open_parent_block_device(devnum, &fd);
if (r <= 0)
return r;
@ -649,105 +706,6 @@ static int enumerate_partitions(dev_t devnum) {
return r;
}
static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
int r;
assert(key);
if (proc_cmdline_key_streq(key, "systemd.gpt_auto") ||
proc_cmdline_key_streq(key, "rd.systemd.gpt_auto")) {
r = value ? parse_boolean(value) : 1;
if (r < 0)
log_warning_errno(r, "Failed to parse gpt-auto switch \"%s\", ignoring: %m", value);
else
arg_enabled = r;
} else if (proc_cmdline_key_streq(key, "root")) {
if (proc_cmdline_value_missing(key, value))
return 0;
/* Disable root disk logic if there's a root= value
* specified (unless it happens to be "gpt-auto") */
arg_root_enabled = streq(value, "gpt-auto");
} else if (proc_cmdline_key_streq(key, "roothash")) {
if (proc_cmdline_value_missing(key, value))
return 0;
/* Disable root disk logic if there's roothash= defined (i.e. verity enabled) */
arg_root_enabled = false;
} else if (proc_cmdline_key_streq(key, "rw") && !value)
arg_root_rw = true;
else if (proc_cmdline_key_streq(key, "ro") && !value)
arg_root_rw = false;
return 0;
}
#if ENABLE_EFI
static int add_root_cryptsetup(void) {
/* If a device /dev/gpt-auto-root-luks appears, then make it pull in systemd-cryptsetup-root.service, which
* sets it up, and causes /dev/gpt-auto-root to appear which is all we are looking for. */
return add_cryptsetup("root", "/dev/gpt-auto-root-luks", true, false, NULL);
}
#endif
static int add_root_mount(void) {
#if ENABLE_EFI
int r;
if (!is_efi_boot()) {
log_debug("Not a EFI boot, not creating root mount.");
return 0;
}
r = efi_loader_get_device_part_uuid(NULL);
if (r == -ENOENT) {
log_debug("EFI loader partition unknown, exiting.");
return 0;
} else if (r < 0)
return log_error_errno(r, "Failed to read ESP partition UUID: %m");
/* OK, we have an ESP partition, this is fantastic, so let's
* wait for a root device to show up. A udev rule will create
* the link for us under the right name. */
if (in_initrd()) {
r = generator_write_initrd_root_device_deps(arg_dest, "/dev/gpt-auto-root");
if (r < 0)
return 0;
r = add_root_cryptsetup();
if (r < 0)
return r;
}
/* Note that we do not need to enable systemd-remount-fs.service here. If
* /etc/fstab exists, systemd-fstab-generator will pull it in for us. */
return add_mount(
"root",
"/dev/gpt-auto-root",
in_initrd() ? "/sysroot" : "/",
NULL,
arg_root_rw > 0,
NULL,
"Root Partition",
in_initrd() ? SPECIAL_INITRD_ROOT_FS_TARGET : SPECIAL_LOCAL_FS_TARGET);
#else
return 0;
#endif
}
static int add_mounts(void) {
dev_t devno;
int r;
@ -785,6 +743,50 @@ static int add_mounts(void) {
return enumerate_partitions(devno);
}
static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
int r;
assert(key);
if (proc_cmdline_key_streq(key, "systemd.gpt_auto") ||
proc_cmdline_key_streq(key, "rd.systemd.gpt_auto")) {
r = value ? parse_boolean(value) : 1;
if (r < 0)
log_warning_errno(r, "Failed to parse gpt-auto switch \"%s\", ignoring: %m", value);
else
arg_enabled = r;
} else if (proc_cmdline_key_streq(key, "root")) {
if (proc_cmdline_value_missing(key, value))
return 0;
/* Disable root disk logic if there's a root= value
* specified (unless it happens to be "gpt-auto") */
if (!streq(value, "gpt-auto")) {
arg_root_enabled = false;
log_debug("Disabling root partition auto-detection, root= is defined.");
}
} else if (proc_cmdline_key_streq(key, "roothash")) {
if (proc_cmdline_value_missing(key, value))
return 0;
/* Disable root disk logic if there's roothash= defined (i.e. verity enabled) */
arg_root_enabled = false;
} else if (proc_cmdline_key_streq(key, "rw") && !value)
arg_root_rw = true;
else if (proc_cmdline_key_streq(key, "ro") && !value)
arg_root_rw = false;
return 0;
}
static int run(const char *dest, const char *dest_early, const char *dest_late) {
int r, k;

View File

@ -103,6 +103,18 @@ static bool net_condition_test_strv(char * const *patterns, const char *string)
return has_positive_rule ? match : true;
}
static bool net_condition_test_ifname(char * const *patterns, const char *ifname, char * const *alternative_names) {
if (net_condition_test_strv(patterns, ifname))
return true;
char * const *p;
STRV_FOREACH(p, alternative_names)
if (net_condition_test_strv(patterns, *p))
return true;
return false;
}
static int net_condition_test_property(char * const *match_property, sd_device *device) {
char * const *p;
@ -166,6 +178,7 @@ bool net_match_config(Set *match_mac,
sd_device *device,
const struct ether_addr *dev_mac,
const char *dev_name,
char * const *alternative_names,
enum nl80211_iftype wifi_iftype,
const char *ssid,
const struct ether_addr *bssid) {
@ -196,7 +209,7 @@ bool net_match_config(Set *match_mac,
if (!net_condition_test_strv(match_types, dev_type))
return false;
if (!net_condition_test_strv(match_names, dev_name))
if (!net_condition_test_ifname(match_names, dev_name, alternative_names))
return false;
if (!net_condition_test_property(match_property, device))
@ -349,7 +362,7 @@ int config_parse_match_ifnames(
return 0;
}
if (!ifname_valid(word)) {
if (!ifname_valid_full(word, ltype)) {
log_syntax(unit, LOG_ERR, filename, line, 0,
"Interface name is not valid or too long, ignoring assignment: %s", word);
continue;

View File

@ -27,6 +27,7 @@ bool net_match_config(Set *match_mac,
sd_device *device,
const struct ether_addr *dev_mac,
const char *dev_name,
char * const *alternative_names,
enum nl80211_iftype wifi_iftype,
const char *ssid,
const struct ether_addr *bssid);

View File

@ -8,11 +8,12 @@
#include "alloc-util.h"
#include "format-util.h"
#include "memory-util.h"
#include "netlink-internal.h"
#include "netlink-types.h"
#include "netlink-util.h"
#include "socket-util.h"
#include "memory-util.h"
#include "strv.h"
#define GET_CONTAINER(m, i) ((i) < (m)->n_containers ? (struct rtattr*)((uint8_t*)(m)->hdr + (m)->containers[i].offset) : NULL)
#define PUSH_CONTAINER(m, new) (m)->container_offsets[(m)->n_containers++] = (uint8_t*)(new) - (uint8_t*)(m)->hdr;
@ -86,7 +87,8 @@ int sd_netlink_message_request_dump(sd_netlink_message *m, int dump) {
assert_return(m, -EINVAL);
assert_return(m->hdr, -EINVAL);
assert_return(IN_SET(m->hdr->nlmsg_type, RTM_GETLINK, RTM_GETADDR, RTM_GETROUTE, RTM_GETNEIGH,
assert_return(IN_SET(m->hdr->nlmsg_type,
RTM_GETLINK, RTM_GETLINKPROP, RTM_GETADDR, RTM_GETROUTE, RTM_GETNEIGH,
RTM_GETRULE, RTM_GETADDRLABEL, RTM_GETNEXTHOP), -EINVAL);
SET_FLAG(m->hdr->nlmsg_flags, NLM_F_DUMP, dump);
@ -248,6 +250,35 @@ int sd_netlink_message_append_string(sd_netlink_message *m, unsigned short type,
return 0;
}
int sd_netlink_message_append_strv(sd_netlink_message *m, unsigned short type, char * const *data) {
size_t length, size;
char * const *p;
int r;
assert_return(m, -EINVAL);
assert_return(!m->sealed, -EPERM);
assert_return(data, -EINVAL);
r = message_attribute_has_type(m, &size, type, NETLINK_TYPE_STRING);
if (r < 0)
return r;
STRV_FOREACH(p, data) {
if (size) {
length = strnlen(*p, size+1);
if (length > size)
return -EINVAL;
} else
length = strlen(*p);
r = add_rtattr(m, type, *p, length + 1);
if (r < 0)
return r;
}
return 0;
}
int sd_netlink_message_append_flag(sd_netlink_message *m, unsigned short type) {
size_t size;
int r;
@ -827,6 +858,63 @@ int sd_netlink_message_read_in6_addr(sd_netlink_message *m, unsigned short type,
return 0;
}
int sd_netlink_message_read_strv(sd_netlink_message *m, unsigned short container_type, unsigned short type_id, char ***ret) {
_cleanup_strv_free_ char **s = NULL;
const NLTypeSystem *type_system;
const NLType *nl_type;
struct rtattr *rta;
void *container;
unsigned short rt_len;
int r;
assert_return(m, -EINVAL);
assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -EINVAL);
r = type_system_get_type(m->containers[m->n_containers].type_system,
&nl_type,
container_type);
if (r < 0)
return r;
if (type_get_type(nl_type) != NETLINK_TYPE_NESTED)
return -EINVAL;
r = type_system_get_type_system(m->containers[m->n_containers].type_system,
&type_system,
container_type);
if (r < 0)
return r;
r = type_system_get_type(type_system, &nl_type, type_id);
if (r < 0)
return r;
if (type_get_type(nl_type) != NETLINK_TYPE_STRING)
return -EINVAL;
r = netlink_message_read_internal(m, container_type, &container, NULL);
if (r < 0)
return r;
rt_len = (unsigned short) r;
rta = container;
for (; RTA_OK(rta, rt_len); rta = RTA_NEXT(rta, rt_len)) {
unsigned short type;
type = RTA_TYPE(rta);
if (type != type_id)
continue;
r = strv_extend(&s, RTA_DATA(rta));
if (r < 0)
return r;
}
*ret = TAKE_PTR(s);
return 0;
}
static int netlink_container_parse(sd_netlink_message *m,
struct netlink_container *container,
struct rtattr *rta,

View File

@ -527,6 +527,15 @@ static const NLTypeSystem rtnl_af_spec_type_system = {
.types = rtnl_af_spec_types,
};
static const NLType rtnl_prop_list_types[] = {
[IFLA_ALT_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = ALTIFNAMSIZ - 1 },
};
static const NLTypeSystem rtnl_prop_list_type_system = {
.count = ELEMENTSOF(rtnl_prop_list_types),
.types = rtnl_prop_list_types,
};
static const NLType rtnl_link_types[] = {
[IFLA_ADDRESS] = { .type = NETLINK_TYPE_ETHER_ADDR },
[IFLA_BROADCAST] = { .type = NETLINK_TYPE_ETHER_ADDR },
@ -581,8 +590,9 @@ static const NLType rtnl_link_types[] = {
/*
[IFLA_PHYS_PORT_ID] = { .type = NETLINK_TYPE_BINARY, .len = MAX_PHYS_PORT_ID_LEN },
*/
[IFLA_MIN_MTU] = { .type = NETLINK_TYPE_U32 },
[IFLA_MAX_MTU] = { .type = NETLINK_TYPE_U32 },
[IFLA_MIN_MTU] = { .type = NETLINK_TYPE_U32 },
[IFLA_MAX_MTU] = { .type = NETLINK_TYPE_U32 },
[IFLA_PROP_LIST] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_prop_list_type_system },
};
static const NLTypeSystem rtnl_link_type_system = {
@ -824,6 +834,9 @@ static const NLType rtnl_types[] = {
[RTM_DELLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
[RTM_GETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
[RTM_SETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
[RTM_NEWLINKPROP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
[RTM_DELLINKPROP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
[RTM_GETLINKPROP] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) },
[RTM_NEWADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
[RTM_DELADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },
[RTM_GETADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) },

View File

@ -4,6 +4,7 @@
#include "netlink-internal.h"
#include "netlink-util.h"
#include "strv.h"
int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
@ -83,6 +84,45 @@ int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias,
return 0;
}
int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const *alternative_names) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
int r;
assert(rtnl);
assert(ifindex > 0);
if (strv_isempty(alternative_names))
return 0;
if (!*rtnl) {
r = sd_netlink_open(rtnl);
if (r < 0)
return r;
}
r = sd_rtnl_message_new_link(*rtnl, &message, RTM_NEWLINKPROP, ifindex);
if (r < 0)
return r;
r = sd_netlink_message_open_container(message, IFLA_PROP_LIST);
if (r < 0)
return r;
r = sd_netlink_message_append_strv(message, IFLA_ALT_IFNAME, alternative_names);
if (r < 0)
return r;
r = sd_netlink_message_close_container(message);
if (r < 0)
return r;
r = sd_netlink_call(*rtnl, message, 0, NULL);
if (r < 0)
return r;
return 0;
}
int rtnl_message_new_synthetic_error(sd_netlink *rtnl, int error, uint32_t serial, sd_netlink_message **ret) {
struct nlmsgerr *err;
int r;

View File

@ -26,7 +26,9 @@ static inline bool rtnl_message_type_is_nexthop(uint16_t type) {
}
static inline bool rtnl_message_type_is_link(uint16_t type) {
return IN_SET(type, RTM_NEWLINK, RTM_SETLINK, RTM_GETLINK, RTM_DELLINK);
return IN_SET(type,
RTM_NEWLINK, RTM_SETLINK, RTM_GETLINK, RTM_DELLINK,
RTM_NEWLINKPROP, RTM_DELLINKPROP, RTM_GETLINKPROP);
}
static inline bool rtnl_message_type_is_addr(uint16_t type) {
@ -47,6 +49,7 @@ static inline bool rtnl_message_type_is_qdisc(uint16_t type) {
int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name);
int rtnl_set_link_properties(sd_netlink **rtnl, int ifindex, const char *alias, const struct ether_addr *mac, uint32_t mtu);
int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const *alternative_names);
int rtnl_log_parse_error(int r);
int rtnl_log_create_error(int r);

View File

@ -512,6 +512,8 @@ int sd_rtnl_message_new_link(sd_netlink *rtnl, sd_netlink_message **ret,
if (nlmsg_type == RTM_NEWLINK)
(*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL;
else if (nlmsg_type == RTM_NEWLINK)
(*ret)->hdr->nlmsg_flags |= NLM_F_EXCL | NLM_F_CREATE | NLM_F_APPEND;
ifi = NLMSG_DATA((*ret)->hdr);

View File

@ -13,6 +13,7 @@
#include "socket-util.h"
#include "stdio-util.h"
#include "string-util.h"
#include "strv.h"
#include "util.h"
static void test_message_link_bridge(sd_netlink *rtnl) {
@ -547,7 +548,36 @@ static void test_array(void) {
assert_se(streq(name, expected));
}
assert_se(sd_netlink_message_exit_container(m) >= 0);
}
static void test_strv(sd_netlink *rtnl) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
_cleanup_strv_free_ char **names_in = NULL, **names_out;
const char *p;
assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINKPROP, 1) >= 0);
for (unsigned i = 0; i < 10; i++) {
char name[STRLEN("hoge") + DECIMAL_STR_MAX(uint32_t)];
xsprintf(name, "hoge%" PRIu32, i + 1000);
assert_se(strv_extend(&names_in, name) >= 0);
}
assert_se(sd_netlink_message_open_container(m, IFLA_PROP_LIST) >= 0);
assert_se(sd_netlink_message_append_strv(m, IFLA_ALT_IFNAME, names_in) >= 0);
assert_se(sd_netlink_message_close_container(m) >= 0);
rtnl_message_seal(m);
assert_se(sd_netlink_message_rewind(m, NULL) >= 0);
assert_se(sd_netlink_message_read_strv(m, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &names_out) >= 0);
assert_se(strv_equal(names_in, names_out));
assert_se(sd_netlink_message_enter_container(m, IFLA_PROP_LIST) >= 0);
assert_se(sd_netlink_message_read_string(m, IFLA_ALT_IFNAME, &p) >= 0);
assert_se(streq(p, "hoge1009"));
assert_se(sd_netlink_message_exit_container(m) >= 0);
}
int main(void) {
@ -568,6 +598,7 @@ int main(void) {
test_message(rtnl);
test_container(rtnl);
test_array();
test_strv(rtnl);
if_loopback = (int) if_nametoindex("lo");
assert_se(if_loopback > 0);

View File

@ -139,6 +139,7 @@ typedef struct LinkInfo {
uint32_t max_mtu;
uint32_t tx_queues;
uint32_t rx_queues;
char **alternative_names;
union {
struct rtnl_link_stats64 stats64;
@ -191,6 +192,7 @@ static const LinkInfo* link_info_array_free(LinkInfo *array) {
for (unsigned i = 0; array && array[i].needs_freeing; i++) {
sd_device_unref(array[i].sd_device);
free(array[i].ssid);
strv_free(array[i].alternative_names);
}
return mfree(array);
@ -304,6 +306,7 @@ static int decode_link(sd_netlink_message *m, LinkInfo *info, char **patterns) {
(void) sd_netlink_message_read_u32(m, IFLA_MTU, &info->mtu);
(void) sd_netlink_message_read_u32(m, IFLA_MIN_MTU, &info->min_mtu);
(void) sd_netlink_message_read_u32(m, IFLA_MAX_MTU, &info->max_mtu);
(void) sd_netlink_message_read_strv(m, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &info->alternative_names);
info->has_rx_queues =
sd_netlink_message_read_u32(m, IFLA_NUM_RX_QUEUES, &info->rx_queues) >= 0 &&
@ -1063,6 +1066,7 @@ static int link_status_one(
_cleanup_free_ int *carrier_bound_to = NULL, *carrier_bound_by = NULL;
_cleanup_(table_unrefp) Table *table = NULL;
TableCell *cell;
char **p;
int r;
assert(rtnl);
@ -1144,6 +1148,18 @@ static int link_status_one(
if (r < 0)
return r;
STRV_FOREACH(p, info->alternative_names)
if (p == info->alternative_names)
r = table_add_many(table,
TABLE_EMPTY,
TABLE_STRING, "Alternative Names:",
TABLE_STRING, *p);
else
r = table_add_many(table,
TABLE_EMPTY,
TABLE_EMPTY,
TABLE_STRING, *p);
if (path) {
r = table_add_many(table,
TABLE_EMPTY,

View File

@ -180,7 +180,9 @@ int br_vlan_configure(Link *link, uint16_t pvid, uint32_t *br_vid_bitmap, uint32
/* master needs flag self */
if (!link->network->bridge) {
flags = BRIDGE_FLAGS_SELF;
sd_netlink_message_append_data(req, IFLA_BRIDGE_FLAGS, &flags, sizeof(uint16_t));
r = sd_netlink_message_append_data(req, IFLA_BRIDGE_FLAGS, &flags, sizeof(uint16_t));
if (r < 0)
return log_link_error_errno(link, r, "Could not open IFLA_BRIDGE_FLAGS: %m");
}
/* add vlan info */

View File

@ -542,10 +542,10 @@ static int link_update_flags(Link *link, sd_netlink_message *m, bool force_updat
static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
_cleanup_(link_unrefp) Link *link = NULL;
uint16_t type;
const char *ifname, *kind = NULL;
int r, ifindex;
unsigned short iftype;
int r, ifindex;
uint16_t type;
assert(manager);
assert(message);
@ -617,6 +617,10 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) {
if (r < 0)
log_link_debug_errno(link, r, "MAC address not found for new device, continuing without");
r = sd_netlink_message_read_strv(message, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &link->alternative_names);
if (r < 0 && r != -ENODATA)
return r;
if (asprintf(&link->state_file, "/run/systemd/netif/links/%d", link->ifindex) < 0)
return -ENOMEM;
@ -713,6 +717,7 @@ static Link *link_free(Link *link) {
free(link->lldp_file);
free(link->ifname);
strv_free(link->alternative_names);
free(link->kind);
free(link->ssid);
@ -2934,14 +2939,28 @@ static int link_configure_duid(Link *link) {
return 0;
}
int link_reconfigure(Link *link, bool force) {
static int link_reconfigure_internal(Link *link, sd_netlink_message *m, bool force) {
Network *network;
int r;
if (IN_SET(link->state, LINK_STATE_PENDING, LINK_STATE_LINGER))
return 0;
r = network_get(link->manager, link->sd_device, link->ifname,
if (m) {
_cleanup_strv_free_ char **s = NULL;
r = sd_netlink_message_get_errno(m);
if (r < 0)
return r;
r = sd_netlink_message_read_strv(m, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &s);
if (r < 0 && r != -ENODATA)
return r;
strv_free_and_replace(link->alternative_names, s);
}
r = network_get(link->manager, link->sd_device, link->ifname, link->alternative_names,
&link->mac, link->wlan_iftype, link->ssid, &link->bssid, &network);
if (r == -ENOENT) {
link_enter_unmanaged(link);
@ -2959,10 +2978,8 @@ int link_reconfigure(Link *link, bool force) {
/* Dropping old .network file */
r = link_stop_clients(link, false);
if (r < 0) {
link_enter_failed(link);
if (r < 0)
return r;
}
if (link_dhcp4_server_enabled(link))
(void) sd_dhcp_server_stop(link->dhcp_server);
@ -3006,6 +3023,46 @@ int link_reconfigure(Link *link, bool force) {
return 0;
}
static int link_reconfigure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
r = link_reconfigure_internal(link, m, false);
if (r < 0)
link_enter_failed(link);
return 1;
}
static int link_force_reconfigure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
r = link_reconfigure_internal(link, m, true);
if (r < 0)
link_enter_failed(link);
return 1;
}
int link_reconfigure(Link *link, bool force) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
int r;
r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_GETLINK,
link->ifindex);
if (r < 0)
return r;
r = netlink_call_async(link->manager->rtnl, NULL, req,
force ? link_force_reconfigure_handler : link_reconfigure_handler,
link_netlink_destroy_callback, link);
if (r < 0)
return r;
link_ref(link);
return 0;
}
static int link_initialized_and_synced(Link *link) {
Network *network;
int r;
@ -3035,7 +3092,7 @@ static int link_initialized_and_synced(Link *link) {
if (r < 0)
return r;
r = network_get(link->manager, link->sd_device, link->ifname,
r = network_get(link->manager, link->sd_device, link->ifname, link->alternative_names,
&link->mac, link->wlan_iftype, link->ssid, &link->bssid, &network);
if (r == -ENOENT) {
link_enter_unmanaged(link);
@ -3080,8 +3137,23 @@ static int link_initialized_and_synced(Link *link) {
}
static int link_initialized_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
_cleanup_strv_free_ char **s = NULL;
int r;
r = sd_netlink_message_get_errno(m);
if (r < 0) {
link_enter_failed(link);
return 0;
}
r = sd_netlink_message_read_strv(m, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &s);
if (r < 0 && r != -ENODATA) {
link_enter_failed(link);
return 0;
}
strv_free_and_replace(link->alternative_names, s);
r = link_initialized_and_synced(link);
if (r < 0)
link_enter_failed(link);
@ -3414,9 +3486,11 @@ static int link_carrier_gained(Link *link) {
if (r < 0)
return r;
if (r > 0) {
r = link_reconfigure(link, false);
if (r < 0)
r = link_reconfigure_internal(link, NULL, false);
if (r < 0) {
link_enter_failed(link);
return r;
}
}
if (IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED)) {
@ -3520,6 +3594,7 @@ static int link_admin_state_up(Link *link) {
}
int link_update(Link *link, sd_netlink_message *m) {
_cleanup_strv_free_ char **s = NULL;
struct ether_addr mac;
const char *ifname;
uint32_t mtu;
@ -3551,6 +3626,10 @@ int link_update(Link *link, sd_netlink_message *m) {
return r;
}
r = sd_netlink_message_read_strv(m, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &s);
if (r >= 0)
strv_free_and_replace(link->alternative_names, s);
r = sd_netlink_message_read_u32(m, IFLA_MTU, &mtu);
if (r >= 0 && mtu > 0) {
link->mtu = mtu;

View File

@ -48,6 +48,7 @@ typedef struct Link {
int ifindex;
int master_ifindex;
char *ifname;
char **alternative_names;
char *kind;
unsigned short iftype;
char *state_file;

View File

@ -34,7 +34,7 @@ Match.Type, config_parse_match_strv,
Match.WLANInterfaceType, config_parse_match_strv, 0, offsetof(Network, match_wlan_iftype)
Match.SSID, config_parse_match_strv, 0, offsetof(Network, match_ssid)
Match.BSSID, config_parse_hwaddrs, 0, offsetof(Network, match_bssid)
Match.Name, config_parse_match_ifnames, 0, offsetof(Network, match_name)
Match.Name, config_parse_match_ifnames, 1, offsetof(Network, match_name)
Match.Property, config_parse_match_property, 0, offsetof(Network, match_property)
Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(Network, conditions)
Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(Network, conditions)

View File

@ -718,7 +718,7 @@ int network_get_by_name(Manager *manager, const char *name, Network **ret) {
}
int network_get(Manager *manager, sd_device *device,
const char *ifname, const struct ether_addr *address,
const char *ifname, char * const *alternative_names, const struct ether_addr *address,
enum nl80211_iftype wlan_iftype, const char *ssid, const struct ether_addr *bssid,
Network **ret) {
Network *network;
@ -731,7 +731,7 @@ int network_get(Manager *manager, sd_device *device,
if (net_match_config(network->match_mac, network->match_path, network->match_driver,
network->match_type, network->match_name, network->match_property,
network->match_wlan_iftype, network->match_ssid, network->match_bssid,
device, address, ifname, wlan_iftype, ssid, bssid)) {
device, address, ifname, alternative_names, wlan_iftype, ssid, bssid)) {
if (network->match_name && device) {
const char *attr;
uint8_t name_assign_type = NET_NAME_UNKNOWN;

View File

@ -297,8 +297,9 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
int network_verify(Network *network);
int network_get_by_name(Manager *manager, const char *name, Network **ret);
int network_get(Manager *manager, sd_device *device, const char *ifname, const struct ether_addr *mac,
enum nl80211_iftype wlan_iftype, const char *ssid, const struct ether_addr *bssid, Network **ret);
int network_get(Manager *manager, sd_device *device, const char *ifname, char * const *alternative_names,
const struct ether_addr *mac, enum nl80211_iftype wlan_iftype, const char *ssid,
const struct ether_addr *bssid, Network **ret);
int network_apply(Network *network, Link *link);
void network_apply_anonymize_if_set(Network *network);

View File

@ -125,7 +125,7 @@ static void test_network_get(Manager *manager, sd_device *loopback) {
/* let's assume that the test machine does not have a .network file
that applies to the loopback device... */
assert_se(network_get(manager, loopback, "lo", &mac, 0, NULL, NULL, &network) == -ENOENT);
assert_se(network_get(manager, loopback, "lo", NULL, &mac, 0, NULL, NULL, &network) == -ENOENT);
assert_se(!network);
}

View File

@ -985,6 +985,66 @@ int config_parse_ifname(
return 0;
}
int config_parse_ifnames(
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_strv_free_ char **names = NULL;
char ***s = data;
const char *p;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
if (isempty(rvalue)) {
*s = strv_free(*s);
return 0;
}
p = rvalue;
for (;;) {
_cleanup_free_ char *word = NULL;
r = extract_first_word(&p, &word, NULL, 0);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to extract interface name, ignoring assignment: %s",
rvalue);
return 0;
}
if (r == 0)
break;
if (!ifname_valid_full(word, ltype)) {
log_syntax(unit, LOG_ERR, filename, line, 0,
"Interface name is not valid or too long, ignoring assignment: %s",
word);
continue;
}
r = strv_consume(&names, TAKE_PTR(word));
if (r < 0)
return log_oom();
}
r = strv_extend_strv(s, names, true);
if (r < 0)
return log_oom();
return 0;
}
int config_parse_ip_port(
const char *unit,
const char *filename,

View File

@ -137,6 +137,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_signal);
CONFIG_PARSER_PROTOTYPE(config_parse_personality);
CONFIG_PARSER_PROTOTYPE(config_parse_permille);
CONFIG_PARSER_PROTOTYPE(config_parse_ifname);
CONFIG_PARSER_PROTOTYPE(config_parse_ifnames);
CONFIG_PARSER_PROTOTYPE(config_parse_ip_port);
CONFIG_PARSER_PROTOTYPE(config_parse_mtu);
CONFIG_PARSER_PROTOTYPE(config_parse_rlimit);

View File

@ -562,17 +562,20 @@ int efi_loader_get_boot_usec(usec_t *firmware, usec_t *loader) {
r = read_usec(EFI_VENDOR_LOADER, "LoaderTimeInitUSec", &x);
if (r < 0)
return r;
return log_debug_errno(r, "Failed to read LoaderTimeInitUSec: %m");
r = read_usec(EFI_VENDOR_LOADER, "LoaderTimeExecUSec", &y);
if (r < 0)
return r;
return log_debug_errno(r, "Failed to read LoaderTimeExecUSec: %m");
if (y == 0 || y < x)
return -EIO;
return log_debug_errno(SYNTHETIC_ERRNO(EIO),
"Bad LoaderTimeInitUSec=%"PRIu64", LoaderTimeExecUSec=%" PRIu64"; refusing.",
x, y);
if (y > USEC_PER_HOUR)
return -EIO;
return log_debug_errno(SYNTHETIC_ERRNO(EIO),
"LoaderTimeExecUSec=%"PRIu64" too large, refusing.", x);
*firmware = x;
*loader = y;

View File

@ -11,6 +11,7 @@
#include <linux/loop.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include "alloc-util.h"
#include "fd-util.h"
@ -19,6 +20,14 @@
#include "parse-util.h"
#include "stat-util.h"
#include "stdio-util.h"
#include "string-util.h"
static void cleanup_clear_loop_close(int *fd) {
if (*fd >= 0) {
(void) ioctl(*fd, LOOP_CLR_FD);
(void) safe_close(*fd);
}
}
int loop_device_make_full(
int fd,
@ -28,9 +37,7 @@ int loop_device_make_full(
uint32_t loop_flags,
LoopDevice **ret) {
_cleanup_close_ int control = -1, loop = -1;
_cleanup_free_ char *loopdev = NULL;
unsigned n_attempts = 0;
struct loop_info64 info;
LoopDevice *d = NULL;
struct stat st;
@ -44,7 +51,7 @@ int loop_device_make_full(
return -errno;
if (S_ISBLK(st.st_mode)) {
if (ioctl(loop, LOOP_GET_STATUS64, &info) >= 0) {
if (ioctl(fd, LOOP_GET_STATUS64, &info) >= 0) {
/* Oh! This is a loopback device? That's interesting! */
#if HAVE_VALGRIND_MEMCHECK_H
@ -58,7 +65,7 @@ int loop_device_make_full(
}
if (offset == 0 && IN_SET(size, 0, UINT64_MAX)) {
int copy;
_cleanup_close_ int copy = -1;
/* If this is already a block device, store a copy of the fd as it is */
@ -69,9 +76,8 @@ int loop_device_make_full(
d = new(LoopDevice, 1);
if (!d)
return -ENOMEM;
*d = (LoopDevice) {
.fd = copy,
.fd = TAKE_FD(copy),
.nr = nr,
.node = TAKE_PTR(loopdev),
.relinquished = true, /* It's not allocated by us, don't destroy it when this object is freed */
@ -86,13 +92,18 @@ int loop_device_make_full(
return r;
}
_cleanup_close_ int control = -1;
_cleanup_(cleanup_clear_loop_close) int loop_with_fd = -1;
control = open("/dev/loop-control", O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
if (control < 0)
return -errno;
/* Loop around LOOP_CTL_GET_FREE, since at the moment we attempt to open the returned device it might
* be gone already, taken by somebody else racing against us. */
for (;;) {
for (unsigned n_attempts = 0;;) {
_cleanup_close_ int loop = -1;
nr = ioctl(control, LOOP_CTL_GET_FREE);
if (nr < 0)
return -errno;
@ -101,19 +112,24 @@ int loop_device_make_full(
return -ENOMEM;
loop = open(loopdev, O_CLOEXEC|O_NONBLOCK|O_NOCTTY|open_flags);
if (loop < 0)
return -errno;
if (ioctl(loop, LOOP_SET_FD, fd) < 0) {
if (loop < 0) {
/* Somebody might've gotten the same number from the kernel, used the device,
* and called LOOP_CTL_REMOVE on it. Let's retry with a new number. */
if (errno != ENOENT)
return -errno;
} else {
if (ioctl(loop, LOOP_SET_FD, fd) >= 0) {
loop_with_fd = TAKE_FD(loop);
break;
}
if (errno != EBUSY)
return -errno;
}
if (++n_attempts >= 64) /* Give up eventually */
return -EBUSY;
} else
break;
if (++n_attempts >= 64) /* Give up eventually */
return -EBUSY;
loopdev = mfree(loopdev);
loop = safe_close(loop);
}
info = (struct loop_info64) {
@ -123,33 +139,20 @@ int loop_device_make_full(
.lo_sizelimit = size == UINT64_MAX ? 0 : size,
};
if (ioctl(loop, LOOP_SET_STATUS64, &info) < 0) {
r = -errno;
goto fail;
}
if (ioctl(loop_with_fd, LOOP_SET_STATUS64, &info) < 0)
return -errno;
d = new(LoopDevice, 1);
if (!d) {
r = -ENOMEM;
goto fail;
}
if (!d)
return -ENOMEM;
*d = (LoopDevice) {
.fd = TAKE_FD(loop),
.fd = TAKE_FD(loop_with_fd),
.node = TAKE_PTR(loopdev),
.nr = nr,
};
*ret = d;
return d->fd;
fail:
if (fd >= 0)
(void) ioctl(fd, LOOP_CLR_FD);
if (d && d->fd >= 0)
(void) ioctl(d->fd, LOOP_CLR_FD);
return r;
return 0;
}
int loop_device_make_by_path(const char *path, int open_flags, uint32_t loop_flags, LoopDevice **ret) {
@ -163,7 +166,7 @@ int loop_device_make_by_path(const char *path, int open_flags, uint32_t loop_fla
if (fd < 0)
return -errno;
return loop_device_make(fd, open_flags, loop_flags, ret);
return loop_device_make_full(fd, open_flags, 0, 0, loop_flags, ret);
}
LoopDevice* loop_device_unref(LoopDevice *d) {
@ -171,7 +174,6 @@ LoopDevice* loop_device_unref(LoopDevice *d) {
return NULL;
if (d->fd >= 0) {
if (d->nr >= 0 && !d->relinquished) {
if (ioctl(d->fd, LOOP_CLR_FD) < 0)
log_debug_errno(errno, "Failed to clear loop device: %m");
@ -186,11 +188,19 @@ LoopDevice* loop_device_unref(LoopDevice *d) {
control = open("/dev/loop-control", O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
if (control < 0)
log_debug_errno(errno, "Failed to open loop control device: %m");
else {
if (ioctl(control, LOOP_CTL_REMOVE, d->nr) < 0)
log_debug_errno(errno, "Failed to remove loop device: %m");
}
log_warning_errno(errno,
"Failed to open loop control device, cannot remove loop device %s: %m",
strna(d->node));
else
for (unsigned n_attempts = 0;;) {
if (ioctl(control, LOOP_CTL_REMOVE, d->nr) >= 0)
break;
if (errno != EBUSY || ++n_attempts >= 64) {
log_warning_errno(errno, "Failed to remove device %s: %m", strna(d->node));
break;
}
usleep(50 * USEC_PER_MSEC);
}
}
free(d->node);

View File

@ -15,10 +15,6 @@ struct LoopDevice {
};
int loop_device_make_full(int fd, int open_flags, uint64_t offset, uint64_t size, uint32_t loop_flags, LoopDevice **ret);
static inline int loop_device_make(int fd, int open_flags, uint32_t loop_flags, LoopDevice **ret) {
return loop_device_make_full(fd, open_flags, 0, 0, loop_flags, ret);
}
int loop_device_make_by_path(const char *path, int open_flags, uint32_t loop_flags, LoopDevice **ret);
int loop_device_open(const char *loop_path, int open_flags, LoopDevice **ret);

View File

@ -80,6 +80,7 @@ int sd_netlink_attach_event(sd_netlink *nl, sd_event *e, int64_t priority);
int sd_netlink_detach_event(sd_netlink *nl);
int sd_netlink_message_append_string(sd_netlink_message *m, unsigned short type, const char *data);
int sd_netlink_message_append_strv(sd_netlink_message *m, unsigned short type, char * const *data);
int sd_netlink_message_append_flag(sd_netlink_message *m, unsigned short type);
int sd_netlink_message_append_u8(sd_netlink_message *m, unsigned short type, uint8_t data);
int sd_netlink_message_append_u16(sd_netlink_message *m, unsigned short type, uint16_t data);
@ -100,6 +101,7 @@ int sd_netlink_message_close_container(sd_netlink_message *m);
int sd_netlink_message_read(sd_netlink_message *m, unsigned short type, size_t size, void *data);
int sd_netlink_message_read_string_strdup(sd_netlink_message *m, unsigned short type, char **data);
int sd_netlink_message_read_string(sd_netlink_message *m, unsigned short type, const char **data);
int sd_netlink_message_read_strv(sd_netlink_message *m, unsigned short container_type, unsigned short type_id, char ***ret);
int sd_netlink_message_read_u8(sd_netlink_message *m, unsigned short type, uint8_t *data);
int sd_netlink_message_read_u16(sd_netlink_message *m, unsigned short type, uint16_t *data);
int sd_netlink_message_read_u32(sd_netlink_message *m, unsigned short type, uint32_t *data);

View File

@ -45,6 +45,7 @@ static void test_ifname_valid(void) {
assert(ifname_valid("xxxxxxxxxxxxxxx"));
assert(!ifname_valid("xxxxxxxxxxxxxxxx"));
assert(ifname_valid_full("xxxxxxxxxxxxxxxx", true));
}
static void test_socket_address_parse_one(const char *in, int ret, int family, const char *expected) {

View File

@ -35,6 +35,7 @@ Link.MACAddressPolicy, config_parse_mac_address_policy, 0,
Link.MACAddress, config_parse_hwaddr, 0, offsetof(link_config, mac)
Link.NamePolicy, config_parse_name_policy, 0, offsetof(link_config, name_policy)
Link.Name, config_parse_ifname, 0, offsetof(link_config, name)
Link.AlternativeName, config_parse_ifnames, 1, offsetof(link_config, alternative_names)
Link.Alias, config_parse_ifalias, 0, offsetof(link_config, alias)
Link.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(link_config, mtu)
Link.BitsPerSecond, config_parse_si_size, 0, offsetof(link_config, speed)

View File

@ -58,6 +58,7 @@ static void link_config_free(link_config *link) {
free(link->mac);
free(link->name_policy);
free(link->name);
strv_free(link->alternative_names);
free(link->alias);
free(link);
@ -243,7 +244,7 @@ int link_config_get(link_config_ctx *ctx, sd_device *device, link_config **ret)
LIST_FOREACH(links, link, ctx->links) {
if (net_match_config(link->match_mac, link->match_path, link->match_driver,
link->match_type, link->match_name, link->match_property, NULL, NULL, NULL,
device, NULL, NULL, 0, NULL, NULL)) {
device, NULL, NULL, NULL, 0, NULL, NULL)) {
if (link->match_name && !strv_contains(link->match_name, "*")) {
unsigned name_assign_type = NET_NAME_UNKNOWN;
@ -458,6 +459,10 @@ int link_config_apply(link_config_ctx *ctx, link_config *config,
if (r < 0)
return log_warning_errno(r, "Could not set Alias=, MACAddress= or MTU= on %s: %m", old_name);
r = rtnl_set_link_alternative_names(&ctx->rtnl, ifindex, config->alternative_names);
if (r < 0)
return log_warning_errno(r, "Could not set AlternativeName= on %s: %m", old_name);
*name = new_name;
return 0;

View File

@ -48,6 +48,7 @@ struct link_config {
MACAddressPolicy mac_address_policy;
NamePolicy *name_policy;
char *name;
char **alternative_names;
char *alias;
uint32_t mtu;
size_t speed;

View File

@ -51,7 +51,7 @@ TEST_NO_NSPAWN=1
Don't run tests under systemd-nspawn
TEST_NO_KVM=1
Disable QEMU KVM autodetection (may be necessary when you're trying to run the
Disable QEMU KVM auto-detection (may be necessary when you're trying to run the
*vanilla* QEMU and have both qemu and qemu-kvm installed)
TEST_NESTED_KVM=1

View File

@ -16,6 +16,7 @@ MACAddressPolicy=
MACAddress=
NamePolicy=
Name=
AlternativeName=
Alias=
MTUBytes=
BitsPerSecond=

View File

@ -0,0 +1,5 @@
[Match]
OriginalName=dummy98
[Link]
AlternativeName=hogehogehogehogehogehoge

View File

@ -14,6 +14,7 @@ Name=ifb99
Name=ipiptun99
Name=nlmon99
Name=xfrm99
Name=hogehogehogehogehogehoge
[Network]
LinkLocalAddressing=yes

View File

@ -127,6 +127,17 @@ def expectedFailureIfNexthopIsNotAvailable():
return f
def expectedFailureIfAlternativeNameIsNotAvailable():
def f(func):
call('ip link add dummy98 type dummy', stderr=subprocess.DEVNULL)
rc = call('ip link prop add dev dummy98 altname hogehogehogehogehoge', stderr=subprocess.DEVNULL)
if rc == 0:
return func
else:
return unittest.expectedFailure(func)
return f
def setUpModule():
global running_units
@ -425,6 +436,7 @@ class NetworkctlTests(unittest.TestCase, Utilities):
'11-dummy-mtu.netdev',
'11-dummy.network',
'12-dummy.netdev',
'12-dummy.link',
'25-address-static.network',
'25-veth.netdev',
'netdev-link-local-addressing-yes.network',
@ -439,6 +451,16 @@ class NetworkctlTests(unittest.TestCase, Utilities):
remove_unit_from_networkd_path(self.units)
stop_networkd(show_logs=True)
@expectedFailureIfAlternativeNameIsNotAvailable()
def test_altname(self):
copy_unit_to_networkd_unit_path('netdev-link-local-addressing-yes.network', '12-dummy.netdev', '12-dummy.link')
check_output('udevadm control --reload')
start_networkd()
self.wait_online(['dummy98:degraded'])
output = check_output(*networkctl_cmd, 'status', 'dummy98', env=env)
self.assertRegex(output, 'hogehogehogehogehogehoge')
def test_reconfigure(self):
copy_unit_to_networkd_unit_path('25-address-static.network', '12-dummy.netdev')
start_networkd()
@ -529,11 +551,11 @@ class NetworkctlTests(unittest.TestCase, Utilities):
start_networkd()
self.wait_online(['test1:degraded'])
output = check_output(*networkctl_cmd, 'status', 'test1')
output = check_output(*networkctl_cmd, 'status', 'test1', env=env)
print(output)
self.assertRegex(output, 'Type: ether')
output = check_output(*networkctl_cmd, 'status', 'lo')
output = check_output(*networkctl_cmd, 'status', 'lo', env=env)
print(output)
self.assertRegex(output, 'Type: loopback')
@ -543,12 +565,12 @@ class NetworkctlTests(unittest.TestCase, Utilities):
start_networkd()
self.wait_online(['test1:degraded'])
output = check_output(*networkctl_cmd, 'status', 'test1')
output = check_output(*networkctl_cmd, 'status', 'test1', env=env)
print(output)
self.assertRegex(output, r'Link File: (/usr)?/lib/systemd/network/99-default.link')
self.assertRegex(output, r'Network File: /run/systemd/network/11-dummy.network')
output = check_output(*networkctl_cmd, 'status', 'lo')
output = check_output(*networkctl_cmd, 'status', 'lo', env=env)
print(output)
self.assertRegex(output, r'Link File: (/usr)?/lib/systemd/network/99-default.link')
self.assertRegex(output, r'Network File: n/a')
@ -560,7 +582,7 @@ class NetworkctlTests(unittest.TestCase, Utilities):
self.wait_online(['test1:degraded', 'veth99:degraded', 'veth-peer:degraded'])
check_output(*networkctl_cmd, 'delete', 'test1', 'veth99')
check_output(*networkctl_cmd, 'delete', 'test1', 'veth99', env=env)
self.assertFalse(link_exists('test1'))
self.assertFalse(link_exists('veth99'))
self.assertFalse(link_exists('veth-peer'))
@ -805,7 +827,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
self.assertEqual(1, int(read_link_attr('bridge99', 'bridge', 'stp_state')))
self.assertEqual(3, int(read_link_attr('bridge99', 'bridge', 'multicast_igmp_version')))
output = check_output(*networkctl_cmd, 'status', 'bridge99')
output = check_output(*networkctl_cmd, 'status', 'bridge99', env=env)
print(output)
self.assertRegex(output, 'Priority: 9')
self.assertRegex(output, 'STP: yes')
@ -1372,7 +1394,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
self.assertRegex(output, '00:11:22:33:44:66 dst 10.0.0.6 self permanent')
self.assertRegex(output, '00:11:22:33:44:77 dst 10.0.0.7 self permanent')
output = check_output(*networkctl_cmd, 'status', 'vxlan99')
output = check_output(*networkctl_cmd, 'status', 'vxlan99', env=env)
print(output)
self.assertRegex(output, 'VNI: 999')
self.assertRegex(output, 'Destination Port: 5555')
@ -1643,7 +1665,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
start_networkd()
self.wait_online(['test1:routable'])
output = check_output(*networkctl_cmd, 'status', 'test1')
output = check_output(*networkctl_cmd, 'status', 'test1', env=env)
print(output)
self.assertRegex(output, '192.168.0.15')
self.assertRegex(output, '192.168.0.1')