]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: replace IPAddressAccessItem with struct in_addr_prefix
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 10 Sep 2021 04:58:28 +0000 (13:58 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 14 Sep 2021 11:30:09 +0000 (20:30 +0900)
Previously, if a unit file which contains n IPAddressAllow/Deny= lines,
then the computational order of parsing the file was O(n^3), as
ip_address_access_reduce(), whose order is O(n^2), is called for each line.

By replacing in_addr_prefix related functions, now the computational
order is O(n log n).

Fixes #20680.

12 files changed:
src/analyze/analyze-security.c
src/core/bpf-firewall.c
src/core/cgroup.c
src/core/cgroup.h
src/core/dbus-cgroup.c
src/core/ip-address-access.c [deleted file]
src/core/ip-address-access.h [deleted file]
src/core/load-fragment-gperf.gperf.in
src/core/manager.h
src/core/meson.build
src/core/unit.h
src/test/test-bpf-firewall.c

index c674961001101ddf2103c3657312770908b8a81d..400eebbda8a99781b6205b587ac0b58fc38dc140 100644 (file)
@@ -11,7 +11,7 @@
 #include "bus-util.h"
 #include "env-util.h"
 #include "format-table.h"
-#include "in-addr-util.h"
+#include "in-addr-prefix-util.h"
 #include "locale-util.h"
 #include "macro.h"
 #include "manager.h"
@@ -2582,10 +2582,10 @@ static int get_security_info(Unit *u, ExecContext *c, CGroupContext *g, Security
                                 return log_oom();
                 }
 
-                IPAddressAccessItem *i;
+                struct in_addr_prefix *i;
                 bool deny_ipv4 = false, deny_ipv6 = false;
 
-                LIST_FOREACH(items, i, g->ip_address_deny) {
+                SET_FOREACH(i, g->ip_address_deny) {
                         if (i->family == AF_INET && i->prefixlen == 0)
                                 deny_ipv4 = true;
                         else if (i->family == AF_INET6 && i->prefixlen == 0)
@@ -2594,7 +2594,7 @@ static int get_security_info(Unit *u, ExecContext *c, CGroupContext *g, Security
                 info->ip_address_deny_all = deny_ipv4 && deny_ipv6;
 
                 info->ip_address_allow_localhost = info->ip_address_allow_other = false;
-                LIST_FOREACH(items, i, g->ip_address_allow) {
+                SET_FOREACH(i, g->ip_address_allow) {
                         if (in_addr_is_localhost(i->family, &i->address))
                                 info->ip_address_allow_localhost = true;
                         else
index 9317edeb4cea558401a81c8e67ddb51380bb27d3..d23b43bcb24b9bc6d719718f5b5fe37950d24b57 100644 (file)
@@ -18,7 +18,7 @@
 #include "bpf-firewall.h"
 #include "bpf-program.h"
 #include "fd-util.h"
-#include "ip-address-access.h"
+#include "in-addr-prefix-util.h"
 #include "memory-util.h"
 #include "missing_syscall.h"
 #include "unit.h"
@@ -335,13 +335,13 @@ static int bpf_firewall_compile_bpf(
         return 0;
 }
 
-static int bpf_firewall_count_access_items(IPAddressAccessItem *list, size_t *n_ipv4, size_t *n_ipv6) {
-        IPAddressAccessItem *a;
+static int bpf_firewall_count_access_items(Set *prefixes, size_t *n_ipv4, size_t *n_ipv6) {
+        struct in_addr_prefix *a;
 
         assert(n_ipv4);
         assert(n_ipv6);
 
-        LIST_FOREACH(items, a, list) {
+        SET_FOREACH(a, prefixes)
                 switch (a->family) {
 
                 case AF_INET:
@@ -355,26 +355,25 @@ static int bpf_firewall_count_access_items(IPAddressAccessItem *list, size_t *n_
                 default:
                         return -EAFNOSUPPORT;
                 }
-        }
 
         return 0;
 }
 
 static int bpf_firewall_add_access_items(
-                IPAddressAccessItem *list,
+                Set *prefixes,
                 int ipv4_map_fd,
                 int ipv6_map_fd,
                 int verdict) {
 
         struct bpf_lpm_trie_key *key_ipv4, *key_ipv6;
+        struct in_addr_prefix *a;
         uint64_t value = verdict;
-        IPAddressAccessItem *a;
         int r;
 
         key_ipv4 = alloca0(offsetof(struct bpf_lpm_trie_key, data) + sizeof(uint32_t));
         key_ipv6 = alloca0(offsetof(struct bpf_lpm_trie_key, data) + sizeof(uint32_t) * 4);
 
-        LIST_FOREACH(items, a, list) {
+        SET_FOREACH(a, prefixes)
                 switch (a->family) {
 
                 case AF_INET:
@@ -400,7 +399,6 @@ static int bpf_firewall_add_access_items(
                 default:
                         return -EAFNOSUPPORT;
                 }
-        }
 
         return 0;
 }
@@ -414,7 +412,6 @@ static int bpf_firewall_prepare_access_maps(
 
         _cleanup_close_ int ipv4_map_fd = -1, ipv6_map_fd = -1;
         size_t n_ipv4 = 0, n_ipv6 = 0;
-        IPAddressAccessItem *list;
         Unit *p;
         int r;
 
@@ -424,18 +421,29 @@ static int bpf_firewall_prepare_access_maps(
 
         for (p = u; p; p = UNIT_GET_SLICE(p)) {
                 CGroupContext *cc;
+                Set *prefixes;
+                bool *reduced;
 
                 cc = unit_get_cgroup_context(p);
                 if (!cc)
                         continue;
 
-                list = verdict == ACCESS_ALLOWED ? cc->ip_address_allow : cc->ip_address_deny;
+                prefixes = verdict == ACCESS_ALLOWED ? cc->ip_address_allow : cc->ip_address_deny;
+                reduced = verdict == ACCESS_ALLOWED ? &cc->ip_address_allow_reduced : &cc->ip_address_deny_reduced;
+
+                if (!*reduced) {
+                        r = in_addr_prefixes_reduce(prefixes);
+                        if (r < 0)
+                                return r;
+
+                        *reduced = true;
+                }
 
-                bpf_firewall_count_access_items(list, &n_ipv4, &n_ipv6);
+                bpf_firewall_count_access_items(prefixes, &n_ipv4, &n_ipv6);
 
                 /* Skip making the LPM trie map in cases where we are using "any" in order to hack around
                  * needing CAP_SYS_ADMIN for allocating LPM trie map. */
-                if (ip_address_access_item_is_any(list)) {
+                if (in_addr_prefixes_is_any(prefixes)) {
                         *ret_has_any = true;
                         return 0;
                 }
index 52bdf54b5fb690159326b1b94134dda8c7474227..2d136793f90dee1365f1ff2e3abc500f5609a72a 100644 (file)
@@ -19,6 +19,7 @@
 #include "fd-util.h"
 #include "fileio.h"
 #include "fs-util.h"
+#include "in-addr-prefix-util.h"
 #include "io-util.h"
 #include "ip-protocol-list.h"
 #include "limits-util.h"
@@ -238,8 +239,8 @@ void cgroup_context_done(CGroupContext *c) {
         cgroup_context_remove_socket_bind(&c->socket_bind_allow);
         cgroup_context_remove_socket_bind(&c->socket_bind_deny);
 
-        c->ip_address_allow = ip_address_access_free_all(c->ip_address_allow);
-        c->ip_address_deny = ip_address_access_free_all(c->ip_address_deny);
+        c->ip_address_allow = set_free(c->ip_address_allow);
+        c->ip_address_deny = set_free(c->ip_address_deny);
 
         c->ip_filters_ingress = strv_free(c->ip_filters_ingress);
         c->ip_filters_egress = strv_free(c->ip_filters_egress);
@@ -395,7 +396,7 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
         CGroupDeviceAllow *a;
         CGroupContext *c;
         CGroupSocketBindItem *bi;
-        IPAddressAccessItem *iaai;
+        struct in_addr_prefix *iaai;
         char **path;
 
         char cda[FORMAT_CGROUP_DIFF_MAX];
@@ -549,18 +550,18 @@ void cgroup_context_dump(Unit *u, FILE* f, const char *prefix) {
                                 FORMAT_BYTES(b->wbps));
         }
 
-        LIST_FOREACH(items, iaai, c->ip_address_allow) {
+        SET_FOREACH(iaai, c->ip_address_allow) {
                 _cleanup_free_ char *k = NULL;
 
-                (void) in_addr_to_string(iaai->family, &iaai->address, &k);
-                fprintf(f, "%sIPAddressAllow: %s/%u\n", prefix, strnull(k), iaai->prefixlen);
+                (void) in_addr_prefix_to_string(iaai->family, &iaai->address, iaai->prefixlen, &k);
+                fprintf(f, "%sIPAddressAllow: %s\n", prefix, strnull(k));
         }
 
-        LIST_FOREACH(items, iaai, c->ip_address_deny) {
+        SET_FOREACH(iaai, c->ip_address_deny) {
                 _cleanup_free_ char *k = NULL;
 
-                (void) in_addr_to_string(iaai->family, &iaai->address, &k);
-                fprintf(f, "%sIPAddressDeny: %s/%u\n", prefix, strnull(k), iaai->prefixlen);
+                (void) in_addr_prefix_to_string(iaai->family, &iaai->address, iaai->prefixlen, &k);
+                fprintf(f, "%sIPAddressDeny: %s\n", prefix, strnull(k));
         }
 
         STRV_FOREACH(path, c->ip_filters_ingress)
@@ -1555,8 +1556,8 @@ static bool unit_get_needs_bpf_firewall(Unit *u) {
                 return false;
 
         if (c->ip_accounting ||
-            c->ip_address_allow ||
-            c->ip_address_deny ||
+            !set_isempty(c->ip_address_allow) ||
+            !set_isempty(c->ip_address_deny) ||
             c->ip_filters_ingress ||
             c->ip_filters_egress)
                 return true;
@@ -1567,8 +1568,8 @@ static bool unit_get_needs_bpf_firewall(Unit *u) {
                 if (!c)
                         return false;
 
-                if (c->ip_address_allow ||
-                    c->ip_address_deny)
+                if (!set_isempty(c->ip_address_allow) ||
+                    !set_isempty(c->ip_address_deny))
                         return true;
         }
 
index 5b55dd7121bf6c005ab2aeb64bc677ec612587ae..9bb968b6c15d1cd8efdac90290f4706df85a8023 100644 (file)
@@ -5,7 +5,6 @@
 
 #include "cgroup-util.h"
 #include "cpu-set-util.h"
-#include "ip-address-access.h"
 #include "list.h"
 #include "time-util.h"
 
@@ -153,8 +152,12 @@ struct CGroupContext {
         bool memory_min_set:1;
         bool memory_low_set:1;
 
-        LIST_HEAD(IPAddressAccessItem, ip_address_allow);
-        LIST_HEAD(IPAddressAccessItem, ip_address_deny);
+        Set *ip_address_allow;
+        Set *ip_address_deny;
+        /* These two flags indicate that redundant entries have been removed from
+         * ip_address_allow/ip_address_deny, i.e. in_addr_prefixes_reduce() has already been called. */
+        bool ip_address_allow_reduced;
+        bool ip_address_deny_reduced;
 
         char **ip_filters_ingress;
         char **ip_filters_egress;
index 75efa9fe1f37836140a4d16ebc730b43b33e708c..ef7d529de9bef509e999b558f0aed8fd58d3205f 100644 (file)
@@ -15,6 +15,7 @@
 #include "errno-util.h"
 #include "fd-util.h"
 #include "fileio.h"
+#include "in-addr-prefix-util.h"
 #include "ip-protocol-list.h"
 #include "limits-util.h"
 #include "parse-util.h"
@@ -318,14 +319,17 @@ static int property_get_ip_address_access(
                 void *userdata,
                 sd_bus_error *error) {
 
-        IPAddressAccessItem** items = userdata, *i;
+        Set **prefixes = userdata;
+        struct in_addr_prefix *i;
         int r;
 
+        assert(prefixes);
+
         r = sd_bus_message_open_container(reply, 'a', "(iayu)");
         if (r < 0)
                 return r;
 
-        LIST_FOREACH(items, i, *items) {
+        SET_FOREACH(i, *prefixes) {
 
                 r = sd_bus_message_open_container(reply, 'r', "iayu");
                 if (r < 0)
@@ -1745,11 +1749,9 @@ int bus_cgroup_set_property(
                 return 1;
 
         } else if (STR_IN_SET(name, "IPAddressAllow", "IPAddressDeny")) {
-                IPAddressAccessItem **list;
+                _cleanup_set_free_ Set *new_prefixes = NULL;
                 size_t n = 0;
 
-                list = streq(name, "IPAddressAllow") ? &c->ip_address_allow : &c->ip_address_deny;
-
                 r = sd_bus_message_enter_container(message, 'a', "(iayu)");
                 if (r < 0)
                         return r;
@@ -1789,17 +1791,16 @@ int bus_cgroup_set_property(
                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Prefix length %" PRIu32 " too large for address family %s.", prefixlen, af_to_name(family));
 
                         if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
-                                IPAddressAccessItem *item;
-
-                                item = new0(IPAddressAccessItem, 1);
-                                if (!item)
-                                        return -ENOMEM;
+                                struct in_addr_prefix prefix = {
+                                        .family = family,
+                                        .prefixlen = prefixlen,
+                                };
 
-                                item->family = family;
-                                item->prefixlen = prefixlen;
-                                memcpy(&item->address, ap, an);
+                                memcpy(&prefix.address, ap, an);
 
-                                LIST_PREPEND(items, *list, item);
+                                r = in_addr_prefix_add(&new_prefixes, &prefix);
+                                if (r < 0)
+                                        return r;
                         }
 
                         r = sd_bus_message_exit_container(message);
@@ -1813,33 +1814,46 @@ int bus_cgroup_set_property(
                 if (r < 0)
                         return r;
 
-                *list = ip_address_access_reduce(*list);
-
                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
                         _cleanup_free_ char *buf = NULL;
                         _cleanup_fclose_ FILE *f = NULL;
-                        IPAddressAccessItem *item;
                         size_t size = 0;
-
-                        if (n == 0)
-                                *list = ip_address_access_free_all(*list);
+                        Set **prefixes;
+                        bool *reduced;
 
                         unit_invalidate_cgroup_bpf(u);
                         f = open_memstream_unlocked(&buf, &size);
                         if (!f)
                                 return -ENOMEM;
 
-                        fputs(name, f);
-                        fputs("=\n", f);
+                        prefixes = streq(name, "IPAddressAllow") ? &c->ip_address_allow : &c->ip_address_deny;
+                        reduced = streq(name, "IPAddressAllow") ? &c->ip_address_allow_reduced : &c->ip_address_deny_reduced;
+
+                        if (n == 0) {
+                                *reduced = true;
+                                *prefixes = set_free(*prefixes);
+                                fputs(name, f);
+                                fputs("=\n", f);
+                        } else {
+                                struct in_addr_prefix *p;
+
+                                *reduced = false;
 
-                        LIST_FOREACH(items, item, *list) {
-                                char buffer[CONST_MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN)];
+                                r = in_addr_prefixes_merge(prefixes, new_prefixes);
+                                if (r < 0)
+                                        return r;
 
-                                errno = 0;
-                                if (!inet_ntop(item->family, &item->address, buffer, sizeof(buffer)))
-                                        return errno_or_else(EINVAL);
+                                SET_FOREACH(p, new_prefixes) {
+                                        _cleanup_free_ char *buffer = NULL;
 
-                                fprintf(f, "%s=%s/%u\n", name, buffer, item->prefixlen);
+                                        r = in_addr_prefix_to_string(p->family, &p->address, p->prefixlen, &buffer);
+                                        if (r == -ENOMEM)
+                                                return r;
+                                        if (r < 0)
+                                                continue;
+
+                                        fprintf(f, "%s=%s\n", name, buffer);
+                                }
                         }
 
                         r = fflush_and_check(f);
diff --git a/src/core/ip-address-access.c b/src/core/ip-address-access.c
deleted file mode 100644 (file)
index a11251e..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "alloc-util.h"
-#include "bpf-firewall.h"
-#include "extract-word.h"
-#include "hostname-util.h"
-#include "ip-address-access.h"
-#include "parse-util.h"
-#include "string-util.h"
-
-int config_parse_ip_address_access(
-                const char *unit,
-                const char *filename,
-                unsigned line,
-                const char *section,
-                unsigned section_line,
-                const char *lvalue,
-                int ltype,
-                const char *rvalue,
-                void *data,
-                void *userdata) {
-
-        IPAddressAccessItem **list = data;
-        const char *p;
-        int r;
-
-        assert(list);
-
-        if (isempty(rvalue)) {
-                *list = ip_address_access_free_all(*list);
-                return 0;
-        }
-
-        p = rvalue;
-
-        for (;;) {
-                _cleanup_free_ IPAddressAccessItem *a = NULL;
-                _cleanup_free_ char *word = NULL;
-
-                r = extract_first_word(&p, &word, NULL, 0);
-                if (r == 0)
-                        break;
-                if (r == -ENOMEM)
-                        return log_oom();
-                if (r < 0) {
-                        log_syntax(unit, LOG_WARNING, filename, line, r, "Invalid syntax, ignoring: %s", rvalue);
-                        break;
-                }
-
-                a = new0(IPAddressAccessItem, 1);
-                if (!a)
-                        return log_oom();
-
-                if (streq(word, "any")) {
-                        /* "any" is a shortcut for 0.0.0.0/0 and ::/0 */
-
-                        a->family = AF_INET;
-                        LIST_APPEND(items, *list, a);
-
-                        a = new0(IPAddressAccessItem, 1);
-                        if (!a)
-                                return log_oom();
-
-                        a->family = AF_INET6;
-
-                } else if (is_localhost(word)) {
-                        /* "localhost" is a shortcut for 127.0.0.0/8 and ::1/128 */
-
-                        a->family = AF_INET;
-                        a->address.in.s_addr = htobe32(0x7f000000);
-                        a->prefixlen = 8;
-                        LIST_APPEND(items, *list, a);
-
-                        a = new0(IPAddressAccessItem, 1);
-                        if (!a)
-                                return log_oom();
-
-                        a->family = AF_INET6;
-                        a->address.in6 = (struct in6_addr) IN6ADDR_LOOPBACK_INIT;
-                        a->prefixlen = 128;
-
-                } else if (streq(word, "link-local")) {
-
-                        /* "link-local" is a shortcut for 169.254.0.0/16 and fe80::/64 */
-
-                        a->family = AF_INET;
-                        a->address.in.s_addr = htobe32((UINT32_C(169) << 24 | UINT32_C(254) << 16));
-                        a->prefixlen = 16;
-                        LIST_APPEND(items, *list, a);
-
-                        a = new0(IPAddressAccessItem, 1);
-                        if (!a)
-                                return log_oom();
-
-                        a->family = AF_INET6;
-                        a->address.in6 = (struct in6_addr) {
-                                .s6_addr32[0] = htobe32(0xfe800000)
-                        };
-                        a->prefixlen = 64;
-
-                } else if (streq(word, "multicast")) {
-
-                        /* "multicast" is a shortcut for 224.0.0.0/4 and ff00::/8 */
-
-                        a->family = AF_INET;
-                        a->address.in.s_addr = htobe32((UINT32_C(224) << 24));
-                        a->prefixlen = 4;
-                        LIST_APPEND(items, *list, a);
-
-                        a = new0(IPAddressAccessItem, 1);
-                        if (!a)
-                                return log_oom();
-
-                        a->family = AF_INET6;
-                        a->address.in6 = (struct in6_addr) {
-                                .s6_addr32[0] = htobe32(0xff000000)
-                        };
-                        a->prefixlen = 8;
-
-                } else {
-                        r = in_addr_prefix_from_string_auto(word, &a->family, &a->address, &a->prefixlen);
-                        if (r < 0) {
-                                log_syntax(unit, LOG_WARNING, filename, line, r, "Address prefix is invalid, ignoring assignment: %s", word);
-                                return 0;
-                        }
-                }
-
-                LIST_APPEND(items, *list, a);
-                a = NULL;
-        }
-
-        *list = ip_address_access_reduce(*list);
-
-        return 0;
-}
-
-IPAddressAccessItem* ip_address_access_free_all(IPAddressAccessItem *first) {
-        IPAddressAccessItem *next, *p = first;
-
-        while (p) {
-                next = p->items_next;
-                free(p);
-
-                p = next;
-        }
-
-        return NULL;
-}
-
-IPAddressAccessItem* ip_address_access_reduce(IPAddressAccessItem *first) {
-        IPAddressAccessItem *a, *b, *tmp;
-        int r;
-
-        /* Drops all entries from the list that are covered by another entry in full, thus removing all redundant
-         * entries. */
-
-        LIST_FOREACH_SAFE(items, a, tmp, first) {
-
-                /* Drop irrelevant bits */
-                (void) in_addr_mask(a->family, &a->address, a->prefixlen);
-
-                LIST_FOREACH(items, b, first) {
-
-                        if (a == b)
-                                continue;
-
-                        if (a->family != b->family)
-                                continue;
-
-                        if (b->prefixlen > a->prefixlen)
-                                continue;
-
-                        r = in_addr_prefix_covers(b->family,
-                                                  &b->address,
-                                                  b->prefixlen,
-                                                  &a->address);
-                        if (r > 0) {
-                                /* b covers a fully, then let's drop a */
-                                LIST_REMOVE(items, first, a);
-                                free(a);
-                                break;
-                        }
-                }
-        }
-
-        return first;
-}
-
-bool ip_address_access_item_is_any(IPAddressAccessItem *first) {
-        /* Check for exactly two entries */
-        if (!first || !first->items_next || first->items_next->items_next)
-                return false;
-
-        /* Check both entries cover the full range */
-        if (first->prefixlen != 0 || first->items_next->prefixlen != 0)
-                return false;
-
-        /* Check that one of them is the IPv4 and the other IPv6 */
-        if (!((first->family == AF_INET && first->items_next->family == AF_INET6) ||
-                                (first->family == AF_INET6 && first->items_next->family == AF_INET)))
-                return false;
-
-        /* No need to check the actual addresses, they don't matter if the prefix is zero */
-        return true;
-}
diff --git a/src/core/ip-address-access.h b/src/core/ip-address-access.h
deleted file mode 100644 (file)
index 71b5459..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-#pragma once
-
-#include "conf-parser.h"
-#include "in-addr-util.h"
-#include "list.h"
-
-typedef struct IPAddressAccessItem IPAddressAccessItem;
-
-struct IPAddressAccessItem {
-        int family;
-        unsigned char prefixlen;
-        union in_addr_union address;
-        LIST_FIELDS(IPAddressAccessItem, items);
-};
-
-CONFIG_PARSER_PROTOTYPE(config_parse_ip_address_access);
-
-IPAddressAccessItem* ip_address_access_free_all(IPAddressAccessItem *first);
-
-IPAddressAccessItem* ip_address_access_reduce(IPAddressAccessItem *first);
-
-/* Returns true if a list consists of only the two items necessary for "any"
- * (0.0.0.0/0 and ::/0). */
-bool ip_address_access_item_is_any(IPAddressAccessItem *first);
index 489841af7a73bf1302d25a6c4e3d58d020230e9a..b3dc3bc0fcb10c9921f80d68a44fd921bce1aa7c 100644 (file)
 {{type}}.Delegate,                         config_parse_delegate,                       0,                                  offsetof({{type}}, cgroup_context)
 {{type}}.DisableControllers,               config_parse_disable_controllers,            0,                                  offsetof({{type}}, cgroup_context)
 {{type}}.IPAccounting,                     config_parse_bool,                           0,                                  offsetof({{type}}, cgroup_context.ip_accounting)
-{{type}}.IPAddressAllow,                   config_parse_ip_address_access,              0,                                  offsetof({{type}}, cgroup_context.ip_address_allow)
-{{type}}.IPAddressDeny,                    config_parse_ip_address_access,              0,                                  offsetof({{type}}, cgroup_context.ip_address_deny)
+{{type}}.IPAddressAllow,                   config_parse_in_addr_prefixes,               AF_UNSPEC,                          offsetof({{type}}, cgroup_context.ip_address_allow)
+{{type}}.IPAddressDeny,                    config_parse_in_addr_prefixes,               AF_UNSPEC,                          offsetof({{type}}, cgroup_context.ip_address_deny)
 {{type}}.IPIngressFilterPath,              config_parse_ip_filter_bpf_progs,            0,                                  offsetof({{type}}, cgroup_context.ip_filters_ingress)
 {{type}}.IPEgressFilterPath,               config_parse_ip_filter_bpf_progs,            0,                                  offsetof({{type}}, cgroup_context.ip_filters_egress)
 {{type}}.ManagedOOMSwap,                   config_parse_managed_oom_mode,               0,                                  offsetof({{type}}, cgroup_context.moom_swap)
@@ -243,6 +243,7 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
 #include <stddef.h>
 #include "all-units.h"
 #include "conf-parser.h"
+#include "in-addr-prefix-util.h"
 #include "load-fragment.h"
 %}
 struct ConfigPerfItem;
index 1220c9fb1610b24fca71f2169f1788ab7c70f543..4234e187fdf82c269ee8024cf64f75417ebb4c3a 100644 (file)
@@ -12,7 +12,6 @@
 #include "cgroup.h"
 #include "fdset.h"
 #include "hashmap.h"
-#include "ip-address-access.h"
 #include "list.h"
 #include "prioq.h"
 #include "ratelimit.h"
index 87a15ec71aec8bdfd5324c4ccbd4279b68477ba7..d36be869ce7ecfd2d0ca35ad2baff788992b9c72 100644 (file)
@@ -71,8 +71,6 @@ libcore_sources = '''
         generator-setup.h
         ima-setup.c
         ima-setup.h
-        ip-address-access.c
-        ip-address-access.h
         job.c
         job.h
         kill.c
index 80d56aefc1cc985989b2c447839d368e17379d7c..c8e99acf703974604e047b4249279f37d5d048ce 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <stdbool.h>
 #include <stdlib.h>
+#include <sys/socket.h>
 #include <unistd.h>
 
 #include "sd-id128.h"
index 8b7d46bee3f8d4b9aead3c77c5d8a551cde55439..1e0ad177b9956616fa9e49b2677bb19e6860e4db 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "bpf-firewall.h"
 #include "bpf-program.h"
+#include "in-addr-prefix-util.h"
 #include "load-fragment.h"
 #include "manager.h"
 #include "memory-util.h"
@@ -106,21 +107,39 @@ int main(int argc, char *argv[]) {
 
         cc->ip_accounting = true;
 
-        assert_se(config_parse_ip_address_access(u->id, "filename", 1, "Service", 1, "IPAddressAllow", 0, "10.0.1.0/24", &cc->ip_address_allow, NULL) == 0);
-        assert_se(config_parse_ip_address_access(u->id, "filename", 1, "Service", 1, "IPAddressAllow", 0, "127.0.0.2", &cc->ip_address_allow, NULL) == 0);
-        assert_se(config_parse_ip_address_access(u->id, "filename", 1, "Service", 1, "IPAddressDeny", 0, "127.0.0.3", &cc->ip_address_deny, NULL) == 0);
-        assert_se(config_parse_ip_address_access(u->id, "filename", 1, "Service", 1, "IPAddressDeny", 0, "10.0.3.2/24", &cc->ip_address_deny, NULL) == 0);
-        assert_se(config_parse_ip_address_access(u->id, "filename", 1, "Service", 1, "IPAddressDeny", 0, "127.0.0.1/25", &cc->ip_address_deny, NULL) == 0);
-        assert_se(config_parse_ip_address_access(u->id, "filename", 1, "Service", 1, "IPAddressDeny", 0, "127.0.0.4", &cc->ip_address_deny, NULL) == 0);
-
-        assert(cc->ip_address_allow);
-        assert(cc->ip_address_allow->items_next);
-        assert(!cc->ip_address_allow->items_next->items_next);
-
-        /* The deny list is defined redundantly, let's ensure it got properly reduced */
-        assert(cc->ip_address_deny);
-        assert(cc->ip_address_deny->items_next);
-        assert(!cc->ip_address_deny->items_next->items_next);
+        assert_se(config_parse_in_addr_prefixes(u->id, "filename", 1, "Service", 1, "IPAddressAllow", 0, "10.0.1.0/24", &cc->ip_address_allow, NULL) == 0);
+        assert_se(config_parse_in_addr_prefixes(u->id, "filename", 1, "Service", 1, "IPAddressAllow", 0, "127.0.0.2", &cc->ip_address_allow, NULL) == 0);
+        assert_se(config_parse_in_addr_prefixes(u->id, "filename", 1, "Service", 1, "IPAddressDeny", 0, "127.0.0.3", &cc->ip_address_deny, NULL) == 0);
+        assert_se(config_parse_in_addr_prefixes(u->id, "filename", 1, "Service", 1, "IPAddressDeny", 0, "10.0.3.2/24", &cc->ip_address_deny, NULL) == 0);
+        assert_se(config_parse_in_addr_prefixes(u->id, "filename", 1, "Service", 1, "IPAddressDeny", 0, "127.0.0.1/25", &cc->ip_address_deny, NULL) == 0);
+        assert_se(config_parse_in_addr_prefixes(u->id, "filename", 1, "Service", 1, "IPAddressDeny", 0, "127.0.0.4", &cc->ip_address_deny, NULL) == 0);
+
+        assert_se(set_size(cc->ip_address_allow) == 2);
+        assert_se(set_size(cc->ip_address_deny) == 4);
+
+        /* The deny list is defined redundantly, let's ensure it will be properly reduced */
+        assert_se(in_addr_prefixes_reduce(cc->ip_address_allow) >= 0);
+        assert_se(in_addr_prefixes_reduce(cc->ip_address_deny) >= 0);
+
+        assert_se(set_size(cc->ip_address_allow) == 2);
+        assert_se(set_size(cc->ip_address_deny) == 2);
+
+        assert_se(set_contains(cc->ip_address_allow, &(struct in_addr_prefix) {
+                                .family = AF_INET,
+                                .address.in.s_addr = htobe32((UINT32_C(10) << 24) | (UINT32_C(1) << 8)),
+                                .prefixlen = 24 }));
+        assert_se(set_contains(cc->ip_address_allow, &(struct in_addr_prefix) {
+                                .family = AF_INET,
+                                .address.in.s_addr = htobe32(0x7f000002),
+                                .prefixlen = 32 }));
+        assert_se(set_contains(cc->ip_address_deny, &(struct in_addr_prefix) {
+                                .family = AF_INET,
+                                .address.in.s_addr = htobe32(0x7f000000),
+                                .prefixlen = 25 }));
+        assert_se(set_contains(cc->ip_address_deny, &(struct in_addr_prefix) {
+                                .family = AF_INET,
+                                .address.in.s_addr = htobe32((UINT32_C(10) << 24) | (UINT32_C(3) << 8)),
+                                .prefixlen = 24 }));
 
         assert_se(config_parse_exec(u->id, "filename", 1, "Service", 1, "ExecStart", SERVICE_EXEC_START, "/bin/ping -c 1 127.0.0.2 -W 5", SERVICE(u)->exec_command, u) == 0);
         assert_se(config_parse_exec(u->id, "filename", 1, "Service", 1, "ExecStart", SERVICE_EXEC_START, "/bin/ping -c 1 127.0.0.3 -W 5", SERVICE(u)->exec_command, u) == 0);