summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS36
-rw-r--r--TODO24
-rw-r--r--catalog/systemd.pl.catalog.in60
-rw-r--r--docs/BOOT_LOADER_SPECIFICATION.md2
-rw-r--r--docs/CODING_STYLE.md2
-rw-r--r--docs/HOME_DIRECTORY.md2
-rw-r--r--docs/INITRD_INTERFACE.md2
-rw-r--r--docs/RANDOM_SEEDS.md8
-rw-r--r--docs/USER_RECORD.md66
-rw-r--r--hwdb.d/20-OUI.hwdb178
-rw-r--r--hwdb.d/20-acpi-vendor.hwdb.patch4
-rw-r--r--hwdb.d/60-keyboard.hwdb9
-rw-r--r--hwdb.d/60-sensor.hwdb7
-rw-r--r--hwdb.d/70-mouse.hwdb4
-rw-r--r--hwdb.d/ma-large.txt222
-rw-r--r--hwdb.d/ma-medium.txt792
-rw-r--r--hwdb.d/ma-small.txt1044
-rw-r--r--man/coredump.conf.xml2
-rw-r--r--man/coredumpctl.xml4
-rw-r--r--man/crypttab.xml11
-rw-r--r--man/daemon.xml4
-rw-r--r--man/file-hierarchy.xml2
-rw-r--r--man/homectl.xml127
-rw-r--r--man/homed.conf.xml2
-rw-r--r--man/journal-remote.conf.xml2
-rw-r--r--man/journal-upload.conf.xml2
-rw-r--r--man/journalctl.xml12
-rw-r--r--man/journald.conf.xml2
-rw-r--r--man/kernel-install.xml4
-rw-r--r--man/logind.conf.xml4
-rw-r--r--man/machine-id.xml2
-rw-r--r--man/machinectl.xml2
-rw-r--r--man/networkd.conf.xml2
-rw-r--r--man/nss-myhostname.xml3
-rw-r--r--man/nss-mymachines.xml3
-rw-r--r--man/nss-resolve.xml2
-rw-r--r--man/nss-systemd.xml2
-rw-r--r--man/org.freedesktop.LogControl1.xml2
-rw-r--r--man/org.freedesktop.home1.xml4
-rw-r--r--man/org.freedesktop.hostname1.xml2
-rw-r--r--man/org.freedesktop.systemd1.xml4
-rw-r--r--man/pam_systemd.xml2
-rw-r--r--man/portablectl.xml4
-rw-r--r--man/pstore.conf.xml4
-rw-r--r--man/repart.d.xml2
-rw-r--r--man/resolved.conf.xml2
-rw-r--r--man/sd_bus_creds_get_pid.xml2
-rw-r--r--man/sd_bus_enqueue_for_read.xml2
-rw-r--r--man/sd_bus_get_fd.xml2
-rw-r--r--man/sd_bus_is_open.xml2
-rw-r--r--man/sd_bus_message_new_method_error.xml2
-rw-r--r--man/sd_bus_set_connected_signal.xml2
-rw-r--r--man/sd_bus_slot_set_destroy_callback.xml2
-rw-r--r--man/sd_bus_slot_set_floating.xml2
-rw-r--r--man/sd_event_new.xml2
-rw-r--r--man/sd_event_source_set_destroy_callback.xml2
-rw-r--r--man/sd_hwdb_get.xml2
-rw-r--r--man/sd_journal_has_runtime_files.xml2
-rw-r--r--man/sd_login_monitor_new.xml2
-rw-r--r--man/sd_machine_get_class.xml2
-rw-r--r--man/sd_pid_get_owner_uid.xml2
-rw-r--r--man/standard-conf.xml2
-rw-r--r--man/sysctl.d.xml10
-rw-r--r--man/systemctl.xml16
-rw-r--r--man/systemd-analyze.xml10
-rw-r--r--man/systemd-bless-boot-generator.xml2
-rw-r--r--man/systemd-boot.xml12
-rw-r--r--man/systemd-firstboot.xml20
-rw-r--r--man/systemd-gpt-auto-generator.xml2
-rw-r--r--man/systemd-journal-gatewayd.service.xml6
-rw-r--r--man/systemd-journal-upload.service.xml2
-rw-r--r--man/systemd-logind.service.xml2
-rw-r--r--man/systemd-mount.xml23
-rw-r--r--man/systemd-nspawn.xml48
-rw-r--r--man/systemd-random-seed.service.xml2
-rw-r--r--man/systemd-repart.xml19
-rw-r--r--man/systemd-sleep.conf.xml2
-rw-r--r--man/systemd-socket-proxyd.xml2
-rw-r--r--man/systemd-suspend.service.xml15
-rw-r--r--man/systemd-system.conf.xml10
-rw-r--r--man/systemd-time-wait-sync.service.xml2
-rw-r--r--man/systemd.automount.xml6
-rw-r--r--man/systemd.device.xml6
-rw-r--r--man/systemd.dnssd.xml2
-rw-r--r--man/systemd.exec.xml58
-rw-r--r--man/systemd.journal-fields.xml3
-rw-r--r--man/systemd.kill.xml2
-rw-r--r--man/systemd.link.xml4
-rw-r--r--man/systemd.mount.xml6
-rw-r--r--man/systemd.net-naming-scheme.xml2
-rw-r--r--man/systemd.netdev.xml201
-rw-r--r--man/systemd.network.xml587
-rw-r--r--man/systemd.nspawn.xml8
-rw-r--r--man/systemd.offline-updates.xml6
-rw-r--r--man/systemd.path.xml6
-rw-r--r--man/systemd.scope.xml4
-rw-r--r--man/systemd.service.xml14
-rw-r--r--man/systemd.slice.xml4
-rw-r--r--man/systemd.socket.xml181
-rw-r--r--man/systemd.special.xml20
-rw-r--r--man/systemd.swap.xml8
-rw-r--r--man/systemd.syntax.xml4
-rw-r--r--man/systemd.target.xml4
-rw-r--r--man/systemd.time.xml28
-rw-r--r--man/systemd.timer.xml6
-rw-r--r--man/systemd.unit.xml12
-rw-r--r--man/systemd.xml21
-rw-r--r--man/tc.xml24
-rw-r--r--man/timesyncd.conf.xml2
-rw-r--r--man/userdbctl.xml7
-rw-r--r--meson.build16
-rw-r--r--meson_options.txt2
-rw-r--r--po/cs.po47
-rw-r--r--src/basic/locale-util.c6
-rw-r--r--src/basic/locale-util.h3
-rw-r--r--src/basic/macro.h6
-rw-r--r--src/basic/namespace-util.c14
-rw-r--r--src/basic/namespace-util.h2
-rw-r--r--src/basic/process-util.c2
-rw-r--r--src/basic/random-util.c2
-rw-r--r--src/basic/socket-util.c10
-rw-r--r--src/basic/unit-name.c5
-rw-r--r--src/basic/user-util.c2
-rw-r--r--src/core/automount.c1
-rw-r--r--src/core/bpf-firewall.c2
-rw-r--r--src/core/execute.c2
-rw-r--r--src/core/load-fragment.c2
-rw-r--r--src/core/machine-id-setup.c8
-rw-r--r--src/core/main.c1
-rw-r--r--src/core/manager.c18
-rw-r--r--src/core/manager.h1
-rw-r--r--src/core/mount.c7
-rw-r--r--src/core/namespace.c8
-rw-r--r--src/core/transaction.c18
-rw-r--r--src/core/unit.c2
-rw-r--r--src/firstboot/firstboot.c129
-rw-r--r--src/home/homectl-fido2.c539
-rw-r--r--src/home/homectl-fido2.h10
-rw-r--r--src/home/homectl-pkcs11.c480
-rw-r--r--src/home/homectl-pkcs11.h11
-rw-r--r--src/home/homectl.c542
-rw-r--r--src/home/homed-home.c12
-rw-r--r--src/home/homed.c2
-rw-r--r--src/home/homework-cifs.c4
-rw-r--r--src/home/homework-cifs.h2
-rw-r--r--src/home/homework-directory.c12
-rw-r--r--src/home/homework-directory.h4
-rw-r--r--src/home/homework-fido2.c197
-rw-r--r--src/home/homework-fido2.h6
-rw-r--r--src/home/homework-fscrypt.c25
-rw-r--r--src/home/homework-fscrypt.h4
-rw-r--r--src/home/homework-luks.c100
-rw-r--r--src/home/homework-luks.h12
-rw-r--r--src/home/homework-pkcs11.c6
-rw-r--r--src/home/homework.c250
-rw-r--r--src/home/homework.h16
-rw-r--r--src/home/meson.build8
-rw-r--r--src/home/pam_systemd_home.c25
-rw-r--r--src/home/user-record-util.c58
-rw-r--r--src/home/user-record-util.h3
-rw-r--r--src/initctl/initctl.c145
-rw-r--r--src/journal-remote/journal-remote-main.c2
-rw-r--r--src/journal-remote/journal-upload.c2
-rw-r--r--src/journal/compress.c7
-rw-r--r--src/journal/journal-file.c2
-rw-r--r--src/journal/journald-kmsg.c2
-rw-r--r--src/libsystemd-network/dhcp6-internal.h2
-rw-r--r--src/libsystemd-network/dhcp6-network.c6
-rw-r--r--src/libsystemd-network/icmp6-util.c8
-rw-r--r--src/libsystemd-network/icmp6-util.h4
-rw-r--r--src/libsystemd-network/sd-dhcp-client.c10
-rw-r--r--src/libsystemd-network/sd-dhcp6-client.c4
-rw-r--r--src/libsystemd-network/sd-radv.c2
-rw-r--r--src/libsystemd-network/test-dhcp-client.c2
-rw-r--r--src/libsystemd-network/test-dhcp6-client.c10
-rw-r--r--src/libsystemd-network/test-ipv4ll.c2
-rw-r--r--src/libsystemd-network/test-ndisc-ra.c10
-rw-r--r--src/libsystemd-network/test-ndisc-rs.c7
-rw-r--r--src/libsystemd/sd-bus/bus-common-errors.c2
-rw-r--r--src/libsystemd/sd-bus/bus-common-errors.h2
-rw-r--r--src/libsystemd/sd-bus/bus-internal.h2
-rw-r--r--src/libsystemd/sd-device/sd-device.c75
-rw-r--r--src/libsystemd/sd-netlink/netlink-types.c43
-rw-r--r--src/login/logind-core.c24
-rw-r--r--src/login/pam_systemd.c2
-rw-r--r--src/network/meson.build2
-rw-r--r--src/network/netdev/bond.c10
-rw-r--r--src/network/networkd-dhcp4.c72
-rw-r--r--src/network/networkd-dhcp4.h2
-rw-r--r--src/network/networkd-dhcp6.c95
-rw-r--r--src/network/networkd-dhcp6.h13
-rw-r--r--src/network/networkd-link.c201
-rw-r--r--src/network/networkd-link.h2
-rw-r--r--src/network/networkd-network-gperf.gperf47
-rw-r--r--src/network/networkd-network.c9
-rw-r--r--src/network/networkd-network.h5
-rw-r--r--src/network/networkd-radv.c31
-rw-r--r--src/network/networkd-radv.h2
-rw-r--r--src/network/networkd-routing-policy-rule.c10
-rw-r--r--src/network/networkd-sriov.c501
-rw-r--r--src/network/networkd-sriov.h46
-rw-r--r--src/network/networkd.c2
-rw-r--r--src/network/tc/cake.c8
-rw-r--r--src/network/tc/drr.c2
-rw-r--r--src/network/tc/ets.c2
-rw-r--r--src/network/tc/fifo.c2
-rw-r--r--src/network/tc/fq-codel.c7
-rw-r--r--src/network/tc/fq.c6
-rw-r--r--src/network/tc/qdisc.c2
-rw-r--r--src/network/tc/qfq.c2
-rw-r--r--src/network/tc/tbf.c82
-rw-r--r--src/network/tc/tbf.h1
-rw-r--r--src/network/tc/tclass.c2
-rw-r--r--src/network/wait-online/wait-online.c2
-rw-r--r--src/partition/repart.c4
-rw-r--r--src/resolve/resolved-dns-packet.c10
-rw-r--r--src/resolve/resolved-dns-rr.c18
-rw-r--r--src/resolve/resolved-dns-rr.h2
-rw-r--r--src/resolve/resolved-dns-stream.c2
-rw-r--r--src/resolve/resolved.c2
-rw-r--r--src/shared/dropin.c4
-rw-r--r--src/shared/linux/nl80211.h2
-rw-r--r--src/shared/mount-util.c5
-rw-r--r--src/shared/mount-util.h11
-rw-r--r--src/shared/pkcs11-util.c81
-rw-r--r--src/shared/pkcs11-util.h2
-rw-r--r--src/shared/tests.c6
-rw-r--r--src/shared/user-record-show.c5
-rw-r--r--src/shared/user-record.c437
-rw-r--r--src/shared/user-record.h25
-rw-r--r--src/shared/utmp-wtmp.c69
-rw-r--r--src/shared/utmp-wtmp.h11
-rw-r--r--src/shared/varlink.c2
-rw-r--r--src/sleep/sleep.c2
-rw-r--r--src/systemd/sd-lldp.h2
-rw-r--r--src/test/test-locale-util.c3
-rw-r--r--src/test/test-process-util.c4
-rw-r--r--src/test/test-udev.c13
-rw-r--r--src/test/test-unit-name.c2
-rw-r--r--src/test/test-util.c80
-rw-r--r--src/test/test-xdg-autostart.c6
-rw-r--r--src/timesync/timesyncd.c2
-rw-r--r--src/udev/udevadm-info.c77
-rw-r--r--src/update-utmp/update-utmp.c6
-rw-r--r--src/userdb/userdbctl.c8
-rw-r--r--src/userdb/userdbd.c2
-rw-r--r--src/xdg-autostart-generator/xdg-autostart-service.c77
-rw-r--r--test/fuzz/fuzz-network-parser/directives.network25
-rw-r--r--test/fuzz/fuzz-network-parser/oss-fuzz-23895bin0 -> 2395 bytes
-rw-r--r--test/fuzz/fuzz-network-parser/oss-fuzz-23950bin0 -> 21603 bytes
-rw-r--r--test/fuzz/fuzz-xdg-desktop/oss-fuzz-22812bin0 -> 128273 bytes
-rw-r--r--test/test-network/conf/25-qdisc-cake.network2
-rw-r--r--test/test-network/conf/25-qdisc-clsact-and-htb.network14
-rw-r--r--test/test-network/conf/25-qdisc-drr.network2
-rw-r--r--test/test-network/conf/25-qdisc-qfq.network4
-rw-r--r--test/test-network/conf/25-sriov.network37
-rwxr-xr-xtest/test-network/systemd-networkd-tests.py58
-rw-r--r--test/units/test-honor-first-shutdown.service4
-rwxr-xr-xtest/units/testsuite-48.sh27
-rwxr-xr-xtravis-ci/managers/fedora.sh8
260 files changed, 6467 insertions, 3040 deletions
diff --git a/NEWS b/NEWS
index 5d79200cf1..fe75cc6c35 100644
--- a/NEWS
+++ b/NEWS
@@ -91,6 +91,15 @@ CHANGES WITH 246 in spe:
from the documentation, but will now result in warnings when used,
and be converted to "journal" and "journal+console" automatically.
+ * If the service setting User= is set to the "nobody" user, a warning
+ message is now written to the logs (but the value is nonetheless
+ accepted). Setting User=nobody is unsafe, since the primary purpose
+ of the "nobody" user is to own all files whose owner cannot be mapped
+ locally. It's in particular used by the NFS subsystem and in user
+ namespacing. By running a service under this user's UID it might get
+ read and even write access to all these otherwise unmappable files,
+ which is quite likely a major security problem.
+
* A new kernel command line option systemd.hostname= has been added
that allows controlling the hostname that is initialized early during
boot.
@@ -147,6 +156,9 @@ CHANGES WITH 246 in spe:
* networkd.conf gained a new boolean setting ManageForeignRoutes=. If
enabled systemd-networkd manages all routes configured by other tools.
+ * .network files managed by systemd-networkd gained a new section
+ [SR-IOV], in order to configure SR-IOV capable network devices.
+
* systemd-networkd's [IPv6Prefix] section in .network files gained a
new boolean setting Assign=. If enabled an address from the prefix is
automatically assigned to the interface.
@@ -178,10 +190,10 @@ CHANGES WITH 246 in spe:
traffic). DataBitRate=, DataSamplePoint=, FDMode=, FDNonISO= have
been added to configure various CAN-FD aspects.
- * systemd-networkd's [DHCPv6] section gained a new WithoutRA= boolean
- setting. If enabled, DHCPv6 will be attempted right-away without
- requiring an Router Advertisement packet suggesting it
- first. Conversely, the [IPv6AcceptRA] gained a boolean option
+ * systemd-networkd's [DHCPv6] section gained a new option WithoutRA=.
+ When enabled, DHCPv6 will be attempted right-away without requiring an
+ Router Advertisement packet suggesting it first (i.e. without the 'M'
+ or 'O' flags set). The [IPv6AcceptRA] section gained a boolean option
DHCPv6Client= that may be used to turn off the DHCPv6 client even if
the RA packets suggest it.
@@ -367,6 +379,21 @@ CHANGES WITH 246 in spe:
storage and file system may now be configured explicitly, too, via
the new /etc/systemd/homed.conf configuration file.
+ * systemd-homed now supports unlocking home directories with FIDO2
+ security tokens that support the 'hmac-secret' extension, in addition
+ to the existing support for PKCS#11 security token unlocking
+ support. Note that many recent hardware security tokens support both
+ interfaces. The FIDO2 support is accessible via homectl's
+ --fido2-device= option.
+
+ * homectl's --pkcs11-uri= setting now accepts two special parameters:
+ if "auto" is specified and only one suitable PKCS#11 security token
+ is plugged in, its URL is automatically determined and enrolled for
+ unlocking the home directory. If "list" is specified a brief table of
+ suitable PKCS#11 security tokens is shown. Similar, the new
+ --fido2-device= option also supports these two special values, for
+ automatically selecting and listing suitable FIDO2 devices.
+
* The /etc/crypttab tmp option now optionally takes an argument
selecting the file system to use. Moreover, the default is now
changed from ext2 to ext4.
@@ -493,7 +520,6 @@ CHANGES WITH 246 in spe:
LogControl1 D-Bus API which allows clients to change log level +
target of the service during runtime.
-
CHANGES WITH 245:
* A new tool "systemd-repart" has been added, that operates as an
diff --git a/TODO b/TODO
index 6751bd96aa..7ee5f26cc1 100644
--- a/TODO
+++ b/TODO
@@ -49,6 +49,9 @@ Features:
* nspawn: support time namespaces
+* systemd-firstboot: make sure to always use chase_symlinks() before
+ reading/writing files
+
* add ConditionSecurity=tpm2
* Remove any support for booting without /usr pre-mounted in the initrd entirely.
@@ -94,8 +97,9 @@ Features:
this, it's useful to have one that can dump contents of them, too.
* All tools that support --root= should also learn --image= so that they can
- operate on disk images directly. Specifically: bootctl, firstboot, tmpfiles,
- sysusers, systemctl, repart, journalctl, coredumpctl.
+ operate on disk images directly. Specifically: bootctl, tmpfiles, sysusers,
+ systemctl, repart, journalctl, coredumpctl. (Already done: systemd-nspawn,
+ systemd-firstboot)
* seccomp: by default mask x32 ABI system wide on x86-64. it's on its way out
@@ -138,20 +142,20 @@ Features:
* homed: support new FS_IOC_ADD_ENCRYPTION_KEY ioctl for setting up fscrypt
-* busctl: maybe expose a verb "ping" for pinging a dbus service to see if it
- exists and responds.
-
* homed: maybe pre-create ~/.cache as subvol so that it can have separate quota
easily?
+* busctl: maybe expose a verb "ping" for pinging a dbus service to see if it
+ exists and responds.
+
* when systemd-nspawn and suchlike dissect an OS image, and there are multiple
root partitions, do an strverscmp() on the partition label and boot
first. That is inspired how sd-boot figures out which kernel to boot, and
thus allows defining OS images which can be A/B updated and we default to the
newest version automatically, both in nspawn and in sd-boot
-* cryptsetup/homed: also support FIDO2 HMAC password logic for unlocking
- devices. (see: https://github.com/mjec/fido2-hmac-secret)
+* cryptsetup: support FIDO2 tokens for deriving keys (i.e. do what homed can do
+ also in plain cryptsetup)
* systemd-gpt-auto should probably set x-systemd.growfs on the mounts it
creates
@@ -343,7 +347,8 @@ Features:
beefing up logind to make pam session close hook synchronous and wait until
systemd --user is shut down.
- logind: maybe keep a "busy fd" as long as there's a non-released session around or the user@.service
- - maybe make automatic, read-only, time-based reflink-copies of LUKS disk images (think: time machine)
+ - maybe make automatic, read-only, time-based reflink-copies of LUKS disk
+ images (and btrfs snapshots of subvolumes) (think: time machine)
- distinguish destroy / remove (i.e. currently we can unregister a user, unregister+remove their home directory, but not just remove their home directory)
- in systemd's PAMName= logic: query passwords with ssh-askpassword, so that we can make "loginctl set-linger" mode work
- fingerprint authentication, pattern authentication, …
@@ -359,6 +364,9 @@ Features:
- make slice for users configurable (requires logind rework)
- logind: populate auto-login list bus property from PKCS#11 token
- when determining state of a LUKS home directory, check DM suspended sysfs file
+ - introduce API for "making room", that grows/shrinks home directory
+ according to elastic parameters, discards blocks, and removes additional snapshots. Call it
+ either from UI when disk space gets low
* introduce a new per-process uuid, similar to the boot id, the machine id, the
invocation id, that is derived from process creds, specifically a hashed
diff --git a/catalog/systemd.pl.catalog.in b/catalog/systemd.pl.catalog.in
index 5f3d416322..961d09a2f5 100644
--- a/catalog/systemd.pl.catalog.in
+++ b/catalog/systemd.pl.catalog.in
@@ -298,7 +298,8 @@ Maszyna wirtualna @NAME@ (PID prowadzący @LEADER@) została wyłączona.
Subject: Wyłączono tryb DNSSEC, ponieważ serwer go nie obsługuje
Defined-By: systemd
Support: %SUPPORT_URL%
-Documentation: man:systemd-resolved.service(8) resolved.conf(5)
+Documentation: man:systemd-resolved.service(8)
+Documentation: man:resolved.conf(5)
Usługa resolver (systemd-resolved.service) wykryła, że skonfigurowany serwer
DNS nie obsługuje DNSSEC, w wyniku czego walidacja DNSSEC została wyłączona.
@@ -416,6 +417,7 @@ przez jednostkę @UNIT@.
Subject: Przyjmowanie nazwy użytkownika/grupy @USER_GROUP_NAME@, która nie zgadza się ze ścisłymi regułami nazw użytkowników/grup.
Defined-By: systemd
Support: %SUPPORT_URL%
+Documentation: https://systemd.io/USER_NAMES
Podano nazwę użytkownika/grupy @USER_GROUP_NAME@, co zostało przyjęte
zgodnie z rozluźnionymi regułami nazw użytkowników/grup, ale nie spełnia
@@ -432,5 +434,57 @@ nazw z początkową lub końcową spacją, ciągów „.” lub „..”, ciąg
zawierających tylko cyfry lub ciągów zaczynających się myślnikiem
i zawierających oprócz niego tylko cyfry.
-https://systemd.io/USER_NAMES zawiera więcej informacji o ścisłych
-i rozluźnionych regułach nazw użytkowników/grup.
+-- 1b3bb94037f04bbf81028e135a12d293
+Subject: Utworzenie prawidłowej nazwy jednostki ze ścieżki „@MOUNT_POINT@” się nie powiodło.
+Defined-By: systemd
+Support: %SUPPORT_URL%
+
+Następująca ścieżka do punktu montowania nie może zostać przekonwertowana
+na prawidłową nazwę jednostki .mount:
+
+ @MOUNT_POINT@
+
+Zwykle oznacza to, że ścieżka do punktu montowania jest dłuższa niż dozwolona
+dla prawidłowych nazw jednostek.
+
+systemd dynamicznie syntetyzuje jednostki .mount dla wszystkich punktów
+montowania pojawiających się na komputerze. Stosowany do tego jest prosty
+algorytm: używana jest bezwzględna nazwa ścieżki ze wszystkimi znakami „/”
+zastąpionymi znakami „-” (początkowy jest usuwany). Co więcej, wszystkie
+niealfanumeryczne znaki (a także „:”, „-”, „_”, „.”, „\”) są zastępowane
+„\xNN”, gdzie „NN” jest szesnastkowym kodem znaki. Na końcu dołączany jest
+przyrostek „.mount”. Wynikowy ciąg musi mieć poniżej 256 znaków długości,
+aby był prawidłową nazwą jednostki. To ograniczenie obowiązuje, aby wszystkie
+nazwy jednostek mogły być używane także jako nazwy plików. Jeśli punkt
+montowania — po zastosowaniu algorytmu — jest dłuższy niż to ograniczenie,
+to nie może zostać zmapowany do jednostki. W takim przypadku systemd nie
+zsyntetyzuje jednostki i nie może być używany do zarządzania punktem
+montowania. Nie pojawi się w tabeli jednostek menedżera usług, przez co
+nie zostanie także bezpiecznie i automatycznie zdjęty podczas wyłączania
+komputera.
+
+Zasadniczo zalecane jest unikanie takich za długich ścieżek do punktów
+montowania, a jeśli są używane mimo to, zarządzanie nimi niezależnie
+od systemd, tzn. stawianie ich i automatyczne zdejmowanie podczas
+wyłączania komputera przez inne oprogramowanie.
+
+-- b480325f9c394a7b802c231e51a2752c
+Subject: Skonfigurowany jest szczególny użytkownik @OFFENDING_USER@, jest to niebezpieczne!
+Defined-By: systemd
+Support: %SUPPORT_URL%
+Documentation: https://systemd.io/UIDS-GIDS
+
+Jednostka @UNIT@ jest skonfigurowana do używania User=@OFFENDING_USER@.
+
+Nie jest to bezpieczne. Głównym zastosowaniem użytkownika @OFFENDING_USER@
+w linuksowych systemach operacyjnych jest bycie właścicielem plików, których
+nie można w inny sposób zmapować do żadnego lokalnego użytkownika. Jest
+używany między innymi przez klienta NFS i przestrzenie nazw użytkowników
+Linuksa. Wykonywanie procesów jednostki pod tożsamością tego użytkownika
+może spowodować, że będą one miały dostęp do odczytu, a może nawet do zapisu,
+plików, których nie można zmapować w inny sposób.
+
+Mocno zalecane jest unikanie wykonywania usług pod tą tożsamością użytkownika,
+zwłaszcza na komputerach używających NFS lub mających kontenery. Należy
+przydzielić identyfikator użytkownika dla tej konkretnej usługi, statycznie
+przez systemd-sysusers lub dynamicznie przez ustawienie usługi DynamicUser=.
diff --git a/docs/BOOT_LOADER_SPECIFICATION.md b/docs/BOOT_LOADER_SPECIFICATION.md
index 6bb72e0faa..803ba5440f 100644
--- a/docs/BOOT_LOADER_SPECIFICATION.md
+++ b/docs/BOOT_LOADER_SPECIFICATION.md
@@ -47,7 +47,7 @@ functionality. Here's why we think that it is not enough for our uses:
* The various EFI implementations implement the boot order/boot item logic to different levels. Some firmware implementations do not offer a boot menu at all and instead unconditionally follow the EFI boot order, booting the first item that is working.
* If the firmware setup is used to reset all data usually all EFI boot entries are lost, making the system entirely unbootable, as the firmware setups generally do not offer a UI to define additional boot items. By placing the menu item information on disk, it is always available, regardless if the BIOS setup data is lost.
-* Harddisk images should be moveable between machines and be bootable without requiring explicit EFI variables to be set. This also requires that the list of boot options is defined on disk, and not in EFI variables alone.
+* Harddisk images should be movable between machines and be bootable without requiring explicit EFI variables to be set. This also requires that the list of boot options is defined on disk, and not in EFI variables alone.
* EFI is not universal yet (especially on non-x86 platforms), this specification is useful both for EFI and non-EFI boot loaders.
* Many EFI systems disable USB support during early boot to optimize boot times, thus making keyboard input unavailable in the EFI menu. It is thus useful if the OS UI has a standardized way to discover available boot options which can be booted to.
diff --git a/docs/CODING_STYLE.md b/docs/CODING_STYLE.md
index 12a0c993fc..f335a1012e 100644
--- a/docs/CODING_STYLE.md
+++ b/docs/CODING_STYLE.md
@@ -521,7 +521,7 @@ layout: default
hence we might want to call it "big endian" right-away.
- Please never use `dup()`. Use `fcntl(fd, F_DUPFD_CLOEXEC, 3)` instead. For
- two reason: first, you want `O_CLOEXEC` set on the new `fd` (see
+ two reasons: first, you want `O_CLOEXEC` set on the new `fd` (see
above). Second, `dup()` will happily duplicate your `fd` as 0, 1, 2,
i.e. stdin, stdout, stderr, should those `fd`s be closed. Given the special
semantics of those `fd`s, it's probably a good idea to avoid
diff --git a/docs/HOME_DIRECTORY.md b/docs/HOME_DIRECTORY.md
index d82aca7065..a3eabb7e63 100644
--- a/docs/HOME_DIRECTORY.md
+++ b/docs/HOME_DIRECTORY.md
@@ -125,7 +125,7 @@ medium. (Moreover it allows to embed additional partitions later on, for
example for allowing a multi-purpose USB stick that contains both a home
directory and a generic storage volume.)
-Rationale for including the encrypted user record in the the LUKS2 header:
+Rationale for including the encrypted user record in the LUKS2 header:
Linux kernel file system implementations are generally not robust towards
maliciously formatted file systems; there's a good chance that file system
images can be used as attack vectors, exploiting the kernel. Thus it is
diff --git a/docs/INITRD_INTERFACE.md b/docs/INITRD_INTERFACE.md
index 8985f2761c..e59bbcce15 100644
--- a/docs/INITRD_INTERFACE.md
+++ b/docs/INITRD_INTERFACE.md
@@ -36,7 +36,7 @@ interfaces are currently used by dracut and the ArchLinux initrds.
optionally followed (in `argv[2]`, `argv[3]`, … systemd's original command
line options, for example `--log-level=` and similar.
-* Storage daemons run from the initrd should follow the the guide on [systemd
+* Storage daemons run from the initrd should follow the guide on [systemd
and Storage Daemons for the Root File
System](https://systemd.io/ROOT_STORAGE_DAEMONS) to survive properly from the
boot initrd all the way to the point where systemd jumps back into the initrd
diff --git a/docs/RANDOM_SEEDS.md b/docs/RANDOM_SEEDS.md
index e4b4a7a9cb..da3fe40baa 100644
--- a/docs/RANDOM_SEEDS.md
+++ b/docs/RANDOM_SEEDS.md
@@ -212,10 +212,10 @@ boot, in order to ensure the entropy pool is filled up quickly.
random-seed`](https://www.freedesktop.org/software/systemd/man/bootctl.html#random-seed))
a seed file with an initial seed is placed in a file `/loader/random-seed`
in the ESP. In addition, an identically sized randomized EFI variable called
- the the 'system token' is set, which is written to the machine's firmware
- NVRAM. During boot, when `systemd-boot` finds both the random seed file and
- the system token they are combined and hashed with SHA256 (in counter mode,
- to generate sufficient data), to generate a new random seed file to store in
+ the 'system token' is set, which is written to the machine's firmware NVRAM.
+ During boot, when `systemd-boot` finds both the random seed file and the
+ system token they are combined and hashed with SHA256 (in counter mode, to
+ generate sufficient data), to generate a new random seed file to store in
the ESP as well as a random seed to pass to the OS kernel. The new random
seed file for the ESP is then written to the ESP, ensuring this is completed
before the OS is invoked. Very early during initialization PID 1 will read
diff --git a/docs/USER_RECORD.md b/docs/USER_RECORD.md
index 7b6fe47665..f6d22c217b 100644
--- a/docs/USER_RECORD.md
+++ b/docs/USER_RECORD.md
@@ -180,7 +180,7 @@ strictly local context and without signatures doesn't have to deal with the
`perMachine` or `binding` sections and can include its data exclusively in the
regular section. A service that uses a separate, private channel for
authenticating users (or that doesn't have a concept of authentication at all)
-does not need to to be concerned with the `secret` section of user records, as
+does not need to be concerned with the `secret` section of user records, as
the fields included therein are only useful when executing authentication
operations natively against JSON user records.
@@ -368,11 +368,11 @@ directory is first created, and defaults to `/etc/skel` if not defined.
access mask for the home directory when it is first created.
`tasksMax` → Takes an unsigned 64bit integer indicating the maximum number of
-tasks the user may start in parallel during system runtime. This value is
-enforced on all tasks (i.e. processes and threads) the user starts or that are
-forked off these processes regardless if the change user identity (for example
-by setuid binaries/`su`/`sudo` and
-similar). [`systemd-logind.service`](https://www.freedesktop.org/software/systemd/man/systemd-logind.service.html)
+tasks the user may start in parallel during system runtime. This counts
+all tasks (i.e. threads, where each process is at least one thread) the user starts or that are
+forked from these processes even if the user identity is changed (for example
+by setuid binaries/`su`/`sudo` and similar).
+[`systemd-logind.service`](https://www.freedesktop.org/software/systemd/man/systemd-logind.service.html)
enforces this by setting the `TasksMax` slice property for the user's slice
`user-$UID.slice`.
@@ -546,6 +546,11 @@ below). It's undefined how precise the URI is: during log-in it is tested
against all plugged in security tokens and if there's exactly one matching
private key found with it it is used.
+`fido2HmacCredential` → An array of strings, each with a Base64-encoded FIDO2
+credential ID that shell be used for authentication with FIDO2 devices that
+implement the `hmac-secret` extension. The salt to pass to the FIDO2 device is
+found in `fido2HmacSalt`.
+
`privileged` → An object, which contains the fields of the `privileged` section
of the user record, see below.
@@ -594,7 +599,7 @@ as the lines in the traditional `~/.ssh/authorized_key` file.
`pkcs11EncryptedKey` → An array of objects. Each element of the array should be
an object consisting of three string fields: `uri` shall contain a PKCS#11
-security token URI, `data` shall contain a Base64 encoded encrypted key and
+security token URI, `data` shall contain a Base64-encoded encrypted key and
`hashedPassword` shall contain a UNIX password hash to test the key
against. Authenticating with a security token against this account shall work
as follows: the encrypted secret key is converted from its Base64
@@ -602,13 +607,29 @@ representation into binary, then decrypted with the PKCS#11 `C_Decrypt()`
function of the PKCS#11 module referenced by the specified URI, using the
private key found on the same token. The resulting decrypted key is then
Base64-encoded and tested against the specified UNIX hashed password. The
-Base64-enceded decrypted key may also be used to unlock further resources
+Base64-encoded decrypted key may also be used to unlock further resources
during log-in, for example the LUKS or `fscrypt` storage backend. It is
generally recommended that for each entry in `pkcs11EncryptedKey` there's also
a matching one in `pkcs11TokenUri` and vice versa, with the same URI, appearing
in the same order, but this should not be required by applications processing
user records.
+`fido2HmacSalt` → An array of objects, implementing authentication support with
+FIDO2 devices that implement the `hmac-secret` extension. Each element of the
+array should be an object consisting of three string fields: `credential`,
+`salt`, `hashedPassword`. The first two shall contain Base64-encoded binary
+data: the FIDO2 credential ID and the salt value to pass to the FIDO2
+device. During authentication this salt along with the credential ID is sent to
+the FIDO2 token, which will HMAC hash the salt with its internal secret key and
+return the result. This resulting binary key should then be Base64-encoded and
+used as string password for the further layers of the stack. The
+`hashedPassword` field of the `fido2HmacSalt` field shall be a UNIX password
+hash to test this derived secret key against for authentication. It is
+generally recommended that for each entry in `fido2HmacSalt` there's also a
+matching one in `fido2HmacCredential`, and vice versa, with the same credential
+ID, appearing in the same order, but this should not be required by
+applications processing user records.
+
## Fields in the `perMachine` section
As mentioned, the `perMachine` section contains settings that shall apply to
@@ -652,13 +673,13 @@ that may be used in this section are identical to the equally named ones in the
`mountNoDevices`, `mountNoSuid`, `mountNoExecute`, `cifsDomain`,
`cifsUserName`, `cifsService`, `imagePath`, `uid`, `gid`, `memberOf`,
`fileSystemType`, `partitionUuid`, `luksUuid`, `fileSystemUuid`, `luksDiscard`,
-`luksOfflineDiscard`, `luksOfflineDiscard`, `luksCipher`, `luksCipherMode`,
-`luksVolumeKeySize`, `luksPbkdfHashAlgorithm`, `luksPbkdfType`,
-`luksPbkdfTimeCostUSec`, `luksPbkdfMemoryCost`, `luksPbkdfParallelThreads`,
-`rateLimitIntervalUSec`, `rateLimitBurst`, `enforcePasswordPolicy`,
-`autoLogin`, `stopDelayUSec`, `killProcesses`, `passwordChangeMinUSec`,
-`passwordChangeMaxUSec`, `passwordChangeWarnUSec`,
-`passwordChangeInactiveUSec`, `passwordChangeNow`, `pkcs11TokenUri`.
+`luksOfflineDiscard`, `luksCipher`, `luksCipherMode`, `luksVolumeKeySize`,
+`luksPbkdfHashAlgorithm`, `luksPbkdfType`, `luksPbkdfTimeCostUSec`,
+`luksPbkdfMemoryCost`, `luksPbkdfParallelThreads`, `rateLimitIntervalUSec`,
+`rateLimitBurst`, `enforcePasswordPolicy`, `autoLogin`, `stopDelayUSec`,
+`killProcesses`, `passwordChangeMinUSec`, `passwordChangeMaxUSec`,
+`passwordChangeWarnUSec`, `passwordChangeInactiveUSec`, `passwordChangeNow`,
+`pkcs11TokenUri`, `fido2HmacCredential`.
## Fields in the `binding` section
@@ -810,7 +831,7 @@ public key.
The `signature` field in the top-level user record object is an array of
objects. Each object encapsulates one signature and has two fields: `data` and
`key` (both are strings). The `data` field contains the actual signature,
-encoded in base64, the `key` field contains a copy of the public key whose
+encoded in Base64, the `key` field contains a copy of the public key whose
private key was used to make the signature, in PEM format. Currently only
signatures with Ed25519 keys are defined.
@@ -864,13 +885,20 @@ The `secret` field of the top-level user record contains the following fields:
`password` → an array of strings, each containing a plain text password.
-`pkcs11Pin` → an array of strings, each containing a plain text PIN, suitable
-for unlocking PKCS#11 security tokens that require that.
+`tokenPin` → an array of strings, each containing a plain text PIN, suitable
+for unlocking security tokens that require that. (The field `pkcs11Pin` should
+be considered a compatibility alias for this field, and merged with `tokenPin`
+in case both are set.)
`pkcs11ProtectedAuthenticationPathPermitted` → a boolean. If set to true allows
the receiver to use the PKCS#11 "protected authentication path" (i.e. a
physical button/touch element on the security token) for authenticating the
-user. If false or unset authentication this way shall not be attempted.
+user. If false or unset, authentication this way shall not be attempted.
+
+`fido2UserPresencePermitted` → a boolean. If set to true allows the receiver to
+use the FIDO2 "user presence" flag. This is similar to the concept of
+`pkcs11ProtectedAuthenticationPathPermitted`, but exposes the FIDO2 concept
+behind it. If false or unset authentication this way shall not be attempted.
## Mapping to `struct passwd` and `struct spwd`
diff --git a/hwdb.d/20-OUI.hwdb b/hwdb.d/20-OUI.hwdb
index ace062cb12..b9819f28d7 100644
--- a/hwdb.d/20-OUI.hwdb
+++ b/hwdb.d/20-OUI.hwdb
@@ -5808,7 +5808,7 @@ OUI:00078D*
ID_OUI_FROM_DATABASE=NetEngines Ltd.
OUI:00078E*
- ID_OUI_FROM_DATABASE=Garz & Friche GmbH
+ ID_OUI_FROM_DATABASE=Garz & Fricke GmbH
OUI:00078F*
ID_OUI_FROM_DATABASE=Emkay Innovative Products
@@ -30855,7 +30855,7 @@ OUI:003053*
ID_OUI_FROM_DATABASE=Basler AG
OUI:003054*
- ID_OUI_FROM_DATABASE=CASTLENET TECHNOLOGY, INC.
+ ID_OUI_FROM_DATABASE=Castlenet Technology Inc.
OUI:003055*
ID_OUI_FROM_DATABASE=Renesas Technology America, Inc.
@@ -39593,6 +39593,9 @@ OUI:0445A1*
OUI:044665*
ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
+OUI:0446CF*
+ ID_OUI_FROM_DATABASE=Beijing Venustech Cybervision Co.,Ltd.
+
OUI:04489A*
ID_OUI_FROM_DATABASE=Apple, Inc.
@@ -40001,6 +40004,9 @@ OUI:04C103*
OUI:04C1B9*
ID_OUI_FROM_DATABASE=Fiberhome Telecommunication Technologies Co.,LTD
+OUI:04C1D8*
+ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd.
+
OUI:04C23E*
ID_OUI_FROM_DATABASE=HTC Corporation
@@ -46652,6 +46658,9 @@ OUI:20F3A3*
OUI:20F41B*
ID_OUI_FROM_DATABASE=Shenzhen Bilian electronic CO.,LTD
+OUI:20F44F*
+ ID_OUI_FROM_DATABASE=Nokia
+
OUI:20F452*
ID_OUI_FROM_DATABASE=Shanghai IUV Software Development Co. Ltd
@@ -47009,6 +47018,9 @@ OUI:245CCB*
OUI:245EBE*
ID_OUI_FROM_DATABASE=QNAP Systems, Inc.
+OUI:245F9F*
+ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd.
+
OUI:245FDF*
ID_OUI_FROM_DATABASE=KYOCERA CORPORATION
@@ -47210,6 +47222,9 @@ OUI:24AF54*
OUI:24B0A9*
ID_OUI_FROM_DATABASE=Shanghai Mobiletek Communication Ltd.
+OUI:24B105*
+ ID_OUI_FROM_DATABASE=Prama Hikvision India Private Limited
+
OUI:24B209*
ID_OUI_FROM_DATABASE=Avaya Inc
@@ -50495,6 +50510,9 @@ OUI:343D98*
OUI:343DC4*
ID_OUI_FROM_DATABASE=BUFFALO.INC
+OUI:343EA4*
+ ID_OUI_FROM_DATABASE=Ring LLC
+
OUI:3440B5*
ID_OUI_FROM_DATABASE=IBM
@@ -53135,6 +53153,9 @@ OUI:40040C*
OUI:400589*
ID_OUI_FROM_DATABASE=T-Mobile, USA
+OUI:400634*
+ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd.
+
OUI:4006A0*
ID_OUI_FROM_DATABASE=Texas Instruments
@@ -54563,6 +54584,9 @@ OUI:44A42D*
OUI:44A466*
ID_OUI_FROM_DATABASE=GROUPE LDLC
+OUI:44A54E*
+ ID_OUI_FROM_DATABASE=Qorvo Utrecht B.V.
+
OUI:44A56E*
ID_OUI_FROM_DATABASE=NETGEAR
@@ -56762,6 +56786,9 @@ OUI:502690*
OUI:5027C7*
ID_OUI_FROM_DATABASE=TECHNART Co.,Ltd
+OUI:502873*
+ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd.
+
OUI:50294D*
ID_OUI_FROM_DATABASE=NANJING IOT SENSOR TECHNOLOGY CO,LTD
@@ -57614,6 +57641,9 @@ OUI:54055F*
OUI:540593*
ID_OUI_FROM_DATABASE=WOORI ELEC Co.,Ltd
+OUI:5405DB*
+ ID_OUI_FROM_DATABASE=LCFC(HeFei) Electronics Technology co., ltd
+
OUI:54068B*
ID_OUI_FROM_DATABASE=Ningbo Deli Kebei Technology Co.LTD
@@ -59360,6 +59390,9 @@ OUI:5C78F8*
OUI:5C7D5E*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+OUI:5C7D7D*
+ ID_OUI_FROM_DATABASE=Technicolor CH USA Inc.
+
OUI:5C80B6*
ID_OUI_FROM_DATABASE=Intel Corporate
@@ -63332,6 +63365,9 @@ OUI:706173*
OUI:70617B*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
+OUI:7061EE*
+ ID_OUI_FROM_DATABASE=Sunwoda Electronic Co.,Ltd
+
OUI:7062B8*
ID_OUI_FROM_DATABASE=D-Link International
@@ -63608,6 +63644,9 @@ OUI:709BFC*
OUI:709C8F*
ID_OUI_FROM_DATABASE=Nero AG
+OUI:709CD1*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
OUI:709E29*
ID_OUI_FROM_DATABASE=Sony Interactive Entertainment Inc.
@@ -64637,6 +64676,9 @@ OUI:70B3D5154*
OUI:70B3D5155*
ID_OUI_FROM_DATABASE=Sanwa New Tec Co.,Ltd
+OUI:70B3D5157*
+ ID_OUI_FROM_DATABASE=Shanghai Jupper Technology Co.Ltd
+
OUI:70B3D5158*
ID_OUI_FROM_DATABASE=EAX Labs s.r.o.
@@ -65564,6 +65606,9 @@ OUI:70B3D52AD*
OUI:70B3D52AE*
ID_OUI_FROM_DATABASE=Alere Technologies AS
+OUI:70B3D52AF*
+ ID_OUI_FROM_DATABASE=Enlaps
+
OUI:70B3D52B0*
ID_OUI_FROM_DATABASE=Beijing Zhongyi Yue Tai Technology Co., Ltd
@@ -65771,6 +65816,9 @@ OUI:70B3D52F9*
OUI:70B3D52FA*
ID_OUI_FROM_DATABASE=Toray Medical Co.,Ltd
+OUI:70B3D52FB*
+ ID_OUI_FROM_DATABASE=IK MULTIMEDIA PRODUCTION SRL
+
OUI:70B3D52FC*
ID_OUI_FROM_DATABASE=Loanguard T/A SE Controls
@@ -66245,6 +66293,9 @@ OUI:70B3D53B1*
OUI:70B3D53B2*
ID_OUI_FROM_DATABASE=Sicon srl
+OUI:70B3D53B4*
+ ID_OUI_FROM_DATABASE=YOUSUNG
+
OUI:70B3D53B5*
ID_OUI_FROM_DATABASE=Preston Industries dba PolyScience
@@ -67259,6 +67310,9 @@ OUI:70B3D5532*
OUI:70B3D5533*
ID_OUI_FROM_DATABASE=Nippon Marine Enterprises, Ltd.
+OUI:70B3D5534*
+ ID_OUI_FROM_DATABASE=Weihai Weigao Medical Imaging Technology Co., Ltd
+
OUI:70B3D5535*
ID_OUI_FROM_DATABASE=SITA Messtechnik GmbH
@@ -67652,6 +67706,9 @@ OUI:70B3D55C9*
OUI:70B3D55CA*
ID_OUI_FROM_DATABASE=ACD Elekronik GmbH
+OUI:70B3D55CB*
+ ID_OUI_FROM_DATABASE=ECoCoMS Ltd.
+
OUI:70B3D55CC*
ID_OUI_FROM_DATABASE=Akse srl
@@ -67898,6 +67955,9 @@ OUI:70B3D5623*
OUI:70B3D5625*
ID_OUI_FROM_DATABASE=VX Instruments GmbH
+OUI:70B3D5626*
+ ID_OUI_FROM_DATABASE=KRONOTECH SRL
+
OUI:70B3D5628*
ID_OUI_FROM_DATABASE=MECT SRL
@@ -69140,6 +69200,9 @@ OUI:70B3D57EE*
OUI:70B3D57EF*
ID_OUI_FROM_DATABASE=CRAVIS CO., LIMITED
+OUI:70B3D57F0*
+ ID_OUI_FROM_DATABASE=Yokogawa Denshikiki Co.,Ltd
+
OUI:70B3D57F1*
ID_OUI_FROM_DATABASE=AeroVision Avionics, Inc.
@@ -69446,6 +69509,9 @@ OUI:70B3D5862*
OUI:70B3D5863*
ID_OUI_FROM_DATABASE=Shenzhen Wesion Technology Co., Ltd
+OUI:70B3D5864*
+ ID_OUI_FROM_DATABASE=BORMANN EDV und Zubehoer
+
OUI:70B3D5865*
ID_OUI_FROM_DATABASE=Insitu, Inc.
@@ -69875,6 +69941,9 @@ OUI:70B3D5903*
OUI:70B3D5904*
ID_OUI_FROM_DATABASE=PHB Eletronica Ltda.
+OUI:70B3D5905*
+ ID_OUI_FROM_DATABASE=Wexiodisk AB
+
OUI:70B3D5906*
ID_OUI_FROM_DATABASE=Aplex Technology Inc.
@@ -70490,6 +70559,9 @@ OUI:70B3D59E7*
OUI:70B3D59E8*
ID_OUI_FROM_DATABASE=Zerospace ICT Services B.V.
+OUI:70B3D59E9*
+ ID_OUI_FROM_DATABASE=LiveCopper Inc.
+
OUI:70B3D59EA*
ID_OUI_FROM_DATABASE=Blue Storm Associates, Inc.
@@ -70637,6 +70709,9 @@ OUI:70B3D5A21*
OUI:70B3D5A22*
ID_OUI_FROM_DATABASE=eSys Solutions Sweden AB
+OUI:70B3D5A23*
+ ID_OUI_FROM_DATABASE=LG Electronics
+
OUI:70B3D5A24*
ID_OUI_FROM_DATABASE=Booz Allen Hamilton
@@ -71510,6 +71585,9 @@ OUI:70B3D5B66*
OUI:70B3D5B67*
ID_OUI_FROM_DATABASE=RedWave Labs Ltd
+OUI:70B3D5B68*
+ ID_OUI_FROM_DATABASE=S-Rain Control A/S
+
OUI:70B3D5B6A*
ID_OUI_FROM_DATABASE=YUYAMA MFG Co.,Ltd
@@ -71765,6 +71843,9 @@ OUI:70B3D5BC5*
OUI:70B3D5BC6*
ID_OUI_FROM_DATABASE=Hatteland Display AS
+OUI:70B3D5BC7*
+ ID_OUI_FROM_DATABASE=Autonomic Controls, Inc.
+
OUI:70B3D5BC9*
ID_OUI_FROM_DATABASE=Yite technology
@@ -72647,6 +72728,9 @@ OUI:70B3D5D15*
OUI:70B3D5D16*
ID_OUI_FROM_DATABASE=Monnit Corporation
+OUI:70B3D5D18*
+ ID_OUI_FROM_DATABASE=MetCom Solutions GmbH
+
OUI:70B3D5D19*
ID_OUI_FROM_DATABASE=Senior Group LLC
@@ -72980,6 +73064,9 @@ OUI:70B3D5D94*
OUI:70B3D5D95*
ID_OUI_FROM_DATABASE=SANO SERVICE Co.,Ltd
+OUI:70B3D5D96*
+ ID_OUI_FROM_DATABASE=Thermo Fisher Scientific Inc.
+
OUI:70B3D5D97*
ID_OUI_FROM_DATABASE=BRS Sistemas Eletrônicos
@@ -74012,6 +74099,9 @@ OUI:70B3D5F13*
OUI:70B3D5F14*
ID_OUI_FROM_DATABASE=SANYU SWITCH CO., LTD.
+OUI:70B3D5F15*
+ ID_OUI_FROM_DATABASE=ARECA EMBEDDED SYSTEMS PVT LTD
+
OUI:70B3D5F16*
ID_OUI_FROM_DATABASE=BRS Sistemas Eletrônicos
@@ -74189,6 +74279,9 @@ OUI:70B3D5F57*
OUI:70B3D5F58*
ID_OUI_FROM_DATABASE=CDR SRL
+OUI:70B3D5F59*
+ ID_OUI_FROM_DATABASE=KOREA SPECTRAL PRODUCTS
+
OUI:70B3D5F5A*
ID_OUI_FROM_DATABASE=HAMEG GmbH
@@ -76784,6 +76877,9 @@ OUI:78F7D0*
OUI:78F882*
ID_OUI_FROM_DATABASE=LG Electronics (Mobile Communications)
+OUI:78F8B8*
+ ID_OUI_FROM_DATABASE=Rako Controls Ltd
+
OUI:78F944*
ID_OUI_FROM_DATABASE=Private
@@ -80699,6 +80795,9 @@ OUI:8C444F*
OUI:8C4500*
ID_OUI_FROM_DATABASE=Murata Manufacturing Co., Ltd.
+OUI:8C47BE*
+ ID_OUI_FROM_DATABASE=Dell Inc.
+
OUI:8C4962*
ID_OUI_FROM_DATABASE=Roku, Inc
@@ -80987,6 +81086,9 @@ OUI:8C8ABB*
OUI:8C8B83*
ID_OUI_FROM_DATABASE=Texas Instruments
+OUI:8C8D28*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
OUI:8C8E76*
ID_OUI_FROM_DATABASE=taskit GmbH
@@ -86198,6 +86300,9 @@ OUI:A45046*
OUI:A45055*
ID_OUI_FROM_DATABASE=BUSWARE.DE
+OUI:A45129*
+ ID_OUI_FROM_DATABASE=XAG
+
OUI:A4516F*
ID_OUI_FROM_DATABASE=Microsoft Mobile Oy
@@ -86489,6 +86594,9 @@ OUI:A4A6A9*
OUI:A4A80F*
ID_OUI_FROM_DATABASE=Shenzhen Coship Electronics Co., Ltd.
+OUI:A4AC0F*
+ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd.
+
OUI:A4AD00*
ID_OUI_FROM_DATABASE=Ragsdale Technology
@@ -87146,6 +87254,9 @@ OUI:A865B2*
OUI:A8667F*
ID_OUI_FROM_DATABASE=Apple, Inc.
+OUI:A8698C*
+ ID_OUI_FROM_DATABASE=Oracle Corporation
+
OUI:A86A6F*
ID_OUI_FROM_DATABASE=RIM
@@ -88727,6 +88838,9 @@ OUI:B07D47*
OUI:B07D62*
ID_OUI_FROM_DATABASE=Dipl.-Ing. H. Horstmann GmbH
+OUI:B07D64*
+ ID_OUI_FROM_DATABASE=Intel Corporate
+
OUI:B07E11*
ID_OUI_FROM_DATABASE=Texas Instruments
@@ -89237,6 +89351,9 @@ OUI:B0FD0BE*
OUI:B0FEBD*
ID_OUI_FROM_DATABASE=Private
+OUI:B0FEE5*
+ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd.
+
OUI:B40016*
ID_OUI_FROM_DATABASE=INGENICO TERMINALS SAS
@@ -91931,9 +92048,42 @@ OUI:C05E79*
OUI:C06118*
ID_OUI_FROM_DATABASE=TP-LINK TECHNOLOGIES CO.,LTD.
+OUI:C0619A1*
+ ID_OUI_FROM_DATABASE=KidKraft
+
+OUI:C0619A2*
+ ID_OUI_FROM_DATABASE=Grup Arge Enerji ve Kontrol Sistemleri
+
OUI:C0619A3*
ID_OUI_FROM_DATABASE=LYAND ACOUSTIC TECHNOLOGY CO.,LTD.
+OUI:C0619A4*
+ ID_OUI_FROM_DATABASE=Stello
+
+OUI:C0619A5*
+ ID_OUI_FROM_DATABASE=Nanjing Balance Network Technology Co., Ltd
+
+OUI:C0619A6*
+ ID_OUI_FROM_DATABASE=IPG Automotive GmbH
+
+OUI:C0619A7*
+ ID_OUI_FROM_DATABASE=MAD PIECE LLC.
+
+OUI:C0619A8*
+ ID_OUI_FROM_DATABASE=Nanjing SinoVatio Technology Co., Ltd
+
+OUI:C0619A9*
+ ID_OUI_FROM_DATABASE=Wingtech Mobile Communications Co.,Ltd.
+
+OUI:C0619AA*
+ ID_OUI_FROM_DATABASE=Gronn Kontakt AS
+
+OUI:C0619AC*
+ ID_OUI_FROM_DATABASE=JAM-Labs Corp
+
+OUI:C0619AD*
+ ID_OUI_FROM_DATABASE=Uhnder
+
OUI:C0626B*
ID_OUI_FROM_DATABASE=Cisco Systems, Inc
@@ -92618,6 +92768,9 @@ OUI:C42996*
OUI:C42AD0*
ID_OUI_FROM_DATABASE=Apple, Inc.
+OUI:C42B44*
+ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd.
+
OUI:C42C03*
ID_OUI_FROM_DATABASE=Apple, Inc.
@@ -93941,6 +94094,9 @@ OUI:C8BAE9*
OUI:C8BBD3*
ID_OUI_FROM_DATABASE=Embrane
+OUI:C8BC9C*
+ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd.
+
OUI:C8BCC8*
ID_OUI_FROM_DATABASE=Apple, Inc.
@@ -94640,6 +94796,9 @@ OUI:CC82EB*
OUI:CC856C*
ID_OUI_FROM_DATABASE=SHENZHEN MDK DIGITAL TECHNOLOGY CO.,LTD
+OUI:CC874A*
+ ID_OUI_FROM_DATABASE=Nokia
+
OUI:CC8826*
ID_OUI_FROM_DATABASE=LG Innotek
@@ -94745,6 +94904,9 @@ OUI:CCAB2C*
OUI:CCAF78*
ID_OUI_FROM_DATABASE=Hon Hai Precision Ind. Co.,Ltd.
+OUI:CCB0A8*
+ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd.
+
OUI:CCB0DA*
ID_OUI_FROM_DATABASE=Liteon Technology Corporation
@@ -95117,6 +95279,9 @@ OUI:CCFD17*
OUI:CCFE3C*
ID_OUI_FROM_DATABASE=Samsung Electronics Co.,Ltd
+OUI:CCFF90*
+ ID_OUI_FROM_DATABASE=Huawei Device Co., Ltd.
+
OUI:D0034B*
ID_OUI_FROM_DATABASE=Apple, Inc.
@@ -98153,6 +98318,9 @@ OUI:DCA266*
OUI:DCA333*
ID_OUI_FROM_DATABASE=Shenzhen YOUHUA Technology Co., Ltd
+OUI:DCA3A2*
+ ID_OUI_FROM_DATABASE=Feng mi(Beijing)technology co., LTD
+
OUI:DCA3AC*
ID_OUI_FROM_DATABASE=RBcloudtech
@@ -101054,6 +101222,9 @@ OUI:EC55F9*
OUI:EC5623*
ID_OUI_FROM_DATABASE=HUAWEI TECHNOLOGIES CO.,LTD
+OUI:EC570D*
+ ID_OUI_FROM_DATABASE=AFE Inc.
+
OUI:EC58EA*
ID_OUI_FROM_DATABASE=Ruckus Wireless
@@ -103907,6 +104078,9 @@ OUI:F8A097*
OUI:F8A188*
ID_OUI_FROM_DATABASE=LED Roadway Lighting
+OUI:F8A26D*
+ ID_OUI_FROM_DATABASE=CANON INC.
+
OUI:F8A2B4*
ID_OUI_FROM_DATABASE=RHEWA-WAAGENFABRIK August Freudewald GmbH &Co. KG
diff --git a/hwdb.d/20-acpi-vendor.hwdb.patch b/hwdb.d/20-acpi-vendor.hwdb.patch
index 73f8864474..d2284b5c7e 100644
--- a/hwdb.d/20-acpi-vendor.hwdb.patch
+++ b/hwdb.d/20-acpi-vendor.hwdb.patch
@@ -1,5 +1,5 @@
---- 20-acpi-vendor.hwdb.base 2020-06-25 15:39:12.679783537 +0200
-+++ 20-acpi-vendor.hwdb 2020-06-25 15:39:12.697783719 +0200
+--- 20-acpi-vendor.hwdb.base 2020-07-06 17:50:38.655308539 +0200
++++ 20-acpi-vendor.hwdb 2020-07-06 17:50:38.678308990 +0200
@@ -3,6 +3,8 @@
# Data imported from:
# https://uefi.org/uefi-pnp-export
diff --git a/hwdb.d/60-keyboard.hwdb b/hwdb.d/60-keyboard.hwdb
index 5886ef2a63..3284cced1a 100644
--- a/hwdb.d/60-keyboard.hwdb
+++ b/hwdb.d/60-keyboard.hwdb
@@ -526,10 +526,15 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pnHP*Pavilion*dv7*Notebook*PC:
KEYBOARD_KEY_c6=break
KEYBOARD_KEY_94=reserved
-# Pavilion and Spectre x360 13 (Prevents random airplane mode activation)
+# Pavilion 13 x360 (Tablet mode and SYSRQ key)
+evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[pP][aA][vV][iI][lL][iI][oO][nN]*13*x360*:pvr*
+ KEYBOARD_KEY_d7=!f22 # touchpad off
+ KEYBOARD_KEY_d9=unknown
+ KEYBOARD_KEY_d2=sysrq # Fn+Print = SYSRQ
+
+# Spectre x360 13 (Prevents random airplane mode activation)
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[sS][pP][eE][cC][tT][rR][eE]*x360*13*:pvr*
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pn*[sS][pP][eE][cC][tT][rR][eE]*x360Convertible*:pvr*
-evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*[pP][aA][vV][iI][lL][iI][oO][nN]*13*x360*:pvr*
KEYBOARD_KEY_d7=unknown
# Spectre x360 13
diff --git a/hwdb.d/60-sensor.hwdb b/hwdb.d/60-sensor.hwdb
index b14b05fde6..576b314d3c 100644
--- a/hwdb.d/60-sensor.hwdb
+++ b/hwdb.d/60-sensor.hwdb
@@ -316,6 +316,10 @@ sensor:modalias:platform:cros-ec-accel:dmi:*:svnGoogle:pnCaroline*
sensor:modalias:platform:cros-ec-accel:dmi:*svnGoogle:pnVayne*
ACCEL_MOUNT_MATRIX=-1, 0, 0; 0, -1, 0; 0, 0, -1
+# nocturne board (Google Pixel Slate)
+sensor:modalias:platform:cros-ec-accel:dmi:*Google_Nocturne*
+ ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1
+
#########################################
# GP-electronic
#########################################
@@ -689,6 +693,9 @@ sensor:modalias:acpi:KIOX020A*:dmi:*:svnTREKSTOR:pnPRIMEBOOKC11B:*
#########################################
# Umax
#########################################
+sensor:modalias:acpi:KIOX000A*:dmi:*:svnUMAX:pnVisionBook10WiPro:*
+ ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1
+
sensor:modalias:acpi:SMO8500*:dmi:*:svnUMAX:pnVisionBook10WiPlus:*
ACCEL_MOUNT_MATRIX=0, -1, 0; -1, 0, 0; 0, 0, 1
diff --git a/hwdb.d/70-mouse.hwdb b/hwdb.d/70-mouse.hwdb
index 63ef1fba12..d0a2a22709 100644
--- a/hwdb.d/70-mouse.hwdb
+++ b/hwdb.d/70-mouse.hwdb
@@ -381,6 +381,10 @@ mouse:usb:v046dp101b:name:Logitech M705:
mouse:usb:v046dpc52b:name:Logitech Unifying Device. Wireless PID:101b:
MOUSE_DPI=1000@125
+# Logitech M705 (newer version?)
+mouse:usb:v046dp406d:name:Logitech M705:
+ MOUSE_DPI=1000@167
+
# Logitech M305 Wireless Optical Mouse
mouse:usb:v046dpc52f:name:Logitech USB Receiver:
MOUSE_DPI=1000@170
diff --git a/hwdb.d/ma-large.txt b/hwdb.d/ma-large.txt
index 4f0c9ea62a..4e30f6c49b 100644
--- a/hwdb.d/ma-large.txt
+++ b/hwdb.d/ma-large.txt
@@ -26045,12 +26045,6 @@ D4C766 (base 16) Acentic GmbH
Seoul
KR
-00-07-8E (hex) Garz & Friche GmbH
-00078E (base 16) Garz & Friche GmbH
- Tempowerhving 4
-
- DE
-
00-07-54 (hex) Xyterra Computing, Inc.
000754 (base 16) Xyterra Computing, Inc.
14505 Hayden Rd.,
@@ -34049,12 +34043,42 @@ B8DD71 (base 16) zte corporation
shenzhen guangdong 518057
CN
+78-F8-B8 (hex) Rako Controls Ltd
+78F8B8 (base 16) Rako Controls Ltd
+ Knight Road
+ Rochester Kent ME2 2AH
+ GB
+
00-16-12 (hex) Otsuka Electronics Co., Ltd.
001612 (base 16) Otsuka Electronics Co., Ltd.
1-10 Sasagaoka, Minakuchi
kouka shiga 528-0061
JP
+A4-51-29 (hex) XAG
+A45129 (base 16) XAG
+ Block C, 115 Gaopu Road
+ Guangzhou 510663
+ CN
+
+CC-87-4A (hex) Nokia
+CC874A (base 16) Nokia
+ 600 March Road
+ Kanata Ontario K2K 2E6
+ CA
+
+04-46-CF (hex) Beijing Venustech Cybervision Co.,Ltd.
+0446CF (base 16) Beijing Venustech Cybervision Co.,Ltd.
+ Venus Plaza No.21Zhongguancun Software Park,No.8 Dongbeiwang Xilu, Haidian District
+ Beijing Beijing 100193
+ CN
+
+00-07-8E (hex) Garz & Fricke GmbH
+00078E (base 16) Garz & Fricke GmbH
+ Schlachthofstrasse 20
+ Hamburg Hamburg 21079
+ DE
+
9C-FF-C2 (hex) AVI Systems GmbH
9CFFC2 (base 16) AVI Systems GmbH
Dr. Franz Wilhelmstraße 2A
@@ -61469,12 +61493,6 @@ D4AAFF (base 16) MICRO WORLD
Washington DC 20008
US
-00-30-54 (hex) CASTLENET TECHNOLOGY, INC.
-003054 (base 16) CASTLENET TECHNOLOGY, INC.
- NO. 130 WU-KUNG RD.,
- TAIWAN TAIWAN R.O.C.
- TW
-
00-30-0B (hex) mPHASE Technologies, Inc.
00300B (base 16) mPHASE Technologies, Inc.
250 14th Street
@@ -67385,12 +67403,60 @@ A4AE12 (base 16) Hon Hai Precision Ind. Co., Ltd.
ShenZhen GuangDong 518109
CN
+DC-A3-A2 (hex) Feng mi(Beijing)technology co., LTD
+DCA3A2 (base 16) Feng mi(Beijing)technology co., LTD
+ RenHe Town barracks south street 10 yuan 33 level 301
+ shunyi district Beijing 101300
+ CN
+
7C-25-DA (hex) FN-LINK TECHNOLOGY LIMITED
7C25DA (base 16) FN-LINK TECHNOLOGY LIMITED
A Building,HuiXin industial park,No 31, YongHe road, Fuyong town, Bao'an District
SHENZHEN GUANGDONG 518100
CN
+A8-69-8C (hex) Oracle Corporation
+A8698C (base 16) Oracle Corporation
+ 500 Oracle Parkway
+ Redwood Shores CA 94065
+ US
+
+EC-57-0D (hex) AFE Inc.
+EC570D (base 16) AFE Inc.
+ 11210 County Line Rd
+ Mount Pleasant WI 53177
+ US
+
+A4-AC-0F (hex) Huawei Device Co., Ltd.
+A4AC0F (base 16) Huawei Device Co., Ltd.
+ No.2 of Xincheng Road, Songshan Lake Zone
+ Dongguan Guangdong 523808
+ CN
+
+CC-FF-90 (hex) Huawei Device Co., Ltd.
+CCFF90 (base 16) Huawei Device Co., Ltd.
+ No.2 of Xincheng Road, Songshan Lake Zone
+ Dongguan Guangdong 523808
+ CN
+
+54-05-DB (hex) LCFC(HeFei) Electronics Technology co., ltd
+5405DB (base 16) LCFC(HeFei) Electronics Technology co., ltd
+ YunGu Road 3188-1
+ Hefei Anhui 230000
+ CN
+
+44-A5-4E (hex) Qorvo Utrecht B.V.
+44A54E (base 16) Qorvo Utrecht B.V.
+ Leidseveer 10
+ Utrecht Utrecht 3511SB
+ NL
+
+00-30-54 (hex) Castlenet Technology Inc.
+003054 (base 16) Castlenet Technology Inc.
+ NO. 130 WU-KUNG RD.,
+ TAIWAN TAIWAN R.O.C.
+ TW
+
84-80-94 (hex) Meter, Inc.
848094 (base 16) Meter, Inc.
148 Townsend St
@@ -101240,6 +101306,36 @@ DCCD2F (base 16) Seiko Epson Corporation
shenzhen guangdong 518057
CN
+8C-8D-28 (hex) Intel Corporate
+8C8D28 (base 16) Intel Corporate
+ Lot 8, Jalan Hi-Tech 2/3
+ Kulim Kedah 09000
+ MY
+
+34-3E-A4 (hex) Ring LLC
+343EA4 (base 16) Ring LLC
+ 1523 26th St
+ Santa Monica CA 90404
+ US
+
+B0-FE-E5 (hex) Huawei Device Co., Ltd.
+B0FEE5 (base 16) Huawei Device Co., Ltd.
+ No.2 of Xincheng Road, Songshan Lake Zone
+ Dongguan Guangdong 523808
+ CN
+
+04-C1-D8 (hex) Huawei Device Co., Ltd.
+04C1D8 (base 16) Huawei Device Co., Ltd.
+ No.2 of Xincheng Road, Songshan Lake Zone
+ Dongguan Guangdong 523808
+ CN
+
+C8-BC-9C (hex) Huawei Device Co., Ltd.
+C8BC9C (base 16) Huawei Device Co., Ltd.
+ No.2 of Xincheng Road, Songshan Lake Zone
+ Dongguan Guangdong 523808
+ CN
+
F8-D0-27 (hex) Seiko Epson Corporation
F8D027 (base 16) Seiko Epson Corporation
2070 Kotobuki Koaka
@@ -134828,18 +134924,24 @@ B0B113 (base 16) Texas Instruments
Holzkirchen 83607
DE
+24-B1-05 (hex) Prama Hikvision India Private Limited
+24B105 (base 16) Prama Hikvision India Private Limited
+ Prama Hikvision India Pvt Ltd, Akurli Cross Road No 1, Kandivali East
+ Mumbai Maharashtra 400101
+ IN
+
+70-9C-D1 (hex) Intel Corporate
+709CD1 (base 16) Intel Corporate
+ Lot 8, Jalan Hi-Tech 2/3
+ Kulim Kedah 09000
+ MY
+
80-60-B7 (hex) CLOUD NETWORK TECHNOLOGY SINGAPORE PTE. LTD.
8060B7 (base 16) CLOUD NETWORK TECHNOLOGY SINGAPORE PTE. LTD.
B22 Building,NO.51 Tongle Road, Shajing Town, Jiangnan District, Nanning, Guangxi Province, China
Nanning Guangxi 530007
CN
-34-20-E3 (hex) Ruckus Wireless
-3420E3 (base 16) Ruckus Wireless
- 350 West Java Drive
- Sunnyvale CA 94089
- US
-
90-AA-C3 (hex) Hitron Technologies. Inc
90AAC3 (base 16) Hitron Technologies. Inc
No. 1-8, Lising 1st Rd. Hsinchu Science Park, Hsinchu, 300, Taiwan, R.O.C
@@ -134858,6 +134960,42 @@ DC7223 (base 16) Hui Zhou Gaoshengda Technology Co.,LTD
Hui Zhou Guangdong 516006
CN
+34-20-E3 (hex) Ruckus Wireless
+3420E3 (base 16) Ruckus Wireless
+ 350 West Java Drive
+ Sunnyvale CA 94089
+ US
+
+8C-47-BE (hex) Dell Inc.
+8C47BE (base 16) Dell Inc.
+ One Dell Way
+ Round Rock TX 78682
+ US
+
+20-F4-4F (hex) Nokia
+20F44F (base 16) Nokia
+ 600 March Road
+ Kanata Ontario K2K 2E6
+ CA
+
+24-5F-9F (hex) Huawei Device Co., Ltd.
+245F9F (base 16) Huawei Device Co., Ltd.
+ No.2 of Xincheng Road, Songshan Lake Zone
+ Dongguan Guangdong 523808
+ CN
+
+CC-B0-A8 (hex) Huawei Device Co., Ltd.
+CCB0A8 (base 16) Huawei Device Co., Ltd.
+ No.2 of Xincheng Road, Songshan Lake Zone
+ Dongguan Guangdong 523808
+ CN
+
+50-28-73 (hex) Huawei Device Co., Ltd.
+502873 (base 16) Huawei Device Co., Ltd.
+ No.2 of Xincheng Road, Songshan Lake Zone
+ Dongguan Guangdong 523808
+ CN
+
7C-8A-E1 (hex) COMPAL INFORMATION (KUNSHAN) CO., LTD.
7C8AE1 (base 16) COMPAL INFORMATION (KUNSHAN) CO., LTD.
NO. 25, THE 3RD Street KUNSHAN EXPORT PROCESSING ZONE
@@ -168581,20 +168719,56 @@ CCB182 (base 16) HUAWEI TECHNOLOGIES CO.,LTD
Piscataway NJ 08554
US
-F4-BF-A8 (hex) Juniper Networks
-F4BFA8 (base 16) Juniper Networks
- 1133 Innovation Way
- Sunnyvale CA 94089
- US
-
28-C2-1F (hex) SAMSUNG ELECTRO-MECHANICS(THAILAND)
28C21F (base 16) SAMSUNG ELECTRO-MECHANICS(THAILAND)
93Moo5T. Bangsamak SEMTHAI, WELLGROW INDUSTRIAL ESTATE
Bangpakong Chachoengsao 24180
TH
+5C-7D-7D (hex) Technicolor CH USA Inc.
+5C7D7D (base 16) Technicolor CH USA Inc.
+ 5030 Sugarloaf Parkway Bldg 6
+ Lawrenceville GA 30044
+ US
+
+B0-7D-64 (hex) Intel Corporate
+B07D64 (base 16) Intel Corporate
+ Lot 8, Jalan Hi-Tech 2/3
+ Kulim Kedah 09000
+ MY
+
+F4-BF-A8 (hex) Juniper Networks
+F4BFA8 (base 16) Juniper Networks
+ 1133 Innovation Way
+ Sunnyvale CA 94089
+ US
+
C0-61-9A (hex) IEEE Registration Authority
C0619A (base 16) IEEE Registration Authority
445 Hoes Lane
Piscataway NJ 08554
US
+
+70-61-EE (hex) Sunwoda Electronic Co.,Ltd
+7061EE (base 16) Sunwoda Electronic Co.,Ltd
+ No 2,Yihe Road, shiyan Street?shilong Community ,Baoan District
+ Shenzhen 518105
+ CN
+
+40-06-34 (hex) Huawei Device Co., Ltd.
+400634 (base 16) Huawei Device Co., Ltd.
+ No.2 of Xincheng Road, Songshan Lake Zone
+ Dongguan Guangdong 523808
+ CN
+
+C4-2B-44 (hex) Huawei Device Co., Ltd.
+C42B44 (base 16) Huawei Device Co., Ltd.
+ No.2 of Xincheng Road, Songshan Lake Zone
+ Dongguan Guangdong 523808
+ CN
+
+F8-A2-6D (hex) CANON INC.
+F8A26D (base 16) CANON INC.
+ 30-2 Shimomaruko 3-chome,
+ Ohta-ku Tokyo 146-8501
+ JP
diff --git a/hwdb.d/ma-medium.txt b/hwdb.d/ma-medium.txt
index dbf33ec70e..d46c9dabde 100644
--- a/hwdb.d/ma-medium.txt
+++ b/hwdb.d/ma-medium.txt
@@ -3539,12 +3539,6 @@ E00000-EFFFFF (base 16) Nanjing Yining Intelligent Technology Co., Ltd.
Nanjing Jiangsu 210019
CN
-B0-B3-53 (hex) Blake UK
-000000-0FFFFF (base 16) Blake UK
- 177-187, Rutland Road
- Sheffield --select-- S3 9PT
- GB
-
B0-B3-53 (hex) Beijing Geekplus Technology Co.,Ltd.
C00000-CFFFFF (base 16) Beijing Geekplus Technology Co.,Ltd.
1st Floor, Building 1, Chaolai High-Tech industrial Part, Chaoyang District
@@ -3557,6 +3551,12 @@ D00000-DFFFFF (base 16) IPvideo Corporation
Bay Shore NY 11706
US
+B0-B3-53 (hex) Blake UK
+000000-0FFFFF (base 16) Blake UK
+ 177-187, Rutland Road
+ Sheffield --select-- S3 9PT
+ GB
+
B0-B3-53 (hex) Zoox
B00000-BFFFFF (base 16) Zoox
1149 Chess Drive
@@ -3575,30 +3575,30 @@ B00000-BFFFFF (base 16) Zoox
New Taipei City Xizhi Dist 221
TW
-64-62-66 (hex) Annapurna labs
-100000-1FFFFF (base 16) Annapurna labs
- Matam Scientific Industries Center, Building 8.2
- Mail box 15123 Haifa 3508409
- IL
-
14-AE-85 (hex) MTA Systems
A00000-AFFFFF (base 16) MTA Systems
Pemstraße 2
Mauthausen 4310
AT
-64-62-66 (hex) Bühler AG
-500000-5FFFFF (base 16) Bühler AG
- Gupfenstrasse 5
- Uzwil 9240
- CH
-
64-62-66 (hex) MiiVii Dynamics Technology CO.,LTD
000000-0FFFFF (base 16) MiiVii Dynamics Technology CO.,LTD
1408-1415 Tower A BUGG Building,No.18 N. Taipingzhuang Rd,haidian District
Beijing Beijing 100000
CN
+64-62-66 (hex) Annapurna labs
+100000-1FFFFF (base 16) Annapurna labs
+ Matam Scientific Industries Center, Building 8.2
+ Mail box 15123 Haifa 3508409
+ IL
+
+64-62-66 (hex) Bühler AG
+500000-5FFFFF (base 16) Bühler AG
+ Gupfenstrasse 5
+ Uzwil 9240
+ CH
+
64-62-66 (hex) Shenzhen Jie Shi Lian Industrial Co., LTD
E00000-EFFFFF (base 16) Shenzhen Jie Shi Lian Industrial Co., LTD
6F,C Building,Jinao Industrial Park,Juling Rd,Guanlan Town,Longhua
@@ -3611,24 +3611,30 @@ E00000-EFFFFF (base 16) Shenzhen Jie Shi Lian Industrial Co., LTD
Hong Kong Hong Kong 00000
HK
-94-CC-04 (hex) Hanzhuo Information Technology(Shanghai) Ltd.
-D00000-DFFFFF (base 16) Hanzhuo Information Technology(Shanghai) Ltd.
- Room 2085, building 2, 622 Yingyuan middle Road, Jiading Strict
- Shanghai 201200
- CN
-
94-CC-04 (hex) Sam Nazarko Trading Ltd
600000-6FFFFF (base 16) Sam Nazarko Trading Ltd
18 Watermill Way
London Surrey SW19 2RD
GB
+94-CC-04 (hex) Hanzhuo Information Technology(Shanghai) Ltd.
+D00000-DFFFFF (base 16) Hanzhuo Information Technology(Shanghai) Ltd.
+ Room 2085, building 2, 622 Yingyuan middle Road, Jiading Strict
+ Shanghai 201200
+ CN
+
94-CC-04 (hex) hyBee Inc.
A00000-AFFFFF (base 16) hyBee Inc.
#1003, Innovalley B, 253, Pangyo-ro, Bundang-gu
Seongnam-si Gyeonggi-do 13486
KR
+94-05-BB (hex) iungo
+800000-8FFFFF (base 16) iungo
+ Vrouwenlaan 62
+ Zwolle Overijssel 8017 HS
+ NL
+
94-CC-04 (hex) Nanjing Yacer Communication Technology Co. Ltd.
200000-2FFFFF (base 16) Nanjing Yacer Communication Technology Co. Ltd.
333 Taiping South Road Jinling Yujingyuan 19nd  floor Unit K Qin Huai District
@@ -3641,78 +3647,72 @@ A00000-AFFFFF (base 16) hyBee Inc.
Dubai 90072
AE
-94-05-BB (hex) iungo
-800000-8FFFFF (base 16) iungo
- Vrouwenlaan 62
- Zwolle Overijssel 8017 HS
- NL
-
-94-05-BB (hex) Qingdao Maotran Electronics co., ltd
-000000-0FFFFF (base 16) Qingdao Maotran Electronics co., ltd
- Room2907, Building 2 of Minghui International, No.39 of Shiling Road, Laoshan District
- Qingdao Shandong 266000
- CN
-
94-05-BB (hex) Dongguan CXWE Technology Co.,Ltd.
200000-2FFFFF (base 16) Dongguan CXWE Technology Co.,Ltd.
Room 805, building 1, No. 16, Keji 4th Road, Songshanhu
Dongguan Guangdong 523000
CN
-F4-90-CB (hex) Cheetah Medical
-C00000-CFFFFF (base 16) Cheetah Medical
- 2A Hashlosha st.
- Tel Aviv 6706055
- IL
-
94-05-BB (hex) Zimmer GmbH
900000-9FFFFF (base 16) Zimmer GmbH
Im Salmenkopf 5
Rheinau Baden-Württemberg 77866
DE
+94-05-BB (hex) Qingdao Maotran Electronics co., ltd
+000000-0FFFFF (base 16) Qingdao Maotran Electronics co., ltd
+ Room2907, Building 2 of Minghui International, No.39 of Shiling Road, Laoshan District
+ Qingdao Shandong 266000
+ CN
+
94-05-BB (hex) BAE Systems
E00000-EFFFFF (base 16) BAE Systems
21 continental boulevard
Merrimack NH 03054
US
+F4-90-CB (hex) Cheetah Medical
+C00000-CFFFFF (base 16) Cheetah Medical
+ 2A Hashlosha st.
+ Tel Aviv 6706055
+ IL
+
F4-90-CB (hex) A-dec Inc.
B00000-BFFFFF (base 16) A-dec Inc.
2601 Crestview Drive
Newberg OR 97132
US
-94-05-BB (hex) LTE-X, Inc
-700000-7FFFFF (base 16) LTE-X, Inc
- 4F Ginza Showa Dori Building 8-14-14 Ginza
- Chuo-ku Tokyo 104-0062
- JP
-
C0-9B-F4 (hex) LTD Delovoy Office
600000-6FFFFF (base 16) LTD Delovoy Office
Block “B”, floor 6, build 4/1, Stroiteley blvd
Krasnogorsk 143401
RU
+94-05-BB (hex) LTE-X, Inc
+700000-7FFFFF (base 16) LTE-X, Inc
+ 4F Ginza Showa Dori Building 8-14-14 Ginza
+ Chuo-ku Tokyo 104-0062
+ JP
+
F4-90-CB (hex) TEQ SA
700000-7FFFFF (base 16) TEQ SA
Via al Municipio 16
Barbengo Ticino 6917
CH
-A4-DA-22 (hex) Grundig
-A00000-AFFFFF (base 16) Grundig
- Steinhof 39
- Erkrath North Rhine-Westphalia 40699
- DE
-
E8-B4-70 (hex) YAWATA ELECTRIC INDUSTRIAL CO.,LTD.
400000-4FFFFF (base 16) YAWATA ELECTRIC INDUSTRIAL CO.,LTD.
1-17-1 Ohmorihigashi
Ohta-ku Tokyo 143-0012
JP
+A4-DA-22 (hex) Grundig
+A00000-AFFFFF (base 16) Grundig
+ Steinhof 39
+ Erkrath North Rhine-Westphalia 40699
+ DE
+
E8-B4-70 (hex) Tibit Communications
700000-7FFFFF (base 16) Tibit Communications
1 Willowbrook Court, Suite 150
@@ -3731,6 +3731,12 @@ E8-B4-70 (hex) Tibit Communications
Zhonghe Dist. New Taipei City 23512
TW
+94-FB-A7 (hex) Reichert Inc.
+000000-0FFFFF (base 16) Reichert Inc.
+ 3362 Walden Ave
+ Depew NY 14043
+ US
+
38-F7-CD (hex) VANGUARD
300000-3FFFFF (base 16) VANGUARD
1st Floor 3 Moore
@@ -3749,12 +3755,6 @@ B00000-BFFFFF (base 16) Fibergate Inc.
Tokyo Minato-ku 1050012
JP
-94-FB-A7 (hex) Reichert Inc.
-000000-0FFFFF (base 16) Reichert Inc.
- 3362 Walden Ave
- Depew NY 14043
- US
-
38-F7-CD (hex) Fast Cotton(Beijing) Limited
600000-6FFFFF (base 16) Fast Cotton(Beijing) Limited
Fast Cotton(Beijing)Limited
@@ -3797,11 +3797,11 @@ B00000-BFFFFF (base 16) EVCO SPA
SEDICO BELLUNO 32036
IT
-F0-D7-AF (hex) Rievtech Electronic Co.,Ltd
-700000-7FFFFF (base 16) Rievtech Electronic Co.,Ltd
- Room 505, Building A, No.88,Dazhou Road,Tiexinqiao,Yu huatai District, Nanjing City, Jiangsu Province,P.R.China +0086 25 52895099 52890138 info@rievtech.com sales@rievtech.com
- Nanjing City Jiangsu Province 210000
- CN
+AC-1D-DF (hex) FINEpowerX INC
+B00000-BFFFFF (base 16) FINEpowerX INC
+ Rm 2208, U-Tower, 120 HeungDeok JungAng-ro, GiHeung-Gu
+ YongIn-si Gyeonggi-do 16950
+ KR
F0-D7-AF (hex) Shenzhen Virtual Clusters Information Technology Co.,Ltd.
C00000-CFFFFF (base 16) Shenzhen Virtual Clusters Information Technology Co.,Ltd.
@@ -3809,11 +3809,11 @@ C00000-CFFFFF (base 16) Shenzhen Virtual Clusters Information Technology Co
Shenzhen 518054
CN
-AC-1D-DF (hex) FINEpowerX INC
-B00000-BFFFFF (base 16) FINEpowerX INC
- Rm 2208, U-Tower, 120 HeungDeok JungAng-ro, GiHeung-Gu
- YongIn-si Gyeonggi-do 16950
- KR
+F0-D7-AF (hex) Rievtech Electronic Co.,Ltd
+700000-7FFFFF (base 16) Rievtech Electronic Co.,Ltd
+ Room 505, Building A, No.88,Dazhou Road,Tiexinqiao,Yu huatai District, Nanjing City, Jiangsu Province,P.R.China +0086 25 52895099 52890138 info@rievtech.com sales@rievtech.com
+ Nanjing City Jiangsu Province 210000
+ CN
30-49-50 (hex) ATLI WORLD LIMITED
100000-1FFFFF (base 16) ATLI WORLD LIMITED
@@ -3821,66 +3821,54 @@ B00000-BFFFFF (base 16) FINEpowerX INC
Kowloon Hong Kong 852
HK
-30-49-50 (hex) Anacove LLC
-C00000-CFFFFF (base 16) Anacove LLC
- 7856 Revelle drive
- LA JOLLA CA 92037
- US
-
30-49-50 (hex) Ledworks SRL
A00000-AFFFFF (base 16) Ledworks SRL
Via Tortona 37
Milano Milano 20144
IT
-D0-14-11 (hex) CYLTek Co.,LTD.
-B00000-BFFFFF (base 16) CYLTek Co.,LTD.
- R603,6F.,NO.168,Sec.2,Fuxing 3rd.Rd.
- Zhubei City,Hsinchu County 30273
- TW
-
-D0-D9-4F (hex) Mitsubishi Electric US, Inc.
-700000-7FFFFF (base 16) Mitsubishi Electric US, Inc.
- 1340 Satellite Boulevard
- Suwanee GA 30345
- US
-
30-49-50 (hex) Sercomm Corporation.
200000-2FFFFF (base 16) Sercomm Corporation.
3F,No.81,Yu-Yih Rd.,Chu-Nan Chen
Miao-Lih Hsuan 115
TW
+30-49-50 (hex) Anacove LLC
+C00000-CFFFFF (base 16) Anacove LLC
+ 7856 Revelle drive
+ LA JOLLA CA 92037
+ US
+
D0-14-11 (hex) powerall
400000-4FFFFF (base 16) powerall
75,Ojeong-ro,Bucheon-si,Gyeonggi-do,Republic of korea
Gyeonggi-do province 14445
KR
+D0-14-11 (hex) CYLTek Co.,LTD.
+B00000-BFFFFF (base 16) CYLTek Co.,LTD.
+ R603,6F.,NO.168,Sec.2,Fuxing 3rd.Rd.
+ Zhubei City,Hsinchu County 30273
+ TW
+
D0-14-11 (hex) ABB EVI SPA
A00000-AFFFFF (base 16) ABB EVI SPA
VIA DI SAN GIORGIO, 642
TERRANUOVA BRACCIOLINI AREZZO 52028
IT
+D0-D9-4F (hex) Mitsubishi Electric US, Inc.
+700000-7FFFFF (base 16) Mitsubishi Electric US, Inc.
+ 1340 Satellite Boulevard
+ Suwanee GA 30345
+ US
+
D0-14-11 (hex) Airthings
900000-9FFFFF (base 16) Airthings
Wergelandsveien 7
Oslo 0167
NO
-F4-69-D5 (hex) ShenZhenShi EVADA technology Co.,Ltd
-A00000-AFFFFF (base 16) ShenZhenShi EVADA technology Co.,Ltd
- Qianhai,No.1 qianwan Road
- ShenZhen Guangdong 518000
- CN
-
-F4-69-D5 (hex) Mossman Limited
-000000-0FFFFF (base 16) Mossman Limited
- 1014, 10/F, Leader Industrial Building,
- 57-59 Au Pui Wan Street, Fotan, Shatin Hong Kong NT
- HK
-
5C-85-7E (hex) Shenzhen IP3 Century Intelligent Technology CO.,Ltd
400000-4FFFFF (base 16) Shenzhen IP3 Century Intelligent Technology CO.,Ltd
aiying.li@ip3-tech.com
@@ -3893,6 +3881,18 @@ F4-69-D5 (hex) Mossman Limited
ShangHai 201100
CN
+F4-69-D5 (hex) ShenZhenShi EVADA technology Co.,Ltd
+A00000-AFFFFF (base 16) ShenZhenShi EVADA technology Co.,Ltd
+ Qianhai,No.1 qianwan Road
+ ShenZhen Guangdong 518000
+ CN
+
+F4-69-D5 (hex) Mossman Limited
+000000-0FFFFF (base 16) Mossman Limited
+ 1014, 10/F, Leader Industrial Building,
+ 57-59 Au Pui Wan Street, Fotan, Shatin Hong Kong NT
+ HK
+
5C-85-7E (hex) ProdataKey
600000-6FFFFF (base 16) ProdataKey
67 W 13490 S
@@ -3932,24 +3932,42 @@ F4-69-D5 (hex) Rosco, Inc
Nanjing Jiangsu 211100
CN
-4C-93-A6 (hex) Commsignia, Ltd.
-300000-3FFFFF (base 16) Commsignia, Ltd.
- Irinyi Jozsef u 4-20
- Budapest 1117
- HU
-
28-B7-7C (hex) Shenzhen PUAS Industrial Co.,LTD
800000-8FFFFF (base 16) Shenzhen PUAS Industrial Co.,LTD
2/F, C/Building, Huawang Industrial Park, LongHua New Area In Shenzhen 518106 P.R.C
Shenzhen Guangdong 518106
CN
+4C-93-A6 (hex) Commsignia, Ltd.
+300000-3FFFFF (base 16) Commsignia, Ltd.
+ Irinyi Jozsef u 4-20
+ Budapest 1117
+ HU
+
28-B7-7C (hex) SolarEdge Technologies
100000-1FFFFF (base 16) SolarEdge Technologies
1 Abba Eban St.
Herzelia 46725
IL
+C0-61-9A (hex) Nanjing Balance Network Technology Co., Ltd
+500000-5FFFFF (base 16) Nanjing Balance Network Technology Co., Ltd
+ 9-10/F,building 01, No.8,Bailongjiang East Street,Jianye District
+ Nanjing Jiangsu 210017
+ CN
+
+C0-61-9A (hex) MAD PIECE LLC.
+700000-7FFFFF (base 16) MAD PIECE LLC.
+ 2196 flatbush ave.
+ BROOKLYN NY 11234
+ US
+
+C0-61-9A (hex) Uhnder
+D00000-DFFFFF (base 16) Uhnder
+ 3409 Executive Center Drive Ste205
+ Austin TX 78731
+ US
+
4C-4B-F9 (hex) Shenzhen dingsheng technology co., LTD
400000-4FFFFF (base 16) Shenzhen dingsheng technology co., LTD
Floor 3, building 5, kaijeda industrial zone, no.97, huaxing road, langkou community, dalang street, longhua district
@@ -7376,18 +7394,18 @@ B00000-BFFFFF (base 16) Shenzhen Dingsheng Intelligent Technology Co., Ltd
Chengdu Sichuan 611731
CN
-94-CC-04 (hex) Shanxi Baixin Information Technology Co., Ltd.
-C00000-CFFFFF (base 16) Shanxi Baixin Information Technology Co., Ltd.
- Room 210-213, Room 215-217, Room 219-220, No.2, Yari Street, Taiyuan University Park, Shanxi Comprehensive Reform Demonstration Zone
- Taiyuan Shanxi 030032
- CN
-
D0-C8-57 (hex) IFLYTEK CO.,LTD.
D00000-DFFFFF (base 16) IFLYTEK CO.,LTD.
National Intelligent Speech High-tech Industrialization Base, No. 666, Wangjiang Road West,
Hefei An hui 230088
CN
+94-CC-04 (hex) Shanxi Baixin Information Technology Co., Ltd.
+C00000-CFFFFF (base 16) Shanxi Baixin Information Technology Co., Ltd.
+ Room 210-213, Room 215-217, Room 219-220, No.2, Yari Street, Taiyuan University Park, Shanxi Comprehensive Reform Demonstration Zone
+ Taiyuan Shanxi 030032
+ CN
+
94-05-BB (hex) ZIGPOS GmbH
600000-6FFFFF (base 16) ZIGPOS GmbH
Räcknitzhöhe 35a
@@ -7430,18 +7448,18 @@ C0-9B-F4 (hex) Big Dutchman International GmbH
Vechta Niedersachsen 49377
DE
-C0-9B-F4 (hex) Continental Automotive Component Malaysia Sdn.Bhd.
-E00000-EFFFFF (base 16) Continental Automotive Component Malaysia Sdn.Bhd.
- 2455, MK.1, Tingkat Perusahaan 2A,
- Prai Industrial Estate, Prai, Penang 13600
- MY
-
E8-B4-70 (hex) Anduril Industries
C00000-CFFFFF (base 16) Anduril Industries
2272 Michelson Dr
Irvine CA 92612
US
+C0-9B-F4 (hex) Continental Automotive Component Malaysia Sdn.Bhd.
+E00000-EFFFFF (base 16) Continental Automotive Component Malaysia Sdn.Bhd.
+ 2455, MK.1, Tingkat Perusahaan 2A,
+ Prai Industrial Estate, Prai, Penang 13600
+ MY
+
E8-B4-70 (hex) Webfleet Solutions B.V.
300000-3FFFFF (base 16) Webfleet Solutions B.V.
De Ruijterkade 154
@@ -7454,11 +7472,11 @@ D00000-DFFFFF (base 16) Medica Corporation
Bedford MA 01730
US
-94-FB-A7 (hex) Shenzhen Golden Star Technology Ltd
-B00000-BFFFFF (base 16) Shenzhen Golden Star Technology Ltd
- Rm.622,building B,MingYou Industrial products Exhibition&Procurement center, Baoyuan Road,Xixiang,Bao’an District,
- Shenzhen Guangdong 518000
- CN
+94-FB-A7 (hex) Sercomm Corporation.
+600000-6FFFFF (base 16) Sercomm Corporation.
+ 3F,No.81,Yu-Yih Rd.,Chu-Nan Chen
+ Miao-Lih Hsuan 115
+ TW
94-FB-A7 (hex) GUANG DONG TAKSTAR ELECTRONIC CO.,LTD.
300000-3FFFFF (base 16) GUANG DONG TAKSTAR ELECTRONIC CO.,LTD.
@@ -7472,23 +7490,17 @@ C00000-CFFFFF (base 16) Solaborate Inc.
Rancho Cucamonga CA 91730
US
-94-FB-A7 (hex) Sercomm Corporation.
-600000-6FFFFF (base 16) Sercomm Corporation.
- 3F,No.81,Yu-Yih Rd.,Chu-Nan Chen
- Miao-Lih Hsuan 115
- TW
-
94-FB-A7 (hex) CAVITY EYE
500000-5FFFFF (base 16) CAVITY EYE
Ébner György köz 4.
Budaörs 2040
HU
-94-FB-A7 (hex) Anvil Systems Group, Inc.
-700000-7FFFFF (base 16) Anvil Systems Group, Inc.
- 8211 Terminal Road, Suite 1900
- Lorton VA 22079
- US
+94-FB-A7 (hex) Shenzhen Golden Star Technology Ltd
+B00000-BFFFFF (base 16) Shenzhen Golden Star Technology Ltd
+ Rm.622,building B,MingYou Industrial products Exhibition&Procurement center, Baoyuan Road,Xixiang,Bao’an District,
+ Shenzhen Guangdong 518000
+ CN
38-F7-CD (hex) NZIA Connect Inc
100000-1FFFFF (base 16) NZIA Connect Inc
@@ -7496,6 +7508,12 @@ C00000-CFFFFF (base 16) Solaborate Inc.
Incheon 21315
KR
+94-FB-A7 (hex) Anvil Systems Group, Inc.
+700000-7FFFFF (base 16) Anvil Systems Group, Inc.
+ 8211 Terminal Road, Suite 1900
+ Lorton VA 22079
+ US
+
38-F7-CD (hex) Distech Controls
A00000-AFFFFF (base 16) Distech Controls
4205 place de Java
@@ -7598,12 +7616,6 @@ F4-69-D5 (hex) Terminus (Shanghai) Technology Co.,Ltd.
Miao-Lih Hsuan 115
TW
-4C-93-A6 (hex) Shandong Senter Electronic Co., Ltd
-600000-6FFFFF (base 16) Shandong Senter Electronic Co., Ltd
- No. 18 Liuyishan Road, New&High-tech area
- Zibo Shandong 255086
- CN
-
4C-93-A6 (hex) 5Voxel Co., Ltd.
700000-7FFFFF (base 16) 5Voxel Co., Ltd.
6F-2, No.273, Nong-an St.
@@ -7616,11 +7628,11 @@ F4-69-D5 (hex) Terminus (Shanghai) Technology Co.,Ltd.
-4C-93-A6 (hex) CELLTRON
-E00000-EFFFFF (base 16) CELLTRON
- #601 L&C TOWER, 153-18 LS-ro,Sanbon
- Gunpo Gyeonggi 15808
- KR
+28-B7-7C (hex) Annapurna labs
+400000-4FFFFF (base 16) Annapurna labs
+ Matam Scientific Industries Center, Building 8.2
+ Mail box 15123 Haifa 3508409
+ IL
28-B7-7C (hex) Zhuhai RongBang Electronic Technology Co., Ltd.
200000-2FFFFF (base 16) Zhuhai RongBang Electronic Technology Co., Ltd.
@@ -7628,11 +7640,17 @@ E00000-EFFFFF (base 16) CELLTRON
Zhuhai GuangDong 519000
CN
-28-B7-7C (hex) Annapurna labs
-400000-4FFFFF (base 16) Annapurna labs
- Matam Scientific Industries Center, Building 8.2
- Mail box 15123 Haifa 3508409
- IL
+4C-93-A6 (hex) Shandong Senter Electronic Co., Ltd
+600000-6FFFFF (base 16) Shandong Senter Electronic Co., Ltd
+ No. 18 Liuyishan Road, New&High-tech area
+ Zibo Shandong 255086
+ CN
+
+4C-93-A6 (hex) CELLTRON
+E00000-EFFFFF (base 16) CELLTRON
+ #601 L&C TOWER, 153-18 LS-ro,Sanbon
+ Gunpo Gyeonggi 15808
+ KR
28-B7-7C (hex) Convertertec Deutschland GmbH
700000-7FFFFF (base 16) Convertertec Deutschland GmbH
@@ -7640,6 +7658,24 @@ E00000-EFFFFF (base 16) CELLTRON
Kempen 47906
DE
+C0-61-9A (hex) Wingtech Mobile Communications Co.,Ltd.
+900000-9FFFFF (base 16) Wingtech Mobile Communications Co.,Ltd.
+ No.777,Yazhong Road,Nanhu District
+ Jiaxing Zhejiang 314001
+ CN
+
+C0-61-9A (hex) Nanjing SinoVatio Technology Co., Ltd
+800000-8FFFFF (base 16) Nanjing SinoVatio Technology Co., Ltd
+ No. 888 Zhengfang Middle Rd, Jiangning District
+ Nanjing JiangSu 211153
+ CN
+
+C0-61-9A (hex) Gronn Kontakt AS
+A00000-AFFFFF (base 16) Gronn Kontakt AS
+ Kjøita 18
+ Kristiansand 4630
+ NO
+
20-85-93 (hex) UNILUMIN GROUP CO.,LTD
300000-3FFFFF (base 16) UNILUMIN GROUP CO.,LTD
No.112 Yongfu Rd.,BaoanDistrict,
@@ -11141,24 +11177,18 @@ F4-90-CB (hex) Avilution
Madison AL 35758
US
-F4-90-CB (hex) OmniNet
-400000-4FFFFF (base 16) OmniNet
- 6410 Del Rio Rd
- Charlotte NC 28277
- US
-
-F4-90-CB (hex) Epitel, Inc.
-000000-0FFFFF (base 16) Epitel, Inc.
- 630 S. Stringfellow Ct., Unit #B
- Salt Lake City UT 84111
- US
-
F4-90-CB (hex) Fractyl Labs
900000-9FFFFF (base 16) Fractyl Labs
17 HARTWELL AVE
LEXINGTON MA 02421
US
+F4-90-CB (hex) OmniNet
+400000-4FFFFF (base 16) OmniNet
+ 6410 Del Rio Rd
+ Charlotte NC 28277
+ US
+
C0-9B-F4 (hex) JSC NPK ATRONIK
400000-4FFFFF (base 16) JSC NPK ATRONIK
VARSHAVSKOE SH, 118-1-P XLII K4 10
@@ -11171,6 +11201,12 @@ C00000-CFFFFF (base 16) Pinpark Inc.
Taipei Taiwan 104
TW
+F4-90-CB (hex) Epitel, Inc.
+000000-0FFFFF (base 16) Epitel, Inc.
+ 630 S. Stringfellow Ct., Unit #B
+ Salt Lake City UT 84111
+ US
+
C0-9B-F4 (hex) NUCTECH COMPANY LIMITED
B00000-BFFFFF (base 16) NUCTECH COMPANY LIMITED
2/F Block A,Tongfang Building,Shuangqinglu,Haidian District
@@ -11183,18 +11219,6 @@ C0-9B-F4 (hex) Osprey Video, Inc
Carrollton TX 75006
US
-E8-B4-70 (hex) internet domain name system beijing engineering research center ltd
-200000-2FFFFF (base 16) internet domain name system beijing engineering research center ltd
- 4,4TH SOUTH STREET ZHONG GUAN CUN
- hai dian qu ,beijing BEIJING 100190
- CN
-
-E8-B4-70 (hex) DongGuan Ramaxel Memory Technology
-000000-0FFFFF (base 16) DongGuan Ramaxel Memory Technology
- No.32, Industrial East Road,Innovation Park, High-tech Industrial Development Zone, Songshan Lake, Dongguan City, Guangdong Province,China
- DongGuan Guangdong 523808
- CN
-
C0-9B-F4 (hex) Infiot Inc.
500000-5FFFFF (base 16) Infiot Inc.
75 E. Santa Clara St., Suite 600
@@ -11207,23 +11231,29 @@ A00000-AFFFFF (base 16) plc2 Design GmbH
Freiburg i. Br. 79112
DE
-E8-B4-70 (hex) Miltek Industries Pte Ltd
-900000-9FFFFF (base 16) Miltek Industries Pte Ltd
- 62 Ubi Road 1 #10-03, Oxley Bizhub 2. Singapore 408734
- Singapore 408734
- SG
-
E8-B4-70 (hex) DEHN SE + Co KG
800000-8FFFFF (base 16) DEHN SE + Co KG
Hans-Dehn-Straße 1
Neumarkt Bavaria 92318
DE
-E8-B4-70 (hex) Alperia Fiber srl
-500000-5FFFFF (base 16) Alperia Fiber srl
- Via Dodiciville 8
- Bolzano bz 39100
- IT
+E8-B4-70 (hex) internet domain name system beijing engineering research center ltd
+200000-2FFFFF (base 16) internet domain name system beijing engineering research center ltd
+ 4,4TH SOUTH STREET ZHONG GUAN CUN
+ hai dian qu ,beijing BEIJING 100190
+ CN
+
+E8-B4-70 (hex) DongGuan Ramaxel Memory Technology
+000000-0FFFFF (base 16) DongGuan Ramaxel Memory Technology
+ No.32, Industrial East Road,Innovation Park, High-tech Industrial Development Zone, Songshan Lake, Dongguan City, Guangdong Province,China
+ DongGuan Guangdong 523808
+ CN
+
+E8-B4-70 (hex) Miltek Industries Pte Ltd
+900000-9FFFFF (base 16) Miltek Industries Pte Ltd
+ 62 Ubi Road 1 #10-03, Oxley Bizhub 2. Singapore 408734
+ Singapore 408734
+ SG
E8-B4-70 (hex) Elcoma
600000-6FFFFF (base 16) Elcoma
@@ -11231,11 +11261,11 @@ E8-B4-70 (hex) Elcoma
Recife Pernambuco 50030-330
BR
-38-F7-CD (hex) APT MOBILE SATCOM LIMITED
-E00000-EFFFFF (base 16) APT MOBILE SATCOM LIMITED
- 18th Floor, Building C, Shenye U Center, Zhoushi Road, Baoan District
- Shenzhen Guangdong 518000
- CN
+E8-B4-70 (hex) Alperia Fiber srl
+500000-5FFFFF (base 16) Alperia Fiber srl
+ Via Dodiciville 8
+ Bolzano bz 39100
+ IT
70-69-79 (hex) Linksys Telecom Shenzhen CO., LTD
100000-1FFFFF (base 16) Linksys Telecom Shenzhen CO., LTD
@@ -11249,6 +11279,12 @@ D00000-DFFFFF (base 16) FREUND ELEKTRONIKA D.O.O., IP-INTEGRA TECHNOLOGIES
SARAJEVO 71000
BA
+38-F7-CD (hex) APT MOBILE SATCOM LIMITED
+E00000-EFFFFF (base 16) APT MOBILE SATCOM LIMITED
+ 18th Floor, Building C, Shenye U Center, Zhoushi Road, Baoan District
+ Shenzhen Guangdong 518000
+ CN
+
CC-C2-61 (hex) Nortek Security & Control
C00000-CFFFFF (base 16) Nortek Security & Control
5919 Sea Otter Place
@@ -11261,6 +11297,12 @@ CC-C2-61 (hex) Guardiar USA
Ennis TX 75119
US
+CC-C2-61 (hex) NWL Inc.
+100000-1FFFFF (base 16) NWL Inc.
+ 312 Rising Sun Road
+ Bordentown NJ 08505
+ US
+
CC-C2-61 (hex) Winterthur Gas & Diesel Ltd.
B00000-BFFFFF (base 16) Winterthur Gas & Diesel Ltd.
Schützenstrasse 3
@@ -11273,12 +11315,6 @@ CC-C2-61 (hex) NETRADYNE, INC.
SAN DIEGO CA 92122
US
-CC-C2-61 (hex) NWL Inc.
-100000-1FFFFF (base 16) NWL Inc.
- 312 Rising Sun Road
- Bordentown NJ 08505
- US
-
F0-D7-AF (hex) New IT Project LLC
900000-9FFFFF (base 16) New IT Project LLC
Nagatinskaya St. 16, bld. 9, space VII, room 15, office 5
@@ -11327,24 +11363,18 @@ D0-14-11 (hex) Realwave Inc.
Carlsbad CA 92008-5507
US
-D0-14-11 (hex) Tecnosoft srl
-E00000-EFFFFF (base 16) Tecnosoft srl
- via Galvani, 4
- Peschiera Borromeo Milan 20068
- IT
-
-5C-85-7E (hex) BeiJing Xinsheng Technology Co.,Ltd
-800000-8FFFFF (base 16) BeiJing Xinsheng Technology Co.,Ltd
- 1-1827, East (LIANHANG building), chaichangtun village, Yongledian Town, Tongzhou District
- BeiJing BeiJing 250100
- CN
-
5C-85-7E (hex) HHCC Plant Technology Co., Ltd.
B00000-BFFFFF (base 16) HHCC Plant Technology Co., Ltd.
RM626, 6th Floor, Zhongguoleshili,’,#35 Xiaoyun Road, Chaoyang District,Beijing, China
Beijing Beijing 100028
CN
+D0-14-11 (hex) Tecnosoft srl
+E00000-EFFFFF (base 16) Tecnosoft srl
+ via Galvani, 4
+ Peschiera Borromeo Milan 20068
+ IT
+
D0-14-11 (hex) iLOQ Oy
300000-3FFFFF (base 16) iLOQ Oy
Yrttipellontie 10
@@ -11357,6 +11387,12 @@ D0-14-11 (hex) iLOQ Oy
Chandler AZ 85225
US
+5C-85-7E (hex) BeiJing Xinsheng Technology Co.,Ltd
+800000-8FFFFF (base 16) BeiJing Xinsheng Technology Co.,Ltd
+ 1-1827, East (LIANHANG building), chaichangtun village, Yongledian Town, Tongzhou District
+ BeiJing BeiJing 250100
+ CN
+
F4-69-D5 (hex) Konntek Inc
B00000-BFFFFF (base 16) Konntek Inc
3600 F-X Tessier, Unit #H
@@ -11393,12 +11429,6 @@ B00000-BFFFFF (base 16) Felten Electronics
Saint-Genis-Pouilly 01630
FR
-28-B7-7C (hex) GROTHE GmbH
-500000-5FFFFF (base 16) GROTHE GmbH
- Loehestrasse 22
- Hennef 53773
- DE
-
28-B7-7C (hex) SHENZHEN EVIEW GPS TECHNOLOGY
000000-0FFFFF (base 16) SHENZHEN EVIEW GPS TECHNOLOGY
Rm 201, building 1-A, Nankechuang Industrial Park, Gaofeng Road, Longhua district
@@ -11417,12 +11447,36 @@ A00000-AFFFFF (base 16) Simaudio Ltd
Boucherville Quebec J4B 5H2
CA
+28-B7-7C (hex) GROTHE GmbH
+500000-5FFFFF (base 16) GROTHE GmbH
+ Loehestrasse 22
+ Hennef 53773
+ DE
+
28-B7-7C (hex) Vehant Technologies Pvt Ltd.
B00000-BFFFFF (base 16) Vehant Technologies Pvt Ltd.
Plot no. 97, Ecotech-12, block-Ecotech -12, Sector-Noida Extension
Greater Noida Uttar Pradesh 201310
IN
+C0-61-9A (hex) Stello
+400000-4FFFFF (base 16) Stello
+ 1041 Rue Parent
+ Saint-Bruno-de-Montarville Quebec J3V 6L7
+ CA
+
+C0-61-9A (hex) Grup Arge Enerji ve Kontrol Sistemleri
+200000-2FFFFF (base 16) Grup Arge Enerji ve Kontrol Sistemleri
+ ?kitelli OSB Mah. YTÜ ?kitelli Teknopark Sok. No:1 / 2B01-2B07-2B08-2B09
+ ?stanbul ?STANBUL 34490
+ TR
+
+C0-61-9A (hex) IPG Automotive GmbH
+600000-6FFFFF (base 16) IPG Automotive GmbH
+ Bannwaldallee 60
+ Karlsruhe 76185
+ DE
+
4C-4B-F9 (hex) Shandong Linkotech Electronic Co., Ltd.
600000-6FFFFF (base 16) Shandong Linkotech Electronic Co., Ltd.
22nd Floor, Building 2, Aosheng Building, No.1166 Xinyi Street, High-tech Zone
@@ -14879,18 +14933,18 @@ B0-B3-53 (hex) Zenlayer
DIAMOND BAR CA 91765
US
-90-E2-FC (hex) ShenZhen Temwey Innovation Technology Co.,Ltd.
-200000-2FFFFF (base 16) ShenZhen Temwey Innovation Technology Co.,Ltd.
- Room 1008, 10/F, Bld.B, Bantian International Centre, No. 5 South Huancheng Road, Bantian Street of Shenzhen Longgang District
- SHENZHEN GUANGDONG 518129
- CN
-
90-E2-FC (hex) Beijing Lanxum Computer Technology CO.,LTD.
D00000-DFFFFF (base 16) Beijing Lanxum Computer Technology CO.,LTD.
3A Floor,BlockB,Technology Fortune Center,No 8 Xueqing Road,Haidian District,
Beijing Beijing 100192
CN
+90-E2-FC (hex) ShenZhen Temwey Innovation Technology Co.,Ltd.
+200000-2FFFFF (base 16) ShenZhen Temwey Innovation Technology Co.,Ltd.
+ Room 1008, 10/F, Bld.B, Bantian International Centre, No. 5 South Huancheng Road, Bantian Street of Shenzhen Longgang District
+ SHENZHEN GUANGDONG 518129
+ CN
+
90-E2-FC (hex) Dongguan Kangyong electronics technology Co. Ltd
400000-4FFFFF (base 16) Dongguan Kangyong electronics technology Co. Ltd
No 9,Yincheng 1st Road, Xiabian Village, Chang’an Town
@@ -14921,12 +14975,6 @@ D00000-DFFFFF (base 16) VANTAGE INTEGRATED SECURITY SOLUTIONS PVT LTD
Wolverhampton West Midlands WV6 0JZ
GB
-64-62-66 (hex) Pass & Seymour, Inc d/b/a Legrand
-600000-6FFFFF (base 16) Pass & Seymour, Inc d/b/a Legrand
- 50 Boyd Ave
- Syracuse NY 13209
- US
-
64-62-66 (hex) FaceHeart Inc.
300000-3FFFFF (base 16) FaceHeart Inc.
Rm. 8, 19F., No.118, Ciyun Rd., East Dist.
@@ -14939,6 +14987,12 @@ A00000-AFFFFF (base 16) Sensoro Co., Ltd.
Beijing Beijing 100102
CN
+64-62-66 (hex) Pass & Seymour, Inc d/b/a Legrand
+600000-6FFFFF (base 16) Pass & Seymour, Inc d/b/a Legrand
+ 50 Boyd Ave
+ Syracuse NY 13209
+ US
+
94-CC-04 (hex) Shandong free optical technology co., ltd.
B00000-BFFFFF (base 16) Shandong free optical technology co., ltd.
195 East First Street, Industrial First Street, Economic Development Zone, Weifang, Weicheng District,
@@ -15002,18 +15056,6 @@ A00000-AFFFFF (base 16) Inveo
Beijing Beijing 100000
CN
-94-FB-A7 (hex) Skyring Smart Technologies(Shenzhen) Co., Ltd.
-E00000-EFFFFF (base 16) Skyring Smart Technologies(Shenzhen) Co., Ltd.
- 6F GDC Building, 9Gaoxin Centeral Avenue 3rd, Nanshan District
- Shenzhen Guangdong 518057
- CN
-
-94-FB-A7 (hex) Inaxsys Security Systems inc.
-100000-1FFFFF (base 16) Inaxsys Security Systems inc.
- 11685 Philippe-Panneton
- Montreal Quebec H1E 4M1
- CA
-
94-FB-A7 (hex) ELKRON
A00000-AFFFFF (base 16) ELKRON
Via Bologna 188/C
@@ -15032,6 +15074,18 @@ D00000-DFFFFF (base 16) Macherey-Nagel GmbH & Co. KG
Düren Deutschland 52355
DE
+94-FB-A7 (hex) Skyring Smart Technologies(Shenzhen) Co., Ltd.
+E00000-EFFFFF (base 16) Skyring Smart Technologies(Shenzhen) Co., Ltd.
+ 6F GDC Building, 9Gaoxin Centeral Avenue 3rd, Nanshan District
+ Shenzhen Guangdong 518057
+ CN
+
+94-FB-A7 (hex) Inaxsys Security Systems inc.
+100000-1FFFFF (base 16) Inaxsys Security Systems inc.
+ 11685 Philippe-Panneton
+ Montreal Quebec H1E 4M1
+ CA
+
38-F7-CD (hex) Polska Fabryka Wodomierzy i Ciep?omierzy FILA
000000-0FFFFF (base 16) Polska Fabryka Wodomierzy i Ciep?omierzy FILA
?eromskiego 30
@@ -15122,9 +15176,21 @@ D0-14-11 (hex) EkkoSense Ltd
Triumph Road, Nottingham UK Mainland NG7 2TU
GB
+30-49-50 (hex) IK Elektronik GmbH
+500000-5FFFFF (base 16) IK Elektronik GmbH
+ Friedrichsgruener Str. 11-13
+ Muldenhammer 08262
+ DE
+
D0-14-11 (hex) Private
100000-1FFFFF (base 16) Private
+5C-85-7E (hex) Sichuan C.H Control Technology Co., Ltd.
+100000-1FFFFF (base 16) Sichuan C.H Control Technology Co., Ltd.
+ 4F,B8,Tianfu Software Park, No. 99, Tianhua 1st Road
+ Chengdu Si chuan 610000
+ CN
+
5C-85-7E (hex) Nautech Electronics Ltd
D00000-DFFFFF (base 16) Nautech Electronics Ltd
120 Cryers Road
@@ -15137,11 +15203,11 @@ D00000-DFFFFF (base 16) Nautech Electronics Ltd
Southborough MA 01772
US
-30-49-50 (hex) IK Elektronik GmbH
-500000-5FFFFF (base 16) IK Elektronik GmbH
- Friedrichsgruener Str. 11-13
- Muldenhammer 08262
- DE
+5C-85-7E (hex) Zhejiang Jetron Ark Digital Technology Co., Ltd
+A00000-AFFFFF (base 16) Zhejiang Jetron Ark Digital Technology Co., Ltd
+ Room 12-9, building B (Hongmao building), No. 338, Juxing West Road, Jiangbei District, Ningbo, ZheJiang, China
+ Ningbo 315000
+ CN
5C-85-7E (hex) Beijing HZFD Technology Co., Ltd
700000-7FFFFF (base 16) Beijing HZFD Technology Co., Ltd
@@ -15149,22 +15215,16 @@ D00000-DFFFFF (base 16) Nautech Electronics Ltd
Beijing Beiijng 100044
CN
-5C-85-7E (hex) Sichuan C.H Control Technology Co., Ltd.
-100000-1FFFFF (base 16) Sichuan C.H Control Technology Co., Ltd.
- 4F,B8,Tianfu Software Park, No. 99, Tianhua 1st Road
- Chengdu Si chuan 610000
- CN
-
F4-69-D5 (hex) Junchuang (Xiamen) Automation Technology Co.,Ltd
100000-1FFFFF (base 16) Junchuang (Xiamen) Automation Technology Co.,Ltd
Room 705, building a, No. 96, Xiangxing Road, industrial zone, Xiamen Torch High tech Zone
Xiamen Fujian 361101
CN
-5C-85-7E (hex) Zhejiang Jetron Ark Digital Technology Co., Ltd
-A00000-AFFFFF (base 16) Zhejiang Jetron Ark Digital Technology Co., Ltd
- Room 12-9, building B (Hongmao building), No. 338, Juxing West Road, Jiangbei District, Ningbo, ZheJiang, China
- Ningbo 315000
+4C-93-A6 (hex) Wuhan Maiwe communication Co.,Ltd
+C00000-CFFFFF (base 16) Wuhan Maiwe communication Co.,Ltd
+ Building 2,Area E, Phase ii, Optical valley core center, No.52, Liufang road, East Lake Hi-tech Development Zone,Wuhan,China
+ Wuhan Hubei 430000
CN
F4-69-D5 (hex) ITS Co., Ltd.
@@ -15173,11 +15233,11 @@ F4-69-D5 (hex) ITS Co., Ltd.
Ulsan 44690
KR
-4C-93-A6 (hex) Wuhan Maiwe communication Co.,Ltd
-C00000-CFFFFF (base 16) Wuhan Maiwe communication Co.,Ltd
- Building 2,Area E, Phase ii, Optical valley core center, No.52, Liufang road, East Lake Hi-tech Development Zone,Wuhan,China
- Wuhan Hubei 430000
- CN
+4C-93-A6 (hex) Atrie Technology Fzc
+100000-1FFFFF (base 16) Atrie Technology Fzc
+ ELOB office no E-44F-41, Hamriya Free zone
+ Sharjah Sharjah 10001
+ AE
4C-93-A6 (hex) Cantronic Systems (Canada) Inc
D00000-DFFFFF (base 16) Cantronic Systems (Canada) Inc
@@ -15185,12 +15245,6 @@ D00000-DFFFFF (base 16) Cantronic Systems (Canada) Inc
Coquitlam British Columbia V3K 6V5
CA
-4C-93-A6 (hex) Atrie Technology Fzc
-100000-1FFFFF (base 16) Atrie Technology Fzc
- ELOB office no E-44F-41, Hamriya Free zone
- Sharjah Sharjah 10001
- AE
-
28-B7-7C (hex) Anser Coding Inc.
900000-9FFFFF (base 16) Anser Coding Inc.
34F., No. 99, Sec. 1, XinTai 5th Rd., Xizhi Dist.,
@@ -18584,11 +18638,11 @@ B0-B3-53 (hex) Sprocomm Technologies CO.,LTD.
shenzhen guangdong 518000
CN
-3C-FA-D3 (hex) Mirico
-E00000-EFFFFF (base 16) Mirico
- 30 DongSan Rd 9th floor Mirico
- Ansan Gyunggi 15434
- KR
+B0-B3-53 (hex) VOXISCOM
+800000-8FFFFF (base 16) VOXISCOM
+ Rue Jules Ferry
+ PORNIC 44210
+ FR
B0-B3-53 (hex) Innotas Elektronik GmbH
400000-4FFFFF (base 16) Innotas Elektronik GmbH
@@ -18596,11 +18650,11 @@ B0-B3-53 (hex) Innotas Elektronik GmbH
Zittau D-02763
DE
-B0-B3-53 (hex) VOXISCOM
-800000-8FFFFF (base 16) VOXISCOM
- Rue Jules Ferry
- PORNIC 44210
- FR
+3C-FA-D3 (hex) Mirico
+E00000-EFFFFF (base 16) Mirico
+ 30 DongSan Rd 9th floor Mirico
+ Ansan Gyunggi 15434
+ KR
90-E2-FC (hex) Power Engineering & Manufacturing, Inc.
A00000-AFFFFF (base 16) Power Engineering & Manufacturing, Inc.
@@ -18644,12 +18698,6 @@ C00000-CFFFFF (base 16) IO Industries Inc.
London Ontario N5V 0A4
CA
-90-E2-FC (hex) Fair Winds Digital srl
-700000-7FFFFF (base 16) Fair Winds Digital srl
- Via Italo Svevo 85
- Rome Italy 00137
- IT
-
14-AE-85 (hex) AZ-TECHNOLOGY SDN BHD
500000-5FFFFF (base 16) AZ-TECHNOLOGY SDN BHD
A108 & A109 BLOCK A KELANA BUSINESS CENTRE NO: 97 JALAN SS7/2 KELANA JAYA
@@ -18662,29 +18710,29 @@ C00000-CFFFFF (base 16) IO Industries Inc.
PADOVA PADOVA 35129
IT
+90-E2-FC (hex) Fair Winds Digital srl
+700000-7FFFFF (base 16) Fair Winds Digital srl
+ Via Italo Svevo 85
+ Rome Italy 00137
+ IT
+
14-AE-85 (hex) TMG TE GmbH
600000-6FFFFF (base 16) TMG TE GmbH
Zur Gießerei 10
Karlsruhe 776227
DE
-14-AE-85 (hex) Sercomm Corporation.
-E00000-EFFFFF (base 16) Sercomm Corporation.
- 3F,No.81,Yu-Yih Rd.,Chu-Nan Chen
- Miao-Lih Hsuan 115
- TW
-
14-AE-85 (hex) NTC SOFT
B00000-BFFFFF (base 16) NTC SOFT
B-805, Gwangmyeong SK Techno park, 60, Haan-ro,
Gwangmyeong-si Gyeonggi-do 14322
KR
-94-CC-04 (hex) Hangzhou Yongkong Technology Co., Ltd.
-000000-0FFFFF (base 16) Hangzhou Yongkong Technology Co., Ltd.
- Room 503, Building 12, Lefu Zhihui Garden, 28 Xiangyuan Road, Gongshu Distric
- Hangzhou Zhejiang 310000
- CN
+14-AE-85 (hex) Sercomm Corporation.
+E00000-EFFFFF (base 16) Sercomm Corporation.
+ 3F,No.81,Yu-Yih Rd.,Chu-Nan Chen
+ Miao-Lih Hsuan 115
+ TW
64-62-66 (hex) Jiangsu Aisida Electronic Co.,Ltd
C00000-CFFFFF (base 16) Jiangsu Aisida Electronic Co.,Ltd
@@ -18692,6 +18740,12 @@ C00000-CFFFFF (base 16) Jiangsu Aisida Electronic Co.,Ltd
DanYang JiangSu 212300
CN
+94-CC-04 (hex) Hangzhou Yongkong Technology Co., Ltd.
+000000-0FFFFF (base 16) Hangzhou Yongkong Technology Co., Ltd.
+ Room 503, Building 12, Lefu Zhihui Garden, 28 Xiangyuan Road, Gongshu Distric
+ Hangzhou Zhejiang 310000
+ CN
+
94-CC-04 (hex) Gowing Business And Contracting Wenzhou Co., LTD
700000-7FFFFF (base 16) Gowing Business And Contracting Wenzhou Co., LTD
Room 101, No.4 Liming Industrial District, Lucheng, Wenzhou, China
@@ -18722,6 +18776,12 @@ C00000-CFFFFF (base 16) Jiangsu Aisida Electronic Co.,Ltd
North Andover MA 01845
US
+94-05-BB (hex) Neurik AG
+300000-3FFFFF (base 16) Neurik AG
+ Im alten Riet 143
+ Schaan SCHAAN 9494
+ LI
+
94-05-BB (hex) Dongguan Kingtron Electronics Tech Co., Ltd
100000-1FFFFF (base 16) Dongguan Kingtron Electronics Tech Co., Ltd
No.3 Fumin North Rd,Shu'an Industrial Park, Humen Town
@@ -18734,12 +18794,6 @@ D00000-DFFFFF (base 16) Sunthink S&T Development Co.,Ltd
Shenzhen 518100
CN
-94-05-BB (hex) Neurik AG
-300000-3FFFFF (base 16) Neurik AG
- Im alten Riet 143
- Schaan SCHAAN 9494
- LI
-
DC-44-27 (hex) Tesla,Inc.
100000-1FFFFF (base 16) Tesla,Inc.
3500 Deer Creek Road
@@ -18752,24 +18806,30 @@ F4-90-CB (hex) ICE Gateway GmbH
Berlin Berlin 12489
DE
-C0-9B-F4 (hex) SHENZHEN WINS ELECTRONIC TECHNOLOGY CO., LTD
-800000-8FFFFF (base 16) SHENZHEN WINS ELECTRONIC TECHNOLOGY CO., LTD
- Baoan Xixiang Xinbaoji Industry Park,Building A1-2
- Shenzhen Guangdong 518026
- CN
-
F4-90-CB (hex) DELEM BV
100000-1FFFFF (base 16) DELEM BV
LUCHTHAVEN WEG 42
5657 EB EINDHOVEN
NL
+C0-9B-F4 (hex) SHENZHEN WINS ELECTRONIC TECHNOLOGY CO., LTD
+800000-8FFFFF (base 16) SHENZHEN WINS ELECTRONIC TECHNOLOGY CO., LTD
+ Baoan Xixiang Xinbaoji Industry Park,Building A1-2
+ Shenzhen Guangdong 518026
+ CN
+
C0-9B-F4 (hex) Hitachi High-Tech Materials Corporation
200000-2FFFFF (base 16) Hitachi High-Tech Materials Corporation
Toranomon Hills Business Tower, 1-17-1 Toranomon, Minato-ku
Tokyo 105-6413
JP
+E8-B4-70 (hex) Autocom Diagnostic Partner AB
+100000-1FFFFF (base 16) Autocom Diagnostic Partner AB
+ Grafitvägen 23B
+ TROLLHÄTTAN 46138
+ SE
+
E8-B4-70 (hex) UNICACCES GROUPE
E00000-EFFFFF (base 16) UNICACCES GROUPE
24 Chemin des Vieilles Vignes
@@ -18782,30 +18842,12 @@ B00000-BFFFFF (base 16) Digifocus Technology Inc.
Taipei City 11494
TW
-E8-B4-70 (hex) Autocom Diagnostic Partner AB
-100000-1FFFFF (base 16) Autocom Diagnostic Partner AB
- Grafitvägen 23B
- TROLLHÄTTAN 46138
- SE
-
94-FB-A7 (hex) Silver-I Co.,LTD.
800000-8FFFFF (base 16) Silver-I Co.,LTD.
2-14-4 Shinyokohama,kohoku-ku
Yokohama Kanagawa 222-0033
JP
-38-F7-CD (hex) NORDI TELEKOMMUNIKATSIOONI OÜ
-400000-4FFFFF (base 16) NORDI TELEKOMMUNIKATSIOONI OÜ
- Valukoja 8
- Tallinn city Estonian Republic 11415
- EE
-
-38-F7-CD (hex) Shanghai qinzhuo Electronic Co., Ltd.
-500000-5FFFFF (base 16) Shanghai qinzhuo Electronic Co., Ltd.
- No. W, floor 1, building 2, No. 258, Minfeng Road, Pudong New Area
- Shanghai Shanghai 201209
- CN
-
38-F7-CD (hex) RFbeam Microwave GmbH
900000-9FFFFF (base 16) RFbeam Microwave GmbH
Schuppisstrasse 7
@@ -18818,23 +18860,29 @@ C00000-CFFFFF (base 16) Shenzhen MADIGI Electronic Technology Co., Ltd
Shenzhen Guangdong 518000
CN
-70-69-79 (hex) Faurecia Clarion Electronics (Dongguan) Co., Ltd
-900000-9FFFFF (base 16) Faurecia Clarion Electronics (Dongguan) Co., Ltd
- South of Dongkeng Avenue, Dongkeng Town, Dongguan City, Guangdong
- DONGGUAN GUANGDONG 523455
+38-F7-CD (hex) Shanghai qinzhuo Electronic Co., Ltd.
+500000-5FFFFF (base 16) Shanghai qinzhuo Electronic Co., Ltd.
+ No. W, floor 1, building 2, No. 258, Minfeng Road, Pudong New Area
+ Shanghai Shanghai 201209
CN
+38-F7-CD (hex) NORDI TELEKOMMUNIKATSIOONI OÜ
+400000-4FFFFF (base 16) NORDI TELEKOMMUNIKATSIOONI OÜ
+ Valukoja 8
+ Tallinn city Estonian Republic 11415
+ EE
+
38-F7-CD (hex) BlastWave Inc.
800000-8FFFFF (base 16) BlastWave Inc.
1987 Leghorn Street, Suite 100
Moutain View CA 94043
US
-70-69-79 (hex) Intelitech SIA
-700000-7FFFFF (base 16) Intelitech SIA
- 2-22 Kruzes str.
- Riga Other LV-1046
- LV
+70-69-79 (hex) Faurecia Clarion Electronics (Dongguan) Co., Ltd
+900000-9FFFFF (base 16) Faurecia Clarion Electronics (Dongguan) Co., Ltd
+ South of Dongkeng Avenue, Dongkeng Town, Dongguan City, Guangdong
+ DONGGUAN GUANGDONG 523455
+ CN
70-69-79 (hex) Beijing Security Union Information Technology Co.,Ltd
600000-6FFFFF (base 16) Beijing Security Union Information Technology Co.,Ltd
@@ -18842,6 +18890,18 @@ C00000-CFFFFF (base 16) Shenzhen MADIGI Electronic Technology Co., Ltd
Beijing Beijing 100085
CN
+70-69-79 (hex) Intelitech SIA
+700000-7FFFFF (base 16) Intelitech SIA
+ 2-22 Kruzes str.
+ Riga Other LV-1046
+ LV
+
+CC-C2-61 (hex) Ebiologic Technology Co., Ltd.
+000000-0FFFFF (base 16) Ebiologic Technology Co., Ltd.
+ 9F., No.33, Ln. 3, Sec. 1, Zhongzheng E. Rd., Tamsui Dist., New Taipei City 251, Taiwan (R.O.C.)
+ New Taipei City 251
+ TW
+
CC-C2-61 (hex) Dspread Technology (Beijing) Inc.
D00000-DFFFFF (base 16) Dspread Technology (Beijing) Inc.
Jingxin Building, 2045 Suite , Chaoyang District
@@ -18854,12 +18914,6 @@ CC-C2-61 (hex) Viper Design, LLC
Goodlettsville TN 37072
US
-CC-C2-61 (hex) Ebiologic Technology Co., Ltd.
-000000-0FFFFF (base 16) Ebiologic Technology Co., Ltd.
- 9F., No.33, Ln. 3, Sec. 1, Zhongzheng E. Rd., Tamsui Dist., New Taipei City 251, Taiwan (R.O.C.)
- New Taipei City 251
- TW
-
CC-C2-61 (hex) BYTERG LLC
900000-9FFFFF (base 16) BYTERG LLC
1st Nagatinsky proezd 10 build.1
@@ -18884,18 +18938,18 @@ F0-D7-AF (hex) Anord Mardix (USA) Inc.
Sandston VA 23150
US
-F0-D7-AF (hex) SHEN ZHEN MICHIP TECHNOLOGIES CO.,LTD.
-800000-8FFFFF (base 16) SHEN ZHEN MICHIP TECHNOLOGIES CO.,LTD.
- Fuxingda Indestrial park.Floor4?Building4
- SHEN ZHEN GUANG DONG 518126
- CN
-
94-FB-A7 (hex) Rosenberger Technologies Co.,Ltd.
D00000-DFFFFF (base 16) Rosenberger Technologies Co.,Ltd.
NO.6, ShenAn Rd, Dianshanhu Town
Kunshan City Jiangsu Province 215345
CN
+F0-D7-AF (hex) SHEN ZHEN MICHIP TECHNOLOGIES CO.,LTD.
+800000-8FFFFF (base 16) SHEN ZHEN MICHIP TECHNOLOGIES CO.,LTD.
+ Fuxingda Indestrial park.Floor4?Building4
+ SHEN ZHEN GUANG DONG 518126
+ CN
+
30-49-50 (hex) Guangzhou Lian-med Technology Co.,Ltd.
000000-0FFFFF (base 16) Guangzhou Lian-med Technology Co.,Ltd.
Room 501, Building G1,No. 31 Kefeng Road, Huangpu district
@@ -18908,6 +18962,12 @@ E00000-EFFFFF (base 16) IoTmaxx GmbH
Hannover 30159
DE
+D0-14-11 (hex) Guangdong Shiqi Manufacture Co., Ltd.
+D00000-DFFFFF (base 16) Guangdong Shiqi Manufacture Co., Ltd.
+ No. D10~11, Lunjiao intensive industrial Zone, Licun Village committee, Lunjiao street office, Shunde District
+ Foshan Guangdong 528300
+ CN
+
D0-14-11 (hex) Ahnnet
600000-6FFFFF (base 16) Ahnnet
B-313, Samhwan HIPEX, 230, Pangyoyeok-ro, Bundang-gu
@@ -18920,10 +18980,10 @@ D0-14-11 (hex) Ahnnet
Warszawa 02-226
PL
-D0-14-11 (hex) Guangdong Shiqi Manufacture Co., Ltd.
-D00000-DFFFFF (base 16) Guangdong Shiqi Manufacture Co., Ltd.
- No. D10~11, Lunjiao intensive industrial Zone, Licun Village committee, Lunjiao street office, Shunde District
- Foshan Guangdong 528300
+5C-85-7E (hex) Guoyi Liangzi (Hefei) Technology Co., Ltd(CIQTEK)
+E00000-EFFFFF (base 16) Guoyi Liangzi (Hefei) Technology Co., Ltd(CIQTEK)
+ 1-4th Floor, Building No.E2, Chuangxin Industrial Park, No.2800, Chuangxin Road Gaoxin District
+ Hefei Anhui Hefei
CN
5C-85-7E (hex) Express LUCK Industrial Ltd.
@@ -18932,50 +18992,56 @@ D00000-DFFFFF (base 16) Guangdong Shiqi Manufacture Co., Ltd.
Shenzhen Guangdong 518100
CN
-5C-85-7E (hex) Guoyi Liangzi (Hefei) Technology Co., Ltd(CIQTEK)
-E00000-EFFFFF (base 16) Guoyi Liangzi (Hefei) Technology Co., Ltd(CIQTEK)
- 1-4th Floor, Building No.E2, Chuangxin Industrial Park, No.2800, Chuangxin Road Gaoxin District
- Hefei Anhui Hefei
- CN
-
F4-69-D5 (hex) Nantong ZYDZ Electronic.,Co.Ltd
D00000-DFFFFF (base 16) Nantong ZYDZ Electronic.,Co.Ltd
# F, High-Tech business Incubator, No.86 East Waihuan Road,
Nantong Jiangsu 226300
CN
-4C-93-A6 (hex) Hanwang Technology Co.,Ltd
-A00000-AFFFFF (base 16) Hanwang Technology Co.,Ltd
- HANVON TOWER, BUILDING NO.5, ZHONGGUANCUN SOFTWARE PARK, HAIDIAN DISTRICT, BEIJING, CHINA 100193
- BEIJING BEIJING 100193
- CN
-
F4-69-D5 (hex) Stype CS d.o.o.
400000-4FFFFF (base 16) Stype CS d.o.o.
Velikopoljska 32
Zagreb 10010
HR
+4C-93-A6 (hex) Hanwang Technology Co.,Ltd
+A00000-AFFFFF (base 16) Hanwang Technology Co.,Ltd
+ HANVON TOWER, BUILDING NO.5, ZHONGGUANCUN SOFTWARE PARK, HAIDIAN DISTRICT, BEIJING, CHINA 100193
+ BEIJING BEIJING 100193
+ CN
+
28-B7-7C (hex) AnyLink LLC
C00000-CFFFFF (base 16) AnyLink LLC
100 N Washington St. Floor 6
Boston MA 02114
US
+28-B7-7C (hex) Shanghai Taiji Software Co.,Limited
+600000-6FFFFF (base 16) Shanghai Taiji Software Co.,Limited
+ Room J1224, No. 6, Lane 129, Huajiang Road, Jiading District
+ Shanghai Shanghai 201800
+ CN
+
28-B7-7C (hex) Enedo Finland Oy
D00000-DFFFFF (base 16) Enedo Finland Oy
Martinkyläntie 43
Vantaa 01720
FI
-28-B7-7C (hex) Shanghai Taiji Software Co.,Limited
-600000-6FFFFF (base 16) Shanghai Taiji Software Co.,Limited
- Room J1224, No. 6, Lane 129, Huajiang Road, Jiading District
- Shanghai Shanghai 201800
- CN
+C0-61-9A (hex) JAM-Labs Corp
+C00000-CFFFFF (base 16) JAM-Labs Corp
+ 4109 Clipper Ct
+ Fremont CA 94538
+ US
C0-61-9A (hex) LYAND ACOUSTIC TECHNOLOGY CO.,LTD.
300000-3FFFFF (base 16) LYAND ACOUSTIC TECHNOLOGY CO.,LTD.
No. 73 JinFu Road XiaoJinKou
Huizhou city GuangDong 516023
CN
+
+C0-61-9A (hex) KidKraft
+100000-1FFFFF (base 16) KidKraft
+ 4630 Olin Rd
+ Dallas TX 75244
+ US
diff --git a/hwdb.d/ma-small.txt b/hwdb.d/ma-small.txt
index d4ca6d3e89..dc40087604 100644
--- a/hwdb.d/ma-small.txt
+++ b/hwdb.d/ma-small.txt
@@ -4193,12 +4193,6 @@ EF1000-EF1FFF (base 16) Nanotok LLC
Hong Kong Hong Kong 00000
HK
-70-B3-D5 (hex) Technology Link Corporation
-B1B000-B1BFFF (base 16) Technology Link Corporation
- Shin-Yokohama Kohoku-ku
- yokohama kanagawa 222-0033
- JP
-
70-B3-D5 (hex) VANTAGE INTEGRATED SECURITY SOLUTIONS PVT LTD
6BE000-6BEFFF (base 16) VANTAGE INTEGRATED SECURITY SOLUTIONS PVT LTD
B3, Bredon House, 321, Tettenhall Road, Tettenhall
@@ -4223,11 +4217,11 @@ F47000-F47FFF (base 16) TXMission Ltd.
Watford Hertfordshire WD25 8HU
GB
-70-B3-D5 (hex) sensorway
-C52000-C52FFF (base 16) sensorway
- A-339 samsong techno valley, 140 tongilro, deockyanggu
- goyangsi gyeonggido 10594
- KR
+70-B3-D5 (hex) Technology Link Corporation
+B1B000-B1BFFF (base 16) Technology Link Corporation
+ Shin-Yokohama Kohoku-ku
+ yokohama kanagawa 222-0033
+ JP
70-B3-D5 (hex) Tucsen Photonics Co., Ltd.
8A7000-8A7FFF (base 16) Tucsen Photonics Co., Ltd.
@@ -4235,11 +4229,11 @@ C52000-C52FFF (base 16) sensorway
fuzhou 350000
CN
-70-B3-D5 (hex) Beijing Yourong Runda Rechnology Development Co.Ltd.
-980000-980FFF (base 16) Beijing Yourong Runda Rechnology Development Co.Ltd.
- Changping District Science and Technology Park Advanced Road 37
- Beijing 6219650
- CN
+70-B3-D5 (hex) sensorway
+C52000-C52FFF (base 16) sensorway
+ A-339 samsong techno valley, 140 tongilro, deockyanggu
+ goyangsi gyeonggido 10594
+ KR
70-B3-D5 (hex) KDT Corp.
E72000-E72FFF (base 16) KDT Corp.
@@ -4247,11 +4241,11 @@ E72000-E72FFF (base 16) KDT Corp.
shaoxing zhejiang 312030
CN
-70-B3-D5 (hex) AUTOMATICA Y REGULACION S.A.
-EBF000-EBFFFF (base 16) AUTOMATICA Y REGULACION S.A.
- Condell 1735, Nunoa
- Santiago RM 7770331
- CL
+70-B3-D5 (hex) Beijing Yourong Runda Rechnology Development Co.Ltd.
+980000-980FFF (base 16) Beijing Yourong Runda Rechnology Development Co.Ltd.
+ Changping District Science and Technology Park Advanced Road 37
+ Beijing 6219650
+ CN
70-B3-D5 (hex) R.C. Systems Inc
52F000-52FFFF (base 16) R.C. Systems Inc
@@ -4265,18 +4259,18 @@ EBF000-EBFFFF (base 16) AUTOMATICA Y REGULACION S.A.
Brendola Vicenza 36040
IT
+70-B3-D5 (hex) AUTOMATICA Y REGULACION S.A.
+EBF000-EBFFFF (base 16) AUTOMATICA Y REGULACION S.A.
+ Condell 1735, Nunoa
+ Santiago RM 7770331
+ CL
+
70-B3-D5 (hex) Digital Solutions JSC
D9F000-D9FFFF (base 16) Digital Solutions JSC
room 4, office 1, 3rd floor, building 7, house 9a, 2nd Sinichkina Str.
Moscow 111020
RU
-70-B3-D5 (hex) DOGA
-62A000-62AFFF (base 16) DOGA
- 11 rue Lavoisier
- MAUREPAS 78310
- FR
-
70-B3-D5 (hex) Oculii
B96000-B96FFF (base 16) Oculii
829 Space Dr
@@ -4295,11 +4289,11 @@ B96000-B96FFF (base 16) Oculii
Woodside NY 11377
US
-70-B3-D5 (hex) Remote Diagnostic Technologies Ltd
-C99000-C99FFF (base 16) Remote Diagnostic Technologies Ltd
- Pavilion C2 Ashwood Park, Ashwood Way
- Basingstoke Hampshire RG23 8BG
- GB
+70-B3-D5 (hex) DOGA
+62A000-62AFFF (base 16) DOGA
+ 11 rue Lavoisier
+ MAUREPAS 78310
+ FR
70-B3-D5 (hex) NEUROPHET, Inc.
E31000-E31FFF (base 16) NEUROPHET, Inc.
@@ -4307,6 +4301,18 @@ E31000-E31FFF (base 16) NEUROPHET, Inc.
Seoul Province 06247
KR
+70-B3-D5 (hex) Remote Diagnostic Technologies Ltd
+C99000-C99FFF (base 16) Remote Diagnostic Technologies Ltd
+ Pavilion C2 Ashwood Park, Ashwood Way
+ Basingstoke Hampshire RG23 8BG
+ GB
+
+70-B3-D5 (hex) Gogo Business Aviation
+3E0000-3E0FFF (base 16) Gogo Business Aviation
+ 105 Edgeview Dr., Suite 300
+ Broomfield CO 80021
+ US
+
70-B3-D5 (hex) Chromateq
944000-944FFF (base 16) Chromateq
191, allée de Lauzard, Bat. B, RDC 1 (Chromateq)
@@ -4325,30 +4331,12 @@ F3D000-F3DFFF (base 16) KAYA Instruments
Nesher 3688520
IL
-70-B3-D5 (hex) Gogo Business Aviation
-3E0000-3E0FFF (base 16) Gogo Business Aviation
- 105 Edgeview Dr., Suite 300
- Broomfield CO 80021
- US
-
70-B3-D5 (hex) Asiga Pty Ltd
53E000-53EFFF (base 16) Asiga Pty Ltd
Unit 2, 19-21 Bourke Road
Alexandria New South Wales 2015
AU
-70-B3-D5 (hex) ENABLER LTD.
-15A000-15AFFF (base 16) ENABLER LTD.
- 29F Shiroyama Trust Tower 4-3-1 Toranomon
- Minato-ku Tokyo 105-6029
- JP
-
-70-B3-D5 (hex) LINEAGE POWER PVT LTD.,
-62E000-62EFFF (base 16) LINEAGE POWER PVT LTD.,
- 30-A1, KIADB, 1ST PHASE INDUSTRIAL ESTATE,KUMBALGODU, BANGALORE-MYSORE ROAD
- BANGALORE KARNATAKA 560074
- IN
-
70-B3-D5 (hex) Salupo Sas
898000-898FFF (base 16) Salupo Sas
Via Laganeto n. 129
@@ -4361,35 +4349,53 @@ F3D000-F3DFFF (base 16) KAYA Instruments
Amagasaki Hyogo 660-0082
JP
+70-B3-D5 (hex) LINEAGE POWER PVT LTD.,
+62E000-62EFFF (base 16) LINEAGE POWER PVT LTD.,
+ 30-A1, KIADB, 1ST PHASE INDUSTRIAL ESTATE,KUMBALGODU, BANGALORE-MYSORE ROAD
+ BANGALORE KARNATAKA 560074
+ IN
+
+70-B3-D5 (hex) ENABLER LTD.
+15A000-15AFFF (base 16) ENABLER LTD.
+ 29F Shiroyama Trust Tower 4-3-1 Toranomon
+ Minato-ku Tokyo 105-6029
+ JP
+
70-B3-D5 (hex) Grupo Epelsa S.L.
40D000-40DFFF (base 16) Grupo Epelsa S.L.
C/ Punto Net,3
Alcala de Henares Madrid 28805
ES
+70-B3-D5 (hex) WEPTECH elektronik GmbH
+9CD000-9CDFFF (base 16) WEPTECH elektronik GmbH
+ Ostring 10
+ Landau 76829
+ DE
+
70-B3-D5 (hex) AnaPico AG
0BB000-0BBFFF (base 16) AnaPico AG
Europa-Strasse 9
Glattbrugg Schweiz 8152
CH
+70-B3-D5 (hex) Egag, LLC
+9A8000-9A8FFF (base 16) Egag, LLC
+ 303 King James Ct
+ Upper Marlboro MD 20774
+ US
+
70-B3-D5 (hex) Season Electronics Ltd
F46000-F46FFF (base 16) Season Electronics Ltd
600 Nest Business Park
Havant Hampshire PO9 5TL
GB
-70-B3-D5 (hex) WEPTECH elektronik GmbH
-9CD000-9CDFFF (base 16) WEPTECH elektronik GmbH
- Ostring 10
- Landau 76829
- DE
-
-70-B3-D5 (hex) Egag, LLC
-9A8000-9A8FFF (base 16) Egag, LLC
- 303 King James Ct
- Upper Marlboro MD 20774
- US
+70-B3-D5 (hex) Algodue Elettronica Srl
+191000-191FFF (base 16) Algodue Elettronica Srl
+ Via P. Gobetti, 16F
+ Maggiora NO 28014
+ IT
70-B3-D5 (hex) Hermann Sewerin GmbH
484000-484FFF (base 16) Hermann Sewerin GmbH
@@ -4403,42 +4409,18 @@ F46000-F46FFF (base 16) Season Electronics Ltd
GwangMyung-si Gyeonggi-do, Korea 14322
KR
-70-B3-D5 (hex) Algodue Elettronica Srl
-191000-191FFF (base 16) Algodue Elettronica Srl
- Via P. Gobetti, 16F
- Maggiora NO 28014
- IT
-
70-B3-D5 (hex) Beijing Vizum Technology Co.,Ltd.
F33000-F33FFF (base 16) Beijing Vizum Technology Co.,Ltd.
Room603, Floor6, Block2, No.1 Zhongguancun, No.81 Beiqing Road
Beijing Beijing 100094
CN
-70-B3-D5 (hex) Volution Group UK
-687000-687FFF (base 16) Volution Group UK
- Vent-Axia Ltd, Fleming Way
- Crawley WEST SUSSEX RH10 9YX
- GB
-
-70-B3-D5 (hex) Vertex Co.,Ltd.
-8DD000-8DDFFF (base 16) Vertex Co.,Ltd.
- 4-1-17 Higashifuchinobe,Chuo-ku
- Sagamihara Kanagawa 252-0203
- JP
-
70-B3-D5 (hex) Monnit Corporation
393000-393FFF (base 16) Monnit Corporation
3400 S West Temple
Salt Lake City UT 84115
US
-70-B3-D5 (hex) Specialized Communications Corp.
-867000-867FFF (base 16) Specialized Communications Corp.
- 20940 Twin Springs Drive
- Smithsburg 21783
- US
-
70-B3-D5 (hex) eSight
FD9000-FD9FFF (base 16) eSight
515 Legget Drive, Suite 200
@@ -4451,6 +4433,24 @@ D99000-D99FFF (base 16) Nilar AB
Gävle Gavleborg 80647
SE
+70-B3-D5 (hex) Volution Group UK
+687000-687FFF (base 16) Volution Group UK
+ Vent-Axia Ltd, Fleming Way
+ Crawley WEST SUSSEX RH10 9YX
+ GB
+
+70-B3-D5 (hex) Vertex Co.,Ltd.
+8DD000-8DDFFF (base 16) Vertex Co.,Ltd.
+ 4-1-17 Higashifuchinobe,Chuo-ku
+ Sagamihara Kanagawa 252-0203
+ JP
+
+70-B3-D5 (hex) Specialized Communications Corp.
+867000-867FFF (base 16) Specialized Communications Corp.
+ 20940 Twin Springs Drive
+ Smithsburg 21783
+ US
+
70-B3-D5 (hex) Jabil, Inc.
736000-736FFF (base 16) Jabil, Inc.
888 Executive Center Dr. W.
@@ -4505,6 +4505,12 @@ D06000-D06FFF (base 16) YUYAMA MFG Co.,Ltd
Guangzhou Guangdong 510665
CN
+70-B3-D5 (hex) 7thSense Design Limited
+E46000-E46FFF (base 16) 7thSense Design Limited
+ 2 The Courtyard, Shoreham Road
+ Upper Beeding West Sussex BN44 3TN
+ GB
+
70-B3-D5 (hex) Cominfo, Inc.
6F5000-6F5FFF (base 16) Cominfo, Inc.
Nabrezi 695
@@ -4517,41 +4523,53 @@ D06000-D06FFF (base 16) YUYAMA MFG Co.,Ltd
Shenyang Liaoning 110000
CN
-70-B3-D5 (hex) 7thSense Design Limited
-E46000-E46FFF (base 16) 7thSense Design Limited
- 2 The Courtyard, Shoreham Road
- Upper Beeding West Sussex BN44 3TN
- GB
-
70-B3-D5 (hex) Weltek Technologies Co. Ltd.
C48000-C48FFF (base 16) Weltek Technologies Co. Ltd.
Flat A-B, 12/F, Block 1, Wah Fung Ind. Centre, 33-39 Kwai Fung Crescent, Kwai Chung, N.T.
HK 852
HK
-70-B3-D5 (hex) TimeMachines Inc.
-756000-756FFF (base 16) TimeMachines Inc.
- 300 S 68th Street Place, Suite 100
- Lincoln NE 68510
- US
-
70-B3-D5 (hex) BirdDog Australia
3B9000-3B9FFF (base 16) BirdDog Australia
Unit 1, 8 Theobald St
THORNBURY VIC 3071
AU
+70-B3-D5 (hex) Clarity Medical Pvt Ltd
+C0D000-C0DFFF (base 16) Clarity Medical Pvt Ltd
+ PLOT No. 1687A, JLPL INDUSTRIAL AREA, SECTOR 82, MOHALI
+ MOHALI Punjab 140306
+ IN
+
+70-B3-D5 (hex) TimeMachines Inc.
+756000-756FFF (base 16) TimeMachines Inc.
+ 300 S 68th Street Place, Suite 100
+ Lincoln NE 68510
+ US
+
70-B3-D5 (hex) Algra tec AG
80C000-80CFFF (base 16) Algra tec AG
Rigistr. 1
Merenschwand Aargau 5634
CH
-70-B3-D5 (hex) Clarity Medical Pvt Ltd
-C0D000-C0DFFF (base 16) Clarity Medical Pvt Ltd
- PLOT No. 1687A, JLPL INDUSTRIAL AREA, SECTOR 82, MOHALI
- MOHALI Punjab 140306
- IN
+70-B3-D5 (hex) KRONOTECH SRL
+626000-626FFF (base 16) KRONOTECH SRL
+ VIALE UNGHERIA 125
+ UDINE ITALY/UDINE 33100
+ IT
+
+70-B3-D5 (hex) Enlaps
+2AF000-2AFFFF (base 16) Enlaps
+ 29 chemin du vieux chene, Tarmac
+ MEYLAN 38240
+ FR
+
+70-B3-D5 (hex) BORMANN EDV und Zubehoer
+864000-864FFF (base 16) BORMANN EDV und Zubehoer
+ Lohwaldstr. 53
+ Neusaess Bayern 85356
+ DE
70-B3-D5 (hex) EVCO SPA
A80000-A80FFF (base 16) EVCO SPA
@@ -8873,30 +8891,24 @@ A7F000-A7FFFF (base 16) AUDIO VISUAL DIGITAL SYSTEMS
Bergisch Gladbach North Rhine-Westphalia 51465
DE
-70-B3-D5 (hex) Cetitec GmbH
-B36000-B36FFF (base 16) Cetitec GmbH
- Mannheimer Strasse 17
- Pforzheim 75179
- DE
-
70-B3-D5 (hex) DONG IL VISION Co., Ltd.
038000-038FFF (base 16) DONG IL VISION Co., Ltd.
#9 Ftrek tower, 11-25, Simindaero 327 beongil,Dongan-gu
Anyangi-Si Gyeonggi-Do 14055
KR
+70-B3-D5 (hex) Cetitec GmbH
+B36000-B36FFF (base 16) Cetitec GmbH
+ Mannheimer Strasse 17
+ Pforzheim 75179
+ DE
+
70-B3-D5 (hex) Kamacho Scale Co., Ltd.
385000-385FFF (base 16) Kamacho Scale Co., Ltd.
2246 Mure
Takamatsu-shi Kagawa-ken 761-0196
JP
-70-B3-D5 (hex) Visual Robotics
-0F4000-0F4FFF (base 16) Visual Robotics
- 38 Irving Rd
- Eugene OR 97404
- US
-
70-B3-D5 (hex) Vessel Technology Ltd
44D000-44DFFF (base 16) Vessel Technology Ltd
Banchory Business Centre, Burn O'Bennie Road
@@ -8909,11 +8921,11 @@ FA8000-FA8FFF (base 16) Munters
Pethch Tikva Israel 4959376
IL
-70-B3-D5 (hex) TEX COMPUTER SRL
-6C2000-6C2FFF (base 16) TEX COMPUTER SRL
- VIA MERCADANTE 35
- CATTOLICA RIMINI 47841
- IT
+70-B3-D5 (hex) Visual Robotics
+0F4000-0F4FFF (base 16) Visual Robotics
+ 38 Irving Rd
+ Eugene OR 97404
+ US
70-B3-D5 (hex) TangRen C&S CO., Ltd
3FC000-3FCFFF (base 16) TangRen C&S CO., Ltd
@@ -8921,29 +8933,29 @@ FA8000-FA8FFF (base 16) Munters
Shenzhen Guangdong 518052
CN
+70-B3-D5 (hex) TEX COMPUTER SRL
+6C2000-6C2FFF (base 16) TEX COMPUTER SRL
+ VIA MERCADANTE 35
+ CATTOLICA RIMINI 47841
+ IT
+
70-B3-D5 (hex) LOTES TM OOO
EA5000-EA5FFF (base 16) LOTES TM OOO
Barklaya 22, str.1
Moscow 121309
RU
-70-B3-D5 (hex) Yi An Electronics Co., Ltd
-F28000-F28FFF (base 16) Yi An Electronics Co., Ltd
- 5F.-2, No. 81, Sec. 1, Xintai 5th Rd., Xizhi Dist
- New Taipei City 22101
- TW
-
70-B3-D5 (hex) Ariston Thermo s.p.a.
3D6000-3D6FFF (base 16) Ariston Thermo s.p.a.
Via Aristide Merloni 45
Fabriano Ancona 60044
IT
-70-B3-D5 (hex) MG s.r.l.
-130000-130FFF (base 16) MG s.r.l.
- via Monte Bianco, 1
- Solbiate Olona VA 21058
- IT
+70-B3-D5 (hex) Yi An Electronics Co., Ltd
+F28000-F28FFF (base 16) Yi An Electronics Co., Ltd
+ 5F.-2, No. 81, Sec. 1, Xintai 5th Rd., Xizhi Dist
+ New Taipei City 22101
+ TW
70-B3-D5 (hex) DORLET SAU
639000-639FFF (base 16) DORLET SAU
@@ -8957,6 +8969,18 @@ F28000-F28FFF (base 16) Yi An Electronics Co., Ltd
Ryazan 390048
RU
+70-B3-D5 (hex) MG s.r.l.
+130000-130FFF (base 16) MG s.r.l.
+ via Monte Bianco, 1
+ Solbiate Olona VA 21058
+ IT
+
+70-B3-D5 (hex) Postmark Incorporated
+CBB000-CBBFFF (base 16) Postmark Incorporated
+ 3197 Duncan Lane
+ San Luis Obispo CA 93401
+ US
+
70-B3-D5 (hex) Glory Technology Service Inc.
801000-801FFF (base 16) Glory Technology Service Inc.
3F., No.43-1, Ln. 11, Sec. 6, Minquan E. Rd
@@ -8969,12 +8993,6 @@ F28000-F28FFF (base 16) Yi An Electronics Co., Ltd
Gifu-shi Gifu 500-8122
JP
-70-B3-D5 (hex) Postmark Incorporated
-CBB000-CBBFFF (base 16) Postmark Incorporated
- 3197 Duncan Lane
- San Luis Obispo CA 93401
- US
-
70-B3-D5 (hex) Abbott Diagnostics Technologies AS
53F000-53FFFF (base 16) Abbott Diagnostics Technologies AS
P. O. Box 6863 Rodeløkka
@@ -8999,12 +9017,6 @@ CBB000-CBBFFF (base 16) Postmark Incorporated
VILLA BARTOLOMEA IT 37049
IT
-70-B3-D5 (hex) Global Power Products
-3B1000-3B1FFF (base 16) Global Power Products
- 225 Arnold Road
- Lawrenceville 30044
- US
-
70-B3-D5 (hex) Sankyo Intec Co,ltd
E7F000-E7FFFF (base 16) Sankyo Intec Co,ltd
127 Tokimata
@@ -9017,6 +9029,18 @@ E7F000-E7FFFF (base 16) Sankyo Intec Co,ltd
waltham MA 02453
US
+70-B3-D5 (hex) Global Power Products
+3B1000-3B1FFF (base 16) Global Power Products
+ 225 Arnold Road
+ Lawrenceville 30044
+ US
+
+70-B3-D5 (hex) Nidec asi spa
+D88000-D88FFF (base 16) Nidec asi spa
+ s.s11 , ca sordis 4
+ Montebello Vicentino vicenza 36054
+ IT
+
70-B3-D5 (hex) EnergizeEV
EB6000-EB6FFF (base 16) EnergizeEV
#160, 1684 Decoto Road
@@ -9029,12 +9053,6 @@ F66000-F66FFF (base 16) Seznam.cz, a.s., CZ26168685
Praha Czech Republic 15000
CZ
-70-B3-D5 (hex) Nidec asi spa
-D88000-D88FFF (base 16) Nidec asi spa
- s.s11 , ca sordis 4
- Montebello Vicentino vicenza 36054
- IT
-
70-B3-D5 (hex) Frog Cellsat Limited
C5E000-C5EFFF (base 16) Frog Cellsat Limited
D-213, Sector-63, Noida
@@ -9077,11 +9095,11 @@ C5E000-C5EFFF (base 16) Frog Cellsat Limited
Shanghai Shanghai 201114
CN
-70-B3-D5 (hex) NooliTIC
-E51000-E51FFF (base 16) NooliTIC
- 165 avenue de bretagne
- LILLE 59000
- FR
+70-B3-D5 (hex) Sphere of economical technologies Ltd
+1C1000-1C1FFF (base 16) Sphere of economical technologies Ltd
+ 132, 7-ya Liniya Str.
+ Omsk Omskaya oblast 644021
+ RU
70-B3-D5 (hex) Simplified MFG
66F000-66FFFF (base 16) Simplified MFG
@@ -9089,11 +9107,11 @@ E51000-E51FFF (base 16) NooliTIC
Mesa AZ 85206
US
-70-B3-D5 (hex) Sphere of economical technologies Ltd
-1C1000-1C1FFF (base 16) Sphere of economical technologies Ltd
- 132, 7-ya Liniya Str.
- Omsk Omskaya oblast 644021
- RU
+70-B3-D5 (hex) NooliTIC
+E51000-E51FFF (base 16) NooliTIC
+ 165 avenue de bretagne
+ LILLE 59000
+ FR
70-B3-D5 (hex) Scenario Automation
43C000-43CFFF (base 16) Scenario Automation
@@ -9131,18 +9149,18 @@ D35000-D35FFF (base 16) King-On Technology Ltd.
New Taipei City Taiwan 23143
TW
-70-B3-D5 (hex) BRS Sistemas Eletrônicos
-3CD000-3CDFFF (base 16) BRS Sistemas Eletrônicos
- Rua Gomes de Freitas, 491 / 204
- Porto Alegre RS 91380-000
- BR
-
70-B3-D5 (hex) Nuance Hearing Ltd.
AE4000-AE4FFF (base 16) Nuance Hearing Ltd.
Raoul Wallenberg 24, Building A1, Floor 3
Tel Aviv 6971920
IL
+70-B3-D5 (hex) BRS Sistemas Eletrônicos
+3CD000-3CDFFF (base 16) BRS Sistemas Eletrônicos
+ Rua Gomes de Freitas, 491 / 204
+ Porto Alegre RS 91380-000
+ BR
+
70-B3-D5 (hex) HONG JIANG ELECTRONICS CO., LTD.
E64000-E64FFF (base 16) HONG JIANG ELECTRONICS CO., LTD.
9F, No. 649-3, Zhong Zheng Rd.,, Xin Zhuang Dist., New Taipei City,, TAIWAN(R.O.C.)
@@ -9155,10 +9173,10 @@ E64000-E64FFF (base 16) HONG JIANG ELECTRONICS CO., LTD.
TianHe GuangZhou 515800
CN
-70-B3-D5 (hex) Klaxoon
-DB3000-DB3FFF (base 16) Klaxoon
- 3 av de Belle Fontaine
- Cesson-Sevigne 35510
+70-B3-D5 (hex) OLEDCOMM
+7D3000-7D3FFF (base 16) OLEDCOMM
+ 10-12 avenue de l'Europe
+ Vélizy Villacoublay Ile de France 78140
FR
70-B3-D5 (hex) Malin Space Science System
@@ -9167,12 +9185,30 @@ FE5000-FE5FFF (base 16) Malin Space Science System
San Diego CA 92121
US
-70-B3-D5 (hex) OLEDCOMM
-7D3000-7D3FFF (base 16) OLEDCOMM
- 10-12 avenue de l'Europe
- Vélizy Villacoublay Ile de France 78140
+70-B3-D5 (hex) Wexiodisk AB
+905000-905FFF (base 16) Wexiodisk AB
+ Mardvagen 4
+ Vaxjo Kronoberg 352 45
+ SE
+
+70-B3-D5 (hex) Klaxoon
+DB3000-DB3FFF (base 16) Klaxoon
+ 3 av de Belle Fontaine
+ Cesson-Sevigne 35510
FR
+70-B3-D5 (hex) ECoCoMS Ltd.
+5CB000-5CBFFF (base 16) ECoCoMS Ltd.
+ BIC-ISOT, Tzarigradsko shose blvd., 7-th km, Corpus 3, fl. 4,
+ Sofia BG 1784
+ BG
+
+70-B3-D5 (hex) MetCom Solutions GmbH
+D18000-D18FFF (base 16) MetCom Solutions GmbH
+ Marie-Curie-Str. 19
+ Mannheim Baden-Wuerttemberg 68219
+ DE
+
70-B3-D5 (hex) System West dba ICS Electronics
E06000-E06FFF (base 16) System West dba ICS Electronics
7034 Commerce Circle Suite A
@@ -13400,6 +13436,18 @@ F23000-F23FFF (base 16) Lyse AS
Bad Marienberg Rheinland-Pfalz 56470
DE
+70-B3-D5 (hex) Walton Hi-Tech Industries Ltd.
+E5C000-E5CFFF (base 16) Walton Hi-Tech Industries Ltd.
+ HOLDING NO. I-65/2, WARD NO-07
+ CHANDRA, KALIAKOIR, GAZIPUR. 1750
+ BD
+
+70-B3-D5 (hex) Flextronics International Kft
+699000-699FFF (base 16) Flextronics International Kft
+ 38. Zrinyi Str.
+ Zalaegerszeg Zala 8900
+ HU
+
70-B3-D5 (hex) JFA Electronics Industry and Commerce EIRELI
5F7000-5F7FFF (base 16) JFA Electronics Industry and Commerce EIRELI
Rua Flor das Pedras, 175
@@ -13412,12 +13460,6 @@ F23000-F23FFF (base 16) Lyse AS
Boonton Township NJ 07005
US
-70-B3-D5 (hex) Walton Hi-Tech Industries Ltd.
-E5C000-E5CFFF (base 16) Walton Hi-Tech Industries Ltd.
- HOLDING NO. I-65/2, WARD NO-07
- CHANDRA, KALIAKOIR, GAZIPUR. 1750
- BD
-
70-B3-D5 (hex) aquila biolabs GmbH
7DB000-7DBFFF (base 16) aquila biolabs GmbH
Arnold-Sommerfeld-Ring 2
@@ -13430,12 +13472,6 @@ C82000-C82FFF (base 16) Sicon srl
Isola Vicentina Vicenza 36033
IT
-70-B3-D5 (hex) Flextronics International Kft
-699000-699FFF (base 16) Flextronics International Kft
- 38. Zrinyi Str.
- Zalaegerszeg Zala 8900
- HU
-
70-B3-D5 (hex) LGE
DAE000-DAEFFF (base 16) LGE
10, Magokjungang 10-ro, Gangseo-gu
@@ -13490,6 +13526,12 @@ F64000-F64FFF (base 16) silicom
Borehamwood Hert WD6 1NA
GB
+70-B3-D5 (hex) Kospel S.A.
+249000-249FFF (base 16) Kospel S.A.
+ Olchowa 1
+ Koszalin 75-136
+ PL
+
70-B3-D5 (hex) Microchip Technology Germany II GmbH&Co.KG
77F000-77FFFF (base 16) Microchip Technology Germany II GmbH&Co.KG
Emmy-Noether-Straße 14
@@ -13502,12 +13544,6 @@ C98000-C98FFF (base 16) Trust Automation
San Luis Obispo CA 93401
US
-70-B3-D5 (hex) Kospel S.A.
-249000-249FFF (base 16) Kospel S.A.
- Olchowa 1
- Koszalin 75-136
- PL
-
70-B3-D5 (hex) Coheros Oy
D2E000-D2EFFF (base 16) Coheros Oy
Tammukkakatu 6
@@ -13520,18 +13556,6 @@ E24000-E24FFF (base 16) Gogo Business Aviation
Broomfield CO 80021
US
-70-B3-D5 (hex) Taejin InfoTech
-A75000-A75FFF (base 16) Taejin InfoTech
- 40, Imi-ro, A-411
- Uiwang-si Gyeonggi-do 16006
- KR
-
-70-B3-D5 (hex) ARCLAN'SYSTEM
-25C000-25CFFF (base 16) ARCLAN'SYSTEM
- 1140 rue Ampère - Actimart II - Lot 9
- AIX EN PROVENCE 13290
- FR
-
70-B3-D5 (hex) Smart Embedded Systems
A09000-A09FFF (base 16) Smart Embedded Systems
6701 Koll Center Parkway #250
@@ -13544,6 +13568,18 @@ F6A000-F6AFFF (base 16) Guan Show Technologe Co., Ltd.
Kaohsiung City 802
TW
+70-B3-D5 (hex) Taejin InfoTech
+A75000-A75FFF (base 16) Taejin InfoTech
+ 40, Imi-ro, A-411
+ Uiwang-si Gyeonggi-do 16006
+ KR
+
+70-B3-D5 (hex) ARCLAN'SYSTEM
+25C000-25CFFF (base 16) ARCLAN'SYSTEM
+ 1140 rue Ampère - Actimart II - Lot 9
+ AIX EN PROVENCE 13290
+ FR
+
70-B3-D5 (hex) LLC Sarov Innovative Technologies (WIZOLUTION)
50F000-50FFFF (base 16) LLC Sarov Innovative Technologies (WIZOLUTION)
RUSSIAN FEDERATION, Nizhny Novgorod region, Varlamovskaya road, 7, build 2
@@ -13556,6 +13592,12 @@ A77000-A77FFF (base 16) SPX Radiodetection
Bristol Avon BS14 0AF
GB
+70-B3-D5 (hex) INVISSYS
+AD4000-AD4FFF (base 16) INVISSYS
+ 25 rue marcel issartier
+ merignac 33700
+ FR
+
70-B3-D5 (hex) LM-Instruments Oy
5AC000-5ACFFF (base 16) LM-Instruments Oy
Norrbyn rantatie 8
@@ -13568,28 +13610,16 @@ DBB000-DBBFFF (base 16) Fuhr GmbH Filtertechnik
Klein-Winternheim Rheinland-Pfalz 55270
DE
-70-B3-D5 (hex) Sanmina Israel
-C18000-C18FFF (base 16) Sanmina Israel
- Koren Industrial Zone , POBox 102
- Maalot Israel 2101002
- IL
-
-70-B3-D5 (hex) INVISSYS
-AD4000-AD4FFF (base 16) INVISSYS
- 25 rue marcel issartier
- merignac 33700
- FR
-
70-B3-D5 (hex) Panoramic Power
669000-669FFF (base 16) Panoramic Power
15 Atir Yeda
Kfar Saba 4464312
IL
-70-B3-D5 (hex) Panoramic Power
-06D000-06DFFF (base 16) Panoramic Power
- Atir Yeda 15
- Kfar Saba 4464312
+70-B3-D5 (hex) Sanmina Israel
+C18000-C18FFF (base 16) Sanmina Israel
+ Koren Industrial Zone , POBox 102
+ Maalot Israel 2101002
IL
70-B3-D5 (hex) Avlinkpro
@@ -13598,11 +13628,11 @@ AD4000-AD4FFF (base 16) INVISSYS
Totowa NJ 07512
US
-70-B3-D5 (hex) DECYBEN
-683000-683FFF (base 16) DECYBEN
- 170 Rue Raymond Losserand
- Paris 75014
- FR
+70-B3-D5 (hex) Panoramic Power
+06D000-06DFFF (base 16) Panoramic Power
+ Atir Yeda 15
+ Kfar Saba 4464312
+ IL
70-B3-D5 (hex) C4I Systems Ltd
5C6000-5C6FFF (base 16) C4I Systems Ltd
@@ -13616,11 +13646,11 @@ C36000-C36FFF (base 16) Knowledge Resources GmbH
Bsel BS 4057
CH
-70-B3-D5 (hex) CoreEL Technologies Pvt Ltd
-10D000-10DFFF (base 16) CoreEL Technologies Pvt Ltd
- #21, 7th Main, 1st Block ,Koramangala,
- Bangalore Karnataka 560034
- IN
+70-B3-D5 (hex) DECYBEN
+683000-683FFF (base 16) DECYBEN
+ 170 Rue Raymond Losserand
+ Paris 75014
+ FR
70-B3-D5 (hex) adnexo GmbH
4E3000-4E3FFF (base 16) adnexo GmbH
@@ -13640,6 +13670,12 @@ C23000-C23FFF (base 16) Sumitomo Heavy Industries, Ltd.
Moscow Moscow 109380
RU
+70-B3-D5 (hex) CoreEL Technologies Pvt Ltd
+10D000-10DFFF (base 16) CoreEL Technologies Pvt Ltd
+ #21, 7th Main, 1st Block ,Koramangala,
+ Bangalore Karnataka 560034
+ IN
+
70-B3-D5 (hex) Shenzhen Vikings Technology Co., Ltd.
46A000-46AFFF (base 16) Shenzhen Vikings Technology Co., Ltd.
Floor 3, building 2, tiantong industrial park, gaofeng community, dalang street, longhua district
@@ -13652,18 +13688,18 @@ C23000-C23FFF (base 16) Sumitomo Heavy Industries, Ltd.
Ho Chi Minh City Ho Chi Minh 70000
VN
-70-B3-D5 (hex) aelettronica group srl
-AD9000-AD9FFF (base 16) aelettronica group srl
- via matteotti,22
- gaggiano milano 20083
- IT
-
70-B3-D5 (hex) C W F Hamilton & Co Ltd
82A000-82AFFF (base 16) C W F Hamilton & Co Ltd
20 Lunns Road, Middleton
Christchurch Canterbury 8024
NZ
+70-B3-D5 (hex) aelettronica group srl
+AD9000-AD9FFF (base 16) aelettronica group srl
+ via matteotti,22
+ gaggiano milano 20083
+ IT
+
70-B3-D5 (hex) Wuhan Xingtuxinke ELectronic Co.,Ltd
165000-165FFF (base 16) Wuhan Xingtuxinke ELectronic Co.,Ltd
NO.C3-8F,Software Park,Optics Valley,East Lake Development Zone,Wuhan,Hubei,China
@@ -13724,18 +13760,18 @@ B90000-B90FFF (base 16) Amico Corporation
Seung-nam Si Gyeonggi-Do 13488
KR
-70-B3-D5 (hex) TIAMA
-8A1000-8A1FFF (base 16) TIAMA
- ZA des Plattes - 1 Chemin des Plattes
- VOURLES 69390
- FR
-
70-B3-D5 (hex) Honeywell/Intelligrated
94C000-94CFFF (base 16) Honeywell/Intelligrated
10045 International Blvd
Cincinnati OH 45246
US
+70-B3-D5 (hex) TIAMA
+8A1000-8A1FFF (base 16) TIAMA
+ ZA des Plattes - 1 Chemin des Plattes
+ VOURLES 69390
+ FR
+
70-B3-D5 (hex) LARIMART SPA
536000-536FFF (base 16) LARIMART SPA
VIA DI TORREVECCHIA
@@ -13754,18 +13790,18 @@ EDA000-EDAFFF (base 16) Breas Medical AB
Mölnlycke SE-435 33
SE
-70-B3-D5 (hex) Packet Power
-B54000-B54FFF (base 16) Packet Power
- 2716 Summer Str. N.E.
- Minneapolis MN 55413
- US
-
70-B3-D5 (hex) Ketronixs Sdn Bhd
6AC000-6ACFFF (base 16) Ketronixs Sdn Bhd
51-17-B Menara BHL Bank, Jalan Sultan Ahmad Shah
Georgetown Penang 10050
MY
+70-B3-D5 (hex) Packet Power
+B54000-B54FFF (base 16) Packet Power
+ 2716 Summer Str. N.E.
+ Minneapolis MN 55413
+ US
+
70-B3-D5 (hex) Alto Aviation
D0F000-D0FFFF (base 16) Alto Aviation
86 Leominster Road
@@ -13784,6 +13820,12 @@ D0F000-D0FFFF (base 16) Alto Aviation
Marseille 13012
FR
+70-B3-D5 (hex) LG Electronics
+A23000-A23FFF (base 16) LG Electronics
+ LG Science Park, 10, Magokjungang 10-ro, GangSeo-gu
+ SEOUL 07796
+ KR
+
70-B3-D5 (hex) YUYAMA MFG Co.,Ltd
BBB000-BBBFFF (base 16) YUYAMA MFG Co.,Ltd
3-3-1
@@ -18008,30 +18050,24 @@ BE0000-BE0FFF (base 16) Cognosos, Inc.
Taoyuan 330
TW
-70-B3-D5 (hex) Zhuhai Lonl electric Co.,Ltd.
-EA9000-EA9FFF (base 16) Zhuhai Lonl electric Co.,Ltd.
- 2nd floor, building B3, nanfang software park, xiangzhou district
- Zhuhai Guangdong 519000
- CN
-
70-B3-D5 (hex) PolyTech A/S
F4C000-F4CFFF (base 16) PolyTech A/S
HI Park 445
Herning Herning 7400
DK
+70-B3-D5 (hex) Zhuhai Lonl electric Co.,Ltd.
+EA9000-EA9FFF (base 16) Zhuhai Lonl electric Co.,Ltd.
+ 2nd floor, building B3, nanfang software park, xiangzhou district
+ Zhuhai Guangdong 519000
+ CN
+
70-B3-D5 (hex) Shanghai Tiancheng Communication Technology Corporation
1C3000-1C3FFF (base 16) Shanghai Tiancheng Communication Technology Corporation
No.618,Guangxing Rd.,Songjiang
shanghai 200090
CN
-70-B3-D5 (hex) T&M Media Pty Ltd
-B41000-B41FFF (base 16) T&M Media Pty Ltd
- 6, 476 Gardeners Road
- Alexandria NSW 2015
- AU
-
70-B3-D5 (hex) SAMBO HITECH
282000-282FFF (base 16) SAMBO HITECH
469,Seokjung-ro,Namdong-Gu
@@ -18044,34 +18080,40 @@ F9F000-F9FFFF (base 16) M.A.C. Solutions (UK) Ltd
Redditch Worcestershire B98 8LG
GB
-70-B3-D5 (hex) Shenzhen CAMERAY ELECTRONIC CO., LTD
-1E2000-1E2FFF (base 16) Shenzhen CAMERAY ELECTRONIC CO., LTD
- 4-5FL, Building 1, Guanghui Science, and Technology Park; Minqing Road, Longhua Town
- shenzhen GD 518109
- CN
-
-70-B3-D5 (hex) Vulcan Wireless Inc.
-E4D000-E4DFFF (base 16) Vulcan Wireless Inc.
- 2218 Faraday Ave Suite 110
- Carlsbad CA 92008
- US
-
70-B3-D5 (hex) ERA TOYS LIMITED
193000-193FFF (base 16) ERA TOYS LIMITED
Room 505, 5th Floor, Beverley Commercial Centre, 87-105 Chatham Road South
Tsim Sha Tsui Kowloon 0000
HK
+70-B3-D5 (hex) T&M Media Pty Ltd
+B41000-B41FFF (base 16) T&M Media Pty Ltd
+ 6, 476 Gardeners Road
+ Alexandria NSW 2015
+ AU
+
+70-B3-D5 (hex) A&T Corporation
+32E000-32EFFF (base 16) A&T Corporation
+ 2023-1
+ Endo, Fujisawa, Kanagawa 252-0816
+ JP
+
70-B3-D5 (hex) Scorpion Precision Industry (HK)CO. Ltd.
02B000-02BFFF (base 16) Scorpion Precision Industry (HK)CO. Ltd.
16th Floor, Excelsior Industrial Building,68-76 Sha Tsui Road,
Tsuen Wan New Territories 999077
HK
-70-B3-D5 (hex) Cryptotronix LLC
-0DB000-0DBFFF (base 16) Cryptotronix LLC
- P.O. Box 273029
- Fort Collins CO 80525
+70-B3-D5 (hex) Shenzhen CAMERAY ELECTRONIC CO., LTD
+1E2000-1E2FFF (base 16) Shenzhen CAMERAY ELECTRONIC CO., LTD
+ 4-5FL, Building 1, Guanghui Science, and Technology Park; Minqing Road, Longhua Town
+ shenzhen GD 518109
+ CN
+
+70-B3-D5 (hex) Vulcan Wireless Inc.
+E4D000-E4DFFF (base 16) Vulcan Wireless Inc.
+ 2218 Faraday Ave Suite 110
+ Carlsbad CA 92008
US
70-B3-D5 (hex) MIVO Technology AB
@@ -18080,11 +18122,11 @@ E4D000-E4DFFF (base 16) Vulcan Wireless Inc.
Stockholm 11215
SE
-70-B3-D5 (hex) A&T Corporation
-32E000-32EFFF (base 16) A&T Corporation
- 2023-1
- Endo, Fujisawa, Kanagawa 252-0816
- JP
+70-B3-D5 (hex) Cryptotronix LLC
+0DB000-0DBFFF (base 16) Cryptotronix LLC
+ P.O. Box 273029
+ Fort Collins CO 80525
+ US
70-B3-D5 (hex) TOMEI TSUSHIN KOGYO CO,.LTD
FB1000-FB1FFF (base 16) TOMEI TSUSHIN KOGYO CO,.LTD
@@ -18092,12 +18134,6 @@ FB1000-FB1FFF (base 16) TOMEI TSUSHIN KOGYO CO,.LTD
Inazawa Shi Aichi ken 4928274
JP
-70-B3-D5 (hex) DogWatch Inc
-1E7000-1E7FFF (base 16) DogWatch Inc
- 10 Michigan Drive
- Natick 01760
- US
-
70-B3-D5 (hex) RCH Vietnam Limited Liability Company
C09000-C09FFF (base 16) RCH Vietnam Limited Liability Company
Workshop F.01B-2, Lot No. F.01B Long Hau
@@ -18110,6 +18146,24 @@ F69000-F69FFF (base 16) Copper Labs, Inc.
Boulder CO 80301
US
+70-B3-D5 (hex) DogWatch Inc
+1E7000-1E7FFF (base 16) DogWatch Inc
+ 10 Michigan Drive
+ Natick 01760
+ US
+
+70-B3-D5 (hex) Grossenbacher Systeme AG
+B75000-B75FFF (base 16) Grossenbacher Systeme AG
+ Spinnereistrasse 10
+ St. Gallen 9008
+ CH
+
+70-B3-D5 (hex) ITsynergy Ltd
+D2A000-D2AFFF (base 16) ITsynergy Ltd
+ 9 Bonhill Street
+ London EC2A 4DJ
+ GB
+
70-B3-D5 (hex) SHENZHEN HUINENGYUAN Technology Co., Ltd
A83000-A83FFF (base 16) SHENZHEN HUINENGYUAN Technology Co., Ltd
Room 206, 3 Building, Hongwanchuangke Center, Gushu, Xixiang, Baoan District
@@ -18134,41 +18188,23 @@ C94000-C94FFF (base 16) Vars Technology
Blaricum 1261WT
NL
-70-B3-D5 (hex) Grossenbacher Systeme AG
-B75000-B75FFF (base 16) Grossenbacher Systeme AG
- Spinnereistrasse 10
- St. Gallen 9008
- CH
-
-70-B3-D5 (hex) ITsynergy Ltd
-D2A000-D2AFFF (base 16) ITsynergy Ltd
- 9 Bonhill Street
- London EC2A 4DJ
- GB
-
70-B3-D5 (hex) Vaunix Technology Corporation
EE6000-EE6FFF (base 16) Vaunix Technology Corporation
7 New Pasture Rd
Newburyport MA 01950
US
-70-B3-D5 (hex) chargeBIG
-869000-869FFF (base 16) chargeBIG
- Pragstraße 26-46
- Stuttgart 70376
- DE
-
70-B3-D5 (hex) Portrait Displays, Inc.
D77000-D77FFF (base 16) Portrait Displays, Inc.
6663 OWENS DR
PLEASANTON CA 94588
US
-70-B3-D5 (hex) Sprintshield d.o.o.
-B03000-B03FFF (base 16) Sprintshield d.o.o.
- Marina Getaldi?a 3
- Velika Gorica 10410
- HR
+70-B3-D5 (hex) chargeBIG
+869000-869FFF (base 16) chargeBIG
+ Pragstraße 26-46
+ Stuttgart 70376
+ DE
70-B3-D5 (hex) Tricom Research Inc.
601000-601FFF (base 16) Tricom Research Inc.
@@ -18176,11 +18212,11 @@ B03000-B03FFF (base 16) Sprintshield d.o.o.
Irvine CA 92614
US
-70-B3-D5 (hex) Mictrotrac Retsch GmbH
-F09000-F09FFF (base 16) Mictrotrac Retsch GmbH
- Retsch-Allee 1-5
- Haan NRW 42781
- DE
+70-B3-D5 (hex) Sprintshield d.o.o.
+B03000-B03FFF (base 16) Sprintshield d.o.o.
+ Marina Getaldi?a 3
+ Velika Gorica 10410
+ HR
70-B3-D5 (hex) KeyProd
473000-473FFF (base 16) KeyProd
@@ -18188,22 +18224,10 @@ F09000-F09FFF (base 16) Mictrotrac Retsch GmbH
Paris 77008
FR
-70-B3-D5 (hex) WARECUBE,INC
-AD3000-AD3FFF (base 16) WARECUBE,INC
- #A-811, 142-10, Saneop-ro, 156beon-gil, Gwonseon-gu
- Suwon-si 16648
- KR
-
-70-B3-D5 (hex) myUpTech AB
-FC3000-FC3FFF (base 16) myUpTech AB
- Box 14
- Markaryd 28532
- SE
-
-70-B3-D5 (hex) Scharco Elektronik GmbH
-C72000-C72FFF (base 16) Scharco Elektronik GmbH
- Tilsiter Strasse 8
- Wuppertal NRW 42277
+70-B3-D5 (hex) Mictrotrac Retsch GmbH
+F09000-F09FFF (base 16) Mictrotrac Retsch GmbH
+ Retsch-Allee 1-5
+ Haan NRW 42781
DE
70-B3-D5 (hex) MB connect line GmbH Fernwartungssysteme
@@ -18218,12 +18242,30 @@ E01000-E01FFF (base 16) EarTex
London England N1 6DR
GB
+70-B3-D5 (hex) Scharco Elektronik GmbH
+C72000-C72FFF (base 16) Scharco Elektronik GmbH
+ Tilsiter Strasse 8
+ Wuppertal NRW 42277
+ DE
+
70-B3-D5 (hex) AVL DiTEST GmbH
78D000-78DFFF (base 16) AVL DiTEST GmbH
Alte Poststrasse 156
Graz 8020
AT
+70-B3-D5 (hex) WARECUBE,INC
+AD3000-AD3FFF (base 16) WARECUBE,INC
+ #A-811, 142-10, Saneop-ro, 156beon-gil, Gwonseon-gu
+ Suwon-si 16648
+ KR
+
+70-B3-D5 (hex) myUpTech AB
+FC3000-FC3FFF (base 16) myUpTech AB
+ Box 14
+ Markaryd 28532
+ SE
+
70-B3-D5 (hex) TextSpeak Corporation
F0E000-F0EFFF (base 16) TextSpeak Corporation
55 Greensfarm RD 2nd Flr 200-69
@@ -18236,18 +18278,18 @@ F0E000-F0EFFF (base 16) TextSpeak Corporation
Zola Predosa Bologna 40069
IT
-70-B3-D5 (hex) HongSeok Ltd.
-30A000-30AFFF (base 16) HongSeok Ltd.
- 166, Osan-ro, Osan-myeon
- Iksan-si Jeollabuk-do 54670
- KR
-
70-B3-D5 (hex) WAYNE ANALYTICS LLC
301000-301FFF (base 16) WAYNE ANALYTICS LLC
100 Rialto Place, Suite 721
MELBOURNE FL 32901
US
+70-B3-D5 (hex) HongSeok Ltd.
+30A000-30AFFF (base 16) HongSeok Ltd.
+ 166, Osan-ro, Osan-myeon
+ Iksan-si Jeollabuk-do 54670
+ KR
+
70-B3-D5 (hex) GS Elektromedizinsiche Geräte G. Stemple GmbH
3D3000-3D3FFF (base 16) GS Elektromedizinsiche Geräte G. Stemple GmbH
Hauswiesenstr. 26
@@ -18278,16 +18320,22 @@ E1C000-E1CFFF (base 16) RoomMate AS
Daejeon Yuseong-gu 34016
KR
+70-B3-D5 (hex) Sequent AG
+291000-291FFF (base 16) Sequent AG
+ Eptingerstrasse 3
+ Basel 4052
+ CH
+
70-B3-D5 (hex) KODENSHI CORP.
DBA000-DBAFFF (base 16) KODENSHI CORP.
161,Jyuichi,Makishima
UJI KYOTO 6110041
JP
-70-B3-D5 (hex) Sequent AG
-291000-291FFF (base 16) Sequent AG
- Eptingerstrasse 3
- Basel 4052
+70-B3-D5 (hex) ID Quantique SA
+657000-657FFF (base 16) ID Quantique SA
+ 3 chemin de la marbrerie
+ Carouge 1227
CH
70-B3-D5 (hex) Profusion Limited
@@ -18296,11 +18344,11 @@ DBA000-DBAFFF (base 16) KODENSHI CORP.
Southend on Sea Essex SS2 6UN
GB
-70-B3-D5 (hex) ID Quantique SA
-657000-657FFF (base 16) ID Quantique SA
- 3 chemin de la marbrerie
- Carouge 1227
- CH
+70-B3-D5 (hex) CDS Institute of Management Strategy, Inc.
+3A3000-3A3FFF (base 16) CDS Institute of Management Strategy, Inc.
+ Fukuyoshi-cho Billding 7F, Roppongi 2-2-6
+ MINATO-KU TOKYO 1060032
+ JP
70-B3-D5 (hex) Cubitech
B86000-B86FFF (base 16) Cubitech
@@ -18308,12 +18356,6 @@ B86000-B86FFF (base 16) Cubitech
Tavros Athens 17778
GR
-70-B3-D5 (hex) CDS Institute of Management Strategy, Inc.
-3A3000-3A3FFF (base 16) CDS Institute of Management Strategy, Inc.
- Fukuyoshi-cho Billding 7F, Roppongi 2-2-6
- MINATO-KU TOKYO 1060032
- JP
-
70-B3-D5 (hex) BIT Group USA, Inc.
C75000-C75FFF (base 16) BIT Group USA, Inc.
15870 Bernardo center drive
@@ -18350,12 +18392,6 @@ B6F000-B6FFFF (base 16) Integra Metering SAS
Ramsen 8262
CH
-70-B3-D5 (hex) K&A Electronics Inc.
-9E4000-9E4FFF (base 16) K&A Electronics Inc.
- 2609 Pinelawn dr.
- La Crescenta CA 91214
- US
-
70-B3-D5 (hex) Paramount Bed Holdings Co., Ltd.
8F1000-8F1FFF (base 16) Paramount Bed Holdings Co., Ltd.
2-14-5. Higashisuna
@@ -18374,6 +18410,12 @@ B6F000-B6FFFF (base 16) Integra Metering SAS
LONDON County (optional) N17 9LJ
GB
+70-B3-D5 (hex) K&A Electronics Inc.
+9E4000-9E4FFF (base 16) K&A Electronics Inc.
+ 2609 Pinelawn dr.
+ La Crescenta CA 91214
+ US
+
70-B3-D5 (hex) Indutherm Giesstechnologie GmbH
8DE000-8DEFFF (base 16) Indutherm Giesstechnologie GmbH
Brettener Straße 32
@@ -18398,6 +18440,12 @@ D97000-D97FFF (base 16) BRS Sistemas Eletrônicos
Porto Alegre - RS (Non U.S.) 91380-000
BR
+70-B3-D5 (hex) Ideas srl
+B63000-B63FFF (base 16) Ideas srl
+ Via dei Brughi, 21
+ Gessate Milan 20060
+ IT
+
70-B3-D5 (hex) 2M Technology
F7D000-F7DFFF (base 16) 2M Technology
802 Greenview Drive
@@ -18410,18 +18458,30 @@ F7D000-F7DFFF (base 16) 2M Technology
Natick MA 01760
US
-70-B3-D5 (hex) Ideas srl
-B63000-B63FFF (base 16) Ideas srl
- Via dei Brughi, 21
- Gessate Milan 20060
- IT
-
70-B3-D5 (hex) Invert Robotics Ltd.
FC7000-FC7FFF (base 16) Invert Robotics Ltd.
Unit A, 235 Annex Road
Christchurch 8024
NZ
+70-B3-D5 (hex) AERIAL CAMERA SYSTEMS Ltd
+FC4000-FC4FFF (base 16) AERIAL CAMERA SYSTEMS Ltd
+ 3 The Merlin Centre, Lancaster Road,
+ HIGH WYCOMBE HP12 3QL
+ GB
+
+70-B3-D5 (hex) TUALCOM ELEKTRONIK A.S.
+4A3000-4A3FFF (base 16) TUALCOM ELEKTRONIK A.S.
+ Mustafa Kemal mah.
+ ANKARA 06530
+ TR
+
+70-B3-D5 (hex) Underground Systems, Inc.
+424000-424FFF (base 16) Underground Systems, Inc.
+ 3A Trowbridge Drive
+ Bethel CT 06801
+ US
+
70-B3-D5 (hex) MPM Micro Präzision Marx GmbH
F60000-F60FFF (base 16) MPM Micro Präzision Marx GmbH
Neuenweiherstraße 19
@@ -18434,23 +18494,11 @@ F60000-F60FFF (base 16) MPM Micro Präzision Marx GmbH
San Francisco CA 94103-4938
US
-70-B3-D5 (hex) Underground Systems, Inc.
-424000-424FFF (base 16) Underground Systems, Inc.
- 3A Trowbridge Drive
- Bethel CT 06801
- US
-
-70-B3-D5 (hex) AERIAL CAMERA SYSTEMS Ltd
-FC4000-FC4FFF (base 16) AERIAL CAMERA SYSTEMS Ltd
- 3 The Merlin Centre, Lancaster Road,
- HIGH WYCOMBE HP12 3QL
- GB
-
-70-B3-D5 (hex) TUALCOM ELEKTRONIK A.S.
-4A3000-4A3FFF (base 16) TUALCOM ELEKTRONIK A.S.
- Mustafa Kemal mah.
- ANKARA 06530
- TR
+70-B3-D5 (hex) Hensoldt Sensors GmbH
+2D3000-2D3FFF (base 16) Hensoldt Sensors GmbH
+ Woerthstrasse 85
+ Ulm Baden-Wuerttemberg 89081
+ DE
70-B3-D5 (hex) Kron Medidores
C1E000-C1EFFF (base 16) Kron Medidores
@@ -18458,11 +18506,41 @@ C1E000-C1EFFF (base 16) Kron Medidores
São Paulo São Paulo 04760-020
BR
-70-B3-D5 (hex) Hensoldt Sensors GmbH
-2D3000-2D3FFF (base 16) Hensoldt Sensors GmbH
- Woerthstrasse 85
- Ulm Baden-Wuerttemberg 89081
- DE
+70-B3-D5 (hex) Shanghai Jupper Technology Co.Ltd
+157000-157FFF (base 16) Shanghai Jupper Technology Co.Ltd
+ Room511,building D10, Lane 3188, Xiupu road, Pudong New District
+ Shanghai 201315
+ CN
+
+70-B3-D5 (hex) S-Rain Control A/S
+B68000-B68FFF (base 16) S-Rain Control A/S
+ Oldenvej 6
+ Kvistgård Copenhagen DK-3490
+ DK
+
+70-B3-D5 (hex) Thermo Fisher Scientific Inc.
+D96000-D96FFF (base 16) Thermo Fisher Scientific Inc.
+ Thermo Fisher Scientific Inc.
+ Shanghai Shanghai 201206
+ CN
+
+70-B3-D5 (hex) Autonomic Controls, Inc.
+BC7000-BC7FFF (base 16) Autonomic Controls, Inc.
+ 28 Kaysal Ct
+ ARMONK NY 10504
+ US
+
+70-B3-D5 (hex) Yokogawa Denshikiki Co.,Ltd
+7F0000-7F0FFF (base 16) Yokogawa Denshikiki Co.,Ltd
+ Minami Shinjuku Hoshino Bldg. 5-23-13 Sendagaya
+ Shibuya-ku Tokyo 151-0051
+ JP
+
+70-B3-D5 (hex) IK MULTIMEDIA PRODUCTION SRL
+2FB000-2FBFFF (base 16) IK MULTIMEDIA PRODUCTION SRL
+ Via dell'Industria 46
+ Modena Italy 41122
+ IT
70-B3-D5 (hex) DISMUNTEL SAL
92C000-92CFFF (base 16) DISMUNTEL SAL
@@ -22790,17 +22868,23 @@ A6A000-A6AFFF (base 16) Privafy, Inc
Oslo Oslo 0504
NO
+70-B3-D5 (hex) RCH Vietnam Limited Liability Company
+6BD000-6BDFFF (base 16) RCH Vietnam Limited Liability Company
+ Workshop F.01B-2, Lot No. F.01B Long Hau
+ Ho Chi Minh City Ho Chi Minh 70000
+ VN
+
70-B3-D5 (hex) Gamber Johnson-LLC
E34000-E34FFF (base 16) Gamber Johnson-LLC
3001 Borham Ave
Stevens Point WI 54481
US
-70-B3-D5 (hex) RCH Vietnam Limited Liability Company
-6BD000-6BDFFF (base 16) RCH Vietnam Limited Liability Company
- Workshop F.01B-2, Lot No. F.01B Long Hau
- Ho Chi Minh City Ho Chi Minh 70000
- VN
+70-B3-D5 (hex) YUYAMA MFG Co.,Ltd
+C2B000-C2BFFF (base 16) YUYAMA MFG Co.,Ltd
+ 3-3-1
+ TOYONAKASHI OSAKA 561-0841
+ JP
70-B3-D5 (hex) YUYAMA MFG Co.,Ltd
1F2000-1F2FFF (base 16) YUYAMA MFG Co.,Ltd
@@ -22814,77 +22898,71 @@ E34000-E34FFF (base 16) Gamber Johnson-LLC
Moscow 105484
RU
-70-B3-D5 (hex) YUYAMA MFG Co.,Ltd
-C2B000-C2BFFF (base 16) YUYAMA MFG Co.,Ltd
- 3-3-1
- TOYONAKASHI OSAKA 561-0841
- JP
-
70-B3-D5 (hex) eSMART Technologies SA
979000-979FFF (base 16) eSMART Technologies SA
Chemin de la Rueyre, 118
Renens VD 1020
CH
-70-B3-D5 (hex) Duplomatic MS spa
-DE1000-DE1FFF (base 16) Duplomatic MS spa
- Via Re Depaolini 24
- Parabiago Milan 20015
- IT
-
70-B3-D5 (hex) Axnes AS
65F000-65FFFF (base 16) Axnes AS
Terje Løvåsvei 1
Grimstad 4879
NO
+70-B3-D5 (hex) Duplomatic MS spa
+DE1000-DE1FFF (base 16) Duplomatic MS spa
+ Via Re Depaolini 24
+ Parabiago Milan 20015
+ IT
+
70-B3-D5 (hex) Nanjing Pingguang Electronic Technology Co., Ltd
541000-541FFF (base 16) Nanjing Pingguang Electronic Technology Co., Ltd
B30/B31 4th Floor, Building#11, Shengtai Road, JiangNing District
NanJing 211100
CN
+70-B3-D5 (hex) PHYZHON Health Inc
+744000-744FFF (base 16) PHYZHON Health Inc
+ 180 Blue Ravine Road, suite A
+ Folsom CA 95630
+ US
+
70-B3-D5 (hex) thingdust AG
3C1000-3C1FFF (base 16) thingdust AG
Moosstrasse 7
Lucerne Lucerne 6003
CH
+70-B3-D5 (hex) Panoramic Power
+53A000-53AFFF (base 16) Panoramic Power
+ 15 Atir Yeda
+ Kfar Saba 4464312
+ IL
+
70-B3-D5 (hex) ALVAT s.r.o.
369000-369FFF (base 16) ALVAT s.r.o.
Chodovska 228/3
Praha 4 14100
CZ
-70-B3-D5 (hex) PHYZHON Health Inc
-744000-744FFF (base 16) PHYZHON Health Inc
- 180 Blue Ravine Road, suite A
- Folsom CA 95630
- US
-
70-B3-D5 (hex) PCB Piezotronics
4CA000-4CAFFF (base 16) PCB Piezotronics
3425 Walden Avenue
Depew NY 14043
US
-70-B3-D5 (hex) Panoramic Power
-53A000-53AFFF (base 16) Panoramic Power
- 15 Atir Yeda
- Kfar Saba 4464312
- IL
-
70-B3-D5 (hex) STEP sarl
481000-481FFF (base 16) STEP sarl
11, avenue Aristide Berges
LANCEY ISERE 38190
FR
-70-B3-D5 (hex) ZPAS S.A.
-2D9000-2D9FFF (base 16) ZPAS S.A.
- Przygorze 209
- Woliborz Lower Silesian (Dolno?l?skie) 57-431
- PL
+70-B3-D5 (hex) Mianjie Technology
+8FC000-8FCFFF (base 16) Mianjie Technology
+ Zhubang2000 Building2 1205
+ Beijing 100000
+ CN
70-B3-D5 (hex) Redstone Sunshine(Beijing)Technology Co.,Ltd.
6C9000-6C9FFF (base 16) Redstone Sunshine(Beijing)Technology Co.,Ltd.
@@ -22892,11 +22970,11 @@ DE1000-DE1FFF (base 16) Duplomatic MS spa
Beijing 100020
CN
-70-B3-D5 (hex) Mianjie Technology
-8FC000-8FCFFF (base 16) Mianjie Technology
- Zhubang2000 Building2 1205
- Beijing 100000
- CN
+70-B3-D5 (hex) ZPAS S.A.
+2D9000-2D9FFF (base 16) ZPAS S.A.
+ Przygorze 209
+ Woliborz Lower Silesian (Dolno?l?skie) 57-431
+ PL
70-B3-D5 (hex) HAI ROBOTICS Co., Ltd.
0B7000-0B7FFF (base 16) HAI ROBOTICS Co., Ltd.
@@ -22922,18 +23000,18 @@ DE1000-DE1FFF (base 16) Duplomatic MS spa
Santa Ana CA 92705
US
-70-B3-D5 (hex) Peter Huber Kaeltemaschinenbau AG
-DC4000-DC4FFF (base 16) Peter Huber Kaeltemaschinenbau AG
- Werner-von-Siemens-Str. 1
- Offenburg Ba-Wue 77656
- DE
-
70-B3-D5 (hex) Beijing Aumiwalker technology CO.,LTD
C7C000-C7CFFF (base 16) Beijing Aumiwalker technology CO.,LTD
Floor 6, Tower 1, No.1 Zhonghe Road Fengtai Science Park Beijing P.R.C.
Beijing Beijing 100071
CN
+70-B3-D5 (hex) Peter Huber Kaeltemaschinenbau AG
+DC4000-DC4FFF (base 16) Peter Huber Kaeltemaschinenbau AG
+ Werner-von-Siemens-Str. 1
+ Offenburg Ba-Wue 77656
+ DE
+
70-B3-D5 (hex) Kazdream Technologies LLP
089000-089FFF (base 16) Kazdream Technologies LLP
10, Turkestan Str.
@@ -22946,6 +23024,12 @@ E5A000-E5AFFF (base 16) Cardinal Scales Manufacturing Co
Webb City MO 64870
US
+70-B3-D5 (hex) Military Research Institute
+2F7000-2F7FFF (base 16) Military Research Institute
+ Veslarska 230
+ Brno 63700
+ CZ
+
70-B3-D5 (hex) Farmpro Ltd
17C000-17CFFF (base 16) Farmpro Ltd
806, 28 Digitalro 30gil, Gurogu
@@ -22958,12 +23042,6 @@ E83000-E83FFF (base 16) Talleres de Escoriaza SA
Irun Gipuzkoa 20305
ES
-70-B3-D5 (hex) Military Research Institute
-2F7000-2F7FFF (base 16) Military Research Institute
- Veslarska 230
- Brno 63700
- CZ
-
70-B3-D5 (hex) Network Innovations
DA7000-DA7FFF (base 16) Network Innovations
4950 West Prospect Road
@@ -22976,6 +23054,18 @@ DA7000-DA7FFF (base 16) Network Innovations
Champagne au Mont d'Or Rhône 69543
FR
+70-B3-D5 (hex) Grossenbacher Systeme AG
+5FE000-5FEFFF (base 16) Grossenbacher Systeme AG
+ Spinnereistrasse 10
+ St. Gallen 9008
+ CH
+
+70-B3-D5 (hex) QUISS GmbH
+AAB000-AABFFF (base 16) QUISS GmbH
+ Lilienthalstraße 5
+ Puchheim 82178
+ DE
+
70-B3-D5 (hex) Shanghai Qinyue Communication Technology Co., Ltd.
B57000-B57FFF (base 16) Shanghai Qinyue Communication Technology Co., Ltd.
Room 101,Building 51,Lane 588,ShuPing Road,Jiading District
@@ -22988,24 +23078,18 @@ B57000-B57FFF (base 16) Shanghai Qinyue Communication Technology Co., Ltd.
Oslo Select One 1405
NO
-70-B3-D5 (hex) QUISS GmbH
-AAB000-AABFFF (base 16) QUISS GmbH
- Lilienthalstraße 5
- Puchheim 82178
- DE
-
-70-B3-D5 (hex) Grossenbacher Systeme AG
-5FE000-5FEFFF (base 16) Grossenbacher Systeme AG
- Spinnereistrasse 10
- St. Gallen 9008
- CH
-
70-B3-D5 (hex) Accolade Technology Inc
87A000-87AFFF (base 16) Accolade Technology Inc
124 Grove Street, Suite 315
FRANKLIN MA 02038
US
+70-B3-D5 (hex) Loehnert Elektronik GmbH
+8A3000-8A3FFF (base 16) Loehnert Elektronik GmbH
+ Oskar-Sembach-Ring 18
+ Lauf a.d.Peg. Bavaria 91207
+ DE
+
70-B3-D5 (hex) Adcole Space
922000-922FFF (base 16) Adcole Space
734 Forest St.,Suite #100
@@ -23024,17 +23108,11 @@ AAB000-AABFFF (base 16) QUISS GmbH
Dinkelsbuehl Bavaria 91550
DE
-70-B3-D5 (hex) Loehnert Elektronik GmbH
-8A3000-8A3FFF (base 16) Loehnert Elektronik GmbH
- Oskar-Sembach-Ring 18
- Lauf a.d.Peg. Bavaria 91207
- DE
-
-70-B3-D5 (hex) plc-tec AG
-095000-095FFF (base 16) plc-tec AG
- Panoramastrasse 5
- Hägglingen 5607
- CH
+70-B3-D5 (hex) Tobi Tribe Inc
+D68000-D68FFF (base 16) Tobi Tribe Inc
+ 13263 MIDDLETON FARM LN,
+ HERNDON, VA 20171
+ US
70-B3-D5 (hex) Edge Power Solutions
612000-612FFF (base 16) Edge Power Solutions
@@ -23042,11 +23120,11 @@ AAB000-AABFFF (base 16) QUISS GmbH
Melbourne FL 32940
US
-70-B3-D5 (hex) Tobi Tribe Inc
-D68000-D68FFF (base 16) Tobi Tribe Inc
- 13263 MIDDLETON FARM LN,
- HERNDON, VA 20171
- US
+70-B3-D5 (hex) Eurotempest AB
+E37000-E37FFF (base 16) Eurotempest AB
+ Algolgatan 10
+ Linköping Other 58335
+ SE
70-B3-D5 (hex) Antek Technology
9E5000-9E5FFF (base 16) Antek Technology
@@ -23054,8 +23132,38 @@ D68000-D68FFF (base 16) Tobi Tribe Inc
Taipei 100
TW
-70-B3-D5 (hex) Eurotempest AB
-E37000-E37FFF (base 16) Eurotempest AB
- Algolgatan 10
- Linköping Other 58335
- SE
+70-B3-D5 (hex) plc-tec AG
+095000-095FFF (base 16) plc-tec AG
+ Panoramastrasse 5
+ Hägglingen 5607
+ CH
+
+70-B3-D5 (hex) Weihai Weigao Medical Imaging Technology Co., Ltd
+534000-534FFF (base 16) Weihai Weigao Medical Imaging Technology Co., Ltd
+ No. 566-1, Qishan Road, Lingang Economic and Technological Development Zone
+ Weihai Shandong 264210
+ CN
+
+70-B3-D5 (hex) ARECA EMBEDDED SYSTEMS PVT LTD
+F15000-F15FFF (base 16) ARECA EMBEDDED SYSTEMS PVT LTD
+ Plot No.5B, Survey No.184-185, P-V, Cherlapally
+ HYDERABAD TELANGANA 500051
+ IN
+
+70-B3-D5 (hex) KOREA SPECTRAL PRODUCTS
+F59000-F59FFF (base 16) KOREA SPECTRAL PRODUCTS
+ Room #402, 273, DIGITAL-RO,
+ GURO-GU SEOUL 08381
+ KR
+
+70-B3-D5 (hex) YOUSUNG
+3B4000-3B4FFF (base 16) YOUSUNG
+ 76, Gaetbeol-ro, Yeonsu-gu
+ Incheon 21999
+ KR
+
+70-B3-D5 (hex) LiveCopper Inc.
+9E9000-9E9FFF (base 16) LiveCopper Inc.
+ 600 Greer Rd
+ Palo Alto CA 94303
+ US
diff --git a/man/coredump.conf.xml b/man/coredump.conf.xml
index 81cdc33898..46da7741c9 100644
--- a/man/coredump.conf.xml
+++ b/man/coredump.conf.xml
@@ -49,7 +49,7 @@
<title>Options</title>
<para>All options are configured in the
- <literal>[Coredump]</literal> section:</para>
+ [Coredump] section:</para>
<variablelist class='config-directives'>
diff --git a/man/coredumpctl.xml b/man/coredumpctl.xml
index a313611369..150d410c24 100644
--- a/man/coredumpctl.xml
+++ b/man/coredumpctl.xml
@@ -52,8 +52,8 @@
matching specified characteristics. If no command is
specified, this is the implied default.</para>
- <para>The output is designed to be human readable and contains list contains
- a table with the following columns:</para>
+ <para>The output is designed to be human readable and contains a table with the following
+ columns:</para>
<variablelist>
<varlistentry>
<term>TIME</term>
diff --git a/man/crypttab.xml b/man/crypttab.xml
index 4cdc52dcb8..ee54499bfe 100644
--- a/man/crypttab.xml
+++ b/man/crypttab.xml
@@ -255,6 +255,7 @@
<listitem><para>Perform encryption using the same cpu that IO was submitted on. The default is to use
an unbound workqueue so that encryption work is automatically balanced between available CPUs.</para>
+
<para>This requires kernel 4.0 or newer.</para>
</listitem>
</varlistentry>
@@ -263,9 +264,10 @@
<term><option>submit-from-crypt-cpus</option></term>
<listitem><para>Disable offloading writes to a separate thread after encryption. There are some
- situations where offloading write bios from the encryption threads to a single thread degrades
- performance significantly. The default is to offload write bios to the same thread because it benefits
- CFQ to have writes submitted using the same context.</para>
+ situations where offloading write requests from the encryption threads to a dedicated thread degrades
+ performance significantly. The default is to offload write requests to a dedicated thread because it
+ benefits the CFQ scheduler to have writes submitted using the same context.</para>
+
<para>This requires kernel 4.0 or newer.</para>
</listitem>
</varlistentry>
@@ -512,7 +514,8 @@ external /dev/sda3 keyfile:LABEL=keydev keyfile-timeout=10s</programlist
<para>The PKCS#11 logic allows hooking up any compatible security token that is capable of storing RSA
decryption keys. Here's an example how to set up a Yubikey security token for this purpose, using
- <command>ykman</command> from the yubikey-manager project:</para>
+ <citerefentry project='debian'><refentrytitle>ykmap</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ from the yubikey-manager project:</para>
<programlisting><xi:include href="yubikey-crypttab.sh" parse="text" /></programlisting>
diff --git a/man/daemon.xml b/man/daemon.xml
index 52b3883607..072529eeec 100644
--- a/man/daemon.xml
+++ b/man/daemon.xml
@@ -357,7 +357,7 @@
special target unit <filename>sockets.target</filename>. It is
recommended to place a
<varname>WantedBy=sockets.target</varname> directive in the
- <literal>[Install]</literal> section to automatically add such a
+ [Install] section to automatically add such a
dependency on installation of a socket unit. Unless
<varname>DefaultDependencies=no</varname> is set, the necessary
ordering dependencies are implicitly created for all socket
@@ -520,7 +520,7 @@
operating system-independent.</para></listitem>
<listitem><para>Make sure to include an
- <literal>[Install]</literal> section including installation
+ [Install] section including installation
information for the unit file. See
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details. To activate your service on boot, make sure to
diff --git a/man/file-hierarchy.xml b/man/file-hierarchy.xml
index 497cb580c7..d5899dc362 100644
--- a/man/file-hierarchy.xml
+++ b/man/file-hierarchy.xml
@@ -648,7 +648,7 @@
<filename>/usr/share/</filename> hierarchy to the locations
defined by the various relevant specifications.</para>
- <para>During runtime, and for local configuration and state,
+ <para>During runtime, and for local configuration and runtime state,
additional directories are defined:</para>
<table>
diff --git a/man/homectl.xml b/man/homectl.xml
index 3a4c6e5f5b..6a8448f25d 100644
--- a/man/homectl.xml
+++ b/man/homectl.xml
@@ -119,9 +119,9 @@
<term><option>--identity=</option><replaceable>FILE</replaceable></term>
<listitem><para>Read the user's JSON record from the specified file. If passed as
- <literal>-</literal> reads the user record from standard input. The supplied JSON object must follow
- the structure documented on <ulink url="https://systemd.io/USER_RECORDS">JSON User
- Records</ulink>. This option may be used in conjunction with the <command>create</command> and
+ <literal>-</literal> read the user record from standard input. The supplied JSON object must follow
+ the structure documented on <ulink url="https://systemd.io/USER_RECORD">JSON User Records</ulink>.
+ This option may be used in conjunction with the <command>create</command> and
<command>update</command> commands (see below), where it allows configuring the user record in JSON
as-is, instead of setting the individual user record properties (see below).</para></listitem>
</varlistentry>
@@ -247,10 +247,9 @@
different system and the configured UID is taken by another user there, then
<command>systemd-homed</command> may assign the user a different UID on that system. The specified
UID must be outside of the system user range. It is recommended to use the 60001…60513 UID range for
- this purpose. If not specified the UID is automatically picked. When logging in and the home
- directory is found to be owned by a UID not matching the user's assigned one the home directory and
- all files and directories inside it will have their ownership changed automatically before login
- completes.</para>
+ this purpose. If not specified, the UID is automatically picked. If the home directory is found to be
+ owned by a different UID when logging in, the home directory and everything underneath it will have
+ its ownership changed automatically before login completes.</para>
<para>Note that users managed by <command>systemd-homed</command> always have a matching group
associated with the same name as well as a GID matching the UID of the user. Thus, configuring the
@@ -266,19 +265,19 @@
privileges. Note that <command>systemd-homed</command> does not manage any groups besides a group
matching the user in name and numeric UID/GID. Thus any groups listed here must be registered
independently, for example with <citerefentry
- project='man-pages'><refentrytitle>groupadd</refentrytitle><manvolnum>8</manvolnum></citerefentry>. If
- non-existent groups that are listed there are ignored. This option may be used more than once, in
- which case all specified group lists are combined. If the user is currently a member of a group
- which is not listed, the user will be removed from the group.</para></listitem>
+ project='man-pages'><refentrytitle>groupadd</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
+ Any non-existent groups are ignored. This option may be used more than once, in which case all
+ specified group lists are combined. If the user is currently a member of a group which is not listed,
+ the user will be removed from the group.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--skel=</option><replaceable>PATH</replaceable></term>
<listitem><para>Takes a file system path to a directory. Specifies the skeleton directory to
- initialize the home directory with. All files and directories in the specified are copied into any
- newly create home directory. If not specified defaults to
- <filename>/etc/skel/</filename>.</para></listitem>
+ initialize the home directory with. All files and directories in the specified path are copied into
+ any newly create home directory. If not specified defaults to <filename>/etc/skel/</filename>.
+ </para></listitem>
</varlistentry>
<varlistentry>
@@ -313,7 +312,7 @@
<listitem><para>Takes a specifier indicating the preferred language of the user. The
<varname>$LANG</varname> environment variable is initialized from this value on login, and thus a
value suitable for this environment variable is accepted here, for example
- <option>--language=de_DE.UTF8</option></para></listitem>
+ <option>--language=de_DE.UTF8</option>.</para></listitem>
</varlistentry>
<varlistentry>
@@ -331,8 +330,50 @@
security token with exactly one pair of X.509 certificate and private key. A random secret key is
then generated, encrypted with the public key of the X.509 certificate, and stored as part of the
user record. At login time it is decrypted with the PKCS#11 module and then used to unlock the
- account and associated resources. See below for an example how to set up authentication with security
- token.</para></listitem>
+ account and associated resources. See below for an example how to set up authentication with a
+ security token.</para>
+
+ <para>Instead of a valid PKCS#11 URI, the special strings <literal>list</literal> and
+ <literal>auto</literal> may be specified. If <literal>list</literal> is passed, a brief table of
+ suitable, currently plugged in PKCS#11 hardware tokens is shown, along with their URIs. If
+ <literal>auto</literal> is passed, a suitable PKCS#11 hardware token is automatically selected (this
+ operation will fail if there isn't exactly one suitable token discovered). The latter is a useful
+ shortcut for the most common case where a single PKCS#11 hardware token is plugged in.</para>
+
+ <para>Note that many hardware security tokens implement both PKCS#11/PIV and FIDO2 with the
+ <literal>hmac-secret</literal> extension (for example: the YubiKey 5 series), as supported with the
+ <option>--fido2-device=</option> option below. Both mechanisms are similarly powerful, though FIDO2
+ is the more modern technology. PKCS#11/PIV tokens have the benefit of being recognizable before
+ authentication and hence can be used for implying the user identity to use for logging in, which
+ FIDO2 does not allow. PKCS#11/PIV devices generally require initialization (i.e. storing a
+ private/public key pair on them, see example below) before they can be used; FIDO2 security tokens
+ generally do not required that, and work out of the box.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--fido2-device=</option><replaceable>PATH</replaceable></term>
+
+ <listitem><para>Takes a path to a Linux <literal>hidraw</literal> device
+ (e.g. <filename>/dev/hidraw1</filename>), referring to a FIDO2 security token implementing the
+ <literal>hmac-secret</literal> extension, that shall be able to unlock the user account. If used, a
+ random salt value is generated on the host, which is passed to the FIDO2 device, which calculates a
+ HMAC hash of it, keyed by its internal secret key. The result is then used as key for unlocking the
+ user account. The random salt is included in the user record, so that whenever authentication is
+ needed it can be passed again to the FIDO2 token, to retrieve the actual key.</para>
+
+ <para>Instead of a valid path to a FIDO2 <literal>hidraw</literal> device the special strings
+ <literal>list</literal> and <literal>auto</literal> may be specified. If <literal>list</literal> is
+ passed, a brief table of suitable discovered FIDO2 devices is shown. If <literal>auto</literal> is
+ passed, a suitable FIDO2 token is automatically selected, if exactly one is discovered. The latter is
+ a useful shortcut for the most common case where a single FIDO2 hardware token is plugged in.</para>
+
+ <para>Note that FIDO2 devices suitable for this option must implement the
+ <literal>hmac-secret</literal> extension. Most current devices (such as the YubiKey 5 series) do. If
+ the extension is not implemented the device cannot be used for unlocking home directories.</para>
+
+ <para>Note that many hardware security tokens implement both FIDO2 and PKCS#11/PIV (and thus may be
+ used with either <option>--fido2-device=</option> or <option>--pkcs11-token-uri=</option>), for a
+ discussion see above.</para></listitem>
</varlistentry>
<varlistentry>
@@ -397,19 +438,19 @@
<listitem><para>Each of these options takes a time span specification as argument (in the syntax
documented in
<citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>5</manvolnum></citerefentry>) and
- configure various aspects of the user's password expiration policy. Specifically,
+ configures various aspects of the user's password expiration policy. Specifically,
<option>--password-change-min=</option> configures how much time has to pass after changing the
password of the user until the password may be changed again. If the user tries to change their
password before this time passes the attempt is refused. <option>--password-change-max=</option>
- configures how much time has to pass after the the password is changed until the password expires and
- needs to be changed again. After this time passes any attempts to log in may only proceed after the
- password is changed. <option>--password-change-warn=</option> specifies how much earlier than then
- the time configured with <option>--password-change-max=</option> the user is warned at login to
- change their password as it will expire soon. Finally <option>--password-change-inactive=</option>
- configures the time which has to pass after the password as expired until the user is not permitted
- to log in or change the password anymore. Note that these options only apply to password
- authentication, and do not apply to other forms of authentication, for example PKCS#11-based security
- token authentication.</para></listitem>
+ configures how soon after it has been changed the password expires and needs to be changed again.
+ After this time passes logging in may only proceed after the password is changed.
+ <option>--password-change-warn=</option> specifies how much earlier than then the time configured
+ with <option>--password-change-max=</option> the user is warned at login to change their password as
+ it will expire soon. Finally <option>--password-change-inactive=</option> configures the time which
+ has to pass after the password as expired until the user is not permitted to log in or change the
+ password anymore. Note that these options only apply to password authentication, and do not apply to
+ other forms of authentication, for example PKCS#11-based security token
+ authentication.</para></listitem>
</varlistentry>
<varlistentry>
@@ -463,10 +504,10 @@
<term><option>--tasks-max=</option><replaceable>TASKS</replaceable></term>
<listitem><para>Takes a non-zero unsigned integer as argument. Configures the maximum numer of tasks
- (i.e. processes and threads) the user may have at any given time. This limit applies to all tasks
- forked off the user's sessions, even if they change user identity via <citerefentry
- project='man-pages'><refentrytitle>su</refentrytitle><manvolnum>1</manvolnum></citerefentry> or a
- similar tool. Use <option>--rlimit=LIMIT_NPROC=</option> to place a limit on the tasks actually
+ (i.e. threads, where each process is at least one thread) the user may have at any given time. This
+ limit applies to all tasks forked off the user's sessions, even if they change user identity via
+ <citerefentry project='man-pages'><refentrytitle>su</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ or a similar tool. Use <option>--rlimit=LIMIT_NPROC=</option> to place a limit on the tasks actually
running under the UID of the user, thus excluding any child processes that might have changed user
identity. This controls the <varname>TasksMax=</varname> setting of the per-user systemd slice unit
<filename>user-$UID.slice</filename>. See
@@ -491,7 +532,7 @@
<term><option>--cpu-weight=</option><replaceable>WEIGHT</replaceable></term>
<term><option>--io-weight=</option><replaceable>WEIGHT</replaceable></term>
- <listitem><para>Set a CPU and IO scheduling weights of the processes of the user, including those of
+ <listitem><para>Set CPU and IO scheduling weights of the processes of the user, including those of
processes forked off by the user that changed user credentials. Takes a numeric value in the range
1…10000. This controls the <varname>CPUWeight=</varname> and <varname>IOWeight=</varname> settings of
the per-user systemd slice unit <filename>user-$UID.slice</filename>. See
@@ -653,8 +694,8 @@
<para>Activation of a home directory involves various operations that depend on the selected storage
mechanism. If the LUKS2 mechanism is used, this generally involves: inquiring the user for a
password, setting up a loopback device, validating and activating the LUKS2 volume, checking the file
- system, mounting the file system, and potentiatlly changing the ownership of all included files to
- the correct UID/GID.</para></listitem>
+ system, mounting the file system, and potentially changing the ownership of all included files to the
+ correct UID/GID.</para></listitem>
</varlistentry>
<varlistentry>
@@ -810,7 +851,7 @@
</example>
<example>
- <title>Set up authentication with a YubiKey security token:</title>
+ <title>Set up authentication with a YubiKey security token using PKCS#11/PIV:</title>
<programlisting># Clear the Yubikey from any old keys (careful!)
ykman piv reset
@@ -821,16 +862,18 @@ ykman piv generate-key -a RSA2048 9d pubkey.pem
# Create a self-signed certificate from this public key, and store it on the device.
ykman piv generate-certificate --subject "Knobelei" 9d pubkey.pem
-# We don't need the publibc key on disk anymore
+# We don't need the public key on disk anymore
rm pubkey.pem
-# Check if the newly create key on the Yubikey shows up as token in PKCS#11. Have a look at the output, and
-# copy the resulting token URI to the clipboard.
-p11tool --list-tokens
+# Allow the security token to unlock the account of user 'lafcadio'.
+homectl update lafcadio --pkcs11-token-uri=auto</programlisting>
+ </example>
+
+ <example>
+ <title>Set up authentication with a FIDO2 security token:</title>
-# Allow the security token referenced by the determined PKCS#11 URI to unlock the account of user
-# 'lafcadio'. (Replace the '…' by the URI from the clipboard.)
-homectl update lafcadio --pkcs11-token-uri=…</programlisting>
+ <programlisting># Allow a FIDO2 security token to unlock the account of user 'nihilbaxter'.
+homectl update nihilbaxter --fido2-device=auto</programlisting>
</example>
</refsect1>
diff --git a/man/homed.conf.xml b/man/homed.conf.xml
index 9e321940b7..2c5f3355d3 100644
--- a/man/homed.conf.xml
+++ b/man/homed.conf.xml
@@ -42,7 +42,7 @@
<refsect1>
<title>Options</title>
- <para>The following options are available in the <literal>[Home]</literal> section:</para>
+ <para>The following options are available in the [Home] section:</para>
<variablelist class='home-directives'>
diff --git a/man/journal-remote.conf.xml b/man/journal-remote.conf.xml
index ab3dfd0111..3db12dd0ce 100644
--- a/man/journal-remote.conf.xml
+++ b/man/journal-remote.conf.xml
@@ -49,7 +49,7 @@
<title>Options</title>
<para>All options are configured in the
- <literal>[Remote]</literal> section:</para>
+ [Remote] section:</para>
<variablelist class='config-directives'>
<varlistentry>
diff --git a/man/journal-upload.conf.xml b/man/journal-upload.conf.xml
index f2721a75e7..6cb1aa474d 100644
--- a/man/journal-upload.conf.xml
+++ b/man/journal-upload.conf.xml
@@ -43,7 +43,7 @@
<refsect1>
<title>Options</title>
- <para>All options are configured in the <literal>[Upload]</literal> section:</para>
+ <para>All options are configured in the [Upload] section:</para>
<variablelist class='config-directives'>
<varlistentry>
diff --git a/man/journalctl.xml b/man/journalctl.xml
index 5c32ce8b9b..ea60196e86 100644
--- a/man/journalctl.xml
+++ b/man/journalctl.xml
@@ -555,7 +555,7 @@
is also added for <literal>_SYSTEMD_SLICE=<replaceable>UNIT</replaceable></literal>,
such that if the provided <replaceable>UNIT</replaceable> is a
<citerefentry><refentrytitle>systemd.slice</refentrytitle><manvolnum>5</manvolnum></citerefentry>
- unit, all logs of the children of the slice will be logged.
+ unit, all logs of children of the slice will be shown.
</para>
<para>This parameter can be specified multiple times.</para>
@@ -574,7 +574,7 @@
is also added for <literal>_SYSTEMD_USER_SLICE=<replaceable>UNIT</replaceable></literal>,
such that if the provided <replaceable>UNIT</replaceable> is a
<citerefentry><refentrytitle>systemd.slice</refentrytitle><manvolnum>5</manvolnum></citerefentry>
- unit, all logs of the children of the unit will be logged.</para>
+ unit, all logs of children of the unit will be shown.</para>
<para>This parameter can be specified multiple times.</para>
</listitem>
@@ -761,8 +761,8 @@
underneath the specified directory instead of the root
directory (e.g. <option>--update-catalog</option> will create
<filename><replaceable>ROOT</replaceable>/var/lib/systemd/catalog/database</filename>,
- and journal files under <filename><replaceable>ROOT</replaceable>/run/journal</filename>
- or <filename><replaceable>ROOT</replaceable>/var/log/journal</filename> will be displayed).
+ and journal files under <filename><replaceable>ROOT</replaceable>/run/journal/</filename>
+ or <filename><replaceable>ROOT</replaceable>/var/log/journal/</filename> will be displayed).
</para></listitem>
</varlistentry>
@@ -929,10 +929,10 @@
<filename>/run/log/journal/</filename> into <filename>/var/log/journal/</filename>, if persistent
storage is enabled. This call does not return until the operation is complete. Note that this call is
idempotent: the data is only flushed from <filename>/run/log/journal/</filename> into
- <filename>/var/log/journal</filename> once during system runtime (but see
+ <filename>/var/log/journal/</filename> once during system runtime (but see
<option>--relinquish-var</option> below), and this command exits cleanly without executing any
operation if this has already happened. This command effectively guarantees that all data is flushed
- to <filename>/var/log/journal</filename> at the time it returns.</para></listitem>
+ to <filename>/var/log/journal/</filename> at the time it returns.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/man/journald.conf.xml b/man/journald.conf.xml
index 957ec36a68..5c9419b012 100644
--- a/man/journald.conf.xml
+++ b/man/journald.conf.xml
@@ -53,7 +53,7 @@
<title>Options</title>
<para>All options are configured in the
- <literal>[Journal]</literal> section:</para>
+ [Journal] section:</para>
<variablelist class='config-directives'>
diff --git a/man/kernel-install.xml b/man/kernel-install.xml
index 3df80751dd..273270f550 100644
--- a/man/kernel-install.xml
+++ b/man/kernel-install.xml
@@ -36,7 +36,7 @@
<title>Description</title>
<para><command>kernel-install</command> is used to install and remove kernel and initramfs images to and
from the boot loader partition, referred to as <varname>$BOOT</varname> here. It will usually be one of
- <filename>/boot</filename>, <filename>/efi</filename>, or <filename>/boot/efi</filename>, see below.
+ <filename>/boot/</filename>, <filename>/efi/</filename>, or <filename>/boot/efi/</filename>, see below.
</para>
<para><command>kernel-install</command> will execute the files
@@ -137,7 +137,7 @@
<para>The partition where the kernels and <ulink url="https://systemd.io/BOOT_LOADER_SPECIFICATION">Boot
Loader Specification</ulink> snippets are located is called <varname>$BOOT</varname>.
<command>kernel-install</command> determines the location of this partition by checking
- <filename>/efi/</filename>, <filename>/boot/</filename>, and <filename>/boot/efi</filename>
+ <filename>/efi/</filename>, <filename>/boot/</filename>, and <filename>/boot/efi/</filename>
in turn. The first location where <filename>$BOOT/loader/entries/</filename> or
<filename>$BOOT/$MACHINE_ID/</filename> exists is used.</para>
</refsect1>
diff --git a/man/logind.conf.xml b/man/logind.conf.xml
index b00daf366d..22f21355b6 100644
--- a/man/logind.conf.xml
+++ b/man/logind.conf.xml
@@ -46,7 +46,7 @@
<title>Options</title>
<para>All options are configured in the
- <literal>[Login]</literal> section:</para>
+ [Login] section:</para>
<variablelist class='config-directives'>
@@ -277,7 +277,7 @@
<varlistentry>
<term><varname>HoldoffTimeoutSec=</varname></term>
- <listitem><para>Specifies the timeout after system startup or
+ <listitem><para>Specifies a period of time after system startup or
system resume in which systemd will hold off on reacting to
lid events. This is required for the system to properly
detect any hotplugged devices so systemd can ignore lid events
diff --git a/man/machine-id.xml b/man/machine-id.xml
index ebee065a61..bd55366ac8 100644
--- a/man/machine-id.xml
+++ b/man/machine-id.xml
@@ -39,7 +39,7 @@
<para>The machine ID may be set, for example when network booting, with the
<varname>systemd.machine_id=</varname> kernel command line parameter or by passing the
- option <option>--machine-id=</option> to systemd. An ID is specified in this manner
+ option <option>--machine-id=</option> to systemd. An ID specified in this manner
has higher priority and will be used instead of the ID stored in
<filename>/etc/machine-id</filename>.</para>
diff --git a/man/machinectl.xml b/man/machinectl.xml
index e903eca721..37e51f90cf 100644
--- a/man/machinectl.xml
+++ b/man/machinectl.xml
@@ -320,7 +320,7 @@
<listitem><para>Copies files or directories from a container
into the host system. Takes a container name, followed by the
- source path in the container the destination path on the host.
+ source path in the container and the destination path on the host.
If the destination path is omitted, the same as the source path
is used.</para>
diff --git a/man/networkd.conf.xml b/man/networkd.conf.xml
index 6c60f6cf6b..e8e41ebe92 100644
--- a/man/networkd.conf.xml
+++ b/man/networkd.conf.xml
@@ -45,7 +45,7 @@
<refsect1>
<title>[Network] Section Options</title>
- <para>The following options are available in the <literal>[Network]</literal> section:</para>
+ <para>The following options are available in the [Network] section:</para>
<variablelist class='network-directives'>
<varlistentry>
diff --git a/man/nss-myhostname.xml b/man/nss-myhostname.xml
index e23b24483e..8bb21f2621 100644
--- a/man/nss-myhostname.xml
+++ b/man/nss-myhostname.xml
@@ -18,8 +18,7 @@
<refnamediv>
<refname>nss-myhostname</refname>
<refname>libnss_myhostname.so.2</refname>
- <refpurpose>Provide hostname resolution for the locally
- configured system hostname.</refpurpose>
+ <refpurpose>Hostname resolution for the locally configured system hostname</refpurpose>
</refnamediv>
<refsynopsisdiv>
diff --git a/man/nss-mymachines.xml b/man/nss-mymachines.xml
index 1ff88aba2d..6e48835550 100644
--- a/man/nss-mymachines.xml
+++ b/man/nss-mymachines.xml
@@ -18,8 +18,7 @@
<refnamediv>
<refname>nss-mymachines</refname>
<refname>libnss_mymachines.so.2</refname>
- <refpurpose>Provide hostname resolution for local
- container instances.</refpurpose>
+ <refpurpose>Hostname resolution for local container instances</refpurpose>
</refnamediv>
<refsynopsisdiv>
diff --git a/man/nss-resolve.xml b/man/nss-resolve.xml
index 8bc75b1316..332cf0b06d 100644
--- a/man/nss-resolve.xml
+++ b/man/nss-resolve.xml
@@ -18,7 +18,7 @@
<refnamediv>
<refname>nss-resolve</refname>
<refname>libnss_resolve.so.2</refname>
- <refpurpose>Provide hostname resolution via <filename>systemd-resolved.service</filename></refpurpose>
+ <refpurpose>Hostname resolution via <filename>systemd-resolved.service</filename></refpurpose>
</refnamediv>
<refsynopsisdiv>
diff --git a/man/nss-systemd.xml b/man/nss-systemd.xml
index ac22452bc3..26730f0fe9 100644
--- a/man/nss-systemd.xml
+++ b/man/nss-systemd.xml
@@ -18,7 +18,7 @@
<refnamediv>
<refname>nss-systemd</refname>
<refname>libnss_systemd.so.2</refname>
- <refpurpose>Provide UNIX user and group name resolution for user/group lookup via Varlink</refpurpose>
+ <refpurpose>UNIX user and group name resolution for user/group lookup via Varlink</refpurpose>
</refnamediv>
<refsynopsisdiv>
diff --git a/man/org.freedesktop.LogControl1.xml b/man/org.freedesktop.LogControl1.xml
index 385e290312..d8ce392c87 100644
--- a/man/org.freedesktop.LogControl1.xml
+++ b/man/org.freedesktop.LogControl1.xml
@@ -83,7 +83,7 @@ node /org/freedesktop/LogControl1 {
<para><varname>LogTarget</varname> describes the log target (mechanism). It should be one of
<literal>console</literal> (log to the console or standard output),
<literal>kmsg</literal> (log to the kernel ring buffer),
- <literal>journal</literal> (log the the journal natively, see
+ <literal>journal</literal> (log to the journal natively, see
<citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>),
<literal>syslog</literal> (log using the
<citerefentry project='man-pages'><refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum></citerefentry> call).
diff --git a/man/org.freedesktop.home1.xml b/man/org.freedesktop.home1.xml
index f65ef33f21..5cf1159703 100644
--- a/man/org.freedesktop.home1.xml
+++ b/man/org.freedesktop.home1.xml
@@ -24,7 +24,7 @@
<title>Introduction</title>
<para><citerefentry><refentrytitle>systemd-homed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
- is a system service which may be used to to create, remove, change or inspect home areas. This page
+ is a system service which may be used to create, remove, change or inspect home areas. This page
describes the D-Bus interface.
</para>
</refsect1>
@@ -227,7 +227,7 @@ node /org/freedesktop/home1 {
interface.</para>
<para><function>CreateHome()</function> registers and creates a new home directory. This takes a fully
- specified JSON user record as argument (including the <literal>secret</literal> section. This registers
+ specified JSON user record as argument (including the <literal>secret</literal> section). This registers
the user record locally and creates a home directory matching it, depending on the settings specified
in the record in combination with local configuration.</para>
diff --git a/man/org.freedesktop.hostname1.xml b/man/org.freedesktop.hostname1.xml
index d17d9a5521..6b2341e48c 100644
--- a/man/org.freedesktop.hostname1.xml
+++ b/man/org.freedesktop.hostname1.xml
@@ -239,7 +239,7 @@ node /org/freedesktop/hostname1 {
<para><varname>KernelName</varname>, <varname>KernelRelease</varname>, and
<varname>KernelVersion</varname> expose the kernel name (e.g. <literal>Linux</literal>), release
- (e.g. <literal>5.0.0-11</literal>, and version (i.e. the build number, e.g. <literal>#11</literal>) as
+ (e.g. <literal>5.0.0-11</literal>), and version (i.e. the build number, e.g. <literal>#11</literal>) as
reported by
<citerefentry project="man-pages"><refentrytitle>uname</refentrytitle><manvolnum>2</manvolnum></citerefentry>.
<varname>OperatingSystemPrettyName</varname>, <varname>OperatingSystemCPEName</varname>, and
diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml
index 8e3c7611a8..6b16ae16da 100644
--- a/man/org.freedesktop.systemd1.xml
+++ b/man/org.freedesktop.systemd1.xml
@@ -1472,12 +1472,12 @@ node /org/freedesktop/systemd1 {
<para>Read access is generally granted to all clients. Additionally, for unprivileged clients, some
operations are allowed through the polkit privilege system. Operations which modify unit state
(<function>StartUnit()</function>, <function>StopUnit()</function>, <function>KillUnit()</function>,
- <function>RestartUnit()</function> and similar, <function>SetProperty</function>) require
+ <function>RestartUnit()</function> and similar, <function>SetProperty()</function>) require
<interfacename>org.freedesktop.systemd1.manage-units</interfacename>. Operations which modify unit file
enablement state (<function>EnableUnitFiles()</function>, <function>DisableUnitFiles()</function>,
<function>ReenableUnitFiles()</function>, <function>LinkUnitFiles()</function>,
<function>PresetUnitFiles</function>, <function>MaskUnitFiles</function>, and similar) require
- <interfacename>org.freedesktop.systemd1.manage-unit-files</interfacename>). Operations which modify the
+ <interfacename>org.freedesktop.systemd1.manage-unit-files</interfacename>. Operations which modify the
exported environment (<function>SetEnvironment()</function>, <function>UnsetEnvironment()</function>,
<function>UnsetAndSetEnvironment()</function>) require
<interfacename>org.freedesktop.systemd1.set-environment</interfacename>. <function>Reload()</function>
diff --git a/man/pam_systemd.xml b/man/pam_systemd.xml
index cf9ba71adc..609743be6b 100644
--- a/man/pam_systemd.xml
+++ b/man/pam_systemd.xml
@@ -153,7 +153,7 @@
hence be used to uniquely label files or other resources of this session. Combine this ID with the boot
identifier, as returned by
<citerefentry><refentrytitle>sd_id128_get_boot</refentrytitle><manvolnum>3</manvolnum></citerefentry>, for a
- globally unique identifier for the current session.</para></listitem>
+ globally unique identifier.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/man/portablectl.xml b/man/portablectl.xml
index f2d8da40c4..962429683d 100644
--- a/man/portablectl.xml
+++ b/man/portablectl.xml
@@ -118,7 +118,7 @@
<para>By default all unit files whose names start with a prefix generated from the image's file name are copied
out. Specifically, the prefix is determined from the image file name with any suffix such as
- <filename>.raw</filename> removed, truncated at the first occurrence of and underscore character
+ <filename>.raw</filename> removed, truncated at the first occurrence of an underscore character
(<literal>_</literal>), if there is one. The underscore logic is supposed to be used to versioning so that the
an image file <filename>foobar_47.11.raw</filename> will result in a unit file matching prefix of
<filename>foobar</filename>. This prefix is then compared with all unit files names contained in the image in
@@ -403,7 +403,7 @@
</tgroup>
</table>
- <para>For details on this profiles, and their effects please have a look at their precise definitions,
+ <para>For details on these profiles and their effects see their precise definitions,
e.g. <filename>/usr/lib/systemd/portable/profile/default/service.conf</filename> and similar.</para>
</refsect1>
diff --git a/man/pstore.conf.xml b/man/pstore.conf.xml
index 2b9c8b1a71..501171e78a 100644
--- a/man/pstore.conf.xml
+++ b/man/pstore.conf.xml
@@ -44,7 +44,7 @@
<title>Options</title>
<para>All options are configured in the
- <literal>[PStore]</literal> section:</para>
+ [PStore] section:</para>
<variablelist class='config-directives'>
@@ -82,7 +82,7 @@
<refsect1>
<title>See Also</title>
<para>
- <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>systemd-journald.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
</para>
</refsect1>
diff --git a/man/repart.d.xml b/man/repart.d.xml
index ac0daaea6f..1b104e76d0 100644
--- a/man/repart.d.xml
+++ b/man/repart.d.xml
@@ -140,7 +140,7 @@
<row>
<entry><constant>root-secondary</constant></entry>
- <entry>Root file system partition of the secondary architecture of the local architecture; usually the matching 32bit architecture for the local 64bit architecture)</entry>
+ <entry>Root file system partition of the secondary architecture of the local architecture (usually the matching 32bit architecture for the local 64bit architecture)</entry>
</row>
<row>
diff --git a/man/resolved.conf.xml b/man/resolved.conf.xml
index a39da086bf..0e7a9f4bc6 100644
--- a/man/resolved.conf.xml
+++ b/man/resolved.conf.xml
@@ -41,7 +41,7 @@
<refsect1>
<title>Options</title>
- <para>The following options are available in the <literal>[Resolve]</literal> section:</para>
+ <para>The following options are available in the [Resolve] section:</para>
<variablelist class='network-directives'>
diff --git a/man/sd_bus_creds_get_pid.xml b/man/sd_bus_creds_get_pid.xml
index a7690d5817..a3e8079c51 100644
--- a/man/sd_bus_creds_get_pid.xml
+++ b/man/sd_bus_creds_get_pid.xml
@@ -332,7 +332,7 @@
information, in particular it should not be used for security-relevant decisions. That's because the
executable might have been replaced or removed by the time the value can be processed. Moreover, the
kernel exports this information in an ambiguous way (i.e. a deleted executable cannot be safely
- distinguished from one whose name suffix is <literal> (deleted)</literal>.</para>
+ distinguished from one whose name suffix is <literal> (deleted)</literal>).</para>
<para><function>sd_bus_creds_get_cmdline()</function> will
retrieve an array of command line arguments (as stored in
diff --git a/man/sd_bus_enqueue_for_read.xml b/man/sd_bus_enqueue_for_read.xml
index 3318a3031b..f948b5914f 100644
--- a/man/sd_bus_enqueue_for_read.xml
+++ b/man/sd_bus_enqueue_for_read.xml
@@ -19,7 +19,7 @@
<refnamediv>
<refname>sd_bus_enqueue_for_read</refname>
- <refpurpose>Re-enqueue a bus message on a bus connection, for reading.</refpurpose>
+ <refpurpose>Re-enqueue a bus message on a bus connection, for reading</refpurpose>
</refnamediv>
<refsynopsisdiv>
diff --git a/man/sd_bus_get_fd.xml b/man/sd_bus_get_fd.xml
index 69261af93e..466606118b 100644
--- a/man/sd_bus_get_fd.xml
+++ b/man/sd_bus_get_fd.xml
@@ -79,7 +79,7 @@
<constant>POLLIN</constant>, <constant>POLLOUT</constant>, … events, or negative on error.
</para>
- <para><function>sd_bus_get_timeout()</function> returns the timeout in µs to pass to to
+ <para><function>sd_bus_get_timeout()</function> returns the timeout in µs to pass to
<function>poll()</function> or a similar call when waiting for events on the specified bus
connection. The returned timeout may be zero, in which case a subsequent I/O polling call
should be invoked in non-blocking mode. The returned timeout may be
diff --git a/man/sd_bus_is_open.xml b/man/sd_bus_is_open.xml
index d993142cb5..4a21189c1d 100644
--- a/man/sd_bus_is_open.xml
+++ b/man/sd_bus_is_open.xml
@@ -20,7 +20,7 @@
<refname>sd_bus_is_open</refname>
<refname>sd_bus_is_ready</refname>
- <refpurpose>Check whether the a bus connection is open or ready.</refpurpose>
+ <refpurpose>Check whether the bus connection is open or ready</refpurpose>
</refnamediv>
<refsynopsisdiv>
diff --git a/man/sd_bus_message_new_method_error.xml b/man/sd_bus_message_new_method_error.xml
index aa29007c27..39bb24c3a5 100644
--- a/man/sd_bus_message_new_method_error.xml
+++ b/man/sd_bus_message_new_method_error.xml
@@ -22,7 +22,7 @@
<refname>sd_bus_message_new_method_errno</refname>
<refname>sd_bus_message_new_method_errnof</refname>
- <refpurpose>Create a an error reply for a method call</refpurpose>
+ <refpurpose>Create an error reply for a method call</refpurpose>
</refnamediv>
<refsynopsisdiv>
diff --git a/man/sd_bus_set_connected_signal.xml b/man/sd_bus_set_connected_signal.xml
index edb0df205a..b025112b63 100644
--- a/man/sd_bus_set_connected_signal.xml
+++ b/man/sd_bus_set_connected_signal.xml
@@ -20,7 +20,7 @@
<refname>sd_bus_set_connected_signal</refname>
<refname>sd_bus_get_connected_signal</refname>
- <refpurpose>Control emmission of local connection establishment signal on bus connections</refpurpose>
+ <refpurpose>Control emission of local connection establishment signal on bus connections</refpurpose>
</refnamediv>
<refsynopsisdiv>
diff --git a/man/sd_bus_slot_set_destroy_callback.xml b/man/sd_bus_slot_set_destroy_callback.xml
index c6fe72e37b..c2a0876e21 100644
--- a/man/sd_bus_slot_set_destroy_callback.xml
+++ b/man/sd_bus_slot_set_destroy_callback.xml
@@ -23,7 +23,7 @@
<refname>sd_bus_track_get_destroy_callback</refname>
<refname>sd_bus_destroy_t</refname>
- <refpurpose>Define the callback function for resource cleanup.</refpurpose>
+ <refpurpose>Define the callback function for resource cleanup</refpurpose>
</refnamediv>
<refsynopsisdiv>
diff --git a/man/sd_bus_slot_set_floating.xml b/man/sd_bus_slot_set_floating.xml
index f63907aa40..ecfc079514 100644
--- a/man/sd_bus_slot_set_floating.xml
+++ b/man/sd_bus_slot_set_floating.xml
@@ -19,7 +19,7 @@
<refname>sd_bus_slot_set_floating</refname>
<refname>sd_bus_slot_get_floating</refname>
- <refpurpose>Control whether a bus slot object is "floating".</refpurpose>
+ <refpurpose>Control whether a bus slot object is "floating"</refpurpose>
</refnamediv>
<refsynopsisdiv>
diff --git a/man/sd_event_new.xml b/man/sd_event_new.xml
index 3db39c9d06..0e572c40ee 100644
--- a/man/sd_event_new.xml
+++ b/man/sd_event_new.xml
@@ -131,7 +131,7 @@
automatically as the code block is left:</para>
<programlisting>{
- __attribute__((cleanup(sd_event_unrefp)) sd_event *event = NULL;
+ __attribute__((cleanup(sd_event_unrefp))) sd_event *event = NULL;
int r;
r = sd_event_default(&amp;event);
diff --git a/man/sd_event_source_set_destroy_callback.xml b/man/sd_event_source_set_destroy_callback.xml
index 2ffca9ec36..3df926b863 100644
--- a/man/sd_event_source_set_destroy_callback.xml
+++ b/man/sd_event_source_set_destroy_callback.xml
@@ -21,7 +21,7 @@
<refname>sd_event_source_get_destroy_callback</refname>
<refname>sd_event_destroy_t</refname>
- <refpurpose>Define the callback function for resource cleanup.</refpurpose>
+ <refpurpose>Define the callback function for resource cleanup</refpurpose>
</refnamediv>
<refsynopsisdiv>
diff --git a/man/sd_hwdb_get.xml b/man/sd_hwdb_get.xml
index 1372f4d80c..dbaaf6292c 100644
--- a/man/sd_hwdb_get.xml
+++ b/man/sd_hwdb_get.xml
@@ -64,7 +64,7 @@
<para><function>sd_hwdb_get()</function> queries the <parameter>hwdb</parameter> object created earlier
with <citerefentry><refentrytitle>sd_hwdb_new</refentrytitle><manvolnum>3</manvolnum></citerefentry> for
entries matching the specified string <parameter>modalias</parameter>, and returns the value
- corresponding to the the key <parameter>key</parameter>. The value is returned as a
+ corresponding to the key <parameter>key</parameter>. The value is returned as a
<constant>NUL</constant>-terminated string in <parameter>value</parameter>. It must not be modified by
the caller and is valid as long as a reference to <parameter>hwdb</parameter> is kept. When multiple
patterns in the database match <parameter>modalias</parameter>, the one with the highest priority is
diff --git a/man/sd_journal_has_runtime_files.xml b/man/sd_journal_has_runtime_files.xml
index 7e6e7d4b9d..02fdc12473 100644
--- a/man/sd_journal_has_runtime_files.xml
+++ b/man/sd_journal_has_runtime_files.xml
@@ -21,7 +21,7 @@
<refnamediv>
<refname>sd_journal_has_runtime_files</refname>
<refname>sd_journal_has_persistent_files</refname>
- <refpurpose>Query availability of runtime or persistent journal files.</refpurpose>
+ <refpurpose>Query availability of runtime or persistent journal files</refpurpose>
</refnamediv>
<refsynopsisdiv>
diff --git a/man/sd_login_monitor_new.xml b/man/sd_login_monitor_new.xml
index be1c843ee0..d1c83e2d20 100644
--- a/man/sd_login_monitor_new.xml
+++ b/man/sd_login_monitor_new.xml
@@ -112,7 +112,7 @@
code block is left:</para>
<programlisting>{
- __attribute__((cleanup(sd_login_monitor_unrefp)) sd_login_monitor *m = NULL;
+ __attribute__((cleanup(sd_login_monitor_unrefp))) sd_login_monitor *m = NULL;
int r;
r = sd_login_monitor_default(&amp;m);
diff --git a/man/sd_machine_get_class.xml b/man/sd_machine_get_class.xml
index db6cf0dbc0..cd259c863f 100644
--- a/man/sd_machine_get_class.xml
+++ b/man/sd_machine_get_class.xml
@@ -19,7 +19,7 @@
<refname>sd_machine_get_class</refname>
<refname>sd_machine_get_ifindices</refname>
<refpurpose>Determine the class and network interface indices of a
- locally running virtual machine or container.</refpurpose>
+ locally running virtual machine or container</refpurpose>
</refnamediv>
<refsynopsisdiv>
diff --git a/man/sd_pid_get_owner_uid.xml b/man/sd_pid_get_owner_uid.xml
index e9d7a8eb69..9c16d5bc9c 100644
--- a/man/sd_pid_get_owner_uid.xml
+++ b/man/sd_pid_get_owner_uid.xml
@@ -35,7 +35,7 @@
<refname>sd_peer_get_cgroup</refname>
<refpurpose>Determine the owner uid of the user unit or session,
or the session, user unit, system unit, container/VM or slice that
- a specific PID or socket peer belongs to.</refpurpose>
+ a specific PID or socket peer belongs to</refpurpose>
</refnamediv>
<refsynopsisdiv>
diff --git a/man/standard-conf.xml b/man/standard-conf.xml
index a58c76d85f..ee8cc7bc0a 100644
--- a/man/standard-conf.xml
+++ b/man/standard-conf.xml
@@ -13,7 +13,7 @@
<para>Configuration files are read from directories in <filename>/etc/</filename>,
<filename>/run/</filename>, <filename>/usr/local/lib/</filename>, and <filename>/usr/lib/</filename>, in
- order of precedence, as listed in the SYNOPSIS section above. Files must have the the
+ order of precedence, as listed in the SYNOPSIS section above. Files must have the
<literal>.conf</literal> extension. Files in <filename>/etc/</filename> override files with the same name
in <filename>/run/</filename>, <filename>/usr/local/lib/</filename>, and
<filename>/usr/lib/</filename>. Files in <filename>/run/</filename> override files with the same name
diff --git a/man/sysctl.d.xml b/man/sysctl.d.xml
index d26f82475b..70504510f9 100644
--- a/man/sysctl.d.xml
+++ b/man/sysctl.d.xml
@@ -70,11 +70,11 @@ key.pattern.overridden.with.glob = custom
followed by <literal>=</literal>, see SYNOPSIS.</para>
<para>Any access permission errors and attempts to write variables not present on the local system are
- logged, but do not cause the service to fail. Debug log level is used, which means that the message will
- not show up at all by default. Moreover, if a variable assignment is prefixed with a single
- <literal>-</literal> character, any failure to set the variable will be logged at debug level, but will
- not cause the service to fail. All other errors when setting variables are logged with higher priority
- and cause the service to return failure at the end (other variables are still processed).</para>
+ logged at debug level and do not cause the service to fail. Moreover, if a variable assignment is
+ prefixed with a single <literal>-</literal> character, failure to set the variable for other reasons will
+ be logged at debug level and will not cause the service to fail. In other cases, errors when setting
+ variables are logged with higher priority and cause the service to return failure at the end (after
+ processing other variables).</para>
<para>The settings configured with <filename>sysctl.d</filename> files will be applied early on boot. The
network interface-specific options will also be applied individually for each network interface as it
diff --git a/man/systemctl.xml b/man/systemctl.xml
index 53342c4b9d..28c2194285 100644
--- a/man/systemctl.xml
+++ b/man/systemctl.xml
@@ -412,7 +412,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
<para>The "Loaded:" line in the output will show <literal>loaded</literal> if the unit has been loaded into
memory. Other possible values for "Loaded:" include: <literal>error</literal> if there was a problem
- loading it, <literal>not-found</literal> if not unit file was found for this unit,
+ loading it, <literal>not-found</literal> if no unit file was found for this unit,
<literal>bad-setting</literal> if an essential unit file setting could not be parsed and
<literal>masked</literal> if the unit file has been masked. Along with showing the path to the unit file,
this line will also show the enablement state. Enabled commands start at boot. See the full table of
@@ -582,7 +582,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
<listitem>
<para>Enable one or more units or unit instances. This will create a set of symlinks, as encoded in the
- <literal>[Install]</literal> sections of the indicated unit files. After the symlinks have been created,
+ [Install] sections of the indicated unit files. After the symlinks have been created,
the system manager configuration is reloaded (in a way equivalent to <command>daemon-reload</command>), in
order to ensure the changes are taken into account immediately. Note that this does
<emphasis>not</emphasis> have the effect of also starting any of the units being enabled. If this is
@@ -605,7 +605,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
<option>--quiet</option>.
</para>
- <para>Note that this operation creates only the symlinks suggested in the <literal>[Install]</literal>
+ <para>Note that this operation creates only the symlinks suggested in the [Install]
section of the unit files. While this command is the recommended way to manipulate the unit configuration
directory, the administrator is free to make additional changes manually by placing or removing symlinks
below this directory. This is particularly useful to create configurations that deviate from the suggested
@@ -645,7 +645,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
<para>This command expects valid unit names only, it does not accept paths to unit files.</para>
<para>In addition to the units specified as arguments, all units are disabled that are listed in the
- <varname>Also=</varname> setting contained in the <literal>[Install]</literal> section of any of the unit
+ <varname>Also=</varname> setting contained in the [Install] section of any of the unit
files being operated on.</para>
<para>This command implicitly reloads the system manager configuration after completing the operation. Note
@@ -668,7 +668,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
<listitem>
<para>Reenable one or more units, as specified on the command line. This is a combination of
<command>disable</command> and <command>enable</command> and is useful to reset the symlinks a unit file is
- enabled with to the defaults configured in its <literal>[Install]</literal> section. This command expects
+ enabled with to the defaults configured in its [Install] section. This command expects
a unit name only, it does not accept paths to unit files.</para>
</listitem>
</varlistentry>
@@ -768,17 +768,17 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
</row>
<row>
<entry><literal>static</literal></entry>
- <entry>The unit file is not enabled, and has no provisions for enabling in the <literal>[Install]</literal> unit file section.</entry>
+ <entry>The unit file is not enabled, and has no provisions for enabling in the [Install] unit file section.</entry>
<entry>0</entry>
</row>
<row>
<entry><literal>indirect</literal></entry>
- <entry>The unit file itself is not enabled, but it has a non-empty <varname>Also=</varname> setting in the <literal>[Install]</literal> unit file section, listing other unit files that might be enabled, or it has an alias under a different name through a symlink that is not specified in <varname>Also=</varname>. For template unit file, an instance different than the one specified in <varname>DefaultInstance=</varname> is enabled.</entry>
+ <entry>The unit file itself is not enabled, but it has a non-empty <varname>Also=</varname> setting in the [Install] unit file section, listing other unit files that might be enabled, or it has an alias under a different name through a symlink that is not specified in <varname>Also=</varname>. For template unit files, an instance different than the one specified in <varname>DefaultInstance=</varname> is enabled.</entry>
<entry>0</entry>
</row>
<row>
<entry><literal>disabled</literal></entry>
- <entry>The unit file is not enabled, but contains an <literal>[Install]</literal> section with installation instructions.</entry>
+ <entry>The unit file is not enabled, but contains an [Install] section with installation instructions.</entry>
<entry>&gt; 0</entry>
</row>
<row>
diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml
index ba8e67dff4..3d6de1710d 100644
--- a/man/systemd-analyze.xml
+++ b/man/systemd-analyze.xml
@@ -509,9 +509,9 @@ NAutoVTs=8
<para>This command will load unit files and print warnings if any errors are detected. Files specified
on the command line will be loaded, but also any other units referenced by them. The full unit search
path is formed by combining the directories for all command line arguments, and the usual unit load
- paths (variable <varname>$SYSTEMD_UNIT_PATH</varname> is supported, and may be used to replace or
+ paths. The variable <varname>$SYSTEMD_UNIT_PATH</varname> is supported, and may be used to replace or
augment the compiled in set of unit load paths; see
- <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>). All
+ <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>. All
units files present in the directories containing the command line arguments will be used in preference
to the other paths.</para>
@@ -700,9 +700,9 @@ Service b@0.service not loaded, b.socket cannot be started.
<varlistentry>
<term><option>--man=no</option></term>
- <listitem><para>Do not invoke man to verify the existence of
- man pages listed in <varname>Documentation=</varname>.
- </para></listitem>
+ <listitem><para>Do not invoke
+ <citerefentry project='man-pages'><refentrytitle>man</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ to verify the existence of man pages listed in <varname>Documentation=</varname>.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/man/systemd-bless-boot-generator.xml b/man/systemd-bless-boot-generator.xml
index 0c5144f6b8..8275838bce 100644
--- a/man/systemd-bless-boot-generator.xml
+++ b/man/systemd-bless-boot-generator.xml
@@ -17,7 +17,7 @@
<refnamediv>
<refname>systemd-bless-boot-generator</refname>
- <refpurpose>Pull <filename>systemd-bless-boot.service</filename> into the initial boot transaction when boot counting is in effect.</refpurpose>
+ <refpurpose>Pull <filename>systemd-bless-boot.service</filename> into the initial boot transaction when boot counting is in effect</refpurpose>
</refnamediv>
<refsynopsisdiv>
diff --git a/man/systemd-boot.xml b/man/systemd-boot.xml
index b666ae1e53..c3d7bc9d46 100644
--- a/man/systemd-boot.xml
+++ b/man/systemd-boot.xml
@@ -91,7 +91,7 @@
<listitem><para>The boot manager optionally reads a random seed from the ESP partition, combines it
with a 'system token' stored in a persistent EFI variable and derives a random seed to use by the OS as
- entropy pool initializaton, providing a full entropy pool during early boot.</para></listitem>
+ entropy pool initialization, providing a full entropy pool during early boot.</para></listitem>
</itemizedlist>
<para><citerefentry><refentrytitle>bootctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
@@ -313,7 +313,7 @@
is maintained persistently, while <varname>LoaderConfigTimeoutOneShot</varname> is a one-time override which is
read once (in which case it takes precedence over <varname>LoaderConfigTimeout</varname>) and then
removed. <varname>LoaderConfigTimeout</varname> may be manipulated with the
- <keycap>t</keycap>/<keycap>T</keycap> keys, see above.)</para></listitem>
+ <keycap>t</keycap>/<keycap>T</keycap> keys, see above.</para></listitem>
</varlistentry>
<varlistentry>
@@ -343,7 +343,7 @@
boots. <citerefentry><refentrytitle>bootctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
<option>set-default</option> and <option>set-oneshot</option> commands make use of these variables. The boot
loader modifies <varname>LoaderEntryDefault</varname> on request, when the <keycap>d</keycap> key is used, see
- above.)</para></listitem>
+ above.</para></listitem>
</varlistentry>
<varlistentry>
@@ -422,9 +422,9 @@
<varlistentry>
<term><varname>LoaderSystemToken</varname></term>
- <listitem><para>A binary random data field, that is used for generating the random see to pass to the
- OS (see above). Note that this random data is generally only generated once, during OS installation,
- and is then never updated again.</para></listitem>
+ <listitem><para>A binary random data field, that is used for generating the random seed to pass to
+ the OS (see above). Note that this random data is generally only generated once, during OS
+ installation, and is then never updated again.</para></listitem>
</varlistentry>
</variablelist>
diff --git a/man/systemd-firstboot.xml b/man/systemd-firstboot.xml
index 81e62484fd..491ca6e9bf 100644
--- a/man/systemd-firstboot.xml
+++ b/man/systemd-firstboot.xml
@@ -99,6 +99,18 @@
</varlistentry>
<varlistentry>
+ <term><option>--image=<replaceable>path</replaceable></option></term>
+ <listitem><para>Takes a path to a disk image file or block device node. If specified all operations
+ are applied to file system in the indicated disk image. This is similar to <option>--root=</option>
+ but operates on file systems stored in disk images or block devices. The disk image should either
+ contain just a file system or a set of file systems within a GPT partition table, following the
+ <ulink url="https://systemd.io/DISCOVERABLE_PARTITIONS">Discoverable Partitions
+ Specification</ulink>. For further information on supported disk images, see
+ <citerefentry><refentrytitle>systemd-nspawn</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
+ switch of the same name.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>--locale=<replaceable>LOCALE</replaceable></option></term>
<term><option>--locale-messages=<replaceable>LOCALE</replaceable></option></term>
@@ -247,6 +259,14 @@
option should not be used lightly.</para></listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--welcome=</option></term>
+
+ <listitem><para>Takes a boolean argument. By default when prompting the user for configuration
+ options a brief welcome text is shown before the first question is asked. Pass false to this option
+ to turn off the welcome text.</para></listitem>
+ </varlistentry>
+
<xi:include href="standard-options.xml" xpointer="help" />
<xi:include href="standard-options.xml" xpointer="version" />
</variablelist>
diff --git a/man/systemd-gpt-auto-generator.xml b/man/systemd-gpt-auto-generator.xml
index b0fa617d63..78fdacccab 100644
--- a/man/systemd-gpt-auto-generator.xml
+++ b/man/systemd-gpt-auto-generator.xml
@@ -19,7 +19,7 @@
<refname>systemd-gpt-auto-generator</refname>
<refpurpose>Generator for automatically discovering and mounting root, <filename>/home/</filename>,
<filename>/srv/</filename>, <filename>/var/</filename> and <filename>/var/tmp/</filename> partitions, as
- well as discovering and enabling swap partitions, based on GPT partition type GUIDs.</refpurpose>
+ well as discovering and enabling swap partitions, based on GPT partition type GUIDs</refpurpose>
</refnamediv>
<refsynopsisdiv>
diff --git a/man/systemd-journal-gatewayd.service.xml b/man/systemd-journal-gatewayd.service.xml
index 633b4cb55b..0f7aaab624 100644
--- a/man/systemd-journal-gatewayd.service.xml
+++ b/man/systemd-journal-gatewayd.service.xml
@@ -217,9 +217,9 @@
</para>
<para>where
- <option>cursor</option> is a cursor string,
- <option>num_skip</option> is an integer,
- <option>num_entries</option> is an unsigned integer.
+ <replaceable>cursor</replaceable> is a cursor string,
+ <replaceable>num_skip</replaceable> is an integer,
+ <replaceable>num_entries</replaceable> is an unsigned integer.
</para>
<para>Range defaults to all available events.</para>
diff --git a/man/systemd-journal-upload.service.xml b/man/systemd-journal-upload.service.xml
index a073a37a29..174bef803f 100644
--- a/man/systemd-journal-upload.service.xml
+++ b/man/systemd-journal-upload.service.xml
@@ -267,7 +267,7 @@ openssl ca -batch -config ca.conf -notext -in $CLIENT.csr -out $CLIENT.pem
those files can be specified using
<varname>TrustedCertificateFile=</varname>,
<varname>ServerCertificateFile=</varname>,
- <varname>ServerKeyFile=</varname>, in
+ and <varname>ServerKeyFile=</varname> in
<filename>/etc/systemd/journal-remote.conf</filename> and
<filename>/etc/systemd/journal-upload.conf</filename>,
respectively. The default locations can be queried by using
diff --git a/man/systemd-logind.service.xml b/man/systemd-logind.service.xml
index c602b2e42f..bbfcad4af6 100644
--- a/man/systemd-logind.service.xml
+++ b/man/systemd-logind.service.xml
@@ -103,7 +103,7 @@
<citerefentry><refentrytitle>systemd-user-sessions.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>loginctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>logind.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
- <citerefentry><refentrytitle>pam_systemd</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ <citerefentry><refentrytitle>pam_systemd</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>3</manvolnum></citerefentry>
</para>
</refsect1>
diff --git a/man/systemd-mount.xml b/man/systemd-mount.xml
index a6e6dd9b48..f1089eed3b 100644
--- a/man/systemd-mount.xml
+++ b/man/systemd-mount.xml
@@ -50,10 +50,11 @@
<replaceable>WHERE</replaceable>.</para>
<para>In many ways, <command>systemd-mount</command> is similar to the lower-level
- <citerefentry project='man-pages'><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry> command, however instead
- of executing the mount operation directly and immediately, <command>systemd-mount</command> schedules it through
- the service manager job queue, so that it may pull in further dependencies (such as parent mounts, or a file system
- checker to execute a priori), and may make use of the auto-mounting logic.</para>
+ <citerefentry project='man-pages'><refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ command, however instead of executing the mount operation directly and immediately,
+ <command>systemd-mount</command> schedules it through the service manager job queue, so that it may pull
+ in further dependencies (such as parent mounts, or a file system checker to execute a priori), and may
+ make use of the auto-mounting logic.</para>
<para>The command takes either one or two arguments. If only one argument is specified it should refer to
a block device or regular file containing a file system (e.g. <literal>/dev/sdb1</literal> or
@@ -61,15 +62,15 @@
label and other metadata, and is mounted to a directory below <filename>/run/media/system/</filename>
whose name is generated from the file system label. In this mode the block device or image file must
exist at the time of invocation of the command, so that it may be probed. If the device is found to be a
- removable block device (e.g. a USB stick) an automount point instead of a regular mount point is created
+ removable block device (e.g. a USB stick), an automount point is created instead of a regular mount point
(i.e. the <option>--automount=</option> option is implied, see below).</para>
- <para>If two arguments are specified the first indicates the mount source (the <replaceable>WHAT</replaceable>) and
- the second indicates the path to mount it on (the <replaceable>WHERE</replaceable>). In this mode no probing of the
- source is attempted, and a backing device node doesn't have to exist yet. However, if this mode is combined with
- <option>--discover</option>, device node probing for additional metadata is enabled, and – much like in the
- single-argument case discussed above – the specified device has to exist at the time of invocation of the
- command.</para>
+ <para>If two arguments are specified, the first indicates the mount source (the
+ <replaceable>WHAT</replaceable>) and the second indicates the path to mount it on (the
+ <replaceable>WHERE</replaceable>). In this mode no probing of the source is attempted, and a backing
+ device node doesn't have to exist. However, if this mode is combined with <option>--discover</option>,
+ device node probing for additional metadata is enabled, and – much like in the single-argument case
+ discussed above – the specified device has to exist at the time of invocation of the command.</para>
<para>Use the <option>--list</option> command to show a terse table of all local, known block devices with file
systems that may be mounted with this command.</para>
diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml
index e28572db6d..69558ac85c 100644
--- a/man/systemd-nspawn.xml
+++ b/man/systemd-nspawn.xml
@@ -531,11 +531,9 @@
<term><option>-u</option></term>
<term><option>--user=</option></term>
- <listitem><para>After transitioning into the container, change
- to the specified user-defined in the container's user
- database. Like all other systemd-nspawn features, this is not
- a security feature and provides protection against accidental
- destructive operations only.</para></listitem>
+ <listitem><para>After transitioning into the container, change to the specified user defined in the
+ container's user database. Like all other systemd-nspawn features, this is not a security feature and
+ provides protection against accidental destructive operations only.</para></listitem>
</varlistentry>
<varlistentry>
@@ -560,7 +558,7 @@
With option <option>yes</option> systemd-nspawn waits for the
<literal>READY=1</literal> message from the init process in the container
before sending its own to systemd. For more details about notifications
- see <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>).</para></listitem>
+ see <citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.</para></listitem>
</varlistentry>
</variablelist>
@@ -1167,10 +1165,9 @@
<para>Finally, if set to <literal>auto</literal> the file is left as it is if private networking is
turned on (see <option>--private-network</option>). Otherwise, if
- <filename>systemd-resolved.service</filename> is connectible its stub
- <filename>resolv.conf</filename> file is used, and if not the host's
- <filename>/etc/resolv.conf</filename> file is used. In the latter cases the file is copied if the
- image is writable, and bind mounted otherwise.</para>
+ <filename>systemd-resolved.service</filename> is running its stub <filename>resolv.conf</filename>
+ file is used, and if not the host's <filename>/etc/resolv.conf</filename> file. In the latter cases
+ the file is copied if the image is writable, and bind mounted otherwise.</para>
<para>It's recommended to use <literal>copy-…</literal> or <literal>replace-…</literal> if the
container shall be able to make changes to the DNS configuration on its own, deviating from the
@@ -1186,19 +1183,20 @@
<varlistentry>
<term><option>--timezone=</option></term>
- <listitem><para>Configures how <filename>/etc/localtime</filename> inside of the container (i.e. local timezone
- synchronization from host to container) shall be handled. Takes one of <literal>off</literal>,
- <literal>copy</literal>, <literal>bind</literal>, <literal>symlink</literal>, <literal>delete</literal> or
- <literal>auto</literal>. If set to <literal>off</literal> the <filename>/etc/localtime</filename> file in the
- container is left as it is included in the image, and neither modified nor bind mounted over. If set to
- <literal>copy</literal> the <filename>/etc/localtime</filename> file of the host is copied into the
- container. Similar, if <literal>bind</literal> is used, it is bind mounted from the host into the container. If
- set to <literal>symlink</literal> a symlink from <filename>/etc/localtime</filename> in the container is
- created pointing to the matching the timezone file of the container that matches the timezone setting on the
- host. If set to <literal>delete</literal> the file in the container is deleted, should it exist. If set to
- <literal>auto</literal> and the <filename>/etc/localtime</filename> file of the host is a symlink, then
- <literal>symlink</literal> mode is used, and <literal>copy</literal> otherwise, except if the image is
- read-only in which case <literal>bind</literal> is used instead. Defaults to
+ <listitem><para>Configures how <filename>/etc/localtime</filename> inside of the container
+ (i.e. local timezone synchronization from host to container) shall be handled. Takes one of
+ <literal>off</literal>, <literal>copy</literal>, <literal>bind</literal>, <literal>symlink</literal>,
+ <literal>delete</literal> or <literal>auto</literal>. If set to <literal>off</literal> the
+ <filename>/etc/localtime</filename> file in the container is left as it is included in the image, and
+ neither modified nor bind mounted over. If set to <literal>copy</literal> the
+ <filename>/etc/localtime</filename> file of the host is copied into the container. Similarly, if
+ <literal>bind</literal> is used, the file is bind mounted from the host into the container. If set to
+ <literal>symlink</literal>, a symlink is created pointing from <filename>/etc/localtime</filename> in
+ the container to the timezone file in the container that matches the timezone setting on the host. If
+ set to <literal>delete</literal>, the file in the container is deleted, should it exist. If set to
+ <literal>auto</literal> and the <filename>/etc/localtime</filename> file of the host is a symlink,
+ then <literal>symlink</literal> mode is used, and <literal>copy</literal> otherwise, except if the
+ image is read-only in which case <literal>bind</literal> is used instead. Defaults to
<literal>auto</literal>.</para></listitem>
</varlistentry>
@@ -1441,7 +1439,7 @@
<para>This installs a minimal Fedora distribution into the
directory <filename index="false">/var/lib/machines/f&fedora_latest_version;</filename>
- and then boots an OS in a namespace container in it. Because the installation
+ and then boots that OS in a namespace container. Because the installation
is located underneath the standard <filename>/var/lib/machines/</filename>
directory, it is also possible to start the machine using
<command>systemd-nspawn -M f&fedora_latest_version;</command>.</para>
@@ -1455,7 +1453,7 @@
<para>This installs a minimal Debian unstable distribution into
the directory <filename>~/debian-tree/</filename> and then
- spawns a shell in a namespace container in it.</para>
+ spawns a shell from this image in a namespace container.</para>
<para><command>debootstrap</command> supports
<ulink url="https://www.debian.org">Debian</ulink>,
diff --git a/man/systemd-random-seed.service.xml b/man/systemd-random-seed.service.xml
index 28783a15e9..a9e322425f 100644
--- a/man/systemd-random-seed.service.xml
+++ b/man/systemd-random-seed.service.xml
@@ -44,7 +44,7 @@
<citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry>, with
its <command>bootctl random-seed</command> functionality.</para>
- <para>When loading the random seed from disk its file is immediately updated with a new seed retrieved
+ <para>When loading the random seed from disk, the file is immediately updated with a new seed retrieved
from the kernel, in order to ensure no two boots operate with the same random seed. This new seed is
retrieved synchronously from the kernel, which means the service will not complete start-up until the
random pool is fully initialized. On entropy-starved systems this may take a while. This functionality is
diff --git a/man/systemd-repart.xml b/man/systemd-repart.xml
index 74c6ba95b1..ffa88baf67 100644
--- a/man/systemd-repart.xml
+++ b/man/systemd-repart.xml
@@ -57,9 +57,10 @@
available but not yet used. Specifically the following use cases are among those covered:</para>
<itemizedlist>
- <listitem><para>The root partition may be grown to cover the whole available disk space</para></listitem>
- <listitem><para>A <filename>/home/</filename>, swap or <filename>/srv/</filename> partition can be added in</para></listitem>
- <listitem><para>A second (or third, …) root partition may be added in, to cover A/B style setups
+ <listitem><para>The root partition may be grown to cover the whole available disk space.</para></listitem>
+ <listitem><para>A <filename>/home/</filename>, swap or <filename>/srv/</filename> partition can be
+ added.</para></listitem>
+ <listitem><para>A second (or third, …) root partition may be added, to cover A/B style setups
where a second version of the root file system is alternatingly used for implementing update
schemes. The deployed image would carry only a single partition ("A") but on first boot a second
partition ("B") for this purpose is automatically created.</para></listitem>
@@ -69,7 +70,7 @@
<orderedlist>
<listitem><para>The <filename>repart.d/*.conf</filename> configuration files are loaded and parsed,
- and ordered by filename (without the directory suffix). </para></listitem>
+ and ordered by filename (without the directory prefix).</para></listitem>
<listitem><para>The partition table already existing on the block device is loaded and
parsed.</para></listitem>
@@ -119,13 +120,13 @@
</orderedlist>
<para>As exception to the normally strictly incremental operation, when called in a special "factory
- reset" mode <command>systemd-repart</command> may also be used to erase select existing partitions to
+ reset" mode, <command>systemd-repart</command> may also be used to erase existing partitions to
reset an installation back to vendor defaults. This mode of operation is used when either the
<option>--factory-reset=yes</option> switch is passed on the tool's command line, or the
<option>systemd.factory_reset=yes</option> option specified on the kernel command line, or the
<varname>FactoryReset</varname> EFI variable (vendor UUID
<constant>8cf2644b-4b0b-428f-9387-6d876050dc67</constant>) is set to "yes". It alters the algorithm above
- slightly: between the 3rd and the 4th step above the any partition marked explicitly via the
+ slightly: between the 3rd and the 4th step above any partition marked explicitly via the
<varname>FactoryReset=</varname> boolean is deleted, and the algorithm restarted, thus immediately
re-creating these partitions anew empty.</para>
@@ -267,9 +268,9 @@
<varlistentry>
<term><option>--definitions=</option></term>
- <listitem><para>Takes a file system path. If specified the <filename>*.conf</filename> are directly
- read from the specified directory instead of searching in
- <filename>/usr/lib/repart.d/*.conf</filename>, <filename>/etc/repart.d/*.conf</filename>,
+ <listitem><para>Takes a file system path. If specified the <filename>*.conf</filename> files are read
+ from the specified directory instead of searching in <filename>/usr/lib/repart.d/*.conf</filename>,
+ <filename>/etc/repart.d/*.conf</filename>,
<filename>/run/repart.d/*.conf</filename>.</para></listitem>
</varlistentry>
diff --git a/man/systemd-sleep.conf.xml b/man/systemd-sleep.conf.xml
index a6949b0c3b..1acf0e8905 100644
--- a/man/systemd-sleep.conf.xml
+++ b/man/systemd-sleep.conf.xml
@@ -105,7 +105,7 @@
<title>Options</title>
<para>The following options can be configured in the
- <literal>[Sleep]</literal> section of
+ [Sleep] section of
<filename>/etc/systemd/sleep.conf</filename> or a
<filename>sleep.conf.d</filename> file:</para>
diff --git a/man/systemd-socket-proxyd.xml b/man/systemd-socket-proxyd.xml
index 58b26aad87..a4e18989fc 100644
--- a/man/systemd-socket-proxyd.xml
+++ b/man/systemd-socket-proxyd.xml
@@ -16,7 +16,7 @@
</refmeta>
<refnamediv>
<refname>systemd-socket-proxyd</refname>
- <refpurpose>Bidirectionally proxy local sockets to another (possibly remote) socket.</refpurpose>
+ <refpurpose>Bidirectionally proxy local sockets to another (possibly remote) socket</refpurpose>
</refnamediv>
<refsynopsisdiv>
<cmdsynopsis>
diff --git a/man/systemd-suspend.service.xml b/man/systemd-suspend.service.xml
index 2310e6f526..e57000e09a 100644
--- a/man/systemd-suspend.service.xml
+++ b/man/systemd-suspend.service.xml
@@ -71,19 +71,16 @@
url="https://www.freedesktop.org/wiki/Software/systemd/inhibit">Inhibitor
interface</ulink>.</para>
- <para>Note that
- <filename>systemd-suspend.service</filename>,
- <filename>systemd-hibernate.service</filename>, and
- <filename>systemd-hybrid-sleep.service</filename>
- <filename>systemd-suspend-then-hibernate.service</filename>
- should never be executed directly. Instead, trigger system sleep
- states with a command such as <literal>systemctl suspend</literal>
- or similar.</para>
+ <para>Note that <filename>systemd-suspend.service</filename>,
+ <filename>systemd-hibernate.service</filename>, <filename>systemd-hybrid-sleep.service</filename>, and
+ <filename>systemd-suspend-then-hibernate.service</filename> should never be executed directly. Instead,
+ trigger system sleep with a command such as <command>systemctl suspend</command> or <command>systemctl
+ hibernate</command>.</para>
<para>Internally, this service will echo a string like
<literal>mem</literal> into <filename>/sys/power/state</filename>,
to trigger the actual system suspend. What exactly is written
- where can be configured in the <literal>[Sleep]</literal> section
+ where can be configured in the [Sleep] section
of <filename>/etc/systemd/sleep.conf</filename> or a
<filename>sleep.conf.d</filename> file. See
<citerefentry><refentrytitle>systemd-sleep.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml
index 435c3882db..8cf5666f4b 100644
--- a/man/systemd-system.conf.xml
+++ b/man/systemd-system.conf.xml
@@ -58,7 +58,7 @@
<title>Options</title>
<para>All options are configured in the
- <literal>[Manager]</literal> section:</para>
+ [Manager] section:</para>
<variablelist class='config-directives'>
@@ -149,7 +149,7 @@
for details. During the first phase of the shutdown operation the system and service manager remains running
and hence <varname>RuntimeWatchdogSec=</varname> is still honoured. In order to define a timeout on this first
phase of system shutdown, configure <varname>JobTimeoutSec=</varname> and <varname>JobTimeoutAction=</varname>
- in the <literal>[Unit]</literal> section of the <filename>shutdown.target</filename> unit. By default
+ in the [Unit] section of the <filename>shutdown.target</filename> unit. By default
<varname>RuntimeWatchdogSec=</varname> defaults to 0 (off), and <varname>RebootWatchdogSec=</varname> to
10min. <varname>KExecWatchdogSec=</varname> may be used to additionally enable the watchdog when kexec
is being executed rather than when rebooting. Note that if the kernel does not reset the watchdog on kexec (depending
@@ -387,9 +387,9 @@
units. See
<citerefentry><refentrytitle>setrlimit</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
details. These settings may be overridden in individual units using the corresponding
- <varname>LimitXXX=</varname> directives, see
- <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>, for
- details, and they accept the same parameter syntax. Note that these resource limits are only defaults
+ <varname>LimitXXX=</varname> directives and they accept the same parameter syntax,
+ see <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+ for details. Note that these resource limits are only defaults
for units, they are not applied to the service manager process (i.e. PID 1) itself.</para></listitem>
</varlistentry>
diff --git a/man/systemd-time-wait-sync.service.xml b/man/systemd-time-wait-sync.service.xml
index c8a92f94a8..685fe74339 100644
--- a/man/systemd-time-wait-sync.service.xml
+++ b/man/systemd-time-wait-sync.service.xml
@@ -18,7 +18,7 @@
<refnamediv>
<refname>systemd-time-wait-sync.service</refname>
<refname>systemd-time-wait-sync</refname>
- <refpurpose>Wait Until Kernel Time Synchronized</refpurpose>
+ <refpurpose>Wait until kernel time is synchronized</refpurpose>
</refnamediv>
<refsynopsisdiv>
diff --git a/man/systemd.automount.xml b/man/systemd.automount.xml
index fd65f5da79..29b9bb14e1 100644
--- a/man/systemd.automount.xml
+++ b/man/systemd.automount.xml
@@ -35,9 +35,9 @@
this unit type. See
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for the common options of all unit configuration files. The common
- configuration items are configured in the generic <literal>[Unit]</literal> and
- <literal>[Install]</literal> sections. The automount specific configuration options
- are configured in the <literal>[Automount]</literal> section.</para>
+ configuration items are configured in the generic [Unit] and
+ [Install] sections. The automount specific configuration options
+ are configured in the [Automount] section.</para>
<para>Automount units must be named after the automount directories they control. Example: the automount point
<filename index="false">/home/lennart</filename> must be configured in a unit file
diff --git a/man/systemd.device.xml b/man/systemd.device.xml
index ae786a3298..085fd62bce 100644
--- a/man/systemd.device.xml
+++ b/man/systemd.device.xml
@@ -36,8 +36,8 @@
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for the common options of all unit configuration files. The common
configuration items are configured in the generic
- <literal>[Unit]</literal> and <literal>[Install]</literal>
- sections. A separate <literal>[Device]</literal> section does not
+ [Unit] and [Install]
+ sections. A separate [Device] section does not
exist, since no device-specific options may be configured.</para>
<para>systemd will dynamically create device units for all kernel
@@ -60,7 +60,7 @@
<para>Device units will be reloaded by systemd whenever the
corresponding device generates a <literal>changed</literal> event.
Other units can use <varname>ReloadPropagatedFrom=</varname> to react
- to that event</para>
+ to that event.</para>
</refsect1>
<refsect1>
diff --git a/man/systemd.dnssd.xml b/man/systemd.dnssd.xml
index 2fb0a8ee70..d7e6caddf1 100644
--- a/man/systemd.dnssd.xml
+++ b/man/systemd.dnssd.xml
@@ -64,7 +64,7 @@
<refsect1>
<title>[Service] Section Options</title>
- <para>The network service file contains a <literal>[Service]</literal>
+ <para>The network service file contains a [Service]
section, which specifies a discoverable network service announced in a
local network with Multicast DNS broadcasts.</para>
diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
index 64799edd99..6d6eca09a1 100644
--- a/man/systemd.exec.xml
+++ b/man/systemd.exec.xml
@@ -511,10 +511,11 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
<varlistentry>
<term><varname>AppArmorProfile=</varname></term>
- <listitem><para>Takes a profile name as argument. The process executed by the unit will switch to this profile
- when started. Profiles must already be loaded in the kernel, or the unit will fail. This result in a non
- operation if AppArmor is not enabled. If prefixed by <literal>-</literal>, all errors will be ignored. This
- does not affect commands prefixed with <literal>+</literal>.</para></listitem>
+ <listitem><para>Takes a profile name as argument. The process executed by the unit will switch to
+ this profile when started. Profiles must already be loaded in the kernel, or the unit will fail. If
+ prefixed by <literal>-</literal>, all errors will be ignored. This setting has no effect if AppArmor
+ is not enabled. This setting not affect commands prefixed with <literal>+</literal>.</para>
+ </listitem>
</varlistentry>
<varlistentry>
@@ -880,7 +881,7 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
in <varname>NUMAMask=</varname>. For more details on each policy please see,
<citerefentry><refentrytitle>set_mempolicy</refentrytitle><manvolnum>2</manvolnum></citerefentry>. For overall
overview of NUMA support in Linux see,
- <citerefentry project='man-pages'><refentrytitle>numa</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+ <citerefentry project='man-pages'><refentrytitle>numa</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
</para></listitem>
</varlistentry>
@@ -1067,14 +1068,16 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
<varname>RootDirectory=</varname> or <varname>RootImage=</varname> these paths always reside on the host and
are mounted from there into the unit's file system namespace.</para>
- <para>If <varname>DynamicUser=</varname> is used in conjunction with <varname>StateDirectory=</varname>,
- <varname>CacheDirectory=</varname> and <varname>LogsDirectory=</varname> is slightly altered: the directories
- are created below <filename>/var/lib/private</filename>, <filename>/var/cache/private</filename> and
+ <para>If <varname>DynamicUser=</varname> is used in conjunction with
+ <varname>StateDirectory=</varname>, the logic for <varname>CacheDirectory=</varname> and
+ <varname>LogsDirectory=</varname> is slightly altered: the directories are created below
+ <filename>/var/lib/private</filename>, <filename>/var/cache/private</filename> and
<filename>/var/log/private</filename>, respectively, which are host directories made inaccessible to
- unprivileged users, which ensures that access to these directories cannot be gained through dynamic user ID
- recycling. Symbolic links are created to hide this difference in behaviour. Both from perspective of the host
- and from inside the unit, the relevant directories hence always appear directly below
- <filename>/var/lib</filename>, <filename>/var/cache</filename> and <filename>/var/log</filename>.</para>
+ unprivileged users, which ensures that access to these directories cannot be gained through dynamic
+ user ID recycling. Symbolic links are created to hide this difference in behaviour. Both from
+ perspective of the host and from inside the unit, the relevant directories hence always appear
+ directly below <filename>/var/lib</filename>, <filename>/var/cache</filename> and
+ <filename>/var/log</filename>.</para>
<para>Use <varname>RuntimeDirectory=</varname> to manage one or more runtime directories for the unit and bind
their lifetime to the daemon runtime. This is particularly useful for unprivileged daemons that cannot create
@@ -1238,8 +1241,8 @@ BindReadOnlyPaths=/var/lib/systemd</programlisting>
<term><varname>PrivateTmp=</varname></term>
<listitem><para>Takes a boolean argument. If true, sets up a new file system namespace for the executed
- processes and mounts private <filename>/tmp</filename> and <filename>/var/tmp</filename> directories inside it
- that is not shared by processes outside of the namespace. This is useful to secure access to temporary files of
+ processes and mounts private <filename>/tmp/</filename> and <filename>/var/tmp/</filename> directories inside it
+ that are not shared by processes outside of the namespace. This is useful to secure access to temporary files of
the process, but makes sharing between processes via <filename>/tmp</filename> or <filename>/var/tmp</filename>
impossible. If this is enabled, all temporary files created by a service in these directories will be removed
after the service is stopped. Defaults to false. It is possible to run two or more units within the same
@@ -1399,7 +1402,7 @@ BindReadOnlyPaths=/var/lib/systemd</programlisting>
this option removes <constant>CAP_SYS_TIME</constant> and <constant>CAP_WAKE_ALARM</constant> from the
capability bounding set for this unit, installs a system call filter to block calls that can set the
clock, and <varname>DeviceAllow=char-rtc r</varname> is implied. This ensures <filename>/dev/rtc0</filename>,
- <filename>/dev/rtc1</filename>, etc are made read only to the service. See
+ <filename>/dev/rtc1</filename>, etc. are made read-only to the service. See
<citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for the details about <varname>DeviceAllow=</varname>.</para>
@@ -1495,7 +1498,7 @@ BindReadOnlyPaths=/var/lib/systemd</programlisting>
<citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>)
are unaffected. Also, sockets created with <function>socketpair()</function> (which creates connected
AF_UNIX sockets only) are unaffected. Note that this option has no effect on 32-bit x86, s390, s390x,
- mips, mips-le, ppc, ppc-le, pcc64, ppc64-le and is ignored (but works correctly on other ABIs,
+ mips, mips-le, ppc, ppc-le, ppc64, ppc64-le and is ignored (but works correctly on other ABIs,
including x86-64). Note that on systems supporting multiple ABIs (such as x86/x86-64) it is
recommended to turn off alternative ABIs for services, so that they cannot be used to circumvent the
restrictions of this option. Specifically, it is recommended to combine this option with
@@ -1696,7 +1699,7 @@ RestrictNamespaces=~cgroup net</programlisting>
<option>shared</option> mount propagation is used, but — as mentioned — as <option>slave</option> is applied
first, propagation from the unit's processes to the host is still turned off.</para>
- <para>It is not recommended to to use <option>private</option> mount propagation for units, as this means
+ <para>It is not recommended to use <option>private</option> mount propagation for units, as this means
temporary mounts (such as removable media) of the host will stay mounted and thus indefinitely busy in forked
off processes, as unmount propagation events won't be received by the file system namespace of the unit.</para>
@@ -1803,7 +1806,7 @@ RestrictNamespaces=~cgroup net</programlisting>
</row>
<row>
<entry>@file-system</entry>
- <entry>File system operations: opening, creating files and directories for read and write, renaming and removing them, reading file properties, or creating hard and symbolic links.</entry>
+ <entry>File system operations: opening, creating files and directories for read and write, renaming and removing them, reading file properties, or creating hard and symbolic links</entry>
</row>
<row>
<entry>@io-event</entry>
@@ -1819,7 +1822,7 @@ RestrictNamespaces=~cgroup net</programlisting>
</row>
<row>
<entry>@memlock</entry>
- <entry>Locking of memory into RAM (<citerefentry project='man-pages'><refentrytitle>mlock</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>mlockall</refentrytitle><manvolnum>2</manvolnum></citerefentry> and related calls)</entry>
+ <entry>Locking of memory in RAM (<citerefentry project='man-pages'><refentrytitle>mlock</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>mlockall</refentrytitle><manvolnum>2</manvolnum></citerefentry> and related calls)</entry>
</row>
<row>
<entry>@module</entry>
@@ -1843,7 +1846,7 @@ RestrictNamespaces=~cgroup net</programlisting>
</row>
<row>
<entry>@process</entry>
- <entry>Process control, execution, namespaceing operations (<citerefentry project='man-pages'><refentrytitle>clone</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>kill</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>namespaces</refentrytitle><manvolnum>7</manvolnum></citerefentry>, …</entry>
+ <entry>Process control, execution, namespaceing operations (<citerefentry project='man-pages'><refentrytitle>clone</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>kill</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>namespaces</refentrytitle><manvolnum>7</manvolnum></citerefentry>, …)</entry>
</row>
<row>
<entry>@raw-io</entry>
@@ -1871,7 +1874,7 @@ RestrictNamespaces=~cgroup net</programlisting>
</row>
<row>
<entry>@sync</entry>
- <entry>Synchronizing files and memory to disk: (<citerefentry project='man-pages'><refentrytitle>fsync</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>msync</refentrytitle><manvolnum>2</manvolnum></citerefentry>, and related calls)</entry>
+ <entry>Synchronizing files and memory to disk (<citerefentry project='man-pages'><refentrytitle>fsync</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>msync</refentrytitle><manvolnum>2</manvolnum></citerefentry>, and related calls)</entry>
</row>
<row>
<entry>@system-service</entry>
@@ -1949,7 +1952,7 @@ SystemCallErrorNumber=EPERM</programlisting>
manager is compiled for). If running in user mode, or in system mode, but without the
<constant>CAP_SYS_ADMIN</constant> capability (e.g. setting <varname>User=nobody</varname>),
<varname>NoNewPrivileges=yes</varname> is implied. By default, this option is set to the empty list, i.e. no
- system call architecture filtering is applied.</para>
+ filtering is applied.</para>
<para>If this setting is used, processes of this unit will only be permitted to call native system calls, and
system calls of the specified architectures. For the purposes of this option, the x32 architecture is treated
@@ -2213,8 +2216,9 @@ SystemCallErrorNumber=EPERM</programlisting>
<constant>AF_UNIX</constant> socket in the file system, as in that case only a
single stream connection is created for both input and output.</para>
- <para><option>append:<replaceable>path</replaceable></option> is similar to <option>file:<replaceable>path
- </replaceable></option> above, but it opens the file in append mode.</para>
+ <para><option>append:<replaceable>path</replaceable></option> is similar to
+ <option>file:<replaceable>path</replaceable></option> above, but it opens the file in append mode.
+ </para>
<para><option>socket</option> connects standard output to a socket acquired via socket activation. The
semantics are similar to the same option of <varname>StandardInput=</varname>, see above.</para>
@@ -2551,7 +2555,7 @@ StandardInputData=SWNrIHNpdHplIGRhIHVuJyBlc3NlIEtsb3BzLAp1ZmYgZWVtYWwga2xvcHAncy
<varname>UnsetEnvironment=</varname> are removed again from the compiled environment variable list, immediately
before it is passed to the executed process.</para>
- <para>The following select environment variables are set or propagated by the service manager for each invoked
+ <para>The following environment variables are set or propagated by the service manager for each invoked
process:</para>
<variablelist class='environment-variables'>
@@ -2622,7 +2626,7 @@ StandardInputData=SWNrIHNpdHplIGRhIHVuJyBlc3NlIEtsb3BzLAp1ZmYgZWVtYWwga2xvcHAncy
<term><varname>$LOGS_DIRECTORY</varname></term>
<term><varname>$CONFIGURATION_DIRECTORY</varname></term>
- <listitem><para>Contains and absolute paths to the directories defined with
+ <listitem><para>Absolute paths to the directories defined with
<varname>RuntimeDirectory=</varname>, <varname>StateDirectory=</varname>,
<varname>CacheDirectory=</varname>, <varname>LogsDirectory=</varname>, and
<varname>ConfigurationDirectory=</varname> when those settings are used.</para>
@@ -3228,7 +3232,7 @@ StandardInputData=SWNrIHNpdHplIGRhIHVuJyBlc3NlIEtsb3BzLAp1ZmYgZWVtYWwga2xvcHAncy
<row>
<entry>242</entry>
<entry><constant>EXIT_NUMA_POLICY</constant></entry>
- <entry>Failed to set up unit's NUMA memory policy. See <varname>NUMAPolicy=</varname> and <varname>NUMAMask=</varname>above.</entry>
+ <entry>Failed to set up unit's NUMA memory policy. See <varname>NUMAPolicy=</varname> and <varname>NUMAMask=</varname> above.</entry>
</row>
</tbody>
diff --git a/man/systemd.journal-fields.xml b/man/systemd.journal-fields.xml
index 31ad143113..197a468f25 100644
--- a/man/systemd.journal-fields.xml
+++ b/man/systemd.journal-fields.xml
@@ -524,7 +524,8 @@
structured log entries via calls such as
<citerefentry><refentrytitle>sd_journal_send</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
They may also not be used as matches for
- <citerefentry><refentrytitle>sd_journal_add_match</refentrytitle><manvolnum>3</manvolnum></citerefentry></para>
+ <citerefentry><refentrytitle>sd_journal_add_match</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
+ </para>
<variablelist class='journal-directives'>
<varlistentry>
diff --git a/man/systemd.kill.xml b/man/systemd.kill.xml
index 5e4d430031..73f61c80e4 100644
--- a/man/systemd.kill.xml
+++ b/man/systemd.kill.xml
@@ -151,7 +151,7 @@
terminate upon receiving the initial <constant>SIGTERM</constant>
signal. This can be achieved by configuring <varname>LimitCORE=</varname>
and setting <varname>FinalKillSignal=</varname> to either
- <constant>SIGQUIT</constant> or <constant>SIGABRT</constant>
+ <constant>SIGQUIT</constant> or <constant>SIGABRT</constant>.
Defaults to <constant>SIGKILL</constant>.
</para></listitem>
</varlistentry>
diff --git a/man/systemd.link.xml b/man/systemd.link.xml
index d7724a0a59..dc59ee4e9a 100644
--- a/man/systemd.link.xml
+++ b/man/systemd.link.xml
@@ -64,8 +64,8 @@
<title>[Match] Section Options</title>
<para>A link file is said to match a device if all matches specified by the
- <literal>[Match]</literal> section are satisfied. When a link file does not contain valid settings
- in <literal>[Match]</literal> section, then the file will match all devices and
+ [Match] section are satisfied. When a link file does not contain valid settings
+ in [Match] section, then the file will match all devices and
<command>systemd-udevd</command> warns about that. Hint: to avoid the warning and to make it clear
that all interfaces shall be matched, add the following:
<programlisting>OriginalName=*</programlisting>
diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml
index 33d861a33f..9e1f5d40fd 100644
--- a/man/systemd.mount.xml
+++ b/man/systemd.mount.xml
@@ -34,9 +34,9 @@
this unit type. See
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for the common options of all unit configuration files. The common
- configuration items are configured in the generic <literal>[Unit]</literal> and
- <literal>[Install]</literal> sections. The mount specific configuration options are
- configured in the <literal>[Mount]</literal> section.</para>
+ configuration items are configured in the generic [Unit] and
+ [Install] sections. The mount specific configuration options are
+ configured in the [Mount] section.</para>
<para>Additional options are listed in
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml
index 4fc85d40ec..324c94dbd9 100644
--- a/man/systemd.net-naming-scheme.xml
+++ b/man/systemd.net-naming-scheme.xml
@@ -357,7 +357,7 @@
</variablelist>
<para>Note that <constant>latest</constant> may be used to denote the latest scheme known (to this
- particular version of systemd.</para>
+ particular version of systemd).</para>
</refsect1>
<refsect1>
diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml
index 6ebaf1143c..37659326e3 100644
--- a/man/systemd.netdev.xml
+++ b/man/systemd.netdev.xml
@@ -114,10 +114,10 @@
<entry>An IPv4 over IPv4 tunnel.</entry></row>
<row><entry><varname>ipvlan</varname></entry>
- <entry>An ipvlan device is a stacked device which receives packets from its underlying device based on IP address filtering.</entry></row>
+ <entry>An IPVLAN device is a stacked device which receives packets from its underlying device based on IP address filtering.</entry></row>
<row><entry><varname>ipvtap</varname></entry>
- <entry>An ipvtap device is a stacked device which receives packets from its underlying device based on IP address filtering and can be accessed using the tap user space interface.</entry></row>
+ <entry>An IPVTAP device is a stacked device which receives packets from its underlying device based on IP address filtering and can be accessed using the tap user space interface.</entry></row>
<row><entry><varname>macvlan</varname></entry>
<entry>A macvlan device is a stacked device which receives packets from its underlying device based on MAC address filtering.</entry></row>
@@ -193,7 +193,7 @@
<title>[Match] Section Options</title>
<para>A virtual network device is only created if the
- <literal>[Match]</literal> section matches the current
+ [Match] section matches the current
environment, or if the section is empty. The following keys are
accepted:</para>
@@ -259,7 +259,7 @@
<refsect1>
<title>[NetDev] Section Options</title>
- <para>The <literal>[NetDev]</literal> section accepts the
+ <para>The [NetDev] section accepts the
following keys:</para>
<variablelist class='network-directives'>
@@ -273,13 +273,13 @@
<term><varname>Name=</varname></term>
<listitem>
<para>The interface name used when creating the netdev.
- This option is compulsory.</para>
+ This setting is compulsory.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>Kind=</varname></term>
<listitem>
- <para>The netdev kind. This option is compulsory. See the
+ <para>The netdev kind. This setting is compulsory. See the
<literal>Supported netdev kinds</literal> section for the
valid keys.</para>
</listitem>
@@ -287,10 +287,10 @@
<varlistentry>
<term><varname>MTUBytes=</varname></term>
<listitem>
- <para>The maximum transmission unit in bytes to set for the device. The usual suffixes K, M, G,
+ <para>The maximum transmission unit in bytes to set for the device. The usual suffixes K, M, G
are supported and are understood to the base of 1024. For <literal>tun</literal> or
<literal>tap</literal> devices, <varname>MTUBytes=</varname> setting is not currently supported in
- <literal>[NetDev]</literal> section. Please specify it in <literal>[Link]</literal> section of
+ [NetDev] section. Please specify it in [Link] section of
corresponding
<citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>
files.</para>
@@ -300,8 +300,8 @@
<term><varname>MACAddress=</varname></term>
<listitem>
<para>The MAC address to use for the device. For <literal>tun</literal> or <literal>tap</literal>
- devices, setting <varname>MACAddress=</varname> in the <literal>[NetDev]</literal> section is not
- supported. Please specify it in <literal>[Link]</literal> section of the corresponding
+ devices, setting <varname>MACAddress=</varname> in the [NetDev] section is not
+ supported. Please specify it in [Link] section of the corresponding
<citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>
file. If this option is not set, <literal>vlan</literal> devices inherit the MAC address of the
physical interface. For other kind of netdevs, if this option is not set, then MAC address is
@@ -316,7 +316,7 @@
<refsect1>
<title>[Bridge] Section Options</title>
- <para>The <literal>[Bridge]</literal> section only applies for
+ <para>The [Bridge] section only applies for
netdevs of kind <literal>bridge</literal>, and accepts the
following keys:</para>
@@ -436,7 +436,7 @@
<refsect1>
<title>[VLAN] Section Options</title>
- <para>The <literal>[VLAN]</literal> section only applies for
+ <para>The [VLAN] section only applies for
netdevs of kind <literal>vlan</literal>, and accepts the
following key:</para>
@@ -445,7 +445,7 @@
<term><varname>Id=</varname></term>
<listitem>
<para>The VLAN ID to use. An integer in the range 0–4094.
- This option is compulsory.</para>
+ This setting is compulsory.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -478,8 +478,8 @@
<varlistentry>
<term><varname>ReorderHeader=</varname></term>
<listitem>
- <para>Takes a boolean. The VLAN reorder header is set VLAN interfaces behave like physical interfaces.
- When unset, the kernel's default will be used.</para>
+ <para>Takes a boolean. When enabled, the VLAN reorder header is used and VLAN interfaces behave
+ like physical interfaces. When unset, the kernel's default will be used.</para>
</listitem>
</varlistentry>
</variablelist>
@@ -488,7 +488,7 @@
<refsect1>
<title>[MACVLAN] Section Options</title>
- <para>The <literal>[MACVLAN]</literal> section only applies for
+ <para>The [MACVLAN] section only applies for
netdevs of kind <literal>macvlan</literal>, and accepts the
following key:</para>
@@ -510,15 +510,15 @@
<refsect1>
<title>[MACVTAP] Section Options</title>
- <para>The <literal>[MACVTAP]</literal> section applies for
+ <para>The [MACVTAP] section applies for
netdevs of kind <literal>macvtap</literal> and accepts the
- same key as <literal>[MACVLAN]</literal>.</para>
+ same key as [MACVLAN].</para>
</refsect1>
<refsect1>
<title>[IPVLAN] Section Options</title>
- <para>The <literal>[IPVLAN]</literal> section only applies for
+ <para>The [IPVLAN] section only applies for
netdevs of kind <literal>ipvlan</literal>, and accepts the
following key:</para>
@@ -545,15 +545,15 @@
<refsect1>
<title>[IPVTAP] Section Options</title>
- <para>The <literal>[IPVTAP]</literal> section only applies for
+ <para>The [IPVTAP] section only applies for
netdevs of kind <literal>ipvtap</literal> and accepts the
- same key as <literal>[IPVLAN]</literal>.</para>
+ same key as [IPVLAN].</para>
</refsect1>
<refsect1>
<title>[VXLAN] Section Options</title>
- <para>The <literal>[VXLAN]</literal> section only applies for
+ <para>The [VXLAN] section only applies for
netdevs of kind <literal>vxlan</literal>, and accepts the
following keys:</para>
@@ -579,7 +579,8 @@
<varlistentry>
<term><varname>Group=</varname></term>
<listitem>
- <para>Configures VXLAN multicast group IP address. All members of a VXLAN must use the same multicast group address.</para>
+ <para>Configures VXLAN multicast group IP address. All members of a VXLAN must use the same
+ multicast group address.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -637,8 +638,7 @@
<varlistentry>
<term><varname>L3MissNotification=</varname></term>
<listitem>
- <para>Takes a boolean. When true, enables netlink IP address miss
- notifications.</para>
+ <para>Takes a boolean. When true, enables netlink IP address miss notifications.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -739,7 +739,7 @@
<refsect1>
<title>[GENEVE] Section Options</title>
- <para>The <literal>[GENEVE]</literal> section only applies for
+ <para>The [GENEVE] section only applies for
netdevs of kind <literal>geneve</literal>, and accepts the
following keys:</para>
@@ -765,15 +765,16 @@
<varlistentry>
<term><varname>TTL=</varname></term>
<listitem>
- <para>Accepts the same key in <literal>[VXLAN]</literal> section except when unset or
- set to 0, the kernel's default will be used meaning that packets TTL will be set from
+ <para>Accepts the same values as in the [VXLAN] section, except that when unset
+ or set to 0, the kernel's default will be used, meaning that packet TTL will be set from
<filename>/proc/sys/net/ipv4/ip_default_ttl</filename>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>UDPChecksum=</varname></term>
<listitem>
- <para>Takes a boolean. When true, specifies if UDP checksum is calculated for transmitted packets over IPv4.</para>
+ <para>Takes a boolean. When true, specifies that UDP checksum is calculated for transmitted packets
+ over IPv4.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -804,7 +805,7 @@
<varlistentry>
<term><varname>IPDoNotFragment=</varname></term>
<listitem>
- <para>Accepts the same key in <literal>[VXLAN]</literal> section.</para>
+ <para>Accepts the same key in [VXLAN] section.</para>
</listitem>
</varlistentry>
</variablelist>
@@ -813,7 +814,7 @@
<refsect1>
<title>[L2TP] Section Options</title>
- <para>The <literal>[L2TP]</literal> section only applies for
+ <para>The [L2TP] section only applies for
netdevs of kind <literal>l2tp</literal>, and accepts the
following keys:</para>
@@ -821,21 +822,23 @@
<varlistentry>
<term><varname>TunnelId=</varname></term>
<listitem>
- <para>Specifies the tunnel id. The value used must match the <literal>PeerTunnelId=</literal> value being used at the peer.
- Ranges a number between 1 and 4294967295). This option is compulsory.</para>
+ <para>Specifies the tunnel identifier. Takes an number in the range 1–4294967295. The value used
+ must match the <literal>PeerTunnelId=</literal> value being used at the peer. This setting is
+ compulsory.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>PeerTunnelId=</varname></term>
<listitem>
- <para>Specifies the peer tunnel id. The value used must match the <literal>PeerTunnelId=</literal> value being used at the peer.
- Ranges a number between 1 and 4294967295). This option is compulsory.</para>
+ <para>Specifies the peer tunnel id. Takes a number in the range 1—4294967295. The value used must
+ match the <literal>PeerTunnelId=</literal> value being used at the peer. This setting is
+ compulsory.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>Remote=</varname></term>
<listitem>
- <para>Specifies the IP address of the remote peer. This option is compulsory.</para>
+ <para>Specifies the IP address of the remote peer. This setting is compulsory.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -852,27 +855,29 @@
<varlistentry>
<term><varname>EncapsulationType=</varname></term>
<listitem>
- <para>Specifies the encapsulation type of the tunnel. Takes one of <literal>udp</literal> or <literal>ip</literal>.</para>
+ <para>Specifies the encapsulation type of the tunnel. Takes one of <literal>udp</literal> or
+ <literal>ip</literal>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>UDPSourcePort=</varname></term>
<listitem>
- <para>Specifies the UDP source port to be used for the tunnel. When UDP encapsulation is selected it's mandotory. Ignored when ip
- encapsulation is selected.</para>
+ <para>Specifies the UDP source port to be used for the tunnel. When UDP encapsulation is selected
+ it's mandatory. Ignored when IP encapsulation is selected.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>UDPDestinationPort=</varname></term>
<listitem>
- <para>Specifies destination port. When UDP encapsulation is selected it's mandotory. Ignored when ip
+ <para>Specifies destination port. When UDP encapsulation is selected it's mandatory. Ignored when IP
encapsulation is selected.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>UDPChecksum=</varname></term>
<listitem>
- <para>Takes a boolean. When true, specifies if UDP checksum is calculated for transmitted packets over IPv4.</para>
+ <para>Takes a boolean. When true, specifies that UDP checksum is calculated for transmitted packets
+ over IPv4.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -893,28 +898,30 @@
<refsect1>
<title>[L2TPSession] Section Options</title>
- <para>The <literal>[L2TPSession]</literal> section only applies for
+ <para>The [L2TPSession] section only applies for
netdevs of kind <literal>l2tp</literal>, and accepts the
following keys:</para>
<variablelist class='network-directives'>
<varlistentry>
<term><varname>Name=</varname></term>
<listitem>
- <para>Specifies the name of the session. This option is compulsory.</para>
+ <para>Specifies the name of the session. This setting is compulsory.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>SessionId=</varname></term>
<listitem>
- <para>Specifies the session id. The value used must match the <literal>SessionId=</literal> value being used at the peer.
- Ranges a number between 1 and 4294967295). This option is compulsory.</para>
+ <para>Specifies the session identifier. Takes an number in the range 1–4294967295. The value used
+ must match the <literal>SessionId=</literal> value being used at the peer. This setting is
+ compulsory.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>PeerSessionId=</varname></term>
<listitem>
- <para>Specifies the peer session id. The value used must match the <literal>PeerSessionId=</literal> value being used at the peer.
- Ranges a number between 1 and 4294967295). This option is compulsory.</para>
+ <para>Specifies the peer session identifier. Takes an number in the range 1–4294967295.
+ The value used must match the <literal>PeerSessionId=</literal> value being used at the peer.
+ This setting is compulsory.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -929,7 +936,7 @@
<refsect1>
<title>[MACsec] Section Options</title>
- <para>The <literal>[MACsec]</literal> section only applies for network devices of kind
+ <para>The [MACsec] section only applies for network devices of kind
<literal>macsec</literal>, and accepts the following keys:</para>
<variablelist class='network-directives'>
@@ -952,7 +959,7 @@
<refsect1>
<title>[MACsecReceiveChannel] Section Options</title>
- <para>The <literal>[MACsecReceiveChannel]</literal> section only applies for network devices of
+ <para>The [MACsecReceiveChannel] section only applies for network devices of
kind <literal>macsec</literal>, and accepts the following keys:</para>
<variablelist class='network-directives'>
@@ -968,7 +975,7 @@
<term><varname>MACAddress=</varname></term>
<listitem>
<para>Specifies the MAC address to be used for the MACsec receive channel. The MAC address
- used to make secure channel identifier (SCI). This option is compulsory, and is not set by
+ used to make secure channel identifier (SCI). This setting is compulsory, and is not set by
default.</para>
</listitem>
</varlistentry>
@@ -978,7 +985,7 @@
<refsect1>
<title>[MACsecTransmitAssociation] Section Options</title>
- <para>The <literal>[MACsecTransmitAssociation]</literal> section only applies for network devices
+ <para>The [MACsecTransmitAssociation] section only applies for network devices
of kind <literal>macsec</literal>, and accepts the following keys:</para>
<variablelist class='network-directives'>
@@ -1002,7 +1009,7 @@
<term><varname>Key=</varname></term>
<listitem>
<para>Specifies the encryption key used in the transmission channel. The same key must be
- configured on the peer’s matching receive channel. This option is compulsory, and is not set
+ configured on the peer’s matching receive channel. This setting is compulsory, and is not set
by default. Takes a 128-bit key encoded in a hexadecimal string, for example
<literal>dffafc8d7b9a43d5b9a3dfbbf6a30c16</literal>.</para>
</listitem>
@@ -1028,7 +1035,7 @@
<term><varname>UseForEncoding=</varname></term>
<listitem>
<para>Takes a boolean. If enabled, then the security association is used for encoding. Only
- one <literal>[MACsecTransmitAssociation]</literal> section can enable this option. When enabled,
+ one [MACsecTransmitAssociation] section can enable this option. When enabled,
<varname>Activate=yes</varname> is implied. Defaults to unset.</para>
</listitem>
</varlistentry>
@@ -1038,7 +1045,7 @@
<refsect1>
<title>[MACsecReceiveAssociation] Section Options</title>
- <para>The <literal>[MACsecReceiveAssociation]</literal> section only applies for
+ <para>The [MACsecReceiveAssociation] section only applies for
network devices of kind <literal>macsec</literal>, and accepts the
following keys:</para>
@@ -1046,43 +1053,43 @@
<varlistentry>
<term><varname>Port=</varname></term>
<listitem>
- <para>Accepts the same key in <literal>[MACsecReceiveChannel]</literal> section.</para>
+ <para>Accepts the same key in [MACsecReceiveChannel] section.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>MACAddress=</varname></term>
<listitem>
- <para>Accepts the same key in <literal>[MACsecReceiveChannel]</literal> section.</para>
+ <para>Accepts the same key in [MACsecReceiveChannel] section.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>PacketNumber=</varname></term>
<listitem>
- <para>Accepts the same key in <literal>[MACsecTransmitAssociation]</literal> section.</para>
+ <para>Accepts the same key in [MACsecTransmitAssociation] section.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>KeyId=</varname></term>
<listitem>
- <para>Accepts the same key in <literal>[MACsecTransmitAssociation]</literal> section.</para>
+ <para>Accepts the same key in [MACsecTransmitAssociation] section.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>Key=</varname></term>
<listitem>
- <para>Accepts the same key in <literal>[MACsecTransmitAssociation]</literal> section.</para>
+ <para>Accepts the same key in [MACsecTransmitAssociation] section.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>KeyFile=</varname></term>
<listitem>
- <para>Accepts the same key in <literal>[MACsecTransmitAssociation]</literal> section.</para>
+ <para>Accepts the same key in [MACsecTransmitAssociation] section.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>Activate=</varname></term>
<listitem>
- <para>Accepts the same key in <literal>[MACsecTransmitAssociation]</literal> section.</para>
+ <para>Accepts the same key in [MACsecTransmitAssociation] section.</para>
</listitem>
</varlistentry>
</variablelist>
@@ -1091,7 +1098,7 @@
<refsect1>
<title>[Tunnel] Section Options</title>
- <para>The <literal>[Tunnel]</literal> section only applies for
+ <para>The [Tunnel] section only applies for
netdevs of kind
<literal>ipip</literal>,
<literal>sit</literal>,
@@ -1136,7 +1143,7 @@
<para>A fixed Time To Live N on tunneled packets. N is a
number in the range 1–255. 0 is a special value meaning that
packets inherit the TTL value. The default value for IPv4
- tunnels is: inherit. The default value for IPv6 tunnels is
+ tunnels is 0 (inherit). The default value for IPv6 tunnels is
64.</para>
</listitem>
</varlistentry>
@@ -1192,7 +1199,7 @@
both directions (<varname>InputKey=</varname> and <varname>OutputKey=</varname>).
The <varname>Key=</varname> is either a number or an IPv4 address-like dotted quad.
It is used as mark-configured SAD/SPD entry as part of the lookup key (both in data
- and control path) in ip xfrm (framework used to implement IPsec protocol).
+ and control path) in IP XFRM (framework used to implement IPsec protocol).
See <ulink url="http://man7.org/linux/man-pages/man8/ip-xfrm.8.html">
ip-xfrm — transform configuration</ulink> for details. It is only used for VTI/VTI6,
GRE, GRETAP, and ERSPAN tunnels.</para>
@@ -1274,7 +1281,7 @@
<varlistentry>
<term><varname>Encapsulation=</varname></term>
<listitem>
- <para>Accepts the same key as in the <literal>[FooOverUDP]</literal> section.</para>
+ <para>Accepts the same key as in the [FooOverUDP] section.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -1314,7 +1321,7 @@
<refsect1>
<title>[FooOverUDP] Section Options</title>
- <para>The <literal>[FooOverUDP]</literal> section only applies for
+ <para>The [FooOverUDP] section only applies for
netdevs of kind <literal>fou</literal> and accepts the
following keys:</para>
@@ -1322,29 +1329,32 @@
<varlistentry>
<term><varname>Encapsulation=</varname></term>
<listitem>
- <para>Specifies the encapsulation mechanism used to store networking packets of various protocols inside the UDP packets. Supports the following values:
+ <para>Specifies the encapsulation mechanism used to store networking packets of various protocols
+ inside the UDP packets. Supports the following values:
- <literal>FooOverUDP</literal> provides the simplest no frills model of UDP encapsulation, it simply encapsulates
- packets directly in the UDP payload.
- <literal>GenericUDPEncapsulation</literal> is a generic and extensible encapsulation, it allows encapsulation of packets for any IP
- protocol and optional data as part of the encapsulation.
- For more detailed information see <ulink url="https://lwn.net/Articles/615044">Generic UDP Encapsulation</ulink>.
- Defaults to <literal>FooOverUDP</literal>.
+ <literal>FooOverUDP</literal> provides the simplest no frills model of UDP encapsulation, it simply
+ encapsulates packets directly in the UDP payload. <literal>GenericUDPEncapsulation</literal> is a
+ generic and extensible encapsulation, it allows encapsulation of packets for any IP protocol and
+ optional data as part of the encapsulation. For more detailed information see <ulink
+ url="https://lwn.net/Articles/615044">Generic UDP Encapsulation</ulink>. Defaults to
+ <literal>FooOverUDP</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>Port=</varname></term>
<listitem>
- <para>Specifies the port number, where the IP encapsulation packets will arrive. Please take note that the packets
- will arrive with the encapsulation will be removed. Then they will be manually fed back into the network stack, and sent ahead
- for delivery to the real destination. This option is mandatory.</para>
+ <para>Specifies the port number, where the IP encapsulation packets will arrive. Please take note
+ that the packets will arrive with the encapsulation will be removed. Then they will be manually fed
+ back into the network stack, and sent ahead for delivery to the real destination. This option is
+ mandatory.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>PeerPort=</varname></term>
<listitem>
- <para>Specifies the peer port number. Defaults to unset. Note that when peer port is set <literal>Peer=</literal> address is mandotory.</para>
+ <para>Specifies the peer port number. Defaults to unset. Note that when peer port is set
+ <literal>Peer=</literal> address is mandatory.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -1360,7 +1370,8 @@
<varlistentry>
<term><varname>Peer=</varname></term>
<listitem>
- <para>Configures peer IP address. Note that when peer address is set <literal>PeerPort=</literal> is mandotory.</para>
+ <para>Configures peer IP address. Note that when peer address is set <literal>PeerPort=</literal>
+ is mandatory.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -1375,7 +1386,7 @@
<refsect1>
<title>[Peer] Section Options</title>
- <para>The <literal>[Peer]</literal> section only applies for
+ <para>The [Peer] section only applies for
netdevs of kind <literal>veth</literal> and accepts the
following keys:</para>
@@ -1384,7 +1395,7 @@
<term><varname>Name=</varname></term>
<listitem>
<para>The interface name used when creating the netdev.
- This option is compulsory.</para>
+ This setting is compulsory.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -1401,7 +1412,7 @@
<refsect1>
<title>[VXCAN] Section Options</title>
- <para>The <literal>[VXCAN]</literal> section only applies for
+ <para>The [VXCAN] section only applies for
netdevs of kind <literal>vxcan</literal> and accepts the
following key:</para>
@@ -1410,7 +1421,7 @@
<term><varname>Peer=</varname></term>
<listitem>
<para>The peer interface name used when creating the netdev.
- This option is compulsory.</para>
+ This setting is compulsory.</para>
</listitem>
</varlistentry>
</variablelist>
@@ -1419,7 +1430,7 @@
<refsect1>
<title>[Tun] Section Options</title>
- <para>The <literal>[Tun]</literal> section only applies for
+ <para>The [Tun] section only applies for
netdevs of kind <literal>tun</literal>, and accepts the following
keys:</para>
@@ -1469,15 +1480,15 @@
<refsect1>
<title>[Tap] Section Options</title>
- <para>The <literal>[Tap]</literal> section only applies for
+ <para>The [Tap] section only applies for
netdevs of kind <literal>tap</literal>, and accepts the same keys
- as the <literal>[Tun]</literal> section.</para>
+ as the [Tun] section.</para>
</refsect1>
<refsect1>
<title>[WireGuard] Section Options</title>
- <para>The <literal>[WireGuard]</literal> section accepts the following
+ <para>The [WireGuard] section accepts the following
keys:</para>
<variablelist class='network-directives'>
@@ -1524,7 +1535,7 @@
<refsect1>
<title>[WireGuardPeer] Section Options</title>
- <para>The <literal>[WireGuardPeer]</literal> section accepts the following
+ <para>The [WireGuardPeer] section accepts the following
keys:</para>
<variablelist class='network-directives'>
@@ -1600,7 +1611,7 @@
<refsect1>
<title>[Bond] Section Options</title>
- <para>The <literal>[Bond]</literal> section accepts the following
+ <para>The [Bond] section accepts the following
key:</para>
<variablelist class='network-directives'>
@@ -1702,14 +1713,15 @@
<varlistentry>
<term><varname>AdActorSystemPriority=</varname></term>
<listitem>
- <para>Specifies the 802.3ad actor system priority. Ranges [1-65535].</para>
+ <para>Specifies the 802.3ad actor system priority. Takes a number in the range 1—65535.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>AdUserPortKey=</varname></term>
<listitem>
- <para>Specifies the 802.3ad user defined portion of the port key. Ranges [0-1023].</para>
+ <para>Specifies the 802.3ad user defined portion of the port key. Takes a number in the range
+ 0–1023.</para>
</listitem>
</varlistentry>
@@ -1879,7 +1891,7 @@
<refsect1>
<title>[Xfrm] Section Options</title>
- <para>The <literal>[Xfrm]</literal> section accepts the following
+ <para>The [Xfrm] section accepts the following
keys:</para>
<variablelist class='network-directives'>
@@ -1902,13 +1914,12 @@
</variablelist>
<para>For more detail information see
- <ulink url="https://lwn.net/Articles/757391">
- Virtual xfrm interfaces</ulink></para>
+ <ulink url="https://lwn.net/Articles/757391">Virtual XFRM Interfaces</ulink>.</para>
</refsect1>
<refsect1>
<title>[VRF] Section Options</title>
- <para>The <literal>[VRF]</literal> section only applies for
+ <para>The [VRF] section only applies for
netdevs of kind <literal>vrf</literal> and accepts the
following key:</para>
@@ -1916,7 +1927,7 @@
<varlistentry>
<term><varname>Table=</varname></term>
<listitem>
- <para>The numeric routing table identifier. This option is compulsory.</para>
+ <para>The numeric routing table identifier. This setting is compulsory.</para>
</listitem>
</varlistentry>
</variablelist>
diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index dce81692df..d08543c5fc 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -72,21 +72,16 @@
<refsect1>
<title>[Match] Section Options</title>
- <para>The network file contains a <literal>[Match]</literal>
- section, which determines if a given network file may be applied
- to a given device; and a <literal>[Network]</literal> section
- specifying how the device should be configured. The first (in
- lexical order) of the network files that matches a given device
- is applied, all later files are ignored, even if they match as
- well.</para>
-
- <para>A network file is said to match a network interface if all matches specified by the
- <literal>[Match]</literal> section are satisfied. When a network file does not contain valid
- settings in <literal>[Match]</literal> section, then the file will match all interfaces and
- <command>systemd-networkd</command> warns about that. Hint: to avoid the warning and to make it
- clear that all interfaces shall be matched, add the following:
- <programlisting>Name=*</programlisting>
- The following keys are accepted:</para>
+ <para>The network file contains a [Match] section, which determines if a given network file may be
+ applied to a given device; and a [Network] section specifying how the device should be configured. The
+ first (in lexical order) of the network files that matches a given device is applied, all later files
+ are ignored, even if they match as well.</para>
+
+ <para>A network file is said to match a network interface if all matches specified by the [Match]
+ section are satisfied. When a network file does not contain valid settings in [Match] section, then the
+ file will match all interfaces and <command>systemd-networkd</command> warns about that. Hint: to avoid
+ the warning and to make it clear that all interfaces shall be matched, add the following:
+ <programlisting>Name=*</programlisting> The following keys are accepted:</para>
<variablelist class='network-directives'>
<xi:include href="systemd.link.xml" xpointer="mac-address" />
@@ -132,9 +127,8 @@
<listitem>
<para>A whitespace-separated list of hardware address of the currently connected wireless
LAN. Use full colon-, hyphen- or dot-delimited hexadecimal. See the example in
- <varname>MACAddress=</varname>. This option may appear more than one, in which case the
- lists are merged. If the empty string is assigned to this option, the list of BSSID defined
- prior to this is reset.</para>
+ <varname>MACAddress=</varname>. This option may appear more than once, in which case the
+ lists are merged. If the empty string is assigned to this option, the list is reset.</para>
</listitem>
</varlistentry>
@@ -150,7 +144,7 @@
<refsect1>
<title>[Link] Section Options</title>
- <para> The <literal>[Link]</literal> section accepts the following keys:</para>
+ <para> The [Link] section accepts the following keys:</para>
<variablelist class='network-directives'>
<varlistentry>
@@ -211,7 +205,7 @@
<para>Link groups are similar to port ranges found in managed switches.
When network interfaces are added to a numbered group, operations on
all the interfaces from that group can be performed at once. An unsigned
- integer ranges 0 to 4294967294. Default to unset.</para>
+ integer in the range 0—4294967294. Defaults to unset.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -238,9 +232,95 @@
</refsect1>
<refsect1>
+ <title>[SR-IOV] Section Options</title>
+ <para>The [SR-IOV] section accepts the following keys. Specify several [SR-IOV] sections to configure
+ several SR-IOVs. SR-IOV provides the ability to partition a single physical PCI resource into virtual
+ PCI functions which can then be injected into a VM. In the case of network VFs, SR-IOV improves
+ north-south network performance (that is, traffic with endpoints outside the host machine) by allowing
+ traffic to bypass the host machine’s network stack.</para>
+
+ <variablelist class='network-directives'>
+ <varlistentry>
+ <term><varname>VirtualFunction=</varname></term>
+ <listitem>
+ <para>Specifies a Virtual Function (VF), lightweight PCIe function designed solely to move data
+ in and out. Takes an unsigned integer in the range 0..2147483646. This option is compulsory.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>VLANId=</varname></term>
+ <listitem>
+ <para>Specifies VLAN ID of the virtual function. Takes an unsigned integer in the range 1..4095.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>QualityOfService=</varname></term>
+ <listitem>
+ <para>Specifies quality of service of the virtual function. Takes an unsigned integer in the range 1..4294967294.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>VLANProtocol=</varname></term>
+ <listitem>
+ <para>Specifies VLAN protocol of the virtual function. Takes <literal>802.1Q</literal> or
+ <literal>802.1ad</literal>.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>MACSpoofCheck=</varname></term>
+ <listitem>
+ <para>Takes a boolean. Controls the MAC spoof checking. When unset, the kernel's default will be used.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>QueryReceiveSideScaling=</varname></term>
+ <listitem>
+ <para>Takes a boolean. Toggle the ability of querying the receive side scaling (RSS)
+ configuration of the virtual function (VF). The VF RSS information like RSS hash key may be
+ considered sensitive on some devices where this information is shared between VF and the
+ physical function (PF). When unset, the kernel's default will be used.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>Trust=</varname></term>
+ <listitem>
+ <para>Takes a boolean. Allows to set trust mode of the virtual function (VF). When set, VF
+ users can set a specific feature which may impact security and/or performance. When unset,
+ the kernel's default will be used.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>LinkState=</varname></term>
+ <listitem>
+ <para>Allows to set the link state of the virtual function (VF). Takes a boolean or a
+ special value <literal>auto</literal>. Setting to <literal>auto</literal> means a
+ reflection of the physical function (PF) link state, <literal>yes</literal> lets the VF to
+ communicate with other VFs on this host even if the PF link state is down,
+ <literal>no</literal> causes the hardware to drop any packets sent by the VF. When unset,
+ the kernel's default will be used.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>MACAddress=</varname></term>
+ <listitem>
+ <para>Specifies the MAC address for the virtual function.</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
<title>[Network] Section Options</title>
- <para>The <literal>[Network]</literal> section accepts the following keys:</para>
+ <para>The [Network] section accepts the following keys:</para>
<variablelist class='network-directives'>
<varlistentry>
@@ -269,16 +349,15 @@
specified through DHCP is not used for name resolution.
See option <option>UseDomains=</option> below.</para>
- <para>See the <literal>[DHCPv4]</literal> or <literal>[DHCPv6]</literal> section below for
- further configuration options for the DHCP client support.</para>
+ <para>See the [DHCPv4] or [DHCPv6] sections below for further configuration options for the DHCP
+ client support.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>DHCPServer=</varname></term>
<listitem>
<para>Takes a boolean. If set to <literal>yes</literal>, DHCPv4 server will be started. Defaults
- to <literal>no</literal>. Further settings for the DHCP
- server may be set in the <literal>[DHCPServer]</literal>
+ to <literal>no</literal>. Further settings for the DHCP server may be set in the [DHCPServer]
section described below.</para>
</listitem>
</varlistentry>
@@ -408,10 +487,8 @@
<varlistentry>
<term><varname>DNSSEC=</varname></term>
<listitem>
- <para>Takes a boolean. or
- <literal>allow-downgrade</literal>. When true, enables
- <ulink
- url="https://tools.ietf.org/html/rfc4033">DNSSEC</ulink>
+ <para>Takes a boolean or <literal>allow-downgrade</literal>. When true, enables
+ <ulink url="https://tools.ietf.org/html/rfc4033">DNSSEC</ulink>
DNS validation support on the link. When set to
<literal>allow-downgrade</literal>, compatibility with
non-DNSSEC capable networks is increased, by automatically
@@ -643,8 +720,8 @@
forwarding is enabled, and to enable it otherwise. Cannot be enabled on bond devices and when link
local addressing is disabled.</para>
- <para>Further settings for the IPv6 RA support may be configured in the
- <literal>[IPv6AcceptRA]</literal> section, see below.</para>
+ <para>Further settings for the IPv6 RA support may be configured in the [IPv6AcceptRA] section, see
+ below.</para>
<para>Also see <ulink
url="https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt">ip-sysctl.txt</ulink> in the kernel
@@ -683,7 +760,7 @@
<term><varname>IPv4ProxyARP=</varname></term>
<listitem><para>Takes a boolean. Configures proxy ARP for IPv4. Proxy ARP is the technique in which one host,
usually a router, answers ARP requests intended for another machine. By "faking" its identity,
- the router accepts responsibility for routing packets to the "real" destination. (see <ulink
+ the router accepts responsibility for routing packets to the "real" destination. See <ulink
url="https://tools.ietf.org/html/rfc1027">RFC 1027</ulink>.
When unset, the kernel's default will be used.
</para></listitem>
@@ -714,18 +791,15 @@
</varlistentry>
<varlistentry>
<term><varname>IPv6PrefixDelegation=</varname></term>
- <listitem><para>Whether to enable or disable Router Advertisement sending on a link.
- Allowed values are <literal>static</literal> which distributes prefixes as defined in
- the <literal>[IPv6PrefixDelegation]</literal> and any <literal>[IPv6Prefix]</literal>
- sections, <literal>dhcpv6</literal> which requests prefixes using a DHCPv6 client
- configured for another link and any values configured in the
- <literal>[IPv6PrefixDelegation]</literal> section while ignoring all static prefix
- configuration sections, <literal>yes</literal> which uses both static configuration
- and DHCPv6, and <literal>false</literal> which turns off IPv6 prefix delegation
- altogether. Defaults to <literal>false</literal>. See the
- <literal>[IPv6PrefixDelegation]</literal> and the <literal>[IPv6Prefix]</literal>
- sections for more configuration options.
- </para></listitem>
+ <listitem><para>Whether to enable or disable Router Advertisement sending on a link. Allowed
+ values are <literal>static</literal> which distributes prefixes as defined in the
+ [IPv6PrefixDelegation] and any [IPv6Prefix] sections, <literal>dhcpv6</literal> which requests
+ prefixes using a DHCPv6 client configured for another link and any values configured in the
+ [IPv6PrefixDelegation] section while ignoring all static prefix configuration sections,
+ <literal>yes</literal> which uses both static configuration and DHCPv6, and
+ <literal>false</literal> which turns off IPv6 prefix delegation altogether. Defaults to
+ <literal>false</literal>. See the [IPv6PrefixDelegation] and the [IPv6Prefix] sections for more
+ configuration options.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>IPv6PDSubnetId=</varname></term>
@@ -891,16 +965,15 @@
<refsect1>
<title>[Address] Section Options</title>
- <para>An <literal>[Address]</literal> section accepts the
- following keys. Specify several <literal>[Address]</literal>
+ <para>An [Address] section accepts the following keys. Specify several [Address]
sections to configure several addresses.</para>
<variablelist class='network-directives'>
<varlistentry>
<term><varname>Address=</varname></term>
<listitem>
- <para>As in the <literal>[Network]</literal> section. This key is mandatory. Each
- <literal>[Address]</literal> section can contain one <varname>Address=</varname> setting.</para>
+ <para>As in the [Network] section. This key is mandatory. Each [Address] section can contain one
+ <varname>Address=</varname> setting.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -944,7 +1017,7 @@
<term><varname>Scope=</varname></term>
<listitem>
<para>The scope of the address, which can be <literal>global</literal>,
- <literal>link</literal> or <literal>host</literal> or an unsigned integer ranges 0 to 255.
+ <literal>link</literal> or <literal>host</literal> or an unsigned integer in the range 0—255.
Defaults to <literal>global</literal>.</para>
</listitem>
</varlistentry>
@@ -1006,12 +1079,10 @@
<refsect1>
<title>[Neighbor] Section Options</title>
- <para>A <literal>[Neighbor]</literal> section accepts the
- following keys. The neighbor section adds a permanent, static
- entry to the neighbor table (IPv6) or ARP table (IPv4) for
- the given hardware address on the links matched for the network.
- Specify several <literal>[Neighbor]</literal> sections to configure
- several static neighbors.</para>
+ <para>A [Neighbor] section accepts the following keys. The neighbor section adds a permanent, static
+ entry to the neighbor table (IPv6) or ARP table (IPv4) for the given hardware address on the links
+ matched for the network. Specify several [Neighbor] sections to configure several static neighbors.
+ </para>
<variablelist class='network-directives'>
<varlistentry>
@@ -1032,18 +1103,17 @@
<refsect1>
<title>[IPv6AddressLabel] Section Options</title>
- <para>An <literal>[IPv6AddressLabel]</literal> section accepts the
- following keys. Specify several <literal>[IPv6AddressLabel]</literal>
- sections to configure several address labels. IPv6 address labels are
- used for address selection. See <ulink url="https://tools.ietf.org/html/rfc3484">RFC 3484</ulink>.
- Precedence is managed by userspace, and only the label itself is stored in the kernel</para>
+ <para>An [IPv6AddressLabel] section accepts the following keys. Specify several [IPv6AddressLabel]
+ sections to configure several address labels. IPv6 address labels are used for address selection. See
+ <ulink url="https://tools.ietf.org/html/rfc3484">RFC 3484</ulink>. Precedence is managed by userspace,
+ and only the label itself is stored in the kernel</para>
<variablelist class='network-directives'>
<varlistentry>
<term><varname>Label=</varname></term>
<listitem>
- <para> The label for the prefix (an unsigned integer) ranges 0 to 4294967294.
- 0xffffffff is reserved. This key is mandatory.</para>
+ <para>The label for the prefix, an unsigned integer in the range 0–4294967294.
+ 0xffffffff is reserved. This setting is mandatory.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -1059,15 +1129,14 @@
<refsect1>
<title>[RoutingPolicyRule] Section Options</title>
- <para>An <literal>[RoutingPolicyRule]</literal> section accepts the
- following keys. Specify several <literal>[RoutingPolicyRule]</literal>
+ <para>An [RoutingPolicyRule] section accepts the following keys. Specify several [RoutingPolicyRule]
sections to configure several rules.</para>
<variablelist class='network-directives'>
<varlistentry>
<term><varname>TypeOfService=</varname></term>
<listitem>
- <para>Specifies the type of service to match a number between 0 to 255.</para>
+ <para>Takes a number between 0 and 255 that specifies the type of service to match.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -1174,16 +1243,15 @@
<refsect1>
<title>[NextHop] Section Options</title>
- <para>The <literal>[NextHop]</literal> section accepts the
- following keys. Specify several <literal>[NextHop]</literal>
- sections to configure several nexthop. Nexthop is used to manipulate entries in the kernel's nexthop
- tables.</para>
+ <para>The [NextHop] section is used to manipulate entries in the kernel's "nexthop" tables. The
+ [NextHop] section accepts the following keys. Specify several [NextHop] sections to configure several
+ hops.</para>
<variablelist class='network-directives'>
<varlistentry>
<term><varname>Gateway=</varname></term>
<listitem>
- <para>As in the <literal>[Network]</literal> section. This is mandatory.</para>
+ <para>As in the [Network] section. This is mandatory.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -1197,9 +1265,8 @@
<refsect1>
<title>[Route] Section Options</title>
- <para>The <literal>[Route]</literal> section accepts the
- following keys. Specify several <literal>[Route]</literal>
- sections to configure several routes.</para>
+ <para>The [Route] section accepts the following keys. Specify several [Route] sections to configure
+ several routes.</para>
<variablelist class='network-directives'>
<varlistentry>
@@ -1246,10 +1313,10 @@
<term><varname>IPv6Preference=</varname></term>
<listitem>
<para>Specifies the route preference as defined in <ulink
- url="https://tools.ietf.org/html/rfc4191">RFC4191</ulink> for Router Discovery messages.
- Which can be one of <literal>low</literal> the route has a lowest priority,
- <literal>medium</literal> the route has a default priority or
- <literal>high</literal> the route has a highest priority.</para>
+ url="https://tools.ietf.org/html/rfc4191">RFC 4191</ulink> for Router Discovery messages. Which
+ can be one of <literal>low</literal> the route has a lowest priority, <literal>medium</literal>
+ the route has a default priority or <literal>high</literal> the route has a highest priority.
+ </para>
</listitem>
</varlistentry>
<varlistentry>
@@ -1384,8 +1451,7 @@
<refsect1>
<title>[DHCPv4] Section Options</title>
- <para>The <literal>[DHCPv4]</literal> section configures the
- DHCPv4 client, if it is enabled with the
+ <para>The [DHCPv4] section configures the DHCPv4 client, if it is enabled with the
<varname>DHCP=</varname> setting described above:</para>
<variablelist class='network-directives'>
@@ -1630,8 +1696,8 @@
<para>The table identifier for DHCP routes (a number between 1 and 4294967295, or 0 to unset).
The table can be retrieved using <command>ip route show table <replaceable>num</replaceable></command>.
</para>
- <para>When used in combination with <varname>VRF=</varname> the
- VRF's routing table is used unless this parameter is specified.
+ <para>When used in combination with <varname>VRF=</varname>, the
+ VRF's routing table is used when this parameter is not specified.
</para>
</listitem>
</varlistentry>
@@ -1670,18 +1736,27 @@
<varlistentry>
<term><varname>SendDecline=</varname></term>
<listitem>
- <para>A boolean. When <literal>true</literal>, DHCPv4 clients receives IP address from DHCP server.
- After new IP is received, DHCPv4 performs IPv4 Duplicate Address Detection. If duplicate use of IP is detected
- the DHCPv4 client rejects the IP by sending a DHCPDECLINE packet DHCP clients try to obtain an IP address again.
- See <ulink url="https://tools.ietf.org/html/rfc5227">RFC 5224</ulink>.
- Defaults to <literal>unset</literal>.</para>
+ <para>A boolean. When <literal>true</literal>, the DHCPv4 client receives the IP address from the
+ DHCP server. After a new IP is received, the DHCPv4 client performs IPv4 Duplicate Address
+ Detection. If duplicate use is detected, the DHCPv4 client rejects the IP by sending a
+ DHCPDECLINE packet and tries to obtain an IP address again. See <ulink
+ url="https://tools.ietf.org/html/rfc5227">RFC 5224</ulink>. Defaults to
+ <literal>unset</literal>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>DenyList=</varname></term>
<listitem>
- <para>A whitespace-separated list of IPv4 addresses. DHCP offers from servers in the list are rejected.</para>
+ <para>A whitespace-separated list of IPv4 addresses. DHCP offers from servers in the list are rejected. Note that
+ if <varname>AllowList=</varname> is configured then <varname>DenyList=</varname> is ignored.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><varname>AllowList=</varname></term>
+ <listitem>
+ <para>A whitespace-separated list of IPv4 addresses. DHCP offers from servers in the list are accepted.</para>
</listitem>
</varlistentry>
@@ -1727,7 +1802,7 @@
<refsect1>
<title>[DHCPv6] Section Options</title>
- <para>The <literal>[DHCPv6]</literal> section configures the DHCPv6 client, if it is enabled with the
+ <para>The [DHCPv6] section configures the DHCPv6 client, if it is enabled with the
<varname>DHCP=</varname> setting described above, or invoked by the IPv6 Router Advertisement:</para>
<variablelist class='network-directives'>
@@ -1735,7 +1810,7 @@
<term><varname>UseDNS=</varname></term>
<term><varname>UseNTP=</varname></term>
<listitem>
- <para>As in the <literal>[DHCPv4]</literal> section.</para>
+ <para>As in the [DHCPv4] section.</para>
</listitem>
</varlistentry>
@@ -1752,7 +1827,7 @@
<para>Takes a boolean. The DHCPv6 client can obtain configuration parameters from a DHCPv6 server through
a rapid two-message exchange (solicit and reply). When the rapid commit option is enabled by both
the DHCPv6 client and the DHCPv6 server, the two-message exchange is used, rather than the default
- four-method exchange (solicit, advertise, request, and reply). The two-message exchange provides
+ four-message exchange (solicit, advertise, request, and reply). The two-message exchange provides
faster client configuration and is beneficial in environments in which networks are under a heavy load.
See <ulink url="https://tools.ietf.org/html/rfc3315#section-17.2.1">RFC 3315</ulink> for details.
Defaults to true.</para>
@@ -1780,14 +1855,15 @@
<varlistentry>
<term><varname>SendVendorOption=</varname></term>
<listitem>
- <para>Send an arbitrary vendor option in the DHCPv6 request. Takes an enterprise identifier, DHCP option number,
- data type, and data separated with a colon
- (<literal><replaceable>enterprise identifier</replaceable>:<replaceable>option</replaceable>:<replaceable>type</replaceable>:
- <replaceable>value</replaceable></literal>). Enterprise identifier is an unsigned integer ranges 1..4294967294.
- The option number must be an integer in the range 1..254. Data type takes one of <literal>uint8</literal>,
- <literal>uint16</literal>, <literal>uint32</literal>, <literal>ipv4address</literal>, <literal>ipv6address</literal>, or
- <literal>string</literal>. Special characters in the data string may be escaped using
- <ulink url="https://en.wikipedia.org/wiki/Escape_sequences_in_C#Table_of_escape_sequences">C-style
+ <para>Send an arbitrary vendor option in the DHCPv6 request. Takes an enterprise identifier, DHCP
+ option number, data type, and data separated with a colon (<literal><replaceable>enterprise
+ identifier</replaceable>:<replaceable>option</replaceable>:<replaceable>type</replaceable>:
+ <replaceable>value</replaceable></literal>). Enterprise identifier is an unsigned integer in the
+ range 1–4294967294. The option number must be an integer in the range 1–254. Data type takes one
+ of <literal>uint8</literal>, <literal>uint16</literal>, <literal>uint32</literal>,
+ <literal>ipv4address</literal>, <literal>ipv6address</literal>, or
+ <literal>string</literal>. Special characters in the data string may be escaped using <ulink
+ url="https://en.wikipedia.org/wiki/Escape_sequences_in_C#Table_of_escape_sequences">C-style
escapes</ulink>. This setting can be specified multiple times. If an empty string is specified,
then all options specified earlier are cleared. Defaults to unset.</para>
</listitem>
@@ -1831,24 +1907,26 @@
<varlistentry>
<term><varname>PrefixDelegationHint=</varname></term>
<listitem>
- <para>Takes an IPv6 address with prefix length as <varname>Address=</varname> in
- the "[Network]" section. Specifies the DHCPv6 client for the requesting router to include
- a prefix-hint in the DHCPv6 solicitation. Prefix ranges 1..128. Defaults to unset.</para>
+ <para>Takes an IPv6 address with prefix length in the same format as the
+ <varname>Address=</varname> in the [Network] section. The DHCPv6 client will include a prefix
+ hint in the DHCPv6 solicitation sent to the server. The prefix length must be in the range
+ 1–128. Defaults to unset.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>WithoutRA=</varname></term>
<listitem>
- <para>When true, DHCPv6 client starts without router advertisements's managed or other address configuration flag.
- Defaults to false.</para>
+ <para>Allows DHCPv6 client to start without router advertisements's managed or other address
+ configuration flag. Takes one of <literal>solicit</literal> or
+ <literal>information-request</literal>. Defaults to unset.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>SendOption=</varname></term>
<listitem>
- <para>As in the <literal>[DHCPv4]</literal> section, however because DHCPv6 uses 16-bit fields to store
+ <para>As in the [DHCPv4] section, however because DHCPv6 uses 16-bit fields to store
option numbers, the option number is an integer in the range 1..65536.</para>
</listitem>
</varlistentry>
@@ -1882,9 +1960,8 @@
<refsect1>
<title>[IPv6AcceptRA] Section Options</title>
- <para>The <literal>[IPv6AcceptRA]</literal> section configures the IPv6 Router Advertisement
- (RA) client, if it is enabled with the <varname>IPv6AcceptRA=</varname> setting described
- above:</para>
+ <para>The [IPv6AcceptRA] section configures the IPv6 Router Advertisement (RA) client, if it is enabled
+ with the <varname>IPv6AcceptRA=</varname> setting described above:</para>
<variablelist class='network-directives'>
<varlistentry>
@@ -1964,8 +2041,7 @@
<refsect1>
<title>[DHCPServer] Section Options</title>
- <para>The <literal>[DHCPServer]</literal> section contains
- settings for the DHCP server, if enabled via the
+ <para>The [DHCPServer] section contains settings for the DHCP server, if enabled via the
<varname>DHCPServer=</varname> option described above:</para>
<variablelist class='network-directives'>
@@ -2099,11 +2175,9 @@
<refsect1>
<title>[IPv6PrefixDelegation] Section Options</title>
- <para>The <literal>[IPv6PrefixDelegation]</literal> section contains
- settings for sending IPv6 Router Advertisements and whether to act as
- a router, if enabled via the <varname>IPv6PrefixDelegation=</varname>
- option described above. IPv6 network prefixes are defined with one or
- more <literal>[IPv6Prefix]</literal> sections.</para>
+ <para>The [IPv6PrefixDelegation] section contains settings for sending IPv6 Router Advertisements and
+ whether to act as a router, if enabled via the <varname>IPv6PrefixDelegation=</varname> option described
+ above. IPv6 network prefixes are defined with one or more [IPv6Prefix] sections.</para>
<variablelist class='network-directives'>
@@ -2147,32 +2221,26 @@
<term><varname>EmitDNS=</varname></term>
<term><varname>DNS=</varname></term>
- <listitem><para><varname>DNS=</varname> specifies a list of recursive DNS server IPv6 addresses
- that are distributed via Router Advertisement messages when <varname>EmitDNS=</varname> is
- true. <varname>DNS=</varname> also takes special value <literal>_link_local</literal>; in that
- case the IPv6 link local address is distributed. If <varname>DNS=</varname> is empty, DNS
- servers are read from the <literal>[Network]</literal> section. If the
- <literal>[Network]</literal> section does not contain any DNS servers either, DNS servers from
- the uplink with the highest priority default route are used. When <varname>EmitDNS=</varname>
- is false, no DNS server information is sent in Router Advertisement messages.
- <varname>EmitDNS=</varname> defaults to true.
- </para></listitem>
+ <listitem><para><varname>DNS=</varname> specifies a list of recursive DNS server IPv6 addresses that
+ are distributed via Router Advertisement messages when <varname>EmitDNS=</varname> is
+ true. <varname>DNS=</varname> also takes special value <literal>_link_local</literal>; in that case
+ the IPv6 link local address is distributed. If <varname>DNS=</varname> is empty, DNS servers are read
+ from the [Network] section. If the [Network] section does not contain any DNS servers either, DNS
+ servers from the uplink with the highest priority default route are used. When
+ <varname>EmitDNS=</varname> is false, no DNS server information is sent in Router Advertisement
+ messages. <varname>EmitDNS=</varname> defaults to true.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>EmitDomains=</varname></term>
<term><varname>Domains=</varname></term>
- <listitem><para>A list of DNS search domains distributed via Router
- Advertisement messages when <varname>EmitDomains=</varname> is true. If
- <varname>Domains=</varname> is empty, DNS search domains are read from the
- <literal>[Network]</literal> section. If the <literal>[Network]</literal>
- section does not contain any DNS search domains either, DNS search
- domains from the uplink with the highest priority default route are
- used. When <varname>EmitDomains=</varname> is false, no DNS search domain
- information is sent in Router Advertisement messages.
- <varname>EmitDomains=</varname> defaults to true.
- </para></listitem>
+ <listitem><para>A list of DNS search domains distributed via Router Advertisement messages when
+ <varname>EmitDomains=</varname> is true. If <varname>Domains=</varname> is empty, DNS search domains
+ are read from the [Network] section. If the [Network] section does not contain any DNS search domains
+ either, DNS search domains from the uplink with the highest priority default route are used. When
+ <varname>EmitDomains=</varname> is false, no DNS search domain information is sent in Router
+ Advertisement messages. <varname>EmitDomains=</varname> defaults to true.</para></listitem>
</varlistentry>
<varlistentry>
@@ -2188,10 +2256,9 @@
<refsect1>
<title>[IPv6Prefix] Section Options</title>
- <para>One or more <literal>[IPv6Prefix]</literal> sections contain the IPv6
- prefixes that are announced via Router Advertisements. See
- <ulink url="https://tools.ietf.org/html/rfc4861">RFC 4861</ulink>
- for further details.</para>
+ <para>One or more [IPv6Prefix] sections contain the IPv6 prefixes that are announced via Router
+ Advertisements. See <ulink url="https://tools.ietf.org/html/rfc4861">RFC 4861</ulink> for further
+ details.</para>
<variablelist class='network-directives'>
@@ -2209,13 +2276,11 @@
<varlistentry>
<term><varname>Prefix=</varname></term>
- <listitem><para>The IPv6 prefix that is to be distributed to hosts.
- Similarly to configuring static IPv6 addresses, the setting is
- configured as an IPv6 prefix and its prefix length, separated by a
- <literal>/</literal> character. Use multiple
- <literal>[IPv6Prefix]</literal> sections to configure multiple IPv6
- prefixes since prefix lifetimes, address autoconfiguration and onlink
- status may differ from one prefix to another.</para></listitem>
+ <listitem><para>The IPv6 prefix that is to be distributed to hosts. Similarly to configuring static
+ IPv6 addresses, the setting is configured as an IPv6 prefix and its prefix length, separated by a
+ <literal>/</literal> character. Use multiple [IPv6Prefix] sections to configure multiple IPv6
+ prefixes since prefix lifetimes, address autoconfiguration and onlink status may differ from one
+ prefix to another.</para></listitem>
</varlistentry>
<varlistentry>
@@ -2238,7 +2303,7 @@
<refsect1>
<title>[IPv6RoutePrefix] Section Options</title>
- <para>One or more <literal>[IPv6RoutePrefix]</literal> sections contain the IPv6
+ <para>One or more [IPv6RoutePrefix] sections contain the IPv6
prefix routes that are announced via Router Advertisements. See
<ulink url="https://tools.ietf.org/html/rfc4191">RFC 4191</ulink>
for further details.</para>
@@ -2248,12 +2313,10 @@
<varlistentry>
<term><varname>Route=</varname></term>
- <listitem><para>The IPv6 route that is to be distributed to hosts.
- Similarly to configuring static IPv6 routes, the setting is
- configured as an IPv6 prefix routes and its prefix route length,
- separated by a<literal>/</literal> character. Use multiple
- <literal>[IPv6PrefixRoutes]</literal> sections to configure multiple IPv6
- prefix routes.</para></listitem>
+ <listitem><para>The IPv6 route that is to be distributed to hosts. Similarly to configuring static
+ IPv6 routes, the setting is configured as an IPv6 prefix routes and its prefix route length,
+ separated by a <literal>/</literal> character. Use multiple [IPv6PrefixRoutes] sections to configure
+ multiple IPv6 prefix routes.</para></listitem>
</varlistentry>
<varlistentry>
@@ -2269,8 +2332,7 @@
<refsect1>
<title>[Bridge] Section Options</title>
- <para>The <literal>[Bridge]</literal> section accepts the
- following keys.</para>
+ <para>The [Bridge] section accepts the following keys:</para>
<variablelist class='network-directives'>
<varlistentry>
<term><varname>UnicastFlood=</varname></term>
@@ -2318,10 +2380,9 @@
<varlistentry>
<term><varname>HairPin=</varname></term>
<listitem>
- <para>Takes a boolean. Configures whether traffic may be sent back
- out of the port on which it was received. When this flag is false, and the bridge
- will not forward traffic back out of the receiving port.
- When unset, the kernel's default will be used.</para>
+ <para>Takes a boolean. Configures whether traffic may be sent back out of the port on which it
+ was received. When this flag is false, then the bridge will not forward traffic back out of the
+ receiving port. When unset, the kernel's default will be used.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -2397,17 +2458,14 @@
</refsect1>
<refsect1>
<title>[BridgeFDB] Section Options</title>
- <para>The <literal>[BridgeFDB]</literal> section manages the
- forwarding database table of a port and accepts the following
- keys. Specify several <literal>[BridgeFDB]</literal> sections to
- configure several static MAC table entries.</para>
+ <para>The [BridgeFDB] section manages the forwarding database table of a port and accepts the following
+ keys. Specify several [BridgeFDB] sections to configure several static MAC table entries.</para>
<variablelist class='network-directives'>
<varlistentry>
<term><varname>MACAddress=</varname></term>
<listitem>
- <para>As in the <literal>[Network]</literal> section. This
- key is mandatory.</para>
+ <para>As in the [Network] section. This key is mandatory.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -2450,8 +2508,8 @@
<refsect1>
<title>[LLDP] Section Options</title>
- <para>The <literal>[LLDP]</literal> section manages the Link Layer Discovery Protocol (LLDP) and accepts the
- following keys.</para>
+ <para>The [LLDP] section manages the Link Layer Discovery Protocol (LLDP) and accepts the following
+ keys.</para>
<variablelist class='network-directives'>
<varlistentry>
<term><varname>MUDURL=</varname></term>
@@ -2472,8 +2530,8 @@
<refsect1>
<title>[CAN] Section Options</title>
- <para>The <literal>[CAN]</literal> section manages the Controller Area Network (CAN bus) and accepts the
- following keys.</para>
+ <para>The [CAN] section manages the Controller Area Network (CAN bus) and accepts the
+ following keys:</para>
<variablelist class='network-directives'>
<varlistentry>
<term><varname>BitRate=</varname></term>
@@ -2551,7 +2609,7 @@
<refsect1>
<title>[QDisc] Section Options</title>
- <para>The <literal>[QDisc]</literal> section manages the traffic control queueing discipline (qdisc).</para>
+ <para>The [QDisc] section manages the traffic control queueing discipline (qdisc).</para>
<variablelist class='network-directives'>
<varlistentry>
@@ -2568,10 +2626,10 @@
<refsect1>
<title>[NetworkEmulator] Section Options</title>
- <para>The <literal>[NetworkEmulator]</literal> section manages the queueing discipline (qdisc) of
- the network emulator. It can be used to configure the kernel packet scheduler and simulate packet
- delay and loss for UDP or TCP applications, or limit the bandwidth usage of a particular service to
- simulate internet connections.</para>
+ <para>The [NetworkEmulator] section manages the queueing discipline (qdisc) of the network emulator. It
+ can be used to configure the kernel packet scheduler and simulate packet delay and loss for UDP or TCP
+ applications, or limit the bandwidth usage of a particular service to simulate internet connections.
+ </para>
<variablelist class='network-directives'>
<xi:include href="tc.xml" xpointer="qdisc-parent" />
@@ -2597,7 +2655,7 @@
<term><varname>PacketLimit=</varname></term>
<listitem>
<para>Specifies the maximum number of packets the qdisc may hold queued at a time.
- An unsigned integer ranges 0 to 4294967294. Defaults to 1000.</para>
+ An unsigned integer in the range 0–4294967294. Defaults to 1000.</para>
</listitem>
</varlistentry>
@@ -2621,8 +2679,8 @@
<refsect1>
<title>[TokenBucketFilter] Section Options</title>
- <para>The <literal>[TokenBucketFilter]</literal> section manages the queueing discipline (qdisc) of
- token bucket filter (tbf).</para>
+ <para>The [TokenBucketFilter] section manages the queueing discipline (qdisc) of token bucket filter
+ (tbf).</para>
<variablelist class='network-directives'>
<xi:include href="tc.xml" xpointer="qdisc-parent" />
@@ -2637,20 +2695,20 @@
</varlistentry>
<varlistentry>
- <term><varname>LimitSize=</varname></term>
+ <term><varname>LimitBytes=</varname></term>
<listitem>
<para>Takes the number of bytes that can be queued waiting for tokens to become available.
When the size is suffixed with K, M, or G, it is parsed as Kilobytes, Megabytes, or Gigabytes,
- respectively, to the base of 1000. Defaults to unset.</para>
+ respectively, to the base of 1024. Defaults to unset.</para>
</listitem>
</varlistentry>
<varlistentry>
- <term><varname>Burst=</varname></term>
+ <term><varname>BurstBytes=</varname></term>
<listitem>
<para>Specifies the size of the bucket. This is the maximum amount of bytes that tokens
can be available for instantaneous transfer. When the size is suffixed with K, M, or G, it is
- parsed as Kilobytes, Megabytes, or Gigabytes, respectively, to the base of 1000. Defaults to
+ parsed as Kilobytes, Megabytes, or Gigabytes, respectively, to the base of 1024. Defaults to
unset.</para>
</listitem>
</varlistentry>
@@ -2669,7 +2727,7 @@
<listitem>
<para>The Minimum Packet Unit (MPU) determines the minimal token usage (specified in bytes)
for a packet. When suffixed with K, M, or G, the specified size is parsed as Kilobytes,
- Megabytes, or Gigabytes, respectively, to the base of 1000. Defaults to zero.</para>
+ Megabytes, or Gigabytes, respectively, to the base of 1024. Defaults to zero.</para>
</listitem>
</varlistentry>
@@ -2686,7 +2744,7 @@
<term><varname>MTUBytes=</varname></term>
<listitem>
<para>Specifies the size of the peakrate bucket. When suffixed with K, M, or G, the specified
- size is parsed as Kilobytes, Megabytes, or Gigabytes, respectively, to the base of 1000.
+ size is parsed as Kilobytes, Megabytes, or Gigabytes, respectively, to the base of 1024.
Defaults to unset.</para>
</listitem>
</varlistentry>
@@ -2695,8 +2753,8 @@
<refsect1>
<title>[PIE] Section Options</title>
- <para>The <literal>[PIE]</literal> section manages the queueing discipline
- (qdisc) of Proportional Integral controller-Enhanced (PIE).</para>
+ <para>The [PIE] section manages the queueing discipline (qdisc) of Proportional Integral
+ controller-Enhanced (PIE).</para>
<variablelist class='network-directives'>
<xi:include href="tc.xml" xpointer="qdisc-parent" />
@@ -2706,7 +2764,7 @@
<term><varname>PacketLimit=</varname></term>
<listitem>
<para>Specifies the hard limit on the queue size in number of packets. When this limit is reached, incoming packets are
- dropped. An unsigned integer ranges 1 to 4294967294. Defaults to unset and kernel's default is used.</para>
+ dropped. An unsigned integer in the range 1–4294967294. Defaults to unset and kernel's default is used.</para>
</listitem>
</varlistentry>
</variablelist>
@@ -2714,8 +2772,8 @@
<refsect1>
<title>[StochasticFairBlue] Section Options</title>
- <para>The <literal>[StochasticFairBlue]</literal> section manages the queueing discipline
- (qdisc) of stochastic fair blue (sfb).</para>
+ <para>The [StochasticFairBlue] section manages the queueing discipline (qdisc) of stochastic fair blue
+ (sfb).</para>
<variablelist class='network-directives'>
<xi:include href="tc.xml" xpointer="qdisc-parent" />
@@ -2724,8 +2782,9 @@
<varlistentry>
<term><varname>PacketLimit=</varname></term>
<listitem>
- <para>Specifies the hard limit on the queue size in number of packets. When this limit is reached, incoming packets are
- dropped. An unsigned integer ranges 0 to 4294967294. Defaults to unset and kernel's default is used.</para>
+ <para>Specifies the hard limit on the queue size in number of packets. When this limit is reached,
+ incoming packets are dropped. An unsigned integer in the range 0–4294967294. Defaults to unset and
+ kernel's default is used.</para>
</listitem>
</varlistentry>
</variablelist>
@@ -2733,8 +2792,8 @@
<refsect1>
<title>[StochasticFairnessQueueing] Section Options</title>
- <para>The <literal>[StochasticFairnessQueueing]</literal> section manages the queueing discipline
- (qdisc) of stochastic fairness queueing (sfq).</para>
+ <para>The [StochasticFairnessQueueing] section manages the queueing discipline (qdisc) of stochastic
+ fairness queueing (sfq).</para>
<variablelist class='network-directives'>
<xi:include href="tc.xml" xpointer="qdisc-parent" />
@@ -2751,20 +2810,21 @@
<refsect1>
<title>[BFIFO] Section Options</title>
- <para>The <literal>[BFIFO]</literal> section manages the queueing discipline (qdisc) of
- Byte limited Packet First In First Out (bfifo).</para>
+ <para>The [BFIFO] section manages the queueing discipline (qdisc) of Byte limited Packet First In First
+ Out (bfifo).</para>
<variablelist class='network-directives'>
<xi:include href="tc.xml" xpointer="qdisc-parent" />
<xi:include href="tc.xml" xpointer="qdisc-handle" />
<varlistentry>
- <term><varname>LimitSize=</varname></term>
+ <term><varname>LimitBytes=</varname></term>
<listitem>
- <para>Specifies the hard limit on the FIFO size in bytes. The size limit (a buffer size) to prevent it
- from overflowing in case it is unable to dequeue packets as quickly as it receives them. When this limit
- is reached, incoming packets are dropped. When suffixed with K, M, or G, the specified size is parsed as
- Kilobytes, Megabytes, or Gigabytes, respectively, to the base of 1024. Defaults to unset and kernel's default is used.</para>
+ <para>Specifies the hard limit on the FIFO size in bytes. The size limit (a buffer size) to prevent
+ it from overflowing in case it is unable to dequeue packets as quickly as it receives them. When
+ this limit is reached, incoming packets are dropped. When suffixed with K, M, or G, the specified
+ size is parsed as Kilobytes, Megabytes, or Gigabytes, respectively, to the base of 1024. Defaults
+ to unset and kernel's default is used.</para>
</listitem>
</varlistentry>
</variablelist>
@@ -2772,8 +2832,8 @@
<refsect1>
<title>[PFIFO] Section Options</title>
- <para>The <literal>[PFIFO]</literal> section manages the queueing discipline (qdisc) of
- Packet First In First Out (pfifo).</para>
+ <para>The [PFIFO] section manages the queueing discipline (qdisc) of Packet First In First Out
+ (pfifo).</para>
<variablelist class='network-directives'>
<xi:include href="tc.xml" xpointer="qdisc-parent" />
@@ -2782,9 +2842,10 @@
<varlistentry>
<term><varname>PacketLimit=</varname></term>
<listitem>
- <para>Specifies the hard limit on the FIFO size in number of packets. The size limit (a buffer size) to prevent it
- from overflowing in case it is unable to dequeue packets as quickly as it receives them. When this limit is reached,
- incoming packets are dropped. An unsigned integer ranges 0 to 4294967294. Defaults to unset and kernel's default is used.</para>
+ <para>Specifies the hard limit on the FIFO size in number of packets. The size limit (a buffer
+ size) to prevent it from overflowing in case it is unable to dequeue packets as quickly as it
+ receives them. When this limit is reached, incoming packets are dropped. An unsigned integer in the
+ range 0–4294967294. Defaults to unset and kernel's default is used.</para>
</listitem>
</varlistentry>
</variablelist>
@@ -2792,8 +2853,8 @@
<refsect1>
<title>[PFIFOHeadDrop] Section Options</title>
- <para>The <literal>[PFIFOHeadDrop]</literal> section manages the queueing discipline (qdisc) of
- Packet First In First Out Head Drop (pfifo_head_drop).</para>
+ <para>The [PFIFOHeadDrop] section manages the queueing discipline (qdisc) of Packet First In First Out
+ Head Drop (pfifo_head_drop).</para>
<variablelist class='network-directives'>
<xi:include href="tc.xml" xpointer="qdisc-parent" />
@@ -2802,15 +2863,15 @@
<varlistentry>
<term><varname>PacketLimit=</varname></term>
<listitem>
- <para>As in <literal>[PFIFO]</literal> section.</para></listitem>
+ <para>As in [PFIFO] section.</para></listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>[PFIFOFast] Section Options</title>
- <para>The <literal>[PFIFOFast]</literal> section manages the queueing discipline (qdisc) of
- Packet First In First Out Fast (pfifo_fast).</para>
+ <para>The [PFIFOFast] section manages the queueing discipline (qdisc) of Packet First In First Out Fast
+ (pfifo_fast).</para>
<variablelist class='network-directives'>
<xi:include href="tc.xml" xpointer="qdisc-parent" />
@@ -2820,18 +2881,18 @@
<refsect1>
<title>[CAKE] Section Options</title>
- <para>The <literal>[CAKE]</literal> section manages the queueing discipline (qdisc) of
- Common Applications Kept Enhanced (CAKE).</para>
+ <para>The [CAKE] section manages the queueing discipline (qdisc) of Common Applications Kept Enhanced
+ (CAKE).</para>
<variablelist class='network-directives'>
<xi:include href="tc.xml" xpointer="qdisc-parent" />
<xi:include href="tc.xml" xpointer="qdisc-handle" />
<varlistentry>
- <term><varname>Overhead=</varname></term>
+ <term><varname>OverheadBytes=</varname></term>
<listitem>
- <para>Specifies that bytes to be addeded to the size of each packet. Bytes may be negative.
- Takes an integer ranges -64 to 256. Defaults to unset and kernel's default is used.</para>
+ <para>Specifies that bytes to be addeded to the size of each packet. Bytes may be negative. Takes
+ an integer in the range from -64 to 256. Defaults to unset and kernel's default is used.</para>
</listitem>
</varlistentry>
@@ -2848,7 +2909,7 @@
<refsect1>
<title>[ControlledDelay] Section Options</title>
- <para>The <literal>[ControlledDelay]</literal> section manages the queueing discipline (qdisc) of
+ <para>The [ControlledDelay] section manages the queueing discipline (qdisc) of
controlled delay (CoDel).</para>
<variablelist class='network-directives'>
@@ -2858,8 +2919,9 @@
<varlistentry>
<term><varname>PacketLimit=</varname></term>
<listitem>
- <para>Specifies the hard limit on the queue size in number of packets. When this limit is reached, incoming packets are
- dropped. An unsigned integer ranges 0 to 4294967294. Defaults to unset and kernel's default is used.</para>
+ <para>Specifies the hard limit on the queue size in number of packets. When this limit is reached,
+ incoming packets are dropped. An unsigned integer in the range 0–4294967294. Defaults to unset and
+ kernel's default is used.</para>
</listitem>
</varlistentry>
@@ -2899,8 +2961,8 @@
<refsect1>
<title>[DeficitRoundRobinScheduler] Section Options</title>
- <para>The <literal>[DeficitRoundRobinScheduler]</literal> section manages the queueing discipline (qdisc) of
- Deficit Round Robin Scheduler (DRR).</para>
+ <para>The [DeficitRoundRobinScheduler] section manages the queueing discipline (qdisc) of Deficit Round
+ Robin Scheduler (DRR).</para>
<variablelist class='network-directives'>
<xi:include href="tc.xml" xpointer="qdisc-parent" />
@@ -2910,19 +2972,20 @@
<refsect1>
<title>[DeficitRoundRobinSchedulerClass] Section Options</title>
- <para>The <literal>[DeficitRoundRobinSchedulerClass]</literal> section manages the traffic control class of
- Deficit Round Robin Scheduler (DRR).</para>
+ <para>The [DeficitRoundRobinSchedulerClass] section manages the traffic control class of Deficit Round
+ Robin Scheduler (DRR).</para>
<variablelist class='network-directives'>
<xi:include href="tc.xml" xpointer="tclass-parent" />
<xi:include href="tc.xml" xpointer="tclass-classid" />
<varlistentry>
- <term><varname>Quantum=</varname></term>
+ <term><varname>QuantumBytes=</varname></term>
<listitem>
- <para>Specifies the amount of bytes a flow is allowed to dequeue before the
- scheduler moves to the next class. An unsigned integer ranges 1 to 4294967294.
- Defaults to the MTU of the interface.</para>
+ <para>Specifies the amount of bytes a flow is allowed to dequeue before the scheduler moves
+ to the next class. When suffixed with K, M, or G, the specified size is parsed as Kilobytes,
+ Megabytes, or Gigabytes, respectively, to the base of 1024. Defaults to the MTU of the
+ interface.</para>
</listitem>
</varlistentry>
@@ -2931,8 +2994,8 @@
<refsect1>
<title>[EnhancedTransmissionSelection] Section Options</title>
- <para>The <literal>[EnhancedTransmissionSelection]</literal> section manages the queueing discipline (qdisc) of
- Enhanced Transmission Selection (ETS).</para>
+ <para>The [EnhancedTransmissionSelection] section manages the queueing discipline (qdisc) of Enhanced
+ Transmission Selection (ETS).</para>
<variablelist class='network-directives'>
<xi:include href="tc.xml" xpointer="qdisc-parent" />
@@ -2941,18 +3004,17 @@
<varlistentry>
<term><varname>Bands=</varname></term>
<listitem>
- <para>Specifies the number of bands. An unsigned integer ranges 1 to 16. This value has to be
- at least large enough to cover the strict bands specified through the
- <varname>StrictBands=</varname> and bandwidth-sharing bands specified in
- <varname>QuantumBytes=</varname>.</para>
+ <para>Specifies the number of bands. An unsigned integer in the range 1–16. This value has to be at
+ least large enough to cover the strict bands specified through the <varname>StrictBands=</varname>
+ and bandwidth-sharing bands specified in <varname>QuantumBytes=</varname>.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>StrictBands=</varname></term>
<listitem>
- <para>Specifies the number of bands that should be created in strict mode. An unsigned integer
- ranges 1 to 16.</para>
+ <para>Specifies the number of bands that should be created in strict mode. An unsigned integer in
+ the range 1–16.</para>
</listitem>
</varlistentry>
@@ -2983,8 +3045,8 @@
<refsect1>
<title>[GenericRandomEarlyDetection] Section Options</title>
- <para>The <literal>[GenericRandomEarlyDetection]</literal> section manages the queueing discipline
- (qdisc) of Generic Random Early Detection (GRED).</para>
+ <para>The [GenericRandomEarlyDetection] section manages the queueing discipline (qdisc) of Generic Random
+ Early Detection (GRED).</para>
<variablelist class='network-directives'>
<xi:include href="tc.xml" xpointer="qdisc-parent" />
@@ -3017,8 +3079,8 @@
<refsect1>
<title>[FairQueueingControlledDelay] Section Options</title>
- <para>The <literal>[FairQueueingControlledDelay]</literal> section manages the queueing discipline
- (qdisc) of fair queuing controlled delay (FQ-CoDel).</para>
+ <para>The [FairQueueingControlledDelay] section manages the queueing discipline (qdisc) of fair queuing
+ controlled delay (FQ-CoDel).</para>
<variablelist class='network-directives'>
<xi:include href="tc.xml" xpointer="qdisc-parent" />
@@ -3033,7 +3095,7 @@
</varlistentry>
<varlistentry>
- <term><varname>MemoryLimit=</varname></term>
+ <term><varname>MemoryLimitBytes=</varname></term>
<listitem>
<para>Specifies the limit on the total number of bytes that can be queued in this FQ-CoDel instance.
When suffixed with K, M, or G, the specified size is parsed as Kilobytes, Megabytes, or Gigabytes,
@@ -3066,9 +3128,9 @@
</varlistentry>
<varlistentry>
- <term><varname>Quantum=</varname></term>
+ <term><varname>QuantumBytes=</varname></term>
<listitem>
- <para>Specifies the number of bytes used as 'deficit' in the fair queuing algorithmtimespan.
+ <para>Specifies the number of bytes used as the "deficit" in the fair queuing algorithm timespan.
When suffixed with K, M, or G, the specified size is parsed as Kilobytes, Megabytes, or Gigabytes,
respectively, to the base of 1024. Defaults to unset and kernel's default is used.</para>
</listitem>
@@ -3094,8 +3156,8 @@
<refsect1>
<title>[FairQueueing] Section Options</title>
- <para>The <literal>[FairQueueing]</literal> section manages the queueing discipline
- (qdisc) of fair queue traffic policing (FQ).</para>
+ <para>The [FairQueueing] section manages the queueing discipline (qdisc) of fair queue traffic policing
+ (FQ).</para>
<variablelist class='network-directives'>
<xi:include href="tc.xml" xpointer="qdisc-parent" />
@@ -3118,7 +3180,7 @@
</varlistentry>
<varlistentry>
- <term><varname>Quantum=</varname></term>
+ <term><varname>QuantumBytes=</varname></term>
<listitem>
<para>Specifies the credit per dequeue RR round, i.e. the amount of bytes a flow is allowed
to dequeue at once. When suffixed with K, M, or G, the specified size is parsed as Kilobytes,
@@ -3128,7 +3190,7 @@
</varlistentry>
<varlistentry>
- <term><varname>InitialQuantum=</varname></term>
+ <term><varname>InitialQuantumBytes=</varname></term>
<listitem>
<para>Specifies the initial sending rate credit, i.e. the amount of bytes a new flow is
allowed to dequeue initially. When suffixed with K, M, or G, the specified size is parsed as
@@ -3183,8 +3245,8 @@
<refsect1>
<title>[TrivialLinkEqualizer] Section Options</title>
- <para>The <literal>[TrivialLinkEqualizer]</literal> section manages the queueing discipline (qdisc) of
- trivial link equalizer (teql).</para>
+ <para>The [TrivialLinkEqualizer] section manages the queueing discipline (qdisc) of trivial link
+ equalizer (teql).</para>
<variablelist class='network-directives'>
<xi:include href="tc.xml" xpointer="qdisc-parent" />
@@ -3204,8 +3266,8 @@
<refsect1>
<title>[HierarchyTokenBucket] Section Options</title>
- <para>The <literal>[HierarchyTokenBucket]</literal> section manages the queueing discipline (qdisc) of
- hierarchy token bucket (htb).</para>
+ <para>The [HierarchyTokenBucket] section manages the queueing discipline (qdisc) of hierarchy token
+ bucket (htb).</para>
<variablelist class='network-directives'>
<xi:include href="tc.xml" xpointer="qdisc-parent" />
@@ -3231,8 +3293,8 @@
<refsect1>
<title>[HierarchyTokenBucketClass] Section Options</title>
- <para>The <literal>[HierarchyTokenBucketClass]</literal> section manages the traffic control class of
- hierarchy token bucket (htb).</para>
+ <para>The [HierarchyTokenBucketClass] section manages the traffic control class of hierarchy token bucket
+ (htb).</para>
<variablelist class='network-directives'>
<xi:include href="tc.xml" xpointer="tclass-parent" />
@@ -3313,8 +3375,8 @@
<refsect1>
<title>[HeavyHitterFilter] Section Options</title>
- <para>The <literal>[HeavyHitterFilter]</literal> section manages the queueing discipline
- (qdisc) of Heavy Hitter Filter (hhf).</para>
+ <para>The [HeavyHitterFilter] section manages the queueing discipline (qdisc) of Heavy Hitter Filter
+ (hhf).</para>
<variablelist class='network-directives'>
<xi:include href="tc.xml" xpointer="qdisc-parent" />
@@ -3323,8 +3385,9 @@
<varlistentry>
<term><varname>PacketLimit=</varname></term>
<listitem>
- <para>Specifies the hard limit on the queue size in number of packets. When this limit is reached, incoming packets are
- dropped. An unsigned integer ranges 0 to 4294967294. Defaults to unset and kernel's default is used.</para>
+ <para>Specifies the hard limit on the queue size in number of packets. When this limit is reached,
+ incoming packets are dropped. An unsigned integer in the range 0–4294967294. Defaults to unset and
+ kernel's default is used.</para>
</listitem>
</varlistentry>
</variablelist>
@@ -3332,8 +3395,8 @@
<refsect1>
<title>[QuickFairQueueing] Section Options</title>
- <para>The <literal>[QuickFairQueueing]</literal> section manages the queueing discipline
- (qdisc) of Quick Fair Queueing (QFQ).</para>
+ <para>The [QuickFairQueueing] section manages the queueing discipline (qdisc) of Quick Fair Queueing
+ (QFQ).</para>
<variablelist class='network-directives'>
<xi:include href="tc.xml" xpointer="qdisc-parent" />
@@ -3343,8 +3406,8 @@
<refsect1>
<title>[QuickFairQueueingClass] Section Options</title>
- <para>The <literal>[QuickFairQueueingClass]</literal> section manages the traffic control class of
- Quick Fair Queueing (qfq).</para>
+ <para>The [QuickFairQueueingClass] section manages the traffic control class of Quick Fair Queueing
+ (qfq).</para>
<variablelist class='network-directives'>
<xi:include href="tc.xml" xpointer="tclass-parent" />
@@ -3359,10 +3422,10 @@
</varlistentry>
<varlistentry>
- <term><varname>MaxPacketSize=</varname></term>
+ <term><varname>MaxPacketBytes=</varname></term>
<listitem>
<para>Specifies the maximum packet size in bytes for the class. When suffixed with K, M, or G, the specified
- size is parsed as Kilobytes, Megabytes, or Gigabytes, respectively, to the base of 1000. When unset,
+ size is parsed as Kilobytes, Megabytes, or Gigabytes, respectively, to the base of 1024. When unset,
the kernel default is used.</para>
</listitem>
</varlistentry>
@@ -3371,9 +3434,9 @@
<refsect1>
<title>[BridgeVLAN] Section Options</title>
- <para>The <literal>[BridgeVLAN]</literal> section manages the VLAN ID configuration of a bridge port and accepts
- the following keys. Specify several <literal>[BridgeVLAN]</literal> sections to configure several VLAN entries.
- The <varname>VLANFiltering=</varname> option has to be enabled, see <literal>[Bridge]</literal> section in
+ <para>The [BridgeVLAN] section manages the VLAN ID configuration of a bridge port and accepts the
+ following keys. Specify several [BridgeVLAN] sections to configure several VLAN entries. The
+ <varname>VLANFiltering=</varname> option has to be enabled, see the [Bridge] section in
<citerefentry><refentrytitle>systemd.netdev</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
<variablelist class='network-directives'>
diff --git a/man/systemd.nspawn.xml b/man/systemd.nspawn.xml
index 27eae50b51..4b37c5dc44 100644
--- a/man/systemd.nspawn.xml
+++ b/man/systemd.nspawn.xml
@@ -80,7 +80,7 @@
<refsect1>
<title>[Exec] Section Options</title>
- <para>Settings files may include an <literal>[Exec]</literal>
+ <para>Settings files may include an [Exec]
section, which carries various execution parameters:</para>
<variablelist class='nspawn-directives'>
@@ -344,7 +344,7 @@
<refsect1>
<title>[Files] Section Options</title>
- <para>Settings files may include a <literal>[Files]</literal>
+ <para>Settings files may include a [Files]
section, which carries various parameters configuring the file
system of the container:</para>
@@ -405,7 +405,7 @@
<varlistentry>
<term><varname>Inaccessible=</varname></term>
- <listitem><para>Masks the specified file or directly in the container, by over-mounting it with an empty file
+ <listitem><para>Masks the specified file or directory in the container, by over-mounting it with an empty file
node of the same type with the most restrictive access mode. Takes a file system path as argument. This option
may be used multiple times to mask multiple files or directories. This option is equivalent to the command line
switch <option>--inaccessible=</option>, see
@@ -439,7 +439,7 @@
<refsect1>
<title>[Network] Section Options</title>
- <para>Settings files may include a <literal>[Network]</literal>
+ <para>Settings files may include a [Network]
section, which carries various parameters configuring the network
connectivity of the container:</para>
diff --git a/man/systemd.offline-updates.xml b/man/systemd.offline-updates.xml
index 89c12b598b..81a37f6789 100644
--- a/man/systemd.offline-updates.xml
+++ b/man/systemd.offline-updates.xml
@@ -33,7 +33,7 @@
<orderedlist>
<listitem>
- <para>The package manager prepares system updates by downloading all (RPM or DEB or
+ <para>The package manager prepares system updates by downloading all (.rpm or .deb or
whatever) packages to update off-line in a special directory
<filename index="false">/var/lib/system-update</filename> (or
another directory of the package/upgrade manager's choice).</para>
@@ -85,8 +85,8 @@
</listitem>
<listitem>
- <para>The upgrade scripts should exit only after the update is finished. It is expected
- that the service which performs the upgrade will cause the machine to reboot after it
+ <para>The update scripts should exit only after the update is finished. It is expected
+ that the service which performs the update will cause the machine to reboot after it
is done. If the <filename>system-update.target</filename> is successfully reached, i.e.
all update services have run, and the <filename>/system-update</filename> symlink still
exists, it will be removed and the machine rebooted as a safety measure.</para>
diff --git a/man/systemd.path.xml b/man/systemd.path.xml
index f6fe3d8388..604bf494ba 100644
--- a/man/systemd.path.xml
+++ b/man/systemd.path.xml
@@ -34,9 +34,9 @@
this unit type. See
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for the common options of all unit configuration files. The common
- configuration items are configured in the generic <literal>[Unit]</literal> and
- <literal>[Install]</literal> sections. The path specific configuration options are
- configured in the <literal>[Path]</literal> section.</para>
+ configuration items are configured in the generic [Unit] and
+ [Install] sections. The path specific configuration options are
+ configured in the [Path] section.</para>
<para>For each path file, a matching unit file must exist,
describing the unit to activate when the path changes. By default,
diff --git a/man/systemd.scope.xml b/man/systemd.scope.xml
index b624ac5f93..449b90b484 100644
--- a/man/systemd.scope.xml
+++ b/man/systemd.scope.xml
@@ -89,7 +89,7 @@
<refsect1>
<title>Options</title>
- <para>Scope files may include a <literal>[Scope]</literal>
+ <para>Scope files may include a [Scope]
section, which carries information about the scope and the
units it contains. A number of options that may be used in
this section are shared with other unit types. These options are
@@ -97,7 +97,7 @@
<citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>
and
<citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
- The options specific to the <literal>[Scope]</literal> section
+ The options specific to the [Scope] section
of scope units are the following:</para>
<variablelist class='unit-directives'>
diff --git a/man/systemd.service.xml b/man/systemd.service.xml
index 61484d530c..4e281ec6d4 100644
--- a/man/systemd.service.xml
+++ b/man/systemd.service.xml
@@ -35,9 +35,9 @@
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for the common options of all unit configuration files. The common
configuration items are configured in the generic
- <literal>[Unit]</literal> and <literal>[Install]</literal>
+ [Unit] and [Install]
sections. The service specific configuration options are
- configured in the <literal>[Service]</literal> section.</para>
+ configured in the [Service] section.</para>
<para>Additional options are listed in
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
@@ -138,7 +138,7 @@
<refsect1>
<title>Options</title>
- <para>Service files must include a <literal>[Service]</literal>
+ <para>Service files must include a [Service]
section, which carries information about the service and the
process it supervises. A number of options that may be used in
this section are shared with other unit types. These options are
@@ -147,7 +147,7 @@
<citerefentry><refentrytitle>systemd.kill</refentrytitle><manvolnum>5</manvolnum></citerefentry>
and
<citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
- The options specific to the <literal>[Service]</literal> section
+ The options specific to the [Service] section
of service units are the following:</para>
<variablelist class='unit-directives'>
@@ -884,7 +884,7 @@
project='man-pages'><refentrytitle>signal</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
a list of signal names.</para>
- <para>Note that this setting does not change the the mapping between numeric exit statuses and their
+ <para>Note that this setting does not change the mapping between numeric exit statuses and their
names, i.e. regardless how this setting is used 0 will still be mapped to <literal>SUCCESS</literal>
(and thus typically shown as <literal>0/SUCCESS</literal> in tool outputs) and 1 to
<literal>FAILURE</literal> (and thus typically shown as <literal>1/FAILURE</literal>), and so on. It
@@ -896,7 +896,7 @@
this option will have no effect.</para>
<example>
- <title>A service with with the <varname>SuccessExitStatus=</varname> setting</title>
+ <title>A service with the <varname>SuccessExitStatus=</varname> setting</title>
<programlisting>SuccessExitStatus=TEMPFAIL 250 SIGUSR1</programlisting>
@@ -1495,7 +1495,7 @@ ExecStart=/usr/sbin/simple-dbus-service
WantedBy=multi-user.target</programlisting>
<para>For <emphasis>bus-activatable</emphasis> services, do not
- include a <literal>[Install]</literal> section in the systemd
+ include a [Install] section in the systemd
service file, but use the <varname>SystemdService=</varname>
option in the corresponding DBus service file, for example
(<filename>/usr/share/dbus-1/system-services/org.example.simple-dbus-service.service</filename>):</para>
diff --git a/man/systemd.slice.xml b/man/systemd.slice.xml
index 7157dfa32d..5019bf9976 100644
--- a/man/systemd.slice.xml
+++ b/man/systemd.slice.xml
@@ -55,9 +55,9 @@
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for the common options of all unit configuration
files. The common configuration items are configured
- in the generic <literal>[Unit]</literal> and <literal>[Install]</literal> sections. The
+ in the generic [Unit] and [Install] sections. The
slice specific configuration options are configured in
- the <literal>[Slice]</literal> section. Currently, only generic resource control settings
+ the [Slice] section. Currently, only generic resource control settings
as described in
<citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry> are allowed.
</para>
diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml
index 46a2dbc7ed..f989b99f95 100644
--- a/man/systemd.socket.xml
+++ b/man/systemd.socket.xml
@@ -35,9 +35,9 @@
this unit type. See
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for the common options of all unit configuration files. The common
- configuration items are configured in the generic <literal>[Unit]</literal> and
- <literal>[Install]</literal> sections. The socket specific configuration options are
- configured in the <literal>[Socket]</literal> section.</para>
+ configuration items are configured in the generic [Unit] and
+ [Install] sections. The socket specific configuration options are
+ configured in the [Socket] section.</para>
<para>Additional options are listed in
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
@@ -117,10 +117,9 @@
<listitem><para>Socket units automatically gain a <varname>Before=</varname>
dependency on the service units they activate.</para></listitem>
- <listitem><para>Socket units referring to file system paths (such as AF_UNIX
- sockets or FIFOs) implicitly gain <varname>Requires=</varname> and
- <varname>After=</varname> dependencies on all mount units
- necessary to access those paths.</para></listitem>
+ <listitem><para>Socket units referring to file system paths (such as <constant>AF_UNIX</constant>
+ sockets or FIFOs) implicitly gain <varname>Requires=</varname> and <varname>After=</varname>
+ dependencies on all mount units necessary to access those paths.</para></listitem>
<listitem><para>Socket units using the <varname>BindToDevice=</varname>
setting automatically gain a <varname>BindsTo=</varname> and
@@ -300,7 +299,7 @@
url="https://www.kernel.org/doc/Documentation/usb/functionfs.txt">USB
FunctionFS</ulink> endpoints location to listen on, for
implementation of USB gadget functions. This expects an
- absolute file system path of functionfs mount point as the argument.
+ absolute file system path of FunctionFS mount point as the argument.
Behavior otherwise is very similar to the <varname>ListenFIFO=</varname>
directive above. Use this to open the FunctionFS endpoint
<filename>ep0</filename>. When using this option, the
@@ -313,9 +312,9 @@
<varlistentry>
<term><varname>SocketProtocol=</varname></term>
<listitem><para>Takes one of <option>udplite</option>
- or <option>sctp</option>. Specifies a socket protocol
- (<constant>IPPROTO_UDPLITE</constant>) UDP-Lite
- (<constant>IPPROTO_SCTP</constant>) SCTP socket respectively. </para>
+ or <option>sctp</option>. The socket will use the UDP-Lite
+ (<constant>IPPROTO_UDPLITE</constant>) or SCTP
+ (<constant>IPPROTO_SCTP</constant>) protocol, respectively.</para>
</listitem>
</varlistentry>
@@ -349,16 +348,14 @@
<varlistentry>
<term><varname>BindToDevice=</varname></term>
- <listitem><para>Specifies a network interface name to bind
- this socket to. If set, traffic will only be accepted from the
- specified network interfaces. This controls the
- SO_BINDTODEVICE socket option (see <citerefentry
- project='man-pages'><refentrytitle>socket</refentrytitle><manvolnum>7</manvolnum></citerefentry>
- for details). If this option is used, an implicit dependency
- from this socket unit on the network interface device unit
- (<citerefentry><refentrytitle>systemd.device</refentrytitle><manvolnum>5</manvolnum></citerefentry>
- is created. Note that setting this parameter might result in
- additional dependencies to be added to the unit (see
+ <listitem><para>Specifies a network interface name to bind this socket to. If set, traffic will only
+ be accepted from the specified network interfaces. This controls the
+ <constant>SO_BINDTODEVICE</constant> socket option (see <citerefentry
+ project='man-pages'><refentrytitle>socket</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
+ details). If this option is used, an implicit dependency from this socket unit on the network
+ interface device unit is created
+ (see <citerefentry><refentrytitle>systemd.device</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
+ Note that setting this parameter might result in additional dependencies to be added to the unit (see
above).</para></listitem>
</varlistentry>
@@ -366,12 +363,10 @@
<term><varname>SocketUser=</varname></term>
<term><varname>SocketGroup=</varname></term>
- <listitem><para>Takes a UNIX user/group name. When specified,
- all AF_UNIX sockets and FIFO nodes in the file system are
- owned by the specified user and group. If unset (the default),
- the nodes are owned by the root user/group (if run in system
- context) or the invoking user/group (if run in user context).
- If only a user is specified but no group, then the group is
+ <listitem><para>Takes a UNIX user/group name. When specified, all <constant>AF_UNIX</constant>
+ sockets and FIFO nodes in the file system are owned by the specified user and group. If unset (the
+ default), the nodes are owned by the root user/group (if run in system context) or the invoking
+ user/group (if run in user context). If only a user is specified but no group, then the group is
derived from the user's default group.</para></listitem>
</varlistentry>
@@ -420,10 +415,10 @@
to work unmodified with systemd socket
activation.</para>
- <para>For IPv4 and IPv6 connections, the <varname>REMOTE_ADDR</varname>
- environment variable will contain the remote IP address, and <varname>REMOTE_PORT</varname>
- will contain the remote port. This is the same as the format used by CGI.
- For SOCK_RAW, the port is the IP protocol.</para></listitem>
+ <para>For IPv4 and IPv6 connections, the <varname>REMOTE_ADDR</varname> environment variable will
+ contain the remote IP address, and <varname>REMOTE_PORT</varname> will contain the remote port. This
+ is the same as the format used by CGI. For <constant>SOCK_RAW</constant>, the port is the IP
+ protocol.</para></listitem>
</varlistentry>
<varlistentry>
@@ -456,17 +451,13 @@
<varlistentry>
<term><varname>KeepAlive=</varname></term>
- <listitem><para>Takes a boolean argument. If true, the TCP/IP
- stack will send a keep alive message after 2h (depending on
- the configuration of
- <filename>/proc/sys/net/ipv4/tcp_keepalive_time</filename>)
- for all TCP streams accepted on this socket. This controls the
- SO_KEEPALIVE socket option (see
- <citerefentry project='man-pages'><refentrytitle>socket</refentrytitle><manvolnum>7</manvolnum></citerefentry>
- and the <ulink
- url="http://www.tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/">TCP
- Keepalive HOWTO</ulink> for details.) Defaults to
- <option>false</option>.</para></listitem>
+ <listitem><para>Takes a boolean argument. If true, the TCP/IP stack will send a keep alive message
+ after 2h (depending on the configuration of
+ <filename>/proc/sys/net/ipv4/tcp_keepalive_time</filename>) for all TCP streams accepted on this
+ socket. This controls the <constant>SO_KEEPALIVE</constant> socket option (see <citerefentry
+ project='man-pages'><refentrytitle>socket</refentrytitle><manvolnum>7</manvolnum></citerefentry> and
+ the <ulink url="http://www.tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/">TCP Keepalive
+ HOWTO</ulink> for details.) Defaults to <option>false</option>.</para></listitem>
</varlistentry>
<varlistentry>
@@ -483,15 +474,12 @@
<varlistentry>
<term><varname>KeepAliveIntervalSec=</varname></term>
- <listitem><para>Takes time (in seconds) as argument between
- individual keepalive probes, if the socket option SO_KEEPALIVE
- has been set on this socket. This controls
- the TCP_KEEPINTVL socket option (see
- <citerefentry project='man-pages'><refentrytitle>socket</refentrytitle><manvolnum>7</manvolnum></citerefentry>
- and the <ulink
- url="http://www.tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/">TCP
- Keepalive HOWTO</ulink> for details.) Defaults value is 75
- seconds.</para></listitem>
+ <listitem><para>Takes time (in seconds) as argument between individual keepalive probes, if the
+ socket option <constant>SO_KEEPALIVE</constant> has been set on this socket. This controls the
+ <constant>TCP_KEEPINTVL</constant> socket option (see <citerefentry
+ project='man-pages'><refentrytitle>socket</refentrytitle><manvolnum>7</manvolnum></citerefentry> and
+ the <ulink url="http://www.tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/">TCP Keepalive
+ HOWTO</ulink> for details.) Defaults value is 75 seconds.</para></listitem>
</varlistentry>
<varlistentry>
@@ -513,17 +501,16 @@
algorithm works by combining a number of small outgoing
messages, and sending them all at once. This controls the
TCP_NODELAY socket option (see
- <citerefentry project='die-net'><refentrytitle>tcp</refentrytitle><manvolnum>7</manvolnum></citerefentry>
+ <citerefentry project='die-net'><refentrytitle>tcp</refentrytitle><manvolnum>7</manvolnum></citerefentry>).
Defaults to <option>false</option>.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>Priority=</varname></term>
- <listitem><para>Takes an integer argument controlling the
- priority for all traffic sent from this socket. This controls
- the SO_PRIORITY socket option (see
- <citerefentry project='man-pages'><refentrytitle>socket</refentrytitle><manvolnum>7</manvolnum></citerefentry>
- for details.).</para></listitem>
+ <listitem><para>Takes an integer argument controlling the priority for all traffic sent from this
+ socket. This controls the <constant>SO_PRIORITY</constant> socket option (see <citerefentry
+ project='man-pages'><refentrytitle>socket</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
+ details.).</para></listitem>
</varlistentry>
<varlistentry>
@@ -559,12 +546,12 @@
<varlistentry>
<term><varname>ReceiveBuffer=</varname></term>
<term><varname>SendBuffer=</varname></term>
- <listitem><para>Takes an integer argument controlling the
- receive or send buffer sizes of this socket, respectively.
- This controls the SO_RCVBUF and SO_SNDBUF socket options (see
- <citerefentry project='man-pages'><refentrytitle>socket</refentrytitle><manvolnum>7</manvolnum></citerefentry>
- for details.). The usual suffixes K, M, G are supported and
- are understood to the base of 1024.</para></listitem>
+ <listitem><para>Takes an integer argument controlling the receive or send buffer sizes of this
+ socket, respectively. This controls the <constant>SO_RCVBUF</constant> and
+ <constant>SO_SNDBUF</constant> socket options (see <citerefentry
+ project='man-pages'><refentrytitle>socket</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
+ details.). The usual suffixes K, M, G are supported and are understood to the base of
+ 1024.</para></listitem>
</varlistentry>
<varlistentry>
@@ -593,23 +580,20 @@
<varlistentry>
<term><varname>Mark=</varname></term>
- <listitem><para>Takes an integer value. Controls the firewall
- mark of packets generated by this socket. This can be used in
- the firewall logic to filter packets from this socket. This
- sets the SO_MARK socket option. See
- <citerefentry project='die-net'><refentrytitle>iptables</refentrytitle><manvolnum>8</manvolnum></citerefentry>
- for details.</para></listitem>
+ <listitem><para>Takes an integer value. Controls the firewall mark of packets generated by this
+ socket. This can be used in the firewall logic to filter packets from this socket. This sets the
+ <constant>SO_MARK</constant> socket option. See <citerefentry
+ project='die-net'><refentrytitle>iptables</refentrytitle><manvolnum>8</manvolnum></citerefentry> for
+ details.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>ReusePort=</varname></term>
- <listitem><para>Takes a boolean value. If true, allows
- multiple
- <citerefentry><refentrytitle>bind</refentrytitle><manvolnum>2</manvolnum></citerefentry>s
- to this TCP or UDP port. This controls the SO_REUSEPORT socket
- option. See
- <citerefentry project='man-pages'><refentrytitle>socket</refentrytitle><manvolnum>7</manvolnum></citerefentry>
- for details.</para></listitem>
+ <listitem><para>Takes a boolean value. If true, allows multiple
+ <citerefentry><refentrytitle>bind</refentrytitle><manvolnum>2</manvolnum></citerefentry>s to this TCP
+ or UDP port. This controls the <constant>SO_REUSEPORT</constant> socket option. See <citerefentry
+ project='man-pages'><refentrytitle>socket</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
+ details.</para></listitem>
</varlistentry>
<varlistentry>
@@ -685,28 +669,23 @@
<varlistentry>
<term><varname>Broadcast=</varname></term>
- <listitem><para>Takes a boolean value. This controls the
- SO_BROADCAST socket option, which allows broadcast datagrams
- to be sent from this socket. Defaults to
+ <listitem><para>Takes a boolean value. This controls the <constant>SO_BROADCAST</constant> socket
+ option, which allows broadcast datagrams to be sent from this socket. Defaults to
<option>false</option>.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>PassCredentials=</varname></term>
- <listitem><para>Takes a boolean value. This controls the
- SO_PASSCRED socket option, which allows
- <constant>AF_UNIX</constant> sockets to receive the
- credentials of the sending process in an ancillary message.
- Defaults to <option>false</option>.</para></listitem>
+ <listitem><para>Takes a boolean value. This controls the <constant>SO_PASSCRED</constant> socket
+ option, which allows <constant>AF_UNIX</constant> sockets to receive the credentials of the sending
+ process in an ancillary message. Defaults to <option>false</option>.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>PassSecurity=</varname></term>
- <listitem><para>Takes a boolean value. This controls the
- SO_PASSSEC socket option, which allows
- <constant>AF_UNIX</constant> sockets to receive the security
- context of the sending process in an ancillary message.
- Defaults to <option>false</option>.</para></listitem>
+ <listitem><para>Takes a boolean value. This controls the <constant>SO_PASSSEC</constant> socket
+ option, which allows <constant>AF_UNIX</constant> sockets to receive the security context of the
+ sending process in an ancillary message. Defaults to <option>false</option>.</para></listitem>
</varlistentry>
<varlistentry>
@@ -720,11 +699,10 @@
<varlistentry>
<term><varname>TCPCongestion=</varname></term>
- <listitem><para>Takes a string value. Controls the TCP
- congestion algorithm used by this socket. Should be one of
- "westwood", "veno", "cubic", "lp" or any other available
- algorithm supported by the IP stack. This setting applies only
- to stream sockets.</para></listitem>
+ <listitem><para>Takes a string value. Controls the TCP congestion algorithm used by this
+ socket. Should be one of <literal>westwood</literal>, <literal>veno</literal>,
+ <literal>cubic</literal>, <literal>lp</literal> or any other available algorithm supported by the IP
+ stack. This setting applies only to stream sockets.</para></listitem>
</varlistentry>
<varlistentry>
@@ -788,15 +766,12 @@
<varlistentry>
<term><varname>RemoveOnStop=</varname></term>
- <listitem><para>Takes a boolean argument. If enabled, any file
- nodes created by this socket unit are removed when it is
- stopped. This applies to AF_UNIX sockets in the file system,
- POSIX message queues, FIFOs, as well as any symlinks to them
- configured with <varname>Symlinks=</varname>. Normally, it
- should not be necessary to use this option, and is not
- recommended as services might continue to run after the socket
- unit has been terminated and it should still be possible to
- communicate with them via their file system node. Defaults to
+ <listitem><para>Takes a boolean argument. If enabled, any file nodes created by this socket unit are
+ removed when it is stopped. This applies to <constant>AF_UNIX</constant> sockets in the file system,
+ POSIX message queues, FIFOs, as well as any symlinks to them configured with
+ <varname>Symlinks=</varname>. Normally, it should not be necessary to use this option, and is not
+ recommended as services might continue to run after the socket unit has been terminated and it should
+ still be possible to communicate with them via their file system node. Defaults to
off.</para></listitem>
</varlistentry>
diff --git a/man/systemd.special.xml b/man/systemd.special.xml
index 9f368f903d..a948969a8f 100644
--- a/man/systemd.special.xml
+++ b/man/systemd.special.xml
@@ -297,7 +297,7 @@
this unit (or <filename>multi-user.target</filename>) during
installation. This is best configured via
<varname>WantedBy=graphical.target</varname> in the unit's
- <literal>[Install]</literal> section.</para>
+ [Install] section.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -447,7 +447,7 @@
add <varname>Wants=</varname> dependencies for their unit to
this unit during installation. This is best configured via
<varname>WantedBy=multi-user.target</varname> in the unit's
- <literal>[Install]</literal> section.</para>
+ [Install] section.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -505,7 +505,7 @@
applications get pulled in via <varname>Wants=</varname>
dependencies from this unit. This is best configured via a
<varname>WantedBy=paths.target</varname> in the path unit's
- <literal>[Install]</literal> section.</para>
+ [Install] section.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -641,7 +641,7 @@
<para>Adding slice units to <filename>slices.target</filename> is generally not
necessary. Instead, when some unit that uses <varname>Slice=</varname> is started, the
specified slice will be started automatically. Adding
- <varname>WantedBy=slices.target</varname> lines to the <literal>[Install]</literal>
+ <varname>WantedBy=slices.target</varname> lines to the [Install]
section should only be done for units that need to be always active. In that case care
needs to be taken to avoid creating a loop through the automatic dependencies on
"parent" slices.</para>
@@ -659,7 +659,7 @@
<varname>Wants=</varname> dependencies to this unit for
their socket unit during installation. This is best
configured via a <varname>WantedBy=sockets.target</varname>
- in the socket unit's <literal>[Install]</literal>
+ in the socket unit's [Install]
section.</para>
</listitem>
</varlistentry>
@@ -742,7 +742,7 @@
applications get pulled in via <varname>Wants=</varname>
dependencies from this unit. This is best configured via
<varname>WantedBy=timers.target</varname> in the timer
- unit's <literal>[Install]</literal> section.</para>
+ unit's [Install] section.</para>
</listitem>
</varlistentry>
<varlistentry>
@@ -1043,7 +1043,7 @@
<para>By default, all user processes and services started on
behalf of the user, including the per-user systemd instance
are found in this slice. This is pulled in by
- <filename>systemd-logind.service</filename></para>
+ <filename>systemd-logind.service</filename>.</para>
</listitem>
</varlistentry>
@@ -1052,8 +1052,8 @@
<listitem>
<para>By default, all virtual machines and containers
registered with <command>systemd-machined</command> are
- found in this slice. This is pulled in by
- <filename>systemd-machined.service</filename></para>
+ found in this slice. This is pulled in by
+ <filename>systemd-machined.service</filename>.</para>
</listitem>
</varlistentry>
</variablelist>
@@ -1104,7 +1104,7 @@
<para>This target is active whenever any graphical session is running. It is used to
stop user services which only apply to a graphical (X, Wayland, etc.) session when the
session is terminated. Such services should have
- <literal>PartOf=graphical-session.target</literal> in their <literal>[Unit]</literal>
+ <literal>PartOf=graphical-session.target</literal> in their [Unit]
section. A target for a particular session (e. g.
<filename>gnome-session.target</filename>) starts and stops
<literal>graphical-session.target</literal> with
diff --git a/man/systemd.swap.xml b/man/systemd.swap.xml
index c4160290a5..4b1f850af4 100644
--- a/man/systemd.swap.xml
+++ b/man/systemd.swap.xml
@@ -37,9 +37,9 @@
this unit type. See
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for the common options of all unit configuration files. The common
- configuration items are configured in the generic <literal>[Unit]</literal> and
- <literal>[Install]</literal> sections. The swap specific configuration options are
- configured in the <literal>[Swap]</literal> section.</para>
+ configuration items are configured in the generic [Unit] and
+ [Install] sections. The swap specific configuration options are
+ configured in the [Swap] section.</para>
<para>Additional options are listed in
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
@@ -166,7 +166,7 @@
<refsect1>
<title>Options</title>
- <para>Swap files must include a [Swap] section, which carries
+ <para>Swap unit files must include a [Swap] section, which carries
information about the swap device it supervises. A number of
options that may be used in this section are shared with other
unit types. These options are documented in
diff --git a/man/systemd.syntax.xml b/man/systemd.syntax.xml
index 04b1564b17..df100ec4e7 100644
--- a/man/systemd.syntax.xml
+++ b/man/systemd.syntax.xml
@@ -98,10 +98,10 @@ KeyTwo=value 2 \
value 2 continued
[Section C]
-KeyThree=value 2\
+KeyThree=value 3\
# this line is ignored
; this line is ignored too
- value 2 continued
+ value 3 continued
</programlisting></example>
<para>Boolean arguments used in configuration files can be written in
diff --git a/man/systemd.target.xml b/man/systemd.target.xml
index 3052b17786..a706a4588a 100644
--- a/man/systemd.target.xml
+++ b/man/systemd.target.xml
@@ -34,8 +34,8 @@
<para>This unit type has no specific options. See
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for the common options of all unit configuration files. The common
- configuration items are configured in the generic <literal>[Unit]</literal> and
- <literal>[Install]</literal> sections. A separate <literal>[Target]</literal> section does not exist,
+ configuration items are configured in the generic [Unit] and
+ [Install] sections. A separate [Target] section does not exist,
since no target-specific options may be configured.</para>
<para>Target units do not offer any additional functionality on
diff --git a/man/systemd.time.xml b/man/systemd.time.xml
index b4656b05d1..5b7800e78b 100644
--- a/man/systemd.time.xml
+++ b/man/systemd.time.xml
@@ -98,18 +98,20 @@
<refsect1>
<title>Parsing Timestamps</title>
- <para>When parsing, systemd will accept a similar syntax, but expects no timezone specification, unless it is given
- as the literal string <literal>UTC</literal> (for the UTC timezone), or is specified to be the locally configured
- timezone, or the timezone name in the IANA timezone database format. The complete list of timezones
- supported on your system can be obtained using the <literal>timedatectl list-timezones</literal>
- (see <citerefentry><refentrytitle>timedatectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>).
- Using IANA format is recommended over local timezone names, as less prone to errors (eg: with local timezone it's possible to
- specify daylight saving time in winter, while it's incorrect). The weekday specification is optional, but when
- the weekday is specified, it must either be in the abbreviated (<literal>Wed</literal>) or non-abbreviated
- (<literal>Wednesday</literal>) English language form (case does not matter), and is not subject to the locale
- choice of the user. Either the date, or the time part may be omitted, in which case the current date or 00:00:00,
- respectively, is assumed. The seconds component of the time may also be omitted, in which case ":00" is
- assumed. Year numbers may be specified in full or may be abbreviated (omitting the century).</para>
+ <para>When parsing, systemd will accept a similar syntax, but expects no timezone specification, unless
+ it is given as the literal string <literal>UTC</literal> (for the UTC timezone), or is specified to be
+ the locally configured timezone, or the timezone name in the IANA timezone database format. The complete
+ list of timezones supported on your system can be obtained using the <literal>timedatectl
+ list-timezones</literal> (see
+ <citerefentry><refentrytitle>timedatectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>). Using
+ IANA format is recommended over local timezone names, as less prone to errors (e.g. with local timezone
+ it's possible to specify daylight saving time in winter, even though that is not correct). The weekday
+ specification is optional, but when the weekday is specified, it must either be in the abbreviated
+ (<literal>Wed</literal>) or non-abbreviated (<literal>Wednesday</literal>) English language form (case
+ does not matter), and is not subject to the locale choice of the user. Either the date, or the time part
+ may be omitted, in which case the current date or 00:00:00, respectively, is assumed. The seconds
+ component of the time may also be omitted, in which case ":00" is assumed. Year numbers may be specified
+ in full or may be abbreviated (omitting the century).</para>
<para>A timestamp is considered invalid if a weekday is specified and the date does not match the specified day of
the week.</para>
@@ -282,7 +284,7 @@ Wed..Sat,Tue 12-10-15 1:2:3 → Tue..Sat 2012-10-15 01:02:03
<para>Use the <command>calendar</command> command of
<citerefentry><refentrytitle>systemd-analyze</refentrytitle><manvolnum>1</manvolnum></citerefentry> to validate
and normalize calendar time specifications for testing purposes. The tool also calculates when a specified
- calendar event would elapse next.</para>
+ calendar event would occur next.</para>
</refsect1>
<refsect1>
diff --git a/man/systemd.timer.xml b/man/systemd.timer.xml
index 040b8e2893..5822402712 100644
--- a/man/systemd.timer.xml
+++ b/man/systemd.timer.xml
@@ -35,9 +35,9 @@
this unit type. See
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for the common options of all unit configuration files. The common
- configuration items are configured in the generic <literal>[Unit]</literal> and
- <literal>[Install]</literal> sections. The timer specific configuration options are
- configured in the <literal>[Timer]</literal> section.</para>
+ configuration items are configured in the generic [Unit] and
+ [Install] sections. The timer specific configuration options are
+ configured in the [Timer] section.</para>
<para>For each timer file, a matching unit file must exist,
describing the unit to activate when the timer elapses. By
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
index 8c0815488b..af45900cd0 100644
--- a/man/systemd.unit.xml
+++ b/man/systemd.unit.xml
@@ -737,7 +737,7 @@
that the listed unit is fully started up before the configured unit is started.</para>
<para>When two units with an ordering dependency between them are shut down, the inverse of the
- start-up order is applied. i.e. if a unit is configured with <varname>After=</varname> on another
+ start-up order is applied. I.e. if a unit is configured with <varname>After=</varname> on another
unit, the former is stopped before the latter if both are shut down. Given two units with any
ordering dependency between them, if one unit is shut down and the other is started up, the shutdown
is ordered before the start-up. It doesn't matter if the ordering dependency is
@@ -833,7 +833,7 @@
<option>--job-mode=</option> option for details on the
possible values. If this is set to <literal>isolate</literal>,
only a single unit may be listed in
- <varname>OnFailure=</varname>..</para></listitem>
+ <varname>OnFailure=</varname>.</para></listitem>
</varlistentry>
<varlistentry>
@@ -1027,9 +1027,9 @@
<term><varname>StartLimitAction=</varname></term>
<listitem><para>Configure an additional action to take if the rate limit configured with
- <varname>StartLimitIntervalSec=</varname> and <varname>StartLimitBurst=</varname> is hit. Takes the same
- values as the setting <varname>FailureAction=</varname>/<varname>SuccessAction=</varname> settings and executes
- the same actions. If <option>none</option> is set, hitting the rate limit will trigger no action besides that
+ <varname>StartLimitIntervalSec=</varname> and <varname>StartLimitBurst=</varname> is hit. Takes the same
+ values as the <varname>FailureAction=</varname>/<varname>SuccessAction=</varname> settings. If
+ <option>none</option> is set, hitting the rate limit will trigger no action except that
the start will not be permitted. Defaults to <option>none</option>.</para></listitem>
</varlistentry>
@@ -1639,7 +1639,7 @@
<refsect1>
<title>[Install] Section Options</title>
- <para>Unit files may include an <literal>[Install]</literal> section, which carries installation information for
+ <para>Unit files may include an [Install] section, which carries installation information for
the unit. This section is not interpreted by
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry> during runtime; it is
used by the <command>enable</command> and <command>disable</command> commands of the
diff --git a/man/systemd.xml b/man/systemd.xml
index 11954a78da..a13d53e72c 100644
--- a/man/systemd.xml
+++ b/man/systemd.xml
@@ -760,13 +760,11 @@
<varlistentry>
<term><varname>systemd.crash_chvt</varname></term>
- <listitem><para>Takes a positive integer, or a boolean argument. Can be also
- specified without an argument, with the same effect as a positive boolean. If
- a positive integer (in the range 1–63) is specified, the system manager (PID
- 1) will activate the specified virtual terminal (VT) when it
- crashes. Defaults to disabled, meaning that no such switch is attempted. If
- set to enabled, the VT the kernel messages are written to is selected.
- </para></listitem>
+ <listitem><para>Takes a positive integer, or a boolean argument. Can be also specified without an
+ argument, with the same effect as a positive boolean. If a positive integer (in the range 1–63) is
+ specified, the system manager (PID 1) will activate the specified virtual terminal when it crashes.
+ Defaults to disabled, meaning that no such switch is attempted. If set to enabled, the virtual
+ terminal the kernel messages are written to is used instead.</para></listitem>
</varlistentry>
<varlistentry>
@@ -1089,14 +1087,15 @@
this context, because they are properly namespaced. When an option is specified both on the kernel
command line, and as a normal command line argument, the latter has higher precedence.</para>
- <para>When <command>systemd</command> is used a user manager, the kernel command line is ignored and
+ <para>When <command>systemd</command> is used as a user manager, the kernel command line is ignored and
the options described are understood. Nevertheless, <command>systemd</command> is usually started in
this mode through the
<citerefentry><refentrytitle>user@.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
service, which is shared between all users, and it may be more convenient to use configuration files to
modify settings, see
<citerefentry><refentrytitle>systemd-user.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
- or a drop-in that specifies one of the environment variables listed above in "Environment, see
+ or a drop-in that specifies one of the environment variables listed above in the Environment section,
+ see
<citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
<variablelist>
@@ -1146,8 +1145,8 @@
<varlistentry>
<term><option>--show-status</option></term>
- <listitem><para>Show terse unit status information is shown on the console during boot-up and
- shutdown. See <varname>systemd.show_status</varname> above.</para></listitem>
+ <listitem><para>Show terse unit status information on the console during boot-up and shutdown. See
+ <varname>systemd.show_status</varname> above.</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/man/tc.xml b/man/tc.xml
index 1711915c22..f312ac2692 100644
--- a/man/tc.xml
+++ b/man/tc.xml
@@ -10,27 +10,28 @@
<varlistentry id='qdisc-parent'>
<term><varname>Parent=</varname></term>
<listitem>
- <para>Specifies the parent Queueing Discipline (qdisc). Takes one of <literal>root</literal>,
- <literal>clsact</literal>, <literal>ingress</literal> or a class id. The class id takes the
- major and minor number in hexadecimal ranges 1 to ffff separated with a colon
- (<literal>major:minor</literal>). Defaults to <literal>root</literal>.</para>
+ <para>Configures the parent Queueing Discipline (qdisc). Takes one of <literal>root</literal>,
+ <literal>clsact</literal>, <literal>ingress</literal> or a class identifier. The class identifier is
+ specified as the major and minor numbers in hexadecimal in the range 0x1–Oxffff separated with a
+ colon (<literal>major:minor</literal>). Defaults to <literal>root</literal>.</para>
</listitem>
</varlistentry>
<varlistentry id='qdisc-handle'>
<term><varname>Handle=</varname></term>
<listitem>
- <para>Specifies the major number of unique identifier of the qdisc, known as the handle.
- Takes a number in hexadecimal ranges 1 to ffff. Defaults to unset.</para>
+ <para>Configures the major number of unique identifier of the qdisc, known as the handle.
+ Takes a hexadecimal number in the range 0x1–0xffff. Defaults to unset.</para>
</listitem>
</varlistentry>
<varlistentry id='tclass-parent'>
<term><varname>Parent=</varname></term>
<listitem>
- <para>Specifies the parent Queueing Discipline (qdisc). Takes one of <literal>root</literal>,
- or a qdisc id. The qdisc id takes the major and minor number in hexadecimal ranges 1 to ffff
- separated with a colon (<literal>major:minor</literal>). Defaults to <literal>root</literal>.
+ <para>Configures the parent Queueing Discipline (qdisc). Takes one of <literal>root</literal>, or a
+ qdisc identifier. The qdisc identifier is specified as the major and minor numbers in hexadecimal in
+ the range 0x1–Oxffff separated with a colon (<literal>major:minor</literal>). Defaults to
+ <literal>root</literal>.
</para>
</listitem>
</varlistentry>
@@ -38,8 +39,9 @@
<varlistentry id='tclass-classid'>
<term><varname>ClassId=</varname></term>
<listitem>
- <para>Specifies the major and minur number of unique identifier of the class, known as the
- class ID. Each number is in hexadecimal ranges 1 to ffff. Defaults to unset.</para>
+ <para>Configues the unique identifier of the class. It is specified as the major and minor numbers in
+ hexadecimal in the range 0x1–Oxffff separated with a colon (<literal>major:minor</literal>).
+ Defaults to unset.</para>
</listitem>
</varlistentry>
</variablelist>
diff --git a/man/timesyncd.conf.xml b/man/timesyncd.conf.xml
index c64d015400..44694e8033 100644
--- a/man/timesyncd.conf.xml
+++ b/man/timesyncd.conf.xml
@@ -41,7 +41,7 @@
<refsect1>
<title>Options</title>
- <para>The following settings are configured in the <literal>[Time]</literal> section:</para>
+ <para>The following settings are configured in the [Time] section:</para>
<variablelist class='network-directives'>
diff --git a/man/userdbctl.xml b/man/userdbctl.xml
index 606ce673b5..777393ab75 100644
--- a/man/userdbctl.xml
+++ b/man/userdbctl.xml
@@ -163,11 +163,10 @@
<title>Well-Known Services</title>
<para>The <command>userdbctl services</command> command will list all currently running services that
- provide user or group definitions to the system. The following are well-known services are shown among
- this list.</para>
+ provide user or group definitions to the system. The following well-known services are shown among
+ this list:</para>
<variablelist>
-
<varlistentry>
<term><constant>io.systemd.DynamicUser</constant></term>
@@ -218,7 +217,7 @@
<para>Note that <command>userdbctl</command> has internal support for NSS-based lookups too. This means
that if neither <constant>io.systemd.Multiplexer</constant> nor
- <constant>io.systemd.NameSeviceSwitch</constant> are running look-ups into the the basic user/group
+ <constant>io.systemd.NameSeviceSwitch</constant> are running look-ups into the basic user/group
databases will still work.</para>
</refsect1>
diff --git a/meson.build b/meson.build
index 08f322117f..fc75fddf6b 100644
--- a/meson.build
+++ b/meson.build
@@ -1153,6 +1153,17 @@ else
endif
conf.set10('HAVE_P11KIT', have)
+want_libfido2 = get_option('libfido2')
+if want_libfido2 != 'false' and not skip_deps
+ libfido2 = dependency('libfido2',
+ required : want_libfido2 == 'true')
+ have = libfido2.found()
+else
+ have = false
+ libfido2 = []
+endif
+conf.set10('HAVE_LIBFIDO2', have)
+
want_elfutils = get_option('elfutils')
if want_elfutils != 'false' and not skip_deps
libdw = dependency('libdw',
@@ -2146,7 +2157,8 @@ if conf.get('ENABLE_HOMED') == 1
libcrypt,
libopenssl,
libfdisk,
- libp11kit],
+ libp11kit,
+ libfido2],
install_rpath : rootlibexecdir,
install : true,
install_dir : rootlibexecdir)
@@ -2173,6 +2185,7 @@ if conf.get('ENABLE_HOMED') == 1
libcrypt,
libopenssl,
libp11kit,
+ libfido2,
libpwquality],
install_rpath : rootlibexecdir,
install : true,
@@ -3575,6 +3588,7 @@ foreach tuple : [
['pwquality'],
['libfdisk'],
['p11kit'],
+ ['libfido2'],
['AUDIT'],
['IMA'],
['AppArmor'],
diff --git a/meson_options.txt b/meson_options.txt
index e13bfb0c4b..fd73d5e681 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -312,6 +312,8 @@ option('openssl', type : 'combo', choices : ['auto', 'true', 'false'],
description : 'openssl support')
option('p11kit', type : 'combo', choices : ['auto', 'true', 'false'],
description : 'p11kit support')
+option('libfido2', type : 'combo', choices : ['auto', 'true', 'false'],
+ description : 'FIDO2 support')
option('elfutils', type : 'combo', choices : ['auto', 'true', 'false'],
description : 'elfutils support')
option('zlib', type : 'combo', choices : ['auto', 'true', 'false'],
diff --git a/po/cs.po b/po/cs.po
index 78180f6389..8805dce0db 100644
--- a/po/cs.po
+++ b/po/cs.po
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: systemd master\n"
"Report-Msgid-Bugs-To: https://github.com/systemd/systemd/issues\n"
-"POT-Creation-Date: 2020-02-29 15:12+0000\n"
-"PO-Revision-Date: 2020-03-01 13:58+0100\n"
+"POT-Creation-Date: 2020-05-30 13:27+0000\n"
+"PO-Revision-Date: 2020-07-01 16:40+0200\n"
"Last-Translator: Daniel Rusek <mail@asciiwolf.com>\n"
"Language-Team: Czech\n"
"Language: cs\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
"|| n%100>=20) ? 1 : 2);\n"
-"X-Generator: Poedit 2.3\n"
+"X-Generator: Poedit 2.3.1\n"
#: src/core/org.freedesktop.systemd1.policy.in:22
msgid "Send passphrase back to system"
@@ -740,26 +740,34 @@ msgid "Authentication is required to reset DNS settings."
msgstr "Pro resetování nastavení DNS je vyžadováno ověření."
#: src/network/org.freedesktop.network1.policy:143
+msgid "DHCP server sends force renew message"
+msgstr "DHCP server posílá zprávu vynuceného obnovení"
+
+#: src/network/org.freedesktop.network1.policy:144
+msgid "Authentication is required to send force renew message."
+msgstr "Pro poslání zprávy vynuceného obnovení je vyžadováno ověření."
+
+#: src/network/org.freedesktop.network1.policy:154
msgid "Renew dynamic addresses"
msgstr "Obnovit dynamické adresy"
-#: src/network/org.freedesktop.network1.policy:144
+#: src/network/org.freedesktop.network1.policy:155
msgid "Authentication is required to renew dynamic addresses."
msgstr "Pro obnovení dynamických adres je vyžadováno ověření."
-#: src/network/org.freedesktop.network1.policy:154
+#: src/network/org.freedesktop.network1.policy:165
msgid "Reload network settings"
msgstr "Znovu načíst nastavení sítě"
-#: src/network/org.freedesktop.network1.policy:155
+#: src/network/org.freedesktop.network1.policy:166
msgid "Authentication is required to reload network settings."
msgstr "Pro opětovné načtení nastavení sítě je vyžadováno ověření."
-#: src/network/org.freedesktop.network1.policy:165
+#: src/network/org.freedesktop.network1.policy:176
msgid "Reconfigure network interface"
msgstr "Přenastavit síťové rozhraní"
-#: src/network/org.freedesktop.network1.policy:166
+#: src/network/org.freedesktop.network1.policy:177
msgid "Authentication is required to reconfigure network interface."
msgstr "Pro přenastavení síťového rozhraní je vyžadováno ověření."
@@ -853,40 +861,47 @@ msgid ""
"shall be enabled."
msgstr "Pro kontrolu synchronizace času ze sítě je vyžadováno ověření."
-#: src/core/dbus-unit.c:356
+#: src/core/dbus-unit.c:358
msgid "Authentication is required to start '$(unit)'."
msgstr "Pro spuštění „$(unit)” je vyžadováno ověření."
-#: src/core/dbus-unit.c:357
+#: src/core/dbus-unit.c:359
msgid "Authentication is required to stop '$(unit)'."
msgstr "Pro vypnutí „$(unit)” je vyžadováno ověření."
-#: src/core/dbus-unit.c:358
+#: src/core/dbus-unit.c:360
msgid "Authentication is required to reload '$(unit)'."
msgstr "Pro opětovné načtení „$(unit)” je vyžadováno ověření."
-#: src/core/dbus-unit.c:359 src/core/dbus-unit.c:360
+#: src/core/dbus-unit.c:361 src/core/dbus-unit.c:362
msgid "Authentication is required to restart '$(unit)'."
msgstr "Pro restart „$(unit)” je vyžadováno ověření."
-#: src/core/dbus-unit.c:532
+#: src/core/dbus-unit.c:534
msgid ""
"Authentication is required to send a UNIX signal to the processes of "
"'$(unit)'."
msgstr "Pro odeslání UNIX signálu procesům „$(unit)” je vyžadováno ověření."
-#: src/core/dbus-unit.c:563
+#: src/core/dbus-unit.c:565
msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
msgstr "Pro resetování chybného stavu „$(unit)” je vyžadováno ověření."
-#: src/core/dbus-unit.c:596
+#: src/core/dbus-unit.c:598
msgid "Authentication is required to set properties on '$(unit)'."
msgstr "Pro nastavení vlastností na „$(unit)” je vyžadováno ověření."
-#: src/core/dbus-unit.c:705
+#: src/core/dbus-unit.c:707
msgid ""
"Authentication is required to delete files and directories associated with "
"'$(unit)'."
msgstr ""
"Pro odstranění souborů nebo adresářů souvisejících s „$(unit)” je vyžadováno "
"ověření."
+
+#: src/core/dbus-unit.c:756
+msgid ""
+"Authentication is required to freeze or thaw the processes of '$(unit)' unit."
+msgstr ""
+"Pro zmrazení nebo rozmrazení procesů jednotky „$(unit)” je vyžadováno "
+"ověření."
diff --git a/src/basic/locale-util.c b/src/basic/locale-util.c
index 01af759a7d..8e6a12b602 100644
--- a/src/basic/locale-util.c
+++ b/src/basic/locale-util.c
@@ -373,7 +373,8 @@ const char *special_glyph(SpecialGlyph code) {
[SPECIAL_GLYPH_SLIGHTLY_UNHAPPY_SMILEY] = ":-(",
[SPECIAL_GLYPH_UNHAPPY_SMILEY] = ":-{",
[SPECIAL_GLYPH_DEPRESSED_SMILEY] = ":-[",
- [SPECIAL_GLYPH_LOCK_AND_KEY] = "o-,"
+ [SPECIAL_GLYPH_LOCK_AND_KEY] = "o-,",
+ [SPECIAL_GLYPH_TOUCH] = "O=", /* Yeah, not very convincing, can you do it better? */
},
/* UTF-8 */
@@ -415,6 +416,9 @@ const char *special_glyph(SpecialGlyph code) {
/* This emoji is a single character cell glyph in Unicode, and three in ASCII */
[SPECIAL_GLYPH_LOCK_AND_KEY] = "\360\237\224\220", /* 🔐 (actually called: CLOSED LOCK WITH KEY) */
+
+ /* This emoji is a single character cell glyph in Unicode, and two in ASCII */
+ [SPECIAL_GLYPH_TOUCH] = "\360\237\221\206", /* 👆 (actually called: BACKHAND INDEX POINTING UP */
},
};
diff --git a/src/basic/locale-util.h b/src/basic/locale-util.h
index e4f9711b08..aa25e17f15 100644
--- a/src/basic/locale-util.h
+++ b/src/basic/locale-util.h
@@ -65,7 +65,8 @@ typedef enum {
SPECIAL_GLYPH_UNHAPPY_SMILEY,
SPECIAL_GLYPH_DEPRESSED_SMILEY,
SPECIAL_GLYPH_LOCK_AND_KEY,
- _SPECIAL_GLYPH_MAX
+ SPECIAL_GLYPH_TOUCH,
+ _SPECIAL_GLYPH_MAX,
} SpecialGlyph;
const char *special_glyph(SpecialGlyph code) _const_;
diff --git a/src/basic/macro.h b/src/basic/macro.h
index fd8772f377..ceea8176f5 100644
--- a/src/basic/macro.h
+++ b/src/basic/macro.h
@@ -538,6 +538,12 @@ static inline int __coverity_check_and_return__(int condition) {
(y) = (_t); \
} while (false)
+/* Iterates through a specified list of pointers. Accepts NULL pointers, but uses (void*) -1 as internal marker for EOL. */
+#define FOREACH_POINTER(p, x, ...) \
+ for (typeof(p) *_l = (typeof(p)[]) { ({ p = x; }), ##__VA_ARGS__, (void*) -1 }; \
+ p != (typeof(p)) (void*) -1; \
+ p = *(++_l))
+
/* Define C11 thread_local attribute even on older gcc compiler
* version */
#ifndef thread_local
diff --git a/src/basic/namespace-util.c b/src/basic/namespace-util.c
index b0168ae227..b34c532604 100644
--- a/src/basic/namespace-util.c
+++ b/src/basic/namespace-util.c
@@ -2,6 +2,7 @@
#include <fcntl.h>
#include <sys/ioctl.h>
+#include <sys/mount.h>
#include "fd-util.h"
#include "missing_fs.h"
@@ -169,3 +170,16 @@ int fd_is_network_ns(int fd) {
return r == CLONE_NEWNET;
}
+
+int detach_mount_namespace(void) {
+
+ /* Detaches the mount namespace, disabling propagation from our namespace to the host */
+
+ if (unshare(CLONE_NEWNS) < 0)
+ return -errno;
+
+ if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0)
+ return -errno;
+
+ return 0;
+}
diff --git a/src/basic/namespace-util.h b/src/basic/namespace-util.h
index 8c17ce91b2..99d9b977ed 100644
--- a/src/basic/namespace-util.h
+++ b/src/basic/namespace-util.h
@@ -7,3 +7,5 @@ int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *
int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd);
int fd_is_network_ns(int fd);
+
+int detach_mount_namespace(void);
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
index f6ecc7f86f..80f13048c1 100644
--- a/src/basic/process-util.c
+++ b/src/basic/process-util.c
@@ -1334,7 +1334,7 @@ int safe_fork_full(
ppid = getppid();
if (ppid == 0)
- /* Parent is in a differn't PID namespace. */;
+ /* Parent is in a different PID namespace. */;
else if (ppid != original_pid) {
log_debug("Parent died early, raising SIGTERM.");
(void) raise(SIGTERM);
diff --git a/src/basic/random-util.c b/src/basic/random-util.c
index 4a30c4d359..6eeed9af34 100644
--- a/src/basic/random-util.c
+++ b/src/basic/random-util.c
@@ -77,7 +77,7 @@ int rdrand(unsigned long *ret) {
* hash functions for its hash tables, with a seed generated randomly. The hash tables
* systemd employs watch the fill level closely and reseed if necessary. This allows use of
* a low quality RNG initially, as long as it improves should a hash table be under attack:
- * the attacker after all needs to to trigger many collisions to exploit it for the purpose
+ * the attacker after all needs to trigger many collisions to exploit it for the purpose
* of DoS, but if doing so improves the seed the attack surface is reduced as the attack
* takes place.
*
diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c
index 07f534f34d..fb12659857 100644
--- a/src/basic/socket-util.c
+++ b/src/basic/socket-util.c
@@ -105,7 +105,7 @@ int socket_address_verify(const SocketAddress *a, bool strict) {
if (a->size != offsetof(struct sockaddr_un, sun_path) + (e - a->sockaddr.un.sun_path) + 1)
return -EINVAL;
} else {
- /* If there's no embedded NUL byte, then then the size needs to match the whole
+ /* If there's no embedded NUL byte, then the size needs to match the whole
* structure or the structure with one extra NUL byte suffixed. (Yeah, Linux is awful,
* and considers both equivalent: getsockname() even extends sockaddr_un beyond its
* size if the path is non NUL terminated.)*/
@@ -1130,6 +1130,7 @@ int socket_bind_to_ifname(int fd, const char *ifname) {
int socket_bind_to_ifindex(int fd, int ifindex) {
char ifname[IF_NAMESIZE + 1];
+ int r;
assert(fd >= 0);
@@ -1141,10 +1142,9 @@ int socket_bind_to_ifindex(int fd, int ifindex) {
return 0;
}
- if (setsockopt(fd, SOL_SOCKET, SO_BINDTOIFINDEX, &ifindex, sizeof(ifindex)) >= 0)
- return 0;
- if (errno != ENOPROTOOPT)
- return -errno;
+ r = setsockopt_int(fd, SOL_SOCKET, SO_BINDTOIFINDEX, ifindex);
+ if (r != -ENOPROTOOPT)
+ return r;
/* Fall back to SO_BINDTODEVICE on kernels < 5.0 which didn't have SO_BINDTOIFINDEX */
if (!format_ifname(ifindex, ifname))
diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c
index 10405b711f..43d8b3477e 100644
--- a/src/basic/unit-name.c
+++ b/src/basic/unit-name.c
@@ -537,8 +537,7 @@ int unit_name_from_path(const char *path, const char *suffix, char **ret) {
}
int unit_name_from_path_instance(const char *prefix, const char *path, const char *suffix, char **ret) {
- _cleanup_free_ char *p = NULL;
- char *s;
+ _cleanup_free_ char *p = NULL, *s = NULL;
int r;
assert(prefix);
@@ -564,7 +563,7 @@ int unit_name_from_path_instance(const char *prefix, const char *path, const cha
if (!unit_name_is_valid(s, UNIT_NAME_INSTANCE))
return -EINVAL;
- *ret = s;
+ *ret = TAKE_PTR(s);
return 0;
}
diff --git a/src/basic/user-util.c b/src/basic/user-util.c
index 7dd2f6664a..66f8856fdf 100644
--- a/src/basic/user-util.c
+++ b/src/basic/user-util.c
@@ -777,7 +777,7 @@ bool valid_user_group_name(const char *u, ValidUserFlags flags) {
return false;
if (in_charset(u, "0123456789")) /* Don't allow fully numeric strings, they might be confused
- * with with UIDs (note that this test is more broad than
+ * with UIDs (note that this test is more broad than
* the parse_uid() test above, as it will cover more than
* the 32bit range, and it will detect 65535 (which is in
* invalid UID, even though in the unsigned 32 bit range) */
diff --git a/src/core/automount.c b/src/core/automount.c
index 77420b929f..1f05198766 100644
--- a/src/core/automount.c
+++ b/src/core/automount.c
@@ -1085,6 +1085,7 @@ const UnitVTable automount_vtable = {
"Unit\0"
"Automount\0"
"Install\0",
+ .private_section = "Automount",
.can_transient = true,
.can_fail = true,
diff --git a/src/core/bpf-firewall.c b/src/core/bpf-firewall.c
index 2ec274df01..bceb049b58 100644
--- a/src/core/bpf-firewall.c
+++ b/src/core/bpf-firewall.c
@@ -544,7 +544,7 @@ int bpf_firewall_compile(Unit *u) {
"BPF_F_ALLOW_MULTI is not supported on this manager, not doing BPF firewall on slice units.");
/* Note that when we compile a new firewall we first flush out the access maps and the BPF programs themselves,
- * but we reuse the the accounting maps. That way the firewall in effect always maps to the actual
+ * but we reuse the accounting maps. That way the firewall in effect always maps to the actual
* configuration, but we don't flush out the accounting unnecessarily */
u->ip_bpf_ingress = bpf_program_unref(u->ip_bpf_ingress);
diff --git a/src/core/execute.c b/src/core/execute.c
index 4bee1b1966..078aa14418 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -2855,7 +2855,7 @@ static int setup_keyring(
}
out:
- /* Revert back uid & gid for the the last time, and exit */
+ /* Revert back uid & gid for the last time, and exit */
/* no extra logging, as only the first already reported error matters */
if (getuid() != saved_uid)
(void) setreuid(saved_uid, -1);
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index f9c974f9b5..526ed210b3 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -668,7 +668,7 @@ int config_parse_kill_mode(
if (m == KILL_NONE)
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Unit configured to use KillMode=none. "
- "This is unsafe, as it disables systemd's process life-cycle management for the service. "
+ "This is unsafe, as it disables systemd's process lifecycle management for the service. "
"Please update your service to use a safer KillMode=, such as 'mixed' or 'control-group'. "
"Support for KillMode=none is deprecated and will eventually be removed.");
diff --git a/src/core/machine-id-setup.c b/src/core/machine-id-setup.c
index 284b77c1fc..f76b82a8a4 100644
--- a/src/core/machine-id-setup.c
+++ b/src/core/machine-id-setup.c
@@ -223,11 +223,9 @@ int machine_id_commit(const char *root) {
return log_error_errno(r, "Can't fetch current mount namespace: %m");
/* Switch to a new mount namespace, isolate ourself and unmount etc_machine_id in our new namespace */
- if (unshare(CLONE_NEWNS) < 0)
- return log_error_errno(errno, "Failed to enter new namespace: %m");
-
- if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0)
- return log_error_errno(errno, "Couldn't make-rslave / mountpoint in our private namespace: %m");
+ r = detach_mount_namespace();
+ if (r < 0)
+ return log_error_errno(r, "Failed to set up new mount namespace: %m");
if (umount(etc_machine_id) < 0)
return log_error_errno(errno, "Failed to unmount transient %s file in our private namespace: %m", etc_machine_id);
diff --git a/src/core/main.c b/src/core/main.c
index 2154c8eb12..4a376976e9 100644
--- a/src/core/main.c
+++ b/src/core/main.c
@@ -2320,6 +2320,7 @@ static void reset_arguments(void) {
arg_random_seed = mfree(arg_random_seed);
arg_random_seed_size = 0;
+ arg_clock_usec = 0;
}
static int parse_configuration(const struct rlimit *saved_rlimit_nofile,
diff --git a/src/core/manager.c b/src/core/manager.c
index 7b199f5175..743ef6b4fc 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -1932,11 +1932,19 @@ unsigned manager_dispatch_load_queue(Manager *m) {
return n;
}
-static bool manager_unit_cache_needs_refresh(Manager *m, Unit *u) {
- assert(m);
+bool manager_unit_file_maybe_loadable_from_cache(Unit *u) {
+ assert(u);
+
+ if (u->load_state != UNIT_NOT_FOUND)
+ return false;
+
+ if (u->manager->unit_cache_mtime == 0)
+ return false;
+
+ if (u->manager->unit_cache_mtime > u->fragment_loadtime)
+ return true;
- return m->unit_cache_mtime > 0 &&
- (m->unit_cache_mtime > u->fragment_loadtime || !lookup_paths_mtime_good(&m->lookup_paths, m->unit_cache_mtime));
+ return !lookup_paths_mtime_good(&u->manager->lookup_paths, u->manager->unit_cache_mtime);
}
int manager_load_unit_prepare(
@@ -1988,7 +1996,7 @@ int manager_load_unit_prepare(
* we need to try again - even if the cache is current, it might have been
* updated in a different context before we had a chance to retry loading
* this particular unit. */
- if (ret->load_state == UNIT_NOT_FOUND && manager_unit_cache_needs_refresh(m, ret))
+ if (manager_unit_file_maybe_loadable_from_cache(ret))
ret->load_state = UNIT_STUB;
else {
*_ret = ret;
diff --git a/src/core/manager.h b/src/core/manager.h
index 2cd0dacdb0..81b0c13a95 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -463,6 +463,7 @@ Unit *manager_get_unit(Manager *m, const char *name);
int manager_get_job_from_dbus_path(Manager *m, const char *s, Job **_j);
+bool manager_unit_file_maybe_loadable_from_cache(Unit *u);
int manager_load_unit_prepare(Manager *m, const char *name, const char *path, sd_bus_error *e, Unit **_ret);
int manager_load_unit(Manager *m, const char *name, const char *path, sd_bus_error *e, Unit **_ret);
int manager_load_startable_unit_or_warn(Manager *m, const char *name, const char *path, Unit **ret);
diff --git a/src/core/mount.c b/src/core/mount.c
index 8b30a4db6a..337e94e90e 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -1017,8 +1017,11 @@ static void mount_enter_mounting(Mount *m) {
/* Create the source directory for bind-mounts if needed */
p = get_mount_parameters_fragment(m);
- if (p && mount_is_bind(p))
- (void) mkdir_p_label(p->what, m->directory_mode);
+ if (p && mount_is_bind(p)) {
+ r = mkdir_p_label(p->what, m->directory_mode);
+ if (r < 0)
+ log_unit_error_errno(UNIT(m), r, "Failed to make bind mount source '%s': %m", p->what);
+ }
if (p) {
_cleanup_free_ char *opts = NULL;
diff --git a/src/core/namespace.c b/src/core/namespace.c
index 785a469478..b2bbcf58f2 100644
--- a/src/core/namespace.c
+++ b/src/core/namespace.c
@@ -747,7 +747,7 @@ static int mount_private_dev(MountEntry *m) {
NULSTR_FOREACH(d, devnodes) {
r = clone_device_node(d, temporary_mount, &can_mknod);
- /* ENXIO means the the *source* is not a device file, skip creation in that case */
+ /* ENXIO means the *source* is not a device file, skip creation in that case */
if (r < 0 && r != -ENXIO)
goto fail;
}
@@ -1034,7 +1034,7 @@ static int apply_mount(
/* Hmm, either the source or the destination are missing. Let's see if we can create the destination, then try again */
if (stat(what, &st) < 0)
- log_debug_errno(errno, "Mount point source '%s' is not accessible: %m", what);
+ log_error_errno(errno, "Mount point source '%s' is not accessible: %m", what);
else {
int q;
@@ -1046,7 +1046,7 @@ static int apply_mount(
q = touch(mount_entry_path(m));
if (q < 0)
- log_debug_errno(q, "Failed to create destination mount point node '%s': %m", mount_entry_path(m));
+ log_error_errno(q, "Failed to create destination mount point node '%s': %m", mount_entry_path(m));
else
try_again = true;
}
@@ -1060,7 +1060,7 @@ static int apply_mount(
}
if (r < 0)
- return log_debug_errno(r, "Failed to mount %s to %s: %m", what, mount_entry_path(m));
+ return log_error_errno(r, "Failed to mount %s to %s: %m", what, mount_entry_path(m));
}
log_debug("Successfully mounted %s to %s", what, mount_entry_path(m));
diff --git a/src/core/transaction.c b/src/core/transaction.c
index ef6470656c..4a57b8e3f9 100644
--- a/src/core/transaction.c
+++ b/src/core/transaction.c
@@ -954,6 +954,24 @@ int transaction_add_job_and_dependencies(
if (type != JOB_STOP) {
r = bus_unit_validate_load_state(unit, e);
+ /* The time-based cache allows to start new units without daemon-reload,
+ * but if they are already referenced (because of dependencies or ordering)
+ * then we have to force a load of the fragment. As an optimization, check
+ * first if anything in the usual paths was modified since the last time
+ * the cache was loaded. Also check if the last time an attempt to load the
+ * unit was made was before the most recent cache refresh, so that we know
+ * we need to try again - even if the cache is current, it might have been
+ * updated in a different context before we had a chance to retry loading
+ * this particular unit.
+ * Given building up the transaction is a synchronous operation, attempt
+ * to load the unit immediately. */
+ if (r < 0 && manager_unit_file_maybe_loadable_from_cache(unit)) {
+ unit->load_state = UNIT_STUB;
+ r = unit_load(unit);
+ if (r < 0 || unit->load_state == UNIT_STUB)
+ unit->load_state = UNIT_NOT_FOUND;
+ r = bus_unit_validate_load_state(unit, e);
+ }
if (r < 0)
return r;
}
diff --git a/src/core/unit.c b/src/core/unit.c
index 18bf0cd52a..edc96537cb 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -258,7 +258,7 @@ int unit_add_name(Unit *u, const char *text) {
t = unit_name_to_type(name);
if (t < 0)
return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EINVAL),
- "failed to to derive unit type from name '%s': %m", name);
+ "failed to derive unit type from name '%s': %m", name);
if (u->type != _UNIT_TYPE_INVALID && t != u->type)
return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EINVAL),
diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c
index 0c3ef3e2a7..5c9ee779ca 100644
--- a/src/firstboot/firstboot.c
+++ b/src/firstboot/firstboot.c
@@ -2,6 +2,7 @@
#include <fcntl.h>
#include <getopt.h>
+#include <linux/loop.h>
#include <unistd.h>
#include "sd-id128.h"
@@ -9,6 +10,7 @@
#include "alloc-util.h"
#include "ask-password-api.h"
#include "copy.h"
+#include "dissect-image.h"
#include "env-file.h"
#include "fd-util.h"
#include "fileio.h"
@@ -17,9 +19,12 @@
#include "kbd-util.h"
#include "libcrypt-util.h"
#include "locale-util.h"
+#include "loop-util.h"
#include "main-func.h"
#include "memory-util.h"
#include "mkdir.h"
+#include "mount-util.h"
+#include "namespace-util.h"
#include "os-util.h"
#include "parse-util.h"
#include "path-util.h"
@@ -31,10 +36,12 @@
#include "terminal-util.h"
#include "time-util.h"
#include "tmpfile-util-label.h"
+#include "tmpfile-util.h"
#include "umask-util.h"
#include "user-util.h"
static char *arg_root = NULL;
+static char *arg_image = NULL;
static char *arg_locale = NULL; /* $LANG */
static char *arg_keymap = NULL;
static char *arg_locale_messages = NULL; /* $LC_MESSAGES */
@@ -55,8 +62,10 @@ static bool arg_copy_root_password = false;
static bool arg_force = false;
static bool arg_delete_root_password = false;
static bool arg_root_password_is_hashed = false;
+static bool arg_welcome = true;
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
+STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
STATIC_DESTRUCTOR_REGISTER(arg_locale, freep);
STATIC_DESTRUCTOR_REGISTER(arg_locale_messages, freep);
STATIC_DESTRUCTOR_REGISTER(arg_keymap, freep);
@@ -85,6 +94,9 @@ static void print_welcome(void) {
const char *pn;
int r;
+ if (!arg_welcome)
+ return;
+
if (done)
return;
@@ -826,6 +838,75 @@ static int process_kernel_cmdline(void) {
return 0;
}
+static int setup_image(char **ret_mount_dir, LoopDevice **ret_loop_device, DecryptedImage **ret_decrypted_image) {
+ DissectImageFlags f = DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_VALIDATE_OS|DISSECT_IMAGE_RELAX_VAR_CHECK|DISSECT_IMAGE_FSCK;
+ _cleanup_(loop_device_unrefp) LoopDevice *d = NULL;
+ _cleanup_(decrypted_image_unrefp) DecryptedImage *decrypted_image = NULL;
+ _cleanup_(dissected_image_unrefp) DissectedImage *dissected_image = NULL;
+ _cleanup_(rmdir_and_freep) char *mount_dir = NULL;
+ _cleanup_free_ char *temp = NULL;
+ int r;
+
+ if (!arg_image) {
+ *ret_mount_dir = NULL;
+ *ret_decrypted_image = NULL;
+ *ret_loop_device = NULL;
+ return 0;
+ }
+
+ assert(!arg_root);
+
+ r = tempfn_random_child(NULL, "firstboot", &temp);
+ if (r < 0)
+ return log_error_errno(r, "Failed to generate temporary mount directory: %m");
+
+ r = loop_device_make_by_path(arg_image, O_RDWR, LO_FLAGS_PARTSCAN, &d);
+ if (r < 0)
+ return log_error_errno(r, "Failed to set up loopback device: %m");
+
+ r = dissect_image_and_warn(d->fd, arg_image, NULL, 0, NULL, f, &dissected_image);
+ if (r < 0)
+ return r;
+
+ r = dissected_image_decrypt_interactively(dissected_image, NULL, NULL, 0, NULL, NULL, NULL, 0, f, &decrypted_image);
+ if (r < 0)
+ return r;
+
+ r = detach_mount_namespace();
+ if (r < 0)
+ return log_error_errno(r, "Failed to detach mount namespace: %m");
+
+ mount_dir = strdup(temp);
+ if (!mount_dir)
+ return log_oom();
+
+ r = mkdir_p(mount_dir, 0700);
+ if (r < 0) {
+ mount_dir = mfree(mount_dir);
+ return log_error_errno(r, "Failed to create mount point: %m");
+ }
+
+ r = dissected_image_mount(dissected_image, mount_dir, UID_INVALID, f);
+ if (r < 0)
+ return log_error_errno(r, "Failed to mount image: %m");
+
+ if (decrypted_image) {
+ r = decrypted_image_relinquish(decrypted_image);
+ if (r < 0)
+ return log_error_errno(r, "Failed to relinquish DM devices: %m");
+ }
+
+ loop_device_relinquish(d);
+
+ arg_root = TAKE_PTR(temp);
+
+ *ret_mount_dir = TAKE_PTR(mount_dir);
+ *ret_decrypted_image = TAKE_PTR(decrypted_image);
+ *ret_loop_device = TAKE_PTR(d);
+
+ return 1;
+}
+
static int help(void) {
_cleanup_free_ char *link = NULL;
int r;
@@ -839,6 +920,7 @@ static int help(void) {
" -h --help Show this help\n"
" --version Show package version\n"
" --root=PATH Operate on an alternate filesystem root\n"
+ " --image=PATH Operate on an alternate filesystem image\n"
" --locale=LOCALE Set primary locale (LANG=)\n"
" --locale-messages=LOCALE Set message locale (LC_MESSAGES=)\n"
" --keymap=KEYMAP Set keymap\n"
@@ -862,6 +944,7 @@ static int help(void) {
" --setup-machine-id Generate a new random machine ID\n"
" --force Overwrite existing files\n"
" --delete-root-password Delete root password\n"
+ " --welcome=no Disable the welcome text\n"
"\nSee the %s for details.\n"
, program_invocation_short_name
, link
@@ -875,6 +958,7 @@ static int parse_argv(int argc, char *argv[]) {
enum {
ARG_VERSION = 0x100,
ARG_ROOT,
+ ARG_IMAGE,
ARG_LOCALE,
ARG_LOCALE_MESSAGES,
ARG_KEYMAP,
@@ -899,12 +983,14 @@ static int parse_argv(int argc, char *argv[]) {
ARG_SETUP_MACHINE_ID,
ARG_FORCE,
ARG_DELETE_ROOT_PASSWORD,
+ ARG_WELCOME,
};
static const struct option options[] = {
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, ARG_VERSION },
{ "root", required_argument, NULL, ARG_ROOT },
+ { "image", required_argument, NULL, ARG_IMAGE },
{ "locale", required_argument, NULL, ARG_LOCALE },
{ "locale-messages", required_argument, NULL, ARG_LOCALE_MESSAGES },
{ "keymap", required_argument, NULL, ARG_KEYMAP },
@@ -929,6 +1015,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "setup-machine-id", no_argument, NULL, ARG_SETUP_MACHINE_ID },
{ "force", no_argument, NULL, ARG_FORCE },
{ "delete-root-password", no_argument, NULL, ARG_DELETE_ROOT_PASSWORD },
+ { "welcome", required_argument, NULL, ARG_WELCOME },
{}
};
@@ -953,6 +1040,12 @@ static int parse_argv(int argc, char *argv[]) {
return r;
break;
+ case ARG_IMAGE:
+ r = parse_path_argument_and_warn(optarg, false, &arg_image);
+ if (r < 0)
+ return r;
+ break;
+
case ARG_LOCALE:
r = free_and_strdup(&arg_locale, optarg);
if (r < 0)
@@ -1086,7 +1179,6 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_SETUP_MACHINE_ID:
-
r = sd_id128_randomize(&arg_machine_id);
if (r < 0)
return log_error_errno(r, "Failed to generate randomized machine ID: %m");
@@ -1101,6 +1193,14 @@ static int parse_argv(int argc, char *argv[]) {
arg_delete_root_password = true;
break;
+ case ARG_WELCOME:
+ r = parse_boolean(optarg);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse --welcome= argument: %s", optarg);
+
+ arg_welcome = r;
+ break;
+
case '?':
return -EINVAL;
@@ -1120,11 +1220,16 @@ static int parse_argv(int argc, char *argv[]) {
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"--delete-root-password cannot be combined with other root password options");
+ if (arg_image && arg_root)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Please specify either --root= or --image=, the combination of both is not supported.");
+
return 1;
}
static int run(int argc, char *argv[]) {
- bool enabled;
+ _cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
+ _cleanup_(decrypted_image_unrefp) DecryptedImage *decrypted_image = NULL;
+ _cleanup_(umount_and_rmdir_and_freep) char *unlink_dir = NULL;
int r;
r = parse_argv(argc, argv);
@@ -1135,11 +1240,23 @@ static int run(int argc, char *argv[]) {
umask(0022);
- r = proc_cmdline_get_bool("systemd.firstboot", &enabled);
+ if (!arg_root && !arg_image) {
+ bool enabled;
+
+ /* If we are called without --root=/--image= let's honour the systemd.firstboot kernel
+ * command line option, because we are called to provision the host with basic settings (as
+ * opposed to some other file system tree/image) */
+
+ r = proc_cmdline_get_bool("systemd.firstboot", &enabled);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse systemd.firstboot= kernel command line argument, ignoring: %m");
+ if (r > 0 && !enabled)
+ return 0; /* disabled */
+ }
+
+ r = setup_image(&unlink_dir, &loop_device, &decrypted_image);
if (r < 0)
- return log_error_errno(r, "Failed to parse systemd.firstboot= kernel command line argument, ignoring: %m");
- if (r > 0 && !enabled)
- return 0; /* disabled */
+ return r;
r = process_locale();
if (r < 0)
diff --git a/src/home/homectl-fido2.c b/src/home/homectl-fido2.c
new file mode 100644
index 0000000000..b7b2c1a3b5
--- /dev/null
+++ b/src/home/homectl-fido2.c
@@ -0,0 +1,539 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#if HAVE_LIBFIDO2
+#include <fido.h>
+#endif
+
+#include "ask-password-api.h"
+#include "errno-util.h"
+#include "format-table.h"
+#include "hexdecoct.h"
+#include "homectl-fido2.h"
+#include "homectl-pkcs11.h"
+#include "libcrypt-util.h"
+#include "locale-util.h"
+#include "memory-util.h"
+#include "random-util.h"
+#include "strv.h"
+
+#if HAVE_LIBFIDO2
+static int add_fido2_credential_id(
+ JsonVariant **v,
+ const void *cid,
+ size_t cid_size) {
+
+ _cleanup_(json_variant_unrefp) JsonVariant *w = NULL;
+ _cleanup_strv_free_ char **l = NULL;
+ _cleanup_free_ char *escaped = NULL;
+ int r;
+
+ assert(v);
+ assert(cid);
+
+ r = base64mem(cid, cid_size, &escaped);
+ if (r < 0)
+ return log_error_errno(r, "Failed to base64 encode FIDO2 credential ID: %m");
+
+ w = json_variant_ref(json_variant_by_key(*v, "fido2HmacCredential"));
+ if (w) {
+ r = json_variant_strv(w, &l);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse FIDO2 credential ID list: %m");
+
+ if (strv_contains(l, escaped))
+ return 0;
+ }
+
+ r = strv_extend(&l, escaped);
+ if (r < 0)
+ return log_oom();
+
+ w = json_variant_unref(w);
+ r = json_variant_new_array_strv(&w, l);
+ if (r < 0)
+ return log_error_errno(r, "Failed to create FIDO2 credential ID JSON: %m");
+
+ r = json_variant_set_field(v, "fido2HmacCredential", w);
+ if (r < 0)
+ return log_error_errno(r, "Failed to update FIDO2 credential ID: %m");
+
+ return 0;
+}
+
+static int add_fido2_salt(
+ JsonVariant **v,
+ const void *cid,
+ size_t cid_size,
+ const void *fido2_salt,
+ size_t fido2_salt_size,
+ const void *secret,
+ size_t secret_size) {
+
+ _cleanup_(json_variant_unrefp) JsonVariant *l = NULL, *w = NULL, *e = NULL;
+ _cleanup_(erase_and_freep) char *base64_encoded = NULL;
+ _cleanup_free_ char *unix_salt = NULL;
+ struct crypt_data cd = {};
+ char *k;
+ int r;
+
+ r = make_salt(&unix_salt);
+ if (r < 0)
+ return log_error_errno(r, "Failed to generate salt: %m");
+
+ /* Before using UNIX hashing on the supplied key we base64 encode it, since crypt_r() and friends
+ * expect a NUL terminated string, and we use a binary key */
+ r = base64mem(secret, secret_size, &base64_encoded);
+ if (r < 0)
+ return log_error_errno(r, "Failed to base64 encode secret key: %m");
+
+ errno = 0;
+ k = crypt_r(base64_encoded, unix_salt, &cd);
+ if (!k)
+ return log_error_errno(errno_or_else(EINVAL), "Failed to UNIX hash secret key: %m");
+
+ r = json_build(&e, JSON_BUILD_OBJECT(
+ JSON_BUILD_PAIR("credential", JSON_BUILD_BASE64(cid, cid_size)),
+ JSON_BUILD_PAIR("salt", JSON_BUILD_BASE64(fido2_salt, fido2_salt_size)),
+ JSON_BUILD_PAIR("hashedPassword", JSON_BUILD_STRING(k))));
+ if (r < 0)
+ return log_error_errno(r, "Failed to build FIDO2 salt JSON key object: %m");
+
+ w = json_variant_ref(json_variant_by_key(*v, "privileged"));
+ l = json_variant_ref(json_variant_by_key(w, "fido2HmacSalt"));
+
+ r = json_variant_append_array(&l, e);
+ if (r < 0)
+ return log_error_errno(r, "Failed append FIDO2 salt: %m");
+
+ r = json_variant_set_field(&w, "fido2HmacSalt", l);
+ if (r < 0)
+ return log_error_errno(r, "Failed to set FDO2 salt: %m");
+
+ r = json_variant_set_field(v, "privileged", w);
+ if (r < 0)
+ return log_error_errno(r, "Failed to update privileged field: %m");
+
+ return 0;
+}
+#endif
+
+#define FIDO2_SALT_SIZE 32
+
+int identity_add_fido2_parameters(
+ JsonVariant **v,
+ const char *device) {
+
+#if HAVE_LIBFIDO2
+ _cleanup_(fido_cbor_info_free) fido_cbor_info_t *di = NULL;
+ _cleanup_(fido_assert_free) fido_assert_t *a = NULL;
+ _cleanup_(erase_and_freep) char *used_pin = NULL;
+ _cleanup_(fido_cred_free) fido_cred_t *c = NULL;
+ _cleanup_(fido_dev_free) fido_dev_t *d = NULL;
+ _cleanup_(erase_and_freep) void *salt = NULL;
+ JsonVariant *un, *realm, *rn;
+ bool found_extension = false;
+ const void *cid, *secret;
+ const char *fido_un;
+ size_t n, cid_size, secret_size;
+ char **e;
+ int r;
+
+ /* Construction is like this: we generate a salt of 32 bytes. We then ask the FIDO2 device to
+ * HMAC-SHA256 it for us with its internal key. The result is the key used by LUKS and account
+ * authentication. LUKS and UNIX password auth all do their own salting before hashing, so that FIDO2
+ * device never sees the volume key.
+ *
+ * S = HMAC-SHA256(I, D)
+ *
+ * with: S → LUKS/account authentication key (never stored)
+ * I → internal key on FIDO2 device (stored in the FIDO2 device)
+ * D → salt we generate here (stored in the privileged part of the JSON record)
+ *
+ */
+
+ assert(v);
+ assert(device);
+
+ salt = malloc(FIDO2_SALT_SIZE);
+ if (!salt)
+ return log_oom();
+
+ r = genuine_random_bytes(salt, FIDO2_SALT_SIZE, RANDOM_BLOCK);
+ if (r < 0)
+ return log_error_errno(r, "Failed to generate salt: %m");
+
+ d = fido_dev_new();
+ if (!d)
+ return log_oom();
+
+ r = fido_dev_open(d, device);
+ if (r != FIDO_OK)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to open FIDO2 device %s: %s", device, fido_strerr(r));
+
+ if (!fido_dev_is_fido2(d))
+ return log_error_errno(SYNTHETIC_ERRNO(ENODEV),
+ "Specified device %s is not a FIDO2 device.", device);
+
+ di = fido_cbor_info_new();
+ if (!di)
+ return log_oom();
+
+ r = fido_dev_get_cbor_info(d, di);
+ if (r != FIDO_OK)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to get CBOR device info for %s: %s", device, fido_strerr(r));
+
+ e = fido_cbor_info_extensions_ptr(di);
+ n = fido_cbor_info_extensions_len(di);
+
+ for (size_t i = 0; i < n; i++)
+ if (streq(e[i], "hmac-secret")) {
+ found_extension = true;
+ break;
+ }
+
+ if (!found_extension)
+ return log_error_errno(SYNTHETIC_ERRNO(ENODEV),
+ "Specified device %s is a FIDO2 device, but does not support the required HMAC-SECRET extension.", device);
+
+ c = fido_cred_new();
+ if (!c)
+ return log_oom();
+
+ r = fido_cred_set_extensions(c, FIDO_EXT_HMAC_SECRET);
+ if (r != FIDO_OK)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to enable HMAC-SECRET extension on FIDO2 credential: %s", fido_strerr(r));
+
+ r = fido_cred_set_rp(c, "io.systemd.home", "Home Directory");
+ if (r != FIDO_OK)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to set FIDO2 credential relying party ID/name: %s", fido_strerr(r));
+
+ r = fido_cred_set_type(c, COSE_ES256);
+ if (r != FIDO_OK)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to set FIDO2 credential type to ES256: %s", fido_strerr(r));
+
+ un = json_variant_by_key(*v, "userName");
+ if (!un)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "userName field of user record is missing");
+ if (!json_variant_is_string(un))
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "userName field of user record is not a string");
+
+ realm = json_variant_by_key(*v, "realm");
+ if (realm) {
+ if (!json_variant_is_string(realm))
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "realm field of user record is not a string");
+
+ fido_un = strjoina(json_variant_string(un), json_variant_string(realm));
+ } else
+ fido_un = json_variant_string(un);
+
+ rn = json_variant_by_key(*v, "realName");
+ if (rn && !json_variant_is_string(rn))
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "realName field of user record is not a string");
+
+ r = fido_cred_set_user(c,
+ (const unsigned char*) fido_un, strlen(fido_un), /* We pass the user ID and name as the same */
+ fido_un,
+ rn ? json_variant_string(rn) : NULL,
+ NULL /* icon URL */);
+ if (r != FIDO_OK)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to set FIDO2 credential user data: %s", fido_strerr(r));
+
+ r = fido_cred_set_clientdata_hash(c, (const unsigned char[32]) {}, 32);
+ if (r != FIDO_OK)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to set FIDO2 client data hash: %s", fido_strerr(r));
+
+ r = fido_cred_set_rk(c, FIDO_OPT_FALSE);
+ if (r != FIDO_OK)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to turn off FIDO2 resident key option of credential: %s", fido_strerr(r));
+
+ r = fido_cred_set_uv(c, FIDO_OPT_FALSE);
+ if (r != FIDO_OK)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to turn off FIDO2 user verification option of credential: %s", fido_strerr(r));
+
+ log_info("Initializing FIDO2 credential on security token.");
+
+ log_notice("%s%s(Hint: This might require verification of user presence on security token.)",
+ emoji_enabled() ? special_glyph(SPECIAL_GLYPH_TOUCH) : "",
+ emoji_enabled() ? " " : "");
+
+ r = fido_dev_make_cred(d, c, NULL);
+ if (r == FIDO_ERR_PIN_REQUIRED) {
+ _cleanup_free_ char *text = NULL;
+
+ if (asprintf(&text, "Please enter security token PIN:") < 0)
+ return log_oom();
+
+ for (;;) {
+ _cleanup_(strv_free_erasep) char **pin = NULL;
+ char **i;
+
+ r = ask_password_auto(text, "user-home", NULL, "fido2-pin", USEC_INFINITY, 0, &pin);
+ if (r < 0)
+ return log_error_errno(r, "Failed to acquire user PIN: %m");
+
+ r = FIDO_ERR_PIN_INVALID;
+ STRV_FOREACH(i, pin) {
+ if (isempty(*i)) {
+ log_info("PIN may not be empty.");
+ continue;
+ }
+
+ r = fido_dev_make_cred(d, c, *i);
+ if (r == FIDO_OK) {
+ used_pin = strdup(*i);
+ if (!used_pin)
+ return log_oom();
+ break;
+ }
+ if (r != FIDO_ERR_PIN_INVALID)
+ break;
+ }
+
+ if (r != FIDO_ERR_PIN_INVALID)
+ break;
+
+ log_notice("PIN incorrect, please try again.");
+ }
+ }
+ if (r == FIDO_ERR_PIN_AUTH_BLOCKED)
+ return log_notice_errno(SYNTHETIC_ERRNO(EPERM),
+ "Token PIN is currently blocked, please remove and reinsert token.");
+ if (r == FIDO_ERR_ACTION_TIMEOUT)
+ return log_error_errno(SYNTHETIC_ERRNO(ENOSTR),
+ "Token action timeout. (User didn't interact with token quickly enough.)");
+ if (r != FIDO_OK)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to generate FIDO2 credential: %s", fido_strerr(r));
+
+ cid = fido_cred_id_ptr(c);
+ if (!cid)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to get FIDO2 credential ID.");
+
+ cid_size = fido_cred_id_len(c);
+
+ a = fido_assert_new();
+ if (!a)
+ return log_oom();
+
+ r = fido_assert_set_extensions(a, FIDO_EXT_HMAC_SECRET);
+ if (r != FIDO_OK)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to enable HMAC-SECRET extension on FIDO2 assertion: %s", fido_strerr(r));
+
+ r = fido_assert_set_hmac_salt(a, salt, FIDO2_SALT_SIZE);
+ if (r != FIDO_OK)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to set salt on FIDO2 assertion: %s", fido_strerr(r));
+
+ r = fido_assert_set_rp(a, "io.systemd.home");
+ if (r != FIDO_OK)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to set FIDO2 assertion ID: %s", fido_strerr(r));
+
+ r = fido_assert_set_clientdata_hash(a, (const unsigned char[32]) {}, 32);
+ if (r != FIDO_OK)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to set FIDO2 assertion client data hash: %s", fido_strerr(r));
+
+ r = fido_assert_allow_cred(a, cid, cid_size);
+ if (r != FIDO_OK)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to add FIDO2 assertion credential ID: %s", fido_strerr(r));
+
+ r = fido_assert_set_up(a, FIDO_OPT_FALSE);
+ if (r != FIDO_OK)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to turn off FIDO2 assertion user presence: %s", fido_strerr(r));
+
+ log_info("Generating secret key on FIDO2 security token.");
+
+ r = fido_dev_get_assert(d, a, used_pin);
+ if (r == FIDO_ERR_UP_REQUIRED) {
+ r = fido_assert_set_up(a, FIDO_OPT_TRUE);
+ if (r != FIDO_OK)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to turn on FIDO2 assertion user presence: %s", fido_strerr(r));
+
+ log_notice("%s%sIn order to allow secret key generation, please verify presence on security token.",
+ emoji_enabled() ? special_glyph(SPECIAL_GLYPH_TOUCH) : "",
+ emoji_enabled() ? " " : "");
+
+ r = fido_dev_get_assert(d, a, used_pin);
+ }
+ if (r == FIDO_ERR_ACTION_TIMEOUT)
+ return log_error_errno(SYNTHETIC_ERRNO(ENOSTR),
+ "Token action timeout. (User didn't interact with token quickly enough.)");
+ if (r != FIDO_OK)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to ask token for assertion: %s", fido_strerr(r));
+
+ secret = fido_assert_hmac_secret_ptr(a, 0);
+ if (!secret)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to retrieve HMAC secret.");
+
+ secret_size = fido_assert_hmac_secret_len(a, 0);
+
+ r = add_fido2_credential_id(v, cid, cid_size);
+ if (r < 0)
+ return r;
+
+ r = add_fido2_salt(v,
+ cid,
+ cid_size,
+ salt,
+ FIDO2_SALT_SIZE,
+ secret,
+ secret_size);
+ if (r < 0)
+ return r;
+
+ /* If we acquired the PIN also include it in the secret section of the record, so that systemd-homed
+ * can use it if it needs to, given that it likely needs to decrypt the key again to pass to LUKS or
+ * fscrypt. */
+ r = identity_add_token_pin(v, used_pin);
+ if (r < 0)
+ return r;
+
+ return 0;
+#else
+ return log_error_errno(EOPNOTSUPP, "FIDO2 tokens not supported on this build.");
+#endif
+}
+
+int list_fido2_devices(void) {
+#if HAVE_LIBFIDO2
+ _cleanup_(table_unrefp) Table *t = NULL;
+ size_t allocated = 64, found = 0;
+ fido_dev_info_t *di = NULL;
+ int r;
+
+ di = fido_dev_info_new(allocated);
+ if (!di)
+ return log_oom();
+
+ r = fido_dev_info_manifest(di, allocated, &found);
+ if (r == FIDO_ERR_INTERNAL || (r == FIDO_OK && found == 0)) {
+ /* The library returns FIDO_ERR_INTERNAL when no devices are found. I wish it wouldn't. */
+ log_info("No FIDO2 devices found.");
+ r = 0;
+ goto finish;
+ }
+ if (r != FIDO_OK) {
+ r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to enumerate FIDO2 devices: %s", fido_strerr(r));
+ goto finish;
+ }
+
+ t = table_new("path", "manufacturer", "product");
+ if (!t) {
+ r = log_oom();
+ goto finish;
+ }
+
+ for (size_t i = 0; i < found; i++) {
+ const fido_dev_info_t *entry;
+
+ entry = fido_dev_info_ptr(di, i);
+ if (!entry) {
+ r = log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to get device information for FIDO device %zu.", i);
+ goto finish;
+ }
+
+ r = table_add_many(
+ t,
+ TABLE_PATH, fido_dev_info_path(entry),
+ TABLE_STRING, fido_dev_info_manufacturer_string(entry),
+ TABLE_STRING, fido_dev_info_product_string(entry));
+ if (r < 0) {
+ table_log_add_error(r);
+ goto finish;
+ }
+ }
+
+ r = table_print(t, stdout);
+ if (r < 0) {
+ log_error_errno(r, "Failed to show device table: %m");
+ goto finish;
+ }
+
+ r = 0;
+
+finish:
+ fido_dev_info_free(&di, allocated);
+ return r;
+#else
+ return log_error_errno(EOPNOTSUPP, "FIDO2 tokens not supported on this build.");
+#endif
+}
+
+int find_fido2_auto(char **ret) {
+#if HAVE_LIBFIDO2
+ _cleanup_free_ char *copy = NULL;
+ size_t di_size = 64, found = 0;
+ const fido_dev_info_t *entry;
+ fido_dev_info_t *di = NULL;
+ const char *path;
+ int r;
+
+ di = fido_dev_info_new(di_size);
+ if (!di)
+ return log_oom();
+
+ r = fido_dev_info_manifest(di, di_size, &found);
+ if (r == FIDO_ERR_INTERNAL || (r == FIDO_OK && found == 0)) {
+ /* The library returns FIDO_ERR_INTERNAL when no devices are found. I wish it wouldn't. */
+ r = log_error_errno(SYNTHETIC_ERRNO(ENODEV), "No FIDO2 devices found.");
+ goto finish;
+ }
+ if (r != FIDO_OK) {
+ r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to enumerate FIDO2 devices: %s", fido_strerr(r));
+ goto finish;
+ }
+ if (found > 1) {
+ r = log_error_errno(SYNTHETIC_ERRNO(ENOTUNIQ), "More than one FIDO2 device found.");
+ goto finish;
+ }
+
+ entry = fido_dev_info_ptr(di, 0);
+ if (!entry) {
+ r = log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to get device information for FIDO device 0.");
+ goto finish;
+ }
+
+ path = fido_dev_info_path(entry);
+ if (!path) {
+ r = log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to query FIDO device path.");
+ goto finish;
+ }
+
+ copy = strdup(path);
+ if (!copy) {
+ r = log_oom();
+ goto finish;
+ }
+
+ *ret = TAKE_PTR(copy);
+ r = 0;
+
+finish:
+ fido_dev_info_free(&di, di_size);
+ return r;
+#else
+ return log_error_errno(EOPNOTSUPP, "FIDO2 tokens not supported on this build.");
+#endif
+}
diff --git a/src/home/homectl-fido2.h b/src/home/homectl-fido2.h
new file mode 100644
index 0000000000..0d9faefa81
--- /dev/null
+++ b/src/home/homectl-fido2.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+#include "json.h"
+
+int identity_add_fido2_parameters(JsonVariant **v, const char *device);
+
+int list_fido2_devices(void);
+
+int find_fido2_auto(char **ret);
diff --git a/src/home/homectl-pkcs11.c b/src/home/homectl-pkcs11.c
new file mode 100644
index 0000000000..830aafaab1
--- /dev/null
+++ b/src/home/homectl-pkcs11.c
@@ -0,0 +1,480 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include "errno-util.h"
+#include "format-table.h"
+#include "hexdecoct.h"
+#include "homectl-pkcs11.h"
+#include "libcrypt-util.h"
+#include "memory-util.h"
+#include "openssl-util.h"
+#include "pkcs11-util.h"
+#include "random-util.h"
+#include "strv.h"
+
+struct pkcs11_callback_data {
+ char *pin_used;
+ X509 *cert;
+};
+
+static void pkcs11_callback_data_release(struct pkcs11_callback_data *data) {
+ erase_and_free(data->pin_used);
+ X509_free(data->cert);
+}
+
+#if HAVE_P11KIT
+static int pkcs11_callback(
+ CK_FUNCTION_LIST *m,
+ CK_SESSION_HANDLE session,
+ CK_SLOT_ID slot_id,
+ const CK_SLOT_INFO *slot_info,
+ const CK_TOKEN_INFO *token_info,
+ P11KitUri *uri,
+ void *userdata) {
+
+ _cleanup_(erase_and_freep) char *pin_used = NULL;
+ struct pkcs11_callback_data *data = userdata;
+ CK_OBJECT_HANDLE object;
+ int r;
+
+ assert(m);
+ assert(slot_info);
+ assert(token_info);
+ assert(uri);
+ assert(data);
+
+ /* Called for every token matching our URI */
+
+ r = pkcs11_token_login(m, session, slot_id, token_info, "home directory operation", "user-home", "pkcs11-pin", UINT64_MAX, &pin_used);
+ if (r < 0)
+ return r;
+
+ r = pkcs11_token_find_x509_certificate(m, session, uri, &object);
+ if (r < 0)
+ return r;
+
+ r = pkcs11_token_read_x509_certificate(m, session, object, &data->cert);
+ if (r < 0)
+ return r;
+
+ /* Let's read some random data off the token and write it to the kernel pool before we generate our
+ * random key from it. This way we can claim the quality of the RNG is at least as good as the
+ * kernel's and the token's pool */
+ (void) pkcs11_token_acquire_rng(m, session);
+
+ data->pin_used = TAKE_PTR(pin_used);
+ return 1;
+}
+#endif
+
+static int acquire_pkcs11_certificate(
+ const char *uri,
+ X509 **ret_cert,
+ char **ret_pin_used) {
+
+#if HAVE_P11KIT
+ _cleanup_(pkcs11_callback_data_release) struct pkcs11_callback_data data = {};
+ int r;
+
+ r = pkcs11_find_token(uri, pkcs11_callback, &data);
+ if (r == -EAGAIN) /* pkcs11_find_token() doesn't log about this error, but all others */
+ return log_error_errno(ENXIO, "Specified PKCS#11 token with URI '%s' not found.", uri);
+ if (r < 0)
+ return r;
+
+ *ret_cert = TAKE_PTR(data.cert);
+ *ret_pin_used = TAKE_PTR(data.pin_used);
+
+ return 0;
+#else
+ return log_error_errno(EOPNOTSUPP, "PKCS#11 tokens not supported on this build.");
+#endif
+}
+
+static int encrypt_bytes(
+ EVP_PKEY *pkey,
+ const void *decrypted_key,
+ size_t decrypted_key_size,
+ void **ret_encrypt_key,
+ size_t *ret_encrypt_key_size) {
+
+ _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = NULL;
+ _cleanup_free_ void *b = NULL;
+ size_t l;
+
+ ctx = EVP_PKEY_CTX_new(pkey, NULL);
+ if (!ctx)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to allocate public key context");
+
+ if (EVP_PKEY_encrypt_init(ctx) <= 0)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to initialize public key context");
+
+ if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to configure PKCS#1 padding");
+
+ if (EVP_PKEY_encrypt(ctx, NULL, &l, decrypted_key, decrypted_key_size) <= 0)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to determine encrypted key size");
+
+ b = malloc(l);
+ if (!b)
+ return log_oom();
+
+ if (EVP_PKEY_encrypt(ctx, b, &l, decrypted_key, decrypted_key_size) <= 0)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to determine encrypted key size");
+
+ *ret_encrypt_key = TAKE_PTR(b);
+ *ret_encrypt_key_size = l;
+
+ return 0;
+}
+
+static int add_pkcs11_encrypted_key(
+ JsonVariant **v,
+ const char *uri,
+ const void *encrypted_key, size_t encrypted_key_size,
+ const void *decrypted_key, size_t decrypted_key_size) {
+
+ _cleanup_(json_variant_unrefp) JsonVariant *l = NULL, *w = NULL, *e = NULL;
+ _cleanup_(erase_and_freep) char *base64_encoded = NULL;
+ _cleanup_free_ char *salt = NULL;
+ struct crypt_data cd = {};
+ char *k;
+ int r;
+
+ assert(v);
+ assert(uri);
+ assert(encrypted_key);
+ assert(encrypted_key_size > 0);
+ assert(decrypted_key);
+ assert(decrypted_key_size > 0);
+
+ r = make_salt(&salt);
+ if (r < 0)
+ return log_error_errno(r, "Failed to generate salt: %m");
+
+ /* Before using UNIX hashing on the supplied key we base64 encode it, since crypt_r() and friends
+ * expect a NUL terminated string, and we use a binary key */
+ r = base64mem(decrypted_key, decrypted_key_size, &base64_encoded);
+ if (r < 0)
+ return log_error_errno(r, "Failed to base64 encode secret key: %m");
+
+ errno = 0;
+ k = crypt_r(base64_encoded, salt, &cd);
+ if (!k)
+ return log_error_errno(errno_or_else(EINVAL), "Failed to UNIX hash secret key: %m");
+
+ r = json_build(&e, JSON_BUILD_OBJECT(
+ JSON_BUILD_PAIR("uri", JSON_BUILD_STRING(uri)),
+ JSON_BUILD_PAIR("data", JSON_BUILD_BASE64(encrypted_key, encrypted_key_size)),
+ JSON_BUILD_PAIR("hashedPassword", JSON_BUILD_STRING(k))));
+ if (r < 0)
+ return log_error_errno(r, "Failed to build encrypted JSON key object: %m");
+
+ w = json_variant_ref(json_variant_by_key(*v, "privileged"));
+ l = json_variant_ref(json_variant_by_key(w, "pkcs11EncryptedKey"));
+
+ r = json_variant_append_array(&l, e);
+ if (r < 0)
+ return log_error_errno(r, "Failed append PKCS#11 encrypted key: %m");
+
+ r = json_variant_set_field(&w, "pkcs11EncryptedKey", l);
+ if (r < 0)
+ return log_error_errno(r, "Failed to set PKCS#11 encrypted key: %m");
+
+ r = json_variant_set_field(v, "privileged", w);
+ if (r < 0)
+ return log_error_errno(r, "Failed to update privileged field: %m");
+
+ return 0;
+}
+
+static int add_pkcs11_token_uri(JsonVariant **v, const char *uri) {
+ _cleanup_(json_variant_unrefp) JsonVariant *w = NULL;
+ _cleanup_strv_free_ char **l = NULL;
+ int r;
+
+ assert(v);
+ assert(uri);
+
+ w = json_variant_ref(json_variant_by_key(*v, "pkcs11TokenUri"));
+ if (w) {
+ r = json_variant_strv(w, &l);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse PKCS#11 token list: %m");
+
+ if (strv_contains(l, uri))
+ return 0;
+ }
+
+ r = strv_extend(&l, uri);
+ if (r < 0)
+ return log_oom();
+
+ w = json_variant_unref(w);
+ r = json_variant_new_array_strv(&w, l);
+ if (r < 0)
+ return log_error_errno(r, "Failed to create PKCS#11 token URI JSON: %m");
+
+ r = json_variant_set_field(v, "pkcs11TokenUri", w);
+ if (r < 0)
+ return log_error_errno(r, "Failed to update PKCS#11 token URI list: %m");
+
+ return 0;
+}
+
+int identity_add_token_pin(JsonVariant **v, const char *pin) {
+ _cleanup_(json_variant_unrefp) JsonVariant *w = NULL, *l = NULL;
+ _cleanup_(strv_free_erasep) char **pins = NULL;
+ int r;
+
+ assert(v);
+
+ if (isempty(pin))
+ return 0;
+
+ w = json_variant_ref(json_variant_by_key(*v, "secret"));
+ l = json_variant_ref(json_variant_by_key(w, "tokenPin"));
+
+ r = json_variant_strv(l, &pins);
+ if (r < 0)
+ return log_error_errno(r, "Failed to convert PIN array: %m");
+
+ if (strv_find(pins, pin))
+ return 0;
+
+ r = strv_extend(&pins, pin);
+ if (r < 0)
+ return log_oom();
+
+ strv_uniq(pins);
+
+ l = json_variant_unref(l);
+
+ r = json_variant_new_array_strv(&l, pins);
+ if (r < 0)
+ return log_error_errno(r, "Failed to allocate new PIN array JSON: %m");
+
+ json_variant_sensitive(l);
+
+ r = json_variant_set_field(&w, "tokenPin", l);
+ if (r < 0)
+ return log_error_errno(r, "Failed to update PIN field: %m");
+
+ r = json_variant_set_field(v, "secret", w);
+ if (r < 0)
+ return log_error_errno(r, "Failed to update secret object: %m");
+
+ return 1;
+}
+
+int identity_add_pkcs11_key_data(JsonVariant **v, const char *uri) {
+ _cleanup_(erase_and_freep) void *decrypted_key = NULL, *encrypted_key = NULL;
+ _cleanup_(erase_and_freep) char *pin = NULL;
+ size_t decrypted_key_size, encrypted_key_size;
+ _cleanup_(X509_freep) X509 *cert = NULL;
+ EVP_PKEY *pkey;
+ RSA *rsa;
+ int bits;
+ int r;
+
+ assert(v);
+
+ r = acquire_pkcs11_certificate(uri, &cert, &pin);
+ if (r < 0)
+ return r;
+
+ pkey = X509_get0_pubkey(cert);
+ if (!pkey)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to extract public key from X.509 certificate.");
+
+ if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA)
+ return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "X.509 certificate does not refer to RSA key.");
+
+ rsa = EVP_PKEY_get0_RSA(pkey);
+ if (!rsa)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to acquire RSA public key from X.509 certificate.");
+
+ bits = RSA_bits(rsa);
+ log_debug("Bits in RSA key: %i", bits);
+
+ /* We use PKCS#1 padding for the RSA cleartext, hence let's leave some extra space for it, hence only
+ * generate a random key half the size of the RSA length */
+ decrypted_key_size = bits / 8 / 2;
+
+ if (decrypted_key_size < 1)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO), "Uh, RSA key size too short?");
+
+ log_debug("Generating %zu bytes random key.", decrypted_key_size);
+
+ decrypted_key = malloc(decrypted_key_size);
+ if (!decrypted_key)
+ return log_oom();
+
+ r = genuine_random_bytes(decrypted_key, decrypted_key_size, RANDOM_BLOCK);
+ if (r < 0)
+ return log_error_errno(r, "Failed to generate random key: %m");
+
+ r = encrypt_bytes(pkey, decrypted_key, decrypted_key_size, &encrypted_key, &encrypted_key_size);
+ if (r < 0)
+ return log_error_errno(r, "Failed to encrypt key: %m");
+
+ /* Add the token URI to the public part of the record. */
+ r = add_pkcs11_token_uri(v, uri);
+ if (r < 0)
+ return r;
+
+ /* Include the encrypted version of the random key we just generated in the privileged part of the record */
+ r = add_pkcs11_encrypted_key(
+ v,
+ uri,
+ encrypted_key, encrypted_key_size,
+ decrypted_key, decrypted_key_size);
+ if (r < 0)
+ return r;
+
+ /* If we acquired the PIN also include it in the secret section of the record, so that systemd-homed
+ * can use it if it needs to, given that it likely needs to decrypt the key again to pass to LUKS or
+ * fscrypt. */
+ r = identity_add_token_pin(v, pin);
+ if (r < 0)
+ return r;
+
+ return 0;
+}
+
+#if HAVE_P11KIT
+static int list_callback(
+ CK_FUNCTION_LIST *m,
+ CK_SESSION_HANDLE session,
+ CK_SLOT_ID slot_id,
+ const CK_SLOT_INFO *slot_info,
+ const CK_TOKEN_INFO *token_info,
+ P11KitUri *uri,
+ void *userdata) {
+
+ _cleanup_free_ char *token_uri_string = NULL, *token_label = NULL, *token_manufacturer_id = NULL, *token_model = NULL;
+ _cleanup_(p11_kit_uri_freep) P11KitUri *token_uri = NULL;
+ Table *t = userdata;
+ int uri_result, r;
+
+ assert(slot_info);
+ assert(token_info);
+
+ /* We only care about hardware devices here with a token inserted. Let's filter everything else
+ * out. (Note that the user can explicitly specify non-hardware tokens if they like, but during
+ * enumeration we'll filter those, since software tokens are typically the system certificate store
+ * and such, and it's typically not what people want to bind their home directories to.) */
+ if (!FLAGS_SET(token_info->flags, CKF_HW_SLOT|CKF_TOKEN_PRESENT))
+ return -EAGAIN;
+
+ token_label = pkcs11_token_label(token_info);
+ if (!token_label)
+ return log_oom();
+
+ token_manufacturer_id = pkcs11_token_manufacturer_id(token_info);
+ if (!token_manufacturer_id)
+ return log_oom();
+
+ token_model = pkcs11_token_model(token_info);
+ if (!token_model)
+ return log_oom();
+
+ token_uri = uri_from_token_info(token_info);
+ if (!token_uri)
+ return log_oom();
+
+ uri_result = p11_kit_uri_format(token_uri, P11_KIT_URI_FOR_ANY, &token_uri_string);
+ if (uri_result != P11_KIT_URI_OK)
+ return log_warning_errno(SYNTHETIC_ERRNO(EAGAIN), "Failed to format slot URI: %s", p11_kit_uri_message(uri_result));
+
+ r = table_add_many(
+ t,
+ TABLE_STRING, token_uri_string,
+ TABLE_STRING, token_label,
+ TABLE_STRING, token_manufacturer_id,
+ TABLE_STRING, token_model);
+ if (r < 0)
+ return table_log_add_error(r);
+
+ return -EAGAIN; /* keep scanning */
+}
+#endif
+
+int list_pkcs11_tokens(void) {
+#if HAVE_P11KIT
+ _cleanup_(table_unrefp) Table *t = NULL;
+ int r;
+
+ t = table_new("uri", "label", "manufacturer", "model");
+ if (!t)
+ return log_oom();
+
+ r = pkcs11_find_token(NULL, list_callback, t);
+ if (r < 0 && r != -EAGAIN)
+ return r;
+
+ if (table_get_rows(t) <= 1) {
+ log_info("No suitable PKCS#11 tokens found.");
+ return 0;
+ }
+
+ r = table_print(t, stdout);
+ if (r < 0)
+ return log_error_errno(r, "Failed to show device table: %m");
+
+ return 0;
+#else
+ return log_error_errno(EOPNOTSUPP, "PKCS#11 tokens not supported on this build.");
+#endif
+}
+
+#if HAVE_P11KIT
+static int auto_callback(
+ CK_FUNCTION_LIST *m,
+ CK_SESSION_HANDLE session,
+ CK_SLOT_ID slot_id,
+ const CK_SLOT_INFO *slot_info,
+ const CK_TOKEN_INFO *token_info,
+ P11KitUri *uri,
+ void *userdata) {
+
+ _cleanup_(p11_kit_uri_freep) P11KitUri *token_uri = NULL;
+ char **t = userdata;
+ int uri_result;
+
+ assert(slot_info);
+ assert(token_info);
+
+ if (!FLAGS_SET(token_info->flags, CKF_HW_SLOT|CKF_TOKEN_PRESENT))
+ return -EAGAIN;
+
+ if (*t)
+ return log_error_errno(SYNTHETIC_ERRNO(ENOTUNIQ),
+ "More than one suitable PKCS#11 token found.");
+
+ token_uri = uri_from_token_info(token_info);
+ if (!token_uri)
+ return log_oom();
+
+ uri_result = p11_kit_uri_format(token_uri, P11_KIT_URI_FOR_ANY, t);
+ if (uri_result != P11_KIT_URI_OK)
+ return log_warning_errno(SYNTHETIC_ERRNO(EAGAIN), "Failed to format slot URI: %s", p11_kit_uri_message(uri_result));
+
+ return 0;
+}
+#endif
+
+int find_pkcs11_token_auto(char **ret) {
+#if HAVE_P11KIT
+ int r;
+
+ r = pkcs11_find_token(NULL, auto_callback, ret);
+ if (r == -EAGAIN)
+ return log_error_errno(SYNTHETIC_ERRNO(ENODEV), "No suitable PKCS#11 tokens found.");
+ if (r < 0)
+ return r;
+
+ return 0;
+#else
+ return log_error_errno(EOPNOTSUPP, "PKCS#11 tokens not supported on this build.");
+#endif
+}
diff --git a/src/home/homectl-pkcs11.h b/src/home/homectl-pkcs11.h
new file mode 100644
index 0000000000..0403c73ea1
--- /dev/null
+++ b/src/home/homectl-pkcs11.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+#include "json.h"
+
+int identity_add_token_pin(JsonVariant **v, const char *pin);
+
+int identity_add_pkcs11_key_data(JsonVariant **v, const char *token_uri);
+
+int list_pkcs11_tokens(void);
+int find_pkcs11_token_auto(char **ret);
diff --git a/src/home/homectl.c b/src/home/homectl.c
index 47a506f5e0..149f960f76 100644
--- a/src/home/homectl.c
+++ b/src/home/homectl.c
@@ -4,7 +4,6 @@
#include "sd-bus.h"
-#include "alloc-util.h"
#include "ask-password-api.h"
#include "bus-common-errors.h"
#include "bus-error.h"
@@ -15,15 +14,12 @@
#include "fd-util.h"
#include "fileio.h"
#include "format-table.h"
-#include "format-util.h"
-#include "fs-util.h"
-#include "hexdecoct.h"
#include "home-util.h"
-#include "libcrypt-util.h"
+#include "homectl-fido2.h"
+#include "homectl-pkcs11.h"
#include "locale-util.h"
#include "main-func.h"
#include "memory-util.h"
-#include "openssl-util.h"
#include "pager.h"
#include "parse-util.h"
#include "path-util.h"
@@ -31,7 +27,6 @@
#include "pretty-print.h"
#include "process-util.h"
#include "pwquality-util.h"
-#include "random-util.h"
#include "rlimit-util.h"
#include "spawn-polkit-agent.h"
#include "terminal-util.h"
@@ -56,6 +51,7 @@ static char **arg_identity_filter_rlimits = NULL;
static uint64_t arg_disk_size = UINT64_MAX;
static uint64_t arg_disk_size_relative = UINT64_MAX;
static char **arg_pkcs11_token_uri = NULL;
+static char **arg_fido2_device = NULL;
static bool arg_json = false;
static JsonFormatFlags arg_json_format_flags = 0;
static bool arg_and_resize = false;
@@ -73,6 +69,7 @@ STATIC_DESTRUCTOR_REGISTER(arg_identity_extra_rlimits, json_variant_unrefp);
STATIC_DESTRUCTOR_REGISTER(arg_identity_filter, strv_freep);
STATIC_DESTRUCTOR_REGISTER(arg_identity_filter_rlimits, strv_freep);
STATIC_DESTRUCTOR_REGISTER(arg_pkcs11_token_uri, strv_freep);
+STATIC_DESTRUCTOR_REGISTER(arg_fido2_device, strv_freep);
static bool identity_properties_specified(void) {
return
@@ -83,7 +80,8 @@ static bool identity_properties_specified(void) {
!json_variant_is_blank_object(arg_identity_extra_rlimits) ||
!strv_isempty(arg_identity_filter) ||
!strv_isempty(arg_identity_filter_rlimits) ||
- !strv_isempty(arg_pkcs11_token_uri);
+ !strv_isempty(arg_pkcs11_token_uri) ||
+ !strv_isempty(arg_fido2_device);
}
static int acquire_bus(sd_bus **bus) {
@@ -144,12 +142,12 @@ static int list_homes(int argc, char *argv[], void *userdata) {
TABLE_UID, uid,
TABLE_GID, gid);
if (r < 0)
- return log_error_errno(r, "Failed to add row to table: %m");
+ return table_log_add_error(r);
r = table_add_cell(table, &cell, TABLE_STRING, state);
if (r < 0)
- return log_error_errno(r, "Failed to add field to table: %m");
+ return table_log_add_error(r);
color = user_record_state_color(state);
if (color)
@@ -160,7 +158,7 @@ static int list_homes(int argc, char *argv[], void *userdata) {
TABLE_STRING, home,
TABLE_STRING, strna(empty_to_null(shell)));
if (r < 0)
- return log_error_errno(r, "Failed to add row to table: %m");
+ return table_log_add_error(r);
}
r = sd_bus_message_exit_container(reply);
@@ -236,7 +234,7 @@ static int acquire_existing_password(const char *user_name, UserRecord *hr, bool
return 0;
}
-static int acquire_pkcs11_pin(const char *user_name, UserRecord *hr) {
+static int acquire_token_pin(const char *user_name, UserRecord *hr) {
_cleanup_(strv_free_erasep) char **pin = NULL;
_cleanup_free_ char *question = NULL;
char *e;
@@ -247,9 +245,9 @@ static int acquire_pkcs11_pin(const char *user_name, UserRecord *hr) {
e = getenv("PIN");
if (e) {
- r = user_record_set_pkcs11_pin(hr, STRV_MAKE(e), false);
+ r = user_record_set_token_pin(hr, STRV_MAKE(e), false);
if (r < 0)
- return log_error_errno(r, "Failed to store PKCS#11 PIN: %m");
+ return log_error_errno(r, "Failed to store token PIN: %m");
string_erase(e);
@@ -263,11 +261,11 @@ static int acquire_pkcs11_pin(const char *user_name, UserRecord *hr) {
return log_oom();
/* We never cache or use cached PINs, since usually there are only very few attempts allowed before the PIN is blocked */
- r = ask_password_auto(question, "user-home", NULL, "pkcs11-pin", USEC_INFINITY, 0, &pin);
+ r = ask_password_auto(question, "user-home", NULL, "token-pin", USEC_INFINITY, 0, &pin);
if (r < 0)
return log_error_errno(r, "Failed to acquire security token PIN: %m");
- r = user_record_set_pkcs11_pin(hr, pin, false);
+ r = user_record_set_token_pin(hr, pin, false);
if (r < 0)
return log_error_errno(r, "Failed to store security token PIN: %m");
@@ -315,26 +313,38 @@ static int handle_generic_user_record_error(
} else if (sd_bus_error_has_name(error, BUS_ERROR_TOKEN_PIN_NEEDED)) {
- r = acquire_pkcs11_pin(user_name, hr);
+ r = acquire_token_pin(user_name, hr);
if (r < 0)
return r;
} else if (sd_bus_error_has_name(error, BUS_ERROR_TOKEN_PROTECTED_AUTHENTICATION_PATH_NEEDED)) {
- log_notice("Please authenticate physically on security token.");
+ log_notice("%s%sPlease authenticate physically on security token.",
+ emoji_enabled() ? special_glyph(SPECIAL_GLYPH_TOUCH) : "",
+ emoji_enabled() ? " " : "");
r = user_record_set_pkcs11_protected_authentication_path_permitted(hr, true);
if (r < 0)
return log_error_errno(r, "Failed to set PKCS#11 protected authentication path permitted flag: %m");
+ } else if (sd_bus_error_has_name(error, BUS_ERROR_TOKEN_USER_PRESENCE_NEEDED)) {
+
+ log_notice("%s%sAuthentication requires presence verification on security token.",
+ emoji_enabled() ? special_glyph(SPECIAL_GLYPH_TOUCH) : "",
+ emoji_enabled() ? " " : "");
+
+ r = user_record_set_fido2_user_presence_permitted(hr, true);
+ if (r < 0)
+ return log_error_errno(r, "Failed to set FIDO2 user presence permitted flag: %m");
+
} else if (sd_bus_error_has_name(error, BUS_ERROR_TOKEN_PIN_LOCKED))
- return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Security token PIN is locked, please unlock security token PIN first.");
+ return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Security token PIN is locked, please unlock it first. (Hint: Removal and re-insertion might suffice.)");
else if (sd_bus_error_has_name(error, BUS_ERROR_TOKEN_BAD_PIN)) {
log_notice("Security token PIN incorrect, please try again.");
- r = acquire_pkcs11_pin(user_name, hr);
+ r = acquire_token_pin(user_name, hr);
if (r < 0)
return r;
@@ -342,7 +352,7 @@ static int handle_generic_user_record_error(
log_notice("Security token PIN incorrect, please try again (only a few tries left!).");
- r = acquire_pkcs11_pin(user_name, hr);
+ r = acquire_token_pin(user_name, hr);
if (r < 0)
return r;
@@ -350,7 +360,7 @@ static int handle_generic_user_record_error(
log_notice("Security token PIN incorrect, please try again (only one try left!).");
- r = acquire_pkcs11_pin(user_name, hr);
+ r = acquire_token_pin(user_name, hr);
if (r < 0)
return r;
} else
@@ -889,336 +899,6 @@ static int add_disposition(JsonVariant **v) {
return 1;
}
-struct pkcs11_callback_data {
- char *pin_used;
- X509 *cert;
-};
-
-static void pkcs11_callback_data_release(struct pkcs11_callback_data *data) {
- erase_and_free(data->pin_used);
- X509_free(data->cert);
-}
-
-#if HAVE_P11KIT
-static int pkcs11_callback(
- CK_FUNCTION_LIST *m,
- CK_SESSION_HANDLE session,
- CK_SLOT_ID slot_id,
- const CK_SLOT_INFO *slot_info,
- const CK_TOKEN_INFO *token_info,
- P11KitUri *uri,
- void *userdata) {
-
- _cleanup_(erase_and_freep) char *pin_used = NULL;
- struct pkcs11_callback_data *data = userdata;
- CK_OBJECT_HANDLE object;
- int r;
-
- assert(m);
- assert(slot_info);
- assert(token_info);
- assert(uri);
- assert(data);
-
- /* Called for every token matching our URI */
-
- r = pkcs11_token_login(m, session, slot_id, token_info, "home directory operation", "user-home", "pkcs11-pin", UINT64_MAX, &pin_used);
- if (r < 0)
- return r;
-
- r = pkcs11_token_find_x509_certificate(m, session, uri, &object);
- if (r < 0)
- return r;
-
- r = pkcs11_token_read_x509_certificate(m, session, object, &data->cert);
- if (r < 0)
- return r;
-
- /* Let's read some random data off the token and write it to the kernel pool before we generate our
- * random key from it. This way we can claim the quality of the RNG is at least as good as the
- * kernel's and the token's pool */
- (void) pkcs11_token_acquire_rng(m, session);
-
- data->pin_used = TAKE_PTR(pin_used);
- return 1;
-}
-#endif
-
-static int acquire_pkcs11_certificate(
- const char *uri,
- X509 **ret_cert,
- char **ret_pin_used) {
-
-#if HAVE_P11KIT
- _cleanup_(pkcs11_callback_data_release) struct pkcs11_callback_data data = {};
- int r;
-
- r = pkcs11_find_token(uri, pkcs11_callback, &data);
- if (r == -EAGAIN) /* pkcs11_find_token() doesn't log about this error, but all others */
- return log_error_errno(ENXIO, "Specified PKCS#11 token with URI '%s' not found.", uri);
- if (r < 0)
- return r;
-
- *ret_cert = TAKE_PTR(data.cert);
- *ret_pin_used = TAKE_PTR(data.pin_used);
-
- return 0;
-#else
- return log_error_errno(EOPNOTSUPP, "PKCS#11 tokens not supported on this build.");
-#endif
-}
-
-static int encrypt_bytes(
- EVP_PKEY *pkey,
- const void *decrypted_key,
- size_t decrypted_key_size,
- void **ret_encrypt_key,
- size_t *ret_encrypt_key_size) {
-
- _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = NULL;
- _cleanup_free_ void *b = NULL;
- size_t l;
-
- ctx = EVP_PKEY_CTX_new(pkey, NULL);
- if (!ctx)
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to allocate public key context");
-
- if (EVP_PKEY_encrypt_init(ctx) <= 0)
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to initialize public key context");
-
- if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to configure PKCS#1 padding");
-
- if (EVP_PKEY_encrypt(ctx, NULL, &l, decrypted_key, decrypted_key_size) <= 0)
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to determine encrypted key size");
-
- b = malloc(l);
- if (!b)
- return log_oom();
-
- if (EVP_PKEY_encrypt(ctx, b, &l, decrypted_key, decrypted_key_size) <= 0)
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to determine encrypted key size");
-
- *ret_encrypt_key = TAKE_PTR(b);
- *ret_encrypt_key_size = l;
-
- return 0;
-}
-
-static int add_pkcs11_pin(JsonVariant **v, const char *pin) {
- _cleanup_(json_variant_unrefp) JsonVariant *w = NULL, *l = NULL;
- _cleanup_(strv_free_erasep) char **pins = NULL;
- int r;
-
- assert(v);
-
- if (isempty(pin))
- return 0;
-
- w = json_variant_ref(json_variant_by_key(*v, "secret"));
- l = json_variant_ref(json_variant_by_key(w, "pkcs11Pin"));
-
- r = json_variant_strv(l, &pins);
- if (r < 0)
- return log_error_errno(r, "Failed to convert PIN array: %m");
-
- if (strv_find(pins, pin))
- return 0;
-
- r = strv_extend(&pins, pin);
- if (r < 0)
- return log_oom();
-
- strv_uniq(pins);
-
- l = json_variant_unref(l);
-
- r = json_variant_new_array_strv(&l, pins);
- if (r < 0)
- return log_error_errno(r, "Failed to allocate new PIN array JSON: %m");
-
- json_variant_sensitive(l);
-
- r = json_variant_set_field(&w, "pkcs11Pin", l);
- if (r < 0)
- return log_error_errno(r, "Failed to update PIN field: %m");
-
- r = json_variant_set_field(v, "secret", w);
- if (r < 0)
- return log_error_errno(r, "Failed to update secret object: %m");
-
- return 1;
-}
-
-static int add_pkcs11_encrypted_key(
- JsonVariant **v,
- const char *uri,
- const void *encrypted_key, size_t encrypted_key_size,
- const void *decrypted_key, size_t decrypted_key_size) {
-
- _cleanup_(json_variant_unrefp) JsonVariant *l = NULL, *w = NULL, *e = NULL;
- _cleanup_(erase_and_freep) char *base64_encoded = NULL;
- _cleanup_free_ char *salt = NULL;
- struct crypt_data cd = {};
- char *k;
- int r;
-
- assert(v);
- assert(uri);
- assert(encrypted_key);
- assert(encrypted_key_size > 0);
- assert(decrypted_key);
- assert(decrypted_key_size > 0);
-
- r = make_salt(&salt);
- if (r < 0)
- return log_error_errno(r, "Failed to generate salt: %m");
-
- /* Before using UNIX hashing on the supplied key we base64 encode it, since crypt_r() and friends
- * expect a NUL terminated string, and we use a binary key */
- r = base64mem(decrypted_key, decrypted_key_size, &base64_encoded);
- if (r < 0)
- return log_error_errno(r, "Failed to base64 encode secret key: %m");
-
- errno = 0;
- k = crypt_r(base64_encoded, salt, &cd);
- if (!k)
- return log_error_errno(errno_or_else(EINVAL), "Failed to UNIX hash secret key: %m");
-
- r = json_build(&e, JSON_BUILD_OBJECT(
- JSON_BUILD_PAIR("uri", JSON_BUILD_STRING(uri)),
- JSON_BUILD_PAIR("data", JSON_BUILD_BASE64(encrypted_key, encrypted_key_size)),
- JSON_BUILD_PAIR("hashedPassword", JSON_BUILD_STRING(k))));
- if (r < 0)
- return log_error_errno(r, "Failed to build encrypted JSON key object: %m");
-
- w = json_variant_ref(json_variant_by_key(*v, "privileged"));
- l = json_variant_ref(json_variant_by_key(w, "pkcs11EncryptedKey"));
-
- r = json_variant_append_array(&l, e);
- if (r < 0)
- return log_error_errno(r, "Failed append PKCS#11 encrypted key: %m");
-
- r = json_variant_set_field(&w, "pkcs11EncryptedKey", l);
- if (r < 0)
- return log_error_errno(r, "Failed to set PKCS#11 encrypted key: %m");
-
- r = json_variant_set_field(v, "privileged", w);
- if (r < 0)
- return log_error_errno(r, "Failed to update privileged field: %m");
-
- return 0;
-}
-
-static int add_pkcs11_token_uri(JsonVariant **v, const char *uri) {
- _cleanup_(json_variant_unrefp) JsonVariant *w = NULL;
- _cleanup_strv_free_ char **l = NULL;
- int r;
-
- assert(v);
- assert(uri);
-
- w = json_variant_ref(json_variant_by_key(*v, "pkcs11TokenUri"));
- if (w) {
- r = json_variant_strv(w, &l);
- if (r < 0)
- return log_error_errno(r, "Failed to parse PKCS#11 token list: %m");
-
- if (strv_contains(l, uri))
- return 0;
- }
-
- r = strv_extend(&l, uri);
- if (r < 0)
- return log_oom();
-
- w = json_variant_unref(w);
- r = json_variant_new_array_strv(&w, l);
- if (r < 0)
- return log_error_errno(r, "Failed to create PKCS#11 token URI JSON: %m");
-
- r = json_variant_set_field(v, "pkcs11TokenUri", w);
- if (r < 0)
- return log_error_errno(r, "Failed to update PKCS#11 token URI list: %m");
-
- return 0;
-}
-
-static int add_pkcs11_key_data(JsonVariant **v, const char *uri) {
- _cleanup_(erase_and_freep) void *decrypted_key = NULL, *encrypted_key = NULL;
- _cleanup_(erase_and_freep) char *pin = NULL;
- size_t decrypted_key_size, encrypted_key_size;
- _cleanup_(X509_freep) X509 *cert = NULL;
- EVP_PKEY *pkey;
- RSA *rsa;
- int bits;
- int r;
-
- assert(v);
-
- r = acquire_pkcs11_certificate(uri, &cert, &pin);
- if (r < 0)
- return r;
-
- pkey = X509_get0_pubkey(cert);
- if (!pkey)
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to extract public key from X.509 certificate.");
-
- if (EVP_PKEY_base_id(pkey) != EVP_PKEY_RSA)
- return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "X.509 certificate does not refer to RSA key.");
-
- rsa = EVP_PKEY_get0_RSA(pkey);
- if (!rsa)
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to acquire RSA public key from X.509 certificate.");
-
- bits = RSA_bits(rsa);
- log_debug("Bits in RSA key: %i", bits);
-
- /* We use PKCS#1 padding for the RSA cleartext, hence let's leave some extra space for it, hence only
- * generate a random key half the size of the RSA length */
- decrypted_key_size = bits / 8 / 2;
-
- if (decrypted_key_size < 1)
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Uh, RSA key size too short?");
-
- log_debug("Generating %zu bytes random key.", decrypted_key_size);
-
- decrypted_key = malloc(decrypted_key_size);
- if (!decrypted_key)
- return log_oom();
-
- r = genuine_random_bytes(decrypted_key, decrypted_key_size, RANDOM_BLOCK);
- if (r < 0)
- return log_error_errno(r, "Failed to generate random key: %m");
-
- r = encrypt_bytes(pkey, decrypted_key, decrypted_key_size, &encrypted_key, &encrypted_key_size);
- if (r < 0)
- return log_error_errno(r, "Failed to encrypt key: %m");
-
- /* Add the token URI to the public part of the record. */
- r = add_pkcs11_token_uri(v, uri);
- if (r < 0)
- return r;
-
- /* Include the encrypted version of the random key we just generated in the privileged part of the record */
- r = add_pkcs11_encrypted_key(
- v,
- uri,
- encrypted_key, encrypted_key_size,
- decrypted_key, decrypted_key_size);
- if (r < 0)
- return r;
-
- /* If we acquired the PIN also include it in the secret section of the record, so that systemd-homed
- * can use it if it needs to, given that it likely needs to decrypt the key again to pass to LUKS or
- * fscrypt. */
- r = add_pkcs11_pin(v, pin);
- if (r < 0)
- return r;
-
- return 0;
-}
-
static int acquire_new_home_record(UserRecord **ret) {
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
_cleanup_(user_record_unrefp) UserRecord *hr = NULL;
@@ -1246,7 +926,13 @@ static int acquire_new_home_record(UserRecord **ret) {
return r;
STRV_FOREACH(i, arg_pkcs11_token_uri) {
- r = add_pkcs11_key_data(&v, *i);
+ r = identity_add_pkcs11_key_data(&v, *i);
+ if (r < 0)
+ return r;
+ }
+
+ STRV_FOREACH(i, arg_fido2_device) {
+ r = identity_add_fido2_parameters(&v, *i);
if (r < 0)
return r;
}
@@ -1423,7 +1109,7 @@ static int create_home(int argc, char *argv[], void *userdata) {
r = json_variant_format(hr->json, 0, &formatted);
if (r < 0)
- return r;
+ return log_error_errno(r, "Failed to format user record: %m");
r = bus_message_new_method_call(bus, &m, bus_home_mgr, "CreateHome");
if (r < 0)
@@ -1437,25 +1123,28 @@ static int create_home(int argc, char *argv[], void *userdata) {
r = sd_bus_call(bus, m, HOME_SLOW_BUS_CALL_TIMEOUT_USEC, &error, NULL);
if (r < 0) {
- if (!sd_bus_error_has_name(&error, BUS_ERROR_LOW_PASSWORD_QUALITY))
- return log_error_errno(r, "Failed to create user home: %s", bus_error_message(&error, r));
-
- log_error_errno(r, "%s", bus_error_message(&error, r));
- log_info("(Use --enforce-password-policy=no to turn off password quality checks for this account.)");
- } else
- break; /* done */
+ if (sd_bus_error_has_name(&error, BUS_ERROR_LOW_PASSWORD_QUALITY)) {
+ log_error_errno(r, "%s", bus_error_message(&error, r));
+ log_info("(Use --enforce-password-policy=no to turn off password quality checks for this account.)");
- r = user_record_set_hashed_password(hr, original_hashed_passwords);
- if (r < 0)
- return r;
+ r = user_record_set_hashed_password(hr, original_hashed_passwords);
+ if (r < 0)
+ return r;
- r = acquire_new_password(hr->user_name, hr, /* suggest = */ false);
- if (r < 0)
- return r;
+ r = acquire_new_password(hr->user_name, hr, /* suggest = */ false);
+ if (r < 0)
+ return r;
- r = user_record_make_hashed_password(hr, hr->password, /* extend = */ true);
- if (r < 0)
- return log_error_errno(r, "Failed to hash passwords: %m");
+ r = user_record_make_hashed_password(hr, hr->password, /* extend = */ true);
+ if (r < 0)
+ return log_error_errno(r, "Failed to hash passwords: %m");
+ } else {
+ r = handle_generic_user_record_error(hr->user_name, hr, &error, r, false);
+ if (r < 0)
+ return r;
+ }
+ } else
+ break; /* done */
}
return 0;
@@ -1566,14 +1255,20 @@ static int acquire_updated_home_record(
return r;
STRV_FOREACH(i, arg_pkcs11_token_uri) {
- r = add_pkcs11_key_data(&json, *i);
+ r = identity_add_pkcs11_key_data(&json, *i);
+ if (r < 0)
+ return r;
+ }
+
+ STRV_FOREACH(i, arg_fido2_device) {
+ r = identity_add_fido2_parameters(&json, *i);
if (r < 0)
return r;
}
/* If the user supplied a full record, then add in lastChange, but do not override. Otherwise always
* override. */
- r = update_last_change(&json, !!arg_pkcs11_token_uri, !arg_identity);
+ r = update_last_change(&json, arg_pkcs11_token_uri || arg_fido2_device, !arg_identity);
if (r < 0)
return r;
@@ -1592,6 +1287,26 @@ static int acquire_updated_home_record(
return 0;
}
+static int home_record_reset_human_interaction_permission(UserRecord *hr) {
+ int r;
+
+ assert(hr);
+
+ /* When we execute multiple operations one after the other, let's reset the permission to ask the
+ * user each time, so that if interaction is necessary we will be told so again and thus can print a
+ * nice message to the user, telling the user so. */
+
+ r = user_record_set_pkcs11_protected_authentication_path_permitted(hr, -1);
+ if (r < 0)
+ return log_error_errno(r, "Failed to reset PKCS#11 protected authentication path permission flag: %m");
+
+ r = user_record_set_fido2_user_presence_permitted(hr, -1);
+ if (r < 0)
+ return log_error_errno(r, "Failed to reset FIDO2 user presence permission flag: %m");
+
+ return 0;
+}
+
static int update_home(int argc, char *argv[], void *userdata) {
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
_cleanup_(user_record_unrefp) UserRecord *hr = NULL;
@@ -1620,6 +1335,12 @@ static int update_home(int argc, char *argv[], void *userdata) {
if (r < 0)
return r;
+ /* If we do multiple operations, let's output things more verbosely, since otherwise the repeated
+ * authentication might be confusing. */
+
+ if (arg_and_resize || arg_and_change_password)
+ log_info("Updating home directory.");
+
for (;;) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
@@ -1631,7 +1352,7 @@ static int update_home(int argc, char *argv[], void *userdata) {
r = json_variant_format(hr->json, 0, &formatted);
if (r < 0)
- return r;
+ return log_error_errno(r, "Failed to format user record: %m");
(void) sd_bus_message_sensitive(m);
@@ -1655,13 +1376,16 @@ static int update_home(int argc, char *argv[], void *userdata) {
break;
}
+ if (arg_and_resize)
+ log_info("Resizing home.");
+
+ (void) home_record_reset_human_interaction_permission(hr);
+
/* Also sync down disk size to underlying LUKS/fscrypt/quota */
while (arg_and_resize) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
- log_debug("Resizing");
-
r = bus_message_new_method_call(bus, &m, bus_home_mgr, "ResizeHome");
if (r < 0)
return bus_log_create_error(r);
@@ -1688,13 +1412,16 @@ static int update_home(int argc, char *argv[], void *userdata) {
break;
}
+ if (arg_and_change_password)
+ log_info("Synchronizing passwords and encryption keys.");
+
+ (void) home_record_reset_human_interaction_permission(hr);
+
/* Also sync down passwords to underlying LUKS/fscrypt */
while (arg_and_change_password) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
- log_debug("Propagating password");
-
r = bus_message_new_method_call(bus, &m, bus_home_mgr, "ChangePasswordHome");
if (r < 0)
return bus_log_create_error(r);
@@ -1732,6 +1459,8 @@ static int passwd_home(int argc, char *argv[], void *userdata) {
if (arg_pkcs11_token_uri)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "To change the PKCS#11 security token use 'homectl update --pkcs11-token-uri=…'.");
+ if (arg_fido2_device)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "To change the FIDO2 security token use 'homectl update --fido2-device=…'.");
if (identity_properties_specified())
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "The 'passwd' verb does not permit changing other record properties at the same time.");
@@ -2182,6 +1911,8 @@ static int help(int argc, char *argv[], void *userdata) {
" Specify SSH public keys\n"
" --pkcs11-token-uri=URI URI to PKCS#11 security token containing\n"
" private key and matching X.509 certificate\n"
+ " --fido2-device=PATH Path to FIDO2 hidraw device with hmac-secret\n"
+ " extension\n"
"\n%4$sAccount Management User Record Properties:%5$s\n"
" --locked=BOOL Set locked account state\n"
" --not-before=TIMESTAMP Do not allow logins before\n"
@@ -2328,6 +2059,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_EXPORT_FORMAT,
ARG_AUTO_LOGIN,
ARG_PKCS11_TOKEN_URI,
+ ARG_FIDO2_DEVICE,
ARG_AND_RESIZE,
ARG_AND_CHANGE_PASSWORD,
};
@@ -2405,6 +2137,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "json", required_argument, NULL, ARG_JSON },
{ "export-format", required_argument, NULL, ARG_EXPORT_FORMAT },
{ "pkcs11-token-uri", required_argument, NULL, ARG_PKCS11_TOKEN_URI },
+ { "fido2-device", required_argument, NULL, ARG_FIDO2_DEVICE },
{ "and-resize", required_argument, NULL, ARG_AND_RESIZE },
{ "and-change-password", required_argument, NULL, ARG_AND_CHANGE_PASSWORD },
{}
@@ -3365,6 +3098,9 @@ static int parse_argv(int argc, char *argv[]) {
case ARG_PKCS11_TOKEN_URI: {
const char *p;
+ if (streq(optarg, "list"))
+ return list_pkcs11_tokens();
+
/* If --pkcs11-token-uri= is specified we always drop everything old */
FOREACH_STRING(p, "pkcs11TokenUri", "pkcs11EncryptedKey") {
r = drop_from_identity(p);
@@ -3377,10 +3113,19 @@ static int parse_argv(int argc, char *argv[]) {
break;
}
- if (!pkcs11_uri_valid(optarg))
- return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Not a valid PKCS#11 URI: %s", optarg);
+ if (streq(optarg, "auto")) {
+ _cleanup_free_ char *found = NULL;
+
+ r = find_pkcs11_token_auto(&found);
+ if (r < 0)
+ return r;
+ r = strv_consume(&arg_pkcs11_token_uri, TAKE_PTR(found));
+ } else {
+ if (!pkcs11_uri_valid(optarg))
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Not a valid PKCS#11 URI: %s", optarg);
- r = strv_extend(&arg_pkcs11_token_uri, optarg);
+ r = strv_extend(&arg_pkcs11_token_uri, optarg);
+ }
if (r < 0)
return r;
@@ -3388,6 +3133,41 @@ static int parse_argv(int argc, char *argv[]) {
break;
}
+ case ARG_FIDO2_DEVICE: {
+ const char *p;
+
+ if (streq(optarg, "list"))
+ return list_fido2_devices();
+
+ FOREACH_STRING(p, "fido2HmacCredential", "fido2HmacSalt") {
+ r = drop_from_identity(p);
+ if (r < 0)
+ return r;
+ }
+
+ if (isempty(optarg)) {
+ arg_fido2_device = strv_free(arg_fido2_device);
+ break;
+ }
+
+ if (streq(optarg, "auto")) {
+ _cleanup_free_ char *found = NULL;
+
+ r = find_fido2_auto(&found);
+ if (r < 0)
+ return r;
+
+ r = strv_consume(&arg_fido2_device, TAKE_PTR(found));
+ } else
+ r = strv_extend(&arg_fido2_device, optarg);
+
+ if (r < 0)
+ return r;
+
+ strv_uniq(arg_fido2_device);
+ break;
+ }
+
case 'j':
arg_json = true;
arg_json_format_flags = JSON_FORMAT_PRETTY_AUTO|JSON_FORMAT_COLOR_AUTO;
@@ -3458,7 +3238,7 @@ static int parse_argv(int argc, char *argv[]) {
}
}
- if (!strv_isempty(arg_pkcs11_token_uri))
+ if (!strv_isempty(arg_pkcs11_token_uri) || !strv_isempty(arg_fido2_device))
arg_and_change_password = true;
if (arg_disk_size != UINT64_MAX || arg_disk_size_relative != UINT64_MAX)
diff --git a/src/home/homed-home.c b/src/home/homed-home.c
index 47ee7d2328..f0c157cb7d 100644
--- a/src/home/homed-home.c
+++ b/src/home/homed-home.c
@@ -457,6 +457,10 @@ static int convert_worker_errno(Home *h, int e, sd_bus_error *error) {
return sd_bus_error_setf(error, BUS_ERROR_TOKEN_PIN_NEEDED, "PIN for security token required.");
case -ERFKILL:
return sd_bus_error_setf(error, BUS_ERROR_TOKEN_PROTECTED_AUTHENTICATION_PATH_NEEDED, "Security token requires protected authentication path.");
+ case -EMEDIUMTYPE:
+ return sd_bus_error_setf(error, BUS_ERROR_TOKEN_USER_PRESENCE_NEEDED, "Security token requires user presence.");
+ case -ENOSTR:
+ return sd_bus_error_setf(error, BUS_ERROR_TOKEN_ACTION_TIMEOUT, "Token action timeout. (User was supposed to verify presence or similar, by interacting with the token, and didn't do that in time.)");
case -EOWNERDEAD:
return sd_bus_error_setf(error, BUS_ERROR_TOKEN_PIN_LOCKED, "PIN of security token locked.");
case -ENOLCK:
@@ -1357,7 +1361,13 @@ static int user_record_extend_with_binding(UserRecord *hr, UserRecord *with_bind
return 0;
}
-static int home_update_internal(Home *h, const char *verb, UserRecord *hr, UserRecord *secret, sd_bus_error *error) {
+static int home_update_internal(
+ Home *h,
+ const char *verb,
+ UserRecord *hr,
+ UserRecord *secret,
+ sd_bus_error *error) {
+
_cleanup_(user_record_unrefp) UserRecord *new_hr = NULL, *saved_secret = NULL, *signed_hr = NULL;
int r, c;
diff --git a/src/home/homed.c b/src/home/homed.c
index 2fd3b65d89..ed8404d7e3 100644
--- a/src/home/homed.c
+++ b/src/home/homed.c
@@ -13,8 +13,8 @@
#include "signal-util.h"
static int run(int argc, char *argv[]) {
- _cleanup_(notify_on_cleanup) const char *notify_stop = NULL;
_cleanup_(manager_freep) Manager *m = NULL;
+ _cleanup_(notify_on_cleanup) const char *notify_stop = NULL;
int r;
log_setup_service();
diff --git a/src/home/homework-cifs.c b/src/home/homework-cifs.c
index 27c92e16e7..cfceaed742 100644
--- a/src/home/homework-cifs.c
+++ b/src/home/homework-cifs.c
@@ -98,7 +98,7 @@ int home_prepare_cifs(
int home_activate_cifs(
UserRecord *h,
- char ***pkcs11_decrypted_passwords,
+ PasswordCache *cache,
UserRecord **ret_home) {
_cleanup_(home_setup_undo) HomeSetup setup = HOME_SETUP_INIT;
@@ -120,7 +120,7 @@ int home_activate_cifs(
if (r < 0)
return r;
- r = home_refresh(h, &setup, NULL, pkcs11_decrypted_passwords, NULL, &new_home);
+ r = home_refresh(h, &setup, NULL, cache, NULL, &new_home);
if (r < 0)
return r;
diff --git a/src/home/homework-cifs.h b/src/home/homework-cifs.h
index 346be8826e..ee799e2a4b 100644
--- a/src/home/homework-cifs.h
+++ b/src/home/homework-cifs.h
@@ -6,6 +6,6 @@
int home_prepare_cifs(UserRecord *h, bool already_activated, HomeSetup *setup);
-int home_activate_cifs(UserRecord *h, char ***pkcs11_decrypted_passwords, UserRecord **ret_home);
+int home_activate_cifs(UserRecord *h, PasswordCache *cache, UserRecord **ret_home);
int home_create_cifs(UserRecord *h, UserRecord **ret_home);
diff --git a/src/home/homework-directory.c b/src/home/homework-directory.c
index 8a4cb1732a..7d00da214a 100644
--- a/src/home/homework-directory.c
+++ b/src/home/homework-directory.c
@@ -26,7 +26,7 @@ int home_prepare_directory(UserRecord *h, bool already_activated, HomeSetup *set
int home_activate_directory(
UserRecord *h,
- char ***pkcs11_decrypted_passwords,
+ PasswordCache *cache,
UserRecord **ret_home) {
_cleanup_(user_record_unrefp) UserRecord *new_home = NULL, *header_home = NULL;
@@ -44,11 +44,11 @@ int home_activate_directory(
assert_se(hdo = user_record_home_directory(h));
hd = strdupa(hdo);
- r = home_prepare(h, false, pkcs11_decrypted_passwords, &setup, &header_home);
+ r = home_prepare(h, false, cache, &setup, &header_home);
if (r < 0)
return r;
- r = home_refresh(h, &setup, header_home, pkcs11_decrypted_passwords, NULL, &new_home);
+ r = home_refresh(h, &setup, header_home, cache, NULL, &new_home);
if (r < 0)
return r;
@@ -193,7 +193,7 @@ int home_create_directory_or_subvolume(UserRecord *h, UserRecord **ret_home) {
int home_resize_directory(
UserRecord *h,
bool already_activated,
- char ***pkcs11_decrypted_passwords,
+ PasswordCache *cache,
HomeSetup *setup,
UserRecord **ret_home) {
@@ -205,11 +205,11 @@ int home_resize_directory(
assert(ret_home);
assert(IN_SET(user_record_storage(h), USER_DIRECTORY, USER_SUBVOLUME, USER_FSCRYPT));
- r = home_prepare(h, already_activated, pkcs11_decrypted_passwords, setup, NULL);
+ r = home_prepare(h, already_activated, cache, setup, NULL);
if (r < 0)
return r;
- r = home_load_embedded_identity(h, setup->root_fd, NULL, USER_RECONCILE_REQUIRE_NEWER_OR_EQUAL, pkcs11_decrypted_passwords, &embedded_home, &new_home);
+ r = home_load_embedded_identity(h, setup->root_fd, NULL, USER_RECONCILE_REQUIRE_NEWER_OR_EQUAL, cache, &embedded_home, &new_home);
if (r < 0)
return r;
diff --git a/src/home/homework-directory.h b/src/home/homework-directory.h
index 047c3a70a0..717837f348 100644
--- a/src/home/homework-directory.h
+++ b/src/home/homework-directory.h
@@ -5,6 +5,6 @@
#include "user-record.h"
int home_prepare_directory(UserRecord *h, bool already_activated, HomeSetup *setup);
-int home_activate_directory(UserRecord *h, char ***pkcs11_decrypted_passwords, UserRecord **ret_home);
+int home_activate_directory(UserRecord *h, PasswordCache *cache, UserRecord **ret_home);
int home_create_directory_or_subvolume(UserRecord *h, UserRecord **ret_home);
-int home_resize_directory(UserRecord *h, bool already_activated, char ***pkcs11_decrypted_passwords, HomeSetup *setup, UserRecord **ret_home);
+int home_resize_directory(UserRecord *h, bool already_activated, PasswordCache *cache, HomeSetup *setup, UserRecord **ret_home);
diff --git a/src/home/homework-fido2.c b/src/home/homework-fido2.c
new file mode 100644
index 0000000000..36fe059ab3
--- /dev/null
+++ b/src/home/homework-fido2.c
@@ -0,0 +1,197 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include <fido.h>
+
+#include "hexdecoct.h"
+#include "homework-fido2.h"
+#include "strv.h"
+
+static int fido2_use_specific_token(
+ const char *path,
+ UserRecord *h,
+ UserRecord *secret,
+ const Fido2HmacSalt *salt,
+ char **ret) {
+
+ _cleanup_(fido_cbor_info_free) fido_cbor_info_t *di = NULL;
+ _cleanup_(fido_assert_free) fido_assert_t *a = NULL;
+ _cleanup_(fido_dev_free) fido_dev_t *d = NULL;
+ bool found_extension = false;
+ size_t n, hmac_size;
+ const void *hmac;
+ char **e;
+ int r;
+
+ d = fido_dev_new();
+ if (!d)
+ return log_oom();
+
+ r = fido_dev_open(d, path);
+ if (r != FIDO_OK)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to open FIDO2 device %s: %s", path, fido_strerr(r));
+
+ if (!fido_dev_is_fido2(d))
+ return log_error_errno(SYNTHETIC_ERRNO(ENODEV),
+ "Specified device %s is not a FIDO2 device.", path);
+
+ di = fido_cbor_info_new();
+ if (!di)
+ return log_oom();
+
+ r = fido_dev_get_cbor_info(d, di);
+ if (r != FIDO_OK)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to get CBOR device info for %s: %s", path, fido_strerr(r));
+
+ e = fido_cbor_info_extensions_ptr(di);
+ n = fido_cbor_info_extensions_len(di);
+
+ for (size_t i = 0; i < n; i++)
+ if (streq(e[i], "hmac-secret")) {
+ found_extension = true;
+ break;
+ }
+
+ if (!found_extension)
+ return log_error_errno(SYNTHETIC_ERRNO(ENODEV),
+ "Specified device %s is a FIDO2 device, but does not support the required HMAC-SECRET extension.", path);
+
+ a = fido_assert_new();
+ if (!a)
+ return log_oom();
+
+ r = fido_assert_set_extensions(a, FIDO_EXT_HMAC_SECRET);
+ if (r != FIDO_OK)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to enable HMAC-SECRET extension on FIDO2 assertion: %s", fido_strerr(r));
+
+ r = fido_assert_set_hmac_salt(a, salt->salt, salt->salt_size);
+ if (r != FIDO_OK)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to set salt on FIDO2 assertion: %s", fido_strerr(r));
+
+ r = fido_assert_set_rp(a, "io.systemd.home");
+ if (r != FIDO_OK)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to set FIDO2 assertion ID: %s", fido_strerr(r));
+
+ r = fido_assert_set_clientdata_hash(a, (const unsigned char[32]) {}, 32);
+ if (r != FIDO_OK)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to set FIDO2 assertion client data hash: %s", fido_strerr(r));
+
+ r = fido_assert_allow_cred(a, salt->credential.id, salt->credential.size);
+ if (r != FIDO_OK)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to add FIDO2 assertion credential ID: %s", fido_strerr(r));
+
+ r = fido_assert_set_up(a, h->fido2_user_presence_permitted <= 0 ? FIDO_OPT_FALSE : FIDO_OPT_TRUE);
+ if (r != FIDO_OK)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to set FIDO2 assertion user presence: %s", fido_strerr(r));
+
+ log_info("Asking FIDO2 token for authentication.");
+
+ r = fido_dev_get_assert(d, a, NULL); /* try without pin first */
+ if (r == FIDO_ERR_PIN_REQUIRED) {
+ char **i;
+
+ /* OK, we needed a pin, try with all pins in turn */
+ STRV_FOREACH(i, secret->token_pin) {
+ r = fido_dev_get_assert(d, a, *i);
+ if (r != FIDO_ERR_PIN_INVALID)
+ break;
+ }
+ }
+
+ switch (r) {
+ case FIDO_OK:
+ break;
+ case FIDO_ERR_NO_CREDENTIALS:
+ return log_error_errno(SYNTHETIC_ERRNO(EBADSLT),
+ "Wrong security token; needed credentials not present on token.");
+ case FIDO_ERR_PIN_REQUIRED:
+ return log_error_errno(SYNTHETIC_ERRNO(ENOANO),
+ "Security token requires PIN.");
+ case FIDO_ERR_PIN_AUTH_BLOCKED:
+ return log_error_errno(SYNTHETIC_ERRNO(EOWNERDEAD),
+ "PIN of security token is blocked, please remove/reinsert token.");
+ case FIDO_ERR_PIN_INVALID:
+ return log_error_errno(SYNTHETIC_ERRNO(ENOLCK),
+ "PIN of security token incorrect.");
+ case FIDO_ERR_UP_REQUIRED:
+ return log_error_errno(SYNTHETIC_ERRNO(EMEDIUMTYPE),
+ "User presence required.");
+ case FIDO_ERR_ACTION_TIMEOUT:
+ return log_error_errno(SYNTHETIC_ERRNO(ENOSTR),
+ "Token action timeout. (User didn't interact with token quickly enough.)");
+ default:
+ return log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to ask token for assertion: %s", fido_strerr(r));
+ }
+
+ hmac = fido_assert_hmac_secret_ptr(a, 0);
+ if (!hmac)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to retrieve HMAC secret.");
+
+ hmac_size = fido_assert_hmac_secret_len(a, 0);
+
+ r = base64mem(hmac, hmac_size, ret);
+ if (r < 0)
+ return log_error_errno(r, "Failed to base64 encode HMAC secret: %m");
+
+ return 0;
+}
+
+int fido2_use_token(UserRecord *h, UserRecord *secret, const Fido2HmacSalt *salt, char **ret) {
+ size_t allocated = 64, found = 0;
+ fido_dev_info_t *di = NULL;
+ int r;
+
+ di = fido_dev_info_new(allocated);
+ if (!di)
+ return log_oom();
+
+ r = fido_dev_info_manifest(di, allocated, &found);
+ if (r == FIDO_ERR_INTERNAL) {
+ /* The library returns FIDO_ERR_INTERNAL when no devices are found. I wish it wouldn't. */
+ r = log_debug_errno(SYNTHETIC_ERRNO(EAGAIN), "Got FIDO_ERR_INTERNAL, assuming no devices.");
+ goto finish;
+ }
+ if (r != FIDO_OK) {
+ r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to enumerate FIDO2 devices: %s", fido_strerr(r));
+ goto finish;
+ }
+
+ for (size_t i = 0; i < found; i++) {
+ const fido_dev_info_t *entry;
+ const char *path;
+
+ entry = fido_dev_info_ptr(di, i);
+ if (!entry) {
+ r = log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to get device information for FIDO device %zu.", i);
+ goto finish;
+ }
+
+ path = fido_dev_info_path(entry);
+ if (!path) {
+ r = log_error_errno(SYNTHETIC_ERRNO(EIO),
+ "Failed to query FIDO device path.");
+ goto finish;
+ }
+
+ r = fido2_use_specific_token(path, h, secret, salt, ret);
+ if (!IN_SET(r,
+ -EBADSLT, /* device doesn't understand our credential hash */
+ -ENODEV /* device is not a FIDO2 device with HMAC-SECRET */))
+ goto finish;
+ }
+
+ r = -EAGAIN;
+
+finish:
+ fido_dev_info_free(&di, allocated);
+ return r;
+}
diff --git a/src/home/homework-fido2.h b/src/home/homework-fido2.h
new file mode 100644
index 0000000000..d3b142a923
--- /dev/null
+++ b/src/home/homework-fido2.h
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#pragma once
+
+#include "user-record.h"
+
+int fido2_use_token(UserRecord *h, UserRecord *secret, const Fido2HmacSalt *salt, char **ret);
diff --git a/src/home/homework-fscrypt.c b/src/home/homework-fscrypt.c
index 696e265397..da9bb64b71 100644
--- a/src/home/homework-fscrypt.c
+++ b/src/home/homework-fscrypt.c
@@ -208,7 +208,7 @@ static int fscrypt_slot_try_many(
}
static int fscrypt_setup(
- char **pkcs11_decrypted_passwords,
+ const PasswordCache *cache,
char **password,
HomeSetup *setup,
void **ret_volume_key,
@@ -230,6 +230,7 @@ static int fscrypt_setup(
_cleanup_free_ char *value = NULL;
size_t salt_size, encrypted_size;
const char *nr, *e;
+ char **list;
int n;
/* Check if this xattr has the format 'trusted.fscrypt_slot<nr>' where '<nr>' is a 32bit unsigned integer */
@@ -256,19 +257,17 @@ static int fscrypt_setup(
if (r < 0)
return log_error_errno(r, "Failed to decode encrypted key of %s: %m", xa);
- r = fscrypt_slot_try_many(
- pkcs11_decrypted_passwords,
- salt, salt_size,
- encrypted, encrypted_size,
- setup->fscrypt_key_descriptor,
- ret_volume_key, ret_volume_key_size);
- if (r == -ENOANO)
+ r = -ENOANO;
+ FOREACH_POINTER(list, cache->pkcs11_passwords, cache->fido2_passwords, password) {
r = fscrypt_slot_try_many(
- password,
+ list,
salt, salt_size,
encrypted, encrypted_size,
setup->fscrypt_key_descriptor,
ret_volume_key, ret_volume_key_size);
+ if (r != -ENOANO)
+ break;
+ }
if (r < 0) {
if (r != -ENOANO)
return r;
@@ -282,7 +281,7 @@ static int fscrypt_setup(
int home_prepare_fscrypt(
UserRecord *h,
bool already_activated,
- char ***pkcs11_decrypted_passwords,
+ PasswordCache *cache,
HomeSetup *setup) {
_cleanup_(erase_and_freep) void *volume_key = NULL;
@@ -314,7 +313,7 @@ int home_prepare_fscrypt(
memcpy(setup->fscrypt_key_descriptor, policy.master_key_descriptor, FS_KEY_DESCRIPTOR_SIZE);
r = fscrypt_setup(
- pkcs11_decrypted_passwords ? *pkcs11_decrypted_passwords : NULL,
+ cache,
h->password,
setup,
&volume_key,
@@ -584,7 +583,7 @@ int home_create_fscrypt(
int home_passwd_fscrypt(
UserRecord *h,
HomeSetup *setup,
- char **pkcs11_decrypted_passwords, /* the passwords acquired via PKCS#11 security tokens */
+ PasswordCache *cache, /* the passwords acquired via PKCS#11/FIDO2 security tokens */
char **effective_passwords /* new passwords */) {
_cleanup_(erase_and_freep) void *volume_key = NULL;
@@ -600,7 +599,7 @@ int home_passwd_fscrypt(
assert(setup);
r = fscrypt_setup(
- pkcs11_decrypted_passwords,
+ cache,
h->password,
setup,
&volume_key,
diff --git a/src/home/homework-fscrypt.h b/src/home/homework-fscrypt.h
index aa3bcd3a69..e5cf7baaaa 100644
--- a/src/home/homework-fscrypt.h
+++ b/src/home/homework-fscrypt.h
@@ -4,7 +4,7 @@
#include "homework.h"
#include "user-record.h"
-int home_prepare_fscrypt(UserRecord *h, bool already_activated, char ***pkcs11_decrypted_passwords, HomeSetup *setup);
+int home_prepare_fscrypt(UserRecord *h, bool already_activated, PasswordCache *cache, HomeSetup *setup);
int home_create_fscrypt(UserRecord *h, char **effective_passwords, UserRecord **ret_home);
-int home_passwd_fscrypt(UserRecord *h, HomeSetup *setup, char **pkcs11_decrypted_passwords, char **effective_passwords);
+int home_passwd_fscrypt(UserRecord *h, HomeSetup *setup, PasswordCache *cache, char **effective_passwords);
diff --git a/src/home/homework-luks.c b/src/home/homework-luks.c
index 2a782e34bc..99cab0929e 100644
--- a/src/home/homework-luks.c
+++ b/src/home/homework-luks.c
@@ -216,7 +216,7 @@ static int luks_setup(
const char *cipher_mode,
uint64_t volume_key_size,
char **passwords,
- char **pkcs11_decrypted_passwords,
+ const PasswordCache *cache,
bool discard,
struct crypt_device **ret,
sd_id128_t *ret_found_uuid,
@@ -227,6 +227,7 @@ static int luks_setup(
_cleanup_(erase_and_freep) void *vk = NULL;
sd_id128_t p;
size_t vks;
+ char **list;
int r;
assert(node);
@@ -278,12 +279,14 @@ static int luks_setup(
if (!vk)
return log_oom();
- r = luks_try_passwords(cd, pkcs11_decrypted_passwords, vk, &vks);
- if (r == -ENOKEY) {
- r = luks_try_passwords(cd, passwords, vk, &vks);
- if (r == -ENOKEY)
- return log_error_errno(r, "No valid password for LUKS superblock.");
+ r = -ENOKEY;
+ FOREACH_POINTER(list, cache->pkcs11_passwords, cache->fido2_passwords, passwords) {
+ r = luks_try_passwords(cd, list, vk, &vks);
+ if (r != -ENOKEY)
+ break;
}
+ if (r == -ENOKEY)
+ return log_error_errno(r, "No valid password for LUKS superblock.");
if (r < 0)
return log_error_errno(r, "Failed to unlocks LUKS superblock: %m");
@@ -312,7 +315,7 @@ static int luks_setup(
static int luks_open(
const char *dm_name,
char **passwords,
- char **pkcs11_decrypted_passwords,
+ PasswordCache *cache,
struct crypt_device **ret,
sd_id128_t *ret_found_uuid,
void **ret_volume_key,
@@ -321,6 +324,7 @@ static int luks_open(
_cleanup_(crypt_freep) struct crypt_device *cd = NULL;
_cleanup_(erase_and_freep) void *vk = NULL;
sd_id128_t p;
+ char **list;
size_t vks;
int r;
@@ -361,12 +365,14 @@ static int luks_open(
if (!vk)
return log_oom();
- r = luks_try_passwords(cd, pkcs11_decrypted_passwords, vk, &vks);
- if (r == -ENOKEY) {
- r = luks_try_passwords(cd, passwords, vk, &vks);
- if (r == -ENOKEY)
- return log_error_errno(r, "No valid password for LUKS superblock.");
+ r = -ENOKEY;
+ FOREACH_POINTER(list, cache->pkcs11_passwords, cache->fido2_passwords, passwords) {
+ r = luks_try_passwords(cd, list, vk, &vks);
+ if (r != -ENOKEY)
+ break;
}
+ if (r == -ENOKEY)
+ return log_error_errno(r, "No valid password for LUKS superblock.");
if (r < 0)
return log_error_errno(r, "Failed to unlocks LUKS superblock: %m");
@@ -622,7 +628,7 @@ static int luks_validate_home_record(
struct crypt_device *cd,
UserRecord *h,
const void *volume_key,
- char ***pkcs11_decrypted_passwords,
+ PasswordCache *cache,
UserRecord **ret_luks_home_record) {
int r, token;
@@ -727,7 +733,7 @@ static int luks_validate_home_record(
if (!user_record_compatible(h, lhr))
return log_error_errno(SYNTHETIC_ERRNO(EREMCHG), "LUKS home record not compatible with host record, refusing.");
- r = user_record_authenticate(lhr, h, pkcs11_decrypted_passwords, /* strict_verify= */ true);
+ r = user_record_authenticate(lhr, h, cache, /* strict_verify= */ true);
if (r < 0)
return r;
assert(r > 0); /* Insist that a password was verified */
@@ -982,7 +988,7 @@ int home_prepare_luks(
UserRecord *h,
bool already_activated,
const char *force_image_path,
- char ***pkcs11_decrypted_passwords,
+ PasswordCache *cache,
HomeSetup *setup,
UserRecord **ret_luks_home) {
@@ -1010,7 +1016,7 @@ int home_prepare_luks(
r = luks_open(setup->dm_name,
h->password,
- pkcs11_decrypted_passwords ? *pkcs11_decrypted_passwords : NULL,
+ cache,
&cd,
&found_luks_uuid,
&volume_key,
@@ -1018,7 +1024,7 @@ int home_prepare_luks(
if (r < 0)
return r;
- r = luks_validate_home_record(cd, h, volume_key, pkcs11_decrypted_passwords, &luks_home);
+ r = luks_validate_home_record(cd, h, volume_key, cache, &luks_home);
if (r < 0)
return r;
@@ -1133,7 +1139,7 @@ int home_prepare_luks(
h->luks_cipher_mode,
h->luks_volume_key_size,
h->password,
- pkcs11_decrypted_passwords ? *pkcs11_decrypted_passwords : NULL,
+ cache,
user_record_luks_discard(h) || user_record_luks_offline_discard(h),
&cd,
&found_luks_uuid,
@@ -1144,7 +1150,7 @@ int home_prepare_luks(
dm_activated = true;
- r = luks_validate_home_record(cd, h, volume_key, pkcs11_decrypted_passwords, &luks_home);
+ r = luks_validate_home_record(cd, h, volume_key, cache, &luks_home);
if (r < 0)
goto fail;
@@ -1218,7 +1224,7 @@ static void print_size_summary(uint64_t host_size, uint64_t encrypted_size, stru
int home_activate_luks(
UserRecord *h,
- char ***pkcs11_decrypted_passwords,
+ PasswordCache *cache,
UserRecord **ret_home) {
_cleanup_(user_record_unrefp) UserRecord *new_home = NULL, *luks_home_record = NULL;
@@ -1250,7 +1256,7 @@ int home_activate_luks(
h,
false,
NULL,
- pkcs11_decrypted_passwords,
+ cache,
&setup,
&luks_home_record);
if (r < 0)
@@ -1268,7 +1274,7 @@ int home_activate_luks(
h,
&setup,
luks_home_record,
- pkcs11_decrypted_passwords,
+ cache,
&sfs,
&new_home);
if (r < 0)
@@ -1464,7 +1470,7 @@ static int luks_format(
const char *dm_name,
sd_id128_t uuid,
const char *label,
- char **pkcs11_decrypted_passwords,
+ const PasswordCache *cache,
char **effective_passwords,
bool discard,
UserRecord *hr,
@@ -1533,7 +1539,8 @@ static int luks_format(
STRV_FOREACH(pp, effective_passwords) {
- if (strv_contains(pkcs11_decrypted_passwords, *pp)) {
+ if (strv_contains(cache->pkcs11_passwords, *pp) ||
+ strv_contains(cache->fido2_passwords, *pp)) {
log_debug("Using minimal PBKDF for slot %i", slot);
r = crypt_set_pbkdf_type(cd, &minimal_pbkdf);
} else {
@@ -1858,7 +1865,7 @@ static int home_truncate(
int home_create_luks(
UserRecord *h,
- char **pkcs11_decrypted_passwords,
+ PasswordCache *cache,
char **effective_passwords,
UserRecord **ret_home) {
@@ -2055,7 +2062,7 @@ int home_create_luks(
dm_name,
luks_uuid,
user_record_user_name_and_realm(h),
- pkcs11_decrypted_passwords,
+ cache,
effective_passwords,
user_record_luks_discard(h) || user_record_luks_offline_discard(h),
h,
@@ -2561,7 +2568,7 @@ static int apply_resize_partition(int fd, sd_id128_t disk_uuids, struct fdisk_ta
int home_resize_luks(
UserRecord *h,
bool already_activated,
- char ***pkcs11_decrypted_passwords,
+ PasswordCache *cache,
HomeSetup *setup,
UserRecord **ret_home) {
@@ -2647,11 +2654,11 @@ int home_resize_luks(
}
}
- r = home_prepare_luks(h, already_activated, whole_disk, pkcs11_decrypted_passwords, setup, &header_home);
+ r = home_prepare_luks(h, already_activated, whole_disk, cache, setup, &header_home);
if (r < 0)
return r;
- r = home_load_embedded_identity(h, setup->root_fd, header_home, USER_RECONCILE_REQUIRE_NEWER_OR_EQUAL, pkcs11_decrypted_passwords, &embedded_home, &new_home);
+ r = home_load_embedded_identity(h, setup->root_fd, header_home, USER_RECONCILE_REQUIRE_NEWER_OR_EQUAL, cache, &embedded_home, &new_home);
if (r < 0)
return r;
@@ -2855,13 +2862,14 @@ int home_resize_luks(
int home_passwd_luks(
UserRecord *h,
HomeSetup *setup,
- char **pkcs11_decrypted_passwords, /* the passwords acquired via PKCS#11 security tokens */
- char **effective_passwords /* new passwords */) {
+ PasswordCache *cache, /* the passwords acquired via PKCS#11/FIDO2 security tokens */
+ char **effective_passwords /* new passwords */) {
size_t volume_key_size, i, max_key_slots, n_effective;
_cleanup_(erase_and_freep) void *volume_key = NULL;
struct crypt_pbkdf_type good_pbkdf, minimal_pbkdf;
const char *type;
+ char **list;
int r;
assert(h);
@@ -2886,12 +2894,14 @@ int home_passwd_luks(
if (!volume_key)
return log_oom();
- r = luks_try_passwords(setup->crypt_device, pkcs11_decrypted_passwords, volume_key, &volume_key_size);
- if (r == -ENOKEY) {
- r = luks_try_passwords(setup->crypt_device, h->password, volume_key, &volume_key_size);
- if (r == -ENOKEY)
- return log_error_errno(SYNTHETIC_ERRNO(ENOKEY), "Failed to unlock LUKS superblock with supplied passwords.");
+ r = -ENOKEY;
+ FOREACH_POINTER(list, cache->pkcs11_passwords, cache->fido2_passwords, h->password) {
+ r = luks_try_passwords(setup->crypt_device, list, volume_key, &volume_key_size);
+ if (r != -ENOKEY)
+ break;
}
+ if (r == -ENOKEY)
+ return log_error_errno(SYNTHETIC_ERRNO(ENOKEY), "Failed to unlock LUKS superblock with supplied passwords.");
if (r < 0)
return log_error_errno(r, "Failed to unlocks LUKS superblock: %m");
@@ -2911,7 +2921,8 @@ int home_passwd_luks(
continue;
}
- if (strv_find(pkcs11_decrypted_passwords, effective_passwords[i])) {
+ if (strv_contains(cache->pkcs11_passwords, effective_passwords[i]) ||
+ strv_contains(cache->fido2_passwords, effective_passwords[i])) {
log_debug("Using minimal PBKDF for slot %zu", i);
r = crypt_set_pbkdf_type(setup->crypt_device, &minimal_pbkdf);
} else {
@@ -3008,9 +3019,10 @@ static int luks_try_resume(
return -ENOKEY;
}
-int home_unlock_luks(UserRecord *h, char ***pkcs11_decrypted_passwords) {
+int home_unlock_luks(UserRecord *h, PasswordCache *cache) {
_cleanup_free_ char *dm_name = NULL, *dm_node = NULL;
_cleanup_(crypt_freep) struct crypt_device *cd = NULL;
+ char **list;
int r;
assert(h);
@@ -3026,12 +3038,14 @@ int home_unlock_luks(UserRecord *h, char ***pkcs11_decrypted_passwords) {
log_info("Discovered used LUKS device %s.", dm_node);
crypt_set_log_callback(cd, cryptsetup_log_glue, NULL);
- r = luks_try_resume(cd, dm_name, pkcs11_decrypted_passwords ? *pkcs11_decrypted_passwords : NULL);
- if (r == -ENOKEY) {
- r = luks_try_resume(cd, dm_name, h->password);
- if (r == -ENOKEY)
- return log_error_errno(r, "No valid password for LUKS superblock.");
+ r = -ENOKEY;
+ FOREACH_POINTER(list, cache->pkcs11_passwords, cache->fido2_passwords, h->password) {
+ r = luks_try_resume(cd, dm_name, list);
+ if (r != -ENOKEY)
+ break;
}
+ if (r == -ENOKEY)
+ return log_error_errno(r, "No valid password for LUKS superblock.");
if (r < 0)
return log_error_errno(r, "Failed to resume LUKS superblock: %m");
diff --git a/src/home/homework-luks.h b/src/home/homework-luks.h
index bd51f5da50..b51f1ad7a0 100644
--- a/src/home/homework-luks.h
+++ b/src/home/homework-luks.h
@@ -5,24 +5,24 @@
#include "homework.h"
#include "user-record.h"
-int home_prepare_luks(UserRecord *h, bool already_activated, const char *force_image_path, char ***pkcs11_decrypted_passwords, HomeSetup *setup, UserRecord **ret_luks_home);
+int home_prepare_luks(UserRecord *h, bool already_activated, const char *force_image_path, PasswordCache *cache, HomeSetup *setup, UserRecord **ret_luks_home);
-int home_activate_luks(UserRecord *h, char ***pkcs11_decrypted_passwords, UserRecord **ret_home);
+int home_activate_luks(UserRecord *h, PasswordCache *cache, UserRecord **ret_home);
int home_deactivate_luks(UserRecord *h);
int home_trim_luks(UserRecord *h);
int home_store_header_identity_luks(UserRecord *h, HomeSetup *setup, UserRecord *old_home);
-int home_create_luks(UserRecord *h, char **pkcs11_decrypted_passwords, char **effective_passwords, UserRecord **ret_home);
+int home_create_luks(UserRecord *h, PasswordCache *cache, char **effective_passwords, UserRecord **ret_home);
int home_validate_update_luks(UserRecord *h, HomeSetup *setup);
-int home_resize_luks(UserRecord *h, bool already_activated, char ***pkcs11_decrypted_passwords, HomeSetup *setup, UserRecord **ret_home);
+int home_resize_luks(UserRecord *h, bool already_activated, PasswordCache *cache, HomeSetup *setup, UserRecord **ret_home);
-int home_passwd_luks(UserRecord *h, HomeSetup *setup, char **pkcs11_decrypted_passwords, char **effective_passwords);
+int home_passwd_luks(UserRecord *h, HomeSetup *setup, PasswordCache *cache, char **effective_passwords);
int home_lock_luks(UserRecord *h);
-int home_unlock_luks(UserRecord *h, char ***pkcs11_decrypted_passwords);
+int home_unlock_luks(UserRecord *h, PasswordCache *cache);
static inline uint64_t luks_volume_key_size_convert(struct crypt_device *cd) {
int k;
diff --git a/src/home/homework-pkcs11.c b/src/home/homework-pkcs11.c
index 915bc0e57e..3a03fb7200 100644
--- a/src/home/homework-pkcs11.c
+++ b/src/home/homework-pkcs11.c
@@ -62,10 +62,10 @@ int pkcs11_callback(
goto decrypt;
}
- if (strv_isempty(data->secret->pkcs11_pin))
- return log_error_errno(SYNTHETIC_ERRNO(ENOANO), "Security Token requires PIN.");
+ if (strv_isempty(data->secret->token_pin))
+ return log_error_errno(SYNTHETIC_ERRNO(ENOANO), "Security token requires PIN.");
- STRV_FOREACH(i, data->secret->pkcs11_pin) {
+ STRV_FOREACH(i, data->secret->token_pin) {
rv = m->C_Login(session, CKU_USER, (CK_UTF8CHAR*) *i, strlen(*i));
if (rv == CKR_OK) {
log_info("Successfully logged into security token '%s' with PIN.", token_label);
diff --git a/src/home/homework.c b/src/home/homework.c
index 316933cf4e..83bd875d2d 100644
--- a/src/home/homework.c
+++ b/src/home/homework.c
@@ -11,6 +11,7 @@
#include "home-util.h"
#include "homework-cifs.h"
#include "homework-directory.h"
+#include "homework-fido2.h"
#include "homework-fscrypt.h"
#include "homework-luks.h"
#include "homework-mount.h"
@@ -21,7 +22,6 @@
#include "missing_magic.h"
#include "mount-util.h"
#include "path-util.h"
-#include "pkcs11-util.h"
#include "rm-rf.h"
#include "stat-util.h"
#include "strv.h"
@@ -32,14 +32,22 @@
/* Make sure a bad password always results in a 3s delay, no matter what */
#define BAD_PASSWORD_DELAY_USEC (3 * USEC_PER_SEC)
+void password_cache_free(PasswordCache *cache) {
+ if (!cache)
+ return;
+
+ cache->pkcs11_passwords = strv_free_erase(cache->pkcs11_passwords);
+ cache->fido2_passwords = strv_free_erase(cache->fido2_passwords);
+}
+
int user_record_authenticate(
UserRecord *h,
UserRecord *secret,
- char ***pkcs11_decrypted_passwords,
+ PasswordCache *cache,
bool strict_verify) {
- bool need_password = false, need_token = false, need_pin = false, need_protected_authentication_path_permitted = false,
- pin_locked = false, pin_incorrect = false, pin_incorrect_few_tries_left = false, pin_incorrect_one_try_left = false;
+ bool need_password = false, need_token = false, need_pin = false, need_protected_authentication_path_permitted = false, need_user_presence_permitted = false,
+ pin_locked = false, pin_incorrect = false, pin_incorrect_few_tries_left = false, pin_incorrect_one_try_left = false, token_action_timeout = false;
int r;
assert(h);
@@ -47,14 +55,14 @@ int user_record_authenticate(
/* Tries to authenticate a user record with the supplied secrets. i.e. checks whether at least one
* supplied plaintext passwords matches a hashed password field of the user record. Or if a
- * configured PKCS#11 token is around and can unlock the record.
+ * configured PKCS#11 or FIDO2 token is around and can unlock the record.
*
- * Note that the pkcs11_decrypted_passwords parameter is both an input and and output parameter: it
- * is a list of configured, decrypted PKCS#11 passwords. We typically have to call this function
- * multiple times over the course of an operation (think: on login we authenticate the host user
- * record, the record embedded in the LUKS record and the one embedded in $HOME). Hence we keep a
- * list of passwords we already decrypted, so that we don't have to do the (slow an potentially
- * interactive) PKCS#11 dance for the relevant token again and again. */
+ * Note that the 'cache' parameter is both an input and output parameter: it contains lists of
+ * configured, decrypted PKCS#11/FIDO2 passwords. We typically have to call this function multiple
+ * times over the course of an operation (think: on login we authenticate the host user record, the
+ * record embedded in the LUKS record and the one embedded in $HOME). Hence we keep a list of
+ * passwords we already decrypted, so that we don't have to do the (slow and potentially interactive)
+ * PKCS#11/FIDO2 dance for the relevant token again and again. */
/* First, let's see if the supplied plain-text passwords work? */
r = user_record_test_secret(h, secret);
@@ -70,19 +78,12 @@ int user_record_authenticate(
return 1;
}
- /* Second, let's see if any of the PKCS#11 security tokens are plugged in and help us */
+ /* Second, test cached PKCS#11 passwords */
for (size_t n = 0; n < h->n_pkcs11_encrypted_key; n++) {
-#if HAVE_P11KIT
- _cleanup_(pkcs11_callback_data_release) struct pkcs11_callback_data data = {
- .user_record = h,
- .secret = secret,
- .encrypted_key = h->pkcs11_encrypted_key + n,
- };
char **pp;
- /* See if any of the previously calculated passwords work */
- STRV_FOREACH(pp, *pkcs11_decrypted_passwords) {
- r = test_password_one(data.encrypted_key->hashed_password, *pp);
+ STRV_FOREACH(pp, cache->pkcs11_passwords) {
+ r = test_password_one(h->pkcs11_encrypted_key[n].hashed_password, *pp);
if (r < 0)
return log_error_errno(r, "Failed to check supplied PKCS#11 password: %m");
if (r > 0) {
@@ -90,6 +91,32 @@ int user_record_authenticate(
return 1;
}
}
+ }
+
+ /* Third, test cached FIDO2 passwords */
+ for (size_t n = 0; n < h->n_fido2_hmac_salt; n++) {
+ char **pp;
+
+ /* See if any of the previously calculated passwords work */
+ STRV_FOREACH(pp, cache->fido2_passwords) {
+ r = test_password_one(h->fido2_hmac_salt[n].hashed_password, *pp);
+ if (r < 0)
+ return log_error_errno(r, "Failed to check supplied FIDO2 password: %m");
+ if (r > 0) {
+ log_info("Previously acquired FIDO2 password unlocks user record.");
+ return 0;
+ }
+ }
+ }
+
+ /* Fourth, let's see if any of the PKCS#11 security tokens are plugged in and help us */
+ for (size_t n = 0; n < h->n_pkcs11_encrypted_key; n++) {
+#if HAVE_P11KIT
+ _cleanup_(pkcs11_callback_data_release) struct pkcs11_callback_data data = {
+ .user_record = h,
+ .secret = secret,
+ .encrypted_key = h->pkcs11_encrypted_key + n,
+ };
r = pkcs11_find_token(data.encrypted_key->uri, pkcs11_callback, &data);
switch (r) {
@@ -126,7 +153,56 @@ int user_record_authenticate(
log_info("Decrypted password from PKCS#11 security token %s unlocks user record.", data.encrypted_key->uri);
- r = strv_extend(pkcs11_decrypted_passwords, data.decrypted_password);
+ r = strv_extend(&cache->pkcs11_passwords, data.decrypted_password);
+ if (r < 0)
+ return log_oom();
+
+ return 0;
+ }
+#else
+ need_token = true;
+ break;
+#endif
+ }
+
+ /* Fifth, let's see if any of the FIDO2 security tokens are plugged in and help us */
+ for (size_t n = 0; n < h->n_fido2_hmac_salt; n++) {
+#if HAVE_LIBFIDO2
+ _cleanup_(erase_and_freep) char *decrypted_password = NULL;
+
+ r = fido2_use_token(h, secret, h->fido2_hmac_salt + n, &decrypted_password);
+ switch (r) {
+ case -EAGAIN:
+ need_token = true;
+ break;
+ case -ENOANO:
+ need_pin = true;
+ break;
+ case -EOWNERDEAD:
+ pin_locked = true;
+ break;
+ case -ENOLCK:
+ pin_incorrect = true;
+ break;
+ case -EMEDIUMTYPE:
+ need_user_presence_permitted = true;
+ break;
+ case -ENOSTR:
+ token_action_timeout = true;
+ break;
+ default:
+ if (r < 0)
+ return r;
+
+ r = test_password_one(h->fido2_hmac_salt[n].hashed_password, decrypted_password);
+ if (r < 0)
+ return log_error_errno(r, "Failed to test FIDO2 password: %m");
+ if (r == 0)
+ return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Configured FIDO2 security token does not decrypt encrypted key correctly.");
+
+ log_info("Decrypted password from FIDO2 security token unlocks user record.");
+
+ r = strv_extend(&cache->fido2_passwords, decrypted_password);
if (r < 0)
return log_oom();
@@ -147,8 +223,12 @@ int user_record_authenticate(
return -ENOLCK;
if (pin_locked)
return -EOWNERDEAD;
+ if (token_action_timeout)
+ return -ENOSTR;
if (need_protected_authentication_path_permitted)
return -ERFKILL;
+ if (need_user_presence_permitted)
+ return -EMEDIUMTYPE;
if (need_pin)
return -ENOANO;
if (need_token)
@@ -156,10 +236,11 @@ int user_record_authenticate(
if (need_password)
return -ENOKEY;
- /* Hmm, this means neither PCKS#11 nor classic hashed passwords were supplied, we cannot authenticate this reasonably */
+ /* Hmm, this means neither PCKS#11/FIDO2 nor classic hashed passwords were supplied, we cannot
+ * authenticate this reasonably */
if (strict_verify)
return log_debug_errno(SYNTHETIC_ERRNO(EKEYREVOKED),
- "No hashed passwords and no PKCS#11 tokens defined, cannot authenticate user record, refusing.");
+ "No hashed passwords and no PKCS#11/FIDO2 tokens defined, cannot authenticate user record, refusing.");
/* If strict verification is off this means we are possibly in the case where we encountered an
* unfixated record, i.e. a synthetic one that accordingly lacks any authentication data. In this
@@ -230,7 +311,7 @@ int home_setup_undo(HomeSetup *setup) {
int home_prepare(
UserRecord *h,
bool already_activated,
- char ***pkcs11_decrypted_passwords,
+ PasswordCache *cache,
HomeSetup *setup,
UserRecord **ret_header_home) {
@@ -249,7 +330,7 @@ int home_prepare(
switch (user_record_storage(h)) {
case USER_LUKS:
- return home_prepare_luks(h, already_activated, NULL, pkcs11_decrypted_passwords, setup, ret_header_home);
+ return home_prepare_luks(h, already_activated, NULL, cache, setup, ret_header_home);
case USER_SUBVOLUME:
case USER_DIRECTORY:
@@ -257,7 +338,7 @@ int home_prepare(
break;
case USER_FSCRYPT:
- r = home_prepare_fscrypt(h, already_activated, pkcs11_decrypted_passwords, setup);
+ r = home_prepare_fscrypt(h, already_activated, cache, setup);
break;
case USER_CIFS:
@@ -387,7 +468,7 @@ int home_load_embedded_identity(
int root_fd,
UserRecord *header_home,
UserReconcileMode mode,
- char ***pkcs11_decrypted_passwords,
+ PasswordCache *cache,
UserRecord **ret_embedded_home,
UserRecord **ret_new_home) {
@@ -414,7 +495,7 @@ int home_load_embedded_identity(
return log_error_errno(SYNTHETIC_ERRNO(EREMCHG), "Embedded home record not compatible with host record, refusing.");
/* Insist that credentials the user supplies also unlocks any embedded records. */
- r = user_record_authenticate(embedded_home, h, pkcs11_decrypted_passwords, /* strict_verify= */ true);
+ r = user_record_authenticate(embedded_home, h, cache, /* strict_verify= */ true);
if (r < 0)
return r;
assert(r > 0); /* Insist that a password was verified */
@@ -576,7 +657,7 @@ int home_refresh(
UserRecord *h,
HomeSetup *setup,
UserRecord *header_home,
- char ***pkcs11_decrypted_passwords,
+ PasswordCache *cache,
struct statfs *ret_statfs,
UserRecord **ret_new_home) {
@@ -590,7 +671,7 @@ int home_refresh(
/* When activating a home directory, does the identity work: loads the identity from the $HOME
* directory, reconciles it with our idea, chown()s everything. */
- r = home_load_embedded_identity(h, setup->root_fd, header_home, USER_RECONCILE_ANY, pkcs11_decrypted_passwords, &embedded_home, &new_home);
+ r = home_load_embedded_identity(h, setup->root_fd, header_home, USER_RECONCILE_ANY, cache, &embedded_home, &new_home);
if (r < 0)
return r;
@@ -615,7 +696,7 @@ int home_refresh(
}
static int home_activate(UserRecord *h, UserRecord **ret_home) {
- _cleanup_(strv_free_erasep) char **pkcs11_decrypted_passwords = NULL;
+ _cleanup_(password_cache_free) PasswordCache cache = {};
_cleanup_(user_record_unrefp) UserRecord *new_home = NULL;
int r;
@@ -628,7 +709,7 @@ static int home_activate(UserRecord *h, UserRecord **ret_home) {
if (!IN_SET(user_record_storage(h), USER_LUKS, USER_DIRECTORY, USER_SUBVOLUME, USER_FSCRYPT, USER_CIFS))
return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Activating home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));
- r = user_record_authenticate(h, h, &pkcs11_decrypted_passwords, /* strict_verify= */ false);
+ r = user_record_authenticate(h, h, &cache, /* strict_verify= */ false);
if (r < 0)
return r;
@@ -647,7 +728,7 @@ static int home_activate(UserRecord *h, UserRecord **ret_home) {
switch (user_record_storage(h)) {
case USER_LUKS:
- r = home_activate_luks(h, &pkcs11_decrypted_passwords, &new_home);
+ r = home_activate_luks(h, &cache, &new_home);
if (r < 0)
return r;
@@ -656,14 +737,14 @@ static int home_activate(UserRecord *h, UserRecord **ret_home) {
case USER_SUBVOLUME:
case USER_DIRECTORY:
case USER_FSCRYPT:
- r = home_activate_directory(h, &pkcs11_decrypted_passwords, &new_home);
+ r = home_activate_directory(h, &cache, &new_home);
if (r < 0)
return r;
break;
case USER_CIFS:
- r = home_activate_cifs(h, &pkcs11_decrypted_passwords, &new_home);
+ r = home_activate_cifs(h, &cache, &new_home);
if (r < 0)
return r;
@@ -783,15 +864,16 @@ int home_populate(UserRecord *h, int dir_fd) {
static int user_record_compile_effective_passwords(
UserRecord *h,
- char ***ret_effective_passwords,
- char ***ret_pkcs11_decrypted_passwords) {
+ PasswordCache *cache,
+ char ***ret_effective_passwords) {
- _cleanup_(strv_free_erasep) char **effective = NULL, **pkcs11_passwords = NULL;
+ _cleanup_(strv_free_erasep) char **effective = NULL;
size_t n;
char **i;
int r;
assert(h);
+ assert(cache);
/* We insist on at least one classic hashed password to be defined in addition to any PKCS#11 one, as
* a safe fallback, but also to simplify the password changing algorithm: there we require providing
@@ -858,11 +940,37 @@ static int user_record_compile_effective_passwords(
return log_oom();
}
- if (ret_pkcs11_decrypted_passwords) {
- r = strv_extend(&pkcs11_passwords, data.decrypted_password);
+ r = strv_extend(&cache->pkcs11_passwords, data.decrypted_password);
+ if (r < 0)
+ return log_oom();
+#else
+ return -EBADSLT;
+#endif
+ }
+
+ for (n = 0; n < h->n_fido2_hmac_salt; n++) {
+#if HAVE_LIBFIDO2
+ _cleanup_(erase_and_freep) char *decrypted_password = NULL;
+
+ r = fido2_use_token(h, h, h->fido2_hmac_salt + n, &decrypted_password);
+ if (r < 0)
+ return r;
+
+ r = test_password_one(h->fido2_hmac_salt[n].hashed_password, decrypted_password);
+ if (r < 0)
+ return log_error_errno(r, "Failed to test FIDO2 password: %m");
+ if (r == 0)
+ return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Decrypted password from token is not correct, refusing.");
+
+ if (ret_effective_passwords) {
+ r = strv_extend(&effective, decrypted_password);
if (r < 0)
return log_oom();
}
+
+ r = strv_extend(&cache->fido2_passwords, decrypted_password);
+ if (r < 0)
+ return log_oom();
#else
return -EBADSLT;
#endif
@@ -870,8 +978,6 @@ static int user_record_compile_effective_passwords(
if (ret_effective_passwords)
*ret_effective_passwords = TAKE_PTR(effective);
- if (ret_pkcs11_decrypted_passwords)
- *ret_pkcs11_decrypted_passwords = TAKE_PTR(pkcs11_passwords);
return 0;
}
@@ -934,8 +1040,9 @@ static int determine_default_storage(UserStorage *ret) {
}
static int home_create(UserRecord *h, UserRecord **ret_home) {
- _cleanup_(strv_free_erasep) char **effective_passwords = NULL, **pkcs11_decrypted_passwords = NULL;
+ _cleanup_(strv_free_erasep) char **effective_passwords = NULL;
_cleanup_(user_record_unrefp) UserRecord *new_home = NULL;
+ _cleanup_(password_cache_free) PasswordCache cache = {};
UserStorage new_storage = _USER_STORAGE_INVALID;
const char *new_fs = NULL;
int r;
@@ -947,7 +1054,7 @@ static int home_create(UserRecord *h, UserRecord **ret_home) {
if (!uid_is_valid(h->uid))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record lacks UID, refusing.");
- r = user_record_compile_effective_passwords(h, &effective_passwords, &pkcs11_decrypted_passwords);
+ r = user_record_compile_effective_passwords(h, &cache, &effective_passwords);
if (r < 0)
return r;
@@ -996,7 +1103,7 @@ static int home_create(UserRecord *h, UserRecord **ret_home) {
switch (user_record_storage(h)) {
case USER_LUKS:
- r = home_create_luks(h, pkcs11_decrypted_passwords, effective_passwords, &new_home);
+ r = home_create_luks(h, &cache, effective_passwords, &new_home);
break;
case USER_DIRECTORY:
@@ -1182,15 +1289,15 @@ static int home_validate_update(UserRecord *h, HomeSetup *setup) {
static int home_update(UserRecord *h, UserRecord **ret) {
_cleanup_(user_record_unrefp) UserRecord *new_home = NULL, *header_home = NULL, *embedded_home = NULL;
- _cleanup_(strv_free_erasep) char **pkcs11_decrypted_passwords = NULL;
_cleanup_(home_setup_undo) HomeSetup setup = HOME_SETUP_INIT;
+ _cleanup_(password_cache_free) PasswordCache cache = {};
bool already_activated = false;
int r;
assert(h);
assert(ret);
- r = user_record_authenticate(h, h, &pkcs11_decrypted_passwords, /* strict_verify= */ true);
+ r = user_record_authenticate(h, h, &cache, /* strict_verify= */ true);
if (r < 0)
return r;
assert(r > 0); /* Insist that a password was verified */
@@ -1201,11 +1308,11 @@ static int home_update(UserRecord *h, UserRecord **ret) {
already_activated = r > 0;
- r = home_prepare(h, already_activated, &pkcs11_decrypted_passwords, &setup, &header_home);
+ r = home_prepare(h, already_activated, &cache, &setup, &header_home);
if (r < 0)
return r;
- r = home_load_embedded_identity(h, setup.root_fd, header_home, USER_RECONCILE_REQUIRE_NEWER, &pkcs11_decrypted_passwords, &embedded_home, &new_home);
+ r = home_load_embedded_identity(h, setup.root_fd, header_home, USER_RECONCILE_REQUIRE_NEWER, &cache, &embedded_home, &new_home);
if (r < 0)
return r;
@@ -1237,7 +1344,7 @@ static int home_update(UserRecord *h, UserRecord **ret) {
static int home_resize(UserRecord *h, UserRecord **ret) {
_cleanup_(home_setup_undo) HomeSetup setup = HOME_SETUP_INIT;
- _cleanup_(strv_free_erasep) char **pkcs11_decrypted_passwords = NULL;
+ _cleanup_(password_cache_free) PasswordCache cache = {};
bool already_activated = false;
int r;
@@ -1247,7 +1354,7 @@ static int home_resize(UserRecord *h, UserRecord **ret) {
if (h->disk_size == UINT64_MAX)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No target size specified, refusing.");
- r = user_record_authenticate(h, h, &pkcs11_decrypted_passwords, /* strict_verify= */ true);
+ r = user_record_authenticate(h, h, &cache, /* strict_verify= */ true);
if (r < 0)
return r;
assert(r > 0); /* Insist that a password was verified */
@@ -1261,12 +1368,12 @@ static int home_resize(UserRecord *h, UserRecord **ret) {
switch (user_record_storage(h)) {
case USER_LUKS:
- return home_resize_luks(h, already_activated, &pkcs11_decrypted_passwords, &setup, ret);
+ return home_resize_luks(h, already_activated, &cache, &setup, ret);
case USER_DIRECTORY:
case USER_SUBVOLUME:
case USER_FSCRYPT:
- return home_resize_directory(h, already_activated, &pkcs11_decrypted_passwords, &setup, ret);
+ return home_resize_directory(h, already_activated, &cache, &setup, ret);
default:
return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Resizing home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));
@@ -1275,8 +1382,9 @@ static int home_resize(UserRecord *h, UserRecord **ret) {
static int home_passwd(UserRecord *h, UserRecord **ret_home) {
_cleanup_(user_record_unrefp) UserRecord *header_home = NULL, *embedded_home = NULL, *new_home = NULL;
- _cleanup_(strv_free_erasep) char **effective_passwords = NULL, **pkcs11_decrypted_passwords = NULL;
+ _cleanup_(strv_free_erasep) char **effective_passwords = NULL;
_cleanup_(home_setup_undo) HomeSetup setup = HOME_SETUP_INIT;
+ _cleanup_(password_cache_free) PasswordCache cache = {};
bool already_activated = false;
int r;
@@ -1286,7 +1394,7 @@ static int home_passwd(UserRecord *h, UserRecord **ret_home) {
if (!IN_SET(user_record_storage(h), USER_LUKS, USER_DIRECTORY, USER_SUBVOLUME, USER_FSCRYPT))
return log_error_errno(SYNTHETIC_ERRNO(ENOTTY), "Changing password of home directories of type '%s' currently not supported.", user_storage_to_string(user_record_storage(h)));
- r = user_record_compile_effective_passwords(h, &effective_passwords, &pkcs11_decrypted_passwords);
+ r = user_record_compile_effective_passwords(h, &cache, &effective_passwords);
if (r < 0)
return r;
@@ -1296,24 +1404,24 @@ static int home_passwd(UserRecord *h, UserRecord **ret_home) {
already_activated = r > 0;
- r = home_prepare(h, already_activated, &pkcs11_decrypted_passwords, &setup, &header_home);
+ r = home_prepare(h, already_activated, &cache, &setup, &header_home);
if (r < 0)
return r;
- r = home_load_embedded_identity(h, setup.root_fd, header_home, USER_RECONCILE_REQUIRE_NEWER_OR_EQUAL, &pkcs11_decrypted_passwords, &embedded_home, &new_home);
+ r = home_load_embedded_identity(h, setup.root_fd, header_home, USER_RECONCILE_REQUIRE_NEWER_OR_EQUAL, &cache, &embedded_home, &new_home);
if (r < 0)
return r;
switch (user_record_storage(h)) {
case USER_LUKS:
- r = home_passwd_luks(h, &setup, pkcs11_decrypted_passwords, effective_passwords);
+ r = home_passwd_luks(h, &setup, &cache, effective_passwords);
if (r < 0)
return r;
break;
case USER_FSCRYPT:
- r = home_passwd_fscrypt(h, &setup, pkcs11_decrypted_passwords, effective_passwords);
+ r = home_passwd_fscrypt(h, &setup, &cache, effective_passwords);
if (r < 0)
return r;
break;
@@ -1351,14 +1459,14 @@ static int home_passwd(UserRecord *h, UserRecord **ret_home) {
static int home_inspect(UserRecord *h, UserRecord **ret_home) {
_cleanup_(user_record_unrefp) UserRecord *header_home = NULL, *new_home = NULL;
_cleanup_(home_setup_undo) HomeSetup setup = HOME_SETUP_INIT;
- _cleanup_(strv_free_erasep) char **pkcs11_decrypted_passwords = NULL;
+ _cleanup_(password_cache_free) PasswordCache cache = {};
bool already_activated = false;
int r;
assert(h);
assert(ret_home);
- r = user_record_authenticate(h, h, &pkcs11_decrypted_passwords, /* strict_verify= */ false);
+ r = user_record_authenticate(h, h, &cache, /* strict_verify= */ false);
if (r < 0)
return r;
@@ -1368,11 +1476,11 @@ static int home_inspect(UserRecord *h, UserRecord **ret_home) {
already_activated = r > 0;
- r = home_prepare(h, already_activated, &pkcs11_decrypted_passwords, &setup, &header_home);
+ r = home_prepare(h, already_activated, &cache, &setup, &header_home);
if (r < 0)
return r;
- r = home_load_embedded_identity(h, setup.root_fd, header_home, USER_RECONCILE_ANY, &pkcs11_decrypted_passwords, NULL, &new_home);
+ r = home_load_embedded_identity(h, setup.root_fd, header_home, USER_RECONCILE_ANY, &cache, NULL, &new_home);
if (r < 0)
return r;
@@ -1415,7 +1523,7 @@ static int home_lock(UserRecord *h) {
}
static int home_unlock(UserRecord *h) {
- _cleanup_(strv_free_erasep) char **pkcs11_decrypted_passwords = NULL;
+ _cleanup_(password_cache_free) PasswordCache cache = {};
int r;
assert(h);
@@ -1428,11 +1536,11 @@ static int home_unlock(UserRecord *h) {
/* Note that we don't check if $HOME is actually mounted, since we want to avoid disk accesses on
* that mount until we have resumed the device. */
- r = user_record_authenticate(h, h, &pkcs11_decrypted_passwords, /* strict_verify= */ false);
+ r = user_record_authenticate(h, h, &cache, /* strict_verify= */ false);
if (r < 0)
return r;
- r = home_unlock_luks(h, &pkcs11_decrypted_passwords);
+ r = home_unlock_luks(h, &cache);
if (r < 0)
return r;
@@ -1495,10 +1603,12 @@ static int run(int argc, char *argv[]) {
* ESOCKTNOSUPPORT → operation not support on this file system
* ENOKEY → password incorrect (or not sufficient, or not supplied)
* EBADSLT → similar, but PKCS#11 device is defined and might be able to provide password, if it was plugged in which it is not
- * ENOANO → suitable PKCS#11 device found, but PIN is missing to unlock it
+ * ENOANO → suitable PKCS#11/FIDO2 device found, but PIN is missing to unlock it
* ERFKILL → suitable PKCS#11 device found, but OK to ask for on-device interactive authentication not given
- * EOWNERDEAD → suitable PKCS#11 device found, but its PIN is locked
- * ENOLCK → suitable PKCS#11 device found, but PIN incorrect
+ * EMEDIUMTYPE → suitable FIDO2 device found, but OK to ask for user presence not given
+ * ENOSTR → suitable FIDO2 device found, but user didn't react to action request on token quickly enough
+ * EOWNERDEAD → suitable PKCS#11/FIDO2 device found, but its PIN is locked
+ * ENOLCK → suitable PKCS#11/FIDO2 device found, but PIN incorrect
* ETOOMANYREFS → suitable PKCS#11 device found, but PIN incorrect, and only few tries left
* EUCLEAN → suitable PKCS#11 device found, but PIN incorrect, and only one try left
* EBUSY → file system is currently active
diff --git a/src/home/homework.h b/src/home/homework.h
index 46641172a4..ce8f2a461f 100644
--- a/src/home/homework.h
+++ b/src/home/homework.h
@@ -36,6 +36,14 @@ typedef struct HomeSetup {
uint64_t partition_size;
} HomeSetup;
+typedef struct PasswordCache {
+ /* Decoding passwords from security tokens is expensive and typically requires user interaction, hence cache any we already figured out. */
+ char **pkcs11_passwords;
+ char **fido2_passwords;
+} PasswordCache;
+
+void password_cache_free(PasswordCache *cache);
+
#define HOME_SETUP_INIT \
{ \
.root_fd = -1, \
@@ -46,16 +54,16 @@ typedef struct HomeSetup {
int home_setup_undo(HomeSetup *setup);
-int home_prepare(UserRecord *h, bool already_activated, char ***pkcs11_decrypted_passwords, HomeSetup *setup, UserRecord **ret_header_home);
+int home_prepare(UserRecord *h, bool already_activated, PasswordCache *cache, HomeSetup *setup, UserRecord **ret_header_home);
-int home_refresh(UserRecord *h, HomeSetup *setup, UserRecord *header_home, char ***pkcs11_decrypted_passwords, struct statfs *ret_statfs, UserRecord **ret_new_home);
+int home_refresh(UserRecord *h, HomeSetup *setup, UserRecord *header_home, PasswordCache *cache, struct statfs *ret_statfs, UserRecord **ret_new_home);
int home_populate(UserRecord *h, int dir_fd);
-int home_load_embedded_identity(UserRecord *h, int root_fd, UserRecord *header_home, UserReconcileMode mode, char ***pkcs11_decrypted_passwords, UserRecord **ret_embedded_home, UserRecord **ret_new_home);
+int home_load_embedded_identity(UserRecord *h, int root_fd, UserRecord *header_home, UserReconcileMode mode, PasswordCache *cache, UserRecord **ret_embedded_home, UserRecord **ret_new_home);
int home_store_embedded_identity(UserRecord *h, int root_fd, uid_t uid, UserRecord *old_home);
int home_extend_embedded_identity(UserRecord *h, UserRecord *used, HomeSetup *setup);
-int user_record_authenticate(UserRecord *h, UserRecord *secret, char ***pkcs11_decrypted_passwords, bool strict_verify);
+int user_record_authenticate(UserRecord *h, UserRecord *secret, PasswordCache *cache, bool strict_verify);
int home_sync_and_statfs(int root_fd, struct statfs *ret);
diff --git a/src/home/meson.build b/src/home/meson.build
index 2c5664aae1..797f3a3c6d 100644
--- a/src/home/meson.build
+++ b/src/home/meson.build
@@ -14,6 +14,7 @@ systemd_homework_sources = files('''
homework-mount.c
homework-mount.h
homework-pkcs11.h
+ homework-fido2.h
homework-quota.c
homework-quota.h
homework.c
@@ -25,6 +26,9 @@ systemd_homework_sources = files('''
if conf.get('HAVE_P11KIT') == 1
systemd_homework_sources += files('homework-pkcs11.c')
endif
+if conf.get('HAVE_LIBFIDO2') == 1
+ systemd_homework_sources += files('homework-fido2.c')
+endif
systemd_homed_sources = files('''
home-util.c
@@ -65,6 +69,10 @@ systemd_homed_sources += [homed_gperf_c]
homectl_sources = files('''
home-util.c
home-util.h
+ homectl-fido2.c
+ homectl-fido2.h
+ homectl-pkcs11.c
+ homectl-pkcs11.h
homectl.c
pwquality-util.c
pwquality-util.h
diff --git a/src/home/pam_systemd_home.c b/src/home/pam_systemd_home.c
index 34dfd134fc..2c2c7a0819 100644
--- a/src/home/pam_systemd_home.c
+++ b/src/home/pam_systemd_home.c
@@ -359,7 +359,7 @@ static int handle_generic_user_record_error(
return PAM_AUTHTOK_ERR;
}
- r = user_record_set_pkcs11_pin(secret, STRV_MAKE(newp), false);
+ r = user_record_set_token_pin(secret, STRV_MAKE(newp), false);
if (r < 0) {
pam_syslog(handle, LOG_ERR, "Failed to store PIN: %s", strerror_safe(r));
return PAM_SERVICE_ERR;
@@ -375,6 +375,21 @@ static int handle_generic_user_record_error(
return PAM_SERVICE_ERR;
}
+ } else if (sd_bus_error_has_name(error, BUS_ERROR_TOKEN_USER_PRESENCE_NEEDED)) {
+
+ (void) pam_prompt(handle, PAM_ERROR_MSG, NULL, "Please verify presence on security token of user %s.", user_name);
+
+ r = user_record_set_fido2_user_presence_permitted(secret, true);
+ if (r < 0) {
+ pam_syslog(handle, LOG_ERR, "Failed to set FIDO2 user presence permitted flag: %s", strerror_safe(r));
+ return PAM_SERVICE_ERR;
+ }
+
+ } else if (sd_bus_error_has_name(error, BUS_ERROR_TOKEN_PIN_LOCKED)) {
+
+ (void) pam_prompt(handle, PAM_ERROR_MSG, NULL, "Security token PIN is locked, please unlock it first. (Hint: Removal and re-insertion might suffice.)");
+ return PAM_SERVICE_ERR;
+
} else if (sd_bus_error_has_name(error, BUS_ERROR_TOKEN_BAD_PIN)) {
_cleanup_(erase_and_freep) char *newp = NULL;
@@ -388,7 +403,7 @@ static int handle_generic_user_record_error(
return PAM_AUTHTOK_ERR;
}
- r = user_record_set_pkcs11_pin(secret, STRV_MAKE(newp), false);
+ r = user_record_set_token_pin(secret, STRV_MAKE(newp), false);
if (r < 0) {
pam_syslog(handle, LOG_ERR, "Failed to store PIN: %s", strerror_safe(r));
return PAM_SERVICE_ERR;
@@ -407,7 +422,7 @@ static int handle_generic_user_record_error(
return PAM_AUTHTOK_ERR;
}
- r = user_record_set_pkcs11_pin(secret, STRV_MAKE(newp), false);
+ r = user_record_set_token_pin(secret, STRV_MAKE(newp), false);
if (r < 0) {
pam_syslog(handle, LOG_ERR, "Failed to store PIN: %s", strerror_safe(r));
return PAM_SERVICE_ERR;
@@ -426,7 +441,7 @@ static int handle_generic_user_record_error(
return PAM_AUTHTOK_ERR;
}
- r = user_record_set_pkcs11_pin(secret, STRV_MAKE(newp), false);
+ r = user_record_set_token_pin(secret, STRV_MAKE(newp), false);
if (r < 0) {
pam_syslog(handle, LOG_ERR, "Failed to store PIN: %s", strerror_safe(r));
return PAM_SERVICE_ERR;
@@ -499,7 +514,7 @@ static int acquire_home(
return r;
/* Implement our own retry loop here instead of relying on the PAM client's one. That's because it
- * might happen that the the record we stored on the host does not match the encryption password of
+ * might happen that the record we stored on the host does not match the encryption password of
* the LUKS image in case the image was used in a different system where the password was
* changed. In that case it will happen that the LUKS password and the host password are
* different, and we handle that by collecting and passing multiple passwords in that case. Hence we
diff --git a/src/home/user-record-util.c b/src/home/user-record-util.c
index 8f51f8d6e8..5d0ac86533 100644
--- a/src/home/user-record-util.c
+++ b/src/home/user-record-util.c
@@ -172,7 +172,7 @@ int user_record_reconcile(
* -REMCHG: identity records are not about the same user
* -ESTALE: embedded identity record is equally new or newer than supplied record
*
- * Return the new record to use, which is either the the embedded record updated with the host
+ * Return the new record to use, which is either the embedded record updated with the host
* binding or the host record. In both cases the secret data is stripped. */
assert(host);
@@ -887,7 +887,7 @@ int user_record_set_password(UserRecord *h, char **password, bool prepend) {
return 0;
}
-int user_record_set_pkcs11_pin(UserRecord *h, char **pin, bool prepend) {
+int user_record_set_token_pin(UserRecord *h, char **pin, bool prepend) {
_cleanup_(json_variant_unrefp) JsonVariant *w = NULL;
_cleanup_(strv_free_erasep) char **e = NULL;
int r;
@@ -899,17 +899,17 @@ int user_record_set_pkcs11_pin(UserRecord *h, char **pin, bool prepend) {
if (!e)
return -ENOMEM;
- r = strv_extend_strv(&e, h->pkcs11_pin, true);
+ r = strv_extend_strv(&e, h->token_pin, true);
if (r < 0)
return r;
strv_uniq(e);
- if (strv_equal(h->pkcs11_pin, e))
+ if (strv_equal(h->token_pin, e))
return 0;
} else {
- if (strv_equal(h->pkcs11_pin, pin))
+ if (strv_equal(h->token_pin, pin))
return 0;
e = strv_copy(pin);
@@ -922,7 +922,7 @@ int user_record_set_pkcs11_pin(UserRecord *h, char **pin, bool prepend) {
w = json_variant_ref(json_variant_by_key(h->json, "secret"));
if (strv_isempty(e))
- r = json_variant_filter(&w, STRV_MAKE("pkcs11Pin"));
+ r = json_variant_filter(&w, STRV_MAKE("tokenPin"));
else {
_cleanup_(json_variant_unrefp) JsonVariant *l = NULL;
@@ -932,7 +932,7 @@ int user_record_set_pkcs11_pin(UserRecord *h, char **pin, bool prepend) {
json_variant_sensitive(l);
- r = json_variant_set_field(&w, "pkcs11Pin", l);
+ r = json_variant_set_field(&w, "tokenPin", l);
}
if (r < 0)
return r;
@@ -943,7 +943,7 @@ int user_record_set_pkcs11_pin(UserRecord *h, char **pin, bool prepend) {
if (r < 0)
return r;
- strv_free_and_replace(h->pkcs11_pin, e);
+ strv_free_and_replace(h->token_pin, e);
SET_FLAG(h->mask, USER_RECORD_SECRET, !json_variant_is_blank_object(w));
return 0;
@@ -980,6 +980,34 @@ int user_record_set_pkcs11_protected_authentication_path_permitted(UserRecord *h
return 0;
}
+int user_record_set_fido2_user_presence_permitted(UserRecord *h, int b) {
+ _cleanup_(json_variant_unrefp) JsonVariant *w = NULL;
+ int r;
+
+ assert(h);
+
+ w = json_variant_ref(json_variant_by_key(h->json, "secret"));
+
+ if (b < 0)
+ r = json_variant_filter(&w, STRV_MAKE("fido2UserPresencePermitted"));
+ else
+ r = json_variant_set_field_boolean(&w, "fido2UserPresencePermitted", b);
+ if (r < 0)
+ return r;
+
+ if (json_variant_is_blank_object(w))
+ r = json_variant_filter(&h->json, STRV_MAKE("secret"));
+ else
+ r = json_variant_set_field(&h->json, "secret", w);
+ if (r < 0)
+ return r;
+
+ h->fido2_user_presence_permitted = b;
+
+ SET_FLAG(h->mask, USER_RECORD_SECRET, !json_variant_is_blank_object(w));
+ return 0;
+}
+
static bool per_machine_entry_empty(JsonVariant *v) {
const char *k;
_unused_ JsonVariant *e;
@@ -1062,12 +1090,22 @@ int user_record_merge_secret(UserRecord *h, UserRecord *secret) {
if (r < 0)
return r;
- r = user_record_set_pkcs11_pin(h, secret->pkcs11_pin, true);
+ r = user_record_set_token_pin(h, secret->token_pin, true);
if (r < 0)
return r;
if (secret->pkcs11_protected_authentication_path_permitted >= 0) {
- r = user_record_set_pkcs11_protected_authentication_path_permitted(h, secret->pkcs11_protected_authentication_path_permitted);
+ r = user_record_set_pkcs11_protected_authentication_path_permitted(
+ h,
+ secret->pkcs11_protected_authentication_path_permitted);
+ if (r < 0)
+ return r;
+ }
+
+ if (secret->fido2_user_presence_permitted >= 0) {
+ r = user_record_set_fido2_user_presence_permitted(
+ h,
+ secret->fido2_user_presence_permitted);
if (r < 0)
return r;
}
diff --git a/src/home/user-record-util.h b/src/home/user-record-util.h
index 6afc8df19a..2458298825 100644
--- a/src/home/user-record-util.h
+++ b/src/home/user-record-util.h
@@ -47,8 +47,9 @@ int user_record_set_disk_size(UserRecord *h, uint64_t disk_size);
int user_record_set_password(UserRecord *h, char **password, bool prepend);
int user_record_make_hashed_password(UserRecord *h, char **password, bool extend);
int user_record_set_hashed_password(UserRecord *h, char **hashed_password);
-int user_record_set_pkcs11_pin(UserRecord *h, char **pin, bool prepend);
+int user_record_set_token_pin(UserRecord *h, char **pin, bool prepend);
int user_record_set_pkcs11_protected_authentication_path_permitted(UserRecord *h, int b);
+int user_record_set_fido2_user_presence_permitted(UserRecord *h, int b);
int user_record_set_password_change_now(UserRecord *h, int b);
int user_record_merge_secret(UserRecord *h, UserRecord *secret);
int user_record_good_authentication(UserRecord *h);
diff --git a/src/initctl/initctl.c b/src/initctl/initctl.c
index 7505512fe7..7eee197665 100644
--- a/src/initctl/initctl.c
+++ b/src/initctl/initctl.c
@@ -14,12 +14,14 @@
#include "alloc-util.h"
#include "bus-error.h"
#include "bus-util.h"
+#include "daemon-util.h"
#include "def.h"
#include "fd-util.h"
#include "format-util.h"
#include "initreq.h"
#include "list.h"
#include "log.h"
+#include "main-func.h"
#include "memory-util.h"
#include "process-util.h"
#include "special.h"
@@ -68,11 +70,9 @@ static const char *translate_runlevel(int runlevel, bool *isolate) {
{ '6', SPECIAL_REBOOT_TARGET, false },
};
- unsigned i;
-
assert(isolate);
- for (i = 0; i < ELEMENTSOF(table); i++)
+ for (size_t i = 0; i < ELEMENTSOF(table); i++)
if (table[i].runlevel == runlevel) {
*isolate = table[i].isolate;
if (runlevel == '6' && kexec_loaded())
@@ -228,6 +228,7 @@ static void fifo_free(Fifo *f) {
free(f);
}
+DEFINE_TRIVIAL_CLEANUP_FUNC(Fifo*, fifo_free);
static void server_done(Server *s) {
assert(s);
@@ -241,79 +242,49 @@ static void server_done(Server *s) {
static int server_init(Server *s, unsigned n_sockets) {
int r;
- unsigned i;
+
+ /* This function will leave s partially initialized on failure. Caller needs to clean up. */
assert(s);
assert(n_sockets > 0);
- *s = (struct Server) {
- .epoll_fd = epoll_create1(EPOLL_CLOEXEC),
- };
-
- if (s->epoll_fd < 0) {
- r = log_error_errno(errno,
- "Failed to create epoll object: %m");
- goto fail;
- }
-
- for (i = 0; i < n_sockets; i++) {
- Fifo *f;
- int fd;
+ s->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
+ if (s->epoll_fd < 0)
+ return log_error_errno(errno, "Failed to create epoll object: %m");
- fd = SD_LISTEN_FDS_START+i;
+ for (unsigned i = 0; i < n_sockets; i++) {
+ _cleanup_(fifo_freep) Fifo *f = NULL;
+ int fd = SD_LISTEN_FDS_START + i;
r = sd_is_fifo(fd, NULL);
- if (r < 0) {
- log_error_errno(r, "Failed to determine file descriptor type: %m");
- goto fail;
- }
-
- if (!r) {
- log_error("Wrong file descriptor type.");
- r = -EINVAL;
- goto fail;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to determine file descriptor type: %m");
+ if (!r)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Wrong file descriptor type.");
f = new0(Fifo, 1);
- if (!f) {
- r = -ENOMEM;
- log_error_errno(errno, "Failed to create fifo object: %m");
- goto fail;
- }
-
- f->fd = -1;
+ if (!f)
+ return log_oom();
struct epoll_event ev = {
.events = EPOLLIN,
.data.ptr = f,
};
- if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
- r = -errno;
- fifo_free(f);
- log_error_errno(errno, "Failed to add fifo fd to epoll object: %m");
- goto fail;
- }
+ if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0)
+ return log_error_errno(errno, "Failed to add fifo fd to epoll object: %m");
f->fd = fd;
- LIST_PREPEND(fifo, s->fifos, f);
f->server = s;
+ LIST_PREPEND(fifo, s->fifos, TAKE_PTR(f));
s->n_fifos++;
}
r = bus_connect_system_systemd(&s->bus);
- if (r < 0) {
- log_error_errno(r, "Failed to get D-Bus connection: %m");
- r = -EIO;
- goto fail;
- }
+ if (r < 0)
+ return log_error_errno(r, "Failed to get D-Bus connection: %m");
return 0;
-
-fail:
- server_done(s);
-
- return r;
}
static int process_event(Server *s, struct epoll_event *ev) {
@@ -337,43 +308,33 @@ static int process_event(Server *s, struct epoll_event *ev) {
return 0;
}
-int main(int argc, char *argv[]) {
- Server server;
- int r = EXIT_FAILURE, n;
-
- if (getppid() != 1) {
- log_error("This program should be invoked by init only.");
- return EXIT_FAILURE;
- }
+static int run(int argc, char *argv[]) {
+ _cleanup_(server_done) Server server = { .epoll_fd = -1 };
+ _cleanup_(notify_on_cleanup) const char *notify_stop = NULL;
+ int r, n;
- if (argc > 1) {
- log_error("This program does not take arguments.");
- return EXIT_FAILURE;
- }
+ if (argc > 1)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "This program does not take arguments.");
log_setup_service();
umask(0022);
n = sd_listen_fds(true);
- if (n < 0) {
- log_error_errno(r, "Failed to read listening file descriptors from environment: %m");
- return EXIT_FAILURE;
- }
-
- if (n <= 0 || n > SERVER_FD_MAX) {
- log_error("No or too many file descriptors passed.");
- return EXIT_FAILURE;
- }
+ if (n < 0)
+ return log_error_errno(errno,
+ "Failed to read listening file descriptors from environment: %m");
- if (server_init(&server, (unsigned) n) < 0)
- return EXIT_FAILURE;
+ if (n <= 0 || n > SERVER_FD_MAX)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "No or too many file descriptors passed.");
- log_debug("systemd-initctl running as pid "PID_FMT, getpid_cached());
+ r = server_init(&server, (unsigned) n);
+ if (r < 0)
+ return r;
- sd_notify(false,
- "READY=1\n"
- "STATUS=Processing requests...");
+ notify_stop = notify_start(NOTIFY_READY, NOTIFY_STOPPING);
while (!server.quit) {
struct epoll_event event;
@@ -383,27 +344,17 @@ int main(int argc, char *argv[]) {
if (k < 0) {
if (errno == EINTR)
continue;
- log_error_errno(errno, "epoll_wait() failed: %m");
- goto fail;
+ return log_error_errno(errno, "epoll_wait() failed: %m");
}
-
- if (k <= 0)
+ if (k == 0)
break;
- if (process_event(&server, &event) < 0)
- goto fail;
+ r = process_event(&server, &event);
+ if (r < 0)
+ return r;
}
- r = EXIT_SUCCESS;
-
- log_debug("systemd-initctl stopped as pid "PID_FMT, getpid_cached());
-
-fail:
- sd_notify(false,
- "STOPPING=1\n"
- "STATUS=Shutting down...");
-
- server_done(&server);
-
- return r;
+ return 0;
}
+
+DEFINE_MAIN_FUNCTION(run);
diff --git a/src/journal-remote/journal-remote-main.c b/src/journal-remote/journal-remote-main.c
index f82d188a8c..273fdf9196 100644
--- a/src/journal-remote/journal-remote-main.c
+++ b/src/journal-remote/journal-remote-main.c
@@ -1104,8 +1104,8 @@ static int load_certificates(char **key, char **cert, char **trust) {
}
static int run(int argc, char **argv) {
- _cleanup_(notify_on_cleanup) const char *notify_message = NULL;
_cleanup_(journal_remote_server_destroy) RemoteServer s = {};
+ _cleanup_(notify_on_cleanup) const char *notify_message = NULL;
_cleanup_free_ char *key = NULL, *cert = NULL, *trust = NULL;
int r;
diff --git a/src/journal-remote/journal-upload.c b/src/journal-remote/journal-upload.c
index e169a27eb3..13ca90f957 100644
--- a/src/journal-remote/journal-upload.c
+++ b/src/journal-remote/journal-upload.c
@@ -815,8 +815,8 @@ static int open_journal(sd_journal **j) {
}
static int run(int argc, char **argv) {
- _cleanup_(notify_on_cleanup) const char *notify_message = NULL;
_cleanup_(destroy_uploader) Uploader u = {};
+ _cleanup_(notify_on_cleanup) const char *notify_message = NULL;
bool use_journal;
int r;
diff --git a/src/journal/compress.c b/src/journal/compress.c
index ec398e0cc1..e6ce64fc65 100644
--- a/src/journal/compress.c
+++ b/src/journal/compress.c
@@ -852,8 +852,6 @@ int compress_stream_zstd(int fdf, int fdt, uint64_t max_bytes) {
size_t in_allocsize, out_allocsize;
size_t z;
uint64_t left = max_bytes, in_bytes = 0;
- /* This can be used in the future to add uncompressed size to the header */
- uint64_t in_totalsize = 0;
assert(fdf >= 0);
assert(fdt >= 0);
@@ -867,11 +865,6 @@ int compress_stream_zstd(int fdf, int fdt, uint64_t max_bytes) {
if (!cctx || !out_buff || !in_buff)
return -ENOMEM;
- if (in_totalsize) {
- z = ZSTD_CCtx_setPledgedSrcSize(cctx, in_totalsize);
- if (z)
- log_debug("Failed to enable ZSTD input size, ignoring: %s", ZSTD_getErrorName(z));
- }
z = ZSTD_CCtx_setParameter(cctx, ZSTD_c_checksumFlag, 1);
if (ZSTD_isError(z))
log_debug("Failed to enable ZSTD checksum, ignoring: %s", ZSTD_getErrorName(z));
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
index 9a08de1ba4..cdcded2e24 100644
--- a/src/journal/journal-file.c
+++ b/src/journal/journal-file.c
@@ -625,7 +625,7 @@ int journal_file_fstat(JournalFile *f) {
f->last_stat_usec = now(CLOCK_MONOTONIC);
- /* Refuse dealing with with files that aren't regular */
+ /* Refuse dealing with files that aren't regular */
r = stat_verify_regular(&f->last_stat);
if (r < 0)
return r;
diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c
index 95aaf87876..6e7c806fd8 100644
--- a/src/journal/journald-kmsg.c
+++ b/src/journal/journald-kmsg.c
@@ -315,7 +315,7 @@ static int server_read_dev_kmsg(Server *s) {
if (IN_SET(errno, EAGAIN, EINTR, EPIPE))
return 0;
- return log_error_errno(errno, "Failed to read from kernel: %m");
+ return log_error_errno(errno, "Failed to read from /dev/kmsg: %m");
}
dev_kmsg_record(s, buffer, l);
diff --git a/src/libsystemd-network/dhcp6-internal.h b/src/libsystemd-network/dhcp6-internal.h
index b0d1216eed..baf7bb2ef4 100644
--- a/src/libsystemd-network/dhcp6-internal.h
+++ b/src/libsystemd-network/dhcp6-internal.h
@@ -112,7 +112,7 @@ int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
int dhcp6_option_parse_domainname(const uint8_t *optval, uint16_t optlen,
char ***str_arr);
-int dhcp6_network_bind_udp_socket(int index, struct in6_addr *address);
+int dhcp6_network_bind_udp_socket(int ifindex, struct in6_addr *address);
int dhcp6_network_send_udp_socket(int s, struct in6_addr *address,
const void *packet, size_t len);
diff --git a/src/libsystemd-network/dhcp6-network.c b/src/libsystemd-network/dhcp6-network.c
index f82afe6a09..e2efa8bbe3 100644
--- a/src/libsystemd-network/dhcp6-network.c
+++ b/src/libsystemd-network/dhcp6-network.c
@@ -17,16 +17,16 @@
#include "fd-util.h"
#include "socket-util.h"
-int dhcp6_network_bind_udp_socket(int index, struct in6_addr *local_address) {
+int dhcp6_network_bind_udp_socket(int ifindex, struct in6_addr *local_address) {
union sockaddr_union src = {
.in6.sin6_family = AF_INET6,
.in6.sin6_port = htobe16(DHCP6_PORT_CLIENT),
- .in6.sin6_scope_id = index,
+ .in6.sin6_scope_id = ifindex,
};
_cleanup_close_ int s = -1;
int r;
- assert(index > 0);
+ assert(ifindex > 0);
assert(local_address);
src.in6.sin6_addr = *local_address;
diff --git a/src/libsystemd-network/icmp6-util.c b/src/libsystemd-network/icmp6-util.c
index bdd94867ac..d9690293f1 100644
--- a/src/libsystemd-network/icmp6-util.c
+++ b/src/libsystemd-network/icmp6-util.c
@@ -81,11 +81,11 @@ static int icmp6_bind_router_message(const struct icmp6_filter *filter,
return TAKE_FD(s);
}
-int icmp6_bind_router_solicitation(int index) {
+int icmp6_bind_router_solicitation(int ifindex) {
struct icmp6_filter filter = {};
struct ipv6_mreq mreq = {
.ipv6mr_multiaddr = IN6ADDR_ALL_NODES_MULTICAST_INIT,
- .ipv6mr_interface = index,
+ .ipv6mr_interface = ifindex,
};
ICMP6_FILTER_SETBLOCKALL(&filter);
@@ -94,11 +94,11 @@ int icmp6_bind_router_solicitation(int index) {
return icmp6_bind_router_message(&filter, &mreq);
}
-int icmp6_bind_router_advertisement(int index) {
+int icmp6_bind_router_advertisement(int ifindex) {
struct icmp6_filter filter = {};
struct ipv6_mreq mreq = {
.ipv6mr_multiaddr = IN6ADDR_ALL_ROUTERS_MULTICAST_INIT,
- .ipv6mr_interface = index,
+ .ipv6mr_interface = ifindex,
};
ICMP6_FILTER_SETBLOCKALL(&filter);
diff --git a/src/libsystemd-network/icmp6-util.h b/src/libsystemd-network/icmp6-util.h
index 725a68086b..ac68ded1fe 100644
--- a/src/libsystemd-network/icmp6-util.h
+++ b/src/libsystemd-network/icmp6-util.h
@@ -17,8 +17,8 @@
{ { { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } } }
-int icmp6_bind_router_solicitation(int index);
-int icmp6_bind_router_advertisement(int index);
+int icmp6_bind_router_solicitation(int ifindex);
+int icmp6_bind_router_advertisement(int ifindex);
int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr);
int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *dst,
triple_timestamp *timestamp);
diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index d5f25d5a19..8f10b2d9bf 100644
--- a/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/libsystemd-network/sd-dhcp-client.c
@@ -376,7 +376,7 @@ int sd_dhcp_client_set_client_id(
/* For hardware types, log debug message about unexpected data length.
*
* Note that infiniband's INFINIBAND_ALEN is 20 bytes long, but only
- * last last 8 bytes of the address are stable and suitable to put into
+ * the last 8 bytes of the address are stable and suitable to put into
* the client-id. The caller is advised to account for that. */
if ((type == ARPHRD_ETHER && data_len != ETH_ALEN) ||
(type == ARPHRD_INFINIBAND && data_len != 8))
@@ -1441,7 +1441,10 @@ static int client_timeout_t1(sd_event_source *s, uint64_t usec, void *userdata)
sd_dhcp_client *client = userdata;
DHCP_CLIENT_DONT_DESTROY(client);
- client->state = DHCP_STATE_RENEWING;
+ if (client->lease)
+ client->state = DHCP_STATE_RENEWING;
+ else if (client->state != DHCP_STATE_INIT)
+ client->state = DHCP_STATE_INIT_REBOOT;
client->attempt = 0;
return client_initialize_time_events(client);
@@ -2012,6 +2015,9 @@ int sd_dhcp_client_send_renew(sd_dhcp_client *client) {
assert_return(client, -EINVAL);
assert_return(client->fd >= 0, -EINVAL);
+ if (IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_INIT_REBOOT, DHCP_STATE_STOPPED))
+ return 0;
+
client->start_delay = 0;
client->attempt = 1;
client->state = DHCP_STATE_RENEWING;
diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c
index e1572703e2..5cdb82bc6f 100644
--- a/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/libsystemd-network/sd-dhcp6-client.c
@@ -159,7 +159,7 @@ int sd_dhcp6_client_set_callback(
int sd_dhcp6_client_set_ifindex(sd_dhcp6_client *client, int ifindex) {
assert_return(client, -EINVAL);
- assert_return(ifindex >= -1, -EINVAL);
+ assert_return(ifindex > 0, -EINVAL);
assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
client->ifindex = ifindex;
@@ -1489,7 +1489,7 @@ static int client_receive_message(
break;
}
- _fallthrough_; /* for Soliciation Rapid Commit option check */
+ _fallthrough_; /* for Solicitation Rapid Commit option check */
case DHCP6_STATE_REQUEST:
case DHCP6_STATE_RENEW:
case DHCP6_STATE_REBIND:
diff --git a/src/libsystemd-network/sd-radv.c b/src/libsystemd-network/sd-radv.c
index 7ea6f0d561..cc5c0223b5 100644
--- a/src/libsystemd-network/sd-radv.c
+++ b/src/libsystemd-network/sd-radv.c
@@ -415,7 +415,7 @@ _public_ int sd_radv_start(sd_radv *ra) {
_public_ int sd_radv_set_ifindex(sd_radv *ra, int ifindex) {
assert_return(ra, -EINVAL);
- assert_return(ifindex >= -1, -EINVAL);
+ assert_return(ifindex > 0, -EINVAL);
if (ra->state != SD_RADV_STATE_IDLE)
return -EBUSY;
diff --git a/src/libsystemd-network/test-dhcp-client.c b/src/libsystemd-network/test-dhcp-client.c
index 80a8566194..8f2f4462be 100644
--- a/src/libsystemd-network/test-dhcp-client.c
+++ b/src/libsystemd-network/test-dhcp-client.c
@@ -258,7 +258,7 @@ int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link, const
}
int dhcp_network_bind_raw_socket(
- int index,
+ int ifindex,
union sockaddr_union *link,
uint32_t id,
const uint8_t *addr, size_t addr_len,
diff --git a/src/libsystemd-network/test-dhcp6-client.c b/src/libsystemd-network/test-dhcp6-client.c
index 56c8c978e5..7af7d670b5 100644
--- a/src/libsystemd-network/test-dhcp6-client.c
+++ b/src/libsystemd-network/test-dhcp6-client.c
@@ -30,7 +30,7 @@ static struct ether_addr mac_addr = {
static sd_event_source *hangcheck;
static int test_dhcp_fd[2];
-static int test_index = 42;
+static int test_ifindex = 42;
static int test_client_message_num;
static be32_t test_iaid = 0;
static uint8_t test_duid[14] = { };
@@ -48,7 +48,7 @@ static int test_client_basic(sd_event *e) {
assert_se(sd_dhcp6_client_set_ifindex(client, 15) == 0);
assert_se(sd_dhcp6_client_set_ifindex(client, -42) == -EINVAL);
- assert_se(sd_dhcp6_client_set_ifindex(client, -1) == 0);
+ assert_se(sd_dhcp6_client_set_ifindex(client, -1) == -EINVAL);
assert_se(sd_dhcp6_client_set_ifindex(client, 42) >= 0);
assert_se(sd_dhcp6_client_set_mac(client, (const uint8_t *) &mac_addr,
@@ -877,8 +877,8 @@ int dhcp6_network_send_udp_socket(int s, struct in6_addr *server_address,
return len;
}
-int dhcp6_network_bind_udp_socket(int index, struct in6_addr *local_address) {
- assert_se(index == test_index);
+int dhcp6_network_bind_udp_socket(int ifindex, struct in6_addr *local_address) {
+ assert_se(ifindex == test_ifindex);
if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, test_dhcp_fd) < 0)
return -errno;
@@ -899,7 +899,7 @@ static int test_client_solicit(sd_event *e) {
assert_se(sd_dhcp6_client_attach_event(client, e, 0) >= 0);
- assert_se(sd_dhcp6_client_set_ifindex(client, test_index) == 0);
+ assert_se(sd_dhcp6_client_set_ifindex(client, test_ifindex) == 0);
assert_se(sd_dhcp6_client_set_mac(client, (const uint8_t *) &mac_addr,
sizeof (mac_addr),
ARPHRD_ETHER) >= 0);
diff --git a/src/libsystemd-network/test-ipv4ll.c b/src/libsystemd-network/test-ipv4ll.c
index 6051e65820..310b658e18 100644
--- a/src/libsystemd-network/test-ipv4ll.c
+++ b/src/libsystemd-network/test-ipv4ll.c
@@ -78,7 +78,7 @@ int arp_send_announcement(int fd, int ifindex,
return arp_network_send_raw_socket(fd, ifindex, &ea);
}
-int arp_network_bind_raw_socket(int index, be32_t address, const struct ether_addr *eth_mac) {
+int arp_network_bind_raw_socket(int ifindex, be32_t address, const struct ether_addr *eth_mac) {
if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, test_fd) < 0)
return -errno;
diff --git a/src/libsystemd-network/test-ndisc-ra.c b/src/libsystemd-network/test-ndisc-ra.c
index 7c6c4663f3..d759ec03a8 100644
--- a/src/libsystemd-network/test-ndisc-ra.c
+++ b/src/libsystemd-network/test-ndisc-ra.c
@@ -159,8 +159,8 @@ static void test_radv(void) {
assert_se(ra);
assert_se(sd_radv_set_ifindex(NULL, 0) < 0);
- assert_se(sd_radv_set_ifindex(ra, 0) >= 0);
- assert_se(sd_radv_set_ifindex(ra, -1) >= 0);
+ assert_se(sd_radv_set_ifindex(ra, 0) < 0);
+ assert_se(sd_radv_set_ifindex(ra, -1) < 0);
assert_se(sd_radv_set_ifindex(ra, -2) < 0);
assert_se(sd_radv_set_ifindex(ra, 42) >= 0);
@@ -219,12 +219,12 @@ static void test_radv(void) {
assert_se(!ra);
}
-int icmp6_bind_router_solicitation(int index) {
+int icmp6_bind_router_solicitation(int ifindex) {
return -ENOSYS;
}
-int icmp6_bind_router_advertisement(int index) {
- assert_se(index == 42);
+int icmp6_bind_router_advertisement(int ifindex) {
+ assert_se(ifindex == 42);
return test_fd[1];
}
diff --git a/src/libsystemd-network/test-ndisc-rs.c b/src/libsystemd-network/test-ndisc-rs.c
index 9fc902645c..5d1e66fcdc 100644
--- a/src/libsystemd-network/test-ndisc-rs.c
+++ b/src/libsystemd-network/test-ndisc-rs.c
@@ -174,8 +174,8 @@ static int test_rs_hangcheck(sd_event_source *s, uint64_t usec,
return 0;
}
-int icmp6_bind_router_solicitation(int index) {
- assert_se(index == 42);
+int icmp6_bind_router_solicitation(int ifindex) {
+ assert_se(ifindex == 42);
if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, test_fd) < 0)
return -errno;
@@ -183,8 +183,7 @@ int icmp6_bind_router_solicitation(int index) {
return test_fd[0];
}
-int icmp6_bind_router_advertisement(int index) {
-
+int icmp6_bind_router_advertisement(int ifindex) {
return -ENOSYS;
}
diff --git a/src/libsystemd/sd-bus/bus-common-errors.c b/src/libsystemd/sd-bus/bus-common-errors.c
index 28f98cebce..dc9a2fdc3a 100644
--- a/src/libsystemd/sd-bus/bus-common-errors.c
+++ b/src/libsystemd/sd-bus/bus-common-errors.c
@@ -120,6 +120,8 @@ BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_common_errors[] = {
SD_BUS_ERROR_MAP(BUS_ERROR_BAD_PASSWORD_AND_NO_TOKEN, EBADSLT),
SD_BUS_ERROR_MAP(BUS_ERROR_TOKEN_PIN_NEEDED, ENOANO),
SD_BUS_ERROR_MAP(BUS_ERROR_TOKEN_PROTECTED_AUTHENTICATION_PATH_NEEDED, ERFKILL),
+ SD_BUS_ERROR_MAP(BUS_ERROR_TOKEN_USER_PRESENCE_NEEDED, EMEDIUMTYPE),
+ SD_BUS_ERROR_MAP(BUS_ERROR_TOKEN_ACTION_TIMEOUT, ENOSTR),
SD_BUS_ERROR_MAP(BUS_ERROR_TOKEN_PIN_LOCKED, EOWNERDEAD),
SD_BUS_ERROR_MAP(BUS_ERROR_TOKEN_BAD_PIN, ENOLCK),
SD_BUS_ERROR_MAP(BUS_ERROR_TOKEN_BAD_PIN_FEW_TRIES_LEFT, ETOOMANYREFS),
diff --git a/src/libsystemd/sd-bus/bus-common-errors.h b/src/libsystemd/sd-bus/bus-common-errors.h
index 68ecbd65dd..ae80543880 100644
--- a/src/libsystemd/sd-bus/bus-common-errors.h
+++ b/src/libsystemd/sd-bus/bus-common-errors.h
@@ -100,6 +100,8 @@
#define BUS_ERROR_BAD_PASSWORD_AND_NO_TOKEN "org.freedesktop.home1.BadPasswordAndNoToken"
#define BUS_ERROR_TOKEN_PIN_NEEDED "org.freedesktop.home1.TokenPinNeeded"
#define BUS_ERROR_TOKEN_PROTECTED_AUTHENTICATION_PATH_NEEDED "org.freedesktop.home1.TokenProtectedAuthenticationPathNeeded"
+#define BUS_ERROR_TOKEN_USER_PRESENCE_NEEDED "org.freedesktop.home1.TokenUserPresenceNeeded"
+#define BUS_ERROR_TOKEN_ACTION_TIMEOUT "org.freedesktop.home1.TokenActionTimeout"
#define BUS_ERROR_TOKEN_PIN_LOCKED "org.freedesktop.home1.TokenPinLocked"
#define BUS_ERROR_TOKEN_BAD_PIN "org.freedesktop.home1.BadPin"
#define BUS_ERROR_TOKEN_BAD_PIN_FEW_TRIES_LEFT "org.freedesktop.home1.BadPinFewTriesLeft"
diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h
index 7e13f4f73b..ef2c3dbc4f 100644
--- a/src/libsystemd/sd-bus/bus-internal.h
+++ b/src/libsystemd/sd-bus/bus-internal.h
@@ -43,7 +43,7 @@ struct match_callback {
unsigned last_iteration;
- /* Don't dispatch this slot with with messages that arrived in any iteration before or at the this
+ /* Don't dispatch this slot with messages that arrived in any iteration before or at the this
* one. We use this to ensure that matches don't apply "retroactively" and thus can confuse the
* caller: matches will only match incoming messages from the moment on the match was installed. */
uint64_t after;
diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c
index 24f34dc182..13596f2303 100644
--- a/src/libsystemd/sd-device/sd-device.c
+++ b/src/libsystemd/sd-device/sd-device.c
@@ -1564,34 +1564,68 @@ _public_ const char *sd_device_get_property_next(sd_device *device, const char *
return key;
}
-static int device_sysattrs_read_all(sd_device *device) {
+static int device_sysattrs_read_all_internal(sd_device *device, const char *subdir) {
+ _cleanup_free_ char *path_dir = NULL;
_cleanup_closedir_ DIR *dir = NULL;
- const char *syspath;
struct dirent *dent;
+ const char *syspath;
int r;
- assert(device);
-
- if (device->sysattrs_read)
- return 0;
-
r = sd_device_get_syspath(device, &syspath);
if (r < 0)
return r;
- dir = opendir(syspath);
+ if (subdir) {
+ _cleanup_free_ char *p = NULL;
+
+ p = path_join(syspath, subdir, "uevent");
+ if (!p)
+ return -ENOMEM;
+
+ if (access(p, F_OK) >= 0)
+ /* this is a child device, skipping */
+ return 0;
+ if (errno != ENOENT) {
+ log_debug_errno(errno, "Failed to stat %s, ignoring subdir: %m", p);
+ return 0;
+ }
+
+ path_dir = path_join(syspath, subdir);
+ if (!path_dir)
+ return -ENOMEM;
+ }
+
+ dir = opendir(path_dir ?: syspath);
if (!dir)
return -errno;
FOREACH_DIRENT_ALL(dent, dir, return -errno) {
- _cleanup_free_ char *path = NULL;
+ _cleanup_free_ char *path = NULL, *p = NULL;
struct stat statbuf;
- /* only handle symlinks and regular files */
- if (!IN_SET(dent->d_type, DT_LNK, DT_REG))
+ if (dot_or_dot_dot(dent->d_name))
+ continue;
+
+ /* only handle symlinks, regular files, and directories */
+ if (!IN_SET(dent->d_type, DT_LNK, DT_REG, DT_DIR))
+ continue;
+
+ if (subdir) {
+ p = path_join(subdir, dent->d_name);
+ if (!p)
+ return -ENOMEM;
+ }
+
+ if (dent->d_type == DT_DIR) {
+ /* read subdirectory */
+ r = device_sysattrs_read_all_internal(device, p ?: dent->d_name);
+ if (r < 0)
+ return r;
+
continue;
+ }
- path = path_join(syspath, dent->d_name);
+ path = path_join(syspath, p ?: dent->d_name);
if (!path)
return -ENOMEM;
@@ -1601,11 +1635,26 @@ static int device_sysattrs_read_all(sd_device *device) {
if (!(statbuf.st_mode & S_IRUSR))
continue;
- r = set_put_strdup(&device->sysattrs, dent->d_name);
+ r = set_put_strdup(&device->sysattrs, p ?: dent->d_name);
if (r < 0)
return r;
}
+ return 0;
+}
+
+static int device_sysattrs_read_all(sd_device *device) {
+ int r;
+
+ assert(device);
+
+ if (device->sysattrs_read)
+ return 0;
+
+ r = device_sysattrs_read_all_internal(device, NULL);
+ if (r < 0)
+ return r;
+
device->sysattrs_read = true;
return 0;
diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c
index 488bfb5f4f..a1e4ec9f27 100644
--- a/src/libsystemd/sd-netlink/netlink-types.c
+++ b/src/libsystemd/sd-netlink/netlink-types.c
@@ -537,6 +537,43 @@ static const NLTypeSystem rtnl_prop_list_type_system = {
.types = rtnl_prop_list_types,
};
+static const NLType rtnl_vf_vlan_list_types[] = {
+ [IFLA_VF_VLAN_INFO] = { .size = sizeof(struct ifla_vf_vlan_info) },
+};
+
+static const NLTypeSystem rtnl_vf_vlan_type_system = {
+ .count = ELEMENTSOF(rtnl_vf_vlan_list_types),
+ .types = rtnl_vf_vlan_list_types,
+};
+
+static const NLType rtnl_vf_vlan_info_types[] = {
+ [IFLA_VF_MAC] = { .size = sizeof(struct ifla_vf_mac) },
+ [IFLA_VF_VLAN] = { .size = sizeof(struct ifla_vf_vlan) },
+ [IFLA_VF_VLAN_LIST] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_vf_vlan_type_system},
+ [IFLA_VF_TX_RATE] = { .size = sizeof(struct ifla_vf_tx_rate) },
+ [IFLA_VF_SPOOFCHK] = { .size = sizeof(struct ifla_vf_spoofchk) },
+ [IFLA_VF_RATE] = { .size = sizeof(struct ifla_vf_rate) },
+ [IFLA_VF_LINK_STATE] = { .size = sizeof(struct ifla_vf_link_state) },
+ [IFLA_VF_RSS_QUERY_EN] = { .size = sizeof(struct ifla_vf_rss_query_en) },
+ [IFLA_VF_TRUST] = { .size = sizeof(struct ifla_vf_trust) },
+ [IFLA_VF_IB_NODE_GUID] = { .size = sizeof(struct ifla_vf_guid) },
+ [IFLA_VF_IB_PORT_GUID] = { .size = sizeof(struct ifla_vf_guid) },
+};
+
+static const NLTypeSystem rtnl_vf_vlan_info_type_system = {
+ .count = ELEMENTSOF(rtnl_vf_vlan_info_types),
+ .types = rtnl_vf_vlan_info_types,
+};
+
+static const NLType rtnl_link_io_srv_types[] = {
+ [IFLA_VF_INFO] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_vf_vlan_info_type_system },
+};
+
+static const NLTypeSystem rtnl_io_srv_type_system = {
+ .count = ELEMENTSOF(rtnl_link_io_srv_types),
+ .types = rtnl_link_io_srv_types,
+};
+
static const NLType rtnl_link_types[] = {
[IFLA_ADDRESS] = { .type = NETLINK_TYPE_ETHER_ADDR },
[IFLA_BROADCAST] = { .type = NETLINK_TYPE_ETHER_ADDR },
@@ -564,10 +601,8 @@ static const NLType rtnl_link_types[] = {
[IFLA_LINKINFO] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_info_type_system },
[IFLA_NET_NS_PID] = { .type = NETLINK_TYPE_U32 },
[IFLA_IFALIAS] = { .type = NETLINK_TYPE_STRING, .size = IFALIASZ - 1 },
-/*
- [IFLA_NUM_VF],
- [IFLA_VFINFO_LIST] = {. type = NETLINK_TYPE_NESTED, },
-*/
+ [IFLA_NUM_VF] = { .type = NETLINK_TYPE_U32 },
+ [IFLA_VFINFO_LIST] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_io_srv_type_system },
[IFLA_STATS64] = { .size = sizeof(struct rtnl_link_stats64) },
/*
[IFLA_VF_PORTS] = { .type = NETLINK_TYPE_NESTED },
diff --git a/src/login/logind-core.c b/src/login/logind-core.c
index 475759c79b..480ec1927b 100644
--- a/src/login/logind-core.c
+++ b/src/login/logind-core.c
@@ -4,9 +4,6 @@
#include <sys/ioctl.h>
#include <sys/types.h>
#include <linux/vt.h>
-#if ENABLE_UTMP
-#include <utmpx.h>
-#endif
#include "sd-device.h"
@@ -29,6 +26,7 @@
#include "udev-util.h"
#include "user-util.h"
#include "userdb.h"
+#include "utmp-wtmp.h"
void manager_reset_config(Manager *m) {
assert(m);
@@ -685,13 +683,14 @@ bool manager_all_buttons_ignored(Manager *m) {
int manager_read_utmp(Manager *m) {
#if ENABLE_UTMP
int r;
+ _cleanup_(utxent_cleanup) bool utmpx = false;
assert(m);
if (utmpxname(_PATH_UTMPX) < 0)
return log_error_errno(errno, "Failed to set utmp path to " _PATH_UTMPX ": %m");
- setutxent();
+ utmpx = utxent_start();
for (;;) {
_cleanup_free_ char *t = NULL;
@@ -704,8 +703,7 @@ int manager_read_utmp(Manager *m) {
if (!u) {
if (errno != 0)
log_warning_errno(errno, "Failed to read " _PATH_UTMPX ", ignoring: %m");
- r = 0;
- break;
+ return 0;
}
if (u->ut_type != USER_PROCESS)
@@ -715,18 +713,14 @@ int manager_read_utmp(Manager *m) {
continue;
t = strndup(u->ut_line, sizeof(u->ut_line));
- if (!t) {
- r = log_oom();
- break;
- }
+ if (!t)
+ return log_oom();
c = path_startswith(t, "/dev/");
if (c) {
r = free_and_strdup(&t, c);
- if (r < 0) {
- log_oom();
- break;
- }
+ if (r < 0)
+ return log_oom();
}
if (isempty(t))
@@ -756,8 +750,6 @@ int manager_read_utmp(Manager *m) {
log_debug("Acquired TTY information '%s' from utmp for session '%s'.", s->tty, s->id);
}
- endutxent();
- return r;
#else
return 0;
#endif
diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c
index 525b2a0393..16f4289585 100644
--- a/src/login/pam_systemd.c
+++ b/src/login/pam_systemd.c
@@ -468,7 +468,7 @@ static bool validate_runtime_directory(pam_handle_t *handle, const char *path, u
/* Some extra paranoia: let's not set $XDG_RUNTIME_DIR if the directory we'd set it to isn't actually
* set up properly for us. This is supposed to provide a careful safety net for supporting su/sudo
* type transitions: in that case the UID changes, but the session and thus the user owning it
- * doesn't change. Since the $XDG_RUNTIME_DIR life-cycle is bound to the session's user being logged
+ * doesn't change. Since the $XDG_RUNTIME_DIR lifecycle is bound to the session's user being logged
* in at least once we should be particularly careful when setting the environment variable, since
* otherwise we might end up setting $XDG_RUNTIME_DIR to some directory owned by the wrong user. */
diff --git a/src/network/meson.build b/src/network/meson.build
index 97a164091a..b3a88d9910 100644
--- a/src/network/meson.build
+++ b/src/network/meson.build
@@ -105,6 +105,8 @@ sources = files('''
networkd-routing-policy-rule.h
networkd-speed-meter.c
networkd-speed-meter.h
+ networkd-sriov.c
+ networkd-sriov.h
networkd-util.c
networkd-util.h
networkd-wifi.c
diff --git a/src/network/netdev/bond.c b/src/network/netdev/bond.c
index 23bd3e1e46..8c1ba11e5f 100644
--- a/src/network/netdev/bond.c
+++ b/src/network/netdev/bond.c
@@ -327,7 +327,7 @@ int config_parse_arp_ip_target_address(
r = extract_first_word(&rvalue, &n, NULL, 0);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
- "Failed to parse Bond ARP ip target address, ignoring assignment: %s",
+ "Failed to parse Bond ARP IP target address, ignoring assignment: %s",
rvalue);
return 0;
}
@@ -337,7 +337,7 @@ int config_parse_arp_ip_target_address(
r = in_addr_from_string(AF_INET, n, &ip);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
- "Bond ARP ip target address is invalid, ignoring assignment: %s", n);
+ "Bond ARP IP target address is invalid, ignoring assignment: %s", n);
continue;
}
@@ -347,7 +347,7 @@ int config_parse_arp_ip_target_address(
if (ordered_set_size(b->arp_ip_targets) >= NETDEV_BOND_ARP_TARGETS_MAX) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
- "Too many ARP ip targets are specified. The maximum number is %d. Ignoring assignment: %s",
+ "Too many ARP IP targets are specified. The maximum number is %d. Ignoring assignment: %s",
NETDEV_BOND_ARP_TARGETS_MAX, n);
continue;
}
@@ -355,10 +355,10 @@ int config_parse_arp_ip_target_address(
r = ordered_set_put(b->arp_ip_targets, UINT32_TO_PTR(ip.in.s_addr));
if (r == -EEXIST)
log_syntax(unit, LOG_WARNING, filename, line, r,
- "Bond ARP ip target address is duplicated, ignoring assignment: %s", n);
+ "Bond ARP IP target address is duplicated, ignoring assignment: %s", n);
if (r < 0)
log_syntax(unit, LOG_ERR, filename, line, r,
- "Failed to store bond ARP ip target address '%s', ignoring assignment: %m", n);
+ "Failed to store bond ARP IP target address '%s', ignoring assignment: %m", n);
}
}
diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c
index 20dae6c19f..37b16315e5 100644
--- a/src/network/networkd-dhcp4.c
+++ b/src/network/networkd-dhcp4.c
@@ -1025,7 +1025,7 @@ static int dhcp_lease_ip_change(sd_dhcp_client *client, Link *link) {
link->dhcp_lease_old = TAKE_PTR(link->dhcp_lease);
- /* On ip address change, to keep the connectability, we would like to assign new address and
+ /* On IP address change, to keep the connectability, we would like to assign new address and
* routes, and then release old lease. There are two possible success paths:
*
* 1. new address and routes are configured.
@@ -1066,12 +1066,40 @@ static int dhcp_server_is_deny_listed(Link *link, sd_dhcp_client *client) {
r = sd_dhcp_lease_get_server_identifier(lease, &addr);
if (r < 0)
- return log_link_debug_errno(link, r, "Failed to get DHCP server ip address: %m");
+ return log_link_debug_errno(link, r, "Failed to get DHCP server IP address: %m");
if (set_contains(link->network->dhcp_deny_listed_ip, UINT32_TO_PTR(addr.s_addr))) {
log_struct(LOG_DEBUG,
LOG_LINK_INTERFACE(link),
- LOG_LINK_MESSAGE(link, "DHCPv4 ip '%u.%u.%u.%u' found in deny-listed ip addresses, ignoring offer",
+ LOG_LINK_MESSAGE(link, "DHCPv4 IP '%u.%u.%u.%u' found in deny-listed IP addresses, ignoring offer",
+ ADDRESS_FMT_VAL(addr)));
+ return true;
+ }
+
+ return false;
+}
+
+static int dhcp_server_is_allow_listed(Link *link, sd_dhcp_client *client) {
+ sd_dhcp_lease *lease;
+ struct in_addr addr;
+ int r;
+
+ assert(link);
+ assert(link->network);
+ assert(client);
+
+ r = sd_dhcp_client_get_lease(client, &lease);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Failed to get DHCP lease: %m");
+
+ r = sd_dhcp_lease_get_server_identifier(lease, &addr);
+ if (r < 0)
+ return log_link_debug_errno(link, r, "Failed to get DHCP server IP address: %m");
+
+ if (set_contains(link->network->dhcp_allow_listed_ip, UINT32_TO_PTR(addr.s_addr))) {
+ log_struct(LOG_DEBUG,
+ LOG_LINK_INTERFACE(link),
+ LOG_LINK_MESSAGE(link, "DHCPv4 IP '%u.%u.%u.%u' found in allow-listed IP addresses, accepting offer",
ADDRESS_FMT_VAL(addr)));
return true;
}
@@ -1163,12 +1191,19 @@ static int dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) {
}
break;
case SD_DHCP_CLIENT_EVENT_SELECTING:
- r = dhcp_server_is_deny_listed(link, client);
- if (r < 0)
- return r;
- if (r != 0)
- return -ENOMSG;
-
+ if (!set_isempty(link->network->dhcp_allow_listed_ip)) {
+ r = dhcp_server_is_allow_listed(link, client);
+ if (r < 0)
+ return r;
+ if (r == 0)
+ return -ENOMSG;
+ } else {
+ r = dhcp_server_is_deny_listed(link, client);
+ if (r < 0)
+ return r;
+ if (r != 0)
+ return -ENOMSG;
+ }
break;
default:
if (event < 0)
@@ -1485,7 +1520,7 @@ int dhcp4_configure(Link *link) {
if (link->network->ip_service_type > 0) {
r = sd_dhcp_client_set_service_type(link->dhcp_client, link->network->ip_service_type);
if (r < 0)
- return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set ip service type: %m");
+ return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set IP service type: %m");
}
if (link->network->dhcp_fallback_lease_lifetime > 0) {
@@ -1551,7 +1586,7 @@ int config_parse_dhcp_max_attempts(
return 0;
}
-int config_parse_dhcp_deny_listed_ip_address(
+int config_parse_dhcp_acl_ip_address(
const char *unit,
const char *filename,
unsigned line,
@@ -1564,6 +1599,7 @@ int config_parse_dhcp_deny_listed_ip_address(
void *userdata) {
Network *network = data;
+ Set **acl;
int r;
assert(filename);
@@ -1571,8 +1607,10 @@ int config_parse_dhcp_deny_listed_ip_address(
assert(rvalue);
assert(data);
+ acl = STR_IN_SET(lvalue, "DenyList", "BlackList") ? &network->dhcp_deny_listed_ip : &network->dhcp_allow_listed_ip;
+
if (isempty(rvalue)) {
- network->dhcp_deny_listed_ip = set_free(network->dhcp_deny_listed_ip);
+ *acl = set_free(*acl);
return 0;
}
@@ -1583,8 +1621,8 @@ int config_parse_dhcp_deny_listed_ip_address(
r = extract_first_word(&p, &n, NULL, 0);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
- "Failed to parse DHCP deny-listed IP address, ignoring assignment: %s",
- rvalue);
+ "Failed to parse DHCP '%s=' IP address, ignoring assignment: %s",
+ lvalue, rvalue);
return 0;
}
if (r == 0)
@@ -1593,14 +1631,14 @@ int config_parse_dhcp_deny_listed_ip_address(
r = in_addr_from_string(AF_INET, n, &ip);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
- "DHCP deny-listed IP address is invalid, ignoring assignment: %s", n);
+ "DHCP '%s=' IP address is invalid, ignoring assignment: %s", lvalue, n);
continue;
}
- r = set_ensure_put(&network->dhcp_deny_listed_ip, NULL, UINT32_TO_PTR(ip.in.s_addr));
+ r = set_ensure_put(acl, NULL, UINT32_TO_PTR(ip.in.s_addr));
if (r < 0)
log_syntax(unit, LOG_ERR, filename, line, r,
- "Failed to store DHCP deny-listed IP address '%s', ignoring assignment: %m", n);
+ "Failed to store DHCP '%s=' IP address '%s', ignoring assignment: %m", lvalue, n);
}
return 0;
diff --git a/src/network/networkd-dhcp4.h b/src/network/networkd-dhcp4.h
index 567ee724da..96ac696ce6 100644
--- a/src/network/networkd-dhcp4.h
+++ b/src/network/networkd-dhcp4.h
@@ -23,7 +23,7 @@ int dhcp4_set_client_identifier(Link *link);
int dhcp4_set_promote_secondaries(Link *link);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_client_identifier);
-CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_deny_listed_ip_address);
+CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_acl_ip_address);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_max_attempts);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_ip_service_type);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_mud_url);
diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c
index 27b74407af..6637e81c66 100644
--- a/src/network/networkd-dhcp6.c
+++ b/src/network/networkd-dhcp6.c
@@ -6,7 +6,6 @@
#include <netinet/in.h>
#include <linux/if.h>
#include <linux/if_arp.h>
-#include "sd-radv.h"
#include "sd-dhcp6-client.h"
@@ -18,7 +17,9 @@
#include "networkd-dhcp6.h"
#include "networkd-link.h"
#include "networkd-manager.h"
+#include "networkd-radv.h"
#include "siphash24.h"
+#include "string-table.h"
#include "string-util.h"
#include "radv-internal.h"
#include "web-util.h"
@@ -27,7 +28,6 @@ static int dhcp6_lease_address_acquired(sd_dhcp6_client *client, Link *link);
static Link *dhcp6_prefix_get(Manager *m, struct in6_addr *addr);
static int dhcp6_prefix_add(Manager *m, struct in6_addr *addr, Link *link);
static int dhcp6_prefix_remove_all(Manager *m, Link *link);
-static bool dhcp6_link_has_dhcpv6_prefix(Link *link);
static int dhcp6_assign_delegated_prefix(Link *link, const struct in6_addr *prefix,
uint8_t prefix_len,
uint32_t lifetime_preferred,
@@ -77,7 +77,7 @@ static int dhcp6_get_preferred_delegated_prefix(
if (subnet_id >= 0) {
/* If the link has a preference for a particular subnet id try to allocate that */
- if ((uint64_t)subnet_id >= n_prefixes)
+ if ((uint64_t) subnet_id >= n_prefixes)
return log_link_debug_errno(link,
SYNTHETIC_ERRNO(ERANGE),
"subnet id %" PRIi64 " is out of range. Only have %" PRIu64 " subnets.",
@@ -111,28 +111,24 @@ static int dhcp6_get_preferred_delegated_prefix(
log_link_debug(link, "The requested prefix %s is available. Using it.",
strnull(assigned_buf));
return 0;
- } else {
- for (uint64_t n = 0; n < n_prefixes; n++) {
- /* if we do not have an allocation preference just iterate
- * through the address space and return the first free prefix. */
- Link* assigned_link = dhcp6_prefix_get(manager, &prefix.in6);
-
- if (!assigned_link || assigned_link == link) {
- *ret_addr = prefix.in6;
- return 0;
- }
+ }
- r = in_addr_prefix_next(AF_INET6, &prefix, 64);
- if (r < 0)
- return log_link_error_errno(link,
- r,
- "Can't allocate another prefix. Out of address space?");
+ for (uint64_t n = 0; n < n_prefixes; n++) {
+ /* if we do not have an allocation preference just iterate
+ * through the address space and return the first free prefix. */
+ Link* assigned_link = dhcp6_prefix_get(manager, &prefix.in6);
+
+ if (!assigned_link || assigned_link == link) {
+ *ret_addr = prefix.in6;
+ return 0;
}
- log_link_warning(link, "Couldn't find a suitable prefix. Ran out of address space.");
+ r = in_addr_prefix_next(AF_INET6, &prefix, 64);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Can't allocate another prefix. Out of address space?");
}
- return -ERANGE;
+ return log_link_warning_errno(link, SYNTHETIC_ERRNO(ERANGE), "Couldn't find a suitable prefix. Ran out of address space.");
}
static bool dhcp6_enable_prefix_delegation(Link *dhcp6_link) {
@@ -158,8 +154,7 @@ static bool dhcp6_enable_prefix_delegation(Link *dhcp6_link) {
return false;
}
-static int dhcp6_lease_information_acquired(sd_dhcp6_client *client,
- Link *link) {
+static int dhcp6_lease_information_acquired(sd_dhcp6_client *client, Link *link) {
return 0;
}
@@ -167,34 +162,12 @@ static int dhcp6_pd_prefix_assign(Link *link, struct in6_addr *prefix,
uint8_t prefix_len,
uint32_t lifetime_preferred,
uint32_t lifetime_valid) {
- sd_radv *radv = link->radv;
int r;
- _cleanup_(sd_radv_prefix_unrefp) sd_radv_prefix *p = NULL;
-
- r = sd_radv_prefix_new(&p);
- if (r < 0)
- return r;
-
- r = sd_radv_prefix_set_prefix(p, prefix, prefix_len);
- if (r < 0)
- return r;
-
- r = sd_radv_prefix_set_preferred_lifetime(p, lifetime_preferred);
- if (r < 0)
- return r;
-
- r = sd_radv_prefix_set_valid_lifetime(p, lifetime_valid);
- if (r < 0)
- return r;
- r = sd_radv_stop(radv);
+ r = radv_add_prefix(link, prefix, prefix_len, lifetime_preferred, lifetime_valid);
if (r < 0)
return r;
- r = sd_radv_add_prefix(radv, p, true);
- if (r < 0 && r != -EEXIST)
- return r;
-
r = dhcp6_prefix_add(link->manager, prefix, link);
if (r < 0)
return r;
@@ -205,7 +178,7 @@ static int dhcp6_pd_prefix_assign(Link *link, struct in6_addr *prefix,
return r;
}
- return sd_radv_start(radv);
+ return 0;
}
static int dhcp6_route_remove_handler(sd_netlink *nl, sd_netlink_message *m, Link *link) {
@@ -311,14 +284,11 @@ static int dhcp6_pd_prefix_distribute(Link *dhcp6_link,
if (!dhcp6_get_prefix_delegation(link))
continue;
- if (dhcp6_link_has_dhcpv6_prefix(link))
- continue;
-
if (assign_preferred_subnet_id != dhcp6_has_preferred_subnet_id(link))
continue;
r = dhcp6_get_preferred_delegated_prefix(manager, link, &prefix.in6, pd_prefix_len,
- &assigned_prefix.in6);
+ &assigned_prefix.in6);
if (assign_preferred_subnet_id && r == -EAGAIN) {
/* A link has a preferred subnet_id but that one is
@@ -1028,20 +998,6 @@ static int dhcp6_prefix_remove_all(Manager *m, Link *link) {
return 0;
}
-static bool dhcp6_link_has_dhcpv6_prefix(Link *link) {
- Iterator i;
- Link *l;
-
- assert(link);
- assert(link->manager);
-
- HASHMAP_FOREACH(l, link->manager->dhcp6_prefixes, i)
- if (link == l)
- return true;
-
- return false;
-}
-
static int dhcp6_assign_delegated_prefix(Link *link,
const struct in6_addr *prefix,
uint8_t prefix_len,
@@ -1205,3 +1161,14 @@ int config_parse_dhcp6_delegated_prefix_token(
return 0;
}
+
+DEFINE_CONFIG_PARSE_ENUM(config_parse_dhcp6_client_start_mode, dhcp6_client_start_mode, DHCP6ClientStartMode,
+ "Failed to parse WithoutRA= setting");
+
+static const char* const dhcp6_client_start_mode_table[_DHCP6_CLIENT_START_MODE_MAX] = {
+ [DHCP6_CLIENT_START_MODE_NO] = "no",
+ [DHCP6_CLIENT_START_MODE_INFORMATION_REQUEST] = "information-request",
+ [DHCP6_CLIENT_START_MODE_SOLICIT] = "solicit",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(dhcp6_client_start_mode, DHCP6ClientStartMode);
diff --git a/src/network/networkd-dhcp6.h b/src/network/networkd-dhcp6.h
index 913410fe77..858559a1e0 100644
--- a/src/network/networkd-dhcp6.h
+++ b/src/network/networkd-dhcp6.h
@@ -4,6 +4,15 @@
#include "sd-dhcp6-client.h"
#include "conf-parser.h"
+#include "macro.h"
+
+typedef enum DHCP6ClientStartMode {
+ DHCP6_CLIENT_START_MODE_NO,
+ DHCP6_CLIENT_START_MODE_INFORMATION_REQUEST,
+ DHCP6_CLIENT_START_MODE_SOLICIT,
+ _DHCP6_CLIENT_START_MODE_MAX,
+ _DHCP6_CLIENT_START_MODE_INVALID = -1,
+} DHCP6ClientStartMode;
typedef struct Link Link;
typedef struct Manager Manager;
@@ -17,3 +26,7 @@ int dhcp6_prefix_remove(Manager *m, struct in6_addr *addr);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp6_pd_hint);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp6_mud_url);
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp6_delegated_prefix_token);
+CONFIG_PARSER_PROTOTYPE(config_parse_dhcp6_client_start_mode);
+
+const char* dhcp6_client_start_mode_to_string(DHCP6ClientStartMode i) _const_;
+DHCP6ClientStartMode dhcp6_client_start_mode_from_string(const char *s) _pure_;
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index b3c0224034..053aa3b4ce 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -3,6 +3,7 @@
#include <netinet/in.h>
#include <linux/if.h>
#include <linux/if_arp.h>
+#include <linux/if_link.h>
#include <unistd.h>
#include "alloc-util.h"
@@ -31,6 +32,7 @@
#include "networkd-manager.h"
#include "networkd-ndisc.h"
#include "networkd-neighbor.h"
+#include "networkd-sriov.h"
#include "networkd-radv.h"
#include "networkd-routing-policy-rule.h"
#include "networkd-wifi.h"
@@ -1127,6 +1129,9 @@ void link_check_ready(Link *link) {
if (!link->tc_configured)
return;
+ if (!link->sr_iov_configured)
+ return;
+
if (link_has_carrier(link) || !link->network->configure_without_carrier) {
if (link_ipv4ll_enabled(link, ADDRESS_FAMILY_IPV4) && !link->ipv4ll_address)
@@ -1559,11 +1564,13 @@ static int link_acquire_ipv6_conf(Link *link) {
return log_link_warning_errno(link, r, "Could not start IPv6 Router Advertisement: %m");
}
- if (link_dhcp6_enabled(link) && link->network->dhcp6_without_ra) {
+ if (link_dhcp6_enabled(link) && IN_SET(link->network->dhcp6_without_ra,
+ DHCP6_CLIENT_START_MODE_INFORMATION_REQUEST,
+ DHCP6_CLIENT_START_MODE_SOLICIT)) {
assert(link->dhcp6_client);
assert(in_addr_is_link_local(AF_INET6, (const union in_addr_union*)&link->ipv6ll_address) > 0);
- r = dhcp6_request_address(link, true);
+ r = dhcp6_request_address(link, link->network->dhcp6_without_ra == DHCP6_CLIENT_START_MODE_INFORMATION_REQUEST);
if (r < 0 && r != -EBUSY)
return log_link_warning_errno(link, r, "Could not acquire DHCPv6 lease: %m");
else
@@ -2836,6 +2843,28 @@ static int link_configure_traffic_control(Link *link) {
return 0;
}
+static int link_configure_sr_iov(Link *link) {
+ SRIOV *sr_iov;
+ Iterator i;
+ int r;
+
+ link->sr_iov_configured = false;
+ link->sr_iov_messages = 0;
+
+ ORDERED_HASHMAP_FOREACH(sr_iov, link->network->sr_iov_by_section, i) {
+ r = sr_iov_configure(link, sr_iov);
+ if (r < 0)
+ return r;
+ }
+
+ if (link->sr_iov_messages == 0)
+ link->sr_iov_configured = true;
+ else
+ log_link_debug(link, "Configuring SR-IOV");
+
+ return 0;
+}
+
static int link_configure(Link *link) {
int r;
@@ -2847,6 +2876,10 @@ static int link_configure(Link *link) {
if (r < 0)
return r;
+ r = link_configure_sr_iov(link);
+ if (r < 0)
+ return r;
+
if (link->iftype == ARPHRD_CAN)
return link_configure_can(link);
@@ -3417,7 +3450,6 @@ static int link_load(Link *link) {
*dhcp4_address = NULL,
*ipv4ll_address = NULL;
union in_addr_union address;
- const char *p;
int r;
assert(link);
@@ -3456,107 +3488,100 @@ static int link_load(Link *link) {
network_file_fail:
- if (addresses) {
- p = addresses;
-
- for (;;) {
- _cleanup_free_ char *address_str = NULL;
- char *prefixlen_str;
- int family;
- unsigned char prefixlen;
-
- r = extract_first_word(&p, &address_str, NULL, 0);
- if (r < 0) {
- log_link_debug_errno(link, r, "Failed to extract next address string: %m");
- continue;
- }
- if (r == 0)
- break;
+ for (const char *p = addresses; p; ) {
+ _cleanup_free_ char *address_str = NULL;
+ char *prefixlen_str;
+ int family;
+ unsigned char prefixlen;
- prefixlen_str = strchr(address_str, '/');
- if (!prefixlen_str) {
- log_link_debug(link, "Failed to parse address and prefix length %s", address_str);
- continue;
- }
-
- *prefixlen_str++ = '\0';
+ r = extract_first_word(&p, &address_str, NULL, 0);
+ if (r < 0)
+ log_link_warning_errno(link, r, "failed to parse ADDRESSES: %m");
+ if (r <= 0)
+ break;
- r = sscanf(prefixlen_str, "%hhu", &prefixlen);
- if (r != 1) {
- log_link_error(link, "Failed to parse prefixlen %s", prefixlen_str);
- continue;
- }
+ prefixlen_str = strchr(address_str, '/');
+ if (!prefixlen_str) {
+ log_link_debug(link, "Failed to parse address and prefix length %s", address_str);
+ continue;
+ }
+ *prefixlen_str++ = '\0';
- r = in_addr_from_string_auto(address_str, &family, &address);
- if (r < 0) {
- log_link_debug_errno(link, r, "Failed to parse address %s: %m", address_str);
- continue;
- }
+ r = sscanf(prefixlen_str, "%hhu", &prefixlen);
+ if (r != 1) {
+ log_link_error(link, "Failed to parse prefixlen %s", prefixlen_str);
+ continue;
+ }
- r = address_add(link, family, &address, prefixlen, NULL);
- if (r < 0)
- return log_link_error_errno(link, r, "Failed to add address: %m");
+ r = in_addr_from_string_auto(address_str, &family, &address);
+ if (r < 0) {
+ log_link_debug_errno(link, r, "Failed to parse address %s: %m", address_str);
+ continue;
}
- }
- if (routes) {
- p = routes;
+ r = address_add(link, family, &address, prefixlen, NULL);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Failed to add address: %m");
+ }
- for (;;) {
- _cleanup_(sd_event_source_unrefp) sd_event_source *expire = NULL;
- _cleanup_(route_freep) Route *tmp = NULL;
- _cleanup_free_ char *route_str = NULL;
- char *prefixlen_str;
- Route *route;
+ for (const char *p = routes; p; ) {
+ _cleanup_(sd_event_source_unrefp) sd_event_source *expire = NULL;
+ _cleanup_(route_freep) Route *tmp = NULL;
+ _cleanup_free_ char *route_str = NULL;
+ char *prefixlen_str;
+ Route *route;
- r = extract_first_word(&p, &route_str, NULL, 0);
- if (r < 0) {
- log_link_debug_errno(link, r, "Failed to extract next route string: %m");
- continue;
- }
- if (r == 0)
- break;
+ r = extract_first_word(&p, &route_str, NULL, 0);
+ if (r < 0)
+ log_link_debug_errno(link, r, "failed to parse ROUTES: %m");
+ if (r <= 0)
+ break;
- prefixlen_str = strchr(route_str, '/');
- if (!prefixlen_str) {
- log_link_debug(link, "Failed to parse route %s", route_str);
- continue;
- }
+ prefixlen_str = strchr(route_str, '/');
+ if (!prefixlen_str) {
+ log_link_debug(link, "Failed to parse route %s", route_str);
+ continue;
+ }
+ *prefixlen_str++ = '\0';
- *prefixlen_str++ = '\0';
+ r = route_new(&tmp);
+ if (r < 0)
+ return log_oom();
- r = route_new(&tmp);
- if (r < 0)
- return log_oom();
+ r = sscanf(prefixlen_str,
+ "%hhu/%hhu/%"SCNu32"/%"PRIu32"/"USEC_FMT,
+ &tmp->dst_prefixlen,
+ &tmp->tos,
+ &tmp->priority,
+ &tmp->table,
+ &tmp->lifetime);
+ if (r != 5) {
+ log_link_debug(link,
+ "Failed to parse destination prefix length, tos, priority, table or expiration %s",
+ prefixlen_str);
+ continue;
+ }
- r = sscanf(prefixlen_str, "%hhu/%hhu/%"SCNu32"/%"PRIu32"/"USEC_FMT, &tmp->dst_prefixlen, &tmp->tos, &tmp->priority, &tmp->table, &tmp->lifetime);
- if (r != 5) {
- log_link_debug(link,
- "Failed to parse destination prefix length, tos, priority, table or expiration %s",
- prefixlen_str);
- continue;
- }
+ r = in_addr_from_string_auto(route_str, &tmp->family, &tmp->dst);
+ if (r < 0) {
+ log_link_debug_errno(link, r, "Failed to parse route destination %s: %m", route_str);
+ continue;
+ }
- r = in_addr_from_string_auto(route_str, &tmp->family, &tmp->dst);
- if (r < 0) {
- log_link_debug_errno(link, r, "Failed to parse route destination %s: %m", route_str);
- continue;
- }
+ r = route_add(link, tmp, &route);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Failed to add route: %m");
- r = route_add(link, tmp, &route);
+ if (route->lifetime != USEC_INFINITY && !kernel_route_expiration_supported()) {
+ r = sd_event_add_time(link->manager->event, &expire,
+ clock_boottime_or_monotonic(),
+ route->lifetime, 0, route_expire_handler, route);
if (r < 0)
- return log_link_error_errno(link, r, "Failed to add route: %m");
-
- if (route->lifetime != USEC_INFINITY && !kernel_route_expiration_supported()) {
- r = sd_event_add_time(link->manager->event, &expire, clock_boottime_or_monotonic(), route->lifetime,
- 0, route_expire_handler, route);
- if (r < 0)
- log_link_warning_errno(link, r, "Could not arm route expiration handler: %m");
- }
-
- sd_event_source_unref(route->expire);
- route->expire = TAKE_PTR(expire);
+ log_link_warning_errno(link, r, "Could not arm route expiration handler: %m");
}
+
+ sd_event_source_unref(route->expire);
+ route->expire = TAKE_PTR(expire);
}
if (dhcp4_address) {
diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h
index 5a81805a04..f53b9da2e3 100644
--- a/src/network/networkd-link.h
+++ b/src/network/networkd-link.h
@@ -82,6 +82,7 @@ typedef struct Link {
unsigned routing_policy_rule_messages;
unsigned routing_policy_rule_remove_messages;
unsigned tc_messages;
+ unsigned sr_iov_messages;
unsigned enslaving;
Set *addresses;
@@ -118,6 +119,7 @@ typedef struct Link {
bool static_nexthops_configured:1;
bool routing_policy_rules_configured:1;
bool tc_configured:1;
+ bool sr_iov_configured:1;
bool setting_mtu:1;
bool setting_genmode:1;
bool ipv6_mtu_set:1;
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index 5a0c86b5b3..6b471c51e9 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -15,6 +15,7 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
#include "networkd-ipv4ll.h"
#include "networkd-ndisc.h"
#include "networkd-network.h"
+#include "networkd-sriov.h"
#include "qdisc.h"
#include "tclass.h"
#include "vlan-util.h"
@@ -53,6 +54,15 @@ Link.Multicast, config_parse_tristate,
Link.AllMulticast, config_parse_tristate, 0, offsetof(Network, allmulticast)
Link.Unmanaged, config_parse_bool, 0, offsetof(Network, unmanaged)
Link.RequiredForOnline, config_parse_required_for_online, 0, 0
+SR-IOV.VirtualFunction, config_parse_sr_iov_uint32, 0, 0
+SR-IOV.VLANId, config_parse_sr_iov_uint32, 0, 0
+SR-IOV.QualityOfService, config_parse_sr_iov_uint32, 0, 0
+SR-IOV.VLANProtocol, config_parse_sr_iov_vlan_proto, 0, 0
+SR-IOV.MACSpoofCheck, config_parse_sr_iov_boolean, 0, 0
+SR-IOV.QueryReceiveSideScaling, config_parse_sr_iov_boolean, 0, 0
+SR-IOV.Trust, config_parse_sr_iov_boolean, 0, 0
+SR-IOV.LinkState, config_parse_sr_iov_link_state, 0, 0
+SR-IOV.MACAddress, config_parse_sr_iov_mac, 0, 0
Network.Description, config_parse_string, 0, offsetof(Network, description)
Network.Bridge, config_parse_ifname, 0, offsetof(Network, bridge_name)
Network.Bond, config_parse_ifname, 0, offsetof(Network, bond_name)
@@ -187,8 +197,8 @@ DHCPv4.IAID, config_parse_iaid,
DHCPv4.ListenPort, config_parse_uint16, 0, offsetof(Network, dhcp_client_port)
DHCPv4.SendRelease, config_parse_bool, 0, offsetof(Network, dhcp_send_release)
DHCPv4.SendDecline, config_parse_bool, 0, offsetof(Network, dhcp_send_decline)
-DHCPv4.DenyList, config_parse_dhcp_deny_listed_ip_address, 0, 0
-DHCPv4.BlackList, config_parse_dhcp_deny_listed_ip_address, 0, 0
+DHCPv4.DenyList, config_parse_dhcp_acl_ip_address, 0, 0
+DHCPv4.AllowList, config_parse_dhcp_acl_ip_address, 0, 0
DHCPv4.IPServiceType, config_parse_dhcp_ip_service_type, 0, offsetof(Network, ip_service_type)
DHCPv4.SendOption, config_parse_dhcp_send_option, AF_INET, offsetof(Network, dhcp_client_send_options)
DHCPv4.SendVendorOption, config_parse_dhcp_send_option, 0, offsetof(Network, dhcp_client_send_vendor_options)
@@ -206,7 +216,7 @@ DHCPv6.ForceDHCPv6PDOtherInformation, config_parse_bool,
DHCPv6.AssignAcquiredDelegatedPrefixAddress, config_parse_bool, 0, offsetof(Network, dhcp6_pd_assign_prefix)
DHCPv6.AssignAcquiredDelegatedPrefixToken, config_parse_dhcp6_delegated_prefix_token, 0, 0
DHCPv6.PrefixDelegationHint, config_parse_dhcp6_pd_hint, 0, 0
-DHCPv6.WithoutRA, config_parse_bool, 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.RouteMetric, config_parse_dhcp_route_metric, 0, 0
IPv6AcceptRA.UseAutonomousPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_autonomous_prefix)
@@ -294,11 +304,11 @@ QDisc.Parent, config_parse_qdisc_parent,
QDisc.Handle, config_parse_qdisc_handle, _QDISC_KIND_INVALID, 0
BFIFO.Parent, config_parse_qdisc_parent, QDISC_KIND_BFIFO, 0
BFIFO.Handle, config_parse_qdisc_handle, QDISC_KIND_BFIFO, 0
-BFIFO.LimitSize, config_parse_bfifo_size, QDISC_KIND_BFIFO, 0
+BFIFO.LimitBytes, config_parse_bfifo_size, QDISC_KIND_BFIFO, 0
CAKE.Parent, config_parse_qdisc_parent, QDISC_KIND_CAKE, 0
CAKE.Handle, config_parse_qdisc_handle, QDISC_KIND_CAKE, 0
CAKE.Bandwidth, config_parse_cake_bandwidth, QDISC_KIND_CAKE, 0
-CAKE.Overhead, config_parse_cake_overhead, QDISC_KIND_CAKE, 0
+CAKE.OverheadBytes, config_parse_cake_overhead, QDISC_KIND_CAKE, 0
ControlledDelay.Parent, config_parse_qdisc_parent, QDISC_KIND_CODEL, 0
ControlledDelay.Handle, config_parse_qdisc_handle, QDISC_KIND_CODEL, 0
ControlledDelay.PacketLimit, config_parse_controlled_delay_u32, QDISC_KIND_CODEL, 0
@@ -310,7 +320,7 @@ DeficitRoundRobinScheduler.Parent, config_parse_qdisc_parent,
DeficitRoundRobinScheduler.Handle, config_parse_qdisc_handle, QDISC_KIND_DRR, 0
DeficitRoundRobinSchedulerClass.Parent, config_parse_tclass_parent, TCLASS_KIND_DRR, 0
DeficitRoundRobinSchedulerClass.ClassId, config_parse_tclass_classid, TCLASS_KIND_DRR, 0
-DeficitRoundRobinSchedulerClass.Quantum, config_parse_drr_size, TCLASS_KIND_DRR, 0
+DeficitRoundRobinSchedulerClass.QuantumBytes, config_parse_drr_size, TCLASS_KIND_DRR, 0
EnhancedTransmissionSelection.Parent, config_parse_qdisc_parent, QDISC_KIND_ETS, 0
EnhancedTransmissionSelection.Handle, config_parse_qdisc_handle, QDISC_KIND_ETS, 0
EnhancedTransmissionSelection.Bands, config_parse_ets_u8, QDISC_KIND_ETS, 0
@@ -330,13 +340,13 @@ QuickFairQueueing.Handle, config_parse_qdisc_handle,
QuickFairQueueingClass.Parent, config_parse_tclass_parent, TCLASS_KIND_QFQ, 0
QuickFairQueueingClass.ClassId, config_parse_tclass_classid, TCLASS_KIND_QFQ, 0
QuickFairQueueingClass.Weight, config_parse_quick_fair_queueing_weight, TCLASS_KIND_QFQ, 0
-QuickFairQueueingClass.MaxPacketSize, config_parse_quick_fair_queueing_max_packet, TCLASS_KIND_QFQ, 0
+QuickFairQueueingClass.MaxPacketBytes, config_parse_quick_fair_queueing_max_packet, TCLASS_KIND_QFQ, 0
FairQueueing.Parent, config_parse_qdisc_parent, QDISC_KIND_FQ, 0
FairQueueing.Handle, config_parse_qdisc_handle, QDISC_KIND_FQ, 0
FairQueueing.PacketLimit, config_parse_fair_queueing_u32, QDISC_KIND_FQ, 0
FairQueueing.FlowLimit, config_parse_fair_queueing_u32, QDISC_KIND_FQ, 0
-FairQueueing.Quantum, config_parse_fair_queueing_size, QDISC_KIND_FQ, 0
-FairQueueing.InitialQuantum, config_parse_fair_queueing_size, QDISC_KIND_FQ, 0
+FairQueueing.QuantumBytes, config_parse_fair_queueing_size, QDISC_KIND_FQ, 0
+FairQueueing.InitialQuantumBytes, config_parse_fair_queueing_size, QDISC_KIND_FQ, 0
FairQueueing.MaximumRate, config_parse_fair_queueing_max_rate, QDISC_KIND_FQ, 0
FairQueueing.Buckets, config_parse_fair_queueing_u32, QDISC_KIND_FQ, 0
FairQueueing.OrphanMask, config_parse_fair_queueing_u32, QDISC_KIND_FQ, 0
@@ -345,9 +355,9 @@ FairQueueing.CEThresholdSec, config_parse_fair_queueing_usec,
FairQueueingControlledDelay.Parent, config_parse_qdisc_parent, QDISC_KIND_FQ_CODEL, 0
FairQueueingControlledDelay.Handle, config_parse_qdisc_handle, QDISC_KIND_FQ_CODEL, 0
FairQueueingControlledDelay.PacketLimit, config_parse_fair_queueing_controlled_delay_u32, QDISC_KIND_FQ_CODEL, 0
-FairQueueingControlledDelay.MemoryLimit, config_parse_fair_queueing_controlled_delay_size, QDISC_KIND_FQ_CODEL, 0
+FairQueueingControlledDelay.MemoryLimitBytes, config_parse_fair_queueing_controlled_delay_size, QDISC_KIND_FQ_CODEL, 0
FairQueueingControlledDelay.Flows, config_parse_fair_queueing_controlled_delay_u32, QDISC_KIND_FQ_CODEL, 0
-FairQueueingControlledDelay.Quantum, config_parse_fair_queueing_controlled_delay_size, QDISC_KIND_FQ_CODEL, 0
+FairQueueingControlledDelay.QuantumBytes, config_parse_fair_queueing_controlled_delay_size, QDISC_KIND_FQ_CODEL, 0
FairQueueingControlledDelay.TargetSec, config_parse_fair_queueing_controlled_delay_usec, QDISC_KIND_FQ_CODEL, 0
FairQueueingControlledDelay.IntervalSec, config_parse_fair_queueing_controlled_delay_usec, QDISC_KIND_FQ_CODEL, 0
FairQueueingControlledDelay.CEThresholdSec, config_parse_fair_queueing_controlled_delay_usec, QDISC_KIND_FQ_CODEL, 0
@@ -392,18 +402,19 @@ StochasticFairnessQueueing.Handle, config_parse_qdisc_handle,
StochasticFairnessQueueing.PerturbPeriodSec, config_parse_stochastic_fairness_queueing_perturb_period, QDISC_KIND_SFQ, 0
TokenBucketFilter.Parent, config_parse_qdisc_parent, QDISC_KIND_TBF, 0
TokenBucketFilter.Handle, config_parse_qdisc_handle, QDISC_KIND_TBF, 0
-TokenBucketFilter.Rate, config_parse_token_bucket_filter_size, QDISC_KIND_TBF, 0
-TokenBucketFilter.Burst, config_parse_token_bucket_filter_size, QDISC_KIND_TBF, 0
-TokenBucketFilter.LimitSize, config_parse_token_bucket_filter_size, QDISC_KIND_TBF, 0
+TokenBucketFilter.Rate, config_parse_token_bucket_filter_rate, QDISC_KIND_TBF, 0
+TokenBucketFilter.BurstBytes, config_parse_token_bucket_filter_size, QDISC_KIND_TBF, 0
+TokenBucketFilter.LimitBytes, config_parse_token_bucket_filter_size, QDISC_KIND_TBF, 0
TokenBucketFilter.MTUBytes, config_parse_token_bucket_filter_size, QDISC_KIND_TBF, 0
TokenBucketFilter.MPUBytes, config_parse_token_bucket_filter_size, QDISC_KIND_TBF, 0
-TokenBucketFilter.PeakRate, config_parse_token_bucket_filter_size, QDISC_KIND_TBF, 0
+TokenBucketFilter.PeakRate, config_parse_token_bucket_filter_rate, QDISC_KIND_TBF, 0
TokenBucketFilter.LatencySec, config_parse_token_bucket_filter_latency, QDISC_KIND_TBF, 0
TrivialLinkEqualizer.Parent, config_parse_qdisc_parent, QDISC_KIND_TEQL, 0
TrivialLinkEqualizer.Handle, config_parse_qdisc_handle, QDISC_KIND_TEQL, 0
TrivialLinkEqualizer.Id, config_parse_trivial_link_equalizer_id, QDISC_KIND_TEQL, 0
/* backwards compatibility: do not add new entries to this section */
Network.IPv4LL, config_parse_ipv4ll, 0, offsetof(Network, link_local)
+DHCPv4.BlackList, config_parse_dhcp_acl_ip_address, 0, 0
DHCP.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier)
DHCP.UseDNS, config_parse_dhcp_use_dns, 0, 0
DHCP.UseNTP, config_parse_dhcp_use_ntp, 0, 0
@@ -436,3 +447,9 @@ TrafficControlQueueingDiscipline.NetworkEmulatorDelayJitterSec, config_parse_net
TrafficControlQueueingDiscipline.NetworkEmulatorLossRate, config_parse_network_emulator_rate, 0, 0
TrafficControlQueueingDiscipline.NetworkEmulatorDuplicateRate, config_parse_network_emulator_rate, 0, 0
TrafficControlQueueingDiscipline.NetworkEmulatorPacketLimit, config_parse_network_emulator_packet_limit, 0, 0
+FairQueueing.Quantum, config_parse_fair_queueing_size, QDISC_KIND_FQ, 0
+FairQueueing.InitialQuantum, config_parse_fair_queueing_size, QDISC_KIND_FQ, 0
+FairQueueingControlledDelay.MemoryLimit, config_parse_fair_queueing_controlled_delay_size, QDISC_KIND_FQ_CODEL, 0
+FairQueueingControlledDelay.Quantum, config_parse_fair_queueing_controlled_delay_size, QDISC_KIND_FQ_CODEL, 0
+TokenBucketFilter.Burst, config_parse_token_bucket_filter_size, QDISC_KIND_TBF, 0
+TokenBucketFilter.LimitSize, config_parse_token_bucket_filter_size, QDISC_KIND_TBF, 0
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index e3012b4769..22bd06a891 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -16,6 +16,7 @@
#include "network-internal.h"
#include "networkd-manager.h"
#include "networkd-network.h"
+#include "networkd-sriov.h"
#include "parse-util.h"
#include "path-lookup.h"
#include "set.h"
@@ -158,6 +159,7 @@ int network_verify(Network *network) {
Route *route, *route_next;
FdbEntry *fdb, *fdb_next;
TrafficControl *tc;
+ SRIOV *sr_iov;
Iterator i;
assert(network);
@@ -330,6 +332,10 @@ int network_verify(Network *network) {
if (traffic_control_section_verify(tc, &has_root, &has_clsact) < 0)
traffic_control_free(tc);
+ ORDERED_HASHMAP_FOREACH(sr_iov, network->sr_iov_by_section, i)
+ if (sr_iov_section_verify(sr_iov) < 0)
+ sr_iov_free(sr_iov);
+
return 0;
}
@@ -484,6 +490,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
filename, NETWORK_DIRS, dropin_dirname,
"Match\0"
"Link\0"
+ "SR-IOV\0"
"Network\0"
"Address\0"
"Neighbor\0"
@@ -663,6 +670,7 @@ static Network *network_free(Network *network) {
strv_free(network->dhcp_user_class);
free(network->dhcp_hostname);
set_free(network->dhcp_deny_listed_ip);
+ set_free(network->dhcp_allow_listed_ip);
set_free(network->dhcp_request_options);
set_free(network->dhcp6_request_options);
free(network->mac);
@@ -731,6 +739,7 @@ static Network *network_free(Network *network) {
hashmap_free(network->prefixes_by_section);
hashmap_free(network->route_prefixes_by_section);
hashmap_free(network->rules_by_section);
+ 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);
if (network->manager &&
diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
index 916bfdc9a8..424298248f 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -17,6 +17,7 @@
#include "networkd-brvlan.h"
#include "networkd-dhcp-common.h"
#include "networkd-dhcp4.h"
+#include "networkd-dhcp6.h"
#include "networkd-dhcp-server.h"
#include "networkd-fdb.h"
#include "networkd-ipv6-proxy-ndp.h"
@@ -139,6 +140,7 @@ struct Network {
DHCPUseDomains dhcp_use_domains;
sd_ipv4acd *dhcp_acd;
Set *dhcp_deny_listed_ip;
+ Set *dhcp_allow_listed_ip;
Set *dhcp_request_options;
OrderedHashmap *dhcp_client_send_options;
OrderedHashmap *dhcp_client_send_vendor_options;
@@ -150,7 +152,6 @@ struct Network {
bool dhcp6_use_dns_set;
bool dhcp6_use_ntp;
bool dhcp6_use_ntp_set;
- bool dhcp6_without_ra;
uint8_t dhcp6_pd_length;
uint32_t dhcp6_route_metric;
bool dhcp6_route_metric_set;
@@ -158,6 +159,7 @@ struct Network {
char **dhcp6_user_class;
char **dhcp6_vendor_class;
struct in6_addr dhcp6_pd_address;
+ DHCP6ClientStartMode dhcp6_without_ra;
OrderedHashmap *dhcp6_client_send_options;
OrderedHashmap *dhcp6_client_send_vendor_options;
Set *dhcp6_request_options;
@@ -311,6 +313,7 @@ struct Network {
Hashmap *route_prefixes_by_section;
Hashmap *rules_by_section;
OrderedHashmap *tc_by_section;
+ OrderedHashmap *sr_iov_by_section;
/* All kinds of DNS configuration */
struct in_addr_data *dns;
diff --git a/src/network/networkd-radv.c b/src/network/networkd-radv.c
index f5f8ec65ed..d52aadecfa 100644
--- a/src/network/networkd-radv.c
+++ b/src/network/networkd-radv.c
@@ -672,6 +672,37 @@ int radv_configure(Link *link) {
return 0;
}
+int radv_add_prefix(Link *link, struct in6_addr *prefix, uint8_t prefix_len,
+ uint32_t lifetime_preferred, uint32_t lifetime_valid) {
+ _cleanup_(sd_radv_prefix_unrefp) sd_radv_prefix *p = NULL;
+ int r;
+
+ assert(link);
+ assert(link->radv);
+
+ r = sd_radv_prefix_new(&p);
+ if (r < 0)
+ return r;
+
+ r = sd_radv_prefix_set_prefix(p, prefix, prefix_len);
+ if (r < 0)
+ return r;
+
+ r = sd_radv_prefix_set_preferred_lifetime(p, lifetime_preferred);
+ if (r < 0)
+ return r;
+
+ r = sd_radv_prefix_set_valid_lifetime(p, lifetime_valid);
+ if (r < 0)
+ return r;
+
+ r = sd_radv_add_prefix(link->radv, p, true);
+ if (r < 0 && r != -EEXIST)
+ return r;
+
+ return 0;
+}
+
int config_parse_radv_dns(
const char *unit,
const char *filename,
diff --git a/src/network/networkd-radv.h b/src/network/networkd-radv.h
index b115243ef5..741aa8692f 100644
--- a/src/network/networkd-radv.h
+++ b/src/network/networkd-radv.h
@@ -52,6 +52,8 @@ DEFINE_NETWORK_SECTION_FUNCTIONS(RoutePrefix, route_prefix_free);
int radv_emit_dns(Link *link);
int radv_configure(Link *link);
+int radv_add_prefix(Link *link, struct in6_addr *prefix, uint8_t prefix_len,
+ uint32_t lifetime_preferred, uint32_t lifetime_valid);
const char* radv_prefix_delegation_to_string(RADVPrefixDelegation i) _const_;
RADVPrefixDelegation radv_prefix_delegation_from_string(const char *s) _pure_;
diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c
index c4124c0906..035f006d35 100644
--- a/src/network/networkd-routing-policy-rule.c
+++ b/src/network/networkd-routing-policy-rule.c
@@ -506,17 +506,17 @@ int routing_policy_rule_configure(RoutingPolicyRule *rule, Link *link, link_netl
if (rule->tos > 0) {
r = sd_rtnl_message_routing_policy_rule_set_tos(m, rule->tos);
if (r < 0)
- return log_link_error_errno(link, r, "Could not set ip rule tos: %m");
+ return log_link_error_errno(link, r, "Could not set IP rule TOS: %m");
}
if (rule->table < 256) {
r = sd_rtnl_message_routing_policy_rule_set_table(m, rule->table);
if (r < 0)
- return log_link_error_errno(link, r, "Could not set ip rule table: %m");
+ return log_link_error_errno(link, r, "Could not set IP rule table: %m");
} else {
r = sd_rtnl_message_routing_policy_rule_set_table(m, RT_TABLE_UNSPEC);
if (r < 0)
- return log_link_error_errno(link, r, "Could not set ip rule table: %m");
+ return log_link_error_errno(link, r, "Could not set IP rule table: %m");
r = sd_netlink_message_append_u32(m, FRA_TABLE, rule->table);
if (r < 0)
@@ -698,7 +698,7 @@ int config_parse_routing_policy_rule_tos(
r = safe_atou8(rvalue, &n->tos);
if (r < 0) {
- log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse RPDB rule tos, ignoring: %s", rvalue);
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse RPDB rule TOS, ignoring: %s", rvalue);
return 0;
}
@@ -1372,7 +1372,7 @@ int routing_policy_load_rules(const char *state_file, Set **rules) {
} else if (streq(a, "tos")) {
r = safe_atou8(b, &rule->tos);
if (r < 0) {
- log_error_errno(r, "Failed to parse RPDB rule tos, ignoring: %s", b);
+ log_error_errno(r, "Failed to parse RPDB rule TOS, ignoring: %s", b);
continue;
}
} else if (streq(a, "table")) {
diff --git a/src/network/networkd-sriov.c b/src/network/networkd-sriov.c
new file mode 100644
index 0000000000..5ae751ed46
--- /dev/null
+++ b/src/network/networkd-sriov.c
@@ -0,0 +1,501 @@
+/* SPDX-License-Identifier: LGPL-2.1+
+ * Copyright © 2020 VMware, Inc. */
+
+#include "alloc-util.h"
+#include "netlink-util.h"
+#include "networkd-manager.h"
+#include "networkd-sriov.h"
+#include "parse-util.h"
+#include "set.h"
+#include "string-util.h"
+
+static int sr_iov_new(SRIOV **ret) {
+ SRIOV *sr_iov;
+
+ sr_iov = new(SRIOV, 1);
+ if (!sr_iov)
+ return -ENOMEM;
+
+ *sr_iov = (SRIOV) {
+ .vf = (uint32_t) -1,
+ .vlan_proto = ETH_P_8021Q,
+ .vf_spoof_check_setting = -1,
+ .trust = -1,
+ .query_rss = -1,
+ .link_state = _SR_IOV_LINK_STATE_INVALID,
+ };
+
+ *ret = TAKE_PTR(sr_iov);
+
+ return 0;
+}
+
+static int sr_iov_new_static(Network *network, const char *filename, unsigned section_line, SRIOV **ret) {
+ _cleanup_(network_config_section_freep) NetworkConfigSection *n = NULL;
+ _cleanup_(sr_iov_freep) SRIOV *sr_iov = NULL;
+ SRIOV *existing = NULL;
+ int r;
+
+ assert(network);
+ assert(ret);
+ assert(filename);
+ assert(section_line > 0);
+
+ r = network_config_section_new(filename, section_line, &n);
+ if (r < 0)
+ return r;
+
+ existing = ordered_hashmap_get(network->sr_iov_by_section, n);
+ if (existing) {
+ *ret = existing;
+ return 0;
+ }
+
+ r = sr_iov_new(&sr_iov);
+ if (r < 0)
+ return r;
+
+ sr_iov->network = network;
+ sr_iov->section = TAKE_PTR(n);
+
+ r = ordered_hashmap_ensure_allocated(&network->sr_iov_by_section, &network_config_hash_ops);
+ if (r < 0)
+ return r;
+
+ r = ordered_hashmap_put(network->sr_iov_by_section, sr_iov->section, sr_iov);
+ if (r < 0)
+ return r;
+
+ *ret = TAKE_PTR(sr_iov);
+ return 0;
+}
+
+SRIOV *sr_iov_free(SRIOV *sr_iov) {
+ if (!sr_iov)
+ return NULL;
+
+ if (sr_iov->network && sr_iov->section)
+ ordered_hashmap_remove(sr_iov->network->sr_iov_by_section, sr_iov->section);
+
+ network_config_section_free(sr_iov->section);
+
+ return mfree(sr_iov);
+}
+
+static int sr_iov_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
+ int r;
+
+ assert(link);
+ assert(link->sr_iov_messages > 0);
+ link->sr_iov_messages--;
+
+ if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
+ return 1;
+
+ r = sd_netlink_message_get_errno(m);
+ if (r < 0 && r != -EEXIST) {
+ log_link_message_error_errno(link, m, r, "Could not set up SR-IOV");
+ link_enter_failed(link);
+ return 1;
+ }
+
+ if (link->sr_iov_messages == 0) {
+ log_link_debug(link, "SR-IOV configured");
+ link->sr_iov_configured = true;
+ link_check_ready(link);
+ }
+
+ return 1;
+}
+
+int sr_iov_configure(Link *link, SRIOV *sr_iov) {
+ _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
+ int r;
+
+ assert(link);
+ assert(link->manager);
+ assert(link->manager->rtnl);
+ assert(link->ifindex > 0);
+
+ log_link_debug(link, "Setting SR-IOV virtual function %"PRIu32, sr_iov->vf);
+
+ r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not allocate RTM_SETLINK message: %m");
+
+ r = sd_netlink_message_open_container(req, IFLA_VFINFO_LIST);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not open IFLA_VFINFO_LIST container: %m");
+
+ r = sd_netlink_message_open_container(req, IFLA_VF_INFO);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not open IFLA_VF_INFO container: %m");
+
+ if (!ether_addr_is_null(&sr_iov->mac)) {
+ struct ifla_vf_mac ivm = {
+ .vf = sr_iov->vf,
+ };
+
+ memcpy(ivm.mac, &sr_iov->mac, ETH_ALEN);
+ r = sd_netlink_message_append_data(req, IFLA_VF_MAC, &ivm, sizeof(struct ifla_vf_mac));
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFLA_VF_MAC: %m");
+ }
+
+ if (sr_iov->vf_spoof_check_setting >= 0) {
+ struct ifla_vf_spoofchk ivs = {
+ .vf = sr_iov->vf,
+ .setting = sr_iov->vf_spoof_check_setting,
+ };
+
+ r = sd_netlink_message_append_data(req, IFLA_VF_SPOOFCHK, &ivs, sizeof(struct ifla_vf_spoofchk));
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFLA_VF_SPOOFCHK: %m");
+ }
+
+ if (sr_iov->query_rss >= 0) {
+ struct ifla_vf_rss_query_en ivs = {
+ .vf = sr_iov->vf,
+ .setting = sr_iov->query_rss,
+ };
+
+ r = sd_netlink_message_append_data(req, IFLA_VF_RSS_QUERY_EN, &ivs, sizeof(struct ifla_vf_rss_query_en));
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFLA_VF_RSS_QUERY_EN: %m");
+ }
+
+ if (sr_iov->trust >= 0) {
+ struct ifla_vf_trust ivt = {
+ .vf = sr_iov->vf,
+ .setting = sr_iov->trust,
+ };
+
+ r = sd_netlink_message_append_data(req, IFLA_VF_TRUST, &ivt, sizeof(struct ifla_vf_trust));
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFLA_VF_TRUST: %m");
+ }
+
+ if (sr_iov->link_state >= 0) {
+ struct ifla_vf_link_state ivl = {
+ .vf = sr_iov->vf,
+ .link_state = sr_iov->link_state,
+ };
+
+ r = sd_netlink_message_append_data(req, IFLA_VF_LINK_STATE, &ivl, sizeof(struct ifla_vf_link_state));
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFLA_VF_LINK_STATE: %m");
+ }
+
+ if (sr_iov->vlan > 0) {
+ /* Because of padding, first the buffer must be initialized with 0. */
+ struct ifla_vf_vlan_info ivvi = {};
+ ivvi.vf = sr_iov->vf;
+ ivvi.vlan = sr_iov->vlan;
+ ivvi.qos = sr_iov->qos;
+ ivvi.vlan_proto = htobe16(sr_iov->vlan_proto);
+
+ r = sd_netlink_message_open_container(req, IFLA_VF_VLAN_LIST);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not open IFLA_VF_VLAN_LIST container: %m");
+
+ r = sd_netlink_message_append_data(req, IFLA_VF_VLAN_INFO, &ivvi, sizeof(struct ifla_vf_vlan_info));
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFLA_VF_VLAN_INFO: %m");
+
+ r = sd_netlink_message_close_container(req);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not close IFLA_VF_VLAN_LIST container: %m");
+ }
+
+ r = sd_netlink_message_close_container(req);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not close IFLA_VF_INFO container: %m");
+
+ r = sd_netlink_message_close_container(req);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not close IFLA_VFINFO_LIST container: %m");
+
+ r = netlink_call_async(link->manager->rtnl, NULL, req, sr_iov_handler,
+ link_netlink_destroy_callback, link);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
+
+ link_ref(link);
+ link->sr_iov_messages++;
+
+ return 0;
+}
+
+int sr_iov_section_verify(SRIOV *sr_iov) {
+ assert(sr_iov);
+
+ if (section_is_invalid(sr_iov->section))
+ return -EINVAL;
+
+ if (sr_iov->vf == (uint32_t) -1)
+ return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
+ "%s: [SRIOV] section without VirtualFunction= field configured. "
+ "Ignoring [SRIOV] section from line %u.",
+ sr_iov->section->filename, sr_iov->section->line);
+
+ return 0;
+}
+
+int config_parse_sr_iov_uint32(
+ 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_(sr_iov_free_or_set_invalidp) SRIOV *sr_iov = NULL;
+ Network *network = data;
+ uint32_t k;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = sr_iov_new_static(network, filename, section_line, &sr_iov);
+ if (r < 0)
+ return r;
+
+ if (isempty(rvalue)) {
+ if (streq(lvalue, "VirtualFunction"))
+ sr_iov->vf = (uint32_t) -1;
+ else if (streq(lvalue, "VLANId"))
+ sr_iov->vlan = 0;
+ else if (streq(lvalue, "QualityOfService"))
+ sr_iov->qos = 0;
+ else
+ assert_not_reached("Invalid lvalue");
+
+ TAKE_PTR(sr_iov);
+ return 0;
+ }
+
+ r = safe_atou32(rvalue, &k);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to parse SR-IOV '%s=', ignoring assignment: %s", lvalue, rvalue);
+ return 0;
+ }
+
+ if (streq(lvalue, "VLANId")) {
+ if (k == 0 || k > 4095) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid SR-IOV VLANId: %d", k);
+ return 0;
+ }
+ sr_iov->vlan = k;
+ } else if (streq(lvalue, "VirtualFunction")) {
+ if (k >= INT_MAX) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid SR-IOV virtual function: %d", k);
+ return 0;
+ }
+ sr_iov->vf = k;
+ } else if (streq(lvalue, "QualityOfService"))
+ sr_iov->qos = k;
+ else
+ assert_not_reached("Invalid lvalue");
+
+ TAKE_PTR(sr_iov);
+ return 0;
+}
+
+int config_parse_sr_iov_vlan_proto(
+ 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_(sr_iov_free_or_set_invalidp) SRIOV *sr_iov = NULL;
+ Network *network = data;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = sr_iov_new_static(network, filename, section_line, &sr_iov);
+ if (r < 0)
+ return r;
+
+ if (isempty(rvalue) || streq(rvalue, "802.1Q"))
+ sr_iov->vlan_proto = ETH_P_8021Q;
+ else if (streq(rvalue, "802.1ad"))
+ sr_iov->vlan_proto = ETH_P_8021AD;
+ else {
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Invalid SR-IOV '%s=', ignoring assignment: %s", lvalue, rvalue);
+ return 0;
+ }
+
+ TAKE_PTR(sr_iov);
+ return 0;
+}
+
+int config_parse_sr_iov_link_state(
+ 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_(sr_iov_free_or_set_invalidp) SRIOV *sr_iov = NULL;
+ Network *network = data;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = sr_iov_new_static(network, filename, section_line, &sr_iov);
+ if (r < 0)
+ return r;
+
+ /* Unfortunately, SR_IOV_LINK_STATE_DISABLE is 2, not 0. So, we cannot use
+ * DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN() macro. */
+
+ if (isempty(rvalue)) {
+ sr_iov->link_state = _SR_IOV_LINK_STATE_INVALID;
+ TAKE_PTR(sr_iov);
+ return 0;
+ }
+
+ if (streq(rvalue, "auto")) {
+ sr_iov->link_state = SR_IOV_LINK_STATE_AUTO;
+ TAKE_PTR(sr_iov);
+ return 0;
+ }
+
+ r = parse_boolean(rvalue);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to parse SR-IOV '%s=', ignoring assignment: %s", lvalue, rvalue);
+ return 0;
+ }
+
+ sr_iov->link_state = r ? SR_IOV_LINK_STATE_ENABLE : SR_IOV_LINK_STATE_DISABLE;
+ TAKE_PTR(sr_iov);
+ return 0;
+}
+
+int config_parse_sr_iov_boolean(
+ 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_(sr_iov_free_or_set_invalidp) SRIOV *sr_iov = NULL;
+ Network *network = data;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = sr_iov_new_static(network, filename, section_line, &sr_iov);
+ if (r < 0)
+ return r;
+
+ if (isempty(rvalue)) {
+ if (streq(lvalue, "MACSpoofCheck"))
+ sr_iov->vf_spoof_check_setting = -1;
+ else if (streq(lvalue, "QueryReceiveSideScaling"))
+ sr_iov->query_rss = -1;
+ else if (streq(lvalue, "Trust"))
+ sr_iov->trust = -1;
+ else
+ assert_not_reached("Invalid lvalue");
+
+ TAKE_PTR(sr_iov);
+ return 0;
+ }
+
+ r = parse_boolean(rvalue);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse '%s=', ignoring: %s", lvalue, rvalue);
+ return 0;
+ }
+
+ if (streq(lvalue, "MACSpoofCheck"))
+ sr_iov->vf_spoof_check_setting = r;
+ else if (streq(lvalue, "QueryReceiveSideScaling"))
+ sr_iov->query_rss = r;
+ else if (streq(lvalue, "Trust"))
+ sr_iov->trust = r;
+ else
+ assert_not_reached("Invalid lvalue");
+
+ TAKE_PTR(sr_iov);
+ return 0;
+}
+
+int config_parse_sr_iov_mac(
+ 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_(sr_iov_free_or_set_invalidp) SRIOV *sr_iov = NULL;
+ Network *network = data;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = sr_iov_new_static(network, filename, section_line, &sr_iov);
+ if (r < 0)
+ return r;
+
+ if (isempty(rvalue)) {
+ sr_iov->mac = ETHER_ADDR_NULL;
+ TAKE_PTR(sr_iov);
+ return 0;
+ }
+
+ r = ether_addr_from_string(rvalue, &sr_iov->mac);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, 0,
+ "Failed to parse SR-IOV '%s=', ignoring assignment: %s", lvalue, rvalue);
+ return 0;
+ }
+
+ TAKE_PTR(sr_iov);
+ return 0;
+}
diff --git a/src/network/networkd-sriov.h b/src/network/networkd-sriov.h
new file mode 100644
index 0000000000..a545d1292a
--- /dev/null
+++ b/src/network/networkd-sriov.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: LGPL-2.1+
+ * Copyright © 2020 VMware, Inc. */
+#pragma once
+
+#include <linux/if_link.h>
+
+#include "conf-parser.h"
+#include "networkd-link.h"
+#include "networkd-network.h"
+#include "networkd-util.h"
+
+typedef enum SRIOVLinkState {
+ SR_IOV_LINK_STATE_AUTO = IFLA_VF_LINK_STATE_AUTO,
+ SR_IOV_LINK_STATE_ENABLE = IFLA_VF_LINK_STATE_ENABLE,
+ SR_IOV_LINK_STATE_DISABLE = IFLA_VF_LINK_STATE_DISABLE,
+ _SR_IOV_LINK_STATE_MAX,
+ _SR_IOV_LINK_STATE_INVALID = -1,
+} SRIOVLinkState;
+
+typedef struct SRIOV {
+ NetworkConfigSection *section;
+ Network *network;
+
+ uint32_t vf; /* 0 - 2147483646 */
+ uint32_t vlan; /* 0 - 4095, 0 disables VLAN filter */
+ uint32_t qos;
+ uint16_t vlan_proto; /* ETH_P_8021Q or ETH_P_8021AD */
+ int vf_spoof_check_setting;
+ int query_rss;
+ int trust;
+ SRIOVLinkState link_state;
+ struct ether_addr mac;
+} SRIOV;
+
+SRIOV *sr_iov_free(SRIOV *sr_iov);
+
+int sr_iov_configure(Link *link, SRIOV *sr_iov);
+int sr_iov_section_verify(SRIOV *sr_iov);
+
+DEFINE_NETWORK_SECTION_FUNCTIONS(SRIOV, sr_iov_free);
+
+CONFIG_PARSER_PROTOTYPE(config_parse_sr_iov_uint32);
+CONFIG_PARSER_PROTOTYPE(config_parse_sr_iov_boolean);
+CONFIG_PARSER_PROTOTYPE(config_parse_sr_iov_link_state);
+CONFIG_PARSER_PROTOTYPE(config_parse_sr_iov_vlan_proto);
+CONFIG_PARSER_PROTOTYPE(config_parse_sr_iov_mac);
diff --git a/src/network/networkd.c b/src/network/networkd.c
index 35f22fea80..445aee16ad 100644
--- a/src/network/networkd.c
+++ b/src/network/networkd.c
@@ -17,8 +17,8 @@
#include "user-util.h"
static int run(int argc, char *argv[]) {
- _cleanup_(notify_on_cleanup) const char *notify_message = NULL;
_cleanup_(manager_freep) Manager *m = NULL;
+ _cleanup_(notify_on_cleanup) const char *notify_message = NULL;
int r;
log_setup_service();
diff --git a/src/network/tc/cake.c b/src/network/tc/cake.c
index b499661bd3..286c7e172f 100644
--- a/src/network/tc/cake.c
+++ b/src/network/tc/cake.c
@@ -136,14 +136,14 @@ int config_parse_cake_overhead(
r = safe_atoi32(rvalue, &v);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
- "Failed to parse 'Overhead=', ignoring assignment: %s",
- rvalue);
+ "Failed to parse '%s=', ignoring assignment: %s",
+ lvalue, rvalue);
return 0;
}
if (v < -64 || v > 256) {
log_syntax(unit, LOG_ERR, filename, line, 0,
- "Invalid 'Overhead=', ignoring assignment: %s",
- rvalue);
+ "Invalid '%s=', ignoring assignment: %s",
+ lvalue, rvalue);
return 0;
}
diff --git a/src/network/tc/drr.c b/src/network/tc/drr.c
index ac64eb8b03..a671f32d99 100644
--- a/src/network/tc/drr.c
+++ b/src/network/tc/drr.c
@@ -79,7 +79,7 @@ int config_parse_drr_size(
return 0;
}
- r = parse_size(rvalue, 1000, &u);
+ r = parse_size(rvalue, 1024, &u);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse '%s=', ignoring assignment: %s",
diff --git a/src/network/tc/ets.c b/src/network/tc/ets.c
index c4fa5646dd..83e9d8bff3 100644
--- a/src/network/tc/ets.c
+++ b/src/network/tc/ets.c
@@ -283,7 +283,7 @@ int config_parse_ets_prio(
lvalue, word);
continue;
}
- if (ets->n_quanta > TC_PRIO_MAX) {
+ if (ets->n_prio > TC_PRIO_MAX) {
log_syntax(unit, LOG_ERR, filename, line, 0,
"Too many priomap in '%s=', ignoring assignment: %s",
lvalue, word);
diff --git a/src/network/tc/fifo.c b/src/network/tc/fifo.c
index 8ef6e513bb..1a608dd7c0 100644
--- a/src/network/tc/fifo.c
+++ b/src/network/tc/fifo.c
@@ -140,7 +140,7 @@ int config_parse_bfifo_size(
return 0;
}
- r = parse_size(rvalue, 1000, &u);
+ r = parse_size(rvalue, 1024, &u);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse '%s=', ignoring assignment: %s",
diff --git a/src/network/tc/fq-codel.c b/src/network/tc/fq-codel.c
index 6c7932c70f..721112d317 100644
--- a/src/network/tc/fq-codel.c
+++ b/src/network/tc/fq-codel.c
@@ -9,6 +9,7 @@
#include "parse-util.h"
#include "qdisc.h"
#include "string-util.h"
+#include "strv.h"
static int fair_queueing_controlled_delay_init(QDisc *qdisc) {
FairQueueingControlledDelay *fqcd;
@@ -301,15 +302,15 @@ int config_parse_fair_queueing_controlled_delay_size(
fqcd = FQ_CODEL(qdisc);
- if (streq(lvalue, "MemoryLimit"))
+ if (STR_IN_SET(lvalue, "MemoryLimitBytes", "MemoryLimit"))
p = &fqcd->memory_limit;
- else if (streq(lvalue, "Quantum"))
+ else if (STR_IN_SET(lvalue, "QuantumBytes", "Quantum"))
p = &fqcd->quantum;
else
assert_not_reached("Invalid lvalue.");
if (isempty(rvalue)) {
- if (streq(lvalue, "MemoryLimit"))
+ if (STR_IN_SET(lvalue, "MemoryLimitBytes", "MemoryLimit"))
*p = UINT32_MAX;
else
*p = 0;
diff --git a/src/network/tc/fq.c b/src/network/tc/fq.c
index c7eeec2307..f717dc790c 100644
--- a/src/network/tc/fq.c
+++ b/src/network/tc/fq.c
@@ -9,7 +9,7 @@
#include "netlink-util.h"
#include "parse-util.h"
#include "string-util.h"
-#include "util.h"
+#include "strv.h"
static int fair_queueing_init(QDisc *qdisc) {
FairQueueing *fq;
@@ -198,9 +198,9 @@ int config_parse_fair_queueing_size(
fq = FQ(qdisc);
- if (streq(lvalue, "Quantum"))
+ if (STR_IN_SET(lvalue, "QuantumBytes", "Quantum"))
p = &fq->quantum;
- else if (streq(lvalue, "InitialQuantum"))
+ else if (STR_IN_SET(lvalue, "InitialQuantumBytes", "InitialQuantum"))
p = &fq->initial_quantum;
else
assert_not_reached("Invalid lvalue");
diff --git a/src/network/tc/qdisc.c b/src/network/tc/qdisc.c
index 91cdd8917f..c2b6c1de2f 100644
--- a/src/network/tc/qdisc.c
+++ b/src/network/tc/qdisc.c
@@ -39,7 +39,7 @@ const QDiscVTable * const qdisc_vtable[_QDISC_KIND_MAX] = {
};
static int qdisc_new(QDiscKind kind, QDisc **ret) {
- QDisc *qdisc;
+ _cleanup_(qdisc_freep) QDisc *qdisc = NULL;
int r;
if (kind == _QDISC_KIND_INVALID) {
diff --git a/src/network/tc/qfq.c b/src/network/tc/qfq.c
index 71d5b15e81..52c17625bf 100644
--- a/src/network/tc/qfq.c
+++ b/src/network/tc/qfq.c
@@ -142,7 +142,7 @@ int config_parse_quick_fair_queueing_max_packet(
return 0;
}
- r = parse_size(rvalue, 1000, &v);
+ r = parse_size(rvalue, 1024, &v);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse '%s=', ignoring assignment: %s",
diff --git a/src/network/tc/tbf.c b/src/network/tc/tbf.c
index 0682ab4cc6..2c730352d2 100644
--- a/src/network/tc/tbf.c
+++ b/src/network/tc/tbf.c
@@ -12,8 +12,8 @@
#include "parse-util.h"
#include "qdisc.h"
#include "string-util.h"
+#include "strv.h"
#include "tc-util.h"
-#include "util.h"
static int token_bucket_filter_fill_message(Link *link, QDisc *qdisc, sd_netlink_message *req) {
uint32_t rtab[256], ptab[256];
@@ -143,24 +143,22 @@ int config_parse_token_bucket_filter_size(
tbf = TBF(qdisc);
if (isempty(rvalue)) {
- if (streq(lvalue, "Rate"))
- tbf->rate = 0;
- else if (streq(lvalue, "Burst"))
+ if (STR_IN_SET(lvalue, "BurstBytes", "Burst"))
tbf->burst = 0;
- else if (streq(lvalue, "LimitSize"))
+ else if (STR_IN_SET(lvalue, "LimitBytes", "LimitSize"))
tbf->limit = 0;
else if (streq(lvalue, "MTUBytes"))
tbf->mtu = 0;
else if (streq(lvalue, "MPUBytes"))
tbf->mpu = 0;
- else if (streq(lvalue, "PeakRate"))
- tbf->peak_rate = 0;
+ else
+ assert_not_reached("unknown lvalue");
qdisc = NULL;
return 0;
}
- r = parse_size(rvalue, 1000, &k);
+ r = parse_size(rvalue, 1024, &k);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse '%s=', ignoring assignment: %s",
@@ -168,18 +166,76 @@ int config_parse_token_bucket_filter_size(
return 0;
}
- if (streq(lvalue, "Rate"))
- tbf->rate = k / 8;
- else if (streq(lvalue, "Burst"))
+ if (STR_IN_SET(lvalue, "BurstBytes", "Burst"))
tbf->burst = k;
- else if (streq(lvalue, "LimitSize"))
+ else if (STR_IN_SET(lvalue, "LimitBytes", "LimitSize"))
tbf->limit = k;
else if (streq(lvalue, "MPUBytes"))
tbf->mpu = k;
else if (streq(lvalue, "MTUBytes"))
tbf->mtu = k;
+ else
+ assert_not_reached("unknown lvalue");
+
+ qdisc = NULL;
+
+ return 0;
+}
+
+int config_parse_token_bucket_filter_rate(
+ 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_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
+ Network *network = data;
+ TokenBucketFilter *tbf;
+ uint64_t k, *p;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ r = qdisc_new_static(QDISC_KIND_TBF, network, filename, section_line, &qdisc);
+ if (r == -ENOMEM)
+ return log_oom();
+ if (r < 0)
+ return log_syntax(unit, LOG_ERR, filename, line, r,
+ "More than one kind of queueing discipline, ignoring assignment: %m");
+
+ tbf = TBF(qdisc);
+ if (streq(lvalue, "Rate"))
+ p = &tbf->rate;
else if (streq(lvalue, "PeakRate"))
- tbf->peak_rate = k / 8;
+ p = &tbf->peak_rate;
+ else
+ assert_not_reached("unknown lvalue");
+
+ if (isempty(rvalue)) {
+ *p = 0;
+
+ qdisc = NULL;
+ return 0;
+ }
+
+ r = parse_size(rvalue, 1000, &k);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, r,
+ "Failed to parse '%s=', ignoring assignment: %s",
+ lvalue, rvalue);
+ return 0;
+ }
+
+ *p = k / 8;
qdisc = NULL;
diff --git a/src/network/tc/tbf.h b/src/network/tc/tbf.h
index b66aef206c..a785be25e0 100644
--- a/src/network/tc/tbf.h
+++ b/src/network/tc/tbf.h
@@ -23,3 +23,4 @@ extern const QDiscVTable tbf_vtable;
CONFIG_PARSER_PROTOTYPE(config_parse_token_bucket_filter_latency);
CONFIG_PARSER_PROTOTYPE(config_parse_token_bucket_filter_size);
+CONFIG_PARSER_PROTOTYPE(config_parse_token_bucket_filter_rate);
diff --git a/src/network/tc/tclass.c b/src/network/tc/tclass.c
index 4f75e1b42d..a89e7757ad 100644
--- a/src/network/tc/tclass.c
+++ b/src/network/tc/tclass.c
@@ -22,7 +22,7 @@ const TClassVTable * const tclass_vtable[_TCLASS_KIND_MAX] = {
};
static int tclass_new(TClassKind kind, TClass **ret) {
- TClass *tclass;
+ _cleanup_(tclass_freep) TClass *tclass = NULL;
int r;
tclass = malloc0(tclass_vtable[kind]->object_size);
diff --git a/src/network/wait-online/wait-online.c b/src/network/wait-online/wait-online.c
index 17ed5d38cf..cfd9093f1a 100644
--- a/src/network/wait-online/wait-online.c
+++ b/src/network/wait-online/wait-online.c
@@ -183,8 +183,8 @@ static int parse_argv(int argc, char *argv[]) {
}
static int run(int argc, char *argv[]) {
- _cleanup_(notify_on_cleanup) const char *notify_message = NULL;
_cleanup_(manager_freep) Manager *m = NULL;
+ _cleanup_(notify_on_cleanup) const char *notify_message = NULL;
int r;
log_setup_service();
diff --git a/src/partition/repart.c b/src/partition/repart.c
index 6da00be2ab..3080521279 100644
--- a/src/partition/repart.c
+++ b/src/partition/repart.c
@@ -1666,7 +1666,7 @@ static int context_dump_partitions(Context *context, const char *node) {
TABLE_UINT64, p->new_padding,
TABLE_STRING, padding_change, TABLE_SET_COLOR, !p->partitions_next && sum_padding > 0 ? ansi_underline() : NULL);
if (r < 0)
- return log_error_errno(r, "Failed to add row to table: %m");
+ return table_log_add_error(r);
}
if (sum_padding > 0 || sum_size > 0) {
@@ -1689,7 +1689,7 @@ static int context_dump_partitions(Context *context, const char *node) {
TABLE_EMPTY,
TABLE_STRING, b);
if (r < 0)
- return log_error_errno(r, "Failed to add row to table: %m");
+ return table_log_add_error(r);
}
r = table_print(t, stdout);
diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c
index 7a80240b97..63ede72473 100644
--- a/src/resolve/resolved-dns-packet.c
+++ b/src/resolve/resolved-dns-packet.c
@@ -839,7 +839,7 @@ int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, const DnsAns
rds = p->size - saved_size;
- switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
+ switch (rr->unparsable ? _DNS_TYPE_INVALID : rr->key->type) {
case DNS_TYPE_SRV:
r = dns_packet_append_uint16(p, rr->srv.priority, NULL);
@@ -1125,7 +1125,7 @@ int dns_packet_append_rr(DnsPacket *p, const DnsResourceRecord *rr, const DnsAns
case DNS_TYPE_OPT:
case DNS_TYPE_OPENPGPKEY:
- case _DNS_TYPE_INVALID: /* unparseable */
+ case _DNS_TYPE_INVALID: /* unparsable */
default:
r = dns_packet_append_blob(p, rr->generic.data, rr->generic.data_size, NULL);
@@ -1815,8 +1815,8 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_fl
break;
} else {
dns_packet_rewind(p, pos);
- rr->unparseable = true;
- goto unparseable;
+ rr->unparsable = true;
+ goto unparsable;
}
}
@@ -2059,7 +2059,7 @@ int dns_packet_read_rr(DnsPacket *p, DnsResourceRecord **ret, bool *ret_cache_fl
case DNS_TYPE_OPT: /* we only care about the header of OPT for now. */
case DNS_TYPE_OPENPGPKEY:
default:
- unparseable:
+ unparsable:
r = dns_packet_read_memdup(p, rdlength, &rr->generic.data, &rr->generic.data_size, NULL);
break;
diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c
index 6ba26a24b2..fa43dd089d 100644
--- a/src/resolve/resolved-dns-rr.c
+++ b/src/resolve/resolved-dns-rr.c
@@ -474,11 +474,11 @@ static DnsResourceRecord* dns_resource_record_free(DnsResourceRecord *rr) {
case DNS_TYPE_OPENPGPKEY:
default:
- if (!rr->unparseable)
+ if (!rr->unparsable)
free(rr->generic.data);
}
- if (rr->unparseable)
+ if (rr->unparsable)
free(rr->generic.data);
free(rr->wire_format);
@@ -563,10 +563,10 @@ int dns_resource_record_payload_equal(const DnsResourceRecord *a, const DnsResou
/* Check if a and b are the same, but don't look at their keys */
- if (a->unparseable != b->unparseable)
+ if (a->unparsable != b->unparsable)
return 0;
- switch (a->unparseable ? _DNS_TYPE_INVALID : a->key->type) {
+ switch (a->unparsable ? _DNS_TYPE_INVALID : a->key->type) {
case DNS_TYPE_SRV:
r = dns_name_equal(a->srv.name, b->srv.name);
@@ -828,7 +828,7 @@ const char *dns_resource_record_to_string(DnsResourceRecord *rr) {
dns_resource_key_to_string(rr->key, k, sizeof(k));
- switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
+ switch (rr->unparsable ? _DNS_TYPE_INVALID : rr->key->type) {
case DNS_TYPE_SRV:
r = asprintf(&s, "%s %u %u %u %s",
@@ -1175,7 +1175,7 @@ ssize_t dns_resource_record_payload(DnsResourceRecord *rr, void **out) {
assert(rr);
assert(out);
- switch(rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
+ switch(rr->unparsable ? _DNS_TYPE_INVALID : rr->key->type) {
case DNS_TYPE_SRV:
case DNS_TYPE_PTR:
case DNS_TYPE_NS:
@@ -1343,7 +1343,7 @@ void dns_resource_record_hash_func(const DnsResourceRecord *rr, struct siphash *
dns_resource_key_hash_func(rr->key, state);
- switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
+ switch (rr->unparsable ? _DNS_TYPE_INVALID : rr->key->type) {
case DNS_TYPE_SRV:
siphash24_compress(&rr->srv.priority, sizeof(rr->srv.priority), state);
@@ -1510,9 +1510,9 @@ DnsResourceRecord *dns_resource_record_copy(DnsResourceRecord *rr) {
copy->expiry = rr->expiry;
copy->n_skip_labels_signer = rr->n_skip_labels_signer;
copy->n_skip_labels_source = rr->n_skip_labels_source;
- copy->unparseable = rr->unparseable;
+ copy->unparsable = rr->unparsable;
- switch (rr->unparseable ? _DNS_TYPE_INVALID : rr->key->type) {
+ switch (rr->unparsable ? _DNS_TYPE_INVALID : rr->key->type) {
case DNS_TYPE_SRV:
copy->srv.priority = rr->srv.priority;
diff --git a/src/resolve/resolved-dns-rr.h b/src/resolve/resolved-dns-rr.h
index 291447f00e..6c824f7962 100644
--- a/src/resolve/resolved-dns-rr.h
+++ b/src/resolve/resolved-dns-rr.h
@@ -102,7 +102,7 @@ struct DnsResourceRecord {
/* How many labels to strip to determine "synthesizing source" of this RR, i.e. the wildcard's immediate parent. -1 if not signed. */
unsigned n_skip_labels_source;
- bool unparseable:1;
+ bool unparsable:1;
bool wire_format_canonical:1;
void *wire_format;
diff --git a/src/resolve/resolved-dns-stream.c b/src/resolve/resolved-dns-stream.c
index 1e2ff05c3e..d4c49e673e 100644
--- a/src/resolve/resolved-dns-stream.c
+++ b/src/resolve/resolved-dns-stream.c
@@ -190,7 +190,7 @@ static int dns_stream_identify(DnsStream *s) {
s->ifindex = manager_find_ifindex(s->manager, s->local.sa.sa_family, s->local.sa.sa_family == AF_INET ? (union in_addr_union*) &s->local.in.sin_addr : (union in_addr_union*) &s->local.in6.sin6_addr);
if (s->protocol == DNS_PROTOCOL_LLMNR && s->ifindex > 0) {
- uint32_t ifindex = htobe32(s->ifindex);
+ be32_t ifindex = htobe32(s->ifindex);
/* Make sure all packets for this connection are sent on the same interface */
if (s->local.sa.sa_family == AF_INET) {
diff --git a/src/resolve/resolved.c b/src/resolve/resolved.c
index 566b950a63..16477f28d6 100644
--- a/src/resolve/resolved.c
+++ b/src/resolve/resolved.c
@@ -22,8 +22,8 @@
#include "user-util.h"
static int run(int argc, char *argv[]) {
- _cleanup_(notify_on_cleanup) const char *notify_stop = NULL;
_cleanup_(manager_freep) Manager *m = NULL;
+ _cleanup_(notify_on_cleanup) const char *notify_stop = NULL;
int r;
log_setup_service();
diff --git a/src/shared/dropin.c b/src/shared/dropin.c
index 2693b63233..932da0c853 100644
--- a/src/shared/dropin.c
+++ b/src/shared/dropin.c
@@ -204,7 +204,7 @@ static int unit_file_find_dirs(
type = unit_name_to_type(name);
if (type < 0)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
- "Failed to to derive unit type from unit name: %s",
+ "Failed to derive unit type from unit name: %s",
name);
if (is_instance) {
@@ -254,7 +254,7 @@ int unit_file_find_dropin_paths(
type = unit_name_to_type(n);
if (type < 0)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
- "Failed to to derive unit type from unit name: %s", n);
+ "Failed to derive unit type from unit name: %s", n);
/* Special top level drop in for "<unit type>.<suffix>". Add this last as it's the most generic
* and should be able to be overridden by more specific drop-ins. */
diff --git a/src/shared/linux/nl80211.h b/src/shared/linux/nl80211.h
index beee59c831..b065c1fe4d 100644
--- a/src/shared/linux/nl80211.h
+++ b/src/shared/linux/nl80211.h
@@ -1435,7 +1435,7 @@ enum nl80211_commands {
* rates as defined by IEEE 802.11 7.3.2.2 but without the length
* restriction (at most %NL80211_MAX_SUPP_RATES).
* @NL80211_ATTR_STA_VLAN: interface index of VLAN interface to move station
- * to, or the AP interface the station was originally added to to.
+ * to, or the AP interface the station was originally added to.
* @NL80211_ATTR_STA_INFO: information about a station, part of station info
* given for %NL80211_CMD_GET_STATION, nested attribute containing
* info as possible, see &enum nl80211_sta_info.
diff --git a/src/shared/mount-util.c b/src/shared/mount-util.c
index 45fdd3b2da..b3fac13f7e 100644
--- a/src/shared/mount-util.c
+++ b/src/shared/mount-util.c
@@ -58,8 +58,8 @@ int umount_recursive(const char *prefix, int flags) {
if (!path_startswith(path, prefix))
continue;
- if (umount2(path, flags) < 0) {
- r = log_debug_errno(errno, "Failed to umount %s: %m", path);
+ if (umount2(path, flags | UMOUNT_NOFOLLOW) < 0) {
+ log_debug_errno(errno, "Failed to umount %s, ignoring: %m", path);
continue;
}
@@ -70,7 +70,6 @@ int umount_recursive(const char *prefix, int flags) {
break;
}
-
} while (again);
return n;
diff --git a/src/shared/mount-util.h b/src/shared/mount-util.h
index bcbd32c840..5934d71678 100644
--- a/src/shared/mount-util.h
+++ b/src/shared/mount-util.h
@@ -3,7 +3,9 @@
#include <mntent.h>
#include <stdio.h>
+#include <unistd.h>
+#include "errno-util.h"
#include "macro.h"
/* 4MB for contents of regular files, 64k inodes for directories, symbolic links and device specials,
@@ -53,3 +55,12 @@ int mount_option_mangle(
char **ret_remaining_options);
int mode_to_inaccessible_node(const char *runtime_dir, mode_t mode, char **dest);
+
+/* Useful for usage with _cleanup_(), unmounts, removes a directory and frees the pointer */
+static inline void umount_and_rmdir_and_free(char *p) {
+ PROTECT_ERRNO;
+ (void) umount_recursive(p, 0);
+ (void) rmdir(p);
+ free(p);
+}
+DEFINE_TRIVIAL_CLEANUP_FUNC(char*, umount_and_rmdir_and_free);
diff --git a/src/shared/pkcs11-util.c b/src/shared/pkcs11-util.c
index b4a7d86afe..632964df44 100644
--- a/src/shared/pkcs11-util.c
+++ b/src/shared/pkcs11-util.c
@@ -151,6 +151,28 @@ char *pkcs11_token_label(const CK_TOKEN_INFO *token_info) {
return t;
}
+char *pkcs11_token_manufacturer_id(const CK_TOKEN_INFO *token_info) {
+ char *t;
+
+ t = strndup((char*) token_info->manufacturerID, sizeof(token_info->manufacturerID));
+ if (!t)
+ return NULL;
+
+ strstrip(t);
+ return t;
+}
+
+char *pkcs11_token_model(const CK_TOKEN_INFO *token_info) {
+ char *t;
+
+ t = strndup((char*) token_info->model, sizeof(token_info->model));
+ if (!t)
+ return NULL;
+
+ strstrip(t);
+ return t;
+}
+
int pkcs11_token_login(
CK_FUNCTION_LIST *m,
CK_SESSION_HANDLE session,
@@ -165,9 +187,8 @@ int pkcs11_token_login(
_cleanup_free_ char *token_uri_string = NULL, *token_uri_escaped = NULL, *id = NULL, *token_label = NULL;
_cleanup_(p11_kit_uri_freep) P11KitUri *token_uri = NULL;
CK_TOKEN_INFO updated_token_info;
- int uri_result;
+ int uri_result, r;
CK_RV rv;
- int r;
assert(m);
assert(token_info);
@@ -211,28 +232,8 @@ int pkcs11_token_login(
for (unsigned tries = 0; tries < 3; tries++) {
_cleanup_strv_free_erase_ char **passwords = NULL;
- _cleanup_free_ char *text = NULL;
char **i, *e;
- if (FLAGS_SET(token_info->flags, CKF_USER_PIN_FINAL_TRY))
- r = asprintf(&text,
- "Please enter correct PIN for security token '%s' in order to unlock %s (final try):",
- token_label, friendly_name);
- else if (FLAGS_SET(token_info->flags, CKF_USER_PIN_COUNT_LOW))
- r = asprintf(&text,
- "PIN has been entered incorrectly previously, please enter correct PIN for security token '%s' in order to unlock %s:",
- token_label, friendly_name);
- else if (tries == 0)
- r = asprintf(&text,
- "Please enter PIN for security token '%s' in order to unlock %s:",
- token_label, friendly_name);
- else
- r = asprintf(&text,
- "Please enter PIN for security token '%s' in order to unlock %s (try #%u):",
- token_label, friendly_name, tries+1);
- if (r < 0)
- return log_oom();
-
e = getenv("PIN");
if (e) {
passwords = strv_new(e);
@@ -243,6 +244,27 @@ int pkcs11_token_login(
if (unsetenv("PIN") < 0)
return log_error_errno(errno, "Failed to unset $PIN: %m");
} else {
+ _cleanup_free_ char *text = NULL;
+
+ if (FLAGS_SET(token_info->flags, CKF_USER_PIN_FINAL_TRY))
+ r = asprintf(&text,
+ "Please enter correct PIN for security token '%s' in order to unlock %s (final try):",
+ token_label, friendly_name);
+ else if (FLAGS_SET(token_info->flags, CKF_USER_PIN_COUNT_LOW))
+ r = asprintf(&text,
+ "PIN has been entered incorrectly previously, please enter correct PIN for security token '%s' in order to unlock %s:",
+ token_label, friendly_name);
+ else if (tries == 0)
+ r = asprintf(&text,
+ "Please enter PIN for security token '%s' in order to unlock %s:",
+ token_label, friendly_name);
+ else
+ r = asprintf(&text,
+ "Please enter PIN for security token '%s' in order to unlock %s (try #%u):",
+ token_label, friendly_name, tries+1);
+ if (r < 0)
+ return log_oom();
+
/* We never cache PINs, simply because it's fatal if we use wrong PINs, since usually there are only 3 tries */
r = ask_password_auto(text, icon_name, id, keyname, until, 0, &passwords);
if (r < 0)
@@ -702,7 +724,6 @@ static int token_process(
assert(m);
assert(slot_info);
assert(token_info);
- assert(search_uri);
token_label = pkcs11_token_label(token_info);
if (!token_label)
@@ -740,7 +761,6 @@ static int slot_process(
CK_RV rv;
assert(m);
- assert(search_uri);
/* We return -EAGAIN for all failures we can attribute to a specific slot in some way, so that the
* caller might try other slots before giving up. */
@@ -786,7 +806,7 @@ static int slot_process(
return -EAGAIN;
}
- if (!p11_kit_uri_match_token_info(search_uri, &token_info)) {
+ if (search_uri && !p11_kit_uri_match_token_info(search_uri, &token_info)) {
log_debug("Found non-matching token with URI %s.", token_uri_string);
return -EAGAIN;
}
@@ -820,7 +840,6 @@ static int module_process(
int r;
assert(m);
- assert(search_uri);
/* We ignore most errors from modules here, in order to skip over faulty modules: one faulty module
* should not have the effect that we don't try the others anymore. We indicate such per-module
@@ -883,14 +902,14 @@ int pkcs11_find_token(
_cleanup_(p11_kit_uri_freep) P11KitUri *search_uri = NULL;
int r;
- assert(pkcs11_uri);
-
/* Execute the specified callback for each matching token found. If nothing is found returns
* -EAGAIN. Logs about all errors, except for EAGAIN, which the caller has to log about. */
- r = uri_from_string(pkcs11_uri, &search_uri);
- if (r < 0)
- return log_error_errno(r, "Failed to parse PKCS#11 URI '%s': %m", pkcs11_uri);
+ if (pkcs11_uri) {
+ r = uri_from_string(pkcs11_uri, &search_uri);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse PKCS#11 URI '%s': %m", pkcs11_uri);
+ }
modules = p11_kit_modules_load_and_initialize(0);
if (!modules)
diff --git a/src/shared/pkcs11-util.h b/src/shared/pkcs11-util.h
index 46791eb23b..959e7c3e0d 100644
--- a/src/shared/pkcs11-util.h
+++ b/src/shared/pkcs11-util.h
@@ -27,6 +27,8 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(CK_FUNCTION_LIST**, p11_kit_modules_finalize_and_rel
CK_RV pkcs11_get_slot_list_malloc(CK_FUNCTION_LIST *m, CK_SLOT_ID **ret_slotids, CK_ULONG *ret_n_slotids);
char *pkcs11_token_label(const CK_TOKEN_INFO *token_info);
+char *pkcs11_token_manufacturer_id(const CK_TOKEN_INFO *token_info);
+char *pkcs11_token_model(const CK_TOKEN_INFO *token_info);
int pkcs11_token_login(CK_FUNCTION_LIST *m, CK_SESSION_HANDLE session, CK_SLOT_ID slotid, const CK_TOKEN_INFO *token_info, const char *friendly_name, const char *icon_name, const char *keyname, usec_t until, char **ret_used_pin);
diff --git a/src/shared/tests.c b/src/shared/tests.c
index ecf8e8f623..ff662ecfe0 100644
--- a/src/shared/tests.c
+++ b/src/shared/tests.c
@@ -21,6 +21,7 @@
#include "env-util.h"
#include "fs-util.h"
#include "log.h"
+#include "namespace-util.h"
#include "path-util.h"
#include "random-util.h"
#include "strv.h"
@@ -137,10 +138,7 @@ bool have_namespaces(void) {
if (pid == 0) {
/* child */
- if (unshare(CLONE_NEWNS) < 0)
- _exit(EXIT_FAILURE);
-
- if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL) < 0)
+ if (detach_mount_namespace() < 0)
_exit(EXIT_FAILURE);
_exit(EXIT_SUCCESS);
diff --git a/src/shared/user-record-show.c b/src/shared/user-record-show.c
index de04859a2f..84ededd86e 100644
--- a/src/shared/user-record-show.c
+++ b/src/shared/user-record-show.c
@@ -472,10 +472,13 @@ void user_record_show(UserRecord *hr, bool show_full_group_info) {
STRV_FOREACH(i, hr->pkcs11_token_uri)
printf(i == hr->pkcs11_token_uri ?
- " Sec. Token: %s\n" :
+ "PKCS11 Token: %s\n" :
" %s\n", *i);
}
+ if (hr->n_fido2_hmac_credential > 0)
+ printf(" FIDO2 Token: %zu\n", hr->n_fido2_hmac_credential);
+
k = strv_length(hr->hashed_password);
if (k == 0)
printf(" Passwords: %snone%s\n",
diff --git a/src/shared/user-record.c b/src/shared/user-record.c
index 83d86f69e7..16edaa45fa 100644
--- a/src/shared/user-record.c
+++ b/src/shared/user-record.c
@@ -81,6 +81,7 @@ UserRecord* user_record_new(void) {
.password_change_inactive_usec = UINT64_MAX,
.password_change_now = -1,
.pkcs11_protected_authentication_path_permitted = -1,
+ .fido2_user_presence_permitted = -1,
};
return h;
@@ -95,6 +96,22 @@ static void pkcs11_encrypted_key_done(Pkcs11EncryptedKey *k) {
erase_and_free(k->hashed_password);
}
+static void fido2_hmac_credential_done(Fido2HmacCredential *c) {
+ if (!c)
+ return;
+
+ free(c->id);
+}
+
+static void fido2_hmac_salt_done(Fido2HmacSalt *s) {
+ if (!s)
+ return;
+
+ fido2_hmac_credential_done(&s->credential);
+ erase_and_free(s->salt);
+ erase_and_free(s->hashed_password);
+}
+
static UserRecord* user_record_free(UserRecord *h) {
if (!h)
return NULL;
@@ -120,7 +137,7 @@ static UserRecord* user_record_free(UserRecord *h) {
strv_free_erase(h->hashed_password);
strv_free_erase(h->ssh_authorized_keys);
strv_free_erase(h->password);
- strv_free_erase(h->pkcs11_pin);
+ strv_free_erase(h->token_pin);
free(h->cifs_service);
free(h->cifs_user_name);
@@ -147,6 +164,11 @@ static UserRecord* user_record_free(UserRecord *h) {
pkcs11_encrypted_key_done(h->pkcs11_encrypted_key + i);
free(h->pkcs11_encrypted_key);
+ for (size_t i = 0; i < h->n_fido2_hmac_credential; i++)
+ fido2_hmac_credential_done(h->fido2_hmac_credential + i);
+ for (size_t i = 0; i < h->n_fido2_hmac_salt; i++)
+ fido2_hmac_salt_done(h->fido2_hmac_salt + i);
+
json_variant_unref(h->json);
return mfree(h);
@@ -620,8 +642,10 @@ static int dispatch_secret(const char *name, JsonVariant *variant, JsonDispatchF
static const JsonDispatch secret_dispatch_table[] = {
{ "password", _JSON_VARIANT_TYPE_INVALID, json_dispatch_strv, offsetof(UserRecord, password), 0 },
- { "pkcs11Pin", _JSON_VARIANT_TYPE_INVALID, json_dispatch_strv, offsetof(UserRecord, pkcs11_pin), 0 },
+ { "tokenPin", _JSON_VARIANT_TYPE_INVALID, json_dispatch_strv, offsetof(UserRecord, token_pin), 0 },
+ { "pkcs11Pin", /* legacy alias */ _JSON_VARIANT_TYPE_INVALID, json_dispatch_strv, offsetof(UserRecord, token_pin), 0 },
{ "pkcs11ProtectedAuthenticationPathPermitted", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(UserRecord, pkcs11_protected_authentication_path_permitted), 0 },
+ { "fido2UserPresencePermitted", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(UserRecord, fido2_user_presence_permitted), 0 },
{},
};
@@ -706,7 +730,7 @@ static int dispatch_pkcs11_key_data(const char *name, JsonVariant *variant, Json
int r;
if (json_variant_is_null(variant)) {
- k->data = mfree(k->data);
+ k->data = erase_and_free(k->data);
k->size = 0;
return 0;
}
@@ -766,13 +790,141 @@ static int dispatch_pkcs11_key(const char *name, JsonVariant *variant, JsonDispa
return 0;
}
+static int dispatch_fido2_hmac_credential(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
+ Fido2HmacCredential *k = userdata;
+ size_t l;
+ void *b;
+ int r;
+
+ if (json_variant_is_null(variant)) {
+ k->id = mfree(k->id);
+ k->size = 0;
+ return 0;
+ }
+
+ if (!json_variant_is_string(variant))
+ return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a string.", strna(name));
+
+ r = unbase64mem(json_variant_string(variant), (size_t) -1, &b, &l);
+ if (r < 0)
+ return json_log(variant, flags, r, "Failed to decode FIDO2 credential ID: %m");
+
+ free_and_replace(k->id, b);
+ k->size = l;
+
+ return 0;
+}
+
+static int dispatch_fido2_hmac_credential_array(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
+ UserRecord *h = userdata;
+ JsonVariant *e;
+ int r;
+
+ if (!json_variant_is_array(variant))
+ return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not an array of strings.", strna(name));
+
+ JSON_VARIANT_ARRAY_FOREACH(e, variant) {
+ Fido2HmacCredential *array;
+ size_t l;
+ void *b;
+
+ if (!json_variant_is_string(e))
+ return json_log(e, flags, SYNTHETIC_ERRNO(EINVAL), "JSON array element is not a string.");
+
+ array = reallocarray(h->fido2_hmac_credential, h->n_fido2_hmac_credential + 1, sizeof(Fido2HmacCredential));
+ if (!array)
+ return log_oom();
+
+ r = unbase64mem(json_variant_string(e), (size_t) -1, &b, &l);
+ if (r < 0)
+ return json_log(variant, flags, r, "Failed to decode FIDO2 credential ID: %m");
+
+ h->fido2_hmac_credential = array;
+
+ h->fido2_hmac_credential[h->n_fido2_hmac_credential++] = (Fido2HmacCredential) {
+ .id = b,
+ .size = l,
+ };
+ }
+
+ return 0;
+}
+
+static int dispatch_fido2_hmac_salt_value(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
+ Fido2HmacSalt *k = userdata;
+ size_t l;
+ void *b;
+ int r;
+
+ if (json_variant_is_null(variant)) {
+ k->salt = erase_and_free(k->salt);
+ k->salt_size = 0;
+ return 0;
+ }
+
+ if (!json_variant_is_string(variant))
+ return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a string.", strna(name));
+
+ r = unbase64mem(json_variant_string(variant), (size_t) -1, &b, &l);
+ if (r < 0)
+ return json_log(variant, flags, r, "Failed to decode FIDO2 salt: %m");
+
+ erase_and_free(k->salt);
+ k->salt = b;
+ k->salt_size = l;
+
+ return 0;
+}
+
+static int dispatch_fido2_hmac_salt(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
+ UserRecord *h = userdata;
+ JsonVariant *e;
+ int r;
+
+ if (!json_variant_is_array(variant))
+ return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not an array of objects.", strna(name));
+
+ JSON_VARIANT_ARRAY_FOREACH(e, variant) {
+ Fido2HmacSalt *array, *k;
+
+ static const JsonDispatch fido2_hmac_salt_dispatch_table[] = {
+ { "credential", JSON_VARIANT_STRING, dispatch_fido2_hmac_credential, offsetof(Fido2HmacSalt, credential), JSON_MANDATORY },
+ { "salt", JSON_VARIANT_STRING, dispatch_fido2_hmac_salt_value, 0, JSON_MANDATORY },
+ { "hashedPassword", JSON_VARIANT_STRING, json_dispatch_string, offsetof(Fido2HmacSalt, hashed_password), JSON_MANDATORY },
+ {},
+ };
+
+ if (!json_variant_is_object(e))
+ return json_log(e, flags, SYNTHETIC_ERRNO(EINVAL), "JSON array element is not an object.");
+
+ array = reallocarray(h->fido2_hmac_salt, h->n_fido2_hmac_salt + 1, sizeof(Fido2HmacSalt));
+ if (!array)
+ return log_oom();
+
+ h->fido2_hmac_salt = array;
+ k = h->fido2_hmac_salt + h->n_fido2_hmac_salt;
+ *k = (Fido2HmacSalt) {};
+
+ r = json_dispatch(e, fido2_hmac_salt_dispatch_table, NULL, flags, k);
+ if (r < 0) {
+ fido2_hmac_salt_done(k);
+ return r;
+ }
+
+ h->n_fido2_hmac_salt++;
+ }
+
+ return 0;
+}
+
static int dispatch_privileged(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
static const JsonDispatch privileged_dispatch_table[] = {
- { "passwordHint", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, password_hint), 0 },
- { "hashedPassword", _JSON_VARIANT_TYPE_INVALID, json_dispatch_strv, offsetof(UserRecord, hashed_password), JSON_SAFE },
- { "sshAuthorizedKeys", _JSON_VARIANT_TYPE_INVALID, json_dispatch_strv, offsetof(UserRecord, ssh_authorized_keys), 0 },
- { "pkcs11EncryptedKey", JSON_VARIANT_ARRAY, dispatch_pkcs11_key, 0, 0 },
+ { "passwordHint", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, password_hint), 0 },
+ { "hashedPassword", _JSON_VARIANT_TYPE_INVALID, json_dispatch_strv, offsetof(UserRecord, hashed_password), JSON_SAFE },
+ { "sshAuthorizedKeys", _JSON_VARIANT_TYPE_INVALID, json_dispatch_strv, offsetof(UserRecord, ssh_authorized_keys), 0 },
+ { "pkcs11EncryptedKey", JSON_VARIANT_ARRAY, dispatch_pkcs11_key, 0, 0 },
+ { "fido2HmacSalt", JSON_VARIANT_ARRAY, dispatch_fido2_hmac_salt, 0, 0 },
{},
};
@@ -906,66 +1058,67 @@ int per_machine_hostname_match(JsonVariant *hns, JsonDispatchFlags flags) {
static int dispatch_per_machine(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
static const JsonDispatch per_machine_dispatch_table[] = {
- { "matchMachineId", _JSON_VARIANT_TYPE_INVALID, NULL, 0, 0 },
- { "matchHostname", _JSON_VARIANT_TYPE_INVALID, NULL, 0, 0 },
- { "iconName", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, icon_name), JSON_SAFE },
- { "location", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, location), 0 },
- { "shell", JSON_VARIANT_STRING, json_dispatch_filename_or_path, offsetof(UserRecord, shell), 0 },
- { "umask", JSON_VARIANT_UNSIGNED, json_dispatch_umask, offsetof(UserRecord, umask), 0 },
- { "environment", JSON_VARIANT_ARRAY, json_dispatch_environment, offsetof(UserRecord, environment), 0 },
- { "timeZone", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, time_zone), JSON_SAFE },
- { "preferredLanguage", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, preferred_language), JSON_SAFE },
- { "niceLevel", _JSON_VARIANT_TYPE_INVALID, json_dispatch_nice, offsetof(UserRecord, nice_level), 0 },
- { "resourceLimits", _JSON_VARIANT_TYPE_INVALID, json_dispatch_rlimits, offsetof(UserRecord, rlimits), 0 },
- { "locked", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(UserRecord, locked), 0 },
- { "notBeforeUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, not_before_usec), 0 },
- { "notAfterUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, not_after_usec), 0 },
- { "storage", JSON_VARIANT_STRING, json_dispatch_storage, offsetof(UserRecord, storage), 0 },
- { "diskSize", JSON_VARIANT_UNSIGNED, json_dispatch_disk_size, offsetof(UserRecord, disk_size), 0 },
- { "diskSizeRelative", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, disk_size_relative), 0 },
- { "skeletonDirectory", JSON_VARIANT_STRING, json_dispatch_path, offsetof(UserRecord, skeleton_directory), 0 },
- { "accessMode", JSON_VARIANT_UNSIGNED, json_dispatch_access_mode, offsetof(UserRecord, access_mode), 0 },
- { "tasksMax", JSON_VARIANT_UNSIGNED, json_dispatch_tasks_or_memory_max, offsetof(UserRecord, tasks_max), 0 },
- { "memoryHigh", JSON_VARIANT_UNSIGNED, json_dispatch_tasks_or_memory_max, offsetof(UserRecord, memory_high), 0 },
- { "memoryMax", JSON_VARIANT_UNSIGNED, json_dispatch_tasks_or_memory_max, offsetof(UserRecord, memory_max), 0 },
- { "cpuWeight", JSON_VARIANT_UNSIGNED, json_dispatch_weight, offsetof(UserRecord, cpu_weight), 0 },
- { "ioWeight", JSON_VARIANT_UNSIGNED, json_dispatch_weight, offsetof(UserRecord, io_weight), 0 },
- { "mountNoDevices", JSON_VARIANT_BOOLEAN, json_dispatch_boolean, offsetof(UserRecord, nodev), 0 },
- { "mountNoSuid", JSON_VARIANT_BOOLEAN, json_dispatch_boolean, offsetof(UserRecord, nosuid), 0 },
- { "mountNoExecute", JSON_VARIANT_BOOLEAN, json_dispatch_boolean, offsetof(UserRecord, noexec), 0 },
- { "cifsDomain", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, cifs_domain), JSON_SAFE },
- { "cifsUserName", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, cifs_user_name), JSON_SAFE },
- { "cifsService", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, cifs_service), JSON_SAFE },
- { "imagePath", JSON_VARIANT_STRING, json_dispatch_path, offsetof(UserRecord, image_path), 0 },
- { "uid", JSON_VARIANT_UNSIGNED, json_dispatch_uid_gid, offsetof(UserRecord, uid), 0 },
- { "gid", JSON_VARIANT_UNSIGNED, json_dispatch_uid_gid, offsetof(UserRecord, gid), 0 },
- { "memberOf", JSON_VARIANT_ARRAY, json_dispatch_user_group_list, offsetof(UserRecord, member_of), JSON_RELAX},
- { "fileSystemType", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, file_system_type), JSON_SAFE },
- { "partitionUuid", JSON_VARIANT_STRING, json_dispatch_id128, offsetof(UserRecord, partition_uuid), 0 },
- { "luksUuid", JSON_VARIANT_STRING, json_dispatch_id128, offsetof(UserRecord, luks_uuid), 0 },
- { "fileSystemUuid", JSON_VARIANT_STRING, json_dispatch_id128, offsetof(UserRecord, file_system_uuid), 0 },
- { "luksDiscard", _JSON_VARIANT_TYPE_INVALID, json_dispatch_tristate, offsetof(UserRecord, luks_discard), 0, },
- { "luksOfflineDiscard", _JSON_VARIANT_TYPE_INVALID, json_dispatch_tristate, offsetof(UserRecord, luks_offline_discard), 0, },
- { "luksCipher", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, luks_cipher), JSON_SAFE },
- { "luksCipherMode", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, luks_cipher_mode), JSON_SAFE },
- { "luksVolumeKeySize", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_volume_key_size), 0 },
- { "luksPbkdfHashAlgorithm", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, luks_pbkdf_hash_algorithm), JSON_SAFE },
- { "luksPbkdfType", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, luks_pbkdf_type), JSON_SAFE },
- { "luksPbkdfTimeCostUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_pbkdf_time_cost_usec), 0 },
- { "luksPbkdfMemoryCost", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_pbkdf_memory_cost), 0 },
- { "luksPbkdfParallelThreads", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_pbkdf_parallel_threads), 0 },
- { "rateLimitIntervalUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, ratelimit_interval_usec), 0 },
- { "rateLimitBurst", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, ratelimit_burst), 0 },
- { "enforcePasswordPolicy", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(UserRecord, enforce_password_policy), 0 },
- { "autoLogin", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(UserRecord, auto_login), 0 },
- { "stopDelayUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, stop_delay_usec), 0 },
- { "killProcesses", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(UserRecord, kill_processes), 0 },
- { "passwordChangeMinUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, password_change_min_usec), 0 },
- { "passwordChangeMaxUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, password_change_max_usec), 0 },
- { "passwordChangeWarnUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, password_change_warn_usec), 0 },
- { "passwordChangeInactiveUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, password_change_inactive_usec), 0 },
- { "passwordChangeNow", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(UserRecord, password_change_now), 0 },
- { "pkcs11TokenUri", JSON_VARIANT_ARRAY, dispatch_pkcs11_uri_array, offsetof(UserRecord, pkcs11_token_uri), 0 },
+ { "matchMachineId", _JSON_VARIANT_TYPE_INVALID, NULL, 0, 0 },
+ { "matchHostname", _JSON_VARIANT_TYPE_INVALID, NULL, 0, 0 },
+ { "iconName", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, icon_name), JSON_SAFE },
+ { "location", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, location), 0 },
+ { "shell", JSON_VARIANT_STRING, json_dispatch_filename_or_path, offsetof(UserRecord, shell), 0 },
+ { "umask", JSON_VARIANT_UNSIGNED, json_dispatch_umask, offsetof(UserRecord, umask), 0 },
+ { "environment", JSON_VARIANT_ARRAY, json_dispatch_environment, offsetof(UserRecord, environment), 0 },
+ { "timeZone", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, time_zone), JSON_SAFE },
+ { "preferredLanguage", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, preferred_language), JSON_SAFE },
+ { "niceLevel", _JSON_VARIANT_TYPE_INVALID, json_dispatch_nice, offsetof(UserRecord, nice_level), 0 },
+ { "resourceLimits", _JSON_VARIANT_TYPE_INVALID, json_dispatch_rlimits, offsetof(UserRecord, rlimits), 0 },
+ { "locked", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(UserRecord, locked), 0 },
+ { "notBeforeUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, not_before_usec), 0 },
+ { "notAfterUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, not_after_usec), 0 },
+ { "storage", JSON_VARIANT_STRING, json_dispatch_storage, offsetof(UserRecord, storage), 0 },
+ { "diskSize", JSON_VARIANT_UNSIGNED, json_dispatch_disk_size, offsetof(UserRecord, disk_size), 0 },
+ { "diskSizeRelative", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, disk_size_relative), 0 },
+ { "skeletonDirectory", JSON_VARIANT_STRING, json_dispatch_path, offsetof(UserRecord, skeleton_directory), 0 },
+ { "accessMode", JSON_VARIANT_UNSIGNED, json_dispatch_access_mode, offsetof(UserRecord, access_mode), 0 },
+ { "tasksMax", JSON_VARIANT_UNSIGNED, json_dispatch_tasks_or_memory_max, offsetof(UserRecord, tasks_max), 0 },
+ { "memoryHigh", JSON_VARIANT_UNSIGNED, json_dispatch_tasks_or_memory_max, offsetof(UserRecord, memory_high), 0 },
+ { "memoryMax", JSON_VARIANT_UNSIGNED, json_dispatch_tasks_or_memory_max, offsetof(UserRecord, memory_max), 0 },
+ { "cpuWeight", JSON_VARIANT_UNSIGNED, json_dispatch_weight, offsetof(UserRecord, cpu_weight), 0 },
+ { "ioWeight", JSON_VARIANT_UNSIGNED, json_dispatch_weight, offsetof(UserRecord, io_weight), 0 },
+ { "mountNoDevices", JSON_VARIANT_BOOLEAN, json_dispatch_boolean, offsetof(UserRecord, nodev), 0 },
+ { "mountNoSuid", JSON_VARIANT_BOOLEAN, json_dispatch_boolean, offsetof(UserRecord, nosuid), 0 },
+ { "mountNoExecute", JSON_VARIANT_BOOLEAN, json_dispatch_boolean, offsetof(UserRecord, noexec), 0 },
+ { "cifsDomain", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, cifs_domain), JSON_SAFE },
+ { "cifsUserName", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, cifs_user_name), JSON_SAFE },
+ { "cifsService", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, cifs_service), JSON_SAFE },
+ { "imagePath", JSON_VARIANT_STRING, json_dispatch_path, offsetof(UserRecord, image_path), 0 },
+ { "uid", JSON_VARIANT_UNSIGNED, json_dispatch_uid_gid, offsetof(UserRecord, uid), 0 },
+ { "gid", JSON_VARIANT_UNSIGNED, json_dispatch_uid_gid, offsetof(UserRecord, gid), 0 },
+ { "memberOf", JSON_VARIANT_ARRAY, json_dispatch_user_group_list, offsetof(UserRecord, member_of), JSON_RELAX},
+ { "fileSystemType", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, file_system_type), JSON_SAFE },
+ { "partitionUuid", JSON_VARIANT_STRING, json_dispatch_id128, offsetof(UserRecord, partition_uuid), 0 },
+ { "luksUuid", JSON_VARIANT_STRING, json_dispatch_id128, offsetof(UserRecord, luks_uuid), 0 },
+ { "fileSystemUuid", JSON_VARIANT_STRING, json_dispatch_id128, offsetof(UserRecord, file_system_uuid), 0 },
+ { "luksDiscard", _JSON_VARIANT_TYPE_INVALID, json_dispatch_tristate, offsetof(UserRecord, luks_discard), 0, },
+ { "luksOfflineDiscard", _JSON_VARIANT_TYPE_INVALID, json_dispatch_tristate, offsetof(UserRecord, luks_offline_discard), 0, },
+ { "luksCipher", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, luks_cipher), JSON_SAFE },
+ { "luksCipherMode", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, luks_cipher_mode), JSON_SAFE },
+ { "luksVolumeKeySize", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_volume_key_size), 0 },
+ { "luksPbkdfHashAlgorithm", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, luks_pbkdf_hash_algorithm), JSON_SAFE },
+ { "luksPbkdfType", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, luks_pbkdf_type), JSON_SAFE },
+ { "luksPbkdfTimeCostUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_pbkdf_time_cost_usec), 0 },
+ { "luksPbkdfMemoryCost", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_pbkdf_memory_cost), 0 },
+ { "luksPbkdfParallelThreads", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_pbkdf_parallel_threads), 0 },
+ { "rateLimitIntervalUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, ratelimit_interval_usec), 0 },
+ { "rateLimitBurst", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, ratelimit_burst), 0 },
+ { "enforcePasswordPolicy", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(UserRecord, enforce_password_policy), 0 },
+ { "autoLogin", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(UserRecord, auto_login), 0 },
+ { "stopDelayUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, stop_delay_usec), 0 },
+ { "killProcesses", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(UserRecord, kill_processes), 0 },
+ { "passwordChangeMinUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, password_change_min_usec), 0 },
+ { "passwordChangeMaxUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, password_change_max_usec), 0 },
+ { "passwordChangeWarnUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, password_change_warn_usec), 0 },
+ { "passwordChangeInactiveUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, password_change_inactive_usec), 0 },
+ { "passwordChangeNow", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(UserRecord, password_change_now), 0 },
+ { "pkcs11TokenUri", JSON_VARIANT_ARRAY, dispatch_pkcs11_uri_array, offsetof(UserRecord, pkcs11_token_uri), 0 },
+ { "fido2HmacCredential", JSON_VARIANT_ARRAY, dispatch_fido2_hmac_credential_array, 0, 0 },
{},
};
@@ -1247,84 +1400,85 @@ int user_group_record_mangle(
int user_record_load(UserRecord *h, JsonVariant *v, UserRecordLoadFlags load_flags) {
static const JsonDispatch user_dispatch_table[] = {
- { "userName", JSON_VARIANT_STRING, json_dispatch_user_group_name, offsetof(UserRecord, user_name), JSON_RELAX},
- { "realm", JSON_VARIANT_STRING, json_dispatch_realm, offsetof(UserRecord, realm), 0 },
- { "realName", JSON_VARIANT_STRING, json_dispatch_gecos, offsetof(UserRecord, real_name), 0 },
- { "emailAddress", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, email_address), JSON_SAFE },
- { "iconName", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, icon_name), JSON_SAFE },
- { "location", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, location), 0 },
- { "disposition", JSON_VARIANT_STRING, json_dispatch_user_disposition, offsetof(UserRecord, disposition), 0 },
- { "lastChangeUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, last_change_usec), 0 },
- { "lastPasswordChangeUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, last_password_change_usec), 0 },
- { "shell", JSON_VARIANT_STRING, json_dispatch_filename_or_path, offsetof(UserRecord, shell), 0 },
- { "umask", JSON_VARIANT_UNSIGNED, json_dispatch_umask, offsetof(UserRecord, umask), 0 },
- { "environment", JSON_VARIANT_ARRAY, json_dispatch_environment, offsetof(UserRecord, environment), 0 },
- { "timeZone", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, time_zone), JSON_SAFE },
- { "preferredLanguage", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, preferred_language), JSON_SAFE },
- { "niceLevel", _JSON_VARIANT_TYPE_INVALID, json_dispatch_nice, offsetof(UserRecord, nice_level), 0 },
- { "resourceLimits", _JSON_VARIANT_TYPE_INVALID, json_dispatch_rlimits, offsetof(UserRecord, rlimits), 0 },
- { "locked", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(UserRecord, locked), 0 },
- { "notBeforeUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, not_before_usec), 0 },
- { "notAfterUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, not_after_usec), 0 },
- { "storage", JSON_VARIANT_STRING, json_dispatch_storage, offsetof(UserRecord, storage), 0 },
- { "diskSize", JSON_VARIANT_UNSIGNED, json_dispatch_disk_size, offsetof(UserRecord, disk_size), 0 },
- { "diskSizeRelative", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, disk_size_relative), 0 },
- { "skeletonDirectory", JSON_VARIANT_STRING, json_dispatch_path, offsetof(UserRecord, skeleton_directory), 0 },
- { "accessMode", JSON_VARIANT_UNSIGNED, json_dispatch_access_mode, offsetof(UserRecord, access_mode), 0 },
- { "tasksMax", JSON_VARIANT_UNSIGNED, json_dispatch_tasks_or_memory_max, offsetof(UserRecord, tasks_max), 0 },
- { "memoryHigh", JSON_VARIANT_UNSIGNED, json_dispatch_tasks_or_memory_max, offsetof(UserRecord, memory_high), 0 },
- { "memoryMax", JSON_VARIANT_UNSIGNED, json_dispatch_tasks_or_memory_max, offsetof(UserRecord, memory_max), 0 },
- { "cpuWeight", JSON_VARIANT_UNSIGNED, json_dispatch_weight, offsetof(UserRecord, cpu_weight), 0 },
- { "ioWeight", JSON_VARIANT_UNSIGNED, json_dispatch_weight, offsetof(UserRecord, io_weight), 0 },
- { "mountNoDevices", JSON_VARIANT_BOOLEAN, json_dispatch_boolean, offsetof(UserRecord, nodev), 0 },
- { "mountNoSuid", JSON_VARIANT_BOOLEAN, json_dispatch_boolean, offsetof(UserRecord, nosuid), 0 },
- { "mountNoExecute", JSON_VARIANT_BOOLEAN, json_dispatch_boolean, offsetof(UserRecord, noexec), 0 },
- { "cifsDomain", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, cifs_domain), JSON_SAFE },
- { "cifsUserName", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, cifs_user_name), JSON_SAFE },
- { "cifsService", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, cifs_service), JSON_SAFE },
- { "imagePath", JSON_VARIANT_STRING, json_dispatch_path, offsetof(UserRecord, image_path), 0 },
- { "homeDirectory", JSON_VARIANT_STRING, json_dispatch_home_directory, offsetof(UserRecord, home_directory), 0 },
- { "uid", JSON_VARIANT_UNSIGNED, json_dispatch_uid_gid, offsetof(UserRecord, uid), 0 },
- { "gid", JSON_VARIANT_UNSIGNED, json_dispatch_uid_gid, offsetof(UserRecord, gid), 0 },
- { "memberOf", JSON_VARIANT_ARRAY, json_dispatch_user_group_list, offsetof(UserRecord, member_of), JSON_RELAX},
- { "fileSystemType", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, file_system_type), JSON_SAFE },
- { "partitionUuid", JSON_VARIANT_STRING, json_dispatch_id128, offsetof(UserRecord, partition_uuid), 0 },
- { "luksUuid", JSON_VARIANT_STRING, json_dispatch_id128, offsetof(UserRecord, luks_uuid), 0 },
- { "fileSystemUuid", JSON_VARIANT_STRING, json_dispatch_id128, offsetof(UserRecord, file_system_uuid), 0 },
- { "luksDiscard", _JSON_VARIANT_TYPE_INVALID, json_dispatch_tristate, offsetof(UserRecord, luks_discard), 0 },
+ { "userName", JSON_VARIANT_STRING, json_dispatch_user_group_name, offsetof(UserRecord, user_name), JSON_RELAX},
+ { "realm", JSON_VARIANT_STRING, json_dispatch_realm, offsetof(UserRecord, realm), 0 },
+ { "realName", JSON_VARIANT_STRING, json_dispatch_gecos, offsetof(UserRecord, real_name), 0 },
+ { "emailAddress", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, email_address), JSON_SAFE },
+ { "iconName", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, icon_name), JSON_SAFE },
+ { "location", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, location), 0 },
+ { "disposition", JSON_VARIANT_STRING, json_dispatch_user_disposition, offsetof(UserRecord, disposition), 0 },
+ { "lastChangeUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, last_change_usec), 0 },
+ { "lastPasswordChangeUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, last_password_change_usec), 0 },
+ { "shell", JSON_VARIANT_STRING, json_dispatch_filename_or_path, offsetof(UserRecord, shell), 0 },
+ { "umask", JSON_VARIANT_UNSIGNED, json_dispatch_umask, offsetof(UserRecord, umask), 0 },
+ { "environment", JSON_VARIANT_ARRAY, json_dispatch_environment, offsetof(UserRecord, environment), 0 },
+ { "timeZone", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, time_zone), JSON_SAFE },
+ { "preferredLanguage", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, preferred_language), JSON_SAFE },
+ { "niceLevel", _JSON_VARIANT_TYPE_INVALID, json_dispatch_nice, offsetof(UserRecord, nice_level), 0 },
+ { "resourceLimits", _JSON_VARIANT_TYPE_INVALID, json_dispatch_rlimits, offsetof(UserRecord, rlimits), 0 },
+ { "locked", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(UserRecord, locked), 0 },
+ { "notBeforeUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, not_before_usec), 0 },
+ { "notAfterUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, not_after_usec), 0 },
+ { "storage", JSON_VARIANT_STRING, json_dispatch_storage, offsetof(UserRecord, storage), 0 },
+ { "diskSize", JSON_VARIANT_UNSIGNED, json_dispatch_disk_size, offsetof(UserRecord, disk_size), 0 },
+ { "diskSizeRelative", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, disk_size_relative), 0 },
+ { "skeletonDirectory", JSON_VARIANT_STRING, json_dispatch_path, offsetof(UserRecord, skeleton_directory), 0 },
+ { "accessMode", JSON_VARIANT_UNSIGNED, json_dispatch_access_mode, offsetof(UserRecord, access_mode), 0 },
+ { "tasksMax", JSON_VARIANT_UNSIGNED, json_dispatch_tasks_or_memory_max, offsetof(UserRecord, tasks_max), 0 },
+ { "memoryHigh", JSON_VARIANT_UNSIGNED, json_dispatch_tasks_or_memory_max, offsetof(UserRecord, memory_high), 0 },
+ { "memoryMax", JSON_VARIANT_UNSIGNED, json_dispatch_tasks_or_memory_max, offsetof(UserRecord, memory_max), 0 },
+ { "cpuWeight", JSON_VARIANT_UNSIGNED, json_dispatch_weight, offsetof(UserRecord, cpu_weight), 0 },
+ { "ioWeight", JSON_VARIANT_UNSIGNED, json_dispatch_weight, offsetof(UserRecord, io_weight), 0 },
+ { "mountNoDevices", JSON_VARIANT_BOOLEAN, json_dispatch_boolean, offsetof(UserRecord, nodev), 0 },
+ { "mountNoSuid", JSON_VARIANT_BOOLEAN, json_dispatch_boolean, offsetof(UserRecord, nosuid), 0 },
+ { "mountNoExecute", JSON_VARIANT_BOOLEAN, json_dispatch_boolean, offsetof(UserRecord, noexec), 0 },
+ { "cifsDomain", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, cifs_domain), JSON_SAFE },
+ { "cifsUserName", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, cifs_user_name), JSON_SAFE },
+ { "cifsService", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, cifs_service), JSON_SAFE },
+ { "imagePath", JSON_VARIANT_STRING, json_dispatch_path, offsetof(UserRecord, image_path), 0 },
+ { "homeDirectory", JSON_VARIANT_STRING, json_dispatch_home_directory, offsetof(UserRecord, home_directory), 0 },
+ { "uid", JSON_VARIANT_UNSIGNED, json_dispatch_uid_gid, offsetof(UserRecord, uid), 0 },
+ { "gid", JSON_VARIANT_UNSIGNED, json_dispatch_uid_gid, offsetof(UserRecord, gid), 0 },
+ { "memberOf", JSON_VARIANT_ARRAY, json_dispatch_user_group_list, offsetof(UserRecord, member_of), JSON_RELAX},
+ { "fileSystemType", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, file_system_type), JSON_SAFE },
+ { "partitionUuid", JSON_VARIANT_STRING, json_dispatch_id128, offsetof(UserRecord, partition_uuid), 0 },
+ { "luksUuid", JSON_VARIANT_STRING, json_dispatch_id128, offsetof(UserRecord, luks_uuid), 0 },
+ { "fileSystemUuid", JSON_VARIANT_STRING, json_dispatch_id128, offsetof(UserRecord, file_system_uuid), 0 },
+ { "luksDiscard", _JSON_VARIANT_TYPE_INVALID, json_dispatch_tristate, offsetof(UserRecord, luks_discard), 0 },
{ "luksOfflineDiscard", _JSON_VARIANT_TYPE_INVALID, json_dispatch_tristate, offsetof(UserRecord, luks_offline_discard), 0 },
- { "luksCipher", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, luks_cipher), JSON_SAFE },
- { "luksCipherMode", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, luks_cipher_mode), JSON_SAFE },
- { "luksVolumeKeySize", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_volume_key_size), 0 },
- { "luksPbkdfHashAlgorithm", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, luks_pbkdf_hash_algorithm), JSON_SAFE },
- { "luksPbkdfType", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, luks_pbkdf_type), JSON_SAFE },
- { "luksPbkdfTimeCostUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_pbkdf_time_cost_usec), 0 },
- { "luksPbkdfMemoryCost", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_pbkdf_memory_cost), 0 },
- { "luksPbkdfParallelThreads", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_pbkdf_parallel_threads), 0 },
- { "service", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, service), JSON_SAFE },
- { "rateLimitIntervalUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, ratelimit_interval_usec), 0 },
- { "rateLimitBurst", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, ratelimit_burst), 0 },
- { "enforcePasswordPolicy", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(UserRecord, enforce_password_policy), 0 },
- { "autoLogin", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(UserRecord, auto_login), 0 },
- { "stopDelayUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, stop_delay_usec), 0 },
- { "killProcesses", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(UserRecord, kill_processes), 0 },
- { "passwordChangeMinUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, password_change_min_usec), 0 },
- { "passwordChangeMaxUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, password_change_max_usec), 0 },
- { "passwordChangeWarnUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, password_change_warn_usec), 0 },
- { "passwordChangeInactiveUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, password_change_inactive_usec), 0 },
- { "passwordChangeNow", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(UserRecord, password_change_now), 0 },
- { "pkcs11TokenUri", JSON_VARIANT_ARRAY, dispatch_pkcs11_uri_array, offsetof(UserRecord, pkcs11_token_uri), 0 },
-
- { "secret", JSON_VARIANT_OBJECT, dispatch_secret, 0, 0 },
- { "privileged", JSON_VARIANT_OBJECT, dispatch_privileged, 0, 0 },
+ { "luksCipher", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, luks_cipher), JSON_SAFE },
+ { "luksCipherMode", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, luks_cipher_mode), JSON_SAFE },
+ { "luksVolumeKeySize", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_volume_key_size), 0 },
+ { "luksPbkdfHashAlgorithm", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, luks_pbkdf_hash_algorithm), JSON_SAFE },
+ { "luksPbkdfType", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, luks_pbkdf_type), JSON_SAFE },
+ { "luksPbkdfTimeCostUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_pbkdf_time_cost_usec), 0 },
+ { "luksPbkdfMemoryCost", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_pbkdf_memory_cost), 0 },
+ { "luksPbkdfParallelThreads", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, luks_pbkdf_parallel_threads), 0 },
+ { "service", JSON_VARIANT_STRING, json_dispatch_string, offsetof(UserRecord, service), JSON_SAFE },
+ { "rateLimitIntervalUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, ratelimit_interval_usec), 0 },
+ { "rateLimitBurst", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, ratelimit_burst), 0 },
+ { "enforcePasswordPolicy", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(UserRecord, enforce_password_policy), 0 },
+ { "autoLogin", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(UserRecord, auto_login), 0 },
+ { "stopDelayUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, stop_delay_usec), 0 },
+ { "killProcesses", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(UserRecord, kill_processes), 0 },
+ { "passwordChangeMinUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, password_change_min_usec), 0 },
+ { "passwordChangeMaxUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, password_change_max_usec), 0 },
+ { "passwordChangeWarnUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, password_change_warn_usec), 0 },
+ { "passwordChangeInactiveUSec", JSON_VARIANT_UNSIGNED, json_dispatch_uint64, offsetof(UserRecord, password_change_inactive_usec), 0 },
+ { "passwordChangeNow", JSON_VARIANT_BOOLEAN, json_dispatch_tristate, offsetof(UserRecord, password_change_now), 0 },
+ { "pkcs11TokenUri", JSON_VARIANT_ARRAY, dispatch_pkcs11_uri_array, offsetof(UserRecord, pkcs11_token_uri), 0 },
+ { "fido2HmacCredential", JSON_VARIANT_ARRAY, dispatch_fido2_hmac_credential_array, 0, 0 },
+
+ { "secret", JSON_VARIANT_OBJECT, dispatch_secret, 0, 0 },
+ { "privileged", JSON_VARIANT_OBJECT, dispatch_privileged, 0, 0 },
/* Ignore the perMachine, binding, status stuff here, and process it later, so that it overrides whatever is set above */
- { "perMachine", JSON_VARIANT_ARRAY, NULL, 0, 0 },
- { "binding", JSON_VARIANT_OBJECT, NULL, 0, 0 },
- { "status", JSON_VARIANT_OBJECT, NULL, 0, 0 },
+ { "perMachine", JSON_VARIANT_ARRAY, NULL, 0, 0 },
+ { "binding", JSON_VARIANT_OBJECT, NULL, 0, 0 },
+ { "status", JSON_VARIANT_OBJECT, NULL, 0, 0 },
/* Ignore 'signature', we check it with explicit accessors instead */
- { "signature", JSON_VARIANT_ARRAY, NULL, 0, 0 },
+ { "signature", JSON_VARIANT_ARRAY, NULL, 0, 0 },
{},
};
@@ -1684,6 +1838,9 @@ bool user_record_can_authenticate(UserRecord *h) {
if (h->n_pkcs11_encrypted_key > 0)
return true;
+ if (h->n_fido2_hmac_salt > 0)
+ return true;
+
return !strv_isempty(h->hashed_password);
}
diff --git a/src/shared/user-record.h b/src/shared/user-record.h
index 9fd10610d9..1bfd095d27 100644
--- a/src/shared/user-record.h
+++ b/src/shared/user-record.h
@@ -189,6 +189,23 @@ typedef struct Pkcs11EncryptedKey {
char *hashed_password;
} Pkcs11EncryptedKey;
+typedef struct Fido2HmacCredential {
+ void *id;
+ size_t size;
+} Fido2HmacCredential;
+
+typedef struct Fido2HmacSalt {
+ /* The FIDO2 Cridential ID to use */
+ Fido2HmacCredential credential;
+
+ /* The FIDO2 salt value */
+ void *salt;
+ size_t salt_size;
+
+ /* What to test the hashed salt value against, usually UNIX password hash here. */
+ char *hashed_password;
+} Fido2HmacSalt;
+
typedef struct UserRecord {
/* The following three fields are not part of the JSON record */
unsigned n_ref;
@@ -239,7 +256,7 @@ typedef struct UserRecord {
char **hashed_password;
char **ssh_authorized_keys;
char **password;
- char **pkcs11_pin;
+ char **token_pin;
char *cifs_domain;
char *cifs_user_name;
@@ -309,6 +326,12 @@ typedef struct UserRecord {
size_t n_pkcs11_encrypted_key;
int pkcs11_protected_authentication_path_permitted;
+ Fido2HmacCredential *fido2_hmac_credential;
+ size_t n_fido2_hmac_credential;
+ Fido2HmacSalt *fido2_hmac_salt;
+ size_t n_fido2_hmac_salt;
+ int fido2_user_presence_permitted;
+
JsonVariant *json;
} UserRecord;
diff --git a/src/shared/utmp-wtmp.c b/src/shared/utmp-wtmp.c
index 9debb54390..9edcd8302a 100644
--- a/src/shared/utmp-wtmp.c
+++ b/src/shared/utmp-wtmp.c
@@ -25,8 +25,8 @@
#include "utmp-wtmp.h"
int utmp_get_runlevel(int *runlevel, int *previous) {
+ _cleanup_(utxent_cleanup) bool utmpx = false;
struct utmpx *found, lookup = { .ut_type = RUN_LVL };
- int r;
const char *e;
assert(runlevel);
@@ -35,8 +35,7 @@ int utmp_get_runlevel(int *runlevel, int *previous) {
* precedence. Presumably, sysvinit does this to work around a
* race condition that would otherwise exist where we'd always
* go to disk and hence might read runlevel data that might be
- * very new and does not apply to the current script being
- * executed. */
+ * very new and not apply to the current script being executed. */
e = getenv("RUNLEVEL");
if (e && e[0] > 0) {
@@ -58,27 +57,17 @@ int utmp_get_runlevel(int *runlevel, int *previous) {
if (utmpxname(_PATH_UTMPX) < 0)
return -errno;
- setutxent();
+ utmpx = utxent_start();
found = getutxid(&lookup);
if (!found)
- r = -errno;
- else {
- int a, b;
-
- a = found->ut_pid & 0xFF;
- b = (found->ut_pid >> 8) & 0xFF;
-
- *runlevel = a;
- if (previous)
- *previous = b;
-
- r = 0;
- }
+ return -errno;
- endutxent();
+ *runlevel = found->ut_pid & 0xFF;
+ if (previous)
+ *previous = (found->ut_pid >> 8) & 0xFF;
- return r;
+ return 0;
}
static void init_timestamp(struct utmpx *store, usec_t t) {
@@ -106,7 +95,7 @@ static void init_entry(struct utmpx *store, usec_t t) {
}
static int write_entry_utmp(const struct utmpx *store) {
- int r;
+ _cleanup_(utxent_cleanup) bool utmpx = false;
assert(store);
@@ -117,26 +106,35 @@ static int write_entry_utmp(const struct utmpx *store) {
if (utmpxname(_PATH_UTMPX) < 0)
return -errno;
- setutxent();
-
- if (!pututxline(store))
- r = -errno;
- else
- r = 0;
-
- endutxent();
+ utmpx = utxent_start();
- return r;
+ if (pututxline(store))
+ return 0;
+ if (errno == ENOENT) {
+ /* If utmp/wtmp have been disabled, that's a good thing, hence ignore the error. */
+ log_debug_errno(errno, "Not writing utmp: %m");
+ return 0;
+ }
+ return -errno;
}
static int write_entry_wtmp(const struct utmpx *store) {
assert(store);
/* wtmp is a simple append-only file where each entry is
- simply appended to the end; i.e. basically a log. */
+ * simply appended to the end; i.e. basically a log. */
errno = 0;
updwtmpx(_PATH_WTMPX, store);
+ if (errno == ENOENT) {
+ /* If utmp/wtmp have been disabled, that's a good thing, hence ignore the error. */
+ log_debug_errno(errno, "Not writing wtmp: %m");
+ return 0;
+ }
+ if (errno == EROFS) {
+ log_warning_errno(errno, "Failed to write wtmp record, ignoring: %m");
+ return 0;
+ }
return -errno;
}
@@ -145,16 +143,7 @@ static int write_utmp_wtmp(const struct utmpx *store_utmp, const struct utmpx *s
r = write_entry_utmp(store_utmp);
s = write_entry_wtmp(store_wtmp);
-
- if (r >= 0)
- r = s;
-
- /* If utmp/wtmp have been disabled, that's a good thing, hence
- * ignore the errors */
- if (r == -ENOENT)
- r = 0;
-
- return r;
+ return r < 0 ? r : s;
}
static int write_entry_both(const struct utmpx *store) {
diff --git a/src/shared/utmp-wtmp.h b/src/shared/utmp-wtmp.h
index 9e433cf73e..fe55bad12d 100644
--- a/src/shared/utmp-wtmp.h
+++ b/src/shared/utmp-wtmp.h
@@ -8,6 +8,8 @@
#include "util.h"
#if ENABLE_UTMP
+#include <utmpx.h>
+
int utmp_get_runlevel(int *runlevel, int *previous);
int utmp_put_shutdown(void);
@@ -24,6 +26,15 @@ int utmp_wall(
bool (*match_tty)(const char *tty, void *userdata),
void *userdata);
+static inline bool utxent_start(void) {
+ setutxent();
+ return true;
+}
+static inline void utxent_cleanup(bool *initialized) {
+ if (initialized)
+ endutxent();
+}
+
#else /* ENABLE_UTMP */
static inline int utmp_get_runlevel(int *runlevel, int *previous) {
diff --git a/src/shared/varlink.c b/src/shared/varlink.c
index 1f4d5a614c..be3559dc10 100644
--- a/src/shared/varlink.c
+++ b/src/shared/varlink.c
@@ -387,7 +387,7 @@ DEFINE_TRIVIAL_REF_UNREF_FUNC(Varlink, varlink, varlink_destroy);
static int varlink_test_disconnect(Varlink *v) {
assert(v);
- /* Tests whether we the the connection has been terminated. We are careful to not stop processing it
+ /* Tests whether we the connection has been terminated. We are careful to not stop processing it
* prematurely, since we want to handle half-open connections as well as possible and want to flush
* out and read data before we close down if we can. */
diff --git a/src/sleep/sleep.c b/src/sleep/sleep.c
index f494ca6ffb..7029352ca5 100644
--- a/src/sleep/sleep.c
+++ b/src/sleep/sleep.c
@@ -71,7 +71,7 @@ static int write_hibernate_location_info(const HibernateLocation *hibernate_loca
return 0;
}
- return log_debug_errno(errno, "/sys/power/resume_offset not writeable: %m");
+ return log_debug_errno(errno, "/sys/power/resume_offset not writable: %m");
}
xsprintf(offset_str, "%" PRIu64, hibernate_location->offset);
diff --git a/src/systemd/sd-lldp.h b/src/systemd/sd-lldp.h
index 2dc9f63246..c2abc20121 100644
--- a/src/systemd/sd-lldp.h
+++ b/src/systemd/sd-lldp.h
@@ -176,7 +176,7 @@ int sd_lldp_neighbor_get_mud_url(sd_lldp_neighbor *n, const char **ret);
int sd_lldp_neighbor_get_system_capabilities(sd_lldp_neighbor *n, uint16_t *ret);
int sd_lldp_neighbor_get_enabled_capabilities(sd_lldp_neighbor *n, uint16_t *ret);
-/* Low-level, iterative TLV access. This is for evertyhing else, it iteratively goes through all available TLVs
+/* Low-level, iterative TLV access. This is for everything else, it iteratively goes through all available TLVs
* (including the ones covered with the calls above), and allows multiple TLVs for the same fields. */
int sd_lldp_neighbor_tlv_rewind(sd_lldp_neighbor *n);
int sd_lldp_neighbor_tlv_next(sd_lldp_neighbor *n);
diff --git a/src/test/test-locale-util.c b/src/test/test-locale-util.c
index 45b6782145..347982dd52 100644
--- a/src/test/test-locale-util.c
+++ b/src/test/test-locale-util.c
@@ -89,7 +89,7 @@ static void test_keymaps(void) {
#define dump_glyph(x) log_info(STRINGIFY(x) ": %s", special_glyph(x))
static void dump_special_glyphs(void) {
- assert_cc(SPECIAL_GLYPH_LOCK_AND_KEY + 1 == _SPECIAL_GLYPH_MAX);
+ assert_cc(SPECIAL_GLYPH_TOUCH + 1 == _SPECIAL_GLYPH_MAX);
log_info("/* %s */", __func__);
@@ -116,6 +116,7 @@ static void dump_special_glyphs(void) {
dump_glyph(SPECIAL_GLYPH_UNHAPPY_SMILEY);
dump_glyph(SPECIAL_GLYPH_DEPRESSED_SMILEY);
dump_glyph(SPECIAL_GLYPH_LOCK_AND_KEY);
+ dump_glyph(SPECIAL_GLYPH_TOUCH);
}
int main(int argc, char *argv[]) {
diff --git a/src/test/test-process-util.c b/src/test/test-process-util.c
index d78e0544a7..b00dd4a980 100644
--- a/src/test/test-process-util.c
+++ b/src/test/test-process-util.c
@@ -636,7 +636,7 @@ static void test_setpriority_closest(void) {
q = getpriority(PRIO_PROCESS, 0);
assert_se(errno == 0 && p == q);
- /* It should also be possible to to set the nice level to one higher */
+ /* It should also be possible to set the nice level to one higher */
if (p < PRIO_MAX-1) {
assert_se(setpriority_closest(++p) > 0);
@@ -645,7 +645,7 @@ static void test_setpriority_closest(void) {
assert_se(errno == 0 && p == q);
}
- /* It should also be possible to to set the nice level to two higher */
+ /* It should also be possible to set the nice level to two higher */
if (p < PRIO_MAX-1) {
assert_se(setpriority_closest(++p) > 0);
diff --git a/src/test/test-udev.c b/src/test/test-udev.c
index 208e7a0e96..c0b215dadc 100644
--- a/src/test/test-udev.c
+++ b/src/test/test-udev.c
@@ -17,6 +17,7 @@
#include "log.h"
#include "main-func.h"
#include "mkdir.h"
+#include "namespace-util.h"
#include "selinux-util.h"
#include "signal-util.h"
#include "string-util.h"
@@ -36,15 +37,13 @@ static int fake_filesystems(void) {
{ "test/run", "/etc/udev/rules.d", "Failed to mount empty /etc/udev/rules.d", true },
{ "test/run", UDEVLIBEXECDIR "/rules.d", "Failed to mount empty " UDEVLIBEXECDIR "/rules.d", true },
};
- unsigned i;
-
- if (unshare(CLONE_NEWNS) < 0)
- return log_error_errno(errno, "Failed to call unshare(): %m");
+ int r;
- if (mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL) < 0)
- return log_error_errno(errno, "Failed to mount / as private: %m");
+ r = detach_mount_namespace();
+ if (r < 0)
+ return log_error_errno(r, "Failed to detach mount namespace: %m");
- for (i = 0; i < ELEMENTSOF(fakefss); i++)
+ for (size_t i = 0; i < ELEMENTSOF(fakefss); i++)
if (mount(fakefss[i].src, fakefss[i].target, NULL, MS_BIND, NULL) < 0) {
log_full_errno(fakefss[i].ignore_mount_error ? LOG_DEBUG : LOG_ERR, errno, "%s: %m", fakefss[i].error);
if (!fakefss[i].ignore_mount_error)
diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c
index 6e294c72d6..0d524f9a56 100644
--- a/src/test/test-unit-name.c
+++ b/src/test/test-unit-name.c
@@ -130,6 +130,7 @@ static void test_unit_name_from_path(void) {
test_unit_name_from_path_one("///", ".mount", "-.mount", 0);
test_unit_name_from_path_one("/foo/../bar", ".mount", NULL, -EINVAL);
test_unit_name_from_path_one("/foo/./bar", ".mount", NULL, -EINVAL);
+ test_unit_name_from_path_one("/waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", ".mount", NULL, -EINVAL);
}
static void test_unit_name_from_path_instance_one(const char *pattern, const char *path, const char *suffix, const char *expected, int ret) {
@@ -159,6 +160,7 @@ static void test_unit_name_from_path_instance(void) {
test_unit_name_from_path_instance_one("waldo", "..", ".mount", NULL, -EINVAL);
test_unit_name_from_path_instance_one("waldo", "/foo", ".waldi", NULL, -EINVAL);
test_unit_name_from_path_instance_one("wa--ldo", "/--", ".mount", "wa--ldo@\\x2d\\x2d.mount", 0);
+ test_unit_name_from_path_instance_one("waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "/waldo", ".mount", NULL, -EINVAL);
}
static void test_unit_name_to_path_one(const char *unit, const char *path, int ret) {
diff --git a/src/test/test-util.c b/src/test/test-util.c
index 76dd72a598..d4a6c8f5c3 100644
--- a/src/test/test-util.c
+++ b/src/test/test-util.c
@@ -410,6 +410,85 @@ static void test_system_tasks_max_scale(void) {
assert_se(system_tasks_max_scale(UINT64_MAX/4, UINT64_MAX) == UINT64_MAX);
}
+static void test_foreach_pointer(void) {
+ int a, b, c, *i;
+ size_t k = 0;
+
+ FOREACH_POINTER(i, &a, &b, &c) {
+ switch (k) {
+
+ case 0:
+ assert_se(i == &a);
+ break;
+
+ case 1:
+ assert_se(i == &b);
+ break;
+
+ case 2:
+ assert_se(i == &c);
+ break;
+
+ default:
+ assert_not_reached("unexpected index");
+ break;
+ }
+
+ k++;
+ }
+
+ assert(k == 3);
+
+ FOREACH_POINTER(i, &b) {
+ assert(k == 3);
+ assert(i == &b);
+ k = 4;
+ }
+
+ assert(k == 4);
+
+ FOREACH_POINTER(i, NULL, &c, NULL, &b, NULL, &a, NULL) {
+ switch (k) {
+
+ case 4:
+ assert_se(i == NULL);
+ break;
+
+ case 5:
+ assert_se(i == &c);
+ break;
+
+ case 6:
+ assert_se(i == NULL);
+ break;
+
+ case 7:
+ assert_se(i == &b);
+ break;
+
+ case 8:
+ assert_se(i == NULL);
+ break;
+
+ case 9:
+ assert_se(i == &a);
+ break;
+
+ case 10:
+ assert_se(i == NULL);
+ break;
+
+ default:
+ assert_not_reached("unexpected index");
+ break;
+ }
+
+ k++;
+ }
+
+ assert(k == 11);
+}
+
int main(int argc, char *argv[]) {
test_setup_logging(LOG_INFO);
@@ -428,6 +507,7 @@ int main(int argc, char *argv[]) {
test_physical_memory_scale();
test_system_tasks_max();
test_system_tasks_max_scale();
+ test_foreach_pointer();
return 0;
}
diff --git a/src/test/test-xdg-autostart.c b/src/test/test-xdg-autostart.c
index cc75bc6024..70287b3c55 100644
--- a/src/test/test-xdg-autostart.c
+++ b/src/test/test-xdg-autostart.c
@@ -67,7 +67,7 @@ static void test_xdg_desktop_parse(unsigned i, const char *s) {
case 0:
assert_se(streq(service->exec_string, "/bin/sleep 100"));
assert_se(strv_equal(service->only_show_in, STRV_MAKE("A", "B")));
- assert_se(strv_equal(service->not_show_in, STRV_MAKE("C", "", "D\\;", "E")));
+ assert_se(strv_equal(service->not_show_in, STRV_MAKE("C", "D\\;", "E")));
assert_se(!service->hidden);
break;
case 1:
@@ -81,14 +81,12 @@ static void test_xdg_desktop_parse(unsigned i, const char *s) {
}
int main(int argc, char *argv[]) {
- size_t i;
-
test_setup_logging(LOG_DEBUG);
test_translate_name();
test_xdg_format_exec_start();
- for (i = 0; i < ELEMENTSOF(xdg_desktop_file); i++)
+ for (size_t i = 0; i < ELEMENTSOF(xdg_desktop_file); i++)
test_xdg_desktop_parse(i, xdg_desktop_file[i]);
return 0;
diff --git a/src/timesync/timesyncd.c b/src/timesync/timesyncd.c
index e56e09ca8c..4f514d536d 100644
--- a/src/timesync/timesyncd.c
+++ b/src/timesync/timesyncd.c
@@ -89,8 +89,8 @@ settime:
}
static int run(int argc, char *argv[]) {
- _cleanup_(notify_on_cleanup) const char *notify_message = NULL;
_cleanup_(manager_freep) Manager *m = NULL;
+ _cleanup_(notify_on_cleanup) const char *notify_message = NULL;
const char *user = "systemd-timesync";
uid_t uid, uid_current;
gid_t gid;
diff --git a/src/udev/udevadm-info.c b/src/udev/udevadm-info.c
index 1debdf2b31..b1209e6baf 100644
--- a/src/udev/udevadm-info.c
+++ b/src/udev/udevadm-info.c
@@ -17,6 +17,7 @@
#include "device-util.h"
#include "dirent-util.h"
#include "fd-util.h"
+#include "sort-util.h"
#include "string-table.h"
#include "string-util.h"
#include "udev-util.h"
@@ -56,9 +57,36 @@ static bool skip_attribute(const char *name) {
return string_table_lookup(skip, ELEMENTSOF(skip), name) >= 0;
}
-static void print_all_attributes(sd_device *device, const char *key) {
+typedef struct SysAttr {
+ const char *name;
+ const char *value;
+} SysAttr;
+
+static int sysattr_compare(const SysAttr *a, const SysAttr *b) {
+ return strcmp(a->name, b->name);
+}
+
+static int print_all_attributes(sd_device *device, bool is_parent) {
+ _cleanup_free_ SysAttr *sysattrs = NULL;
+ size_t n_items = 0, n_allocated = 0;
const char *name, *value;
+ value = NULL;
+ (void) sd_device_get_devpath(device, &value);
+ printf(" looking at %sdevice '%s':\n", is_parent ? "parent " : "", strempty(value));
+
+ value = NULL;
+ (void) sd_device_get_sysname(device, &value);
+ printf(" %s==\"%s\"\n", is_parent ? "KERNELS" : "KERNEL", strempty(value));
+
+ value = NULL;
+ (void) sd_device_get_subsystem(device, &value);
+ printf(" %s==\"%s\"\n", is_parent ? "SUBSYSTEMS" : "SUBSYSTEM", strempty(value));
+
+ value = NULL;
+ (void) sd_device_get_driver(device, &value);
+ printf(" %s==\"%s\"\n", is_parent ? "DRIVERS" : "DRIVER", strempty(value));
+
FOREACH_DEVICE_SYSATTR(device, name) {
size_t len;
@@ -79,14 +107,29 @@ static void print_all_attributes(sd_device *device, const char *key) {
if (len > 0)
continue;
- printf(" %s{%s}==\"%s\"\n", key, name, value);
+ if (!GREEDY_REALLOC(sysattrs, n_allocated, n_items + 1))
+ return log_oom();
+
+ sysattrs[n_items] = (SysAttr) {
+ .name = name,
+ .value = value,
+ };
+ n_items++;
}
+
+ typesafe_qsort(sysattrs, n_items, sysattr_compare);
+
+ for (size_t i = 0; i < n_items; i++)
+ printf(" %s{%s}==\"%s\"\n", is_parent ? "ATTRS" : "ATTR", sysattrs[i].name, sysattrs[i].value);
+
puts("");
+
+ return 0;
}
static int print_device_chain(sd_device *device) {
sd_device *child, *parent;
- const char *str;
+ int r;
printf("\n"
"Udevadm info starts with the device specified by the devpath and then\n"
@@ -96,30 +139,14 @@ static int print_device_chain(sd_device *device) {
"and the attributes from one single parent device.\n"
"\n");
- (void) sd_device_get_devpath(device, &str);
- printf(" looking at device '%s':\n", str);
- (void) sd_device_get_sysname(device, &str);
- printf(" KERNEL==\"%s\"\n", str);
- if (sd_device_get_subsystem(device, &str) < 0)
- str = "";
- printf(" SUBSYSTEM==\"%s\"\n", str);
- if (sd_device_get_driver(device, &str) < 0)
- str = "";
- printf(" DRIVER==\"%s\"\n", str);
- print_all_attributes(device, "ATTR");
+ r = print_all_attributes(device, false);
+ if (r < 0)
+ return r;
for (child = device; sd_device_get_parent(child, &parent) >= 0; child = parent) {
- (void) sd_device_get_devpath(parent, &str);
- printf(" looking at parent device '%s':\n", str);
- (void) sd_device_get_sysname(parent, &str);
- printf(" KERNELS==\"%s\"\n", str);
- if (sd_device_get_subsystem(parent, &str) < 0)
- str = "";
- printf(" SUBSYSTEMS==\"%s\"\n", str);
- if (sd_device_get_driver(parent, &str) < 0)
- str = "";
- printf(" DRIVERS==\"%s\"\n", str);
- print_all_attributes(parent, "ATTRS");
+ r = print_all_attributes(parent, true);
+ if (r < 0)
+ return r;
}
return 0;
diff --git a/src/update-utmp/update-utmp.c b/src/update-utmp/update-utmp.c
index fd24cdc789..47354d5012 100644
--- a/src/update-utmp/update-utmp.c
+++ b/src/update-utmp/update-utmp.c
@@ -84,11 +84,10 @@ static int get_current_runlevel(Context *c) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
int r;
- unsigned i;
assert(c);
- for (i = 0; i < ELEMENTSOF(table); i++) {
+ for (size_t i = 0; i < ELEMENTSOF(table); i++) {
_cleanup_free_ char *state = NULL, *path = NULL;
path = unit_dbus_path_from_name(table[i].special);
@@ -223,9 +222,6 @@ static int run(int argc, char *argv[]) {
};
int r;
- if (getppid() != 1)
- return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
- "This program should be invoked by init only.");
if (argc != 2)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"This program requires one argument.");
diff --git a/src/userdb/userdbctl.c b/src/userdb/userdbctl.c
index 648eacd023..382a1cc9e4 100644
--- a/src/userdb/userdbctl.c
+++ b/src/userdb/userdbctl.c
@@ -85,7 +85,7 @@ static int show_user(UserRecord *ur, Table *table) {
TABLE_STRING, user_record_shell(ur),
TABLE_INT, (int) user_record_disposition(ur));
if (r < 0)
- return log_error_errno(r, "Failed to add row to table: %m");
+ return table_log_add_error(r);
break;
@@ -234,7 +234,7 @@ static int show_group(GroupRecord *gr, Table *table) {
TABLE_GID, gr->gid,
TABLE_INT, (int) group_record_disposition(gr));
if (r < 0)
- return log_error_errno(r, "Failed to add row to table: %m");
+ return table_log_add_error(r);
break;
@@ -377,7 +377,7 @@ static int show_membership(const char *user, const char *group, Table *table) {
TABLE_STRING, user,
TABLE_STRING, group);
if (r < 0)
- return log_error_errno(r, "Failed to add row to table: %m");
+ return table_log_add_error(r);
break;
@@ -521,7 +521,7 @@ static int display_services(int argc, char *argv[], void *userdata) {
TABLE_STRING, no ?: "yes",
TABLE_SET_COLOR, no ? ansi_highlight_red() : ansi_highlight_green());
if (r < 0)
- return log_error_errno(r, "Failed to add table row: %m");
+ return table_log_add_error(r);
}
if (table_get_rows(t) <= 0) {
diff --git a/src/userdb/userdbd.c b/src/userdb/userdbd.c
index 978fd1d788..dbc285e61a 100644
--- a/src/userdb/userdbd.c
+++ b/src/userdb/userdbd.c
@@ -20,8 +20,8 @@
*/
static int run(int argc, char *argv[]) {
- _cleanup_(notify_on_cleanup) const char *notify_stop = NULL;
_cleanup_(manager_freep) Manager *m = NULL;
+ _cleanup_(notify_on_cleanup) const char *notify_stop = NULL;
int r;
log_setup_service();
diff --git a/src/xdg-autostart-generator/xdg-autostart-service.c b/src/xdg-autostart-generator/xdg-autostart-service.c
index 0d33c70401..4a30f9e433 100644
--- a/src/xdg-autostart-generator/xdg-autostart-service.c
+++ b/src/xdg-autostart-generator/xdg-autostart-service.c
@@ -182,6 +182,40 @@ static int xdg_config_parse_string(
return 0;
}
+static int strv_strndup_unescape_and_push(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ char ***sv,
+ size_t *n_allocated,
+ size_t *n,
+ const char *start,
+ const char *end) {
+
+ if (end == start)
+ return 0;
+
+ _cleanup_free_ char *copy = NULL;
+ int r;
+
+ copy = strndup(start, end - start);
+ if (!copy)
+ return log_oom();
+
+ r = xdg_unescape_string(unit, filename, line, copy);
+ if (r < 0)
+ return r;
+
+ if (!greedy_realloc((void**) sv, n_allocated, *n + 2, sizeof(char*))) /* One extra for NULL */
+ return log_oom();
+
+ (*sv)[*n] = TAKE_PTR(copy);
+ (*sv)[*n + 1] = NULL;
+ (*n)++;
+
+ return 0;
+}
+
static int xdg_config_parse_strv(
const char *unit,
const char *filename,
@@ -194,9 +228,7 @@ static int xdg_config_parse_strv(
void *data,
void *userdata) {
- char ***sv = data;
- const char *start;
- const char *end;
+ char ***ret_sv = data;
int r;
assert(filename);
@@ -205,23 +237,25 @@ static int xdg_config_parse_strv(
assert(data);
/* XDG does not allow duplicate definitions. */
- if (*sv) {
- log_syntax(unit, LOG_ERR, filename, line, 0, "Key %s was defined multiple times, ignoring.", lvalue);
+ if (*ret_sv) {
+ log_syntax(unit, LOG_ERR, filename, line, 0, "Key %s was already defined, ignoring.", lvalue);
return 0;
}
- *sv = strv_new(NULL);
- if (!*sv)
+ size_t n = 0, n_allocated = 0;
+ _cleanup_strv_free_ char **sv = NULL;
+
+ if (!GREEDY_REALLOC0(sv, n_allocated, 1))
return log_oom();
/* We cannot use strv_split because it does not handle escaping correctly. */
- start = rvalue;
+ const char *start = rvalue, *end;
for (end = start; *end; end++) {
if (*end == '\\') {
/* Move forward, and ensure it is a valid escape. */
end++;
- if (strchr("sntr\\;", *end) == NULL) {
+ if (!strchr("sntr\\;", *end)) {
log_syntax(unit, LOG_ERR, filename, line, 0, "Undefined escape sequence \\%c.", *end);
return 0;
}
@@ -229,29 +263,24 @@ static int xdg_config_parse_strv(
}
if (*end == ';') {
- _cleanup_free_ char *copy = NULL;
-
- copy = strndup(start, end - start);
- if (!copy)
- return log_oom();
- r = xdg_unescape_string(unit, filename, line, copy);
+ r = strv_strndup_unescape_and_push(unit, filename, line,
+ &sv, &n_allocated, &n,
+ start, end);
if (r < 0)
return r;
- r = strv_consume(sv, TAKE_PTR(copy));
- if (r < 0)
- return log_oom();
start = end + 1;
}
}
- /* Any trailing entry should be ignored if it is empty. */
- if (end > start) {
- r = strv_extend(sv, start);
- if (r < 0)
- return log_oom();
- }
+ /* Handle the trailing entry after the last separator */
+ r = strv_strndup_unescape_and_push(unit, filename, line,
+ &sv, &n_allocated, &n,
+ start, end);
+ if (r < 0)
+ return r;
+ *ret_sv = TAKE_PTR(sv);
return 0;
}
diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network
index 703da475b6..aa04c1192a 100644
--- a/test/fuzz/fuzz-network-parser/directives.network
+++ b/test/fuzz/fuzz-network-parser/directives.network
@@ -38,6 +38,16 @@ MTUBytes=
Multicast=
MACAddress=
Group=
+[SR-IOV]
+VirtualFunction=
+MACSpoofCheck=
+VLANId=
+VLANProtocol=
+QualityOfService=
+QueryReceiveSideScaling=
+Trust=
+LinkState=
+MACAddress=
[BridgeFDB]
VLANId=
MACAddress=
@@ -97,6 +107,7 @@ UseTimezone=
RouteTable=
DenyList=
BlackList=
+AllowList=
RequestOptions=
SendRelease=
MaxAttempts=
@@ -322,7 +333,9 @@ PacketLimit=
Parent=
Handle=
Rate=
+BurstBytes=
Burst=
+LimitBytes=
LimitSize=
MTUBytes=
MPUBytes=
@@ -336,8 +349,10 @@ PerturbPeriodSec=
Parent=
Handle=
PacketLimit=
+MemoryLimitBytes=
MemoryLimit=
Flows=
+QuantumBytes=
Quantum=
TargetSec=
IntervalSec=
@@ -348,7 +363,9 @@ Parent=
Handle=
PacketLimit=
FlowLimit=
+QuantumBytes=
Quantum=
+InitialQuantumBytes=
InitialQuantum=
MaximumRate=
Buckets=
@@ -367,7 +384,7 @@ ECN=
Parent=
Handle=
Bandwidth=
-Overhead=
+OverheadBytes=
[TrafficControlQueueingDiscipline]
Parent=
NetworkEmulatorDelaySec=
@@ -398,7 +415,7 @@ CeilBufferBytes=
[BFIFO]
Parent=
Handle=
-LimitSize=
+LimitBytes=
[PFIFO]
Parent=
Handle=
@@ -431,14 +448,14 @@ Handle=
Parent=
ClassId=
Weight=
-MaxPacketSize=
+MaxPacketBytes=
[DeficitRoundRobinScheduler]
Parent=
Handle=
[DeficitRoundRobinSchedulerClass]
Parent=
ClassId=
-Quantum=
+QuantumBytes=
[EnhancedTransmissionSelection]
Parent=
Handle=
diff --git a/test/fuzz/fuzz-network-parser/oss-fuzz-23895 b/test/fuzz/fuzz-network-parser/oss-fuzz-23895
new file mode 100644
index 0000000000..a86361d0b3
--- /dev/null
+++ b/test/fuzz/fuzz-network-parser/oss-fuzz-23895
Binary files differ
diff --git a/test/fuzz/fuzz-network-parser/oss-fuzz-23950 b/test/fuzz/fuzz-network-parser/oss-fuzz-23950
new file mode 100644
index 0000000000..5bfb17ba38
--- /dev/null
+++ b/test/fuzz/fuzz-network-parser/oss-fuzz-23950
Binary files differ
diff --git a/test/fuzz/fuzz-xdg-desktop/oss-fuzz-22812 b/test/fuzz/fuzz-xdg-desktop/oss-fuzz-22812
new file mode 100644
index 0000000000..4b4cadffb7
--- /dev/null
+++ b/test/fuzz/fuzz-xdg-desktop/oss-fuzz-22812
Binary files differ
diff --git a/test/test-network/conf/25-qdisc-cake.network b/test/test-network/conf/25-qdisc-cake.network
index b713245dbc..a1b00f258f 100644
--- a/test/test-network/conf/25-qdisc-cake.network
+++ b/test/test-network/conf/25-qdisc-cake.network
@@ -8,5 +8,5 @@ Address=10.1.2.3/16
[CAKE]
Parent=root
Handle=3a
-Overhead=128
+OverheadBytes=128
Bandwidth=500M
diff --git a/test/test-network/conf/25-qdisc-clsact-and-htb.network b/test/test-network/conf/25-qdisc-clsact-and-htb.network
index f18e2f76d9..fd2520db50 100644
--- a/test/test-network/conf/25-qdisc-clsact-and-htb.network
+++ b/test/test-network/conf/25-qdisc-clsact-and-htb.network
@@ -58,8 +58,8 @@ Parent=2:32
Handle=0032
PacketLimit=1000
FlowLimit=200
-Quantum=1500
-InitialQuantum=13000
+QuantumBytes=1500
+InitialQuantumBytes=13000
MaximumRate=1M
Buckets=512
OrphanMask=511
@@ -93,11 +93,11 @@ CeilRate=0.5M
Parent=2:34
Handle=0034
PacketLimit=20480
-MemoryLimit=64M
+MemoryLimitBytes=64M
Flows=2048
TargetSec=10ms
IntervalSec=200ms
-Quantum=1400
+QuantumBytes=1400
ECN=yes
CEThresholdSec=100ms
@@ -112,10 +112,10 @@ CeilRate=0.5M
Parent=2:35
Handle=0035
Rate=1G
-Burst=5K
+BurstBytes=5000
LatencySec=70msec
PeakRate=100G
-MTUBytes=1M
+MTUBytes=1000000
[HierarchyTokenBucketClass]
Parent=root
@@ -177,7 +177,7 @@ CeilRate=0.5M
[BFIFO]
Parent=2:3a
Handle=003a
-LimitSize=1M
+LimitBytes=1000000
[HierarchyTokenBucketClass]
Parent=root
diff --git a/test/test-network/conf/25-qdisc-drr.network b/test/test-network/conf/25-qdisc-drr.network
index 4632740061..dff8b0978d 100644
--- a/test/test-network/conf/25-qdisc-drr.network
+++ b/test/test-network/conf/25-qdisc-drr.network
@@ -12,4 +12,4 @@ Handle=0002
[DeficitRoundRobinSchedulerClass]
Parent=root
ClassId=0002:0030
-Quantum=2000
+QuantumBytes=2000
diff --git a/test/test-network/conf/25-qdisc-qfq.network b/test/test-network/conf/25-qdisc-qfq.network
index c94fc9e4cb..3a24415c12 100644
--- a/test/test-network/conf/25-qdisc-qfq.network
+++ b/test/test-network/conf/25-qdisc-qfq.network
@@ -13,10 +13,10 @@ Handle=0002
Parent=root
ClassId=0002:0030
Weight=2
-MaxPacketSize=16000
+MaxPacketBytes=16000
[QuickFairQueueingClass]
Parent=root
ClassId=0002:0031
Weight=10
-MaxPacketSize=8000
+MaxPacketBytes=8000
diff --git a/test/test-network/conf/25-sriov.network b/test/test-network/conf/25-sriov.network
new file mode 100644
index 0000000000..c962c3d845
--- /dev/null
+++ b/test/test-network/conf/25-sriov.network
@@ -0,0 +1,37 @@
+[Match]
+Name=eni99np1
+
+[Network]
+Address=192.168.100.100/24
+
+[SR-IOV]
+VirtualFunction=0
+VLANId=5
+VLANProtocol=802.1ad
+QualityOfService=1
+MACSpoofCheck=yes
+QueryReceiveSideScaling=yes
+Trust=yes
+LinkState=yes
+MACAddress=00:11:22:33:44:55
+
+[SR-IOV]
+VirtualFunction=1
+VLANId=6
+VLANProtocol=802.1Q
+QualityOfService=2
+MACSpoofCheck=no
+QueryReceiveSideScaling=no
+Trust=no
+LinkState=no
+MACAddress=00:11:22:33:44:56
+
+[SR-IOV]
+VirtualFunction=2
+VLANId=7
+QualityOfService=3
+MACSpoofCheck=no
+QueryReceiveSideScaling=no
+Trust=no
+LinkState=auto
+MACAddress=00:11:22:33:44:57
diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py
index c48163b055..caf077c836 100755
--- a/test/test-network/systemd-networkd-tests.py
+++ b/test/test-network/systemd-networkd-tests.py
@@ -158,6 +158,33 @@ def expectedFailureIfAlternativeNameIsNotAvailable():
return f
+def expectedFailureIfNetdevsimWithSRIOVIsNotAvailable():
+ def f(func):
+ call('rmmod netdevsim', stderr=subprocess.DEVNULL)
+ rc = call('modprobe netdevsim', stderr=subprocess.DEVNULL)
+ if rc != 0:
+ return unittest.expectedFailure(func)
+
+ try:
+ with open('/sys/bus/netdevsim/new_device', mode='w') as f:
+ f.write('99 1')
+ except Exception as error:
+ return unittest.expectedFailure(func)
+
+ call('udevadm settle')
+ call('udevadm info -w10s /sys/devices/netdevsim99/net/eni99np1', stderr=subprocess.DEVNULL)
+ try:
+ with open('/sys/class/net/eni99np1/device/sriov_numvfs', mode='w') as f:
+ f.write('3')
+ except Exception as error:
+ call('rmmod netdevsim', stderr=subprocess.DEVNULL)
+ return unittest.expectedFailure(func)
+
+ call('rmmod netdevsim', stderr=subprocess.DEVNULL)
+ return func
+
+ return f
+
def expectedFailureIfCAKEIsNotAvailable():
def f(func):
call('ip link add dummy98 type dummy', stderr=subprocess.DEVNULL)
@@ -1695,6 +1722,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
'25-route-vrf.network',
'25-gateway-static.network',
'25-gateway-next-static.network',
+ '25-sriov.network',
'25-sysctl-disable-ipv6.network',
'25-sysctl.network',
'25-test1.network',
@@ -2237,7 +2265,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
self.assertRegex(output, 'inet6 .* scope link')
output = check_output('ip -4 route show dev dummy98')
print(output)
- self.assertEqual(output, '10.2.0.0/16 proto kernel scope link src 10.2.3.4')
+ self.assertRegex(output, '10.2.0.0/16 proto kernel scope link src 10.2.3.4')
output = check_output('ip -6 route show dev dummy98')
print(output)
self.assertRegex(output, 'default via 2607:5300:203:39ff:ff:ff:ff:ff proto static')
@@ -2260,7 +2288,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
self.assertRegex(output, 'inet6 .* scope link')
output = check_output('ip -4 route show dev dummy98')
print(output)
- self.assertEqual(output, '10.2.0.0/16 proto kernel scope link src 10.2.3.4')
+ self.assertRegex(output, '10.2.0.0/16 proto kernel scope link src 10.2.3.4')
output = check_output('ip -6 route show dev dummy98')
print(output)
self.assertRegex(output, 'default via 2607:5300:203:39ff:ff:ff:ff:ff proto static')
@@ -2508,6 +2536,32 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
self.assertRegex(output, 'quanta 1 2 3 4 5')
self.assertRegex(output, 'priomap 3 4 5 6 7')
+ @expectedFailureIfNetdevsimWithSRIOVIsNotAvailable()
+ def test_sriov(self):
+ call('rmmod netdevsim', stderr=subprocess.DEVNULL)
+ call('modprobe netdevsim', stderr=subprocess.DEVNULL)
+ with open('/sys/bus/netdevsim/new_device', mode='w') as f:
+ f.write('99 1')
+
+ call('udevadm settle')
+ call('udevadm info -w10s /sys/devices/netdevsim99/net/eni99np1', stderr=subprocess.DEVNULL)
+ with open('/sys/class/net/eni99np1/device/sriov_numvfs', mode='w') as f:
+ f.write('3')
+
+ copy_unit_to_networkd_unit_path('25-sriov.network')
+ start_networkd()
+ self.wait_online(['eni99np1:routable'])
+
+ output = check_output('ip link show dev eni99np1')
+ print(output)
+ self.assertRegex(output,
+ 'vf 0 .*00:11:22:33:44:55.*vlan 5, qos 1, vlan protocol 802.1ad, spoof checking on, link-state enable, trust on, query_rss on\n *'
+ 'vf 1 .*00:11:22:33:44:56.*vlan 6, qos 2, spoof checking off, link-state disable, trust off, query_rss off\n *'
+ 'vf 2 .*00:11:22:33:44:57.*vlan 7, qos 3, spoof checking off, link-state auto, trust off, query_rss off'
+ )
+
+ call('rmmod netdevsim', stderr=subprocess.DEVNULL)
+
class NetworkdStateFileTests(unittest.TestCase, Utilities):
links = [
'dummy98',
diff --git a/test/units/test-honor-first-shutdown.service b/test/units/test-honor-first-shutdown.service
index 374f1e6b5f..3170f979e2 100644
--- a/test/units/test-honor-first-shutdown.service
+++ b/test/units/test-honor-first-shutdown.service
@@ -4,8 +4,8 @@ After=multi-user.target
[Service]
ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh
-ExecStop=sh -c 'kill -SIGKILL $MAINPID'
+ExecStop=sh -c 'kill -KILL $MAINPID'
FailureAction=reboot
[Install]
-WantedBy=multi-user.target \ No newline at end of file
+WantedBy=multi-user.target
diff --git a/test/units/testsuite-48.sh b/test/units/testsuite-48.sh
index 93e5e98e42..03231e71b1 100755
--- a/test/units/testsuite-48.sh
+++ b/test/units/testsuite-48.sh
@@ -53,6 +53,33 @@ systemctl start testservice-48.service
systemctl is-active testservice-48.service
+# Stop and remove, and try again to exercise the transaction setup code path by
+# having the target pull in the unloaded but available unit
+systemctl stop testservice-48.service testservice-48.target
+rm -f /run/systemd/system/testservice-48.service /run/systemd/system/testservice-48.target
+systemctl daemon-reload
+
+sleep 3.1
+
+cat > /run/systemd/system/testservice-48.target <<EOF
+[Unit]
+Conflicts=shutdown.target
+Wants=testservice-48.service
+EOF
+
+systemctl daemon-reload
+
+systemctl start testservice-48.target
+
+cat > /run/systemd/system/testservice-48.service <<EOF
+[Service]
+ExecStart=/bin/sleep infinity
+EOF
+
+systemctl restart testservice-48.target
+
+systemctl is-active testservice-48.service
+
echo OK > /testok
exit 0
diff --git a/travis-ci/managers/fedora.sh b/travis-ci/managers/fedora.sh
index cc665021d4..8fe43c0771 100755
--- a/travis-ci/managers/fedora.sh
+++ b/travis-ci/managers/fedora.sh
@@ -18,11 +18,15 @@ REPO_ROOT="${REPO_ROOT:-$PWD}"
ADDITIONAL_DEPS=(
clang
dnf-plugins-core
- hostname libasan
- jq iputils
+ hostname
+ iputils
+ jq
+ libasan
libfdisk-devel
+ libfido2-devel
libpwquality-devel
libubsan
+ libzstd-devel
llvm
openssl-devel
p11-kit-devel