network: use request queue to configure IPv6 RA engine

This commit is contained in:
Yu Watanabe 2021-06-16 03:37:57 +09:00
parent 2b24292692
commit a254fab20d
5 changed files with 98 additions and 33 deletions

View file

@ -618,12 +618,8 @@ static int link_acquire_dynamic_ipv6_conf(Link *link) {
log_link_debug(link, "Starting IPv6 Router Advertisements");
r = radv_emit_dns(link);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to configure DNS or Domains in IPv6 Router Advertisement: %m");
r = sd_radv_start(link->radv);
if (r < 0 && r != -EBUSY)
if (r < 0)
return log_link_warning_errno(link, r, "Could not start IPv6 Router Advertisement: %m");
}
@ -1147,7 +1143,7 @@ static int link_configure(Link *link) {
if (r < 0)
return r;
r = radv_configure(link);
r = link_request_radv(link);
if (r < 0)
return r;

View file

@ -43,6 +43,8 @@ static void request_free_object(RequestType type, void *object) {
case REQUEST_TYPE_NEXTHOP:
nexthop_free(object);
break;
case REQUEST_TYPE_RADV:
break;
case REQUEST_TYPE_ROUTE:
route_free(object);
break;
@ -121,6 +123,9 @@ static void request_hash_func(const Request *req, struct siphash *state) {
case REQUEST_TYPE_NEXTHOP:
nexthop_hash_func(req->nexthop, state);
break;
case REQUEST_TYPE_RADV:
/* This type does not have an object. */
break;
case REQUEST_TYPE_ROUTE:
route_hash_func(req->route, state);
break;
@ -174,6 +179,8 @@ static int request_compare_func(const struct Request *a, const struct Request *b
return nexthop_compare_func(a->nexthop, b->nexthop);
case REQUEST_TYPE_ROUTE:
return route_compare_func(a->route, b->route);
case REQUEST_TYPE_RADV:
return 0;
case REQUEST_TYPE_ROUTING_POLICY_RULE:
return routing_policy_rule_compare_func(a->rule, b->rule);
case REQUEST_TYPE_SET_LINK:
@ -211,10 +218,14 @@ int link_queue_request(
assert(IN_SET(type,
REQUEST_TYPE_ACTIVATE_LINK,
REQUEST_TYPE_DHCP_SERVER,
REQUEST_TYPE_RADV,
REQUEST_TYPE_SET_LINK,
REQUEST_TYPE_UP_DOWN) ||
object);
assert(type == REQUEST_TYPE_DHCP_SERVER || netlink_handler);
assert(IN_SET(type,
REQUEST_TYPE_DHCP_SERVER,
REQUEST_TYPE_RADV) ||
netlink_handler);
req = new(Request, 1);
if (!req) {
@ -298,6 +309,9 @@ int manager_process_requests(sd_event_source *s, void *userdata) {
case REQUEST_TYPE_NEXTHOP:
r = request_process_nexthop(req);
break;
case REQUEST_TYPE_RADV:
r = request_process_radv(req);
break;
case REQUEST_TYPE_ROUTE:
r = request_process_route(req);
break;

View file

@ -31,6 +31,7 @@ typedef enum RequestType {
REQUEST_TYPE_IPV6_PROXY_NDP,
REQUEST_TYPE_NEIGHBOR,
REQUEST_TYPE_NEXTHOP,
REQUEST_TYPE_RADV,
REQUEST_TYPE_ROUTE,
REQUEST_TYPE_ROUTING_POLICY_RULE,
REQUEST_TYPE_SET_LINK,

View file

@ -10,6 +10,7 @@
#include "networkd-link.h"
#include "networkd-manager.h"
#include "networkd-network.h"
#include "networkd-queue.h"
#include "networkd-radv.h"
#include "parse-util.h"
#include "string-util.h"
@ -595,7 +596,7 @@ static int radv_set_dns(Link *link, Link *uplink) {
return 0;
set_dns:
set_dns:
return sd_radv_set_rdnss(link->radv,
DIV_ROUND_UP(lifetime_usec, USEC_PER_SEC),
dns, n_dns);
@ -634,7 +635,7 @@ static int radv_set_domains(Link *link, Link *uplink) {
return 0;
set_domains:
set_domains:
s = ordered_set_get_strv(search_domains);
if (!s)
return log_oom();
@ -645,23 +646,6 @@ static int radv_set_domains(Link *link, Link *uplink) {
}
int radv_emit_dns(Link *link) {
Link *uplink = NULL;
int r;
(void) manager_find_uplink(link->manager, AF_INET6, link, &uplink);
r = radv_set_dns(link, uplink);
if (r < 0)
log_link_warning_errno(link, r, "Could not set RA DNS: %m");
r = radv_set_domains(link, uplink);
if (r < 0)
log_link_warning_errno(link, r, "Could not set RA Domains: %m");
return 0;
}
static bool link_radv_enabled(Link *link) {
assert(link);
@ -671,8 +655,9 @@ static bool link_radv_enabled(Link *link) {
return link->network->router_prefix_delegation;
}
int radv_configure(Link *link) {
static int radv_configure(Link *link) {
uint16_t router_lifetime;
Link *uplink = NULL;
RoutePrefix *q;
Prefix *p;
int r;
@ -680,9 +665,6 @@ int radv_configure(Link *link) {
assert(link);
assert(link->network);
if (!link_radv_enabled(link))
return 0;
if (link->radv)
return -EBUSY;
@ -748,6 +730,16 @@ int radv_configure(Link *link) {
return r;
}
(void) manager_find_uplink(link->manager, AF_INET6, link, &uplink);
r = radv_set_dns(link, uplink);
if (r < 0)
return log_link_debug_errno(link, r, "Could not set RA DNS: %m");
r = radv_set_domains(link, uplink);
if (r < 0)
return log_link_debug_errno(link, r, "Could not set RA Domains: %m");
return 0;
}
@ -779,6 +771,66 @@ int radv_update_mac(Link *link) {
return 0;
}
static bool radv_is_ready_to_configure(Link *link) {
assert(link);
assert(link->network);
if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
return false;
if (in6_addr_is_null(&link->ipv6ll_address))
return false;
return true;
}
int request_process_radv(Request *req) {
Link *link;
int r;
assert(req);
assert(req->link);
assert(req->type == REQUEST_TYPE_RADV);
link = req->link;
if (!radv_is_ready_to_configure(link))
return 0;
r = radv_configure(link);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to configure IPv6 Router Advertisement engine: %m");
if (link_has_carrier(link)) {
r = sd_radv_start(link->radv);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to start IPv6 Router Advertisement engine: %m");
}
log_link_debug(link, "IPv6 Router Advertisement engine is configured%s.",
link_has_carrier(link) ? " and started." : "");
return 1;
}
int link_request_radv(Link *link) {
int r;
assert(link);
if (!link_radv_enabled(link))
return 0;
if (link->radv)
return 0;
r = link_queue_request(link, REQUEST_TYPE_RADV, NULL, false, NULL, NULL, NULL);
if (r < 0)
return log_link_warning_errno(link, r, "Failed to request IPv6 Router Advertisement engine: %m");
log_link_debug(link, "IPv6 Router Advertisement engine is requested.");
return 0;
}
int radv_add_prefix(
Link *link,
const struct in6_addr *prefix,

View file

@ -14,8 +14,9 @@
#include "conf-parser.h"
#include "networkd-util.h"
typedef struct Network Network;
typedef struct Link Link;
typedef struct Network Network;
typedef struct Request Request;
typedef enum RADVPrefixDelegation {
RADV_PREFIX_DELEGATION_NONE = 0,
@ -50,12 +51,13 @@ void network_drop_invalid_prefixes(Network *network);
void network_drop_invalid_route_prefixes(Network *network);
void network_adjust_radv(Network *network);
int radv_emit_dns(Link *link);
int radv_configure(Link *link);
int radv_update_mac(Link *link);
int radv_add_prefix(Link *link, const struct in6_addr *prefix, uint8_t prefix_len,
uint32_t lifetime_preferred, uint32_t lifetime_valid);
int request_process_radv(Request *req);
int link_request_radv(Link *link);
const char* radv_prefix_delegation_to_string(RADVPrefixDelegation i) _const_;
RADVPrefixDelegation radv_prefix_delegation_from_string(const char *s) _pure_;