[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, 20 Jun 2012 15:34:45 +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     |  181 +++++++++++++++++++++++++++++++++++++++++++++
 libnm-util/nm-utils.h     |   10 +++
 src/Makefile.am           |    1 +
 src/nm-manager.c          |   92 +++++++++++++++++++++++
 6 files changed, 302 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 3651a32..263c267 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..e402ee3 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,183 @@ 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;
+
+	if (nm_setting_dcb_get_app_subtype(setting) != app_subtype)
+		return NULL;
+
+	j = 0;
+	num = nm_setting_dcb_get_num_app_eaw (setting);
+	for (i = 0; i < num; ++i) {
+		guint8 value = nm_setting_dcb_get_app_eaw (setting, i);
+		if (value != EAW_ERROR)
+			buf[j++] = hexlist[value];
+		else
+			buf[j++] = EAW_ERROR;
+	}
+
+	num = nm_setting_dcb_get_num_app_cfg (setting);
+	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[nm_setting_dcb_get_app_cfg (setting, 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..0959a06 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,92 @@ 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)
+{
+	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;
+	param.subtype = nm_setting_dcb_get_app_subtype (setting);
+	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 +3656,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
[
Date Prev][
Date Next]   [
Thread Prev][
Thread Next]   
[
Thread Index]
[
Date Index]
[
Author Index]