if (r < 0)
return r;
- r = ndisc_configure(link);
+ r = link_request_ndisc(link);
if (r < 0)
return r;
if (link->flags & IFF_LOOPBACK)
return false;
+ if (link->hw_addr.length != ETH_ALEN && !streq_ptr(link->kind, "wwan"))
+ /* Currently, only interfaces whose MAC address length is ETH_ALEN are supported.
+ * Note, wwan interfaces may be assigned MAC address slightly later.
+ * Hence, let's wait for a while.*/
+ return false;
+
if (!link->network)
return false;
}
}
-int ndisc_configure(Link *link) {
+static int ndisc_configure(Link *link) {
int r;
assert(link);
}
int ndisc_start(Link *link) {
+ int r;
+
assert(link);
if (!link->ndisc || !link->dhcp6_client)
log_link_debug(link, "Discovering IPv6 routers");
- return sd_ndisc_start(link->ndisc);
+ r = sd_ndisc_start(link->ndisc);
+ if (r < 0)
+ return r;
+
+ return 1;
+}
+
+int request_process_ndisc(Request *req) {
+ Link *link;
+ int r;
+
+ assert(req);
+ assert(req->type == REQUEST_TYPE_NDISC);
+
+ link = ASSERT_PTR(req->link);
+
+ if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
+ return 0;
+
+ if (link->hw_addr.length != ETH_ALEN || hw_addr_is_null(&link->hw_addr))
+ /* No MAC address is assigned to the hardware, or non-supported MAC address length. */
+ return 0;
+
+ r = ndisc_configure(link);
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Failed to configure IPv6 Router Discovery: %m");
+
+ r = ndisc_start(link);
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Failed to start IPv6 Router Discovery: %m");
+
+ log_link_debug(link, "IPv6 Router Discovery is configured%s.",
+ r > 0 ? " and started" : "");
+
+ return 1;
+}
+
+int link_request_ndisc(Link *link) {
+ int r;
+
+ assert(link);
+
+ if (!link_ipv6_accept_ra_enabled(link))
+ return 0;
+
+ if (link->ndisc)
+ return 0;
+
+ r = link_queue_request(link, REQUEST_TYPE_NDISC, NULL, false, NULL, NULL, NULL);
+ if (r < 0)
+ return log_link_warning_errno(link, r, "Failed to request configuring of the IPv6 Router Discovery: %m");
+
+ log_link_debug(link, "Requested configuring of the IPv6 Router Discovery.");
+ return 0;
}
void ndisc_vacuum(Link *link) {
typedef struct Link Link;
typedef struct Network Network;
+typedef struct Request Request;
typedef enum IPv6AcceptRAStartDHCP6Client {
IPV6_ACCEPT_RA_START_DHCP6_CLIENT_NO,
void network_adjust_ipv6_accept_ra(Network *network);
-int ndisc_configure(Link *link);
int ndisc_start(Link *link);
void ndisc_vacuum(Link *link);
void ndisc_flush(Link *link);
+int request_process_ndisc(Request *req);
+int link_request_ndisc(Link *link);
+
CONFIG_PARSER_PROTOTYPE(config_parse_ipv6_accept_ra_start_dhcp6_client);
CONFIG_PARSER_PROTOTYPE(config_parse_ipv6_accept_ra_use_domains);
#include "networkd-dhcp6.h"
#include "networkd-ipv6-proxy-ndp.h"
#include "networkd-manager.h"
+#include "networkd-ndisc.h"
#include "networkd-neighbor.h"
#include "networkd-nexthop.h"
#include "networkd-route.h"
case REQUEST_TYPE_IPV6_PROXY_NDP:
free(object);
break;
+ case REQUEST_TYPE_NDISC:
+ break;
case REQUEST_TYPE_NEIGHBOR:
neighbor_free(object);
break;
case REQUEST_TYPE_IPV6_PROXY_NDP:
in6_addr_hash_func(req->ipv6_proxy_ndp, state);
break;
+ case REQUEST_TYPE_NDISC:
+ /* This type does not have an object. */
+ break;
case REQUEST_TYPE_NEIGHBOR:
neighbor_hash_func(req->neighbor, state);
break;
return 0;
case REQUEST_TYPE_IPV6_PROXY_NDP:
return in6_addr_compare_func(a->ipv6_proxy_ndp, b->ipv6_proxy_ndp);
+ case REQUEST_TYPE_NDISC:
+ return 0;
case REQUEST_TYPE_NEIGHBOR:
return neighbor_compare_func(a->neighbor, b->neighbor);
case REQUEST_TYPE_NEXTHOP:
REQUEST_TYPE_DHCP_SERVER,
REQUEST_TYPE_DHCP4_CLIENT,
REQUEST_TYPE_DHCP6_CLIENT,
+ REQUEST_TYPE_NDISC,
REQUEST_TYPE_RADV,
REQUEST_TYPE_SET_LINK,
REQUEST_TYPE_UP_DOWN) ||
REQUEST_TYPE_DHCP_SERVER,
REQUEST_TYPE_DHCP4_CLIENT,
REQUEST_TYPE_DHCP6_CLIENT,
+ REQUEST_TYPE_NDISC,
REQUEST_TYPE_RADV) ||
netlink_handler);
case REQUEST_TYPE_IPV6_PROXY_NDP:
r = request_process_ipv6_proxy_ndp_address(req);
break;
+ case REQUEST_TYPE_NDISC:
+ r = request_process_ndisc(req);
+ break;
case REQUEST_TYPE_NEIGHBOR:
r = request_process_neighbor(req);
break;
REQUEST_TYPE_DHCP4_CLIENT,
REQUEST_TYPE_DHCP6_CLIENT,
REQUEST_TYPE_IPV6_PROXY_NDP,
+ REQUEST_TYPE_NDISC,
REQUEST_TYPE_NEIGHBOR,
REQUEST_TYPE_NEXTHOP,
REQUEST_TYPE_RADV,