mirror of
https://github.com/systemd/systemd
synced 2026-03-15 01:24:51 +01:00
Compare commits
No commits in common. "c799d93cfa8d8202a05b28dc8836d5a29fa0487e" and "5c2e5957678462d871c5c2ea5261becec5f8f80f" have entirely different histories.
c799d93cfa
...
5c2e595767
@ -13,7 +13,7 @@ account sufficient pam_unix.so
|
||||
account required pam_permit.so
|
||||
|
||||
-password sufficient pam_systemd_home.so
|
||||
password sufficient pam_unix.so sha512 shadow try_first_pass use_authtok
|
||||
password sufficient pam_unix.so sha512 shadow try_first_pass try_authtok
|
||||
password required pam_deny.so
|
||||
|
||||
-session optional pam_keyinit.so revoke
|
||||
|
||||
@ -318,8 +318,7 @@ account sufficient pam_unix.so
|
||||
account required pam_permit.so
|
||||
|
||||
-password sufficient pam_systemd_home.so
|
||||
password sufficient pam_unix.so sha512 shadow try_first_pass use_authtok
|
||||
|
||||
password sufficient pam_unix.so sha512 shadow try_first_pass try_authtok
|
||||
password required pam_deny.so
|
||||
|
||||
-session optional pam_keyinit.so revoke
|
||||
|
||||
@ -139,7 +139,7 @@ account sufficient pam_unix.so
|
||||
account required pam_permit.so
|
||||
|
||||
<command>-password sufficient pam_systemd_home.so</command>
|
||||
password sufficient pam_unix.so sha512 shadow try_first_pass use_authtok
|
||||
password sufficient pam_unix.so sha512 shadow try_first_pass try_authtok
|
||||
password required pam_deny.so
|
||||
|
||||
-session optional pam_keyinit.so revoke
|
||||
|
||||
@ -775,7 +775,7 @@ BPFProgram=bind6:/sys/fs/bpf/sock-addr-hook
|
||||
|
||||
<para><replaceable>bind-rule</replaceable> := [<replaceable>address-family</replaceable><constant>:</constant>]<replaceable>ip-ports</replaceable></para>
|
||||
|
||||
<para><replaceable>address-family</replaceable> := { <constant>ipv4</constant> | <constant>ipv6</constant> }</para>
|
||||
<para><replaceable>address-family</replaceable> := { <constant>IPv4</constant> | <constant>IPv6</constant> }</para>
|
||||
|
||||
<para><replaceable>ip-ports</replaceable> := { <replaceable>ip-port</replaceable> | <replaceable>ip-port-range</replaceable> |
|
||||
<constant>any</constant> }</para>
|
||||
@ -812,7 +812,7 @@ BPFProgram=bind6:/sys/fs/bpf/sock-addr-hook
|
||||
<para>Examples:<programlisting>…
|
||||
# Allow binding IPv6 socket addresses with a port greater than or equal to 10000.
|
||||
[Service]
|
||||
SocketBindAllow=ipv6:10000-65535
|
||||
SocketBindAllow=IPv6:10000-65535
|
||||
SocketBindDeny=any
|
||||
…
|
||||
# Allow binding IPv4 and IPv6 socket addresses with 1234 and 4321 ports.
|
||||
@ -823,7 +823,7 @@ SocketBindDeny=any
|
||||
…
|
||||
# Deny binding IPv6 socket addresses.
|
||||
[Service]
|
||||
SocketBindDeny=ipv6:any
|
||||
SocketBindDeny=IPv6:any
|
||||
…
|
||||
# Deny binding IPv4 and IPv6 socket addresses.
|
||||
[Service]
|
||||
|
||||
@ -38,15 +38,3 @@ int af_from_name(const char *name) {
|
||||
int af_max(void) {
|
||||
return ELEMENTSOF(af_names);
|
||||
}
|
||||
|
||||
const char *af_to_ipv4_ipv6(int id) {
|
||||
/* Pretty often we want to map the address family to the typically used protocol name for IPv4 +
|
||||
* IPv6. Let's add special helpers for that. */
|
||||
return id == AF_INET ? "ipv4" :
|
||||
id == AF_INET6 ? "ipv6" : NULL;
|
||||
}
|
||||
|
||||
int af_from_ipv4_ipv6(const char *af) {
|
||||
return streq_ptr(af, "ipv4") ? AF_INET :
|
||||
streq_ptr(af, "ipv6") ? AF_INET6 : AF_UNSPEC;
|
||||
}
|
||||
|
||||
@ -22,7 +22,4 @@ static inline const char* af_to_name_short(int id) {
|
||||
return f + 3;
|
||||
}
|
||||
|
||||
const char* af_to_ipv4_ipv6(int id);
|
||||
int af_from_ipv4_ipv6(const char *af);
|
||||
|
||||
int af_max(void);
|
||||
|
||||
@ -5,10 +5,6 @@
|
||||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "fd-util.h"
|
||||
|
||||
#define CREDENTIAL_NAME_MAX FDNAME_MAX
|
||||
|
||||
bool credential_name_valid(const char *s);
|
||||
|
||||
int get_credentials_dir(const char **ret);
|
||||
|
||||
@ -454,7 +454,7 @@ bool fdname_is_valid(const char *s) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return p - s <= FDNAME_MAX;
|
||||
return p - s < 256;
|
||||
}
|
||||
|
||||
int fd_get_path(int fd, char **ret) {
|
||||
|
||||
@ -8,9 +8,6 @@
|
||||
|
||||
#include "macro.h"
|
||||
|
||||
/* maximum length of fdname */
|
||||
#define FDNAME_MAX 255
|
||||
|
||||
/* Make sure we can distinguish fd 0 and NULL */
|
||||
#define FD_TO_PTR(fd) INT_TO_PTR((fd)+1)
|
||||
#define PTR_TO_FD(p) (PTR_TO_INT(p)-1)
|
||||
|
||||
@ -371,26 +371,28 @@ static inline void *ordered_hashmap_first_key(OrderedHashmap *h) {
|
||||
return _hashmap_first_key(HASHMAP_BASE(h), false);
|
||||
}
|
||||
|
||||
#define hashmap_clear_with_destructor(h, f) \
|
||||
#define hashmap_clear_with_destructor(_s, _f) \
|
||||
({ \
|
||||
Hashmap *_h = (h); \
|
||||
void *_item; \
|
||||
while ((_item = hashmap_steal_first(_h))) \
|
||||
f(_item); \
|
||||
_h; \
|
||||
while ((_item = hashmap_steal_first(_s))) \
|
||||
_f(_item); \
|
||||
})
|
||||
#define hashmap_free_with_destructor(h, f) \
|
||||
hashmap_free(hashmap_clear_with_destructor(h, f))
|
||||
#define ordered_hashmap_clear_with_destructor(h, f) \
|
||||
#define hashmap_free_with_destructor(_s, _f) \
|
||||
({ \
|
||||
OrderedHashmap *_h = (h); \
|
||||
void *_item; \
|
||||
while ((_item = ordered_hashmap_steal_first(_h))) \
|
||||
f(_item); \
|
||||
_h; \
|
||||
hashmap_clear_with_destructor(_s, _f); \
|
||||
hashmap_free(_s); \
|
||||
})
|
||||
#define ordered_hashmap_clear_with_destructor(_s, _f) \
|
||||
({ \
|
||||
void *_item; \
|
||||
while ((_item = ordered_hashmap_steal_first(_s))) \
|
||||
_f(_item); \
|
||||
})
|
||||
#define ordered_hashmap_free_with_destructor(_s, _f) \
|
||||
({ \
|
||||
ordered_hashmap_clear_with_destructor(_s, _f); \
|
||||
ordered_hashmap_free(_s); \
|
||||
})
|
||||
#define ordered_hashmap_free_with_destructor(h, f) \
|
||||
ordered_hashmap_free(ordered_hashmap_clear_with_destructor(h, f))
|
||||
|
||||
/* no hashmap_next */
|
||||
void* ordered_hashmap_next(OrderedHashmap *h, const void *key);
|
||||
|
||||
@ -73,13 +73,7 @@ int in_addr_prefix_range(
|
||||
union in_addr_union *ret_start,
|
||||
union in_addr_union *ret_end);
|
||||
int in_addr_to_string(int family, const union in_addr_union *u, char **ret);
|
||||
static inline int in6_addr_to_string(const struct in6_addr *u, char **ret) {
|
||||
return in_addr_to_string(AF_INET6, (const union in_addr_union*) u, ret);
|
||||
}
|
||||
int in_addr_prefix_to_string(int family, const union in_addr_union *u, unsigned prefixlen, char **ret);
|
||||
static inline int in6_addr_prefix_to_string(const struct in6_addr *u, unsigned prefixlen, char **ret) {
|
||||
return in_addr_prefix_to_string(AF_INET6, (const union in_addr_union*) u, prefixlen, ret);
|
||||
}
|
||||
int in_addr_port_ifindex_name_to_string(int family, const union in_addr_union *u, uint16_t port, int ifindex, const char *server_name, char **ret);
|
||||
static inline int in_addr_ifindex_to_string(int family, const union in_addr_union *u, int ifindex, char **ret) {
|
||||
return in_addr_port_ifindex_name_to_string(family, u, 0, ifindex, NULL, ret);
|
||||
@ -126,10 +120,3 @@ extern const struct hash_ops in_addr_data_hash_ops;
|
||||
extern const struct hash_ops in_addr_prefix_hash_ops;
|
||||
extern const struct hash_ops in_addr_prefix_hash_ops_free;
|
||||
extern const struct hash_ops in6_addr_hash_ops;
|
||||
|
||||
#define IPV4_ADDRESS_FMT_STR "%u.%u.%u.%u"
|
||||
#define IPV4_ADDRESS_FMT_VAL(address) \
|
||||
be32toh((address).s_addr) >> 24, \
|
||||
(be32toh((address).s_addr) >> 16) & 0xFFu, \
|
||||
(be32toh((address).s_addr) >> 8) & 0xFFu, \
|
||||
be32toh((address).s_addr) & 0xFFu
|
||||
|
||||
@ -75,17 +75,6 @@ void ordered_set_print(FILE *f, const char *field, OrderedSet *s);
|
||||
#define ORDERED_SET_FOREACH(e, s) \
|
||||
_ORDERED_SET_FOREACH(e, s, UNIQ_T(i, UNIQ))
|
||||
|
||||
#define ordered_set_clear_with_destructor(s, f) \
|
||||
({ \
|
||||
OrderedSet *_s = (s); \
|
||||
void *_item; \
|
||||
while ((_item = ordered_set_steal_first(_s))) \
|
||||
f(_item); \
|
||||
_s; \
|
||||
})
|
||||
#define ordered_set_free_with_destructor(s, f) \
|
||||
ordered_set_free(ordered_set_clear_with_destructor(s, f))
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedSet*, ordered_set_free);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(OrderedSet*, ordered_set_free_free);
|
||||
|
||||
|
||||
@ -95,16 +95,17 @@ static inline void *set_steal_first(Set *s) {
|
||||
return _hashmap_first_key_and_value(HASHMAP_BASE(s), true, NULL);
|
||||
}
|
||||
|
||||
#define set_clear_with_destructor(s, f) \
|
||||
#define set_clear_with_destructor(_s, _f) \
|
||||
({ \
|
||||
Set *_s = (s); \
|
||||
void *_item; \
|
||||
while ((_item = set_steal_first(_s))) \
|
||||
f(_item); \
|
||||
_s; \
|
||||
_f(_item); \
|
||||
})
|
||||
#define set_free_with_destructor(_s, _f) \
|
||||
({ \
|
||||
set_clear_with_destructor(_s, _f); \
|
||||
set_free(_s); \
|
||||
})
|
||||
#define set_free_with_destructor(s, f) \
|
||||
set_free(set_clear_with_destructor(s, f))
|
||||
|
||||
/* no set_steal_first_key */
|
||||
/* no set_first_key */
|
||||
|
||||
@ -224,7 +224,6 @@ if have_gnu_efi
|
||||
'-Bsymbolic',
|
||||
'-nostdlib',
|
||||
'-znocombreloc',
|
||||
'--build-id=sha1',
|
||||
'-L', efi_libdir,
|
||||
efi_crt0]
|
||||
if ['aarch64', 'arm', 'riscv64'].contains(efi_arch)
|
||||
@ -255,22 +254,24 @@ if have_gnu_efi
|
||||
|
||||
libgcc_file_name = run_command(efi_cc + ['-print-libgcc-file-name']).stdout().strip()
|
||||
systemd_boot_efi_name = 'systemd-boot@0@.efi'.format(EFI_MACHINE_TYPE_NAME)
|
||||
stub_elf_name = 'linux@0@.elf.stub'.format(EFI_MACHINE_TYPE_NAME)
|
||||
stub_efi_name = 'linux@0@.efi.stub'.format(EFI_MACHINE_TYPE_NAME)
|
||||
no_undefined_symbols = find_program('no-undefined-symbols.sh')
|
||||
|
||||
efi_stubs = []
|
||||
foreach tuple : [['systemd_boot.so', systemd_boot_efi_name, systemd_boot_objects, false],
|
||||
[stub_elf_name, stub_efi_name, stub_objects, true]]
|
||||
foreach tuple : [['systemd_boot.so', systemd_boot_efi_name, systemd_boot_objects],
|
||||
['stub.so', stub_efi_name, stub_objects]]
|
||||
so = custom_target(
|
||||
tuple[0],
|
||||
input : tuple[2],
|
||||
output : tuple[0],
|
||||
command : [efi_ld, '-o', '@OUTPUT@',
|
||||
efi_ldflags, tuple[2],
|
||||
'-lefi', '-lgnuefi', libgcc_file_name],
|
||||
install : tuple[3],
|
||||
install_dir : bootlibdir)
|
||||
command : [efi_ld, '-o', '@OUTPUT@'] +
|
||||
efi_ldflags + tuple[2] +
|
||||
['-lefi', '-lgnuefi', libgcc_file_name])
|
||||
|
||||
if want_tests != 'false'
|
||||
test('no-undefined-symbols-' + tuple[0],
|
||||
no_undefined_symbols,
|
||||
args : [so])
|
||||
endif
|
||||
|
||||
stub = custom_target(
|
||||
tuple[1],
|
||||
@ -283,26 +284,22 @@ if have_gnu_efi
|
||||
'-j', '.data',
|
||||
'-j', '.dynamic',
|
||||
'-j', '.dynsym',
|
||||
'-j', '.rel*',
|
||||
efi_format,
|
||||
'@INPUT@', '@OUTPUT@'],
|
||||
'-j', '.rel*']
|
||||
+ efi_format +
|
||||
['@INPUT@', '@OUTPUT@'],
|
||||
install : true,
|
||||
install_dir : bootlibdir)
|
||||
|
||||
efi_stubs += [[so, stub]]
|
||||
|
||||
if want_tests != 'false'
|
||||
test('no-undefined-symbols-' + tuple[0],
|
||||
no_undefined_symbols,
|
||||
args : so)
|
||||
endif
|
||||
set_variable(tuple[0].underscorify(), so)
|
||||
set_variable(tuple[0].underscorify() + '_stub', stub)
|
||||
endforeach
|
||||
|
||||
############################################################
|
||||
|
||||
test_efi_disk_img = custom_target(
|
||||
'test-efi-disk.img',
|
||||
input : [efi_stubs[0][0], efi_stubs[1][1]],
|
||||
input : [systemd_boot_so, stub_so_stub],
|
||||
output : 'test-efi-disk.img',
|
||||
command : [test_efi_create_disk_sh, '@OUTPUT@','@INPUT@', splash_bmp])
|
||||
command : [test_efi_create_disk_sh, '@OUTPUT@',
|
||||
'@INPUT0@', '@INPUT1@', splash_bmp])
|
||||
endif
|
||||
|
||||
@ -4,7 +4,6 @@
|
||||
|
||||
#include "sd-messages.h"
|
||||
|
||||
#include "af-list.h"
|
||||
#include "alloc-util.h"
|
||||
#include "blockdev-util.h"
|
||||
#include "bpf-devices.h"
|
||||
@ -203,10 +202,12 @@ void cgroup_context_remove_bpf_foreign_program(CGroupContext *c, CGroupBPFForeig
|
||||
}
|
||||
|
||||
void cgroup_context_remove_socket_bind(CGroupSocketBindItem **head) {
|
||||
CGroupSocketBindItem *h;
|
||||
|
||||
assert(head);
|
||||
|
||||
while (*head) {
|
||||
CGroupSocketBindItem *h = *head;
|
||||
h = *head;
|
||||
LIST_REMOVE(socket_bind_items, *head, h);
|
||||
free(h);
|
||||
}
|
||||
@ -593,18 +594,16 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
|
||||
}
|
||||
|
||||
void cgroup_context_dump_socket_bind_item(const CGroupSocketBindItem *item, FILE *f) {
|
||||
const char *family, *colon;
|
||||
|
||||
family = strempty(af_to_ipv4_ipv6(item->address_family));
|
||||
colon = isempty(family) ? "" : ":";
|
||||
const char *family = item->address_family == AF_INET ? "IPv4:" :
|
||||
item->address_family == AF_INET6 ? "IPv6:" : "";
|
||||
|
||||
if (item->nr_ports == 0)
|
||||
fprintf(f, " %s%sany", family, colon);
|
||||
fprintf(f, " %sany", family);
|
||||
else if (item->nr_ports == 1)
|
||||
fprintf(f, " %s%s%" PRIu16, family, colon, item->port_min);
|
||||
fprintf(f, " %s%" PRIu16, family, item->port_min);
|
||||
else {
|
||||
uint16_t port_max = item->port_min + item->nr_ports - 1;
|
||||
fprintf(f, " %s%s%" PRIu16 "-%" PRIu16, family, colon, item->port_min, port_max);
|
||||
fprintf(f, " %s%" PRIu16 "-%" PRIu16, family, item->port_min, port_max);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1581,7 +1580,7 @@ static bool unit_get_needs_socket_bind(Unit *u) {
|
||||
if (!c)
|
||||
return false;
|
||||
|
||||
return c->socket_bind_allow || c->socket_bind_deny;
|
||||
return c->socket_bind_allow != NULL || c->socket_bind_deny != NULL;
|
||||
}
|
||||
|
||||
static CGroupMask unit_get_cgroup_mask(Unit *u) {
|
||||
|
||||
@ -475,11 +475,8 @@ int manager_varlink_init(Manager *m) {
|
||||
void manager_varlink_done(Manager *m) {
|
||||
assert(m);
|
||||
|
||||
/* Explicitly close the varlink connection to oomd. Note we first take the varlink connection out of
|
||||
* the manager, and only then disconnect it — in two steps – so that we don't end up accidentally
|
||||
* unreffing it twice. After all, closing the connection might cause the disconnect handler we
|
||||
* installed (vl_disconnect() above) to be called, where we will unref it too. */
|
||||
varlink_close_unref(TAKE_PTR(m->managed_oom_varlink_request));
|
||||
/* Send the final message if we still have a subscribe request open. */
|
||||
m->managed_oom_varlink_request = varlink_close_unref(m->managed_oom_varlink_request);
|
||||
|
||||
m->varlink_server = varlink_server_unref(m->varlink_server);
|
||||
}
|
||||
|
||||
@ -293,7 +293,15 @@ int config_parse_unit_path_printf(
|
||||
assert(rvalue);
|
||||
assert(u);
|
||||
|
||||
r = unit_path_printf(u, rvalue, &k);
|
||||
/* Let's not bother with anything that is too long */
|
||||
if (strlen(rvalue) >= PATH_MAX) {
|
||||
log_syntax(unit, fatal ? LOG_ERR : LOG_WARNING, filename, line, 0,
|
||||
"%s value too long%s.",
|
||||
lvalue, fatal ? "" : ", ignoring");
|
||||
return fatal ? -ENAMETOOLONG : 0;
|
||||
}
|
||||
|
||||
r = unit_full_printf(u, rvalue, &k);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, fatal ? LOG_ERR : LOG_WARNING, filename, line, r,
|
||||
"Failed to resolve unit specifiers in '%s'%s: %m",
|
||||
@ -344,7 +352,7 @@ int config_parse_unit_path_strv_printf(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = unit_path_printf(u, word, &k);
|
||||
r = unit_full_printf(u, word, &k);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to resolve unit specifiers in '%s', ignoring: %m", word);
|
||||
@ -425,7 +433,7 @@ int config_parse_socket_listen(
|
||||
if (ltype != SOCKET_SOCKET) {
|
||||
_cleanup_free_ char *k = NULL;
|
||||
|
||||
r = unit_path_printf(UNIT(s), rvalue, &k);
|
||||
r = unit_full_printf(UNIT(s), rvalue, &k);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to resolve unit specifiers in '%s', ignoring: %m", rvalue);
|
||||
return 0;
|
||||
@ -447,7 +455,7 @@ int config_parse_socket_listen(
|
||||
} else if (streq(lvalue, "ListenNetlink")) {
|
||||
_cleanup_free_ char *k = NULL;
|
||||
|
||||
r = unit_path_printf(UNIT(s), rvalue, &k);
|
||||
r = unit_full_printf(UNIT(s), rvalue, &k);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to resolve unit specifiers in '%s', ignoring: %m", rvalue);
|
||||
return 0;
|
||||
@ -464,7 +472,7 @@ int config_parse_socket_listen(
|
||||
} else {
|
||||
_cleanup_free_ char *k = NULL;
|
||||
|
||||
r = unit_path_printf(UNIT(s), rvalue, &k);
|
||||
r = unit_full_printf(UNIT(s), rvalue, &k);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to resolve unit specifiers in '%s', ignoring: %m", rvalue);
|
||||
return 0;
|
||||
@ -761,7 +769,7 @@ int config_parse_exec(
|
||||
f++;
|
||||
}
|
||||
|
||||
r = unit_path_printf(u, f, &path);
|
||||
r = unit_full_printf(u, f, &path);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, ignore ? LOG_WARNING : LOG_ERR, filename, line, r,
|
||||
"Failed to resolve unit specifiers in '%s'%s: %m",
|
||||
@ -848,7 +856,7 @@ int config_parse_exec(
|
||||
if (r < 0)
|
||||
return ignore ? 0 : -ENOEXEC;
|
||||
|
||||
r = unit_path_printf(u, word, &resolved);
|
||||
r = unit_full_printf(u, word, &resolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, ignore ? LOG_WARNING : LOG_ERR, filename, line, r,
|
||||
"Failed to resolve unit specifiers in %s%s: %m",
|
||||
@ -948,7 +956,7 @@ int config_parse_exec_input(
|
||||
if (n) {
|
||||
_cleanup_free_ char *resolved = NULL;
|
||||
|
||||
r = unit_fd_printf(u, n, &resolved);
|
||||
r = unit_full_printf(u, n, &resolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to resolve unit specifiers in '%s', ignoring: %m", n);
|
||||
return 0;
|
||||
@ -968,7 +976,7 @@ int config_parse_exec_input(
|
||||
} else if ((n = startswith(rvalue, "file:"))) {
|
||||
_cleanup_free_ char *resolved = NULL;
|
||||
|
||||
r = unit_path_printf(u, n, &resolved);
|
||||
r = unit_full_printf(u, n, &resolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to resolve unit specifiers in '%s', ignoring: %m", n);
|
||||
return 0;
|
||||
@ -1032,7 +1040,7 @@ int config_parse_exec_input_text(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = unit_full_printf_full(u, unescaped, EXEC_STDIN_DATA_MAX, &resolved);
|
||||
r = unit_full_printf(u, unescaped, &resolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to resolve unit specifiers in '%s', ignoring: %m", unescaped);
|
||||
@ -1147,7 +1155,7 @@ int config_parse_exec_output(
|
||||
|
||||
n = startswith(rvalue, "fd:");
|
||||
if (n) {
|
||||
r = unit_fd_printf(u, n, &resolved);
|
||||
r = unit_full_printf(u, n, &resolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to resolve unit specifiers in %s: %m", n);
|
||||
return 0;
|
||||
@ -1172,7 +1180,7 @@ int config_parse_exec_output(
|
||||
|
||||
} else if ((n = startswith(rvalue, "file:"))) {
|
||||
|
||||
r = unit_path_printf(u, n, &resolved);
|
||||
r = unit_full_printf(u, n, &resolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to resolve unit specifiers in %s, ignoring: %m", n);
|
||||
return 0;
|
||||
@ -1186,7 +1194,7 @@ int config_parse_exec_output(
|
||||
|
||||
} else if ((n = startswith(rvalue, "append:"))) {
|
||||
|
||||
r = unit_path_printf(u, n, &resolved);
|
||||
r = unit_full_printf(u, n, &resolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to resolve unit specifiers in %s, ignoring: %m", n);
|
||||
return 0;
|
||||
@ -1200,7 +1208,7 @@ int config_parse_exec_output(
|
||||
|
||||
} else if ((n = startswith(rvalue, "truncate:"))) {
|
||||
|
||||
r = unit_path_printf(u, n, &resolved);
|
||||
r = unit_full_printf(u, n, &resolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to resolve unit specifiers in %s, ignoring: %m", n);
|
||||
return 0;
|
||||
@ -2072,7 +2080,7 @@ int config_parse_path_spec(const char *unit,
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = unit_path_printf(UNIT(p), rvalue, &k);
|
||||
r = unit_full_printf(UNIT(p), rvalue, &k);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to resolve unit specifiers in %s, ignoring: %m", rvalue);
|
||||
return 0;
|
||||
@ -2167,7 +2175,7 @@ int config_parse_fdname(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = unit_fd_printf(UNIT(s), rvalue, &p);
|
||||
r = unit_full_printf(UNIT(s), rvalue, &p);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to resolve unit specifiers in '%s', ignoring: %m", rvalue);
|
||||
return 0;
|
||||
@ -2256,7 +2264,7 @@ int config_parse_bus_name(
|
||||
assert(rvalue);
|
||||
assert(u);
|
||||
|
||||
r = unit_full_printf_full(u, rvalue, SD_BUS_MAXIMUM_NAME_LENGTH, &k);
|
||||
r = unit_full_printf(u, rvalue, &k);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to resolve unit specifiers in %s, ignoring: %m", rvalue);
|
||||
return 0;
|
||||
@ -2549,7 +2557,7 @@ int config_parse_working_directory(
|
||||
} else {
|
||||
_cleanup_free_ char *k = NULL;
|
||||
|
||||
r = unit_path_printf(u, rvalue, &k);
|
||||
r = unit_full_printf(u, rvalue, &k);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, missing_ok ? LOG_WARNING : LOG_ERR, filename, line, r,
|
||||
"Failed to resolve unit specifiers in working directory path '%s'%s: %m",
|
||||
@ -2596,7 +2604,7 @@ int config_parse_unit_env_file(const char *unit,
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = unit_full_printf_full(u, rvalue, PATH_MAX, &n);
|
||||
r = unit_full_printf(u, rvalue, &n);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to resolve unit specifiers in '%s', ignoring: %m", rvalue);
|
||||
return 0;
|
||||
@ -2657,7 +2665,7 @@ int config_parse_environ(
|
||||
return 0;
|
||||
|
||||
if (u) {
|
||||
r = unit_env_printf(u, word, &resolved);
|
||||
r = unit_full_printf(u, word, &resolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to resolve unit specifiers in %s, ignoring: %m", word);
|
||||
@ -2722,7 +2730,7 @@ int config_parse_pass_environ(
|
||||
break;
|
||||
|
||||
if (u) {
|
||||
r = unit_env_printf(u, word, &k);
|
||||
r = unit_full_printf(u, word, &k);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to resolve specifiers in %s, ignoring: %m", word);
|
||||
@ -2797,7 +2805,7 @@ int config_parse_unset_environ(
|
||||
break;
|
||||
|
||||
if (u) {
|
||||
r = unit_env_printf(u, word, &k);
|
||||
r = unit_full_printf(u, word, &k);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to resolve unit specifiers in %s, ignoring: %m", word);
|
||||
@ -2924,7 +2932,7 @@ int config_parse_log_namespace(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = unit_full_printf_full(u, rvalue, NAME_MAX, &k);
|
||||
r = unit_full_printf(u, rvalue, &k);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to resolve unit specifiers in %s, ignoring: %m", rvalue);
|
||||
return 0;
|
||||
@ -2977,7 +2985,7 @@ int config_parse_unit_condition_path(
|
||||
if (negate)
|
||||
rvalue++;
|
||||
|
||||
r = unit_path_printf(u, rvalue, &p);
|
||||
r = unit_full_printf(u, rvalue, &p);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to resolve unit specifiers in %s, ignoring: %m", rvalue);
|
||||
return 0;
|
||||
@ -3082,7 +3090,7 @@ int config_parse_unit_requires_mounts_for(
|
||||
if (r == 0)
|
||||
return 0;
|
||||
|
||||
r = unit_path_printf(u, word, &resolved);
|
||||
r = unit_full_printf(u, word, &resolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to resolve unit specifiers in '%s', ignoring: %m", word);
|
||||
continue;
|
||||
@ -3952,7 +3960,7 @@ int config_parse_device_allow(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = unit_path_printf(userdata, path, &resolved);
|
||||
r = unit_full_printf(userdata, path, &resolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to resolve unit specifiers in '%s', ignoring: %m", path);
|
||||
@ -4018,7 +4026,7 @@ int config_parse_io_device_weight(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = unit_path_printf(userdata, path, &resolved);
|
||||
r = unit_full_printf(userdata, path, &resolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to resolve unit specifiers in '%s', ignoring: %m", path);
|
||||
@ -4087,7 +4095,7 @@ int config_parse_io_device_latency(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = unit_path_printf(userdata, path, &resolved);
|
||||
r = unit_full_printf(userdata, path, &resolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to resolve unit specifiers in '%s', ignoring: %m", path);
|
||||
@ -4157,7 +4165,7 @@ int config_parse_io_limit(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = unit_path_printf(userdata, path, &resolved);
|
||||
r = unit_full_printf(userdata, path, &resolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to resolve unit specifiers in '%s', ignoring: %m", path);
|
||||
@ -4243,7 +4251,7 @@ int config_parse_blockio_device_weight(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = unit_path_printf(userdata, path, &resolved);
|
||||
r = unit_full_printf(userdata, path, &resolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to resolve unit specifiers in '%s', ignoring: %m", path);
|
||||
@ -4316,7 +4324,7 @@ int config_parse_blockio_bandwidth(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = unit_path_printf(userdata, path, &resolved);
|
||||
r = unit_full_printf(userdata, path, &resolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to resolve unit specifiers in '%s', ignoring: %m", path);
|
||||
@ -4432,7 +4440,7 @@ int config_parse_exec_directories(
|
||||
if (r == 0)
|
||||
return 0;
|
||||
|
||||
r = unit_path_printf(u, word, &k);
|
||||
r = unit_full_printf(u, word, &k);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to resolve unit specifiers in \"%s\", ignoring: %m", word);
|
||||
@ -4495,7 +4503,7 @@ int config_parse_set_credential(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = unit_cred_printf(u, word, &k);
|
||||
r = unit_full_printf(u, word, &k);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to resolve unit specifiers in \"%s\", ignoring: %m", word);
|
||||
return 0;
|
||||
@ -4580,7 +4588,7 @@ int config_parse_load_credential(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = unit_cred_printf(u, word, &k);
|
||||
r = unit_full_printf(u, word, &k);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to resolve unit specifiers in \"%s\", ignoring: %m", word);
|
||||
return 0;
|
||||
@ -4597,7 +4605,7 @@ int config_parse_load_credential(
|
||||
if (!q)
|
||||
return log_oom();
|
||||
} else {
|
||||
r = unit_path_printf(u, p, &q);
|
||||
r = unit_full_printf(u, p, &q);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to resolve unit specifiers in \"%s\", ignoring: %m", p);
|
||||
return 0;
|
||||
@ -4732,7 +4740,7 @@ int config_parse_namespace_path_strv(
|
||||
w++;
|
||||
}
|
||||
|
||||
r = unit_path_printf(u, w, &resolved);
|
||||
r = unit_full_printf(u, w, &resolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to resolve unit specifiers in %s: %m", w);
|
||||
continue;
|
||||
@ -4812,7 +4820,7 @@ int config_parse_temporary_filesystems(
|
||||
continue;
|
||||
}
|
||||
|
||||
r = unit_path_printf(u, path, &resolved);
|
||||
r = unit_full_printf(u, path, &resolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to resolve unit specifiers in %s, ignoring: %m", path);
|
||||
continue;
|
||||
@ -4873,7 +4881,7 @@ int config_parse_bind_paths(
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
r = unit_full_printf_full(u, source, PATH_MAX, &sresolved);
|
||||
r = unit_full_printf(u, source, &sresolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to resolve unit specifiers in \"%s\", ignoring: %m", source);
|
||||
@ -4904,7 +4912,7 @@ int config_parse_bind_paths(
|
||||
continue;
|
||||
}
|
||||
|
||||
r = unit_path_printf(u, destination, &dresolved);
|
||||
r = unit_full_printf(u, destination, &dresolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to resolve specifiers in \"%s\", ignoring: %m", destination);
|
||||
@ -5020,7 +5028,7 @@ int config_parse_mount_images(
|
||||
s++;
|
||||
}
|
||||
|
||||
r = unit_path_printf(u, s, &sresolved);
|
||||
r = unit_full_printf(u, s, &sresolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to resolve unit specifiers in \"%s\", ignoring: %m", s);
|
||||
@ -5036,7 +5044,7 @@ int config_parse_mount_images(
|
||||
continue;
|
||||
}
|
||||
|
||||
r = unit_path_printf(u, second, &dresolved);
|
||||
r = unit_full_printf(u, second, &dresolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to resolve specifiers in \"%s\", ignoring: %m", second);
|
||||
@ -5179,7 +5187,7 @@ int config_parse_extension_images(
|
||||
s++;
|
||||
}
|
||||
|
||||
r = unit_path_printf(u, s, &sresolved);
|
||||
r = unit_full_printf(u, s, &sresolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to resolve unit specifiers in \"%s\", ignoring: %m", s);
|
||||
@ -5408,7 +5416,7 @@ int config_parse_pid_file(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = unit_path_printf(u, rvalue, &k);
|
||||
r = unit_full_printf(u, rvalue, &k);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to resolve unit specifiers in '%s', ignoring: %m", rvalue);
|
||||
return 0;
|
||||
@ -5529,7 +5537,7 @@ int config_parse_ip_filter_bpf_progs(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = unit_path_printf(u, rvalue, &resolved);
|
||||
r = unit_full_printf(u, rvalue, &resolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to resolve unit specifiers in '%s', ignoring: %m", rvalue);
|
||||
return 0;
|
||||
@ -5603,7 +5611,7 @@ int config_parse_bpf_foreign_program(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = unit_path_printf(u, rvalue, &resolved);
|
||||
r = unit_full_printf(u, rvalue, &resolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to resolve unit specifiers in '%s', ignoring: %m", rvalue);
|
||||
return 0;
|
||||
@ -5653,10 +5661,13 @@ int config_parse_cgroup_socket_bind(
|
||||
}
|
||||
|
||||
if (rvalue) {
|
||||
af = af_from_ipv4_ipv6(word);
|
||||
if (af == AF_UNSPEC) {
|
||||
if (streq(word, "IPv4"))
|
||||
af = AF_INET;
|
||||
else if (streq(word, "IPv6"))
|
||||
af = AF_INET6;
|
||||
else {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"Only \"ipv4\" and \"ipv6\" protocols are supported, ignoring.");
|
||||
"Only IPv4 and IPv6 protocols are supported, ignoring.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -201,10 +201,10 @@ int unit_name_printf(const Unit *u, const char* format, char **ret) {
|
||||
assert(format);
|
||||
assert(ret);
|
||||
|
||||
return specifier_printf(format, UNIT_NAME_MAX, table, u, ret);
|
||||
return specifier_printf(format, table, u, ret);
|
||||
}
|
||||
|
||||
int unit_full_printf_full(const Unit *u, const char *format, size_t max_length, char **ret) {
|
||||
int unit_full_printf(const Unit *u, const char *format, char **ret) {
|
||||
/* This is similar to unit_name_printf() but also supports unescaping. Also, adds a couple of additional codes
|
||||
* (which are likely not suitable for unescaped inclusion in unit names):
|
||||
*
|
||||
@ -265,5 +265,5 @@ int unit_full_printf_full(const Unit *u, const char *format, size_t max_length,
|
||||
{}
|
||||
};
|
||||
|
||||
return specifier_printf(format, max_length, table, u, ret);
|
||||
return specifier_printf(format, table, u, ret);
|
||||
}
|
||||
|
||||
@ -1,26 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "creds-util.h"
|
||||
#include "env-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
#include "unit.h"
|
||||
|
||||
int unit_name_printf(const Unit *u, const char* text, char **ret);
|
||||
int unit_full_printf_full(const Unit *u, const char *text, size_t max_length, char **ret);
|
||||
static inline int unit_full_printf(const Unit *u, const char *text, char **ret) {
|
||||
return unit_full_printf_full(u, text, LONG_LINE_MAX, ret);
|
||||
}
|
||||
static inline int unit_path_printf(const Unit *u, const char *text, char **ret) {
|
||||
return unit_full_printf_full(u, text, PATH_MAX-1, ret);
|
||||
}
|
||||
static inline int unit_fd_printf(const Unit *u, const char *text, char **ret) {
|
||||
return unit_full_printf_full(u, text, FDNAME_MAX, ret);
|
||||
}
|
||||
static inline int unit_cred_printf(const Unit *u, const char *text, char **ret) {
|
||||
return unit_full_printf_full(u, text, CREDENTIAL_NAME_MAX, ret);
|
||||
}
|
||||
static inline int unit_env_printf(const Unit *u, const char *text, char **ret) {
|
||||
return unit_full_printf_full(u, text, sc_arg_max(), ret);
|
||||
}
|
||||
int unit_full_printf(const Unit *u, const char *text, char **ret);
|
||||
|
||||
@ -8,7 +8,6 @@
|
||||
|
||||
#include "sd-daemon.h"
|
||||
|
||||
#include "af-list.h"
|
||||
#include "alloc-util.h"
|
||||
#include "def.h"
|
||||
#include "errno-util.h"
|
||||
@ -499,7 +498,7 @@ static int accept_connection(
|
||||
|
||||
log_debug("Accepted %s %s connection from %s",
|
||||
type,
|
||||
af_to_ipv4_ipv6(socket_address_family(addr)),
|
||||
socket_address_family(addr) == AF_INET ? "IP" : "IPv6",
|
||||
a);
|
||||
|
||||
*hostname = b;
|
||||
|
||||
@ -27,5 +27,5 @@ int deserialize_dhcp_routes(struct sd_dhcp_route **ret, size_t *ret_size, size_t
|
||||
/* It is not necessary to add deserialize_dhcp_option(). Use unhexmem() instead. */
|
||||
int serialize_dhcp_option(FILE *f, const char *key, const void *data, size_t size);
|
||||
|
||||
int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file);
|
||||
int dhcp_lease_save(const sd_dhcp_lease *lease, const char *lease_file);
|
||||
int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file);
|
||||
|
||||
@ -2052,7 +2052,7 @@ int sd_dhcp_client_send_renew(sd_dhcp_client *client) {
|
||||
return client_initialize_time_events(client);
|
||||
}
|
||||
|
||||
int sd_dhcp_client_is_running(sd_dhcp_client *client) {
|
||||
int sd_dhcp_client_is_running(const sd_dhcp_client *client) {
|
||||
if (!client)
|
||||
return 0;
|
||||
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
#include "tmpfile-util.h"
|
||||
#include "unaligned.h"
|
||||
|
||||
int sd_dhcp_lease_get_address(sd_dhcp_lease *lease, struct in_addr *addr) {
|
||||
int sd_dhcp_lease_get_address(const sd_dhcp_lease *lease, struct in_addr *addr) {
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(addr, -EINVAL);
|
||||
|
||||
@ -42,7 +42,7 @@ int sd_dhcp_lease_get_address(sd_dhcp_lease *lease, struct in_addr *addr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_dhcp_lease_get_broadcast(sd_dhcp_lease *lease, struct in_addr *addr) {
|
||||
int sd_dhcp_lease_get_broadcast(const sd_dhcp_lease *lease, struct in_addr *addr) {
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(addr, -EINVAL);
|
||||
|
||||
@ -53,7 +53,7 @@ int sd_dhcp_lease_get_broadcast(sd_dhcp_lease *lease, struct in_addr *addr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_dhcp_lease_get_lifetime(sd_dhcp_lease *lease, uint32_t *lifetime) {
|
||||
int sd_dhcp_lease_get_lifetime(const sd_dhcp_lease *lease, uint32_t *lifetime) {
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(lifetime, -EINVAL);
|
||||
|
||||
@ -64,7 +64,7 @@ int sd_dhcp_lease_get_lifetime(sd_dhcp_lease *lease, uint32_t *lifetime) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_dhcp_lease_get_t1(sd_dhcp_lease *lease, uint32_t *t1) {
|
||||
int sd_dhcp_lease_get_t1(const sd_dhcp_lease *lease, uint32_t *t1) {
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(t1, -EINVAL);
|
||||
|
||||
@ -75,7 +75,7 @@ int sd_dhcp_lease_get_t1(sd_dhcp_lease *lease, uint32_t *t1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_dhcp_lease_get_t2(sd_dhcp_lease *lease, uint32_t *t2) {
|
||||
int sd_dhcp_lease_get_t2(const sd_dhcp_lease *lease, uint32_t *t2) {
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(t2, -EINVAL);
|
||||
|
||||
@ -86,7 +86,7 @@ int sd_dhcp_lease_get_t2(sd_dhcp_lease *lease, uint32_t *t2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu) {
|
||||
int sd_dhcp_lease_get_mtu(const sd_dhcp_lease *lease, uint16_t *mtu) {
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(mtu, -EINVAL);
|
||||
|
||||
@ -98,7 +98,7 @@ int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu) {
|
||||
}
|
||||
|
||||
int sd_dhcp_lease_get_servers(
|
||||
sd_dhcp_lease *lease,
|
||||
const sd_dhcp_lease *lease,
|
||||
sd_dhcp_lease_server_type_t what,
|
||||
const struct in_addr **addr) {
|
||||
|
||||
@ -114,26 +114,26 @@ int sd_dhcp_lease_get_servers(
|
||||
return (int) lease->servers[what].size;
|
||||
}
|
||||
|
||||
int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr) {
|
||||
int sd_dhcp_lease_get_dns(const sd_dhcp_lease *lease, const struct in_addr **addr) {
|
||||
return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_DNS, addr);
|
||||
}
|
||||
int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr) {
|
||||
int sd_dhcp_lease_get_ntp(const sd_dhcp_lease *lease, const struct in_addr **addr) {
|
||||
return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_NTP, addr);
|
||||
}
|
||||
int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr) {
|
||||
int sd_dhcp_lease_get_sip(const sd_dhcp_lease *lease, const struct in_addr **addr) {
|
||||
return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_SIP, addr);
|
||||
}
|
||||
int sd_dhcp_lease_get_pop3(sd_dhcp_lease *lease, const struct in_addr **addr) {
|
||||
int sd_dhcp_lease_get_pop3(const sd_dhcp_lease *lease, const struct in_addr **addr) {
|
||||
return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_POP3, addr);
|
||||
}
|
||||
int sd_dhcp_lease_get_smtp(sd_dhcp_lease *lease, const struct in_addr **addr) {
|
||||
int sd_dhcp_lease_get_smtp(const sd_dhcp_lease *lease, const struct in_addr **addr) {
|
||||
return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_SMTP, addr);
|
||||
}
|
||||
int sd_dhcp_lease_get_lpr(sd_dhcp_lease *lease, const struct in_addr **addr) {
|
||||
int sd_dhcp_lease_get_lpr(const sd_dhcp_lease *lease, const struct in_addr **addr) {
|
||||
return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_LPR, addr);
|
||||
}
|
||||
|
||||
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname) {
|
||||
int sd_dhcp_lease_get_domainname(const sd_dhcp_lease *lease, const char **domainname) {
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(domainname, -EINVAL);
|
||||
|
||||
@ -144,7 +144,7 @@ int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_dhcp_lease_get_hostname(sd_dhcp_lease *lease, const char **hostname) {
|
||||
int sd_dhcp_lease_get_hostname(const sd_dhcp_lease *lease, const char **hostname) {
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(hostname, -EINVAL);
|
||||
|
||||
@ -155,7 +155,7 @@ int sd_dhcp_lease_get_hostname(sd_dhcp_lease *lease, const char **hostname) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_dhcp_lease_get_root_path(sd_dhcp_lease *lease, const char **root_path) {
|
||||
int sd_dhcp_lease_get_root_path(const sd_dhcp_lease *lease, const char **root_path) {
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(root_path, -EINVAL);
|
||||
|
||||
@ -166,7 +166,7 @@ int sd_dhcp_lease_get_root_path(sd_dhcp_lease *lease, const char **root_path) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_dhcp_lease_get_router(sd_dhcp_lease *lease, const struct in_addr **addr) {
|
||||
int sd_dhcp_lease_get_router(const sd_dhcp_lease *lease, const struct in_addr **addr) {
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(addr, -EINVAL);
|
||||
|
||||
@ -177,7 +177,7 @@ int sd_dhcp_lease_get_router(sd_dhcp_lease *lease, const struct in_addr **addr)
|
||||
return (int) lease->router_size;
|
||||
}
|
||||
|
||||
int sd_dhcp_lease_get_netmask(sd_dhcp_lease *lease, struct in_addr *addr) {
|
||||
int sd_dhcp_lease_get_netmask(const sd_dhcp_lease *lease, struct in_addr *addr) {
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(addr, -EINVAL);
|
||||
|
||||
@ -188,7 +188,7 @@ int sd_dhcp_lease_get_netmask(sd_dhcp_lease *lease, struct in_addr *addr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_dhcp_lease_get_server_identifier(sd_dhcp_lease *lease, struct in_addr *addr) {
|
||||
int sd_dhcp_lease_get_server_identifier(const sd_dhcp_lease *lease, struct in_addr *addr) {
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(addr, -EINVAL);
|
||||
|
||||
@ -199,7 +199,7 @@ int sd_dhcp_lease_get_server_identifier(sd_dhcp_lease *lease, struct in_addr *ad
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_dhcp_lease_get_next_server(sd_dhcp_lease *lease, struct in_addr *addr) {
|
||||
int sd_dhcp_lease_get_next_server(const sd_dhcp_lease *lease, struct in_addr *addr) {
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(addr, -EINVAL);
|
||||
|
||||
@ -214,7 +214,7 @@ int sd_dhcp_lease_get_next_server(sd_dhcp_lease *lease, struct in_addr *addr) {
|
||||
* The returned routes array must be freed by the caller.
|
||||
* Route objects have the same lifetime of the lease and must not be freed.
|
||||
*/
|
||||
int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, sd_dhcp_route ***routes) {
|
||||
int sd_dhcp_lease_get_routes(const sd_dhcp_lease *lease, sd_dhcp_route ***routes) {
|
||||
sd_dhcp_route **ret;
|
||||
unsigned i;
|
||||
|
||||
@ -235,7 +235,7 @@ int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, sd_dhcp_route ***routes) {
|
||||
return (int) lease->static_route_size;
|
||||
}
|
||||
|
||||
int sd_dhcp_lease_get_search_domains(sd_dhcp_lease *lease, char ***domains) {
|
||||
int sd_dhcp_lease_get_search_domains(const sd_dhcp_lease *lease, char ***domains) {
|
||||
size_t r;
|
||||
|
||||
assert_return(lease, -EINVAL);
|
||||
@ -250,7 +250,7 @@ int sd_dhcp_lease_get_search_domains(sd_dhcp_lease *lease, char ***domains) {
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, size_t *data_len) {
|
||||
int sd_dhcp_lease_get_vendor_specific(const sd_dhcp_lease *lease, const void **data, size_t *data_len) {
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(data, -EINVAL);
|
||||
assert_return(data_len, -EINVAL);
|
||||
@ -868,7 +868,7 @@ int dhcp_lease_new(sd_dhcp_lease **ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dhcp_lease_save(sd_dhcp_lease *lease, const char *lease_file) {
|
||||
int dhcp_lease_save(const sd_dhcp_lease *lease, const char *lease_file) {
|
||||
_cleanup_(unlink_and_freep) char *temp_path = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
struct sd_dhcp_raw_option *option;
|
||||
@ -1313,7 +1313,7 @@ int dhcp_lease_set_default_subnet_mask(sd_dhcp_lease *lease) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const void **client_id, size_t *client_id_len) {
|
||||
int sd_dhcp_lease_get_client_id(const sd_dhcp_lease *lease, const void **client_id, size_t *client_id_len) {
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(client_id, -EINVAL);
|
||||
assert_return(client_id_len, -EINVAL);
|
||||
@ -1348,7 +1348,7 @@ int dhcp_lease_set_client_id(sd_dhcp_lease *lease, const void *client_id, size_t
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_dhcp_lease_get_timezone(sd_dhcp_lease *lease, const char **tz) {
|
||||
int sd_dhcp_lease_get_timezone(const sd_dhcp_lease *lease, const char **tz) {
|
||||
assert_return(lease, -EINVAL);
|
||||
assert_return(tz, -EINVAL);
|
||||
|
||||
@ -1359,7 +1359,7 @@ int sd_dhcp_lease_get_timezone(sd_dhcp_lease *lease, const char **tz) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_dhcp_route_get_destination(sd_dhcp_route *route, struct in_addr *destination) {
|
||||
int sd_dhcp_route_get_destination(const sd_dhcp_route *route, struct in_addr *destination) {
|
||||
assert_return(route, -EINVAL);
|
||||
assert_return(destination, -EINVAL);
|
||||
|
||||
@ -1367,7 +1367,7 @@ int sd_dhcp_route_get_destination(sd_dhcp_route *route, struct in_addr *destinat
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_dhcp_route_get_destination_prefix_length(sd_dhcp_route *route, uint8_t *length) {
|
||||
int sd_dhcp_route_get_destination_prefix_length(const sd_dhcp_route *route, uint8_t *length) {
|
||||
assert_return(route, -EINVAL);
|
||||
assert_return(length, -EINVAL);
|
||||
|
||||
@ -1375,7 +1375,7 @@ int sd_dhcp_route_get_destination_prefix_length(sd_dhcp_route *route, uint8_t *l
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_dhcp_route_get_gateway(sd_dhcp_route *route, struct in_addr *gateway) {
|
||||
int sd_dhcp_route_get_gateway(const sd_dhcp_route *route, struct in_addr *gateway) {
|
||||
assert_return(route, -EINVAL);
|
||||
assert_return(gateway, -EINVAL);
|
||||
|
||||
@ -1383,7 +1383,7 @@ int sd_dhcp_route_get_gateway(sd_dhcp_route *route, struct in_addr *gateway) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_dhcp_route_get_option(sd_dhcp_route *route) {
|
||||
int sd_dhcp_route_get_option(const sd_dhcp_route *route) {
|
||||
assert_return(route, -EINVAL);
|
||||
|
||||
return route->option;
|
||||
|
||||
@ -12,7 +12,6 @@
|
||||
|
||||
#include "sd-bus.h"
|
||||
|
||||
#include "af-list.h"
|
||||
#include "alloc-util.h"
|
||||
#include "bus-container.h"
|
||||
#include "bus-control.h"
|
||||
@ -822,8 +821,11 @@ static int parse_tcp_address(sd_bus *b, const char **p, char **guid) {
|
||||
return -EINVAL;
|
||||
|
||||
if (family) {
|
||||
hints.ai_family = af_from_ipv4_ipv6(family);
|
||||
if (hints.ai_family == AF_UNSPEC)
|
||||
if (streq(family, "ipv4"))
|
||||
hints.ai_family = AF_INET;
|
||||
else if (streq(family, "ipv6"))
|
||||
hints.ai_family = AF_INET6;
|
||||
else
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
@ -152,7 +152,7 @@ int nlmsg_type_to_genl_family(const sd_netlink *nl, uint16_t type, sd_genl_famil
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_genl_message_get_family(sd_netlink *nl, sd_netlink_message *m, sd_genl_family_t *family) {
|
||||
int sd_genl_message_get_family(const sd_netlink *nl, const sd_netlink_message *m, sd_genl_family_t *family) {
|
||||
uint16_t type;
|
||||
int r;
|
||||
|
||||
|
||||
@ -114,7 +114,7 @@ sd_netlink_message *sd_netlink_message_unref(sd_netlink_message *m) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int sd_netlink_message_get_type(sd_netlink_message *m, uint16_t *type) {
|
||||
int sd_netlink_message_get_type(const sd_netlink_message *m, uint16_t *type) {
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(type, -EINVAL);
|
||||
|
||||
@ -132,7 +132,7 @@ int sd_netlink_message_set_flags(sd_netlink_message *m, uint16_t flags) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_netlink_message_is_broadcast(sd_netlink_message *m) {
|
||||
int sd_netlink_message_is_broadcast(const sd_netlink_message *m) {
|
||||
assert_return(m, -EINVAL);
|
||||
|
||||
return m->broadcast;
|
||||
@ -1235,14 +1235,14 @@ uint32_t rtnl_message_get_serial(sd_netlink_message *m) {
|
||||
return m->hdr->nlmsg_seq;
|
||||
}
|
||||
|
||||
int sd_netlink_message_is_error(sd_netlink_message *m) {
|
||||
int sd_netlink_message_is_error(const sd_netlink_message *m) {
|
||||
assert_return(m, 0);
|
||||
assert_return(m->hdr, 0);
|
||||
|
||||
return m->hdr->nlmsg_type == NLMSG_ERROR;
|
||||
}
|
||||
|
||||
int sd_netlink_message_get_errno(sd_netlink_message *m) {
|
||||
int sd_netlink_message_get_errno(const sd_netlink_message *m) {
|
||||
struct nlmsgerr *err;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
|
||||
@ -142,7 +142,7 @@ void *sd_netlink_slot_set_userdata(sd_netlink_slot *slot, void *userdata) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sd_netlink_slot_get_destroy_callback(sd_netlink_slot *slot, sd_netlink_destroy_t *callback) {
|
||||
int sd_netlink_slot_get_destroy_callback(const sd_netlink_slot *slot, sd_netlink_destroy_t *callback) {
|
||||
assert_return(slot, -EINVAL);
|
||||
|
||||
if (callback)
|
||||
@ -158,7 +158,7 @@ int sd_netlink_slot_set_destroy_callback(sd_netlink_slot *slot, sd_netlink_destr
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_netlink_slot_get_floating(sd_netlink_slot *slot) {
|
||||
int sd_netlink_slot_get_floating(const sd_netlink_slot *slot) {
|
||||
assert_return(slot, -EINVAL);
|
||||
|
||||
return slot->floating;
|
||||
@ -186,7 +186,7 @@ int sd_netlink_slot_set_floating(sd_netlink_slot *slot, int b) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int sd_netlink_slot_get_description(sd_netlink_slot *slot, const char **description) {
|
||||
int sd_netlink_slot_get_description(const sd_netlink_slot *slot, const char **description) {
|
||||
assert_return(slot, -EINVAL);
|
||||
|
||||
if (description)
|
||||
|
||||
@ -409,44 +409,6 @@ int rtattr_append_attribute(struct rtattr **rta, unsigned short type, const void
|
||||
return 0;
|
||||
}
|
||||
|
||||
MultipathRoute *multipath_route_free(MultipathRoute *m) {
|
||||
if (!m)
|
||||
return NULL;
|
||||
|
||||
free(m->ifname);
|
||||
|
||||
return mfree(m);
|
||||
}
|
||||
|
||||
int multipath_route_dup(const MultipathRoute *m, MultipathRoute **ret) {
|
||||
_cleanup_(multipath_route_freep) MultipathRoute *n = NULL;
|
||||
_cleanup_free_ char *ifname = NULL;
|
||||
|
||||
assert(m);
|
||||
assert(ret);
|
||||
|
||||
if (m->ifname) {
|
||||
ifname = strdup(m->ifname);
|
||||
if (!ifname)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
n = new(MultipathRoute, 1);
|
||||
if (!n)
|
||||
return -ENOMEM;
|
||||
|
||||
*n = (MultipathRoute) {
|
||||
.gateway = m->gateway,
|
||||
.weight = m->weight,
|
||||
.ifindex = m->ifindex,
|
||||
.ifname = TAKE_PTR(ifname),
|
||||
};
|
||||
|
||||
*ret = TAKE_PTR(n);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rtattr_read_nexthop(const struct rtnexthop *rtnh, size_t size, int family, OrderedSet **ret) {
|
||||
_cleanup_ordered_set_free_free_ OrderedSet *set = NULL;
|
||||
int r;
|
||||
@ -458,7 +420,7 @@ int rtattr_read_nexthop(const struct rtnexthop *rtnh, size_t size, int family, O
|
||||
return -EBADMSG;
|
||||
|
||||
for (; size >= sizeof(struct rtnexthop); ) {
|
||||
_cleanup_(multipath_route_freep) MultipathRoute *m = NULL;
|
||||
_cleanup_free_ MultipathRoute *m = NULL;
|
||||
|
||||
if (NLMSG_ALIGN(rtnh->rtnh_len) > size)
|
||||
return -EBADMSG;
|
||||
|
||||
@ -19,16 +19,10 @@ typedef struct RouteVia {
|
||||
|
||||
typedef struct MultipathRoute {
|
||||
RouteVia gateway;
|
||||
uint32_t weight;
|
||||
int ifindex;
|
||||
char *ifname;
|
||||
uint32_t weight;
|
||||
} MultipathRoute;
|
||||
|
||||
MultipathRoute *multipath_route_free(MultipathRoute *m);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(MultipathRoute*, multipath_route_free);
|
||||
|
||||
int multipath_route_dup(const MultipathRoute *m, MultipathRoute **ret);
|
||||
|
||||
int rtnl_message_new_synthetic_error(sd_netlink *rtnl, int error, uint32_t serial, sd_netlink_message **ret);
|
||||
uint32_t rtnl_message_get_serial(sd_netlink_message *m);
|
||||
void rtnl_message_seal(sd_netlink_message *m);
|
||||
|
||||
@ -81,7 +81,7 @@ int sd_rtnl_message_route_set_flags(sd_netlink_message *m, unsigned flags) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_route_get_flags(sd_netlink_message *m, unsigned *flags) {
|
||||
int sd_rtnl_message_route_get_flags(const sd_netlink_message *m, unsigned *flags) {
|
||||
struct rtmsg *rtm;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
@ -110,7 +110,7 @@ int sd_rtnl_message_route_set_table(sd_netlink_message *m, unsigned char table)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_route_get_family(sd_netlink_message *m, int *family) {
|
||||
int sd_rtnl_message_route_get_family(const sd_netlink_message *m, int *family) {
|
||||
struct rtmsg *rtm;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
@ -125,7 +125,7 @@ int sd_rtnl_message_route_get_family(sd_netlink_message *m, int *family) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_route_get_type(sd_netlink_message *m, unsigned char *type) {
|
||||
int sd_rtnl_message_route_get_type(const sd_netlink_message *m, unsigned char *type) {
|
||||
struct rtmsg *rtm;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
@ -154,7 +154,7 @@ int sd_rtnl_message_route_set_type(sd_netlink_message *m, unsigned char type) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_route_get_protocol(sd_netlink_message *m, unsigned char *protocol) {
|
||||
int sd_rtnl_message_route_get_protocol(const sd_netlink_message *m, unsigned char *protocol) {
|
||||
struct rtmsg *rtm;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
@ -169,7 +169,7 @@ int sd_rtnl_message_route_get_protocol(sd_netlink_message *m, unsigned char *pro
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_route_get_scope(sd_netlink_message *m, unsigned char *scope) {
|
||||
int sd_rtnl_message_route_get_scope(const sd_netlink_message *m, unsigned char *scope) {
|
||||
struct rtmsg *rtm;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
@ -184,7 +184,7 @@ int sd_rtnl_message_route_get_scope(sd_netlink_message *m, unsigned char *scope)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_route_get_tos(sd_netlink_message *m, uint8_t *tos) {
|
||||
int sd_rtnl_message_route_get_tos(const sd_netlink_message *m, uint8_t *tos) {
|
||||
struct rtmsg *rtm;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
@ -199,7 +199,7 @@ int sd_rtnl_message_route_get_tos(sd_netlink_message *m, uint8_t *tos) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_route_get_table(sd_netlink_message *m, unsigned char *table) {
|
||||
int sd_rtnl_message_route_get_table(const sd_netlink_message *m, unsigned char *table) {
|
||||
struct rtmsg *rtm;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
@ -214,7 +214,7 @@ int sd_rtnl_message_route_get_table(sd_netlink_message *m, unsigned char *table)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_route_get_dst_prefixlen(sd_netlink_message *m, unsigned char *dst_len) {
|
||||
int sd_rtnl_message_route_get_dst_prefixlen(const sd_netlink_message *m, unsigned char *dst_len) {
|
||||
struct rtmsg *rtm;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
@ -229,7 +229,7 @@ int sd_rtnl_message_route_get_dst_prefixlen(sd_netlink_message *m, unsigned char
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_route_get_src_prefixlen(sd_netlink_message *m, unsigned char *src_len) {
|
||||
int sd_rtnl_message_route_get_src_prefixlen(const sd_netlink_message *m, unsigned char *src_len) {
|
||||
struct rtmsg *rtm;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
@ -324,7 +324,7 @@ int sd_rtnl_message_nexthop_set_flags(sd_netlink_message *m, uint8_t flags) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_nexthop_get_family(sd_netlink_message *m, uint8_t *family) {
|
||||
int sd_rtnl_message_nexthop_get_family(const sd_netlink_message *m, uint8_t *family) {
|
||||
struct nhmsg *nhm;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
@ -338,7 +338,7 @@ int sd_rtnl_message_nexthop_get_family(sd_netlink_message *m, uint8_t *family) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_nexthop_get_protocol(sd_netlink_message *m, uint8_t *protocol) {
|
||||
int sd_rtnl_message_nexthop_get_protocol(const sd_netlink_message *m, uint8_t *protocol) {
|
||||
struct nhmsg *nhm;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
@ -378,7 +378,7 @@ int sd_rtnl_message_neigh_set_state(sd_netlink_message *m, uint16_t state) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_neigh_get_flags(sd_netlink_message *m, uint8_t *flags) {
|
||||
int sd_rtnl_message_neigh_get_flags(const sd_netlink_message *m, uint8_t *flags) {
|
||||
struct ndmsg *ndm;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
@ -391,7 +391,7 @@ int sd_rtnl_message_neigh_get_flags(sd_netlink_message *m, uint8_t *flags) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_neigh_get_state(sd_netlink_message *m, uint16_t *state) {
|
||||
int sd_rtnl_message_neigh_get_state(const sd_netlink_message *m, uint16_t *state) {
|
||||
struct ndmsg *ndm;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
@ -404,7 +404,7 @@ int sd_rtnl_message_neigh_get_state(sd_netlink_message *m, uint16_t *state) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_neigh_get_family(sd_netlink_message *m, int *family) {
|
||||
int sd_rtnl_message_neigh_get_family(const sd_netlink_message *m, int *family) {
|
||||
struct ndmsg *ndm;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
@ -419,7 +419,7 @@ int sd_rtnl_message_neigh_get_family(sd_netlink_message *m, int *family) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_neigh_get_ifindex(sd_netlink_message *m, int *index) {
|
||||
int sd_rtnl_message_neigh_get_ifindex(const sd_netlink_message *m, int *index) {
|
||||
struct ndmsg *ndm;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
@ -572,7 +572,7 @@ int sd_rtnl_message_addr_set_scope(sd_netlink_message *m, unsigned char scope) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_addr_get_family(sd_netlink_message *m, int *family) {
|
||||
int sd_rtnl_message_addr_get_family(const sd_netlink_message *m, int *family) {
|
||||
struct ifaddrmsg *ifa;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
@ -587,7 +587,7 @@ int sd_rtnl_message_addr_get_family(sd_netlink_message *m, int *family) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_addr_get_prefixlen(sd_netlink_message *m, unsigned char *prefixlen) {
|
||||
int sd_rtnl_message_addr_get_prefixlen(const sd_netlink_message *m, unsigned char *prefixlen) {
|
||||
struct ifaddrmsg *ifa;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
@ -602,7 +602,7 @@ int sd_rtnl_message_addr_get_prefixlen(sd_netlink_message *m, unsigned char *pre
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_addr_get_scope(sd_netlink_message *m, unsigned char *scope) {
|
||||
int sd_rtnl_message_addr_get_scope(const sd_netlink_message *m, unsigned char *scope) {
|
||||
struct ifaddrmsg *ifa;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
@ -617,7 +617,7 @@ int sd_rtnl_message_addr_get_scope(sd_netlink_message *m, unsigned char *scope)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_addr_get_flags(sd_netlink_message *m, unsigned char *flags) {
|
||||
int sd_rtnl_message_addr_get_flags(const sd_netlink_message *m, unsigned char *flags) {
|
||||
struct ifaddrmsg *ifa;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
@ -632,7 +632,7 @@ int sd_rtnl_message_addr_get_flags(sd_netlink_message *m, unsigned char *flags)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_addr_get_ifindex(sd_netlink_message *m, int *ifindex) {
|
||||
int sd_rtnl_message_addr_get_ifindex(const sd_netlink_message *m, int *ifindex) {
|
||||
struct ifaddrmsg *ifa;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
@ -692,7 +692,7 @@ int sd_rtnl_message_new_addr_update(sd_netlink *rtnl, sd_netlink_message **ret,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_link_get_ifindex(sd_netlink_message *m, int *ifindex) {
|
||||
int sd_rtnl_message_link_get_ifindex(const sd_netlink_message *m, int *ifindex) {
|
||||
struct ifinfomsg *ifi;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
@ -707,7 +707,7 @@ int sd_rtnl_message_link_get_ifindex(sd_netlink_message *m, int *ifindex) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_link_get_flags(sd_netlink_message *m, unsigned *flags) {
|
||||
int sd_rtnl_message_link_get_flags(const sd_netlink_message *m, unsigned *flags) {
|
||||
struct ifinfomsg *ifi;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
@ -722,7 +722,7 @@ int sd_rtnl_message_link_get_flags(sd_netlink_message *m, unsigned *flags) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_link_get_type(sd_netlink_message *m, unsigned short *type) {
|
||||
int sd_rtnl_message_link_get_type(const sd_netlink_message *m, unsigned short *type) {
|
||||
struct ifinfomsg *ifi;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
@ -737,7 +737,7 @@ int sd_rtnl_message_link_get_type(sd_netlink_message *m, unsigned short *type) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_get_family(sd_netlink_message *m, int *family) {
|
||||
int sd_rtnl_message_get_family(const sd_netlink_message *m, int *family) {
|
||||
assert_return(m, -EINVAL);
|
||||
assert_return(family, -EINVAL);
|
||||
|
||||
@ -835,7 +835,7 @@ int sd_rtnl_message_addrlabel_set_prefixlen(sd_netlink_message *m, unsigned char
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_addrlabel_get_prefixlen(sd_netlink_message *m, unsigned char *prefixlen) {
|
||||
int sd_rtnl_message_addrlabel_get_prefixlen(const sd_netlink_message *m, unsigned char *prefixlen) {
|
||||
struct ifaddrlblmsg *addrlabel;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
@ -884,7 +884,7 @@ int sd_rtnl_message_routing_policy_rule_set_tos(sd_netlink_message *m, uint8_t t
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_routing_policy_rule_get_tos(sd_netlink_message *m, uint8_t *tos) {
|
||||
int sd_rtnl_message_routing_policy_rule_get_tos(const sd_netlink_message *m, uint8_t *tos) {
|
||||
struct fib_rule_hdr *frh;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
@ -912,7 +912,7 @@ int sd_rtnl_message_routing_policy_rule_set_table(sd_netlink_message *m, uint8_t
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_routing_policy_rule_get_table(sd_netlink_message *m, uint8_t *table) {
|
||||
int sd_rtnl_message_routing_policy_rule_get_table(const sd_netlink_message *m, uint8_t *table) {
|
||||
struct fib_rule_hdr *frh;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
@ -939,7 +939,7 @@ int sd_rtnl_message_routing_policy_rule_set_flags(sd_netlink_message *m, uint32_
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_routing_policy_rule_get_flags(sd_netlink_message *m, uint32_t *flags) {
|
||||
int sd_rtnl_message_routing_policy_rule_get_flags(const sd_netlink_message *m, uint32_t *flags) {
|
||||
struct fib_rule_hdr *frh;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
@ -966,7 +966,7 @@ int sd_rtnl_message_routing_policy_rule_set_fib_type(sd_netlink_message *m, uint
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_routing_policy_rule_get_fib_type(sd_netlink_message *m, uint8_t *type) {
|
||||
int sd_rtnl_message_routing_policy_rule_get_fib_type(const sd_netlink_message *m, uint8_t *type) {
|
||||
struct fib_rule_hdr *frh;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
@ -994,7 +994,7 @@ int sd_rtnl_message_routing_policy_rule_set_fib_dst_prefixlen(sd_netlink_message
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_routing_policy_rule_get_fib_dst_prefixlen(sd_netlink_message *m, uint8_t *len) {
|
||||
int sd_rtnl_message_routing_policy_rule_get_fib_dst_prefixlen(const sd_netlink_message *m, uint8_t *len) {
|
||||
struct fib_rule_hdr *frh;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
@ -1022,7 +1022,7 @@ int sd_rtnl_message_routing_policy_rule_set_fib_src_prefixlen(sd_netlink_message
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_rtnl_message_routing_policy_rule_get_fib_src_prefixlen(sd_netlink_message *m, uint8_t *len) {
|
||||
int sd_rtnl_message_routing_policy_rule_get_fib_src_prefixlen(const sd_netlink_message *m, uint8_t *len) {
|
||||
struct fib_rule_hdr *frh;
|
||||
|
||||
assert_return(m, -EINVAL);
|
||||
|
||||
@ -742,7 +742,7 @@ int sd_netlink_call(sd_netlink *rtnl,
|
||||
return sd_netlink_read(rtnl, serial, usec, ret);
|
||||
}
|
||||
|
||||
int sd_netlink_get_events(sd_netlink *rtnl) {
|
||||
int sd_netlink_get_events(const sd_netlink *rtnl) {
|
||||
assert_return(rtnl, -EINVAL);
|
||||
assert_return(!rtnl_pid_changed(rtnl), -ECHILD);
|
||||
|
||||
@ -752,7 +752,7 @@ int sd_netlink_get_events(sd_netlink *rtnl) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sd_netlink_get_timeout(sd_netlink *rtnl, uint64_t *timeout_usec) {
|
||||
int sd_netlink_get_timeout(const sd_netlink *rtnl, uint64_t *timeout_usec) {
|
||||
struct reply_callback *c;
|
||||
|
||||
assert_return(rtnl, -EINVAL);
|
||||
|
||||
@ -105,8 +105,6 @@ sources = files('''
|
||||
networkd-network.h
|
||||
networkd-nexthop.c
|
||||
networkd-nexthop.h
|
||||
networkd-queue.c
|
||||
networkd-queue.h
|
||||
networkd-route.c
|
||||
networkd-route.h
|
||||
networkd-routing-policy-rule.c
|
||||
|
||||
@ -9,9 +9,9 @@
|
||||
#include "netlink-util.h"
|
||||
#include "networkd-address-pool.h"
|
||||
#include "networkd-address.h"
|
||||
#include "networkd-ipv6-proxy-ndp.h"
|
||||
#include "networkd-manager.h"
|
||||
#include "networkd-network.h"
|
||||
#include "networkd-queue.h"
|
||||
#include "parse-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
@ -150,7 +150,7 @@ static bool address_may_have_broadcast(const Address *a) {
|
||||
* See https://tools.ietf.org/html/rfc3021 */
|
||||
|
||||
return a->family == AF_INET &&
|
||||
in4_addr_is_null(&a->in_addr_peer.in) &&
|
||||
in_addr_is_null(AF_INET, &a->in_addr_peer) &&
|
||||
a->prefixlen <= 30;
|
||||
}
|
||||
|
||||
@ -406,7 +406,7 @@ static int address_update(Address *address, const Address *src) {
|
||||
}
|
||||
|
||||
if (address->family == AF_INET6 &&
|
||||
in6_addr_is_link_local(&address->in_addr.in6) > 0 &&
|
||||
in_addr_is_link_local(AF_INET6, &address->in_addr) > 0 &&
|
||||
in6_addr_is_null(&address->link->ipv6ll_address)) {
|
||||
|
||||
r = link_ipv6ll_gained(address->link, &address->in_addr.in6);
|
||||
@ -485,63 +485,6 @@ int link_has_ipv6_address(Link *link, const struct in6_addr *address) {
|
||||
return address_get(link, a, NULL) >= 0;
|
||||
}
|
||||
|
||||
static int link_get_ipv4_address(Set *addresses, const struct in_addr *address, Address **ret) {
|
||||
Address *a;
|
||||
|
||||
assert(address);
|
||||
|
||||
SET_FOREACH(a, addresses) {
|
||||
if (a->family != AF_INET)
|
||||
continue;
|
||||
|
||||
if (!in4_addr_equal(&a->in_addr.in, address))
|
||||
continue;
|
||||
|
||||
if (ret)
|
||||
*ret = a;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
int manager_has_address(Manager *manager, int family, const union in_addr_union *address, bool check_ready) {
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(manager);
|
||||
assert(IN_SET(family, AF_INET, AF_INET6));
|
||||
assert(address);
|
||||
|
||||
if (family == AF_INET)
|
||||
HASHMAP_FOREACH(link, manager->links) {
|
||||
Address *a;
|
||||
|
||||
if (link_get_ipv4_address(link->addresses, &address->in, &a) >= 0)
|
||||
return !check_ready || address_is_ready(a);
|
||||
if (link_get_ipv4_address(link->addresses_foreign, &address->in, &a) >= 0)
|
||||
return !check_ready || address_is_ready(a);
|
||||
}
|
||||
else {
|
||||
_cleanup_(address_freep) Address *tmp = NULL;
|
||||
Address *a;
|
||||
|
||||
r = address_new(&tmp);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
tmp->family = family;
|
||||
tmp->in_addr = *address;
|
||||
|
||||
HASHMAP_FOREACH(link, manager->links)
|
||||
if (address_get(link, tmp, &a) >= 0)
|
||||
return !check_ready || address_is_ready(a);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void log_address_debug(const Address *address, const char *str, const Link *link) {
|
||||
_cleanup_free_ char *addr = NULL, *peer = NULL;
|
||||
char valid_buf[FORMAT_TIMESPAN_MAX], preferred_buf[FORMAT_TIMESPAN_MAX];
|
||||
@ -577,6 +520,25 @@ static void log_address_debug(const Address *address, const char *str, const Lin
|
||||
preferred_str ? "for " : "forever", strempty(preferred_str));
|
||||
}
|
||||
|
||||
static int address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(link);
|
||||
assert(link->ifname);
|
||||
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 1;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EADDRNOTAVAIL)
|
||||
log_link_message_warning_errno(link, m, r, "Could not drop address");
|
||||
else if (r >= 0)
|
||||
(void) manager_rtnl_process_address(rtnl, m, link->manager);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int address_set_netlink_message(const Address *address, sd_netlink_message *req, Link *link) {
|
||||
int r;
|
||||
|
||||
@ -608,33 +570,6 @@ static int address_set_netlink_message(const Address *address, sd_netlink_messag
|
||||
return 0;
|
||||
}
|
||||
|
||||
int address_remove_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg) {
|
||||
int r;
|
||||
|
||||
assert(rtnl);
|
||||
assert(m);
|
||||
assert(link);
|
||||
assert(link->address_remove_messages > 0);
|
||||
assert(error_msg);
|
||||
|
||||
link->address_remove_messages--;
|
||||
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 0;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EADDRNOTAVAIL)
|
||||
log_link_message_warning_errno(link, m, r, error_msg);
|
||||
else if (r >= 0)
|
||||
(void) manager_rtnl_process_address(rtnl, m, link->manager);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
return address_remove_handler_internal(rtnl, m, link, "Could not drop address");
|
||||
}
|
||||
|
||||
int address_remove(
|
||||
const Address *address,
|
||||
Link *link,
|
||||
@ -668,7 +603,6 @@ int address_remove(
|
||||
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
||||
|
||||
link_ref(link);
|
||||
link->address_remove_messages++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -772,7 +706,7 @@ int link_drop_foreign_addresses(Link *link) {
|
||||
|
||||
SET_FOREACH(address, link->addresses_foreign) {
|
||||
/* we consider IPv6LL addresses to be managed by the kernel */
|
||||
if (address->family == AF_INET6 && in6_addr_is_link_local(&address->in_addr.in6) == 1 && link_ipv6ll_enabled(link))
|
||||
if (address->family == AF_INET6 && in_addr_is_link_local(AF_INET6, &address->in_addr) == 1 && link_ipv6ll_enabled(link))
|
||||
continue;
|
||||
|
||||
if (link_address_is_dynamic(link, address)) {
|
||||
@ -798,6 +732,35 @@ int link_drop_foreign_addresses(Link *link) {
|
||||
return r;
|
||||
}
|
||||
|
||||
static int remove_static_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(link);
|
||||
assert(link->ifname);
|
||||
assert(link->address_remove_messages > 0);
|
||||
|
||||
link->address_remove_messages--;
|
||||
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 1;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EADDRNOTAVAIL)
|
||||
log_link_message_warning_errno(link, m, r, "Could not drop address");
|
||||
else if (r >= 0)
|
||||
(void) manager_rtnl_process_address(rtnl, m, link->manager);
|
||||
|
||||
if (link->address_remove_messages == 0 && link->request_static_addresses) {
|
||||
link_set_state(link, LINK_STATE_CONFIGURING);
|
||||
r = link_set_addresses(link);
|
||||
if (r < 0)
|
||||
link_enter_failed(link);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int link_drop_addresses(Link *link) {
|
||||
Address *address, *pool_address;
|
||||
int k, r = 0;
|
||||
@ -806,15 +769,17 @@ int link_drop_addresses(Link *link) {
|
||||
|
||||
SET_FOREACH(address, link->addresses) {
|
||||
/* we consider IPv6LL addresses to be managed by the kernel */
|
||||
if (address->family == AF_INET6 && in6_addr_is_link_local(&address->in_addr.in6) == 1 && link_ipv6ll_enabled(link))
|
||||
if (address->family == AF_INET6 && in_addr_is_link_local(AF_INET6, &address->in_addr) == 1 && link_ipv6ll_enabled(link))
|
||||
continue;
|
||||
|
||||
k = address_remove(address, link, NULL);
|
||||
k = address_remove(address, link, remove_static_address_handler);
|
||||
if (k < 0 && r >= 0) {
|
||||
r = k;
|
||||
continue;
|
||||
}
|
||||
|
||||
link->address_remove_messages++;
|
||||
|
||||
SET_FOREACH(pool_address, link->pool_addresses)
|
||||
if (address_equal(address, pool_address))
|
||||
address_free(set_remove(link->pool_addresses, pool_address));
|
||||
@ -880,31 +845,9 @@ static int address_acquire(Link *link, const Address *original, Address **ret) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int address_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg) {
|
||||
int r;
|
||||
|
||||
assert(rtnl);
|
||||
assert(m);
|
||||
assert(link);
|
||||
assert(error_msg);
|
||||
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 0;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EEXIST) {
|
||||
log_link_message_warning_errno(link, m, r, error_msg);
|
||||
link_enter_failed(link);
|
||||
return 0;
|
||||
} else if (r >= 0)
|
||||
(void) manager_rtnl_process_address(rtnl, m, link->manager);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ipv4_dad_configure(Address *address);
|
||||
|
||||
static int address_configure(
|
||||
int address_configure(
|
||||
const Address *address,
|
||||
Link *link,
|
||||
link_netlink_message_handler_t callback,
|
||||
@ -1008,24 +951,78 @@ static int address_configure(
|
||||
return k;
|
||||
}
|
||||
|
||||
static int static_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
static int static_address_ready_callback(Address *address) {
|
||||
Address *a;
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->static_address_messages > 0);
|
||||
assert(address);
|
||||
assert(address->link);
|
||||
|
||||
link->static_address_messages--;
|
||||
link = address->link;
|
||||
|
||||
r = address_configure_handler_internal(rtnl, m, link, "Failed to set static address");
|
||||
if (r <= 0)
|
||||
if (!link->addresses_configured)
|
||||
return 0;
|
||||
|
||||
SET_FOREACH(a, link->static_addresses)
|
||||
if (!address_is_ready(a)) {
|
||||
_cleanup_free_ char *str = NULL;
|
||||
|
||||
(void) in_addr_prefix_to_string(a->family, &a->in_addr, a->prefixlen, &str);
|
||||
log_link_debug(link, "an address %s is not ready", strnull(str));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This should not be called again */
|
||||
SET_FOREACH(a, link->static_addresses)
|
||||
a->callback = NULL;
|
||||
|
||||
link->addresses_ready = true;
|
||||
|
||||
r = link_set_ipv6_proxy_ndp_addresses(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (link->static_address_messages == 0) {
|
||||
log_link_debug(link, "Addresses set");
|
||||
link->static_addresses_configured = true;
|
||||
link_check_ready(link);
|
||||
return link_set_routes(link);
|
||||
}
|
||||
|
||||
r = dhcp4_server_configure(link);
|
||||
static int address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
assert(rtnl);
|
||||
assert(m);
|
||||
assert(link);
|
||||
assert(link->ifname);
|
||||
assert(link->address_messages > 0);
|
||||
|
||||
link->address_messages--;
|
||||
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 1;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EEXIST) {
|
||||
log_link_message_warning_errno(link, m, r, "Could not set address");
|
||||
link_enter_failed(link);
|
||||
return 1;
|
||||
} else if (r >= 0)
|
||||
(void) manager_rtnl_process_address(rtnl, m, link->manager);
|
||||
|
||||
if (link->address_messages == 0) {
|
||||
Address *a;
|
||||
|
||||
log_link_debug(link, "Addresses set");
|
||||
link->addresses_configured = true;
|
||||
|
||||
/* When all static addresses are already ready, then static_address_ready_callback()
|
||||
* will not be called automatically. So, call it here. */
|
||||
a = set_first(link->static_addresses);
|
||||
if (!a) {
|
||||
log_link_debug(link, "No static address is stored. Already removed?");
|
||||
return 1;
|
||||
}
|
||||
|
||||
r = static_address_ready_callback(a);
|
||||
if (r < 0)
|
||||
link_enter_failed(link);
|
||||
}
|
||||
@ -1033,65 +1030,55 @@ static int static_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int static_address_after_configure(Request *req, void *object) {
|
||||
Address *address = object;
|
||||
Link *link;
|
||||
static int static_address_configure(const Address *address, Link *link) {
|
||||
Address *ret;
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->link);
|
||||
assert(req->type == REQUEST_TYPE_ADDRESS);
|
||||
assert(address);
|
||||
assert(link);
|
||||
|
||||
link = req->link;
|
||||
r = address_configure(address, link, address_handler, &ret);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Could not configure static address: %m");
|
||||
|
||||
r = set_ensure_put(&link->static_addresses, &address_hash_ops, address);
|
||||
link->address_messages++;
|
||||
|
||||
r = set_ensure_put(&link->static_addresses, &address_hash_ops, ret);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to store static address: %m");
|
||||
|
||||
ret->callback = static_address_ready_callback;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int link_request_address(
|
||||
Link *link,
|
||||
Address *address,
|
||||
bool consume_object,
|
||||
unsigned *message_counter,
|
||||
link_netlink_message_handler_t netlink_handler,
|
||||
Request **ret) {
|
||||
|
||||
assert(link);
|
||||
assert(address);
|
||||
|
||||
log_address_debug(address, "Requesting", link);
|
||||
return link_queue_request(link, REQUEST_TYPE_ADDRESS, address, consume_object,
|
||||
message_counter, netlink_handler, ret);
|
||||
}
|
||||
|
||||
int link_request_static_addresses(Link *link) {
|
||||
Address *a;
|
||||
int link_set_addresses(Link *link) {
|
||||
Address *ad;
|
||||
Prefix *p;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->network);
|
||||
|
||||
link->static_addresses_configured = false;
|
||||
if (link->address_remove_messages != 0) {
|
||||
log_link_debug(link, "Removing old addresses, new addresses will be configured later.");
|
||||
link->request_static_addresses = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ORDERED_HASHMAP_FOREACH(a, link->network->addresses_by_section) {
|
||||
Request *req;
|
||||
if (link->address_messages != 0) {
|
||||
log_link_debug(link, "Static addresses are configuring.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = link_request_address(link, a, false, &link->static_address_messages,
|
||||
static_address_handler, &req);
|
||||
ORDERED_HASHMAP_FOREACH(ad, link->network->addresses_by_section) {
|
||||
r = static_address_configure(ad, link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
req->after_configure = static_address_after_configure;
|
||||
}
|
||||
|
||||
HASHMAP_FOREACH(p, link->network->prefixes_by_section) {
|
||||
_cleanup_(address_freep) Address *address = NULL;
|
||||
Request *req;
|
||||
|
||||
if (!p->assign)
|
||||
continue;
|
||||
@ -1110,18 +1097,22 @@ int link_request_static_addresses(Link *link) {
|
||||
|
||||
address->family = AF_INET6;
|
||||
address->route_metric = p->route_metric;
|
||||
r = static_address_configure(address, link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = link_request_address(link, TAKE_PTR(address), true, &link->static_address_messages,
|
||||
static_address_handler, &req);
|
||||
if (link->address_messages == 0) {
|
||||
link->addresses_configured = true;
|
||||
link->addresses_ready = true;
|
||||
|
||||
r = link_set_ipv6_proxy_ndp_addresses(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
req->after_configure = static_address_after_configure;
|
||||
}
|
||||
|
||||
if (link->static_address_messages == 0) {
|
||||
link->static_addresses_configured = true;
|
||||
link_check_ready(link);
|
||||
r = link_set_routes(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else {
|
||||
log_link_debug(link, "Setting addresses");
|
||||
link_set_state(link, LINK_STATE_CONFIGURING);
|
||||
@ -1130,34 +1121,6 @@ int link_request_static_addresses(Link *link) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int request_process_address(Request *req) {
|
||||
Address *ret = NULL; /* avoid false maybe-uninitialized warning */
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->link);
|
||||
assert(req->address);
|
||||
assert(req->type == REQUEST_TYPE_ADDRESS);
|
||||
|
||||
if (!link_is_ready_to_configure(req->link, false))
|
||||
return 0;
|
||||
|
||||
if (req->link->address_remove_messages > 0)
|
||||
return 0;
|
||||
|
||||
r = address_configure(req->address, req->link, req->netlink_handler, &ret);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (req->after_configure) {
|
||||
r = req->after_configure(req, ret);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) {
|
||||
_cleanup_(address_freep) Address *tmp = NULL;
|
||||
Link *link = NULL;
|
||||
@ -1341,6 +1304,7 @@ int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message,
|
||||
}
|
||||
|
||||
static void static_address_on_acd(sd_ipv4acd *acd, int event, void *userdata) {
|
||||
_cleanup_free_ char *pretty = NULL;
|
||||
Address *address;
|
||||
Link *link;
|
||||
int r;
|
||||
@ -1351,26 +1315,22 @@ static void static_address_on_acd(sd_ipv4acd *acd, int event, void *userdata) {
|
||||
address = (Address *) userdata;
|
||||
link = address->link;
|
||||
|
||||
assert(address->family == AF_INET);
|
||||
|
||||
(void) in_addr_to_string(address->family, &address->in_addr, &pretty);
|
||||
switch (event) {
|
||||
case SD_IPV4ACD_EVENT_STOP:
|
||||
log_link_debug(link, "Stopping ACD client...");
|
||||
return;
|
||||
|
||||
case SD_IPV4ACD_EVENT_BIND:
|
||||
log_link_debug(link, "Successfully claimed address "IPV4_ADDRESS_FMT_STR,
|
||||
IPV4_ADDRESS_FMT_VAL(address->in_addr.in));
|
||||
log_link_debug(link, "Successfully claimed address %s", strna(pretty));
|
||||
link_check_ready(link);
|
||||
break;
|
||||
|
||||
case SD_IPV4ACD_EVENT_CONFLICT:
|
||||
log_link_warning(link, "DAD conflict. Dropping address "IPV4_ADDRESS_FMT_STR,
|
||||
IPV4_ADDRESS_FMT_VAL(address->in_addr.in));
|
||||
log_link_warning(link, "DAD conflict. Dropping address %s", strna(pretty));
|
||||
r = address_remove(address, link, NULL);
|
||||
if (r < 0)
|
||||
log_link_error_errno(link, r, "Failed to drop DAD conflicted address "IPV4_ADDRESS_FMT_STR,
|
||||
IPV4_ADDRESS_FMT_VAL(address->in_addr.in));
|
||||
log_link_error_errno(link, r, "Failed to drop DAD conflicted address %s", strna(pretty));;
|
||||
|
||||
link_check_ready(link);
|
||||
break;
|
||||
@ -1393,7 +1353,12 @@ static int ipv4_dad_configure(Address *address) {
|
||||
if (address->family != AF_INET)
|
||||
return 0;
|
||||
|
||||
log_address_debug(address, "Starting IPv4ACD client. Probing", address->link);
|
||||
if (DEBUG_LOGGING) {
|
||||
_cleanup_free_ char *pretty = NULL;
|
||||
|
||||
(void) in_addr_to_string(address->family, &address->in_addr, &pretty);
|
||||
log_link_debug(address->link, "Starting IPv4ACD client. Probing address %s", strna(pretty));
|
||||
}
|
||||
|
||||
if (!address->acd) {
|
||||
r = sd_ipv4acd_new(&address->acd);
|
||||
|
||||
@ -16,7 +16,6 @@
|
||||
|
||||
typedef struct Manager Manager;
|
||||
typedef struct Network Network;
|
||||
typedef struct Request Request;
|
||||
typedef int (*address_ready_callback_t)(Address *address);
|
||||
|
||||
typedef struct Address {
|
||||
@ -52,8 +51,7 @@ typedef struct Address {
|
||||
int address_new(Address **ret);
|
||||
Address *address_free(Address *address);
|
||||
int address_get(Link *link, const Address *in, Address **ret);
|
||||
int address_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg);
|
||||
int address_remove_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg);
|
||||
int address_configure(const Address *address, Link *link, link_netlink_message_handler_t callback, Address **ret);
|
||||
int address_remove(const Address *address, Link *link, link_netlink_message_handler_t callback);
|
||||
bool address_equal(const Address *a1, const Address *a2);
|
||||
bool address_is_ready(const Address *a);
|
||||
@ -62,26 +60,16 @@ int generate_ipv6_eui_64_address(const Link *link, struct in6_addr *ret);
|
||||
|
||||
DEFINE_NETWORK_SECTION_FUNCTIONS(Address, address_free);
|
||||
|
||||
int link_set_addresses(Link *link);
|
||||
int link_drop_addresses(Link *link);
|
||||
int link_drop_foreign_addresses(Link *link);
|
||||
bool link_address_is_dynamic(const Link *link, const Address *address);
|
||||
int link_has_ipv6_address(Link *link, const struct in6_addr *address);
|
||||
int manager_has_address(Manager *manager, int family, const union in_addr_union *address, bool check_ready);
|
||||
|
||||
void ipv4_dad_unref(Link *link);
|
||||
int ipv4_dad_stop(Link *link);
|
||||
int ipv4_dad_update_mac(Link *link);
|
||||
|
||||
int link_request_address(
|
||||
Link *link,
|
||||
Address *address,
|
||||
bool consume_object,
|
||||
unsigned *message_counter,
|
||||
link_netlink_message_handler_t netlink_handler,
|
||||
Request **ret);
|
||||
int link_request_static_addresses(Link *link);
|
||||
int request_process_address(Request *req);
|
||||
|
||||
int manager_rtnl_process_address(sd_netlink *nl, sd_netlink_message *message, Manager *m);
|
||||
|
||||
void network_drop_invalid_addresses(Network *network);
|
||||
@ -98,3 +86,10 @@ CONFIG_PARSER_PROTOTYPE(config_parse_address_flags);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_address_scope);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_address_route_metric);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_duplicate_address_detection);
|
||||
|
||||
#define IPV4_ADDRESS_FMT_STR "%u.%u.%u.%u"
|
||||
#define IPV4_ADDRESS_FMT_VAL(address) \
|
||||
be32toh((address).s_addr) >> 24, \
|
||||
(be32toh((address).s_addr) >> 16) & 0xFFu, \
|
||||
(be32toh((address).s_addr) >> 8) & 0xFFu, \
|
||||
be32toh((address).s_addr) & 0xFFu
|
||||
|
||||
@ -17,16 +17,13 @@
|
||||
#include "networkd-link.h"
|
||||
#include "networkd-manager.h"
|
||||
#include "networkd-network.h"
|
||||
#include "networkd-nexthop.h"
|
||||
#include "networkd-queue.h"
|
||||
#include "networkd-route.h"
|
||||
#include "networkd-state-file.h"
|
||||
#include "string-table.h"
|
||||
#include "strv.h"
|
||||
#include "sysctl-util.h"
|
||||
#include "web-util.h"
|
||||
|
||||
static int dhcp4_request_address_and_routes(Link *link, bool announce);
|
||||
static int dhcp4_update_address(Link *link, bool announce);
|
||||
static int dhcp4_remove_all(Link *link);
|
||||
|
||||
void network_adjust_dhcp4(Network *network) {
|
||||
@ -86,20 +83,8 @@ static void dhcp4_check_ready(Link *link) {
|
||||
if (link->network->dhcp_send_decline && !link->dhcp4_address_bind)
|
||||
return;
|
||||
|
||||
if (link->dhcp4_messages > 0) {
|
||||
log_link_debug(link, "%s(): DHCPv4 address and routes are not set.", __func__);
|
||||
if (link->dhcp4_messages > 0)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!link->dhcp_address) {
|
||||
log_link_debug(link, "%s(): DHCPv4 address is not set.", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!address_is_ready(link->dhcp_address)) {
|
||||
log_link_debug(link, "%s(): DHCPv4 address is not ready.", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
link->dhcp4_configured = true;
|
||||
|
||||
@ -117,27 +102,6 @@ static void dhcp4_check_ready(Link *link) {
|
||||
link_check_ready(link);
|
||||
}
|
||||
|
||||
static int dhcp4_after_route_configure(Request *req, void *object) {
|
||||
Route *route = object;
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->link);
|
||||
assert(req->type == REQUEST_TYPE_ROUTE);
|
||||
assert(route);
|
||||
|
||||
link = req->link;
|
||||
|
||||
r = set_ensure_put(&link->dhcp_routes, &route_hash_ops, route);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to store DHCPv4 route: %m");
|
||||
|
||||
set_remove(link->dhcp_routes_old, route);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
@ -171,15 +135,6 @@ static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *li
|
||||
r = dhcp4_remove_all(link);
|
||||
if (r < 0)
|
||||
link_enter_failed(link);
|
||||
|
||||
r = link_request_static_nexthops(link, true);
|
||||
if (r < 0)
|
||||
link_enter_failed(link);
|
||||
|
||||
r = link_request_static_routes(link, true);
|
||||
if (r < 0)
|
||||
link_enter_failed(link);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -188,26 +143,24 @@ static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *li
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dhcp4_request_route(Route *in, Link *link) {
|
||||
_cleanup_(route_freep) Route *route = in;
|
||||
Request *req;
|
||||
static int dhcp_route_configure(Route *route, Link *link) {
|
||||
Route *ret;
|
||||
int r;
|
||||
|
||||
assert(route);
|
||||
assert(link);
|
||||
|
||||
r = link_has_route(link, route);
|
||||
r = route_configure(route, link, dhcp4_route_handler, &ret);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
link->dhcp4_configured = false;
|
||||
return log_link_error_errno(link, r, "Failed to set DHCPv4 route: %m");
|
||||
|
||||
r = link_request_route(link, TAKE_PTR(route), true, &link->dhcp4_messages,
|
||||
dhcp4_route_handler, &req);
|
||||
link->dhcp4_messages++;
|
||||
|
||||
r = set_ensure_put(&link->dhcp_routes, &route_hash_ops, ret);
|
||||
if (r < 0)
|
||||
return r;
|
||||
return log_link_error_errno(link, r, "Failed to store DHCPv4 route: %m");
|
||||
|
||||
req->after_configure = dhcp4_after_route_configure;
|
||||
(void) set_remove(link->dhcp_routes_old, ret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -218,7 +171,7 @@ static bool link_prefixroute(Link *link) {
|
||||
link->manager->dhcp4_prefix_root_cannot_set_table;
|
||||
}
|
||||
|
||||
static int dhcp4_request_prefix_route(Link *link) {
|
||||
static int link_set_dhcp_prefix_route(Link *link) {
|
||||
_cleanup_(route_freep) Route *route = NULL;
|
||||
struct in_addr address, netmask;
|
||||
int r;
|
||||
@ -251,10 +204,10 @@ static int dhcp4_request_prefix_route(Link *link) {
|
||||
route->table = link_get_dhcp_route_table(link);
|
||||
route->mtu = link->network->dhcp_route_mtu;
|
||||
|
||||
return dhcp4_request_route(TAKE_PTR(route), link);
|
||||
return dhcp_route_configure(route, link);
|
||||
}
|
||||
|
||||
static int dhcp4_request_route_to_gateway(Link *link, const struct in_addr *gw) {
|
||||
static int link_set_dhcp_route_to_gateway(Link *link, const struct in_addr *gw) {
|
||||
_cleanup_(route_freep) Route *route = NULL;
|
||||
struct in_addr address;
|
||||
int r;
|
||||
@ -281,15 +234,14 @@ static int dhcp4_request_route_to_gateway(Link *link, const struct in_addr *gw)
|
||||
route->table = link_get_dhcp_route_table(link);
|
||||
route->mtu = link->network->dhcp_route_mtu;
|
||||
|
||||
return dhcp4_request_route(TAKE_PTR(route), link);
|
||||
return dhcp_route_configure(route, link);
|
||||
}
|
||||
|
||||
static int dhcp4_request_route_auto(
|
||||
Route *in,
|
||||
static int dhcp_route_configure_auto(
|
||||
Route *route,
|
||||
Link *link,
|
||||
const struct in_addr *gw) {
|
||||
|
||||
_cleanup_(route_freep) Route *route = in;
|
||||
struct in_addr address, netmask, prefix;
|
||||
uint8_t prefixlen;
|
||||
int r;
|
||||
@ -299,6 +251,8 @@ static int dhcp4_request_route_auto(
|
||||
assert(link->dhcp_lease);
|
||||
assert(gw);
|
||||
|
||||
/* The route object may be reused in an iteration. All elements must be set or cleared. */
|
||||
|
||||
r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -355,7 +309,7 @@ static int dhcp4_request_route_auto(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = dhcp4_request_route_to_gateway(link, gw);
|
||||
r = link_set_dhcp_route_to_gateway(link, gw);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -365,12 +319,13 @@ static int dhcp4_request_route_auto(
|
||||
route->prefsrc.in = address;
|
||||
}
|
||||
|
||||
return dhcp4_request_route(TAKE_PTR(route), link);
|
||||
return dhcp_route_configure(route, link);
|
||||
}
|
||||
|
||||
static int dhcp4_request_static_routes(Link *link, struct in_addr *ret_default_gw) {
|
||||
static int link_set_dhcp_static_routes(Link *link, struct in_addr *ret_default_gw) {
|
||||
_cleanup_free_ sd_dhcp_route **static_routes = NULL;
|
||||
bool classless_route = false, static_route = false;
|
||||
_cleanup_(route_freep) Route *route = NULL;
|
||||
struct in_addr default_gw = {};
|
||||
int n, r;
|
||||
|
||||
@ -405,14 +360,6 @@ static int dhcp4_request_static_routes(Link *link, struct in_addr *ret_default_g
|
||||
if (classless_route && static_route)
|
||||
log_link_debug(link, "Classless static routes received from DHCP server: ignoring static-route option");
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
_cleanup_(route_freep) Route *route = NULL;
|
||||
struct in_addr gw;
|
||||
|
||||
if (sd_dhcp_route_get_option(static_routes[i]) !=
|
||||
(classless_route ? SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE : SD_DHCP_OPTION_STATIC_ROUTE))
|
||||
continue;
|
||||
|
||||
r = route_new(&route);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -424,6 +371,13 @@ static int dhcp4_request_static_routes(Link *link, struct in_addr *ret_default_g
|
||||
route->table = link_get_dhcp_route_table(link);
|
||||
route->mtu = link->network->dhcp_route_mtu;
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
struct in_addr gw;
|
||||
|
||||
if (sd_dhcp_route_get_option(static_routes[i]) !=
|
||||
(classless_route ? SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE : SD_DHCP_OPTION_STATIC_ROUTE))
|
||||
continue;
|
||||
|
||||
r = sd_dhcp_route_get_gateway(static_routes[i], &gw);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -444,7 +398,7 @@ static int dhcp4_request_static_routes(Link *link, struct in_addr *ret_default_g
|
||||
in4_addr_is_null(&default_gw))
|
||||
default_gw = gw;
|
||||
|
||||
r = dhcp4_request_route_auto(TAKE_PTR(route), link, &gw);
|
||||
r = dhcp_route_configure_auto(route, link, &gw);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -453,7 +407,7 @@ static int dhcp4_request_static_routes(Link *link, struct in_addr *ret_default_g
|
||||
return classless_route;
|
||||
}
|
||||
|
||||
static int dhcp4_request_gateway(Link *link, struct in_addr *ret_gw) {
|
||||
static int link_set_dhcp_gateway(Link *link, struct in_addr *ret_gw) {
|
||||
_cleanup_(route_freep) Route *route = NULL;
|
||||
const struct in_addr *router;
|
||||
struct in_addr address;
|
||||
@ -485,7 +439,7 @@ static int dhcp4_request_gateway(Link *link, struct in_addr *ret_gw) {
|
||||
|
||||
/* The dhcp netmask may mask out the gateway. First, add an explicit route for the gateway host
|
||||
* so that we can route no matter the netmask or existing kernel route tables. */
|
||||
r = dhcp4_request_route_to_gateway(link, &router[0]);
|
||||
r = link_set_dhcp_route_to_gateway(link, &router[0]);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -503,7 +457,7 @@ static int dhcp4_request_gateway(Link *link, struct in_addr *ret_gw) {
|
||||
route->table = link_get_dhcp_route_table(link);
|
||||
route->mtu = link->network->dhcp_route_mtu;
|
||||
|
||||
r = dhcp4_request_route(TAKE_PTR(route), link);
|
||||
r = dhcp_route_configure(route, link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -514,21 +468,17 @@ static int dhcp4_request_gateway(Link *link, struct in_addr *ret_gw) {
|
||||
if (rt->gw_family != AF_INET)
|
||||
continue;
|
||||
|
||||
r = route_dup(rt, &route);
|
||||
if (r < 0)
|
||||
return r;
|
||||
rt->gw.in = router[0];
|
||||
if (!rt->protocol_set)
|
||||
rt->protocol = RTPROT_DHCP;
|
||||
if (!rt->priority_set)
|
||||
rt->priority = link->network->dhcp_route_metric;
|
||||
if (!rt->table_set)
|
||||
rt->table = link_get_dhcp_route_table(link);
|
||||
if (rt->mtu == 0)
|
||||
rt->mtu = link->network->dhcp_route_mtu;
|
||||
|
||||
route->gw.in = router[0];
|
||||
if (!route->protocol_set)
|
||||
route->protocol = RTPROT_DHCP;
|
||||
if (!route->priority_set)
|
||||
route->priority = link->network->dhcp_route_metric;
|
||||
if (!route->table_set)
|
||||
route->table = link_get_dhcp_route_table(link);
|
||||
if (route->mtu == 0)
|
||||
route->mtu = link->network->dhcp_route_mtu;
|
||||
|
||||
r = dhcp4_request_route(TAKE_PTR(route), link);
|
||||
r = dhcp_route_configure(rt, link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -537,12 +487,13 @@ static int dhcp4_request_gateway(Link *link, struct in_addr *ret_gw) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dhcp4_request_routes_to_servers(
|
||||
static int link_set_routes_to_servers(
|
||||
Link *link,
|
||||
const struct in_addr *servers,
|
||||
size_t n_servers,
|
||||
const struct in_addr *gw) {
|
||||
|
||||
_cleanup_(route_freep) Route *route = NULL;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
@ -551,25 +502,24 @@ static int dhcp4_request_routes_to_servers(
|
||||
assert(servers || n_servers == 0);
|
||||
assert(gw);
|
||||
|
||||
for (size_t i = 0; i < n_servers; i++) {
|
||||
_cleanup_(route_freep) Route *route = NULL;
|
||||
|
||||
if (in4_addr_is_null(&servers[i]))
|
||||
continue;
|
||||
|
||||
r = route_new(&route);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
route->family = AF_INET;
|
||||
route->dst.in = servers[i];
|
||||
route->dst_prefixlen = 32;
|
||||
route->protocol = RTPROT_DHCP;
|
||||
route->priority = link->network->dhcp_route_metric;
|
||||
route->table = link_get_dhcp_route_table(link);
|
||||
route->mtu = link->network->dhcp_route_mtu;
|
||||
|
||||
r = dhcp4_request_route_auto(TAKE_PTR(route), link, gw);
|
||||
for (size_t i = 0; i < n_servers; i++) {
|
||||
if (in4_addr_is_null(&servers[i]))
|
||||
continue;
|
||||
|
||||
route->dst.in = servers[i];
|
||||
|
||||
r = dhcp_route_configure_auto(route, link, gw);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -577,7 +527,7 @@ static int dhcp4_request_routes_to_servers(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dhcp4_request_routes_to_dns(Link *link, const struct in_addr *gw) {
|
||||
static int link_set_routes_to_dns(Link *link, const struct in_addr *gw) {
|
||||
const struct in_addr *dns;
|
||||
int r;
|
||||
|
||||
@ -596,10 +546,10 @@ static int dhcp4_request_routes_to_dns(Link *link, const struct in_addr *gw) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return dhcp4_request_routes_to_servers(link, dns, r, gw);
|
||||
return link_set_routes_to_servers(link, dns, r, gw);
|
||||
}
|
||||
|
||||
static int dhcp4_request_routes_to_ntp(Link *link, const struct in_addr *gw) {
|
||||
static int link_set_routes_to_ntp(Link *link, const struct in_addr *gw) {
|
||||
const struct in_addr *ntp;
|
||||
int r;
|
||||
|
||||
@ -618,17 +568,25 @@ static int dhcp4_request_routes_to_ntp(Link *link, const struct in_addr *gw) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return dhcp4_request_routes_to_servers(link, ntp, r, gw);
|
||||
return link_set_routes_to_servers(link, ntp, r, gw);
|
||||
}
|
||||
|
||||
static int dhcp4_request_routes(Link *link) {
|
||||
static int link_set_dhcp_routes(Link *link) {
|
||||
struct in_addr gw = {};
|
||||
Route *rt;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
|
||||
if (!link->dhcp_lease)
|
||||
if (!link->dhcp_lease) /* link went down while we configured the IP addresses? */
|
||||
return 0;
|
||||
|
||||
if (!link->network) /* link went down while we configured the IP addresses? */
|
||||
return 0;
|
||||
|
||||
if (!link_has_carrier(link) && !link->network->configure_without_carrier)
|
||||
/* During configuring addresses, the link lost its carrier. As networkd is dropping
|
||||
* the addresses now, let's not configure the routes either. */
|
||||
return 0;
|
||||
|
||||
while ((rt = set_steal_first(link->dhcp_routes))) {
|
||||
@ -637,28 +595,28 @@ static int dhcp4_request_routes(Link *link) {
|
||||
return log_link_error_errno(link, r, "Failed to store old DHCPv4 route: %m");
|
||||
}
|
||||
|
||||
r = dhcp4_request_prefix_route(link);
|
||||
r = link_set_dhcp_prefix_route(link);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "DHCP error: Could not request prefix route: %m");
|
||||
return log_link_error_errno(link, r, "DHCP error: Could not set prefix route: %m");
|
||||
|
||||
r = dhcp4_request_static_routes(link, &gw);
|
||||
r = link_set_dhcp_static_routes(link, &gw);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "DHCP error: Could not request static routes: %m");
|
||||
return log_link_error_errno(link, r, "DHCP error: Could not set static routes: %m");
|
||||
if (r == 0) {
|
||||
/* According to RFC 3442: If the DHCP server returns both a Classless Static Routes option and
|
||||
* a Router option, the DHCP client MUST ignore the Router option. */
|
||||
r = dhcp4_request_gateway(link, &gw);
|
||||
r = link_set_dhcp_gateway(link, &gw);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "DHCP error: Could not request gateway: %m");
|
||||
return log_link_error_errno(link, r, "DHCP error: Could not set gateway: %m");
|
||||
}
|
||||
|
||||
r = dhcp4_request_routes_to_dns(link, &gw);
|
||||
r = link_set_routes_to_dns(link, &gw);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "DHCP error: Could not request routes to DNS servers: %m");
|
||||
return log_link_error_errno(link, r, "DHCP error: Could not set routes to DNS servers: %m");
|
||||
|
||||
r = dhcp4_request_routes_to_ntp(link, &gw);
|
||||
r = link_set_routes_to_ntp(link, &gw);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "DHCP error: Could not request routes to NTP servers: %m");
|
||||
return log_link_error_errno(link, r, "DHCP error: Could not set routes to NTP servers: %m");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -712,20 +670,24 @@ static int dhcp_reset_hostname(Link *link) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dhcp4_route_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
static int dhcp4_remove_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(link);
|
||||
assert(link->dhcp4_remove_messages > 0);
|
||||
|
||||
link->dhcp4_remove_messages--;
|
||||
|
||||
r = link_route_remove_handler_internal(rtnl, m, link, "Failed to remove DHCPv4 route, ignoring");
|
||||
if (r <= 0)
|
||||
return r;
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 1;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -ESRCH)
|
||||
log_link_message_warning_errno(link, m, r, "Failed to remove DHCPv4 route, ignoring");
|
||||
|
||||
if (link->dhcp4_remove_messages == 0) {
|
||||
r = dhcp4_request_address_and_routes(link, false);
|
||||
r = dhcp4_update_address(link, false);
|
||||
if (r < 0)
|
||||
link_enter_failed(link);
|
||||
}
|
||||
@ -733,20 +695,26 @@ static int dhcp4_route_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, L
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dhcp4_address_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
static int dhcp4_remove_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(link);
|
||||
assert(link->dhcp4_remove_messages > 0);
|
||||
|
||||
link->dhcp4_remove_messages--;
|
||||
|
||||
r = address_remove_handler_internal(rtnl, m, link, "Failed to remove DHCPv4 address, ignoring");
|
||||
if (r <= 0)
|
||||
return r;
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 1;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EADDRNOTAVAIL)
|
||||
log_link_message_warning_errno(link, m, r, "Failed to remove DHCPv4 address, ignoring");
|
||||
else
|
||||
(void) manager_rtnl_process_address(rtnl, m, link->manager);
|
||||
|
||||
if (link->dhcp4_remove_messages == 0) {
|
||||
r = dhcp4_request_address_and_routes(link, false);
|
||||
r = dhcp4_update_address(link, false);
|
||||
if (r < 0)
|
||||
link_enter_failed(link);
|
||||
}
|
||||
@ -761,7 +729,7 @@ static int dhcp4_remove_all(Link *link) {
|
||||
assert(link);
|
||||
|
||||
SET_FOREACH(route, link->dhcp_routes) {
|
||||
k = route_remove(route, NULL, link, dhcp4_route_remove_handler);
|
||||
k = route_remove(route, NULL, link, dhcp4_remove_route_handler);
|
||||
if (k < 0)
|
||||
r = k;
|
||||
else
|
||||
@ -769,7 +737,7 @@ static int dhcp4_remove_all(Link *link) {
|
||||
}
|
||||
|
||||
if (link->dhcp_address) {
|
||||
k = address_remove(link->dhcp_address, link, dhcp4_address_remove_handler);
|
||||
k = address_remove(link->dhcp_address, link, dhcp4_remove_address_handler);
|
||||
if (k < 0)
|
||||
r = k;
|
||||
else
|
||||
@ -811,18 +779,12 @@ static int dhcp_lease_lost(Link *link) {
|
||||
|
||||
(void) sd_ipv4acd_stop(link->dhcp_acd);
|
||||
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = link_request_static_nexthops(link, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return link_request_static_routes(link, true);
|
||||
}
|
||||
|
||||
static void dhcp_address_on_acd(sd_ipv4acd *acd, int event, void *userdata) {
|
||||
struct in_addr address;
|
||||
_cleanup_free_ char *pretty = NULL;
|
||||
union in_addr_union address = {};
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
@ -833,21 +795,23 @@ static void dhcp_address_on_acd(sd_ipv4acd *acd, int event, void *userdata) {
|
||||
|
||||
switch (event) {
|
||||
case SD_IPV4ACD_EVENT_STOP:
|
||||
log_link_debug(link, "Stopping ACD client for DHCPv4 address.");
|
||||
log_link_debug(link, "Stopping ACD client for DHCP4...");
|
||||
return;
|
||||
|
||||
case SD_IPV4ACD_EVENT_BIND:
|
||||
if (DEBUG_LOGGING) {
|
||||
(void) sd_dhcp_lease_get_address(link->dhcp_lease, &address);
|
||||
log_link_debug(link, "Successfully claimed DHCPv4 address "IPV4_ADDRESS_FMT_STR, IPV4_ADDRESS_FMT_VAL(address));
|
||||
(void) sd_dhcp_lease_get_address(link->dhcp_lease, &address.in);
|
||||
(void) in_addr_to_string(AF_INET, &address, &pretty);
|
||||
log_link_debug(link, "Successfully claimed DHCP4 address %s", strna(pretty));
|
||||
}
|
||||
link->dhcp4_address_bind = true;
|
||||
dhcp4_check_ready(link);
|
||||
break;
|
||||
|
||||
case SD_IPV4ACD_EVENT_CONFLICT:
|
||||
(void) sd_dhcp_lease_get_address(link->dhcp_lease, &address);
|
||||
log_link_warning(link, "DAD conflict. Dropping DHCPv4 address "IPV4_ADDRESS_FMT_STR, IPV4_ADDRESS_FMT_VAL(address));
|
||||
(void) sd_dhcp_lease_get_address(link->dhcp_lease, &address.in);
|
||||
(void) in_addr_to_string(AF_INET, &address, &pretty);
|
||||
log_link_warning(link, "DAD conflict. Dropping DHCP4 address %s", strna(pretty));
|
||||
|
||||
r = sd_dhcp_client_send_decline(link->dhcp_client);
|
||||
if (r < 0)
|
||||
@ -929,7 +893,8 @@ static int dhcp4_dad_update_mac(Link *link) {
|
||||
}
|
||||
|
||||
static int dhcp4_start_acd(Link *link) {
|
||||
struct in_addr addr, old;
|
||||
union in_addr_union addr;
|
||||
struct in_addr old;
|
||||
int r;
|
||||
|
||||
if (!link->network->dhcp_send_decline)
|
||||
@ -942,7 +907,7 @@ static int dhcp4_start_acd(Link *link) {
|
||||
|
||||
link->dhcp4_address_bind = false;
|
||||
|
||||
r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr);
|
||||
r = sd_dhcp_lease_get_address(link->dhcp_lease, &addr.in);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -950,7 +915,7 @@ static int dhcp4_start_acd(Link *link) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_ipv4acd_set_address(link->dhcp_acd, &addr);
|
||||
r = sd_ipv4acd_set_address(link->dhcp_acd, &addr.in);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -958,51 +923,45 @@ static int dhcp4_start_acd(Link *link) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
log_link_debug(link, "Starting IPv4ACD client. Probing DHCPv4 address "IPV4_ADDRESS_FMT_STR,
|
||||
IPV4_ADDRESS_FMT_VAL(addr));
|
||||
if (DEBUG_LOGGING) {
|
||||
_cleanup_free_ char *pretty = NULL;
|
||||
|
||||
return sd_ipv4acd_start(link->dhcp_acd, !in4_addr_equal(&addr, &old));
|
||||
(void) in_addr_to_string(AF_INET, &addr, &pretty);
|
||||
log_link_debug(link, "Starting IPv4ACD client. Probing DHCPv4 address %s", strna(pretty));
|
||||
}
|
||||
|
||||
r = sd_ipv4acd_start(link->dhcp_acd, !in4_addr_equal(&addr.in, &old));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dhcp4_address_ready_callback(Address *address) {
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(address);
|
||||
|
||||
link = address->link;
|
||||
|
||||
/* Do not call this again. */
|
||||
address->callback = NULL;
|
||||
|
||||
dhcp4_check_ready(address->link);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dhcp4_after_address_configure(Request *req, void *object) {
|
||||
Address *address = object;
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->link);
|
||||
assert(req->type == REQUEST_TYPE_ADDRESS);
|
||||
assert(address);
|
||||
|
||||
link = req->link;
|
||||
|
||||
if (!address_equal(link->dhcp_address, address)) {
|
||||
if (link->dhcp_address_old &&
|
||||
!address_equal(link->dhcp_address_old, link->dhcp_address)) {
|
||||
/* Still too old address exists? Let's remove it immediately. */
|
||||
r = address_remove(link->dhcp_address_old, link, NULL);
|
||||
r = link_set_dhcp_routes(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
link->dhcp_address_old = link->dhcp_address;
|
||||
}
|
||||
|
||||
link->dhcp_address = address;
|
||||
/* Reconfigure static routes as kernel may remove some routes when lease expires. */
|
||||
r = link_set_routes(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = dhcp4_start_acd(link);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to start IPv4ACD for DHCPv4 address: %m");
|
||||
return log_link_error_errno(link, r, "Failed to start IPv4ACD for DHCP4 address: %m");
|
||||
|
||||
dhcp4_check_ready(link);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1010,30 +969,36 @@ static int dhcp4_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->dhcp4_messages > 0);
|
||||
|
||||
link->dhcp4_messages--;
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 1;
|
||||
|
||||
r = address_configure_handler_internal(rtnl, m, link, "Could not set DHCPv4 address");
|
||||
if (r <= 0)
|
||||
return r;
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EEXIST) {
|
||||
log_link_message_warning_errno(link, m, r, "Could not set DHCPv4 address");
|
||||
link_enter_failed(link);
|
||||
return 1;
|
||||
} else if (r >= 0)
|
||||
(void) manager_rtnl_process_address(rtnl, m, link->manager);
|
||||
|
||||
if (address_is_ready(link->dhcp_address)) {
|
||||
r = dhcp4_address_ready_callback(link->dhcp_address);
|
||||
if (r < 0)
|
||||
if (r < 0) {
|
||||
link_enter_failed(link);
|
||||
return 1;
|
||||
}
|
||||
} else
|
||||
link->dhcp_address->callback = dhcp4_address_ready_callback;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dhcp4_request_address(Link *link, bool announce) {
|
||||
static int dhcp4_update_address(Link *link, bool announce) {
|
||||
_cleanup_(address_freep) Address *addr = NULL;
|
||||
uint32_t lifetime = CACHE_INFO_INFINITY_LIFE_TIME;
|
||||
struct in_addr address, netmask;
|
||||
unsigned prefixlen;
|
||||
Request *req;
|
||||
Address *ret;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
@ -1042,6 +1007,15 @@ static int dhcp4_request_address(Link *link, bool announce) {
|
||||
if (!link->dhcp_lease)
|
||||
return 0;
|
||||
|
||||
link_set_state(link, LINK_STATE_CONFIGURING);
|
||||
link->dhcp4_configured = false;
|
||||
|
||||
/* address_handler calls link_set_routes() and link_set_nexthop(). Before they are called, the
|
||||
* related flags must be cleared. Otherwise, the link becomes configured state before routes
|
||||
* are configured. */
|
||||
link->static_routes_configured = false;
|
||||
link->static_nexthops_configured = false;
|
||||
|
||||
r = sd_dhcp_lease_get_address(link->dhcp_lease, &address);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "DHCP error: no address: %m");
|
||||
@ -1099,34 +1073,15 @@ static int dhcp4_request_address(Link *link, bool announce) {
|
||||
SET_FLAG(addr->flags, IFA_F_NOPREFIXROUTE, !link_prefixroute(link));
|
||||
addr->route_metric = link->network->dhcp_route_metric;
|
||||
|
||||
if (address_get(link, addr, NULL) < 0)
|
||||
link->dhcp4_configured = false;
|
||||
|
||||
r = link_request_address(link, TAKE_PTR(addr), true, &link->dhcp4_messages,
|
||||
dhcp4_address_handler, &req);
|
||||
/* allow reusing an existing address and simply update its lifetime
|
||||
* in case it already exists */
|
||||
r = address_configure(addr, link, dhcp4_address_handler, &ret);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to request DHCPv4 address: %m");
|
||||
return log_link_error_errno(link, r, "Failed to set DHCPv4 address: %m");
|
||||
|
||||
req->after_configure = dhcp4_after_address_configure;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dhcp4_request_address_and_routes(Link *link, bool announce) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
|
||||
r = dhcp4_request_address(link, announce);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = dhcp4_request_routes(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
link_set_state(link, LINK_STATE_CONFIGURING);
|
||||
link_check_ready(link);
|
||||
if (!address_equal(link->dhcp_address, ret))
|
||||
link->dhcp_address_old = link->dhcp_address;
|
||||
link->dhcp_address = ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1146,7 +1101,7 @@ static int dhcp_lease_renew(sd_dhcp_client *client, Link *link) {
|
||||
link->dhcp_lease = sd_dhcp_lease_ref(lease);
|
||||
link_dirty(link);
|
||||
|
||||
return dhcp4_request_address_and_routes(link, false);
|
||||
return dhcp4_update_address(link, false);
|
||||
}
|
||||
|
||||
static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
|
||||
@ -1211,7 +1166,16 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
|
||||
}
|
||||
}
|
||||
|
||||
return dhcp4_request_address_and_routes(link, true);
|
||||
if (link->dhcp4_remove_messages == 0) {
|
||||
r = dhcp4_update_address(link, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else
|
||||
log_link_debug(link,
|
||||
"The link has previously assigned DHCPv4 address or routes. "
|
||||
"The newly assigned address and routes will set up after old ones are removed.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dhcp_lease_ip_change(sd_dhcp_client *client, Link *link) {
|
||||
|
||||
@ -18,7 +18,6 @@
|
||||
#include "networkd-dhcp6.h"
|
||||
#include "networkd-link.h"
|
||||
#include "networkd-manager.h"
|
||||
#include "networkd-queue.h"
|
||||
#include "networkd-radv.h"
|
||||
#include "siphash24.h"
|
||||
#include "string-table.h"
|
||||
@ -44,7 +43,7 @@ bool link_dhcp6_pd_is_enabled(Link *link) {
|
||||
|
||||
static bool dhcp6_lease_has_pd_prefix(sd_dhcp6_lease *lease) {
|
||||
uint32_t lifetime_preferred, lifetime_valid;
|
||||
struct in6_addr pd_prefix;
|
||||
union in_addr_union pd_prefix;
|
||||
uint8_t pd_prefix_len;
|
||||
|
||||
if (!lease)
|
||||
@ -52,7 +51,7 @@ static bool dhcp6_lease_has_pd_prefix(sd_dhcp6_lease *lease) {
|
||||
|
||||
sd_dhcp6_lease_reset_pd_prefix_iter(lease);
|
||||
|
||||
return sd_dhcp6_lease_get_pd(lease, &pd_prefix, &pd_prefix_len, &lifetime_preferred, &lifetime_valid) >= 0;
|
||||
return sd_dhcp6_lease_get_pd(lease, &pd_prefix.in6, &pd_prefix_len, &lifetime_preferred, &lifetime_valid) >= 0;
|
||||
}
|
||||
|
||||
DHCP6DelegatedPrefix *dhcp6_pd_free(DHCP6DelegatedPrefix *p) {
|
||||
@ -87,21 +86,21 @@ static int dhcp6_pd_compare_func(const DHCP6DelegatedPrefix *a, const DHCP6Deleg
|
||||
|
||||
DEFINE_HASH_OPS(dhcp6_pd_hash_ops, DHCP6DelegatedPrefix, dhcp6_pd_hash_func, dhcp6_pd_compare_func);
|
||||
|
||||
static Link *dhcp6_pd_get_link_by_prefix(Link *link, const struct in6_addr *prefix) {
|
||||
static Link *dhcp6_pd_get_link_by_prefix(Link *link, const union in_addr_union *prefix) {
|
||||
DHCP6DelegatedPrefix *pd;
|
||||
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
assert(prefix);
|
||||
|
||||
pd = hashmap_get(link->manager->dhcp6_prefixes, prefix);
|
||||
pd = hashmap_get(link->manager->dhcp6_prefixes, &prefix->in6);
|
||||
if (!pd)
|
||||
return NULL;
|
||||
|
||||
return pd->link;
|
||||
}
|
||||
|
||||
static int dhcp6_pd_get_assigned_prefix(Link *link, const struct in6_addr *pd_prefix, struct in6_addr *ret_prefix) {
|
||||
static int dhcp6_pd_get_assigned_prefix(Link *link, const union in_addr_union *pd_prefix, union in_addr_union *ret_prefix) {
|
||||
DHCP6DelegatedPrefix *pd, in;
|
||||
|
||||
assert(link);
|
||||
@ -110,7 +109,7 @@ static int dhcp6_pd_get_assigned_prefix(Link *link, const struct in6_addr *pd_pr
|
||||
assert(ret_prefix);
|
||||
|
||||
in = (DHCP6DelegatedPrefix) {
|
||||
.pd_prefix = *pd_prefix,
|
||||
.pd_prefix = pd_prefix->in6,
|
||||
.link = link,
|
||||
};
|
||||
|
||||
@ -118,7 +117,7 @@ static int dhcp6_pd_get_assigned_prefix(Link *link, const struct in6_addr *pd_pr
|
||||
if (!pd)
|
||||
return -ENOENT;
|
||||
|
||||
*ret_prefix = pd->prefix;
|
||||
ret_prefix->in6 = pd->prefix;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -230,7 +229,7 @@ int dhcp6_pd_remove(Link *link) {
|
||||
return r;
|
||||
}
|
||||
|
||||
static int dhcp6_pd_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
static int dhcp6_pd_route_handler(sd_netlink *nl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
@ -238,9 +237,15 @@ static int dhcp6_pd_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link
|
||||
|
||||
link->dhcp6_pd_route_messages--;
|
||||
|
||||
r = route_configure_handler_internal(rtnl, m, link, "Failed to add DHCPv6 Prefix Delegation route");
|
||||
if (r <= 0)
|
||||
return r;
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 1;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EEXIST) {
|
||||
log_link_message_warning_errno(link, m, r, "Failed to add DHCPv6 Prefix Delegation route");
|
||||
link_enter_failed(link);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (link->dhcp6_pd_route_messages == 0) {
|
||||
log_link_debug(link, "DHCPv6 prefix delegation routes set");
|
||||
@ -259,32 +264,11 @@ static int dhcp6_pd_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dhcp6_pd_after_route_configure(Request *req, void *object) {
|
||||
Route *route = object;
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->link);
|
||||
assert(req->type == REQUEST_TYPE_ROUTE);
|
||||
assert(route);
|
||||
|
||||
link = req->link;
|
||||
|
||||
r = set_ensure_put(&link->dhcp6_pd_routes, &route_hash_ops, route);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to store DHCPv6 prefix route: %m");
|
||||
|
||||
set_remove(link->dhcp6_pd_routes_old, route);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dhcp6_pd_request_route(Link *link, const struct in6_addr *prefix, const struct in6_addr *pd_prefix) {
|
||||
static int dhcp6_set_pd_route(Link *link, const union in_addr_union *prefix, const union in_addr_union *pd_prefix) {
|
||||
_cleanup_(dhcp6_pd_freep) DHCP6DelegatedPrefix *pd = NULL;
|
||||
_cleanup_(route_freep) Route *route = NULL;
|
||||
Link *assigned_link;
|
||||
Request *req;
|
||||
Route *ret;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
@ -297,23 +281,24 @@ static int dhcp6_pd_request_route(Link *link, const struct in6_addr *prefix, con
|
||||
return r;
|
||||
|
||||
route->family = AF_INET6;
|
||||
route->dst.in6 = *prefix;
|
||||
route->dst = *prefix;
|
||||
route->dst_prefixlen = 64;
|
||||
route->protocol = RTPROT_DHCP;
|
||||
route->priority = link->network->dhcp6_pd_route_metric;
|
||||
|
||||
r = link_has_route(link, route);
|
||||
r = route_configure(route, link, dhcp6_pd_route_handler, &ret);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return log_link_error_errno(link, r, "Failed to set DHCPv6 prefix route: %m");
|
||||
if (r > 0)
|
||||
link->dhcp6_pd_route_configured = false;
|
||||
|
||||
r = link_request_route(link, TAKE_PTR(route), true, &link->dhcp6_pd_route_messages,
|
||||
dhcp6_pd_route_handler, &req);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to request DHCPv6 prefix route: %m");
|
||||
link->dhcp6_pd_route_messages++;
|
||||
|
||||
req->after_configure = dhcp6_pd_after_route_configure;
|
||||
r = set_ensure_put(&link->dhcp6_pd_routes, &route_hash_ops, ret);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to store DHCPv6 prefix route: %m");
|
||||
|
||||
(void) set_remove(link->dhcp6_pd_routes_old, ret);
|
||||
|
||||
assigned_link = dhcp6_pd_get_link_by_prefix(link, prefix);
|
||||
if (assigned_link) {
|
||||
@ -326,8 +311,8 @@ static int dhcp6_pd_request_route(Link *link, const struct in6_addr *prefix, con
|
||||
return log_oom();
|
||||
|
||||
*pd = (DHCP6DelegatedPrefix) {
|
||||
.prefix = *prefix,
|
||||
.pd_prefix = *pd_prefix,
|
||||
.prefix = prefix->in6,
|
||||
.pd_prefix = pd_prefix->in6,
|
||||
.link = link_ref(link),
|
||||
};
|
||||
|
||||
@ -353,9 +338,16 @@ static int dhcp6_pd_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Lin
|
||||
|
||||
link->dhcp6_pd_address_messages--;
|
||||
|
||||
r = address_configure_handler_internal(rtnl, m, link, "Could not set DHCPv6 delegated prefix address");
|
||||
if (r <= 0)
|
||||
return r;
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 1;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EEXIST) {
|
||||
log_link_message_warning_errno(link, m, r, "Could not set DHCPv6 delegated prefix address");
|
||||
link_enter_failed(link);
|
||||
return 1;
|
||||
} else if (r >= 0)
|
||||
(void) manager_rtnl_process_address(rtnl, m, link->manager);
|
||||
|
||||
if (link->dhcp6_pd_address_messages == 0) {
|
||||
log_link_debug(link, "DHCPv6 delegated prefix addresses set");
|
||||
@ -378,15 +370,12 @@ static void log_dhcp6_pd_address(Link *link, const Address *address) {
|
||||
_cleanup_free_ char *buffer = NULL;
|
||||
int log_level;
|
||||
|
||||
assert(address);
|
||||
assert(address->family == AF_INET6);
|
||||
|
||||
log_level = address_get(link, address, NULL) >= 0 ? LOG_DEBUG : LOG_INFO;
|
||||
|
||||
if (log_level < log_get_max_level())
|
||||
return;
|
||||
|
||||
(void) in6_addr_prefix_to_string(&address->in_addr.in6, address->prefixlen, &buffer);
|
||||
(void) in_addr_prefix_to_string(address->family, &address->in_addr, address->prefixlen, &buffer);
|
||||
if (address->cinfo.ifa_valid != CACHE_INFO_INFINITY_LIFE_TIME)
|
||||
valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX,
|
||||
address->cinfo.ifa_valid * USEC_PER_SEC,
|
||||
@ -402,35 +391,14 @@ static void log_dhcp6_pd_address(Link *link, const Address *address) {
|
||||
preferred_str ? "for " : "forever", strempty(preferred_str));
|
||||
}
|
||||
|
||||
static int dhcp6_pd_after_address_configure(Request *req, void *object) {
|
||||
Address *address = object;
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->link);
|
||||
assert(req->type == REQUEST_TYPE_ADDRESS);
|
||||
assert(address);
|
||||
|
||||
link = req->link;
|
||||
|
||||
r = set_ensure_put(&link->dhcp6_pd_addresses, &address_hash_ops, address);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to store DHCPv6 delegated prefix address: %m");
|
||||
|
||||
set_remove(link->dhcp6_pd_addresses_old, address);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dhcp6_pd_request_address(
|
||||
static int dhcp6_set_pd_address(
|
||||
Link *link,
|
||||
const struct in6_addr *prefix,
|
||||
const union in_addr_union *prefix,
|
||||
uint32_t lifetime_preferred,
|
||||
uint32_t lifetime_valid) {
|
||||
|
||||
_cleanup_(address_freep) Address *address = NULL;
|
||||
Request *req;
|
||||
Address *ret;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
@ -444,10 +412,10 @@ static int dhcp6_pd_request_address(
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to allocate address for DHCPv6 delegated prefix: %m");
|
||||
|
||||
address->in_addr.in6 = *prefix;
|
||||
address->in_addr = *prefix;
|
||||
|
||||
if (in6_addr_is_set(&link->network->dhcp6_pd_token))
|
||||
memcpy(address->in_addr.in6.s6_addr + 8, link->network->dhcp6_pd_token.s6_addr + 8, 8);
|
||||
if (in_addr_is_set(AF_INET6, &link->network->dhcp6_pd_token))
|
||||
memcpy(address->in_addr.in6.s6_addr + 8, link->network->dhcp6_pd_token.in6.s6_addr + 8, 8);
|
||||
else {
|
||||
r = generate_ipv6_eui_64_address(link, &address->in_addr.in6);
|
||||
if (r < 0)
|
||||
@ -462,24 +430,27 @@ static int dhcp6_pd_request_address(
|
||||
address->route_metric = link->network->dhcp6_pd_route_metric;
|
||||
|
||||
log_dhcp6_pd_address(link, address);
|
||||
|
||||
if (address_get(link, address, NULL) < 0)
|
||||
r = address_configure(address, link, dhcp6_pd_address_handler, &ret);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to set DHCPv6 delegated prefix address: %m");
|
||||
if (r > 0)
|
||||
link->dhcp6_pd_address_configured = false;
|
||||
|
||||
r = link_request_address(link, TAKE_PTR(address), true, &link->dhcp6_pd_address_messages,
|
||||
dhcp6_pd_address_handler, &req);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to request DHCPv6 delegated prefix address: %m");
|
||||
link->dhcp6_pd_address_messages++;
|
||||
|
||||
req->after_configure = dhcp6_pd_after_address_configure;
|
||||
r = set_ensure_put(&link->dhcp6_pd_addresses, &address_hash_ops, ret);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to store DHCPv6 delegated prefix address: %m");
|
||||
|
||||
(void) set_remove(link->dhcp6_pd_addresses_old, ret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dhcp6_pd_assign_prefix(
|
||||
Link *link,
|
||||
const struct in6_addr *prefix,
|
||||
const struct in6_addr *pd_prefix,
|
||||
const union in_addr_union *prefix,
|
||||
const union in_addr_union *pd_prefix,
|
||||
uint32_t lifetime_preferred,
|
||||
uint32_t lifetime_valid) {
|
||||
|
||||
@ -490,16 +461,16 @@ static int dhcp6_pd_assign_prefix(
|
||||
assert(prefix);
|
||||
|
||||
if (link->network->dhcp6_pd_announce) {
|
||||
r = radv_add_prefix(link, prefix, 64, lifetime_preferred, lifetime_valid);
|
||||
r = radv_add_prefix(link, &prefix->in6, 64, lifetime_preferred, lifetime_valid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = dhcp6_pd_request_route(link, prefix, pd_prefix);
|
||||
r = dhcp6_set_pd_route(link, prefix, pd_prefix);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = dhcp6_pd_request_address(link, prefix, lifetime_preferred, lifetime_valid);
|
||||
r = dhcp6_set_pd_address(link, prefix, lifetime_preferred, lifetime_valid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -515,9 +486,9 @@ static bool link_has_preferred_subnet_id(Link *link) {
|
||||
|
||||
static int dhcp6_get_preferred_delegated_prefix(
|
||||
Link *link,
|
||||
const struct in6_addr *masked_pd_prefix,
|
||||
const union in_addr_union *masked_pd_prefix,
|
||||
uint8_t pd_prefix_len,
|
||||
struct in6_addr *ret) {
|
||||
union in_addr_union *ret) {
|
||||
|
||||
/* We start off with the original PD prefix we have been assigned and iterate from there */
|
||||
union in_addr_union prefix;
|
||||
@ -531,7 +502,7 @@ static int dhcp6_get_preferred_delegated_prefix(
|
||||
assert(pd_prefix_len <= 64);
|
||||
|
||||
n_prefixes = UINT64_C(1) << (64 - pd_prefix_len);
|
||||
prefix.in6 = *masked_pd_prefix;
|
||||
prefix = *masked_pd_prefix;
|
||||
|
||||
if (link_has_preferred_subnet_id(link)) {
|
||||
uint64_t subnet_id = link->network->dhcp6_pd_subnet_id;
|
||||
@ -550,28 +521,28 @@ static int dhcp6_get_preferred_delegated_prefix(
|
||||
|
||||
/* Verify that the prefix we did calculate fits in the pd prefix.
|
||||
* This should not fail as we checked the prefix size beforehand */
|
||||
assert_se(in_addr_prefix_covers(AF_INET6, (const union in_addr_union*) masked_pd_prefix, pd_prefix_len, &prefix) > 0);
|
||||
assert_se(in_addr_prefix_covers(AF_INET6, masked_pd_prefix, pd_prefix_len, &prefix) > 0);
|
||||
|
||||
assigned_link = dhcp6_pd_get_link_by_prefix(link, &prefix.in6);
|
||||
assigned_link = dhcp6_pd_get_link_by_prefix(link, &prefix);
|
||||
if (assigned_link && assigned_link != link) {
|
||||
_cleanup_free_ char *assigned_buf = NULL;
|
||||
|
||||
(void) in6_addr_to_string(&prefix.in6, &assigned_buf);
|
||||
(void) in_addr_to_string(AF_INET6, &prefix, &assigned_buf);
|
||||
return log_link_warning_errno(link, SYNTHETIC_ERRNO(EAGAIN),
|
||||
"The requested prefix %s is already assigned to another link.",
|
||||
strna(assigned_buf));
|
||||
}
|
||||
|
||||
*ret = prefix.in6;
|
||||
*ret = prefix;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (uint64_t n = 0; n < n_prefixes; n++) {
|
||||
/* If we do not have an allocation preference just iterate
|
||||
* through the address space and return the first free prefix. */
|
||||
assigned_link = dhcp6_pd_get_link_by_prefix(link, &prefix.in6);
|
||||
assigned_link = dhcp6_pd_get_link_by_prefix(link, &prefix);
|
||||
if (!assigned_link || assigned_link == link) {
|
||||
*ret = prefix.in6;
|
||||
*ret = prefix;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -584,7 +555,7 @@ static int dhcp6_get_preferred_delegated_prefix(
|
||||
}
|
||||
|
||||
static void dhcp6_pd_prefix_distribute(Link *dhcp6_link,
|
||||
const struct in6_addr *masked_pd_prefix,
|
||||
const union in_addr_union *masked_pd_prefix,
|
||||
uint8_t pd_prefix_len,
|
||||
uint32_t lifetime_preferred,
|
||||
uint32_t lifetime_valid,
|
||||
@ -600,7 +571,7 @@ static void dhcp6_pd_prefix_distribute(Link *dhcp6_link,
|
||||
|
||||
HASHMAP_FOREACH(link, dhcp6_link->manager->links) {
|
||||
_cleanup_free_ char *assigned_buf = NULL;
|
||||
struct in6_addr assigned_prefix;
|
||||
union in_addr_union assigned_prefix;
|
||||
|
||||
if (link == dhcp6_link)
|
||||
continue;
|
||||
@ -623,7 +594,7 @@ static void dhcp6_pd_prefix_distribute(Link *dhcp6_link,
|
||||
}
|
||||
}
|
||||
|
||||
(void) in6_addr_to_string(&assigned_prefix, &assigned_buf);
|
||||
(void) in_addr_to_string(AF_INET6, &assigned_prefix, &assigned_buf);
|
||||
r = dhcp6_pd_assign_prefix(link, &assigned_prefix, masked_pd_prefix,
|
||||
lifetime_preferred, lifetime_valid);
|
||||
if (r < 0) {
|
||||
@ -688,10 +659,11 @@ static int dhcp6_pd_finalize(Link *link) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!link->dhcp6_pd_address_configured || !link->dhcp6_pd_route_configured)
|
||||
if (link->dhcp6_pd_address_configured && link->dhcp6_pd_route_configured)
|
||||
link_check_ready(link);
|
||||
else
|
||||
link_set_state(link, LINK_STATE_CONFIGURING);
|
||||
|
||||
link_check_ready(link);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -809,7 +781,7 @@ static int dhcp6_remove(Link *link) {
|
||||
return r;
|
||||
}
|
||||
|
||||
static int dhcp6_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
static int dhcp6_route_handler(sd_netlink *nl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
@ -817,9 +789,15 @@ static int dhcp6_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *li
|
||||
|
||||
link->dhcp6_route_messages--;
|
||||
|
||||
r = route_configure_handler_internal(rtnl, m, link, "Failed to set unreachable route for DHCPv6 delegated subnet");
|
||||
if (r <= 0)
|
||||
return r;
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 1;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EEXIST) {
|
||||
log_link_message_warning_errno(link, m, r, "Failed to add unreachable route for DHCPv6 delegated subnet");
|
||||
link_enter_failed(link);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (link->dhcp6_route_messages == 0) {
|
||||
log_link_debug(link, "Unreachable routes for DHCPv6 delegated subnets set");
|
||||
@ -837,37 +815,16 @@ static int dhcp6_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *li
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dhcp6_after_route_configure(Request *req, void *object) {
|
||||
Route *route = object;
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->link);
|
||||
assert(req->type == REQUEST_TYPE_ROUTE);
|
||||
assert(route);
|
||||
|
||||
link = req->link;
|
||||
|
||||
r = set_ensure_put(&link->dhcp6_routes, &route_hash_ops, route);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to store unreachable route for DHCPv6 delegated subnet: %m");
|
||||
|
||||
set_remove(link->dhcp6_routes_old, route);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dhcp6_request_unreachable_route(Link *link, const struct in6_addr *addr, uint8_t prefixlen) {
|
||||
static int dhcp6_set_unreachable_route(Link *link, const union in_addr_union *addr, uint8_t prefixlen) {
|
||||
_cleanup_(route_freep) Route *route = NULL;
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
Request *req;
|
||||
Route *ret;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(addr);
|
||||
|
||||
(void) in6_addr_prefix_to_string(addr, prefixlen, &buf);
|
||||
(void) in_addr_prefix_to_string(AF_INET6, addr, prefixlen, &buf);
|
||||
|
||||
if (prefixlen == 64) {
|
||||
log_link_debug(link, "Not adding a blocking route for DHCPv6 delegated subnet %s since distributed prefix is 64",
|
||||
@ -880,30 +837,32 @@ static int dhcp6_request_unreachable_route(Link *link, const struct in6_addr *ad
|
||||
return log_oom();
|
||||
|
||||
route->family = AF_INET6;
|
||||
route->dst.in6 = *addr;
|
||||
route->dst = *addr;
|
||||
route->dst_prefixlen = prefixlen;
|
||||
route->table = link_get_dhcp_route_table(link);
|
||||
route->type = RTN_UNREACHABLE;
|
||||
route->protocol = RTPROT_DHCP;
|
||||
|
||||
r = link_has_route(link, route);
|
||||
r = route_configure(route, link, dhcp6_route_handler, &ret);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return log_link_error_errno(link, r, "Failed to set unreachable route for DHCPv6 delegated subnet %s: %m",
|
||||
strna(buf));
|
||||
if (r > 0)
|
||||
link->dhcp6_route_configured = false;
|
||||
|
||||
r = link_request_route(link, TAKE_PTR(route), true, &link->dhcp6_route_messages,
|
||||
dhcp6_route_handler, &req);
|
||||
link->dhcp6_route_messages++;
|
||||
|
||||
r = set_ensure_put(&link->dhcp6_routes, &route_hash_ops, ret);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to request unreachable route for DHCPv6 delegated subnet %s: %m",
|
||||
return log_link_error_errno(link, r, "Failed to store unreachable route for DHCPv6 delegated subnet %s: %m",
|
||||
strna(buf));
|
||||
|
||||
req->after_configure = dhcp6_after_route_configure;
|
||||
(void) set_remove(link->dhcp6_routes_old, ret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dhcp6_pd_prefix_add(Link *link, const struct in6_addr *prefix, uint8_t prefixlen) {
|
||||
static int dhcp6_pd_prefix_add(Link *link, const union in_addr_union *prefix, uint8_t prefixlen) {
|
||||
_cleanup_free_ struct in_addr_prefix *p = NULL;
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
int r;
|
||||
@ -918,10 +877,10 @@ static int dhcp6_pd_prefix_add(Link *link, const struct in6_addr *prefix, uint8_
|
||||
*p = (struct in_addr_prefix) {
|
||||
.family = AF_INET6,
|
||||
.prefixlen = prefixlen,
|
||||
.address.in6 = *prefix,
|
||||
.address = *prefix,
|
||||
};
|
||||
|
||||
(void) in6_addr_prefix_to_string(prefix, prefixlen, &buf);
|
||||
(void) in_addr_prefix_to_string(p->family, &p->address, p->prefixlen, &buf);
|
||||
|
||||
log_link_full(link,
|
||||
set_contains(link->dhcp6_pd_prefixes, p) ? LOG_DEBUG :
|
||||
@ -959,11 +918,10 @@ static int dhcp6_pd_prefix_acquired(Link *dhcp6_link) {
|
||||
|
||||
for (sd_dhcp6_lease_reset_pd_prefix_iter(dhcp6_link->dhcp6_lease);;) {
|
||||
uint32_t lifetime_preferred, lifetime_valid;
|
||||
struct in6_addr pd_prefix;
|
||||
union in_addr_union prefix;
|
||||
union in_addr_union pd_prefix, prefix;
|
||||
uint8_t pd_prefix_len;
|
||||
|
||||
r = sd_dhcp6_lease_get_pd(dhcp6_link->dhcp6_lease, &pd_prefix, &pd_prefix_len,
|
||||
r = sd_dhcp6_lease_get_pd(dhcp6_link->dhcp6_lease, &pd_prefix.in6, &pd_prefix_len,
|
||||
&lifetime_preferred, &lifetime_valid);
|
||||
if (r < 0)
|
||||
break;
|
||||
@ -974,7 +932,7 @@ static int dhcp6_pd_prefix_acquired(Link *dhcp6_link) {
|
||||
if (r == 0)
|
||||
continue;
|
||||
|
||||
r = dhcp6_request_unreachable_route(dhcp6_link, &pd_prefix, pd_prefix_len);
|
||||
r = dhcp6_set_unreachable_route(dhcp6_link, &pd_prefix, pd_prefix_len);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -989,7 +947,7 @@ static int dhcp6_pd_prefix_acquired(Link *dhcp6_link) {
|
||||
|
||||
assert(pd_prefix_len <= 64);
|
||||
|
||||
prefix.in6 = pd_prefix;
|
||||
prefix = pd_prefix;
|
||||
r = in_addr_mask(AF_INET6, &prefix, pd_prefix_len);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(dhcp6_link, r, "Failed to mask DHCPv6 PD prefix: %m");
|
||||
@ -998,20 +956,20 @@ static int dhcp6_pd_prefix_acquired(Link *dhcp6_link) {
|
||||
uint64_t n_prefixes = UINT64_C(1) << (64 - pd_prefix_len);
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
|
||||
(void) in6_addr_prefix_to_string(&prefix.in6, pd_prefix_len, &buf);
|
||||
(void) in_addr_prefix_to_string(AF_INET6, &prefix, pd_prefix_len, &buf);
|
||||
log_link_debug(dhcp6_link, "Assigning up to %" PRIu64 " prefixes from %s",
|
||||
n_prefixes, strna(buf));
|
||||
}
|
||||
|
||||
dhcp6_pd_prefix_distribute(dhcp6_link,
|
||||
&prefix.in6,
|
||||
&prefix,
|
||||
pd_prefix_len,
|
||||
lifetime_preferred,
|
||||
lifetime_valid,
|
||||
true);
|
||||
|
||||
dhcp6_pd_prefix_distribute(dhcp6_link,
|
||||
&prefix.in6,
|
||||
&prefix,
|
||||
pd_prefix_len,
|
||||
lifetime_preferred,
|
||||
lifetime_valid,
|
||||
@ -1038,9 +996,16 @@ static int dhcp6_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *
|
||||
|
||||
link->dhcp6_address_messages--;
|
||||
|
||||
r = address_configure_handler_internal(rtnl, m, link, "Could not set DHCPv6 address");
|
||||
if (r <= 0)
|
||||
return r;
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 1;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EEXIST) {
|
||||
log_link_message_warning_errno(link, m, r, "Could not set DHCPv6 address");
|
||||
link_enter_failed(link);
|
||||
return 1;
|
||||
} else if (r >= 0)
|
||||
(void) manager_rtnl_process_address(rtnl, m, link->manager);
|
||||
|
||||
if (link->dhcp6_address_messages == 0) {
|
||||
log_link_debug(link, "DHCPv6 addresses set");
|
||||
@ -1067,9 +1032,8 @@ static void log_dhcp6_address(Link *link, const Address *address, char **ret) {
|
||||
|
||||
assert(link);
|
||||
assert(address);
|
||||
assert(address->family == AF_INET6);
|
||||
|
||||
(void) in6_addr_prefix_to_string(&address->in_addr.in6, address->prefixlen, &buffer);
|
||||
(void) in_addr_prefix_to_string(address->family, &address->in_addr, address->prefixlen, &buffer);
|
||||
if (address->cinfo.ifa_valid != CACHE_INFO_INFINITY_LIFE_TIME)
|
||||
valid_str = format_timespan(valid_buf, FORMAT_TIMESPAN_MAX,
|
||||
address->cinfo.ifa_valid * USEC_PER_SEC,
|
||||
@ -1121,28 +1085,7 @@ finalize:
|
||||
*ret = TAKE_PTR(buffer);
|
||||
}
|
||||
|
||||
static int dhcp6_after_address_configure(Request *req, void *object) {
|
||||
Address *address = object;
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->link);
|
||||
assert(req->type == REQUEST_TYPE_ADDRESS);
|
||||
assert(address);
|
||||
|
||||
link = req->link;
|
||||
|
||||
r = set_ensure_put(&link->dhcp6_addresses, &address_hash_ops, address);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to store DHCPv6 address: %m");
|
||||
|
||||
set_remove(link->dhcp6_addresses_old, address);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dhcp6_request_address(
|
||||
static int dhcp6_update_address(
|
||||
Link *link,
|
||||
const struct in6_addr *ip6_addr,
|
||||
uint32_t lifetime_preferred,
|
||||
@ -1150,7 +1093,7 @@ static int dhcp6_request_address(
|
||||
|
||||
_cleanup_(address_freep) Address *addr = NULL;
|
||||
_cleanup_free_ char *buffer = NULL;
|
||||
Request *req;
|
||||
Address *ret;
|
||||
int r;
|
||||
|
||||
r = address_new(&addr);
|
||||
@ -1166,15 +1109,19 @@ static int dhcp6_request_address(
|
||||
|
||||
log_dhcp6_address(link, addr, &buffer);
|
||||
|
||||
if (address_get(link, addr, NULL) < 0)
|
||||
r = address_configure(addr, link, dhcp6_address_handler, &ret);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to set DHCPv6 address %s: %m", strna(buffer));
|
||||
if (r > 0)
|
||||
link->dhcp6_address_configured = false;
|
||||
|
||||
r = link_request_address(link, TAKE_PTR(addr), true, &link->dhcp6_address_messages,
|
||||
dhcp6_address_handler, &req);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to request DHCPv6 address %s: %m", strna(buffer));
|
||||
link->dhcp6_address_messages++;
|
||||
|
||||
req->after_configure = dhcp6_after_address_configure;
|
||||
r = set_ensure_put(&link->dhcp6_addresses, &address_hash_ops, ret);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to store DHCPv6 address %s: %m", strna(buffer));
|
||||
|
||||
(void) set_remove(link->dhcp6_addresses_old, ret);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1197,7 +1144,7 @@ static int dhcp6_address_acquired(Link *link) {
|
||||
if (r < 0)
|
||||
break;
|
||||
|
||||
r = dhcp6_request_address(link, &ip6_addr, lifetime_preferred, lifetime_valid);
|
||||
r = dhcp6_update_address(link, &ip6_addr, lifetime_preferred, lifetime_valid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
@ -1277,10 +1224,11 @@ static int dhcp6_lease_ip_acquired(sd_dhcp6_client *client, Link *link) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!link->dhcp6_address_configured || !link->dhcp6_route_configured)
|
||||
if (link->dhcp6_address_configured && link->dhcp6_route_configured)
|
||||
link_check_ready(link);
|
||||
else
|
||||
link_set_state(link, LINK_STATE_CONFIGURING);
|
||||
|
||||
link_check_ready(link);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1350,7 +1298,7 @@ static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
|
||||
}
|
||||
}
|
||||
|
||||
int dhcp6_request_information(Link *link, int ir) {
|
||||
int dhcp6_request_address(Link *link, int ir) {
|
||||
int r, inf_req, pd;
|
||||
bool running;
|
||||
|
||||
@ -1428,7 +1376,7 @@ int dhcp6_start(Link *link) {
|
||||
|
||||
log_link_debug(link, "Acquiring DHCPv6 lease");
|
||||
|
||||
return dhcp6_request_information(link, link->network->dhcp6_without_ra == DHCP6_CLIENT_START_MODE_INFORMATION_REQUEST);
|
||||
return dhcp6_request_address(link, link->network->dhcp6_without_ra == DHCP6_CLIENT_START_MODE_INFORMATION_REQUEST);
|
||||
}
|
||||
|
||||
int dhcp6_request_prefix_delegation(Link *link) {
|
||||
@ -1901,8 +1849,7 @@ int config_parse_dhcp6_pd_token(
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
struct in6_addr *addr = data;
|
||||
union in_addr_union tmp;
|
||||
union in_addr_union *addr = data, tmp;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
@ -1911,7 +1858,7 @@ int config_parse_dhcp6_pd_token(
|
||||
assert(data);
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
*addr = (struct in6_addr) {};
|
||||
*addr = IN_ADDR_NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1928,7 +1875,7 @@ int config_parse_dhcp6_pd_token(
|
||||
return 0;
|
||||
}
|
||||
|
||||
*addr = tmp.in6;
|
||||
*addr = tmp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ int dhcp6_pd_remove(Link *link);
|
||||
int dhcp6_configure(Link *link);
|
||||
int dhcp6_update_mac(Link *link);
|
||||
int dhcp6_start(Link *link);
|
||||
int dhcp6_request_information(Link *link, int ir);
|
||||
int dhcp6_request_address(Link *link, int ir);
|
||||
int dhcp6_request_prefix_delegation(Link *link);
|
||||
|
||||
int link_serialize_dhcp6_client(Link *link, FILE *f);
|
||||
|
||||
@ -8,55 +8,39 @@
|
||||
#include "networkd-ipv4ll.h"
|
||||
#include "networkd-link.h"
|
||||
#include "networkd-manager.h"
|
||||
#include "networkd-queue.h"
|
||||
#include "parse-util.h"
|
||||
|
||||
static int address_new_from_ipv4ll(Link *link, Address **ret) {
|
||||
_cleanup_(address_freep) Address *address = NULL;
|
||||
struct in_addr addr;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->ipv4ll);
|
||||
assert(ret);
|
||||
|
||||
r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = address_new(&address);
|
||||
if (r < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
address->family = AF_INET;
|
||||
address->in_addr.in = addr;
|
||||
address->prefixlen = 16;
|
||||
address->broadcast.s_addr = address->in_addr.in.s_addr | htobe32(UINT32_C(0xffffffff) >> address->prefixlen);
|
||||
address->scope = RT_SCOPE_LINK;
|
||||
address->route_metric = IPV4LL_ROUTE_METRIC;
|
||||
|
||||
*ret = TAKE_PTR(address);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ipv4ll_address_lost(Link *link) {
|
||||
_cleanup_(address_freep) Address *address = NULL;
|
||||
struct in_addr addr;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
|
||||
link->ipv4ll_address_configured = false;
|
||||
|
||||
r = address_new_from_ipv4ll(link, &address);
|
||||
if (r == -ENOENT)
|
||||
r = sd_ipv4ll_get_address(link->ipv4ll, &addr);
|
||||
if (r < 0)
|
||||
return 0;
|
||||
|
||||
log_link_debug(link, "IPv4 link-local release "IPV4_ADDRESS_FMT_STR, IPV4_ADDRESS_FMT_VAL(addr));
|
||||
|
||||
r = address_new(&address);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not allocate address: %m");
|
||||
|
||||
address->family = AF_INET;
|
||||
address->in_addr.in = addr;
|
||||
address->prefixlen = 16;
|
||||
address->scope = RT_SCOPE_LINK;
|
||||
|
||||
r = address_remove(address, link, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
log_link_debug(link, "IPv4 link-local release "IPV4_ADDRESS_FMT_STR,
|
||||
IPV4_ADDRESS_FMT_VAL(address->in_addr.in));
|
||||
link_check_ready(link);
|
||||
|
||||
return address_remove(address, link, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ipv4ll_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
@ -65,9 +49,13 @@ static int ipv4ll_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link
|
||||
assert(link);
|
||||
assert(!link->ipv4ll_address_configured);
|
||||
|
||||
r = address_configure_handler_internal(rtnl, m, link, "Could not set ipv4ll address");
|
||||
if (r <= 0)
|
||||
return r;
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EEXIST) {
|
||||
log_link_message_warning_errno(link, m, r, "could not set ipv4ll address");
|
||||
link_enter_failed(link);
|
||||
return 1;
|
||||
} else if (r >= 0)
|
||||
(void) manager_rtnl_process_address(rtnl, m, link->manager);
|
||||
|
||||
link->ipv4ll_address_configured = true;
|
||||
link_check_ready(link);
|
||||
@ -76,7 +64,8 @@ static int ipv4ll_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link
|
||||
}
|
||||
|
||||
static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
|
||||
_cleanup_(address_freep) Address *address = NULL;
|
||||
_cleanup_(address_freep) Address *ll_addr = NULL;
|
||||
struct in_addr address;
|
||||
int r;
|
||||
|
||||
assert(ll);
|
||||
@ -84,16 +73,31 @@ static int ipv4ll_address_claimed(sd_ipv4ll *ll, Link *link) {
|
||||
|
||||
link->ipv4ll_address_configured = false;
|
||||
|
||||
r = address_new_from_ipv4ll(link, &address);
|
||||
r = sd_ipv4ll_get_address(ll, &address);
|
||||
if (r == -ENOENT)
|
||||
return 0;
|
||||
if (r < 0)
|
||||
else if (r < 0)
|
||||
return r;
|
||||
|
||||
log_link_debug(link, "IPv4 link-local claim "IPV4_ADDRESS_FMT_STR,
|
||||
IPV4_ADDRESS_FMT_VAL(address->in_addr.in));
|
||||
IPV4_ADDRESS_FMT_VAL(address));
|
||||
|
||||
return link_request_address(link, TAKE_PTR(address), true, NULL, ipv4ll_address_handler, NULL);
|
||||
r = address_new(&ll_addr);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
ll_addr->family = AF_INET;
|
||||
ll_addr->in_addr.in = address;
|
||||
ll_addr->prefixlen = 16;
|
||||
ll_addr->broadcast.s_addr = ll_addr->in_addr.in.s_addr | htobe32(0xfffffffflu >> ll_addr->prefixlen);
|
||||
ll_addr->scope = RT_SCOPE_LINK;
|
||||
ll_addr->route_metric = IPV4LL_ROUTE_METRIC;
|
||||
|
||||
r = address_configure(ll_addr, link, ipv4ll_address_handler, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ipv4ll_handler(sd_ipv4ll *ll, int event, void *userdata) {
|
||||
|
||||
@ -33,7 +33,6 @@
|
||||
#include "networkd-dhcp6.h"
|
||||
#include "networkd-fdb.h"
|
||||
#include "networkd-ipv4ll.h"
|
||||
#include "networkd-ipv6-proxy-ndp.h"
|
||||
#include "networkd-link-bus.h"
|
||||
#include "networkd-link.h"
|
||||
#include "networkd-lldp-tx.h"
|
||||
@ -42,12 +41,11 @@
|
||||
#include "networkd-ndisc.h"
|
||||
#include "networkd-neighbor.h"
|
||||
#include "networkd-nexthop.h"
|
||||
#include "networkd-queue.h"
|
||||
#include "networkd-sriov.h"
|
||||
#include "networkd-sysctl.h"
|
||||
#include "networkd-radv.h"
|
||||
#include "networkd-routing-policy-rule.h"
|
||||
#include "networkd-sriov.h"
|
||||
#include "networkd-state-file.h"
|
||||
#include "networkd-sysctl.h"
|
||||
#include "networkd-wifi.h"
|
||||
#include "set.h"
|
||||
#include "socket-util.h"
|
||||
@ -135,25 +133,6 @@ bool link_ipv6_enabled(Link *link) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool link_is_ready_to_configure(Link *link, bool allow_unmanaged) {
|
||||
assert(link);
|
||||
|
||||
if (!link->network || link->network->unmanaged) {
|
||||
if (!allow_unmanaged)
|
||||
return false;
|
||||
|
||||
return link_has_carrier(link);
|
||||
}
|
||||
|
||||
if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
|
||||
return false;
|
||||
|
||||
if (!link_has_carrier(link) && !link->network->configure_without_carrier)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool link_is_enslaved(Link *link) {
|
||||
if (link->flags & IFF_SLAVE)
|
||||
/* Even if the link is not managed by networkd, honor IFF_SLAVE flag. */
|
||||
@ -794,9 +773,12 @@ void link_check_ready(Link *link) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!link->static_addresses_configured)
|
||||
if (!link->addresses_configured)
|
||||
return (void) log_link_debug(link, "%s(): static addresses are not configured.", __func__);
|
||||
|
||||
if (!link->neighbors_configured)
|
||||
return (void) log_link_debug(link, "%s(): static neighbors are not configured.", __func__);
|
||||
|
||||
SET_FOREACH(a, link->addresses)
|
||||
if (!address_is_ready(a)) {
|
||||
_cleanup_free_ char *str = NULL;
|
||||
@ -805,16 +787,13 @@ void link_check_ready(Link *link) {
|
||||
return (void) log_link_debug(link, "%s(): an address %s is not ready.", __func__, strna(str));
|
||||
}
|
||||
|
||||
if (!link->static_neighbors_configured)
|
||||
return (void) log_link_debug(link, "%s(): static neighbors are not configured.", __func__);
|
||||
if (!link->static_routes_configured)
|
||||
return (void) log_link_debug(link, "%s(): static routes are not configured.", __func__);
|
||||
|
||||
if (!link->static_nexthops_configured)
|
||||
return (void) log_link_debug(link, "%s(): static nexthops are not configured.", __func__);
|
||||
|
||||
if (!link->static_routes_configured)
|
||||
return (void) log_link_debug(link, "%s(): static routes are not configured.", __func__);
|
||||
|
||||
if (!link->static_routing_policy_rules_configured)
|
||||
if (!link->routing_policy_rules_configured)
|
||||
return (void) log_link_debug(link, "%s(): static routing policy rules are not configured.", __func__);
|
||||
|
||||
if (!link->tc_configured)
|
||||
@ -878,6 +857,15 @@ static int link_set_static_configs(Link *link) {
|
||||
assert(link->network);
|
||||
assert(link->state != _LINK_STATE_INVALID);
|
||||
|
||||
/* Reset all *_configured flags we are configuring. */
|
||||
link->request_static_addresses = false;
|
||||
link->addresses_configured = false;
|
||||
link->addresses_ready = false;
|
||||
link->neighbors_configured = false;
|
||||
link->static_routes_configured = false;
|
||||
link->static_nexthops_configured = false;
|
||||
link->routing_policy_rules_configured = false;
|
||||
|
||||
r = link_set_bridge_fdb(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -886,7 +874,11 @@ static int link_set_static_configs(Link *link) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = link_set_ipv6_proxy_ndp_addresses(link);
|
||||
r = link_set_neighbors(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = link_set_addresses(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -894,23 +886,8 @@ static int link_set_static_configs(Link *link) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = link_request_static_addresses(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = link_request_static_neighbors(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = link_request_static_nexthops(link, false);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = link_request_static_routes(link, false);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = link_request_static_routing_policy_rules(link);
|
||||
/* now that we can figure out a default address for the dhcp server, start it */
|
||||
r = dhcp4_server_configure(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -2051,20 +2028,20 @@ static int link_drop_foreign_config(Link *link) {
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
|
||||
r = link_drop_foreign_routes(link);
|
||||
|
||||
k = link_drop_foreign_nexthops(link);
|
||||
if (k < 0 && r >= 0)
|
||||
r = k;
|
||||
|
||||
k = link_drop_foreign_addresses(link);
|
||||
if (k < 0 && r >= 0)
|
||||
r = k;
|
||||
r = link_drop_foreign_addresses(link);
|
||||
|
||||
k = link_drop_foreign_neighbors(link);
|
||||
if (k < 0 && r >= 0)
|
||||
r = k;
|
||||
|
||||
k = link_drop_foreign_routes(link);
|
||||
if (k < 0 && r >= 0)
|
||||
r = k;
|
||||
|
||||
k = link_drop_foreign_nexthops(link);
|
||||
if (k < 0 && r >= 0)
|
||||
r = k;
|
||||
|
||||
k = manager_drop_foreign_routing_policy_rules(link->manager);
|
||||
if (k < 0 && r >= 0)
|
||||
r = k;
|
||||
@ -2078,20 +2055,20 @@ static int link_drop_config(Link *link) {
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
|
||||
r = link_drop_routes(link);
|
||||
|
||||
k = link_drop_nexthops(link);
|
||||
if (k < 0 && r >= 0)
|
||||
r = k;
|
||||
|
||||
k = link_drop_addresses(link);
|
||||
if (k < 0 && r >= 0)
|
||||
r = k;
|
||||
r = link_drop_addresses(link);
|
||||
|
||||
k = link_drop_neighbors(link);
|
||||
if (k < 0 && r >= 0)
|
||||
r = k;
|
||||
|
||||
k = link_drop_routes(link);
|
||||
if (k < 0 && r >= 0)
|
||||
r = k;
|
||||
|
||||
k = link_drop_nexthops(link);
|
||||
if (k < 0 && r >= 0)
|
||||
r = k;
|
||||
|
||||
k = manager_drop_routing_policy_rules(link->manager, link);
|
||||
if (k < 0 && r >= 0)
|
||||
r = k;
|
||||
@ -2101,17 +2078,6 @@ static int link_drop_config(Link *link) {
|
||||
return r;
|
||||
}
|
||||
|
||||
static void link_drop_requests(Link *link) {
|
||||
Request *req;
|
||||
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
|
||||
ORDERED_SET_FOREACH(req, link->manager->request_queue)
|
||||
if (req->link == link)
|
||||
request_drop(req);
|
||||
}
|
||||
|
||||
int link_configure(Link *link) {
|
||||
int r;
|
||||
|
||||
@ -2266,8 +2232,6 @@ static int link_reconfigure_internal(Link *link, sd_netlink_message *m, bool for
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
link_drop_requests(link);
|
||||
|
||||
r = link_drop_config(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -2700,8 +2664,6 @@ static int link_carrier_lost(Link *link) {
|
||||
return r;
|
||||
}
|
||||
|
||||
link_drop_requests(link);
|
||||
|
||||
r = link_drop_config(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -78,16 +78,13 @@ typedef struct Link {
|
||||
LinkAddressState ipv4_address_state;
|
||||
LinkAddressState ipv6_address_state;
|
||||
|
||||
unsigned address_label_messages;
|
||||
unsigned static_address_messages;
|
||||
unsigned static_neighbor_messages;
|
||||
unsigned static_nexthop_messages;
|
||||
unsigned static_route_messages;
|
||||
unsigned static_routing_policy_rule_messages;
|
||||
unsigned address_messages;
|
||||
unsigned address_remove_messages;
|
||||
unsigned neighbor_remove_messages;
|
||||
unsigned nexthop_remove_messages;
|
||||
unsigned route_remove_messages;
|
||||
unsigned address_label_messages;
|
||||
unsigned neighbor_messages;
|
||||
unsigned route_messages;
|
||||
unsigned nexthop_messages;
|
||||
unsigned routing_policy_rule_messages;
|
||||
unsigned tc_messages;
|
||||
unsigned sr_iov_messages;
|
||||
unsigned enslaving;
|
||||
@ -121,11 +118,13 @@ typedef struct Link {
|
||||
sd_ipv4ll *ipv4ll;
|
||||
bool ipv4ll_address_configured:1;
|
||||
|
||||
bool static_addresses_configured:1;
|
||||
bool static_neighbors_configured:1;
|
||||
bool static_nexthops_configured:1;
|
||||
bool request_static_addresses:1;
|
||||
bool addresses_configured:1;
|
||||
bool addresses_ready:1;
|
||||
bool neighbors_configured:1;
|
||||
bool static_routes_configured:1;
|
||||
bool static_routing_policy_rules_configured:1;
|
||||
bool static_nexthops_configured:1;
|
||||
bool routing_policy_rules_configured:1;
|
||||
bool tc_configured:1;
|
||||
bool sr_iov_configured:1;
|
||||
bool setting_mtu:1;
|
||||
@ -200,8 +199,6 @@ typedef struct Link {
|
||||
|
||||
typedef int (*link_netlink_message_handler_t)(sd_netlink*, sd_netlink_message*, Link*);
|
||||
|
||||
bool link_is_ready_to_configure(Link *link, bool allow_unmanaged);
|
||||
|
||||
void link_ntp_settings_clear(Link *link);
|
||||
void link_dns_settings_clear(Link *link);
|
||||
Link *link_unref(Link *link);
|
||||
|
||||
@ -34,7 +34,6 @@
|
||||
#include "networkd-neighbor.h"
|
||||
#include "networkd-network-bus.h"
|
||||
#include "networkd-nexthop.h"
|
||||
#include "networkd-queue.h"
|
||||
#include "networkd-routing-policy-rule.h"
|
||||
#include "networkd-speed-meter.h"
|
||||
#include "networkd-state-file.h"
|
||||
@ -407,10 +406,6 @@ int manager_new(Manager **ret) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_event_add_post(m->event, NULL, manager_process_requests, m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = manager_connect_rtnl(m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -451,8 +446,6 @@ Manager* manager_free(Manager *m) {
|
||||
HASHMAP_FOREACH(link, m->links)
|
||||
(void) link_stop_engines(link, true);
|
||||
|
||||
m->request_queue = ordered_set_free_with_destructor(m->request_queue, request_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);
|
||||
|
||||
|
||||
@ -62,7 +62,6 @@ struct Manager {
|
||||
char* dynamic_hostname;
|
||||
char* dynamic_timezone;
|
||||
|
||||
unsigned routing_policy_rule_remove_messages;
|
||||
Set *rules;
|
||||
Set *rules_foreign;
|
||||
|
||||
@ -70,12 +69,10 @@ struct Manager {
|
||||
Hashmap *nexthops_by_id;
|
||||
|
||||
/* Manager stores nexthops without RTA_OIF attribute. */
|
||||
unsigned nexthop_remove_messages;
|
||||
Set *nexthops;
|
||||
Set *nexthops_foreign;
|
||||
|
||||
/* Manager stores routes without RTA_OIF attribute. */
|
||||
unsigned route_remove_messages;
|
||||
Set *routes;
|
||||
Set *routes_foreign;
|
||||
|
||||
@ -94,8 +91,6 @@ struct Manager {
|
||||
bool bridge_mdb_on_master_not_supported;
|
||||
|
||||
FirewallContext *fw_ctx;
|
||||
|
||||
OrderedSet *request_queue;
|
||||
};
|
||||
|
||||
int manager_new(Manager **ret);
|
||||
|
||||
@ -15,7 +15,6 @@
|
||||
#include "networkd-dhcp6.h"
|
||||
#include "networkd-manager.h"
|
||||
#include "networkd-ndisc.h"
|
||||
#include "networkd-queue.h"
|
||||
#include "networkd-state-file.h"
|
||||
#include "string-table.h"
|
||||
#include "string-util.h"
|
||||
@ -90,7 +89,6 @@ static int ndisc_address_callback(Address *address) {
|
||||
|
||||
assert(address);
|
||||
assert(address->link);
|
||||
assert(address->family == AF_INET6);
|
||||
|
||||
SET_FOREACH(n, address->link->ndisc_addresses)
|
||||
if (n->address == address) {
|
||||
@ -101,7 +99,7 @@ static int ndisc_address_callback(Address *address) {
|
||||
if (in6_addr_is_null(&router)) {
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
|
||||
(void) in6_addr_prefix_to_string(&address->in_addr.in6, address->prefixlen, &buf);
|
||||
(void) in_addr_prefix_to_string(address->family, &address->in_addr, address->prefixlen, &buf);
|
||||
log_link_debug(address->link, "%s is called for %s, but it is already removed, ignoring.",
|
||||
__func__, strna(buf));
|
||||
return 0;
|
||||
@ -109,7 +107,7 @@ static int ndisc_address_callback(Address *address) {
|
||||
|
||||
/* Make this called only once */
|
||||
SET_FOREACH(n, address->link->ndisc_addresses)
|
||||
if (in6_addr_equal(&n->router, &router))
|
||||
if (IN6_ARE_ADDR_EQUAL(&n->router, &router))
|
||||
n->address->callback = NULL;
|
||||
|
||||
return ndisc_remove_old_one(address->link, &router, true);
|
||||
@ -133,7 +131,7 @@ static int ndisc_remove_old_one(Link *link, const struct in6_addr *router, bool
|
||||
return 0;
|
||||
|
||||
SET_FOREACH(na, link->ndisc_addresses)
|
||||
if (!na->marked && in6_addr_equal(&na->router, router)) {
|
||||
if (!na->marked && IN6_ARE_ADDR_EQUAL(&na->router, router)) {
|
||||
set_callback = true;
|
||||
break;
|
||||
}
|
||||
@ -147,13 +145,13 @@ static int ndisc_remove_old_one(Link *link, const struct in6_addr *router, bool
|
||||
|
||||
if (set_callback) {
|
||||
SET_FOREACH(na, link->ndisc_addresses)
|
||||
if (!na->marked && in6_addr_equal(&na->router, router))
|
||||
if (!na->marked && IN6_ARE_ADDR_EQUAL(&na->router, router))
|
||||
na->address->callback = ndisc_address_callback;
|
||||
|
||||
if (DEBUG_LOGGING) {
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
|
||||
(void) in6_addr_to_string(router, &buf);
|
||||
(void) in_addr_to_string(AF_INET6, (const union in_addr_union*) router, &buf);
|
||||
log_link_debug(link, "No SLAAC address obtained from %s is ready. "
|
||||
"The old NDisc information will be removed later.",
|
||||
strna(buf));
|
||||
@ -165,32 +163,32 @@ static int ndisc_remove_old_one(Link *link, const struct in6_addr *router, bool
|
||||
if (DEBUG_LOGGING) {
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
|
||||
(void) in6_addr_to_string(router, &buf);
|
||||
(void) in_addr_to_string(AF_INET6, (const union in_addr_union*) router, &buf);
|
||||
log_link_debug(link, "Removing old NDisc information obtained from %s.", strna(buf));
|
||||
}
|
||||
|
||||
SET_FOREACH(na, link->ndisc_addresses)
|
||||
if (na->marked && in6_addr_equal(&na->router, router)) {
|
||||
if (na->marked && IN6_ARE_ADDR_EQUAL(&na->router, router)) {
|
||||
k = address_remove(na->address, link, NULL);
|
||||
if (k < 0)
|
||||
r = k;
|
||||
}
|
||||
|
||||
SET_FOREACH(nr, link->ndisc_routes)
|
||||
if (nr->marked && in6_addr_equal(&nr->router, router)) {
|
||||
if (nr->marked && IN6_ARE_ADDR_EQUAL(&nr->router, router)) {
|
||||
k = route_remove(nr->route, NULL, link, NULL);
|
||||
if (k < 0)
|
||||
r = k;
|
||||
}
|
||||
|
||||
SET_FOREACH(rdnss, link->ndisc_rdnss)
|
||||
if (rdnss->marked && in6_addr_equal(&rdnss->router, router)) {
|
||||
if (rdnss->marked && IN6_ARE_ADDR_EQUAL(&rdnss->router, router)) {
|
||||
free(set_remove(link->ndisc_rdnss, rdnss));
|
||||
updated = true;
|
||||
}
|
||||
|
||||
SET_FOREACH(dnssl, link->ndisc_dnssl)
|
||||
if (dnssl->marked && in6_addr_equal(&dnssl->router, router)) {
|
||||
if (dnssl->marked && IN6_ARE_ADDR_EQUAL(&dnssl->router, router)) {
|
||||
free(set_remove(link->ndisc_dnssl, dnssl));
|
||||
updated = true;
|
||||
}
|
||||
@ -306,9 +304,15 @@ static int ndisc_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *li
|
||||
|
||||
link->ndisc_routes_messages--;
|
||||
|
||||
r = route_configure_handler_internal(rtnl, m, link, "Could not set NDisc route");
|
||||
if (r <= 0)
|
||||
return r;
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 1;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EEXIST) {
|
||||
log_link_message_error_errno(link, m, r, "Could not set NDisc route");
|
||||
link_enter_failed(link);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (link->ndisc_routes_messages == 0) {
|
||||
log_link_debug(link, "NDisc routes set.");
|
||||
@ -326,23 +330,24 @@ static int ndisc_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *li
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ndisc_after_route_configure(Request *req, void *object) {
|
||||
static int ndisc_route_configure(Route *route, Link *link, sd_ndisc_router *rt) {
|
||||
_cleanup_free_ NDiscRoute *nr = NULL;
|
||||
NDiscRoute *nr_exist;
|
||||
struct in6_addr router;
|
||||
Route *route = object;
|
||||
sd_ndisc_router *rt;
|
||||
Link *link;
|
||||
Route *ret;
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->link);
|
||||
assert(req->type == REQUEST_TYPE_ROUTE);
|
||||
assert(req->userdata);
|
||||
assert(route);
|
||||
assert(link);
|
||||
assert(rt);
|
||||
|
||||
link = req->link;
|
||||
rt = req->userdata;
|
||||
r = route_configure(route, link, ndisc_route_handler, &ret);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to set NDisc route: %m");
|
||||
if (r > 0)
|
||||
link->ndisc_routes_configured = false;
|
||||
|
||||
link->ndisc_routes_messages++;
|
||||
|
||||
r = sd_ndisc_router_get_address(rt, &router);
|
||||
if (r < 0)
|
||||
@ -354,7 +359,7 @@ static int ndisc_after_route_configure(Request *req, void *object) {
|
||||
|
||||
*nr = (NDiscRoute) {
|
||||
.router = router,
|
||||
.route = route,
|
||||
.route = ret,
|
||||
};
|
||||
|
||||
nr_exist = set_get(link->ndisc_routes, nr);
|
||||
@ -373,39 +378,6 @@ static int ndisc_after_route_configure(Request *req, void *object) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ndisc_request_on_free(Request *req) {
|
||||
assert(req);
|
||||
|
||||
sd_ndisc_router_unref(req->userdata);
|
||||
}
|
||||
|
||||
static int ndisc_request_route(Route *in, Link *link, sd_ndisc_router *rt) {
|
||||
_cleanup_(route_freep) Route *route = in;
|
||||
Request *req;
|
||||
int r;
|
||||
|
||||
assert(route);
|
||||
assert(link);
|
||||
assert(rt);
|
||||
|
||||
r = link_has_route(link, route);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
link->ndisc_routes_configured = false;
|
||||
|
||||
r = link_request_route(link, TAKE_PTR(route), true, &link->ndisc_routes_messages,
|
||||
ndisc_route_handler, &req);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
req->userdata = sd_ndisc_router_ref(rt);
|
||||
req->after_configure = ndisc_after_route_configure;
|
||||
req->on_free = ndisc_request_on_free;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ndisc_address_hash_func(const NDiscAddress *x, struct siphash *state) {
|
||||
address_hash_func(x->address, state);
|
||||
}
|
||||
@ -429,9 +401,16 @@ static int ndisc_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *
|
||||
|
||||
link->ndisc_addresses_messages--;
|
||||
|
||||
r = address_configure_handler_internal(rtnl, m, link, "Could not set NDisc address");
|
||||
if (r <= 0)
|
||||
return r;
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 1;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EEXIST) {
|
||||
log_link_message_error_errno(link, m, r, "Could not set NDisc address");
|
||||
link_enter_failed(link);
|
||||
return 1;
|
||||
} else if (r >= 0)
|
||||
(void) manager_rtnl_process_address(rtnl, m, link->manager);
|
||||
|
||||
if (link->ndisc_addresses_messages == 0) {
|
||||
log_link_debug(link, "NDisc SLAAC addresses set.");
|
||||
@ -447,23 +426,24 @@ static int ndisc_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ndisc_after_address_configure(Request *req, void *object) {
|
||||
static int ndisc_address_configure(Address *address, Link *link, sd_ndisc_router *rt) {
|
||||
_cleanup_free_ NDiscAddress *na = NULL;
|
||||
NDiscAddress *na_exist;
|
||||
struct in6_addr router;
|
||||
sd_ndisc_router *rt;
|
||||
Address *address = object;
|
||||
Link *link;
|
||||
Address *ret;
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->link);
|
||||
assert(req->type == REQUEST_TYPE_ADDRESS);
|
||||
assert(req->userdata);
|
||||
assert(address);
|
||||
assert(link);
|
||||
assert(rt);
|
||||
|
||||
link = req->link;
|
||||
rt = req->userdata;
|
||||
r = address_configure(address, link, ndisc_address_handler, &ret);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to set NDisc SLAAC address: %m");
|
||||
if (r > 0)
|
||||
link->ndisc_addresses_configured = false;
|
||||
|
||||
link->ndisc_addresses_messages++;
|
||||
|
||||
r = sd_ndisc_router_get_address(rt, &router);
|
||||
if (r < 0)
|
||||
@ -475,7 +455,7 @@ static int ndisc_after_address_configure(Request *req, void *object) {
|
||||
|
||||
*na = (NDiscAddress) {
|
||||
.router = router,
|
||||
.address = address,
|
||||
.address = ret,
|
||||
};
|
||||
|
||||
na_exist = set_get(link->ndisc_addresses, na);
|
||||
@ -494,33 +474,9 @@ static int ndisc_after_address_configure(Request *req, void *object) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ndisc_request_address(Address *in, Link *link, sd_ndisc_router *rt) {
|
||||
_cleanup_(address_freep) Address *address = in;
|
||||
Request *req;
|
||||
int r;
|
||||
|
||||
assert(address);
|
||||
assert(link);
|
||||
assert(rt);
|
||||
|
||||
if (address_get(link, address, NULL) < 0)
|
||||
link->ndisc_addresses_configured = false;
|
||||
|
||||
r = link_request_address(link, TAKE_PTR(address), true, &link->ndisc_addresses_messages,
|
||||
ndisc_address_handler, &req);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
req->userdata = sd_ndisc_router_ref(rt);
|
||||
req->after_configure = ndisc_after_address_configure;
|
||||
req->on_free = ndisc_request_on_free;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
|
||||
_cleanup_(route_freep) Route *route = NULL;
|
||||
struct in6_addr gateway;
|
||||
union in_addr_union gateway;
|
||||
uint16_t lifetime;
|
||||
unsigned preference;
|
||||
uint32_t table, mtu;
|
||||
@ -537,17 +493,17 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
|
||||
if (lifetime == 0) /* not a default router */
|
||||
return 0;
|
||||
|
||||
r = sd_ndisc_router_get_address(rt, &gateway);
|
||||
r = sd_ndisc_router_get_address(rt, &gateway.in6);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to get gateway address from RA: %m");
|
||||
|
||||
if (link_has_ipv6_address(link, &gateway) > 0) {
|
||||
if (link_has_ipv6_address(link, &gateway.in6) > 0) {
|
||||
if (DEBUG_LOGGING) {
|
||||
_cleanup_free_ char *buffer = NULL;
|
||||
|
||||
(void) in6_addr_to_string(&gateway, &buffer);
|
||||
(void) in_addr_to_string(AF_INET6, &gateway, &buffer);
|
||||
log_link_debug(link, "No NDisc route added, gateway %s matches local address",
|
||||
strna(buffer));
|
||||
strnull(buffer));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -578,13 +534,13 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
|
||||
route->protocol = RTPROT_RA;
|
||||
route->pref = preference;
|
||||
route->gw_family = AF_INET6;
|
||||
route->gw.in6 = gateway;
|
||||
route->gw = gateway;
|
||||
route->lifetime = usec_add(time_now, lifetime * USEC_PER_SEC);
|
||||
route->mtu = mtu;
|
||||
|
||||
r = ndisc_request_route(TAKE_PTR(route), link, rt);
|
||||
r = ndisc_route_configure(route, link, rt);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not request default route: %m");
|
||||
return log_link_error_errno(link, r, "Could not set default route: %m");
|
||||
|
||||
Route *route_gw;
|
||||
HASHMAP_FOREACH(route_gw, link->network->routes_by_section) {
|
||||
@ -594,26 +550,22 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
|
||||
if (route_gw->gw_family != AF_INET6)
|
||||
continue;
|
||||
|
||||
r = route_dup(route_gw, &route);
|
||||
if (r < 0)
|
||||
return r;
|
||||
route_gw->gw = gateway;
|
||||
if (!route_gw->table_set)
|
||||
route_gw->table = table;
|
||||
if (!route_gw->priority_set)
|
||||
route_gw->priority = link->network->ipv6_accept_ra_route_metric;
|
||||
if (!route_gw->protocol_set)
|
||||
route_gw->protocol = RTPROT_RA;
|
||||
if (!route_gw->pref_set)
|
||||
route_gw->pref = preference;
|
||||
route_gw->lifetime = usec_add(time_now, lifetime * USEC_PER_SEC);
|
||||
if (route_gw->mtu == 0)
|
||||
route_gw->mtu = mtu;
|
||||
|
||||
route->gw.in6 = gateway;
|
||||
if (!route->table_set)
|
||||
route->table = table;
|
||||
if (!route->priority_set)
|
||||
route->priority = link->network->ipv6_accept_ra_route_metric;
|
||||
if (!route->protocol_set)
|
||||
route->protocol = RTPROT_RA;
|
||||
if (!route->pref_set)
|
||||
route->pref = preference;
|
||||
route->lifetime = usec_add(time_now, lifetime * USEC_PER_SEC);
|
||||
if (route->mtu == 0)
|
||||
route->mtu = mtu;
|
||||
|
||||
r = ndisc_request_route(TAKE_PTR(route), link, rt);
|
||||
r = ndisc_route_configure(route_gw, link, rt);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not request gateway: %m");
|
||||
return log_link_error_errno(link, r, "Could not set gateway: %m");
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -698,7 +650,7 @@ static int ndisc_router_generate_addresses(Link *link, struct in6_addr *address,
|
||||
_cleanup_free_ struct in6_addr *new_address = NULL;
|
||||
|
||||
if (j->address_generation_type == IPV6_TOKEN_ADDRESS_GENERATION_PREFIXSTABLE
|
||||
&& (in6_addr_is_null(&j->prefix) || in6_addr_equal(&j->prefix, address))) {
|
||||
&& (in6_addr_is_null(&j->prefix) || 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
|
||||
@ -757,6 +709,7 @@ static int ndisc_router_generate_addresses(Link *link, struct in6_addr *address,
|
||||
static int ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *rt) {
|
||||
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;
|
||||
@ -793,10 +746,6 @@ static int ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *r
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
SET_FOREACH(a, addresses) {
|
||||
_cleanup_(address_freep) Address *address = NULL;
|
||||
Address *existing_address;
|
||||
|
||||
r = address_new(&address);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
@ -805,6 +754,10 @@ static int ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *r
|
||||
address->prefixlen = prefixlen;
|
||||
address->flags = IFA_F_NOPREFIXROUTE|IFA_F_MANAGETEMPADDR;
|
||||
address->cinfo.ifa_prefered = lifetime_preferred;
|
||||
|
||||
SET_FOREACH(a, addresses) {
|
||||
Address *existing_address;
|
||||
|
||||
address->in_addr.in6 = *a;
|
||||
|
||||
/* see RFC4862 section 5.5.3.e */
|
||||
@ -825,9 +778,9 @@ static int ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *r
|
||||
if (address->cinfo.ifa_valid == 0)
|
||||
continue;
|
||||
|
||||
r = ndisc_request_address(TAKE_PTR(address), link, rt);
|
||||
r = ndisc_address_configure(address, link, rt);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not request SLAAC address: %m");
|
||||
return log_link_error_errno(link, r, "Could not set SLAAC address: %m");
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -871,16 +824,16 @@ static int ndisc_router_process_onlink_prefix(Link *link, sd_ndisc_router *rt) {
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to get prefix address: %m");
|
||||
|
||||
r = ndisc_request_route(TAKE_PTR(route), link, rt);
|
||||
r = ndisc_route_configure(route, link, rt);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not request prefix route: %m");;
|
||||
return log_link_error_errno(link, r, "Could not set prefix route: %m");;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ndisc_router_process_route(Link *link, sd_ndisc_router *rt) {
|
||||
_cleanup_(route_freep) Route *route = NULL;
|
||||
struct in6_addr gateway, dst;
|
||||
union in_addr_union gateway, dst;
|
||||
uint32_t lifetime;
|
||||
unsigned preference, prefixlen;
|
||||
usec_t time_now;
|
||||
@ -895,35 +848,35 @@ static int ndisc_router_process_route(Link *link, sd_ndisc_router *rt) {
|
||||
if (lifetime == 0)
|
||||
return 0;
|
||||
|
||||
r = sd_ndisc_router_route_get_address(rt, &dst);
|
||||
r = sd_ndisc_router_route_get_address(rt, &dst.in6);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to get route address: %m");
|
||||
|
||||
if ((!set_isempty(link->network->ndisc_allow_listed_route_prefix) &&
|
||||
!set_contains(link->network->ndisc_allow_listed_route_prefix, &dst)) ||
|
||||
set_contains(link->network->ndisc_deny_listed_route_prefix, &dst)) {
|
||||
!set_contains(link->network->ndisc_allow_listed_route_prefix, &dst.in6)) ||
|
||||
set_contains(link->network->ndisc_deny_listed_route_prefix, &dst.in6)) {
|
||||
if (DEBUG_LOGGING) {
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
|
||||
(void) in6_addr_to_string(&dst, &buf);
|
||||
(void) in_addr_to_string(AF_INET6, &dst, &buf);
|
||||
if (!set_isempty(link->network->ndisc_allow_listed_route_prefix))
|
||||
log_link_debug(link, "Route prefix '%s' is not in allow list, ignoring", strna(buf));
|
||||
log_link_debug(link, "Route prefix '%s' is not in allow list, ignoring", strnull(buf));
|
||||
else
|
||||
log_link_debug(link, "Route prefix '%s' is in deny list, ignoring", strna(buf));
|
||||
log_link_debug(link, "Route prefix '%s' is in deny list, ignoring", strnull(buf));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = sd_ndisc_router_get_address(rt, &gateway);
|
||||
r = sd_ndisc_router_get_address(rt, &gateway.in6);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to get gateway address from RA: %m");
|
||||
|
||||
if (link_has_ipv6_address(link, &gateway) > 0) {
|
||||
if (link_has_ipv6_address(link, &gateway.in6) > 0) {
|
||||
if (DEBUG_LOGGING) {
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
|
||||
(void) in6_addr_to_string(&gateway, &buf);
|
||||
log_link_debug(link, "Advertised route gateway %s is local to the link, ignoring route", strna(buf));
|
||||
(void) in_addr_to_string(AF_INET6, &gateway, &buf);
|
||||
log_link_debug(link, "Advertised route gateway, %s, is local to the link, ignoring route", strnull(buf));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -949,15 +902,15 @@ static int ndisc_router_process_route(Link *link, sd_ndisc_router *rt) {
|
||||
route->priority = link->network->ipv6_accept_ra_route_metric;
|
||||
route->protocol = RTPROT_RA;
|
||||
route->pref = preference;
|
||||
route->gw.in6 = gateway;
|
||||
route->gw = gateway;
|
||||
route->gw_family = AF_INET6;
|
||||
route->dst.in6 = dst;
|
||||
route->dst = dst;
|
||||
route->dst_prefixlen = prefixlen;
|
||||
route->lifetime = usec_add(time_now, lifetime * USEC_PER_SEC);
|
||||
|
||||
r = ndisc_request_route(TAKE_PTR(route), link, rt);
|
||||
r = ndisc_route_configure(route, link, rt);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not request additional route: %m");
|
||||
return log_link_error_errno(link, r, "Could not set additional route: %m");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1006,7 +959,7 @@ static int ndisc_router_process_rdnss(Link *link, sd_ndisc_router *rt) {
|
||||
return log_link_error_errno(link, n, "Failed to get RDNSS addresses: %m");
|
||||
|
||||
SET_FOREACH(rdnss, link->ndisc_rdnss)
|
||||
if (in6_addr_equal(&rdnss->router, &router))
|
||||
if (IN6_ARE_ADDR_EQUAL(&rdnss->router, &router))
|
||||
rdnss->marked = true;
|
||||
|
||||
if (lifetime == 0)
|
||||
@ -1100,7 +1053,7 @@ static int ndisc_router_process_dnssl(Link *link, sd_ndisc_router *rt) {
|
||||
return log_link_error_errno(link, r, "Failed to get DNSSL addresses: %m");
|
||||
|
||||
SET_FOREACH(dnssl, link->ndisc_dnssl)
|
||||
if (in6_addr_equal(&dnssl->router, &router))
|
||||
if (IN6_ARE_ADDR_EQUAL(&dnssl->router, &router))
|
||||
dnssl->marked = true;
|
||||
|
||||
if (lifetime == 0)
|
||||
@ -1166,20 +1119,20 @@ static int ndisc_router_process_options(Link *link, sd_ndisc_router *rt) {
|
||||
switch (type) {
|
||||
|
||||
case SD_NDISC_OPTION_PREFIX_INFORMATION: {
|
||||
struct in6_addr a;
|
||||
union in_addr_union a;
|
||||
uint8_t flags;
|
||||
|
||||
r = sd_ndisc_router_prefix_get_address(rt, &a);
|
||||
r = sd_ndisc_router_prefix_get_address(rt, &a.in6);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to get prefix address: %m");
|
||||
|
||||
if ((!set_isempty(link->network->ndisc_allow_listed_prefix) &&
|
||||
!set_contains(link->network->ndisc_allow_listed_prefix, &a)) ||
|
||||
set_contains(link->network->ndisc_deny_listed_prefix, &a)) {
|
||||
!set_contains(link->network->ndisc_allow_listed_prefix, &a.in6)) ||
|
||||
set_contains(link->network->ndisc_deny_listed_prefix, &a.in6)) {
|
||||
if (DEBUG_LOGGING) {
|
||||
_cleanup_free_ char *b = NULL;
|
||||
|
||||
(void) in6_addr_to_string(&a, &b);
|
||||
(void) in_addr_to_string(AF_INET6, &a, &b);
|
||||
if (!set_isempty(link->network->ndisc_allow_listed_prefix))
|
||||
log_link_debug(link, "Prefix '%s' is not in allow list, ignoring", strna(b));
|
||||
else
|
||||
@ -1234,7 +1187,7 @@ static int ndisc_router_process_options(Link *link, sd_ndisc_router *rt) {
|
||||
}
|
||||
|
||||
static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) {
|
||||
struct in6_addr router;
|
||||
union in_addr_union router;
|
||||
uint64_t flags;
|
||||
NDiscAddress *na;
|
||||
NDiscRoute *nr;
|
||||
@ -1245,17 +1198,17 @@ static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) {
|
||||
assert(link->manager);
|
||||
assert(rt);
|
||||
|
||||
r = sd_ndisc_router_get_address(rt, &router);
|
||||
r = sd_ndisc_router_get_address(rt, &router.in6);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to get router address from RA: %m");
|
||||
|
||||
if ((!set_isempty(link->network->ndisc_allow_listed_router) &&
|
||||
!set_contains(link->network->ndisc_allow_listed_router, &router)) ||
|
||||
set_contains(link->network->ndisc_deny_listed_router, &router)) {
|
||||
!set_contains(link->network->ndisc_allow_listed_router, &router.in6)) ||
|
||||
set_contains(link->network->ndisc_deny_listed_router, &router.in6)) {
|
||||
if (DEBUG_LOGGING) {
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
|
||||
(void) in6_addr_to_string(&router, &buf);
|
||||
(void) in_addr_to_string(AF_INET6, &router, &buf);
|
||||
if (!set_isempty(link->network->ndisc_allow_listed_router))
|
||||
log_link_debug(link, "Router '%s' is not in allow list, ignoring", strna(buf));
|
||||
else
|
||||
@ -1265,11 +1218,11 @@ static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) {
|
||||
}
|
||||
|
||||
SET_FOREACH(na, link->ndisc_addresses)
|
||||
if (in6_addr_equal(&na->router, &router))
|
||||
if (IN6_ARE_ADDR_EQUAL(&na->router, &router.in6))
|
||||
na->marked = true;
|
||||
|
||||
SET_FOREACH(nr, link->ndisc_routes)
|
||||
if (in6_addr_equal(&nr->router, &router))
|
||||
if (IN6_ARE_ADDR_EQUAL(&nr->router, &router.in6))
|
||||
nr->marked = true;
|
||||
|
||||
r = sd_ndisc_router_get_flags(rt, &flags);
|
||||
@ -1282,11 +1235,11 @@ static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) {
|
||||
|
||||
if (flags & (ND_RA_FLAG_MANAGED | ND_RA_FLAG_OTHER))
|
||||
/* (re)start DHCPv6 client in stateful or stateless mode according to RA flags */
|
||||
r = dhcp6_request_information(link, !(flags & ND_RA_FLAG_MANAGED));
|
||||
r = dhcp6_request_address(link, !(flags & ND_RA_FLAG_MANAGED));
|
||||
else
|
||||
/* When IPv6AcceptRA.DHCPv6Client=always, start dhcp6 client in managed mode
|
||||
* even if router does not have M or O flag. */
|
||||
r = dhcp6_request_information(link, false);
|
||||
r = dhcp6_request_address(link, false);
|
||||
if (r < 0 && r != -EBUSY)
|
||||
return log_link_error_errno(link, r, "Could not acquire DHCPv6 lease on NDisc request: %m");
|
||||
else
|
||||
@ -1314,10 +1267,11 @@ static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!link->ndisc_addresses_configured || !link->ndisc_routes_configured)
|
||||
if (link->ndisc_addresses_configured && link->ndisc_routes_configured)
|
||||
link_check_ready(link);
|
||||
else
|
||||
link_set_state(link, LINK_STATE_CONFIGURING);
|
||||
|
||||
link_check_ready(link);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
#include "networkd-manager.h"
|
||||
#include "networkd-neighbor.h"
|
||||
#include "networkd-network.h"
|
||||
#include "networkd-queue.h"
|
||||
#include "set.h"
|
||||
|
||||
Neighbor *neighbor_free(Neighbor *neighbor) {
|
||||
@ -236,12 +235,34 @@ static void log_neighbor_debug(const Neighbor *neighbor, const char *str, const
|
||||
"%s neighbor: lladdr: %s, dst: %s",
|
||||
str, strna(lladdr), strna(dst));
|
||||
}
|
||||
static int neighbor_configure(
|
||||
const Neighbor *neighbor,
|
||||
Link *link,
|
||||
link_netlink_message_handler_t callback,
|
||||
Neighbor **ret) {
|
||||
|
||||
static int neighbor_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(link);
|
||||
assert(link->neighbor_messages > 0);
|
||||
|
||||
link->neighbor_messages--;
|
||||
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 1;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EEXIST)
|
||||
/* Neighbor may not exist yet. So, do not enter failed state here. */
|
||||
log_link_message_warning_errno(link, m, r, "Could not set neighbor, ignoring");
|
||||
|
||||
if (link->neighbor_messages == 0) {
|
||||
log_link_debug(link, "Neighbors set");
|
||||
link->neighbors_configured = true;
|
||||
link_check_ready(link);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int neighbor_configure(Neighbor *neighbor, Link *link) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
|
||||
int r;
|
||||
|
||||
@ -250,7 +271,6 @@ static int neighbor_configure(
|
||||
assert(link->ifindex > 0);
|
||||
assert(link->manager);
|
||||
assert(link->manager->rtnl);
|
||||
assert(callback);
|
||||
|
||||
log_neighbor_debug(neighbor, "Configuring", link);
|
||||
|
||||
@ -271,65 +291,22 @@ static int neighbor_configure(
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append NDA_DST attribute: %m");
|
||||
|
||||
r = neighbor_add(link, neighbor, ret);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not add neighbor: %m");
|
||||
|
||||
r = netlink_call_async(link->manager->rtnl, NULL, req, callback,
|
||||
r = netlink_call_async(link->manager->rtnl, NULL, req, neighbor_configure_handler,
|
||||
link_netlink_destroy_callback, link);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
||||
|
||||
link->neighbor_messages++;
|
||||
link_ref(link);
|
||||
|
||||
r = neighbor_add(link, neighbor, NULL);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not add neighbor: %m");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int static_neighbor_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(link);
|
||||
assert(link->static_neighbor_messages > 0);
|
||||
|
||||
link->static_neighbor_messages--;
|
||||
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 1;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EEXIST) {
|
||||
log_link_message_warning_errno(link, m, r, "Could not set neighbor");
|
||||
link_enter_failed(link);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (link->static_neighbor_messages == 0) {
|
||||
log_link_debug(link, "Neighbors set");
|
||||
link->static_neighbors_configured = true;
|
||||
link_check_ready(link);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int link_request_neighbor(
|
||||
Link *link,
|
||||
Neighbor *neighbor,
|
||||
bool consume_object,
|
||||
unsigned *message_counter,
|
||||
link_netlink_message_handler_t netlink_handler,
|
||||
Request **ret) {
|
||||
|
||||
assert(link);
|
||||
assert(neighbor);
|
||||
|
||||
log_neighbor_debug(neighbor, "Requesting", link);
|
||||
return link_queue_request(link, REQUEST_TYPE_NEIGHBOR, neighbor, consume_object,
|
||||
message_counter, netlink_handler, ret);
|
||||
}
|
||||
|
||||
int link_request_static_neighbors(Link *link) {
|
||||
int link_set_neighbors(Link *link) {
|
||||
Neighbor *neighbor;
|
||||
int r;
|
||||
|
||||
@ -337,20 +314,24 @@ int link_request_static_neighbors(Link *link) {
|
||||
assert(link->network);
|
||||
assert(link->state != _LINK_STATE_INVALID);
|
||||
|
||||
link->static_neighbors_configured = false;
|
||||
|
||||
HASHMAP_FOREACH(neighbor, link->network->neighbors_by_section) {
|
||||
r = link_request_neighbor(link, neighbor, false, &link->static_neighbor_messages,
|
||||
static_neighbor_configure_handler, NULL);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Could not request neighbor: %m");
|
||||
if (link->neighbor_messages != 0) {
|
||||
log_link_debug(link, "Neighbors are configuring.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (link->static_neighbor_messages == 0) {
|
||||
link->static_neighbors_configured = true;
|
||||
link->neighbors_configured = false;
|
||||
|
||||
HASHMAP_FOREACH(neighbor, link->network->neighbors_by_section) {
|
||||
r = neighbor_configure(neighbor, link);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Could not set neighbor: %m");
|
||||
}
|
||||
|
||||
if (link->neighbor_messages == 0) {
|
||||
link->neighbors_configured = true;
|
||||
link_check_ready(link);
|
||||
} else {
|
||||
log_link_debug(link, "Requesting neighbors");
|
||||
log_link_debug(link, "Setting neighbors");
|
||||
link_set_state(link, LINK_STATE_CONFIGURING);
|
||||
}
|
||||
|
||||
@ -362,9 +343,6 @@ static int neighbor_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link
|
||||
|
||||
assert(m);
|
||||
assert(link);
|
||||
assert(link->neighbor_remove_messages > 0);
|
||||
|
||||
link->neighbor_remove_messages--;
|
||||
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 1;
|
||||
@ -404,7 +382,6 @@ static int neighbor_remove(Neighbor *neighbor, Link *link) {
|
||||
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
||||
|
||||
link_ref(link);
|
||||
link->neighbor_remove_messages++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -460,34 +437,6 @@ int link_drop_neighbors(Link *link) {
|
||||
return r;
|
||||
}
|
||||
|
||||
int request_process_neighbor(Request *req) {
|
||||
Neighbor *ret;
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->link);
|
||||
assert(req->neighbor);
|
||||
assert(req->type == REQUEST_TYPE_NEIGHBOR);
|
||||
|
||||
if (!link_is_ready_to_configure(req->link, false))
|
||||
return 0;
|
||||
|
||||
if (req->link->neighbor_remove_messages > 0)
|
||||
return 0;
|
||||
|
||||
r = neighbor_configure(req->neighbor, req->link, req->netlink_handler, &ret);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (req->after_configure) {
|
||||
r = req->after_configure(req, ret);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) {
|
||||
_cleanup_(neighbor_freep) Neighbor *tmp = NULL;
|
||||
_cleanup_free_ void *lladdr = NULL;
|
||||
|
||||
@ -10,10 +10,9 @@
|
||||
#include "in-addr-util.h"
|
||||
#include "networkd-util.h"
|
||||
|
||||
typedef struct Link Link;
|
||||
typedef struct Manager Manager;
|
||||
typedef struct Network Network;
|
||||
typedef struct Request Request;
|
||||
typedef Manager Manager;
|
||||
typedef Network Network;
|
||||
typedef Link Link;
|
||||
|
||||
union lladdr_union {
|
||||
struct ether_addr mac;
|
||||
@ -35,12 +34,10 @@ Neighbor *neighbor_free(Neighbor *neighbor);
|
||||
|
||||
void network_drop_invalid_neighbors(Network *network);
|
||||
|
||||
int link_set_neighbors(Link *link);
|
||||
int link_drop_neighbors(Link *link);
|
||||
int link_drop_foreign_neighbors(Link *link);
|
||||
|
||||
int link_request_static_neighbors(Link *link);
|
||||
int request_process_neighbor(Request *req);
|
||||
|
||||
int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message, Manager *m);
|
||||
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_neighbor_address);
|
||||
|
||||
@ -228,7 +228,7 @@ struct Network {
|
||||
bool dhcp6_pd_manage_temporary_address;
|
||||
int64_t dhcp6_pd_subnet_id;
|
||||
uint32_t dhcp6_pd_route_metric;
|
||||
struct in6_addr dhcp6_pd_token;
|
||||
union in_addr_union dhcp6_pd_token;
|
||||
|
||||
/* Bridge Support */
|
||||
int use_bpdu;
|
||||
|
||||
@ -10,8 +10,6 @@
|
||||
#include "networkd-manager.h"
|
||||
#include "networkd-network.h"
|
||||
#include "networkd-nexthop.h"
|
||||
#include "networkd-queue.h"
|
||||
#include "networkd-route.h"
|
||||
#include "parse-util.h"
|
||||
#include "set.h"
|
||||
#include "string-util.h"
|
||||
@ -358,16 +356,13 @@ static void log_nexthop_debug(const NextHop *nexthop, uint32_t id, const char *s
|
||||
str, nexthop->id, id, strna(gw), yes_no(nexthop->blackhole));
|
||||
}
|
||||
|
||||
static int link_nexthop_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
static int nexthop_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(link);
|
||||
assert(link->nexthop_remove_messages > 0);
|
||||
|
||||
link->nexthop_remove_messages--;
|
||||
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
/* Note that link may be NULL. */
|
||||
if (link && IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 1;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
@ -377,22 +372,6 @@ static int link_nexthop_remove_handler(sd_netlink *rtnl, sd_netlink_message *m,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int manager_nexthop_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Manager *manager) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(manager);
|
||||
assert(manager->nexthop_remove_messages > 0);
|
||||
|
||||
manager->nexthop_remove_messages--;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -ENOENT)
|
||||
log_message_warning_errno(m, r, "Could not drop nexthop, ignoring");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nexthop_remove(const NextHop *nexthop, Manager *manager, Link *link) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
|
||||
int r;
|
||||
@ -417,40 +396,55 @@ static int nexthop_remove(const NextHop *nexthop, Manager *manager, Link *link)
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append NHA_ID attribute: %m");
|
||||
|
||||
if (link)
|
||||
r = netlink_call_async(manager->rtnl, NULL, req, link_nexthop_remove_handler,
|
||||
r = netlink_call_async(manager->rtnl, NULL, req, nexthop_remove_handler,
|
||||
link_netlink_destroy_callback, link);
|
||||
else
|
||||
r = netlink_call_async(manager->rtnl, NULL, req, manager_nexthop_remove_handler,
|
||||
NULL, manager);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
||||
|
||||
link_ref(link); /* link may be NULL, link_ref() is OK with that */
|
||||
|
||||
if (link)
|
||||
link->nexthop_remove_messages++;
|
||||
else
|
||||
manager->nexthop_remove_messages++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nexthop_configure(
|
||||
const NextHop *nexthop,
|
||||
Link *link,
|
||||
link_netlink_message_handler_t callback,
|
||||
NextHop **ret) {
|
||||
static int nexthop_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->nexthop_messages > 0);
|
||||
|
||||
link->nexthop_messages--;
|
||||
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 1;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EEXIST) {
|
||||
log_link_message_warning_errno(link, m, r, "Could not set nexthop");
|
||||
link_enter_failed(link);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (link->nexthop_messages == 0) {
|
||||
log_link_debug(link, "Nexthops set");
|
||||
link->static_nexthops_configured = true;
|
||||
/* Now all nexthops are configured. Let's configure remaining routes. */
|
||||
r = link_set_routes_with_gateway(link);
|
||||
if (r < 0)
|
||||
link_enter_failed(link);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int nexthop_configure(const NextHop *nexthop, Link *link) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
|
||||
int r, k;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
assert(link->manager->rtnl);
|
||||
assert(link->ifindex > 0);
|
||||
assert(IN_SET(nexthop->family, AF_INET, AF_INET6));
|
||||
assert(callback);
|
||||
|
||||
log_nexthop_debug(nexthop, nexthop->id, "Configuring", link);
|
||||
|
||||
@ -488,90 +482,60 @@ static int nexthop_configure(
|
||||
}
|
||||
}
|
||||
|
||||
k = nexthop_add(link, nexthop, ret);
|
||||
if (k < 0)
|
||||
return log_link_error_errno(link, k, "Could not add nexthop: %m");
|
||||
|
||||
r = netlink_call_async(link->manager->rtnl, NULL, req, callback,
|
||||
r = netlink_call_async(link->manager->rtnl, NULL, req, nexthop_handler,
|
||||
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 k;
|
||||
r = nexthop_add(link, nexthop, NULL);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not add nexthop: %m");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int static_nexthop_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->static_nexthop_messages > 0);
|
||||
|
||||
link->static_nexthop_messages--;
|
||||
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 1;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EEXIST) {
|
||||
log_link_message_warning_errno(link, m, r, "Could not set nexthop");
|
||||
link_enter_failed(link);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (link->static_nexthop_messages == 0) {
|
||||
log_link_debug(link, "Nexthops set");
|
||||
link->static_nexthops_configured = true;
|
||||
link_check_ready(link);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int link_request_nexthop(
|
||||
Link *link,
|
||||
NextHop *nexthop,
|
||||
bool consume_object,
|
||||
unsigned *message_counter,
|
||||
link_netlink_message_handler_t netlink_handler,
|
||||
Request **ret) {
|
||||
|
||||
assert(link);
|
||||
assert(nexthop);
|
||||
|
||||
log_nexthop_debug(nexthop, nexthop->id, "Requesting", link);
|
||||
return link_queue_request(link, REQUEST_TYPE_NEXTHOP, nexthop, consume_object,
|
||||
message_counter, netlink_handler, ret);
|
||||
}
|
||||
|
||||
int link_request_static_nexthops(Link *link, bool only_ipv4) {
|
||||
int link_set_nexthops(Link *link) {
|
||||
enum {
|
||||
PHASE_ID, /* First phase: Nexthops with ID */
|
||||
PHASE_WITHOUT_ID, /* Second phase: Nexthops without ID */
|
||||
_PHASE_MAX,
|
||||
} phase;
|
||||
NextHop *nh;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->network);
|
||||
|
||||
if (link->nexthop_messages != 0) {
|
||||
log_link_debug(link, "Nexthops are configuring.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
link->static_nexthops_configured = false;
|
||||
|
||||
for (phase = PHASE_ID; phase < _PHASE_MAX; phase++)
|
||||
HASHMAP_FOREACH(nh, link->network->nexthops_by_section) {
|
||||
if (only_ipv4 && nh->family != AF_INET)
|
||||
if ((nh->id > 0) != (phase == PHASE_ID))
|
||||
continue;
|
||||
|
||||
r = link_request_nexthop(link, nh, false, &link->static_nexthop_messages,
|
||||
static_nexthop_handler, NULL);
|
||||
r = nexthop_configure(nh, link);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Could not request nexthop: %m");
|
||||
return log_link_warning_errno(link, r, "Could not set nexthop: %m");
|
||||
|
||||
link->nexthop_messages++;
|
||||
}
|
||||
|
||||
if (link->static_nexthop_messages == 0) {
|
||||
if (link->nexthop_messages == 0) {
|
||||
link->static_nexthops_configured = true;
|
||||
link_check_ready(link);
|
||||
} else {
|
||||
log_link_debug(link, "Requesting nexthops");
|
||||
link_set_state(link, LINK_STATE_CONFIGURING);
|
||||
/* Finally, configure routes with gateways. */
|
||||
return link_set_routes_with_gateway(link);
|
||||
}
|
||||
|
||||
log_link_debug(link, "Setting nexthops");
|
||||
link_set_state(link, LINK_STATE_CONFIGURING);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -693,73 +657,6 @@ int link_drop_nexthops(Link *link) {
|
||||
return r;
|
||||
}
|
||||
|
||||
static bool nexthop_is_ready_to_configure(Link *link, const NextHop *nexthop) {
|
||||
assert(link);
|
||||
assert(nexthop);
|
||||
|
||||
if (nexthop->blackhole) {
|
||||
if (link->manager->nexthop_remove_messages > 0)
|
||||
return false;
|
||||
} else {
|
||||
Link *l;
|
||||
|
||||
HASHMAP_FOREACH(l, link->manager->links) {
|
||||
if (l->address_remove_messages > 0)
|
||||
return false;
|
||||
if (l->nexthop_remove_messages > 0)
|
||||
return false;
|
||||
if (l->route_remove_messages > 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (nexthop->id == 0) {
|
||||
Request *req;
|
||||
|
||||
ORDERED_SET_FOREACH(req, link->manager->request_queue) {
|
||||
if (req->type != REQUEST_TYPE_NEXTHOP)
|
||||
continue;
|
||||
if (req->nexthop->id != 0)
|
||||
return false; /* first configure nexthop with id. */
|
||||
}
|
||||
}
|
||||
|
||||
if (nexthop->onlink <= 0 &&
|
||||
in_addr_is_set(nexthop->family, &nexthop->gw) &&
|
||||
!manager_address_is_reachable(link->manager, nexthop->family, &nexthop->gw))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int request_process_nexthop(Request *req) {
|
||||
NextHop *ret;
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->link);
|
||||
assert(req->nexthop);
|
||||
assert(req->type == REQUEST_TYPE_NEXTHOP);
|
||||
|
||||
if (!link_is_ready_to_configure(req->link, false))
|
||||
return 0;
|
||||
|
||||
if (!nexthop_is_ready_to_configure(req->link, req->nexthop))
|
||||
return 0;
|
||||
|
||||
r = nexthop_configure(req->nexthop, req->link, req->netlink_handler, &ret);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (req->after_configure) {
|
||||
r = req->after_configure(req, ret);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) {
|
||||
_cleanup_(nexthop_freep) NextHop *tmp = NULL;
|
||||
NextHop *nexthop = NULL;
|
||||
|
||||
@ -15,7 +15,6 @@
|
||||
typedef struct Link Link;
|
||||
typedef struct Manager Manager;
|
||||
typedef struct Network Network;
|
||||
typedef struct Request Request;
|
||||
|
||||
typedef struct NextHop {
|
||||
Network *network;
|
||||
@ -37,12 +36,10 @@ NextHop *nexthop_free(NextHop *nexthop);
|
||||
|
||||
void network_drop_invalid_nexthops(Network *network);
|
||||
|
||||
int link_set_nexthops(Link *link);
|
||||
int link_drop_nexthops(Link *link);
|
||||
int link_drop_foreign_nexthops(Link *link);
|
||||
|
||||
int link_request_static_nexthops(Link *link, bool only_ipv4);
|
||||
int request_process_nexthop(Request *req);
|
||||
|
||||
int manager_get_nexthop_by_id(Manager *manager, uint32_t id, NextHop **ret);
|
||||
int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message, Manager *m);
|
||||
|
||||
|
||||
@ -1,151 +0,0 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "networkd-address.h"
|
||||
#include "networkd-manager.h"
|
||||
#include "networkd-neighbor.h"
|
||||
#include "networkd-nexthop.h"
|
||||
#include "networkd-route.h"
|
||||
#include "networkd-routing-policy-rule.h"
|
||||
#include "networkd-queue.h"
|
||||
|
||||
static void request_free_object(RequestType type, void *object) {
|
||||
switch(type) {
|
||||
case REQUEST_TYPE_ADDRESS:
|
||||
address_free(object);
|
||||
break;
|
||||
case REQUEST_TYPE_NEIGHBOR:
|
||||
neighbor_free(object);
|
||||
break;
|
||||
case REQUEST_TYPE_NEXTHOP:
|
||||
nexthop_free(object);
|
||||
break;
|
||||
case REQUEST_TYPE_ROUTE:
|
||||
route_free(object);
|
||||
break;
|
||||
case REQUEST_TYPE_ROUTING_POLICY_RULE:
|
||||
routing_policy_rule_free(object);
|
||||
break;
|
||||
default:
|
||||
assert_not_reached("invalid request type.");
|
||||
}
|
||||
}
|
||||
|
||||
Request *request_free(Request *req) {
|
||||
if (!req)
|
||||
return NULL;
|
||||
|
||||
if (req->on_free)
|
||||
req->on_free(req);
|
||||
if (req->consume_object)
|
||||
request_free_object(req->type, req->object);
|
||||
if (req->link && req->link->manager)
|
||||
ordered_set_remove(req->link->manager->request_queue, req);
|
||||
link_unref(req->link);
|
||||
|
||||
return mfree(req);
|
||||
}
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(Request*, request_free);
|
||||
|
||||
void request_drop(Request *req) {
|
||||
if (req->message_counter)
|
||||
(*req->message_counter)--;
|
||||
|
||||
request_free(req);
|
||||
}
|
||||
|
||||
int link_queue_request(
|
||||
Link *link,
|
||||
RequestType type,
|
||||
void *object,
|
||||
bool consume_object,
|
||||
unsigned *message_counter,
|
||||
link_netlink_message_handler_t netlink_handler,
|
||||
Request **ret) {
|
||||
|
||||
_cleanup_(request_freep) Request *req = NULL;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
assert(type >= 0 && type < _REQUEST_TYPE_MAX);
|
||||
assert(object);
|
||||
assert(netlink_handler);
|
||||
|
||||
req = new(Request, 1);
|
||||
if (!req) {
|
||||
if (consume_object)
|
||||
request_free_object(type, object);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
*req = (Request) {
|
||||
.link = link,
|
||||
.type = type,
|
||||
.object = object,
|
||||
.consume_object = consume_object,
|
||||
.message_counter = message_counter,
|
||||
.netlink_handler = netlink_handler,
|
||||
};
|
||||
|
||||
link_ref(link);
|
||||
|
||||
r = ordered_set_ensure_put(&link->manager->request_queue, NULL, req);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (req->message_counter)
|
||||
(*req->message_counter)++;
|
||||
|
||||
if (ret)
|
||||
*ret = req;
|
||||
|
||||
TAKE_PTR(req);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int manager_process_requests(sd_event_source *s, void *userdata) {
|
||||
Manager *manager = userdata;
|
||||
int r;
|
||||
|
||||
assert(manager);
|
||||
|
||||
for (;;) {
|
||||
bool processed = false;
|
||||
Request *req;
|
||||
|
||||
ORDERED_SET_FOREACH(req, manager->request_queue) {
|
||||
switch(req->type) {
|
||||
case REQUEST_TYPE_ADDRESS:
|
||||
r = request_process_address(req);
|
||||
break;
|
||||
case REQUEST_TYPE_NEIGHBOR:
|
||||
r = request_process_neighbor(req);
|
||||
break;
|
||||
case REQUEST_TYPE_NEXTHOP:
|
||||
r = request_process_nexthop(req);
|
||||
break;
|
||||
case REQUEST_TYPE_ROUTE:
|
||||
r = request_process_route(req);
|
||||
break;
|
||||
case REQUEST_TYPE_ROUTING_POLICY_RULE:
|
||||
r = request_process_routing_policy_rule(req);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
if (r < 0)
|
||||
link_enter_failed(req->link);
|
||||
if (r > 0) {
|
||||
ordered_set_remove(manager->request_queue, req);
|
||||
request_free(req);
|
||||
processed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!processed)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1,60 +0,0 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "sd-event.h"
|
||||
|
||||
#include "networkd-link.h"
|
||||
|
||||
typedef struct Address Address;
|
||||
typedef struct Neighbor Neighbor;
|
||||
typedef struct NextHop NextHop;
|
||||
typedef struct Route Route;
|
||||
typedef struct RoutingPolicyRule RoutingPolicyRule;
|
||||
|
||||
typedef struct Request Request;
|
||||
|
||||
typedef int (*request_after_configure_handler_t)(Request*, void*);
|
||||
typedef void (*request_on_free_handler_t)(Request*);
|
||||
|
||||
typedef enum RequestType {
|
||||
REQUEST_TYPE_ADDRESS,
|
||||
REQUEST_TYPE_NEIGHBOR,
|
||||
REQUEST_TYPE_NEXTHOP,
|
||||
REQUEST_TYPE_ROUTE,
|
||||
REQUEST_TYPE_ROUTING_POLICY_RULE,
|
||||
_REQUEST_TYPE_MAX,
|
||||
_REQUEST_TYPE_INVALID = -EINVAL,
|
||||
} RequestType;
|
||||
|
||||
typedef struct Request {
|
||||
Link *link;
|
||||
RequestType type;
|
||||
bool consume_object;
|
||||
union {
|
||||
Address *address;
|
||||
Neighbor *neighbor;
|
||||
NextHop *nexthop;
|
||||
Route *route;
|
||||
RoutingPolicyRule *rule;
|
||||
void *object;
|
||||
};
|
||||
void *userdata;
|
||||
unsigned *message_counter;
|
||||
link_netlink_message_handler_t netlink_handler;
|
||||
request_after_configure_handler_t after_configure;
|
||||
request_on_free_handler_t on_free;
|
||||
} Request;
|
||||
|
||||
Request *request_free(Request *req);
|
||||
void request_drop(Request *req);
|
||||
|
||||
int link_queue_request(
|
||||
Link *link,
|
||||
RequestType type,
|
||||
void *object,
|
||||
bool consume_object,
|
||||
unsigned *message_counter,
|
||||
link_netlink_message_handler_t netlink_handler,
|
||||
Request **ret);
|
||||
|
||||
int manager_process_requests(sd_event_source *s, void *userdata);
|
||||
@ -9,8 +9,8 @@
|
||||
#include "networkd-manager.h"
|
||||
#include "networkd-network.h"
|
||||
#include "networkd-nexthop.h"
|
||||
#include "networkd-queue.h"
|
||||
#include "networkd-route.h"
|
||||
#include "networkd-routing-policy-rule.h"
|
||||
#include "parse-util.h"
|
||||
#include "socket-netlink.h"
|
||||
#include "string-table.h"
|
||||
@ -288,7 +288,7 @@ Route *route_free(Route *route) {
|
||||
set_remove(route->manager->routes_foreign, route);
|
||||
}
|
||||
|
||||
ordered_set_free_with_destructor(route->multipath_routes, multipath_route_free);
|
||||
ordered_set_free_free(route->multipath_routes);
|
||||
|
||||
sd_event_source_unref(route->expire);
|
||||
|
||||
@ -510,44 +510,6 @@ static void route_copy(Route *dest, const Route *src, const MultipathRoute *m, c
|
||||
}
|
||||
}
|
||||
|
||||
int route_dup(const Route *src, Route **ret) {
|
||||
_cleanup_(route_freep) Route *dest = NULL;
|
||||
MultipathRoute *m;
|
||||
int r;
|
||||
|
||||
assert(src);
|
||||
assert(ret);
|
||||
|
||||
dest = newdup(Route, src, 1);
|
||||
if (!dest)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Unset all pointers */
|
||||
dest->network = NULL;
|
||||
dest->section = NULL;
|
||||
dest->link = NULL;
|
||||
dest->manager = NULL;
|
||||
dest->multipath_routes = NULL;
|
||||
dest->expire = NULL;
|
||||
|
||||
ORDERED_SET_FOREACH(m, src->multipath_routes) {
|
||||
_cleanup_(multipath_route_freep) MultipathRoute *n = NULL;
|
||||
|
||||
r = multipath_route_dup(m, &n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = ordered_set_ensure_put(&dest->multipath_routes, NULL, n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
TAKE_PTR(n);
|
||||
}
|
||||
|
||||
*ret = TAKE_PTR(dest);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int route_add_internal(Manager *manager, Link *link, Set **routes, const Route *in, Route **ret) {
|
||||
_cleanup_(route_freep) Route *route = NULL;
|
||||
int r;
|
||||
@ -642,115 +604,13 @@ static bool route_type_is_reject(const Route *route) {
|
||||
return IN_SET(route->type, RTN_UNREACHABLE, RTN_PROHIBIT, RTN_BLACKHOLE, RTN_THROW);
|
||||
}
|
||||
|
||||
int link_has_route(Link *link, const Route *route) {
|
||||
MultipathRoute *m;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(route);
|
||||
|
||||
if (route->nexthop_id > 0) {
|
||||
_cleanup_(route_freep) Route *tmp = NULL;
|
||||
NextHop *nh;
|
||||
|
||||
if (manager_get_nexthop_by_id(link->manager, route->nexthop_id, &nh) < 0)
|
||||
return false;
|
||||
|
||||
r = route_new(&tmp);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
route_copy(tmp, route, NULL, nh);
|
||||
|
||||
if (route_type_is_reject(route) || (nh && nh->blackhole))
|
||||
return route_get(link->manager, NULL, tmp, NULL) >= 0;
|
||||
else
|
||||
return route_get(NULL, link, tmp, NULL) >= 0;
|
||||
}
|
||||
|
||||
if (ordered_set_isempty(route->multipath_routes)) {
|
||||
if (route_type_is_reject(route))
|
||||
return route_get(link->manager, NULL, route, NULL) >= 0;
|
||||
else
|
||||
return route_get(NULL, link, route, NULL) >= 0;
|
||||
}
|
||||
|
||||
ORDERED_SET_FOREACH(m, route->multipath_routes) {
|
||||
_cleanup_(route_freep) Route *tmp = NULL;
|
||||
Link *l;
|
||||
|
||||
if (m->ifname) {
|
||||
r = resolve_interface(&link->manager->rtnl, m->ifname);
|
||||
if (r < 0)
|
||||
return false;
|
||||
m->ifindex = r;
|
||||
|
||||
if (link_get(link->manager, m->ifindex, &l) < 0)
|
||||
return false;
|
||||
} else
|
||||
l = link;
|
||||
|
||||
r = route_new(&tmp);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
route_copy(tmp, route, m, NULL);
|
||||
|
||||
if (route_get(NULL, l, tmp, NULL) < 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool route_address_is_reachable(const Route *route, int family, const union in_addr_union *address) {
|
||||
assert(route);
|
||||
assert(IN_SET(family, AF_INET, AF_INET6));
|
||||
assert(address);
|
||||
|
||||
if (route->family != family)
|
||||
return false;
|
||||
|
||||
if (!in_addr_is_set(route->family, &route->dst))
|
||||
return false;
|
||||
|
||||
return in_addr_prefix_intersect(
|
||||
route->family,
|
||||
&route->dst,
|
||||
route->dst_prefixlen,
|
||||
address,
|
||||
FAMILY_ADDRESS_SIZE(family) * 8) > 0;
|
||||
}
|
||||
|
||||
bool manager_address_is_reachable(Manager *manager, int family, const union in_addr_union *address) {
|
||||
Link *link;
|
||||
|
||||
assert(manager);
|
||||
assert(IN_SET(family, AF_INET, AF_INET6));
|
||||
assert(address);
|
||||
|
||||
HASHMAP_FOREACH(link, manager->links) {
|
||||
Route *route;
|
||||
|
||||
SET_FOREACH(route, link->routes)
|
||||
if (route_address_is_reachable(route, family, address))
|
||||
return true;
|
||||
SET_FOREACH(route, link->routes_foreign)
|
||||
if (route_address_is_reachable(route, family, address))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void log_route_debug(const Route *route, const char *str, const Link *link, const Manager *manager) {
|
||||
_cleanup_free_ char *dst = NULL, *src = NULL, *gw_alloc = NULL, *prefsrc = NULL,
|
||||
static void log_route_debug(const Route *route, const char *str, const Link *link, const Manager *m) {
|
||||
_cleanup_free_ char *dst = NULL, *src = NULL, *gw = NULL, *prefsrc = NULL,
|
||||
*table = NULL, *scope = NULL, *proto = NULL;
|
||||
const char *gw = NULL;
|
||||
|
||||
assert(route);
|
||||
assert(str);
|
||||
assert(manager);
|
||||
assert(m);
|
||||
|
||||
/* link may be NULL. */
|
||||
|
||||
@ -761,32 +621,12 @@ static void log_route_debug(const Route *route, const char *str, const Link *lin
|
||||
(void) in_addr_prefix_to_string(route->family, &route->dst, route->dst_prefixlen, &dst);
|
||||
if (in_addr_is_set(route->family, &route->src))
|
||||
(void) in_addr_to_string(route->family, &route->src, &src);
|
||||
if (in_addr_is_set(route->gw_family, &route->gw)) {
|
||||
(void) in_addr_to_string(route->gw_family, &route->gw, &gw_alloc);
|
||||
gw = gw_alloc;
|
||||
} else if (route->gateway_from_dhcp_or_ra) {
|
||||
if (route->gw_family == AF_INET)
|
||||
gw = "_dhcp4";
|
||||
else if (route->gw_family == AF_INET6)
|
||||
gw = "_ipv6ra";
|
||||
} else {
|
||||
MultipathRoute *m;
|
||||
|
||||
ORDERED_SET_FOREACH(m, route->multipath_routes) {
|
||||
_cleanup_free_ char *buf = NULL, *joined = NULL;
|
||||
union in_addr_union a = m->gateway.address;
|
||||
|
||||
(void) in_addr_to_string(m->gateway.family, &a, &buf);
|
||||
joined = strjoin(gw_alloc, gw_alloc ? "," : "", strna(buf), m->ifname ? "@" : "", strempty(m->ifname));
|
||||
if (joined)
|
||||
free_and_replace(gw_alloc, joined);
|
||||
}
|
||||
gw = gw_alloc;
|
||||
}
|
||||
if (in_addr_is_set(route->gw_family, &route->gw))
|
||||
(void) in_addr_to_string(route->gw_family, &route->gw, &gw);
|
||||
if (in_addr_is_set(route->family, &route->prefsrc))
|
||||
(void) in_addr_to_string(route->family, &route->prefsrc, &prefsrc);
|
||||
(void) route_scope_to_string_alloc(route->scope, &scope);
|
||||
(void) manager_get_route_table_to_string(manager, route->table, &table);
|
||||
(void) manager_get_route_table_to_string(m, route->table, &table);
|
||||
(void) route_protocol_full_to_string_alloc(route->protocol, &proto);
|
||||
|
||||
log_link_debug(link,
|
||||
@ -903,42 +743,18 @@ static int route_set_netlink_message(const Route *route, sd_netlink_message *req
|
||||
return 0;
|
||||
}
|
||||
|
||||
int link_route_remove_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg) {
|
||||
static int route_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(link);
|
||||
assert(link->route_remove_messages > 0);
|
||||
assert(error_msg);
|
||||
|
||||
link->route_remove_messages--;
|
||||
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 0;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -ESRCH)
|
||||
log_link_message_warning_errno(link, m, r, error_msg);
|
||||
|
||||
/* Note that link may be NULL. */
|
||||
if (link && IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int link_route_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
return link_route_remove_handler_internal(rtnl, m, link, "Could not drop route, ignoring");
|
||||
}
|
||||
|
||||
static int manager_route_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Manager *manager) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(manager);
|
||||
assert(manager->route_remove_messages > 0);
|
||||
|
||||
manager->route_remove_messages--;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -ESRCH)
|
||||
log_message_warning_errno(m, r, "Could not drop route, ignoring");
|
||||
log_link_message_warning_errno(link, m, r, "Could not drop route, ignoring");
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -958,6 +774,7 @@ int route_remove(
|
||||
|
||||
if (!manager)
|
||||
manager = link->manager;
|
||||
/* link may be NULL! */
|
||||
|
||||
log_route_debug(route, "Removing", link, manager);
|
||||
|
||||
@ -986,29 +803,18 @@ int route_remove(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (link) {
|
||||
r = netlink_call_async(manager->rtnl, NULL, req,
|
||||
callback ?: link_route_remove_handler,
|
||||
callback ?: route_remove_handler,
|
||||
link_netlink_destroy_callback, link);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
||||
|
||||
link_ref(link);
|
||||
link->route_remove_messages++;
|
||||
} else {
|
||||
r = netlink_call_async(manager->rtnl, NULL, req,
|
||||
manager_route_remove_handler,
|
||||
NULL, manager);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Could not send rtnetlink message: %m");
|
||||
|
||||
manager->route_remove_messages++;
|
||||
}
|
||||
link_ref(link); /* link may be NULL, link_ref() is OK with that */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool link_has_static_route(const Link *link, const Route *route) {
|
||||
static bool link_has_route(const Link *link, const Route *route) {
|
||||
Route *net_route;
|
||||
|
||||
assert(link);
|
||||
@ -1024,7 +830,7 @@ static bool link_has_static_route(const Link *link, const Route *route) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool links_have_static_route(const Manager *manager, const Route *route, const Link *except) {
|
||||
static bool links_have_route(const Manager *manager, const Route *route, const Link *except) {
|
||||
Link *link;
|
||||
|
||||
assert(manager);
|
||||
@ -1033,7 +839,7 @@ static bool links_have_static_route(const Manager *manager, const Route *route,
|
||||
if (link == except)
|
||||
continue;
|
||||
|
||||
if (link_has_static_route(link, route))
|
||||
if (link_has_route(link, route))
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1057,7 +863,7 @@ static int manager_drop_routes_internal(Manager *manager, bool foreign, const Li
|
||||
continue;
|
||||
|
||||
/* The route will be configured later, or already configured by a link. */
|
||||
if (links_have_static_route(manager, route, except))
|
||||
if (links_have_route(manager, route, except))
|
||||
continue;
|
||||
|
||||
/* The existing links do not have the route. Let's drop this now. It may be
|
||||
@ -1109,7 +915,7 @@ int link_drop_foreign_routes(Link *link) {
|
||||
FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP))
|
||||
continue;
|
||||
|
||||
if (link_has_static_route(link, route))
|
||||
if (link_has_route(link, route))
|
||||
k = route_add(NULL, link, route, NULL, NULL, NULL);
|
||||
else
|
||||
k = route_remove(route, NULL, link, NULL);
|
||||
@ -1288,36 +1094,14 @@ static int append_nexthops(const Route *route, sd_netlink_message *req) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int route_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(link);
|
||||
assert(error_msg);
|
||||
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 0;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EEXIST) {
|
||||
log_link_message_warning_errno(link, m, r, "Could not set route with gateway");
|
||||
link_enter_failed(link);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int route_configure(
|
||||
int route_configure(
|
||||
const Route *route,
|
||||
Link *link,
|
||||
link_netlink_message_handler_t callback,
|
||||
unsigned *ret_n_routes,
|
||||
Route ***ret_routes) {
|
||||
Route **ret) {
|
||||
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
|
||||
_cleanup_free_ Route **routes = NULL;
|
||||
unsigned n_routes = 0; /* avoid false maybe-uninitialized warning */
|
||||
Route *nr;
|
||||
int r, k;
|
||||
|
||||
assert(link);
|
||||
@ -1326,7 +1110,6 @@ static int route_configure(
|
||||
assert(link->ifindex > 0);
|
||||
assert(IN_SET(route->family, AF_INET, AF_INET6));
|
||||
assert(callback);
|
||||
assert(!!ret_n_routes == !!ret_routes);
|
||||
|
||||
if (route_get(link->manager, link, route, NULL) <= 0 &&
|
||||
set_size(link->routes) >= routes_max())
|
||||
@ -1409,36 +1192,21 @@ static int route_configure(
|
||||
if (route->nexthop_id != 0 ||
|
||||
in_addr_is_set(route->gw_family, &route->gw) ||
|
||||
ordered_set_isempty(route->multipath_routes)) {
|
||||
|
||||
if (ret_routes) {
|
||||
n_routes = 1;
|
||||
routes = new(Route*, n_routes);
|
||||
if (!routes)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
k = route_add_and_setup_timer(link, route, NULL, routes);
|
||||
k = route_add_and_setup_timer(link, route, NULL, &nr);
|
||||
if (k < 0)
|
||||
return k;
|
||||
} else {
|
||||
MultipathRoute *m;
|
||||
Route **p;
|
||||
|
||||
r = append_nexthops(route, req);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_MULTIPATH attribute: %m");
|
||||
|
||||
if (ret_routes) {
|
||||
n_routes = ordered_set_size(route->multipath_routes);
|
||||
routes = new(Route*, n_routes);
|
||||
if (!routes)
|
||||
return log_oom();
|
||||
}
|
||||
assert(!ret);
|
||||
|
||||
k = 0;
|
||||
p = routes;
|
||||
ORDERED_SET_FOREACH(m, route->multipath_routes) {
|
||||
r = route_add_and_setup_timer(link, route, m, ret_routes ? p++ : NULL);
|
||||
r = route_add_and_setup_timer(link, route, m, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r > 0)
|
||||
@ -1453,28 +1221,32 @@ static int route_configure(
|
||||
|
||||
link_ref(link);
|
||||
|
||||
if (ret_routes) {
|
||||
*ret_n_routes = n_routes;
|
||||
*ret_routes = TAKE_PTR(routes);
|
||||
}
|
||||
if (ret)
|
||||
*ret = nr;
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
static int static_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
static int route_handler_with_gateway(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->static_route_messages > 0);
|
||||
assert(link->route_messages > 0);
|
||||
|
||||
link->static_route_messages--;
|
||||
link->route_messages--;
|
||||
|
||||
r = route_configure_handler_internal(rtnl, m, link, "Could not set route");
|
||||
if (r <= 0)
|
||||
return r;
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 1;
|
||||
|
||||
if (link->static_route_messages == 0) {
|
||||
log_link_debug(link, "Routes set");
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EEXIST) {
|
||||
log_link_message_warning_errno(link, m, r, "Could not set route with gateway");
|
||||
link_enter_failed(link);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (link->route_messages == 0) {
|
||||
log_link_debug(link, "Routes with gateway set");
|
||||
link->static_routes_configured = true;
|
||||
link_check_ready(link);
|
||||
}
|
||||
@ -1482,157 +1254,140 @@ static int static_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *l
|
||||
return 1;
|
||||
}
|
||||
|
||||
int link_request_route(
|
||||
Link *link,
|
||||
Route *route,
|
||||
bool consume_object,
|
||||
unsigned *message_counter,
|
||||
link_netlink_message_handler_t netlink_handler,
|
||||
Request **ret) {
|
||||
static int route_handler_without_gateway(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
assert(route);
|
||||
assert(link->route_messages > 0);
|
||||
|
||||
log_route_debug(route, "Requesting", link, link->manager);
|
||||
return link_queue_request(link, REQUEST_TYPE_ROUTE, route, consume_object,
|
||||
message_counter, netlink_handler, ret);
|
||||
link->route_messages--;
|
||||
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 1;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EEXIST) {
|
||||
log_link_message_warning_errno(link, m, r, "Could not set route without gateway");
|
||||
link_enter_failed(link);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int link_request_static_routes(Link *link, bool only_ipv4) {
|
||||
Route *route;
|
||||
if (link->route_messages == 0) {
|
||||
log_link_debug(link, "Routes set without gateway");
|
||||
/* Now, we can talk to gateways, let's configure nexthops. */
|
||||
r = link_set_nexthops(link);
|
||||
if (r < 0)
|
||||
link_enter_failed(link);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool route_has_gateway(const Route *route) {
|
||||
assert(route);
|
||||
|
||||
if (in_addr_is_set(route->gw_family, &route->gw))
|
||||
return true;
|
||||
|
||||
if (!ordered_set_isempty(route->multipath_routes))
|
||||
return true;
|
||||
|
||||
if (route->nexthop_id > 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int link_set_routes_internal(Link *link, bool with_gateway) {
|
||||
Route *rt;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->network);
|
||||
|
||||
link->static_routes_configured = false;
|
||||
|
||||
HASHMAP_FOREACH(route, link->network->routes_by_section) {
|
||||
if (route->gateway_from_dhcp_or_ra)
|
||||
HASHMAP_FOREACH(rt, link->network->routes_by_section) {
|
||||
if (rt->gateway_from_dhcp_or_ra)
|
||||
continue;
|
||||
|
||||
if (only_ipv4 && route->family != AF_INET)
|
||||
if (route_has_gateway(rt) != with_gateway)
|
||||
continue;
|
||||
|
||||
r = link_request_route(link, route, false, &link->static_route_messages,
|
||||
static_route_handler, NULL);
|
||||
r = route_configure(rt, link, with_gateway ? route_handler_with_gateway : route_handler_without_gateway, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
return log_link_warning_errno(link, r, "Could not set routes: %m");
|
||||
|
||||
link->route_messages++;
|
||||
}
|
||||
|
||||
if (link->static_route_messages == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int link_set_routes_with_gateway(Link *link) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->network);
|
||||
|
||||
if (!link_has_carrier(link) && !link->network->configure_without_carrier)
|
||||
/* During configuring addresses, the link lost its carrier. As networkd is dropping
|
||||
* the addresses now, let's not configure the routes either. */
|
||||
return 0;
|
||||
|
||||
/* Finally, add routes that needs a gateway. */
|
||||
r = link_set_routes_internal(link, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (link->route_messages == 0) {
|
||||
link->static_routes_configured = true;
|
||||
link_check_ready(link);
|
||||
} else {
|
||||
log_link_debug(link, "Requesting routes");
|
||||
log_link_debug(link, "Setting routes with gateway");
|
||||
link_set_state(link, LINK_STATE_CONFIGURING);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int route_is_ready_to_configure(const Route *route, Link *link) {
|
||||
MultipathRoute *m;
|
||||
NextHop *nh = NULL;
|
||||
int link_set_routes(Link *link) {
|
||||
int r;
|
||||
|
||||
assert(route);
|
||||
assert(link);
|
||||
assert(link->network);
|
||||
assert(link->state != _LINK_STATE_INVALID);
|
||||
|
||||
if (route->nexthop_id > 0 &&
|
||||
manager_get_nexthop_by_id(link->manager, route->nexthop_id, &nh) < 0)
|
||||
return false;
|
||||
link->static_routes_configured = false;
|
||||
|
||||
if (route_type_is_reject(route) || (nh && nh->blackhole)) {
|
||||
if (nh && link->manager->nexthop_remove_messages > 0)
|
||||
return false;
|
||||
if (link->manager->route_remove_messages > 0)
|
||||
return false;
|
||||
} else {
|
||||
Link *l;
|
||||
|
||||
HASHMAP_FOREACH(l, link->manager->links) {
|
||||
if (l->address_remove_messages > 0)
|
||||
return false;
|
||||
if (l->nexthop_remove_messages > 0)
|
||||
return false;
|
||||
if (l->route_remove_messages > 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (in_addr_is_set(route->family, &route->prefsrc) > 0) {
|
||||
r = manager_has_address(link->manager, route->family, &route->prefsrc, route->family == AF_INET6);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (route->gateway_onlink <= 0 &&
|
||||
in_addr_is_set(route->gw_family, &route->gw) > 0 &&
|
||||
!manager_address_is_reachable(link->manager, route->gw_family, &route->gw))
|
||||
return false;
|
||||
|
||||
ORDERED_SET_FOREACH(m, route->multipath_routes) {
|
||||
union in_addr_union a = m->gateway.address;
|
||||
|
||||
if (route->gateway_onlink <= 0 &&
|
||||
!manager_address_is_reachable(link->manager, m->gateway.family, &a))
|
||||
return false;
|
||||
|
||||
if (m->ifname) {
|
||||
Link *l;
|
||||
|
||||
r = resolve_interface(&link->manager->rtnl, m->ifname);
|
||||
if (r < 0)
|
||||
return false;
|
||||
m->ifindex = r;
|
||||
|
||||
if (link_get(link->manager, m->ifindex, &l) < 0)
|
||||
return false;
|
||||
|
||||
if (!link_is_ready_to_configure(l, true))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int request_process_route(Request *req) {
|
||||
_cleanup_free_ Route **routes = NULL;
|
||||
unsigned n_routes;
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->link);
|
||||
assert(req->route);
|
||||
assert(req->type == REQUEST_TYPE_ROUTE);
|
||||
|
||||
if (!link_is_ready_to_configure(req->link, false))
|
||||
if (!link->addresses_ready)
|
||||
return 0;
|
||||
|
||||
r = route_is_ready_to_configure(req->route, req->link);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
if (!link_has_carrier(link) && !link->network->configure_without_carrier)
|
||||
/* During configuring addresses, the link lost its carrier. As networkd is dropping
|
||||
* the addresses now, let's not configure the routes either. */
|
||||
return 0;
|
||||
|
||||
r = route_configure(req->route, req->link, req->netlink_handler,
|
||||
req->after_configure ? &n_routes : NULL,
|
||||
req->after_configure ? &routes : NULL);
|
||||
if (link->route_messages != 0) {
|
||||
log_link_debug(link, "Static routes are configuring.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = link_set_routing_policy_rules(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (req->after_configure) {
|
||||
assert(n_routes > 0);
|
||||
|
||||
for (unsigned i = 0; i < n_routes; i++) {
|
||||
r = req->after_configure(req, routes[i]);
|
||||
/* First, add the routes that enable us to talk to gateways. */
|
||||
r = link_set_routes_internal(link, false);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
if (link->route_messages == 0)
|
||||
/* If no route is configured, then configure nexthops. */
|
||||
return link_set_nexthops(link);
|
||||
|
||||
log_link_debug(link, "Setting routes without gateway");
|
||||
link_set_state(link, LINK_STATE_CONFIGURING);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int process_route_one(Manager *manager, Link *link, uint16_t type, const Route *tmp, const MultipathRoute *m) {
|
||||
@ -2705,14 +2460,13 @@ int config_parse_multipath_route(
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
_cleanup_(multipath_route_freep) MultipathRoute *m = NULL;
|
||||
_cleanup_(route_free_or_set_invalidp) Route *n = NULL;
|
||||
_cleanup_free_ char *word = NULL;
|
||||
_cleanup_free_ char *word = NULL, *buf = NULL;
|
||||
_cleanup_free_ MultipathRoute *m = NULL;
|
||||
Network *network = userdata;
|
||||
const char *p, *ip, *dev;
|
||||
union in_addr_union a;
|
||||
int family, r;
|
||||
const char *p;
|
||||
char *dev;
|
||||
|
||||
assert(filename);
|
||||
assert(section);
|
||||
@ -2730,7 +2484,7 @@ int config_parse_multipath_route(
|
||||
}
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
n->multipath_routes = ordered_set_free_with_destructor(n->multipath_routes, multipath_route_free);
|
||||
n->multipath_routes = ordered_set_free_free(n->multipath_routes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2750,14 +2504,15 @@ int config_parse_multipath_route(
|
||||
|
||||
dev = strchr(word, '@');
|
||||
if (dev) {
|
||||
*dev++ = '\0';
|
||||
|
||||
m->ifname = strdup(dev);
|
||||
if (!m->ifname)
|
||||
buf = strndup(word, dev - word);
|
||||
if (!buf)
|
||||
return log_oom();
|
||||
}
|
||||
ip = buf;
|
||||
dev++;
|
||||
} else
|
||||
ip = word;
|
||||
|
||||
r = in_addr_from_string_auto(word, &family, &a);
|
||||
r = in_addr_from_string_auto(ip, &family, &a);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Invalid multipath route gateway '%s', ignoring assignment: %m", rvalue);
|
||||
@ -2766,6 +2521,16 @@ int config_parse_multipath_route(
|
||||
m->gateway.address = a;
|
||||
m->gateway.family = family;
|
||||
|
||||
if (dev) {
|
||||
r = resolve_interface(NULL, dev);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Invalid interface name or index, ignoring assignment: %s", dev);
|
||||
return 0;
|
||||
}
|
||||
m->ifindex = r;
|
||||
}
|
||||
|
||||
if (!isempty(p)) {
|
||||
r = safe_atou32(p, &m->weight);
|
||||
if (r < 0) {
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "sd-netlink.h"
|
||||
|
||||
@ -13,7 +14,6 @@
|
||||
|
||||
typedef struct Manager Manager;
|
||||
typedef struct Network Network;
|
||||
typedef struct Request Request;
|
||||
|
||||
typedef struct Route {
|
||||
Network *network;
|
||||
@ -71,31 +71,18 @@ extern const struct hash_ops route_hash_ops;
|
||||
int route_new(Route **ret);
|
||||
Route *route_free(Route *route);
|
||||
DEFINE_NETWORK_SECTION_FUNCTIONS(Route, route_free);
|
||||
int route_dup(const Route *src, Route **ret);
|
||||
|
||||
int route_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg);
|
||||
int link_route_remove_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, const char *error_msg);
|
||||
int route_configure(const Route *route, Link *link, link_netlink_message_handler_t callback, Route **ret);
|
||||
int route_remove(const Route *route, Manager *manager, Link *link, link_netlink_message_handler_t callback);
|
||||
|
||||
int link_has_route(Link *link, const Route *route);
|
||||
bool manager_address_is_reachable(Manager *manager, int family, const union in_addr_union *address);
|
||||
|
||||
int link_set_routes(Link *link);
|
||||
int link_set_routes_with_gateway(Link *link);
|
||||
int link_drop_routes(Link *link);
|
||||
int link_drop_foreign_routes(Link *link);
|
||||
|
||||
uint32_t link_get_dhcp_route_table(const Link *link);
|
||||
uint32_t link_get_ipv6_accept_ra_route_table(const Link *link);
|
||||
|
||||
int link_request_route(
|
||||
Link *link,
|
||||
Route *route,
|
||||
bool consume_object,
|
||||
unsigned *message_counter,
|
||||
link_netlink_message_handler_t netlink_handler,
|
||||
Request **ret);
|
||||
int link_request_static_routes(Link *link, bool only_ipv4);
|
||||
int request_process_route(Request *req);
|
||||
|
||||
int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, Manager *m);
|
||||
|
||||
int network_add_ipv4ll_route(Network *network);
|
||||
|
||||
@ -12,8 +12,6 @@
|
||||
#include "ip-protocol-list.h"
|
||||
#include "netlink-util.h"
|
||||
#include "networkd-manager.h"
|
||||
#include "networkd-queue.h"
|
||||
#include "networkd-route.h"
|
||||
#include "networkd-routing-policy-rule.h"
|
||||
#include "networkd-util.h"
|
||||
#include "parse-util.h"
|
||||
@ -111,35 +109,45 @@ static int routing_policy_rule_new_static(Network *network, const char *filename
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int routing_policy_rule_dup(const RoutingPolicyRule *src, RoutingPolicyRule **ret) {
|
||||
_cleanup_(routing_policy_rule_freep) RoutingPolicyRule *dest = NULL;
|
||||
static int routing_policy_rule_copy(RoutingPolicyRule *dest, const RoutingPolicyRule *src) {
|
||||
_cleanup_free_ char *iif = NULL, *oif = NULL;
|
||||
|
||||
assert(dest);
|
||||
assert(src);
|
||||
assert(ret);
|
||||
|
||||
dest = newdup(RoutingPolicyRule, src, 1);
|
||||
if (!dest)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Unset all pointers */
|
||||
dest->manager = NULL;
|
||||
dest->network = NULL;
|
||||
dest->section = NULL;
|
||||
dest->iif = dest->oif = NULL;
|
||||
|
||||
if (src->iif) {
|
||||
dest->iif = strdup(src->iif);
|
||||
if (!dest->iif)
|
||||
iif = strdup(src->iif);
|
||||
if (!iif)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (src->oif) {
|
||||
dest->oif = strdup(src->oif);
|
||||
if (!dest->oif)
|
||||
oif = strdup(src->oif);
|
||||
if (!oif)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
*ret = TAKE_PTR(dest);
|
||||
dest->family = src->family;
|
||||
dest->from = src->from;
|
||||
dest->from_prefixlen = src->from_prefixlen;
|
||||
dest->to = src->to;
|
||||
dest->to_prefixlen = src->to_prefixlen;
|
||||
dest->invert_rule = src->invert_rule;
|
||||
dest->tos = src->tos;
|
||||
dest->type = src->type;
|
||||
dest->fwmark = src->fwmark;
|
||||
dest->fwmask = src->fwmask;
|
||||
dest->priority = src->priority;
|
||||
dest->table = src->table;
|
||||
dest->iif = TAKE_PTR(iif);
|
||||
dest->oif = TAKE_PTR(oif);
|
||||
dest->ipproto = src->ipproto;
|
||||
dest->protocol = src->protocol;
|
||||
dest->sport = src->sport;
|
||||
dest->dport = src->dport;
|
||||
dest->uid_range = src->uid_range;
|
||||
dest->suppress_prefixlen = src->suppress_prefixlen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -315,7 +323,7 @@ static int routing_policy_rule_get(Manager *m, const RoutingPolicyRule *rule, Ro
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static int routing_policy_rule_add(Manager *m, const RoutingPolicyRule *in, RoutingPolicyRule **ret) {
|
||||
static int routing_policy_rule_add(Manager *m, const RoutingPolicyRule *in, int family, RoutingPolicyRule **ret) {
|
||||
_cleanup_(routing_policy_rule_freep) RoutingPolicyRule *rule = NULL;
|
||||
RoutingPolicyRule *existing;
|
||||
bool is_new = false;
|
||||
@ -323,12 +331,19 @@ static int routing_policy_rule_add(Manager *m, const RoutingPolicyRule *in, Rout
|
||||
|
||||
assert(m);
|
||||
assert(in);
|
||||
assert(IN_SET(in->family, AF_INET, AF_INET6));
|
||||
assert(IN_SET(family, AF_INET, AF_INET6));
|
||||
assert(in->family == AF_UNSPEC || in->family == family);
|
||||
|
||||
r = routing_policy_rule_dup(in, &rule);
|
||||
r = routing_policy_rule_new(&rule);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = routing_policy_rule_copy(rule, in);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
rule->family = family;
|
||||
|
||||
r = routing_policy_rule_get(m, rule, &existing);
|
||||
if (r == -ENOENT) {
|
||||
/* Rule does not exist, use a new one. */
|
||||
@ -375,11 +390,11 @@ static int routing_policy_rule_consume_foreign(Manager *m, RoutingPolicyRule *ru
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void log_routing_policy_rule_debug(const RoutingPolicyRule *rule, const char *str, const Link *link, const Manager *m) {
|
||||
static void log_routing_policy_rule_debug(const RoutingPolicyRule *rule, int family, const char *str, const Link *link, const Manager *m) {
|
||||
_cleanup_free_ char *from = NULL, *to = NULL, *table = NULL;
|
||||
|
||||
assert(rule);
|
||||
assert(IN_SET(rule->family, AF_INET, AF_INET6));
|
||||
assert(IN_SET(family, AF_INET, AF_INET6));
|
||||
assert(str);
|
||||
assert(m);
|
||||
|
||||
@ -388,8 +403,8 @@ static void log_routing_policy_rule_debug(const RoutingPolicyRule *rule, const c
|
||||
if (!DEBUG_LOGGING)
|
||||
return;
|
||||
|
||||
(void) in_addr_prefix_to_string(rule->family, &rule->from, rule->from_prefixlen, &from);
|
||||
(void) in_addr_prefix_to_string(rule->family, &rule->to, rule->to_prefixlen, &to);
|
||||
(void) in_addr_prefix_to_string(family, &rule->from, rule->from_prefixlen, &from);
|
||||
(void) in_addr_prefix_to_string(family, &rule->to, rule->to_prefixlen, &to);
|
||||
(void) manager_get_route_table_to_string(m, rule->table, &table);
|
||||
|
||||
log_link_debug(link,
|
||||
@ -519,14 +534,10 @@ static int routing_policy_rule_set_netlink_message(const RoutingPolicyRule *rule
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int routing_policy_rule_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Manager *manager) {
|
||||
static int routing_policy_rule_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(manager);
|
||||
assert(manager->routing_policy_rule_remove_messages > 0);
|
||||
|
||||
manager->routing_policy_rule_remove_messages--;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0)
|
||||
@ -544,7 +555,7 @@ static int routing_policy_rule_remove(const RoutingPolicyRule *rule, Manager *ma
|
||||
assert(manager->rtnl);
|
||||
assert(IN_SET(rule->family, AF_INET, AF_INET6));
|
||||
|
||||
log_routing_policy_rule_debug(rule, "Removing", NULL, manager);
|
||||
log_routing_policy_rule_debug(rule, rule->family, "Removing", NULL, manager);
|
||||
|
||||
r = sd_rtnl_message_new_routing_policy_rule(manager->rtnl, &m, RTM_DELRULE, rule->family);
|
||||
if (r < 0)
|
||||
@ -554,37 +565,58 @@ static int routing_policy_rule_remove(const RoutingPolicyRule *rule, Manager *ma
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = netlink_call_async(manager->rtnl, NULL, m,
|
||||
r = sd_netlink_call_async(manager->rtnl, NULL, m,
|
||||
routing_policy_rule_remove_handler,
|
||||
NULL, manager);
|
||||
NULL, NULL, 0, __func__);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Could not send rtnetlink message: %m");
|
||||
|
||||
manager->routing_policy_rule_remove_messages++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int routing_policy_rule_configure(
|
||||
const RoutingPolicyRule *rule,
|
||||
Link *link,
|
||||
link_netlink_message_handler_t callback,
|
||||
RoutingPolicyRule **ret) {
|
||||
static int routing_policy_rule_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
assert(rtnl);
|
||||
assert(m);
|
||||
assert(link);
|
||||
assert(link->ifname);
|
||||
assert(link->routing_policy_rule_messages > 0);
|
||||
|
||||
link->routing_policy_rule_messages--;
|
||||
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 1;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EEXIST) {
|
||||
log_link_message_warning_errno(link, m, r, "Could not add routing policy rule");
|
||||
link_enter_failed(link);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (link->routing_policy_rule_messages == 0) {
|
||||
log_link_debug(link, "Routing policy rule configured");
|
||||
link->routing_policy_rules_configured = true;
|
||||
link_check_ready(link);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int routing_policy_rule_configure_internal(const RoutingPolicyRule *rule, int family, Link *link) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
|
||||
int r;
|
||||
|
||||
assert(rule);
|
||||
assert(IN_SET(rule->family, AF_INET, AF_INET6));
|
||||
assert(link);
|
||||
assert(link->ifindex > 0);
|
||||
assert(link->manager);
|
||||
assert(link->manager->rtnl);
|
||||
assert(callback);
|
||||
|
||||
log_routing_policy_rule_debug(rule, "Configuring", link, link->manager);
|
||||
log_routing_policy_rule_debug(rule, family, "Configuring", link, link->manager);
|
||||
|
||||
r = sd_rtnl_message_new_routing_policy_rule(link->manager->rtnl, &m, RTM_NEWRULE, rule->family);
|
||||
r = sd_rtnl_message_new_routing_policy_rule(link->manager->rtnl, &m, RTM_NEWRULE, family);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not allocate RTM_NEWRULE message: %m");
|
||||
|
||||
@ -592,20 +624,43 @@ static int routing_policy_rule_configure(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = routing_policy_rule_add(link->manager, rule, ret);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not add rule: %m");
|
||||
|
||||
r = netlink_call_async(link->manager->rtnl, NULL, m, callback,
|
||||
r = netlink_call_async(link->manager->rtnl, NULL, m,
|
||||
routing_policy_rule_handler,
|
||||
link_netlink_destroy_callback, link);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not send rtnetlink message: %m");
|
||||
|
||||
link_ref(link);
|
||||
link->routing_policy_rule_messages++;
|
||||
|
||||
r = routing_policy_rule_add(link->manager, rule, family, NULL);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not add rule: %m");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int routing_policy_rule_configure(const RoutingPolicyRule *rule, Link *link) {
|
||||
int r;
|
||||
|
||||
if (IN_SET(rule->family, AF_INET, AF_INET6))
|
||||
return routing_policy_rule_configure_internal(rule, rule->family, link);
|
||||
|
||||
if (FLAGS_SET(rule->address_family, ADDRESS_FAMILY_IPV4)) {
|
||||
r = routing_policy_rule_configure_internal(rule, AF_INET, link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (FLAGS_SET(rule->address_family, ADDRESS_FAMILY_IPV6)) {
|
||||
r = routing_policy_rule_configure_internal(rule, AF_INET6, link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int links_have_routing_policy_rule(const Manager *m, const RoutingPolicyRule *rule, const Link *except) {
|
||||
Link *link;
|
||||
int r;
|
||||
@ -630,7 +685,11 @@ static int links_have_routing_policy_rule(const Manager *m, const RoutingPolicyR
|
||||
/* The case Family=both. */
|
||||
_cleanup_(routing_policy_rule_freep) RoutingPolicyRule *tmp = NULL;
|
||||
|
||||
r = routing_policy_rule_dup(link_rule, &tmp);
|
||||
r = routing_policy_rule_new(&tmp);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = routing_policy_rule_copy(tmp, link_rule);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -676,153 +735,36 @@ int manager_drop_routing_policy_rules_internal(Manager *m, bool foreign, const L
|
||||
return r;
|
||||
}
|
||||
|
||||
static int static_routing_policy_rule_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
assert(rtnl);
|
||||
assert(m);
|
||||
assert(link);
|
||||
assert(link->ifname);
|
||||
assert(link->static_routing_policy_rule_messages > 0);
|
||||
|
||||
link->static_routing_policy_rule_messages--;
|
||||
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 1;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EEXIST) {
|
||||
log_link_message_warning_errno(link, m, r, "Could not add routing policy rule");
|
||||
link_enter_failed(link);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (link->static_routing_policy_rule_messages == 0) {
|
||||
log_link_debug(link, "Routing policy rule configured");
|
||||
link->static_routing_policy_rules_configured = true;
|
||||
link_check_ready(link);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int link_request_routing_policy_rule(
|
||||
Link *link,
|
||||
RoutingPolicyRule *rule,
|
||||
bool consume_object,
|
||||
unsigned *message_counter,
|
||||
link_netlink_message_handler_t netlink_handler,
|
||||
Request **ret) {
|
||||
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
assert(rule);
|
||||
|
||||
log_routing_policy_rule_debug(rule, "Requesting", link, link->manager);
|
||||
return link_queue_request(link, REQUEST_TYPE_ROUTING_POLICY_RULE, rule, consume_object,
|
||||
message_counter, netlink_handler, ret);
|
||||
}
|
||||
|
||||
static int link_request_static_routing_policy_rule(Link *link, RoutingPolicyRule *rule) {
|
||||
int r;
|
||||
|
||||
if (IN_SET(rule->family, AF_INET, AF_INET6))
|
||||
return link_request_routing_policy_rule(link, rule, false,
|
||||
&link->static_routing_policy_rule_messages,
|
||||
static_routing_policy_rule_configure_handler,
|
||||
NULL);
|
||||
|
||||
if (FLAGS_SET(rule->address_family, ADDRESS_FAMILY_IPV4)) {
|
||||
_cleanup_(routing_policy_rule_freep) RoutingPolicyRule *tmp = NULL;
|
||||
|
||||
r = routing_policy_rule_dup(rule, &tmp);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
tmp->family = AF_INET;
|
||||
|
||||
r = link_request_routing_policy_rule(link, TAKE_PTR(tmp), true,
|
||||
&link->static_routing_policy_rule_messages,
|
||||
static_routing_policy_rule_configure_handler,
|
||||
NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (FLAGS_SET(rule->address_family, ADDRESS_FAMILY_IPV6)) {
|
||||
_cleanup_(routing_policy_rule_freep) RoutingPolicyRule *tmp = NULL;
|
||||
|
||||
r = routing_policy_rule_dup(rule, &tmp);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
tmp->family = AF_INET6;
|
||||
|
||||
r = link_request_routing_policy_rule(link, TAKE_PTR(tmp), true,
|
||||
&link->static_routing_policy_rule_messages,
|
||||
static_routing_policy_rule_configure_handler,
|
||||
NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int link_request_static_routing_policy_rules(Link *link) {
|
||||
int link_set_routing_policy_rules(Link *link) {
|
||||
RoutingPolicyRule *rule;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->network);
|
||||
|
||||
link->static_routing_policy_rules_configured = false;
|
||||
|
||||
HASHMAP_FOREACH(rule, link->network->rules_by_section) {
|
||||
r = link_request_static_routing_policy_rule(link, rule);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Could not request routing policy rule: %m");
|
||||
if (link->routing_policy_rule_messages != 0) {
|
||||
log_link_debug(link, "Routing policy rules are configuring.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (link->static_routing_policy_rule_messages == 0) {
|
||||
link->static_routing_policy_rules_configured = true;
|
||||
link_check_ready(link);
|
||||
} else {
|
||||
log_link_debug(link, "Requesting routing policy rules");
|
||||
link->routing_policy_rules_configured = false;
|
||||
|
||||
HASHMAP_FOREACH(rule, link->network->rules_by_section) {
|
||||
r = routing_policy_rule_configure(rule, link);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Could not set routing policy rule: %m");
|
||||
}
|
||||
|
||||
if (link->routing_policy_rule_messages == 0)
|
||||
link->routing_policy_rules_configured = true;
|
||||
else {
|
||||
log_link_debug(link, "Setting routing policy rules");
|
||||
link_set_state(link, LINK_STATE_CONFIGURING);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int request_process_routing_policy_rule(Request *req) {
|
||||
RoutingPolicyRule *ret = NULL; /* avoid false maybe-uninitialized warning */
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->link);
|
||||
assert(req->rule);
|
||||
assert(req->type == REQUEST_TYPE_ROUTING_POLICY_RULE);
|
||||
|
||||
if (!link_is_ready_to_configure(req->link, false))
|
||||
return 0;
|
||||
|
||||
if (req->link->manager->routing_policy_rule_remove_messages > 0)
|
||||
return 0;
|
||||
|
||||
r = routing_policy_rule_configure(req->rule, req->link, req->netlink_handler, &ret);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (req->after_configure) {
|
||||
r = req->after_configure(req, ret);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const RoutingPolicyRule kernel_rules[] = {
|
||||
{ .family = AF_INET, .priority = 0, .table = RT_TABLE_LOCAL, .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, },
|
||||
{ .family = AF_INET, .priority = 32766, .table = RT_TABLE_MAIN, .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, },
|
||||
@ -1035,11 +977,11 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Man
|
||||
switch (type) {
|
||||
case RTM_NEWRULE:
|
||||
if (rule)
|
||||
log_routing_policy_rule_debug(tmp, "Received remembered", NULL, m);
|
||||
log_routing_policy_rule_debug(tmp, tmp->family, "Received remembered", NULL, m);
|
||||
else if (!m->manage_foreign_routes)
|
||||
log_routing_policy_rule_debug(tmp, "Ignoring received foreign", NULL, m);
|
||||
log_routing_policy_rule_debug(tmp, tmp->family, "Ignoring received foreign", NULL, m);
|
||||
else {
|
||||
log_routing_policy_rule_debug(tmp, "Remembering foreign", NULL, m);
|
||||
log_routing_policy_rule_debug(tmp, tmp->family, "Remembering foreign", NULL, m);
|
||||
r = routing_policy_rule_consume_foreign(m, TAKE_PTR(tmp));
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Could not remember foreign rule, ignoring: %m");
|
||||
@ -1047,10 +989,10 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Man
|
||||
break;
|
||||
case RTM_DELRULE:
|
||||
if (rule) {
|
||||
log_routing_policy_rule_debug(tmp, "Forgetting", NULL, m);
|
||||
log_routing_policy_rule_debug(tmp, tmp->family, "Forgetting", NULL, m);
|
||||
routing_policy_rule_free(rule);
|
||||
} else
|
||||
log_routing_policy_rule_debug(tmp, "Kernel removed unknown", NULL, m);
|
||||
log_routing_policy_rule_debug(tmp, tmp->family, "Kernel removed unknown", NULL, m);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@ -4,15 +4,16 @@
|
||||
#include <inttypes.h>
|
||||
#include <linux/fib_rules.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "conf-parser.h"
|
||||
#include "in-addr-util.h"
|
||||
#include "networkd-util.h"
|
||||
#include "set.h"
|
||||
|
||||
typedef struct Network Network;
|
||||
typedef struct Link Link;
|
||||
typedef struct Manager Manager;
|
||||
typedef struct Network Network;
|
||||
typedef struct Request Request;
|
||||
|
||||
typedef struct RoutingPolicyRule {
|
||||
Manager *manager;
|
||||
@ -54,8 +55,7 @@ RoutingPolicyRule *routing_policy_rule_free(RoutingPolicyRule *rule);
|
||||
|
||||
void network_drop_invalid_routing_policy_rules(Network *network);
|
||||
|
||||
int link_request_static_routing_policy_rules(Link *link);
|
||||
int request_process_routing_policy_rule(Request *req);
|
||||
int link_set_routing_policy_rules(Link *link);
|
||||
|
||||
int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Manager *m);
|
||||
int manager_drop_routing_policy_rules_internal(Manager *m, bool foreign, const Link *except);
|
||||
|
||||
@ -977,7 +977,7 @@ static int config_parse_label(
|
||||
/* Nota bene: the empty label is a totally valid one. Let's hence not follow our usual rule of
|
||||
* assigning the empty string to reset to default here, but really accept it as label to set. */
|
||||
|
||||
r = specifier_printf(rvalue, GPT_LABEL_MAX, specifier_table, NULL, &resolved);
|
||||
r = specifier_printf(rvalue, specifier_table, NULL, &resolved);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to expand specifiers in Label=, ignoring: %s", rvalue);
|
||||
@ -1142,7 +1142,7 @@ static int config_parse_copy_files(
|
||||
if (!isempty(p))
|
||||
return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL), "Too many arguments: %s", rvalue);
|
||||
|
||||
r = specifier_printf(source, PATH_MAX-1, specifier_table, NULL, &resolved_source);
|
||||
r = specifier_printf(source, specifier_table, NULL, &resolved_source);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to expand specifiers in CopyFiles= source, ignoring: %s", rvalue);
|
||||
@ -1153,7 +1153,7 @@ static int config_parse_copy_files(
|
||||
if (r < 0)
|
||||
return 0;
|
||||
|
||||
r = specifier_printf(target, PATH_MAX-1, specifier_table, NULL, &resolved_target);
|
||||
r = specifier_printf(target, specifier_table, NULL, &resolved_target);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to expand specifiers in CopyFiles= target, ignoring: %s", resolved_target);
|
||||
@ -1202,7 +1202,7 @@ static int config_parse_copy_blocks(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = specifier_printf(rvalue, PATH_MAX-1, specifier_table, NULL, &d);
|
||||
r = specifier_printf(rvalue, specifier_table, NULL, &d);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to expand specifiers in CopyBlocks= source path, ignoring: %s", rvalue);
|
||||
@ -1250,7 +1250,7 @@ static int config_parse_make_dirs(
|
||||
if (r == 0)
|
||||
return 0;
|
||||
|
||||
r = specifier_printf(word, PATH_MAX-1, specifier_table, NULL, &d);
|
||||
r = specifier_printf(word, specifier_table, NULL, &d);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to expand specifiers in MakeDirectories= parameter, ignoring: %s", word);
|
||||
|
||||
@ -255,7 +255,7 @@ int config_parse_dnssd_service_name(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = specifier_printf(rvalue, DNS_LABEL_MAX, specifier_table, NULL, &name);
|
||||
r = specifier_printf(rvalue, specifier_table, NULL, &name);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Invalid service instance name template '%s', ignoring assignment: %m", rvalue);
|
||||
|
||||
@ -170,7 +170,7 @@ int dnssd_render_instance_name(DnssdService *s, char **ret_name) {
|
||||
assert(s);
|
||||
assert(s->name_template);
|
||||
|
||||
r = specifier_printf(s->name_template, DNS_LABEL_MAX, specifier_table, s, &name);
|
||||
r = specifier_printf(s->name_template, specifier_table, s, &name);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to replace specifiers: %m");
|
||||
|
||||
|
||||
@ -1097,27 +1097,18 @@ uint32_t manager_find_mtu(Manager *m) {
|
||||
uint32_t mtu = 0;
|
||||
Link *l;
|
||||
|
||||
/* If we don't know on which link a DNS packet would be delivered, let's find the largest MTU that
|
||||
* works on all interfaces we know of that have an IP address asociated */
|
||||
/* If we don't know on which link a DNS packet would be
|
||||
* delivered, let's find the largest MTU that works on all
|
||||
* interfaces we know of */
|
||||
|
||||
HASHMAP_FOREACH(l, m->links) {
|
||||
/* Let's filter out links without IP addresses (e.g. AF_CAN links and suchlike) */
|
||||
if (!l->addresses)
|
||||
continue;
|
||||
|
||||
/* Safety check: MTU shorter than what we need for the absolutely shortest DNS request? Then
|
||||
* let's ignore this link. */
|
||||
if (l->mtu < MIN(UDP4_PACKET_HEADER_SIZE + DNS_PACKET_HEADER_SIZE,
|
||||
UDP6_PACKET_HEADER_SIZE + DNS_PACKET_HEADER_SIZE))
|
||||
if (l->mtu <= 0)
|
||||
continue;
|
||||
|
||||
if (mtu <= 0 || l->mtu < mtu)
|
||||
mtu = l->mtu;
|
||||
}
|
||||
|
||||
if (mtu == 0) /* found nothing? then let's assume the typical Ethernet MTU for lack of anything more precise */
|
||||
return 1500;
|
||||
|
||||
return mtu;
|
||||
}
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
# Some examples of DNS servers which may be used for DNS= and FallbackDNS=:
|
||||
# Cloudflare: 1.1.1.1#cloudflare-dns.com 1.0.0.1#cloudflare-dns.com 2606:4700:4700::1111#cloudflare-dns.com 2606:4700:4700::1001#cloudflare-dns.com
|
||||
# Google: 8.8.8.8#dns.google 8.8.4.4#dns.google 2001:4860:4860::8888#dns.google 2001:4860:4860::8844#dns.google
|
||||
# Quad9: 9.9.9.9#dns.quad9.net 149.112.112.112#dns.quad9.net 2620:fe::fe#dns.quad9.net 2620:fe::9#dns.quad9.net
|
||||
# Quad9: 9.9.9.9#dns.quad9.net 2620:fe::fe#dns.quad9.net
|
||||
#DNS=
|
||||
#FallbackDNS=@DNS_SERVERS@
|
||||
#Domains=
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "af-list.h"
|
||||
#include "alloc-util.h"
|
||||
#include "bus-error.h"
|
||||
#include "bus-unit-util.h"
|
||||
@ -880,10 +879,14 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
|
||||
|
||||
address_family = eq ? word : NULL;
|
||||
if (address_family) {
|
||||
family = af_from_ipv4_ipv6(address_family);
|
||||
if (family == AF_UNSPEC)
|
||||
if (!STR_IN_SET(address_family, "IPv4", "IPv6"))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Only \"ipv4\" and \"ipv6\" protocols are supported");
|
||||
"Only IPv4 and IPv6 protocols are supported");
|
||||
|
||||
if (streq(address_family, "IPv4"))
|
||||
family = AF_INET;
|
||||
else
|
||||
family = AF_INET6;
|
||||
}
|
||||
|
||||
user_port = eq ? eq : word;
|
||||
|
||||
@ -985,7 +985,7 @@ bool dns_service_name_is_valid(const char *name) {
|
||||
l = strlen(name);
|
||||
if (l <= 0)
|
||||
return false;
|
||||
if (l > DNS_LABEL_MAX)
|
||||
if (l > 63)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
@ -104,7 +104,7 @@ int gpt_partition_label_valid(const char *s) {
|
||||
if (!recoded)
|
||||
return -ENOMEM;
|
||||
|
||||
return char16_strlen(recoded) <= GPT_LABEL_MAX;
|
||||
return char16_strlen(recoded) <= 36;
|
||||
}
|
||||
|
||||
bool gpt_partition_type_is_root(sd_id128_t id) {
|
||||
|
||||
@ -115,9 +115,6 @@
|
||||
#define GPT_FLAG_NO_AUTO (1ULL << 63)
|
||||
#define GPT_FLAG_GROWFS (1ULL << 59)
|
||||
|
||||
/* maximum length of gpt label */
|
||||
#define GPT_LABEL_MAX 36
|
||||
|
||||
const char *gpt_partition_type_uuid_to_string(sd_id128_t id);
|
||||
const char *gpt_partition_type_uuid_to_string_harder(
|
||||
sd_id128_t id,
|
||||
|
||||
@ -103,7 +103,7 @@ static int specifier_last_component(char specifier, const void *data, const void
|
||||
return 0;
|
||||
}
|
||||
|
||||
int install_full_printf_internal(const UnitFileInstallInfo *i, const char *format, size_t max_length, char **ret) {
|
||||
int install_full_printf(const UnitFileInstallInfo *i, const char *format, char **ret) {
|
||||
/* This is similar to unit_name_printf() */
|
||||
|
||||
const Specifier table[] = {
|
||||
@ -123,5 +123,5 @@ int install_full_printf_internal(const UnitFileInstallInfo *i, const char *forma
|
||||
assert(format);
|
||||
assert(ret);
|
||||
|
||||
return specifier_printf(format, max_length, table, i, ret);
|
||||
return specifier_printf(format, table, i, ret);
|
||||
}
|
||||
|
||||
@ -2,12 +2,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "install.h"
|
||||
#include "unit-name.h"
|
||||
|
||||
int install_full_printf_internal(const UnitFileInstallInfo *i, const char *format, size_t max_length, char **ret);
|
||||
static inline int install_name_printf(const UnitFileInstallInfo *i, const char *format, char **ret) {
|
||||
return install_full_printf_internal(i, format, UNIT_NAME_MAX, ret);
|
||||
}
|
||||
static inline int install_path_printf(const UnitFileInstallInfo *i, const char *format, char **ret) {
|
||||
return install_full_printf_internal(i, format, PATH_MAX-1, ret);
|
||||
}
|
||||
int install_full_printf(const UnitFileInstallInfo *i, const char *format, char **ret);
|
||||
|
||||
@ -1143,7 +1143,7 @@ static int config_parse_also(
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
r = install_name_printf(info, word, &printed);
|
||||
r = install_full_printf(info, word, &printed);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -1190,7 +1190,7 @@ static int config_parse_default_instance(
|
||||
return log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"DefaultInstance= only makes sense for template units, ignoring.");
|
||||
|
||||
r = install_name_printf(i, rvalue, &printed);
|
||||
r = install_full_printf(i, rvalue, &printed);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -1816,7 +1816,7 @@ static int install_info_symlink_alias(
|
||||
STRV_FOREACH(s, i->aliases) {
|
||||
_cleanup_free_ char *alias_path = NULL, *dst = NULL, *dst_updated = NULL;
|
||||
|
||||
q = install_path_printf(i, *s, &dst);
|
||||
q = install_full_printf(i, *s, &dst);
|
||||
if (q < 0)
|
||||
return q;
|
||||
|
||||
@ -1891,7 +1891,7 @@ static int install_info_symlink_wants(
|
||||
STRV_FOREACH(s, list) {
|
||||
_cleanup_free_ char *path = NULL, *dst = NULL;
|
||||
|
||||
q = install_name_printf(i, *s, &dst);
|
||||
q = install_full_printf(i, *s, &dst);
|
||||
if (q < 0)
|
||||
return q;
|
||||
|
||||
|
||||
@ -29,9 +29,9 @@
|
||||
* and "%" used for escaping. */
|
||||
#define POSSIBLE_SPECIFIERS ALPHANUMERICAL "%"
|
||||
|
||||
int specifier_printf(const char *text, size_t max_length, const Specifier table[], const void *userdata, char **ret) {
|
||||
int specifier_printf(const char *text, const Specifier table[], const void *userdata, char **_ret) {
|
||||
size_t l, allocated = 0;
|
||||
_cleanup_free_ char *result = NULL;
|
||||
_cleanup_free_ char *ret = NULL;
|
||||
char *t;
|
||||
const char *f;
|
||||
bool percent = false;
|
||||
@ -41,11 +41,11 @@ int specifier_printf(const char *text, size_t max_length, const Specifier table[
|
||||
assert(table);
|
||||
|
||||
l = strlen(text);
|
||||
if (!GREEDY_REALLOC(result, allocated, l + 1))
|
||||
if (!GREEDY_REALLOC(ret, allocated, l + 1))
|
||||
return -ENOMEM;
|
||||
t = result;
|
||||
t = ret;
|
||||
|
||||
for (f = text; *f != '\0'; f++, l--) {
|
||||
for (f = text; *f; f++, l--)
|
||||
if (percent) {
|
||||
if (*f == '%')
|
||||
*(t++) = '%';
|
||||
@ -64,13 +64,13 @@ int specifier_printf(const char *text, size_t max_length, const Specifier table[
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
j = t - result;
|
||||
j = t - ret;
|
||||
k = strlen(w);
|
||||
|
||||
if (!GREEDY_REALLOC(result, allocated, j + k + l + 1))
|
||||
if (!GREEDY_REALLOC(ret, allocated, j + k + l + 1))
|
||||
return -ENOMEM;
|
||||
memcpy(result + j, w, k);
|
||||
t = result + j + k;
|
||||
memcpy(ret + j, w, k);
|
||||
t = ret + j + k;
|
||||
} else if (strchr(POSSIBLE_SPECIFIERS, *f))
|
||||
/* Oops, an unknown specifier. */
|
||||
return -EBADSLT;
|
||||
@ -86,26 +86,19 @@ int specifier_printf(const char *text, size_t max_length, const Specifier table[
|
||||
else
|
||||
*(t++) = *f;
|
||||
|
||||
if ((size_t) (t - result) > max_length)
|
||||
return -ENAMETOOLONG;
|
||||
}
|
||||
|
||||
/* If string ended with a stray %, also end with % */
|
||||
if (percent) {
|
||||
if (percent)
|
||||
*(t++) = '%';
|
||||
if ((size_t) (t - result) > max_length)
|
||||
return -ENAMETOOLONG;
|
||||
}
|
||||
*(t++) = 0;
|
||||
|
||||
/* Try to deallocate unused bytes, but don't sweat it too much */
|
||||
if ((size_t)(t - result) < allocated) {
|
||||
t = realloc(result, t - result);
|
||||
if ((size_t)(t - ret) < allocated) {
|
||||
t = realloc(ret, t - ret);
|
||||
if (t)
|
||||
result = t;
|
||||
ret = t;
|
||||
}
|
||||
|
||||
*ret = TAKE_PTR(result);
|
||||
*_ret = TAKE_PTR(ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -131,7 +124,7 @@ int specifier_machine_id(char specifier, const void *data, const void *userdata,
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
n = new(char, SD_ID128_STRING_MAX);
|
||||
n = new(char, 33);
|
||||
if (!n)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -148,7 +141,7 @@ int specifier_boot_id(char specifier, const void *data, const void *userdata, ch
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
n = new(char, SD_ID128_STRING_MAX);
|
||||
n = new(char, 33);
|
||||
if (!n)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ typedef struct Specifier {
|
||||
const void *data;
|
||||
} Specifier;
|
||||
|
||||
int specifier_printf(const char *text, size_t max_length, const Specifier table[], const void *userdata, char **ret);
|
||||
int specifier_printf(const char *text, const Specifier table[], const void *userdata, char **ret);
|
||||
|
||||
int specifier_string(char specifier, const void *data, const void *userdata, char **ret);
|
||||
|
||||
|
||||
@ -1210,8 +1210,9 @@ int varlink_close(Varlink *v) {
|
||||
|
||||
varlink_set_state(v, VARLINK_DISCONNECTED);
|
||||
|
||||
/* Let's take a reference first, since varlink_detach_server() might drop the final (dangling) ref
|
||||
* which would destroy us before we can call varlink_clear() */
|
||||
/* Let's take a reference first, since varlink_detach_server() might drop the final ref from the
|
||||
* disconnect callback, which would invalidate the pointer we are holding before we can call
|
||||
* varlink_clear(). */
|
||||
varlink_ref(v);
|
||||
varlink_detach_server(v);
|
||||
varlink_clear(v);
|
||||
@ -1224,15 +1225,32 @@ Varlink* varlink_close_unref(Varlink *v) {
|
||||
if (!v)
|
||||
return NULL;
|
||||
|
||||
(void) varlink_close(v);
|
||||
/* A reference is given to us to be destroyed. But when calling varlink_close(), a callback might
|
||||
* also drop a reference. We allow this, and will hold a temporary reference to the object to make
|
||||
* sure that the object still exists when control returns to us. If there's just one reference
|
||||
* remaining after varlink_close(), even though there were at least two right before, we'll handle
|
||||
* that gracefully instead of crashing.
|
||||
*
|
||||
* In other words, this call drops the donated reference, but if the internal call to varlink_close()
|
||||
* dropped a reference to, we don't drop the reference afain. This allows the caller to say:
|
||||
* global_object->varlink = varlink_close_unref(global_object->varlink);
|
||||
* even though there is some callback which has access to global_object and may drop the reference
|
||||
* stored in global_object->varlink. Without this step, the same code would have to be written as:
|
||||
* Varlink *t = TAKE_PTR(global_object->varlink);
|
||||
* varlink_close_unref(t);
|
||||
*/
|
||||
/* n_ref >= 1 */
|
||||
varlink_ref(v); /* n_ref >= 2 */
|
||||
varlink_close(v); /* n_ref >= 1 */
|
||||
if (v->n_ref > 1)
|
||||
v->n_ref--; /* n_ref >= 1 */
|
||||
return varlink_unref(v);
|
||||
}
|
||||
|
||||
Varlink* varlink_flush_close_unref(Varlink *v) {
|
||||
if (!v)
|
||||
return NULL;
|
||||
if (v)
|
||||
varlink_flush(v);
|
||||
|
||||
(void) varlink_flush(v);
|
||||
return varlink_close_unref(v);
|
||||
}
|
||||
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include "af-list.h"
|
||||
#include "bus-error.h"
|
||||
#include "bus-locator.h"
|
||||
#include "bus-map-properties.h"
|
||||
@ -1711,25 +1710,22 @@ static int print_property(const char *name, const char *expected_value, sd_bus_m
|
||||
return 1;
|
||||
} else if (STR_IN_SET(name, "SocketBindAllow", "SocketBindDeny")) {
|
||||
uint16_t nr_ports, port_min;
|
||||
const char *family;
|
||||
int af;
|
||||
|
||||
r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(iqq)");
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
while ((r = sd_bus_message_read(m, "(iqq)", &af, &nr_ports, &port_min)) > 0) {
|
||||
const char *family, *colon;
|
||||
|
||||
family = strempty(af_to_ipv4_ipv6(af));
|
||||
colon = isempty(family) ? "" : ":";
|
||||
|
||||
family = af == AF_INET ? "IPv4:" : af == AF_INET6 ? "IPv6:" : "";
|
||||
if (nr_ports == 0)
|
||||
bus_print_property_valuef(name, expected_value, flags, "%s%sany", family, colon);
|
||||
bus_print_property_valuef(name, expected_value, flags, "%sany", family);
|
||||
else if (nr_ports == 1)
|
||||
bus_print_property_valuef(
|
||||
name, expected_value, flags, "%s%s%hu", family, colon, port_min);
|
||||
name, expected_value, flags, "%s%hu", family, port_min);
|
||||
else
|
||||
bus_print_property_valuef(
|
||||
name, expected_value, flags, "%s%s%hu-%hu", family, colon, port_min,
|
||||
name, expected_value, flags, "%s%hu-%hu", family, port_min,
|
||||
(uint16_t) (port_min + nr_ports - 1));
|
||||
}
|
||||
if (r < 0)
|
||||
|
||||
@ -206,7 +206,7 @@ int sd_dhcp_client_set_fallback_lease_lifetime(
|
||||
int sd_dhcp_client_add_option(sd_dhcp_client *client, sd_dhcp_option *v);
|
||||
int sd_dhcp_client_add_vendor_option(sd_dhcp_client *client, sd_dhcp_option *v);
|
||||
|
||||
int sd_dhcp_client_is_running(sd_dhcp_client *client);
|
||||
int sd_dhcp_client_is_running(const sd_dhcp_client *client);
|
||||
int sd_dhcp_client_stop(sd_dhcp_client *client);
|
||||
int sd_dhcp_client_start(sd_dhcp_client *client);
|
||||
int sd_dhcp_client_send_release(sd_dhcp_client *client);
|
||||
|
||||
@ -46,36 +46,36 @@ typedef enum sd_dhcp_lease_server_type_t {
|
||||
_SD_ENUM_FORCE_S64(DHCP_LEASE_SERVER_TYPE),
|
||||
} sd_dhcp_lease_server_type_t;
|
||||
|
||||
int sd_dhcp_lease_get_address(sd_dhcp_lease *lease, struct in_addr *addr);
|
||||
int sd_dhcp_lease_get_lifetime(sd_dhcp_lease *lease, uint32_t *lifetime);
|
||||
int sd_dhcp_lease_get_t1(sd_dhcp_lease *lease, uint32_t *t1);
|
||||
int sd_dhcp_lease_get_t2(sd_dhcp_lease *lease, uint32_t *t2);
|
||||
int sd_dhcp_lease_get_broadcast(sd_dhcp_lease *lease, struct in_addr *addr);
|
||||
int sd_dhcp_lease_get_netmask(sd_dhcp_lease *lease, struct in_addr *addr);
|
||||
int sd_dhcp_lease_get_router(sd_dhcp_lease *lease, const struct in_addr **addr);
|
||||
int sd_dhcp_lease_get_next_server(sd_dhcp_lease *lease, struct in_addr *addr);
|
||||
int sd_dhcp_lease_get_server_identifier(sd_dhcp_lease *lease, struct in_addr *addr);
|
||||
int sd_dhcp_lease_get_servers(sd_dhcp_lease *lease, sd_dhcp_lease_server_type_t what, const struct in_addr **addr);
|
||||
int sd_dhcp_lease_get_dns(sd_dhcp_lease *lease, const struct in_addr **addr);
|
||||
int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr);
|
||||
int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr);
|
||||
int sd_dhcp_lease_get_pop3(sd_dhcp_lease *lease, const struct in_addr **addr);
|
||||
int sd_dhcp_lease_get_smtp(sd_dhcp_lease *lease, const struct in_addr **addr);
|
||||
int sd_dhcp_lease_get_lpr(sd_dhcp_lease *lease, const struct in_addr **addr);
|
||||
int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu);
|
||||
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname);
|
||||
int sd_dhcp_lease_get_search_domains(sd_dhcp_lease *lease, char ***domains);
|
||||
int sd_dhcp_lease_get_hostname(sd_dhcp_lease *lease, const char **hostname);
|
||||
int sd_dhcp_lease_get_root_path(sd_dhcp_lease *lease, const char **root_path);
|
||||
int sd_dhcp_lease_get_routes(sd_dhcp_lease *lease, sd_dhcp_route ***routes);
|
||||
int sd_dhcp_lease_get_vendor_specific(sd_dhcp_lease *lease, const void **data, size_t *data_len);
|
||||
int sd_dhcp_lease_get_client_id(sd_dhcp_lease *lease, const void **client_id, size_t *client_id_len);
|
||||
int sd_dhcp_lease_get_timezone(sd_dhcp_lease *lease, const char **timezone);
|
||||
int sd_dhcp_lease_get_address(const sd_dhcp_lease *lease, struct in_addr *addr);
|
||||
int sd_dhcp_lease_get_lifetime(const sd_dhcp_lease *lease, uint32_t *lifetime);
|
||||
int sd_dhcp_lease_get_t1(const sd_dhcp_lease *lease, uint32_t *t1);
|
||||
int sd_dhcp_lease_get_t2(const sd_dhcp_lease *lease, uint32_t *t2);
|
||||
int sd_dhcp_lease_get_broadcast(const sd_dhcp_lease *lease, struct in_addr *addr);
|
||||
int sd_dhcp_lease_get_netmask(const sd_dhcp_lease *lease, struct in_addr *addr);
|
||||
int sd_dhcp_lease_get_router(const sd_dhcp_lease *lease, const struct in_addr **addr);
|
||||
int sd_dhcp_lease_get_next_server(const sd_dhcp_lease *lease, struct in_addr *addr);
|
||||
int sd_dhcp_lease_get_server_identifier(const sd_dhcp_lease *lease, struct in_addr *addr);
|
||||
int sd_dhcp_lease_get_servers(const sd_dhcp_lease *lease, sd_dhcp_lease_server_type_t what, const struct in_addr **addr);
|
||||
int sd_dhcp_lease_get_dns(const sd_dhcp_lease *lease, const struct in_addr **addr);
|
||||
int sd_dhcp_lease_get_ntp(const sd_dhcp_lease *lease, const struct in_addr **addr);
|
||||
int sd_dhcp_lease_get_sip(const sd_dhcp_lease *lease, const struct in_addr **addr);
|
||||
int sd_dhcp_lease_get_pop3(const sd_dhcp_lease *lease, const struct in_addr **addr);
|
||||
int sd_dhcp_lease_get_smtp(const sd_dhcp_lease *lease, const struct in_addr **addr);
|
||||
int sd_dhcp_lease_get_lpr(const sd_dhcp_lease *lease, const struct in_addr **addr);
|
||||
int sd_dhcp_lease_get_mtu(const sd_dhcp_lease *lease, uint16_t *mtu);
|
||||
int sd_dhcp_lease_get_domainname(const sd_dhcp_lease *lease, const char **domainname);
|
||||
int sd_dhcp_lease_get_search_domains(const sd_dhcp_lease *lease, char ***domains);
|
||||
int sd_dhcp_lease_get_hostname(const sd_dhcp_lease *lease, const char **hostname);
|
||||
int sd_dhcp_lease_get_root_path(const sd_dhcp_lease *lease, const char **root_path);
|
||||
int sd_dhcp_lease_get_routes(const sd_dhcp_lease *lease, sd_dhcp_route ***routes);
|
||||
int sd_dhcp_lease_get_vendor_specific(const sd_dhcp_lease *lease, const void **data, size_t *data_len);
|
||||
int sd_dhcp_lease_get_client_id(const sd_dhcp_lease *lease, const void **client_id, size_t *client_id_len);
|
||||
int sd_dhcp_lease_get_timezone(const sd_dhcp_lease *lease, const char **timezone);
|
||||
|
||||
int sd_dhcp_route_get_destination(sd_dhcp_route *route, struct in_addr *destination);
|
||||
int sd_dhcp_route_get_destination_prefix_length(sd_dhcp_route *route, uint8_t *length);
|
||||
int sd_dhcp_route_get_gateway(sd_dhcp_route *route, struct in_addr *gateway);
|
||||
int sd_dhcp_route_get_option(sd_dhcp_route *route);
|
||||
int sd_dhcp_route_get_destination(const sd_dhcp_route *route, struct in_addr *destination);
|
||||
int sd_dhcp_route_get_destination_prefix_length(const sd_dhcp_route *route, uint8_t *length);
|
||||
int sd_dhcp_route_get_gateway(const sd_dhcp_route *route, struct in_addr *gateway);
|
||||
int sd_dhcp_route_get_option(const sd_dhcp_route *route);
|
||||
|
||||
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_dhcp_lease, sd_dhcp_lease_unref);
|
||||
|
||||
|
||||
@ -73,8 +73,8 @@ int sd_netlink_call(sd_netlink *nl, sd_netlink_message *message, uint64_t timeou
|
||||
sd_netlink_message **reply);
|
||||
int sd_netlink_read(sd_netlink *nl, uint32_t serial, uint64_t timeout, sd_netlink_message **reply);
|
||||
|
||||
int sd_netlink_get_events(sd_netlink *nl);
|
||||
int sd_netlink_get_timeout(sd_netlink *nl, uint64_t *timeout);
|
||||
int sd_netlink_get_events(const sd_netlink *nl);
|
||||
int sd_netlink_get_timeout(const sd_netlink *nl, uint64_t *timeout);
|
||||
int sd_netlink_process(sd_netlink *nl, sd_netlink_message **ret);
|
||||
int sd_netlink_wait(sd_netlink *nl, uint64_t timeout);
|
||||
|
||||
@ -137,33 +137,33 @@ sd_netlink_message *sd_netlink_message_ref(sd_netlink_message *m);
|
||||
sd_netlink_message *sd_netlink_message_unref(sd_netlink_message *m);
|
||||
|
||||
int sd_netlink_message_request_dump(sd_netlink_message *m, int dump);
|
||||
int sd_netlink_message_is_error(sd_netlink_message *m);
|
||||
int sd_netlink_message_get_errno(sd_netlink_message *m);
|
||||
int sd_netlink_message_get_type(sd_netlink_message *m, uint16_t *type);
|
||||
int sd_netlink_message_is_error(const sd_netlink_message *m);
|
||||
int sd_netlink_message_get_errno(const sd_netlink_message *m);
|
||||
int sd_netlink_message_get_type(const sd_netlink_message *m, uint16_t *type);
|
||||
int sd_netlink_message_set_flags(sd_netlink_message *m, uint16_t flags);
|
||||
int sd_netlink_message_is_broadcast(sd_netlink_message *m);
|
||||
int sd_netlink_message_is_broadcast(const sd_netlink_message *m);
|
||||
|
||||
/* rtnl */
|
||||
int sd_rtnl_message_get_family(sd_netlink_message *m, int *family);
|
||||
int sd_rtnl_message_get_family(const sd_netlink_message *m, int *family);
|
||||
|
||||
int sd_rtnl_message_new_addr(sd_netlink *nl, sd_netlink_message **ret, uint16_t msg_type, int index, int family);
|
||||
int sd_rtnl_message_new_addr_update(sd_netlink *nl, sd_netlink_message **ret, int index, int family);
|
||||
int sd_rtnl_message_addr_set_prefixlen(sd_netlink_message *m, unsigned char prefixlen);
|
||||
int sd_rtnl_message_addr_set_scope(sd_netlink_message *m, unsigned char scope);
|
||||
int sd_rtnl_message_addr_set_flags(sd_netlink_message *m, unsigned char flags);
|
||||
int sd_rtnl_message_addr_get_family(sd_netlink_message *m, int *family);
|
||||
int sd_rtnl_message_addr_get_prefixlen(sd_netlink_message *m, unsigned char *prefixlen);
|
||||
int sd_rtnl_message_addr_get_scope(sd_netlink_message *m, unsigned char *scope);
|
||||
int sd_rtnl_message_addr_get_flags(sd_netlink_message *m, unsigned char *flags);
|
||||
int sd_rtnl_message_addr_get_ifindex(sd_netlink_message *m, int *ifindex);
|
||||
int sd_rtnl_message_addr_get_family(const sd_netlink_message *m, int *family);
|
||||
int sd_rtnl_message_addr_get_prefixlen(const sd_netlink_message *m, unsigned char *prefixlen);
|
||||
int sd_rtnl_message_addr_get_scope(const sd_netlink_message *m, unsigned char *scope);
|
||||
int sd_rtnl_message_addr_get_flags(const sd_netlink_message *m, unsigned char *flags);
|
||||
int sd_rtnl_message_addr_get_ifindex(const sd_netlink_message *m, int *ifindex);
|
||||
|
||||
int sd_rtnl_message_new_link(sd_netlink *nl, sd_netlink_message **ret, uint16_t msg_type, int index);
|
||||
int sd_rtnl_message_link_set_flags(sd_netlink_message *m, unsigned flags, unsigned change);
|
||||
int sd_rtnl_message_link_set_type(sd_netlink_message *m, unsigned type);
|
||||
int sd_rtnl_message_link_set_family(sd_netlink_message *m, unsigned family);
|
||||
int sd_rtnl_message_link_get_ifindex(sd_netlink_message *m, int *ifindex);
|
||||
int sd_rtnl_message_link_get_flags(sd_netlink_message *m, unsigned *flags);
|
||||
int sd_rtnl_message_link_get_type(sd_netlink_message *m, unsigned short *type);
|
||||
int sd_rtnl_message_link_get_ifindex(const sd_netlink_message *m, int *ifindex);
|
||||
int sd_rtnl_message_link_get_flags(const sd_netlink_message *m, unsigned *flags);
|
||||
int sd_rtnl_message_link_get_type(const sd_netlink_message *m, unsigned short *type);
|
||||
|
||||
int sd_rtnl_message_new_route(sd_netlink *nl, sd_netlink_message **ret, uint16_t nlmsg_type, int rtm_family, unsigned char rtm_protocol);
|
||||
int sd_rtnl_message_route_set_dst_prefixlen(sd_netlink_message *m, unsigned char prefixlen);
|
||||
@ -172,46 +172,46 @@ int sd_rtnl_message_route_set_scope(sd_netlink_message *m, unsigned char scope);
|
||||
int sd_rtnl_message_route_set_flags(sd_netlink_message *m, unsigned flags);
|
||||
int sd_rtnl_message_route_set_table(sd_netlink_message *m, unsigned char table);
|
||||
int sd_rtnl_message_route_set_type(sd_netlink_message *m, unsigned char type);
|
||||
int sd_rtnl_message_route_get_flags(sd_netlink_message *m, unsigned *flags);
|
||||
int sd_rtnl_message_route_get_family(sd_netlink_message *m, int *family);
|
||||
int sd_rtnl_message_route_get_protocol(sd_netlink_message *m, unsigned char *protocol);
|
||||
int sd_rtnl_message_route_get_scope(sd_netlink_message *m, unsigned char *scope);
|
||||
int sd_rtnl_message_route_get_tos(sd_netlink_message *m, unsigned char *tos);
|
||||
int sd_rtnl_message_route_get_table(sd_netlink_message *m, unsigned char *table);
|
||||
int sd_rtnl_message_route_get_dst_prefixlen(sd_netlink_message *m, unsigned char *dst_len);
|
||||
int sd_rtnl_message_route_get_src_prefixlen(sd_netlink_message *m, unsigned char *src_len);
|
||||
int sd_rtnl_message_route_get_type(sd_netlink_message *m, unsigned char *type);
|
||||
int sd_rtnl_message_route_get_flags(const sd_netlink_message *m, unsigned *flags);
|
||||
int sd_rtnl_message_route_get_family(const sd_netlink_message *m, int *family);
|
||||
int sd_rtnl_message_route_get_protocol(const sd_netlink_message *m, unsigned char *protocol);
|
||||
int sd_rtnl_message_route_get_scope(const sd_netlink_message *m, unsigned char *scope);
|
||||
int sd_rtnl_message_route_get_tos(const sd_netlink_message *m, unsigned char *tos);
|
||||
int sd_rtnl_message_route_get_table(const sd_netlink_message *m, unsigned char *table);
|
||||
int sd_rtnl_message_route_get_dst_prefixlen(const sd_netlink_message *m, unsigned char *dst_len);
|
||||
int sd_rtnl_message_route_get_src_prefixlen(const sd_netlink_message *m, unsigned char *src_len);
|
||||
int sd_rtnl_message_route_get_type(const sd_netlink_message *m, unsigned char *type);
|
||||
|
||||
int sd_rtnl_message_new_nexthop(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nhmsg_type, int nh_family, unsigned char nh_protocol);
|
||||
int sd_rtnl_message_nexthop_set_flags(sd_netlink_message *m, uint8_t flags);
|
||||
int sd_rtnl_message_nexthop_get_family(sd_netlink_message *m, uint8_t *family);
|
||||
int sd_rtnl_message_nexthop_get_protocol(sd_netlink_message *m, uint8_t *protocol);
|
||||
int sd_rtnl_message_nexthop_get_family(const sd_netlink_message *m, uint8_t *family);
|
||||
int sd_rtnl_message_nexthop_get_protocol(const sd_netlink_message *m, uint8_t *protocol);
|
||||
|
||||
int sd_rtnl_message_new_neigh(sd_netlink *nl, sd_netlink_message **ret, uint16_t msg_type, int index, int nda_family);
|
||||
int sd_rtnl_message_neigh_set_flags(sd_netlink_message *m, uint8_t flags);
|
||||
int sd_rtnl_message_neigh_set_state(sd_netlink_message *m, uint16_t state);
|
||||
int sd_rtnl_message_neigh_get_family(sd_netlink_message *m, int *family);
|
||||
int sd_rtnl_message_neigh_get_ifindex(sd_netlink_message *m, int *index);
|
||||
int sd_rtnl_message_neigh_get_state(sd_netlink_message *m, uint16_t *state);
|
||||
int sd_rtnl_message_neigh_get_flags(sd_netlink_message *m, uint8_t *flags);
|
||||
int sd_rtnl_message_neigh_get_family(const sd_netlink_message *m, int *family);
|
||||
int sd_rtnl_message_neigh_get_ifindex(const sd_netlink_message *m, int *index);
|
||||
int sd_rtnl_message_neigh_get_state(const sd_netlink_message *m, uint16_t *state);
|
||||
int sd_rtnl_message_neigh_get_flags(const sd_netlink_message *m, uint8_t *flags);
|
||||
|
||||
int sd_rtnl_message_new_addrlabel(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nlmsg_type, int ifindex, int ifal_family);
|
||||
int sd_rtnl_message_addrlabel_set_prefixlen(sd_netlink_message *m, unsigned char prefixlen);
|
||||
int sd_rtnl_message_addrlabel_get_prefixlen(sd_netlink_message *m, unsigned char *prefixlen);
|
||||
int sd_rtnl_message_addrlabel_get_prefixlen(const sd_netlink_message *m, unsigned char *prefixlen);
|
||||
|
||||
int sd_rtnl_message_new_routing_policy_rule(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nlmsg_type, int ifal_family);
|
||||
int sd_rtnl_message_routing_policy_rule_set_tos(sd_netlink_message *m, uint8_t tos);
|
||||
int sd_rtnl_message_routing_policy_rule_get_tos(sd_netlink_message *m, uint8_t *tos);
|
||||
int sd_rtnl_message_routing_policy_rule_get_tos(const sd_netlink_message *m, uint8_t *tos);
|
||||
int sd_rtnl_message_routing_policy_rule_set_table(sd_netlink_message *m, uint8_t table);
|
||||
int sd_rtnl_message_routing_policy_rule_get_table(sd_netlink_message *m, uint8_t *table);
|
||||
int sd_rtnl_message_routing_policy_rule_get_table(const sd_netlink_message *m, uint8_t *table);
|
||||
int sd_rtnl_message_routing_policy_rule_set_fib_src_prefixlen(sd_netlink_message *m, uint8_t len);
|
||||
int sd_rtnl_message_routing_policy_rule_get_fib_src_prefixlen(sd_netlink_message *m, uint8_t *len);
|
||||
int sd_rtnl_message_routing_policy_rule_get_fib_src_prefixlen(const sd_netlink_message *m, uint8_t *len);
|
||||
int sd_rtnl_message_routing_policy_rule_set_fib_dst_prefixlen(sd_netlink_message *m, uint8_t len);
|
||||
int sd_rtnl_message_routing_policy_rule_get_fib_dst_prefixlen(sd_netlink_message *m, uint8_t *len);
|
||||
int sd_rtnl_message_routing_policy_rule_get_fib_dst_prefixlen(const sd_netlink_message *m, uint8_t *len);
|
||||
int sd_rtnl_message_routing_policy_rule_set_fib_type(sd_netlink_message *m, uint8_t type);
|
||||
int sd_rtnl_message_routing_policy_rule_get_fib_type(sd_netlink_message *m, uint8_t *type);
|
||||
int sd_rtnl_message_routing_policy_rule_get_fib_type(const sd_netlink_message *m, uint8_t *type);
|
||||
int sd_rtnl_message_routing_policy_rule_set_flags(sd_netlink_message *m, uint32_t flags);
|
||||
int sd_rtnl_message_routing_policy_rule_get_flags(sd_netlink_message *m, uint32_t *flags);
|
||||
int sd_rtnl_message_routing_policy_rule_get_flags(const sd_netlink_message *m, uint32_t *flags);
|
||||
|
||||
int sd_rtnl_message_new_qdisc(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t nlmsg_type, int tcm_family, int tcm_ifindex);
|
||||
int sd_rtnl_message_set_qdisc_parent(sd_netlink_message *m, uint32_t parent);
|
||||
@ -252,7 +252,7 @@ int sd_nfnl_nft_message_add_setelem_end(sd_netlink_message *m);
|
||||
/* genl */
|
||||
int sd_genl_socket_open(sd_netlink **nl);
|
||||
int sd_genl_message_new(sd_netlink *nl, sd_genl_family_t family, uint8_t cmd, sd_netlink_message **m);
|
||||
int sd_genl_message_get_family(sd_netlink *nl, sd_netlink_message *m, sd_genl_family_t *family);
|
||||
int sd_genl_message_get_family(const sd_netlink *nl, const sd_netlink_message *m, sd_genl_family_t *family);
|
||||
|
||||
/* slot */
|
||||
sd_netlink_slot *sd_netlink_slot_ref(sd_netlink_slot *nl);
|
||||
@ -261,11 +261,11 @@ sd_netlink_slot *sd_netlink_slot_unref(sd_netlink_slot *nl);
|
||||
sd_netlink *sd_netlink_slot_get_netlink(sd_netlink_slot *slot);
|
||||
void *sd_netlink_slot_get_userdata(sd_netlink_slot *slot);
|
||||
void *sd_netlink_slot_set_userdata(sd_netlink_slot *slot, void *userdata);
|
||||
int sd_netlink_slot_get_destroy_callback(sd_netlink_slot *slot, sd_netlink_destroy_t *callback);
|
||||
int sd_netlink_slot_get_destroy_callback(const sd_netlink_slot *slot, sd_netlink_destroy_t *callback);
|
||||
int sd_netlink_slot_set_destroy_callback(sd_netlink_slot *slot, sd_netlink_destroy_t callback);
|
||||
int sd_netlink_slot_get_floating(sd_netlink_slot *slot);
|
||||
int sd_netlink_slot_get_floating(const sd_netlink_slot *slot);
|
||||
int sd_netlink_slot_set_floating(sd_netlink_slot *slot, int b);
|
||||
int sd_netlink_slot_get_description(sd_netlink_slot *slot, const char **description);
|
||||
int sd_netlink_slot_get_description(const sd_netlink_slot *slot, const char **description);
|
||||
int sd_netlink_slot_set_description(sd_netlink_slot *slot, const char *description);
|
||||
|
||||
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_netlink, sd_netlink_unref);
|
||||
|
||||
@ -1492,7 +1492,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
||||
name = mfree(name);
|
||||
|
||||
if (name) {
|
||||
r = specifier_printf(name, NAME_MAX, specifier_table, NULL, &resolved_name);
|
||||
r = specifier_printf(name, specifier_table, NULL, &resolved_name);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m", fname, line, name);
|
||||
|
||||
@ -1507,7 +1507,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
||||
id = mfree(id);
|
||||
|
||||
if (id) {
|
||||
r = specifier_printf(id, PATH_MAX-1, specifier_table, NULL, &resolved_id);
|
||||
r = specifier_printf(id, specifier_table, NULL, &resolved_id);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m",
|
||||
fname, line, name);
|
||||
@ -1518,7 +1518,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
||||
description = mfree(description);
|
||||
|
||||
if (description) {
|
||||
r = specifier_printf(description, LONG_LINE_MAX, specifier_table, NULL, &resolved_description);
|
||||
r = specifier_printf(description, specifier_table, NULL, &resolved_description);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m",
|
||||
fname, line, description);
|
||||
@ -1534,7 +1534,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
||||
home = mfree(home);
|
||||
|
||||
if (home) {
|
||||
r = specifier_printf(home, PATH_MAX-1, specifier_table, NULL, &resolved_home);
|
||||
r = specifier_printf(home, specifier_table, NULL, &resolved_home);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m",
|
||||
fname, line, home);
|
||||
@ -1550,7 +1550,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
|
||||
shell = mfree(shell);
|
||||
|
||||
if (shell) {
|
||||
r = specifier_printf(shell, PATH_MAX-1, specifier_table, NULL, &resolved_shell);
|
||||
r = specifier_printf(shell, specifier_table, NULL, &resolved_shell);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m",
|
||||
fname, line, shell);
|
||||
|
||||
@ -512,7 +512,7 @@ static void test_install_printf(void) {
|
||||
_cleanup_free_ char \
|
||||
*d1 = strdup(i.name), \
|
||||
*d2 = strdup(i.path); \
|
||||
assert_se(install_name_printf(&src, pattern, &t) >= 0 || !result); \
|
||||
assert_se(install_full_printf(&src, pattern, &t) >= 0 || !result); \
|
||||
memzero(i.name, strlen(i.name)); \
|
||||
memzero(i.path, strlen(i.path)); \
|
||||
assert_se(d1 && d2); \
|
||||
|
||||
@ -141,8 +141,8 @@ int main(int argc, char *argv[]) {
|
||||
assert_se(manager_startup(m, NULL, NULL) >= 0);
|
||||
|
||||
assert_se(test_socket_bind(m, "socket_bind_test.service", netcat_path, "2000", STRV_MAKE("2000"), STRV_MAKE("any")) >= 0);
|
||||
assert_se(test_socket_bind(m, "socket_bind_test.service", netcat_path, "2000", STRV_MAKE("ipv6:2001-2002"), STRV_MAKE("any")) >= 0);
|
||||
assert_se(test_socket_bind(m, "socket_bind_test.service", netcat_path, "6666", STRV_MAKE("ipv4:6666", "6667"), STRV_MAKE("any")) >= 0);
|
||||
assert_se(test_socket_bind(m, "socket_bind_test.service", netcat_path, "2000", STRV_MAKE("IPv6:2001-2002"), STRV_MAKE("any")) >= 0);
|
||||
assert_se(test_socket_bind(m, "socket_bind_test.service", netcat_path, "6666", STRV_MAKE("IPv4:6666", "6667"), STRV_MAKE("any")) >= 0);
|
||||
assert_se(test_socket_bind(m, "socket_bind_test.service", netcat_path, "6666", STRV_MAKE("6667", "6668", ""), STRV_MAKE("any")) >= 0);
|
||||
assert_se(test_socket_bind(m, "socket_bind_test.service", netcat_path, "7777", STRV_MAKE_EMPTY, STRV_MAKE_EMPTY) >= 0);
|
||||
assert_se(test_socket_bind(m, "socket_bind_test.service", netcat_path, "8888", STRV_MAKE("any"), STRV_MAKE("any")) >= 0);
|
||||
|
||||
@ -56,38 +56,6 @@ static const Specifier specifier_table[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
static void test_specifier_printf(void) {
|
||||
static const Specifier table[] = {
|
||||
{ 'X', specifier_string, (char*) "AAAA" },
|
||||
{ 'Y', specifier_string, (char*) "BBBB" },
|
||||
COMMON_SYSTEM_SPECIFIERS,
|
||||
{}
|
||||
};
|
||||
|
||||
_cleanup_free_ char *w = NULL;
|
||||
int r;
|
||||
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
r = specifier_printf("xxx a=%X b=%Y yyy", SIZE_MAX, table, NULL, &w);
|
||||
assert_se(r >= 0);
|
||||
assert_se(w);
|
||||
|
||||
puts(w);
|
||||
assert_se(streq(w, "xxx a=AAAA b=BBBB yyy"));
|
||||
|
||||
free(w);
|
||||
r = specifier_printf("machine=%m, boot=%b, host=%H, version=%v, arch=%a", SIZE_MAX, table, NULL, &w);
|
||||
assert_se(r >= 0);
|
||||
assert_se(w);
|
||||
puts(w);
|
||||
|
||||
w = mfree(w);
|
||||
specifier_printf("os=%o, os-version=%w, build=%B, variant=%W", SIZE_MAX, table, NULL, &w);
|
||||
if (w)
|
||||
puts(w);
|
||||
}
|
||||
|
||||
static void test_specifiers(void) {
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
@ -97,7 +65,7 @@ static void test_specifiers(void) {
|
||||
|
||||
xsprintf(spec, "%%%c", s->specifier);
|
||||
|
||||
assert_se(specifier_printf(spec, SIZE_MAX, specifier_table, NULL, &resolved) >= 0);
|
||||
assert_se(specifier_printf(spec, specifier_table, NULL, &resolved) >= 0);
|
||||
|
||||
log_info("%%%c → %s", s->specifier, resolved);
|
||||
}
|
||||
@ -108,7 +76,6 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
test_specifier_escape();
|
||||
test_specifier_escape_strv();
|
||||
test_specifier_printf();
|
||||
test_specifiers();
|
||||
|
||||
return 0;
|
||||
|
||||
@ -3,9 +3,42 @@
|
||||
#include "alloc-util.h"
|
||||
#include "escape.h"
|
||||
#include "nulstr-util.h"
|
||||
#include "specifier.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
|
||||
static void test_specifier_printf(void) {
|
||||
static const Specifier table[] = {
|
||||
{ 'X', specifier_string, (char*) "AAAA" },
|
||||
{ 'Y', specifier_string, (char*) "BBBB" },
|
||||
COMMON_SYSTEM_SPECIFIERS,
|
||||
{}
|
||||
};
|
||||
|
||||
_cleanup_free_ char *w = NULL;
|
||||
int r;
|
||||
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
r = specifier_printf("xxx a=%X b=%Y yyy", table, NULL, &w);
|
||||
assert_se(r >= 0);
|
||||
assert_se(w);
|
||||
|
||||
puts(w);
|
||||
assert_se(streq(w, "xxx a=AAAA b=BBBB yyy"));
|
||||
|
||||
free(w);
|
||||
r = specifier_printf("machine=%m, boot=%b, host=%H, version=%v, arch=%a", table, NULL, &w);
|
||||
assert_se(r >= 0);
|
||||
assert_se(w);
|
||||
puts(w);
|
||||
|
||||
w = mfree(w);
|
||||
specifier_printf("os=%o, os-version=%w, build=%B, variant=%W", table, NULL, &w);
|
||||
if (w)
|
||||
puts(w);
|
||||
}
|
||||
|
||||
static void test_str_in_set(void) {
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
@ -989,6 +1022,7 @@ static void test_strv_fnmatch(void) {
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
test_specifier_printf();
|
||||
test_str_in_set();
|
||||
test_strptr_in_set();
|
||||
test_startswith_set();
|
||||
|
||||
@ -2522,7 +2522,7 @@ static int specifier_expansion_from_arg(Item *i) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to unescape parameter to write: %s", i->argument);
|
||||
|
||||
r = specifier_printf(unescaped, PATH_MAX-1, specifier_table, NULL, &resolved);
|
||||
r = specifier_printf(unescaped, specifier_table, NULL, &resolved);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -2532,7 +2532,7 @@ static int specifier_expansion_from_arg(Item *i) {
|
||||
case SET_XATTR:
|
||||
case RECURSIVE_SET_XATTR:
|
||||
STRV_FOREACH(xattr, i->xattrs) {
|
||||
r = specifier_printf(*xattr, SIZE_MAX, specifier_table, NULL, &resolved);
|
||||
r = specifier_printf(*xattr, specifier_table, NULL, &resolved);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -2706,7 +2706,7 @@ static int parse_line(
|
||||
i.append_or_force = append_or_force;
|
||||
i.allow_failure = allow_failure;
|
||||
|
||||
r = specifier_printf(path, PATH_MAX-1, specifier_table, NULL, &i.path);
|
||||
r = specifier_printf(path, specifier_table, NULL, &i.path);
|
||||
if (r == -ENXIO)
|
||||
return log_unresolvable_specifier(fname, line);
|
||||
if (r < 0) {
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
set -e
|
||||
|
||||
out="${1:?}"
|
||||
systemd_efi="${2:?}"
|
||||
boot_stub="${3:?}"
|
||||
splash_bmp="${4:?}"
|
||||
|
||||
efi_dir="$(bootctl -p)"
|
||||
entry_dir="${efi_dir}/$(cat /etc/machine-id)/$(uname -r)"
|
||||
out="$1"
|
||||
systemd_efi="$2"
|
||||
boot_stub="$3"
|
||||
splash_bmp="$4"
|
||||
if [ -z "$out" -o -z "$systemd_efi" -o -z "$boot_stub" -o -z "$splash_bmp" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# create GPT table with EFI System Partition
|
||||
rm -f "$out"
|
||||
@ -15,17 +15,15 @@ dd if=/dev/null of="$out" bs=1M seek=512 count=1 status=none
|
||||
parted --script "$out" "mklabel gpt" "mkpart ESP fat32 1MiB 511MiB" "set 1 boot on"
|
||||
|
||||
# create FAT32 file system
|
||||
LOOP="$(losetup --show -f -P "$out")"
|
||||
mkfs.vfat -F32 "${LOOP}p1"
|
||||
LOOP=$(losetup --show -f -P "$out")
|
||||
mkfs.vfat -F32 ${LOOP}p1
|
||||
mkdir -p mnt
|
||||
mount "${LOOP}p1" mnt
|
||||
mount ${LOOP}p1 mnt
|
||||
|
||||
mkdir -p mnt/EFI/{BOOT,systemd}
|
||||
cp "$systemd_efi" mnt/EFI/BOOT/BOOTX64.efi
|
||||
|
||||
if [ -e /boot/shellx64.efi ]; then
|
||||
cp /boot/shellx64.efi mnt/
|
||||
fi
|
||||
[ -e /boot/shellx64.efi ] && cp /boot/shellx64.efi mnt/
|
||||
|
||||
mkdir mnt/EFI/Linux
|
||||
echo -n "foo=yes bar=no root=/dev/fakeroot debug rd.break=initqueue" >mnt/cmdline.txt
|
||||
@ -33,8 +31,8 @@ objcopy \
|
||||
--add-section .osrel=/etc/os-release --change-section-vma .osrel=0x20000 \
|
||||
--add-section .cmdline=mnt/cmdline.txt --change-section-vma .cmdline=0x30000 \
|
||||
--add-section .splash="$splash_bmp" --change-section-vma .splash=0x40000 \
|
||||
--add-section .linux="${entry_dir}/linux" --change-section-vma .linux=0x2000000 \
|
||||
--add-section .initrd="${entry_dir}/initrd" --change-section-vma .initrd=0x3000000 \
|
||||
--add-section .linux=/boot/$(cat /etc/machine-id)/$(uname -r)/linux --change-section-vma .linux=0x2000000 \
|
||||
--add-section .initrd=/boot/$(cat /etc/machine-id)/$(uname -r)/initrd --change-section-vma .initrd=0x3000000 \
|
||||
"$boot_stub" mnt/EFI/Linux/linux-test.efi
|
||||
|
||||
# install entries
|
||||
@ -50,4 +48,4 @@ echo -e "title Test6\nlinux /test6\n" > mnt/loader/entries/test6.conf
|
||||
sync
|
||||
umount mnt
|
||||
rmdir mnt
|
||||
losetup -d "$LOOP"
|
||||
losetup -d $LOOP
|
||||
|
||||
@ -2784,16 +2784,20 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
||||
expect_up = initial_up
|
||||
next_up = not expect_up
|
||||
|
||||
# if initial expected state is down, must wait for setup_state to reach configuring
|
||||
# so systemd-networkd considers it 'activated'
|
||||
setup_state = None if initial_up else 'configuring'
|
||||
|
||||
for iteration in range(4):
|
||||
with self.subTest(iteration=iteration, expect_up=expect_up):
|
||||
operstate = 'routable' if expect_up else 'off'
|
||||
setup_state = 'configured' if expect_up else None
|
||||
self.wait_operstate('test1', operstate, setup_state=setup_state, setup_timeout=20)
|
||||
setup_state = None
|
||||
|
||||
if expect_up:
|
||||
self.assertIn('UP', check_output('ip link show test1'))
|
||||
self.assertIn('192.168.10.30/24', check_output('ip address show test1'))
|
||||
self.assertIn('default via 192.168.10.1', check_output('ip route show dev test1'))
|
||||
self.assertIn('default via 192.168.10.1', check_output('ip route show'))
|
||||
else:
|
||||
self.assertIn('DOWN', check_output('ip link show test1'))
|
||||
|
||||
@ -2896,8 +2900,6 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
||||
self.assertEqual(rc, 0)
|
||||
time.sleep(1)
|
||||
|
||||
self.wait_online(['veth99:routable', 'veth-peer:routable'])
|
||||
|
||||
output = check_output('ip nexthop list dev veth99')
|
||||
print(output)
|
||||
self.assertEqual(output, '')
|
||||
@ -2911,8 +2913,6 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
||||
self.assertEqual(rc, 0)
|
||||
time.sleep(1)
|
||||
|
||||
self.wait_online(['veth99:routable', 'veth-peer:routable'])
|
||||
|
||||
rc = call('ip link del veth99')
|
||||
self.assertEqual(rc, 0)
|
||||
time.sleep(2)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user