From: Yu Watanabe Date: Wed, 17 Feb 2021 13:57:10 +0000 (+0900) Subject: firewall-util: replace nft_in6addr_to_range() with in_addr_prefix_range() X-Git-Tag: v248-rc1~79^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9997507421cfe3a9bba6d09a7f1a61d24c0e7b2f;p=thirdparty%2Fsystemd.git firewall-util: replace nft_in6addr_to_range() with in_addr_prefix_range() --- 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; - - 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) { -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; }