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.
333 lines
10 KiB
333 lines
10 KiB
From 0bc166920c14081ed90d4774a52ca38813fc1739 Mon Sep 17 00:00:00 2001 |
|
From: padkrish <padkrish@cisco.com> |
|
Date: Wed, 21 Jan 2015 03:40:52 +0000 |
|
Subject: [PATCH] VDP: Changes in OUI infra for get-tlv |
|
|
|
Changes made in OUI infra code to support retrieving OUI parameters |
|
during get-tlv |
|
|
|
Signed-off-by: padkrish <padkrish@cisco.com> |
|
Signed-off-by: John Fastabend <john.r.fastabend@intel.com> |
|
--- |
|
include/qbg_vdp22_oui.h | 7 +++++++ |
|
include/qbg_vdpnl.h | 1 + |
|
qbg/vdp22.c | 32 ++++++++++++++++++++++++++++++++ |
|
qbg/vdp22_cmds.c | 4 ++++ |
|
qbg/vdp22_oui.c | 5 +++++ |
|
qbg/vdp_ascii.c | 37 +++++++++++++++++++++++++++++++++++++ |
|
qbg/vdpnl.c | 14 ++++++++++++++ |
|
vdptool.c | 38 ++++++++++++++++++++++++++++++++++---- |
|
8 files changed, 134 insertions(+), 4 deletions(-) |
|
|
|
diff --git a/include/qbg_vdp22_oui.h b/include/qbg_vdp22_oui.h |
|
index 79e1ff5..923e19f 100644 |
|
--- a/include/qbg_vdp22_oui.h |
|
+++ b/include/qbg_vdp22_oui.h |
|
@@ -53,6 +53,7 @@ typedef struct vdptool_oui_data_s { |
|
typedef struct vdptool_oui_hndlr_tbl_s { |
|
char *oui_name; |
|
bool (*oui_cli_encode_hndlr)(char *dst, char *src, size_t len); |
|
+ void (*oui_print_decode_hndlr)(char *dst); |
|
} vdptool_oui_hndlr_tbl_t; |
|
|
|
struct vdpnl_oui_data_s { |
|
@@ -81,6 +82,11 @@ struct vdp22_oui_handler_s { |
|
/* This handler converts the vdpnl structure to vsi22 structure */ |
|
bool (*vdpnl2vsi22_hndlr)(void *, struct vdpnl_oui_data_s *, |
|
struct vdp22_oui_data_s *); |
|
+ /* This handler converts the vdpnl structure to string */ |
|
+ bool (*vdpnl2str_hndlr)(struct vdpnl_oui_data_s *, char *, |
|
+ int *, int); |
|
+ bool (*vsi2vdpnl_hndlr)(void *, struct vdp22_oui_data_s *, |
|
+ struct vdpnl_oui_data_s *); |
|
/* This handler creates the OUI fields for Tx */ |
|
size_t (*vdp_tx_hndlr)(char unsigned *, |
|
struct vdp22_oui_data_s *, size_t); |
|
@@ -95,6 +101,7 @@ struct vdp22_oui_handler_s { |
|
unsigned char vdp22_oui_get_vsi22_fmt(void *); |
|
unsigned char *vdp22_oui_get_vsi22_len(void *, unsigned char *); |
|
int oui_vdp_str2uuid(unsigned char *, char *, size_t); |
|
+int oui_vdp_uuid2str(unsigned char *, char *, size_t); |
|
bool oui_vdp_hndlr_init(struct vdp22_oui_handler_s *); |
|
int oui_vdp_hexstr2bin(const char *hex, unsigned char *buf, size_t len); |
|
|
|
diff --git a/include/qbg_vdpnl.h b/include/qbg_vdpnl.h |
|
index bf18e71..cb7efca 100644 |
|
--- a/include/qbg_vdpnl.h |
|
+++ b/include/qbg_vdpnl.h |
|
@@ -81,6 +81,7 @@ int vdp_str2vdpnl(char *, struct vdpnl_vsi *, char *); |
|
int vdp_vdpnl2str(struct vdpnl_vsi *, char *, size_t); |
|
int vdp22_sendevent(struct vdpnl_vsi *); |
|
void vdp22_freemaclist(struct vdpnl_vsi *); |
|
+void vsinl_delete_oui(struct vdpnl_vsi *); |
|
int vdp22_parse_str_vdpnl(struct vdpnl_vsi *, unsigned short *, char *); |
|
struct vsi22 *vdp22_alloc_vsi_ext(struct vdpnl_vsi *, int *); |
|
void copy_vsi_external(struct vdpnl_vsi *, struct vsi22 *, int); |
|
diff --git a/qbg/vdp22.c b/qbg/vdp22.c |
|
index ab170ed..10b80a4 100644 |
|
--- a/qbg/vdp22.c |
|
+++ b/qbg/vdp22.c |
|
@@ -1010,6 +1010,37 @@ static void copy_fid(struct vdpnl_vsi *vsi, struct vsi22 *p) |
|
} |
|
|
|
/* |
|
+ * This function copies the OUI from VSI22 to vdpnl structure. |
|
+ */ |
|
+ |
|
+static void copy_oui(struct vdpnl_vsi *vsi, struct vsi22 *p) |
|
+{ |
|
+ struct vdp22_oui_handler_s *oui_hndlr; |
|
+ bool ret; |
|
+ int idx; |
|
+ |
|
+ vsi->oui_list = calloc(p->no_ouidata, sizeof(*vsi->oui_list)); |
|
+ if (!vsi->oui_list) |
|
+ return; |
|
+ vsi->ouisz = p->no_ouidata; |
|
+ for (idx = 0; idx < p->no_ouidata; idx++) { |
|
+ struct vdpnl_oui_data_s *to = &vsi->oui_list[idx]; |
|
+ struct vdp22_oui_data_s *from = &p->oui_str_data[idx]; |
|
+ |
|
+ oui_hndlr = vdp22_get_oui_hndlr(from->oui_name); |
|
+ if (oui_hndlr == NULL) { |
|
+ LLDPAD_ERR("%s: No handler registered for OUI %s\n", |
|
+ __func__, from->oui_name); |
|
+ continue; |
|
+ } |
|
+ ret = oui_hndlr->vsi2vdpnl_hndlr(p, from, to); |
|
+ if (!ret) |
|
+ LLDPAD_ERR("%s: handler return error for oui %s\n", |
|
+ __func__, from->oui_name); |
|
+ } |
|
+} |
|
+ |
|
+/* |
|
* Fill the VSI data to return to caller. Currently returned data depends |
|
* on requestor: |
|
* 1. Via netlink message from libvirtd and vdptest: |
|
@@ -1033,6 +1064,7 @@ static void copy_vsi(struct vdpnl_vsi *vsi, struct vsi22 *p, int clif) |
|
if (clif || (p->flags & VDP22_RETURN_VID)) { |
|
copy_fid(vsi, p); |
|
p->flags &= ~VDP22_RETURN_VID; |
|
+ copy_oui(vsi, p); |
|
} |
|
} |
|
|
|
diff --git a/qbg/vdp22_cmds.c b/qbg/vdp22_cmds.c |
|
index 5b5788f..79ea9ca 100644 |
|
--- a/qbg/vdp22_cmds.c |
|
+++ b/qbg/vdp22_cmds.c |
|
@@ -434,6 +434,7 @@ static int catvsis(struct vdpnl_vsi *vsi, char *out, size_t out_len) |
|
for (i = 1; vdp22_status(i, vsi, 1) > 0; ++i) { |
|
if (wanted_req != vsi->request) { |
|
vdp22_freemaclist(vsi); |
|
+ vsinl_delete_oui(vsi); |
|
continue; |
|
} |
|
rc = vdp_vdpnl2str(vsi, tmp_buf, out_len - used); |
|
@@ -443,6 +444,7 @@ static int catvsis(struct vdpnl_vsi *vsi, char *out, size_t out_len) |
|
if ((c < 0) || ((unsigned)c >= (out_len - used))) |
|
return 0; |
|
vdp22_freemaclist(vsi); |
|
+ vsinl_delete_oui(vsi); |
|
if (rc) { |
|
used = strlen(out); |
|
} else |
|
@@ -533,6 +535,8 @@ static int get_vsi_partial_arg(UNUSED char *arg, char *orig_argvalue, |
|
len = strlen(tmp_buf); |
|
c = snprintf(out + used, out_len - used, "%04x%s", |
|
len, tmp_buf); |
|
+ vdp22_freemaclist(vsinl); |
|
+ vsinl_delete_oui(vsinl); |
|
if ((c < 0) || ((unsigned)c >= (out_len - used))) |
|
goto out_delvsi; |
|
if (rc) |
|
diff --git a/qbg/vdp22_oui.c b/qbg/vdp22_oui.c |
|
index 3a2d0cc..4960324 100644 |
|
--- a/qbg/vdp22_oui.c |
|
+++ b/qbg/vdp22_oui.c |
|
@@ -57,6 +57,11 @@ int oui_vdp_str2uuid(unsigned char *to, char *buffer, size_t max) |
|
return vdp_str2uuid(to, buffer, max); |
|
} |
|
|
|
+int oui_vdp_uuid2str(unsigned char *from, char *buffer, size_t max) |
|
+{ |
|
+ return vdp_uuid2str(from, buffer, max); |
|
+} |
|
+ |
|
int oui_vdp_hexstr2bin(const char *hex, unsigned char *buf, size_t len) |
|
{ |
|
return hexstr2bin(hex, buf, len); |
|
diff --git a/qbg/vdp_ascii.c b/qbg/vdp_ascii.c |
|
index 80a4419..709ffd9 100644 |
|
--- a/qbg/vdp_ascii.c |
|
+++ b/qbg/vdp_ascii.c |
|
@@ -244,6 +244,10 @@ static bool oui_str2vdpnl(struct vdpnl_vsi *vsi, char *p, unsigned short idx) |
|
oui_hndlr = vdp22_get_oui_hndlr(oui_name); |
|
if (!oui_hndlr) |
|
return false; |
|
+ if (!vsi->oui_list) { |
|
+ LLDPAD_ERR("%s: Null OUI List\n", __func__); |
|
+ return false; |
|
+ } |
|
strncpy(vsi->oui_list[idx].oui_name, oui_name, |
|
sizeof(vsi->oui_list[idx].oui_name)); |
|
if (oui_hndlr->str2vdpnl_hndlr) |
|
@@ -597,11 +601,16 @@ static void mgrid2str(char *to, struct vdpnl_vsi *p, size_t to_len) |
|
/* |
|
* Convert a vdpnl_vsi to string. |
|
*/ |
|
+ |
|
int vdp_vdpnl2str(struct vdpnl_vsi *p, char *s, size_t length) |
|
{ |
|
int c, i; |
|
size_t total = 0; |
|
char instance[VDP_UUID_STRLEN + 2]; |
|
+ struct vdp22_oui_handler_s *oui_hndlr; |
|
+ int oui_total = 0; |
|
+ int ret; |
|
+ int idx; |
|
|
|
mgrid2str(instance, p, sizeof(instance)); |
|
c = snprintf(s, length, "%02x%s%04x%s%02x%s%04x%s%02x%s%04x%lu%02x%s" |
|
@@ -642,6 +651,34 @@ int vdp_vdpnl2str(struct vdpnl_vsi *p, char *s, size_t length) |
|
if (!c) |
|
goto out; |
|
} |
|
+ for (idx = 0; idx < p->ouisz; idx++) { |
|
+ struct vdpnl_oui_data_s *from = &p->oui_list[idx]; |
|
+ |
|
+ oui_total = 0; |
|
+ oui_hndlr = vdp22_get_oui_hndlr(from->oui_name); |
|
+ if (oui_hndlr == NULL) { |
|
+ LLDPAD_ERR("%s: Unknown OUI Name %s\n", __func__, |
|
+ from->oui_name); |
|
+ } else { |
|
+ c = snprintf(s, length, "%02x%s", |
|
+ (unsigned int)strlen(VSI22_ARG_OUI_STR), |
|
+ VSI22_ARG_OUI_STR); |
|
+ s = check_and_update(&total, &length, s, c); |
|
+ if (!s) |
|
+ goto out; |
|
+ ret = oui_hndlr->vdpnl2str_hndlr(from, s, &oui_total, |
|
+ length); |
|
+ if (!ret) { |
|
+ LLDPAD_ERR("%s: handler return error for " |
|
+ "oui %s\n", __func__, |
|
+ from->oui_name); |
|
+ goto out; |
|
+ } |
|
+ s = check_and_update(&total, &length, s, oui_total); |
|
+ if (!s) |
|
+ goto out; |
|
+ } |
|
+ } |
|
|
|
out: |
|
return s ? total : 0; |
|
diff --git a/qbg/vdpnl.c b/qbg/vdpnl.c |
|
index 5c0ffd4..9b8fcdd 100644 |
|
--- a/qbg/vdpnl.c |
|
+++ b/qbg/vdpnl.c |
|
@@ -365,6 +365,19 @@ static int vdpnl_get(struct vdpnl_vsi *p, struct nlmsghdr *nlh) |
|
} |
|
|
|
/* |
|
+ * Delete the OUI structures of VSI22 |
|
+ */ |
|
+ |
|
+void vsinl_delete_oui(struct vdpnl_vsi *p) |
|
+{ |
|
+ if ((p->ouisz == 0) || (p->oui_list == NULL)) |
|
+ return; |
|
+ p->ouisz = 0; |
|
+ free(p->oui_list); |
|
+ p->oui_list = NULL; |
|
+} |
|
+ |
|
+/* |
|
* Free an malloc'ed maclist array. |
|
*/ |
|
void vdp22_freemaclist(struct vdpnl_vsi *vsi) |
|
@@ -419,6 +432,7 @@ static int vdpnl_getlink(struct nlmsghdr *nlh, size_t len) |
|
nla_nest_end(msg, vf_port); |
|
} |
|
vdp22_freemaclist(&p); |
|
+ vsinl_delete_oui(&p); |
|
} while (rc == 1); |
|
nla_nest_end(msg, vf_ports); |
|
if (rc < 0) { |
|
diff --git a/vdptool.c b/vdptool.c |
|
index 8edd6ca..b805372 100644 |
|
--- a/vdptool.c |
|
+++ b/vdptool.c |
|
@@ -58,8 +58,11 @@ |
|
#include "qbg_vdp22_oui.h" |
|
|
|
#define OUI_ENCODE_HNDLR(name) name##_oui_encode_hndlr |
|
+#define OUI_PRNT_DECODE_HNDLR(name) name##_oui_print_decode_hndlr |
|
+ |
|
#define EXTERN_OUI_FN(name) \ |
|
- extern bool name##_oui_encode_hndlr(char *, char *, size_t) |
|
+ extern bool name##_oui_encode_hndlr(char *, char *, size_t); \ |
|
+ extern void name##_oui_print_decode_hndlr(char *) |
|
|
|
/* The handler declaration for encoding OUI specific information should be |
|
* here. The corresponding decoder handler should be in lldpad. |
|
@@ -70,7 +73,7 @@ EXTERN_OUI_FN(cisco); |
|
/* The OUI specific handlers should be added here */ |
|
|
|
vdptool_oui_hndlr_tbl_t oui_hndlr_tbl[] = { |
|
- {"cisco", OUI_ENCODE_HNDLR(cisco)} |
|
+ {"cisco", OUI_ENCODE_HNDLR(cisco), OUI_PRNT_DECODE_HNDLR(cisco)} |
|
}; |
|
|
|
|
|
@@ -508,6 +511,29 @@ void print_vsi_err_msg(char *key_val) |
|
printf("\tInternal Error : %s\n", VSI22_TX_ERR_STR); |
|
} |
|
|
|
+static void print_oui_vals(char *argvals) |
|
+{ |
|
+ char oui_name[VDP22_OUI_MAX_NAME]; |
|
+ char *temp_argval = argvals; |
|
+ char *oui_val; |
|
+ int tbl_size, cnt; |
|
+ u8 oui_name_len; |
|
+ |
|
+ hexstr2bin(argvals, &oui_name_len, sizeof(oui_name_len)); |
|
+ if (oui_name_len >= VDP22_OUI_MAX_NAME) |
|
+ return; |
|
+ temp_argval = argvals + 2 * sizeof(oui_name_len); |
|
+ oui_val = temp_argval + oui_name_len; |
|
+ strncpy(oui_name, temp_argval, oui_name_len); |
|
+ oui_name[oui_name_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_name, |
|
+ VDP22_OUI_MAX_NAME)) |
|
+ oui_hndlr_tbl[cnt].oui_print_decode_hndlr(oui_val); |
|
+ } |
|
+} |
|
+ |
|
static void print_vsi(char **args, char **argvals, int numargs, |
|
bool err_flag) |
|
{ |
|
@@ -517,8 +543,12 @@ static void print_vsi(char **args, char **argvals, int numargs, |
|
if (err_flag && (!strcmp(args[i], VSI22_ARG_HINTS_STR))) |
|
print_vsi_err_msg(argvals[i]); |
|
else { |
|
- printf("\t%s", args[i]); |
|
- printf(" = %s\n", argvals[i]); |
|
+ if (!strcmp(args[i], VSI22_ARG_OUI_STR)) { |
|
+ print_oui_vals(argvals[i]); |
|
+ } else { |
|
+ printf("\t%s", args[i]); |
|
+ printf(" = %s\n", argvals[i]); |
|
+ } |
|
} |
|
} |
|
} |
|
-- |
|
2.1.0 |
|
|
|
|