network: move functions
No functional change. Preparation for later commits.
This commit is contained in:
@@ -132,6 +132,26 @@ static int address_label_configure(AddressLabel *label, Link *link, link_netlink
|
||||
return 0;
|
||||
}
|
||||
|
||||
int request_process_address_label(Request *req) {
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->label);
|
||||
assert(req->type == REQUEST_TYPE_ADDRESS_LABEL);
|
||||
|
||||
link = ASSERT_PTR(req->link);
|
||||
|
||||
if (!link_is_ready_to_configure(link, false))
|
||||
return 0;
|
||||
|
||||
r = address_label_configure(req->label, link, req->netlink_handler);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to configure address label: %m");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int link_request_static_address_labels(Link *link) {
|
||||
AddressLabel *label;
|
||||
int r;
|
||||
@@ -159,26 +179,6 @@ int link_request_static_address_labels(Link *link) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int request_process_address_label(Request *req) {
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->label);
|
||||
assert(req->type == REQUEST_TYPE_ADDRESS_LABEL);
|
||||
|
||||
link = ASSERT_PTR(req->link);
|
||||
|
||||
if (!link_is_ready_to_configure(link, false))
|
||||
return 0;
|
||||
|
||||
r = address_label_configure(req->label, link, req->netlink_handler);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to configure address label: %m");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int address_label_section_verify(AddressLabel *label) {
|
||||
assert(label);
|
||||
assert(label->section);
|
||||
|
||||
@@ -1123,6 +1123,45 @@ static int static_address_handler(sd_netlink *rtnl, sd_netlink_message *m, Link
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool address_is_ready_to_configure(Link *link, const Address *address) {
|
||||
assert(link);
|
||||
assert(address);
|
||||
|
||||
if (!link_is_ready_to_configure(link, false))
|
||||
return false;
|
||||
|
||||
if (FLAGS_SET(address->state, NETWORK_CONFIG_STATE_PROBING))
|
||||
return false;
|
||||
|
||||
/* Refuse adding more than the limit */
|
||||
if (set_size(link->addresses) >= ADDRESSES_PER_LINK_MAX)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int request_process_address(Request *req) {
|
||||
Address *address;
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->type == REQUEST_TYPE_ADDRESS);
|
||||
|
||||
address = ASSERT_PTR(req->address);
|
||||
link = ASSERT_PTR(req->link);
|
||||
|
||||
if (!address_is_ready_to_configure(link, address))
|
||||
return 0;
|
||||
|
||||
r = address_configure(address, link, req->netlink_handler);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to configure address: %m");
|
||||
|
||||
address_enter_configuring(address);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int link_request_address(
|
||||
Link *link,
|
||||
Address *address,
|
||||
@@ -1252,45 +1291,6 @@ int link_request_static_addresses(Link *link) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool address_is_ready_to_configure(Link *link, const Address *address) {
|
||||
assert(link);
|
||||
assert(address);
|
||||
|
||||
if (!link_is_ready_to_configure(link, false))
|
||||
return false;
|
||||
|
||||
if (FLAGS_SET(address->state, NETWORK_CONFIG_STATE_PROBING))
|
||||
return false;
|
||||
|
||||
/* Refuse adding more than the limit */
|
||||
if (set_size(link->addresses) >= ADDRESSES_PER_LINK_MAX)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int request_process_address(Request *req) {
|
||||
Address *address;
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->type == REQUEST_TYPE_ADDRESS);
|
||||
|
||||
address = ASSERT_PTR(req->address);
|
||||
link = ASSERT_PTR(req->link);
|
||||
|
||||
if (!address_is_ready_to_configure(link, address))
|
||||
return 0;
|
||||
|
||||
r = address_configure(address, link, req->netlink_handler);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to configure address: %m");
|
||||
|
||||
address_enter_configuring(address);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int manager_rtnl_process_address(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) {
|
||||
_cleanup_(address_freep) Address *tmp = NULL;
|
||||
struct ifa_cacheinfo cinfo;
|
||||
|
||||
@@ -194,33 +194,6 @@ static int bridge_fdb_configure(BridgeFDB *fdb, Link *link, link_netlink_message
|
||||
return 0;
|
||||
}
|
||||
|
||||
int link_request_static_bridge_fdb(Link *link) {
|
||||
BridgeFDB *fdb;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->network);
|
||||
|
||||
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);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to request static bridge FDB entry: %m");
|
||||
}
|
||||
|
||||
if (link->static_bridge_fdb_messages == 0) {
|
||||
link->static_bridge_fdb_configured = true;
|
||||
link_check_ready(link);
|
||||
} else {
|
||||
log_link_debug(link, "Setting bridge FDB entries");
|
||||
link_set_state(link, LINK_STATE_CONFIGURING);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool bridge_fdb_is_ready_to_configure(BridgeFDB *fdb, Link *link) {
|
||||
Link *out = NULL;
|
||||
|
||||
@@ -266,6 +239,33 @@ int request_process_bridge_fdb(Request *req) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int link_request_static_bridge_fdb(Link *link) {
|
||||
BridgeFDB *fdb;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->network);
|
||||
|
||||
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);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to request static bridge FDB entry: %m");
|
||||
}
|
||||
|
||||
if (link->static_bridge_fdb_messages == 0) {
|
||||
link->static_bridge_fdb_configured = true;
|
||||
link_check_ready(link);
|
||||
} else {
|
||||
log_link_debug(link, "Setting bridge FDB entries");
|
||||
link_set_state(link, LINK_STATE_CONFIGURING);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void network_drop_invalid_bridge_fdb_entries(Network *network) {
|
||||
BridgeFDB *fdb;
|
||||
|
||||
|
||||
@@ -174,40 +174,6 @@ static int bridge_mdb_configure(BridgeMDB *mdb, Link *link, link_netlink_message
|
||||
return 0;
|
||||
}
|
||||
|
||||
int link_request_static_bridge_mdb(Link *link) {
|
||||
BridgeMDB *mdb;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
|
||||
link->static_bridge_mdb_configured = false;
|
||||
|
||||
if (!link->network)
|
||||
return 0;
|
||||
|
||||
if (hashmap_isempty(link->network->bridge_mdb_entries_by_section))
|
||||
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);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to request MDB entry to multicast group database: %m");
|
||||
}
|
||||
|
||||
finish:
|
||||
if (link->static_bridge_mdb_messages == 0) {
|
||||
link->static_bridge_mdb_configured = true;
|
||||
link_check_ready(link);
|
||||
} else {
|
||||
log_link_debug(link, "Setting bridge MDB entries.");
|
||||
link_set_state(link, LINK_STATE_CONFIGURING);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool bridge_mdb_is_ready_to_configure(Link *link) {
|
||||
Link *master;
|
||||
|
||||
@@ -257,6 +223,40 @@ int request_process_bridge_mdb(Request *req) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int link_request_static_bridge_mdb(Link *link) {
|
||||
BridgeMDB *mdb;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
|
||||
link->static_bridge_mdb_configured = false;
|
||||
|
||||
if (!link->network)
|
||||
return 0;
|
||||
|
||||
if (hashmap_isempty(link->network->bridge_mdb_entries_by_section))
|
||||
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);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Failed to request MDB entry to multicast group database: %m");
|
||||
}
|
||||
|
||||
finish:
|
||||
if (link->static_bridge_mdb_messages == 0) {
|
||||
link->static_bridge_mdb_configured = true;
|
||||
link_check_ready(link);
|
||||
} else {
|
||||
log_link_debug(link, "Setting bridge MDB entries.");
|
||||
link_set_state(link, LINK_STATE_CONFIGURING);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bridge_mdb_verify(BridgeMDB *mdb) {
|
||||
if (section_is_invalid(mdb->section))
|
||||
return -EINVAL;
|
||||
|
||||
@@ -532,19 +532,6 @@ static int dhcp4_server_configure(Link *link) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int link_request_dhcp_server(Link *link) {
|
||||
assert(link);
|
||||
|
||||
if (!link_dhcp4_server_enabled(link))
|
||||
return 0;
|
||||
|
||||
if (link->dhcp_server)
|
||||
return 0;
|
||||
|
||||
log_link_debug(link, "Requesting DHCP server.");
|
||||
return link_queue_request(link, REQUEST_TYPE_DHCP_SERVER, NULL, false, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static bool dhcp_server_is_ready_to_configure(Link *link) {
|
||||
Link *uplink = NULL;
|
||||
Address *a;
|
||||
@@ -592,6 +579,19 @@ int request_process_dhcp_server(Request *req) {
|
||||
return dhcp4_server_configure(req->link);
|
||||
}
|
||||
|
||||
int link_request_dhcp_server(Link *link) {
|
||||
assert(link);
|
||||
|
||||
if (!link_dhcp4_server_enabled(link))
|
||||
return 0;
|
||||
|
||||
if (link->dhcp_server)
|
||||
return 0;
|
||||
|
||||
log_link_debug(link, "Requesting DHCP server.");
|
||||
return link_queue_request(link, REQUEST_TYPE_DHCP_SERVER, NULL, false, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
int config_parse_dhcp_server_relay_agent_suboption(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
|
||||
@@ -84,6 +84,25 @@ static int ipv6_proxy_ndp_address_configure(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int request_process_ipv6_proxy_ndp_address(Request *req) {
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->ipv6_proxy_ndp);
|
||||
assert(req->type == REQUEST_TYPE_IPV6_PROXY_NDP);
|
||||
assert_se(link = req->link);
|
||||
|
||||
if (!link_is_ready_to_configure(link, false))
|
||||
return 0;
|
||||
|
||||
r = ipv6_proxy_ndp_address_configure(req->ipv6_proxy_ndp, link, req->netlink_handler);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to configure IPv6 proxy NDP address: %m");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int link_request_static_ipv6_proxy_ndp_addresses(Link *link) {
|
||||
struct in6_addr *address;
|
||||
int r;
|
||||
@@ -112,25 +131,6 @@ int link_request_static_ipv6_proxy_ndp_addresses(Link *link) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int request_process_ipv6_proxy_ndp_address(Request *req) {
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->ipv6_proxy_ndp);
|
||||
assert(req->type == REQUEST_TYPE_IPV6_PROXY_NDP);
|
||||
assert_se(link = req->link);
|
||||
|
||||
if (!link_is_ready_to_configure(link, false))
|
||||
return 0;
|
||||
|
||||
r = ipv6_proxy_ndp_address_configure(req->ipv6_proxy_ndp, link, req->netlink_handler);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to configure IPv6 proxy NDP address: %m");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int config_parse_ipv6_proxy_ndp_address(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
|
||||
@@ -229,6 +229,28 @@ static int neighbor_configure(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int request_process_neighbor(Request *req) {
|
||||
Neighbor *neighbor;
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->type == REQUEST_TYPE_NEIGHBOR);
|
||||
|
||||
neighbor = ASSERT_PTR(req->neighbor);
|
||||
link = ASSERT_PTR(req->link);
|
||||
|
||||
if (!link_is_ready_to_configure(link, false))
|
||||
return 0;
|
||||
|
||||
r = neighbor_configure(neighbor, link, req->netlink_handler);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to configure neighbor: %m");
|
||||
|
||||
neighbor_enter_configuring(neighbor);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int static_neighbor_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
@@ -447,28 +469,6 @@ void link_foreignize_neighbors(Link *link) {
|
||||
neighbor->source = NETWORK_CONFIG_SOURCE_FOREIGN;
|
||||
}
|
||||
|
||||
int request_process_neighbor(Request *req) {
|
||||
Neighbor *neighbor;
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->type == REQUEST_TYPE_NEIGHBOR);
|
||||
|
||||
neighbor = ASSERT_PTR(req->neighbor);
|
||||
link = ASSERT_PTR(req->link);
|
||||
|
||||
if (!link_is_ready_to_configure(link, false))
|
||||
return 0;
|
||||
|
||||
r = neighbor_configure(neighbor, link, req->netlink_handler);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to configure neighbor: %m");
|
||||
|
||||
neighbor_enter_configuring(neighbor);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int manager_rtnl_process_neighbor(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) {
|
||||
_cleanup_(neighbor_freep) Neighbor *tmp = NULL;
|
||||
Neighbor *neighbor = NULL;
|
||||
|
||||
@@ -524,6 +524,72 @@ static int static_nexthop_handler(sd_netlink *rtnl, sd_netlink_message *m, Link
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool nexthop_is_ready_to_configure(Link *link, const NextHop *nexthop) {
|
||||
struct nexthop_grp *nhg;
|
||||
|
||||
assert(link);
|
||||
assert(nexthop);
|
||||
|
||||
if (!link_is_ready_to_configure(link, false))
|
||||
return false;
|
||||
|
||||
if (nexthop_owned_by_link(nexthop)) {
|
||||
/* TODO: fdb nexthop does not require IFF_UP. The conditions below needs to be updated
|
||||
* when fdb nexthop support is added. See rtm_to_nh_config() in net/ipv4/nexthop.c of
|
||||
* kernel. */
|
||||
if (link->set_flags_messages > 0)
|
||||
return false;
|
||||
if (!FLAGS_SET(link->flags, IFF_UP))
|
||||
return false;
|
||||
}
|
||||
|
||||
/* All group members must be configured first. */
|
||||
HASHMAP_FOREACH(nhg, nexthop->group) {
|
||||
NextHop *g;
|
||||
|
||||
if (manager_get_nexthop_by_id(link->manager, nhg->id, &g) < 0)
|
||||
return false;
|
||||
|
||||
if (!nexthop_exists(g))
|
||||
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. */
|
||||
}
|
||||
}
|
||||
|
||||
return gateway_is_ready(link, FLAGS_SET(nexthop->flags, RTNH_F_ONLINK), nexthop->family, &nexthop->gw);
|
||||
}
|
||||
|
||||
int request_process_nexthop(Request *req) {
|
||||
NextHop *nexthop;
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->type == REQUEST_TYPE_NEXTHOP);
|
||||
|
||||
nexthop = ASSERT_PTR(req->nexthop);
|
||||
link = ASSERT_PTR(req->link);
|
||||
|
||||
if (!nexthop_is_ready_to_configure(link, nexthop))
|
||||
return 0;
|
||||
|
||||
r = nexthop_configure(nexthop, link, req->netlink_handler);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to configure nexthop");
|
||||
|
||||
nexthop_enter_configuring(nexthop);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int link_request_nexthop(
|
||||
Link *link,
|
||||
NextHop *nexthop,
|
||||
@@ -759,72 +825,6 @@ void link_foreignize_nexthops(Link *link) {
|
||||
}
|
||||
}
|
||||
|
||||
static bool nexthop_is_ready_to_configure(Link *link, const NextHop *nexthop) {
|
||||
struct nexthop_grp *nhg;
|
||||
|
||||
assert(link);
|
||||
assert(nexthop);
|
||||
|
||||
if (!link_is_ready_to_configure(link, false))
|
||||
return false;
|
||||
|
||||
if (nexthop_owned_by_link(nexthop)) {
|
||||
/* TODO: fdb nexthop does not require IFF_UP. The conditions below needs to be updated
|
||||
* when fdb nexthop support is added. See rtm_to_nh_config() in net/ipv4/nexthop.c of
|
||||
* kernel. */
|
||||
if (link->set_flags_messages > 0)
|
||||
return false;
|
||||
if (!FLAGS_SET(link->flags, IFF_UP))
|
||||
return false;
|
||||
}
|
||||
|
||||
/* All group members must be configured first. */
|
||||
HASHMAP_FOREACH(nhg, nexthop->group) {
|
||||
NextHop *g;
|
||||
|
||||
if (manager_get_nexthop_by_id(link->manager, nhg->id, &g) < 0)
|
||||
return false;
|
||||
|
||||
if (!nexthop_exists(g))
|
||||
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. */
|
||||
}
|
||||
}
|
||||
|
||||
return gateway_is_ready(link, FLAGS_SET(nexthop->flags, RTNH_F_ONLINK), nexthop->family, &nexthop->gw);
|
||||
}
|
||||
|
||||
int request_process_nexthop(Request *req) {
|
||||
NextHop *nexthop;
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->type == REQUEST_TYPE_NEXTHOP);
|
||||
|
||||
nexthop = ASSERT_PTR(req->nexthop);
|
||||
link = ASSERT_PTR(req->link);
|
||||
|
||||
if (!nexthop_is_ready_to_configure(link, nexthop))
|
||||
return 0;
|
||||
|
||||
r = nexthop_configure(nexthop, link, req->netlink_handler);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to configure nexthop");
|
||||
|
||||
nexthop_enter_configuring(nexthop);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int manager_rtnl_process_nexthop(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) {
|
||||
_cleanup_(nexthop_freep) NextHop *tmp = NULL;
|
||||
_cleanup_free_ void *raw_group = NULL;
|
||||
|
||||
+131
-131
@@ -1309,6 +1309,137 @@ static int static_route_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *l
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int route_is_ready_to_configure(const Route *route, Link *link) {
|
||||
int r;
|
||||
|
||||
assert(route);
|
||||
assert(link);
|
||||
|
||||
if (!link_is_ready_to_configure(link, false))
|
||||
return false;
|
||||
|
||||
if (set_size(link->routes) >= routes_max())
|
||||
return false;
|
||||
|
||||
if (route->nexthop_id > 0) {
|
||||
struct nexthop_grp *nhg;
|
||||
NextHop *nh;
|
||||
|
||||
if (manager_get_nexthop_by_id(link->manager, route->nexthop_id, &nh) < 0)
|
||||
return false;
|
||||
|
||||
if (!nexthop_exists(nh))
|
||||
return false;
|
||||
|
||||
HASHMAP_FOREACH(nhg, nh->group) {
|
||||
NextHop *g;
|
||||
|
||||
if (manager_get_nexthop_by_id(link->manager, nhg->id, &g) < 0)
|
||||
return false;
|
||||
|
||||
if (!nexthop_exists(g))
|
||||
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 (!gateway_is_ready(link, FLAGS_SET(route->flags, RTNH_F_ONLINK), route->gw_family, &route->gw))
|
||||
return false;
|
||||
|
||||
MultipathRoute *m;
|
||||
ORDERED_SET_FOREACH(m, route->multipath_routes) {
|
||||
union in_addr_union a = m->gateway.address;
|
||||
Link *l = NULL;
|
||||
|
||||
r = multipath_route_get_link(link->manager, m, &l);
|
||||
if (r < 0)
|
||||
return false;
|
||||
if (r > 0) {
|
||||
if (!link_is_ready_to_configure(l, true))
|
||||
return false;
|
||||
|
||||
m->ifindex = l->ifindex;
|
||||
}
|
||||
|
||||
if (!gateway_is_ready(l ?: link, FLAGS_SET(route->flags, RTNH_F_ONLINK), m->gateway.family, &a))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int request_process_route(Request *req) {
|
||||
_cleanup_(converted_routes_freep) ConvertedRoutes *converted = NULL;
|
||||
Route *route;
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->link);
|
||||
assert(req->route);
|
||||
assert(req->type == REQUEST_TYPE_ROUTE);
|
||||
|
||||
link = req->link;
|
||||
route = req->route;
|
||||
|
||||
r = route_is_ready_to_configure(route, link);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to check if route is ready to configure: %m");
|
||||
if (r == 0)
|
||||
return 0;
|
||||
|
||||
if (route_needs_convert(route)) {
|
||||
r = route_convert(link->manager, route, &converted);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to convert route: %m");
|
||||
|
||||
assert(r > 0);
|
||||
assert(converted);
|
||||
|
||||
for (size_t i = 0; i < converted->n; i++) {
|
||||
Route *existing;
|
||||
|
||||
if (route_get(link->manager, converted->links[i] ?: link, converted->routes[i], &existing) < 0) {
|
||||
_cleanup_(route_freep) Route *tmp = NULL;
|
||||
|
||||
r = route_dup(converted->routes[i], &tmp);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
r = route_add(link->manager, converted->links[i] ?: link, tmp);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to add route: %m");
|
||||
|
||||
TAKE_PTR(tmp);
|
||||
} else {
|
||||
existing->source = converted->routes[i]->source;
|
||||
existing->provider = converted->routes[i]->provider;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
r = route_configure(route, link, req->netlink_handler);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to configure route: %m");
|
||||
|
||||
if (converted)
|
||||
for (size_t i = 0; i < converted->n; i++) {
|
||||
Route *existing;
|
||||
|
||||
assert_se(route_get(link->manager, converted->links[i] ?: link, converted->routes[i], &existing) >= 0);
|
||||
route_enter_configuring(existing);
|
||||
}
|
||||
else
|
||||
route_enter_configuring(route);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int link_request_route(
|
||||
Link *link,
|
||||
Route *route,
|
||||
@@ -1450,137 +1581,6 @@ int link_request_static_routes(Link *link, bool only_ipv4) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int route_is_ready_to_configure(const Route *route, Link *link) {
|
||||
int r;
|
||||
|
||||
assert(route);
|
||||
assert(link);
|
||||
|
||||
if (!link_is_ready_to_configure(link, false))
|
||||
return false;
|
||||
|
||||
if (set_size(link->routes) >= routes_max())
|
||||
return false;
|
||||
|
||||
if (route->nexthop_id > 0) {
|
||||
struct nexthop_grp *nhg;
|
||||
NextHop *nh;
|
||||
|
||||
if (manager_get_nexthop_by_id(link->manager, route->nexthop_id, &nh) < 0)
|
||||
return false;
|
||||
|
||||
if (!nexthop_exists(nh))
|
||||
return false;
|
||||
|
||||
HASHMAP_FOREACH(nhg, nh->group) {
|
||||
NextHop *g;
|
||||
|
||||
if (manager_get_nexthop_by_id(link->manager, nhg->id, &g) < 0)
|
||||
return false;
|
||||
|
||||
if (!nexthop_exists(g))
|
||||
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 (!gateway_is_ready(link, FLAGS_SET(route->flags, RTNH_F_ONLINK), route->gw_family, &route->gw))
|
||||
return false;
|
||||
|
||||
MultipathRoute *m;
|
||||
ORDERED_SET_FOREACH(m, route->multipath_routes) {
|
||||
union in_addr_union a = m->gateway.address;
|
||||
Link *l = NULL;
|
||||
|
||||
r = multipath_route_get_link(link->manager, m, &l);
|
||||
if (r < 0)
|
||||
return false;
|
||||
if (r > 0) {
|
||||
if (!link_is_ready_to_configure(l, true))
|
||||
return false;
|
||||
|
||||
m->ifindex = l->ifindex;
|
||||
}
|
||||
|
||||
if (!gateway_is_ready(l ?: link, FLAGS_SET(route->flags, RTNH_F_ONLINK), m->gateway.family, &a))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int request_process_route(Request *req) {
|
||||
_cleanup_(converted_routes_freep) ConvertedRoutes *converted = NULL;
|
||||
Route *route;
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->link);
|
||||
assert(req->route);
|
||||
assert(req->type == REQUEST_TYPE_ROUTE);
|
||||
|
||||
link = req->link;
|
||||
route = req->route;
|
||||
|
||||
r = route_is_ready_to_configure(route, link);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to check if route is ready to configure: %m");
|
||||
if (r == 0)
|
||||
return 0;
|
||||
|
||||
if (route_needs_convert(route)) {
|
||||
r = route_convert(link->manager, route, &converted);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to convert route: %m");
|
||||
|
||||
assert(r > 0);
|
||||
assert(converted);
|
||||
|
||||
for (size_t i = 0; i < converted->n; i++) {
|
||||
Route *existing;
|
||||
|
||||
if (route_get(link->manager, converted->links[i] ?: link, converted->routes[i], &existing) < 0) {
|
||||
_cleanup_(route_freep) Route *tmp = NULL;
|
||||
|
||||
r = route_dup(converted->routes[i], &tmp);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
r = route_add(link->manager, converted->links[i] ?: link, tmp);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to add route: %m");
|
||||
|
||||
TAKE_PTR(tmp);
|
||||
} else {
|
||||
existing->source = converted->routes[i]->source;
|
||||
existing->provider = converted->routes[i]->provider;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
r = route_configure(route, link, req->netlink_handler);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to configure route: %m");
|
||||
|
||||
if (converted)
|
||||
for (size_t i = 0; i < converted->n; i++) {
|
||||
Route *existing;
|
||||
|
||||
assert_se(route_get(link->manager, converted->links[i] ?: link, converted->routes[i], &existing) >= 0);
|
||||
route_enter_configuring(existing);
|
||||
}
|
||||
else
|
||||
route_enter_configuring(route);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int process_route_one(
|
||||
Manager *manager,
|
||||
Link *link,
|
||||
|
||||
@@ -728,6 +728,28 @@ void link_foreignize_routing_policy_rules(Link *link) {
|
||||
}
|
||||
}
|
||||
|
||||
int request_process_routing_policy_rule(Request *req) {
|
||||
RoutingPolicyRule *rule;
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->type == REQUEST_TYPE_ROUTING_POLICY_RULE);
|
||||
|
||||
link = ASSERT_PTR(req->link);
|
||||
rule = ASSERT_PTR(req->rule);
|
||||
|
||||
if (!link_is_ready_to_configure(link, false))
|
||||
return 0;
|
||||
|
||||
r = routing_policy_rule_configure(rule, link, req->netlink_handler);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to configure routing policy rule: %m");
|
||||
|
||||
routing_policy_rule_enter_configuring(rule);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int static_routing_policy_rule_configure_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
|
||||
int r;
|
||||
|
||||
@@ -856,28 +878,6 @@ int link_request_static_routing_policy_rules(Link *link) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int request_process_routing_policy_rule(Request *req) {
|
||||
RoutingPolicyRule *rule;
|
||||
Link *link;
|
||||
int r;
|
||||
|
||||
assert(req);
|
||||
assert(req->type == REQUEST_TYPE_ROUTING_POLICY_RULE);
|
||||
|
||||
link = ASSERT_PTR(req->link);
|
||||
rule = ASSERT_PTR(req->rule);
|
||||
|
||||
if (!link_is_ready_to_configure(link, false))
|
||||
return 0;
|
||||
|
||||
r = routing_policy_rule_configure(rule, link, req->netlink_handler);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to configure routing policy rule: %m");
|
||||
|
||||
routing_policy_rule_enter_configuring(rule);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const RoutingPolicyRule kernel_rules[] = {
|
||||
{ .family = AF_INET, .priority_set = true, .priority = 0, .table = RT_TABLE_LOCAL, .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, .suppress_ifgroup = -1, },
|
||||
{ .family = AF_INET, .priority_set = true, .priority = 32766, .table = RT_TABLE_MAIN, .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, .suppress_ifgroup = -1, },
|
||||
|
||||
Reference in New Issue
Block a user