[PATCH 2/2] DCB: generate commands and send them to lldpad
- From: Weiping Pan <wpan redhat com>
- To: dcbw redhat com
- Cc: tgraf redhat com, networkmanager-list gnome org
- Subject: [PATCH 2/2] DCB: generate commands and send them to lldpad
- Date: Wed, 27 Jun 2012 17:48:00 +0800
This patch is to generate DCB commands according to NMSettingDcb,
and then send these commands to lldpad to execute.
NetworkManager should link against liblldp_clif.so.
Signed-off-by: Weiping Pan <wpan redhat com>
---
configure.ac | 17 ++++
libnm-util/libnm-util.ver | 1 +
libnm-util/nm-utils.c | 191 +++++++++++++++++++++++++++++++++++++++++++++
libnm-util/nm-utils.h | 10 +++
src/Makefile.am | 1 +
src/nm-manager.c | 94 ++++++++++++++++++++++
6 files changed, 314 insertions(+), 0 deletions(-)
diff --git a/configure.ac b/configure.ac
index f40962f..87316e0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -423,6 +423,21 @@ if (test "${libnl_version}" = "1"); then
NM_LIBNL_CHECK
fi
+have_liblldp_clif="no"
+PKG_CHECK_MODULES(LIBLLDP_CLIF, liblldp_clif, [have_liblldp_clif=yes], [have_liblldp_clif=no])
+if (test "${have_liblldp_clif}" = "yes"); then
+ AC_DEFINE(HAVE_LIBLLDP_CLIF, 1, [Define if you require specific liblldp_clif- support])
+ LIBLLDP_CLIF_LIBS="$LIBLLDP_CLIF_LIBS"
+ liblldp_clif_version="1"
+ have_liblldp_clif="yes"
+fi
+
+if (test "${have_liblldp_clif}" = "no"); then
+ AC_MSG_ERROR([liblldp_clif shared library is required])
+fi
+
+AC_SUBST(LIBLLDP_CLIF_LIBS)
+
PKG_CHECK_MODULES(UUID, uuid)
AC_SUBST(UUID_CFLAGS)
AC_SUBST(UUID_LIBS)
@@ -888,6 +903,8 @@ fi
echo libnl version: ${libnl_version}
+echo liblldp_clif version: ${liblldp_clif_version}
+
if test "${ac_with_wext}" = "yes"; then
echo WEXT support: yes
else
diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver
index 41c82c8..5e21f3c 100644
--- a/libnm-util/libnm-util.ver
+++ b/libnm-util/libnm-util.ver
@@ -1,5 +1,6 @@
{
global:
+ dcb_get_cmd_args;
nm_connection_add_setting;
nm_connection_clear_secrets;
nm_connection_clear_secrets_with_flags;
diff --git a/libnm-util/nm-utils.c b/libnm-util/nm-utils.c
index f76d0e1..884b2dd 100644
--- a/libnm-util/nm-utils.c
+++ b/libnm-util/nm-utils.c
@@ -39,6 +39,7 @@
#include <glib/gi18n.h>
#include <dbus/dbus-glib.h>
#include <uuid/uuid.h>
+#include <lldpad/clif_cmds.h>
#include "nm-utils.h"
#include "nm-utils-private.h"
@@ -2568,3 +2569,193 @@ nm_utils_hwaddr_ntoa (gconstpointer addr, int type)
return g_string_free (out, FALSE);
}
+
+static const char *hexlist = "0123456789ABCDEF";
+
+static char *dcb_get_dcb_args (NMSettingDcb *setting)
+{
+ char buf[8];
+ int j = 0;
+
+ if (nm_setting_dcb_get_dcb_enabled (setting))
+ buf[j++] = '1';
+ else
+ buf[j++] = '0';
+
+ buf[j] = 0;
+
+ return g_strdup(buf);
+}
+
+static char *dcb_get_app_args(NMSettingDcb *setting, int app_subtype)
+{
+ guint32 num;
+ gchar buf[512];
+ int i, j;
+ dcb_app *app = NULL;
+
+ num = nm_setting_dcb_get_num_apps (setting);
+
+ for (i = 0; i < num; ++i) {
+ app = nm_setting_dcb_get_app (setting, i);
+ if (app->app_subtype == app_subtype)
+ break;
+ else
+ app = NULL;
+ }
+
+ if (!app)
+ return NULL;
+
+ j = 0;
+ for (i = 0; i < app->app_eaw->len; ++i) {
+ guint8 value = g_array_index (app->app_eaw, guint8, i);
+ if (value != EAW_ERROR)
+ buf[j++] = hexlist[value];
+ else
+ buf[j++] = EAW_ERROR;
+ }
+
+ num = app->app_cfg->len;
+ if (num) {
+ /* the length of app cfg is 02 */
+ /* hard code it */
+ buf[j++] = '0';
+ buf[j++] = '2';
+
+ for (i = 0; i < num; ++i)
+ buf[j++] = hexlist[g_array_index (app->app_cfg, guint8, i)];
+ }
+
+ buf[j] = 0;
+ return g_strdup(buf);
+}
+
+static char *dcb_get_pg_args (NMSettingDcb *setting)
+{
+ gchar buf[512];
+ guint32 num;
+ int i, j;
+
+ /* pg eaw */
+ j = 0;
+ num = nm_setting_dcb_get_num_pg_eaw (setting);
+ for (i = 0; i < num; ++i) {
+ guint8 value = nm_setting_dcb_get_pg_eaw (setting, i);
+ if (value != EAW_ERROR)
+ buf[j++] = hexlist[value];
+ else
+ buf[j++] = EAW_ERROR;
+ }
+
+ /* pg_up2tc */
+ num = nm_setting_dcb_get_num_pg_up2tc (setting);
+ for (i = 0; i < num; i++) {
+ guint8 value = nm_setting_dcb_get_pg_up2tc (setting, i);
+ if (value != DCB_NOT_SUPPLIED)
+ buf[j++] = hexlist[value];
+ else
+ buf[j++] = DCB_NOT_SUPPLIED;
+ }
+
+ /* pg_pct */
+ num = nm_setting_dcb_get_num_pg_pct (setting);
+ for (i = 0; i < num; i++) {
+ guint16 percent = nm_setting_dcb_get_pg_pct (setting, i);
+ if (percent == DCB_NOT_SUPPLIED) {
+ buf[j++] = 'x';
+ buf[j++] = 'x';
+ } else {
+ g_snprintf (&buf[j], 3, "%02X", percent);
+ /* overwrite the last '\0'*/
+ j += 2;
+ }
+ }
+
+ /* pg_pgid */
+ num = nm_setting_dcb_get_num_pg_pgid (setting);
+ for (i = 0; i < num; i++) {
+ guint8 value = nm_setting_dcb_get_pg_pgid (setting, i);
+ if (value != DCB_UNLIMITED_PRIORITY_GROUP)
+ buf[j++] = hexlist[nm_setting_dcb_get_pg_pgid (setting, i)];
+ else
+ buf[j++] = DCB_UNLIMITED_PRIORITY_GROUP;
+ }
+
+ /* pg_uppct */
+ num = nm_setting_dcb_get_num_pg_uppct (setting);
+ for (i = 0; i < num; i++) {
+ guint16 percent = nm_setting_dcb_get_pg_uppct (setting, i);
+ if (percent == DCB_NOT_SUPPLIED) {
+ buf[j++] = 'x';
+ buf[j++] = 'x';
+ } else {
+ g_snprintf (&buf[j], 3, "%02X", percent);
+ /* overwrite the last '\0'*/
+ j += 2;
+ }
+ }
+
+ /* pg_strict */
+ num = nm_setting_dcb_get_num_pg_strict (setting);
+ for (i = 0; i < num; i++)
+ buf[j++] = hexlist[nm_setting_dcb_get_pg_strict (setting, i)];
+
+ buf[j++] = 'x';
+ buf[j] = 0;
+ return g_strdup(buf);
+}
+
+static char *dcb_get_pfc_args (NMSettingDcb *setting)
+{
+ gchar buf[512];
+ guint32 num;
+ int i, j;
+
+ j = 0;
+ num = nm_setting_dcb_get_num_pfc_eaw (setting);
+ for (i = 0; i < num; ++i) {
+ guint8 value = nm_setting_dcb_get_pfc_eaw (setting, i);
+ if (value != EAW_ERROR)
+ buf[j++] = hexlist[value];
+ else
+ buf[j++] = EAW_ERROR;
+ }
+
+ num = nm_setting_dcb_get_num_pfc_up (setting);
+ if (num) {
+ for (i = 0; i < num; i++)
+ buf[j++] = hexlist[nm_setting_dcb_get_pfc_up (setting, i)];
+ buf[j++] = 'x';
+ }
+
+ buf[j] = 0;
+ return g_strdup(buf);
+}
+
+char *dcb_get_cmd_args (NMSettingDcb *setting, struct dcb_cmd_param *param)
+{
+ int type;
+ char *args = NULL;
+
+ type = param->feature;
+
+ switch (type) {
+ case FEATURE_DCB:
+ args = dcb_get_dcb_args (setting);
+ break;
+ case FEATURE_APP:
+ args = dcb_get_app_args (setting, param->subtype);
+ break;
+ case FEATURE_PG:
+ args = dcb_get_pg_args (setting);
+ break;
+ case FEATURE_PFC:
+ args = dcb_get_pfc_args (setting);
+ break;
+ default:
+ break;
+ }
+
+ return args;
+}
diff --git a/libnm-util/nm-utils.h b/libnm-util/nm-utils.h
index 7bc536a..3d78f08 100644
--- a/libnm-util/nm-utils.h
+++ b/libnm-util/nm-utils.h
@@ -134,6 +134,16 @@ char *nm_utils_hwaddr_ntoa (gconstpointer addr, int type);
GByteArray *nm_utils_hwaddr_atoba (const char *asc, int type);
guint8 *nm_utils_hwaddr_aton (const char *asc, int type, gpointer buffer);
+struct dcb_cmd_param {
+ int cmd;
+ int feature;
+ int subtype;
+ int port_len;
+ const char *port;
+};
+
+char *dcb_get_cmd_args (NMSettingDcb *setting, struct dcb_cmd_param *param);
+
G_END_DECLS
#endif /* NM_UTILS_H */
diff --git a/src/Makefile.am b/src/Makefile.am
index 7930c28..886dae5 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -325,6 +325,7 @@ NetworkManager_LDADD = \
$(GLIB_LIBS) \
$(GUDEV_LIBS) \
$(LIBNL_LIBS) \
+ $(LIBLLDP_CLIF_LIBS) \
$(GMODULE_LIBS) \
$(POLKIT_LIBS) \
$(SYSTEMD_LIBS) \
diff --git a/src/nm-manager.c b/src/nm-manager.c
index f2816cd..ef1cb72 100644
--- a/src/nm-manager.c
+++ b/src/nm-manager.c
@@ -32,6 +32,8 @@
#include <dbus/dbus-glib.h>
#include <gio/gio.h>
#include <glib/gi18n.h>
+#include <lldpad/clif.h>
+#include <lldpad/clif_cmds.h>
#include "nm-glib-compat.h"
#include "nm-manager.h"
@@ -69,6 +71,7 @@
#include "nm-device-factory.h"
#include "wifi-utils.h"
#include "nm-enum-types.h"
+#include "nm-setting-dcb.h"
#if WITH_CONCHECK
#include "nm-connectivity.h"
@@ -1155,6 +1158,94 @@ system_create_virtual_devices (NMManager *self)
g_slist_free (connections);
}
+static int
+dcb_handle_one_command (struct clif *clif_server, NMSettingDcb *setting, struct dcb_cmd_param *param)
+{
+ size_t len;
+ char buf[4096];
+ char *cmd_args;
+ int ret;
+
+ memset(buf, 0, sizeof(buf));
+ cmd_args = dcb_get_cmd_args (setting, param);
+
+ if (!cmd_args)
+ return 1;
+
+ snprintf(buf, sizeof(buf), "%c%01x%02x%02x%02x%02x%s%s",
+ DCB_CMD, CLIF_MSG_VERSION,
+ param->cmd, param->feature, param->subtype, param->port_len,
+ param->port, cmd_args);
+ g_free (cmd_args);
+
+ len = sizeof(buf) - 1;
+ ret = clif_request(clif_server, buf, strlen(buf), buf, &len, NULL);
+ if (ret == -2) {
+ printf("'%s' command timed out.\n", buf);
+ return -2;
+ } else if (ret < 0) {
+ printf("'%s' command failed.\n", buf);
+ return -1;
+ }
+
+ return 0;
+}
+
+static void
+system_handle_dcb_commands (struct clif *clif_server, NMSettingDcb *setting, const char *ifname)
+{
+ int app_subtype;
+ struct dcb_cmd_param param;
+
+ param.cmd = CMD_SET_CONFIG;
+ param.port_len = strlen(ifname);
+ param.port = ifname;
+
+ param.feature = FEATURE_DCB;
+ param.subtype = 0 ;
+ dcb_handle_one_command (clif_server, setting, ¶m);
+
+ param.feature = FEATURE_APP;
+ for (app_subtype = 0; app_subtype <= APP_STYPE_MAX; app_subtype++) {
+ param.subtype = app_subtype;
+ dcb_handle_one_command (clif_server, setting, ¶m);
+ }
+
+ param.feature = FEATURE_PG;
+ dcb_handle_one_command (clif_server, setting, ¶m);
+
+ param.feature = FEATURE_PFC;
+ dcb_handle_one_command (clif_server, setting, ¶m);
+}
+
+static void
+system_handle_dcb_setting (NMManager *self)
+{
+ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
+ GSList *iter, *connections;
+ struct clif *clif_server = NULL;
+
+ clif_server = clif_open ();
+ if (!clif_server) {
+ nm_log_dbg (LOGD_CORE, "lldpad has not started...");
+ return;
+ }
+
+ connections = nm_settings_get_connections (priv->settings);
+ for (iter = connections; iter; iter = g_slist_next (iter)) {
+ NMConnection *connection = iter->data;
+ NMSettingDcb *dcb = nm_connection_get_setting_dcb (connection);
+ if (dcb) {
+ const char *ifname = nm_setting_dcb_get_interface_name (dcb);
+ system_handle_dcb_commands (clif_server, dcb, ifname);
+ }
+ }
+ g_slist_free (connections);
+ clif_close (clif_server);
+
+ return;
+}
+
static void
connection_added (NMSettings *settings,
NMSettingsConnection *connection,
@@ -3567,6 +3658,9 @@ nm_manager_start (NMManager *self)
* connection-added signals thus devices have to be created manually.
*/
system_create_virtual_devices (self);
+
+ /* handle DCB setting */
+ system_handle_dcb_setting (self);
}
static gboolean
--
1.7.4.4
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]