summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2015-10-30 11:02:44 +0100
committerThomas Haller <thaller@redhat.com>2015-11-02 13:12:31 +0100
commitcb968e382b63ca79468e24e2c04539e00f9080a9 (patch)
tree4bafa1fcafe4c4df91a67b0414cdf8b311185d6f
parentf0123557ac5a6aee7202516013b925d3bc8a2f21 (diff)
downloadNetworkManager-th/platform-parse-nl-bgo754570.tar.gz
vlan: handle vlan flags, ingress and egress map in NMDeviceVlanth/platform-parse-nl-bgo754570
In update_connection(), pickup the configuration of the vlan interface from platform and create the proper NMSettingVlan setting. And during stage1, configure the flags of the device. Also, change all the ingress/egress mappings at once instead of having a netlink request for each mapping. Also, ensure we *clear* all other mappings so that only those are set, that were configured (done by the *gress_reset_all argument).
-rw-r--r--libnm-core/nm-core-internal.h11
-rw-r--r--libnm-core/nm-setting-vlan.c82
-rw-r--r--src/devices/nm-device-vlan.c62
3 files changed, 135 insertions, 20 deletions
diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h
index b78a996ea6..4c95d0d0a7 100644
--- a/libnm-core/nm-core-internal.h
+++ b/libnm-core/nm-core-internal.h
@@ -251,4 +251,15 @@ NMUtilsStrStrDictKey *_nm_utils_strstrdictkey_create (const char *v1, const char
/***********************************************************/
+gboolean _nm_setting_vlan_set_priorities (NMSettingVlan *setting,
+ NMVlanPriorityMap map,
+ const NMVlanQosMapping *qos_map,
+ guint n_qos_map);
+void _nm_setting_vlan_get_priorities (NMSettingVlan *setting,
+ NMVlanPriorityMap map,
+ NMVlanQosMapping **out_qos_map,
+ guint *out_n_qos_map);
+
+/***********************************************************/
+
#endif
diff --git a/libnm-core/nm-setting-vlan.c b/libnm-core/nm-setting-vlan.c
index cb971b6d53..8428a36904 100644
--- a/libnm-core/nm-setting-vlan.c
+++ b/libnm-core/nm-setting-vlan.c
@@ -396,6 +396,88 @@ nm_setting_vlan_add_priority (NMSettingVlan *setting,
return TRUE;
}
+gboolean
+_nm_setting_vlan_set_priorities (NMSettingVlan *setting,
+ NMVlanPriorityMap map,
+ const NMVlanQosMapping *qos_map,
+ guint n_qos_map)
+{
+ gboolean has_changes = FALSE;
+ GSList *map_prev, *map_new;
+ guint i;
+ gint64 from_last;
+
+ map_prev = get_map (setting, map);
+
+ if (n_qos_map != g_slist_length (map_prev))
+ has_changes = TRUE;
+ else {
+ const GSList *iter;
+
+ iter = map_prev;
+ for (i = 0; i < n_qos_map; i++, iter = iter->next) {
+ const NMVlanQosMapping *m = iter->data;
+
+ if ( m->from != qos_map[i].from
+ || m->to != qos_map[i].to) {
+ has_changes = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (!has_changes)
+ return FALSE;
+
+ map_new = NULL;
+ from_last = G_MAXINT64;
+ for (i = n_qos_map; i > 0;) {
+ const NMVlanQosMapping *m = &qos_map[--i];
+ NMVlanQosMapping *item;
+
+ /* We require the array to be presorted. */
+ if (m->from >= from_last)
+ g_return_val_if_reached (FALSE);
+ from_last = m->from;
+
+ item = g_malloc0 (sizeof (NMVlanQosMapping));
+ item->from = m->from;
+ item->to = m->to;
+ map_new = g_slist_prepend (map_new, item);
+ }
+
+ g_slist_free_full (map_prev, g_free);
+ set_map (setting, map, map_new);
+
+ return TRUE;
+}
+
+void
+_nm_setting_vlan_get_priorities (NMSettingVlan *setting,
+ NMVlanPriorityMap map,
+ NMVlanQosMapping **out_qos_map,
+ guint *out_n_qos_map)
+{
+ GSList *list;
+ NMVlanQosMapping *qos_map = NULL;
+ guint n_qos_map, i;
+
+ list = get_map (setting, map);
+
+ n_qos_map = g_slist_length (list);
+
+ if (n_qos_map > 0) {
+ qos_map = g_new (NMVlanQosMapping, n_qos_map);
+
+ for (i = 0; list; i++, list = list->next) {
+ nm_assert (i < n_qos_map);
+ qos_map[i] = *((const NMVlanQosMapping *) list->data);
+ }
+ }
+ *out_qos_map = qos_map;
+ *out_n_qos_map = n_qos_map;
+}
+
/**
* nm_setting_vlan_remove_priority:
* @setting: the #NMSettingVlan
diff --git a/src/devices/nm-device-vlan.c b/src/devices/nm-device-vlan.c
index de3a57e110..55790a9273 100644
--- a/src/devices/nm-device-vlan.c
+++ b/src/devices/nm-device-vlan.c
@@ -36,6 +36,7 @@
#include "nm-device-factory.h"
#include "nm-manager.h"
#include "nm-core-internal.h"
+#include "nmp-object.h"
#include "nmdbus-device-vlan.h"
@@ -468,25 +469,27 @@ update_connection (NMDevice *device, NMConnection *connection)
NMDevice *parent;
const char *setting_parent, *new_parent;
const NMPlatformLink *plink;
- const NMPlatformLnkVlan *plnk;
+ const NMPObject *polnk;
+ nm_auto_nmpobj NMPObject *polnk_ref = NULL;
if (!s_vlan) {
s_vlan = (NMSettingVlan *) nm_setting_vlan_new ();
nm_connection_add_setting (connection, (NMSetting *) s_vlan);
}
- plnk = nm_platform_link_get_lnk_vlan (NM_PLATFORM_GET, ifindex, &plink);
- if (!plnk) {
+ polnk = nm_platform_link_get_lnk (NM_PLATFORM_GET, ifindex, NM_LINK_TYPE_VLAN, &plink);
+ if (!polnk) {
_LOGW (LOGD_VLAN, "failed to get VLAN interface info while updating connection.");
return;
}
+ polnk_ref = nmp_object_ref ((NMPObject *) polnk);
- if (priv->vlan_id != plnk->id) {
- priv->vlan_id = plnk->id;
+ if (priv->vlan_id != polnk->lnk_vlan.id) {
+ priv->vlan_id = polnk->lnk_vlan.id;
g_object_notify (G_OBJECT (device), NM_DEVICE_VLAN_ID);
}
- if (plnk->id != nm_setting_vlan_get_id (s_vlan))
+ if (polnk->lnk_vlan.id != nm_setting_vlan_get_id (s_vlan))
g_object_set (s_vlan, NM_SETTING_VLAN_ID, priv->vlan_id, NULL);
if (plink->parent != NM_PLATFORM_LINK_OTHER_NETNS)
@@ -511,6 +514,16 @@ update_connection (NMDevice *device, NMConnection *connection)
g_object_set (s_vlan, NM_SETTING_VLAN_PARENT, new_parent, NULL);
} else
g_object_set (s_vlan, NM_SETTING_VLAN_PARENT, NULL, NULL);
+
+ if (polnk->lnk_vlan.flags != nm_setting_vlan_get_flags (s_vlan))
+ g_object_set (s_vlan, NM_SETTING_VLAN_FLAGS, (NMVlanFlags) polnk->lnk_vlan.flags, NULL);
+
+ _nm_setting_vlan_set_priorities (s_vlan, NM_VLAN_INGRESS_MAP,
+ polnk->_lnk_vlan.ingress_qos_map,
+ polnk->_lnk_vlan.n_ingress_qos_map);
+ _nm_setting_vlan_set_priorities (s_vlan, NM_VLAN_EGRESS_MAP,
+ polnk->_lnk_vlan.egress_qos_map,
+ polnk->_lnk_vlan.n_egress_qos_map);
}
static NMActStageReturn
@@ -545,20 +558,29 @@ act_stage1_prepare (NMDevice *dev, NMDeviceStateReason *reason)
s_vlan = nm_connection_get_setting_vlan (connection);
if (s_vlan) {
- int ifindex = nm_device_get_ifindex (dev);
- int num, i;
- guint32 from, to;
-
- num = nm_setting_vlan_get_num_priorities (s_vlan, NM_VLAN_INGRESS_MAP);
- for (i = 0; i < num; i++) {
- if (nm_setting_vlan_get_priority (s_vlan, NM_VLAN_INGRESS_MAP, i, &from, &to))
- nm_platform_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, from, to);
- }
- num = nm_setting_vlan_get_num_priorities (s_vlan, NM_VLAN_EGRESS_MAP);
- for (i = 0; i < num; i++) {
- if (nm_setting_vlan_get_priority (s_vlan, NM_VLAN_EGRESS_MAP, i, &from, &to))
- nm_platform_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, from, to);
- }
+ gs_free NMVlanQosMapping *ingress_map = NULL;
+ gs_free NMVlanQosMapping *egress_map = NULL;
+ guint n_ingress_map = 0, n_egress_map = 0;
+
+ _nm_setting_vlan_get_priorities (s_vlan,
+ NM_VLAN_INGRESS_MAP,
+ &ingress_map,
+ &n_ingress_map);
+ _nm_setting_vlan_get_priorities (s_vlan,
+ NM_VLAN_EGRESS_MAP,
+ &egress_map,
+ &n_egress_map);
+
+ nm_platform_link_vlan_change (NM_PLATFORM_GET,
+ nm_device_get_ifindex (dev),
+ NM_VLAN_FLAGS_ALL,
+ nm_setting_vlan_get_flags (s_vlan),
+ TRUE,
+ ingress_map,
+ n_ingress_map,
+ TRUE,
+ egress_map,
+ n_egress_map);
}
return ret;