|
|
ee47b4 |
From 19bdcc3fe966dc7d6fc154d7d29addfe200c6afc Mon Sep 17 00:00:00 2001
|
|
|
ee47b4 |
From: padkrish <padkrish@cisco.com>
|
|
|
ee47b4 |
Date: Wed, 21 Jan 2015 03:39:19 +0000
|
|
|
ee47b4 |
Subject: [PATCH] VDP: Support for OUI infrastructure in vdp22.
|
|
|
ee47b4 |
|
|
|
ee47b4 |
This commit is a framework for supporting OUI fields
|
|
|
ee47b4 |
in VDP22. This specific patch has changes for converting
|
|
|
ee47b4 |
OUI input to vdpnl structure, vdpnl to VSI
|
|
|
ee47b4 |
and place-holders for calling the OUI handlers.
|
|
|
ee47b4 |
The specific changes are:
|
|
|
ee47b4 |
|
|
|
ee47b4 |
vdp22.c:
|
|
|
ee47b4 |
-------
|
|
|
ee47b4 |
Currently, the OUI handler code is linked statically to the lldpad (vdp22).
|
|
|
ee47b4 |
Some more enhancements are needed to support the dynamic linking of OUI
|
|
|
ee47b4 |
handler code. This is the general flow:
|
|
|
ee47b4 |
All the OUI handlers specify their init function in vdp22_oui_init_list. When
|
|
|
ee47b4 |
VDP22 receives a command with the OUI fields, then based on the OUI value,
|
|
|
ee47b4 |
it calls the appropriate init function. The OUI specific init function
|
|
|
ee47b4 |
implemented in the OUI specific file (not in this file) then registers its
|
|
|
ee47b4 |
handlers with VDP22. The handlers prototype is in qbg_vdp22_oui.h and it
|
|
|
ee47b4 |
currently has:
|
|
|
ee47b4 |
1. Handler for converting the OUI string to OUI structure which is a member of vdpnl structure.
|
|
|
ee47b4 |
2. Handler for converting the OUI structure from vdpnl structure to a OUI structure which is a member of vsi22 structure
|
|
|
ee47b4 |
3. Handler for creating the OUI fields for Tx.
|
|
|
ee47b4 |
4. handler for processing/Rx the OUI information
|
|
|
ee47b4 |
5. Handler for freeing the OUI structure
|
|
|
ee47b4 |
6. Handler to return the size of OUI PTLV
|
|
|
ee47b4 |
|
|
|
ee47b4 |
Then, accordingly the respective handlers are called.
|
|
|
ee47b4 |
Function 'vdp22_delete_oui' calls each of the registered handlers for freeing
|
|
|
ee47b4 |
its OUI specific fields.
|
|
|
ee47b4 |
Function 'vdpnl_alloc_vsi_oui' calls each of the registered handlers for
|
|
|
ee47b4 |
creating a OUI structure in vsi22 structure.
|
|
|
ee47b4 |
Function 'oui_vdp_hndlr_init' is called by OUI specific code to register
|
|
|
ee47b4 |
its handlers.
|
|
|
ee47b4 |
Function 'vdp22_oui_init' calls the OUI specific init function.
|
|
|
ee47b4 |
Comments are embedded in the other functions added.
|
|
|
ee47b4 |
|
|
|
ee47b4 |
vdp22sm.c:
|
|
|
ee47b4 |
----------
|
|
|
ee47b4 |
Function 'oui22_ptlv_sz' calls each of the handlers in its VSI structure
|
|
|
ee47b4 |
to get the size of the OUI specific PTLV size.
|
|
|
ee47b4 |
Function 'oui22_2tlv' calls the handler for generating the OUI data for Tx.
|
|
|
ee47b4 |
|
|
|
ee47b4 |
vdp22_cmds.c:
|
|
|
ee47b4 |
-------------
|
|
|
ee47b4 |
This file has a minor modification to get the number of OUI fields which is
|
|
|
ee47b4 |
encoded in the input to lldpad.
|
|
|
ee47b4 |
|
|
|
ee47b4 |
vdp_ascii.c:
|
|
|
ee47b4 |
------------
|
|
|
ee47b4 |
Function 'oui_str2vdpnl' calls the respective handler to convert the OUI input
|
|
|
ee47b4 |
string to the OUI structure stored in vdpnl structure.
|
|
|
ee47b4 |
|
|
|
ee47b4 |
Signed-off-by: padkrish <padkrish@cisco.com>
|
|
|
ee47b4 |
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
|
|
|
ee47b4 |
---
|
|
|
ee47b4 |
include/qbg_vdp22_oui.h | 38 ++++++++++++
|
|
|
ee47b4 |
qbg/vdp22.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
ee47b4 |
qbg/vdp22_cmds.c | 10 ++-
|
|
|
ee47b4 |
qbg/vdp22sm.c | 54 +++++++++++++++-
|
|
|
ee47b4 |
qbg/vdp_ascii.c | 37 ++++++++++-
|
|
|
ee47b4 |
5 files changed, 293 insertions(+), 5 deletions(-)
|
|
|
ee47b4 |
|
|
|
ee47b4 |
diff --git a/include/qbg_vdp22_oui.h b/include/qbg_vdp22_oui.h
|
|
|
ee47b4 |
index d31c6ad..0cce31e 100644
|
|
|
ee47b4 |
--- a/include/qbg_vdp22_oui.h
|
|
|
ee47b4 |
+++ b/include/qbg_vdp22_oui.h
|
|
|
ee47b4 |
@@ -32,6 +32,7 @@
|
|
|
ee47b4 |
*/
|
|
|
ee47b4 |
enum vdp22_oui {
|
|
|
ee47b4 |
VDP22_OUI_TYPE_LEN = 3, /* Size of OUI Type field */
|
|
|
ee47b4 |
+ MAX_NUM_OUI = 10,
|
|
|
ee47b4 |
VDP22_OUI_MAX_NAME = 20,
|
|
|
ee47b4 |
MAX_OUI_DATA_LEN = 200
|
|
|
ee47b4 |
};
|
|
|
ee47b4 |
@@ -54,4 +55,41 @@ typedef struct vdptool_oui_hndlr_tbl_s {
|
|
|
ee47b4 |
bool (*oui_cli_encode_hndlr)(char *dst, char *src, size_t len);
|
|
|
ee47b4 |
} vdptool_oui_hndlr_tbl_t;
|
|
|
ee47b4 |
|
|
|
ee47b4 |
+struct vdpnl_oui_data_s {
|
|
|
ee47b4 |
+ unsigned char oui_type[VDP22_OUI_TYPE_LEN];
|
|
|
ee47b4 |
+ char oui_name[VDP22_OUI_MAX_NAME];
|
|
|
ee47b4 |
+ int len;
|
|
|
ee47b4 |
+ char data[MAX_OUI_DATA_LEN];
|
|
|
ee47b4 |
+ /* If vdpnl structure is used for IPC, then this cannot be a ptr as
|
|
|
ee47b4 |
+ * otherwise it needs to be flattened out. If this is just used within
|
|
|
ee47b4 |
+ * lldpad then this can be made a ptr instead of a static array.
|
|
|
ee47b4 |
+ * May need to revisit later TODO
|
|
|
ee47b4 |
+ */
|
|
|
ee47b4 |
+};
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
+struct vdp22_oui_init_s {
|
|
|
ee47b4 |
+ unsigned char oui_type[VDP22_OUI_TYPE_LEN];
|
|
|
ee47b4 |
+ char oui_name[VDP22_OUI_MAX_NAME];
|
|
|
ee47b4 |
+ bool (*oui_init)();
|
|
|
ee47b4 |
+};
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
+struct vdp22_oui_handler_s {
|
|
|
ee47b4 |
+ unsigned char oui_type[VDP22_OUI_TYPE_LEN];
|
|
|
ee47b4 |
+ char oui_name[VDP22_OUI_MAX_NAME];
|
|
|
ee47b4 |
+ /* This handler converts the OUI string to vdpnl structure */
|
|
|
ee47b4 |
+ bool (*str2vdpnl_hndlr)(struct vdpnl_oui_data_s *, char *);
|
|
|
ee47b4 |
+ /* This handler converts the vdpnl structure to vsi22 structure */
|
|
|
ee47b4 |
+ bool (*vdpnl2vsi22_hndlr)(void *, struct vdpnl_oui_data_s *,
|
|
|
ee47b4 |
+ struct vdp22_oui_data_s *);
|
|
|
ee47b4 |
+ /* This handler creates the OUI fields for Tx */
|
|
|
ee47b4 |
+ size_t (*vdp_tx_hndlr)(char unsigned *,
|
|
|
ee47b4 |
+ struct vdp22_oui_data_s *, size_t);
|
|
|
ee47b4 |
+ /* This handler is called for processing/Rx the OUI information */
|
|
|
ee47b4 |
+ bool (*vdp_rx_hndlr)();
|
|
|
ee47b4 |
+ /* This handler frees the OUI structures */
|
|
|
ee47b4 |
+ bool (*vdp_free_oui_hndlr)(struct vdp22_oui_data_s *);
|
|
|
ee47b4 |
+ /* This handler returns the size of OUI PTLV */
|
|
|
ee47b4 |
+ unsigned long (*oui_ptlv_size_hndlr)(void *);
|
|
|
ee47b4 |
+};
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
#endif /* __VDP22_OUI_H__ */
|
|
|
ee47b4 |
diff --git a/qbg/vdp22.c b/qbg/vdp22.c
|
|
|
ee47b4 |
index d7aa648..5cae83f 100644
|
|
|
ee47b4 |
--- a/qbg/vdp22.c
|
|
|
ee47b4 |
+++ b/qbg/vdp22.c
|
|
|
ee47b4 |
@@ -44,6 +44,22 @@
|
|
|
ee47b4 |
#include "qbg_vdp22_cmds.h"
|
|
|
ee47b4 |
#include "qbg_vdp22def.h"
|
|
|
ee47b4 |
|
|
|
ee47b4 |
+#define INIT_FN(name) name##_oui_init
|
|
|
ee47b4 |
+#define EXTERN_FN(name)\
|
|
|
ee47b4 |
+extern bool name##_oui_init()
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
+/* Init handlers for OUI. OUI handlers should be added in vdp22_oui_init_list.
|
|
|
ee47b4 |
+ * First argument specifies the OUI code assigned to the Organization.
|
|
|
ee47b4 |
+ * Second argument is the string which should match with the CLI and the third
|
|
|
ee47b4 |
+ * argument is the init handler.
|
|
|
ee47b4 |
+ */
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
+struct vdp22_oui_init_s vdp22_oui_init_list[] = {
|
|
|
ee47b4 |
+};
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
+struct vdp22_oui_handler_s vdp22_oui_list[MAX_NUM_OUI];
|
|
|
ee47b4 |
+unsigned char g_oui_index;
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
/*
|
|
|
ee47b4 |
* VDP22 helper functions
|
|
|
ee47b4 |
*/
|
|
|
ee47b4 |
@@ -218,6 +234,36 @@ void vdp22_showvsi(struct vsi22 *p)
|
|
|
ee47b4 |
}
|
|
|
ee47b4 |
|
|
|
ee47b4 |
/*
|
|
|
ee47b4 |
+ * Delete the OUI structures of VSI22
|
|
|
ee47b4 |
+ * This calls the respective OUI handlers which are responsible for freeing
|
|
|
ee47b4 |
+ * the OUI specific 'data' element of 'vdp22_oui_data_s' structure.
|
|
|
ee47b4 |
+ */
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
+static void vdp22_delete_oui(struct vsi22 *p)
|
|
|
ee47b4 |
+{
|
|
|
ee47b4 |
+ struct vdp22_oui_data_s *oui_str;
|
|
|
ee47b4 |
+ struct vdp22_oui_handler_s *oui_hndlr;
|
|
|
ee47b4 |
+ int idx;
|
|
|
ee47b4 |
+ bool ret;
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
+ if ((p->no_ouidata == 0) || (!p->oui_str_data))
|
|
|
ee47b4 |
+ return;
|
|
|
ee47b4 |
+ for (idx = 0; idx < p->no_ouidata; idx++) {
|
|
|
ee47b4 |
+ oui_str = &p->oui_str_data[idx];
|
|
|
ee47b4 |
+ oui_hndlr = vdp22_get_oui_hndlr(oui_str->oui_name);
|
|
|
ee47b4 |
+ if (!oui_hndlr)
|
|
|
ee47b4 |
+ LLDPAD_ERR("%s: Unknown OUI %s\n",
|
|
|
ee47b4 |
+ __func__, oui_str->oui_name);
|
|
|
ee47b4 |
+ else {
|
|
|
ee47b4 |
+ ret = oui_hndlr->vdp_free_oui_hndlr(oui_str);
|
|
|
ee47b4 |
+ LLDPAD_DBG("%s: Free handler returned %d\n", __func__,
|
|
|
ee47b4 |
+ ret);
|
|
|
ee47b4 |
+ }
|
|
|
ee47b4 |
+ }
|
|
|
ee47b4 |
+ free(p->oui_str_data);
|
|
|
ee47b4 |
+}
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
+/*
|
|
|
ee47b4 |
* Delete a complete VSI node not on queue.
|
|
|
ee47b4 |
*/
|
|
|
ee47b4 |
void vdp22_delete_vsi(struct vsi22 *p)
|
|
|
ee47b4 |
@@ -225,6 +271,7 @@ void vdp22_delete_vsi(struct vsi22 *p)
|
|
|
ee47b4 |
LLDPAD_DBG("%s:%s vsi:%p(%02x)\n", __func__, p->vdp->ifname, p,
|
|
|
ee47b4 |
p->vsi[0]);
|
|
|
ee47b4 |
free(p->fdata);
|
|
|
ee47b4 |
+ vdp22_delete_oui(p);
|
|
|
ee47b4 |
free(p);
|
|
|
ee47b4 |
}
|
|
|
ee47b4 |
|
|
|
ee47b4 |
@@ -475,6 +522,38 @@ static bool filter_ok(unsigned char ffmt, struct fid22 *fp,
|
|
|
ee47b4 |
return rc;
|
|
|
ee47b4 |
}
|
|
|
ee47b4 |
|
|
|
ee47b4 |
+static void vdpnl_alloc_vsi_oui(struct vdpnl_vsi *vsi, struct vsi22 *p)
|
|
|
ee47b4 |
+{
|
|
|
ee47b4 |
+ struct vdp22_oui_handler_s *oui_hndlr;
|
|
|
ee47b4 |
+ bool ret;
|
|
|
ee47b4 |
+ int idx;
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
+ if (vsi->ouisz == 0)
|
|
|
ee47b4 |
+ return;
|
|
|
ee47b4 |
+ p->no_ouidata = vsi->ouisz;
|
|
|
ee47b4 |
+ p->oui_str_data = calloc(vsi->ouisz, sizeof(struct vdp22_oui_data_s));
|
|
|
ee47b4 |
+ if (!p->oui_str_data) {
|
|
|
ee47b4 |
+ LLDPAD_ERR("%s: calloc return failure\n", __func__);
|
|
|
ee47b4 |
+ return;
|
|
|
ee47b4 |
+ }
|
|
|
ee47b4 |
+ for (idx = 0; idx < vsi->ouisz; idx++) {
|
|
|
ee47b4 |
+ struct vdpnl_oui_data_s *from = &vsi->oui_list[idx];
|
|
|
ee47b4 |
+ struct vdp22_oui_data_s *to = &p->oui_str_data[idx];
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
+ oui_hndlr = vdp22_get_oui_hndlr(from->oui_name);
|
|
|
ee47b4 |
+ if (!oui_hndlr)
|
|
|
ee47b4 |
+ LLDPAD_ERR("%s: Unknown OUI Name %s\n",
|
|
|
ee47b4 |
+ __func__, from->oui_name);
|
|
|
ee47b4 |
+ else {
|
|
|
ee47b4 |
+ ret = oui_hndlr->vdpnl2vsi22_hndlr(p, from, to);
|
|
|
ee47b4 |
+ if (!ret)
|
|
|
ee47b4 |
+ LLDPAD_ERR("%s: handler return error for "
|
|
|
ee47b4 |
+ "oui %s\n", __func__,
|
|
|
ee47b4 |
+ from->oui_name);
|
|
|
ee47b4 |
+ }
|
|
|
ee47b4 |
+ }
|
|
|
ee47b4 |
+}
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
/*
|
|
|
ee47b4 |
* Allocate a VSI node with filter information data.
|
|
|
ee47b4 |
* Check if input data is valid.
|
|
|
ee47b4 |
@@ -540,6 +619,7 @@ static struct vsi22 *vdp22_alloc_vsi_int(struct vdpnl_vsi *vsi,
|
|
|
ee47b4 |
fp->requestor.req_pid = vsi->req_pid;
|
|
|
ee47b4 |
fp->requestor.req_seq = vsi->req_seq;
|
|
|
ee47b4 |
}
|
|
|
ee47b4 |
+ vdpnl_alloc_vsi_oui(vsi, p);
|
|
|
ee47b4 |
*rc = 0;
|
|
|
ee47b4 |
LLDPAD_DBG("%s:%s vsi:%p(%02x)\n", __func__, vsi->ifname, p, p->vsi[0]);
|
|
|
ee47b4 |
return p;
|
|
|
ee47b4 |
@@ -1113,3 +1193,82 @@ void copy_vsi_external(struct vdpnl_vsi *vsi, struct vsi22 *p, int clif)
|
|
|
ee47b4 |
{
|
|
|
ee47b4 |
copy_vsi(vsi, p, clif);
|
|
|
ee47b4 |
}
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
+/*
|
|
|
ee47b4 |
+ * This is called by the ORG specific code to register its handlers.
|
|
|
ee47b4 |
+ */
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
+bool oui_vdp_hndlr_init(struct vdp22_oui_handler_s *handler_ptr)
|
|
|
ee47b4 |
+{
|
|
|
ee47b4 |
+ if (!handler_ptr) {
|
|
|
ee47b4 |
+ LLDPAD_DBG("%s: NULL handler\n", __func__);
|
|
|
ee47b4 |
+ return false;
|
|
|
ee47b4 |
+ }
|
|
|
ee47b4 |
+ memcpy(&(vdp22_oui_list[g_oui_index]), handler_ptr,
|
|
|
ee47b4 |
+ sizeof(vdp22_oui_list[g_oui_index]));
|
|
|
ee47b4 |
+ g_oui_index++;
|
|
|
ee47b4 |
+ return true;
|
|
|
ee47b4 |
+}
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
+/*
|
|
|
ee47b4 |
+ * This calls the ORG specific init function. Then the ORG specific init
|
|
|
ee47b4 |
+ * function registers its handlers.
|
|
|
ee47b4 |
+ */
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
+static void vdp22_oui_init(char *oui_name)
|
|
|
ee47b4 |
+{
|
|
|
ee47b4 |
+ int total;
|
|
|
ee47b4 |
+ int idx;
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
+ total = sizeof(vdp22_oui_init_list) / sizeof(vdp22_oui_init_list[0]);
|
|
|
ee47b4 |
+ for (idx = 0; idx < total; idx++) {
|
|
|
ee47b4 |
+ if (!strncmp(vdp22_oui_init_list[idx].oui_name, oui_name,
|
|
|
ee47b4 |
+ sizeof(vdp22_oui_init_list[idx].oui_name))) {
|
|
|
ee47b4 |
+ if (!vdp22_oui_init_list[idx].oui_init())
|
|
|
ee47b4 |
+ LLDPAD_ERR("%s: oui init return error for OUI "
|
|
|
ee47b4 |
+ "%s\n", __func__, oui_name);
|
|
|
ee47b4 |
+ }
|
|
|
ee47b4 |
+ }
|
|
|
ee47b4 |
+}
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
+static struct vdp22_oui_handler_s *get_oui_hndlr_internal(char *oui_name)
|
|
|
ee47b4 |
+{
|
|
|
ee47b4 |
+ int total;
|
|
|
ee47b4 |
+ int idx;
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
+ total = g_oui_index;
|
|
|
ee47b4 |
+ for (idx = 0; idx < total; idx++) {
|
|
|
ee47b4 |
+ if (!strncmp(vdp22_oui_list[idx].oui_name, oui_name,
|
|
|
ee47b4 |
+ sizeof(vdp22_oui_list[idx].oui_name)))
|
|
|
ee47b4 |
+ return &vdp22_oui_list[idx];
|
|
|
ee47b4 |
+ }
|
|
|
ee47b4 |
+ return NULL;
|
|
|
ee47b4 |
+}
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
+/*
|
|
|
ee47b4 |
+ * Return the handler structure associated with this OUI.
|
|
|
ee47b4 |
+ * If the handler is already registered, then get_oui_hndlr_internal function
|
|
|
ee47b4 |
+ * will return it. Otherwise, vdp22_oui_init is called so that the handler
|
|
|
ee47b4 |
+ * init function is called which will register its handlers. This is done so
|
|
|
ee47b4 |
+ * that the ORG specific handlers are registered only on demand.
|
|
|
ee47b4 |
+ */
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
+struct vdp22_oui_handler_s *vdp22_get_oui_hndlr(char *oui_name)
|
|
|
ee47b4 |
+{
|
|
|
ee47b4 |
+ struct vdp22_oui_handler_s *hndlr;
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
+ if (oui_name == NULL) {
|
|
|
ee47b4 |
+ LLDPAD_ERR("%s: NULL arg\n", __func__);
|
|
|
ee47b4 |
+ return NULL;
|
|
|
ee47b4 |
+ }
|
|
|
ee47b4 |
+ /*
|
|
|
ee47b4 |
+ * First check if the handler exists.
|
|
|
ee47b4 |
+ * If not the OUI plugin is probably not initialized
|
|
|
ee47b4 |
+ * Initialize the handlers
|
|
|
ee47b4 |
+ */
|
|
|
ee47b4 |
+ hndlr = get_oui_hndlr_internal(oui_name);
|
|
|
ee47b4 |
+ if (hndlr != NULL)
|
|
|
ee47b4 |
+ return hndlr;
|
|
|
ee47b4 |
+ vdp22_oui_init(oui_name);
|
|
|
ee47b4 |
+ return get_oui_hndlr_internal(oui_name);
|
|
|
ee47b4 |
+}
|
|
|
ee47b4 |
diff --git a/qbg/vdp22_cmds.c b/qbg/vdp22_cmds.c
|
|
|
ee47b4 |
index 5d5ef6b..5b5788f 100644
|
|
|
ee47b4 |
--- a/qbg/vdp22_cmds.c
|
|
|
ee47b4 |
+++ b/qbg/vdp22_cmds.c
|
|
|
ee47b4 |
@@ -356,20 +356,25 @@ static int get_vdp22_retval(int rc)
|
|
|
ee47b4 |
}
|
|
|
ee47b4 |
}
|
|
|
ee47b4 |
|
|
|
ee47b4 |
-static int set_arg_vsi3(struct cmd *cmd, char *argvalue, bool test, int size)
|
|
|
ee47b4 |
+static int set_arg_vsi3(struct cmd *cmd, char *argvalue, bool test, int size,
|
|
|
ee47b4 |
+ int oui_size)
|
|
|
ee47b4 |
{
|
|
|
ee47b4 |
cmd_status good_cmd = vdp22_cmdok(cmd, cmd_settlv);
|
|
|
ee47b4 |
int rc;
|
|
|
ee47b4 |
struct vdpnl_vsi vsi;
|
|
|
ee47b4 |
struct vdpnl_mac mac[size];
|
|
|
ee47b4 |
+ struct vdpnl_oui_data_s oui[oui_size];
|
|
|
ee47b4 |
|
|
|
ee47b4 |
if (good_cmd != cmd_success)
|
|
|
ee47b4 |
return good_cmd;
|
|
|
ee47b4 |
|
|
|
ee47b4 |
memset(&vsi, 0, sizeof(vsi));
|
|
|
ee47b4 |
memset(&mac, 0, sizeof(mac));
|
|
|
ee47b4 |
+ memset(&oui, 0, sizeof(oui));
|
|
|
ee47b4 |
vsi.maclist = mac;
|
|
|
ee47b4 |
vsi.macsz = size;
|
|
|
ee47b4 |
+ vsi.oui_list = (struct vdpnl_oui_data_s *)oui;
|
|
|
ee47b4 |
+ vsi.ouisz = oui_size;
|
|
|
ee47b4 |
rc = vdp_str2vdpnl(argvalue, &vsi, cmd->ifname);
|
|
|
ee47b4 |
if (rc) {
|
|
|
ee47b4 |
good_cmd = get_vdp22_retval(rc);
|
|
|
ee47b4 |
@@ -392,11 +397,12 @@ out:
|
|
|
ee47b4 |
static int set_arg_vsi2(struct cmd *cmd, char *argvalue, bool test)
|
|
|
ee47b4 |
{
|
|
|
ee47b4 |
int no = (cmd->ops >> OP_FID_POS) & 0xff;
|
|
|
ee47b4 |
+ int oui_no = (cmd->ops >> OP_OUI_POS) & 0xff;
|
|
|
ee47b4 |
|
|
|
ee47b4 |
if (no <= 0)
|
|
|
ee47b4 |
return -EINVAL;
|
|
|
ee47b4 |
if ((cmd->ops & op_arg) && (cmd->ops & op_argval))
|
|
|
ee47b4 |
- return set_arg_vsi3(cmd, argvalue, test, no);
|
|
|
ee47b4 |
+ return set_arg_vsi3(cmd, argvalue, test, no, oui_no);
|
|
|
ee47b4 |
else /* Not supported for now */
|
|
|
ee47b4 |
return cmd_failed;
|
|
|
ee47b4 |
}
|
|
|
ee47b4 |
diff --git a/qbg/vdp22sm.c b/qbg/vdp22sm.c
|
|
|
ee47b4 |
index 83a97fb..db0e413 100644
|
|
|
ee47b4 |
--- a/qbg/vdp22sm.c
|
|
|
ee47b4 |
+++ b/qbg/vdp22sm.c
|
|
|
ee47b4 |
@@ -184,6 +184,33 @@ static inline size_t vsi22_ptlv_sz(struct vsi22 *vp)
|
|
|
ee47b4 |
}
|
|
|
ee47b4 |
|
|
|
ee47b4 |
/*
|
|
|
ee47b4 |
+ * This function calls the registered OUI handlers that returns the size of
|
|
|
ee47b4 |
+ * the OUI data.
|
|
|
ee47b4 |
+ */
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
+static inline size_t oui22_ptlv_sz(struct vsi22 *vp)
|
|
|
ee47b4 |
+{
|
|
|
ee47b4 |
+ struct vdp22_oui_handler_s *oui_hndlr;
|
|
|
ee47b4 |
+ struct vdp22_oui_data_s *oui_str;
|
|
|
ee47b4 |
+ size_t size = 0;
|
|
|
ee47b4 |
+ int idx;
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
+ if (vp->no_ouidata == 0)
|
|
|
ee47b4 |
+ return 0;
|
|
|
ee47b4 |
+ for (idx = 0; idx < vp->no_ouidata; idx++) {
|
|
|
ee47b4 |
+ oui_str = &(vp->oui_str_data[idx]);
|
|
|
ee47b4 |
+ oui_hndlr = vdp22_get_oui_hndlr(oui_str->oui_name);
|
|
|
ee47b4 |
+ if (!oui_hndlr) {
|
|
|
ee47b4 |
+ LLDPAD_ERR("%s: No handler registered for OUI %s\n",
|
|
|
ee47b4 |
+ __func__, oui_str->oui_name);
|
|
|
ee47b4 |
+ continue;
|
|
|
ee47b4 |
+ }
|
|
|
ee47b4 |
+ size += oui_hndlr->oui_ptlv_size_hndlr(oui_str->data);
|
|
|
ee47b4 |
+ }
|
|
|
ee47b4 |
+ return size;
|
|
|
ee47b4 |
+}
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
+/*
|
|
|
ee47b4 |
* Extract 1, 2, 3, 4 byte integers in network byte format.
|
|
|
ee47b4 |
* Extract n bytes.
|
|
|
ee47b4 |
* Assume enough space available.
|
|
|
ee47b4 |
@@ -309,6 +336,29 @@ static size_t vsi22_2tlv_fdata(unsigned char *cp, struct fid22 *p,
|
|
|
ee47b4 |
return nbytes;
|
|
|
ee47b4 |
}
|
|
|
ee47b4 |
|
|
|
ee47b4 |
+static void oui22_2tlv(struct vsi22 *vp, char unsigned *cp)
|
|
|
ee47b4 |
+{
|
|
|
ee47b4 |
+ struct vdp22_oui_handler_s *oui_hndlr;
|
|
|
ee47b4 |
+ struct vdp22_oui_data_s *oui_str;
|
|
|
ee47b4 |
+ size_t offset = 0;
|
|
|
ee47b4 |
+ size_t temp_offset = 0;
|
|
|
ee47b4 |
+ int idx;
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
+ if (vp->no_ouidata == 0)
|
|
|
ee47b4 |
+ return;
|
|
|
ee47b4 |
+ for (idx = 0; idx < vp->no_ouidata; idx++) {
|
|
|
ee47b4 |
+ oui_str = &(vp->oui_str_data[idx]);
|
|
|
ee47b4 |
+ oui_hndlr = vdp22_get_oui_hndlr(oui_str->oui_name);
|
|
|
ee47b4 |
+ if (!oui_hndlr) {
|
|
|
ee47b4 |
+ LLDPAD_ERR("%s: No handler registered for OUI %s\n",
|
|
|
ee47b4 |
+ __func__, oui_str->oui_name);
|
|
|
ee47b4 |
+ continue;
|
|
|
ee47b4 |
+ }
|
|
|
ee47b4 |
+ temp_offset = oui_hndlr->vdp_tx_hndlr(cp, oui_str, offset);
|
|
|
ee47b4 |
+ offset += temp_offset;
|
|
|
ee47b4 |
+ }
|
|
|
ee47b4 |
+}
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
static void vsi22_2tlv(struct vsi22 *vp, char unsigned *cp, unsigned char stat)
|
|
|
ee47b4 |
{
|
|
|
ee47b4 |
size_t offset = 0, i;
|
|
|
ee47b4 |
@@ -478,7 +528,8 @@ static void vdp22st_wait_syscmd(struct vsi22 *vsip)
|
|
|
ee47b4 |
*/
|
|
|
ee47b4 |
static void vdp22st_process(struct vsi22 *vsi)
|
|
|
ee47b4 |
{
|
|
|
ee47b4 |
- unsigned short len = mgr22_ptlv_sz() + vsi22_ptlv_sz(vsi);
|
|
|
ee47b4 |
+ unsigned short len = mgr22_ptlv_sz() + vsi22_ptlv_sz(vsi) +
|
|
|
ee47b4 |
+ oui22_ptlv_sz(vsi);
|
|
|
ee47b4 |
unsigned char buf[len];
|
|
|
ee47b4 |
struct qbg22_imm qbg;
|
|
|
ee47b4 |
|
|
|
ee47b4 |
@@ -487,6 +538,7 @@ static void vdp22st_process(struct vsi22 *vsi)
|
|
|
ee47b4 |
qbg.u.c.data = buf;
|
|
|
ee47b4 |
mgr22_2tlv(vsi, buf);
|
|
|
ee47b4 |
vsi22_2tlv(vsi, buf + mgr22_ptlv_sz(), vsi->hints);
|
|
|
ee47b4 |
+ oui22_2tlv(vsi, buf + mgr22_ptlv_sz() + vsi22_ptlv_sz(vsi));
|
|
|
ee47b4 |
vsi->smi.txmit_error = modules_notify(LLDP_MOD_ECP22, LLDP_MOD_VDP22,
|
|
|
ee47b4 |
vsi->vdp->ifname, &qbg);
|
|
|
ee47b4 |
if (!vsi->smi.txmit_error) {
|
|
|
ee47b4 |
diff --git a/qbg/vdp_ascii.c b/qbg/vdp_ascii.c
|
|
|
ee47b4 |
index 70ec79b..80a4419 100644
|
|
|
ee47b4 |
--- a/qbg/vdp_ascii.c
|
|
|
ee47b4 |
+++ b/qbg/vdp_ascii.c
|
|
|
ee47b4 |
@@ -54,7 +54,8 @@ struct vsi_keyword_handler vsi_key_handle[] = {
|
|
|
ee47b4 |
/* {VSI22_ARG_VSIIDFRMT_STR, VSI_VSIIDFRMT_ARG}, TODO*/
|
|
|
ee47b4 |
{VSI22_ARG_VSIID_STR, VSI_VSIID_ARG},
|
|
|
ee47b4 |
{VSI22_ARG_HINTS_STR, VSI_HINTS_ARG},
|
|
|
ee47b4 |
- {VSI22_ARG_FILTER_STR, VSI_FILTER_ARG} };
|
|
|
ee47b4 |
+ {VSI22_ARG_FILTER_STR, VSI_FILTER_ARG},
|
|
|
ee47b4 |
+ {VSI22_ARG_OUI_STR, VSI_OUI_ARG} };
|
|
|
ee47b4 |
|
|
|
ee47b4 |
/*
|
|
|
ee47b4 |
* Check if it is a UUID and consists of hexadecimal digits and dashes only.
|
|
|
ee47b4 |
@@ -225,6 +226,33 @@ static bool gethints(struct vdpnl_vsi *p, char *s)
|
|
|
ee47b4 |
return true;
|
|
|
ee47b4 |
}
|
|
|
ee47b4 |
|
|
|
ee47b4 |
+static bool oui_str2vdpnl(struct vdpnl_vsi *vsi, char *p, unsigned short idx)
|
|
|
ee47b4 |
+{
|
|
|
ee47b4 |
+ struct vdp22_oui_handler_s *oui_hndlr;
|
|
|
ee47b4 |
+ char *temp_argval = p;
|
|
|
ee47b4 |
+ char *oui_val;
|
|
|
ee47b4 |
+ char oui_name[VDP22_OUI_MAX_NAME];
|
|
|
ee47b4 |
+ u8 oui_name_len;
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
+ hexstr2bin(p, &oui_name_len, sizeof(oui_name_len));
|
|
|
ee47b4 |
+ if (oui_name_len >= VDP22_OUI_MAX_NAME)
|
|
|
ee47b4 |
+ return false;
|
|
|
ee47b4 |
+ temp_argval = p + 2 * sizeof(oui_name_len);
|
|
|
ee47b4 |
+ oui_val = temp_argval + oui_name_len;
|
|
|
ee47b4 |
+ strncpy(oui_name, temp_argval, oui_name_len);
|
|
|
ee47b4 |
+ oui_name[oui_name_len] = '\0';
|
|
|
ee47b4 |
+ oui_hndlr = vdp22_get_oui_hndlr(oui_name);
|
|
|
ee47b4 |
+ if (!oui_hndlr)
|
|
|
ee47b4 |
+ return false;
|
|
|
ee47b4 |
+ strncpy(vsi->oui_list[idx].oui_name, oui_name,
|
|
|
ee47b4 |
+ sizeof(vsi->oui_list[idx].oui_name));
|
|
|
ee47b4 |
+ if (oui_hndlr->str2vdpnl_hndlr)
|
|
|
ee47b4 |
+ return oui_hndlr->str2vdpnl_hndlr(&(vsi->oui_list[idx]),
|
|
|
ee47b4 |
+ oui_val);
|
|
|
ee47b4 |
+ else
|
|
|
ee47b4 |
+ return false;
|
|
|
ee47b4 |
+}
|
|
|
ee47b4 |
+
|
|
|
ee47b4 |
/*
|
|
|
ee47b4 |
* Read VSI association mode. If can be followed by an error code in brackets.
|
|
|
ee47b4 |
* For vdp22 protocol the allowed words are assoc, preassoc, preassoc-rr and
|
|
|
ee47b4 |
@@ -315,7 +343,7 @@ int vdp22_parse_str_vdpnl(struct vdpnl_vsi *vsi, u16 *key_flags,
|
|
|
ee47b4 |
int i, ioff = 0, numargs;
|
|
|
ee47b4 |
int ilen = strlen(orig_argvalue);
|
|
|
ee47b4 |
unsigned int no;
|
|
|
ee47b4 |
- unsigned short idx = 0;
|
|
|
ee47b4 |
+ unsigned short idx = 0, oui_idx = 0;
|
|
|
ee47b4 |
u16 num_arg_keys = 0;
|
|
|
ee47b4 |
|
|
|
ee47b4 |
argvalue = strdup(orig_argvalue);
|
|
|
ee47b4 |
@@ -373,6 +401,11 @@ int vdp22_parse_str_vdpnl(struct vdpnl_vsi *vsi, u16 *key_flags,
|
|
|
ee47b4 |
if (!argvals[i] || !gethints(vsi, argvals[i]))
|
|
|
ee47b4 |
goto out_err;
|
|
|
ee47b4 |
break;
|
|
|
ee47b4 |
+ case VSI_OUI_ARG:
|
|
|
ee47b4 |
+ if (!oui_str2vdpnl(vsi, argvals[i], oui_idx))
|
|
|
ee47b4 |
+ goto out_err;
|
|
|
ee47b4 |
+ oui_idx++;
|
|
|
ee47b4 |
+ break;
|
|
|
ee47b4 |
default:
|
|
|
ee47b4 |
goto out_err;
|
|
|
ee47b4 |
}
|
|
|
ee47b4 |
--
|
|
|
ee47b4 |
2.1.0
|
|
|
ee47b4 |
|