Merge pull request #133 from ifupdown-ng/feature/smart-stanza-merging

improve stanza merging by rewriting address properties as CIDR
This commit is contained in:
Ariadne Conill 2020-12-02 11:50:15 -07:00 committed by GitHub
commit 3d47b34d7a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 87 additions and 9 deletions

View file

@ -263,6 +263,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)
{
@ -501,6 +507,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;

View file

@ -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)
{

View file

@ -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);

View file

@ -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

View file

@ -38,7 +38,9 @@ tests_init \
allow_undefined_positive \
allow_undefined_negative \
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
@ -256,3 +258,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
}