summaryrefslogtreecommitdiffstats
path: root/src/core/ip-address-access.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2017-09-05 17:41:34 +0200
committerLennart Poettering <lennart@poettering.net>2017-09-22 15:24:55 +0200
commit1274b6c68759be1b06140d13e5ec3a0ce3967e94 (patch)
tree6c129d674b1ee28d684b011f442d2349bb44bd5e /src/core/ip-address-access.c
parentmkosi: when the build fails, show its log output, and propagate error (diff)
downloadsystemd-1274b6c68759be1b06140d13e5ec3a0ce3967e94.tar.xz
systemd-1274b6c68759be1b06140d13e5ec3a0ce3967e94.zip
ip-address-access: minimize IP address lists
Let's drop redundant items from the IP address list after parsing. Let's also mask out redundant bits hidden by the prefixlength.
Diffstat (limited to 'src/core/ip-address-access.c')
-rw-r--r--src/core/ip-address-access.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/core/ip-address-access.c b/src/core/ip-address-access.c
index 6a89bb23c1..18d28708be 100644
--- a/src/core/ip-address-access.c
+++ b/src/core/ip-address-access.c
@@ -148,6 +148,8 @@ int config_parse_ip_address_access(
a = NULL;
}
+ *list = ip_address_access_reduce(*list);
+
return 0;
}
@@ -163,3 +165,43 @@ IPAddressAccessItem* ip_address_access_free_all(IPAddressAccessItem *first) {
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)
+ continue;
+
+ /* b covers a fully, then let's drop a */
+
+ LIST_REMOVE(items, first, a);
+ free(a);
+ }
+ }
+
+ return first;
+}