From 0abafedb9a4997d1463927528fef85d7c3ab32d8 Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Wed, 21 Oct 2020 08:06:59 -0600 Subject: [PATCH 01/20] interface: add lif_interface::is_explicit --- libifupdown/interface.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libifupdown/interface.h b/libifupdown/interface.h index c86efdc..0c6d8b2 100644 --- a/libifupdown/interface.h +++ b/libifupdown/interface.h @@ -50,6 +50,7 @@ struct lif_interface { bool is_bond; bool is_template; bool is_pending; + bool is_explicit; bool has_config_error; /* error found in interface configuration */ From 0d28f94a476068614c92801637eb40decea5d0e6 Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Wed, 21 Oct 2020 08:09:21 -0600 Subject: [PATCH 02/20] interface: auto interfaces are always explicit --- libifupdown/interface-file.c | 3 +++ libifupdown/interface.c | 1 + 2 files changed, 4 insertions(+) diff --git a/libifupdown/interface-file.c b/libifupdown/interface-file.c index d2e88ac..6481be8 100644 --- a/libifupdown/interface-file.c +++ b/libifupdown/interface-file.c @@ -172,6 +172,9 @@ handle_auto(struct lif_interface_file_parse_state *state, char *token, char *buf if (!state->cur_iface->is_template) state->cur_iface->is_auto = true; + if (state->cur_iface->is_auto) + state->cur_iface->is_explicit = true; + return true; } diff --git a/libifupdown/interface.c b/libifupdown/interface.c index 532edba..7e96bcd 100644 --- a/libifupdown/interface.c +++ b/libifupdown/interface.c @@ -223,6 +223,7 @@ lif_interface_collection_init(struct lif_dict *collection) /* always enable loopback interface as part of a collection */ if_lo = lif_interface_collection_find(collection, "lo"); if_lo->is_auto = true; + if_lo->is_explicit = true; lif_interface_use_executor(if_lo, "loopback"); } From 045211514bfa9a0de93b18eec90611221b711926 Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Wed, 21 Oct 2020 08:11:45 -0600 Subject: [PATCH 03/20] lifecycle: skip parent interfaces marked as explicitly configured when going down these interfaces will be taken down by ifdown itself when appropriate --- libifupdown/lifecycle.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libifupdown/lifecycle.c b/libifupdown/lifecycle.c index c12bb38..056783f 100644 --- a/libifupdown/lifecycle.c +++ b/libifupdown/lifecycle.c @@ -396,6 +396,15 @@ handle_dependents(const struct lif_execute_opts *opts, struct lif_interface *par continue; } + if (!up && iface->is_explicit) + { + if (opts->verbose) + fprintf(stderr, "ifupdown: skipping dependent interface %s (of %s) -- interface is marked as explicitly configured\n", + iface->ifname, parent->ifname); + + continue; + } + if (opts->verbose) fprintf(stderr, "ifupdown: changing state of dependent interface %s (of %s) to %s\n", iface->ifname, parent->ifname, up ? "up" : "down"); From d92cfdd184a95688051dec8192bd6944762a0a89 Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Wed, 21 Oct 2020 08:15:52 -0600 Subject: [PATCH 04/20] state: add lif_state_record::is_explicit --- libifupdown/state.c | 1 + libifupdown/state.h | 3 +++ 2 files changed, 4 insertions(+) diff --git a/libifupdown/state.c b/libifupdown/state.c index ed4f344..6e26066 100644 --- a/libifupdown/state.c +++ b/libifupdown/state.c @@ -99,6 +99,7 @@ lif_state_upsert(struct lif_dict *state, const char *ifname, struct lif_interfac rec->mapped_if = strdup(iface->ifname); rec->refcount = iface->refcount; + rec->is_explicit = iface->is_explicit; lif_dict_add(state, ifname, rec); } diff --git a/libifupdown/state.h b/libifupdown/state.h index bec039c..ae2ba5c 100644 --- a/libifupdown/state.h +++ b/libifupdown/state.h @@ -17,11 +17,14 @@ #define LIBIFUPDOWN_STATE_H__GUARD #include +#include #include "libifupdown/interface.h" struct lif_state_record { char *mapped_if; size_t refcount; + + bool is_explicit; }; extern bool lif_state_read(struct lif_dict *state, FILE *f); From 69999cd35777c1bc37dbb3792637f1fb1105836d Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Wed, 21 Oct 2020 08:29:54 -0600 Subject: [PATCH 05/20] state: write and restore explicit flag from ifstate --- libifupdown/state.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libifupdown/state.c b/libifupdown/state.c index 6e26066..0fa055c 100644 --- a/libifupdown/state.c +++ b/libifupdown/state.c @@ -29,8 +29,13 @@ lif_state_read(struct lif_dict *state, FILE *fd) char *bufp = linebuf; char *ifname = lif_next_token(&bufp); char *refcount = lif_next_token(&bufp); + char *explicit = lif_next_token(&bufp); size_t rc = 1; char *equals_p = strchr(linebuf, '='); + bool is_explicit = false; + + if (*explicit) + is_explicit = true; if (*refcount) { @@ -42,12 +47,12 @@ lif_state_read(struct lif_dict *state, FILE *fd) if (equals_p == NULL) { - lif_state_upsert(state, ifname, &(struct lif_interface){ .ifname = ifname, .refcount = rc }); + lif_state_upsert(state, ifname, &(struct lif_interface){ .ifname = ifname, .refcount = rc, .is_explicit = is_explicit }); continue; } *equals_p++ = '\0'; - lif_state_upsert(state, ifname, &(struct lif_interface){ .ifname = equals_p, .refcount = rc }); + lif_state_upsert(state, ifname, &(struct lif_interface){ .ifname = equals_p, .refcount = rc, .is_explicit = is_explicit }); } return true; @@ -129,7 +134,8 @@ lif_state_write(const struct lif_dict *state, FILE *f) struct lif_dict_entry *entry = iter->data; struct lif_state_record *rec = entry->data; - fprintf(f, "%s=%s %zu\n", entry->key, rec->mapped_if, rec->refcount); + fprintf(f, "%s=%s %zu%s\n", entry->key, rec->mapped_if, rec->refcount, + rec->is_explicit ? " explicit" : ""); } } From 0464118429973d9650279973dea4a08f9006a14e Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Wed, 21 Oct 2020 08:30:35 -0600 Subject: [PATCH 06/20] state: synchronize is_explicit from state records to parsed interface collections --- libifupdown/state.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libifupdown/state.c b/libifupdown/state.c index 0fa055c..019d527 100644 --- a/libifupdown/state.c +++ b/libifupdown/state.c @@ -182,6 +182,7 @@ lif_state_sync(struct lif_dict *state, struct lif_dict *if_collection) struct lif_interface *iface = lif_interface_collection_find(if_collection, rec->mapped_if); iface->refcount = rec->refcount; + iface->is_explicit = rec->is_explicit; } return true; From ebae949462083e7e5531edfbc63c8753bab1830e Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Wed, 21 Oct 2020 08:32:29 -0600 Subject: [PATCH 07/20] ifquery: when querying state, denote presence of the explicit flag --- cmd/ifquery.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/ifquery.c b/cmd/ifquery.c index 720ab58..ffb62f2 100644 --- a/cmd/ifquery.c +++ b/cmd/ifquery.c @@ -182,7 +182,8 @@ list_state(struct lif_dict *state, struct match_options *opts) if (listing_running) printf("%s\n", entry->key); else - printf("%s=%s %zu\n", entry->key, rec->mapped_if, rec->refcount); + printf("%s=%s %zu%s\n", entry->key, rec->mapped_if, rec->refcount, + rec->is_explicit ? " explicit" : ""); } } From e16c24203e9726518b9601d0b7c35e9ef6802f8c Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Wed, 21 Oct 2020 08:42:47 -0600 Subject: [PATCH 08/20] ifupdown: record explicitly configured interfaces as explicit in ifstate --- cmd/ifupdown.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/cmd/ifupdown.c b/cmd/ifupdown.c index 1edc2d0..afceaa6 100644 --- a/cmd/ifupdown.c +++ b/cmd/ifupdown.c @@ -140,7 +140,7 @@ skip_interface(struct lif_interface *iface, const char *ifname) } bool -change_interface(struct lif_interface *iface, struct lif_dict *collection, struct lif_dict *state, const char *ifname) +change_interface(struct lif_interface *iface, struct lif_dict *collection, struct lif_dict *state, const char *ifname, bool update_state) { int lockfd = acquire_state_lock(exec_opts.state_file, ifname); @@ -178,6 +178,12 @@ change_interface(struct lif_interface *iface, struct lif_dict *collection, struc if (lockfd != -1) close(lockfd); + if (up && update_state) + { + iface->is_explicit = true; + lif_state_upsert(state, ifname, iface); + } + return true; } @@ -202,7 +208,7 @@ change_auto_interfaces(struct lif_dict *collection, struct lif_dict *state, stru fnmatch(opts->include_pattern, iface->ifname, 0)) continue; - if (!change_interface(iface, collection, state, iface->ifname)) + if (!change_interface(iface, collection, state, iface->ifname, false)) return false; } @@ -307,7 +313,7 @@ ifupdown_main(int argc, char *argv[]) iface = entry->data; } - if (!change_interface(iface, &collection, &state, ifname)) + if (!change_interface(iface, &collection, &state, ifname, true)) return update_state_file_and_exit(EXIT_FAILURE, &state); } From 61da61dfdbca8d8335353995a3843af853706cac Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Wed, 21 Oct 2020 08:46:47 -0600 Subject: [PATCH 09/20] ifupdown: upgrade dependent interfaces to explicit interfaces if explicitly requested --- cmd/ifupdown.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/cmd/ifupdown.c b/cmd/ifupdown.c index afceaa6..2c32706 100644 --- a/cmd/ifupdown.c +++ b/cmd/ifupdown.c @@ -95,7 +95,7 @@ acquire_state_lock(const char *state_path, const char *lifname) } bool -skip_interface(struct lif_interface *iface, const char *ifname) +skip_interface(struct lif_interface *iface, const char *ifname, struct lif_dict *state, bool update_state) { if (iface->is_template) { @@ -123,16 +123,23 @@ skip_interface(struct lif_interface *iface, const char *ifname) if (up && iface->refcount > 0) { if (exec_opts.verbose) - fprintf(stderr, "%s: skipping auto interface %s (already configured), use --force to force configuration\n", - argv0, ifname); + fprintf(stderr, "%s: skipping %sinterface %s (already configured), use --force to force configuration\n", + argv0, iface->is_auto ? "auto " : "", ifname); + + if (update_state) + { + iface->is_explicit = true; + lif_state_upsert(state, ifname, iface); + } + return true; } if (!up && iface->refcount == 0) { if (exec_opts.verbose) - fprintf(stderr, "%s: skipping auto interface %s (already deconfigured), use --force to force deconfiguration\n", - argv0, ifname); + fprintf(stderr, "%s: skipping %sinterface %s (already deconfigured), use --force to force deconfiguration\n", + argv0, iface->is_auto ? "auto " : "", ifname); return true; } @@ -150,7 +157,7 @@ change_interface(struct lif_interface *iface, struct lif_dict *collection, struc return false; } - if (skip_interface(iface, ifname)) + if (skip_interface(iface, ifname, state, update_state)) { if (lockfd != -1) close(lockfd); From 93dff795679e12cf1d89a83b09911b8d5989f13c Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Wed, 21 Oct 2020 08:55:30 -0600 Subject: [PATCH 10/20] state: explicitly check for explicit keyword when loading from the ifstate file --- libifupdown/state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libifupdown/state.c b/libifupdown/state.c index 019d527..05701ce 100644 --- a/libifupdown/state.c +++ b/libifupdown/state.c @@ -34,7 +34,7 @@ lif_state_read(struct lif_dict *state, FILE *fd) char *equals_p = strchr(linebuf, '='); bool is_explicit = false; - if (*explicit) + if (*explicit && !strcmp(explicit, "explicit")) is_explicit = true; if (*refcount) From 42836934e918033ebd604503163f97cf52f3308c Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Wed, 21 Oct 2020 09:21:21 -0600 Subject: [PATCH 11/20] ifupdown-ng 0.10.1. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a87ef80..4f1bc03 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ LIBBSD_CFLAGS = LIBBSD_LIBS = PACKAGE_NAME := ifupdown-ng -PACKAGE_VERSION := 0.10.0 +PACKAGE_VERSION := 0.10.1 PACKAGE_BUGREPORT := https://github.com/ifupdown-ng/ifupdown-ng/issues/new From 40c7ed53e1a5e8bf115b2a9f48d57d18d6d67057 Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Thu, 19 Nov 2020 03:17:57 -0700 Subject: [PATCH 12/20] multicall: do not call getopt_long() inside the stub applet --- cmd/multicall.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/cmd/multicall.c b/cmd/multicall.c index 705000f..582765c 100644 --- a/cmd/multicall.c +++ b/cmd/multicall.c @@ -66,6 +66,8 @@ applet_cmp(const void *a, const void *b) void multicall_usage(int status) __attribute__((noreturn)); +struct if_applet ifupdown_applet; + int main(int argc, char *argv[]) { @@ -85,9 +87,11 @@ main(int argc, char *argv[]) } self_applet = *app; - process_options(*app, argc, argv); - return (*app)->main(argc, argv); + if (self_applet != &ifupdown_applet) + process_options(*app, argc, argv); + + return self_applet->main(argc, argv); } int @@ -99,8 +103,6 @@ multicall_main(int argc, char *argv[]) return main(argc - 1, argv + 1); } -struct if_applet ifupdown_applet; - void multicall_usage(int status) { From 9e859d458b6d441d93900dbf2f6ad2b9f5c0233e Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Thu, 19 Nov 2020 03:28:51 -0700 Subject: [PATCH 13/20] tests: add getopt regression test for multicall stub --- tests/Kyuafile | 1 + tests/multicall_test | 11 +++++++++++ 2 files changed, 12 insertions(+) create mode 100755 tests/multicall_test diff --git a/tests/Kyuafile b/tests/Kyuafile index a7fb909..6a8019b 100644 --- a/tests/Kyuafile +++ b/tests/Kyuafile @@ -2,6 +2,7 @@ syntax(2) test_suite('ifupdown-ng') +atf_test_program{name='multicall_test'} atf_test_program{name='ifquery_test'} atf_test_program{name='ifup_test'} atf_test_program{name='ifdown_test'} diff --git a/tests/multicall_test b/tests/multicall_test new file mode 100755 index 0000000..0b4c3ab --- /dev/null +++ b/tests/multicall_test @@ -0,0 +1,11 @@ +#!/usr/bin/env atf-sh + +. $(atf_get_srcdir)/test_env.sh + +tests_init \ + regress_getopt + +regress_getopt_body() { + atf_check -e not-inline:'-F: applet not found' -o ignore -s exit:1 \ + ifupdown ifquery -F +} From bd730bece4f7e31592fa92bee74b2de461c13698 Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Wed, 4 Nov 2020 11:46:06 -0700 Subject: [PATCH 14/20] interface: learn hostname from uname(2) only if an interface requests the dhcp executor Closes #74. --- libifupdown/interface.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/libifupdown/interface.c b/libifupdown/interface.c index 7e96bcd..69a38c8 100644 --- a/libifupdown/interface.c +++ b/libifupdown/interface.c @@ -122,16 +122,6 @@ lif_interface_init(struct lif_interface *interface, const char *ifname) /* keep the 'vlan' executor as a config hint for backwards compatibility */ if (strchr(ifname, '.') != NULL) lif_interface_use_executor(interface, "vlan"); - - if (!lif_config.use_hostname_for_dhcp) - return; - - /* learn a reasonable default hostname */ - struct utsname un; - if (uname(&un) < 0) - return; - - lif_dict_add(&interface->vars, "hostname", strdup(un.nodename)); } bool @@ -211,6 +201,16 @@ lif_interface_use_executor(struct lif_interface *interface, const char *executor interface->is_bridge = true; else if (!strcmp(executor, "bond")) interface->is_bond = true; + + if (strcmp(executor, "dhcp") || !lif_config.use_hostname_for_dhcp) + return; + + /* learn a reasonable default hostname */ + struct utsname un; + if (uname(&un) < 0) + return; + + lif_dict_add(&interface->vars, "hostname", strdup(un.nodename)); } void From b425ad75e333e2d74a0049d40b989ed792425ac2 Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Wed, 2 Dec 2020 10:59:40 -0700 Subject: [PATCH 15/20] tests: ifquery: add tests for checking the default netmasks --- tests/fixtures/without-netmask.interfaces | 5 +++++ tests/ifquery_test | 16 +++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 tests/fixtures/without-netmask.interfaces diff --git a/tests/fixtures/without-netmask.interfaces b/tests/fixtures/without-netmask.interfaces new file mode 100644 index 0000000..7537c67 --- /dev/null +++ b/tests/fixtures/without-netmask.interfaces @@ -0,0 +1,5 @@ +iface v6 + address 2001:470:1f10::1 + +iface v4 + address 203.0.113.2 diff --git a/tests/ifquery_test b/tests/ifquery_test index e095255..9c5b2c7 100755 --- a/tests/ifquery_test +++ b/tests/ifquery_test @@ -34,7 +34,9 @@ tests_init \ vlan_explicit_learned_dependency \ vlan_guessed_learned_dependency \ vlan_complex_learned_dependency \ - wireguard + wireguard \ + default_netmask_v4 \ + default_netmask_v6 noargs_body() { atf_check -s exit:1 -e ignore ifquery -S/dev/null @@ -226,3 +228,15 @@ wireguard_body() { -o match:"use wireguard" \ ifquery -E $EXECUTORS_LINUX -i $FIXTURES/wireguard.interfaces wg0 } + +default_netmask_v4_body() { + atf_check -s exit:0 \ + -o match:"203.0.113.2/24" \ + ifquery -i $FIXTURES/without-netmask.interfaces -p address v4 +} + +default_netmask_v6_body() { + atf_check -s exit:0 \ + -o match:"2001:470:1f10::1/64" \ + ifquery -i $FIXTURES/without-netmask.interfaces -p address v6 +} From 726a888c8d24813aa603d10d5c4dd9c289199068 Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Wed, 2 Dec 2020 11:05:40 -0700 Subject: [PATCH 16/20] interface: fix default netmask size for AF_INET6 addresses (closes #130) --- libifupdown/interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libifupdown/interface.c b/libifupdown/interface.c index 69a38c8..b18e318 100644 --- a/libifupdown/interface.c +++ b/libifupdown/interface.c @@ -93,7 +93,7 @@ lif_address_format_cidr(const struct lif_interface *iface, struct lif_dict_entry if (!addr->netmask) { /* if netmask is not set, default to 255.255.255.0, ifupdown does so too */ - addr->netmask = 24; + addr->netmask = addr->domain == AF_INET6 ? 64 : 24; struct lif_dict_entry *entry = lif_dict_find(&iface->vars, "netmask"); if (entry != NULL) From 6da55d9299f02951633fa34de65c115f71f7d32f Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Wed, 2 Dec 2020 11:17:41 -0700 Subject: [PATCH 17/20] tests: add fixture illustrating how smart stanza merging should work --- tests/fixtures/stanza-merging.interfaces | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 tests/fixtures/stanza-merging.interfaces diff --git a/tests/fixtures/stanza-merging.interfaces b/tests/fixtures/stanza-merging.interfaces new file mode 100644 index 0000000..6327cbc --- /dev/null +++ b/tests/fixtures/stanza-merging.interfaces @@ -0,0 +1,14 @@ +# cidr and without-cidr should be equivalent +iface cidr + address 203.0.113.1/32 + +iface cidr + address 203.0.113.2/24 + +iface without-cidr + address 203.0.113.1 + netmask 32 + +iface without-cidr + address 203.0.113.2 + netmask 24 From f671e2d410a6f1d317d6d89573605c0591302c08 Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Wed, 2 Dec 2020 11:38:39 -0700 Subject: [PATCH 18/20] interface: add lif_interface_finalize() which rewrites addresses as CIDR when an interface stanza ends --- libifupdown/interface-file.c | 11 ++++++++ libifupdown/interface.c | 52 ++++++++++++++++++++++++++++++------ libifupdown/interface.h | 1 + 3 files changed, 56 insertions(+), 8 deletions(-) diff --git a/libifupdown/interface-file.c b/libifupdown/interface-file.c index 6481be8..5d94fc8 100644 --- a/libifupdown/interface-file.c +++ b/libifupdown/interface-file.c @@ -256,6 +256,12 @@ handle_iface(struct lif_interface_file_parse_state *state, char *token, char *bu return true; } + /* if we have a current interface, call lif_interface_finalize to finalize any + * address properties by converting them to CIDR and flushing the netmask property. + */ + if (state->cur_iface != NULL) + lif_interface_finalize(state->cur_iface); + state->cur_iface = lif_interface_collection_find(state->collection, ifname); if (state->cur_iface == NULL) { @@ -494,6 +500,11 @@ lif_interface_file_parse(struct lif_interface_file_parse_state *state, const cha } fclose(f); + + /* finalize any open interface */ + if (state->cur_iface != NULL) + lif_interface_finalize(state->cur_iface); + state->cur_filename = old_filename; state->cur_lineno = old_lineno; return true; diff --git a/libifupdown/interface.c b/libifupdown/interface.c index b18e318..0294383 100644 --- a/libifupdown/interface.c +++ b/libifupdown/interface.c @@ -84,6 +84,19 @@ count_set_bits(const char *netmask) return r; } +static inline size_t +determine_interface_netmask(const struct lif_interface *iface, const struct lif_address *addr) +{ + /* if netmask is not set, default to /24 or /64, ifupdown does so too */ + size_t netmask = addr->domain == AF_INET6 ? 64 : 24; + + struct lif_dict_entry *entry = lif_dict_find(&iface->vars, "netmask"); + if (entry != NULL) + netmask = count_set_bits(entry->data); + + return netmask; +} + bool lif_address_format_cidr(const struct lif_interface *iface, struct lif_dict_entry *entry, char *buf, size_t buflen) { @@ -91,14 +104,7 @@ lif_address_format_cidr(const struct lif_interface *iface, struct lif_dict_entry size_t orig_netmask = addr->netmask; if (!addr->netmask) - { - /* if netmask is not set, default to 255.255.255.0, ifupdown does so too */ - addr->netmask = addr->domain == AF_INET6 ? 64 : 24; - - struct lif_dict_entry *entry = lif_dict_find(&iface->vars, "netmask"); - if (entry != NULL) - addr->netmask = count_set_bits(entry->data); - } + addr->netmask = determine_interface_netmask(iface, addr); if (!lif_address_unparse(addr, buf, buflen, true)) { @@ -213,6 +219,36 @@ lif_interface_use_executor(struct lif_interface *interface, const char *executor lif_dict_add(&interface->vars, "hostname", strdup(un.nodename)); } +void +lif_interface_finalize(struct lif_interface *interface) +{ + struct lif_node *iter; + + /* convert all addresses to CIDR notation. */ + LIF_DICT_FOREACH(iter, &interface->vars) + { + struct lif_dict_entry *entry = iter->data; + + if (strcmp(entry->key, "address")) + continue; + + struct lif_address *addr = entry->data; + + if (!addr->netmask) + addr->netmask = determine_interface_netmask(interface, addr); + } + + /* with all addresses converted to CIDR, netmask property is no longer needed. */ + struct lif_dict_entry *entry = lif_dict_find(&interface->vars, "netmask"); + + if (entry != NULL) + { + free(entry->data); + + lif_dict_delete_entry(&interface->vars, entry); + } +} + void lif_interface_collection_init(struct lif_dict *collection) { diff --git a/libifupdown/interface.h b/libifupdown/interface.h index 0c6d8b2..49c867d 100644 --- a/libifupdown/interface.h +++ b/libifupdown/interface.h @@ -75,6 +75,7 @@ extern bool lif_interface_address_add(struct lif_interface *interface, const cha extern void lif_interface_address_delete(struct lif_interface *interface, const char *address); extern void lif_interface_fini(struct lif_interface *interface); extern void lif_interface_use_executor(struct lif_interface *interface, const char *executor); +extern void lif_interface_finalize(struct lif_interface *interface); extern void lif_interface_collection_init(struct lif_dict *collection); extern void lif_interface_collection_fini(struct lif_dict *collection); From bcf090f7ad08441f90555ed53af8d8557bb6efcd Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Wed, 2 Dec 2020 11:42:45 -0700 Subject: [PATCH 19/20] tests: ifquery: add tests to verify stanza merging works as expected --- tests/ifquery_test | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tests/ifquery_test b/tests/ifquery_test index 9c5b2c7..d85cd27 100755 --- a/tests/ifquery_test +++ b/tests/ifquery_test @@ -36,7 +36,9 @@ tests_init \ vlan_complex_learned_dependency \ wireguard \ default_netmask_v4 \ - default_netmask_v6 + default_netmask_v6 \ + stanza_merging_with_cidr \ + stanza_merging_without_cidr noargs_body() { atf_check -s exit:1 -e ignore ifquery -S/dev/null @@ -240,3 +242,17 @@ default_netmask_v6_body() { -o match:"2001:470:1f10::1/64" \ ifquery -i $FIXTURES/without-netmask.interfaces -p address v6 } + +stanza_merging_with_cidr_body() { + atf_check -s exit:0 \ + -o match:"203.0.113.1/32" \ + -o match:"203.0.113.2/24" \ + ifquery -i $FIXTURES/stanza-merging.interfaces -p address cidr +} + +stanza_merging_without_cidr_body() { + atf_check -s exit:0 \ + -o match:"203.0.113.1/32" \ + -o match:"203.0.113.2/24" \ + ifquery -i $FIXTURES/stanza-merging.interfaces -p address without-cidr +} From 975e4f1bea359fd42c88fd41a67ccede44fc4470 Mon Sep 17 00:00:00 2001 From: Ariadne Conill Date: Wed, 2 Dec 2020 11:52:01 -0700 Subject: [PATCH 20/20] ifupdown-ng 0.10.2. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 4f1bc03..797208e 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ LIBBSD_CFLAGS = LIBBSD_LIBS = PACKAGE_NAME := ifupdown-ng -PACKAGE_VERSION := 0.10.1 +PACKAGE_VERSION := 0.10.2 PACKAGE_BUGREPORT := https://github.com/ifupdown-ng/ifupdown-ng/issues/new