]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-ndisc: make sd_ndisc return time values in usec 29254/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 21 Sep 2023 17:18:06 +0000 (02:18 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 22 Sep 2023 16:34:56 +0000 (01:34 +0900)
This also introduces sd_ndisc_router_get_lifetime_timestamp() and
friends that return timestamp rather than timespan.

src/libsystemd-network/ndisc-router.c
src/libsystemd-network/ndisc-router.h
src/libsystemd-network/sd-ndisc.c
src/libsystemd-network/test-ndisc-rs.c
src/network/networkd-ndisc.c
src/systemd/sd-ndisc.h

index f03a9f18dd2dbd8f5923a6c4a515833de3046485..74331591f0bea9ef333ece4685db673d1be836a3 100644 (file)
@@ -59,6 +59,38 @@ int sd_ndisc_router_get_timestamp(sd_ndisc_router *rt, clockid_t clock, uint64_t
         return 0;
 }
 
+#define DEFINE_GET_TIMESTAMP(name)                                      \
+        int sd_ndisc_router_##name##_timestamp(                         \
+                        sd_ndisc_router *rt,                            \
+                        clockid_t clock,                                \
+                        uint64_t *ret) {                                \
+                                                                        \
+                usec_t s, t;                                            \
+                int r;                                                  \
+                                                                        \
+                assert_return(rt, -EINVAL);                             \
+                assert_return(ret, -EINVAL);                            \
+                                                                        \
+                r = sd_ndisc_router_##name(rt, &s);                     \
+                if (r < 0)                                              \
+                        return r;                                       \
+                                                                        \
+                r = sd_ndisc_router_get_timestamp(rt, clock, &t);       \
+                if (r < 0)                                              \
+                        return r;                                       \
+                                                                        \
+                *ret = time_span_to_stamp(s, t);                        \
+                return 0;                                               \
+        }
+
+DEFINE_GET_TIMESTAMP(get_lifetime);
+DEFINE_GET_TIMESTAMP(prefix_get_valid_lifetime);
+DEFINE_GET_TIMESTAMP(prefix_get_preferred_lifetime);
+DEFINE_GET_TIMESTAMP(route_get_lifetime);
+DEFINE_GET_TIMESTAMP(rdnss_get_lifetime);
+DEFINE_GET_TIMESTAMP(dnssl_get_lifetime);
+DEFINE_GET_TIMESTAMP(prefix64_get_lifetime);
+
 int sd_ndisc_router_get_raw(sd_ndisc_router *rt, const void **ret, size_t *ret_size) {
         assert_return(rt, -EINVAL);
         assert_return(ret, -EINVAL);
@@ -110,8 +142,8 @@ int ndisc_router_parse(sd_ndisc *nd, sd_ndisc_router *rt) {
 
         rt->hop_limit = a->nd_ra_curhoplimit;
         rt->flags = a->nd_ra_flags_reserved; /* the first 8 bits */
-        rt->lifetime = be16toh(a->nd_ra_router_lifetime);
-        rt->icmp6_ratelimit_msec = be32toh(a->nd_ra_retransmit);
+        rt->lifetime_usec = be16_sec_to_usec(a->nd_ra_router_lifetime, /* max_as_infinity = */ false);
+        rt->icmp6_ratelimit_usec = be32_msec_to_usec(a->nd_ra_retransmit, /* max_as_infinity = */ false);
 
         rt->preference = (rt->flags >> 3) & 3;
         if (!IN_SET(rt->preference, SD_NDISC_PREFERENCE_LOW, SD_NDISC_PREFERENCE_HIGH))
@@ -243,11 +275,11 @@ int sd_ndisc_router_get_hop_limit(sd_ndisc_router *rt, uint8_t *ret) {
         return 0;
 }
 
-int sd_ndisc_router_get_icmp6_ratelimit(sd_ndisc_router *rt, uint32_t *ret) {
+int sd_ndisc_router_get_icmp6_ratelimit(sd_ndisc_router *rt, uint64_t *ret) {
         assert_return(rt, -EINVAL);
         assert_return(ret, -EINVAL);
 
-        *ret = rt->icmp6_ratelimit_msec;
+        *ret = rt->icmp6_ratelimit_usec;
         return 0;
 }
 
@@ -259,11 +291,11 @@ int sd_ndisc_router_get_flags(sd_ndisc_router *rt, uint64_t *ret) {
         return 0;
 }
 
-int sd_ndisc_router_get_lifetime(sd_ndisc_router *rt, uint16_t *ret) {
+int sd_ndisc_router_get_lifetime(sd_ndisc_router *rt, uint64_t *ret) {
         assert_return(rt, -EINVAL);
         assert_return(ret, -EINVAL);
 
-        *ret = rt->lifetime;
+        *ret = rt->lifetime_usec;
         return 0;
 }
 
@@ -389,7 +421,7 @@ static int get_prefix_info(sd_ndisc_router *rt, struct nd_opt_prefix_info **ret)
         return 0;
 }
 
-int sd_ndisc_router_prefix_get_valid_lifetime(sd_ndisc_router *rt, uint32_t *ret) {
+int sd_ndisc_router_prefix_get_valid_lifetime(sd_ndisc_router *rt, uint64_t *ret) {
         struct nd_opt_prefix_info *ri;
         int r;
 
@@ -400,11 +432,11 @@ int sd_ndisc_router_prefix_get_valid_lifetime(sd_ndisc_router *rt, uint32_t *ret
         if (r < 0)
                 return r;
 
-        *ret = be32toh(ri->nd_opt_pi_valid_time);
+        *ret = be32_sec_to_usec(ri->nd_opt_pi_valid_time, /* max_as_infinity = */ true);
         return 0;
 }
 
-int sd_ndisc_router_prefix_get_preferred_lifetime(sd_ndisc_router *rt, uint32_t *ret) {
+int sd_ndisc_router_prefix_get_preferred_lifetime(sd_ndisc_router *rt, uint64_t *ret) {
         struct nd_opt_prefix_info *pi;
         int r;
 
@@ -415,7 +447,7 @@ int sd_ndisc_router_prefix_get_preferred_lifetime(sd_ndisc_router *rt, uint32_t
         if (r < 0)
                 return r;
 
-        *ret = be32toh(pi->nd_opt_pi_preferred_time);
+        *ret = be32_sec_to_usec(pi->nd_opt_pi_preferred_time, /* max_as_infinity = */ true);
         return 0;
 }
 
@@ -502,7 +534,7 @@ static int get_route_info(sd_ndisc_router *rt, uint8_t **ret) {
         return 0;
 }
 
-int sd_ndisc_router_route_get_lifetime(sd_ndisc_router *rt, uint32_t *ret) {
+int sd_ndisc_router_route_get_lifetime(sd_ndisc_router *rt, uint64_t *ret) {
         uint8_t *ri;
         int r;
 
@@ -513,7 +545,7 @@ int sd_ndisc_router_route_get_lifetime(sd_ndisc_router *rt, uint32_t *ret) {
         if (r < 0)
                 return r;
 
-        *ret = be32toh(*(uint32_t*) (ri + 4));
+        *ret = unaligned_be32_sec_to_usec(ri + 4, /* max_as_infinity = */ true);
         return 0;
 }
 
@@ -603,7 +635,7 @@ int sd_ndisc_router_rdnss_get_addresses(sd_ndisc_router *rt, const struct in6_ad
         return (NDISC_ROUTER_OPTION_LENGTH(rt) - 8) / 16;
 }
 
-int sd_ndisc_router_rdnss_get_lifetime(sd_ndisc_router *rt, uint32_t *ret) {
+int sd_ndisc_router_rdnss_get_lifetime(sd_ndisc_router *rt, uint64_t *ret) {
         uint8_t *ri;
         int r;
 
@@ -614,7 +646,7 @@ int sd_ndisc_router_rdnss_get_lifetime(sd_ndisc_router *rt, uint32_t *ret) {
         if (r < 0)
                 return r;
 
-        *ret = be32toh(*(uint32_t*) (ri + 4));
+        *ret = unaligned_be32_sec_to_usec(ri + 4, /* max_as_infinity = */ true);
         return 0;
 }
 
@@ -731,7 +763,7 @@ int sd_ndisc_router_dnssl_get_domains(sd_ndisc_router *rt, char ***ret) {
         return k;
 }
 
-int sd_ndisc_router_dnssl_get_lifetime(sd_ndisc_router *rt, uint32_t *ret) {
+int sd_ndisc_router_dnssl_get_lifetime(sd_ndisc_router *rt, uint64_t *ret) {
         uint8_t *ri;
         int r;
 
@@ -742,7 +774,7 @@ int sd_ndisc_router_dnssl_get_lifetime(sd_ndisc_router *rt, uint32_t *ret) {
         if (r < 0)
                 return r;
 
-        *ret = be32toh(*(uint32_t*) (ri + 4));
+        *ret = unaligned_be32_sec_to_usec(ri + 4, /* max_as_infinity = */ true);
         return 0;
 }
 
@@ -862,7 +894,7 @@ int sd_ndisc_router_prefix64_get_prefixlen(sd_ndisc_router *rt, unsigned *ret) {
         return 0;
 }
 
-int sd_ndisc_router_prefix64_get_lifetime_sec(sd_ndisc_router *rt, uint16_t *ret) {
+int sd_ndisc_router_prefix64_get_lifetime(sd_ndisc_router *rt, uint64_t *ret) {
         struct nd_opt_prefix64_info *pi;
         uint16_t lifetime_prefix_len;
         int r;
@@ -876,6 +908,6 @@ int sd_ndisc_router_prefix64_get_lifetime_sec(sd_ndisc_router *rt, uint16_t *ret
 
         lifetime_prefix_len = be16toh(pi->lifetime_and_plc);
 
-        *ret = lifetime_prefix_len & PREF64_SCALED_LIFETIME_MASK;
+        *ret = (lifetime_prefix_len & PREF64_SCALED_LIFETIME_MASK) * USEC_PER_SEC;
         return 0;
 }
index cf702f52c394aa949934750dc0c02d82c34b8e67..0a55e1ac57bdf8e34c379847bdf5eaf53c2ee20d 100644 (file)
@@ -23,11 +23,11 @@ struct sd_ndisc_router {
 
         uint64_t flags;
         unsigned preference;
-        uint16_t lifetime;
+        uint64_t lifetime_usec;
 
         uint8_t hop_limit;
         uint32_t mtu;
-        uint32_t icmp6_ratelimit_msec;
+        uint64_t icmp6_ratelimit_usec;
 };
 
 static inline void* NDISC_ROUTER_RAW(const sd_ndisc_router *rt) {
index d7d9e7e2d9f3299614dad60d89374545efe8130d..1beed5d0ce29f995950c02fb63b94ea971314b0b 100644 (file)
@@ -189,10 +189,10 @@ static int ndisc_handle_datagram(sd_ndisc *nd, sd_ndisc_router *rt) {
         if (r < 0)
                 return r;
 
-        log_ndisc(nd, "Received Router Advertisement: flags %s preference %s lifetime %" PRIu16 " sec",
+        log_ndisc(nd, "Received Router Advertisement: flags %s preference %s lifetime %s",
                   rt->flags & ND_RA_FLAG_MANAGED ? "MANAGED" : rt->flags & ND_RA_FLAG_OTHER ? "OTHER" : "none",
                   rt->preference == SD_NDISC_PREFERENCE_HIGH ? "high" : rt->preference == SD_NDISC_PREFERENCE_LOW ? "low" : "medium",
-                  rt->lifetime);
+                  FORMAT_TIMESPAN(rt->lifetime_usec, USEC_PER_SEC));
 
         ndisc_callback(nd, SD_NDISC_EVENT_ROUTER, rt);
         return 0;
index 09e292a2ec36d9da8360b19d8c9b118e24f9d573..d94cc1ceb74ad8672657c397ce1dbb69d4e8cad2 100644 (file)
@@ -28,9 +28,9 @@ static sd_ndisc *test_timeout_nd;
 static void router_dump(sd_ndisc_router *rt) {
         struct in6_addr addr;
         uint8_t hop_limit;
-        uint64_t t, flags;
+        usec_t t, lifetime;
+        uint64_t flags;
         uint32_t mtu;
-        uint16_t lifetime;
         unsigned preference;
         int r;
 
@@ -62,7 +62,8 @@ static void router_dump(sd_ndisc_router *rt) {
                  preference == SD_NDISC_PREFERENCE_HIGH ? "high" : "medium");
 
         assert_se(sd_ndisc_router_get_lifetime(rt, &lifetime) >= 0);
-        log_info("Lifetime: %" PRIu16, lifetime);
+        assert_se(sd_ndisc_router_get_lifetime_timestamp(rt, CLOCK_REALTIME, &t) >= 0);
+        log_info("Lifetime: %s (%s)", FORMAT_TIMESPAN(lifetime, USEC_PER_SEC), FORMAT_TIMESTAMP(t));
 
         if (sd_ndisc_router_get_mtu(rt, &mtu) < 0)
                 log_info("No MTU set");
@@ -99,16 +100,17 @@ static void router_dump(sd_ndisc_router *rt) {
                 }
 
                 case SD_NDISC_OPTION_PREFIX_INFORMATION: {
-                        uint32_t lifetime_valid, lifetime_preferred;
                         unsigned prefix_len;
                         uint8_t pfl;
                         struct in6_addr a;
 
-                        assert_se(sd_ndisc_router_prefix_get_valid_lifetime(rt, &lifetime_valid) >= 0);
-                        log_info("Valid Lifetime: %" PRIu32, lifetime_valid);
+                        assert_se(sd_ndisc_router_prefix_get_valid_lifetime(rt, &lifetime) >= 0);
+                        assert_se(sd_ndisc_router_prefix_get_valid_lifetime_timestamp(rt, CLOCK_REALTIME, &t) >= 0);
+                        log_info("Valid Lifetime: %s (%s)", FORMAT_TIMESPAN(lifetime, USEC_PER_SEC), FORMAT_TIMESTAMP(t));
 
-                        assert_se(sd_ndisc_router_prefix_get_preferred_lifetime(rt, &lifetime_preferred) >= 0);
-                        log_info("Preferred Lifetime: %" PRIu32, lifetime_preferred);
+                        assert_se(sd_ndisc_router_prefix_get_preferred_lifetime(rt, &lifetime) >= 0);
+                        assert_se(sd_ndisc_router_prefix_get_preferred_lifetime_timestamp(rt, CLOCK_REALTIME, &t) >= 0);
+                        log_info("Preferred Lifetime: %s (%s)", FORMAT_TIMESPAN(lifetime, USEC_PER_SEC), FORMAT_TIMESTAMP(t));
 
                         assert_se(sd_ndisc_router_prefix_get_flags(rt, &pfl) >= 0);
                         log_info("Flags: <%s|%s>",
@@ -126,7 +128,6 @@ static void router_dump(sd_ndisc_router *rt) {
 
                 case SD_NDISC_OPTION_RDNSS: {
                         const struct in6_addr *a;
-                        uint32_t lt;
                         int n, i;
 
                         n = sd_ndisc_router_rdnss_get_addresses(rt, &a);
@@ -135,14 +136,14 @@ static void router_dump(sd_ndisc_router *rt) {
                         for (i = 0; i < n; i++)
                                 log_info("DNS: %s", IN6_ADDR_TO_STRING(a + i));
 
-                        assert_se(sd_ndisc_router_rdnss_get_lifetime(rt, &lt) >= 0);
-                        log_info("Lifetime: %" PRIu32, lt);
+                        assert_se(sd_ndisc_router_rdnss_get_lifetime(rt, &lifetime) >= 0);
+                        assert_se(sd_ndisc_router_rdnss_get_lifetime_timestamp(rt, CLOCK_REALTIME, &t) >= 0);
+                        log_info("Lifetime: %s (%s)", FORMAT_TIMESPAN(lifetime, USEC_PER_SEC), FORMAT_TIMESTAMP(t));
                         break;
                 }
 
                 case SD_NDISC_OPTION_DNSSL: {
                         _cleanup_strv_free_ char **l = NULL;
-                        uint32_t lt;
                         int n, i;
 
                         n = sd_ndisc_router_dnssl_get_domains(rt, &l);
@@ -151,8 +152,9 @@ static void router_dump(sd_ndisc_router *rt) {
                         for (i = 0; i < n; i++)
                                 log_info("Domain: %s", l[i]);
 
-                        assert_se(sd_ndisc_router_dnssl_get_lifetime(rt, &lt) >= 0);
-                        log_info("Lifetime: %" PRIu32, lt);
+                        assert_se(sd_ndisc_router_dnssl_get_lifetime(rt, &lifetime) >= 0);
+                        assert_se(sd_ndisc_router_dnssl_get_lifetime_timestamp(rt, CLOCK_REALTIME, &t) >= 0);
+                        log_info("Lifetime: %s (%s)", FORMAT_TIMESPAN(lifetime, USEC_PER_SEC), FORMAT_TIMESTAMP(t));
                         break;
                 }}
 
index 00eac3477d86bdfa848f5fd0095d385a69fe6fda..08af9c73b9935321ace3af665ffc812683712458 100644 (file)
@@ -278,9 +278,8 @@ static int ndisc_request_address(Address *in, Link *link, sd_ndisc_router *rt) {
 }
 
 static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
-        usec_t lifetime_usec, timestamp_usec;
+        usec_t lifetime_usec;
         struct in6_addr gateway;
-        uint16_t lifetime_sec;
         unsigned preference;
         int r;
 
@@ -292,16 +291,10 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
             hashmap_isempty(link->network->routes_by_section))
                 return 0;
 
-        r = sd_ndisc_router_get_lifetime(rt, &lifetime_sec);
+        r = sd_ndisc_router_get_lifetime_timestamp(rt, CLOCK_BOOTTIME, &lifetime_usec);
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to get gateway lifetime from RA: %m");
 
-        r = sd_ndisc_router_get_timestamp(rt, CLOCK_BOOTTIME, &timestamp_usec);
-        if (r < 0)
-                return log_link_warning_errno(link, r, "Failed to get RA timestamp: %m");
-
-        lifetime_usec = sec16_to_usec(lifetime_sec, timestamp_usec);
-
         r = sd_ndisc_router_get_address(rt, &gateway);
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to get gateway address from RA: %m");
@@ -363,8 +356,8 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
 }
 
 static int ndisc_router_process_icmp6_ratelimit(Link *link, sd_ndisc_router *rt) {
-        char buf[DECIMAL_STR_MAX(unsigned)];
-        uint32_t icmp6_ratelimit;
+        char buf[DECIMAL_STR_MAX(usec_t)];
+        usec_t icmp6_ratelimit;
         int r;
 
         assert(link);
@@ -380,10 +373,12 @@ static int ndisc_router_process_icmp6_ratelimit(Link *link, sd_ndisc_router *rt)
                 return 0;
         }
 
-        if (icmp6_ratelimit == 0)
+        if (!timestamp_is_set(icmp6_ratelimit))
                 return 0;
 
-        xsprintf(buf, "%u", icmp6_ratelimit);
+        /* Limit the maximal rates for sending ICMPv6 packets. 0 to disable any limiting, otherwise the
+         * minimal space between responses in milliseconds. Default: 1000. */
+        xsprintf(buf, USEC_FMT, DIV_ROUND_UP(icmp6_ratelimit, USEC_PER_MSEC));
 
         r = sysctl_write_ip_property(AF_INET6, NULL, "icmp/ratelimit", buf);
         if (r < 0)
@@ -393,8 +388,7 @@ static int ndisc_router_process_icmp6_ratelimit(Link *link, sd_ndisc_router *rt)
 }
 
 static int ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *rt) {
-        uint32_t lifetime_valid_sec, lifetime_preferred_sec;
-        usec_t lifetime_valid_usec, lifetime_preferred_usec, timestamp_usec;
+        usec_t lifetime_valid_usec, lifetime_preferred_usec;
         _cleanup_set_free_ Set *addresses = NULL;
         struct in6_addr prefix, *a;
         unsigned prefixlen;
@@ -407,10 +401,6 @@ static int ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *r
         if (!link->network->ipv6_accept_ra_use_autonomous_prefix)
                 return 0;
 
-        r = sd_ndisc_router_get_timestamp(rt, CLOCK_BOOTTIME, &timestamp_usec);
-        if (r < 0)
-                return log_link_warning_errno(link, r, "Failed to get RA timestamp: %m");
-
         r = sd_ndisc_router_prefix_get_address(rt, &prefix);
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to get prefix address: %m");
@@ -426,21 +416,18 @@ static int ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *r
                 return 0;
         }
 
-        r = sd_ndisc_router_prefix_get_valid_lifetime(rt, &lifetime_valid_sec);
+        r = sd_ndisc_router_prefix_get_valid_lifetime_timestamp(rt, CLOCK_BOOTTIME, &lifetime_valid_usec);
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to get prefix valid lifetime: %m");
 
-        r = sd_ndisc_router_prefix_get_preferred_lifetime(rt, &lifetime_preferred_sec);
+        r = sd_ndisc_router_prefix_get_preferred_lifetime_timestamp(rt, CLOCK_BOOTTIME, &lifetime_preferred_usec);
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to get prefix preferred lifetime: %m");
 
         /* The preferred lifetime is never greater than the valid lifetime */
-        if (lifetime_preferred_sec > lifetime_valid_sec)
+        if (lifetime_preferred_usec > lifetime_valid_usec)
                 return 0;
 
-        lifetime_valid_usec = sec_to_usec(lifetime_valid_sec, timestamp_usec);
-        lifetime_preferred_usec = sec_to_usec(lifetime_preferred_sec, timestamp_usec);
-
         r = ndisc_generate_addresses(link, &prefix, prefixlen, &addresses);
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to generate SLAAC addresses: %m");
@@ -470,8 +457,7 @@ static int ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *r
 static int ndisc_router_process_onlink_prefix(Link *link, sd_ndisc_router *rt) {
         _cleanup_(route_freep) Route *route = NULL;
         unsigned prefixlen, preference;
-        usec_t timestamp_usec;
-        uint32_t lifetime_sec;
+        usec_t lifetime_usec;
         struct in6_addr prefix;
         int r;
 
@@ -482,14 +468,10 @@ static int ndisc_router_process_onlink_prefix(Link *link, sd_ndisc_router *rt) {
         if (!link->network->ipv6_accept_ra_use_onlink_prefix)
                 return 0;
 
-        r = sd_ndisc_router_prefix_get_valid_lifetime(rt, &lifetime_sec);
+        r = sd_ndisc_router_prefix_get_valid_lifetime_timestamp(rt, CLOCK_BOOTTIME, &lifetime_usec);
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to get prefix lifetime: %m");
 
-        r = sd_ndisc_router_get_timestamp(rt, CLOCK_BOOTTIME, &timestamp_usec);
-        if (r < 0)
-                return log_link_warning_errno(link, r, "Failed to get RA timestamp: %m");
-
         r = sd_ndisc_router_prefix_get_address(rt, &prefix);
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to get prefix address: %m");
@@ -511,7 +493,7 @@ static int ndisc_router_process_onlink_prefix(Link *link, sd_ndisc_router *rt) {
         route->dst.in6 = prefix;
         route->dst_prefixlen = prefixlen;
         route->pref = preference;
-        route->lifetime_usec = sec_to_usec(lifetime_sec, timestamp_usec);
+        route->lifetime_usec = lifetime_usec;
 
         r = ndisc_request_route(TAKE_PTR(route), link, rt);
         if (r < 0)
@@ -578,8 +560,7 @@ static int ndisc_router_process_route(Link *link, sd_ndisc_router *rt) {
         _cleanup_(route_freep) Route *route = NULL;
         unsigned preference, prefixlen;
         struct in6_addr gateway, dst;
-        uint32_t lifetime_sec;
-        usec_t timestamp_usec;
+        usec_t lifetime_usec;
         int r;
 
         assert(link);
@@ -587,7 +568,7 @@ static int ndisc_router_process_route(Link *link, sd_ndisc_router *rt) {
         if (!link->network->ipv6_accept_ra_use_route_prefix)
                 return 0;
 
-        r = sd_ndisc_router_route_get_lifetime(rt, &lifetime_sec);
+        r = sd_ndisc_router_route_get_lifetime_timestamp(rt, CLOCK_BOOTTIME, &lifetime_usec);
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to get route lifetime from RA: %m");
 
@@ -635,10 +616,6 @@ static int ndisc_router_process_route(Link *link, sd_ndisc_router *rt) {
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to get default router preference from RA: %m");
 
-        r = sd_ndisc_router_get_timestamp(rt, CLOCK_BOOTTIME, &timestamp_usec);
-        if (r < 0)
-                return log_link_warning_errno(link, r, "Failed to get RA timestamp: %m");
-
         r = route_new(&route);
         if (r < 0)
                 return log_oom();
@@ -649,7 +626,7 @@ static int ndisc_router_process_route(Link *link, sd_ndisc_router *rt) {
         route->gw_family = AF_INET6;
         route->dst.in6 = dst;
         route->dst_prefixlen = prefixlen;
-        route->lifetime_usec = sec_to_usec(lifetime_sec, timestamp_usec);
+        route->lifetime_usec = lifetime_usec;
 
         r = ndisc_request_route(TAKE_PTR(route), link, rt);
         if (r < 0)
@@ -674,8 +651,7 @@ DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
                 free);
 
 static int ndisc_router_process_rdnss(Link *link, sd_ndisc_router *rt) {
-        usec_t lifetime_usec, timestamp_usec;
-        uint32_t lifetime_sec;
+        usec_t lifetime_usec;
         const struct in6_addr *a;
         struct in6_addr router;
         bool updated = false, logged_about_too_many = false;
@@ -692,16 +668,10 @@ static int ndisc_router_process_rdnss(Link *link, sd_ndisc_router *rt) {
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to get router address from RA: %m");
 
-        r = sd_ndisc_router_get_timestamp(rt, CLOCK_BOOTTIME, &timestamp_usec);
-        if (r < 0)
-                return log_link_warning_errno(link, r, "Failed to get RA timestamp: %m");
-
-        r = sd_ndisc_router_rdnss_get_lifetime(rt, &lifetime_sec);
+        r = sd_ndisc_router_rdnss_get_lifetime_timestamp(rt, CLOCK_BOOTTIME, &lifetime_usec);
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to get RDNSS lifetime: %m");
 
-        lifetime_usec = sec_to_usec(lifetime_sec, timestamp_usec);
-
         n = sd_ndisc_router_rdnss_get_addresses(rt, &a);
         if (n < 0)
                 return log_link_warning_errno(link, n, "Failed to get RDNSS addresses: %m");
@@ -774,9 +744,8 @@ DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
 
 static int ndisc_router_process_dnssl(Link *link, sd_ndisc_router *rt) {
         _cleanup_strv_free_ char **l = NULL;
-        usec_t lifetime_usec, timestamp_usec;
+        usec_t lifetime_usec;
         struct in6_addr router;
-        uint32_t lifetime_sec;
         bool updated = false, logged_about_too_many = false;
         int r;
 
@@ -791,16 +760,10 @@ static int ndisc_router_process_dnssl(Link *link, sd_ndisc_router *rt) {
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to get router address from RA: %m");
 
-        r = sd_ndisc_router_get_timestamp(rt, CLOCK_BOOTTIME, &timestamp_usec);
-        if (r < 0)
-                return log_link_warning_errno(link, r, "Failed to get RA timestamp: %m");
-
-        r = sd_ndisc_router_dnssl_get_lifetime(rt, &lifetime_sec);
+        r = sd_ndisc_router_dnssl_get_lifetime_timestamp(rt, CLOCK_BOOTTIME, &lifetime_usec);
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to get DNSSL lifetime: %m");
 
-        lifetime_usec = sec_to_usec(lifetime_sec, timestamp_usec);
-
         r = sd_ndisc_router_dnssl_get_domains(rt, &l);
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to get DNSSL addresses: %m");
@@ -884,10 +847,9 @@ DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
 static int ndisc_router_process_captive_portal(Link *link, sd_ndisc_router *rt) {
         _cleanup_(ndisc_captive_portal_freep) NDiscCaptivePortal *new_entry = NULL;
         _cleanup_free_ char *captive_portal = NULL;
-        usec_t lifetime_usec, timestamp_usec;
+        usec_t lifetime_usec;
         NDiscCaptivePortal *exist;
         struct in6_addr router;
-        uint16_t lifetime_sec;
         const char *uri;
         size_t len;
         int r;
@@ -906,16 +868,10 @@ static int ndisc_router_process_captive_portal(Link *link, sd_ndisc_router *rt)
         /* RFC 4861 section 4.2. states that the lifetime in the message header should be used only for the
          * default gateway, but the captive portal option does not have a lifetime field, hence, we use the
          * main lifetime for the portal. */
-        r = sd_ndisc_router_get_lifetime(rt, &lifetime_sec);
+        r = sd_ndisc_router_get_lifetime_timestamp(rt, CLOCK_BOOTTIME, &lifetime_usec);
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to get lifetime of RA message: %m");
 
-        r = sd_ndisc_router_get_timestamp(rt, CLOCK_BOOTTIME, &timestamp_usec);
-        if (r < 0)
-                return log_link_warning_errno(link, r, "Failed to get RA timestamp: %m");
-
-        lifetime_usec = sec16_to_usec(lifetime_sec, timestamp_usec);
-
         r = sd_ndisc_router_captive_portal_get_uri(rt, &uri, &len);
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to get captive portal from RA: %m");
@@ -1012,9 +968,8 @@ DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
 
 static int ndisc_router_process_pref64(Link *link, sd_ndisc_router *rt) {
         _cleanup_free_ NDiscPREF64 *new_entry = NULL;
-        usec_t lifetime_usec, timestamp_usec;
+        usec_t lifetime_usec;
         struct in6_addr a, router;
-        uint16_t lifetime_sec;
         unsigned prefix_len;
         NDiscPREF64 *exist;
         int r;
@@ -1038,16 +993,10 @@ static int ndisc_router_process_pref64(Link *link, sd_ndisc_router *rt) {
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to get pref64 prefix length: %m");
 
-        r = sd_ndisc_router_prefix64_get_lifetime_sec(rt, &lifetime_sec);
+        r = sd_ndisc_router_prefix64_get_lifetime_timestamp(rt, CLOCK_BOOTTIME, &lifetime_usec);
         if (r < 0)
                 return log_link_warning_errno(link, r, "Failed to get pref64 prefix lifetime: %m");
 
-        r = sd_ndisc_router_get_timestamp(rt, CLOCK_BOOTTIME, &timestamp_usec);
-        if (r < 0)
-                return log_link_warning_errno(link, r, "Failed to get RA timestamp: %m");
-
-        lifetime_usec = sec16_to_usec(lifetime_sec, timestamp_usec);
-
         if (lifetime_usec == 0) {
                 free(set_remove(link->ndisc_pref64,
                                 &(NDiscPREF64) {
index 89d3f5217f0b35833f5186ae89189d7928ec11e5..3f93e3a40682849f673ae689b77fad030cba739a 100644 (file)
@@ -91,10 +91,11 @@ int sd_ndisc_router_get_timestamp(sd_ndisc_router *rt, clockid_t clock, uint64_t
 int sd_ndisc_router_get_raw(sd_ndisc_router *rt, const void **ret, size_t *ret_size);
 
 int sd_ndisc_router_get_hop_limit(sd_ndisc_router *rt, uint8_t *ret);
-int sd_ndisc_router_get_icmp6_ratelimit(sd_ndisc_router *rt, uint32_t *ret);
+int sd_ndisc_router_get_icmp6_ratelimit(sd_ndisc_router *rt, uint64_t *ret);
 int sd_ndisc_router_get_flags(sd_ndisc_router *rt, uint64_t *ret);
 int sd_ndisc_router_get_preference(sd_ndisc_router *rt, unsigned *ret);
-int sd_ndisc_router_get_lifetime(sd_ndisc_router *rt, uint16_t *ret);
+int sd_ndisc_router_get_lifetime(sd_ndisc_router *rt, uint64_t *ret);
+int sd_ndisc_router_get_lifetime_timestamp(sd_ndisc_router *rt, clockid_t clock, uint64_t *ret);
 int sd_ndisc_router_get_mtu(sd_ndisc_router *rt, uint32_t *ret);
 
 /* Generic option access */
@@ -105,25 +106,30 @@ int sd_ndisc_router_option_is_type(sd_ndisc_router *rt, uint8_t type);
 int sd_ndisc_router_option_get_raw(sd_ndisc_router *rt, const void **ret, size_t *ret_size);
 
 /* Specific option access: SD_NDISC_OPTION_PREFIX_INFORMATION */
-int sd_ndisc_router_prefix_get_valid_lifetime(sd_ndisc_router *rt, uint32_t *ret);
-int sd_ndisc_router_prefix_get_preferred_lifetime(sd_ndisc_router *rt, uint32_t *ret);
+int sd_ndisc_router_prefix_get_valid_lifetime(sd_ndisc_router *rt, uint64_t *ret);
+int sd_ndisc_router_prefix_get_valid_lifetime_timestamp(sd_ndisc_router *rt, clockid_t clock, uint64_t *ret);
+int sd_ndisc_router_prefix_get_preferred_lifetime(sd_ndisc_router *rt, uint64_t *ret);
+int sd_ndisc_router_prefix_get_preferred_lifetime_timestamp(sd_ndisc_router *rt, clockid_t clock, uint64_t *ret);
 int sd_ndisc_router_prefix_get_flags(sd_ndisc_router *rt, uint8_t *ret);
 int sd_ndisc_router_prefix_get_address(sd_ndisc_router *rt, struct in6_addr *ret);
 int sd_ndisc_router_prefix_get_prefixlen(sd_ndisc_router *rt, unsigned *ret);
 
 /* Specific option access: SD_NDISC_OPTION_ROUTE_INFORMATION */
-int sd_ndisc_router_route_get_lifetime(sd_ndisc_router *rt, uint32_t *ret);
+int sd_ndisc_router_route_get_lifetime(sd_ndisc_router *rt, uint64_t *ret);
+int sd_ndisc_router_route_get_lifetime_timestamp(sd_ndisc_router *rt, clockid_t clock, uint64_t *ret);
 int sd_ndisc_router_route_get_address(sd_ndisc_router *rt, struct in6_addr *ret);
 int sd_ndisc_router_route_get_prefixlen(sd_ndisc_router *rt, unsigned *ret);
 int sd_ndisc_router_route_get_preference(sd_ndisc_router *rt, unsigned *ret);
 
 /* Specific option access: SD_NDISC_OPTION_RDNSS */
 int sd_ndisc_router_rdnss_get_addresses(sd_ndisc_router *rt, const struct in6_addr **ret);
-int sd_ndisc_router_rdnss_get_lifetime(sd_ndisc_router *rt, uint32_t *ret);
+int sd_ndisc_router_rdnss_get_lifetime(sd_ndisc_router *rt, uint64_t *ret);
+int sd_ndisc_router_rdnss_get_lifetime_timestamp(sd_ndisc_router *rt, clockid_t clock, uint64_t *ret);
 
 /* Specific option access: SD_NDISC_OPTION_DNSSL */
 int sd_ndisc_router_dnssl_get_domains(sd_ndisc_router *rt, char ***ret);
-int sd_ndisc_router_dnssl_get_lifetime(sd_ndisc_router *rt, uint32_t *ret);
+int sd_ndisc_router_dnssl_get_lifetime(sd_ndisc_router *rt, uint64_t *ret);
+int sd_ndisc_router_dnssl_get_lifetime_timestamp(sd_ndisc_router *rt, clockid_t clock, uint64_t *ret);
 
 /* Specific option access: SD_NDISC_OPTION_CAPTIVE_PORTAL */
 int sd_ndisc_router_captive_portal_get_uri(sd_ndisc_router *rt, const char **ret, size_t *ret_size);
@@ -131,7 +137,8 @@ int sd_ndisc_router_captive_portal_get_uri(sd_ndisc_router *rt, const char **ret
 /* Specific option access: SD_NDISC_OPTION_PREF64 */
 int sd_ndisc_router_prefix64_get_prefix(sd_ndisc_router *rt, struct in6_addr *ret);
 int sd_ndisc_router_prefix64_get_prefixlen(sd_ndisc_router *rt, unsigned *ret);
-int sd_ndisc_router_prefix64_get_lifetime_sec(sd_ndisc_router *rt, uint16_t *ret);
+int sd_ndisc_router_prefix64_get_lifetime(sd_ndisc_router *rt, uint64_t *ret);
+int sd_ndisc_router_prefix64_get_lifetime_timestamp(sd_ndisc_router *rt, clockid_t clock, uint64_t *ret);
 
 _SD_DEFINE_POINTER_CLEANUP_FUNC(sd_ndisc, sd_ndisc_unref);
 _SD_DEFINE_POINTER_CLEANUP_FUNC(sd_ndisc_router, sd_ndisc_router_unref);