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