From 436175a4154d1b0330cf47445d9a13f8b52cbda0 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 02 2019 17:59:22 +0000 Subject: import lldpad-1.0.1-5.git036e314.el7 --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..57b7885 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/lldpad-1.0.1.tar.gz diff --git a/.lldpad.metadata b/.lldpad.metadata new file mode 100644 index 0000000..b6c69a4 --- /dev/null +++ b/.lldpad.metadata @@ -0,0 +1 @@ +238c6c548b8dd013d52ee996841d8dc69f8eeedf SOURCES/lldpad-1.0.1.tar.gz diff --git a/SOURCES/0001-memleak-on-received-TLVs-from-modules.patch b/SOURCES/0001-memleak-on-received-TLVs-from-modules.patch new file mode 100644 index 0000000..d186ca3 --- /dev/null +++ b/SOURCES/0001-memleak-on-received-TLVs-from-modules.patch @@ -0,0 +1,110 @@ +From 9b0389837d7532909a8070d5a08f0175c367c12e Mon Sep 17 00:00:00 2001 +From: Chris Leech +Date: Wed, 23 May 2018 16:37:51 -0700 +Subject: [PATCH] memleak on received TLVs from modules + +Most of the TLV modules that have an rchange handler for received TLVs +seem to get the return values wrong, returning 0 or TLV_OK without +freeing or storing the unpacked TLV to be freed later. That leaks the +allocation, as rxProcessFrame believes the module has claimed ownership. + +In a test setup, it's probably easiest to see by enabling some TLV type +on one side of a connection only. Or, any unexpected TLV that doesn't +get handled will be erroneously leaked by the EVB modules. +--- + lldp_8021qaz.c | 4 ++-- + lldp_evb.c | 8 +++++--- + lldp_evb22.c | 8 +++++--- + 3 files changed, 12 insertions(+), 8 deletions(-) + +diff --git a/lldp_8021qaz.c b/lldp_8021qaz.c +index 094676d..198ebcf 100644 +--- a/lldp_8021qaz.c ++++ b/lldp_8021qaz.c +@@ -1924,7 +1924,7 @@ int ieee8021qaz_rchange(struct port *port, struct lldp_agent *agent, + struct ieee8021qaz_unpkd_tlvs *rx; + + if (agent->type != NEAREST_BRIDGE) +- return 0; ++ return SUBTYPE_INVALID; + + qaz_tlvs = ieee8021qaz_data(port->ifname); + if (!qaz_tlvs) +@@ -2005,7 +2005,7 @@ int ieee8021qaz_rchange(struct port *port, struct lldp_agent *agent, + } + } + +- return TLV_OK; ++ return SUBTYPE_INVALID; + } + + static void ieee8021qaz_free_rx(struct ieee8021qaz_unpkd_tlvs *rx) +diff --git a/lldp_evb.c b/lldp_evb.c +index 4b3752e..07f5ffb 100644 +--- a/lldp_evb.c ++++ b/lldp_evb.c +@@ -210,7 +210,8 @@ static int evb_rchange(struct port *port, struct lldp_agent *agent, + u8 oui_subtype[OUI_SUB_SIZE] = LLDP_OUI_SUBTYPE; + + if (agent->type != NEAREST_CUSTOMER_BRIDGE) +- return 0; ++ return SUBTYPE_INVALID; ++ + ed = evb_data(port->ifname, agent->type); + + if (!ed) +@@ -229,7 +230,7 @@ static int evb_rchange(struct port *port, struct lldp_agent *agent, + if (!ed->txmit) { + LLDPAD_WARN("%s:%s agent %d EVB Config disabled\n", + __func__, ed->ifname, agent->type); +- return TLV_OK; ++ return SUBTYPE_INVALID; + } + + LLDPAD_DBG("%s:%s agent %d received tlv:\n", __func__, +@@ -246,7 +247,8 @@ static int evb_rchange(struct port *port, struct lldp_agent *agent, + evb_print_tlvinfo(ed->ifname, &ed->tie); + vdp_update(port->ifname, ed->tie.ccap); + } +- return TLV_OK; ++ ++ return SUBTYPE_INVALID; + } + + /* +diff --git a/lldp_evb22.c b/lldp_evb22.c +index 85c6abc..64b04e0 100644 +--- a/lldp_evb22.c ++++ b/lldp_evb22.c +@@ -305,7 +305,8 @@ static int evb22_rchange(struct port *port, struct lldp_agent *agent, + u8 oui_subtype[OUI_SUB_SIZE] = LLDP_MOD_EVB22_OUI; + + if (agent->type != NEAREST_CUSTOMER_BRIDGE) +- return 0; ++ return SUBTYPE_INVALID; ++ + ed = evb22_data(port->ifname, agent->type); + + if (!ed) +@@ -324,7 +325,7 @@ static int evb22_rchange(struct port *port, struct lldp_agent *agent, + if (!ed->txmit) { + LLDPAD_WARN("%s:%s agent %d EVB Config disabled\n", + __func__, ed->ifname, agent->type); +- return TLV_OK; ++ return SUBTYPE_INVALID; + } + + LLDPAD_DBG("%s:%s agent %d received tlv:\n", __func__, +@@ -341,7 +342,8 @@ static int evb22_rchange(struct port *port, struct lldp_agent *agent, + evb22_print_tlvinfo(ed->ifname, &ed->out); + /* TODO vdp_update(port->ifname, ed->tie.ccap); */ + } +- return TLV_OK; ++ ++ return SUBTYPE_INVALID; + } + + /* +-- +2.19.1 + diff --git a/SOURCES/lldpad-0.9.46-Ignore-supplied-PG-configuration-if-PG-is-being-disabled.patch b/SOURCES/lldpad-0.9.46-Ignore-supplied-PG-configuration-if-PG-is-being-disabled.patch new file mode 100644 index 0000000..2d06279 --- /dev/null +++ b/SOURCES/lldpad-0.9.46-Ignore-supplied-PG-configuration-if-PG-is-being-disabled.patch @@ -0,0 +1,51 @@ +Disabling PG currently validates the entire given PG config, +even if no configuration is given. Of course since PG is +being disabled, the configuration wouldn't be used anyway, so +ignore any PG configuration given when disabling it. + +Signed-off-by: Dan Williams +--- + lldp_dcbx_cmds.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/lldp_dcbx_cmds.c b/lldp_dcbx_cmds.c +index 7fdf6c4..8dcee7a 100644 +--- a/lldp_dcbx_cmds.c ++++ b/lldp_dcbx_cmds.c +@@ -939,14 +939,18 @@ static int set_pg_config(pg_attribs *pg_data, char *port_id, char *ibuf, + cmd_status status = cmd_success; + int i, is_pfc; + int plen; + int off; + bool used[MAX_BANDWIDTH_GROUPS]; + bool uppcts_changed = false; + ++ /* If PG is disabled, skip changing any other attributes */ ++ if (!(pg_data->protocol.Enable)) ++ goto done; ++ + plen=strlen(port_id); + off = DCB_PORT_OFF + plen + CFG_LEN; + + if (ilen == (off + CFG_PG_DLEN)) { + for (i = 0; i < MAX_USER_PRIORITIES; i++) { + flag = *(ibuf+off+PG_UP2TC(i)); + if (flag == CLIF_NOT_SUPPLIED) +@@ -1063,14 +1067,15 @@ static int set_pg_config(pg_attribs *pg_data, char *port_id, char *ibuf, + } + + if (status != cmd_success) { + printf("invalid DCB settings\n"); + return status; + } + ++done: + is_pfc = get_pfc(port_id, &pfc_data); + if (is_pfc == cmd_success) + status = put_pg(port_id, pg_data, &pfc_data); + else + status = put_pg(port_id, pg_data, NULL); + + if (status != cmd_success) +-- +1.8.5.3 diff --git a/SOURCES/open-lldp-v1.0.1-1-VDP-vdp22_cmds-retrieve-vsi-paramenter-data.patch b/SOURCES/open-lldp-v1.0.1-1-VDP-vdp22_cmds-retrieve-vsi-paramenter-data.patch new file mode 100644 index 0000000..fb2968a --- /dev/null +++ b/SOURCES/open-lldp-v1.0.1-1-VDP-vdp22_cmds-retrieve-vsi-paramenter-data.patch @@ -0,0 +1,106 @@ +From dff810b2e546eb74e8b9cebb7185ca5bcb5ecc9d Mon Sep 17 00:00:00 2001 +From: Thomas Richter +Date: Wed, 21 Jan 2015 03:35:59 +0000 +Subject: [PATCH] VDP: vdp22_cmds retrieve vsi paramenter data + +This patch adds support for the retrieval of the +vsi parameter data to a command line client. + +Signed-off-by: Thomas Richter +Signed-off-by: John Fastabend +--- + include/qbg_vdpnl.h | 1 + + qbg/vdp22_cmds.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 64 insertions(+) + +diff --git a/include/qbg_vdpnl.h b/include/qbg_vdpnl.h +index 7b26bc7..510a20c 100644 +--- a/include/qbg_vdpnl.h ++++ b/include/qbg_vdpnl.h +@@ -78,4 +78,5 @@ int event_trigger(struct nlmsghdr *, pid_t); + 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 *); + #endif +diff --git a/qbg/vdp22_cmds.c b/qbg/vdp22_cmds.c +index a75c02d..f055441 100644 +--- a/qbg/vdp22_cmds.c ++++ b/qbg/vdp22_cmds.c +@@ -471,10 +471,73 @@ static int test_arg_vsi(struct cmd *cmd, UNUSED char *arg, char *argvalue, + return set_arg_vsi2(cmd, argvalue, true); + } + ++/* ++ * Concatenate all VSI information into one string. ++ * Return length of string in bytes. ++ */ ++static int catvsis(struct vdpnl_vsi *vsi, char *out, size_t out_len) ++{ ++ int rc, i; ++ size_t used = 0; ++ unsigned char wanted_req = vsi->request; ++ ++ for (i = 1; vdp22_status(i, vsi, 1) > 0; ++i) { ++ if (wanted_req != vsi->request) { ++ vdp22_freemaclist(vsi); ++ continue; ++ } ++ rc = vdp_vdpnl2str(vsi, out + used, out_len - used); ++ vdp22_freemaclist(vsi); ++ if (rc) { ++ strcat(out, ";"); ++ used = strlen(out); ++ } else ++ return 0; ++ } ++ return used; ++} ++ ++/* ++ * Return all VSIs on a particular interface into one string. ++ */ ++static int get_arg_vsi(struct cmd *cmd, char *arg, UNUSED char *argvalue, ++ char *obuf, int obuf_len) ++{ ++ cmd_status good_cmd = vdp22_cmdok(cmd, cmd_gettlv); ++ struct vdpnl_vsi vsi; ++ char vsi_str[MAX_CLIF_MSGBUF]; ++ int rc; ++ ++ if (good_cmd != cmd_success) ++ return good_cmd; ++ if (!port_find_by_ifindex(get_ifidx(cmd->ifname))) ++ return cmd_device_not_found; ++ good_cmd = ifok(cmd); ++ if (good_cmd != cmd_success) ++ return good_cmd; ++ ++ memset(obuf, 0, obuf_len); ++ memset(&vsi, 0, sizeof(vsi)); ++ vsi.request = cmd->tlvid; ++ strncpy(vsi.ifname, cmd->ifname, sizeof(vsi.ifname) - 1); ++ good_cmd = cmd_failed; ++ if (!catvsis(&vsi, vsi_str, sizeof(vsi_str))) ++ goto out; ++ rc = snprintf(obuf, obuf_len, "%02x%s%04x%s", ++ (unsigned int)strlen(arg), arg, (unsigned int)strlen(vsi_str), ++ vsi_str); ++ if (rc > 0 || rc < obuf_len) ++ good_cmd = cmd_success; ++out: ++ return good_cmd; ++} ++ ++ + static struct arg_handlers arg_handlers[] = { + { + .arg = ARG_VDP22_VSI, + .arg_class = TLV_ARG, ++ .handle_get = get_arg_vsi, + .handle_set = set_arg_vsi, + .handle_test = test_arg_vsi + }, +-- +2.1.0 + diff --git a/SOURCES/open-lldp-v1.0.1-10-VDP-Support-for-OUI-infrastructure-in-vdp22.patch b/SOURCES/open-lldp-v1.0.1-10-VDP-Support-for-OUI-infrastructure-in-vdp22.patch new file mode 100644 index 0000000..9f8ab5e --- /dev/null +++ b/SOURCES/open-lldp-v1.0.1-10-VDP-Support-for-OUI-infrastructure-in-vdp22.patch @@ -0,0 +1,172 @@ +From 7289ac24898ae74a3a47fb4e4378d1535c21adba Mon Sep 17 00:00:00 2001 +From: padkrish +Date: Wed, 21 Jan 2015 03:39:47 +0000 +Subject: [PATCH] VDP: Support for OUI infrastructure in vdp22. + +This commit is a framework for supporting OUI fields +in VDP22. This specific patch adds helper functions +(functions exported by VDP to OUI code) to be called by OUI +specific handler code. + +Signed-off-by: padkrish +Signed-off-by: John Fastabend +--- + Makefile.am | 2 +- + include/qbg_utils.h | 1 + + include/qbg_vdp22_oui.h | 48 +++++++++++++++++++++++++++++++++++++ + qbg/vdp22_oui.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 113 insertions(+), 1 deletion(-) + create mode 100644 qbg/vdp22_oui.c + +diff --git a/Makefile.am b/Makefile.am +index 403088b..f63311c 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -70,7 +70,7 @@ 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 ++include/qbg_vdp22_oui.h qbg/vdp22_oui.c + + lib_LTLIBRARIES = liblldp_clif.la + liblldp_clif_la_LDFLAGS = -version-info 1:0:0 +diff --git a/include/qbg_utils.h b/include/qbg_utils.h +index 6033556..963cb87 100644 +--- a/include/qbg_utils.h ++++ b/include/qbg_utils.h +@@ -42,4 +42,5 @@ int modules_notify(int, int, char *, void *); + + /* Convert VSI IDs to strings */ + int vdp_uuid2str(const unsigned char *, char *, size_t); ++int vdp_str2uuid(unsigned char *, char *, size_t); + #endif +diff --git a/include/qbg_vdp22_oui.h b/include/qbg_vdp22_oui.h +index 0cce31e..79e1ff5 100644 +--- a/include/qbg_vdp22_oui.h ++++ b/include/qbg_vdp22_oui.h +@@ -92,4 +92,52 @@ struct vdp22_oui_handler_s { + unsigned long (*oui_ptlv_size_hndlr)(void *); + }; + ++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); ++bool oui_vdp_hndlr_init(struct vdp22_oui_handler_s *); ++int oui_vdp_hexstr2bin(const char *hex, unsigned char *buf, size_t len); ++ ++static inline size_t oui_append_1o(unsigned char *cp, const unsigned char data) ++{ ++ *cp = data; ++ return 1; ++} ++ ++static inline size_t oui_append_2o(unsigned char *cp, const unsigned short data) ++{ ++ *cp = (data >> 8) & 0xff; ++ *(cp + 1) = data & 0xff; ++ return 2; ++} ++ ++static inline size_t oui_append_3o(unsigned char *cp, const unsigned long data) ++{ ++ *cp = (data >> 16) & 0xff; ++ *(cp + 1) = (data >> 8) & 0xff; ++ *(cp + 2) = data & 0xff; ++ return 3; ++} ++static inline size_t oui_append_4o(unsigned char *cp, const unsigned long data) ++{ ++ *cp = (data >> 24) & 0xff; ++ *(cp + 1) = (data >> 16) & 0xff; ++ *(cp + 2) = (data >> 8) & 0xff; ++ *(cp + 3) = data & 0xff; ++ return 4; ++} ++ ++static inline size_t oui_append_nb(unsigned char *cp, const unsigned char *data, ++ const size_t nlen) ++{ ++ memcpy(cp, data, nlen); ++ return nlen; ++} ++ ++static inline unsigned short oui_get_tlv_head(unsigned short type, ++ unsigned short len) ++{ ++ return (type & 0x7f) << 9 | (len & 0x1ff); ++} ++ + #endif /* __VDP22_OUI_H__ */ +diff --git a/qbg/vdp22_oui.c b/qbg/vdp22_oui.c +new file mode 100644 +index 0000000..3a2d0cc +--- /dev/null ++++ b/qbg/vdp22_oui.c +@@ -0,0 +1,63 @@ ++/******************************************************************************* ++ ++ Implementation of OUI Functionality for VDP2.2 ++ This file contains the exported functions from VDP to the OUI handlers file. ++ Copyright (c) 2012-2014 by Cisco Systems, Inc. ++ ++ Author(s): Padmanabhan Krishnan ++ ++ 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 ++#include ++#include ++#include ++#include ++#include "messages.h" ++#include "lldp_util.h" ++#include "qbg_vdp22.h" ++#include "qbg_utils.h" ++#include "qbg_vdp22_oui.h" ++ ++unsigned char vdp22_oui_get_vsi22_fmt(void *vsi_data) ++{ ++ if (vsi_data != NULL) ++ return ((struct vsi22 *)(vsi_data))->vsi_fmt; ++ LLDPAD_ERR("%s: NULL Arg\n", __func__); ++ return 0; ++} ++ ++unsigned char *vdp22_oui_get_vsi22_len(void *vsi_data, unsigned char *len) ++{ ++ if ((vsi_data != NULL) && (len != NULL)) { ++ *len = VDP22_IDSZ; ++ return ((struct vsi22 *)(vsi_data))->vsi; ++ } ++ LLDPAD_ERR("%s: NULL Arg\n", __func__); ++ return NULL; ++} ++ ++int oui_vdp_str2uuid(unsigned char *to, char *buffer, size_t max) ++{ ++ return vdp_str2uuid(to, buffer, max); ++} ++ ++int oui_vdp_hexstr2bin(const char *hex, unsigned char *buf, size_t len) ++{ ++ return hexstr2bin(hex, buf, len); ++} +-- +2.1.0 + diff --git a/SOURCES/open-lldp-v1.0.1-11-VDP-Support-for-Cisco-specific-OUI-extensions-to-VDP.patch b/SOURCES/open-lldp-v1.0.1-11-VDP-Support-for-Cisco-specific-OUI-extensions-to-VDP.patch new file mode 100644 index 0000000..de37ade --- /dev/null +++ b/SOURCES/open-lldp-v1.0.1-11-VDP-Support-for-Cisco-specific-OUI-extensions-to-VDP.patch @@ -0,0 +1,650 @@ +From 409b8d4027d391a401b1d3c0f56569d6402679f7 Mon Sep 17 00:00:00 2001 +From: padkrish +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 +Signed-off-by: John Fastabend +--- + 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 ++ ++ 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 ++#include ++#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 ++ ++ 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 ++#include ++#include ++#include ++#include ++#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 ++ ++ 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 ++#include ++#include ++#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 + diff --git a/SOURCES/open-lldp-v1.0.1-12-VDP22-Fix-the-ack-timeout-handler-to-set-the-right-t.patch b/SOURCES/open-lldp-v1.0.1-12-VDP22-Fix-the-ack-timeout-handler-to-set-the-right-t.patch new file mode 100644 index 0000000..0cb20fb --- /dev/null +++ b/SOURCES/open-lldp-v1.0.1-12-VDP22-Fix-the-ack-timeout-handler-to-set-the-right-t.patch @@ -0,0 +1,33 @@ +From c26e175bea45306657c3435dc1ac2203584cf77a Mon Sep 17 00:00:00 2001 +From: padkrish +Date: Wed, 21 Jan 2015 03:40:32 +0000 +Subject: [PATCH] VDP22: Fix the ack timeout handler to set the right timeout + variable + +Currently the acktimeout handler sets the keepalive timeout boolean +variable as a result of which the profiles don't get deleted when +there's a timeout. This diff sets the acktimeout variable in the +acktimeout handler. + +Signed-off-by: padkrish +Signed-off-by: John Fastabend +--- + qbg/vdp22sm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/qbg/vdp22sm.c b/qbg/vdp22sm.c +index db0e413..14356ac 100644 +--- a/qbg/vdp22sm.c ++++ b/qbg/vdp22sm.c +@@ -439,7 +439,7 @@ static void vdp22st_handle_ackto(UNUSED void *ctx, void *data) + LLDPAD_DBG("%s:%s timeout ack timer for %p(%02x) ackreceived:%d\n", + __func__, p->vdp->ifname, p, p->vsi[0], p->smi.ackreceived); + if (!p->smi.ackreceived) { +- p->smi.kato = true; ++ p->smi.acktimeout = true; + vdp22st_run(p); + } + } +-- +2.1.0 + diff --git a/SOURCES/open-lldp-v1.0.1-13-VDP-Changes-in-OUI-infra-for-get-tlv.patch b/SOURCES/open-lldp-v1.0.1-13-VDP-Changes-in-OUI-infra-for-get-tlv.patch new file mode 100644 index 0000000..85a4305 --- /dev/null +++ b/SOURCES/open-lldp-v1.0.1-13-VDP-Changes-in-OUI-infra-for-get-tlv.patch @@ -0,0 +1,333 @@ +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 + diff --git a/SOURCES/open-lldp-v1.0.1-14-VDP-Changes-in-Cisco-OUI-handlers-to-support-get-tlv.patch b/SOURCES/open-lldp-v1.0.1-14-VDP-Changes-in-Cisco-OUI-handlers-to-support-get-tlv.patch new file mode 100644 index 0000000..71466e0 --- /dev/null +++ b/SOURCES/open-lldp-v1.0.1-14-VDP-Changes-in-Cisco-OUI-handlers-to-support-get-tlv.patch @@ -0,0 +1,283 @@ +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 + diff --git a/SOURCES/open-lldp-v1.0.1-15-VDP-Add-vdptool-man-page-to-Makefile.patch b/SOURCES/open-lldp-v1.0.1-15-VDP-Add-vdptool-man-page-to-Makefile.patch new file mode 100644 index 0000000..9bc32b5 --- /dev/null +++ b/SOURCES/open-lldp-v1.0.1-15-VDP-Add-vdptool-man-page-to-Makefile.patch @@ -0,0 +1,27 @@ +From 5add0baccd0c888742a00af4b17754990dbcbf93 Mon Sep 17 00:00:00 2001 +From: padkrish +Date: Wed, 21 Jan 2015 03:41:38 +0000 +Subject: [PATCH] VDP: Add vdptool man page to Makefile + +Signed-off-by: padkrish +Signed-off-by: John Fastabend +--- + Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile.am b/Makefile.am +index abc9348..27dffc2 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -109,7 +109,7 @@ dist_man_MANS = docs/lldpad.8 docs/dcbtool.8 docs/lldptool.8 \ + docs/lldptool-ets.8 docs/lldptool-pfc.8 docs/lldptool-app.8 \ + docs/lldptool-evb.8 docs/lldptool-vdp.8 docs/lldptool-med.8 \ + docs/lldptool-dcbx.8 \ +- docs/lldptool-evb22.8 ++ docs/lldptool-evb22.8 docs/vdptool.8 + if BUILD_DEBUG + nodist_man_MANS = test/qbg22sim.1 test/vdptest.1 + endif +-- +2.1.0 + diff --git a/SOURCES/open-lldp-v1.0.1-16-VDP-Fixed-DBG-print-compile-errors-in-32-bit-systems.patch b/SOURCES/open-lldp-v1.0.1-16-VDP-Fixed-DBG-print-compile-errors-in-32-bit-systems.patch new file mode 100644 index 0000000..2cc1c3a --- /dev/null +++ b/SOURCES/open-lldp-v1.0.1-16-VDP-Fixed-DBG-print-compile-errors-in-32-bit-systems.patch @@ -0,0 +1,45 @@ +From b6c5d86ea57594893d4fd95a0bf8043c45c953a4 Mon Sep 17 00:00:00 2001 +From: Paddu Krishnan +Date: Wed, 21 Jan 2015 03:42:01 +0000 +Subject: [PATCH] VDP: Fixed DBG print compile errors in 32-bit systems + +Signed-off-by: Paddu Krishnan +Signed-off-by: John Fastabend +--- + qbg/vdp22cisco_oui.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/qbg/vdp22cisco_oui.c b/qbg/vdp22cisco_oui.c +index e8a824c..272d480 100644 +--- a/qbg/vdp22cisco_oui.c ++++ b/qbg/vdp22cisco_oui.c +@@ -92,7 +92,7 @@ bool cisco_str2vdpnl_hndlr(struct vdpnl_oui_data_s *vdp_oui_p, char *token) + 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", ++ LLDPAD_DBG("Name %s Len %zu\n", + vdp_cisco_oui_p->vm_name, + vdp_cisco_oui_p->vm_name_len); + break; +@@ -364,7 +364,7 @@ static inline size_t cisco_vdp22_gen_l3addr(char unsigned *cp, size_t offset, + 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); ++ LLDPAD_DBG("%s: Valid VM Addr offset %zu\n", __func__, offset); + return offset; + } + +@@ -395,7 +395,7 @@ static inline size_t cisco_vdp22_gen_vmname(char unsigned *cp, size_t offset, + 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); ++ LLDPAD_DBG("%s: Valid VM Name offset %zu\n", __func__, offset); + return offset; + } + +-- +2.1.0 + diff --git a/SOURCES/open-lldp-v1.0.1-17-lldp-automake-fixes-for-dist-distcheck.patch b/SOURCES/open-lldp-v1.0.1-17-lldp-automake-fixes-for-dist-distcheck.patch new file mode 100644 index 0000000..2c7e1e3 --- /dev/null +++ b/SOURCES/open-lldp-v1.0.1-17-lldp-automake-fixes-for-dist-distcheck.patch @@ -0,0 +1,130 @@ +From c986aa5bc5f509f3cbc033212e0808a992ec48bf Mon Sep 17 00:00:00 2001 +From: John Fastabend +Date: Fri, 30 Jan 2015 08:32:07 -0800 +Subject: [PATCH] lldp: automake fixes for dist/distcheck + +This fixes the dist and distcheck automake targets for making release +archives. + +All missing header files that have been added to git are listed in +noinst_HEADERS, so they get added to the release archive but are not +installed. Some of these ( qgb_vdp22_(cmds|clif).h ) may be part of the +client API and need to be moved to lldpad_include_HEADERS? + +The srcdir prefix was removed from references to liblldp_clif.la, it's +not needed and breaks builds where the output dir is different from the +source dir as this is a generated file. + +The liblldp_clid-vdp22.3 man page was added. + +The qbg22sim and vdptest man pages were added to the release archive, +but still should only be installed if debug is configured. + +lldpad.init was added to dist_noinst_DATA to add to the release + +The custom systemd unit file install rule was replaced with a dist_DATA +definition, letting automake build the rules to handle them. Before +they were being left out of the release archive. + +Same thing with the bash completion files, just tell automake where they +go. + +Compared to git-archive, make dist now gets almost everything. +I left the test data files out for now, even though the binaries and +man pages are being included. + +Signed-off-by: Chris Leech +Signed-off-by: John Fastabend +--- + Makefile.am | 42 ++++++++++++++++++------------------------ + 1 file changed, 18 insertions(+), 24 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index 27dffc2..69deda2 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -43,7 +43,10 @@ include/lldp_8023_clif.h include/lldp_dcbx_clif.h include/lldp_evb_clif.h \ + include/lldp_evb22_clif.h include/qbg_vdp_clif.h include/qbg_vdpnl.h \ + include/qbg_vdp22_clif.h include/lldp_8021qaz_clif.h \ + include/lldp_orgspec_clif.h include/lldp_cisco_clif.h \ +-include/lldptool.h include/lldp_rtnl.h include/dcbtool.h include/lldp_dcbx_cfg.h ++include/lldptool.h include/lldp_rtnl.h include/dcbtool.h include/lldp_dcbx_cfg.h \ ++include/qbg_vdp22_cmds.h include/qbg_vdp22_clif.h \ ++include/linux/ethtool.h include/linux/if_bonding.h include/linux/if_bridge.h \ ++include/linux/if.h include/linux/if_link.h include/linux/if_vlan.h + + lldpad_SOURCES = lldpad.c config.c lldp_dcbx_nl.c ctrl_iface.c \ + event_iface.c eloop.c lldp_dcbx_cmds.c log.c lldpad_shm.c \ +@@ -84,7 +87,7 @@ vdptool_LDFLAGS = -llldp_clif $(LIBNL_LIBS) + + dcbtool_SOURCES = dcbtool.c dcbtool_cmds.c parse_cli.l \ + weak_readline.c $(lldpad_include_HEADERS) $(noinst_HEADERS) +-dcbtool_LDADD = ${srcdir}/liblldp_clif.la ++dcbtool_LDADD = liblldp_clif.la + dcbtool_LDFLAGS = -ldl -llldp_clif + + lldptool_SOURCES = lldptool.c lldptool_cmds.c lldp_rtnl.c \ +@@ -93,7 +96,7 @@ lldptool_SOURCES = lldptool.c lldptool_cmds.c lldp_rtnl.c \ + lldp_8021qaz_clif.c lldp_evb_clif.c qbg/vdp_clif.c \ + lldp_orgspec_clif.c lldp_cisco_clif.c lldp_evb22_clif.c \ + weak_readline.c $(lldpad_include_HEADERS) $(noinst_HEADERS) +-lldptool_LDADD = ${srcdir}/liblldp_clif.la ++lldptool_LDADD = liblldp_clif.la + lldptool_LDFLAGS = -ldl -llldp_clif $(LIBNL_LIBS) + + if BUILD_DEBUG +@@ -104,14 +107,20 @@ qbg22sim_SOURCES = test/qbg22sim.c + qbg22sim_LDFLAGS = -lrt + endif + ++## put a spec file and documentation in the distribution archive ++dist_noinst_DATA = lldpad.spec README COPYING ChangeLog lldpad.init ++ + ## man pages + dist_man_MANS = docs/lldpad.8 docs/dcbtool.8 docs/lldptool.8 \ + docs/lldptool-ets.8 docs/lldptool-pfc.8 docs/lldptool-app.8 \ + docs/lldptool-evb.8 docs/lldptool-vdp.8 docs/lldptool-med.8 \ + docs/lldptool-dcbx.8 \ +- docs/lldptool-evb22.8 docs/vdptool.8 ++ docs/lldptool-evb22.8 docs/vdptool.8 \ ++ docs/liblldp_clif-vdp22.3 + if BUILD_DEBUG +-nodist_man_MANS = test/qbg22sim.1 test/vdptest.1 ++dist_man_MANS += test/qbg22sim.1 test/vdptest.1 ++else ++dist_noinst_DATA += test/qbg22sim.1 test/vdptest.1 + endif + + ## force the creation of an empty configuration directory at install time +@@ -124,24 +133,9 @@ install-data-hook: installdirs-local + pkgconfigdir = ${libdir}/pkgconfig + pkgconfig_DATA = lldpad.pc liblldp_clif.pc + +-## put a spec file and documentation in the distribution archive +-dist_noinst_DATA = lldpad.spec README COPYING ChangeLog ++systemdsystemunitdir = $(prefix)/lib/systemd/system ++dist_systemdsystemunit_DATA = lldpad.service lldpad.socket + +-## special hooks to handle the init script +-install-data-local: lldpad.service lldpad.socket +- $(MKDIR_P) $(DESTDIR)/usr/lib/systemd/system +- $(INSTALL_DATA) lldpad.service $(DESTDIR)/usr/lib/systemd/system/lldpad.service +- $(INSTALL_DATA) lldpad.socket $(DESTDIR)/usr/lib/systemd/system/lldpad.socket +- +-BASH_COMPLETION_DIR=/etc/bash_completion.d/ +- +-install-data-hook: +- ## provide support for bash completion +- $(MKDIR_P) $(DESTDIR)/$(BASH_COMPLETION_DIR) +- $(INSTALL_DATA) ${srcdir}/contrib/bash_completion/* $(DESTDIR)/$(BASH_COMPLETION_DIR) +- +-uninstall-local: +- rm -f '$(DESTDIR)/usr/lib/systemd/system/lldpad.*' +- rm -f '$(includedir)/dcbd/clif_cmds.h' +- rm -f '$(includedir)/dcbd' ++bashcompletiondir = $(sysconfdir)/bash_completion.d ++dist_bashcompletion_DATA = contrib/bash_completion/lldpad contrib/bash_completion/lldptool + +-- +2.1.0 + diff --git a/SOURCES/open-lldp-v1.0.1-18-enabled-test-tool-building-for-distcheck.patch b/SOURCES/open-lldp-v1.0.1-18-enabled-test-tool-building-for-distcheck.patch new file mode 100644 index 0000000..6590ef8 --- /dev/null +++ b/SOURCES/open-lldp-v1.0.1-18-enabled-test-tool-building-for-distcheck.patch @@ -0,0 +1,26 @@ +From 0d2fa5cd29b8ce60c5b1dfc2a68e09794e9073c8 Mon Sep 17 00:00:00 2001 +From: Chris Leech +Date: Fri, 30 Jan 2015 08:21:41 +0000 +Subject: [PATCH] enabled test tool building for distcheck + +set the --enable-debug flag when running distcheck, to test build the +debug tools as well + +Signed-off-by: Chris Leech +Signed-off-by: John Fastabend +--- + Makefile.am | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/Makefile.am b/Makefile.am +index 69deda2..b1c381b 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -139,3 +139,4 @@ dist_systemdsystemunit_DATA = lldpad.service lldpad.socket + bashcompletiondir = $(sysconfdir)/bash_completion.d + dist_bashcompletion_DATA = contrib/bash_completion/lldpad contrib/bash_completion/lldptool + ++AM_DISTCHECK_CONFIGURE_FLAGS = --enable-debug +-- +2.1.0 + diff --git a/SOURCES/open-lldp-v1.0.1-19-nltest-build-error.patch b/SOURCES/open-lldp-v1.0.1-19-nltest-build-error.patch new file mode 100644 index 0000000..d0427a4 --- /dev/null +++ b/SOURCES/open-lldp-v1.0.1-19-nltest-build-error.patch @@ -0,0 +1,40 @@ +From 53ebbfd6dd8cf475884fd523207e354696a0670d Mon Sep 17 00:00:00 2001 +From: Chris Leech +Date: Fri, 30 Jan 2015 08:21:42 +0000 +Subject: [PATCH] nltest build error +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +test/nltest.c: In function ‘set_hw_bcn’: +test/nltest.c:994:38: error: iteration 8u invokes undefined behavior +[-Werror=aggressive-loop-optimizations] + bcn_data->up_settings[i].rp_admin = 1; + ^ +test/nltest.c:993:3: note: containing loop + for (i = 0; i <= 8; i++) { + ^ +cc1: all warnings being treated as errors + +Signed-off-by: Chris Leech +Signed-off-by: John Fastabend +--- + test/nltest.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test/nltest.c b/test/nltest.c +index da05463..cd28977 100644 +--- a/test/nltest.c ++++ b/test/nltest.c +@@ -990,7 +990,7 @@ static int set_hw_bcn(char *device_name, bcn_cfg *bcn_data, + oper_mode = 1; + + { +- for (i = 0; i <= 8; i++) { ++ for (i = 0; i < 8; i++) { + bcn_data->up_settings[i].rp_admin = 1; + } + bcn_data->rp_alpha = 0.5; +-- +2.1.0 + diff --git a/SOURCES/open-lldp-v1.0.1-2-VDP-vdptool-first-version.patch b/SOURCES/open-lldp-v1.0.1-2-VDP-vdptool-first-version.patch new file mode 100644 index 0000000..f1918c7 --- /dev/null +++ b/SOURCES/open-lldp-v1.0.1-2-VDP-vdptool-first-version.patch @@ -0,0 +1,1671 @@ +From 3b559d8d0b52e6a254dc3f59833de4308e18711e Mon Sep 17 00:00:00 2001 +From: Thomas Richter +Date: Wed, 21 Jan 2015 03:36:26 +0000 +Subject: [PATCH] VDP: vdptool first version + +This is the first version of a vdp command line interface +tool to send and retrieve data to the vdp22 module. +This tool follows similar concept as the lldptool. +The command line options are similar and some intended +functionality (such as -n to retrieve neighbor inforamtion, +that is tlv data send by bridges) is not yet implemented. + +Signed-off-by: Thomas Richter +Signed-off-by: John Fastabend +--- + .gitignore | 1 + + Makefile.am | 8 +- + docs/vdptool.8 | 280 +++++++++++ + include/qbg_vdp22_clif.h | 2 + + qbg/vdp22_clif.c | 141 ++++++ + vdptool.c | 1149 ++++++++++++++++++++++++++++++++++++++++++++++ + 6 files changed, 1579 insertions(+), 2 deletions(-) + create mode 100644 docs/vdptool.8 + create mode 100644 qbg/vdp22_clif.c + create mode 100644 vdptool.c + +diff --git a/.gitignore b/.gitignore +index c2ac5d7..e2230d9 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -31,6 +31,7 @@ missing + dcbtool + lldpad + lldptool ++vdptool + nltest + vdptest + qbg22sim +diff --git a/Makefile.am b/Makefile.am +index 4889d32..fc4f8d6 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -1,5 +1,5 @@ + # target programs to be installed in ${sbindir} +-sbin_PROGRAMS = lldpad dcbtool lldptool ++sbin_PROGRAMS = lldpad dcbtool lldptool vdptool + + # package nltest and vdptest, but do not install it anywhere + if BUILD_DEBUG +@@ -41,7 +41,7 @@ include/parse_cli.h include/version.h include/lldptool_cli.h include/list.h \ + include/lldp_mand_clif.h include/lldp_basman_clif.h include/lldp_med_clif.h \ + include/lldp_8023_clif.h include/lldp_dcbx_clif.h include/lldp_evb_clif.h \ + include/lldp_evb22_clif.h include/qbg_vdp_clif.h include/qbg_vdpnl.h \ +-include/lldp_8021qaz_clif.h \ ++include/qbg_vdp22_clif.h include/lldp_8021qaz_clif.h \ + include/lldp_orgspec_clif.h include/lldp_cisco_clif.h \ + include/lldptool.h include/lldp_rtnl.h include/dcbtool.h include/lldp_dcbx_cfg.h + +@@ -76,6 +76,10 @@ 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_LDADD = ${srcdir}/liblldp_clif.la ++vdptool_LDFLAGS = -llldp_clif $(LIBNL_LIBS) ++ + dcbtool_SOURCES = dcbtool.c dcbtool_cmds.c parse_cli.l \ + weak_readline.c $(lldpad_include_HEADERS) $(noinst_HEADERS) + dcbtool_LDADD = ${srcdir}/liblldp_clif.la +diff --git a/docs/vdptool.8 b/docs/vdptool.8 +new file mode 100644 +index 0000000..5110bb9 +--- /dev/null ++++ b/docs/vdptool.8 +@@ -0,0 +1,280 @@ ++.\" LICENSE ++.\" ++.\" This software program is released under the terms of a license agreement ++.\" between you ('Licensee') and Intel. Do not use or load this software or ++.\" any associated materials (collectively, the 'Software') until you have ++.\" carefully read the full terms and conditions of the LICENSE located in this ++.\" software package. By loading or using the Software, you agree to the ++.\" terms of this Agreement. If you do not agree with the terms of this ++.\" Agreement, do not install or use the Software. ++.\" ++.\" * Other names and brands may be claimed as the property of others. ++.\" ++.TH vdptool 8 "April 2014" "open-lldp" "Linux" ++.SH NAME ++vdptool \- manage the VSI associations and status of lldpad ++.SH SYNOPSIS ++.B vdptool [options] [argument] ++.br ++.SH DESCRIPTION ++.B vdptool ++is used to query and configure the VSI associations in ++.B lldpad. ++Only the ratified stardard version of the VDP protocol ++(also refered to as vdp22) is supported. ++It connects to the client interface of ++.B lldpad ++to perform these operations. ++.B vdptool ++will operate in interactive mode if it is executed without a \fIcommand\fR. ++In interactive mode, ++.B vdptool ++will also function as an event listener to print out events ++as they are received asynchronously from ++.BR lldpad "(still to be done)." ++It will use libreadline for interactive input when available ++(still to be done). ++.SH OPTIONS ++.TP ++.B \-i [ifname] ++specifies the network interface to which the command applies. Most ++.B vdptool ++commands require specifying a network interface. ++.TP ++.B -V [tlvid] ++specifies the VDP tlv identifier to be set or queried. ++.br ++The tlvid is an integer value used to identify specific ++VDP TLVs. The tlvid value is the type value for types not equal ++to 127 (the organizationally specific type). ++For organizationally specific ++TLVs, the tlvid is the value represented by the 3 byte OUI and 1 byte ++subtype - where the subtype is the lowest order byte of the tlvid. ++.br ++The tlvid can be entered as a numerical value (e.g. 10 or 0xa), or for ++supported TLVs, as a keyword (such as assoc, deassoc, preassoc, ++preassoc-rr, etc). ++Review the ++.B vdptool ++help output to see the list of supported TLV keywords. ++.sp 1 ++Use option -c to specify the parameters and its values to be set or queried. ++.TP ++.B \-n ++"neighbor" option for commands which can use it (e.g. get-tlv). ++Use this flag to retrieve the last VDP22 data returned from the ++bridge. ++(not yet supported). ++.TP ++.B \-c ++Specifies additional parameters for TLV queries and associations commands. ++The argument list varies, depending on the command option ++.B (-T) ++or ++.BR (-t) . ++To establish a VSI association use the command option ++.B (-T) ++and specify additional information as arguments in the form ++of key=value. See the ++.I "VSI Parameter" ++subsection and ++.I Example ++section below. ++To query a VSI specific association use the command option ++.B (-t) ++and specify the value of the ++VSI Instance Identifier (keywork uuid followed be the VSI ++UUID value) ++of the VSI association as configuration parameter. ++.TP ++.B \-r ++show raw client interface messages ++.TP ++.B \-R ++show only raw Client interface messages ++.SS VSI Parameter ++Each VDP22 TLVs contains a command mode, manager identifier, ++type identifier, type identifier version, VSI instance identifier, ++migiration hints and filter information. ++The fields are explained next: ++.TP ++.B "mode (Command Mode):" ++The command mode determines the type ++of the VSI association to be established. ++It is an ascii string can be one of: ++.RS ++.IP assoc: ++Create an VSI association. ++.IP preassoc: ++Create an VSI preassociation. The association ++is only announced to the switch. ++.IP preassoc-rr: ++Create an VSI preassociation. The association ++is only announced to the switch and the ++switch should reserve the resources. ++.IP deassoc: ++Delete an VSI association. ++.RE ++Other strings are not recognized and return an error. ++.TP ++.B "mgrid2 (Manager identifier):" ++The manager identifier is a string of up to 16 ++alphanumeric characters. ++It can also be an UUID according to RFC 4122 ++with optional dashes in between. ++.TP ++.B "typeid (Type Identifier):" ++The type identifier is a number in the range ++of 0 to 2^24 - 1. ++.TP ++.B "typeidver (Type Identifier Version):" ++The type identifer version is a number ++in the range of 0 to 255. ++.TP ++.B "uuid (VSI Instance Identifier):" ++The VSI instance identifier is ++an UUID according to RFC 4122 ++with optional dashes in between. ++.TP ++.B "hints (Migration Hints):" ++The migiration hints is a string aiding in ++migration of virtual machines: ++.RS ++.IP none: ++No hints available. ++.IP from: ++The virtual machine is migrating away. ++.IP to: ++The virtual machine is migrating to. ++.RE ++.TP ++.B "fid (Filter Information Data):" ++The filter information data can be supplied in four ++different formats identified by numbers in parathesis. ++Multiple filter information fields can be supplied, ++but all have to be of the same format. ++.RS ++.IP "vlan (1)" ++A vlan number only, also known as filter information format 1. ++The vlan identifier is a number in the range of 1 to 2^16 - 1. ++The high order 4 bits are used as quality of service bits. ++The vlan identifier can be zero, a vlan identifier is then ++selected by the switch. Refer to IEEE 802.1 Qbg ratified ++standard for details. ++.IP "vlan-mac (2)" ++A vlan number and MAC address delimited by a slash ('-'), ++also known as filter information format 2. ++The MAC address is specified in the format xx:xx:xx:xx:xx:xx. ++The colons are mandatory. ++For vlan details see (1). ++.IP "vlan-mac-group (4)" ++A vlan number, MAC address and group identifier, ++each delimited by a slash ('-'), ++also known as filter information format 4. ++The group identifier is a 32 bit number. ++For vlan and MAC address details see (1) and (2). ++.IP "vlan--group (3)" ++A vlan number and group identifier, ++delimited by two slashes ('--'), ++also known as filter information format 3. ++For vlan and group details see (1) and (4). ++.RE ++.SH COMMANDS ++.TP ++.B license ++show license information ++.TP ++.B \-h, help ++show usage information ++.TP ++.B \-v, version ++show version information ++.TP ++.B \-t, get-tlv ++get TLV information for the specified interface ++.TP ++.B \-T, set-tlv ++set TLV information for the specified interface ++.TP ++.B \-p, ping ++display the process identifier of the running lldpad process ++.TP ++.B \-q, quit ++exit from interactive mode ++.PP ++.SH NOTES ++This tool is in its early design and development phase. ++It it buggy, incomplete and most of the ideas have not even ++been thought of.... ++It reflects the current state of development when ++I had been given another work assignment. ++I append it so some else can continue to work on this. ++.SH EXAMPLES ++.TP ++Display process identifier of lldpad ++.br ++vdptool -p ++.TP ++Create a VSI association on interface eth2 ++.br ++.nf ++Supported today: One config parameter and comma separated list ++vdptool -i eth2 -T -V assoc -c vsi=assoc,blabla,5, \\ ++ 1122,4,none,2-52:00:00:11:22:33-200 ++ ++Planned for the future: ++vdptool -i eth2 -T -V assoc -c mgrid2=blabla -c typeid=5 \\ ++ -c uuid=1122 -c typeidver=4 -c hints=none -c fid=2-52:00:00:11:22:33-200 ++.fi ++.TP ++Query all VSI association on interface eth2 ++.br ++vdptool -i eth2 -t -V assoc ++.SH SEE ALSO ++.BR lldptool-dcbx (8), ++.BR lldptool-ets (8), ++.BR lldptool-pfc (8), ++.BR lldptool-app (8), ++.BR lldptool-med (8), ++.BR lldptool-vdp (8), ++.BR lldptool-evb (8), ++.BR lldptool-evb22 (8), ++.BR dcbtool (8), ++.BR lldpad (8) ++.br ++.SH COPYRIGHT ++vdptool - VSI configuration utility ++.br ++.IP Copyright(c) ++(c) 2014 IBM Corporation. ++.BR ++Portions of vdptool are based on: ++.IP open-lldp-0.96 ++.IP "lldptool - LLDP agent configuration utility" ++.IP Copyright(c) ++2007-2012 Intel Corporation. ++.BR ++Portions of lldptool are based on: ++.IP hostapd-0.5.7 ++.IP Copyright ++(c) 2004-2008, Jouni Malinen ++ ++.SH LICENSE ++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. ++.LP ++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. ++.LP ++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. ++.LP ++The full GNU General Public License is included in this distribution in ++the file called "COPYING". ++.SH SUPPORT ++Contact Information: ++open-lldp Mailing List +diff --git a/include/qbg_vdp22_clif.h b/include/qbg_vdp22_clif.h +index 20330b8..008022a 100644 +--- a/include/qbg_vdp22_clif.h ++++ b/include/qbg_vdp22_clif.h +@@ -52,4 +52,6 @@ typedef enum { + op_delete = 0x20, + op_key = 0x40 + } vdp22_op; ++ ++struct lldp_module *vdp22_cli_register(void); + #endif +diff --git a/qbg/vdp22_clif.c b/qbg/vdp22_clif.c +new file mode 100644 +index 0000000..649305d +--- /dev/null ++++ b/qbg/vdp22_clif.c +@@ -0,0 +1,141 @@ ++/******************************************************************************* ++ ++ Implementation of VDP 22 (ratified standard) according to IEEE 802.1Qbg ++ (c) Copyright IBM Corp. 2014 ++ ++ Author(s): Thomas Richter ++ ++ 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 ++#include ++#include ++#include ++ ++#include "lldp_mod.h" ++#include "clif_msgs.h" ++#include "lldp.h" ++#include "qbg22.h" ++#include "qbg_vdp22def.h" ++#include "qbg_vdpnl.h" ++#include "qbg_vdp22_cmds.h" ++#include "qbg_vdp22_clif.h" ++#include "qbg_vdp22def.h" ++ ++static struct type_name_info vdp22_tlv_names[] = { ++ { ++ .name = "VDP VSI Association", ++ .key = "assoc", ++ .type = VDP22_ASSOC ++ }, ++ { ++ .name = "VDP VSI Deassociation", ++ .key = "deassoc", ++ .type = VDP22_DEASSOC ++ }, ++ { ++ .name = "VDP VSI Preassociation", ++ .key = "preassoc", ++ .type = VDP22_PREASSOC ++ }, ++ { ++ .name = "VDP VSI Preassociation with resource reservation", ++ .key = "preassoc-rr", ++ .type = VDP22_PREASSOC_WITH_RR ++ }, ++ { ++ .type = INVALID_TLVID ++ } ++}; ++ ++static int vdp22_print_help(void) ++{ ++ struct type_name_info *tn = &vdp22_tlv_names[0]; ++ ++ while (tn->type != INVALID_TLVID) { ++ if (tn->key && strlen(tn->key) && tn->name) { ++ printf(" %s", tn->key); ++ if (strlen(tn->key) + 3 < 8) ++ printf("\t"); ++ printf("\t: %s\n", tn->name); ++ } ++ tn++; ++ } ++ return 0; ++} ++ ++static u32 vdp22_lookup_tlv_name(char *tlvid_str) ++{ ++ struct type_name_info *tn = &vdp22_tlv_names[0]; ++ ++ while (tn->type != INVALID_TLVID) { ++ if (!strcasecmp(tn->key, tlvid_str)) ++ return tn->type; ++ tn++; ++ } ++ return INVALID_TLVID; ++} ++ ++static void vdp22_cli_unregister(struct lldp_module *mod) ++{ ++ free(mod); ++} ++ ++/* return 1: if it printed the TLV ++ * 0: if it did not ++ */ ++static int vdp22_print_tlv(u32 tlvid, u16 len, char *info) ++{ ++ struct type_name_info *tn = &vdp22_tlv_names[0]; ++ ++ while (tn->type != INVALID_TLVID) { ++ if (tlvid == tn->type) { ++ printf("%s\n", tn->name); ++ if (tn->print_info) { ++ printf("\t"); ++ tn->print_info(len - 4, info); ++ } ++ return 1; ++ } ++ tn++; ++ } ++ return 0; ++} ++ ++static const struct lldp_mod_ops vdp22_ops_clif = { ++ .lldp_mod_register = vdp22_cli_register, ++ .lldp_mod_unregister = vdp22_cli_unregister, ++ .print_tlv = vdp22_print_tlv, ++ .lookup_tlv_name = vdp22_lookup_tlv_name, ++ .print_help = vdp22_print_help, ++}; ++ ++struct lldp_module *vdp22_cli_register(void) ++{ ++ struct lldp_module *mod; ++ ++ mod = malloc(sizeof(*mod)); ++ if (!mod) { ++ fprintf(stderr, "failed to malloc module data\n"); ++ return NULL; ++ } ++ mod->id = LLDP_MOD_VDP22; ++ mod->ops = &vdp22_ops_clif; ++ return mod; ++} +diff --git a/vdptool.c b/vdptool.c +new file mode 100644 +index 0000000..e7d384a +--- /dev/null ++++ b/vdptool.c +@@ -0,0 +1,1149 @@ ++/******************************************************************************* ++ ++ LLDP Agent Daemon (LLDPAD) Software ++ Copyright(c) IBM Corp. 2014 ++ ++ Substantially modified from: ++ hostapd-0.5.7 ++ Copyright (c) 2002-2007, Jouni Malinen and ++ contributors ++ ++ 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". ++ ++ Contact Information: ++ open-lldp Mailing List ++ ++*******************************************************************************/ ++ ++/* ++ * Thomas Richter, IBM LTC Boeblingen, Germany, Feb 2014 ++ * ++ * Command line interface tool to connect to vdp module of lldpad to ++ * set and query VSI profile settings. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "version.h" ++#include "clif.h" ++#include "clif_msgs.h" ++#include "lldp_mod.h" ++ ++#include "qbg22.h" ++#include "qbg_vdp22_clif.h" ++ ++static char *print_status(cmd_status status) ++{ ++ char *str; ++ ++ switch (status) { ++ case cmd_success: ++ str = "Successful"; ++ break; ++ case cmd_failed: ++ str = "Failed"; ++ break; ++ case cmd_device_not_found: ++ str = "Device not found or inactive"; ++ break; ++ case cmd_agent_not_found: ++ str = "Agent instance for device not found"; ++ break; ++ case cmd_invalid: ++ str = "Invalid command"; ++ break; ++ case cmd_bad_params: ++ str = "Invalid parameters"; ++ break; ++ case cmd_peer_not_present: ++ str = "Peer feature not present"; ++ break; ++ case cmd_ctrl_vers_not_compatible: ++ str = "Version not compatible"; ++ break; ++ case cmd_not_capable: ++ str = "Device not capable"; ++ break; ++ case cmd_not_applicable: ++ str = "Command not applicable"; ++ break; ++ case cmd_no_access: ++ str = "Access denied"; ++ break; ++ case cmd_agent_not_supported: ++ str = "TLV does not support agent type"; ++ break; ++ default: ++ str = "Unknown status"; ++ break; ++ } ++ return str; ++} ++ ++static void get_arg_value(char *str, char **arg, char **argval) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < strlen(str); i++) ++ if (!isprint(str[i])) ++ return; ++ ++ for (i = 0; i < strlen(str); i++) ++ if (str[i] == '=') ++ break; ++ ++ if (i < strlen(str)) { ++ str[i] = '\0'; ++ *argval = &str[i+1]; ++ } ++ *arg = str; ++} ++ ++static int render_cmd(struct cmd *cmd, int argc, char **args, char **argvals) ++{ ++ int len; ++ int i; ++ ++ len = sizeof(cmd->obuf); ++ ++ /* all command messages begin this way */ ++ snprintf(cmd->obuf, len, "%c%08x%c%1x%02x%08x%02x%s%02x%08x", ++ MOD_CMD, cmd->module_id, CMD_REQUEST, CLIF_MSG_VERSION, ++ cmd->cmd, cmd->ops, (unsigned int) strlen(cmd->ifname), ++ cmd->ifname, cmd->type, cmd->tlvid); ++#if PADDU ++ if (cmd->cmd == cmd_settlv) { ++ size_t len2 = 0; ++ /* ++ * Get total length and append it plus any args and argvals ++ * to the command message ++ */ ++ for (i = 0; i < argc; i++) { ++ if (args[i]) ++ len2 += 2 + strlen(args[i]); ++ if (argvals[i]) ++ len2 += 4 + strlen(argvals[i]); ++ } ++ snprintf(cmd->obuf + strlen(cmd->obuf), len - strlen(cmd->obuf), ++ "%04zx", len2); ++ } ++#endif ++ /* Add any args and argvals to the command message */ ++ for (i = 0; i < argc; i++) { ++ if (args[i]) ++ snprintf(cmd->obuf + strlen(cmd->obuf), ++ len - strlen(cmd->obuf), ++ "%02x%s", (unsigned int)strlen(args[i]), ++ args[i]); ++ if (argvals[i]) ++ snprintf(cmd->obuf + strlen(cmd->obuf), ++ len - strlen(cmd->obuf), "%04x%s", ++ (unsigned int)strlen(argvals[i]), argvals[i]); ++ } ++ return strlen(cmd->obuf); ++} ++ ++int vdp_clif_command(struct clif *, char *, int); ++ ++static int vdp_cmd_gettlv(struct clif *clif, int argc, char *argv[], ++ struct cmd *cmd, int raw) ++{ ++ int numargs = 0; ++ char **args; ++ char **argvals; ++ int i; ++ ++ if (cmd->cmd != cmd_gettlv) ++ return cmd_invalid; ++ ++ args = calloc(argc, sizeof(char *)); ++ if (!args) ++ return cmd_failed; ++ ++ argvals = calloc(argc, sizeof(char *)); ++ if (!argvals) { ++ free(args); ++ return cmd_failed; ++ } ++ ++ for (i = 0; i < argc; i++) ++ get_arg_value(argv[i], &args[i], &argvals[i]); ++ numargs = i; ++ ++ /* Default is local tlv query */ ++ if (!(cmd->ops & op_neighbor)) ++ cmd->ops |= op_local; ++ ++ if (numargs) { ++ /* Only commands with the config option should have arguments.*/ ++ if (!(cmd->ops & op_config)) { ++ printf("%s\n", print_status(cmd_invalid)); ++ goto out; ++ } ++ ++ /* Commands to get neighbor TLVs cannot have arguments. */ ++ if (cmd->ops & op_neighbor) { ++ printf("%s\n", print_status(cmd_invalid)); ++ goto out; ++ } ++ cmd->ops |= op_arg; ++ } ++ ++ for (i = 0; i < numargs; i++) { ++ if (argvals[i]) { ++ printf("%s\n", print_status(cmd_invalid)); ++ goto out; ++ } ++ } ++ ++ render_cmd(cmd, argc, args, argvals); ++ free(args); ++ free(argvals); ++ return vdp_clif_command(clif, cmd->obuf, raw); ++out: ++ free(args); ++ free(argvals); ++ return cmd_invalid; ++} ++ ++static int vdp_cmd_settlv(struct clif *clif, int argc, char *argv[], ++ struct cmd *cmd, int raw) ++{ ++ int numargs = 0; ++ char **args; ++ char **argvals; ++ int i; ++ ++ if (cmd->cmd != cmd_settlv) ++ return cmd_invalid; ++ args = calloc(argc, sizeof(char *)); ++ if (!args) ++ return cmd_failed; ++ ++ argvals = calloc(argc, sizeof(char *)); ++ if (!argvals) { ++ free(args); ++ return cmd_failed; ++ } ++ ++ for (i = 0; i < argc; i++) ++ get_arg_value(argv[i], &args[i], &argvals[i]); ++ numargs = i; ++ ++ for (i = 0; i < numargs; i++) { ++ if (!argvals[i]) { ++ printf("%s\n", print_status(cmd_invalid)); ++ goto out; ++ } ++ } ++ ++ if (numargs) ++ cmd->ops |= (op_arg | op_argval); ++ ++ render_cmd(cmd, argc, args, argvals); ++ free(args); ++ free(argvals); ++ return vdp_clif_command(clif, cmd->obuf, raw); ++out: ++ free(args); ++ free(argvals); ++ return cmd_invalid; ++} ++ ++static int hex2u8(char *b) ++{ ++ int hex = -1; ++ ++ if (isxdigit(*b) && isxdigit(*(b + 1))) ++ sscanf(b, "%02x", &hex); ++ return hex; ++} ++ ++static int hex2u16(char *b) ++{ ++ int hex = -1; ++ ++ if (isxdigit(*b) && isxdigit(*(b + 1)) && isxdigit(*(b + 2)) ++ && isxdigit(*(b + 3))) ++ sscanf(b, "%04x", &hex); ++ return hex; ++} ++ ++static int hex2u32(char *b) ++{ ++ int hex; ++ char *b_old = b; ++ ++ for (hex = 0; hex < 8; ++hex) ++ if (!isxdigit(*b++)) ++ return -1; ++ sscanf(b_old, "%08x", &hex); ++ return hex; ++} ++ ++static int vdp_parse_response(char *buf) ++{ ++ return hex2u8(buf + CLIF_STAT_OFF); ++} ++ ++static void print_pair(char *arg, size_t arglen, char *value, size_t valuelen) ++{ ++ while (arglen--) ++ putchar(*arg++); ++ putchar('='); ++ while (valuelen--) ++ putchar(*value++); ++ putchar('\n'); ++} ++ ++static int print_arg_value(char *ibuf) ++{ ++ int arglen, valuelen, offset = 0, ilen = strlen(ibuf); ++ char *arg, *value; ++ ++ while (offset < ilen) { ++ /* Length of argument */ ++ arglen = hex2u8(ibuf + offset); ++ if (arglen < 0) ++ break; ++ offset += 2; ++ arg = ibuf + offset; ++ offset += arglen; ++ ++ /* Length of argument value */ ++ valuelen = hex2u16(ibuf + offset); ++ if (valuelen < 0) ++ break; ++ offset += 4; ++ value = ibuf + offset; ++ offset += valuelen; ++ ++ print_pair(arg, arglen, value, valuelen); ++ } ++ return offset; ++} ++ ++static int get_tlvid(char *ibuf) ++{ ++ return hex2u32(ibuf); ++} ++ ++/* ++ * Print a TLV. ++ */ ++static void print_tlv2(char *ibuf) ++{ ++ size_t ilen = strlen(ibuf); ++ u16 tlv_type; ++ u16 tlv_len; ++ u32 tlvid; ++ int offset = 0; ++ int printed; ++ struct lldp_module *np; ++ ++ while (ilen > 0) { ++ tlv_len = 2 * sizeof(u16); ++ if (ilen < 2 * sizeof(u16)) { ++ printf("corrupted TLV ilen:%zd, tlv_len:%d\n", ++ ilen, tlv_len); ++ break; ++ } ++ tlv_type = hex2u16(ibuf + offset); ++ tlv_len = tlv_type; ++ tlv_type >>= 9; ++ tlv_len &= 0x01ff; ++ offset += 2 * sizeof(u16); ++ ilen -= 2 * sizeof(u16); ++ ++ if (ilen < (unsigned) 2 * tlv_len) { ++ printf("corrupted TLV ilen:%zd, tlv_len:%d\n", ++ ilen, tlv_len); ++ break; ++ } ++ tlvid = tlv_type; ++ if (tlvid == INVALID_TLVID) { ++ tlvid = get_tlvid(ibuf + offset); ++ offset += 8; ++ } ++ printed = 0; ++ LIST_FOREACH(np, &lldp_head, lldp) { ++ if (np->ops->print_tlv(tlvid, tlv_len, ibuf + offset)) { ++ printed = 1; ++ break; ++ } ++ } ++ ++ if (!printed) { ++ if (tlvid < INVALID_TLVID) ++ printf("Unidentified TLV\n\ttype:%d %*.*s\n", ++ tlv_type, tlv_len*2, tlv_len*2, ++ ibuf+offset); ++ else ++ printf("Unidentified Org Specific TLV\n\t" ++ "OUI: 0x%06x, Subtype: %d, Info: %*.*s\n", ++ tlvid >> 8, tlvid & 0x0ff, ++ tlv_len*2-8, tlv_len*2-8, ++ ibuf+offset); ++ } ++ if (tlvid > INVALID_TLVID) ++ offset += (2 * tlv_len - 8); ++ else ++ offset += 2 * tlv_len; ++ ilen -= 2 * tlv_len; ++ if (tlvid == END_OF_LLDPDU_TLV) ++ break; ++ } ++} ++ ++/* Print reply from get command */ ++static void print_tlvs(struct cmd *cmd, char *ibuf) ++{ ++ if (cmd->ops & op_config) { ++ print_arg_value(ibuf); ++ return; ++ } ++ print_tlv2(ibuf); ++} ++ ++static void print_cmd_response(char *ibuf, int status) ++{ ++ struct cmd cmd; ++ unsigned char len; ++ int ioff; ++ ++ if (status != cmd_success) { ++ printf("%s\n", print_status(status)); ++ return; ++ } ++ ++ cmd.cmd = hex2u8(ibuf + CMD_CODE); ++ cmd.ops = hex2u32(ibuf + CMD_OPS); ++ len = hex2u8(ibuf + CMD_IF_LEN); ++ ioff = CMD_IF; ++ if (len < sizeof(cmd.ifname)) { ++ memcpy(cmd.ifname, ibuf + CMD_IF, len); ++ } else { ++ printf("Response ifname too long: %*s\n", (int)len, cmd.ifname); ++ return; ++ } ++ cmd.ifname[len] = '\0'; ++ ioff += len; ++ ++ if (cmd.cmd == cmd_gettlv || cmd.cmd == cmd_settlv) { ++ cmd.tlvid = hex2u32(ibuf + ioff); ++ ioff += 2 * sizeof(cmd.tlvid); ++ } ++ ++ switch (cmd.cmd) { ++ case cmd_gettlv: ++ print_tlvs(&cmd, ibuf + ioff); ++ break; ++ case cmd_settlv: ++ printf("%s", ibuf + ioff); ++ break; ++ default: ++ return; ++ } ++} ++ ++static void vdp_print_response(char *buf, int status) ++{ ++ switch (buf[CLIF_RSP_OFF]) { ++ case PING_CMD: ++ if (status) ++ printf("FAILED:%s\n", print_status(status)); ++ else ++ printf("%s\n", buf + CLIF_RSP_OFF + 5); ++ break; ++ case ATTACH_CMD: ++ case DETACH_CMD: ++ if (status) ++ printf("FAILED:%s\n", print_status(status)); ++ else ++ printf("OK\n"); ++ break; ++ case CMD_REQUEST: ++ print_cmd_response(buf + CLIF_RSP_OFF, status); ++ break; ++ default: ++ printf("Unknown VDP command response: %s\n", buf); ++ break; ++ } ++} ++ ++static void vdp_print_event_msg(char *buf) ++{ ++ printf("%s buf:%s\n", __func__, buf); ++} ++ ++/* ++ * Dummy function to avoid linkage of many sources ++ */ ++int get_perm_hwaddr(UNUSED const char *ifname, UNUSED unsigned char *buf_perm, ++ UNUSED unsigned char *buf_san) ++{ ++ return -EIO; ++} ++ ++static int show_raw; ++ ++static const char *cli_version = ++ "vdptool v" LLDPTOOL_VERSION "\n" ++ "Copyright (c) 2014, IBM Corporation\n"; ++ ++ ++static const char *cli_license = ++"This program is free software. You can distribute it and/or modify it\n" ++"under the terms of the GNU General Public License version 2.\n" ++"\n"; ++/* ++"Alternatively, this software may be distributed under the terms of the\n" ++"BSD license. See README and COPYING for more details.\n"; ++*/ ++ ++static const char *cli_full_license = ++"This program is free software; you can redistribute it and/or modify\n" ++"it under the terms of the GNU General Public License version 2 as\n" ++"published by the Free Software Foundation.\n" ++"\n" ++"This program is distributed in the hope that it will be useful,\n" ++"but WITHOUT ANY WARRANTY; without even the implied warranty of\n" ++"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" ++"GNU General Public License for more details.\n" ++"\n" ++"You should have received a copy of the GNU General Public License\n" ++"along with this program; if not, write to the Free Software\n" ++"Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n" ++"\n" ++"Alternatively, this software may be distributed under the terms of the\n" ++"BSD license.\n" ++"\n" ++"Redistribution and use in source and binary forms, with or without\n" ++"modification, are permitted provided that the following conditions are\n" ++"met:\n" ++"\n" ++"1. Redistributions of source code must retain the above copyright\n" ++" notice, this list of conditions and the following disclaimer.\n" ++"\n" ++"2. Redistributions in binary form must reproduce the above copyright\n" ++" notice, this list of conditions and the following disclaimer in the\n" ++" documentation and/or other materials provided with the distribution.\n" ++"\n" ++"3. Neither the name(s) of the above-listed copyright holder(s) nor the\n" ++" names of its contributors may be used to endorse or promote products\n" ++" derived from this software without specific prior written permission.\n" ++"\n" ++"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n" ++"\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n" ++"LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n" ++"A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n" ++"OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n" ++"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n" ++"LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n" ++"DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n" ++"THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n" ++"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n" ++"OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" ++"\n"; ++ ++static const char *commands_usage = ++"Usage:\n" ++" vdptool [options] [arg] general command line usage format\n" ++" vdptool go into interactive mode\n" ++" [options] [arg] general interactive command format\n"; ++ ++static const char *commands_options = ++"Options:\n" ++" -i [ifname] network interface\n" ++" -V [tlvid] TLV identifier\n" ++" may be numeric or keyword (see below)\n" ++" -c used with get TLV command to specify\n" ++" that the list of configuration elements\n" ++" -n \"neighbor\" option for command (To be done)\n" ++" -r show raw message\n" ++" -R show only raw messages\n"; ++ ++static const char *commands_help = ++"Commands:\n" ++" license show license information\n" ++" -h|help show command usage information\n" ++" -v|version show version\n" ++" -p|ping ping lldpad and query pid of lldpad\n" ++" -q|quit exit lldptool (interactive mode)\n" ++" -t|get-tlv get tlvid value\n" ++" -T|set-tlv set arg for tlvid to value\n"; ++ ++static struct clif *clif_conn; ++static int cli_quit; ++static int cli_attached; ++ ++/* ++ * insert to head, so first one is last ++ */ ++struct lldp_module *(*register_tlv_table[])(void) = { ++ vdp22_cli_register, ++ NULL, ++}; ++ ++static void init_modules(void) ++{ ++ struct lldp_module *module; ++ struct lldp_module *premod = NULL; ++ int i = 0; ++ ++ LIST_INIT(&lldp_head); ++ for (i = 0; register_tlv_table[i]; i++) { ++ module = register_tlv_table[i](); ++ if (premod) ++ LIST_INSERT_AFTER(premod, module, lldp); ++ else ++ LIST_INSERT_HEAD(&lldp_head, module, lldp); ++ premod = module; ++ } ++} ++ ++void deinit_modules(void) ++{ ++ struct lldp_module *module; ++ ++ while (lldp_head.lh_first != NULL) { ++ module = lldp_head.lh_first; ++ LIST_REMOVE(lldp_head.lh_first, lldp); ++ module->ops->lldp_mod_unregister(module); ++ } ++} ++ ++static void usage(void) ++{ ++ fprintf(stderr, "%s\n", cli_version); ++ fprintf(stderr, "\n%s\n%s\n%s\n", ++ commands_usage, commands_options, commands_help); ++} ++ ++static void print_raw_message(char *msg, int print) ++{ ++ if (!print || !(print & SHOW_RAW)) ++ return; ++ ++ if (!(print & SHOW_RAW_ONLY)) { ++ switch (msg[MSG_TYPE]) { ++ case EVENT_MSG: ++ printf("event: "); ++ break; ++ case CMD_RESPONSE: ++ printf("rsp: "); ++ break; ++ default: ++ printf("cmd: "); ++ break; ++ } ++ } ++ printf("%s\n", msg); ++} ++ ++static int parse_print_message(char *msg, int print) ++{ ++ int status = 0; ++ ++ status = vdp_parse_response(msg); ++ print_raw_message(msg, print); ++ if (print & SHOW_RAW_ONLY) ++ return status; ++ ++ if (msg[MSG_TYPE] == CMD_RESPONSE) ++ vdp_print_response(msg, status); ++ else if (msg[MSG_TYPE] == MOD_CMD && msg[MOD_MSG_TYPE] == EVENT_MSG) ++ vdp_print_event_msg(&msg[MOD_MSG_TYPE]); ++ return status; ++} ++ ++static void cli_close_connection(void) ++{ ++ if (clif_conn == NULL) ++ return; ++ ++ if (cli_attached) { ++ clif_detach(clif_conn); ++ cli_attached = 0; ++ } ++ clif_close(clif_conn); ++ clif_conn = NULL; ++} ++ ++ ++static void cli_msg_cb(char *msg, UNUSED size_t len) ++{ ++ parse_print_message(msg, SHOW_OUTPUT | show_raw); ++} ++ ++ ++/* structure of the print argument bitmap: ++ * SHOW_NO_OUTPUT (0x0) - don't print anything for the command ++ * SHOW_OUTPUT (0x01) - print output for the command ++ * SHOW_RAW (0x02) - print the raw clif command messages ++ * SHOW_RAW_ONLY (0x04) - print only the raw clif command messages ++*/ ++static int _clif_command(struct clif *clif, char *cmd, int print) ++{ ++ char buf[MAX_CLIF_MSGBUF]; ++ size_t len; ++ int ret; ++ ++ print_raw_message(cmd, print); ++ ++ if (clif_conn == NULL) { ++ printf("Not connected to lldpad - command dropped.\n"); ++ return -1; ++ } ++ len = sizeof(buf) - 1; ++ ret = clif_request(clif, cmd, strlen(cmd), buf, &len, cli_msg_cb); ++ if (ret == -2) { ++ printf("'%s' command timed out.\n", cmd); ++ return -2; ++ } else if (ret < 0) { ++ printf("'%s' command failed.\n", cmd); ++ return -1; ++ } ++ if (print) { ++ buf[len] = '\0'; ++ ret = parse_print_message(buf, print); ++ } ++ ++ return ret; ++} ++ ++int vdp_clif_command(struct clif *clif, char *cmd, int raw) ++{ ++ return _clif_command(clif, cmd, SHOW_OUTPUT | raw); ++} ++ ++static int cli_cmd_ping(struct clif *clif, UNUSED int argc, UNUSED char *argv[], ++ UNUSED struct cmd *command, int raw) ++{ ++ return vdp_clif_command(clif, "P", raw); ++} ++ ++static int ++cli_cmd_nop(UNUSED struct clif *clif, UNUSED int argc, UNUSED char *argv[], ++ UNUSED struct cmd *command, UNUSED int raw) ++{ ++ return 0; ++} ++ ++static int ++cli_cmd_help(UNUSED struct clif *clif, UNUSED int argc, UNUSED char *argv[], ++ UNUSED struct cmd *command, UNUSED int raw) ++{ ++ struct lldp_module *np; ++ ++ printf("%s\n%s\n%s", commands_usage, commands_options, commands_help); ++ ++ printf("\nTLV identifiers:\n"); ++ LIST_FOREACH(np, &lldp_head, lldp) ++ if (np->ops->print_help) ++ np->ops->print_help(); ++ return 0; ++} ++ ++static int ++cli_cmd_version(UNUSED struct clif *clif, UNUSED int argc, UNUSED char *argv[], ++ UNUSED struct cmd *command, UNUSED int raw) ++{ ++ printf("%s\n", cli_version); ++ return 0; ++} ++ ++static int ++cli_cmd_license(UNUSED struct clif *clif, UNUSED int argc, UNUSED char *argv[], ++ UNUSED struct cmd *command, UNUSED int raw) ++{ ++ printf("%s\n", cli_full_license); ++ return 0; ++} ++ ++static int ++cli_cmd_quit(UNUSED struct clif *clif, UNUSED int argc, UNUSED char *argv[], ++ UNUSED struct cmd *command, UNUSED int raw) ++{ ++ cli_quit = 1; ++ return 0; ++} ++ ++static struct cli_cmd { ++ vdp22_cmd cmdcode; ++ const char *cmdstr; ++ int (*handler)(struct clif *clif, int argc, char *argv[], ++ struct cmd *cmd, int raw); ++} cli_commands[] = { ++ { cmd_ping, "ping", cli_cmd_ping }, ++ { cmd_help, "help", cli_cmd_help }, ++ { cmd_license, "license", cli_cmd_license }, ++ { cmd_version, "version", cli_cmd_version }, ++ { cmd_quit, "quit", cli_cmd_quit }, ++ { cmd_gettlv, "gettlv", vdp_cmd_gettlv }, ++ { cmd_gettlv, "get-tlv", vdp_cmd_gettlv }, ++ { cmd_settlv, "settlv", vdp_cmd_settlv }, ++ { cmd_settlv, "set-tlv", vdp_cmd_settlv }, ++ { cmd_nop, NULL, cli_cmd_nop } ++}; ++ ++u32 lookup_tlvid(char *tlvid_str) ++{ ++ struct lldp_module *np; ++ u32 tlvid = INVALID_TLVID; ++ ++ LIST_FOREACH(np, &lldp_head, lldp) { ++ if (np->ops->lookup_tlv_name) { ++ tlvid = np->ops->lookup_tlv_name(tlvid_str); ++ if (tlvid != INVALID_TLVID) ++ break; ++ } ++ } ++ ++ return tlvid; ++} ++ ++void print_args(int argc, char *argv[]) ++{ ++ int i; ++ ++ for (i = 0; i < argc; i++) ++ printf("\tremaining arg %d = %s\n", i, argv[i]); ++} ++ ++static struct option lldptool_opts[] = { ++ {"help", 0, NULL, 'h'}, ++ {"version", 0, NULL, 'v'}, ++ {"stats", 0, NULL, 'S'}, ++ {"get-tlv", 0, NULL, 't'}, ++ {"set-tlv", 0, NULL, 'T'}, ++ {"get-lldp", 0, NULL, 'l'}, ++ {"set-lldp", 0, NULL, 'L'}, ++ {0, 0, 0, 0} ++}; ++ ++static int request(struct clif *clif, int argc, char *argv[]) ++{ ++ struct cli_cmd *cmd, *match = NULL; ++ struct cmd command; ++ int count; ++ int ret = 0; ++ int newraw = 0; ++ int numargs = 0; ++ char **argptr = &argv[0]; ++ char *end; ++ int c; ++ int option_index; ++ ++ memset((void *)&command, 0, sizeof(command)); ++ command.cmd = cmd_nop; ++ command.type = NEAREST_CUSTOMER_BRIDGE; ++ command.module_id = LLDP_MOD_VDP22; ++ command.tlvid = INVALID_TLVID; ++ ++ opterr = 0; ++ for (;;) { ++ c = getopt_long(argc, argv, "i:tThcnvrRpqV:", ++ lldptool_opts, &option_index); ++ if (c < 0) ++ break; ++ switch (c) { ++ case '?': ++ printf("missing argument for option %s\n\n", ++ argv[optind-1]); ++ usage(); ++ return -1; ++ case 'i': ++ strncpy(command.ifname, optarg, IFNAMSIZ); ++ command.ifname[IFNAMSIZ] = '\0'; ++ break; ++ case 'V': ++ if (command.tlvid != INVALID_TLVID) { ++ printf("\nInvalid command: multiple TLV identifiers: %s\n", ++ optarg); ++ return -1; ++ } ++ ++ /* Currently tlvid unset lookup and verify parameter */ ++ errno = 0; ++ command.tlvid = strtoul(optarg, &end, 0); ++ if (!command.tlvid || errno || *end != '\0' || ++ end == optarg) ++ command.tlvid = lookup_tlvid(optarg); ++ if (command.tlvid == INVALID_TLVID) { ++ printf("\nInvalid TLV identifier: %s\n", ++ optarg); ++ return -1; ++ } ++ break; ++ case 'p': ++ command.cmd = cmd_ping; ++ break; ++ case 'q': ++ command.cmd = cmd_quit; ++ break; ++ case 't': ++ command.cmd = cmd_gettlv; ++ break; ++ case 'T': ++ command.cmd = cmd_settlv; ++ break; ++ case 'c': ++ command.ops |= op_config; ++ break; ++ case 'n': ++ command.ops |= op_neighbor; ++ break; ++ case 'h': ++ command.cmd = cmd_help; ++ break; ++ case 'r': ++ if (newraw) { ++ usage(); ++ return -1; ++ } ++ newraw = SHOW_RAW; ++ break; ++ case 'R': ++ if (newraw) { ++ usage(); ++ return -1; ++ } ++ newraw = (SHOW_RAW | SHOW_RAW_ONLY); ++ break; ++ case 'v': ++ command.cmd = cmd_version; ++ break; ++ default: ++ usage(); ++ ret = -1; ++ } ++ } ++ ++ /* if no command was supplied via an option flag, then ++ * the first remaining argument should be the command. ++ */ ++ count = 0; ++ if (command.cmd == cmd_nop && optind < argc) { ++ cmd = cli_commands; ++ while (cmd->cmdcode != cmd_nop) { ++ if (strncasecmp(cmd->cmdstr, argv[optind], ++ strlen(argv[optind])) == 0) { ++ match = cmd; ++ command.cmd = match->cmdcode; ++ count++; ++ } ++ cmd++; ++ } ++ } ++ ++ if (count > 1) { ++ printf("Ambiguous command '%s'; possible commands:", ++ argv[optind]); ++ cmd = cli_commands; ++ while (cmd->cmdstr) { ++ if (strncasecmp(cmd->cmdstr, argv[optind], ++ strlen(argv[optind])) == 0) ++ printf(" %s", cmd->cmdstr); ++ cmd++; ++ } ++ printf("\n"); ++ ret = -1; ++ } else { ++ if (!match) { ++ cmd = cli_commands; ++ while (cmd->cmdcode != command.cmd) ++ cmd++; ++ match = cmd; ++ } ++ numargs = argc-optind - count; ++ if (numargs) ++ argptr = &argv[argc-numargs]; ++ ret = match->handler(clif, numargs, argptr, &command, newraw); ++ } ++ return ret; ++} ++ ++static void cli_recv_pending(struct clif *clif, int in_read) ++{ ++ int first = 1; ++ ++ if (clif == NULL) ++ return; ++ while (clif_pending(clif)) { ++ char buf[256]; ++ size_t len = sizeof(buf) - 1; ++ if (clif_recv(clif, buf, &len) == 0) { ++ buf[len] = '\0'; ++ if (in_read && first) ++ printf("\n"); ++ first = 0; ++ cli_msg_cb(buf, len); ++ } else { ++ printf("Could not read pending message.\n"); ++ break; ++ } ++ } ++} ++ ++static char *do_readline(const char *prompt) ++{ ++ size_t size = 0; ++ ssize_t rc; ++ char *line = NULL; ++ ++ fputs(prompt, stdout); ++ fflush(stdout); ++ ++ rc = getline(&line, &size, stdin); ++ if (rc <= 0) ++ return NULL; ++ if (line[rc - 1] == '\n') ++ line[rc - 1] = 0; ++ return line; ++} ++ ++static void cli_interactive(void) ++{ ++ const int max_args = 20; ++ char *cmd, *argv[max_args], *pos; ++ int argc; ++ ++ setlinebuf(stdout); ++ printf("\nInteractive mode\n\n"); ++ do { ++ cli_recv_pending(clif_conn, 0); ++ alarm(1); ++ cmd = do_readline("> "); ++ alarm(0); ++ if (!cmd) ++ break; ++ argc = 1; ++ pos = cmd; ++ for (;;) { ++ while (*pos == ' ') ++ pos++; ++ if (*pos == '\0') ++ break; ++ argv[argc] = pos; ++ argc++; ++ if (argc == max_args) ++ break; ++ while (*pos != '\0' && *pos != ' ') ++ pos++; ++ if (*pos == ' ') ++ *pos++ = '\0'; ++ } ++ if (argc) { ++ optind = 0; ++ request(clif_conn, argc, argv); ++ } ++ free(cmd); ++ } while (!cli_quit); ++} ++ ++static void cli_terminate(UNUSED int sig) ++{ ++ cli_close_connection(); ++ exit(0); ++} ++ ++static void cli_alarm(UNUSED int sig) ++{ ++ if (clif_conn && _clif_command(clif_conn, "P", SHOW_NO_OUTPUT)) { ++ printf("Connection to lldpad lost - trying to reconnect\n"); ++ cli_close_connection(); ++ } ++ if (!clif_conn) { ++ clif_conn = clif_open(); ++ if (clif_conn) { ++ char attach_str[9] = ""; ++ u32 mod_id = LLDP_MOD_VDP22; ++ bin2hexstr((u8 *)&mod_id, 4, attach_str, 8); ++ printf("Connection to lldpad re-established\n"); ++ if (clif_attach(clif_conn, attach_str) == 0) ++ cli_attached = 1; ++ else ++ printf("Warning: Failed to attach to lldpad.\n"); ++ } ++ } ++ if (clif_conn) ++ cli_recv_pending(clif_conn, 1); ++ alarm(1); ++} ++ ++ ++int main(int argc, char *argv[]) ++{ ++ int interactive = 1; ++ int warning_displayed = 0; ++ int ret = 0; ++ ++ if (argc > 1) ++ interactive = 0; ++ if (interactive) ++ printf("%s\n\n%s\n\n", cli_version, cli_license); ++ for (;;) { ++ clif_conn = clif_open(); ++ if (clif_conn) { ++ if (warning_displayed) ++ printf("Connection established.\n"); ++ break; ++ } ++ ++ if (!interactive) { ++ perror("Failed to connect to lldpad - clif_open"); ++ return -1; ++ } ++ ++ if (!warning_displayed) { ++ printf("Could not connect to lldpad - re-trying\n"); ++ warning_displayed = 1; ++ } ++ sleep(1); ++ } ++ ++ init_modules(); ++ signal(SIGINT, cli_terminate); ++ signal(SIGTERM, cli_terminate); ++ signal(SIGALRM, cli_alarm); ++ ++ if (interactive) { ++ char attach_str[9] = ""; ++ u32 mod_id = LLDP_MOD_VDP22; ++ bin2hexstr((u8 *)&mod_id, 4, attach_str, 8); ++ if (clif_attach(clif_conn, attach_str) == 0) ++ cli_attached = 1; ++ else ++ printf("Warning: Failed to attach to lldpad.\n"); ++ cli_interactive(); ++ } else { ++ ret = request(clif_conn, argc, &argv[0]); ++ ret = !!ret; ++ } ++ cli_close_connection(); ++ deinit_modules(); ++ return ret; ++} +-- +2.1.0 + diff --git a/SOURCES/open-lldp-v1.0.1-20-lldp-automake-fix-drop-prefix-on-vdptool_LDADD.patch b/SOURCES/open-lldp-v1.0.1-20-lldp-automake-fix-drop-prefix-on-vdptool_LDADD.patch new file mode 100644 index 0000000..eb1ff0f --- /dev/null +++ b/SOURCES/open-lldp-v1.0.1-20-lldp-automake-fix-drop-prefix-on-vdptool_LDADD.patch @@ -0,0 +1,34 @@ +From 7a7150e3e6443e2fff0f3967995fa16a4b8665d7 Mon Sep 17 00:00:00 2001 +From: John Fastabend +Date: Fri, 30 Jan 2015 08:55:00 -0800 +Subject: [PATCH] lldp: automake fix, drop prefix on vdptool_LDADD + +Add another fix to the Makefile to drop prefix in vdptool_LDADD +this resolves the following error from 'make distcheck' + +libtool: link: cannot find the library `../liblldp_clif.la' or unhandled argument `../liblldp_clif.la' +make[1]: *** [vdptool] Error 1 +make[1]: Leaving directory `/home/john/git/lldp/lldpad/lldpad-1.0.1/_build' +make: *** [distcheck] Error 1 + +Signed-off-by: John Fastabend +--- + Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/Makefile.am b/Makefile.am +index b1c381b..84d68ee 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -82,7 +82,7 @@ liblldp_clif_includedir = ${srcdir}/include + liblldp_clif_la_SOURCES = clif.c + + vdptool_SOURCES = vdptool.c lldp_util.c qbg/vdp22_clif.c vdptool_cisco_oui.c +-vdptool_LDADD = ${srcdir}/liblldp_clif.la ++vdptool_LDADD = liblldp_clif.la + vdptool_LDFLAGS = -llldp_clif $(LIBNL_LIBS) + + dcbtool_SOURCES = dcbtool.c dcbtool_cmds.c parse_cli.l \ +-- +2.1.0 + diff --git a/SOURCES/open-lldp-v1.0.1-21-lldpad-Fix-DCBX-event-generation-from-lldpad.patch b/SOURCES/open-lldp-v1.0.1-21-lldpad-Fix-DCBX-event-generation-from-lldpad.patch new file mode 100644 index 0000000..735cc3d --- /dev/null +++ b/SOURCES/open-lldp-v1.0.1-21-lldpad-Fix-DCBX-event-generation-from-lldpad.patch @@ -0,0 +1,141 @@ +From 9ad33e441e018352a95621f2cecfb31234bd6b00 Mon Sep 17 00:00:00 2001 +From: Neerav Parikh +Date: Fri, 20 Mar 2015 05:38:09 +0000 +Subject: [PATCH] lldpad: Fix DCBX event generation from lldpad + +Whenever there is a change in LLDP TLVs lldpad notifies clients that +may have registered for event notification based on TLV type. +For legacy clients like "fcoemon" lldpad by default registers them +for any changes to CEE DCBX TLV type; when such clients attach to +lldpad clif interface. + +Now, the lldpad code that registers such clients for CEE DCBX TLV +types is not generating correct DCBX TLV module id when it registers +these clients for change event notification. Hence, whenever there +is a change in such TLVs lldpad determines that the client is not +registered for CEE DCBX TLV change notification and does not notify +these clients. + +These results in clients not taking appropriate actions based on +changes to CEE DCBX TLVs. + +The patch fixes the issue by setting the correct module id value for +the CEE DCBX for legacy clients like "fcoemon". + +Tested-by: Jack Morgan +Signed-off-by: Neerav Parikh +Signed-off-by: John Fastabend +--- + ctrl_iface.c | 68 +++++++++++++++++++++++++++++++----------------------------- + lldpad.c | 2 ++ + 2 files changed, 37 insertions(+), 33 deletions(-) + +diff --git a/ctrl_iface.c b/ctrl_iface.c +index e4fd0b7..1734f49 100644 +--- a/ctrl_iface.c ++++ b/ctrl_iface.c +@@ -173,46 +173,44 @@ int clif_iface_attach(struct clif_data *clifd, + */ + /* set default string to DCBX Events */ + if (ibuf[1] == '\0') { +- u32 hex = LLDP_MOD_DCBX; +- tlv = malloc(sizeof(char) * (8 + 2)); +- if (!tlv) ++ dst->tlv_types = malloc(sizeof(u32) * 2); ++ if (!dst->tlv_types) + goto err_tlv; +- tlv[0] = 'A'; +- tlv[9] = 0; +- bin2hexstr((u8*)&hex, 4, &tlv[1], 8); +- } else ++ dst->tlv_types[0] = LLDP_MOD_DCBX; ++ /* Insert Termination Pattern */ ++ dst->tlv_types[1] = ~0; ++ } else { + tlv = strdup(ibuf); +- +- str = tlv; +- str++; +- /* Count number of TLV Modules */ +- tokenize = strtok(str, delim); +- tlv_count++; +- do { +- tokenize = strtok(NULL, delim); ++ str = tlv; ++ str++; ++ /* Count number of TLV Modules */ ++ tokenize = strtok(str, delim); + tlv_count++; +- } while (tokenize); ++ do { ++ tokenize = strtok(NULL, delim); ++ tlv_count++; ++ } while (tokenize); + +- dst->tlv_types = malloc(sizeof(u32) * tlv_count); +- if (!dst->tlv_types) +- goto err_types; +- memset(dst->tlv_types, 0, sizeof(u32) * tlv_count); +- +- /* Populate tlv_types from comma separated string */ +- tokenize = strtok(str, delim); +- for (i=0; tokenize; i++) { +- char *myend; +- +- dst->tlv_types[i] = strtol(tokenize, &myend, 16); +- if (*myend) /* No hexnumber for module id */ ++ dst->tlv_types = malloc(sizeof(u32) * tlv_count); ++ if (!dst->tlv_types) + goto err_types; +- tokenize = strtok(NULL, delim); ++ memset(dst->tlv_types, 0, sizeof(u32) * tlv_count); ++ ++ /* Populate tlv_types from comma separated string */ ++ tokenize = strtok(str, delim); ++ for (i = 0; tokenize; i++) { ++ char *myend; ++ ++ dst->tlv_types[i] = strtol(tokenize, &myend, 16); ++ if (*myend) /* No hexnumber for module id */ ++ goto err_types; ++ tokenize = strtok(NULL, delim); ++ } ++ free(tlv); ++ /* Insert Termination Pattern */ ++ dst->tlv_types[i] = ~0; + } + +- /* Insert Termination Pattern */ +- dst->tlv_types[i] = ~0; +- free(tlv); +- + /* Insert new node at beginning */ + dst->next = clifd->ctrl_dst; + clifd->ctrl_dst = dst; +@@ -595,6 +593,10 @@ void ctrl_iface_send(struct clif_data *clifd, int level, u32 moduleid, + dst->addrlen); + } + } else { ++ fprintf(stderr, ++ "CTRL_IFACE monitor[%d][%d] %d:%s: ", ++ idx, clifd->ctrl_sock, dst->addrlen, ++ dst->addr.sun_path); + dst->errors = 0; + } + } +diff --git a/lldpad.c b/lldpad.c +index 406dcd5..72ab69d 100644 +--- a/lldpad.c ++++ b/lldpad.c +@@ -150,6 +150,8 @@ void send_event(int level, u32 moduleid, char *msg) + { + struct clif_data *cd = NULL; + ++ LLDPAD_DBG("lldpad: send_event level=%d moduleid=%d msg=%s\n", ++ level, moduleid, msg); + cd = (struct clif_data *) eloop_get_user_data(); + if (cd) + ctrl_iface_send(cd, level, moduleid, msg, strlen(msg)); +-- +2.1.0 + diff --git a/SOURCES/open-lldp-v1.0.1-22-vdp-Fixed-the-memory-leak-for-modify-VSI-support-for.patch b/SOURCES/open-lldp-v1.0.1-22-vdp-Fixed-the-memory-leak-for-modify-VSI-support-for.patch new file mode 100644 index 0000000..3285467 --- /dev/null +++ b/SOURCES/open-lldp-v1.0.1-22-vdp-Fixed-the-memory-leak-for-modify-VSI-support-for.patch @@ -0,0 +1,223 @@ +From 73e0c42cc00f537fee1f58e5475cab1f2193e3cc Mon Sep 17 00:00:00 2001 +From: padkrish +Date: Fri, 10 Apr 2015 09:03:24 +0000 +Subject: [PATCH] vdp: Fixed the memory leak for modify VSI, support for OUI + modify + +This patch has a fix for freeing the memory after a VSI update. +Support for modifying the OUI parameters have been added +to the infra. +Cisco specific handler is also added to support OUI modify. + +Signed-off-by: padkrish +Signed-off-by: John Fastabend +--- + include/qbg_vdp22.h | 2 +- + include/qbg_vdp22_oui.h | 3 +++ + include/vdp_cisco.h | 2 ++ + qbg/vdp22.c | 5 +++-- + qbg/vdp22cisco_oui.c | 44 +++++++++++++++++++++++++++++++++++++++++--- + qbg/vdp22sm.c | 35 ++++++++++++++++++++++++++++++++--- + 6 files changed, 82 insertions(+), 9 deletions(-) + +diff --git a/include/qbg_vdp22.h b/include/qbg_vdp22.h +index 6585a10..b1896a5 100644 +--- a/include/qbg_vdp22.h ++++ b/include/qbg_vdp22.h +@@ -181,7 +181,7 @@ void vdp22_stop(char *); + int vdp22_from_ecp22(struct vdp22 *); + int vdp22_query(const char *); + struct vdp22 *vdp22_getvdp(const char *); +-int vdp22_addreq(struct vsi22 *, struct vdp22 *); ++int vdp22_addreq(struct vsi22 *, struct vdp22 *, bool *); + int vdp22_nlback(struct vsi22 *); + int vdp22_clntback(struct vsi22 *); + struct vsi22 *vdp22_copy_vsi(struct vsi22 *); +diff --git a/include/qbg_vdp22_oui.h b/include/qbg_vdp22_oui.h +index 923e19f..d60075d 100644 +--- a/include/qbg_vdp22_oui.h ++++ b/include/qbg_vdp22_oui.h +@@ -82,6 +82,9 @@ 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 modifies the existing OUI parameters */ ++ bool (*vsi22_mod_hndlr)(void *, struct vdp22_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); +diff --git a/include/vdp_cisco.h b/include/vdp_cisco.h +index 821db68..4abe802 100644 +--- a/include/vdp_cisco.h ++++ b/include/vdp_cisco.h +@@ -113,6 +113,8 @@ 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_vsi22_mod_hndlr(void *, struct vdp22_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 *); +diff --git a/qbg/vdp22.c b/qbg/vdp22.c +index 10b80a4..8f14fdd 100644 +--- a/qbg/vdp22.c ++++ b/qbg/vdp22.c +@@ -900,6 +900,7 @@ int vdp22_request(struct vdpnl_vsi *vsi, int clif) + int rc; + struct vsi22 *p; + struct vdp22 *vdp; ++ bool modf_vsi = false; + + LLDPAD_DBG("%s:%s clif:%d\n", __func__, vsi->ifname, clif); + vdp = vdp22_findif(vsi->ifname, NULL); +@@ -917,8 +918,8 @@ int vdp22_request(struct vdpnl_vsi *vsi, int clif) + vsi->request += 1; + p = vdp22_alloc_vsi_int(vsi, vdp, &rc, true); + if (p) { +- rc = vdp22_addreq(p, vdp); +- if (rc) ++ rc = vdp22_addreq(p, vdp, &modf_vsi); ++ if (rc || modf_vsi) + vdp22_delete_vsi(p); + } + } else +diff --git a/qbg/vdp22cisco_oui.c b/qbg/vdp22cisco_oui.c +index 272d480..da6ce24 100644 +--- a/qbg/vdp22cisco_oui.c ++++ b/qbg/vdp22cisco_oui.c +@@ -34,8 +34,9 @@ + + struct vdp22_oui_handler_s cisco_oui_hndlr = { + {0x00, 0x00, 0x0c}, "cisco", cisco_str2vdpnl_hndlr, +- cisco_vdpnl2vsi22_hndlr, cisco_vdpnl2str_hndlr, +- cisco_vsi2vdpnl_hndlr, cisco_vdp_tx_hndlr, cisco_vdp_rx_hndlr, ++ cisco_vdpnl2vsi22_hndlr, cisco_vsi22_mod_hndlr, ++ cisco_vdpnl2str_hndlr, cisco_vsi2vdpnl_hndlr, ++ cisco_vdp_tx_hndlr, cisco_vdp_rx_hndlr, + cisco_vdp_free_oui, cisco_vdp_oui_ptlvsize}; + + /* +@@ -104,9 +105,11 @@ bool cisco_str2vdpnl_hndlr(struct vdpnl_oui_data_s *vdp_oui_p, char *token) + } + strncpy(uuid, token, data_len); + if (oui_vdp_str2uuid(vdp_cisco_oui_p->uuid, uuid, +- sizeof(vdp_cisco_oui_p->uuid))) ++ 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 = false; ++ } else + vdp_cisco_oui_p->uuid_set = true; + free(uuid); + break; +@@ -177,6 +180,41 @@ bool cisco_vdpnl2vsi22_hndlr(void *vsi_data, struct vdpnl_oui_data_s *from, + } + + /* ++ * This converts modifies the existing OUI parameters ++ */ ++ ++bool cisco_vsi22_mod_hndlr(UNUSED void *vsi_data, struct vdp22_oui_data_s *from, ++ struct vdp22_oui_data_s *to) ++{ ++ vdp_cisco_oui_t *from_oui; ++ vdp_cisco_oui_t *to_oui; ++ ++ from_oui = (vdp_cisco_oui_t *)from->data; ++ to_oui = (vdp_cisco_oui_t *)to->data; ++ if ((!from_oui) || (!to_oui)) { ++ LLDPAD_DBG("%s: NULL OUI data\n", __func__); ++ return false; ++ } ++ if (from_oui->vm_name_len != 0) { ++ to_oui->vm_name_len = from_oui->vm_name_len; ++ strncpy(to_oui->vm_name, from_oui->vm_name, ++ to_oui->vm_name_len); ++ } ++ /* UUID can be modified only if not set */ ++ if (!to_oui->uuid_set) { ++ memcpy(to_oui->uuid, from_oui->uuid, sizeof(to_oui->uuid)); ++ to_oui->uuid_set = true; ++ } ++ if (from_oui->vm_addr_len != 0) { ++ to_oui->vm_addr_len = from_oui->vm_addr_len; ++ to_oui->afi = from_oui->afi; ++ memcpy(&(to_oui->l3_addr), &(from_oui->l3_addr), ++ sizeof(to_oui->l3_addr)); ++ } ++ return true; ++} ++ ++/* + * This function converts the OUI information from vdpnl struct to string + */ + +diff --git a/qbg/vdp22sm.c b/qbg/vdp22sm.c +index 14356ac..be838a9 100644 +--- a/qbg/vdp22sm.c ++++ b/qbg/vdp22sm.c +@@ -184,10 +184,36 @@ static inline size_t vsi22_ptlv_sz(struct vsi22 *vp) + } + + /* ++ * This function modifies the existing OUI parameters in a VSI. ++ */ ++static void vdp22_modoui(struct vsi22 *p, struct vsi22 *vsip) ++{ ++ struct vdp22_oui_handler_s *oui_hndlr; ++ int idx, inn_idx, ret; ++ ++ for (idx = 0; idx < vsip->no_ouidata; idx++) { ++ struct vdp22_oui_data_s *from = &vsip->oui_str_data[idx]; ++ ++ for (inn_idx = 0; inn_idx < p->no_ouidata; inn_idx++) { ++ struct vdp22_oui_data_s *to = &p->oui_str_data[inn_idx]; ++ ++ if (!strncmp(to->oui_name, from->oui_name, ++ sizeof(to->oui_name))) { ++ oui_hndlr = vdp22_get_oui_hndlr(to->oui_name); ++ ret = oui_hndlr->vsi22_mod_hndlr(p, from, to); ++ if (!ret) ++ LLDPAD_ERR("%s: handler return error for oui %s\n", ++ __func__, from->oui_name); ++ return; ++ } ++ } ++ } ++} ++ ++/* + * This function calls the registered OUI handlers that returns the size of + * the OUI data. + */ +- + static inline size_t oui22_ptlv_sz(struct vsi22 *vp) + { + struct vdp22_oui_handler_s *oui_hndlr; +@@ -1054,7 +1080,7 @@ bool vdp22_cmp_fdata(struct vsi22 *p, struct vsi22 *vsip) + /* + * Handle a new request. + */ +-int vdp22_addreq(struct vsi22 *vsip, struct vdp22 *vdp) ++int vdp22_addreq(struct vsi22 *vsip, struct vdp22 *vdp, bool *modf_vsi) + { + int rc = 0; + struct vsi22 *p; +@@ -1094,8 +1120,11 @@ int vdp22_addreq(struct vsi22 *vsip, struct vdp22 *vdp) + LLDPAD_DBG("%s:%s TODO mismatch filter data [%02x]\n", + __func__, vsip->vdp->ifname, vsip->vsi[0]); + rc = -EINVAL; +- } else ++ } else { ++ vdp22_modoui(p, vsip); + rc = vdp22_modvsi(p, vsip->vsi_mode); ++ *modf_vsi = true; ++ } + } + out: + LLDPAD_DBG("%s:%s rc:%d\n", __func__, vsip->vdp->ifname, rc); +-- +2.1.0 + diff --git a/SOURCES/open-lldp-v1.0.1-23-lldp-make-TTL-TLV-configurable.patch b/SOURCES/open-lldp-v1.0.1-23-lldp-make-TTL-TLV-configurable.patch new file mode 100644 index 0000000..51cbc9b --- /dev/null +++ b/SOURCES/open-lldp-v1.0.1-23-lldp-make-TTL-TLV-configurable.patch @@ -0,0 +1,312 @@ +From 986eb2e84fd3339a30a4ab09c6d788c63236fed6 Mon Sep 17 00:00:00 2001 +From: Gary Loughnane +Date: Tue, 21 Apr 2015 17:45:41 +0000 +Subject: [PATCH] lldp: make TTL TLV configurable + +This allows the TTL TLV to be configured. + +Currently the Time To Live TLV is a static value set to 120 seconds. +LLDP specification says this can be a value of between 0 and 65535 +seconds. This patch makes the TTL TLV a configurable entity. + +Signed-off-by: Gary Loughnane +Signed-off-by: John Fastabend +--- + include/lldp_mand.h | 1 + + include/lldp_mand_cmds.h | 4 +++ + lldp/agent.c | 2 +- + lldp/ports.c | 3 +- + lldp/states.h | 2 +- + lldp/tx.c | 30 ++++++++++++++-- + lldp_mand.c | 21 ++++++++--- + lldp_mand_cmds.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++ + 8 files changed, 141 insertions(+), 12 deletions(-) + +diff --git a/include/lldp_mand.h b/include/lldp_mand.h +index 9154b7c..fc21ede 100644 +--- a/include/lldp_mand.h ++++ b/include/lldp_mand.h +@@ -93,4 +93,5 @@ void mand_unregister(struct lldp_module *mod); + struct packed_tlv *mand_gettlv(struct port *, struct lldp_agent *); + void mand_ifdown(char *, struct lldp_agent *); + void mand_ifup(char *, struct lldp_agent *); ++void mand_update_ttl(const char *, u16); + #endif /* _LLDP_MAND_H */ +diff --git a/include/lldp_mand_cmds.h b/include/lldp_mand_cmds.h +index aacac7c..8effc6e 100644 +--- a/include/lldp_mand_cmds.h ++++ b/include/lldp_mand_cmds.h +@@ -28,6 +28,10 @@ + #define _LLDP_MAND_CMDS_H + + #define ARG_MAND_SUBTYPE "subtype" ++#define ARG_TTL_VALUE "value" ++ ++#define TTL_MIN_VAL 0x0 ++#define TTL_MAX_VAL 0xFFFF + + struct arg_handlers *mand_get_arg_handlers(); + +diff --git a/lldp/agent.c b/lldp/agent.c +index 4bc5394..73ab054 100644 +--- a/lldp/agent.c ++++ b/lldp/agent.c +@@ -101,7 +101,7 @@ void lldp_init_agent(struct port *port, struct lldp_agent *agent, int type) + + /* init TX path */ + txInitializeTimers(agent); +- txInitializeLLDP(agent); ++ txInitializeLLDP(port, agent); + } + + int lldp_add_agent(const char *ifname, enum agent_type type) +diff --git a/lldp/ports.c b/lldp/ports.c +index 3bd6a2a..6384f14 100644 +--- a/lldp/ports.c ++++ b/lldp/ports.c +@@ -230,7 +230,6 @@ int reinit_port(const char *ifname) + /* Reset relevant state variables */ + agent->tx.state = TX_LLDP_INITIALIZE; + agent->rx.state = LLDP_WAIT_PORT_OPERATIONAL; +- agent->tx.txTTL = 0; + agent->msap.length1 = 0; + agent->msap.msap1 = NULL; + agent->msap.length2 = 0; +@@ -243,7 +242,7 @@ int reinit_port(const char *ifname) + + /* init TX path */ + txInitializeTimers(agent); +- txInitializeLLDP(agent); ++ txInitializeLLDP(port, agent); + } + + return 0; +diff --git a/lldp/states.h b/lldp/states.h +index fa5f11f..7cf69b8 100644 +--- a/lldp/states.h ++++ b/lldp/states.h +@@ -52,7 +52,7 @@ enum { + * The txInitializeLLDP () procedure initializes the LLDP transmit module as + * defined in 10.1.1. + */ +-void txInitializeLLDP(struct lldp_agent *agent); ++void txInitializeLLDP(struct port *port, struct lldp_agent *agent); + + /** + * The mibConstrInfoLLDPDU () procedure constructs an information LLDPDU as +diff --git a/lldp/tx.c b/lldp/tx.c +index 69c1a1a..c3a5c62 100644 +--- a/lldp/tx.c ++++ b/lldp/tx.c +@@ -34,6 +34,8 @@ + #include "lldp_tlv.h" + #include "lldp_mod.h" + #include "lldp_mand.h" ++#include "config.h" ++#include "lldp_mand_clif.h" + + bool mibConstrInfoLLDPDU(struct port *port, struct lldp_agent *agent) + { +@@ -110,7 +112,29 @@ error: + return false; + } + +-void txInitializeLLDP(struct lldp_agent *agent) ++static u16 get_ttl_init_val(char *ifname, struct lldp_agent *agent) ++{ ++ u16 ttl; ++ int config_ttl; ++ int read_config_err; ++ char arg_path[512] = { 0 }; ++ ++ snprintf(arg_path, sizeof(arg_path), "%s%08x.%s", ++ TLVID_PREFIX, ++ TLVID_NOUI(TIME_TO_LIVE_TLV), ++ ARG_TTL_VALUE); ++ read_config_err = get_config_setting(ifname, agent->type, ++ arg_path, &config_ttl, CONFIG_TYPE_INT); ++ ++ if (read_config_err) ++ ttl = DEFAULT_TX_HOLD * DEFAULT_TX_INTERVAL; ++ else ++ ttl = (u16)(config_ttl); ++ ++ return ttl; ++} ++ ++void txInitializeLLDP(struct port *port, struct lldp_agent *agent) + { + if (agent->tx.frameout) { + free(agent->tx.frameout); +@@ -125,7 +149,7 @@ void txInitializeLLDP(struct lldp_agent *agent) + agent->timers.msgTxInterval = DEFAULT_TX_INTERVAL; + agent->timers.msgFastTx = FAST_TX_INTERVAL; + +- agent->tx.txTTL = 0; ++ agent->tx.txTTL = get_ttl_init_val(port->ifname, agent); + agent->msap.length1 = 0; + agent->msap.msap1 = NULL; + agent->msap.length2 = 0; +@@ -240,7 +264,7 @@ void run_tx_sm(struct port *port, struct lldp_agent *agent) + do { + switch(agent->tx.state) { + case TX_LLDP_INITIALIZE: +- txInitializeLLDP(agent); ++ txInitializeLLDP(port, agent); + break; + case TX_IDLE: + process_tx_idle(agent); +diff --git a/lldp_mand.c b/lldp_mand.c +index b269d3f..652a454 100644 +--- a/lldp_mand.c ++++ b/lldp_mand.c +@@ -446,11 +446,7 @@ static int mand_bld_ttl_tlv(struct mand_data *md, struct lldp_agent *agent) + } + memset(tlv->info, 0, tlv->length); + +- if (agent->tx.txTTL) +- ttl = htons(agent->tx.txTTL); +- else +- ttl = htons(DEFAULT_TX_HOLD * DEFAULT_TX_INTERVAL); +- ++ ttl = htons(agent->tx.txTTL); + memcpy(tlv->info, &ttl, tlv->length); + LLDPAD_DBG("%s:%s:done:type=%d length=%d ttl=%d\n", __func__, + md->ifname, tlv->type, tlv->length, ntohs(ttl)); +@@ -685,3 +681,18 @@ void mand_unregister(struct lldp_module *mod) + free(mod); + LLDPAD_INFO("%s:done\n", __func__); + } ++ ++void mand_update_ttl(const char *ifname, u16 ttl_val) ++{ ++ struct port *port = port_find_by_ifindex(get_ifidx(ifname)); ++ struct lldp_agent *agent; ++ ++ if (!port) ++ return; ++ ++ LIST_FOREACH(agent, &port->agent_head, entry) { ++ agent->tx.txTTL = ttl_val; ++ agent->tx.localChange = 1; ++ agent->tx.txFast = agent->timers.txFastInit; ++ } ++} +diff --git a/lldp_mand_cmds.c b/lldp_mand_cmds.c +index 532337b..7d24bf8 100644 +--- a/lldp_mand_cmds.c ++++ b/lldp_mand_cmds.c +@@ -58,6 +58,11 @@ static int get_mand_subtype(struct cmd *, char *, char *, char *, int); + static int set_mand_subtype(struct cmd *, char *, char *, char *, int); + static int test_mand_subtype(struct cmd *, char *, char *, char *, int); + ++ ++static int get_mand_ttl_value(struct cmd *, char *, char *, char *, int); ++static int set_mand_ttl_value(struct cmd *, char *, char *, char *, int); ++static int test_mand_ttl_value(struct cmd *, char *, char *, char *, int); ++ + static struct arg_handlers arg_handlers[] = { + { .arg = ARG_ADMINSTATUS, .arg_class = LLDP_ARG, + .handle_get = get_arg_adminstatus, +@@ -72,6 +77,11 @@ static struct arg_handlers arg_handlers[] = { + .handle_get = get_mand_subtype, + .handle_set = set_mand_subtype, + .handle_test = test_mand_subtype, }, ++ { .arg = ARG_TTL_VALUE, ++ .arg_class = TLV_ARG, ++ .handle_get = get_mand_ttl_value, ++ .handle_set = set_mand_ttl_value, ++ .handle_test = test_mand_ttl_value, }, + { .arg = 0 } + }; + +@@ -271,6 +281,86 @@ static int _set_mand_subtype(struct cmd *cmd, char *arg, char *argvalue, + return 0; + } + ++static int get_mand_ttl_value(struct cmd *cmd, char *arg, ++ UNUSED char *argvalue, char *obuf, int obuf_len) ++{ ++ int ttl_val; ++ char string[8], arg_path[256]; ++ ++ if (cmd->cmd != cmd_gettlv) ++ return cmd_invalid; ++ ++ switch (cmd->tlvid) { ++ case TIME_TO_LIVE_TLV: ++ snprintf(arg_path, sizeof(arg_path), "%s%08x.%s", ++ TLVID_PREFIX, TLVID_NOUI(TIME_TO_LIVE_TLV), ++ ARG_TTL_VALUE); ++ get_config_setting(cmd->ifname, cmd->type, arg_path, ++ &ttl_val, CONFIG_TYPE_INT); ++ break; ++ case INVALID_TLVID: ++ return cmd_invalid; ++ default: ++ return cmd_not_applicable; ++ } ++ ++ snprintf(string, sizeof(string), "%d", ttl_val); ++ snprintf(obuf, obuf_len, "%02x%s%04x%s", ++ (unsigned int) strlen(arg), arg, ++ (unsigned int)strlen(string), string); ++ ++ return 0; ++} ++ ++static int _set_mand_ttl_value(struct cmd *cmd, char *arg, char *argvalue, ++ char *obuf, int obuf_len, bool test) ++{ ++ int ttl_val; ++ char *end; ++ char arg_path[256]; ++ ++ if (cmd->cmd != cmd_settlv) ++ return cmd_invalid; ++ ++ switch (cmd->tlvid) { ++ case TIME_TO_LIVE_TLV: ++ break; ++ case INVALID_TLVID: ++ return cmd_invalid; ++ default: ++ return cmd_not_applicable; ++ } ++ ++ ttl_val = strtoul(argvalue, &end, 0); ++ if ((*end) || (TTL_MIN_VAL > ttl_val) || (ttl_val > TTL_MAX_VAL)) ++ return cmd_bad_params; ++ ++ if (test) ++ return cmd_success; ++ ++ snprintf(arg_path, sizeof(arg_path), "%s%08x.%s", TLVID_PREFIX, ++ cmd->tlvid, arg); ++ snprintf(obuf, obuf_len, "%s=%s\n", arg, argvalue); ++ set_config_setting(cmd->ifname, cmd->type, ++ arg_path, &ttl_val, CONFIG_TYPE_INT); ++ ++ mand_update_ttl(cmd->ifname, ttl_val); ++ ++ return 0; ++} ++ ++static int set_mand_ttl_value(struct cmd *cmd, char *arg, char *argvalue, ++ char *obuf, int obuf_len) ++{ ++ return _set_mand_ttl_value(cmd, arg, argvalue, obuf, obuf_len, false); ++} ++ ++static int test_mand_ttl_value(struct cmd *cmd, char *arg, char *argvalue, ++ char *obuf, int obuf_len) ++{ ++ return _set_mand_ttl_value(cmd, arg, argvalue, obuf, obuf_len, true); ++} ++ + static int set_mand_subtype(struct cmd *cmd, char *arg, char *argvalue, + char *obuf, int obuf_len) + { +-- +2.1.0 + diff --git a/SOURCES/open-lldp-v1.0.1-24-switch-from-sysv-to-posix-shared-memory-apis.patch b/SOURCES/open-lldp-v1.0.1-24-switch-from-sysv-to-posix-shared-memory-apis.patch new file mode 100644 index 0000000..3c96a91 --- /dev/null +++ b/SOURCES/open-lldp-v1.0.1-24-switch-from-sysv-to-posix-shared-memory-apis.patch @@ -0,0 +1,423 @@ +From 3124c4b4537083618b82f230b05997c70096c897 Mon Sep 17 00:00:00 2001 +From: Chris Leech +Date: Mon, 20 Jul 2015 17:32:02 -0700 +Subject: [PATCH] switch from sysv to posix shared memory apis + +The use of SysV shared memory, to pass state between running instances of +lldpad in the initramfs and then from the root fs, is difficult to work +with from a security policy. When lldpad runs in the initramfs there is +no security policy loaded. Then when it's restarted after an SELinux +policy has been loaded, there is no way to correct the context on the +already existing shared memory segment. This would result in the need +for an overly permissive policy for lldpad. + +By switching to POSIX APIs the segment is mapped from a tmpfs file with +a directory entry under /dev/shm/. This lets us add a file contents +entry to the SELinux policy that matches that path, and a proper +security context can be restored to it before restarting lldpad. + +- Chris +--- + Makefile.am | 2 +- + include/lldpad_shm.h | 2 +- + lldpad_shm.c | 169 ++++++++++++++++++++++++++++++--------------------- + 3 files changed, 103 insertions(+), 70 deletions(-) + +diff --git a/Makefile.am b/Makefile.am +index 84d68ee..551d4c7 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -17,7 +17,7 @@ parse_cli.o: CFLAGS+=-U_FORTIFY_SOURCE -Wno-error + + ## system requires a shared libconfig + AM_CFLAGS = -Wall -Werror -Wextra -Wformat=2 $(LIBCONFIG_CFLAGS) $(LIBNL_CFLAGS) +-AM_LDFLAGS = $(LIBCONFIG_LIBS) $(LIBNL_LIBS) ++AM_LDFLAGS = $(LIBCONFIG_LIBS) $(LIBNL_LIBS) -lrt + + ## header files to be installed, for programs using the client interface to lldpad + lldpad_includedir= ${includedir}/lldpad +diff --git a/include/lldpad_shm.h b/include/lldpad_shm.h +index 00d20eb..587b555 100644 +--- a/include/lldpad_shm.h ++++ b/include/lldpad_shm.h +@@ -31,7 +31,7 @@ + #include "lldpad.h" + #include "lldp_rtnl.h" + +-#define LLDPAD_SHM_KEY ((('l'<<24) | ('l'<<16) | ('d'<<8) | ('p')) + 'a' + 'd' + 1) ++#define LLDPAD_SHM_PATH "/lldpad.state" + #define LLDPAD_SHM_SIZE 4096 + + /* PID value used to indicate pid field is uninitialized */ +diff --git a/lldpad_shm.c b/lldpad_shm.c +index 4afcf73..d8bc0c5 100644 +--- a/lldpad_shm.c ++++ b/lldpad_shm.c +@@ -29,7 +29,9 @@ + #include + #include + #include +-#include ++#include ++#include ++#include + #include + #include + #include +@@ -39,16 +41,7 @@ + + void mark_lldpad_shm_for_removal() + { +- int shmid; +- struct shmid_ds shminfo; +- +- shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE, 0); +- +- if (shmid < 0) +- return; +- +- if (shmctl(shmid, IPC_RMID, &shminfo) < 0) +- return; ++ shm_unlink(LLDPAD_SHM_PATH); + } + + /* return: 1 = success, 0 = failed */ +@@ -101,16 +94,21 @@ int lldpad_shm_get_msap(const char *device_name, int type, char *info, size_t *l + unsigned num_entries; + int version; + +- shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE, 0); +- if (shmid < 0 && errno == ENOENT) +- shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE, +- IPC_CREAT | IPC_EXCL | 0x180); ++ shmid = shm_open(LLDPAD_SHM_PATH, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); + + if (shmid < 0) + return rval; + +- shmaddr = (struct lldpad_shm_tbl *)shmat(shmid, NULL, 0); +- if ((long) shmaddr == -1) ++ if (ftruncate(shmid, LLDPAD_SHM_SIZE)) { ++ close(shmid); ++ return rval; ++ } ++ ++ shmaddr = (struct lldpad_shm_tbl *) mmap(NULL, LLDPAD_SHM_SIZE, ++ PROT_READ | PROT_WRITE, ++ MAP_SHARED, shmid, 0); ++ close(shmid); ++ if (shmaddr == MAP_FAILED) + return rval; + + version = (shmaddr->num_entries & SHM_VER_MASK) >> SHM_VER_SHIFT; +@@ -147,7 +145,7 @@ int lldpad_shm_get_msap(const char *device_name, int type, char *info, size_t *l + rval = 1; + } + done: +- shmdt(shmaddr); ++ munmap(shmaddr, LLDPAD_SHM_SIZE); + + return rval; + } +@@ -162,16 +160,21 @@ int lldpad_shm_set_msap(const char *device_name, int type, char *info, size_t le + int version; + unsigned num_entries; + +- shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE, 0); +- if (shmid < 0 && errno == ENOENT) +- shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE, +- IPC_CREAT | IPC_EXCL | 0x180); ++ shmid = shm_open(LLDPAD_SHM_PATH, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); + + if (shmid < 0) + return rval; + +- shmaddr = (struct lldpad_shm_tbl *)shmat(shmid, NULL, 0); +- if ((long) shmaddr == -1) ++ if (ftruncate(shmid, LLDPAD_SHM_SIZE)) { ++ close(shmid); ++ return rval; ++ } ++ ++ shmaddr = (struct lldpad_shm_tbl *) mmap(NULL, LLDPAD_SHM_SIZE, ++ PROT_READ | PROT_WRITE, ++ MAP_SHARED, shmid, 0); ++ close(shmid); ++ if (shmaddr == MAP_FAILED) + return rval; + + version = (shmaddr->num_entries & SHM_VER_MASK) >> SHM_VER_SHIFT; +@@ -212,7 +215,7 @@ int lldpad_shm_set_msap(const char *device_name, int type, char *info, size_t le + } + + done: +- shmdt(shmaddr); ++ munmap(shmaddr, LLDPAD_SHM_SIZE); + + return rval; + } +@@ -226,16 +229,21 @@ int lldpad_shm_get_dcbx(const char *device_name) + unsigned num_entries; + int version; + +- shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE, 0); +- if (shmid < 0 && errno == ENOENT) +- shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE, +- IPC_CREAT | IPC_EXCL | 0x180); ++ shmid = shm_open(LLDPAD_SHM_PATH, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); + + if (shmid < 0) + return rval; + +- shmaddr = (struct lldpad_shm_tbl *)shmat(shmid, NULL, 0); +- if ((long) shmaddr == -1) ++ if (ftruncate(shmid, LLDPAD_SHM_SIZE)) { ++ close(shmid); ++ return rval; ++ } ++ ++ shmaddr = (struct lldpad_shm_tbl *) mmap(NULL, LLDPAD_SHM_SIZE, ++ PROT_READ | PROT_WRITE, ++ MAP_SHARED, shmid, 0); ++ close(shmid); ++ if (shmaddr == MAP_FAILED) + return rval; + + version = (shmaddr->num_entries & SHM_VER_MASK) >> SHM_VER_SHIFT; +@@ -264,7 +272,7 @@ int lldpad_shm_get_dcbx(const char *device_name) + } + + done: +- shmdt(shmaddr); ++ munmap(shmaddr, LLDPAD_SHM_SIZE); + + return rval; + } +@@ -279,16 +287,21 @@ int lldpad_shm_set_dcbx(const char *device_name, int dcbx_mode) + unsigned num_entries; + int version; + +- shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE, 0); +- if (shmid < 0 && errno == ENOENT) +- shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE, +- IPC_CREAT | IPC_EXCL | 0x180); ++ shmid = shm_open(LLDPAD_SHM_PATH, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); + + if (shmid < 0) + return rval; + +- shmaddr = (struct lldpad_shm_tbl *)shmat(shmid, NULL, 0); +- if ((long) shmaddr == -1) ++ if (ftruncate(shmid, LLDPAD_SHM_SIZE)) { ++ close(shmid); ++ return rval; ++ } ++ ++ shmaddr = (struct lldpad_shm_tbl *) mmap(NULL, LLDPAD_SHM_SIZE, ++ PROT_READ | PROT_WRITE, ++ MAP_SHARED, shmid, 0); ++ close(shmid); ++ if (shmaddr == MAP_FAILED) + return rval; + + version = (shmaddr->num_entries & SHM_VER_MASK) >> SHM_VER_SHIFT; +@@ -330,7 +343,7 @@ int lldpad_shm_set_dcbx(const char *device_name, int dcbx_mode) + } + + done: +- shmdt(shmaddr); ++ munmap(shmaddr, LLDPAD_SHM_SIZE); + + return rval; + } +@@ -346,16 +359,21 @@ pid_t lldpad_shm_getpid() + pid_t rval = -1; + int version; + +- shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE, 0); +- if (shmid < 0 && errno == ENOENT) +- shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE, +- IPC_CREAT | IPC_EXCL | 0x180); ++ shmid = shm_open(LLDPAD_SHM_PATH, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); + + if (shmid < 0) + return rval; + +- shmaddr = (struct lldpad_shm_tbl *)shmat(shmid, NULL, 0); +- if ((long) shmaddr == -1) ++ if (ftruncate(shmid, LLDPAD_SHM_SIZE)) { ++ close(shmid); ++ return rval; ++ } ++ ++ shmaddr = (struct lldpad_shm_tbl *) mmap(NULL, LLDPAD_SHM_SIZE, ++ PROT_READ | PROT_WRITE, ++ MAP_SHARED, shmid, 0); ++ close(shmid); ++ if (shmaddr == MAP_FAILED) + return rval; + + version = (shmaddr->num_entries & SHM_VER_MASK) >> SHM_VER_SHIFT; +@@ -366,7 +384,7 @@ pid_t lldpad_shm_getpid() + + rval = shmaddr->pid; + +- shmdt(shmaddr); ++ munmap(shmaddr, LLDPAD_SHM_SIZE); + + return rval; + } +@@ -379,13 +397,16 @@ int lldpad_shm_setpid(pid_t pid) + pid_t rval = 0; + int version; + +- shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE, 0); ++ shmid = shm_open(LLDPAD_SHM_PATH, O_RDWR, S_IRUSR | S_IWUSR); + + if (shmid < 0) + return rval; + +- shmaddr = (struct lldpad_shm_tbl *)shmat(shmid, NULL, 0); +- if ((long) shmaddr == -1) ++ shmaddr = (struct lldpad_shm_tbl *) mmap(NULL, LLDPAD_SHM_SIZE, ++ PROT_READ | PROT_WRITE, ++ MAP_SHARED, shmid, 0); ++ close(shmid); ++ if (shmaddr == MAP_FAILED) + return rval; + + version = (shmaddr->num_entries & SHM_VER_MASK) >> SHM_VER_SHIFT; +@@ -396,7 +417,7 @@ int lldpad_shm_setpid(pid_t pid) + + shmaddr->pid = pid; + +- shmdt(shmaddr); ++ munmap(shmaddr, LLDPAD_SHM_SIZE); + + return 1; + } +@@ -410,13 +431,16 @@ int clear_dcbx_state() + int version; + unsigned num_entries; + +- shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE, 0); ++ shmid = shm_open(LLDPAD_SHM_PATH, O_RDWR, S_IRUSR | S_IWUSR); + + if (shmid < 0) + return 0; + +- shmaddr = (struct lldpad_shm_tbl *)shmat(shmid, NULL, 0); +- if ((long) shmaddr == -1) ++ shmaddr = (struct lldpad_shm_tbl *) mmap(NULL, LLDPAD_SHM_SIZE, ++ PROT_READ | PROT_WRITE, ++ MAP_SHARED, shmid, 0); ++ close(shmid); ++ if (shmaddr == MAP_FAILED) + return 0; + + version = (shmaddr->num_entries & SHM_VER_MASK) >> SHM_VER_SHIFT; +@@ -437,7 +461,7 @@ int clear_dcbx_state() + sizeof(dcbx_state)); + + done: +- shmdt(shmaddr); ++ munmap(shmaddr, LLDPAD_SHM_SIZE); + return 1; + } + +@@ -451,13 +475,16 @@ int set_dcbx_state(const char *device_name, dcbx_state *state) + int version; + unsigned num_entries; + +- shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE, 0); ++ shmid = shm_open(LLDPAD_SHM_PATH, O_RDWR, S_IRUSR | S_IWUSR); + + if (shmid < 0) + return rval; + +- shmaddr = (struct lldpad_shm_tbl *)shmat(shmid, NULL, 0); +- if ((long) shmaddr == -1) ++ shmaddr = (struct lldpad_shm_tbl *) mmap(NULL, LLDPAD_SHM_SIZE, ++ PROT_READ | PROT_WRITE, ++ MAP_SHARED, shmid, 0); ++ close(shmid); ++ if (shmaddr == MAP_FAILED) + return rval; + + version = (shmaddr->num_entries & SHM_VER_MASK) >> SHM_VER_SHIFT; +@@ -487,7 +514,7 @@ int set_dcbx_state(const char *device_name, dcbx_state *state) + } + + done: +- shmdt(shmaddr); ++ munmap(shmaddr, LLDPAD_SHM_SIZE); + + return rval; + } +@@ -505,13 +532,16 @@ int get_dcbx_state(const char *device_name, dcbx_state *state) + int version; + unsigned num_entries; + +- shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE, 0); ++ shmid = shm_open(LLDPAD_SHM_PATH, O_RDWR, S_IRUSR | S_IWUSR); + + if (shmid < 0) + return rval; + +- shmaddr = (struct lldpad_shm_tbl *)shmat(shmid, NULL, 0); +- if ((long) shmaddr == -1) ++ shmaddr = (struct lldpad_shm_tbl *) mmap(NULL, LLDPAD_SHM_SIZE, ++ PROT_READ | PROT_WRITE, ++ MAP_SHARED, shmid, 0); ++ close(shmid); ++ if (shmaddr == MAP_FAILED) + return rval; + + version = (shmaddr->num_entries & SHM_VER_MASK) >> SHM_VER_SHIFT; +@@ -537,7 +567,7 @@ int get_dcbx_state(const char *device_name, dcbx_state *state) + } + + done: +- shmdt(shmaddr); ++ munmap(shmaddr, LLDPAD_SHM_SIZE); + + return rval; + } +@@ -562,17 +592,20 @@ int print_lldpad_shm() + int ent_size; + struct lldpad_shm_entry *entry_ptr = NULL; + +- shmid = shmget(LLDPAD_SHM_KEY, LLDPAD_SHM_SIZE, 0); ++ shmid = shm_open(LLDPAD_SHM_PATH, O_RDWR, S_IRUSR | S_IWUSR); + + if (shmid < 0) { +- printf("failed to shmget\n"); ++ printf("failed to shm_open\n"); + return rval; + } + +- shmaddr = (struct lldpad_shm_tbl *)shmat(shmid, NULL, 0); ++ shmaddr = (struct lldpad_shm_tbl *) mmap(NULL, LLDPAD_SHM_SIZE, ++ PROT_READ | PROT_WRITE, ++ MAP_SHARED, shmid, 0); + shmaddr_ver0 = (struct lldpad_shm_tbl_ver0 *)shmaddr; +- if ((long) shmaddr == -1) { +- printf("failed to shmat\n"); ++ close(shmid); ++ if (shmaddr == MAP_FAILED) { ++ printf("failed to mmap\n"); + return rval; + } + +@@ -633,7 +666,7 @@ int print_lldpad_shm() + rval = 1; + + done: +- shmdt(shmaddr); ++ munmap(shmaddr, LLDPAD_SHM_SIZE); + + return rval; + } +-- +2.1.0 + diff --git a/SOURCES/open-lldp-v1.0.1-25-l2_linux_packet-correctly-process-return-value-of-ge.patch b/SOURCES/open-lldp-v1.0.1-25-l2_linux_packet-correctly-process-return-value-of-ge.patch new file mode 100644 index 0000000..916c079 --- /dev/null +++ b/SOURCES/open-lldp-v1.0.1-25-l2_linux_packet-correctly-process-return-value-of-ge.patch @@ -0,0 +1,37 @@ +From e212eb214afaea300194333f652b950941299339 Mon Sep 17 00:00:00 2001 +From: Johannes Thumshirn +Date: Wed, 20 May 2015 16:14:37 +0000 +Subject: [PATCH] l2_linux_packet: correctly process return value of + get_perm_hwaddr + +On success get_perm_hwaddr() returns the number of bytes read from the +netlink socket. + +l2_packet_init() checked for 0 as a successful return value. + +Adopt get_perm_hwaddr() to return 0 on success. + +Refrence: bsc#929171 + +Signed-off-by: Johannes Thumshirn +Signed-off-by: John Fastabend +--- + lldp_rtnl.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/lldp_rtnl.c b/lldp_rtnl.c +index 33b4d19..8d4f0cc 100644 +--- a/lldp_rtnl.c ++++ b/lldp_rtnl.c +@@ -322,6 +322,8 @@ int get_perm_hwaddr(const char *ifname, u8 *buf_perm, u8 *buf_san) + + memcpy(buf_perm, RTA_DATA(rta), ETH_ALEN); + memcpy(buf_san, RTA_DATA(rta) + ETH_ALEN, ETH_ALEN); ++ ++ rc = 0; + out: + close(s); + out_nosock: +-- +2.5.5 + diff --git a/SOURCES/open-lldp-v1.0.1-26-lldpad-system-capability-incorrect-advertised-as-sta.patch b/SOURCES/open-lldp-v1.0.1-26-lldpad-system-capability-incorrect-advertised-as-sta.patch new file mode 100644 index 0000000..872c527 --- /dev/null +++ b/SOURCES/open-lldp-v1.0.1-26-lldpad-system-capability-incorrect-advertised-as-sta.patch @@ -0,0 +1,72 @@ +From 036e314bd93602f7388262cc37faf8b626980af1 Mon Sep 17 00:00:00 2001 +From: Gary Loughnane +Date: Mon, 17 Aug 2015 21:19:24 +0000 +Subject: [PATCH] lldpad: system capability incorrect advertised as station + only + +Fix system capability TLV on switch. On our switches we have found +that the system capability was being advertised as Station Only. This +patch changes the capability to Bridge. + +Signed-off-by: Gary Loughnane +Signed-off-by: John Fastabend +--- + include/lldp_util.h | 1 + + lldp_util.c | 22 +++++++++++++++++++++- + 2 files changed, 22 insertions(+), 1 deletion(-) + +diff --git a/include/lldp_util.h b/include/lldp_util.h +index 878426b..69b67b1 100644 +--- a/include/lldp_util.h ++++ b/include/lldp_util.h +@@ -125,6 +125,7 @@ int is_active(const char *ifname); + int is_bond(const char *ifname); + int is_san_mac(u8 *addr); + int is_bridge(const char *ifname); ++int is_bridge_port(const char *ifname); + int is_vlan(const char *ifname); + int is_vlan_capable(const char *ifname); + int is_wlan(const char *ifname); +diff --git a/lldp_util.c b/lldp_util.c +index f1fb7b9..62f0af8 100644 +--- a/lldp_util.c ++++ b/lldp_util.c +@@ -580,6 +580,26 @@ int is_bridge(const char *ifname) + return rc; + } + ++int is_bridge_port(const char *ifname) ++{ ++ int rc = 0; ++ char path[256]; ++ DIR *dirp; ++ ++ if (!is_ether(ifname)) { ++ return 0; ++ } ++ /* check if the given ifname is a bridge port in sysfs */ ++ snprintf(path, sizeof(path), "/sys/class/net/%s/brport/", ifname); ++ dirp = opendir(path); ++ if (dirp) { ++ closedir(dirp); ++ rc = 1; ++ } ++ ++ return rc; ++} ++ + int is_vlan(const char *ifname) + { + int fd; +@@ -942,7 +962,7 @@ u16 get_caps(const char *ifname) + if (is_vlan(ifname)) + caps |= SYSCAP_CVLAN; + +- if (is_bridge(ifname)) ++ if (is_bridge_port(ifname)) + caps |= SYSCAP_BRIDGE; + + if (is_router()) +-- +2.5.5 + diff --git a/SOURCES/open-lldp-v1.0.1-27-fix-build-warnings.patch b/SOURCES/open-lldp-v1.0.1-27-fix-build-warnings.patch new file mode 100644 index 0000000..405270c --- /dev/null +++ b/SOURCES/open-lldp-v1.0.1-27-fix-build-warnings.patch @@ -0,0 +1,94 @@ +From 80fb9db6598440d3af6bdcbcd4f6788f7e660bbe Mon Sep 17 00:00:00 2001 +From: Chris Leech +Date: Wed, 17 Jun 2015 10:40:34 -0700 +Subject: [PATCH] fix build warnings + +--- + include/lldp_8021qaz.h | 6 ------ + lldp/agent.c | 5 +++++ + lldp/agent.h | 6 +++--- + lldp_util.c | 4 ++-- + 4 files changed, 10 insertions(+), 11 deletions(-) + +diff --git a/include/lldp_8021qaz.h b/include/lldp_8021qaz.h +index 55353b8..09dee20 100644 +--- a/include/lldp_8021qaz.h ++++ b/include/lldp_8021qaz.h +@@ -218,9 +218,6 @@ int ieee8021qaz_mod_app(struct app_tlv_head *head, int peer, + u8 prio, u8 sel, u16 proto, u32 ops); + int ieee8021qaz_app_sethw(char *ifname, struct app_tlv_head *head); + +-inline int get_prio_map(u32 prio_map, int tc); +-inline void set_prio_map(u32 *prio_map, u8 prio, int tc); +- + struct ieee8021qaz_tlvs *ieee8021qaz_data(const char *); + + int ieee8021qaz_tlvs_rxed(const char *ifname); +@@ -234,9 +231,6 @@ int ieee8021qaz_rchange(struct port *port, struct lldp_agent *, + void ieee8021qaz_ifup(char *ifname, struct lldp_agent *); + void ieee8021qaz_ifdown(char *ifname, struct lldp_agent *); + u8 ieee8021qaz_mibDeleteObject(struct port *port, struct lldp_agent *); +-inline int ieee8021qaz_clif_cmd(void *data, struct sockaddr_un *from, +- socklen_t fromlen, char *ibuf, int ilen, +- char *rbuf); + int ieee8021qaz_check_operstate(void); + int get_dcbx_hw(const char *ifname, __u8 *dcbx); + +diff --git a/lldp/agent.c b/lldp/agent.c +index 73ab054..333929a 100644 +--- a/lldp/agent.c ++++ b/lldp/agent.c +@@ -36,6 +36,11 @@ + #include "lldp_mand_clif.h" + #include "lldp/agent.h" + ++/* IEEE 802.1AB-2009 - Table 7-1: group MAC addresses used by LLDP */ ++const u8 nearest_bridge[ETH_ALEN] = {0x01,0x80,0xc2,0x00,0x00,0x0e}; ++const u8 nearest_nontpmr_bridge[ETH_ALEN] = {0x01,0x80,0xc2,0x00,0x00,0x03}; ++const u8 nearest_customer_bridge[ETH_ALEN] = {0x01,0x80,0xc2,0x00,0x00,0x00}; ++ + static const u8 * agent_groupmacs[AGENT_MAX] = { + nearest_bridge, + nearest_nontpmr_bridge, +diff --git a/lldp/agent.h b/lldp/agent.h +index a54f72f..90da3e0 100644 +--- a/lldp/agent.h ++++ b/lldp/agent.h +@@ -48,9 +48,9 @@ enum agent_type { + }; + + /* IEEE 802.1AB-2009 - Table 7-1: group MAC addresses used by LLDP */ +-static const u8 nearest_bridge[ETH_ALEN] = {0x01,0x80,0xc2,0x00,0x00,0x0e}; +-static const u8 nearest_nontpmr_bridge[ETH_ALEN] = {0x01,0x80,0xc2,0x00,0x00,0x03}; +-static const u8 nearest_customer_bridge[ETH_ALEN] = {0x01,0x80,0xc2,0x00,0x00,0x00}; ++extern const u8 nearest_bridge[ETH_ALEN]; ++extern const u8 nearest_nontpmr_bridge[ETH_ALEN]; ++extern const u8 nearest_customer_bridge[ETH_ALEN]; + + struct agenttimers { + /* Tx */ +diff --git a/lldp_util.c b/lldp_util.c +index 62f0af8..f12d46b 100644 +--- a/lldp_util.c ++++ b/lldp_util.c +@@ -1197,7 +1197,7 @@ int check_link_status(const char *ifname) + int get_arg_val_list(char *ibuf, int ilen, int *ioff, + char **args, char **argvals) + { +- u8 arglen; ++ u8 arglen = 0; + u16 argvalue_len; + int *arglens = NULL; + int *argvallens = NULL; +@@ -1265,7 +1265,7 @@ int get_arg_val_list(char *ibuf, int ilen, int *ioff, + + int get_arg_list(char *ibuf, int ilen, int *ioff, char **args) + { +- u8 arglen; ++ u8 arglen = 0; + int *arglens = NULL; + int *p; + int numargs; +-- +2.5.5 + diff --git a/SOURCES/open-lldp-v1.0.1-28-fix-oid-display.patch b/SOURCES/open-lldp-v1.0.1-28-fix-oid-display.patch new file mode 100644 index 0000000..74ef1dd --- /dev/null +++ b/SOURCES/open-lldp-v1.0.1-28-fix-oid-display.patch @@ -0,0 +1,52 @@ +From cf3f54d1883e5bc23e4c4006a63e1dde88684013 Mon Sep 17 00:00:00 2001 +From: Aaron Conole +Date: Thu, 21 Jun 2018 13:28:48 -0400 +Subject: [PATCH] basman_clif: print the OID properly + +When invoking the lldp tool to view the management information, the display +for the OID is printed as the actual binary bits, rather than the +OID dotted-notation form. + +This change will display the OID as expected. + +Signed-off-by: Aaron Conole +--- + lldp_basman_clif.c | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +diff --git a/lldp_basman_clif.c b/lldp_basman_clif.c +index 7dba9d2..abd152d 100644 +--- a/lldp_basman_clif.c ++++ b/lldp_basman_clif.c +@@ -272,8 +272,15 @@ void print_mng_addr(u16 len, char *info) + memset(buf, 0, sizeof(buf)); + if (hexstr2bin(info+offset, (u8 *)&buf, oidlen)) + printf("\tOID: Error parsing OID\n"); +- else +- printf("\tOID: %s\n", buf); ++ else { ++ printf("\tOID: 0."); ++ for (i = 0; i < oidlen; ++i) { ++ printf("%d", buf[i]); ++ if (i != (oidlen - 1)) ++ printf("."); ++ } ++ printf("\n"); ++ } + } else if (oidlen > 128) { + printf("\tOID: Invalid length = %d\n", oidlen); + } +@@ -310,3 +317,10 @@ u32 basman_lookup_tlv_name(char *tlvid_str) + } + return INVALID_TLVID; + } ++ ++/* Local Variables: */ ++/* c-indent-level: 8 */ ++/* c-basic-offset: 8 */ ++/* tab-width: 8 */ ++/* indent-tabs-mode: t */ ++/* End: */ +-- +2.14.3 + diff --git a/SOURCES/open-lldp-v1.0.1-3-VDP-vdptool-test-cases-Some-test-cases-to-test-the-n.patch b/SOURCES/open-lldp-v1.0.1-3-VDP-vdptool-test-cases-Some-test-cases-to-test-the-n.patch new file mode 100644 index 0000000..76430d9 --- /dev/null +++ b/SOURCES/open-lldp-v1.0.1-3-VDP-vdptool-test-cases-Some-test-cases-to-test-the-n.patch @@ -0,0 +1,2722 @@ +From 61965537b574e8dcd1d7b61ef543ab11fcbbbe6b Mon Sep 17 00:00:00 2001 +From: Thomas Richter +Date: Wed, 21 Jan 2015 03:36:48 +0000 +Subject: [PATCH] VDP: vdptool test cases Some test cases to test the new + vdptool. + +Signed-off-by: Thomas Richter +Signed-off-by: John Fastabend +--- + test/qbg22/vdp22/300-lldpad.conf | 55 +++++++++++++++++++++++ + test/qbg22/vdp22/300.nlc | 54 +++++++++++++++++++++++ + test/qbg22/vdp22/300.vdp | 55 +++++++++++++++++++++++ + test/qbg22/vdp22/301-lldpad.conf | 55 +++++++++++++++++++++++ + test/qbg22/vdp22/301.nlc | 54 +++++++++++++++++++++++ + test/qbg22/vdp22/301.vdp | 55 +++++++++++++++++++++++ + test/qbg22/vdp22/302-lldpad.conf | 55 +++++++++++++++++++++++ + test/qbg22/vdp22/302.nlc | 54 +++++++++++++++++++++++ + test/qbg22/vdp22/302.vdp | 55 +++++++++++++++++++++++ + test/qbg22/vdp22/303-lldpad.conf | 55 +++++++++++++++++++++++ + test/qbg22/vdp22/303.nlc | 54 +++++++++++++++++++++++ + test/qbg22/vdp22/303.vdp | 55 +++++++++++++++++++++++ + test/qbg22/vdp22/304-lldpad.conf | 55 +++++++++++++++++++++++ + test/qbg22/vdp22/304.nlc | 54 +++++++++++++++++++++++ + test/qbg22/vdp22/304.vdp | 55 +++++++++++++++++++++++ + test/qbg22/vdp22/305-lldpad.conf | 55 +++++++++++++++++++++++ + test/qbg22/vdp22/305.nlc | 54 +++++++++++++++++++++++ + test/qbg22/vdp22/305.vdp | 55 +++++++++++++++++++++++ + test/qbg22/vdp22/306-lldpad.conf | 55 +++++++++++++++++++++++ + test/qbg22/vdp22/306.nlc | 54 +++++++++++++++++++++++ + test/qbg22/vdp22/306.vdp | 55 +++++++++++++++++++++++ + test/qbg22/vdp22/307-lldpad.conf | 55 +++++++++++++++++++++++ + test/qbg22/vdp22/307.nlc | 54 +++++++++++++++++++++++ + test/qbg22/vdp22/307.vdp | 55 +++++++++++++++++++++++ + test/qbg22/vdp22/308-lldpad.conf | 55 +++++++++++++++++++++++ + test/qbg22/vdp22/308.nlc | 54 +++++++++++++++++++++++ + test/qbg22/vdp22/308.vdp | 55 +++++++++++++++++++++++ + test/qbg22/vdp22/309-lldpad.conf | 55 +++++++++++++++++++++++ + test/qbg22/vdp22/309.nlc | 54 +++++++++++++++++++++++ + test/qbg22/vdp22/309.vdp | 55 +++++++++++++++++++++++ + test/qbg22/vdp22/310-lldpad.conf | 55 +++++++++++++++++++++++ + test/qbg22/vdp22/310.nlc | 54 +++++++++++++++++++++++ + test/qbg22/vdp22/310.vdp | 55 +++++++++++++++++++++++ + test/qbg22/vdp22/320-lldpad.conf | 55 +++++++++++++++++++++++ + test/qbg22/vdp22/320.nlc | 65 +++++++++++++++++++++++++++ + test/qbg22/vdp22/320.vdp | 55 +++++++++++++++++++++++ + test/qbg22/vdp22/321-lldpad.conf | 55 +++++++++++++++++++++++ + test/qbg22/vdp22/321.nlc | 78 +++++++++++++++++++++++++++++++++ + test/qbg22/vdp22/321.vdp | 55 +++++++++++++++++++++++ + test/qbg22/vdp22/322-lldpad.conf | 55 +++++++++++++++++++++++ + test/qbg22/vdp22/322.nlc | 95 ++++++++++++++++++++++++++++++++++++++++ + test/qbg22/vdp22/322.vdp | 55 +++++++++++++++++++++++ + 42 files changed, 2372 insertions(+) + create mode 100644 test/qbg22/vdp22/300-lldpad.conf + create mode 100755 test/qbg22/vdp22/300.nlc + create mode 100644 test/qbg22/vdp22/300.vdp + create mode 100644 test/qbg22/vdp22/301-lldpad.conf + create mode 100755 test/qbg22/vdp22/301.nlc + create mode 100644 test/qbg22/vdp22/301.vdp + create mode 100644 test/qbg22/vdp22/302-lldpad.conf + create mode 100755 test/qbg22/vdp22/302.nlc + create mode 100644 test/qbg22/vdp22/302.vdp + create mode 100644 test/qbg22/vdp22/303-lldpad.conf + create mode 100755 test/qbg22/vdp22/303.nlc + create mode 100644 test/qbg22/vdp22/303.vdp + create mode 100644 test/qbg22/vdp22/304-lldpad.conf + create mode 100755 test/qbg22/vdp22/304.nlc + create mode 100644 test/qbg22/vdp22/304.vdp + create mode 100644 test/qbg22/vdp22/305-lldpad.conf + create mode 100755 test/qbg22/vdp22/305.nlc + create mode 100644 test/qbg22/vdp22/305.vdp + create mode 100644 test/qbg22/vdp22/306-lldpad.conf + create mode 100755 test/qbg22/vdp22/306.nlc + create mode 100644 test/qbg22/vdp22/306.vdp + create mode 100644 test/qbg22/vdp22/307-lldpad.conf + create mode 100755 test/qbg22/vdp22/307.nlc + create mode 100644 test/qbg22/vdp22/307.vdp + create mode 100644 test/qbg22/vdp22/308-lldpad.conf + create mode 100755 test/qbg22/vdp22/308.nlc + create mode 100644 test/qbg22/vdp22/308.vdp + create mode 100644 test/qbg22/vdp22/309-lldpad.conf + create mode 100755 test/qbg22/vdp22/309.nlc + create mode 100644 test/qbg22/vdp22/309.vdp + create mode 100644 test/qbg22/vdp22/310-lldpad.conf + create mode 100755 test/qbg22/vdp22/310.nlc + create mode 100644 test/qbg22/vdp22/310.vdp + create mode 100644 test/qbg22/vdp22/320-lldpad.conf + create mode 100755 test/qbg22/vdp22/320.nlc + create mode 100644 test/qbg22/vdp22/320.vdp + create mode 100644 test/qbg22/vdp22/321-lldpad.conf + create mode 100755 test/qbg22/vdp22/321.nlc + create mode 100644 test/qbg22/vdp22/321.vdp + create mode 100644 test/qbg22/vdp22/322-lldpad.conf + create mode 100755 test/qbg22/vdp22/322.nlc + create mode 100644 test/qbg22/vdp22/322.vdp + +diff --git a/test/qbg22/vdp22/300-lldpad.conf b/test/qbg22/vdp22/300-lldpad.conf +new file mode 100644 +index 0000000..6027a6d +--- /dev/null ++++ b/test/qbg22/vdp22/300-lldpad.conf +@@ -0,0 +1,55 @@ ++# ++# Test case for LLDPAD testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# Configuration file for lldpad station mode setup. ++ ++dcbx : ++{ ++ version = "1.0"; ++ dcbx_version = 2; ++}; ++nearest_customer_bridge : ++{ ++ veth0 : ++ { ++ tlvid00000001 : ++ { ++ info = "04CA802A1EE5D1"; ++ }; ++ tlvid00000002 : ++ { ++ info = "03CA802A1EE5D1"; ++ }; ++ adminStatus = 3; ++ tlvid0080c20d : ++ { ++ enableTx = true; ++ evbmode = "station"; ++ evbrrcap = false; ++ evbrrreq = true; ++ evbgpid = false; ++ ecpretries = 3; ++ ecprte = 14; ++ vdprwd = 20; ++ vdprka = 20; ++ }; ++ }; ++}; +diff --git a/test/qbg22/vdp22/300.nlc b/test/qbg22/vdp22/300.nlc +new file mode 100755 +index 0000000..ea801b2 +--- /dev/null ++++ b/test/qbg22/vdp22/300.nlc +@@ -0,0 +1,54 @@ ++#!/bin/bash ++# ++# Test case for LLDPAD VDP testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2013 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# ++# Thomas Richter, IBM Research & Development, Boeblingen, Germany, 20-Apr-2013 ++# ++# Execute a simple assoc with wrong user input using vdptool. ++# Wrong association command ++# ++ ++sleep 30 # Must: Wait some time for lldpad to start up and initialize ++outfile=$(basename $0) ++dirfile=$(dirname $0) ++cd $dirfile ++ ++vsi_ok="Invalid parameters" ++reply=$(../../../vdptool -i veth0 -T -V assoc -c vsi=Xassoc,hello,1,2,001122334-455667788-99aabbccddee,none,22222-a:b:c:0:0:0) ++rc=$? ++if [ "$rc" -eq 1 ] ++then ++ if [ "$reply" != "$vsi_ok" ] ++ then ++ echo "vdptool reply mismatch" ++ echo "expected reply:$vsi_ok" ++ echo "returned reply:$reply" ++ else ++ let rc=0 ++ fi ++else ++ echo "vdptool unexpected success" ++ let rc=1 ++fi ++ ++sleep 5 ++exit $rc +diff --git a/test/qbg22/vdp22/300.vdp b/test/qbg22/vdp22/300.vdp +new file mode 100644 +index 0000000..cb9bacd +--- /dev/null ++++ b/test/qbg22/vdp22/300.vdp +@@ -0,0 +1,55 @@ ++# ++# Test case for LLDPAD testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# Configuration file for lldpad bridge mode setup. ++ ++dcbx : ++{ ++ version = "1.0"; ++ dcbx_version = 2; ++}; ++nearest_customer_bridge : ++{ ++ veth2 : ++ { ++ tlvid00000001 : ++ { ++ info = "041E64AF9A93DF"; ++ }; ++ tlvid00000002 : ++ { ++ info = "031E64AF9A93DF"; ++ }; ++ adminStatus = 3; ++ tlvid0080c20d : ++ { ++ enableTx = true; ++ evbmode = "bridge"; ++ evbrrcap = true; ++ evbrrreq = true; ++ evbgpid = false; ++ ecpretries = 3; ++ ecprte = 14; ++ vdprwd = 20; ++ vdprka = 20; ++ }; ++ }; ++}; +diff --git a/test/qbg22/vdp22/301-lldpad.conf b/test/qbg22/vdp22/301-lldpad.conf +new file mode 100644 +index 0000000..11ed7a2 +--- /dev/null ++++ b/test/qbg22/vdp22/301-lldpad.conf +@@ -0,0 +1,55 @@ ++# ++# Test case for LLDPAD testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# Configuration file for lldpad station mode setup. ++ ++dcbx : ++{ ++ version = "1.0"; ++ dcbx_version = 2; ++}; ++nearest_customer_bridge : ++{ ++ veth0 : ++ { ++ tlvid00000001 : ++ { ++ info = "04C68829509676"; ++ }; ++ tlvid00000002 : ++ { ++ info = "03C68829509676"; ++ }; ++ adminStatus = 3; ++ tlvid0080c20d : ++ { ++ enableTx = true; ++ evbmode = "station"; ++ evbrrcap = false; ++ evbrrreq = true; ++ evbgpid = false; ++ ecpretries = 3; ++ ecprte = 14; ++ vdprwd = 20; ++ vdprka = 20; ++ }; ++ }; ++}; +diff --git a/test/qbg22/vdp22/301.nlc b/test/qbg22/vdp22/301.nlc +new file mode 100755 +index 0000000..90409d7 +--- /dev/null ++++ b/test/qbg22/vdp22/301.nlc +@@ -0,0 +1,54 @@ ++#!/bin/bash ++# ++# Test case for LLDPAD VDP testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# ++# Thomas Richter, IBM Research & Development, Boeblingen, Germany, 20-Apr-2013 ++# ++# Execute a simple assoc with wrong user input using vdptool. ++# Wrong manager identifier ++# ++ ++sleep 30 # Must: Wait some time for lldpad to start up and initialize ++outfile=$(basename $0) ++dirfile=$(dirname $0) ++cd $dirfile ++ ++vsi_ok="Invalid parameters" ++reply=$(../../../vdptool -i veth0 -T -V assoc -c vsi=assoc,\\hello,1,2,001122334-455667788-99aabbccddee,none,22222-a:b:c:0:0:0) ++rc=$? ++if [ "$rc" -eq 1 ] ++then ++ if [ "$reply" != "$vsi_ok" ] ++ then ++ echo "vdptool reply mismatch" ++ echo "expected reply:$vsi_ok" ++ echo "returned reply:$reply" ++ else ++ let rc=0 ++ fi ++else ++ echo "vdptool unexpected success" ++ let rc=1 ++fi ++ ++sleep 5 ++exit $rc +diff --git a/test/qbg22/vdp22/301.vdp b/test/qbg22/vdp22/301.vdp +new file mode 100644 +index 0000000..0c7e96a +--- /dev/null ++++ b/test/qbg22/vdp22/301.vdp +@@ -0,0 +1,55 @@ ++# ++# Test case for LLDPAD testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# Configuration file for lldpad bridge mode setup. ++ ++dcbx : ++{ ++ version = "1.0"; ++ dcbx_version = 2; ++}; ++nearest_customer_bridge : ++{ ++ veth2 : ++ { ++ tlvid00000001 : ++ { ++ info = "04C68829509676"; ++ }; ++ tlvid00000002 : ++ { ++ info = "03C68829509676"; ++ }; ++ adminStatus = 3; ++ tlvid0080c20d : ++ { ++ enableTx = true; ++ evbmode = "bridge"; ++ evbrrcap = true; ++ evbrrreq = true; ++ evbgpid = false; ++ ecpretries = 3; ++ ecprte = 14; ++ vdprwd = 20; ++ vdprka = 20; ++ }; ++ }; ++}; +diff --git a/test/qbg22/vdp22/302-lldpad.conf b/test/qbg22/vdp22/302-lldpad.conf +new file mode 100644 +index 0000000..11ed7a2 +--- /dev/null ++++ b/test/qbg22/vdp22/302-lldpad.conf +@@ -0,0 +1,55 @@ ++# ++# Test case for LLDPAD testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# Configuration file for lldpad station mode setup. ++ ++dcbx : ++{ ++ version = "1.0"; ++ dcbx_version = 2; ++}; ++nearest_customer_bridge : ++{ ++ veth0 : ++ { ++ tlvid00000001 : ++ { ++ info = "04C68829509676"; ++ }; ++ tlvid00000002 : ++ { ++ info = "03C68829509676"; ++ }; ++ adminStatus = 3; ++ tlvid0080c20d : ++ { ++ enableTx = true; ++ evbmode = "station"; ++ evbrrcap = false; ++ evbrrreq = true; ++ evbgpid = false; ++ ecpretries = 3; ++ ecprte = 14; ++ vdprwd = 20; ++ vdprka = 20; ++ }; ++ }; ++}; +diff --git a/test/qbg22/vdp22/302.nlc b/test/qbg22/vdp22/302.nlc +new file mode 100755 +index 0000000..1f0dfed +--- /dev/null ++++ b/test/qbg22/vdp22/302.nlc +@@ -0,0 +1,54 @@ ++#!/bin/bash ++# ++# Test case for LLDPAD VDP testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# ++# Thomas Richter, IBM Research & Development, Boeblingen, Germany, 20-Apr-2013 ++# ++# Execute a simple assoc with wrong user input using vdptool. ++# Wrong type identifier ++# ++ ++sleep 30 # Must: Wait some time for lldpad to start up and initialize ++outfile=$(basename $0) ++dirfile=$(dirname $0) ++cd $dirfile ++ ++vsi_ok="Invalid parameters" ++reply=$(../../../vdptool -i veth0 -T -V assoc -c vsi=assoc,hello,1000000999,2,001122334-455667788-99aabbccddee,none,22222-a:b:c:0:0:0) ++rc=$? ++if [ "$rc" -eq 1 ] ++then ++ if [ "$reply" != "$vsi_ok" ] ++ then ++ echo "vdptool reply mismatch" ++ echo "expected reply:$vsi_ok" ++ echo "returned reply:$reply" ++ else ++ let rc=0 ++ fi ++else ++ echo "vdptool unexpected success" ++ let rc=1 ++fi ++ ++sleep 5 ++exit $rc +diff --git a/test/qbg22/vdp22/302.vdp b/test/qbg22/vdp22/302.vdp +new file mode 100644 +index 0000000..0c7e96a +--- /dev/null ++++ b/test/qbg22/vdp22/302.vdp +@@ -0,0 +1,55 @@ ++# ++# Test case for LLDPAD testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# Configuration file for lldpad bridge mode setup. ++ ++dcbx : ++{ ++ version = "1.0"; ++ dcbx_version = 2; ++}; ++nearest_customer_bridge : ++{ ++ veth2 : ++ { ++ tlvid00000001 : ++ { ++ info = "04C68829509676"; ++ }; ++ tlvid00000002 : ++ { ++ info = "03C68829509676"; ++ }; ++ adminStatus = 3; ++ tlvid0080c20d : ++ { ++ enableTx = true; ++ evbmode = "bridge"; ++ evbrrcap = true; ++ evbrrreq = true; ++ evbgpid = false; ++ ecpretries = 3; ++ ecprte = 14; ++ vdprwd = 20; ++ vdprka = 20; ++ }; ++ }; ++}; +diff --git a/test/qbg22/vdp22/303-lldpad.conf b/test/qbg22/vdp22/303-lldpad.conf +new file mode 100644 +index 0000000..11ed7a2 +--- /dev/null ++++ b/test/qbg22/vdp22/303-lldpad.conf +@@ -0,0 +1,55 @@ ++# ++# Test case for LLDPAD testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# Configuration file for lldpad station mode setup. ++ ++dcbx : ++{ ++ version = "1.0"; ++ dcbx_version = 2; ++}; ++nearest_customer_bridge : ++{ ++ veth0 : ++ { ++ tlvid00000001 : ++ { ++ info = "04C68829509676"; ++ }; ++ tlvid00000002 : ++ { ++ info = "03C68829509676"; ++ }; ++ adminStatus = 3; ++ tlvid0080c20d : ++ { ++ enableTx = true; ++ evbmode = "station"; ++ evbrrcap = false; ++ evbrrreq = true; ++ evbgpid = false; ++ ecpretries = 3; ++ ecprte = 14; ++ vdprwd = 20; ++ vdprka = 20; ++ }; ++ }; ++}; +diff --git a/test/qbg22/vdp22/303.nlc b/test/qbg22/vdp22/303.nlc +new file mode 100755 +index 0000000..b40e6c6 +--- /dev/null ++++ b/test/qbg22/vdp22/303.nlc +@@ -0,0 +1,54 @@ ++#!/bin/bash ++# ++# Test case for LLDPAD VDP testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# ++# Thomas Richter, IBM Research & Development, Boeblingen, Germany, 20-Apr-2013 ++# ++# Execute a simple assoc with wrong user input using vdptool. ++# Wrong typeidversion ++# ++ ++sleep 30 # Must: Wait some time for lldpad to start up and initialize ++outfile=$(basename $0) ++dirfile=$(dirname $0) ++cd $dirfile ++ ++vsi_ok="Invalid parameters" ++reply=$(../../../vdptool -i veth0 -T -V assoc -c vsi=assoc,hello,1,257,001122334-455667788-99aabbccddee,none,22222-a:b:c:0:0:0) ++rc=$? ++if [ "$rc" -eq 1 ] ++then ++ if [ "$reply" != "$vsi_ok" ] ++ then ++ echo "vdptool reply mismatch" ++ echo "expected reply:$vsi_ok" ++ echo "returned reply:$reply" ++ else ++ let rc=0 ++ fi ++else ++ echo "vdptool unexpected success" ++ let rc=1 ++fi ++ ++sleep 5 ++exit $rc +diff --git a/test/qbg22/vdp22/303.vdp b/test/qbg22/vdp22/303.vdp +new file mode 100644 +index 0000000..0c7e96a +--- /dev/null ++++ b/test/qbg22/vdp22/303.vdp +@@ -0,0 +1,55 @@ ++# ++# Test case for LLDPAD testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# Configuration file for lldpad bridge mode setup. ++ ++dcbx : ++{ ++ version = "1.0"; ++ dcbx_version = 2; ++}; ++nearest_customer_bridge : ++{ ++ veth2 : ++ { ++ tlvid00000001 : ++ { ++ info = "04C68829509676"; ++ }; ++ tlvid00000002 : ++ { ++ info = "03C68829509676"; ++ }; ++ adminStatus = 3; ++ tlvid0080c20d : ++ { ++ enableTx = true; ++ evbmode = "bridge"; ++ evbrrcap = true; ++ evbrrreq = true; ++ evbgpid = false; ++ ecpretries = 3; ++ ecprte = 14; ++ vdprwd = 20; ++ vdprka = 20; ++ }; ++ }; ++}; +diff --git a/test/qbg22/vdp22/304-lldpad.conf b/test/qbg22/vdp22/304-lldpad.conf +new file mode 100644 +index 0000000..11ed7a2 +--- /dev/null ++++ b/test/qbg22/vdp22/304-lldpad.conf +@@ -0,0 +1,55 @@ ++# ++# Test case for LLDPAD testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# Configuration file for lldpad station mode setup. ++ ++dcbx : ++{ ++ version = "1.0"; ++ dcbx_version = 2; ++}; ++nearest_customer_bridge : ++{ ++ veth0 : ++ { ++ tlvid00000001 : ++ { ++ info = "04C68829509676"; ++ }; ++ tlvid00000002 : ++ { ++ info = "03C68829509676"; ++ }; ++ adminStatus = 3; ++ tlvid0080c20d : ++ { ++ enableTx = true; ++ evbmode = "station"; ++ evbrrcap = false; ++ evbrrreq = true; ++ evbgpid = false; ++ ecpretries = 3; ++ ecprte = 14; ++ vdprwd = 20; ++ vdprka = 20; ++ }; ++ }; ++}; +diff --git a/test/qbg22/vdp22/304.nlc b/test/qbg22/vdp22/304.nlc +new file mode 100755 +index 0000000..3bae87e +--- /dev/null ++++ b/test/qbg22/vdp22/304.nlc +@@ -0,0 +1,54 @@ ++#!/bin/bash ++# ++# Test case for LLDPAD VDP testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# ++# Thomas Richter, IBM Research & Development, Boeblingen, Germany, 20-Apr-2013 ++# ++# Execute a simple assoc with wrong user input using vdptool. ++# Wrong hints ++# ++ ++sleep 30 # Must: Wait some time for lldpad to start up and initialize ++outfile=$(basename $0) ++dirfile=$(dirname $0) ++cd $dirfile ++ ++vsi_ok="Invalid parameters" ++reply=$(../../../vdptool -i veth0 -T -V assoc -c vsi=assoc,hello,1,255,001122334-455667788-99aabbccddee,nix,22222-a:b:c:0:0:0) ++rc=$? ++if [ "$rc" -eq 1 ] ++then ++ if [ "$reply" != "$vsi_ok" ] ++ then ++ echo "vdptool reply mismatch" ++ echo "expected reply:$vsi_ok" ++ echo "returned reply:$reply" ++ else ++ let rc=0 ++ fi ++else ++ echo "vdptool unexpected success" ++ let rc=1 ++fi ++ ++sleep 5 ++exit $rc +diff --git a/test/qbg22/vdp22/304.vdp b/test/qbg22/vdp22/304.vdp +new file mode 100644 +index 0000000..0c7e96a +--- /dev/null ++++ b/test/qbg22/vdp22/304.vdp +@@ -0,0 +1,55 @@ ++# ++# Test case for LLDPAD testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# Configuration file for lldpad bridge mode setup. ++ ++dcbx : ++{ ++ version = "1.0"; ++ dcbx_version = 2; ++}; ++nearest_customer_bridge : ++{ ++ veth2 : ++ { ++ tlvid00000001 : ++ { ++ info = "04C68829509676"; ++ }; ++ tlvid00000002 : ++ { ++ info = "03C68829509676"; ++ }; ++ adminStatus = 3; ++ tlvid0080c20d : ++ { ++ enableTx = true; ++ evbmode = "bridge"; ++ evbrrcap = true; ++ evbrrreq = true; ++ evbgpid = false; ++ ecpretries = 3; ++ ecprte = 14; ++ vdprwd = 20; ++ vdprka = 20; ++ }; ++ }; ++}; +diff --git a/test/qbg22/vdp22/305-lldpad.conf b/test/qbg22/vdp22/305-lldpad.conf +new file mode 100644 +index 0000000..11ed7a2 +--- /dev/null ++++ b/test/qbg22/vdp22/305-lldpad.conf +@@ -0,0 +1,55 @@ ++# ++# Test case for LLDPAD testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# Configuration file for lldpad station mode setup. ++ ++dcbx : ++{ ++ version = "1.0"; ++ dcbx_version = 2; ++}; ++nearest_customer_bridge : ++{ ++ veth0 : ++ { ++ tlvid00000001 : ++ { ++ info = "04C68829509676"; ++ }; ++ tlvid00000002 : ++ { ++ info = "03C68829509676"; ++ }; ++ adminStatus = 3; ++ tlvid0080c20d : ++ { ++ enableTx = true; ++ evbmode = "station"; ++ evbrrcap = false; ++ evbrrreq = true; ++ evbgpid = false; ++ ecpretries = 3; ++ ecprte = 14; ++ vdprwd = 20; ++ vdprka = 20; ++ }; ++ }; ++}; +diff --git a/test/qbg22/vdp22/305.nlc b/test/qbg22/vdp22/305.nlc +new file mode 100755 +index 0000000..ae951e1 +--- /dev/null ++++ b/test/qbg22/vdp22/305.nlc +@@ -0,0 +1,54 @@ ++#!/bin/bash ++# ++# Test case for LLDPAD VDP testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# ++# Thomas Richter, IBM Research & Development, Boeblingen, Germany, 20-Apr-2013 ++# ++# Execute a simple assoc with wrong user input using vdptool. ++# FID missing ++# ++ ++sleep 30 # Must: Wait some time for lldpad to start up and initialize ++outfile=$(basename $0) ++dirfile=$(dirname $0) ++cd $dirfile ++ ++vsi_ok="Unknown status" ++reply=$(../../../vdptool -i veth0 -T -V deassoc -c vsi=deassoc,hello,1,254,001122334-455667788-99aabbccddee,-) ++rc=$? ++if [ "$rc" -eq 1 ] ++then ++ if [ "$reply" != "$vsi_ok" ] ++ then ++ echo "vdptool reply mismatch" ++ echo "expected reply:$vsi_ok" ++ echo "returned reply:$reply" ++ else ++ let rc=0 ++ fi ++else ++ echo "vdptool unexpected success" ++ let rc=1 ++fi ++ ++sleep 5 ++exit $rc +diff --git a/test/qbg22/vdp22/305.vdp b/test/qbg22/vdp22/305.vdp +new file mode 100644 +index 0000000..0c7e96a +--- /dev/null ++++ b/test/qbg22/vdp22/305.vdp +@@ -0,0 +1,55 @@ ++# ++# Test case for LLDPAD testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# Configuration file for lldpad bridge mode setup. ++ ++dcbx : ++{ ++ version = "1.0"; ++ dcbx_version = 2; ++}; ++nearest_customer_bridge : ++{ ++ veth2 : ++ { ++ tlvid00000001 : ++ { ++ info = "04C68829509676"; ++ }; ++ tlvid00000002 : ++ { ++ info = "03C68829509676"; ++ }; ++ adminStatus = 3; ++ tlvid0080c20d : ++ { ++ enableTx = true; ++ evbmode = "bridge"; ++ evbrrcap = true; ++ evbrrreq = true; ++ evbgpid = false; ++ ecpretries = 3; ++ ecprte = 14; ++ vdprwd = 20; ++ vdprka = 20; ++ }; ++ }; ++}; +diff --git a/test/qbg22/vdp22/306-lldpad.conf b/test/qbg22/vdp22/306-lldpad.conf +new file mode 100644 +index 0000000..11ed7a2 +--- /dev/null ++++ b/test/qbg22/vdp22/306-lldpad.conf +@@ -0,0 +1,55 @@ ++# ++# Test case for LLDPAD testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# Configuration file for lldpad station mode setup. ++ ++dcbx : ++{ ++ version = "1.0"; ++ dcbx_version = 2; ++}; ++nearest_customer_bridge : ++{ ++ veth0 : ++ { ++ tlvid00000001 : ++ { ++ info = "04C68829509676"; ++ }; ++ tlvid00000002 : ++ { ++ info = "03C68829509676"; ++ }; ++ adminStatus = 3; ++ tlvid0080c20d : ++ { ++ enableTx = true; ++ evbmode = "station"; ++ evbrrcap = false; ++ evbrrreq = true; ++ evbgpid = false; ++ ecpretries = 3; ++ ecprte = 14; ++ vdprwd = 20; ++ vdprka = 20; ++ }; ++ }; ++}; +diff --git a/test/qbg22/vdp22/306.nlc b/test/qbg22/vdp22/306.nlc +new file mode 100755 +index 0000000..817a35b +--- /dev/null ++++ b/test/qbg22/vdp22/306.nlc +@@ -0,0 +1,54 @@ ++#!/bin/bash ++# ++# Test case for LLDPAD VDP testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# ++# Thomas Richter, IBM Research & Development, Boeblingen, Germany, 20-Apr-2013 ++# ++# Execute a simple assoc with wrong user input using vdptool. ++# FID bad vlan ++# ++ ++sleep 30 # Must: Wait some time for lldpad to start up and initialize ++outfile=$(basename $0) ++dirfile=$(dirname $0) ++cd $dirfile ++ ++vsi_ok="Invalid parameters" ++reply=$(../../../vdptool -i veth0 -T -V deassoc -c vsi=deassoc,hello,1,253,001122334-455667788-99aabbccddee,-,65536) ++rc=$? ++if [ "$rc" -eq 1 ] ++then ++ if [ "$reply" != "$vsi_ok" ] ++ then ++ echo "vdptool reply mismatch" ++ echo "expected reply:$vsi_ok" ++ echo "returned reply:$reply" ++ else ++ let rc=0 ++ fi ++else ++ echo "vdptool unexpected success" ++ let rc=1 ++fi ++ ++sleep 5 ++exit $rc +diff --git a/test/qbg22/vdp22/306.vdp b/test/qbg22/vdp22/306.vdp +new file mode 100644 +index 0000000..0c7e96a +--- /dev/null ++++ b/test/qbg22/vdp22/306.vdp +@@ -0,0 +1,55 @@ ++# ++# Test case for LLDPAD testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# Configuration file for lldpad bridge mode setup. ++ ++dcbx : ++{ ++ version = "1.0"; ++ dcbx_version = 2; ++}; ++nearest_customer_bridge : ++{ ++ veth2 : ++ { ++ tlvid00000001 : ++ { ++ info = "04C68829509676"; ++ }; ++ tlvid00000002 : ++ { ++ info = "03C68829509676"; ++ }; ++ adminStatus = 3; ++ tlvid0080c20d : ++ { ++ enableTx = true; ++ evbmode = "bridge"; ++ evbrrcap = true; ++ evbrrreq = true; ++ evbgpid = false; ++ ecpretries = 3; ++ ecprte = 14; ++ vdprwd = 20; ++ vdprka = 20; ++ }; ++ }; ++}; +diff --git a/test/qbg22/vdp22/307-lldpad.conf b/test/qbg22/vdp22/307-lldpad.conf +new file mode 100644 +index 0000000..11ed7a2 +--- /dev/null ++++ b/test/qbg22/vdp22/307-lldpad.conf +@@ -0,0 +1,55 @@ ++# ++# Test case for LLDPAD testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# Configuration file for lldpad station mode setup. ++ ++dcbx : ++{ ++ version = "1.0"; ++ dcbx_version = 2; ++}; ++nearest_customer_bridge : ++{ ++ veth0 : ++ { ++ tlvid00000001 : ++ { ++ info = "04C68829509676"; ++ }; ++ tlvid00000002 : ++ { ++ info = "03C68829509676"; ++ }; ++ adminStatus = 3; ++ tlvid0080c20d : ++ { ++ enableTx = true; ++ evbmode = "station"; ++ evbrrcap = false; ++ evbrrreq = true; ++ evbgpid = false; ++ ecpretries = 3; ++ ecprte = 14; ++ vdprwd = 20; ++ vdprka = 20; ++ }; ++ }; ++}; +diff --git a/test/qbg22/vdp22/307.nlc b/test/qbg22/vdp22/307.nlc +new file mode 100755 +index 0000000..d252568 +--- /dev/null ++++ b/test/qbg22/vdp22/307.nlc +@@ -0,0 +1,54 @@ ++#!/bin/bash ++# ++# Test case for LLDPAD VDP testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# ++# Thomas Richter, IBM Research & Development, Boeblingen, Germany, 20-Apr-2013 ++# ++# Execute a simple assoc with wrong user input using vdptool. ++# FID bad mac ++# ++ ++sleep 30 # Must: Wait some time for lldpad to start up and initialize ++outfile=$(basename $0) ++dirfile=$(dirname $0) ++cd $dirfile ++ ++vsi_ok="Invalid parameters" ++reply=$(../../../vdptool -i veth0 -T -V deassoc -c vsi=deassoc,hello,1,253,001122334-455667788-99aabbccddee,-,3-00:11:cc:ddd:e:f) ++rc=$? ++if [ "$rc" -eq 1 ] ++then ++ if [ "$reply" != "$vsi_ok" ] ++ then ++ echo "vdptool reply mismatch" ++ echo "expected reply:$vsi_ok" ++ echo "returned reply:$reply" ++ else ++ let rc=0 ++ fi ++else ++ echo "vdptool unexpected success" ++ let rc=1 ++fi ++ ++sleep 5 ++exit $rc +diff --git a/test/qbg22/vdp22/307.vdp b/test/qbg22/vdp22/307.vdp +new file mode 100644 +index 0000000..0c7e96a +--- /dev/null ++++ b/test/qbg22/vdp22/307.vdp +@@ -0,0 +1,55 @@ ++# ++# Test case for LLDPAD testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# Configuration file for lldpad bridge mode setup. ++ ++dcbx : ++{ ++ version = "1.0"; ++ dcbx_version = 2; ++}; ++nearest_customer_bridge : ++{ ++ veth2 : ++ { ++ tlvid00000001 : ++ { ++ info = "04C68829509676"; ++ }; ++ tlvid00000002 : ++ { ++ info = "03C68829509676"; ++ }; ++ adminStatus = 3; ++ tlvid0080c20d : ++ { ++ enableTx = true; ++ evbmode = "bridge"; ++ evbrrcap = true; ++ evbrrreq = true; ++ evbgpid = false; ++ ecpretries = 3; ++ ecprte = 14; ++ vdprwd = 20; ++ vdprka = 20; ++ }; ++ }; ++}; +diff --git a/test/qbg22/vdp22/308-lldpad.conf b/test/qbg22/vdp22/308-lldpad.conf +new file mode 100644 +index 0000000..11ed7a2 +--- /dev/null ++++ b/test/qbg22/vdp22/308-lldpad.conf +@@ -0,0 +1,55 @@ ++# ++# Test case for LLDPAD testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# Configuration file for lldpad station mode setup. ++ ++dcbx : ++{ ++ version = "1.0"; ++ dcbx_version = 2; ++}; ++nearest_customer_bridge : ++{ ++ veth0 : ++ { ++ tlvid00000001 : ++ { ++ info = "04C68829509676"; ++ }; ++ tlvid00000002 : ++ { ++ info = "03C68829509676"; ++ }; ++ adminStatus = 3; ++ tlvid0080c20d : ++ { ++ enableTx = true; ++ evbmode = "station"; ++ evbrrcap = false; ++ evbrrreq = true; ++ evbgpid = false; ++ ecpretries = 3; ++ ecprte = 14; ++ vdprwd = 20; ++ vdprka = 20; ++ }; ++ }; ++}; +diff --git a/test/qbg22/vdp22/308.nlc b/test/qbg22/vdp22/308.nlc +new file mode 100755 +index 0000000..9ab72bc +--- /dev/null ++++ b/test/qbg22/vdp22/308.nlc +@@ -0,0 +1,54 @@ ++#!/bin/bash ++# ++# Test case for LLDPAD VDP testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# ++# Thomas Richter, IBM Research & Development, Boeblingen, Germany, 20-Apr-2013 ++# ++# Execute a simple assoc with wrong user input using vdptool. ++# FID format vlan-mac and mac ++# ++ ++sleep 30 # Must: Wait some time for lldpad to start up and initialize ++outfile=$(basename $0) ++dirfile=$(dirname $0) ++cd $dirfile ++ ++vsi_ok="Invalid parameters" ++reply=$(../../../vdptool -i veth0 -T -V preassoc -c vsi=preassoc,hello,1,253,001122334-455667788-99aabbccddee,-,3-00:11:cc:d:e:f,4444) ++rc=$? ++if [ "$rc" -eq 1 ] ++then ++ if [ "$reply" != "$vsi_ok" ] ++ then ++ echo "vdptool reply mismatch" ++ echo "expected reply:$vsi_ok" ++ echo "returned reply:$reply" ++ else ++ let rc=0 ++ fi ++else ++ echo "vdptool unexpected success" ++ let rc=1 ++fi ++ ++sleep 5 ++exit $rc +diff --git a/test/qbg22/vdp22/308.vdp b/test/qbg22/vdp22/308.vdp +new file mode 100644 +index 0000000..0c7e96a +--- /dev/null ++++ b/test/qbg22/vdp22/308.vdp +@@ -0,0 +1,55 @@ ++# ++# Test case for LLDPAD testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# Configuration file for lldpad bridge mode setup. ++ ++dcbx : ++{ ++ version = "1.0"; ++ dcbx_version = 2; ++}; ++nearest_customer_bridge : ++{ ++ veth2 : ++ { ++ tlvid00000001 : ++ { ++ info = "04C68829509676"; ++ }; ++ tlvid00000002 : ++ { ++ info = "03C68829509676"; ++ }; ++ adminStatus = 3; ++ tlvid0080c20d : ++ { ++ enableTx = true; ++ evbmode = "bridge"; ++ evbrrcap = true; ++ evbrrreq = true; ++ evbgpid = false; ++ ecpretries = 3; ++ ecprte = 14; ++ vdprwd = 20; ++ vdprka = 20; ++ }; ++ }; ++}; +diff --git a/test/qbg22/vdp22/309-lldpad.conf b/test/qbg22/vdp22/309-lldpad.conf +new file mode 100644 +index 0000000..11ed7a2 +--- /dev/null ++++ b/test/qbg22/vdp22/309-lldpad.conf +@@ -0,0 +1,55 @@ ++# ++# Test case for LLDPAD testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# Configuration file for lldpad station mode setup. ++ ++dcbx : ++{ ++ version = "1.0"; ++ dcbx_version = 2; ++}; ++nearest_customer_bridge : ++{ ++ veth0 : ++ { ++ tlvid00000001 : ++ { ++ info = "04C68829509676"; ++ }; ++ tlvid00000002 : ++ { ++ info = "03C68829509676"; ++ }; ++ adminStatus = 3; ++ tlvid0080c20d : ++ { ++ enableTx = true; ++ evbmode = "station"; ++ evbrrcap = false; ++ evbrrreq = true; ++ evbgpid = false; ++ ecpretries = 3; ++ ecprte = 14; ++ vdprwd = 20; ++ vdprka = 20; ++ }; ++ }; ++}; +diff --git a/test/qbg22/vdp22/309.nlc b/test/qbg22/vdp22/309.nlc +new file mode 100755 +index 0000000..8de0f86 +--- /dev/null ++++ b/test/qbg22/vdp22/309.nlc +@@ -0,0 +1,54 @@ ++#!/bin/bash ++# ++# Test case for LLDPAD VDP testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# ++# Thomas Richter, IBM Research & Development, Boeblingen, Germany, 20-Apr-2013 ++# ++# Execute a simple assoc with wrong user input using vdptool. ++# FID bad group ++# ++ ++sleep 30 # Must: Wait some time for lldpad to start up and initialize ++outfile=$(basename $0) ++dirfile=$(dirname $0) ++cd $dirfile ++ ++vsi_ok="Invalid parameters" ++reply=$(../../../vdptool -i veth0 -T -V preassoc -c vsi=preassoc,hello,1,253,001122334-455667788-99aabbccddee,-,333-00:11:cc:d:e:f-44a44) ++rc=$? ++if [ "$rc" -eq 1 ] ++then ++ if [ "$reply" != "$vsi_ok" ] ++ then ++ echo "vdptool reply mismatch" ++ echo "expected reply:$vsi_ok" ++ echo "returned reply:$reply" ++ else ++ let rc=0 ++ fi ++else ++ echo "vdptool unexpected success" ++ let rc=1 ++fi ++ ++sleep 5 ++exit $rc +diff --git a/test/qbg22/vdp22/309.vdp b/test/qbg22/vdp22/309.vdp +new file mode 100644 +index 0000000..0c7e96a +--- /dev/null ++++ b/test/qbg22/vdp22/309.vdp +@@ -0,0 +1,55 @@ ++# ++# Test case for LLDPAD testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# Configuration file for lldpad bridge mode setup. ++ ++dcbx : ++{ ++ version = "1.0"; ++ dcbx_version = 2; ++}; ++nearest_customer_bridge : ++{ ++ veth2 : ++ { ++ tlvid00000001 : ++ { ++ info = "04C68829509676"; ++ }; ++ tlvid00000002 : ++ { ++ info = "03C68829509676"; ++ }; ++ adminStatus = 3; ++ tlvid0080c20d : ++ { ++ enableTx = true; ++ evbmode = "bridge"; ++ evbrrcap = true; ++ evbrrreq = true; ++ evbgpid = false; ++ ecpretries = 3; ++ ecprte = 14; ++ vdprwd = 20; ++ vdprka = 20; ++ }; ++ }; ++}; +diff --git a/test/qbg22/vdp22/310-lldpad.conf b/test/qbg22/vdp22/310-lldpad.conf +new file mode 100644 +index 0000000..11ed7a2 +--- /dev/null ++++ b/test/qbg22/vdp22/310-lldpad.conf +@@ -0,0 +1,55 @@ ++# ++# Test case for LLDPAD testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# Configuration file for lldpad station mode setup. ++ ++dcbx : ++{ ++ version = "1.0"; ++ dcbx_version = 2; ++}; ++nearest_customer_bridge : ++{ ++ veth0 : ++ { ++ tlvid00000001 : ++ { ++ info = "04C68829509676"; ++ }; ++ tlvid00000002 : ++ { ++ info = "03C68829509676"; ++ }; ++ adminStatus = 3; ++ tlvid0080c20d : ++ { ++ enableTx = true; ++ evbmode = "station"; ++ evbrrcap = false; ++ evbrrreq = true; ++ evbgpid = false; ++ ecpretries = 3; ++ ecprte = 14; ++ vdprwd = 20; ++ vdprka = 20; ++ }; ++ }; ++}; +diff --git a/test/qbg22/vdp22/310.nlc b/test/qbg22/vdp22/310.nlc +new file mode 100755 +index 0000000..ae90509 +--- /dev/null ++++ b/test/qbg22/vdp22/310.nlc +@@ -0,0 +1,54 @@ ++#!/bin/bash ++# ++# Test case for LLDPAD VDP testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# ++# Thomas Richter, IBM Research & Development, Boeblingen, Germany, 20-Apr-2013 ++# ++# Execute a simple assoc with wrong user input using vdptool. ++# FID same mac several times ++# ++ ++sleep 30 # Must: Wait some time for lldpad to start up and initialize ++outfile=$(basename $0) ++dirfile=$(dirname $0) ++cd $dirfile ++ ++vsi_ok="Invalid parameters" ++reply=$(../../../vdptool -i veth0 -T -V preassoc -c vsi=preassoc,hello,1,253,001122334-455667788-99aabbccddee,-,333-00:11:cc:d:e:f-44444,222-00:11:cc:d:e:f-44444) ++rc=$? ++if [ "$rc" -eq 1 ] ++then ++ if [ "$reply" != "$vsi_ok" ] ++ then ++ echo "vdptool reply mismatch" ++ echo "expected reply:$vsi_ok" ++ echo "returned reply:$reply" ++ else ++ let rc=0 ++ fi ++else ++ echo "vdptool unexpected success" ++ let rc=1 ++fi ++ ++sleep 5 ++exit $rc +diff --git a/test/qbg22/vdp22/310.vdp b/test/qbg22/vdp22/310.vdp +new file mode 100644 +index 0000000..0c7e96a +--- /dev/null ++++ b/test/qbg22/vdp22/310.vdp +@@ -0,0 +1,55 @@ ++# ++# Test case for LLDPAD testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# Configuration file for lldpad bridge mode setup. ++ ++dcbx : ++{ ++ version = "1.0"; ++ dcbx_version = 2; ++}; ++nearest_customer_bridge : ++{ ++ veth2 : ++ { ++ tlvid00000001 : ++ { ++ info = "04C68829509676"; ++ }; ++ tlvid00000002 : ++ { ++ info = "03C68829509676"; ++ }; ++ adminStatus = 3; ++ tlvid0080c20d : ++ { ++ enableTx = true; ++ evbmode = "bridge"; ++ evbrrcap = true; ++ evbrrreq = true; ++ evbgpid = false; ++ ecpretries = 3; ++ ecprte = 14; ++ vdprwd = 20; ++ vdprka = 20; ++ }; ++ }; ++}; +diff --git a/test/qbg22/vdp22/320-lldpad.conf b/test/qbg22/vdp22/320-lldpad.conf +new file mode 100644 +index 0000000..11ed7a2 +--- /dev/null ++++ b/test/qbg22/vdp22/320-lldpad.conf +@@ -0,0 +1,55 @@ ++# ++# Test case for LLDPAD testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# Configuration file for lldpad station mode setup. ++ ++dcbx : ++{ ++ version = "1.0"; ++ dcbx_version = 2; ++}; ++nearest_customer_bridge : ++{ ++ veth0 : ++ { ++ tlvid00000001 : ++ { ++ info = "04C68829509676"; ++ }; ++ tlvid00000002 : ++ { ++ info = "03C68829509676"; ++ }; ++ adminStatus = 3; ++ tlvid0080c20d : ++ { ++ enableTx = true; ++ evbmode = "station"; ++ evbrrcap = false; ++ evbrrreq = true; ++ evbgpid = false; ++ ecpretries = 3; ++ ecprte = 14; ++ vdprwd = 20; ++ vdprka = 20; ++ }; ++ }; ++}; +diff --git a/test/qbg22/vdp22/320.nlc b/test/qbg22/vdp22/320.nlc +new file mode 100755 +index 0000000..2dca2c2 +--- /dev/null ++++ b/test/qbg22/vdp22/320.nlc +@@ -0,0 +1,65 @@ ++#!/bin/bash ++# ++# Test case for LLDPAD VDP testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# ++# Thomas Richter, IBM Research & Development, Boeblingen, Germany, 20-Apr-2013 ++# ++# Execute a simple assoc input using vdptool. Expect success. ++# ++ ++sleep 30 # Must: Wait some time for lldpad to start up and initialize ++outfile=$(basename $0) ++dirfile=$(dirname $0) ++cd $dirfile ++ ++vsi1="assoc,hello,1,2,00112233-4455-6677-8899-aabbccddeeff" ++vsi2="22222-0a:0b:0c:00:00:00" ++vsi_cmd="$vsi1,none,$vsi2" ++vsi_ok="vsi=$vsi1,0,$vsi2;" ++ ++../../../vdptool -i veth0 -T -V assoc -c vsi=$vsi_cmd ++rc=$? ++if [ "$rc" -ne 0 ] ++then ++ echo "vdptool failure (step 1)" ++ exit $rc ++fi ++ ++sleep 30 ++reply="$(../../../vdptool -i veth0 -t -V assoc -c vsi)" ++rc=$? ++if [ "$rc" -ne 0 ] ++then ++ echo "vdptool failure (step 2)" ++ exit $rc ++fi ++ ++if [ "$reply" != "$vsi_ok" ] ++then ++ echo "vdptool reply mismatch" ++ echo "expected reply:$vsi_ok" ++ echo "returned reply:$reply" ++ let rc=1 ++fi ++ ++sleep 5 ++exit $rc +diff --git a/test/qbg22/vdp22/320.vdp b/test/qbg22/vdp22/320.vdp +new file mode 100644 +index 0000000..0c7e96a +--- /dev/null ++++ b/test/qbg22/vdp22/320.vdp +@@ -0,0 +1,55 @@ ++# ++# Test case for LLDPAD testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# Configuration file for lldpad bridge mode setup. ++ ++dcbx : ++{ ++ version = "1.0"; ++ dcbx_version = 2; ++}; ++nearest_customer_bridge : ++{ ++ veth2 : ++ { ++ tlvid00000001 : ++ { ++ info = "04C68829509676"; ++ }; ++ tlvid00000002 : ++ { ++ info = "03C68829509676"; ++ }; ++ adminStatus = 3; ++ tlvid0080c20d : ++ { ++ enableTx = true; ++ evbmode = "bridge"; ++ evbrrcap = true; ++ evbrrreq = true; ++ evbgpid = false; ++ ecpretries = 3; ++ ecprte = 14; ++ vdprwd = 20; ++ vdprka = 20; ++ }; ++ }; ++}; +diff --git a/test/qbg22/vdp22/321-lldpad.conf b/test/qbg22/vdp22/321-lldpad.conf +new file mode 100644 +index 0000000..11ed7a2 +--- /dev/null ++++ b/test/qbg22/vdp22/321-lldpad.conf +@@ -0,0 +1,55 @@ ++# ++# Test case for LLDPAD testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# Configuration file for lldpad station mode setup. ++ ++dcbx : ++{ ++ version = "1.0"; ++ dcbx_version = 2; ++}; ++nearest_customer_bridge : ++{ ++ veth0 : ++ { ++ tlvid00000001 : ++ { ++ info = "04C68829509676"; ++ }; ++ tlvid00000002 : ++ { ++ info = "03C68829509676"; ++ }; ++ adminStatus = 3; ++ tlvid0080c20d : ++ { ++ enableTx = true; ++ evbmode = "station"; ++ evbrrcap = false; ++ evbrrreq = true; ++ evbgpid = false; ++ ecpretries = 3; ++ ecprte = 14; ++ vdprwd = 20; ++ vdprka = 20; ++ }; ++ }; ++}; +diff --git a/test/qbg22/vdp22/321.nlc b/test/qbg22/vdp22/321.nlc +new file mode 100755 +index 0000000..1d5247a +--- /dev/null ++++ b/test/qbg22/vdp22/321.nlc +@@ -0,0 +1,78 @@ ++#!/bin/bash ++# ++# Test case for LLDPAD VDP testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# ++# Thomas Richter, IBM Research & Development, Boeblingen, Germany, 20-Apr-2013 ++# ++# Execute two simple assoc input via vdptool. Expect success. ++# ++ ++sleep 30 # Must: Wait some time for lldpad to start up and initialize ++outfile=$(basename $0) ++dirfile=$(dirname $0) ++cd $dirfile ++ ++vsi1="assoc,hello,1,2,00112233-4455-6677-8899-aabbccddeeff" ++vsi2="22222-0a:0b:0c:00:00:00" ++vsi_cmd="$vsi1,none,$vsi2" ++vsi_ok="$vsi1,0,$vsi2;" ++vsi1b="assoc,world,1,2,00112233-4455-6677-8899-ffeeddccbbaa" ++vsi2b="2-aa:bb:cc:00:00:00" ++vsib_cmd="$vsi1b,none,$vsi2b" ++vsib_ok="$vsi1b,0,$vsi2b;" ++ ++../../../vdptool -i veth0 -T -V assoc -c vsi=$vsi_cmd ++rc=$? ++if [ "$rc" -ne 0 ] ++then ++ echo "vdptool failure (step 1)" ++ exit $rc ++fi ++ ++sleep 30 ++../../../vdptool -i veth0 -T -V assoc -c vsi=$vsib_cmd ++rc=$? ++if [ "$rc" -ne 0 ] ++then ++ echo "vdptool failure (step 2)" ++ exit $rc ++fi ++ ++sleep 30 ++reply="$(../../../vdptool -i veth0 -t -V assoc -c vsi)" ++rc=$? ++if [ "$rc" -ne 0 ] ++then ++ echo "vdptool failure (step 3)" ++ exit $rc ++fi ++ ++if [ "$reply" != "vsi=$vsib_ok$vsi_ok" ] ++then ++ echo "vdptool reply mismatch" ++ echo "expected reply:vsi=$vsib_ok$vsi_ok" ++ echo "returned reply:$reply" ++ let rc=1 ++fi ++ ++sleep 5 ++exit $rc +diff --git a/test/qbg22/vdp22/321.vdp b/test/qbg22/vdp22/321.vdp +new file mode 100644 +index 0000000..0c7e96a +--- /dev/null ++++ b/test/qbg22/vdp22/321.vdp +@@ -0,0 +1,55 @@ ++# ++# Test case for LLDPAD testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# Configuration file for lldpad bridge mode setup. ++ ++dcbx : ++{ ++ version = "1.0"; ++ dcbx_version = 2; ++}; ++nearest_customer_bridge : ++{ ++ veth2 : ++ { ++ tlvid00000001 : ++ { ++ info = "04C68829509676"; ++ }; ++ tlvid00000002 : ++ { ++ info = "03C68829509676"; ++ }; ++ adminStatus = 3; ++ tlvid0080c20d : ++ { ++ enableTx = true; ++ evbmode = "bridge"; ++ evbrrcap = true; ++ evbrrreq = true; ++ evbgpid = false; ++ ecpretries = 3; ++ ecprte = 14; ++ vdprwd = 20; ++ vdprka = 20; ++ }; ++ }; ++}; +diff --git a/test/qbg22/vdp22/322-lldpad.conf b/test/qbg22/vdp22/322-lldpad.conf +new file mode 100644 +index 0000000..11ed7a2 +--- /dev/null ++++ b/test/qbg22/vdp22/322-lldpad.conf +@@ -0,0 +1,55 @@ ++# ++# Test case for LLDPAD testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# Configuration file for lldpad station mode setup. ++ ++dcbx : ++{ ++ version = "1.0"; ++ dcbx_version = 2; ++}; ++nearest_customer_bridge : ++{ ++ veth0 : ++ { ++ tlvid00000001 : ++ { ++ info = "04C68829509676"; ++ }; ++ tlvid00000002 : ++ { ++ info = "03C68829509676"; ++ }; ++ adminStatus = 3; ++ tlvid0080c20d : ++ { ++ enableTx = true; ++ evbmode = "station"; ++ evbrrcap = false; ++ evbrrreq = true; ++ evbgpid = false; ++ ecpretries = 3; ++ ecprte = 14; ++ vdprwd = 20; ++ vdprka = 20; ++ }; ++ }; ++}; +diff --git a/test/qbg22/vdp22/322.nlc b/test/qbg22/vdp22/322.nlc +new file mode 100755 +index 0000000..5b5840e +--- /dev/null ++++ b/test/qbg22/vdp22/322.nlc +@@ -0,0 +1,95 @@ ++#!/bin/bash ++# ++# Test case for LLDPAD VDP testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# ++# Thomas Richter, IBM Research & Development, Boeblingen, Germany, 20-Apr-2013 ++# ++# Execute assoc/preassoc input via vdptool. Expect success. ++# ++ ++sleep 30 # Must: Wait some time for lldpad to start up and initialize ++outfile=$(basename $0) ++dirfile=$(dirname $0) ++cd $dirfile ++ ++vsi1="assoc,hello,1,2,00112233-4455-6677-8899-aabbccddeeff" ++vsi2="22222-0a:0b:0c:00:00:00" ++vsi_cmd="$vsi1,none,$vsi2" ++vsi_ok="$vsi1,0,$vsi2;" ++vsi1b="preassoc,world,1,2,00112233-4455-6677-8899-ffeeddccbbaa" ++vsi2b="2-aa:bb:cc:00:00:00" ++vsib_cmd="$vsi1b,none,$vsi2b" ++vsib_ok="$vsi1b,0,$vsi2b;" ++ ++../../../vdptool -i veth0 -T -V assoc -c vsi=$vsi_cmd ++rc=$? ++if [ "$rc" -ne 0 ] ++then ++ echo "vdptool failure (step 1)" ++ exit $rc ++fi ++ ++sleep 30 ++../../../vdptool -i veth0 -T -V preassoc -c vsi=$vsib_cmd ++rc=$? ++if [ "$rc" -ne 0 ] ++then ++ echo "vdptool failure (step 2)" ++ exit $rc ++fi ++ ++sleep 30 ++reply="$(../../../vdptool -i veth0 -t -V assoc -c vsi)" ++rc=$? ++if [ "$rc" -ne 0 ] ++then ++ echo "vdptool failure (step 3)" ++ exit $rc ++fi ++ ++if [ "$reply" != "vsi=$vsi_ok" ] ++then ++ echo "vdptool reply mismatch (step 3)" ++ echo "expected reply:vsi=$vsi_ok" ++ echo "returned reply:$reply" ++ exit 6 ++fi ++ ++sleep 5 ++reply="$(../../../vdptool -i veth0 -t -V preassoc -c vsi)" ++rc=$? ++if [ "$rc" -ne 0 ] ++then ++ echo "vdptool failure (step 4)" ++ exit $rc ++fi ++ ++if [ "$reply" != "vsi=$vsib_ok" ] ++then ++ echo "vdptool reply mismatch (step 4)" ++ echo "expected reply:vsi=$vsib_ok" ++ echo "returned reply:$reply" ++ let rc=1 ++fi ++ ++sleep 5 ++exit $rc +diff --git a/test/qbg22/vdp22/322.vdp b/test/qbg22/vdp22/322.vdp +new file mode 100644 +index 0000000..0c7e96a +--- /dev/null ++++ b/test/qbg22/vdp22/322.vdp +@@ -0,0 +1,55 @@ ++# ++# Test case for LLDPAD testing according to IEEE 802.1Qbg ratified standard ++# ++# Copyright (c) International Business Machines Corp., 2014 ++# ++# Author(s): Thomas Richter ++# ++# 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. ++# ++ ++# Configuration file for lldpad bridge mode setup. ++ ++dcbx : ++{ ++ version = "1.0"; ++ dcbx_version = 2; ++}; ++nearest_customer_bridge : ++{ ++ veth2 : ++ { ++ tlvid00000001 : ++ { ++ info = "04C68829509676"; ++ }; ++ tlvid00000002 : ++ { ++ info = "03C68829509676"; ++ }; ++ adminStatus = 3; ++ tlvid0080c20d : ++ { ++ enableTx = true; ++ evbmode = "bridge"; ++ evbrrcap = true; ++ evbrrreq = true; ++ evbgpid = false; ++ ecpretries = 3; ++ ecprte = 14; ++ vdprwd = 20; ++ vdprka = 20; ++ }; ++ }; ++}; +-- +2.1.0 + diff --git a/SOURCES/open-lldp-v1.0.1-4-VDP-Changes-to-make-the-interface-to-VDP22-in-lldpad.patch b/SOURCES/open-lldp-v1.0.1-4-VDP-Changes-to-make-the-interface-to-VDP22-in-lldpad.patch new file mode 100644 index 0000000..341acd8 --- /dev/null +++ b/SOURCES/open-lldp-v1.0.1-4-VDP-Changes-to-make-the-interface-to-VDP22-in-lldpad.patch @@ -0,0 +1,593 @@ +From e3f6d0eab95ef6b7336aaea2f44ecb79ead4216d Mon Sep 17 00:00:00 2001 +From: padkrish +Date: Wed, 21 Jan 2015 03:37:09 +0000 +Subject: [PATCH] VDP: Changes to make the interface to VDP22 (in lldpad) as + TLV + +Changes to make the interface to VDP22 (in lldpad) as len, key, len, +value, which is in sync with other modules of lldpad. + +Currently, the VSI parameters of VDP22 to LLDPAD are comma separated. +This patch has changes to have VSI Parameters being given to VDP22 as +Keyword_len followed by Keyword followed by value_len followed by +value. vdptool is also modified to reflect the same. This is +synchronous with other interface of lldpad like lldptool. + +As an example, if vdptool is invoked as: + +"vdptool -i eth2 -T -S -V assoc -c mode=assoc -c mgrid2=0 \ + -c typeid=0 -c typeidver=0 -c uuid=00000000-3333-2222-888a-aabbccddee72 \ + -c hints=none -c filter=0-00:00:00:11:22:72-90001", + +the input to lldpad will be: + +"M000080c4C3020000011c04eth2020000000304mode0005assoc06mgrid20001006typeid0001009typeidver0001004uuid002400000000-3333-2222-888a-aabbccddee7205hints0004none06filter00190-00:00:00:11:22:72-90001" + +Another option is also added to vdptool to wait and print the response +from the bridge. + +Signed-off-by: padkrish +--- + include/qbg_vdp22.h | 5 ++ + include/qbg_vdp22_clif.h | 7 +++ + include/qbg_vdp22def.h | 24 ++++++++ + qbg/vdp22_cmds.c | 125 +++++++------------------------------- + qbg/vdp_ascii.c | 152 +++++++++++++++++++++++++++++++---------------- + vdptool.c | 53 +++++++++++------ + 6 files changed, 193 insertions(+), 173 deletions(-) + +diff --git a/include/qbg_vdp22.h b/include/qbg_vdp22.h +index b345602..45f44d5 100644 +--- a/include/qbg_vdp22.h ++++ b/include/qbg_vdp22.h +@@ -163,6 +163,11 @@ struct vdp22_user_data { /* Head for all VDP data */ + LIST_HEAD(vdp22_head, vdp22) head; + }; + ++struct vsi_keyword_handler { ++ char *keyword; ++ enum vsi_mand_arg val; ++}; ++ + struct lldp_module *vdp22_register(void); + void vdp22_unregister(struct lldp_module *); + void vdp22_start(const char *, int); +diff --git a/include/qbg_vdp22_clif.h b/include/qbg_vdp22_clif.h +index 008022a..8346b98 100644 +--- a/include/qbg_vdp22_clif.h ++++ b/include/qbg_vdp22_clif.h +@@ -29,6 +29,10 @@ + + #ifndef QBG_VDP22_CLIF_H + #define QBG_VDP22_CLIF_H ++ ++#define OP_FID_POS 8 /* Second Byte */ ++#define OP_OUI_POS 16 /* Third Byte */ ++ + typedef enum { + cmd_getstats, + cmd_gettlv, +@@ -51,6 +55,9 @@ typedef enum { + op_config = 0x10, + op_delete = 0x20, + op_key = 0x40 ++ /* Second Byte is used for signifying the number of Filter fields and ++ * the third byte is used for signifying the number of OUI fields. ++ */ + } vdp22_op; + + struct lldp_module *vdp22_cli_register(void); +diff --git a/include/qbg_vdp22def.h b/include/qbg_vdp22def.h +index 52f4502..21ba15d 100644 +--- a/include/qbg_vdp22def.h ++++ b/include/qbg_vdp22def.h +@@ -72,4 +72,28 @@ enum vdp22_migration_hints { + VDP22_MIGFROM = 32 /* S-bit migrate from hint */ + }; + ++enum vsi_mand_arg { ++ VSI_MODE_ARG = 0, ++ VSI_MGRID2_ARG, ++ VSI_TYPEID_ARG, ++ VSI_TYPEIDVER_ARG, ++/* VSI_VSIIDFRMT_ARG, TODO */ ++ VSI_VSIID_ARG, ++ VSI_FILTER_ARG, ++ VSI_MAND_NUM_ARG, ++ VSI_HINTS_ARG, ++ VSI_INVALID_ARG ++}; ++ ++#define VSI22_ARG_MODE_STR "mode" ++#define VSI22_ARG_MGRID_STR "mgrid2" ++#define VSI22_ARG_TYPEID_STR "typeid" ++#define VSI22_ARG_TYPEIDVER_STR "typeidver" ++#define VSI22_ARG_VSIIDFRMT_STR "vsiidfrmt" ++/*#define VSI22_ARG_VSIID_STR "vsiid" TODO*/ ++#define VSI22_ARG_VSIID_STR "uuid" ++#define VSI22_ARG_HINTS_STR "hints" ++#define VSI22_ARG_FILTER_STR "filter" ++#define VSI22_ARG_OUI_STR "oui" ++ + #endif +diff --git a/qbg/vdp22_cmds.c b/qbg/vdp22_cmds.c +index f055441..dde4669 100644 +--- a/qbg/vdp22_cmds.c ++++ b/qbg/vdp22_cmds.c +@@ -104,37 +104,6 @@ static int handle_get_arg(struct cmd *cmd, char *arg, char *argvalue, + return status; + } + +-static int handle_get(struct cmd *cmd, UNUSED char *arg, char *argvalue, +- char *obuf, int obuf_len) +-{ +- struct arg_handlers *ah; +- int rval; +- char *nbuf; +- int nbuf_len; +- +- memset(obuf, 0, obuf_len); +- nbuf = obuf + 12; +- nbuf_len = obuf_len - 12; +- +- ah = get_my_arghndl(cmd->module_id); +- if (!ah) +- return cmd_not_applicable; +- for (; ah->arg; ++ah) { +- if (strcmp(ah->arg, ARG_VDP22_VSI)) +- continue; +- if (ah->handle_get && (ah->arg_class == TLV_ARG)) { +- rval = ah->handle_get(cmd, ah->arg, argvalue, +- nbuf, nbuf_len); +- if (rval != cmd_success && rval != cmd_not_applicable) +- return rval; +- +- nbuf_len -= strlen(nbuf); +- nbuf = nbuf + strlen(nbuf); +- } +- } +- return cmd_success; +-} +- + static int handle_test_arg(struct cmd *cmd, char *arg, char *argvalue, + char *obuf, int obuf_len) + { +@@ -223,17 +192,13 @@ static int handle_set_arg(struct cmd *cmd, char *arg, char *argvalue, + */ + int vdp22_clif_cmd(UNUSED void *data, UNUSED struct sockaddr_un *from, + UNUSED socklen_t fromlen, +- char *ibuf, int ilen, char *rbuf, int rlen) ++ char *ibuf, UNUSED int ilen, char *rbuf, int rlen) + { + struct cmd cmd; + u8 len, version; + int ioff, roff; + int rstatus = cmd_invalid; +- char **args; +- char **argvals; + bool test_failed = false; +- int numargs = 0; +- int i, offset; + + memset(&cmd, 0, sizeof(cmd)); + cmd.module_id = LLDP_MOD_VDP22; +@@ -275,32 +240,6 @@ int vdp22_clif_cmd(UNUSED void *data, UNUSED struct sockaddr_un *from, + if (!(cmd.ops & op_config)) + return cmd_invalid; + +- /* Count args and argvalues */ +- offset = ioff; +- for (numargs = 0; (ilen - offset) > 2; numargs++) { +- offset += 2; +- if (ilen - offset > 0) { +- offset++; +- if (ilen - offset > 4) +- offset += 4; +- } +- } +- +- args = calloc(numargs, sizeof(char *)); +- if (!args) +- return cmd_failed; +- +- argvals = calloc(numargs, sizeof(char *)); +- if (!argvals) { +- free(args); +- return cmd_failed; +- } +- +- if ((cmd.ops & op_arg) && (cmd.ops & op_argval)) +- numargs = get_arg_val_list(ibuf, ilen, &ioff, args, argvals); +- else if (cmd.ops & op_arg) +- numargs = get_arg_list(ibuf, ilen, &ioff, args); +- + snprintf(rbuf, rlen, "%c%1x%02x%08x%02x%s", + CMD_REQUEST, CLIF_MSG_VERSION, + cmd.cmd, cmd.ops, +@@ -309,42 +248,29 @@ int vdp22_clif_cmd(UNUSED void *data, UNUSED struct sockaddr_un *from, + + /* Confirm port is a valid LLDP port */ + if (!get_ifidx(cmd.ifname) || !is_valid_lldp_device(cmd.ifname)) { +- free(argvals); +- free(args); + return cmd_device_not_found; + } + + snprintf(rbuf + roff, rlen - roff, "%08x", cmd.tlvid); + roff += 8; + if (cmd.cmd == cmd_gettlv) { +- if (!numargs) +- rstatus = handle_get(&cmd, NULL, NULL, +- rbuf + strlen(rbuf), +- rlen - strlen(rbuf)); +- else +- for (i = 0; i < numargs; i++) +- rstatus = handle_get_arg(&cmd, args[i], NULL, +- rbuf + strlen(rbuf), +- rlen - strlen(rbuf)); ++ rstatus = handle_get_arg(&cmd, ARG_VDP22_VSI, ++ NULL, ++ rbuf + strlen(rbuf), ++ rlen - strlen(rbuf)); + } else { +- for (i = 0; i < numargs; i++) { +- rstatus = handle_test_arg(&cmd, args[i], argvals[i], +- rbuf + strlen(rbuf), +- rlen - strlen(rbuf)); +- if (rstatus != cmd_not_applicable && +- rstatus != cmd_success) +- test_failed = true; +- } ++ rstatus = handle_test_arg(&cmd, ARG_VDP22_VSI, ++ ibuf + ioff, ++ rbuf + strlen(rbuf), ++ rlen - strlen(rbuf)); ++ if (rstatus != cmd_not_applicable && rstatus != cmd_success) ++ test_failed = true; + if (!test_failed) +- for (i = 0; i < numargs; i++) +- rstatus = handle_set_arg(&cmd, args[i], +- argvals[i], +- rbuf + strlen(rbuf), +- rlen - strlen(rbuf)); ++ rstatus = handle_set_arg(&cmd, ++ ARG_VDP22_VSI, ibuf + ioff, ++ rbuf + strlen(rbuf), ++ rlen - strlen(rbuf)); + } +- +- free(argvals); +- free(args); + return rstatus; + } + +@@ -436,27 +362,16 @@ out: + return good_cmd; + } + +-/* +- * Count the number of fid data fields in the argument value. +- */ +-#define VDP22_FID_IDX 6 /* Min index of fid data */ +-static int count_fid(char *argvalue) +-{ +- char *p = argvalue; +- int i; +- +- for (i = 0; (p = strchr(p, ',')); ++i, ++p) +- ; +- return i + 1 - VDP22_FID_IDX; +-} +- + static int set_arg_vsi2(struct cmd *cmd, char *argvalue, bool test) + { +- int no = count_fid(argvalue); ++ int no = (cmd->ops >> OP_FID_POS) & 0xff; + + if (no <= 0) + return -EINVAL; +- return set_arg_vsi3(cmd, argvalue, test, no); ++ if ((cmd->ops & op_arg) && (cmd->ops & op_argval)) ++ return set_arg_vsi3(cmd, argvalue, test, no); ++ else /* Not supported for now */ ++ return cmd_failed; + } + + static int set_arg_vsi(struct cmd *cmd, UNUSED char *arg, char *argvalue, +diff --git a/qbg/vdp_ascii.c b/qbg/vdp_ascii.c +index 0ace562..09e53c6 100644 +--- a/qbg/vdp_ascii.c ++++ b/qbg/vdp_ascii.c +@@ -43,6 +43,17 @@ + #include "qbg_vdp22.h" + #include "qbg_vdpnl.h" + #include "qbg_utils.h" ++#include "lldp_util.h" ++ ++struct vsi_keyword_handler vsi_key_handle[] = { ++ {VSI22_ARG_MODE_STR, VSI_MODE_ARG}, ++ {VSI22_ARG_MGRID_STR, VSI_MGRID2_ARG}, ++ {VSI22_ARG_TYPEID_STR, VSI_TYPEID_ARG}, ++ {VSI22_ARG_TYPEIDVER_STR, VSI_TYPEIDVER_ARG}, ++/* {VSI22_ARG_VSIIDFRMT_STR, VSI_VSIIDFRMT_ARG}, TODO*/ ++ {VSI22_ARG_VSIID_STR, VSI_VSIID_ARG}, ++ {VSI22_ARG_HINTS_STR, VSI_HINTS_ARG}, ++ {VSI22_ARG_FILTER_STR, VSI_FILTER_ARG} }; + + /* + * Check if it is a UUID and consists of hexadecimal digits and dashes only. +@@ -253,6 +264,18 @@ static bool getmode(struct vdpnl_vsi *p, char *s) + return true; + } + ++enum vsi_mand_arg get_keywork_val(char *keyword) ++{ ++ int count, key_str_size; ++ ++ key_str_size = sizeof(vsi_key_handle) / sizeof(vsi_key_handle[0]); ++ for (count = 0; count < key_str_size; count++) { ++ if (!strcmp(keyword, vsi_key_handle[count].keyword)) ++ return vsi_key_handle[count].val; ++ } ++ return VSI_INVALID_ARG; ++} ++ + /* + * Parse the mode parameter to create/change an VSI assoication. + * The format is a comma separated list of tokens: +@@ -276,66 +299,95 @@ static bool getmode(struct vdpnl_vsi *p, char *s) + * mac := xx:xx:xx:xx:xx:xx + */ + +-static int str2vdpnl(char *argvalue, struct vdpnl_vsi *vsi) ++static int str2vdpnl(char *orig_argvalue, struct vdpnl_vsi *vsi) + { ++ char **args; ++ char **argvals; ++ char *argvalue; + int rc = -ENOMEM; + unsigned int no; +- unsigned short idx; +- char *cmdstring, *token; ++ unsigned short idx = 0; ++ int i, ioff = 0, offset; ++ int ilen = strlen(orig_argvalue); ++ int numargs; ++ enum vsi_mand_arg vsi_key; ++ u16 vsi_mand_mask = (1 << VSI_MAND_NUM_ARG) - 1; ++ u16 num_arg_keys = 0; + +- cmdstring = strdup(argvalue); +- if (!cmdstring) +- goto out_free; +- rc = -EINVAL; +- /* 1st field is VSI command */ +- token = strtok(cmdstring, ","); +- if (!token || !getmode(vsi, token)) +- goto out_free; ++ argvalue = strdup(orig_argvalue); ++ if (!argvalue) ++ goto out; ++ /* Count args and argvalues */ ++ offset = ioff; ++ for (numargs = 0; (ilen - offset) > 2; numargs++) { ++ offset += 2; ++ if (ilen - offset > 0) { ++ offset++; ++ if (ilen - offset > 4) ++ offset += 4; ++ } ++ } ++ args = calloc(numargs, sizeof(char *)); ++ if (!args) ++ goto out_argvalue; + +- /* 2nd field is VSI Manager Identifer (16 bytes maximum) */ +- token = strtok(NULL, ","); +- if (!token || !getmgr2id(vsi, token)) +- goto out_free; +- +- /* 3rd field is type identifier */ +- token = strtok(NULL, ","); +- if (!token || !getnumber(token, 0, 0xffffff, &no)) +- goto out_free; +- vsi->vsi_typeid = no; +- +- /* 4th field is type version identifier */ +- token = strtok(NULL, ","); +- if (!token || !getnumber(token, 0, 0xff, &no)) +- goto out_free; +- vsi->vsi_typeversion = no; +- +- /* 5th field is filter VSI UUID */ +- token = strtok(NULL, ","); +- if (!token || vdp_str2uuid(vsi->vsi_uuid, token, sizeof(vsi->vsi_uuid))) +- goto out_free; +- vsi->vsi_idfmt = VDP22_ID_UUID; +- +- /* 6th field is migration hints */ +- token = strtok(NULL, ","); +- if (!token || !gethints(vsi, token)) +- goto out_free; +- +- /* +- * 7th and remaining fields are filter information format data. +- * All fields must have the same format. The first fid field determines +- * the format. +- */ +- for (idx = 0, token = strtok(NULL, ","); token != NULL; +- ++idx, token = strtok(NULL, ",")) { +- if (idx < vsi->macsz && !getfid(vsi, token, idx)) ++ argvals = calloc(numargs, sizeof(char *)); ++ if (!argvals) ++ goto out_args; ++ numargs = get_arg_val_list(argvalue, ilen, &ioff, args, argvals); ++ for (i = 0; i < numargs; i++) { ++ vsi_key = get_keywork_val(args[i]); ++ switch (vsi_key) { ++ case VSI_MODE_ARG: ++ if (!argvals[i] || !getmode(vsi, argvals[i])) ++ goto out_free; ++ break; ++ case VSI_MGRID2_ARG: ++ if (!argvals[i] || !getmgr2id(vsi, argvals[i])) ++ goto out_free; ++ break; ++ case VSI_TYPEID_ARG: ++ if (!argvals[i] || ++ !getnumber(argvals[i], 0, 0xffffff, &no)) ++ goto out_free; ++ vsi->vsi_typeid = no; ++ break; ++ case VSI_TYPEIDVER_ARG: ++ if (!argvals[i] || !getnumber(argvals[i], 0, 0xff, &no)) ++ goto out_free; ++ vsi->vsi_typeversion = no; ++ break; ++ case VSI_VSIID_ARG: ++ if (!argvals[i] || ++ vdp_str2uuid(vsi->vsi_uuid, argvals[i], ++ sizeof(vsi->vsi_uuid))) ++ goto out_free; ++ vsi->vsi_idfmt = VDP22_ID_UUID; ++ break; ++ case VSI_FILTER_ARG: ++ if (idx < vsi->macsz && !getfid(vsi, argvals[i], idx)) ++ goto out_free; ++ idx++; ++ break; ++ case VSI_HINTS_ARG: ++ if (!argvals[i] || !gethints(vsi, argvals[i])) ++ goto out_free; ++ break; ++ default: + goto out_free; ++ } ++ num_arg_keys |= (1 << vsi_key); + } +- + /* Return error if no filter information provided */ +- if (idx) ++ if ((num_arg_keys & vsi_mand_mask) == vsi_mand_mask) + rc = 0; + out_free: +- free(cmdstring); ++ free(argvals); ++out_args: ++ free(args); ++out_argvalue: ++ free(argvalue); ++out: + return rc; + } + +diff --git a/vdptool.c b/vdptool.c +index e7d384a..f506020 100644 +--- a/vdptool.c ++++ b/vdptool.c +@@ -125,31 +125,28 @@ static int render_cmd(struct cmd *cmd, int argc, char **args, char **argvals) + { + int len; + int i; ++ int fid = 0, oui = 0; + + len = sizeof(cmd->obuf); + ++ if (cmd->cmd == cmd_settlv) { ++ for (i = 0; i < argc; i++) { ++ if (args[i]) { ++ if (!strncasecmp(args[i], "filter", ++ strlen("filter"))) ++ fid++; ++ else if (!strncasecmp(args[i], "oui", ++ strlen("oui"))) ++ oui++; ++ } ++ } ++ } ++ cmd->ops |= (fid << OP_FID_POS) | (oui << OP_OUI_POS); + /* all command messages begin this way */ + snprintf(cmd->obuf, len, "%c%08x%c%1x%02x%08x%02x%s%02x%08x", + MOD_CMD, cmd->module_id, CMD_REQUEST, CLIF_MSG_VERSION, + cmd->cmd, cmd->ops, (unsigned int) strlen(cmd->ifname), + cmd->ifname, cmd->type, cmd->tlvid); +-#if PADDU +- if (cmd->cmd == cmd_settlv) { +- size_t len2 = 0; +- /* +- * Get total length and append it plus any args and argvals +- * to the command message +- */ +- for (i = 0; i < argc; i++) { +- if (args[i]) +- len2 += 2 + strlen(args[i]); +- if (argvals[i]) +- len2 += 4 + strlen(argvals[i]); +- } +- snprintf(cmd->obuf + strlen(cmd->obuf), len - strlen(cmd->obuf), +- "%04zx", len2); +- } +-#endif + /* Add any args and argvals to the command message */ + for (i = 0; i < argc; i++) { + if (args[i]) +@@ -710,6 +707,9 @@ static int _clif_command(struct clif *clif, char *cmd, int print) + char buf[MAX_CLIF_MSGBUF]; + size_t len; + int ret; ++ int rc; ++ char reply[100]; ++ size_t reply_len2 = sizeof(reply); + + print_raw_message(cmd, print); + +@@ -730,6 +730,13 @@ static int _clif_command(struct clif *clif, char *cmd, int print) + buf[len] = '\0'; + ret = parse_print_message(buf, print); + } ++ if (cli_attached) { ++ rc = clif_vsievt(clif, reply, &reply_len2, 5); ++ printf("\nReturn from vsievt %d ret %d Reply %s\n", rc, ret, ++ reply); ++ if (!rc) ++ printf("\nMsg is %s\n", reply); ++ } + + return ret; + } +@@ -854,6 +861,7 @@ static int request(struct clif *clif, int argc, char *argv[]) + int numargs = 0; + char **argptr = &argv[0]; + char *end; ++ char attach_str[9] = ""; + int c; + int option_index; + +@@ -865,7 +873,7 @@ static int request(struct clif *clif, int argc, char *argv[]) + + opterr = 0; + for (;;) { +- c = getopt_long(argc, argv, "i:tThcnvrRpqV:", ++ c = getopt_long(argc, argv, "i:tTWhcnvrRpqV:", + lldptool_opts, &option_index); + if (c < 0) + break; +@@ -936,6 +944,15 @@ static int request(struct clif *clif, int argc, char *argv[]) + case 'v': + command.cmd = cmd_version; + break; ++ case 'W': ++ snprintf(attach_str, sizeof(attach_str), "%x", ++ LLDP_MOD_VDP22); ++ if (clif_attach(clif, attach_str) != 0) { ++ printf("Warning: Failed to attach to lldpad.\n"); ++ return -1; ++ } ++ cli_attached = 1; ++ break; + default: + usage(); + ret = -1; +-- +2.1.0 + diff --git a/SOURCES/open-lldp-v1.0.1-5-VDP-Support-for-get-tlv-in-vdptool-and-VDP22.patch b/SOURCES/open-lldp-v1.0.1-5-VDP-Support-for-get-tlv-in-vdptool-and-VDP22.patch new file mode 100644 index 0000000..d880bb5 --- /dev/null +++ b/SOURCES/open-lldp-v1.0.1-5-VDP-Support-for-get-tlv-in-vdptool-and-VDP22.patch @@ -0,0 +1,1194 @@ +From 0a21b0c0b9674f90cb9185e7fe097ae83657328f Mon Sep 17 00:00:00 2001 +From: padkrish +Date: Wed, 21 Jan 2015 03:37:31 +0000 +Subject: [PATCH] VDP: Support for get-tlv in vdptool and VDP22 + +This commit has the following changes: +a. Change in VDP22 and vdptool to support get-tlv. This actually refers to +get-vsi. Support for querying and printing all VSI's, partial VSI's is added. +The vdptool man page document is also modified accordingly. +b. The response from lldpad (VDP22) is modified to support to the +len, key, len, value format. Earlier, only the meessage to VDP22 has the +format. The response from VDP22 followed the comma separated format for VSI +parameters. +c. Fix some formatting issues + +Signed-off-by: padkrish +Signed-off-by: John Fastabend +--- + docs/vdptool.8 | 47 +++++++----- + include/lldp_util.h | 1 + + include/qbg_vdp22.h | 5 +- + include/qbg_vdp22def.h | 11 ++- + include/qbg_vdpnl.h | 3 + + lldp_util.c | 52 ++++++++++---- + qbg/vdp22.c | 28 ++++++-- + qbg/vdp22_cmds.c | 135 +++++++++++++++++++++++++++++++---- + qbg/vdp22sm.c | 5 +- + qbg/vdp_ascii.c | 190 +++++++++++++++++++++++++++++++------------------ + vdptool.c | 152 +++++++++++---------------------------- + 11 files changed, 395 insertions(+), 234 deletions(-) + +diff --git a/docs/vdptool.8 b/docs/vdptool.8 +index 5110bb9..02b4e8e 100644 +--- a/docs/vdptool.8 ++++ b/docs/vdptool.8 +@@ -70,17 +70,17 @@ bridge. + Specifies additional parameters for TLV queries and associations commands. + The argument list varies, depending on the command option + .B (-T) +-or ++or + .BR (-t) . +-To establish a VSI association use the command option ++To establish a VSI association use the command option + .B (-T) + and specify additional information as arguments in the form +-of key=value. See the ++of key=value. See the + .I "VSI Parameter" + subsection and + .I Example + section below. +-To query a VSI specific association use the command option ++To query a VSI specific association use the command option + .B (-t) + and specify the value of the + VSI Instance Identifier (keywork uuid followed be the VSI +@@ -92,6 +92,9 @@ show raw client interface messages + .TP + .B \-R + show only raw Client interface messages ++.TP ++.B \-W ++Wait for the bridge response message + .SS VSI Parameter + Each VDP22 TLVs contains a command mode, manager identifier, + type identifier, type identifier version, VSI instance identifier, +@@ -99,7 +102,7 @@ migiration hints and filter information. + The fields are explained next: + .TP + .B "mode (Command Mode):" +-The command mode determines the type ++The command mode determines the type + of the VSI association to be established. + It is an ascii string can be one of: + .RS +@@ -110,7 +113,7 @@ Create an VSI preassociation. The association + is only announced to the switch. + .IP preassoc-rr: + Create an VSI preassociation. The association +-is only announced to the switch and the ++is only announced to the switch and the + switch should reserve the resources. + .IP deassoc: + Delete an VSI association. +@@ -137,7 +140,7 @@ an UUID according to RFC 4122 + with optional dashes in between. + .TP + .B "hints (Migration Hints):" +-The migiration hints is a string aiding in ++The migiration hints is a string aiding in + migration of virtual machines: + .RS + .IP none: +@@ -168,13 +171,13 @@ The MAC address is specified in the format xx:xx:xx:xx:xx:xx. + The colons are mandatory. + For vlan details see (1). + .IP "vlan-mac-group (4)" +-A vlan number, MAC address and group identifier, ++A vlan number, MAC address and group identifier, + each delimited by a slash ('-'), + also known as filter information format 4. + The group identifier is a 32 bit number. + For vlan and MAC address details see (1) and (2). + .IP "vlan--group (3)" +-A vlan number and group identifier, ++A vlan number and group identifier, + delimited by two slashes ('--'), + also known as filter information format 3. + For vlan and group details see (1) and (4). +@@ -218,18 +221,30 @@ vdptool -p + Create a VSI association on interface eth2 + .br + .nf +-Supported today: One config parameter and comma separated list +-vdptool -i eth2 -T -V assoc -c vsi=assoc,blabla,5, \\ +- 1122,4,none,2-52:00:00:11:22:33-200 ++vdptool -i eth2 -T -V assoc -c mode=assoc -c mgrid2=blabla \\ ++ -c typeid=5 -c uuid=1122 -c typeidver=4 -c hints=none \\ ++ -c filter=2-52:00:00:11:22:33-200 ++.fi ++.TP ++Create a VSI association on interface eth2 and wait for the response from the bridge ++.br ++.nf ++vdptool -i eth2 -T -W -V assoc -c mode=assoc -c mgrid2=blabla \\ ++ -c typeid=5 -c uuid=1122 -c typeidver=4 -c hints=none \\ ++ -c filter=0-52:00:00:11:22:33-200 ++.fi + +-Planned for the future: +-vdptool -i eth2 -T -V assoc -c mgrid2=blabla -c typeid=5 \\ +- -c uuid=1122 -c typeidver=4 -c hints=none -c fid=2-52:00:00:11:22:33-200 +-.fi + .TP + Query all VSI association on interface eth2 + .br + vdptool -i eth2 -t -V assoc ++ ++.TP ++Query VSI association on interface eth2 that matches specific VSI parameters. Any of the VSI parameters below can be omitted. ++.br ++vdptool -i eth2 -t -V assoc -t -V assoc -c mode=assoc \\ ++ -c mgrid2=blabla -c typeid=5 -c uuid=1122 \\ ++ -c typeidver=4 -c hints=none + .SH SEE ALSO + .BR lldptool-dcbx (8), + .BR lldptool-ets (8), +diff --git a/include/lldp_util.h b/include/lldp_util.h +index 5767d4e..878426b 100644 +--- a/include/lldp_util.h ++++ b/include/lldp_util.h +@@ -170,6 +170,7 @@ int check_link_status(const char *ifname); + int get_arg_val_list(char *ibuf, int ilen, int *ioff, + char **args, char **argvals); + int get_arg_list(char *ibuf, int ilen, int *ioff, char **args); ++int get_vsistr_arg_count(int ioff, int ilen); + + #define ntohll(x) be64_to_cpu(x) + #define htonll(x) cpu_to_be64(x) +diff --git a/include/qbg_vdp22.h b/include/qbg_vdp22.h +index 45f44d5..af0aa15 100644 +--- a/include/qbg_vdp22.h ++++ b/include/qbg_vdp22.h +@@ -165,7 +165,7 @@ struct vdp22_user_data { /* Head for all VDP data */ + + struct vsi_keyword_handler { + char *keyword; +- enum vsi_mand_arg val; ++ enum vsi_key_arg val; + }; + + struct lldp_module *vdp22_register(void); +@@ -175,6 +175,7 @@ void vdp22_showvsi(struct vsi22 *p); + void vdp22_stop(char *); + int vdp22_from_ecp22(struct vdp22 *); + int vdp22_query(const char *); ++struct vdp22 *vdp22_getvdp(const char *); + int vdp22_addreq(struct vsi22 *, struct vdp22 *); + int vdp22_nlback(struct vsi22 *); + int vdp22_clntback(struct vsi22 *); +@@ -184,6 +185,8 @@ int vdp22br_resources(struct vsi22 *, int *); + int vdp22_info(const char *); + void vdp22_stop_timers(struct vsi22 *); + int vdp22_start_localchange_timer(struct vsi22 *); ++bool vdp22_cmp_fdata(struct vsi22 *, struct vsi22 *); ++void vdp22_delete_vsi(struct vsi22 *); + + /* + * Functions to get and set vlan identifier and qos. +diff --git a/include/qbg_vdp22def.h b/include/qbg_vdp22def.h +index 21ba15d..ff4270c 100644 +--- a/include/qbg_vdp22def.h ++++ b/include/qbg_vdp22def.h +@@ -30,6 +30,15 @@ + #define QBG_VDP22DEF_H + + /* ++ * Define for length of vid-mac-gid ++ * VID in string cannot be more than 4B (Max is 4K) ++ * MAC when represented as 11:22:33:44:55:66 has 17B ++ * GID is 4B ++ * The below should be more than sufficient. ++ */ ++#define MAX_GID_MAC_VID_STR 50 ++ ++/* + * Define VDP22 filter formats. + */ + enum vdp22_ffmt { /* Format of filter information */ +@@ -72,7 +81,7 @@ enum vdp22_migration_hints { + VDP22_MIGFROM = 32 /* S-bit migrate from hint */ + }; + +-enum vsi_mand_arg { ++enum vsi_key_arg { + VSI_MODE_ARG = 0, + VSI_MGRID2_ARG, + VSI_TYPEID_ARG, +diff --git a/include/qbg_vdpnl.h b/include/qbg_vdpnl.h +index 510a20c..c5c93ed 100644 +--- a/include/qbg_vdpnl.h ++++ b/include/qbg_vdpnl.h +@@ -79,4 +79,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 *); ++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); + #endif +diff --git a/lldp_util.c b/lldp_util.c +index 754b0cd..f1fb7b9 100644 +--- a/lldp_util.c ++++ b/lldp_util.c +@@ -199,7 +199,7 @@ int is_bond(const char *ifname) + */ + int is_san_mac(u8 *addr) + { +- int i; ++ int i; + + for ( i = 0; i < ETH_ALEN; i++) { + if ( addr[i]!= 0xff ) +@@ -215,7 +215,7 @@ int is_san_mac(u8 *addr) + * @addr: address of buffer in which to return the selected MAC address + * + * Checks to see if ifname is a slave of the bond port. If it is, +- * then a ++ * then a + * Returns 0 if a source MAC from the bond could not be found. 1 is + * returned if the slave was found in the bond. addr is updated with + * the source MAC that should be used. +@@ -287,7 +287,7 @@ int get_src_mac_from_bond(struct port *bond_port, char *ifname, u8 *addr) + + switch (ifb.bond_mode) { + case BOND_MODE_ACTIVEBACKUP: +- /* If current port is not the active slave, then ++ /* If current port is not the active slave, then + * if the bond MAC is equal to the port's + * permanent MAC, then find and return + * the permanent MAC of the active +@@ -297,7 +297,7 @@ int get_src_mac_from_bond(struct port *bond_port, char *ifname, u8 *addr) + if (strncmp(ifname, act_ifname, IFNAMSIZ)) + if (get_perm_hwaddr(ifname, addr, san_mac) == 0) + if (!memcmp(bond_mac, addr, ETH_ALEN)) +- get_perm_hwaddr(act_ifname, addr, ++ get_perm_hwaddr(act_ifname, addr, + san_mac); + break; + default: +@@ -346,7 +346,7 @@ int get_ifflags(const char *ifname) + int flags = 0; + struct ifreq ifr; + +- /* use ioctl */ ++ /* use ioctl */ + fd = get_ioctl_socket(); + if (fd >= 0) { + memset(&ifr, 0, sizeof(ifr)); +@@ -382,7 +382,7 @@ int get_ifpflags(const char *ifname) + int flags = 0; + struct ifreq ifr; + +- /* use ioctl */ ++ /* use ioctl */ + fd = get_ioctl_socket(); + if (fd >= 0) { + memset(&ifr, 0, sizeof(ifr)); +@@ -417,7 +417,7 @@ int get_iflink(const char *ifname) + snprintf(path, sizeof(path), "/sys/class/net/%s/iflink", ifname); + return read_int(path); + } +- ++ + int is_ether(const char *ifname) + { + /* check for bridge in sysfs */ +@@ -486,7 +486,7 @@ int is_slave(const char *ifmaster, const char *ifslave) + } + } + } +- ++ + out_done: + return rc; + } +@@ -562,13 +562,13 @@ int is_bridge(const char *ifname) + if (dirp) { + closedir(dirp); + rc = 1; +- } else { +- /* use ioctl */ ++ } else { ++ /* use ioctl */ + fd = get_ioctl_socket(); + if (fd >= 0) { + struct ifreq ifr; + struct __bridge_info bi; +- unsigned long args[4] = { BRCTL_GET_BRIDGE_INFO, ++ unsigned long args[4] = { BRCTL_GET_BRIDGE_INFO, + (unsigned long) &bi, 0, 0 }; + + ifr.ifr_data = (char *)args; +@@ -748,7 +748,7 @@ int is_autoneg_supported(const char *ifname) + int fd; + struct ifreq ifr; + struct ethtool_cmd cmd; +- ++ + fd = get_ioctl_socket(); + if (fd >= 0) { + memset(&ifr, 0, sizeof(ifr)); +@@ -769,7 +769,7 @@ int is_autoneg_enabled(const char *ifname) + int fd; + struct ifreq ifr; + struct ethtool_cmd cmd; +- ++ + fd = get_ioctl_socket(); + if (fd >= 0) { + memset(&ifr, 0, sizeof(ifr)); +@@ -806,7 +806,7 @@ int get_maucaps(const char *ifname) + u16 caps = MAUCAPADV_bOther; + struct ifreq ifr; + struct ethtool_cmd cmd; +- ++ + fd = get_ioctl_socket(); + if (fd >= 0) { + memset(&ifr, 0, sizeof(ifr)); +@@ -940,7 +940,7 @@ u16 get_caps(const char *ifname) + + /* how to find TPID to determine C-VLAN vs. S-VLAN ? */ + if (is_vlan(ifname)) +- caps |= SYSCAP_CVLAN; ++ caps |= SYSCAP_CVLAN; + + if (is_bridge(ifname)) + caps |= SYSCAP_BRIDGE; +@@ -1282,3 +1282,25 @@ int get_arg_list(char *ibuf, int ilen, int *ioff, char **args) + free(arglens); + return numargs; + } ++ ++/* ++ * This functionality can be seen in many places to convert a LenData to a ++ * argument array. ++ */ ++ ++int get_vsistr_arg_count(int ioff, int ilen) ++{ ++ int offset; ++ int numargs; ++ ++ offset = ioff; ++ for (numargs = 0; (ilen - offset) > 2; numargs++) { ++ offset += 2; ++ if (ilen - offset > 0) { ++ offset++; ++ if (ilen - offset > 4) ++ offset += 4; ++ } ++ } ++ return numargs; ++} +diff --git a/qbg/vdp22.c b/qbg/vdp22.c +index a3cb7c9..af11af8 100644 +--- a/qbg/vdp22.c ++++ b/qbg/vdp22.c +@@ -219,7 +219,7 @@ void vdp22_showvsi(struct vsi22 *p) + /* + * Delete a complete VSI node not on queue. + */ +-static void vdp22_delete_vsi(struct vsi22 *p) ++void vdp22_delete_vsi(struct vsi22 *p) + { + LLDPAD_DBG("%s:%s vsi:%p(%02x)\n", __func__, p->vdp->ifname, p, + p->vsi[0]); +@@ -477,14 +477,15 @@ static bool filter_ok(unsigned char ffmt, struct fid22 *fp, + * Allocate a VSI node with filter information data. + * Check if input data is valid. + */ +-static struct vsi22 *vdp22_alloc_vsi(struct vdpnl_vsi *vsi, struct vdp22 *vdp, +- int *rc) ++static struct vsi22 *vdp22_alloc_vsi_int(struct vdpnl_vsi *vsi, ++ struct vdp22 *vdp, ++ int *rc, bool vsinl_chk) + { + struct vsi22 *p; + int i; + + *rc = -EINVAL; +- if (!check_vsinl(vsi)) ++ if (vsinl_chk && (!check_vsinl(vsi))) + return NULL; + p = calloc(1, sizeof(*p)); + if (!p) { +@@ -546,6 +547,16 @@ error1: + return NULL; + } + ++struct vsi22 *vdp22_alloc_vsi_ext(struct vdpnl_vsi *vsinl, int *rc) ++{ ++ struct vdp22 *vdp; ++ ++ vdp = vdp22_getvdp(vsinl->ifname); ++ if (!vdp) ++ return NULL; ++ return vdp22_alloc_vsi_int(vsinl, vdp, rc, false); ++} ++ + /* + * Allocate a VSI node with filter information data. + * Check if input data is valid. Data was received by bridge from unknown +@@ -750,7 +761,7 @@ static struct vdp22 *vdp22_create(const char *ifname, + /* + * Query the supported VDP protocol on an interface. + */ +-static struct vdp22 *vdp22_getvdp(const char *ifname) ++struct vdp22 *vdp22_getvdp(const char *ifname) + { + struct vdp22 *vdp; + +@@ -820,7 +831,7 @@ int vdp22_request(struct vdpnl_vsi *vsi, int clif) + /* Adjust numbering for VDP 0.2 protocol from netlink */ + if (!clif) + vsi->request += 1; +- p = vdp22_alloc_vsi(vsi, vdp, &rc); ++ p = vdp22_alloc_vsi_int(vsi, vdp, &rc, true); + if (p) { + rc = vdp22_addreq(p, vdp); + if (rc) +@@ -1079,3 +1090,8 @@ int vdp22_info(const char *ifname) + return rc; + + } ++ ++void copy_vsi_external(struct vdpnl_vsi *vsi, struct vsi22 *p, int clif) ++{ ++ copy_vsi(vsi, p, clif); ++} +diff --git a/qbg/vdp22_cmds.c b/qbg/vdp22_cmds.c +index dde4669..409858d 100644 +--- a/qbg/vdp22_cmds.c ++++ b/qbg/vdp22_cmds.c +@@ -237,7 +237,7 @@ int vdp22_clif_cmd(UNUSED void *data, UNUSED struct sockaddr_un *from, + return cmd_not_applicable; + } + +- if (!(cmd.ops & op_config)) ++ if (!(cmd.ops & op_config) && (cmd.cmd != cmd_gettlv)) + return cmd_invalid; + + snprintf(rbuf, rlen, "%c%1x%02x%08x%02x%s", +@@ -254,10 +254,9 @@ int vdp22_clif_cmd(UNUSED void *data, UNUSED struct sockaddr_un *from, + snprintf(rbuf + roff, rlen - roff, "%08x", cmd.tlvid); + roff += 8; + if (cmd.cmd == cmd_gettlv) { +- rstatus = handle_get_arg(&cmd, ARG_VDP22_VSI, +- NULL, +- rbuf + strlen(rbuf), +- rlen - strlen(rbuf)); ++ rstatus = handle_get_arg(&cmd, ARG_VDP22_VSI, ibuf + ioff, ++ rbuf + strlen(rbuf), ++ rlen - strlen(rbuf)); + } else { + rstatus = handle_test_arg(&cmd, ARG_VDP22_VSI, + ibuf + ioff, +@@ -392,19 +391,25 @@ static int test_arg_vsi(struct cmd *cmd, UNUSED char *arg, char *argvalue, + */ + static int catvsis(struct vdpnl_vsi *vsi, char *out, size_t out_len) + { +- int rc, i; ++ int rc, i, len, c; + size_t used = 0; + unsigned char wanted_req = vsi->request; ++ char tmp_buf[MAX_CLIF_MSGBUF]; + ++ memset(tmp_buf, 0, sizeof(tmp_buf)); + for (i = 1; vdp22_status(i, vsi, 1) > 0; ++i) { + if (wanted_req != vsi->request) { + vdp22_freemaclist(vsi); + continue; + } +- rc = vdp_vdpnl2str(vsi, out + used, out_len - used); ++ rc = vdp_vdpnl2str(vsi, tmp_buf, out_len - used); ++ len = strlen(tmp_buf); ++ c = snprintf(out + used, out_len - used, "%04x%s", len, ++ tmp_buf); ++ if ((c < 0) || ((unsigned)c >= (out_len - used))) ++ return 0; + vdp22_freemaclist(vsi); + if (rc) { +- strcat(out, ";"); + used = strlen(out); + } else + return 0; +@@ -413,15 +418,113 @@ static int catvsis(struct vdpnl_vsi *vsi, char *out, size_t out_len) + } + + /* ++ * Based on the VSI arguments specified, checks if it matches. ++ * This does't check for all VSI parameters. ++ */ ++ ++static bool vdp22_partial_vsi_equal(struct vsi22 *p1, struct vsi22 *p2, ++ enum vsi_key_arg vsi_arg_key_flags) ++{ ++ enum vsi_key_arg key_enum; ++ ++ for (key_enum = VSI_MODE_ARG; key_enum < VSI_INVALID_ARG; key_enum++) { ++ if (!((1 << key_enum) & vsi_arg_key_flags)) ++ continue; ++ switch (key_enum) { ++ case VSI_MODE_ARG: ++ break; ++ case VSI_MGRID2_ARG: ++ if (memcmp(p1->mgrid, p2->mgrid, ++ sizeof(p2->mgrid))) ++ return false; ++ case VSI_TYPEID_ARG: ++ if (p1->type_id != p2->type_id) ++ return false; ++ break; ++ case VSI_TYPEIDVER_ARG: ++ if (p1->type_ver != p2->type_ver) ++ return false; ++ break; ++#ifdef LATER ++/* Currently not supported */ ++ case VSI_VSIIDFRMT_ARG: ++ if (p1->vsi_fmt != p2->vsi_fmt) ++ return false; ++ break; ++#endif ++ case VSI_VSIID_ARG: ++ if (memcmp(p1->vsi, p2->vsi, sizeof(p1->vsi))) ++ return false; ++ break; ++ case VSI_FILTER_ARG: ++ if ((p1->fif != p2->fif) || (!vdp22_cmp_fdata(p1, p2))) ++ return false; ++ break; ++ case VSI_HINTS_ARG: ++ break; ++ default: ++ return false; ++ } ++ } ++ return true; ++} ++ ++static int get_vsi_partial_arg(UNUSED char *arg, char *orig_argvalue, ++ struct vdpnl_vsi *vsinl, char *out, ++ size_t out_len) ++{ ++ char tmp_buf[MAX_CLIF_MSGBUF]; ++ struct vsi22 *p, *vsi; ++ struct vdp22 *vdp; ++ size_t used = 0; ++ int rc = -ENOMEM, len, c; ++ u16 vsi_arg_key_flags = 0; ++ ++ if (vdp22_parse_str_vdpnl(vsinl, &vsi_arg_key_flags, orig_argvalue)) ++ goto out; ++ vdp = vdp22_getvdp(vsinl->ifname); ++ if (!vdp) ++ goto out; ++ ++ vsi = vdp22_alloc_vsi_ext(vsinl, &rc); ++ if (!vsi) ++ goto out; ++ LIST_FOREACH(p, &vdp->vsi22_que, node) { ++ if (p->vsi_mode != vsi->vsi_mode) ++ continue; ++ if (vdp22_partial_vsi_equal(p, vsi, vsi_arg_key_flags)) { ++ copy_vsi_external(vsinl, p, 1); ++ rc = vdp_vdpnl2str(vsinl, tmp_buf, out_len - used); ++ len = strlen(tmp_buf); ++ c = snprintf(out + used, out_len - used, "%04x%s", ++ len, tmp_buf); ++ vdp22_freemaclist(vsinl); ++ if ((c < 0) || ((unsigned)c >= (out_len - used))) ++ goto out_delvsi; ++ if (rc) ++ used = strlen(out); ++ else ++ goto out_delvsi; ++ } ++ } ++out_delvsi: ++ vdp22_delete_vsi(vsi); ++out: ++ return rc; ++} ++ ++/* + * Return all VSIs on a particular interface into one string. + */ +-static int get_arg_vsi(struct cmd *cmd, char *arg, UNUSED char *argvalue, ++static int get_arg_vsi(struct cmd *cmd, char *arg, char *argvalue, + char *obuf, int obuf_len) + { + cmd_status good_cmd = vdp22_cmdok(cmd, cmd_gettlv); + struct vdpnl_vsi vsi; + char vsi_str[MAX_CLIF_MSGBUF]; + int rc; ++ int fsize = (cmd->ops >> OP_FID_POS) & 0xff; ++ struct vdpnl_mac mac[fsize]; + + if (good_cmd != cmd_success) + return good_cmd; +@@ -433,14 +536,20 @@ static int get_arg_vsi(struct cmd *cmd, char *arg, UNUSED char *argvalue, + + memset(obuf, 0, obuf_len); + memset(&vsi, 0, sizeof(vsi)); ++ memset(vsi_str, 0, sizeof(vsi_str)); + vsi.request = cmd->tlvid; + strncpy(vsi.ifname, cmd->ifname, sizeof(vsi.ifname) - 1); + good_cmd = cmd_failed; +- if (!catvsis(&vsi, vsi_str, sizeof(vsi_str))) ++ if ((cmd->ops & op_config) && (cmd->ops & op_arg)) { ++ memset(&mac, 0, sizeof(mac)); ++ vsi.macsz = fsize; ++ vsi.maclist = mac; ++ if (!get_vsi_partial_arg(arg, argvalue, &vsi, vsi_str, ++ sizeof(vsi_str))) ++ goto out; ++ } else if (!catvsis(&vsi, vsi_str, sizeof(vsi_str))) + goto out; +- rc = snprintf(obuf, obuf_len, "%02x%s%04x%s", +- (unsigned int)strlen(arg), arg, (unsigned int)strlen(vsi_str), +- vsi_str); ++ rc = snprintf(obuf, obuf_len, "%s", vsi_str); + if (rc > 0 || rc < obuf_len) + good_cmd = cmd_success; + out: +diff --git a/qbg/vdp22sm.c b/qbg/vdp22sm.c +index d1f65b4..6264f74 100644 +--- a/qbg/vdp22sm.c ++++ b/qbg/vdp22sm.c +@@ -944,7 +944,8 @@ static bool cmp_fdata1(struct fid22 *p1, struct fid22 *p2, unsigned char fif) + + if (fif == VDP22_FFMT_MACVID || fif == VDP22_FFMT_GROUPMACVID) + is_good = !memcmp(p1->mac, p2->mac, sizeof(p1->mac)); +- if (fif == VDP22_FFMT_GROUPVID || fif == VDP22_FFMT_GROUPMACVID) ++ if (is_good && ++ (fif == VDP22_FFMT_GROUPVID || fif == VDP22_FFMT_GROUPMACVID)) + is_good = (p1->grpid == p2->grpid); + if (is_good) { + if (vdp22_get_vlanid(p1->vlan)) +@@ -956,7 +957,7 @@ static bool cmp_fdata1(struct fid22 *p1, struct fid22 *p2, unsigned char fif) + return is_good; + } + +-static bool vdp22_cmp_fdata(struct vsi22 *p, struct vsi22 *vsip) ++bool vdp22_cmp_fdata(struct vsi22 *p, struct vsi22 *vsip) + { + int i; + +diff --git a/qbg/vdp_ascii.c b/qbg/vdp_ascii.c +index 09e53c6..76dde4a 100644 +--- a/qbg/vdp_ascii.c ++++ b/qbg/vdp_ascii.c +@@ -110,6 +110,15 @@ static bool getnumber(char *s, unsigned int min, unsigned int max, + } + + /* ++ * Returns the byte length of a given number ++ */ ++ ++static int get_strlen_num(unsigned long no) ++{ ++ return snprintf(NULL, 0, "%lu", no); ++} ++ ++/* + * Read filter information data. The format is an ascii string: + * filter-data filter-format + * vlan 1 +@@ -264,7 +273,7 @@ static bool getmode(struct vdpnl_vsi *p, char *s) + return true; + } + +-enum vsi_mand_arg get_keywork_val(char *keyword) ++enum vsi_key_arg get_keywork_val(char *keyword) + { + int count, key_str_size; + +@@ -276,65 +285,36 @@ enum vsi_mand_arg get_keywork_val(char *keyword) + return VSI_INVALID_ARG; + } + +-/* +- * Parse the mode parameter to create/change an VSI assoication. +- * The format is a comma separated list of tokens: +- * cmd,mgrid,typeid,typeidversion,vsiid,hints,fid[,fid,fid,...] +- * with +- * cmd := "assoc" | "deassoc" | "preassoc" | "preassoc-rr" +- * mgrid := less or equal to 16 byte alphanumeric characters +- * | UUID (with dashes in between) +- * typeid := number in range of 1 - 2^24 -1 +- * typeidversion:= number in range of 1 - 255 +- * vsiid := UUID (with dashes in between) +- * hints := varies between input (command) and output (event message) +- * on input --> dash (-) | "none" | "from" | "to" +- * on output --> response (number between 0..255) +- * fid := vlan +- * | vlan-mac +- * | vlan--group +- * | vlan-mac-group +- * vlan := number in range of 1..2^16 -1 +- * group := number in range of 1..2^32 - 1 +- * mac := xx:xx:xx:xx:xx:xx +- */ +- +-static int str2vdpnl(char *orig_argvalue, struct vdpnl_vsi *vsi) ++int vdp22_parse_str_vdpnl(struct vdpnl_vsi *vsi, u16 *key_flags, ++ char *orig_argvalue) + { +- char **args; + char **argvals; ++ char **args; + char *argvalue; ++ enum vsi_key_arg vsi_key; + int rc = -ENOMEM; ++ int i, ioff = 0, numargs; ++ int ilen = strlen(orig_argvalue); + unsigned int no; + unsigned short idx = 0; +- int i, ioff = 0, offset; +- int ilen = strlen(orig_argvalue); +- int numargs; +- enum vsi_mand_arg vsi_key; +- u16 vsi_mand_mask = (1 << VSI_MAND_NUM_ARG) - 1; + u16 num_arg_keys = 0; + + argvalue = strdup(orig_argvalue); + if (!argvalue) + goto out; + /* Count args and argvalues */ +- offset = ioff; +- for (numargs = 0; (ilen - offset) > 2; numargs++) { +- offset += 2; +- if (ilen - offset > 0) { +- offset++; +- if (ilen - offset > 4) +- offset += 4; +- } +- } ++ numargs = get_vsistr_arg_count(ioff, ilen); ++ if (numargs == 0) ++ goto out_argvalue; + args = calloc(numargs, sizeof(char *)); + if (!args) + goto out_argvalue; +- + argvals = calloc(numargs, sizeof(char *)); + if (!argvals) + goto out_args; + numargs = get_arg_val_list(argvalue, ilen, &ioff, args, argvals); ++ if (numargs == 0) ++ goto out_free; + for (i = 0; i < numargs; i++) { + vsi_key = get_keywork_val(args[i]); + switch (vsi_key) { +@@ -378,9 +358,9 @@ static int str2vdpnl(char *orig_argvalue, struct vdpnl_vsi *vsi) + } + num_arg_keys |= (1 << vsi_key); + } +- /* Return error if no filter information provided */ +- if ((num_arg_keys & vsi_mand_mask) == vsi_mand_mask) +- rc = 0; ++ *key_flags = num_arg_keys; ++ rc = 0; ++ + out_free: + free(argvals); + out_args: +@@ -392,6 +372,44 @@ out: + } + + /* ++ * Parse the mode parameter to create/change an VSI assoication. ++ * The format is a comma separated list of tokens: ++ * cmd,mgrid,typeid,typeidversion,vsiid,hints,fid[,fid,fid,...] ++ * with ++ * cmd := "assoc" | "deassoc" | "preassoc" | "preassoc-rr" ++ * mgrid := less or equal to 16 byte alphanumeric characters ++ * | UUID (with dashes in between) ++ * typeid := number in range of 1 - 2^24 -1 ++ * typeidversion:= number in range of 1 - 255 ++ * vsiid := UUID (with dashes in between) ++ * hints := varies between input (command) and output (event message) ++ * on input --> dash (-) | "none" | "from" | "to" ++ * on output --> response (number between 0..255) ++ * fid := vlan ++ * | vlan-mac ++ * | vlan--group ++ * | vlan-mac-group ++ * vlan := number in range of 1..2^16 -1 ++ * group := number in range of 1..2^32 - 1 ++ * mac := xx:xx:xx:xx:xx:xx ++ */ ++ ++static int str2vdpnl(char *orig_argvalue, struct vdpnl_vsi *vsi) ++{ ++ int rc = -ENOMEM; ++ u16 vsi_mand_mask = (1 << VSI_MAND_NUM_ARG) - 1; ++ u16 num_arg_keys = 0; ++ ++ if (vdp22_parse_str_vdpnl(vsi, &num_arg_keys, orig_argvalue)) ++ goto out; ++ /* Return error if no filter information provided */ ++ if ((num_arg_keys & vsi_mand_mask) == vsi_mand_mask) ++ rc = 0; ++out: ++ return rc; ++} ++ ++/* + * Fill the vdpnl_vsi structure from the string. + * Allocate the maclist. Must be free'ed by caller. + */ +@@ -426,6 +444,7 @@ static char *check_and_update(size_t *total, size_t *length, char *s, int c) + /* + * Convert VSI association to string. + */ ++#ifdef LATER_USE + static const char *mode2str(unsigned char x) + { + if (x == VDP22_ASSOC) +@@ -438,6 +457,7 @@ static const char *mode2str(unsigned char x) + return "deassoc"; + return "unknown"; + } ++#endif + + /* + * Convert filter information format into vlan[-mac][-group] string. +@@ -448,26 +468,50 @@ static int fid2str(char *s, size_t length, int fif, struct vdpnl_mac *p) + { + int c; + size_t total = 0; ++ char tmp_buf[MAX_GID_MAC_VID_STR]; + +- c = snprintf(s, length, "%d", vdp22_set_qos(p->qos) | +- vdp22_set_vlanid(p->vlan)); ++ c = snprintf(s, length, "%02x%s", ++ (unsigned int)strlen(VSI22_ARG_FILTER_STR), ++ VSI22_ARG_FILTER_STR); + s = check_and_update(&total, &length, s, c); + if (!s) + goto out; +- if (fif == VDP22_FFMT_MACVID || fif == VDP22_FFMT_GROUPMACVID) { +- c = snprintf(s, length, "-%02x:%02x:%02x:%02x:%02x:%02x", +- p->mac[0], p->mac[1], p->mac[2], p->mac[3], +- p->mac[4], p->mac[5]); +- s = check_and_update(&total, &length, s, c); +- if (!s) +- goto out; +- } +- if (fif == VDP22_FFMT_GROUPVID || fif == VDP22_FFMT_GROUPMACVID) { +- c = snprintf(s, length, "-%ld", p->gpid); +- s = check_and_update(&total, &length, s, c); +- if (!s) +- goto out; ++ memset(tmp_buf, 0, sizeof(tmp_buf)); ++ switch (fif) { ++ case VDP22_FFMT_VID: ++ snprintf(tmp_buf, MAX_GID_MAC_VID_STR, "%d", ++ vdp22_set_qos(p->qos) | ++ vdp22_set_vlanid(p->vlan)); ++ break; ++ case VDP22_FFMT_MACVID: ++ snprintf(tmp_buf, MAX_GID_MAC_VID_STR, ++ "%d-%02x:%02x:%02x:%02x:%02x:%02x", ++ vdp22_set_qos(p->qos) | ++ vdp22_set_vlanid(p->vlan), ++ p->mac[0], p->mac[1], p->mac[2], p->mac[3], ++ p->mac[4], p->mac[5]); ++ break; ++ case VDP22_FFMT_GROUPVID: ++ snprintf(tmp_buf, MAX_GID_MAC_VID_STR, ++ "%d-%ld", ++ vdp22_set_qos(p->qos) | vdp22_set_vlanid(p->vlan), ++ p->gpid); ++ break; ++ case VDP22_FFMT_GROUPMACVID: ++ snprintf(tmp_buf, MAX_GID_MAC_VID_STR, ++ "%d-%02x:%02x:%02x:%02x:%02x:%02x-%ld", ++ vdp22_set_qos(p->qos) | vdp22_set_vlanid(p->vlan), ++ p->mac[0], p->mac[1], p->mac[2], p->mac[3], ++ p->mac[4], p->mac[5], p->gpid); ++ break; ++ default: ++ break; + } ++ c = snprintf(s, length, "%04x%s", (unsigned int)strlen(tmp_buf), ++ tmp_buf); ++ s = check_and_update(&total, &length, s, c); ++ if (!s) ++ goto out; + out: + return s ? total : 0; + } +@@ -500,15 +544,28 @@ int vdp_vdpnl2str(struct vdpnl_vsi *p, char *s, size_t length) + char instance[VDP_UUID_STRLEN + 2]; + + mgrid2str(instance, p, sizeof(instance)); +- c = snprintf(s, length, "%s,%s,%ld,%d,", +- mode2str(p->request), instance, p->vsi_typeid, +- p->vsi_typeversion); ++ c = snprintf(s, length, "%02x%s%04x%s%02x%s%04x%lu%02x%s%04x%d", ++ (unsigned int)strlen(VSI22_ARG_MGRID_STR), ++ VSI22_ARG_MGRID_STR, ++ (unsigned int)strlen(instance), instance, ++ (unsigned int)strlen(VSI22_ARG_TYPEID_STR), ++ VSI22_ARG_TYPEID_STR, get_strlen_num(p->vsi_typeid), ++ p->vsi_typeid, ++ (unsigned int)strlen(VSI22_ARG_TYPEIDVER_STR), ++ VSI22_ARG_TYPEIDVER_STR, ++ get_strlen_num(p->vsi_typeversion), p->vsi_typeversion); + s = check_and_update(&total, &length, s, c); + if (!s) + goto out; + + vdp_uuid2str(p->vsi_uuid, instance, sizeof(instance)); +- c = snprintf(s, length, "%s,%d,", instance, p->response); ++ c = snprintf(s, length, "%02x%s%04x%s%02x%s%04x%d", ++ (unsigned int)strlen(VSI22_ARG_VSIID_STR), ++ VSI22_ARG_VSIID_STR, (unsigned int)strlen(instance), ++ instance, ++ (unsigned int)strlen(VSI22_ARG_HINTS_STR), ++ VSI22_ARG_HINTS_STR, ++ get_strlen_num(p->response), p->response); + s = check_and_update(&total, &length, s, c); + if (!s) + goto out; +@@ -519,13 +576,8 @@ int vdp_vdpnl2str(struct vdpnl_vsi *p, char *s, size_t length) + s = check_and_update(&total, &length, s, c); + if (!c) + goto out; +- if (p->macsz > 1 && i < p->macsz - 1) { +- c = snprintf(s, length, ","); +- s = check_and_update(&total, &length, s, c); +- if (!s) +- goto out; +- } + } ++ + out: + return s ? total : 0; + } +diff --git a/vdptool.c b/vdptool.c +index f506020..551e829 100644 +--- a/vdptool.c ++++ b/vdptool.c +@@ -53,6 +53,7 @@ + + #include "qbg22.h" + #include "qbg_vdp22_clif.h" ++#include "lldp_util.h" + + static char *print_status(cmd_status status) + { +@@ -129,7 +130,7 @@ static int render_cmd(struct cmd *cmd, int argc, char **args, char **argvals) + + len = sizeof(cmd->obuf); + +- if (cmd->cmd == cmd_settlv) { ++ if ((cmd->cmd == cmd_settlv) || (cmd->cmd == cmd_gettlv)) { + for (i = 0; i < argc; i++) { + if (args[i]) { + if (!strncasecmp(args[i], "filter", +@@ -208,13 +209,6 @@ static int vdp_cmd_gettlv(struct clif *clif, int argc, char *argv[], + cmd->ops |= op_arg; + } + +- for (i = 0; i < numargs; i++) { +- if (argvals[i]) { +- printf("%s\n", print_status(cmd_invalid)); +- goto out; +- } +- } +- + render_cmd(cmd, argc, args, argvals); + free(args); + free(argvals); +@@ -305,125 +299,61 @@ static int vdp_parse_response(char *buf) + return hex2u8(buf + CLIF_STAT_OFF); + } + +-static void print_pair(char *arg, size_t arglen, char *value, size_t valuelen) ++int get_vsi_args(char *ibuf) + { +- while (arglen--) +- putchar(*arg++); +- putchar('='); +- while (valuelen--) +- putchar(*value++); +- putchar('\n'); +-} ++ int ioff = 0; ++ char **args; ++ char **argvals; ++ int numargs, i; ++ int ilen = strlen(ibuf); + +-static int print_arg_value(char *ibuf) +-{ +- int arglen, valuelen, offset = 0, ilen = strlen(ibuf); +- char *arg, *value; ++ /* count args and argvalus */ ++ numargs = get_vsistr_arg_count(ioff, ilen); + +- while (offset < ilen) { +- /* Length of argument */ +- arglen = hex2u8(ibuf + offset); +- if (arglen < 0) +- break; +- offset += 2; +- arg = ibuf + offset; +- offset += arglen; ++ args = calloc(numargs, sizeof(char *)); ++ if (!args) ++ return cmd_failed; + +- /* Length of argument value */ +- valuelen = hex2u16(ibuf + offset); +- if (valuelen < 0) +- break; +- offset += 4; +- value = ibuf + offset; +- offset += valuelen; ++ argvals = calloc(numargs, sizeof(char *)); ++ if (!argvals) { ++ free(args); ++ return cmd_failed; ++ } + +- print_pair(arg, arglen, value, valuelen); ++ numargs = get_arg_val_list(ibuf, ilen, &ioff, args, argvals); ++ for (i = 0; i < numargs; i++) { ++ printf("\t%s", args[i]); ++ printf(" = %s\n", argvals[i]); + } +- return offset; +-} + +-static int get_tlvid(char *ibuf) +-{ +- return hex2u32(ibuf); ++ free(args); ++ free(argvals); ++ return ioff; + } + +-/* +- * Print a TLV. +- */ +-static void print_tlv2(char *ibuf) ++static void print_all_vsis(char *ibuf) + { + size_t ilen = strlen(ibuf); +- u16 tlv_type; +- u16 tlv_len; +- u32 tlvid; +- int offset = 0; +- int printed; +- struct lldp_module *np; ++ u16 vsi_len; ++ int offset = 0, vsi_cnt = 0; ++ char tmp_ibuf[strlen(ibuf)]; + + while (ilen > 0) { +- tlv_len = 2 * sizeof(u16); +- if (ilen < 2 * sizeof(u16)) { +- printf("corrupted TLV ilen:%zd, tlv_len:%d\n", +- ilen, tlv_len); +- break; +- } +- tlv_type = hex2u16(ibuf + offset); +- tlv_len = tlv_type; +- tlv_type >>= 9; +- tlv_len &= 0x01ff; ++ vsi_len = hex2u16(ibuf + offset); ++ if (vsi_len > ilen) ++ return; + offset += 2 * sizeof(u16); + ilen -= 2 * sizeof(u16); +- +- if (ilen < (unsigned) 2 * tlv_len) { +- printf("corrupted TLV ilen:%zd, tlv_len:%d\n", +- ilen, tlv_len); +- break; +- } +- tlvid = tlv_type; +- if (tlvid == INVALID_TLVID) { +- tlvid = get_tlvid(ibuf + offset); +- offset += 8; +- } +- printed = 0; +- LIST_FOREACH(np, &lldp_head, lldp) { +- if (np->ops->print_tlv(tlvid, tlv_len, ibuf + offset)) { +- printed = 1; +- break; +- } +- } +- +- if (!printed) { +- if (tlvid < INVALID_TLVID) +- printf("Unidentified TLV\n\ttype:%d %*.*s\n", +- tlv_type, tlv_len*2, tlv_len*2, +- ibuf+offset); +- else +- printf("Unidentified Org Specific TLV\n\t" +- "OUI: 0x%06x, Subtype: %d, Info: %*.*s\n", +- tlvid >> 8, tlvid & 0x0ff, +- tlv_len*2-8, tlv_len*2-8, +- ibuf+offset); +- } +- if (tlvid > INVALID_TLVID) +- offset += (2 * tlv_len - 8); +- else +- offset += 2 * tlv_len; +- ilen -= 2 * tlv_len; +- if (tlvid == END_OF_LLDPDU_TLV) +- break; ++ strncpy(tmp_ibuf, ibuf + offset, vsi_len); ++ tmp_ibuf[vsi_len] = '\0'; ++ printf("%s %d:\n", "VSI ", vsi_cnt); ++ get_vsi_args(tmp_ibuf); ++ offset += vsi_len; ++ ilen -= vsi_len; ++ vsi_cnt++; + } + } + +-/* Print reply from get command */ +-static void print_tlvs(struct cmd *cmd, char *ibuf) +-{ +- if (cmd->ops & op_config) { +- print_arg_value(ibuf); +- return; +- } +- print_tlv2(ibuf); +-} +- + static void print_cmd_response(char *ibuf, int status) + { + struct cmd cmd; +@@ -455,7 +385,7 @@ static void print_cmd_response(char *ibuf, int status) + + switch (cmd.cmd) { + case cmd_gettlv: +- print_tlvs(&cmd, ibuf + ioff); ++ print_all_vsis(ibuf + ioff); + break; + case cmd_settlv: + printf("%s", ibuf + ioff); +@@ -708,7 +638,7 @@ static int _clif_command(struct clif *clif, char *cmd, int print) + size_t len; + int ret; + int rc; +- char reply[100]; ++ char reply[200]; + size_t reply_len2 = sizeof(reply); + + print_raw_message(cmd, print); +-- +2.1.0 + diff --git a/SOURCES/open-lldp-v1.0.1-6-VDP-Support-in-VDP22-for-correct-error-code-status-t.patch b/SOURCES/open-lldp-v1.0.1-6-VDP-Support-in-VDP22-for-correct-error-code-status-t.patch new file mode 100644 index 0000000..0c54df6 --- /dev/null +++ b/SOURCES/open-lldp-v1.0.1-6-VDP-Support-in-VDP22-for-correct-error-code-status-t.patch @@ -0,0 +1,894 @@ +From faf19bd8bdb1a6ca0dd98843cd09fd96b1f2f901 Mon Sep 17 00:00:00 2001 +From: padkrish +Date: Wed, 21 Jan 2015 03:37:57 +0000 +Subject: [PATCH] VDP: Support in VDP22 for correct error code/status to + vdptool + +This commit has the following changes: +a. Returning the status or error code to vdptool for the error cases. Errors +can be Tx error, invalid parameters, incorrect configuration etc. The vdptool + is modified to print the error messages from lldpad. +b. Modify the vdptool option from set-tlv/get-tlv to set-vsi/get-vsi. The + vdptool man page document is also modified accordingly. +c. Re-arrange the definitions in header files. +d. Fix some formatting issues. + +Signed-off-by: padkrish +Signed-off-by: John Fastabend +--- + docs/vdptool.8 | 12 ++-- + include/lldpad_status.h | 25 +++++---- + include/qbg_vdp22.h | 50 +++++++++-------- + include/qbg_vdp22_clif.h | 8 +++ + include/qbg_vdp22def.h | 39 +++++++++++++ + qbg/vdp22.c | 20 ++++++- + qbg/vdp22_cmds.c | 63 +++++++++++++++------ + qbg/vdp22sm.c | 15 ----- + qbg/vdp_ascii.c | 56 +++++++++++++++---- + vdptool.c | 141 ++++++++++++++++++++++++++++++++++++++--------- + 10 files changed, 316 insertions(+), 113 deletions(-) + +diff --git a/docs/vdptool.8 b/docs/vdptool.8 +index 02b4e8e..0b50a13 100644 +--- a/docs/vdptool.8 ++++ b/docs/vdptool.8 +@@ -98,7 +98,7 @@ Wait for the bridge response message + .SS VSI Parameter + Each VDP22 TLVs contains a command mode, manager identifier, + type identifier, type identifier version, VSI instance identifier, +-migiration hints and filter information. ++migration hints and filter information. + The fields are explained next: + .TP + .B "mode (Command Mode):" +@@ -140,7 +140,7 @@ an UUID according to RFC 4122 + with optional dashes in between. + .TP + .B "hints (Migration Hints):" +-The migiration hints is a string aiding in ++The migration hints is a string aiding in + migration of virtual machines: + .RS + .IP none: +@@ -193,11 +193,11 @@ show usage information + .B \-v, version + show version information + .TP +-.B \-t, get-tlv +-get TLV information for the specified interface ++.B \-t, get-vsi ++get VSI information for the specified interface + .TP +-.B \-T, set-tlv +-set TLV information for the specified interface ++.B \-T, set-vsi ++set VSI information for the specified interface + .TP + .B \-p, ping + display the process identifier of the running lldpad process +diff --git a/include/lldpad_status.h b/include/lldpad_status.h +index df6e0f7..568063b 100644 +--- a/include/lldpad_status.h ++++ b/include/lldpad_status.h +@@ -33,18 +33,19 @@ + #define LLDPAD_STATUS_H + + typedef enum { +- cmd_success = 0, +- cmd_failed, +- cmd_device_not_found, +- cmd_agent_not_found, +- cmd_invalid, +- cmd_bad_params, +- cmd_peer_not_present, +- cmd_ctrl_vers_not_compatible, +- cmd_not_capable, +- cmd_not_applicable, +- cmd_no_access, +- cmd_agent_not_supported, ++ cmd_success = 0, ++ cmd_failed, ++ cmd_device_not_found, ++ cmd_agent_not_found, ++ cmd_invalid, ++ cmd_bad_params, ++ cmd_peer_not_present, ++ cmd_ctrl_vers_not_compatible, ++ cmd_not_capable, ++ cmd_not_applicable, ++ cmd_no_access, ++ cmd_agent_not_supported, ++ cmd_max_status, + } cmd_status; + + #endif /* LLDPAD_STATUS_H */ +diff --git a/include/qbg_vdp22.h b/include/qbg_vdp22.h +index af0aa15..6c3c9ee 100644 +--- a/include/qbg_vdp22.h ++++ b/include/qbg_vdp22.h +@@ -65,22 +65,36 @@ enum vdp22_role { /* State for VDP22 bridge processing */ + VDP22_STATION /* State role */ + }; + +-enum vdp22_cmdresp { /* VDP22 Protocol command responses */ +- VDP22_RESP_SUCCESS = 0, /* Success */ +- VDP22_RESP_INVALID_FORMAT = 1, +- VDP22_RESP_NO_RESOURCES = 2, +- VDP22_RESP_NO_VSIMGR = 3, /* No contact to VSI manager */ +- VDP22_RESP_OTHER = 4, /* Other reasons */ +- VDP22_RESP_NOADDR = 5, /* Invalid VID, MAC, GROUP etc */ +- VDP22_RESP_DEASSOC = 252, /* Deassoc response */ +- VDP22_RESP_TIMEOUT = 253, /* Timeout response */ +- VDP22_RESP_KEEP = 254, /* Keep response */ +- VDP22_RESP_NONE = 255 /* No response returned so far */ ++/* ++ * VSI information. One node per matching entry (same mgrid, type_id, type_ver, ++ * id_fmt, id and fif). Filter data can be added and removed. ++ */ ++enum vsi22_flags { /* Flags (or'ed in) */ ++ VDP22_BUSY = 1, /* This node is under work */ ++ VDP22_DELETE_ME = 2, /* Deallocate this node */ ++ VDP22_RETURN_VID = 4, /* Return wildcard vlan id */ ++ VDP22_NOTIFY = 8, /* Send netlink message to requestor */ ++ VDP22_NLCMD = 16 /* Netlink command pending */ ++}; ++ ++enum { /* VDP22 Protocol command responses */ ++ USEC_PER_SEC = 1000000, /* Microseconds per second */ ++ VDP22_RESBIT = 0x80, /* VSI reserved bit */ ++ VDP22_ACKBIT = 0x40, /* VSI Acknowledgement bit */ ++ VDP22_KEEPBIT = 0x20, /* VSI keep error bit */ ++ VDP22_HARDBIT = 0x10, /* VSI hard error bit */ ++ VDP22_STATUS_MASK = 0x0f, /* Status mask */ ++ VDP22_STATUS_SHIFT = 0, /* Status offset */ + }; + + enum { + VDP22_MGRIDSZ = 16, /* Size of manager identifier */ +- VDP22_IDSZ = 16 /* Size of vsi identifier */ ++ VDP22_IDSZ = 16, /* Size of vsi identifier */ ++}; ++ ++struct vdp22_ptlv { /* Packed TLV for VDP data exchange */ ++ unsigned short head; /* TLV 16 bit header */ ++ unsigned char data[]; /* TLV Data buffer */ + }; + + struct vsi_origin { /* Originator of VSI request */ +@@ -99,18 +113,6 @@ struct fid22 { /* Filter data: GROUP,MAC,VLAN entry */ + struct vsi_origin requestor; + }; + +-/* +- * VSI information. One node per matching entry (same mgrid, type_id, type_ver, +- * id_fmt, id and fif). Filter data can be added and removed. +- */ +-enum vsi22_flags { /* Flags (or'ed in) */ +- VDP22_BUSY = 1, /* This node is under work */ +- VDP22_DELETE_ME = 2, /* Deallocate this node */ +- VDP22_RETURN_VID = 4, /* Return wildcard vlan id */ +- VDP22_NOTIFY = 8, /* Send netlink message to requestor */ +- VDP22_NLCMD = 16 /* Netlink command pending */ +-}; +- + struct vdp22smi { /* Data structure for VDP22 state machine */ + int state; /* State of VDP state machine for VSI */ + bool kato; /* VSI KA ACK timeout hit for this VSI */ +diff --git a/include/qbg_vdp22_clif.h b/include/qbg_vdp22_clif.h +index 8346b98..0cc603e 100644 +--- a/include/qbg_vdp22_clif.h ++++ b/include/qbg_vdp22_clif.h +@@ -33,6 +33,8 @@ + #define OP_FID_POS 8 /* Second Byte */ + #define OP_OUI_POS 16 /* Third Byte */ + ++#include "lldpad_status.h" ++ + typedef enum { + cmd_getstats, + cmd_gettlv, +@@ -60,5 +62,11 @@ typedef enum { + */ + } vdp22_op; + ++enum vdp22_cmd_status { ++ cmd_vdp_prot_no_support = cmd_max_status + 1, ++ cmd_vdp_nomem, ++ cmd_vdp_busy, ++}; ++ + struct lldp_module *vdp22_cli_register(void); + #endif +diff --git a/include/qbg_vdp22def.h b/include/qbg_vdp22def.h +index ff4270c..c305a2b 100644 +--- a/include/qbg_vdp22def.h ++++ b/include/qbg_vdp22def.h +@@ -94,6 +94,31 @@ enum vsi_key_arg { + VSI_INVALID_ARG + }; + ++enum vdp22_cmdresp { /* VDP22 Protocol command responses */ ++ VDP22_RESP_SUCCESS = 0, /* Success */ ++ VDP22_RESP_INVALID_FORMAT = 1, ++ VDP22_RESP_NO_RESOURCES = 2, ++ VDP22_RESP_NO_VSIMGR = 3, /* No contact to VSI manager */ ++ VDP22_RESP_OTHER = 4, /* Other reasons */ ++ VDP22_RESP_NOADDR = 5, /* Invalid VID, MAC, GROUP etc */ ++ VDP22_RESP_DEASSOC = 252, /* Deassoc response */ ++ VDP22_RESP_TIMEOUT = 253, /* Timeout response */ ++ VDP22_RESP_KEEP = 254, /* Keep response */ ++ VDP22_RESP_NONE = 255 /* No response returned so far */ ++}; ++ ++/* ++ * Errors applicable mostly for VDP22_RESP_NONE ++ */ ++ ++enum vdp22_cmderr { ++ VDP22_KATO = 0, ++ VDP22_ACKTO, ++ VDP22_TXERR ++}; ++ ++#define VDP22_STATUS_BITS 8 /* Number of bits in Status field */ ++ + #define VSI22_ARG_MODE_STR "mode" + #define VSI22_ARG_MGRID_STR "mgrid2" + #define VSI22_ARG_TYPEID_STR "typeid" +@@ -105,4 +130,18 @@ enum vsi_key_arg { + #define VSI22_ARG_FILTER_STR "filter" + #define VSI22_ARG_OUI_STR "oui" + ++#define VSI22_KATO_ERR_STR "Keepalive Timeout" ++#define VSI22_ACKTO_ERR_STR "Ack not received from bridge" ++#define VSI22_TX_ERR_STR "Transmission Error" ++ ++#define VSI22_INVALID_FRMT_ERR_STR "VDP TLV Format is Invalid" ++#define VSI22_NO_RES_ERR_STR "Insufficient resources at bridge" ++#define VSI22_NO_VSIMGR_ERR_STR "Unable to contact VSI Mgr" ++#define VSI22_OTHER_ERR_STR "Other Failures" ++#define VSI22_NOADDR_ERR_STR "Invalid VID, GroupID or MAC address field" ++#define VSI22_DEASS_ERR_STR "Deassoc received from switch" ++#define VSI22_TIMEOUT_ERR_STR "Timeout Error" ++#define VSI22_KEEP_ERR_STR "Command rejected by bridge and state prior to" \ ++ " requested command is kept" ++ + #endif +diff --git a/qbg/vdp22.c b/qbg/vdp22.c +index af11af8..d7aa648 100644 +--- a/qbg/vdp22.c ++++ b/qbg/vdp22.c +@@ -42,6 +42,7 @@ + #include "qbg_vdp22.h" + #include "qbg_utils.h" + #include "qbg_vdp22_cmds.h" ++#include "qbg_vdp22def.h" + + /* + * VDP22 helper functions +@@ -469,7 +470,8 @@ static bool filter_ok(unsigned char ffmt, struct fid22 *fp, + else + rc = false; + } +- LLDPAD_DBG("%s:rc:%d\n", __func__, rc); ++ LLDPAD_DBG("%s: ffmt:%d gpid_on:%d rc:%d\n", __func__, ffmt, ++ gpid_on, rc); + return rc; + } + +@@ -1007,12 +1009,26 @@ static pid_t havepid(struct vsi22 *vsi) + return mypid; + } + ++unsigned char vdp22_getsm_errcode(struct vsi22 *vsi) ++{ ++ unsigned char err_code = 0; ++ ++ if (vsi->smi.kato) ++ err_code |= (1 << VDP22_KATO); ++ if (vsi->smi.acktimeout) ++ err_code |= (1 << VDP22_ACKTO); ++ if (vsi->smi.txmit_error) ++ err_code |= (1 << VDP22_TXERR); ++ return err_code; ++} ++ + /* + * Convert and VSI22 to VDP netlink format and send it back to the originator. + */ + static int vdp22_back(struct vsi22 *vsi, pid_t to, + int (*fct)(struct vdpnl_vsi *)) + { ++ unsigned char err_code; + int i; + struct vdpnl_vsi nl; + struct vdpnl_mac nlmac[vsi->no_fdata]; +@@ -1025,6 +1041,8 @@ static int vdp22_back(struct vsi22 *vsi, pid_t to, + memcpy(nl.ifname, vsi->vdp->ifname, sizeof(nl.ifname)); + nl.request = vsi->vsi_mode; + nl.response = vsi->status; ++ err_code = vdp22_getsm_errcode(vsi); ++ nl.response |= (err_code << VDP22_STATUS_BITS); + nl.vsi_mgrid = vsi->mgrid[0]; + memcpy(nl.vsi_mgrid2, vsi->mgrid, sizeof(nl.vsi_mgrid2)); + nl.vsi_typeversion = vsi->type_ver; +diff --git a/qbg/vdp22_cmds.c b/qbg/vdp22_cmds.c +index 409858d..5d5ef6b 100644 +--- a/qbg/vdp22_cmds.c ++++ b/qbg/vdp22_cmds.c +@@ -165,7 +165,8 @@ static int handle_set_arg(struct cmd *cmd, char *arg, char *argvalue, + * bb: C for command and 2 or 3 for message version number + * cc: 1 for get command and 2 for set command + * dddddddd: 8 hex digits options, supported are op_arg, op_argval, op_conifg +- * and op_local ++ * and op_local. The number of filter (fid) parameters are encoded ++ * here (second byte from right). + * ee: 2 hex digit length of interface name + * ffff: string for interface name + * gg: 2 hex digit for bridge type (nearest customer bridge only) +@@ -179,7 +180,7 @@ static int handle_set_arg(struct cmd *cmd, char *arg, char *argvalue, + * The total input length can be used to determine the number of arguaments. + * + * The member ops of struct cmd settings depends on the invoked with +- * -T (cmd_gettlv) -a assoc: ++ * -T (cmd_getvsi) -a assoc: + * -c key --> ops=(0x15) op_config,op_arg,op_local), numargs > 0 + * -c key=abc --> ops=(0x1d) op_config,op_arg,op_argval,op_local), numargs > 0 + * -c --> ops=0x11 (op_config,op_local), numargs = 0 +@@ -279,8 +280,16 @@ int vdp22_clif_cmd(UNUSED void *data, UNUSED struct sockaddr_un *from, + int vdp22_sendevent(struct vdpnl_vsi *p) + { + char msg[MAX_CLIF_MSGBUF]; ++ char tmp_buf[MAX_CLIF_MSGBUF]; ++ int c, len; + +- vdp_vdpnl2str(p, msg, sizeof(msg)); ++ vdp_vdpnl2str(p, tmp_buf, sizeof(msg)); ++ len = strlen(tmp_buf); ++ if ((unsigned)len > sizeof(msg)) ++ return 0; ++ c = snprintf(msg, sizeof(msg), "%04x%s", len, tmp_buf); ++ if ((c < 0) || ((unsigned)c >= sizeof(msg))) ++ return 0; + LLDPAD_DBG("%s:%s vsi:%p(%#2x), len:%zd msg:%s\n", __func__, + p->ifname, p, p->vsi_uuid[0], strlen(msg), msg); + send_event(16, LLDP_MOD_VDP22, msg); +@@ -324,6 +333,29 @@ static int ifok(struct cmd *cmd) + return good_cmd; + } + ++static int get_vdp22_retval(int rc) ++{ ++ if (!rc) ++ return cmd_success; ++ ++ switch (rc) { ++ case -EPROTONOSUPPORT: ++ return cmd_vdp_prot_no_support; ++ case -EOPNOTSUPP: ++ return cmd_not_capable; ++ case -EINVAL: ++ return cmd_bad_params; ++ case -ENOMEM: ++ return cmd_vdp_nomem; ++ case -EBUSY: ++ return cmd_vdp_busy; ++ case -ENODEV: ++ return cmd_device_not_found; ++ default: ++ return cmd_failed; ++ } ++} ++ + static int set_arg_vsi3(struct cmd *cmd, char *argvalue, bool test, int size) + { + cmd_status good_cmd = vdp22_cmdok(cmd, cmd_settlv); +@@ -340,7 +372,7 @@ static int set_arg_vsi3(struct cmd *cmd, char *argvalue, bool test, int size) + vsi.macsz = size; + rc = vdp_str2vdpnl(argvalue, &vsi, cmd->ifname); + if (rc) { +- good_cmd = cmd_bad_params; ++ good_cmd = get_vdp22_retval(rc); + goto out; + } + if (!port_find_by_ifindex(get_ifidx(cmd->ifname))) { +@@ -351,12 +383,8 @@ static int set_arg_vsi3(struct cmd *cmd, char *argvalue, bool test, int size) + if (good_cmd != cmd_success || test) + goto out; + rc = vdp22_request(&vsi, 1); +- if (!rc) +- good_cmd = cmd_success; +- else if (rc == -ENODEV) +- good_cmd = cmd_device_not_found; +- else +- good_cmd = cmd_failed; ++ good_cmd = get_vdp22_retval(rc); ++ + out: + return good_cmd; + } +@@ -480,7 +508,8 @@ static int get_vsi_partial_arg(UNUSED char *arg, char *orig_argvalue, + int rc = -ENOMEM, len, c; + u16 vsi_arg_key_flags = 0; + +- if (vdp22_parse_str_vdpnl(vsinl, &vsi_arg_key_flags, orig_argvalue)) ++ rc = vdp22_parse_str_vdpnl(vsinl, &vsi_arg_key_flags, orig_argvalue); ++ if (rc) + goto out; + vdp = vdp22_getvdp(vsinl->ifname); + if (!vdp) +@@ -498,7 +527,6 @@ 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); + if ((c < 0) || ((unsigned)c >= (out_len - used))) + goto out_delvsi; + if (rc) +@@ -544,11 +572,14 @@ static int get_arg_vsi(struct cmd *cmd, char *arg, char *argvalue, + memset(&mac, 0, sizeof(mac)); + vsi.macsz = fsize; + vsi.maclist = mac; +- if (!get_vsi_partial_arg(arg, argvalue, &vsi, vsi_str, +- sizeof(vsi_str))) +- goto out; +- } else if (!catvsis(&vsi, vsi_str, sizeof(vsi_str))) ++ rc = get_vsi_partial_arg(arg, argvalue, &vsi, vsi_str, ++ sizeof(vsi_str)); ++ } else ++ rc = catvsis(&vsi, vsi_str, sizeof(vsi_str)); ++ if (!rc) { ++ good_cmd = get_vdp22_retval(rc); + goto out; ++ } + rc = snprintf(obuf, obuf_len, "%s", vsi_str); + if (rc > 0 || rc < obuf_len) + good_cmd = cmd_success; +diff --git a/qbg/vdp22sm.c b/qbg/vdp22sm.c +index 6264f74..83a97fb 100644 +--- a/qbg/vdp22sm.c ++++ b/qbg/vdp22sm.c +@@ -46,21 +46,6 @@ + #include "qbg_vdp22.h" + #include "qbg_utils.h" + +-struct vdp22_ptlv { /* Packed TLV for VDP data exchange */ +- unsigned short head; /* TLV 16 bit header */ +- unsigned char data[]; /* TLV Data buffer */ +-}; +- +-enum { /* VDP22 Protocol command responses */ +- USEC_PER_SEC = 1000000, /* Microseconds per second */ +- VDP22_RESBIT = 0x80, /* VSI reserved bit */ +- VDP22_ACKBIT = 0x40, /* VSI Acknowledgement bit */ +- VDP22_KEEPBIT = 0x20, /* VSI keep error bit */ +- VDP22_HARDBIT = 0x10, /* VSI hard error bit */ +- VDP22_STATUS_MASK = 0x0f, /* Status mask */ +- VDP22_STATUS_SHIFT = 0, /* Status offset */ +-}; +- + /* + * Set status code + */ +diff --git a/qbg/vdp_ascii.c b/qbg/vdp_ascii.c +index 76dde4a..70ec79b 100644 +--- a/qbg/vdp_ascii.c ++++ b/qbg/vdp_ascii.c +@@ -44,6 +44,7 @@ + #include "qbg_vdpnl.h" + #include "qbg_utils.h" + #include "lldp_util.h" ++#include "messages.h" + + struct vsi_keyword_handler vsi_key_handle[] = { + {VSI22_ARG_MODE_STR, VSI_MODE_ARG}, +@@ -285,6 +286,24 @@ enum vsi_key_arg get_keywork_val(char *keyword) + return VSI_INVALID_ARG; + } + ++/* ++ * If the ordering is maintained in vsi_key_handle, then this function is not ++ * necessary as the keyword can be retrieved using ++ * 'vsi_key_handle[keyval].keyword'. ++ */ ++ ++char *get_keyword_str(enum vsi_key_arg keyval) ++{ ++ int count, key_str_size; ++ ++ key_str_size = sizeof(vsi_key_handle) / sizeof(vsi_key_handle[0]); ++ for (count = 0; count < key_str_size; count++) { ++ if (vsi_key_handle[count].val == keyval) ++ return vsi_key_handle[count].keyword; ++ } ++ return NULL; ++} ++ + int vdp22_parse_str_vdpnl(struct vdpnl_vsi *vsi, u16 *key_flags, + char *orig_argvalue) + { +@@ -315,52 +334,57 @@ int vdp22_parse_str_vdpnl(struct vdpnl_vsi *vsi, u16 *key_flags, + numargs = get_arg_val_list(argvalue, ilen, &ioff, args, argvals); + if (numargs == 0) + goto out_free; ++ rc = -EINVAL; + for (i = 0; i < numargs; i++) { + vsi_key = get_keywork_val(args[i]); + switch (vsi_key) { + case VSI_MODE_ARG: + if (!argvals[i] || !getmode(vsi, argvals[i])) +- goto out_free; ++ goto out_err; + break; + case VSI_MGRID2_ARG: + if (!argvals[i] || !getmgr2id(vsi, argvals[i])) +- goto out_free; ++ goto out_err; + break; + case VSI_TYPEID_ARG: + if (!argvals[i] || + !getnumber(argvals[i], 0, 0xffffff, &no)) +- goto out_free; ++ goto out_err; + vsi->vsi_typeid = no; + break; + case VSI_TYPEIDVER_ARG: + if (!argvals[i] || !getnumber(argvals[i], 0, 0xff, &no)) +- goto out_free; ++ goto out_err; + vsi->vsi_typeversion = no; + break; + case VSI_VSIID_ARG: + if (!argvals[i] || + vdp_str2uuid(vsi->vsi_uuid, argvals[i], + sizeof(vsi->vsi_uuid))) +- goto out_free; ++ goto out_err; + vsi->vsi_idfmt = VDP22_ID_UUID; + break; + case VSI_FILTER_ARG: + if (idx < vsi->macsz && !getfid(vsi, argvals[i], idx)) +- goto out_free; ++ goto out_err; + idx++; + break; + case VSI_HINTS_ARG: + if (!argvals[i] || !gethints(vsi, argvals[i])) +- goto out_free; ++ goto out_err; + break; + default: +- goto out_free; ++ goto out_err; + } + num_arg_keys |= (1 << vsi_key); + } + *key_flags = num_arg_keys; + rc = 0; + ++out_err: ++ if (rc) ++ LLDPAD_ERR("Incorrect arguments specified for key %s\n", ++ get_keyword_str(vsi_key)); + out_free: + free(argvals); + out_args: +@@ -400,11 +424,16 @@ static int str2vdpnl(char *orig_argvalue, struct vdpnl_vsi *vsi) + u16 vsi_mand_mask = (1 << VSI_MAND_NUM_ARG) - 1; + u16 num_arg_keys = 0; + +- if (vdp22_parse_str_vdpnl(vsi, &num_arg_keys, orig_argvalue)) ++ rc = vdp22_parse_str_vdpnl(vsi, &num_arg_keys, orig_argvalue); ++ if (rc) { ++ LLDPAD_ERR("%s: Incorrect arguments\n", __func__); + goto out; ++ } + /* Return error if no filter information provided */ + if ((num_arg_keys & vsi_mand_mask) == vsi_mand_mask) + rc = 0; ++ else ++ LLDPAD_ERR("%s: Incomplete arguments\n", __func__); + out: + return rc; + } +@@ -444,7 +473,6 @@ static char *check_and_update(size_t *total, size_t *length, char *s, int c) + /* + * Convert VSI association to string. + */ +-#ifdef LATER_USE + static const char *mode2str(unsigned char x) + { + if (x == VDP22_ASSOC) +@@ -457,7 +485,6 @@ static const char *mode2str(unsigned char x) + return "deassoc"; + return "unknown"; + } +-#endif + + /* + * Convert filter information format into vlan[-mac][-group] string. +@@ -544,7 +571,12 @@ int vdp_vdpnl2str(struct vdpnl_vsi *p, char *s, size_t length) + char instance[VDP_UUID_STRLEN + 2]; + + mgrid2str(instance, p, sizeof(instance)); +- c = snprintf(s, length, "%02x%s%04x%s%02x%s%04x%lu%02x%s%04x%d", ++ c = snprintf(s, length, "%02x%s%04x%s%02x%s%04x%s%02x%s%04x%lu%02x%s" ++ "%04x%d", ++ (unsigned int)strlen(VSI22_ARG_MODE_STR), ++ VSI22_ARG_MODE_STR, ++ (unsigned int)strlen(mode2str(p->request)), ++ mode2str(p->request), + (unsigned int)strlen(VSI22_ARG_MGRID_STR), + VSI22_ARG_MGRID_STR, + (unsigned int)strlen(instance), instance, +diff --git a/vdptool.c b/vdptool.c +index 551e829..f7fd288 100644 +--- a/vdptool.c ++++ b/vdptool.c +@@ -54,6 +54,28 @@ + #include "qbg22.h" + #include "qbg_vdp22_clif.h" + #include "lldp_util.h" ++#include "qbg_vdp22def.h" ++ ++static char *print_vdp_status(enum vdp22_cmd_status status) ++{ ++ char *str; ++ ++ switch (status) { ++ case cmd_vdp_prot_no_support: ++ str = "VDP protocol not supported on interface"; ++ break; ++ case cmd_vdp_nomem: ++ str = "Not enough memory"; ++ break; ++ case cmd_vdp_busy: ++ str = "VSI association in progress"; ++ break; ++ default: ++ str = "Unknown status"; ++ break; ++ } ++ return str; ++} + + static char *print_status(cmd_status status) + { +@@ -97,7 +119,7 @@ static char *print_status(cmd_status status) + str = "TLV does not support agent type"; + break; + default: +- str = "Unknown status"; ++ str = print_vdp_status(status); + break; + } + return str; +@@ -165,7 +187,7 @@ static int render_cmd(struct cmd *cmd, int argc, char **args, char **argvals) + + int vdp_clif_command(struct clif *, char *, int); + +-static int vdp_cmd_gettlv(struct clif *clif, int argc, char *argv[], ++static int vdp_cmd_getvsi(struct clif *clif, int argc, char *argv[], + struct cmd *cmd, int raw) + { + int numargs = 0; +@@ -219,7 +241,7 @@ out: + return cmd_invalid; + } + +-static int vdp_cmd_settlv(struct clif *clif, int argc, char *argv[], ++static int vdp_cmd_setvsi(struct clif *clif, int argc, char *argv[], + struct cmd *cmd, int raw) + { + int numargs = 0; +@@ -299,12 +321,77 @@ static int vdp_parse_response(char *buf) + return hex2u8(buf + CLIF_STAT_OFF); + } + +-int get_vsi_args(char *ibuf) ++void print_vsi_err_msg(char *key_val) ++{ ++ unsigned long errcode; ++ int resp_err, smi_err; ++ ++ errcode = strtol(key_val, NULL, 10); ++ resp_err = errcode & 0xff; ++ smi_err = (errcode >> VDP22_STATUS_BITS) & 0xff; ++ ++ switch (resp_err) { ++ case VDP22_RESP_INVALID_FORMAT: ++ printf("\tError returned by Bridge: %s\n", ++ VSI22_INVALID_FRMT_ERR_STR); ++ break; ++ case VDP22_RESP_NO_RESOURCES: ++ printf("\tError returned by Bridge: %s\n", ++ VSI22_NO_RES_ERR_STR); ++ break; ++ case VDP22_RESP_NO_VSIMGR: ++ printf("\tError returned by Bridge: %s\n", ++ VSI22_NO_VSIMGR_ERR_STR); ++ break; ++ case VDP22_RESP_OTHER: ++ printf("\tError returned by Bridge: %s\n", VSI22_OTHER_ERR_STR); ++ break; ++ case VDP22_RESP_NOADDR: ++ printf("\tError returned by Bridge: %s\n", ++ VSI22_NOADDR_ERR_STR); ++ break; ++ case VDP22_RESP_DEASSOC: ++ printf("\tError returned by Bridge: %s\n", VSI22_DEASS_ERR_STR); ++ break; ++ case VDP22_RESP_TIMEOUT: ++ printf("\tError returned by Bridge: %s\n", ++ VSI22_TIMEOUT_ERR_STR); ++ break; ++ case VDP22_RESP_KEEP: ++ printf("\tError returned by Bridge: %s\n", VSI22_KEEP_ERR_STR); ++ break; ++ default: ++ break; ++ } ++ if (smi_err & (1 << VDP22_KATO)) ++ printf("\tInternal Error : %s\n", VSI22_KATO_ERR_STR); ++ if (smi_err & (1 << VDP22_ACKTO)) ++ printf("\tInternal Error : %s\n", VSI22_ACKTO_ERR_STR); ++ if (smi_err & (1 << VDP22_TXERR)) ++ printf("\tInternal Error : %s\n", VSI22_TX_ERR_STR); ++} ++ ++static void print_vsi(char **args, char **argvals, int numargs, ++ bool err_flag) ++{ ++ int i; ++ ++ for (i = 0; i < numargs; i++) { ++ 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]); ++ } ++ } ++} ++ ++int get_vsi_args(char *ibuf, bool print_err_code) + { + int ioff = 0; + char **args; + char **argvals; +- int numargs, i; ++ int numargs; + int ilen = strlen(ibuf); + + /* count args and argvalus */ +@@ -321,17 +408,14 @@ int get_vsi_args(char *ibuf) + } + + numargs = get_arg_val_list(ibuf, ilen, &ioff, args, argvals); +- for (i = 0; i < numargs; i++) { +- printf("\t%s", args[i]); +- printf(" = %s\n", argvals[i]); +- } ++ print_vsi(args, argvals, numargs, print_err_code); + + free(args); + free(argvals); + return ioff; + } + +-static void print_all_vsis(char *ibuf) ++static void print_all_vsis(char *ibuf, bool err_code, char *msg) + { + size_t ilen = strlen(ibuf); + u16 vsi_len; +@@ -346,8 +430,11 @@ static void print_all_vsis(char *ibuf) + ilen -= 2 * sizeof(u16); + strncpy(tmp_ibuf, ibuf + offset, vsi_len); + tmp_ibuf[vsi_len] = '\0'; +- printf("%s %d:\n", "VSI ", vsi_cnt); +- get_vsi_args(tmp_ibuf); ++ if (msg) ++ printf("%s\n", msg); ++ else ++ printf("%s %d:\n", "VSI ", vsi_cnt); ++ get_vsi_args(tmp_ibuf, err_code); + offset += vsi_len; + ilen -= vsi_len; + vsi_cnt++; +@@ -361,7 +448,7 @@ static void print_cmd_response(char *ibuf, int status) + int ioff; + + if (status != cmd_success) { +- printf("%s\n", print_status(status)); ++ printf("FAILED: %s\n", print_status(status)); + return; + } + +@@ -385,7 +472,7 @@ static void print_cmd_response(char *ibuf, int status) + + switch (cmd.cmd) { + case cmd_gettlv: +- print_all_vsis(ibuf + ioff); ++ print_all_vsis(ibuf + ioff, false, NULL); + break; + case cmd_settlv: + printf("%s", ibuf + ioff); +@@ -423,6 +510,7 @@ static void vdp_print_response(char *buf, int status) + static void vdp_print_event_msg(char *buf) + { + printf("%s buf:%s\n", __func__, buf); ++ print_all_vsis(buf + CLIF_RSP_OFF, true, "Response from VDP"); + } + + /* +@@ -519,8 +607,8 @@ static const char *commands_help = + " -v|version show version\n" + " -p|ping ping lldpad and query pid of lldpad\n" + " -q|quit exit lldptool (interactive mode)\n" +-" -t|get-tlv get tlvid value\n" +-" -T|set-tlv set arg for tlvid to value\n"; ++" -t|get-vsi get VSI association(s)\n" ++" -T|set-vsi set VSI association\n"; + + static struct clif *clif_conn; + static int cli_quit; +@@ -638,7 +726,7 @@ static int _clif_command(struct clif *clif, char *cmd, int print) + size_t len; + int ret; + int rc; +- char reply[200]; ++ char reply[MAX_CLIF_MSGBUF]; + size_t reply_len2 = sizeof(reply); + + print_raw_message(cmd, print); +@@ -653,7 +741,8 @@ static int _clif_command(struct clif *clif, char *cmd, int print) + printf("'%s' command timed out.\n", cmd); + return -2; + } else if (ret < 0) { +- printf("'%s' command failed.\n", cmd); ++ printf("'%s' command failed with error %s.\n", cmd, ++ strerror(errno)); + return -1; + } + if (print) { +@@ -662,10 +751,8 @@ static int _clif_command(struct clif *clif, char *cmd, int print) + } + if (cli_attached) { + rc = clif_vsievt(clif, reply, &reply_len2, 5); +- printf("\nReturn from vsievt %d ret %d Reply %s\n", rc, ret, +- reply); + if (!rc) +- printf("\nMsg is %s\n", reply); ++ print_all_vsis(reply, true, "Response from VDP"); + } + + return ret; +@@ -739,10 +826,10 @@ static struct cli_cmd { + { cmd_license, "license", cli_cmd_license }, + { cmd_version, "version", cli_cmd_version }, + { cmd_quit, "quit", cli_cmd_quit }, +- { cmd_gettlv, "gettlv", vdp_cmd_gettlv }, +- { cmd_gettlv, "get-tlv", vdp_cmd_gettlv }, +- { cmd_settlv, "settlv", vdp_cmd_settlv }, +- { cmd_settlv, "set-tlv", vdp_cmd_settlv }, ++ { cmd_gettlv, "getvsi", vdp_cmd_getvsi }, ++ { cmd_gettlv, "get-vsi", vdp_cmd_getvsi }, ++ { cmd_settlv, "setvsi", vdp_cmd_setvsi }, ++ { cmd_settlv, "set-vsi", vdp_cmd_setvsi }, + { cmd_nop, NULL, cli_cmd_nop } + }; + +@@ -774,8 +861,8 @@ static struct option lldptool_opts[] = { + {"help", 0, NULL, 'h'}, + {"version", 0, NULL, 'v'}, + {"stats", 0, NULL, 'S'}, +- {"get-tlv", 0, NULL, 't'}, +- {"set-tlv", 0, NULL, 'T'}, ++ {"get-vsi", 0, NULL, 't'}, ++ {"set-vsi", 0, NULL, 'T'}, + {"get-lldp", 0, NULL, 'l'}, + {"set-lldp", 0, NULL, 'L'}, + {0, 0, 0, 0} +-- +2.1.0 + diff --git a/SOURCES/open-lldp-v1.0.1-7-VDP-Support-for-OUI-infrastructure-in-VDP22.patch b/SOURCES/open-lldp-v1.0.1-7-VDP-Support-for-OUI-infrastructure-in-VDP22.patch new file mode 100644 index 0000000..aa2c193 --- /dev/null +++ b/SOURCES/open-lldp-v1.0.1-7-VDP-Support-for-OUI-infrastructure-in-VDP22.patch @@ -0,0 +1,158 @@ +From 64c9ba3c03c735e8031964edf52e148373ec29ce Mon Sep 17 00:00:00 2001 +From: padkrish +Date: Wed, 21 Jan 2015 03:38:24 +0000 +Subject: [PATCH] VDP: Support for OUI infrastructure in VDP22. + +This patch contains the header field changes for a general framework +for supporting OUI fields in VDP22 at the station side. The specific +changes are described below. + +qbg_vdpnl.h: +------------- +Couple of parameters are added to the vdpnl_vsi structure. One is +the number of OUI parameters. Generally, this will be 1, as the +chances of having different OUI in a single message for VDP22 is +quite low. Nevertheless, there's support for having multiple OUI +in a single VSI. The other field is a general structure of len,opaque +data format for carrying the OUI data. + +qbg_vdp22_oui.h: +---------------- +This is a new header file added for supporting the OUI framework. This +file contains the OUI specific sub-structures for vdpnl and vsi22 +structures and function handler structure.:w + +Signed-off-by: padkrish +Signed-off-by: John Fastabend +--- + Makefile.am | 3 ++- + include/qbg_vdp22.h | 4 ++++ + include/qbg_vdp22_oui.h | 46 ++++++++++++++++++++++++++++++++++++++++++++++ + include/qbg_vdp22def.h | 1 + + include/qbg_vdpnl.h | 2 ++ + 5 files changed, 55 insertions(+), 1 deletion(-) + create mode 100644 include/qbg_vdp22_oui.h + +diff --git a/Makefile.am b/Makefile.am +index fc4f8d6..403088b 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -69,7 +69,8 @@ lldp_8021qaz_cmds.c include/lldp_8021qaz_cmds.h \ + 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_vdp22def.h qbg/vdp22_cmds.c qbg/vdp_ascii.c \ ++include/qbg_vdp22_oui.h + + lib_LTLIBRARIES = liblldp_clif.la + liblldp_clif_la_LDFLAGS = -version-info 1:0:0 +diff --git a/include/qbg_vdp22.h b/include/qbg_vdp22.h +index 6c3c9ee..6585a10 100644 +--- a/include/qbg_vdp22.h ++++ b/include/qbg_vdp22.h +@@ -59,6 +59,7 @@ + #include + + #include ++#include + + enum vdp22_role { /* State for VDP22 bridge processing */ + VDP22_BRIDGE = 1, /* Bridge role */ +@@ -140,6 +141,8 @@ struct vsi22 { + unsigned char fif; /* Filter info format */ + unsigned short no_fdata; /* Entries in filter data */ + struct fid22 *fdata; /* Filter data variable length */ ++ unsigned short no_ouidata; /* Entries in OUI data */ ++ struct vdp22_oui_data_s *oui_str_data; /* OUI data variable length */ + struct vdp22 *vdp; /* Back pointer to VDP head */ + unsigned long flags; /* Flags, see above */ + struct vdp22smi smi; /* State machine information */ +@@ -189,6 +192,7 @@ void vdp22_stop_timers(struct vsi22 *); + int vdp22_start_localchange_timer(struct vsi22 *); + bool vdp22_cmp_fdata(struct vsi22 *, struct vsi22 *); + void vdp22_delete_vsi(struct vsi22 *); ++struct vdp22_oui_handler_s * vdp22_get_oui_hndlr(char *); + + /* + * Functions to get and set vlan identifier and qos. +diff --git a/include/qbg_vdp22_oui.h b/include/qbg_vdp22_oui.h +new file mode 100644 +index 0000000..0aeb7b9 +--- /dev/null ++++ b/include/qbg_vdp22_oui.h +@@ -0,0 +1,46 @@ ++/******************************************************************************* ++ ++ Implementation of OUI for VDP2.2 ++ Copyright (c) 2012-2014 by Cisco Systems, Inc. ++ ++ Author(s): Padmanabhan Krishnan ++ ++ 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_OUI_H__ ++#define __VDP22_OUI_H__ ++ ++#include ++ ++/* ++ * Generic OUI related defines ++ */ ++enum vdp22_oui { ++ VDP22_OUI_TYPE_LEN = 3, /* Size of OUI Type field */ ++ VDP22_OUI_MAX_NAME = 20, ++}; ++ ++struct vdp22_oui_data_s { ++ void *vsi_data; ++ unsigned char oui_type[VDP22_OUI_TYPE_LEN]; ++ char oui_name[VDP22_OUI_MAX_NAME]; ++ int len; ++ void *data; ++}; ++ ++#endif /* __VDP22_OUI_H__ */ +diff --git a/include/qbg_vdp22def.h b/include/qbg_vdp22def.h +index c305a2b..a2d2654 100644 +--- a/include/qbg_vdp22def.h ++++ b/include/qbg_vdp22def.h +@@ -91,6 +91,7 @@ enum vsi_key_arg { + VSI_FILTER_ARG, + VSI_MAND_NUM_ARG, + VSI_HINTS_ARG, ++ VSI_OUI_ARG, + VSI_INVALID_ARG + }; + +diff --git a/include/qbg_vdpnl.h b/include/qbg_vdpnl.h +index c5c93ed..bf18e71 100644 +--- a/include/qbg_vdpnl.h ++++ b/include/qbg_vdpnl.h +@@ -66,6 +66,8 @@ struct vdpnl_vsi { /* Data structure for VSI data via netlink */ + unsigned char filter_fmt; /* Filter format type */ + int macsz; /* Entries in mac-vlan pair list */ + struct vdpnl_mac *maclist; /* List of MAC-VLAN pairs */ ++ int ouisz; /* No of OUI entries */ ++ struct vdpnl_oui_data_s *oui_list; /* OUI Entries */ + }; + + int vdpnl_recv(unsigned char *, size_t); +-- +2.1.0 + diff --git a/SOURCES/open-lldp-v1.0.1-8-VDP-Support-for-OUI-infrastructure-in-vdptool.patch b/SOURCES/open-lldp-v1.0.1-8-VDP-Support-for-OUI-infrastructure-in-vdptool.patch new file mode 100644 index 0000000..674f448 --- /dev/null +++ b/SOURCES/open-lldp-v1.0.1-8-VDP-Support-for-OUI-infrastructure-in-vdptool.patch @@ -0,0 +1,355 @@ +From 321bfe6c5cbad58e97fbb2df3c93564c89f1e09b Mon Sep 17 00:00:00 2001 +From: padkrish +Date: Wed, 21 Jan 2015 03:38:53 +0000 +Subject: [PATCH] VDP: Support for OUI infrastructure in vdptool. + +This patch contains the changes made in vdptool to support OUI fields +in vdptool. This commit has only the infra-structure changes needed +for supporting OUI. No specific OUI fields are added as a part of this +commit. The man page for vdptool is also modified accordingly. + +The OUI data can be given as input to vdptool in different ways. It +could be + + vdptool .... -c oui=companyA,Data1 -c oui=companyB,Data2 -c oui=companyA,Data3 + + Or + + vdptool .... -c oui=companyA,Data1Data3 -c oui=companyB,data2 + +where companyA and companyB are the name of the Organizations. +Anything after the comma in OUI data field is Org specific and it's +upto the respective organization specific handlers to encode it so +that it could be decoded appropriately by the ORG specific handlers +inside lldpad. That is, Data1 and Data3 is specific to Organization +'companyA' and the OUI handlers of companyA in vdptool and lldpad is +responsible for encoding/decoding the data. The common code in vdptool +and lldpad just treats it as opaque data. 'companyA' or 'companyB' +above is the key using which the right handlers will be called. + +Irrespective of how the command line interface to vdptool is, the +input to lldpad is always the same. i.e. KeywordlenKeywordDatalenData +For OUI, the data field will have the complete OUI data starting with +ORG name (e.g companyA). So, in order to call the right handler +routine, the OUI data field is split as OUInamelenOUInameOUIData. + +OUInamelen is 2B. + +For example if the following is given: + +vdptool -T -W -i eth2 -V assoc \ + -c mode=assoc -c mgrid2=0 -c typeid=0 -c typeidver=0 \ + -c uuid=18ea3452-b364-4e13-a1a2-9c6524deb685 -c hints=none \ + -c filter=0-fa:16:3e:4c:2d:85-90001 -c oui=companyA,val1=data1 + +The data sent to lldpad by vdptool will be as follows assuming +companyA encode handlers in vdptool encodes it the same way: + +04mode0005assoc06mgrid20001006typeid0001009typeidver0001004uuid002418ea3452-b364-4e13-a1a2-9c6524deb68505hints0004none06filter00190-fa:16:3e:4c:2d:85-9000103oui001408companyAval1=data1 + +This commit will not insert the oui fields as given above because no OUI +specific handlers are added. + +Signed-off-by: padkrish +Signed-off-by: John Fastabend +--- + docs/vdptool.8 | 50 +++++++++++++++- + include/qbg_vdp22_oui.h | 11 ++++ + vdptool.c | 149 +++++++++++++++++++++++++++++++++++++++++++++--- + 3 files changed, 201 insertions(+), 9 deletions(-) + +diff --git a/docs/vdptool.8 b/docs/vdptool.8 +index 0b50a13..4580c71 100644 +--- a/docs/vdptool.8 ++++ b/docs/vdptool.8 +@@ -182,6 +182,31 @@ delimited by two slashes ('--'), + also known as filter information format 3. + For vlan and group details see (1) and (4). + .RE ++.TP ++.B "oui (Organizationally Unique Identifier):" ++This defines the optional Organizationally ++defined information field. This contains the ++specific sets of values for this entry. There ++can be multiple organizational specific fields, ++in which case there will be multiple keywords ++.I oui= ++followed by the values. ++The value is of the following format: ++.EX ++oui=OUI,[Organization specific values ] ++.EE ++The OUI specifies the name of the Organization ++that is responsible for defining ++this content. A comma is mandatory after the OUI ++field. The fields following this ++ is specified by the organization and ++hence will be decoded based on the value of this ++OUI field. Currently, the following values for ++OUI are supported. ++.RS ++.IP cisco - ++Specifies Cisco defined OUI. ++.TP + .SH COMMANDS + .TP + .B license +@@ -226,13 +251,33 @@ vdptool -i eth2 -T -V assoc -c mode=assoc -c mgrid2=blabla \\ + -c filter=2-52:00:00:11:22:33-200 + .fi + .TP +-Create a VSI association on interface eth2 and wait for the response from the bridge ++Create a VSI association on interface eth2 and wait for the ++response from the bridge + .br + .nf + vdptool -i eth2 -T -W -V assoc -c mode=assoc -c mgrid2=blabla \\ + -c typeid=5 -c uuid=1122 -c typeidver=4 -c hints=none \\ + -c filter=0-52:00:00:11:22:33-200 + .fi ++.TP ++Create a VSI association on interface eth2 wth OUI parameters ++and wait for the response from the bridge ++.br ++.nf ++vdptool -i eth2 -T -W -V assoc -c mode=assoc -c mgrid2=blabla \\ ++ -c typeid=5 -c uuid=1122 -c typeidver=4 -c hints=none \\ ++ -c filter=0-52:00:00:11:22:33-200 -c oui=CompanyA,data ++.fi ++.TP ++Create a VSI association on interface eth2 wth multiple OUI parameters ++and wait for the response from the bridge ++.br ++.nf ++vdptool -i eth2 -T -W -V assoc -c mode=assoc -c mgrid2=blabla \\ ++ -c typeid=5 -c uuid=1122 -c typeidver=4 -c hints=none \\ ++ -c filter=0-52:00:00:11:22:33-200 -c oui=CompanyA,data \\ ++ -c oui=CompanyB,data ++.fi + + .TP + Query all VSI association on interface eth2 +@@ -240,7 +285,8 @@ Query all VSI association on interface eth2 + vdptool -i eth2 -t -V assoc + + .TP +-Query VSI association on interface eth2 that matches specific VSI parameters. Any of the VSI parameters below can be omitted. ++Query VSI association on interface eth2 that matches specific ++VSI parameters. Any of the VSI parameters below can be omitted. + .br + vdptool -i eth2 -t -V assoc -t -V assoc -c mode=assoc \\ + -c mgrid2=blabla -c typeid=5 -c uuid=1122 \\ +diff --git a/include/qbg_vdp22_oui.h b/include/qbg_vdp22_oui.h +index 0aeb7b9..d31c6ad 100644 +--- a/include/qbg_vdp22_oui.h ++++ b/include/qbg_vdp22_oui.h +@@ -33,6 +33,7 @@ + enum vdp22_oui { + VDP22_OUI_TYPE_LEN = 3, /* Size of OUI Type field */ + VDP22_OUI_MAX_NAME = 20, ++ MAX_OUI_DATA_LEN = 200 + }; + + struct vdp22_oui_data_s { +@@ -43,4 +44,14 @@ struct vdp22_oui_data_s { + void *data; + }; + ++typedef struct vdptool_oui_data_s { ++ char oui_name[VDP22_OUI_MAX_NAME]; ++ char data[MAX_OUI_DATA_LEN]; ++} vdptool_oui_data_t; ++ ++typedef struct vdptool_oui_hndlr_tbl_s { ++ char *oui_name; ++ bool (*oui_cli_encode_hndlr)(char *dst, char *src, size_t len); ++} vdptool_oui_hndlr_tbl_t; ++ + #endif /* __VDP22_OUI_H__ */ +diff --git a/vdptool.c b/vdptool.c +index f7fd288..c857a85 100644 +--- a/vdptool.c ++++ b/vdptool.c +@@ -55,6 +55,22 @@ + #include "qbg_vdp22_clif.h" + #include "lldp_util.h" + #include "qbg_vdp22def.h" ++#include "qbg_vdp22_oui.h" ++ ++#define OUI_ENCODE_HNDLR(name) name##_oui_encode_hndlr ++#define EXTERN_OUI_FN(name) \ ++ extern bool name##_oui_encode_hndlr(char *, char *, size_t) ++ ++/* The handler declaration for encoding OUI specific information should be ++ * here. The corresponding decoder handler should be in lldpad. ++ */ ++ ++ ++/* The OUI specific handlers should be added here */ ++ ++vdptool_oui_hndlr_tbl_t oui_hndlr_tbl[] = { ++}; ++ + + static char *print_vdp_status(enum vdp22_cmd_status status) + { +@@ -144,23 +160,137 @@ static void get_arg_value(char *str, char **arg, char **argval) + *arg = str; + } + +-static int render_cmd(struct cmd *cmd, int argc, char **args, char **argvals) ++static char *get_oui_name(char *argvals) ++{ ++ char *oui_loc; ++ ++ oui_loc = strchr(argvals, ','); ++ if (oui_loc == NULL) ++ return NULL; ++ *oui_loc = '\0'; ++ return oui_loc + 1; ++} ++ ++static void fill_oui_hdr(vdptool_oui_data_t *oui_data, char *oui_name) ++{ ++ strncpy(oui_data->oui_name, oui_name, sizeof(oui_data->oui_name)); ++ snprintf(oui_data->data, sizeof(oui_data->data), "%02x%s", ++ (unsigned int)strlen(oui_data->oui_name), oui_data->oui_name); ++} ++ ++static bool run_vdptool_oui_hndlr(vdptool_oui_data_t *oui_data, char *argvals) ++{ ++ int cnt = 0, tbl_size; ++ char *dst; ++ size_t 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_data->oui_name, ++ VDP22_OUI_MAX_NAME)) { ++ len = strlen(oui_data->data); ++ if (len >= sizeof(oui_data->data)) ++ return false; ++ dst = oui_data->data + len; ++ return oui_hndlr_tbl[cnt].oui_cli_encode_hndlr(dst, ++ argvals, len); ++ } ++ } ++ return false; ++} ++ ++/* ++ * The OUI can be input in many ways. ++ * It could be vdptool .... -c oui=companyA,Data1 -c oui=companyB,Data2 \ ++ * -c oui=companyA,Data3 ++ * Or ++ * vdptool .... -c oui=companyA,Data1Data3 -c oui=companyB,data2 ++ * This function takes care of both the case cases ++ * ++ * Anything after the comma in OUI data field is Org specific and it's upto ++ * the respective organization specific handlers to encode it so that it could ++ * be decoded appropriately by the ORG specific handlers inside lldpad. ++ * That is, Data1 and Data3 is ORG companyA specific and the OUI handlers ++ * of ORG companyA in vdptool and lldpad is responsible for encoding/decoding. ++ * ++ * Irrespective of how the command line interface to vdptool is, the input to ++ * lldpad is always the same. i.e. KeywordlenKeywordDatalenData ++ * For OUI, the data field will have the complete OUI data starting with ++ * ORG name (e.g companyA). So, in order to call the right handler routine, ++ * the OUI data field is split as OUInamelenOUInameOUIData. ++ * OUInamelen is 2B. ++ */ ++ ++static bool rewrite_oui_argval(char *argvals, vdptool_oui_data_t **oui_data, ++ int total_oui) ++{ ++ char *new_oui_argvals, *new_oui_name, *exist_oui_name; ++ bool flag = true, ret = false; ++ int cnt; ++ ++ new_oui_argvals = get_oui_name(argvals); ++ if (!new_oui_argvals) { ++ printf("Incorrect OUI Value, missing comma as delimited for " ++ "OUI Type\n"); ++ return false; ++ } ++ new_oui_name = argvals; ++ for (cnt = 0; cnt < total_oui; cnt++) { ++ if (!oui_data[cnt]) ++ continue; ++ exist_oui_name = oui_data[cnt]->oui_name; ++ if (!strncmp(new_oui_name, exist_oui_name, ++ VDP22_OUI_MAX_NAME)) { ++ flag = false; ++ break; ++ } ++ } ++ if (flag) { ++ oui_data[total_oui] = calloc(1, sizeof(vdptool_oui_data_t)); ++ fill_oui_hdr(oui_data[total_oui], new_oui_name); ++ ret = run_vdptool_oui_hndlr(oui_data[total_oui], ++ new_oui_argvals); ++ } else ++ ret = run_vdptool_oui_hndlr(oui_data[cnt], new_oui_argvals); ++ if (!ret) ++ return false; ++ return flag; ++} ++ ++int render_cmd(struct cmd *cmd, int argc, char **args, char **argvals) + { + int len; + int i; + int fid = 0, oui = 0; ++ vdptool_oui_data_t **oui_data; ++ bool is_new; + + len = sizeof(cmd->obuf); + ++ /* To avoid another loop to figure the number of OUI's */ ++ oui_data = calloc(argc, sizeof(vdptool_oui_data_t *)); ++ if (!oui_data) { ++ printf("Not enough memory\n"); ++ return 0; ++ } ++ + if ((cmd->cmd == cmd_settlv) || (cmd->cmd == cmd_gettlv)) { + for (i = 0; i < argc; i++) { +- if (args[i]) { +- if (!strncasecmp(args[i], "filter", +- strlen("filter"))) +- fid++; +- else if (!strncasecmp(args[i], "oui", +- strlen("oui"))) ++ if (!args[i]) ++ continue; ++ if (!strncasecmp(args[i], "filter", strlen("filter"))) ++ fid++; ++ else if (!strncasecmp(args[i], "oui", strlen("oui"))) { ++ is_new = rewrite_oui_argval(argvals[i], ++ oui_data, ++ oui); ++ if (is_new) { ++ argvals[i] = oui_data[oui]->data; + oui++; ++ } else { ++ args[i] = NULL; ++ argvals[i] = NULL; ++ } + } + } + } +@@ -182,6 +312,11 @@ static int render_cmd(struct cmd *cmd, int argc, char **args, char **argvals) + len - strlen(cmd->obuf), "%04x%s", + (unsigned int)strlen(argvals[i]), argvals[i]); + } ++ for (i = 0; i < oui; i++) { ++ if (oui_data[i]) ++ free(oui_data[i]); ++ } ++ free(oui_data); + return strlen(cmd->obuf); + } + +-- +2.1.0 + diff --git a/SOURCES/open-lldp-v1.0.1-9-VDP-Support-for-OUI-infrastructure-in-vdp22.patch b/SOURCES/open-lldp-v1.0.1-9-VDP-Support-for-OUI-infrastructure-in-vdp22.patch new file mode 100644 index 0000000..47c73ac --- /dev/null +++ b/SOURCES/open-lldp-v1.0.1-9-VDP-Support-for-OUI-infrastructure-in-vdp22.patch @@ -0,0 +1,524 @@ +From 19bdcc3fe966dc7d6fc154d7d29addfe200c6afc Mon Sep 17 00:00:00 2001 +From: padkrish +Date: Wed, 21 Jan 2015 03:39:19 +0000 +Subject: [PATCH] VDP: Support for OUI infrastructure in vdp22. + +This commit is a framework for supporting OUI fields +in VDP22. This specific patch has changes for converting +OUI input to vdpnl structure, vdpnl to VSI + and place-holders for calling the OUI handlers. +The specific changes are: + +vdp22.c: +------- +Currently, the OUI handler code is linked statically to the lldpad (vdp22). +Some more enhancements are needed to support the dynamic linking of OUI +handler code. This is the general flow: +All the OUI handlers specify their init function in vdp22_oui_init_list. When +VDP22 receives a command with the OUI fields, then based on the OUI value, +it calls the appropriate init function. The OUI specific init function +implemented in the OUI specific file (not in this file) then registers its +handlers with VDP22. The handlers prototype is in qbg_vdp22_oui.h and it +currently has: +1. Handler for converting the OUI string to OUI structure which is a member of vdpnl structure. +2. Handler for converting the OUI structure from vdpnl structure to a OUI structure which is a member of vsi22 structure +3. Handler for creating the OUI fields for Tx. +4. handler for processing/Rx the OUI information +5. Handler for freeing the OUI structure +6. Handler to return the size of OUI PTLV + +Then, accordingly the respective handlers are called. +Function 'vdp22_delete_oui' calls each of the registered handlers for freeing +its OUI specific fields. +Function 'vdpnl_alloc_vsi_oui' calls each of the registered handlers for +creating a OUI structure in vsi22 structure. +Function 'oui_vdp_hndlr_init' is called by OUI specific code to register +its handlers. +Function 'vdp22_oui_init' calls the OUI specific init function. +Comments are embedded in the other functions added. + +vdp22sm.c: +---------- +Function 'oui22_ptlv_sz' calls each of the handlers in its VSI structure +to get the size of the OUI specific PTLV size. +Function 'oui22_2tlv' calls the handler for generating the OUI data for Tx. + +vdp22_cmds.c: +------------- +This file has a minor modification to get the number of OUI fields which is +encoded in the input to lldpad. + +vdp_ascii.c: +------------ +Function 'oui_str2vdpnl' calls the respective handler to convert the OUI input +string to the OUI structure stored in vdpnl structure. + +Signed-off-by: padkrish +Signed-off-by: John Fastabend +--- + include/qbg_vdp22_oui.h | 38 ++++++++++++ + qbg/vdp22.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++++ + qbg/vdp22_cmds.c | 10 ++- + qbg/vdp22sm.c | 54 +++++++++++++++- + qbg/vdp_ascii.c | 37 ++++++++++- + 5 files changed, 293 insertions(+), 5 deletions(-) + +diff --git a/include/qbg_vdp22_oui.h b/include/qbg_vdp22_oui.h +index d31c6ad..0cce31e 100644 +--- a/include/qbg_vdp22_oui.h ++++ b/include/qbg_vdp22_oui.h +@@ -32,6 +32,7 @@ + */ + enum vdp22_oui { + VDP22_OUI_TYPE_LEN = 3, /* Size of OUI Type field */ ++ MAX_NUM_OUI = 10, + VDP22_OUI_MAX_NAME = 20, + MAX_OUI_DATA_LEN = 200 + }; +@@ -54,4 +55,41 @@ typedef struct vdptool_oui_hndlr_tbl_s { + bool (*oui_cli_encode_hndlr)(char *dst, char *src, size_t len); + } vdptool_oui_hndlr_tbl_t; + ++struct vdpnl_oui_data_s { ++ unsigned char oui_type[VDP22_OUI_TYPE_LEN]; ++ char oui_name[VDP22_OUI_MAX_NAME]; ++ int len; ++ char data[MAX_OUI_DATA_LEN]; ++ /* If vdpnl structure is used for IPC, then this cannot be a ptr as ++ * otherwise it needs to be flattened out. If this is just used within ++ * lldpad then this can be made a ptr instead of a static array. ++ * May need to revisit later TODO ++ */ ++}; ++ ++struct vdp22_oui_init_s { ++ unsigned char oui_type[VDP22_OUI_TYPE_LEN]; ++ char oui_name[VDP22_OUI_MAX_NAME]; ++ bool (*oui_init)(); ++}; ++ ++struct vdp22_oui_handler_s { ++ unsigned char oui_type[VDP22_OUI_TYPE_LEN]; ++ char oui_name[VDP22_OUI_MAX_NAME]; ++ /* This handler converts the OUI string to vdpnl structure */ ++ bool (*str2vdpnl_hndlr)(struct vdpnl_oui_data_s *, char *); ++ /* 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 creates the OUI fields for Tx */ ++ size_t (*vdp_tx_hndlr)(char unsigned *, ++ struct vdp22_oui_data_s *, size_t); ++ /* This handler is called for processing/Rx the OUI information */ ++ bool (*vdp_rx_hndlr)(); ++ /* This handler frees the OUI structures */ ++ bool (*vdp_free_oui_hndlr)(struct vdp22_oui_data_s *); ++ /* This handler returns the size of OUI PTLV */ ++ unsigned long (*oui_ptlv_size_hndlr)(void *); ++}; ++ + #endif /* __VDP22_OUI_H__ */ +diff --git a/qbg/vdp22.c b/qbg/vdp22.c +index d7aa648..5cae83f 100644 +--- a/qbg/vdp22.c ++++ b/qbg/vdp22.c +@@ -44,6 +44,22 @@ + #include "qbg_vdp22_cmds.h" + #include "qbg_vdp22def.h" + ++#define INIT_FN(name) name##_oui_init ++#define EXTERN_FN(name)\ ++extern bool name##_oui_init() ++ ++/* 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 ++ * argument is the init handler. ++ */ ++ ++struct vdp22_oui_init_s vdp22_oui_init_list[] = { ++}; ++ ++struct vdp22_oui_handler_s vdp22_oui_list[MAX_NUM_OUI]; ++unsigned char g_oui_index; ++ + /* + * VDP22 helper functions + */ +@@ -218,6 +234,36 @@ void vdp22_showvsi(struct vsi22 *p) + } + + /* ++ * Delete the OUI structures of VSI22 ++ * This calls the respective OUI handlers which are responsible for freeing ++ * the OUI specific 'data' element of 'vdp22_oui_data_s' structure. ++ */ ++ ++static void vdp22_delete_oui(struct vsi22 *p) ++{ ++ struct vdp22_oui_data_s *oui_str; ++ struct vdp22_oui_handler_s *oui_hndlr; ++ int idx; ++ bool ret; ++ ++ if ((p->no_ouidata == 0) || (!p->oui_str_data)) ++ return; ++ for (idx = 0; idx < p->no_ouidata; idx++) { ++ oui_str = &p->oui_str_data[idx]; ++ oui_hndlr = vdp22_get_oui_hndlr(oui_str->oui_name); ++ if (!oui_hndlr) ++ LLDPAD_ERR("%s: Unknown OUI %s\n", ++ __func__, oui_str->oui_name); ++ else { ++ ret = oui_hndlr->vdp_free_oui_hndlr(oui_str); ++ LLDPAD_DBG("%s: Free handler returned %d\n", __func__, ++ ret); ++ } ++ } ++ free(p->oui_str_data); ++} ++ ++/* + * Delete a complete VSI node not on queue. + */ + void vdp22_delete_vsi(struct vsi22 *p) +@@ -225,6 +271,7 @@ void vdp22_delete_vsi(struct vsi22 *p) + LLDPAD_DBG("%s:%s vsi:%p(%02x)\n", __func__, p->vdp->ifname, p, + p->vsi[0]); + free(p->fdata); ++ vdp22_delete_oui(p); + free(p); + } + +@@ -475,6 +522,38 @@ static bool filter_ok(unsigned char ffmt, struct fid22 *fp, + return rc; + } + ++static void vdpnl_alloc_vsi_oui(struct vdpnl_vsi *vsi, struct vsi22 *p) ++{ ++ struct vdp22_oui_handler_s *oui_hndlr; ++ bool ret; ++ int idx; ++ ++ if (vsi->ouisz == 0) ++ return; ++ p->no_ouidata = vsi->ouisz; ++ p->oui_str_data = calloc(vsi->ouisz, sizeof(struct vdp22_oui_data_s)); ++ if (!p->oui_str_data) { ++ LLDPAD_ERR("%s: calloc return failure\n", __func__); ++ return; ++ } ++ for (idx = 0; idx < vsi->ouisz; idx++) { ++ struct vdpnl_oui_data_s *from = &vsi->oui_list[idx]; ++ struct vdp22_oui_data_s *to = &p->oui_str_data[idx]; ++ ++ oui_hndlr = vdp22_get_oui_hndlr(from->oui_name); ++ if (!oui_hndlr) ++ LLDPAD_ERR("%s: Unknown OUI Name %s\n", ++ __func__, from->oui_name); ++ else { ++ ret = oui_hndlr->vdpnl2vsi22_hndlr(p, from, to); ++ if (!ret) ++ LLDPAD_ERR("%s: handler return error for " ++ "oui %s\n", __func__, ++ from->oui_name); ++ } ++ } ++} ++ + /* + * Allocate a VSI node with filter information data. + * Check if input data is valid. +@@ -540,6 +619,7 @@ static struct vsi22 *vdp22_alloc_vsi_int(struct vdpnl_vsi *vsi, + fp->requestor.req_pid = vsi->req_pid; + fp->requestor.req_seq = vsi->req_seq; + } ++ vdpnl_alloc_vsi_oui(vsi, p); + *rc = 0; + LLDPAD_DBG("%s:%s vsi:%p(%02x)\n", __func__, vsi->ifname, p, p->vsi[0]); + return p; +@@ -1113,3 +1193,82 @@ void copy_vsi_external(struct vdpnl_vsi *vsi, struct vsi22 *p, int clif) + { + copy_vsi(vsi, p, clif); + } ++ ++/* ++ * This is called by the ORG specific code to register its handlers. ++ */ ++ ++bool oui_vdp_hndlr_init(struct vdp22_oui_handler_s *handler_ptr) ++{ ++ if (!handler_ptr) { ++ LLDPAD_DBG("%s: NULL handler\n", __func__); ++ return false; ++ } ++ memcpy(&(vdp22_oui_list[g_oui_index]), handler_ptr, ++ sizeof(vdp22_oui_list[g_oui_index])); ++ g_oui_index++; ++ return true; ++} ++ ++/* ++ * This calls the ORG specific init function. Then the ORG specific init ++ * function registers its handlers. ++ */ ++ ++static void vdp22_oui_init(char *oui_name) ++{ ++ int total; ++ int idx; ++ ++ total = sizeof(vdp22_oui_init_list) / sizeof(vdp22_oui_init_list[0]); ++ for (idx = 0; idx < total; idx++) { ++ if (!strncmp(vdp22_oui_init_list[idx].oui_name, oui_name, ++ sizeof(vdp22_oui_init_list[idx].oui_name))) { ++ if (!vdp22_oui_init_list[idx].oui_init()) ++ LLDPAD_ERR("%s: oui init return error for OUI " ++ "%s\n", __func__, oui_name); ++ } ++ } ++} ++ ++static struct vdp22_oui_handler_s *get_oui_hndlr_internal(char *oui_name) ++{ ++ int total; ++ int idx; ++ ++ total = g_oui_index; ++ for (idx = 0; idx < total; idx++) { ++ if (!strncmp(vdp22_oui_list[idx].oui_name, oui_name, ++ sizeof(vdp22_oui_list[idx].oui_name))) ++ return &vdp22_oui_list[idx]; ++ } ++ return NULL; ++} ++ ++/* ++ * Return the handler structure associated with this OUI. ++ * If the handler is already registered, then get_oui_hndlr_internal function ++ * will return it. Otherwise, vdp22_oui_init is called so that the handler ++ * init function is called which will register its handlers. This is done so ++ * that the ORG specific handlers are registered only on demand. ++ */ ++ ++struct vdp22_oui_handler_s *vdp22_get_oui_hndlr(char *oui_name) ++{ ++ struct vdp22_oui_handler_s *hndlr; ++ ++ if (oui_name == NULL) { ++ LLDPAD_ERR("%s: NULL arg\n", __func__); ++ return NULL; ++ } ++ /* ++ * First check if the handler exists. ++ * If not the OUI plugin is probably not initialized ++ * Initialize the handlers ++ */ ++ hndlr = get_oui_hndlr_internal(oui_name); ++ if (hndlr != NULL) ++ return hndlr; ++ vdp22_oui_init(oui_name); ++ return get_oui_hndlr_internal(oui_name); ++} +diff --git a/qbg/vdp22_cmds.c b/qbg/vdp22_cmds.c +index 5d5ef6b..5b5788f 100644 +--- a/qbg/vdp22_cmds.c ++++ b/qbg/vdp22_cmds.c +@@ -356,20 +356,25 @@ static int get_vdp22_retval(int rc) + } + } + +-static int set_arg_vsi3(struct cmd *cmd, char *argvalue, bool test, int size) ++static int set_arg_vsi3(struct cmd *cmd, char *argvalue, bool test, int size, ++ int oui_size) + { + cmd_status good_cmd = vdp22_cmdok(cmd, cmd_settlv); + int rc; + struct vdpnl_vsi vsi; + struct vdpnl_mac mac[size]; ++ struct vdpnl_oui_data_s oui[oui_size]; + + if (good_cmd != cmd_success) + return good_cmd; + + memset(&vsi, 0, sizeof(vsi)); + memset(&mac, 0, sizeof(mac)); ++ memset(&oui, 0, sizeof(oui)); + vsi.maclist = mac; + vsi.macsz = size; ++ vsi.oui_list = (struct vdpnl_oui_data_s *)oui; ++ vsi.ouisz = oui_size; + rc = vdp_str2vdpnl(argvalue, &vsi, cmd->ifname); + if (rc) { + good_cmd = get_vdp22_retval(rc); +@@ -392,11 +397,12 @@ out: + static int set_arg_vsi2(struct cmd *cmd, char *argvalue, bool test) + { + int no = (cmd->ops >> OP_FID_POS) & 0xff; ++ int oui_no = (cmd->ops >> OP_OUI_POS) & 0xff; + + if (no <= 0) + return -EINVAL; + if ((cmd->ops & op_arg) && (cmd->ops & op_argval)) +- return set_arg_vsi3(cmd, argvalue, test, no); ++ return set_arg_vsi3(cmd, argvalue, test, no, oui_no); + else /* Not supported for now */ + return cmd_failed; + } +diff --git a/qbg/vdp22sm.c b/qbg/vdp22sm.c +index 83a97fb..db0e413 100644 +--- a/qbg/vdp22sm.c ++++ b/qbg/vdp22sm.c +@@ -184,6 +184,33 @@ static inline size_t vsi22_ptlv_sz(struct vsi22 *vp) + } + + /* ++ * This function calls the registered OUI handlers that returns the size of ++ * the OUI data. ++ */ ++ ++static inline size_t oui22_ptlv_sz(struct vsi22 *vp) ++{ ++ struct vdp22_oui_handler_s *oui_hndlr; ++ struct vdp22_oui_data_s *oui_str; ++ size_t size = 0; ++ int idx; ++ ++ if (vp->no_ouidata == 0) ++ return 0; ++ for (idx = 0; idx < vp->no_ouidata; idx++) { ++ oui_str = &(vp->oui_str_data[idx]); ++ oui_hndlr = vdp22_get_oui_hndlr(oui_str->oui_name); ++ if (!oui_hndlr) { ++ LLDPAD_ERR("%s: No handler registered for OUI %s\n", ++ __func__, oui_str->oui_name); ++ continue; ++ } ++ size += oui_hndlr->oui_ptlv_size_hndlr(oui_str->data); ++ } ++ return size; ++} ++ ++/* + * Extract 1, 2, 3, 4 byte integers in network byte format. + * Extract n bytes. + * Assume enough space available. +@@ -309,6 +336,29 @@ static size_t vsi22_2tlv_fdata(unsigned char *cp, struct fid22 *p, + return nbytes; + } + ++static void oui22_2tlv(struct vsi22 *vp, char unsigned *cp) ++{ ++ struct vdp22_oui_handler_s *oui_hndlr; ++ struct vdp22_oui_data_s *oui_str; ++ size_t offset = 0; ++ size_t temp_offset = 0; ++ int idx; ++ ++ if (vp->no_ouidata == 0) ++ return; ++ for (idx = 0; idx < vp->no_ouidata; idx++) { ++ oui_str = &(vp->oui_str_data[idx]); ++ oui_hndlr = vdp22_get_oui_hndlr(oui_str->oui_name); ++ if (!oui_hndlr) { ++ LLDPAD_ERR("%s: No handler registered for OUI %s\n", ++ __func__, oui_str->oui_name); ++ continue; ++ } ++ temp_offset = oui_hndlr->vdp_tx_hndlr(cp, oui_str, offset); ++ offset += temp_offset; ++ } ++} ++ + static void vsi22_2tlv(struct vsi22 *vp, char unsigned *cp, unsigned char stat) + { + size_t offset = 0, i; +@@ -478,7 +528,8 @@ static void vdp22st_wait_syscmd(struct vsi22 *vsip) + */ + static void vdp22st_process(struct vsi22 *vsi) + { +- unsigned short len = mgr22_ptlv_sz() + vsi22_ptlv_sz(vsi); ++ unsigned short len = mgr22_ptlv_sz() + vsi22_ptlv_sz(vsi) + ++ oui22_ptlv_sz(vsi); + unsigned char buf[len]; + struct qbg22_imm qbg; + +@@ -487,6 +538,7 @@ static void vdp22st_process(struct vsi22 *vsi) + qbg.u.c.data = buf; + mgr22_2tlv(vsi, buf); + vsi22_2tlv(vsi, buf + mgr22_ptlv_sz(), vsi->hints); ++ oui22_2tlv(vsi, buf + mgr22_ptlv_sz() + vsi22_ptlv_sz(vsi)); + vsi->smi.txmit_error = modules_notify(LLDP_MOD_ECP22, LLDP_MOD_VDP22, + vsi->vdp->ifname, &qbg); + if (!vsi->smi.txmit_error) { +diff --git a/qbg/vdp_ascii.c b/qbg/vdp_ascii.c +index 70ec79b..80a4419 100644 +--- a/qbg/vdp_ascii.c ++++ b/qbg/vdp_ascii.c +@@ -54,7 +54,8 @@ struct vsi_keyword_handler vsi_key_handle[] = { + /* {VSI22_ARG_VSIIDFRMT_STR, VSI_VSIIDFRMT_ARG}, TODO*/ + {VSI22_ARG_VSIID_STR, VSI_VSIID_ARG}, + {VSI22_ARG_HINTS_STR, VSI_HINTS_ARG}, +- {VSI22_ARG_FILTER_STR, VSI_FILTER_ARG} }; ++ {VSI22_ARG_FILTER_STR, VSI_FILTER_ARG}, ++ {VSI22_ARG_OUI_STR, VSI_OUI_ARG} }; + + /* + * Check if it is a UUID and consists of hexadecimal digits and dashes only. +@@ -225,6 +226,33 @@ static bool gethints(struct vdpnl_vsi *p, char *s) + return true; + } + ++static bool oui_str2vdpnl(struct vdpnl_vsi *vsi, char *p, unsigned short idx) ++{ ++ struct vdp22_oui_handler_s *oui_hndlr; ++ char *temp_argval = p; ++ char *oui_val; ++ char oui_name[VDP22_OUI_MAX_NAME]; ++ u8 oui_name_len; ++ ++ hexstr2bin(p, &oui_name_len, sizeof(oui_name_len)); ++ if (oui_name_len >= VDP22_OUI_MAX_NAME) ++ return false; ++ temp_argval = p + 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'; ++ oui_hndlr = vdp22_get_oui_hndlr(oui_name); ++ if (!oui_hndlr) ++ return false; ++ strncpy(vsi->oui_list[idx].oui_name, oui_name, ++ sizeof(vsi->oui_list[idx].oui_name)); ++ if (oui_hndlr->str2vdpnl_hndlr) ++ return oui_hndlr->str2vdpnl_hndlr(&(vsi->oui_list[idx]), ++ oui_val); ++ else ++ return false; ++} ++ + /* + * Read VSI association mode. If can be followed by an error code in brackets. + * For vdp22 protocol the allowed words are assoc, preassoc, preassoc-rr and +@@ -315,7 +343,7 @@ int vdp22_parse_str_vdpnl(struct vdpnl_vsi *vsi, u16 *key_flags, + int i, ioff = 0, numargs; + int ilen = strlen(orig_argvalue); + unsigned int no; +- unsigned short idx = 0; ++ unsigned short idx = 0, oui_idx = 0; + u16 num_arg_keys = 0; + + argvalue = strdup(orig_argvalue); +@@ -373,6 +401,11 @@ int vdp22_parse_str_vdpnl(struct vdpnl_vsi *vsi, u16 *key_flags, + if (!argvals[i] || !gethints(vsi, argvals[i])) + goto out_err; + break; ++ case VSI_OUI_ARG: ++ if (!oui_str2vdpnl(vsi, argvals[i], oui_idx)) ++ goto out_err; ++ oui_idx++; ++ break; + default: + goto out_err; + } +-- +2.1.0 + diff --git a/SPECS/lldpad.spec b/SPECS/lldpad.spec new file mode 100644 index 0000000..e802a38 --- /dev/null +++ b/SPECS/lldpad.spec @@ -0,0 +1,331 @@ +# https://fedoraproject.org/wiki/Packaging:Guidelines#Compiler_flags +%define _hardened_build 1 + +%global checkout 036e314 + +Name: lldpad +Version: 1.0.1 +Release: 5.git%{checkout}%{?dist} +Summary: Intel LLDP Agent +Group: System Environment/Daemons +License: GPLv2 +URL: http://open-lldp.org/ +Source0: %{name}-%{version}.tar.gz +Patch1: open-lldp-v1.0.1-1-VDP-vdp22_cmds-retrieve-vsi-paramenter-data.patch +Patch2: open-lldp-v1.0.1-2-VDP-vdptool-first-version.patch +Patch3: open-lldp-v1.0.1-3-VDP-vdptool-test-cases-Some-test-cases-to-test-the-n.patch +Patch4: open-lldp-v1.0.1-4-VDP-Changes-to-make-the-interface-to-VDP22-in-lldpad.patch +Patch5: open-lldp-v1.0.1-5-VDP-Support-for-get-tlv-in-vdptool-and-VDP22.patch +Patch6: open-lldp-v1.0.1-6-VDP-Support-in-VDP22-for-correct-error-code-status-t.patch +Patch7: open-lldp-v1.0.1-7-VDP-Support-for-OUI-infrastructure-in-VDP22.patch +Patch8: open-lldp-v1.0.1-8-VDP-Support-for-OUI-infrastructure-in-vdptool.patch +Patch9: open-lldp-v1.0.1-9-VDP-Support-for-OUI-infrastructure-in-vdp22.patch +Patch10: open-lldp-v1.0.1-10-VDP-Support-for-OUI-infrastructure-in-vdp22.patch +Patch11: open-lldp-v1.0.1-11-VDP-Support-for-Cisco-specific-OUI-extensions-to-VDP.patch +Patch12: open-lldp-v1.0.1-12-VDP22-Fix-the-ack-timeout-handler-to-set-the-right-t.patch +Patch13: open-lldp-v1.0.1-13-VDP-Changes-in-OUI-infra-for-get-tlv.patch +Patch14: open-lldp-v1.0.1-14-VDP-Changes-in-Cisco-OUI-handlers-to-support-get-tlv.patch +Patch15: open-lldp-v1.0.1-15-VDP-Add-vdptool-man-page-to-Makefile.patch +Patch16: open-lldp-v1.0.1-16-VDP-Fixed-DBG-print-compile-errors-in-32-bit-systems.patch +Patch17: open-lldp-v1.0.1-17-lldp-automake-fixes-for-dist-distcheck.patch +Patch18: open-lldp-v1.0.1-18-enabled-test-tool-building-for-distcheck.patch +Patch19: open-lldp-v1.0.1-19-nltest-build-error.patch +Patch20: open-lldp-v1.0.1-20-lldp-automake-fix-drop-prefix-on-vdptool_LDADD.patch +Patch21: open-lldp-v1.0.1-21-lldpad-Fix-DCBX-event-generation-from-lldpad.patch +Patch22: open-lldp-v1.0.1-22-vdp-Fixed-the-memory-leak-for-modify-VSI-support-for.patch +Patch23: open-lldp-v1.0.1-23-lldp-make-TTL-TLV-configurable.patch +Patch24: open-lldp-v1.0.1-24-switch-from-sysv-to-posix-shared-memory-apis.patch +Patch25: open-lldp-v1.0.1-25-l2_linux_packet-correctly-process-return-value-of-ge.patch +Patch26: open-lldp-v1.0.1-26-lldpad-system-capability-incorrect-advertised-as-sta.patch +# not upstream +Patch27: open-lldp-v1.0.1-27-fix-build-warnings.patch +Patch99: lldpad-0.9.46-Ignore-supplied-PG-configuration-if-PG-is-being-disabled.patch +Patch100: open-lldp-v1.0.1-28-fix-oid-display.patch +Patch101: 0001-memleak-on-received-TLVs-from-modules.patch + +Requires: kernel >= 2.6.32 +BuildRequires: automake autoconf libtool +BuildRequires: flex >= 2.5.33 +BuildRequires: kernel-headers >= 2.6.32 +BuildRequires: libconfig-devel >= 1.3.2 +BuildRequires: libnl3-devel +BuildRequires: readline-devel +BuildRequires: systemd +Requires: readline +Requires(post): systemd +Requires(preun): systemd +Requires(postun): systemd +Provides: dcbd = %{version}-%{release} +Obsoletes: dcbd < 0.9.26 + +%description +This package contains the Linux user space daemon and configuration tool for +Intel LLDP Agent with Enhanced Ethernet support for the Data Center. + +%package devel +Summary: Development files for %{name} +Group: Development/Libraries +Requires: %{name}%{?_isa} = %{version}-%{release} +Provides: dcbd-devel = %{version}-%{release} +Obsoletes: dcbd-devel < 0.9.26 + +%description devel +The %{name}-devel package contains header files for developing applications +that use %{name}. + +%prep +%autosetup -p1 + +%build +./bootstrap.sh +%configure --disable-static +# fix the hardened build flags +sed -i -e 's! \\\$compiler_flags !&\\\$CFLAGS \\\$LDFLAGS !' libtool +make %{?_smp_mflags} + +%install +make install DESTDIR=%{buildroot} +mkdir -p %{buildroot}%{_sharedstatedir}/%{name} +rm -f %{buildroot}%{_libdir}/liblldp_clif.la + +%post +/sbin/ldconfig +%systemd_post %{name}.service %{name}.socket + +%preun +%systemd_preun %{name}.service %{name}.socket + +%postun +/sbin/ldconfig +%systemd_postun_with_restart %{name}.service %{name}.socket + +%post devel +## provide legacy support for apps that use the old dcbd interface. +if [ ! -e %{_includedir}/dcbd ]; then + ln -T -s %{_includedir}/lldpad %{_includedir}/dcbd +fi +if [ ! -e %{_includedir}/dcbd/clif_cmds.h ]; then + ln -T -s %{_includedir}/lldpad/lldp_dcbx_cmds.h %{_includedir}/dcbd/clif_cmds.h +fi + +%preun devel +if [ -e %{_includedir}/dcbd/clif_cmds.h ]; then + rm -f %{_includedir}/dcbd/clif_cmds.h +fi +if [ -e %{_includedir}/dcbd ]; then + rm -f %{_includedir}/dcbd +fi + +%files +%doc COPYING README ChangeLog +%{_sbindir}/* +%{_libdir}/liblldp_clif.so.* +%dir %{_sharedstatedir}/%{name} +%{_unitdir}/%{name}.service +%{_unitdir}/%{name}.socket +%dir %{_sysconfdir}/bash_completion.d/ +%{_sysconfdir}/bash_completion.d/* +%{_mandir}/man3/* +%{_mandir}/man8/* + +%files devel +%{_includedir}/* +%{_libdir}/pkgconfig/*.pc +%{_libdir}/liblldp_clif.so + +%changelog +* Tue Feb 26 2019 Aaron Conole - 1.0.1-5.git036e314 +- Fix memory leak on TLV reception (#1196320) + +* Wed Aug 08 2018 Aaron Conole - 1.0.1-4.git036e314 +- fix the OID printing routine (#1551623) + +* Wed Jul 06 2016 Chris Leech - 1.0.1-3.git036e314 +- 1273663 sync with upstream v1.0.1-26-g036e314 + system capability incorrect advertised as station only + +* Wed Aug 12 2015 Chris Leech - 1.0.1-2.git986eb2e +- convert from sysv shm to posix, to allow selinux restorecon (#1080287) + +* Thu Jun 18 2015 Chris Leech - 1.0.1-1.git986eb2e +- rebased to upstream v1.0.1-23-g986eb2e (#1175802) + +* Tue Oct 21 2014 Chris Leech - 0.9.46-10 +- Sync with upstream v0.9.46-123-g48a5f38 (#1087096) + +* Fri Jun 27 2014 Chris Leech - 0.9.46-9 +- Fix IEEE mode DCBX (#1102886) + +* Wed Mar 19 2014 Petr Šabata - 0.9.46-8 +- Ignore supplied PG configuration if PG is being disabled (#1067261) + +* Tue Mar 18 2014 Petr Šabata - 0.9.46-7 +- Migrate properly with VEPA (#1070725) + +* Fri Jan 24 2014 Daniel Mach - 0.9.46-6 +- Mass rebuild 2014-01-24 + +* Fri Dec 27 2013 Daniel Mach - 0.9.46-5 +- Mass rebuild 2013-12-27 + +* Fri Nov 08 2013 Petr Šabata - 0.9.46-4 +- Support multiple virtual machines again (#1020625) + +* Wed Jul 31 2013 Petr Šabata - 0.9.46-3 +- Require 'systemd' instead of 'systemd-units' + +* Tue Jul 02 2013 Petr Šabata - 0.9.46-2 +- Fix the hardened build flags + +* Tue Jun 04 2013 Petr Šabata - 0.9.46-1 +- 0.9.46 bump +- 802.1Qaz fixes to enable support on not CEE DCBX-enabled hardware +- 802.1Qbg EVB module support +- lldpad now supports bonded interfaces + +* Tue Mar 05 2013 Petr Šabata - 0.9.45-5 +- Fix build by patching the sizeof() call in lldp_8021qaz_cmds.c + +* Thu Feb 14 2013 Fedora Release Engineering - 0.9.45-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Tue Aug 28 2012 Petr Šabata - 0.9.45-3 +- Migrate to systemd scriptlets (#850192) + +* Thu Aug 23 2012 Petr Šabata - 0.9.45-2 +- Fix displaying of the Management Address TLV (327ef662) + +* Wed Aug 15 2012 Petr Šabata - 0.9.45-1 +- 0.9.45 bump +- Provide bash-completion and the new clif library + +* Thu Jul 19 2012 Fedora Release Engineering - 0.9.44-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Fri Jan 27 2012 Petr Šabata - 0.9.44-1 +- 0.9.44 bump, patches cleanup +- Correct dependencies a bit +- Require dlopen()'d readline + +* Fri Jan 13 2012 Fedora Release Engineering - 0.9.43-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Thu Oct 06 2011 Petr Sabata - 0.9.43-5 +- Do not enable lldpad by default (#701999) + +* Fri Sep 23 2011 Petr Sabata - 0.9.43-4 +- Enable hardened build + +* Tue Sep 13 2011 Petr Sabata - 0.9.43-3 +- Mute systemd output (#737897) + +* Tue Aug 30 2011 Petr Sabata - 0.9.43-2 +- Apply various upstream 0.9.43 bugfixes +- Include not yet accepted Jens Osterkamp's patch to fix bug #720080 +- Whitespace cleanup, phew + +* Thu Jul 07 2011 Petr Sabata - 0.9.43-1 +- 0.9.43 bump +- Drop the the clean exit patch and our unit file, both are now included upstream + +* Tue Jun 21 2011 Petr Sabata - 0.9.42-2 +- Introduce systemd unit file, drop SysV support +- Call systemctl instead of service and chkconfig +- Enable the service only on new installation (post) +- Clean exit patch + +* Mon Jun 13 2011 Petr Sabata - 0.9.42-1 +- 0.9.42 bump (massive patches cleanup) +- Remove obsolete defattr +- Remove COPYING and README from devel subpackage + +* Wed May 4 2011 Petr Sabata - 0.9.41-3 +- Fix the frequent, power consuming lldpad wake-ups (rhbz#701943) + +* Thu Apr 21 2011 Petr Sabata - 0.9.41-2 +- Bring in upstream 802.1Qbg bugfixes + +* Thu Feb 10 2011 Petr Sabata - 0.9.41-1 +- 0.9.41 bump +- New BR: autotools, flex +- Buildroot garbage removed +- Devel post and preun scriptlets sanitized + +* Tue Feb 08 2011 Fedora Release Engineering - 0.9.38-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Mon Jun 28 2010 Jan Zeleny - 0.9.38-1 +- rebased to 0.9.38 (various enhancements and bugfixes, see + lldpad-0.9.38-relnotes.txt on http://e1000.sf.net for complete list) + +* Mon May 10 2010 Jan Zeleny - 0.9.32-2 +- rebuild to match new libconfig + +* Mon Apr 12 2010 Jan Zeleny - 0.9.32-1 +- rebased to 0.9.32 (various enhancements and bugfixes, see + lldpad-0.9.32-relnotes.txt on http://e1000.sf.net for complete list) + +* Thu Mar 25 2010 Jan Zeleny - 0.9.29-2 +- added Provides and Obsoletes tags to devel subpackage + +* Mon Mar 15 2010 Jan Zeleny - 0.9.29-1 +- updated package to 0.9.29, improved compatibility with fcoe-utils + +* Fri Feb 26 2010 Jan Zeleny - 0.9.26-2 +- updated spec file and LSB init script patch for re-review + (#568641) + +* Thu Feb 25 2010 Jan Zeleny - 0.9.26-1 +- rebased to 0.9.26 +- package renamed to lldpad +- enahanced functionality (LLDP supported as well as DCBX) + +* Fri Nov 13 2009 Jan Zeleny - 0.9.19-2 +- init script patch adding LSB compliance + +* Thu Oct 08 2009 Jan Zeleny - 0.9.19-1 +- update to new upstream version + +* Mon Oct 05 2009 Jan Zeleny - 0.9.15-5 +- replaced the last patch, which was not fully functional, with + the new one + +* Wed Sep 09 2009 Karsten Hopp 0.9.15-4 +- buildrequire libconfig-devel >= 1.3.2, it doesn't build with 1.3.1 due to + the different config_lookup_string api + +* Thu Aug 20 2009 Jan Zeleny - 0.9.15-3 +- update of config_lookup_string() function calls + +* Thu Aug 20 2009 Jan Zeleny - 0.9.15-2 +- rebuild in order to match new libconfig + +* Mon Aug 17 2009 Jan Zeleny - 0.9.15-1 +- rebase to 0.9.15 + +* Fri Jul 24 2009 Fedora Release Engineering - 0.9.7-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Fri Mar 20 2009 Jan Zeleny - 0.9.7-4 +- updated scriptlets in spec file to follow the rules + +* Wed Mar 11 2009 Jan Zeleny - 0.9.7-3 +- added devel files again to support fcoe-utils package +- added kernel >= 2.6.29 to Requires, deleted dcbnl.h, since it is + aviable in kernel 2.6.29-rc7 +- changed config dir from /etc/sysconfig/dcbd to /etc/dcbd +- updated init script: added mandatory Short description tag, + deleted default runlevels, which should start the script + +* Tue Mar 10 2009 Jan Zeleny - 0.9.7-2 +- added patch to enable usage of libconfig shared in system +- removed devel part of package + +* Mon Mar 2 2009 Chris Leech - 0.9.7-1 +- Updated to 0.9.7 +- Added a private copy of dcbnl.h until kernel-headers includes it. + Export patch is making it's way to the upstream kernel via net-2.6, + expected in 2.6.29-rc7 + +* Thu Feb 26 2009 Chris Leech - 0.9.5-1 +- initial RPM packaging