Compare commits

...

7 Commits

Author SHA1 Message Date
Michal Sekletár 28ca867abd sd-journal: close journal files that were deleted by journald before we've setup inotify watch
Fixes #14695
2020-02-05 18:34:52 +01:00
Zbigniew Jędrzejewski-Szmek c7220ca802 units: drop OnFailure= from .target units
See c80a9a33d0, target units can't fail.
I guess we need to figure out some replacement functionality, but at least
let's avoid the warning from systemd for now.
2020-02-05 18:34:30 +01:00
Chris Down e0e2112f61 cgroup: systemctl: Don't display NULL if protection was set to max
Inside format_bytes, we return NULL if the value is UINT64_MAX. This
makes some kind of sense where this has some other semantic meaning than
being a value, but in this case the value is both a.) not the default
(so we definitely want to display it), and b.) means "infinity" (or
"max" in cgroup terminology).

This patch adds a small wrapper around format_bytes that can be used for
these cases, to avoid the following situation:

    [root@tangsanjiao ~]# cat /sys/fs/cgroup/workload.slice/memory.low
    max
    [root@tangsanjiao ~]# systemctl show workload.slice -p MemoryLow
    MemoryLow=infinity
    [root@tangsanjiao ~]# systemctl status workload.slice | grep low:
	Memory: 14.9G (low: (null))

After the patch:

    [root@tangsanjiao ~]# systemctl status workload.slice | grep low:
	Memory: 15.1G (low: infinity)
2020-02-05 18:32:33 +01:00
Michal Koutný 8b51950f4c docs: Correct resource weight range 2020-02-05 16:58:07 +00:00
Zbigniew Jędrzejewski-Szmek 5bbcff2a1d
Merge pull request #14415 from ssahani/prefixstable-rfc-7217-new
network: Allow to specify multiple IPv6Token for SLAAC
2020-02-05 17:05:33 +01:00
Yu Watanabe 87bbebeab6 test-network: add tests for IPv6Token= 2020-02-05 17:44:42 +09:00
Susant Sahani 5f506a5560 network: Allow to specify multiple IPv6Token for SLAAC
Provide names to choose between different auto-generation types:
2.1 "eui64" for EUI-64 of RFC 4291
2.2 "prefixstable" for RFC 7217

```
[Match]
Name=veth99

[Network]
DHCP=no
IPv6AcceptRA=yes
IPv6Token=prefixstable:2001:888:0db8:1::
```
2020-02-05 17:44:42 +09:00
20 changed files with 326 additions and 44 deletions

View File

@ -381,9 +381,9 @@ that might have changed user identity), in bytes. Enforced by
[`systemd-logind.service`](https://www.freedesktop.org/software/systemd/man/systemd-logind.service.html), [`systemd-logind.service`](https://www.freedesktop.org/software/systemd/man/systemd-logind.service.html),
similar to `tasksMax`. similar to `tasksMax`.
`cpuWeight`/`ioWeight` → These take unsigned integers in the range 100…10000 `cpuWeight`/`ioWeight` → These take unsigned integers in the range 1…10000
and configure the CPU and IO scheduling weights for the user's processes as a (defaults to 100) and configure the CPU and IO scheduling weights for the
whole. Also enforced by user's processes as a whole. Also enforced by
[`systemd-logind.service`](https://www.freedesktop.org/software/systemd/man/systemd-logind.service.html), [`systemd-logind.service`](https://www.freedesktop.org/software/systemd/man/systemd-logind.service.html),
similar to `tasksMax`, `memoryHigh` and `memoryMax`. similar to `tasksMax`, `memoryHigh` and `memoryMax`.

View File

@ -308,11 +308,19 @@
<varlistentry> <varlistentry>
<term><varname>IPv6Token=</varname></term> <term><varname>IPv6Token=</varname></term>
<listitem> <listitem>
<para>An IPv6 address with the top 64 bits unset. When set, indicates the <para>Specifies an optional address generation mechanism and an optional address prefix. If
64-bit interface part of SLAAC IPv6 addresses for this link. Note that the mechanism is present, the two parts must be separated with a colon
the token is only ever used for SLAAC, and not for DHCPv6 addresses, even <literal><replaceable>type</replaceable>:<replaceable>prefix</replaceable></literal>. The
in the case DHCP is requested by router advertisement. By default, the address generation mechanism may be either <constant>prefixstable</constant> or
token is autogenerated.</para> <constant>eui64</constant>. If not specified, <constant>eui64</constant> is assumed. When
set to <literal>prefixstable</literal> a method for generating IPv6 Interface Identifiers to
be used with IPv6 Stateless Address Autocon figuration (SLAAC). See
<ulink url="https://tools.ietf.org/html/rfc7217">RFC 7217</ulink>. When IPv6 address is set,
indicates the 64-bit interface part of SLAAC IPv6 addresses for this link.</para>
<para>Note that the token is only ever used for SLAAC, and not for DHCPv6 addresses, even in
the case DHCP is requested by router advertisement. By default, the token is autogenerated.
</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>

View File

@ -5,6 +5,7 @@
#include <net/if.h> #include <net/if.h>
#include <stdbool.h> #include <stdbool.h>
#include "cgroup-util.h"
#include "macro.h" #include "macro.h"
assert_cc(sizeof(pid_t) == sizeof(int32_t)); assert_cc(sizeof(pid_t) == sizeof(int32_t));
@ -71,8 +72,15 @@ typedef enum {
FORMAT_BYTES_TRAILING_B = 1 << 2, FORMAT_BYTES_TRAILING_B = 1 << 2,
} FormatBytesFlag; } FormatBytesFlag;
#define FORMAT_BYTES_MAX 8 #define FORMAT_BYTES_MAX 16
char *format_bytes_full(char *buf, size_t l, uint64_t t, FormatBytesFlag flag); char *format_bytes_full(char *buf, size_t l, uint64_t t, FormatBytesFlag flag);
static inline char *format_bytes(char *buf, size_t l, uint64_t t) { static inline char *format_bytes(char *buf, size_t l, uint64_t t) {
return format_bytes_full(buf, l, t, FORMAT_BYTES_USE_IEC | FORMAT_BYTES_BELOW_POINT | FORMAT_BYTES_TRAILING_B); return format_bytes_full(buf, l, t, FORMAT_BYTES_USE_IEC | FORMAT_BYTES_BELOW_POINT | FORMAT_BYTES_TRAILING_B);
} }
static inline char *format_bytes_cgroup_protection(char *buf, size_t l, uint64_t t) {
if (t == CGROUP_LIMIT_MAX) {
(void) snprintf(buf, l, "%s", "infinity");
return buf;
}
return format_bytes(buf, l, t);
}

View File

@ -601,7 +601,7 @@ static int journal_file_verify_header(JournalFile *f) {
return 0; return 0;
} }
static int journal_file_fstat(JournalFile *f) { int journal_file_fstat(JournalFile *f) {
int r; int r;
assert(f); assert(f);

View File

@ -145,6 +145,7 @@ int journal_file_open(
int journal_file_set_offline(JournalFile *f, bool wait); int journal_file_set_offline(JournalFile *f, bool wait);
bool journal_file_is_offlining(JournalFile *f); bool journal_file_is_offlining(JournalFile *f);
JournalFile* journal_file_close(JournalFile *j); JournalFile* journal_file_close(JournalFile *j);
int journal_file_fstat(JournalFile *f);
DEFINE_TRIVIAL_CLEANUP_FUNC(JournalFile*, journal_file_close); DEFINE_TRIVIAL_CLEANUP_FUNC(JournalFile*, journal_file_close);
int journal_file_open_reliably( int journal_file_open_reliably(

View File

@ -2661,6 +2661,8 @@ _public_ int sd_journal_wait(sd_journal *j, uint64_t timeout_usec) {
assert_return(!journal_pid_changed(j), -ECHILD); assert_return(!journal_pid_changed(j), -ECHILD);
if (j->inotify_fd < 0) { if (j->inotify_fd < 0) {
Iterator i;
JournalFile *f;
/* This is the first invocation, hence create the /* This is the first invocation, hence create the
* inotify watch */ * inotify watch */
@ -2668,6 +2670,19 @@ _public_ int sd_journal_wait(sd_journal *j, uint64_t timeout_usec) {
if (r < 0) if (r < 0)
return r; return r;
/* Server might have done some vacuuming while we weren't watching.
Get rid of the deleted files now so they don't stay around indefinitely. */
ORDERED_HASHMAP_FOREACH(f, j->files, i) {
r = journal_file_fstat(f);
if (r < 0) {
log_debug_errno(r,"Failed to fstat() journal file '%s' : %m", f->path);
continue;
}
if (f->last_stat.st_nlink <= 0)
remove_file_real(j, f);
}
/* The journal might have changed since the context /* The journal might have changed since the context
* object was created and we weren't watching before, * object was created and we weren't watching before,
* hence don't wait for anything, and return * hence don't wait for anything, and return

View File

@ -13,12 +13,74 @@
#include "networkd-manager.h" #include "networkd-manager.h"
#include "networkd-ndisc.h" #include "networkd-ndisc.h"
#include "networkd-route.h" #include "networkd-route.h"
#include "string-util.h"
#include "strv.h" #include "strv.h"
#define NDISC_DNSSL_MAX 64U #define NDISC_DNSSL_MAX 64U
#define NDISC_RDNSS_MAX 64U #define NDISC_RDNSS_MAX 64U
#define NDISC_PREFIX_LFT_MIN 7200U #define NDISC_PREFIX_LFT_MIN 7200U
#define DAD_CONFLICTS_IDGEN_RETRIES_RFC7217 3
/* https://tools.ietf.org/html/rfc5453 */
/* https://www.iana.org/assignments/ipv6-interface-ids/ipv6-interface-ids.xml */
#define SUBNET_ROUTER_ANYCAST_ADDRESS_RFC4291 ((struct in6_addr) { .s6_addr = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } })
#define SUBNET_ROUTER_ANYCAST_PREFIXLEN 8
#define RESERVED_IPV6_INTERFACE_IDENTIFIERS_ADDRESS_RFC4291 ((struct in6_addr) { .s6_addr = { 0x02, 0x00, 0x5E, 0xFF, 0xFE } })
#define RESERVED_IPV6_INTERFACE_IDENTIFIERS_PREFIXLEN 5
#define RESERVED_SUBNET_ANYCAST_ADDRESSES_RFC4291 ((struct in6_addr) { .s6_addr = { 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF } })
#define RESERVED_SUBNET_ANYCAST_PREFIXLEN 7
#define NDISC_APP_ID SD_ID128_MAKE(13,ac,81,a7,d5,3f,49,78,92,79,5d,0c,29,3a,bc,7e)
static bool stableprivate_address_is_valid(const struct in6_addr *addr) {
assert(addr);
/* According to rfc4291, generated address should not be in the following ranges. */
if (memcmp(addr, &SUBNET_ROUTER_ANYCAST_ADDRESS_RFC4291, SUBNET_ROUTER_ANYCAST_PREFIXLEN) == 0)
return false;
if (memcmp(addr, &RESERVED_IPV6_INTERFACE_IDENTIFIERS_ADDRESS_RFC4291, RESERVED_IPV6_INTERFACE_IDENTIFIERS_PREFIXLEN) == 0)
return false;
if (memcmp(addr, &RESERVED_SUBNET_ANYCAST_ADDRESSES_RFC4291, RESERVED_SUBNET_ANYCAST_PREFIXLEN) == 0)
return false;
return true;
}
static int make_stableprivate_address(Link *link, const struct in6_addr *prefix, uint8_t prefix_len, uint8_t dad_counter, struct in6_addr *addr) {
sd_id128_t secret_key;
struct siphash state;
uint64_t rid;
size_t l;
int r;
/* According to rfc7217 section 5.1
* RID = F(Prefix, Net_Iface, Network_ID, DAD_Counter, secret_key) */
r = sd_id128_get_machine_app_specific(NDISC_APP_ID, &secret_key);
if (r < 0)
return log_error_errno(r, "Failed to generate key: %m");
siphash24_init(&state, secret_key.bytes);
l = MAX(DIV_ROUND_UP(prefix_len, 8), 8);
siphash24_compress(prefix, l, &state);
siphash24_compress(link->ifname, strlen(link->ifname), &state);
siphash24_compress(&link->mac, sizeof(struct ether_addr), &state);
siphash24_compress(&dad_counter, sizeof(uint8_t), &state);
rid = htole64(siphash24_finalize(&state));
memcpy(addr->s6_addr, prefix->s6_addr, l);
memcpy((uint8_t *) &addr->s6_addr + l, &rid, 16 - l);
return 0;
}
static int ndisc_netlink_route_message_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) { static int ndisc_netlink_route_message_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r; int r;
@ -192,12 +254,62 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
return 0; return 0;
} }
static int ndisc_router_generate_address(Link *link, unsigned prefixlen, uint32_t lifetime_preferred, Address *address) {
bool prefix = false;
struct in6_addr addr;
IPv6Token *j;
Iterator i;
int r;
assert(address);
assert(link);
addr = address->in_addr.in6;
ORDERED_HASHMAP_FOREACH(j, link->network->ipv6_tokens, i)
if (j->address_generation_type == IPV6_TOKEN_ADDRESS_GENERATION_PREFIXSTABLE
&& memcmp(&j->prefix, &addr, FAMILY_ADDRESS_SIZE(address->family)) == 0) {
for (; j->dad_counter < DAD_CONFLICTS_IDGEN_RETRIES_RFC7217; j->dad_counter++) {
r = make_stableprivate_address(link, &j->prefix, prefixlen, j->dad_counter, &address->in_addr.in6);
if (r < 0)
return r;
if (stableprivate_address_is_valid(&address->in_addr.in6)) {
prefix = true;
break;
}
}
} else if (j->address_generation_type == IPV6_TOKEN_ADDRESS_GENERATION_EUI64) {
memcpy(((uint8_t *)&address->in_addr.in6) + 8, ((uint8_t *) &j->prefix) + 8, 8);
prefix = true;
break;
}
/* eui64 or fallback if prefixstable do not match */
if (!prefix) {
/* see RFC4291 section 2.5.1 */
address->in_addr.in6.s6_addr[8] = link->mac.ether_addr_octet[0];
address->in_addr.in6.s6_addr[8] ^= 1 << 1;
address->in_addr.in6.s6_addr[9] = link->mac.ether_addr_octet[1];
address->in_addr.in6.s6_addr[10] = link->mac.ether_addr_octet[2];
address->in_addr.in6.s6_addr[11] = 0xff;
address->in_addr.in6.s6_addr[12] = 0xfe;
address->in_addr.in6.s6_addr[13] = link->mac.ether_addr_octet[3];
address->in_addr.in6.s6_addr[14] = link->mac.ether_addr_octet[4];
address->in_addr.in6.s6_addr[15] = link->mac.ether_addr_octet[5];
}
address->prefixlen = prefixlen;
address->flags = IFA_F_NOPREFIXROUTE|IFA_F_MANAGETEMPADDR;
address->cinfo.ifa_prefered = lifetime_preferred;
return 0;
}
static int ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *rt) { static int ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *rt) {
uint32_t lifetime_valid, lifetime_preferred, lifetime_remaining;
_cleanup_(address_freep) Address *address = NULL; _cleanup_(address_freep) Address *address = NULL;
Address *existing_address; Address *existing_address;
uint32_t lifetime_valid, lifetime_preferred, lifetime_remaining;
usec_t time_now;
unsigned prefixlen; unsigned prefixlen;
usec_t time_now;
int r; int r;
assert(link); assert(link);
@ -232,23 +344,9 @@ static int ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *r
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Failed to get prefix address: %m"); return log_link_error_errno(link, r, "Failed to get prefix address: %m");
if (in_addr_is_null(AF_INET6, (const union in_addr_union *) &link->network->ipv6_token) == 0) r = ndisc_router_generate_address(link, prefixlen, lifetime_preferred, address);
memcpy(((char *)&address->in_addr.in6) + 8, ((char *)&link->network->ipv6_token) + 8, 8); if (r < 0)
else { return log_link_error_errno(link, r, "Falied to generate prefix stable address: %m");
/* see RFC4291 section 2.5.1 */
address->in_addr.in6.s6_addr[8] = link->mac.ether_addr_octet[0];
address->in_addr.in6.s6_addr[8] ^= 1 << 1;
address->in_addr.in6.s6_addr[9] = link->mac.ether_addr_octet[1];
address->in_addr.in6.s6_addr[10] = link->mac.ether_addr_octet[2];
address->in_addr.in6.s6_addr[11] = 0xff;
address->in_addr.in6.s6_addr[12] = 0xfe;
address->in_addr.in6.s6_addr[13] = link->mac.ether_addr_octet[3];
address->in_addr.in6.s6_addr[14] = link->mac.ether_addr_octet[4];
address->in_addr.in6.s6_addr[15] = link->mac.ether_addr_octet[5];
}
address->prefixlen = prefixlen;
address->flags = IFA_F_NOPREFIXROUTE|IFA_F_MANAGETEMPADDR;
address->cinfo.ifa_prefered = lifetime_preferred;
/* see RFC4862 section 5.5.3.e */ /* see RFC4862 section 5.5.3.e */
r = address_get(link, address->family, &address->in_addr, address->prefixlen, &existing_address); r = address_get(link, address->family, &address->in_addr, address->prefixlen, &existing_address);
@ -755,6 +853,30 @@ void ndisc_flush(Link *link) {
link->ndisc_dnssl = set_free_free(link->ndisc_dnssl); link->ndisc_dnssl = set_free_free(link->ndisc_dnssl);
} }
int ipv6token_new(IPv6Token **ret) {
IPv6Token *p;
p = new(IPv6Token, 1);
if (!p)
return -ENOMEM;
*p = (IPv6Token) {
.address_generation_type = IPV6_TOKEN_ADDRESS_GENERATION_NONE,
};
*ret = TAKE_PTR(p);
return 0;
}
DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
ipv6_token_hash_ops,
void,
trivial_hash_func,
trivial_compare_func,
IPv6Token,
free);
int config_parse_ndisc_black_listed_prefix( int config_parse_ndisc_black_listed_prefix(
const char *unit, const char *unit,
const char *filename, const char *filename,
@ -826,3 +948,86 @@ int config_parse_ndisc_black_listed_prefix(
return 0; return 0;
} }
int config_parse_address_generation_type(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
_cleanup_free_ IPv6Token *token = NULL;
_cleanup_free_ char *word = NULL;
union in_addr_union buffer;
Network *network = data;
const char *p;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
if (isempty(rvalue)) {
network->ipv6_tokens = ordered_hashmap_free(network->ipv6_tokens);
return 0;
}
p = rvalue;
r = extract_first_word(&p, &word, ":", 0);
if (r == -ENOMEM)
return log_oom();
if (r <= 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Invalid IPv6Token= , ignoring assignment: %s", rvalue);
return 0;
}
r = ipv6token_new(&token);
if (r < 0)
return log_oom();
if (streq(word, "eui64"))
token->address_generation_type = IPV6_TOKEN_ADDRESS_GENERATION_EUI64;
else if (streq(word, "prefixstable"))
token->address_generation_type = IPV6_TOKEN_ADDRESS_GENERATION_PREFIXSTABLE;
else {
token->address_generation_type = IPV6_TOKEN_ADDRESS_GENERATION_EUI64;
p = rvalue;
}
r = in_addr_from_string(AF_INET6, p, &buffer);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse IPv6 %s, ignoring: %s", lvalue, rvalue);
return 0;
}
if (in_addr_is_null(AF_INET6, &buffer)) {
log_syntax(unit, LOG_ERR, filename, line, 0,
"IPv6 %s cannot be the ANY address, ignoring: %s", lvalue, rvalue);
return 0;
}
token->prefix = buffer.in6;
r = ordered_hashmap_ensure_allocated(&network->ipv6_tokens, &ipv6_token_hash_ops);
if (r < 0)
return log_oom();
r = ordered_hashmap_put(network->ipv6_tokens, &token->prefix, token);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to store IPv6 token '%s'", rvalue);
return 0;
}
TAKE_PTR(token);
return 0;
}

View File

@ -5,6 +5,16 @@
#include "networkd-link.h" #include "networkd-link.h"
#include "time-util.h" #include "time-util.h"
typedef struct IPv6Token IPv6Token;
typedef enum IPv6TokenAddressGeneration {
IPV6_TOKEN_ADDRESS_GENERATION_NONE,
IPV6_TOKEN_ADDRESS_GENERATION_EUI64,
IPV6_TOKEN_ADDRESS_GENERATION_PREFIXSTABLE,
_IPV6_TOKEN_ADDRESS_GENERATION_MAX,
_IPV6_TOKEN_ADDRESS_GENERATION_INVALID = -1,
} IPv6TokenAddressGeneration;
typedef struct NDiscRDNSS { typedef struct NDiscRDNSS {
usec_t valid_until; usec_t valid_until;
struct in6_addr address; struct in6_addr address;
@ -15,6 +25,16 @@ typedef struct NDiscDNSSL {
/* The domain name follows immediately. */ /* The domain name follows immediately. */
} NDiscDNSSL; } NDiscDNSSL;
struct IPv6Token {
IPv6TokenAddressGeneration address_generation_type;
uint8_t dad_counter;
struct in6_addr prefix;
};
int ipv6token_new(IPv6Token **ret);
DEFINE_TRIVIAL_CLEANUP_FUNC(IPv6Token *, freep);
static inline char* NDISC_DNSSL_DOMAIN(const NDiscDNSSL *n) { static inline char* NDISC_DNSSL_DOMAIN(const NDiscDNSSL *n) {
return ((char*) n) + ALIGN(sizeof(NDiscDNSSL)); return ((char*) n) + ALIGN(sizeof(NDiscDNSSL));
} }
@ -24,3 +44,4 @@ void ndisc_vacuum(Link *link);
void ndisc_flush(Link *link); void ndisc_flush(Link *link);
CONFIG_PARSER_PROTOTYPE(config_parse_ndisc_black_listed_prefix); CONFIG_PARSER_PROTOTYPE(config_parse_ndisc_black_listed_prefix);
CONFIG_PARSER_PROTOTYPE(config_parse_address_generation_type);

View File

@ -68,7 +68,7 @@ Network.DHCPServer, config_parse_bool,
Network.LinkLocalAddressing, config_parse_link_local_address_family, 0, offsetof(Network, link_local) Network.LinkLocalAddressing, config_parse_link_local_address_family, 0, offsetof(Network, link_local)
Network.IPv4LLRoute, config_parse_bool, 0, offsetof(Network, ipv4ll_route) Network.IPv4LLRoute, config_parse_bool, 0, offsetof(Network, ipv4ll_route)
Network.DefaultRouteOnDevice, config_parse_bool, 0, offsetof(Network, default_route_on_device) Network.DefaultRouteOnDevice, config_parse_bool, 0, offsetof(Network, default_route_on_device)
Network.IPv6Token, config_parse_ipv6token, 0, offsetof(Network, ipv6_token) Network.IPv6Token, config_parse_address_generation_type, 0, 0
Network.LLDP, config_parse_lldp_mode, 0, offsetof(Network, lldp_mode) Network.LLDP, config_parse_lldp_mode, 0, offsetof(Network, lldp_mode)
Network.EmitLLDP, config_parse_lldp_emit, 0, offsetof(Network, lldp_emit) Network.EmitLLDP, config_parse_lldp_emit, 0, offsetof(Network, lldp_emit)
Network.Address, config_parse_address, 0, 0 Network.Address, config_parse_address, 0, 0

View File

@ -705,6 +705,7 @@ static Network *network_free(Network *network) {
ordered_hashmap_free(network->dhcp_client_send_options); ordered_hashmap_free(network->dhcp_client_send_options);
ordered_hashmap_free(network->dhcp_server_send_options); ordered_hashmap_free(network->dhcp_server_send_options);
ordered_hashmap_free(network->ipv6_tokens);
return mfree(network); return mfree(network);
} }

View File

@ -22,6 +22,7 @@
#include "networkd-ipv6-proxy-ndp.h" #include "networkd-ipv6-proxy-ndp.h"
#include "networkd-lldp-rx.h" #include "networkd-lldp-rx.h"
#include "networkd-lldp-tx.h" #include "networkd-lldp-tx.h"
#include "networkd-ndisc.h"
#include "networkd-neighbor.h" #include "networkd-neighbor.h"
#include "networkd-nexthop.h" #include "networkd-nexthop.h"
#include "networkd-radv.h" #include "networkd-radv.h"
@ -218,8 +219,8 @@ struct Network {
uint32_t ipv6_accept_ra_route_table; uint32_t ipv6_accept_ra_route_table;
bool ipv6_accept_ra_route_table_set; bool ipv6_accept_ra_route_table_set;
Set *ndisc_black_listed_prefix; Set *ndisc_black_listed_prefix;
OrderedHashmap *ipv6_tokens;
union in_addr_union ipv6_token;
IPv6PrivacyExtensions ipv6_privacy_extensions; IPv6PrivacyExtensions ipv6_privacy_extensions;
struct ether_addr *mac; struct ether_addr *mac;

View File

@ -4478,11 +4478,11 @@ static void print_status_info(
printf(" ("); printf(" (");
if (i->memory_min > 0) { if (i->memory_min > 0) {
printf("%smin: %s", prefix, format_bytes(buf, sizeof(buf), i->memory_min)); printf("%smin: %s", prefix, format_bytes_cgroup_protection(buf, sizeof(buf), i->memory_min));
prefix = " "; prefix = " ";
} }
if (i->memory_low > 0) { if (i->memory_low > 0) {
printf("%slow: %s", prefix, format_bytes(buf, sizeof(buf), i->memory_low)); printf("%slow: %s", prefix, format_bytes_cgroup_protection(buf, sizeof(buf), i->memory_low));
prefix = " "; prefix = " ";
} }
if (i->memory_high != CGROUP_LIMIT_MAX) { if (i->memory_high != CGROUP_LIMIT_MAX) {

View File

@ -0,0 +1,6 @@
[Match]
Name=veth99
[Network]
IPv6AcceptRA=true
IPv6Token=::1a:2b:3c:4d

View File

@ -0,0 +1,6 @@
[Match]
Name=veth99
[Network]
IPv6AcceptRA=true
IPv6Token=prefixstable:2002:da8:1::

View File

@ -2644,7 +2644,9 @@ class NetworkdRATests(unittest.TestCase, Utilities):
units = [ units = [
'25-veth.netdev', '25-veth.netdev',
'ipv6-prefix.network', 'ipv6-prefix.network',
'ipv6-prefix-veth.network'] 'ipv6-prefix-veth.network',
'ipv6-prefix-veth-token-eui64.network',
'ipv6-prefix-veth-token-prefixstable.network']
def setUp(self): def setUp(self):
remove_links(self.links) remove_links(self.links)
@ -2669,6 +2671,24 @@ class NetworkdRATests(unittest.TestCase, Utilities):
print(output) print(output)
self.assertRegex(output, '2002:da8:1:0') self.assertRegex(output, '2002:da8:1:0')
def test_ipv6_token_eui64(self):
copy_unit_to_networkd_unit_path('25-veth.netdev', 'ipv6-prefix.network', 'ipv6-prefix-veth-token-eui64.network')
start_networkd()
self.wait_online(['veth99:routable', 'veth-peer:degraded'])
output = check_output(*networkctl_cmd, '-n', '0', 'status', 'veth99', env=env)
print(output)
self.assertRegex(output, '2002:da8:1:0:1a:2b:3c:4d')
def test_ipv6_token_prefixstable(self):
copy_unit_to_networkd_unit_path('25-veth.netdev', 'ipv6-prefix.network', 'ipv6-prefix-veth-token-prefixstable.network')
start_networkd()
self.wait_online(['veth99:routable', 'veth-peer:degraded'])
output = check_output(*networkctl_cmd, '-n', '0', 'status', 'veth99', env=env)
print(output)
self.assertRegex(output, '2002:da8:1:0')
class NetworkdDHCPServerTests(unittest.TestCase, Utilities): class NetworkdDHCPServerTests(unittest.TestCase, Utilities):
links = ['veth99'] links = ['veth99']

View File

@ -10,8 +10,6 @@
[Unit] [Unit]
Description=Initrd File Systems Description=Initrd File Systems
Documentation=man:systemd.special(7) Documentation=man:systemd.special(7)
OnFailure=emergency.target
OnFailureJobMode=replace-irreversibly
ConditionPathExists=/etc/initrd-release ConditionPathExists=/etc/initrd-release
After=initrd-parse-etc.service After=initrd-parse-etc.service
DefaultDependencies=no DefaultDependencies=no

View File

@ -11,7 +11,5 @@
Description=Initrd Root Device Description=Initrd Root Device
Documentation=man:systemd.special(7) Documentation=man:systemd.special(7)
ConditionPathExists=/etc/initrd-release ConditionPathExists=/etc/initrd-release
OnFailure=emergency.target
OnFailureJobMode=replace-irreversibly
DefaultDependencies=no DefaultDependencies=no
Conflicts=shutdown.target Conflicts=shutdown.target

View File

@ -11,7 +11,5 @@
Description=Initrd Root File System Description=Initrd Root File System
Documentation=man:systemd.special(7) Documentation=man:systemd.special(7)
ConditionPathExists=/etc/initrd-release ConditionPathExists=/etc/initrd-release
OnFailure=emergency.target
OnFailureJobMode=replace-irreversibly
DefaultDependencies=no DefaultDependencies=no
Conflicts=shutdown.target Conflicts=shutdown.target

View File

@ -10,8 +10,6 @@
[Unit] [Unit]
Description=Initrd Default Target Description=Initrd Default Target
Documentation=man:systemd.special(7) Documentation=man:systemd.special(7)
OnFailure=emergency.target
OnFailureJobMode=replace-irreversibly
ConditionPathExists=/etc/initrd-release ConditionPathExists=/etc/initrd-release
Requires=basic.target Requires=basic.target
Wants=initrd-root-fs.target initrd-root-device.target initrd-fs.target initrd-parse-etc.service Wants=initrd-root-fs.target initrd-root-device.target initrd-fs.target initrd-parse-etc.service

View File

@ -13,5 +13,3 @@ Documentation=man:systemd.special(7)
DefaultDependencies=no DefaultDependencies=no
Conflicts=shutdown.target Conflicts=shutdown.target
After=local-fs-pre.target After=local-fs-pre.target
OnFailure=emergency.target
OnFailureJobMode=replace-irreversibly