1
0
mirror of https://github.com/systemd/systemd synced 2025-09-26 23:34:44 +02:00

Compare commits

..

No commits in common. "836540070dcc1325f6159df40dc64f3cdf95e8e3" and "5b49641015adcc7e8edbb9e8e54d5ac5ddf3bf52" have entirely different histories.

13 changed files with 159 additions and 302 deletions

View File

@ -299,10 +299,7 @@ s - Service VLAN, m - Two-port MAC Relay (TPMR)
<command>reconfigure</command> <command>reconfigure</command>
<replaceable>DEVICE…</replaceable> <replaceable>DEVICE…</replaceable>
</term> </term>
<listitem><para>Reconfigure network interfaces. Takes interface name or index number. Note that <listitem><para>Reconfigure network interfaces. Takes interface name or index number.</para></listitem>
this does not reload <filename>.netdev</filename> or <filename>.network</filename>
corresponding to the the specifed interface. So, if you edit config files, it is necessary to
call <command>networkctl reload</command> first to apply new settings.</para></listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>

View File

@ -179,13 +179,6 @@ node /org/freedesktop/systemd1 {
DisableUnitFiles(in as files, DisableUnitFiles(in as files,
in b runtime, in b runtime,
out a(sss) changes); out a(sss) changes);
EnableUnitFilesWithFlags(in as files,
in t flags,
out b carries_install_info,
out a(sss) changes);
DisableUnitFilesWithFlags(in as files,
in t flags,
out a(sss) changes);
ReenableUnitFiles(in as files, ReenableUnitFiles(in as files,
in b runtime, in b runtime,
in b force, in b force,
@ -843,10 +836,6 @@ node /org/freedesktop/systemd1 {
<variablelist class="dbus-method" generated="True" extra-ref="DisableUnitFiles()"/> <variablelist class="dbus-method" generated="True" extra-ref="DisableUnitFiles()"/>
<variablelist class="dbus-method" generated="True" extra-ref="EnableUnitFilesWithFlags()"/>
<variablelist class="dbus-method" generated="True" extra-ref="DisableUnitFilesWithFlags()"/>
<variablelist class="dbus-method" generated="True" extra-ref="ReenableUnitFiles()"/> <variablelist class="dbus-method" generated="True" extra-ref="ReenableUnitFiles()"/>
<variablelist class="dbus-method" generated="True" extra-ref="LinkUnitFiles()"/> <variablelist class="dbus-method" generated="True" extra-ref="LinkUnitFiles()"/>
@ -1303,20 +1292,6 @@ node /org/freedesktop/systemd1 {
<para>Similarly, <function>DisableUnitFiles()</function> disables one or more units in the system, <para>Similarly, <function>DisableUnitFiles()</function> disables one or more units in the system,
i.e. removes all symlinks to them in <filename>/etc</filename> and <filename>/run</filename>.</para> i.e. removes all symlinks to them in <filename>/etc</filename> and <filename>/run</filename>.</para>
<para>The <function>EnableUnitFilesWithFlags()</function> and <function>DisableUnitFilesWithFlags()</function>
take in options as flags instead of booleans to allow for extendability, defined as follows:</para>
<programlisting>
#define SD_SYSTEMD_UNIT_RUNTIME (UINT64_C(1) &lt;&lt; 0)
#define SD_SYSTEMD_UNIT_FORCE (UINT64_C(1) &lt;&lt; 1)
#define SD_SYSTEMD_UNIT_PORTABLE (UINT64_C(1) &lt;&lt; 2)
</programlisting>
<para><varname>SD_SYSTEMD_UNIT_RUNTIME</varname> will enable or disable the unit for runtime only,
<varname>SD_SYSTEMD_UNIT_FORCE</varname> controls whether symlinks pointing to other units shall be
replaced if necessary. <varname>SD_SYSTEMD_UNIT_PORTABLE</varname> will add or remove the symlinks in
<filename>/etc/systemd/system.attached</filename> and <filename>/run/systemd/system.attached</filename>.</para>
<para>Similarly, <function>ReenableUnitFiles()</function> applies the changes to one or more units that <para>Similarly, <function>ReenableUnitFiles()</function> applies the changes to one or more units that
would result from disabling and enabling the unit quickly one after the other in an atomic would result from disabling and enabling the unit quickly one after the other in an atomic
fashion. This is useful to apply updated [Install] information contained in unit files.</para> fashion. This is useful to apply updated [Install] information contained in unit files.</para>
@ -1505,7 +1480,6 @@ node /org/freedesktop/systemd1 {
<function>RestartUnit()</function> and similar, <function>SetProperty()</function>) require <function>RestartUnit()</function> and similar, <function>SetProperty()</function>) require
<interfacename>org.freedesktop.systemd1.manage-units</interfacename>. Operations which modify unit file <interfacename>org.freedesktop.systemd1.manage-units</interfacename>. Operations which modify unit file
enablement state (<function>EnableUnitFiles()</function>, <function>DisableUnitFiles()</function>, enablement state (<function>EnableUnitFiles()</function>, <function>DisableUnitFiles()</function>,
<function>EnableUnitFilesWithFlags()</function>, <function>DisableUnitFilesWithFlags()</function>,
<function>ReenableUnitFiles()</function>, <function>LinkUnitFiles()</function>, <function>ReenableUnitFiles()</function>, <function>LinkUnitFiles()</function>,
<function>PresetUnitFiles</function>, <function>MaskUnitFiles</function>, and similar) require <function>PresetUnitFiles</function>, <function>MaskUnitFiles</function>, and similar) require
<interfacename>org.freedesktop.systemd1.manage-unit-files</interfacename>. Operations which modify the <interfacename>org.freedesktop.systemd1.manage-unit-files</interfacename>. Operations which modify the

View File

@ -48,7 +48,6 @@ _resolvectl() {
[DNSSEC]='dnssec' [DNSSEC]='dnssec'
[DNSOVERTLS]='dnsovertls' [DNSOVERTLS]='dnsovertls'
[STANDALONE]='statistics reset-statistics flush-caches reset-server-features' [STANDALONE]='statistics reset-statistics flush-caches reset-server-features'
[LOG_LEVEL]='log-level'
) )
local -A ARGS=( local -A ARGS=(
[FAMILY]='tcp udp sctp' [FAMILY]='tcp udp sctp'
@ -96,9 +95,6 @@ _resolvectl() {
elif __contains_word "$verb" ${VERBS[STATUS]}; then elif __contains_word "$verb" ${VERBS[STATUS]}; then
comps="$interfaces" comps="$interfaces"
elif __contains_word "$verb" ${VERBS[LOG_LEVEL]}; then
comps='debug info notice warning err crit alert emerg'
elif __contains_word "$verb" ${VERBS[FAMILY]}; then elif __contains_word "$verb" ${VERBS[FAMILY]}; then
for ((i++; i < COMP_CWORD; i++)); do for ((i++; i < COMP_CWORD; i++)); do
if __contains_word "${COMP_WORDS[i]}" ${ARGS[FAMILY]} && if __contains_word "${COMP_WORDS[i]}" ${ARGS[FAMILY]} &&

View File

@ -34,7 +34,7 @@ int _set_ensure_allocated(Set **s, const struct hash_ops *hash_ops HASHMAP_DEBUG
int set_put(Set *s, const void *key); int set_put(Set *s, const void *key);
/* no set_update */ /* no set_update */
/* no set_replace */ /* no set_replace */
static inline void *set_get(const Set *s, const void *key) { static inline void *set_get(const Set *s, void *key) {
return _hashmap_get(HASHMAP_BASE((Set *) s), key); return _hashmap_get(HASHMAP_BASE((Set *) s), key);
} }
/* no set_get2 */ /* no set_get2 */

View File

@ -2083,7 +2083,7 @@ static int method_enable_unit_files_generic(
UnitFileChange *changes = NULL; UnitFileChange *changes = NULL;
size_t n_changes = 0; size_t n_changes = 0;
UnitFileFlags flags; UnitFileFlags flags;
int r; int runtime, force, r;
assert(message); assert(message);
assert(m); assert(m);
@ -2092,23 +2092,11 @@ static int method_enable_unit_files_generic(
if (r < 0) if (r < 0)
return r; return r;
if (sd_bus_message_is_method_call(message, NULL, "EnableUnitFilesWithFlags")) { r = sd_bus_message_read(message, "bb", &runtime, &force);
uint64_t raw_flags; if (r < 0)
return r;
r = sd_bus_message_read(message, "t", &raw_flags); flags = unit_file_bools_to_flags(runtime, force);
if (r < 0)
return r;
if ((raw_flags & ~_UNIT_FILE_FLAGS_MASK_PUBLIC) != 0)
return -EINVAL;
flags = raw_flags;
} else {
int runtime, force;
r = sd_bus_message_read(message, "bb", &runtime, &force);
if (r < 0)
return r;
flags = unit_file_bools_to_flags(runtime, force);
}
r = bus_verify_manage_unit_files_async(m, message, error); r = bus_verify_manage_unit_files_async(m, message, error);
if (r < 0) if (r < 0)
@ -2123,10 +2111,6 @@ static int method_enable_unit_files_generic(
return reply_unit_file_changes_and_free(m, message, carries_install_info ? r : -1, changes, n_changes, error); return reply_unit_file_changes_and_free(m, message, carries_install_info ? r : -1, changes, n_changes, error);
} }
static int method_enable_unit_files_with_flags(sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_enable_unit_files_generic(message, userdata, unit_file_enable, true, error);
}
static int method_enable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) { static int method_enable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_enable_unit_files_generic(message, userdata, unit_file_enable, true, error); return method_enable_unit_files_generic(message, userdata, unit_file_enable, true, error);
} }
@ -2204,9 +2188,8 @@ static int method_disable_unit_files_generic(
_cleanup_strv_free_ char **l = NULL; _cleanup_strv_free_ char **l = NULL;
UnitFileChange *changes = NULL; UnitFileChange *changes = NULL;
UnitFileFlags flags;
size_t n_changes = 0; size_t n_changes = 0;
int r; int r, runtime;
assert(message); assert(message);
assert(m); assert(m);
@ -2215,24 +2198,9 @@ static int method_disable_unit_files_generic(
if (r < 0) if (r < 0)
return r; return r;
if (sd_bus_message_is_method_call(message, NULL, "DisableUnitFilesWithFlags")) { r = sd_bus_message_read(message, "b", &runtime);
uint64_t raw_flags; if (r < 0)
return r;
r = sd_bus_message_read(message, "t", &raw_flags);
if (r < 0)
return r;
if ((raw_flags & ~_UNIT_FILE_FLAGS_MASK_PUBLIC) != 0 ||
FLAGS_SET(raw_flags, UNIT_FILE_FORCE))
return -EINVAL;
flags = raw_flags;
} else {
int runtime;
r = sd_bus_message_read(message, "b", &runtime);
if (r < 0)
return r;
flags = unit_file_bools_to_flags(runtime, false);
}
r = bus_verify_manage_unit_files_async(m, message, error); r = bus_verify_manage_unit_files_async(m, message, error);
if (r < 0) if (r < 0)
@ -2240,17 +2208,13 @@ static int method_disable_unit_files_generic(
if (r == 0) if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
r = call(m->unit_file_scope, flags, NULL, l, &changes, &n_changes); r = call(m->unit_file_scope, runtime ? UNIT_FILE_RUNTIME : 0, NULL, l, &changes, &n_changes);
if (r < 0) if (r < 0)
return install_error(error, r, changes, n_changes); return install_error(error, r, changes, n_changes);
return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes, error); return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes, error);
} }
static int method_disable_unit_files_with_flags(sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_disable_unit_files_generic(message, userdata, unit_file_disable, error);
}
static int method_disable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) { static int method_disable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
return method_disable_unit_files_generic(message, userdata, unit_file_disable, error); return method_disable_unit_files_generic(message, userdata, unit_file_disable, error);
} }
@ -3020,23 +2984,6 @@ const sd_bus_vtable bus_manager_vtable[] = {
SD_BUS_PARAM(changes), SD_BUS_PARAM(changes),
method_disable_unit_files, method_disable_unit_files,
SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("EnableUnitFilesWithFlags",
"ast",
SD_BUS_PARAM(files)
SD_BUS_PARAM(flags),
"ba(sss)",
SD_BUS_PARAM(carries_install_info)
SD_BUS_PARAM(changes),
method_enable_unit_files_with_flags,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("DisableUnitFilesWithFlags",
"ast",
SD_BUS_PARAM(files)
SD_BUS_PARAM(flags),
"a(sss)",
SD_BUS_PARAM(changes),
method_disable_unit_files_with_flags,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("ReenableUnitFiles", SD_BUS_METHOD_WITH_NAMES("ReenableUnitFiles",
"asbb", "asbb",
SD_BUS_PARAM(files) SD_BUS_PARAM(files)

View File

@ -142,17 +142,10 @@ static void ipv4acd_client_notify(sd_ipv4acd *acd, int event) {
} }
int sd_ipv4acd_stop(sd_ipv4acd *acd) { int sd_ipv4acd_stop(sd_ipv4acd *acd) {
IPv4ACDState old_state;
assert_return(acd, -EINVAL); assert_return(acd, -EINVAL);
old_state = acd->state;
ipv4acd_reset(acd); ipv4acd_reset(acd);
if (old_state == IPV4ACD_STATE_INIT)
return 0;
log_ipv4acd(acd, "STOPPED"); log_ipv4acd(acd, "STOPPED");
ipv4acd_client_notify(acd, SD_IPV4ACD_EVENT_STOP); ipv4acd_client_notify(acd, SD_IPV4ACD_EVENT_STOP);
@ -442,15 +435,6 @@ int sd_ipv4acd_set_address(sd_ipv4acd *acd, const struct in_addr *address) {
return 0; return 0;
} }
int sd_ipv4acd_get_address(sd_ipv4acd *acd, struct in_addr *address) {
assert_return(acd, -EINVAL);
assert_return(address, -EINVAL);
address->s_addr = acd->address;
return 0;
}
int sd_ipv4acd_is_running(sd_ipv4acd *acd) { int sd_ipv4acd_is_running(sd_ipv4acd *acd) {
assert_return(acd, false); assert_return(acd, false);

View File

@ -22,8 +22,19 @@
static int dhcp4_update_address(Link *link, bool announce); static int dhcp4_update_address(Link *link, bool announce);
static int dhcp4_remove_all(Link *link); static int dhcp4_remove_all(Link *link);
static int dhcp4_release_old_lease(Link *link, bool force);
static int dhcp4_release_old_lease(Link *link) { static int dhcp4_address_callback(Address *address) {
assert(address);
assert(address->link);
/* Do not call this callback again. */
address->callback = NULL;
return dhcp4_release_old_lease(address->link, true);
}
static int dhcp4_release_old_lease(Link *link, bool force) {
Route *route; Route *route;
Iterator i; Iterator i;
int k, r = 0; int k, r = 0;
@ -33,6 +44,12 @@ static int dhcp4_release_old_lease(Link *link) {
if (!link->dhcp_address_old && set_isempty(link->dhcp_routes_old)) if (!link->dhcp_address_old && set_isempty(link->dhcp_routes_old))
return 0; return 0;
if (!force && (link->dhcp_address && !address_is_ready(link->dhcp_address))) {
log_link_debug(link, "New DHCPv4 address is not ready. The old lease will be removed later.");
link->dhcp_address->callback = dhcp4_address_callback;
return 0;
}
log_link_debug(link, "Removing old DHCPv4 address and routes."); log_link_debug(link, "Removing old DHCPv4 address and routes.");
link_dirty(link); link_dirty(link);
@ -64,7 +81,7 @@ static void dhcp4_check_ready(Link *link) {
link->dhcp4_configured = true; link->dhcp4_configured = true;
/* New address and routes are configured now. Let's release old lease. */ /* New address and routes are configured now. Let's release old lease. */
r = dhcp4_release_old_lease(link); r = dhcp4_release_old_lease(link, false);
if (r < 0) { if (r < 0) {
link_enter_failed(link); link_enter_failed(link);
return; return;
@ -234,10 +251,11 @@ static int dhcp_prefix_route_from_lease(
static int link_set_dhcp_routes(Link *link) { static int link_set_dhcp_routes(Link *link) {
_cleanup_free_ sd_dhcp_route **static_routes = NULL; _cleanup_free_ sd_dhcp_route **static_routes = NULL;
bool classless_route = false, static_route = false; bool classless_route = false, static_route = false;
const struct in_addr *router;
struct in_addr address; struct in_addr address;
int r, n, i;
uint32_t table; uint32_t table;
Route *rt; Route *rt;
int r, n;
assert(link); assert(link);
@ -280,9 +298,9 @@ static int link_set_dhcp_routes(Link *link) {
if (n == -ENODATA) if (n == -ENODATA)
log_link_debug_errno(link, n, "DHCP: No routes received from DHCP server: %m"); log_link_debug_errno(link, n, "DHCP: No routes received from DHCP server: %m");
else if (n < 0) else if (n < 0)
return log_link_error_errno(link, n, "DHCP: could not get routes: %m"); log_link_debug_errno(link, n, "DHCP: could not get routes: %m");
for (int i = 0; i < n; i++) { for (i = 0; i < n; i++) {
switch (sd_dhcp_route_get_option(static_routes[i])) { switch (sd_dhcp_route_get_option(static_routes[i])) {
case SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE: case SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE:
classless_route = true; classless_route = true;
@ -294,14 +312,11 @@ static int link_set_dhcp_routes(Link *link) {
} }
if (link->network->dhcp_use_routes) { if (link->network->dhcp_use_routes) {
/* if the DHCP server returns both a Classless Static Routes option and a Static Routes option, for (i = 0; i < n; i++) {
* the DHCP client MUST ignore the Static Routes option. */
if (classless_route && static_route)
log_link_warning(link, "Classless static routes received from DHCP server: ignoring static-route option");
for (int i = 0; i < n; i++) {
_cleanup_(route_freep) Route *route = NULL; _cleanup_(route_freep) Route *route = NULL;
/* if the DHCP server returns both a Classless Static Routes option and a Static Routes option,
the DHCP client MUST ignore the Static Routes option. */
if (classless_route && if (classless_route &&
sd_dhcp_route_get_option(static_routes[i]) != SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE) sd_dhcp_route_get_option(static_routes[i]) != SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE)
continue; continue;
@ -332,20 +347,20 @@ static int link_set_dhcp_routes(Link *link) {
} }
if (link->network->dhcp_use_gateway) { if (link->network->dhcp_use_gateway) {
const struct in_addr *router;
r = sd_dhcp_lease_get_router(link->dhcp_lease, &router); r = sd_dhcp_lease_get_router(link->dhcp_lease, &router);
if (IN_SET(r, 0, -ENODATA)) if (IN_SET(r, 0, -ENODATA))
log_link_info(link, "DHCP: No gateway received from DHCP server."); log_link_info(link, "DHCP: No gateway received from DHCP server.");
else if (r < 0) else if (r < 0)
return log_link_error_errno(link, r, "DHCP error: could not get gateway: %m"); log_link_warning_errno(link, r, "DHCP error: could not get gateway: %m");
else if (in4_addr_is_null(&router[0])) else if (in4_addr_is_null(&router[0]))
log_link_info(link, "DHCP: Received gateway is null."); log_link_info(link, "DHCP: Received gateway is null.");
else if (classless_route)
/* According to RFC 3442: If the DHCP server returns both a Classless Static Routes option and /* According to RFC 3442: If the DHCP server returns both a Classless Static Routes option and
* a Router option, the DHCP client MUST ignore the Router option. */ a Router option, the DHCP client MUST ignore the Router option. */
log_link_warning(link, "Classless static routes received from DHCP server: ignoring router option"); if (classless_route && static_route)
else { log_link_warning(link, "Classless static routes received from DHCP server: ignoring static-route option and router option");
if (r > 0 && !classless_route && !in4_addr_is_null(&router[0])) {
_cleanup_(route_freep) Route *route = NULL, *route_gw = NULL; _cleanup_(route_freep) Route *route = NULL, *route_gw = NULL;
r = route_new(&route_gw); r = route_new(&route_gw);
@ -384,20 +399,20 @@ static int link_set_dhcp_routes(Link *link) {
r = dhcp_route_configure(route, link); r = dhcp_route_configure(route, link);
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Could not set router: %m"); return log_link_error_errno(link, r, "Could not set router: %m");
}
LIST_FOREACH(routes, rt, link->network->static_routes) { LIST_FOREACH(routes, rt, link->network->static_routes) {
if (!rt->gateway_from_dhcp) if (!rt->gateway_from_dhcp)
continue; continue;
if (rt->family != AF_INET) if (rt->family != AF_INET)
continue; continue;
rt->gw.in = router[0]; rt->gw.in = router[0];
r = dhcp_route_configure(rt, link); r = dhcp_route_configure(rt, link);
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Could not set gateway: %m"); return log_link_error_errno(link, r, "Could not set gateway: %m");
}
} }
} }
@ -542,7 +557,7 @@ static int dhcp_lease_lost(Link *link) {
link->dhcp4_configured = false; link->dhcp4_configured = false;
/* dhcp_lease_lost() may be called during renewing IP address. */ /* dhcp_lease_lost() may be called during renewing IP address. */
k = dhcp4_release_old_lease(link); k = dhcp4_release_old_lease(link, true);
if (k < 0) if (k < 0)
r = k; r = k;
@ -610,7 +625,7 @@ static void dhcp_address_on_acd(sd_ipv4acd *acd, int event, void *userdata) {
assert_not_reached("Invalid IPv4ACD event."); assert_not_reached("Invalid IPv4ACD event.");
} }
(void) sd_ipv4acd_stop(acd); sd_ipv4acd_stop(acd);
return; return;
} }
@ -641,7 +656,6 @@ static int configure_dhcpv4_duplicate_address_detection(Link *link) {
static int dhcp4_start_acd(Link *link) { static int dhcp4_start_acd(Link *link) {
union in_addr_union addr; union in_addr_union addr;
struct in_addr old;
int r; int r;
if (!link->network->dhcp_send_decline) if (!link->network->dhcp_send_decline)
@ -650,18 +664,12 @@ static int dhcp4_start_acd(Link *link) {
if (!link->dhcp_lease) if (!link->dhcp_lease)
return 0; return 0;
(void) sd_ipv4acd_stop(link->network->dhcp_acd);
link->dhcp4_address_bind = false; link->dhcp4_address_bind = false;
r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr.in); r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr.in);
if (r < 0) if (r < 0)
return r; return r;
r = sd_ipv4acd_get_address(link->network->dhcp_acd, &old);
if (r < 0)
return r;
r = sd_ipv4acd_set_address(link->network->dhcp_acd, &addr.in); r = sd_ipv4acd_set_address(link->network->dhcp_acd, &addr.in);
if (r < 0) if (r < 0)
return r; return r;
@ -677,41 +685,13 @@ static int dhcp4_start_acd(Link *link) {
log_link_debug(link, "Starting IPv4ACD client. Probing DHCPv4 address %s", strna(pretty)); log_link_debug(link, "Starting IPv4ACD client. Probing DHCPv4 address %s", strna(pretty));
} }
r = sd_ipv4acd_start(link->network->dhcp_acd, !in4_addr_equal(&addr.in, &old)); r = sd_ipv4acd_start(link->network->dhcp_acd, true);
if (r < 0) if (r < 0)
return r; return r;
return 1; return 1;
} }
static int dhcp4_address_ready_callback(Address *address) {
Link *link;
int r;
assert(address);
link = address->link;
/* Do not call this again. */
address->callback = NULL;
r = link_set_dhcp_routes(link);
if (r < 0)
return r;
/* Reconfigure static routes as kernel may remove some routes when lease expires. */
r = link_request_set_routes(link);
if (r < 0)
return r;
r = dhcp4_start_acd(link);
if (r < 0)
return log_link_error_errno(link, r, "Failed to start IPv4ACD for DHCP4 adddress: %m");
dhcp4_check_ready(link);
return 0;
}
static int dhcp4_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { static int dhcp4_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r; int r;
@ -728,14 +708,27 @@ static int dhcp4_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *
} else if (r >= 0) } else if (r >= 0)
(void) manager_rtnl_process_address(rtnl, m, link->manager); (void) manager_rtnl_process_address(rtnl, m, link->manager);
if (address_is_ready(link->dhcp_address)) { r = link_set_dhcp_routes(link);
r = dhcp4_address_ready_callback(link->dhcp_address); if (r < 0) {
if (r < 0) { link_enter_failed(link);
link_enter_failed(link); return 1;
return 1; }
}
} else /* Add back static routes since kernel removes while DHCPv4 address is removed from when lease expires */
link->dhcp_address->callback = dhcp4_address_ready_callback; r = link_request_set_routes(link);
if (r < 0) {
link_enter_failed(link);
return 1;
}
r = dhcp4_start_acd(link);
if (r < 0) {
log_link_error_errno(link, r, "Failed to start IPv4ACD for DHCP4 adddress: %m");
link_enter_failed(link);
return 1;
}
dhcp4_check_ready(link);
return 1; return 1;
} }

View File

@ -1166,6 +1166,26 @@ int config_parse_routing_policy_rule_suppress_prefixlen(
return 0; return 0;
} }
static int routing_policy_rule_read_full_file(const char *state_file, char **ret) {
_cleanup_free_ char *s = NULL;
size_t size;
int r;
assert(state_file);
r = read_full_file(state_file, &s, &size);
if (r == -ENOENT)
return -ENODATA;
if (r < 0)
return r;
if (size <= 0)
return -ENODATA;
*ret = TAKE_PTR(s);
return size;
}
int routing_policy_serialize_rules(Set *rules, FILE *f) { int routing_policy_serialize_rules(Set *rules, FILE *f) {
RoutingPolicyRule *rule = NULL; RoutingPolicyRule *rule = NULL;
Iterator i; Iterator i;
@ -1175,25 +1195,17 @@ int routing_policy_serialize_rules(Set *rules, FILE *f) {
SET_FOREACH(rule, rules, i) { SET_FOREACH(rule, rules, i) {
_cleanup_free_ char *from_str = NULL, *to_str = NULL; _cleanup_free_ char *from_str = NULL, *to_str = NULL;
const char *family_str;
bool space = false; bool space = false;
const char *family_str;
fputs("RULE=", f); fputs("RULE=", f);
family_str = af_to_name(rule->family);
if (family_str) {
fprintf(f, "family=%s",
family_str);
space = true;
}
if (!in_addr_is_null(rule->family, &rule->from)) { if (!in_addr_is_null(rule->family, &rule->from)) {
r = in_addr_to_string(rule->family, &rule->from, &from_str); r = in_addr_to_string(rule->family, &rule->from, &from_str);
if (r < 0) if (r < 0)
return r; return r;
fprintf(f, "%sfrom=%s/%hhu", fprintf(f, "from=%s/%hhu",
space ? " " : "",
from_str, rule->from_prefixlen); from_str, rule->from_prefixlen);
space = true; space = true;
} }
@ -1209,6 +1221,12 @@ int routing_policy_serialize_rules(Set *rules, FILE *f) {
space = true; space = true;
} }
family_str = af_to_name(rule->family);
if (family_str)
fprintf(f, "%sfamily=%s",
space ? " " : "",
family_str);
if (rule->tos != 0) { if (rule->tos != 0) {
fprintf(f, "%stos=%hhu", fprintf(f, "%stos=%hhu",
space ? " " : "", space ? " " : "",
@ -1216,12 +1234,9 @@ int routing_policy_serialize_rules(Set *rules, FILE *f) {
space = true; space = true;
} }
if (rule->priority != 0) { fprintf(f, "%spriority=%"PRIu32,
fprintf(f, "%spriority=%"PRIu32, space ? " " : "",
space ? " " : "", rule->priority);
rule->priority);
space = true;
}
if (rule->fwmark != 0) { if (rule->fwmark != 0) {
fprintf(f, "%sfwmark=%"PRIu32"/%"PRIu32, fprintf(f, "%sfwmark=%"PRIu32"/%"PRIu32,
@ -1280,35 +1295,14 @@ int routing_policy_serialize_rules(Set *rules, FILE *f) {
space = true; space = true;
} }
fprintf(f, "%sinvert_rule=%s table=%"PRIu32"\n", fprintf(f, "%stable=%"PRIu32 "\n",
space ? " " : "", space ? " " : "",
yes_no(rule->invert_rule),
rule->table); rule->table);
} }
return 0; return 0;
} }
static int routing_policy_rule_read_full_file(const char *state_file, char **ret) {
_cleanup_free_ char *s = NULL;
size_t size;
int r;
assert(state_file);
r = read_full_file(state_file, &s, &size);
if (r == -ENOENT)
return -ENODATA;
if (r < 0)
return r;
if (size <= 0)
return -ENODATA;
*ret = TAKE_PTR(s);
return size;
}
int routing_policy_load_rules(const char *state_file, Set **rules) { int routing_policy_load_rules(const char *state_file, Set **rules) {
_cleanup_strv_free_ char **l = NULL; _cleanup_strv_free_ char **l = NULL;
_cleanup_free_ char *data = NULL; _cleanup_free_ char *data = NULL;
@ -1340,34 +1334,19 @@ int routing_policy_load_rules(const char *state_file, Set **rules) {
return r; return r;
for (;;) { for (;;) {
_cleanup_free_ char *a = NULL; _cleanup_free_ char *word = NULL, *a = NULL, *b = NULL;
char *b;
r = extract_first_word(&p, &a, NULL, 0); r = extract_first_word(&p, &word, NULL, 0);
if (r < 0) if (r < 0)
return r; return r;
if (r == 0) if (r == 0)
break; break;
b = strchr(a, '='); r = split_pair(word, "=", &a, &b);
if (!b) { if (r < 0)
log_warning_errno(r, "Failed to parse RPDB rule, ignoring: %s", a);
continue; continue;
}
*b++ = '\0';
if (streq(a, "family")) { if (STR_IN_SET(a, "from", "to")) {
r = af_from_name(b);
if (r < 0) {
log_warning_errno(r, "Failed to parse RPDB rule family, ignoring: %s", b);
continue;
}
if (rule->family != AF_UNSPEC && rule->family != r) {
log_warning("RPDB rule family is already specified, ignoring assignment: %s", b);
continue;
}
rule->family = r;
} if (STR_IN_SET(a, "from", "to")) {
union in_addr_union *buffer; union in_addr_union *buffer;
uint8_t *prefixlen; uint8_t *prefixlen;
@ -1379,36 +1358,41 @@ int routing_policy_load_rules(const char *state_file, Set **rules) {
prefixlen = &rule->from_prefixlen; prefixlen = &rule->from_prefixlen;
} }
if (rule->family == AF_UNSPEC) r = in_addr_prefix_from_string_auto(b, &rule->family, buffer, prefixlen);
r = in_addr_prefix_from_string_auto(b, &rule->family, buffer, prefixlen);
else
r = in_addr_prefix_from_string(b, rule->family, buffer, prefixlen);
if (r < 0) { if (r < 0) {
log_warning_errno(r, "RPDB rule prefix is invalid, ignoring assignment: %s", b); log_error_errno(r, "RPDB rule prefix is invalid, ignoring assignment: %s", b);
continue; continue;
} }
} else if (streq(a, "family")) {
r = af_from_name(b);
if (r < 0) {
log_error_errno(r, "Failed to parse RPDB rule family, ignoring: %s", b);
continue;
}
rule->family = r;
} else if (streq(a, "tos")) { } else if (streq(a, "tos")) {
r = safe_atou8(b, &rule->tos); r = safe_atou8(b, &rule->tos);
if (r < 0) { if (r < 0) {
log_warning_errno(r, "Failed to parse RPDB rule TOS, ignoring: %s", b); log_error_errno(r, "Failed to parse RPDB rule TOS, ignoring: %s", b);
continue; continue;
} }
} else if (streq(a, "table")) { } else if (streq(a, "table")) {
r = safe_atou32(b, &rule->table); r = safe_atou32(b, &rule->table);
if (r < 0) { if (r < 0) {
log_warning_errno(r, "Failed to parse RPDB rule table, ignoring: %s", b); log_error_errno(r, "Failed to parse RPDB rule table, ignoring: %s", b);
continue; continue;
} }
} else if (streq(a, "priority")) { } else if (streq(a, "priority")) {
r = safe_atou32(b, &rule->priority); r = safe_atou32(b, &rule->priority);
if (r < 0) { if (r < 0) {
log_warning_errno(r, "Failed to parse RPDB rule priority, ignoring: %s", b); log_error_errno(r, "Failed to parse RPDB rule priority, ignoring: %s", b);
continue; continue;
} }
} else if (streq(a, "fwmark")) { } else if (streq(a, "fwmark")) {
r = parse_fwmark_fwmask(b, &rule->fwmark, &rule->fwmask); r = parse_fwmark_fwmask(b, &rule->fwmark, &rule->fwmask);
if (r < 0) { if (r < 0) {
log_warning_errno(r, "Failed to parse RPDB rule firewall mark or mask, ignoring: %s", a); log_error_errno(r, "Failed to parse RPDB rule firewall mark or mask, ignoring: %s", a);
continue; continue;
} }
} else if (streq(a, "iif")) { } else if (streq(a, "iif")) {
@ -1422,13 +1406,13 @@ int routing_policy_load_rules(const char *state_file, Set **rules) {
} else if (streq(a, "protocol")) { } else if (streq(a, "protocol")) {
r = safe_atou8(b, &rule->protocol); r = safe_atou8(b, &rule->protocol);
if (r < 0) { if (r < 0) {
log_warning_errno(r, "Failed to parse RPDB rule protocol, ignoring: %s", b); log_error_errno(r, "Failed to parse RPDB rule protocol, ignoring: %s", b);
continue; continue;
} }
} else if (streq(a, "sourceport")) { } else if (streq(a, "sourceport")) {
r = parse_ip_port_range(b, &low, &high); r = parse_ip_port_range(b, &low, &high);
if (r < 0) { if (r < 0) {
log_warning_errno(r, "Invalid routing policy rule source port range, ignoring assignment: '%s'", b); log_error_errno(r, "Invalid routing policy rule source port range, ignoring assignment: '%s'", b);
continue; continue;
} }
@ -1437,7 +1421,7 @@ int routing_policy_load_rules(const char *state_file, Set **rules) {
} else if (streq(a, "destinationport")) { } else if (streq(a, "destinationport")) {
r = parse_ip_port_range(b, &low, &high); r = parse_ip_port_range(b, &low, &high);
if (r < 0) { if (r < 0) {
log_warning_errno(r, "Invalid routing policy rule destination port range, ignoring assignment: '%s'", b); log_error_errno(r, "Invalid routing policy rule destination port range, ignoring assignment: '%s'", b);
continue; continue;
} }
@ -1448,7 +1432,7 @@ int routing_policy_load_rules(const char *state_file, Set **rules) {
r = parse_uid_range(b, &lower, &upper); r = parse_uid_range(b, &lower, &upper);
if (r < 0) { if (r < 0) {
log_warning_errno(r, "Invalid routing policy rule uid range, ignoring assignment: '%s'", b); log_error_errno(r, "Invalid routing policy rule uid range, ignoring assignment: '%s'", b);
continue; continue;
} }
@ -1457,22 +1441,14 @@ int routing_policy_load_rules(const char *state_file, Set **rules) {
} else if (streq(a, "suppress_prefixlen")) { } else if (streq(a, "suppress_prefixlen")) {
r = parse_ip_prefix_length(b, &rule->suppress_prefixlen); r = parse_ip_prefix_length(b, &rule->suppress_prefixlen);
if (r == -ERANGE) { if (r == -ERANGE) {
log_warning_errno(r, "Prefix length outside of valid range 0-128, ignoring: %s", b); log_error_errno(r, "Prefix length outside of valid range 0-128, ignoring: %s", b);
continue; continue;
} }
if (r < 0) { if (r < 0) {
log_warning_errno(r, "Failed to parse RPDB rule suppress_prefixlen, ignoring: %s", b); log_error_errno(r, "Failed to parse RPDB rule suppress_prefixlen, ignoring: %s", b);
continue; continue;
} }
} else if (streq(a, "invert_rule")) { }
r = parse_boolean(b);
if (r < 0) {
log_warning_errno(r, "Failed to parse RPDB rule invert_rule, ignoring: %s", b);
continue;
}
rule->invert_rule = r;
} else
log_warning("Unknown RPDB rule, ignoring: %s", a);
} }
r = set_ensure_put(rules, &routing_policy_rule_hash_ops, rule); r = set_ensure_put(rules, &routing_policy_rule_hash_ops, rule);

View File

@ -62,34 +62,31 @@ int main(int argc, char **argv) {
test_setup_logging(LOG_DEBUG); test_setup_logging(LOG_DEBUG);
test_rule_serialization("basic parsing", test_rule_serialization("basic parsing",
"RULE=family=AF_INET from=1.2.3.4/32 to=2.3.4.5/32 tos=5 priority=10 fwmark=1/2 invert_rule=yes table=10", NULL); "RULE=from=1.2.3.4/32 to=2.3.4.5/32 family=AF_INET tos=5 priority=0 fwmark=1/2 table=10", NULL);
test_rule_serialization("ignored values", test_rule_serialization("ignored values",
"RULE=something=to=ignore from=1.2.3.4/32 from=1.2.3.4/32" "RULE=something=to=ignore from=1.2.3.4/32 from=1.2.3.4/32"
" \t to=2.3.4.5/24 to=2.3.4.5/32 tos=5 fwmark=2 fwmark=1 table=10 table=20", " \t to=2.3.4.5/24 to=2.3.4.5/32 tos=5 fwmark=2 fwmark=1 table=10 table=20",
"RULE=family=AF_INET from=1.2.3.4/32 to=2.3.4.5/32 tos=5 fwmark=1/0 invert_rule=no table=20"); "RULE=from=1.2.3.4/32"
" to=2.3.4.5/32 family=AF_INET tos=5 priority=0 fwmark=1/0 table=20");
test_rule_serialization("ipv6", test_rule_serialization("ipv6",
"RULE=family=AF_INET6 from=1::2/64 to=2::3/64 invert_rule=yes table=6", NULL); "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 priority=0 table=6", NULL);
assert_se(asprintf(&p, "RULE=family=AF_INET6 from=1::2/64 to=2::3/64 invert_rule=no table=%d", RT_TABLE_MAIN) >= 0); assert_se(asprintf(&p, "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 priority=0 table=%d", RT_TABLE_MAIN) >= 0);
test_rule_serialization("default table", test_rule_serialization("default table",
"RULE=from=1::2/64 to=2::3/64", p); "RULE=from=1::2/64 to=2::3/64", p);
test_rule_serialization("incoming interface", test_rule_serialization("incoming interface",
"RULE=from=1::2/64 to=2::3/64 table=1 iif=lo", "RULE=from=1::2/64 to=2::3/64 table=1 iif=lo",
"RULE=family=AF_INET6 from=1::2/64 to=2::3/64 iif=lo invert_rule=no table=1"); "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 priority=0 iif=lo table=1");
test_rule_serialization("outgoing interface", test_rule_serialization("outgoing interface",
"RULE=family=AF_INET6 from=1::2/64 to=2::3/64 oif=eth0 invert_rule=no table=1", NULL); "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 priority=0 oif=eth0 table=1", NULL);
test_rule_serialization("freeing interface names", test_rule_serialization("freeing interface names",
"RULE=from=1::2/64 to=2::3/64 family=AF_INET6 iif=e0 iif=e1 oif=e0 oif=e1 table=1", "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 iif=e0 iif=e1 oif=e0 oif=e1 table=1",
"RULE=family=AF_INET6 from=1::2/64 to=2::3/64 iif=e1 oif=e1 invert_rule=no table=1"); "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 priority=0 iif=e1 oif=e1 table=1");
test_rule_serialization("ignoring invalid family",
"RULE=from=1::2/64 to=2::3/64 family=AF_UNSEPC family=AF_INET table=1",
"RULE=family=AF_INET6 from=1::2/64 to=2::3/64 invert_rule=no table=1");
return 0; return 0;
} }

View File

@ -392,7 +392,6 @@ static int maybe_enable_disable(sd_bus *bus, const char *path, bool enable) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_strv_free_ char **names = NULL; _cleanup_strv_free_ char **names = NULL;
UnitFileChange *changes = NULL; UnitFileChange *changes = NULL;
const uint64_t flags = UNIT_FILE_PORTABLE | (arg_runtime ? UNIT_FILE_RUNTIME : 0);
size_t n_changes = 0; size_t n_changes = 0;
int r; int r;
@ -409,7 +408,7 @@ static int maybe_enable_disable(sd_bus *bus, const char *path, bool enable) {
"org.freedesktop.systemd1", "org.freedesktop.systemd1",
"/org/freedesktop/systemd1", "/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager", "org.freedesktop.systemd1.Manager",
enable ? "EnableUnitFilesWithFlags" : "DisableUnitFilesWithFlags"); enable ? "EnableUnitFiles" : "DisableUnitFiles");
if (r < 0) if (r < 0)
return bus_log_create_error(r); return bus_log_create_error(r);
@ -417,10 +416,16 @@ static int maybe_enable_disable(sd_bus *bus, const char *path, bool enable) {
if (r < 0) if (r < 0)
return bus_log_create_error(r); return bus_log_create_error(r);
r = sd_bus_message_append(m, "t", flags); r = sd_bus_message_append(m, "b", arg_runtime);
if (r < 0) if (r < 0)
return bus_log_create_error(r); return bus_log_create_error(r);
if (enable) {
r = sd_bus_message_append(m, "b", false);
if (r < 0)
return bus_log_create_error(r);
}
r = sd_bus_call(bus, m, 0, &error, &reply); r = sd_bus_call(bus, m, 0, &error, &reply);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to %s the portable service %s: %s", return log_error_errno(r, "Failed to %s the portable service %s: %s",

View File

@ -2545,7 +2545,6 @@ static int native_help(void) {
" dnssec [LINK [MODE]] Get/set per-interface DNSSEC mode\n" " dnssec [LINK [MODE]] Get/set per-interface DNSSEC mode\n"
" nta [LINK [DOMAIN...]] Get/set per-interface DNSSEC NTA\n" " nta [LINK [DOMAIN...]] Get/set per-interface DNSSEC NTA\n"
" revert LINK Revert per-interface configuration\n" " revert LINK Revert per-interface configuration\n"
" log-level [LEVEL] Get/set logging threshold for systemd-resolved\n"
"\nOptions:\n" "\nOptions:\n"
" -h --help Show this help\n" " -h --help Show this help\n"
" --version Show package version\n" " --version Show package version\n"

View File

@ -249,15 +249,6 @@ static int path_is_vendor_or_generator(const LookupPaths *p, const char *path) {
return path_equal(rpath, SYSTEM_DATA_UNIT_PATH); return path_equal(rpath, SYSTEM_DATA_UNIT_PATH);
} }
static const char* config_path_from_flags(const LookupPaths *paths, UnitFileFlags flags) {
assert(paths);
if (FLAGS_SET(flags, UNIT_FILE_PORTABLE))
return FLAGS_SET(flags, UNIT_FILE_RUNTIME) ? paths->runtime_attached : paths->persistent_attached;
else
return FLAGS_SET(flags, UNIT_FILE_RUNTIME) ? paths->runtime_config : paths->persistent_config;
}
int unit_file_changes_add( int unit_file_changes_add(
UnitFileChange **changes, UnitFileChange **changes,
size_t *n_changes, size_t *n_changes,
@ -2591,7 +2582,7 @@ int unit_file_enable(
if (r < 0) if (r < 0)
return r; return r;
config_path = config_path_from_flags(&paths, flags); config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
if (!config_path) if (!config_path)
return -ENXIO; return -ENXIO;
@ -2634,7 +2625,7 @@ int unit_file_disable(
if (r < 0) if (r < 0)
return r; return r;
config_path = config_path_from_flags(&paths, flags); config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
if (!config_path) if (!config_path)
return -ENXIO; return -ENXIO;

View File

@ -35,11 +35,9 @@ enum UnitFileChangeType {
}; };
enum UnitFileFlags { enum UnitFileFlags {
UNIT_FILE_RUNTIME = 1 << 0, /* Public API via DBUS, do not change */ UNIT_FILE_RUNTIME = 1 << 0,
UNIT_FILE_FORCE = 1 << 1, /* Public API via DBUS, do not change */ UNIT_FILE_FORCE = 1 << 1,
UNIT_FILE_PORTABLE = 1 << 2, /* Public API via DBUS, do not change */ UNIT_FILE_DRY_RUN = 1 << 2,
UNIT_FILE_DRY_RUN = 1 << 3,
_UNIT_FILE_FLAGS_MASK_PUBLIC = UNIT_FILE_RUNTIME|UNIT_FILE_PORTABLE|UNIT_FILE_FORCE,
}; };
/* type can either one of the UnitFileChangeTypes listed above, or a negative error. /* type can either one of the UnitFileChangeTypes listed above, or a negative error.