New upstream version 249.4

This commit is contained in:
Michael Biebl 2021-08-30 10:27:49 +02:00
parent 9d66932971
commit 2c6f20efa6
43 changed files with 387 additions and 122 deletions

View File

@ -1706,7 +1706,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b DefaultDependencies = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s OnSuccesJobMode = '...';
readonly s OnSuccessJobMode = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s OnFailureJobMode = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
@ -1815,7 +1815,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
<!--property CanFreeze is not documented!-->
<!--property OnSuccesJobMode is not documented!-->
<!--property OnSuccessJobMode is not documented!-->
<!--property OnFailureJobMode is not documented!-->
@ -2019,7 +2019,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
<variablelist class="dbus-property" generated="True" extra-ref="DefaultDependencies"/>
<variablelist class="dbus-property" generated="True" extra-ref="OnSuccesJobMode"/>
<variablelist class="dbus-property" generated="True" extra-ref="OnSuccessJobMode"/>
<variablelist class="dbus-property" generated="True" extra-ref="OnFailureJobMode"/>

View File

@ -662,49 +662,49 @@
<varlistentry>
<term><varname>ReceiveChecksumOffload=</varname></term>
<listitem>
<para>Takes a boolean. If set to true, the hardware offload for checksumming of ingress
<para>Takes a boolean. If set to true, hardware offload for checksumming of ingress
network packets is enabled. When unset, the kernel's default will be used.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>TransmitChecksumOffload=</varname></term>
<listitem>
<para>Takes a boolean. If set to true, the hardware offload for checksumming of egress
<para>Takes a boolean. If set to true, hardware offload for checksumming of egress
network packets is enabled. When unset, the kernel's default will be used.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>TCPSegmentationOffload=</varname></term>
<listitem>
<para>Takes a boolean. If set to true, the TCP Segmentation Offload (TSO) is enabled.
<para>Takes a boolean. If set to true, TCP Segmentation Offload (TSO) is enabled.
When unset, the kernel's default will be used.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>TCP6SegmentationOffload=</varname></term>
<listitem>
<para>Takes a boolean. If set to true, the TCP6 Segmentation Offload (tx-tcp6-segmentation) is enabled.
<para>Takes a boolean. If set to true, TCP6 Segmentation Offload (tx-tcp6-segmentation) is enabled.
When unset, the kernel's default will be used.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>GenericSegmentationOffload=</varname></term>
<listitem>
<para>Takes a boolean. If set to true, the Generic Segmentation Offload (GSO) is enabled.
<para>Takes a boolean. If set to true, Generic Segmentation Offload (GSO) is enabled.
When unset, the kernel's default will be used.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>GenericReceiveOffload=</varname></term>
<listitem>
<para>Takes a boolean. If set to true, the Generic Receive Offload (GRO) is enabled.
<para>Takes a boolean. If set to true, Generic Receive Offload (GRO) is enabled.
When unset, the kernel's default will be used.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>LargeReceiveOffload=</varname></term>
<listitem>
<para>Takes a boolean. If set to true, the Large Receive Offload (LRO) is enabled.
<para>Takes a boolean. If set to true, Large Receive Offload (LRO) is enabled.
When unset, the kernel's default will be used.</para>
</listitem>
</varlistentry>
@ -763,7 +763,7 @@
<varlistentry>
<term><varname>RxFlowControl=</varname></term>
<listitem>
<para>Takes a boolean. When set, enables the receive flow control, also known as the ethernet
<para>Takes a boolean. When set, enables receive flow control, also known as the ethernet
receive PAUSE message (generate and send ethernet PAUSE frames). When unset, the kernel's
default will be used.</para>
</listitem>
@ -771,7 +771,7 @@
<varlistentry>
<term><varname>TxFlowControl=</varname></term>
<listitem>
<para>Takes a boolean. When set, enables the transmit flow control, also known as the ethernet
<para>Takes a boolean. When set, enables transmit flow control, also known as the ethernet
transmit PAUSE message (respond to received ethernet PAUSE frames). When unset, the kernel's
default will be used.</para>
</listitem>
@ -779,7 +779,7 @@
<varlistentry>
<term><varname>AutoNegotiationFlowControl=</varname></term>
<listitem>
<para>Takes a boolean. When set, the auto negotiation enables the interface to exchange state
<para>Takes a boolean. When set, auto negotiation enables the interface to exchange state
advertisements with the connected peer so that the two devices can agree on the ethernet
PAUSE configuration. When unset, the kernel's default will be used.</para>
</listitem>

View File

@ -1238,7 +1238,9 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
<term><varname>Priority=</varname></term>
<listitem>
<para>Specifies the priority of this rule. <varname>Priority=</varname> is an unsigned
integer. Higher number means lower priority, and rules get processed in order of increasing number.</para>
integer in the range 0…4294967295. Higher number means lower priority, and rules get
processed in order of increasing number. Defaults to unset, and the kernel will pick
a value dynamically.</para>
</listitem>
</varlistentry>
<varlistentry>

View File

@ -23,7 +23,7 @@ _udevadm_trigger(){
'--dry-run[Do not actually trigger the event.]' \
'--quiet[Suppress error logging in triggering events.]' \
'--type=[Trigger a specific type of devices.]:types:(devices subsystems failed)' \
'--action=[Type of event to be triggered.]:actions:(add change remove)' \
'--action=[Type of event to be triggered.]:actions:(add change remove move online offline bind unbind)' \
'--subsystem-match=[Trigger events for devices which belong to a matching subsystem.]' \
'--subsystem-nomatch=[Do not trigger events for devices which belong to a matching subsystem.]' \
'--attr-match=attribute=[Trigger events for devices with a matching sysfs attribute.]' \
@ -74,7 +74,7 @@ _udevadm_monitor(){
(( $+functions[_udevadm_test] )) ||
_udevadm_test(){
_arguments \
'--action=[The action string.]:actions:(add change remove)' \
'--action=[The action string.]:actions:(add change remove move online offline bind unbind)' \
'--subsystem=[The subsystem string.]' \
'--help[Print help text.]' \
'*::devpath:_files -P /sys/ -W /sys'

View File

@ -1910,7 +1910,7 @@ static int property_read_ip_filters(
if (streq(member, "IPIngressFilterPath"))
info->ip_filters_custom_ingress = !strv_isempty(l);
else if (streq(member, "IPEgressFilterPath"))
info->ip_filters_custom_ingress = !strv_isempty(l);
info->ip_filters_custom_egress = !strv_isempty(l);
return 0;
}

View File

@ -1724,7 +1724,7 @@ static ConfigEntry *config_entry_add_loader(
*entry = (ConfigEntry) {
.type = type,
.title = StrDuplicate(title),
.version = StrDuplicate(version),
.version = version ? StrDuplicate(version) : NULL,
.device = device,
.loader = StrDuplicate(loader),
.id = StrDuplicate(id),

View File

@ -25,7 +25,7 @@ static VOID linux_efi_handover(EFI_HANDLE image, struct boot_params *params) {
handover(image, ST, params);
}
EFI_STATUS linux_exec(EFI_HANDLE *image,
EFI_STATUS linux_exec(EFI_HANDLE image,
CHAR8 *cmdline, UINTN cmdline_len,
UINTN linux_addr,
UINTN initrd_addr, UINTN initrd_size) {

View File

@ -83,7 +83,7 @@ struct boot_params {
UINT8 _pad9[276];
} __attribute__((packed));
EFI_STATUS linux_exec(EFI_HANDLE *image,
EFI_STATUS linux_exec(EFI_HANDLE image,
CHAR8 *cmdline, UINTN cmdline_size,
UINTN linux_addr,
UINTN initrd_addr, UINTN initrd_size);

View File

@ -245,7 +245,7 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
err = uefi_call_wrapper(root_dir->Open, 5, root_dir, &handle, (CHAR16*) L"\\loader\\random-seed", EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0ULL);
if (EFI_ERROR(err)) {
if (err != EFI_NOT_FOUND)
if (err != EFI_NOT_FOUND && err != EFI_WRITE_PROTECTED)
Print(L"Failed to open random seed file: %r\n", err);
return err;
}

View File

@ -3039,6 +3039,9 @@ static int unit_check_cgroup_events(Unit *u) {
assert(u);
if (!u->cgroup_path)
return 0;
r = cg_get_keyed_attribute_graceful(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, "cgroup.events",
STRV_MAKE("populated", "frozen"), values);
if (r < 0)
@ -3871,6 +3874,21 @@ void unit_invalidate_cgroup_bpf(Unit *u) {
}
}
void unit_cgroup_catchup(Unit *u) {
assert(u);
if (!UNIT_HAS_CGROUP_CONTEXT(u))
return;
/* We dropped the inotify watch during reexec/reload, so we need to
* check these as they may have changed.
* Note that (currently) the kernel doesn't actually update cgroup
* file modification times, so we can't just serialize and then check
* the mtime for file(s) we are interested in. */
(void) unit_check_cgroup_events(u);
unit_add_to_cgroup_oom_queue(u);
}
bool unit_cgroup_delegate(Unit *u) {
CGroupContext *c;

View File

@ -313,6 +313,8 @@ void manager_invalidate_startup_units(Manager *m);
const char* cgroup_device_policy_to_string(CGroupDevicePolicy i) _const_;
CGroupDevicePolicy cgroup_device_policy_from_string(const char *s) _pure_;
void unit_cgroup_catchup(Unit *u);
bool unit_cgroup_delegate(Unit *u);
int compare_job_priority(const void *a, const void *b);

View File

@ -905,7 +905,8 @@ const sd_bus_vtable bus_unit_vtable[] = {
SD_BUS_PROPERTY("RefuseManualStop", "b", bus_property_get_bool, offsetof(Unit, refuse_manual_stop), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("AllowIsolate", "b", bus_property_get_bool, offsetof(Unit, allow_isolate), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("DefaultDependencies", "b", bus_property_get_bool, offsetof(Unit, default_dependencies), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("OnSuccesJobMode", "s", property_get_job_mode, offsetof(Unit, on_success_job_mode), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("OnSuccesJobMode", "s", property_get_job_mode, offsetof(Unit, on_success_job_mode), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN), /* deprecated */
SD_BUS_PROPERTY("OnSuccessJobMode", "s", property_get_job_mode, offsetof(Unit, on_success_job_mode), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("OnFailureJobMode", "s", property_get_job_mode, offsetof(Unit, on_failure_job_mode), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("IgnoreOnIsolate", "b", bus_property_get_bool, offsetof(Unit, ignore_on_isolate), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("NeedDaemonReload", "b", property_get_need_daemon_reload, 0, SD_BUS_VTABLE_PROPERTY_CONST),

View File

@ -1410,6 +1410,10 @@ static void manager_clear_jobs_and_units(Manager *m) {
assert(!m->cleanup_queue);
assert(!m->gc_unit_queue);
assert(!m->gc_job_queue);
assert(!m->cgroup_realize_queue);
assert(!m->cgroup_empty_queue);
assert(!m->cgroup_oom_queue);
assert(!m->target_deps_queue);
assert(!m->stop_when_unneeded_queue);
assert(!m->start_when_upheld_queue);
assert(!m->stop_when_bound_queue);

View File

@ -733,6 +733,9 @@ Unit* unit_free(Unit *u) {
if (u->in_dbus_queue)
LIST_REMOVE(dbus_queue, u->manager->dbus_unit_queue, u);
if (u->in_cleanup_queue)
LIST_REMOVE(cleanup_queue, u->manager->cleanup_queue, u);
if (u->in_gc_queue)
LIST_REMOVE(gc_queue, u->manager->gc_unit_queue, u);
@ -742,8 +745,8 @@ Unit* unit_free(Unit *u) {
if (u->in_cgroup_empty_queue)
LIST_REMOVE(cgroup_empty_queue, u->manager->cgroup_empty_queue, u);
if (u->in_cleanup_queue)
LIST_REMOVE(cleanup_queue, u->manager->cleanup_queue, u);
if (u->in_cgroup_oom_queue)
LIST_REMOVE(cgroup_oom_queue, u->manager->cgroup_oom_queue, u);
if (u->in_target_deps_queue)
LIST_REMOVE(target_deps_queue, u->manager->target_deps_queue, u);
@ -3578,7 +3581,6 @@ int unit_add_blockdev_dependency(Unit *u, const char *what, UnitDependencyMask m
int unit_coldplug(Unit *u) {
int r = 0, q;
char **i;
Job *uj;
assert(u);
@ -3601,9 +3603,13 @@ int unit_coldplug(Unit *u) {
r = q;
}
uj = u->job ?: u->nop_job;
if (uj) {
q = job_coldplug(uj);
if (u->job) {
q = job_coldplug(u->job);
if (q < 0 && r >= 0)
r = q;
}
if (u->nop_job) {
q = job_coldplug(u->nop_job);
if (q < 0 && r >= 0)
r = q;
}
@ -3616,6 +3622,8 @@ void unit_catchup(Unit *u) {
if (UNIT_VTABLE(u)->catchup)
UNIT_VTABLE(u)->catchup(u);
unit_cgroup_catchup(u);
}
static bool fragment_mtime_newer(const char *path, usec_t mtime, bool path_masked) {

View File

@ -435,7 +435,8 @@ static int add_mount(
/* Order the mount unit we generate relative to the post unit, so that DefaultDependencies= on the
* target unit won't affect us. */
if (post && !FLAGS_SET(flags, MOUNT_AUTOMOUNT) && !FLAGS_SET(flags, MOUNT_NOAUTO))
if (post && !FLAGS_SET(flags, MOUNT_AUTOMOUNT) && !FLAGS_SET(flags, MOUNT_NOAUTO) &&
!FLAGS_SET(flags, MOUNT_NOFAIL))
fprintf(f, "Before=%s\n", post);
if (passno != 0) {

View File

@ -256,6 +256,9 @@ int curl_glue_make(CURL **ret, const char *url, void *userdata) {
if (curl_easy_setopt(c, CURLOPT_LOW_SPEED_LIMIT, 30L) != CURLE_OK)
return -EIO;
if (curl_easy_setopt(c, CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS|CURLPROTO_FILE) != CURLE_OK)
return -EIO;
*ret = TAKE_PTR(c);
return 0;
}

View File

@ -415,6 +415,13 @@ static JournalFile* find_journal(Server *s, uid_t uid) {
if (s->runtime_journal)
return s->runtime_journal;
/* If we are not in persistent mode, then we need return NULL immediately rather than opening a
* persistent journal of any sort.
*
* Fixes https://github.com/systemd/systemd/issues/20390 */
if (!IN_SET(s->storage, STORAGE_AUTO, STORAGE_PERSISTENT))
return NULL;
if (uid_for_system_journal(uid))
return s->system_journal;

View File

@ -1107,7 +1107,7 @@ int dhcp_server_handle_message(sd_dhcp_server *server, DHCPMessage *message, siz
if (server->bound_leases[pool_offset] == existing_lease) {
server->bound_leases[pool_offset] = NULL;
hashmap_remove(server->leases_by_client_id, existing_lease);
hashmap_remove(server->leases_by_client_id, &existing_lease->client_id);
dhcp_lease_free(existing_lease);
if (server->callback)

View File

@ -1219,7 +1219,7 @@ static int client_parse_message(
if (lease->ia.addresses) {
lt_t1 = MIN(lt_t1, be32toh(lease->ia.ia_na.lifetime_t1));
lt_t2 = MIN(lt_t2, be32toh(lease->ia.ia_na.lifetime_t1));
lt_t2 = MIN(lt_t2, be32toh(lease->ia.ia_na.lifetime_t2));
}
break;
@ -1328,17 +1328,16 @@ static int client_parse_message(
dhcp6_message_type_to_string(message->type));
return -EINVAL;
}
}
} else {
if (lease->ia.addresses) {
lease->ia.ia_na.lifetime_t1 = htobe32(lt_t1);
lease->ia.ia_na.lifetime_t2 = htobe32(lt_t2);
}
if (lease->ia.addresses) {
lease->ia.ia_na.lifetime_t1 = htobe32(lt_t1);
lease->ia.ia_na.lifetime_t2 = htobe32(lt_t2);
}
if (lease->pd.addresses) {
lease->pd.ia_pd.lifetime_t1 = htobe32(lt_t1);
lease->pd.ia_pd.lifetime_t2 = htobe32(lt_t2);
}
if (lease->pd.addresses) {
lease->pd.ia_pd.lifetime_t1 = htobe32(lt_t1);
lease->pd.ia_pd.lifetime_t2 = htobe32(lt_t2);
}
client->information_refresh_time_usec = MAX(irt, IRT_MINIMUM);

View File

@ -5,6 +5,7 @@
#include "conf-parser.h"
#include "macvlan.h"
#include "macvlan-util.h"
#include "networkd-network.h"
#include "parse-util.h"
DEFINE_CONFIG_PARSE_ENUM(config_parse_macvlan_mode, macvlan_mode, MacVlanMode, "Failed to parse macvlan mode");
@ -16,6 +17,7 @@ static int netdev_macvlan_fill_message_create(NetDev *netdev, Link *link, sd_net
assert(netdev);
assert(link);
assert(netdev->ifname);
assert(link->network);
if (netdev->kind == NETDEV_KIND_MACVLAN)
m = MACVLAN(netdev);
@ -52,6 +54,13 @@ static int netdev_macvlan_fill_message_create(NetDev *netdev, Link *link, sd_net
return log_netdev_error_errno(netdev, r, "Could not append IFLA_MACVLAN_MODE attribute: %m");
}
/* set the nopromisc flag if Promiscuous= of the link is explicitly set to false */
if (m->mode == NETDEV_MACVLAN_MODE_PASSTHRU && link->network->promiscuous == 0) {
r = sd_netlink_message_append_u16(req, IFLA_MACVLAN_FLAGS, MACVLAN_FLAG_NOPROMISC);
if (r < 0)
return log_netdev_error_errno(netdev, r, "Could not append IFLA_MACVLAN_FLAGS attribute: %m");
}
if (m->bc_queue_length != UINT32_MAX) {
r = sd_netlink_message_append_u32(req, IFLA_MACVLAN_BC_QUEUE_LEN, m->bc_queue_length);
if (r < 0)

View File

@ -1272,17 +1272,17 @@ int request_process_address(Request *req) {
if (r <= 0)
return r;
r = address_get(link, req->address, &a);
if (r < 0)
return r;
r = address_configure(a, link, req->netlink_handler);
r = address_configure(req->address, link, req->netlink_handler);
if (r < 0)
return r;
/* To prevent a double decrement on failure in after_configure(). */
req->message_counter = NULL;
r = address_get(link, req->address, &a);
if (r < 0)
return r;
if (req->after_configure) {
r = req->after_configure(req, a);
if (r < 0)

View File

@ -1,5 +1,6 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <net/if.h>
#include <netinet/in.h>
#include <linux/if.h>
#include <linux/if_arp.h>
@ -21,6 +22,7 @@
#include "ethtool-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "format-util.h"
#include "fs-util.h"
#include "ipvlan.h"
#include "missing_network.h"
@ -2161,6 +2163,7 @@ static int link_update_alternative_names(Link *link, sd_netlink_message *message
}
static int link_update_name(Link *link, sd_netlink_message *message) {
char ifname_from_index[IF_NAMESIZE + 1];
const char *ifname;
int r;
@ -2177,6 +2180,16 @@ static int link_update_name(Link *link, sd_netlink_message *message) {
if (streq(ifname, link->ifname))
return 0;
if (!format_ifname(link->ifindex, ifname_from_index))
return log_link_debug_errno(link, SYNTHETIC_ERRNO(ENXIO), "Could not get interface name for index %i.", link->ifindex);
if (!streq(ifname, ifname_from_index)) {
log_link_debug(link, "New interface name '%s' received from the kernel does not correspond "
"with the name currently configured on the actual interface '%s'. Ignoring.",
ifname, ifname_from_index);
return 0;
}
log_link_info(link, "Interface name change detected, renamed to %s.", ifname);
hashmap_remove(link->manager->links_by_name, link->ifname);

View File

@ -765,7 +765,9 @@ static int ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *r
assert(link);
assert(rt);
r = sd_ndisc_router_get_timestamp(rt, clock_boottime_or_monotonic(), &time_now);
/* Do not use clock_boottime_or_monotonic() here, as the kernel internally manages cstamp and
* tstamp with jiffies, and it is not increased while the system is suspended. */
r = sd_ndisc_router_get_timestamp(rt, CLOCK_MONOTONIC, &time_now);
if (r < 0)
return log_link_error_errno(link, r, "Failed to get RA timestamp: %m");

View File

@ -791,12 +791,7 @@ static bool nexthop_is_ready_to_configure(Link *link, const NextHop *nexthop) {
}
}
if (nexthop->onlink <= 0 &&
in_addr_is_set(nexthop->family, &nexthop->gw) &&
!manager_address_is_reachable(link->manager, nexthop->family, &nexthop->gw))
return false;
return true;
return gateway_is_ready(link, nexthop->onlink, nexthop->family, &nexthop->gw);
}
int request_process_nexthop(Request *req) {

View File

@ -746,21 +746,54 @@ static bool route_address_is_reachable(const Route *route, int family, const uni
FAMILY_ADDRESS_SIZE(family) * 8) > 0;
}
bool manager_address_is_reachable(Manager *manager, int family, const union in_addr_union *address) {
Link *link;
assert(manager);
static bool prefix_route_address_is_reachable(const Address *a, int family, const union in_addr_union *address) {
assert(a);
assert(IN_SET(family, AF_INET, AF_INET6));
assert(address);
HASHMAP_FOREACH(link, manager->links_by_index) {
Route *route;
if (a->family != family)
return false;
if (!address_is_ready(a))
return false;
if (FLAGS_SET(a->flags, IFA_F_NOPREFIXROUTE))
return false;
if (in_addr_is_set(a->family, &a->in_addr_peer))
return false;
SET_FOREACH(route, link->routes)
if (route_address_is_reachable(route, family, address))
return in_addr_prefix_intersect(
family,
&a->in_addr,
a->prefixlen,
address,
FAMILY_ADDRESS_SIZE(family) * 8) > 0;
}
static bool link_address_is_reachable(Link *link, int family, const union in_addr_union *address) {
Route *route;
assert(link);
assert(link->manager);
assert(IN_SET(family, AF_INET, AF_INET6));
assert(address);
SET_FOREACH(route, link->routes)
if (route_address_is_reachable(route, family, address))
return true;
SET_FOREACH(route, link->routes_foreign)
if (route_address_is_reachable(route, family, address))
return true;
/* If we do not manage foreign routes, then there may exist a prefix route we do not know,
* which was created on configuring an address. Hence, also check the addresses. */
if (!link->manager->manage_foreign_routes) {
Address *a;
SET_FOREACH(a, link->addresses)
if (prefix_route_address_is_reachable(a, family, address))
return true;
SET_FOREACH(route, link->routes_foreign)
if (route_address_is_reachable(route, family, address))
SET_FOREACH(a, link->addresses_foreign)
if (prefix_route_address_is_reachable(a, family, address))
return true;
}
@ -1658,6 +1691,22 @@ int link_request_static_routes(Link *link, bool only_ipv4) {
return 0;
}
bool gateway_is_ready(Link *link, int onlink, int family, const union in_addr_union *gw) {
assert(link);
assert(gw);
if (onlink > 0)
return true;
if (!in_addr_is_set(family, gw))
return true;
if (family == AF_INET6 && in6_addr_is_link_local(&gw->in6))
return true;
return link_address_is_reachable(link, family, gw);
}
static int route_is_ready_to_configure(const Route *route, Link *link) {
MultipathRoute *m;
NextHop *nh = NULL;
@ -1701,19 +1750,13 @@ static int route_is_ready_to_configure(const Route *route, Link *link) {
return r;
}
if (route->gateway_onlink <= 0 &&
in_addr_is_set(route->gw_family, &route->gw) > 0 &&
!manager_address_is_reachable(link->manager, route->gw_family, &route->gw))
if (!gateway_is_ready(link, route->gateway_onlink, route->gw_family, &route->gw))
return false;
ORDERED_SET_FOREACH(m, route->multipath_routes) {
union in_addr_union a = m->gateway.address;
Link *l = NULL;
if (route->gateway_onlink <= 0 &&
!manager_address_is_reachable(link->manager, m->gateway.family, &a))
return false;
if (m->ifname) {
if (link_get_by_name(link->manager, m->ifname, &l) < 0)
return false;
@ -1725,6 +1768,9 @@ static int route_is_ready_to_configure(const Route *route, Link *link) {
}
if (l && !link_is_ready_to_configure(l, true))
return false;
if (!gateway_is_ready(l ?: link, route->gateway_onlink, m->gateway.family, &a))
return false;
}
return true;

View File

@ -78,8 +78,8 @@ int route_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Li
int route_remove(const Route *route, Manager *manager, Link *link);
int link_has_route(Link *link, const Route *route);
bool manager_address_is_reachable(Manager *manager, int family, const union in_addr_union *address);
int manager_find_uplink(Manager *m, int family, Link *exclude, Link **ret);
bool gateway_is_ready(Link *link, int onlink, int family, const union in_addr_union *gw);
int link_drop_routes(Link *link);
int link_drop_foreign_routes(Link *link);

View File

@ -163,7 +163,9 @@ void routing_policy_rule_hash_func(const RoutingPolicyRule *rule, struct siphash
siphash24_compress(&rule->type, sizeof(rule->type), state);
siphash24_compress(&rule->fwmark, sizeof(rule->fwmark), state);
siphash24_compress(&rule->fwmask, sizeof(rule->fwmask), state);
siphash24_compress(&rule->priority, sizeof(rule->priority), state);
siphash24_compress_boolean(rule->priority_set, state);
if (rule->priority_set)
siphash24_compress(&rule->priority, sizeof(rule->priority), state);
siphash24_compress(&rule->table, sizeof(rule->table), state);
siphash24_compress(&rule->suppress_prefixlen, sizeof(rule->suppress_prefixlen), state);
@ -229,10 +231,16 @@ int routing_policy_rule_compare_func(const RoutingPolicyRule *a, const RoutingPo
if (r != 0)
return r;
r = CMP(a->priority, b->priority);
r = CMP(a->priority_set, b->priority_set);
if (r != 0)
return r;
if (a->priority_set) {
r = CMP(a->priority, b->priority);
if (r != 0)
return r;
}
r = CMP(a->table, b->table);
if (r != 0)
return r;
@ -293,8 +301,9 @@ DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
routing_policy_rule_compare_func,
routing_policy_rule_free);
static int routing_policy_rule_get(Manager *m, const RoutingPolicyRule *rule, RoutingPolicyRule **ret) {
static int routing_policy_rule_get(Manager *m, const RoutingPolicyRule *rule, bool require_priority, RoutingPolicyRule **ret) {
RoutingPolicyRule *existing;
int r;
assert(m);
@ -312,6 +321,23 @@ static int routing_policy_rule_get(Manager *m, const RoutingPolicyRule *rule, Ro
return 0;
}
if (!require_priority && rule->priority_set) {
_cleanup_(routing_policy_rule_freep) RoutingPolicyRule *tmp = NULL;
r = routing_policy_rule_dup(rule, &tmp);
if (r < 0)
return r;
tmp->priority_set = false;
existing = set_get(m->rules, tmp);
if (existing) {
if (ret)
*ret = existing;
return 1;
}
}
return -ENOENT;
}
@ -328,7 +354,7 @@ static int routing_policy_rule_add(Manager *m, const RoutingPolicyRule *in, Rout
if (r < 0)
return r;
r = routing_policy_rule_get(m, rule, &existing);
r = routing_policy_rule_get(m, rule, true, &existing);
if (r == -ENOENT) {
/* Rule does not exist, use a new one. */
r = set_ensure_put(&m->rules, &routing_policy_rule_hash_ops, rule);
@ -371,6 +397,32 @@ static int routing_policy_rule_consume_foreign(Manager *m, RoutingPolicyRule *ru
return 1;
}
static int routing_policy_rule_update_priority(RoutingPolicyRule *rule, uint32_t priority) {
int r;
assert(rule);
assert(rule->manager);
if (rule->priority_set)
return 0;
if (!set_remove(rule->manager->rules, rule))
return -ENOENT;
rule->priority = priority;
rule->priority_set = true;
r = set_put(rule->manager->rules, rule);
if (r <= 0) {
/* Undo */
rule->priority_set = false;
assert_se(set_put(rule->manager->rules, rule) > 0);
return r == 0 ? -EEXIST : r;
}
return 1;
}
static void log_routing_policy_rule_debug(const RoutingPolicyRule *rule, const char *str, const Link *link, const Manager *m) {
_cleanup_free_ char *from = NULL, *to = NULL, *table = NULL;
@ -422,9 +474,11 @@ static int routing_policy_rule_set_netlink_message(const RoutingPolicyRule *rule
return log_link_error_errno(link, r, "Could not set destination prefix length: %m");
}
r = sd_netlink_message_append_u32(m, FRA_PRIORITY, rule->priority);
if (r < 0)
return log_link_error_errno(link, r, "Could not append FRA_PRIORITY attribute: %m");
if (rule->priority_set) {
r = sd_netlink_message_append_u32(m, FRA_PRIORITY, rule->priority);
if (r < 0)
return log_link_error_errno(link, r, "Could not append FRA_PRIORITY attribute: %m");
}
if (rule->tos > 0) {
r = sd_rtnl_message_routing_policy_rule_set_tos(m, rule->tos);
@ -662,6 +716,28 @@ int manager_drop_routing_policy_rules_internal(Manager *m, bool foreign, const L
continue;
}
if (!foreign) {
_cleanup_(routing_policy_rule_freep) RoutingPolicyRule *tmp = NULL;
/* The rule may be configured without priority. Try to find without priority. */
k = routing_policy_rule_dup(rule, &tmp);
if (k < 0) {
if (r >= 0)
r = k;
continue;
}
tmp->priority_set = false;
k = links_have_routing_policy_rule(m, tmp, except);
if (k != 0) {
if (k < 0 && r >= 0)
r = k;
continue;
}
}
k = routing_policy_rule_remove(rule, m);
if (k < 0 && r >= 0)
r = k;
@ -821,11 +897,11 @@ int request_process_routing_policy_rule(Request *req) {
}
static const RoutingPolicyRule kernel_rules[] = {
{ .family = AF_INET, .priority = 0, .table = RT_TABLE_LOCAL, .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, },
{ .family = AF_INET, .priority = 32766, .table = RT_TABLE_MAIN, .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, },
{ .family = AF_INET, .priority = 32767, .table = RT_TABLE_DEFAULT, .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, },
{ .family = AF_INET6, .priority = 0, .table = RT_TABLE_LOCAL, .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, },
{ .family = AF_INET6, .priority = 32766, .table = RT_TABLE_MAIN, .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, },
{ .family = AF_INET, .priority_set = true, .priority = 0, .table = RT_TABLE_LOCAL, .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, },
{ .family = AF_INET, .priority_set = true, .priority = 32766, .table = RT_TABLE_MAIN, .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, },
{ .family = AF_INET, .priority_set = true, .priority = 32767, .table = RT_TABLE_DEFAULT, .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, },
{ .family = AF_INET6, .priority_set = true, .priority = 0, .table = RT_TABLE_LOCAL, .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, },
{ .family = AF_INET6, .priority_set = true, .priority = 32766, .table = RT_TABLE_MAIN, .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, },
};
static bool routing_policy_rule_is_created_by_kernel(const RoutingPolicyRule *rule) {
@ -936,6 +1012,9 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Man
log_warning_errno(r, "rtnl: could not get FRA_PRIORITY attribute, ignoring: %m");
return 0;
}
/* The kernel does not send priority if priority is zero. So, the flag below must be always set
* even if the message does not contain FRA_PRIORITY. */
tmp->priority_set = true;
r = sd_netlink_message_read_u32(message, FRA_TABLE, &tmp->table);
if (r < 0 && r != -ENODATA) {
@ -1027,13 +1106,16 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Man
* protocol of the received rule is RTPROT_KERNEL or RTPROT_STATIC. */
tmp->protocol = routing_policy_rule_is_created_by_kernel(tmp) ? RTPROT_KERNEL : RTPROT_STATIC;
(void) routing_policy_rule_get(m, tmp, &rule);
(void) routing_policy_rule_get(m, tmp, false, &rule);
switch (type) {
case RTM_NEWRULE:
if (rule)
if (rule) {
log_routing_policy_rule_debug(tmp, "Received remembered", NULL, m);
else if (!m->manage_foreign_routes)
r = routing_policy_rule_update_priority(rule, tmp->priority);
if (r < 0)
log_warning_errno(r, "Failed to update priority of remembered routing policy rule, ignoring: %m");
} else if (!m->manage_foreign_routes)
log_routing_policy_rule_debug(tmp, "Ignoring received foreign", NULL, m);
else {
log_routing_policy_rule_debug(tmp, "Remembering foreign", NULL, m);
@ -1155,11 +1237,19 @@ int config_parse_routing_policy_rule_priority(
if (r < 0)
return log_oom();
if (isempty(rvalue)) {
n->priority = 0;
n->priority_set = false;
TAKE_PTR(n);
return 0;
}
r = safe_atou32(rvalue, &n->priority);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse RPDB rule priority, ignoring: %s", rvalue);
return 0;
}
n->priority_set = true;
TAKE_PTR(n);
return 0;

View File

@ -20,6 +20,7 @@ typedef struct RoutingPolicyRule {
NetworkConfigSection *section;
bool invert_rule;
bool priority_set;
uint8_t tos;
uint8_t type;

View File

@ -229,10 +229,14 @@ static int link_configure(
log_link_debug(link, "Setting %s", set_link_operation_to_string(op));
if (IN_SET(op, SET_LINK_BOND, SET_LINK_CAN)) {
if (op == SET_LINK_BOND) {
r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_NEWLINK, link->master_ifindex);
if (r < 0)
return log_link_debug_errno(link, r, "Could not allocate RTM_NEWLINK message: %m");
} else if (op == SET_LINK_CAN) {
r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_NEWLINK, link->ifindex);
if (r < 0)
return log_link_debug_errno(link, r, "Could not allocate RTM_NEWLINK message: %m");
} else {
r = sd_rtnl_message_new_link(link->manager->rtnl, &req, RTM_SETLINK, link->ifindex);
if (r < 0)

View File

@ -362,9 +362,8 @@ void dns_server_packet_rcode_downgrade(DnsServer *s, DnsServerFeatureLevel level
if (s->possible_feature_level > level) {
s->possible_feature_level = level;
dns_server_reset_counters(s);
log_debug("Downgrading transaction feature level fixed an RCODE error, downgrading server %s too.", strna(dns_server_string_full(s)));
}
log_debug("Downgrading transaction feature level fixed an RCODE error, downgrading server %s too.", strna(dns_server_string_full(s)));
}
void dns_server_packet_invalid(DnsServer *s, DnsServerFeatureLevel level) {

View File

@ -585,7 +585,7 @@ static int dns_stub_send_reply(
DNS_PACKET_RD(q->request_packet),
!!q->request_packet->opt,
edns0_do,
DNS_PACKET_AD(q->request_packet) && dns_query_fully_authenticated(q),
(DNS_PACKET_AD(q->request_packet) || DNS_PACKET_DO(q->request_packet)) && dns_query_fully_authenticated(q),
DNS_PACKET_CD(q->request_packet),
q->stub_listener_extra ? ADVERTISE_EXTRA_DATAGRAM_SIZE_MAX : ADVERTISE_DATAGRAM_SIZE_MAX,
dns_packet_has_nsid_request(q->request_packet) > 0 && !q->stub_listener_extra);
@ -627,7 +627,7 @@ static int dns_stub_send_failure(
DNS_PACKET_RD(p),
!!p->opt,
DNS_PACKET_DO(p),
DNS_PACKET_AD(p) && authenticated,
(DNS_PACKET_AD(p) || DNS_PACKET_DO(p)) && authenticated,
DNS_PACKET_CD(p),
l ? ADVERTISE_EXTRA_DATAGRAM_SIZE_MAX : ADVERTISE_DATAGRAM_SIZE_MAX,
dns_packet_has_nsid_request(p) > 0 && !l);

View File

@ -1142,22 +1142,35 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p, bool encrypt
break;
}
/* Reduce this feature level by one and try again. */
switch (t->current_feature_level) {
case DNS_SERVER_FEATURE_LEVEL_TLS_DO:
t->clamp_feature_level_servfail = DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN;
break;
case DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN + 1:
/* Skip plain TLS when TLS is not supported */
t->clamp_feature_level_servfail = DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN - 1;
break;
default:
t->clamp_feature_level_servfail = t->current_feature_level - 1;
}
/* SERVFAIL can happen for many reasons and may be transient.
* To avoid unnecessary downgrades retry once with the initial level.
* Check for clamp_feature_level_servfail having an invalid value as a sign that this is the
* first attempt to downgrade. If so, clamp to the current value so that the transaction
* is retried without actually downgrading. If the next try also fails we will downgrade by
* hitting the else branch below. */
if (DNS_PACKET_RCODE(p) == DNS_RCODE_SERVFAIL &&
t->clamp_feature_level_servfail < 0) {
t->clamp_feature_level_servfail = t->current_feature_level;
log_debug("Server returned error %s, retrying transaction.",
dns_rcode_to_string(DNS_PACKET_RCODE(p)));
} else {
/* Reduce this feature level by one and try again. */
switch (t->current_feature_level) {
case DNS_SERVER_FEATURE_LEVEL_TLS_DO:
t->clamp_feature_level_servfail = DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN;
break;
case DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN + 1:
/* Skip plain TLS when TLS is not supported */
t->clamp_feature_level_servfail = DNS_SERVER_FEATURE_LEVEL_TLS_PLAIN - 1;
break;
default:
t->clamp_feature_level_servfail = t->current_feature_level - 1;
}
log_debug("Server returned error %s, retrying transaction with reduced feature level %s.",
dns_rcode_to_string(DNS_PACKET_RCODE(p)),
dns_server_feature_level_to_string(t->clamp_feature_level_servfail));
log_debug("Server returned error %s, retrying transaction with reduced feature level %s.",
dns_rcode_to_string(DNS_PACKET_RCODE(p)),
dns_server_feature_level_to_string(t->clamp_feature_level_servfail));
}
dns_transaction_retry(t, false /* use the same server */);
return;

View File

@ -305,7 +305,7 @@ static int image_make(
}
/* Get directory creation time (not available everywhere, but that's OK */
(void) fd_getcrtime(dfd, &crtime);
(void) fd_getcrtime(fd, &crtime);
/* If the IMMUTABLE bit is set, we consider the directory read-only. Since the ioctl is not
* supported everywhere we ignore failures. */

View File

@ -20,11 +20,11 @@
#include "util.h"
static int sethostname_idempotent_full(const char *s, bool really) {
char buf[HOST_NAME_MAX + 1] = {};
char buf[HOST_NAME_MAX + 1];
assert(s);
if (gethostname(buf, sizeof(buf) - 1) < 0)
if (gethostname(buf, sizeof(buf)) < 0)
return -errno;
if (streq(buf, s))
@ -42,11 +42,11 @@ int sethostname_idempotent(const char *s) {
}
bool get_hostname_filtered(char ret[static HOST_NAME_MAX + 1]) {
char buf[HOST_NAME_MAX + 1] = {};
char buf[HOST_NAME_MAX + 1];
/* Returns true if we got a good hostname, false otherwise. */
if (gethostname(buf, sizeof(buf) - 1) < 0)
if (gethostname(buf, sizeof(buf)) < 0)
return false; /* This can realistically only fail with ENAMETOOLONG.
* Let's treat that case the same as an invalid hostname. */

View File

@ -215,13 +215,14 @@ int utmp_put_init_process(const char *id, pid_t pid, pid_t sid, const char *line
}
int utmp_put_dead_process(const char *id, pid_t pid, int code, int status) {
_cleanup_(utxent_cleanup) bool utmpx = false;
struct utmpx lookup = {
.ut_type = INIT_PROCESS /* looks for DEAD_PROCESS, LOGIN_PROCESS, USER_PROCESS, too */
}, store, store_wtmp, *found;
assert(id);
setutxent();
utmpx = utxent_start();
/* Copy the whole string if it fits, or just the suffix without the terminating NUL. */
copy_suffix(store.ut_id, sizeof(store.ut_id), id);
@ -339,6 +340,7 @@ int utmp_wall(
bool (*match_tty)(const char *tty, void *userdata),
void *userdata) {
_cleanup_(utxent_cleanup) bool utmpx = false;
_cleanup_free_ char *text = NULL, *hn = NULL, *un = NULL, *stdin_tty = NULL;
char date[FORMAT_TIMESTAMP_MAX];
struct utmpx *u;
@ -368,7 +370,7 @@ int utmp_wall(
message) < 0)
return -ENOMEM;
setutxent();
utmpx = utxent_start();
r = 0;

View File

@ -89,5 +89,7 @@ int main(void) {
printf("big_enum2_pos → %zu\n", sizeof(big_enum2_pos));
printf("big_enum2_neg → %zu\n", sizeof(big_enum2_neg));
printf("timeval: %zu\n", sizeof(struct timeval));
printf("timespec: %zu\n", sizeof(struct timespec));
return 0;
}

View File

@ -412,7 +412,7 @@ static int manager_receive_response(sd_event_source *source, int fd, uint32_t re
.iov_base = &ntpmsg,
.iov_len = sizeof(ntpmsg),
};
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct timeval))) control;
CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct timespec))) control;
union sockaddr_union server_addr;
struct msghdr msghdr = {
.msg_iov = &iov,

View File

@ -28,10 +28,12 @@ static int builtin_net_setup_link(sd_device *dev, int argc, char **argv, bool te
r = link_config_get(ctx, dev, &link);
if (r < 0) {
if (r == -ENOENT)
return log_device_debug_errno(dev, r, "No matching link configuration found.");
if (r == -ENODEV)
return log_device_debug_errno(dev, r, "Link vanished while searching for configuration for it.");
if (r == -ENOENT) {
log_device_debug_errno(dev, r, "No matching link configuration found, ignoring device.");
return 0;
}
return log_device_error_errno(dev, r, "Failed to get link config: %m");
}

View File

@ -348,12 +348,14 @@ run_qemu() {
[ "$ARCH" ] || ARCH=$(uname -m)
case $ARCH in
ppc64*)
KERNEL_BIN="/boot/vmlinux-$KERNEL_VER"
CONSOLE=hvc0
;;
# Ubuntu ppc64* calls the kernel binary as vmlinux-*, RHEL/CentOS
# uses the "standard" vmlinuz- prefix
[[ -e "/boot/vmlinux-$KERNEL_VER" ]] && KERNEL_BIN="/boot/vmlinux-$KERNEL_VER" || KERNEL_BIN="/boot/vmlinuz-$KERNEL_VER"
CONSOLE=hvc0
;;
*)
KERNEL_BIN="/boot/vmlinuz-$KERNEL_VER"
;;
KERNEL_BIN="/boot/vmlinuz-$KERNEL_VER"
;;
esac
fi
fi

View File

@ -38,6 +38,10 @@ Id=7
Family=ipv6
Blackhole=yes
[NextHop]
Id=8
Gateway=fe80::222:4dff:ff:ff:ff:ff
[NextHop]
Gateway=192.168.5.2

View File

@ -17,6 +17,10 @@ Destination=2001:1234:5:9fff:ff:ff:ff:ff/128
[Route]
Gateway=2001:1234:5:8fff:ff:ff:ff:ff
[Route]
Destination=2001:1234:5:afff:ff:ff:ff:ff/128
Gateway=fe80::222:4dff:ff:ff:ff:ff
[Route]
Destination=149.10.124.64
Scope=link

View File

@ -0,0 +1,2 @@
[Network]
ManageForeignRoutes=no

View File

@ -16,6 +16,7 @@ from shutil import copytree
network_unit_file_path='/run/systemd/network'
networkd_runtime_directory='/run/systemd/netif'
networkd_conf_dropin_path='/run/systemd/networkd.conf.d'
networkd_ci_path='/run/networkd-ci'
network_sysctl_ipv6_path='/proc/sys/net/ipv6/conf'
network_sysctl_ipv4_path='/proc/sys/net/ipv4/conf'
@ -263,6 +264,7 @@ def setUpModule():
global running_units
os.makedirs(network_unit_file_path, exist_ok=True)
os.makedirs(networkd_conf_dropin_path, exist_ok=True)
os.makedirs(networkd_ci_path, exist_ok=True)
shutil.rmtree(networkd_ci_path)
@ -460,6 +462,17 @@ def remove_unit_from_networkd_path(units):
if (os.path.exists(os.path.join(network_unit_file_path, unit + '.d'))):
shutil.rmtree(os.path.join(network_unit_file_path, unit + '.d'))
def copy_networkd_conf_dropin(*dropins):
"""Copy networkd.conf dropin files into the testbed."""
for dropin in dropins:
shutil.copy(os.path.join(networkd_ci_path, dropin), networkd_conf_dropin_path)
def remove_networkd_conf_dropin(dropins):
"""Remove previously copied networkd.conf dropin files from the testbed."""
for dropin in dropins:
if (os.path.exists(os.path.join(networkd_conf_dropin_path, dropin))):
os.remove(os.path.join(networkd_conf_dropin_path, dropin))
def start_dnsmasq(additional_options='', ipv4_range='192.168.5.10,192.168.5.200', ipv6_range='2600::10,2600::20', lease_time='1h'):
dnsmasq_command = f'dnsmasq -8 /var/run/networkd-ci/test-dnsmasq-log-file --log-queries=extra --log-dhcp --pid-file=/var/run/networkd-ci/test-test-dnsmasq.pid --conf-file=/dev/null --interface=veth-peer --enable-ra --dhcp-range={ipv6_range},{lease_time} --dhcp-range={ipv4_range},{lease_time} -R --dhcp-leasefile=/var/run/networkd-ci/lease --dhcp-option=26,1492 --dhcp-option=option:router,192.168.5.1 --port=0 ' + additional_options
check_output(dnsmasq_command)
@ -1858,6 +1871,10 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
'routing-policy-rule-reconfigure2.network',
]
networkd_conf_dropins = [
'networkd-manage-foreign-routes-no.conf',
]
routing_policy_rule_tables = ['7', '8', '9', '10', '1011']
routes = [['blackhole', '202.54.1.2'], ['unreachable', '202.54.1.3'], ['prohibit', '202.54.1.4']]
@ -1875,6 +1892,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
remove_routes(self.routes)
remove_links(self.links)
remove_unit_from_networkd_path(self.units)
remove_networkd_conf_dropin(self.networkd_conf_dropins)
stop_networkd(show_logs=True)
call('ip netns del ns99', stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
@ -2253,7 +2271,10 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
self.assertRegex(output, 'lookup 7')
self.assertRegex(output, 'uidrange 100-200')
def test_route_static(self):
def _test_route_static(self, manage_foreign_routes):
if not manage_foreign_routes:
copy_networkd_conf_dropin('networkd-manage-foreign-routes-no.conf')
copy_unit_to_networkd_unit_path('25-route-static.network', '12-dummy.netdev')
start_networkd()
self.wait_online(['dummy98:routable'])
@ -2266,6 +2287,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
print(output)
self.assertIn('2001:1234:5:8fff:ff:ff:ff:ff proto static', output)
self.assertIn('2001:1234:5:8f63::1 proto kernel', output)
self.assertIn('2001:1234:5:afff:ff:ff:ff:ff via fe80:0:222:4dff:ff:ff:ff:ff proto static', output)
print('### ip -6 route show default')
output = check_output('ip -6 route show default')
@ -2459,6 +2481,13 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
print(output)
self.assertEqual(output, '')
self.tearDown()
def test_route_static(self):
for manage_foreign_routes in [True, False]:
with self.subTest(manage_foreign_routes=manage_foreign_routes):
self._test_route_static(manage_foreign_routes)
@expectedFailureIfRTA_VIAIsNotSupported()
def test_route_via_ipv6(self):
copy_unit_to_networkd_unit_path('25-route-via-ipv6.network', '12-dummy.netdev')
@ -2907,6 +2936,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
self.assertIn('id 3 dev veth99', output)
self.assertIn('id 4 dev veth99', output)
self.assertRegex(output, 'id 5 via 192.168.10.1 dev veth99 .*onlink')
self.assertIn('id 8 via fe80:0:222:4dff:ff:ff:ff:ff dev veth99', output)
self.assertRegex(output, r'id [0-9]* via 192.168.5.2 dev veth99')
output = check_output('ip nexthop list dev dummy98')
@ -3614,7 +3644,7 @@ class NetworkdBridgeTests(unittest.TestCase, Utilities):
output = check_output('ip rule list table 100')
print(output)
self.assertIn('0: from all to 8.8.8.8 lookup 100', output)
self.assertIn('from all to 8.8.8.8 lookup 100', output)
class NetworkdLLDPTests(unittest.TestCase, Utilities):
links = ['veth99']