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