[lldp-devel] [PATCH] vdp22 add module support for vdp protocol ratified standard

Thomas Richter tmricht at linux.vnet.ibm.com
Tue Feb 19 08:00:59 UTC 2013


This patch adds basic module support for the vdp protocol
for the ratified standard of IEEE 802.1 Qbg.
Add functions for module registration, notification
and creates basic data structures.

Signed-off-by: Thomas Richter <tmricht at linux.vnet.ibm.com>
---
 Makefile.am          |    3 +-
 include/lldp_vdp22.h |   62 +++++++++++++
 lldpad.c             |    2 +
 qbg/lldp_evb22.c     |    3 +
 qbg/lldp_vdp22.c     |  246 ++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 315 insertions(+), 1 deletions(-)
 create mode 100644 include/lldp_vdp22.h
 create mode 100644 qbg/lldp_vdp22.c

diff --git a/Makefile.am b/Makefile.am
index 8a6cf0d..b9ca42e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -66,7 +66,8 @@ lldp_8023.c include/lldp_8023.h \
 lldp_8021qaz.c include/lldp_8021qaz.h \
 lldp_8021qaz_cmds.c include/lldp_8021qaz_cmds.h \
 include/lldp_evb22.h qbg/lldp_evb22.c qbg/lldp_evb22_cmds.c \
-include/lldp_qbg22.h include/lldp_ecp22.h qbg/lldp_ecp22.c
+include/lldp_qbg22.h include/lldp_ecp22.h qbg/lldp_ecp22.c \
+include/lldp_vdp22.h qbg/lldp_vdp22.c
 
 lib_LTLIBRARIES = liblldp_clif.la
 liblldp_clif_la_LDFLAGS = -version-info 1:0:0
diff --git a/include/lldp_vdp22.h b/include/lldp_vdp22.h
new file mode 100644
index 0000000..e4ea1ff
--- /dev/null
+++ b/include/lldp_vdp22.h
@@ -0,0 +1,62 @@
+/*******************************************************************************
+
+  Implementation of EVB TLVs for LLDP
+  (c) Copyright IBM Corp. 2013
+
+  Author(s): Thomas Richter <tmricht at linux.vnet.ibm.com>
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope 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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+*******************************************************************************/
+
+/*
+ * External interface definition for the ratified standard VDP protocol.
+ */
+#ifndef LLDP_VDP22_H
+#define LLDP_VDP22_H
+
+#include	<sys/queue.h>
+#include	<net/if.h>
+#include	<linux/if_ether.h>
+
+#include	"lldp_mod.h"
+
+struct vsi22_profile {
+	LIST_ENTRY(vsi22_profile) prof22_entry;
+};
+
+struct vdp22 {		/* Per interface VSI/VDP data */
+	char ifname[IFNAMSIZ];		/* Interface name */
+	unsigned char max_rwd;		/* Max number of resource wait delay */
+	unsigned char max_rka;		/* Max number of reinit keep alive */
+	unsigned char gpid;		/* Supports group ids in VDP */
+	unsigned short input_len;	/* Length of input data from ECP */
+	unsigned char input[ETH_DATA_LEN];	/* Input data from ECP */
+	LIST_HEAD(profile22_head, vsi22_profile) prof22_head;
+	LIST_ENTRY(vdp22) entry;
+};
+
+struct vdp22_user_data {		/* Head for all VDP data */
+	LIST_HEAD(vdp22_head, vdp22) head;
+};
+
+struct lldp_module *vdp22_register(void);
+void vdp22_unregister(struct lldp_module *);
+void vdp22_start(char *);
+void vdp22_stop(char *);
+
+#endif
diff --git a/lldpad.c b/lldpad.c
index 1988bc6..d29a53d 100644
--- a/lldpad.c
+++ b/lldpad.c
@@ -54,6 +54,7 @@
 #include "lldp_evb22.h"
 #include "lldp_ecp22.h"
 #include "lldp_vdp.h"
+#include "lldp_vdp22.h"
 #include "lldp_8021qaz.h"
 #include "config.h"
 #include "lldpad_shm.h"
@@ -73,6 +74,7 @@ struct lldp_module *(*register_tlv_table[])(void) = {
 	evb_register,
 	evb22_register,
 	vdp_register,
+	vdp22_register,
 	ecp22_register,
 	ieee8021qaz_register,
 	NULL,
diff --git a/qbg/lldp_evb22.c b/qbg/lldp_evb22.c
index 7625b25..f9eeace 100644
--- a/qbg/lldp_evb22.c
+++ b/qbg/lldp_evb22.c
@@ -31,6 +31,7 @@
 #include "lldp_tlv.h"
 #include "lldp_evb22.h"
 #include "lldp_ecp22.h"
+#include "lldp_vdp22.h"
 #include "lldp_qbg_utils.h"
 #include "lldp_evb_cmds.h"
 #include "messages.h"
@@ -347,6 +348,7 @@ static void evb22_stop_modules(char *ifname)
 {
 	LLDPAD_DBG("%s:%s STOP\n", __func__, ifname);
 	ecp22_stop(ifname);
+	vdp22_stop(ifname);
 }
 
 static void evb22_ifdown(char *ifname, struct lldp_agent *agent)
@@ -452,6 +454,7 @@ static void evb22_start_modules(char *ifname)
 {
 	LLDPAD_DBG("%s:%s START\n", __func__, ifname);
 	ecp22_start(ifname);
+	vdp22_start(ifname);
 }
 
 /*
diff --git a/qbg/lldp_vdp22.c b/qbg/lldp_vdp22.c
new file mode 100644
index 0000000..b9390f6
--- /dev/null
+++ b/qbg/lldp_vdp22.c
@@ -0,0 +1,246 @@
+/******************************************************************************
+
+  Implementation of EVB TLVs for LLDP
+  (c) Copyright IBM Corp. 2013
+
+  Author(s): Thomas Richter <tmricht at linux.vnet.ibm.com>
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms and conditions of the GNU General Public License,
+  version 2, as published by the Free Software Foundation.
+
+  This program is distributed in the hope 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 St - Fifth Floor, Boston, MA 02110-1301 USA.
+
+  The full GNU General Public License is included in this distribution in
+  the file called "COPYING".
+
+******************************************************************************/
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "messages.h"
+#include "config.h"
+
+#include "lldp_qbg22.h"
+#include "lldp_vdp22.h"
+
+/*
+ * VDP22 helper functions
+ */
+/*
+ * Find the vdp data associated with an interface.
+ * Return pointer or NULL if not found.
+ */
+static struct vdp22 *vdp22_findif(char *ifname, struct vdp22_user_data *ud)
+{
+	struct vdp22 *vdp = 0;
+
+	if (ud) {
+		LIST_FOREACH(vdp, &ud->head, entry)
+			if (!strncmp(ifname, vdp->ifname, IFNAMSIZ))
+				break;
+	}
+	return vdp;
+}
+
+/*
+ * Update data exchanged via ECP protocol.
+ * Returns true when data update succeeded.
+ */
+static int data_from_ecp(char *ifname, struct ecp22_to_ulp *ptr)
+{
+	struct vdp22_user_data *vud;
+	struct vdp22 *vdp;
+
+	vud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_VDP22);
+	vdp = vdp22_findif(ifname, vud);
+	if (vdp) {
+		memcpy(vdp->input, ptr->data, ptr->len);
+		vdp->input_len = ptr->len;
+		return 0;
+	}
+	return -ENOENT;
+}
+
+/*
+ * Update data exchanged via EVB protocol.
+ * Returns true when data update succeeded.
+ */
+static int data_from_evb(char *ifname, struct evb22_to_vdp22 *ptr)
+{
+	struct vdp22_user_data *vud;
+	struct vdp22 *vdp;
+
+	vud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_VDP22);
+	vdp = vdp22_findif(ifname, vud);
+	if (vdp) {
+		vdp->max_rwd = ptr->max_rwd;
+		vdp->max_rka = ptr->max_rka;
+		vdp->gpid = ptr->gpid;
+		return 0;
+	}
+	return -ENOENT;
+}
+
+/*
+ * Handle notifications from other modules. Check if sender-id and data type
+ * indicator match. Return false when data could not be delivered.
+ */
+static int vdp22_notify(int sender_id, char *ifname, void *data)
+{
+	struct qbg22_imm *qbg = (struct qbg22_imm *)data;
+
+	LLDPAD_DBG("%s:%s sender-id:%#x data_type:%d\n", __func__, ifname,
+		   sender_id, qbg->data_type);
+	if (sender_id == LLDP_MOD_EVB22 && qbg->data_type == EVB22_TO_VDP22)
+		return data_from_evb(ifname, &qbg->u.b);
+	if (sender_id == LLDP_MOD_ECP22 && qbg->data_type == ECP22_TO_ULP)
+		return data_from_ecp(ifname, &qbg->u.c);
+	return 0;
+}
+
+/*
+ * Remove a vdp22 element and delete the chain of active profiles.
+ */
+static void vdp22_free_elem(struct vdp22 *vdp)
+{
+	while (!LIST_EMPTY(&vdp->prof22_head)) {
+		struct vsi22_profile *prof = LIST_FIRST(&vdp->prof22_head);
+
+		free(prof);
+	}
+	LIST_REMOVE(vdp, entry);
+	free(vdp);
+}
+
+/*
+ * Disable the interface for VDP protocol support.
+ */
+void vdp22_stop(char *ifname)
+{
+	struct vdp22_user_data *vud;
+	struct vdp22 *vdp;
+
+	LLDPAD_DBG("%s:%s stop vdp\n", __func__, ifname);
+	vud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_VDP22);
+	if (!vud) {
+		LLDPAD_ERR("%s:%s no VDP22 module\n", __func__, ifname);
+		return;
+	}
+	vdp = vdp22_findif(ifname, vud);
+	if (!vdp) {
+		LLDPAD_ERR("%s:%s no VDP22 data\n", __func__, ifname);
+		return;
+	}
+	vdp22_free_elem(vdp);
+}
+
+/*
+ * vdp22_create - create data structure and initialize vdp protocol
+ * @ifname: interface for which the vdp protocol is initialized
+ *
+ * returns NULL on error and an pointer to the vdp22 structure on success.
+ *
+ * finds the port to the interface name, sets up the receive handle for
+ * incoming vdp frames and initializes the vdp rx and tx state machines.
+ * To be called when a successful exchange of EVB TLVs has been
+ * made and ECP protocols are supported by both sides.
+ */
+static struct vdp22 *vdp22_create(char *ifname, struct vdp22_user_data *eud)
+{
+	struct vdp22 *vdp;
+
+	vdp = calloc(1, sizeof *vdp);
+	if (!vdp) {
+		LLDPAD_ERR("%s:%s unable to allocate vdp protocol\n", __func__,
+			   ifname);
+		return NULL;
+	}
+	strncpy(vdp->ifname, ifname, sizeof vdp->ifname);
+	LIST_INIT(&vdp->prof22_head);
+	LIST_INSERT_HEAD(&eud->head, vdp, entry);
+	LLDPAD_DBG("%s:%s create vdp data\n", __func__, ifname);
+	return vdp;
+}
+/*
+ * Enable the interface for VDP protocol support.
+ */
+void vdp22_start(char *ifname)
+{
+	struct vdp22_user_data *vud;
+	struct vdp22 *vdp;
+
+	LLDPAD_DBG("%s:%s start vdp\n", __func__, ifname);
+	vud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_VDP22);
+	if (!vud) {
+		LLDPAD_ERR("%s:%s no VDP22 module\n", __func__, ifname);
+		return;
+	}
+	vdp = vdp22_findif(ifname, vud);
+	if (!vdp)
+		vdp = vdp22_create(ifname, vud);
+}
+
+/*
+ * Remove all interface/agent specific vdp data.
+ */
+static void vdp22_free_data(struct vdp22_user_data *ud)
+{
+	if (ud) {
+		while (!LIST_EMPTY(&ud->head)) {
+			struct vdp22 *vd = LIST_FIRST(&ud->head);
+
+			vdp22_free_elem(vd);
+		}
+	}
+}
+
+void vdp22_unregister(struct lldp_module *mod)
+{
+	if (mod->data) {
+		vdp22_free_data((struct vdp22_user_data *)mod->data);
+		free(mod->data);
+	}
+	free(mod);
+	LLDPAD_DBG("%s:done\n", __func__);
+}
+
+static const struct lldp_mod_ops vdp22_ops =  {
+	.lldp_mod_register	= vdp22_register,
+	.lldp_mod_unregister	= vdp22_unregister,
+	.lldp_mod_notify	= vdp22_notify
+};
+
+struct lldp_module *vdp22_register(void)
+{
+	struct lldp_module *mod;
+	struct vdp22_user_data *ud;
+
+	mod = calloc(1, sizeof *mod);
+	if (!mod) {
+		LLDPAD_ERR("%s: failed to malloc module data\n", __func__);
+		return NULL;
+	}
+	ud = calloc(1, sizeof *ud);
+	if (!ud) {
+		free(mod);
+		LLDPAD_ERR("%s failed to malloc module user data\n", __func__);
+		return NULL;
+	}
+	LIST_INIT(&ud->head);
+	mod->id = LLDP_MOD_VDP22;
+	mod->ops = &vdp22_ops;
+	mod->data = ud;
+	LLDPAD_DBG("%s:done\n", __func__);
+	return mod;
+}
-- 
1.7.1



More information about the lldp-devel mailing list