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

Compare commits

..

25 Commits

Author SHA1 Message Date
Lennart Poettering
347d8a2889
Merge pull request #19381 from poettering/generator-tweaks
generator: two minor tweaks
2021-04-21 18:33:05 +02:00
Lennart Poettering
2b66f48e4e generator: write out special systemd-fsck-usr.service
So far all file systems where checked by instances of
systemd-fsck@.service, with the exception of the root fs which was
covered by systemd-fsck-root.service. The special handling is necessary
to deal with ordering issues: we typically want the root fs to be
checked before all others, and — weirdly — allow mounting it before the
fsck done (for compat with initrd-less boots).

This adds similar special handling for /usr: if the hierarchy is placed
on a separate file system check it with a special
systemd-fsck-usr.service instead of a regular sysemd-fsck@.service
instance. Reason is again ordering: we want to allow mounting of /usr
without the root fs already being around in the initrd, to cover for
cases where the root fs is created on first boot and thus cannot be
mounted/checked before /usr.
2021-04-21 18:32:29 +02:00
Zbigniew Jędrzejewski-Szmek
1f2a7ca7ac
Merge pull request #19362 from yuwata/network-dhcp6-pd-log-19354
network: dhcp6: add logs about delegated prefix
2021-04-21 18:20:49 +02:00
Zbigniew Jędrzejewski-Szmek
59ab650fc5
Merge pull request #19370 from mrc0mmand/shellcheck-pt4
More shellcheck shenanigans
2021-04-21 18:14:32 +02:00
Yangyang Shen
80e9720616 journald: enforce longer line length limit during "setup" phase of stream protocol
This PR made modification on Lennart Poettering's basis. Fix the LineMax's function failure problem.

Signed-off-by: Yangyang Shen <shenyangyang4@huawei.com>
2021-04-21 17:22:24 +02:00
Lennart Poettering
599aee40a3 generator: explain why systemd-root-fsck.service exists in a comment 2021-04-21 15:18:07 +02:00
Lennart Poettering
122860f102 generator: exit early when asked to generate fsck unit for / and /usr in initrd
Let's exit early if we are invoked to generate an fsck unit for the
rootfs or /usr of the initrd itself. The "systemd-root-fsck.service" and
"systemd-usr-fsck.service" units are after all for the host file
systems, and the initrd file hierarchy is from an unpacked cpio anyway.
Hence, this semantically doesn't really make sense, so quickly exit if
we detect this case. This allows us to remove some checks further down
the codepath.
2021-04-21 15:18:07 +02:00
Yu Watanabe
b67bbfef14
Merge pull request #19344 from yuwata/network-route-metric-19028
network: add RouteMetric= setting in [Address] and more
2021-04-21 20:51:31 +09:00
Lennart Poettering
2671fbefce units: fix repart conditions to run if definitions exist in /sysroot + /sysusr
The systemd-repart code was already smart enough to look for definitions
there, but the unit file conditions made that pointless. Let's fix that.
2021-04-21 12:23:31 +01:00
Yu Watanabe
baad6421b1 network: dhcp6: logs about generated addresses in delegated prefix 2021-04-21 14:04:39 +09:00
Yu Watanabe
4b409e855b network: dhcp6: logs about delegated prefixes
Closes #19354.
2021-04-21 14:04:33 +09:00
Yu Watanabe
eccdc68771 in-addr-util: introduce 'struct in_addr_prefix' and hash ops for it 2021-04-21 13:57:47 +09:00
Yu Watanabe
93e44aa92f in-addr-util: add assertions 2021-04-21 13:57:47 +09:00
Yu Watanabe
3e726c156b test-network: update test for RouteMetric= 2021-04-21 13:55:02 +09:00
Yu Watanabe
4c0aae015f man: update explanation about route metric 2021-04-21 13:55:02 +09:00
Yu Watanabe
b3cde1c3f5 network: set metric for prefix route of IPv4 link-local address 2021-04-21 13:55:02 +09:00
Yu Watanabe
0e1fb1d09a network: radv: add RouteMetric= setting in [IPv6Prefix] 2021-04-21 13:55:02 +09:00
Yu Watanabe
9fe0b7b493 network: dhcp6-pd: add RouteMetric= setting in [DHCPv6PrefixDelegation] 2021-04-21 13:55:02 +09:00
Yu Watanabe
8ebafba9f9 network: move RouteMetric= from [DHCPv6] to [IPv6AcceptRA]
As the value is used in the routes in RA.
2021-04-21 13:55:02 +09:00
Yu Watanabe
415deef9c3 network: dhcp4: also apply RouteMetric= setting in [DHCPv4] to prefix route 2021-04-21 13:55:02 +09:00
Yu Watanabe
c4ff0629dd network: add RouteMetric= setting in [Address] section 2021-04-21 13:54:59 +09:00
Yu Watanabe
a8d21c91f9 network: show route metric in debug log 2021-04-21 13:42:45 +09:00
Yu Watanabe
0e7bb99ff9 sd-netlink: add missing address types 2021-04-21 13:42:08 +09:00
Frantisek Sumsal
3b6fd3c1de tools: shellcheck-ify most of the tool scripts 2021-04-20 20:11:13 +02:00
Frantisek Sumsal
437e889b18 src: shellcheck-ify shell scripts 2021-04-20 18:39:36 +02:00
49 changed files with 573 additions and 236 deletions

View File

@ -1099,6 +1099,15 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
Defaults to <literal>global</literal>.</para> Defaults to <literal>global</literal>.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>RouteMetric=</varname></term>
<listitem>
<para>The metric of the prefix route, which is pointing to the subnet of the configured IP
address, taking the configured prefix length into account. Takes an unsigned integer in the
range 0…4294967295. When unset or set to 0, the kernel's default value is used. This
setting will be ignored when <varname>AddPrefixRoute=</varname> is false.</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><varname>HomeAddress=</varname></term> <term><varname>HomeAddress=</varname></term>
<listitem> <listitem>
@ -1421,7 +1430,8 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
<varlistentry> <varlistentry>
<term><varname>Metric=</varname></term> <term><varname>Metric=</varname></term>
<listitem> <listitem>
<para>The metric of the route (an unsigned integer).</para> <para>The metric of the route. Takes an unsigned integer in the range 0…4294967295.
Defaluts to unset, and the kernel's default will be used.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
@ -1837,7 +1847,8 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
<varlistentry> <varlistentry>
<term><varname>RouteMetric=</varname></term> <term><varname>RouteMetric=</varname></term>
<listitem> <listitem>
<para>Set the routing metric for routes specified by the DHCP server. Defaults to 1024.</para> <para>Set the routing metric for routes specified by the DHCP server. Takes an unsigned
integer in the range 0…4294967295. Defaults to 1024.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -1977,13 +1988,6 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>RouteMetric=</varname></term>
<listitem>
<para>Set the routing metric for routes specified by the DHCP server. Defaults to 1024.</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><varname>RapidCommit=</varname></term> <term><varname>RapidCommit=</varname></term>
<listitem> <listitem>
@ -2158,6 +2162,14 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
<para>As in the [Address] section, but defaults to true.</para> <para>As in the [Address] section, but defaults to true.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>RouteMetric=</varname></term>
<listitem>
<para>The metric of the route to the delegated prefix subnet. Takes an unsigned integer in
the range 0…4294967295. When unset or set to 0, the kernel's default value is used.</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>
@ -2207,6 +2219,14 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>RouteMetric=</varname></term>
<listitem>
<para>Set the routing metric for the routes received in the Router Advertisement. Takes an
unsigned integer in the range 0…4294967295. Defaults to 1024.</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><varname>UseAutonomousPrefix=</varname></term> <term><varname>UseAutonomousPrefix=</varname></term>
<listitem> <listitem>
@ -2564,6 +2584,15 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
<listitem><para>Takes a boolean. When true, adds an address from the prefix. Default to false. <listitem><para>Takes a boolean. When true, adds an address from the prefix. Default to false.
</para></listitem> </para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>RouteMetric=</varname></term>
<listitem>
<para>The metric of the prefix route. Takes an unsigned integer in the range 0…4294967295.
When unset or set to 0, the kernel's default value is used. This setting is ignored when
<varname>Assign=</varname> is false.</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>

View File

@ -1,7 +1,8 @@
#!/bin/sh #!/bin/bash
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
set -eu set -eu
set -o pipefail
$1 -E -dM -include sys/socket.h -include "$2" -include "$3" - </dev/null | \ ${1:?} -E -dM -include sys/socket.h -include "${2:?}" -include "${3:?}" - </dev/null | \
grep -Ev 'AF_UNSPEC|AF_MAX' | \ grep -Ev 'AF_UNSPEC|AF_MAX' | \
awk '/^#define[ \t]+AF_[^ \t]+[ \t]+[AP]F_[^ \t]/ { print $2; }' awk '/^#define[ \t]+AF_[^ \t]+[ \t]+[AP]F_[^ \t]/ { print $2; }'

View File

@ -1,7 +1,8 @@
#!/bin/sh #!/bin/bash
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
set -eu set -eu
set -o pipefail
$1 -dM -include linux/if_arp.h -include "$2" - </dev/null | \ ${1:?} -dM -include linux/if_arp.h -include "${2:?}" - </dev/null | \
awk '/^#define[ \t]+ARPHRD_[^ \t]+[ \t]+[^ \t]/ { print $2; }' | \ awk '/^#define[ \t]+ARPHRD_[^ \t]+[ \t]+[^ \t]/ { print $2; }' | \
sed -e 's/ARPHRD_//' sed -e 's/ARPHRD_//'

View File

@ -1,7 +1,8 @@
#!/bin/sh #!/bin/bash
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
set -eu set -eu
set -o pipefail
$1 -dM -include linux/capability.h -include "$2" -include "$3" - </dev/null | \ ${1:?} -dM -include linux/capability.h -include "${2:?}" -include "${3:?}" - </dev/null | \
awk '/^#define[ \t]+CAP_[A-Z_]+[ \t]+/ { print $2; }' | \ awk '/^#define[ \t]+CAP_[A-Z_]+[ \t]+/ { print $2; }' | \
grep -v CAP_LAST_CAP grep -v CAP_LAST_CAP

View File

@ -1,6 +1,7 @@
#!/bin/sh #!/bin/bash
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
set -eu set -eu
set -o pipefail
$1 -dM -include errno.h - </dev/null | \ ${1:?} -dM -include errno.h - </dev/null | \
awk '/^#define[ \t]+E[^ _]+[ \t]+/ { print $2; }' awk '/^#define[ \t]+E[^ _]+[ \t]+/ { print $2; }'

View File

@ -803,6 +803,9 @@ int in_addr_prefix_from_string_auto_internal(
} }
static void in_addr_data_hash_func(const struct in_addr_data *a, struct siphash *state) { static void in_addr_data_hash_func(const struct in_addr_data *a, struct siphash *state) {
assert(a);
assert(state);
siphash24_compress(&a->family, sizeof(a->family), state); siphash24_compress(&a->family, sizeof(a->family), state);
siphash24_compress(&a->address, FAMILY_ADDRESS_SIZE(a->family), state); siphash24_compress(&a->address, FAMILY_ADDRESS_SIZE(a->family), state);
} }
@ -810,6 +813,9 @@ static void in_addr_data_hash_func(const struct in_addr_data *a, struct siphash
static int in_addr_data_compare_func(const struct in_addr_data *x, const struct in_addr_data *y) { static int in_addr_data_compare_func(const struct in_addr_data *x, const struct in_addr_data *y) {
int r; int r;
assert(x);
assert(y);
r = CMP(x->family, y->family); r = CMP(x->family, y->family);
if (r != 0) if (r != 0)
return r; return r;
@ -819,13 +825,46 @@ static int in_addr_data_compare_func(const struct in_addr_data *x, const struct
DEFINE_HASH_OPS(in_addr_data_hash_ops, struct in_addr_data, in_addr_data_hash_func, in_addr_data_compare_func); DEFINE_HASH_OPS(in_addr_data_hash_ops, struct in_addr_data, in_addr_data_hash_func, in_addr_data_compare_func);
static void in_addr_prefix_hash_func(const struct in_addr_prefix *a, struct siphash *state) {
assert(a);
assert(state);
siphash24_compress(&a->family, sizeof(a->family), state);
siphash24_compress(&a->prefixlen, sizeof(a->prefixlen), state);
siphash24_compress(&a->address, FAMILY_ADDRESS_SIZE(a->family), state);
}
static int in_addr_prefix_compare_func(const struct in_addr_prefix *x, const struct in_addr_prefix *y) {
int r;
assert(x);
assert(y);
r = CMP(x->family, y->family);
if (r != 0)
return r;
r = CMP(x->prefixlen, y->prefixlen);
if (r != 0)
return r;
return memcmp(&x->address, &y->address, FAMILY_ADDRESS_SIZE(x->family));
}
DEFINE_HASH_OPS(in_addr_prefix_hash_ops, struct in_addr_prefix, in_addr_prefix_hash_func, in_addr_prefix_compare_func);
DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(in_addr_prefix_hash_ops_free, struct in_addr_prefix, in_addr_prefix_hash_func, in_addr_prefix_compare_func, free);
void in6_addr_hash_func(const struct in6_addr *addr, struct siphash *state) { void in6_addr_hash_func(const struct in6_addr *addr, struct siphash *state) {
assert(addr); assert(addr);
assert(state);
siphash24_compress(addr, sizeof(*addr), state); siphash24_compress(addr, sizeof(*addr), state);
} }
int in6_addr_compare_func(const struct in6_addr *a, const struct in6_addr *b) { int in6_addr_compare_func(const struct in6_addr *a, const struct in6_addr *b) {
assert(a);
assert(b);
return memcmp(a, b, sizeof(*a)); return memcmp(a, b, sizeof(*a));
} }

View File

@ -20,6 +20,12 @@ struct in_addr_data {
union in_addr_union address; union in_addr_union address;
}; };
struct in_addr_prefix {
int family;
uint8_t prefixlen;
union in_addr_union address;
};
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) { static inline bool in4_addr_is_set(const struct in_addr *a) {
return !in4_addr_is_null(a); return !in4_addr_is_null(a);
@ -111,4 +117,6 @@ void in6_addr_hash_func(const struct in6_addr *addr, struct siphash *state);
int in6_addr_compare_func(const struct in6_addr *a, const struct in6_addr *b); int in6_addr_compare_func(const struct in6_addr *a, const struct in6_addr *b);
extern const struct hash_ops in_addr_data_hash_ops; extern const struct hash_ops in_addr_data_hash_ops;
extern const struct hash_ops in_addr_prefix_hash_ops;
extern const struct hash_ops in_addr_prefix_hash_ops_free;
extern const struct hash_ops in6_addr_hash_ops; extern const struct hash_ops in6_addr_hash_ops;

View File

@ -1,13 +1,14 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
set -eu set -eu
set -o pipefail
for i in *.h */*.h; do for i in *.h */*.h; do
if [[ $i == 'loadavg.h' ]]; then if [[ "$i" == "loadavg.h" ]]; then
curl --fail https://raw.githubusercontent.com/torvalds/linux/master/include/linux/sched/$i -o $i curl --fail "https://raw.githubusercontent.com/torvalds/linux/master/include/linux/sched/$i" -o "$i"
else else
curl --fail https://raw.githubusercontent.com/torvalds/linux/master/include/uapi/linux/$i -o $i curl --fail "https://raw.githubusercontent.com/torvalds/linux/master/include/uapi/linux/$i" -o "$i"
fi fi
sed -i -e 's/__user //g' -e '/^#include <linux\/compiler.h>/ d' $i sed -i -e 's/__user //g' -e '/^#include <linux\/compiler.h>/ d' "$i"
done done

View File

@ -80,6 +80,7 @@
/* Magic early boot services */ /* Magic early boot services */
#define SPECIAL_FSCK_SERVICE "systemd-fsck@.service" #define SPECIAL_FSCK_SERVICE "systemd-fsck@.service"
#define SPECIAL_FSCK_ROOT_SERVICE "systemd-fsck-root.service" #define SPECIAL_FSCK_ROOT_SERVICE "systemd-fsck-root.service"
#define SPECIAL_FSCK_USR_SERVICE "systemd-fsck-usr.service"
#define SPECIAL_QUOTACHECK_SERVICE "systemd-quotacheck.service" #define SPECIAL_QUOTACHECK_SERVICE "systemd-quotacheck.service"
#define SPECIAL_QUOTAON_SERVICE "quotaon.service" #define SPECIAL_QUOTAON_SERVICE "quotaon.service"
#define SPECIAL_REMOUNT_FS_SERVICE "systemd-remount-fs.service" #define SPECIAL_REMOUNT_FS_SERVICE "systemd-remount-fs.service"

View File

@ -1,8 +1,9 @@
#!/bin/sh #!/bin/bash
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
set -eu set -eu
set -o pipefail
if nm -D -u "$1" | grep ' U '; then if nm -D -u "${1:?}" | grep ' U '; then
echo "Undefined symbols detected!" echo "Undefined symbols detected!"
exit 1 exit 1
fi fi

View File

@ -39,6 +39,12 @@
#define STDOUT_STREAMS_MAX 4096 #define STDOUT_STREAMS_MAX 4096
/* During the "setup" protocol phase of the stream logic let's define a different maximum line length than
* during the actual operational phase. We want to allow users to specify very short line lengths after all,
* but the unit name we embed in the setup protocol might be longer than that. Hence, during the setup phase
* let's enforce a line length matching the maximum unit name length (255) */
#define STDOUT_STREAM_SETUP_PROTOCOL_LINE_MAX (UNIT_NAME_MAX-1U)
typedef enum StdoutStreamState { typedef enum StdoutStreamState {
STDOUT_STREAM_IDENTIFIER, STDOUT_STREAM_IDENTIFIER,
STDOUT_STREAM_UNIT_ID, STDOUT_STREAM_UNIT_ID,
@ -47,7 +53,7 @@ typedef enum StdoutStreamState {
STDOUT_STREAM_FORWARD_TO_SYSLOG, STDOUT_STREAM_FORWARD_TO_SYSLOG,
STDOUT_STREAM_FORWARD_TO_KMSG, STDOUT_STREAM_FORWARD_TO_KMSG,
STDOUT_STREAM_FORWARD_TO_CONSOLE, STDOUT_STREAM_FORWARD_TO_CONSOLE,
STDOUT_STREAM_RUNNING STDOUT_STREAM_RUNNING,
} StdoutStreamState; } StdoutStreamState;
/* The different types of log record terminators: a real \n was read, a NUL character was read, the maximum line length /* The different types of log record terminators: a real \n was read, a NUL character was read, the maximum line length
@ -468,6 +474,18 @@ static int stdout_stream_found(
return r; return r;
} }
static size_t stdout_stream_line_max(StdoutStream *s) {
assert(s);
/* During the "setup" phase of our protocol, let's ensure we use a line length where a full unit name
* can fit in */
if (s->state != STDOUT_STREAM_RUNNING)
return STDOUT_STREAM_SETUP_PROTOCOL_LINE_MAX;
/* After the protocol's "setup" phase is complete, let's use whatever the user configured */
return s->server->line_max;
}
static int stdout_stream_scan( static int stdout_stream_scan(
StdoutStream *s, StdoutStream *s,
char *p, char *p,
@ -475,19 +493,22 @@ static int stdout_stream_scan(
LineBreak force_flush, LineBreak force_flush,
size_t *ret_consumed) { size_t *ret_consumed) {
size_t consumed = 0; size_t consumed = 0, line_max;
int r; int r;
assert(s); assert(s);
assert(p); assert(p);
line_max = stdout_stream_line_max(s);
for (;;) { for (;;) {
LineBreak line_break; LineBreak line_break;
size_t skip, found; size_t skip, found;
char *end1, *end2; char *end1, *end2;
size_t tmp_remaining = MIN(remaining, line_max);
end1 = memchr(p, '\n', remaining); end1 = memchr(p, '\n', tmp_remaining);
end2 = memchr(p, 0, end1 ? (size_t) (end1 - p) : remaining); end2 = memchr(p, 0, end1 ? (size_t) (end1 - p) : tmp_remaining);
if (end2) { if (end2) {
/* We found a NUL terminator */ /* We found a NUL terminator */
@ -499,9 +520,9 @@ static int stdout_stream_scan(
found = end1 - p; found = end1 - p;
skip = found + 1; skip = found + 1;
line_break = LINE_BREAK_NEWLINE; line_break = LINE_BREAK_NEWLINE;
} else if (remaining >= s->server->line_max) { } else if (remaining >= line_max) {
/* Force a line break after the maximum line length */ /* Force a line break after the maximum line length */
found = skip = s->server->line_max; found = skip = line_max;
line_break = LINE_BREAK_LINE_MAX; line_break = LINE_BREAK_LINE_MAX;
} else } else
break; break;
@ -563,7 +584,7 @@ static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents,
/* Try to make use of the allocated buffer in full, but never read more than the configured line size. Also, /* Try to make use of the allocated buffer in full, but never read more than the configured line size. Also,
* always leave room for a terminating NUL we might need to add. */ * always leave room for a terminating NUL we might need to add. */
limit = MIN(s->allocated - 1, s->server->line_max); limit = MIN(s->allocated - 1, MAX(s->server->line_max, STDOUT_STREAM_SETUP_PROTOCOL_LINE_MAX));
assert(s->length <= limit); assert(s->length <= limit);
iovec = IOVEC_MAKE(s->buffer + s->length, limit - s->length); iovec = IOVEC_MAKE(s->buffer + s->length, limit - s->length);

View File

@ -1,16 +1,17 @@
#!/bin/sh #!/bin/bash
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
set -eu set -eu
set -o pipefail
cpp="$1" cpp="${1:?}"
shift shift
includes="" includes=()
for i in "$@"; do for i in "$@"; do
includes="$includes -include $i" includes+=(-include "$i")
done done
$cpp -dM $includes - </dev/null | \ $cpp -dM "${includes[@]}" - </dev/null | \
grep -vE 'AUDIT_.*(FIRST|LAST)_' | \ grep -vE 'AUDIT_.*(FIRST|LAST)_' | \
sed -r -n 's/^#define\s+AUDIT_(\w+)\s+([0-9]{4})\s*$$/\1\t\2/p' | \ sed -r -n 's/^#define\s+AUDIT_(\w+)\s+([0-9]{4})\s*$$/\1\t\2/p' | \
sort -k2 sort -k2

View File

@ -683,13 +683,13 @@ static const NLType rtnl_address_types[] = {
[IFA_ADDRESS] = { .type = NETLINK_TYPE_IN_ADDR }, [IFA_ADDRESS] = { .type = NETLINK_TYPE_IN_ADDR },
[IFA_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, [IFA_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR },
[IFA_LABEL] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ - 1 }, [IFA_LABEL] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ - 1 },
[IFA_BROADCAST] = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */ [IFA_BROADCAST] = { .type = NETLINK_TYPE_IN_ADDR },
[IFA_ANYCAST] = { .type = NETLINK_TYPE_IN_ADDR },
[IFA_CACHEINFO] = { .type = NETLINK_TYPE_CACHE_INFO, .size = sizeof(struct ifa_cacheinfo) }, [IFA_CACHEINFO] = { .type = NETLINK_TYPE_CACHE_INFO, .size = sizeof(struct ifa_cacheinfo) },
/* [IFA_MULTICAST] = { .type = NETLINK_TYPE_IN_ADDR },
[IFA_ANYCAST],
[IFA_MULTICAST],
*/
[IFA_FLAGS] = { .type = NETLINK_TYPE_U32 }, [IFA_FLAGS] = { .type = NETLINK_TYPE_U32 },
[IFA_RT_PRIORITY] = { .type = NETLINK_TYPE_U32 },
[IFA_TARGET_NETNSID] = { .type = NETLINK_TYPE_S32 },
}; };
static const NLTypeSystem rtnl_address_type_system = { static const NLTypeSystem rtnl_address_type_system = {

View File

@ -918,6 +918,10 @@ int address_configure(
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Could not append IFA_CACHEINFO attribute: %m"); return log_link_error_errno(link, r, "Could not append IFA_CACHEINFO attribute: %m");
r = sd_netlink_message_append_u32(req, IFA_RT_PRIORITY, address->route_metric);
if (r < 0)
return log_link_error_errno(link, r, "Could not append IFA_RT_PRIORITY attribute: %m");
k = address_add(link, address, &a); k = address_add(link, address, &a);
if (k < 0) if (k < 0)
return log_link_error_errno(link, k, "Could not add address: %m"); return log_link_error_errno(link, k, "Could not add address: %m");
@ -1091,6 +1095,7 @@ int link_set_addresses(Link *link) {
return log_link_warning_errno(link, r, "Could not generate EUI64 address: %m"); return log_link_warning_errno(link, r, "Could not generate EUI64 address: %m");
address->family = AF_INET6; address->family = AF_INET6;
address->route_metric = p->route_metric;
r = static_address_configure(address, link); r = static_address_configure(address, link);
if (r < 0) if (r < 0)
return r; return r;
@ -1801,6 +1806,48 @@ int config_parse_address_scope(
return 0; return 0;
} }
int config_parse_address_route_metric(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
Network *network = userdata;
_cleanup_(address_free_or_set_invalidp) Address *n = NULL;
int r;
assert(filename);
assert(section);
assert(lvalue);
assert(rvalue);
assert(data);
r = address_new_static(network, filename, section_line, &n);
if (r == -ENOMEM)
return log_oom();
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to allocate new address, ignoring assignment: %m");
return 0;
}
r = safe_atou32(rvalue, &n->route_metric);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Could not parse %s=, ignoring assignment: %s", lvalue, rvalue);
return 0;
}
TAKE_PTR(n);
return 0;
}
int config_parse_duplicate_address_detection( int config_parse_duplicate_address_detection(
const char *unit, const char *unit,
const char *filename, const char *filename,

View File

@ -28,6 +28,7 @@ typedef struct Address {
unsigned char prefixlen; unsigned char prefixlen;
unsigned char scope; unsigned char scope;
uint32_t flags; uint32_t flags;
uint32_t route_metric; /* route metric for prefix route */
char *label; char *label;
int set_broadcast; int set_broadcast;
@ -83,6 +84,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_label);
CONFIG_PARSER_PROTOTYPE(config_parse_lifetime); CONFIG_PARSER_PROTOTYPE(config_parse_lifetime);
CONFIG_PARSER_PROTOTYPE(config_parse_address_flags); CONFIG_PARSER_PROTOTYPE(config_parse_address_flags);
CONFIG_PARSER_PROTOTYPE(config_parse_address_scope); CONFIG_PARSER_PROTOTYPE(config_parse_address_scope);
CONFIG_PARSER_PROTOTYPE(config_parse_address_route_metric);
CONFIG_PARSER_PROTOTYPE(config_parse_duplicate_address_detection); CONFIG_PARSER_PROTOTYPE(config_parse_duplicate_address_detection);
#define IPV4_ADDRESS_FMT_STR "%u.%u.%u.%u" #define IPV4_ADDRESS_FMT_STR "%u.%u.%u.%u"

View File

@ -332,14 +332,14 @@ int config_parse_dhcp_route_metric(
if (streq_ptr(section, "DHCPv4")) { if (streq_ptr(section, "DHCPv4")) {
network->dhcp_route_metric = metric; network->dhcp_route_metric = metric;
network->dhcp_route_metric_set = true; network->dhcp_route_metric_set = true;
} else if (streq_ptr(section, "DHCPv6")) { } else if (STRPTR_IN_SET(section, "DHCPv6", "IPv6AcceptRA")) {
network->dhcp6_route_metric = metric; network->ipv6_accept_ra_route_metric = metric;
network->dhcp6_route_metric_set = true; network->ipv6_accept_ra_route_metric_set = true;
} else { /* [DHCP] section */ } else { /* [DHCP] section */
if (!network->dhcp_route_metric_set) if (!network->dhcp_route_metric_set)
network->dhcp_route_metric = metric; network->dhcp_route_metric = metric;
if (!network->dhcp6_route_metric_set) if (!network->ipv6_accept_ra_route_metric_set)
network->dhcp6_route_metric = metric; network->ipv6_accept_ra_route_metric = metric;
} }
return 0; return 0;

View File

@ -893,6 +893,7 @@ static int dhcp4_update_address(Link *link, bool announce) {
if (prefixlen <= 30) if (prefixlen <= 30)
addr->broadcast.s_addr = address.s_addr | ~netmask.s_addr; addr->broadcast.s_addr = address.s_addr | ~netmask.s_addr;
SET_FLAG(addr->flags, IFA_F_NOPREFIXROUTE, !link_prefixroute(link)); SET_FLAG(addr->flags, IFA_F_NOPREFIXROUTE, !link_prefixroute(link));
addr->route_metric = link->network->dhcp_route_metric;
/* allow reusing an existing address and simply update its lifetime /* allow reusing an existing address and simply update its lifetime
* in case it already exists */ * in case it already exists */

View File

@ -284,6 +284,7 @@ static int dhcp6_set_pd_route(Link *link, const union in_addr_union *prefix, con
route->dst = *prefix; route->dst = *prefix;
route->dst_prefixlen = 64; route->dst_prefixlen = 64;
route->protocol = RTPROT_DHCP; route->protocol = RTPROT_DHCP;
route->priority = link->network->dhcp6_pd_route_metric;
r = route_configure(route, link, dhcp6_pd_route_handler, &ret); r = route_configure(route, link, dhcp6_pd_route_handler, &ret);
if (r < 0) if (r < 0)
@ -363,6 +364,33 @@ static int dhcp6_pd_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Lin
return 1; return 1;
} }
static void log_dhcp6_pd_address(Link *link, const Address *address) {
char valid_buf[FORMAT_TIMESPAN_MAX], preferred_buf[FORMAT_TIMESPAN_MAX];
const char *valid_str = NULL, *preferred_str = NULL;
_cleanup_free_ char *buffer = NULL;
int log_level;
log_level = address_get(link, address, NULL) >= 0 ? LOG_DEBUG : LOG_INFO;
if (log_level < log_get_max_level())
return;
(void) in_addr_prefix_to_string(address->family, &address->in_addr, address->prefixlen, &buffer);
if (address->cinfo.ifa_valid != CACHE_INFO_INFINITY_LIFE_TIME)
valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX,
address->cinfo.ifa_valid * USEC_PER_SEC,
USEC_PER_SEC);
if (address->cinfo.ifa_prefered != CACHE_INFO_INFINITY_LIFE_TIME)
preferred_str = format_timespan(preferred_buf, FORMAT_TIMESPAN_MAX,
address->cinfo.ifa_prefered * USEC_PER_SEC,
USEC_PER_SEC);
log_link_full(link, log_level, "DHCPv6-PD address %s (valid %s%s, preferred %s%s)",
strna(buffer),
valid_str ? "for " : "forever", strempty(valid_str),
preferred_str ? "for " : "forever", strempty(preferred_str));
}
static int dhcp6_set_pd_address( static int dhcp6_set_pd_address(
Link *link, Link *link,
const union in_addr_union *prefix, const union in_addr_union *prefix,
@ -399,7 +427,9 @@ static int dhcp6_set_pd_address(
address->cinfo.ifa_prefered = lifetime_preferred; address->cinfo.ifa_prefered = lifetime_preferred;
address->cinfo.ifa_valid = lifetime_valid; address->cinfo.ifa_valid = lifetime_valid;
SET_FLAG(address->flags, IFA_F_MANAGETEMPADDR, link->network->dhcp6_pd_manage_temporary_address); SET_FLAG(address->flags, IFA_F_MANAGETEMPADDR, link->network->dhcp6_pd_manage_temporary_address);
address->route_metric = link->network->dhcp6_pd_route_metric;
log_dhcp6_pd_address(link, address);
r = address_configure(address, link, dhcp6_pd_address_handler, &ret); r = address_configure(address, link, dhcp6_pd_address_handler, &ret);
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Failed to set DHCPv6 delegated prefix address: %m"); return log_link_error_errno(link, r, "Failed to set DHCPv6 delegated prefix address: %m");
@ -652,6 +682,8 @@ static void dhcp6_pd_prefix_lost(Link *dhcp6_link) {
if (r < 0) if (r < 0)
link_enter_failed(link); link_enter_failed(link);
} }
set_clear(dhcp6_link->dhcp6_pd_prefixes);
} }
static int dhcp6_remove_old(Link *link, bool force); static int dhcp6_remove_old(Link *link, bool force);
@ -794,20 +826,12 @@ static int dhcp6_set_unreachable_route(Link *link, const union in_addr_union *ad
(void) in_addr_prefix_to_string(AF_INET6, addr, prefixlen, &buf); (void) in_addr_prefix_to_string(AF_INET6, addr, prefixlen, &buf);
if (prefixlen > 64) {
log_link_debug(link, "PD Prefix length > 64, ignoring prefix %s", strna(buf));
return 0;
}
if (prefixlen == 64) { if (prefixlen == 64) {
log_link_debug(link, "Not adding a blocking route for DHCPv6 delegated subnet %s 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 0;
} }
if (prefixlen < 48)
log_link_warning(link, "PD Prefix length < 48, looks unusual: %s", strna(buf));
r = route_new(&route); r = route_new(&route);
if (r < 0) if (r < 0)
return log_oom(); return log_oom();
@ -835,7 +859,45 @@ static int dhcp6_set_unreachable_route(Link *link, const union in_addr_union *ad
(void) set_remove(link->dhcp6_routes_old, ret); (void) set_remove(link->dhcp6_routes_old, ret);
return 1; return 0;
}
static int dhcp6_pd_prefix_add(Link *link, const union in_addr_union *prefix, uint8_t prefixlen) {
_cleanup_free_ struct in_addr_prefix *p = NULL;
_cleanup_free_ char *buf = NULL;
int r;
assert(link);
assert(prefix);
p = new(struct in_addr_prefix, 1);
if (!p)
return log_oom();
*p = (struct in_addr_prefix) {
.family = AF_INET6,
.prefixlen = prefixlen,
.address = *prefix,
};
(void) in_addr_prefix_to_string(p->family, &p->address, p->prefixlen, &buf);
log_link_full(link,
set_contains(link->dhcp6_pd_prefixes, p) ? LOG_DEBUG :
prefixlen > 64 || prefixlen < 48 ? LOG_WARNING : LOG_INFO,
"DHCP6: received PD Prefix %s%s",
strna(buf),
prefixlen > 64 ? " with prefix length > 64, ignoring." :
prefixlen < 48 ? " with prefix lenght < 48, looks unusual.": "");
/* Store PD prefix even if prefixlen > 64, not to make logged at warning level so frequently. */
r = set_ensure_put(&link->dhcp6_pd_prefixes, &in_addr_prefix_hash_ops_free, p);
if (r < 0)
return log_link_error_errno(link, r, "Failed to store DHCP6 PD prefix %s: %m", strna(buf));
if (r > 0)
TAKE_PTR(p);
return prefixlen <= 64;
} }
static int dhcp6_pd_prefix_acquired(Link *dhcp6_link) { static int dhcp6_pd_prefix_acquired(Link *dhcp6_link) {
@ -864,12 +926,16 @@ static int dhcp6_pd_prefix_acquired(Link *dhcp6_link) {
if (r < 0) if (r < 0)
break; break;
r = dhcp6_set_unreachable_route(dhcp6_link, &pd_prefix, pd_prefix_len); r = dhcp6_pd_prefix_add(dhcp6_link, &pd_prefix, pd_prefix_len);
if (r < 0) if (r < 0)
return r; return r;
if (r == 0) if (r == 0)
continue; continue;
r = dhcp6_set_unreachable_route(dhcp6_link, &pd_prefix, pd_prefix_len);
if (r < 0)
return r;
/* We are doing prefix allocation in two steps: /* We are doing prefix allocation in two steps:
* 1. all those links that have a preferred subnet id will be assigned their subnet * 1. all those links that have a preferred subnet id will be assigned their subnet
* 2. all those links that remain will receive prefixes in sequential order. Prefixes * 2. all those links that remain will receive prefixes in sequential order. Prefixes

View File

@ -91,6 +91,7 @@ static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
ll_addr->prefixlen = 16; ll_addr->prefixlen = 16;
ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htobe32(0xfffffffflu >> ll_addr->prefixlen); ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htobe32(0xfffffffflu >> ll_addr->prefixlen);
ll_addr->scope = RT_SCOPE_LINK; ll_addr->scope = RT_SCOPE_LINK;
ll_addr->route_metric = IPV4LL_ROUTE_METRIC;
r = address_configure(ll_addr, link, ipv4ll_address_handler, NULL); r = address_configure(ll_addr, link, ipv4ll_address_handler, NULL);
if (r < 0) if (r < 0)

View File

@ -573,6 +573,8 @@ static Link *link_free(Link *link) {
link->dhcp6_pd_addresses_old = set_free(link->dhcp6_pd_addresses_old); link->dhcp6_pd_addresses_old = set_free(link->dhcp6_pd_addresses_old);
link->ndisc_addresses = set_free(link->ndisc_addresses); link->ndisc_addresses = set_free(link->ndisc_addresses);
link->dhcp6_pd_prefixes = set_free(link->dhcp6_pd_prefixes);
link_free_engines(link); link_free_engines(link);
free(link->ifname); free(link->ifname);

View File

@ -151,6 +151,7 @@ typedef struct Link {
sd_dhcp6_lease *dhcp6_lease; sd_dhcp6_lease *dhcp6_lease;
Set *dhcp6_addresses, *dhcp6_addresses_old; Set *dhcp6_addresses, *dhcp6_addresses_old;
Set *dhcp6_routes, *dhcp6_routes_old; Set *dhcp6_routes, *dhcp6_routes_old;
Set *dhcp6_pd_prefixes;
Set *dhcp6_pd_addresses, *dhcp6_pd_addresses_old; Set *dhcp6_pd_addresses, *dhcp6_pd_addresses_old;
Set *dhcp6_pd_routes, *dhcp6_pd_routes_old; Set *dhcp6_pd_routes, *dhcp6_pd_routes_old;
unsigned dhcp6_address_messages; unsigned dhcp6_address_messages;

View File

@ -530,7 +530,7 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
route->family = AF_INET6; route->family = AF_INET6;
route->table = table; route->table = table;
route->priority = link->network->dhcp6_route_metric; route->priority = link->network->ipv6_accept_ra_route_metric;
route->protocol = RTPROT_RA; route->protocol = RTPROT_RA;
route->pref = preference; route->pref = preference;
route->gw_family = AF_INET6; route->gw_family = AF_INET6;
@ -554,7 +554,7 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
if (!route_gw->table_set) if (!route_gw->table_set)
route_gw->table = table; route_gw->table = table;
if (!route_gw->priority_set) if (!route_gw->priority_set)
route_gw->priority = link->network->dhcp6_route_metric; route_gw->priority = link->network->ipv6_accept_ra_route_metric;
if (!route_gw->protocol_set) if (!route_gw->protocol_set)
route_gw->protocol = RTPROT_RA; route_gw->protocol = RTPROT_RA;
if (!route_gw->pref_set) if (!route_gw->pref_set)
@ -814,7 +814,7 @@ static int ndisc_router_process_onlink_prefix(Link *link, sd_ndisc_router *rt) {
route->family = AF_INET6; route->family = AF_INET6;
route->table = link_get_ipv6_accept_ra_route_table(link); route->table = link_get_ipv6_accept_ra_route_table(link);
route->priority = link->network->dhcp6_route_metric; route->priority = link->network->ipv6_accept_ra_route_metric;
route->protocol = RTPROT_RA; route->protocol = RTPROT_RA;
route->flags = RTM_F_PREFIX; route->flags = RTM_F_PREFIX;
route->dst_prefixlen = prefixlen; route->dst_prefixlen = prefixlen;
@ -899,7 +899,7 @@ static int ndisc_router_process_route(Link *link, sd_ndisc_router *rt) {
route->family = AF_INET6; route->family = AF_INET6;
route->table = link_get_ipv6_accept_ra_route_table(link); route->table = link_get_ipv6_accept_ra_route_table(link);
route->priority = link->network->dhcp6_route_metric; route->priority = link->network->ipv6_accept_ra_route_metric;
route->protocol = RTPROT_RA; route->protocol = RTPROT_RA;
route->pref = preference; route->pref = preference;
route->gw = gateway; route->gw = gateway;

View File

@ -146,6 +146,7 @@ Address.AddPrefixRoute, config_parse_address_flags,
Address.AutoJoin, config_parse_address_flags, IFA_F_MCAUTOJOIN, 0 Address.AutoJoin, config_parse_address_flags, IFA_F_MCAUTOJOIN, 0
Address.DuplicateAddressDetection, config_parse_duplicate_address_detection, 0, 0 Address.DuplicateAddressDetection, config_parse_duplicate_address_detection, 0, 0
Address.Scope, config_parse_address_scope, 0, 0 Address.Scope, config_parse_address_scope, 0, 0
Address.RouteMetric, config_parse_address_route_metric, 0, 0
IPv6AddressLabel.Prefix, config_parse_address_label_prefix, 0, 0 IPv6AddressLabel.Prefix, config_parse_address_label_prefix, 0, 0
IPv6AddressLabel.Label, config_parse_address_label, 0, 0 IPv6AddressLabel.Label, config_parse_address_label, 0, 0
Neighbor.Address, config_parse_neighbor_address, 0, 0 Neighbor.Address, config_parse_neighbor_address, 0, 0
@ -243,13 +244,13 @@ DHCPv6.ForceDHCPv6PDOtherInformation, config_parse_bool,
DHCPv6.PrefixDelegationHint, config_parse_dhcp6_pd_hint, 0, 0 DHCPv6.PrefixDelegationHint, config_parse_dhcp6_pd_hint, 0, 0
DHCPv6.WithoutRA, config_parse_dhcp6_client_start_mode, 0, offsetof(Network, dhcp6_without_ra) DHCPv6.WithoutRA, config_parse_dhcp6_client_start_mode, 0, offsetof(Network, dhcp6_without_ra)
DHCPv6.SendOption, config_parse_dhcp_send_option, AF_INET6, offsetof(Network, dhcp6_client_send_options) DHCPv6.SendOption, config_parse_dhcp_send_option, AF_INET6, offsetof(Network, dhcp6_client_send_options)
DHCPv6.RouteMetric, config_parse_dhcp_route_metric, 0, 0
IPv6AcceptRA.UseAutonomousPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_autonomous_prefix) IPv6AcceptRA.UseAutonomousPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_autonomous_prefix)
IPv6AcceptRA.UseOnLinkPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_onlink_prefix) IPv6AcceptRA.UseOnLinkPrefix, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_onlink_prefix)
IPv6AcceptRA.UseDNS, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_dns) IPv6AcceptRA.UseDNS, config_parse_bool, 0, offsetof(Network, ipv6_accept_ra_use_dns)
IPv6AcceptRA.UseDomains, config_parse_ipv6_accept_ra_use_domains, 0, offsetof(Network, ipv6_accept_ra_use_domains) IPv6AcceptRA.UseDomains, config_parse_ipv6_accept_ra_use_domains, 0, offsetof(Network, ipv6_accept_ra_use_domains)
IPv6AcceptRA.DHCPv6Client, config_parse_ipv6_accept_ra_start_dhcp6_client, 0, offsetof(Network, ipv6_accept_ra_start_dhcp6_client) IPv6AcceptRA.DHCPv6Client, config_parse_ipv6_accept_ra_start_dhcp6_client, 0, offsetof(Network, ipv6_accept_ra_start_dhcp6_client)
IPv6AcceptRA.RouteTable, config_parse_section_route_table, 0, 0 IPv6AcceptRA.RouteTable, config_parse_section_route_table, 0, 0
IPv6AcceptRA.RouteMetric, config_parse_dhcp_route_metric, 0, 0
IPv6AcceptRA.RouterAllowList, config_parse_ndisc_address_filter, 0, offsetof(Network, ndisc_allow_listed_router) IPv6AcceptRA.RouterAllowList, config_parse_ndisc_address_filter, 0, offsetof(Network, ndisc_allow_listed_router)
IPv6AcceptRA.RouterDenyList, config_parse_ndisc_address_filter, 0, offsetof(Network, ndisc_deny_listed_router) IPv6AcceptRA.RouterDenyList, config_parse_ndisc_address_filter, 0, offsetof(Network, ndisc_deny_listed_router)
IPv6AcceptRA.PrefixAllowList, config_parse_ndisc_address_filter, 0, offsetof(Network, ndisc_allow_listed_prefix) IPv6AcceptRA.PrefixAllowList, config_parse_ndisc_address_filter, 0, offsetof(Network, ndisc_allow_listed_prefix)
@ -308,6 +309,7 @@ DHCPv6PrefixDelegation.Announce, config_parse_bool,
DHCPv6PrefixDelegation.Assign, config_parse_bool, 0, offsetof(Network, dhcp6_pd_assign) DHCPv6PrefixDelegation.Assign, config_parse_bool, 0, offsetof(Network, dhcp6_pd_assign)
DHCPv6PrefixDelegation.ManageTemporaryAddress, config_parse_bool, 0, offsetof(Network, dhcp6_pd_manage_temporary_address) DHCPv6PrefixDelegation.ManageTemporaryAddress, config_parse_bool, 0, offsetof(Network, dhcp6_pd_manage_temporary_address)
DHCPv6PrefixDelegation.Token, config_parse_dhcp6_pd_token, 0, offsetof(Network, dhcp6_pd_token) DHCPv6PrefixDelegation.Token, config_parse_dhcp6_pd_token, 0, offsetof(Network, dhcp6_pd_token)
DHCPv6PrefixDelegation.RouteMetric, config_parse_uint32, 0, offsetof(Network, dhcp6_pd_route_metric)
IPv6SendRA.RouterLifetimeSec, config_parse_sec, 0, offsetof(Network, router_lifetime_usec) IPv6SendRA.RouterLifetimeSec, config_parse_sec, 0, offsetof(Network, router_lifetime_usec)
IPv6SendRA.Managed, config_parse_bool, 0, offsetof(Network, router_managed) IPv6SendRA.Managed, config_parse_bool, 0, offsetof(Network, router_managed)
IPv6SendRA.OtherInformation, config_parse_bool, 0, offsetof(Network, router_other_information) IPv6SendRA.OtherInformation, config_parse_bool, 0, offsetof(Network, router_other_information)
@ -323,6 +325,7 @@ IPv6Prefix.AddressAutoconfiguration, config_parse_prefix_flags,
IPv6Prefix.ValidLifetimeSec, config_parse_prefix_lifetime, 0, 0 IPv6Prefix.ValidLifetimeSec, config_parse_prefix_lifetime, 0, 0
IPv6Prefix.PreferredLifetimeSec, config_parse_prefix_lifetime, 0, 0 IPv6Prefix.PreferredLifetimeSec, config_parse_prefix_lifetime, 0, 0
IPv6Prefix.Assign, config_parse_prefix_assign, 0, 0 IPv6Prefix.Assign, config_parse_prefix_assign, 0, 0
IPv6Prefix.RouteMetric, config_parse_prefix_metric, 0, 0
IPv6RoutePrefix.Route, config_parse_route_prefix, 0, 0 IPv6RoutePrefix.Route, config_parse_route_prefix, 0, 0
IPv6RoutePrefix.LifetimeSec, config_parse_route_prefix_lifetime, 0, 0 IPv6RoutePrefix.LifetimeSec, config_parse_route_prefix_lifetime, 0, 0
LLDP.MUDURL, config_parse_lldp_mud, 0, 0 LLDP.MUDURL, config_parse_lldp_mud, 0, 0
@ -491,6 +494,7 @@ DHCP.RapidCommit, config_parse_bool,
DHCP.ForceDHCPv6PDOtherInformation, config_parse_bool, 0, offsetof(Network, dhcp6_force_pd_other_information) DHCP.ForceDHCPv6PDOtherInformation, config_parse_bool, 0, offsetof(Network, dhcp6_force_pd_other_information)
DHCPv4.UseDomainName, config_parse_dhcp_use_domains, 0, 0 DHCPv4.UseDomainName, config_parse_dhcp_use_domains, 0, 0
DHCPv4.CriticalConnection, config_parse_tristate, 0, offsetof(Network, dhcp_critical) DHCPv4.CriticalConnection, config_parse_tristate, 0, offsetof(Network, dhcp_critical)
DHCPv6.RouteMetric, config_parse_dhcp_route_metric, 0, 0
IPv6AcceptRA.DenyList, config_parse_ndisc_address_filter, 0, offsetof(Network, ndisc_deny_listed_prefix) IPv6AcceptRA.DenyList, config_parse_ndisc_address_filter, 0, offsetof(Network, ndisc_deny_listed_prefix)
IPv6AcceptRA.BlackList, config_parse_ndisc_address_filter, 0, offsetof(Network, ndisc_deny_listed_prefix) IPv6AcceptRA.BlackList, config_parse_ndisc_address_filter, 0, offsetof(Network, ndisc_deny_listed_prefix)
TrafficControlQueueingDiscipline.Parent, config_parse_qdisc_parent, _QDISC_KIND_INVALID, 0 TrafficControlQueueingDiscipline.Parent, config_parse_qdisc_parent, _QDISC_KIND_INVALID, 0

View File

@ -321,7 +321,6 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.dhcp6_use_hostname = true, .dhcp6_use_hostname = true,
.dhcp6_use_ntp = true, .dhcp6_use_ntp = true,
.dhcp6_rapid_commit = true, .dhcp6_rapid_commit = true,
.dhcp6_route_metric = DHCP_ROUTE_METRIC,
.dhcp6_pd = -1, .dhcp6_pd = -1,
.dhcp6_pd_announce = true, .dhcp6_pd_announce = true,
@ -379,6 +378,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.ipv6_accept_ra_use_autonomous_prefix = true, .ipv6_accept_ra_use_autonomous_prefix = true,
.ipv6_accept_ra_use_onlink_prefix = true, .ipv6_accept_ra_use_onlink_prefix = true,
.ipv6_accept_ra_route_table = RT_TABLE_MAIN, .ipv6_accept_ra_route_table = RT_TABLE_MAIN,
.ipv6_accept_ra_route_metric = DHCP_ROUTE_METRIC,
.ipv6_accept_ra_start_dhcp6_client = IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES, .ipv6_accept_ra_start_dhcp6_client = IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES,
.can_triple_sampling = -1, .can_triple_sampling = -1,

View File

@ -170,8 +170,6 @@ struct Network {
DHCPUseDomains dhcp6_use_domains; DHCPUseDomains dhcp6_use_domains;
bool dhcp6_use_domains_set; bool dhcp6_use_domains_set;
uint8_t dhcp6_pd_length; uint8_t dhcp6_pd_length;
uint32_t dhcp6_route_metric;
bool dhcp6_route_metric_set;
char *dhcp6_mudurl; char *dhcp6_mudurl;
char **dhcp6_user_class; char **dhcp6_user_class;
char **dhcp6_vendor_class; char **dhcp6_vendor_class;
@ -221,6 +219,7 @@ struct Network {
bool dhcp6_pd_assign; bool dhcp6_pd_assign;
bool dhcp6_pd_manage_temporary_address; bool dhcp6_pd_manage_temporary_address;
int64_t dhcp6_pd_subnet_id; int64_t dhcp6_pd_subnet_id;
uint32_t dhcp6_pd_route_metric;
union in_addr_union dhcp6_pd_token; union in_addr_union dhcp6_pd_token;
/* Bridge Support */ /* Bridge Support */
@ -277,10 +276,12 @@ struct Network {
bool ipv6_accept_ra_use_onlink_prefix; bool ipv6_accept_ra_use_onlink_prefix;
bool active_slave; bool active_slave;
bool primary_slave; bool primary_slave;
bool ipv6_accept_ra_route_table_set;
DHCPUseDomains ipv6_accept_ra_use_domains; DHCPUseDomains ipv6_accept_ra_use_domains;
IPv6AcceptRAStartDHCP6Client ipv6_accept_ra_start_dhcp6_client; IPv6AcceptRAStartDHCP6Client ipv6_accept_ra_start_dhcp6_client;
uint32_t ipv6_accept_ra_route_table; uint32_t ipv6_accept_ra_route_table;
bool ipv6_accept_ra_route_table_set;
uint32_t ipv6_accept_ra_route_metric;
bool ipv6_accept_ra_route_metric_set;
Set *ndisc_deny_listed_router; Set *ndisc_deny_listed_router;
Set *ndisc_allow_listed_router; Set *ndisc_allow_listed_router;
Set *ndisc_deny_listed_prefix; Set *ndisc_deny_listed_prefix;

View File

@ -382,6 +382,45 @@ int config_parse_prefix_assign(
return 0; return 0;
} }
int config_parse_prefix_metric(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
Network *network = userdata;
_cleanup_(prefix_free_or_set_invalidp) Prefix *p = NULL;
int r;
assert(filename);
assert(section);
assert(lvalue);
assert(rvalue);
assert(data);
r = prefix_new_static(network, filename, section_line, &p);
if (r < 0)
return log_oom();
r = safe_atou32(rvalue, &p->route_metric);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse %s=, ignoring assignment: %s",
lvalue, rvalue);
return 0;
}
TAKE_PTR(p);
return 0;
}
int config_parse_route_prefix( int config_parse_route_prefix(
const char *unit, const char *unit,
const char *filename, const char *filename,

View File

@ -33,6 +33,7 @@ typedef struct Prefix {
sd_radv_prefix *radv_prefix; sd_radv_prefix *radv_prefix;
bool assign; bool assign;
uint32_t route_metric;
} Prefix; } Prefix;
typedef struct RoutePrefix { typedef struct RoutePrefix {
@ -64,6 +65,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_prefix);
CONFIG_PARSER_PROTOTYPE(config_parse_prefix_flags); CONFIG_PARSER_PROTOTYPE(config_parse_prefix_flags);
CONFIG_PARSER_PROTOTYPE(config_parse_prefix_lifetime); CONFIG_PARSER_PROTOTYPE(config_parse_prefix_lifetime);
CONFIG_PARSER_PROTOTYPE(config_parse_prefix_assign); CONFIG_PARSER_PROTOTYPE(config_parse_prefix_assign);
CONFIG_PARSER_PROTOTYPE(config_parse_prefix_metric);
CONFIG_PARSER_PROTOTYPE(config_parse_radv_dns); CONFIG_PARSER_PROTOTYPE(config_parse_radv_dns);
CONFIG_PARSER_PROTOTYPE(config_parse_radv_search_domains); CONFIG_PARSER_PROTOTYPE(config_parse_radv_search_domains);
CONFIG_PARSER_PROTOTYPE(config_parse_route_prefix); CONFIG_PARSER_PROTOTYPE(config_parse_route_prefix);

View File

@ -628,11 +628,11 @@ static void log_route_debug(const Route *route, const char *str, const Link *lin
(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, src: %s, gw: %s, prefsrc: %s, scope: %s, table: %s, proto: %s, type: %s, nexthop: %"PRIu32, "%s route: dst: %s, src: %s, gw: %s, prefsrc: %s, scope: %s, table: %s, proto: %s, type: %s, nexthop: %"PRIu32", priority: %"PRIu32,
str, strna(dst), 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)),
route->nexthop_id); route->nexthop_id, route->priority);
} }
} }

View File

@ -1,25 +1,28 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
set -ex set -eux
set -o pipefail
[[ -e /dev/loop-control ]] || exit 77 [[ -e /dev/loop-control ]] || exit 77
repart=$1 repart="${1:?}"
test -x $repart test -x "$repart"
D=$(mktemp --tmpdir --directory "test-repart.XXXXXXXXXX") D="$(mktemp --tmpdir --directory "test-repart.XXXXXXXXXX")"
# shellcheck disable=SC2064
trap "rm -rf '$D'" EXIT INT QUIT PIPE trap "rm -rf '$D'" EXIT INT QUIT PIPE
mkdir -p $D/definitions mkdir -p "$D/definitions"
SEED=e2a40bf9-73f1-4278-9160-49c031e7aef8 SEED=e2a40bf9-73f1-4278-9160-49c031e7aef8
echo "### Testing systemd-repart --empty=create ###" echo "### Testing systemd-repart --empty=create ###"
$repart $D/zzz --empty=create --size=1G --seed=$SEED "$repart" "$D/zzz" --empty=create --size=1G --seed="$SEED"
sfdisk -d $D/zzz | grep -v -e 'sector-size' -e '^$' >$D/empty sfdisk -d "$D/zzz" | grep -v -e 'sector-size' -e '^$' >"$D/empty"
cmp $D/empty - <<EOF cmp "$D/empty" - <<EOF
label: gpt label: gpt
label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D
device: $D/zzz device: $D/zzz
@ -30,32 +33,32 @@ EOF
echo "### Testing with root, root2, home, & swap ###" echo "### Testing with root, root2, home, & swap ###"
cat >$D/definitions/root.conf <<EOF cat >"$D/definitions/root.conf" <<EOF
[Partition] [Partition]
Type=root-x86-64 Type=root-x86-64
EOF EOF
ln -s root.conf $D/definitions/root2.conf ln -s root.conf "$D/definitions/root2.conf"
cat >$D/definitions/home.conf <<EOF cat >"$D/definitions/home.conf" <<EOF
[Partition] [Partition]
Type=home Type=home
Label=home-first Label=home-first
Label=home-always-too-long-xxxxxxxxxxxxxx-%v Label=home-always-too-long-xxxxxxxxxxxxxx-%v
EOF EOF
cat >$D/definitions/swap.conf <<EOF cat >"$D/definitions/swap.conf" <<EOF
[Partition] [Partition]
Type=swap Type=swap
SizeMaxBytes=64M SizeMaxBytes=64M
PaddingMinBytes=92M PaddingMinBytes=92M
EOF EOF
$repart $D/zzz --dry-run=no --seed=$SEED --definitions=$D/definitions "$repart" "$D/zzz" --dry-run=no --seed="$SEED" --definitions="$D/definitions"
sfdisk -d $D/zzz | grep -v -e 'sector-size' -e '^$' >$D/populated sfdisk -d "$D/zzz" | grep -v -e 'sector-size' -e '^$' >"$D/populated"
cmp $D/populated - <<EOF cmp "$D/populated" - <<EOF
label: gpt label: gpt
label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D
device: $D/zzz device: $D/zzz
@ -70,27 +73,27 @@ EOF
echo "### Testing with root, root2, home, swap, & another partition ###" echo "### Testing with root, root2, home, swap, & another partition ###"
cat >$D/definitions/swap.conf <<EOF cat >"$D/definitions/swap.conf" <<EOF
[Partition] [Partition]
Type=swap Type=swap
SizeMaxBytes=64M SizeMaxBytes=64M
EOF EOF
cat >$D/definitions/extra.conf <<EOF cat >"$D/definitions/extra.conf" <<EOF
[Partition] [Partition]
Type=linux-generic Type=linux-generic
Label=custom_label Label=custom_label
UUID=a0a1a2a3a4a5a6a7a8a9aaabacadaeaf UUID=a0a1a2a3a4a5a6a7a8a9aaabacadaeaf
EOF EOF
echo "Label=ignored_label" >>$D/definitions/home.conf echo "Label=ignored_label" >>"$D/definitions/home.conf"
echo "UUID=b0b1b2b3b4b5b6b7b8b9babbbcbdbebf" >>$D/definitions/home.conf echo "UUID=b0b1b2b3b4b5b6b7b8b9babbbcbdbebf" >>"$D/definitions/home.conf"
$repart $D/zzz --dry-run=no --seed=$SEED --definitions=$D/definitions "$repart" "$D/zzz" --dry-run=no --seed="$SEED" --definitions="$D/definitions"
sfdisk -d $D/zzz | grep -v -e 'sector-size' -e '^$' >$D/populated2 sfdisk -d "$D/zzz" | grep -v -e 'sector-size' -e '^$' >"$D/populated2"
cmp $D/populated2 - <<EOF cmp "$D/populated2" - <<EOF
label: gpt label: gpt
label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D
device: $D/zzz device: $D/zzz
@ -106,11 +109,11 @@ EOF
echo "### Resizing to 2G ###" echo "### Resizing to 2G ###"
$repart $D/zzz --size=2G --dry-run=no --seed=$SEED --definitions=$D/definitions "$repart" "$D/zzz" --size=2G --dry-run=no --seed="$SEED" --definitions="$D/definitions"
sfdisk -d $D/zzz | grep -v -e 'sector-size' -e '^$' >$D/populated3 sfdisk -d "$D/zzz" | grep -v -e 'sector-size' -e '^$' >"$D/populated3"
cmp $D/populated3 - <<EOF cmp "$D/populated3" - <<EOF
label: gpt label: gpt
label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D
device: $D/zzz device: $D/zzz
@ -124,11 +127,11 @@ $D/zzz4 : start= 1777624, size= 131072, type=0657FD6D-A4AB-43C4-84E5-09
$D/zzz5 : start= 1908696, size= 2285568, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=A0A1A2A3-A4A5-A6A7-A8A9-AAABACADAEAF, name="custom_label" $D/zzz5 : start= 1908696, size= 2285568, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=A0A1A2A3-A4A5-A6A7-A8A9-AAABACADAEAF, name="custom_label"
EOF EOF
dd if=/dev/urandom of=$D/block-copy bs=4096 count=10240 dd if=/dev/urandom of="$D/block-copy" bs=4096 count=10240
echo "### Testing with root, root2, home, swap, another partition, & partition copy ###" echo "### Testing with root, root2, home, swap, another partition, & partition copy ###"
cat >$D/definitions/extra2.conf <<EOF cat >"$D/definitions/extra2.conf" <<EOF
[Partition] [Partition]
Type=linux-generic Type=linux-generic
Label=block-copy Label=block-copy
@ -136,11 +139,11 @@ UUID=2a1d97e1d0a346cca26eadc643926617
CopyBlocks=$D/block-copy CopyBlocks=$D/block-copy
EOF EOF
$repart $D/zzz --size=3G --dry-run=no --seed=$SEED --definitions=$D/definitions "$repart" "$D/zzz" --size=3G --dry-run=no --seed="$SEED" --definitions="$D/definitions"
sfdisk -d $D/zzz | grep -v -e 'sector-size' -e '^$' >$D/populated4 sfdisk -d "$D/zzz" | grep -v -e 'sector-size' -e '^$' >"$D/populated4"
cmp $D/populated4 - <<EOF cmp "$D/populated4" - <<EOF
label: gpt label: gpt
label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D
device: $D/zzz device: $D/zzz
@ -155,14 +158,14 @@ $D/zzz5 : start= 1908696, size= 2285568, type=0FC63DAF-8483-4772-8E79-3D
$D/zzz6 : start= 4194264, size= 2097152, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=2A1D97E1-D0A3-46CC-A26E-ADC643926617, name="block-copy" $D/zzz6 : start= 4194264, size= 2097152, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=2A1D97E1-D0A3-46CC-A26E-ADC643926617, name="block-copy"
EOF EOF
cmp --bytes=41943040 --ignore-initial=0:$((512*4194264)) $D/block-copy $D/zzz cmp --bytes=41943040 --ignore-initial=0:$((512*4194264)) "$D/block-copy" "$D/zzz"
if [ `id -u` == 0 ] && type -P cryptsetup diff losetup > /dev/null ; then if [ "$(id -u)" -eq 0 ] && type -P cryptsetup diff losetup >/dev/null ; then
echo "### Testing Format=/Encrypt=/CopyFiles=" echo "### Testing Format=/Encrypt=/CopyFiles="
# These tests require privileges unfortunately # These tests require privileges unfortunately
cat >$D/definitions/extra3.conf <<EOF cat >"$D/definitions/extra3.conf" <<EOF
[Partition] [Partition]
Type=linux-generic Type=linux-generic
Label=luks-format-copy Label=luks-format-copy
@ -173,11 +176,11 @@ CopyFiles=$D/definitions:/def
SizeMinBytes=48M SizeMinBytes=48M
EOF EOF
$repart $D/zzz --size=auto --dry-run=no --seed=$SEED --definitions=$D/definitions "$repart" "$D/zzz" --size=auto --dry-run=no --seed="$SEED" --definitions="$D/definitions"
sfdisk -d $D/zzz | grep -v -e 'sector-size' -e '^$' >$D/populated5 sfdisk -d "$D/zzz" | grep -v -e 'sector-size' -e '^$' >"$D/populated5"
cmp $D/populated5 - <<EOF cmp "$D/populated5" - <<EOF
label: gpt label: gpt
label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D label-id: EF7F7EE2-47B3-4251-B1A1-09EA8BF12D5D
device: $D/zzz device: $D/zzz
@ -193,23 +196,23 @@ $D/zzz6 : start= 4194264, size= 2097152, type=0FC63DAF-8483-4772-8E79-3D
$D/zzz7 : start= 6291416, size= 98304, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=7B93D1F2-595D-4CE3-B0B9-837FBD9E63B0, name="luks-format-copy" $D/zzz7 : start= 6291416, size= 98304, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=7B93D1F2-595D-4CE3-B0B9-837FBD9E63B0, name="luks-format-copy"
EOF EOF
LOOP=`losetup -P --show --find $D/zzz` LOOP="$(losetup -P --show --find "$D/zzz")"
VOLUME=test-repart-$RANDOM VOLUME="test-repart-$RANDOM"
touch $D/empty-password touch "$D/empty-password"
cryptsetup open --type=luks2 --key-file=$D/empty-password ${LOOP}p7 $VOLUME cryptsetup open --type=luks2 --key-file="$D/empty-password" "${LOOP}p7" "$VOLUME"
mkdir $D/mount mkdir "$D/mount"
mount -t ext4 /dev/mapper/$VOLUME $D/mount mount -t ext4 "/dev/mapper/$VOLUME" "$D/mount"
# Use deferred closing on the mapper and autoclear on the loop, so they are cleaned up on umount # Use deferred closing on the mapper and autoclear on the loop, so they are cleaned up on umount
cryptsetup close --deferred $VOLUME cryptsetup close --deferred "$VOLUME"
losetup -d $LOOP losetup -d "$LOOP"
diff -r $D/mount/def $D/definitions > /dev/null diff -r "$D/mount/def" "$D/definitions" >/dev/null
umount $D/mount umount "$D/mount"
else else
echo "### Skipping Format=/Encrypt=/CopyFiles= test, lacking privileges or missing cryptsetup/diff/losetup" echo "### Skipping Format=/Encrypt=/CopyFiles= test, lacking privileges or missing cryptsetup/diff/losetup"
fi fi
echo "### Testing json output ###" echo "### Testing json output ###"
$repart $D/zzz --size=3G --dry-run=no --seed=$SEED --definitions=$D/definitions --json=help "$repart" "$D/zzz" --size=3G --dry-run=no --seed="$SEED" --definitions="$D/definitions" --json=help
$repart $D/zzz --size=3G --dry-run=no --seed=$SEED --definitions=$D/definitions --json=pretty "$repart" "$D/zzz" --size=3G --dry-run=no --seed="$SEED" --definitions="$D/definitions" --json=pretty
$repart $D/zzz --size=3G --dry-run=no --seed=$SEED --definitions=$D/definitions --json=short "$repart" "$D/zzz" --size=3G --dry-run=no --seed="$SEED" --definitions="$D/definitions" --json=short

View File

@ -1,8 +1,9 @@
#!/bin/sh #!/bin/bash
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
set -eu set -eu
set -o pipefail
$1 -dM -include netinet/in.h - </dev/null | \ ${1:?} -dM -include netinet/in.h - </dev/null | \
awk '/^#define[ \t]+IPPROTO_[^ \t]+[ \t]+[^ \t]/ { print $2; }' | \ awk '/^#define[ \t]+IPPROTO_[^ \t]+[ \t]+[^ \t]/ { print $2; }' | \
sed -e 's/IPPROTO_//' sed -e 's/IPPROTO_//'

View File

@ -71,12 +71,22 @@ int generator_add_symlink(const char *dir, const char *dst, const char *dep_type
return 0; return 0;
} }
static int write_fsck_sysroot_service(const char *dir, const char *what) { static int write_fsck_sysroot_service(
const char *unit, /* Either SPECIAL_FSCK_ROOT_SERVICE or SPECIAL_FSCK_USR_SERVICE */
const char *dir,
const char *what,
const char *extra_after) {
_cleanup_free_ char *device = NULL, *escaped = NULL, *escaped2 = NULL; _cleanup_free_ char *device = NULL, *escaped = NULL, *escaped2 = NULL;
_cleanup_fclose_ FILE *f = NULL; _cleanup_fclose_ FILE *f = NULL;
const char *unit; const char *fn;
int r; int r;
/* Writes out special versions of systemd-root-fsck.service and systemd-usr-fsck.service for use in
* the initrd. The regular statically shipped versions of these unit files use / and /usr for as
* paths, which doesn't match what we need for the initrd (where the dirs are /sysroot +
* /sysusr/usr), hence we overwrite those versions here. */
escaped = specifier_escape(what); escaped = specifier_escape(what);
if (!escaped) if (!escaped)
return log_oom(); return log_oom();
@ -85,41 +95,44 @@ static int write_fsck_sysroot_service(const char *dir, const char *what) {
if (!escaped2) if (!escaped2)
return log_oom(); return log_oom();
unit = strjoina(dir, "/"SPECIAL_FSCK_ROOT_SERVICE); fn = strjoina(dir, "/", unit);
log_debug("Creating %s", unit); log_debug("Creating %s", fn);
r = unit_name_from_path(what, ".device", &device); r = unit_name_from_path(what, ".device", &device);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to convert device \"%s\" to unit name: %m", what); return log_error_errno(r, "Failed to convert device \"%s\" to unit name: %m", what);
f = fopen(unit, "wxe"); f = fopen(fn, "wxe");
if (!f) if (!f)
return log_error_errno(errno, "Failed to create unit file %s: %m", unit); return log_error_errno(errno, "Failed to create unit file %s: %m", fn);
fprintf(f, fprintf(f,
"# Automatically generated by %1$s\n\n" "# Automatically generated by %1$s\n\n"
"[Unit]\n" "[Unit]\n"
"Description=File System Check on %2$s\n" "Description=File System Check on %2$s\n"
"Documentation=man:systemd-fsck-root.service(8)\n" "Documentation=man:%3$s(8)\n"
"DefaultDependencies=no\n" "DefaultDependencies=no\n"
"BindsTo=%3$s\n" "BindsTo=%4$s\n"
"Conflicts=shutdown.target\n" "Conflicts=shutdown.target\n"
"After=initrd-root-device.target local-fs-pre.target %3$s\n" "After=%5$s%6$slocal-fs-pre.target %4$s\n"
"Before=shutdown.target\n" "Before=shutdown.target\n"
"\n" "\n"
"[Service]\n" "[Service]\n"
"Type=oneshot\n" "Type=oneshot\n"
"RemainAfterExit=yes\n" "RemainAfterExit=yes\n"
"ExecStart=" SYSTEMD_FSCK_PATH " %4$s\n" "ExecStart=" SYSTEMD_FSCK_PATH " %7$s\n"
"TimeoutSec=0\n", "TimeoutSec=0\n",
program_invocation_short_name, program_invocation_short_name,
escaped, escaped,
unit,
device, device,
strempty(extra_after),
isempty(extra_after) ? "" : " ",
escaped2); escaped2);
r = fflush_and_check(f); r = fflush_and_check(f);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to write unit file %s: %m", unit); return log_error_errno(r, "Failed to write unit file %s: %m", fn);
return 0; return 0;
} }
@ -138,6 +151,13 @@ int generator_write_fsck_deps(
assert(what); assert(what);
assert(where); assert(where);
/* Let's do an early exit if we are invoked for the root and /usr/ trees in the initrd, to avoid
* generating confusing log messages */
if (in_initrd() && PATH_IN_SET(where, "/", "/usr")) {
log_debug("Skipping fsck for %s in initrd.", where);
return 0;
}
if (!is_device_path(what)) { if (!is_device_path(what)) {
log_warning("Checking was requested for \"%s\", but it is not a device.", what); log_warning("Checking was requested for \"%s\", but it is not a device.", what);
return 0; return 0;
@ -157,6 +177,11 @@ int generator_write_fsck_deps(
if (path_equal(where, "/")) { if (path_equal(where, "/")) {
const char *lnk; const char *lnk;
/* We support running the fsck instance for the root fs while it is already mounted, for
* compatibility with non-initrd boots. It's ugly, but it is how it is. Since unlike for
* regular file systems this means the ordering is reversed (i.e. mount *before* fsck) we
* have a separate fsck unit for this, independent of systemd-fsck@.service. */
lnk = strjoina(dir, "/" SPECIAL_LOCAL_FS_TARGET ".wants/" SPECIAL_FSCK_ROOT_SERVICE); lnk = strjoina(dir, "/" SPECIAL_LOCAL_FS_TARGET ".wants/" SPECIAL_FSCK_ROOT_SERVICE);
(void) mkdir_parents(lnk, 0755); (void) mkdir_parents(lnk, 0755);
@ -168,19 +193,27 @@ int generator_write_fsck_deps(
const char *fsck, *dep; const char *fsck, *dep;
if (in_initrd() && path_equal(where, "/sysroot")) { if (in_initrd() && path_equal(where, "/sysroot")) {
r = write_fsck_sysroot_service(dir, what); r = write_fsck_sysroot_service(SPECIAL_FSCK_ROOT_SERVICE, dir, what, SPECIAL_INITRD_ROOT_DEVICE_TARGET);
if (r < 0) if (r < 0)
return r; return r;
fsck = SPECIAL_FSCK_ROOT_SERVICE; fsck = SPECIAL_FSCK_ROOT_SERVICE;
dep = "Requires"; dep = "Requires";
} else if (in_initrd() && path_equal(where, "/sysusr/usr")) {
r = write_fsck_sysroot_service(SPECIAL_FSCK_USR_SERVICE, dir, what, NULL);
if (r < 0)
return r;
fsck = SPECIAL_FSCK_USR_SERVICE;
dep = "Requires";
} else { } else {
/* When this is /usr, then let's add a Wants= dependency, otherwise a Requires= /* When this is /usr, then let's add a Wants= dependency, otherwise a Requires=
* dependency. Why? We can't possibly unmount /usr during shutdown, but if we have a * dependency. Why? We can't possibly unmount /usr during shutdown, but if we have a
* Requires= from /usr onto a fsck@.service unit and that unit is shut down, then * Requires= from /usr onto a fsck@.service unit and that unit is shut down, then
* we'd have to unmount /usr too. */ * we'd have to unmount /usr too. */
dep = !in_initrd() && path_equal(where, "/usr") ? "Wants" : "Requires"; dep = path_equal(where, "/usr") ? "Wants" : "Requires";
r = unit_name_from_path_instance("systemd-fsck", what, ".service", &_fsck); r = unit_name_from_path_instance("systemd-fsck", what, ".service", &_fsck);
if (r < 0) if (r < 0)

View File

@ -2,6 +2,7 @@
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
set -eu set -eu
# shellcheck disable=SC1004
awk ' awk '
BEGIN { BEGIN {
print "%{\n\ print "%{\n\
@ -16,4 +17,4 @@ _Pragma(\"GCC diagnostic ignored \\\"-Wimplicit-fallthrough\\\"\")\n\
/^KEY_/ { print tolower(substr($1 ,5)) ", " $1 } /^KEY_/ { print tolower(substr($1 ,5)) ", " $1 }
{ print tolower($1) ", " $1 } { print tolower($1) ", " $1 }
' < "$1" ' < "${1:?}"

View File

@ -1,8 +1,9 @@
#!/bin/sh #!/bin/bash
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
set -eu set -eu
set -o pipefail
$1 -dM -include linux/input.h - </dev/null | awk ' ${1:?} -dM -include linux/input.h - </dev/null | awk '
/\<(KEY_(MAX|MIN_INTERESTING))|(BTN_(MISC|MOUSE|JOYSTICK|GAMEPAD|DIGI|WHEEL|TRIGGER_HAPPY))\>/ { next } /\<(KEY_(MAX|MIN_INTERESTING))|(BTN_(MISC|MOUSE|JOYSTICK|GAMEPAD|DIGI|WHEEL|TRIGGER_HAPPY))\>/ { next }
/^#define[ \t]+(KEY|BTN)_[^ ]+[ \t]+[0-9BK]/ { print $2 } /^#define[ \t]+(KEY|BTN)_[^ ]+[ \t]+[0-9BK]/ { print $2 }
' '

View File

@ -147,6 +147,7 @@ Announce=
Assign= Assign=
ManageTemporaryAddress= ManageTemporaryAddress=
Token= Token=
RouteMetric=
[Route] [Route]
Destination= Destination=
Protocol= Protocol=
@ -236,6 +237,7 @@ PreferredLifetimeSec=
AddressAutoconfiguration= AddressAutoconfiguration=
ValidLifetimeSec= ValidLifetimeSec=
Assign= Assign=
RouteMetric=
[IPv6RoutePrefix] [IPv6RoutePrefix]
Route= Route=
LifetimeSec= LifetimeSec=
@ -270,6 +272,7 @@ ManageTemporaryAddress=
Broadcast= Broadcast=
Peer= Peer=
Label= Label=
RouteMetric=
[RoutingPolicyRule] [RoutingPolicyRule]
Table= Table=
IncomingInterface= IncomingInterface=
@ -317,6 +320,7 @@ Prefix=
[IPv6AcceptRA] [IPv6AcceptRA]
UseDomains= UseDomains=
RouteTable= RouteTable=
RouteMetric=
UseDNS= UseDNS=
DHCPv6Client= DHCPv6Client=
UseAutonomousPrefix= UseAutonomousPrefix=

View File

@ -3911,7 +3911,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
self.wait_online(['veth99:routable', 'veth-peer:routable']) self.wait_online(['veth99:routable', 'veth-peer:routable'])
# link become 'routable' when at least one protocol provide an valid address. # link become 'routable' when at least one protocol provide an valid address.
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4') self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic', ipv='-4')
self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6') self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
output = check_output(*networkctl_cmd, '-n', '0', 'status', 'veth99', env=env) output = check_output(*networkctl_cmd, '-n', '0', 'status', 'veth99', env=env)
@ -4014,7 +4014,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
output = check_output('ip address show dev veth99 scope global') output = check_output('ip address show dev veth99 scope global')
print(output) print(output)
self.assertRegex(output, r'inet 192.168.5.250/24 brd 192.168.5.255 scope global veth99') self.assertRegex(output, r'inet 192.168.5.250/24 brd 192.168.5.255 scope global veth99')
self.assertRegex(output, r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global secondary dynamic veth99') self.assertRegex(output, r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global secondary dynamic veth99')
output = check_output('ip route show dev veth99') output = check_output('ip route show dev veth99')
print(output) print(output)
@ -4044,7 +4044,9 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
output = check_output('ip route show dev veth99') output = check_output('ip route show dev veth99')
print(output) print(output)
self.assertRegex(output, 'metric 24') self.assertIn('default via 192.168.5.1 proto dhcp src 192.168.5.181 metric 24', output)
self.assertIn('192.168.5.0/24 proto kernel scope link src 192.168.5.181 metric 24', output)
self.assertIn('192.168.5.1 proto dhcp scope link src 192.168.5.181 metric 24', output)
def test_dhcp_client_reassign_static_routes_ipv4(self): def test_dhcp_client_reassign_static_routes_ipv4(self):
copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
@ -4056,7 +4058,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
output = check_output('ip address show dev veth99 scope global') output = check_output('ip address show dev veth99 scope global')
print(output) print(output)
self.assertRegex(output, r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99') self.assertRegex(output, r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic veth99')
output = check_output('ip route show dev veth99') output = check_output('ip route show dev veth99')
print(output) print(output)
@ -4201,7 +4203,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
self.wait_online(['veth99:routable', 'veth-peer:routable']) self.wait_online(['veth99:routable', 'veth-peer:routable'])
# link become 'routable' when at least one protocol provide an valid address. # link become 'routable' when at least one protocol provide an valid address.
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4') self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic', ipv='-4')
self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6') self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
output = check_output('ip address show dev veth99 scope global') output = check_output('ip address show dev veth99 scope global')
@ -4244,7 +4246,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
self.wait_online(['veth99:routable', 'veth-peer:routable', 'vrf99:carrier']) self.wait_online(['veth99:routable', 'veth-peer:routable', 'vrf99:carrier'])
# link become 'routable' when at least one protocol provide an valid address. # link become 'routable' when at least one protocol provide an valid address.
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4') self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic', ipv='-4')
self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6') self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
print('## ip -d link show dev vrf99') print('## ip -d link show dev vrf99')
@ -4255,14 +4257,14 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
print('## ip address show vrf vrf99') print('## ip address show vrf vrf99')
output = check_output('ip address show vrf vrf99') output = check_output('ip address show vrf vrf99')
print(output) print(output)
self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99') self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic veth99')
self.assertRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)') self.assertRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)')
self.assertRegex(output, 'inet6 .* scope link') self.assertRegex(output, 'inet6 .* scope link')
print('## ip address show dev veth99') print('## ip address show dev veth99')
output = check_output('ip address show dev veth99') output = check_output('ip address show dev veth99')
print(output) print(output)
self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99') self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic veth99')
self.assertRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)') self.assertRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)')
self.assertRegex(output, 'inet6 .* scope link') self.assertRegex(output, 'inet6 .* scope link')
@ -4338,9 +4340,9 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
output = check_output('ip -6 address show dev veth99 scope link') output = check_output('ip -6 address show dev veth99 scope link')
self.assertRegex(output, r'inet6 .* scope link') self.assertRegex(output, r'inet6 .* scope link')
output = check_output('ip -4 address show dev veth99 scope global dynamic') output = check_output('ip -4 address show dev veth99 scope global dynamic')
self.assertRegex(output, r'inet 192\.168\.5\.\d+/24 brd 192\.168\.5\.255 scope global dynamic veth99') self.assertRegex(output, r'inet 192\.168\.5\.\d+/24 metric 1024 brd 192\.168\.5\.255 scope global dynamic veth99')
output = check_output('ip -4 address show dev veth99 scope link') output = check_output('ip -4 address show dev veth99 scope link')
self.assertNotRegex(output, r'inet 169\.254\.\d+\.\d+/16 brd 169\.254\.255\.255 scope link') self.assertNotRegex(output, r'inet 169\.254\.\d+\.\d+/16 metric 2048 brd 169\.254\.255\.255 scope link')
print('Wait for the dynamic address to be expired') print('Wait for the dynamic address to be expired')
time.sleep(130) time.sleep(130)
@ -4353,9 +4355,9 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
output = check_output('ip -6 address show dev veth99 scope link') output = check_output('ip -6 address show dev veth99 scope link')
self.assertRegex(output, r'inet6 .* scope link') self.assertRegex(output, r'inet6 .* scope link')
output = check_output('ip -4 address show dev veth99 scope global dynamic') output = check_output('ip -4 address show dev veth99 scope global dynamic')
self.assertRegex(output, r'inet 192\.168\.5\.\d+/24 brd 192\.168\.5\.255 scope global dynamic veth99') self.assertRegex(output, r'inet 192\.168\.5\.\d+/24 metric 1024 brd 192\.168\.5\.255 scope global dynamic veth99')
output = check_output('ip -4 address show dev veth99 scope link') output = check_output('ip -4 address show dev veth99 scope link')
self.assertNotRegex(output, r'inet 169\.254\.\d+\.\d+/16 brd 169\.254\.255\.255 scope link') self.assertNotRegex(output, r'inet 169\.254\.\d+\.\d+/16 metric 2048 brd 169\.254\.255\.255 scope link')
search_words_in_dnsmasq_log('DHCPOFFER', show_all=True) search_words_in_dnsmasq_log('DHCPOFFER', show_all=True)
@ -4375,13 +4377,13 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
output = check_output('ip -6 address show dev veth99 scope link') output = check_output('ip -6 address show dev veth99 scope link')
self.assertRegex(output, r'inet6 .* scope link') self.assertRegex(output, r'inet6 .* scope link')
output = check_output('ip -4 address show dev veth99 scope global dynamic') output = check_output('ip -4 address show dev veth99 scope global dynamic')
self.assertNotRegex(output, r'inet 192\.168\.5\.\d+/24 brd 192\.168\.5\.255 scope global dynamic veth99') self.assertNotRegex(output, r'inet 192\.168\.5\.\d+/24 metric 1024 brd 192\.168\.5\.255 scope global dynamic veth99')
output = check_output('ip -4 address show dev veth99 scope link') output = check_output('ip -4 address show dev veth99 scope link')
self.assertRegex(output, r'inet 169\.254\.\d+\.\d+/16 brd 169\.254\.255\.255 scope link') self.assertRegex(output, r'inet 169\.254\.\d+\.\d+/16 metric 2048 brd 169\.254\.255\.255 scope link')
start_dnsmasq(lease_time='2m') start_dnsmasq(lease_time='2m')
self.wait_address('veth99', r'inet 192\.168\.5\.\d+/24 brd 192\.168\.5\.255 scope global dynamic', ipv='-4') self.wait_address('veth99', r'inet 192\.168\.5\.\d+/24 metric 1024 brd 192\.168\.5\.255 scope global dynamic', ipv='-4')
self.wait_address_dropped('veth99', r'inet 169\.254\.\d+\.\d+/16 brd 169\.255\.255\.255 scope link', scope='link', ipv='-4') self.wait_address_dropped('veth99', r'inet 169\.254\.\d+\.\d+/16 metric 2048 brd 169\.255\.255\.255 scope link', scope='link', ipv='-4')
def test_dhcp_client_route_remove_on_renew(self): def test_dhcp_client_route_remove_on_renew(self):
copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
@ -4395,7 +4397,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
output = check_output('ip -4 address show dev veth99 scope global dynamic') output = check_output('ip -4 address show dev veth99 scope global dynamic')
print(output) print(output)
self.assertRegex(output, 'inet 192.168.5.1[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99') self.assertRegex(output, 'inet 192.168.5.1[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic veth99')
address1=None address1=None
for line in output.splitlines(): for line in output.splitlines():
if 'brd 192.168.5.255 scope global dynamic veth99' in line: if 'brd 192.168.5.255 scope global dynamic veth99' in line:
@ -4415,10 +4417,10 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
output = check_output('ip -4 address show dev veth99 scope global dynamic') output = check_output('ip -4 address show dev veth99 scope global dynamic')
print(output) print(output)
self.assertRegex(output, 'inet 192.168.5.2[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99') self.assertRegex(output, 'inet 192.168.5.2[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic veth99')
address2=None address2=None
for line in output.splitlines(): for line in output.splitlines():
if 'brd 192.168.5.255 scope global dynamic veth99' in line: if 'metric 1024 brd 192.168.5.255 scope global dynamic veth99' in line:
address2 = line.split()[1].split('/')[0] address2 = line.split()[1].split('/')[0]
break break
@ -4440,7 +4442,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
self.wait_online(['veth99:routable', 'veth-peer:routable']) self.wait_online(['veth99:routable', 'veth-peer:routable'])
# link become 'routable' when at least one protocol provide an valid address. # link become 'routable' when at least one protocol provide an valid address.
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4') self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic', ipv='-4')
self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6') self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
time.sleep(3) time.sleep(3)
@ -4458,7 +4460,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
self.wait_online(['veth99:routable', 'veth-peer:routable']) self.wait_online(['veth99:routable', 'veth-peer:routable'])
# link become 'routable' when at least one protocol provide an valid address. # link become 'routable' when at least one protocol provide an valid address.
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4') self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic', ipv='-4')
self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6') self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
time.sleep(3) time.sleep(3)
@ -4476,7 +4478,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
self.wait_online(['veth99:routable', 'veth-peer:routable']) self.wait_online(['veth99:routable', 'veth-peer:routable'])
# link become 'routable' when at least one protocol provide an valid address. # link become 'routable' when at least one protocol provide an valid address.
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4') self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic', ipv='-4')
self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6') self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
time.sleep(3) time.sleep(3)
@ -4494,7 +4496,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
self.wait_online(['veth99:routable', 'veth-peer:routable']) self.wait_online(['veth99:routable', 'veth-peer:routable'])
# link become 'routable' when at least one protocol provide an valid address. # link become 'routable' when at least one protocol provide an valid address.
self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic', ipv='-4') self.wait_address('veth99', r'inet 192.168.5.[0-9]*/24 metric 1024 brd 192.168.5.255 scope global dynamic', ipv='-4')
self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6') self.wait_address('veth99', r'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)', ipv='-6')
time.sleep(3) time.sleep(3)

View File

@ -2,9 +2,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
set -eu set -eu
cd "$MESON_SOURCE_ROOT" cd "${MESON_SOURCE_ROOT:?}"
if [ ! -f .git/hooks/pre-commit.sample -o -f .git/hooks/pre-commit ]; then if [ ! -f .git/hooks/pre-commit.sample ] || [ -f .git/hooks/pre-commit ]; then
exit 2 # not needed exit 2 # not needed
fi fi

View File

@ -1,31 +1,32 @@
#!/bin/sh #!/bin/bash
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
set -eu set -eu
set -o pipefail
sd_good=0 sd_good=0
sd_total=0 sd_total=0
udev_good=0 udev_good=0
udev_total=0 udev_total=0
deprecated=" deprecated=(
-e sd_bus_try_close -e sd_bus_try_close
-e sd_bus_process_priority -e sd_bus_process_priority
-e sd_bus_message_get_priority -e sd_bus_message_get_priority
-e sd_bus_message_set_priority -e sd_bus_message_set_priority
-e sd_seat_can_multi_session -e sd_seat_can_multi_session
-e sd_journal_open_container -e sd_journal_open_container
" )
for symbol in `nm -g --defined-only "$@" | grep " T " | cut -d" " -f3 | grep -wv $deprecated | sort -u` ; do for symbol in $(nm -g --defined-only "$@" | grep " T " | cut -d" " -f3 | grep -wv "${deprecated[@]}" | sort -u); do
if test -f ${MESON_BUILD_ROOT}/man/$symbol.3 ; then if test -f "${MESON_BUILD_ROOT:?}/man/$symbol.3"; then
echo "✓ Symbol $symbol() is documented." echo "✓ Symbol $symbol() is documented."
good=1 good=1
else else
printf " \x1b[1;31mSymbol $symbol() lacks documentation.\x1b[0m\n" echo -e " \x1b[1;31mSymbol $symbol() lacks documentation.\x1b[0m"
good=0 good=0
fi fi
case $symbol in case "$symbol" in
sd_*) sd_*)
((sd_good+=good)) ((sd_good+=good))
((sd_total+=1)) ((sd_total+=1))

View File

@ -1,6 +1,7 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
set -eu set -eu
set -o pipefail
SOURCE_ROOT="${1:?Missing argument: project source root}" SOURCE_ROOT="${1:?Missing argument: project source root}"
BUILD_ROOT="${2:?Missing argument: project build root}" BUILD_ROOT="${2:?Missing argument: project build root}"

View File

@ -1,30 +1,41 @@
#!/bin/sh #!/bin/bash
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
set -eu set -eu
set -o pipefail
# Note: `grep ... >/dev/null` instead of just `grep -q` is used intentionally
# here, since `grep -q` exits on the first match causing SIGPIPE being
# sent to the sender.
BINARY="${1:?}"
export SYSTEMD_LOG_LEVEL=info export SYSTEMD_LOG_LEVEL=info
if [[ ! -x "$BINARY" ]]; then
echo "$BINARY is not an executable"
exit 1
fi
# output width # output width
if "$1" --help | grep -v 'default:' | grep -E -q '.{80}.'; then if "$BINARY" --help | grep -v 'default:' | grep -E '.{80}.' >/dev/null; then
echo "$(basename "$1") --help output is too wide:" echo "$(basename "$BINARY") --help output is too wide:"
"$1" --help | awk 'length > 80' | grep -E --color=yes '.{80}' "$BINARY" --help | awk 'length > 80' | grep -E --color=yes '.{80}'
exit 1 exit 1
fi fi
# --help prints something. Also catches case where args are ignored. # --help prints something. Also catches case where args are ignored.
if ! "$1" --help | grep -q .; then if ! "$BINARY" --help | grep . >/dev/null; then
echo "$(basename "$1") --help output is empty." echo "$(basename "$BINARY") --help output is empty."
exit 2 exit 2
fi fi
# no --help output to stdout # no --help output to stdout
if "$1" --help 2>&1 1>/dev/null | grep .; then if "$BINARY" --help 2>&1 1>/dev/null | grep .; then
echo "$(basename "$1") --help prints to stderr" echo "$(basename "$BINARY") --help prints to stderr"
exit 3 exit 3
fi fi
# error output to stderr # error output to stderr
if ! "$1" --no-such-parameter 2>&1 1>/dev/null | grep -q .; then if ! ("$BINARY" --no-such-parameter 2>&1 1>/dev/null || :) | grep . >/dev/null; then
echo "$(basename "$1") with an unknown parameter does not print to stderr" echo "$(basename "$BINARY") with an unknown parameter does not print to stderr"
exit 4 exit 4
fi fi

View File

@ -1,12 +1,12 @@
#!/bin/sh #!/bin/sh
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
set -e set -eu
# Try to guess the build directory: # Try to guess the build directory:
# we look for subdirectories of the parent directory that look like ninja build dirs. # we look for subdirectories of the parent directory that look like ninja build dirs.
if [ -n "$BUILD_DIR" ]; then if [ -n "${BUILD_DIR:=}" ]; then
echo "$(realpath "$BUILD_DIR")" realpath "$BUILD_DIR"
exit 0 exit 0
fi fi
@ -14,20 +14,20 @@ root="$(dirname "$(realpath "$0")")"
found= found=
for i in "$root"/../*/build.ninja; do for i in "$root"/../*/build.ninja; do
c="$(dirname $i)" c="$(dirname "$i")"
[ -d "$c" ] || continue [ -d "$c" ] || continue
[ "$(basename "$c")" != mkosi.builddir ] || continue [ "$(basename "$c")" != mkosi.builddir ] || continue
if [ -n "$found" ]; then if [ -n "$found" ]; then
echo 'Found multiple candidates, specify build directory with $BUILD_DIR' >&2 echo "Found multiple candidates, specify build directory with \$BUILD_DIR" >&2
exit 2 exit 2
fi fi
found="$c" found="$c"
done done
if [ -z "$found" ]; then if [ -z "$found" ]; then
echo 'Specify build directory with $BUILD_DIR' >&2 echo "Specify build directory with \$BUILD_DIR" >&2
exit 1 exit 1
fi fi
echo "$(realpath $found)" realpath "$found"

View File

@ -1,38 +1,40 @@
#!/bin/sh #!/bin/sh
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
TOP=`git rev-parse --show-toplevel` set -eu
case "$1" in TOP="$(git rev-parse --show-toplevel)"
case "${1:-}" in
recdiff) recdiff)
if [ "$2" = "" ] ; then if [ "${2:-}" = "" ] ; then
DIR="$TOP" DIR="$TOP"
else else
DIR="$2" DIR="$2"
fi fi
find $DIR -type f \( -name '*.[ch]' -o -name '*.xml' \) -exec $0 diff \{\} \; find "$DIR" -type f \( -name '*.[ch]' -o -name '*.xml' \) -exec "$0" diff \{\} \;
;; ;;
recpatch) recpatch)
if [ "$2" = "" ] ; then if [ "${2:-}" = "" ] ; then
DIR="$TOP" DIR="$TOP"
else else
DIR="$2" DIR="$2"
fi fi
find $DIR -type f \( -name '*.[ch]' -o -name '*.xml' \) -exec $0 patch \{\} \; find "$DIR" -type f \( -name '*.[ch]' -o -name '*.xml' \) -exec "$0" patch \{\} \;
;; ;;
diff) diff)
T=`mktemp` T="$(mktemp)"
sed '/^$/N;/^\n$/D' < "$2" > "$T" sed '/^$/N;/^\n$/D' <"${2:?}" >"$T"
diff -u "$2" "$T" diff -u "$2" "$T"
rm -f "$T" rm -f "$T"
;; ;;
patch) patch)
sed -i '/^$/N;/^\n$/D' "$2" sed -i '/^$/N;/^\n$/D' "${2:?}"
;; ;;
*) *)

View File

@ -1,38 +1,40 @@
#!/bin/sh #!/bin/sh
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
TOP=`git rev-parse --show-toplevel` set -eu
case "$1" in TOP="$(git rev-parse --show-toplevel)"
case "${1:-}" in
recdiff) recdiff)
if [ "$2" = "" ] ; then if [ "${2:-}" = "" ] ; then
DIR="$TOP" DIR="$TOP"
else else
DIR="$2" DIR="$2"
fi fi
find $DIR -type f \( -name '*.[ch]' -o -name '*.xml' \) -exec $0 diff \{\} \; find "$DIR" -type f \( -name '*.[ch]' -o -name '*.xml' \) -exec "$0" diff \{\} \;
;; ;;
recpatch) recpatch)
if [ "$2" = "" ] ; then if [ "${2:-}" = "" ] ; then
DIR="$TOP" DIR="$TOP"
else else
DIR="$2" DIR="$2"
fi fi
find $DIR -type f \( -name '*.[ch]' -o -name '*.xml' \) -exec $0 patch \{\} \; find "$DIR" -type f \( -name '*.[ch]' -o -name '*.xml' \) -exec "$0" patch \{\} \;
;; ;;
diff) diff)
T=`mktemp` T="$(mktemp)"
sed 's/\t/ /g' < "$2" > "$T" sed 's/\t/ /g' <"${2:?}" >"$T"
diff -u "$2" "$T" diff -u "$2" "$T"
rm -f "$T" rm -f "$T"
;; ;;
patch) patch)
sed -i 's/\t/ /g' "$2" sed -i 's/\t/ /g' "${2:?}"
;; ;;
*) *)

View File

@ -1,25 +1,21 @@
#!/bin/sh #!/bin/bash
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
set -eu set -eu
CONFIG=$1 CONFIG="${1:?Missing path to config.h}"
TARGET=$2 TARGET="${2:?Missing target m4 file}"
if [ $# -ne 2 ]; then if [ ! -f "$CONFIG" ]; then
echo 'Invalid number of arguments.'
exit 1
fi
if [ ! -f $CONFIG ]; then
echo "$CONFIG not found." echo "$CONFIG not found."
exit 2 exit 2
fi fi
if [ ! -f $TARGET ]; then if [ ! -f "$TARGET" ]; then
echo "$TARGET not found." echo "$TARGET not found."
exit 3 exit 3
fi fi
DEFINES=$(awk '$1 == "#define" && $3 == "1" { printf "-D%s ", $2 }' $CONFIG) DEFINES=()
mapfile -t DEFINES < <(awk '$1 == "#define" && $3 == "1" { printf "-D%s\n", $2 }' "$CONFIG")
m4 -P $DEFINES $TARGET m4 -P "${DEFINES[@]}" "$TARGET"

View File

@ -2,6 +2,9 @@
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
set -eu set -eu
SOURCE="${1:?}"
TARGET="${2:?}"
if [ "${MESON_INSTALL_QUIET:-0}" = 1 ] ; then if [ "${MESON_INSTALL_QUIET:-0}" = 1 ] ; then
VERBOSE="" VERBOSE=""
else else
@ -11,9 +14,9 @@ fi
# this is needed mostly because $DESTDIR is provided as a variable, # this is needed mostly because $DESTDIR is provided as a variable,
# and we need to create the target directory... # and we need to create the target directory...
mkdir -${VERBOSE}p "$(dirname "${DESTDIR:-}$2")" mkdir -${VERBOSE}p "$(dirname "${DESTDIR:-}$TARGET")"
if [ "$(dirname $1)" = . -o "$(dirname $1)" = .. ]; then if [ "$(dirname "$SOURCE")" = . ] || [ "$(dirname "$SOURCE")" = .. ]; then
ln -${VERBOSE}fs -T -- "$1" "${DESTDIR:-}$2" ln -${VERBOSE}fs -T -- "$SOURCE" "${DESTDIR:-}$TARGET"
else else
ln -${VERBOSE}fs -T --relative -- "${DESTDIR:-}$1" "${DESTDIR:-}$2" ln -${VERBOSE}fs -T --relative -- "${DESTDIR:-}$SOURCE" "${DESTDIR:-}$TARGET"
fi fi

View File

@ -4,8 +4,8 @@
set -eu set -eu
set -o pipefail set -o pipefail
dir="$1" dir="${1:?}"
fallback="$2" fallback="${2:?}"
# Apparently git describe has a bug where it always considers the work-tree # Apparently git describe has a bug where it always considers the work-tree
# dirty when invoked with --git-dir (even though 'git status' is happy). Work # dirty when invoked with --git-dir (even though 'git status' is happy). Work

View File

@ -2,7 +2,7 @@
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
set -eu set -eu
cd "$1" cd "${1:?}"
(curl --fail -L 'https://chromium.googlesource.com/chromiumos/platform2/+/master/power_manager/udev/gen_autosuspend_rules.py?format=TEXT'; echo) \ (curl --fail -L 'https://chromium.googlesource.com/chromiumos/platform2/+/master/power_manager/udev/gen_autosuspend_rules.py?format=TEXT'; echo) \
| base64 -d > tools/chromiumos/gen_autosuspend_rules.py | base64 -d > tools/chromiumos/gen_autosuspend_rules.py

View File

@ -2,7 +2,7 @@
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
set -eu set -eu
cd "$1" cd "${1:?}"
unset permissive unset permissive
if [ "${2:-}" = "-p" ]; then if [ "${2:-}" = "-p" ]; then
@ -28,6 +28,6 @@ if [ "${2:-}" != "-n" ]; then (
set -x set -x
./acpi-update.py >20-acpi-vendor.hwdb.base ./acpi-update.py >20-acpi-vendor.hwdb.base
patch -p0 -o- 20-acpi-vendor.hwdb.base <20-acpi-vendor.hwdb.patch >20-acpi-vendor.hwdb patch -p0 -o- 20-acpi-vendor.hwdb.base <20-acpi-vendor.hwdb.patch >20-acpi-vendor.hwdb
! diff -u 20-acpi-vendor.hwdb.base 20-acpi-vendor.hwdb >20-acpi-vendor.hwdb.patch diff -u 20-acpi-vendor.hwdb.base 20-acpi-vendor.hwdb >20-acpi-vendor.hwdb.patch && exit 1
./ids_parser.py ./ids_parser.py

View File

@ -2,10 +2,10 @@
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
set -eu set -eu
cd "$1" && shift cd "${1:?}" && shift
curl --fail -L -o syscall-list.txt 'https://raw.githubusercontent.com/hrw/syscalls-table/master/syscall-names.text' curl --fail -L -o syscall-list.txt 'https://raw.githubusercontent.com/hrw/syscalls-table/master/syscall-names.text'
for arch in "$@"; do for arch in "$@"; do
curl --fail -L -o syscalls-$arch.txt "https://raw.githubusercontent.com/hrw/syscalls-table/master/tables/syscalls-$arch" curl --fail -L -o "syscalls-$arch.txt" "https://raw.githubusercontent.com/hrw/syscalls-table/master/tables/syscalls-$arch"
done done

View File

@ -19,6 +19,11 @@ ConditionDirectoryNotEmpty=|/usr/lib/repart.d
ConditionDirectoryNotEmpty=|/usr/local/lib/repart.d ConditionDirectoryNotEmpty=|/usr/local/lib/repart.d
ConditionDirectoryNotEmpty=|/etc/repart.d ConditionDirectoryNotEmpty=|/etc/repart.d
ConditionDirectoryNotEmpty=|/run/repart.d ConditionDirectoryNotEmpty=|/run/repart.d
ConditionDirectoryNotEmpty=|/sysroot/usr/lib/repart.d
ConditionDirectoryNotEmpty=|/sysroot/usr/local/lib/repart.d
ConditionDirectoryNotEmpty=|/sysroot/etc/repart.d
ConditionDirectoryNotEmpty=|/sysusr/usr/lib/repart.d
ConditionDirectoryNotEmpty=|/sysusr/usr/local/lib/repart.d
[Service] [Service]
Type=oneshot Type=oneshot