diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-07-15 07:59:13 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-15 07:59:13 +0900 |
commit | 3f5ef8aeac7cf9bc19fc58d2eec915650f505ba5 (patch) | |
tree | 79efff1968c28bb283fd49ff201629607c65cd87 /src | |
parent | b5e17d7fed3ab1f1f2c64a20d904390577b53fa9 (diff) | |
parent | 72c747e6d10637c0844e7c239a47bd5e6d42763c (diff) | |
download | systemd-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.c | 14 | ||||
-rw-r--r-- | src/basic/in-addr-util.h | 1 | ||||
-rw-r--r-- | src/libsystemd-network/sd-ipv4ll.c | 11 | ||||
-rw-r--r-- | src/network/networkd-ipv4ll.c | 5 |
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; } |