mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +03:00
network/nexthop: preparation for dynamically configuring nexthops
Preparation for later commits.
This commit is contained in:
parent
bdc6edbdab
commit
b5b42b516e
@ -105,7 +105,6 @@ static NextHop* nexthop_free(NextHop *nexthop) {
|
||||
}
|
||||
|
||||
DEFINE_TRIVIAL_REF_UNREF_FUNC(NextHop, nexthop, nexthop_free);
|
||||
DEFINE_SECTION_CLEANUP_FUNCTIONS(NextHop, nexthop_unref);
|
||||
|
||||
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
||||
nexthop_hash_ops,
|
||||
@ -123,7 +122,7 @@ DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
|
||||
NextHop,
|
||||
nexthop_detach);
|
||||
|
||||
static int nexthop_new(NextHop **ret) {
|
||||
int nexthop_new(NextHop **ret) {
|
||||
_cleanup_(nexthop_unrefp) NextHop *nexthop = NULL;
|
||||
|
||||
nexthop = new(NextHop, 1);
|
||||
@ -339,7 +338,7 @@ static int nexthop_get(Link *link, const NextHop *in, NextHop **ret) {
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static int nexthop_get_request_by_id(Manager *manager, uint32_t id, Request **ret) {
|
||||
int nexthop_get_request_by_id(Manager *manager, uint32_t id, Request **ret) {
|
||||
Request *req;
|
||||
|
||||
assert(manager);
|
||||
@ -459,7 +458,7 @@ static int nexthop_acquire_id(Manager *manager, NextHop *nexthop) {
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
static void log_nexthop_debug(const NextHop *nexthop, const char *str, Manager *manager) {
|
||||
void log_nexthop_debug(const NextHop *nexthop, const char *str, Manager *manager) {
|
||||
_cleanup_free_ char *state = NULL, *group = NULL, *flags = NULL;
|
||||
struct nexthop_grp *nhg;
|
||||
Link *link = NULL;
|
||||
@ -569,6 +568,33 @@ int nexthop_remove(NextHop *nexthop, Manager *manager) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nexthop_remove_and_cancel(NextHop *nexthop, Manager *manager) {
|
||||
_cleanup_(request_unrefp) Request *req = NULL;
|
||||
bool waiting = false;
|
||||
|
||||
assert(nexthop);
|
||||
assert(nexthop->id > 0);
|
||||
assert(manager);
|
||||
|
||||
/* If the nexthop is remembered by the manager, then use the remembered object. */
|
||||
(void) nexthop_get_by_id(manager, nexthop->id, &nexthop);
|
||||
|
||||
/* Cancel the request for the nexthop. If the request is already called but we have not received the
|
||||
* notification about the request, then explicitly remove the nexthop. */
|
||||
if (nexthop_get_request_by_id(manager, nexthop->id, &req) >= 0) {
|
||||
request_ref(req); /* avoid the request freed by request_detach() */
|
||||
waiting = req->waiting_reply;
|
||||
request_detach(req);
|
||||
nexthop_cancel_requesting(nexthop);
|
||||
}
|
||||
|
||||
/* If we know that the nexthop will come or already exists, remove it. */
|
||||
if (waiting || (nexthop->manager && nexthop_exists(nexthop)))
|
||||
return nexthop_remove(nexthop, manager);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nexthop_configure(NextHop *nexthop, Link *link, Request *req) {
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
|
||||
int r;
|
||||
@ -633,19 +659,32 @@ static int nexthop_configure(NextHop *nexthop, Link *link, Request *req) {
|
||||
return request_call_netlink_async(link->manager->rtnl, m, req);
|
||||
}
|
||||
|
||||
static int static_nexthop_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, NextHop *nexthop) {
|
||||
int nexthop_configure_handler_internal(sd_netlink_message *m, Link *link, const char *error_msg) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(link);
|
||||
assert(error_msg);
|
||||
|
||||
r = sd_netlink_message_get_errno(m);
|
||||
if (r < 0 && r != -EEXIST) {
|
||||
log_link_message_warning_errno(link, m, r, "Could not set nexthop");
|
||||
log_link_message_warning_errno(link, m, r, error_msg);
|
||||
link_enter_failed(link);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int static_nexthop_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, NextHop *nexthop) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
|
||||
r = nexthop_configure_handler_internal(m, link, "Failed to set static nexthop");
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
if (link->static_nexthop_messages == 0) {
|
||||
log_link_debug(link, "Nexthops set");
|
||||
link->static_nexthops_configured = true;
|
||||
@ -740,7 +779,12 @@ static int nexthop_process_request(Request *req, Link *link, NextHop *nexthop) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int link_request_nexthop(Link *link, const NextHop *nexthop) {
|
||||
int link_request_nexthop(
|
||||
Link *link,
|
||||
const NextHop *nexthop,
|
||||
unsigned *message_counter,
|
||||
nexthop_netlink_handler_t netlink_handler) {
|
||||
|
||||
_cleanup_(nexthop_unrefp) NextHop *tmp = NULL;
|
||||
NextHop *existing = NULL;
|
||||
int r;
|
||||
@ -780,8 +824,8 @@ static int link_request_nexthop(Link *link, const NextHop *nexthop) {
|
||||
nexthop_hash_func,
|
||||
nexthop_compare_func,
|
||||
nexthop_process_request,
|
||||
&link->static_nexthop_messages,
|
||||
static_nexthop_handler,
|
||||
message_counter,
|
||||
netlink_handler,
|
||||
NULL);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
@ -807,7 +851,7 @@ int link_request_static_nexthops(Link *link, bool only_ipv4) {
|
||||
if (only_ipv4 && nh->family != AF_INET)
|
||||
continue;
|
||||
|
||||
r = link_request_nexthop(link, nh);
|
||||
r = link_request_nexthop(link, nh, &link->static_nexthop_messages, static_nexthop_handler);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Could not request nexthop: %m");
|
||||
}
|
||||
@ -866,16 +910,17 @@ int link_drop_nexthops(Link *link, bool only_static) {
|
||||
if (!nexthop_exists(nexthop))
|
||||
continue;
|
||||
|
||||
if (only_static) {
|
||||
if (nexthop->source != NETWORK_CONFIG_SOURCE_STATIC)
|
||||
if (nexthop->source == NETWORK_CONFIG_SOURCE_FOREIGN) {
|
||||
if (only_static)
|
||||
continue;
|
||||
} else {
|
||||
|
||||
/* Do not mark foreign nexthop when KeepConfiguration= is enabled. */
|
||||
if (nexthop->source == NETWORK_CONFIG_SOURCE_FOREIGN &&
|
||||
link->network &&
|
||||
if (link->network &&
|
||||
FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_STATIC))
|
||||
continue;
|
||||
}
|
||||
|
||||
} else if (nexthop->source != NETWORK_CONFIG_SOURCE_STATIC)
|
||||
continue; /* Ignore dynamically configurad nexthops. */
|
||||
|
||||
/* Ignore nexthops bound to other links. */
|
||||
if (nexthop->ifindex > 0 && nexthop->ifindex != link->ifindex)
|
||||
@ -1106,6 +1151,7 @@ int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message,
|
||||
NextHop *n = ASSERT_PTR(req->userdata);
|
||||
|
||||
nexthop->source = n->source;
|
||||
nexthop->provider = n->provider;
|
||||
}
|
||||
|
||||
r = sd_rtnl_message_get_family(message, &nexthop->family);
|
||||
|
@ -16,13 +16,21 @@
|
||||
typedef struct Link Link;
|
||||
typedef struct Manager Manager;
|
||||
typedef struct Network Network;
|
||||
typedef struct NextHop NextHop;
|
||||
typedef int (*nexthop_netlink_handler_t)(
|
||||
sd_netlink *rtnl,
|
||||
sd_netlink_message *m,
|
||||
Request *req,
|
||||
Link *link,
|
||||
NextHop *address);
|
||||
|
||||
typedef struct NextHop {
|
||||
struct NextHop {
|
||||
Network *network;
|
||||
Manager *manager;
|
||||
ConfigSection *section;
|
||||
NetworkConfigSource source;
|
||||
NetworkConfigState state;
|
||||
union in_addr_union provider; /* DHCP server or router address */
|
||||
|
||||
unsigned n_ref;
|
||||
|
||||
@ -44,12 +52,17 @@ typedef struct NextHop {
|
||||
/* For managing routes and nexthops that depend on this nexthop. */
|
||||
Set *nexthops;
|
||||
Set *routes;
|
||||
} NextHop;
|
||||
};
|
||||
|
||||
void log_nexthop_debug(const NextHop *nexthop, const char *str, Manager *manager);
|
||||
|
||||
int nexthop_new(NextHop **ret);
|
||||
NextHop* nexthop_ref(NextHop *nexthop);
|
||||
NextHop* nexthop_unref(NextHop *nexthop);
|
||||
DEFINE_SECTION_CLEANUP_FUNCTIONS(NextHop, nexthop_unref);
|
||||
|
||||
int nexthop_remove(NextHop *nexthop, Manager *manager);
|
||||
int nexthop_remove_and_cancel(NextHop *nexthop, Manager *manager);
|
||||
|
||||
int network_drop_invalid_nexthops(Network *network);
|
||||
|
||||
@ -62,9 +75,16 @@ static inline int link_drop_static_nexthops(Link *link) {
|
||||
}
|
||||
void link_forget_nexthops(Link *link);
|
||||
|
||||
int nexthop_configure_handler_internal(sd_netlink_message *m, Link *link, const char *error_msg);
|
||||
int link_request_nexthop(
|
||||
Link *link,
|
||||
const NextHop *nexthop,
|
||||
unsigned *message_counter,
|
||||
nexthop_netlink_handler_t netlink_handler);
|
||||
int link_request_static_nexthops(Link *link, bool only_ipv4);
|
||||
|
||||
int nexthop_get_by_id(Manager *manager, uint32_t id, NextHop **ret);
|
||||
int nexthop_get_request_by_id(Manager *manager, uint32_t id, Request **ret);
|
||||
int nexthop_is_ready(Manager *manager, uint32_t id, NextHop **ret);
|
||||
int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message, Manager *m);
|
||||
int manager_build_nexthop_ids(Manager *manager);
|
||||
|
Loading…
Reference in New Issue
Block a user