]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: address-generation: modernize config_parse_address_generation_type()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 1 Oct 2021 12:23:56 +0000 (21:23 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 6 Oct 2021 16:14:51 +0000 (01:14 +0900)
- drop unused _NONE type,
- rename IPv6Token::prefix -> IPv6Token::address,
- clear unused part of IPv6Token::address,
- use Set, instead of OrderedSet.

src/network/networkd-address-generation.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-network.h

index 7a897bf06bc8cf2514a687cd752d345a9e467b95..3b807dbcfa7009bdfdcc2cbd1aa66bdd0260f435 100644 (file)
 
 #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 {
-        IPV6_TOKEN_ADDRESS_GENERATION_NONE,
-        IPV6_TOKEN_ADDRESS_GENERATION_STATIC,
-        IPV6_TOKEN_ADDRESS_GENERATION_PREFIXSTABLE,
-        _IPV6_TOKEN_ADDRESS_GENERATION_MAX,
-        _IPV6_TOKEN_ADDRESS_GENERATION_INVALID = -EINVAL,
-} IPv6TokenAddressGeneration;
+typedef enum AddressGenerationType {
+        ADDRESS_GENERATION_STATIC,
+        ADDRESS_GENERATION_PREFIXSTABLE,
+        _ADDRESS_GENERATION_TYPE_MAX,
+        _ADDRESS_GENERATION_TYPE_INVALID = -EINVAL,
+} AddressGenerationType;
 
 typedef struct IPv6Token {
-        IPv6TokenAddressGeneration address_generation_type;
-        struct in6_addr prefix;
+        AddressGenerationType type;
+        struct in6_addr address;
 } IPv6Token;
 
 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)
                 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;
 
-                if (j->address_generation_type == IPV6_TOKEN_ADDRESS_GENERATION_PREFIXSTABLE
-                    && (in6_addr_is_null(&j->prefix) || in6_addr_equal(&j->prefix, &masked))) {
+                if (j->type == ADDRESS_GENERATION_PREFIXSTABLE
+                    && (in6_addr_is_null(&j->address) || in6_addr_equal(&j->address, &masked))) {
                         struct in6_addr addr;
 
                         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)
                                 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);
                         if (!new_address)
                                 return log_oom();
 
                         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) {
@@ -223,35 +222,19 @@ int ndisc_router_generate_addresses(Link *link, struct in6_addr *prefix, uint8_t
         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) {
-        siphash24_compress(&p->address_generation_type, sizeof(p->address_generation_type), state);
-        siphash24_compress(&p->prefix, sizeof(p->prefix), state);
+        siphash24_compress(&p->type, sizeof(p->type), state);
+        siphash24_compress(&p->address, sizeof(p->address), state);
 }
 
 static int ipv6_token_compare_func(const IPv6Token *a, const IPv6Token *b) {
         int r;
 
-        r = CMP(a->address_generation_type, b->address_generation_type);
+        r = CMP(a->type, b->type);
         if (r != 0)
                 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(
@@ -261,6 +244,25 @@ DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
                 ipv6_token_compare_func,
                 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(
                 const char *unit,
                 const char *filename,
@@ -273,9 +275,9 @@ int config_parse_address_generation_type(
                 void *data,
                 void *userdata) {
 
-        _cleanup_free_ IPv6Token *token = NULL;
-        union in_addr_union buffer;
-        Network *network = data;
+        union in_addr_union buffer = {};
+        AddressGenerationType type;
+        Set **tokens = data;
         const char *p;
         int r;
 
@@ -285,16 +287,13 @@ int config_parse_address_generation_type(
         assert(data);
 
         if (isempty(rvalue)) {
-                network->ipv6_tokens = ordered_set_free(network->ipv6_tokens);
+                *tokens = set_free(*tokens);
                 return 0;
         }
 
-        r = ipv6token_new(&token);
-        if (r < 0)
-                return log_oom();
-
         if ((p = startswith(rvalue, "prefixstable"))) {
-                token->address_generation_type = IPV6_TOKEN_ADDRESS_GENERATION_PREFIXSTABLE;
+                type = ADDRESS_GENERATION_PREFIXSTABLE;
+
                 if (*p == ':')
                         p++;
                 else if (*p == '\0')
@@ -305,8 +304,10 @@ int config_parse_address_generation_type(
                                    lvalue, rvalue);
                         return 0;
                 }
+
         } else {
-                token->address_generation_type = IPV6_TOKEN_ADDRESS_GENERATION_STATIC;
+                type = ADDRESS_GENERATION_STATIC;
+
                 p = startswith(rvalue, "static:");
                 if (!p)
                         p = rvalue;
@@ -320,27 +321,33 @@ int config_parse_address_generation_type(
                                    lvalue, rvalue);
                         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,
                                    "IPv6 address in %s= cannot be the ANY address, ignoring assignment: %s",
                                    lvalue, rvalue);
                         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);
-        if (r == -ENOMEM)
+        r = ipv6_token_add(tokens, type, &buffer.in6);
+        if (r < 0)
                 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;
 }
index 6794ac40dbaa717367274b50967f80b1dd4b54d2..9aa253e1d9441b466cdf681bc7df781f83359bd5 100644 (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.IPv4LLRoute,                         config_parse_bool,                                        0,                             offsetof(Network, ipv4ll_route)
 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.EmitLLDP,                            config_parse_lldp_multicast_mode,                         0,                             offsetof(Network, lldp_multicast_mode)
 Network.Address,                             config_parse_address,                                     0,                             0
index 7611476ad664cb5ef1f9a6b0e31b83aa61e45541..98a9cccc03dd0bbd202207716f24f30fa874c60b 100644 (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_server_send_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_vendor_options);
+        set_free(network->ndisc_tokens);
 
         return mfree(network);
 }
index fb896598a85c72e09e893127fe2b2d64791d6eb4..81b7797e6ed0757d8ecd91537c198dbfd1932751 100644 (file)
@@ -321,7 +321,7 @@ struct Network {
         Set *ndisc_allow_listed_prefix;
         Set *ndisc_deny_listed_route_prefix;
         Set *ndisc_allow_listed_route_prefix;
-        OrderedSet *ipv6_tokens;
+        Set *ndisc_tokens;
 
         /* LLDP support */
         LLDPMode lldp_mode; /* LLDP reception */