Blame SOURCES/open-lldp-v1.0.1-8-VDP-Support-for-OUI-infrastructure-in-vdptool.patch

89f6b3
From 321bfe6c5cbad58e97fbb2df3c93564c89f1e09b Mon Sep 17 00:00:00 2001
89f6b3
From: padkrish <padkrish@cisco.com>
89f6b3
Date: Wed, 21 Jan 2015 03:38:53 +0000
89f6b3
Subject: [PATCH] VDP: Support for OUI infrastructure in vdptool.
89f6b3
89f6b3
This patch contains the changes made in vdptool to support OUI fields
89f6b3
in vdptool. This commit has only the infra-structure changes needed
89f6b3
for supporting OUI. No specific OUI fields are added as a part of this
89f6b3
commit. The man page for vdptool is also modified accordingly.
89f6b3
89f6b3
The OUI data can be given as input to vdptool in different ways. It
89f6b3
could be
89f6b3
89f6b3
   vdptool .... -c oui=companyA,Data1 -c oui=companyB,Data2 -c oui=companyA,Data3
89f6b3
89f6b3
 Or
89f6b3
89f6b3
   vdptool .... -c oui=companyA,Data1Data3 -c oui=companyB,data2
89f6b3
89f6b3
where companyA and companyB are the name of the Organizations.
89f6b3
Anything after the comma in OUI data field is Org specific and it's
89f6b3
upto the respective organization specific handlers to encode it so
89f6b3
that it could be decoded appropriately by the ORG specific handlers
89f6b3
inside lldpad. That is, Data1 and Data3 is specific to Organization
89f6b3
'companyA' and the OUI handlers of companyA in vdptool and lldpad is
89f6b3
responsible for encoding/decoding the data. The common code in vdptool
89f6b3
and lldpad just treats it as opaque data. 'companyA' or 'companyB'
89f6b3
above is the key using which the right handlers will be called.
89f6b3
89f6b3
Irrespective of how the command line interface to vdptool is, the
89f6b3
input to lldpad is always the same. i.e. KeywordlenKeywordDatalenData
89f6b3
For OUI, the data field will have the complete OUI data starting with
89f6b3
ORG name (e.g companyA). So, in order to call the right handler
89f6b3
routine, the OUI data field is split as OUInamelenOUInameOUIData.
89f6b3
89f6b3
OUInamelen is 2B.
89f6b3
89f6b3
For example if the following is given:
89f6b3
89f6b3
vdptool -T -W -i eth2  -V assoc \
89f6b3
    -c mode=assoc -c mgrid2=0 -c typeid=0 -c typeidver=0  \
89f6b3
    -c uuid=18ea3452-b364-4e13-a1a2-9c6524deb685 -c hints=none \
89f6b3
    -c filter=0-fa:16:3e:4c:2d:85-90001 -c oui=companyA,val1=data1
89f6b3
89f6b3
The data sent to lldpad by vdptool will be as follows assuming
89f6b3
companyA encode handlers in vdptool encodes it the same way:
89f6b3
89f6b3
04mode0005assoc06mgrid20001006typeid0001009typeidver0001004uuid002418ea3452-b364-4e13-a1a2-9c6524deb68505hints0004none06filter00190-fa:16:3e:4c:2d:85-9000103oui001408companyAval1=data1
89f6b3
89f6b3
This commit will not insert the oui fields as given above because no OUI
89f6b3
specific handlers are added.
89f6b3
89f6b3
Signed-off-by: padkrish <padkrish@cisco.com>
89f6b3
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
89f6b3
---
89f6b3
 docs/vdptool.8          |  50 +++++++++++++++-
89f6b3
 include/qbg_vdp22_oui.h |  11 ++++
89f6b3
 vdptool.c               | 149 +++++++++++++++++++++++++++++++++++++++++++++---
89f6b3
 3 files changed, 201 insertions(+), 9 deletions(-)
89f6b3
89f6b3
diff --git a/docs/vdptool.8 b/docs/vdptool.8
89f6b3
index 0b50a13..4580c71 100644
89f6b3
--- a/docs/vdptool.8
89f6b3
+++ b/docs/vdptool.8
89f6b3
@@ -182,6 +182,31 @@ delimited by two slashes ('--'),
89f6b3
 also known as filter information format 3.
89f6b3
 For vlan and group details see (1) and (4).
89f6b3
 .RE
89f6b3
+.TP
89f6b3
+.B "oui (Organizationally Unique Identifier):"
89f6b3
+This defines the optional Organizationally
89f6b3
+defined information field. This contains the
89f6b3
+specific sets of values for this entry. There
89f6b3
+can be multiple organizational specific fields,
89f6b3
+in which case there will be multiple keywords
89f6b3
+.I oui=
89f6b3
+followed by the values.
89f6b3
+The value is of the following format:
89f6b3
+.EX
89f6b3
+oui=OUI,[Organization specific values ]
89f6b3
+.EE
89f6b3
+The OUI specifies the name of the Organization
89f6b3
+that is responsible for defining
89f6b3
+this content. A comma is mandatory after the OUI
89f6b3
+field. The fields following this
89f6b3
+ is specified by the organization and
89f6b3
+hence will be decoded based on the value of this
89f6b3
+OUI field. Currently, the following values for
89f6b3
+OUI are supported.
89f6b3
+.RS
89f6b3
+.IP cisco -
89f6b3
+Specifies Cisco defined OUI.
89f6b3
+.TP
89f6b3
 .SH COMMANDS
89f6b3
 .TP
89f6b3
 .B license
89f6b3
@@ -226,13 +251,33 @@ vdptool -i eth2 -T -V assoc -c mode=assoc -c mgrid2=blabla \\
89f6b3
 	-c filter=2-52:00:00:11:22:33-200
89f6b3
 .fi
89f6b3
 .TP
89f6b3
-Create a VSI association on interface eth2 and wait for the response from the bridge
89f6b3
+Create a VSI association on interface eth2 and wait for the
89f6b3
+response from the bridge
89f6b3
 .br
89f6b3
 .nf
89f6b3
 vdptool -i eth2 -T -W -V assoc -c mode=assoc -c mgrid2=blabla \\
89f6b3
 	-c typeid=5 -c uuid=1122 -c typeidver=4 -c hints=none \\
89f6b3
 	-c filter=0-52:00:00:11:22:33-200
89f6b3
 .fi
89f6b3
+.TP
89f6b3
+Create a VSI association on interface eth2 wth OUI parameters
89f6b3
+and wait for the response from the bridge
89f6b3
+.br
89f6b3
+.nf
89f6b3
+vdptool -i eth2 -T -W -V assoc -c mode=assoc -c mgrid2=blabla \\
89f6b3
+	-c typeid=5 -c uuid=1122 -c typeidver=4 -c hints=none \\
89f6b3
+	-c filter=0-52:00:00:11:22:33-200 -c oui=CompanyA,data
89f6b3
+.fi
89f6b3
+.TP
89f6b3
+Create a VSI association on interface eth2 wth multiple OUI parameters
89f6b3
+and wait for the response from the bridge
89f6b3
+.br
89f6b3
+.nf
89f6b3
+vdptool -i eth2 -T -W -V assoc -c mode=assoc -c mgrid2=blabla \\
89f6b3
+	-c typeid=5 -c uuid=1122 -c typeidver=4 -c hints=none \\
89f6b3
+	-c filter=0-52:00:00:11:22:33-200 -c oui=CompanyA,data \\
89f6b3
+	-c oui=CompanyB,data
89f6b3
+.fi
89f6b3
 
89f6b3
 .TP
89f6b3
 Query all VSI association on interface eth2
89f6b3
@@ -240,7 +285,8 @@ Query all VSI association on interface eth2
89f6b3
 vdptool -i eth2 -t -V assoc
89f6b3
 
89f6b3
 .TP
89f6b3
-Query  VSI association on interface eth2 that matches specific VSI parameters. Any of the VSI parameters below can be omitted.
89f6b3
+Query  VSI association on interface eth2 that matches specific
89f6b3
+VSI parameters. Any of the VSI parameters below can be omitted.
89f6b3
 .br
89f6b3
 vdptool -i eth2 -t -V assoc -t -V assoc -c mode=assoc \\
89f6b3
         -c mgrid2=blabla -c typeid=5 -c uuid=1122 \\
89f6b3
diff --git a/include/qbg_vdp22_oui.h b/include/qbg_vdp22_oui.h
89f6b3
index 0aeb7b9..d31c6ad 100644
89f6b3
--- a/include/qbg_vdp22_oui.h
89f6b3
+++ b/include/qbg_vdp22_oui.h
89f6b3
@@ -33,6 +33,7 @@
89f6b3
 enum vdp22_oui {
89f6b3
 	VDP22_OUI_TYPE_LEN = 3,          /* Size of OUI Type field */
89f6b3
 	VDP22_OUI_MAX_NAME = 20,
89f6b3
+	MAX_OUI_DATA_LEN = 200
89f6b3
 };
89f6b3
 
89f6b3
 struct vdp22_oui_data_s {
89f6b3
@@ -43,4 +44,14 @@ struct vdp22_oui_data_s {
89f6b3
 	void *data;
89f6b3
 };
89f6b3
 
89f6b3
+typedef struct vdptool_oui_data_s {
89f6b3
+	char oui_name[VDP22_OUI_MAX_NAME];
89f6b3
+	char data[MAX_OUI_DATA_LEN];
89f6b3
+} vdptool_oui_data_t;
89f6b3
+
89f6b3
+typedef struct vdptool_oui_hndlr_tbl_s {
89f6b3
+	char *oui_name;
89f6b3
+	bool (*oui_cli_encode_hndlr)(char *dst, char *src, size_t len);
89f6b3
+} vdptool_oui_hndlr_tbl_t;
89f6b3
+
89f6b3
 #endif /* __VDP22_OUI_H__ */
89f6b3
diff --git a/vdptool.c b/vdptool.c
89f6b3
index f7fd288..c857a85 100644
89f6b3
--- a/vdptool.c
89f6b3
+++ b/vdptool.c
89f6b3
@@ -55,6 +55,22 @@
89f6b3
 #include "qbg_vdp22_clif.h"
89f6b3
 #include "lldp_util.h"
89f6b3
 #include "qbg_vdp22def.h"
89f6b3
+#include "qbg_vdp22_oui.h"
89f6b3
+
89f6b3
+#define OUI_ENCODE_HNDLR(name) name##_oui_encode_hndlr
89f6b3
+#define EXTERN_OUI_FN(name) \
89f6b3
+	extern bool name##_oui_encode_hndlr(char *, char *, size_t)
89f6b3
+
89f6b3
+/* The handler declaration  for encoding OUI specific information should be
89f6b3
+ * here. The corresponding decoder handler should be in lldpad.
89f6b3
+ */
89f6b3
+
89f6b3
+
89f6b3
+/* The OUI specific handlers should be added here */
89f6b3
+
89f6b3
+vdptool_oui_hndlr_tbl_t oui_hndlr_tbl[] = {
89f6b3
+};
89f6b3
+
89f6b3
 
89f6b3
 static char *print_vdp_status(enum vdp22_cmd_status status)
89f6b3
 {
89f6b3
@@ -144,23 +160,137 @@ static void get_arg_value(char *str, char **arg, char **argval)
89f6b3
 	*arg = str;
89f6b3
 }
89f6b3
 
89f6b3
-static int render_cmd(struct cmd *cmd, int argc, char **args, char **argvals)
89f6b3
+static char *get_oui_name(char *argvals)
89f6b3
+{
89f6b3
+	char *oui_loc;
89f6b3
+
89f6b3
+	oui_loc = strchr(argvals, ',');
89f6b3
+	if (oui_loc == NULL)
89f6b3
+		return NULL;
89f6b3
+	*oui_loc = '\0';
89f6b3
+	return oui_loc + 1;
89f6b3
+}
89f6b3
+
89f6b3
+static void fill_oui_hdr(vdptool_oui_data_t *oui_data, char *oui_name)
89f6b3
+{
89f6b3
+	strncpy(oui_data->oui_name, oui_name, sizeof(oui_data->oui_name));
89f6b3
+	snprintf(oui_data->data, sizeof(oui_data->data), "%02x%s",
89f6b3
+		 (unsigned int)strlen(oui_data->oui_name), oui_data->oui_name);
89f6b3
+}
89f6b3
+
89f6b3
+static bool run_vdptool_oui_hndlr(vdptool_oui_data_t *oui_data, char *argvals)
89f6b3
+{
89f6b3
+	int cnt = 0, tbl_size;
89f6b3
+	char *dst;
89f6b3
+	size_t len = 0;
89f6b3
+
89f6b3
+	tbl_size = sizeof(oui_hndlr_tbl) / sizeof(vdptool_oui_hndlr_tbl_t);
89f6b3
+	for (cnt = 0; cnt < tbl_size; cnt++) {
89f6b3
+		if (!strncmp(oui_hndlr_tbl[cnt].oui_name, oui_data->oui_name,
89f6b3
+			     VDP22_OUI_MAX_NAME)) {
89f6b3
+			len = strlen(oui_data->data);
89f6b3
+			if (len >= sizeof(oui_data->data))
89f6b3
+				return false;
89f6b3
+			dst = oui_data->data + len;
89f6b3
+			return oui_hndlr_tbl[cnt].oui_cli_encode_hndlr(dst,
89f6b3
+								argvals, len);
89f6b3
+		}
89f6b3
+	}
89f6b3
+	return false;
89f6b3
+}
89f6b3
+
89f6b3
+/*
89f6b3
+ * The OUI can be input in many ways.
89f6b3
+ * It could be vdptool .... -c oui=companyA,Data1 -c oui=companyB,Data2 \
89f6b3
+ *			    -c oui=companyA,Data3
89f6b3
+ * Or
89f6b3
+ * vdptool .... -c oui=companyA,Data1Data3 -c oui=companyB,data2
89f6b3
+ * This function takes care of both the case cases
89f6b3
+ *
89f6b3
+ * Anything after the comma in OUI data field is Org specific and it's upto
89f6b3
+ * the respective organization specific handlers to encode it so that it could
89f6b3
+ * be decoded appropriately by the ORG specific handlers inside lldpad.
89f6b3
+ * That is, Data1 and Data3 is ORG companyA specific and the OUI handlers
89f6b3
+ * of ORG companyA in vdptool and lldpad is responsible for encoding/decoding.
89f6b3
+ *
89f6b3
+ * Irrespective of how the command line interface to vdptool is, the input to
89f6b3
+ * lldpad is always the same. i.e. KeywordlenKeywordDatalenData
89f6b3
+ * For OUI, the data field will have the complete OUI data starting with
89f6b3
+ * ORG name (e.g companyA). So, in order to call the right handler routine,
89f6b3
+ * the OUI data field is split as OUInamelenOUInameOUIData.
89f6b3
+ * OUInamelen is 2B.
89f6b3
+ */
89f6b3
+
89f6b3
+static bool rewrite_oui_argval(char *argvals, vdptool_oui_data_t **oui_data,
89f6b3
+			       int total_oui)
89f6b3
+{
89f6b3
+	char *new_oui_argvals, *new_oui_name, *exist_oui_name;
89f6b3
+	bool flag = true, ret = false;
89f6b3
+	int cnt;
89f6b3
+
89f6b3
+	new_oui_argvals = get_oui_name(argvals);
89f6b3
+	if (!new_oui_argvals) {
89f6b3
+		printf("Incorrect OUI Value, missing comma as delimited for "
89f6b3
+		       "OUI Type\n");
89f6b3
+		return false;
89f6b3
+	}
89f6b3
+	new_oui_name = argvals;
89f6b3
+	for (cnt = 0; cnt < total_oui; cnt++) {
89f6b3
+		if (!oui_data[cnt])
89f6b3
+			continue;
89f6b3
+		exist_oui_name = oui_data[cnt]->oui_name;
89f6b3
+		if (!strncmp(new_oui_name, exist_oui_name,
89f6b3
+			     VDP22_OUI_MAX_NAME)) {
89f6b3
+			flag = false;
89f6b3
+			break;
89f6b3
+		}
89f6b3
+	}
89f6b3
+	if (flag) {
89f6b3
+		oui_data[total_oui] = calloc(1, sizeof(vdptool_oui_data_t));
89f6b3
+		fill_oui_hdr(oui_data[total_oui], new_oui_name);
89f6b3
+		ret = run_vdptool_oui_hndlr(oui_data[total_oui],
89f6b3
+					    new_oui_argvals);
89f6b3
+	} else
89f6b3
+		ret = run_vdptool_oui_hndlr(oui_data[cnt], new_oui_argvals);
89f6b3
+	if (!ret)
89f6b3
+		return false;
89f6b3
+	return flag;
89f6b3
+}
89f6b3
+
89f6b3
+int render_cmd(struct cmd *cmd, int argc, char **args, char **argvals)
89f6b3
 {
89f6b3
 	int len;
89f6b3
 	int i;
89f6b3
 	int fid = 0, oui = 0;
89f6b3
+	vdptool_oui_data_t **oui_data;
89f6b3
+	bool is_new;
89f6b3
 
89f6b3
 	len = sizeof(cmd->obuf);
89f6b3
 
89f6b3
+	/* To avoid another loop to figure the number of OUI's */
89f6b3
+	oui_data = calloc(argc, sizeof(vdptool_oui_data_t *));
89f6b3
+	if (!oui_data) {
89f6b3
+		printf("Not enough memory\n");
89f6b3
+		return 0;
89f6b3
+	}
89f6b3
+
89f6b3
 	if ((cmd->cmd == cmd_settlv) || (cmd->cmd == cmd_gettlv)) {
89f6b3
 		for (i = 0; i < argc; i++) {
89f6b3
-			if (args[i]) {
89f6b3
-				if (!strncasecmp(args[i], "filter",
89f6b3
-						strlen("filter")))
89f6b3
-					fid++;
89f6b3
-				else if (!strncasecmp(args[i], "oui",
89f6b3
-						strlen("oui")))
89f6b3
+			if (!args[i])
89f6b3
+				continue;
89f6b3
+			if (!strncasecmp(args[i], "filter", strlen("filter")))
89f6b3
+				fid++;
89f6b3
+			else if (!strncasecmp(args[i], "oui", strlen("oui"))) {
89f6b3
+				is_new = rewrite_oui_argval(argvals[i],
89f6b3
+							    oui_data,
89f6b3
+							    oui);
89f6b3
+				if (is_new) {
89f6b3
+					argvals[i] = oui_data[oui]->data;
89f6b3
 					oui++;
89f6b3
+				} else {
89f6b3
+					args[i] = NULL;
89f6b3
+					argvals[i] = NULL;
89f6b3
+				}
89f6b3
 			}
89f6b3
 		}
89f6b3
 	}
89f6b3
@@ -182,6 +312,11 @@ static int render_cmd(struct cmd *cmd, int argc, char **args, char **argvals)
89f6b3
 				 len - strlen(cmd->obuf), "%04x%s",
89f6b3
 				 (unsigned int)strlen(argvals[i]), argvals[i]);
89f6b3
 	}
89f6b3
+	for (i = 0; i < oui; i++) {
89f6b3
+		if (oui_data[i])
89f6b3
+			free(oui_data[i]);
89f6b3
+	}
89f6b3
+	free(oui_data);
89f6b3
 	return strlen(cmd->obuf);
89f6b3
 }
89f6b3
 
89f6b3
-- 
89f6b3
2.1.0
89f6b3