mirror of
https://github.com/systemd/systemd.git
synced 2025-01-12 13:18:14 +03:00
network: use request queue to configure neighbors
This commit is contained in:
parent
0e5ef6beb6
commit
40ca350ea1
@ -796,9 +796,6 @@ void link_check_ready(Link *link) {
|
||||
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;
|
||||
@ -807,6 +804,9 @@ 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__);
|
||||
|
||||
@ -881,7 +881,6 @@ static int link_set_static_configs(Link *link) {
|
||||
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;
|
||||
|
||||
@ -897,11 +896,11 @@ static int link_set_static_configs(Link *link) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = link_set_neighbors(link);
|
||||
r = link_set_addresses(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = link_set_addresses(link);
|
||||
r = link_request_static_neighbors(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -81,10 +81,11 @@ typedef struct Link {
|
||||
unsigned address_messages;
|
||||
unsigned address_remove_messages;
|
||||
unsigned address_label_messages;
|
||||
unsigned neighbor_messages;
|
||||
unsigned static_neighbor_messages;
|
||||
unsigned route_messages;
|
||||
unsigned nexthop_messages;
|
||||
unsigned static_routing_policy_rule_messages;
|
||||
unsigned neighbor_remove_messages;
|
||||
unsigned tc_messages;
|
||||
unsigned sr_iov_messages;
|
||||
unsigned enslaving;
|
||||
@ -121,7 +122,7 @@ typedef struct Link {
|
||||
bool request_static_addresses:1;
|
||||
bool addresses_configured:1;
|
||||
bool addresses_ready:1;
|
||||
bool neighbors_configured:1;
|
||||
bool static_neighbors_configured:1;
|
||||
bool static_routes_configured:1;
|
||||
bool static_nexthops_configured:1;
|
||||
bool static_routing_policy_rules_configured:1;
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "networkd-manager.h"
|
||||
#include "networkd-neighbor.h"
|
||||
#include "networkd-network.h"
|
||||
#include "networkd-queue.h"
|
||||
#include "set.h"
|
||||
|
||||
Neighbor *neighbor_free(Neighbor *neighbor) {
|
||||
@ -270,18 +271,17 @@ 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,
|
||||
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, ret);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not add neighbor: %m");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -290,28 +290,46 @@ static int static_neighbor_configure_handler(sd_netlink *rtnl, sd_netlink_messag
|
||||
|
||||
assert(m);
|
||||
assert(link);
|
||||
assert(link->neighbor_messages > 0);
|
||||
assert(link->static_neighbor_messages > 0);
|
||||
|
||||
link->neighbor_messages--;
|
||||
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)
|
||||
/* 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 (r < 0 && r != -EEXIST) {
|
||||
log_link_message_warning_errno(link, m, r, "Could not set neighbor");
|
||||
link_enter_failed(link);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (link->neighbor_messages == 0) {
|
||||
if (link->static_neighbor_messages == 0) {
|
||||
log_link_debug(link, "Neighbors set");
|
||||
link->neighbors_configured = true;
|
||||
link->static_neighbors_configured = true;
|
||||
link_check_ready(link);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int link_set_neighbors(Link *link) {
|
||||
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) {
|
||||
Neighbor *neighbor;
|
||||
int r;
|
||||
|
||||
@ -319,24 +337,20 @@ int link_set_neighbors(Link *link) {
|
||||
assert(link->network);
|
||||
assert(link->state != _LINK_STATE_INVALID);
|
||||
|
||||
if (link->neighbor_messages != 0) {
|
||||
log_link_debug(link, "Neighbors are configuring.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
link->neighbors_configured = false;
|
||||
link->static_neighbors_configured = false;
|
||||
|
||||
HASHMAP_FOREACH(neighbor, link->network->neighbors_by_section) {
|
||||
r = neighbor_configure(neighbor, link, static_neighbor_configure_handler, NULL);
|
||||
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 set neighbor: %m");
|
||||
return log_link_warning_errno(link, r, "Could not request neighbor: %m");
|
||||
}
|
||||
|
||||
if (link->neighbor_messages == 0) {
|
||||
link->neighbors_configured = true;
|
||||
if (link->static_neighbor_messages == 0) {
|
||||
link->static_neighbors_configured = true;
|
||||
link_check_ready(link);
|
||||
} else {
|
||||
log_link_debug(link, "Setting neighbors");
|
||||
log_link_debug(link, "Requesting neighbors");
|
||||
link_set_state(link, LINK_STATE_CONFIGURING);
|
||||
}
|
||||
|
||||
@ -348,6 +362,9 @@ 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;
|
||||
@ -387,6 +404,7 @@ 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;
|
||||
}
|
||||
@ -442,6 +460,34 @@ 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,9 +10,10 @@
|
||||
#include "in-addr-util.h"
|
||||
#include "networkd-util.h"
|
||||
|
||||
typedef Manager Manager;
|
||||
typedef Network Network;
|
||||
typedef Link Link;
|
||||
typedef struct Link Link;
|
||||
typedef struct Manager Manager;
|
||||
typedef struct Network Network;
|
||||
typedef struct Request Request;
|
||||
|
||||
union lladdr_union {
|
||||
struct ether_addr mac;
|
||||
@ -34,10 +35,12 @@ 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);
|
||||
|
@ -10,6 +10,9 @@
|
||||
|
||||
static void request_free_object(RequestType type, void *object) {
|
||||
switch(type) {
|
||||
case REQUEST_TYPE_NEIGHBOR:
|
||||
neighbor_free(object);
|
||||
break;
|
||||
case REQUEST_TYPE_ROUTING_POLICY_RULE:
|
||||
routing_policy_rule_free(object);
|
||||
break;
|
||||
@ -104,6 +107,9 @@ int manager_process_requests(sd_event_source *s, void *userdata) {
|
||||
|
||||
ORDERED_SET_FOREACH(req, manager->request_queue) {
|
||||
switch(req->type) {
|
||||
case REQUEST_TYPE_NEIGHBOR:
|
||||
r = request_process_neighbor(req);
|
||||
break;
|
||||
case REQUEST_TYPE_ROUTING_POLICY_RULE:
|
||||
r = request_process_routing_policy_rule(req);
|
||||
break;
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "networkd-link.h"
|
||||
|
||||
typedef struct Neighbor Neighbor;
|
||||
typedef struct RoutingPolicyRule RoutingPolicyRule;
|
||||
|
||||
typedef struct Request Request;
|
||||
@ -13,6 +14,7 @@ typedef int (*request_after_configure_handler_t)(Request*, void*);
|
||||
typedef void (*request_on_free_handler_t)(Request*);
|
||||
|
||||
typedef enum RequestType {
|
||||
REQUEST_TYPE_NEIGHBOR,
|
||||
REQUEST_TYPE_ROUTING_POLICY_RULE,
|
||||
_REQUEST_TYPE_MAX,
|
||||
_REQUEST_TYPE_INVALID = -EINVAL,
|
||||
@ -23,6 +25,7 @@ typedef struct Request {
|
||||
RequestType type;
|
||||
bool consume_object;
|
||||
union {
|
||||
Neighbor *neighbor;
|
||||
RoutingPolicyRule *rule;
|
||||
void *object;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user