case REQUEST_TYPE_NEXTHOP:
nexthop_free(object);
break;
+ case REQUEST_TYPE_RADV:
+ break;
case REQUEST_TYPE_ROUTE:
route_free(object);
break;
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;
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:
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) {
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;
#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"
return 0;
- set_dns:
+set_dns:
return sd_radv_set_rdnss(link->radv,
DIV_ROUND_UP(lifetime_usec, USEC_PER_SEC),
dns, n_dns);
return 0;
- set_domains:
+set_domains:
s = ordered_set_get_strv(search_domains);
if (!s)
return log_oom();
}
-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);
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;
assert(link);
assert(link->network);
- if (!link_radv_enabled(link))
- return 0;
-
if (link->radv)
return -EBUSY;
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;
}
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,
#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,
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_;