1
0
mirror of https://github.com/systemd/systemd.git synced 2024-11-01 00:51:24 +03:00

network: address-generation: modernize config_parse_address_generation_type()

- drop unused _NONE type,
- rename IPv6Token::prefix -> IPv6Token::address,
- clear unused part of IPv6Token::address,
- use Set, instead of OrderedSet.
This commit is contained in:
Yu Watanabe 2021-10-01 21:23:56 +09:00
parent ffb834cb87
commit 3bac5fe6c9
4 changed files with 67 additions and 60 deletions

View File

@ -22,17 +22,16 @@
#define NDISC_APP_ID SD_ID128_MAKE(13,ac,81,a7,d5,3f,49,78,92,79,5d,0c,29,3a,bc,7e) #define NDISC_APP_ID SD_ID128_MAKE(13,ac,81,a7,d5,3f,49,78,92,79,5d,0c,29,3a,bc,7e)
typedef enum IPv6TokenAddressGeneration { typedef enum AddressGenerationType {
IPV6_TOKEN_ADDRESS_GENERATION_NONE, ADDRESS_GENERATION_STATIC,
IPV6_TOKEN_ADDRESS_GENERATION_STATIC, ADDRESS_GENERATION_PREFIXSTABLE,
IPV6_TOKEN_ADDRESS_GENERATION_PREFIXSTABLE, _ADDRESS_GENERATION_TYPE_MAX,
_IPV6_TOKEN_ADDRESS_GENERATION_MAX, _ADDRESS_GENERATION_TYPE_INVALID = -EINVAL,
_IPV6_TOKEN_ADDRESS_GENERATION_INVALID = -EINVAL, } AddressGenerationType;
} IPv6TokenAddressGeneration;
typedef struct IPv6Token { typedef struct IPv6Token {
IPv6TokenAddressGeneration address_generation_type; AddressGenerationType type;
struct in6_addr prefix; struct in6_addr address;
} IPv6Token; } IPv6Token;
void generate_eui64_address(const Link *link, const struct in6_addr *prefix, struct in6_addr *ret) { void generate_eui64_address(const Link *link, const struct in6_addr *prefix, struct in6_addr *ret) {
@ -169,11 +168,11 @@ int ndisc_router_generate_addresses(Link *link, struct in6_addr *prefix, uint8_t
if (!addresses) if (!addresses)
return log_oom(); return log_oom();
ORDERED_SET_FOREACH(j, link->network->ipv6_tokens) { SET_FOREACH(j, link->network->ndisc_tokens) {
_cleanup_free_ struct in6_addr *new_address = NULL; _cleanup_free_ struct in6_addr *new_address = NULL;
if (j->address_generation_type == IPV6_TOKEN_ADDRESS_GENERATION_PREFIXSTABLE if (j->type == ADDRESS_GENERATION_PREFIXSTABLE
&& (in6_addr_is_null(&j->prefix) || in6_addr_equal(&j->prefix, &masked))) { && (in6_addr_is_null(&j->address) || in6_addr_equal(&j->address, &masked))) {
struct in6_addr addr; struct in6_addr addr;
if (generate_stable_private_address(link, &NDISC_APP_ID, &masked, &addr) < 0) if (generate_stable_private_address(link, &NDISC_APP_ID, &masked, &addr) < 0)
@ -183,13 +182,13 @@ int ndisc_router_generate_addresses(Link *link, struct in6_addr *prefix, uint8_t
if (!new_address) if (!new_address)
return log_oom(); return log_oom();
} else if (j->address_generation_type == IPV6_TOKEN_ADDRESS_GENERATION_STATIC) { } else if (j->type == ADDRESS_GENERATION_STATIC) {
new_address = new(struct in6_addr, 1); new_address = new(struct in6_addr, 1);
if (!new_address) if (!new_address)
return log_oom(); return log_oom();
memcpy(new_address->s6_addr, masked.s6_addr, 8); memcpy(new_address->s6_addr, masked.s6_addr, 8);
memcpy(new_address->s6_addr + 8, j->prefix.s6_addr + 8, 8); memcpy(new_address->s6_addr + 8, j->address.s6_addr + 8, 8);
} }
if (new_address) { if (new_address) {
@ -223,35 +222,19 @@ int ndisc_router_generate_addresses(Link *link, struct in6_addr *prefix, uint8_t
return 0; return 0;
} }
static int ipv6token_new(IPv6Token **ret) {
IPv6Token *p;
p = new(IPv6Token, 1);
if (!p)
return -ENOMEM;
*p = (IPv6Token) {
.address_generation_type = IPV6_TOKEN_ADDRESS_GENERATION_NONE,
};
*ret = TAKE_PTR(p);
return 0;
}
static void ipv6_token_hash_func(const IPv6Token *p, struct siphash *state) { static void ipv6_token_hash_func(const IPv6Token *p, struct siphash *state) {
siphash24_compress(&p->address_generation_type, sizeof(p->address_generation_type), state); siphash24_compress(&p->type, sizeof(p->type), state);
siphash24_compress(&p->prefix, sizeof(p->prefix), state); siphash24_compress(&p->address, sizeof(p->address), state);
} }
static int ipv6_token_compare_func(const IPv6Token *a, const IPv6Token *b) { static int ipv6_token_compare_func(const IPv6Token *a, const IPv6Token *b) {
int r; int r;
r = CMP(a->address_generation_type, b->address_generation_type); r = CMP(a->type, b->type);
if (r != 0) if (r != 0)
return r; return r;
return memcmp(&a->prefix, &b->prefix, sizeof(struct in6_addr)); return memcmp(&a->address, &b->address, sizeof(struct in6_addr));
} }
DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR( DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
@ -261,6 +244,25 @@ DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
ipv6_token_compare_func, ipv6_token_compare_func,
free); free);
static int ipv6_token_add(Set **tokens, AddressGenerationType type, const struct in6_addr *addr) {
IPv6Token *p;
assert(tokens);
assert(type >= 0 && type < _ADDRESS_GENERATION_TYPE_MAX);
assert(addr);
p = new(IPv6Token, 1);
if (!p)
return -ENOMEM;
*p = (IPv6Token) {
.type = type,
.address = *addr,
};
return set_ensure_consume(tokens, &ipv6_token_hash_ops, p);
}
int config_parse_address_generation_type( int config_parse_address_generation_type(
const char *unit, const char *unit,
const char *filename, const char *filename,
@ -273,9 +275,9 @@ int config_parse_address_generation_type(
void *data, void *data,
void *userdata) { void *userdata) {
_cleanup_free_ IPv6Token *token = NULL; union in_addr_union buffer = {};
union in_addr_union buffer; AddressGenerationType type;
Network *network = data; Set **tokens = data;
const char *p; const char *p;
int r; int r;
@ -285,16 +287,13 @@ int config_parse_address_generation_type(
assert(data); assert(data);
if (isempty(rvalue)) { if (isempty(rvalue)) {
network->ipv6_tokens = ordered_set_free(network->ipv6_tokens); *tokens = set_free(*tokens);
return 0; return 0;
} }
r = ipv6token_new(&token);
if (r < 0)
return log_oom();
if ((p = startswith(rvalue, "prefixstable"))) { if ((p = startswith(rvalue, "prefixstable"))) {
token->address_generation_type = IPV6_TOKEN_ADDRESS_GENERATION_PREFIXSTABLE; type = ADDRESS_GENERATION_PREFIXSTABLE;
if (*p == ':') if (*p == ':')
p++; p++;
else if (*p == '\0') else if (*p == '\0')
@ -305,8 +304,10 @@ int config_parse_address_generation_type(
lvalue, rvalue); lvalue, rvalue);
return 0; return 0;
} }
} else { } else {
token->address_generation_type = IPV6_TOKEN_ADDRESS_GENERATION_STATIC; type = ADDRESS_GENERATION_STATIC;
p = startswith(rvalue, "static:"); p = startswith(rvalue, "static:");
if (!p) if (!p)
p = rvalue; p = rvalue;
@ -320,27 +321,33 @@ int config_parse_address_generation_type(
lvalue, rvalue); lvalue, rvalue);
return 0; return 0;
} }
if (token->address_generation_type == IPV6_TOKEN_ADDRESS_GENERATION_STATIC && }
in_addr_is_null(AF_INET6, &buffer)) {
switch (type) {
case ADDRESS_GENERATION_STATIC:
/* Only last 64 bits are used. */
memzero(buffer.in6.s6_addr, 8);
if (in6_addr_is_null(&buffer.in6)) {
log_syntax(unit, LOG_WARNING, filename, line, 0, log_syntax(unit, LOG_WARNING, filename, line, 0,
"IPv6 address in %s= cannot be the ANY address, ignoring assignment: %s", "IPv6 address in %s= cannot be the ANY address, ignoring assignment: %s",
lvalue, rvalue); lvalue, rvalue);
return 0; return 0;
} }
token->prefix = buffer.in6; break;
case ADDRESS_GENERATION_PREFIXSTABLE:
/* At most, the initial 64 bits are used. */
(void) in6_addr_mask(&buffer.in6, 64);
break;
default:
assert_not_reached();
} }
r = ordered_set_ensure_put(&network->ipv6_tokens, &ipv6_token_hash_ops, token); r = ipv6_token_add(tokens, type, &buffer.in6);
if (r == -ENOMEM) if (r < 0)
return log_oom(); return log_oom();
if (r == -EEXIST)
log_syntax(unit, LOG_DEBUG, filename, line, r,
"IPv6 token '%s' is duplicated, ignoring: %m", rvalue);
else if (r < 0)
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to store IPv6 token '%s', ignoring: %m", rvalue);
else
TAKE_PTR(token);
return 0; return 0;
} }

View File

@ -104,7 +104,7 @@ Network.IPv6LinkLocalAddressGenerationMode, config_parse_ipv6_link_local_addres
Network.IPv6StableSecretAddress, config_parse_in_addr_non_null, AF_INET6, offsetof(Network, ipv6ll_stable_secret) Network.IPv6StableSecretAddress, config_parse_in_addr_non_null, AF_INET6, offsetof(Network, ipv6ll_stable_secret)
Network.IPv4LLRoute, config_parse_bool, 0, offsetof(Network, ipv4ll_route) Network.IPv4LLRoute, config_parse_bool, 0, offsetof(Network, ipv4ll_route)
Network.DefaultRouteOnDevice, config_parse_bool, 0, offsetof(Network, default_route_on_device) Network.DefaultRouteOnDevice, config_parse_bool, 0, offsetof(Network, default_route_on_device)
Network.IPv6Token, config_parse_address_generation_type, 0, 0 Network.IPv6Token, config_parse_address_generation_type, 0, offsetof(Network, ndisc_tokens)
Network.LLDP, config_parse_lldp_mode, 0, offsetof(Network, lldp_mode) Network.LLDP, config_parse_lldp_mode, 0, offsetof(Network, lldp_mode)
Network.EmitLLDP, config_parse_lldp_multicast_mode, 0, offsetof(Network, lldp_multicast_mode) Network.EmitLLDP, config_parse_lldp_multicast_mode, 0, offsetof(Network, lldp_multicast_mode)
Network.Address, config_parse_address, 0, 0 Network.Address, config_parse_address, 0, 0

View File

@ -706,9 +706,9 @@ static Network *network_free(Network *network) {
ordered_hashmap_free(network->dhcp_client_send_vendor_options); ordered_hashmap_free(network->dhcp_client_send_vendor_options);
ordered_hashmap_free(network->dhcp_server_send_options); ordered_hashmap_free(network->dhcp_server_send_options);
ordered_hashmap_free(network->dhcp_server_send_vendor_options); ordered_hashmap_free(network->dhcp_server_send_vendor_options);
ordered_set_free(network->ipv6_tokens);
ordered_hashmap_free(network->dhcp6_client_send_options); ordered_hashmap_free(network->dhcp6_client_send_options);
ordered_hashmap_free(network->dhcp6_client_send_vendor_options); ordered_hashmap_free(network->dhcp6_client_send_vendor_options);
set_free(network->ndisc_tokens);
return mfree(network); return mfree(network);
} }

View File

@ -321,7 +321,7 @@ struct Network {
Set *ndisc_allow_listed_prefix; Set *ndisc_allow_listed_prefix;
Set *ndisc_deny_listed_route_prefix; Set *ndisc_deny_listed_route_prefix;
Set *ndisc_allow_listed_route_prefix; Set *ndisc_allow_listed_route_prefix;
OrderedSet *ipv6_tokens; Set *ndisc_tokens;
/* LLDP support */ /* LLDP support */
LLDPMode lldp_mode; /* LLDP reception */ LLDPMode lldp_mode; /* LLDP reception */