diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-01-31 04:35:44 +0100 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-01-31 05:10:28 +0100 |
commit | ba4c7184b320bb8698d470530d46a6c94641cc6e (patch) | |
tree | 5e05fdb041f36363746987e711f2b60f431ae344 /src | |
parent | network: configure DHCP clients after MAC address is assigned (diff) | |
download | systemd-ba4c7184b320bb8698d470530d46a6c94641cc6e.tar.xz systemd-ba4c7184b320bb8698d470530d46a6c94641cc6e.zip |
network: configure NDisc after MAC address is assigned
Diffstat (limited to 'src')
-rw-r--r-- | src/network/networkd-link.c | 2 | ||||
-rw-r--r-- | src/network/networkd-ndisc.c | 65 | ||||
-rw-r--r-- | src/network/networkd-ndisc.h | 5 | ||||
-rw-r--r-- | src/network/networkd-queue.c | 13 | ||||
-rw-r--r-- | src/network/networkd-queue.h | 1 |
5 files changed, 82 insertions, 4 deletions
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index ab4f321b00..a8de644559 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -1200,7 +1200,7 @@ static int link_configure(Link *link) { if (r < 0) return r; - r = ndisc_configure(link); + r = link_request_ndisc(link); if (r < 0) return r; diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index f616f2c9bc..4193b51093 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -34,6 +34,12 @@ bool link_ipv6_accept_ra_enabled(Link *link) { 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; @@ -1055,7 +1061,7 @@ static void ndisc_handler(sd_ndisc *nd, sd_ndisc_event_t event, sd_ndisc_router } } -int ndisc_configure(Link *link) { +static int ndisc_configure(Link *link) { int r; assert(link); @@ -1090,6 +1096,8 @@ int ndisc_configure(Link *link) { } int ndisc_start(Link *link) { + int r; + assert(link); if (!link->ndisc || !link->dhcp6_client) @@ -1103,7 +1111,60 @@ int ndisc_start(Link *link) { 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) { diff --git a/src/network/networkd-ndisc.h b/src/network/networkd-ndisc.h index acb97a892e..1958652778 100644 --- a/src/network/networkd-ndisc.h +++ b/src/network/networkd-ndisc.h @@ -6,6 +6,7 @@ typedef struct Link Link; typedef struct Network Network; +typedef struct Request Request; typedef enum IPv6AcceptRAStartDHCP6Client { IPV6_ACCEPT_RA_START_DHCP6_CLIENT_NO, @@ -43,10 +44,12 @@ bool link_ipv6_accept_ra_enabled(Link *link); 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); diff --git a/src/network/networkd-queue.c b/src/network/networkd-queue.c index 8cd5300ce6..14dc1cf492 100644 --- a/src/network/networkd-queue.c +++ b/src/network/networkd-queue.c @@ -9,6 +9,7 @@ #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" @@ -39,6 +40,8 @@ static void request_free_object(RequestType type, void *object) { case REQUEST_TYPE_IPV6_PROXY_NDP: free(object); break; + case REQUEST_TYPE_NDISC: + break; case REQUEST_TYPE_NEIGHBOR: neighbor_free(object); break; @@ -119,6 +122,9 @@ static void request_hash_func(const Request *req, struct siphash *state) { 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; @@ -177,6 +183,8 @@ static int request_compare_func(const struct Request *a, const struct Request *b 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: @@ -224,6 +232,7 @@ int link_queue_request( 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) || @@ -232,6 +241,7 @@ int link_queue_request( REQUEST_TYPE_DHCP_SERVER, REQUEST_TYPE_DHCP4_CLIENT, REQUEST_TYPE_DHCP6_CLIENT, + REQUEST_TYPE_NDISC, REQUEST_TYPE_RADV) || netlink_handler); @@ -314,6 +324,9 @@ int manager_process_requests(sd_event_source *s, void *userdata) { 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; diff --git a/src/network/networkd-queue.h b/src/network/networkd-queue.h index c0cdacfbd8..ac33e885f2 100644 --- a/src/network/networkd-queue.h +++ b/src/network/networkd-queue.h @@ -25,6 +25,7 @@ typedef enum RequestType { 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, |