1
0
mirror of https://github.com/systemd/systemd synced 2025-11-09 20:04:46 +01:00

Compare commits

...

23 Commits

Author SHA1 Message Date
Lennart Poettering
e9769453e3
Merge pull request #16561 from yuwata/test-ordered-set
test: clarify that ordered_set_put() returns -EEXIST if entry is duplicated
2020-07-23 18:31:03 +02:00
Lennart Poettering
8047ac8fdc core: clean more env vars from env block pid1 receives
We generally clean all env vars we use ourselves to communicate with out
childrens. We forgot some more recent additions however. Let's correct
that.
2020-07-23 18:30:15 +02:00
Lennart Poettering
b226422cd7 firstboot: don't create /etc/passwd with mode 000
It needs to be world readable (unlike /etc/shadow) when created anew.

This fixes systems that boot with "systemd-nspawn --volatile=yes", i.e.
come up with an entirely empty /etc/ and thus no existing /etc/passwd
file when firstboot runs.
2020-07-23 17:09:11 +02:00
Lennart Poettering
2a2e78e969 nspawn: fix MS_SHARED mount propagation for userns containers
We want our OS trees to be MS_SHARED by default, so that our service
namespacing logic can work correctly. Thus in nspawn we mount everything
MS_SHARED when organizing our tree. We do this early on, before changing
the user namespace (if that's requested). However CLONE_NEWUSER actually
resets MS_SHARED to MS_SLAVE for all mounts (so that less privileged
environments can't affect the more privileged ones). Hence, when
invoking it we have to reset things to MS_SHARED afterwards again. This
won't reestablish propagation, but it will make sure we get a new set of
mount peer groups everywhere that then are honoured for the mount
namespaces/propagated mounts set up inside the container further down.
2020-07-23 17:08:39 +02:00
szb512
fe224669fb Update mkosi.ubuntu to 'focal'
[zjs: Looking at https://packages.ubuntu.com/bionic/iptables-dev, iptables-dev
was a transitional package that was pulling in libxtables-dev, libip4tc-dev,
and libip6tc-dev (as listed by @GiedriusS). iptables-dev is gone in focal, so
replace it by the expanded list.]
2020-07-23 16:44:09 +02:00
Yu Watanabe
6f5d73aba6 network: compare with peer address if it is specified
Follow-ups for dfef713f3e390ced671ce0ee87782cc373c937d0.
2020-07-23 16:37:56 +02:00
Zbigniew Jędrzejewski-Szmek
01b92946c5
Merge pull request #16532 from yuwata/network-sync-state-file
network: sync link state file on dbus call, and ndisc cleanups
2020-07-23 16:34:38 +02:00
Zbigniew Jędrzejewski-Szmek
d4fa0493a7 test-ordered-set: add a case where we get 0 for duplicate entries
This API is a complete mess. We forgot to do a hashed comparison for duplicate
entries and we use a direct pointer comparison. For trivial_hash_ops the result
is the same. For all other case, it's not. Fixing this properly will require
auditing all the uses of set_put() and ordered_set_put(). For now, let's just
acknowledge the breakage.
2020-07-23 15:47:21 +02:00
Zbigniew Jędrzejewski-Szmek
5cf821acf8 man: do not say that isolate is like switching runlevels
We need to do better here, but for now let's at least not trick
users into nuking their graphical environment. Inspired by #16548.
2020-07-23 15:30:35 +02:00
Zbigniew Jędrzejewski-Szmek
402e1e699f
Merge pull request #16557 from keszybz/two-ci-fixes
Two ci fixes
2020-07-23 15:24:46 +02:00
Yu Watanabe
2645d4bcc1 test: clarify that ordered_set_put() returns -EEXIST if entry is duplicated 2020-07-23 21:29:32 +09:00
Zbigniew Jędrzejewski-Szmek
0390b094f5 meson: do not choke on time epoch when there are no git tags
github ci was failing with:

meson.build:685:16: ERROR: String '' cannot be converted to int
2020-07-23 12:25:14 +02:00
Zbigniew Jędrzejewski-Szmek
960a64691f semaphore: pull in tree explicitly
semaphoreci was failing with:
Can't exec "tree": No such file or directory at /tmp/autopkgtest-lxc.v9oand4g/downtmp/build.TIm/src/test/udev-test.pl line 1752.

https://semaphoreci.com/systemd/systemd/branches/pull-request-16551/builds/1
2020-07-23 12:25:14 +02:00
Yu Watanabe
7f8c1e95a5 test-network: add test for duplicated IPv6Token= 2020-07-22 20:26:11 +09:00
Yu Watanabe
2c62149509 network: ndisc: ignore duplicated IPv6Token= 2020-07-22 20:26:11 +09:00
Yu Watanabe
92ee90af47 network: ndisc: do not store duplicated data in Set
The Address objects in the set generated by ndisc_router_generate_addresses()
have the equivalent prefixlen, flags, prefered lifetime.
This commit makes ndisc_router_generate_addresses() return Set of
in6_addr.
2020-07-22 20:26:05 +09:00
Yu Watanabe
3dbd8a15d5 util: use IN6_ARE_ADDR_EQUAL() macro 2020-07-22 19:55:15 +09:00
Yu Watanabe
f91b234077 test-network: drop unnecessary sleep() in NetworkdStateFileTests.test_state_file 2020-07-22 19:55:15 +09:00
Yu Watanabe
1b14222124 network: make bus methods sync link state file 2020-07-22 19:55:15 +09:00
Yu Watanabe
c2a6595014 network: introduce link_save_and_clean() 2020-07-22 19:55:14 +09:00
Yu Watanabe
f281fc1e95 tree-wide: use siphash24_compress_string() where it is applicable 2020-07-22 19:55:14 +09:00
Yu Watanabe
1c568d65ac util: introduce siphash24_compress_string() 2020-07-22 19:55:14 +09:00
Yu Watanabe
6c04fccb1d util: make siphash24_compress_boolean() inline
This also changes the stored type from int to uint8_t in order to make
hash value endianness independent.
2020-07-22 19:55:14 +09:00
25 changed files with 292 additions and 192 deletions

View File

@ -5,7 +5,7 @@
[Distribution]
Distribution=ubuntu
Release=bionic
Release=focal
Repositories=main,universe
[Output]
@ -25,7 +25,6 @@ BuildPackages=
git
gnu-efi
gperf
iptables-dev
libacl1-dev
libaudit-dev
libblkid-dev
@ -39,6 +38,8 @@ BuildPackages=
libgcrypt20-dev
libgnutls28-dev
libidn2-0-dev
libip4tc-dev
libip6tc-dev
libkmod-dev
liblz4-dev
liblz4-tool
@ -51,6 +52,7 @@ BuildPackages=
libsmartcols-dev
libtool
libxkbcommon-dev
libxtables-dev
libzstd-dev
m4
meson
@ -65,6 +67,6 @@ BuildPackages=
zstd
Packages=
libqrencode3
libqrencode4
locales
libidn2-0

3
TODO
View File

@ -1087,7 +1087,8 @@ Features:
- document systemd-journal-flush.service properly
- documentation: recommend to connect the timer units of a service to the service via Also= in [Install]
- man: document the very specific env the shutdown drop-in tools live in
- man: add more examples to man pages
- man: add more examples to man pages,
- in particular an example how to do the equivalent of switching runlevels
- man: maybe sort directives in man pages, and take sections from --help and apply them to man too
- document root=gpt-auto properly

View File

@ -263,11 +263,9 @@ Sun 2017-02-26 20:57:49 EST 2h 3min left Sun 2017-02-26 11:56:36 EST 6h ago
If a unit name with no extension is given, an extension of
<literal>.target</literal> will be assumed.</para>
<para>This is similar to changing the runlevel in a
traditional init system. The <command>isolate</command>
command will immediately stop processes that are not enabled
in the new unit, possibly including the graphical
environment or terminal you are currently using.</para>
<para>This command is dangerous, since it will immediately stop processes that are not enabled in
the new target, possibly including the graphical environment or terminal you are currently using.
</para>
<para>Note that this is allowed only on units where
<option>AllowIsolate=</option> is enabled. See

View File

@ -676,17 +676,17 @@ conf.set_quoted('DEFAULT_NET_NAMING_SCHEME', default_net_naming_scheme)
time_epoch = get_option('time-epoch')
if time_epoch == -1
source_date_epoch = run_command('sh', ['-c', 'echo "$SOURCE_DATE_EPOCH"']).stdout().strip()
if source_date_epoch != ''
time_epoch = source_date_epoch.to_int()
elif git.found() and run_command('test', '-e', '.git').returncode() == 0
time_epoch = run_command('sh', ['-c', 'echo "$SOURCE_DATE_EPOCH"']).stdout().strip()
if time_epoch == '' and git.found() and run_command('test', '-e', '.git').returncode() == 0
# If we're in a git repository, use the creation time of the latest git tag.
latest_tag = run_command('git', 'describe', '--abbrev=0', '--tags').stdout().strip()
time_epoch = run_command('git', 'log', '-1', '--format=%at', latest_tag).stdout().to_int()
else
NEWS = files('NEWS')
time_epoch = run_command(stat, '-c', '%Y', NEWS).stdout().to_int()
time_epoch = run_command('git', 'log', '-1', '--format=%at', latest_tag).stdout()
endif
if time_epoch == ''
NEWS = files('NEWS')
time_epoch = run_command(stat, '-c', '%Y', NEWS).stdout()
endif
time_epoch = time_epoch.to_int()
endif
conf.set('TIME_EPOCH', time_epoch)

View File

@ -37,7 +37,7 @@ apt-get -q --allow-releaseinfo-change update
apt-get -y dist-upgrade
apt-get install -y eatmydata
# The following four are needed as long as these deps are not covered by Debian's own packaging
apt-get install -y fdisk libfdisk-dev libp11-kit-dev libssl-dev libpwquality-dev
apt-get install -y fdisk tree libfdisk-dev libp11-kit-dev libssl-dev libpwquality-dev
apt-get purge --auto-remove -y unattended-upgrades
systemctl unmask systemd-networkd
systemctl enable systemd-networkd

View File

@ -108,11 +108,7 @@ int in_addr_equal(int family, const union in_addr_union *a, const union in_addr_
return in4_addr_equal(&a->in, &b->in);
if (family == AF_INET6)
return
a->in6.s6_addr32[0] == b->in6.s6_addr32[0] &&
a->in6.s6_addr32[1] == b->in6.s6_addr32[1] &&
a->in6.s6_addr32[2] == b->in6.s6_addr32[2] &&
a->in6.s6_addr32[3] == b->in6.s6_addr32[3];
return IN6_ARE_ADDR_EQUAL(&a->in6, &b->in6);
return -EAFNOSUPPORT;
}

View File

@ -151,12 +151,6 @@ void siphash24_compress(const void *_in, size_t inlen, struct siphash *state) {
}
}
void siphash24_compress_boolean(bool in, struct siphash *state) {
int i = in;
siphash24_compress(&i, sizeof i, state);
}
uint64_t siphash24_finalize(struct siphash *state) {
uint64_t b;

View File

@ -17,9 +17,21 @@ struct siphash {
void siphash24_init(struct siphash *state, const uint8_t k[static 16]);
void siphash24_compress(const void *in, size_t inlen, struct siphash *state);
void siphash24_compress_boolean(bool in, struct siphash *state);
#define siphash24_compress_byte(byte, state) siphash24_compress((const uint8_t[]) { (byte) }, 1, (state))
static inline void siphash24_compress_boolean(bool in, struct siphash *state) {
uint8_t i = in;
siphash24_compress(&i, sizeof i, state);
}
static inline void siphash24_compress_string(const char *in, struct siphash *state) {
if (!in)
return;
siphash24_compress(in, strlen(in), state);
}
uint64_t siphash24_finalize(struct siphash *state);
uint64_t siphash24(const void *in, size_t inlen, const uint8_t k[static 16]);

View File

@ -589,6 +589,8 @@ static char** sanitize_environment(char **l) {
/* Let's remove some environment variables that we need ourselves to communicate with our clients */
strv_env_unset_many(
l,
"CACHE_DIRECTORY",
"CONFIGURATION_DIRECTORY",
"EXIT_CODE",
"EXIT_STATUS",
"INVOCATION_ID",
@ -596,13 +598,16 @@ static char** sanitize_environment(char **l) {
"LISTEN_FDNAMES",
"LISTEN_FDS",
"LISTEN_PID",
"LOGS_DIRECTORY",
"MAINPID",
"MANAGERPID",
"NOTIFY_SOCKET",
"PIDFILE",
"REMOTE_ADDR",
"REMOTE_PORT",
"RUNTIME_DIRECTORY",
"SERVICE_RESULT",
"STATE_DIRECTORY",
"WATCHDOG_PID",
"WATCHDOG_USEC",
NULL);

View File

@ -685,7 +685,7 @@ static int write_root_passwd(const char *passwd_path, const char *password, cons
if (errno != ENOENT)
return -errno;
r = fchmod(fileno(passwd), 0000);
r = fchmod(fileno(passwd), 0644);
if (r < 0)
return -errno;

View File

@ -55,7 +55,7 @@ typedef struct CatalogItem {
static void catalog_hash_func(const CatalogItem *i, struct siphash *state) {
siphash24_compress(&i->id, sizeof(i->id), state);
siphash24_compress(i->language, strlen(i->language), state);
siphash24_compress_string(i->language, state);
}
static int catalog_compare_func(const CatalogItem *a, const CatalogItem *b) {

View File

@ -110,7 +110,10 @@ int bus_link_method_set_ntp_servers(sd_bus_message *message, void *userdata, sd_
strv_free_and_replace(l->ntp, ntp);
(void) link_dirty(l);
link_dirty(l);
r = link_save_and_clean(l);
if (r < 0)
return r;
return sd_bus_reply_method_return(message, NULL);
}
@ -150,7 +153,10 @@ static int bus_link_method_set_dns_servers_internal(sd_bus_message *message, voi
free_and_replace(l->dns, dns);
l->n_dns = n;
(void) link_dirty(l);
link_dirty(l);
r = link_save_and_clean(l);
if (r < 0)
return r;
return sd_bus_reply_method_return(message, NULL);
@ -240,7 +246,10 @@ int bus_link_method_set_domains(sd_bus_message *message, void *userdata, sd_bus_
l->search_domains = TAKE_PTR(search_domains);
l->route_domains = TAKE_PTR(route_domains);
(void) link_dirty(l);
link_dirty(l);
r = link_save_and_clean(l);
if (r < 0)
return r;
return sd_bus_reply_method_return(message, NULL);
}
@ -271,7 +280,11 @@ int bus_link_method_set_default_route(sd_bus_message *message, void *userdata, s
if (l->dns_default_route != b) {
l->dns_default_route = b;
(void) link_dirty(l);
link_dirty(l);
r = link_save_and_clean(l);
if (r < 0)
return r;
}
return sd_bus_reply_method_return(message, NULL);
@ -313,7 +326,11 @@ int bus_link_method_set_llmnr(sd_bus_message *message, void *userdata, sd_bus_er
if (l->llmnr != mode) {
l->llmnr = mode;
(void) link_dirty(l);
link_dirty(l);
r = link_save_and_clean(l);
if (r < 0)
return r;
}
return sd_bus_reply_method_return(message, NULL);
@ -355,7 +372,11 @@ int bus_link_method_set_mdns(sd_bus_message *message, void *userdata, sd_bus_err
if (l->mdns != mode) {
l->mdns = mode;
(void) link_dirty(l);
link_dirty(l);
r = link_save_and_clean(l);
if (r < 0)
return r;
}
return sd_bus_reply_method_return(message, NULL);
@ -397,7 +418,11 @@ int bus_link_method_set_dns_over_tls(sd_bus_message *message, void *userdata, sd
if (l->dns_over_tls_mode != mode) {
l->dns_over_tls_mode = mode;
(void) link_dirty(l);
link_dirty(l);
r = link_save_and_clean(l);
if (r < 0)
return r;
}
return sd_bus_reply_method_return(message, NULL);
@ -439,7 +464,11 @@ int bus_link_method_set_dnssec(sd_bus_message *message, void *userdata, sd_bus_e
if (l->dnssec_mode != mode) {
l->dnssec_mode = mode;
(void) link_dirty(l);
link_dirty(l);
r = link_save_and_clean(l);
if (r < 0)
return r;
}
return sd_bus_reply_method_return(message, NULL);
@ -493,7 +522,10 @@ int bus_link_method_set_dnssec_negative_trust_anchors(sd_bus_message *message, v
set_free_free(l->dnssec_negative_trust_anchors);
l->dnssec_negative_trust_anchors = TAKE_PTR(ns);
(void) link_dirty(l);
link_dirty(l);
r = link_save_and_clean(l);
if (r < 0)
return r;
return sd_bus_reply_method_return(message, NULL);
}
@ -519,7 +551,11 @@ int bus_link_method_revert_ntp(sd_bus_message *message, void *userdata, sd_bus_e
return 1; /* Polkit will call us back */
link_ntp_settings_clear(l);
(void) link_dirty(l);
link_dirty(l);
r = link_save_and_clean(l);
if (r < 0)
return r;
return sd_bus_reply_method_return(message, NULL);
}
@ -545,7 +581,11 @@ int bus_link_method_revert_dns(sd_bus_message *message, void *userdata, sd_bus_e
return 1; /* Polkit will call us back */
link_dns_settings_clear(l);
(void) link_dirty(l);
link_dirty(l);
r = link_save_and_clean(l);
if (r < 0)
return r;
return sd_bus_reply_method_return(message, NULL);
}
@ -629,10 +669,9 @@ int bus_link_method_reconfigure(sd_bus_message *message, void *userdata, sd_bus_
return r;
link_set_state(l, LINK_STATE_INITIALIZED);
r = link_save(l);
r = link_save_and_clean(l);
if (r < 0)
return r;
link_clean(l);
return sd_bus_reply_method_return(message, NULL);
}

View File

@ -1297,7 +1297,10 @@ static int link_request_set_addresses(Link *link) {
LIST_FOREACH(addresses, ad, link->network->static_addresses) {
bool update;
update = address_get(link, ad->family, &ad->in_addr, ad->prefixlen, NULL) > 0;
if (ad->family == AF_INET6 && !in_addr_is_null(ad->family, &ad->in_addr_peer))
update = address_get(link, ad->family, &ad->in_addr_peer, ad->prefixlen, NULL) > 0;
else
update = address_get(link, ad->family, &ad->in_addr, ad->prefixlen, NULL) > 0;
r = address_configure(ad, link, address_handler, update);
if (r < 0)
@ -2603,6 +2606,9 @@ static bool link_is_static_address_configured(Link *link, Address *address) {
LIST_FOREACH(addresses, net_address, link->network->static_addresses)
if (address_equal(net_address, address))
return true;
else if (address->family == AF_INET6 && net_address->family == AF_INET6 &&
in_addr_equal(AF_INET6, &address->in_addr, &net_address->in_addr_peer) > 0)
return true;
return false;
}
@ -4525,6 +4531,17 @@ void link_clean(Link *link) {
link_unref(set_remove(link->manager->dirty_links, link));
}
int link_save_and_clean(Link *link) {
int r;
r = link_save(link);
if (r < 0)
return r;
link_clean(link);
return 0;
}
static const char* const link_state_table[_LINK_STATE_MAX] = {
[LINK_STATE_PENDING] = "pending",
[LINK_STATE_INITIALIZED] = "initialized",

View File

@ -208,6 +208,7 @@ int link_update(Link *link, sd_netlink_message *message);
void link_dirty(Link *link);
void link_clean(Link *link);
int link_save(Link *link);
int link_save_and_clean(Link *link);
int link_carrier_reset(Link *link);
bool link_has_carrier(Link *link);

View File

@ -1727,8 +1727,7 @@ static int manager_dirty_handler(sd_event_source *s, void *userdata) {
manager_save(m);
SET_FOREACH(link, m->dirty_links, i)
if (link_save(link) >= 0)
link_clean(link);
(void) link_save_and_clean(link);
return 1;
}
@ -1899,7 +1898,7 @@ int manager_start(Manager *m) {
manager_save(m);
HASHMAP_FOREACH(link, m->links, i)
link_save(link);
(void) link_save(link);
return 0;
}

View File

@ -35,53 +35,6 @@
#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(addr->s6_addr + l, &rid, 16 - l);
return 0;
}
static int ndisc_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int r;
@ -228,9 +181,66 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
return 0;
}
static int ndisc_router_generate_addresses(Link *link, unsigned prefixlen, uint32_t lifetime_preferred, Address *address, Set **ret) {
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 **ret) {
_cleanup_free_ struct in6_addr *addr = NULL;
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_string(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));
addr = new(struct in6_addr, 1);
if (!addr)
return log_oom();
memcpy(addr->s6_addr, prefix->s6_addr, l);
memcpy(addr->s6_addr + l, &rid, 16 - l);
if (!stableprivate_address_is_valid(addr)) {
*ret = NULL;
return 0;
}
*ret = TAKE_PTR(addr);
return 1;
}
static int ndisc_router_generate_addresses(Link *link, struct in6_addr *address, uint8_t prefixlen, Set **ret) {
_cleanup_set_free_free_ Set *addresses = NULL;
struct in6_addr addr;
IPv6Token *j;
Iterator i;
int r;
@ -239,76 +249,63 @@ static int ndisc_router_generate_addresses(Link *link, unsigned prefixlen, uint3
assert(address);
assert(ret);
addresses = set_new(&address_hash_ops);
addresses = set_new(&in6_addr_hash_ops);
if (!addresses)
return log_oom();
addr = address->in_addr.in6;
ORDERED_HASHMAP_FOREACH(j, link->network->ipv6_tokens, i) {
bool have_address = false;
_cleanup_(address_freep) Address *new_address = NULL;
r = address_new(&new_address);
if (r < 0)
return log_oom();
*new_address = *address;
ORDERED_SET_FOREACH(j, link->network->ipv6_tokens, i) {
_cleanup_free_ struct in6_addr *new_address = NULL;
if (j->address_generation_type == IPV6_TOKEN_ADDRESS_GENERATION_PREFIXSTABLE
&& memcmp(&j->prefix, &addr, FAMILY_ADDRESS_SIZE(address->family)) == 0) {
&& IN6_ARE_ADDR_EQUAL(&j->prefix, address)) {
/* While this loop uses dad_counter and a retry limit as specified in RFC 7217, the loop
does not actually attempt Duplicate Address Detection; the counter will be incremented
only when the address generation algorithm produces an invalid address, and the loop
may exit with an address which ends up being unusable due to duplication on the link.
*/
for (; j->dad_counter < DAD_CONFLICTS_IDGEN_RETRIES_RFC7217; j->dad_counter++) {
r = make_stableprivate_address(link, &j->prefix, prefixlen, j->dad_counter, &new_address->in_addr.in6);
r = make_stableprivate_address(link, &j->prefix, prefixlen, j->dad_counter, &new_address);
if (r < 0)
return r;
if (r > 0)
break;
if (stableprivate_address_is_valid(&new_address->in_addr.in6)) {
have_address = true;
break;
}
}
} else if (j->address_generation_type == IPV6_TOKEN_ADDRESS_GENERATION_STATIC) {
memcpy(new_address->in_addr.in6.s6_addr + 8, j->prefix.s6_addr + 8, 8);
have_address = true;
new_address = new(struct in6_addr, 1);
if (!new_address)
return log_oom();
memcpy(new_address->s6_addr, address->s6_addr, 8);
memcpy(new_address->s6_addr + 8, j->prefix.s6_addr + 8, 8);
}
if (have_address) {
new_address->prefixlen = prefixlen;
new_address->flags = IFA_F_NOPREFIXROUTE|IFA_F_MANAGETEMPADDR;
new_address->cinfo.ifa_prefered = lifetime_preferred;
if (new_address) {
r = set_put(addresses, new_address);
if (r < 0)
return log_link_error_errno(link, r, "Failed to store SLAAC address: %m");
TAKE_PTR(new_address);
else if (r == 0)
log_link_debug_errno(link, r, "Generated SLAAC address is duplicated, ignoring.");
else
TAKE_PTR(new_address);
}
}
/* fall back to EUI-64 if no tokens provided addresses */
if (set_isempty(addresses)) {
_cleanup_(address_freep) Address *new_address = NULL;
_cleanup_free_ struct in6_addr *new_address = NULL;
r = address_new(&new_address);
if (r < 0)
new_address = newdup(struct in6_addr, address, 1);
if (!new_address)
return log_oom();
*new_address = *address;
r = generate_ipv6_eui_64_address(link, &new_address->in_addr.in6);
r = generate_ipv6_eui_64_address(link, new_address);
if (r < 0)
return log_link_error_errno(link, r, "Failed to generate EUI64 address: %m");
new_address->prefixlen = prefixlen;
new_address->flags = IFA_F_NOPREFIXROUTE|IFA_F_MANAGETEMPADDR;
new_address->cinfo.ifa_prefered = lifetime_preferred;
r = set_put(addresses, new_address);
if (r < 0)
return log_link_error_errno(link, r, "Failed to store SLAAC address: %m");
TAKE_PTR(new_address);
}
@ -321,9 +318,9 @@ static int ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *r
uint32_t lifetime_valid, lifetime_preferred, lifetime_remaining;
_cleanup_set_free_free_ Set *addresses = NULL;
_cleanup_(address_freep) Address *address = NULL;
struct in6_addr addr, *a;
unsigned prefixlen;
usec_t time_now;
Address *a;
Iterator i;
int r;
@ -350,41 +347,47 @@ static int ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *r
if (lifetime_preferred > lifetime_valid)
return 0;
r = sd_ndisc_router_prefix_get_address(rt, &addr);
if (r < 0)
return log_link_error_errno(link, r, "Failed to get prefix address: %m");
r = ndisc_router_generate_addresses(link, &addr, prefixlen, &addresses);
if (r < 0)
return r;
r = address_new(&address);
if (r < 0)
return log_oom();
address->family = AF_INET6;
r = sd_ndisc_router_prefix_get_address(rt, &address->in_addr.in6);
if (r < 0)
return log_link_error_errno(link, r, "Failed to get prefix address: %m");
r = ndisc_router_generate_addresses(link, prefixlen, lifetime_preferred, address, &addresses);
if (r < 0)
return r;
address->prefixlen = prefixlen;
address->flags = IFA_F_NOPREFIXROUTE|IFA_F_MANAGETEMPADDR;
address->cinfo.ifa_prefered = lifetime_preferred;
SET_FOREACH(a, addresses, i) {
Address *existing_address;
/* see RFC4862 section 5.5.3.e */
r = address_get(link, a->family, &a->in_addr, a->prefixlen, &existing_address);
r = address_get(link, AF_INET6, (union in_addr_union *) a, prefixlen, &existing_address);
if (r > 0) {
lifetime_remaining = existing_address->cinfo.tstamp / 100 + existing_address->cinfo.ifa_valid - time_now / USEC_PER_SEC;
if (lifetime_valid > NDISC_PREFIX_LFT_MIN || lifetime_valid > lifetime_remaining)
a->cinfo.ifa_valid = lifetime_valid;
address->cinfo.ifa_valid = lifetime_valid;
else if (lifetime_remaining <= NDISC_PREFIX_LFT_MIN)
a->cinfo.ifa_valid = lifetime_remaining;
address->cinfo.ifa_valid = lifetime_remaining;
else
a->cinfo.ifa_valid = NDISC_PREFIX_LFT_MIN;
address->cinfo.ifa_valid = NDISC_PREFIX_LFT_MIN;
} else if (lifetime_valid > 0)
a->cinfo.ifa_valid = lifetime_valid;
address->cinfo.ifa_valid = lifetime_valid;
else
continue; /* see RFC4862 section 5.5.3.d */
if (a->cinfo.ifa_valid == 0)
if (address->cinfo.ifa_valid == 0)
continue;
r = address_configure(a, link, ndisc_address_handler, true);
address->in_addr.in6 = *a;
r = address_configure(address, link, ndisc_address_handler, true);
if (r < 0)
return log_link_error_errno(link, r, "Could not set SLAAC address: %m");
if (r > 0)
@ -577,7 +580,7 @@ static int ndisc_router_process_rdnss(Link *link, sd_ndisc_router *rt) {
}
static void ndisc_dnssl_hash_func(const NDiscDNSSL *x, struct siphash *state) {
siphash24_compress(NDISC_DNSSL_DOMAIN(x), strlen(NDISC_DNSSL_DOMAIN(x)), state);
siphash24_compress_string(NDISC_DNSSL_DOMAIN(x), state);
}
static int ndisc_dnssl_compare_func(const NDiscDNSSL *a, const NDiscDNSSL *b) {
@ -904,12 +907,26 @@ int ipv6token_new(IPv6Token **ret) {
return 0;
}
DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
static void ipv6_token_hash_func(const IPv6Token *p, struct siphash *state) {
siphash24_compress(&p->address_generation_type, sizeof(p->address_generation_type), state);
siphash24_compress(&p->prefix, sizeof(p->prefix), state);
}
static int ipv6_token_compare_func(const IPv6Token *a, const IPv6Token *b) {
int r;
r = CMP(a->address_generation_type, b->address_generation_type);
if (r != 0)
return r;
return memcmp(&a->prefix, &b->prefix, sizeof(struct in6_addr));
}
DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(
ipv6_token_hash_ops,
void,
trivial_hash_func,
trivial_compare_func,
IPv6Token,
ipv6_token_hash_func,
ipv6_token_compare_func,
free);
int config_parse_ndisc_deny_listed_prefix(
@ -999,7 +1016,7 @@ int config_parse_address_generation_type(
assert(data);
if (isempty(rvalue)) {
network->ipv6_tokens = ordered_hashmap_free(network->ipv6_tokens);
network->ipv6_tokens = ordered_set_free(network->ipv6_tokens);
return 0;
}
@ -1031,18 +1048,19 @@ int config_parse_address_generation_type(
token->prefix = buffer.in6;
r = ordered_hashmap_ensure_allocated(&network->ipv6_tokens, &ipv6_token_hash_ops);
r = ordered_set_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) {
r = ordered_set_put(network->ipv6_tokens, token);
if (r == -EEXIST)
log_syntax(unit, LOG_DEBUG, filename, line, r,
"IPv6 token '%s' is duplicated, ignoring: %m", rvalue);
else if (r < 0)
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to store IPv6 token '%s'", rvalue);
return 0;
}
TAKE_PTR(token);
"Failed to store IPv6 token '%s', ignoring: %m", rvalue);
else
TAKE_PTR(token);
return 0;
}

View File

@ -763,7 +763,7 @@ static Network *network_free(Network *network) {
ordered_hashmap_free(network->dhcp_client_send_vendor_options);
ordered_hashmap_free(network->dhcp_server_send_options);
ordered_hashmap_free(network->dhcp_server_send_vendor_options);
ordered_hashmap_free(network->ipv6_tokens);
ordered_set_free(network->ipv6_tokens);
ordered_hashmap_free(network->dhcp6_client_send_options);
ordered_hashmap_free(network->dhcp6_client_send_vendor_options);

View File

@ -255,7 +255,7 @@ struct Network {
IPv6AcceptRAStartDHCP6Client ipv6_accept_ra_start_dhcp6_client;
uint32_t ipv6_accept_ra_route_table;
Set *ndisc_deny_listed_prefix;
OrderedHashmap *ipv6_tokens;
OrderedSet *ipv6_tokens;
IPv6PrivacyExtensions ipv6_privacy_extensions;

View File

@ -132,11 +132,8 @@ static void routing_policy_rule_hash_func(const RoutingPolicyRule *rule, struct
siphash24_compress(&rule->dport, sizeof(rule->dport), state);
siphash24_compress(&rule->uid_range, sizeof(rule->uid_range), state);
if (rule->iif)
siphash24_compress(rule->iif, strlen(rule->iif), state);
if (rule->oif)
siphash24_compress(rule->oif, strlen(rule->oif), state);
siphash24_compress_string(rule->iif, state);
siphash24_compress_string(rule->oif, state);
break;
default:

View File

@ -117,7 +117,7 @@ int kernel_route_expiration_supported(void) {
}
static void network_config_hash_func(const NetworkConfigSection *c, struct siphash *state) {
siphash24_compress(c->filename, strlen(c->filename), state);
siphash24_compress_string(c->filename, state);
siphash24_compress(&c->line, sizeof(c->line), state);
}

View File

@ -2977,13 +2977,20 @@ static int inner_child(
/* Wait until the parent wrote the UID map */
if (!barrier_place_and_sync(barrier)) /* #2 */
return log_error_errno(SYNTHETIC_ERRNO(ESRCH),
"Parent died too early");
}
return log_error_errno(SYNTHETIC_ERRNO(ESRCH), "Parent died too early");
r = reset_uid_gid();
if (r < 0)
return log_error_errno(r, "Couldn't become new root: %m");
/* Become the new root user inside our namespace */
r = reset_uid_gid();
if (r < 0)
return log_error_errno(r, "Couldn't become new root: %m");
/* Creating a new user namespace means all MS_SHARED mounts become MS_SLAVE. Let's put them
* back to MS_SHARED here, since that's what we want as defaults. (This will not reconnect
* propagation, but simply create new peer groups for all our mounts). */
r = mount_verbose(LOG_ERR, NULL, "/", NULL, MS_SHARED|MS_REC, NULL);
if (r < 0)
return r;
}
r = mount_all(NULL,
arg_mount_settings | MOUNT_IN_USERNS,
@ -3350,9 +3357,8 @@ static int outer_child(
if (r < 0)
return r;
/* Mark everything as slave, so that we still
* receive mounts from the real root, but don't
* propagate mounts to the real root. */
/* Mark everything as slave, so that we still receive mounts from the real root, but don't propagate
* mounts to the real root. */
r = mount_verbose(LOG_ERR, NULL, "/", NULL, MS_SLAVE|MS_REC, NULL);
if (r < 0)
return r;
@ -3598,9 +3604,8 @@ static int outer_child(
notify_socket = safe_close(notify_socket);
uid_shift_socket = safe_close(uid_shift_socket);
/* The inner child has all namespaces that are
* requested, so that we all are owned by the user if
* user namespaces are turned on. */
/* The inner child has all namespaces that are requested, so that we all are owned by the
* user if user namespaces are turned on. */
if (arg_network_namespace_path) {
r = namespace_enter(-1, -1, netns_fd, -1, -1);

View File

@ -627,8 +627,7 @@ static void dns_server_hash_func(const DnsServer *s, struct siphash *state) {
siphash24_compress(&s->address, FAMILY_ADDRESS_SIZE(s->family), state);
siphash24_compress(&s->port, sizeof(s->port), state);
siphash24_compress(&s->ifindex, sizeof(s->ifindex), state);
if (s->server_name)
siphash24_compress(s->server_name, strlen(s->server_name), state);
siphash24_compress_string(s->server_name, state);
}
static int dns_server_compare_func(const DnsServer *x, const DnsServer *y) {

View File

@ -7,6 +7,8 @@
#include "strv.h"
static void test_set_steal_first(void) {
log_info("/* %s */", __func__);
_cleanup_ordered_set_free_ OrderedSet *m = NULL;
int seen[3] = {};
char *val;
@ -42,12 +44,18 @@ DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(item_hash_ops, void, trivial_hash_
static void test_set_free_with_hash_ops(void) {
OrderedSet *m;
struct Item items[4] = {};
unsigned i;
log_info("/* %s */", __func__);
assert_se(m = ordered_set_new(&item_hash_ops));
for (i = 0; i < ELEMENTSOF(items) - 1; i++)
for (size_t i = 0; i < ELEMENTSOF(items) - 1; i++)
assert_se(ordered_set_put(m, items + i) == 1);
for (size_t i = 0; i < ELEMENTSOF(items) - 1; i++)
assert_se(ordered_set_put(m, items + i) == 0); /* We get 0 here, because we use trivial hash
* ops. Also see below... */
m = ordered_set_free(m);
assert_se(items[0].seen == 1);
assert_se(items[1].seen == 1);
@ -57,7 +65,9 @@ static void test_set_free_with_hash_ops(void) {
static void test_set_put(void) {
_cleanup_ordered_set_free_ OrderedSet *m = NULL;
_cleanup_free_ char **t = NULL;
_cleanup_free_ char **t = NULL, *str = NULL;
log_info("/* %s */", __func__);
m = ordered_set_new(&string_hash_ops);
assert_se(m);
@ -71,6 +81,10 @@ static void test_set_put(void) {
assert_se(ordered_set_put(m, (void*) "333") == 0);
assert_se(ordered_set_put(m, (void*) "22") == 0);
assert_se(str = strdup("333"));
assert_se(ordered_set_put(m, str) == -EEXIST); /* ... and we get -EEXIST here, because we use
* non-trivial hash ops. */
assert_se(t = ordered_set_get_strv(m));
assert_se(streq(t[0], "1"));
assert_se(streq(t[1], "22"));
@ -86,6 +100,8 @@ static void test_set_put_string_set(void) {
_cleanup_free_ char **final = NULL; /* "just free" because the strings are in the set */
void *t;
log_info("/* %s */", __func__);
m = ordered_set_new(&string_hash_ops);
assert_se(m);

View File

@ -4,4 +4,6 @@ Name=veth99
[Network]
IPv6AcceptRA=true
IPv6Token=::1a:2b:3c:4d
IPv6Token=::1a:2b:3c:4d
IPv6Token=::1a:2b:3c:4d
IPv6Token=::fa:de:ca:fe

View File

@ -2592,7 +2592,9 @@ class NetworkdStateFileTests(unittest.TestCase, Utilities):
path = os.path.join('/run/systemd/netif/links/', ifindex)
self.assertTrue(os.path.exists(path))
time.sleep(2)
# make link state file updated
check_output(*resolvectl_cmd, 'revert', 'dummy98', env=env)
with open(path) as f:
data = f.read()
@ -2616,7 +2618,6 @@ class NetworkdStateFileTests(unittest.TestCase, Utilities):
check_output(*resolvectl_cmd, 'mdns', 'dummy98', 'no', env=env)
check_output(*resolvectl_cmd, 'dnssec', 'dummy98', 'yes', env=env)
check_output(*timedatectl_cmd, 'ntp-servers', 'dummy98', '2.fedora.pool.ntp.org', '3.fedora.pool.ntp.org', env=env)
time.sleep(2)
with open(path) as f:
data = f.read()
@ -2629,7 +2630,6 @@ class NetworkdStateFileTests(unittest.TestCase, Utilities):
self.assertRegex(data, r'DNSSEC=yes')
check_output(*timedatectl_cmd, 'revert', 'dummy98', env=env)
time.sleep(2)
with open(path) as f:
data = f.read()
@ -2642,7 +2642,6 @@ class NetworkdStateFileTests(unittest.TestCase, Utilities):
self.assertRegex(data, r'DNSSEC=yes')
check_output(*resolvectl_cmd, 'revert', 'dummy98', env=env)
time.sleep(2)
with open(path) as f:
data = f.read()