]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
firewall-util: replace nft_in6addr_to_range() with in_addr_prefix_range() 18653/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 17 Feb 2021 13:57:10 +0000 (22:57 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 17 Feb 2021 13:57:37 +0000 (22:57 +0900)
src/shared/firewall-util-nft.c
src/test/test-firewall-util.c

index 6b900f0d067b1bb5e6b276d942de96ddd4548495..05c322d353cae5a2e8e82651f6e27d9663c97145 100644 (file)
@@ -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;
 
index d5501b807d17eb80120202f715c9fda018d34230..8d69f192d81dcacdfa0401a0e15198ef05a2f73e 100644 (file)
@@ -1,6 +1,4 @@
 /* SPDX-License-Identifier: LGPL-2.1-or-later */
-#include <arpa/inet.h>
-#include <stdlib.h>
 
 #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;
 }