Compare commits

..

16 Commits

Author SHA1 Message Date
Lennart Poettering 66032ef489 macro: introduce POINTER_MAX as define for (void*) -1
Just add a safer, prettier way to write (void*) -1, that doesn't rely on
two's complement, but uses the correct underlying C constructs.
2020-10-22 08:33:20 +09:00
Jonathan Lebon 6c5496c492 units: add initrd-cryptsetup.target
For encrypted block devices that we need to unlock from the initramfs,
we currently rely on dracut shipping `cryptsetup.target`. This works,
but doesn't cover the case where the encrypted block device requires
networking (i.e. the `remote-cryptsetup.target` version). That target
however is traditionally dynamically enabled.

Instead, let's rework things here by adding a `initrd-cryptsetup.target`
specifically for initramfs encrypted block device setup. This plays the
role of both `cryptsetup.target` and `remote-cryptsetup.target` in the
initramfs.

Then, adapt `systemd-cryptsetup-generator` to hook all generated
services to this new unit when running from the initrd. This is
analogous to `systemd-fstab-generator` hooking all mounts to
`initrd-fs.target`, regardless of whether they're network-backed or not.
2020-10-21 22:08:19 +02:00
Lennart Poettering 69f30d4321
Merge pull request #17356 from yuwata/sd-xxx-stop
network: about sd_xxx_stop()
2020-10-21 18:07:38 +02:00
Lennart Poettering d9da267f71
Merge pull request #17400 from yuwata/network-route-counter-17396
network: about route message counter
2020-10-21 18:07:12 +02:00
Yu Watanabe 0c54bfd698 network: call netlink in the last of route_configure()
Otherwise, assertion will be hit when route_add() fails.
2020-10-20 15:44:24 +09:00
Yu Watanabe 40075951dc network: also compare and hash weight of the gateway 2020-10-20 15:32:55 +09:00
Yu Watanabe cc17f75f66 network: copy multipath route element earlier
`route_get()` compares input with existing routes, however previously,
the input may did not have information about gateway. So, the
comparison result might be incorrect, and the foregoing set_put() might
return -EEXIST.
2020-10-20 15:32:55 +09:00
Yu Watanabe 8c212f76c2 network: make route_configure() return 0 on success
Previously, route_configure() always returns 1 on success, and never
returns 0. It is not necessary to return positive value.
2020-10-20 14:20:22 +09:00
Yu Watanabe 7abe175c00 network: also unref IPv4 ACD clients in Address objects
This should not change any behavior, as currently link_free_engines() is
always called after all addresses are dropped. But the function may be
used in other places in the future. So, let's also stop the clients.
2020-10-15 08:11:32 +09:00
Yu Watanabe 1c49487284 network: move link_lldp_emit_stop() to link_free_engines()
This should not change any behavior.
2020-10-15 08:06:04 +09:00
Yu Watanabe 9cc65242d7 network: also stop LLDP client in link_stop_engines() 2020-10-15 07:57:33 +09:00
Yu Watanabe 2a99eed02c network: stop DHCPv4 server in link_stop_clients()
Then, rename link_stop_clients() -> link_stop_engines().
2020-10-15 07:56:30 +09:00
Yu Watanabe a391901eb2 network: drop unnecessary conditions
sd_ipv4acd_stop() and sd_ipv4ll_stop() are idempotent.
2020-10-15 07:40:13 +09:00
Yu Watanabe c6a7531e0e network: voidify sd_ipv4acd_stop() at one place 2020-10-15 07:39:40 +09:00
Yu Watanabe 84add3cd2b network: drop conditions to check existence of each engine 2020-10-15 07:38:45 +09:00
Yu Watanabe c8bae36372 libsystemd-network: do not request each daemon exist in sd_xxx_stop() 2020-10-15 07:24:17 +09:00
27 changed files with 166 additions and 107 deletions

View File

@ -41,6 +41,7 @@
<filename>hybrid-sleep.target</filename>, <filename>hybrid-sleep.target</filename>,
<filename>suspend-then-hibernate.target</filename>, <filename>suspend-then-hibernate.target</filename>,
<filename>initrd.target</filename>, <filename>initrd.target</filename>,
<filename>initrd-cryptsetup.target</filename>,
<filename>initrd-fs.target</filename>, <filename>initrd-fs.target</filename>,
<filename>initrd-root-device.target</filename>, <filename>initrd-root-device.target</filename>,
<filename>initrd-root-fs.target</filename>, <filename>initrd-root-fs.target</filename>,
@ -182,8 +183,10 @@
<varlistentry> <varlistentry>
<term><filename>cryptsetup.target</filename></term> <term><filename>cryptsetup.target</filename></term>
<listitem> <listitem>
<para>A target that pulls in setup services for all <para>A target that pulls in setup services for local encrypted block devices.
encrypted block devices.</para> See <filename>remote-cryptsetup.target</filename> below for the equivalent target for remote
volumes, and <filename>initrd-cryptsetup.target</filename> below for the equivalent target in the
initrd.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
@ -352,12 +355,20 @@
<varlistentry> <varlistentry>
<term><filename>initrd.target</filename></term> <term><filename>initrd.target</filename></term>
<listitem> <listitem>
<para>This is the default target in the initramfs, similar to <filename>default.target</filename> <para>This is the default target in the initrd, similar to <filename>default.target</filename>
in the main system. It is used to mount the real root and transition to it. See in the main system. It is used to mount the real root and transition to it. See
<citerefentry><refentrytitle>bootup</refentrytitle><manvolnum>7</manvolnum></citerefentry> for <citerefentry><refentrytitle>bootup</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
more discussion.</para> more discussion.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><filename>initrd-cryptsetup.target</filename></term>
<listitem>
<para>A target that pulls in setup services for all encrypted block devices. See
<filename>cryptsetup.target</filename> and <filename>remote-cryptsetup.target</filename> for the
equivalent targets in the real root.</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><filename>initrd-fs.target</filename></term> <term><filename>initrd-fs.target</filename></term>
<listitem> <listitem>
@ -549,7 +560,9 @@
<para>Similar to <filename>cryptsetup.target</filename>, but for encrypted <para>Similar to <filename>cryptsetup.target</filename>, but for encrypted
devices which are accessed over the network. It is used for devices which are accessed over the network. It is used for
<citerefentry><refentrytitle>crypttab</refentrytitle><manvolnum>8</manvolnum></citerefentry> <citerefentry><refentrytitle>crypttab</refentrytitle><manvolnum>8</manvolnum></citerefentry>
entries marked with <option>_netdev</option>.</para> entries marked with <option>_netdev</option>.
See <filename>cryptsetup.target</filename> for the equivalent target for local volumes, and
<filename>initrd-cryptsetup.target</filename> for the equivalent target in the initrd.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>

View File

@ -554,10 +554,13 @@ static inline int __coverity_check_and_return__(int condition) {
#define STRV_MAKE(...) ((char**) ((const char*[]) { __VA_ARGS__, NULL })) #define STRV_MAKE(...) ((char**) ((const char*[]) { __VA_ARGS__, NULL }))
#define STRV_MAKE_EMPTY ((char*[1]) { NULL }) #define STRV_MAKE_EMPTY ((char*[1]) { NULL })
/* Iterates through a specified list of pointers. Accepts NULL pointers, but uses (void*) -1 as internal marker for EOL. */ /* Pointers range from NULL to POINTER_MAX */
#define FOREACH_POINTER(p, x, ...) \ #define POINTER_MAX ((void*) UINTPTR_MAX)
for (typeof(p) *_l = (typeof(p)[]) { ({ p = x; }), ##__VA_ARGS__, (void*) -1 }; \
p != (typeof(p)) (void*) -1; \ /* Iterates through a specified list of pointers. Accepts NULL pointers, but uses POINTER_MAX as internal marker for EOL. */
#define FOREACH_POINTER(p, x, ...) \
for (typeof(p) *_l = (typeof(p)[]) { ({ p = x; }), ##__VA_ARGS__, POINTER_MAX }; \
p != (typeof(p)) POINTER_MAX; \
p = *(++_l)) p = *(++_l))
/* Define C11 thread_local attribute even on older gcc compiler /* Define C11 thread_local attribute even on older gcc compiler

View File

@ -550,7 +550,7 @@ char* path_join_internal(const char *first, ...) {
sz = strlen_ptr(first); sz = strlen_ptr(first);
va_start(ap, first); va_start(ap, first);
while ((p = va_arg(ap, char*)) != (const char*) -1) while ((p = va_arg(ap, char*)) != POINTER_MAX)
if (!isempty(p)) if (!isempty(p))
sz += 1 + strlen(p); sz += 1 + strlen(p);
va_end(ap); va_end(ap);
@ -570,7 +570,7 @@ char* path_join_internal(const char *first, ...) {
} }
va_start(ap, first); va_start(ap, first);
while ((p = va_arg(ap, char*)) != (const char*) -1) { while ((p = va_arg(ap, char*)) != POINTER_MAX) {
if (isempty(p)) if (isempty(p))
continue; continue;

View File

@ -62,7 +62,7 @@ int path_compare(const char *a, const char *b) _pure_;
bool path_equal(const char *a, const char *b) _pure_; bool path_equal(const char *a, const char *b) _pure_;
bool path_equal_or_files_same(const char *a, const char *b, int flags); bool path_equal_or_files_same(const char *a, const char *b, int flags);
char* path_join_internal(const char *first, ...); char* path_join_internal(const char *first, ...);
#define path_join(x, ...) path_join_internal(x, __VA_ARGS__, (const char*) -1) #define path_join(x, ...) path_join_internal(x, __VA_ARGS__, POINTER_MAX)
char* path_simplify(char *path, bool kill_dots); char* path_simplify(char *path, bool kill_dots);

View File

@ -62,7 +62,7 @@ char **strv_new_internal(const char *x, ...) _sentinel_;
char **strv_new_ap(const char *x, va_list ap); char **strv_new_ap(const char *x, va_list ap);
#define strv_new(...) strv_new_internal(__VA_ARGS__, NULL) #define strv_new(...) strv_new_internal(__VA_ARGS__, NULL)
#define STRV_IGNORE ((const char *) -1) #define STRV_IGNORE ((const char *) POINTER_MAX)
static inline const char* STRV_IFNOTNULL(const char *x) { static inline const char* STRV_IFNOTNULL(const char *x) {
return x ? x : STRV_IGNORE; return x ? x : STRV_IGNORE;

View File

@ -455,10 +455,16 @@ static int create_disk(
} }
} }
const char *target;
if (in_initrd())
target = "initrd-cryptsetup.target";
else if (netdev)
target = "remote-cryptsetup.target";
else
target = "cryptsetup.target";
if (!nofail) if (!nofail)
fprintf(f, fprintf(f, "Before=%s\n", target);
"Before=%s\n",
netdev ? "remote-cryptsetup.target" : "cryptsetup.target");
if (password && !keydev) { if (password && !keydev) {
r = print_dependencies(f, password); r = print_dependencies(f, password);
@ -521,8 +527,7 @@ static int create_disk(
return log_error_errno(r, "Failed to write unit file %s: %m", n); return log_error_errno(r, "Failed to write unit file %s: %m", n);
if (!noauto) { if (!noauto) {
r = generator_add_symlink(arg_dest, r = generator_add_symlink(arg_dest, target,
netdev ? "remote-cryptsetup.target" : "cryptsetup.target",
nofail ? "wants" : "requires", n); nofail ? "wants" : "requires", n);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -142,7 +142,7 @@ static int acquire_user_record(
if (r == PAM_SUCCESS && json) { if (r == PAM_SUCCESS && json) {
/* We determined earlier that this is not a homed user? Then exit early. (We use -1 as /* We determined earlier that this is not a homed user? Then exit early. (We use -1 as
* negative cache indicator) */ * negative cache indicator) */
if (json == (void*) -1) if (json == POINTER_MAX)
return PAM_USER_UNKNOWN; return PAM_USER_UNKNOWN;
} else { } else {
_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;
@ -235,7 +235,7 @@ static int acquire_user_record(
user_unknown: user_unknown:
/* Cache this, so that we don't check again */ /* Cache this, so that we don't check again */
r = pam_set_data(handle, homed_field, (void*) -1, NULL); r = pam_set_data(handle, homed_field, POINTER_MAX, NULL);
if (r != PAM_SUCCESS) if (r != PAM_SUCCESS)
pam_syslog(handle, LOG_ERR, "Failed to set PAM user record data '%s' to invalid, ignoring: %s", pam_syslog(handle, LOG_ERR, "Failed to set PAM user record data '%s' to invalid, ignoring: %s",
homed_field, pam_strerror(handle, r)); homed_field, pam_strerror(handle, r));

View File

@ -2135,9 +2135,10 @@ int sd_dhcp_client_send_decline(sd_dhcp_client *client) {
} }
int sd_dhcp_client_stop(sd_dhcp_client *client) { int sd_dhcp_client_stop(sd_dhcp_client *client) {
DHCP_CLIENT_DONT_DESTROY(client); if (!client)
return 0;
assert_return(client, -EINVAL); DHCP_CLIENT_DONT_DESTROY(client);
client_stop(client, SD_DHCP_CLIENT_EVENT_STOP); client_stop(client, SD_DHCP_CLIENT_EVENT_STOP);
client->state = DHCP_STATE_STOPPED; client->state = DHCP_STATE_STOPPED;

View File

@ -225,7 +225,8 @@ sd_event *sd_dhcp_server_get_event(sd_dhcp_server *server) {
} }
int sd_dhcp_server_stop(sd_dhcp_server *server) { int sd_dhcp_server_stop(sd_dhcp_server *server) {
assert_return(server, -EINVAL); if (!server)
return 0;
server->receive_message = server->receive_message =
sd_event_source_unref(server->receive_message); sd_event_source_unref(server->receive_message);

View File

@ -1676,7 +1676,8 @@ static int client_start(sd_dhcp6_client *client, enum DHCP6State state) {
} }
int sd_dhcp6_client_stop(sd_dhcp6_client *client) { int sd_dhcp6_client_stop(sd_dhcp6_client *client) {
assert_return(client, -EINVAL); if (!client)
return 0;
client_stop(client, SD_DHCP6_CLIENT_EVENT_STOP); client_stop(client, SD_DHCP6_CLIENT_EVENT_STOP);

View File

@ -144,7 +144,8 @@ 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; IPv4ACDState old_state;
assert_return(acd, -EINVAL); if (!acd)
return 0;
old_state = acd->state; old_state = acd->state;

View File

@ -89,7 +89,8 @@ int sd_ipv4ll_new(sd_ipv4ll **ret) {
} }
int sd_ipv4ll_stop(sd_ipv4ll *ll) { int sd_ipv4ll_stop(sd_ipv4ll *ll) {
assert_return(ll, -EINVAL); if (!ll)
return 0;
return sd_ipv4acd_stop(ll->acd); return sd_ipv4acd_stop(ll->acd);
} }

View File

@ -276,7 +276,8 @@ fail:
} }
_public_ int sd_lldp_stop(sd_lldp *lldp) { _public_ int sd_lldp_stop(sd_lldp *lldp) {
assert_return(lldp, -EINVAL); if (!lldp)
return 0;
if (lldp->fd < 0) if (lldp->fd < 0)
return 0; return 0;

View File

@ -321,7 +321,8 @@ static int ndisc_timeout_no_ra(sd_event_source *s, uint64_t usec, void *userdata
} }
_public_ int sd_ndisc_stop(sd_ndisc *nd) { _public_ int sd_ndisc_stop(sd_ndisc *nd) {
assert_return(nd, -EINVAL); if (!nd)
return 0;
if (nd->fd < 0) if (nd->fd < 0)
return 0; return 0;

View File

@ -353,7 +353,8 @@ fail:
_public_ int sd_radv_stop(sd_radv *ra) { _public_ int sd_radv_stop(sd_radv *ra) {
int r; int r;
assert_return(ra, -EINVAL); if (!ra)
return 0;
if (ra->state == SD_RADV_STATE_IDLE) if (ra->state == SD_RADV_STATE_IDLE)
return 0; return 0;

View File

@ -1341,7 +1341,7 @@ static void static_address_on_acd(sd_ipv4acd *acd, int event, void *userdata) {
assert_not_reached("Invalid IPv4ACD event."); assert_not_reached("Invalid IPv4ACD event.");
} }
sd_ipv4acd_stop(acd); (void) sd_ipv4acd_stop(acd);
return; return;
} }
@ -1402,11 +1402,9 @@ static int ipv4_dad_update_mac_one(Address *address) {
running = sd_ipv4acd_is_running(address->acd); running = sd_ipv4acd_is_running(address->acd);
if (running) { r = sd_ipv4acd_stop(address->acd);
r = sd_ipv4acd_stop(address->acd); if (r < 0)
if (r < 0) return r;
return r;
}
r = sd_ipv4acd_set_mac(address->acd, &address->link->mac); r = sd_ipv4acd_set_mac(address->acd, &address->link->mac);
if (r < 0) if (r < 0)
@ -1443,9 +1441,6 @@ int ipv4_dad_stop(Link *link) {
assert(link); assert(link);
SET_FOREACH(address, link->addresses) { SET_FOREACH(address, link->addresses) {
if (!address->acd)
continue;
k = sd_ipv4acd_stop(address->acd); k = sd_ipv4acd_stop(address->acd);
if (k < 0 && r >= 0) if (k < 0 && r >= 0)
r = k; r = k;
@ -1454,6 +1449,15 @@ int ipv4_dad_stop(Link *link) {
return r; return r;
} }
void ipv4_dad_unref(Link *link) {
Address *address;
assert(link);
SET_FOREACH(address, link->addresses)
address->acd = sd_ipv4acd_unref(address->acd);
}
int config_parse_broadcast( int config_parse_broadcast(
const char *unit, const char *unit,
const char *filename, const char *filename,

View File

@ -65,6 +65,7 @@ int link_drop_foreign_addresses(Link *link);
int link_serialize_addresses(Link *link, FILE *f); int link_serialize_addresses(Link *link, FILE *f);
int link_deserialize_addresses(Link *link, const char *addresses); int link_deserialize_addresses(Link *link, const char *addresses);
void ipv4_dad_unref(Link *link);
int ipv4_dad_stop(Link *link); int ipv4_dad_stop(Link *link);
int ipv4_dad_update_mac(Link *link); int ipv4_dad_update_mac(Link *link);

View File

@ -570,8 +570,7 @@ static int dhcp_lease_lost(Link *link) {
link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease); link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
link_dirty(link); link_dirty(link);
if (link->dhcp_acd) (void) sd_ipv4acd_stop(link->dhcp_acd);
(void) sd_ipv4acd_stop(link->dhcp_acd);
return r; return r;
} }

View File

@ -207,11 +207,9 @@ int ipv4ll_update_mac(Link *link) {
restart = sd_ipv4ll_is_running(link->ipv4ll) > 0; restart = sd_ipv4ll_is_running(link->ipv4ll) > 0;
if (restart) { r = sd_ipv4ll_stop(link->ipv4ll);
r = sd_ipv4ll_stop(link->ipv4ll); if (r < 0)
if (r < 0) return r;
return r;
}
r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac); r = sd_ipv4ll_set_mac(link->ipv4ll, &link->mac);
if (r < 0) if (r < 0)

View File

@ -493,8 +493,10 @@ static void link_free_engines(Link *link) {
link->dhcp_server = sd_dhcp_server_unref(link->dhcp_server); link->dhcp_server = sd_dhcp_server_unref(link->dhcp_server);
link->dhcp_client = sd_dhcp_client_unref(link->dhcp_client); link->dhcp_client = sd_dhcp_client_unref(link->dhcp_client);
link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease); link->dhcp_lease = sd_dhcp_lease_unref(link->dhcp_lease);
link->dhcp_acd = sd_ipv4acd_unref(link->dhcp_acd);
link->lldp = sd_lldp_unref(link->lldp); link->lldp = sd_lldp_unref(link->lldp);
link_lldp_emit_stop(link);
ndisc_flush(link); ndisc_flush(link);
@ -503,7 +505,8 @@ static void link_free_engines(Link *link) {
link->dhcp6_lease = sd_dhcp6_lease_unref(link->dhcp6_lease); link->dhcp6_lease = sd_dhcp6_lease_unref(link->dhcp6_lease);
link->ndisc = sd_ndisc_unref(link->ndisc); link->ndisc = sd_ndisc_unref(link->ndisc);
link->radv = sd_radv_unref(link->radv); link->radv = sd_radv_unref(link->radv);
link->dhcp_acd = sd_ipv4acd_unref(link->dhcp_acd);
ipv4_dad_unref(link);
} }
static Link *link_free(Link *link) { static Link *link_free(Link *link) {
@ -538,7 +541,6 @@ static Link *link_free(Link *link) {
link->dhcp6_pd_addresses_old = set_free(link->dhcp6_pd_addresses_old); link->dhcp6_pd_addresses_old = set_free(link->dhcp6_pd_addresses_old);
link->ndisc_addresses = set_free(link->ndisc_addresses); link->ndisc_addresses = set_free(link->ndisc_addresses);
link_lldp_emit_stop(link);
link_free_engines(link); link_free_engines(link);
free(link->lease_file); free(link->lease_file);
free(link->lldp_file); free(link->lldp_file);
@ -605,7 +607,7 @@ static void link_enter_unmanaged(Link *link) {
link_dirty(link); link_dirty(link);
} }
int link_stop_clients(Link *link, bool may_keep_dhcp) { int link_stop_engines(Link *link, bool may_keep_dhcp) {
int r = 0, k; int r = 0, k;
assert(link); assert(link);
@ -617,49 +619,47 @@ int link_stop_clients(Link *link, bool may_keep_dhcp) {
(link->manager->restarting || (link->manager->restarting ||
FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP_ON_STOP)); FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP_ON_STOP));
if (link->dhcp_client && !keep_dhcp) { if (!keep_dhcp) {
k = sd_dhcp_client_stop(link->dhcp_client); k = sd_dhcp_client_stop(link->dhcp_client);
if (k < 0) if (k < 0)
r = log_link_warning_errno(link, k, "Could not stop DHCPv4 client: %m"); r = log_link_warning_errno(link, k, "Could not stop DHCPv4 client: %m");
} }
if (link->dhcp_acd) { k = sd_ipv4acd_stop(link->dhcp_acd);
k = sd_ipv4acd_stop(link->dhcp_acd); if (k < 0)
if (k < 0) r = log_link_warning_errno(link, k, "Could not stop IPv4 ACD client for DHCPv4: %m");
r = log_link_warning_errno(link, k, "Could not stop IPv4 ACD client for DHCPv4: %m");
}
if (link->ipv4ll) { k = sd_dhcp_server_stop(link->dhcp_server);
k = sd_ipv4ll_stop(link->ipv4ll); if (k < 0)
if (k < 0) r = log_link_warning_errno(link, k, "Could not stop DHCPv4 server: %m");
r = log_link_warning_errno(link, k, "Could not stop IPv4 link-local: %m");
} k = sd_lldp_stop(link->lldp);
if (k < 0)
r = log_link_warning_errno(link, k, "Could not stop LLDP: %m");
k = sd_ipv4ll_stop(link->ipv4ll);
if (k < 0)
r = log_link_warning_errno(link, k, "Could not stop IPv4 link-local: %m");
k = ipv4_dad_stop(link); k = ipv4_dad_stop(link);
if (k < 0) if (k < 0)
r = log_link_warning_errno(link, k, "Could not stop IPv4 ACD client: %m"); r = log_link_warning_errno(link, k, "Could not stop IPv4 ACD client: %m");
if (link->dhcp6_client) { k = sd_dhcp6_client_stop(link->dhcp6_client);
k = sd_dhcp6_client_stop(link->dhcp6_client); if (k < 0)
if (k < 0) r = log_link_warning_errno(link, k, "Could not stop DHCPv6 client: %m");
r = log_link_warning_errno(link, k, "Could not stop DHCPv6 client: %m");
}
k = dhcp6_pd_remove(link); k = dhcp6_pd_remove(link);
if (k < 0) if (k < 0)
r = log_link_warning_errno(link, k, "Could not remove DHCPv6 PD addresses and routes: %m"); r = log_link_warning_errno(link, k, "Could not remove DHCPv6 PD addresses and routes: %m");
if (link->ndisc) { k = sd_ndisc_stop(link->ndisc);
k = sd_ndisc_stop(link->ndisc); if (k < 0)
if (k < 0) r = log_link_warning_errno(link, k, "Could not stop IPv6 Router Discovery: %m");
r = log_link_warning_errno(link, k, "Could not stop IPv6 Router Discovery: %m");
}
if (link->radv) { k = sd_radv_stop(link->radv);
k = sd_radv_stop(link->radv); if (k < 0)
if (k < 0) r = log_link_warning_errno(link, k, "Could not stop IPv6 Router Advertisement: %m");
r = log_link_warning_errno(link, k, "Could not stop IPv6 Router Advertisement: %m");
}
link_lldp_emit_stop(link); link_lldp_emit_stop(link);
return r; return r;
@ -675,7 +675,7 @@ void link_enter_failed(Link *link) {
link_set_state(link, LINK_STATE_FAILED); link_set_state(link, LINK_STATE_FAILED);
(void) link_stop_clients(link, false); (void) link_stop_engines(link, false);
link_dirty(link); link_dirty(link);
} }
@ -2090,13 +2090,10 @@ static int link_reconfigure_internal(Link *link, sd_netlink_message *m, bool for
log_link_info(link, "Re-configuring with %s", network->filename); log_link_info(link, "Re-configuring with %s", network->filename);
/* Dropping old .network file */ /* Dropping old .network file */
r = link_stop_clients(link, false); r = link_stop_engines(link, false);
if (r < 0) if (r < 0)
return r; return r;
if (link->dhcp_server)
(void) sd_dhcp_server_stop(link->dhcp_server);
r = link_drop_config(link); r = link_drop_config(link);
if (r < 0) if (r < 0)
return r; return r;
@ -2541,15 +2538,12 @@ static int link_carrier_lost(Link *link) {
if (link->setting_mtu) if (link->setting_mtu)
return 0; return 0;
r = link_stop_clients(link, false); r = link_stop_engines(link, false);
if (r < 0) { if (r < 0) {
link_enter_failed(link); link_enter_failed(link);
return r; return r;
} }
if (link->dhcp_server)
(void) sd_dhcp_server_stop(link->dhcp_server);
r = link_drop_config(link); r = link_drop_config(link);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -231,7 +231,7 @@ int link_set_mtu(Link *link, uint32_t mtu);
bool link_ipv4ll_enabled(Link *link, AddressFamily mask); bool link_ipv4ll_enabled(Link *link, AddressFamily mask);
int link_stop_clients(Link *link, bool may_keep_dhcp); int link_stop_engines(Link *link, bool may_keep_dhcp);
const char* link_state_to_string(LinkState s) _const_; const char* link_state_to_string(LinkState s) _const_;
LinkState link_state_from_string(const char *s) _pure_; LinkState link_state_from_string(const char *s) _pure_;

View File

@ -864,7 +864,7 @@ void manager_free(Manager *m) {
free(m->state_file); free(m->state_file);
HASHMAP_FOREACH(link, m->links) HASHMAP_FOREACH(link, m->links)
(void) link_stop_clients(link, true); (void) link_stop_engines(link, true);
m->dhcp6_prefixes = hashmap_free_with_destructor(m->dhcp6_prefixes, dhcp6_pd_free); m->dhcp6_prefixes = hashmap_free_with_destructor(m->dhcp6_prefixes, dhcp6_pd_free);
m->dhcp6_pd_prefixes = set_free_with_destructor(m->dhcp6_pd_prefixes, dhcp6_pd_free); m->dhcp6_pd_prefixes = set_free_with_destructor(m->dhcp6_pd_prefixes, dhcp6_pd_free);

View File

@ -697,11 +697,9 @@ int radv_update_mac(Link *link) {
restart = sd_radv_is_running(link->radv); restart = sd_radv_is_running(link->radv);
if (restart) { r = sd_radv_stop(link->radv);
r = sd_radv_stop(link->radv); if (r < 0)
if (r < 0) return r;
return r;
}
r = sd_radv_set_mac(link->radv, &link->mac); r = sd_radv_set_mac(link->radv, &link->mac);
if (r < 0) if (r < 0)

View File

@ -299,9 +299,10 @@ void route_hash_func(const Route *route, struct siphash *state) {
siphash24_compress(&route->src, FAMILY_ADDRESS_SIZE(route->family), state); siphash24_compress(&route->src, FAMILY_ADDRESS_SIZE(route->family), state);
siphash24_compress(&route->gw_family, sizeof(route->gw_family), state); siphash24_compress(&route->gw_family, sizeof(route->gw_family), state);
if (IN_SET(route->gw_family, AF_INET, AF_INET6)) if (IN_SET(route->gw_family, AF_INET, AF_INET6)) {
siphash24_compress(&route->gw, FAMILY_ADDRESS_SIZE(route->gw_family), state); siphash24_compress(&route->gw, FAMILY_ADDRESS_SIZE(route->gw_family), state);
siphash24_compress(&route->gw_weight, sizeof(route->gw_weight), state);
}
siphash24_compress(&route->prefsrc, FAMILY_ADDRESS_SIZE(route->family), state); siphash24_compress(&route->prefsrc, FAMILY_ADDRESS_SIZE(route->family), state);
@ -356,6 +357,10 @@ int route_compare_func(const Route *a, const Route *b) {
r = memcmp(&a->gw, &b->gw, FAMILY_ADDRESS_SIZE(a->family)); r = memcmp(&a->gw, &b->gw, FAMILY_ADDRESS_SIZE(a->family));
if (r != 0) if (r != 0)
return r; return r;
r = CMP(a->gw_weight, b->gw_weight);
if (r != 0)
return r;
} }
r = memcmp(&a->prefsrc, &b->prefsrc, FAMILY_ADDRESS_SIZE(a->family)); r = memcmp(&a->prefsrc, &b->prefsrc, FAMILY_ADDRESS_SIZE(a->family));
@ -484,23 +489,23 @@ static void route_copy(Route *dest, const Route *src, const MultipathRoute *m) {
} else { } else {
dest->gw_family = src->gw_family; dest->gw_family = src->gw_family;
dest->gw = src->gw; dest->gw = src->gw;
dest->gw_weight = src->gw_weight;
} }
} }
static int route_add_internal(Manager *manager, Link *link, Set **routes, const Route *in, const MultipathRoute *m, Route **ret) { static int route_add_internal(Manager *manager, Link *link, Set **routes, const Route *in, Route **ret) {
_cleanup_(route_freep) Route *route = NULL; _cleanup_(route_freep) Route *route = NULL;
int r; int r;
assert(manager || link); assert(manager || link);
assert(routes); assert(routes);
assert(in); assert(in);
assert(!m || (link && (m->ifindex == 0 || m->ifindex == link->ifindex)));
r = route_new(&route); r = route_new(&route);
if (r < 0) if (r < 0)
return r; return r;
route_copy(route, in, m); route_copy(route, in, NULL);
r = set_ensure_put(routes, &route_hash_ops, route); r = set_ensure_put(routes, &route_hash_ops, route);
if (r < 0) if (r < 0)
@ -521,20 +526,32 @@ static int route_add_internal(Manager *manager, Link *link, Set **routes, const
static int route_add_foreign(Manager *manager, Link *link, const Route *in, Route **ret) { static int route_add_foreign(Manager *manager, Link *link, const Route *in, Route **ret) {
assert(manager || link); assert(manager || link);
return route_add_internal(manager, link, link ? &link->routes_foreign : &manager->routes_foreign, in, NULL, ret); return route_add_internal(manager, link, link ? &link->routes_foreign : &manager->routes_foreign, in, ret);
} }
static int route_add(Manager *manager, Link *link, const Route *in, const MultipathRoute *m, Route **ret) { static int route_add(Manager *manager, Link *link, const Route *in, const MultipathRoute *m, Route **ret) {
_cleanup_(route_freep) Route *tmp = NULL;
Route *route; Route *route;
int r; int r;
assert(manager || link); assert(manager || link);
assert(in); assert(in);
if (m) {
assert(link && (m->ifindex == 0 || m->ifindex == link->ifindex));
r = route_new(&tmp);
if (r < 0)
return r;
route_copy(tmp, in, m);
in = tmp;
}
r = route_get(manager, link, in, &route); r = route_get(manager, link, in, &route);
if (r == -ENOENT) { if (r == -ENOENT) {
/* Route does not exist, create a new one */ /* Route does not exist, create a new one */
r = route_add_internal(manager, link, link ? &link->routes : &manager->routes, in, m, &route); r = route_add_internal(manager, link, link ? &link->routes : &manager->routes, in, &route);
if (r < 0) if (r < 0)
return r; return r;
} else if (r == 0) { } else if (r == 0) {
@ -1102,13 +1119,6 @@ int route_configure(
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Could not append RTA_MULTIPATH attribute: %m"); return log_link_error_errno(link, r, "Could not append RTA_MULTIPATH attribute: %m");
r = netlink_call_async(link->manager->rtnl, NULL, req, callback,
link_netlink_destroy_callback, link);
if (r < 0)
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
link_ref(link);
if (ordered_set_isempty(route->multipath_routes)) { if (ordered_set_isempty(route->multipath_routes)) {
Route *nr; Route *nr;
@ -1130,7 +1140,14 @@ int route_configure(
} }
} }
return 1; r = netlink_call_async(link->manager->rtnl, NULL, req, callback,
link_netlink_destroy_callback, link);
if (r < 0)
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
link_ref(link);
return 0;
} }
static int route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { static int route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
@ -1201,8 +1218,8 @@ int link_set_routes(Link *link) {
r = route_configure(rt, link, route_handler, NULL); r = route_configure(rt, link, route_handler, NULL);
if (r < 0) if (r < 0)
return log_link_warning_errno(link, r, "Could not set routes: %m"); return log_link_warning_errno(link, r, "Could not set routes: %m");
if (r > 0)
link->route_messages++; link->route_messages++;
} }
if (link->route_messages == 0) { if (link->route_messages == 0) {

View File

@ -3892,7 +3892,7 @@ int json_dispatch(JsonVariant *v, const JsonDispatch table[], JsonDispatchCallba
assert_se(value = json_variant_by_index(v, i+1)); assert_se(value = json_variant_by_index(v, i+1));
for (p = table; p->name; p++) for (p = table; p->name; p++)
if (p->name == (const char*) -1 || if (p->name == POINTER_MAX ||
streq_ptr(json_variant_string(key), p->name)) streq_ptr(json_variant_string(key), p->name))
break; break;

View File

@ -0,0 +1,17 @@
# SPDX-License-Identifier: LGPL-2.1+
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[Unit]
Description=Initrd Encrypted Volumes
Documentation=man:systemd.special(7)
OnFailure=emergency.target
OnFailureJobMode=replace-irreversibly
AssertPathExists=/etc/initrd-release
DefaultDependencies=no
Conflicts=shutdown.target

View File

@ -28,6 +28,8 @@ units = [
['hybrid-sleep.target', 'ENABLE_HIBERNATE'], ['hybrid-sleep.target', 'ENABLE_HIBERNATE'],
['suspend-then-hibernate.target', 'ENABLE_HIBERNATE'], ['suspend-then-hibernate.target', 'ENABLE_HIBERNATE'],
['initrd-cleanup.service', 'ENABLE_INITRD'], ['initrd-cleanup.service', 'ENABLE_INITRD'],
['initrd-cryptsetup.target', 'HAVE_LIBCRYPTSETUP ENABLE_INITRD',
'sysinit.target.wants/'],
['initrd-fs.target', 'ENABLE_INITRD'], ['initrd-fs.target', 'ENABLE_INITRD'],
['initrd-parse-etc.service', 'ENABLE_INITRD'], ['initrd-parse-etc.service', 'ENABLE_INITRD'],
['initrd-root-device.target', 'ENABLE_INITRD'], ['initrd-root-device.target', 'ENABLE_INITRD'],