platform/vlan: add support for ingress/egress-qos-mappings and changing flags
Previously, we could only set the ingress-qos-mappings/egress-qos-mappings. Now also cache the mappings and expose them from the platform cache. Also, support changing the vlan flags not only when creating the vlan interface.
This commit is contained in:
@@ -685,15 +685,18 @@ vlan_add (NMPlatform *platform, const char *name, int parent, int vlan_id, guint
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
vlan_set_ingress_map (NMPlatform *platform, int ifindex, int from, int to)
|
link_vlan_change (NMPlatform *platform,
|
||||||
|
int ifindex,
|
||||||
|
NMVlanFlags flags_mask,
|
||||||
|
NMVlanFlags flags_set,
|
||||||
|
gboolean ingress_reset_all,
|
||||||
|
const NMVlanQosMapping *ingress_map,
|
||||||
|
gsize n_ingress_map,
|
||||||
|
gboolean egress_reset_all,
|
||||||
|
const NMVlanQosMapping *egress_map,
|
||||||
|
gsize n_egress_map)
|
||||||
{
|
{
|
||||||
return !!link_get (platform, ifindex);
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
vlan_set_egress_map (NMPlatform *platform, int ifindex, int from, int to)
|
|
||||||
{
|
|
||||||
return !!link_get (platform, ifindex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@@ -1445,8 +1448,7 @@ nm_fake_platform_class_init (NMFakePlatformClass *klass)
|
|||||||
platform_class->slave_get_option = slave_get_option;
|
platform_class->slave_get_option = slave_get_option;
|
||||||
|
|
||||||
platform_class->vlan_add = vlan_add;
|
platform_class->vlan_add = vlan_add;
|
||||||
platform_class->vlan_set_ingress_map = vlan_set_ingress_map;
|
platform_class->link_vlan_change = link_vlan_change;
|
||||||
platform_class->vlan_set_egress_map = vlan_set_egress_map;
|
|
||||||
|
|
||||||
platform_class->infiniband_partition_add = infiniband_partition_add;
|
platform_class->infiniband_partition_add = infiniband_partition_add;
|
||||||
|
|
||||||
|
@@ -255,6 +255,25 @@ clear_host_address (int family, const void *network, int plen, void *dst)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_vlan_qos_mapping_cmp_from (gconstpointer a, gconstpointer b, gpointer user_data)
|
||||||
|
{
|
||||||
|
const NMVlanQosMapping *map_a = a;
|
||||||
|
const NMVlanQosMapping *map_b = b;
|
||||||
|
|
||||||
|
if (map_a->from != map_b->from)
|
||||||
|
return map_a->from < map_b->from ? -1 : 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_vlan_qos_mapping_cmp_from_ptr (gconstpointer a, gconstpointer b, gpointer user_data)
|
||||||
|
{
|
||||||
|
return _vlan_qos_mapping_cmp_from (*((const NMVlanQosMapping **) a),
|
||||||
|
*((const NMVlanQosMapping **) b),
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* NMLinkType functions
|
* NMLinkType functions
|
||||||
******************************************************************/
|
******************************************************************/
|
||||||
@@ -929,6 +948,65 @@ _parse_lnk_macvlan (const char *kind, struct nlattr *info_data)
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_vlan_qos_mapping_from_nla (struct nlattr *nlattr,
|
||||||
|
const NMVlanQosMapping **out_map,
|
||||||
|
guint *out_n_map)
|
||||||
|
{
|
||||||
|
struct nlattr *nla;
|
||||||
|
int remaining;
|
||||||
|
gs_unref_ptrarray GPtrArray *array = NULL;
|
||||||
|
|
||||||
|
G_STATIC_ASSERT (sizeof (NMVlanQosMapping) == sizeof (struct ifla_vlan_qos_mapping));
|
||||||
|
G_STATIC_ASSERT (sizeof (((NMVlanQosMapping *) 0)->to) == sizeof (((struct ifla_vlan_qos_mapping *) 0)->to));
|
||||||
|
G_STATIC_ASSERT (sizeof (((NMVlanQosMapping *) 0)->from) == sizeof (((struct ifla_vlan_qos_mapping *) 0)->from));
|
||||||
|
G_STATIC_ASSERT (sizeof (NMVlanQosMapping) == sizeof (((NMVlanQosMapping *) 0)->from) + sizeof (((NMVlanQosMapping *) 0)->to));
|
||||||
|
|
||||||
|
nm_assert (out_map && !*out_map);
|
||||||
|
nm_assert (out_n_map && !*out_n_map);
|
||||||
|
|
||||||
|
if (!nlattr)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
array = g_ptr_array_new ();
|
||||||
|
nla_for_each_nested (nla, nlattr, remaining) {
|
||||||
|
if (nla_len (nla) < sizeof(NMVlanQosMapping))
|
||||||
|
return FALSE;
|
||||||
|
g_ptr_array_add (array, nla_data (nla));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array->len > 0) {
|
||||||
|
NMVlanQosMapping *list;
|
||||||
|
guint i, j;
|
||||||
|
|
||||||
|
/* The sorting is necessary, because for egress mapping, kernel
|
||||||
|
* doesn't sent the items strictly sorted by the from field. */
|
||||||
|
g_ptr_array_sort_with_data (array, _vlan_qos_mapping_cmp_from_ptr, NULL);
|
||||||
|
|
||||||
|
list = g_new (NMVlanQosMapping, array->len);
|
||||||
|
|
||||||
|
for (i = 0, j = 0; i < array->len; i++) {
|
||||||
|
NMVlanQosMapping *map;
|
||||||
|
|
||||||
|
map = array->pdata[i];
|
||||||
|
|
||||||
|
/* kernel doesn't really send us duplicates. Just be extra cautious
|
||||||
|
* because we want strong guarantees about the sort order and uniqueness
|
||||||
|
* of our mapping list (for simpler equality comparison). */
|
||||||
|
if ( j > 0
|
||||||
|
&& list[j - 1].from == map->from)
|
||||||
|
list[j - 1] = *map;
|
||||||
|
else
|
||||||
|
list[j++] = *map;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_n_map = j;
|
||||||
|
*out_map = list;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Copied and heavily modified from libnl3's vlan_parse() */
|
/* Copied and heavily modified from libnl3's vlan_parse() */
|
||||||
static NMPObject *
|
static NMPObject *
|
||||||
_parse_lnk_vlan (const char *kind, struct nlattr *info_data)
|
_parse_lnk_vlan (const char *kind, struct nlattr *info_data)
|
||||||
@@ -942,7 +1020,8 @@ _parse_lnk_vlan (const char *kind, struct nlattr *info_data)
|
|||||||
};
|
};
|
||||||
struct nlattr *tb[IFLA_VLAN_MAX+1];
|
struct nlattr *tb[IFLA_VLAN_MAX+1];
|
||||||
int err;
|
int err;
|
||||||
NMPObject *obj = NULL;
|
nm_auto_nmpobj NMPObject *obj = NULL;
|
||||||
|
NMPObject *obj_result;
|
||||||
|
|
||||||
if (!info_data || g_strcmp0 (kind, "vlan"))
|
if (!info_data || g_strcmp0 (kind, "vlan"))
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -954,9 +1033,30 @@ _parse_lnk_vlan (const char *kind, struct nlattr *info_data)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
obj = nmp_object_new (NMP_OBJECT_TYPE_LNK_VLAN, NULL);
|
obj = nmp_object_new (NMP_OBJECT_TYPE_LNK_VLAN, NULL);
|
||||||
obj->lnk_vlan.id = nla_get_u16(tb[IFLA_VLAN_ID]);
|
obj->lnk_vlan.id = nla_get_u16 (tb[IFLA_VLAN_ID]);
|
||||||
|
|
||||||
return obj;
|
if (tb[IFLA_VLAN_FLAGS]) {
|
||||||
|
struct ifla_vlan_flags flags;
|
||||||
|
|
||||||
|
nla_memcpy (&flags, tb[IFLA_VLAN_FLAGS], sizeof(flags));
|
||||||
|
|
||||||
|
obj->lnk_vlan.flags = flags.flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_vlan_qos_mapping_from_nla (tb[IFLA_VLAN_INGRESS_QOS],
|
||||||
|
&obj->_lnk_vlan.ingress_qos_map,
|
||||||
|
&obj->_lnk_vlan.n_ingress_qos_map))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!_vlan_qos_mapping_from_nla (tb[IFLA_VLAN_EGRESS_QOS],
|
||||||
|
&obj->_lnk_vlan.egress_qos_map,
|
||||||
|
&obj->_lnk_vlan.n_egress_qos_map))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
|
||||||
|
obj_result = obj;
|
||||||
|
obj = NULL;
|
||||||
|
return obj_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -1676,17 +1776,46 @@ _nl_msg_new_link_set_linkinfo_vlan (struct nl_msg *msg,
|
|||||||
int vlan_id,
|
int vlan_id,
|
||||||
guint32 flags_mask,
|
guint32 flags_mask,
|
||||||
guint32 flags_set,
|
guint32 flags_set,
|
||||||
const struct ifla_vlan_qos_mapping *ingress_qos,
|
const NMVlanQosMapping *ingress_qos,
|
||||||
int ingress_qos_len,
|
int ingress_qos_len,
|
||||||
const struct ifla_vlan_qos_mapping *egress_qos,
|
const NMVlanQosMapping *egress_qos,
|
||||||
int egress_qos_len)
|
int egress_qos_len)
|
||||||
{
|
{
|
||||||
struct nlattr *info;
|
struct nlattr *info;
|
||||||
struct nlattr *data;
|
struct nlattr *data;
|
||||||
guint i;
|
guint i;
|
||||||
|
gboolean has_any_vlan_properties = FALSE;
|
||||||
|
|
||||||
|
#define VLAN_XGRESS_PRIO_VALID(from) (((from) & ~(guint32) 0x07) == 0)
|
||||||
|
|
||||||
nm_assert (msg);
|
nm_assert (msg);
|
||||||
|
|
||||||
|
/* We must not create an empty IFLA_LINKINFO section. Otherwise, kernel
|
||||||
|
* rejects the request as invalid. */
|
||||||
|
if ( flags_mask != 0
|
||||||
|
|| vlan_id >= 0)
|
||||||
|
has_any_vlan_properties = TRUE;
|
||||||
|
if ( !has_any_vlan_properties
|
||||||
|
&& ingress_qos && ingress_qos_len > 0) {
|
||||||
|
for (i = 0; i < ingress_qos_len; i++) {
|
||||||
|
if (VLAN_XGRESS_PRIO_VALID (ingress_qos[i].from)) {
|
||||||
|
has_any_vlan_properties = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( !has_any_vlan_properties
|
||||||
|
&& egress_qos && egress_qos_len > 0) {
|
||||||
|
for (i = 0; i < egress_qos_len; i++) {
|
||||||
|
if (VLAN_XGRESS_PRIO_VALID (egress_qos[i].to)) {
|
||||||
|
has_any_vlan_properties = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!has_any_vlan_properties)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
if (!(info = nla_nest_start (msg, IFLA_LINKINFO)))
|
if (!(info = nla_nest_start (msg, IFLA_LINKINFO)))
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
|
|
||||||
@@ -1708,26 +1837,38 @@ _nl_msg_new_link_set_linkinfo_vlan (struct nl_msg *msg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ingress_qos && ingress_qos_len > 0) {
|
if (ingress_qos && ingress_qos_len > 0) {
|
||||||
struct nlattr *qos;
|
struct nlattr *qos = NULL;
|
||||||
|
|
||||||
if (!(qos = nla_nest_start(msg, IFLA_VLAN_INGRESS_QOS)))
|
for (i = 0; i < ingress_qos_len; i++) {
|
||||||
|
/* Silently ignore invalid mappings. Kernel would truncate
|
||||||
|
* them and modify the wrong mapping. */
|
||||||
|
if (VLAN_XGRESS_PRIO_VALID (ingress_qos[i].from)) {
|
||||||
|
if (!qos) {
|
||||||
|
if (!(qos = nla_nest_start (msg, IFLA_VLAN_INGRESS_QOS)))
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
|
}
|
||||||
for (i = 0; i < ingress_qos_len; i++)
|
|
||||||
NLA_PUT (msg, i, sizeof (ingress_qos[i]), &ingress_qos[i]);
|
NLA_PUT (msg, i, sizeof (ingress_qos[i]), &ingress_qos[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nla_nest_end(msg, qos);
|
if (qos)
|
||||||
|
nla_nest_end (msg, qos);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (egress_qos && egress_qos_len > 0) {
|
if (egress_qos && egress_qos_len > 0) {
|
||||||
struct nlattr *qos;
|
struct nlattr *qos = NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < egress_qos_len; i++) {
|
||||||
|
if (VLAN_XGRESS_PRIO_VALID (egress_qos[i].to)) {
|
||||||
|
if (!qos) {
|
||||||
if (!(qos = nla_nest_start(msg, IFLA_VLAN_EGRESS_QOS)))
|
if (!(qos = nla_nest_start(msg, IFLA_VLAN_EGRESS_QOS)))
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
|
}
|
||||||
for (i = 0; i < egress_qos_len; i++)
|
|
||||||
NLA_PUT (msg, i, sizeof (egress_qos[i]), &egress_qos[i]);
|
NLA_PUT (msg, i, sizeof (egress_qos[i]), &egress_qos[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qos)
|
||||||
nla_nest_end(msg, qos);
|
nla_nest_end(msg, qos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3950,54 +4091,155 @@ nla_put_failure:
|
|||||||
g_return_val_if_reached (FALSE);
|
g_return_val_if_reached (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static void
|
||||||
vlan_set_ingress_map (NMPlatform *platform, int ifindex, int from, int to)
|
_vlan_change_vlan_qos_mapping_create (gboolean is_ingress_map,
|
||||||
|
gboolean reset_all,
|
||||||
|
const NMVlanQosMapping *current_map,
|
||||||
|
guint current_n_map,
|
||||||
|
const NMVlanQosMapping *set_map,
|
||||||
|
guint set_n_map,
|
||||||
|
NMVlanQosMapping **out_map,
|
||||||
|
guint *out_n_map)
|
||||||
{
|
{
|
||||||
nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
|
NMVlanQosMapping *map;
|
||||||
struct ifla_vlan_qos_mapping ingress_qos = {
|
guint i, j, len;
|
||||||
.from = from,
|
const guint INGRESS_RANGE_LEN = 8;
|
||||||
.to = to,
|
|
||||||
};
|
|
||||||
unsigned flags;
|
|
||||||
|
|
||||||
if (!_lookup_cached_link_data (platform, ifindex, "vlan-ingress", &flags))
|
nm_assert (out_map && !*out_map);
|
||||||
return FALSE;
|
nm_assert (out_n_map && !*out_n_map);
|
||||||
|
|
||||||
_LOGD ("link: change %d: vlan-ingress: set %d -> %d", ifindex, from, to);
|
if (!reset_all)
|
||||||
|
current_n_map = 0;
|
||||||
|
else if (is_ingress_map)
|
||||||
|
current_n_map = INGRESS_RANGE_LEN;
|
||||||
|
|
||||||
nlmsg = _nl_msg_new_link (RTM_NEWLINK,
|
len = current_n_map + set_n_map;
|
||||||
0,
|
|
||||||
ifindex,
|
|
||||||
NULL,
|
|
||||||
flags);
|
|
||||||
if ( !nlmsg
|
|
||||||
|| !_nl_msg_new_link_set_linkinfo_vlan (nlmsg,
|
|
||||||
-1,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
&ingress_qos,
|
|
||||||
1,
|
|
||||||
NULL,
|
|
||||||
0))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
return do_change_link (platform, ifindex, nlmsg) == NM_PLATFORM_ERROR_SUCCESS;
|
if (len == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
map = g_new (NMVlanQosMapping, len);
|
||||||
|
|
||||||
|
if (current_n_map) {
|
||||||
|
if (is_ingress_map) {
|
||||||
|
/* For the ingress-map, there are only 8 entries (0 to 7).
|
||||||
|
* When the user requests to reset all entires, we don't actually
|
||||||
|
* need the cached entries, we can just explicitly clear all possible
|
||||||
|
* ones.
|
||||||
|
*
|
||||||
|
* That makes only a real difference in case our cache is out-of-date.
|
||||||
|
*
|
||||||
|
* For the egress map we cannot do that, because there are far too
|
||||||
|
* many. There we can only clear the entries that we know about. */
|
||||||
|
for (i = 0; i < INGRESS_RANGE_LEN; i++) {
|
||||||
|
map[i].from = i;
|
||||||
|
map[i].to = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (i = 0; i < current_n_map; i++) {
|
||||||
|
map[i].from = current_map[i].from;
|
||||||
|
map[i].to = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (set_n_map)
|
||||||
|
memcpy (&map[current_n_map], set_map, sizeof (*set_map) * set_n_map);
|
||||||
|
|
||||||
|
g_qsort_with_data (map,
|
||||||
|
len,
|
||||||
|
sizeof (*map),
|
||||||
|
_vlan_qos_mapping_cmp_from,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
for (i = 0, j = 0; i < len; i++) {
|
||||||
|
if ( ( is_ingress_map && !VLAN_XGRESS_PRIO_VALID (map[i].from))
|
||||||
|
|| (!is_ingress_map && !VLAN_XGRESS_PRIO_VALID (map[i].to)))
|
||||||
|
continue;
|
||||||
|
if ( j > 0
|
||||||
|
&& map[j - 1].from == map[i].from)
|
||||||
|
map[j - 1] = map[i];
|
||||||
|
else
|
||||||
|
map[j++] = map[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_map = map;
|
||||||
|
*out_n_map = j;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
vlan_set_egress_map (NMPlatform *platform, int ifindex, int from, int to)
|
link_vlan_change (NMPlatform *platform,
|
||||||
|
int ifindex,
|
||||||
|
NMVlanFlags flags_mask,
|
||||||
|
NMVlanFlags flags_set,
|
||||||
|
gboolean ingress_reset_all,
|
||||||
|
const NMVlanQosMapping *ingress_map,
|
||||||
|
gsize n_ingress_map,
|
||||||
|
gboolean egress_reset_all,
|
||||||
|
const NMVlanQosMapping *egress_map,
|
||||||
|
gsize n_egress_map)
|
||||||
{
|
{
|
||||||
|
NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
|
||||||
|
const NMPObject *obj_cache;
|
||||||
nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
|
nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
|
||||||
struct ifla_vlan_qos_mapping egress_qos = {
|
|
||||||
.from = from,
|
|
||||||
.to = to,
|
|
||||||
};
|
|
||||||
unsigned flags;
|
unsigned flags;
|
||||||
|
const NMPObjectLnkVlan *lnk;
|
||||||
|
guint new_n_ingress_map = 0;
|
||||||
|
guint new_n_egress_map = 0;
|
||||||
|
gs_free NMVlanQosMapping *new_ingress_map = NULL;
|
||||||
|
gs_free NMVlanQosMapping *new_egress_map = NULL;
|
||||||
|
char s_flags[64];
|
||||||
|
char s_ingress[256];
|
||||||
|
char s_egress[256];
|
||||||
|
|
||||||
if (!_lookup_cached_link_data (platform, ifindex, "vlan-egress", &flags))
|
obj_cache = nmp_cache_lookup_link (priv->cache, ifindex);
|
||||||
|
if ( !obj_cache
|
||||||
|
|| !obj_cache->_link.netlink.is_in_netlink) {
|
||||||
|
_LOGD ("link: change %d: %s: link does not exist", ifindex, "vlan");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
_LOGD ("link: change %d: vlan-egress: set %d -> %d", ifindex, from, to);
|
lnk = obj_cache->_link.netlink.lnk ? &obj_cache->_link.netlink.lnk->_lnk_vlan : NULL;
|
||||||
|
flags = obj_cache->link.flags;
|
||||||
|
|
||||||
|
flags_set &= flags_mask;
|
||||||
|
|
||||||
|
_vlan_change_vlan_qos_mapping_create (TRUE,
|
||||||
|
ingress_reset_all,
|
||||||
|
lnk ? lnk->ingress_qos_map : NULL,
|
||||||
|
lnk ? lnk->n_ingress_qos_map : 0,
|
||||||
|
ingress_map,
|
||||||
|
n_ingress_map,
|
||||||
|
&new_ingress_map,
|
||||||
|
&new_n_ingress_map);
|
||||||
|
|
||||||
|
_vlan_change_vlan_qos_mapping_create (FALSE,
|
||||||
|
egress_reset_all,
|
||||||
|
lnk ? lnk->egress_qos_map : NULL,
|
||||||
|
lnk ? lnk->n_egress_qos_map : 0,
|
||||||
|
egress_map,
|
||||||
|
n_egress_map,
|
||||||
|
&new_egress_map,
|
||||||
|
&new_n_egress_map);
|
||||||
|
|
||||||
|
_LOGD ("link: change %d: vlan:%s%s%s",
|
||||||
|
ifindex,
|
||||||
|
flags_mask
|
||||||
|
? nm_sprintf_buf (s_flags, " flags 0x%x/0x%x", (unsigned) flags_set, (unsigned) flags_mask)
|
||||||
|
: "",
|
||||||
|
new_n_ingress_map
|
||||||
|
? nm_platform_vlan_qos_mapping_to_string (" ingress-qos-map",
|
||||||
|
new_ingress_map,
|
||||||
|
new_n_ingress_map,
|
||||||
|
s_ingress,
|
||||||
|
sizeof (s_ingress))
|
||||||
|
: "",
|
||||||
|
new_n_egress_map
|
||||||
|
? nm_platform_vlan_qos_mapping_to_string (" egress-qos-map",
|
||||||
|
new_egress_map,
|
||||||
|
new_n_egress_map,
|
||||||
|
s_egress,
|
||||||
|
sizeof (s_egress))
|
||||||
|
: "");
|
||||||
|
|
||||||
nlmsg = _nl_msg_new_link (RTM_NEWLINK,
|
nlmsg = _nl_msg_new_link (RTM_NEWLINK,
|
||||||
0,
|
0,
|
||||||
@@ -4007,12 +4249,12 @@ vlan_set_egress_map (NMPlatform *platform, int ifindex, int from, int to)
|
|||||||
if ( !nlmsg
|
if ( !nlmsg
|
||||||
|| !_nl_msg_new_link_set_linkinfo_vlan (nlmsg,
|
|| !_nl_msg_new_link_set_linkinfo_vlan (nlmsg,
|
||||||
-1,
|
-1,
|
||||||
0,
|
flags_mask,
|
||||||
0,
|
flags_set,
|
||||||
NULL,
|
new_ingress_map,
|
||||||
0,
|
new_n_ingress_map,
|
||||||
&egress_qos,
|
new_egress_map,
|
||||||
1))
|
new_n_egress_map))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
return do_change_link (platform, ifindex, nlmsg) == NM_PLATFORM_ERROR_SUCCESS;
|
return do_change_link (platform, ifindex, nlmsg) == NM_PLATFORM_ERROR_SUCCESS;
|
||||||
@@ -5228,8 +5470,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass)
|
|||||||
platform_class->slave_get_option = slave_get_option;
|
platform_class->slave_get_option = slave_get_option;
|
||||||
|
|
||||||
platform_class->vlan_add = vlan_add;
|
platform_class->vlan_add = vlan_add;
|
||||||
platform_class->vlan_set_ingress_map = vlan_set_ingress_map;
|
platform_class->link_vlan_change = link_vlan_change;
|
||||||
platform_class->vlan_set_egress_map = vlan_set_egress_map;
|
|
||||||
|
|
||||||
platform_class->infiniband_partition_add = infiniband_partition_add;
|
platform_class->infiniband_partition_add = infiniband_partition_add;
|
||||||
|
|
||||||
|
@@ -1582,25 +1582,91 @@ nm_platform_slave_get_option (NMPlatform *self, int ifindex, const char *option)
|
|||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
nm_platform_vlan_set_ingress_map (NMPlatform *self, int ifindex, int from, int to)
|
nm_platform_link_vlan_change (NMPlatform *self,
|
||||||
|
int ifindex,
|
||||||
|
NMVlanFlags flags_mask,
|
||||||
|
NMVlanFlags flags_set,
|
||||||
|
gboolean ingress_reset_all,
|
||||||
|
const NMVlanQosMapping *ingress_map,
|
||||||
|
gsize n_ingress_map,
|
||||||
|
gboolean egress_reset_all,
|
||||||
|
const NMVlanQosMapping *egress_map,
|
||||||
|
gsize n_egress_map)
|
||||||
{
|
{
|
||||||
_CHECK_SELF (self, klass, FALSE);
|
_CHECK_SELF (self, klass, FALSE);
|
||||||
|
|
||||||
g_return_val_if_fail (klass->vlan_set_ingress_map, FALSE);
|
nm_assert (klass->link_vlan_change);
|
||||||
|
|
||||||
_LOGD ("link: setting vlan ingress map for %d from %d to %d", ifindex, from, to);
|
g_return_val_if_fail (!n_ingress_map || ingress_map, FALSE);
|
||||||
return klass->vlan_set_ingress_map (self, ifindex, from, to);
|
g_return_val_if_fail (!n_egress_map || egress_map, FALSE);
|
||||||
|
|
||||||
|
flags_set &= flags_mask;
|
||||||
|
|
||||||
|
if (_LOGD_ENABLED ()) {
|
||||||
|
char buf[512];
|
||||||
|
char *b = buf;
|
||||||
|
gsize len, i;
|
||||||
|
|
||||||
|
b[0] = '\0';
|
||||||
|
len = sizeof (buf);
|
||||||
|
|
||||||
|
if (flags_mask)
|
||||||
|
nm_utils_strbuf_append (&b, &len, " flags 0x%x/0x%x", (unsigned) flags_set, (unsigned) flags_mask);
|
||||||
|
|
||||||
|
if (ingress_reset_all || n_ingress_map) {
|
||||||
|
nm_utils_strbuf_append_str (&b, &len, " ingress-qos-map");
|
||||||
|
nm_platform_vlan_qos_mapping_to_string ("", ingress_map, n_ingress_map, b, len);
|
||||||
|
i = strlen (b);
|
||||||
|
b += i;
|
||||||
|
len -= i;
|
||||||
|
if (ingress_reset_all)
|
||||||
|
nm_utils_strbuf_append_str (&b, &len, " (reset-all)");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (egress_reset_all || n_egress_map) {
|
||||||
|
nm_utils_strbuf_append_str (&b, &len, " egress-qos-map");
|
||||||
|
nm_platform_vlan_qos_mapping_to_string ("", egress_map, n_egress_map, b, len);
|
||||||
|
i = strlen (b);
|
||||||
|
b += i;
|
||||||
|
len -= i;
|
||||||
|
if (egress_reset_all)
|
||||||
|
nm_utils_strbuf_append_str (&b, &len, " (reset-all)");
|
||||||
|
}
|
||||||
|
|
||||||
|
_LOGD ("link: change vlan %d:%s", ifindex, buf);
|
||||||
|
}
|
||||||
|
return klass->link_vlan_change (self,
|
||||||
|
ifindex,
|
||||||
|
flags_mask,
|
||||||
|
flags_set,
|
||||||
|
ingress_reset_all,
|
||||||
|
ingress_map,
|
||||||
|
n_ingress_map,
|
||||||
|
egress_reset_all,
|
||||||
|
egress_map,
|
||||||
|
n_egress_map);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
nm_platform_vlan_set_ingress_map (NMPlatform *self, int ifindex, int from, int to)
|
||||||
|
{
|
||||||
|
NMVlanQosMapping map = {
|
||||||
|
.from = from,
|
||||||
|
.to = to,
|
||||||
|
};
|
||||||
|
|
||||||
|
return nm_platform_link_vlan_change (self, ifindex, 0, 0, FALSE, &map, 1, FALSE, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
nm_platform_vlan_set_egress_map (NMPlatform *self, int ifindex, int from, int to)
|
nm_platform_vlan_set_egress_map (NMPlatform *self, int ifindex, int from, int to)
|
||||||
{
|
{
|
||||||
_CHECK_SELF (self, klass, FALSE);
|
NMVlanQosMapping map = {
|
||||||
|
.from = from,
|
||||||
|
.to = to,
|
||||||
|
};
|
||||||
|
|
||||||
g_return_val_if_fail (klass->vlan_set_egress_map, FALSE);
|
return nm_platform_link_vlan_change (self, ifindex, 0, 0, FALSE, NULL, 0, FALSE, &map, 1);
|
||||||
|
|
||||||
_LOGD ("link: setting vlan egress map for %d from %d to %d", ifindex, from, to);
|
|
||||||
return klass->vlan_set_egress_map (self, ifindex, from, to);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NMPlatformError
|
NMPlatformError
|
||||||
@@ -2438,6 +2504,40 @@ nm_platform_ip6_route_get (NMPlatform *self, int ifindex, struct in6_addr networ
|
|||||||
|
|
||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
|
|
||||||
|
const char *
|
||||||
|
nm_platform_vlan_qos_mapping_to_string (const char *name,
|
||||||
|
const NMVlanQosMapping *map,
|
||||||
|
gsize n_map,
|
||||||
|
char *buf,
|
||||||
|
gsize len)
|
||||||
|
{
|
||||||
|
gsize i;
|
||||||
|
char *b;
|
||||||
|
|
||||||
|
nm_utils_to_string_buffer_init (&buf, &len);
|
||||||
|
|
||||||
|
if (!n_map) {
|
||||||
|
nm_utils_strbuf_append_str (&buf, &len, "");
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!map)
|
||||||
|
g_return_val_if_reached ("");
|
||||||
|
|
||||||
|
b = buf;
|
||||||
|
|
||||||
|
if (name) {
|
||||||
|
nm_utils_strbuf_append_str (&b, &len, name);
|
||||||
|
nm_utils_strbuf_append_str (&b, &len, " {");
|
||||||
|
} else
|
||||||
|
nm_utils_strbuf_append_c (&b, &len, '{');
|
||||||
|
|
||||||
|
for (i = 0; i < n_map; i++)
|
||||||
|
nm_utils_strbuf_append (&b, &len, " %u:%u", map[i].from, map[i].to);
|
||||||
|
nm_utils_strbuf_append_str (&b, &len, " }");
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
source_to_string (NMIPConfigSource source)
|
source_to_string (NMIPConfigSource source)
|
||||||
{
|
{
|
||||||
@@ -2685,10 +2785,16 @@ nm_platform_lnk_macvlan_to_string (const NMPlatformLnkMacvlan *lnk, char *buf, g
|
|||||||
const char *
|
const char *
|
||||||
nm_platform_lnk_vlan_to_string (const NMPlatformLnkVlan *lnk, char *buf, gsize len)
|
nm_platform_lnk_vlan_to_string (const NMPlatformLnkVlan *lnk, char *buf, gsize len)
|
||||||
{
|
{
|
||||||
|
char *b;
|
||||||
|
|
||||||
if (!nm_utils_to_string_buffer_init_null (lnk, &buf, &len))
|
if (!nm_utils_to_string_buffer_init_null (lnk, &buf, &len))
|
||||||
return buf;
|
return buf;
|
||||||
|
|
||||||
g_snprintf (buf, len, "vlan %u", (guint) lnk->id);
|
b = buf;
|
||||||
|
|
||||||
|
nm_utils_strbuf_append (&b, &len, "vlan %u", lnk->id);
|
||||||
|
if (lnk->flags)
|
||||||
|
nm_utils_strbuf_append (&b, &len, " flags 0x%x", lnk->flags);
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3231,6 +3337,7 @@ nm_platform_lnk_vlan_cmp (const NMPlatformLnkVlan *a, const NMPlatformLnkVlan *b
|
|||||||
{
|
{
|
||||||
_CMP_SELF (a, b);
|
_CMP_SELF (a, b);
|
||||||
_CMP_FIELD (a, b, id);
|
_CMP_FIELD (a, b, id);
|
||||||
|
_CMP_FIELD (a, b, flags);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -25,9 +25,11 @@
|
|||||||
#include <linux/if.h>
|
#include <linux/if.h>
|
||||||
#include <linux/if_addr.h>
|
#include <linux/if_addr.h>
|
||||||
|
|
||||||
#include <nm-dbus-interface.h>
|
#include "nm-dbus-interface.h"
|
||||||
#include "nm-default.h"
|
#include "nm-default.h"
|
||||||
#include "NetworkManagerUtils.h"
|
#include "NetworkManagerUtils.h"
|
||||||
|
#include "nm-setting-vlan.h"
|
||||||
|
#include "nm-core-types-internal.h"
|
||||||
|
|
||||||
#define NM_TYPE_PLATFORM (nm_platform_get_type ())
|
#define NM_TYPE_PLATFORM (nm_platform_get_type ())
|
||||||
#define NM_PLATFORM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_PLATFORM, NMPlatform))
|
#define NM_PLATFORM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_PLATFORM, NMPlatform))
|
||||||
@@ -105,7 +107,6 @@ extern const NMIPAddr nm_ip_addr_zero;
|
|||||||
|
|
||||||
#define NMIPAddrInit { .addr6 = IN6ADDR_ANY_INIT }
|
#define NMIPAddrInit { .addr6 = IN6ADDR_ANY_INIT }
|
||||||
|
|
||||||
|
|
||||||
#define NM_PLATFORM_LINK_OTHER_NETNS (-1)
|
#define NM_PLATFORM_LINK_OTHER_NETNS (-1)
|
||||||
|
|
||||||
#define __NMPlatformObject_COMMON \
|
#define __NMPlatformObject_COMMON \
|
||||||
@@ -381,6 +382,7 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
/* rtnl_link_vlan_get_id(), IFLA_VLAN_ID */
|
/* rtnl_link_vlan_get_id(), IFLA_VLAN_ID */
|
||||||
guint16 id;
|
guint16 id;
|
||||||
|
NMVlanFlags flags;
|
||||||
} NMPlatformLnkVlan;
|
} NMPlatformLnkVlan;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -510,8 +512,16 @@ typedef struct {
|
|||||||
char * (*slave_get_option) (NMPlatform *, int ifindex, const char *option);
|
char * (*slave_get_option) (NMPlatform *, int ifindex, const char *option);
|
||||||
|
|
||||||
gboolean (*vlan_add) (NMPlatform *, const char *name, int parent, int vlanid, guint32 vlanflags, NMPlatformLink *out_link);
|
gboolean (*vlan_add) (NMPlatform *, const char *name, int parent, int vlanid, guint32 vlanflags, NMPlatformLink *out_link);
|
||||||
gboolean (*vlan_set_ingress_map) (NMPlatform *, int ifindex, int from, int to);
|
gboolean (*link_vlan_change) (NMPlatform *self,
|
||||||
gboolean (*vlan_set_egress_map) (NMPlatform *, int ifindex, int from, int to);
|
int ifindex,
|
||||||
|
NMVlanFlags flags_mask,
|
||||||
|
NMVlanFlags flags_set,
|
||||||
|
gboolean ingress_reset_all,
|
||||||
|
const NMVlanQosMapping *ingress_map,
|
||||||
|
gsize n_ingress_map,
|
||||||
|
gboolean egress_reset_all,
|
||||||
|
const NMVlanQosMapping *egress_map,
|
||||||
|
gsize n_egress_map);
|
||||||
|
|
||||||
gboolean (*infiniband_partition_add) (NMPlatform *, int parent, int p_key, NMPlatformLink *out_link);
|
gboolean (*infiniband_partition_add) (NMPlatform *, int parent, int p_key, NMPlatformLink *out_link);
|
||||||
|
|
||||||
@@ -706,6 +716,17 @@ const NMPlatformLnkVxlan *nm_platform_link_get_lnk_vxlan (NMPlatform *self, int
|
|||||||
NMPlatformError nm_platform_vlan_add (NMPlatform *self, const char *name, int parent, int vlanid, guint32 vlanflags, NMPlatformLink *out_link);
|
NMPlatformError nm_platform_vlan_add (NMPlatform *self, const char *name, int parent, int vlanid, guint32 vlanflags, NMPlatformLink *out_link);
|
||||||
gboolean nm_platform_vlan_set_ingress_map (NMPlatform *self, int ifindex, int from, int to);
|
gboolean nm_platform_vlan_set_ingress_map (NMPlatform *self, int ifindex, int from, int to);
|
||||||
gboolean nm_platform_vlan_set_egress_map (NMPlatform *self, int ifindex, int from, int to);
|
gboolean nm_platform_vlan_set_egress_map (NMPlatform *self, int ifindex, int from, int to);
|
||||||
|
gboolean nm_platform_link_vlan_change (NMPlatform *self,
|
||||||
|
int ifindex,
|
||||||
|
NMVlanFlags flags_mask,
|
||||||
|
NMVlanFlags flags_set,
|
||||||
|
gboolean ingress_reset_all,
|
||||||
|
const NMVlanQosMapping *ingress_map,
|
||||||
|
gsize n_ingress_map,
|
||||||
|
gboolean egress_reset_all,
|
||||||
|
const NMVlanQosMapping *egress_map,
|
||||||
|
gsize n_egress_map);
|
||||||
|
|
||||||
|
|
||||||
NMPlatformError nm_platform_infiniband_partition_add (NMPlatform *self, int parent, int p_key, NMPlatformLink *out_link);
|
NMPlatformError nm_platform_infiniband_partition_add (NMPlatform *self, int parent, int p_key, NMPlatformLink *out_link);
|
||||||
gboolean nm_platform_infiniband_get_properties (NMPlatform *self, int ifindex, int *parent, int *p_key, const char **mode);
|
gboolean nm_platform_infiniband_get_properties (NMPlatform *self, int ifindex, int *parent, int *p_key, const char **mode);
|
||||||
@@ -783,6 +804,12 @@ const char *nm_platform_ip6_address_to_string (const NMPlatformIP6Address *addre
|
|||||||
const char *nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route, char *buf, gsize len);
|
const char *nm_platform_ip4_route_to_string (const NMPlatformIP4Route *route, char *buf, gsize len);
|
||||||
const char *nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, char *buf, gsize len);
|
const char *nm_platform_ip6_route_to_string (const NMPlatformIP6Route *route, char *buf, gsize len);
|
||||||
|
|
||||||
|
const char *nm_platform_vlan_qos_mapping_to_string (const char *name,
|
||||||
|
const NMVlanQosMapping *map,
|
||||||
|
gsize n_map,
|
||||||
|
char *buf,
|
||||||
|
gsize len);
|
||||||
|
|
||||||
int nm_platform_link_cmp (const NMPlatformLink *a, const NMPlatformLink *b);
|
int nm_platform_link_cmp (const NMPlatformLink *a, const NMPlatformLink *b);
|
||||||
int nm_platform_lnk_gre_cmp (const NMPlatformLnkGre *a, const NMPlatformLnkGre *b);
|
int nm_platform_lnk_gre_cmp (const NMPlatformLnkGre *a, const NMPlatformLnkGre *b);
|
||||||
int nm_platform_lnk_infiniband_cmp (const NMPlatformLnkInfiniband *a, const NMPlatformLnkInfiniband *b);
|
int nm_platform_lnk_infiniband_cmp (const NMPlatformLnkInfiniband *a, const NMPlatformLnkInfiniband *b);
|
||||||
|
@@ -82,6 +82,40 @@ _id_hash_ip6_addr (const struct in6_addr *addr)
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_vlan_xgress_qos_mappings_cmp (guint n_map,
|
||||||
|
const NMVlanQosMapping *map1,
|
||||||
|
const NMVlanQosMapping *map2)
|
||||||
|
{
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
for (i = 0; i < n_map; i++) {
|
||||||
|
if (map1[i].from != map2[i].from)
|
||||||
|
return map1[i].from < map2[i].from ? -1 : 1;
|
||||||
|
if (map1[i].to != map2[i].to)
|
||||||
|
return map1[i].to < map2[i].to ? -1 : 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_vlan_xgress_qos_mappings_cpy (guint *dst_n_map,
|
||||||
|
const NMVlanQosMapping **dst_map,
|
||||||
|
guint src_n_map,
|
||||||
|
const NMVlanQosMapping *src_map)
|
||||||
|
{
|
||||||
|
if (src_n_map == 0) {
|
||||||
|
g_clear_pointer (dst_map, g_free);
|
||||||
|
*dst_n_map = 0;
|
||||||
|
} else if ( src_n_map != *dst_n_map
|
||||||
|
|| _vlan_xgress_qos_mappings_cmp (src_n_map, *dst_map, src_map) != 0) {
|
||||||
|
g_clear_pointer (dst_map, g_free);
|
||||||
|
*dst_n_map = src_n_map;
|
||||||
|
if (src_n_map > 0)
|
||||||
|
*dst_map = g_memdup (src_map, sizeof (*src_map) * src_n_map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************/
|
/******************************************************************/
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
@@ -212,6 +246,13 @@ _vt_cmd_obj_dispose_link (NMPObject *obj)
|
|||||||
nmp_object_unref (obj->_link.netlink.lnk);
|
nmp_object_unref (obj->_link.netlink.lnk);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_vt_cmd_obj_dispose_lnk_vlan (NMPObject *obj)
|
||||||
|
{
|
||||||
|
g_free ((gpointer) obj->_lnk_vlan.ingress_qos_map);
|
||||||
|
g_free ((gpointer) obj->_lnk_vlan.egress_qos_map);
|
||||||
|
}
|
||||||
|
|
||||||
static NMPObject *
|
static NMPObject *
|
||||||
_nmp_object_new_from_class (const NMPClass *klass)
|
_nmp_object_new_from_class (const NMPClass *klass)
|
||||||
{
|
{
|
||||||
@@ -451,6 +492,65 @@ _vt_cmd_obj_to_string_link (const NMPObject *obj, NMPObjectToStringMode to_strin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
_vt_cmd_obj_to_string_lnk_vlan (const NMPObject *obj, NMPObjectToStringMode to_string_mode, char *buf, gsize buf_size)
|
||||||
|
{
|
||||||
|
const NMPClass *klass = NMP_OBJECT_GET_CLASS (obj);
|
||||||
|
char buf2[sizeof (_nm_utils_to_string_buffer)];
|
||||||
|
char *b;
|
||||||
|
gsize l;
|
||||||
|
|
||||||
|
klass = NMP_OBJECT_GET_CLASS (obj);
|
||||||
|
|
||||||
|
switch (to_string_mode) {
|
||||||
|
case NMP_OBJECT_TO_STRING_ID:
|
||||||
|
g_snprintf (buf, buf_size, "%p", obj);
|
||||||
|
return buf;
|
||||||
|
case NMP_OBJECT_TO_STRING_ALL:
|
||||||
|
|
||||||
|
g_snprintf (buf, buf_size,
|
||||||
|
"[%s,%p,%d,%ccache,%calive,%cvisible; %s]",
|
||||||
|
klass->obj_type_name, obj, obj->_ref_count,
|
||||||
|
obj->is_cached ? '+' : '-',
|
||||||
|
nmp_object_is_alive (obj) ? '+' : '-',
|
||||||
|
nmp_object_is_visible (obj) ? '+' : '-',
|
||||||
|
nmp_object_to_string (obj, NMP_OBJECT_TO_STRING_PUBLIC, buf2, sizeof (buf2)));
|
||||||
|
return buf;
|
||||||
|
case NMP_OBJECT_TO_STRING_PUBLIC:
|
||||||
|
NMP_OBJECT_GET_CLASS (obj)->cmd_plobj_to_string (&obj->object, buf, buf_size);
|
||||||
|
|
||||||
|
b = buf;
|
||||||
|
l = strlen (b);
|
||||||
|
b += l;
|
||||||
|
buf_size -= l;
|
||||||
|
|
||||||
|
if (obj->_lnk_vlan.n_ingress_qos_map) {
|
||||||
|
nm_platform_vlan_qos_mapping_to_string (" ingress-qos-map",
|
||||||
|
obj->_lnk_vlan.ingress_qos_map,
|
||||||
|
obj->_lnk_vlan.n_ingress_qos_map,
|
||||||
|
b,
|
||||||
|
buf_size);
|
||||||
|
l = strlen (b);
|
||||||
|
b += l;
|
||||||
|
buf_size -= l;
|
||||||
|
}
|
||||||
|
if (obj->_lnk_vlan.n_egress_qos_map) {
|
||||||
|
nm_platform_vlan_qos_mapping_to_string (" egress-qos-map",
|
||||||
|
obj->_lnk_vlan.egress_qos_map,
|
||||||
|
obj->_lnk_vlan.n_egress_qos_map,
|
||||||
|
b,
|
||||||
|
buf_size);
|
||||||
|
l = strlen (b);
|
||||||
|
b += l;
|
||||||
|
buf_size -= l;
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
default:
|
||||||
|
g_return_val_if_reached ("ERROR");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define _vt_cmd_plobj_to_string_id(type, plat_type, ...) \
|
#define _vt_cmd_plobj_to_string_id(type, plat_type, ...) \
|
||||||
static const char * \
|
static const char * \
|
||||||
_vt_cmd_plobj_to_string_id_##type (const NMPlatformObject *_obj, char *buf, gsize buf_len) \
|
_vt_cmd_plobj_to_string_id_##type (const NMPlatformObject *_obj, char *buf, gsize buf_len) \
|
||||||
@@ -528,6 +628,28 @@ _vt_cmd_obj_cmp_link (const NMPObject *obj1, const NMPObject *obj2)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_vt_cmd_obj_cmp_lnk_vlan (const NMPObject *obj1, const NMPObject *obj2)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
|
||||||
|
c = nm_platform_lnk_vlan_cmp (&obj1->lnk_vlan, &obj2->lnk_vlan);
|
||||||
|
if (c)
|
||||||
|
return c;
|
||||||
|
|
||||||
|
if (obj1->_lnk_vlan.n_ingress_qos_map != obj2->_lnk_vlan.n_ingress_qos_map)
|
||||||
|
return obj1->_lnk_vlan.n_ingress_qos_map < obj2->_lnk_vlan.n_ingress_qos_map ? -1 : 1;
|
||||||
|
if (obj1->_lnk_vlan.n_egress_qos_map != obj2->_lnk_vlan.n_egress_qos_map)
|
||||||
|
return obj1->_lnk_vlan.n_egress_qos_map < obj2->_lnk_vlan.n_egress_qos_map ? -1 : 1;
|
||||||
|
|
||||||
|
c = _vlan_xgress_qos_mappings_cmp (obj1->_lnk_vlan.n_ingress_qos_map, obj1->_lnk_vlan.ingress_qos_map, obj2->_lnk_vlan.ingress_qos_map);
|
||||||
|
if (c)
|
||||||
|
return c;
|
||||||
|
c = _vlan_xgress_qos_mappings_cmp (obj1->_lnk_vlan.n_egress_qos_map, obj1->_lnk_vlan.egress_qos_map, obj2->_lnk_vlan.egress_qos_map);
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
nmp_object_equal (const NMPObject *obj1, const NMPObject *obj2)
|
nmp_object_equal (const NMPObject *obj1, const NMPObject *obj2)
|
||||||
{
|
{
|
||||||
@@ -578,6 +700,20 @@ _vt_cmd_obj_copy_link (NMPObject *dst, const NMPObject *src)
|
|||||||
dst->_link = src->_link;
|
dst->_link = src->_link;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_vt_cmd_obj_copy_lnk_vlan (NMPObject *dst, const NMPObject *src)
|
||||||
|
{
|
||||||
|
dst->lnk_vlan = src->lnk_vlan;
|
||||||
|
_vlan_xgress_qos_mappings_cpy (&dst->_lnk_vlan.n_ingress_qos_map,
|
||||||
|
&dst->_lnk_vlan.ingress_qos_map,
|
||||||
|
src->_lnk_vlan.n_ingress_qos_map,
|
||||||
|
src->_lnk_vlan.ingress_qos_map);
|
||||||
|
_vlan_xgress_qos_mappings_cpy (&dst->_lnk_vlan.n_egress_qos_map,
|
||||||
|
&dst->_lnk_vlan.egress_qos_map,
|
||||||
|
src->_lnk_vlan.n_egress_qos_map,
|
||||||
|
src->_lnk_vlan.egress_qos_map);
|
||||||
|
}
|
||||||
|
|
||||||
#define _vt_cmd_plobj_id_copy(type, plat_type, cmd) \
|
#define _vt_cmd_plobj_id_copy(type, plat_type, cmd) \
|
||||||
static void \
|
static void \
|
||||||
_vt_cmd_plobj_id_copy_##type (NMPlatformObject *_dst, const NMPlatformObject *_src) \
|
_vt_cmd_plobj_id_copy_##type (NMPlatformObject *_dst, const NMPlatformObject *_src) \
|
||||||
@@ -1919,6 +2055,10 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
|
|||||||
.sizeof_public = sizeof (NMPlatformLnkVlan),
|
.sizeof_public = sizeof (NMPlatformLnkVlan),
|
||||||
.obj_type_name = "vlan",
|
.obj_type_name = "vlan",
|
||||||
.lnk_link_type = NM_LINK_TYPE_VLAN,
|
.lnk_link_type = NM_LINK_TYPE_VLAN,
|
||||||
|
.cmd_obj_cmp = _vt_cmd_obj_cmp_lnk_vlan,
|
||||||
|
.cmd_obj_copy = _vt_cmd_obj_copy_lnk_vlan,
|
||||||
|
.cmd_obj_dispose = _vt_cmd_obj_dispose_lnk_vlan,
|
||||||
|
.cmd_obj_to_string = _vt_cmd_obj_to_string_lnk_vlan,
|
||||||
.cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_vlan_to_string,
|
.cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_vlan_to_string,
|
||||||
.cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_vlan_cmp,
|
.cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_vlan_cmp,
|
||||||
},
|
},
|
||||||
|
@@ -174,6 +174,11 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
NMPlatformLnkVlan _public;
|
NMPlatformLnkVlan _public;
|
||||||
|
|
||||||
|
guint n_ingress_qos_map;
|
||||||
|
guint n_egress_qos_map;
|
||||||
|
const NMVlanQosMapping *ingress_qos_map;
|
||||||
|
const NMVlanQosMapping *egress_qos_map;
|
||||||
} NMPObjectLnkVlan;
|
} NMPObjectLnkVlan;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@@ -811,6 +811,85 @@ test_software_detect_add (const char *testpath,
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static void
|
||||||
|
_assert_xgress_qos_mappings_impl (int ifindex,
|
||||||
|
gboolean is_ingress_map ,
|
||||||
|
int n_entries,
|
||||||
|
int n,
|
||||||
|
...)
|
||||||
|
{
|
||||||
|
const NMPlatformLink *plink;
|
||||||
|
const NMPObject *lnk;
|
||||||
|
guint n_map;
|
||||||
|
const NMVlanQosMapping *map;
|
||||||
|
va_list ap;
|
||||||
|
guint i;
|
||||||
|
|
||||||
|
lnk = nm_platform_link_get_lnk (NM_PLATFORM_GET, ifindex, NM_LINK_TYPE_VLAN, &plink);
|
||||||
|
|
||||||
|
g_assert (plink);
|
||||||
|
g_assert_cmpint (plink->ifindex, ==, ifindex);
|
||||||
|
g_assert (lnk);
|
||||||
|
g_assert (&lnk->lnk_vlan == nm_platform_link_get_lnk_vlan (NM_PLATFORM_GET, ifindex, NULL));
|
||||||
|
|
||||||
|
if (nmtst_is_debug ())
|
||||||
|
nmtstp_run_command_check ("ip -d link show %s", plink->name);
|
||||||
|
|
||||||
|
if (is_ingress_map) {
|
||||||
|
map = lnk->_lnk_vlan.ingress_qos_map;
|
||||||
|
n_map = lnk->_lnk_vlan.n_ingress_qos_map;
|
||||||
|
} else {
|
||||||
|
map = lnk->_lnk_vlan.egress_qos_map;
|
||||||
|
n_map = lnk->_lnk_vlan.n_egress_qos_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n_entries != -1)
|
||||||
|
g_assert_cmpint (n_map, ==, n_entries);
|
||||||
|
|
||||||
|
for (i = 0; i < n_map; i++) {
|
||||||
|
if (is_ingress_map) {
|
||||||
|
g_assert_cmpint (map[i].from, >=, 0);
|
||||||
|
g_assert_cmpint (map[i].from, <=, 7);
|
||||||
|
}
|
||||||
|
if (i > 0)
|
||||||
|
g_assert_cmpint (map[i - 1].from, <, map[i].from);
|
||||||
|
}
|
||||||
|
|
||||||
|
va_start (ap, n);
|
||||||
|
for (; n > 0; n--) {
|
||||||
|
gboolean found = FALSE;
|
||||||
|
guint from = va_arg (ap, guint);
|
||||||
|
guint to = va_arg (ap, guint);
|
||||||
|
|
||||||
|
for (i = 0; i < n_map; i++) {
|
||||||
|
if (map[i].from == from) {
|
||||||
|
g_assert (!found);
|
||||||
|
found = TRUE;
|
||||||
|
|
||||||
|
g_assert (map[i].to == to);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_assert (found);
|
||||||
|
}
|
||||||
|
va_end (ap);
|
||||||
|
}
|
||||||
|
#define _assert_xgress_qos_mappings(ifindex, is_ingress_map, n_entries, ...) \
|
||||||
|
_assert_xgress_qos_mappings_impl ((ifindex), (is_ingress_map), (n_entries), \
|
||||||
|
(G_STATIC_ASSERT_EXPR ((NM_NARG (__VA_ARGS__) % 2) == 0), NM_NARG (__VA_ARGS__) / 2), \
|
||||||
|
__VA_ARGS__)
|
||||||
|
#define _assert_ingress_qos_mappings(ifindex, n_entries, ...) _assert_xgress_qos_mappings (ifindex, TRUE, n_entries, __VA_ARGS__)
|
||||||
|
#define _assert_egress_qos_mappings(ifindex, n_entries, ...) _assert_xgress_qos_mappings (ifindex, FALSE, n_entries, __VA_ARGS__)
|
||||||
|
|
||||||
|
static void
|
||||||
|
_assert_vlan_flags (int ifindex, NMVlanFlags flags)
|
||||||
|
{
|
||||||
|
const NMPlatformLnkVlan *plnk;
|
||||||
|
|
||||||
|
plnk = nm_platform_link_get_lnk_vlan (NM_PLATFORM_GET, ifindex, NULL);
|
||||||
|
g_assert (plnk);
|
||||||
|
g_assert_cmpint (plnk->flags, ==, flags);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_vlan_set_xgress (void)
|
test_vlan_set_xgress (void)
|
||||||
{
|
{
|
||||||
@@ -822,29 +901,452 @@ test_vlan_set_xgress (void)
|
|||||||
nmtstp_run_command_check ("ip link add name %s link %s type vlan id 1245", DEVICE_NAME, PARENT_NAME);
|
nmtstp_run_command_check ("ip link add name %s link %s type vlan id 1245", DEVICE_NAME, PARENT_NAME);
|
||||||
ifindex = nmtstp_assert_wait_for_link (DEVICE_NAME, NM_LINK_TYPE_VLAN, 100)->ifindex;
|
ifindex = nmtstp_assert_wait_for_link (DEVICE_NAME, NM_LINK_TYPE_VLAN, 100)->ifindex;
|
||||||
|
|
||||||
|
/* ingress-qos-map */
|
||||||
|
|
||||||
g_assert (nm_platform_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 4, 5));
|
g_assert (nm_platform_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 4, 5));
|
||||||
|
_assert_ingress_qos_mappings (ifindex, 1,
|
||||||
|
4, 5);
|
||||||
|
|
||||||
g_assert (nm_platform_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 3, 7));
|
g_assert (nm_platform_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 3, 7));
|
||||||
|
_assert_ingress_qos_mappings (ifindex, 2,
|
||||||
|
3, 7,
|
||||||
|
4, 5);
|
||||||
|
|
||||||
g_assert (nm_platform_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 3, 8));
|
g_assert (nm_platform_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 3, 8));
|
||||||
|
_assert_ingress_qos_mappings (ifindex, 2,
|
||||||
|
3, 8,
|
||||||
|
4, 5);
|
||||||
|
|
||||||
g_assert (nm_platform_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 0, 4));
|
g_assert (nm_platform_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 0, 4));
|
||||||
|
_assert_ingress_qos_mappings (ifindex, 3,
|
||||||
|
0, 4,
|
||||||
|
3, 8,
|
||||||
|
4, 5);
|
||||||
|
|
||||||
|
g_assert (nm_platform_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 0, G_MAXUINT32));
|
||||||
|
_assert_ingress_qos_mappings (ifindex, 3,
|
||||||
|
0, G_MAXUINT32,
|
||||||
|
3, 8,
|
||||||
|
4, 5);
|
||||||
|
|
||||||
|
g_assert (nm_platform_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 0, G_MAXUINT32 - 1));
|
||||||
|
_assert_ingress_qos_mappings (ifindex, 3,
|
||||||
|
0, G_MAXUINT32 - 1,
|
||||||
|
3, 8,
|
||||||
|
4, 5);
|
||||||
|
|
||||||
|
g_assert (nm_platform_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 0, 5));
|
||||||
|
_assert_ingress_qos_mappings (ifindex, 3,
|
||||||
|
0, 5,
|
||||||
|
3, 8,
|
||||||
|
4, 5);
|
||||||
|
|
||||||
|
g_assert (nm_platform_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 0, 5));
|
||||||
|
_assert_ingress_qos_mappings (ifindex, 3,
|
||||||
|
0, 5,
|
||||||
|
3, 8,
|
||||||
|
4, 5);
|
||||||
|
|
||||||
|
/* Set invalid values: */
|
||||||
|
g_assert (nm_platform_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 8, 3));
|
||||||
|
_assert_ingress_qos_mappings (ifindex, 3,
|
||||||
|
0, 5,
|
||||||
|
3, 8,
|
||||||
|
4, 5);
|
||||||
|
|
||||||
|
g_assert (nm_platform_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 9, 4));
|
||||||
|
_assert_ingress_qos_mappings (ifindex, 3,
|
||||||
|
0, 5,
|
||||||
|
3, 8,
|
||||||
|
4, 5);
|
||||||
|
|
||||||
|
/* egress-qos-map */
|
||||||
|
|
||||||
g_assert (nm_platform_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 7, 3));
|
g_assert (nm_platform_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 7, 3));
|
||||||
|
_assert_egress_qos_mappings (ifindex, 1,
|
||||||
|
7, 3);
|
||||||
|
|
||||||
g_assert (nm_platform_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 8, 4));
|
g_assert (nm_platform_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 8, 4));
|
||||||
|
_assert_egress_qos_mappings (ifindex, 2,
|
||||||
|
7, 3,
|
||||||
|
8, 4);
|
||||||
|
|
||||||
g_assert (nm_platform_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 0, 4));
|
g_assert (nm_platform_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 0, 4));
|
||||||
|
_assert_egress_qos_mappings (ifindex, 3,
|
||||||
|
0, 4,
|
||||||
|
7, 3,
|
||||||
|
8, 4);
|
||||||
|
|
||||||
/* TODO: assert that the values are actually set. Currently only verified
|
g_assert (nm_platform_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 1, 4));
|
||||||
* by manual inspection. */
|
_assert_egress_qos_mappings (ifindex, 4,
|
||||||
|
0, 4,
|
||||||
|
1, 4,
|
||||||
|
7, 3,
|
||||||
|
8, 4);
|
||||||
|
|
||||||
if (nmtst_is_debug ())
|
g_assert (nm_platform_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 1, 5));
|
||||||
nmtstp_run_command_check ("ip -d link show %s", DEVICE_NAME);
|
_assert_egress_qos_mappings (ifindex, 4,
|
||||||
|
0, 4,
|
||||||
|
1, 5,
|
||||||
|
7, 3,
|
||||||
|
8, 4);
|
||||||
|
|
||||||
|
g_assert (nm_platform_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 9, 5));
|
||||||
|
_assert_egress_qos_mappings (ifindex, 5,
|
||||||
|
0, 4,
|
||||||
|
1, 5,
|
||||||
|
7, 3,
|
||||||
|
8, 4,
|
||||||
|
9, 5);
|
||||||
|
|
||||||
|
g_assert (nm_platform_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 8, 5));
|
||||||
|
_assert_egress_qos_mappings (ifindex, 5,
|
||||||
|
0, 4,
|
||||||
|
1, 5,
|
||||||
|
7, 3,
|
||||||
|
8, 5,
|
||||||
|
9, 5);
|
||||||
|
|
||||||
g_assert (nm_platform_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 7, 0));
|
|
||||||
g_assert (nm_platform_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 8, 0));
|
g_assert (nm_platform_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 8, 0));
|
||||||
|
_assert_egress_qos_mappings (ifindex, 4,
|
||||||
|
0, 4,
|
||||||
|
1, 5,
|
||||||
|
7, 3,
|
||||||
|
9, 5);
|
||||||
|
|
||||||
g_assert (nm_platform_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 3, 0));
|
g_assert (nm_platform_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 0, 0));
|
||||||
g_assert (nm_platform_vlan_set_ingress_map (NM_PLATFORM_GET, ifindex, 0, 0));
|
_assert_egress_qos_mappings (ifindex, 3,
|
||||||
|
1, 5,
|
||||||
|
7, 3,
|
||||||
|
9, 5);
|
||||||
|
|
||||||
if (nmtst_is_debug ())
|
g_assert (nm_platform_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 100, 4));
|
||||||
nmtstp_run_command_check ("ip -d link show %s", DEVICE_NAME);
|
_assert_egress_qos_mappings (ifindex, 4,
|
||||||
|
1, 5,
|
||||||
|
7, 3,
|
||||||
|
9, 5,
|
||||||
|
100, 4);
|
||||||
|
|
||||||
|
g_assert (nm_platform_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, G_MAXUINT32, 4));
|
||||||
|
_assert_egress_qos_mappings (ifindex, 5,
|
||||||
|
1, 5,
|
||||||
|
7, 3,
|
||||||
|
9, 5,
|
||||||
|
100, 4,
|
||||||
|
G_MAXUINT32, 4);
|
||||||
|
|
||||||
|
g_assert (nm_platform_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, G_MAXUINT32, 8));
|
||||||
|
_assert_egress_qos_mappings (ifindex, 5,
|
||||||
|
1, 5,
|
||||||
|
7, 3,
|
||||||
|
9, 5,
|
||||||
|
100, 4,
|
||||||
|
G_MAXUINT32, 4);
|
||||||
|
|
||||||
|
g_assert (nm_platform_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, G_MAXUINT32, 0));
|
||||||
|
_assert_egress_qos_mappings (ifindex, 4,
|
||||||
|
1, 5,
|
||||||
|
7, 3,
|
||||||
|
9, 5,
|
||||||
|
100, 4);
|
||||||
|
|
||||||
|
g_assert (nm_platform_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 100, 0));
|
||||||
|
_assert_egress_qos_mappings (ifindex, 3,
|
||||||
|
1, 5,
|
||||||
|
7, 3,
|
||||||
|
9, 5);
|
||||||
|
|
||||||
|
g_assert (nm_platform_vlan_set_egress_map (NM_PLATFORM_GET, ifindex, 1, 0));
|
||||||
|
_assert_egress_qos_mappings (ifindex, 2,
|
||||||
|
7, 3,
|
||||||
|
9, 5);
|
||||||
|
|
||||||
|
{
|
||||||
|
const NMVlanQosMapping ingress_map[] = {
|
||||||
|
{ .from = 1, .to = 5 },
|
||||||
|
};
|
||||||
|
|
||||||
|
g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET,
|
||||||
|
ifindex,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
TRUE,
|
||||||
|
ingress_map,
|
||||||
|
G_N_ELEMENTS (ingress_map),
|
||||||
|
FALSE,
|
||||||
|
NULL,
|
||||||
|
0));
|
||||||
|
_assert_ingress_qos_mappings (ifindex, 1,
|
||||||
|
1, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const NMVlanQosMapping ingress_map[] = {
|
||||||
|
{ .from = 3, .to = 5 },
|
||||||
|
{ .from = 7, .to = 1655 },
|
||||||
|
{ .from = 7, .to = 17655 },
|
||||||
|
{ .from = 5, .to = 754 },
|
||||||
|
{ .from = 4, .to = 12 },
|
||||||
|
};
|
||||||
|
|
||||||
|
g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET,
|
||||||
|
ifindex,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
TRUE,
|
||||||
|
ingress_map,
|
||||||
|
G_N_ELEMENTS (ingress_map),
|
||||||
|
FALSE,
|
||||||
|
NULL,
|
||||||
|
0));
|
||||||
|
_assert_ingress_qos_mappings (ifindex, 4,
|
||||||
|
3, 5,
|
||||||
|
4, 12,
|
||||||
|
7, 17655,
|
||||||
|
5, 754);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const NMVlanQosMapping ingress_map[] = {
|
||||||
|
{ .from = 3, .to = 18 },
|
||||||
|
{ .from = 6, .to = 121 },
|
||||||
|
};
|
||||||
|
|
||||||
|
g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET,
|
||||||
|
ifindex,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
ingress_map,
|
||||||
|
G_N_ELEMENTS (ingress_map),
|
||||||
|
FALSE,
|
||||||
|
NULL,
|
||||||
|
0));
|
||||||
|
_assert_ingress_qos_mappings (ifindex, 5,
|
||||||
|
3, 18,
|
||||||
|
4, 12,
|
||||||
|
6, 121,
|
||||||
|
7, 17655,
|
||||||
|
5, 754);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const NMVlanQosMapping ingress_map[] = {
|
||||||
|
{ .from = 3, .to = 0 },
|
||||||
|
{ .from = 6, .to = 7 },
|
||||||
|
};
|
||||||
|
|
||||||
|
g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET,
|
||||||
|
ifindex,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
TRUE,
|
||||||
|
ingress_map,
|
||||||
|
G_N_ELEMENTS (ingress_map),
|
||||||
|
FALSE,
|
||||||
|
NULL,
|
||||||
|
0));
|
||||||
|
_assert_ingress_qos_mappings (ifindex, 1,
|
||||||
|
6, 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
const NMVlanQosMapping ingress_map[] = {
|
||||||
|
{ .from = 1, .to = 5 },
|
||||||
|
};
|
||||||
|
|
||||||
|
g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET,
|
||||||
|
ifindex,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
TRUE,
|
||||||
|
ingress_map,
|
||||||
|
G_N_ELEMENTS (ingress_map),
|
||||||
|
FALSE,
|
||||||
|
NULL,
|
||||||
|
0));
|
||||||
|
_assert_ingress_qos_mappings (ifindex, 1,
|
||||||
|
1, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const NMVlanQosMapping egress_map[] = {
|
||||||
|
{ .from = 5, .to = 1 },
|
||||||
|
};
|
||||||
|
|
||||||
|
g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET,
|
||||||
|
ifindex,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
TRUE,
|
||||||
|
egress_map,
|
||||||
|
G_N_ELEMENTS (egress_map)));
|
||||||
|
_assert_egress_qos_mappings (ifindex, 1,
|
||||||
|
5, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const NMVlanQosMapping egress_map[] = {
|
||||||
|
{ .from = 5, .to = 3 },
|
||||||
|
{ .from = 1655, .to = 5 },
|
||||||
|
{ .from = 1655, .to = 7 },
|
||||||
|
{ .from = G_MAXUINT32, .to = 6 },
|
||||||
|
{ .from = G_MAXUINT32, .to = 8 },
|
||||||
|
{ .from = 754, .to = 4 },
|
||||||
|
{ .from = 3, .to = 2 },
|
||||||
|
};
|
||||||
|
|
||||||
|
g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET,
|
||||||
|
ifindex,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
TRUE,
|
||||||
|
egress_map,
|
||||||
|
G_N_ELEMENTS (egress_map)));
|
||||||
|
_assert_egress_qos_mappings (ifindex, 5,
|
||||||
|
3, 2,
|
||||||
|
5, 3,
|
||||||
|
754, 4,
|
||||||
|
1655, 7,
|
||||||
|
G_MAXUINT32, 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const NMVlanQosMapping egress_map[] = {
|
||||||
|
{ .from = 754, .to = 3 },
|
||||||
|
{ .from = 755, .to = 8 },
|
||||||
|
{ .from = 1655, .to = 0 },
|
||||||
|
{ .from = 6, .to = 1 },
|
||||||
|
};
|
||||||
|
|
||||||
|
g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET,
|
||||||
|
ifindex,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
egress_map,
|
||||||
|
G_N_ELEMENTS (egress_map)));
|
||||||
|
_assert_egress_qos_mappings (ifindex, 5,
|
||||||
|
3, 2,
|
||||||
|
5, 3,
|
||||||
|
6, 1,
|
||||||
|
754, 3,
|
||||||
|
G_MAXUINT32, 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const NMVlanQosMapping egress_map[] = {
|
||||||
|
{ .from = 6, .to = 0 },
|
||||||
|
{ .from = 3, .to = 4 },
|
||||||
|
};
|
||||||
|
|
||||||
|
g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET,
|
||||||
|
ifindex,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
TRUE,
|
||||||
|
egress_map,
|
||||||
|
G_N_ELEMENTS (egress_map)));
|
||||||
|
_assert_egress_qos_mappings (ifindex, 1,
|
||||||
|
3, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const NMVlanQosMapping egress_map[] = {
|
||||||
|
{ .from = 1, .to = 5 },
|
||||||
|
};
|
||||||
|
|
||||||
|
g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET,
|
||||||
|
ifindex,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
TRUE,
|
||||||
|
egress_map,
|
||||||
|
G_N_ELEMENTS (egress_map)));
|
||||||
|
_assert_egress_qos_mappings (ifindex, 1,
|
||||||
|
1, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const NMVlanQosMapping ingress_map[] = {
|
||||||
|
{ .from = 6, .to = 145 },
|
||||||
|
{ .from = 4, .to = 1 },
|
||||||
|
{ .from = 6, .to = 12 },
|
||||||
|
};
|
||||||
|
const NMVlanQosMapping egress_map[] = {
|
||||||
|
{ .from = 1, .to = 5 },
|
||||||
|
{ .from = 3232, .to = 7 },
|
||||||
|
};
|
||||||
|
|
||||||
|
g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET,
|
||||||
|
ifindex,
|
||||||
|
NM_VLAN_FLAG_REORDER_HEADERS | NM_VLAN_FLAG_GVRP,
|
||||||
|
NM_VLAN_FLAG_REORDER_HEADERS,
|
||||||
|
TRUE,
|
||||||
|
ingress_map,
|
||||||
|
G_N_ELEMENTS (ingress_map),
|
||||||
|
TRUE,
|
||||||
|
egress_map,
|
||||||
|
G_N_ELEMENTS (egress_map)));
|
||||||
|
_assert_ingress_qos_mappings (ifindex, 2,
|
||||||
|
4, 1,
|
||||||
|
6, 12);
|
||||||
|
_assert_egress_qos_mappings (ifindex, 2,
|
||||||
|
1, 5,
|
||||||
|
3232, 7);
|
||||||
|
_assert_vlan_flags (ifindex, NM_VLAN_FLAG_REORDER_HEADERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const NMVlanQosMapping ingress_map[] = {
|
||||||
|
{ .from = 6, .to = 145 },
|
||||||
|
{ .from = 4, .to = 1 },
|
||||||
|
{ .from = 6, .to = 12 },
|
||||||
|
};
|
||||||
|
const NMVlanQosMapping egress_map[] = {
|
||||||
|
{ .from = 1, .to = 7 },
|
||||||
|
{ .from = 64, .to = 10 },
|
||||||
|
{ .from = 64, .to = 10 },
|
||||||
|
{ .from = 64, .to = 10 },
|
||||||
|
{ .from = 64, .to = 10 },
|
||||||
|
{ .from = 3232, .to = 0 },
|
||||||
|
{ .from = 64, .to = 4 },
|
||||||
|
};
|
||||||
|
|
||||||
|
g_assert (nm_platform_link_vlan_change (NM_PLATFORM_GET,
|
||||||
|
ifindex,
|
||||||
|
NM_VLAN_FLAG_GVRP,
|
||||||
|
NM_VLAN_FLAG_GVRP,
|
||||||
|
FALSE,
|
||||||
|
ingress_map,
|
||||||
|
G_N_ELEMENTS (ingress_map),
|
||||||
|
FALSE,
|
||||||
|
egress_map,
|
||||||
|
G_N_ELEMENTS (egress_map)));
|
||||||
|
_assert_ingress_qos_mappings (ifindex, 2,
|
||||||
|
4, 1,
|
||||||
|
6, 12);
|
||||||
|
_assert_egress_qos_mappings (ifindex, 2,
|
||||||
|
1, 7,
|
||||||
|
64, 4);
|
||||||
|
_assert_vlan_flags (ifindex, NM_VLAN_FLAG_REORDER_HEADERS | NM_VLAN_FLAG_GVRP);
|
||||||
|
}
|
||||||
|
|
||||||
g_assert (nm_platform_link_delete (NM_PLATFORM_GET, ifindex));
|
g_assert (nm_platform_link_delete (NM_PLATFORM_GET, ifindex));
|
||||||
g_assert (nm_platform_link_delete (NM_PLATFORM_GET, ifindex_parent));
|
g_assert (nm_platform_link_delete (NM_PLATFORM_GET, ifindex_parent));
|
||||||
|
Reference in New Issue
Block a user