mirror of
https://github.com/systemd/systemd
synced 2026-03-10 07:04:46 +01:00
Compare commits
No commits in common. "c83e44110cea3d1542640b954c1d83041a710fe3" and "b332778b30d23193c792d5f5c5dcccd61f4a489c" have entirely different histories.
c83e44110c
...
b332778b30
@ -226,7 +226,7 @@ appliance-like installations.
|
|||||||
### What partitioning tools will create a DPS-compliant partition table?
|
### What partitioning tools will create a DPS-compliant partition table?
|
||||||
|
|
||||||
As of util-linux 2.25.2, the `fdisk` tool provides type codes to create the
|
As of util-linux 2.25.2, the `fdisk` tool provides type codes to create the
|
||||||
root, home, and swap partitions that the DPS expects. By default, `fdisk` will
|
root, home, and swap partitions that the DPS expects, By default, `fdisk` will
|
||||||
create an old-style MBR, not a GPT, so typing `l` to list partition types will
|
create an old-style MBR, not a GPT, so typing `l` to list partition types will
|
||||||
not show the choices to let you set the correct UUID. Make sure to first create
|
not show the choices to let you set the correct UUID. Make sure to first create
|
||||||
an empty GPT, then type `l` in order for the DPS-compliant type codes to be
|
an empty GPT, then type `l` in order for the DPS-compliant type codes to be
|
||||||
|
|||||||
@ -2408,9 +2408,7 @@ SystemCallErrorNumber=EPERM</programlisting>
|
|||||||
<citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry> for more
|
<citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry> for more
|
||||||
details about named file descriptors and their ordering.</para>
|
details about named file descriptors and their ordering.</para>
|
||||||
|
|
||||||
<para>This setting defaults to <option>null</option>, unless
|
<para>This setting defaults to <option>null</option>.</para></listitem>
|
||||||
<varname>StandardInputText=</varname>/<varname>StandardInputData=</varname> are set, in which case it
|
|
||||||
defaults to <option>data</option>.</para></listitem>
|
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
@ -2524,11 +2522,9 @@ SystemCallErrorNumber=EPERM</programlisting>
|
|||||||
<term><varname>StandardInputText=</varname></term>
|
<term><varname>StandardInputText=</varname></term>
|
||||||
<term><varname>StandardInputData=</varname></term>
|
<term><varname>StandardInputData=</varname></term>
|
||||||
|
|
||||||
<listitem><para>Configures arbitrary textual or binary data to pass via file descriptor 0 (STDIN) to
|
<listitem><para>Configures arbitrary textual or binary data to pass via file descriptor 0 (STDIN) to the
|
||||||
the executed processes. These settings have no effect unless <varname>StandardInput=</varname> is set
|
executed processes. These settings have no effect unless <varname>StandardInput=</varname> is set to
|
||||||
to <option>data</option> (which is the default if <varname>StandardInput=</varname> is not set
|
<option>data</option>. Use this option to embed process input data directly in the unit file.</para>
|
||||||
otherwise, but <varname>StandardInputText=</varname>/<varname>StandardInputData=</varname> is). Use
|
|
||||||
this option to embed process input data directly in the unit file.</para>
|
|
||||||
|
|
||||||
<para><varname>StandardInputText=</varname> accepts arbitrary textual data. C-style escapes for special
|
<para><varname>StandardInputText=</varname> accepts arbitrary textual data. C-style escapes for special
|
||||||
characters as well as the usual <literal>%</literal>-specifiers are resolved. Each time this setting is used
|
characters as well as the usual <literal>%</literal>-specifiers are resolved. Each time this setting is used
|
||||||
|
|||||||
@ -1349,14 +1349,6 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
|
|||||||
<literal>no</literal>.</para>
|
<literal>no</literal>.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
|
||||||
<term><varname>Blackhole=</varname></term>
|
|
||||||
<listitem>
|
|
||||||
<para>Takes a boolean. If enabled, packets to the corresponding routes are discarded
|
|
||||||
silently, and <varname>Gateway=</varname> cannot be specified. Defaults to
|
|
||||||
<literal>no</literal>.</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
|||||||
@ -1063,32 +1063,28 @@
|
|||||||
<refsect2>
|
<refsect2>
|
||||||
<title>Conditions and Asserts</title>
|
<title>Conditions and Asserts</title>
|
||||||
|
|
||||||
<para>Unit files may also include a number of <varname index="false">Condition…=</varname> and <varname
|
<para>Unit files may also include a number of <varname index="false">Condition…=</varname> and
|
||||||
index="false">Assert…=</varname> settings. Before the unit is started, systemd will verify that the
|
<varname index="false">Assert…=</varname> settings. Before the unit is started, systemd will verify
|
||||||
specified conditions and asserts are true. If not, the starting of the unit will be (mostly silently)
|
that the specified conditions are true. If not, the starting of the unit will be (mostly silently)
|
||||||
skipped (in case of conditions), or aborted with an error message (in case of asserts). Failing
|
skipped. Failing conditions will not result in the unit being moved into the <literal>failed</literal>
|
||||||
conditions or asserts will not result in the unit being moved into the <literal>failed</literal>
|
state. The conditions are checked at the time the queued start job is to be executed. The ordering
|
||||||
state. The conditions and asserts are checked at the time the queued start job is to be executed. The
|
dependencies are still respected, so other units are still pulled in and ordered as if this unit was
|
||||||
ordering dependencies are still respected, so other units are still pulled in and ordered as if this
|
successfully activated. Use condition expressions in order to skip units that do not apply to the local
|
||||||
unit was successfully activated, and the conditions and asserts are executed the precise moment the
|
system, for example because the kernel or runtime environment doesn't require their functionality.
|
||||||
unit would normally start and thus can validate system state after the units ordered before completed
|
|
||||||
initialization. Use condition expressions for skipping units that do not apply to the local system, for
|
|
||||||
example because the kernel or runtime environment doesn't require their functionality.
|
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>If multiple conditions are specified, the unit will be executed if all of them apply (i.e. a
|
<para>If multiple conditions are specified, the unit will be executed if all of them apply (i.e. a
|
||||||
logical AND is applied). Condition checks can use a pipe symbol (<literal>|</literal>) after the equals
|
logical AND is applied). Condition checks can use a pipe symbol (<literal>|</literal>) after the equals
|
||||||
sign (<literal>Condition…=|…</literal>), which causes the condition to become a
|
sign (<literal>Condition…=|…</literal>), which causes the condition becomes a triggering condition. If
|
||||||
<emphasis>triggering</emphasis> condition. If at least one triggering condition is defined for a unit,
|
at least one triggering condition is defined for a unit, then the unit will be executed if at least one
|
||||||
then the unit will be started if at least one of the triggering conditions of the unit applies and all
|
of the triggering conditions apply and all of the non-triggering conditions. If you prefix an argument
|
||||||
of the regular (i.e. non-triggering) conditions apply. If you prefix an argument with the pipe symbol
|
with the pipe symbol and an exclamation mark, the pipe symbol must be passed first, the exclamation
|
||||||
and an exclamation mark, the pipe symbol must be passed first, the exclamation second. If any of these
|
second. If any of these options is assigned the empty string, the list of conditions is reset
|
||||||
options is assigned the empty string, the list of conditions is reset completely, all previous
|
completely, all previous condition settings (of any kind) will have no effect.</para>
|
||||||
condition settings (of any kind) will have no effect.</para>
|
|
||||||
|
|
||||||
<para>The <varname>AssertArchitecture=</varname>, <varname>AssertVirtualization=</varname>, … options
|
<para>The <varname>AssertArchitecture=</varname>, <varname>AssertVirtualization=</varname>, … options
|
||||||
are similar to conditions but cause the start job to fail (instead of being skipped). The failed check
|
provide a similar mechanism that causes the job to fail (instead of being skipped). The failed check is
|
||||||
is logged. Units with failed conditions are considered to be in a clean state and will be garbage
|
logged. Units with failed conditions are considered to be in a clean state and will be garbage
|
||||||
collected if they are not referenced. This means that when queried, the condition failure may or may
|
collected if they are not referenced. This means that when queried, the condition failure may or may
|
||||||
not show up in the state of the unit.</para>
|
not show up in the state of the unit.</para>
|
||||||
|
|
||||||
|
|||||||
@ -71,9 +71,11 @@ static int find_pci_or_platform_parent(sd_device *device, sd_device **ret) {
|
|||||||
return -ENODATA;
|
return -ENODATA;
|
||||||
|
|
||||||
c += strspn(c, DIGITS);
|
c += strspn(c, DIGITS);
|
||||||
if (*c == '-' && !STARTSWITH_SET(c, "-LVDS-", "-Embedded DisplayPort-"))
|
if (*c == '-') {
|
||||||
/* A connector DRM device, let's ignore all but LVDS and eDP! */
|
/* A connector DRM device, let's ignore all but LVDS and eDP! */
|
||||||
|
if (!STARTSWITH_SET(c, "-LVDS-", "-Embedded DisplayPort-"))
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
}
|
||||||
|
|
||||||
} else if (streq(subsystem, "pci") &&
|
} else if (streq(subsystem, "pci") &&
|
||||||
sd_device_get_sysattr_value(parent, "class", &value) >= 0) {
|
sd_device_get_sysattr_value(parent, "class", &value) >= 0) {
|
||||||
@ -135,14 +137,19 @@ static int validate_device(sd_device *device) {
|
|||||||
|
|
||||||
assert(device);
|
assert(device);
|
||||||
|
|
||||||
/* Verify whether we should actually care for a specific backlight device. For backlight devices
|
/* Verify whether we should actually care for a specific
|
||||||
* there might be multiple ways to access the same control: "firmware" (i.e. ACPI), "platform"
|
* backlight device. For backlight devices there might be
|
||||||
* (i.e. via the machine's EC) and "raw" (via the graphics card). In general we should prefer
|
* multiple ways to access the same control: "firmware"
|
||||||
* "firmware" (i.e. ACPI) or "platform" access over "raw" access, in order not to confuse the
|
* (i.e. ACPI), "platform" (i.e. via the machine's EC) and
|
||||||
* BIOS/EC, and compatibility with possible low-level hotkey handling of screen brightness. The
|
* "raw" (via the graphics card). In general we should prefer
|
||||||
* kernel will already make sure to expose only one of "firmware" and "platform" for the same
|
* "firmware" (i.e. ACPI) or "platform" access over "raw"
|
||||||
* device to userspace. However, we still need to make sure that we use "raw" only if no
|
* access, in order not to confuse the BIOS/EC, and
|
||||||
* "firmware" or "platform" device for the same device exists. */
|
* compatibility with possible low-level hotkey handling of
|
||||||
|
* screen brightness. The kernel will already make sure to
|
||||||
|
* expose only one of "firmware" and "platform" for the same
|
||||||
|
* device to userspace. However, we still need to make sure
|
||||||
|
* that we use "raw" only if no "firmware" or "platform"
|
||||||
|
* device for the same device exists. */
|
||||||
|
|
||||||
r = sd_device_get_subsystem(device, &subsystem);
|
r = sd_device_get_subsystem(device, &subsystem);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -187,12 +194,13 @@ static int validate_device(sd_device *device) {
|
|||||||
!STR_IN_SET(v, "platform", "firmware"))
|
!STR_IN_SET(v, "platform", "firmware"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* OK, so there's another backlight device, and it's a platform or firmware device.
|
/* OK, so there's another backlight device, and it's a
|
||||||
* Let's see if we can verify it belongs to the same device as ours. */
|
* platform or firmware device, so, let's see if we
|
||||||
|
* can verify it belongs to the same device as ours. */
|
||||||
if (find_pci_or_platform_parent(other, &other_parent) < 0)
|
if (find_pci_or_platform_parent(other, &other_parent) < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (same_device(parent, other_parent) > 0) {
|
if (same_device(parent, other_parent)) {
|
||||||
const char *device_sysname = NULL, *other_sysname = NULL;
|
const char *device_sysname = NULL, *other_sysname = NULL;
|
||||||
|
|
||||||
/* Both have the same PCI parent, that means we are out. */
|
/* Both have the same PCI parent, that means we are out. */
|
||||||
@ -249,6 +257,11 @@ static int get_max_brightness(sd_device *device, unsigned *ret) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Some systems turn the backlight all the way off at the lowest levels.
|
||||||
|
* clamp_brightness clamps the saved brightness to at least 1 or 5% of
|
||||||
|
* max_brightness in case of 'backlight' subsystem. This avoids preserving
|
||||||
|
* an unreadably dim screen, which would otherwise force the user to
|
||||||
|
* disable state restoration. */
|
||||||
static int clamp_brightness(sd_device *device, bool saved, unsigned max_brightness, unsigned *brightness) {
|
static int clamp_brightness(sd_device *device, bool saved, unsigned max_brightness, unsigned *brightness) {
|
||||||
unsigned new_brightness, min_brightness;
|
unsigned new_brightness, min_brightness;
|
||||||
const char *subsystem;
|
const char *subsystem;
|
||||||
@ -257,11 +270,6 @@ static int clamp_brightness(sd_device *device, bool saved, unsigned max_brightne
|
|||||||
assert(device);
|
assert(device);
|
||||||
assert(brightness);
|
assert(brightness);
|
||||||
|
|
||||||
/* Some systems turn the backlight all the way off at the lowest levels. This clamps the saved
|
|
||||||
* brightness to at least 1 or 5% of max_brightness in case of 'backlight' subsystem. This
|
|
||||||
* avoids preserving an unreadably dim screen, which would otherwise force the user to disable
|
|
||||||
* state restoration. */
|
|
||||||
|
|
||||||
r = sd_device_get_subsystem(device, &subsystem);
|
r = sd_device_get_subsystem(device, &subsystem);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_device_warning_errno(device, r, "Failed to get device subsystem: %m");
|
return log_device_warning_errno(device, r, "Failed to get device subsystem: %m");
|
||||||
@ -380,9 +388,6 @@ static int run(int argc, char *argv[]) {
|
|||||||
if (argc != 3)
|
if (argc != 3)
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program requires two arguments.");
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This program requires two arguments.");
|
||||||
|
|
||||||
if (!STR_IN_SET(argv[1], "load", "save"))
|
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown verb %s.", argv[1]);
|
|
||||||
|
|
||||||
umask(0022);
|
umask(0022);
|
||||||
|
|
||||||
r = mkdir_p("/var/lib/systemd/backlight", 0755);
|
r = mkdir_p("/var/lib/systemd/backlight", 0755);
|
||||||
@ -404,8 +409,9 @@ static int run(int argc, char *argv[]) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to get backlight or LED device '%s:%s': %m", ss, sysname);
|
return log_error_errno(r, "Failed to get backlight or LED device '%s:%s': %m", ss, sysname);
|
||||||
|
|
||||||
/* If max_brightness is 0, then there is no actual backlight device. This happens on desktops
|
/* If max_brightness is 0, then there is no actual backlight
|
||||||
* with Asus mainboards that load the eeepc-wmi module. */
|
* device. This happens on desktops with Asus mainboards
|
||||||
|
* that load the eeepc-wmi module. */
|
||||||
if (get_max_brightness(device, &max_brightness) < 0)
|
if (get_max_brightness(device, &max_brightness) < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -426,11 +432,14 @@ static int run(int argc, char *argv[]) {
|
|||||||
} else
|
} else
|
||||||
saved = strjoina("/var/lib/systemd/backlight/", escaped_ss, ":", escaped_sysname);
|
saved = strjoina("/var/lib/systemd/backlight/", escaped_ss, ":", escaped_sysname);
|
||||||
|
|
||||||
/* If there are multiple conflicting backlight devices, then their probing at boot-time might
|
/* If there are multiple conflicting backlight devices, then
|
||||||
* happen in any order. This means the validity checking of the device then is not reliable,
|
* their probing at boot-time might happen in any order. This
|
||||||
* since it might not see other devices conflicting with a specific backlight. To deal with
|
* means the validity checking of the device then is not
|
||||||
* this, we will actively delete backlight state files at shutdown (where device probing should
|
* reliable, since it might not see other devices conflicting
|
||||||
* be complete), so that the validity check at boot time doesn't have to be reliable. */
|
* with a specific backlight. To deal with this, we will
|
||||||
|
* actively delete backlight state files at shutdown (where
|
||||||
|
* device probing should be complete), so that the validity
|
||||||
|
* check at boot time doesn't have to be reliable. */
|
||||||
|
|
||||||
if (streq(argv[1], "load")) {
|
if (streq(argv[1], "load")) {
|
||||||
_cleanup_free_ char *value = NULL;
|
_cleanup_free_ char *value = NULL;
|
||||||
@ -494,7 +503,7 @@ static int run(int argc, char *argv[]) {
|
|||||||
return log_device_error_errno(device, r, "Failed to write %s: %m", saved);
|
return log_device_error_errno(device, r, "Failed to write %s: %m", saved);
|
||||||
|
|
||||||
} else
|
} else
|
||||||
assert_not_reached("Unknown verb.");
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown verb %s.", argv[1]);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5648,14 +5648,15 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
|
|||||||
for (size_t i = 0; i < c->n_mount_images; i++) {
|
for (size_t i = 0; i < c->n_mount_images; i++) {
|
||||||
MountOptions *o;
|
MountOptions *o;
|
||||||
|
|
||||||
fprintf(f, "%sMountImages: %s%s:%s", prefix,
|
fprintf(f, "%sMountImages: %s%s:%s%s", prefix,
|
||||||
c->mount_images[i].ignore_enoent ? "-": "",
|
c->mount_images[i].ignore_enoent ? "-": "",
|
||||||
c->mount_images[i].source,
|
c->mount_images[i].source,
|
||||||
c->mount_images[i].destination);
|
c->mount_images[i].destination,
|
||||||
|
LIST_IS_EMPTY(c->mount_images[i].mount_options) ? "": ":");
|
||||||
LIST_FOREACH(mount_options, o, c->mount_images[i].mount_options)
|
LIST_FOREACH(mount_options, o, c->mount_images[i].mount_options)
|
||||||
fprintf(f, ":%s:%s",
|
fprintf(f, "%s:%s",
|
||||||
partition_designator_to_string(o->partition_designator),
|
partition_designator_to_string(o->partition_designator),
|
||||||
strempty(o->options));
|
o->options);
|
||||||
fprintf(f, "\n");
|
fprintf(f, "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -419,6 +419,7 @@ static int parse_options(const char *options) {
|
|||||||
|
|
||||||
static char* disk_description(const char *path) {
|
static char* disk_description(const char *path) {
|
||||||
static const char name_fields[] =
|
static const char name_fields[] =
|
||||||
|
"ID_PART_ENTRY_NAME\0"
|
||||||
"DM_NAME\0"
|
"DM_NAME\0"
|
||||||
"ID_MODEL_FROM_DATABASE\0"
|
"ID_MODEL_FROM_DATABASE\0"
|
||||||
"ID_MODEL\0";
|
"ID_MODEL\0";
|
||||||
@ -426,7 +427,6 @@ static char* disk_description(const char *path) {
|
|||||||
_cleanup_(sd_device_unrefp) sd_device *device = NULL;
|
_cleanup_(sd_device_unrefp) sd_device *device = NULL;
|
||||||
const char *i, *name;
|
const char *i, *name;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(path);
|
assert(path);
|
||||||
|
|
||||||
@ -436,27 +436,9 @@ static char* disk_description(const char *path) {
|
|||||||
if (!S_ISBLK(st.st_mode))
|
if (!S_ISBLK(st.st_mode))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (sd_device_new_from_stat_rdev(&device, &st) < 0)
|
if (sd_device_new_from_devnum(&device, 'b', st.st_rdev) < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (sd_device_get_property_value(device, "ID_PART_ENTRY_NAME", &name) >= 0) {
|
|
||||||
_cleanup_free_ char *unescaped = NULL;
|
|
||||||
|
|
||||||
/* ID_PART_ENTRY_NAME uses \x style escaping, using libblkid's blkid_encode_string(). Let's
|
|
||||||
* reverse this here to make the string more human friendly in case people embed spaces or
|
|
||||||
* other weird stuff. */
|
|
||||||
|
|
||||||
r = cunescape(name, UNESCAPE_RELAX, &unescaped);
|
|
||||||
if (r < 0) {
|
|
||||||
log_debug_errno(r, "Failed to unescape ID_PART_ENTRY_NAME, skipping device: %m");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isempty(unescaped) && !string_has_cc(unescaped, NULL))
|
|
||||||
return TAKE_PTR(unescaped);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* These need no unescaping. */
|
|
||||||
NULSTR_FOREACH(i, name_fields)
|
NULSTR_FOREACH(i, name_fields)
|
||||||
if (sd_device_get_property_value(device, i, &name) >= 0 &&
|
if (sd_device_get_property_value(device, i, &name) >= 0 &&
|
||||||
!isempty(name))
|
!isempty(name))
|
||||||
|
|||||||
@ -287,7 +287,7 @@ static int run(int argc, char *argv[]) {
|
|||||||
"%s is not a block device.",
|
"%s is not a block device.",
|
||||||
device);
|
device);
|
||||||
|
|
||||||
r = sd_device_new_from_stat_rdev(&dev, &st);
|
r = sd_device_new_from_devnum(&dev, 'b', st.st_rdev);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to detect device %s: %m", device);
|
return log_error_errno(r, "Failed to detect device %s: %m", device);
|
||||||
|
|
||||||
|
|||||||
@ -2711,7 +2711,7 @@ static int home_get_image_path_seat(Home *h, char **ret) {
|
|||||||
if (!S_ISBLK(st.st_mode))
|
if (!S_ISBLK(st.st_mode))
|
||||||
return -ENOTBLK;
|
return -ENOTBLK;
|
||||||
|
|
||||||
r = sd_device_new_from_stat_rdev(&d, &st);
|
r = sd_device_new_from_devnum(&d, 'b', st.st_rdev);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
|||||||
@ -929,7 +929,7 @@ static int umount_by_device(sd_bus *bus, const char *what) {
|
|||||||
return log_error_errno(SYNTHETIC_ERRNO(ENOTBLK),
|
return log_error_errno(SYNTHETIC_ERRNO(ENOTBLK),
|
||||||
"Not a block device: %s", what);
|
"Not a block device: %s", what);
|
||||||
|
|
||||||
r = sd_device_new_from_stat_rdev(&d, &st);
|
r = sd_device_new_from_devnum(&d, 'b', st.st_rdev);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to get device from device number: %m");
|
return log_error_errno(r, "Failed to get device from device number: %m");
|
||||||
|
|
||||||
@ -1270,7 +1270,7 @@ static int discover_loop_backing_file(void) {
|
|||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
"Invalid file type: %s", loop_dev);
|
"Invalid file type: %s", loop_dev);
|
||||||
|
|
||||||
r = sd_device_new_from_stat_rdev(&d, &st);
|
r = sd_device_new_from_devnum(&d, 'b', st.st_rdev);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to get device from device number: %m");
|
return log_error_errno(r, "Failed to get device from device number: %m");
|
||||||
|
|
||||||
@ -1314,7 +1314,7 @@ static int discover_device(void) {
|
|||||||
"Invalid file type: %s",
|
"Invalid file type: %s",
|
||||||
arg_mount_what);
|
arg_mount_what);
|
||||||
|
|
||||||
r = sd_device_new_from_stat_rdev(&d, &st);
|
r = sd_device_new_from_devnum(&d, 'b', st.st_rdev);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to get device from device number: %m");
|
return log_error_errno(r, "Failed to get device from device number: %m");
|
||||||
|
|
||||||
|
|||||||
@ -894,8 +894,6 @@ Manager* manager_free(Manager *m) {
|
|||||||
m->routes = set_free(m->routes);
|
m->routes = set_free(m->routes);
|
||||||
m->routes_foreign = set_free(m->routes_foreign);
|
m->routes_foreign = set_free(m->routes_foreign);
|
||||||
|
|
||||||
m->nexthops = set_free(m->nexthops);
|
|
||||||
m->nexthops_foreign = set_free(m->nexthops_foreign);
|
|
||||||
m->nexthops_by_id = hashmap_free(m->nexthops_by_id);
|
m->nexthops_by_id = hashmap_free(m->nexthops_by_id);
|
||||||
|
|
||||||
sd_event_source_unref(m->speed_meter_event_source);
|
sd_event_source_unref(m->speed_meter_event_source);
|
||||||
|
|||||||
@ -64,10 +64,6 @@ struct Manager {
|
|||||||
/* Manage nexthops by id. */
|
/* Manage nexthops by id. */
|
||||||
Hashmap *nexthops_by_id;
|
Hashmap *nexthops_by_id;
|
||||||
|
|
||||||
/* Manager stores nexthops without RTA_OIF attribute. */
|
|
||||||
Set *nexthops;
|
|
||||||
Set *nexthops_foreign;
|
|
||||||
|
|
||||||
/* Manager stores routes without RTA_OIF attribute. */
|
/* Manager stores routes without RTA_OIF attribute. */
|
||||||
Set *routes;
|
Set *routes;
|
||||||
Set *routes_foreign;
|
Set *routes_foreign;
|
||||||
|
|||||||
@ -190,7 +190,6 @@ NextHop.Id, config_parse_nexthop_id,
|
|||||||
NextHop.Gateway, config_parse_nexthop_gateway, 0, 0
|
NextHop.Gateway, config_parse_nexthop_gateway, 0, 0
|
||||||
NextHop.Family, config_parse_nexthop_family, 0, 0
|
NextHop.Family, config_parse_nexthop_family, 0, 0
|
||||||
NextHop.OnLink, config_parse_nexthop_onlink, 0, 0
|
NextHop.OnLink, config_parse_nexthop_onlink, 0, 0
|
||||||
NextHop.Blackhole, config_parse_nexthop_blackhole, 0, 0
|
|
||||||
DHCPv4.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier)
|
DHCPv4.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier)
|
||||||
DHCPv4.UseDNS, config_parse_dhcp_use_dns, 0, 0
|
DHCPv4.UseDNS, config_parse_dhcp_use_dns, 0, 0
|
||||||
DHCPv4.RoutesToDNS, config_parse_bool, 0, offsetof(Network, dhcp_routes_to_dns)
|
DHCPv4.RoutesToDNS, config_parse_bool, 0, offsetof(Network, dhcp_routes_to_dns)
|
||||||
|
|||||||
@ -33,14 +33,6 @@ NextHop *nexthop_free(NextHop *nexthop) {
|
|||||||
hashmap_remove(nexthop->link->manager->nexthops_by_id, UINT32_TO_PTR(nexthop->id));
|
hashmap_remove(nexthop->link->manager->nexthops_by_id, UINT32_TO_PTR(nexthop->id));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nexthop->manager) {
|
|
||||||
set_remove(nexthop->manager->nexthops, nexthop);
|
|
||||||
set_remove(nexthop->manager->nexthops_foreign, nexthop);
|
|
||||||
|
|
||||||
if (nexthop->id > 0)
|
|
||||||
hashmap_remove(nexthop->manager->nexthops_by_id, UINT32_TO_PTR(nexthop->id));
|
|
||||||
}
|
|
||||||
|
|
||||||
return mfree(nexthop);
|
return mfree(nexthop);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +95,6 @@ static void nexthop_hash_func(const NextHop *nexthop, struct siphash *state) {
|
|||||||
assert(nexthop);
|
assert(nexthop);
|
||||||
|
|
||||||
siphash24_compress(&nexthop->id, sizeof(nexthop->id), state);
|
siphash24_compress(&nexthop->id, sizeof(nexthop->id), state);
|
||||||
siphash24_compress(&nexthop->blackhole, sizeof(nexthop->blackhole), state);
|
|
||||||
siphash24_compress(&nexthop->family, sizeof(nexthop->family), state);
|
siphash24_compress(&nexthop->family, sizeof(nexthop->family), state);
|
||||||
|
|
||||||
switch (nexthop->family) {
|
switch (nexthop->family) {
|
||||||
@ -125,10 +116,6 @@ static int nexthop_compare_func(const NextHop *a, const NextHop *b) {
|
|||||||
if (r != 0)
|
if (r != 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = CMP(a->blackhole, b->blackhole);
|
|
||||||
if (r != 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
r = CMP(a->family, b->family);
|
r = CMP(a->family, b->family);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
return r;
|
return r;
|
||||||
@ -146,18 +133,6 @@ DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(
|
|||||||
nexthop_compare_func,
|
nexthop_compare_func,
|
||||||
nexthop_free);
|
nexthop_free);
|
||||||
|
|
||||||
static void nexthop_copy(NextHop *dest, const NextHop *src) {
|
|
||||||
assert(dest);
|
|
||||||
assert(src);
|
|
||||||
|
|
||||||
/* This only copies entries used in the above hash and compare functions. */
|
|
||||||
|
|
||||||
dest->id = src->id;
|
|
||||||
dest->blackhole = src->blackhole;
|
|
||||||
dest->family = src->family;
|
|
||||||
dest->gw = src->gw;
|
|
||||||
}
|
|
||||||
|
|
||||||
int manager_get_nexthop_by_id(Manager *manager, uint32_t id, NextHop **ret) {
|
int manager_get_nexthop_by_id(Manager *manager, uint32_t id, NextHop **ret) {
|
||||||
NextHop *nh;
|
NextHop *nh;
|
||||||
|
|
||||||
@ -175,20 +150,20 @@ int manager_get_nexthop_by_id(Manager *manager, uint32_t id, NextHop **ret) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nexthop_get(Manager *manager, Link *link, const NextHop *in, NextHop **ret) {
|
static int nexthop_get(Link *link, const NextHop *in, NextHop **ret) {
|
||||||
NextHop *existing;
|
NextHop *existing;
|
||||||
|
|
||||||
assert(manager || link);
|
assert(link);
|
||||||
assert(in);
|
assert(in);
|
||||||
|
|
||||||
existing = set_get(link ? link->nexthops : manager->nexthops, in);
|
existing = set_get(link->nexthops, in);
|
||||||
if (existing) {
|
if (existing) {
|
||||||
if (ret)
|
if (ret)
|
||||||
*ret = existing;
|
*ret = existing;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
existing = set_get(link ? link->nexthops_foreign : manager->nexthops_foreign, in);
|
existing = set_get(link->nexthops_foreign, in);
|
||||||
if (existing) {
|
if (existing) {
|
||||||
if (ret)
|
if (ret)
|
||||||
*ret = existing;
|
*ret = existing;
|
||||||
@ -198,11 +173,11 @@ static int nexthop_get(Manager *manager, Link *link, const NextHop *in, NextHop
|
|||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nexthop_add_internal(Manager *manager, Link *link, Set **nexthops, const NextHop *in, NextHop **ret) {
|
static int nexthop_add_internal(Link *link, Set **nexthops, const NextHop *in, NextHop **ret) {
|
||||||
_cleanup_(nexthop_freep) NextHop *nexthop = NULL;
|
_cleanup_(nexthop_freep) NextHop *nexthop = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(manager || link);
|
assert(link);
|
||||||
assert(nexthops);
|
assert(nexthops);
|
||||||
assert(in);
|
assert(in);
|
||||||
|
|
||||||
@ -210,7 +185,9 @@ static int nexthop_add_internal(Manager *manager, Link *link, Set **nexthops, co
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
nexthop_copy(nexthop, in);
|
nexthop->id = in->id;
|
||||||
|
nexthop->family = in->family;
|
||||||
|
nexthop->gw = in->gw;
|
||||||
|
|
||||||
r = set_ensure_put(nexthops, &nexthop_hash_ops, nexthop);
|
r = set_ensure_put(nexthops, &nexthop_hash_ops, nexthop);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -219,7 +196,6 @@ static int nexthop_add_internal(Manager *manager, Link *link, Set **nexthops, co
|
|||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
|
|
||||||
nexthop->link = link;
|
nexthop->link = link;
|
||||||
nexthop->manager = manager;
|
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
*ret = nexthop;
|
*ret = nexthop;
|
||||||
@ -228,9 +204,8 @@ static int nexthop_add_internal(Manager *manager, Link *link, Set **nexthops, co
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nexthop_add_foreign(Manager *manager, Link *link, const NextHop *in, NextHop **ret) {
|
static int nexthop_add_foreign(Link *link, const NextHop *in, NextHop **ret) {
|
||||||
assert(manager || link);
|
return nexthop_add_internal(link, &link->nexthops_foreign, in, ret);
|
||||||
return nexthop_add_internal(manager, link, link ? &link->nexthops_foreign : &manager->nexthops_foreign, in, ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nexthop_add(Link *link, const NextHop *in, NextHop **ret) {
|
static int nexthop_add(Link *link, const NextHop *in, NextHop **ret) {
|
||||||
@ -238,30 +213,20 @@ static int nexthop_add(Link *link, const NextHop *in, NextHop **ret) {
|
|||||||
NextHop *nexthop;
|
NextHop *nexthop;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(link);
|
r = nexthop_get(link, in, &nexthop);
|
||||||
assert(in);
|
|
||||||
|
|
||||||
if (in->blackhole)
|
|
||||||
r = nexthop_get(link->manager, NULL, in, &nexthop);
|
|
||||||
else
|
|
||||||
r = nexthop_get(NULL, link, in, &nexthop);
|
|
||||||
if (r == -ENOENT) {
|
if (r == -ENOENT) {
|
||||||
/* NextHop does not exist, create a new one */
|
/* NextHop does not exist, create a new one */
|
||||||
r = nexthop_add_internal(link->manager,
|
r = nexthop_add_internal(link, &link->nexthops, in, &nexthop);
|
||||||
in->blackhole ? NULL : link,
|
|
||||||
in->blackhole ? &link->manager->nexthops : &link->nexthops,
|
|
||||||
in, &nexthop);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
is_new = true;
|
is_new = true;
|
||||||
} else if (r == 0) {
|
} else if (r == 0) {
|
||||||
/* Take over a foreign nexthop */
|
/* Take over a foreign nexthop */
|
||||||
r = set_ensure_put(in->blackhole ? &link->manager->nexthops : &link->nexthops,
|
r = set_ensure_put(&link->nexthops, &nexthop_hash_ops, nexthop);
|
||||||
&nexthop_hash_ops, nexthop);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
set_remove(in->blackhole ? link->manager->nexthops_foreign : link->nexthops_foreign, nexthop);
|
set_remove(link->nexthops_foreign, nexthop);
|
||||||
} else if (r == 1) {
|
} else if (r == 1) {
|
||||||
/* NextHop exists, do nothing */
|
/* NextHop exists, do nothing */
|
||||||
;
|
;
|
||||||
@ -273,13 +238,11 @@ static int nexthop_add(Link *link, const NextHop *in, NextHop **ret) {
|
|||||||
return is_new;
|
return is_new;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nexthop_update(Manager *manager, Link *link, NextHop *nexthop, const NextHop *in) {
|
static int nexthop_update(Link *link, NextHop *nexthop, const NextHop *in) {
|
||||||
Set *nexthops;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
/* link may be NULL. */
|
assert(link);
|
||||||
|
assert(link->manager);
|
||||||
assert(manager);
|
|
||||||
assert(nexthop);
|
assert(nexthop);
|
||||||
assert(in);
|
assert(in);
|
||||||
assert(in->id > 0);
|
assert(in->id > 0);
|
||||||
@ -292,21 +255,19 @@ static int nexthop_update(Manager *manager, Link *link, NextHop *nexthop, const
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
nexthops = link ? link->nexthops : manager->nexthops;
|
nexthop = set_remove(link->nexthops, nexthop);
|
||||||
|
|
||||||
nexthop = set_remove(nexthops, nexthop);
|
|
||||||
if (!nexthop)
|
if (!nexthop)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
nexthop->id = in->id;
|
nexthop->id = in->id;
|
||||||
|
|
||||||
r = set_put(nexthops, nexthop);
|
r = set_put(link->nexthops, nexthop);
|
||||||
if (r <= 0) {
|
if (r <= 0) {
|
||||||
int k;
|
int k;
|
||||||
|
|
||||||
/* On failure, revert the change. */
|
/* On failure, revert the change. */
|
||||||
nexthop->id = 0;
|
nexthop->id = 0;
|
||||||
k = set_put(nexthops, nexthop);
|
k = set_put(link->nexthops, nexthop);
|
||||||
if (k <= 0) {
|
if (k <= 0) {
|
||||||
nexthop_free(nexthop);
|
nexthop_free(nexthop);
|
||||||
return k < 0 ? k : -EEXIST;
|
return k < 0 ? k : -EEXIST;
|
||||||
@ -316,14 +277,13 @@ static int nexthop_update(Manager *manager, Link *link, NextHop *nexthop, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
set_manager:
|
set_manager:
|
||||||
return hashmap_ensure_put(&manager->nexthops_by_id, NULL, UINT32_TO_PTR(nexthop->id), nexthop);
|
return hashmap_ensure_put(&link->manager->nexthops_by_id, NULL, UINT32_TO_PTR(nexthop->id), nexthop);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void log_nexthop_debug(const NextHop *nexthop, uint32_t id, const char *str, const Link *link) {
|
static void log_nexthop_debug(const NextHop *nexthop, uint32_t id, const char *str, const Link *link) {
|
||||||
assert(nexthop);
|
assert(nexthop);
|
||||||
assert(str);
|
assert(str);
|
||||||
|
assert(link);
|
||||||
/* link may be NULL. */
|
|
||||||
|
|
||||||
if (DEBUG_LOGGING) {
|
if (DEBUG_LOGGING) {
|
||||||
_cleanup_free_ char *gw = NULL;
|
_cleanup_free_ char *gw = NULL;
|
||||||
@ -331,11 +291,11 @@ static void log_nexthop_debug(const NextHop *nexthop, uint32_t id, const char *s
|
|||||||
(void) in_addr_to_string(nexthop->family, &nexthop->gw, &gw);
|
(void) in_addr_to_string(nexthop->family, &nexthop->gw, &gw);
|
||||||
|
|
||||||
if (nexthop->id == id)
|
if (nexthop->id == id)
|
||||||
log_link_debug(link, "%s nexthop: id: %"PRIu32", gw: %s, blackhole: %s",
|
log_link_debug(link, "%s nexthop: id: %"PRIu32", gw: %s",
|
||||||
str, nexthop->id, strna(gw), yes_no(nexthop->blackhole));
|
str, nexthop->id, strna(gw));
|
||||||
else
|
else
|
||||||
log_link_debug(link, "%s nexthop: id: %"PRIu32"→%"PRIu32", gw: %s, blackhole: %s",
|
log_link_debug(link, "%s nexthop: id: %"PRIu32"→%"PRIu32", gw: %s",
|
||||||
str, nexthop->id, id, strna(gw), yes_no(nexthop->blackhole));
|
str, nexthop->id, id, strna(gw));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -393,11 +353,6 @@ static int nexthop_configure(const NextHop *nexthop, Link *link) {
|
|||||||
return log_link_error_errno(link, r, "Could not append NHA_ID attribute: %m");
|
return log_link_error_errno(link, r, "Could not append NHA_ID attribute: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nexthop->blackhole) {
|
|
||||||
r = sd_netlink_message_append_flag(req, NHA_BLACKHOLE);
|
|
||||||
if (r < 0)
|
|
||||||
return log_link_error_errno(link, r, "Could not append NHA_BLACKHOLE attribute: %m");
|
|
||||||
} else {
|
|
||||||
r = sd_netlink_message_append_u32(req, NHA_OIF, link->ifindex);
|
r = sd_netlink_message_append_u32(req, NHA_OIF, link->ifindex);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "Could not append NHA_OIF attribute: %m");
|
return log_link_error_errno(link, r, "Could not append NHA_OIF attribute: %m");
|
||||||
@ -413,7 +368,6 @@ static int nexthop_configure(const NextHop *nexthop, Link *link) {
|
|||||||
return log_link_error_errno(link, r, "Failed to set RTNH_F_ONLINK flag: %m");
|
return log_link_error_errno(link, r, "Failed to set RTNH_F_ONLINK flag: %m");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
r = netlink_call_async(link->manager->rtnl, NULL, req, nexthop_handler,
|
r = netlink_call_async(link->manager->rtnl, NULL, req, nexthop_handler,
|
||||||
link_netlink_destroy_callback, link);
|
link_netlink_destroy_callback, link);
|
||||||
@ -477,7 +431,7 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
|
|||||||
NextHop *nexthop = NULL;
|
NextHop *nexthop = NULL;
|
||||||
uint32_t ifindex;
|
uint32_t ifindex;
|
||||||
uint16_t type;
|
uint16_t type;
|
||||||
Link *link = NULL;
|
Link *link;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(rtnl);
|
assert(rtnl);
|
||||||
@ -502,11 +456,13 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
|
|||||||
}
|
}
|
||||||
|
|
||||||
r = sd_netlink_message_read_u32(message, NHA_OIF, &ifindex);
|
r = sd_netlink_message_read_u32(message, NHA_OIF, &ifindex);
|
||||||
if (r < 0 && r != -ENODATA) {
|
if (r == -ENODATA) {
|
||||||
|
log_warning_errno(r, "rtnl: received nexthop message without NHA_OIF attribute, ignoring: %m");
|
||||||
|
return 0;
|
||||||
|
} else if (r < 0) {
|
||||||
log_warning_errno(r, "rtnl: could not get NHA_OIF attribute, ignoring: %m");
|
log_warning_errno(r, "rtnl: could not get NHA_OIF attribute, ignoring: %m");
|
||||||
return 0;
|
return 0;
|
||||||
} else if (r >= 0) {
|
} else if (ifindex <= 0) {
|
||||||
if (ifindex <= 0) {
|
|
||||||
log_warning("rtnl: received nexthop message with invalid ifindex %"PRIu32", ignoring.", ifindex);
|
log_warning("rtnl: received nexthop message with invalid ifindex %"PRIu32", ignoring.", ifindex);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -517,7 +473,6 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
|
|||||||
log_warning("rtnl: received nexthop message for link (%"PRIu32") we do not know about, ignoring", ifindex);
|
log_warning("rtnl: received nexthop message for link (%"PRIu32") we do not know about, ignoring", ifindex);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
r = nexthop_new(&tmp);
|
r = nexthop_new(&tmp);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -536,13 +491,6 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = sd_netlink_message_has_flag(message, NHA_BLACKHOLE);
|
|
||||||
if (r < 0) {
|
|
||||||
log_link_warning_errno(link, r, "rtnl: could not get NHA_BLACKHOLE attribute, ignoring: %m");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
tmp->blackhole = r;
|
|
||||||
|
|
||||||
r = sd_netlink_message_read_u32(message, NHA_ID, &tmp->id);
|
r = sd_netlink_message_read_u32(message, NHA_ID, &tmp->id);
|
||||||
if (r == -ENODATA) {
|
if (r == -ENODATA) {
|
||||||
log_link_warning_errno(link, r, "rtnl: received nexthop message without NHA_ID attribute, ignoring: %m");
|
log_link_warning_errno(link, r, "rtnl: received nexthop message without NHA_ID attribute, ignoring: %m");
|
||||||
@ -555,12 +503,7 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* All blackhole nexthops are managed by Manager. Note that the linux kernel does not set
|
r = nexthop_get(link, tmp, &nexthop);
|
||||||
* NHA_OID attribute when NHA_BLACKHOLE is set. Just for safety. */
|
|
||||||
if (tmp->blackhole)
|
|
||||||
link = NULL;
|
|
||||||
|
|
||||||
r = nexthop_get(m, link, tmp, &nexthop);
|
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
|
|
||||||
@ -569,7 +512,7 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
|
|||||||
id = tmp->id;
|
id = tmp->id;
|
||||||
tmp->id = 0;
|
tmp->id = 0;
|
||||||
|
|
||||||
(void) nexthop_get(m, link, tmp, &nexthop);
|
(void) nexthop_get(link, tmp, &nexthop);
|
||||||
|
|
||||||
tmp->id = id;
|
tmp->id = id;
|
||||||
}
|
}
|
||||||
@ -580,14 +523,14 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
|
|||||||
log_nexthop_debug(nexthop, tmp->id, "Received remembered", link);
|
log_nexthop_debug(nexthop, tmp->id, "Received remembered", link);
|
||||||
else {
|
else {
|
||||||
log_nexthop_debug(tmp, tmp->id, "Remembering foreign", link);
|
log_nexthop_debug(tmp, tmp->id, "Remembering foreign", link);
|
||||||
r = nexthop_add_foreign(m, link, tmp, &nexthop);
|
r = nexthop_add_foreign(link, tmp, &nexthop);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_link_warning_errno(link, r, "Could not remember foreign nexthop, ignoring: %m");
|
log_link_warning_errno(link, r, "Could not remember foreign nexthop, ignoring: %m");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r = nexthop_update(m, link, nexthop, tmp);
|
r = nexthop_update(link, nexthop, tmp);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_link_warning_errno(link, r, "Could not update nexthop, ignoring: %m");
|
log_link_warning_errno(link, r, "Could not update nexthop, ignoring: %m");
|
||||||
return 0;
|
return 0;
|
||||||
@ -613,12 +556,6 @@ static int nexthop_section_verify(NextHop *nh) {
|
|||||||
/* When no Gateway= is specified, assume IPv4. */
|
/* When no Gateway= is specified, assume IPv4. */
|
||||||
nh->family = AF_INET;
|
nh->family = AF_INET;
|
||||||
|
|
||||||
if (nh->blackhole && in_addr_is_set(nh->family, &nh->gw))
|
|
||||||
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
|
|
||||||
"%s: blackhole nexthop cannot have gateway address. "
|
|
||||||
"Ignoring [NextHop] section from line %u.",
|
|
||||||
nh->section->filename, nh->section->line);
|
|
||||||
|
|
||||||
if (nh->onlink < 0 && in_addr_is_set(nh->family, &nh->gw) &&
|
if (nh->onlink < 0 && in_addr_is_set(nh->family, &nh->gw) &&
|
||||||
ordered_hashmap_isempty(nh->network->addresses_by_section)) {
|
ordered_hashmap_isempty(nh->network->addresses_by_section)) {
|
||||||
/* If no address is configured, in most cases the gateway cannot be reachable.
|
/* If no address is configured, in most cases the gateway cannot be reachable.
|
||||||
@ -847,42 +784,3 @@ int config_parse_nexthop_onlink(
|
|||||||
TAKE_PTR(n);
|
TAKE_PTR(n);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int config_parse_nexthop_blackhole(
|
|
||||||
const char *unit,
|
|
||||||
const char *filename,
|
|
||||||
unsigned line,
|
|
||||||
const char *section,
|
|
||||||
unsigned section_line,
|
|
||||||
const char *lvalue,
|
|
||||||
int ltype,
|
|
||||||
const char *rvalue,
|
|
||||||
void *data,
|
|
||||||
void *userdata) {
|
|
||||||
|
|
||||||
_cleanup_(nexthop_free_or_set_invalidp) NextHop *n = NULL;
|
|
||||||
Network *network = userdata;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(filename);
|
|
||||||
assert(section);
|
|
||||||
assert(lvalue);
|
|
||||||
assert(rvalue);
|
|
||||||
assert(data);
|
|
||||||
|
|
||||||
r = nexthop_new_static(network, filename, section_line, &n);
|
|
||||||
if (r < 0)
|
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
r = parse_boolean(rvalue);
|
|
||||||
if (r < 0) {
|
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
|
||||||
"Failed to parse %s=, ignoring assignment: %s", lvalue, rvalue);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
n->blackhole = r;
|
|
||||||
|
|
||||||
TAKE_PTR(n);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|||||||
@ -20,13 +20,11 @@ typedef struct NextHop {
|
|||||||
Network *network;
|
Network *network;
|
||||||
NetworkConfigSection *section;
|
NetworkConfigSection *section;
|
||||||
|
|
||||||
Manager *manager;
|
|
||||||
Link *link;
|
Link *link;
|
||||||
|
|
||||||
unsigned char protocol;
|
unsigned char protocol;
|
||||||
|
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
bool blackhole;
|
|
||||||
int family;
|
int family;
|
||||||
union in_addr_union gw;
|
union in_addr_union gw;
|
||||||
int onlink;
|
int onlink;
|
||||||
@ -45,4 +43,3 @@ CONFIG_PARSER_PROTOTYPE(config_parse_nexthop_id);
|
|||||||
CONFIG_PARSER_PROTOTYPE(config_parse_nexthop_gateway);
|
CONFIG_PARSER_PROTOTYPE(config_parse_nexthop_gateway);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_nexthop_family);
|
CONFIG_PARSER_PROTOTYPE(config_parse_nexthop_family);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_nexthop_onlink);
|
CONFIG_PARSER_PROTOTYPE(config_parse_nexthop_onlink);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_nexthop_blackhole);
|
|
||||||
|
|||||||
@ -451,19 +451,35 @@ static int route_get(const Manager *manager, const Link *link, const Route *in,
|
|||||||
assert(manager || link);
|
assert(manager || link);
|
||||||
assert(in);
|
assert(in);
|
||||||
|
|
||||||
existing = set_get(link ? link->routes : manager->routes, in);
|
if (link) {
|
||||||
|
existing = set_get(link->routes, in);
|
||||||
if (existing) {
|
if (existing) {
|
||||||
if (ret)
|
if (ret)
|
||||||
*ret = existing;
|
*ret = existing;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
existing = set_get(link ? link->routes_foreign : manager->routes_foreign, in);
|
existing = set_get(link->routes_foreign, in);
|
||||||
if (existing) {
|
if (existing) {
|
||||||
if (ret)
|
if (ret)
|
||||||
*ret = existing;
|
*ret = existing;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
existing = set_get(manager->routes, in);
|
||||||
|
if (existing) {
|
||||||
|
if (ret)
|
||||||
|
*ret = existing;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
existing = set_get(manager->routes_foreign, in);
|
||||||
|
if (existing) {
|
||||||
|
if (ret)
|
||||||
|
*ret = existing;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
@ -472,8 +488,6 @@ static void route_copy(Route *dest, const Route *src, const MultipathRoute *m, c
|
|||||||
assert(dest);
|
assert(dest);
|
||||||
assert(src);
|
assert(src);
|
||||||
|
|
||||||
/* This only copies entries used by the above hash and compare functions. */
|
|
||||||
|
|
||||||
dest->family = src->family;
|
dest->family = src->family;
|
||||||
dest->src = src->src;
|
dest->src = src->src;
|
||||||
dest->src_prefixlen = src->src_prefixlen;
|
dest->src_prefixlen = src->src_prefixlen;
|
||||||
@ -482,9 +496,6 @@ static void route_copy(Route *dest, const Route *src, const MultipathRoute *m, c
|
|||||||
dest->prefsrc = src->prefsrc;
|
dest->prefsrc = src->prefsrc;
|
||||||
dest->scope = src->scope;
|
dest->scope = src->scope;
|
||||||
dest->protocol = src->protocol;
|
dest->protocol = src->protocol;
|
||||||
if (nh && nh->blackhole)
|
|
||||||
dest->type = RTN_BLACKHOLE;
|
|
||||||
else
|
|
||||||
dest->type = src->type;
|
dest->type = src->type;
|
||||||
dest->tos = src->tos;
|
dest->tos = src->tos;
|
||||||
dest->priority = src->priority;
|
dest->priority = src->priority;
|
||||||
@ -582,11 +593,19 @@ static int route_add(Manager *manager, Link *link, const Route *in, const Multip
|
|||||||
is_new = true;
|
is_new = true;
|
||||||
} else if (r == 0) {
|
} else if (r == 0) {
|
||||||
/* Take over a foreign route */
|
/* Take over a foreign route */
|
||||||
r = set_ensure_put(link ? &link->routes : &manager->routes, &route_hash_ops, route);
|
if (link) {
|
||||||
|
r = set_ensure_put(&link->routes, &route_hash_ops, route);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
set_remove(link ? link->routes_foreign : manager->routes_foreign, route);
|
set_remove(link->routes_foreign, route);
|
||||||
|
} else {
|
||||||
|
r = set_ensure_put(&manager->routes, &route_hash_ops, route);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
set_remove(manager->routes_foreign, route);
|
||||||
|
}
|
||||||
} else if (r == 1) {
|
} else if (r == 1) {
|
||||||
/* Route exists, do nothing */
|
/* Route exists, do nothing */
|
||||||
;
|
;
|
||||||
@ -962,8 +981,8 @@ static int route_add_and_setup_timer(Link *link, const Route *route, const Multi
|
|||||||
|
|
||||||
(void) manager_get_nexthop_by_id(link->manager, route->nexthop_id, &nh);
|
(void) manager_get_nexthop_by_id(link->manager, route->nexthop_id, &nh);
|
||||||
|
|
||||||
if (route_type_is_reject(route) || (nh && nh->blackhole))
|
if (route_type_is_reject(route))
|
||||||
k = route_add(link->manager, NULL, route, NULL, nh, &nr);
|
k = route_add(link->manager, NULL, route, NULL, NULL, &nr);
|
||||||
else if (!m || m->ifindex == 0 || m->ifindex == link->ifindex)
|
else if (!m || m->ifindex == 0 || m->ifindex == link->ifindex)
|
||||||
k = route_add(NULL, link, route, m, nh, &nr);
|
k = route_add(NULL, link, route, m, nh, &nr);
|
||||||
else {
|
else {
|
||||||
|
|||||||
@ -532,7 +532,7 @@ int dissect_image(
|
|||||||
if (!S_ISBLK(st.st_mode))
|
if (!S_ISBLK(st.st_mode))
|
||||||
return -ENOTBLK;
|
return -ENOTBLK;
|
||||||
|
|
||||||
r = sd_device_new_from_stat_rdev(&d, &st);
|
r = sd_device_new_from_devnum(&d, 'b', st.st_rdev);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
|||||||
@ -136,7 +136,7 @@ static int device_new_from_dev_path(const char *devlink, sd_device **ret_device)
|
|||||||
return log_error_errno(SYNTHETIC_ERRNO(ENOTBLK),
|
return log_error_errno(SYNTHETIC_ERRNO(ENOTBLK),
|
||||||
"%s does not point to a block device: %m", devlink);
|
"%s does not point to a block device: %m", devlink);
|
||||||
|
|
||||||
r = sd_device_new_from_stat_rdev(ret_device, &st);
|
r = sd_device_new_from_devnum(ret_device, 'b', st.st_rdev);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to initialize device from %s: %m", devlink);
|
return log_error_errno(r, "Failed to initialize device from %s: %m", devlink);
|
||||||
|
|
||||||
|
|||||||
@ -353,7 +353,6 @@ Id=
|
|||||||
Gateway=
|
Gateway=
|
||||||
Family=
|
Family=
|
||||||
OnLink=
|
OnLink=
|
||||||
Blackhole=
|
|
||||||
[QDisc]
|
[QDisc]
|
||||||
Parent=
|
Parent=
|
||||||
Handle=
|
Handle=
|
||||||
|
|||||||
Binary file not shown.
@ -28,27 +28,9 @@ Id=5
|
|||||||
Gateway=192.168.10.1
|
Gateway=192.168.10.1
|
||||||
OnLink=yes
|
OnLink=yes
|
||||||
|
|
||||||
[NextHop]
|
|
||||||
Id=6
|
|
||||||
Family=ipv4
|
|
||||||
Blackhole=yes
|
|
||||||
|
|
||||||
[NextHop]
|
|
||||||
Id=7
|
|
||||||
Family=ipv6
|
|
||||||
Blackhole=yes
|
|
||||||
|
|
||||||
[NextHop]
|
[NextHop]
|
||||||
Gateway=192.168.5.2
|
Gateway=192.168.5.2
|
||||||
|
|
||||||
[NextHop]
|
|
||||||
Family=ipv4
|
|
||||||
Blackhole=yes
|
|
||||||
|
|
||||||
[NextHop]
|
|
||||||
Family=ipv6
|
|
||||||
Blackhole=yes
|
|
||||||
|
|
||||||
[Route]
|
[Route]
|
||||||
NextHop=1
|
NextHop=1
|
||||||
Destination=10.10.10.10
|
Destination=10.10.10.10
|
||||||
@ -64,11 +46,3 @@ Destination=2001:1234:5:8f62::1
|
|||||||
[Route]
|
[Route]
|
||||||
NextHop=5
|
NextHop=5
|
||||||
Destination=10.10.10.12
|
Destination=10.10.10.12
|
||||||
|
|
||||||
[Route]
|
|
||||||
NextHop=6
|
|
||||||
Destination=10.10.10.13
|
|
||||||
|
|
||||||
[Route]
|
|
||||||
NextHop=7
|
|
||||||
Destination=2001:1234:5:8f62::2
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@ Name=wg99
|
|||||||
Kind=wireguard
|
Kind=wireguard
|
||||||
|
|
||||||
[WireGuard]
|
[WireGuard]
|
||||||
|
PrivateKey=EEGlnEPYJV//kbvvIqxKkQwOiS+UENyPncC4bF46ong=
|
||||||
ListenPort=51820
|
ListenPort=51820
|
||||||
FwMark=1234
|
FwMark=1234
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +0,0 @@
|
|||||||
[WireGuardPeer]
|
|
||||||
PublicKey=TTiCUpCxS7zDn/ax4p5W6Evg41r8hOrnWQw2Sq6Nh10=
|
|
||||||
PresharedKey=it7nd33chCT/tKT2ZZWfYyp43Zs+6oif72hexnSNMqA=
|
|
||||||
|
|
||||||
AllowedIPs=192.168.124.2
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
[WireGuardPeer]
|
|
||||||
PublicKey=9uioxkGzjvGjkse3V35I9AhorWfIjBcrf3UPMS0bw2c=
|
|
||||||
PresharedKey=6Fsg8XN0DE6aPQgAX4r2oazEYJOGqyHUz3QRH/jCB+I=
|
|
||||||
|
|
||||||
AllowedIPs=192.168.124.3
|
|
||||||
@ -1,2 +0,0 @@
|
|||||||
[WireGuard]
|
|
||||||
PrivateKey=EEGlnEPYJV//kbvvIqxKkQwOiS+UENyPncC4bF46ong=
|
|
||||||
@ -1,5 +1,2 @@
|
|||||||
[Match]
|
[Match]
|
||||||
Name=wg99
|
Name=wg99
|
||||||
|
|
||||||
[Network]
|
|
||||||
Address=192.168.124.1/24
|
|
||||||
|
|||||||
@ -404,13 +404,6 @@ def remove_routes(routes):
|
|||||||
for route_type, addr in routes:
|
for route_type, addr in routes:
|
||||||
call('ip route del', route_type, addr, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
call('ip route del', route_type, addr, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||||
|
|
||||||
def remove_blackhole_nexthops():
|
|
||||||
ret = run('ip nexthop show dev lo', stdout=subprocess.PIPE, stderr=subprocess.DEVNULL)
|
|
||||||
if ret.returncode == 0:
|
|
||||||
for line in ret.stdout.rstrip().splitlines():
|
|
||||||
id = line.split()[1]
|
|
||||||
call(f'ip nexthop del id {id}')
|
|
||||||
|
|
||||||
def remove_l2tp_tunnels(tunnel_ids):
|
def remove_l2tp_tunnels(tunnel_ids):
|
||||||
output = check_output('ip l2tp show tunnel')
|
output = check_output('ip l2tp show tunnel')
|
||||||
for tid in tunnel_ids:
|
for tid in tunnel_ids:
|
||||||
@ -1225,11 +1218,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
|||||||
'25-wireguard-preshared-key.txt', '25-wireguard-private-key.txt',
|
'25-wireguard-preshared-key.txt', '25-wireguard-private-key.txt',
|
||||||
'25-wireguard-no-peer.netdev', '25-wireguard-no-peer.network')
|
'25-wireguard-no-peer.netdev', '25-wireguard-no-peer.network')
|
||||||
start_networkd()
|
start_networkd()
|
||||||
self.wait_online(['wg99:routable', 'wg98:routable', 'wg97:carrier'])
|
self.wait_online(['wg99:carrier', 'wg98:routable', 'wg97:carrier'])
|
||||||
|
|
||||||
output = check_output('ip -4 address show dev wg99')
|
|
||||||
print(output)
|
|
||||||
self.assertIn('inet 192.168.124.1/24 scope global wg99', output)
|
|
||||||
|
|
||||||
output = check_output('ip -4 address show dev wg98')
|
output = check_output('ip -4 address show dev wg98')
|
||||||
print(output)
|
print(output)
|
||||||
@ -1243,39 +1232,29 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
|||||||
call('wg')
|
call('wg')
|
||||||
|
|
||||||
output = check_output('wg show wg99 listen-port')
|
output = check_output('wg show wg99 listen-port')
|
||||||
self.assertEqual(output, '51820')
|
self.assertRegex(output, '51820')
|
||||||
output = check_output('wg show wg99 fwmark')
|
output = check_output('wg show wg99 fwmark')
|
||||||
self.assertEqual(output, '0x4d2')
|
self.assertRegex(output, '0x4d2')
|
||||||
output = check_output('wg show wg99 private-key')
|
|
||||||
self.assertEqual(output, 'EEGlnEPYJV//kbvvIqxKkQwOiS+UENyPncC4bF46ong=')
|
|
||||||
output = check_output('wg show wg99 allowed-ips')
|
output = check_output('wg show wg99 allowed-ips')
|
||||||
self.assertIn('9uioxkGzjvGjkse3V35I9AhorWfIjBcrf3UPMS0bw2c=\t192.168.124.3/32', output)
|
self.assertRegex(output, r'RDf\+LSpeEre7YEIKaxg\+wbpsNV7du\+ktR99uBEtIiCA=\t192.168.26.0/24 fd31:bf08:57cb::/48')
|
||||||
self.assertIn('TTiCUpCxS7zDn/ax4p5W6Evg41r8hOrnWQw2Sq6Nh10=\t192.168.124.2/32', output)
|
self.assertRegex(output, r'lsDtM3AbjxNlauRKzHEPfgS1Zp7cp/VX5Use/P4PQSc=\tfdbc:bae2:7871:e1fe:793:8636::/96 fdbc:bae2:7871:500:e1fe:793:8636:dad1/128')
|
||||||
self.assertIn('lsDtM3AbjxNlauRKzHEPfgS1Zp7cp/VX5Use/P4PQSc=\tfdbc:bae2:7871:e1fe:793:8636::/96 fdbc:bae2:7871:500:e1fe:793:8636:dad1/128', output)
|
|
||||||
self.assertIn('RDf+LSpeEre7YEIKaxg+wbpsNV7du+ktR99uBEtIiCA=\t192.168.26.0/24 fd31:bf08:57cb::/48', output)
|
|
||||||
output = check_output('wg show wg99 persistent-keepalive')
|
output = check_output('wg show wg99 persistent-keepalive')
|
||||||
self.assertIn('9uioxkGzjvGjkse3V35I9AhorWfIjBcrf3UPMS0bw2c=\toff', output)
|
self.assertRegex(output, r'RDf\+LSpeEre7YEIKaxg\+wbpsNV7du\+ktR99uBEtIiCA=\t20')
|
||||||
self.assertIn('TTiCUpCxS7zDn/ax4p5W6Evg41r8hOrnWQw2Sq6Nh10=\toff', output)
|
|
||||||
self.assertIn('lsDtM3AbjxNlauRKzHEPfgS1Zp7cp/VX5Use/P4PQSc=\toff', output)
|
|
||||||
self.assertIn('RDf+LSpeEre7YEIKaxg+wbpsNV7du+ktR99uBEtIiCA=\t20', output)
|
|
||||||
output = check_output('wg show wg99 endpoints')
|
output = check_output('wg show wg99 endpoints')
|
||||||
self.assertIn('9uioxkGzjvGjkse3V35I9AhorWfIjBcrf3UPMS0bw2c=\t(none)', output)
|
self.assertRegex(output, r'RDf\+LSpeEre7YEIKaxg\+wbpsNV7du\+ktR99uBEtIiCA=\t192.168.27.3:51820')
|
||||||
self.assertIn('TTiCUpCxS7zDn/ax4p5W6Evg41r8hOrnWQw2Sq6Nh10=\t(none)', output)
|
output = check_output('wg show wg99 private-key')
|
||||||
self.assertIn('lsDtM3AbjxNlauRKzHEPfgS1Zp7cp/VX5Use/P4PQSc=\t(none)', output)
|
self.assertRegex(output, r'EEGlnEPYJV//kbvvIqxKkQwOiS\+UENyPncC4bF46ong=')
|
||||||
self.assertIn('RDf+LSpeEre7YEIKaxg+wbpsNV7du+ktR99uBEtIiCA=\t192.168.27.3:51820', output)
|
|
||||||
output = check_output('wg show wg99 preshared-keys')
|
output = check_output('wg show wg99 preshared-keys')
|
||||||
self.assertIn('9uioxkGzjvGjkse3V35I9AhorWfIjBcrf3UPMS0bw2c=\t6Fsg8XN0DE6aPQgAX4r2oazEYJOGqyHUz3QRH/jCB+I=', output)
|
self.assertRegex(output, r'RDf\+LSpeEre7YEIKaxg\+wbpsNV7du\+ktR99uBEtIiCA= IIWIV17wutHv7t4cR6pOT91z6NSz/T8Arh0yaywhw3M=')
|
||||||
self.assertIn('TTiCUpCxS7zDn/ax4p5W6Evg41r8hOrnWQw2Sq6Nh10=\tit7nd33chCT/tKT2ZZWfYyp43Zs+6oif72hexnSNMqA=', output)
|
self.assertRegex(output, r'lsDtM3AbjxNlauRKzHEPfgS1Zp7cp/VX5Use/P4PQSc= cPLOy1YUrEI0EMMIycPJmOo0aTu3RZnw8bL5meVD6m0=')
|
||||||
self.assertIn('lsDtM3AbjxNlauRKzHEPfgS1Zp7cp/VX5Use/P4PQSc=\tcPLOy1YUrEI0EMMIycPJmOo0aTu3RZnw8bL5meVD6m0=', output)
|
|
||||||
self.assertIn('RDf+LSpeEre7YEIKaxg+wbpsNV7du+ktR99uBEtIiCA=\tIIWIV17wutHv7t4cR6pOT91z6NSz/T8Arh0yaywhw3M=', output)
|
|
||||||
|
|
||||||
output = check_output('wg show wg98 private-key')
|
output = check_output('wg show wg98 private-key')
|
||||||
self.assertEqual(output, 'CJQUtcS9emY2fLYqDlpSZiE/QJyHkPWr+WHtZLZ90FU=')
|
self.assertRegex(output, r'CJQUtcS9emY2fLYqDlpSZiE/QJyHkPWr\+WHtZLZ90FU=')
|
||||||
|
|
||||||
output = check_output('wg show wg97 listen-port')
|
output = check_output('wg show wg97 listen-port')
|
||||||
self.assertEqual(output, '51821')
|
self.assertRegex(output, '51821')
|
||||||
output = check_output('wg show wg97 fwmark')
|
output = check_output('wg show wg97 fwmark')
|
||||||
self.assertEqual(output, '0x4d3')
|
self.assertRegex(output, '0x4d3')
|
||||||
|
|
||||||
def test_geneve(self):
|
def test_geneve(self):
|
||||||
copy_unit_to_networkd_unit_path('25-geneve.netdev', 'netdev-link-local-addressing-yes.network')
|
copy_unit_to_networkd_unit_path('25-geneve.netdev', 'netdev-link-local-addressing-yes.network')
|
||||||
@ -1838,14 +1817,12 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
|||||||
routes = [['blackhole', '202.54.1.2'], ['unreachable', '202.54.1.3'], ['prohibit', '202.54.1.4']]
|
routes = [['blackhole', '202.54.1.2'], ['unreachable', '202.54.1.3'], ['prohibit', '202.54.1.4']]
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
remove_blackhole_nexthops()
|
|
||||||
remove_routing_policy_rule_tables(self.routing_policy_rule_tables)
|
remove_routing_policy_rule_tables(self.routing_policy_rule_tables)
|
||||||
remove_routes(self.routes)
|
remove_routes(self.routes)
|
||||||
remove_links(self.links)
|
remove_links(self.links)
|
||||||
stop_networkd(show_logs=False)
|
stop_networkd(show_logs=False)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
remove_blackhole_nexthops()
|
|
||||||
remove_routing_policy_rule_tables(self.routing_policy_rule_tables)
|
remove_routing_policy_rule_tables(self.routing_policy_rule_tables)
|
||||||
remove_routes(self.routes)
|
remove_routes(self.routes)
|
||||||
remove_links(self.links)
|
remove_links(self.links)
|
||||||
@ -2838,12 +2815,6 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
|||||||
self.assertRegex(output, 'id 5 via 192.168.10.1 dev veth99 .*onlink')
|
self.assertRegex(output, 'id 5 via 192.168.10.1 dev veth99 .*onlink')
|
||||||
self.assertRegex(output, r'id [0-9]* via 192.168.5.2 dev veth99')
|
self.assertRegex(output, r'id [0-9]* via 192.168.5.2 dev veth99')
|
||||||
|
|
||||||
# kernel manages blackhole nexthops on lo
|
|
||||||
output = check_output('ip nexthop list dev lo')
|
|
||||||
print(output)
|
|
||||||
self.assertIn('id 6 blackhole', output)
|
|
||||||
self.assertIn('id 7 blackhole', output)
|
|
||||||
|
|
||||||
output = check_output('ip route show dev veth99 10.10.10.10')
|
output = check_output('ip route show dev veth99 10.10.10.10')
|
||||||
print(output)
|
print(output)
|
||||||
self.assertEqual('10.10.10.10 nhid 1 via 192.168.5.1 proto static', output)
|
self.assertEqual('10.10.10.10 nhid 1 via 192.168.5.1 proto static', output)
|
||||||
@ -2860,14 +2831,6 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
|||||||
print(output)
|
print(output)
|
||||||
self.assertEqual('2001:1234:5:8f62::1 nhid 2 via 2001:1234:5:8f63::2 proto static metric 1024 pref medium', output)
|
self.assertEqual('2001:1234:5:8f62::1 nhid 2 via 2001:1234:5:8f63::2 proto static metric 1024 pref medium', output)
|
||||||
|
|
||||||
output = check_output('ip route show 10.10.10.13')
|
|
||||||
print(output)
|
|
||||||
self.assertEqual('blackhole 10.10.10.13 nhid 6 dev lo proto static', output)
|
|
||||||
|
|
||||||
output = check_output('ip -6 route show 2001:1234:5:8f62::2')
|
|
||||||
print(output)
|
|
||||||
self.assertEqual('blackhole 2001:1234:5:8f62::2 nhid 7 dev lo proto static metric 1024 pref medium', output)
|
|
||||||
|
|
||||||
def test_qdisc(self):
|
def test_qdisc(self):
|
||||||
copy_unit_to_networkd_unit_path('25-qdisc-clsact-and-htb.network', '12-dummy.netdev',
|
copy_unit_to_networkd_unit_path('25-qdisc-clsact-and-htb.network', '12-dummy.netdev',
|
||||||
'25-qdisc-ingress-netem-compat.network', '11-dummy.netdev')
|
'25-qdisc-ingress-netem-compat.network', '11-dummy.netdev')
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user