mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-25 20:00:09 +01:00
Add DCB setting and associated logic to propagate those settings to dcbtool. At the moment we don't use dcbnl to talk directly to the kernel, because some devices do parts of DCB/LLDP in userland and thus need lldpad running, which dcbtool talks to.
This commit is contained in:
commit
df406d06b6
37 changed files with 3799 additions and 8 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -176,7 +176,9 @@ valgrind-*.log
|
|||
/libnm-util/tests/test-need-secrets
|
||||
/libnm-util/tests/test-secrets
|
||||
/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
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@
|
|||
<xi:include href="xml/nm-setting-vlan.xml"/>
|
||||
<xi:include href="xml/nm-setting-olpc-mesh.xml"/>
|
||||
<xi:include href="xml/nm-setting-adsl.xml"/>
|
||||
<xi:include href="xml/nm-setting-dcb.xml"/>
|
||||
<xi:include href="xml/nm-setting-8021x.xml"/>
|
||||
<xi:include href="xml/nm-setting-ip4-config.xml"/>
|
||||
<xi:include href="xml/nm-setting-ip6-config.xml"/>
|
||||
|
|
|
|||
|
|
@ -545,6 +545,9 @@ typedef enum {
|
|||
/* A secondary connection of the base connection failed */
|
||||
NM_DEVICE_STATE_REASON_SECONDARY_CONNECTION_FAILED = 54,
|
||||
|
||||
/* DCB or FCoE setup failed */
|
||||
NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED = 55,
|
||||
|
||||
/* Unused */
|
||||
NM_DEVICE_STATE_REASON_LAST = 0xFFFF
|
||||
} NMDeviceStateReason;
|
||||
|
|
|
|||
|
|
@ -579,6 +579,11 @@
|
|||
A secondary connection of the base connection failed.
|
||||
</tp:docstring>
|
||||
</tp:enumvalue>
|
||||
<tp:enumvalue suffix="DCB_FCOE_FAILED" value="55">
|
||||
<tp:docstring>
|
||||
DCB or FCoE setup failed.
|
||||
</tp:docstring>
|
||||
</tp:enumvalue>
|
||||
</tp:enum>
|
||||
|
||||
<tp:struct name="NM_DEVICE_STATE_REASON_STRUCT">
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ libnm_util_include_HEADERS = \
|
|||
nm-setting-bridge.h \
|
||||
nm-setting-bridge-port.h \
|
||||
nm-setting-connection.h \
|
||||
nm-setting-dcb.h \
|
||||
nm-setting-infiniband.h \
|
||||
nm-setting-ip4-config.h \
|
||||
nm-setting-vlan.h \
|
||||
|
|
@ -71,6 +72,7 @@ libnm_util_la_csources = \
|
|||
nm-setting-bridge.c \
|
||||
nm-setting-bridge-port.c \
|
||||
nm-setting-connection.c \
|
||||
nm-setting-dcb.c \
|
||||
nm-setting-infiniband.c \
|
||||
nm-setting-ip4-config.c \
|
||||
nm-setting-vlan.c \
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ global:
|
|||
nm_connection_get_setting_by_name;
|
||||
nm_connection_get_setting_cdma;
|
||||
nm_connection_get_setting_connection;
|
||||
nm_connection_get_setting_dcb;
|
||||
nm_connection_get_setting_generic;
|
||||
nm_connection_get_setting_gsm;
|
||||
nm_connection_get_setting_infiniband;
|
||||
|
|
@ -263,6 +264,32 @@ global:
|
|||
nm_setting_connection_permissions_user_allowed;
|
||||
nm_setting_connection_remove_permission;
|
||||
nm_setting_connection_remove_secondary;
|
||||
nm_setting_dcb_error_get_type;
|
||||
nm_setting_dcb_error_quark;
|
||||
nm_setting_dcb_flags_get_type;
|
||||
nm_setting_dcb_get_app_fcoe_flags;
|
||||
nm_setting_dcb_get_app_fcoe_mode;
|
||||
nm_setting_dcb_get_app_fcoe_priority;
|
||||
nm_setting_dcb_get_app_fip_flags;
|
||||
nm_setting_dcb_get_app_fip_priority;
|
||||
nm_setting_dcb_get_app_iscsi_flags;
|
||||
nm_setting_dcb_get_app_iscsi_priority;
|
||||
nm_setting_dcb_get_priority_bandwidth;
|
||||
nm_setting_dcb_get_priority_flow_control;
|
||||
nm_setting_dcb_get_priority_flow_control_flags;
|
||||
nm_setting_dcb_get_priority_group_bandwidth;
|
||||
nm_setting_dcb_get_priority_group_flags;
|
||||
nm_setting_dcb_get_priority_group_id;
|
||||
nm_setting_dcb_get_priority_strict_bandwidth;
|
||||
nm_setting_dcb_get_priority_traffic_class;
|
||||
nm_setting_dcb_get_type;
|
||||
nm_setting_dcb_new;
|
||||
nm_setting_dcb_set_priority_bandwidth;
|
||||
nm_setting_dcb_set_priority_flow_control;
|
||||
nm_setting_dcb_set_priority_group_bandwidth;
|
||||
nm_setting_dcb_set_priority_group_id;
|
||||
nm_setting_dcb_set_priority_strict_bandwidth;
|
||||
nm_setting_dcb_set_priority_traffic_class;
|
||||
nm_setting_diff;
|
||||
nm_setting_diff_result_get_type;
|
||||
nm_setting_duplicate;
|
||||
|
|
|
|||
|
|
@ -1326,6 +1326,22 @@ nm_connection_get_setting_connection (NMConnection *connection)
|
|||
return (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_connection_get_setting_dcb:
|
||||
* @connection: the #NMConnection
|
||||
*
|
||||
* A shortcut to return any #NMSettingDcb the connection might contain.
|
||||
*
|
||||
* Returns: (transfer none): an #NMSettingDcb if the connection contains one, otherwise NULL
|
||||
**/
|
||||
NMSettingDcb *
|
||||
nm_connection_get_setting_dcb (NMConnection *connection)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
|
||||
|
||||
return (NMSettingDcb *) nm_connection_get_setting (connection, NM_TYPE_SETTING_DCB);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_connection_get_setting_generic:
|
||||
* @connection: the #NMConnection
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
#include <nm-setting-bridge-port.h>
|
||||
#include <nm-setting-cdma.h>
|
||||
#include <nm-setting-connection.h>
|
||||
#include <nm-setting-dcb.h>
|
||||
#include <nm-setting-generic.h>
|
||||
#include <nm-setting-gsm.h>
|
||||
#include <nm-setting-infiniband.h>
|
||||
|
|
@ -208,6 +209,7 @@ NMSettingBridge * nm_connection_get_setting_bridge (NMConnec
|
|||
NMSettingBridgePort * nm_connection_get_setting_bridge_port (NMConnection *connection);
|
||||
NMSettingCdma * nm_connection_get_setting_cdma (NMConnection *connection);
|
||||
NMSettingConnection * nm_connection_get_setting_connection (NMConnection *connection);
|
||||
NMSettingDcb * nm_connection_get_setting_dcb (NMConnection *connection);
|
||||
NMSettingGeneric * nm_connection_get_setting_generic (NMConnection *connection);
|
||||
NMSettingGsm * nm_connection_get_setting_gsm (NMConnection *connection);
|
||||
NMSettingInfiniband * nm_connection_get_setting_infiniband (NMConnection *connection);
|
||||
|
|
|
|||
1258
libnm-util/nm-setting-dcb.c
Normal file
1258
libnm-util/nm-setting-dcb.c
Normal file
File diff suppressed because it is too large
Load diff
187
libnm-util/nm-setting-dcb.h
Normal file
187
libnm-util/nm-setting-dcb.h
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
|
||||
/*
|
||||
* Dan Williams <dcbw@redhat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* (C) Copyright 2013 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef NM_SETTING_DCB_H
|
||||
#define NM_SETTING_DCB_H
|
||||
|
||||
#include <nm-setting.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define NM_TYPE_SETTING_DCB (nm_setting_dcb_get_type ())
|
||||
#define NM_SETTING_DCB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_SETTING_DCB, NMSettingDcb))
|
||||
#define NM_SETTING_DCB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_SETTING_DCB, NMSettingDcbClass))
|
||||
#define NM_IS_SETTING_DCB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_SETTING_DCB))
|
||||
#define NM_IS_SETTING_DCB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_SETTING_DCB))
|
||||
#define NM_SETTING_DCB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_SETTING_DCB, NMSettingDcbClass))
|
||||
|
||||
#define NM_SETTING_DCB_SETTING_NAME "dcb"
|
||||
|
||||
/**
|
||||
* NMSettingDcbError:
|
||||
* @NM_SETTING_DCB_ERROR_UNKNOWN: unknown or unclassified error
|
||||
* @NM_SETTING_DCB_ERROR_INVALID_PROPERTY: the property was invalid
|
||||
* @NM_SETTING_DCB_ERROR_MISSING_PROPERTY: the property was missing and is
|
||||
* required
|
||||
*/
|
||||
typedef enum {
|
||||
NM_SETTING_DCB_ERROR_UNKNOWN = 0, /*< nick=UnknownError >*/
|
||||
NM_SETTING_DCB_ERROR_INVALID_PROPERTY, /*< nick=InvalidProperty >*/
|
||||
NM_SETTING_DCB_ERROR_MISSING_PROPERTY /*< nick=MissingProperty >*/
|
||||
} NMSettingDcbError;
|
||||
|
||||
#define NM_SETTING_DCB_ERROR nm_setting_dcb_error_quark ()
|
||||
GQuark nm_setting_dcb_error_quark (void);
|
||||
|
||||
/**
|
||||
* NMSettingDcbFlags:
|
||||
* @NM_SETTING_DCB_FLAG_NONE: no flag
|
||||
* @NM_SETTING_DCB_FLAG_ENABLE: the feature is enabled
|
||||
* @NM_SETTING_DCB_FLAG_ADVERTISE: the feature is advertised
|
||||
* @NM_SETTING_DCB_FLAG_WILLING: the feature is willing to change based on
|
||||
* peer configuration advertisements
|
||||
*
|
||||
* DCB feature flags.
|
||||
*
|
||||
* Since: 0.9.10
|
||||
**/
|
||||
typedef enum {
|
||||
NM_SETTING_DCB_FLAG_NONE = 0x00000000,
|
||||
NM_SETTING_DCB_FLAG_ENABLE = 0x00000001,
|
||||
NM_SETTING_DCB_FLAG_ADVERTISE = 0x00000002,
|
||||
NM_SETTING_DCB_FLAG_WILLING = 0x00000004
|
||||
} NMSettingDcbFlags;
|
||||
|
||||
/**
|
||||
* NM_SETTING_DCB_FCOE_MODE_FABRIC:
|
||||
*
|
||||
* Indicates that the FCoE controller should use "fabric" mode (default)
|
||||
*
|
||||
* Since: 0.9.10
|
||||
*/
|
||||
#define NM_SETTING_DCB_FCOE_MODE_FABRIC "fabric"
|
||||
|
||||
/**
|
||||
* NM_SETTING_DCB_FCOE_MODE_VN2VN:
|
||||
*
|
||||
* Indicates that the FCoE controller should use "VN2VN" mode.
|
||||
*
|
||||
* Since: 0.9.10
|
||||
*/
|
||||
#define NM_SETTING_DCB_FCOE_MODE_VN2VN "vn2vn"
|
||||
|
||||
|
||||
/* Properties */
|
||||
#define NM_SETTING_DCB_APP_FCOE_FLAGS "app-fcoe-flags"
|
||||
#define NM_SETTING_DCB_APP_FCOE_PRIORITY "app-fcoe-priority"
|
||||
#define NM_SETTING_DCB_APP_FCOE_MODE "app-fcoe-mode"
|
||||
|
||||
#define NM_SETTING_DCB_APP_ISCSI_FLAGS "app-iscsi-flags"
|
||||
#define NM_SETTING_DCB_APP_ISCSI_PRIORITY "app-iscsi-priority"
|
||||
|
||||
#define NM_SETTING_DCB_APP_FIP_FLAGS "app-fip-flags"
|
||||
#define NM_SETTING_DCB_APP_FIP_PRIORITY "app-fip-priority"
|
||||
|
||||
#define NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS "priority-flow-control-flags"
|
||||
#define NM_SETTING_DCB_PRIORITY_FLOW_CONTROL "priority-flow-control"
|
||||
|
||||
#define NM_SETTING_DCB_PRIORITY_GROUP_FLAGS "priority-group-flags"
|
||||
#define NM_SETTING_DCB_PRIORITY_GROUP_ID "priority-group-id"
|
||||
#define NM_SETTING_DCB_PRIORITY_GROUP_BANDWIDTH "priority-group-bandwidth"
|
||||
#define NM_SETTING_DCB_PRIORITY_BANDWIDTH "priority-bandwidth"
|
||||
#define NM_SETTING_DCB_PRIORITY_STRICT_BANDWIDTH "priority-strict-bandwidth"
|
||||
#define NM_SETTING_DCB_PRIORITY_TRAFFIC_CLASS "priority-traffic-class"
|
||||
|
||||
|
||||
typedef struct {
|
||||
NMSetting parent;
|
||||
} NMSettingDcb;
|
||||
|
||||
typedef struct {
|
||||
NMSettingClass parent;
|
||||
|
||||
/* Padding for future expansion */
|
||||
void (*_reserved1) (void);
|
||||
void (*_reserved2) (void);
|
||||
void (*_reserved3) (void);
|
||||
void (*_reserved4) (void);
|
||||
} NMSettingDcbClass;
|
||||
|
||||
GType nm_setting_dcb_get_type (void);
|
||||
|
||||
NMSetting * nm_setting_dcb_new (void);
|
||||
|
||||
NMSettingDcbFlags nm_setting_dcb_get_app_fcoe_flags (NMSettingDcb *setting);
|
||||
gint nm_setting_dcb_get_app_fcoe_priority (NMSettingDcb *setting);
|
||||
const char * nm_setting_dcb_get_app_fcoe_mode (NMSettingDcb *setting);
|
||||
|
||||
NMSettingDcbFlags nm_setting_dcb_get_app_iscsi_flags (NMSettingDcb *setting);
|
||||
gint nm_setting_dcb_get_app_iscsi_priority (NMSettingDcb *setting);
|
||||
|
||||
NMSettingDcbFlags nm_setting_dcb_get_app_fip_flags (NMSettingDcb *setting);
|
||||
gint nm_setting_dcb_get_app_fip_priority (NMSettingDcb *setting);
|
||||
|
||||
/* Priority Flow Control */
|
||||
NMSettingDcbFlags nm_setting_dcb_get_priority_flow_control_flags (NMSettingDcb *setting);
|
||||
gboolean nm_setting_dcb_get_priority_flow_control (NMSettingDcb *setting,
|
||||
guint user_priority);
|
||||
void nm_setting_dcb_set_priority_flow_control (NMSettingDcb *setting,
|
||||
guint user_priority,
|
||||
gboolean enabled);
|
||||
|
||||
/* Priority Groups */
|
||||
NMSettingDcbFlags nm_setting_dcb_get_priority_group_flags (NMSettingDcb *setting);
|
||||
|
||||
guint nm_setting_dcb_get_priority_group_id (NMSettingDcb *setting,
|
||||
guint user_priority);
|
||||
void nm_setting_dcb_set_priority_group_id (NMSettingDcb *setting,
|
||||
guint user_priority,
|
||||
guint group_id);
|
||||
|
||||
guint nm_setting_dcb_get_priority_group_bandwidth (NMSettingDcb *setting,
|
||||
guint group_id);
|
||||
void nm_setting_dcb_set_priority_group_bandwidth (NMSettingDcb *setting,
|
||||
guint group_id,
|
||||
guint bandwidth_percent);
|
||||
|
||||
guint nm_setting_dcb_get_priority_bandwidth (NMSettingDcb *setting,
|
||||
guint user_priority);
|
||||
void nm_setting_dcb_set_priority_bandwidth (NMSettingDcb *setting,
|
||||
guint user_priority,
|
||||
guint bandwidth_percent);
|
||||
|
||||
gboolean nm_setting_dcb_get_priority_strict_bandwidth (NMSettingDcb *setting,
|
||||
guint user_priority);
|
||||
void nm_setting_dcb_set_priority_strict_bandwidth (NMSettingDcb *setting,
|
||||
guint user_priority,
|
||||
gboolean strict);
|
||||
|
||||
guint nm_setting_dcb_get_priority_traffic_class (NMSettingDcb *setting,
|
||||
guint user_priority);
|
||||
void nm_setting_dcb_set_priority_traffic_class (NMSettingDcb *setting,
|
||||
guint user_priority,
|
||||
guint traffic_class);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* NM_SETTING_DCB_H */
|
||||
|
|
@ -16,7 +16,8 @@ noinst_PROGRAMS = \
|
|||
test-crypto \
|
||||
test-secrets \
|
||||
test-general \
|
||||
test-setting-8021x
|
||||
test-setting-8021x \
|
||||
test-setting-dcb
|
||||
|
||||
test_settings_defaults_SOURCES = \
|
||||
test-settings-defaults.c
|
||||
|
|
@ -58,10 +59,19 @@ test_setting_8021x_LDADD = \
|
|||
$(GLIB_LIBS) \
|
||||
$(DBUS_LIBS)
|
||||
|
||||
check-local: test-settings-defaults test-crypto test-secrets
|
||||
test_setting_dcb_SOURCES = \
|
||||
test-setting-dcb.c
|
||||
|
||||
test_setting_dcb_LDADD = \
|
||||
$(top_builddir)/libnm-util/libnm-util.la \
|
||||
$(GLIB_LIBS) \
|
||||
$(DBUS_LIBS)
|
||||
|
||||
check-local: test-settings-defaults test-crypto test-secrets test-setting-8021x test-setting-dcb
|
||||
$(abs_builddir)/test-settings-defaults
|
||||
$(abs_builddir)/test-secrets
|
||||
$(abs_builddir)/test-general
|
||||
$(abs_builddir)/test-setting-dcb
|
||||
|
||||
# Private key and CA certificate in the same file (PEM)
|
||||
$(abs_builddir)/test-setting-8021x $(srcdir)/certs/test_key_and_cert.pem "test"
|
||||
|
|
|
|||
308
libnm-util/tests/test-setting-dcb.c
Normal file
308
libnm-util/tests/test-setting-dcb.c
Normal file
|
|
@ -0,0 +1,308 @@
|
|||
/* -*- 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-utils.h>
|
||||
#include "nm-setting-dcb.h"
|
||||
|
||||
#define DCB_FLAGS_ALL (NM_SETTING_DCB_FLAG_ENABLE | \
|
||||
NM_SETTING_DCB_FLAG_ADVERTISE | \
|
||||
NM_SETTING_DCB_FLAG_WILLING)
|
||||
|
||||
static void
|
||||
test_dcb_flags_valid (void)
|
||||
{
|
||||
NMSettingDcb *s_dcb;
|
||||
GError *error = NULL;
|
||||
gboolean success;
|
||||
guint i;
|
||||
|
||||
s_dcb = (NMSettingDcb *) nm_setting_dcb_new ();
|
||||
g_assert (s_dcb);
|
||||
|
||||
g_assert_cmpint (nm_setting_dcb_get_app_fcoe_flags (s_dcb), ==, 0);
|
||||
g_assert_cmpint (nm_setting_dcb_get_app_iscsi_flags (s_dcb), ==, 0);
|
||||
g_assert_cmpint (nm_setting_dcb_get_app_fip_flags (s_dcb), ==, 0);
|
||||
g_assert_cmpint (nm_setting_dcb_get_priority_flow_control_flags (s_dcb), ==, 0);
|
||||
g_assert_cmpint (nm_setting_dcb_get_priority_group_flags (s_dcb), ==, 0);
|
||||
|
||||
g_object_set (G_OBJECT (s_dcb),
|
||||
NM_SETTING_DCB_APP_FCOE_FLAGS, DCB_FLAGS_ALL,
|
||||
NM_SETTING_DCB_APP_ISCSI_FLAGS, DCB_FLAGS_ALL,
|
||||
NM_SETTING_DCB_APP_FIP_FLAGS, DCB_FLAGS_ALL,
|
||||
NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS, DCB_FLAGS_ALL,
|
||||
NM_SETTING_DCB_PRIORITY_GROUP_FLAGS, DCB_FLAGS_ALL,
|
||||
NULL);
|
||||
/* Priority Group Bandwidth must total 100% */
|
||||
for (i = 0; i < 7; i++)
|
||||
nm_setting_dcb_set_priority_group_bandwidth (s_dcb, i, 12);
|
||||
nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 7, 16);
|
||||
|
||||
success = nm_setting_verify (NM_SETTING (s_dcb), NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (success);
|
||||
|
||||
g_assert_cmpint (nm_setting_dcb_get_app_fcoe_flags (s_dcb), ==, DCB_FLAGS_ALL);
|
||||
g_assert_cmpint (nm_setting_dcb_get_app_iscsi_flags (s_dcb), ==, DCB_FLAGS_ALL);
|
||||
g_assert_cmpint (nm_setting_dcb_get_app_fip_flags (s_dcb), ==, DCB_FLAGS_ALL);
|
||||
g_assert_cmpint (nm_setting_dcb_get_priority_flow_control_flags (s_dcb), ==, DCB_FLAGS_ALL);
|
||||
g_assert_cmpint (nm_setting_dcb_get_priority_group_flags (s_dcb), ==, DCB_FLAGS_ALL);
|
||||
}
|
||||
|
||||
#define TEST_FLAG(p, f, v) \
|
||||
{ \
|
||||
/* GObject property min/max should ensure the property does not get set to \
|
||||
* the invalid value, so we ensure the value we just tried to set is 0 and \
|
||||
* that verify is successful since the property never got set. \
|
||||
*/ \
|
||||
g_object_set (G_OBJECT (s_dcb), p, v, NULL); \
|
||||
g_assert_cmpint (f (s_dcb), ==, 0); \
|
||||
success = nm_setting_verify (NM_SETTING (s_dcb), NULL, &error); \
|
||||
g_assert_no_error (error); \
|
||||
g_assert (success); \
|
||||
}
|
||||
|
||||
static void
|
||||
test_dcb_flags_invalid (void)
|
||||
{
|
||||
NMSettingDcb *s_dcb;
|
||||
GError *error = NULL;
|
||||
gboolean success;
|
||||
|
||||
s_dcb = (NMSettingDcb *) nm_setting_dcb_new ();
|
||||
g_assert (s_dcb);
|
||||
|
||||
TEST_FLAG (NM_SETTING_DCB_APP_FCOE_FLAGS, nm_setting_dcb_get_app_fcoe_flags, 0x332523);
|
||||
TEST_FLAG (NM_SETTING_DCB_APP_ISCSI_FLAGS, nm_setting_dcb_get_app_iscsi_flags, 0xFF);
|
||||
TEST_FLAG (NM_SETTING_DCB_APP_FIP_FLAGS, nm_setting_dcb_get_app_fip_flags, 0x1111);
|
||||
TEST_FLAG (NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS, nm_setting_dcb_get_priority_flow_control_flags, G_MAXUINT32);
|
||||
TEST_FLAG (NM_SETTING_DCB_PRIORITY_GROUP_FLAGS, nm_setting_dcb_get_priority_group_flags,
|
||||
(NM_SETTING_DCB_FLAG_ENABLE | NM_SETTING_DCB_FLAG_ADVERTISE | NM_SETTING_DCB_FLAG_WILLING) + 1);
|
||||
}
|
||||
|
||||
#define TEST_APP_PRIORITY(lcprop, ucprop, v) \
|
||||
{ \
|
||||
g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_APP_##ucprop##_FLAGS, NM_SETTING_DCB_FLAG_NONE, NULL); \
|
||||
\
|
||||
g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_APP_##ucprop##_PRIORITY, v, NULL); \
|
||||
g_assert_cmpint (nm_setting_dcb_get_app_##lcprop##_priority (s_dcb), ==, v); \
|
||||
\
|
||||
/* Assert that the setting is invalid while the app is disabled unless v is default */ \
|
||||
success = nm_setting_verify (NM_SETTING (s_dcb), NULL, &error); \
|
||||
if (v >= 0) { \
|
||||
g_assert_error (error, NM_SETTING_DCB_ERROR, NM_SETTING_DCB_ERROR_INVALID_PROPERTY); \
|
||||
g_assert (success == FALSE); \
|
||||
} else { \
|
||||
g_assert_no_error (error); \
|
||||
g_assert (success); \
|
||||
} \
|
||||
g_clear_error (&error); \
|
||||
\
|
||||
/* Set the enable flag and re-verify, this time it should be valid */ \
|
||||
g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_APP_##ucprop##_FLAGS, NM_SETTING_DCB_FLAG_ENABLE, NULL); \
|
||||
success = nm_setting_verify (NM_SETTING (s_dcb), NULL, &error); \
|
||||
g_assert_no_error (error); \
|
||||
g_assert (success); \
|
||||
\
|
||||
g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_APP_##ucprop##_PRIORITY, 0, NULL); \
|
||||
}
|
||||
|
||||
static void
|
||||
test_dcb_app_priorities (void)
|
||||
{
|
||||
NMSettingDcb *s_dcb;
|
||||
GError *error = NULL;
|
||||
gboolean success;
|
||||
|
||||
s_dcb = (NMSettingDcb *) nm_setting_dcb_new ();
|
||||
g_assert (s_dcb);
|
||||
|
||||
/* Defaults */
|
||||
g_assert_cmpint (nm_setting_dcb_get_app_fcoe_priority (s_dcb), ==, -1);
|
||||
g_assert_cmpint (nm_setting_dcb_get_app_iscsi_priority (s_dcb), ==, -1);
|
||||
g_assert_cmpint (nm_setting_dcb_get_app_fip_priority (s_dcb), ==, -1);
|
||||
|
||||
TEST_APP_PRIORITY (fcoe, FCOE, 6);
|
||||
TEST_APP_PRIORITY (iscsi, ISCSI, 5);
|
||||
TEST_APP_PRIORITY (fip, FIP, 4);
|
||||
|
||||
TEST_APP_PRIORITY (fcoe, FCOE, -1);
|
||||
TEST_APP_PRIORITY (iscsi, ISCSI, -1);
|
||||
TEST_APP_PRIORITY (fip, FIP, -1);
|
||||
}
|
||||
|
||||
#define TEST_PRIORITY_VALID(fn, id, val, flagsprop, verify) \
|
||||
{ \
|
||||
/* Assert that setting the value gets the same value back out */ \
|
||||
nm_setting_dcb_set_priority_##fn (s_dcb, id, val); \
|
||||
g_assert_cmpint (nm_setting_dcb_get_priority_##fn (s_dcb, id), ==, val); \
|
||||
\
|
||||
if (verify) { \
|
||||
if (val != 0) { \
|
||||
/* Assert that verify fails because the flags do not include 'enabled' \
|
||||
* and a value has been set. \
|
||||
*/ \
|
||||
success = nm_setting_verify (NM_SETTING (s_dcb), NULL, &error); \
|
||||
g_assert_error (error, NM_SETTING_DCB_ERROR, NM_SETTING_DCB_ERROR_INVALID_PROPERTY); \
|
||||
g_assert (success == FALSE); \
|
||||
g_clear_error (&error); \
|
||||
} \
|
||||
\
|
||||
/* Assert that adding the 'enabled' flag verifies the setting */ \
|
||||
g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_PRIORITY_##flagsprop##_FLAGS, NM_SETTING_DCB_FLAG_ENABLE, NULL); \
|
||||
success = nm_setting_verify (NM_SETTING (s_dcb), NULL, &error); \
|
||||
g_assert_no_error (error); \
|
||||
g_assert (success); \
|
||||
} \
|
||||
\
|
||||
/* Reset everything */ \
|
||||
g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_PRIORITY_##flagsprop##_FLAGS, NM_SETTING_DCB_FLAG_NONE, NULL); \
|
||||
nm_setting_dcb_set_priority_##fn (s_dcb, id, 0); \
|
||||
}
|
||||
|
||||
/* If Priority Groups are enabled, PG bandwidth must equal 100% */
|
||||
#define SET_VALID_PRIORITY_GROUP_BANDWIDTH \
|
||||
{ \
|
||||
guint x; \
|
||||
for (x = 0; x < 7; x++) \
|
||||
nm_setting_dcb_set_priority_group_bandwidth (s_dcb, x, 12); \
|
||||
nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 7, 16); \
|
||||
}
|
||||
|
||||
static void
|
||||
test_dcb_priorities_valid (void)
|
||||
{
|
||||
NMSettingDcb *s_dcb;
|
||||
GError *error = NULL;
|
||||
gboolean success;
|
||||
guint i;
|
||||
|
||||
s_dcb = (NMSettingDcb *) nm_setting_dcb_new ();
|
||||
g_assert (s_dcb);
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
TEST_PRIORITY_VALID (flow_control, i, TRUE, FLOW_CONTROL, TRUE);
|
||||
|
||||
SET_VALID_PRIORITY_GROUP_BANDWIDTH
|
||||
for (i = 0; i < 8; i++) {
|
||||
TEST_PRIORITY_VALID (group_id, i, i, GROUP, TRUE);
|
||||
TEST_PRIORITY_VALID (group_id, i, 7 - i, GROUP, TRUE);
|
||||
}
|
||||
|
||||
/* Clear PG bandwidth from earlier tests */
|
||||
for (i = 0; i < 8; i++)
|
||||
nm_setting_dcb_set_priority_group_bandwidth (s_dcb, i, 0);
|
||||
|
||||
/* Priority Group Bandwidth must add up to 100% if enabled, which requires
|
||||
* some dancing for verifying individual values here.
|
||||
*/
|
||||
for (i = 0; i < 8; i++) {
|
||||
guint other = 7 - (i % 8);
|
||||
|
||||
/* Set another priority group to the remaining bandwidth */
|
||||
nm_setting_dcb_set_priority_group_bandwidth (s_dcb, other, 100 - i);
|
||||
TEST_PRIORITY_VALID (group_bandwidth, i, i, GROUP, TRUE);
|
||||
|
||||
/* Set another priority group to the remaining bandwidth */
|
||||
nm_setting_dcb_set_priority_group_bandwidth (s_dcb, other, 100 - (7 - i));
|
||||
TEST_PRIORITY_VALID (group_bandwidth, i, 7 - i, GROUP, TRUE);
|
||||
|
||||
/* Clear remaining bandwidth */
|
||||
nm_setting_dcb_set_priority_group_bandwidth (s_dcb, other, 0);
|
||||
}
|
||||
|
||||
SET_VALID_PRIORITY_GROUP_BANDWIDTH
|
||||
for (i = 0; i < 8; i++) {
|
||||
TEST_PRIORITY_VALID (bandwidth, i, i, GROUP, TRUE);
|
||||
TEST_PRIORITY_VALID (bandwidth, i, 7 - i, GROUP, TRUE);
|
||||
}
|
||||
|
||||
SET_VALID_PRIORITY_GROUP_BANDWIDTH
|
||||
for (i = 0; i < 8; i++)
|
||||
TEST_PRIORITY_VALID (strict_bandwidth, i, TRUE, GROUP, TRUE);
|
||||
|
||||
SET_VALID_PRIORITY_GROUP_BANDWIDTH
|
||||
for (i = 0; i < 8; i++) {
|
||||
TEST_PRIORITY_VALID (traffic_class, i, i, GROUP, TRUE);
|
||||
TEST_PRIORITY_VALID (traffic_class, i, 7 - i, GROUP, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_dcb_bandwidth_sums (void)
|
||||
{
|
||||
NMSettingDcb *s_dcb;
|
||||
GError *error = NULL;
|
||||
gboolean success;
|
||||
|
||||
s_dcb = (NMSettingDcb *) nm_setting_dcb_new ();
|
||||
g_assert (s_dcb);
|
||||
|
||||
/* Assert that setting the value gets the same value back out */
|
||||
nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 0, 9);
|
||||
nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 1, 10);
|
||||
nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 2, 11);
|
||||
nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 3, 12);
|
||||
nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 4, 13);
|
||||
nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 5, 14);
|
||||
nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 6, 15);
|
||||
nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 7, 16);
|
||||
|
||||
/* Assert verify success when sums total 100% */
|
||||
g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_PRIORITY_GROUP_FLAGS, NM_SETTING_DCB_FLAG_ENABLE, NULL);
|
||||
success = nm_setting_verify (NM_SETTING (s_dcb), NULL, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (success);
|
||||
|
||||
/* Assert verify fails when sums do not total 100% */
|
||||
nm_setting_dcb_set_priority_group_bandwidth (s_dcb, 4, 20);
|
||||
success = nm_setting_verify (NM_SETTING (s_dcb), NULL, &error);
|
||||
g_assert_error (error, NM_SETTING_DCB_ERROR, NM_SETTING_DCB_ERROR_INVALID_PROPERTY);
|
||||
g_assert (success == FALSE);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
#define TPATH "/libnm-util/settings/dcb/"
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
GError *error = NULL;
|
||||
gboolean success;
|
||||
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
g_type_init ();
|
||||
|
||||
success = nm_utils_init (&error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (success);
|
||||
|
||||
g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL);
|
||||
|
||||
g_test_add_func (TPATH "flags-valid", test_dcb_flags_valid);
|
||||
g_test_add_func (TPATH "flags-invalid", test_dcb_flags_invalid);
|
||||
g_test_add_func (TPATH "app-priorities", test_dcb_app_priorities);
|
||||
g_test_add_func (TPATH "priorities", test_dcb_priorities_valid);
|
||||
g_test_add_func (TPATH "bandwidth-sums", test_dcb_bandwidth_sums);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
||||
|
|
@ -286,7 +286,8 @@ unmanaged-devices=mac:00:22:68:1c:59:b1;mac:00:1E:65:30:D1:C4;interface-name:eth
|
|||
HW, RFKILL, ETHER, WIFI, BT, MB, DHCP4, DHCP6, PPP,
|
||||
WIFI_SCAN, IP4, IP6, AUTOIP4, DNS, VPN, SHARING, SUPPLICANT,
|
||||
AGENTS, SETTINGS, SUSPEND, CORE, DEVICE, OLPC, WIMAX,
|
||||
INFINIBAND, FIREWALL, ADSL, BOND, VLAN, BRIDGE.</para>
|
||||
INFINIBAND, FIREWALL, ADSL, BOND, VLAN, BRIDGE, DBUS_PROPS,
|
||||
TEAM, CONCHECK, DCB.</para>
|
||||
<para>In addition, these special domains can be used: NONE,
|
||||
ALL, DEFAULT, DHCP, IP.</para></listitem>
|
||||
</varlistentry>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ libnm-util/nm-setting-bridge-port.c
|
|||
libnm-util/nm-setting-bridge.c
|
||||
libnm-util/nm-setting-cdma.c
|
||||
libnm-util/nm-setting-connection.c
|
||||
libnm-util/nm-setting-dcb.c
|
||||
libnm-util/nm-setting-gsm.c
|
||||
libnm-util/nm-setting-infiniband.c
|
||||
libnm-util/nm-setting-ip4-config.c
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@
|
|||
#include "nm-enum-types.h"
|
||||
#include "nm-dbus-manager.h"
|
||||
#include "nm-platform.h"
|
||||
#include "nm-dcb.h"
|
||||
|
||||
#include "nm-device-ethernet-glue.h"
|
||||
|
||||
|
|
@ -1045,9 +1046,24 @@ act_stage2_config (NMDevice *device, NMDeviceStateReason *reason)
|
|||
NMSettingConnection *s_con;
|
||||
const char *connection_type;
|
||||
NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
NMSettingDcb *s_dcb;
|
||||
GError *error = NULL;
|
||||
|
||||
g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE);
|
||||
|
||||
/* DCB and FCoE setup */
|
||||
s_dcb = (NMSettingDcb *) device_get_setting (device, NM_TYPE_SETTING_DCB);
|
||||
if (s_dcb) {
|
||||
if (!nm_dcb_setup (nm_device_get_iface (device), s_dcb, &error)) {
|
||||
nm_log_warn (LOGD_DEVICE | LOGD_HW,
|
||||
"Activation (%s/wired) failed to enable DCB/FCoE: %s",
|
||||
nm_device_get_iface (device), error->message);
|
||||
g_clear_error (&error);
|
||||
*reason = NM_DEVICE_STATE_REASON_DCB_FCOE_FAILED;
|
||||
return NM_ACT_STAGE_RETURN_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
s_con = NM_SETTING_CONNECTION (device_get_setting (device, NM_TYPE_SETTING_CONNECTION));
|
||||
g_assert (s_con);
|
||||
|
||||
|
|
@ -1113,6 +1129,8 @@ deactivate (NMDevice *device)
|
|||
{
|
||||
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device);
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
NMSettingDcb *s_dcb;
|
||||
GError *error = NULL;
|
||||
|
||||
/* Clear wired secrets tries when deactivating */
|
||||
clear_secrets_tries (device);
|
||||
|
|
@ -1129,6 +1147,17 @@ deactivate (NMDevice *device)
|
|||
|
||||
supplicant_interface_release (self);
|
||||
|
||||
/* Tear down DCB/FCoE if it was enabled */
|
||||
s_dcb = (NMSettingDcb *) device_get_setting (device, NM_TYPE_SETTING_DCB);
|
||||
if (s_dcb) {
|
||||
if (!nm_dcb_cleanup (nm_device_get_iface (device), &error)) {
|
||||
nm_log_warn (LOGD_DEVICE | LOGD_HW,
|
||||
"(%s) failed to disable DCB/FCoE: %s",
|
||||
nm_device_get_iface (device), error->message);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset MAC address back to initial address */
|
||||
nm_device_set_hw_addr (device, priv->initial_hw_addr, "reset", LOGD_ETHER);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,8 @@ nm_log_handler (const gchar *log_domain,
|
|||
LOGD_SUPPLICANT | LOGD_AGENTS | LOGD_SETTINGS | LOGD_SUSPEND | \
|
||||
LOGD_CORE | LOGD_DEVICE | LOGD_OLPC_MESH | LOGD_WIMAX | \
|
||||
LOGD_INFINIBAND | LOGD_FIREWALL | LOGD_ADSL | LOGD_BOND | \
|
||||
LOGD_VLAN | LOGD_BRIDGE | LOGD_DBUS_PROPS | LOGD_TEAM | LOGD_CONCHECK)
|
||||
LOGD_VLAN | LOGD_BRIDGE | LOGD_DBUS_PROPS | LOGD_TEAM | LOGD_CONCHECK | \
|
||||
LOGD_DCB)
|
||||
|
||||
#define LOGD_DEFAULT (LOGD_ALL & ~(LOGD_WIFI_SCAN | LOGD_DBUS_PROPS))
|
||||
|
||||
|
|
@ -105,6 +106,7 @@ static const LogDesc domain_descs[] = {
|
|||
{ LOGD_DBUS_PROPS,"DBUS_PROPS" },
|
||||
{ LOGD_TEAM, "TEAM" },
|
||||
{ LOGD_CONCHECK, "CONCHECK" },
|
||||
{ LOGD_DCB, "DCB" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ enum {
|
|||
LOGD_DBUS_PROPS = (1LL << 31),
|
||||
LOGD_TEAM = (1LL << 32),
|
||||
LOGD_CONCHECK = (1LL << 33),
|
||||
LOGD_DCB = (1LL << 34), /* Data Center Bridging */
|
||||
};
|
||||
|
||||
#define LOGD_DHCP (LOGD_DHCP4 | LOGD_DHCP6)
|
||||
|
|
|
|||
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 */
|
||||
|
|
@ -48,6 +48,7 @@
|
|||
#include <nm-setting-team-port.h>
|
||||
#include <nm-setting-bridge.h>
|
||||
#include <nm-setting-bridge-port.h>
|
||||
#include <nm-setting-dcb.h>
|
||||
#include <nm-utils.h>
|
||||
|
||||
#include "wifi-utils.h"
|
||||
|
|
@ -74,7 +75,7 @@ get_int (const char *str, int *value)
|
|||
|
||||
errno = 0;
|
||||
tmp = strtol (str, &e, 0);
|
||||
if (errno || *e != '\0')
|
||||
if (errno || *e != '\0' || tmp > G_MAXINT || tmp < G_MININT)
|
||||
return FALSE;
|
||||
*value = (int) tmp;
|
||||
return TRUE;
|
||||
|
|
@ -1772,6 +1773,397 @@ check_if_team_slave (shvarFile *ifcfg,
|
|||
g_free (value);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
const char *enable_key;
|
||||
const char *advertise_key;
|
||||
const char *willing_key;
|
||||
const char *flags_prop;
|
||||
} DcbFlagsProperty;
|
||||
|
||||
enum {
|
||||
DCB_APP_FCOE_FLAGS = 0,
|
||||
DCB_APP_ISCSI_FLAGS = 1,
|
||||
DCB_APP_FIP_FLAGS = 2,
|
||||
DCB_PFC_FLAGS = 3,
|
||||
DCB_PG_FLAGS = 4,
|
||||
};
|
||||
|
||||
static DcbFlagsProperty dcb_flags_props[] = {
|
||||
{ "DCB_APP_FCOE_ENABLE", "DCB_APP_FCOE_ADVERTISE", "DCB_APP_FCOE_WILLING", NM_SETTING_DCB_APP_FCOE_FLAGS },
|
||||
{ "DCB_APP_ISCSI_ENABLE", "DCB_APP_ISCSI_ADVERTISE", "DCB_APP_ISCSI_WILLING", NM_SETTING_DCB_APP_ISCSI_FLAGS },
|
||||
{ "DCB_APP_FIP_ENABLE", "DCB_APP_FIP_ADVERTISE", "DCB_APP_FIP_WILLING", NM_SETTING_DCB_APP_FIP_FLAGS },
|
||||
{ "DCB_PFC_ENABLE", "DCB_PFC_ADVERTISE", "DCB_PFC_WILLING", NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS },
|
||||
{ "DCB_PG_ENABLE", "DCB_PG_ADVERTISE", "DCB_PG_WILLING", NM_SETTING_DCB_PRIORITY_GROUP_FLAGS },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static NMSettingDcbFlags
|
||||
read_dcb_flags (shvarFile *ifcfg, DcbFlagsProperty *property)
|
||||
{
|
||||
NMSettingDcbFlags flags = NM_SETTING_DCB_FLAG_NONE;
|
||||
|
||||
if (svTrueValue (ifcfg, property->enable_key, FALSE))
|
||||
flags |= NM_SETTING_DCB_FLAG_ENABLE;
|
||||
if (svTrueValue (ifcfg, property->advertise_key, FALSE))
|
||||
flags |= NM_SETTING_DCB_FLAG_ADVERTISE;
|
||||
if (svTrueValue (ifcfg, property->willing_key, FALSE))
|
||||
flags |= NM_SETTING_DCB_FLAG_WILLING;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
read_dcb_app (shvarFile *ifcfg,
|
||||
NMSettingDcb *s_dcb,
|
||||
const char *app,
|
||||
DcbFlagsProperty *flags_prop,
|
||||
const char *priority_prop,
|
||||
GError **error)
|
||||
{
|
||||
NMSettingDcbFlags flags = NM_SETTING_DCB_FLAG_NONE;
|
||||
char *tmp, *val;
|
||||
gboolean success = TRUE;
|
||||
int priority = -1;
|
||||
|
||||
flags = read_dcb_flags (ifcfg, flags_prop);
|
||||
|
||||
/* Priority */
|
||||
tmp = g_strdup_printf ("DCB_APP_%s_PRIORITY", app);
|
||||
val = svGetValue (ifcfg, tmp, FALSE);
|
||||
if (val) {
|
||||
success = get_int (val, &priority);
|
||||
if (success)
|
||||
success = (priority >= 0 && priority <= 7);
|
||||
if (!success) {
|
||||
g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
|
||||
"Invalid %s value '%s' (expected 0 - 7)",
|
||||
tmp, val);
|
||||
}
|
||||
g_free (val);
|
||||
|
||||
if (!(flags & NM_SETTING_DCB_FLAG_ENABLE))
|
||||
PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: ignoring DCB %s priority; app not enabled", app);
|
||||
}
|
||||
g_free (tmp);
|
||||
|
||||
if (success) {
|
||||
g_object_set (G_OBJECT (s_dcb),
|
||||
flags_prop->flags_prop, flags,
|
||||
priority_prop, (guint) priority,
|
||||
NULL);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
typedef void (*DcbSetBoolFunc) (NMSettingDcb *, guint, gboolean);
|
||||
|
||||
static gboolean
|
||||
read_dcb_bool_array (shvarFile *ifcfg,
|
||||
NMSettingDcb *s_dcb,
|
||||
NMSettingDcbFlags flags,
|
||||
const char *prop,
|
||||
const char *desc,
|
||||
DcbSetBoolFunc set_func,
|
||||
GError **error)
|
||||
{
|
||||
char *val;
|
||||
gboolean success = FALSE;
|
||||
guint i;
|
||||
|
||||
val = svGetValue (ifcfg, prop, FALSE);
|
||||
if (!val)
|
||||
return TRUE;
|
||||
|
||||
if (!(flags & NM_SETTING_DCB_FLAG_ENABLE)) {
|
||||
PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: ignoring %s; %s is not enabled", prop, desc);
|
||||
success = TRUE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
val = g_strstrip (val);
|
||||
if (strlen (val) != 8) {
|
||||
PLUGIN_WARN (IFCFG_PLUGIN_NAME, " error: %s value '%s' must be 8 characters long", prop, val);
|
||||
g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, "boolean array must be 8 characters");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* All characters must be either 0 or 1 */
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (val[i] != '0' && val[i] != '1') {
|
||||
PLUGIN_WARN (IFCFG_PLUGIN_NAME, " error: invalid %s value '%s': not all 0s and 1s", prop, val);
|
||||
g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, "invalid boolean digit");
|
||||
goto out;
|
||||
}
|
||||
set_func (s_dcb, i, (val[i] == '1'));
|
||||
}
|
||||
success = TRUE;
|
||||
|
||||
out:
|
||||
g_free (val);
|
||||
return success;
|
||||
}
|
||||
|
||||
typedef void (*DcbSetUintFunc) (NMSettingDcb *, guint, guint);
|
||||
|
||||
static gboolean
|
||||
read_dcb_uint_array (shvarFile *ifcfg,
|
||||
NMSettingDcb *s_dcb,
|
||||
NMSettingDcbFlags flags,
|
||||
const char *prop,
|
||||
const char *desc,
|
||||
gboolean f_allowed,
|
||||
DcbSetUintFunc set_func,
|
||||
GError **error)
|
||||
{
|
||||
char *val;
|
||||
gboolean success = FALSE;
|
||||
guint i;
|
||||
|
||||
val = svGetValue (ifcfg, prop, FALSE);
|
||||
if (!val)
|
||||
return TRUE;
|
||||
|
||||
if (!(flags & NM_SETTING_DCB_FLAG_ENABLE)) {
|
||||
PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: ignoring %s; %s is not enabled", prop, desc);
|
||||
success = TRUE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
val = g_strstrip (val);
|
||||
if (strlen (val) != 8) {
|
||||
PLUGIN_WARN (IFCFG_PLUGIN_NAME, " error: %s value '%s' must be 8 characters long", prop, val);
|
||||
g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, "uint array must be 8 characters");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* All characters must be either 0 - 7 or (optionally) f */
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (val[i] >= '0' && val[i] <= '7')
|
||||
set_func (s_dcb, i, val[i] - '0');
|
||||
else if (f_allowed && (val[i] == 'f' || val[i] == 'F'))
|
||||
set_func (s_dcb, i, 15);
|
||||
else {
|
||||
PLUGIN_WARN (IFCFG_PLUGIN_NAME, " error: invalid %s value '%s': not 0 - 7%s",
|
||||
prop, val, f_allowed ? " or 'f'" : "");
|
||||
g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, "invalid uint digit");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
success = TRUE;
|
||||
|
||||
out:
|
||||
g_free (val);
|
||||
return success;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
read_dcb_percent_array (shvarFile *ifcfg,
|
||||
NMSettingDcb *s_dcb,
|
||||
NMSettingDcbFlags flags,
|
||||
const char *prop,
|
||||
const char *desc,
|
||||
gboolean sum_pct,
|
||||
DcbSetUintFunc set_func,
|
||||
GError **error)
|
||||
{
|
||||
char *val;
|
||||
gboolean success = FALSE;
|
||||
char **split = NULL, **iter;
|
||||
int tmp;
|
||||
guint i, sum = 0;
|
||||
|
||||
val = svGetValue (ifcfg, prop, FALSE);
|
||||
if (!val)
|
||||
return TRUE;
|
||||
|
||||
if (!(flags & NM_SETTING_DCB_FLAG_ENABLE)) {
|
||||
PLUGIN_WARN (IFCFG_PLUGIN_NAME, " warning: ignoring %s; %s is not enabled", prop, desc);
|
||||
success = TRUE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
val = g_strstrip (val);
|
||||
split = g_strsplit_set (val, ",", 0);
|
||||
if (!split || (g_strv_length (split) != 8)) {
|
||||
PLUGIN_WARN (IFCFG_PLUGIN_NAME, " error: invalid %s percentage list value '%s'", prop, val);
|
||||
g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, "percent array must be 8 elements");
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (iter = split, i = 0; iter && *iter; iter++, i++) {
|
||||
if (!get_int (*iter, &tmp) || tmp < 0 || tmp > 100) {
|
||||
PLUGIN_WARN (IFCFG_PLUGIN_NAME, " error: invalid %s percentage value '%s'", prop, *iter);
|
||||
g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, "invalid percent element");
|
||||
goto out;
|
||||
}
|
||||
set_func (s_dcb, i, (guint) tmp);
|
||||
sum += (guint) tmp;
|
||||
}
|
||||
|
||||
if (sum_pct && (sum != 100)) {
|
||||
PLUGIN_WARN (IFCFG_PLUGIN_NAME, " error: %s percentages do not equal 100%%", prop);
|
||||
g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, "invalid percentage sum");
|
||||
goto out;
|
||||
}
|
||||
|
||||
success = TRUE;
|
||||
|
||||
out:
|
||||
if (split)
|
||||
g_strfreev (split);
|
||||
g_free (val);
|
||||
return success;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
make_dcb_setting (shvarFile *ifcfg,
|
||||
const char *network_file,
|
||||
NMSetting **out_setting,
|
||||
GError **error)
|
||||
{
|
||||
NMSettingDcb *s_dcb = NULL;
|
||||
gboolean dcb_on;
|
||||
NMSettingDcbFlags flags = NM_SETTING_DCB_FLAG_NONE;
|
||||
char *val;
|
||||
|
||||
g_return_val_if_fail (out_setting != NULL, FALSE);
|
||||
|
||||
dcb_on = !!svTrueValue (ifcfg, "DCB", FALSE);
|
||||
if (!dcb_on)
|
||||
return TRUE;
|
||||
|
||||
s_dcb = (NMSettingDcb *) nm_setting_dcb_new ();
|
||||
g_assert (s_dcb);
|
||||
|
||||
/* FCOE */
|
||||
if (!read_dcb_app (ifcfg, s_dcb, "FCOE",
|
||||
&dcb_flags_props[DCB_APP_FCOE_FLAGS],
|
||||
NM_SETTING_DCB_APP_FCOE_PRIORITY,
|
||||
error)) {
|
||||
g_object_unref (s_dcb);
|
||||
return FALSE;
|
||||
}
|
||||
if (nm_setting_dcb_get_app_fcoe_flags (s_dcb) & NM_SETTING_DCB_FLAG_ENABLE) {
|
||||
val = svGetValue (ifcfg, "DCB_APP_FCOE_MODE", FALSE);
|
||||
if (val) {
|
||||
if (strcmp (val, NM_SETTING_DCB_FCOE_MODE_FABRIC) == 0 ||
|
||||
strcmp (val, NM_SETTING_DCB_FCOE_MODE_VN2VN) == 0)
|
||||
g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_APP_FCOE_MODE, val, NULL);
|
||||
else {
|
||||
PLUGIN_WARN (IFCFG_PLUGIN_NAME, " error: invalid FCoE mode '%s'", val);
|
||||
g_set_error_literal (error, IFCFG_PLUGIN_ERROR, 0, "invalid FCoE mode");
|
||||
g_free (val);
|
||||
g_object_unref (s_dcb);
|
||||
return FALSE;
|
||||
}
|
||||
g_free (val);
|
||||
}
|
||||
}
|
||||
|
||||
/* iSCSI */
|
||||
if (!read_dcb_app (ifcfg, s_dcb, "ISCSI",
|
||||
&dcb_flags_props[DCB_APP_ISCSI_FLAGS],
|
||||
NM_SETTING_DCB_APP_ISCSI_PRIORITY,
|
||||
error)) {
|
||||
g_object_unref (s_dcb);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* FIP */
|
||||
if (!read_dcb_app (ifcfg, s_dcb, "FIP",
|
||||
&dcb_flags_props[DCB_APP_FIP_FLAGS],
|
||||
NM_SETTING_DCB_APP_FIP_PRIORITY,
|
||||
error)) {
|
||||
g_object_unref (s_dcb);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Priority Flow Control */
|
||||
flags = read_dcb_flags (ifcfg, &dcb_flags_props[DCB_PFC_FLAGS]);
|
||||
g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS, flags, NULL);
|
||||
|
||||
if (!read_dcb_bool_array (ifcfg,
|
||||
s_dcb,
|
||||
flags,
|
||||
"DCB_PFC_UP",
|
||||
"PFC",
|
||||
nm_setting_dcb_set_priority_flow_control,
|
||||
error)) {
|
||||
g_object_unref (s_dcb);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Priority Groups */
|
||||
flags = read_dcb_flags (ifcfg, &dcb_flags_props[DCB_PG_FLAGS]);
|
||||
g_object_set (G_OBJECT (s_dcb), NM_SETTING_DCB_PRIORITY_GROUP_FLAGS, flags, NULL);
|
||||
|
||||
if (!read_dcb_uint_array (ifcfg,
|
||||
s_dcb,
|
||||
flags,
|
||||
"DCB_PG_ID",
|
||||
"PGID",
|
||||
TRUE,
|
||||
nm_setting_dcb_set_priority_group_id,
|
||||
error)) {
|
||||
g_object_unref (s_dcb);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Group bandwidth */
|
||||
if (!read_dcb_percent_array (ifcfg,
|
||||
s_dcb,
|
||||
flags,
|
||||
"DCB_PG_PCT",
|
||||
"PGPCT",
|
||||
TRUE,
|
||||
nm_setting_dcb_set_priority_group_bandwidth,
|
||||
error)) {
|
||||
g_object_unref (s_dcb);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Priority bandwidth */
|
||||
if (!read_dcb_percent_array (ifcfg,
|
||||
s_dcb,
|
||||
flags,
|
||||
"DCB_PG_UPPCT",
|
||||
"UPPCT",
|
||||
FALSE,
|
||||
nm_setting_dcb_set_priority_bandwidth,
|
||||
error)) {
|
||||
g_object_unref (s_dcb);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Strict Bandwidth */
|
||||
if (!read_dcb_bool_array (ifcfg,
|
||||
s_dcb,
|
||||
flags,
|
||||
"DCB_PG_STRICT",
|
||||
"STRICT",
|
||||
nm_setting_dcb_set_priority_strict_bandwidth,
|
||||
error)) {
|
||||
g_object_unref (s_dcb);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!read_dcb_uint_array (ifcfg,
|
||||
s_dcb,
|
||||
flags,
|
||||
"DCB_PG_UP2TC",
|
||||
"UP2TC",
|
||||
FALSE,
|
||||
nm_setting_dcb_set_priority_traffic_class,
|
||||
error)) {
|
||||
g_object_unref (s_dcb);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*out_setting = NM_SETTING (s_dcb);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
add_one_wep_key (shvarFile *ifcfg,
|
||||
const char *shvar_key,
|
||||
|
|
@ -4505,7 +4897,7 @@ connection_from_file (const char *filename,
|
|||
NMConnection *connection = NULL;
|
||||
shvarFile *parsed;
|
||||
char *type, *devtype, *nmc = NULL, *bootproto;
|
||||
NMSetting *s_ip4, *s_ip6, *s_port;
|
||||
NMSetting *s_ip4, *s_ip6, *s_port, *s_dcb = NULL;
|
||||
const char *ifcfg_name = NULL;
|
||||
gboolean nm_controlled = TRUE;
|
||||
char *unmanaged = NULL;
|
||||
|
|
@ -4678,6 +5070,14 @@ connection_from_file (const char *filename,
|
|||
if (s_port)
|
||||
nm_connection_add_setting (connection, s_port);
|
||||
|
||||
if (!make_dcb_setting (parsed, network_file, &s_dcb, error)) {
|
||||
g_object_unref (connection);
|
||||
connection = NULL;
|
||||
goto done;
|
||||
}
|
||||
if (s_dcb)
|
||||
nm_connection_add_setting (connection, s_dcb);
|
||||
|
||||
/* iSCSI / ibft connections are read-only since their settings are
|
||||
* stored in NVRAM and can only be changed in BIOS.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -96,7 +96,18 @@ EXTRA_DIST = \
|
|||
ifcfg-test-infiniband \
|
||||
ifcfg-test-bond-main \
|
||||
ifcfg-test-bond-slave \
|
||||
ifcfg-test-bond-slave-ib
|
||||
ifcfg-test-bond-slave-ib \
|
||||
ifcfg-test-dcb \
|
||||
ifcfg-test-dcb-default-app-priorities \
|
||||
ifcfg-test-dcb-bad-booleans \
|
||||
ifcfg-test-dcb-short-booleans \
|
||||
ifcfg-test-dcb-bad-uints \
|
||||
ifcfg-test-dcb-short-uints \
|
||||
ifcfg-test-dcb-bad-percent \
|
||||
ifcfg-test-dcb-short-percent \
|
||||
ifcfg-test-dcb-pgpct-not-100 \
|
||||
ifcfg-test-fcoe-fabric \
|
||||
ifcfg-test-fcoe-vn2vn
|
||||
|
||||
check-local:
|
||||
@for f in $(EXTRA_DIST); do \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
TYPE=Ethernet
|
||||
DEVICE=eth0
|
||||
HWADDR=00:11:22:33:44:ee
|
||||
BOOTPROTO=none
|
||||
IPADDR=1.2.3.4
|
||||
PREFIX=24
|
||||
GATEWAY=1.1.1.1
|
||||
|
||||
# dcb global switch
|
||||
# use DCB=no to turn it off
|
||||
DCB=yes
|
||||
|
||||
# application settings
|
||||
DCB_APP_FCOE_PRIORITY=7
|
||||
DCB_APP_FCOE_ENABLE=yes
|
||||
DCB_APP_FCOE_ADVERTISE=yes
|
||||
DCB_APP_FCOE_WILLING=yes
|
||||
|
||||
DCB_APP_ISCSI_PRIORITY=6
|
||||
DCB_APP_ISCSI_ENABLE=yes
|
||||
DCB_APP_ISCSI_ADVERTISE=yes
|
||||
DCB_APP_ISCSI_WILLING=yes
|
||||
|
||||
DCB_APP_FIP_PRIORITY=2
|
||||
DCB_APP_FIP_ENABLE=yes
|
||||
DCB_APP_FIP_ADVERTISE=yes
|
||||
DCB_APP_FIP_WILLING=yes
|
||||
|
||||
# priority group settings
|
||||
DCB_PG_UP2TC=76543210
|
||||
DCB_PG_PCT=25,0,0,75,0,0,0,0
|
||||
DCB_PG_ID=0000111f
|
||||
DCB_PG_UPPCT=5,10,30,25,10,50,5,0
|
||||
DCB_PG_STRICT=00110101
|
||||
DCB_PG_ENABLE=yes
|
||||
DCB_PG_ADVERTISE=yes
|
||||
DCB_PG_WILLING=yes
|
||||
|
||||
# priority flow control settings
|
||||
DCB_PFC_UP=10011010
|
||||
DCB_PFC_ENABLE=yes
|
||||
DCB_PFC_ADVERTISE=yes
|
||||
DCB_PFC_WILLING=no
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
TYPE=Ethernet
|
||||
DEVICE=eth0
|
||||
HWADDR=00:11:22:33:44:ee
|
||||
BOOTPROTO=none
|
||||
IPADDR=1.2.3.4
|
||||
PREFIX=24
|
||||
GATEWAY=1.1.1.1
|
||||
|
||||
DCB=yes
|
||||
DCB_PG_STRICT=02030101
|
||||
DCB_PG_ENABLE=yes
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
TYPE=Ethernet
|
||||
DEVICE=eth0
|
||||
HWADDR=00:11:22:33:44:ee
|
||||
BOOTPROTO=none
|
||||
IPADDR=1.2.3.4
|
||||
PREFIX=24
|
||||
GATEWAY=1.1.1.1
|
||||
|
||||
DCB=yes
|
||||
DCB_PG_PCT=25,0,0,75,0,0,110,0
|
||||
DCB_PG_ENABLE=yes
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
TYPE=Ethernet
|
||||
DEVICE=eth0
|
||||
HWADDR=00:11:22:33:44:ee
|
||||
BOOTPROTO=none
|
||||
IPADDR=1.2.3.4
|
||||
PREFIX=24
|
||||
GATEWAY=1.1.1.1
|
||||
|
||||
DCB=yes
|
||||
DCB_PG_UP2TC=96543210
|
||||
DCB_PG_ENABLE=yes
|
||||
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
TYPE=Ethernet
|
||||
DEVICE=eth0
|
||||
DCB=yes
|
||||
DCB_APP_FCOE_ENABLE=yes
|
||||
DCB_APP_ISCSI_ENABLE=yes
|
||||
DCB_APP_FIP_ENABLE=yes
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
TYPE=Ethernet
|
||||
DEVICE=eth0
|
||||
HWADDR=00:11:22:33:44:ee
|
||||
BOOTPROTO=none
|
||||
IPADDR=1.2.3.4
|
||||
PREFIX=24
|
||||
GATEWAY=1.1.1.1
|
||||
|
||||
DCB=yes
|
||||
DCB_PG_PCT=25,0,0,3,75,0,25,0
|
||||
DCB_PG_ENABLE=yes
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
TYPE=Ethernet
|
||||
DEVICE=eth0
|
||||
HWADDR=00:11:22:33:44:ee
|
||||
BOOTPROTO=none
|
||||
IPADDR=1.2.3.4
|
||||
PREFIX=24
|
||||
GATEWAY=1.1.1.1
|
||||
|
||||
DCB=yes
|
||||
DCB_PG_STRICT=0111010
|
||||
DCB_PG_ENABLE=yes
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
TYPE=Ethernet
|
||||
DEVICE=eth0
|
||||
HWADDR=00:11:22:33:44:ee
|
||||
BOOTPROTO=none
|
||||
IPADDR=1.2.3.4
|
||||
PREFIX=24
|
||||
GATEWAY=1.1.1.1
|
||||
|
||||
DCB=yes
|
||||
DCB_PG_PCT=25,0,0,75,0,0,0
|
||||
DCB_PG_ENABLE=yes
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
TYPE=Ethernet
|
||||
DEVICE=eth0
|
||||
HWADDR=00:11:22:33:44:ee
|
||||
BOOTPROTO=none
|
||||
IPADDR=1.2.3.4
|
||||
PREFIX=24
|
||||
GATEWAY=1.1.1.1
|
||||
|
||||
DCB=yes
|
||||
DCB_PG_UP2TC=7654321
|
||||
DCB_PG_ENABLE=yes
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
TYPE=Ethernet
|
||||
DEVICE=eth0
|
||||
DCB=yes
|
||||
DCB_APP_FCOE_ENABLE=yes
|
||||
DCB_APP_FCOE_MODE=fabric
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
TYPE=Ethernet
|
||||
DEVICE=eth0
|
||||
DCB=yes
|
||||
DCB_APP_FCOE_ENABLE=yes
|
||||
DCB_APP_FCOE_MODE=vn2vn
|
||||
|
||||
|
|
@ -45,6 +45,7 @@
|
|||
#include <nm-setting-cdma.h>
|
||||
#include <nm-setting-serial.h>
|
||||
#include <nm-setting-vlan.h>
|
||||
#include <nm-setting-dcb.h>
|
||||
|
||||
#include "nm-test-helpers.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
|
|
@ -12712,6 +12713,416 @@ test_write_bond_slave_ib (void)
|
|||
g_object_unref (reread);
|
||||
}
|
||||
|
||||
#define DCB_ALL_FLAGS (NM_SETTING_DCB_FLAG_ENABLE | \
|
||||
NM_SETTING_DCB_FLAG_ADVERTISE | \
|
||||
NM_SETTING_DCB_FLAG_WILLING)
|
||||
|
||||
static void
|
||||
test_read_dcb_basic (void)
|
||||
{
|
||||
NMConnection *connection;
|
||||
GError *error = NULL;
|
||||
NMSettingDcb *s_dcb;
|
||||
gboolean success;
|
||||
guint i;
|
||||
guint expected_group_ids[8] = { 0, 0, 0, 0, 1, 1, 1, 0xF };
|
||||
guint expected_group_bandwidths[8] = { 25, 0, 0, 75, 0, 0, 0, 0 };
|
||||
guint expected_bandwidths[8] = { 5, 10, 30, 25, 10, 50, 5, 0 };
|
||||
gboolean expected_strict[8] = { FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE, TRUE };
|
||||
guint expected_traffic_classes[8] = { 7, 6, 5, 4, 3, 2, 1, 0 };
|
||||
gboolean expected_pfcs[8] = { TRUE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, FALSE };
|
||||
|
||||
connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb",
|
||||
NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, NULL, &error, NULL);
|
||||
g_assert_no_error (error);
|
||||
g_assert (connection);
|
||||
success = nm_connection_verify (connection, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (success);
|
||||
|
||||
s_dcb = nm_connection_get_setting_dcb (connection);
|
||||
g_assert (s_dcb);
|
||||
|
||||
g_assert_cmpint (nm_setting_dcb_get_app_fcoe_flags (s_dcb), ==, DCB_ALL_FLAGS);
|
||||
g_assert_cmpint (nm_setting_dcb_get_app_fcoe_priority (s_dcb), ==, 7);
|
||||
|
||||
g_assert_cmpint (nm_setting_dcb_get_app_iscsi_flags (s_dcb), ==, DCB_ALL_FLAGS);
|
||||
g_assert_cmpint (nm_setting_dcb_get_app_iscsi_priority (s_dcb), ==, 6);
|
||||
|
||||
g_assert_cmpint (nm_setting_dcb_get_app_fip_flags (s_dcb), ==, DCB_ALL_FLAGS);
|
||||
g_assert_cmpint (nm_setting_dcb_get_app_fip_priority (s_dcb), ==, 2);
|
||||
|
||||
g_assert_cmpint (nm_setting_dcb_get_priority_flow_control_flags (s_dcb), ==, (NM_SETTING_DCB_FLAG_ENABLE | NM_SETTING_DCB_FLAG_ADVERTISE));
|
||||
for (i = 0; i < 8; i++)
|
||||
g_assert_cmpint (nm_setting_dcb_get_priority_flow_control (s_dcb, i), ==, expected_pfcs[i]);
|
||||
|
||||
g_assert_cmpint (nm_setting_dcb_get_priority_group_flags (s_dcb), ==, DCB_ALL_FLAGS);
|
||||
|
||||
/* Group IDs */
|
||||
for (i = 0; i < 8; i++)
|
||||
g_assert_cmpint (nm_setting_dcb_get_priority_group_id (s_dcb, i), ==, expected_group_ids[i]);
|
||||
|
||||
/* Group bandwidth */
|
||||
for (i = 0; i < 8; i++)
|
||||
g_assert_cmpint (nm_setting_dcb_get_priority_group_bandwidth (s_dcb, i), ==, expected_group_bandwidths[i]);
|
||||
|
||||
/* User priority bandwidth */
|
||||
for (i = 0; i < 8; i++)
|
||||
g_assert_cmpint (nm_setting_dcb_get_priority_bandwidth (s_dcb, i), ==, expected_bandwidths[i]);
|
||||
|
||||
/* Strict bandwidth */
|
||||
for (i = 0; i < 8; i++)
|
||||
g_assert_cmpint (nm_setting_dcb_get_priority_strict_bandwidth (s_dcb, i), ==, expected_strict[i]);
|
||||
|
||||
/* Traffic class */
|
||||
for (i = 0; i < 8; i++)
|
||||
g_assert_cmpint (nm_setting_dcb_get_priority_traffic_class (s_dcb, i), ==, expected_traffic_classes[i]);
|
||||
|
||||
g_object_unref (connection);
|
||||
}
|
||||
|
||||
static void
|
||||
test_write_dcb_basic (void)
|
||||
{
|
||||
NMConnection *connection, *reread;
|
||||
GError *error = NULL;
|
||||
NMSettingConnection *s_con;
|
||||
NMSettingWired *s_wired;
|
||||
NMSettingDcb *s_dcb;
|
||||
NMSettingIP4Config *s_ip4;
|
||||
NMSettingIP6Config *s_ip6;
|
||||
gboolean success, ignore_error;
|
||||
guint i;
|
||||
char *uuid, *testfile;
|
||||
const guint group_ids[8] = { 4, 0xF, 6, 0xF, 1, 7, 3, 0xF };
|
||||
const guint group_bandwidths[8] = { 10, 20, 15, 10, 2, 3, 35, 5 };
|
||||
const guint bandwidths[8] = { 10, 20, 30, 40, 50, 10, 0, 25 };
|
||||
const gboolean strict[8] = { TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE };
|
||||
const guint traffic_classes[8] = { 3, 4, 7, 2, 1, 0, 5, 6 };
|
||||
const gboolean pfcs[8] = { TRUE, TRUE, FALSE, TRUE, FALSE, TRUE, TRUE, FALSE };
|
||||
|
||||
connection = nm_connection_new ();
|
||||
|
||||
s_con = (NMSettingConnection *) nm_setting_connection_new ();
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_con));
|
||||
uuid = nm_utils_uuid_generate ();
|
||||
g_object_set (G_OBJECT (s_con),
|
||||
NM_SETTING_CONNECTION_ID, "dcb-test",
|
||||
NM_SETTING_CONNECTION_UUID, uuid,
|
||||
NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
|
||||
NM_SETTING_CONNECTION_INTERFACE_NAME, "eth0",
|
||||
NULL);
|
||||
g_free (uuid);
|
||||
|
||||
/* Wired setting */
|
||||
s_wired = (NMSettingWired *) nm_setting_wired_new ();
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_wired));
|
||||
|
||||
/* IP stuff */
|
||||
s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
|
||||
g_object_set (G_OBJECT (s_ip4), NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_ip4));
|
||||
|
||||
s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
|
||||
g_object_set (G_OBJECT (s_ip6), NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL);
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_ip6));
|
||||
|
||||
/* DCB */
|
||||
s_dcb = (NMSettingDcb *) nm_setting_dcb_new ();
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_dcb));
|
||||
|
||||
g_object_set (G_OBJECT (s_dcb),
|
||||
NM_SETTING_DCB_APP_FCOE_FLAGS, DCB_ALL_FLAGS,
|
||||
NM_SETTING_DCB_APP_FCOE_PRIORITY, 5,
|
||||
NM_SETTING_DCB_APP_ISCSI_FLAGS, DCB_ALL_FLAGS,
|
||||
NM_SETTING_DCB_APP_ISCSI_PRIORITY, 1,
|
||||
NM_SETTING_DCB_APP_FIP_FLAGS, DCB_ALL_FLAGS,
|
||||
NM_SETTING_DCB_APP_FIP_PRIORITY, 3,
|
||||
NM_SETTING_DCB_PRIORITY_FLOW_CONTROL_FLAGS, DCB_ALL_FLAGS,
|
||||
NM_SETTING_DCB_PRIORITY_GROUP_FLAGS, DCB_ALL_FLAGS,
|
||||
NULL);
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
nm_setting_dcb_set_priority_flow_control (s_dcb, i, pfcs[i]);
|
||||
nm_setting_dcb_set_priority_group_id (s_dcb, i, group_ids[i]);
|
||||
nm_setting_dcb_set_priority_group_bandwidth (s_dcb, i, group_bandwidths[i]);
|
||||
nm_setting_dcb_set_priority_bandwidth (s_dcb, i, bandwidths[i]);
|
||||
nm_setting_dcb_set_priority_strict_bandwidth (s_dcb, i, strict[i]);
|
||||
nm_setting_dcb_set_priority_traffic_class (s_dcb, i, traffic_classes[i]);
|
||||
}
|
||||
|
||||
g_assert (nm_connection_verify (connection, &error));
|
||||
|
||||
/* Save the ifcfg */
|
||||
success = writer_new_connection (connection,
|
||||
TEST_SCRATCH_DIR "/network-scripts/",
|
||||
&testfile,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (success);
|
||||
g_assert (testfile);
|
||||
|
||||
/* re-read the connection for comparison */
|
||||
reread = connection_from_file (testfile,
|
||||
NULL,
|
||||
TYPE_ETHERNET,
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
&error,
|
||||
&ignore_error);
|
||||
unlink (testfile);
|
||||
|
||||
g_assert_no_error (error);
|
||||
g_assert (reread);
|
||||
g_assert (nm_connection_verify (reread, &error));
|
||||
g_assert (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT));
|
||||
|
||||
g_object_unref (connection);
|
||||
g_object_unref (reread);
|
||||
g_free (testfile);
|
||||
}
|
||||
|
||||
static void
|
||||
test_read_dcb_default_app_priorities (void)
|
||||
{
|
||||
NMConnection *connection;
|
||||
GError *error = NULL;
|
||||
NMSettingDcb *s_dcb;
|
||||
gboolean success;
|
||||
|
||||
connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-default-app-priorities",
|
||||
NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, NULL, &error, NULL);
|
||||
g_assert_no_error (error);
|
||||
g_assert (connection);
|
||||
success = nm_connection_verify (connection, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (success);
|
||||
|
||||
s_dcb = nm_connection_get_setting_dcb (connection);
|
||||
g_assert (s_dcb);
|
||||
|
||||
g_assert_cmpint (nm_setting_dcb_get_app_fcoe_flags (s_dcb), ==, NM_SETTING_DCB_FLAG_ENABLE);
|
||||
g_assert_cmpint (nm_setting_dcb_get_app_fcoe_priority (s_dcb), ==, -1);
|
||||
|
||||
g_assert_cmpint (nm_setting_dcb_get_app_iscsi_flags (s_dcb), ==, NM_SETTING_DCB_FLAG_ENABLE);
|
||||
g_assert_cmpint (nm_setting_dcb_get_app_iscsi_priority (s_dcb), ==, -1);
|
||||
|
||||
g_assert_cmpint (nm_setting_dcb_get_app_fip_flags (s_dcb), ==, NM_SETTING_DCB_FLAG_ENABLE);
|
||||
g_assert_cmpint (nm_setting_dcb_get_app_fip_priority (s_dcb), ==, -1);
|
||||
|
||||
g_object_unref (connection);
|
||||
}
|
||||
|
||||
static void
|
||||
test_read_dcb_bad_booleans (void)
|
||||
{
|
||||
NMConnection *connection;
|
||||
GError *error = NULL;
|
||||
|
||||
connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-bad-booleans",
|
||||
NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, NULL, &error, NULL);
|
||||
g_assert_error (error, IFCFG_PLUGIN_ERROR, 0);
|
||||
g_assert (strstr (error->message, "invalid boolean digit"));
|
||||
g_assert (connection == NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
test_read_dcb_short_booleans (void)
|
||||
{
|
||||
NMConnection *connection;
|
||||
GError *error = NULL;
|
||||
|
||||
connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-short-booleans",
|
||||
NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, NULL, &error, NULL);
|
||||
g_assert_error (error, IFCFG_PLUGIN_ERROR, 0);
|
||||
g_assert (strstr (error->message, "boolean array must be 8 characters"));
|
||||
g_assert (connection == NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
test_read_dcb_bad_uints (void)
|
||||
{
|
||||
NMConnection *connection;
|
||||
GError *error = NULL;
|
||||
|
||||
connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-bad-uints",
|
||||
NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, NULL, &error, NULL);
|
||||
g_assert_error (error, IFCFG_PLUGIN_ERROR, 0);
|
||||
g_assert (strstr (error->message, "invalid uint digit"));
|
||||
g_assert (connection == NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
test_read_dcb_short_uints (void)
|
||||
{
|
||||
NMConnection *connection;
|
||||
GError *error = NULL;
|
||||
|
||||
connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-short-uints",
|
||||
NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, NULL, &error, NULL);
|
||||
g_assert_error (error, IFCFG_PLUGIN_ERROR, 0);
|
||||
g_assert (strstr (error->message, "uint array must be 8 characters"));
|
||||
g_assert (connection == NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
test_read_dcb_bad_percent (void)
|
||||
{
|
||||
NMConnection *connection;
|
||||
GError *error = NULL;
|
||||
|
||||
connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-bad-percent",
|
||||
NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, NULL, &error, NULL);
|
||||
g_assert_error (error, IFCFG_PLUGIN_ERROR, 0);
|
||||
g_assert (strstr (error->message, "invalid percent element"));
|
||||
g_assert (connection == NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
test_read_dcb_short_percent (void)
|
||||
{
|
||||
NMConnection *connection;
|
||||
GError *error = NULL;
|
||||
|
||||
connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-short-percent",
|
||||
NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, NULL, &error, NULL);
|
||||
g_assert_error (error, IFCFG_PLUGIN_ERROR, 0);
|
||||
g_assert (strstr (error->message, "percent array must be 8 elements"));
|
||||
g_assert (connection == NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
test_read_dcb_pgpct_not_100 (void)
|
||||
{
|
||||
NMConnection *connection;
|
||||
GError *error = NULL;
|
||||
|
||||
connection = connection_from_file (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-dcb-pgpct-not-100",
|
||||
NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, NULL, &error, NULL);
|
||||
g_assert_error (error, IFCFG_PLUGIN_ERROR, 0);
|
||||
g_assert (strstr (error->message, "invalid percentage sum"));
|
||||
g_assert (connection == NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
test_read_fcoe_mode (gconstpointer user_data)
|
||||
{
|
||||
const char *expected_mode = user_data;
|
||||
NMConnection *connection;
|
||||
GError *error = NULL;
|
||||
NMSettingDcb *s_dcb;
|
||||
gboolean success;
|
||||
char *file;
|
||||
|
||||
file = g_strdup_printf (TEST_IFCFG_DIR "/network-scripts/ifcfg-test-fcoe-%s", expected_mode);
|
||||
connection = connection_from_file (file, NULL, TYPE_ETHERNET, NULL, NULL, NULL, NULL, NULL, &error, NULL);
|
||||
g_free (file);
|
||||
g_assert_no_error (error);
|
||||
g_assert (connection);
|
||||
success = nm_connection_verify (connection, &error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (success);
|
||||
|
||||
s_dcb = nm_connection_get_setting_dcb (connection);
|
||||
g_assert (s_dcb);
|
||||
|
||||
g_assert_cmpint (nm_setting_dcb_get_app_fcoe_flags (s_dcb), ==, NM_SETTING_DCB_FLAG_ENABLE);
|
||||
g_assert_cmpstr (nm_setting_dcb_get_app_fcoe_mode (s_dcb), ==, expected_mode);
|
||||
|
||||
g_object_unref (connection);
|
||||
}
|
||||
|
||||
static void
|
||||
test_write_fcoe_mode (gconstpointer user_data)
|
||||
{
|
||||
const char *expected_mode = user_data;
|
||||
NMConnection *connection, *reread;
|
||||
GError *error = NULL;
|
||||
NMSettingConnection *s_con;
|
||||
NMSettingWired *s_wired;
|
||||
NMSettingDcb *s_dcb;
|
||||
NMSettingIP4Config *s_ip4;
|
||||
NMSettingIP6Config *s_ip6;
|
||||
gboolean success, ignore_error;
|
||||
char *uuid, *testfile;
|
||||
|
||||
connection = nm_connection_new ();
|
||||
|
||||
s_con = (NMSettingConnection *) nm_setting_connection_new ();
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_con));
|
||||
uuid = nm_utils_uuid_generate ();
|
||||
g_object_set (G_OBJECT (s_con),
|
||||
NM_SETTING_CONNECTION_ID, "fcoe-test",
|
||||
NM_SETTING_CONNECTION_UUID, uuid,
|
||||
NM_SETTING_CONNECTION_TYPE, NM_SETTING_WIRED_SETTING_NAME,
|
||||
NM_SETTING_CONNECTION_INTERFACE_NAME, "eth0",
|
||||
NULL);
|
||||
g_free (uuid);
|
||||
|
||||
/* Wired setting */
|
||||
s_wired = (NMSettingWired *) nm_setting_wired_new ();
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_wired));
|
||||
|
||||
/* IP stuff */
|
||||
s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
|
||||
g_object_set (G_OBJECT (s_ip4), NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_ip4));
|
||||
|
||||
s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
|
||||
g_object_set (G_OBJECT (s_ip6), NM_SETTING_IP6_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL);
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_ip6));
|
||||
|
||||
/* DCB */
|
||||
s_dcb = (NMSettingDcb *) nm_setting_dcb_new ();
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_dcb));
|
||||
|
||||
g_object_set (G_OBJECT (s_dcb),
|
||||
NM_SETTING_DCB_APP_FCOE_FLAGS, NM_SETTING_DCB_FLAG_ENABLE,
|
||||
NM_SETTING_DCB_APP_FCOE_MODE, expected_mode,
|
||||
NULL);
|
||||
|
||||
g_assert (nm_connection_verify (connection, &error));
|
||||
|
||||
/* Save the ifcfg */
|
||||
success = writer_new_connection (connection,
|
||||
TEST_SCRATCH_DIR "/network-scripts/",
|
||||
&testfile,
|
||||
&error);
|
||||
g_assert_no_error (error);
|
||||
g_assert (success);
|
||||
g_assert (testfile);
|
||||
|
||||
{
|
||||
shvarFile *ifcfg = svNewFile (testfile);
|
||||
char *written_mode;
|
||||
|
||||
g_assert (ifcfg);
|
||||
written_mode = svGetValue (ifcfg, "DCB_APP_FCOE_MODE", FALSE);
|
||||
svCloseFile (ifcfg);
|
||||
g_assert_cmpstr (written_mode, ==, expected_mode);
|
||||
g_free (written_mode);
|
||||
}
|
||||
|
||||
/* re-read the connection for comparison */
|
||||
reread = connection_from_file (testfile,
|
||||
NULL,
|
||||
TYPE_ETHERNET,
|
||||
NULL, NULL, NULL,
|
||||
NULL, NULL,
|
||||
&error,
|
||||
&ignore_error);
|
||||
unlink (testfile);
|
||||
|
||||
g_assert_no_error (error);
|
||||
g_assert (reread);
|
||||
g_assert (nm_connection_verify (reread, &error));
|
||||
g_assert (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT));
|
||||
|
||||
g_object_unref (connection);
|
||||
g_object_unref (reread);
|
||||
g_free (testfile);
|
||||
}
|
||||
|
||||
#define TEST_IFCFG_WIFI_OPEN_SSID_BAD_HEX TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-open-ssid-bad-hex"
|
||||
#define TEST_IFCFG_WIFI_OPEN_SSID_LONG_QUOTED TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-open-ssid-long-quoted"
|
||||
#define TEST_IFCFG_WIFI_OPEN_SSID_LONG_HEX TEST_IFCFG_DIR"/network-scripts/ifcfg-test-wifi-open-ssid-long-hex"
|
||||
|
|
@ -12897,6 +13308,20 @@ int main (int argc, char **argv)
|
|||
test_read_ibft_malformed ("ibft-bad-gateway-read", TEST_IFCFG_DIR "/iscsiadm-test-bad-gateway");
|
||||
test_read_ibft_malformed ("ibft-bad-dns1-read", TEST_IFCFG_DIR "/iscsiadm-test-bad-dns1");
|
||||
test_read_ibft_malformed ("ibft-bad-dns2-read", TEST_IFCFG_DIR "/iscsiadm-test-bad-dns2");
|
||||
g_test_add_func (TPATH "dcb/read-basic", test_read_dcb_basic);
|
||||
g_test_add_func (TPATH "dcb/write-basic", test_write_dcb_basic);
|
||||
g_test_add_func (TPATH "dcb/default-app-priorities", test_read_dcb_default_app_priorities);
|
||||
g_test_add_func (TPATH "dcb/bad-booleans", test_read_dcb_bad_booleans);
|
||||
g_test_add_func (TPATH "dcb/short-booleans", test_read_dcb_short_booleans);
|
||||
g_test_add_func (TPATH "dcb/bad-uints", test_read_dcb_bad_uints);
|
||||
g_test_add_func (TPATH "dcb/short-uints", test_read_dcb_short_uints);
|
||||
g_test_add_func (TPATH "dcb/bad-percent", test_read_dcb_bad_percent);
|
||||
g_test_add_func (TPATH "dcb/short-percent", test_read_dcb_short_percent);
|
||||
g_test_add_func (TPATH "dcb/pgpct-not-100", test_read_dcb_pgpct_not_100);
|
||||
g_test_add_data_func (TPATH "fcoe/fabric", (gpointer) NM_SETTING_DCB_FCOE_MODE_FABRIC, test_read_fcoe_mode);
|
||||
g_test_add_data_func (TPATH "fcoe/vn2vn", (gpointer) NM_SETTING_DCB_FCOE_MODE_VN2VN, test_read_fcoe_mode);
|
||||
g_test_add_data_func (TPATH "fcoe/write-fabric", (gpointer) NM_SETTING_DCB_FCOE_MODE_FABRIC, test_write_fcoe_mode);
|
||||
g_test_add_data_func (TPATH "fcoe/write-vn2vn", (gpointer) NM_SETTING_DCB_FCOE_MODE_VN2VN, test_write_fcoe_mode);
|
||||
|
||||
/* bonding */
|
||||
test_read_bond_main ();
|
||||
|
|
|
|||
|
|
@ -1470,6 +1470,165 @@ write_team_port_setting (NMConnection *connection, shvarFile *ifcfg, GError **er
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
write_dcb_flags (shvarFile *ifcfg, const char *tag, NMSettingDcbFlags flags)
|
||||
{
|
||||
char *prop;
|
||||
|
||||
prop = g_strdup_printf ("DCB_%s_ENABLE", tag);
|
||||
svSetValue (ifcfg, prop, (flags & NM_SETTING_DCB_FLAG_ENABLE) ? "yes" : NULL, FALSE);
|
||||
g_free (prop);
|
||||
|
||||
prop = g_strdup_printf ("DCB_%s_ADVERTISE", tag);
|
||||
svSetValue (ifcfg, prop, (flags & NM_SETTING_DCB_FLAG_ADVERTISE) ? "yes" : NULL, FALSE);
|
||||
g_free (prop);
|
||||
|
||||
prop = g_strdup_printf ("DCB_%s_WILLING", tag);
|
||||
svSetValue (ifcfg, prop, (flags & NM_SETTING_DCB_FLAG_WILLING) ? "yes" : NULL, FALSE);
|
||||
g_free (prop);
|
||||
}
|
||||
|
||||
static void
|
||||
write_dcb_app (shvarFile *ifcfg,
|
||||
const char *tag,
|
||||
NMSettingDcbFlags flags,
|
||||
gint priority)
|
||||
{
|
||||
char *prop, *tmp = NULL;
|
||||
|
||||
write_dcb_flags (ifcfg, tag, flags);
|
||||
|
||||
if ((flags & NM_SETTING_DCB_FLAG_ENABLE) && (priority >= 0))
|
||||
tmp = g_strdup_printf ("%d", priority);
|
||||
prop = g_strdup_printf ("DCB_%s_PRIORITY", tag);
|
||||
svSetValue (ifcfg, prop, tmp, FALSE);
|
||||
g_free (prop);
|
||||
g_free (tmp);
|
||||
}
|
||||
|
||||
typedef gboolean (*DcbGetBoolFunc) (NMSettingDcb *, guint);
|
||||
|
||||
static void
|
||||
write_dcb_bool_array (shvarFile *ifcfg,
|
||||
const char *key,
|
||||
NMSettingDcb *s_dcb,
|
||||
NMSettingDcbFlags flags,
|
||||
DcbGetBoolFunc get_func)
|
||||
{
|
||||
char str[9];
|
||||
guint i;
|
||||
|
||||
if (!(flags & NM_SETTING_DCB_FLAG_ENABLE)) {
|
||||
svSetValue (ifcfg, key, NULL, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
str[8] = 0;
|
||||
for (i = 0; i < 8; i++)
|
||||
str[i] = get_func (s_dcb, i) ? '1' : '0';
|
||||
svSetValue (ifcfg, key, str, FALSE);
|
||||
}
|
||||
|
||||
typedef guint (*DcbGetUintFunc) (NMSettingDcb *, guint);
|
||||
|
||||
static void
|
||||
write_dcb_uint_array (shvarFile *ifcfg,
|
||||
const char *key,
|
||||
NMSettingDcb *s_dcb,
|
||||
NMSettingDcbFlags flags,
|
||||
DcbGetUintFunc get_func)
|
||||
{
|
||||
char str[9];
|
||||
guint i, num;
|
||||
|
||||
if (!(flags & NM_SETTING_DCB_FLAG_ENABLE)) {
|
||||
svSetValue (ifcfg, key, NULL, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
str[8] = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
num = get_func (s_dcb, i);
|
||||
if (num < 10)
|
||||
str[i] = '0' + num;
|
||||
else if (num == 15)
|
||||
str[i] = 'f';
|
||||
else
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
svSetValue (ifcfg, key, str, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
write_dcb_percent_array (shvarFile *ifcfg,
|
||||
const char *key,
|
||||
NMSettingDcb *s_dcb,
|
||||
NMSettingDcbFlags flags,
|
||||
DcbGetUintFunc get_func)
|
||||
{
|
||||
GString *str;
|
||||
guint i;
|
||||
|
||||
if (!(flags & NM_SETTING_DCB_FLAG_ENABLE)) {
|
||||
svSetValue (ifcfg, key, NULL, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
str = g_string_sized_new (30);
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (str->len)
|
||||
g_string_append_c (str, ',');
|
||||
g_string_append_printf (str, "%d", get_func (s_dcb, i));
|
||||
}
|
||||
svSetValue (ifcfg, key, str->str, FALSE);
|
||||
g_string_free (str, TRUE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
write_dcb_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
|
||||
{
|
||||
NMSettingDcb *s_dcb;
|
||||
NMSettingDcbFlags flags;
|
||||
|
||||
s_dcb = nm_connection_get_setting_dcb (connection);
|
||||
if (!s_dcb) {
|
||||
svSetValue (ifcfg, "DCB", NULL, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
svSetValue (ifcfg, "DCB", "yes", FALSE);
|
||||
|
||||
write_dcb_app (ifcfg, "APP_FCOE",
|
||||
nm_setting_dcb_get_app_fcoe_flags (s_dcb),
|
||||
nm_setting_dcb_get_app_fcoe_priority (s_dcb));
|
||||
if (nm_setting_dcb_get_app_fcoe_flags (s_dcb) & NM_SETTING_DCB_FLAG_ENABLE)
|
||||
svSetValue (ifcfg, "DCB_APP_FCOE_MODE", nm_setting_dcb_get_app_fcoe_mode (s_dcb), FALSE);
|
||||
else
|
||||
svSetValue (ifcfg, "DCB_APP_FCOE_MODE", NULL, FALSE);
|
||||
|
||||
write_dcb_app (ifcfg, "APP_ISCSI",
|
||||
nm_setting_dcb_get_app_iscsi_flags (s_dcb),
|
||||
nm_setting_dcb_get_app_iscsi_priority (s_dcb));
|
||||
write_dcb_app (ifcfg, "APP_FIP",
|
||||
nm_setting_dcb_get_app_fip_flags (s_dcb),
|
||||
nm_setting_dcb_get_app_fip_priority (s_dcb));
|
||||
|
||||
write_dcb_flags (ifcfg, "PFC", nm_setting_dcb_get_priority_flow_control_flags (s_dcb));
|
||||
write_dcb_bool_array (ifcfg, "DCB_PFC_UP", s_dcb,
|
||||
nm_setting_dcb_get_priority_flow_control_flags (s_dcb),
|
||||
nm_setting_dcb_get_priority_flow_control);
|
||||
|
||||
flags = nm_setting_dcb_get_priority_group_flags (s_dcb);
|
||||
write_dcb_flags (ifcfg, "PG", flags);
|
||||
write_dcb_uint_array (ifcfg, "DCB_PG_ID", s_dcb, flags, nm_setting_dcb_get_priority_group_id);
|
||||
write_dcb_percent_array (ifcfg, "DCB_PG_PCT", s_dcb, flags, nm_setting_dcb_get_priority_group_bandwidth);
|
||||
write_dcb_percent_array (ifcfg, "DCB_PG_UPPCT", s_dcb, flags, nm_setting_dcb_get_priority_bandwidth);
|
||||
write_dcb_bool_array (ifcfg, "DCB_PG_STRICT", s_dcb, flags, nm_setting_dcb_get_priority_strict_bandwidth);
|
||||
write_dcb_uint_array (ifcfg, "DCB_PG_UP2TC", s_dcb, flags, nm_setting_dcb_get_priority_traffic_class);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
write_connection_setting (NMSettingConnection *s_con, shvarFile *ifcfg)
|
||||
{
|
||||
|
|
@ -2275,6 +2434,9 @@ write_connection (NMConnection *connection,
|
|||
if (!write_team_port_setting (connection, ifcfg, error))
|
||||
goto out;
|
||||
|
||||
if (!write_dcb_setting (connection, ifcfg, error))
|
||||
goto out;
|
||||
|
||||
if (!utils_ignore_ip_config (connection)) {
|
||||
svSetValue (ifcfg, "DHCP_HOSTNAME", NULL, FALSE);
|
||||
|
||||
|
|
|
|||
|
|
@ -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