mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-11 05:17:44 +03:00
Merge pull request #24019 from yuwata/network-ipv4ll
network: refuse 169.254.0.0/24 and 169.254.255.0/24
This commit is contained in:
commit
3f5ef8aeac
@ -401,12 +401,11 @@
|
||||
<varlistentry>
|
||||
<term><varname>IPv4LLStartAddress=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies the first IPv4 link-local address to try. Takes an IPv4 address
|
||||
for example 169.254.1.2, from the link-local address range 169.254.0.0/16.
|
||||
This setting may be useful if the device should always have the same address
|
||||
as long as there is no address conflict. When unset, a random address will be automatically selected.
|
||||
Defaults to unset.
|
||||
</para>
|
||||
<para>Specifies the first IPv4 link-local address to try. Takes an IPv4 address for example
|
||||
169.254.1.2, from the link-local address range: 169.254.0.0/16 except for 169.254.0.0/24 and
|
||||
169.254.255.0/24. This setting may be useful if the device should always have the same address
|
||||
as long as there is no address conflict. When unset, a random address will be automatically
|
||||
selected. Defaults to unset.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -6,3 +6,4 @@ Name=veth99
|
||||
DHCP=ipv4
|
||||
LinkLocalAddressing=yes
|
||||
IPv6AcceptRA=no
|
||||
IPv4LLStartAddress=169.254.133.11
|
||||
|
@ -4570,7 +4570,7 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
||||
output = check_output('ip -4 address show dev veth99')
|
||||
print(output)
|
||||
self.assertNotIn('192.168.5.', output)
|
||||
self.assertRegex(output, r'inet 169\.254\.\d+\.\d+/16 metric 2048 brd 169\.254\.255\.255 scope link')
|
||||
self.assertIn('inet 169.254.133.11/16 metric 2048 brd 169.254.255.255 scope link', output)
|
||||
|
||||
start_dnsmasq()
|
||||
print('Wait for a DHCP lease to be acquired and the IPv4LL address to be dropped')
|
||||
@ -4587,12 +4587,12 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
||||
stop_dnsmasq()
|
||||
print('Wait for the DHCP lease to be expired and an IPv4LL address to be acquired')
|
||||
self.wait_address_dropped('veth99', r'inet 192\.168\.5\.\d+/24 metric 1024 brd 192\.168\.5\.255 scope global dynamic', ipv='-4', timeout_sec=130)
|
||||
self.wait_address('veth99', r'inet 169\.254\.\d+\.\d+/16 metric 2048 brd 169\.254\.255\.255 scope link', scope='link', ipv='-4')
|
||||
self.wait_address('veth99', r'inet 169\.254\.133\.11/16 metric 2048 brd 169\.254\.255\.255 scope link', scope='link', ipv='-4')
|
||||
|
||||
output = check_output('ip -4 address show dev veth99')
|
||||
print(output)
|
||||
self.assertNotIn('192.168.5.', output)
|
||||
self.assertRegex(output, r'inet 169\.254\.\d+\.\d+/16 metric 2048 brd 169\.254\.255\.255 scope link')
|
||||
self.assertIn('inet 169.254.133.11/16 metric 2048 brd 169.254.255.255 scope link', output)
|
||||
|
||||
def test_dhcp_client_use_dns(self):
|
||||
def check(self, ipv4, ipv6):
|
||||
|
Loading…
Reference in New Issue
Block a user