From 518b6da5d3cce088fc5fff2758aac9038bbb515f Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 17 Feb 2021 17:32:54 +0900 Subject: [PATCH 1/5] in-addr-util: make in_addr_prefix_nth() returns 0 on success --- src/basic/in-addr-util.c | 26 ++++++++++++-------------- src/test/test-in-addr-util.c | 4 ++-- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/src/basic/in-addr-util.c b/src/basic/in-addr-util.c index a4f13b620a6..076b29ae9f6 100644 --- a/src/basic/in-addr-util.c +++ b/src/basic/in-addr-util.c @@ -189,8 +189,8 @@ int in_addr_prefix_intersect( int in_addr_prefix_next(int family, union in_addr_union *u, unsigned prefixlen) { assert(u); - /* Increases the network part of an address by one. Returns - * positive if that succeeds, or -ERANGE if this overflows. */ + /* Increases the network part of an address by one. Returns 0 if that succeeds, or -ERANGE if + * this overflows. */ return in_addr_prefix_nth(family, u, prefixlen, 1); } @@ -198,19 +198,18 @@ int in_addr_prefix_next(int family, union in_addr_union *u, unsigned prefixlen) /* * Calculates the nth prefix of size prefixlen starting from the address denoted by u. * - * On success 1 will be returned and the calculated prefix will be available in - * u. In the case nth == 0 the input will be left unchanged and 1 will be returned. + * On success 0 will be returned and the calculated prefix will be available in + * u. In the case nth == 0 the input will be left unchanged and 0 will be returned. * In case the calculation cannot be performed (invalid prefix length, * overflows would occur) -ERANGE is returned. If the address family given isn't * supported -EAFNOSUPPORT will be returned. * - * * Examples: - * - in_addr_prefix_nth(AF_INET, 192.168.0.0, 24, 2), returns 1, writes 192.168.2.0 to u - * - in_addr_prefix_nth(AF_INET, 192.168.0.0, 24, 0), returns 1, no data written + * - in_addr_prefix_nth(AF_INET, 192.168.0.0, 24, 2), returns 0, writes 192.168.2.0 to u + * - in_addr_prefix_nth(AF_INET, 192.168.0.0, 24, 0), returns 0, no data written * - in_addr_prefix_nth(AF_INET, 255.255.255.0, 24, 1), returns -ERANGE, no data written * - in_addr_prefix_nth(AF_INET, 255.255.255.0, 0, 1), returns -ERANGE, no data written - * - in_addr_prefix_nth(AF_INET6, 2001:db8, 64, 0xff00) returns 1, writes 2001:0db8:0000:ff00:: to u + * - in_addr_prefix_nth(AF_INET6, 2001:db8, 64, 0xff00) returns 0, writes 2001:0db8:0000:ff00:: to u */ int in_addr_prefix_nth(int family, union in_addr_union *u, unsigned prefixlen, uint64_t nth) { assert(u); @@ -219,7 +218,7 @@ int in_addr_prefix_nth(int family, union in_addr_union *u, unsigned prefixlen, u return -ERANGE; if (nth == 0) - return 1; + return 0; if (family == AF_INET) { uint32_t c, n, t; @@ -238,7 +237,7 @@ int in_addr_prefix_nth(int family, union in_addr_union *u, unsigned prefixlen, u n &= UINT32_C(0xFFFFFFFF) << (32 - prefixlen); u->in.s_addr = htobe32(n); - return 1; + return 0; } if (family == AF_INET6) { @@ -255,10 +254,9 @@ int in_addr_prefix_nth(int family, union in_addr_union *u, unsigned prefixlen, u for (unsigned i = 16; i > 0; i--) { unsigned j = i - 1; - unsigned d = 0; if (j <= start_byte) { - int16_t t; + unsigned t, d; d = delta & 0xFF; delta >>= 8; @@ -266,7 +264,7 @@ int in_addr_prefix_nth(int family, union in_addr_union *u, unsigned prefixlen, u t = u->in6.s6_addr[j] + d + overflow; overflow = t > UINT8_MAX ? t - UINT8_MAX : 0; - result.s6_addr[j] = (uint8_t)t; + result.s6_addr[j] = (uint8_t) t; } else result.s6_addr[j] = u->in6.s6_addr[j]; } @@ -275,7 +273,7 @@ int in_addr_prefix_nth(int family, union in_addr_union *u, unsigned prefixlen, u return -ERANGE; u->in6 = result; - return 1; + return 0; } return -EAFNOSUPPORT; diff --git a/src/test/test-in-addr-util.c b/src/test/test-in-addr-util.c index 2b6364566bf..beab1caf850 100644 --- a/src/test/test-in-addr-util.c +++ b/src/test/test-in-addr-util.c @@ -241,7 +241,7 @@ static void test_in_addr_prefix_next_one(unsigned f, const char *before, unsigne assert_se(in_addr_from_string(f, before, &ubefore) >= 0); t = ubefore; - assert_se((in_addr_prefix_next(f, &t, pl) > 0) == !!after); + assert_se((in_addr_prefix_next(f, &t, pl) >= 0) == !!after); if (after) { assert_se(in_addr_from_string(f, after, &uafter) >= 0); @@ -278,7 +278,7 @@ static void test_in_addr_prefix_nth_one(unsigned f, const char *before, unsigned assert_se(in_addr_from_string(f, before, &ubefore) >= 0); t = ubefore; - assert_se((in_addr_prefix_nth(f, &t, pl, nth) > 0) == !!after); + assert_se((in_addr_prefix_nth(f, &t, pl, nth) >= 0) == !!after); if (after) { assert_se(in_addr_from_string(f, after, &uafter) >= 0); From 7b6b05cff9b4927fca5e31f9faeb655e1287e3dc Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 17 Feb 2021 19:06:36 +0900 Subject: [PATCH 2/5] in-addr-util: make in_addr_prefix_nth() refuse prefixlen larger than maximum size --- src/basic/in-addr-util.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/basic/in-addr-util.c b/src/basic/in-addr-util.c index 076b29ae9f6..343f62c5dc1 100644 --- a/src/basic/in-addr-util.c +++ b/src/basic/in-addr-util.c @@ -222,8 +222,9 @@ int in_addr_prefix_nth(int family, union in_addr_union *u, unsigned prefixlen, u if (family == AF_INET) { uint32_t c, n, t; + if (prefixlen > 32) - prefixlen = 32; + return -ERANGE; c = be32toh(u->in.s_addr); @@ -247,7 +248,7 @@ int in_addr_prefix_nth(int family, union in_addr_union *u, unsigned prefixlen, u unsigned start_byte = (prefixlen - 1) / 8; if (prefixlen > 128) - prefixlen = 128; + return -ERANGE; /* First calculate what we have to add */ delta = nth << ((128 - prefixlen) % 8); From 9164338b2e6943ded69f623f2c39a46cb94d35dd Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 17 Feb 2021 20:01:26 +0900 Subject: [PATCH 3/5] in-addr-util: make in_addr_prefix_nth() always return valid prefix Previously, e.g. in_addr_prefix_nth(2400::1, prefixlen=32, nth=1) does not return 2400:1:: but does 2400:1::1. --- src/basic/in-addr-util.c | 43 +++++++++++++++--------------------- src/test/test-in-addr-util.c | 13 ++++++----- 2 files changed, 26 insertions(+), 30 deletions(-) diff --git a/src/basic/in-addr-util.c b/src/basic/in-addr-util.c index 343f62c5dc1..aa681b7bb79 100644 --- a/src/basic/in-addr-util.c +++ b/src/basic/in-addr-util.c @@ -199,8 +199,7 @@ int in_addr_prefix_next(int family, union in_addr_union *u, unsigned prefixlen) * Calculates the nth prefix of size prefixlen starting from the address denoted by u. * * On success 0 will be returned and the calculated prefix will be available in - * u. In the case nth == 0 the input will be left unchanged and 0 will be returned. - * In case the calculation cannot be performed (invalid prefix length, + * u. In case the calculation cannot be performed (invalid prefix length, * overflows would occur) -ERANGE is returned. If the address family given isn't * supported -EAFNOSUPPORT will be returned. * @@ -217,9 +216,6 @@ int in_addr_prefix_nth(int family, union in_addr_union *u, unsigned prefixlen, u if (prefixlen <= 0) return -ERANGE; - if (nth == 0) - return 0; - if (family == AF_INET) { uint32_t c, n, t; @@ -242,38 +238,35 @@ int in_addr_prefix_nth(int family, union in_addr_union *u, unsigned prefixlen, u } if (family == AF_INET6) { - struct in6_addr result = {}; - uint8_t overflow = 0; - uint64_t delta; /* this assumes that we only ever have to up to 1<<64 subnets */ - unsigned start_byte = (prefixlen - 1) / 8; + bool overflow = false; if (prefixlen > 128) return -ERANGE; - /* First calculate what we have to add */ - delta = nth << ((128 - prefixlen) % 8); - for (unsigned i = 16; i > 0; i--) { - unsigned j = i - 1; + unsigned t, j = i - 1, p = j * 8; - if (j <= start_byte) { - unsigned t, d; + if (p >= prefixlen) { + u->in6.s6_addr[j] = 0; + continue; + } - d = delta & 0xFF; - delta >>= 8; + if (prefixlen - p < 8) { + u->in6.s6_addr[j] &= 0xff << (8 - (prefixlen - p)); + t = u->in6.s6_addr[j] + ((nth & 0xff) << (8 - (prefixlen - p))); + nth >>= prefixlen - p; + } else { + t = u->in6.s6_addr[j] + (nth & 0xff) + overflow; + nth >>= 8; + } - t = u->in6.s6_addr[j] + d + overflow; - overflow = t > UINT8_MAX ? t - UINT8_MAX : 0; - - result.s6_addr[j] = (uint8_t) t; - } else - result.s6_addr[j] = u->in6.s6_addr[j]; + overflow = t > UINT8_MAX; + u->in6.s6_addr[j] = (uint8_t) (t & 0xff); } - if (overflow || delta != 0) + if (overflow || nth != 0) return -ERANGE; - u->in6 = result; return 0; } diff --git a/src/test/test-in-addr-util.c b/src/test/test-in-addr-util.c index beab1caf850..c2cf26d7206 100644 --- a/src/test/test-in-addr-util.c +++ b/src/test/test-in-addr-util.c @@ -238,6 +238,8 @@ static void test_in_addr_prefix_intersect(void) { static void test_in_addr_prefix_next_one(unsigned f, const char *before, unsigned pl, const char *after) { union in_addr_union ubefore, uafter, t; + log_info("/* %s(%s, prefixlen=%u) */", __func__, before, pl); + assert_se(in_addr_from_string(f, before, &ubefore) >= 0); t = ubefore; @@ -250,13 +252,12 @@ static void test_in_addr_prefix_next_one(unsigned f, const char *before, unsigne } static void test_in_addr_prefix_next(void) { - log_info("/* %s */", __func__); - test_in_addr_prefix_next_one(AF_INET, "192.168.0.0", 24, "192.168.1.0"); test_in_addr_prefix_next_one(AF_INET, "192.168.0.0", 16, "192.169.0.0"); test_in_addr_prefix_next_one(AF_INET, "192.168.0.0", 20, "192.168.16.0"); test_in_addr_prefix_next_one(AF_INET, "0.0.0.0", 32, "0.0.0.1"); + test_in_addr_prefix_next_one(AF_INET, "255.255.255.254", 32, "255.255.255.255"); test_in_addr_prefix_next_one(AF_INET, "255.255.255.255", 32, NULL); test_in_addr_prefix_next_one(AF_INET, "255.255.255.0", 24, NULL); @@ -275,6 +276,8 @@ static void test_in_addr_prefix_next(void) { static void test_in_addr_prefix_nth_one(unsigned f, const char *before, unsigned pl, uint64_t nth, const char *after) { union in_addr_union ubefore, uafter, t; + log_info("/* %s(%s, prefixlen=%u, nth=%"PRIu64") */", __func__, before, pl, nth); + assert_se(in_addr_from_string(f, before, &ubefore) >= 0); t = ubefore; @@ -287,10 +290,9 @@ static void test_in_addr_prefix_nth_one(unsigned f, const char *before, unsigned } static void test_in_addr_prefix_nth(void) { - log_info("/* %s */", __func__); - test_in_addr_prefix_nth_one(AF_INET, "192.168.0.0", 24, 0, "192.168.0.0"); - test_in_addr_prefix_nth_one(AF_INET, "192.168.0.0", 24, 1, "192.168.1.0"); + test_in_addr_prefix_nth_one(AF_INET, "192.168.0.123", 24, 0, "192.168.0.0"); + test_in_addr_prefix_nth_one(AF_INET, "192.168.0.123", 24, 1, "192.168.1.0"); test_in_addr_prefix_nth_one(AF_INET, "192.168.0.0", 24, 4, "192.168.4.0"); test_in_addr_prefix_nth_one(AF_INET, "192.168.0.0", 25, 1, "192.168.0.128"); test_in_addr_prefix_nth_one(AF_INET, "192.168.255.0", 25, 1, "192.168.255.128"); @@ -309,6 +311,7 @@ static void test_in_addr_prefix_nth(void) { test_in_addr_prefix_nth_one(AF_INET6, "0000::", 8, 256, NULL); test_in_addr_prefix_nth_one(AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 128, 1, NULL); test_in_addr_prefix_nth_one(AF_INET6, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0, 1, NULL); + test_in_addr_prefix_nth_one(AF_INET6, "1234:5678:90ab:cdef:1234:5678:90ab:cdef", 12, 1, "1240::"); } static void test_in_addr_to_string_one(int f, const char *addr) { From 1534c5791ae8b581df4cc8fc321cc6a757998be0 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 17 Feb 2021 22:55:01 +0900 Subject: [PATCH 4/5] in-addr-util: introduce in_addr_prefix_range() This will replace nft_in6addr_to_range() in later commit. --- src/basic/in-addr-util.c | 37 +++++++++++++++++++++++++++++++ src/basic/in-addr-util.h | 6 ++++++ src/test/test-in-addr-util.c | 42 ++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+) diff --git a/src/basic/in-addr-util.c b/src/basic/in-addr-util.c index aa681b7bb79..641c5de7a37 100644 --- a/src/basic/in-addr-util.c +++ b/src/basic/in-addr-util.c @@ -350,6 +350,43 @@ int in_addr_random_prefix( return -EAFNOSUPPORT; } +int in_addr_prefix_range( + int family, + const union in_addr_union *in, + unsigned prefixlen, + union in_addr_union *ret_start, + union in_addr_union *ret_end) { + + union in_addr_union start, end; + int r; + + assert(in); + + if (!IN_SET(family, AF_INET, AF_INET6)) + return -EAFNOSUPPORT; + + if (ret_start) { + start = *in; + r = in_addr_prefix_nth(family, &start, prefixlen, 0); + if (r < 0) + return r; + } + + if (ret_end) { + end = *in; + r = in_addr_prefix_nth(family, &end, prefixlen, 1); + if (r < 0) + return r; + } + + if (ret_start) + *ret_start = start; + if (ret_end) + *ret_end = end; + + return 0; +} + int in_addr_to_string(int family, const union in_addr_union *u, char **ret) { _cleanup_free_ char *x = NULL; size_t l; diff --git a/src/basic/in-addr-util.h b/src/basic/in-addr-util.h index 24308b702e2..a5ce8258fd9 100644 --- a/src/basic/in-addr-util.h +++ b/src/basic/in-addr-util.h @@ -41,6 +41,12 @@ int in_addr_prefix_intersect(int family, const union in_addr_union *a, unsigned int in_addr_prefix_next(int family, union in_addr_union *u, unsigned prefixlen); int in_addr_prefix_nth(int family, union in_addr_union *u, unsigned prefixlen, uint64_t nth); int in_addr_random_prefix(int family, union in_addr_union *u, unsigned prefixlen_fixed_part, unsigned prefixlen); +int in_addr_prefix_range( + int family, + const union in_addr_union *in, + unsigned prefixlen, + union in_addr_union *ret_start, + union in_addr_union *ret_end); int in_addr_to_string(int family, const union in_addr_union *u, char **ret); int in_addr_prefix_to_string(int family, const union in_addr_union *u, unsigned prefixlen, char **ret); int in_addr_port_ifindex_name_to_string(int family, const union in_addr_union *u, uint16_t port, int ifindex, const char *server_name, char **ret); diff --git a/src/test/test-in-addr-util.c b/src/test/test-in-addr-util.c index c2cf26d7206..509ea7e31e5 100644 --- a/src/test/test-in-addr-util.c +++ b/src/test/test-in-addr-util.c @@ -314,6 +314,47 @@ static void test_in_addr_prefix_nth(void) { test_in_addr_prefix_nth_one(AF_INET6, "1234:5678:90ab:cdef:1234:5678:90ab:cdef", 12, 1, "1240::"); } +static void test_in_addr_prefix_range_one( + int family, + const char *in, + unsigned prefixlen, + const char *expected_start, + const char *expected_end) { + + union in_addr_union a, s, e; + + log_info("/* %s(%s, prefixlen=%u) */", __func__, in, prefixlen); + + assert_se(in_addr_from_string(family, in, &a) >= 0); + assert_se((in_addr_prefix_range(family, &a, prefixlen, &s, &e) >= 0) == !!expected_start); + + if (expected_start) { + union in_addr_union es; + + assert_se(in_addr_from_string(family, expected_start, &es) >= 0); + assert_se(in_addr_equal(family, &s, &es) > 0); + } + if (expected_end) { + union in_addr_union ee; + + assert_se(in_addr_from_string(family, expected_end, &ee) >= 0); + assert_se(in_addr_equal(family, &e, &ee) > 0); + } +} + +static void test_in_addr_prefix_range(void) { + test_in_addr_prefix_range_one(AF_INET, "192.168.123.123", 24, "192.168.123.0", "192.168.124.0"); + test_in_addr_prefix_range_one(AF_INET, "192.168.123.123", 16, "192.168.0.0", "192.169.0.0"); + + test_in_addr_prefix_range_one(AF_INET6, "dead:beef::", 64, "dead:beef::", "dead:beef:0:1::"); + test_in_addr_prefix_range_one(AF_INET6, "dead:0:0:beef::", 64, "dead:0:0:beef::", "dead:0:0:bef0::"); + test_in_addr_prefix_range_one(AF_INET6, "2001::", 48, "2001::", "2001:0:1::"); + test_in_addr_prefix_range_one(AF_INET6, "2001::", 56, "2001::", "2001:0:0:0100::"); + test_in_addr_prefix_range_one(AF_INET6, "2001::", 65, "2001::", "2001::8000:0:0:0"); + test_in_addr_prefix_range_one(AF_INET6, "2001::", 66, "2001::", "2001::4000:0:0:0"); + test_in_addr_prefix_range_one(AF_INET6, "2001::", 127, "2001::", "2001::2"); +} + static void test_in_addr_to_string_one(int f, const char *addr) { union in_addr_union ua; _cleanup_free_ char *r = NULL; @@ -342,6 +383,7 @@ int main(int argc, char *argv[]) { test_in_addr_prefix_intersect(); test_in_addr_prefix_next(); test_in_addr_prefix_nth(); + test_in_addr_prefix_range(); test_in_addr_to_string(); return 0; From 9997507421cfe3a9bba6d09a7f1a61d24c0e7b2f Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 17 Feb 2021 22:57:10 +0900 Subject: [PATCH 5/5] firewall-util: replace nft_in6addr_to_range() with in_addr_prefix_range() --- src/shared/firewall-util-nft.c | 60 +++++----------------------- src/test/test-firewall-util.c | 73 ++-------------------------------- 2 files changed, 13 insertions(+), 120 deletions(-) diff --git a/src/shared/firewall-util-nft.c b/src/shared/firewall-util-nft.c index 6b900f0d067..05c322d353c 100644 --- a/src/shared/firewall-util-nft.c +++ b/src/shared/firewall-util-nft.c @@ -18,7 +18,6 @@ #include "firewall-util-private.h" #include "in-addr-util.h" #include "macro.h" -#include "memory-util.h" #include "socket-util.h" #include "time-util.h" @@ -30,9 +29,6 @@ #define UDP_DPORT_OFFSET 2 -void nft_in6addr_to_range(const union in_addr_union *source, unsigned int prefixlen, - struct in6_addr *start, struct in6_addr *end); - static int nfnl_netlink_sendv(sd_netlink *nfnl, sd_netlink_message *messages[], size_t msgcount) { @@ -848,55 +844,19 @@ static int fw_nftables_recreate_table(sd_netlink *nfnl, int af, sd_netlink_messa return 0; } -void nft_in6addr_to_range(const union in_addr_union *source, unsigned int prefixlen, - struct in6_addr *ret_start, struct in6_addr *ret_end) { - uint8_t carry = 0; - int i, j; +static int nft_message_add_setelem_ip6range( + sd_netlink_message *m, + const union in_addr_union *source, + unsigned int prefixlen) { - assert(prefixlen <= 128); - - for (i = 0, j = 15; i < 16; i++) { - uint8_t nm; - - nm = 0xFF; - if (prefixlen < 8) - nm = 0xFF << (8 - prefixlen); - - ret_start->s6_addr[i] = source->in6.s6_addr[i] & nm; - if (prefixlen <= 8 && j == 15) { - carry = 1u << (8 - prefixlen); - j = i; - } - - if (prefixlen >= 8) - prefixlen -= 8; - else - prefixlen = 0; - } - *ret_end = *ret_start; - - for (; j >= 0; j--) { - uint16_t overflow = ret_end->s6_addr[j] + carry; - - ret_end->s6_addr[j] = overflow; - if (overflow <= 0xff) - break; - carry = 1; - } - - if (memcmp(ret_start, ret_end, sizeof(*ret_start)) > 0) - zero(ret_end); -} - -static int nft_message_add_setelem_ip6range(sd_netlink_message *m, - const union in_addr_union *source, - unsigned int prefixlen) { - struct in6_addr start, end; + union in_addr_union start, end; int r; - nft_in6addr_to_range(source, prefixlen, &start, &end); + r = in_addr_prefix_range(AF_INET6, source, prefixlen, &start, &end); + if (r < 0) + return r; - r = sd_nfnl_nft_message_add_setelem(m, 0, &start, sizeof(start), NULL, 0); + r = sd_nfnl_nft_message_add_setelem(m, 0, &start.in6, sizeof(start.in6), NULL, 0); if (r < 0) return r; @@ -904,7 +864,7 @@ static int nft_message_add_setelem_ip6range(sd_netlink_message *m, if (r < 0) return r; - r = sd_nfnl_nft_message_add_setelem(m, 1, &end, sizeof(end), NULL, 0); + r = sd_nfnl_nft_message_add_setelem(m, 1, &end.in6, sizeof(end.in6), NULL, 0); if (r < 0) return r; diff --git a/src/test/test-firewall-util.c b/src/test/test-firewall-util.c index d5501b807d1..8d69f192d81 100644 --- a/src/test/test-firewall-util.c +++ b/src/test/test-firewall-util.c @@ -1,6 +1,4 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#include -#include #include "firewall-util.h" #include "log.h" @@ -8,32 +6,14 @@ #include "tests.h" #define MAKE_IN_ADDR_UNION(a,b,c,d) (union in_addr_union) { .in.s_addr = htobe32((uint32_t) (a) << 24 | (uint32_t) (b) << 16 | (uint32_t) (c) << 8 | (uint32_t) (d))} - -void nft_in6addr_to_range(const union in_addr_union *source, unsigned int prefixlen, - struct in6_addr *start, struct in6_addr *end); - -static void make_in6_addr_union(const char *addr, union in_addr_union *u) { - assert_se(inet_pton(AF_INET6, addr, &u->in6) >= 0); -} - -static bool test_in6_eq(const char *addr, const union in_addr_union *u) { - union in_addr_union tmp; - - make_in6_addr_union(addr, &tmp); - - return memcmp(&tmp.in6, &u->in6, sizeof(tmp.in6)) == 0; -} - -static void assert_in6_eq(const union in_addr_union *a, const union in_addr_union *b) { - assert_se(memcmp(&a->in6, &b->in6, sizeof(a->in6)) == 0); -} +#define MAKE_IN6_ADDR_UNION(str, u) assert_se(in_addr_from_string(AF_INET6, str, u) >= 0) static void test_v6(FirewallContext **ctx) { union in_addr_union u = {}, u2 = {}; uint8_t prefixlen; int r; - make_in6_addr_union("dead::beef", &u); + MAKE_IN6_ADDR_UNION("dead::beef", &u); r = fw_add_masquerade(ctx, true, AF_INET6, &u, 128); if (r < 0) @@ -55,7 +35,7 @@ static void test_v6(FirewallContext **ctx) { if (r < 0) log_error_errno(r, "Failed to modify firewall: %m"); - make_in6_addr_union("1c3::c01d", &u2); + MAKE_IN6_ADDR_UNION("1c3::c01d", &u2); r = fw_add_local_dnat(ctx, true, AF_INET6, IPPROTO_TCP, 4711, &u2, 815, &u); if (r < 0) log_error_errno(r, "Failed to modify firewall: %m"); @@ -77,52 +57,6 @@ static void test_v6(FirewallContext **ctx) { log_error_errno(r, "Failed to modify ipv6 firewall: %m"); } -static void test_v6_range(void) { - unsigned int prefixlen = 64; - union in_addr_union a, b, s; - - make_in6_addr_union("dead:0:0:beef::", &s); - - nft_in6addr_to_range(&s, prefixlen, &a.in6, &b.in6); - - assert_in6_eq(&s, &a); - assert_se(test_in6_eq("dead:0:0:bef0::", &b)); - - make_in6_addr_union("2001::", &s); - prefixlen = 56; - nft_in6addr_to_range(&s, prefixlen, &a.in6, &b.in6); - assert_in6_eq(&s, &a); - assert_se(test_in6_eq("2001:0:0:0100::", &b)); - - prefixlen = 48; - nft_in6addr_to_range(&s, prefixlen, &a.in6, &b.in6); - assert_in6_eq(&s, &a); - - assert_se(test_in6_eq("2001:0:0001::", &b)); - - prefixlen = 65; - nft_in6addr_to_range(&s, prefixlen, &a.in6, &b.in6); - assert_se(test_in6_eq("2001::", &a)); - - assert_se(test_in6_eq("2001::8000:0:0:0", &b)); - - prefixlen = 66; - nft_in6addr_to_range(&s, prefixlen, &a.in6, &b.in6); - assert_in6_eq(&s, &a); - - assert_se(test_in6_eq("2001::4000:0:0:0", &b)); - - prefixlen = 127; - nft_in6addr_to_range(&s, prefixlen, &a.in6, &b.in6); - assert_in6_eq(&s, &a); - assert_se(test_in6_eq("2001::0002", &b)); - - make_in6_addr_union("dead:beef::1", &s); - prefixlen = 64; - nft_in6addr_to_range(&s, prefixlen, &a.in6, &b.in6); - assert_se(test_in6_eq("dead:beef::", &a)); -} - int main(int argc, char *argv[]) { _cleanup_(fw_ctx_freep) FirewallContext *ctx; int r; @@ -175,7 +109,6 @@ int main(int argc, char *argv[]) { log_error_errno(r, "Failed to modify firewall: %m"); test_v6(&ctx); - test_v6_range(); return 0; }