From ead7bc6267c87e0816ba2367b9036d8a647f3099 Mon Sep 17 00:00:00 2001 From: padkrish Date: Wed, 21 Jan 2015 03:41:14 +0000 Subject: [PATCH] VDP: Changes in Cisco OUI handlers to support get-tlv Signed-off-by: padkrish Signed-off-by: John Fastabend --- include/vdp_cisco.h | 22 ++++++++++ qbg/vdp22cisco_oui.c | 120 ++++++++++++++++++++++++++++++++++++++++++--------- vdptool_cisco_oui.c | 54 +++++++++++++++++++++++ 3 files changed, 175 insertions(+), 21 deletions(-) diff --git a/include/vdp_cisco.h b/include/vdp_cisco.h index 339d479..821db68 100644 --- a/include/vdp_cisco.h +++ b/include/vdp_cisco.h @@ -96,6 +96,7 @@ typedef union l3_addrtype_ { typedef struct vdp_cisco_oui_s { char key[KEYLEN]; /* Profile name */ u8 uuid[PORT_UUID_MAX]; /* Instance ID */ + bool uuid_set; size_t vm_name_len; char vm_name[MAX_VM_NAME]; u16 afi; @@ -103,10 +104,18 @@ typedef struct vdp_cisco_oui_s { l3_addr_t l3_addr; } vdp_cisco_oui_t; +struct oui_keyword_handler oui_key_handle[] = { + {CISCO_OUI_NAME_ARG_STR, CISCO_OUI_NAME_ARG}, + {CISCO_OUI_NAME_UUID_ARG_STR, CISCO_OUI_NAME_UUID_ARG}, + {CISCO_OUI_L3V4ADDR_ARG_STR, CISCO_OUI_L3V4ADDR_ARG} }; + bool cisco_str2vdpnl_hndlr(struct vdpnl_oui_data_s *, char *); bool cisco_vdp_free_oui(struct vdp22_oui_data_s *); bool cisco_vdpnl2vsi22_hndlr(void *, struct vdpnl_oui_data_s *, struct vdp22_oui_data_s *); +bool cisco_vdpnl2str_hndlr(struct vdpnl_oui_data_s *, char *, int *, int); +bool cisco_vsi2vdpnl_hndlr(void *, struct vdp22_oui_data_s *, + struct vdpnl_oui_data_s *); size_t cisco_vdp_tx_hndlr(char unsigned *, struct vdp22_oui_data_s *, size_t); bool cisco_vdp_rx_hndlr(); unsigned long cisco_vdp_oui_ptlvsize(void *); @@ -118,4 +127,17 @@ static inline void fill_cisco_oui_type(unsigned char *oui_type) oui_type[2] = 0x0c; } +enum oui_key_arg get_oui_key(char *token, u8 key_len) +{ + int count, key_str_size; + + key_str_size = sizeof(oui_key_handle) / sizeof(oui_key_handle[0]); + for (count = 0; count < key_str_size; count++) { + if ((key_len <= strlen(token)) && + (!strncmp(token, oui_key_handle[count].keyword, key_len))) + return oui_key_handle[count].val; + } + return CISCO_OUI_INVALID_ARG; +} + #endif /* __VDP22_VISCO_H__ */ diff --git a/qbg/vdp22cisco_oui.c b/qbg/vdp22cisco_oui.c index ef6c307..e8a824c 100644 --- a/qbg/vdp22cisco_oui.c +++ b/qbg/vdp22cisco_oui.c @@ -29,31 +29,14 @@ #include #include "messages.h" #include "qbg_vdp22def.h" +#include "qbg_utils.h" #include "vdp_cisco.h" struct vdp22_oui_handler_s cisco_oui_hndlr = { {0x00, 0x00, 0x0c}, "cisco", cisco_str2vdpnl_hndlr, - cisco_vdpnl2vsi22_hndlr, - cisco_vdp_tx_hndlr, cisco_vdp_rx_hndlr, cisco_vdp_free_oui, - cisco_vdp_oui_ptlvsize}; - -struct oui_keyword_handler oui_key_handle[] = { - {CISCO_OUI_NAME_ARG_STR, CISCO_OUI_NAME_ARG}, - {CISCO_OUI_NAME_UUID_ARG_STR, CISCO_OUI_NAME_UUID_ARG}, - {CISCO_OUI_L3V4ADDR_ARG_STR, CISCO_OUI_L3V4ADDR_ARG} }; - -enum oui_key_arg get_oui_key(char *token, u8 key_len) -{ - int count, key_str_size; - - key_str_size = sizeof(oui_key_handle) / sizeof(oui_key_handle[0]); - for (count = 0; count < key_str_size; count++) { - if ((key_len <= strlen(token)) && - (!strncmp(token, oui_key_handle[count].keyword, key_len))) - return oui_key_handle[count].val; - } - return CISCO_OUI_INVALID_ARG; -} + cisco_vdpnl2vsi22_hndlr, cisco_vdpnl2str_hndlr, + cisco_vsi2vdpnl_hndlr, cisco_vdp_tx_hndlr, cisco_vdp_rx_hndlr, + cisco_vdp_free_oui, cisco_vdp_oui_ptlvsize}; /* * This function fills the vdpnl structure of OUI from the command separated @@ -124,6 +107,7 @@ bool cisco_str2vdpnl_hndlr(struct vdpnl_oui_data_s *vdp_oui_p, char *token) sizeof(vdp_cisco_oui_p->uuid))) memset(vdp_cisco_oui_p->uuid, 0, sizeof(vdp_cisco_oui_p->uuid)); + vdp_cisco_oui_p->uuid_set = true; free(uuid); break; case CISCO_OUI_L3V4ADDR_ARG: @@ -193,6 +177,100 @@ bool cisco_vdpnl2vsi22_hndlr(void *vsi_data, struct vdpnl_oui_data_s *from, } /* + * This function converts the OUI information from vdpnl struct to string + */ + +bool cisco_vdpnl2str_hndlr(struct vdpnl_oui_data_s *from, char *out_buf, + int *total, int rem_len) +{ + char tmp_out_buf[MAX_OUI_DATA_LEN]; + char uuid_str[VDP_UUID_STRLEN + 2]; + char *tmp_oui_buf; + vdp_cisco_oui_t *vdp_cisco_oui_p; + int c = 0, num_str_bytes; + int tmp_buf_len = sizeof(tmp_out_buf); + + tmp_oui_buf = tmp_out_buf; + if ((from == NULL) || (out_buf == NULL)) { + LLDPAD_ERR("%s: NULL arg\n", __func__); + return false; + } + vdp_cisco_oui_p = (vdp_cisco_oui_t *)from->data; + c = snprintf(tmp_oui_buf, tmp_buf_len, "%02x%s", + (unsigned int)strlen("cisco"), "cisco"); + tmp_buf_len -= c; + tmp_oui_buf += c; + if (vdp_cisco_oui_p->vm_name_len != 0) { + c = snprintf(tmp_oui_buf, tmp_buf_len, + "%02x%s%04x%s", + (unsigned int)strlen(CISCO_OUI_NAME_ARG_STR), + CISCO_OUI_NAME_ARG_STR, + (unsigned int)vdp_cisco_oui_p->vm_name_len, + vdp_cisco_oui_p->vm_name); + if ((c < 0) || (c >= tmp_buf_len)) + return false; + tmp_buf_len -= c; + tmp_oui_buf += c; + } + if (vdp_cisco_oui_p->uuid_set) { + oui_vdp_uuid2str(vdp_cisco_oui_p->uuid, uuid_str, + sizeof(uuid_str)); + c = snprintf(tmp_oui_buf, tmp_buf_len, + "%02x%s%04x%s", + (unsigned int)strlen(CISCO_OUI_NAME_UUID_ARG_STR), + CISCO_OUI_NAME_UUID_ARG_STR, + (unsigned int)strlen(uuid_str), uuid_str); + if ((c < 0) || (c >= tmp_buf_len)) + return false; + tmp_buf_len -= c; + tmp_oui_buf += c; + } + if (vdp_cisco_oui_p->vm_addr_len != 0) { + num_str_bytes = snprintf(NULL, 0, "%ul", + vdp_cisco_oui_p->l3_addr. + ipv4_address.s_addr); + c = snprintf(tmp_oui_buf, tmp_buf_len, "%02x%s%04x%ul", + (unsigned int)strlen(CISCO_OUI_L3V4ADDR_ARG_STR), + CISCO_OUI_L3V4ADDR_ARG_STR, num_str_bytes, + vdp_cisco_oui_p->l3_addr.ipv4_address.s_addr); + if ((c < 0) || (c >= tmp_buf_len)) + return false; + tmp_buf_len -= c; + tmp_oui_buf += c; + } + c = snprintf(out_buf, rem_len, "%04x%s", + (unsigned int)strlen(tmp_out_buf), + tmp_out_buf); + if ((c < 0) || (c >= rem_len)) + return false; + rem_len -= c; + out_buf += c; + *total += c; + return true; +} + +/* + * This function converts the OUI information from vsi22 struct to vdpnl struct + * vsi is not used here, but can be used for storing the pointer to the parent + * struct + */ + +bool cisco_vsi2vdpnl_hndlr(UNUSED void *vsi_data, struct vdp22_oui_data_s *from, + struct vdpnl_oui_data_s *to) +{ + if ((from == NULL) || (to == NULL)) { + LLDPAD_ERR("%s: NULL arg\n", __func__); + return false; + } + memcpy(to->oui_type, from->oui_type, sizeof(to->oui_type)); + strncpy(to->oui_name, from->oui_name, sizeof(to->oui_name)); + to->len = from->len; + memcpy(to->data, from->data, to->len); + return true; +} + + +/* * This function deletes the OUI information associated with a VSI */ diff --git a/vdptool_cisco_oui.c b/vdptool_cisco_oui.c index 4a846ad..7003521 100644 --- a/vdptool_cisco_oui.c +++ b/vdptool_cisco_oui.c @@ -25,6 +25,7 @@ #include #include #include +#include "lldp_util.h" #include "vdp_cisco.h" bool cisco_oui_encode_hndlr(char *dst, char *src, int len) @@ -56,3 +57,56 @@ bool cisco_oui_encode_hndlr(char *dst, char *src, int len) return flag; } +void cisco_oui_print_decode_hndlr(char *token) +{ + struct in_addr vm_inet; + char *v4_addr_str; + unsigned long vm_ip_addr; + int offset = 0, len; + u16 data_len; + u8 key_len; + enum oui_key_arg oui_argtype; + + if (token == NULL) + return; + len = strlen(token); + while (offset < len) { + hexstr2bin(token, &key_len, sizeof(key_len)); + token += 2; + offset += 2; + oui_argtype = get_oui_key(token, key_len); + token += key_len; + offset += key_len; + hexstr2bin(token, (u8 *)&data_len, sizeof(data_len)); + data_len = htons(data_len); + token += 4; + offset += 4; + if ((offset + data_len) > len) + return; + switch (oui_argtype) { + case CISCO_OUI_NAME_ARG: + printf("\t%s", "VM Name"); + printf(" = %.*s\n", data_len, token); + break; + case CISCO_OUI_NAME_UUID_ARG: + printf("\t%s", "VM UUID"); + printf(" = %.*s\n", data_len, token); + break; + case CISCO_OUI_L3V4ADDR_ARG: + v4_addr_str = calloc(data_len, sizeof(char)); + if (!v4_addr_str) + return; + strncpy(v4_addr_str, token, data_len); + vm_ip_addr = strtoul(v4_addr_str, NULL, 10); + vm_inet.s_addr = vm_ip_addr; + printf("\t%s", "VM IP Address"); + printf(" = %s\n", inet_ntoa(vm_inet)); + free(v4_addr_str); + break; + default: + break; + } + token += data_len; + offset += data_len; + } +} -- 2.1.0