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.
650 lines
20 KiB
650 lines
20 KiB
From 409b8d4027d391a401b1d3c0f56569d6402679f7 Mon Sep 17 00:00:00 2001 |
|
From: padkrish <padkrish@cisco.com> |
|
Date: Wed, 21 Jan 2015 03:40:09 +0000 |
|
Subject: [PATCH] VDP: Support for Cisco specific OUI extensions to VDP22 |
|
|
|
This commit has Cisco specific extensions to VDP22. vdptool is also |
|
modified to carry Cisco's extensions for OUI. |
|
The parameters to vdptool that are added for supporting Cisco OUI are: |
|
"-c oui=cisco,vm_name=myname -c oui=cisco,ipv4_addr=a.b.c.d -c oui=cisco,vm_uuid=aaa" |
|
|
|
The description of the files are: |
|
|
|
vdp22cisco_oui.c: |
|
----------------- |
|
This file contain all the handler implementation. |
|
vdp_cisco.h: |
|
------------ |
|
Cisco specific OUI definitions and structures. |
|
vdptool_cisco_oui.c: |
|
-------------------- |
|
Cisco specific OUI extensions for user input. |
|
|
|
Signed-off-by: padkrish <padkrish@cisco.com> |
|
Signed-off-by: John Fastabend <john.r.fastabend@intel.com> |
|
--- |
|
Makefile.am | 5 +- |
|
include/vdp_cisco.h | 121 ++++++++++++++++++ |
|
qbg/vdp22.c | 2 + |
|
qbg/vdp22cisco_oui.c | 355 +++++++++++++++++++++++++++++++++++++++++++++++++++ |
|
vdptool.c | 2 + |
|
vdptool_cisco_oui.c | 58 +++++++++ |
|
6 files changed, 541 insertions(+), 2 deletions(-) |
|
create mode 100644 include/vdp_cisco.h |
|
create mode 100644 qbg/vdp22cisco_oui.c |
|
create mode 100644 vdptool_cisco_oui.c |
|
|
|
diff --git a/Makefile.am b/Makefile.am |
|
index f63311c..abc9348 100644 |
|
--- a/Makefile.am |
|
+++ b/Makefile.am |
|
@@ -70,14 +70,15 @@ include/lldp_evb22.h lldp_evb22.c lldp_evb22_cmds.c \ |
|
include/qbg22.h include/qbg_ecp22.h qbg/ecp22.c \ |
|
include/qbg_vdp22.h qbg/vdp22.c qbg/vdpnl.c qbg/vdp22sm.c qbg/vdp22br.c \ |
|
include/qbg_vdp22def.h qbg/vdp22_cmds.c qbg/vdp_ascii.c \ |
|
-include/qbg_vdp22_oui.h qbg/vdp22_oui.c |
|
+include/qbg_vdp22_oui.h qbg/vdp22_oui.c include/vdp_cisco.h \ |
|
+qbg/vdp22cisco_oui.c |
|
|
|
lib_LTLIBRARIES = liblldp_clif.la |
|
liblldp_clif_la_LDFLAGS = -version-info 1:0:0 |
|
liblldp_clif_includedir = ${srcdir}/include |
|
liblldp_clif_la_SOURCES = clif.c |
|
|
|
-vdptool_SOURCES = vdptool.c lldp_util.c qbg/vdp22_clif.c |
|
+vdptool_SOURCES = vdptool.c lldp_util.c qbg/vdp22_clif.c vdptool_cisco_oui.c |
|
vdptool_LDADD = ${srcdir}/liblldp_clif.la |
|
vdptool_LDFLAGS = -llldp_clif $(LIBNL_LIBS) |
|
|
|
diff --git a/include/vdp_cisco.h b/include/vdp_cisco.h |
|
new file mode 100644 |
|
index 0000000..339d479 |
|
--- /dev/null |
|
+++ b/include/vdp_cisco.h |
|
@@ -0,0 +1,121 @@ |
|
+/******************************************************************************* |
|
+ |
|
+ Implementation of Cisco Specific OUI for VDP2.2 |
|
+ Copyright (c) 2012-2014 by Cisco Systems, Inc. |
|
+ |
|
+ Author(s): Padmanabhan Krishnan <padkrish at cisco dot com> |
|
+ |
|
+ This program is free software; you can redistribute it and/or modify it |
|
+ under the terms and conditions of the GNU General Public License, |
|
+ version 2, as published by the Free Software Foundation. |
|
+ |
|
+ This program is distributed in the hope it will be useful, but WITHOUT |
|
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|
+ more details. |
|
+ |
|
+ You should have received a copy of the GNU General Public License along with |
|
+ this program; if not, write to the Free Software Foundation, Inc., |
|
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. |
|
+ |
|
+ The full GNU General Public License is included in this distribution in |
|
+ the file called "COPYING". |
|
+*******************************************************************************/ |
|
+ |
|
+#ifndef __VDP22_VISCO_H__ |
|
+#define __VDP22_VISCO_H__ |
|
+ |
|
+#include "lldp.h" |
|
+#include <netinet/in.h> |
|
+#include <arpa/inet.h> |
|
+#include "qbg_vdp22_oui.h" |
|
+ |
|
+#define MAX_VM_NAME 100 |
|
+#define CISCO_OUI_VAL "00000C" |
|
+#define CISCO_OUI_HEX 0xC |
|
+ |
|
+#define CISCO_OUI_NAME_ARG_STR "vm_name" |
|
+#define CISCO_OUI_NAME_UUID_ARG_STR "vm_uuid" |
|
+#define CISCO_OUI_L3V4ADDR_ARG_STR "ipv4_addr" |
|
+#define MAX_VM_AF 3 |
|
+ |
|
+#define KEYLEN 16 |
|
+#define PORT_UUID_MAX 16 |
|
+ |
|
+enum oui_key_arg { |
|
+ CISCO_OUI_NAME_ARG = 0, |
|
+ CISCO_OUI_NAME_UUID_ARG, |
|
+ CISCO_OUI_L3V4ADDR_ARG, |
|
+ CISCO_OUI_INVALID_ARG |
|
+}; |
|
+ |
|
+enum cisco_oui_subtype { |
|
+ CISCO_OUI_NAME_SUBTYPE = 0xF1, |
|
+ CISCO_OUI_L3ADDR_SUBTYPE = 0xF2, |
|
+}; |
|
+ |
|
+/* |
|
+ * Name SubTLV |
|
+ * OUI: => 3B = 00-00-0C |
|
+ * subtype => 1B = 0xF1 |
|
+ * VSI ID Frmt => 1B |
|
+ * VSI ID => 16B |
|
+ * VM ID Frmt => 1B |
|
+ * VM ID => 16B |
|
+ * VM Name => Variable |
|
+ * Total => 38 + VM name len |
|
+ */ |
|
+ |
|
+/* |
|
+ * L3 Addr SubTLV |
|
+ * OUI: => 3B = 00-00-0C |
|
+ * subtype => 1B = 0xF2 |
|
+ * VSI ID Frmt => 1B |
|
+ * VSI ID => 16B |
|
+ * AFI => 2B |
|
+ * L3 Addr => Variable |
|
+ * Total => 23 + L3 Addr Len |
|
+ */ |
|
+ |
|
+ /* Subtype Len w/o the 3B Cisco OUI Len */ |
|
+enum cisco_oui_subtype_len { |
|
+ CISCO_VM_NAME_TLV_LEN = 35, /* minus the variable name len */ |
|
+ CISCO_VM_L3ADDR_TLV_LEN = 20 /* minus the variable addr len */ |
|
+}; |
|
+ |
|
+struct oui_keyword_handler { |
|
+ char *keyword; |
|
+ enum oui_key_arg val; |
|
+}; |
|
+ |
|
+typedef union l3_addrtype_ { |
|
+ struct in_addr ipv4_address; |
|
+ struct in6_addr ipv6_address; |
|
+} l3_addr_t; |
|
+ |
|
+typedef struct vdp_cisco_oui_s { |
|
+ char key[KEYLEN]; /* Profile name */ |
|
+ u8 uuid[PORT_UUID_MAX]; /* Instance ID */ |
|
+ size_t vm_name_len; |
|
+ char vm_name[MAX_VM_NAME]; |
|
+ u16 afi; |
|
+ u8 vm_addr_len; |
|
+ l3_addr_t l3_addr; |
|
+} vdp_cisco_oui_t; |
|
+ |
|
+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 *); |
|
+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 *); |
|
+ |
|
+static inline void fill_cisco_oui_type(unsigned char *oui_type) |
|
+{ |
|
+ oui_type[0] = 0x00; |
|
+ oui_type[1] = 0x00; |
|
+ oui_type[2] = 0x0c; |
|
+} |
|
+ |
|
+#endif /* __VDP22_VISCO_H__ */ |
|
diff --git a/qbg/vdp22.c b/qbg/vdp22.c |
|
index 5cae83f..ab170ed 100644 |
|
--- a/qbg/vdp22.c |
|
+++ b/qbg/vdp22.c |
|
@@ -48,6 +48,7 @@ |
|
#define EXTERN_FN(name)\ |
|
extern bool name##_oui_init() |
|
|
|
+EXTERN_FN(cisco); |
|
/* Init handlers for OUI. OUI handlers should be added in vdp22_oui_init_list. |
|
* First argument specifies the OUI code assigned to the Organization. |
|
* Second argument is the string which should match with the CLI and the third |
|
@@ -55,6 +56,7 @@ extern bool name##_oui_init() |
|
*/ |
|
|
|
struct vdp22_oui_init_s vdp22_oui_init_list[] = { |
|
+ {{0x00, 0x00, 0x0c}, "cisco", INIT_FN(cisco)} |
|
}; |
|
|
|
struct vdp22_oui_handler_s vdp22_oui_list[MAX_NUM_OUI]; |
|
diff --git a/qbg/vdp22cisco_oui.c b/qbg/vdp22cisco_oui.c |
|
new file mode 100644 |
|
index 0000000..ef6c307 |
|
--- /dev/null |
|
+++ b/qbg/vdp22cisco_oui.c |
|
@@ -0,0 +1,355 @@ |
|
+/******************************************************************************* |
|
+ |
|
+ Implementation of Cisco Specific OUI for VDP2.2 |
|
+ Copyright (c) 2012-2014 by Cisco Systems, Inc. |
|
+ |
|
+ Author(s): Padmanabhan Krishnan <padkrish at cisco dot com> |
|
+ |
|
+ This program is free software; you can redistribute it and/or modify it |
|
+ under the terms and conditions of the GNU General Public License, |
|
+ version 2, as published by the Free Software Foundation. |
|
+ |
|
+ This program is distributed in the hope it will be useful, but WITHOUT |
|
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|
+ more details. |
|
+ |
|
+ You should have received a copy of the GNU General Public License along with |
|
+ this program; if not, write to the Free Software Foundation, Inc., |
|
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. |
|
+ |
|
+ The full GNU General Public License is included in this distribution in |
|
+ the file called "COPYING". |
|
+*******************************************************************************/ |
|
+ |
|
+#include <stdio.h> |
|
+#include <stdlib.h> |
|
+#include <string.h> |
|
+#include <errno.h> |
|
+#include <ctype.h> |
|
+#include "messages.h" |
|
+#include "qbg_vdp22def.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; |
|
+} |
|
+ |
|
+/* |
|
+ * This function fills the vdpnl structure of OUI from the command separated |
|
+ * arguments containing the OUI information. |
|
+ * The input to this function is right from the OUI data after the ORG specific |
|
+ * OUI Type. |
|
+ */ |
|
+ |
|
+bool cisco_str2vdpnl_hndlr(struct vdpnl_oui_data_s *vdp_oui_p, char *token) |
|
+{ |
|
+ vdp_cisco_oui_t *vdp_cisco_oui_p; |
|
+ char *uuid, *v4_addr_str; |
|
+ int ret, offset = 0, len; |
|
+ bool vm_name_flag = false, l3_addr_flag = false; |
|
+ enum oui_key_arg oui_argtype; |
|
+ u16 data_len; |
|
+ u8 key_len; |
|
+ |
|
+ if ((vdp_oui_p == NULL) || (token == NULL)) { |
|
+ LLDPAD_ERR("%s: NULL arg\n", __func__); |
|
+ return false; |
|
+ } |
|
+ fill_cisco_oui_type(vdp_oui_p->oui_type); |
|
+ vdp_oui_p->len = sizeof(vdp_cisco_oui_t); |
|
+ vdp_cisco_oui_p = (vdp_cisco_oui_t *)vdp_oui_p->data; |
|
+ len = strlen(token); |
|
+ while (offset < len) { |
|
+ oui_vdp_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; |
|
+ oui_vdp_hexstr2bin(token, (u8 *)&data_len, sizeof(data_len)); |
|
+ data_len = htons(data_len); |
|
+ token += 4; |
|
+ offset += 4; |
|
+ if ((offset + data_len) > len) { |
|
+ LLDPAD_ERR("%s Incorrect len offset %d key %d data %d" |
|
+ " Len %d\n", __func__, offset, key_len, |
|
+ data_len, len); |
|
+ return false; |
|
+ } |
|
+ switch (oui_argtype) { |
|
+ case CISCO_OUI_NAME_ARG: |
|
+ if (vm_name_flag) { |
|
+ LLDPAD_ERR("%s: Incorrect arguments: Single VSI" |
|
+ " containing multiple VM Name\n", |
|
+ __func__); |
|
+ return false; |
|
+ } |
|
+ vm_name_flag = true; |
|
+ strncpy(vdp_cisco_oui_p->vm_name, token, data_len); |
|
+ vdp_cisco_oui_p->vm_name[data_len] = '\0'; |
|
+ vdp_cisco_oui_p->vm_name_len = data_len; |
|
+ LLDPAD_DBG("Name %s Len %ld\n", |
|
+ vdp_cisco_oui_p->vm_name, |
|
+ vdp_cisco_oui_p->vm_name_len); |
|
+ break; |
|
+ case CISCO_OUI_NAME_UUID_ARG: |
|
+ uuid = calloc(data_len, sizeof(char)); |
|
+ if (uuid == NULL) { |
|
+ LLDPAD_ERR("%s: NULL uuid\n", __func__); |
|
+ return false; |
|
+ } |
|
+ strncpy(uuid, token, data_len); |
|
+ if (oui_vdp_str2uuid(vdp_cisco_oui_p->uuid, uuid, |
|
+ sizeof(vdp_cisco_oui_p->uuid))) |
|
+ memset(vdp_cisco_oui_p->uuid, 0, |
|
+ sizeof(vdp_cisco_oui_p->uuid)); |
|
+ free(uuid); |
|
+ break; |
|
+ case CISCO_OUI_L3V4ADDR_ARG: |
|
+ if (l3_addr_flag) { |
|
+ LLDPAD_ERR("%s: Incorrect arguments: Single VSI" |
|
+ " containing multiple L3 Address\n", |
|
+ __func__); |
|
+ return true; |
|
+ } |
|
+ l3_addr_flag = true; |
|
+ vdp_cisco_oui_p->afi = MANADDR_IPV4; |
|
+ vdp_cisco_oui_p->vm_addr_len = |
|
+ sizeof(vdp_cisco_oui_p->l3_addr.ipv4_address); |
|
+ v4_addr_str = calloc(data_len, sizeof(char)); |
|
+ if (v4_addr_str == NULL) { |
|
+ LLDPAD_ERR("%s: NULL L3 Address\n", __func__); |
|
+ return false; |
|
+ } |
|
+ strncpy(v4_addr_str, token, data_len); |
|
+ ret = inet_aton(v4_addr_str, |
|
+ &vdp_cisco_oui_p->l3_addr.ipv4_address); |
|
+ LLDPAD_DBG("V4adr %s 0x%lx\n", v4_addr_str, |
|
+ (unsigned long) |
|
+ vdp_cisco_oui_p->l3_addr.ipv4_address.s_addr); |
|
+ free(v4_addr_str); |
|
+ if (!ret) { |
|
+ LLDPAD_ERR("%s: Incorrect addr\n", __func__); |
|
+ return false; |
|
+ } |
|
+ break; |
|
+ default: |
|
+ LLDPAD_ERR("%s: unknown subtype %d\n", __func__, |
|
+ oui_argtype); |
|
+ return false; |
|
+ } |
|
+ token += data_len; |
|
+ offset += data_len; |
|
+ } |
|
+ return true; |
|
+} |
|
+ |
|
+/* |
|
+ * This function converts the OUI information from vdpnl struct to vdp22 struct |
|
+ * vsi is not used here, but can be used for storing the pointer to the parent |
|
+ * struct |
|
+ */ |
|
+ |
|
+bool cisco_vdpnl2vsi22_hndlr(void *vsi_data, struct vdpnl_oui_data_s *from, |
|
+ struct vdp22_oui_data_s *to) |
|
+{ |
|
+ if ((from == NULL) || (to == NULL)) { |
|
+ LLDPAD_ERR("%s: NULL arg\n", __func__); |
|
+ return false; |
|
+ } |
|
+ to->data = calloc(1, from->len); |
|
+ if (to->data == NULL) { |
|
+ LLDPAD_ERR("%s: calloc failure\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)); |
|
+ /* Parent Pointer */ |
|
+ to->vsi_data = vsi_data; |
|
+ to->len = from->len; |
|
+ memcpy(to->data, from->data, to->len); |
|
+ return true; |
|
+} |
|
+ |
|
+/* |
|
+ * This function deletes the OUI information associated with a VSI |
|
+ */ |
|
+ |
|
+bool cisco_vdp_free_oui(struct vdp22_oui_data_s *vdp_oui_p) |
|
+{ |
|
+ if ((vdp_oui_p == NULL) || (vdp_oui_p->data == NULL)) { |
|
+ LLDPAD_ERR("%s: NULL arg\n", __func__); |
|
+ return false; |
|
+ } |
|
+ free(vdp_oui_p->data); |
|
+ vdp_oui_p->len = 0; |
|
+ vdp_oui_p->data = NULL; |
|
+ return true; |
|
+} |
|
+ |
|
+/* |
|
+ * This gets called for any VDP specific response. Currently not implemented. |
|
+ */ |
|
+ |
|
+bool cisco_vdp_rx_hndlr() |
|
+{ |
|
+ return true; |
|
+} |
|
+ |
|
+static inline unsigned long cisco_vdp_name_subtlv_len(vdp_cisco_oui_t *ptr) |
|
+{ |
|
+ return CISCO_VM_NAME_TLV_LEN + ptr->vm_name_len; |
|
+} |
|
+ |
|
+static inline unsigned long cisco_vdp_l3addr_subtlv_len(vdp_cisco_oui_t *ptr) |
|
+{ |
|
+ return CISCO_VM_L3ADDR_TLV_LEN + ptr->vm_addr_len; |
|
+} |
|
+ |
|
+/* |
|
+ * Returns the size |
|
+ * ORG TLV's are sent separately for Name and IP, which is why the T,L of 2B |
|
+ * and 3B for OUI_TYPE_LEN is added for both. This is done to be compatible |
|
+ * with Cisco switch implementation. |
|
+ */ |
|
+ |
|
+unsigned long cisco_vdp_oui_ptlvsize(void *arg_ptr) |
|
+{ |
|
+ vdp_cisco_oui_t *ptr = (vdp_cisco_oui_t *)arg_ptr; |
|
+ unsigned long cnt = 0; |
|
+ |
|
+ if (ptr == NULL) { |
|
+ LLDPAD_ERR("%s: Incorrect arg\n", __func__); |
|
+ return 0; |
|
+ } |
|
+ if (ptr->vm_name_len != 0) { |
|
+ cnt += 2 + VDP22_OUI_TYPE_LEN; |
|
+ cnt += cisco_vdp_name_subtlv_len(ptr); |
|
+ } |
|
+ /* Only V4 or V6 is supported */ |
|
+ if ((ptr->afi == MANADDR_IPV4) || (ptr->afi == MANADDR_IPV6)) { |
|
+ cnt += 2 + VDP22_OUI_TYPE_LEN; |
|
+ cnt += cisco_vdp_l3addr_subtlv_len(ptr); |
|
+ } |
|
+ return cnt; |
|
+} |
|
+ |
|
+static inline size_t cisco_vdp22_gen_l3addr(char unsigned *cp, size_t offset, |
|
+ struct vdp22_oui_data_s *oui_ptr) |
|
+{ |
|
+ vdp_cisco_oui_t *vdp_cisco_oui_str; |
|
+ unsigned char *vsi = NULL; |
|
+ unsigned short head; |
|
+ unsigned char len = 0; |
|
+ unsigned long net_l3_addr; |
|
+ |
|
+ vdp_cisco_oui_str = (vdp_cisco_oui_t *)oui_ptr->data; |
|
+ head = oui_get_tlv_head(VDP22_OUI, VDP22_OUI_TYPE_LEN + |
|
+ cisco_vdp_l3addr_subtlv_len(oui_ptr->data)); |
|
+ offset += oui_append_2o(cp + offset, head); |
|
+ offset += oui_append_3o(cp + offset, CISCO_OUI_HEX); |
|
+ offset += oui_append_1o(cp + offset, CISCO_OUI_L3ADDR_SUBTYPE); |
|
+ offset += oui_append_1o(cp + offset, |
|
+ vdp22_oui_get_vsi22_fmt(oui_ptr->vsi_data)); |
|
+ vsi = vdp22_oui_get_vsi22_len(oui_ptr->vsi_data, &len); |
|
+ if (vsi != NULL) |
|
+ offset += oui_append_nb(cp + offset, vsi, len); |
|
+ else |
|
+ LLDPAD_ERR("%s: get vsi22 return error\n", __func__); |
|
+ offset += oui_append_2o(cp + offset, vdp_cisco_oui_str->afi); |
|
+ if (vdp_cisco_oui_str->afi == MANADDR_IPV4) { |
|
+ net_l3_addr = htonl(vdp_cisco_oui_str->l3_addr. |
|
+ ipv4_address.s_addr); |
|
+ offset += oui_append_4o(cp + offset, net_l3_addr); |
|
+ } else { |
|
+ offset += oui_append_4o(cp + offset, 0); |
|
+ LLDPAD_ERR("%s: Not supported for now\n", __func__); |
|
+ } |
|
+ LLDPAD_DBG("%s: Valid VM Addr offset %ld\n", __func__, offset); |
|
+ return offset; |
|
+} |
|
+ |
|
+static inline size_t cisco_vdp22_gen_vmname(char unsigned *cp, size_t offset, |
|
+ struct vdp22_oui_data_s *oui_ptr) |
|
+{ |
|
+ vdp_cisco_oui_t *vdp_cisco_oui_str; |
|
+ unsigned char *vsi = NULL; |
|
+ unsigned short head; |
|
+ unsigned char len = 0; |
|
+ |
|
+ vdp_cisco_oui_str = (vdp_cisco_oui_t *)oui_ptr->data; |
|
+ head = oui_get_tlv_head(VDP22_OUI, VDP22_OUI_TYPE_LEN + |
|
+ cisco_vdp_name_subtlv_len(oui_ptr->data)); |
|
+ offset += oui_append_2o(cp + offset, head); |
|
+ offset += oui_append_3o(cp + offset, CISCO_OUI_HEX); |
|
+ offset += oui_append_1o(cp + offset, CISCO_OUI_NAME_SUBTYPE); |
|
+ offset += oui_append_1o(cp + offset, |
|
+ vdp22_oui_get_vsi22_fmt(oui_ptr->vsi_data)); |
|
+ vsi = vdp22_oui_get_vsi22_len(oui_ptr->vsi_data, &len); |
|
+ if (vsi != NULL) |
|
+ offset += oui_append_nb(cp + offset, vsi, len); |
|
+ else |
|
+ LLDPAD_ERR("%s: get vsi22 return error\n", __func__); |
|
+ offset += oui_append_1o(cp + offset, VDP22_ID_UUID); |
|
+ offset += oui_append_nb(cp + offset, vdp_cisco_oui_str->uuid, |
|
+ sizeof(vdp_cisco_oui_str->uuid)); |
|
+ offset += oui_append_nb(cp + offset, |
|
+ (char unsigned *)vdp_cisco_oui_str->vm_name, |
|
+ vdp_cisco_oui_str->vm_name_len); |
|
+ LLDPAD_DBG("%s: Valid VM Name offset %ld\n", __func__, offset); |
|
+ return offset; |
|
+} |
|
+ |
|
+/* |
|
+ * This function takes care of converting the OUI for Tx. |
|
+ */ |
|
+ |
|
+size_t cisco_vdp_tx_hndlr(char unsigned *cp, struct vdp22_oui_data_s *oui_ptr, |
|
+ size_t offset) |
|
+{ |
|
+ vdp_cisco_oui_t *vdp_cisco_oui_str; |
|
+ |
|
+ if ((cp == NULL) || (oui_ptr == NULL) || (oui_ptr->data == NULL)) { |
|
+ LLDPAD_ERR("%s: NULL Arguments\n", __func__); |
|
+ return 0; |
|
+ } |
|
+ vdp_cisco_oui_str = (vdp_cisco_oui_t *)oui_ptr->data; |
|
+ if (vdp_cisco_oui_str->vm_name_len != 0) |
|
+ offset = cisco_vdp22_gen_vmname(cp, offset, oui_ptr); |
|
+ if (vdp_cisco_oui_str->vm_addr_len != 0) |
|
+ offset = cisco_vdp22_gen_l3addr(cp, offset, oui_ptr); |
|
+ return offset; |
|
+} |
|
+ |
|
+bool cisco_oui_init() |
|
+{ |
|
+ bool ret; |
|
+ |
|
+ ret = oui_vdp_hndlr_init(&cisco_oui_hndlr); |
|
+ if (!ret) { |
|
+ LLDPAD_ERR("%s: handler init return err\n", __func__); |
|
+ return false; |
|
+ } |
|
+ return true; |
|
+} |
|
diff --git a/vdptool.c b/vdptool.c |
|
index c857a85..8edd6ca 100644 |
|
--- a/vdptool.c |
|
+++ b/vdptool.c |
|
@@ -65,10 +65,12 @@ |
|
* here. The corresponding decoder handler should be in lldpad. |
|
*/ |
|
|
|
+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)} |
|
}; |
|
|
|
|
|
diff --git a/vdptool_cisco_oui.c b/vdptool_cisco_oui.c |
|
new file mode 100644 |
|
index 0000000..4a846ad |
|
--- /dev/null |
|
+++ b/vdptool_cisco_oui.c |
|
@@ -0,0 +1,58 @@ |
|
+/******************************************************************************* |
|
+ |
|
+ Implementation of Cisco Specific OUI for vdptool |
|
+ Copyright (c) 2012-2014 by Cisco Systems, Inc. |
|
+ |
|
+ Author(s): Padmanabhan Krishnan <padkrish at cisco dot com> |
|
+ |
|
+ This program is free software; you can redistribute it and/or modify it |
|
+ under the terms and conditions of the GNU General Public License, |
|
+ version 2, as published by the Free Software Foundation. |
|
+ |
|
+ This program is distributed in the hope it will be useful, but WITHOUT |
|
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|
+ more details. |
|
+ |
|
+ You should have received a copy of the GNU General Public License along with |
|
+ this program; if not, write to the Free Software Foundation, Inc., |
|
+ 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. |
|
+ |
|
+ The full GNU General Public License is included in this distribution in |
|
+ the file called "COPYING". |
|
+*******************************************************************************/ |
|
+ |
|
+#include <stdio.h> |
|
+#include <stdlib.h> |
|
+#include <string.h> |
|
+#include "vdp_cisco.h" |
|
+ |
|
+bool cisco_oui_encode_hndlr(char *dst, char *src, int len) |
|
+{ |
|
+ char *src_temp = strdup(src); |
|
+ char *key, *data; |
|
+ bool flag = false; |
|
+ |
|
+ if (!src_temp) |
|
+ return false; |
|
+ key = src_temp; |
|
+ data = strchr(key, '='); |
|
+ if (!data) { |
|
+ free(src_temp); |
|
+ return false; |
|
+ } |
|
+ *data = '\0'; |
|
+ data++; |
|
+ if ((!strcmp(key, CISCO_OUI_NAME_ARG_STR)) || |
|
+ (!strcmp(key, CISCO_OUI_L3V4ADDR_ARG_STR)) || |
|
+ (!strcmp(key, CISCO_OUI_NAME_UUID_ARG_STR))) { |
|
+ snprintf(dst, MAX_OUI_DATA_LEN - len, "%02x%s%04x%s", |
|
+ (unsigned int)strlen(key), key, |
|
+ (unsigned int)strlen(data), data); |
|
+ flag = true; |
|
+ } else |
|
+ printf("Incorrect Cisco OUI %s\n", key); |
|
+ free(src_temp); |
|
+ return flag; |
|
+} |
|
+ |
|
-- |
|
2.1.0 |
|
|
|
|