summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2022-07-15 07:59:13 +0900
committerGitHub <noreply@github.com>2022-07-15 07:59:13 +0900
commit3f5ef8aeac7cf9bc19fc58d2eec915650f505ba5 (patch)
tree79efff1968c28bb283fd49ff201629607c65cd87 /src
parentb5e17d7fed3ab1f1f2c64a20d904390577b53fa9 (diff)
parent72c747e6d10637c0844e7c239a47bd5e6d42763c (diff)
downloadsystemd-3f5ef8aeac7cf9bc19fc58d2eec915650f505ba5.tar.gz
Merge pull request #24019 from yuwata/network-ipv4ll
network: refuse 169.254.0.0/24 and 169.254.255.0/24
Diffstat (limited to 'src')
-rw-r--r--src/basic/in-addr-util.c14
-rw-r--r--src/basic/in-addr-util.h1
-rw-r--r--src/libsystemd-network/sd-ipv4ll.c11
-rw-r--r--src/network/networkd-ipv4ll.c5
4 files changed, 19 insertions, 12 deletions
diff --git a/src/basic/in-addr-util.c b/src/basic/in-addr-util.c
index 6f8ffaf259..fe356c6d15 100644
--- a/src/basic/in-addr-util.c
+++ b/src/basic/in-addr-util.c
@@ -49,6 +49,20 @@ bool in4_addr_is_link_local(const struct in_addr *a) {
return (be32toh(a->s_addr) & UINT32_C(0xFFFF0000)) == (UINT32_C(169) << 24 | UINT32_C(254) << 16);
}
+bool in4_addr_is_link_local_dynamic(const struct in_addr *a) {
+ assert(a);
+
+ if (!in4_addr_is_link_local(a))
+ return false;
+
+ /* 169.254.0.0/24 and 169.254.255.0/24 must not be used for the dynamic IPv4LL assignment.
+ * See RFC 3927 Section 2.1:
+ * The IPv4 prefix 169.254/16 is registered with the IANA for this purpose. The first 256 and last
+ * 256 addresses in the 169.254/16 prefix are reserved for future use and MUST NOT be selected by a
+ * host using this dynamic configuration mechanism. */
+ return !IN_SET(be32toh(a->s_addr) & 0x0000FF00U, 0x0000U, 0xFF00U);
+}
+
bool in6_addr_is_link_local(const struct in6_addr *a) {
assert(a);
diff --git a/src/basic/in-addr-util.h b/src/basic/in-addr-util.h
index c1e7ef965d..fbc60436c7 100644
--- a/src/basic/in-addr-util.h
+++ b/src/basic/in-addr-util.h
@@ -44,6 +44,7 @@ static inline bool in_addr_data_is_set(const struct in_addr_data *a) {
int in_addr_is_multicast(int family, const union in_addr_union *u);
bool in4_addr_is_link_local(const struct in_addr *a);
+bool in4_addr_is_link_local_dynamic(const struct in_addr *a);
bool in6_addr_is_link_local(const struct in6_addr *a);
int in_addr_is_link_local(int family, const union in_addr_union *u);
bool in6_addr_is_link_local_all_nodes(const struct in6_addr *a);
diff --git a/src/libsystemd-network/sd-ipv4ll.c b/src/libsystemd-network/sd-ipv4ll.c
index fe0d836165..155c1a5de6 100644
--- a/src/libsystemd-network/sd-ipv4ll.c
+++ b/src/libsystemd-network/sd-ipv4ll.c
@@ -212,21 +212,12 @@ int sd_ipv4ll_is_running(sd_ipv4ll *ll) {
return sd_ipv4acd_is_running(ll->acd);
}
-static bool ipv4ll_address_is_valid(const struct in_addr *address) {
- assert(address);
-
- if (!in4_addr_is_link_local(address))
- return false;
-
- return !IN_SET(be32toh(address->s_addr) & 0x0000FF00U, 0x0000U, 0xFF00U);
-}
-
int sd_ipv4ll_set_address(sd_ipv4ll *ll, const struct in_addr *address) {
int r;
assert_return(ll, -EINVAL);
assert_return(address, -EINVAL);
- assert_return(ipv4ll_address_is_valid(address), -EINVAL);
+ assert_return(in4_addr_is_link_local_dynamic(address), -EINVAL);
r = sd_ipv4acd_set_address(ll->acd, address);
if (r < 0)
diff --git a/src/network/networkd-ipv4ll.c b/src/network/networkd-ipv4ll.c
index 8833bee233..6dfa60e08b 100644
--- a/src/network/networkd-ipv4ll.c
+++ b/src/network/networkd-ipv4ll.c
@@ -295,9 +295,10 @@ int config_parse_ipv4ll_address(
"Failed to parse %s=, ignoring assignment: %s", lvalue, rvalue);
return 0;
}
- if (!in4_addr_is_link_local(&a.in)) {
+ if (!in4_addr_is_link_local_dynamic(&a.in)) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
- "Not a IPv4 link local address, ignoring assignment: %s", rvalue);
+ "Specified address cannot be used as an IPv4 link local address, ignoring assignment: %s",
+ rvalue);
return 0;
}