mirror of
https://github.com/Dasharo/systemd.git
synced 2026-03-06 15:02:31 -08:00
Merge pull request #22631 from yuwata/network-redesign-request-queue
network: re-design request queue
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#endif
|
||||
|
||||
typedef void (*free_func_t)(void *p);
|
||||
typedef void* (*mfree_func_t)(void *p);
|
||||
|
||||
/* If for some reason more than 4M are allocated on the stack, let's abort immediately. It's better than
|
||||
* proceeding and smashing the stack limits. Note that by default RLIMIT_STACK is 8M on Linux. */
|
||||
|
||||
@@ -578,14 +578,14 @@ static int independent_netdev_create(NetDev *netdev) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stacked_netdev_create(NetDev *netdev, Link *link, link_netlink_message_handler_t callback) {
|
||||
static int stacked_netdev_create(NetDev *netdev, Link *link, Request *req) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
|
||||
int r;
|
||||
|
||||
assert(netdev);
|
||||
assert(netdev->manager);
|
||||
assert(link);
|
||||
assert(callback);
|
||||
assert(req);
|
||||
|
||||
r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
|
||||
if (r < 0)
|
||||
@@ -595,13 +595,10 @@ static int stacked_netdev_create(NetDev *netdev, Link *link, link_netlink_messag
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = netlink_call_async(netdev->manager->rtnl, NULL, m, callback,
|
||||
link_netlink_destroy_callback, link);
|
||||
r = request_call_netlink_async(netdev->manager->rtnl, m, req);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
link_ref(link);
|
||||
|
||||
netdev->state = NETDEV_STATE_CREATING;
|
||||
log_netdev_debug(netdev, "Creating");
|
||||
return 0;
|
||||
@@ -632,40 +629,29 @@ static int netdev_is_ready_to_create(NetDev *netdev, Link *link) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int request_process_stacked_netdev(Request *req) {
|
||||
NetDev *netdev;
|
||||
Link *link;
|
||||
static int stacked_netdev_process_request(Request *req, Link *link, void *userdata) {
|
||||
NetDev *netdev = ASSERT_PTR(userdata);
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->type == REQUEST_TYPE_NETDEV_STACKED);
|
||||
assert(req->netlink_handler);
|
||||
|
||||
netdev = ASSERT_PTR(req->netdev);
|
||||
link = ASSERT_PTR(req->link);
|
||||
assert(link);
|
||||
|
||||
r = netdev_is_ready_to_create(netdev, link);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
r = stacked_netdev_create(netdev, link, req->netlink_handler);
|
||||
r = stacked_netdev_create(netdev, link, req);
|
||||
if (r < 0)
|
||||
return log_netdev_warning_errno(netdev, r, "Failed to create netdev: %m");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int link_create_stacked_netdev_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
static int create_stacked_netdev_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(link);
|
||||
assert(link->create_stacked_netdev_messages > 0);
|
||||
|
||||
link->create_stacked_netdev_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 != -EEXIST) {
|
||||
@@ -696,10 +682,12 @@ int link_request_stacked_netdev(Link *link, NetDev *netdev) {
|
||||
return 0; /* Already created. */
|
||||
|
||||
link->stacked_netdevs_created = false;
|
||||
r = link_queue_request(link, REQUEST_TYPE_NETDEV_STACKED, netdev_ref(netdev), true,
|
||||
&link->create_stacked_netdev_messages,
|
||||
link_create_stacked_netdev_handler,
|
||||
NULL);
|
||||
r = link_queue_request_full(link, REQUEST_TYPE_NETDEV_STACKED,
|
||||
netdev_ref(netdev), (mfree_func_t) netdev_unref,
|
||||
trivial_hash_func, trivial_compare_func,
|
||||
stacked_netdev_process_request,
|
||||
&link->create_stacked_netdev_messages,
|
||||
create_stacked_netdev_handler, NULL);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to request stacked netdev '%s': %m",
|
||||
netdev->ifname);
|
||||
@@ -708,14 +696,11 @@ int link_request_stacked_netdev(Link *link, NetDev *netdev) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int request_process_independent_netdev(Request *req) {
|
||||
NetDev *netdev;
|
||||
static int independent_netdev_process_request(Request *req, Link *link, void *userdata) {
|
||||
NetDev *netdev = ASSERT_PTR(userdata);
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->type == REQUEST_TYPE_NETDEV_INDEPENDENT);
|
||||
|
||||
netdev = ASSERT_PTR(req->netdev);
|
||||
assert(!link);
|
||||
|
||||
r = netdev_is_ready_to_create(netdev, NULL);
|
||||
if (r <= 0)
|
||||
@@ -747,9 +732,9 @@ static int netdev_request_to_create(NetDev *netdev) {
|
||||
|
||||
} else {
|
||||
/* Otherwise, wait for the dependencies being resolved. */
|
||||
r = netdev_queue_request(netdev, NULL);
|
||||
r = netdev_queue_request(netdev, independent_netdev_process_request, NULL);
|
||||
if (r < 0)
|
||||
return log_netdev_warning_errno(netdev, r, "Failed to request to create: %m");
|
||||
return log_netdev_warning_errno(netdev, r, "Failed to request to create netdev: %m");
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -109,7 +109,6 @@ typedef enum NetDevCreateType {
|
||||
|
||||
typedef struct Manager Manager;
|
||||
typedef struct Condition Condition;
|
||||
typedef struct Request Request;
|
||||
|
||||
typedef struct NetDev {
|
||||
Manager *manager;
|
||||
@@ -209,8 +208,6 @@ int netdev_set_ifindex(NetDev *netdev, sd_netlink_message *newlink);
|
||||
int netdev_generate_hw_addr(NetDev *netdev, Link *link, const char *name,
|
||||
const struct hw_addr_data *hw_addr, struct hw_addr_data *ret);
|
||||
|
||||
int request_process_independent_netdev(Request *req);
|
||||
int request_process_stacked_netdev(Request *req);
|
||||
int link_request_stacked_netdev(Link *link, NetDev *netdev);
|
||||
|
||||
const char *netdev_kind_to_string(NetDevKind d) _const_;
|
||||
|
||||
@@ -65,19 +65,17 @@ static int address_label_new_static(Network *network, const char *filename, unsi
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int address_label_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
static int address_label_configure_handler(
|
||||
sd_netlink *rtnl,
|
||||
sd_netlink_message *m,
|
||||
Request *req,
|
||||
Link *link,
|
||||
void *userdata) {
|
||||
|
||||
int r;
|
||||
|
||||
assert(rtnl);
|
||||
assert(m);
|
||||
assert(link);
|
||||
assert(link->ifname);
|
||||
assert(link->static_address_label_messages > 0);
|
||||
|
||||
link->static_address_label_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) {
|
||||
@@ -95,7 +93,7 @@ static int address_label_configure_handler(sd_netlink *rtnl, sd_netlink_message
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int address_label_configure(AddressLabel *label, Link *link, link_netlink_message_handler_t callback) {
|
||||
static int address_label_configure(AddressLabel *label, Link *link, Request *req) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
|
||||
int r;
|
||||
|
||||
@@ -104,7 +102,7 @@ static int address_label_configure(AddressLabel *label, Link *link, link_netlink
|
||||
assert(link->ifindex > 0);
|
||||
assert(link->manager);
|
||||
assert(link->manager->rtnl);
|
||||
assert(callback);
|
||||
assert(req);
|
||||
|
||||
r = sd_rtnl_message_new_addrlabel(link->manager->rtnl, &m, RTM_NEWADDRLABEL,
|
||||
link->ifindex, AF_INET6);
|
||||
@@ -123,29 +121,20 @@ static int address_label_configure(AddressLabel *label, Link *link, link_netlink
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = netlink_call_async(link->manager->rtnl, NULL, m, callback,
|
||||
link_netlink_destroy_callback, link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
link_ref(link);
|
||||
return 0;
|
||||
return request_call_netlink_async(link->manager->rtnl, m, req);
|
||||
}
|
||||
|
||||
int request_process_address_label(Request *req) {
|
||||
Link *link;
|
||||
static int address_label_process_request(Request *req, Link *link, void *userdata) {
|
||||
AddressLabel *label = ASSERT_PTR(userdata);
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->label);
|
||||
assert(req->type == REQUEST_TYPE_ADDRESS_LABEL);
|
||||
|
||||
link = ASSERT_PTR(req->link);
|
||||
assert(link);
|
||||
|
||||
if (!link_is_ready_to_configure(link, false))
|
||||
return 0;
|
||||
|
||||
r = address_label_configure(req->label, link, req->netlink_handler);
|
||||
r = address_label_configure(label, link, req);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to configure address label: %m");
|
||||
|
||||
@@ -162,8 +151,11 @@ int link_request_static_address_labels(Link *link) {
|
||||
link->static_address_labels_configured = false;
|
||||
|
||||
HASHMAP_FOREACH(label, link->network->address_labels_by_section) {
|
||||
r = link_queue_request(link, REQUEST_TYPE_ADDRESS_LABEL, label, false,
|
||||
&link->static_address_label_messages, address_label_configure_handler, NULL);
|
||||
r = link_queue_request_full(link, REQUEST_TYPE_ADDRESS_LABEL,
|
||||
label, NULL, trivial_hash_func, trivial_compare_func,
|
||||
address_label_process_request,
|
||||
&link->static_address_label_messages,
|
||||
address_label_configure_handler, NULL);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to request address label: %m");
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
typedef struct Link Link;
|
||||
typedef struct Network Network;
|
||||
typedef struct Request Request;
|
||||
|
||||
typedef struct AddressLabel {
|
||||
Network *network;
|
||||
@@ -26,7 +25,6 @@ AddressLabel *address_label_free(AddressLabel *label);
|
||||
void network_drop_invalid_address_labels(Network *network);
|
||||
|
||||
int link_request_static_address_labels(Link *link);
|
||||
int request_process_address_label(Request *req);
|
||||
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_address_label);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_address_label_prefix);
|
||||
|
||||
@@ -316,7 +316,7 @@ DEFINE_PRIVATE_HASH_OPS(
|
||||
address_kernel_hash_func,
|
||||
address_kernel_compare_func);
|
||||
|
||||
void address_hash_func(const Address *a, struct siphash *state) {
|
||||
static void address_hash_func(const Address *a, struct siphash *state) {
|
||||
assert(a);
|
||||
|
||||
siphash24_compress(&a->family, sizeof(a->family), state);
|
||||
@@ -1023,9 +1023,6 @@ int address_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *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);
|
||||
@@ -1036,11 +1033,7 @@ int address_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int address_configure(
|
||||
const Address *address,
|
||||
Link *link,
|
||||
link_netlink_message_handler_t callback) {
|
||||
|
||||
static int address_configure(const Address *address, Link *link, Request *req) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
|
||||
int r;
|
||||
|
||||
@@ -1050,7 +1043,7 @@ static int address_configure(
|
||||
assert(link->ifindex > 0);
|
||||
assert(link->manager);
|
||||
assert(link->manager->rtnl);
|
||||
assert(callback);
|
||||
assert(req);
|
||||
|
||||
log_address_debug(address, "Configuring", link);
|
||||
|
||||
@@ -1091,12 +1084,7 @@ static int address_configure(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = netlink_call_async(link->manager->rtnl, NULL, m, callback, link_netlink_destroy_callback, link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
link_ref(link);
|
||||
return 0;
|
||||
return request_call_netlink_async(link->manager->rtnl, m, req);
|
||||
}
|
||||
|
||||
static bool address_is_ready_to_configure(Link *link, const Address *address) {
|
||||
@@ -1116,21 +1104,17 @@ static bool address_is_ready_to_configure(Link *link, const Address *address) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int request_process_address(Request *req) {
|
||||
Address *address;
|
||||
Link *link;
|
||||
static int address_process_request(Request *req, Link *link, Address *address) {
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->type == REQUEST_TYPE_ADDRESS);
|
||||
|
||||
address = ASSERT_PTR(req->address);
|
||||
link = ASSERT_PTR(req->link);
|
||||
assert(link);
|
||||
assert(address);
|
||||
|
||||
if (!address_is_ready_to_configure(link, address))
|
||||
return 0;
|
||||
|
||||
r = address_configure(address, link, req->netlink_handler);
|
||||
r = address_configure(address, link, req);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to configure address: %m");
|
||||
|
||||
@@ -1143,7 +1127,7 @@ int link_request_address(
|
||||
Address *address,
|
||||
bool consume_object,
|
||||
unsigned *message_counter,
|
||||
link_netlink_message_handler_t netlink_handler,
|
||||
address_netlink_handler_t netlink_handler,
|
||||
Request **ret) {
|
||||
|
||||
Address *acquired, *existing;
|
||||
@@ -1212,8 +1196,12 @@ int link_request_address(
|
||||
return r;
|
||||
|
||||
log_address_debug(existing, "Requesting", link);
|
||||
r = link_queue_request(link, REQUEST_TYPE_ADDRESS, existing, false,
|
||||
message_counter, netlink_handler, ret);
|
||||
r = link_queue_request_safe(link, REQUEST_TYPE_ADDRESS,
|
||||
existing, NULL,
|
||||
address_hash_func,
|
||||
address_compare_func,
|
||||
address_process_request,
|
||||
message_counter, netlink_handler, ret);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to request address: %m");
|
||||
if (r == 0)
|
||||
@@ -1224,13 +1212,10 @@ int link_request_address(
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int static_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
static int static_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Address *address) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->static_address_messages > 0);
|
||||
|
||||
link->static_address_messages--;
|
||||
|
||||
r = address_configure_handler_internal(rtnl, m, link, "Failed to set static address");
|
||||
if (r <= 0)
|
||||
@@ -1300,10 +1285,12 @@ void address_cancel_request(Address *address) {
|
||||
req = (Request) {
|
||||
.link = address->link,
|
||||
.type = REQUEST_TYPE_ADDRESS,
|
||||
.address = address,
|
||||
.userdata = address,
|
||||
.hash_func = (hash_func_t) address_hash_func,
|
||||
.compare_func = (compare_func_t) address_compare_func,
|
||||
};
|
||||
|
||||
request_drop(ordered_set_get(address->link->manager->request_queue, &req));
|
||||
request_detach(address->link->manager, &req);
|
||||
address_cancel_requesting(address);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,12 @@ typedef struct Manager Manager;
|
||||
typedef struct Network Network;
|
||||
typedef struct Request Request;
|
||||
typedef int (*address_ready_callback_t)(Address *address);
|
||||
typedef int (*address_netlink_handler_t)(
|
||||
sd_netlink *rtnl,
|
||||
sd_netlink_message *m,
|
||||
Request *req,
|
||||
Link *link,
|
||||
Address *address);
|
||||
|
||||
struct Address {
|
||||
Link *link;
|
||||
@@ -97,17 +103,15 @@ int link_request_address(
|
||||
Address *address,
|
||||
bool consume_object,
|
||||
unsigned *message_counter,
|
||||
link_netlink_message_handler_t netlink_handler,
|
||||
address_netlink_handler_t netlink_handler,
|
||||
Request **ret);
|
||||
int link_request_static_address(Link *link, Address *address, bool consume);
|
||||
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);
|
||||
|
||||
int network_drop_invalid_addresses(Network *network);
|
||||
|
||||
void address_hash_func(const Address *a, struct siphash *state);
|
||||
int address_compare_func(const Address *a1, const Address *a2);
|
||||
|
||||
DEFINE_NETWORK_CONFIG_STATE_FUNCTIONS(Address, address);
|
||||
|
||||
@@ -93,16 +93,11 @@ static int bridge_fdb_new_static(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bridge_fdb_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
static int bridge_fdb_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(link);
|
||||
assert(link->static_bridge_fdb_messages > 0);
|
||||
|
||||
link->static_bridge_fdb_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 != -EEXIST) {
|
||||
@@ -168,14 +163,14 @@ static int bridge_fdb_configure_message(const BridgeFDB *fdb, Link *link, sd_net
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bridge_fdb_configure(BridgeFDB *fdb, Link *link, link_netlink_message_handler_t callback) {
|
||||
static int bridge_fdb_configure(BridgeFDB *fdb, Link *link, Request *req) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
|
||||
int r;
|
||||
|
||||
assert(fdb);
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
assert(callback);
|
||||
assert(req);
|
||||
|
||||
r = sd_rtnl_message_new_neigh(link->manager->rtnl, &m, RTM_NEWNEIGH, link->ifindex, AF_BRIDGE);
|
||||
if (r < 0)
|
||||
@@ -185,13 +180,7 @@ static int bridge_fdb_configure(BridgeFDB *fdb, Link *link, link_netlink_message
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = netlink_call_async(link->manager->rtnl, NULL, m, callback,
|
||||
link_netlink_destroy_callback, link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
link_ref(link);
|
||||
return 0;
|
||||
return request_call_netlink_async(link->manager->rtnl, m, req);
|
||||
}
|
||||
|
||||
static bool bridge_fdb_is_ready_to_configure(BridgeFDB *fdb, Link *link) {
|
||||
@@ -219,20 +208,17 @@ static bool bridge_fdb_is_ready_to_configure(BridgeFDB *fdb, Link *link) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int request_process_bridge_fdb(Request *req) {
|
||||
BridgeFDB *fdb;
|
||||
Link *link;
|
||||
static int bridge_fdb_process_request(Request *req, Link *link, void *userdata) {
|
||||
BridgeFDB *fdb = ASSERT_PTR(userdata);
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->type == REQUEST_TYPE_BRIDGE_FDB);
|
||||
assert_se(link = req->link);
|
||||
assert_se(fdb = req->fdb);
|
||||
assert(link);
|
||||
|
||||
if (!bridge_fdb_is_ready_to_configure(fdb, link))
|
||||
return 0;
|
||||
|
||||
r = bridge_fdb_configure(fdb, link, req->netlink_handler);
|
||||
r = bridge_fdb_configure(fdb, link, req);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to configure bridge FDB: %m");
|
||||
|
||||
@@ -249,8 +235,14 @@ int link_request_static_bridge_fdb(Link *link) {
|
||||
link->static_bridge_fdb_configured = false;
|
||||
|
||||
HASHMAP_FOREACH(fdb, link->network->bridge_fdb_entries_by_section) {
|
||||
r = link_queue_request(link, REQUEST_TYPE_BRIDGE_FDB, fdb, false,
|
||||
&link->static_bridge_fdb_messages, bridge_fdb_configure_handler, NULL);
|
||||
r = link_queue_request_full(link, REQUEST_TYPE_BRIDGE_FDB,
|
||||
fdb, NULL,
|
||||
trivial_hash_func,
|
||||
trivial_compare_func,
|
||||
bridge_fdb_process_request,
|
||||
&link->static_bridge_fdb_messages,
|
||||
bridge_fdb_configure_handler,
|
||||
NULL);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to request static bridge FDB entry: %m");
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
typedef struct Link Link;
|
||||
typedef struct Network Network;
|
||||
typedef struct Request Request;
|
||||
|
||||
typedef enum NeighborCacheEntryFlags {
|
||||
NEIGHBOR_CACHE_ENTRY_FLAGS_USE = NTF_USE,
|
||||
@@ -47,8 +46,6 @@ void network_drop_invalid_bridge_fdb_entries(Network *network);
|
||||
|
||||
int link_request_static_bridge_fdb(Link *link);
|
||||
|
||||
int request_process_bridge_fdb(Request *req);
|
||||
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_fdb_hwaddr);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_fdb_vlan_id);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_fdb_destination);
|
||||
|
||||
@@ -81,16 +81,11 @@ static int bridge_mdb_new_static(
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bridge_mdb_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
static int bridge_mdb_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, void *userdata) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(link);
|
||||
assert(link->static_bridge_mdb_messages > 0);
|
||||
|
||||
link->static_bridge_mdb_messages--;
|
||||
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 1;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r == -EINVAL && streq_ptr(link->kind, "bridge") && link->master_ifindex <= 0) {
|
||||
@@ -114,7 +109,7 @@ static int bridge_mdb_configure_handler(sd_netlink *rtnl, sd_netlink_message *m,
|
||||
}
|
||||
|
||||
/* send a request to the kernel to add an MDB entry */
|
||||
static int bridge_mdb_configure(BridgeMDB *mdb, Link *link, link_netlink_message_handler_t callback) {
|
||||
static int bridge_mdb_configure(BridgeMDB *mdb, Link *link, Request *req) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
|
||||
struct br_mdb_entry entry;
|
||||
int r;
|
||||
@@ -122,7 +117,7 @@ static int bridge_mdb_configure(BridgeMDB *mdb, Link *link, link_netlink_message
|
||||
assert(mdb);
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
assert(callback);
|
||||
assert(req);
|
||||
|
||||
if (DEBUG_LOGGING) {
|
||||
_cleanup_free_ char *a = NULL;
|
||||
@@ -164,13 +159,7 @@ static int bridge_mdb_configure(BridgeMDB *mdb, Link *link, link_netlink_message
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = netlink_call_async(link->manager->rtnl, NULL, m, callback,
|
||||
link_netlink_destroy_callback, link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
link_ref(link);
|
||||
return 0;
|
||||
return request_call_netlink_async(link->manager->rtnl, m, req);
|
||||
}
|
||||
|
||||
static bool bridge_mdb_is_ready_to_configure(Link *link) {
|
||||
@@ -205,19 +194,17 @@ static bool bridge_mdb_is_ready_to_configure(Link *link) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int request_process_bridge_mdb(Request *req) {
|
||||
Link *link;
|
||||
static int bridge_mdb_process_request(Request *req, Link *link, void *userdata) {
|
||||
BridgeMDB *mdb = ASSERT_PTR(userdata);
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->mdb);
|
||||
assert(req->type == REQUEST_TYPE_BRIDGE_MDB);
|
||||
assert_se(link = req->link);
|
||||
assert(link);
|
||||
|
||||
if (!bridge_mdb_is_ready_to_configure(link))
|
||||
return 0;
|
||||
|
||||
r = bridge_mdb_configure(req->mdb, link, req->netlink_handler);
|
||||
r = bridge_mdb_configure(mdb, link, req);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to configure bridge MDB: %m");
|
||||
|
||||
@@ -240,8 +227,14 @@ int link_request_static_bridge_mdb(Link *link) {
|
||||
goto finish;
|
||||
|
||||
HASHMAP_FOREACH(mdb, link->network->bridge_mdb_entries_by_section) {
|
||||
r = link_queue_request(link, REQUEST_TYPE_BRIDGE_MDB, mdb, false,
|
||||
&link->static_bridge_mdb_messages, bridge_mdb_configure_handler, NULL);
|
||||
r = link_queue_request_full(link, REQUEST_TYPE_BRIDGE_MDB,
|
||||
mdb, NULL,
|
||||
trivial_hash_func,
|
||||
trivial_compare_func,
|
||||
bridge_mdb_process_request,
|
||||
&link->static_bridge_mdb_messages,
|
||||
bridge_mdb_configure_handler,
|
||||
NULL);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to request MDB entry to multicast group database: %m");
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
typedef struct Link Link;
|
||||
typedef struct Network Network;
|
||||
typedef struct Request Request;
|
||||
|
||||
typedef struct BridgeMDB {
|
||||
Network *network;
|
||||
@@ -25,7 +24,6 @@ BridgeMDB *bridge_mdb_free(BridgeMDB *mdb);
|
||||
void network_drop_invalid_bridge_mdb_entries(Network *network);
|
||||
|
||||
int link_request_static_bridge_mdb(Link *link);
|
||||
int request_process_bridge_mdb(Request *req);
|
||||
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_mdb_group_address);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_mdb_vlan_id);
|
||||
|
||||
@@ -288,13 +288,10 @@ static int dhcp_pd_check_ready(Link *link) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dhcp_pd_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
static int dhcp_pd_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Route *route) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->dhcp_pd_messages > 0);
|
||||
|
||||
link->dhcp_pd_messages--;
|
||||
|
||||
r = route_configure_handler_internal(rtnl, m, link, "Failed to add prefix route for DHCP delegated subnet prefix");
|
||||
if (r <= 0)
|
||||
@@ -344,13 +341,10 @@ static int dhcp_pd_request_route(Link *link, const struct in6_addr *prefix, usec
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dhcp_pd_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
static int dhcp_pd_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Address *address) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->dhcp_pd_messages > 0);
|
||||
|
||||
link->dhcp_pd_messages--;
|
||||
|
||||
r = address_configure_handler_internal(rtnl, m, link, "Could not set DHCP-PD address");
|
||||
if (r <= 0)
|
||||
@@ -658,13 +652,10 @@ void dhcp4_pd_prefix_lost(Link *uplink) {
|
||||
(void) link_remove(tunnel);
|
||||
}
|
||||
|
||||
static int dhcp4_unreachable_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
static int dhcp4_unreachable_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Route *route) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->dhcp4_messages > 0);
|
||||
|
||||
link->dhcp4_messages--;
|
||||
|
||||
r = route_configure_handler_internal(rtnl, m, link, "Failed to set unreachable route for DHCPv4 delegated prefix");
|
||||
if (r <= 0)
|
||||
@@ -677,13 +668,10 @@ static int dhcp4_unreachable_route_handler(sd_netlink *rtnl, sd_netlink_message
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int dhcp6_unreachable_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
static int dhcp6_unreachable_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Route *route) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->dhcp6_messages > 0);
|
||||
|
||||
link->dhcp6_messages--;
|
||||
|
||||
r = route_configure_handler_internal(rtnl, m, link, "Failed to set unreachable route for DHCPv6 delegated prefix");
|
||||
if (r <= 0)
|
||||
@@ -704,7 +692,7 @@ static int dhcp_request_unreachable_route(
|
||||
NetworkConfigSource source,
|
||||
const union in_addr_union *server_address,
|
||||
unsigned *counter,
|
||||
link_netlink_message_handler_t callback) {
|
||||
route_netlink_handler_t callback) {
|
||||
|
||||
_cleanup_(route_freep) Route *route = NULL;
|
||||
Route *existing;
|
||||
|
||||
@@ -571,13 +571,10 @@ static bool dhcp_server_is_ready_to_configure(Link *link) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int request_process_dhcp_server(Request *req) {
|
||||
Link *link;
|
||||
static int dhcp_server_process_request(Request *req, Link *link, void *userdata) {
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->type == REQUEST_TYPE_DHCP_SERVER);
|
||||
assert_se(link = req->link);
|
||||
assert(link);
|
||||
|
||||
if (!dhcp_server_is_ready_to_configure(link))
|
||||
return 0;
|
||||
@@ -601,7 +598,7 @@ int link_request_dhcp_server(Link *link) {
|
||||
return 0;
|
||||
|
||||
log_link_debug(link, "Requesting DHCP server.");
|
||||
r = link_queue_request(link, REQUEST_TYPE_DHCP_SERVER, NULL, false, NULL, NULL, NULL);
|
||||
r = link_queue_request(link, REQUEST_TYPE_DHCP_SERVER, dhcp_server_process_request, NULL);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to request configuration of DHCP server: %m");
|
||||
|
||||
|
||||
@@ -5,13 +5,11 @@
|
||||
|
||||
typedef struct Link Link;
|
||||
typedef struct Network Network;
|
||||
typedef struct Request Request;
|
||||
|
||||
void network_adjust_dhcp_server(Network *network);
|
||||
|
||||
int link_request_dhcp_server_address(Link *link);
|
||||
int link_request_dhcp_server(Link *link);
|
||||
int request_process_dhcp_server(Request *req);
|
||||
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_relay_agent_suboption);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_emit);
|
||||
|
||||
@@ -177,16 +177,11 @@ static int dhcp4_retry(Link *link) {
|
||||
return dhcp4_request_address_and_routes(link, false);
|
||||
}
|
||||
|
||||
static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
static int dhcp4_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Route *route) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(link);
|
||||
assert(link->dhcp4_messages > 0);
|
||||
|
||||
link->dhcp4_messages--;
|
||||
|
||||
if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
|
||||
return 1;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r == -ENETUNREACH && !link->dhcp4_route_retrying) {
|
||||
@@ -829,13 +824,10 @@ int dhcp4_lease_lost(Link *link) {
|
||||
return link_request_static_routes(link, true);
|
||||
}
|
||||
|
||||
static int dhcp4_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
static int dhcp4_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Address *address) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->dhcp4_messages > 0);
|
||||
|
||||
link->dhcp4_messages--;
|
||||
|
||||
r = address_configure_handler_internal(rtnl, m, link, "Could not set DHCPv4 address");
|
||||
if (r <= 0)
|
||||
@@ -1597,15 +1589,10 @@ static int dhcp4_configure_duid(Link *link) {
|
||||
return dhcp_configure_duid(link, link_get_dhcp4_duid(link));
|
||||
}
|
||||
|
||||
int request_process_dhcp4_client(Request *req) {
|
||||
Link *link;
|
||||
static int dhcp4_process_request(Request *req, Link *link, void *userdata) {
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->link);
|
||||
assert(req->type == REQUEST_TYPE_DHCP4_CLIENT);
|
||||
|
||||
link = req->link;
|
||||
assert(link);
|
||||
|
||||
if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
|
||||
return 0;
|
||||
@@ -1619,7 +1606,7 @@ int request_process_dhcp4_client(Request *req) {
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
r = dhcp4_configure(req->link);
|
||||
r = dhcp4_configure(link);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to configure DHCPv4 client: %m");
|
||||
|
||||
@@ -1629,7 +1616,6 @@ int request_process_dhcp4_client(Request *req) {
|
||||
|
||||
log_link_debug(link, "DHCPv4 client is configured%s.",
|
||||
r > 0 ? ", acquiring DHCPv4 lease" : "");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1644,7 +1630,7 @@ int link_request_dhcp4_client(Link *link) {
|
||||
if (link->dhcp_client)
|
||||
return 0;
|
||||
|
||||
r = link_queue_request(link, REQUEST_TYPE_DHCP4_CLIENT, NULL, false, NULL, NULL, NULL);
|
||||
r = link_queue_request(link, REQUEST_TYPE_DHCP4_CLIENT, dhcp4_process_request, NULL);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to request configuring of the DHCPv4 client: %m");
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
typedef struct Link Link;
|
||||
typedef struct Network Network;
|
||||
typedef struct Request Request;
|
||||
|
||||
typedef enum DHCPClientIdentifier {
|
||||
DHCP_CLIENT_ID_MAC,
|
||||
@@ -25,7 +24,6 @@ int dhcp4_start(Link *link);
|
||||
int dhcp4_lease_lost(Link *link);
|
||||
int dhcp4_check_ready(Link *link);
|
||||
|
||||
int request_process_dhcp4_client(Request *req);
|
||||
int link_request_dhcp4_client(Link *link);
|
||||
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_client_identifier);
|
||||
|
||||
@@ -136,13 +136,10 @@ int dhcp6_check_ready(Link *link) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dhcp6_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
static int dhcp6_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Address *address) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->dhcp6_messages > 0);
|
||||
|
||||
link->dhcp6_messages--;
|
||||
|
||||
r = address_configure_handler_internal(rtnl, m, link, "Could not set DHCPv6 address");
|
||||
if (r <= 0)
|
||||
@@ -715,15 +712,10 @@ int dhcp6_update_mac(Link *link) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int request_process_dhcp6_client(Request *req) {
|
||||
Link *link;
|
||||
static int dhcp6_process_request(Request *req, Link *link, void *userdata) {
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->link);
|
||||
assert(req->type == REQUEST_TYPE_DHCP6_CLIENT);
|
||||
|
||||
link = req->link;
|
||||
assert(link);
|
||||
|
||||
if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
|
||||
return 0;
|
||||
@@ -751,7 +743,6 @@ int request_process_dhcp6_client(Request *req) {
|
||||
|
||||
log_link_debug(link, "DHCPv6 client is configured%s.",
|
||||
r > 0 ? ", acquiring DHCPv6 lease" : "");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -766,7 +757,7 @@ int link_request_dhcp6_client(Link *link) {
|
||||
if (link->dhcp6_client)
|
||||
return 0;
|
||||
|
||||
r = link_queue_request(link, REQUEST_TYPE_DHCP6_CLIENT, NULL, false, NULL, NULL, NULL);
|
||||
r = link_queue_request(link, REQUEST_TYPE_DHCP6_CLIENT, dhcp6_process_request, NULL);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to request configuring of the DHCPv6 client: %m");
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ typedef enum DHCP6ClientStartMode {
|
||||
} DHCP6ClientStartMode;
|
||||
|
||||
typedef struct Link Link;
|
||||
typedef struct Request Request;
|
||||
|
||||
bool link_dhcp6_with_address_enabled(Link *link);
|
||||
int dhcp6_check_ready(Link *link);
|
||||
@@ -21,7 +20,6 @@ int dhcp6_update_mac(Link *link);
|
||||
int dhcp6_start(Link *link);
|
||||
int dhcp6_start_on_ra(Link *link, bool information_request);
|
||||
|
||||
int request_process_dhcp6_client(Request *req);
|
||||
int link_request_dhcp6_client(Link *link);
|
||||
|
||||
int link_serialize_dhcp6_client(Link *link, FILE *f);
|
||||
|
||||
@@ -70,7 +70,7 @@ static int ipv4ll_address_lost(Link *link) {
|
||||
return address_remove(existing);
|
||||
}
|
||||
|
||||
static int ipv4ll_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
static int ipv4ll_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, Address *address) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
|
||||
@@ -26,13 +26,17 @@ void network_adjust_ipv6_proxy_ndp(Network *network) {
|
||||
}
|
||||
}
|
||||
|
||||
static int ipv6_proxy_ndp_address_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
static int ipv6_proxy_ndp_address_configure_handler(
|
||||
sd_netlink *rtnl,
|
||||
sd_netlink_message *m,
|
||||
Request *req,
|
||||
Link *link,
|
||||
struct in6_addr *address) {
|
||||
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(link);
|
||||
assert(link->static_ipv6_proxy_ndp_messages > 0);
|
||||
|
||||
link->static_ipv6_proxy_ndp_messages--;
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0)
|
||||
@@ -48,11 +52,7 @@ static int ipv6_proxy_ndp_address_configure_handler(sd_netlink *rtnl, sd_netlink
|
||||
}
|
||||
|
||||
/* send a request to the kernel to add an IPv6 Proxy entry to the neighbour table */
|
||||
static int ipv6_proxy_ndp_address_configure(
|
||||
const struct in6_addr *address,
|
||||
Link *link,
|
||||
link_netlink_message_handler_t callback) {
|
||||
|
||||
static int ipv6_proxy_ndp_address_configure(const struct in6_addr *address, Link *link, Request *req) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
|
||||
int r;
|
||||
|
||||
@@ -60,7 +60,7 @@ static int ipv6_proxy_ndp_address_configure(
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
assert(link->manager->rtnl);
|
||||
assert(callback);
|
||||
assert(req);
|
||||
|
||||
/* create new netlink message */
|
||||
r = sd_rtnl_message_new_neigh(link->manager->rtnl, &m, RTM_NEWNEIGH, link->ifindex, AF_INET6);
|
||||
@@ -75,28 +75,20 @@ static int ipv6_proxy_ndp_address_configure(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = netlink_call_async(link->manager->rtnl, NULL, m, callback,
|
||||
link_netlink_destroy_callback, link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
link_ref(link);
|
||||
return 0;
|
||||
return request_call_netlink_async(link->manager->rtnl, m, req);
|
||||
}
|
||||
|
||||
int request_process_ipv6_proxy_ndp_address(Request *req) {
|
||||
Link *link;
|
||||
static int ipv6_proxy_ndp_address_process_request(Request *req, Link *link, struct in6_addr *address) {
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->ipv6_proxy_ndp);
|
||||
assert(req->type == REQUEST_TYPE_IPV6_PROXY_NDP);
|
||||
assert_se(link = req->link);
|
||||
assert(link);
|
||||
assert(address);
|
||||
|
||||
if (!link_is_ready_to_configure(link, false))
|
||||
return 0;
|
||||
|
||||
r = ipv6_proxy_ndp_address_configure(req->ipv6_proxy_ndp, link, req->netlink_handler);
|
||||
r = ipv6_proxy_ndp_address_configure(address, link, req);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to configure IPv6 proxy NDP address: %m");
|
||||
|
||||
@@ -113,9 +105,14 @@ int link_request_static_ipv6_proxy_ndp_addresses(Link *link) {
|
||||
link->static_ipv6_proxy_ndp_configured = false;
|
||||
|
||||
SET_FOREACH(address, link->network->ipv6_proxy_ndp_addresses) {
|
||||
r = link_queue_request(link, REQUEST_TYPE_IPV6_PROXY_NDP, address, false,
|
||||
&link->static_ipv6_proxy_ndp_messages,
|
||||
ipv6_proxy_ndp_address_configure_handler, NULL);
|
||||
r = link_queue_request_safe(link, REQUEST_TYPE_IPV6_PROXY_NDP,
|
||||
address, NULL,
|
||||
in6_addr_hash_func,
|
||||
in6_addr_compare_func,
|
||||
ipv6_proxy_ndp_address_process_request,
|
||||
&link->static_ipv6_proxy_ndp_messages,
|
||||
ipv6_proxy_ndp_address_configure_handler,
|
||||
NULL);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to request IPv6 proxy NDP address: %m");
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user