Skip to content

Commit

Permalink
ATTN: parse/bonds: handle same primary in multiple bonds (#451)
Browse files Browse the repository at this point in the history
* ATTN: parse/bonds: handle same primary in multiple bonds

Error out if an interface is declared as primary of multiple bonds.
Besides being wrong it's causing a memory leak.

ATTN: as this makes the parser stricter, it probably should not be
included in backports/SRUs. Consider converting the error to a warning
and freeing the memory allocation to avoid the leak.

* parse/bond: identify bond assigned to primary

Look for the bond that already has the primary member assigned and
identify it in the error message.
  • Loading branch information
daniloegea authored Apr 15, 2024
1 parent dca7227 commit 7e22e6f
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -2313,6 +2313,11 @@ handle_bond_primary_member(NetplanParser* npp, yaml_node_t* node, const void* da
npp->current.netdef->id, npp->current.netdef->bond_params.primary_member);

ref_ptr = ((char**) ((void*) component + GPOINTER_TO_UINT(data)));
if (*ref_ptr) {
NetplanNetDefinition* bond = _netplan_parser_find_bond_for_primary_member(npp, *ref_ptr);
return yaml_error(npp, node, error, "%s: interface '%s' is already a primary of %s",
npp->current.netdef->id, *ref_ptr, bond->id);
}
*ref_ptr = g_strdup(scalar(node));
npp->current.netdef->bond_params.primary_member = g_strdup(scalar(node));
mark_data_as_dirty(npp, ref_ptr);
Expand Down
3 changes: 3 additions & 0 deletions src/util-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ netplan_netdef_new(NetplanParser* npp, const char* id, NetplanDefType type, Netp
const char *
netplan_parser_get_filename(NetplanParser* npp);

NetplanNetDefinition*
_netplan_parser_find_bond_for_primary_member(const NetplanParser* npp, const char* primary);

gboolean
has_openvswitch(const NetplanOVSSettings* ovs, NetplanBackend backend, GHashTable *ovs_ports);

Expand Down
20 changes: 20 additions & 0 deletions src/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -1184,3 +1184,23 @@ _is_valid_macaddress(const char* value)

return regexec(&re, value, 0, NULL, 0) == 0;
}

/* Given a netdef ID, look for the netdef representing a bond device that has it as primary member */
NetplanNetDefinition*
_netplan_parser_find_bond_for_primary_member(const NetplanParser* npp, const char* primary)
{
GList* iter = npp->ordered;
NetplanNetDefinition* netdef = NULL;

while (iter) {
netdef = iter->data;
if (netdef->type == NETPLAN_DEF_TYPE_BOND) {
if (!g_strcmp0(netdef->bond_params.primary_member, primary)) {
break;
}
}
iter = iter->next;
}

return netdef;
}
14 changes: 14 additions & 0 deletions tests/generator/test_bonds.py
Original file line number Diff line number Diff line change
Expand Up @@ -968,6 +968,20 @@ def test_bond_multiple_assignments(self):
interfaces: [eno1]''', expect_fail=True)
self.assertIn("bond1: interface 'eno1' is already assigned to bond bond0", err)

def test_bond_primary_multiple_assignments(self):
err = self.generate('''network:
version: 2
ethernets:
eno1: {}
bonds:
bond0:
parameters:
primary: eno1
bond1:
parameters:
primary: eno1''', expect_fail=True)
self.assertIn("bond1: interface 'eno1' is already a primary of bond0", err)

def test_bond_bridge_cross_assignments1(self):
err = self.generate('''network:
version: 2
Expand Down

0 comments on commit 7e22e6f

Please sign in to comment.