mirror of
https://github.com/systemd/systemd
synced 2025-11-13 13:54:45 +01:00
Compare commits
No commits in common. "dfc637d0ff756889e8e5b7cb4ec991eb06069aa1" and "5fad3913e2db5eda2339419e049af88953c17ff3" have entirely different histories.
dfc637d0ff
...
5fad3913e2
4
TODO
4
TODO
@ -29,6 +29,10 @@ Features:
|
|||||||
* Add service setting to run a service within the specified VRF. i.e. do the
|
* Add service setting to run a service within the specified VRF. i.e. do the
|
||||||
equivalent of "ip vrf exec".
|
equivalent of "ip vrf exec".
|
||||||
|
|
||||||
|
* systemd-analyze syscall-filter should show a list of syscalls listed in
|
||||||
|
@known but not in other groups (at least at debug level), since they are
|
||||||
|
candidates to be added to them.
|
||||||
|
|
||||||
* export action of device object on sd-device, so that monitor becomes useful
|
* export action of device object on sd-device, so that monitor becomes useful
|
||||||
|
|
||||||
* add root=tmpfs that mounts a tmpfs to /sysroot (to be used in combination
|
* add root=tmpfs that mounts a tmpfs to /sysroot (to be used in combination
|
||||||
|
|||||||
@ -1685,7 +1685,7 @@ static int load_kernel_syscalls(Set **ret) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void syscall_set_remove(Set *s, const SyscallFilterSet *set) {
|
static void kernel_syscalls_remove(Set *s, const SyscallFilterSet *set) {
|
||||||
const char *syscall;
|
const char *syscall;
|
||||||
|
|
||||||
NULSTR_FOREACH(syscall, set->value) {
|
NULSTR_FOREACH(syscall, set->value) {
|
||||||
@ -1716,14 +1716,9 @@ static int dump_syscall_filters(int argc, char *argv[], void *userdata) {
|
|||||||
(void) pager_open(arg_pager_flags);
|
(void) pager_open(arg_pager_flags);
|
||||||
|
|
||||||
if (strv_isempty(strv_skip(argv, 1))) {
|
if (strv_isempty(strv_skip(argv, 1))) {
|
||||||
_cleanup_set_free_ Set *kernel = NULL, *known = NULL;
|
_cleanup_set_free_ Set *kernel = NULL;
|
||||||
const char *sys;
|
|
||||||
int i, k;
|
int i, k;
|
||||||
|
|
||||||
NULSTR_FOREACH(sys, syscall_filter_sets[SYSCALL_FILTER_SET_KNOWN].value)
|
|
||||||
if (set_put_strdup(&known, sys) < 0)
|
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
k = load_kernel_syscalls(&kernel);
|
k = load_kernel_syscalls(&kernel);
|
||||||
|
|
||||||
for (i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) {
|
for (i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) {
|
||||||
@ -1732,30 +1727,10 @@ static int dump_syscall_filters(int argc, char *argv[], void *userdata) {
|
|||||||
puts("");
|
puts("");
|
||||||
|
|
||||||
dump_syscall_filter(set);
|
dump_syscall_filter(set);
|
||||||
syscall_set_remove(kernel, set);
|
kernel_syscalls_remove(kernel, set);
|
||||||
if (i != SYSCALL_FILTER_SET_KNOWN)
|
|
||||||
syscall_set_remove(known, set);
|
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!set_isempty(known)) {
|
|
||||||
_cleanup_free_ char **l = NULL;
|
|
||||||
char **syscall;
|
|
||||||
|
|
||||||
printf("\n"
|
|
||||||
"# %sUngrouped System Calls%s (known but not included in any of the groups except @known):\n",
|
|
||||||
ansi_highlight(), ansi_normal());
|
|
||||||
|
|
||||||
l = set_get_strv(known);
|
|
||||||
if (!l)
|
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
strv_sort(l);
|
|
||||||
|
|
||||||
STRV_FOREACH(syscall, l)
|
|
||||||
printf("# %s\n", *syscall);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (k < 0) {
|
if (k < 0) {
|
||||||
fputc('\n', stdout);
|
fputc('\n', stdout);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|||||||
@ -444,9 +444,6 @@ static inline int __coverity_check_and_return__(int condition) {
|
|||||||
#define PTR_TO_ULONG(p) ((unsigned long) ((uintptr_t) (p)))
|
#define PTR_TO_ULONG(p) ((unsigned long) ((uintptr_t) (p)))
|
||||||
#define ULONG_TO_PTR(u) ((void *) ((uintptr_t) (u)))
|
#define ULONG_TO_PTR(u) ((void *) ((uintptr_t) (u)))
|
||||||
|
|
||||||
#define PTR_TO_UINT8(p) ((uint8_t) ((uintptr_t) (p)))
|
|
||||||
#define UINT8_TO_PTR(u) ((void *) ((uintptr_t) (u)))
|
|
||||||
|
|
||||||
#define PTR_TO_INT32(p) ((int32_t) ((intptr_t) (p)))
|
#define PTR_TO_INT32(p) ((int32_t) ((intptr_t) (p)))
|
||||||
#define INT32_TO_PTR(u) ((void *) ((intptr_t) (u)))
|
#define INT32_TO_PTR(u) ((void *) ((intptr_t) (u)))
|
||||||
#define PTR_TO_UINT32(p) ((uint32_t) ((uintptr_t) (p)))
|
#define PTR_TO_UINT32(p) ((uint32_t) ((uintptr_t) (p)))
|
||||||
|
|||||||
@ -25,8 +25,6 @@
|
|||||||
#include "io-util.h"
|
#include "io-util.h"
|
||||||
#include "memory-util.h"
|
#include "memory-util.h"
|
||||||
#include "random-util.h"
|
#include "random-util.h"
|
||||||
#include "set.h"
|
|
||||||
#include "sort-util.h"
|
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
#include "strv.h"
|
#include "strv.h"
|
||||||
#include "utf8.h"
|
#include "utf8.h"
|
||||||
@ -77,7 +75,9 @@ struct sd_dhcp_client {
|
|||||||
union sockaddr_union link;
|
union sockaddr_union link;
|
||||||
sd_event_source *receive_message;
|
sd_event_source *receive_message;
|
||||||
bool request_broadcast;
|
bool request_broadcast;
|
||||||
Set *req_opts;
|
uint8_t *req_opts;
|
||||||
|
size_t req_opts_allocated;
|
||||||
|
size_t req_opts_size;
|
||||||
bool anonymize;
|
bool anonymize;
|
||||||
be32_t last_addr;
|
be32_t last_addr;
|
||||||
uint8_t mac_addr[MAX_MAC_ADDR_LEN];
|
uint8_t mac_addr[MAX_MAC_ADDR_LEN];
|
||||||
@ -230,6 +230,8 @@ int sd_dhcp_client_set_request_broadcast(sd_dhcp_client *client, int broadcast)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option) {
|
int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option) {
|
||||||
|
size_t i;
|
||||||
|
|
||||||
assert_return(client, -EINVAL);
|
assert_return(client, -EINVAL);
|
||||||
assert_return(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED), -EBUSY);
|
assert_return(IN_SET(client->state, DHCP_STATE_INIT, DHCP_STATE_STOPPED), -EBUSY);
|
||||||
|
|
||||||
@ -246,7 +248,17 @@ int sd_dhcp_client_set_request_option(sd_dhcp_client *client, uint8_t option) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return set_ensure_put(&client->req_opts, NULL, UINT8_TO_PTR(option));
|
for (i = 0; i < client->req_opts_size; i++)
|
||||||
|
if (client->req_opts[i] == option)
|
||||||
|
return -EEXIST;
|
||||||
|
|
||||||
|
if (!GREEDY_REALLOC(client->req_opts, client->req_opts_allocated,
|
||||||
|
client->req_opts_size + 1))
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
client->req_opts[client->req_opts_size++] = option;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sd_dhcp_client_set_request_address(
|
int sd_dhcp_client_set_request_address(
|
||||||
@ -713,10 +725,6 @@ static void client_stop(sd_dhcp_client *client, int error) {
|
|||||||
client_initialize(client);
|
client_initialize(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cmp_uint8(const uint8_t *a, const uint8_t *b) {
|
|
||||||
return CMP(*a, *b);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int client_message_init(
|
static int client_message_init(
|
||||||
sd_dhcp_client *client,
|
sd_dhcp_client *client,
|
||||||
DHCPPacket **ret,
|
DHCPPacket **ret,
|
||||||
@ -827,26 +835,10 @@ static int client_message_init(
|
|||||||
MAY contain the Parameter Request List option. */
|
MAY contain the Parameter Request List option. */
|
||||||
/* NOTE: in case that there would be an option to do not send
|
/* NOTE: in case that there would be an option to do not send
|
||||||
* any PRL at all, the size should be checked before sending */
|
* any PRL at all, the size should be checked before sending */
|
||||||
if (!set_isempty(client->req_opts) && type != DHCP_RELEASE) {
|
if (client->req_opts_size > 0 && type != DHCP_RELEASE) {
|
||||||
_cleanup_free_ uint8_t *opts = NULL;
|
|
||||||
size_t n_opts, i = 0;
|
|
||||||
void *val;
|
|
||||||
|
|
||||||
n_opts = set_size(client->req_opts);
|
|
||||||
opts = new(uint8_t, n_opts);
|
|
||||||
if (!opts)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
SET_FOREACH(val, client->req_opts)
|
|
||||||
opts[i++] = PTR_TO_UINT8(val);
|
|
||||||
assert(i == n_opts);
|
|
||||||
|
|
||||||
/* For anonymizing the request, let's sort the options. */
|
|
||||||
typesafe_qsort(opts, n_opts, cmp_uint8);
|
|
||||||
|
|
||||||
r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
|
r = dhcp_option_append(&packet->dhcp, optlen, &optoffset, 0,
|
||||||
SD_DHCP_OPTION_PARAMETER_REQUEST_LIST,
|
SD_DHCP_OPTION_PARAMETER_REQUEST_LIST,
|
||||||
n_opts, opts);
|
client->req_opts_size, client->req_opts);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -2195,7 +2187,7 @@ static sd_dhcp_client *dhcp_client_free(sd_dhcp_client *client) {
|
|||||||
|
|
||||||
sd_dhcp_lease_unref(client->lease);
|
sd_dhcp_lease_unref(client->lease);
|
||||||
|
|
||||||
set_free(client->req_opts);
|
free(client->req_opts);
|
||||||
free(client->hostname);
|
free(client->hostname);
|
||||||
free(client->vendor_class_identifier);
|
free(client->vendor_class_identifier);
|
||||||
free(client->mudurl);
|
free(client->mudurl);
|
||||||
@ -2208,10 +2200,6 @@ static sd_dhcp_client *dhcp_client_free(sd_dhcp_client *client) {
|
|||||||
DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_client, sd_dhcp_client, dhcp_client_free);
|
DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_dhcp_client, sd_dhcp_client, dhcp_client_free);
|
||||||
|
|
||||||
int sd_dhcp_client_new(sd_dhcp_client **ret, int anonymize) {
|
int sd_dhcp_client_new(sd_dhcp_client **ret, int anonymize) {
|
||||||
const uint8_t *opts;
|
|
||||||
size_t n_opts;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
assert_return(ret, -EINVAL);
|
assert_return(ret, -EINVAL);
|
||||||
|
|
||||||
_cleanup_(sd_dhcp_client_unrefp) sd_dhcp_client *client = new(sd_dhcp_client, 1);
|
_cleanup_(sd_dhcp_client_unrefp) sd_dhcp_client *client = new(sd_dhcp_client, 1);
|
||||||
@ -2231,18 +2219,14 @@ int sd_dhcp_client_new(sd_dhcp_client **ret, int anonymize) {
|
|||||||
};
|
};
|
||||||
/* NOTE: this could be moved to a function. */
|
/* NOTE: this could be moved to a function. */
|
||||||
if (anonymize) {
|
if (anonymize) {
|
||||||
n_opts = ELEMENTSOF(default_req_opts_anonymize);
|
client->req_opts_size = ELEMENTSOF(default_req_opts_anonymize);
|
||||||
opts = default_req_opts_anonymize;
|
client->req_opts = memdup(default_req_opts_anonymize, client->req_opts_size);
|
||||||
} else {
|
} else {
|
||||||
n_opts = ELEMENTSOF(default_req_opts);
|
client->req_opts_size = ELEMENTSOF(default_req_opts);
|
||||||
opts = default_req_opts;
|
client->req_opts = memdup(default_req_opts, client->req_opts_size);
|
||||||
}
|
|
||||||
|
|
||||||
for (size_t i = 0; i < n_opts; i++) {
|
|
||||||
r = sd_dhcp_client_set_request_option(client, opts[i]);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
if (!client->req_opts)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
*ret = TAKE_PTR(client);
|
*ret = TAKE_PTR(client);
|
||||||
|
|
||||||
|
|||||||
@ -71,29 +71,40 @@ static void test_request_basic(sd_event *e) {
|
|||||||
assert_se(sd_dhcp_client_set_hostname(client, "~host") == -EINVAL);
|
assert_se(sd_dhcp_client_set_hostname(client, "~host") == -EINVAL);
|
||||||
assert_se(sd_dhcp_client_set_hostname(client, "~host.domain") == -EINVAL);
|
assert_se(sd_dhcp_client_set_hostname(client, "~host.domain") == -EINVAL);
|
||||||
|
|
||||||
assert_se(sd_dhcp_client_set_request_option(client, SD_DHCP_OPTION_SUBNET_MASK) == 0);
|
assert_se(sd_dhcp_client_set_request_option(client,
|
||||||
assert_se(sd_dhcp_client_set_request_option(client, SD_DHCP_OPTION_ROUTER) == 0);
|
SD_DHCP_OPTION_SUBNET_MASK) == -EEXIST);
|
||||||
|
assert_se(sd_dhcp_client_set_request_option(client,
|
||||||
|
SD_DHCP_OPTION_ROUTER) == -EEXIST);
|
||||||
/* This PRL option is not set when using Anonymize, but in this test
|
/* This PRL option is not set when using Anonymize, but in this test
|
||||||
* Anonymize settings are not being used. */
|
* Anonymize settings are not being used. */
|
||||||
assert_se(sd_dhcp_client_set_request_option(client, SD_DHCP_OPTION_HOST_NAME) == 0);
|
assert_se(sd_dhcp_client_set_request_option(client,
|
||||||
assert_se(sd_dhcp_client_set_request_option(client, SD_DHCP_OPTION_DOMAIN_NAME) == 0);
|
SD_DHCP_OPTION_HOST_NAME) == -EEXIST);
|
||||||
assert_se(sd_dhcp_client_set_request_option(client, SD_DHCP_OPTION_DOMAIN_NAME_SERVER) == 0);
|
assert_se(sd_dhcp_client_set_request_option(client,
|
||||||
|
SD_DHCP_OPTION_DOMAIN_NAME) == -EEXIST);
|
||||||
|
assert_se(sd_dhcp_client_set_request_option(client,
|
||||||
|
SD_DHCP_OPTION_DOMAIN_NAME_SERVER) == -EEXIST);
|
||||||
|
|
||||||
assert_se(sd_dhcp_client_set_request_option(client, SD_DHCP_OPTION_PAD) == -EINVAL);
|
assert_se(sd_dhcp_client_set_request_option(client,
|
||||||
assert_se(sd_dhcp_client_set_request_option(client, SD_DHCP_OPTION_END) == -EINVAL);
|
SD_DHCP_OPTION_PAD) == -EINVAL);
|
||||||
assert_se(sd_dhcp_client_set_request_option(client, SD_DHCP_OPTION_MESSAGE_TYPE) == -EINVAL);
|
assert_se(sd_dhcp_client_set_request_option(client,
|
||||||
assert_se(sd_dhcp_client_set_request_option(client, SD_DHCP_OPTION_OVERLOAD) == -EINVAL);
|
SD_DHCP_OPTION_END) == -EINVAL);
|
||||||
assert_se(sd_dhcp_client_set_request_option(client, SD_DHCP_OPTION_PARAMETER_REQUEST_LIST) == -EINVAL);
|
assert_se(sd_dhcp_client_set_request_option(client,
|
||||||
|
SD_DHCP_OPTION_MESSAGE_TYPE) == -EINVAL);
|
||||||
|
assert_se(sd_dhcp_client_set_request_option(client,
|
||||||
|
SD_DHCP_OPTION_OVERLOAD) == -EINVAL);
|
||||||
|
assert_se(sd_dhcp_client_set_request_option(client,
|
||||||
|
SD_DHCP_OPTION_PARAMETER_REQUEST_LIST)
|
||||||
|
== -EINVAL);
|
||||||
|
|
||||||
/* RFC7844: option 33 (SD_DHCP_OPTION_STATIC_ROUTE) is set in the
|
/* RFC7844: option 33 (SD_DHCP_OPTION_STATIC_ROUTE) is set in the
|
||||||
* default PRL when using Anonymize, so it is changed to other option
|
* default PRL when using Anonymize, so it is changed to other option
|
||||||
* that is not set by default, to check that it was set successfully.
|
* that is not set by default, to check that it was set successfully.
|
||||||
* Options not set by default (using or not anonymize) are option 17
|
* Options not set by default (using or not anonymize) are option 17
|
||||||
* (SD_DHCP_OPTION_ROOT_PATH) and 42 (SD_DHCP_OPTION_NTP_SERVER) */
|
* (SD_DHCP_OPTION_ROOT_PATH) and 42 (SD_DHCP_OPTION_NTP_SERVER) */
|
||||||
assert_se(sd_dhcp_client_set_request_option(client, 17) == 1);
|
|
||||||
assert_se(sd_dhcp_client_set_request_option(client, 17) == 0);
|
|
||||||
assert_se(sd_dhcp_client_set_request_option(client, 42) == 1);
|
|
||||||
assert_se(sd_dhcp_client_set_request_option(client, 17) == 0);
|
assert_se(sd_dhcp_client_set_request_option(client, 17) == 0);
|
||||||
|
assert_se(sd_dhcp_client_set_request_option(client, 17) == -EEXIST);
|
||||||
|
assert_se(sd_dhcp_client_set_request_option(client, 42) == 0);
|
||||||
|
assert_se(sd_dhcp_client_set_request_option(client, 17) == -EEXIST);
|
||||||
|
|
||||||
sd_dhcp_client_unref(client);
|
sd_dhcp_client_unref(client);
|
||||||
}
|
}
|
||||||
@ -115,15 +126,19 @@ static void test_request_anonymize(sd_event *e) {
|
|||||||
r = sd_dhcp_client_attach_event(client, e, 0);
|
r = sd_dhcp_client_attach_event(client, e, 0);
|
||||||
assert_se(r >= 0);
|
assert_se(r >= 0);
|
||||||
|
|
||||||
assert_se(sd_dhcp_client_set_request_option(client, SD_DHCP_OPTION_NETBIOS_NAMESERVER) == 0);
|
assert_se(sd_dhcp_client_set_request_option(client,
|
||||||
|
SD_DHCP_OPTION_NETBIOS_NAMESERVER) == -EEXIST);
|
||||||
/* This PRL option is not set when using Anonymize */
|
/* This PRL option is not set when using Anonymize */
|
||||||
assert_se(sd_dhcp_client_set_request_option(client, SD_DHCP_OPTION_HOST_NAME) == 1);
|
assert_se(sd_dhcp_client_set_request_option(client,
|
||||||
assert_se(sd_dhcp_client_set_request_option(client, SD_DHCP_OPTION_PARAMETER_REQUEST_LIST) == -EINVAL);
|
SD_DHCP_OPTION_HOST_NAME) == 0);
|
||||||
|
assert_se(sd_dhcp_client_set_request_option(client,
|
||||||
|
SD_DHCP_OPTION_PARAMETER_REQUEST_LIST)
|
||||||
|
== -EINVAL);
|
||||||
|
|
||||||
/* RFC7844: option 101 (SD_DHCP_OPTION_NEW_TZDB_TIMEZONE) is not set in the
|
/* RFC7844: option 101 (SD_DHCP_OPTION_NEW_TZDB_TIMEZONE) is not set in the
|
||||||
* default PRL when using Anonymize, */
|
* default PRL when using Anonymize, */
|
||||||
assert_se(sd_dhcp_client_set_request_option(client, 101) == 1);
|
|
||||||
assert_se(sd_dhcp_client_set_request_option(client, 101) == 0);
|
assert_se(sd_dhcp_client_set_request_option(client, 101) == 0);
|
||||||
|
assert_se(sd_dhcp_client_set_request_option(client, 101) == -EEXIST);
|
||||||
|
|
||||||
sd_dhcp_client_unref(client);
|
sd_dhcp_client_unref(client);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1357,6 +1357,10 @@ int dhcp4_configure(Link *link) {
|
|||||||
uint32_t option = PTR_TO_UINT32(request_options);
|
uint32_t option = PTR_TO_UINT32(request_options);
|
||||||
|
|
||||||
r = sd_dhcp_client_set_request_option(link->dhcp_client, option);
|
r = sd_dhcp_client_set_request_option(link->dhcp_client, option);
|
||||||
|
if (r == -EEXIST) {
|
||||||
|
log_link_debug(link, "DHCP4 CLIENT: Failed to set request flag for '%u' already exists, ignoring.", option);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for '%u': %m", option);
|
return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set request flag for '%u': %m", option);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1758,11 +1758,6 @@ static int link_joined(Link *link) {
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
link_set_state(link, LINK_STATE_CONFIGURING);
|
link_set_state(link, LINK_STATE_CONFIGURING);
|
||||||
|
|
||||||
r = link_acquire_conf(link);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
return link_set_static_configs(link);
|
return link_set_static_configs(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2043,6 +2038,12 @@ static int link_configure_continue(Link *link) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_link_warning_errno(link, r, "Cannot set IPv6 MTU for interface, ignoring: %m");
|
log_link_warning_errno(link, r, "Cannot set IPv6 MTU for interface, ignoring: %m");
|
||||||
|
|
||||||
|
if (link_has_carrier(link) || link->network->configure_without_carrier) {
|
||||||
|
r = link_acquire_conf(link);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
return link_enter_join_netdev(link);
|
return link_enter_join_netdev(link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user