Compare commits
31 Commits
08b8f29a25
...
9efa8a3cff
Author | SHA1 | Date |
---|---|---|
Susant Sahani | 9efa8a3cff | |
Susant Sahani | 5c95a9134a | |
Yu Watanabe | fac729f811 | |
Lennart Poettering | f6dbcebdc2 | |
Yu Watanabe | 8abbd9a4d9 | |
Yu Watanabe | 27cd09442f | |
Yu Watanabe | cfbee85ce2 | |
Yu Watanabe | 63ef9d31fd | |
Yu Watanabe | 63b00fa77d | |
Lennart Poettering | bfafec253c | |
Lennart Poettering | ccdf03b9c7 | |
Lennart Poettering | 4a56315a99 | |
Lennart Poettering | 6527b019fc | |
Lennart Poettering | 871dc8d644 | |
Lennart Poettering | a745117dba | |
Lennart Poettering | 70d8586365 | |
Lennart Poettering | 5a7cf2e9d8 | |
Lennart Poettering | b0d0e0ef98 | |
Lennart Poettering | 08ab18618e | |
Lennart Poettering | 43007b302e | |
Lennart Poettering | a3d19f5d99 | |
Lennart Poettering | 35a3eb9bdc | |
Lennart Poettering | 5abee64ed4 | |
Dan Streetman | 0fc0d85fae | |
Dan Streetman | 9bacf4313e | |
Dan Streetman | 6b8a1aa6a3 | |
Dan Streetman | bd0d471c8f | |
Lennart Poettering | 8dd7cbce42 | |
Lennart Poettering | 2c905207db | |
Lennart Poettering | 5aec5c751a | |
Lennart Poettering | ab19db01ae |
324
NEWS
324
NEWS
|
@ -1,6 +1,92 @@
|
||||||
systemd System and Service Manager
|
systemd System and Service Manager
|
||||||
|
|
||||||
CHANGES WITH 246 in spe:
|
CHANGES WITH 246 in spe:
|
||||||
|
|
||||||
|
* The various programs included in systemd can now optionally output
|
||||||
|
their log messages on stderr prefixed with a timestamp, controlled by
|
||||||
|
the $SYSTEMD_LOG_TIME environment variable.
|
||||||
|
|
||||||
|
* A new boolean kernel command line option systemd.swap= has been
|
||||||
|
added, which may be used to turn off automatic activation of swap
|
||||||
|
devices, as listed in /etc/fstab.
|
||||||
|
|
||||||
|
* The CPUAffinity= setting in service unit files now supports a new
|
||||||
|
special value "numa". If used, the NUMA mask is copied into the CPU
|
||||||
|
affinity mask.
|
||||||
|
|
||||||
|
* The man pages for the sd-bus and sd-hwdb APIs have been completed.
|
||||||
|
|
||||||
|
* networkctl gained the new "forcerenew" command for forcing all DHCP
|
||||||
|
server clients to renew their lease. The interface "status" output
|
||||||
|
will now show numerous additional fields of information about an
|
||||||
|
interface. There are new "up" and "down" commands to bring specific
|
||||||
|
interfaces up or down.
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
|
* systemd-networkd's [Network] section gained a new setting
|
||||||
|
IPv6PDSubnetId= that allows explicit configuration of the preferred
|
||||||
|
subnet that networkd's Prefix Delegation logic assigns to an
|
||||||
|
interfaces.
|
||||||
|
|
||||||
|
* systemd-networkd gained support for configuring the HTB queuing
|
||||||
|
discipline in the [HierarchyTokenBucket] and
|
||||||
|
[HierarchyTokenBucketClass] sections. Similar the "pfifo" qdisc may
|
||||||
|
be configured in the [PFIFO] section, "GRED" in
|
||||||
|
[GenericRandomEarlyDetection], "SFB" in [StochasticFairBlue], "cake"
|
||||||
|
in [CAKE], "PIE" in [PIE], "DRR" in [DeficitRoundRobinScheduler] and
|
||||||
|
[DeficitRoundRobinSchedulerClass], "BFIFO" in [BFIFO],
|
||||||
|
"PFIFOHeadDrop" in [PFIFOHeadDrop], "PFIFOFast" in [PFIFOFast] and
|
||||||
|
"HHF" in [HeavyHitterFilter].
|
||||||
|
|
||||||
|
* systemd-networkd gained support for a new Termination= setting in the
|
||||||
|
[CAN] section for configuring the termination resistor. It also
|
||||||
|
gained a new ListenOnly= setting for controlling whether to only
|
||||||
|
listen on CAN interfaces, without interfering with traffic otherwise
|
||||||
|
(which is useful for debugging/monitoring CAN network
|
||||||
|
traffic). DataBitRate=, DataSamplePoint=, FDMode=, FDNonISO= have
|
||||||
|
been added to configure various CAN-FD aspects.
|
||||||
|
|
||||||
|
* .link files managed by systemd-udevd gained options RxFlowControl=,
|
||||||
|
TxFlowControl=, AutoNegotiationFlowControl= in the [Link] section, in
|
||||||
|
order to configure various flow control parameters. They also gained
|
||||||
|
RxMiniBufferSize= and RxJumboBufferSize= in order to configure jumbo
|
||||||
|
frame ring buffer sizes.
|
||||||
|
|
||||||
|
* 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
|
||||||
|
DHCPv6Client= that may be used to turn off the DHCPv6 client even if
|
||||||
|
the RA packets suggest it.
|
||||||
|
|
||||||
|
* systemd-networkd's [DHCPv4] section gained a new setting UseGateway=
|
||||||
|
which may be used to turn off use of the gateway information provided
|
||||||
|
by the DHCP lease. A new FallbackLeaseLifetimeSec= setting may be
|
||||||
|
used to configure how to process leases that lack a lifetime option.
|
||||||
|
|
||||||
|
* systemd-networkd's [DHCPv4] and [DHCPServer] sections gained a new
|
||||||
|
setting SendVendorOption= allowing configuration of additional vendor
|
||||||
|
options to send in the DHCP requests/responses. The [DHCPv6] section
|
||||||
|
gained a new SendOption= setting for sending arbitrary DHCP
|
||||||
|
options. RequestOptions= has been added to request arbitrary options
|
||||||
|
from the server. UserClass= has been added to set the DHCP user class
|
||||||
|
field.
|
||||||
|
|
||||||
|
* systemd-networkd's [DHCPServer] section gained a new set of options
|
||||||
|
POP3Servers=, SMTPServers=, LPRServers= for including server
|
||||||
|
information about these three protocols in the DHCP lease. It also
|
||||||
|
gained support for including "MUD" URLs ("Manufacturer Usage
|
||||||
|
Description"). Support for "MUD" URLs was also added to the LLDP
|
||||||
|
stack, configurable in the [LLDP] section in .network files.
|
||||||
|
|
||||||
|
* systemd-resolved's DNS= configuration option now optionally accepts
|
||||||
|
DNS server addresses suffixed by "#" followed by a host name. If
|
||||||
|
used, the DNS-over-TLS certificate is validated to match the
|
||||||
|
specified hostname.
|
||||||
|
|
||||||
* The fs.suid_dumpable sysctl is set to 2 / "suidsafe". This allows
|
* The fs.suid_dumpable sysctl is set to 2 / "suidsafe". This allows
|
||||||
systemd-coredump to save core files for suid processes. When saving
|
systemd-coredump to save core files for suid processes. When saving
|
||||||
the core file, systemd-coredump will use the effective uid and gid of
|
the core file, systemd-coredump will use the effective uid and gid of
|
||||||
|
@ -14,6 +100,244 @@ CHANGES WITH 246 in spe:
|
||||||
can now be suspended or resumed either using new systemctl verbs,
|
can now be suspended or resumed either using new systemctl verbs,
|
||||||
freeze and thaw respectively, or via D-Bus.
|
freeze and thaw respectively, or via D-Bus.
|
||||||
|
|
||||||
|
* A new sd-path.h API has been added to libsystemd. It provides a
|
||||||
|
simple API for retrieving various search paths and primary
|
||||||
|
directories for various resources.
|
||||||
|
|
||||||
|
* The sd-bus API gained a number of convenience functions that take
|
||||||
|
va_list arguments rather than "...". For example, there's now
|
||||||
|
sd_bus_call_methodv() to match sd_bus_call_method(). Previously,
|
||||||
|
these were missing since the calls are convenience calls only and
|
||||||
|
could be put together from the more low-level functions they build
|
||||||
|
on.
|
||||||
|
|
||||||
|
* sd-bus vtable entries learnt a new flag SD_BUS_VTABLE_ABSOLUTE_OFFSET
|
||||||
|
which alters how the userdata pointer to pass to the callbacks is
|
||||||
|
determined. If the flag is set the offset field is converted as-is
|
||||||
|
into a pointer, without adding it to the object pointer the vtable is
|
||||||
|
associated with.
|
||||||
|
|
||||||
|
* sd-bus now exposed four new functions:
|
||||||
|
sd_bus_interface_name_is_valid() + sd_bus_service_name_is_valid() +
|
||||||
|
sd_bus_member_name_is_valid() + sd_bus_object_path_is_valid() will
|
||||||
|
validate strings to check if they qualify as various D-Bus concepts.
|
||||||
|
|
||||||
|
* systemctl gained a new "-P" switch that is a shortcut for "--value
|
||||||
|
--property=…".
|
||||||
|
|
||||||
|
* The expectations on user/group name syntax are now documented in
|
||||||
|
detail; documentation how classic home directories may be converted
|
||||||
|
into home directories managed by homed has been added; documentation
|
||||||
|
regarding integration of homed/userdb functionality in desktops has
|
||||||
|
been added:
|
||||||
|
|
||||||
|
https://systemd.io/USER_NAMES
|
||||||
|
https://systemd.io/CONVERTING_TO_HOMED
|
||||||
|
https://systemd.io/USERDB_AND_DESKTOPS
|
||||||
|
|
||||||
|
* systemd-run gained a new switch --slice-inherit. If specified the
|
||||||
|
unit it generates is placed in the same slice as the systemd-run
|
||||||
|
process itself.
|
||||||
|
|
||||||
|
* service unit files now accept a new setting CoredumpFilter= which
|
||||||
|
allows configuration of the memory sections coredumps of the
|
||||||
|
service's processes shall include.
|
||||||
|
|
||||||
|
* coredumpctl gained a new --file= switch, matching the same one in
|
||||||
|
journalctl: a specific journal file may be specified to read the
|
||||||
|
coredump data from.
|
||||||
|
|
||||||
|
* Various D-Bus APIs of systemd daemons now have man pages that
|
||||||
|
document the methods, signals and properties.
|
||||||
|
|
||||||
|
* journald.conf gained a new boolean setting Audit= that may be used to
|
||||||
|
control whether systemd-journald will enable audit during
|
||||||
|
initialization.
|
||||||
|
|
||||||
|
* A new default .network file is now shipped that matches TUN/TAP
|
||||||
|
devices that begin with "vt-" in their name. Such interfaces will
|
||||||
|
have IP routing onto the host links set up automatically. This is
|
||||||
|
supposed to be used by VM managers to trivially acquire a network
|
||||||
|
interface which is fully set up for host communication, simply by
|
||||||
|
carefully picking an interface name to use.
|
||||||
|
|
||||||
|
* All D-Bus services shipped in systemd now implement the generic
|
||||||
|
LogControl1 D-Bus API which allows clients to change log level +
|
||||||
|
target of the service during runtime.
|
||||||
|
|
||||||
|
* systemd-nspawn's --resolv-conf= switch gained a number of new
|
||||||
|
supported values. Specifically, options starting with "replace-" are
|
||||||
|
like those prefixed "copy-" but replace any existing resolv.conf
|
||||||
|
file. And options ending in "-uplink" and "-stub" can now be used to
|
||||||
|
propagate other flavours of resolv.conf into the container (as
|
||||||
|
defined by systemd-resolved).
|
||||||
|
|
||||||
|
* systemd-binfmt gained a new switch --unregister for unregistering all
|
||||||
|
registered entries at once. This is now invoked automatically at
|
||||||
|
shutdown, so that binary formats registered with the "F" flag will
|
||||||
|
not block clean file system unmounting.
|
||||||
|
|
||||||
|
* Unit files, tmpfiles.d/ snippets, sysusers.d/ snippets and other
|
||||||
|
configuration files that support specifier expansion learnt six new
|
||||||
|
specifiers: %a resolves to the current architecture, %o/%w/%B/%W
|
||||||
|
resolve to the various ID fields from /etc/os-release, %l resolves to
|
||||||
|
the "short" hostname of the system, i.e. the kernel configured
|
||||||
|
hostname, truncated at the first dot.
|
||||||
|
|
||||||
|
* systemd-notify's --pid= switch gained new values: "parent", "self",
|
||||||
|
"auto" for controlling which PID to send to the service managing: the
|
||||||
|
systemd-notify process' PID, or the one of the process invoking it.
|
||||||
|
|
||||||
|
* When sending a file descriptor (fd) to the service manager to keep
|
||||||
|
track of, using the sd_notify() mechanism, a new parameter FDPOLL=0
|
||||||
|
may be specified. If passed the service manager will refrain from
|
||||||
|
poll()ing on the file descriptor. Traditionally (and when the
|
||||||
|
parameter is not specified), the service manager will poll it for
|
||||||
|
POLLHUP or POLLERR events, and immediately close the fds in that
|
||||||
|
case.
|
||||||
|
|
||||||
|
* A new call sd_notify_barrier() has been added to the sd-daemon.h
|
||||||
|
API. The call will block until all previously sent sd_notify()
|
||||||
|
messages have been processed by the service manager. This is useful
|
||||||
|
to remove races caused by a process already having disappeared at the
|
||||||
|
time a notification message is processed by the service manager,
|
||||||
|
making correct attribution impossible. The systemd-notify tool will
|
||||||
|
now make use of this call implicitly, but this can be turned off again
|
||||||
|
via the new --no-block switch.
|
||||||
|
|
||||||
|
* systemd-logind's Session bus object learnt a new method call
|
||||||
|
SetType() for temporarily updating the session type of an already
|
||||||
|
allocated session. This is useful for upgrading tty sessions to
|
||||||
|
graphical ones once a compositor is invoked.
|
||||||
|
|
||||||
|
* .mount units gained a new ReadWriteOnly= boolean option. If set the
|
||||||
|
it will not be attempted to mount a file system read-only if mounting
|
||||||
|
it read-write mode doesn't succeed. An option x-systemd.rw-only is
|
||||||
|
available in /etc/fstab to control the same.
|
||||||
|
|
||||||
|
* coredumps collected by systemd-coredump may now be compressed using
|
||||||
|
the zstd algorithm.
|
||||||
|
|
||||||
|
* journalctl's "-o cat" output mode will now show one or more journal
|
||||||
|
fields specified with --output-fields= instead of unconditionally
|
||||||
|
MESSAGE=. This is useful to retrieve a very specific set of fields
|
||||||
|
without any decoration.
|
||||||
|
|
||||||
|
* systemd-socket-proxy gained a new switch --exit-idle-time= for
|
||||||
|
configuring an exit-on-idle time.
|
||||||
|
|
||||||
|
* systemd-homed's LUKS backend gained the ability to discard empty file
|
||||||
|
system blocks automatically when the user logs out. This is enabled
|
||||||
|
by default to ensure that home directories take minimal space when
|
||||||
|
logged out but get full size guarantees when logged in. This may be
|
||||||
|
controlled with the new --luks-offline-discard= switch to homectl.
|
||||||
|
|
||||||
|
* If systemd-homed detects that /home/ is encrypted as a whole it will
|
||||||
|
now default to the directory or subvolume backends instead of the
|
||||||
|
LUKS backend, in order to avoid double encryption. The default
|
||||||
|
storage and file system may now be configured explicitly, too, via
|
||||||
|
the new /etc/systemd/homed.conf configuration file.
|
||||||
|
|
||||||
|
* when systemd-journald's log stream is broken up into multiple lines
|
||||||
|
because the PID of the sender changed this is indicated in the
|
||||||
|
generated log records via the _LINE_BREAK=pid-change field.
|
||||||
|
|
||||||
|
* systemd-networkd's .netdev files now support a new setting
|
||||||
|
VLANProtocol= in the [Bridge] section that allows configuration of
|
||||||
|
the VLAN protocol to use.
|
||||||
|
|
||||||
|
* systemd-repart's --empty= setting gained a new value "create". If
|
||||||
|
specified a new empty regular disk image file is created under the
|
||||||
|
specified name. It's size may be specified with the new --size=
|
||||||
|
option. The latter is also supported without the "create" mode, in
|
||||||
|
order to grow existing disk image files to the specified size. These
|
||||||
|
two new options make are useful when creating or manipulating
|
||||||
|
disk images instead of operating on actual block devices.
|
||||||
|
|
||||||
|
* systemd-repart drop-ins now support a new UUID= setting to control
|
||||||
|
the UUID to assign to a newly created partition.
|
||||||
|
|
||||||
|
* StandardError= and StandardOutput= in unit files no longer support
|
||||||
|
the "syslog" and "syslog-console" switches. They were long removed
|
||||||
|
from the documentation, but will now result in warnings when used,
|
||||||
|
and be converted to "journal" and "journal+console" automatically.
|
||||||
|
|
||||||
|
* systemd-networkd supports a new Group= setting in the [Link] section
|
||||||
|
of the .network files, to control the link group.
|
||||||
|
|
||||||
|
* Two new unit file settings
|
||||||
|
ConditionPathIsEncrypted=/AssertPathIsEncrypted= have been
|
||||||
|
added. They may be used to check whether a specific file system path
|
||||||
|
resides on a block device that is encrypted on the block level
|
||||||
|
(i.e. using dm-crypt/LUKS).
|
||||||
|
|
||||||
|
* Another pair of new settings ConditionEnvironment=/AssertEnvironment=
|
||||||
|
has been added that may be used for simple environment checks. This
|
||||||
|
is particularly useful when passing in environment variables from a
|
||||||
|
container manager (or from PAM in case of the systemd --user
|
||||||
|
instance).
|
||||||
|
|
||||||
|
* The /sys/module/kernel/parameters/crash_kexec_post_notifiers file is
|
||||||
|
not automatically set to "Y" at boot, in order to enable pstore
|
||||||
|
generation for collection with systemd-pstore.
|
||||||
|
|
||||||
|
* New kernel command line options systemd.condition-needs-update= and
|
||||||
|
systemd.condition-first-boot= have been added, which override the
|
||||||
|
result of the ConditionNeedsUpdate= and ConditionFirstBoot=
|
||||||
|
conditions.
|
||||||
|
|
||||||
|
* A new kernel command line option systemd.clock-usec= has been added
|
||||||
|
that allows setting the system clock to the specified time in µs
|
||||||
|
since Jan 1st, 1970 early during boot. This is in particular useful
|
||||||
|
in order to make test cases more reliable.
|
||||||
|
|
||||||
|
* A new kernel command line option systemd.hostname= has been added
|
||||||
|
that allows controlling the hostname that is initialized early during
|
||||||
|
boot.
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
|
* There's a new /etc/crypttab option "keyfile-erase". If specified the
|
||||||
|
key file listed in the same line is removed after use, regardless if
|
||||||
|
volume activation was successful or not. This is useful if the key
|
||||||
|
file is only acquired transiently at runtime and shall be erased
|
||||||
|
before the system continues to boot.
|
||||||
|
|
||||||
|
* There's also a new /etc/crypttab option "try-empty-password". If
|
||||||
|
specified, before asking the user for a password it is attempted to
|
||||||
|
unlock the volume with an empty password. This is useful for
|
||||||
|
installing encrypted images whose password shall be set on first boot
|
||||||
|
instead of at installation time.
|
||||||
|
|
||||||
|
* systemd-cryptsetup will now attempt to load the keys to unlock
|
||||||
|
volumes with automatically from files in
|
||||||
|
/etc/cryptsetup-keys.d/<volume>.key and
|
||||||
|
/run/cryptsetup-keys.d/<volume>.key, if any of these files exist.
|
||||||
|
|
||||||
|
* logind.conf gained a new RuntimeDirectoryInodesMax= setting to
|
||||||
|
control the inode limit for the per-user $XDG_RUNTIME_DIR tmpfs
|
||||||
|
instance.
|
||||||
|
|
||||||
|
* systemd-firstboot gained a new --root-password-hashed= parameter for
|
||||||
|
setting the root user's password as UNIX password hash. There's a new
|
||||||
|
--delete-root-password switch which instead of setting a password for
|
||||||
|
the root user, removes it so that log-in without a password is
|
||||||
|
permitted. There's now --force which if specified means any existing
|
||||||
|
configuration is overwritten by the specified settings. It also
|
||||||
|
gained a new --kernel-command-line= parameter which may be used to
|
||||||
|
set the /etc/kernel/cmdline file of an OS image.
|
||||||
|
|
||||||
|
* A new generator systemd-xdg-autostart-generator has been added. It
|
||||||
|
automatically generates systemd unit files from XDG autostart
|
||||||
|
.desktop files, and is useful for allowing systemd to manage services
|
||||||
|
defined that way safely and automatically.
|
||||||
|
|
||||||
|
* systemd will now log about all left-over processes remaining in a
|
||||||
|
unit when the unit is stopped. It will now warn about services using
|
||||||
|
KillMode=none, as this is generally an unsafe thing to make use of.
|
||||||
|
|
||||||
CHANGES WITH 245:
|
CHANGES WITH 245:
|
||||||
|
|
||||||
* A new tool "systemd-repart" has been added, that operates as an
|
* A new tool "systemd-repart" has been added, that operates as an
|
||||||
|
|
3
TODO
3
TODO
|
@ -48,6 +48,9 @@ Features:
|
||||||
* pid1: also remove PID files of a service when the service starts, not just
|
* pid1: also remove PID files of a service when the service starts, not just
|
||||||
when it exits
|
when it exits
|
||||||
|
|
||||||
|
* systemd-path: add ESP and XBOOTLDR path. Add "private" runtime/state/cache dir enum,
|
||||||
|
mapping to $RUNTIME_DIRECTORY, $STATE_DIRECTORY and such
|
||||||
|
|
||||||
* make "systemd-dissect" an official supported tool, i.e. move to /usr/bin/ and
|
* make "systemd-dissect" an official supported tool, i.e. move to /usr/bin/ and
|
||||||
provide man page. Given that we now have a tool that can generate images like
|
provide man page. Given that we now have a tool that can generate images like
|
||||||
this, it's useful to have one that can dump contents of them, too.
|
this, it's useful to have one that can dump contents of them, too.
|
||||||
|
|
|
@ -435,3 +435,34 @@ hyphen and otherwise fully numeric.
|
||||||
For further details on strict and relaxed user/group name rules, see:
|
For further details on strict and relaxed user/group name rules, see:
|
||||||
|
|
||||||
https://systemd.io/USER_NAMES
|
https://systemd.io/USER_NAMES
|
||||||
|
|
||||||
|
-- 1b3bb94037f04bbf81028e135a12d293
|
||||||
|
Subject: Failed to generate valid unit name from path '@MOUNT_POINT@'.
|
||||||
|
Defined-By: systemd
|
||||||
|
Support: %SUPPORT_URL%
|
||||||
|
|
||||||
|
The following mount point path could not be converted into a valid .mount
|
||||||
|
unit name:
|
||||||
|
|
||||||
|
@MOUNT_POINT@
|
||||||
|
|
||||||
|
Typically this means that the path to the mount point is longer than allowed
|
||||||
|
for valid unit names.
|
||||||
|
|
||||||
|
systemd dynamically synthesizes .mount units for all mount points appearing on
|
||||||
|
the system. For that a simple escaping algorithm is applied: the absolute path
|
||||||
|
name is used, with all "/" characters replaced by "-" (the leading one is
|
||||||
|
removed). Moreover, any non-alphanumeric characters (as well as any of ":",
|
||||||
|
"-", "_", ".", "\") are replaced by "\xNN" where "NN" is the hexadecimal code
|
||||||
|
of the character. Finally, ".mount" is suffixed. The resulting string must be
|
||||||
|
under 256 characters in length to be a valid unit name. This restriction is
|
||||||
|
made in order for all unit names to also be suitable as file names. If a mount
|
||||||
|
point appears that — after escaping — is longer than this limit it cannot be
|
||||||
|
mapped to a unit. In this case systemd will refrain from synthesizing a unit
|
||||||
|
and cannot be used to manage the mount point. It will not appear in the service
|
||||||
|
manager's unit table and thus also not be torn down safely and automatically at
|
||||||
|
system shutdown.
|
||||||
|
|
||||||
|
It is generally recommended to avoid such overly long mount point paths, or —
|
||||||
|
if used anyway – manage them independently of systemd, i.e. establish them as
|
||||||
|
well as tear them down automatically at system shutdown by other software.
|
||||||
|
|
|
@ -429,6 +429,7 @@ Most socket unit settings are available to transient units.
|
||||||
✓ Broadcast=
|
✓ Broadcast=
|
||||||
✓ PassCredentials=
|
✓ PassCredentials=
|
||||||
✓ PassSecurity=
|
✓ PassSecurity=
|
||||||
|
✓ PassPacketInfo=
|
||||||
✓ TCPCongestion=
|
✓ TCPCongestion=
|
||||||
✓ ReusePort=
|
✓ ReusePort=
|
||||||
✓ MessageQueueMaxMessages=
|
✓ MessageQueueMaxMessages=
|
||||||
|
|
|
@ -198,7 +198,7 @@ sensor:modalias:acpi:BOSC0200*:dmi:bvnAmericanMegatrendsInc.:bvr5.11:bd05/28/201
|
||||||
|
|
||||||
# Chuwi HiBook Pro (CWI526)
|
# Chuwi HiBook Pro (CWI526)
|
||||||
sensor:modalias:acpi:BOSC0200*:dmi:*:svnHampoo*:pnP1D6_C109K:*
|
sensor:modalias:acpi:BOSC0200*:dmi:*:svnHampoo*:pnP1D6_C109K:*
|
||||||
ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1
|
ACCEL_MOUNT_MATRIX=1, 0, 0; 0, -1, 0; 0, 0, 1
|
||||||
|
|
||||||
# Chuwi CoreBook
|
# Chuwi CoreBook
|
||||||
# Chuwi CoreBook does not have its product name filled, so we
|
# Chuwi CoreBook does not have its product name filled, so we
|
||||||
|
|
|
@ -76,30 +76,30 @@
|
||||||
<constant>SD_PATH_SEARCH_STATE_FACTORY</constant>,
|
<constant>SD_PATH_SEARCH_STATE_FACTORY</constant>,
|
||||||
<constant>SD_PATH_SEARCH_CONFIGURATION</constant>,
|
<constant>SD_PATH_SEARCH_CONFIGURATION</constant>,
|
||||||
|
|
||||||
<constant>SD_PATH_SYSTEMD_UTIL_DIR</constant>,
|
<constant>SD_PATH_SYSTEMD_UTIL</constant>,
|
||||||
<constant>SD_PATH_SYSTEMD_SYSTEM_UNIT_DIR</constant>,
|
<constant>SD_PATH_SYSTEMD_SYSTEM_UNIT</constant>,
|
||||||
<constant>SD_PATH_SYSTEMD_SYSTEM_PRESET_DIR</constant>,
|
<constant>SD_PATH_SYSTEMD_SYSTEM_PRESET</constant>,
|
||||||
<constant>SD_PATH_SYSTEMD_USER_UNIT_DIR</constant>,
|
<constant>SD_PATH_SYSTEMD_USER_UNIT</constant>,
|
||||||
<constant>SD_PATH_SYSTEMD_USER_PRESET_DIR</constant>,
|
<constant>SD_PATH_SYSTEMD_USER_PRESET</constant>,
|
||||||
<constant>SD_PATH_SYSTEMD_SYSTEM_CONF_DIR</constant>,
|
<constant>SD_PATH_SYSTEMD_SYSTEM_CONF</constant>,
|
||||||
<constant>SD_PATH_SYSTEMD_USER_CONF_DIR</constant>,
|
<constant>SD_PATH_SYSTEMD_USER_CONF</constant>,
|
||||||
<constant>SD_PATH_SYSTEMD_SYSTEM_UNIT_PATH</constant>,
|
<constant>SD_PATH_SYSTEMD_SEARCH_SYSTEM_UNIT</constant>,
|
||||||
<constant>SD_PATH_SYSTEMD_USER_UNIT_PATH</constant>,
|
<constant>SD_PATH_SYSTEMD_SEARCH_USER_UNIT</constant>,
|
||||||
<constant>SD_PATH_SYSTEMD_SYSTEM_GENERATOR_DIR</constant>,
|
<constant>SD_PATH_SYSTEMD_SYSTEM_GENERATOR</constant>,
|
||||||
<constant>SD_PATH_SYSTEMD_USER_GENERATOR_DIR</constant>,
|
<constant>SD_PATH_SYSTEMD_USER_GENERATOR</constant>,
|
||||||
<constant>SD_PATH_SYSTEMD_SYSTEM_GENERATOR_PATH</constant>,
|
<constant>SD_PATH_SYSTEMD_SEARCH_SYSTEM_GENERATOR</constant>,
|
||||||
<constant>SD_PATH_SYSTEMD_USER_GENERATOR_PATH</constant>,
|
<constant>SD_PATH_SYSTEMD_SEARCH_USER_GENERATOR</constant>,
|
||||||
<constant>SD_PATH_SYSTEMD_SLEEP_DIR</constant>,
|
<constant>SD_PATH_SYSTEMD_SLEEP</constant>,
|
||||||
<constant>SD_PATH_SYSTEMD_SHUTDOWN_DIR</constant>,
|
<constant>SD_PATH_SYSTEMD_SHUTDOWN</constant>,
|
||||||
|
|
||||||
<constant>SD_PATH_TMPFILES_DIR</constant>,
|
<constant>SD_PATH_TMPFILES</constant>,
|
||||||
<constant>SD_PATH_SYSUSERS_DIR</constant>,
|
<constant>SD_PATH_SYSUSERS</constant>,
|
||||||
<constant>SD_PATH_SYSCTL_DIR</constant>,
|
<constant>SD_PATH_SYSCTL</constant>,
|
||||||
<constant>SD_PATH_BINFMT_DIR</constant>,
|
<constant>SD_PATH_BINFMT</constant>,
|
||||||
<constant>SD_PATH_MODULES_LOAD_DIR</constant>,
|
<constant>SD_PATH_MODULES_LOAD</constant>,
|
||||||
<constant>SD_PATH_CATALOG_DIR</constant>,
|
<constant>SD_PATH_CATALOG</constant>,
|
||||||
|
|
||||||
<constant>SD_PATH_SYSTEMD_NETWORK_PATH</constant>,
|
<constant>SD_PATH_SYSTEMD_SEARCH_NETWORK</constant>,
|
||||||
};</funcsynopsisinfo>
|
};</funcsynopsisinfo>
|
||||||
|
|
||||||
<funcprototype>
|
<funcprototype>
|
||||||
|
|
|
@ -838,15 +838,17 @@
|
||||||
<term><varname>ConfigureWithoutCarrier=</varname></term>
|
<term><varname>ConfigureWithoutCarrier=</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Takes a boolean. Allows networkd to configure a specific link even if it has no carrier.
|
<para>Takes a boolean. Allows networkd to configure a specific link even if it has no carrier.
|
||||||
Defaults to false.
|
Defaults to false. If <option>IgnoreCarrierLoss=</option> is not explicitly set, it will
|
||||||
|
default to this value.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>IgnoreCarrierLoss=</varname></term>
|
<term><varname>IgnoreCarrierLoss=</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>A boolean. Allows networkd to retain both the static and dynamic configuration of the
|
<para>Takes a boolean. Allows networkd to retain both the static and dynamic configuration
|
||||||
interface even if its carrier is lost. Defaults to false.
|
of the interface even if its carrier is lost. When unset, the value specified with
|
||||||
|
<option>ConfigureWithoutCarrier=</option> is used.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
@ -1779,6 +1781,15 @@
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>AssignAcquiredDelegatedPrefixAddress=</varname></term>
|
||||||
|
<listitem>
|
||||||
|
<para>Takes a boolean. Specifies whether to add an address from the delegated prefixes which are received
|
||||||
|
from the WAN interface by the <varname>IPv6PrefixDelegation=</varname>. When true (on LAN interfce), the EUI-64
|
||||||
|
algorithm will be used to form an interface identifier from the delegated prefixes. Defaults to true.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>PrefixDelegationHint=</varname></term>
|
<term><varname>PrefixDelegationHint=</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
|
@ -3299,7 +3310,10 @@ DHCP=ipv6</programlisting>
|
||||||
Name=enp2s0
|
Name=enp2s0
|
||||||
|
|
||||||
[Network]
|
[Network]
|
||||||
IPv6PrefixDelegation=dhcpv6</programlisting>
|
IPv6PrefixDelegation=dhcpv6
|
||||||
|
|
||||||
|
[DHCPv6]
|
||||||
|
AssignAcquiredDelegatedPrefixAddress=yes</programlisting>
|
||||||
|
|
||||||
<para>This will enable IPv6 PD on the interface enp1s0 as an upstream interface where the
|
<para>This will enable IPv6 PD on the interface enp1s0 as an upstream interface where the
|
||||||
DHCPv6 client is running and enp2s0 as a downstream interface where the prefix is delegated to.</para>
|
DHCPv6 client is running and enp2s0 as a downstream interface where the prefix is delegated to.</para>
|
||||||
|
|
|
@ -709,6 +709,15 @@
|
||||||
Defaults to <option>false</option>.</para></listitem>
|
Defaults to <option>false</option>.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>PassPacketInfo=</varname></term>
|
||||||
|
<listitem><para>Takes a boolean value. This controls the <constant>IP_PKTINFO</constant>,
|
||||||
|
<constant>IPV6_RECVPKTINFO</constant> and <constant>NETLINK_PKTINFO</constant> socket options, which
|
||||||
|
enable reception of additional per-packet metadata as ancillary message, on
|
||||||
|
<constant>AF_INET</constant>, <constant>AF_INET6</constant> and <constant>AF_UNIX</constant> sockets.
|
||||||
|
Defaults to <option>false</option>.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>TCPCongestion=</varname></term>
|
<term><varname>TCPCongestion=</varname></term>
|
||||||
<listitem><para>Takes a string value. Controls the TCP
|
<listitem><para>Takes a string value. Controls the TCP
|
||||||
|
|
|
@ -62,3 +62,8 @@ struct sockaddr_vm {
|
||||||
#ifndef IP_TRANSPARENT
|
#ifndef IP_TRANSPARENT
|
||||||
#define IP_TRANSPARENT 19
|
#define IP_TRANSPARENT 19
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* linux/sockios.h */
|
||||||
|
#ifndef SIOCGSKNS
|
||||||
|
#define SIOCGSKNS 0x894C
|
||||||
|
#endif
|
||||||
|
|
|
@ -1174,5 +1174,27 @@ ssize_t recvmsg_safe(int sockfd, struct msghdr *msg, int flags) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
int socket_pass_pktinfo(int fd, bool b) {
|
||||||
|
int af;
|
||||||
|
socklen_t sl = sizeof(af);
|
||||||
|
|
||||||
|
if (getsockopt(fd, SOL_SOCKET, SO_DOMAIN, &af, &sl) < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
switch (af) {
|
||||||
|
|
||||||
|
case AF_INET:
|
||||||
|
return setsockopt_int(fd, IPPROTO_IP, IP_PKTINFO, b);
|
||||||
|
|
||||||
|
case AF_INET6:
|
||||||
|
return setsockopt_int(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, b);
|
||||||
|
|
||||||
|
case AF_NETLINK:
|
||||||
|
return setsockopt_int(fd, SOL_NETLINK, NETLINK_PKTINFO, b);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -EAFNOSUPPORT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -220,3 +220,5 @@ int socket_bind_to_ifname(int fd, const char *ifname);
|
||||||
int socket_bind_to_ifindex(int fd, int ifindex);
|
int socket_bind_to_ifindex(int fd, int ifindex);
|
||||||
|
|
||||||
ssize_t recvmsg_safe(int sockfd, struct msghdr *msg, int flags);
|
ssize_t recvmsg_safe(int sockfd, struct msghdr *msg, int flags);
|
||||||
|
|
||||||
|
int socket_pass_pktinfo(int fd, bool b);
|
||||||
|
|
|
@ -207,8 +207,9 @@ UnitType unit_name_to_type(const char *n) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int unit_name_change_suffix(const char *n, const char *suffix, char **ret) {
|
int unit_name_change_suffix(const char *n, const char *suffix, char **ret) {
|
||||||
char *e, *s;
|
_cleanup_free_ char *s = NULL;
|
||||||
size_t a, b;
|
size_t a, b;
|
||||||
|
char *e;
|
||||||
|
|
||||||
assert(n);
|
assert(n);
|
||||||
assert(suffix);
|
assert(suffix);
|
||||||
|
@ -230,8 +231,12 @@ int unit_name_change_suffix(const char *n, const char *suffix, char **ret) {
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
strcpy(mempcpy(s, n, a), suffix);
|
strcpy(mempcpy(s, n, a), suffix);
|
||||||
*ret = s;
|
|
||||||
|
|
||||||
|
/* Make sure the name is still valid (i.e. didn't grow too large due to longer suffix) */
|
||||||
|
if (!unit_name_is_valid(s, UNIT_NAME_ANY))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
*ret = TAKE_PTR(s);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,8 +258,8 @@ int unit_name_build(const char *prefix, const char *instance, const char *suffix
|
||||||
}
|
}
|
||||||
|
|
||||||
int unit_name_build_from_type(const char *prefix, const char *instance, UnitType type, char **ret) {
|
int unit_name_build_from_type(const char *prefix, const char *instance, UnitType type, char **ret) {
|
||||||
|
_cleanup_free_ char *s = NULL;
|
||||||
const char *ut;
|
const char *ut;
|
||||||
char *s;
|
|
||||||
|
|
||||||
assert(prefix);
|
assert(prefix);
|
||||||
assert(type >= 0);
|
assert(type >= 0);
|
||||||
|
@ -264,19 +269,23 @@ int unit_name_build_from_type(const char *prefix, const char *instance, UnitType
|
||||||
if (!unit_prefix_is_valid(prefix))
|
if (!unit_prefix_is_valid(prefix))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (instance && !unit_instance_is_valid(instance))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
ut = unit_type_to_string(type);
|
ut = unit_type_to_string(type);
|
||||||
|
|
||||||
if (!instance)
|
if (instance) {
|
||||||
s = strjoin(prefix, ".", ut);
|
if (!unit_instance_is_valid(instance))
|
||||||
else
|
return -EINVAL;
|
||||||
|
|
||||||
s = strjoin(prefix, "@", instance, ".", ut);
|
s = strjoin(prefix, "@", instance, ".", ut);
|
||||||
|
} else
|
||||||
|
s = strjoin(prefix, ".", ut);
|
||||||
if (!s)
|
if (!s)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
*ret = s;
|
/* Verify that this didn't grow too large (or otherwise is invalid) */
|
||||||
|
if (!unit_name_is_valid(s, instance ? UNIT_NAME_INSTANCE : UNIT_NAME_PLAIN))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
*ret = TAKE_PTR(s);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,8 +450,8 @@ int unit_name_path_unescape(const char *f, char **ret) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int unit_name_replace_instance(const char *f, const char *i, char **ret) {
|
int unit_name_replace_instance(const char *f, const char *i, char **ret) {
|
||||||
|
_cleanup_free_ char *s = NULL;
|
||||||
const char *p, *e;
|
const char *p, *e;
|
||||||
char *s;
|
|
||||||
size_t a, b;
|
size_t a, b;
|
||||||
|
|
||||||
assert(f);
|
assert(f);
|
||||||
|
@ -466,7 +475,11 @@ int unit_name_replace_instance(const char *f, const char *i, char **ret) {
|
||||||
|
|
||||||
strcpy(mempcpy(mempcpy(s, f, a + 1), i, b), e);
|
strcpy(mempcpy(mempcpy(s, f, a + 1), i, b), e);
|
||||||
|
|
||||||
*ret = s;
|
/* Make sure the resulting name still is valid, i.e. didn't grow too large */
|
||||||
|
if (!unit_name_is_valid(s, UNIT_NAME_INSTANCE))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
*ret = TAKE_PTR(s);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -497,8 +510,7 @@ int unit_name_template(const char *f, char **ret) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int unit_name_from_path(const char *path, const char *suffix, char **ret) {
|
int unit_name_from_path(const char *path, const char *suffix, char **ret) {
|
||||||
_cleanup_free_ char *p = NULL;
|
_cleanup_free_ char *p = NULL, *s = NULL;
|
||||||
char *s = NULL;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(path);
|
assert(path);
|
||||||
|
@ -516,7 +528,11 @@ int unit_name_from_path(const char *path, const char *suffix, char **ret) {
|
||||||
if (!s)
|
if (!s)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
*ret = s;
|
/* Refuse this if this got too long or for some other reason didn't result in a valid name */
|
||||||
|
if (!unit_name_is_valid(s, UNIT_NAME_PLAIN))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
*ret = TAKE_PTR(s);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -544,6 +560,10 @@ int unit_name_from_path_instance(const char *prefix, const char *path, const cha
|
||||||
if (!s)
|
if (!s)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
/* Refuse this if this got too long or for some other reason didn't result in a valid name */
|
||||||
|
if (!unit_name_is_valid(s, UNIT_NAME_INSTANCE))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
*ret = s;
|
*ret = s;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -597,9 +617,9 @@ static bool do_escape_mangle(const char *f, bool allow_globs, char *t) {
|
||||||
* If @allow_globs, globs characters are preserved. Otherwise, they are escaped.
|
* If @allow_globs, globs characters are preserved. Otherwise, they are escaped.
|
||||||
*/
|
*/
|
||||||
int unit_name_mangle_with_suffix(const char *name, const char *operation, UnitNameMangle flags, const char *suffix, char **ret) {
|
int unit_name_mangle_with_suffix(const char *name, const char *operation, UnitNameMangle flags, const char *suffix, char **ret) {
|
||||||
char *s;
|
_cleanup_free_ char *s = NULL;
|
||||||
int r;
|
|
||||||
bool mangled, suggest_escape = true;
|
bool mangled, suggest_escape = true;
|
||||||
|
int r;
|
||||||
|
|
||||||
assert(name);
|
assert(name);
|
||||||
assert(suffix);
|
assert(suffix);
|
||||||
|
@ -657,7 +677,12 @@ int unit_name_mangle_with_suffix(const char *name, const char *operation, UnitNa
|
||||||
if ((!(flags & UNIT_NAME_MANGLE_GLOB) || !string_is_glob(s)) && unit_name_to_type(s) < 0)
|
if ((!(flags & UNIT_NAME_MANGLE_GLOB) || !string_is_glob(s)) && unit_name_to_type(s) < 0)
|
||||||
strcat(s, suffix);
|
strcat(s, suffix);
|
||||||
|
|
||||||
*ret = s;
|
/* Make sure mangling didn't grow this too large (but don't do this check if globbing is allowed,
|
||||||
|
* since globs generally do not qualify as valid unit names) */
|
||||||
|
if (!FLAGS_SET(flags, UNIT_NAME_MANGLE_GLOB) && !unit_name_is_valid(s, UNIT_NAME_ANY))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
*ret = TAKE_PTR(s);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
good:
|
good:
|
||||||
|
@ -665,12 +690,13 @@ good:
|
||||||
if (!s)
|
if (!s)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
*ret = s;
|
*ret = TAKE_PTR(s);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int slice_build_parent_slice(const char *slice, char **ret) {
|
int slice_build_parent_slice(const char *slice, char **ret) {
|
||||||
char *s, *dash;
|
_cleanup_free_ char *s = NULL;
|
||||||
|
char *dash;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(slice);
|
assert(slice);
|
||||||
|
@ -693,13 +719,11 @@ int slice_build_parent_slice(const char *slice, char **ret) {
|
||||||
strcpy(dash, ".slice");
|
strcpy(dash, ".slice");
|
||||||
else {
|
else {
|
||||||
r = free_and_strdup(&s, SPECIAL_ROOT_SLICE);
|
r = free_and_strdup(&s, SPECIAL_ROOT_SLICE);
|
||||||
if (r < 0) {
|
if (r < 0)
|
||||||
free(s);
|
|
||||||
return r;
|
return r;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*ret = s;
|
*ret = TAKE_PTR(s);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -104,6 +104,7 @@ const sd_bus_vtable bus_socket_vtable[] = {
|
||||||
SD_BUS_PROPERTY("Broadcast", "b", bus_property_get_bool, offsetof(Socket, broadcast), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("Broadcast", "b", bus_property_get_bool, offsetof(Socket, broadcast), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("PassCredentials", "b", bus_property_get_bool, offsetof(Socket, pass_cred), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("PassCredentials", "b", bus_property_get_bool, offsetof(Socket, pass_cred), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("PassSecurity", "b", bus_property_get_bool, offsetof(Socket, pass_sec), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("PassSecurity", "b", bus_property_get_bool, offsetof(Socket, pass_sec), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
SD_BUS_PROPERTY("PassPacketInfo", "b", bus_property_get_bool, offsetof(Socket, pass_pktinfo), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("RemoveOnStop", "b", bus_property_get_bool, offsetof(Socket, remove_on_stop), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("RemoveOnStop", "b", bus_property_get_bool, offsetof(Socket, remove_on_stop), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("Listen", "a(ss)", property_get_listen, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("Listen", "a(ss)", property_get_listen, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("Symlinks", "as", NULL, offsetof(Socket, symlinks), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("Symlinks", "as", NULL, offsetof(Socket, symlinks), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
@ -202,6 +203,9 @@ static int bus_socket_set_transient_property(
|
||||||
if (streq(name, "PassSecurity"))
|
if (streq(name, "PassSecurity"))
|
||||||
return bus_set_transient_bool(u, name, &s->pass_sec, message, flags, error);
|
return bus_set_transient_bool(u, name, &s->pass_sec, message, flags, error);
|
||||||
|
|
||||||
|
if (streq(name, "PassPacketInfo"))
|
||||||
|
return bus_set_transient_bool(u, name, &s->pass_pktinfo, message, flags, error);
|
||||||
|
|
||||||
if (streq(name, "ReusePort"))
|
if (streq(name, "ReusePort"))
|
||||||
return bus_set_transient_bool(u, name, &s->reuse_port, message, flags, error);
|
return bus_set_transient_bool(u, name, &s->reuse_port, message, flags, error);
|
||||||
|
|
||||||
|
|
|
@ -396,6 +396,7 @@ Socket.Transparent, config_parse_bool, 0,
|
||||||
Socket.Broadcast, config_parse_bool, 0, offsetof(Socket, broadcast)
|
Socket.Broadcast, config_parse_bool, 0, offsetof(Socket, broadcast)
|
||||||
Socket.PassCredentials, config_parse_bool, 0, offsetof(Socket, pass_cred)
|
Socket.PassCredentials, config_parse_bool, 0, offsetof(Socket, pass_cred)
|
||||||
Socket.PassSecurity, config_parse_bool, 0, offsetof(Socket, pass_sec)
|
Socket.PassSecurity, config_parse_bool, 0, offsetof(Socket, pass_sec)
|
||||||
|
Socket.PassPacketInfo, config_parse_bool, 0, offsetof(Socket, pass_pktinfo)
|
||||||
Socket.TCPCongestion, config_parse_string, 0, offsetof(Socket, tcp_congestion)
|
Socket.TCPCongestion, config_parse_string, 0, offsetof(Socket, tcp_congestion)
|
||||||
Socket.ReusePort, config_parse_bool, 0, offsetof(Socket, reuse_port)
|
Socket.ReusePort, config_parse_bool, 0, offsetof(Socket, reuse_port)
|
||||||
Socket.MessageQueueMaxMessages, config_parse_long, 0, offsetof(Socket, mq_maxmsg)
|
Socket.MessageQueueMaxMessages, config_parse_long, 0, offsetof(Socket, mq_maxmsg)
|
||||||
|
|
|
@ -1674,9 +1674,30 @@ static int mount_setup_unit(
|
||||||
if (!is_path(where))
|
if (!is_path(where))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/* Mount unit names have to be (like all other unit names) short enough to fit into file names. This
|
||||||
|
* means there's a good chance that overly long mount point paths after mangling them to look like a
|
||||||
|
* unit name would result in unit names we don't actually consider valid. This should be OK however
|
||||||
|
* as such long mount point paths should not happen on regular systems — and if they appear
|
||||||
|
* nonetheless they are generally synthesized by software, and thus managed by that other
|
||||||
|
* software. Having such long names just means you cannot use systemd to manage those specific mount
|
||||||
|
* points, which should be an OK restriction to make. After all we don't have to be able to manage
|
||||||
|
* all mount points in the world — as long as we don't choke on them when we encounter them. */
|
||||||
r = unit_name_from_path(where, ".mount", &e);
|
r = unit_name_from_path(where, ".mount", &e);
|
||||||
if (r < 0)
|
if (r < 0) {
|
||||||
return log_error_errno(r, "Failed to generate unit name from path '%s': %m", where);
|
static RateLimit rate_limit = { /* Let's log about this at warning level at most once every
|
||||||
|
* 5s. Given that we generate this whenever we read the file
|
||||||
|
* otherwise we probably shouldn't flood the logs with
|
||||||
|
* this */
|
||||||
|
.interval = 5 * USEC_PER_SEC,
|
||||||
|
.burst = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
return log_struct_errno(
|
||||||
|
ratelimit_below(&rate_limit) ? LOG_WARNING : LOG_DEBUG, r,
|
||||||
|
"MESSAGE_ID=" SD_MESSAGE_MOUNT_POINT_PATH_NOT_SUITABLE_STR,
|
||||||
|
"MOUNT_POINT=%s", where,
|
||||||
|
LOG_MESSAGE("Failed to generate valid unit name from path '%s', ignoring mount point: %m", where));
|
||||||
|
}
|
||||||
|
|
||||||
u = manager_get_unit(m, e);
|
u = manager_get_unit(m, e);
|
||||||
if (u)
|
if (u)
|
||||||
|
@ -1686,7 +1707,7 @@ static int mount_setup_unit(
|
||||||
* by the sysadmin having called mount(8) directly. */
|
* by the sysadmin having called mount(8) directly. */
|
||||||
r = mount_setup_new_unit(m, e, what, where, options, fstype, &flags, &u);
|
r = mount_setup_new_unit(m, e, what, where, options, fstype, &flags, &u);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_warning_errno(r, "Failed to set up mount unit: %m");
|
return log_warning_errno(r, "Failed to set up mount unit for '%s': %m", where);
|
||||||
|
|
||||||
/* If the mount changed properties or state, let's notify our clients */
|
/* If the mount changed properties or state, let's notify our clients */
|
||||||
if (flags & (MOUNT_PROC_JUST_CHANGED|MOUNT_PROC_JUST_MOUNTED))
|
if (flags & (MOUNT_PROC_JUST_CHANGED|MOUNT_PROC_JUST_MOUNTED))
|
||||||
|
|
|
@ -635,6 +635,7 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
|
||||||
"%sBroadcast: %s\n"
|
"%sBroadcast: %s\n"
|
||||||
"%sPassCredentials: %s\n"
|
"%sPassCredentials: %s\n"
|
||||||
"%sPassSecurity: %s\n"
|
"%sPassSecurity: %s\n"
|
||||||
|
"%sPassPacketInfo: %s\n"
|
||||||
"%sTCPCongestion: %s\n"
|
"%sTCPCongestion: %s\n"
|
||||||
"%sRemoveOnStop: %s\n"
|
"%sRemoveOnStop: %s\n"
|
||||||
"%sWritable: %s\n"
|
"%sWritable: %s\n"
|
||||||
|
@ -654,6 +655,7 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
|
||||||
prefix, yes_no(s->broadcast),
|
prefix, yes_no(s->broadcast),
|
||||||
prefix, yes_no(s->pass_cred),
|
prefix, yes_no(s->pass_cred),
|
||||||
prefix, yes_no(s->pass_sec),
|
prefix, yes_no(s->pass_sec),
|
||||||
|
prefix, yes_no(s->pass_pktinfo),
|
||||||
prefix, strna(s->tcp_congestion),
|
prefix, strna(s->tcp_congestion),
|
||||||
prefix, yes_no(s->remove_on_stop),
|
prefix, yes_no(s->remove_on_stop),
|
||||||
prefix, yes_no(s->writable),
|
prefix, yes_no(s->writable),
|
||||||
|
@ -1070,6 +1072,12 @@ static void socket_apply_socket_options(Socket *s, int fd) {
|
||||||
log_unit_warning_errno(UNIT(s), r, "SO_PASSSEC failed: %m");
|
log_unit_warning_errno(UNIT(s), r, "SO_PASSSEC failed: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (s->pass_pktinfo) {
|
||||||
|
r = socket_pass_pktinfo(fd, true);
|
||||||
|
if (r < 0)
|
||||||
|
log_unit_warning_errno(UNIT(s), r, "Failed to enable packet info socket option: %m");
|
||||||
|
}
|
||||||
|
|
||||||
if (s->priority >= 0) {
|
if (s->priority >= 0) {
|
||||||
r = setsockopt_int(fd, SOL_SOCKET, SO_PRIORITY, s->priority);
|
r = setsockopt_int(fd, SOL_SOCKET, SO_PRIORITY, s->priority);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
|
|
@ -121,6 +121,7 @@ struct Socket {
|
||||||
bool broadcast;
|
bool broadcast;
|
||||||
bool pass_cred;
|
bool pass_cred;
|
||||||
bool pass_sec;
|
bool pass_sec;
|
||||||
|
bool pass_pktinfo;
|
||||||
|
|
||||||
/* Only for INET6 sockets: issue IPV6_V6ONLY sockopt */
|
/* Only for INET6 sockets: issue IPV6_V6ONLY sockopt */
|
||||||
SocketAddressBindIPv6Only bind_ipv6_only;
|
SocketAddressBindIPv6Only bind_ipv6_only;
|
||||||
|
|
|
@ -65,16 +65,16 @@ systemdshutdowndir=${systemd_shutdown_dir}
|
||||||
tmpfiles_dir=${prefix}/lib/tmpfiles.d
|
tmpfiles_dir=${prefix}/lib/tmpfiles.d
|
||||||
tmpfilesdir=${tmpfiles_dir}
|
tmpfilesdir=${tmpfiles_dir}
|
||||||
|
|
||||||
sysusers_dir=${prefix}/lib/sysusers.d
|
sysusers_dir=${rootprefix}/lib/sysusers.d
|
||||||
sysusersdir=${sysusers_dir}
|
sysusersdir=${sysusers_dir}
|
||||||
|
|
||||||
sysctl_dir=${prefix}/lib/sysctl.d
|
sysctl_dir=${rootprefix}/lib/sysctl.d
|
||||||
sysctldir=${sysctl_dir}
|
sysctldir=${sysctl_dir}
|
||||||
|
|
||||||
binfmt_dir=${prefix}/lib/binfmt.d
|
binfmt_dir=${rootprefix}/lib/binfmt.d
|
||||||
binfmtdir=${binfmt_dir}
|
binfmtdir=${binfmt_dir}
|
||||||
|
|
||||||
modules_load_dir=${prefix}/lib/modules-load.d
|
modules_load_dir=${rootprefix}/lib/modules-load.d
|
||||||
modulesloaddir=${modules_load_dir}
|
modulesloaddir=${modules_load_dir}
|
||||||
|
|
||||||
catalog_dir=${prefix}/lib/systemd/catalog
|
catalog_dir=${prefix}/lib/systemd/catalog
|
||||||
|
|
|
@ -30,8 +30,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||||
|
|
||||||
assert_se(service = xdg_autostart_service_parse_desktop(name));
|
assert_se(service = xdg_autostart_service_parse_desktop(name));
|
||||||
assert_se(service->name = strdup("fuzz-xdg-desktop.service"));
|
assert_se(service->name = strdup("fuzz-xdg-desktop.service"));
|
||||||
if (service)
|
(void) xdg_autostart_service_generate_unit(service, tmpdir);
|
||||||
(void) xdg_autostart_service_generate_unit(service, tmpdir);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,9 @@
|
||||||
|
|
||||||
#define JOURNAL_FILES_RECHECK_USEC (2 * USEC_PER_SEC)
|
#define JOURNAL_FILES_RECHECK_USEC (2 * USEC_PER_SEC)
|
||||||
|
|
||||||
#define REPLACE_VAR_MAX 256
|
/* The maximum size of variable values we'll expand in catalog entries. We bind this to PATH_MAX for now, as
|
||||||
|
* we want to be able to show all officially valid paths at least */
|
||||||
|
#define REPLACE_VAR_MAX PATH_MAX
|
||||||
|
|
||||||
#define DEFAULT_DATA_THRESHOLD (64*1024)
|
#define DEFAULT_DATA_THRESHOLD (64*1024)
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,7 @@ int dhcp6_option_append_vendor_class(uint8_t **buf, size_t *buflen, char **user_
|
||||||
int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode,
|
int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode,
|
||||||
size_t *optlen, uint8_t **optvalue);
|
size_t *optlen, uint8_t **optvalue);
|
||||||
int dhcp6_option_parse_status(DHCP6Option *option, size_t len);
|
int dhcp6_option_parse_status(DHCP6Option *option, size_t len);
|
||||||
int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia);
|
int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_status_code);
|
||||||
int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
|
int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
|
||||||
struct in6_addr **addrs, size_t count,
|
struct in6_addr **addrs, size_t count,
|
||||||
size_t *allocated);
|
size_t *allocated);
|
||||||
|
|
|
@ -417,13 +417,13 @@ static int dhcp6_option_parse_pdprefix(DHCP6Option *option, DHCP6IA *ia,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia) {
|
int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia, uint16_t *ret_status_code) {
|
||||||
uint16_t iatype, optlen;
|
|
||||||
size_t i, len;
|
|
||||||
int r = 0, status;
|
|
||||||
uint16_t opt;
|
|
||||||
size_t iaaddr_offset;
|
|
||||||
uint32_t lt_t1, lt_t2, lt_valid = 0, lt_min = UINT32_MAX;
|
uint32_t lt_t1, lt_t2, lt_valid = 0, lt_min = UINT32_MAX;
|
||||||
|
uint16_t iatype, optlen;
|
||||||
|
size_t iaaddr_offset;
|
||||||
|
int r = 0, status;
|
||||||
|
size_t i, len;
|
||||||
|
uint16_t opt;
|
||||||
|
|
||||||
assert_return(ia, -EINVAL);
|
assert_return(ia, -EINVAL);
|
||||||
assert_return(!ia->addresses, -EINVAL);
|
assert_return(!ia->addresses, -EINVAL);
|
||||||
|
@ -533,11 +533,15 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia) {
|
||||||
status = dhcp6_option_parse_status(option, optlen + offsetof(DHCP6Option, data));
|
status = dhcp6_option_parse_status(option, optlen + offsetof(DHCP6Option, data));
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
if (status > 0) {
|
if (status > 0) {
|
||||||
|
if (ret_status_code)
|
||||||
|
*ret_status_code = status;
|
||||||
|
|
||||||
log_dhcp6_client(client, "IA status %s",
|
log_dhcp6_client(client, "IA status %s",
|
||||||
dhcp6_message_status_to_string(status));
|
dhcp6_message_status_to_string(status));
|
||||||
|
|
||||||
return -EINVAL;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -581,7 +585,10 @@ int dhcp6_option_parse_ia(DHCP6Option *iaoption, DHCP6IA *ia) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
if (ret_status_code)
|
||||||
|
*ret_status_code = 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
|
int dhcp6_option_parse_ip6addrs(uint8_t *optval, uint16_t optlen,
|
||||||
|
|
|
@ -998,10 +998,11 @@ static int client_parse_message(
|
||||||
size_t len,
|
size_t len,
|
||||||
sd_dhcp6_lease *lease) {
|
sd_dhcp6_lease *lease) {
|
||||||
|
|
||||||
|
uint16_t ia_na_status = 0, ia_pd_status = 0;
|
||||||
uint32_t lt_t1 = ~0, lt_t2 = ~0;
|
uint32_t lt_t1 = ~0, lt_t2 = ~0;
|
||||||
|
usec_t irt = IRT_DEFAULT;
|
||||||
bool clientid = false;
|
bool clientid = false;
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
usec_t irt = IRT_DEFAULT;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(client);
|
assert(client);
|
||||||
|
@ -1015,8 +1016,8 @@ static int client_parse_message(
|
||||||
DHCP6Option *option = (DHCP6Option *) &message->options[pos];
|
DHCP6Option *option = (DHCP6Option *) &message->options[pos];
|
||||||
uint16_t optcode, optlen;
|
uint16_t optcode, optlen;
|
||||||
be32_t iaid_lease;
|
be32_t iaid_lease;
|
||||||
|
int status;
|
||||||
uint8_t *optval;
|
uint8_t *optval;
|
||||||
int status;
|
|
||||||
|
|
||||||
if (len < pos + offsetof(DHCP6Option, data))
|
if (len < pos + offsetof(DHCP6Option, data))
|
||||||
return -ENOBUFS;
|
return -ENOBUFS;
|
||||||
|
@ -1093,10 +1094,15 @@ static int client_parse_message(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = dhcp6_option_parse_ia(option, &lease->ia);
|
r = dhcp6_option_parse_ia(option, &lease->ia, &ia_na_status);
|
||||||
if (r < 0 && r != -ENOMSG)
|
if (r < 0 && r != -ENOMSG)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
if (ia_na_status == DHCP6_STATUS_NO_ADDRS_AVAIL) {
|
||||||
|
pos += offsetof(DHCP6Option, data) + optlen;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
r = dhcp6_lease_get_iaid(lease, &iaid_lease);
|
r = dhcp6_lease_get_iaid(lease, &iaid_lease);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
@ -1121,10 +1127,15 @@ static int client_parse_message(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = dhcp6_option_parse_ia(option, &lease->pd);
|
r = dhcp6_option_parse_ia(option, &lease->pd, &ia_pd_status);
|
||||||
if (r < 0 && r != -ENOMSG)
|
if (r < 0 && r != -ENOMSG)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
if (ia_pd_status == DHCP6_STATUS_NO_PREFIX_AVAIL) {
|
||||||
|
pos += offsetof(DHCP6Option, data) + optlen;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
r = dhcp6_lease_get_pd_iaid(lease, &iaid_lease);
|
r = dhcp6_lease_get_pd_iaid(lease, &iaid_lease);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
@ -1188,6 +1199,11 @@ static int client_parse_message(
|
||||||
pos += offsetof(DHCP6Option, data) + optlen;
|
pos += offsetof(DHCP6Option, data) + optlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ia_na_status > 0 && ia_pd_status > 0) {
|
||||||
|
log_dhcp6_client(client, "No IA_PD prefix or IA_NA address received. Ignoring.");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!clientid) {
|
if (!clientid) {
|
||||||
log_dhcp6_client(client, "%s has incomplete options",
|
log_dhcp6_client(client, "%s has incomplete options",
|
||||||
dhcp6_message_type_to_string(message->type));
|
dhcp6_message_type_to_string(message->type));
|
||||||
|
|
|
@ -252,12 +252,14 @@ static int ipv4ll_start_internal(sd_ipv4ll *ll, bool reset_generation) {
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sd_ipv4ll_start(sd_ipv4ll *ll) {
|
int sd_ipv4ll_start(sd_ipv4ll *ll) {
|
||||||
assert_return(ll, -EINVAL);
|
assert_return(ll, -EINVAL);
|
||||||
assert_return(sd_ipv4ll_is_running(ll) == 0, -EBUSY);
|
|
||||||
|
if (sd_ipv4ll_is_running(ll))
|
||||||
|
return 0;
|
||||||
|
|
||||||
return ipv4ll_start_internal(ll, true);
|
return ipv4ll_start_internal(ll, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -247,17 +247,17 @@ static int test_option_status(sd_event *e) {
|
||||||
option = (DHCP6Option *)option1;
|
option = (DHCP6Option *)option1;
|
||||||
assert_se(sizeof(option1) == sizeof(DHCP6Option) + be16toh(option->len));
|
assert_se(sizeof(option1) == sizeof(DHCP6Option) + be16toh(option->len));
|
||||||
|
|
||||||
r = dhcp6_option_parse_ia(option, &ia);
|
r = dhcp6_option_parse_ia(option, &ia, NULL);
|
||||||
assert_se(r == -EINVAL);
|
assert_se(r == 0);
|
||||||
assert_se(ia.addresses == NULL);
|
assert_se(ia.addresses == NULL);
|
||||||
|
|
||||||
option->len = htobe16(17);
|
option->len = htobe16(17);
|
||||||
r = dhcp6_option_parse_ia(option, &ia);
|
r = dhcp6_option_parse_ia(option, &ia, NULL);
|
||||||
assert_se(r == -ENOBUFS);
|
assert_se(r == -ENOBUFS);
|
||||||
assert_se(ia.addresses == NULL);
|
assert_se(ia.addresses == NULL);
|
||||||
|
|
||||||
option->len = htobe16(sizeof(DHCP6Option));
|
option->len = htobe16(sizeof(DHCP6Option));
|
||||||
r = dhcp6_option_parse_ia(option, &ia);
|
r = dhcp6_option_parse_ia(option, &ia, NULL);
|
||||||
assert_se(r == -ENOBUFS);
|
assert_se(r == -ENOBUFS);
|
||||||
assert_se(ia.addresses == NULL);
|
assert_se(ia.addresses == NULL);
|
||||||
|
|
||||||
|
@ -265,7 +265,7 @@ static int test_option_status(sd_event *e) {
|
||||||
option = (DHCP6Option *)option2;
|
option = (DHCP6Option *)option2;
|
||||||
assert_se(sizeof(option2) == sizeof(DHCP6Option) + be16toh(option->len));
|
assert_se(sizeof(option2) == sizeof(DHCP6Option) + be16toh(option->len));
|
||||||
|
|
||||||
r = dhcp6_option_parse_ia(option, &ia);
|
r = dhcp6_option_parse_ia(option, &ia, NULL);
|
||||||
assert_se(r >= 0);
|
assert_se(r >= 0);
|
||||||
assert_se(ia.addresses == NULL);
|
assert_se(ia.addresses == NULL);
|
||||||
|
|
||||||
|
@ -273,7 +273,7 @@ static int test_option_status(sd_event *e) {
|
||||||
option = (DHCP6Option *)option3;
|
option = (DHCP6Option *)option3;
|
||||||
assert_se(sizeof(option3) == sizeof(DHCP6Option) + be16toh(option->len));
|
assert_se(sizeof(option3) == sizeof(DHCP6Option) + be16toh(option->len));
|
||||||
|
|
||||||
r = dhcp6_option_parse_ia(option, &ia);
|
r = dhcp6_option_parse_ia(option, &ia, NULL);
|
||||||
assert_se(r >= 0);
|
assert_se(r >= 0);
|
||||||
assert_se(ia.addresses != NULL);
|
assert_se(ia.addresses != NULL);
|
||||||
dhcp6_lease_free_ia(&ia);
|
dhcp6_lease_free_ia(&ia);
|
||||||
|
@ -282,8 +282,8 @@ static int test_option_status(sd_event *e) {
|
||||||
option = (DHCP6Option *)option4;
|
option = (DHCP6Option *)option4;
|
||||||
assert_se(sizeof(option4) == sizeof(DHCP6Option) + be16toh(option->len));
|
assert_se(sizeof(option4) == sizeof(DHCP6Option) + be16toh(option->len));
|
||||||
|
|
||||||
r = dhcp6_option_parse_ia(option, &pd);
|
r = dhcp6_option_parse_ia(option, &pd, NULL);
|
||||||
assert_se(r == 0);
|
assert_se(r >= 0);
|
||||||
assert_se(pd.addresses != NULL);
|
assert_se(pd.addresses != NULL);
|
||||||
assert_se(memcmp(&pd.ia_pd.id, &option4[4], 4) == 0);
|
assert_se(memcmp(&pd.ia_pd.id, &option4[4], 4) == 0);
|
||||||
assert_se(memcmp(&pd.ia_pd.lifetime_t1, &option4[8], 4) == 0);
|
assert_se(memcmp(&pd.ia_pd.lifetime_t1, &option4[8], 4) == 0);
|
||||||
|
@ -294,8 +294,8 @@ static int test_option_status(sd_event *e) {
|
||||||
option = (DHCP6Option *)option5;
|
option = (DHCP6Option *)option5;
|
||||||
assert_se(sizeof(option5) == sizeof(DHCP6Option) + be16toh(option->len));
|
assert_se(sizeof(option5) == sizeof(DHCP6Option) + be16toh(option->len));
|
||||||
|
|
||||||
r = dhcp6_option_parse_ia(option, &pd);
|
r = dhcp6_option_parse_ia(option, &pd, NULL);
|
||||||
assert_se(r == 0);
|
assert_se(r >= 0);
|
||||||
assert_se(pd.addresses != NULL);
|
assert_se(pd.addresses != NULL);
|
||||||
dhcp6_lease_free_ia(&pd);
|
dhcp6_lease_free_ia(&pd);
|
||||||
|
|
||||||
|
@ -364,15 +364,15 @@ static int test_advertise_option(sd_event *e) {
|
||||||
_cleanup_(sd_dhcp6_lease_unrefp) sd_dhcp6_lease *lease = NULL;
|
_cleanup_(sd_dhcp6_lease_unrefp) sd_dhcp6_lease *lease = NULL;
|
||||||
DHCP6Message *advertise = (DHCP6Message *)msg_advertise;
|
DHCP6Message *advertise = (DHCP6Message *)msg_advertise;
|
||||||
size_t len = sizeof(msg_advertise) - sizeof(DHCP6Message), pos = 0;
|
size_t len = sizeof(msg_advertise) - sizeof(DHCP6Message), pos = 0;
|
||||||
be32_t val;
|
|
||||||
uint8_t preference = 255;
|
|
||||||
struct in6_addr addr;
|
|
||||||
uint32_t lt_pref, lt_valid;
|
uint32_t lt_pref, lt_valid;
|
||||||
int r;
|
|
||||||
uint8_t *opt;
|
|
||||||
bool opt_clientid = false;
|
bool opt_clientid = false;
|
||||||
const struct in6_addr *addrs;
|
const struct in6_addr *addrs;
|
||||||
|
uint8_t preference = 255;
|
||||||
|
struct in6_addr addr;
|
||||||
char **domains;
|
char **domains;
|
||||||
|
uint8_t *opt;
|
||||||
|
int r;
|
||||||
|
be32_t val;
|
||||||
|
|
||||||
log_debug("/* %s */", __func__);
|
log_debug("/* %s */", __func__);
|
||||||
|
|
||||||
|
@ -410,7 +410,7 @@ static int test_advertise_option(sd_event *e) {
|
||||||
val = htobe32(120);
|
val = htobe32(120);
|
||||||
assert_se(!memcmp(optval + 8, &val, sizeof(val)));
|
assert_se(!memcmp(optval + 8, &val, sizeof(val)));
|
||||||
|
|
||||||
assert_se(dhcp6_option_parse_ia(option, &lease->ia) >= 0);
|
assert_se(dhcp6_option_parse_ia(option, &lease->ia, NULL) >= 0);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -563,12 +563,12 @@ static int test_client_send_reply(DHCP6Message *request) {
|
||||||
|
|
||||||
static int test_client_verify_request(DHCP6Message *request, size_t len) {
|
static int test_client_verify_request(DHCP6Message *request, size_t len) {
|
||||||
_cleanup_(sd_dhcp6_lease_unrefp) sd_dhcp6_lease *lease = NULL;
|
_cleanup_(sd_dhcp6_lease_unrefp) sd_dhcp6_lease *lease = NULL;
|
||||||
size_t pos = 0;
|
|
||||||
bool found_clientid = false, found_iana = false, found_serverid = false,
|
bool found_clientid = false, found_iana = false, found_serverid = false,
|
||||||
found_elapsed_time = false, found_fqdn = false;
|
found_elapsed_time = false, found_fqdn = false;
|
||||||
struct in6_addr addr;
|
|
||||||
be32_t val;
|
|
||||||
uint32_t lt_pref, lt_valid;
|
uint32_t lt_pref, lt_valid;
|
||||||
|
struct in6_addr addr;
|
||||||
|
size_t pos = 0;
|
||||||
|
be32_t val;
|
||||||
|
|
||||||
log_debug("/* %s */", __func__);
|
log_debug("/* %s */", __func__);
|
||||||
|
|
||||||
|
@ -606,7 +606,7 @@ static int test_client_verify_request(DHCP6Message *request, size_t len) {
|
||||||
val = htobe32(120);
|
val = htobe32(120);
|
||||||
assert_se(!memcmp(optval + 8, &val, sizeof(val)));
|
assert_se(!memcmp(optval + 8, &val, sizeof(val)));
|
||||||
|
|
||||||
assert_se(!dhcp6_option_parse_ia(option, &lease->ia));
|
assert_se(dhcp6_option_parse_ia(option, &lease->ia, NULL) >= 0);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -159,10 +159,10 @@ static void test_basic_request(sd_event *e) {
|
||||||
assert_se(sd_ipv4ll_start(ll) == -EINVAL);
|
assert_se(sd_ipv4ll_start(ll) == -EINVAL);
|
||||||
|
|
||||||
assert_se(sd_ipv4ll_set_ifindex(ll, 1) == 0);
|
assert_se(sd_ipv4ll_set_ifindex(ll, 1) == 0);
|
||||||
assert_se(sd_ipv4ll_start(ll) == 0);
|
assert_se(sd_ipv4ll_start(ll) == 1);
|
||||||
|
|
||||||
sd_event_run(e, (uint64_t) -1);
|
sd_event_run(e, (uint64_t) -1);
|
||||||
assert_se(sd_ipv4ll_start(ll) == -EBUSY);
|
assert_se(sd_ipv4ll_start(ll) == 0);
|
||||||
|
|
||||||
assert_se(sd_ipv4ll_is_running(ll));
|
assert_se(sd_ipv4ll_is_running(ll));
|
||||||
|
|
||||||
|
|
|
@ -297,6 +297,7 @@ static void test_rs(void) {
|
||||||
|
|
||||||
assert_se(sd_ndisc_stop(nd) >= 0);
|
assert_se(sd_ndisc_stop(nd) >= 0);
|
||||||
assert_se(sd_ndisc_start(nd) >= 0);
|
assert_se(sd_ndisc_start(nd) >= 0);
|
||||||
|
assert_se(sd_ndisc_start(nd) >= 0);
|
||||||
assert_se(sd_ndisc_stop(nd) >= 0);
|
assert_se(sd_ndisc_stop(nd) >= 0);
|
||||||
|
|
||||||
assert_se(sd_ndisc_start(nd) >= 0);
|
assert_se(sd_ndisc_start(nd) >= 0);
|
||||||
|
|
|
@ -715,4 +715,6 @@ global:
|
||||||
|
|
||||||
sd_path_lookup;
|
sd_path_lookup;
|
||||||
sd_path_lookup_strv;
|
sd_path_lookup_strv;
|
||||||
|
|
||||||
|
sd_notify_barrier;
|
||||||
} LIBSYSTEMD_245;
|
} LIBSYSTEMD_245;
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <linux/filter.h>
|
#include <linux/filter.h>
|
||||||
#include <linux/netlink.h>
|
#include <linux/netlink.h>
|
||||||
|
#include <linux/sockios.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "sd-device.h"
|
#include "sd-device.h"
|
||||||
|
@ -13,10 +15,12 @@
|
||||||
#include "device-monitor-private.h"
|
#include "device-monitor-private.h"
|
||||||
#include "device-private.h"
|
#include "device-private.h"
|
||||||
#include "device-util.h"
|
#include "device-util.h"
|
||||||
|
#include "errno-util.h"
|
||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
#include "format-util.h"
|
#include "format-util.h"
|
||||||
#include "hashmap.h"
|
#include "hashmap.h"
|
||||||
#include "io-util.h"
|
#include "io-util.h"
|
||||||
|
#include "missing_socket.h"
|
||||||
#include "mountpoint-util.h"
|
#include "mountpoint-util.h"
|
||||||
#include "set.h"
|
#include "set.h"
|
||||||
#include "socket-util.h"
|
#include "socket-util.h"
|
||||||
|
@ -163,12 +167,54 @@ int device_monitor_new_full(sd_device_monitor **ret, MonitorNetlinkGroup group,
|
||||||
|
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
r = monitor_set_nl_address(m);
|
r = monitor_set_nl_address(m);
|
||||||
if (r < 0)
|
if (r < 0) {
|
||||||
return log_debug_errno(r, "sd-device-monitor: Failed to set netlink address: %m");
|
log_debug_errno(r, "sd-device-monitor: Failed to set netlink address: %m");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DEBUG_LOGGING) {
|
||||||
|
_cleanup_close_ int netns = -1;
|
||||||
|
|
||||||
|
/* So here's the thing: only AF_NETLINK sockets from the main network namespace will get
|
||||||
|
* hardware events. Let's check if ours is from there, and if not generate a debug message,
|
||||||
|
* since we cannot possibly work correctly otherwise. This is just a safety check to make
|
||||||
|
* things easier to debug. */
|
||||||
|
|
||||||
|
netns = ioctl(m->sock, SIOCGSKNS);
|
||||||
|
if (netns < 0)
|
||||||
|
log_debug_errno(errno, "sd-device-monitor: Unable to get network namespace of udev netlink socket, unable to determine if we are in host netns: %m");
|
||||||
|
else {
|
||||||
|
struct stat a, b;
|
||||||
|
|
||||||
|
if (fstat(netns, &a) < 0) {
|
||||||
|
r = log_debug_errno(errno, "sd-device-monitor: Failed to stat netns of udev netlink socket: %m");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stat("/proc/1/ns/net", &b) < 0) {
|
||||||
|
if (ERRNO_IS_PRIVILEGE(errno))
|
||||||
|
/* If we can't access PID1's netns info due to permissions, it's fine, this is a
|
||||||
|
* safety check only after all. */
|
||||||
|
log_debug_errno(errno, "sd-device-monitor: No permission to stat PID1's netns, unable to determine if we are in host netns: %m");
|
||||||
|
else
|
||||||
|
log_debug_errno(errno, "sd-device-monitor: Failed to stat PID1's netns: %m");
|
||||||
|
|
||||||
|
} else if (a.st_dev != b.st_dev || a.st_ino != b.st_ino)
|
||||||
|
log_debug("sd-device-monitor: Netlink socket we listen on is not from host netns, we won't see device events.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*ret = TAKE_PTR(m);
|
*ret = TAKE_PTR(m);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
/* Let's unset the socket fd in the monitor object before we destroy it so that the fd passed in is
|
||||||
|
* not closed on failure. */
|
||||||
|
if (fd >= 0)
|
||||||
|
m->sock = -1;
|
||||||
|
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
_public_ int sd_device_monitor_new(sd_device_monitor **ret) {
|
_public_ int sd_device_monitor_new(sd_device_monitor **ret) {
|
||||||
|
|
|
@ -16,10 +16,6 @@
|
||||||
#include "socket-util.h"
|
#include "socket-util.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
/* For some reason we need some extra cmsg space on some kernels. It's not clear why, and one of those days
|
|
||||||
* we need to track this down. See: https://github.com/systemd/systemd/pull/15457 */
|
|
||||||
#define EXTRA_CMSG_SPACE 1024
|
|
||||||
|
|
||||||
int socket_open(int family) {
|
int socket_open(int family) {
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
|
@ -244,7 +240,7 @@ int socket_write_message(sd_netlink *nl, sd_netlink_message *m) {
|
||||||
|
|
||||||
static int socket_recv_message(int fd, struct iovec *iov, uint32_t *ret_mcast_group, bool peek) {
|
static int socket_recv_message(int fd, struct iovec *iov, uint32_t *ret_mcast_group, bool peek) {
|
||||||
union sockaddr_union sender;
|
union sockaddr_union sender;
|
||||||
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct nl_pktinfo)) + EXTRA_CMSG_SPACE) control;
|
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct nl_pktinfo))) control;
|
||||||
struct msghdr msg = {
|
struct msghdr msg = {
|
||||||
.msg_iov = iov,
|
.msg_iov = iov,
|
||||||
.msg_iovlen = 1,
|
.msg_iovlen = 1,
|
||||||
|
|
|
@ -320,73 +320,73 @@ static int get_path(uint64_t type, char **buffer, const char **ret) {
|
||||||
case SD_PATH_USER_DESKTOP:
|
case SD_PATH_USER_DESKTOP:
|
||||||
return from_user_dir("XDG_DESKTOP_DIR", buffer, ret);
|
return from_user_dir("XDG_DESKTOP_DIR", buffer, ret);
|
||||||
|
|
||||||
case SD_PATH_SYSTEMD_UTIL_DIR:
|
case SD_PATH_SYSTEMD_UTIL:
|
||||||
*ret = ROOTPREFIX "lib/systemd";
|
*ret = ROOTPREFIX "/lib/systemd";
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case SD_PATH_SYSTEMD_SYSTEM_UNIT_DIR:
|
case SD_PATH_SYSTEMD_SYSTEM_UNIT:
|
||||||
*ret = SYSTEM_DATA_UNIT_PATH;
|
*ret = SYSTEM_DATA_UNIT_PATH;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case SD_PATH_SYSTEMD_SYSTEM_PRESET_DIR:
|
case SD_PATH_SYSTEMD_SYSTEM_PRESET:
|
||||||
*ret = ROOTPREFIX "lib/systemd/system-preset";
|
*ret = ROOTPREFIX "/lib/systemd/system-preset";
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case SD_PATH_SYSTEMD_USER_UNIT_DIR:
|
case SD_PATH_SYSTEMD_USER_UNIT:
|
||||||
*ret = USER_DATA_UNIT_DIR;
|
*ret = USER_DATA_UNIT_DIR;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case SD_PATH_SYSTEMD_USER_PRESET_DIR:
|
case SD_PATH_SYSTEMD_USER_PRESET:
|
||||||
*ret = ROOTPREFIX "lib/systemd/user-preset";
|
*ret = ROOTPREFIX "/lib/systemd/user-preset";
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case SD_PATH_SYSTEMD_SYSTEM_CONF_DIR:
|
case SD_PATH_SYSTEMD_SYSTEM_CONF:
|
||||||
*ret = SYSTEM_CONFIG_UNIT_DIR;
|
*ret = SYSTEM_CONFIG_UNIT_DIR;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case SD_PATH_SYSTEMD_USER_CONF_DIR:
|
case SD_PATH_SYSTEMD_USER_CONF:
|
||||||
*ret = USER_CONFIG_UNIT_DIR;
|
*ret = USER_CONFIG_UNIT_DIR;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case SD_PATH_SYSTEMD_SYSTEM_GENERATOR_DIR:
|
case SD_PATH_SYSTEMD_SYSTEM_GENERATOR:
|
||||||
*ret = SYSTEM_GENERATOR_DIR;
|
*ret = SYSTEM_GENERATOR_DIR;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case SD_PATH_SYSTEMD_USER_GENERATOR_DIR:
|
case SD_PATH_SYSTEMD_USER_GENERATOR:
|
||||||
*ret = USER_GENERATOR_DIR;
|
*ret = USER_GENERATOR_DIR;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case SD_PATH_SYSTEMD_SLEEP_DIR:
|
case SD_PATH_SYSTEMD_SLEEP:
|
||||||
*ret = ROOTPREFIX "lib/systemd/system-sleep";
|
*ret = ROOTPREFIX "/lib/systemd/system-sleep";
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case SD_PATH_SYSTEMD_SHUTDOWN_DIR:
|
case SD_PATH_SYSTEMD_SHUTDOWN:
|
||||||
*ret = ROOTPREFIX "lib/systemd/system-shutdown";
|
*ret = ROOTPREFIX "/lib/systemd/system-shutdown";
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* FIXME: systemd.pc uses ${prefix}, but CONF_PATHS_NULSTR doesn't.
|
/* FIXME: systemd.pc uses ${prefix}, but CONF_PATHS_NULSTR doesn't.
|
||||||
* Should ${prefix} use in systemd.pc be removed? */
|
* Should ${prefix} use in systemd.pc be removed? */
|
||||||
case SD_PATH_TMPFILES_DIR:
|
case SD_PATH_TMPFILES:
|
||||||
*ret = "/usr/lib/tmpfiles.d";
|
*ret = "/usr/lib/tmpfiles.d";
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case SD_PATH_SYSUSERS_DIR:
|
case SD_PATH_SYSUSERS:
|
||||||
*ret = "/usr/lib/sysusers.d";
|
*ret = ROOTPREFIX "/lib/sysusers.d";
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case SD_PATH_SYSCTL_DIR:
|
case SD_PATH_SYSCTL:
|
||||||
*ret = "/usr/lib/sysctl.d";
|
*ret = ROOTPREFIX "/lib/sysctl.d";
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case SD_PATH_BINFMT_DIR:
|
case SD_PATH_BINFMT:
|
||||||
*ret = "/usr/lib/binfmt.d";
|
*ret = ROOTPREFIX "/lib/binfmt.d";
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case SD_PATH_MODULES_LOAD_DIR:
|
case SD_PATH_MODULES_LOAD:
|
||||||
*ret = "/usr/lib/modules-load.d";
|
*ret = ROOTPREFIX "/lib/modules-load.d";
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case SD_PATH_CATALOG_DIR:
|
case SD_PATH_CATALOG:
|
||||||
*ret = "/usr/lib/systemd/catalog";
|
*ret = "/usr/lib/systemd/catalog";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -607,10 +607,10 @@ static int get_search(uint64_t type, char ***list) {
|
||||||
case SD_PATH_SEARCH_BINARIES_DEFAULT:
|
case SD_PATH_SEARCH_BINARIES_DEFAULT:
|
||||||
return strv_from_nulstr(list, DEFAULT_PATH_NULSTR);
|
return strv_from_nulstr(list, DEFAULT_PATH_NULSTR);
|
||||||
|
|
||||||
case SD_PATH_SYSTEMD_SYSTEM_UNIT_PATH:
|
case SD_PATH_SYSTEMD_SEARCH_SYSTEM_UNIT:
|
||||||
case SD_PATH_SYSTEMD_USER_UNIT_PATH: {
|
case SD_PATH_SYSTEMD_SEARCH_USER_UNIT: {
|
||||||
_cleanup_(lookup_paths_free) LookupPaths lp = {};
|
_cleanup_(lookup_paths_free) LookupPaths lp = {};
|
||||||
const UnitFileScope scope = type == SD_PATH_SYSTEMD_SYSTEM_UNIT_PATH ?
|
const UnitFileScope scope = type == SD_PATH_SYSTEMD_SEARCH_SYSTEM_UNIT ?
|
||||||
UNIT_FILE_SYSTEM : UNIT_FILE_USER;
|
UNIT_FILE_SYSTEM : UNIT_FILE_USER;
|
||||||
|
|
||||||
r = lookup_paths_init(&lp, scope, 0, NULL);
|
r = lookup_paths_init(&lp, scope, 0, NULL);
|
||||||
|
@ -621,10 +621,10 @@ static int get_search(uint64_t type, char ***list) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SD_PATH_SYSTEMD_SYSTEM_GENERATOR_PATH:
|
case SD_PATH_SYSTEMD_SEARCH_SYSTEM_GENERATOR:
|
||||||
case SD_PATH_SYSTEMD_USER_GENERATOR_PATH: {
|
case SD_PATH_SYSTEMD_SEARCH_USER_GENERATOR: {
|
||||||
char **t;
|
char **t;
|
||||||
const UnitFileScope scope = type == SD_PATH_SYSTEMD_SYSTEM_GENERATOR_PATH ?
|
const UnitFileScope scope = type == SD_PATH_SYSTEMD_SEARCH_SYSTEM_GENERATOR ?
|
||||||
UNIT_FILE_SYSTEM : UNIT_FILE_USER;
|
UNIT_FILE_SYSTEM : UNIT_FILE_USER;
|
||||||
|
|
||||||
t = generator_binary_paths(scope);
|
t = generator_binary_paths(scope);
|
||||||
|
@ -635,7 +635,7 @@ static int get_search(uint64_t type, char ***list) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
case SD_PATH_SYSTEMD_NETWORK_PATH:
|
case SD_PATH_SYSTEMD_SEARCH_NETWORK:
|
||||||
return strv_from_nulstr(list, NETWORK_DIRS_NULSTR);
|
return strv_from_nulstr(list, NETWORK_DIRS_NULSTR);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,10 @@ 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_add(Manager *m, struct in6_addr *addr, Link *link);
|
||||||
static int dhcp6_prefix_remove_all(Manager *m, Link *link);
|
static int dhcp6_prefix_remove_all(Manager *m, Link *link);
|
||||||
static bool dhcp6_link_has_dhcpv6_prefix(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,
|
||||||
|
uint32_t lifetime_valid);
|
||||||
|
|
||||||
static bool dhcp6_get_prefix_delegation(Link *link) {
|
static bool dhcp6_get_prefix_delegation(Link *link) {
|
||||||
if (!link->network)
|
if (!link->network)
|
||||||
|
@ -191,6 +195,12 @@ static int dhcp6_pd_prefix_assign(Link *link, struct in6_addr *prefix,
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
if (link->network->dhcp6_pd_assign_prefix) {
|
||||||
|
r = dhcp6_assign_delegated_prefix(link, prefix, prefix_len, lifetime_preferred, lifetime_valid);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
return sd_radv_start(radv);
|
return sd_radv_start(radv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1018,3 +1028,43 @@ static bool dhcp6_link_has_dhcpv6_prefix(Link *link) {
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int dhcp6_assign_delegated_prefix(Link *link,
|
||||||
|
const struct in6_addr *prefix,
|
||||||
|
uint8_t prefix_len,
|
||||||
|
uint32_t lifetime_preferred,
|
||||||
|
uint32_t lifetime_valid) {
|
||||||
|
_cleanup_(address_freep) Address *address = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(link);
|
||||||
|
assert(link->network);
|
||||||
|
assert(prefix);
|
||||||
|
|
||||||
|
if (!link->network->dhcp6_pd_assign_prefix)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
r = address_new(&address);
|
||||||
|
if (r < 0)
|
||||||
|
return log_link_error_errno(link, r, "Could not allocate address: %m");
|
||||||
|
|
||||||
|
address->in_addr.in6 = *prefix;
|
||||||
|
r = generate_ipv6_eui_64_address(link, &address->in_addr.in6);
|
||||||
|
if (r < 0)
|
||||||
|
return log_link_warning_errno(link, r, "Failed to generate EUI64 address for DHCPv6 acquired delegated prefix: %m");
|
||||||
|
|
||||||
|
address->prefixlen = prefix_len;
|
||||||
|
address->family = AF_INET6;
|
||||||
|
address->cinfo.ifa_prefered = lifetime_preferred;
|
||||||
|
address->cinfo.ifa_valid = lifetime_valid;
|
||||||
|
|
||||||
|
link_set_state(link, LINK_STATE_CONFIGURING);
|
||||||
|
|
||||||
|
r = address_configure(address, link, address_handler, true);
|
||||||
|
if (r < 0)
|
||||||
|
return log_link_warning_errno(link, r, "Could not set addresses: %m");
|
||||||
|
if (r > 0)
|
||||||
|
link->address_messages++;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -1173,7 +1173,7 @@ static int link_request_set_neighbors(Link *link) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
int address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(rtnl);
|
assert(rtnl);
|
||||||
|
|
|
@ -228,6 +228,7 @@ int link_request_set_routes(Link *link);
|
||||||
int link_request_set_nexthop(Link *link);
|
int link_request_set_nexthop(Link *link);
|
||||||
|
|
||||||
int link_reconfigure(Link *link, bool force);
|
int link_reconfigure(Link *link, bool force);
|
||||||
|
int address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link);
|
||||||
|
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_link_ipv6_address_gen_mode);
|
CONFIG_PARSER_PROTOTYPE(config_parse_link_ipv6_address_gen_mode);
|
||||||
|
|
||||||
|
|
|
@ -102,7 +102,7 @@ Network.ProxyARP, config_parse_tristate,
|
||||||
Network.IPv6ProxyNDPAddress, config_parse_ipv6_proxy_ndp_address, 0, 0
|
Network.IPv6ProxyNDPAddress, config_parse_ipv6_proxy_ndp_address, 0, 0
|
||||||
Network.BindCarrier, config_parse_strv, 0, offsetof(Network, bind_carrier)
|
Network.BindCarrier, config_parse_strv, 0, offsetof(Network, bind_carrier)
|
||||||
Network.ConfigureWithoutCarrier, config_parse_bool, 0, offsetof(Network, configure_without_carrier)
|
Network.ConfigureWithoutCarrier, config_parse_bool, 0, offsetof(Network, configure_without_carrier)
|
||||||
Network.IgnoreCarrierLoss, config_parse_bool, 0, offsetof(Network, ignore_carrier_loss)
|
Network.IgnoreCarrierLoss, config_parse_tristate, 0, offsetof(Network, ignore_carrier_loss)
|
||||||
Network.KeepConfiguration, config_parse_keep_configuration, 0, offsetof(Network, keep_configuration)
|
Network.KeepConfiguration, config_parse_keep_configuration, 0, offsetof(Network, keep_configuration)
|
||||||
Address.Address, config_parse_address, 0, 0
|
Address.Address, config_parse_address, 0, 0
|
||||||
Address.Peer, config_parse_address, 0, 0
|
Address.Peer, config_parse_address, 0, 0
|
||||||
|
@ -199,6 +199,7 @@ DHCPv6.RequestOptions, config_parse_dhcp_request_options,
|
||||||
DHCPv6.UserClass, config_parse_dhcp_user_class, AF_INET6, offsetof(Network, dhcp6_user_class)
|
DHCPv6.UserClass, config_parse_dhcp_user_class, AF_INET6, offsetof(Network, dhcp6_user_class)
|
||||||
DHCPv6.VendorClass, config_parse_dhcp_vendor_class, 0, offsetof(Network, dhcp6_vendor_class)
|
DHCPv6.VendorClass, config_parse_dhcp_vendor_class, 0, offsetof(Network, dhcp6_vendor_class)
|
||||||
DHCPv6.ForceDHCPv6PDOtherInformation, config_parse_bool, 0, offsetof(Network, dhcp6_force_pd_other_information)
|
DHCPv6.ForceDHCPv6PDOtherInformation, config_parse_bool, 0, offsetof(Network, dhcp6_force_pd_other_information)
|
||||||
|
DHCPv6.AssignAcquiredDelegatedPrefixAddress, config_parse_bool, 0, offsetof(Network, dhcp6_pd_assign_prefix)
|
||||||
DHCPv6.PrefixDelegationHint, config_parse_dhcp6_pd_hint, 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_bool, 0, offsetof(Network, dhcp6_without_ra)
|
||||||
DHCPv6.SendOption, config_parse_dhcp_send_option, AF_INET6, offsetof(Network, dhcp6_client_send_options)
|
DHCPv6.SendOption, config_parse_dhcp_send_option, AF_INET6, offsetof(Network, dhcp6_client_send_options)
|
||||||
|
|
|
@ -271,6 +271,9 @@ int network_verify(Network *network) {
|
||||||
if (network->dhcp_use_gateway < 0)
|
if (network->dhcp_use_gateway < 0)
|
||||||
network->dhcp_use_gateway = network->dhcp_use_routes;
|
network->dhcp_use_gateway = network->dhcp_use_routes;
|
||||||
|
|
||||||
|
if (network->ignore_carrier_loss < 0)
|
||||||
|
network->ignore_carrier_loss = network->configure_without_carrier;
|
||||||
|
|
||||||
if (network->dhcp_critical >= 0) {
|
if (network->dhcp_critical >= 0) {
|
||||||
if (network->keep_configuration >= 0)
|
if (network->keep_configuration >= 0)
|
||||||
log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
|
log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
|
||||||
|
@ -409,6 +412,8 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
|
||||||
.dhcp6_use_ntp = true,
|
.dhcp6_use_ntp = true,
|
||||||
.dhcp6_use_dns = true,
|
.dhcp6_use_dns = true,
|
||||||
|
|
||||||
|
.dhcp6_pd_assign_prefix = true,
|
||||||
|
|
||||||
.dhcp_server_emit_dns = true,
|
.dhcp_server_emit_dns = true,
|
||||||
.dhcp_server_emit_ntp = true,
|
.dhcp_server_emit_ntp = true,
|
||||||
.dhcp_server_emit_sip = true,
|
.dhcp_server_emit_sip = true,
|
||||||
|
@ -461,6 +466,8 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
|
||||||
.ipv6_accept_ra_route_table_set = false,
|
.ipv6_accept_ra_route_table_set = false,
|
||||||
.ipv6_accept_ra_start_dhcp6_client = true,
|
.ipv6_accept_ra_start_dhcp6_client = true,
|
||||||
|
|
||||||
|
.configure_without_carrier = false,
|
||||||
|
.ignore_carrier_loss = -1,
|
||||||
.keep_configuration = _KEEP_CONFIGURATION_INVALID,
|
.keep_configuration = _KEEP_CONFIGURATION_INVALID,
|
||||||
.ipv6_address_gen_mode = _LINK_IPV6_ADDRESS_GEN_MODE_INVALID,
|
.ipv6_address_gen_mode = _LINK_IPV6_ADDRESS_GEN_MODE_INVALID,
|
||||||
.can_triple_sampling = -1,
|
.can_triple_sampling = -1,
|
||||||
|
|
|
@ -192,6 +192,7 @@ struct Network {
|
||||||
bool dhcp6_force_pd_other_information; /* Start DHCPv6 PD also when 'O'
|
bool dhcp6_force_pd_other_information; /* Start DHCPv6 PD also when 'O'
|
||||||
RA flag is set, see RFC 7084,
|
RA flag is set, see RFC 7084,
|
||||||
WPD-4 */
|
WPD-4 */
|
||||||
|
bool dhcp6_pd_assign_prefix;
|
||||||
|
|
||||||
/* Bridge Support */
|
/* Bridge Support */
|
||||||
int use_bpdu;
|
int use_bpdu;
|
||||||
|
@ -258,7 +259,7 @@ struct Network {
|
||||||
int allmulticast;
|
int allmulticast;
|
||||||
bool unmanaged;
|
bool unmanaged;
|
||||||
bool configure_without_carrier;
|
bool configure_without_carrier;
|
||||||
bool ignore_carrier_loss;
|
int ignore_carrier_loss;
|
||||||
KeepConfiguration keep_configuration;
|
KeepConfiguration keep_configuration;
|
||||||
LinkIPv6AddressGenMode ipv6_address_gen_mode;
|
LinkIPv6AddressGenMode ipv6_address_gen_mode;
|
||||||
uint32_t iaid;
|
uint32_t iaid;
|
||||||
|
|
124
src/path/path.c
124
src/path/path.c
|
@ -18,71 +18,71 @@
|
||||||
static const char *arg_suffix = NULL;
|
static const char *arg_suffix = NULL;
|
||||||
|
|
||||||
static const char* const path_table[_SD_PATH_MAX] = {
|
static const char* const path_table[_SD_PATH_MAX] = {
|
||||||
[SD_PATH_TEMPORARY] = "temporary",
|
[SD_PATH_TEMPORARY] = "temporary",
|
||||||
[SD_PATH_TEMPORARY_LARGE] = "temporary-large",
|
[SD_PATH_TEMPORARY_LARGE] = "temporary-large",
|
||||||
[SD_PATH_SYSTEM_BINARIES] = "system-binaries",
|
[SD_PATH_SYSTEM_BINARIES] = "system-binaries",
|
||||||
[SD_PATH_SYSTEM_INCLUDE] = "system-include",
|
[SD_PATH_SYSTEM_INCLUDE] = "system-include",
|
||||||
[SD_PATH_SYSTEM_LIBRARY_PRIVATE] = "system-library-private",
|
[SD_PATH_SYSTEM_LIBRARY_PRIVATE] = "system-library-private",
|
||||||
[SD_PATH_SYSTEM_LIBRARY_ARCH] = "system-library-arch",
|
[SD_PATH_SYSTEM_LIBRARY_ARCH] = "system-library-arch",
|
||||||
[SD_PATH_SYSTEM_SHARED] = "system-shared",
|
[SD_PATH_SYSTEM_SHARED] = "system-shared",
|
||||||
[SD_PATH_SYSTEM_CONFIGURATION_FACTORY] = "system-configuration-factory",
|
[SD_PATH_SYSTEM_CONFIGURATION_FACTORY] = "system-configuration-factory",
|
||||||
[SD_PATH_SYSTEM_STATE_FACTORY] = "system-state-factory",
|
[SD_PATH_SYSTEM_STATE_FACTORY] = "system-state-factory",
|
||||||
[SD_PATH_SYSTEM_CONFIGURATION] = "system-configuration",
|
[SD_PATH_SYSTEM_CONFIGURATION] = "system-configuration",
|
||||||
[SD_PATH_SYSTEM_RUNTIME] = "system-runtime",
|
[SD_PATH_SYSTEM_RUNTIME] = "system-runtime",
|
||||||
[SD_PATH_SYSTEM_RUNTIME_LOGS] = "system-runtime-logs",
|
[SD_PATH_SYSTEM_RUNTIME_LOGS] = "system-runtime-logs",
|
||||||
[SD_PATH_SYSTEM_STATE_PRIVATE] = "system-state-private",
|
[SD_PATH_SYSTEM_STATE_PRIVATE] = "system-state-private",
|
||||||
[SD_PATH_SYSTEM_STATE_LOGS] = "system-state-logs",
|
[SD_PATH_SYSTEM_STATE_LOGS] = "system-state-logs",
|
||||||
[SD_PATH_SYSTEM_STATE_CACHE] = "system-state-cache",
|
[SD_PATH_SYSTEM_STATE_CACHE] = "system-state-cache",
|
||||||
[SD_PATH_SYSTEM_STATE_SPOOL] = "system-state-spool",
|
[SD_PATH_SYSTEM_STATE_SPOOL] = "system-state-spool",
|
||||||
[SD_PATH_USER_BINARIES] = "user-binaries",
|
[SD_PATH_USER_BINARIES] = "user-binaries",
|
||||||
[SD_PATH_USER_LIBRARY_PRIVATE] = "user-library-private",
|
[SD_PATH_USER_LIBRARY_PRIVATE] = "user-library-private",
|
||||||
[SD_PATH_USER_LIBRARY_ARCH] = "user-library-arch",
|
[SD_PATH_USER_LIBRARY_ARCH] = "user-library-arch",
|
||||||
[SD_PATH_USER_SHARED] = "user-shared",
|
[SD_PATH_USER_SHARED] = "user-shared",
|
||||||
[SD_PATH_USER_CONFIGURATION] = "user-configuration",
|
[SD_PATH_USER_CONFIGURATION] = "user-configuration",
|
||||||
[SD_PATH_USER_RUNTIME] = "user-runtime",
|
[SD_PATH_USER_RUNTIME] = "user-runtime",
|
||||||
[SD_PATH_USER_STATE_CACHE] = "user-state-cache",
|
[SD_PATH_USER_STATE_CACHE] = "user-state-cache",
|
||||||
[SD_PATH_USER] = "user",
|
[SD_PATH_USER] = "user",
|
||||||
[SD_PATH_USER_DOCUMENTS] = "user-documents",
|
[SD_PATH_USER_DOCUMENTS] = "user-documents",
|
||||||
[SD_PATH_USER_MUSIC] = "user-music",
|
[SD_PATH_USER_MUSIC] = "user-music",
|
||||||
[SD_PATH_USER_PICTURES] = "user-pictures",
|
[SD_PATH_USER_PICTURES] = "user-pictures",
|
||||||
[SD_PATH_USER_VIDEOS] = "user-videos",
|
[SD_PATH_USER_VIDEOS] = "user-videos",
|
||||||
[SD_PATH_USER_DOWNLOAD] = "user-download",
|
[SD_PATH_USER_DOWNLOAD] = "user-download",
|
||||||
[SD_PATH_USER_PUBLIC] = "user-public",
|
[SD_PATH_USER_PUBLIC] = "user-public",
|
||||||
[SD_PATH_USER_TEMPLATES] = "user-templates",
|
[SD_PATH_USER_TEMPLATES] = "user-templates",
|
||||||
[SD_PATH_USER_DESKTOP] = "user-desktop",
|
[SD_PATH_USER_DESKTOP] = "user-desktop",
|
||||||
[SD_PATH_SEARCH_BINARIES] = "search-binaries",
|
[SD_PATH_SEARCH_BINARIES] = "search-binaries",
|
||||||
[SD_PATH_SEARCH_BINARIES_DEFAULT] = "search-binaries-default",
|
[SD_PATH_SEARCH_BINARIES_DEFAULT] = "search-binaries-default",
|
||||||
[SD_PATH_SEARCH_LIBRARY_PRIVATE] = "search-library-private",
|
[SD_PATH_SEARCH_LIBRARY_PRIVATE] = "search-library-private",
|
||||||
[SD_PATH_SEARCH_LIBRARY_ARCH] = "search-library-arch",
|
[SD_PATH_SEARCH_LIBRARY_ARCH] = "search-library-arch",
|
||||||
[SD_PATH_SEARCH_SHARED] = "search-shared",
|
[SD_PATH_SEARCH_SHARED] = "search-shared",
|
||||||
[SD_PATH_SEARCH_CONFIGURATION_FACTORY] = "search-configuration-factory",
|
[SD_PATH_SEARCH_CONFIGURATION_FACTORY] = "search-configuration-factory",
|
||||||
[SD_PATH_SEARCH_STATE_FACTORY] = "search-state-factory",
|
[SD_PATH_SEARCH_STATE_FACTORY] = "search-state-factory",
|
||||||
[SD_PATH_SEARCH_CONFIGURATION] = "search-configuration",
|
[SD_PATH_SEARCH_CONFIGURATION] = "search-configuration",
|
||||||
|
|
||||||
[SD_PATH_SYSTEMD_UTIL_DIR] = "systemd-util-dir",
|
[SD_PATH_SYSTEMD_UTIL] = "systemd-util",
|
||||||
[SD_PATH_SYSTEMD_SYSTEM_UNIT_DIR] = "systemd-system-unit-dir",
|
[SD_PATH_SYSTEMD_SYSTEM_UNIT] = "systemd-system-unit",
|
||||||
[SD_PATH_SYSTEMD_SYSTEM_PRESET_DIR] = "systemd-system-preset-dir",
|
[SD_PATH_SYSTEMD_SYSTEM_PRESET] = "systemd-system-preset",
|
||||||
[SD_PATH_SYSTEMD_USER_UNIT_DIR] = "systemd-user-unit-dir",
|
[SD_PATH_SYSTEMD_SYSTEM_CONF] = "systemd-system-conf",
|
||||||
[SD_PATH_SYSTEMD_USER_PRESET_DIR] = "systemd-user-preset-dir",
|
[SD_PATH_SYSTEMD_SEARCH_SYSTEM_UNIT] = "systemd-system-unit",
|
||||||
[SD_PATH_SYSTEMD_SYSTEM_CONF_DIR] = "systemd-system-conf-dir",
|
[SD_PATH_SYSTEMD_SYSTEM_GENERATOR] = "systemd-system-generator",
|
||||||
[SD_PATH_SYSTEMD_USER_CONF_DIR] = "systemd-user-conf-dir",
|
[SD_PATH_SYSTEMD_SEARCH_SYSTEM_GENERATOR] = "systemd-system-generator",
|
||||||
[SD_PATH_SYSTEMD_SYSTEM_UNIT_PATH] = "systemd-system-unit-path",
|
[SD_PATH_SYSTEMD_USER_UNIT] = "systemd-user-unit",
|
||||||
[SD_PATH_SYSTEMD_USER_UNIT_PATH] = "systemd-user-unit-path",
|
[SD_PATH_SYSTEMD_USER_PRESET] = "systemd-user-preset",
|
||||||
[SD_PATH_SYSTEMD_SYSTEM_GENERATOR_DIR] = "systemd-system-generator-dir",
|
[SD_PATH_SYSTEMD_USER_CONF] = "systemd-user-conf",
|
||||||
[SD_PATH_SYSTEMD_USER_GENERATOR_DIR] = "systemd-user-generator-dir",
|
[SD_PATH_SYSTEMD_SEARCH_USER_UNIT] = "systemd-user-unit",
|
||||||
[SD_PATH_SYSTEMD_SYSTEM_GENERATOR_PATH] = "systemd-system-generator-path",
|
[SD_PATH_SYSTEMD_SEARCH_USER_GENERATOR] = "systemd-user-generator",
|
||||||
[SD_PATH_SYSTEMD_USER_GENERATOR_PATH] = "systemd-user-generator-path",
|
[SD_PATH_SYSTEMD_USER_GENERATOR] = "systemd-user-generator",
|
||||||
[SD_PATH_SYSTEMD_SLEEP_DIR] = "systemd-sleep-dir",
|
[SD_PATH_SYSTEMD_SLEEP] = "systemd-sleep",
|
||||||
[SD_PATH_SYSTEMD_SHUTDOWN_DIR] = "systemd-shutdown-dir",
|
[SD_PATH_SYSTEMD_SHUTDOWN] = "systemd-shutdown",
|
||||||
|
|
||||||
[SD_PATH_TMPFILES_DIR] = "tmpfiles-dir",
|
[SD_PATH_TMPFILES] = "tmpfiles",
|
||||||
[SD_PATH_SYSUSERS_DIR] = "sysusers-dir",
|
[SD_PATH_SYSUSERS] = "sysusers",
|
||||||
[SD_PATH_SYSCTL_DIR] = "sysctl-dir",
|
[SD_PATH_SYSCTL] = "sysctl",
|
||||||
[SD_PATH_BINFMT_DIR] = "binfmt-dir",
|
[SD_PATH_BINFMT] = "binfmt",
|
||||||
[SD_PATH_MODULES_LOAD_DIR] = "modules-load-dir",
|
[SD_PATH_MODULES_LOAD] = "modules-load",
|
||||||
[SD_PATH_CATALOG_DIR] = "catalog-dir",
|
[SD_PATH_CATALOG] = "catalog",
|
||||||
|
|
||||||
[SD_PATH_SYSTEMD_NETWORK_PATH] = "systemd-network-path",
|
[SD_PATH_SYSTEMD_SEARCH_NETWORK] = "systemd-search-network",
|
||||||
};
|
};
|
||||||
|
|
||||||
static int list_homes(void) {
|
static int list_homes(void) {
|
||||||
|
|
|
@ -88,6 +88,7 @@ static int dns_stream_complete(DnsStream *s, int error) {
|
||||||
|
|
||||||
static int dns_stream_identify(DnsStream *s) {
|
static int dns_stream_identify(DnsStream *s) {
|
||||||
CMSG_BUFFER_TYPE(CMSG_SPACE(MAXSIZE(struct in_pktinfo, struct in6_pktinfo))
|
CMSG_BUFFER_TYPE(CMSG_SPACE(MAXSIZE(struct in_pktinfo, struct in6_pktinfo))
|
||||||
|
+ CMSG_SPACE(int) + /* for the TTL */
|
||||||
+ EXTRA_CMSG_SPACE /* kernel appears to require extra space */) control;
|
+ EXTRA_CMSG_SPACE /* kernel appears to require extra space */) control;
|
||||||
struct msghdr mh = {};
|
struct msghdr mh = {};
|
||||||
struct cmsghdr *cmsg;
|
struct cmsghdr *cmsg;
|
||||||
|
|
|
@ -1632,6 +1632,7 @@ static int bus_append_socket_property(sd_bus_message *m, const char *field, cons
|
||||||
"Broadcast",
|
"Broadcast",
|
||||||
"PassCredentials",
|
"PassCredentials",
|
||||||
"PassSecurity",
|
"PassSecurity",
|
||||||
|
"PassPacketInfo",
|
||||||
"ReusePort",
|
"ReusePort",
|
||||||
"RemoveOnStop",
|
"RemoveOnStop",
|
||||||
"SELinuxContextFromNet"))
|
"SELinuxContextFromNet"))
|
||||||
|
|
|
@ -161,6 +161,11 @@ _SD_BEGIN_DECLARATIONS;
|
||||||
#define SD_MESSAGE_UNSAFE_USER_NAME SD_ID128_MAKE(b6,1f,da,c6,12,e9,4b,91,82,28,5b,99,88,43,06,1f)
|
#define SD_MESSAGE_UNSAFE_USER_NAME SD_ID128_MAKE(b6,1f,da,c6,12,e9,4b,91,82,28,5b,99,88,43,06,1f)
|
||||||
#define SD_MESSAGE_UNSAFE_USER_NAME_STR SD_ID128_MAKE_STR(b6,1f,da,c6,12,e9,4b,91,82,28,5b,99,88,43,06,1f)
|
#define SD_MESSAGE_UNSAFE_USER_NAME_STR SD_ID128_MAKE_STR(b6,1f,da,c6,12,e9,4b,91,82,28,5b,99,88,43,06,1f)
|
||||||
|
|
||||||
|
#define SD_MESSAGE_MOUNT_POINT_PATH_NOT_SUITABLE \
|
||||||
|
SD_ID128_MAKE(1b,3b,b9,40,37,f0,4b,bf,81,02,8e,13,5a,12,d2,93)
|
||||||
|
#define SD_MESSAGE_MOUNT_POINT_PATH_NOT_SUITABLE_STR \
|
||||||
|
SD_ID128_MAKE_STR(1b,3b,b9,40,37,f0,4b,bf,81,02,8e,13,5a,12,d2,93)
|
||||||
|
|
||||||
_SD_END_DECLARATIONS;
|
_SD_END_DECLARATIONS;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -78,32 +78,37 @@ enum {
|
||||||
SD_PATH_SEARCH_STATE_FACTORY,
|
SD_PATH_SEARCH_STATE_FACTORY,
|
||||||
SD_PATH_SEARCH_CONFIGURATION,
|
SD_PATH_SEARCH_CONFIGURATION,
|
||||||
|
|
||||||
/* Various systemd paths, generally mirroring systemd.pc */
|
/* Various systemd paths, generally mirroring systemd.pc — Except we drop the "dir" suffix (and
|
||||||
SD_PATH_SYSTEMD_UTIL_DIR,
|
* replaces "path" by "search"), since this API is about dirs/paths anyway, and contains "path"
|
||||||
SD_PATH_SYSTEMD_SYSTEM_UNIT_DIR,
|
* already in the prefix */
|
||||||
SD_PATH_SYSTEMD_SYSTEM_PRESET_DIR,
|
SD_PATH_SYSTEMD_UTIL,
|
||||||
SD_PATH_SYSTEMD_USER_UNIT_DIR,
|
SD_PATH_SYSTEMD_SYSTEM_UNIT,
|
||||||
SD_PATH_SYSTEMD_USER_PRESET_DIR,
|
SD_PATH_SYSTEMD_SYSTEM_PRESET,
|
||||||
SD_PATH_SYSTEMD_SYSTEM_CONF_DIR,
|
SD_PATH_SYSTEMD_SYSTEM_CONF,
|
||||||
SD_PATH_SYSTEMD_USER_CONF_DIR,
|
SD_PATH_SYSTEMD_USER_UNIT,
|
||||||
SD_PATH_SYSTEMD_SYSTEM_UNIT_PATH,
|
SD_PATH_SYSTEMD_USER_PRESET,
|
||||||
SD_PATH_SYSTEMD_USER_UNIT_PATH,
|
SD_PATH_SYSTEMD_USER_CONF,
|
||||||
SD_PATH_SYSTEMD_SYSTEM_GENERATOR_DIR,
|
|
||||||
SD_PATH_SYSTEMD_USER_GENERATOR_DIR,
|
|
||||||
SD_PATH_SYSTEMD_SYSTEM_GENERATOR_PATH,
|
|
||||||
SD_PATH_SYSTEMD_USER_GENERATOR_PATH,
|
|
||||||
SD_PATH_SYSTEMD_SLEEP_DIR,
|
|
||||||
SD_PATH_SYSTEMD_SHUTDOWN_DIR,
|
|
||||||
|
|
||||||
SD_PATH_TMPFILES_DIR,
|
SD_PATH_SYSTEMD_SEARCH_SYSTEM_UNIT,
|
||||||
SD_PATH_SYSUSERS_DIR,
|
SD_PATH_SYSTEMD_SEARCH_USER_UNIT,
|
||||||
SD_PATH_SYSCTL_DIR,
|
|
||||||
SD_PATH_BINFMT_DIR,
|
SD_PATH_SYSTEMD_SYSTEM_GENERATOR,
|
||||||
SD_PATH_MODULES_LOAD_DIR,
|
SD_PATH_SYSTEMD_USER_GENERATOR,
|
||||||
SD_PATH_CATALOG_DIR,
|
SD_PATH_SYSTEMD_SEARCH_SYSTEM_GENERATOR,
|
||||||
|
SD_PATH_SYSTEMD_SEARCH_USER_GENERATOR,
|
||||||
|
|
||||||
|
SD_PATH_SYSTEMD_SLEEP,
|
||||||
|
SD_PATH_SYSTEMD_SHUTDOWN,
|
||||||
|
|
||||||
|
SD_PATH_TMPFILES,
|
||||||
|
SD_PATH_SYSUSERS,
|
||||||
|
SD_PATH_SYSCTL,
|
||||||
|
SD_PATH_BINFMT,
|
||||||
|
SD_PATH_MODULES_LOAD,
|
||||||
|
SD_PATH_CATALOG,
|
||||||
|
|
||||||
/* systemd-networkd search paths */
|
/* systemd-networkd search paths */
|
||||||
SD_PATH_SYSTEMD_NETWORK_PATH,
|
SD_PATH_SYSTEMD_SEARCH_NETWORK,
|
||||||
|
|
||||||
_SD_PATH_MAX,
|
_SD_PATH_MAX,
|
||||||
};
|
};
|
||||||
|
|
|
@ -332,7 +332,9 @@ static int get_mac(sd_device *device, MACAddressPolicy policy, struct ether_addr
|
||||||
/* We require genuine randomness here, since we want to make sure we won't collide with other
|
/* We require genuine randomness here, since we want to make sure we won't collide with other
|
||||||
* systems booting up at the very same time. We do allow RDRAND however, since this is not
|
* systems booting up at the very same time. We do allow RDRAND however, since this is not
|
||||||
* cryptographic key material. */
|
* cryptographic key material. */
|
||||||
genuine_random_bytes(mac->ether_addr_octet, ETH_ALEN, RANDOM_ALLOW_RDRAND);
|
r = genuine_random_bytes(mac->ether_addr_octet, ETH_ALEN, RANDOM_ALLOW_RDRAND);
|
||||||
|
if (r < 0)
|
||||||
|
return log_device_error_errno(device, r, "Failed to acquire random data to generate MAC: %m");
|
||||||
} else {
|
} else {
|
||||||
uint64_t result;
|
uint64_t result;
|
||||||
|
|
||||||
|
|
|
@ -443,13 +443,18 @@ static int worker_device_monitor_handler(sd_device_monitor *monitor, sd_device *
|
||||||
assert(manager);
|
assert(manager);
|
||||||
|
|
||||||
r = worker_process_device(manager, dev);
|
r = worker_process_device(manager, dev);
|
||||||
if (r < 0)
|
if (r == -EAGAIN)
|
||||||
log_device_warning_errno(dev, r, "Failed to process device, ignoring: %m");
|
/* if we couldn't acquire the flock(), then proceed quietly */
|
||||||
|
log_device_debug_errno(dev, r, "Device currently locked, not processing.");
|
||||||
|
else {
|
||||||
|
if (r < 0)
|
||||||
|
log_device_warning_errno(dev, r, "Failed to process device, ignoring: %m");
|
||||||
|
|
||||||
/* send processed event back to libudev listeners */
|
/* send processed event back to libudev listeners */
|
||||||
r = device_monitor_send_device(monitor, NULL, dev);
|
r = device_monitor_send_device(monitor, NULL, dev);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_device_warning_errno(dev, r, "Failed to send device, ignoring: %m");
|
log_device_warning_errno(dev, r, "Failed to send device, ignoring: %m");
|
||||||
|
}
|
||||||
|
|
||||||
/* send udevd the result of the event execution */
|
/* send udevd the result of the event execution */
|
||||||
r = worker_send_message(manager->worker_watch[WRITE_END]);
|
r = worker_send_message(manager->worker_watch[WRITE_END]);
|
||||||
|
|
|
@ -73,7 +73,6 @@ static int xdg_config_parse_bool(
|
||||||
void *userdata) {
|
void *userdata) {
|
||||||
|
|
||||||
bool *b = data;
|
bool *b = data;
|
||||||
const char *value;
|
|
||||||
|
|
||||||
assert(filename);
|
assert(filename);
|
||||||
assert(lvalue);
|
assert(lvalue);
|
||||||
|
@ -85,7 +84,7 @@ static int xdg_config_parse_bool(
|
||||||
else if (streq(rvalue, "false"))
|
else if (streq(rvalue, "false"))
|
||||||
*b = false;
|
*b = false;
|
||||||
else
|
else
|
||||||
return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL), "Invalid value for boolean: %s", value);
|
return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL), "Invalid value for boolean: %s", rvalue);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,6 +119,7 @@ SendOption=
|
||||||
RequestOptions=
|
RequestOptions=
|
||||||
UserClass=
|
UserClass=
|
||||||
VendorClass=
|
VendorClass=
|
||||||
|
AssignAcquiredDelegatedPrefixAddress=
|
||||||
[Route]
|
[Route]
|
||||||
Destination=
|
Destination=
|
||||||
Protocol=
|
Protocol=
|
||||||
|
|
|
@ -164,6 +164,7 @@ PIDFile=
|
||||||
PartOf=
|
PartOf=
|
||||||
PassCredentials=
|
PassCredentials=
|
||||||
PassSecurity=
|
PassSecurity=
|
||||||
|
PassPacketInfo=
|
||||||
PathChanged=
|
PathChanged=
|
||||||
PathExists=
|
PathExists=
|
||||||
PathExistsGlob=
|
PathExistsGlob=
|
||||||
|
|
|
@ -4,4 +4,3 @@ Name=test1
|
||||||
[Network]
|
[Network]
|
||||||
Address=192.168.0.15/24
|
Address=192.168.0.15/24
|
||||||
Gateway=192.168.0.1
|
Gateway=192.168.0.1
|
||||||
ConfigureWithoutCarrier=true
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
[Network]
|
||||||
|
ConfigureWithoutCarrier=true
|
|
@ -0,0 +1,2 @@
|
||||||
|
[Network]
|
||||||
|
IgnoreCarrierLoss=false
|
|
@ -0,0 +1,9 @@
|
||||||
|
[Match]
|
||||||
|
Name=bridge99
|
||||||
|
|
||||||
|
[Network]
|
||||||
|
LinkLocalAddressing=yes
|
||||||
|
IPv6AcceptRA=no
|
||||||
|
ConfigureWithoutCarrier=yes
|
||||||
|
Address=10.1.2.3/24
|
||||||
|
Gateway=10.1.2.1
|
|
@ -445,6 +445,9 @@ class Utilities():
|
||||||
def check_link_exists(self, link):
|
def check_link_exists(self, link):
|
||||||
self.assertTrue(link_exists(link))
|
self.assertTrue(link_exists(link))
|
||||||
|
|
||||||
|
def check_link_attr(self, *args):
|
||||||
|
self.assertEqual(read_link_attr(*args[:-1]), args[-1]);
|
||||||
|
|
||||||
def wait_operstate(self, link, operstate='degraded', setup_state='configured', setup_timeout=5, fail_assert=True):
|
def wait_operstate(self, link, operstate='degraded', setup_state='configured', setup_timeout=5, fail_assert=True):
|
||||||
"""Wait for the link to reach the specified operstate and/or setup state.
|
"""Wait for the link to reach the specified operstate and/or setup state.
|
||||||
|
|
||||||
|
@ -1671,11 +1674,11 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
||||||
'25-gateway-next-static.network',
|
'25-gateway-next-static.network',
|
||||||
'25-sysctl-disable-ipv6.network',
|
'25-sysctl-disable-ipv6.network',
|
||||||
'25-sysctl.network',
|
'25-sysctl.network',
|
||||||
|
'25-test1.network',
|
||||||
'25-veth-peer.network',
|
'25-veth-peer.network',
|
||||||
'25-veth.netdev',
|
'25-veth.netdev',
|
||||||
'25-vrf.netdev',
|
'25-vrf.netdev',
|
||||||
'26-link-local-addressing-ipv6.network',
|
'26-link-local-addressing-ipv6.network',
|
||||||
'configure-without-carrier.network',
|
|
||||||
'routing-policy-rule-dummy98.network',
|
'routing-policy-rule-dummy98.network',
|
||||||
'routing-policy-rule-test1.network']
|
'routing-policy-rule-test1.network']
|
||||||
|
|
||||||
|
@ -1762,15 +1765,56 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
||||||
self.assertNotRegex(output, '192.168.100.10/24')
|
self.assertNotRegex(output, '192.168.100.10/24')
|
||||||
|
|
||||||
def test_configure_without_carrier(self):
|
def test_configure_without_carrier(self):
|
||||||
copy_unit_to_networkd_unit_path('configure-without-carrier.network', '11-dummy.netdev')
|
copy_unit_to_networkd_unit_path('11-dummy.netdev')
|
||||||
start_networkd()
|
start_networkd()
|
||||||
self.wait_online(['test1:routable'])
|
self.wait_operstate('test1', 'off', '')
|
||||||
|
check_output('ip link set dev test1 up carrier off')
|
||||||
|
|
||||||
output = check_output(*networkctl_cmd, '-n', '0', 'status', 'test1', env=env)
|
copy_unit_to_networkd_unit_path('25-test1.network.d/configure-without-carrier.conf', dropins=False)
|
||||||
print(output)
|
restart_networkd()
|
||||||
self.assertRegex(output, '192.168.0.15')
|
self.wait_online(['test1:no-carrier'])
|
||||||
self.assertRegex(output, '192.168.0.1')
|
|
||||||
self.assertRegex(output, 'routable')
|
carrier_map = {'on': '1', 'off': '0'}
|
||||||
|
routable_map = {'on': 'routable', 'off': 'no-carrier'}
|
||||||
|
for carrier in ['off', 'on', 'off']:
|
||||||
|
with self.subTest(carrier=carrier):
|
||||||
|
if carrier_map[carrier] != read_link_attr('test1', 'carrier'):
|
||||||
|
check_output(f'ip link set dev test1 carrier {carrier}')
|
||||||
|
self.wait_online([f'test1:{routable_map[carrier]}'])
|
||||||
|
|
||||||
|
output = check_output(*networkctl_cmd, '-n', '0', 'status', 'test1', env=env)
|
||||||
|
print(output)
|
||||||
|
self.assertRegex(output, '192.168.0.15')
|
||||||
|
self.assertRegex(output, '192.168.0.1')
|
||||||
|
self.assertRegex(output, routable_map[carrier])
|
||||||
|
|
||||||
|
def test_configure_without_carrier_yes_ignore_carrier_loss_no(self):
|
||||||
|
copy_unit_to_networkd_unit_path('11-dummy.netdev')
|
||||||
|
start_networkd()
|
||||||
|
self.wait_operstate('test1', 'off', '')
|
||||||
|
check_output('ip link set dev test1 up carrier off')
|
||||||
|
|
||||||
|
copy_unit_to_networkd_unit_path('25-test1.network')
|
||||||
|
restart_networkd()
|
||||||
|
self.wait_online(['test1:no-carrier'])
|
||||||
|
|
||||||
|
carrier_map = {'on': '1', 'off': '0'}
|
||||||
|
routable_map = {'on': 'routable', 'off': 'no-carrier'}
|
||||||
|
for (carrier, have_config) in [('off', True), ('on', True), ('off', False)]:
|
||||||
|
with self.subTest(carrier=carrier, have_config=have_config):
|
||||||
|
if carrier_map[carrier] != read_link_attr('test1', 'carrier'):
|
||||||
|
check_output(f'ip link set dev test1 carrier {carrier}')
|
||||||
|
self.wait_online([f'test1:{routable_map[carrier]}'])
|
||||||
|
|
||||||
|
output = check_output(*networkctl_cmd, '-n', '0', 'status', 'test1', env=env)
|
||||||
|
print(output)
|
||||||
|
if have_config:
|
||||||
|
self.assertRegex(output, '192.168.0.15')
|
||||||
|
self.assertRegex(output, '192.168.0.1')
|
||||||
|
else:
|
||||||
|
self.assertNotRegex(output, '192.168.0.15')
|
||||||
|
self.assertNotRegex(output, '192.168.0.1')
|
||||||
|
self.assertRegex(output, routable_map[carrier])
|
||||||
|
|
||||||
def test_routing_policy_rule(self):
|
def test_routing_policy_rule(self):
|
||||||
copy_unit_to_networkd_unit_path('routing-policy-rule-test1.network', '11-dummy.netdev')
|
copy_unit_to_networkd_unit_path('routing-policy-rule-test1.network', '11-dummy.netdev')
|
||||||
|
@ -2608,6 +2652,7 @@ class NetworkdBridgeTests(unittest.TestCase, Utilities):
|
||||||
'11-dummy.netdev',
|
'11-dummy.netdev',
|
||||||
'12-dummy.netdev',
|
'12-dummy.netdev',
|
||||||
'26-bridge.netdev',
|
'26-bridge.netdev',
|
||||||
|
'26-bridge-configure-without-carrier.network',
|
||||||
'26-bridge-slave-interface-1.network',
|
'26-bridge-slave-interface-1.network',
|
||||||
'26-bridge-slave-interface-2.network',
|
'26-bridge-slave-interface-2.network',
|
||||||
'26-bridge-vlan-master.network',
|
'26-bridge-vlan-master.network',
|
||||||
|
@ -2722,6 +2767,55 @@ class NetworkdBridgeTests(unittest.TestCase, Utilities):
|
||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, 'ff00::/8 table local metric 256 (linkdown )?pref medium')
|
self.assertRegex(output, 'ff00::/8 table local metric 256 (linkdown )?pref medium')
|
||||||
|
|
||||||
|
def test_bridge_configure_without_carrier(self):
|
||||||
|
copy_unit_to_networkd_unit_path('26-bridge.netdev', '26-bridge-configure-without-carrier.network',
|
||||||
|
'11-dummy.netdev')
|
||||||
|
start_networkd()
|
||||||
|
|
||||||
|
# With ConfigureWithoutCarrier=yes, the bridge should remain configured for all these situations
|
||||||
|
for test in ['no-slave', 'add-slave', 'slave-up', 'slave-no-carrier', 'slave-carrier', 'slave-down']:
|
||||||
|
with self.subTest(test=test):
|
||||||
|
if test == 'no-slave':
|
||||||
|
# bridge has no slaves; it's up but *might* not have carrier
|
||||||
|
self.wait_online(['bridge99:no-carrier'])
|
||||||
|
# due to a bug in the kernel, newly-created bridges are brought up
|
||||||
|
# *with* carrier, unless they have had any setting changed; e.g.
|
||||||
|
# their mac set, priority set, etc. Then, they will lose carrier
|
||||||
|
# as soon as a (down) slave interface is added, and regain carrier
|
||||||
|
# again once the slave interface is brought up.
|
||||||
|
#self.check_link_attr('bridge99', 'carrier', '0')
|
||||||
|
elif test == 'add-slave':
|
||||||
|
# add slave to bridge, but leave it down; bridge is definitely no-carrier
|
||||||
|
self.check_link_attr('test1', 'operstate', 'down')
|
||||||
|
check_output('ip link set dev test1 master bridge99')
|
||||||
|
self.wait_online(['bridge99:no-carrier:no-carrier'])
|
||||||
|
self.check_link_attr('bridge99', 'carrier', '0')
|
||||||
|
elif test == 'slave-up':
|
||||||
|
# bring up slave, which will have carrier; bridge gains carrier
|
||||||
|
check_output('ip link set dev test1 up')
|
||||||
|
self.wait_online(['bridge99:routable'])
|
||||||
|
self.check_link_attr('bridge99', 'carrier', '1')
|
||||||
|
elif test == 'slave-no-carrier':
|
||||||
|
# drop slave carrier; bridge loses carrier
|
||||||
|
check_output('ip link set dev test1 carrier off')
|
||||||
|
self.wait_online(['bridge99:no-carrier:no-carrier'])
|
||||||
|
self.check_link_attr('bridge99', 'carrier', '0')
|
||||||
|
elif test == 'slave-carrier':
|
||||||
|
# restore slave carrier; bridge gains carrier
|
||||||
|
check_output('ip link set dev test1 carrier on')
|
||||||
|
self.wait_online(['bridge99:routable'])
|
||||||
|
self.check_link_attr('bridge99', 'carrier', '1')
|
||||||
|
elif test == 'slave-down':
|
||||||
|
# bring down slave; bridge loses carrier
|
||||||
|
check_output('ip link set dev test1 down')
|
||||||
|
self.wait_online(['bridge99:no-carrier:no-carrier'])
|
||||||
|
self.check_link_attr('bridge99', 'carrier', '0')
|
||||||
|
|
||||||
|
output = check_output(*networkctl_cmd, '-n', '0', 'status', 'bridge99', env=env)
|
||||||
|
print(output)
|
||||||
|
self.assertRegex(output, '10.1.2.3')
|
||||||
|
self.assertRegex(output, '10.1.2.1')
|
||||||
|
|
||||||
def test_bridge_ignore_carrier_loss(self):
|
def test_bridge_ignore_carrier_loss(self):
|
||||||
copy_unit_to_networkd_unit_path('11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev',
|
copy_unit_to_networkd_unit_path('11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev',
|
||||||
'26-bridge-slave-interface-1.network', '26-bridge-slave-interface-2.network',
|
'26-bridge-slave-interface-1.network', '26-bridge-slave-interface-2.network',
|
||||||
|
|
|
@ -37,3 +37,4 @@ SystemCallFilter=@system-service @mount
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
Alias=dbus-org.freedesktop.home1.service
|
Alias=dbus-org.freedesktop.home1.service
|
||||||
|
Also=systemd-userdbd.service
|
||||||
|
|
|
@ -17,7 +17,7 @@ Before=sockets.target
|
||||||
[Socket]
|
[Socket]
|
||||||
ReceiveBuffer=128M
|
ReceiveBuffer=128M
|
||||||
ListenNetlink=route 1361
|
ListenNetlink=route 1361
|
||||||
PassCredentials=yes
|
PassPacketInfo=yes
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=sockets.target
|
WantedBy=sockets.target
|
||||||
|
|
Loading…
Reference in New Issue