mirror of
https://github.com/systemd/systemd.git
synced 2025-01-10 05:18:17 +03:00
network/address: several cleanups for config_parse_address()
- make it accept an empty string, - use config_parse_in_addr_prefix(), - move null address checker to address_section_verify(). No functional change, just refactoring.
This commit is contained in:
parent
5d15c7b19c
commit
1cbc8d9168
@ -3,8 +3,10 @@
|
||||
#include <net/if.h>
|
||||
#include <net/if_arp.h>
|
||||
|
||||
#include "af-list.h"
|
||||
#include "alloc-util.h"
|
||||
#include "firewall-util.h"
|
||||
#include "in-addr-prefix-util.h"
|
||||
#include "logarithm.h"
|
||||
#include "memory-util.h"
|
||||
#include "netlink-util.h"
|
||||
@ -2076,53 +2078,33 @@ static int config_parse_address(
|
||||
void *userdata) {
|
||||
|
||||
Address *address = ASSERT_PTR(userdata);
|
||||
union in_addr_union buffer;
|
||||
unsigned char prefixlen;
|
||||
int r, f;
|
||||
union in_addr_union *a = ASSERT_PTR(data);
|
||||
struct in_addr_prefix prefix;
|
||||
int r;
|
||||
|
||||
assert(rvalue);
|
||||
|
||||
/* Address=address/prefixlen */
|
||||
r = in_addr_prefix_from_string_auto_full(rvalue, PREFIXLEN_REFUSE, &f, &buffer, &prefixlen);
|
||||
if (r == -ENOANO) {
|
||||
r = in_addr_prefix_from_string_auto(rvalue, &f, &buffer, &prefixlen);
|
||||
if (r >= 0)
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Address '%s' is specified without prefix length. Assuming the prefix length is %u. "
|
||||
"Please specify the prefix length explicitly.", rvalue, prefixlen);
|
||||
if (isempty(rvalue)) {
|
||||
/* When an empty string is assigned, clear both Address= and Peer=. */
|
||||
address->family = AF_UNSPEC;
|
||||
address->prefixlen = 0;
|
||||
address->in_addr = IN_ADDR_NULL;
|
||||
address->in_addr_peer = IN_ADDR_NULL;
|
||||
return 1;
|
||||
}
|
||||
if (r < 0)
|
||||
return log_syntax_parse_error(unit, filename, line, r, lvalue, rvalue);
|
||||
|
||||
if (address->family != AF_UNSPEC && f != address->family) {
|
||||
r = config_parse_in_addr_prefix(unit, filename, line, section, section_line, lvalue, /* ltype = */ true, rvalue, &prefix, /* userdata = */ NULL);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
if (address->family != AF_UNSPEC && prefix.family != address->family) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0, "Address is incompatible, ignoring assignment: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (in_addr_is_null(f, &buffer)) {
|
||||
/* Will use address from address pool. Note that for ipv6 case, prefix of the address
|
||||
* pool is 8, but 40 bit is used by the global ID and 16 bit by the subnet ID. So,
|
||||
* let's limit the prefix length to 64 or larger. See RFC4193. */
|
||||
if ((f == AF_INET && prefixlen < 8) ||
|
||||
(f == AF_INET6 && prefixlen < 64)) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"Null address with invalid prefixlen='%u', ignoring assignment: %s",
|
||||
prefixlen, rvalue);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
address->family = f;
|
||||
address->prefixlen = prefixlen;
|
||||
|
||||
if (streq_ptr(lvalue, "Address")) {
|
||||
address->in_addr = buffer;
|
||||
address->requested_as_null = !in_addr_is_set(address->family, &address->in_addr);
|
||||
} else if (streq_ptr(lvalue, "Peer"))
|
||||
address->in_addr_peer = buffer;
|
||||
else
|
||||
assert_not_reached();
|
||||
|
||||
address->family = prefix.family;
|
||||
address->prefixlen = prefix.prefixlen;
|
||||
*a = prefix.address;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -2263,7 +2245,8 @@ int config_parse_address_section(
|
||||
void *userdata) {
|
||||
|
||||
static const ConfigSectionParser table[_ADDRESS_CONF_PARSER_MAX] = {
|
||||
[ADDRESS_ADDRESS] = { .parser = config_parse_address, .ltype = 0, .offset = 0, },
|
||||
[ADDRESS_ADDRESS] = { .parser = config_parse_address, .ltype = 0, .offset = offsetof(Address, in_addr), },
|
||||
[ADDRESS_PEER] = { .parser = config_parse_address, .ltype = 0, .offset = offsetof(Address, in_addr_peer), },
|
||||
[ADDRESS_BROADCAST] = { .parser = config_parse_broadcast, .ltype = 0, .offset = 0, },
|
||||
[ADDRESS_LABEL] = { .parser = config_parse_address_label, .ltype = 0, .offset = offsetof(Address, label), },
|
||||
[ADDRESS_PREFERRED_LIFETIME] = { .parser = config_parse_address_lifetime, .ltype = 0, .offset = offsetof(Address, lifetime_preferred_usec), },
|
||||
@ -2366,11 +2349,22 @@ int address_section_verify(Address *address) {
|
||||
|
||||
if (address->family == AF_UNSPEC)
|
||||
return log_address_section(address, "Address section without Address= field was configured.");
|
||||
assert(IN_SET(address->family, AF_INET, AF_INET6));
|
||||
|
||||
if (address->family == AF_INET6 && !socket_ipv6_is_supported())
|
||||
return log_address_section(address, "An IPv6 address was configured, but the kernel does not support IPv6.");
|
||||
|
||||
assert(IN_SET(address->family, AF_INET, AF_INET6));
|
||||
if (in_addr_is_null(address->family, &address->in_addr)) {
|
||||
/* Will use address from address pool. Note that for ipv6 case, prefix of the address
|
||||
* pool is 8, but 40 bit is used by the global ID and 16 bit by the subnet ID. So,
|
||||
* let's limit the prefix length to 64 or larger. See RFC4193. */
|
||||
unsigned min_prefixlen = address->family == AF_INET ? 8 : 64;
|
||||
if (address->prefixlen < min_prefixlen)
|
||||
return log_address_section(address, "Prefix length for %s null address must be equal or larger than %u.",
|
||||
af_to_ipv4_ipv6(address->family), min_prefixlen);
|
||||
|
||||
address->requested_as_null = !in_addr_is_set(address->family, &address->in_addr);
|
||||
}
|
||||
|
||||
address_section_adjust_broadcast(address);
|
||||
|
||||
|
@ -161,6 +161,7 @@ void link_mark_addresses(Link *link, NetworkConfigSource source);
|
||||
|
||||
typedef enum AddressConfParserType {
|
||||
ADDRESS_ADDRESS,
|
||||
ADDRESS_PEER,
|
||||
ADDRESS_BROADCAST,
|
||||
ADDRESS_LABEL,
|
||||
ADDRESS_PREFERRED_LIFETIME,
|
||||
|
@ -157,7 +157,7 @@ Network.KeepConfiguration, config_parse_keep_configuration,
|
||||
Network.IPv6SendRA, config_parse_router_prefix_delegation, 0, offsetof(Network, router_prefix_delegation)
|
||||
Network.DHCPPrefixDelegation, config_parse_tristate, 0, offsetof(Network, dhcp_pd)
|
||||
Address.Address, config_parse_address_section, ADDRESS_ADDRESS, 0
|
||||
Address.Peer, config_parse_address_section, ADDRESS_ADDRESS, 0
|
||||
Address.Peer, config_parse_address_section, ADDRESS_PEER, 0
|
||||
Address.Broadcast, config_parse_address_section, ADDRESS_BROADCAST, 0
|
||||
Address.Label, config_parse_address_section, ADDRESS_LABEL, 0
|
||||
Address.PreferredLifetime, config_parse_address_section, ADDRESS_PREFERRED_LIFETIME, 0
|
||||
|
Loading…
Reference in New Issue
Block a user