1
0
mirror of https://github.com/systemd/systemd synced 2025-10-01 09:44:46 +02:00

Compare commits

...

40 Commits

Author SHA1 Message Date
Lennart Poettering
dc288ffeab
Merge pull request #18596 from keszybz/systemctl-quiet-legend
systemctl: hide legends with --quiet, allow overriding
2021-02-17 23:40:04 +01:00
Lennart Poettering
a63b54eda5
Merge pull request #18651 from poettering/einval-followup
two follow-up fixes for the enum einvalification
2021-02-17 23:15:50 +01:00
Susant Sahani
176321cb95 network: DHCP option- use correct byteorder 2021-02-17 23:15:26 +01:00
Lennart Poettering
07335f7f1f
Merge pull request #18656 from yuwata/network-nexthop-tiny-cleanups
network: nexthop: tiny cleanups
2021-02-17 23:14:12 +01:00
Lennart Poettering
6e825539d2 hwdb: fix indentation
a bunch of entries use 2ch instead of 1ch indentation. Fix that.
2021-02-17 23:13:45 +01:00
Lennart Poettering
2840d6f61d
Merge pull request #18662 from yuwata/in-addr-is-set
in-addr-util: introduce in_addr_is_set() or friends
2021-02-17 23:13:27 +01:00
Zbigniew Jędrzejewski-Szmek
42a033f784 sysctl: downgrade warning about excluded keys
Our own config generates logs like this:
systemd-sysctl[1280]: Not setting net/ipv4/conf/all/rp_filter (explicit setting exists).
systemd-sysctl[1280]: Not setting net/ipv4/conf/default/rp_filter (explicit setting exists).
systemd-sysctl[1280]: Not setting net/ipv4/conf/all/accept_source_route (explicit setting exists).
systemd-sysctl[1280]: Not setting net/ipv4/conf/default/accept_source_route (explicit setting exists).
systemd-sysctl[1280]: Not setting net/ipv4/conf/all/promote_secondaries (explicit setting exists).
systemd-sysctl[1280]: Not setting net/ipv4/conf/default/promote_secondaries (explicit setting exists).

There is no error and nothing really to see.
2021-02-17 23:13:01 +01:00
Zbigniew Jędrzejewski-Szmek
d60bd2ffb7 shell-completion: complete --legend=no for resolvectl and systemctl
I don't think it makes sense to complete --legend=yes. It is the default, and
it would be only used very rarely (and then it is easy enough to just remove
the '=no' part from the suggested string).
2021-02-17 21:09:14 +01:00
Zbigniew Jędrzejewski-Szmek
6906da2692 systemctl: hide legends with --quiet, allow overriding
--no-legend is replaced by --legend=no.

--quiet now implies --legend=no, but --legend=yes may be used to override that.
--quiet controls hints and warnings and such, and --legend controls just the
legends. I think it makes sense to allow both to controlled independently, in
particular --quiet --legend makes sense when using systemctl in a script to
provide some user-visible output.

Fixes #18560.
2021-02-17 21:09:14 +01:00
Zbigniew Jędrzejewski-Szmek
b01031e3ff journal-remote: inline one more iterator variable declaration 2021-02-17 21:09:14 +01:00
Zbigniew Jędrzejewski-Szmek
9c7f220173 journal-remote: convert to parse_boolean_argument() and fix type confusion
We were passing a reference to 'int arg_seal' to config_parse_bool(),
which expects a 'bool *'. Luckily, this would work, because 'bool'
is smaller than 'int', so config_parse_bool() would set the least-significant
byte of arg_seal. At least I think so. But let's use consistent types ;)

Also, modernize style a bit and don't use integers in boolean context.
2021-02-17 21:08:50 +01:00
Zbigniew Jędrzejewski-Szmek
c3470872c6 tree-wide: use parse_boolean_argument() for variables with non-boolean type
This still works nicely, but we need to assign the return value ourselves.
As before, one nice effect is that error messages are uniform.
2021-02-17 21:08:47 +01:00
Zbigniew Jędrzejewski-Szmek
599c7c545f tree-wide: add a helper to parse boolean optarg
This nicely covers the case when optarg is optional. The same parser can be
used when the option string passed to getopt_long() requires a parameter and
when it doesn't.

The error messages are made consistent.
Also fixes a log error c&p in --crash-reboot message.
2021-02-17 21:06:31 +01:00
Yu Watanabe
ccbd74f602 network: NHA_ID should be always set 2021-02-18 03:56:26 +09:00
Yu Watanabe
c004cd2bbe network: constify arguments 2021-02-18 03:54:50 +09:00
Yu Watanabe
56223d926d network: introduce log_nexthop_debug() 2021-02-18 03:54:50 +09:00
Lennart Poettering
6283e71ba8
Merge pull request #18640 from poettering/resolved-dnssec-retry-harder
resolved: two dnssec retry/downgrade tweaks
2021-02-17 19:50:58 +01:00
Yu Watanabe
c633628daf tree-wide: constify variables if possible 2021-02-18 03:48:07 +09:00
Yu Watanabe
94af46fc66 network: use temporary buffer for safety 2021-02-18 03:48:07 +09:00
Yu Watanabe
5380707aba network: use in_addr_prefix_to_string() 2021-02-18 03:48:07 +09:00
Yu Watanabe
b1dea5cffa resolve: use sockaddr_in_addr() 2021-02-18 03:48:07 +09:00
Yu Watanabe
bb3b08ad98 resolve: make manager_find_ifindex() or friends return earlier 2021-02-18 03:48:07 +09:00
Yu Watanabe
94876904bb tree-wide: use in_addr_is_set() or friends 2021-02-18 03:48:07 +09:00
Yu Watanabe
275468c033 network: assign values after all checks are passed 2021-02-18 03:48:07 +09:00
Yu Watanabe
fa55043450 in-addr-util: introduce in6_addr_equal() 2021-02-18 03:48:06 +09:00
Yu Watanabe
1235befadd in-addr-util: introduce in6_addr_is_link_local() 2021-02-18 03:48:06 +09:00
Yu Watanabe
7653dcc328 in-addr-util: introduce in_addr_is_set() or friends 2021-02-18 03:48:06 +09:00
Yu Watanabe
0c0585ca25 network: enumerate nexthops before routes
Preparation for the later commits.
Routes may have RTA_NH_ID attribute. To resolve the nexthop ID, all
nexthops must be enumerated earlier.
2021-02-17 19:40:02 +01:00
Yu Watanabe
055e4909de network: nexthop: first create nexthops with ID
Otherwise, an ID-less nexthop may conflict with a later nexthop with ID.
2021-02-17 19:39:37 +01:00
Lennart Poettering
ba5b6c5925 portable: make PortableChangeType enum anonymous
Same reasons as previous commit.
2021-02-17 19:29:24 +01:00
Lennart Poettering
93419a9601 install: make UnitFileChangeType enum anonymous
We almost never use the named enum type, in almost all cases we use
"int" instead, since we overload it with negative errnos. To simplify
things, let's use "int" really everywhere.

Moreover, let's rename the fields for this enum to "type_or_errno", to
make the overloading clear. And let's ad some assertions that things are
in the right range.
2021-02-17 19:29:24 +01:00
Lennart Poettering
e30a62bfe6 resolved: see if it's worth retrying a lookup on "failed-auxiliary" DNSSEC error
Maybe we learnt something about the server feature set, let's hence
retry.

Fixes: #11102
2021-02-17 19:25:13 +01:00
Lennart Poettering
d96275d8eb resolved: in DNSSEC permissive mode, check if DO bit wasn't copied from request to response
If the server doesn't copy the DO bit from request to response, this is
a very early and easy indication that it doesn#t support DNSSEC
properly. Hence, let's immediately downgrade to non-DNSSEC mode if we
see this – if permissive mode is on and this is allowed.
2021-02-17 19:25:13 +01:00
Luca Boccassi
0761da386a test: avoid leaking open loop devices
When a subshell is used ('make' or 'make all') the LOOPDEV environment
variable, which is used to store the opened loop device, is lost.
So the cleanup on trap/exit doesn't do anything, and the loop
device used to mount the test image is left around.

Avoid using a subshell to fix the issue.
2021-02-17 18:55:05 +01:00
Lennart Poettering
50fc7d7036
Merge pull request #18653 from yuwata/in-addr-prefix-nth
in-addr-util: fix in_addr_prefix_nth() and use the function to get ip address range in firewall-util
2021-02-17 18:52:24 +01:00
Yu Watanabe
9997507421 firewall-util: replace nft_in6addr_to_range() with in_addr_prefix_range() 2021-02-17 22:57:37 +09:00
Yu Watanabe
1534c5791a in-addr-util: introduce in_addr_prefix_range()
This will replace nft_in6addr_to_range() in later commit.
2021-02-17 22:57:37 +09:00
Yu Watanabe
9164338b2e in-addr-util: make in_addr_prefix_nth() always return valid prefix
Previously, e.g. in_addr_prefix_nth(2400::1, prefixlen=32, nth=1)
does not return 2400:1:: but does 2400:1::1.
2021-02-17 22:57:37 +09:00
Yu Watanabe
7b6b05cff9 in-addr-util: make in_addr_prefix_nth() refuse prefixlen larger than maximum size 2021-02-17 22:57:37 +09:00
Yu Watanabe
518b6da5d3 in-addr-util: make in_addr_prefix_nth() returns 0 on success 2021-02-17 22:57:37 +09:00
86 changed files with 854 additions and 768 deletions

View File

@ -553,15 +553,15 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHP*:pnHPENVYx360Convertible13*:*
# HP Elite x2 1013 G3 # HP Elite x2 1013 G3
evdev:atkbd:dmi:bvn*:bvr*:svnHP*:pnHPElitex21013G3:* evdev:atkbd:dmi:bvn*:bvr*:svnHP*:pnHPElitex21013G3:*
KEYBOARD_KEY_f8=unknown # rfkill is also reported by HP Wireless hotkeys KEYBOARD_KEY_f8=unknown # rfkill is also reported by HP Wireless hotkeys
KEYBOARD_KEY_64=calendar KEYBOARD_KEY_64=calendar
KEYBOARD_KEY_81=f20 # Microphone mute button KEYBOARD_KEY_81=f20 # Microphone mute button
KEYBOARD_KEY_ee=switchvideomode # Switch display outputs KEYBOARD_KEY_ee=switchvideomode # Switch display outputs
KEYBOARD_KEY_92=brightnessdown KEYBOARD_KEY_92=brightnessdown
KEYBOARD_KEY_97=brightnessup KEYBOARD_KEY_97=brightnessup
evdev:name:Intel HID events:dmi:bvn*:bvr*:svnHP*:pnHPElitex21013G3:* evdev:name:Intel HID events:dmi:bvn*:bvr*:svnHP*:pnHPElitex21013G3:*
KEYBOARD_KEY_08=unknown # rfkill is also reported by HP Wireless hotkeys KEYBOARD_KEY_08=unknown # rfkill is also reported by HP Wireless hotkeys
# Elitebook # Elitebook
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*Compaq*:* evdev:atkbd:dmi:bvn*:bvr*:bd*:svnHewlett-Packard*:pn*Compaq*:*

View File

@ -35,6 +35,15 @@
<listitem><para>Do not query the user for authentication for privileged operations.</para></listitem> <listitem><para>Do not query the user for authentication for privileged operations.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry id='legend'>
<term><option>--legend=</option><replaceable>BOOL</replaceable></term>
<listitem>
<para>Enable or disable printing of the legend, i.e. column headers and the footer with hints. The
legend is printed by default, unless disabled with <option>--quiet</option> or similar.</para>
</listitem>
</varlistentry>
<varlistentry id='no-legend'> <varlistentry id='no-legend'>
<term><option>--no-legend</option></term> <term><option>--no-legend</option></term>

View File

@ -2326,7 +2326,7 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
<xi:include href="user-system-options.xml" xpointer="machine" /> <xi:include href="user-system-options.xml" xpointer="machine" />
<xi:include href="standard-options.xml" xpointer="no-pager" /> <xi:include href="standard-options.xml" xpointer="no-pager" />
<xi:include href="standard-options.xml" xpointer="no-legend" /> <xi:include href="standard-options.xml" xpointer="legend" />
<xi:include href="standard-options.xml" xpointer="help" /> <xi:include href="standard-options.xml" xpointer="help" />
<xi:include href="standard-options.xml" xpointer="version" /> <xi:include href="standard-options.xml" xpointer="version" />
</variablelist> </variablelist>

View File

@ -7,7 +7,7 @@
__systemctl() { __systemctl() {
local mode=$1; shift 1 local mode=$1; shift 1
systemctl $mode --full --no-legend --no-pager --plain "$@" 2>/dev/null systemctl $mode --full --legend=no --no-pager --plain "$@" 2>/dev/null
} }
__systemd_properties() { __systemd_properties() {
@ -123,7 +123,7 @@ _systemctl () {
local -A OPTS=( local -A OPTS=(
[STANDALONE]='--all -a --reverse --after --before --defaults --force -f --full -l --global [STANDALONE]='--all -a --reverse --after --before --defaults --force -f --full -l --global
--help -h --no-ask-password --no-block --no-legend --no-pager --no-reload --no-wall --now --help -h --no-ask-password --no-block --legend=no --no-pager --no-reload --no-wall --now
--quiet -q --system --user --version --runtime --recursive -r --firmware-setup --quiet -q --system --user --version --runtime --recursive -r --firmware-setup
--show-types --plain --failed --value --fail --dry-run --wait' --show-types --plain --failed --value --fail --dry-run --wait'
[ARG]='--host -H --kill-who --property -p --signal -s --type -t --state --job-mode --root [ARG]='--host -H --kill-who --property -p --signal -s --type -t --state --job-mode --root

View File

@ -147,7 +147,7 @@
# @todo _systemd-run has a helper with the same name, so we must redefine # @todo _systemd-run has a helper with the same name, so we must redefine
__systemctl() __systemctl()
{ {
systemctl $_sys_service_mgr --full --no-legend --no-pager --plain "$@" 2>/dev/null systemctl $_sys_service_mgr --full --legend=no --no-pager --plain "$@" 2>/dev/null
} }
@ -480,7 +480,7 @@ _arguments -s \
'--check-inhibitors[Specify if inhibitors should be checked]:mode:_systemctl_check_inhibitors' \ '--check-inhibitors[Specify if inhibitors should be checked]:mode:_systemctl_check_inhibitors' \
{-q,--quiet}'[Suppress output]' \ {-q,--quiet}'[Suppress output]' \
'--no-block[Do not wait until operation finished]' \ '--no-block[Do not wait until operation finished]' \
'--no-legend[Do not print a legend, i.e. the column headers and the footer with hints]' \ '--legend=no[Do not print a legend, i.e. the column headers and the footer with hints]' \
'--no-pager[Do not pipe output into a pager]' \ '--no-pager[Do not pipe output into a pager]' \
'--system[Connect to system manager]' \ '--system[Connect to system manager]' \
'--user[Connect to user service manager]' \ '--user[Connect to user service manager]' \

View File

@ -37,6 +37,7 @@
#include "main-func.h" #include "main-func.h"
#include "nulstr-util.h" #include "nulstr-util.h"
#include "pager.h" #include "pager.h"
#include "parse-argument.h"
#include "parse-util.h" #include "parse-util.h"
#include "path-util.h" #include "path-util.h"
#include "pretty-print.h" #include "pretty-print.h"
@ -2340,29 +2341,15 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_MAN: case ARG_MAN:
if (optarg) { r = parse_boolean_argument("--man", optarg, &arg_man);
r = parse_boolean(optarg); if (r < 0)
if (r < 0) return r;
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Failed to parse --man= argument.");
arg_man = r;
} else
arg_man = true;
break; break;
case ARG_GENERATORS: case ARG_GENERATORS:
if (optarg) { r = parse_boolean_argument("--generators", optarg, &arg_generators);
r = parse_boolean(optarg); if (r < 0)
if (r < 0) return r;
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Failed to parse --generators= argument.");
arg_generators = r;
} else
arg_generators = true;
break; break;
case ARG_ITERATIONS: case ARG_ITERATIONS:

View File

@ -24,6 +24,12 @@ bool in4_addr_is_null(const struct in_addr *a) {
return a->s_addr == 0; return a->s_addr == 0;
} }
bool in6_addr_is_null(const struct in6_addr *a) {
assert(a);
return IN6_IS_ADDR_UNSPECIFIED(a);
}
int in_addr_is_null(int family, const union in_addr_union *u) { int in_addr_is_null(int family, const union in_addr_union *u) {
assert(u); assert(u);
@ -31,7 +37,7 @@ int in_addr_is_null(int family, const union in_addr_union *u) {
return in4_addr_is_null(&u->in); return in4_addr_is_null(&u->in);
if (family == AF_INET6) if (family == AF_INET6)
return IN6_IS_ADDR_UNSPECIFIED(&u->in6); return in6_addr_is_null(&u->in6);
return -EAFNOSUPPORT; return -EAFNOSUPPORT;
} }
@ -42,6 +48,12 @@ bool in4_addr_is_link_local(const struct in_addr *a) {
return (be32toh(a->s_addr) & UINT32_C(0xFFFF0000)) == (UINT32_C(169) << 24 | UINT32_C(254) << 16); return (be32toh(a->s_addr) & UINT32_C(0xFFFF0000)) == (UINT32_C(169) << 24 | UINT32_C(254) << 16);
} }
bool in6_addr_is_link_local(const struct in6_addr *a) {
assert(a);
return IN6_IS_ADDR_LINKLOCAL(a);
}
int in_addr_is_link_local(int family, const union in_addr_union *u) { int in_addr_is_link_local(int family, const union in_addr_union *u) {
assert(u); assert(u);
@ -49,7 +61,7 @@ int in_addr_is_link_local(int family, const union in_addr_union *u) {
return in4_addr_is_link_local(&u->in); return in4_addr_is_link_local(&u->in);
if (family == AF_INET6) if (family == AF_INET6)
return IN6_IS_ADDR_LINKLOCAL(&u->in6); return in6_addr_is_link_local(&u->in6);
return -EAFNOSUPPORT; return -EAFNOSUPPORT;
} }
@ -116,6 +128,13 @@ bool in4_addr_equal(const struct in_addr *a, const struct in_addr *b) {
return a->s_addr == b->s_addr; return a->s_addr == b->s_addr;
} }
bool in6_addr_equal(const struct in6_addr *a, const struct in6_addr *b) {
assert(a);
assert(b);
return IN6_ARE_ADDR_EQUAL(a, b);
}
int in_addr_equal(int family, const union in_addr_union *a, const union in_addr_union *b) { int in_addr_equal(int family, const union in_addr_union *a, const union in_addr_union *b) {
assert(a); assert(a);
assert(b); assert(b);
@ -124,7 +143,7 @@ int in_addr_equal(int family, const union in_addr_union *a, const union in_addr_
return in4_addr_equal(&a->in, &b->in); return in4_addr_equal(&a->in, &b->in);
if (family == AF_INET6) if (family == AF_INET6)
return IN6_ARE_ADDR_EQUAL(&a->in6, &b->in6); return in6_addr_equal(&a->in6, &b->in6);
return -EAFNOSUPPORT; return -EAFNOSUPPORT;
} }
@ -189,8 +208,8 @@ int in_addr_prefix_intersect(
int in_addr_prefix_next(int family, union in_addr_union *u, unsigned prefixlen) { int in_addr_prefix_next(int family, union in_addr_union *u, unsigned prefixlen) {
assert(u); assert(u);
/* Increases the network part of an address by one. Returns /* Increases the network part of an address by one. Returns 0 if that succeeds, or -ERANGE if
* positive if that succeeds, or -ERANGE if this overflows. */ * this overflows. */
return in_addr_prefix_nth(family, u, prefixlen, 1); return in_addr_prefix_nth(family, u, prefixlen, 1);
} }
@ -198,19 +217,17 @@ int in_addr_prefix_next(int family, union in_addr_union *u, unsigned prefixlen)
/* /*
* Calculates the nth prefix of size prefixlen starting from the address denoted by u. * Calculates the nth prefix of size prefixlen starting from the address denoted by u.
* *
* On success 1 will be returned and the calculated prefix will be available in * On success 0 will be returned and the calculated prefix will be available in
* u. In the case nth == 0 the input will be left unchanged and 1 will be returned. * u. In case the calculation cannot be performed (invalid prefix length,
* In case the calculation cannot be performed (invalid prefix length,
* overflows would occur) -ERANGE is returned. If the address family given isn't * overflows would occur) -ERANGE is returned. If the address family given isn't
* supported -EAFNOSUPPORT will be returned. * supported -EAFNOSUPPORT will be returned.
* *
*
* Examples: * Examples:
* - in_addr_prefix_nth(AF_INET, 192.168.0.0, 24, 2), returns 1, writes 192.168.2.0 to u * - in_addr_prefix_nth(AF_INET, 192.168.0.0, 24, 2), returns 0, writes 192.168.2.0 to u
* - in_addr_prefix_nth(AF_INET, 192.168.0.0, 24, 0), returns 1, no data written * - in_addr_prefix_nth(AF_INET, 192.168.0.0, 24, 0), returns 0, no data written
* - in_addr_prefix_nth(AF_INET, 255.255.255.0, 24, 1), returns -ERANGE, no data written * - in_addr_prefix_nth(AF_INET, 255.255.255.0, 24, 1), returns -ERANGE, no data written
* - in_addr_prefix_nth(AF_INET, 255.255.255.0, 0, 1), returns -ERANGE, no data written * - in_addr_prefix_nth(AF_INET, 255.255.255.0, 0, 1), returns -ERANGE, no data written
* - in_addr_prefix_nth(AF_INET6, 2001:db8, 64, 0xff00) returns 1, writes 2001:0db8:0000:ff00:: to u * - in_addr_prefix_nth(AF_INET6, 2001:db8, 64, 0xff00) returns 0, writes 2001:0db8:0000:ff00:: to u
*/ */
int in_addr_prefix_nth(int family, union in_addr_union *u, unsigned prefixlen, uint64_t nth) { int in_addr_prefix_nth(int family, union in_addr_union *u, unsigned prefixlen, uint64_t nth) {
assert(u); assert(u);
@ -218,13 +235,11 @@ int in_addr_prefix_nth(int family, union in_addr_union *u, unsigned prefixlen, u
if (prefixlen <= 0) if (prefixlen <= 0)
return -ERANGE; return -ERANGE;
if (nth == 0)
return 1;
if (family == AF_INET) { if (family == AF_INET) {
uint32_t c, n, t; uint32_t c, n, t;
if (prefixlen > 32) if (prefixlen > 32)
prefixlen = 32; return -ERANGE;
c = be32toh(u->in.s_addr); c = be32toh(u->in.s_addr);
@ -238,44 +253,40 @@ int in_addr_prefix_nth(int family, union in_addr_union *u, unsigned prefixlen, u
n &= UINT32_C(0xFFFFFFFF) << (32 - prefixlen); n &= UINT32_C(0xFFFFFFFF) << (32 - prefixlen);
u->in.s_addr = htobe32(n); u->in.s_addr = htobe32(n);
return 1; return 0;
} }
if (family == AF_INET6) { if (family == AF_INET6) {
struct in6_addr result = {}; bool overflow = false;
uint8_t overflow = 0;
uint64_t delta; /* this assumes that we only ever have to up to 1<<64 subnets */
unsigned start_byte = (prefixlen - 1) / 8;
if (prefixlen > 128) if (prefixlen > 128)
prefixlen = 128;
/* First calculate what we have to add */
delta = nth << ((128 - prefixlen) % 8);
for (unsigned i = 16; i > 0; i--) {
unsigned j = i - 1;
unsigned d = 0;
if (j <= start_byte) {
int16_t t;
d = delta & 0xFF;
delta >>= 8;
t = u->in6.s6_addr[j] + d + overflow;
overflow = t > UINT8_MAX ? t - UINT8_MAX : 0;
result.s6_addr[j] = (uint8_t)t;
} else
result.s6_addr[j] = u->in6.s6_addr[j];
}
if (overflow || delta != 0)
return -ERANGE; return -ERANGE;
u->in6 = result; for (unsigned i = 16; i > 0; i--) {
return 1; unsigned t, j = i - 1, p = j * 8;
if (p >= prefixlen) {
u->in6.s6_addr[j] = 0;
continue;
}
if (prefixlen - p < 8) {
u->in6.s6_addr[j] &= 0xff << (8 - (prefixlen - p));
t = u->in6.s6_addr[j] + ((nth & 0xff) << (8 - (prefixlen - p)));
nth >>= prefixlen - p;
} else {
t = u->in6.s6_addr[j] + (nth & 0xff) + overflow;
nth >>= 8;
}
overflow = t > UINT8_MAX;
u->in6.s6_addr[j] = (uint8_t) (t & 0xff);
}
if (overflow || nth != 0)
return -ERANGE;
return 0;
} }
return -EAFNOSUPPORT; return -EAFNOSUPPORT;
@ -358,6 +369,43 @@ int in_addr_random_prefix(
return -EAFNOSUPPORT; return -EAFNOSUPPORT;
} }
int in_addr_prefix_range(
int family,
const union in_addr_union *in,
unsigned prefixlen,
union in_addr_union *ret_start,
union in_addr_union *ret_end) {
union in_addr_union start, end;
int r;
assert(in);
if (!IN_SET(family, AF_INET, AF_INET6))
return -EAFNOSUPPORT;
if (ret_start) {
start = *in;
r = in_addr_prefix_nth(family, &start, prefixlen, 0);
if (r < 0)
return r;
}
if (ret_end) {
end = *in;
r = in_addr_prefix_nth(family, &end, prefixlen, 1);
if (r < 0)
return r;
}
if (ret_start)
*ret_start = start;
if (ret_end)
*ret_end = end;
return 0;
}
int in_addr_to_string(int family, const union in_addr_union *u, char **ret) { int in_addr_to_string(int family, const union in_addr_union *u, char **ret) {
_cleanup_free_ char *x = NULL; _cleanup_free_ char *x = NULL;
size_t l; size_t l;

View File

@ -21,11 +21,29 @@ struct in_addr_data {
}; };
bool in4_addr_is_null(const struct in_addr *a); bool in4_addr_is_null(const struct in_addr *a);
static inline bool in4_addr_is_set(const struct in_addr *a) {
return !in4_addr_is_null(a);
}
bool in6_addr_is_null(const struct in6_addr *a);
static inline bool in6_addr_is_set(const struct in6_addr *a) {
return !in6_addr_is_null(a);
}
int in_addr_is_null(int family, const union in_addr_union *u); int in_addr_is_null(int family, const union in_addr_union *u);
static inline bool in_addr_is_set(int family, const union in_addr_union *u) {
return in_addr_is_null(family, u) == 0;
}
static inline int in_addr_data_is_null(const struct in_addr_data *a) {
assert(a);
return in_addr_is_null(a->family, &a->address);
}
static inline bool in_addr_data_is_set(const struct in_addr_data *a) {
return in_addr_data_is_null(a);
}
int in_addr_is_multicast(int family, const union in_addr_union *u); int in_addr_is_multicast(int family, const union in_addr_union *u);
bool in4_addr_is_link_local(const struct in_addr *a); bool in4_addr_is_link_local(const struct in_addr *a);
bool in6_addr_is_link_local(const struct in6_addr *a);
int in_addr_is_link_local(int family, const union in_addr_union *u); int in_addr_is_link_local(int family, const union in_addr_union *u);
bool in6_addr_is_link_local_all_nodes(const struct in6_addr *a); bool in6_addr_is_link_local_all_nodes(const struct in6_addr *a);
@ -36,11 +54,18 @@ bool in4_addr_is_local_multicast(const struct in_addr *a);
bool in4_addr_is_non_local(const struct in_addr *a); bool in4_addr_is_non_local(const struct in_addr *a);
bool in4_addr_equal(const struct in_addr *a, const struct in_addr *b); bool in4_addr_equal(const struct in_addr *a, const struct in_addr *b);
bool in6_addr_equal(const struct in6_addr *a, const struct in6_addr *b);
int in_addr_equal(int family, const union in_addr_union *a, const union in_addr_union *b); int in_addr_equal(int family, const union in_addr_union *a, const union in_addr_union *b);
int in_addr_prefix_intersect(int family, const union in_addr_union *a, unsigned aprefixlen, const union in_addr_union *b, unsigned bprefixlen); int in_addr_prefix_intersect(int family, const union in_addr_union *a, unsigned aprefixlen, const union in_addr_union *b, unsigned bprefixlen);
int in_addr_prefix_next(int family, union in_addr_union *u, unsigned prefixlen); int in_addr_prefix_next(int family, union in_addr_union *u, unsigned prefixlen);
int in_addr_prefix_nth(int family, union in_addr_union *u, unsigned prefixlen, uint64_t nth); int in_addr_prefix_nth(int family, union in_addr_union *u, unsigned prefixlen, uint64_t nth);
int in_addr_random_prefix(int family, union in_addr_union *u, unsigned prefixlen_fixed_part, unsigned prefixlen); int in_addr_random_prefix(int family, union in_addr_union *u, unsigned prefixlen_fixed_part, unsigned prefixlen);
int in_addr_prefix_range(
int family,
const union in_addr_union *in,
unsigned prefixlen,
union in_addr_union *ret_start,
union in_addr_union *ret_end);
int in_addr_to_string(int family, const union in_addr_union *u, char **ret); int in_addr_to_string(int family, const union in_addr_union *u, char **ret);
int in_addr_prefix_to_string(int family, const union in_addr_union *u, unsigned prefixlen, char **ret); int in_addr_prefix_to_string(int family, const union in_addr_union *u, unsigned prefixlen, char **ret);
int in_addr_port_ifindex_name_to_string(int family, const union in_addr_union *u, uint16_t port, int ifindex, const char *server_name, char **ret); int in_addr_port_ifindex_name_to_string(int family, const union in_addr_union *u, uint16_t port, int ifindex, const char *server_name, char **ret);

View File

@ -2471,27 +2471,22 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_EXPECT_REPLY: case ARG_EXPECT_REPLY:
r = parse_boolean(optarg); r = parse_boolean_argument("--expect-reply=", optarg, &arg_expect_reply);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --expect-reply= parameter '%s': %m", optarg); return r;
arg_expect_reply = r;
break; break;
case ARG_AUTO_START: case ARG_AUTO_START:
r = parse_boolean(optarg); r = parse_boolean_argument("--auto-start=", optarg, &arg_auto_start);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --auto-start= parameter '%s': %m", optarg); return r;
arg_auto_start = r;
break; break;
case ARG_ALLOW_INTERACTIVE_AUTHORIZATION: case ARG_ALLOW_INTERACTIVE_AUTHORIZATION:
r = parse_boolean(optarg); r = parse_boolean_argument("--allow-interactive-authorization=", optarg,
&arg_allow_interactive_authorization);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --allow-interactive-authorization= parameter '%s': %m", optarg); return r;
arg_allow_interactive_authorization = r;
break; break;
case ARG_TIMEOUT: case ARG_TIMEOUT:
@ -2502,19 +2497,15 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_AUGMENT_CREDS: case ARG_AUGMENT_CREDS:
r = parse_boolean(optarg); r = parse_boolean_argument("--augment-creds=", optarg, &arg_augment_creds);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --augment-creds= parameter '%s': %m", optarg); return r;
arg_augment_creds = r;
break; break;
case ARG_WATCH_BIND: case ARG_WATCH_BIND:
r = parse_boolean(optarg); r = parse_boolean_argument("--watch-bind=", optarg, &arg_watch_bind);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --watch-bind= parameter '%s': %m", optarg); return r;
arg_watch_bind = r;
break; break;
case 'j': case 'j':

View File

@ -19,6 +19,7 @@
#include "hashmap.h" #include "hashmap.h"
#include "main-func.h" #include "main-func.h"
#include "missing_sched.h" #include "missing_sched.h"
#include "parse-argument.h"
#include "parse-util.h" #include "parse-util.h"
#include "path-util.h" #include "path-util.h"
#include "pretty-print.h" #include "pretty-print.h"
@ -867,12 +868,11 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_RECURSIVE: case ARG_RECURSIVE:
r = parse_boolean(optarg); r = parse_boolean_argument("--recursive=", optarg, &arg_recursive);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --recursive= argument '%s': %m", optarg); return r;
arg_recursive = r; arg_recursive_unset = !r;
arg_recursive_unset = r == 0;
break; break;
case 'M': case 'M':

View File

@ -2062,9 +2062,9 @@ static int install_error(
for (size_t i = 0; i < n_changes; i++) for (size_t i = 0; i < n_changes; i++)
switch(changes[i].type) { switch(changes[i].type_or_errno) {
case 0 ... INT_MAX: case 0 ... _UNIT_FILE_CHANGE_TYPE_MAX: /* not errors */
continue; continue;
case -EEXIST: case -EEXIST:
@ -2106,7 +2106,8 @@ static int install_error(
goto found; goto found;
default: default:
r = sd_bus_error_set_errnof(error, changes[i].type, "File %s: %m", changes[i].path); assert(changes[i].type_or_errno < 0); /* other errors */
r = sd_bus_error_set_errnof(error, changes[i].type_or_errno, "File %s: %m", changes[i].path);
goto found; goto found;
} }
@ -2151,14 +2152,14 @@ static int reply_unit_file_changes_and_free(
for (size_t i = 0; i < n_changes; i++) { for (size_t i = 0; i < n_changes; i++) {
if (changes[i].type < 0) { if (changes[i].type_or_errno < 0) {
bad = true; bad = true;
continue; continue;
} }
r = sd_bus_message_append( r = sd_bus_message_append(
reply, "(sss)", reply, "(sss)",
unit_file_change_type_to_string(changes[i].type), unit_file_change_type_to_string(changes[i].type_or_errno),
changes[i].path, changes[i].path,
changes[i].source); changes[i].source);
if (r < 0) if (r < 0)
@ -2542,7 +2543,7 @@ static int method_get_unit_file_links(sd_bus_message *message, void *userdata, s
return log_error_errno(r, "Failed to get file links for %s: %m", name); return log_error_errno(r, "Failed to get file links for %s: %m", name);
for (i = 0; i < n_changes; i++) for (i = 0; i < n_changes; i++)
if (changes[i].type == UNIT_FILE_UNLINK) { if (changes[i].type_or_errno == UNIT_FILE_UNLINK) {
r = sd_bus_message_append(reply, "s", changes[i].path); r = sd_bus_message_append(reply, "s", changes[i].path);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -937,15 +937,9 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_DUMP_CORE: case ARG_DUMP_CORE:
if (!optarg) r = parse_boolean_argument("--dump-core", optarg, &arg_dump_core);
arg_dump_core = true; if (r < 0)
else { return r;
r = parse_boolean(optarg);
if (r < 0)
return log_error_errno(r, "Failed to parse dump core boolean: \"%s\": %m",
optarg);
arg_dump_core = r;
}
break; break;
case ARG_CRASH_CHVT: case ARG_CRASH_CHVT:
@ -956,27 +950,15 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_CRASH_SHELL: case ARG_CRASH_SHELL:
if (!optarg) r = parse_boolean_argument("--crash-shell", optarg, &arg_crash_shell);
arg_crash_shell = true; if (r < 0)
else { return r;
r = parse_boolean(optarg);
if (r < 0)
return log_error_errno(r, "Failed to parse crash shell boolean: \"%s\": %m",
optarg);
arg_crash_shell = r;
}
break; break;
case ARG_CRASH_REBOOT: case ARG_CRASH_REBOOT:
if (!optarg) r = parse_boolean_argument("--crash-reboot", optarg, &arg_crash_reboot);
arg_crash_reboot = true; if (r < 0)
else { return r;
r = parse_boolean(optarg);
if (r < 0)
return log_error_errno(r, "Failed to parse crash shell boolean: \"%s\": %m",
optarg);
arg_crash_reboot = r;
}
break; break;
case ARG_CONFIRM_SPAWN: case ARG_CONFIRM_SPAWN:
@ -989,11 +971,9 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_SERVICE_WATCHDOGS: case ARG_SERVICE_WATCHDOGS:
r = parse_boolean(optarg); r = parse_boolean_argument("--service-watchdogs=", optarg, &arg_service_watchdogs);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse service watchdogs boolean: \"%s\": %m", return r;
optarg);
arg_service_watchdogs = r;
break; break;
case ARG_SHOW_STATUS: case ARG_SHOW_STATUS:

View File

@ -15,6 +15,7 @@
#include "main-func.h" #include "main-func.h"
#include "nulstr-util.h" #include "nulstr-util.h"
#include "pager.h" #include "pager.h"
#include "parse-argument.h"
#include "parse-util.h" #include "parse-util.h"
#include "path-util.h" #include "path-util.h"
#include "pretty-print.h" #include "pretty-print.h"
@ -586,7 +587,7 @@ static int parse_argv(int argc, char *argv[]) {
{} {}
}; };
int c; int c, r;
assert(argc >= 1); assert(argc >= 1);
assert(argv); assert(argv);
@ -616,18 +617,10 @@ static int parse_argv(int argc, char *argv[]) {
} }
case ARG_DIFF: case ARG_DIFF:
if (!optarg) r = parse_boolean_argument("--diff", optarg, NULL);
arg_diff = 1; if (r < 0)
else { return r;
int b; arg_diff = r;
b = parse_boolean(optarg);
if (b < 0)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Failed to parse diff boolean.");
arg_diff = b;
}
break; break;
case '?': case '?':

View File

@ -14,6 +14,7 @@
#include "journal-remote.h" #include "journal-remote.h"
#include "main-func.h" #include "main-func.h"
#include "memory-util.h" #include "memory-util.h"
#include "parse-argument.h"
#include "pretty-print.h" #include "pretty-print.h"
#include "process-util.h" #include "process-util.h"
#include "rlimit-util.h" #include "rlimit-util.h"
@ -34,8 +35,8 @@ static const char* arg_listen_raw = NULL;
static const char* arg_listen_http = NULL; static const char* arg_listen_http = NULL;
static const char* arg_listen_https = NULL; static const char* arg_listen_https = NULL;
static char** arg_files = NULL; /* Do not free this. */ static char** arg_files = NULL; /* Do not free this. */
static int arg_compress = true; static bool arg_compress = true;
static int arg_seal = false; static bool arg_seal = false;
static int http_socket = -1, https_socket = -1; static int http_socket = -1, https_socket = -1;
static char** arg_gnutls_log = NULL; static char** arg_gnutls_log = NULL;
@ -965,34 +966,20 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_COMPRESS: case ARG_COMPRESS:
if (optarg) { r = parse_boolean_argument("--compress", optarg, &arg_compress);
r = parse_boolean(optarg); if (r < 0)
if (r < 0) return r;
return log_error_errno(r, "Failed to parse --compress= parameter.");
arg_compress = !!r;
} else
arg_compress = true;
break; break;
case ARG_SEAL: case ARG_SEAL:
if (optarg) { r = parse_boolean_argument("--seal", optarg, &arg_seal);
r = parse_boolean(optarg); if (r < 0)
if (r < 0) return r;
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Failed to parse --seal= parameter.");
arg_seal = !!r;
} else
arg_seal = true;
break; break;
case ARG_GNUTLS_LOG: { case ARG_GNUTLS_LOG:
#if HAVE_GNUTLS #if HAVE_GNUTLS
const char* p = optarg; for (const char* p = optarg;;) {
for (;;) {
_cleanup_free_ char *word = NULL; _cleanup_free_ char *word = NULL;
r = extract_first_word(&p, &word, ",", 0); r = extract_first_word(&p, &word, ",", 0);
@ -1011,7 +998,6 @@ static int parse_argv(int argc, char *argv[]) {
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Option --gnutls-log is not available."); "Option --gnutls-log is not available.");
#endif #endif
}
case '?': case '?':
return -EINVAL; return -EINVAL;

View File

@ -22,6 +22,7 @@
#include "log.h" #include "log.h"
#include "main-func.h" #include "main-func.h"
#include "mkdir.h" #include "mkdir.h"
#include "parse-argument.h"
#include "parse-util.h" #include "parse-util.h"
#include "path-util.h" #include "path-util.h"
#include "pretty-print.h" #include "pretty-print.h"
@ -356,7 +357,7 @@ static int open_file_for_upload(Uploader *u, const char *filename) {
u->input = fd; u->input = fd;
if (arg_follow) { if (arg_follow != 0) {
r = sd_event_add_io(u->events, &u->input_event, r = sd_event_add_io(u->events, &u->input_event,
fd, EPOLLIN, dispatch_fd_input, u); fd, EPOLLIN, dispatch_fd_input, u);
if (r < 0) { if (r < 0) {
@ -747,16 +748,10 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_FOLLOW: case ARG_FOLLOW:
if (optarg) { r = parse_boolean_argument("--follow", optarg, NULL);
r = parse_boolean(optarg); if (r < 0)
if (r < 0) return r;
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), arg_follow = r;
"Failed to parse --follow= parameter.");
arg_follow = !!r;
} else
arg_follow = true;
break; break;
case ARG_SAVE_STATE: case ARG_SAVE_STATE:
@ -857,7 +852,7 @@ static int run(int argc, char **argv) {
r = open_journal_for_upload(&u, j, r = open_journal_for_upload(&u, j,
arg_cursor ?: u.last_cursor, arg_cursor ?: u.last_cursor,
arg_cursor ? arg_after_cursor : true, arg_cursor ? arg_after_cursor : true,
!!arg_follow); arg_follow != 0);
if (r < 0) if (r < 0)
return r; return r;
} }

View File

@ -12,6 +12,7 @@
#include "alloc-util.h" #include "alloc-util.h"
#include "fd-util.h" #include "fd-util.h"
#include "main-func.h" #include "main-func.h"
#include "parse-argument.h"
#include "parse-util.h" #include "parse-util.h"
#include "pretty-print.h" #include "pretty-print.h"
#include "string-util.h" #include "string-util.h"
@ -67,7 +68,7 @@ static int parse_argv(int argc, char *argv[]) {
{} {}
}; };
int c; int c, r;
assert(argc >= 0); assert(argc >= 0);
assert(argv); assert(argv);
@ -104,16 +105,11 @@ static int parse_argv(int argc, char *argv[]) {
"Failed to parse stderr priority value."); "Failed to parse stderr priority value.");
break; break;
case ARG_LEVEL_PREFIX: { case ARG_LEVEL_PREFIX:
int k; r = parse_boolean_argument("--level-prefix=", optarg, &arg_level_prefix);
if (r < 0)
k = parse_boolean(optarg); return r;
if (k < 0)
return log_error_errno(k, "Failed to parse level prefix value.");
arg_level_prefix = k;
break; break;
}
case '?': case '?':
return -EINVAL; return -EINVAL;

View File

@ -145,8 +145,8 @@ int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr) {
return 0; return 0;
} }
int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *dst, int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *ret_dst,
triple_timestamp *timestamp) { triple_timestamp *ret_timestamp) {
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(int)) + /* ttl */ CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(int)) + /* ttl */
CMSG_SPACE(sizeof(struct timeval))) control; CMSG_SPACE(sizeof(struct timeval))) control;
@ -161,6 +161,8 @@ int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *dst,
.msg_controllen = sizeof(control), .msg_controllen = sizeof(control),
}; };
struct cmsghdr *cmsg; struct cmsghdr *cmsg;
struct in6_addr addr = {};
triple_timestamp t;
ssize_t len; ssize_t len;
iov = IOVEC_MAKE(buffer, size); iov = IOVEC_MAKE(buffer, size);
@ -175,8 +177,8 @@ int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *dst,
if (msg.msg_namelen == sizeof(struct sockaddr_in6) && if (msg.msg_namelen == sizeof(struct sockaddr_in6) &&
sa.in6.sin6_family == AF_INET6) { sa.in6.sin6_family == AF_INET6) {
*dst = sa.in6.sin6_addr; addr = sa.in6.sin6_addr;
if (in_addr_is_link_local(AF_INET6, (union in_addr_union*) dst) <= 0) if (!in6_addr_is_link_local(&addr))
return -EADDRNOTAVAIL; return -EADDRNOTAVAIL;
} else if (msg.msg_namelen > 0) } else if (msg.msg_namelen > 0)
@ -200,11 +202,13 @@ int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *dst,
if (cmsg->cmsg_level == SOL_SOCKET && if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SO_TIMESTAMP && cmsg->cmsg_type == SO_TIMESTAMP &&
cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval))) cmsg->cmsg_len == CMSG_LEN(sizeof(struct timeval)))
triple_timestamp_from_realtime(timestamp, timeval_load((struct timeval*) CMSG_DATA(cmsg))); triple_timestamp_from_realtime(&t, timeval_load((struct timeval*) CMSG_DATA(cmsg)));
} }
if (!triple_timestamp_is_set(timestamp)) if (!triple_timestamp_is_set(&t))
triple_timestamp_get(timestamp); triple_timestamp_get(&t);
*ret_dst = addr;
*ret_timestamp = t;
return 0; return 0;
} }

View File

@ -20,5 +20,5 @@
int icmp6_bind_router_solicitation(int ifindex); int icmp6_bind_router_solicitation(int ifindex);
int icmp6_bind_router_advertisement(int ifindex); int icmp6_bind_router_advertisement(int ifindex);
int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr); int icmp6_send_router_solicitation(int s, const struct ether_addr *ether_addr);
int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *dst, int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *ret_dst,
triple_timestamp *timestamp); triple_timestamp *ret_timestamp);

View File

@ -56,7 +56,7 @@ _public_ int sd_ndisc_router_get_address(sd_ndisc_router *rt, struct in6_addr *r
assert_return(rt, -EINVAL); assert_return(rt, -EINVAL);
assert_return(ret_addr, -EINVAL); assert_return(ret_addr, -EINVAL);
if (IN6_IS_ADDR_UNSPECIFIED(&rt->address)) if (in6_addr_is_null(&rt->address))
return -ENODATA; return -ENODATA;
*ret_addr = rt->address; *ret_addr = rt->address;

View File

@ -171,7 +171,7 @@ int sd_dhcp6_client_set_local_address(
assert_return(client, -EINVAL); assert_return(client, -EINVAL);
assert_return(local_address, -EINVAL); assert_return(local_address, -EINVAL);
assert_return(in_addr_is_link_local(AF_INET6, (const union in_addr_union *) local_address) > 0, -EINVAL); assert_return(in6_addr_is_link_local(local_address) > 0, -EINVAL);
assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY); assert_return(IN_SET(client->state, DHCP6_STATE_STOPPED), -EBUSY);
@ -1693,7 +1693,7 @@ int sd_dhcp6_client_start(sd_dhcp6_client *client) {
assert_return(client, -EINVAL); assert_return(client, -EINVAL);
assert_return(client->event, -EINVAL); assert_return(client->event, -EINVAL);
assert_return(client->ifindex > 0, -EINVAL); assert_return(client->ifindex > 0, -EINVAL);
assert_return(in_addr_is_link_local(AF_INET6, (const union in_addr_union *) &client->local_address) > 0, -EINVAL); assert_return(in6_addr_is_link_local(&client->local_address) > 0, -EINVAL);
if (!IN_SET(client->state, DHCP6_STATE_STOPPED)) if (!IN_SET(client->state, DHCP6_STATE_STOPPED))
return -EBUSY; return -EBUSY;

View File

@ -186,7 +186,7 @@ int sd_ipv4ll_is_running(sd_ipv4ll *ll) {
static bool ipv4ll_address_is_valid(const struct in_addr *address) { static bool ipv4ll_address_is_valid(const struct in_addr *address) {
assert(address); assert(address);
if (!in_addr_is_link_local(AF_INET, (const union in_addr_union *) address)) if (!in4_addr_is_link_local(address))
return false; return false;
return !IN_SET(be32toh(address->s_addr) & 0x0000FF00U, 0x0000U, 0xFF00U); return !IN_SET(be32toh(address->s_addr) & 0x0000FF00U, 0x0000U, 0xFF00U);

View File

@ -225,7 +225,7 @@ static int ndisc_recv(sd_event_source *s, int fd, uint32_t revents, void *userda
if (r < 0) { if (r < 0) {
switch (r) { switch (r) {
case -EADDRNOTAVAIL: case -EADDRNOTAVAIL:
(void) in_addr_to_string(AF_INET6, (union in_addr_union*) &rt->address, &addr); (void) in_addr_to_string(AF_INET6, (const union in_addr_union*) &rt->address, &addr);
log_ndisc("Received RA from non-link-local address %s. Ignoring", addr); log_ndisc("Received RA from non-link-local address %s. Ignoring", addr);
break; break;

View File

@ -167,7 +167,7 @@ static int radv_send(sd_radv *ra, const struct in6_addr *dst, uint32_t router_li
if (r < 0) if (r < 0)
return r; return r;
if (dst && !IN6_IS_ADDR_UNSPECIFIED(dst)) if (dst && in6_addr_is_set(dst))
dst_addr.sin6_addr = *dst; dst_addr.sin6_addr = *dst;
adv.nd_ra_type = ND_ROUTER_ADVERT; adv.nd_ra_type = ND_ROUTER_ADVERT;
@ -244,7 +244,7 @@ static int radv_recv(sd_event_source *s, int fd, uint32_t revents, void *userdat
if (r < 0) { if (r < 0) {
switch (r) { switch (r) {
case -EADDRNOTAVAIL: case -EADDRNOTAVAIL:
(void) in_addr_to_string(AF_INET6, (union in_addr_union*) &src, &addr); (void) in_addr_to_string(AF_INET6, (const union in_addr_union*) &src, &addr);
log_radv("Received RS from non-link-local address %s. Ignoring", addr); log_radv("Received RS from non-link-local address %s. Ignoring", addr);
break; break;
@ -272,7 +272,7 @@ static int radv_recv(sd_event_source *s, int fd, uint32_t revents, void *userdat
return 0; return 0;
} }
(void) in_addr_to_string(AF_INET6, (union in_addr_union*) &src, &addr); (void) in_addr_to_string(AF_INET6, (const union in_addr_union*) &src, &addr);
r = radv_send(ra, &src, ra->lifetime); r = radv_send(ra, &src, ra->lifetime);
if (r < 0) if (r < 0)
@ -536,35 +536,36 @@ _public_ int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p, int dynamic) {
return -EINVAL; return -EINVAL;
/* Refuse prefixes that don't have a prefix set */ /* Refuse prefixes that don't have a prefix set */
if (IN6_IS_ADDR_UNSPECIFIED(&p->opt.in6_addr)) if (in6_addr_is_null(&p->opt.in6_addr))
return -ENOEXEC; return -ENOEXEC;
(void) in_addr_prefix_to_string(AF_INET6,
(const union in_addr_union*) &p->opt.in6_addr,
p->opt.prefixlen, &addr_p);
LIST_FOREACH(prefix, cur, ra->prefixes) { LIST_FOREACH(prefix, cur, ra->prefixes) {
r = in_addr_prefix_intersect(AF_INET6, r = in_addr_prefix_intersect(AF_INET6,
(union in_addr_union*) &cur->opt.in6_addr, (const union in_addr_union*) &cur->opt.in6_addr,
cur->opt.prefixlen, cur->opt.prefixlen,
(union in_addr_union*) &p->opt.in6_addr, (const union in_addr_union*) &p->opt.in6_addr,
p->opt.prefixlen); p->opt.prefixlen);
if (r > 0) { if (r < 0)
_cleanup_free_ char *addr_cur = NULL; return r;
if (r == 0)
continue;
(void) in_addr_to_string(AF_INET6, if (dynamic && cur->opt.prefixlen == p->opt.prefixlen)
(union in_addr_union*) &p->opt.in6_addr, goto update;
&addr_p);
if (dynamic && cur->opt.prefixlen == p->opt.prefixlen) _cleanup_free_ char *addr_cur = NULL;
goto update; (void) in_addr_prefix_to_string(AF_INET6,
(const union in_addr_union*) &cur->opt.in6_addr,
cur->opt.prefixlen, &addr_cur);
log_radv("IPv6 prefix %s already configured, ignoring %s",
strna(addr_cur), strna(addr_p));
(void) in_addr_to_string(AF_INET6, return -EEXIST;
(union in_addr_union*) &cur->opt.in6_addr,
&addr_cur);
log_radv("IPv6 prefix %s/%u already configured, ignoring %s/%u",
addr_cur, cur->opt.prefixlen,
addr_p, p->opt.prefixlen);
return -EEXIST;
}
} }
p = sd_radv_prefix_ref(p); p = sd_radv_prefix_ref(p);
@ -573,10 +574,8 @@ _public_ int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p, int dynamic) {
ra->n_prefixes++; ra->n_prefixes++;
(void) in_addr_to_string(AF_INET6, (union in_addr_union*) &p->opt.in6_addr, &addr_p);
if (!dynamic) { if (!dynamic) {
log_radv("Added prefix %s/%d", addr_p, p->opt.prefixlen); log_radv("Added prefix %s", strna(addr_p));
return 0; return 0;
} }
@ -609,8 +608,8 @@ _public_ int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p, int dynamic) {
cur->valid_until = valid_until; cur->valid_until = valid_until;
cur->preferred_until = preferred_until; cur->preferred_until = preferred_until;
log_radv("Updated prefix %s/%u preferred %s valid %s", log_radv("Updated prefix %s preferred %s valid %s",
addr_p, p->opt.prefixlen, strna(addr_p),
format_timespan(time_string_preferred, FORMAT_TIMESPAN_MAX, format_timespan(time_string_preferred, FORMAT_TIMESPAN_MAX,
preferred, USEC_PER_SEC), preferred, USEC_PER_SEC),
format_timespan(time_string_valid, FORMAT_TIMESPAN_MAX, format_timespan(time_string_valid, FORMAT_TIMESPAN_MAX,
@ -631,9 +630,7 @@ _public_ sd_radv_prefix *sd_radv_remove_prefix(sd_radv *ra,
if (prefixlen != cur->opt.prefixlen) if (prefixlen != cur->opt.prefixlen)
continue; continue;
if (!in_addr_equal(AF_INET6, if (!in6_addr_equal(prefix, &cur->opt.in6_addr))
(union in_addr_union *)prefix,
(union in_addr_union *)&cur->opt.in6_addr))
continue; continue;
LIST_REMOVE(prefix, ra->prefixes, cur); LIST_REMOVE(prefix, ra->prefixes, cur);
@ -658,17 +655,16 @@ _public_ int sd_radv_add_route_prefix(sd_radv *ra, sd_radv_route_prefix *p, int
if (!p) if (!p)
return -EINVAL; return -EINVAL;
(void) in_addr_to_string(AF_INET6, (void) in_addr_prefix_to_string(AF_INET6,
(union in_addr_union*) &p->opt.in6_addr, (const union in_addr_union*) &p->opt.in6_addr,
&pretty); p->opt.prefixlen, &pretty);
LIST_FOREACH(prefix, cur, ra->route_prefixes) { LIST_FOREACH(prefix, cur, ra->route_prefixes) {
_cleanup_free_ char *addr = NULL;
r = in_addr_prefix_intersect(AF_INET6, r = in_addr_prefix_intersect(AF_INET6,
(union in_addr_union*) &cur->opt.in6_addr, (const union in_addr_union*) &cur->opt.in6_addr,
cur->opt.prefixlen, cur->opt.prefixlen,
(union in_addr_union*) &p->opt.in6_addr, (const union in_addr_union*) &p->opt.in6_addr,
p->opt.prefixlen); p->opt.prefixlen);
if (r < 0) if (r < 0)
return r; return r;
@ -678,12 +674,12 @@ _public_ int sd_radv_add_route_prefix(sd_radv *ra, sd_radv_route_prefix *p, int
if (dynamic && cur->opt.prefixlen == p->opt.prefixlen) if (dynamic && cur->opt.prefixlen == p->opt.prefixlen)
goto update; goto update;
(void) in_addr_to_string(AF_INET6, _cleanup_free_ char *addr = NULL;
(union in_addr_union*) &cur->opt.in6_addr, (void) in_addr_prefix_to_string(AF_INET6,
&addr); (const union in_addr_union*) &cur->opt.in6_addr,
log_radv("IPv6 route prefix %s/%u already configured, ignoring %s/%u", cur->opt.prefixlen, &addr);
strempty(addr), cur->opt.prefixlen, log_radv("IPv6 route prefix %s already configured, ignoring %s",
strempty(pretty), p->opt.prefixlen); strna(addr), strna(pretty));
return -EEXIST; return -EEXIST;
} }
@ -694,7 +690,7 @@ _public_ int sd_radv_add_route_prefix(sd_radv *ra, sd_radv_route_prefix *p, int
ra->n_route_prefixes++; ra->n_route_prefixes++;
if (!dynamic) { if (!dynamic) {
log_radv("Added prefix %s/%u", strempty(pretty), p->opt.prefixlen); log_radv("Added prefix %s", strna(pretty));
return 0; return 0;
} }
@ -717,8 +713,8 @@ _public_ int sd_radv_add_route_prefix(sd_radv *ra, sd_radv_route_prefix *p, int
if (valid_until == USEC_INFINITY) if (valid_until == USEC_INFINITY)
return -EOVERFLOW; return -EOVERFLOW;
log_radv("Updated route prefix %s/%u valid %s", log_radv("Updated route prefix %s valid %s",
strempty(pretty), p->opt.prefixlen, strna(pretty),
format_timespan(time_string_valid, FORMAT_TIMESPAN_MAX, valid, USEC_PER_SEC)); format_timespan(time_string_valid, FORMAT_TIMESPAN_MAX, valid, USEC_PER_SEC));
return 0; return 0;

View File

@ -23,6 +23,7 @@
#include "mount-util.h" #include "mount-util.h"
#include "mountpoint-util.h" #include "mountpoint-util.h"
#include "pager.h" #include "pager.h"
#include "parse-argument.h"
#include "parse-util.h" #include "parse-util.h"
#include "path-util.h" #include "path-util.h"
#include "pretty-print.h" #include "pretty-print.h"
@ -265,11 +266,9 @@ static int parse_argv(int argc, char *argv[]) {
} }
case ARG_FSCK: case ARG_FSCK:
r = parse_boolean(optarg); r = parse_boolean_argument("--fsck=", optarg, &arg_fsck);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --fsck= argument: %s", optarg); return r;
arg_fsck = r;
break; break;
case ARG_DESCRIPTION: case ARG_DESCRIPTION:
@ -289,9 +288,9 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_AUTOMOUNT: case ARG_AUTOMOUNT:
r = parse_boolean(optarg); r = parse_boolean_argument("--automount=", optarg, NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "--automount= expects a valid boolean parameter: %s", optarg); return r;
arg_action = r ? ACTION_AUTOMOUNT : ACTION_MOUNT; arg_action = r ? ACTION_AUTOMOUNT : ACTION_MOUNT;
break; break;

View File

@ -360,7 +360,7 @@ static int network_set_address(Context *context, const char *ifname, int family,
union in_addr_union *addr, union in_addr_union *peer) { union in_addr_union *addr, union in_addr_union *peer) {
Network *network; Network *network;
if (in_addr_is_null(family, addr) != 0) if (!in_addr_is_set(family, addr))
return 0; return 0;
network = network_get(context, ifname); network = network_get(context, ifname);
@ -375,7 +375,7 @@ static int network_set_route(Context *context, const char *ifname, int family, u
Network *network; Network *network;
int r; int r;
if (in_addr_is_null(family, gateway) != 0) if (!in_addr_is_set(family, gateway))
return 0; return 0;
network = network_get(context, ifname); network = network_get(context, ifname);
@ -1000,7 +1000,7 @@ static int address_dump(Address *address, FILE *f) {
if (r < 0) if (r < 0)
return r; return r;
if (in_addr_is_null(address->family, &address->peer) == 0) { if (in_addr_is_set(address->family, &address->peer)) {
r = in_addr_to_string(address->family, &address->peer, &peer); r = in_addr_to_string(address->family, &address->peer, &peer);
if (r < 0) if (r < 0)
return r; return r;
@ -1021,7 +1021,7 @@ static int route_dump(Route *route, FILE *f) {
_cleanup_free_ char *dest = NULL, *gateway = NULL; _cleanup_free_ char *dest = NULL, *gateway = NULL;
int r; int r;
if (in_addr_is_null(route->family, &route->dest) == 0) { if (in_addr_is_set(route->family, &route->dest)) {
r = in_addr_prefix_to_string(route->family, &route->dest, route->prefixlen, &dest); r = in_addr_prefix_to_string(route->family, &route->dest, route->prefixlen, &dest);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -90,7 +90,7 @@ static int netdev_geneve_create(NetDev *netdev) {
return log_netdev_error_errno(netdev, r, "Could not append IFLA_GENEVE_ID attribute: %m"); return log_netdev_error_errno(netdev, r, "Could not append IFLA_GENEVE_ID attribute: %m");
} }
if (in_addr_is_null(v->remote_family, &v->remote) == 0) { if (in_addr_is_set(v->remote_family, &v->remote)) {
if (v->remote_family == AF_INET) if (v->remote_family == AF_INET)
r = sd_netlink_message_append_in_addr(m, IFLA_GENEVE_REMOTE, &v->remote.in); r = sd_netlink_message_append_in_addr(m, IFLA_GENEVE_REMOTE, &v->remote.in);
else else

View File

@ -252,7 +252,7 @@ static int l2tp_acquire_local_address_one(L2tpTunnel *t, Address *a, union in_ad
if (a->family != t->family) if (a->family != t->family)
return -EINVAL; return -EINVAL;
if (in_addr_is_null(a->family, &a->in_addr_peer) <= 0) if (in_addr_is_set(a->family, &a->in_addr_peer))
return -EINVAL; return -EINVAL;
if (t->local_address_type == NETDEV_L2TP_LOCAL_ADDRESS_STATIC && if (t->local_address_type == NETDEV_L2TP_LOCAL_ADDRESS_STATIC &&
@ -275,7 +275,7 @@ static int l2tp_acquire_local_address(L2tpTunnel *t, Link *link, union in_addr_u
assert(ret); assert(ret);
assert(IN_SET(t->family, AF_INET, AF_INET6)); assert(IN_SET(t->family, AF_INET, AF_INET6));
if (!in_addr_is_null(t->family, &t->local)) { if (in_addr_is_set(t->family, &t->local)) {
/* local address is explicitly specified. */ /* local address is explicitly specified. */
*ret = t->local; *ret = t->local;
return 0; return 0;
@ -435,7 +435,7 @@ int config_parse_l2tp_tunnel_address(
addr_type = l2tp_local_address_type_from_string(rvalue); addr_type = l2tp_local_address_type_from_string(rvalue);
if (addr_type >= 0) { if (addr_type >= 0) {
if (in_addr_is_null(t->family, &t->remote) != 0) if (!in_addr_is_set(t->family, &t->remote))
/* If Remote= is not specified yet, then also clear family. */ /* If Remote= is not specified yet, then also clear family. */
t->family = AF_UNSPEC; t->family = AF_UNSPEC;
@ -682,7 +682,7 @@ static int netdev_l2tp_tunnel_verify(NetDev *netdev, const char *filename) {
"%s: L2TP tunnel with invalid address family configured. Ignoring", "%s: L2TP tunnel with invalid address family configured. Ignoring",
filename); filename);
if (in_addr_is_null(t->family, &t->remote)) if (!in_addr_is_set(t->family, &t->remote))
return log_netdev_error_errno(netdev, SYNTHETIC_ERRNO(EINVAL), return log_netdev_error_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
"%s: L2TP tunnel without a remote address configured. Ignoring", "%s: L2TP tunnel without a remote address configured. Ignoring",
filename); filename);

View File

@ -468,7 +468,7 @@ static int netdev_tunnel_verify(NetDev *netdev, const char *filename) {
"vti/ipip/sit/gre tunnel without a local/remote IPv4 address configured in %s. Ignoring", filename); "vti/ipip/sit/gre tunnel without a local/remote IPv4 address configured in %s. Ignoring", filename);
if (IN_SET(netdev->kind, NETDEV_KIND_GRETAP, NETDEV_KIND_ERSPAN) && if (IN_SET(netdev->kind, NETDEV_KIND_GRETAP, NETDEV_KIND_ERSPAN) &&
(t->family != AF_INET || in_addr_is_null(t->family, &t->remote))) (t->family != AF_INET || !in_addr_is_set(t->family, &t->remote)))
return log_netdev_error_errno(netdev, SYNTHETIC_ERRNO(EINVAL), return log_netdev_error_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
"gretap/erspan tunnel without a remote IPv4 address configured in %s. Ignoring", filename); "gretap/erspan tunnel without a remote IPv4 address configured in %s. Ignoring", filename);
@ -478,7 +478,7 @@ static int netdev_tunnel_verify(NetDev *netdev, const char *filename) {
"vti6/ip6tnl/ip6gre tunnel without a local/remote IPv6 address configured in %s. Ignoring", filename); "vti6/ip6tnl/ip6gre tunnel without a local/remote IPv6 address configured in %s. Ignoring", filename);
if (netdev->kind == NETDEV_KIND_IP6GRETAP && if (netdev->kind == NETDEV_KIND_IP6GRETAP &&
(t->family != AF_INET6 || in_addr_is_null(t->family, &t->remote))) (t->family != AF_INET6 || !in_addr_is_set(t->family, &t->remote)))
return log_netdev_error_errno(netdev, SYNTHETIC_ERRNO(EINVAL), return log_netdev_error_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
"ip6gretap tunnel without a remote IPv6 address configured in %s. Ignoring", filename); "ip6gretap tunnel without a remote IPv6 address configured in %s. Ignoring", filename);
@ -530,11 +530,9 @@ int config_parse_tunnel_address(const char *unit,
*addr = IN_ADDR_NULL; *addr = IN_ADDR_NULL;
/* As a special case, if both the local and remote addresses are /* As a special case, if both the local and remote addresses are
* unspecified, also clear the address family. * unspecified, also clear the address family. */
*/ if (!in_addr_is_set(t->family, &t->local) &&
if (t->family != AF_UNSPEC && !in_addr_is_set(t->family, &t->remote))
in_addr_is_null(t->family, &t->local) != 0 &&
in_addr_is_null(t->family, &t->remote) != 0)
t->family = AF_UNSPEC; t->family = AF_UNSPEC;
return 0; return 0;
} }

View File

@ -37,14 +37,14 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_netli
return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_ID attribute: %m"); return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_ID attribute: %m");
} }
if (in_addr_is_null(v->group_family, &v->group) == 0) { if (in_addr_is_set(v->group_family, &v->group)) {
if (v->group_family == AF_INET) if (v->group_family == AF_INET)
r = sd_netlink_message_append_in_addr(m, IFLA_VXLAN_GROUP, &v->group.in); r = sd_netlink_message_append_in_addr(m, IFLA_VXLAN_GROUP, &v->group.in);
else else
r = sd_netlink_message_append_in6_addr(m, IFLA_VXLAN_GROUP6, &v->group.in6); r = sd_netlink_message_append_in6_addr(m, IFLA_VXLAN_GROUP6, &v->group.in6);
if (r < 0) if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_GROUP attribute: %m"); return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_GROUP attribute: %m");
} else if (in_addr_is_null(v->remote_family, &v->remote) == 0) { } else if (in_addr_is_set(v->remote_family, &v->remote)) {
if (v->remote_family == AF_INET) if (v->remote_family == AF_INET)
r = sd_netlink_message_append_in_addr(m, IFLA_VXLAN_GROUP, &v->remote.in); r = sd_netlink_message_append_in_addr(m, IFLA_VXLAN_GROUP, &v->remote.in);
else else
@ -53,7 +53,7 @@ static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_netli
return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_GROUP attribute: %m"); return log_netdev_error_errno(netdev, r, "Could not append IFLA_VXLAN_GROUP attribute: %m");
} }
if (in_addr_is_null(v->local_family, &v->local) == 0) { if (in_addr_is_set(v->local_family, &v->local)) {
if (v->local_family == AF_INET) if (v->local_family == AF_INET)
r = sd_netlink_message_append_in_addr(m, IFLA_VXLAN_LOCAL, &v->local.in); r = sd_netlink_message_append_in_addr(m, IFLA_VXLAN_LOCAL, &v->local.in);
else else
@ -354,7 +354,7 @@ static int netdev_vxlan_verify(NetDev *netdev, const char *filename) {
if (!v->dest_port && v->generic_protocol_extension) if (!v->dest_port && v->generic_protocol_extension)
v->dest_port = 4790; v->dest_port = 4790;
if (in_addr_is_null(v->group_family, &v->group) == 0 && in_addr_is_null(v->remote_family, &v->remote) == 0) if (in_addr_is_set(v->group_family, &v->group) && in_addr_is_set(v->remote_family, &v->remote))
return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL), return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
"%s: VXLAN both 'Group=' and 'Remote=' cannot be specified. Ignoring.", "%s: VXLAN both 'Group=' and 'Remote=' cannot be specified. Ignoring.",
filename); filename);

View File

@ -1787,7 +1787,7 @@ static int link_status_one(
if (r < 0) if (r < 0)
return table_log_add_error(r); return table_log_add_error(r);
} else if (STRPTR_IN_SET(info->netdev_kind, "ipip", "sit", "gre", "gretap", "erspan", "vti")) { } else if (STRPTR_IN_SET(info->netdev_kind, "ipip", "sit", "gre", "gretap", "erspan", "vti")) {
if (!in_addr_is_null(AF_INET, &info->local)) { if (in_addr_is_set(AF_INET, &info->local)) {
r = table_add_many(table, r = table_add_many(table,
TABLE_EMPTY, TABLE_EMPTY,
TABLE_STRING, "Local:", TABLE_STRING, "Local:",
@ -1796,7 +1796,7 @@ static int link_status_one(
return table_log_add_error(r); return table_log_add_error(r);
} }
if (!in_addr_is_null(AF_INET, &info->remote)) { if (in_addr_is_set(AF_INET, &info->remote)) {
r = table_add_many(table, r = table_add_many(table,
TABLE_EMPTY, TABLE_EMPTY,
TABLE_STRING, "Remote:", TABLE_STRING, "Remote:",
@ -1805,7 +1805,7 @@ static int link_status_one(
return table_log_add_error(r); return table_log_add_error(r);
} }
} else if (STRPTR_IN_SET(info->netdev_kind, "ip6gre", "ip6gretap", "ip6erspan", "vti6")) { } else if (STRPTR_IN_SET(info->netdev_kind, "ip6gre", "ip6gretap", "ip6erspan", "vti6")) {
if (!in_addr_is_null(AF_INET6, &info->local)) { if (in_addr_is_set(AF_INET6, &info->local)) {
r = table_add_many(table, r = table_add_many(table,
TABLE_EMPTY, TABLE_EMPTY,
TABLE_STRING, "Local:", TABLE_STRING, "Local:",
@ -1814,7 +1814,7 @@ static int link_status_one(
return table_log_add_error(r); return table_log_add_error(r);
} }
if (!in_addr_is_null(AF_INET6, &info->remote)) { if (in_addr_is_set(AF_INET6, &info->remote)) {
r = table_add_many(table, r = table_add_many(table,
TABLE_EMPTY, TABLE_EMPTY,
TABLE_STRING, "Remote:", TABLE_STRING, "Remote:",
@ -1830,14 +1830,14 @@ static int link_status_one(
if (r < 0) if (r < 0)
return table_log_add_error(r); return table_log_add_error(r);
if (info->has_tunnel_ipv4 && !in_addr_is_null(AF_INET, &info->remote)) { if (info->has_tunnel_ipv4 && in_addr_is_set(AF_INET, &info->remote)) {
r = table_add_many(table, r = table_add_many(table,
TABLE_EMPTY, TABLE_EMPTY,
TABLE_STRING, "Remote:", TABLE_STRING, "Remote:",
TABLE_IN_ADDR, &info->remote); TABLE_IN_ADDR, &info->remote);
if (r < 0) if (r < 0)
return table_log_add_error(r); return table_log_add_error(r);
} else if (!in_addr_is_null(AF_INET6, &info->remote)) { } else if (in_addr_is_set(AF_INET6, &info->remote)) {
r = table_add_many(table, r = table_add_many(table,
TABLE_EMPTY, TABLE_EMPTY,
TABLE_STRING, "Remote:", TABLE_STRING, "Remote:",

View File

@ -167,8 +167,8 @@ static int address_pool_acquire_one(AddressPool *p, int family, unsigned prefixl
if (DEBUG_LOGGING) { if (DEBUG_LOGGING) {
_cleanup_free_ char *s = NULL; _cleanup_free_ char *s = NULL;
(void) in_addr_to_string(p->family, &u, &s); (void) in_addr_prefix_to_string(p->family, &u, prefixlen, &s);
log_debug("Found range %s/%u", strna(s), prefixlen); log_debug("Found range %s", strna(s));
} }
*found = u; *found = u;

View File

@ -130,7 +130,8 @@ Address *address_free(Address *address) {
if (n->address == address) if (n->address == address)
free(set_remove(address->link->ndisc_addresses, n)); free(set_remove(address->link->ndisc_addresses, n));
if (in_addr_equal(AF_INET6, &address->in_addr, (const union in_addr_union *) &address->link->ipv6ll_address)) if (address->family == AF_INET6 &&
in6_addr_equal(&address->in_addr.in6, &address->link->ipv6ll_address))
memzero(&address->link->ipv6ll_address, sizeof(struct in6_addr)); memzero(&address->link->ipv6ll_address, sizeof(struct in6_addr));
} }
@ -147,7 +148,9 @@ static bool address_may_have_broadcast(const Address *a) {
/* A /31 or /32 IPv4 address does not have a broadcast address. /* A /31 or /32 IPv4 address does not have a broadcast address.
* See https://tools.ietf.org/html/rfc3021 */ * See https://tools.ietf.org/html/rfc3021 */
return a->family == AF_INET && in4_addr_is_null(&a->in_addr_peer.in) && a->prefixlen <= 30; return a->family == AF_INET &&
in_addr_is_null(AF_INET, &a->in_addr_peer) &&
a->prefixlen <= 30;
} }
static uint32_t address_prefix(const Address *a) { static uint32_t address_prefix(const Address *a) {
@ -397,7 +400,7 @@ static int address_update(Address *address, const Address *src) {
if (address->family == AF_INET6 && if (address->family == AF_INET6 &&
in_addr_is_link_local(AF_INET6, &address->in_addr) > 0 && in_addr_is_link_local(AF_INET6, &address->in_addr) > 0 &&
IN6_IS_ADDR_UNSPECIFIED(&address->link->ipv6ll_address) > 0) { in6_addr_is_null(&address->link->ipv6ll_address)) {
r = link_ipv6ll_gained(address->link, &address->in_addr.in6); r = link_ipv6ll_gained(address->link, &address->in_addr.in6);
if (r < 0) if (r < 0)
@ -487,7 +490,7 @@ static void log_address_debug(const Address *address, const char *str, const Lin
bool has_peer; bool has_peer;
(void) in_addr_to_string(address->family, &address->in_addr, &addr); (void) in_addr_to_string(address->family, &address->in_addr, &addr);
has_peer = in_addr_is_null(address->family, &address->in_addr_peer) == 0; has_peer = in_addr_is_set(address->family, &address->in_addr_peer);
if (has_peer) if (has_peer)
(void) in_addr_to_string(address->family, &address->in_addr_peer, &peer); (void) in_addr_to_string(address->family, &address->in_addr_peer, &peer);
@ -788,10 +791,7 @@ static int address_acquire(Link *link, const Address *original, Address **ret) {
assert(ret); assert(ret);
/* Something useful was configured? just use it */ /* Something useful was configured? just use it */
r = in_addr_is_null(original->family, &original->in_addr); if (in_addr_is_set(original->family, &original->in_addr)) {
if (r < 0)
return r;
if (r == 0) {
*ret = NULL; *ret = NULL;
return 0; return 0;
} }
@ -891,7 +891,7 @@ int address_configure(
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Could not set scope: %m"); return log_link_error_errno(link, r, "Could not set scope: %m");
if (in_addr_is_null(address->family, &address->in_addr_peer) == 0) { if (in_addr_is_set(address->family, &address->in_addr_peer)) {
r = netlink_message_append_in_addr_union(req, IFA_ADDRESS, address->family, &address->in_addr_peer); r = netlink_message_append_in_addr_union(req, IFA_ADDRESS, address->family, &address->in_addr_peer);
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Could not append IFA_ADDRESS attribute: %m"); return log_link_error_errno(link, r, "Could not append IFA_ADDRESS attribute: %m");
@ -956,8 +956,8 @@ static int static_address_ready_callback(Address *address) {
if (!address_is_ready(a)) { if (!address_is_ready(a)) {
_cleanup_free_ char *str = NULL; _cleanup_free_ char *str = NULL;
(void) in_addr_to_string(a->family, &a->in_addr, &str); (void) in_addr_prefix_to_string(a->family, &a->in_addr, a->prefixlen, &str);
log_link_debug(link, "an address %s/%u is not ready", strnull(str), a->prefixlen); log_link_debug(link, "an address %s is not ready", strnull(str));
return 0; return 0;
} }
@ -1263,9 +1263,9 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
if (r < 0) { if (r < 0) {
_cleanup_free_ char *buf = NULL; _cleanup_free_ char *buf = NULL;
(void) in_addr_to_string(tmp->family, &tmp->in_addr, &buf); (void) in_addr_prefix_to_string(tmp->family, &tmp->in_addr, tmp->prefixlen, &buf);
log_link_warning_errno(link, r, "Failed to remember foreign address %s/%u, ignoring: %m", log_link_warning_errno(link, r, "Failed to remember foreign address %s, ignoring: %m",
strnull(buf), tmp->prefixlen); strnull(buf));
return 0; return 0;
} }
} }
@ -1457,6 +1457,7 @@ int config_parse_broadcast(
Network *network = userdata; Network *network = userdata;
_cleanup_(address_free_or_set_invalidp) Address *n = NULL; _cleanup_(address_free_or_set_invalidp) Address *n = NULL;
union in_addr_union u;
int r; int r;
assert(filename); assert(filename);
@ -1480,13 +1481,14 @@ int config_parse_broadcast(
return 0; return 0;
} }
r = in_addr_from_string(AF_INET, rvalue, (union in_addr_union*) &n->broadcast); r = in_addr_from_string(AF_INET, rvalue, &u);
if (r < 0) { if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, log_syntax(unit, LOG_WARNING, filename, line, r,
"Broadcast is invalid, ignoring assignment: %s", rvalue); "Broadcast is invalid, ignoring assignment: %s", rvalue);
return 0; return 0;
} }
n->broadcast = u.in;
n->family = AF_INET; n->family = AF_INET;
TAKE_PTR(n); TAKE_PTR(n);

View File

@ -683,25 +683,31 @@ int config_parse_dhcp_send_option(
break; break;
} }
case DHCP_OPTION_DATA_UINT16:{ case DHCP_OPTION_DATA_UINT16:{
r = safe_atou16(p, &uint16_data); uint16_t k;
r = safe_atou16(p, &k);
if (r < 0) { if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse DHCP uint16 data, ignoring assignment: %s", p); "Failed to parse DHCP uint16 data, ignoring assignment: %s", p);
return 0; return 0;
} }
uint16_data = htobe16(k);
udata = &uint16_data; udata = &uint16_data;
sz = sizeof(uint16_t); sz = sizeof(uint16_t);
break; break;
} }
case DHCP_OPTION_DATA_UINT32: { case DHCP_OPTION_DATA_UINT32: {
r = safe_atou32(p, &uint32_data); uint32_t k;
r = safe_atou32(p, &k);
if (r < 0) { if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse DHCP uint32 data, ignoring assignment: %s", p); "Failed to parse DHCP uint32 data, ignoring assignment: %s", p);
return 0; return 0;
} }
uint32_data = htobe32(k);
udata = &uint32_data; udata = &uint32_data;
sz = sizeof(uint32_t); sz = sizeof(uint32_t);

View File

@ -47,7 +47,7 @@ static Address* link_find_dhcp_server_address(Link *link) {
/* The first statically configured address if there is any */ /* The first statically configured address if there is any */
ORDERED_HASHMAP_FOREACH(address, link->network->addresses_by_section) ORDERED_HASHMAP_FOREACH(address, link->network->addresses_by_section)
if (address->family == AF_INET && if (address->family == AF_INET &&
!in_addr_is_null(address->family, &address->in_addr)) in_addr_is_set(address->family, &address->in_addr))
return address; return address;
/* If that didn't work, find a suitable address we got from the pool */ /* If that didn't work, find a suitable address we got from the pool */

View File

@ -122,7 +122,7 @@ static int route_scope_from_address(const Route *route, const struct in_addr *se
assert(self_addr); assert(self_addr);
if (in4_addr_is_localhost(&route->dst.in) || if (in4_addr_is_localhost(&route->dst.in) ||
(!in4_addr_is_null(self_addr) && in4_addr_equal(&route->dst.in, self_addr))) (in4_addr_is_set(self_addr) && in4_addr_equal(&route->dst.in, self_addr)))
return RT_SCOPE_HOST; return RT_SCOPE_HOST;
else if (in4_addr_is_null(&route->gw.in)) else if (in4_addr_is_null(&route->gw.in))
return RT_SCOPE_LINK; return RT_SCOPE_LINK;
@ -835,7 +835,7 @@ static int dhcp4_update_address(Link *link, bool announce) {
if (r < 0 && r != -ENODATA) if (r < 0 && r != -ENODATA)
return log_link_error_errno(link, r, "DHCP error: Could not get gateway: %m"); return log_link_error_errno(link, r, "DHCP error: Could not get gateway: %m");
if (r > 0 && !in4_addr_is_null(&router[0])) if (r > 0 && in4_addr_is_set(&router[0]))
log_struct(LOG_INFO, log_struct(LOG_INFO,
LOG_LINK_INTERFACE(link), LOG_LINK_INTERFACE(link),
LOG_LINK_MESSAGE(link, "DHCPv4 address "IPV4_ADDRESS_FMT_STR"/%u via "IPV4_ADDRESS_FMT_STR, LOG_LINK_MESSAGE(link, "DHCPv4 address "IPV4_ADDRESS_FMT_STR"/%u via "IPV4_ADDRESS_FMT_STR,

View File

@ -379,7 +379,7 @@ static int dhcp6_set_pd_address(
address->in_addr = *prefix; address->in_addr = *prefix;
if (!in_addr_is_null(AF_INET6, &link->network->dhcp6_pd_token)) if (in_addr_is_set(AF_INET6, &link->network->dhcp6_pd_token))
memcpy(address->in_addr.in6.s6_addr + 8, link->network->dhcp6_pd_token.in6.s6_addr + 8, 8); memcpy(address->in_addr.in6.s6_addr + 8, link->network->dhcp6_pd_token.in6.s6_addr + 8, 8);
else { else {
r = generate_ipv6_eui_64_address(link, &address->in_addr.in6); r = generate_ipv6_eui_64_address(link, &address->in_addr.in6);
@ -785,23 +785,21 @@ static int dhcp6_set_unreachable_route(Link *link, const union in_addr_union *ad
assert(link); assert(link);
assert(addr); assert(addr);
(void) in_addr_to_string(AF_INET6, addr, &buf); (void) in_addr_prefix_to_string(AF_INET6, addr, prefixlen, &buf);
if (prefixlen > 64) { if (prefixlen > 64) {
log_link_debug(link, "PD Prefix length > 64, ignoring prefix %s/%u", log_link_debug(link, "PD Prefix length > 64, ignoring prefix %s", strna(buf));
strna(buf), prefixlen);
return 0; return 0;
} }
if (prefixlen == 64) { if (prefixlen == 64) {
log_link_debug(link, "Not adding a blocking route for DHCPv6 delegated subnet %s/64 since distributed prefix is 64", log_link_debug(link, "Not adding a blocking route for DHCPv6 delegated subnet %s since distributed prefix is 64",
strna(buf)); strna(buf));
return 1; return 1;
} }
if (prefixlen < 48) if (prefixlen < 48)
log_link_warning(link, "PD Prefix length < 48, looks unusual %s/%u", log_link_warning(link, "PD Prefix length < 48, looks unusual: %s", strna(buf));
strna(buf), prefixlen);
r = route_new(&route); r = route_new(&route);
if (r < 0) if (r < 0)
@ -816,8 +814,8 @@ static int dhcp6_set_unreachable_route(Link *link, const union in_addr_union *ad
r = route_configure(route, link, dhcp6_route_handler, &ret); r = route_configure(route, link, dhcp6_route_handler, &ret);
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Failed to set unreachable route for DHCPv6 delegated subnet %s/%u: %m", return log_link_error_errno(link, r, "Failed to set unreachable route for DHCPv6 delegated subnet %s: %m",
strna(buf), prefixlen); strna(buf));
if (r > 0) if (r > 0)
link->dhcp6_route_configured = false; link->dhcp6_route_configured = false;
@ -825,8 +823,8 @@ static int dhcp6_set_unreachable_route(Link *link, const union in_addr_union *ad
r = set_ensure_put(&link->dhcp6_routes, &route_hash_ops, ret); r = set_ensure_put(&link->dhcp6_routes, &route_hash_ops, ret);
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Failed to store unreachable route for DHCPv6 delegated subnet %s/%u: %m", return log_link_error_errno(link, r, "Failed to store unreachable route for DHCPv6 delegated subnet %s: %m",
strna(buf), prefixlen); strna(buf));
(void) set_remove(link->dhcp6_routes_old, ret); (void) set_remove(link->dhcp6_routes_old, ret);
@ -885,9 +883,9 @@ static int dhcp6_pd_prefix_acquired(Link *dhcp6_link) {
uint64_t n_prefixes = UINT64_C(1) << (64 - pd_prefix_len); uint64_t n_prefixes = UINT64_C(1) << (64 - pd_prefix_len);
_cleanup_free_ char *buf = NULL; _cleanup_free_ char *buf = NULL;
(void) in_addr_to_string(AF_INET6, &prefix, &buf); (void) in_addr_prefix_to_string(AF_INET6, &prefix, pd_prefix_len, &buf);
log_link_debug(dhcp6_link, "Assigning up to %" PRIu64 " prefixes from %s/%u", log_link_debug(dhcp6_link, "Assigning up to %" PRIu64 " prefixes from %s",
n_prefixes, strna(buf), pd_prefix_len); n_prefixes, strna(buf));
} }
dhcp6_pd_prefix_distribute(dhcp6_link, dhcp6_pd_prefix_distribute(dhcp6_link,
@ -962,7 +960,7 @@ static void log_dhcp6_address(Link *link, const Address *address, char **ret) {
assert(link); assert(link);
assert(address); assert(address);
(void) in_addr_to_string(address->family, &address->in_addr, &buffer); (void) in_addr_prefix_to_string(address->family, &address->in_addr, address->prefixlen, &buffer);
if (address->cinfo.ifa_valid != CACHE_INFO_INFINITY_LIFE_TIME) if (address->cinfo.ifa_valid != CACHE_INFO_INFINITY_LIFE_TIME)
valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX, valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX,
address->cinfo.ifa_valid * USEC_PER_SEC, address->cinfo.ifa_valid * USEC_PER_SEC,
@ -994,18 +992,18 @@ static void log_dhcp6_address(Link *link, const Address *address, char **ret) {
break; break;
} }
log_link_warning(link, "DHCPv6 address %s/%u (valid %s%s, preferred %s%s) conflicts the existing address %s/%u%s.", log_link_warning(link, "DHCPv6 address %s (valid %s%s, preferred %s%s) conflicts the existing address %s %s.",
strnull(buffer), address->prefixlen, strna(buffer),
valid_str ? "for " : "forever", strempty(valid_str), valid_str ? "for " : "forever", strempty(valid_str),
preferred_str ? "for " : "forever", strempty(preferred_str), preferred_str ? "for " : "forever", strempty(preferred_str),
strnull(buffer), existing->prefixlen, strna(buffer),
by_ndisc ? "assigned by NDISC. Please try to use or update IPv6Token= setting " by_ndisc ? "assigned by NDISC. Please try to use or update IPv6Token= setting "
"to change the address generated by NDISC, or disable UseAutonomousPrefix=" : ""); "to change the address generated by NDISC, or disable UseAutonomousPrefix=" : "");
goto finalize; goto finalize;
simple_log: simple_log:
log_link_full(link, log_level, "DHCPv6 address %s/%u (valid %s%s, preferred %s%s)", log_link_full(link, log_level, "DHCPv6 address %s (valid %s%s, preferred %s%s)",
strnull(buffer), address->prefixlen, strna(buffer),
valid_str ? "for " : "forever", strempty(valid_str), valid_str ? "for " : "forever", strempty(valid_str),
preferred_str ? "for " : "forever", strempty(preferred_str)); preferred_str ? "for " : "forever", strempty(preferred_str));
@ -1040,8 +1038,7 @@ static int dhcp6_update_address(
r = address_configure(addr, link, dhcp6_address_handler, &ret); r = address_configure(addr, link, dhcp6_address_handler, &ret);
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Failed to set DHCPv6 address %s/%u: %m", return log_link_error_errno(link, r, "Failed to set DHCPv6 address %s: %m", strna(buffer));
strnull(buffer), addr->prefixlen);
if (r > 0) if (r > 0)
link->dhcp6_address_configured = false; link->dhcp6_address_configured = false;
@ -1049,8 +1046,7 @@ static int dhcp6_update_address(
r = set_ensure_put(&link->dhcp6_addresses, &address_hash_ops, ret); r = set_ensure_put(&link->dhcp6_addresses, &address_hash_ops, ret);
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Failed to store DHCPv6 address %s/%u: %m", return log_link_error_errno(link, r, "Failed to store DHCPv6 address %s: %m", strna(buffer));
strnull(buffer), addr->prefixlen);
(void) set_remove(link->dhcp6_addresses_old, ret); (void) set_remove(link->dhcp6_addresses_old, ret);
@ -1235,7 +1231,7 @@ int dhcp6_request_address(Link *link, int ir) {
assert(link); assert(link);
assert(link->dhcp6_client); assert(link->dhcp6_client);
assert(link->network); assert(link->network);
assert(in_addr_is_link_local(AF_INET6, (const union in_addr_union*) &link->ipv6ll_address) > 0); assert(in6_addr_is_link_local(&link->ipv6ll_address));
r = sd_dhcp6_client_is_running(link->dhcp6_client); r = sd_dhcp6_client_is_running(link->dhcp6_client);
if (r < 0) if (r < 0)
@ -1613,6 +1609,8 @@ int config_parse_dhcp6_pd_hint(
void *userdata) { void *userdata) {
Network *network = data; Network *network = data;
union in_addr_union u;
unsigned char prefixlen;
int r; int r;
assert(filename); assert(filename);
@ -1620,18 +1618,22 @@ int config_parse_dhcp6_pd_hint(
assert(rvalue); assert(rvalue);
assert(data); assert(data);
r = in_addr_prefix_from_string(rvalue, AF_INET6, (union in_addr_union *) &network->dhcp6_pd_address, &network->dhcp6_pd_length); r = in_addr_prefix_from_string(rvalue, AF_INET6, &u, &prefixlen);
if (r < 0) { if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse PrefixDelegationHint=%s, ignoring assignment", rvalue); log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse %s=%s, ignoring assignment.", lvalue, rvalue);
return 0; return 0;
} }
if (network->dhcp6_pd_length < 1 || network->dhcp6_pd_length > 128) { if (prefixlen < 1 || prefixlen > 128) {
log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid prefix length='%d', ignoring assignment", network->dhcp6_pd_length); log_syntax(unit, LOG_WARNING, filename, line, 0,
network->dhcp6_pd_length = 0; "Invalid prefix length in %s=%s, ignoring assignment.", lvalue, rvalue);
return 0; return 0;
} }
network->dhcp6_pd_address = u.in6;
network->dhcp6_pd_length = prefixlen;
return 0; return 0;
} }

View File

@ -142,7 +142,7 @@ static int fdb_entry_configure(Link *link, FdbEntry *fdb_entry) {
return log_link_error_errno(link, r, "Could not append NDA_VLAN attribute: %m"); return log_link_error_errno(link, r, "Could not append NDA_VLAN attribute: %m");
} }
if (!in_addr_is_null(fdb_entry->family, &fdb_entry->destination_addr)) { if (in_addr_is_set(fdb_entry->family, &fdb_entry->destination_addr)) {
r = netlink_message_append_in_addr_union(req, NDA_DST, fdb_entry->family, &fdb_entry->destination_addr); r = netlink_message_append_in_addr_union(req, NDA_DST, fdb_entry->family, &fdb_entry->destination_addr);
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Could not append NDA_DST attribute: %m"); return log_link_error_errno(link, r, "Could not append NDA_DST attribute: %m");

View File

@ -740,8 +740,8 @@ void link_check_ready(Link *link) {
if (!address_is_ready(a)) { if (!address_is_ready(a)) {
_cleanup_free_ char *str = NULL; _cleanup_free_ char *str = NULL;
(void) in_addr_to_string(a->family, &a->in_addr, &str); (void) in_addr_prefix_to_string(a->family, &a->in_addr, a->prefixlen, &str);
return (void) log_link_debug(link, "%s(): an address %s/%d is not ready.", __func__, strnull(str), a->prefixlen); return (void) log_link_debug(link, "%s(): an address %s is not ready.", __func__, strna(str));
} }
if (!link->static_routes_configured) if (!link->static_routes_configured)
@ -766,9 +766,8 @@ void link_check_ready(Link *link) {
bool has_ndisc_address = false; bool has_ndisc_address = false;
NDiscAddress *n; NDiscAddress *n;
if (link_ipv6ll_enabled(link) && if (link_ipv6ll_enabled(link) && !in6_addr_is_set(&link->ipv6ll_address))
in_addr_is_null(AF_INET6, (const union in_addr_union*) &link->ipv6ll_address)) return (void) log_link_debug(link, "%s(): IPv6LL is not configured yet.", __func__);
return (void) log_link_debug(link, "%s(): IPv6LL is not configured.", __func__);
SET_FOREACH(n, link->ndisc_addresses) SET_FOREACH(n, link->ndisc_addresses)
if (!n->marked) { if (!n->marked) {
@ -1156,7 +1155,7 @@ static int link_acquire_ipv6_conf(Link *link) {
if (link->radv) { if (link->radv) {
assert(link->radv); assert(link->radv);
assert(in_addr_is_link_local(AF_INET6, (const union in_addr_union*)&link->ipv6ll_address) > 0); assert(in6_addr_is_link_local(&link->ipv6ll_address));
log_link_debug(link, "Starting IPv6 Router Advertisements"); log_link_debug(link, "Starting IPv6 Router Advertisements");
@ -1173,7 +1172,7 @@ static int link_acquire_ipv6_conf(Link *link) {
DHCP6_CLIENT_START_MODE_INFORMATION_REQUEST, DHCP6_CLIENT_START_MODE_INFORMATION_REQUEST,
DHCP6_CLIENT_START_MODE_SOLICIT)) { DHCP6_CLIENT_START_MODE_SOLICIT)) {
assert(link->dhcp6_client); assert(link->dhcp6_client);
assert(in_addr_is_link_local(AF_INET6, (const union in_addr_union*)&link->ipv6ll_address) > 0); assert(in6_addr_is_link_local(&link->ipv6ll_address));
r = dhcp6_request_address(link, link->network->dhcp6_without_ra == DHCP6_CLIENT_START_MODE_INFORMATION_REQUEST); r = dhcp6_request_address(link, link->network->dhcp6_without_ra == DHCP6_CLIENT_START_MODE_INFORMATION_REQUEST);
if (r < 0 && r != -EBUSY) if (r < 0 && r != -EBUSY)
@ -1223,7 +1222,7 @@ static int link_acquire_conf(Link *link) {
if (r < 0) if (r < 0)
return r; return r;
if (!in_addr_is_null(AF_INET6, (const union in_addr_union*) &link->ipv6ll_address)) { if (in6_addr_is_set(&link->ipv6ll_address)) {
r = link_acquire_ipv6_conf(link); r = link_acquire_ipv6_conf(link);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -1099,6 +1099,10 @@ int manager_enumerate(Manager *m) {
if (r < 0) if (r < 0)
return log_error_errno(r, "Could not enumerate neighbors: %m"); return log_error_errno(r, "Could not enumerate neighbors: %m");
r = manager_enumerate_nexthop(m);
if (r < 0)
return log_error_errno(r, "Could not enumerate nexthop rules: %m");
r = manager_enumerate_routes(m); r = manager_enumerate_routes(m);
if (r < 0) if (r < 0)
return log_error_errno(r, "Could not enumerate routes: %m"); return log_error_errno(r, "Could not enumerate routes: %m");
@ -1107,10 +1111,6 @@ int manager_enumerate(Manager *m) {
if (r < 0) if (r < 0)
return log_error_errno(r, "Could not enumerate routing policy rules: %m"); return log_error_errno(r, "Could not enumerate routing policy rules: %m");
r = manager_enumerate_nexthop(m);
if (r < 0)
return log_error_errno(r, "Could not enumerate nexthop rules: %m");
return 0; return 0;
} }

View File

@ -95,12 +95,12 @@ static int ndisc_address_callback(Address *address) {
break; break;
} }
if (IN6_IS_ADDR_UNSPECIFIED(&router)) { if (in6_addr_is_null(&router)) {
_cleanup_free_ char *buf = NULL; _cleanup_free_ char *buf = NULL;
(void) in_addr_to_string(address->family, &address->in_addr, &buf); (void) in_addr_prefix_to_string(address->family, &address->in_addr, address->prefixlen, &buf);
log_link_debug(address->link, "%s is called for %s/%u, but it is already removed, ignoring.", log_link_debug(address->link, "%s is called for %s, but it is already removed, ignoring.",
__func__, strna(buf), address->prefixlen); __func__, strna(buf));
return 0; return 0;
} }
@ -150,7 +150,7 @@ static int ndisc_remove_old_one(Link *link, const struct in6_addr *router, bool
if (DEBUG_LOGGING) { if (DEBUG_LOGGING) {
_cleanup_free_ char *buf = NULL; _cleanup_free_ char *buf = NULL;
(void) in_addr_to_string(AF_INET6, (union in_addr_union *) router, &buf); (void) in_addr_to_string(AF_INET6, (const union in_addr_union*) router, &buf);
log_link_debug(link, "No SLAAC address obtained from %s is ready. " log_link_debug(link, "No SLAAC address obtained from %s is ready. "
"The old NDisc information will be removed later.", "The old NDisc information will be removed later.",
strna(buf)); strna(buf));
@ -162,7 +162,7 @@ static int ndisc_remove_old_one(Link *link, const struct in6_addr *router, bool
if (DEBUG_LOGGING) { if (DEBUG_LOGGING) {
_cleanup_free_ char *buf = NULL; _cleanup_free_ char *buf = NULL;
(void) in_addr_to_string(AF_INET6, (union in_addr_union *) router, &buf); (void) in_addr_to_string(AF_INET6, (const union in_addr_union*) router, &buf);
log_link_debug(link, "Removing old NDisc information obtained from %s.", strna(buf)); log_link_debug(link, "Removing old NDisc information obtained from %s.", strna(buf));
} }
@ -649,12 +649,11 @@ static int ndisc_router_generate_addresses(Link *link, struct in6_addr *address,
_cleanup_free_ struct in6_addr *new_address = NULL; _cleanup_free_ struct in6_addr *new_address = NULL;
if (j->address_generation_type == IPV6_TOKEN_ADDRESS_GENERATION_PREFIXSTABLE if (j->address_generation_type == IPV6_TOKEN_ADDRESS_GENERATION_PREFIXSTABLE
&& (IN6_IS_ADDR_UNSPECIFIED(&j->prefix) || IN6_ARE_ADDR_EQUAL(&j->prefix, address))) { && (in6_addr_is_null(&j->prefix) || IN6_ARE_ADDR_EQUAL(&j->prefix, address))) {
/* While this loop uses dad_counter and a retry limit as specified in RFC 7217, the loop /* While this loop uses dad_counter and a retry limit as specified in RFC 7217, the loop
does not actually attempt Duplicate Address Detection; the counter will be incremented * does not actually attempt Duplicate Address Detection; the counter will be incremented
only when the address generation algorithm produces an invalid address, and the loop * only when the address generation algorithm produces an invalid address, and the loop
may exit with an address which ends up being unusable due to duplication on the link. * may exit with an address which ends up being unusable due to duplication on the link. */
*/
for (; j->dad_counter < DAD_CONFLICTS_IDGEN_RETRIES_RFC7217; j->dad_counter++) { for (; j->dad_counter < DAD_CONFLICTS_IDGEN_RETRIES_RFC7217; j->dad_counter++) {
r = make_stableprivate_address(link, address, prefixlen, j->dad_counter, &new_address); r = make_stableprivate_address(link, address, prefixlen, j->dad_counter, &new_address);
if (r < 0) if (r < 0)

View File

@ -129,7 +129,7 @@ DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(
nexthop_compare_func, nexthop_compare_func,
nexthop_free); nexthop_free);
static int nexthop_get(Link *link, NextHop *in, NextHop **ret) { static int nexthop_get(Link *link, const NextHop *in, NextHop **ret) {
NextHop *existing; NextHop *existing;
assert(link); assert(link);
@ -152,7 +152,7 @@ static int nexthop_get(Link *link, NextHop *in, NextHop **ret) {
return -ENOENT; return -ENOENT;
} }
static int nexthop_add_internal(Link *link, Set **nexthops, NextHop *in, NextHop **ret) { static int nexthop_add_internal(Link *link, Set **nexthops, const NextHop *in, NextHop **ret) {
_cleanup_(nexthop_freep) NextHop *nexthop = NULL; _cleanup_(nexthop_freep) NextHop *nexthop = NULL;
int r; int r;
@ -183,11 +183,11 @@ static int nexthop_add_internal(Link *link, Set **nexthops, NextHop *in, NextHop
return 0; return 0;
} }
static int nexthop_add_foreign(Link *link, NextHop *in, NextHop **ret) { static int nexthop_add_foreign(Link *link, const NextHop *in, NextHop **ret) {
return nexthop_add_internal(link, &link->nexthops_foreign, in, ret); return nexthop_add_internal(link, &link->nexthops_foreign, in, ret);
} }
static int nexthop_add(Link *link, NextHop *in, NextHop **ret) { static int nexthop_add(Link *link, const NextHop *in, NextHop **ret) {
bool is_new = false; bool is_new = false;
NextHop *nexthop; NextHop *nexthop;
int r; int r;
@ -217,6 +217,21 @@ static int nexthop_add(Link *link, NextHop *in, NextHop **ret) {
return is_new; return is_new;
} }
static void log_nexthop_debug(const NextHop *nexthop, const char *str, const Link *link) {
assert(nexthop);
assert(str);
assert(link);
if (DEBUG_LOGGING) {
_cleanup_free_ char *gw = NULL;
(void) in_addr_to_string(nexthop->family, &nexthop->gw, &gw);
log_link_debug(link, "%s nexthop: id: %"PRIu32", gw: %s",
str, nexthop->id, strna(gw));
}
}
static int nexthop_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { static int nexthop_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r; int r;
@ -244,7 +259,7 @@ static int nexthop_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link)
return 1; return 1;
} }
static int nexthop_configure(NextHop *nexthop, Link *link) { static int nexthop_configure(const NextHop *nexthop, Link *link) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
int r; int r;
@ -254,14 +269,7 @@ static int nexthop_configure(NextHop *nexthop, Link *link) {
assert(link->ifindex > 0); assert(link->ifindex > 0);
assert(IN_SET(nexthop->family, AF_INET, AF_INET6)); assert(IN_SET(nexthop->family, AF_INET, AF_INET6));
if (DEBUG_LOGGING) { log_nexthop_debug(nexthop, "Configuring", link);
_cleanup_free_ char *gw = NULL;
if (!in_addr_is_null(nexthop->family, &nexthop->gw))
(void) in_addr_to_string(nexthop->family, &nexthop->gw, &gw);
log_link_debug(link, "Configuring nexthop: gw: %s", strna(gw));
}
r = sd_rtnl_message_new_nexthop(link->manager->rtnl, &req, r = sd_rtnl_message_new_nexthop(link->manager->rtnl, &req,
RTM_NEWNEXTHOP, nexthop->family, RTM_NEWNEXTHOP, nexthop->family,
@ -279,7 +287,7 @@ static int nexthop_configure(NextHop *nexthop, Link *link) {
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Could not append NHA_OIF attribute: %m"); return log_link_error_errno(link, r, "Could not append NHA_OIF attribute: %m");
if (in_addr_is_null(nexthop->family, &nexthop->gw) == 0) { if (in_addr_is_set(nexthop->family, &nexthop->gw)) {
r = netlink_message_append_in_addr_union(req, NHA_GATEWAY, nexthop->family, &nexthop->gw); r = netlink_message_append_in_addr_union(req, NHA_GATEWAY, nexthop->family, &nexthop->gw);
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Could not append NHA_GATEWAY attribute: %m"); return log_link_error_errno(link, r, "Could not append NHA_GATEWAY attribute: %m");
@ -292,7 +300,7 @@ static int nexthop_configure(NextHop *nexthop, Link *link) {
link_ref(link); link_ref(link);
r = nexthop_add(link, nexthop, &nexthop); r = nexthop_add(link, nexthop, NULL);
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Could not add nexthop: %m"); return log_link_error_errno(link, r, "Could not add nexthop: %m");
@ -300,6 +308,11 @@ static int nexthop_configure(NextHop *nexthop, Link *link) {
} }
int link_set_nexthop(Link *link) { int link_set_nexthop(Link *link) {
enum {
PHASE_ID, /* First phase: Nexthops with ID */
PHASE_WITHOUT_ID, /* Second phase: Nexthops without ID */
_PHASE_MAX,
} phase;
NextHop *nh; NextHop *nh;
int r; int r;
@ -313,13 +326,17 @@ int link_set_nexthop(Link *link) {
link->static_nexthops_configured = false; link->static_nexthops_configured = false;
HASHMAP_FOREACH(nh, link->network->nexthops_by_section) { for (phase = PHASE_ID; phase < _PHASE_MAX; phase++)
r = nexthop_configure(nh, link); HASHMAP_FOREACH(nh, link->network->nexthops_by_section) {
if (r < 0) if ((nh->id > 0) != (phase == PHASE_ID))
return log_link_warning_errno(link, r, "Could not set nexthop: %m"); continue;
link->nexthop_messages++; r = nexthop_configure(nh, link);
} if (r < 0)
return log_link_warning_errno(link, r, "Could not set nexthop: %m");
link->nexthop_messages++;
}
if (link->nexthop_messages == 0) { if (link->nexthop_messages == 0) {
link->static_nexthops_configured = true; link->static_nexthops_configured = true;
@ -334,7 +351,6 @@ int link_set_nexthop(Link *link) {
int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) { int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) {
_cleanup_(nexthop_freep) NextHop *tmp = NULL; _cleanup_(nexthop_freep) NextHop *tmp = NULL;
_cleanup_free_ char *gateway = NULL;
NextHop *nexthop = NULL; NextHop *nexthop = NULL;
uint32_t ifindex; uint32_t ifindex;
uint16_t type; uint16_t type;
@ -399,22 +415,25 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
} }
r = sd_netlink_message_read_u32(message, NHA_ID, &tmp->id); r = sd_netlink_message_read_u32(message, NHA_ID, &tmp->id);
if (r < 0 && r != -ENODATA) { if (r == -ENODATA) {
log_link_warning_errno(link, r, "rtnl: received nexthop message without NHA_ID attribute, ignoring: %m");
return 0;
} else if (r < 0) {
log_link_warning_errno(link, r, "rtnl: could not get NHA_ID attribute, ignoring: %m"); log_link_warning_errno(link, r, "rtnl: could not get NHA_ID attribute, ignoring: %m");
return 0; return 0;
} else if (tmp->id == 0) {
log_link_warning(link, "rtnl: received nexthop message with invalid nexthop ID, ignoring: %m");
return 0;
} }
(void) nexthop_get(link, tmp, &nexthop); (void) nexthop_get(link, tmp, &nexthop);
if (DEBUG_LOGGING)
(void) in_addr_to_string(tmp->family, &tmp->gw, &gateway);
switch (type) { switch (type) {
case RTM_NEWNEXTHOP: case RTM_NEWNEXTHOP:
if (nexthop) if (nexthop)
log_link_debug(link, "Received remembered nexthop: %s, id: %d", strna(gateway), tmp->id); log_nexthop_debug(tmp, "Received remembered", link);
else { else {
log_link_debug(link, "Remembering foreign nexthop: %s, id: %d", strna(gateway), tmp->id); log_nexthop_debug(tmp, "Remembering foreign", link);
r = nexthop_add_foreign(link, tmp, &nexthop); r = nexthop_add_foreign(link, tmp, &nexthop);
if (r < 0) { if (r < 0) {
log_link_warning_errno(link, r, "Could not remember foreign nexthop, ignoring: %m"); log_link_warning_errno(link, r, "Could not remember foreign nexthop, ignoring: %m");
@ -423,12 +442,8 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
} }
break; break;
case RTM_DELNEXTHOP: case RTM_DELNEXTHOP:
if (nexthop) { log_nexthop_debug(tmp, nexthop ? "Forgetting" : "Kernel removed unknown", link);
log_link_debug(link, "Forgetting nexthop: %s, id: %d", strna(gateway), tmp->id); nexthop_free(nexthop);
nexthop_free(nexthop);
} else
log_link_debug(link, "Kernel removed a nexthop we don't remember: %s, id: %d, ignoring.",
strna(gateway), tmp->id);
break; break;
default: default:
@ -582,7 +597,7 @@ int config_parse_nexthop_family(
return log_oom(); return log_oom();
if (isempty(rvalue) && if (isempty(rvalue) &&
in_addr_is_null(n->family, &n->gw) != 0) { !in_addr_is_set(n->family, &n->gw)) {
/* Accept an empty string only when Gateway= is null or not specified. */ /* Accept an empty string only when Gateway= is null or not specified. */
n->family = AF_UNSPEC; n->family = AF_UNSPEC;
TAKE_PTR(n); TAKE_PTR(n);
@ -596,7 +611,7 @@ int config_parse_nexthop_family(
return 0; return 0;
} }
if (in_addr_is_null(n->family, &n->gw) == 0 && if (in_addr_is_set(n->family, &n->gw) &&
((a == ADDRESS_FAMILY_IPV4 && n->family == AF_INET6) || ((a == ADDRESS_FAMILY_IPV4 && n->family == AF_INET6) ||
(a == ADDRESS_FAMILY_IPV6 && n->family == AF_INET))) { (a == ADDRESS_FAMILY_IPV6 && n->family == AF_INET))) {
log_syntax(unit, LOG_WARNING, filename, line, 0, log_syntax(unit, LOG_WARNING, filename, line, 0,

View File

@ -525,8 +525,8 @@ static int radv_set_dns(Link *link, Link *uplink) {
p = dns; p = dns;
for (size_t i = 0; i < link->network->n_router_dns; i++) for (size_t i = 0; i < link->network->n_router_dns; i++)
if (IN6_IS_ADDR_UNSPECIFIED(&link->network->router_dns[i])) { if (in6_addr_is_null(&link->network->router_dns[i])) {
if (!IN6_IS_ADDR_UNSPECIFIED(&link->ipv6ll_address)) if (in6_addr_is_set(&link->ipv6ll_address))
*(p++) = link->ipv6ll_address; *(p++) = link->ipv6ll_address;
} else } else
*(p++) = link->network->router_dns[i]; *(p++) = link->network->router_dns[i];

View File

@ -614,26 +614,24 @@ static void log_route_debug(const Route *route, const char *str, const Link *lin
/* link may be NULL. */ /* link may be NULL. */
if (DEBUG_LOGGING) { if (DEBUG_LOGGING) {
_cleanup_free_ char *dst = NULL, *dst_prefixlen = NULL, *src = NULL, *gw = NULL, _cleanup_free_ char *dst = NULL, *src = NULL, *gw = NULL, *prefsrc = NULL,
*prefsrc = NULL, *table = NULL, *scope = NULL, *proto = NULL; *table = NULL, *scope = NULL, *proto = NULL;
if (!in_addr_is_null(route->family, &route->dst)) { if (in_addr_is_set(route->family, &route->dst))
(void) in_addr_to_string(route->family, &route->dst, &dst); (void) in_addr_prefix_to_string(route->family, &route->dst, route->dst_prefixlen, &dst);
(void) asprintf(&dst_prefixlen, "/%u", route->dst_prefixlen); if (in_addr_is_set(route->family, &route->src))
}
if (!in_addr_is_null(route->family, &route->src))
(void) in_addr_to_string(route->family, &route->src, &src); (void) in_addr_to_string(route->family, &route->src, &src);
if (in_addr_is_null(route->gw_family, &route->gw) == 0) if (in_addr_is_set(route->gw_family, &route->gw))
(void) in_addr_to_string(route->gw_family, &route->gw, &gw); (void) in_addr_to_string(route->gw_family, &route->gw, &gw);
if (!in_addr_is_null(route->family, &route->prefsrc)) if (in_addr_is_set(route->family, &route->prefsrc))
(void) in_addr_to_string(route->family, &route->prefsrc, &prefsrc); (void) in_addr_to_string(route->family, &route->prefsrc, &prefsrc);
(void) route_scope_to_string_alloc(route->scope, &scope); (void) route_scope_to_string_alloc(route->scope, &scope);
(void) manager_get_route_table_to_string(m, route->table, &table); (void) manager_get_route_table_to_string(m, route->table, &table);
(void) route_protocol_full_to_string_alloc(route->protocol, &proto); (void) route_protocol_full_to_string_alloc(route->protocol, &proto);
log_link_debug(link, log_link_debug(link,
"%s route: dst: %s%s, src: %s, gw: %s, prefsrc: %s, scope: %s, table: %s, proto: %s, type: %s", "%s route: dst: %s, src: %s, gw: %s, prefsrc: %s, scope: %s, table: %s, proto: %s, type: %s",
str, strna(dst), strempty(dst_prefixlen), strna(src), strna(gw), strna(prefsrc), str, strna(dst), strna(src), strna(gw), strna(prefsrc),
strna(scope), strna(table), strna(proto), strna(scope), strna(table), strna(proto),
strna(route_type_to_string(route->type))); strna(route_type_to_string(route->type)));
} }
@ -648,7 +646,7 @@ static int route_set_netlink_message(const Route *route, sd_netlink_message *req
/* link may be NULL */ /* link may be NULL */
if (in_addr_is_null(route->gw_family, &route->gw) == 0) { if (in_addr_is_set(route->gw_family, &route->gw)) {
if (route->gw_family == route->family) { if (route->gw_family == route->family) {
r = netlink_message_append_in_addr_union(req, RTA_GATEWAY, route->gw_family, &route->gw); r = netlink_message_append_in_addr_union(req, RTA_GATEWAY, route->gw_family, &route->gw);
if (r < 0) if (r < 0)
@ -685,7 +683,7 @@ static int route_set_netlink_message(const Route *route, sd_netlink_message *req
return log_link_error_errno(link, r, "Could not set source prefix length: %m"); return log_link_error_errno(link, r, "Could not set source prefix length: %m");
} }
if (in_addr_is_null(route->family, &route->prefsrc) == 0) { if (in_addr_is_set(route->family, &route->prefsrc)) {
r = netlink_message_append_in_addr_union(req, RTA_PREFSRC, route->family, &route->prefsrc); r = netlink_message_append_in_addr_union(req, RTA_PREFSRC, route->family, &route->prefsrc);
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Could not append RTA_PREFSRC attribute: %m"); return log_link_error_errno(link, r, "Could not append RTA_PREFSRC attribute: %m");
@ -1260,7 +1258,7 @@ int link_set_routes(Link *link) {
if (rt->gateway_from_dhcp_or_ra) if (rt->gateway_from_dhcp_or_ra)
continue; continue;
if ((in_addr_is_null(rt->gw_family, &rt->gw) != 0 && ordered_set_isempty(rt->multipath_routes)) != (phase == PHASE_NON_GATEWAY)) if ((!in_addr_is_set(rt->gw_family, &rt->gw) && ordered_set_isempty(rt->multipath_routes)) != (phase == PHASE_NON_GATEWAY))
continue; continue;
r = route_configure(rt, link, route_handler, NULL); r = route_configure(rt, link, route_handler, NULL);
@ -2565,7 +2563,7 @@ static int route_section_verify(Route *route, Network *network) {
route->priority = IP6_RT_PRIO_USER; route->priority = IP6_RT_PRIO_USER;
if (ordered_hashmap_isempty(network->addresses_by_section) && if (ordered_hashmap_isempty(network->addresses_by_section) &&
in_addr_is_null(route->gw_family, &route->gw) == 0 && in_addr_is_set(route->gw_family, &route->gw) &&
route->gateway_onlink < 0) { route->gateway_onlink < 0) {
log_warning("%s: Gateway= without static address configured. " log_warning("%s: Gateway= without static address configured. "
"Enabling GatewayOnLink= option.", "Enabling GatewayOnLink= option.",

View File

@ -401,13 +401,13 @@ static void log_routing_policy_rule_debug(const RoutingPolicyRule *rule, int fam
if (DEBUG_LOGGING) { if (DEBUG_LOGGING) {
_cleanup_free_ char *from = NULL, *to = NULL, *table = NULL; _cleanup_free_ char *from = NULL, *to = NULL, *table = NULL;
(void) in_addr_to_string(family, &rule->from, &from); (void) in_addr_prefix_to_string(family, &rule->from, rule->from_prefixlen, &from);
(void) in_addr_to_string(family, &rule->to, &to); (void) in_addr_prefix_to_string(family, &rule->to, rule->to_prefixlen, &to);
(void) manager_get_route_table_to_string(m, rule->table, &table); (void) manager_get_route_table_to_string(m, rule->table, &table);
log_link_debug(link, log_link_debug(link,
"%s routing policy rule: priority: %"PRIu32", %s/%u -> %s/%u, iif: %s, oif: %s, table: %s", "%s routing policy rule: priority: %"PRIu32", %s -> %s, iif: %s, oif: %s, table: %s",
str, rule->priority, strna(from), rule->from_prefixlen, strna(to), rule->to_prefixlen, str, rule->priority, strna(from), strna(to),
strna(rule->iif), strna(rule->oif), strna(table)); strna(rule->iif), strna(rule->oif), strna(table));
} }
} }
@ -420,7 +420,7 @@ static int routing_policy_rule_set_netlink_message(const RoutingPolicyRule *rule
/* link may be NULL. */ /* link may be NULL. */
if (in_addr_is_null(rule->family, &rule->from) == 0) { if (in_addr_is_set(rule->family, &rule->from)) {
r = netlink_message_append_in_addr_union(m, FRA_SRC, rule->family, &rule->from); r = netlink_message_append_in_addr_union(m, FRA_SRC, rule->family, &rule->from);
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Could not append FRA_SRC attribute: %m"); return log_link_error_errno(link, r, "Could not append FRA_SRC attribute: %m");
@ -430,7 +430,7 @@ static int routing_policy_rule_set_netlink_message(const RoutingPolicyRule *rule
return log_link_error_errno(link, r, "Could not set source prefix length: %m"); return log_link_error_errno(link, r, "Could not set source prefix length: %m");
} }
if (in_addr_is_null(rule->family, &rule->to) == 0) { if (in_addr_is_set(rule->family, &rule->to)) {
r = netlink_message_append_in_addr_union(m, FRA_DST, rule->family, &rule->to); r = netlink_message_append_in_addr_union(m, FRA_DST, rule->family, &rule->to);
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Could not append FRA_DST attribute: %m"); return log_link_error_errno(link, r, "Could not append FRA_DST attribute: %m");

View File

@ -34,15 +34,15 @@ static void test_deserialize_in_addr(void) {
assert_se((size = deserialize_in_addrs(&addresses, addresses_string)) >= 0); assert_se((size = deserialize_in_addrs(&addresses, addresses_string)) >= 0);
assert_se(size == 3); assert_se(size == 3);
assert_se(in_addr_equal(AF_INET, &a, (union in_addr_union *) &addresses[0])); assert_se(in4_addr_equal(&a.in, &addresses[0]));
assert_se(in_addr_equal(AF_INET, &b, (union in_addr_union *) &addresses[1])); assert_se(in4_addr_equal(&b.in, &addresses[1]));
assert_se(in_addr_equal(AF_INET, &c, (union in_addr_union *) &addresses[2])); assert_se(in4_addr_equal(&c.in, &addresses[2]));
assert_se((size = deserialize_in6_addrs(&addresses6, addresses_string)) >= 0); assert_se((size = deserialize_in6_addrs(&addresses6, addresses_string)) >= 0);
assert_se(size == 3); assert_se(size == 3);
assert_se(in_addr_equal(AF_INET6, &d, (union in_addr_union *) &addresses6[0])); assert_se(in6_addr_equal(&d.in6, &addresses6[0]));
assert_se(in_addr_equal(AF_INET6, &e, (union in_addr_union *) &addresses6[1])); assert_se(in6_addr_equal(&e.in6, &addresses6[1]));
assert_se(in_addr_equal(AF_INET6, &f, (union in_addr_union *) &addresses6[2])); assert_se(in6_addr_equal(&f.in6, &addresses6[2]));
} }
static void test_deserialize_dhcp_routes(void) { static void test_deserialize_dhcp_routes(void) {

View File

@ -92,7 +92,7 @@ int expose_port_flush(FirewallContext **fw_ctx, ExposePort* l, int af, union in_
if (!l) if (!l)
return 0; return 0;
if (in_addr_is_null(af, exposed)) if (!in_addr_is_set(af, exposed))
return 0; return 0;
log_debug("Lost IP address."); log_debug("Lost IP address.");
@ -159,7 +159,7 @@ int expose_port_execute(sd_netlink *rtnl, FirewallContext **fw_ctx, ExposePort *
p->host_port, p->host_port,
&new_exposed, &new_exposed,
p->container_port, p->container_port,
in_addr_is_null(af, exposed) ? NULL : exposed); in_addr_is_set(af, exposed) ? exposed : NULL);
if (r < 0) if (r < 0)
log_warning_errno(r, "Failed to modify %s firewall: %m", af_to_name(af)); log_warning_errno(r, "Failed to modify %s firewall: %m", af_to_name(af));
} }

View File

@ -134,7 +134,7 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
r_tuple->next = r_tuple_prev; r_tuple->next = r_tuple_prev;
r_tuple->name = r_name; r_tuple->name = r_name;
r_tuple->family = a->family; r_tuple->family = a->family;
r_tuple->scopeid = a->family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL(&a->address.in6) ? a->ifindex : 0; r_tuple->scopeid = a->family == AF_INET6 && in6_addr_is_link_local(&a->address.in6) ? a->ifindex : 0;
memcpy(r_tuple->addr, &a->address, 16); memcpy(r_tuple->addr, &a->address, 16);
idx += ALIGN(sizeof(struct gaih_addrtuple)); idx += ALIGN(sizeof(struct gaih_addrtuple));

View File

@ -77,7 +77,7 @@ static uint32_t ifindex_to_scopeid(int family, const void *a, int ifindex) {
assert(sizeof(in6) == FAMILY_ADDRESS_SIZE(AF_INET6)); assert(sizeof(in6) == FAMILY_ADDRESS_SIZE(AF_INET6));
memcpy(&in6, a, sizeof(struct in6_addr)); memcpy(&in6, a, sizeof(struct in6_addr));
return IN6_IS_ADDR_LINKLOCAL(&in6) ? ifindex : 0; return in6_addr_is_link_local(&in6) ? ifindex : 0;
} }
static int json_dispatch_ifindex(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) { static int json_dispatch_ifindex(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {

View File

@ -44,8 +44,8 @@
#include "mkdir.h" #include "mkdir.h"
#include "mkfs-util.h" #include "mkfs-util.h"
#include "mount-util.h" #include "mount-util.h"
#include "parse-util.h"
#include "parse-argument.h" #include "parse-argument.h"
#include "parse-util.h"
#include "path-util.h" #include "path-util.h"
#include "pretty-print.h" #include "pretty-print.h"
#include "proc-cmdline.h" #include "proc-cmdline.h"
@ -3575,11 +3575,9 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_DRY_RUN: case ARG_DRY_RUN:
r = parse_boolean(optarg); r = parse_boolean_argument("--dry-run=", optarg, &arg_dry_run);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --dry-run= parameter: %s", optarg); return r;
dry_run = r;
break; break;
case ARG_EMPTY: case ARG_EMPTY:
@ -3604,18 +3602,15 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_DISCARD: case ARG_DISCARD:
r = parse_boolean(optarg); r = parse_boolean_argument("--discard=", optarg, &arg_discard);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --discard= parameter: %s", optarg); return r;
arg_discard = r;
break; break;
case ARG_FACTORY_RESET: case ARG_FACTORY_RESET:
r = parse_boolean(optarg); r = parse_boolean_argument("--factory-reset=", optarg, NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --factory-reset= parameter: %s", optarg); return r;
arg_factory_reset = r; arg_factory_reset = r;
break; break;
@ -3646,10 +3641,9 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_PRETTY: case ARG_PRETTY:
r = parse_boolean(optarg); r = parse_boolean_argument("--pretty=", optarg, NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --pretty= parameter: %s", optarg); return r;
arg_pretty = r; arg_pretty = r;
break; break;

View File

@ -10,6 +10,7 @@
#include "dirent-util.h" #include "dirent-util.h"
#include "discover-image.h" #include "discover-image.h"
#include "dissect-image.h" #include "dissect-image.h"
#include "errno-list.h"
#include "fd-util.h" #include "fd-util.h"
#include "fileio.h" #include "fileio.h"
#include "fs-util.h" #include "fs-util.h"
@ -591,7 +592,7 @@ static int unit_file_is_active(
static int portable_changes_add( static int portable_changes_add(
PortableChange **changes, PortableChange **changes,
size_t *n_changes, size_t *n_changes,
PortableChangeType type, int type_or_errno, /* PORTABLE_COPY, PORTABLE_SYMLINK, … if positive, or errno if negative */
const char *path, const char *path,
const char *source) { const char *source) {
@ -601,6 +602,11 @@ static int portable_changes_add(
assert(path); assert(path);
assert(!changes == !n_changes); assert(!changes == !n_changes);
if (type_or_errno >= 0)
assert(type_or_errno < _PORTABLE_CHANGE_TYPE_MAX);
else
assert(type_or_errno >= -ERRNO_MAX);
if (!changes) if (!changes)
return 0; return 0;
@ -624,7 +630,7 @@ static int portable_changes_add(
} }
c[(*n_changes)++] = (PortableChange) { c[(*n_changes)++] = (PortableChange) {
.type = type, .type_or_errno = type_or_errno,
.path = TAKE_PTR(p), .path = TAKE_PTR(p),
.source = TAKE_PTR(s), .source = TAKE_PTR(s),
}; };
@ -635,7 +641,7 @@ static int portable_changes_add(
static int portable_changes_add_with_prefix( static int portable_changes_add_with_prefix(
PortableChange **changes, PortableChange **changes,
size_t *n_changes, size_t *n_changes,
PortableChangeType type, int type_or_errno,
const char *prefix, const char *prefix,
const char *path, const char *path,
const char *source) { const char *source) {
@ -653,7 +659,7 @@ static int portable_changes_add_with_prefix(
source = prefix_roota(prefix, source); source = prefix_roota(prefix, source);
} }
return portable_changes_add(changes, n_changes, type, path, source); return portable_changes_add(changes, n_changes, type_or_errno, path, source);
} }
void portable_changes_free(PortableChange *changes, size_t n_changes) { void portable_changes_free(PortableChange *changes, size_t n_changes) {
@ -1417,7 +1423,7 @@ static const char* const portable_change_type_table[_PORTABLE_CHANGE_TYPE_MAX] =
[PORTABLE_WRITE] = "write", [PORTABLE_WRITE] = "write",
}; };
DEFINE_STRING_TABLE_LOOKUP(portable_change_type, PortableChangeType); DEFINE_STRING_TABLE_LOOKUP(portable_change_type, int);
static const char* const portable_state_table[_PORTABLE_STATE_MAX] = { static const char* const portable_state_table[_PORTABLE_STATE_MAX] = {
[PORTABLE_DETACHED] = "detached", [PORTABLE_DETACHED] = "detached",

View File

@ -24,7 +24,9 @@ typedef enum PortableFlags {
PORTABLE_REATTACH = 1 << 3, PORTABLE_REATTACH = 1 << 3,
} PortableFlags; } PortableFlags;
typedef enum PortableChangeType { /* This enum is anonymous, since we usually store it in an 'int', as we overload it with negative errno
* values. */
enum {
PORTABLE_COPY, PORTABLE_COPY,
PORTABLE_SYMLINK, PORTABLE_SYMLINK,
PORTABLE_UNLINK, PORTABLE_UNLINK,
@ -32,7 +34,7 @@ typedef enum PortableChangeType {
PORTABLE_MKDIR, PORTABLE_MKDIR,
_PORTABLE_CHANGE_TYPE_MAX, _PORTABLE_CHANGE_TYPE_MAX,
_PORTABLE_CHANGE_TYPE_INVALID = -EINVAL, _PORTABLE_CHANGE_TYPE_INVALID = -EINVAL,
} PortableChangeType; };
typedef enum PortableState { typedef enum PortableState {
PORTABLE_DETACHED, PORTABLE_DETACHED,
@ -47,7 +49,7 @@ typedef enum PortableState {
} PortableState; } PortableState;
typedef struct PortableChange { typedef struct PortableChange {
int type; /* PortableFileChangeType or negative error number */ int type_or_errno; /* PORTABLE_COPY, PORTABLE_SYMLINK, … if positive, errno if negative */
char *path; char *path;
char *source; char *source;
} PortableChange; } PortableChange;
@ -68,8 +70,8 @@ int portable_get_profiles(char ***ret);
void portable_changes_free(PortableChange *changes, size_t n_changes); void portable_changes_free(PortableChange *changes, size_t n_changes);
const char *portable_change_type_to_string(PortableChangeType t) _const_; const char *portable_change_type_to_string(int t) _const_;
PortableChangeType portable_change_type_from_string(const char *t) _pure_; int portable_change_type_from_string(const char *t) _pure_;
const char *portable_state_to_string(PortableState t) _const_; const char *portable_state_to_string(PortableState t) _const_;
PortableState portable_state_from_string(const char *t) _pure_; PortableState portable_state_from_string(const char *t) _pure_;

View File

@ -457,8 +457,11 @@ static int reply_portable_compose_message(sd_bus_message *reply, const PortableC
return r; return r;
for (i = 0; i < n_changes; i++) { for (i = 0; i < n_changes; i++) {
if (changes[i].type_or_errno < 0)
continue;
r = sd_bus_message_append(reply, "(sss)", r = sd_bus_message_append(reply, "(sss)",
portable_change_type_to_string(changes[i].type), portable_change_type_to_string(changes[i].type_or_errno),
changes[i].path, changes[i].path,
changes[i].source); changes[i].source);
if (r < 0) if (r < 0)

View File

@ -483,7 +483,7 @@ static int normalize_portable_changes(
} }
changes[n_changes++] = (PortableChange) { changes[n_changes++] = (PortableChange) {
.type = changes_detached[i].type, .type_or_errno = changes_detached[i].type_or_errno,
.path = TAKE_PTR(path), .path = TAKE_PTR(path),
.source = TAKE_PTR(source), .source = TAKE_PTR(source),
}; };

View File

@ -23,6 +23,7 @@
#include "missing_network.h" #include "missing_network.h"
#include "netlink-util.h" #include "netlink-util.h"
#include "pager.h" #include "pager.h"
#include "parse-argument.h"
#include "parse-util.h" #include "parse-util.h"
#include "pretty-print.h" #include "pretty-print.h"
#include "resolvconf-compat.h" #include "resolvconf-compat.h"
@ -2811,11 +2812,9 @@ static int compat_parse_argv(int argc, char *argv[]) {
break; break;
case ARG_LEGEND: case ARG_LEGEND:
r = parse_boolean(optarg); r = parse_boolean_argument("--legend=", optarg, &arg_legend);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --legend= argument"); return r;
arg_legend = r;
break; break;
case 'p': case 'p':
@ -2877,30 +2876,30 @@ static int compat_parse_argv(int argc, char *argv[]) {
break; break;
case ARG_CNAME: case ARG_CNAME:
r = parse_boolean(optarg); r = parse_boolean_argument("--cname=", optarg, NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --cname= argument."); return r;
SET_FLAG(arg_flags, SD_RESOLVED_NO_CNAME, r == 0); SET_FLAG(arg_flags, SD_RESOLVED_NO_CNAME, r == 0);
break; break;
case ARG_SERVICE_ADDRESS: case ARG_SERVICE_ADDRESS:
r = parse_boolean(optarg); r = parse_boolean_argument("--service-address=", optarg, NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --service-address= argument."); return r;
SET_FLAG(arg_flags, SD_RESOLVED_NO_ADDRESS, r == 0); SET_FLAG(arg_flags, SD_RESOLVED_NO_ADDRESS, r == 0);
break; break;
case ARG_SERVICE_TXT: case ARG_SERVICE_TXT:
r = parse_boolean(optarg); r = parse_boolean_argument("--service-txt=", optarg, NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --service-txt= argument."); return r;
SET_FLAG(arg_flags, SD_RESOLVED_NO_TXT, r == 0); SET_FLAG(arg_flags, SD_RESOLVED_NO_TXT, r == 0);
break; break;
case ARG_SEARCH: case ARG_SEARCH:
r = parse_boolean(optarg); r = parse_boolean_argument("--search=", optarg, NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --search argument."); return r;
SET_FLAG(arg_flags, SD_RESOLVED_NO_SEARCH, r == 0); SET_FLAG(arg_flags, SD_RESOLVED_NO_SEARCH, r == 0);
break; break;
@ -3107,11 +3106,9 @@ static int native_parse_argv(int argc, char *argv[]) {
break; break;
case ARG_LEGEND: case ARG_LEGEND:
r = parse_boolean(optarg); r = parse_boolean_argument("--legend=", optarg, &arg_legend);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --legend= argument"); return r;
arg_legend = r;
break; break;
case 'p': case 'p':
@ -3157,72 +3154,72 @@ static int native_parse_argv(int argc, char *argv[]) {
break; break;
case ARG_CNAME: case ARG_CNAME:
r = parse_boolean(optarg); r = parse_boolean_argument("--cname=", optarg, NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --cname= argument."); return r;
SET_FLAG(arg_flags, SD_RESOLVED_NO_CNAME, r == 0); SET_FLAG(arg_flags, SD_RESOLVED_NO_CNAME, r == 0);
break; break;
case ARG_VALIDATE: case ARG_VALIDATE:
r = parse_boolean(optarg); r = parse_boolean_argument("--validate=", optarg, NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --validate= argument."); return r;
SET_FLAG(arg_flags, SD_RESOLVED_NO_VALIDATE, r == 0); SET_FLAG(arg_flags, SD_RESOLVED_NO_VALIDATE, r == 0);
break; break;
case ARG_SYNTHESIZE: case ARG_SYNTHESIZE:
r = parse_boolean(optarg); r = parse_boolean_argument("--synthesize=", optarg, NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --synthesize= argument."); return r;
SET_FLAG(arg_flags, SD_RESOLVED_NO_SYNTHESIZE, r == 0); SET_FLAG(arg_flags, SD_RESOLVED_NO_SYNTHESIZE, r == 0);
break; break;
case ARG_CACHE: case ARG_CACHE:
r = parse_boolean(optarg); r = parse_boolean_argument("--cache=", optarg, NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --cache= argument."); return r;
SET_FLAG(arg_flags, SD_RESOLVED_NO_CACHE, r == 0); SET_FLAG(arg_flags, SD_RESOLVED_NO_CACHE, r == 0);
break; break;
case ARG_ZONE: case ARG_ZONE:
r = parse_boolean(optarg); r = parse_boolean_argument("--zone=", optarg, NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --zone= argument."); return r;
SET_FLAG(arg_flags, SD_RESOLVED_NO_ZONE, r == 0); SET_FLAG(arg_flags, SD_RESOLVED_NO_ZONE, r == 0);
break; break;
case ARG_TRUST_ANCHOR: case ARG_TRUST_ANCHOR:
r = parse_boolean(optarg); r = parse_boolean_argument("--trust-anchor=", optarg, NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --trust-anchor= argument."); return r;
SET_FLAG(arg_flags, SD_RESOLVED_NO_TRUST_ANCHOR, r == 0); SET_FLAG(arg_flags, SD_RESOLVED_NO_TRUST_ANCHOR, r == 0);
break; break;
case ARG_NETWORK: case ARG_NETWORK:
r = parse_boolean(optarg); r = parse_boolean_argument("--network=", optarg, NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --network= argument."); return r;
SET_FLAG(arg_flags, SD_RESOLVED_NO_NETWORK, r == 0); SET_FLAG(arg_flags, SD_RESOLVED_NO_NETWORK, r == 0);
break; break;
case ARG_SERVICE_ADDRESS: case ARG_SERVICE_ADDRESS:
r = parse_boolean(optarg); r = parse_boolean_argument("--service-address=", optarg, NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --service-address= argument."); return r;
SET_FLAG(arg_flags, SD_RESOLVED_NO_ADDRESS, r == 0); SET_FLAG(arg_flags, SD_RESOLVED_NO_ADDRESS, r == 0);
break; break;
case ARG_SERVICE_TXT: case ARG_SERVICE_TXT:
r = parse_boolean(optarg); r = parse_boolean_argument("--service-txt=", optarg, NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --service-txt= argument."); return r;
SET_FLAG(arg_flags, SD_RESOLVED_NO_TXT, r == 0); SET_FLAG(arg_flags, SD_RESOLVED_NO_TXT, r == 0);
break; break;
case ARG_SEARCH: case ARG_SEARCH:
r = parse_boolean(optarg); r = parse_boolean_argument("--search=", optarg, NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --search argument."); return r;
SET_FLAG(arg_flags, SD_RESOLVED_NO_SEARCH, r == 0); SET_FLAG(arg_flags, SD_RESOLVED_NO_SEARCH, r == 0);
break; break;

View File

@ -1730,7 +1730,7 @@ bool dns_resource_record_is_link_local_address(DnsResourceRecord *rr) {
return in4_addr_is_link_local(&rr->a.in_addr); return in4_addr_is_link_local(&rr->a.in_addr);
if (rr->key->type == DNS_TYPE_AAAA) if (rr->key->type == DNS_TYPE_AAAA)
return IN6_IS_ADDR_LINKLOCAL(&rr->aaaa.in6_addr); return in6_addr_is_link_local(&rr->aaaa.in6_addr);
return false; return false;
} }

View File

@ -920,10 +920,10 @@ void dns_scope_process_query(DnsScope *s, DnsStream *stream, DnsPacket *p) {
* the LLMNR multicast addresses. See RFC 4795, * the LLMNR multicast addresses. See RFC 4795,
* section 2.5. */ * section 2.5. */
if (p->family == AF_INET && !in_addr_equal(AF_INET, &p->destination, (union in_addr_union*) &LLMNR_MULTICAST_IPV4_ADDRESS)) if (p->family == AF_INET && !in4_addr_equal(&p->destination.in, &LLMNR_MULTICAST_IPV4_ADDRESS))
return; return;
if (p->family == AF_INET6 && !in_addr_equal(AF_INET6, &p->destination, (union in_addr_union*) &LLMNR_MULTICAST_IPV6_ADDRESS)) if (p->family == AF_INET6 && !in6_addr_equal(&p->destination.in6, &LLMNR_MULTICAST_IPV6_ADDRESS))
return; return;
} }

View File

@ -378,6 +378,17 @@ void dns_server_packet_invalid(DnsServer *s, DnsServerFeatureLevel level) {
s->packet_invalid = true; s->packet_invalid = true;
} }
void dns_server_packet_do_off(DnsServer *s, DnsServerFeatureLevel level) {
assert(s);
/* Invoked whenever the DO flag was not copied from our request to the response. */
if (s->possible_feature_level != level)
return;
s->packet_do_off = true;
}
static bool dns_server_grace_period_expired(DnsServer *s) { static bool dns_server_grace_period_expired(DnsServer *s) {
usec_t ts; usec_t ts;
@ -494,6 +505,17 @@ DnsServerFeatureLevel dns_server_possible_feature_level(DnsServer *s) {
* when we can't use EDNS because the DNS server doesn't support it. */ * when we can't use EDNS because the DNS server doesn't support it. */
log_level = LOG_NOTICE; log_level = LOG_NOTICE;
} else if (s->packet_do_off &&
DNS_SERVER_FEATURE_LEVEL_IS_DNSSEC(s->possible_feature_level) &&
dns_server_get_dnssec_mode(s) != DNSSEC_YES) {
/* The server didn't copy the DO bit from request to response, thus DNSSEC is not
* correctly implemented, let's downgrade if that's allowed. */
log_debug("Detected server didn't copy DO flag from request to response, downgrading feature level...");
s->possible_feature_level = DNS_SERVER_FEATURE_LEVEL_IS_TLS(s->possible_feature_level) ? DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN :
DNS_SERVER_FEATURE_LEVEL_EDNS0;
} else if (s->packet_rrsig_missing && } else if (s->packet_rrsig_missing &&
DNS_SERVER_FEATURE_LEVEL_IS_DNSSEC(s->possible_feature_level) && DNS_SERVER_FEATURE_LEVEL_IS_DNSSEC(s->possible_feature_level) &&
dns_server_get_dnssec_mode(s) != DNSSEC_YES) { dns_server_get_dnssec_mode(s) != DNSSEC_YES) {
@ -653,6 +675,9 @@ bool dns_server_dnssec_supported(DnsServer *server) {
if (server->packet_rrsig_missing) if (server->packet_rrsig_missing)
return false; return false;
if (server->packet_do_off)
return false;
/* DNSSEC servers need to support TCP properly (see RFC5966), if they don't, we assume DNSSEC is borked too */ /* DNSSEC servers need to support TCP properly (see RFC5966), if they don't, we assume DNSSEC is borked too */
if (server->n_failed_tcp >= DNS_SERVER_FEATURE_RETRY_ATTEMPTS) if (server->n_failed_tcp >= DNS_SERVER_FEATURE_RETRY_ATTEMPTS)
return false; return false;
@ -898,6 +923,7 @@ void dns_server_reset_features(DnsServer *s) {
s->packet_bad_opt = false; s->packet_bad_opt = false;
s->packet_rrsig_missing = false; s->packet_rrsig_missing = false;
s->packet_do_off = false;
s->features_grace_period_usec = DNS_SERVER_FEATURE_GRACE_PERIOD_MIN_USEC; s->features_grace_period_usec = DNS_SERVER_FEATURE_GRACE_PERIOD_MIN_USEC;
@ -959,14 +985,16 @@ void dns_server_dump(DnsServer *s, FILE *f) {
"\tSeen truncated packet: %s\n" "\tSeen truncated packet: %s\n"
"\tSeen OPT RR getting lost: %s\n" "\tSeen OPT RR getting lost: %s\n"
"\tSeen RRSIG RR missing: %s\n" "\tSeen RRSIG RR missing: %s\n"
"\tSeen invalid packet: %s\n", "\tSeen invalid packet: %s\n"
"\tServer dropped DO flag: %s\n",
s->received_udp_packet_max, s->received_udp_packet_max,
s->n_failed_udp, s->n_failed_udp,
s->n_failed_tcp, s->n_failed_tcp,
yes_no(s->packet_truncated), yes_no(s->packet_truncated),
yes_no(s->packet_bad_opt), yes_no(s->packet_bad_opt),
yes_no(s->packet_rrsig_missing), yes_no(s->packet_rrsig_missing),
yes_no(s->packet_invalid)); yes_no(s->packet_invalid),
yes_no(s->packet_do_off));
} }
void dns_server_unref_stream(DnsServer *s) { void dns_server_unref_stream(DnsServer *s) {

View File

@ -85,6 +85,7 @@ struct DnsServer {
bool packet_bad_opt:1; /* Set when OPT was missing or otherwise bad on reply */ bool packet_bad_opt:1; /* Set when OPT was missing or otherwise bad on reply */
bool packet_rrsig_missing:1; /* Set when RRSIG was missing */ bool packet_rrsig_missing:1; /* Set when RRSIG was missing */
bool packet_invalid:1; /* Set when we failed to parse a reply */ bool packet_invalid:1; /* Set when we failed to parse a reply */
bool packet_do_off:1; /* Set when the server didn't copy DNSSEC DO flag from request to response */
usec_t verified_usec; usec_t verified_usec;
usec_t features_grace_period_usec; usec_t features_grace_period_usec;
@ -124,6 +125,7 @@ void dns_server_packet_rrsig_missing(DnsServer *s, DnsServerFeatureLevel level);
void dns_server_packet_bad_opt(DnsServer *s, DnsServerFeatureLevel level); void dns_server_packet_bad_opt(DnsServer *s, DnsServerFeatureLevel level);
void dns_server_packet_rcode_downgrade(DnsServer *s, DnsServerFeatureLevel level); void dns_server_packet_rcode_downgrade(DnsServer *s, DnsServerFeatureLevel level);
void dns_server_packet_invalid(DnsServer *s, DnsServerFeatureLevel level); void dns_server_packet_invalid(DnsServer *s, DnsServerFeatureLevel level);
void dns_server_packet_do_off(DnsServer *s, DnsServerFeatureLevel level);
DnsServerFeatureLevel dns_server_possible_feature_level(DnsServer *s); DnsServerFeatureLevel dns_server_possible_feature_level(DnsServer *s);

View File

@ -187,7 +187,7 @@ static int dns_stream_identify(DnsStream *s) {
/* If we don't know the interface index still, we look for the /* If we don't know the interface index still, we look for the
* first local interface with a matching address. Yuck! */ * first local interface with a matching address. Yuck! */
if (s->ifindex <= 0) if (s->ifindex <= 0)
s->ifindex = manager_find_ifindex(s->manager, s->local.sa.sa_family, s->local.sa.sa_family == AF_INET ? (union in_addr_union*) &s->local.in.sin_addr : (union in_addr_union*) &s->local.in6.sin6_addr); s->ifindex = manager_find_ifindex(s->manager, s->local.sa.sa_family, sockaddr_in_addr(&s->local.sa));
if (s->protocol == DNS_PROTOCOL_LLMNR && s->ifindex > 0) { if (s->protocol == DNS_PROTOCOL_LLMNR && s->ifindex > 0) {
/* Make sure all packets for this connection are sent on the same interface */ /* Make sure all packets for this connection are sent on the same interface */

View File

@ -844,6 +844,7 @@ static bool dns_transaction_dnssec_is_live(DnsTransaction *t) {
static int dns_transaction_dnssec_ready(DnsTransaction *t) { static int dns_transaction_dnssec_ready(DnsTransaction *t) {
DnsTransaction *dt; DnsTransaction *dt;
int r;
assert(t); assert(t);
@ -877,7 +878,7 @@ static int dns_transaction_dnssec_ready(DnsTransaction *t) {
case DNS_TRANSACTION_DNSSEC_FAILED: case DNS_TRANSACTION_DNSSEC_FAILED:
/* We handle DNSSEC failures different from other errors, as we care about the DNSSEC /* We handle DNSSEC failures different from other errors, as we care about the DNSSEC
* validationr result */ * validation result */
log_debug("Auxiliary DNSSEC RR query failed validation: %s", dnssec_result_to_string(dt->answer_dnssec_result)); log_debug("Auxiliary DNSSEC RR query failed validation: %s", dnssec_result_to_string(dt->answer_dnssec_result));
t->answer_dnssec_result = dt->answer_dnssec_result; /* Copy error code over */ t->answer_dnssec_result = dt->answer_dnssec_result; /* Copy error code over */
@ -894,6 +895,18 @@ static int dns_transaction_dnssec_ready(DnsTransaction *t) {
return 1; return 1;
fail: fail:
/* Some auxiliary DNSSEC transaction failed for some reason. Maybe we learned something about the
* server due to this failure, and the feature level is now different? Let's see and restart the
* transaction if so. If not, let's propagate the auxiliary failure.
*
* This is particularly relevant if an auxiliary request figured out that DNSSEC doesn't work, and we
* are in permissive DNSSEC mode, and thus should restart things without DNSSEC magic. */
r = dns_transaction_maybe_restart(t);
if (r < 0)
return r;
if (r > 0)
return 0; /* don't validate just yet, we restarted things */
t->answer_dnssec_result = DNSSEC_FAILED_AUXILIARY; t->answer_dnssec_result = DNSSEC_FAILED_AUXILIARY;
dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED); dns_transaction_complete(t, DNS_TRANSACTION_DNSSEC_FAILED);
return 0; return 0;
@ -1279,6 +1292,10 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p, bool encrypt
if (!p->opt) if (!p->opt)
dns_server_packet_bad_opt(t->server, t->current_feature_level); dns_server_packet_bad_opt(t->server, t->current_feature_level);
/* Report that the server didn't copy our query DO bit from request to response */
if (DNS_PACKET_DO(t->sent) && !DNS_PACKET_DO(t->received))
dns_server_packet_do_off(t->server, t->current_feature_level);
/* Report that we successfully received a packet */ /* Report that we successfully received a packet */
dns_server_packet_received(t->server, p->ipproto, t->current_feature_level, p->size); dns_server_packet_received(t->server, p->ipproto, t->current_feature_level, p->size);
} }

View File

@ -61,7 +61,7 @@ static int parse_line(EtcHosts *hosts, unsigned nr, const char *line) {
return 0; return 0;
} }
r = in_addr_is_null(address.family, &address.address); r = in_addr_data_is_null(&address);
if (r < 0) { if (r < 0) {
log_warning_errno(r, "/etc/hosts:%u: address '%s' is invalid, ignoring: %m", nr, address_str); log_warning_errno(r, "/etc/hosts:%u: address '%s' is invalid, ignoring: %m", nr, address_str);
return 0; return 0;

View File

@ -697,6 +697,12 @@ LinkAddress *link_find_address(Link *l, int family, const union in_addr_union *i
assert(l); assert(l);
if (!IN_SET(family, AF_INET, AF_INET6))
return NULL;
if (!in_addr)
return NULL;
LIST_FOREACH(addresses, a, l->addresses) LIST_FOREACH(addresses, a, l->addresses)
if (a->family == family && in_addr_equal(family, &a->in_addr, in_addr)) if (a->family == family && in_addr_equal(family, &a->in_addr, in_addr))
return a; return a;

View File

@ -1153,6 +1153,12 @@ int manager_find_ifindex(Manager *m, int family, const union in_addr_union *in_a
assert(m); assert(m);
if (!IN_SET(family, AF_INET, AF_INET6))
return 0;
if (!in_addr)
return 0;
a = manager_find_link_address(m, family, in_addr); a = manager_find_link_address(m, family, in_addr);
if (a) if (a)
return a->link->ifindex; return a->link->ifindex;
@ -1248,6 +1254,12 @@ LinkAddress* manager_find_link_address(Manager *m, int family, const union in_ad
assert(m); assert(m);
if (!IN_SET(family, AF_INET, AF_INET6))
return NULL;
if (!in_addr)
return NULL;
HASHMAP_FOREACH(l, m->links) { HASHMAP_FOREACH(l, m->links) {
LinkAddress *a; LinkAddress *a;

View File

@ -2388,7 +2388,7 @@ int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet, Un
while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) { while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
/* We expect only "success" changes to be sent over the bus. /* We expect only "success" changes to be sent over the bus.
Hence, reject anything negative. */ Hence, reject anything negative. */
UnitFileChangeType ch = unit_file_change_type_from_string(type); int ch = unit_file_change_type_from_string(type);
if (ch < 0) { if (ch < 0) {
log_notice_errno(ch, "Manager reported unknown change type \"%s\" for path \"%s\", ignoring.", log_notice_errno(ch, "Manager reported unknown change type \"%s\" for path \"%s\", ignoring.",
type, path); type, path);

View File

@ -18,7 +18,6 @@
#include "firewall-util-private.h" #include "firewall-util-private.h"
#include "in-addr-util.h" #include "in-addr-util.h"
#include "macro.h" #include "macro.h"
#include "memory-util.h"
#include "socket-util.h" #include "socket-util.h"
#include "time-util.h" #include "time-util.h"
@ -30,9 +29,6 @@
#define UDP_DPORT_OFFSET 2 #define UDP_DPORT_OFFSET 2
void nft_in6addr_to_range(const union in_addr_union *source, unsigned int prefixlen,
struct in6_addr *start, struct in6_addr *end);
static int nfnl_netlink_sendv(sd_netlink *nfnl, static int nfnl_netlink_sendv(sd_netlink *nfnl,
sd_netlink_message *messages[], sd_netlink_message *messages[],
size_t msgcount) { size_t msgcount) {
@ -848,55 +844,19 @@ static int fw_nftables_recreate_table(sd_netlink *nfnl, int af, sd_netlink_messa
return 0; return 0;
} }
void nft_in6addr_to_range(const union in_addr_union *source, unsigned int prefixlen, static int nft_message_add_setelem_ip6range(
struct in6_addr *ret_start, struct in6_addr *ret_end) { sd_netlink_message *m,
uint8_t carry = 0; const union in_addr_union *source,
int i, j; unsigned int prefixlen) {
assert(prefixlen <= 128); union in_addr_union start, end;
for (i = 0, j = 15; i < 16; i++) {
uint8_t nm;
nm = 0xFF;
if (prefixlen < 8)
nm = 0xFF << (8 - prefixlen);
ret_start->s6_addr[i] = source->in6.s6_addr[i] & nm;
if (prefixlen <= 8 && j == 15) {
carry = 1u << (8 - prefixlen);
j = i;
}
if (prefixlen >= 8)
prefixlen -= 8;
else
prefixlen = 0;
}
*ret_end = *ret_start;
for (; j >= 0; j--) {
uint16_t overflow = ret_end->s6_addr[j] + carry;
ret_end->s6_addr[j] = overflow;
if (overflow <= 0xff)
break;
carry = 1;
}
if (memcmp(ret_start, ret_end, sizeof(*ret_start)) > 0)
zero(ret_end);
}
static int nft_message_add_setelem_ip6range(sd_netlink_message *m,
const union in_addr_union *source,
unsigned int prefixlen) {
struct in6_addr start, end;
int r; int r;
nft_in6addr_to_range(source, prefixlen, &start, &end); r = in_addr_prefix_range(AF_INET6, source, prefixlen, &start, &end);
if (r < 0)
return r;
r = sd_nfnl_nft_message_add_setelem(m, 0, &start, sizeof(start), NULL, 0); r = sd_nfnl_nft_message_add_setelem(m, 0, &start.in6, sizeof(start.in6), NULL, 0);
if (r < 0) if (r < 0)
return r; return r;
@ -904,7 +864,7 @@ static int nft_message_add_setelem_ip6range(sd_netlink_message *m,
if (r < 0) if (r < 0)
return r; return r;
r = sd_nfnl_nft_message_add_setelem(m, 1, &end, sizeof(end), NULL, 0); r = sd_nfnl_nft_message_add_setelem(m, 1, &end.in6, sizeof(end.in6), NULL, 0);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -14,6 +14,7 @@
#include "conf-parser.h" #include "conf-parser.h"
#include "def.h" #include "def.h"
#include "dirent-util.h" #include "dirent-util.h"
#include "errno-list.h"
#include "extract-word.h" #include "extract-word.h"
#include "fd-util.h" #include "fd-util.h"
#include "fileio.h" #include "fileio.h"
@ -261,7 +262,7 @@ static const char* config_path_from_flags(const LookupPaths *paths, UnitFileFlag
int unit_file_changes_add( int unit_file_changes_add(
UnitFileChange **changes, UnitFileChange **changes,
size_t *n_changes, size_t *n_changes,
int type, int type_or_errno, /* UNIT_FILE_SYMLINK, _UNLINK, _IS_MASKED, _IS_DANGLING if positive or errno if negative */
const char *path, const char *path,
const char *source) { const char *source) {
@ -271,6 +272,11 @@ int unit_file_changes_add(
assert(path); assert(path);
assert(!changes == !n_changes); assert(!changes == !n_changes);
if (type_or_errno >= 0)
assert(type_or_errno < _UNIT_FILE_CHANGE_TYPE_MAX);
else
assert(type_or_errno >= -ERRNO_MAX);
if (!changes) if (!changes)
return 0; return 0;
@ -280,19 +286,25 @@ int unit_file_changes_add(
*changes = c; *changes = c;
p = strdup(path); p = strdup(path);
if (source) if (!p)
s = strdup(source);
if (!p || (source && !s))
return -ENOMEM; return -ENOMEM;
path_simplify(p, false); path_simplify(p, false);
if (s)
path_simplify(s, false);
c[*n_changes] = (UnitFileChange) { type, p, s }; if (source) {
p = s = NULL; s = strdup(source);
(*n_changes) ++; if (!s)
return -ENOMEM;
path_simplify(s, false);
}
c[(*n_changes)++] = (UnitFileChange) {
.type_or_errno = type_or_errno,
.path = TAKE_PTR(p),
.source = TAKE_PTR(s),
};
return 0; return 0;
} }
@ -315,9 +327,9 @@ void unit_file_dump_changes(int r, const char *verb, const UnitFileChange *chang
assert(verb || r >= 0); assert(verb || r >= 0);
for (size_t i = 0; i < n_changes; i++) { for (size_t i = 0; i < n_changes; i++) {
assert(verb || changes[i].type >= 0); assert(verb || changes[i].type_or_errno >= 0);
switch(changes[i].type) { switch(changes[i].type_or_errno) {
case UNIT_FILE_SYMLINK: case UNIT_FILE_SYMLINK:
if (!quiet) if (!quiet)
log_info("Created symlink %s %s %s.", log_info("Created symlink %s %s %s.",
@ -340,45 +352,45 @@ void unit_file_dump_changes(int r, const char *verb, const UnitFileChange *chang
break; break;
case -EEXIST: case -EEXIST:
if (changes[i].source) if (changes[i].source)
log_error_errno(changes[i].type, log_error_errno(changes[i].type_or_errno,
"Failed to %s unit, file %s already exists and is a symlink to %s.", "Failed to %s unit, file %s already exists and is a symlink to %s.",
verb, changes[i].path, changes[i].source); verb, changes[i].path, changes[i].source);
else else
log_error_errno(changes[i].type, log_error_errno(changes[i].type_or_errno,
"Failed to %s unit, file %s already exists.", "Failed to %s unit, file %s already exists.",
verb, changes[i].path); verb, changes[i].path);
logged = true; logged = true;
break; break;
case -ERFKILL: case -ERFKILL:
log_error_errno(changes[i].type, "Failed to %s unit, unit %s is masked.", log_error_errno(changes[i].type_or_errno, "Failed to %s unit, unit %s is masked.",
verb, changes[i].path); verb, changes[i].path);
logged = true; logged = true;
break; break;
case -EADDRNOTAVAIL: case -EADDRNOTAVAIL:
log_error_errno(changes[i].type, "Failed to %s unit, unit %s is transient or generated.", log_error_errno(changes[i].type_or_errno, "Failed to %s unit, unit %s is transient or generated.",
verb, changes[i].path); verb, changes[i].path);
logged = true; logged = true;
break; break;
case -EUCLEAN: case -EUCLEAN:
log_error_errno(changes[i].type, log_error_errno(changes[i].type_or_errno,
"Failed to %s unit, \"%s\" is not a valid unit name.", "Failed to %s unit, \"%s\" is not a valid unit name.",
verb, changes[i].path); verb, changes[i].path);
logged = true; logged = true;
break; break;
case -ELOOP: case -ELOOP:
log_error_errno(changes[i].type, "Failed to %s unit, refusing to operate on linked unit file %s", log_error_errno(changes[i].type_or_errno, "Failed to %s unit, refusing to operate on linked unit file %s",
verb, changes[i].path); verb, changes[i].path);
logged = true; logged = true;
break; break;
case -ENOENT: case -ENOENT:
log_error_errno(changes[i].type, "Failed to %s unit, unit %s does not exist.", verb, changes[i].path); log_error_errno(changes[i].type_or_errno, "Failed to %s unit, unit %s does not exist.", verb, changes[i].path);
logged = true; logged = true;
break; break;
default: default:
assert(changes[i].type < 0); assert(changes[i].type_or_errno < 0);
log_error_errno(changes[i].type, "Failed to %s unit, file %s: %m.", log_error_errno(changes[i].type_or_errno, "Failed to %s unit, file %s: %m.",
verb, changes[i].path); verb, changes[i].path);
logged = true; logged = true;
} }
@ -3464,7 +3476,7 @@ static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX]
[UNIT_FILE_IS_DANGLING] = "dangling", [UNIT_FILE_IS_DANGLING] = "dangling",
}; };
DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, UnitFileChangeType); DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, int);
static const char* const unit_file_preset_mode_table[_UNIT_FILE_PRESET_MAX] = { static const char* const unit_file_preset_mode_table[_UNIT_FILE_PRESET_MAX] = {
[UNIT_FILE_PRESET_FULL] = "full", [UNIT_FILE_PRESET_FULL] = "full",

View File

@ -25,7 +25,9 @@ enum UnitFilePresetMode {
_UNIT_FILE_PRESET_INVALID = -EINVAL, _UNIT_FILE_PRESET_INVALID = -EINVAL,
}; };
enum UnitFileChangeType { /* This enum type is anonymous, since we usually store it in an 'int', as we overload it with negative errno
* values. */
enum {
UNIT_FILE_SYMLINK, UNIT_FILE_SYMLINK,
UNIT_FILE_UNLINK, UNIT_FILE_UNLINK,
UNIT_FILE_IS_MASKED, UNIT_FILE_IS_MASKED,
@ -42,20 +44,18 @@ enum UnitFileFlags {
_UNIT_FILE_FLAGS_MASK_PUBLIC = UNIT_FILE_RUNTIME|UNIT_FILE_PORTABLE|UNIT_FILE_FORCE, _UNIT_FILE_FLAGS_MASK_PUBLIC = UNIT_FILE_RUNTIME|UNIT_FILE_PORTABLE|UNIT_FILE_FORCE,
}; };
/* type can either one of the UnitFileChangeTypes listed above, or a negative error. /* type can either one of the UNIT_FILE_SYMLINK, UNIT_FILE_UNLINK, … listed above, or a negative errno value.
* If source is specified, it should be the contents of the path symlink. * If source is specified, it should be the contents of the path symlink. In case of an error, source should
* In case of an error, source should be the existing symlink contents or NULL * be the existing symlink contents or NULL. */
*/
struct UnitFileChange { struct UnitFileChange {
int type; /* UnitFileChangeType or bust */ int type_or_errno; /* UNIT_FILE_SYMLINK, … if positive, errno if negative */
char *path; char *path;
char *source; char *source;
}; };
static inline bool unit_file_changes_have_modification(const UnitFileChange* changes, size_t n_changes) { static inline bool unit_file_changes_have_modification(const UnitFileChange* changes, size_t n_changes) {
size_t i; for (size_t i = 0; i < n_changes; i++)
for (i = 0; i < n_changes; i++) if (IN_SET(changes[i].type_or_errno, UNIT_FILE_SYMLINK, UNIT_FILE_UNLINK))
if (IN_SET(changes[i].type, UNIT_FILE_SYMLINK, UNIT_FILE_UNLINK))
return true; return true;
return false; return false;
} }
@ -206,8 +206,8 @@ const char *unit_file_state_to_string(UnitFileState s) _const_;
UnitFileState unit_file_state_from_string(const char *s) _pure_; UnitFileState unit_file_state_from_string(const char *s) _pure_;
/* from_string conversion is unreliable because of the overlap between -EPERM and -1 for error. */ /* from_string conversion is unreliable because of the overlap between -EPERM and -1 for error. */
const char *unit_file_change_type_to_string(UnitFileChangeType s) _const_; const char *unit_file_change_type_to_string(int s) _const_;
UnitFileChangeType unit_file_change_type_from_string(const char *s) _pure_; int unit_file_change_type_from_string(const char *s) _pure_;
const char *unit_file_preset_mode_to_string(UnitFilePresetMode m) _const_; const char *unit_file_preset_mode_to_string(UnitFilePresetMode m) _const_;
UnitFilePresetMode unit_file_preset_mode_from_string(const char *s) _pure_; UnitFilePresetMode unit_file_preset_mode_from_string(const char *s) _pure_;

View File

@ -10,6 +10,27 @@
/* All functions in this file emit warnigs. */ /* All functions in this file emit warnigs. */
int parse_boolean_argument(const char *optname, const char *s, bool *ret) {
int r;
/* Returns the result through *ret and the return value. */
if (s) {
r = parse_boolean(s);
if (r < 0)
return log_error_errno(r, "Failed to parse boolean argument to %s: %s.", optname, s);
if (ret)
*ret = r;
return r;
} else {
/* s may be NULL. This is controlled by getopt_long() parameters. */
if (ret)
*ret = true;
return true;
}
}
int parse_json_argument(const char *s, JsonFormatFlags *ret) { int parse_json_argument(const char *s, JsonFormatFlags *ret) {
assert(s); assert(s);
assert(ret); assert(ret);

View File

@ -3,6 +3,7 @@
#include "json.h" #include "json.h"
int parse_boolean_argument(const char *optname, const char *s, bool *ret);
int parse_json_argument(const char *s, JsonFormatFlags *ret); int parse_json_argument(const char *s, JsonFormatFlags *ret);
int parse_path_argument(const char *path, bool suppress_root, char **arg); int parse_path_argument(const char *path, bool suppress_root, char **arg);
int parse_signal_argument(const char *s, int *ret); int parse_signal_argument(const char *s, int *ret);

View File

@ -33,7 +33,7 @@ bool dns_server_address_valid(int family, const union in_addr_union *sa) {
/* Refuses the 0 IP addresses as well as 127.0.0.53 (which is our own DNS stub) */ /* Refuses the 0 IP addresses as well as 127.0.0.53 (which is our own DNS stub) */
if (in_addr_is_null(family, sa)) if (!in_addr_is_set(family, sa))
return false; return false;
if (family == AF_INET && sa->in.s_addr == htobe32(INADDR_DNS_STUB)) if (family == AF_INET && sa->in.s_addr == htobe32(INADDR_DNS_STUB))

View File

@ -161,7 +161,7 @@ static int apply_all(OrderedHashmap *sysctl_options) {
continue; continue;
if (ordered_hashmap_contains(sysctl_options, key)) { if (ordered_hashmap_contains(sysctl_options, key)) {
log_info("Not setting %s (explicit setting exists).", key); log_debug("Not setting %s (explicit setting exists).", key);
continue; continue;
} }

View File

@ -23,7 +23,7 @@ static int show_installation_targets_client_side(const char *name) {
return log_error_errno(r, "Failed to get file links for %s: %m", name); return log_error_errno(r, "Failed to get file links for %s: %m", name);
for (size_t i = 0; i < n_changes; i++) for (size_t i = 0; i < n_changes; i++)
if (changes[i].type == UNIT_FILE_UNLINK) if (changes[i].type_or_errno == UNIT_FILE_UNLINK)
printf(" %s\n", changes[i].path); printf(" %s\n", changes[i].path);
return 0; return 0;

View File

@ -64,7 +64,7 @@ static int output_jobs_list(sd_bus *bus, const struct job_info* jobs, unsigned n
assert(n == 0 || jobs); assert(n == 0 || jobs);
if (n == 0) { if (n == 0) {
if (!arg_no_legend) { if (arg_legend != 0) {
on = ansi_highlight_green(); on = ansi_highlight_green();
off = ansi_normal(); off = ansi_normal();
@ -79,7 +79,7 @@ static int output_jobs_list(sd_bus *bus, const struct job_info* jobs, unsigned n
if (!table) if (!table)
return log_oom(); return log_oom();
table_set_header(table, !arg_no_legend); table_set_header(table, arg_legend != 0);
if (arg_full) if (arg_full)
table_set_width(table, 0); table_set_width(table, 0);
@ -111,7 +111,7 @@ static int output_jobs_list(sd_bus *bus, const struct job_info* jobs, unsigned n
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to print the table: %m"); return log_error_errno(r, "Failed to print the table: %m");
if (!arg_no_legend) { if (arg_legend != 0) {
on = ansi_highlight(); on = ansi_highlight();
off = ansi_normal(); off = ansi_normal();

View File

@ -157,7 +157,7 @@ static int output_machines_list(struct machine_info *machine_infos, unsigned n)
if (!table) if (!table)
return log_oom(); return log_oom();
table_set_header(table, !arg_no_legend); table_set_header(table, arg_legend != 0);
if (arg_plain) { if (arg_plain) {
/* Hide the 'glyph' column when --plain is requested */ /* Hide the 'glyph' column when --plain is requested */
r = table_hide_column_from_display(table, 0); r = table_hide_column_from_display(table, 0);
@ -210,7 +210,7 @@ static int output_machines_list(struct machine_info *machine_infos, unsigned n)
if (r < 0) if (r < 0)
return r; return r;
if (!arg_no_legend) { if (arg_legend != 0) {
printf("\n"); printf("\n");
if (state_missing && geteuid() != 0) if (state_missing && geteuid() != 0)
printf("Notice: some information only available to privileged users was not shown.\n"); printf("Notice: some information only available to privileged users was not shown.\n");

View File

@ -58,7 +58,7 @@ static int output_unit_file_list(const UnitFileList *units, unsigned c) {
if (!table) if (!table)
return log_oom(); return log_oom();
table_set_header(table, !arg_no_legend); table_set_header(table, arg_legend != 0);
if (arg_full) if (arg_full)
table_set_width(table, 0); table_set_width(table, 0);
@ -127,7 +127,7 @@ static int output_unit_file_list(const UnitFileList *units, unsigned c) {
if (r < 0) if (r < 0)
return r; return r;
if (!arg_no_legend) if (arg_legend != 0)
printf("\n%u unit files listed.\n", c); printf("\n%u unit files listed.\n", c);
return 0; return 0;

View File

@ -97,7 +97,7 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
if (!table) if (!table)
return log_oom(); return log_oom();
table_set_header(table, !arg_no_legend); table_set_header(table, arg_legend != 0);
if (arg_plain) { if (arg_plain) {
/* Hide the 'glyph' column when --plain is requested */ /* Hide the 'glyph' column when --plain is requested */
r = table_hide_column_from_display(table, 0); r = table_hide_column_from_display(table, 0);
@ -177,7 +177,7 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
if (r < 0) if (r < 0)
return r; return r;
if (!arg_no_legend) { if (arg_legend != 0) {
const char *on, *off; const char *on, *off;
size_t records = table_get_rows(table) - 1; size_t records = table_get_rows(table) - 1;
@ -365,7 +365,7 @@ static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
return log_error_errno(r, "Failed to set columns to display: %m"); return log_error_errno(r, "Failed to set columns to display: %m");
} }
table_set_header(table, !arg_no_legend); table_set_header(table, arg_legend != 0);
if (arg_full) if (arg_full)
table_set_width(table, 0); table_set_width(table, 0);
@ -416,7 +416,7 @@ static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
if (r < 0) if (r < 0)
return r; return r;
if (!arg_no_legend) { if (arg_legend != 0) {
printf("\n%s%u sockets listed.%s\n", on, cs, off); printf("\n%s%u sockets listed.%s\n", on, cs, off);
if (!arg_all) if (!arg_all)
printf("Pass --all to see loaded but inactive sockets, too.\n"); printf("Pass --all to see loaded but inactive sockets, too.\n");
@ -610,7 +610,7 @@ static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
if (!table) if (!table)
return log_oom(); return log_oom();
table_set_header(table, !arg_no_legend); table_set_header(table, arg_legend != 0);
if (arg_full) if (arg_full)
table_set_width(table, 0); table_set_width(table, 0);
@ -655,7 +655,7 @@ static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
if (r < 0) if (r < 0)
return r; return r;
if (!arg_no_legend) { if (arg_legend != 0) {
printf("\n%s%u timers listed.%s\n", on, n, off); printf("\n%s%u timers listed.%s\n", on, n, off);
if (!arg_all) if (!arg_all)
printf("Pass --all to see loaded but inactive timers, too.\n"); printf("Pass --all to see loaded but inactive timers, too.\n");

View File

@ -1474,7 +1474,7 @@ static int print_property(const char *name, const char *expected_value, sd_bus_m
if (prefixlen > FAMILY_ADDRESS_SIZE(family) * 8) if (prefixlen > FAMILY_ADDRESS_SIZE(family) * 8)
continue; continue;
if (in_addr_prefix_to_string(family, (union in_addr_union *) ap, prefixlen, &str) < 0) if (in_addr_prefix_to_string(family, (const union in_addr_union*) ap, prefixlen, &str) < 0)
continue; continue;
if (!strextend_with_separator(&addresses, " ", str)) if (!strextend_with_separator(&addresses, " ", str))

View File

@ -68,7 +68,7 @@ const char *arg_job_mode = "replace";
UnitFileScope arg_scope = UNIT_FILE_SYSTEM; UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
bool arg_wait = false; bool arg_wait = false;
bool arg_no_block = false; bool arg_no_block = false;
bool arg_no_legend = false; int arg_legend = -1; /* -1: true, unless --quiet is passed, 1: true */
PagerFlags arg_pager_flags = 0; PagerFlags arg_pager_flags = 0;
bool arg_no_wtmp = false; bool arg_no_wtmp = false;
bool arg_no_sync = false; bool arg_no_sync = false;
@ -268,7 +268,7 @@ static int systemctl_help(void) {
" --no-block Do not wait until operation finished\n" " --no-block Do not wait until operation finished\n"
" --no-wall Don't send wall message before halt/power-off/reboot\n" " --no-wall Don't send wall message before halt/power-off/reboot\n"
" --no-reload Don't reload daemon after en-/dis-abling unit files\n" " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
" --no-legend Do not print a legend (column headers and hints)\n" " --legend=BOOL Enable/disable the legend (column headers and hints)\n"
" --no-pager Do not pipe output into a pager\n" " --no-pager Do not pipe output into a pager\n"
" --no-ask-password Do not ask for system passwords\n" " --no-ask-password Do not ask for system passwords\n"
" --global Enable/disable/mask unit files globally\n" " --global Enable/disable/mask unit files globally\n"
@ -310,88 +310,89 @@ static int systemctl_help(void) {
} }
static void help_types(void) { static void help_types(void) {
if (!arg_no_legend) if (arg_legend != 0)
puts("Available unit types:"); puts("Available unit types:");
DUMP_STRING_TABLE(unit_type, UnitType, _UNIT_TYPE_MAX); DUMP_STRING_TABLE(unit_type, UnitType, _UNIT_TYPE_MAX);
} }
static void help_states(void) { static void help_states(void) {
if (!arg_no_legend) if (arg_legend != 0)
puts("Available unit load states:"); puts("Available unit load states:");
DUMP_STRING_TABLE(unit_load_state, UnitLoadState, _UNIT_LOAD_STATE_MAX); DUMP_STRING_TABLE(unit_load_state, UnitLoadState, _UNIT_LOAD_STATE_MAX);
if (!arg_no_legend) if (arg_legend != 0)
puts("\nAvailable unit active states:"); puts("\nAvailable unit active states:");
DUMP_STRING_TABLE(unit_active_state, UnitActiveState, _UNIT_ACTIVE_STATE_MAX); DUMP_STRING_TABLE(unit_active_state, UnitActiveState, _UNIT_ACTIVE_STATE_MAX);
if (!arg_no_legend) if (arg_legend != 0)
puts("\nAvailable unit file states:"); puts("\nAvailable unit file states:");
DUMP_STRING_TABLE(unit_file_state, UnitFileState, _UNIT_FILE_STATE_MAX); DUMP_STRING_TABLE(unit_file_state, UnitFileState, _UNIT_FILE_STATE_MAX);
if (!arg_no_legend) if (arg_legend != 0)
puts("\nAvailable automount unit substates:"); puts("\nAvailable automount unit substates:");
DUMP_STRING_TABLE(automount_state, AutomountState, _AUTOMOUNT_STATE_MAX); DUMP_STRING_TABLE(automount_state, AutomountState, _AUTOMOUNT_STATE_MAX);
if (!arg_no_legend) if (arg_legend != 0)
puts("\nAvailable device unit substates:"); puts("\nAvailable device unit substates:");
DUMP_STRING_TABLE(device_state, DeviceState, _DEVICE_STATE_MAX); DUMP_STRING_TABLE(device_state, DeviceState, _DEVICE_STATE_MAX);
if (!arg_no_legend) if (arg_legend != 0)
puts("\nAvailable mount unit substates:"); puts("\nAvailable mount unit substates:");
DUMP_STRING_TABLE(mount_state, MountState, _MOUNT_STATE_MAX); DUMP_STRING_TABLE(mount_state, MountState, _MOUNT_STATE_MAX);
if (!arg_no_legend) if (arg_legend != 0)
puts("\nAvailable path unit substates:"); puts("\nAvailable path unit substates:");
DUMP_STRING_TABLE(path_state, PathState, _PATH_STATE_MAX); DUMP_STRING_TABLE(path_state, PathState, _PATH_STATE_MAX);
if (!arg_no_legend) if (arg_legend != 0)
puts("\nAvailable scope unit substates:"); puts("\nAvailable scope unit substates:");
DUMP_STRING_TABLE(scope_state, ScopeState, _SCOPE_STATE_MAX); DUMP_STRING_TABLE(scope_state, ScopeState, _SCOPE_STATE_MAX);
if (!arg_no_legend) if (arg_legend != 0)
puts("\nAvailable service unit substates:"); puts("\nAvailable service unit substates:");
DUMP_STRING_TABLE(service_state, ServiceState, _SERVICE_STATE_MAX); DUMP_STRING_TABLE(service_state, ServiceState, _SERVICE_STATE_MAX);
if (!arg_no_legend) if (arg_legend != 0)
puts("\nAvailable slice unit substates:"); puts("\nAvailable slice unit substates:");
DUMP_STRING_TABLE(slice_state, SliceState, _SLICE_STATE_MAX); DUMP_STRING_TABLE(slice_state, SliceState, _SLICE_STATE_MAX);
if (!arg_no_legend) if (arg_legend != 0)
puts("\nAvailable socket unit substates:"); puts("\nAvailable socket unit substates:");
DUMP_STRING_TABLE(socket_state, SocketState, _SOCKET_STATE_MAX); DUMP_STRING_TABLE(socket_state, SocketState, _SOCKET_STATE_MAX);
if (!arg_no_legend) if (arg_legend != 0)
puts("\nAvailable swap unit substates:"); puts("\nAvailable swap unit substates:");
DUMP_STRING_TABLE(swap_state, SwapState, _SWAP_STATE_MAX); DUMP_STRING_TABLE(swap_state, SwapState, _SWAP_STATE_MAX);
if (!arg_no_legend) if (arg_legend != 0)
puts("\nAvailable target unit substates:"); puts("\nAvailable target unit substates:");
DUMP_STRING_TABLE(target_state, TargetState, _TARGET_STATE_MAX); DUMP_STRING_TABLE(target_state, TargetState, _TARGET_STATE_MAX);
if (!arg_no_legend) if (arg_legend != 0)
puts("\nAvailable timer unit substates:"); puts("\nAvailable timer unit substates:");
DUMP_STRING_TABLE(timer_state, TimerState, _TIMER_STATE_MAX); DUMP_STRING_TABLE(timer_state, TimerState, _TIMER_STATE_MAX);
} }
static int systemctl_parse_argv(int argc, char *argv[]) { static int systemctl_parse_argv(int argc, char *argv[]) {
enum { enum {
ARG_FAIL = 0x100, ARG_FAIL = 0x100, /* compatibility only */
ARG_REVERSE, ARG_REVERSE,
ARG_AFTER, ARG_AFTER,
ARG_BEFORE, ARG_BEFORE,
ARG_CHECK_INHIBITORS, ARG_CHECK_INHIBITORS,
ARG_DRY_RUN, ARG_DRY_RUN,
ARG_SHOW_TYPES, ARG_SHOW_TYPES,
ARG_IRREVERSIBLE, ARG_IRREVERSIBLE, /* compatibility only */
ARG_IGNORE_DEPENDENCIES, ARG_IGNORE_DEPENDENCIES, /* compatibility only */
ARG_VALUE, ARG_VALUE,
ARG_VERSION, ARG_VERSION,
ARG_USER, ARG_USER,
ARG_SYSTEM, ARG_SYSTEM,
ARG_GLOBAL, ARG_GLOBAL,
ARG_NO_BLOCK, ARG_NO_BLOCK,
ARG_NO_LEGEND, ARG_LEGEND,
ARG_NO_LEGEND, /* compatibility only */
ARG_NO_PAGER, ARG_NO_PAGER,
ARG_NO_WALL, ARG_NO_WALL,
ARG_ROOT, ARG_ROOT,
@ -443,7 +444,8 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
{ "global", no_argument, NULL, ARG_GLOBAL }, { "global", no_argument, NULL, ARG_GLOBAL },
{ "wait", no_argument, NULL, ARG_WAIT }, { "wait", no_argument, NULL, ARG_WAIT },
{ "no-block", no_argument, NULL, ARG_NO_BLOCK }, { "no-block", no_argument, NULL, ARG_NO_BLOCK },
{ "no-legend", no_argument, NULL, ARG_NO_LEGEND }, { "legend", required_argument, NULL, ARG_LEGEND },
{ "no-legend", no_argument, NULL, ARG_NO_LEGEND }, /* compatibility only */
{ "no-pager", no_argument, NULL, ARG_NO_PAGER }, { "no-pager", no_argument, NULL, ARG_NO_PAGER },
{ "no-wall", no_argument, NULL, ARG_NO_WALL }, { "no-wall", no_argument, NULL, ARG_NO_WALL },
{ "dry-run", no_argument, NULL, ARG_DRY_RUN }, { "dry-run", no_argument, NULL, ARG_DRY_RUN },
@ -630,7 +632,14 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
break; break;
case ARG_NO_LEGEND: case ARG_NO_LEGEND:
arg_no_legend = true; arg_legend = false;
break;
case ARG_LEGEND:
r = parse_boolean_argument("--legend", optarg, NULL);
if (r < 0)
return r;
arg_legend = r;
break; break;
case ARG_NO_PAGER: case ARG_NO_PAGER:
@ -663,6 +672,10 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
case 'q': case 'q':
arg_quiet = true; arg_quiet = true;
if (arg_legend < 0)
arg_legend = false;
break; break;
case 'f': case 'f':
@ -721,7 +734,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
optarg); optarg);
if (OUTPUT_MODE_IS_JSON(arg_output)) { if (OUTPUT_MODE_IS_JSON(arg_output)) {
arg_no_legend = true; arg_legend = false;
arg_plain = true; arg_plain = true;
} }
break; break;

View File

@ -52,7 +52,7 @@ extern const char *arg_job_mode;
extern UnitFileScope arg_scope; extern UnitFileScope arg_scope;
extern bool arg_wait; extern bool arg_wait;
extern bool arg_no_block; extern bool arg_no_block;
extern bool arg_no_legend; extern int arg_legend;
extern PagerFlags arg_pager_flags; extern PagerFlags arg_pager_flags;
extern bool arg_no_wtmp; extern bool arg_no_wtmp;
extern bool arg_no_sync; extern bool arg_no_sync;

View File

@ -1,6 +1,4 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */ /* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <arpa/inet.h>
#include <stdlib.h>
#include "firewall-util.h" #include "firewall-util.h"
#include "log.h" #include "log.h"
@ -8,32 +6,14 @@
#include "tests.h" #include "tests.h"
#define MAKE_IN_ADDR_UNION(a,b,c,d) (union in_addr_union) { .in.s_addr = htobe32((uint32_t) (a) << 24 | (uint32_t) (b) << 16 | (uint32_t) (c) << 8 | (uint32_t) (d))} #define MAKE_IN_ADDR_UNION(a,b,c,d) (union in_addr_union) { .in.s_addr = htobe32((uint32_t) (a) << 24 | (uint32_t) (b) << 16 | (uint32_t) (c) << 8 | (uint32_t) (d))}
#define MAKE_IN6_ADDR_UNION(str, u) assert_se(in_addr_from_string(AF_INET6, str, u) >= 0)
void nft_in6addr_to_range(const union in_addr_union *source, unsigned int prefixlen,
struct in6_addr *start, struct in6_addr *end);
static void make_in6_addr_union(const char *addr, union in_addr_union *u) {
assert_se(inet_pton(AF_INET6, addr, &u->in6) >= 0);
}
static bool test_in6_eq(const char *addr, const union in_addr_union *u) {
union in_addr_union tmp;
make_in6_addr_union(addr, &tmp);
return memcmp(&tmp.in6, &u->in6, sizeof(tmp.in6)) == 0;
}
static void assert_in6_eq(const union in_addr_union *a, const union in_addr_union *b) {
assert_se(memcmp(&a->in6, &b->in6, sizeof(a->in6)) == 0);
}
static void test_v6(FirewallContext **ctx) { static void test_v6(FirewallContext **ctx) {
union in_addr_union u = {}, u2 = {}; union in_addr_union u = {}, u2 = {};
uint8_t prefixlen; uint8_t prefixlen;
int r; int r;
make_in6_addr_union("dead::beef", &u); MAKE_IN6_ADDR_UNION("dead::beef", &u);
r = fw_add_masquerade(ctx, true, AF_INET6, &u, 128); r = fw_add_masquerade(ctx, true, AF_INET6, &u, 128);
if (r < 0) if (r < 0)
@ -55,7 +35,7 @@ static void test_v6(FirewallContext **ctx) {
if (r < 0) if (r < 0)
log_error_errno(r, "Failed to modify firewall: %m"); log_error_errno(r, "Failed to modify firewall: %m");
make_in6_addr_union("1c3::c01d", &u2); MAKE_IN6_ADDR_UNION("1c3::c01d", &u2);
r = fw_add_local_dnat(ctx, true, AF_INET6, IPPROTO_TCP, 4711, &u2, 815, &u); r = fw_add_local_dnat(ctx, true, AF_INET6, IPPROTO_TCP, 4711, &u2, 815, &u);
if (r < 0) if (r < 0)
log_error_errno(r, "Failed to modify firewall: %m"); log_error_errno(r, "Failed to modify firewall: %m");
@ -77,52 +57,6 @@ static void test_v6(FirewallContext **ctx) {
log_error_errno(r, "Failed to modify ipv6 firewall: %m"); log_error_errno(r, "Failed to modify ipv6 firewall: %m");
} }
static void test_v6_range(void) {
unsigned int prefixlen = 64;
union in_addr_union a, b, s;
make_in6_addr_union("dead:0:0:beef::", &s);
nft_in6addr_to_range(&s, prefixlen, &a.in6, &b.in6);
assert_in6_eq(&s, &a);
assert_se(test_in6_eq("dead:0:0:bef0::", &b));
make_in6_addr_union("2001::", &s);
prefixlen = 56;
nft_in6addr_to_range(&s, prefixlen, &a.in6, &b.in6);
assert_in6_eq(&s, &a);
assert_se(test_in6_eq("2001:0:0:0100::", &b));
prefixlen = 48;
nft_in6addr_to_range(&s, prefixlen, &a.in6, &b.in6);
assert_in6_eq(&s, &a);
assert_se(test_in6_eq("2001:0:0001::", &b));
prefixlen = 65;
nft_in6addr_to_range(&s, prefixlen, &a.in6, &b.in6);
assert_se(test_in6_eq("2001::", &a));
assert_se(test_in6_eq("2001::8000:0:0:0", &b));
prefixlen = 66;
nft_in6addr_to_range(&s, prefixlen, &a.in6, &b.in6);
assert_in6_eq(&s, &a);
assert_se(test_in6_eq("2001::4000:0:0:0", &b));
prefixlen = 127;
nft_in6addr_to_range(&s, prefixlen, &a.in6, &b.in6);
assert_in6_eq(&s, &a);
assert_se(test_in6_eq("2001::0002", &b));
make_in6_addr_union("dead:beef::1", &s);
prefixlen = 64;
nft_in6addr_to_range(&s, prefixlen, &a.in6, &b.in6);
assert_se(test_in6_eq("dead:beef::", &a));
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
_cleanup_(fw_ctx_freep) FirewallContext *ctx; _cleanup_(fw_ctx_freep) FirewallContext *ctx;
int r; int r;
@ -175,7 +109,6 @@ int main(int argc, char *argv[]) {
log_error_errno(r, "Failed to modify firewall: %m"); log_error_errno(r, "Failed to modify firewall: %m");
test_v6(&ctx); test_v6(&ctx);
test_v6_range();
return 0; return 0;
} }

View File

@ -238,10 +238,12 @@ static void test_in_addr_prefix_intersect(void) {
static void test_in_addr_prefix_next_one(unsigned f, const char *before, unsigned pl, const char *after) { static void test_in_addr_prefix_next_one(unsigned f, const char *before, unsigned pl, const char *after) {
union in_addr_union ubefore, uafter, t; union in_addr_union ubefore, uafter, t;
log_info("/* %s(%s, prefixlen=%u) */", __func__, before, pl);
assert_se(in_addr_from_string(f, before, &ubefore) >= 0); assert_se(in_addr_from_string(f, before, &ubefore) >= 0);
t = ubefore; t = ubefore;
assert_se((in_addr_prefix_next(f, &t, pl) > 0) == !!after); assert_se((in_addr_prefix_next(f, &t, pl) >= 0) == !!after);
if (after) { if (after) {
assert_se(in_addr_from_string(f, after, &uafter) >= 0); assert_se(in_addr_from_string(f, after, &uafter) >= 0);
@ -250,13 +252,12 @@ static void test_in_addr_prefix_next_one(unsigned f, const char *before, unsigne
} }
static void test_in_addr_prefix_next(void) { static void test_in_addr_prefix_next(void) {
log_info("/* %s */", __func__);
test_in_addr_prefix_next_one(AF_INET, "192.168.0.0", 24, "192.168.1.0"); test_in_addr_prefix_next_one(AF_INET, "192.168.0.0", 24, "192.168.1.0");
test_in_addr_prefix_next_one(AF_INET, "192.168.0.0", 16, "192.169.0.0"); test_in_addr_prefix_next_one(AF_INET, "192.168.0.0", 16, "192.169.0.0");
test_in_addr_prefix_next_one(AF_INET, "192.168.0.0", 20, "192.168.16.0"); test_in_addr_prefix_next_one(AF_INET, "192.168.0.0", 20, "192.168.16.0");
test_in_addr_prefix_next_one(AF_INET, "0.0.0.0", 32, "0.0.0.1"); test_in_addr_prefix_next_one(AF_INET, "0.0.0.0", 32, "0.0.0.1");
test_in_addr_prefix_next_one(AF_INET, "255.255.255.254", 32, "255.255.255.255");
test_in_addr_prefix_next_one(AF_INET, "255.255.255.255", 32, NULL); test_in_addr_prefix_next_one(AF_INET, "255.255.255.255", 32, NULL);
test_in_addr_prefix_next_one(AF_INET, "255.255.255.0", 24, NULL); test_in_addr_prefix_next_one(AF_INET, "255.255.255.0", 24, NULL);
@ -275,10 +276,12 @@ static void test_in_addr_prefix_next(void) {
static void test_in_addr_prefix_nth_one(unsigned f, const char *before, unsigned pl, uint64_t nth, const char *after) { static void test_in_addr_prefix_nth_one(unsigned f, const char *before, unsigned pl, uint64_t nth, const char *after) {
union in_addr_union ubefore, uafter, t; union in_addr_union ubefore, uafter, t;
log_info("/* %s(%s, prefixlen=%u, nth=%"PRIu64") */", __func__, before, pl, nth);
assert_se(in_addr_from_string(f, before, &ubefore) >= 0); assert_se(in_addr_from_string(f, before, &ubefore) >= 0);
t = ubefore; t = ubefore;
assert_se((in_addr_prefix_nth(f, &t, pl, nth) > 0) == !!after); assert_se((in_addr_prefix_nth(f, &t, pl, nth) >= 0) == !!after);
if (after) { if (after) {
assert_se(in_addr_from_string(f, after, &uafter) >= 0); assert_se(in_addr_from_string(f, after, &uafter) >= 0);
@ -287,10 +290,9 @@ static void test_in_addr_prefix_nth_one(unsigned f, const char *before, unsigned
} }
static void test_in_addr_prefix_nth(void) { static void test_in_addr_prefix_nth(void) {
log_info("/* %s */", __func__);
test_in_addr_prefix_nth_one(AF_INET, "192.168.0.0", 24, 0, "192.168.0.0"); test_in_addr_prefix_nth_one(AF_INET, "192.168.0.0", 24, 0, "192.168.0.0");
test_in_addr_prefix_nth_one(AF_INET, "192.168.0.0", 24, 1, "192.168.1.0"); test_in_addr_prefix_nth_one(AF_INET, "192.168.0.123", 24, 0, "192.168.0.0");
test_in_addr_prefix_nth_one(AF_INET, "192.168.0.123", 24, 1, "192.168.1.0");
test_in_addr_prefix_nth_one(AF_INET, "192.168.0.0", 24, 4, "192.168.4.0"); test_in_addr_prefix_nth_one(AF_INET, "192.168.0.0", 24, 4, "192.168.4.0");
test_in_addr_prefix_nth_one(AF_INET, "192.168.0.0", 25, 1, "192.168.0.128"); test_in_addr_prefix_nth_one(AF_INET, "192.168.0.0", 25, 1, "192.168.0.128");
test_in_addr_prefix_nth_one(AF_INET, "192.168.255.0", 25, 1, "192.168.255.128"); test_in_addr_prefix_nth_one(AF_INET, "192.168.255.0", 25, 1, "192.168.255.128");
@ -309,6 +311,48 @@ static void test_in_addr_prefix_nth(void) {
test_in_addr_prefix_nth_one(AF_INET6, "0000::", 8, 256, NULL); test_in_addr_prefix_nth_one(AF_INET6, "0000::", 8, 256, NULL);
test_in_addr_prefix_nth_one(AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 128, 1, NULL); test_in_addr_prefix_nth_one(AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 128, 1, NULL);
test_in_addr_prefix_nth_one(AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0, 1, NULL); test_in_addr_prefix_nth_one(AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0, 1, NULL);
test_in_addr_prefix_nth_one(AF_INET6, "1234:5678:90ab:cdef:1234:5678:90ab:cdef", 12, 1, "1240::");
}
static void test_in_addr_prefix_range_one(
int family,
const char *in,
unsigned prefixlen,
const char *expected_start,
const char *expected_end) {
union in_addr_union a, s, e;
log_info("/* %s(%s, prefixlen=%u) */", __func__, in, prefixlen);
assert_se(in_addr_from_string(family, in, &a) >= 0);
assert_se((in_addr_prefix_range(family, &a, prefixlen, &s, &e) >= 0) == !!expected_start);
if (expected_start) {
union in_addr_union es;
assert_se(in_addr_from_string(family, expected_start, &es) >= 0);
assert_se(in_addr_equal(family, &s, &es) > 0);
}
if (expected_end) {
union in_addr_union ee;
assert_se(in_addr_from_string(family, expected_end, &ee) >= 0);
assert_se(in_addr_equal(family, &e, &ee) > 0);
}
}
static void test_in_addr_prefix_range(void) {
test_in_addr_prefix_range_one(AF_INET, "192.168.123.123", 24, "192.168.123.0", "192.168.124.0");
test_in_addr_prefix_range_one(AF_INET, "192.168.123.123", 16, "192.168.0.0", "192.169.0.0");
test_in_addr_prefix_range_one(AF_INET6, "dead:beef::", 64, "dead:beef::", "dead:beef:0:1::");
test_in_addr_prefix_range_one(AF_INET6, "dead:0:0:beef::", 64, "dead:0:0:beef::", "dead:0:0:bef0::");
test_in_addr_prefix_range_one(AF_INET6, "2001::", 48, "2001::", "2001:0:1::");
test_in_addr_prefix_range_one(AF_INET6, "2001::", 56, "2001::", "2001:0:0:0100::");
test_in_addr_prefix_range_one(AF_INET6, "2001::", 65, "2001::", "2001::8000:0:0:0");
test_in_addr_prefix_range_one(AF_INET6, "2001::", 66, "2001::", "2001::4000:0:0:0");
test_in_addr_prefix_range_one(AF_INET6, "2001::", 127, "2001::", "2001::2");
} }
static void test_in_addr_to_string_one(int f, const char *addr) { static void test_in_addr_to_string_one(int f, const char *addr) {
@ -339,6 +383,7 @@ int main(int argc, char *argv[]) {
test_in_addr_prefix_intersect(); test_in_addr_prefix_intersect();
test_in_addr_prefix_next(); test_in_addr_prefix_next();
test_in_addr_prefix_nth(); test_in_addr_prefix_nth();
test_in_addr_prefix_range();
test_in_addr_to_string(); test_in_addr_to_string();
return 0; return 0;

View File

@ -55,7 +55,7 @@ static void test_basic_mask_and_enable(const char *root) {
assert_se(unit_file_mask(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0); assert_se(unit_file_mask(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1); assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/dev/null")); assert_se(streq(changes[0].source, "/dev/null"));
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/a.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/a.service");
assert_se(streq(changes[0].path, p)); assert_se(streq(changes[0].path, p));
@ -75,7 +75,7 @@ static void test_basic_mask_and_enable(const char *root) {
assert_se(unit_file_unmask(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0); assert_se(unit_file_unmask(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1); assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_UNLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_UNLINK);
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/a.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/a.service");
assert_se(streq(changes[0].path, p)); assert_se(streq(changes[0].path, p));
unit_file_changes_free(changes, n_changes); unit_file_changes_free(changes, n_changes);
@ -83,7 +83,7 @@ static void test_basic_mask_and_enable(const char *root) {
assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) == 1); assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) == 1);
assert_se(n_changes == 1); assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/a.service")); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/a.service"));
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/a.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/a.service");
assert_se(streq(changes[0].path, p)); assert_se(streq(changes[0].path, p));
@ -103,7 +103,7 @@ static void test_basic_mask_and_enable(const char *root) {
assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0); assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("a.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1); assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_UNLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_UNLINK);
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/a.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/a.service");
assert_se(streq(changes[0].path, p)); assert_se(streq(changes[0].path, p));
unit_file_changes_free(changes, n_changes); unit_file_changes_free(changes, n_changes);
@ -123,7 +123,7 @@ static void test_basic_mask_and_enable(const char *root) {
/* Let's enable this indirectly via a symlink */ /* Let's enable this indirectly via a symlink */
assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("d.service"), &changes, &n_changes) >= 0); assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("d.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1); assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/a.service")); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/a.service"));
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/a.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/a.service");
assert_se(streq(changes[0].path, p)); assert_se(streq(changes[0].path, p));
@ -139,10 +139,10 @@ static void test_basic_mask_and_enable(const char *root) {
assert_se(unit_file_reenable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("b.service"), &changes, &n_changes) >= 0); assert_se(unit_file_reenable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("b.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 2); assert_se(n_changes == 2);
assert_se(changes[0].type == UNIT_FILE_UNLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_UNLINK);
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/a.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/a.service");
assert_se(streq(changes[0].path, p)); assert_se(streq(changes[0].path, p));
assert_se(changes[1].type == UNIT_FILE_SYMLINK); assert_se(changes[1].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(streq(changes[1].source, "/usr/lib/systemd/system/a.service")); assert_se(streq(changes[1].source, "/usr/lib/systemd/system/a.service"));
assert_se(streq(changes[1].path, p)); assert_se(streq(changes[1].path, p));
unit_file_changes_free(changes, n_changes); unit_file_changes_free(changes, n_changes);
@ -224,7 +224,7 @@ static void test_linked_units(const char *root) {
/* First, let's link the unit into the search path */ /* First, let's link the unit into the search path */
assert_se(unit_file_link(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("/opt/linked.service"), &changes, &n_changes) >= 0); assert_se(unit_file_link(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("/opt/linked.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1); assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/opt/linked.service")); assert_se(streq(changes[0].source, "/opt/linked.service"));
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/linked.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/linked.service");
assert_se(streq(changes[0].path, p)); assert_se(streq(changes[0].path, p));
@ -236,7 +236,7 @@ static void test_linked_units(const char *root) {
/* Let's unlink it from the search path again */ /* Let's unlink it from the search path again */
assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked.service"), &changes, &n_changes) >= 0); assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1); assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_UNLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_UNLINK);
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/linked.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/linked.service");
assert_se(streq(changes[0].path, p)); assert_se(streq(changes[0].path, p));
unit_file_changes_free(changes, n_changes); unit_file_changes_free(changes, n_changes);
@ -250,7 +250,7 @@ static void test_linked_units(const char *root) {
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/linked.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/linked.service");
q = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/linked.service"); q = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/linked.service");
for (i = 0 ; i < n_changes; i++) { for (i = 0 ; i < n_changes; i++) {
assert_se(changes[i].type == UNIT_FILE_SYMLINK); assert_se(changes[i].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(streq(changes[i].source, "/opt/linked.service")); assert_se(streq(changes[i].source, "/opt/linked.service"));
if (p && streq(changes[i].path, p)) if (p && streq(changes[i].path, p))
@ -272,7 +272,7 @@ static void test_linked_units(const char *root) {
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/linked.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/linked.service");
q = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/linked.service"); q = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/linked.service");
for (i = 0; i < n_changes; i++) { for (i = 0; i < n_changes; i++) {
assert_se(changes[i].type == UNIT_FILE_UNLINK); assert_se(changes[i].type_or_errno == UNIT_FILE_UNLINK);
if (p && streq(changes[i].path, p)) if (p && streq(changes[i].path, p))
p = NULL; p = NULL;
@ -292,7 +292,7 @@ static void test_linked_units(const char *root) {
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/linked2.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/linked2.service");
q = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/linked2.service"); q = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/linked2.service");
for (i = 0 ; i < n_changes; i++) { for (i = 0 ; i < n_changes; i++) {
assert_se(changes[i].type == UNIT_FILE_SYMLINK); assert_se(changes[i].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(streq(changes[i].source, "/opt/linked2.service")); assert_se(streq(changes[i].source, "/opt/linked2.service"));
if (p && streq(changes[i].path, p)) if (p && streq(changes[i].path, p))
@ -308,7 +308,7 @@ static void test_linked_units(const char *root) {
assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked3.service"), &changes, &n_changes) >= 0); assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked3.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1); assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(startswith(changes[0].path, root)); assert_se(startswith(changes[0].path, root));
assert_se(endswith(changes[0].path, "linked3.service")); assert_se(endswith(changes[0].path, "linked3.service"));
assert_se(streq(changes[0].source, "/opt/linked3.service")); assert_se(streq(changes[0].source, "/opt/linked3.service"));
@ -332,7 +332,7 @@ static void test_default(const char *root) {
assert_se(unit_file_set_default(UNIT_FILE_SYSTEM, 0, root, "idontexist.target", &changes, &n_changes) == -ENOENT); assert_se(unit_file_set_default(UNIT_FILE_SYSTEM, 0, root, "idontexist.target", &changes, &n_changes) == -ENOENT);
assert_se(n_changes == 1); assert_se(n_changes == 1);
assert_se(changes[0].type == -ENOENT); assert_se(changes[0].type_or_errno == -ENOENT);
assert_se(streq_ptr(changes[0].path, "idontexist.target")); assert_se(streq_ptr(changes[0].path, "idontexist.target"));
unit_file_changes_free(changes, n_changes); unit_file_changes_free(changes, n_changes);
changes = NULL; n_changes = 0; changes = NULL; n_changes = 0;
@ -341,7 +341,7 @@ static void test_default(const char *root) {
assert_se(unit_file_set_default(UNIT_FILE_SYSTEM, 0, root, "test-default.target", &changes, &n_changes) >= 0); assert_se(unit_file_set_default(UNIT_FILE_SYSTEM, 0, root, "test-default.target", &changes, &n_changes) >= 0);
assert_se(n_changes == 1); assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/test-default-real.target")); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/test-default-real.target"));
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR "/" SPECIAL_DEFAULT_TARGET); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR "/" SPECIAL_DEFAULT_TARGET);
assert_se(streq(changes[0].path, p)); assert_se(streq(changes[0].path, p));
@ -371,7 +371,7 @@ static void test_add_dependency(const char *root) {
assert_se(unit_file_add_dependency(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("add-dependency-test-service.service"), "add-dependency-test-target.target", UNIT_WANTS, &changes, &n_changes) >= 0); assert_se(unit_file_add_dependency(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("add-dependency-test-service.service"), "add-dependency-test-target.target", UNIT_WANTS, &changes, &n_changes) >= 0);
assert_se(n_changes == 1); assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/real-add-dependency-test-service.service")); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/real-add-dependency-test-service.service"));
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/real-add-dependency-test-target.target.wants/real-add-dependency-test-service.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/real-add-dependency-test-target.target.wants/real-add-dependency-test-service.service");
assert_se(streq(changes[0].path, p)); assert_se(streq(changes[0].path, p));
@ -412,7 +412,7 @@ static void test_template_enable(const char *root) {
assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template@.service"), &changes, &n_changes) >= 0); assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template@.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1); assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/template@.service")); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/template@.service"));
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/template@def.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/template@def.service");
assert_se(streq(changes[0].path, p)); assert_se(streq(changes[0].path, p));
@ -428,7 +428,7 @@ static void test_template_enable(const char *root) {
assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template@.service"), &changes, &n_changes) >= 0); assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template@.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1); assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_UNLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_UNLINK);
assert_se(streq(changes[0].path, p)); assert_se(streq(changes[0].path, p));
unit_file_changes_free(changes, n_changes); unit_file_changes_free(changes, n_changes);
changes = NULL; n_changes = 0; changes = NULL; n_changes = 0;
@ -443,7 +443,7 @@ static void test_template_enable(const char *root) {
log_info("== %s with template@foo.service enabled ==", __func__); log_info("== %s with template@foo.service enabled ==", __func__);
assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template@foo.service"), &changes, &n_changes) >= 0); assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template@foo.service"), &changes, &n_changes) >= 0);
assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/template@.service")); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/template@.service"));
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/template@foo.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/template@foo.service");
assert_se(streq(changes[0].path, p)); assert_se(streq(changes[0].path, p));
@ -459,7 +459,7 @@ static void test_template_enable(const char *root) {
assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template@foo.service"), &changes, &n_changes) >= 0); assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template@foo.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1); assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_UNLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_UNLINK);
assert_se(streq(changes[0].path, p)); assert_se(streq(changes[0].path, p));
unit_file_changes_free(changes, n_changes); unit_file_changes_free(changes, n_changes);
changes = NULL; n_changes = 0; changes = NULL; n_changes = 0;
@ -476,7 +476,7 @@ static void test_template_enable(const char *root) {
log_info("== %s with template-symlink@quux.service enabled ==", __func__); log_info("== %s with template-symlink@quux.service enabled ==", __func__);
assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template-symlink@quux.service"), &changes, &n_changes) >= 0); assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("template-symlink@quux.service"), &changes, &n_changes) >= 0);
assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/template@.service")); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/template@.service"));
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/template@quux.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/template@quux.service");
assert_se(streq(changes[0].path, p)); assert_se(streq(changes[0].path, p));
@ -522,7 +522,7 @@ static void test_indirect(const char *root) {
assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("indirectc.service"), &changes, &n_changes) >= 0); assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("indirectc.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1); assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/indirectb.service")); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/indirectb.service"));
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/indirectb.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/indirectb.service");
assert_se(streq(changes[0].path, p)); assert_se(streq(changes[0].path, p));
@ -535,7 +535,7 @@ static void test_indirect(const char *root) {
assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("indirectc.service"), &changes, &n_changes) >= 0); assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("indirectc.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1); assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_UNLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_UNLINK);
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/indirectb.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/indirectb.service");
assert_se(streq(changes[0].path, p)); assert_se(streq(changes[0].path, p));
unit_file_changes_free(changes, n_changes); unit_file_changes_free(changes, n_changes);
@ -574,7 +574,7 @@ static void test_preset_and_list(const char *root) {
assert_se(unit_file_preset(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("preset-yes.service"), UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0); assert_se(unit_file_preset(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("preset-yes.service"), UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0);
assert_se(n_changes == 1); assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/preset-yes.service")); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/preset-yes.service"));
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/preset-yes.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/preset-yes.service");
assert_se(streq(changes[0].path, p)); assert_se(streq(changes[0].path, p));
@ -586,7 +586,7 @@ static void test_preset_and_list(const char *root) {
assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("preset-yes.service"), &changes, &n_changes) >= 0); assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("preset-yes.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1); assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_UNLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_UNLINK);
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/preset-yes.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/preset-yes.service");
assert_se(streq(changes[0].path, p)); assert_se(streq(changes[0].path, p));
unit_file_changes_free(changes, n_changes); unit_file_changes_free(changes, n_changes);
@ -611,11 +611,11 @@ static void test_preset_and_list(const char *root) {
for (i = 0; i < n_changes; i++) { for (i = 0; i < n_changes; i++) {
if (changes[i].type == UNIT_FILE_SYMLINK) { if (changes[i].type_or_errno == UNIT_FILE_SYMLINK) {
assert_se(streq(changes[i].source, "/usr/lib/systemd/system/preset-yes.service")); assert_se(streq(changes[i].source, "/usr/lib/systemd/system/preset-yes.service"));
assert_se(streq(changes[i].path, p)); assert_se(streq(changes[i].path, p));
} else } else
assert_se(changes[i].type == UNIT_FILE_UNLINK); assert_se(changes[i].type_or_errno == UNIT_FILE_UNLINK);
} }
unit_file_changes_free(changes, n_changes); unit_file_changes_free(changes, n_changes);
@ -678,7 +678,7 @@ static void test_revert(const char *root) {
/* Revert the override file */ /* Revert the override file */
assert_se(unit_file_revert(UNIT_FILE_SYSTEM, root, STRV_MAKE("xx.service"), &changes, &n_changes) >= 0); assert_se(unit_file_revert(UNIT_FILE_SYSTEM, root, STRV_MAKE("xx.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1); assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_UNLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_UNLINK);
assert_se(streq(changes[0].path, p)); assert_se(streq(changes[0].path, p));
unit_file_changes_free(changes, n_changes); unit_file_changes_free(changes, n_changes);
changes = NULL; n_changes = 0; changes = NULL; n_changes = 0;
@ -690,11 +690,11 @@ static void test_revert(const char *root) {
/* Revert the dropin file */ /* Revert the dropin file */
assert_se(unit_file_revert(UNIT_FILE_SYSTEM, root, STRV_MAKE("xx.service"), &changes, &n_changes) >= 0); assert_se(unit_file_revert(UNIT_FILE_SYSTEM, root, STRV_MAKE("xx.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 2); assert_se(n_changes == 2);
assert_se(changes[0].type == UNIT_FILE_UNLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_UNLINK);
assert_se(streq(changes[0].path, p)); assert_se(streq(changes[0].path, p));
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/xx.service.d"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/xx.service.d");
assert_se(changes[1].type == UNIT_FILE_UNLINK); assert_se(changes[1].type_or_errno == UNIT_FILE_UNLINK);
assert_se(streq(changes[1].path, p)); assert_se(streq(changes[1].path, p));
unit_file_changes_free(changes, n_changes); unit_file_changes_free(changes, n_changes);
changes = NULL; n_changes = 0; changes = NULL; n_changes = 0;
@ -730,7 +730,7 @@ static void test_preset_order(const char *root) {
assert_se(unit_file_preset(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("prefix-1.service"), UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0); assert_se(unit_file_preset(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("prefix-1.service"), UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0);
assert_se(n_changes == 1); assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/prefix-1.service")); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/prefix-1.service"));
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/prefix-1.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/prefix-1.service");
assert_se(streq(changes[0].path, p)); assert_se(streq(changes[0].path, p));
@ -842,8 +842,8 @@ static void test_with_dropin(const char *root) {
assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-1.service"), &changes, &n_changes) == 1); assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-1.service"), &changes, &n_changes) == 1);
assert_se(n_changes == 2); assert_se(n_changes == 2);
assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(changes[1].type == UNIT_FILE_SYMLINK); assert_se(changes[1].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-1.service")); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-1.service"));
assert_se(streq(changes[1].source, "/usr/lib/systemd/system/with-dropin-1.service")); assert_se(streq(changes[1].source, "/usr/lib/systemd/system/with-dropin-1.service"));
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/with-dropin-1.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/with-dropin-1.service");
@ -856,8 +856,8 @@ static void test_with_dropin(const char *root) {
assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-2.service"), &changes, &n_changes) == 1); assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-2.service"), &changes, &n_changes) == 1);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-2.service", &state) >= 0 && state == UNIT_FILE_ENABLED); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-2.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(n_changes == 2); assert_se(n_changes == 2);
assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(changes[1].type == UNIT_FILE_SYMLINK); assert_se(changes[1].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, SYSTEM_CONFIG_UNIT_DIR"/with-dropin-2.service")); assert_se(streq(changes[0].source, SYSTEM_CONFIG_UNIT_DIR"/with-dropin-2.service"));
assert_se(streq(changes[1].source, SYSTEM_CONFIG_UNIT_DIR"/with-dropin-2.service")); assert_se(streq(changes[1].source, SYSTEM_CONFIG_UNIT_DIR"/with-dropin-2.service"));
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/with-dropin-2.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/with-dropin-2.service");
@ -870,8 +870,8 @@ static void test_with_dropin(const char *root) {
assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-3.service"), &changes, &n_changes) == 1); assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-3.service"), &changes, &n_changes) == 1);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-3.service", &state) >= 0 && state == UNIT_FILE_ENABLED); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-3.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(n_changes == 2); assert_se(n_changes == 2);
assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(changes[1].type == UNIT_FILE_SYMLINK); assert_se(changes[1].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-3.service")); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-3.service"));
assert_se(streq(changes[1].source, "/usr/lib/systemd/system/with-dropin-3.service")); assert_se(streq(changes[1].source, "/usr/lib/systemd/system/with-dropin-3.service"));
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/with-dropin-3.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/with-dropin-3.service");
@ -884,8 +884,8 @@ static void test_with_dropin(const char *root) {
assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-4a.service"), &changes, &n_changes) == 2); assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-4a.service"), &changes, &n_changes) == 2);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-3.service", &state) >= 0 && state == UNIT_FILE_ENABLED); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "with-dropin-3.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(n_changes == 2); assert_se(n_changes == 2);
assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(changes[1].type == UNIT_FILE_SYMLINK); assert_se(changes[1].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-4a.service")); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-4a.service"));
assert_se(streq(changes[1].source, "/usr/lib/systemd/system/with-dropin-4b.service")); assert_se(streq(changes[1].source, "/usr/lib/systemd/system/with-dropin-4b.service"));
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/with-dropin-4a.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/with-dropin-4a.service");
@ -954,8 +954,8 @@ static void test_with_dropin_template(const char *root) {
assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-1@instance-1.service"), &changes, &n_changes) == 1); assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-1@instance-1.service"), &changes, &n_changes) == 1);
assert_se(n_changes == 2); assert_se(n_changes == 2);
assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(changes[1].type == UNIT_FILE_SYMLINK); assert_se(changes[1].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-1@.service")); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-1@.service"));
assert_se(streq(changes[1].source, "/usr/lib/systemd/system/with-dropin-1@.service")); assert_se(streq(changes[1].source, "/usr/lib/systemd/system/with-dropin-1@.service"));
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/with-dropin-1@instance-1.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/with-dropin-1@instance-1.service");
@ -967,8 +967,8 @@ static void test_with_dropin_template(const char *root) {
assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-2@instance-1.service"), &changes, &n_changes) == 1); assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-2@instance-1.service"), &changes, &n_changes) == 1);
assert_se(n_changes == 2); assert_se(n_changes == 2);
assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(changes[1].type == UNIT_FILE_SYMLINK); assert_se(changes[1].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-2@.service")); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-2@.service"));
assert_se(streq(changes[1].source, "/usr/lib/systemd/system/with-dropin-2@.service")); assert_se(streq(changes[1].source, "/usr/lib/systemd/system/with-dropin-2@.service"));
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/with-dropin-2@instance-1.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/with-dropin-2@instance-1.service");
@ -980,7 +980,7 @@ static void test_with_dropin_template(const char *root) {
assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-2@instance-2.service"), &changes, &n_changes) == 1); assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-2@instance-2.service"), &changes, &n_changes) == 1);
assert_se(n_changes == 1); assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-2@.service")); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-2@.service"));
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/with-dropin-2@instance-2.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/with-dropin-2@instance-2.service");
assert_se(streq(changes[0].path, p)); assert_se(streq(changes[0].path, p));
@ -989,7 +989,7 @@ static void test_with_dropin_template(const char *root) {
assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-3@.service"), &changes, &n_changes) == 1); assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("with-dropin-3@.service"), &changes, &n_changes) == 1);
assert_se(n_changes == 1); assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_SYMLINK);
assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-3@.service")); assert_se(streq(changes[0].source, "/usr/lib/systemd/system/with-dropin-3@.service"));
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/with-dropin-3@instance-2.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/with-dropin-3@instance-2.service");
assert_se(streq(changes[0].path, p)); assert_se(streq(changes[0].path, p));
@ -1030,7 +1030,7 @@ static void test_preset_multiple_instances(const char *root) {
assert_se(unit_file_preset(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("foo@bar0.service"), UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0); assert_se(unit_file_preset(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("foo@bar0.service"), UNIT_FILE_PRESET_FULL, &changes, &n_changes) >= 0);
assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@bar0.service", &state) >= 0 && state == UNIT_FILE_ENABLED); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "foo@bar0.service", &state) >= 0 && state == UNIT_FILE_ENABLED);
assert_se(n_changes == 1); assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_SYMLINK);
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/foo@bar0.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/foo@bar0.service");
assert_se(streq(changes[0].path, p)); assert_se(streq(changes[0].path, p));
unit_file_changes_free(changes, n_changes); unit_file_changes_free(changes, n_changes);
@ -1038,7 +1038,7 @@ static void test_preset_multiple_instances(const char *root) {
assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("foo@bar0.service"), &changes, &n_changes) >= 0); assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("foo@bar0.service"), &changes, &n_changes) >= 0);
assert_se(n_changes == 1); assert_se(n_changes == 1);
assert_se(changes[0].type == UNIT_FILE_UNLINK); assert_se(changes[0].type_or_errno == UNIT_FILE_UNLINK);
p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/foo@bar0.service"); p = strjoina(root, SYSTEM_CONFIG_UNIT_DIR"/multi-user.target.wants/foo@bar0.service");
assert_se(streq(changes[0].path, p)); assert_se(streq(changes[0].path, p));
unit_file_changes_free(changes, n_changes); unit_file_changes_free(changes, n_changes);

View File

@ -12,9 +12,9 @@ static void dump_changes(UnitFileChange *c, unsigned n) {
assert_se(n == 0 || c); assert_se(n == 0 || c);
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
if (c[i].type == UNIT_FILE_UNLINK) if (c[i].type_or_errno == UNIT_FILE_UNLINK)
printf("rm '%s'\n", c[i].path); printf("rm '%s'\n", c[i].path);
else if (c[i].type == UNIT_FILE_SYMLINK) else if (c[i].type_or_errno == UNIT_FILE_SYMLINK)
printf("ln -s '%s' '%s'\n", c[i].source, c[i].path); printf("ln -s '%s' '%s'\n", c[i].source, c[i].path);
} }
} }

View File

@ -10,6 +10,7 @@
#include "format-util.h" #include "format-util.h"
#include "main-func.h" #include "main-func.h"
#include "pager.h" #include "pager.h"
#include "parse-argument.h"
#include "parse-util.h" #include "parse-util.h"
#include "pretty-print.h" #include "pretty-print.h"
#include "socket-util.h" #include "socket-util.h"
@ -720,17 +721,17 @@ static int parse_argv(int argc, char *argv[]) {
break; break;
case ARG_WITH_NSS: case ARG_WITH_NSS:
r = parse_boolean(optarg); r = parse_boolean_argument("--with-nss=", optarg, NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --with-nss= parameter: %s", optarg); return r;
SET_FLAG(arg_userdb_flags, USERDB_AVOID_NSS, !r); SET_FLAG(arg_userdb_flags, USERDB_AVOID_NSS, !r);
break; break;
case ARG_SYNTHESIZE: case ARG_SYNTHESIZE:
r = parse_boolean(optarg); r = parse_boolean_argument("--synthesize=", optarg, NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to parse --synthesize= parameter: %s", optarg); return r;
SET_FLAG(arg_userdb_flags, USERDB_DONT_SYNTHESIZE, !r); SET_FLAG(arg_userdb_flags, USERDB_DONT_SYNTHESIZE, !r);
break; break;

View File

@ -2320,11 +2320,15 @@ do_test() {
--all) --all)
ret=0 ret=0
echo -n "${testname}: $TEST_DESCRIPTION " echo -n "${testname}: $TEST_DESCRIPTION "
( # Do not use a subshell, otherwise cleanup variables (LOOPDEV) will be lost
test_setup # and loop devices will leak
test_setup_cleanup test_setup </dev/null >"$TESTLOG" 2>&1 || ret=$?
test_run "$2" if [ $ret -eq 0 ]; then
) </dev/null >"$TESTLOG" 2>&1 || ret=$? test_setup_cleanup </dev/null >>"$TESTLOG" 2>&1 || ret=$?
fi
if [ $ret -eq 0 ]; then
test_run "$2" </dev/null >>"$TESTLOG" 2>&1 || ret=$?
fi
test_cleanup test_cleanup
if [ $ret -eq 0 ]; then if [ $ret -eq 0 ]; then
rm "$TESTLOG" rm "$TESTLOG"