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.
651 lines
20 KiB
651 lines
20 KiB
4 years ago
|
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
|
||
|
|