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:
parent
ffb834cb87
commit
3bac5fe6c9
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user