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.
355 lines
11 KiB
355 lines
11 KiB
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 |
|
|
|
|