mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-09 14:40:21 +01:00
core: add dcbtool manipulation logic
This commit is contained in:
parent
3e6906e773
commit
64a7a045b3
6 changed files with 794 additions and 1 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -178,6 +178,7 @@ valgrind-*.log
|
|||
/libnm-util/tests/test-setting-8021x
|
||||
/libnm-util/tests/test-setting-dcb
|
||||
/libnm-glib/tests/test-remote-settings-client
|
||||
/src/tests/test-dcb
|
||||
/src/tests/test-dhcp-options
|
||||
/src/tests/test-ip4-config
|
||||
/src/tests/test-ip6-config
|
||||
|
|
|
|||
|
|
@ -230,6 +230,8 @@ nm_sources = \
|
|||
nm-connectivity.h \
|
||||
nm-dbus-manager.c \
|
||||
nm-dbus-manager.h \
|
||||
nm-dcb.c \
|
||||
nm-dcb.h \
|
||||
nm-dhcp4-config.c \
|
||||
nm-dhcp4-config.h \
|
||||
nm-dhcp6-config.c \
|
||||
|
|
|
|||
339
src/nm-dcb.c
Normal file
339
src/nm-dcb.c
Normal file
|
|
@ -0,0 +1,339 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2013 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <sys/wait.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include "nm-dcb.h"
|
||||
#include "nm-platform.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "nm-posix-signals.h"
|
||||
#include "nm-logging.h"
|
||||
|
||||
GQuark
|
||||
nm_dcb_error_quark (void)
|
||||
{
|
||||
static GQuark ret = 0;
|
||||
|
||||
if (ret == 0)
|
||||
ret = g_quark_from_static_string ("nm-dcb-error");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const char *helper_names[] = { "dcbtool", "fcoeadm" };
|
||||
|
||||
gboolean
|
||||
do_helper (const char *iface,
|
||||
guint which,
|
||||
DcbFunc run_func,
|
||||
gpointer user_data,
|
||||
GError **error,
|
||||
const char *fmt,
|
||||
...)
|
||||
{
|
||||
char **argv = NULL, **split = NULL, *cmdline, *errmsg = NULL;
|
||||
gboolean success = FALSE;
|
||||
guint i, u;
|
||||
va_list args;
|
||||
|
||||
g_return_val_if_fail (fmt != NULL, FALSE);
|
||||
|
||||
va_start (args, fmt);
|
||||
cmdline = g_strdup_vprintf (fmt, args);
|
||||
va_end (args);
|
||||
|
||||
split = g_strsplit_set (cmdline, " ", 0);
|
||||
if (!split) {
|
||||
g_set_error (error, NM_DCB_ERROR, NM_DCB_ERROR_INTERNAL,
|
||||
"failure parsing %s command line", helper_names[which]);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Allocate space for path, custom arg, interface name, arguments, and NULL */
|
||||
i = u = 0;
|
||||
argv = g_new0 (char *, g_strv_length (split) + 4);
|
||||
argv[i++] = NULL; /* Placeholder for dcbtool path */
|
||||
if (which == DCBTOOL) {
|
||||
argv[i++] = "sc";
|
||||
argv[i++] = (char *) iface;
|
||||
}
|
||||
while (u < g_strv_length (split))
|
||||
argv[i++] = split[u++];
|
||||
argv[i++] = NULL;
|
||||
success = run_func (argv, which, user_data, error);
|
||||
if (!success && error)
|
||||
g_assert (*error);
|
||||
|
||||
out:
|
||||
if (split)
|
||||
g_strfreev (split);
|
||||
g_free (argv);
|
||||
g_free (cmdline);
|
||||
g_free (errmsg);
|
||||
return success;
|
||||
}
|
||||
|
||||
#define SET_FLAGS(f, tag) \
|
||||
G_STMT_START { \
|
||||
if (!do_helper (iface, DCBTOOL, run_func, user_data, error, tag " e:%c a:%c w:%c", \
|
||||
f & NM_SETTING_DCB_FLAG_ENABLE ? '1' : '0', \
|
||||
f & NM_SETTING_DCB_FLAG_ADVERTISE ? '1' : '0', \
|
||||
f & NM_SETTING_DCB_FLAG_WILLING ? '1' : '0')) \
|
||||
return FALSE; \
|
||||
} G_STMT_END
|
||||
|
||||
#define SET_APP(f, s, tag) \
|
||||
G_STMT_START { \
|
||||
gint prio = nm_setting_dcb_get_app_##tag##_priority (s); \
|
||||
\
|
||||
SET_FLAGS (f, "app:" #tag); \
|
||||
if ((f & NM_SETTING_DCB_FLAG_ENABLE) && (prio >= 0)) { \
|
||||
if (!do_helper (iface, DCBTOOL, run_func, user_data, error, "app:" #tag " appcfg:%02x", (1 << prio))) \
|
||||
return FALSE; \
|
||||
} \
|
||||
} G_STMT_END
|
||||
|
||||
gboolean
|
||||
_dcb_setup (const char *iface,
|
||||
NMSettingDcb *s_dcb,
|
||||
DcbFunc run_func,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
NMSettingDcbFlags flags;
|
||||
guint i;
|
||||
|
||||
g_assert (s_dcb);
|
||||
|
||||
if (!do_helper (iface, DCBTOOL, run_func, user_data, error, "dcb on"))
|
||||
return FALSE;
|
||||
|
||||
/* FCoE */
|
||||
flags = nm_setting_dcb_get_app_fcoe_flags (s_dcb);
|
||||
SET_APP (flags, s_dcb, fcoe);
|
||||
|
||||
/* iSCSI */
|
||||
flags = nm_setting_dcb_get_app_iscsi_flags (s_dcb);
|
||||
SET_APP (flags, s_dcb, iscsi);
|
||||
|
||||
/* FIP */
|
||||
flags = nm_setting_dcb_get_app_fip_flags (s_dcb);
|
||||
SET_APP (flags, s_dcb, fip);
|
||||
|
||||
/* Priority Flow Control */
|
||||
flags = nm_setting_dcb_get_priority_flow_control_flags (s_dcb);
|
||||
SET_FLAGS (flags, "pfc");
|
||||
if (flags & NM_SETTING_DCB_FLAG_ENABLE) {
|
||||
char buf[10];
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
buf[i] = nm_setting_dcb_get_priority_flow_control (s_dcb, i) ? '1' : '0';
|
||||
buf[i] = 0;
|
||||
if (!do_helper (iface, DCBTOOL, run_func, user_data, error, "pfc pfcup:%s", buf))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Priority Groups */
|
||||
flags = nm_setting_dcb_get_priority_group_flags (s_dcb);
|
||||
SET_FLAGS (flags, "pg");
|
||||
if (flags & NM_SETTING_DCB_FLAG_ENABLE) {
|
||||
char buf[10];
|
||||
guint id;
|
||||
|
||||
/* Priority Groups */
|
||||
for (i = 0; i < 8; i++) {
|
||||
id = nm_setting_dcb_get_priority_group_id (s_dcb, i);
|
||||
g_assert (id < 8 || id == 15);
|
||||
buf[i] = (id < 8) ? ('0' + id) : 'f';
|
||||
}
|
||||
buf[i] = 0;
|
||||
if (!do_helper (iface, DCBTOOL, run_func, user_data, error, "pg pgid:%s", buf))
|
||||
return FALSE;
|
||||
|
||||
/* Priority Group Bandwidth */
|
||||
if (!do_helper (iface, DCBTOOL, run_func, user_data, error, "pg pgpct:%u,%u,%u,%u,%u,%u,%u,%u",
|
||||
nm_setting_dcb_get_priority_group_bandwidth (s_dcb, 0),
|
||||
nm_setting_dcb_get_priority_group_bandwidth (s_dcb, 1),
|
||||
nm_setting_dcb_get_priority_group_bandwidth (s_dcb, 2),
|
||||
nm_setting_dcb_get_priority_group_bandwidth (s_dcb, 3),
|
||||
nm_setting_dcb_get_priority_group_bandwidth (s_dcb, 4),
|
||||
nm_setting_dcb_get_priority_group_bandwidth (s_dcb, 5),
|
||||
nm_setting_dcb_get_priority_group_bandwidth (s_dcb, 6),
|
||||
nm_setting_dcb_get_priority_group_bandwidth (s_dcb, 7)))
|
||||
return FALSE;
|
||||
|
||||
/* Priority Bandwidth */
|
||||
if (!do_helper (iface, DCBTOOL, run_func, user_data, error, "pg uppct:%u,%u,%u,%u,%u,%u,%u,%u",
|
||||
nm_setting_dcb_get_priority_bandwidth (s_dcb, 0),
|
||||
nm_setting_dcb_get_priority_bandwidth (s_dcb, 1),
|
||||
nm_setting_dcb_get_priority_bandwidth (s_dcb, 2),
|
||||
nm_setting_dcb_get_priority_bandwidth (s_dcb, 3),
|
||||
nm_setting_dcb_get_priority_bandwidth (s_dcb, 4),
|
||||
nm_setting_dcb_get_priority_bandwidth (s_dcb, 5),
|
||||
nm_setting_dcb_get_priority_bandwidth (s_dcb, 6),
|
||||
nm_setting_dcb_get_priority_bandwidth (s_dcb, 7)))
|
||||
return FALSE;
|
||||
|
||||
/* Strict Bandwidth */
|
||||
for (i = 0; i < 8; i++)
|
||||
buf[i] = nm_setting_dcb_get_priority_strict_bandwidth (s_dcb, i) ? '1' : '0';
|
||||
buf[i] = 0;
|
||||
if (!do_helper (iface, DCBTOOL, run_func, user_data, error, "pg strict:%s", buf))
|
||||
return FALSE;
|
||||
|
||||
/* Priority Traffic Class */
|
||||
for (i = 0; i < 8; i++) {
|
||||
id = nm_setting_dcb_get_priority_traffic_class (s_dcb, i);
|
||||
g_assert (id < 8);
|
||||
buf[i] = '0' + id;
|
||||
}
|
||||
buf[i] = 0;
|
||||
if (!do_helper (iface, DCBTOOL, run_func, user_data, error, "pg up2tc:%s", buf))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_dcb_cleanup (const char *iface,
|
||||
DcbFunc run_func,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
/* FIXME: do we need to turn off features individually here? */
|
||||
return do_helper (iface, DCBTOOL, run_func, user_data, error, "dcb off");
|
||||
}
|
||||
|
||||
gboolean
|
||||
_fcoe_setup (const char *iface,
|
||||
NMSettingDcb *s_dcb,
|
||||
DcbFunc run_func,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
NMSettingDcbFlags flags;
|
||||
|
||||
g_assert (s_dcb);
|
||||
|
||||
flags = nm_setting_dcb_get_app_fcoe_flags (s_dcb);
|
||||
if (flags & NM_SETTING_DCB_FLAG_ENABLE) {
|
||||
const char *mode = nm_setting_dcb_get_app_fcoe_mode (s_dcb);
|
||||
|
||||
if (!do_helper (NULL, FCOEADM, run_func, user_data, error, "-m %s -c %s", mode, iface))
|
||||
return FALSE;
|
||||
} else {
|
||||
if (!do_helper (NULL, FCOEADM, run_func, user_data, error, "-d %s", iface))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_fcoe_cleanup (const char *iface,
|
||||
DcbFunc run_func,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
return do_helper (NULL, FCOEADM, run_func, user_data, error, "-d %s", iface);
|
||||
}
|
||||
|
||||
|
||||
static const char *dcbpaths[] = {
|
||||
"/sbin/dcbtool",
|
||||
"/usr/sbin/dcbtool",
|
||||
"/usr/local/sbin/dcbtool",
|
||||
NULL
|
||||
};
|
||||
static const char *fcoepaths[] = {
|
||||
"/sbin/fcoeadm",
|
||||
"/usr/sbin/fcoeadm",
|
||||
"/usr/local/sbin/fcoeadm",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
static gboolean
|
||||
run_helper (char **argv, guint which, gpointer user_data, GError **error)
|
||||
{
|
||||
static const char *helper_path[2] = { NULL, NULL };
|
||||
int exit_status = 0;
|
||||
gboolean success;
|
||||
char *errmsg = NULL, *outmsg = NULL;
|
||||
const char **iter;
|
||||
char *cmdline;
|
||||
|
||||
if (G_UNLIKELY (helper_path[which] == NULL)) {
|
||||
iter = (which == DCBTOOL) ? dcbpaths : fcoepaths;
|
||||
while (*iter) {
|
||||
if (g_file_test (*iter, G_FILE_TEST_EXISTS))
|
||||
helper_path[which] = *iter;
|
||||
iter++;
|
||||
}
|
||||
if (!helper_path[which]) {
|
||||
g_set_error (error, NM_DCB_ERROR, NM_DCB_ERROR_HELPER_NOT_FOUND,
|
||||
"%s not found",
|
||||
which == DCBTOOL ? "dcbtool" : "fcoadm");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
argv[0] = (char *) helper_path[which];
|
||||
cmdline = g_strjoinv (" ", argv);
|
||||
nm_log_dbg (LOGD_DCB, "%s", cmdline);
|
||||
|
||||
success = g_spawn_sync ("/", argv, NULL, 0 /*G_SPAWN_DEFAULT*/,
|
||||
nm_unblock_posix_signals, NULL,
|
||||
&outmsg, &errmsg, &exit_status, error);
|
||||
/* Log any stderr output */
|
||||
if (success && WIFEXITED (exit_status) && WEXITSTATUS (exit_status) && (errmsg || outmsg)) {
|
||||
nm_log_dbg (LOGD_DCB, "'%s' failed: '%s'",
|
||||
cmdline, (errmsg && strlen (errmsg)) ? errmsg : outmsg);
|
||||
g_set_error (error, NM_DCB_ERROR, NM_DCB_ERROR_HELPER_FAILED,
|
||||
"Failed to run '%s'", cmdline);
|
||||
success = FALSE;
|
||||
}
|
||||
g_free (errmsg);
|
||||
|
||||
g_free (cmdline);
|
||||
return success;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_dcb_setup (const char *iface, NMSettingDcb *s_dcb, GError **error)
|
||||
{
|
||||
gboolean success;
|
||||
|
||||
success = _dcb_setup (iface, s_dcb, run_helper, GUINT_TO_POINTER (DCBTOOL), error);
|
||||
if (success)
|
||||
success = _fcoe_setup (iface, s_dcb, run_helper, GUINT_TO_POINTER (FCOEADM), error);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_dcb_cleanup (const char *iface, GError **error)
|
||||
{
|
||||
return _dcb_cleanup (iface, run_helper, GUINT_TO_POINTER (DCBTOOL), error);
|
||||
}
|
||||
|
||||
93
src/nm-dcb.h
Normal file
93
src/nm-dcb.h
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2013 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef NM_DCB_H
|
||||
#define NM_DCB_H
|
||||
|
||||
#include <glib.h>
|
||||
#include "nm-setting-dcb.h"
|
||||
|
||||
/**
|
||||
* NMDcbError:
|
||||
* @NM_DCB_ERROR_UNKNOWN: unknown or unclassified error
|
||||
* @NM_DCB_ERROR_INTERNAL: a internal programmer error
|
||||
* @NM_DCB_ERROR_BAD_CONFIG: configuration was invalid
|
||||
* @NM_DCB_ERROR_HELPER_NOT_FOUND: the required helper program was not found
|
||||
* @NM_DCB_ERROR_HELPER_FAILED: the helper program failed
|
||||
*
|
||||
* NOTE: these errors are internal-use only and should never be used with D-Bus.
|
||||
**/
|
||||
typedef enum {
|
||||
NM_DCB_ERROR_UNKNOWN = 0,
|
||||
NM_DCB_ERROR_INTERNAL,
|
||||
NM_DCB_ERROR_BAD_CONFIG,
|
||||
NM_DCB_ERROR_HELPER_NOT_FOUND,
|
||||
NM_DCB_ERROR_HELPER_FAILED,
|
||||
} NMDcbError;
|
||||
|
||||
#define NM_DCB_ERROR (nm_dcb_error_quark ())
|
||||
GQuark nm_dcb_error_quark (void);
|
||||
#define NM_TYPE_DCB_ERROR (nm_dcb_error_get_type ())
|
||||
GType nm_dcb_error_get_type (void);
|
||||
|
||||
|
||||
gboolean nm_dcb_setup (const char *iface, NMSettingDcb *s_dcb, GError **error);
|
||||
gboolean nm_dcb_cleanup (const char *iface, GError **error);
|
||||
|
||||
/* For testcases only! */
|
||||
typedef gboolean (*DcbFunc) (char **argv,
|
||||
guint which,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
|
||||
#define DCBTOOL 0
|
||||
#define FCOEADM 1
|
||||
|
||||
gboolean do_helper (const char *iface,
|
||||
guint which,
|
||||
DcbFunc run_func,
|
||||
gpointer user_data,
|
||||
GError **error,
|
||||
const char *fmt,
|
||||
...) G_GNUC_PRINTF(6, 7);
|
||||
|
||||
gboolean _dcb_setup (const char *iface,
|
||||
NMSettingDcb *s_dcb,
|
||||
DcbFunc run_func,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
|
||||
gboolean _dcb_cleanup (const char *iface,
|
||||
DcbFunc run_func,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
|
||||
gboolean _fcoe_setup (const char *iface,
|
||||
NMSettingDcb *s_dcb,
|
||||
DcbFunc run_func,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
|
||||
gboolean _fcoe_cleanup (const char *iface,
|
||||
DcbFunc run_func,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
|
||||
#endif /* NM_DCB_H */
|
||||
|
|
@ -15,7 +15,8 @@ noinst_PROGRAMS = \
|
|||
test-policy-hosts \
|
||||
test-wifi-ap-utils \
|
||||
test-ip4-config \
|
||||
test-ip6-config
|
||||
test-ip6-config \
|
||||
test-dcb
|
||||
|
||||
####### DHCP options test #######
|
||||
|
||||
|
|
@ -62,6 +63,14 @@ test_ip6_config_SOURCES = \
|
|||
test_ip6_config_LDADD = \
|
||||
$(top_builddir)/src/libNetworkManager.la
|
||||
|
||||
####### DCB test #######
|
||||
|
||||
test_dcb_SOURCES = \
|
||||
test-dcb.c
|
||||
|
||||
test_dcb_LDADD = \
|
||||
$(top_builddir)/src/libNetworkManager.la
|
||||
|
||||
####### secret agent interface test #######
|
||||
|
||||
EXTRA_DIST = test-secret-agent.py
|
||||
|
|
@ -74,4 +83,5 @@ check-local: test-dhcp-options test-policy-hosts test-wifi-ap-utils test-ip4-con
|
|||
$(abs_builddir)/test-wifi-ap-utils
|
||||
$(abs_builddir)/test-ip4-config
|
||||
$(abs_builddir)/test-ip6-config
|
||||
$(abs_builddir)/test-dcb
|
||||
|
||||
|
|
|
|||
348
src/tests/test-dcb.c
Normal file
348
src/tests/test-dcb.c
Normal file
|
|
@ -0,0 +1,348 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2013 Red Hat, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <glib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "nm-dcb.h"
|
||||
|
||||
typedef struct {
|
||||
guint num;
|
||||
const char *cmds[];
|
||||
} DcbExpected;
|
||||
|
||||
static gboolean
|
||||
test_dcb_func (char **argv, guint which, gpointer user_data, GError **error)
|
||||
{
|
||||
DcbExpected *e = user_data;
|
||||
char *f;
|
||||
|
||||
g_assert (argv[0] == NULL);
|
||||
argv[0] = (which == DCBTOOL) ? "dcbtool" : "fcoeadm";
|
||||
|
||||
f = g_strjoinv (" ", argv);
|
||||
if (e->cmds[e->num] == NULL)
|
||||
g_assert_cmpstr (f, ==, NULL);
|
||||
g_assert_cmpstr (e->cmds[e->num], !=, NULL);
|
||||
g_assert_cmpstr (f, ==, e->cmds[e->num++]);
|
||||
g_free (f);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define DCB_FLAGS_ALL (NM_SETTING_DCB_FLAG_ENABLE | \
|
||||
NM_SETTING_DCB_FLAG_ADVERTISE | \
|
||||
NM_SETTING_DCB_FLAG_WILLING)
|
||||
|
||||
static void
|
||||
test_dcb_fcoe (void)
|
||||
{
|
||||
static DcbExpected expected = { 0,
|
||||
{ "dcbtool sc eth0 dcb on",
|
||||
"dcbtool sc eth0 app:fcoe e:1 a:1 w:1",
|
||||
"dcbtool sc eth0 app:fcoe appcfg:40",
|
||||
"dcbtool sc eth0 app:iscsi e:0 a:0 w:0",
|
||||
"dcbtool sc eth0 app:fip e:0 a:0 w:0",
|
||||
"dcbtool sc eth0 pfc e:0 a:0 w:0",
|
||||
"dcbtool sc eth0 pg e:0 a:0 w:0",
|
||||
NULL },
|
||||
};
|
||||
NMSettingDcb *s_dcb;
|
||||
GError *error = NULL;
|
||||
gboolean success;
|
||||
|
||||
s_dcb = (NMSettingDcb *) nm_setting_dcb_new ();
|
||||
g_object_set (G_OBJECT (s_dcb),
|
||||
NM_SETTING_DCB_APP_FCOE_FLAGS, DCB_FLAGS_ALL,
|
||||
NM_SETTING_DCB_APP_FCOE_PRIORITY, 6,
|
||||
NULL);
|
||||
|
||||
success = _dcb_setup ("eth0", s_dcb, test_dcb_func, &expected, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (success);
|
||||
|
||||
g_assert_cmpstr (expected.cmds[expected.num], ==, NULL);
|
||||
g_object_unref (s_dcb);
|
||||
}
|
||||
|
||||
static void
|
||||
test_dcb_iscsi (void)
|
||||
{
|
||||
static DcbExpected expected = { 0,
|
||||
{ "dcbtool sc eth0 dcb on",
|
||||
"dcbtool sc eth0 app:fcoe e:0 a:0 w:0",
|
||||
"dcbtool sc eth0 app:iscsi e:1 a:0 w:1",
|
||||
"dcbtool sc eth0 app:iscsi appcfg:08",
|
||||
"dcbtool sc eth0 app:fip e:0 a:0 w:0",
|
||||
"dcbtool sc eth0 pfc e:0 a:0 w:0",
|
||||
"dcbtool sc eth0 pg e:0 a:0 w:0",
|
||||
NULL },
|
||||
};
|
||||
NMSettingDcb *s_dcb;
|
||||
GError *error = NULL;
|
||||
gboolean success;
|
||||
|
||||
s_dcb = (NMSettingDcb *) nm_setting_dcb_new ();
|
||||
g_object_set (G_OBJECT (s_dcb),
|
||||
NM_SETTING_DCB_APP_ISCSI_FLAGS, (NM_SETTING_DCB_FLAG_ENABLE | NM_SETTING_DCB_FLAG_WILLING),
|
||||
NM_SETTING_DCB_APP_ISCSI_PRIORITY, 3,
|
||||
NULL);
|
||||
|
||||
success = _dcb_setup ("eth0", s_dcb, test_dcb_func, &expected, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (success);
|
||||
|
||||
g_assert_cmpstr (expected.cmds[expected.num], ==, NULL);
|
||||
g_object_unref (s_dcb);
|
||||
}
|
||||
|
||||
static void
|
||||
test_dcb_fip (void)
|
||||
{
|
||||
static DcbExpected expected = { 0,
|
||||
{ "dcbtool sc eth0 dcb on",
|
||||
"dcbtool sc eth0 app:fcoe e:0 a:0 w:0",
|
||||
"dcbtool sc eth0 app:iscsi e:0 a:0 w:0",
|
||||
"dcbtool sc eth0 app:fip e:1 a:1 w:0",
|
||||
"dcbtool sc eth0 app:fip appcfg:01",
|
||||
"dcbtool sc eth0 pfc e:0 a:0 w:0",
|
||||
"dcbtool sc eth0 pg e:0 a:0 w:0",
|
||||
NULL },
|
||||
};
|
||||
NMSettingDcb *s_dcb;
|
||||
GError *error = NULL;
|
||||
gboolean success;
|
||||
|
||||
s_dcb = (NMSettingDcb *) nm_setting_dcb_new ();
|
||||
g_object_set (G_OBJECT (s_dcb),
|
||||
NM_SETTING_DCB_APP_FIP_FLAGS, (NM_SETTING_DCB_FLAG_ENABLE | NM_SETTING_DCB_FLAG_ADVERTISE),
|
||||
NM_SETTING_DCB_APP_FIP_PRIORITY, 0,
|
||||
NULL);
|
||||
|
||||
success = _dcb_setup ("eth0", s_dcb, test_dcb_func, &expected, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (success);
|
||||
|
||||
g_assert_cmpstr (expected.cmds[expected.num], ==, NULL);
|
||||
g_object_unref (s_dcb);
|
||||
}
|
||||
|
||||
static void
|
||||
test_dcb_fip_default_prio (void)
|
||||
{
|
||||
static DcbExpected expected = { 0,
|
||||
{ "dcbtool sc eth0 dcb on",
|
||||
"dcbtool sc eth0 app:fcoe e:0 a:0 w:0",
|
||||
"dcbtool sc eth0 app:iscsi e:0 a:0 w:0",
|
||||
"dcbtool sc eth0 app:fip e:1 a:1 w:0",
|
||||
"dcbtool sc eth0 pfc e:0 a:0 w:0",
|
||||
"dcbtool sc eth0 pg e:0 a:0 w:0",
|
||||
NULL },
|
||||
};
|
||||
NMSettingDcb *s_dcb;
|
||||
GError *error = NULL;
|
||||
gboolean success;
|
||||
|
||||
s_dcb = (NMSettingDcb *) nm_setting_dcb_new ();
|
||||
g_object_set (G_OBJECT (s_dcb),
|
||||
NM_SETTING_DCB_APP_FIP_FLAGS, (NM_SETTING_DCB_FLAG_ENABLE | NM_SETTING_DCB_FLAG_ADVERTISE),
|
||||
NM_SETTING_DCB_APP_FIP_PRIORITY, -1,
|
||||
NULL);
|
||||
|
||||
success = _dcb_setup ("eth0", s_dcb, test_dcb_func, &expected, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (success);
|
||||
|
||||
g_assert_cmpstr (expected.cmds[expected.num], ==, NULL);
|
||||
g_object_unref (s_dcb);
|
||||
}
|
||||
|
||||
static void
|
||||
test_dcb_pfc (void)
|
||||
{
|
||||
static DcbExpected expected = { 0,
|
||||
{ "dcbtool sc eth0 dcb on",
|
||||
"dcbtool sc eth0 app:fcoe e:0 a:0 w:0",
|
||||
"dcbtool sc eth0 app:iscsi e:0 a:0 w:0",
|
||||
"dcbtool sc eth0 app:fip e:0 a:0 w:0",
|
||||
"dcbtool sc eth0 pfc e:1 a:1 w:1",
|
||||
"dcbtool sc eth0 pfc pfcup:01101100",
|
||||
"dcbtool sc eth0 pg e:0 a:0 w:0",
|
||||
NULL },
|
||||
};
|
||||
NMSettingDcb *s_dcb;
|
||||
GError *error = NULL;
|
||||
gboolean success;
|
||||
|
||||
s_dcb = (NMSettingDcb *) nm_setting_dcb_new ();
|
||||
g_object_set (G_OBJECT (s_dcb),
|
||||
NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS, DCB_FLAGS_ALL,
|
||||
NULL);
|
||||
|
||||
nm_setting_dcb_set_priority_flow_control (s_dcb, 0, FALSE);
|
||||
nm_setting_dcb_set_priority_flow_control (s_dcb, 1, TRUE);
|
||||
nm_setting_dcb_set_priority_flow_control (s_dcb, 2, TRUE);
|
||||
nm_setting_dcb_set_priority_flow_control (s_dcb, 3, FALSE);
|
||||
nm_setting_dcb_set_priority_flow_control (s_dcb, 4, TRUE);
|
||||
nm_setting_dcb_set_priority_flow_control (s_dcb, 5, TRUE);
|
||||
nm_setting_dcb_set_priority_flow_control (s_dcb, 6, FALSE);
|
||||
nm_setting_dcb_set_priority_flow_control (s_dcb, 7, FALSE);
|
||||
|
||||
success = _dcb_setup ("eth0", s_dcb, test_dcb_func, &expected, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (success);
|
||||
|
||||
g_assert_cmpstr (expected.cmds[expected.num], ==, NULL);
|
||||
g_object_unref (s_dcb);
|
||||
}
|
||||
|
||||
static void
|
||||
test_dcb_priority_groups (void)
|
||||
{
|
||||
static DcbExpected expected = { 0,
|
||||
{ "dcbtool sc eth0 dcb on",
|
||||
"dcbtool sc eth0 app:fcoe e:0 a:0 w:0",
|
||||
"dcbtool sc eth0 app:iscsi e:0 a:0 w:0",
|
||||
"dcbtool sc eth0 app:fip e:0 a:0 w:0",
|
||||
"dcbtool sc eth0 pfc e:0 a:0 w:0",
|
||||
"dcbtool sc eth0 pg e:1 a:1 w:1",
|
||||
"dcbtool sc eth0 pg pgid:765f3210",
|
||||
"dcbtool sc eth0 pg pgpct:10,40,5,10,5,20,7,3",
|
||||
"dcbtool sc eth0 pg uppct:100,50,33,25,20,16,14,12",
|
||||
"dcbtool sc eth0 pg strict:01010101",
|
||||
"dcbtool sc eth0 pg up2tc:01201201",
|
||||
NULL },
|
||||
};
|
||||
NMSettingDcb *s_dcb;
|
||||
GError *error = NULL;
|
||||
gboolean success;
|
||||
guint i;
|
||||
|
||||
s_dcb = (NMSettingDcb *) nm_setting_dcb_new ();
|
||||
g_object_set (G_OBJECT (s_dcb),
|
||||
NM_SETTING_DCB_PRIORITY_GROUP_FLAGS, DCB_FLAGS_ALL,
|
||||
NULL);
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
/* Make sure at least one 15/f is present in the group IDs */
|
||||
nm_setting_dcb_set_priority_group_id (s_dcb, i, (i == 3) ? 15 : 7 - i);
|
||||
nm_setting_dcb_set_priority_bandwidth (s_dcb, i, 100 / (i + 1));
|
||||
nm_setting_dcb_set_priority_strict_bandwidth (s_dcb, i, i % 2);
|
||||
nm_setting_dcb_set_priority_traffic_class (s_dcb, i, i % 3);
|
||||
}
|
||||
|
||||
nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 0, 10);
|
||||
nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 1, 40);
|
||||
nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 2, 5);
|
||||
nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 3, 10);
|
||||
nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 4, 5);
|
||||
nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 5, 20);
|
||||
nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 6, 7);
|
||||
nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 7, 3);
|
||||
|
||||
success = _dcb_setup ("eth0", s_dcb, test_dcb_func, &expected, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (success);
|
||||
|
||||
g_assert_cmpstr (expected.cmds[expected.num], ==, NULL);
|
||||
g_object_unref (s_dcb);
|
||||
}
|
||||
|
||||
static void
|
||||
test_dcb_cleanup (void)
|
||||
{
|
||||
static DcbExpected expected = { 0,
|
||||
{ "dcbtool sc eth0 dcb off", NULL },
|
||||
};
|
||||
GError *error = NULL;
|
||||
gboolean success;
|
||||
|
||||
success = _dcb_cleanup ("eth0", test_dcb_func, &expected, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (success);
|
||||
}
|
||||
|
||||
static void
|
||||
test_fcoe_create (void)
|
||||
{
|
||||
static DcbExpected expected1 = { 0,
|
||||
{ "fcoeadm -m fabric -c eth0", NULL },
|
||||
};
|
||||
static DcbExpected expected2 = { 0,
|
||||
{ "fcoeadm -m vn2vn -c eth0", NULL },
|
||||
};
|
||||
GError *error = NULL;
|
||||
gboolean success;
|
||||
NMSettingDcb *s_dcb;
|
||||
|
||||
s_dcb = (NMSettingDcb *) nm_setting_dcb_new ();
|
||||
g_object_set (G_OBJECT (s_dcb),
|
||||
NM_SETTING_DCB_APP_FCOE_FLAGS, DCB_FLAGS_ALL,
|
||||
NULL);
|
||||
|
||||
/* Default mode is fabric */
|
||||
success = _fcoe_setup ("eth0", s_dcb, test_dcb_func, &expected1, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (success);
|
||||
|
||||
/* Test VN2VN */
|
||||
g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_APP_FCOE_MODE, NM_SETTING_DCB_FCOE_MODE_VN2VN, NULL);
|
||||
success = _fcoe_setup ("eth0", s_dcb, test_dcb_func, &expected2, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (success);
|
||||
|
||||
g_object_unref (s_dcb);
|
||||
}
|
||||
|
||||
static void
|
||||
test_fcoe_cleanup (void)
|
||||
{
|
||||
static DcbExpected expected = { 0,
|
||||
{ "fcoeadm -d eth0", NULL },
|
||||
};
|
||||
GError *error = NULL;
|
||||
gboolean success;
|
||||
|
||||
success = _fcoe_cleanup ("eth0", test_dcb_func, &expected, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (success);
|
||||
}
|
||||
|
||||
/*******************************************/
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_type_init ();
|
||||
|
||||
g_test_add_func ("/dcb/fcoe", test_dcb_fcoe);
|
||||
g_test_add_func ("/dcb/iscsi", test_dcb_iscsi);
|
||||
g_test_add_func ("/dcb/fip", test_dcb_fip);
|
||||
g_test_add_func ("/dcb/fip-default-priority", test_dcb_fip_default_prio);
|
||||
g_test_add_func ("/dcb/pfc", test_dcb_pfc);
|
||||
g_test_add_func ("/dcb/priority-groups", test_dcb_priority_groups);
|
||||
g_test_add_func ("/dcb/cleanup", test_dcb_cleanup);
|
||||
g_test_add_func ("/fcoe/create", test_fcoe_create);
|
||||
g_test_add_func ("/fcoe/cleanup", test_fcoe_cleanup);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
||||
Loading…
Add table
Reference in a new issue