]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: radv: make conf parsers not set values into sd_radv_prefix/sd_radv_route_prefix
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 27 Sep 2021 12:07:27 +0000 (21:07 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 11 Oct 2021 18:10:30 +0000 (03:10 +0900)
Preparation for later commits.

src/network/networkd-network-gperf.gperf
src/network/networkd-radv.c
src/network/networkd-radv.h

index b670038d2ae43d9ce5451b45c1eb8aa3f12ccd54..a207e374d52b5ae2f07c01fd004ea429e0d598f1 100644 (file)
@@ -342,11 +342,11 @@ IPv6SendRA.Domains,                          config_parse_radv_search_domains,
 IPv6SendRA.DNSLifetimeSec,                   config_parse_sec,                                         0,                             offsetof(Network, router_dns_lifetime_usec)
 IPv6SendRA.UplinkInterface,                  config_parse_uplink,                                      0,                             0
 IPv6Prefix.Prefix,                           config_parse_prefix,                                      0,                             0
-IPv6Prefix.OnLink,                           config_parse_prefix_flags,                                0,                             0
-IPv6Prefix.AddressAutoconfiguration,         config_parse_prefix_flags,                                0,                             0
+IPv6Prefix.OnLink,                           config_parse_prefix_boolean,                              0,                             0
+IPv6Prefix.AddressAutoconfiguration,         config_parse_prefix_boolean,                              0,                             0
 IPv6Prefix.ValidLifetimeSec,                 config_parse_prefix_lifetime,                             0,                             0
 IPv6Prefix.PreferredLifetimeSec,             config_parse_prefix_lifetime,                             0,                             0
-IPv6Prefix.Assign,                           config_parse_prefix_assign,                               0,                             0
+IPv6Prefix.Assign,                           config_parse_prefix_boolean,                              0,                             0
 IPv6Prefix.RouteMetric,                      config_parse_prefix_metric,                               0,                             0
 IPv6Prefix.Token,                            config_parse_prefix_token,                                0,                             0
 IPv6RoutePrefix.Route,                       config_parse_route_prefix,                                0,                             0
index 471f6d78e80df58eb9c523e1c73df19fb8a4f144..5475ed787ec7f9a12b2ca06f852875c5aa72f6af 100644 (file)
@@ -68,7 +68,6 @@ Prefix *prefix_free(Prefix *prefix) {
         }
 
         network_config_section_free(prefix->section);
-        sd_radv_prefix_unref(prefix->radv_prefix);
         set_free(prefix->tokens);
 
         return mfree(prefix);
@@ -76,21 +75,6 @@ Prefix *prefix_free(Prefix *prefix) {
 
 DEFINE_NETWORK_SECTION_FUNCTIONS(Prefix, prefix_free);
 
-static int prefix_new(Prefix **ret) {
-        _cleanup_(prefix_freep) Prefix *prefix = NULL;
-
-        prefix = new0(Prefix, 1);
-        if (!prefix)
-                return -ENOMEM;
-
-        if (sd_radv_prefix_new(&prefix->radv_prefix) < 0)
-                return -ENOMEM;
-
-        *ret = TAKE_PTR(prefix);
-
-        return 0;
-}
-
 static int prefix_new_static(Network *network, const char *filename, unsigned section_line, Prefix **ret) {
         _cleanup_(network_config_section_freep) NetworkConfigSection *n = NULL;
         _cleanup_(prefix_freep) Prefix *prefix = NULL;
@@ -111,19 +95,25 @@ static int prefix_new_static(Network *network, const char *filename, unsigned se
                 return 0;
         }
 
-        r = prefix_new(&prefix);
-        if (r < 0)
-                return r;
+        prefix = new(Prefix, 1);
+        if (!prefix)
+                return -ENOMEM;
+
+        *prefix = (Prefix) {
+                .network = network,
+                .section = TAKE_PTR(n),
 
-        prefix->network = network;
-        prefix->section = TAKE_PTR(n);
+                .preferred_lifetime = 7 * USEC_PER_DAY,
+                .valid_lifetime = 30 * USEC_PER_DAY,
+                .onlink = true,
+                .address_auto_configuration = true,
+        };
 
         r = hashmap_ensure_put(&network->prefixes_by_section, &network_config_hash_ops, prefix->section, prefix);
         if (r < 0)
                 return r;
 
         *ret = TAKE_PTR(prefix);
-
         return 0;
 }
 
@@ -137,28 +127,12 @@ RoutePrefix *route_prefix_free(RoutePrefix *prefix) {
         }
 
         network_config_section_free(prefix->section);
-        sd_radv_route_prefix_unref(prefix->radv_route_prefix);
 
         return mfree(prefix);
 }
 
 DEFINE_NETWORK_SECTION_FUNCTIONS(RoutePrefix, route_prefix_free);
 
-static int route_prefix_new(RoutePrefix **ret) {
-        _cleanup_(route_prefix_freep) RoutePrefix *prefix = NULL;
-
-        prefix = new0(RoutePrefix, 1);
-        if (!prefix)
-                return -ENOMEM;
-
-        if (sd_radv_route_prefix_new(&prefix->radv_route_prefix) < 0)
-                return -ENOMEM;
-
-        *ret = TAKE_PTR(prefix);
-
-        return 0;
-}
-
 static int route_prefix_new_static(Network *network, const char *filename, unsigned section_line, RoutePrefix **ret) {
         _cleanup_(network_config_section_freep) NetworkConfigSection *n = NULL;
         _cleanup_(route_prefix_freep) RoutePrefix *prefix = NULL;
@@ -179,19 +153,22 @@ static int route_prefix_new_static(Network *network, const char *filename, unsig
                 return 0;
         }
 
-        r = route_prefix_new(&prefix);
-        if (r < 0)
-                return r;
+        prefix = new(RoutePrefix, 1);
+        if (!prefix)
+                return -ENOMEM;
+
+        *prefix = (RoutePrefix) {
+                .network = network,
+                .section = TAKE_PTR(n),
 
-        prefix->network = network;
-        prefix->section = TAKE_PTR(n);
+                .lifetime = 7 * USEC_PER_DAY,
+        };
 
         r = hashmap_ensure_put(&network->route_prefixes_by_section, &network_config_hash_ops, prefix->section, prefix);
         if (r < 0)
                 return r;
 
         *ret = TAKE_PTR(prefix);
-
         return 0;
 }
 
@@ -206,28 +183,23 @@ int link_request_radv_addresses(Link *link) {
 
         HASHMAP_FOREACH(p, link->network->prefixes_by_section) {
                 _cleanup_set_free_ Set *addresses = NULL;
-                struct in6_addr prefix, *a;
-                uint8_t prefixlen;
+                struct in6_addr *a;
 
                 if (!p->assign)
                         continue;
 
-                r = sd_radv_prefix_get_prefix(p->radv_prefix, &prefix, &prefixlen);
-                if (r < 0)
-                        return r;
-
                 /* radv_generate_addresses() below requires the prefix length <= 64. */
-                if (prefixlen > 64) {
+                if (p->prefixlen > 64) {
                         _cleanup_free_ char *str = NULL;
 
-                        (void) in6_addr_prefix_to_string(&prefix, prefixlen, &str);
+                        (void) in6_addr_prefix_to_string(&p->prefix, p->prefixlen, &str);
                         log_link_debug(link,
                                        "Prefix is longer than 64, refusing to assign an address in %s.",
                                        strna(str));
                         continue;
                 }
 
-                r = radv_generate_addresses(link, p->tokens, &prefix, prefixlen, &addresses);
+                r = radv_generate_addresses(link, p->tokens, &p->prefix, p->prefixlen, &addresses);
                 if (r < 0)
                         return r;
 
@@ -241,7 +213,7 @@ int link_request_radv_addresses(Link *link) {
                         address->source = NETWORK_CONFIG_SOURCE_STATIC;
                         address->family = AF_INET6;
                         address->in_addr.in6 = *a;
-                        address->prefixlen = prefixlen;
+                        address->prefixlen = p->prefixlen;
                         address->route_metric = p->route_metric;
 
                         r = link_request_static_address(link, TAKE_PTR(address), true);
@@ -253,6 +225,77 @@ int link_request_radv_addresses(Link *link) {
         return 0;
 }
 
+static uint32_t usec_to_lifetime(usec_t usec) {
+        uint64_t t;
+
+        if (usec == USEC_INFINITY)
+                return UINT32_MAX;
+
+        t = DIV_ROUND_UP(usec, USEC_PER_SEC);
+        if (t >= UINT32_MAX)
+                return UINT32_MAX;
+
+        return (uint32_t) t;
+}
+
+static int radv_set_prefix(Link *link, Prefix *prefix) {
+        _cleanup_(sd_radv_prefix_unrefp) sd_radv_prefix *p = NULL;
+        int r;
+
+        assert(link);
+        assert(link->radv);
+        assert(prefix);
+
+        r = sd_radv_prefix_new(&p);
+        if (r < 0)
+                return r;
+
+        r = sd_radv_prefix_set_prefix(p, &prefix->prefix, prefix->prefixlen);
+        if (r < 0)
+                return r;
+
+        r = sd_radv_prefix_set_preferred_lifetime(p, usec_to_lifetime(prefix->preferred_lifetime));
+        if (r < 0)
+                return r;
+
+        r = sd_radv_prefix_set_valid_lifetime(p, usec_to_lifetime(prefix->valid_lifetime));
+        if (r < 0)
+                return r;
+
+        r = sd_radv_prefix_set_onlink(p, prefix->onlink);
+        if (r < 0)
+                return r;
+
+        r = sd_radv_prefix_set_address_autoconfiguration(p, prefix->address_auto_configuration);
+        if (r < 0)
+                return r;
+
+        return sd_radv_add_prefix(link->radv, p, false);
+}
+
+static int radv_set_route_prefix(Link *link, RoutePrefix *prefix) {
+        _cleanup_(sd_radv_route_prefix_unrefp) sd_radv_route_prefix *p = NULL;
+        int r;
+
+        assert(link);
+        assert(link->radv);
+        assert(prefix);
+
+        r = sd_radv_route_prefix_new(&p);
+        if (r < 0)
+                return r;
+
+        r = sd_radv_route_prefix_set_prefix(p, &prefix->prefix, prefix->prefixlen);
+        if (r < 0)
+                return r;
+
+        r = sd_radv_route_prefix_set_lifetime(p, usec_to_lifetime(prefix->lifetime));
+        if (r < 0)
+                return r;
+
+        return sd_radv_add_route_prefix(link->radv, p, false);
+}
+
 static int network_get_ipv6_dns(Network *network, struct in6_addr **ret_addresses, size_t *ret_size) {
         _cleanup_free_ struct in6_addr *addresses = NULL;
         size_t n_addresses = 0;
@@ -455,22 +498,14 @@ static int radv_configure(Link *link) {
         }
 
         HASHMAP_FOREACH(p, link->network->prefixes_by_section) {
-                r = sd_radv_add_prefix(link->radv, p->radv_prefix, false);
-                if (r == -EEXIST)
-                        continue;
-                if (r == -ENOEXEC) {
-                        log_link_warning_errno(link, r, "[IPv6Prefix] section configured without Prefix= setting, ignoring section.");
-                        continue;
-                }
-                if (r < 0)
+                r = radv_set_prefix(link, p);
+                if (r < 0 && r != -EEXIST)
                         return r;
         }
 
         HASHMAP_FOREACH(q, link->network->route_prefixes_by_section) {
-                r = sd_radv_add_route_prefix(link->radv, q->radv_route_prefix, false);
-                if (r == -EEXIST)
-                        continue;
-                if (r < 0)
+                r = radv_set_route_prefix(link, q);
+                if (r < 0 && r != -EEXIST)
                         return r;
         }
 
@@ -675,40 +710,34 @@ int config_parse_prefix(
                 void *data,
                 void *userdata) {
 
-        Network *network = userdata;
         _cleanup_(prefix_free_or_set_invalidp) Prefix *p = NULL;
-        uint8_t prefixlen = 64;
-        union in_addr_union in6addr;
+        Network *network = userdata;
+        union in_addr_union a;
         int r;
 
         assert(filename);
         assert(section);
         assert(lvalue);
         assert(rvalue);
-        assert(data);
+        assert(userdata);
 
         r = prefix_new_static(network, filename, section_line, &p);
         if (r < 0)
                 return log_oom();
 
-        r = in_addr_prefix_from_string(rvalue, AF_INET6, &in6addr, &prefixlen);
-        if (r < 0) {
-                log_syntax(unit, LOG_WARNING, filename, line, r, "Prefix is invalid, ignoring assignment: %s", rvalue);
-                return 0;
-        }
-
-        r = sd_radv_prefix_set_prefix(p->radv_prefix, &in6addr.in6, prefixlen);
+        r = in_addr_prefix_from_string(rvalue, AF_INET6, &a, &p->prefixlen);
         if (r < 0) {
-                log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to set radv prefix, ignoring assignment: %s", rvalue);
+                log_syntax(unit, LOG_WARNING, filename, line, r,
+                           "Prefix is invalid, ignoring assignment: %s", rvalue);
                 return 0;
         }
+        p->prefix = a.in6;
 
-        p = NULL;
-
+        TAKE_PTR(p);
         return 0;
 }
 
-int config_parse_prefix_flags(
+int config_parse_prefix_boolean(
                 const char *unit,
                 const char *filename,
                 unsigned line,
@@ -720,15 +749,15 @@ int config_parse_prefix_flags(
                 void *data,
                 void *userdata) {
 
-        Network *network = userdata;
         _cleanup_(prefix_free_or_set_invalidp) Prefix *p = NULL;
+        Network *network = userdata;
         int r;
 
         assert(filename);
         assert(section);
         assert(lvalue);
         assert(rvalue);
-        assert(data);
+        assert(userdata);
 
         r = prefix_new_static(network, filename, section_line, &p);
         if (r < 0)
@@ -736,21 +765,21 @@ int config_parse_prefix_flags(
 
         r = parse_boolean(rvalue);
         if (r < 0) {
-                log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse %s=, ignoring assignment: %s", lvalue, rvalue);
+                log_syntax(unit, LOG_WARNING, filename, line, r,
+                           "Failed to parse %s=, ignoring assignment: %s", lvalue, rvalue);
                 return 0;
         }
 
         if (streq(lvalue, "OnLink"))
-                r = sd_radv_prefix_set_onlink(p->radv_prefix, r);
+                p->onlink = r;
         else if (streq(lvalue, "AddressAutoconfiguration"))
-                r = sd_radv_prefix_set_address_autoconfiguration(p->radv_prefix, r);
-        if (r < 0) {
-                log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to set %s=, ignoring assignment: %m", lvalue);
-                return 0;
-        }
-
-        p = NULL;
+                p->address_auto_configuration = r;
+        else if (streq(lvalue, "Assign"))
+                p->assign = r;
+        else
+                assert_not_reached();
 
+        TAKE_PTR(p);
         return 0;
 }
 
@@ -766,8 +795,8 @@ int config_parse_prefix_lifetime(
                 void *data,
                 void *userdata) {
 
-        Network *network = userdata;
         _cleanup_(prefix_free_or_set_invalidp) Prefix *p = NULL;
+        Network *network = userdata;
         usec_t usec;
         int r;
 
@@ -775,7 +804,7 @@ int config_parse_prefix_lifetime(
         assert(section);
         assert(lvalue);
         assert(rvalue);
-        assert(data);
+        assert(userdata);
 
         r = prefix_new_static(network, filename, section_line, &p);
         if (r < 0)
@@ -783,64 +812,25 @@ int config_parse_prefix_lifetime(
 
         r = parse_sec(rvalue, &usec);
         if (r < 0) {
-                log_syntax(unit, LOG_WARNING, filename, line, r, "Lifetime is invalid, ignoring assignment: %s", rvalue);
-                return 0;
-        }
-
-        /* a value of 0xffffffff represents infinity */
-        if (streq(lvalue, "PreferredLifetimeSec"))
-                r = sd_radv_prefix_set_preferred_lifetime(p->radv_prefix,
-                                                          DIV_ROUND_UP(usec, USEC_PER_SEC));
-        else if (streq(lvalue, "ValidLifetimeSec"))
-                r = sd_radv_prefix_set_valid_lifetime(p->radv_prefix,
-                                                      DIV_ROUND_UP(usec, USEC_PER_SEC));
-        if (r < 0) {
-                log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to set %s=, ignoring assignment: %m", lvalue);
+                log_syntax(unit, LOG_WARNING, filename, line, r,
+                           "Lifetime is invalid, ignoring assignment: %s", rvalue);
                 return 0;
         }
 
-        p = NULL;
-
-        return 0;
-}
-
-int config_parse_prefix_assign(
-                const char *unit,
-                const char *filename,
-                unsigned line,
-                const char *section,
-                unsigned section_line,
-                const char *lvalue,
-                int ltype,
-                const char *rvalue,
-                void *data,
-                void *userdata) {
-
-        Network *network = userdata;
-        _cleanup_(prefix_free_or_set_invalidp) Prefix *p = NULL;
-        int r;
-
-        assert(filename);
-        assert(section);
-        assert(lvalue);
-        assert(rvalue);
-        assert(data);
-
-        r = prefix_new_static(network, filename, section_line, &p);
-        if (r < 0)
-                return log_oom();
-
-        r = parse_boolean(rvalue);
-        if (r < 0) {
-                log_syntax(unit, LOG_WARNING, filename, line, r,
-                           "Failed to parse %s=, ignoring assignment: %s",
-                           lvalue, rvalue);
+        if (usec != USEC_INFINITY && DIV_ROUND_UP(usec, USEC_PER_SEC) >= UINT32_MAX) {
+                log_syntax(unit, LOG_WARNING, filename, line, 0,
+                           "Lifetime is too long, ignoring assignment: %s", rvalue);
                 return 0;
         }
 
-        p->assign = r;
-        p = NULL;
+        if (streq(lvalue, "PreferredLifetimeSec"))
+                p->preferred_lifetime = usec;
+        else if (streq(lvalue, "ValidLifetimeSec"))
+                p->valid_lifetime = usec;
+        else
+                assert_not_reached();
 
+        TAKE_PTR(p);
         return 0;
 }
 
@@ -856,15 +846,15 @@ int config_parse_prefix_metric(
                 void *data,
                 void *userdata) {
 
-        Network *network = userdata;
         _cleanup_(prefix_free_or_set_invalidp) Prefix *p = NULL;
+        Network *network = userdata;
         int r;
 
         assert(filename);
         assert(section);
         assert(lvalue);
         assert(rvalue);
-        assert(data);
+        assert(userdata);
 
         r = prefix_new_static(network, filename, section_line, &p);
         if (r < 0)
@@ -879,7 +869,6 @@ int config_parse_prefix_metric(
         }
 
         TAKE_PTR(p);
-
         return 0;
 }
 
@@ -930,36 +919,30 @@ int config_parse_route_prefix(
                 void *data,
                 void *userdata) {
 
-        Network *network = userdata;
         _cleanup_(route_prefix_free_or_set_invalidp) RoutePrefix *p = NULL;
-        uint8_t prefixlen = 64;
-        union in_addr_union in6addr;
+        Network *network = userdata;
+        union in_addr_union a;
         int r;
 
         assert(filename);
         assert(section);
         assert(lvalue);
         assert(rvalue);
-        assert(data);
+        assert(userdata);
 
         r = route_prefix_new_static(network, filename, section_line, &p);
         if (r < 0)
                 return log_oom();
 
-        r = in_addr_prefix_from_string(rvalue, AF_INET6, &in6addr, &prefixlen);
-        if (r < 0) {
-                log_syntax(unit, LOG_WARNING, filename, line, r, "Route prefix is invalid, ignoring assignment: %s", rvalue);
-                return 0;
-        }
-
-        r = sd_radv_route_prefix_set_prefix(p->radv_route_prefix, &in6addr.in6, prefixlen);
+        r = in_addr_prefix_from_string(rvalue, AF_INET6, &a, &p->prefixlen);
         if (r < 0) {
-                log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to set route prefix, ignoring assignment: %m");
+                log_syntax(unit, LOG_WARNING, filename, line, r,
+                           "Route prefix is invalid, ignoring assignment: %s", rvalue);
                 return 0;
         }
+        p->prefix = a.in6;
 
-        p = NULL;
-
+        TAKE_PTR(p);
         return 0;
 }
 
@@ -975,8 +958,8 @@ int config_parse_route_prefix_lifetime(
                 void *data,
                 void *userdata) {
 
-        Network *network = userdata;
         _cleanup_(route_prefix_free_or_set_invalidp) RoutePrefix *p = NULL;
+        Network *network = userdata;
         usec_t usec;
         int r;
 
@@ -984,7 +967,7 @@ int config_parse_route_prefix_lifetime(
         assert(section);
         assert(lvalue);
         assert(rvalue);
-        assert(data);
+        assert(userdata);
 
         r = route_prefix_new_static(network, filename, section_line, &p);
         if (r < 0)
@@ -997,16 +980,15 @@ int config_parse_route_prefix_lifetime(
                 return 0;
         }
 
-        /* a value of 0xffffffff represents infinity */
-        r = sd_radv_route_prefix_set_lifetime(p->radv_route_prefix, DIV_ROUND_UP(usec, USEC_PER_SEC));
-        if (r < 0) {
-                log_syntax(unit, LOG_WARNING, filename, line, r,
-                           "Failed to set route lifetime, ignoring assignment: %m");
+        if (usec != USEC_INFINITY && DIV_ROUND_UP(usec, USEC_PER_SEC) >= UINT32_MAX) {
+                log_syntax(unit, LOG_WARNING, filename, line, 0,
+                           "Lifetime is too long, ignoring assignment: %s", rvalue);
                 return 0;
         }
 
-        p = NULL;
+        p->lifetime = usec;
 
+        TAKE_PTR(p);
         return 0;
 }
 
index 5c869d8623e61c7bc8df47f940318bf873b03720..d51fe323dcec8216eed1efee25bad58f64749aee 100644 (file)
@@ -31,7 +31,13 @@ typedef struct Prefix {
         Network *network;
         NetworkConfigSection *section;
 
-        sd_radv_prefix *radv_prefix;
+        struct in6_addr prefix;
+        uint8_t prefixlen;
+        usec_t preferred_lifetime;
+        usec_t valid_lifetime;
+
+        bool onlink;
+        bool address_auto_configuration;
 
         bool assign;
         uint32_t route_metric;
@@ -42,7 +48,9 @@ typedef struct RoutePrefix {
         Network *network;
         NetworkConfigSection *section;
 
-        sd_radv_route_prefix *radv_route_prefix;
+        struct in6_addr prefix;
+        uint8_t prefixlen;
+        usec_t lifetime;
 } RoutePrefix;
 
 Prefix *prefix_free(Prefix *prefix);
@@ -67,9 +75,8 @@ RADVPrefixDelegation radv_prefix_delegation_from_string(const char *s) _pure_;
 CONFIG_PARSER_PROTOTYPE(config_parse_router_prefix_delegation);
 CONFIG_PARSER_PROTOTYPE(config_parse_router_preference);
 CONFIG_PARSER_PROTOTYPE(config_parse_prefix);
-CONFIG_PARSER_PROTOTYPE(config_parse_prefix_flags);
+CONFIG_PARSER_PROTOTYPE(config_parse_prefix_boolean);
 CONFIG_PARSER_PROTOTYPE(config_parse_prefix_lifetime);
-CONFIG_PARSER_PROTOTYPE(config_parse_prefix_assign);
 CONFIG_PARSER_PROTOTYPE(config_parse_prefix_metric);
 CONFIG_PARSER_PROTOTYPE(config_parse_prefix_token);
 CONFIG_PARSER_PROTOTYPE(config_parse_radv_dns);