mirror of
https://github.com/systemd/systemd
synced 2026-03-31 20:24:50 +02:00
Compare commits
5 Commits
aa0379f16f
...
096a154acc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
096a154acc | ||
|
|
37e4637a9e | ||
|
|
b7f7c78793 | ||
|
|
a3ad6acf7b | ||
|
|
796273775c |
@ -17,6 +17,7 @@
|
||||
#include "fileio.h"
|
||||
#include "io-util.h"
|
||||
#include "macro.h"
|
||||
#include "memory-util.h"
|
||||
#include "stdio-util.h"
|
||||
#include "strv.h"
|
||||
#include "time-util.h"
|
||||
@ -159,12 +160,29 @@ int efi_get_variable_string(const char *variable, char **p) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int efi_verify_variable(const char *variable, uint32_t attr, const void *value, size_t size) {
|
||||
_cleanup_free_ void *buf = NULL;
|
||||
size_t n;
|
||||
uint32_t a;
|
||||
int r;
|
||||
|
||||
assert(variable);
|
||||
assert(value || size == 0);
|
||||
|
||||
r = efi_get_variable(variable, &a, &buf, &n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return a == attr && memcmp_nn(buf, n, value, size) == 0;
|
||||
}
|
||||
|
||||
int efi_set_variable(const char *variable, const void *value, size_t size) {
|
||||
struct var {
|
||||
uint32_t attr;
|
||||
char buf[];
|
||||
} _packed_ * _cleanup_free_ buf = NULL;
|
||||
_cleanup_close_ int fd = -1;
|
||||
uint32_t attr = EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS;
|
||||
bool saved_flags_valid = false;
|
||||
unsigned saved_flags;
|
||||
int r;
|
||||
@ -174,6 +192,12 @@ int efi_set_variable(const char *variable, const void *value, size_t size) {
|
||||
|
||||
const char *p = strjoina("/sys/firmware/efi/efivars/", variable);
|
||||
|
||||
/* size 0 means removal, empty variable would not be enough for that */
|
||||
if (size > 0 && efi_verify_variable(variable, attr, value, size) > 0) {
|
||||
log_debug("Variable '%s' is already in wanted state, skipping write.", variable);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Newer efivarfs protects variables that are not in an allow list with FS_IMMUTABLE_FL by default,
|
||||
* to protect them for accidental removal and modification. We are not changing these variables
|
||||
* accidentally however, hence let's unset the bit first. */
|
||||
@ -205,7 +229,7 @@ int efi_set_variable(const char *variable, const void *value, size_t size) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
buf->attr = EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS;
|
||||
buf->attr = attr;
|
||||
memcpy(buf->buf, value, size);
|
||||
|
||||
r = loop_write(fd, buf, sizeof(uint32_t) + size, false);
|
||||
|
||||
@ -150,8 +150,6 @@ static int dhcp6_pd_get_assigned_prefix(Link *link, const struct in6_addr *pd_pr
|
||||
}
|
||||
|
||||
int dhcp6_pd_remove(Link *link, bool only_marked) {
|
||||
Address *address;
|
||||
Route *route;
|
||||
int k, r = 0;
|
||||
|
||||
assert(link);
|
||||
@ -163,6 +161,9 @@ int dhcp6_pd_remove(Link *link, bool only_marked) {
|
||||
if (!only_marked)
|
||||
link->dhcp6_pd_configured = false;
|
||||
|
||||
if (!link->network->dhcp6_pd_assign) {
|
||||
Route *route;
|
||||
|
||||
SET_FOREACH(route, link->routes) {
|
||||
if (route->source != NETWORK_CONFIG_SOURCE_DHCP6PD)
|
||||
continue;
|
||||
@ -180,6 +181,8 @@ int dhcp6_pd_remove(Link *link, bool only_marked) {
|
||||
|
||||
route_cancel_request(route);
|
||||
}
|
||||
} else {
|
||||
Address *address;
|
||||
|
||||
SET_FOREACH(address, link->addresses) {
|
||||
struct in6_addr prefix;
|
||||
@ -203,6 +206,7 @@ int dhcp6_pd_remove(Link *link, bool only_marked) {
|
||||
|
||||
address_cancel_request(address);
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
@ -543,15 +547,15 @@ static int dhcp6_pd_prefix_distribute(
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
struct in6_addr assigned_prefix;
|
||||
|
||||
if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
|
||||
continue;
|
||||
|
||||
if (!link_dhcp6_pd_is_enabled(link))
|
||||
continue;
|
||||
|
||||
if (link == dhcp6_link && !link->network->dhcp6_pd_assign)
|
||||
continue;
|
||||
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
continue;
|
||||
|
||||
if (assign_preferred_subnet_id != link_has_preferred_subnet_id(link))
|
||||
continue;
|
||||
|
||||
@ -577,7 +581,7 @@ static int dhcp6_pd_prefix_distribute(
|
||||
}
|
||||
|
||||
static int dhcp6_pd_prepare(Link *link) {
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
|
||||
return 0;
|
||||
|
||||
if (!link_dhcp6_pd_is_enabled(link))
|
||||
@ -592,7 +596,7 @@ static int dhcp6_pd_prepare(Link *link) {
|
||||
static int dhcp6_pd_finalize(Link *link) {
|
||||
int r;
|
||||
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
|
||||
return 0;
|
||||
|
||||
if (!link_dhcp6_pd_is_enabled(link))
|
||||
@ -840,13 +844,18 @@ static int dhcp6_pd_prefix_acquired(Link *dhcp6_link) {
|
||||
return log_link_warning_errno(dhcp6_link, r, "Failed to get timestamp of DHCPv6 lease: %m");
|
||||
|
||||
HASHMAP_FOREACH(link, dhcp6_link->manager->links_by_index) {
|
||||
if (link == dhcp6_link)
|
||||
continue;
|
||||
|
||||
r = dhcp6_pd_prepare(link);
|
||||
if (r < 0)
|
||||
if (r < 0) {
|
||||
/* When failed on the upstream interface (i.e., the case link == dhcp6_link),
|
||||
* immediately abort the assignment of the prefixes. As, the all assigned
|
||||
* prefixes will be dropped soon in link_enter_failed(), and it is meaningless
|
||||
* to continue the assignment. */
|
||||
if (link == dhcp6_link)
|
||||
return r;
|
||||
|
||||
link_enter_failed(link);
|
||||
}
|
||||
}
|
||||
|
||||
for (sd_dhcp6_lease_reset_pd_prefix_iter(dhcp6_link->dhcp6_lease);;) {
|
||||
uint32_t lifetime_preferred_sec, lifetime_valid_sec;
|
||||
@ -917,13 +926,14 @@ static int dhcp6_pd_prefix_acquired(Link *dhcp6_link) {
|
||||
}
|
||||
|
||||
HASHMAP_FOREACH(link, dhcp6_link->manager->links_by_index) {
|
||||
if (link == dhcp6_link)
|
||||
continue;
|
||||
|
||||
r = dhcp6_pd_finalize(link);
|
||||
if (r < 0)
|
||||
if (r < 0) {
|
||||
if (link == dhcp6_link)
|
||||
return r;
|
||||
|
||||
link_enter_failed(link);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user