aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuca Boccassi <luca.boccassi@microsoft.com>2022-01-31 14:21:28 +0000
committerGitHub <noreply@github.com>2022-01-31 14:21:28 +0000
commit187df3dd91105385c27b4eb0eb5ab05981f6732c (patch)
tree9ede853b4f639119bece08ea04c20bc44d7e0516
parentMerge pull request #22300 from yuwata/bus-fix-error-handling (diff)
parentnetwork: currently IPv4ACD requires MAC address whose length is ETH_ALEN (diff)
downloadsystemd-187df3dd91105385c27b4eb0eb5ab05981f6732c.tar.xz
systemd-187df3dd91105385c27b4eb0eb5ab05981f6732c.zip
Merge pull request #22316 from yuwata/network-mac-address-length
network: several cleanups related to MAC address length
-rw-r--r--src/network/networkd-dhcp-common.c7
-rw-r--r--src/network/networkd-dhcp4.c5
-rw-r--r--src/network/networkd-dhcp6.c5
-rw-r--r--src/network/networkd-ipv4acd.c8
-rw-r--r--src/network/networkd-link.c2
-rw-r--r--src/network/networkd-ndisc.c69
-rw-r--r--src/network/networkd-ndisc.h5
-rw-r--r--src/network/networkd-queue.c13
-rw-r--r--src/network/networkd-queue.h1
-rw-r--r--src/network/networkd-radv.c6
10 files changed, 114 insertions, 7 deletions
diff --git a/src/network/networkd-dhcp-common.c b/src/network/networkd-dhcp-common.c
index 7996960bd12..5331cdcead9 100644
--- a/src/network/networkd-dhcp-common.c
+++ b/src/network/networkd-dhcp-common.c
@@ -61,6 +61,13 @@ bool link_dhcp_enabled(Link *link, int family) {
if (link->iftype == ARPHRD_CAN)
return false;
+ if (!IN_SET(link->hw_addr.length, ETH_ALEN, INFINIBAND_ALEN) &&
+ !streq_ptr(link->kind, "wwan"))
+ /* Currently, only interfaces whose MAC address length is ETH_ALEN or INFINIBAND_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;
diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c
index cb9c428ae9b..718ac62f8e5 100644
--- a/src/network/networkd-dhcp4.c
+++ b/src/network/networkd-dhcp4.c
@@ -1607,6 +1607,11 @@ int request_process_dhcp4_client(Request *req) {
if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
return 0;
+ if (!IN_SET(link->hw_addr.length, ETH_ALEN, INFINIBAND_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 = dhcp4_configure_duid(link);
if (r <= 0)
return r;
diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c
index e591043111d..ab51b7377da 100644
--- a/src/network/networkd-dhcp6.c
+++ b/src/network/networkd-dhcp6.c
@@ -711,6 +711,11 @@ int request_process_dhcp6_client(Request *req) {
if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
return 0;
+ if (!IN_SET(link->hw_addr.length, ETH_ALEN, INFINIBAND_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 = dhcp_configure_duid(link, link_get_dhcp6_duid(link));
if (r <= 0)
return r;
diff --git a/src/network/networkd-ipv4acd.c b/src/network/networkd-ipv4acd.c
index 703278f8b86..009cde27de1 100644
--- a/src/network/networkd-ipv4acd.c
+++ b/src/network/networkd-ipv4acd.c
@@ -132,7 +132,8 @@ int ipv4acd_configure(Address *address) {
int r;
assert(address);
- assert(address->link);
+
+ link = ASSERT_PTR(address->link);
if (address->family != AF_INET)
return 0;
@@ -140,6 +141,9 @@ int ipv4acd_configure(Address *address) {
if (!FLAGS_SET(address->duplicate_address_detection, ADDRESS_FAMILY_IPV4))
return 0;
+ if (link->hw_addr.length != ETH_ALEN || hw_addr_is_null(&link->hw_addr))
+ return 0;
+
/* Currently, only static and DHCP4 addresses are supported. */
assert(IN_SET(address->source, NETWORK_CONFIG_SOURCE_STATIC, NETWORK_CONFIG_SOURCE_DHCP4));
@@ -148,8 +152,6 @@ int ipv4acd_configure(Address *address) {
return 0;
}
- link = address->link;
-
log_link_debug(link, "Configuring IPv4ACD for address "IPV4_ADDRESS_FMT_STR,
IPV4_ADDRESS_FMT_VAL(address->in_addr.in));
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index ab4f321b006..a8de644559b 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 f616f2c9bc7..06c4366b704 100644
--- a/src/network/networkd-ndisc.c
+++ b/src/network/networkd-ndisc.c
@@ -6,6 +6,7 @@
#include <arpa/inet.h>
#include <netinet/icmp6.h>
#include <linux/if.h>
+#include <linux/if_arp.h>
#include "sd-ndisc.h"
@@ -34,6 +35,15 @@ bool link_ipv6_accept_ra_enabled(Link *link) {
if (link->flags & IFF_LOOPBACK)
return false;
+ if (link->iftype == ARPHRD_CAN)
+ 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 +1065,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 +1100,8 @@ int ndisc_configure(Link *link) {
}
int ndisc_start(Link *link) {
+ int r;
+
assert(link);
if (!link->ndisc || !link->dhcp6_client)
@@ -1103,7 +1115,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 acb97a892e2..1958652778d 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 8cd5300ce60..14dc1cf4926 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 c0cdacfbd80..ac33e885f2b 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,
diff --git a/src/network/networkd-radv.c b/src/network/networkd-radv.c
index 0c5eebc8157..507f0a0ccc8 100644
--- a/src/network/networkd-radv.c
+++ b/src/network/networkd-radv.c
@@ -57,6 +57,9 @@ bool link_radv_enabled(Link *link) {
if (!link_may_have_ipv6ll(link))
return false;
+ if (link->hw_addr.length != ETH_ALEN)
+ return false;
+
return link->network->router_prefix_delegation;
}
@@ -547,6 +550,9 @@ static int radv_is_ready_to_configure(Link *link) {
if (in6_addr_is_null(&link->ipv6ll_address))
return false;
+ if (link->hw_addr.length != ETH_ALEN || hw_addr_is_null(&link->hw_addr))
+ return false;
+
if (link->network->router_emit_dns && !link->network->router_dns) {
_cleanup_free_ struct in6_addr *dns = NULL;
size_t n_dns;