Compare commits
12 Commits
e149ba1b1f
...
a0223c308e
Author | SHA1 | Date |
---|---|---|
Elias Probst | a0223c308e | |
Yu Watanabe | 80762cccdc | |
Zbigniew Jędrzejewski-Szmek | a5258a0cb0 | |
Dan Streetman | 352ab9d740 | |
Yu Watanabe | 377a9545e9 | |
Yu Watanabe | 5a8775bb39 | |
Yu Watanabe | 43d4bc9f56 | |
Yu Watanabe | 1132a714ec | |
Yu Watanabe | 5f4d7aa458 | |
Yu Watanabe | bac319a795 | |
Yu Watanabe | b1dc5946e2 | |
Yu Watanabe | 9b3e49fc00 |
2
NEWS
2
NEWS
|
@ -1254,7 +1254,7 @@ CHANGES WITH 245:
|
|||
configuration drop-ins are present, no action is taken.
|
||||
|
||||
* A new component "userdb" has been added, along with a small daemon
|
||||
"systemd-userdb.service" and a client tool "userdbctl". The framework
|
||||
"systemd-userdbd.service" and a client tool "userdbctl". The framework
|
||||
allows defining rich user and group records in a JSON format,
|
||||
extending on the classic "struct passwd" and "struct group"
|
||||
structures. Various components in systemd have been updated to
|
||||
|
|
4
TODO
4
TODO
|
@ -20,7 +20,7 @@ Janitorial Clean-ups:
|
|||
|
||||
Features:
|
||||
|
||||
* teach LoadCredential= the ability to load all files from a specfied dir as
|
||||
* teach LoadCredential= the ability to load all files from a specified dir as
|
||||
individual creds
|
||||
|
||||
* systemd-analyze netif that explains predictable interface (or networkctl)
|
||||
|
@ -49,7 +49,7 @@ Features:
|
|||
that the kernel does what we otherwise do.
|
||||
|
||||
* homed: keep an fd to the homedir open at all times, to keep the fs pinned
|
||||
(autofs and such) while user is loged in.
|
||||
(autofs and such) while user is logged in.
|
||||
|
||||
* nss-systemd: also synthesize shadow records for users/groups
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@ identifier (The ID field of `/etc/os-release`). Example:
|
|||
|
||||
In order to maximize compatibility with file system implementations and
|
||||
restricted boot loader environments, and to minimize conflicting character use
|
||||
with other progams, file names shall be chosen from a restricted character set:
|
||||
with other programs, file names shall be chosen from a restricted character set:
|
||||
ASCII upper and lower case characters, digits, "+", "-", "_" and ".". Also, the
|
||||
file names should have a length of at least one and at most 255 characters
|
||||
(including file name suffix).
|
||||
|
|
|
@ -87,7 +87,7 @@
|
|||
pager may be enabled automatically as describe above. Setting <varname>SYSTEMD_PAGERSECURE=0</varname>
|
||||
or not removing it from the inherited environment allows the user to invoke arbitrary commands. Note
|
||||
that if the <varname>$SYSTEMD_PAGER</varname> or <varname>$PAGER</varname> variables are to be
|
||||
honoured, <varname>$SYSTEMD_PAGERSECURE</varname> must be set too. It might be reasonable to completly
|
||||
honoured, <varname>$SYSTEMD_PAGERSECURE</varname> must be set too. It might be reasonable to completely
|
||||
disable the pager using <option>--no-pager</option> instead.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@
|
|||
|
||||
<orderedlist>
|
||||
<listitem><para>If <filename>/etc/machine-id</filename> does not exist, this is a first boot. During
|
||||
early boot, <command>systemd</command> will write <literal>unitialized\n</literal> to this file and overmount
|
||||
early boot, <command>systemd</command> will write <literal>uninitialized\n</literal> to this file and overmount
|
||||
a temporary file which contains the actual machine ID. Later (after <filename>first-boot-complete.target</filename>
|
||||
has been reached), the real machine ID will be written to disk.</para></listitem>
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@
|
|||
<varname>luks.uuid=</varname>, the data device will be set to the one specified by
|
||||
<varname>rd.luks.data=</varname> or <varname>luks.data=</varname> of the corresponding UUID.</para>
|
||||
|
||||
<para>LUKS data device parameter is usefull for specifying encrypted data devices with detached headers specified in
|
||||
<para>LUKS data device parameter is useful for specifying encrypted data devices with detached headers specified in
|
||||
<varname>luks.options</varname> entry containing <literal>header=</literal> argument. For example,
|
||||
<varname>rd.luks.uuid=</varname>b40f1abf-2a53-400a-889a-2eccc27eaa40
|
||||
<varname>rd.luks.options=</varname>b40f1abf-2a53-400a-889a-2eccc27eaa40=header=/path/to/luks.hdr
|
||||
|
|
|
@ -184,7 +184,7 @@
|
|||
|
||||
<para>In case of single-label names, when search domains are defined, the same logic applies, except
|
||||
that the name is first suffixed by each of the search domains in turn. Note that this search logic
|
||||
doesn't apply to any names with at least one dot. Also see the discussion about compatiblity with
|
||||
doesn't apply to any names with at least one dot. Also see the discussion about compatibility with
|
||||
the traditional glibc resolver below.</para></listitem>
|
||||
|
||||
<listitem><para>If a query does not match any configured routing domain (either per-link or global), it
|
||||
|
@ -232,7 +232,7 @@
|
|||
<filename>/etc/hosts</filename>.</para></listitem>
|
||||
|
||||
<listitem><para>Single-label names are not resolved for A and AAAA records using unicast DNS (unless
|
||||
overriden with <varname>ResolveUnicastSingleLabel=</varname>, see
|
||||
overridden with <varname>ResolveUnicastSingleLabel=</varname>, see
|
||||
<citerefentry><refentrytitle>resolved.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
|
||||
This is similar to the <option>no-tld-query</option> option being set in
|
||||
<citerefentry><refentrytitle>resolv.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
|
||||
|
|
|
@ -885,7 +885,7 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
|
|||
<citerefentry><refentrytitle>umask</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
|
||||
details. Defaults to 0022 for system units. For user units the default value is inherited from the
|
||||
per-user service manager (whose default is in turn inherited from the system service manager, and
|
||||
thus typically also is 0022 — unless overriden by a PAM module). In order to change the per-user mask
|
||||
thus typically also is 0022 — unless overridden by a PAM module). In order to change the per-user mask
|
||||
for all user services, consider setting the <varname>UMask=</varname> setting of the user's
|
||||
<filename>user@.service</filename> system service instance. The per-user umask may also be set via
|
||||
the <varname>umask</varname> field of a user's <ulink url="https://systemd.io/USER_RECORD">JSON User
|
||||
|
|
|
@ -362,7 +362,7 @@
|
|||
<varlistentry>
|
||||
<term><constant>v247</constant></term>
|
||||
|
||||
<listitem><para>If the PCI slot is assocated with PCI bridge and that has multiple child network
|
||||
<listitem><para>If the PCI slot is associated with PCI bridge and that has multiple child network
|
||||
controllers then all of them might derive the same value of <varname>ID_NET_NAME_SLOT</varname>
|
||||
property. That could cause naming conflict if the property is selected as a device name. Now, we detect the
|
||||
situation, slot - bridge relation, and we don't produce the <varname>ID_NET_NAME_SLOT</varname> property to
|
||||
|
|
|
@ -14,13 +14,13 @@
|
|||
#include "sd-dhcp-client.h"
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "async.h"
|
||||
#include "dhcp-identifier.h"
|
||||
#include "dhcp-internal.h"
|
||||
#include "dhcp-lease-internal.h"
|
||||
#include "dhcp-protocol.h"
|
||||
#include "dns-domain.h"
|
||||
#include "event-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "hostname-util.h"
|
||||
#include "io-util.h"
|
||||
#include "memory-util.h"
|
||||
|
@ -681,7 +681,7 @@ static int client_initialize(sd_dhcp_client *client) {
|
|||
|
||||
client->receive_message = sd_event_source_unref(client->receive_message);
|
||||
|
||||
client->fd = asynchronous_close(client->fd);
|
||||
client->fd = safe_close(client->fd);
|
||||
|
||||
(void) event_source_disable(client->timeout_resend);
|
||||
(void) event_source_disable(client->timeout_t1);
|
||||
|
@ -1426,7 +1426,7 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata)
|
|||
assert(client);
|
||||
|
||||
client->receive_message = sd_event_source_unref(client->receive_message);
|
||||
client->fd = asynchronous_close(client->fd);
|
||||
client->fd = safe_close(client->fd);
|
||||
|
||||
client->state = DHCP_STATE_REBINDING;
|
||||
client->attempt = 0;
|
||||
|
@ -1783,7 +1783,7 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, i
|
|||
(void) event_source_disable(client->timeout_resend);
|
||||
client->receive_message =
|
||||
sd_event_source_unref(client->receive_message);
|
||||
client->fd = asynchronous_close(client->fd);
|
||||
client->fd = safe_close(client->fd);
|
||||
|
||||
if (IN_SET(client->state, DHCP_STATE_REQUESTING,
|
||||
DHCP_STATE_REBOOTING))
|
||||
|
|
|
@ -68,7 +68,7 @@ static void test_login(void) {
|
|||
|
||||
r = sd_pid_get_cgroup(0, &cgroup);
|
||||
log_info("sd_pid_get_cgroup(0, …) → %s / \"%s\"", e(r), strnull(cgroup));
|
||||
assert_se(r == 0);
|
||||
assert_se(IN_SET(r, 0, -ENOMEDIUM));
|
||||
|
||||
r = sd_uid_get_display(u2, &display_session);
|
||||
log_info("sd_uid_get_display("UID_FMT", …) → %s / \"%s\"", u2, e(r), strnull(display_session));
|
||||
|
|
|
@ -84,7 +84,7 @@ static int ipv6_proxy_ndp_set(Link *link) {
|
|||
|
||||
r = sysctl_write_ip_property_boolean(AF_INET6, link->ifname, "proxy_ndp", v);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Cannot configure proxy NDP for the interface: %m");
|
||||
return log_link_warning_errno(link, r, "Cannot configure proxy NDP for the interface, ignoring: %m");
|
||||
|
||||
return v;
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ int link_set_ipv6_proxy_ndp_addresses(Link *link) {
|
|||
/* enable or disable proxy_ndp itself depending on whether ipv6_proxy_ndp_addresses are set or not */
|
||||
r = ipv6_proxy_ndp_set(link);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
return 0;
|
||||
|
||||
SET_FOREACH(address, link->network->ipv6_proxy_ndp_addresses) {
|
||||
r = ipv6_proxy_ndp_address_configure(link, address);
|
||||
|
|
|
@ -581,6 +581,110 @@ static int route_add(Manager *manager, Link *link, const Route *in, const Multip
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int route_set_netlink_message(const Route *route, sd_netlink_message *req, Link *link) {
|
||||
unsigned flags;
|
||||
int r;
|
||||
|
||||
assert(route);
|
||||
assert(req);
|
||||
|
||||
/* link may be NULL */
|
||||
|
||||
if (in_addr_is_null(route->gw_family, &route->gw) == 0) {
|
||||
if (route->gw_family == route->family) {
|
||||
r = netlink_message_append_in_addr_union(req, RTA_GATEWAY, route->gw_family, &route->gw);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_GATEWAY attribute: %m");
|
||||
} else {
|
||||
RouteVia rtvia = {
|
||||
.family = route->gw_family,
|
||||
.address = route->gw,
|
||||
};
|
||||
|
||||
r = sd_netlink_message_append_data(req, RTA_VIA, &rtvia, sizeof(rtvia));
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_VIA attribute: %m");
|
||||
}
|
||||
}
|
||||
|
||||
if (route->dst_prefixlen > 0) {
|
||||
r = netlink_message_append_in_addr_union(req, RTA_DST, route->family, &route->dst);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_DST attribute: %m");
|
||||
|
||||
r = sd_rtnl_message_route_set_dst_prefixlen(req, route->dst_prefixlen);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set destination prefix length: %m");
|
||||
}
|
||||
|
||||
if (route->src_prefixlen > 0) {
|
||||
r = netlink_message_append_in_addr_union(req, RTA_SRC, route->family, &route->src);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_SRC attribute: %m");
|
||||
|
||||
r = sd_rtnl_message_route_set_src_prefixlen(req, route->src_prefixlen);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set source prefix length: %m");
|
||||
}
|
||||
|
||||
if (in_addr_is_null(route->family, &route->prefsrc) == 0) {
|
||||
r = netlink_message_append_in_addr_union(req, RTA_PREFSRC, route->family, &route->prefsrc);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_PREFSRC attribute: %m");
|
||||
}
|
||||
|
||||
r = sd_rtnl_message_route_set_scope(req, route->scope);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set scope: %m");
|
||||
|
||||
flags = route->flags;
|
||||
if (route->gateway_onlink >= 0)
|
||||
SET_FLAG(flags, RTNH_F_ONLINK, route->gateway_onlink);
|
||||
|
||||
r = sd_rtnl_message_route_set_flags(req, flags);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set flags: %m");
|
||||
|
||||
if (route->table != RT_TABLE_MAIN) {
|
||||
if (route->table < 256) {
|
||||
r = sd_rtnl_message_route_set_table(req, route->table);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set route table: %m");
|
||||
} else {
|
||||
r = sd_rtnl_message_route_set_table(req, RT_TABLE_UNSPEC);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set route table: %m");
|
||||
|
||||
/* Table attribute to allow more than 256. */
|
||||
r = sd_netlink_message_append_data(req, RTA_TABLE, &route->table, sizeof(route->table));
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_TABLE attribute: %m");
|
||||
}
|
||||
}
|
||||
|
||||
r = sd_rtnl_message_route_set_type(req, route->type);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set route type: %m");
|
||||
|
||||
if (!IN_SET(route->type, RTN_UNREACHABLE, RTN_PROHIBIT, RTN_BLACKHOLE, RTN_THROW)) {
|
||||
assert(link); /* Those routes must be attached to a specific link */
|
||||
|
||||
r = sd_netlink_message_append_u32(req, RTA_OIF, link->ifindex);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_OIF attribute: %m");
|
||||
}
|
||||
|
||||
r = sd_netlink_message_append_u8(req, RTA_PREF, route->pref);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_PREF attribute: %m");
|
||||
|
||||
r = sd_netlink_message_append_u32(req, RTA_PRIORITY, route->priority);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_PRIORITY attribute: %m");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int route_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
|
@ -642,66 +746,11 @@ int route_remove(
|
|||
strna(route_type_to_string(route->type)));
|
||||
}
|
||||
|
||||
if (in_addr_is_null(route->gw_family, &route->gw) == 0) {
|
||||
if (route->gw_family == route->family) {
|
||||
r = netlink_message_append_in_addr_union(req, RTA_GATEWAY, route->gw_family, &route->gw);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_GATEWAY attribute: %m");
|
||||
} else {
|
||||
RouteVia rtvia = {
|
||||
.family = route->gw_family,
|
||||
.address = route->gw,
|
||||
};
|
||||
|
||||
r = sd_netlink_message_append_data(req, RTA_VIA, &rtvia, sizeof(rtvia));
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_VIA attribute: %m");
|
||||
}
|
||||
}
|
||||
|
||||
if (route->dst_prefixlen) {
|
||||
r = netlink_message_append_in_addr_union(req, RTA_DST, route->family, &route->dst);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_DST attribute: %m");
|
||||
|
||||
r = sd_rtnl_message_route_set_dst_prefixlen(req, route->dst_prefixlen);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set destination prefix length: %m");
|
||||
}
|
||||
|
||||
if (route->src_prefixlen) {
|
||||
r = netlink_message_append_in_addr_union(req, RTA_SRC, route->family, &route->src);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_SRC attribute: %m");
|
||||
|
||||
r = sd_rtnl_message_route_set_src_prefixlen(req, route->src_prefixlen);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set source prefix length: %m");
|
||||
}
|
||||
|
||||
if (in_addr_is_null(route->family, &route->prefsrc) == 0) {
|
||||
r = netlink_message_append_in_addr_union(req, RTA_PREFSRC, route->family, &route->prefsrc);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_PREFSRC attribute: %m");
|
||||
}
|
||||
|
||||
r = sd_rtnl_message_route_set_scope(req, route->scope);
|
||||
r = route_set_netlink_message(route, req, link);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set scope: %m");
|
||||
return r;
|
||||
|
||||
r = sd_netlink_message_append_u32(req, RTA_PRIORITY, route->priority);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_PRIORITY attribute: %m");
|
||||
|
||||
if (!IN_SET(route->type, RTN_UNREACHABLE, RTN_PROHIBIT, RTN_BLACKHOLE, RTN_THROW)) {
|
||||
assert(link); /* Those routes must be attached to a specific link */
|
||||
|
||||
r = sd_netlink_message_append_u32(req, RTA_OIF, link->ifindex);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_OIF attribute: %m");
|
||||
}
|
||||
|
||||
r = netlink_call_async(link->manager->rtnl, NULL, req,
|
||||
r = netlink_call_async(manager->rtnl, NULL, req,
|
||||
callback ?: route_remove_handler,
|
||||
link_netlink_destroy_callback, link);
|
||||
if (r < 0)
|
||||
|
@ -712,7 +761,7 @@ int route_remove(
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool link_is_static_route_configured(const Link *link, const Route *route) {
|
||||
static bool link_has_route(const Link *link, const Route *route) {
|
||||
Route *net_route;
|
||||
|
||||
assert(link);
|
||||
|
@ -728,11 +777,78 @@ static bool link_is_static_route_configured(const Link *link, const Route *route
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool links_have_route(Manager *manager, const Route *route, const Link *except) {
|
||||
Link *link;
|
||||
|
||||
assert(manager);
|
||||
|
||||
HASHMAP_FOREACH(link, manager->links) {
|
||||
if (link == except)
|
||||
continue;
|
||||
|
||||
if (link_has_route(link, route))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int manager_drop_foreign_routes(Manager *manager) {
|
||||
Route *route;
|
||||
int k, r = 0;
|
||||
|
||||
assert(manager);
|
||||
|
||||
SET_FOREACH(route, manager->routes_foreign) {
|
||||
/* do not touch routes managed by the kernel */
|
||||
if (route->protocol == RTPROT_KERNEL)
|
||||
continue;
|
||||
|
||||
if (links_have_route(manager, route, NULL))
|
||||
/* The route will be configured later. */
|
||||
continue;
|
||||
|
||||
/* The existing links do not have the route. Let's drop this now. It may by
|
||||
* re-configured later. */
|
||||
k = route_remove(route, manager, NULL, NULL);
|
||||
if (k < 0 && r >= 0)
|
||||
r = k;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int manager_drop_routes(Manager *manager, Link *except) {
|
||||
Route *route;
|
||||
int k, r = 0;
|
||||
|
||||
assert(manager);
|
||||
|
||||
SET_FOREACH(route, manager->routes) {
|
||||
/* do not touch routes managed by the kernel */
|
||||
if (route->protocol == RTPROT_KERNEL)
|
||||
continue;
|
||||
|
||||
if (links_have_route(manager, route, except))
|
||||
/* The route will be configured later. */
|
||||
continue;
|
||||
|
||||
/* The existing links do not have the route. Let's drop this now. It may by
|
||||
* re-configured later. */
|
||||
k = route_remove(route, manager, NULL, NULL);
|
||||
if (k < 0 && r >= 0)
|
||||
r = k;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int link_drop_foreign_routes(Link *link) {
|
||||
Route *route;
|
||||
int k, r = 0;
|
||||
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
|
||||
SET_FOREACH(route, link->routes_foreign) {
|
||||
/* do not touch routes managed by the kernel */
|
||||
|
@ -756,7 +872,7 @@ int link_drop_foreign_routes(Link *link) {
|
|||
FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP))
|
||||
continue;
|
||||
|
||||
if (link_is_static_route_configured(link, route))
|
||||
if (link_has_route(link, route))
|
||||
k = route_add(NULL, link, route, NULL, NULL);
|
||||
else
|
||||
k = route_remove(route, NULL, link, NULL);
|
||||
|
@ -764,6 +880,10 @@ int link_drop_foreign_routes(Link *link) {
|
|||
r = k;
|
||||
}
|
||||
|
||||
k = manager_drop_foreign_routes(link->manager);
|
||||
if (k < 0 && r >= 0)
|
||||
r = k;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -783,6 +903,10 @@ int link_drop_routes(Link *link) {
|
|||
r = k;
|
||||
}
|
||||
|
||||
k = manager_drop_routes(link->manager, link);
|
||||
if (k < 0 && r >= 0)
|
||||
r = k;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -930,7 +1054,6 @@ int route_configure(
|
|||
Route **ret) {
|
||||
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
|
||||
unsigned flags;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
|
@ -974,85 +1097,9 @@ int route_configure(
|
|||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not create RTM_NEWROUTE message: %m");
|
||||
|
||||
if (in_addr_is_null(route->gw_family, &route->gw) == 0) {
|
||||
if (route->gw_family == route->family) {
|
||||
r = netlink_message_append_in_addr_union(req, RTA_GATEWAY, route->gw_family, &route->gw);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_GATEWAY attribute: %m");
|
||||
} else {
|
||||
RouteVia rtvia = {
|
||||
.family = route->gw_family,
|
||||
.address = route->gw,
|
||||
};
|
||||
|
||||
r = sd_netlink_message_append_data(req, RTA_VIA, &rtvia, sizeof(rtvia));
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_VIA attribute: %m");
|
||||
}
|
||||
}
|
||||
|
||||
if (route->dst_prefixlen > 0) {
|
||||
r = netlink_message_append_in_addr_union(req, RTA_DST, route->family, &route->dst);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_DST attribute: %m");
|
||||
|
||||
r = sd_rtnl_message_route_set_dst_prefixlen(req, route->dst_prefixlen);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set destination prefix length: %m");
|
||||
}
|
||||
|
||||
if (route->src_prefixlen > 0) {
|
||||
r = netlink_message_append_in_addr_union(req, RTA_SRC, route->family, &route->src);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_SRC attribute: %m");
|
||||
|
||||
r = sd_rtnl_message_route_set_src_prefixlen(req, route->src_prefixlen);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set source prefix length: %m");
|
||||
}
|
||||
|
||||
if (in_addr_is_null(route->family, &route->prefsrc) == 0) {
|
||||
r = netlink_message_append_in_addr_union(req, RTA_PREFSRC, route->family, &route->prefsrc);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_PREFSRC attribute: %m");
|
||||
}
|
||||
|
||||
r = sd_rtnl_message_route_set_scope(req, route->scope);
|
||||
r = route_set_netlink_message(route, req, link);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set scope: %m");
|
||||
|
||||
flags = route->flags;
|
||||
if (route->gateway_onlink >= 0)
|
||||
SET_FLAG(flags, RTNH_F_ONLINK, route->gateway_onlink);
|
||||
|
||||
r = sd_rtnl_message_route_set_flags(req, flags);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set flags: %m");
|
||||
|
||||
if (route->table != RT_TABLE_MAIN) {
|
||||
if (route->table < 256) {
|
||||
r = sd_rtnl_message_route_set_table(req, route->table);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set route table: %m");
|
||||
} else {
|
||||
r = sd_rtnl_message_route_set_table(req, RT_TABLE_UNSPEC);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set route table: %m");
|
||||
|
||||
/* Table attribute to allow more than 256. */
|
||||
r = sd_netlink_message_append_data(req, RTA_TABLE, &route->table, sizeof(route->table));
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_TABLE attribute: %m");
|
||||
}
|
||||
}
|
||||
|
||||
r = sd_netlink_message_append_u32(req, RTA_PRIORITY, route->priority);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_PRIORITY attribute: %m");
|
||||
|
||||
r = sd_netlink_message_append_u8(req, RTA_PREF, route->pref);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_PREF attribute: %m");
|
||||
return r;
|
||||
|
||||
if (route->lifetime != USEC_INFINITY && kernel_route_expiration_supported()) {
|
||||
r = sd_netlink_message_append_u32(req, RTA_EXPIRES,
|
||||
|
@ -1061,16 +1108,6 @@ int route_configure(
|
|||
return log_link_error_errno(link, r, "Could not append RTA_EXPIRES attribute: %m");
|
||||
}
|
||||
|
||||
r = sd_rtnl_message_route_set_type(req, route->type);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not set route type: %m");
|
||||
|
||||
if (!IN_SET(route->type, RTN_UNREACHABLE, RTN_PROHIBIT, RTN_BLACKHOLE, RTN_THROW)) {
|
||||
r = sd_netlink_message_append_u32(req, RTA_OIF, link->ifindex);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_OIF attribute: %m");
|
||||
}
|
||||
|
||||
if (route->ttl_propagate >= 0) {
|
||||
r = sd_netlink_message_append_u8(req, RTA_TTL_PROPAGATE, route->ttl_propagate);
|
||||
if (r < 0)
|
||||
|
|
|
@ -194,7 +194,7 @@ int link_set_sysctl(Link *link) {
|
|||
|
||||
r = link_set_ipv6_privacy_extensions(link);
|
||||
if (r < 0)
|
||||
log_link_warning_errno(link, r, "Cannot configure IPv6 privacy extension for interface, ignorign: %m");
|
||||
log_link_warning_errno(link, r, "Cannot configure IPv6 privacy extension for interface, ignoring: %m");
|
||||
|
||||
r = link_set_ipv6_accept_ra(link);
|
||||
if (r < 0)
|
||||
|
|
|
@ -270,7 +270,7 @@ static int attach_empty_file(int loop, int nr) {
|
|||
* partitions results in immediatey IO errors. There's no pretty way to get rid of them
|
||||
* again. Neither LOOP_CLR_FD nor LOOP_CTL_REMOVE suffice (see above). What does work is to
|
||||
* reassociate them with a new fd however. This is what we do here hence: we associate the devices
|
||||
* with an empty file (i.e. an image that definitely has no partitons). We then immediately clear it
|
||||
* with an empty file (i.e. an image that definitely has no partitions). We then immediately clear it
|
||||
* again. This suffices to make the partitions go away. Ugly but appears to work. */
|
||||
|
||||
log_debug("Found unattached loopback block device /dev/loop%i with partitions. Attaching empty file to remove them.", nr);
|
||||
|
|
|
@ -3,3 +3,6 @@ Name=veth99
|
|||
|
||||
[Network]
|
||||
IPv6AcceptRA=true
|
||||
|
||||
[IPv6AcceptRA]
|
||||
UseDomains=yes
|
||||
|
|
|
@ -7,6 +7,7 @@ IPv6SendRA=yes
|
|||
[IPv6SendRA]
|
||||
DNS=_link_local 2002:da8:1:0::1
|
||||
DNSLifetimeSec=1min
|
||||
Domains=hogehoge.test
|
||||
|
||||
[IPv6Prefix]
|
||||
Prefix=2002:da8:1:0::/64
|
||||
|
|
|
@ -2230,6 +2230,66 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
|||
self.assertRegex(output, 'via 2001:1234:5:8fff:ff:ff:ff:ff dev dummy98')
|
||||
self.assertRegex(output, 'via 2001:1234:5:9fff:ff:ff:ff:ff dev dummy98')
|
||||
|
||||
copy_unit_to_networkd_unit_path('25-address-static.network')
|
||||
check_output(*networkctl_cmd, 'reload', env=env)
|
||||
self.wait_online(['dummy98:routable'])
|
||||
|
||||
# check all routes managed by Manager are removed
|
||||
print('### ip route show type blackhole')
|
||||
output = check_output('ip route show type blackhole')
|
||||
print(output)
|
||||
self.assertEqual(output, '')
|
||||
|
||||
print('### ip route show type unreachable')
|
||||
output = check_output('ip route show type unreachable')
|
||||
print(output)
|
||||
self.assertEqual(output, '')
|
||||
|
||||
print('### ip route show type prohibit')
|
||||
output = check_output('ip route show type prohibit')
|
||||
print(output)
|
||||
self.assertEqual(output, '')
|
||||
|
||||
remove_unit_from_networkd_path(['25-address-static.network'])
|
||||
check_output(*networkctl_cmd, 'reload', env=env)
|
||||
self.wait_online(['dummy98:routable'])
|
||||
|
||||
# check all routes managed by Manager are reconfigured
|
||||
print('### ip route show type blackhole')
|
||||
output = check_output('ip route show type blackhole')
|
||||
print(output)
|
||||
self.assertRegex(output, 'blackhole 202.54.1.2 proto static')
|
||||
|
||||
print('### ip route show type unreachable')
|
||||
output = check_output('ip route show type unreachable')
|
||||
print(output)
|
||||
self.assertRegex(output, 'unreachable 202.54.1.3 proto static')
|
||||
|
||||
print('### ip route show type prohibit')
|
||||
output = check_output('ip route show type prohibit')
|
||||
print(output)
|
||||
self.assertRegex(output, 'prohibit 202.54.1.4 proto static')
|
||||
|
||||
rc = call("ip link del dummy98")
|
||||
self.assertEqual(rc, 0)
|
||||
time.sleep(2)
|
||||
|
||||
# check all routes managed by Manager are removed
|
||||
print('### ip route show type blackhole')
|
||||
output = check_output('ip route show type blackhole')
|
||||
print(output)
|
||||
self.assertEqual(output, '')
|
||||
|
||||
print('### ip route show type unreachable')
|
||||
output = check_output('ip route show type unreachable')
|
||||
print(output)
|
||||
self.assertEqual(output, '')
|
||||
|
||||
print('### ip route show type prohibit')
|
||||
output = check_output('ip route show type prohibit')
|
||||
print(output)
|
||||
self.assertEqual(output, '')
|
||||
|
||||
@expectedFailureIfRTA_VIAIsNotSupported()
|
||||
def test_route_via_ipv6(self):
|
||||
copy_unit_to_networkd_unit_path('25-route-via-ipv6.network', '12-dummy.netdev')
|
||||
|
@ -3254,6 +3314,10 @@ class NetworkdRATests(unittest.TestCase, Utilities):
|
|||
self.assertRegex(output, 'fe80::')
|
||||
self.assertRegex(output, '2002:da8:1::1')
|
||||
|
||||
output = check_output(*resolvectl_cmd, 'domain', 'veth99', env=env)
|
||||
print(output)
|
||||
self.assertIn('hogehoge.test', output)
|
||||
|
||||
output = check_output(*networkctl_cmd, '-n', '0', 'status', 'veth99', env=env)
|
||||
print(output)
|
||||
self.assertRegex(output, '2002:da8:1:0')
|
||||
|
|
Loading…
Reference in New Issue