From 0bc166920c14081ed90d4774a52ca38813fc1739 Mon Sep 17 00:00:00 2001 From: padkrish 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 Signed-off-by: John Fastabend --- 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