mirror of
https://github.com/systemd/systemd
synced 2026-03-09 22:54:56 +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?
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
@ -2408,9 +2408,7 @@ SystemCallErrorNumber=EPERM</programlisting>
|
||||
<citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry> for more
|
||||
details about named file descriptors and their ordering.</para>
|
||||
|
||||
<para>This setting defaults to <option>null</option>, unless
|
||||
<varname>StandardInputText=</varname>/<varname>StandardInputData=</varname> are set, in which case it
|
||||
defaults to <option>data</option>.</para></listitem>
|
||||
<para>This setting defaults to <option>null</option>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
@ -2524,11 +2522,9 @@ SystemCallErrorNumber=EPERM</programlisting>
|
||||
<term><varname>StandardInputText=</varname></term>
|
||||
<term><varname>StandardInputData=</varname></term>
|
||||
|
||||
<listitem><para>Configures arbitrary textual or binary data to pass via file descriptor 0 (STDIN) to
|
||||
the executed processes. These settings have no effect unless <varname>StandardInput=</varname> is set
|
||||
to <option>data</option> (which is the default if <varname>StandardInput=</varname> is not set
|
||||
otherwise, but <varname>StandardInputText=</varname>/<varname>StandardInputData=</varname> is). Use
|
||||
this option to embed process input data directly in the unit file.</para>
|
||||
<listitem><para>Configures arbitrary textual or binary data to pass via file descriptor 0 (STDIN) to the
|
||||
executed processes. These settings have no effect unless <varname>StandardInput=</varname> is set to
|
||||
<option>data</option>. 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
|
||||
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>
|
||||
</listitem>
|
||||
</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>
|
||||
</refsect1>
|
||||
|
||||
|
||||
@ -1063,32 +1063,28 @@
|
||||
<refsect2>
|
||||
<title>Conditions and Asserts</title>
|
||||
|
||||
<para>Unit files may also include a number of <varname index="false">Condition…=</varname> and <varname
|
||||
index="false">Assert…=</varname> settings. Before the unit is started, systemd will verify that the
|
||||
specified conditions and asserts 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
|
||||
conditions or asserts will not result in the unit being moved into the <literal>failed</literal>
|
||||
state. The conditions and asserts are checked at the time the queued start job is to be executed. The
|
||||
ordering dependencies are still respected, so other units are still pulled in and ordered as if this
|
||||
unit was successfully activated, and the conditions and asserts are executed the precise moment the
|
||||
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>Unit files may also include a number of <varname index="false">Condition…=</varname> and
|
||||
<varname index="false">Assert…=</varname> settings. Before the unit is started, systemd will verify
|
||||
that the specified conditions are true. If not, the starting of the unit will be (mostly silently)
|
||||
skipped. Failing conditions 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
|
||||
dependencies are still respected, so other units are still pulled in and ordered as if this unit was
|
||||
successfully activated. Use condition expressions in order to skip units that do not apply to the local
|
||||
system, for example because the kernel or runtime environment doesn't require their functionality.
|
||||
</para>
|
||||
|
||||
<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
|
||||
sign (<literal>Condition…=|…</literal>), which causes the condition to become a
|
||||
<emphasis>triggering</emphasis> condition. If at least one triggering condition is defined for a unit,
|
||||
then the unit will be started if at least one of the triggering conditions of the unit applies and all
|
||||
of the regular (i.e. non-triggering) conditions apply. If you prefix an argument with the pipe symbol
|
||||
and an exclamation mark, the pipe symbol must be passed first, the exclamation second. If any of these
|
||||
options is assigned the empty string, the list of conditions is reset completely, all previous
|
||||
condition settings (of any kind) will have no effect.</para>
|
||||
sign (<literal>Condition…=|…</literal>), which causes the condition becomes a triggering condition. If
|
||||
at least one triggering condition is defined for a unit, then the unit will be executed if at least one
|
||||
of the triggering conditions apply and all of the non-triggering conditions. If you prefix an argument
|
||||
with the pipe symbol and an exclamation mark, the pipe symbol must be passed first, the exclamation
|
||||
second. If any of these options is assigned the empty string, the list of conditions is reset
|
||||
completely, all previous condition settings (of any kind) will have no effect.</para>
|
||||
|
||||
<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
|
||||
is logged. Units with failed conditions are considered to be in a clean state and will be garbage
|
||||
provide a similar mechanism that causes the job to fail (instead of being skipped). The failed check is
|
||||
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
|
||||
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;
|
||||
|
||||
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! */
|
||||
return -EOPNOTSUPP;
|
||||
if (!STARTSWITH_SET(c, "-LVDS-", "-Embedded DisplayPort-"))
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
} else if (streq(subsystem, "pci") &&
|
||||
sd_device_get_sysattr_value(parent, "class", &value) >= 0) {
|
||||
@ -135,14 +137,19 @@ static int validate_device(sd_device *device) {
|
||||
|
||||
assert(device);
|
||||
|
||||
/* Verify whether we should actually care for a specific backlight device. For backlight devices
|
||||
* there might be multiple ways to access the same control: "firmware" (i.e. ACPI), "platform"
|
||||
* (i.e. via the machine's EC) and "raw" (via the graphics card). In general we should prefer
|
||||
* "firmware" (i.e. ACPI) or "platform" access over "raw" access, in order not to confuse the
|
||||
* BIOS/EC, and 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. */
|
||||
/* Verify whether we should actually care for a specific
|
||||
* backlight device. For backlight devices there might be
|
||||
* multiple ways to access the same control: "firmware"
|
||||
* (i.e. ACPI), "platform" (i.e. via the machine's EC) and
|
||||
* "raw" (via the graphics card). In general we should prefer
|
||||
* "firmware" (i.e. ACPI) or "platform" access over "raw"
|
||||
* access, in order not to confuse the BIOS/EC, and
|
||||
* 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);
|
||||
if (r < 0)
|
||||
@ -187,12 +194,13 @@ static int validate_device(sd_device *device) {
|
||||
!STR_IN_SET(v, "platform", "firmware"))
|
||||
continue;
|
||||
|
||||
/* OK, so there's another backlight device, and it's a platform or firmware device.
|
||||
* Let's see if we can verify it belongs to the same device as ours. */
|
||||
/* OK, so there's another backlight device, and it's a
|
||||
* 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)
|
||||
continue;
|
||||
|
||||
if (same_device(parent, other_parent) > 0) {
|
||||
if (same_device(parent, other_parent)) {
|
||||
const char *device_sysname = NULL, *other_sysname = NULL;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
unsigned new_brightness, min_brightness;
|
||||
const char *subsystem;
|
||||
@ -257,11 +270,6 @@ static int clamp_brightness(sd_device *device, bool saved, unsigned max_brightne
|
||||
assert(device);
|
||||
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);
|
||||
if (r < 0)
|
||||
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)
|
||||
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);
|
||||
|
||||
r = mkdir_p("/var/lib/systemd/backlight", 0755);
|
||||
@ -404,8 +409,9 @@ static int run(int argc, char *argv[]) {
|
||||
if (r < 0)
|
||||
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
|
||||
* with Asus mainboards that load the eeepc-wmi module. */
|
||||
/* If max_brightness is 0, then there is no actual backlight
|
||||
* device. This happens on desktops with Asus mainboards
|
||||
* that load the eeepc-wmi module. */
|
||||
if (get_max_brightness(device, &max_brightness) < 0)
|
||||
return 0;
|
||||
|
||||
@ -426,11 +432,14 @@ static int run(int argc, char *argv[]) {
|
||||
} else
|
||||
saved = strjoina("/var/lib/systemd/backlight/", escaped_ss, ":", escaped_sysname);
|
||||
|
||||
/* If there are multiple conflicting backlight devices, then their probing at boot-time might
|
||||
* happen in any order. This means the validity checking of the device then is not reliable,
|
||||
* since it might not see other devices conflicting 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 there are multiple conflicting backlight devices, then
|
||||
* their probing at boot-time might happen in any order. This
|
||||
* means the validity checking of the device then is not
|
||||
* reliable, since it might not see other devices conflicting
|
||||
* 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")) {
|
||||
_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);
|
||||
|
||||
} else
|
||||
assert_not_reached("Unknown verb.");
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown verb %s.", argv[1]);
|
||||
|
||||
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++) {
|
||||
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].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)
|
||||
fprintf(f, ":%s:%s",
|
||||
fprintf(f, "%s:%s",
|
||||
partition_designator_to_string(o->partition_designator),
|
||||
strempty(o->options));
|
||||
o->options);
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -419,6 +419,7 @@ static int parse_options(const char *options) {
|
||||
|
||||
static char* disk_description(const char *path) {
|
||||
static const char name_fields[] =
|
||||
"ID_PART_ENTRY_NAME\0"
|
||||
"DM_NAME\0"
|
||||
"ID_MODEL_FROM_DATABASE\0"
|
||||
"ID_MODEL\0";
|
||||
@ -426,7 +427,6 @@ static char* disk_description(const char *path) {
|
||||
_cleanup_(sd_device_unrefp) sd_device *device = NULL;
|
||||
const char *i, *name;
|
||||
struct stat st;
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
|
||||
@ -436,27 +436,9 @@ static char* disk_description(const char *path) {
|
||||
if (!S_ISBLK(st.st_mode))
|
||||
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;
|
||||
|
||||
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)
|
||||
if (sd_device_get_property_value(device, i, &name) >= 0 &&
|
||||
!isempty(name))
|
||||
|
||||
@ -287,7 +287,7 @@ static int run(int argc, char *argv[]) {
|
||||
"%s is not a block 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)
|
||||
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))
|
||||
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)
|
||||
return r;
|
||||
|
||||
|
||||
@ -929,7 +929,7 @@ static int umount_by_device(sd_bus *bus, const char *what) {
|
||||
return log_error_errno(SYNTHETIC_ERRNO(ENOTBLK),
|
||||
"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)
|
||||
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),
|
||||
"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)
|
||||
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",
|
||||
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)
|
||||
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_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);
|
||||
|
||||
sd_event_source_unref(m->speed_meter_event_source);
|
||||
|
||||
@ -64,10 +64,6 @@ struct Manager {
|
||||
/* Manage 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. */
|
||||
Set *routes;
|
||||
Set *routes_foreign;
|
||||
|
||||
@ -190,7 +190,6 @@ NextHop.Id, config_parse_nexthop_id,
|
||||
NextHop.Gateway, config_parse_nexthop_gateway, 0, 0
|
||||
NextHop.Family, config_parse_nexthop_family, 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.UseDNS, config_parse_dhcp_use_dns, 0, 0
|
||||
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));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -103,7 +95,6 @@ static void nexthop_hash_func(const NextHop *nexthop, struct siphash *state) {
|
||||
assert(nexthop);
|
||||
|
||||
siphash24_compress(&nexthop->id, sizeof(nexthop->id), state);
|
||||
siphash24_compress(&nexthop->blackhole, sizeof(nexthop->blackhole), state);
|
||||
siphash24_compress(&nexthop->family, sizeof(nexthop->family), state);
|
||||
|
||||
switch (nexthop->family) {
|
||||
@ -125,10 +116,6 @@ static int nexthop_compare_func(const NextHop *a, const NextHop *b) {
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
r = CMP(a->blackhole, b->blackhole);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
r = CMP(a->family, b->family);
|
||||
if (r != 0)
|
||||
return r;
|
||||
@ -146,18 +133,6 @@ DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(
|
||||
nexthop_compare_func,
|
||||
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) {
|
||||
NextHop *nh;
|
||||
|
||||
@ -175,20 +150,20 @@ int manager_get_nexthop_by_id(Manager *manager, uint32_t id, NextHop **ret) {
|
||||
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;
|
||||
|
||||
assert(manager || link);
|
||||
assert(link);
|
||||
assert(in);
|
||||
|
||||
existing = set_get(link ? link->nexthops : manager->nexthops, in);
|
||||
existing = set_get(link->nexthops, in);
|
||||
if (existing) {
|
||||
if (ret)
|
||||
*ret = existing;
|
||||
return 1;
|
||||
}
|
||||
|
||||
existing = set_get(link ? link->nexthops_foreign : manager->nexthops_foreign, in);
|
||||
existing = set_get(link->nexthops_foreign, in);
|
||||
if (existing) {
|
||||
if (ret)
|
||||
*ret = existing;
|
||||
@ -198,11 +173,11 @@ static int nexthop_get(Manager *manager, Link *link, const NextHop *in, NextHop
|
||||
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;
|
||||
int r;
|
||||
|
||||
assert(manager || link);
|
||||
assert(link);
|
||||
assert(nexthops);
|
||||
assert(in);
|
||||
|
||||
@ -210,7 +185,9 @@ static int nexthop_add_internal(Manager *manager, Link *link, Set **nexthops, co
|
||||
if (r < 0)
|
||||
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);
|
||||
if (r < 0)
|
||||
@ -219,7 +196,6 @@ static int nexthop_add_internal(Manager *manager, Link *link, Set **nexthops, co
|
||||
return -EEXIST;
|
||||
|
||||
nexthop->link = link;
|
||||
nexthop->manager = manager;
|
||||
|
||||
if (ret)
|
||||
*ret = nexthop;
|
||||
@ -228,9 +204,8 @@ static int nexthop_add_internal(Manager *manager, Link *link, Set **nexthops, co
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nexthop_add_foreign(Manager *manager, Link *link, const NextHop *in, NextHop **ret) {
|
||||
assert(manager || link);
|
||||
return nexthop_add_internal(manager, link, link ? &link->nexthops_foreign : &manager->nexthops_foreign, in, ret);
|
||||
static int nexthop_add_foreign(Link *link, const NextHop *in, NextHop **ret) {
|
||||
return nexthop_add_internal(link, &link->nexthops_foreign, in, 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;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(in);
|
||||
|
||||
if (in->blackhole)
|
||||
r = nexthop_get(link->manager, NULL, in, &nexthop);
|
||||
else
|
||||
r = nexthop_get(NULL, link, in, &nexthop);
|
||||
r = nexthop_get(link, in, &nexthop);
|
||||
if (r == -ENOENT) {
|
||||
/* NextHop does not exist, create a new one */
|
||||
r = nexthop_add_internal(link->manager,
|
||||
in->blackhole ? NULL : link,
|
||||
in->blackhole ? &link->manager->nexthops : &link->nexthops,
|
||||
in, &nexthop);
|
||||
r = nexthop_add_internal(link, &link->nexthops, in, &nexthop);
|
||||
if (r < 0)
|
||||
return r;
|
||||
is_new = true;
|
||||
} else if (r == 0) {
|
||||
/* Take over a foreign nexthop */
|
||||
r = set_ensure_put(in->blackhole ? &link->manager->nexthops : &link->nexthops,
|
||||
&nexthop_hash_ops, nexthop);
|
||||
r = set_ensure_put(&link->nexthops, &nexthop_hash_ops, nexthop);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
set_remove(in->blackhole ? link->manager->nexthops_foreign : link->nexthops_foreign, nexthop);
|
||||
set_remove(link->nexthops_foreign, nexthop);
|
||||
} else if (r == 1) {
|
||||
/* NextHop exists, do nothing */
|
||||
;
|
||||
@ -273,13 +238,11 @@ static int nexthop_add(Link *link, const NextHop *in, NextHop **ret) {
|
||||
return is_new;
|
||||
}
|
||||
|
||||
static int nexthop_update(Manager *manager, Link *link, NextHop *nexthop, const NextHop *in) {
|
||||
Set *nexthops;
|
||||
static int nexthop_update(Link *link, NextHop *nexthop, const NextHop *in) {
|
||||
int r;
|
||||
|
||||
/* link may be NULL. */
|
||||
|
||||
assert(manager);
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
assert(nexthop);
|
||||
assert(in);
|
||||
assert(in->id > 0);
|
||||
@ -292,21 +255,19 @@ static int nexthop_update(Manager *manager, Link *link, NextHop *nexthop, const
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
nexthops = link ? link->nexthops : manager->nexthops;
|
||||
|
||||
nexthop = set_remove(nexthops, nexthop);
|
||||
nexthop = set_remove(link->nexthops, nexthop);
|
||||
if (!nexthop)
|
||||
return -ENOENT;
|
||||
|
||||
nexthop->id = in->id;
|
||||
|
||||
r = set_put(nexthops, nexthop);
|
||||
r = set_put(link->nexthops, nexthop);
|
||||
if (r <= 0) {
|
||||
int k;
|
||||
|
||||
/* On failure, revert the change. */
|
||||
nexthop->id = 0;
|
||||
k = set_put(nexthops, nexthop);
|
||||
k = set_put(link->nexthops, nexthop);
|
||||
if (k <= 0) {
|
||||
nexthop_free(nexthop);
|
||||
return k < 0 ? k : -EEXIST;
|
||||
@ -316,14 +277,13 @@ static int nexthop_update(Manager *manager, Link *link, NextHop *nexthop, const
|
||||
}
|
||||
|
||||
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) {
|
||||
assert(nexthop);
|
||||
assert(str);
|
||||
|
||||
/* link may be NULL. */
|
||||
assert(link);
|
||||
|
||||
if (DEBUG_LOGGING) {
|
||||
_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);
|
||||
|
||||
if (nexthop->id == id)
|
||||
log_link_debug(link, "%s nexthop: id: %"PRIu32", gw: %s, blackhole: %s",
|
||||
str, nexthop->id, strna(gw), yes_no(nexthop->blackhole));
|
||||
log_link_debug(link, "%s nexthop: id: %"PRIu32", gw: %s",
|
||||
str, nexthop->id, strna(gw));
|
||||
else
|
||||
log_link_debug(link, "%s nexthop: id: %"PRIu32"→%"PRIu32", gw: %s, blackhole: %s",
|
||||
str, nexthop->id, id, strna(gw), yes_no(nexthop->blackhole));
|
||||
log_link_debug(link, "%s nexthop: id: %"PRIu32"→%"PRIu32", gw: %s",
|
||||
str, nexthop->id, id, strna(gw));
|
||||
}
|
||||
}
|
||||
|
||||
@ -393,25 +353,19 @@ static int nexthop_configure(const NextHop *nexthop, Link *link) {
|
||||
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);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append NHA_OIF attribute: %m");
|
||||
r = sd_netlink_message_append_u32(req, NHA_OIF, link->ifindex);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append NHA_OIF attribute: %m");
|
||||
|
||||
if (in_addr_is_set(nexthop->family, &nexthop->gw)) {
|
||||
r = netlink_message_append_in_addr_union(req, NHA_GATEWAY, nexthop->family, &nexthop->gw);
|
||||
if (in_addr_is_set(nexthop->family, &nexthop->gw)) {
|
||||
r = netlink_message_append_in_addr_union(req, NHA_GATEWAY, nexthop->family, &nexthop->gw);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append NHA_GATEWAY attribute: %m");
|
||||
|
||||
if (nexthop->onlink > 0) {
|
||||
r = sd_rtnl_message_nexthop_set_flags(req, RTNH_F_ONLINK);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append NHA_GATEWAY attribute: %m");
|
||||
|
||||
if (nexthop->onlink > 0) {
|
||||
r = sd_rtnl_message_nexthop_set_flags(req, RTNH_F_ONLINK);
|
||||
if (r < 0)
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
@ -477,7 +431,7 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
|
||||
NextHop *nexthop = NULL;
|
||||
uint32_t ifindex;
|
||||
uint16_t type;
|
||||
Link *link = NULL;
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(rtnl);
|
||||
@ -502,21 +456,22 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
|
||||
}
|
||||
|
||||
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");
|
||||
return 0;
|
||||
} else if (r >= 0) {
|
||||
if (ifindex <= 0) {
|
||||
log_warning("rtnl: received nexthop message with invalid ifindex %"PRIu32", ignoring.", ifindex);
|
||||
return 0;
|
||||
}
|
||||
} else if (ifindex <= 0) {
|
||||
log_warning("rtnl: received nexthop message with invalid ifindex %"PRIu32", ignoring.", ifindex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = link_get(m, ifindex, &link);
|
||||
if (r < 0 || !link) {
|
||||
if (!m->enumerating)
|
||||
log_warning("rtnl: received nexthop message for link (%"PRIu32") we do not know about, ignoring", ifindex);
|
||||
return 0;
|
||||
}
|
||||
r = link_get(m, ifindex, &link);
|
||||
if (r < 0 || !link) {
|
||||
if (!m->enumerating)
|
||||
log_warning("rtnl: received nexthop message for link (%"PRIu32") we do not know about, ignoring", ifindex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = nexthop_new(&tmp);
|
||||
@ -536,13 +491,6 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
|
||||
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);
|
||||
if (r == -ENODATA) {
|
||||
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;
|
||||
}
|
||||
|
||||
/* All blackhole nexthops are managed by Manager. Note that the linux kernel does not set
|
||||
* NHA_OID attribute when NHA_BLACKHOLE is set. Just for safety. */
|
||||
if (tmp->blackhole)
|
||||
link = NULL;
|
||||
|
||||
r = nexthop_get(m, link, tmp, &nexthop);
|
||||
r = nexthop_get(link, tmp, &nexthop);
|
||||
if (r < 0) {
|
||||
uint32_t id;
|
||||
|
||||
@ -569,7 +512,7 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
|
||||
id = tmp->id;
|
||||
tmp->id = 0;
|
||||
|
||||
(void) nexthop_get(m, link, tmp, &nexthop);
|
||||
(void) nexthop_get(link, tmp, &nexthop);
|
||||
|
||||
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);
|
||||
else {
|
||||
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) {
|
||||
log_link_warning_errno(link, r, "Could not remember foreign nexthop, ignoring: %m");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
r = nexthop_update(m, link, nexthop, tmp);
|
||||
r = nexthop_update(link, nexthop, tmp);
|
||||
if (r < 0) {
|
||||
log_link_warning_errno(link, r, "Could not update nexthop, ignoring: %m");
|
||||
return 0;
|
||||
@ -613,12 +556,6 @@ static int nexthop_section_verify(NextHop *nh) {
|
||||
/* When no Gateway= is specified, assume IPv4. */
|
||||
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) &&
|
||||
ordered_hashmap_isempty(nh->network->addresses_by_section)) {
|
||||
/* 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);
|
||||
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;
|
||||
NetworkConfigSection *section;
|
||||
|
||||
Manager *manager;
|
||||
Link *link;
|
||||
|
||||
unsigned char protocol;
|
||||
|
||||
uint32_t id;
|
||||
bool blackhole;
|
||||
int family;
|
||||
union in_addr_union gw;
|
||||
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_family);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_nexthop_onlink);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_nexthop_blackhole);
|
||||
|
||||
@ -451,18 +451,34 @@ static int route_get(const Manager *manager, const Link *link, const Route *in,
|
||||
assert(manager || link);
|
||||
assert(in);
|
||||
|
||||
existing = set_get(link ? link->routes : manager->routes, in);
|
||||
if (existing) {
|
||||
if (ret)
|
||||
*ret = existing;
|
||||
return 1;
|
||||
}
|
||||
if (link) {
|
||||
existing = set_get(link->routes, in);
|
||||
if (existing) {
|
||||
if (ret)
|
||||
*ret = existing;
|
||||
return 1;
|
||||
}
|
||||
|
||||
existing = set_get(link ? link->routes_foreign : manager->routes_foreign, in);
|
||||
if (existing) {
|
||||
if (ret)
|
||||
*ret = existing;
|
||||
return 0;
|
||||
existing = set_get(link->routes_foreign, in);
|
||||
if (existing) {
|
||||
if (ret)
|
||||
*ret = existing;
|
||||
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;
|
||||
@ -472,8 +488,6 @@ static void route_copy(Route *dest, const Route *src, const MultipathRoute *m, c
|
||||
assert(dest);
|
||||
assert(src);
|
||||
|
||||
/* This only copies entries used by the above hash and compare functions. */
|
||||
|
||||
dest->family = src->family;
|
||||
dest->src = src->src;
|
||||
dest->src_prefixlen = src->src_prefixlen;
|
||||
@ -482,10 +496,7 @@ static void route_copy(Route *dest, const Route *src, const MultipathRoute *m, c
|
||||
dest->prefsrc = src->prefsrc;
|
||||
dest->scope = src->scope;
|
||||
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->priority = src->priority;
|
||||
dest->table = src->table;
|
||||
@ -582,11 +593,19 @@ static int route_add(Manager *manager, Link *link, const Route *in, const Multip
|
||||
is_new = true;
|
||||
} else if (r == 0) {
|
||||
/* Take over a foreign route */
|
||||
r = set_ensure_put(link ? &link->routes : &manager->routes, &route_hash_ops, route);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (link) {
|
||||
r = set_ensure_put(&link->routes, &route_hash_ops, route);
|
||||
if (r < 0)
|
||||
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) {
|
||||
/* 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);
|
||||
|
||||
if (route_type_is_reject(route) || (nh && nh->blackhole))
|
||||
k = route_add(link->manager, NULL, route, NULL, nh, &nr);
|
||||
if (route_type_is_reject(route))
|
||||
k = route_add(link->manager, NULL, route, NULL, NULL, &nr);
|
||||
else if (!m || m->ifindex == 0 || m->ifindex == link->ifindex)
|
||||
k = route_add(NULL, link, route, m, nh, &nr);
|
||||
else {
|
||||
|
||||
@ -532,7 +532,7 @@ int dissect_image(
|
||||
if (!S_ISBLK(st.st_mode))
|
||||
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)
|
||||
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),
|
||||
"%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)
|
||||
return log_error_errno(r, "Failed to initialize device from %s: %m", devlink);
|
||||
|
||||
|
||||
@ -353,7 +353,6 @@ Id=
|
||||
Gateway=
|
||||
Family=
|
||||
OnLink=
|
||||
Blackhole=
|
||||
[QDisc]
|
||||
Parent=
|
||||
Handle=
|
||||
|
||||
Binary file not shown.
@ -28,27 +28,9 @@ Id=5
|
||||
Gateway=192.168.10.1
|
||||
OnLink=yes
|
||||
|
||||
[NextHop]
|
||||
Id=6
|
||||
Family=ipv4
|
||||
Blackhole=yes
|
||||
|
||||
[NextHop]
|
||||
Id=7
|
||||
Family=ipv6
|
||||
Blackhole=yes
|
||||
|
||||
[NextHop]
|
||||
Gateway=192.168.5.2
|
||||
|
||||
[NextHop]
|
||||
Family=ipv4
|
||||
Blackhole=yes
|
||||
|
||||
[NextHop]
|
||||
Family=ipv6
|
||||
Blackhole=yes
|
||||
|
||||
[Route]
|
||||
NextHop=1
|
||||
Destination=10.10.10.10
|
||||
@ -64,11 +46,3 @@ Destination=2001:1234:5:8f62::1
|
||||
[Route]
|
||||
NextHop=5
|
||||
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
|
||||
|
||||
[WireGuard]
|
||||
PrivateKey=EEGlnEPYJV//kbvvIqxKkQwOiS+UENyPncC4bF46ong=
|
||||
ListenPort=51820
|
||||
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]
|
||||
Name=wg99
|
||||
|
||||
[Network]
|
||||
Address=192.168.124.1/24
|
||||
|
||||
@ -404,13 +404,6 @@ def remove_routes(routes):
|
||||
for route_type, addr in routes:
|
||||
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):
|
||||
output = check_output('ip l2tp show tunnel')
|
||||
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-no-peer.netdev', '25-wireguard-no-peer.network')
|
||||
start_networkd()
|
||||
self.wait_online(['wg99:routable', '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)
|
||||
self.wait_online(['wg99:carrier', 'wg98:routable', 'wg97:carrier'])
|
||||
|
||||
output = check_output('ip -4 address show dev wg98')
|
||||
print(output)
|
||||
@ -1243,39 +1232,29 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
||||
call('wg')
|
||||
|
||||
output = check_output('wg show wg99 listen-port')
|
||||
self.assertEqual(output, '51820')
|
||||
self.assertRegex(output, '51820')
|
||||
output = check_output('wg show wg99 fwmark')
|
||||
self.assertEqual(output, '0x4d2')
|
||||
output = check_output('wg show wg99 private-key')
|
||||
self.assertEqual(output, 'EEGlnEPYJV//kbvvIqxKkQwOiS+UENyPncC4bF46ong=')
|
||||
self.assertRegex(output, '0x4d2')
|
||||
output = check_output('wg show wg99 allowed-ips')
|
||||
self.assertIn('9uioxkGzjvGjkse3V35I9AhorWfIjBcrf3UPMS0bw2c=\t192.168.124.3/32', output)
|
||||
self.assertIn('TTiCUpCxS7zDn/ax4p5W6Evg41r8hOrnWQw2Sq6Nh10=\t192.168.124.2/32', output)
|
||||
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)
|
||||
self.assertRegex(output, r'RDf\+LSpeEre7YEIKaxg\+wbpsNV7du\+ktR99uBEtIiCA=\t192.168.26.0/24 fd31:bf08:57cb::/48')
|
||||
self.assertRegex(output, r'lsDtM3AbjxNlauRKzHEPfgS1Zp7cp/VX5Use/P4PQSc=\tfdbc:bae2:7871:e1fe:793:8636::/96 fdbc:bae2:7871:500:e1fe:793:8636:dad1/128')
|
||||
output = check_output('wg show wg99 persistent-keepalive')
|
||||
self.assertIn('9uioxkGzjvGjkse3V35I9AhorWfIjBcrf3UPMS0bw2c=\toff', output)
|
||||
self.assertIn('TTiCUpCxS7zDn/ax4p5W6Evg41r8hOrnWQw2Sq6Nh10=\toff', output)
|
||||
self.assertIn('lsDtM3AbjxNlauRKzHEPfgS1Zp7cp/VX5Use/P4PQSc=\toff', output)
|
||||
self.assertIn('RDf+LSpeEre7YEIKaxg+wbpsNV7du+ktR99uBEtIiCA=\t20', output)
|
||||
self.assertRegex(output, r'RDf\+LSpeEre7YEIKaxg\+wbpsNV7du\+ktR99uBEtIiCA=\t20')
|
||||
output = check_output('wg show wg99 endpoints')
|
||||
self.assertIn('9uioxkGzjvGjkse3V35I9AhorWfIjBcrf3UPMS0bw2c=\t(none)', output)
|
||||
self.assertIn('TTiCUpCxS7zDn/ax4p5W6Evg41r8hOrnWQw2Sq6Nh10=\t(none)', output)
|
||||
self.assertIn('lsDtM3AbjxNlauRKzHEPfgS1Zp7cp/VX5Use/P4PQSc=\t(none)', output)
|
||||
self.assertIn('RDf+LSpeEre7YEIKaxg+wbpsNV7du+ktR99uBEtIiCA=\t192.168.27.3:51820', output)
|
||||
self.assertRegex(output, r'RDf\+LSpeEre7YEIKaxg\+wbpsNV7du\+ktR99uBEtIiCA=\t192.168.27.3:51820')
|
||||
output = check_output('wg show wg99 private-key')
|
||||
self.assertRegex(output, r'EEGlnEPYJV//kbvvIqxKkQwOiS\+UENyPncC4bF46ong=')
|
||||
output = check_output('wg show wg99 preshared-keys')
|
||||
self.assertIn('9uioxkGzjvGjkse3V35I9AhorWfIjBcrf3UPMS0bw2c=\t6Fsg8XN0DE6aPQgAX4r2oazEYJOGqyHUz3QRH/jCB+I=', output)
|
||||
self.assertIn('TTiCUpCxS7zDn/ax4p5W6Evg41r8hOrnWQw2Sq6Nh10=\tit7nd33chCT/tKT2ZZWfYyp43Zs+6oif72hexnSNMqA=', output)
|
||||
self.assertIn('lsDtM3AbjxNlauRKzHEPfgS1Zp7cp/VX5Use/P4PQSc=\tcPLOy1YUrEI0EMMIycPJmOo0aTu3RZnw8bL5meVD6m0=', output)
|
||||
self.assertIn('RDf+LSpeEre7YEIKaxg+wbpsNV7du+ktR99uBEtIiCA=\tIIWIV17wutHv7t4cR6pOT91z6NSz/T8Arh0yaywhw3M=', output)
|
||||
self.assertRegex(output, r'RDf\+LSpeEre7YEIKaxg\+wbpsNV7du\+ktR99uBEtIiCA= IIWIV17wutHv7t4cR6pOT91z6NSz/T8Arh0yaywhw3M=')
|
||||
self.assertRegex(output, r'lsDtM3AbjxNlauRKzHEPfgS1Zp7cp/VX5Use/P4PQSc= cPLOy1YUrEI0EMMIycPJmOo0aTu3RZnw8bL5meVD6m0=')
|
||||
|
||||
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')
|
||||
self.assertEqual(output, '51821')
|
||||
self.assertRegex(output, '51821')
|
||||
output = check_output('wg show wg97 fwmark')
|
||||
self.assertEqual(output, '0x4d3')
|
||||
self.assertRegex(output, '0x4d3')
|
||||
|
||||
def test_geneve(self):
|
||||
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']]
|
||||
|
||||
def setUp(self):
|
||||
remove_blackhole_nexthops()
|
||||
remove_routing_policy_rule_tables(self.routing_policy_rule_tables)
|
||||
remove_routes(self.routes)
|
||||
remove_links(self.links)
|
||||
stop_networkd(show_logs=False)
|
||||
|
||||
def tearDown(self):
|
||||
remove_blackhole_nexthops()
|
||||
remove_routing_policy_rule_tables(self.routing_policy_rule_tables)
|
||||
remove_routes(self.routes)
|
||||
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, 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')
|
||||
print(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)
|
||||
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):
|
||||
copy_unit_to_networkd_unit_path('25-qdisc-clsact-and-htb.network', '12-dummy.netdev',
|
||||
'25-qdisc-ingress-netem-compat.network', '11-dummy.netdev')
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user