[PATCH 2/3] DCB: generate commands and send them to lldpad



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, &param);
+
+	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, &param);
+	}
+
+	param.feature = FEATURE_PG;
+	dcb_handle_one_command (clif_server, setting, &param);
+
+	param.feature = FEATURE_PFC;
+	dcb_handle_one_command (clif_server, setting, &param);
+}
+
+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



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]