diff --git a/clients/cli/settings.c b/clients/cli/settings.c index 992f8415b5..e5139aeb11 100644 --- a/clients/cli/settings.c +++ b/clients/cli/settings.c @@ -738,6 +738,8 @@ vlan_flags_to_string (guint32 flags) g_string_append (flag_str, _("GVRP, ")); if (flags & NM_VLAN_FLAG_LOOSE_BINDING) g_string_append (flag_str, _("LOOSE_BINDING, ")); + if (flags & NM_VLAN_FLAG_MVRP) + g_string_append (flag_str, _("MVRP, ")); if (flag_str->str[flag_str->len-1] == '(') g_string_append (flag_str, _("unknown")); diff --git a/libnm-core/nm-setting-vlan.c b/libnm-core/nm-setting-vlan.c index 99e433651b..66661ec613 100644 --- a/libnm-core/nm-setting-vlan.c +++ b/libnm-core/nm-setting-vlan.c @@ -181,9 +181,25 @@ get_map (NMSettingVlan *self, NMVlanPriorityMap map) return NULL; } +static gint +prio_map_compare (PriorityMap *a, PriorityMap *b) +{ + return a->from < b->from + ? -1 + : (a->from > b->from + ? 1 + : (a->to < b->to ? -1 : (a->to > b->to ? 1 : 0))); +} + static void set_map (NMSettingVlan *self, NMVlanPriorityMap map, GSList *list) { + /* Sort the list. + * First, it looks better. Second, it assures that comparing lists works + * as expected. + */ + list = g_slist_sort (list, (GCompareFunc) prio_map_compare); + if (map == NM_VLAN_INGRESS_MAP) { NM_SETTING_VLAN_GET_PRIVATE (self)->ingress_priority_map = list; g_object_notify (G_OBJECT (self), NM_SETTING_VLAN_INGRESS_PRIORITY_MAP); @@ -194,6 +210,22 @@ set_map (NMSettingVlan *self, NMVlanPriorityMap map, GSList *list) g_assert_not_reached (); } +static gboolean +check_replace_duplicate_priority (GSList *list, guint32 from, guint32 to) +{ + GSList *iter; + PriorityMap *p; + + for (iter = list; iter; iter = g_slist_next (iter)) { + p = iter->data; + if (p->from == from) { + p->to = to; + return TRUE; + } + } + return FALSE; +} + /** * nm_setting_vlan_add_priority_str: * @setting: the #NMSettingVlan @@ -212,7 +244,7 @@ nm_setting_vlan_add_priority_str (NMSettingVlan *setting, NMVlanPriorityMap map, const char *str) { - GSList *list = NULL, *iter = NULL; + GSList *list = NULL; PriorityMap *item = NULL; g_return_val_if_fail (NM_IS_SETTING_VLAN (setting), FALSE); @@ -226,18 +258,13 @@ nm_setting_vlan_add_priority_str (NMSettingVlan *setting, g_return_val_if_reached (FALSE); /* Duplicates get replaced */ - for (iter = list; iter; iter = g_slist_next (iter)) { - PriorityMap *p = iter->data; - - if (p->from == item->from) { - p->to = item->to; - g_free (item); - if (map == NM_VLAN_INGRESS_MAP) - g_object_notify (G_OBJECT (setting), NM_SETTING_VLAN_INGRESS_PRIORITY_MAP); - else - g_object_notify (G_OBJECT (setting), NM_SETTING_VLAN_EGRESS_PRIORITY_MAP); - return TRUE; - } + if (check_replace_duplicate_priority (list, item->from, item->to)) { + g_free (item); + if (map == NM_VLAN_INGRESS_MAP) + g_object_notify (G_OBJECT (setting), NM_SETTING_VLAN_INGRESS_PRIORITY_MAP); + else + g_object_notify (G_OBJECT (setting), NM_SETTING_VLAN_EGRESS_PRIORITY_MAP); + return TRUE; } set_map (setting, map, g_slist_append (list, item)); @@ -329,23 +356,19 @@ nm_setting_vlan_add_priority (NMSettingVlan *setting, guint32 from, guint32 to) { - GSList *list = NULL, *iter = NULL; + GSList *list = NULL; PriorityMap *item; g_return_val_if_fail (NM_IS_SETTING_VLAN (setting), FALSE); g_return_val_if_fail (map == NM_VLAN_INGRESS_MAP || map == NM_VLAN_EGRESS_MAP, FALSE); list = get_map (setting, map); - for (iter = list; iter; iter = g_slist_next (iter)) { - item = iter->data; - if (item->from == from) { - item->to = to; - if (map == NM_VLAN_INGRESS_MAP) - g_object_notify (G_OBJECT (setting), NM_SETTING_VLAN_INGRESS_PRIORITY_MAP); - else - g_object_notify (G_OBJECT (setting), NM_SETTING_VLAN_EGRESS_PRIORITY_MAP); - return TRUE; - } + if (check_replace_duplicate_priority (list, from, to)) { + if (map == NM_VLAN_INGRESS_MAP) + g_object_notify (G_OBJECT (setting), NM_SETTING_VLAN_INGRESS_PRIORITY_MAP); + else + g_object_notify (G_OBJECT (setting), NM_SETTING_VLAN_EGRESS_PRIORITY_MAP); + return TRUE; } item = g_malloc0 (sizeof (PriorityMap)); @@ -544,9 +567,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) } } - if (priv->flags & ~(NM_VLAN_FLAG_REORDER_HEADERS | - NM_VLAN_FLAG_GVRP | - NM_VLAN_FLAG_LOOSE_BINDING)) { + if (priv->flags & ~NM_VLAN_FLAGS_ALL) { g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, @@ -586,10 +607,12 @@ priority_strv_to_maplist (NMVlanPriorityMap map, char **strv) PriorityMap *item; item = priority_map_new_from_str (map, strv[i]); - if (item) - list = g_slist_prepend (list, item); + if (item) { + if (!check_replace_duplicate_priority (list, item->from, item->to)) + list = g_slist_prepend (list, item); + } } - return g_slist_reverse (list); + return g_slist_sort (list, (GCompareFunc) prio_map_compare); } static void @@ -753,7 +776,8 @@ nm_setting_vlan_class_init (NMSettingVlanClass *setting_class) * interface. Flags include %NM_VLAN_FLAG_REORDER_HEADERS (reordering of * output packet headers), %NM_VLAN_FLAG_GVRP (use of the GVRP protocol), * and %NM_VLAN_FLAG_LOOSE_BINDING (loose binding of the interface to its - * master device's operating state). + * master device's operating state). %NM_VLAN_FLAG_MVRP (use of the MVRP + * protocol). * * The default value of this property is NM_VLAN_FLAG_REORDER_HEADERS, * but it used to be 0. To preserve backward compatibility, the default-value @@ -762,8 +786,8 @@ nm_setting_vlan_class_init (NMSettingVlanClass *setting_class) **/ /* ---ifcfg-rh--- * property: flags - * variable: VLAN_FLAGS, REORDER_HDR - * values: "GVRP", "LOOSE_BINDING" for VLAN_FLAGS; 0 or 1 for REORDER_HDR + * variable: REORDER_HDR, GVRP, MVRP, VLAN_FLAGS + * values: "yes or "no" for REORDER_HDR, GVRP and MVRP; "LOOSE_BINDING" for VLAN_FLAGS * description: VLAN flags. * ---end--- */ diff --git a/libnm-core/nm-setting-vlan.h b/libnm-core/nm-setting-vlan.h index 30305d327c..cf41ba177e 100644 --- a/libnm-core/nm-setting-vlan.h +++ b/libnm-core/nm-setting-vlan.h @@ -79,6 +79,8 @@ typedef enum { * @NM_VLAN_FLAG_LOOSE_BINDING: indicates that this interface's operating * state is tied to the underlying network interface but other details * (like routing) are not. + * @NM_VLAN_FLAG_MVRP: indicates that this interface should use MVRP to register + * itself with it's switch * * #NMVlanFlags values control the behavior of the VLAN interface. **/ @@ -86,10 +88,19 @@ typedef enum { /*< flags >*/ NM_VLAN_FLAG_REORDER_HEADERS = 0x1, NM_VLAN_FLAG_GVRP = 0x2, NM_VLAN_FLAG_LOOSE_BINDING = 0x4, + NM_VLAN_FLAG_MVRP = 0x8, /* NOTE: if adding flags update nm-setting-vlan.c::verify() */ + + /* NOTE: these flags must correspond to the value from the kernel + * header files. */ } NMVlanFlags; +#define NM_VLAN_FLAGS_ALL (NM_VLAN_FLAG_REORDER_HEADERS | \ + NM_VLAN_FLAG_GVRP | \ + NM_VLAN_FLAG_LOOSE_BINDING | \ + NM_VLAN_FLAG_MVRP) + GType nm_setting_vlan_get_type (void); NMSetting *nm_setting_vlan_new (void); diff --git a/libnm-util/nm-setting-vlan.c b/libnm-util/nm-setting-vlan.c index 52676d47f0..310a7da818 100644 --- a/libnm-util/nm-setting-vlan.c +++ b/libnm-util/nm-setting-vlan.c @@ -584,9 +584,7 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) } } - if (priv->flags & ~(NM_VLAN_FLAG_REORDER_HEADERS | - NM_VLAN_FLAG_GVRP | - NM_VLAN_FLAG_LOOSE_BINDING)) { + if (priv->flags & ~NM_VLAN_FLAGS_ALL) { g_set_error_literal (error, NM_SETTING_VLAN_ERROR, NM_SETTING_VLAN_ERROR_INVALID_PROPERTY, @@ -800,7 +798,8 @@ nm_setting_vlan_class_init (NMSettingVlanClass *setting_class) * interface. Flags include %NM_VLAN_FLAG_REORDER_HEADERS (reordering of * output packet headers), %NM_VLAN_FLAG_GVRP (use of the GVRP protocol), * and %NM_VLAN_FLAG_LOOSE_BINDING (loose binding of the interface to its - * master device's operating state). + * master device's operating state), %NM_VLAN_FLAG_MVRP (use of the MVRP + * protocol). **/ g_object_class_install_property (object_class, PROP_FLAGS, diff --git a/libnm-util/nm-setting-vlan.h b/libnm-util/nm-setting-vlan.h index 3e209480c8..ce42dd4154 100644 --- a/libnm-util/nm-setting-vlan.h +++ b/libnm-util/nm-setting-vlan.h @@ -98,6 +98,8 @@ typedef enum { * @NM_VLAN_FLAG_LOOSE_BINDING: indicates that this interface's operating * state is tied to the underlying network interface but other details * (like routing) are not. + * @NM_VLAN_FLAG_MVRP: indicates that this interface should use MVRP to register + * itself with it's switch * * #NMVlanFlags values control the behavior of the VLAN interface. **/ @@ -105,10 +107,16 @@ typedef enum { NM_VLAN_FLAG_REORDER_HEADERS = 0x1, NM_VLAN_FLAG_GVRP = 0x2, NM_VLAN_FLAG_LOOSE_BINDING = 0x4, + NM_VLAN_FLAG_MVRP = 0x8, /* NOTE: if adding flags update nm-setting-vlan.c::verify() */ } NMVlanFlags; +#define NM_VLAN_FLAGS_ALL (NM_VLAN_FLAG_REORDER_HEADERS | \ + NM_VLAN_FLAG_GVRP | \ + NM_VLAN_FLAG_LOOSE_BINDING | \ + NM_VLAN_FLAG_MVRP) + GType nm_setting_vlan_get_type (void); NMSetting *nm_setting_vlan_new (void); diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 5f55832609..775f342d74 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -64,6 +64,8 @@ /* This is only included for the translation of VLAN flags */ #include "nm-setting-vlan.h" +#define VLAN_FLAG_MVRP 0x8 + /*********************************************************************************************/ #define _NMLOG_PREFIX_NAME "platform-linux" @@ -3220,17 +3222,18 @@ vlan_add (NMPlatform *platform, { auto_nl_object struct rtnl_link *rtnllink = (struct rtnl_link *) build_rtnl_link (0, name, NM_LINK_TYPE_VLAN); unsigned int kernel_flags; + unsigned int all_flags = NM_VLAN_FLAGS_ALL; - kernel_flags = 0; - if (vlan_flags & NM_VLAN_FLAG_REORDER_HEADERS) - kernel_flags |= VLAN_FLAG_REORDER_HDR; - if (vlan_flags & NM_VLAN_FLAG_GVRP) - kernel_flags |= VLAN_FLAG_GVRP; - if (vlan_flags & NM_VLAN_FLAG_LOOSE_BINDING) - kernel_flags |= VLAN_FLAG_LOOSE_BINDING; + G_STATIC_ASSERT (NM_VLAN_FLAG_REORDER_HEADERS == VLAN_FLAG_REORDER_HDR); + G_STATIC_ASSERT (NM_VLAN_FLAG_GVRP == VLAN_FLAG_GVRP); + G_STATIC_ASSERT (NM_VLAN_FLAG_LOOSE_BINDING == VLAN_FLAG_LOOSE_BINDING); + G_STATIC_ASSERT (NM_VLAN_FLAG_MVRP == VLAN_FLAG_MVRP); + + kernel_flags = vlan_flags & ((guint32) NM_VLAN_FLAGS_ALL); rtnl_link_set_link (rtnllink, parent); rtnl_link_vlan_set_id (rtnllink, vlan_id); + rtnl_link_vlan_unset_flags (rtnllink, all_flags); rtnl_link_vlan_set_flags (rtnllink, kernel_flags); _LOGD ("link: add vlan '%s', parent %d, vlan id %d, flags %X (native: %X)", @@ -3261,7 +3264,6 @@ vlan_set_ingress_map (NMPlatform *platform, int ifindex, int from, int to) { auto_nl_object struct rtnl_link *change = (struct rtnl_link *) build_rtnl_link (ifindex, NULL, NM_LINK_TYPE_VLAN); - rtnl_link_set_type (change, "vlan"); rtnl_link_vlan_set_ingress_map (change, from, to); _LOGD ("link: change %d: vlan ingress map %d -> %d", ifindex, from, to); @@ -3274,7 +3276,6 @@ vlan_set_egress_map (NMPlatform *platform, int ifindex, int from, int to) { auto_nl_object struct rtnl_link *change = (struct rtnl_link *) build_rtnl_link (ifindex, NULL, NM_LINK_TYPE_VLAN); - rtnl_link_set_type (change, "vlan"); rtnl_link_vlan_set_egress_map (change, from, to); _LOGD ("link: change %d: vlan egress map %d -> %d", ifindex, from, to); diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c index 94b696c92f..60d0bcee3c 100644 --- a/src/settings/plugins/ifcfg-rh/reader.c +++ b/src/settings/plugins/ifcfg-rh/reader.c @@ -4575,6 +4575,7 @@ make_vlan_setting (shvarFile *ifcfg, char *end = NULL; gint vlan_id = -1; guint32 vlan_flags = 0; + gint gvrp; value = svGetValue (ifcfg, "VLAN_ID", FALSE); if (value) { @@ -4652,14 +4653,22 @@ make_vlan_setting (shvarFile *ifcfg, if (svGetValueBoolean (ifcfg, "REORDER_HDR", FALSE)) vlan_flags |= NM_VLAN_FLAG_REORDER_HEADERS; + gvrp = svGetValueBoolean (ifcfg, "GVRP", -1); + if (gvrp > 0) + vlan_flags |= NM_VLAN_FLAG_GVRP; + value = svGetValue (ifcfg, "VLAN_FLAGS", FALSE); if (value) { - if (g_strstr_len (value, -1, "GVRP")) + /* Prefer GVRP variable; only take VLAN_FLAG=GVRP when GVRP is not specified */ + if (g_strstr_len (value, -1, "GVRP") && gvrp == -1) vlan_flags |= NM_VLAN_FLAG_GVRP; if (g_strstr_len (value, -1, "LOOSE_BINDING")) vlan_flags |= NM_VLAN_FLAG_LOOSE_BINDING; } + if (svGetValueBoolean (ifcfg, "MVRP", FALSE)) + vlan_flags |= NM_VLAN_FLAG_MVRP; + g_object_set (s_vlan, NM_SETTING_VLAN_FLAGS, vlan_flags, NULL); g_free (value); diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am index 68ff555263..6d1d21b444 100644 --- a/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/Makefile.am @@ -102,6 +102,8 @@ EXTRA_DIST = \ ifcfg-test-vlan-only-device \ ifcfg-test-vlan-physdev \ ifcfg-test-vlan-reorder-hdr-1 \ + ifcfg-test-vlan-flags-1 \ + ifcfg-test-vlan-flags-2 \ ifcfg-test-wifi-wep-no-keys \ ifcfg-test-permissions \ ifcfg-test-wifi-wep-agent-keys \ diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-flags-1 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-flags-1 new file mode 100644 index 0000000000..5ff8789129 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-flags-1 @@ -0,0 +1,14 @@ +VLAN=yes +TYPE=Vlan +DEVICE=super-vlan +VLAN_ID=44 +PHYSDEV=eth9 +REORDER_HDR=yes +GVRP=no +VLAN_FLAGS="GVRP LOOSE_BINDING" +VLAN_INGRESS_PRIORITY_MAP=0:1,2:5 +VLAN_EGRESS_PRIORITY_MAP=12:3,14:7,3:1 +ONBOOT=yes +BOOTPROTO=static +IPADDR=192.168.43.149 +NETMASK=255.255.255.0 diff --git a/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-flags-2 b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-flags-2 new file mode 100644 index 0000000000..3b536a6628 --- /dev/null +++ b/src/settings/plugins/ifcfg-rh/tests/network-scripts/ifcfg-test-vlan-flags-2 @@ -0,0 +1,11 @@ +VLAN=yes +TYPE=Vlan +DEVICE=super-vlan +VLAN_ID=44 +PHYSDEV=eth9 +REORDER_HDR=no +VLAN_FLAGS="GVRP LOOSE_BINDING" +ONBOOT=yes +BOOTPROTO=static +IPADDR=192.168.43.149 +NETMASK=255.255.255.0 diff --git a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c index f75247b190..2b317e8ee2 100644 --- a/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +++ b/src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c @@ -11004,17 +11004,17 @@ test_read_vlan_interface (void) g_assert_cmpint (nm_setting_vlan_get_num_priorities (s_vlan, NM_VLAN_EGRESS_MAP), ==, 3); g_assert (nm_setting_vlan_get_priority (s_vlan, NM_VLAN_EGRESS_MAP, 0, &from, &to)); + g_assert_cmpint (from, ==, 3); + g_assert_cmpint (to, ==, 1); + + g_assert (nm_setting_vlan_get_priority (s_vlan, NM_VLAN_EGRESS_MAP, 1, &from, &to)); g_assert_cmpint (from, ==, 12); g_assert_cmpint (to, ==, 3); - g_assert (nm_setting_vlan_get_priority (s_vlan, NM_VLAN_EGRESS_MAP, 1, &from, &to)); + g_assert (nm_setting_vlan_get_priority (s_vlan, NM_VLAN_EGRESS_MAP, 2, &from, &to)); g_assert_cmpint (from, ==, 14); g_assert_cmpint (to, ==, 7); - g_assert (nm_setting_vlan_get_priority (s_vlan, NM_VLAN_EGRESS_MAP, 2, &from, &to)); - g_assert_cmpint (from, ==, 3); - g_assert_cmpint (to, ==, 1); - g_object_unref (connection); } @@ -11130,6 +11130,62 @@ test_read_vlan_reorder_hdr_1 (void) g_object_unref (connection); } +static void +test_read_vlan_flags_1 (void) +{ + NMConnection *connection; + GError *error = NULL; + NMSettingVlan *s_vlan; + + connection = connection_from_file_test (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-vlan-flags-1", + NULL, + TYPE_ETHERNET, + NULL, + &error); + g_assert_no_error (error); + g_assert (connection != NULL); + + g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "super-vlan"); + + s_vlan = nm_connection_get_setting_vlan (connection); + g_assert (s_vlan); + + g_assert_cmpstr (nm_setting_vlan_get_parent (s_vlan), ==, "eth9"); + g_assert_cmpint (nm_setting_vlan_get_id (s_vlan), ==, 44); + /* reorder_hdr and loose_binding */ + g_assert_cmpint (nm_setting_vlan_get_flags (s_vlan), ==, 5); + + g_object_unref (connection); +} + +static void +test_read_vlan_flags_2 (void) +{ + NMConnection *connection; + GError *error = NULL; + NMSettingVlan *s_vlan; + + connection = connection_from_file_test (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-vlan-flags-2", + NULL, + TYPE_ETHERNET, + NULL, + &error); + g_assert_no_error (error); + g_assert (connection != NULL); + + g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "super-vlan"); + + s_vlan = nm_connection_get_setting_vlan (connection); + g_assert (s_vlan); + + g_assert_cmpstr (nm_setting_vlan_get_parent (s_vlan), ==, "eth9"); + g_assert_cmpint (nm_setting_vlan_get_id (s_vlan), ==, 44); + /* gvrp and loose_binding */ + g_assert_cmpint (nm_setting_vlan_get_flags (s_vlan), ==, 6); + + g_object_unref (connection); +} + static void test_write_vlan (void) { @@ -11157,6 +11213,54 @@ test_write_vlan (void) g_object_unref (connection); } +static void +test_write_vlan_flags (void) +{ + NMConnection *connection, *reread; + char *written = NULL; + GError *error = NULL; + gboolean success = FALSE; + + connection = connection_from_file_test (TEST_IFCFG_DIR"/network-scripts/ifcfg-test-vlan-flags-2", + NULL, + TYPE_VLAN, + NULL, + &error); + g_assert (connection != NULL); + + success = writer_new_connection (connection, + TEST_SCRATCH_DIR "/network-scripts/", + &written, + &error); + g_assert (success); + + /* reread will be normalized, so we must normalize connection too. */ + nm_connection_normalize (connection, NULL, NULL, NULL); + + /* re-read the connection for comparison */ + reread = connection_from_file_test (written, + NULL, + TYPE_ETHERNET, + NULL, + &error); + + unlink (written); + g_free (written); + + g_assert_no_error (error); + g_assert (reread != NULL); + + success = nm_connection_verify (reread, &error); + g_assert_no_error (error); + g_assert (success); + + success = nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT); + g_assert (success); + + g_object_unref (connection); + g_object_unref (reread); +} + static void test_write_vlan_only_vlanid (void) { @@ -12964,6 +13068,8 @@ int main (int argc, char **argv) test_read_wifi_wep_agent_keys (); test_read_infiniband (); test_read_vlan_interface (); + g_test_add_func (TPATH "vlan/read-flags-1", test_read_vlan_flags_1); + g_test_add_func (TPATH "vlan/read-flags-2", test_read_vlan_flags_2); test_read_vlan_only_vlan_id (); test_read_vlan_only_device (); g_test_add_func (TPATH "vlan/physdev", test_read_vlan_physdev); @@ -13046,6 +13152,7 @@ int main (int argc, char **argv) test_write_wifi_wep_agent_keys (); test_write_infiniband (); test_write_vlan (); + g_test_add_func (TPATH "vlan/write-flags", test_write_vlan_flags); test_write_vlan_only_vlanid (); g_test_add_func (TPATH "vlan/write-vlan-reorder-hdr", test_write_vlan_reorder_hdr); test_write_ethernet_missing_ipv6 (); diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c index 3d03718a81..b2d1419123 100644 --- a/src/settings/plugins/ifcfg-rh/writer.c +++ b/src/settings/plugins/ifcfg-rh/writer.c @@ -1264,15 +1264,14 @@ write_vlan_setting (NMConnection *connection, shvarFile *ifcfg, gboolean *wired, else svSetValue (ifcfg, "REORDER_HDR", "no", FALSE); + svSetValue (ifcfg, "GVRP", vlan_flags & NM_VLAN_FLAG_GVRP ? "yes" : "no", FALSE); + svSetValue (ifcfg, "VLAN_FLAGS", NULL, FALSE); - if (vlan_flags & NM_VLAN_FLAG_GVRP) { - if (vlan_flags & NM_VLAN_FLAG_LOOSE_BINDING) - svSetValue (ifcfg, "VLAN_FLAGS", "GVRP,LOOSE_BINDING", FALSE); - else - svSetValue (ifcfg, "VLAN_FLAGS", "GVRP", FALSE); - } else if (vlan_flags & NM_VLAN_FLAG_LOOSE_BINDING) + if (vlan_flags & NM_VLAN_FLAG_LOOSE_BINDING) svSetValue (ifcfg, "VLAN_FLAGS", "LOOSE_BINDING", FALSE); + svSetValue (ifcfg, "MVRP", vlan_flags & NM_VLAN_FLAG_MVRP ? "yes" : "no", FALSE); + tmp = vlan_priority_maplist_to_stringlist (s_vlan, NM_VLAN_INGRESS_MAP); svSetValue (ifcfg, "VLAN_INGRESS_PRIORITY_MAP", tmp, FALSE); g_free (tmp); diff --git a/src/tests/test-general.c b/src/tests/test-general.c index 3c2a33a97d..3985d23ebe 100644 --- a/src/tests/test-general.c +++ b/src/tests/test-general.c @@ -541,6 +541,62 @@ test_connection_no_match_ip4_addr (void) g_object_unref (copy); } +static void +test_connection_no_match_vlan (void) +{ + NMConnection *orig, *copy, *matched; + GSList *connections = NULL; + NMSettingConnection *s_con; + NMSettingVlan *s_vlan_orig, *s_vlan_copy; + char *uuid; + + orig = nm_simple_connection_new (); + s_con = (NMSettingConnection *) nm_setting_connection_new (); + nm_connection_add_setting (orig, (NMSetting *) s_con); + uuid = nm_utils_uuid_generate (); + g_object_set (G_OBJECT (s_con), + NM_SETTING_CONNECTION_ID, "vlan-test", + NM_SETTING_CONNECTION_UUID, uuid, + NM_SETTING_CONNECTION_TYPE, NM_SETTING_VLAN_SETTING_NAME, + NM_SETTING_CONNECTION_AUTOCONNECT, FALSE, + NULL); + g_free (uuid); + nm_connection_add_setting (orig, nm_setting_vlan_new ()); + + copy = nm_simple_connection_new_clone (orig); + connections = g_slist_append (connections, copy); + + /* Check that the connections do not match if VLAN flags differ */ + s_vlan_orig = nm_connection_get_setting_vlan (orig); + g_assert (s_vlan_orig); + g_object_set (G_OBJECT (s_vlan_orig), + NM_SETTING_VLAN_FLAGS, NM_VLAN_FLAG_REORDER_HEADERS, + NULL); + + s_vlan_copy = nm_connection_get_setting_vlan (copy); + g_assert (s_vlan_copy); + g_object_set (G_OBJECT (s_vlan_copy), + NM_SETTING_VLAN_FLAGS, 0, + NULL); + + matched = nm_utils_match_connection (connections, orig, TRUE, NULL, NULL); + g_assert (matched != copy); + + /* Check that the connections do not match if VLAN priorities differ */ + g_object_set (G_OBJECT (s_vlan_orig), NM_SETTING_VLAN_FLAGS, 0, NULL); + nm_setting_vlan_add_priority_str (s_vlan_orig, NM_VLAN_INGRESS_MAP, "1:3"); + + g_object_set (G_OBJECT (s_vlan_copy), NM_SETTING_VLAN_FLAGS, 0, NULL); + nm_setting_vlan_add_priority_str (s_vlan_copy, NM_VLAN_INGRESS_MAP, "4:2"); + + matched = nm_utils_match_connection (connections, orig, TRUE, NULL, NULL); + g_assert (matched != copy); + + g_slist_free (connections); + g_object_unref (orig); + g_object_unref (copy); +} + static NMConnection * _create_connection_autoconnect (const char *id, gboolean autoconnect, int autoconnect_priority) { @@ -934,6 +990,7 @@ main (int argc, char **argv) g_test_add_func ("/general/connection-match/wired", test_connection_match_wired); g_test_add_func ("/general/connection-match/cloned_mac", test_connection_match_cloned_mac); g_test_add_func ("/general/connection-match/no-match-ip4-addr", test_connection_no_match_ip4_addr); + g_test_add_func ("/general/connection-match/no-match-vlan", test_connection_no_match_vlan); g_test_add_func ("/general/connection-sort/autoconnect-priority", test_connection_sort_autoconnect_priority);