]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
libsystemd-network: introduce several helper functions to handle time values
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 6 Sep 2023 18:13:39 +0000 (03:13 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 19 Sep 2023 20:04:03 +0000 (05:04 +0900)
These will be used in later commits.

src/libsystemd-network/network-common.c
src/libsystemd-network/network-common.h
src/libsystemd-network/sd-radv.c

index b8b4ecdaae4e1d27ec326f87e6934de755f02073..be77d7e0a6eb77d22adfdbc3b591b34a822cb452 100644 (file)
@@ -2,6 +2,7 @@
 
 #include "format-util.h"
 #include "network-common.h"
+#include "unaligned.h"
 
 int get_ifname(int ifindex, char **ifname) {
         assert(ifname);
@@ -13,3 +14,82 @@ int get_ifname(int ifindex, char **ifname) {
 
         return format_ifname_alloc(ifindex, ifname);
 }
+
+usec_t unaligned_be32_sec_to_usec(const void *p, bool max_as_infinity) {
+        uint32_t s = unaligned_read_be32(ASSERT_PTR(p));
+
+        if (s == UINT32_MAX && max_as_infinity)
+                return USEC_INFINITY;
+
+        return s * USEC_PER_SEC;
+}
+
+usec_t be32_sec_to_usec(be32_t t, bool max_as_infinity) {
+        uint32_t s = be32toh(t);
+
+        if (s == UINT32_MAX && max_as_infinity)
+                return USEC_INFINITY;
+
+        return s * USEC_PER_SEC;
+}
+
+usec_t be32_msec_to_usec(be32_t t, bool max_as_infinity) {
+        uint32_t s = be32toh(t);
+
+        if (s == UINT32_MAX && max_as_infinity)
+                return USEC_INFINITY;
+
+        return s * USEC_PER_MSEC;
+}
+
+usec_t be16_sec_to_usec(be16_t t, bool max_as_infinity) {
+        uint16_t s = be16toh(t);
+
+        if (s == UINT16_MAX && max_as_infinity)
+                return USEC_INFINITY;
+
+        return s * USEC_PER_SEC;
+}
+
+be32_t usec_to_be32_sec(usec_t t) {
+        if (t == USEC_INFINITY)
+                /* Some settings, e.g. a lifetime of an address, UINT32_MAX is handled as infinity. so let's
+                 * map USEC_INFINITY to UINT32_MAX. */
+                return htobe32(UINT32_MAX);
+
+        if (t >= (UINT32_MAX - 1) * USEC_PER_SEC)
+                /* Finite but too large. Let's use the largest (or off-by-one from the largest) finite value. */
+                return htobe32(UINT32_MAX - 1);
+
+        return htobe32((uint32_t) DIV_ROUND_UP(t, USEC_PER_SEC));
+}
+
+be32_t usec_to_be32_msec(usec_t t) {
+        if (t == USEC_INFINITY)
+                return htobe32(UINT32_MAX);
+
+        if (t >= (UINT32_MAX - 1) * USEC_PER_MSEC)
+                return htobe32(UINT32_MAX - 1);
+
+        return htobe32((uint32_t) DIV_ROUND_UP(t, USEC_PER_MSEC));
+}
+
+be16_t usec_to_be16_sec(usec_t t) {
+        if (t == USEC_INFINITY)
+                return htobe16(UINT16_MAX);
+
+        if (t >= (UINT16_MAX - 1) * USEC_PER_SEC)
+                return htobe16(UINT16_MAX - 1);
+
+        return htobe16((uint16_t) DIV_ROUND_UP(t, USEC_PER_SEC));
+}
+
+usec_t time_span_to_stamp(usec_t span, usec_t base) {
+        /* Typically, 0 lifetime (timespan) indicates the corresponding configuration (address or so) must be
+         * dropped. So, when the timespan is zero, here we return 0 rather than 'base'. This makes the caller
+         * easily understand that the configuration needs to be dropped immediately. */
+        if (span == 0)
+                return 0;
+
+        return usec_add(base, span);
+}
index 2b0e3b5607615dabaffd7bd746eed3ae55ead66f..cf3d1e01304c86be14654ba108ca588ba34bb5b1 100644 (file)
@@ -2,6 +2,8 @@
 #pragma once
 
 #include "log-link.h"
+#include "sparse-endian.h"
+#include "time-util.h"
 
 #define log_interface_prefix_full_errno_zerook(prefix, type, val, error, fmt, ...) \
         ({                                                              \
         })
 
 int get_ifname(int ifindex, char **ifname);
+
+usec_t unaligned_be32_sec_to_usec(const void *p, bool max_as_infinity);
+usec_t be32_sec_to_usec(be32_t t, bool max_as_infinity);
+usec_t be32_msec_to_usec(be32_t t, bool max_as_infinity);
+usec_t be16_sec_to_usec(be16_t t, bool max_as_infinity);
+be32_t usec_to_be32_sec(usec_t t);
+be32_t usec_to_be32_msec(usec_t t);
+be16_t usec_to_be16_sec(usec_t t);
+usec_t time_span_to_stamp(usec_t span, usec_t base);
index a35311efb99c6aae392afd214bef5361a632d6ec..1226781637eb143210ffe640ab291077c4836801 100644 (file)
@@ -126,18 +126,6 @@ static bool router_lifetime_is_valid(usec_t lifetime_usec) {
                  lifetime_usec <= RADV_MAX_ROUTER_LIFETIME_USEC);
 }
 
-static be32_t usec_to_be32_sec(usec_t usec) {
-        if (usec == USEC_INFINITY)
-                /* UINT32_MAX is handled as infinity. */
-                return htobe32(UINT32_MAX);
-
-        if (usec >= UINT32_MAX * USEC_PER_SEC)
-                /* Finite but too large. Let's use the largest finite value. */
-                return htobe32(UINT32_MAX - 1);
-
-        return htobe32(usec / USEC_PER_SEC);
-}
-
 static int radv_send(sd_radv *ra, const struct in6_addr *dst, usec_t lifetime_usec) {
         struct sockaddr_in6 dst_addr = {
                 .sin6_family = AF_INET6,