ifcfg-rh: add bridge vlans support

This commit is contained in:
Beniamino Galvani 2019-03-23 16:58:57 +01:00
parent c66d17d4fc
commit 56d193e686
6 changed files with 153 additions and 12 deletions

View file

@ -558,6 +558,13 @@ nm_setting_bridge_port_class_init (NMSettingBridgePortClass *klass)
*
* Since: 1.18
**/
/* ---ifcfg-rh---
* property: vlans
* variable: BRIDGE_PORT_VLANS
* description: List of VLANs on the bridge port
* example: BRIDGE_PORT_VLANS="1 pvid untagged,20,40 untagged"
* ---end---
*/
obj_properties[PROP_VLANS] =
g_param_spec_boxed (NM_SETTING_BRIDGE_PORT_VLANS, "", "",
G_TYPE_PTR_ARRAY,

View file

@ -1393,6 +1393,13 @@ nm_setting_bridge_class_init (NMSettingBridgeClass *klass)
*
* Since: 1.18
**/
/* ---ifcfg-rh---
* property: vlans
* variable: BRIDGE_VLANS
* description: List of VLANs on the bridge
* example: BRIDGE_VLANS="1 pvid untagged,20,40 untagged"
* ---end---
*/
obj_properties[PROP_VLANS] =
g_param_spec_boxed (NM_SETTING_BRIDGE_VLANS, "", "",
G_TYPE_PTR_ARRAY,

View file

@ -5054,6 +5054,43 @@ handle_bridging_opts (NMSetting *setting,
}
}
static void
read_bridge_vlans (shvarFile *ifcfg,
const char *key,
NMSetting *setting,
const char *property)
{
gs_unref_ptrarray GPtrArray *array = NULL;
gs_free char *value_to_free = NULL;
const char *value;
value = svGetValueStr (ifcfg, key, &value_to_free);
if (value) {
gs_free const char **strv = NULL;
const char *const *iter;
GError *local = NULL;
NMBridgeVlan *vlan;
array = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_bridge_vlan_unref);
strv = nm_utils_strsplit_set (value, ",", FALSE);
if (strv) {
for (iter = strv; *iter; iter++) {
vlan = nm_bridge_vlan_from_str (*iter, &local);
if (!vlan) {
PARSE_WARNING ("invalid bridge VLAN: %s", local->message);
g_clear_error (&local);
continue;
}
g_ptr_array_add (array, vlan);
}
}
nm_clear_g_free (&value_to_free);
}
g_object_set (setting, property, array, NULL);
}
static NMSetting *
make_bridge_setting (shvarFile *ifcfg,
const char *file,
@ -5112,6 +5149,11 @@ make_bridge_setting (shvarFile *ifcfg,
nm_clear_g_free (&value_to_free);
}
read_bridge_vlans (ifcfg,
"BRIDGE_VLANS",
NM_SETTING (s_bridge),
NM_SETTING_BRIDGE_VLANS);
return (NMSetting *) g_steal_pointer (&s_bridge);
}
@ -5181,6 +5223,11 @@ make_bridge_port_setting (shvarFile *ifcfg)
handle_bridging_opts (s_port, FALSE, value, handle_bridge_option, BRIDGE_OPT_TYPE_PORT_OPTION);
nm_clear_g_free (&value_to_free);
}
read_bridge_vlans (ifcfg,
"BRIDGE_PORT_VLANS",
s_port,
NM_SETTING_BRIDGE_PORT_VLANS);
}
return s_port;

View file

@ -1463,6 +1463,43 @@ get_setting_default_boolean (NMSetting *setting, const char *prop)
return ret;
}
static gboolean
write_bridge_vlans (NMSetting *setting,
const char *property_name,
shvarFile *ifcfg,
const char *key,
GError **error)
{
gs_unref_ptrarray GPtrArray *vlans = NULL;
NMBridgeVlan *vlan;
GString *string;
guint i;
g_object_get (setting, property_name, &vlans, NULL);
if (!vlans || !vlans->len) {
svUnsetValue (ifcfg, key);
return TRUE;
}
string = g_string_new ("");
for (i = 0; i < vlans->len; i++) {
gs_free char *vlan_str = NULL;
vlan = vlans->pdata[i];
vlan_str = nm_bridge_vlan_to_str (vlan, error);
if (!vlan_str)
return FALSE;
if (string->len > 0)
g_string_append (string, ", ");
g_string_append (string, vlan_str);
}
svSetValueStr (ifcfg, key, string->str);
g_string_free (string, TRUE);
return TRUE;
}
static gboolean
write_bridge_setting (NMConnection *connection, shvarFile *ifcfg, gboolean *wired, GError **error)
{
@ -1552,6 +1589,13 @@ write_bridge_setting (NMConnection *connection, shvarFile *ifcfg, gboolean *wire
svSetValueStr (ifcfg, "BRIDGING_OPTS", opts->str);
g_string_free (opts, TRUE);
if (!write_bridge_vlans ((NMSetting *) s_bridge,
NM_SETTING_BRIDGE_VLANS,
ifcfg,
"BRIDGE_VLANS",
error))
return FALSE;
svSetValueStr (ifcfg, "TYPE", TYPE_BRIDGE);
*wired = write_wired_for_virtual (connection, ifcfg);
@ -1564,7 +1608,7 @@ write_bridge_port_setting (NMConnection *connection, shvarFile *ifcfg, GError **
{
NMSettingBridgePort *s_port;
guint32 i;
GString *opts;
GString *string;
s_port = nm_connection_get_setting_bridge_port (connection);
if (!s_port)
@ -1573,28 +1617,35 @@ write_bridge_port_setting (NMConnection *connection, shvarFile *ifcfg, GError **
svUnsetValue (ifcfg, "BRIDGING_OPTS");
/* Bridge options */
opts = g_string_sized_new (32);
string = g_string_sized_new (32);
i = nm_setting_bridge_port_get_priority (s_port);
if (i != get_setting_default_uint (NM_SETTING (s_port), NM_SETTING_BRIDGE_PORT_PRIORITY))
g_string_append_printf (opts, "priority=%u", i);
g_string_append_printf (string, "priority=%u", i);
i = nm_setting_bridge_port_get_path_cost (s_port);
if (i != get_setting_default_uint (NM_SETTING (s_port), NM_SETTING_BRIDGE_PORT_PATH_COST)) {
if (opts->len)
g_string_append_c (opts, ' ');
g_string_append_printf (opts, "path_cost=%u", i);
if (string->len)
g_string_append_c (string, ' ');
g_string_append_printf (string, "path_cost=%u", i);
}
if (nm_setting_bridge_port_get_hairpin_mode (s_port)) {
if (opts->len)
g_string_append_c (opts, ' ');
g_string_append_printf (opts, "hairpin_mode=1");
if (string->len)
g_string_append_c (string, ' ');
g_string_append_printf (string, "hairpin_mode=1");
}
if (opts->len)
svSetValueStr (ifcfg, "BRIDGING_OPTS", opts->str);
g_string_free (opts, TRUE);
if (string->len)
svSetValueStr (ifcfg, "BRIDGING_OPTS", string->str);
g_string_free (string, TRUE);
if (!write_bridge_vlans ((NMSetting *) s_port,
NM_SETTING_BRIDGE_PORT_VLANS,
ifcfg,
"BRIDGE_PORT_VLANS",
error))
return FALSE;
return TRUE;
}

View file

@ -2,6 +2,7 @@ HWADDR=31:33:33:37:BE:CD
MTU=1492
TYPE=Ethernet
BRIDGING_OPTS="priority=50 path_cost=33"
BRIDGE_PORT_VLANS="1 untagged, 2 pvid untagged, 4"
NAME="Test Write Bridge Component"
UUID=${UUID}
ONBOOT=yes

View file

@ -7533,6 +7533,8 @@ test_write_bridge_main (void)
NMIPAddress *addr;
static const char *mac = "31:33:33:37:be:cd";
GError *error = NULL;
gs_unref_ptrarray GPtrArray *vlans = NULL;
NMBridgeVlan *vlan;
connection = nm_simple_connection_new ();
g_assert (connection);
@ -7553,11 +7555,23 @@ test_write_bridge_main (void)
s_bridge = (NMSettingBridge *) nm_setting_bridge_new ();
nm_connection_add_setting (connection, NM_SETTING (s_bridge));
vlans = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_bridge_vlan_unref);
vlan = nm_bridge_vlan_new (11);
nm_bridge_vlan_set_untagged (vlan, TRUE);
g_ptr_array_add (vlans, vlan);
vlan = nm_bridge_vlan_new (22);
nm_bridge_vlan_set_pvid (vlan, TRUE);
nm_bridge_vlan_set_untagged (vlan, TRUE);
g_ptr_array_add (vlans, vlan);
vlan = nm_bridge_vlan_new (44);
g_ptr_array_add (vlans, vlan);
g_object_set (s_bridge,
NM_SETTING_BRIDGE_MAC_ADDRESS, mac,
NM_SETTING_BRIDGE_GROUP_FORWARD_MASK, 19008,
NM_SETTING_BRIDGE_VLAN_FILTERING, TRUE,
NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID, 4000,
NM_SETTING_BRIDGE_VLANS, vlans,
NULL);
/* IP4 setting */
@ -7635,6 +7649,8 @@ test_write_bridge_component (void)
NMSetting *s_port;
static const char *mac = "31:33:33:37:be:cd";
guint32 mtu = 1492;
gs_unref_ptrarray GPtrArray *vlans = NULL;
NMBridgeVlan *vlan;
connection = nm_simple_connection_new ();
g_assert (connection);
@ -7662,11 +7678,23 @@ test_write_bridge_component (void)
NULL);
/* Bridge port */
vlans = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_bridge_vlan_unref);
vlan = nm_bridge_vlan_new (1);
nm_bridge_vlan_set_untagged (vlan, TRUE);
g_ptr_array_add (vlans, vlan);
vlan = nm_bridge_vlan_new (2);
nm_bridge_vlan_set_pvid (vlan, TRUE);
nm_bridge_vlan_set_untagged (vlan, TRUE);
g_ptr_array_add (vlans, vlan);
vlan = nm_bridge_vlan_new (4);
g_ptr_array_add (vlans, vlan);
s_port = nm_setting_bridge_port_new ();
nm_connection_add_setting (connection, s_port);
g_object_set (s_port,
NM_SETTING_BRIDGE_PORT_PRIORITY, 50,
NM_SETTING_BRIDGE_PORT_PATH_COST, 33,
NM_SETTING_BRIDGE_PORT_VLANS, vlans,
NULL);
nmtst_assert_connection_verifies (connection);