Blame SOURCES/open-lldp-v1.0.1-31-Rebase-to-open-lldp-branch-1.1.0.patch

7fda0c
From: Aaron Conole <aconole@redhat.com>
7fda0c
Date: Wed, 09 Jun 2021 15:12:06 +0000
7fda0c
Subject: [PATCH] lldpad: Rebase to openlldp branch 1.1.0
7fda0c
MIME-Version: 1.0
7fda0c
Content-Type: text/plain; charset=UTF-8
7fda0c
Content-Transfer-Encoding: 8bit
7fda0c
7fda0c
Open-LLDP released 1.1.0 which includes a number of important fixes
7fda0c
relevant to customers.  The biggest changes are documented in the
7fda0c
changelog.
7fda0c
7fda0c
This patch updates the lldpad package to 1.1.0 branch as of
7fda0c
4c75fa274230 "tx: rename variable"
7fda0c
7fda0c
Signed-off-by: Aaron Conole <aconole@redhat.com>
7fda0c
---
7fda0c
 ChangeLog                  |   15 +++
7fda0c
 Makefile.am                |   26 +++++
7fda0c
 README                     |    4 
7fda0c
 config.c                   |   45 ++++++---
7fda0c
 configure.ac               |   39 ++++++++
7fda0c
 ctrl_iface.c               |    4 
7fda0c
 dcb_protocol.c             |   19 +---
7fda0c
 dcb_rule_chk.c             |    2 
7fda0c
 dcbtool.c                  |    2 
7fda0c
 dcbtool_cmds.c             |   24 -----
7fda0c
 docs/liblldp_clif-vdp22.3  |    2 
7fda0c
 docs/lldptool.8            |    4 
7fda0c
 event_iface.c              |   22 +++-
7fda0c
 include/config.h           |    3 
7fda0c
 include/linux/if_link.h    |  100 ++++++++++++++++++++-
7fda0c
 include/lldp.h             |   13 ++
7fda0c
 include/lldp_basman_clif.h |    6 -
7fda0c
 include/lldp_mod.h         |    2 
7fda0c
 include/lldp_tlv.h         |   16 ++-
7fda0c
 include/lldp_util.h        |    4 
7fda0c
 include/lldptool.h         |    3 
7fda0c
 include/qbg_ecp22.h        |    4 
7fda0c
 include/qbg_vdpnl.h        |    1 
7fda0c
 lldp/agent.c               |    4 
7fda0c
 lldp/l2_packet.h           |    7 -
7fda0c
 lldp/l2_packet_linux.c     |    6 -
7fda0c
 lldp/ports.c               |    2 
7fda0c
 lldp/rx.c                  |   41 ++++----
7fda0c
 lldp/states.h              |    2 
7fda0c
 lldp/tx.c                  |   31 ++++--
7fda0c
 lldp_8021qaz.c             |   52 ++++++-----
7fda0c
 lldp_8021qaz_clif.c        |   80 ++++++++++++-----
7fda0c
 lldp_8021qaz_cmds.c        |    2 
7fda0c
 lldp_8023.c                |   14 +--
7fda0c
 lldp_basman.c              |   10 --
7fda0c
 lldp_basman_cmds.c         |   90 +++++++++++++++++++
7fda0c
 lldp_dcbx.c                |  111 +++++++++---------------
7fda0c
 lldp_dcbx_cfg.c            |   32 ++++--
7fda0c
 lldp_dcbx_cmds.c           |   13 ++
7fda0c
 lldp_dcbx_nl.c             |   20 +---
7fda0c
 lldp_evb.c                 |    8 -
7fda0c
 lldp_evb22.c               |    8 -
7fda0c
 lldp_evb22_cmds.c          |    2 
7fda0c
 lldp_evb_cmds.c            |    2 
7fda0c
 lldp_mand.c                |   41 +++++---
7fda0c
 lldp_mand_cmds.c           |   17 ++-
7fda0c
 lldp_med.c                 |    8 -
7fda0c
 lldp_med_cmds.c            |    1 
7fda0c
 lldp_rtnl.c                |    3 
7fda0c
 lldp_tlv.c                 |   12 --
7fda0c
 lldp_util.c                |  206 +++++++++++++++++++++++++++++----------------
7fda0c
 lldpad.c                   |   21 +++-
7fda0c
 lldpad.service             |    2 
7fda0c
 lldpad.socket              |    3 
7fda0c
 lldpad.spec.in             |   36 +++++--
7fda0c
 lldptool.c                 |   38 ++------
7fda0c
 lldptool_cmds.c            |    3 
7fda0c
 log.c                      |    1 
7fda0c
 parse_cli.l                |    3 
7fda0c
 qbg/ecp.c                  |    8 -
7fda0c
 qbg/ecp22.c                |   21 +++-
7fda0c
 qbg/vdp.c                  |   16 +--
7fda0c
 qbg/vdp22.c                |   12 +-
7fda0c
 qbg/vdp22_cmds.c           |    7 -
7fda0c
 qbg/vdp22sm.c              |    4 
7fda0c
 qbg/vdp_cmds.c             |    2 
7fda0c
 qbg/vdpnl.c                |    8 -
7fda0c
 qbg_utils.c                |    3 
7fda0c
 tlv_dcbx.c                 |   33 ++++---
7fda0c
 vdptool.c                  |   23 ++---
7fda0c
 vdptool_cisco_oui.c        |    2 
7fda0c
 weak_readline.c            |   16 ++-
7fda0c
 72 files changed, 935 insertions(+), 512 deletions(-)
7fda0c
7fda0c
diff -upr a/ChangeLog b/ChangeLog
7fda0c
--- a/ChangeLog	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/ChangeLog	2021-06-09 11:00:02.478019444 -0400
7fda0c
@@ -1,3 +1,18 @@
7fda0c
+Changes from 1.1.0 to
7fda0c
+Changes from 1.0.1 to 1.1
7fda0c
+- VDP: introduce vdptool
7fda0c
+- VDP: support retrieving vsi parameter
7fda0c
+- VDP: TLV support
7fda0c
+- VDP: Support OUI infrastructure
7fda0c
+- Switch from SysV to posix shared memory
7fda0c
+- DCBX: ignore PG configurations
7fda0c
+- DCBX: Allow for read-only LLDP configuration
7fda0c
+- Support multicast MAC
7fda0c
+- autoconf: Suport systemd or sysv for init system
7fda0c
+- 802.1qaz: print prio map
7fda0c
+- lldptool: Allow to modify optional TLV content
7fda0c
+- CVE-2018-10932: Don't print raw bytes from mngAddr
7fda0c
+- Misc. bug fixes
7fda0c
 Changes from 0.9.46 to 1.0.1
7fda0c
   Mostly fixes and man page updates
7fda0c
   Added more testing infrastructure mostly for EVB
7fda0c
diff -upr a/config.c b/config.c
7fda0c
--- a/config.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/config.c	2020-10-23 14:12:58.973289274 -0400
7fda0c
@@ -56,6 +56,21 @@
7fda0c
 config_t lldpad_cfg;
7fda0c
 
7fda0c
 /*
7fda0c
+ * config_ifkey - Generates a config key
7fda0c
+ *
7fda0c
+ * Given an interface name this functions generates
7fda0c
+ * a key (based on interface's index) suitable
7fda0c
+ * to pass to libconfig.
7fda0c
+ *
7fda0c
+ */
7fda0c
+void config_ifkey(const char *name, char *ifkey) {
7fda0c
+	int index = if_nametoindex(name);
7fda0c
+	
7fda0c
+	if(index)
7fda0c
+		sprintf(ifkey, "if%d", index);
7fda0c
+}
7fda0c
+
7fda0c
+/*
7fda0c
  * init_cfg - initialze the global lldpad_cfg via config_init
7fda0c
  *
7fda0c
  * Returns true (1) for succes and false (0) for failed
7fda0c
@@ -170,7 +185,7 @@ void scan_port(UNUSED void *eloop_data,
7fda0c
 		LIST_FOREACH(agent, &port->agent_head, entry) {
7fda0c
 			LLDPAD_DBG("%s: calling ifdown for agent %p.\n",
7fda0c
 				   __func__, agent);
7fda0c
-			LIST_FOREACH(np, &lldp_head, lldp) {
7fda0c
+			LIST_FOREACH(np, &lldp_mod_head, lldp) {
7fda0c
 				ops = np->ops;
7fda0c
 				if (ops->lldp_mod_ifdown)
7fda0c
 					ops->lldp_mod_ifdown(ifname, agent);
7fda0c
@@ -219,7 +234,7 @@ int check_cfg_file(void)
7fda0c
 			}
7fda0c
 		} else {
7fda0c
 			retval = errno;
7fda0c
-			LLDPAD_ERR("%s is not readable and writeable",
7fda0c
+			LLDPAD_ERR("%s is not readable and writeable\n",
7fda0c
 				cfg_file_name);
7fda0c
 		}
7fda0c
 	}
7fda0c
@@ -295,7 +310,7 @@ int get_int_config(config_setting_t *s,
7fda0c
 	}
7fda0c
 
7fda0c
 	if (!rval)
7fda0c
-		LLDPAD_ERR("invalid value for %s", attr);
7fda0c
+		LLDPAD_ERR("invalid value for %s\n", attr);
7fda0c
 
7fda0c
 	return rval;
7fda0c
 }
7fda0c
@@ -339,7 +354,7 @@ int get_array_config(config_setting_t *s
7fda0c
 	}
7fda0c
 
7fda0c
 	if (!rval)
7fda0c
-		LLDPAD_ERR("invalid setting for %s", attr);
7fda0c
+		LLDPAD_ERR("invalid setting for %s\n", attr);
7fda0c
 
7fda0c
 	return rval;
7fda0c
 }
7fda0c
@@ -379,7 +394,7 @@ void init_ports(void)
7fda0c
 		LIST_FOREACH(agent, &port->agent_head, entry) {
7fda0c
 			LLDPAD_DBG("%s: calling ifup for agent %p.\n",
7fda0c
 				   __func__, agent);
7fda0c
-			LIST_FOREACH(np, &lldp_head, lldp) {
7fda0c
+			LIST_FOREACH(np, &lldp_mod_head, lldp) {
7fda0c
 				if (np->ops->lldp_mod_ifup)
7fda0c
 					np->ops->lldp_mod_ifup(p->if_name, agent);
7fda0c
 			}
7fda0c
@@ -451,14 +466,15 @@ static int lookup_config_value(char *pat
7fda0c
 int get_config_setting(const char *ifname, int agenttype, char *path,
7fda0c
 		       union cfg_get v, int type)
7fda0c
 {
7fda0c
-	char p[1024];
7fda0c
+	char p[1024], ifkey[IFNAMSIZ];
7fda0c
 	int rval = CONFIG_FALSE;
7fda0c
 	const char *section = agent_type2section(agenttype);
7fda0c
 
7fda0c
 	/* look for setting in section->ifname area first */
7fda0c
 	if (ifname) {
7fda0c
+		config_ifkey(ifname, ifkey);
7fda0c
 		snprintf(p, sizeof(p), "%s.%s.%s",
7fda0c
-			 section, ifname, path);
7fda0c
+			 section, ifkey, path);
7fda0c
 		rval = lookup_config_value(p, v, type);
7fda0c
 	}
7fda0c
 
7fda0c
@@ -475,15 +491,16 @@ int get_config_setting(const char *ifnam
7fda0c
 int remove_config_setting(const char *ifname, int agenttype, char *parent,
7fda0c
 			  char *name)
7fda0c
 {
7fda0c
-	char p[1024];
7fda0c
+	char p[1024], ifkey[IFNAMSIZ];
7fda0c
 	int rval = CONFIG_FALSE;
7fda0c
 	config_setting_t *setting = NULL;
7fda0c
 	const char *section = agent_type2section(agenttype);
7fda0c
 
7fda0c
 	/* look for setting in section->ifname area first */
7fda0c
-	if (ifname) {
7fda0c
+	if (ifname) { 
7fda0c
+		config_ifkey(ifname, ifkey);
7fda0c
 		snprintf(p, sizeof(p), "%s.%s.%s",
7fda0c
-			 section, ifname, parent);
7fda0c
+			 section, ifkey, parent);
7fda0c
 		setting = config_lookup(&lldpad_cfg, p);
7fda0c
 	}
7fda0c
 
7fda0c
@@ -570,15 +587,17 @@ int set_config_setting(const char *ifnam
7fda0c
 		       union cfg_set v, int type)
7fda0c
 {
7fda0c
 	config_setting_t *setting = NULL;
7fda0c
-	char p[1024];
7fda0c
+	char p[1024], ifkey[IFNAMSIZ];
7fda0c
 	int rval = cmd_success;
7fda0c
 	const char *section = agent_type2section(agenttype);
7fda0c
 
7fda0c
 	LLDPAD_DBG("%s(%i): \n", __func__, __LINE__);
7fda0c
 
7fda0c
-	if (strlen(ifname))
7fda0c
+	if (strlen(ifname)){
7fda0c
+		config_ifkey(ifname, ifkey);
7fda0c
 		snprintf(p, sizeof(p), "%s.%s.%s",
7fda0c
-			 section, ifname, path);
7fda0c
+			 section, ifkey, path);
7fda0c
+	}
7fda0c
 	else
7fda0c
 		snprintf(p, sizeof(p), "%s.%s.%s",
7fda0c
 			 section, LLDP_COMMON, path);
7fda0c
diff -upr a/configure.ac b/configure.ac
7fda0c
--- a/configure.ac	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/configure.ac	2021-06-09 11:00:02.479019457 -0400
7fda0c
@@ -1,4 +1,4 @@
7fda0c
-AC_INIT([lldpad], [1.0.1], [lldp-devel@open-lldp.org])
7fda0c
+AC_INIT([lldpad], [1.1.0], [lldp-devel@open-lldp.org])
7fda0c
 AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects])
7fda0c
 
7fda0c
 m4_pattern_allow([AM_PROG_AR])
7fda0c
@@ -25,6 +25,43 @@ then
7fda0c
  AC_MSG_ERROR([no suitable flex found. Please install the 'flex' package.])
7fda0c
 fi
7fda0c
 
7fda0c
+dnl Begin determine the systemd use and location
7fda0c
+PKG_CHECK_MODULES([SYSTEMD], [systemd], use_systemd=yes, use_systemd=no)
7fda0c
+
7fda0c
+dnl Configure developer type flags
7fda0c
+OPENLLDP_CHECK_WARNINGS
7fda0c
+OPENLLDP_CHECK_ERROR
7fda0c
+
7fda0c
+dnl Set sysvinit values, if system has systemd it will be rewritten
7fda0c
+AC_SUBST(SPEC_BUILD_REQUIRES_POST, "chkconfig")
7fda0c
+AC_SUBST(SPEC_BUILD_REQUIRES_PREUN, "chkconfig initscripts")
7fda0c
+AC_SUBST(SPEC_BUILD_REQUIRES_POSTUN, "initscripts")
7fda0c
+specfile_install="%{_sysconfdir}/init.d/lldpad"
7fda0c
+specfile_install_socket=""
7fda0c
+
7fda0c
+if test "x$use_systemd" == xyes; then
7fda0c
+        dir=""
7fda0c
+        AC_ARG_WITH([systemdsystemunitdir],
7fda0c
+                AS_HELP_STRING([--with-systemdsystem unitdir=DIR],
7fda0c
+                 [Directory for systemd service files default from pkg-config variable systemdsystemunitdir]),
7fda0c
+                [dir=${withval}],
7fda0c
+                [dir="$($PKG_CONFIG --variable=systemdsystemunitdir systemd)"])
7fda0c
+
7fda0c
+	systemdsystemunitdir=${dir}
7fda0c
+	AC_SUBST(SYSTEMD_SYSTEM_UNIT_DIR, [$systemdsystemunitdir])
7fda0c
+	specfile_install="$systemdsystemunitdir/lldpad.service"	
7fda0c
+	specfile_install_socket="$systemdsystemunitdir/lldpad.socket"
7fda0c
+
7fda0c
+	AC_SUBST(SPEC_BUILD_REQUIRES_POST, "systemd")
7fda0c
+	AC_SUBST(SPEC_BUILD_REQUIRES_PREUN, "systemd")
7fda0c
+	AC_SUBST(SPEC_BUILD_REQUIRES_POSTUN, "systemd")
7fda0c
+fi
7fda0c
+
7fda0c
+AM_CONDITIONAL(SYSTEMD_SYSTEM, test "x$use_systemd" == xyes)
7fda0c
+AC_SUBST(SPEC_FILE_LLDPAD_SERVICE, $specfile_install)
7fda0c
+AC_SUBST(SPEC_FILE_LLDPAD_SOCKET, $specfile_install_socket)
7fda0c
+dnl End systemd stuff
7fda0c
+
7fda0c
 PKG_CHECK_MODULES([LIBCONFIG], [libconfig >= 1.3.2])
7fda0c
 PKG_CHECK_MODULES([LIBNL], [libnl-3.0 >= 3.2])
7fda0c
 
7fda0c
diff -upr a/ctrl_iface.c b/ctrl_iface.c
7fda0c
--- a/ctrl_iface.c	2021-06-09 10:58:59.208200552 -0400
7fda0c
+++ b/ctrl_iface.c	2020-11-03 09:08:48.057229002 -0500
7fda0c
@@ -53,8 +53,6 @@
7fda0c
 #include "lldp_util.h"
7fda0c
 #include "messages.h"
7fda0c
 
7fda0c
-extern struct lldp_head lldp_head;
7fda0c
-
7fda0c
 struct ctrl_dst {
7fda0c
 	struct ctrl_dst *next;
7fda0c
 	struct sockaddr_un addr;
7fda0c
@@ -116,7 +114,7 @@ int clif_iface_module(struct clif_data *
7fda0c
 		return cmd_invalid;
7fda0c
 	}
7fda0c
 
7fda0c
-	mod = find_module_by_id(&lldp_head, module_id);
7fda0c
+	mod = find_module_by_id(&lldp_mod_head, module_id);
7fda0c
 	if (mod && mod->ops && mod->ops->client_cmd)
7fda0c
 		return  (mod->ops->client_cmd)(clifd, from, fromlen,
7fda0c
 			 cmd_start, cmd_len, rbuf+strlen(rbuf), rlen);
7fda0c
diff -upr a/dcb_protocol.c b/dcb_protocol.c
7fda0c
--- a/dcb_protocol.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/dcb_protocol.c	2020-09-23 08:50:52.647813847 -0400
7fda0c
@@ -75,7 +75,7 @@ void pg_insert(struct pghead *head, char
7fda0c
 	entry = (struct pg_store1 *)malloc(sizeof(struct pg_store1));
7fda0c
 	if (!entry)
7fda0c
 		return;
7fda0c
-	strncpy(entry->ifname, ifname, sizeof(entry->ifname));
7fda0c
+	STRNCPY_TERMINATED(entry->ifname, ifname, sizeof(entry->ifname));
7fda0c
 	entry->second = store;
7fda0c
 	LIST_INSERT_HEAD(head, entry, entries);
7fda0c
 }
7fda0c
@@ -1100,7 +1100,7 @@ int dcbx_remove_adapter(char *device_nam
7fda0c
 	assert(device_name);
7fda0c
 	not_default = memcmp(DEF_CFG_STORE, device_name,
7fda0c
 		strlen(DEF_CFG_STORE));
7fda0c
-	strncpy (devName, device_name, MAX_DEVICE_NAME_LEN);
7fda0c
+	STRNCPY_TERMINATED (devName, device_name, MAX_DEVICE_NAME_LEN);
7fda0c
 
7fda0c
 	if (not_default)
7fda0c
 		handle_opermode_true(device_name);
7fda0c
@@ -2257,13 +2257,8 @@ cmd_status get_bwg_descrpt(char *device_
7fda0c
 
7fda0c
 	if ((it != NULL) &&
7fda0c
 		(bwgid < it->second->max_pgid_desc)) {
7fda0c
-		size = (int)strlen(it->second->pgid_desc[bwgid]) +
7fda0c
-			sizeof(char);  /* Localization OK */
7fda0c
-		*name = (char*)malloc(size);
7fda0c
-		if (*name != NULL) {
7fda0c
-			strncpy(*name, it->second->pgid_desc[bwgid],
7fda0c
-					size); /* Localization OK */
7fda0c
-		} else {
7fda0c
+		*name = strdup(it->second->pgid_desc[bwgid]);
7fda0c
+		if (*name == NULL) {
7fda0c
 			goto Error;
7fda0c
 		}
7fda0c
 	} else {
7fda0c
@@ -2272,11 +2267,9 @@ cmd_status get_bwg_descrpt(char *device_
7fda0c
 			size = (int)strlen(
7fda0c
 				attribs.descript.pgid_desc[bwgid]) +
7fda0c
 				sizeof(char);
7fda0c
-			*name = (char*)malloc(size);
7fda0c
+			*name = (char*)calloc(size, sizeof(char));
7fda0c
 			if (*name != NULL) {
7fda0c
-				strncpy(*name,
7fda0c
-					attribs.descript.pgid_desc[bwgid],
7fda0c
-					size); /* Localization OK */
7fda0c
+				memcpy(*name, attribs.descript.pgid_desc[bwgid], size - 1); /* Localization OK */
7fda0c
 			} else {
7fda0c
 				goto Error;
7fda0c
 			}
7fda0c
diff -upr a/dcb_rule_chk.c b/dcb_rule_chk.c
7fda0c
--- a/dcb_rule_chk.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/dcb_rule_chk.c	2020-09-23 08:50:52.647813847 -0400
7fda0c
@@ -206,6 +206,8 @@ static int dcb_fixup_pg(struct pg_attrib
7fda0c
 					strict = 0;
7fda0c
 				if (be == cbe)
7fda0c
 					be = 0;
7fda0c
+				if (pgid < 0)
7fda0c
+					continue;
7fda0c
 			}
7fda0c
 
7fda0c
 			if (pg_done[i] == false) {
7fda0c
diff -upr a/dcbtool.c b/dcbtool.c
7fda0c
--- a/dcbtool.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/dcbtool.c	2020-09-23 08:50:52.647813847 -0400
7fda0c
@@ -47,6 +47,7 @@
7fda0c
 #define UNUSED __attribute__((__unused__))
7fda0c
 
7fda0c
 static int show_raw;
7fda0c
+extern void close_history(void);
7fda0c
 
7fda0c
 static const char *cli_version =
7fda0c
 "dcbtool v" DCBTOOL_VERSION "\n"
7fda0c
@@ -460,6 +461,7 @@ static void cli_interactive(int raw)
7fda0c
 			request(clif_conn, argc, argv, raw);
7fda0c
 		free(cmd);
7fda0c
 	} while (!cli_quit);
7fda0c
+	close_history();
7fda0c
 }
7fda0c
 
7fda0c
 static void cli_terminate(UNUSED int sig)
7fda0c
diff -upr a/dcbtool_cmds.c b/dcbtool_cmds.c
7fda0c
--- a/dcbtool_cmds.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/dcbtool_cmds.c	2020-09-23 08:50:52.647813847 -0400
7fda0c
@@ -27,6 +27,7 @@
7fda0c
 #include <stdlib.h>
7fda0c
 #include <stdio.h>
7fda0c
 #include <ctype.h>
7fda0c
+#include <sys/types.h>
7fda0c
 #include "clif.h"
7fda0c
 #include "dcbtool.h"
7fda0c
 #include "lldp_dcbx_cmds.h"
7fda0c
@@ -38,7 +39,6 @@
7fda0c
 
7fda0c
 static char *print_status(cmd_status status);
7fda0c
 static char *get_pgdesc_args(int cmd);
7fda0c
-static int hex2int(char *b);
7fda0c
 static void free_cmd_args(char *args);
7fda0c
 static char *get_dcb_args(void);
7fda0c
 static char *get_dcbx_args(void);
7fda0c
@@ -93,28 +93,6 @@ static char *print_status(cmd_status sta
7fda0c
 	return str;
7fda0c
 }
7fda0c
 
7fda0c
-/* assumes input is pointer to two hex digits */
7fda0c
-/* returns -1 on error */
7fda0c
-static int hex2int(char *b)
7fda0c
-{
7fda0c
-	int i;
7fda0c
-	int n=0;
7fda0c
-	int m;
7fda0c
-	
7fda0c
-	for (i=0,m=1; i<2; i++,m--) {
7fda0c
-		if (isxdigit(*(b+i))) {
7fda0c
-			if (*(b+i) <= '9')
7fda0c
-				n |= (*(b+i) & 0x0f) << (4*m);
7fda0c
-			else
7fda0c
-				n |= ((*(b+i) & 0x0f) + 9) << (4*m);
7fda0c
-		}
7fda0c
-		else {
7fda0c
-			return -1;
7fda0c
-		}
7fda0c
-	}
7fda0c
-	return n;
7fda0c
-}
7fda0c
-
7fda0c
 static char *get_dcb_args(void)
7fda0c
 {
7fda0c
 	char buf[8];
7fda0c
diff -upr a/docs/liblldp_clif-vdp22.3 b/docs/liblldp_clif-vdp22.3
7fda0c
--- a/docs/liblldp_clif-vdp22.3	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/docs/liblldp_clif-vdp22.3	2020-11-03 09:08:48.058229019 -0500
7fda0c
@@ -1,6 +1,6 @@
7fda0c
 .TH liblldp_clif 3 "February 2014" "open-lldp" "Linux"
7fda0c
 .SH NAME
7fda0c
-clif_vsi,clif_vsievt,clif_vsiwait \- Manipulate VDP IEEE 802.1 Ratified Standard Assocications
7fda0c
+clif_vsi,clif_vsievt,clif_vsiwait \- Manipulate VDP IEEE 802.1 Ratified Standard Associations
7fda0c
 .SH SYNOPSIS
7fda0c
 #include "include/clif.h"
7fda0c
 .sp 1
7fda0c
diff -upr a/docs/lldptool.8 b/docs/lldptool.8
7fda0c
--- a/docs/lldptool.8	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/docs/lldptool.8	2020-11-03 09:08:48.058229019 -0500
7fda0c
@@ -160,9 +160,9 @@ Query the LLDP adminStatus for interface
7fda0c
 
7fda0c
 .TP
7fda0c
 Query the LLDP statistics for interface \fIeth3\fR
7fda0c
-.B lldptool -S -i eth3 adminStatus
7fda0c
+.B lldptool -S -i eth3
7fda0c
 .br
7fda0c
-.B lldptool stats -i eth3 adminStatus
7fda0c
+.B lldptool stats -i eth3
7fda0c
 
7fda0c
 .TP
7fda0c
 Query the local TLVs which are being transmitted for a given interface:
7fda0c
diff -upr a/event_iface.c b/event_iface.c
7fda0c
--- a/event_iface.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/event_iface.c	2021-01-06 11:05:30.808649405 -0500
7fda0c
@@ -77,7 +77,7 @@ static void event_if_decode_rta(int type
7fda0c
 		LLDPAD_DBG(" IFLA_BROADCAST\n");
7fda0c
 		break;
7fda0c
 	case IFLA_IFNAME:
7fda0c
-		strncpy(d, (char *)RTA_DATA(rta), IFNAMSIZ);
7fda0c
+		STRNCPY_TERMINATED(d, (char *)RTA_DATA(rta), IFNAMSIZ);
7fda0c
 		LLDPAD_DBG(" IFLA_IFNAME\n");
7fda0c
 		LLDPAD_DBG("        device name is %s\n", d);
7fda0c
 		break;
7fda0c
@@ -205,6 +205,9 @@ int oper_add_device(char *device_name)
7fda0c
 		port = newport;
7fda0c
 	} else if (is_bond(device_name) || !port->portEnabled)
7fda0c
 		reinit_port(device_name);
7fda0c
+	else if (port->portEnabled) {
7fda0c
+		return 0;
7fda0c
+	}
7fda0c
 
7fda0c
 	lldp_add_agent(device_name, NEAREST_BRIDGE);
7fda0c
 	lldp_add_agent(device_name, NEAREST_NONTPMR_BRIDGE);
7fda0c
@@ -213,7 +216,7 @@ int oper_add_device(char *device_name)
7fda0c
 	LIST_FOREACH(agent, &port->agent_head, entry) {
7fda0c
 		LLDPAD_DBG("%s: calling ifup for agent %p.\n",
7fda0c
 			   __func__, agent);
7fda0c
-		LIST_FOREACH(np, &lldp_head, lldp) {
7fda0c
+		LIST_FOREACH(np, &lldp_mod_head, lldp) {
7fda0c
 			if (np->ops->lldp_mod_ifup)
7fda0c
 				np->ops->lldp_mod_ifup(device_name, agent);
7fda0c
 		}
7fda0c
@@ -280,7 +283,7 @@ static void event_if_decode_nlmsg(int ro
7fda0c
 			LIST_FOREACH(agent, &port->agent_head, entry) {
7fda0c
 				LLDPAD_DBG("%s: calling ifdown for agent %p.\n",
7fda0c
 					   __func__, agent);
7fda0c
-				LIST_FOREACH(np, &lldp_head, lldp) {
7fda0c
+				LIST_FOREACH(np, &lldp_mod_head, lldp) {
7fda0c
 					ops = np->ops;
7fda0c
 					if (ops->lldp_mod_ifdown)
7fda0c
 						ops->lldp_mod_ifdown(device_name,
7fda0c
@@ -415,7 +418,8 @@ event_iface_receive(int sock, UNUSED voi
7fda0c
 int event_iface_init()
7fda0c
 {
7fda0c
 	int fd;
7fda0c
-	int rcv_size = MAX_PAYLOAD;
7fda0c
+	int rcv_size = 0;
7fda0c
+	socklen_t rcv_len = sizeof(int);
7fda0c
 	struct sockaddr_nl snl;
7fda0c
 
7fda0c
 	fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
7fda0c
@@ -423,10 +427,18 @@ int event_iface_init()
7fda0c
 	if (fd < 0)
7fda0c
 		return fd;
7fda0c
 
7fda0c
-	if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcv_size, sizeof(int)) < 0) {
7fda0c
+	/* is receive buffer size too small? */
7fda0c
+	if (getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcv_size, &rcv_len) < 0) {
7fda0c
 		close(fd);
7fda0c
 		return -EIO;
7fda0c
 	}
7fda0c
+	if (rcv_size < MIN_RCVBUF_SIZE) {
7fda0c
+		rcv_size = MIN_RCVBUF_SIZE >> 1;	/* we get back 2x what we set */
7fda0c
+		if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcv_size, rcv_len) < 0) {
7fda0c
+			close(fd);
7fda0c
+			return -EIO;
7fda0c
+		}
7fda0c
+	}
7fda0c
 
7fda0c
 	memset((void *)&snl, 0, sizeof(struct sockaddr_nl));
7fda0c
 	snl.nl_family = AF_NETLINK;
7fda0c
diff -upr a/include/config.h b/include/config.h
7fda0c
--- a/include/config.h	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/include/config.h	2020-09-23 08:50:52.647813847 -0400
7fda0c
@@ -111,4 +111,7 @@ void destroy_cfg(void);
7fda0c
 int check_cfg_file(void);
7fda0c
 int check_for_old_file_format(void);
7fda0c
 void init_ports(void);
7fda0c
+
7fda0c
+void config_ifkey(const char *name, char *ifkey);
7fda0c
+
7fda0c
 #endif /* _CONFIG_H_ */
7fda0c
diff -upr a/include/linux/if_link.h b/include/linux/if_link.h
7fda0c
--- a/include/linux/if_link.h	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/include/linux/if_link.h	2020-09-23 08:50:52.648813865 -0400
7fda0c
@@ -116,15 +116,34 @@ enum {
7fda0c
 	IFLA_STATS64,
7fda0c
 	IFLA_VF_PORTS,
7fda0c
 	IFLA_PORT_SELF,
7fda0c
-        IFLA_AF_SPEC,
7fda0c
-        IFLA_GROUP,             /* Group the device belongs to */
7fda0c
-        IFLA_NET_NS_FD,
7fda0c
-        IFLA_EXT_MASK,          /* Extended info mask, VFs, etc */
7fda0c
-        IFLA_PROMISCUITY,       /* Promiscuity count: > 0 means acts PROMISC */
7fda0c
+	IFLA_AF_SPEC,
7fda0c
+	IFLA_GROUP,		/* Group the device belongs to */
7fda0c
+	IFLA_NET_NS_FD,
7fda0c
+	IFLA_EXT_MASK,		/* Extended info mask, VFs, etc */
7fda0c
+	IFLA_PROMISCUITY,	/* Promiscuity count: > 0 means acts PROMISC */
7fda0c
 #define IFLA_PROMISCUITY IFLA_PROMISCUITY
7fda0c
-        IFLA_NUM_TX_QUEUES,
7fda0c
-        IFLA_NUM_RX_QUEUES,
7fda0c
-        IFLA_CARRIER,
7fda0c
+	IFLA_NUM_TX_QUEUES,
7fda0c
+	IFLA_NUM_RX_QUEUES,
7fda0c
+	IFLA_CARRIER,
7fda0c
+	IFLA_PHYS_PORT_ID,
7fda0c
+	IFLA_CARRIER_CHANGES,
7fda0c
+	IFLA_PHYS_SWITCH_ID,
7fda0c
+	IFLA_LINK_NETNSID,
7fda0c
+	IFLA_PHYS_PORT_NAME,
7fda0c
+	IFLA_PROTO_DOWN,
7fda0c
+	IFLA_GSO_MAX_SEGS,
7fda0c
+	IFLA_GSO_MAX_SIZE,
7fda0c
+	IFLA_PAD,
7fda0c
+	IFLA_XDP,
7fda0c
+	IFLA_EVENT,
7fda0c
+	IFLA_NEW_NETNSID,
7fda0c
+	IFLA_IF_NETNSID,
7fda0c
+	IFLA_TARGET_NETNSID = IFLA_IF_NETNSID, /* new alias */
7fda0c
+	IFLA_CARRIER_UP_COUNT,
7fda0c
+	IFLA_CARRIER_DOWN_COUNT,
7fda0c
+	IFLA_NEW_IFINDEX,
7fda0c
+	IFLA_MIN_MTU,
7fda0c
+	IFLA_MAX_MTU,
7fda0c
 	__IFLA_MAX
7fda0c
 };
7fda0c
 
7fda0c
@@ -192,6 +211,8 @@ enum {
7fda0c
 	IFLA_INFO_KIND,
7fda0c
 	IFLA_INFO_DATA,
7fda0c
 	IFLA_INFO_XSTATS,
7fda0c
+	IFLA_INFO_SLAVE_KIND,
7fda0c
+	IFLA_INFO_SLAVE_DATA,
7fda0c
 	__IFLA_INFO_MAX,
7fda0c
 };
7fda0c
 
7fda0c
@@ -243,6 +264,69 @@ enum macvlan_mode {
7fda0c
 	MACVLAN_MODE_BRIDGE  = 4, /* talk to bridge ports directly */
7fda0c
 };
7fda0c
 
7fda0c
+/* Bonding section */
7fda0c
+
7fda0c
+enum {
7fda0c
+	IFLA_BOND_UNSPEC,
7fda0c
+	IFLA_BOND_MODE,
7fda0c
+	IFLA_BOND_ACTIVE_SLAVE,
7fda0c
+	IFLA_BOND_MIIMON,
7fda0c
+	IFLA_BOND_UPDELAY,
7fda0c
+	IFLA_BOND_DOWNDELAY,
7fda0c
+	IFLA_BOND_USE_CARRIER,
7fda0c
+	IFLA_BOND_ARP_INTERVAL,
7fda0c
+	IFLA_BOND_ARP_IP_TARGET,
7fda0c
+	IFLA_BOND_ARP_VALIDATE,
7fda0c
+	IFLA_BOND_ARP_ALL_TARGETS,
7fda0c
+	IFLA_BOND_PRIMARY,
7fda0c
+	IFLA_BOND_PRIMARY_RESELECT,
7fda0c
+	IFLA_BOND_FAIL_OVER_MAC,
7fda0c
+	IFLA_BOND_XMIT_HASH_POLICY,
7fda0c
+	IFLA_BOND_RESEND_IGMP,
7fda0c
+	IFLA_BOND_NUM_PEER_NOTIF,
7fda0c
+	IFLA_BOND_ALL_SLAVES_ACTIVE,
7fda0c
+	IFLA_BOND_MIN_LINKS,
7fda0c
+	IFLA_BOND_LP_INTERVAL,
7fda0c
+	IFLA_BOND_PACKETS_PER_SLAVE,
7fda0c
+	IFLA_BOND_AD_LACP_RATE,
7fda0c
+	IFLA_BOND_AD_SELECT,
7fda0c
+	IFLA_BOND_AD_INFO,
7fda0c
+	IFLA_BOND_AD_ACTOR_SYS_PRIO,
7fda0c
+	IFLA_BOND_AD_USER_PORT_KEY,
7fda0c
+	IFLA_BOND_AD_ACTOR_SYSTEM,
7fda0c
+	IFLA_BOND_TLB_DYNAMIC_LB,
7fda0c
+	__IFLA_BOND_MAX,
7fda0c
+};
7fda0c
+
7fda0c
+#define IFLA_BOND_MAX	(__IFLA_BOND_MAX - 1)
7fda0c
+
7fda0c
+enum {
7fda0c
+	IFLA_BOND_AD_INFO_UNSPEC,
7fda0c
+	IFLA_BOND_AD_INFO_AGGREGATOR,
7fda0c
+	IFLA_BOND_AD_INFO_NUM_PORTS,
7fda0c
+	IFLA_BOND_AD_INFO_ACTOR_KEY,
7fda0c
+	IFLA_BOND_AD_INFO_PARTNER_KEY,
7fda0c
+	IFLA_BOND_AD_INFO_PARTNER_MAC,
7fda0c
+	__IFLA_BOND_AD_INFO_MAX,
7fda0c
+};
7fda0c
+
7fda0c
+#define IFLA_BOND_AD_INFO_MAX	(__IFLA_BOND_AD_INFO_MAX - 1)
7fda0c
+
7fda0c
+enum {
7fda0c
+	IFLA_BOND_SLAVE_UNSPEC,
7fda0c
+	IFLA_BOND_SLAVE_STATE,
7fda0c
+	IFLA_BOND_SLAVE_MII_STATUS,
7fda0c
+	IFLA_BOND_SLAVE_LINK_FAILURE_COUNT,
7fda0c
+	IFLA_BOND_SLAVE_PERM_HWADDR,
7fda0c
+	IFLA_BOND_SLAVE_QUEUE_ID,
7fda0c
+	IFLA_BOND_SLAVE_AD_AGGREGATOR_ID,
7fda0c
+	IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE,
7fda0c
+	IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE,
7fda0c
+	__IFLA_BOND_SLAVE_MAX,
7fda0c
+};
7fda0c
+
7fda0c
+#define IFLA_BOND_SLAVE_MAX	(__IFLA_BOND_SLAVE_MAX - 1)
7fda0c
+
7fda0c
 /* SR-IOV virtual function management section */
7fda0c
 
7fda0c
 enum {
7fda0c
diff -upr a/include/lldp_basman_clif.h b/include/lldp_basman_clif.h
7fda0c
--- a/include/lldp_basman_clif.h	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/include/lldp_basman_clif.h	2020-09-23 08:50:52.648813865 -0400
7fda0c
@@ -31,7 +31,7 @@ struct lldp_module *basman_cli_register(
7fda0c
 void basman_cli_unregister(struct lldp_module *);
7fda0c
 int basman_print_tlv(u32, u16, char *);
7fda0c
 
7fda0c
-#define ARG_IPV4_ADDR "ipv4"
7fda0c
-#define ARG_IPV6_ADDR "ipv6"
7fda0c
-
7fda0c
+#define ARG_IPV4_ADDR	"ipv4"
7fda0c
+#define ARG_IPV6_ADDR	"ipv6"
7fda0c
+#define ARG_TLVINFO	"info"
7fda0c
 #endif
7fda0c
diff -upr a/include/lldp.h b/include/lldp.h
7fda0c
--- a/include/lldp.h	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/include/lldp.h	2020-09-23 08:50:52.648813865 -0400
7fda0c
@@ -51,6 +51,13 @@ typedef __u64 u64;
7fda0c
 		__x > __y ? __x : __y;	\
7fda0c
 	 })
7fda0c
 
7fda0c
+/* Use strncpy with N-1 and ensure the string is terminated.  */
7fda0c
+#define STRNCPY_TERMINATED(DEST, SRC, N) \
7fda0c
+  do { \
7fda0c
+    strncpy (DEST, SRC, N - 1); \
7fda0c
+    DEST[N - 1] = '\0'; \
7fda0c
+  } while (false)
7fda0c
+
7fda0c
 /*
7fda0c
  * Organizationally Unique Identifier (OUI)
7fda0c
  * http://standards.ieee.org/regauth/oui/oui.txt
7fda0c
@@ -248,5 +255,11 @@ enum {
7fda0c
 #define LLDP_EVB_DEFAULT_RTE				15
7fda0c
 #define LLDP_EVB_DEFAULT_MAX_RTE			31
7fda0c
 
7fda0c
+#ifndef _MSC_VER
7fda0c
+#define STRUCT_PACKED(STRUCT) STRUCT __attribute__((__packed__))
7fda0c
+#else
7fda0c
+#define STRUCT_PACKED(STRUCT) __pragma(pack(push, 1)) STRUCT __pragma(pack(pop))
7fda0c
+#endif
7fda0c
+
7fda0c
 void somethingChangedLocal(const char *ifname, int type);
7fda0c
 #endif /* _LLDP_H */
7fda0c
diff -upr a/include/lldp_mod.h b/include/lldp_mod.h
7fda0c
--- a/include/lldp_mod.h	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/include/lldp_mod.h	2020-10-23 14:12:58.974289292 -0400
7fda0c
@@ -96,7 +96,7 @@ struct lldp_module {
7fda0c
 };
7fda0c
 
7fda0c
 LIST_HEAD(lldp_head, lldp_module);
7fda0c
-struct lldp_head lldp_head;
7fda0c
+extern struct lldp_head lldp_mod_head;
7fda0c
 
7fda0c
 static inline struct lldp_module *find_module_by_id(struct lldp_head *head, int id)
7fda0c
 {
7fda0c
diff -upr a/include/lldp_tlv.h b/include/lldp_tlv.h
7fda0c
--- a/include/lldp_tlv.h	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/include/lldp_tlv.h	2020-09-23 08:50:52.648813865 -0400
7fda0c
@@ -104,8 +104,8 @@ struct packed_tlv *pack_tlv(struct unpac
7fda0c
 struct unpacked_tlv *unpack_tlv(struct packed_tlv *tlv);
7fda0c
 int pack_tlv_after(struct unpacked_tlv *, struct packed_tlv *, int);
7fda0c
 
7fda0c
-struct unpacked_tlv *free_unpkd_tlv(struct unpacked_tlv *tlv);
7fda0c
-struct packed_tlv *free_pkd_tlv(struct packed_tlv *tlv);
7fda0c
+void free_unpkd_tlv(struct unpacked_tlv *tlv);
7fda0c
+void free_pkd_tlv(struct packed_tlv *tlv);
7fda0c
 struct unpacked_tlv *create_tlv(void);
7fda0c
 struct packed_tlv *create_ptlv(void);
7fda0c
 struct unpacked_tlv *bld_end_tlv(void);
7fda0c
@@ -115,14 +115,18 @@ int tlv_ok(struct unpacked_tlv *tlv);
7fda0c
 
7fda0c
 #define FREE_UNPKD_TLV(d, f) \
7fda0c
 { \
7fda0c
-	if ((d)->f) \
7fda0c
-		(d)->f = free_unpkd_tlv((d)->f); \
7fda0c
+	if ((d)->f) {				 \
7fda0c
+		free_unpkd_tlv((d)->f);		 \
7fda0c
+		(d)->f = NULL;			 \
7fda0c
+	}					 \
7fda0c
 }
7fda0c
 
7fda0c
 #define FREE_PKD_TLV(d, f) \
7fda0c
 { \
7fda0c
-	if ((d)->f) \
7fda0c
-		(d)->f = free_pkd_tlv((d)->f); \
7fda0c
+	if ((d)->f) {			       \
7fda0c
+		free_pkd_tlv((d)->f);	       \
7fda0c
+		(d)->f = NULL;		       \
7fda0c
+	}				       \
7fda0c
 }
7fda0c
 
7fda0c
 #define PACK_TLV_AFTER(t, p, l, g) 		\
7fda0c
diff -upr a/include/lldptool.h b/include/lldptool.h
7fda0c
--- a/include/lldptool.h	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/include/lldptool.h	2020-09-23 08:50:52.648813865 -0400
7fda0c
@@ -29,9 +29,8 @@
7fda0c
 
7fda0c
 #include "clif.h"
7fda0c
 
7fda0c
-struct lldp_head lldp_cli_head;
7fda0c
+extern struct lldp_head lldp_cli_head;
7fda0c
 
7fda0c
-int hex2int(char *b);
7fda0c
 int clif_command(struct clif *clif, char *cmd, int raw);
7fda0c
 void print_raw_message(char *msg, int print);
7fda0c
 int parse_print_message(char *msg, int print);
7fda0c
diff -upr a/include/lldp_util.h b/include/lldp_util.h
7fda0c
--- a/include/lldp_util.h	2021-06-09 10:58:59.214200629 -0400
7fda0c
+++ b/include/lldp_util.h	2021-04-05 12:02:17.318590504 -0400
7fda0c
@@ -119,6 +119,7 @@
7fda0c
 
7fda0c
 int hexstr2bin(const char *hex, u8 *buf, size_t len);
7fda0c
 int bin2hexstr(const u8 *hex, size_t hexlen, char *buf, size_t buflen);
7fda0c
+int hex2int(char *b);
7fda0c
 
7fda0c
 int is_valid_lldp_device(const char *ifname);
7fda0c
 int is_active(const char *ifname);
7fda0c
@@ -149,8 +150,7 @@ int get_mautype(const char *);
7fda0c
 int get_ifpflags(const char *);
7fda0c
 int get_iftype(const char *);
7fda0c
 int get_src_mac_from_bond(struct port *bond_port, char *ifname, u8 *addr);
7fda0c
-int get_mac(const char *ifname, u8 mac[]);
7fda0c
-int get_macstr(const char *ifname, char *addr, size_t size);
7fda0c
+int get_mac(const char *ifname, u8 mac[], bool perm_mac);
7fda0c
 int get_saddr(const char *ifname, struct sockaddr_in *saddr);
7fda0c
 int get_ipaddr(const char *ifname, struct in_addr *);
7fda0c
 int get_ipaddrstr(const char *ifname, char *ipaddr, size_t size);
7fda0c
diff -upr a/include/qbg_ecp22.h b/include/qbg_ecp22.h
7fda0c
--- a/include/qbg_ecp22.h	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/include/qbg_ecp22.h	2020-09-23 08:50:52.649813883 -0400
7fda0c
@@ -49,10 +49,10 @@ enum {					/* ECP Transmit states */
7fda0c
 	ECP22_TX_ERROR
7fda0c
 };
7fda0c
 
7fda0c
-enum {
7fda0c
+enum ecp22_mode {
7fda0c
 	ECP22_REQUEST = 0,
7fda0c
 	ECP22_ACK
7fda0c
-} ecp22_mode;
7fda0c
+};
7fda0c
 
7fda0c
 struct ecp22_hdr {		/* ECP22 header */
7fda0c
 	u16 ver_op_sub;		/* ECP22 version, operation, subtype */
7fda0c
diff -upr a/include/qbg_vdpnl.h b/include/qbg_vdpnl.h
7fda0c
--- a/include/qbg_vdpnl.h	2021-06-09 10:58:59.201200461 -0400
7fda0c
+++ b/include/qbg_vdpnl.h	2021-01-06 11:05:30.810649436 -0500
7fda0c
@@ -33,6 +33,7 @@
7fda0c
 #include <linux/if_ether.h>
7fda0c
 
7fda0c
 #define	MAX_PAYLOAD	4096	/* Maximum Payload Size */
7fda0c
+#define	MIN_RCVBUF_SIZE	(MAX_PAYLOAD << 5)	/* SO_RCVBUF min */
7fda0c
 
7fda0c
 enum {
7fda0c
 	vdpnl_nlf1 = 1,		/* Netlink message format 1 (draft 0.2) */
7fda0c
diff -upr a/lldp/agent.c b/lldp/agent.c
7fda0c
--- a/lldp/agent.c	2021-06-09 10:58:59.215200642 -0400
7fda0c
+++ b/lldp/agent.c	2021-01-06 11:05:30.811649451 -0500
7fda0c
@@ -163,7 +163,7 @@ static void timer(UNUSED void *eloop_dat
7fda0c
 			run_rx_sm(port, agent);
7fda0c
 			update_rx_timers(agent);
7fda0c
 
7fda0c
-			LIST_FOREACH(n, &lldp_head, lldp) {
7fda0c
+			LIST_FOREACH(n, &lldp_mod_head, lldp) {
7fda0c
 				if (n->ops && n->ops->timer)
7fda0c
 					n->ops->timer(port, agent);
7fda0c
 			}
7fda0c
@@ -200,7 +200,7 @@ void clean_lldp_agents(void)
7fda0c
 			LLDPAD_DBG("Send shutdown frame on port %s\n",
7fda0c
 				port->ifname);
7fda0c
 			LIST_FOREACH(agent, &port->agent_head, entry) {
7fda0c
-				process_tx_shutdown_frame(port, agent);
7fda0c
+				process_tx_shutdown_frame(port, agent, false);
7fda0c
 			}
7fda0c
 		} else {
7fda0c
 			LLDPAD_DBG("No shutdown frame is sent on port %s\n",
7fda0c
diff -upr a/lldp/l2_packet.h b/lldp/l2_packet.h
7fda0c
--- a/lldp/l2_packet.h	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/lldp/l2_packet.h	2020-09-23 08:50:52.649813883 -0400
7fda0c
@@ -37,7 +37,9 @@
7fda0c
 #define IP2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
7fda0c
 #define IPSTR "%02x:%02x:%02x:%02x:%02x:%02x"
7fda0c
 
7fda0c
+#ifndef ETH_P_LLDP
7fda0c
 #define ETH_P_LLDP 0x88cc
7fda0c
+#endif
7fda0c
 
7fda0c
 #define ETH_P_ECP	0x88b7		/* Draft 0.2 */
7fda0c
 #define ETH_P_ECP22	0x8940		/* Ratified standard */
7fda0c
@@ -56,12 +58,11 @@
7fda0c
  */
7fda0c
 struct l2_packet_data;
7fda0c
 
7fda0c
-
7fda0c
-struct l2_ethhdr {
7fda0c
+STRUCT_PACKED(struct l2_ethhdr {
7fda0c
 	u8 h_dest[ETH_ALEN];
7fda0c
 	u8 h_source[ETH_ALEN];
7fda0c
 	u16 h_proto;
7fda0c
-} STRUCT_PACKED;
7fda0c
+});
7fda0c
 
7fda0c
 /**
7fda0c
  * l2_packet_init - Initialize l2_packet interface
7fda0c
diff -upr a/lldp/l2_packet_linux.c b/lldp/l2_packet_linux.c
7fda0c
--- a/lldp/l2_packet_linux.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/lldp/l2_packet_linux.c	2020-09-23 08:50:52.649813883 -0400
7fda0c
@@ -60,7 +60,7 @@ struct l2_packet_data {
7fda0c
 
7fda0c
 int l2_packet_get_own_src_addr(struct l2_packet_data *l2, u8 *addr)
7fda0c
 {
7fda0c
-	if (is_san_mac(l2->san_mac_addr))
7fda0c
+	if (is_valid_mac(l2->san_mac_addr))
7fda0c
 		memcpy(addr, l2->san_mac_addr, ETH_ALEN);
7fda0c
 	else {
7fda0c
 		/* get an appropriate src MAC to use if the port is
7fda0c
@@ -169,7 +169,7 @@ struct l2_packet_data * l2_packet_init(
7fda0c
 	if (l2 == NULL)
7fda0c
 		return NULL;
7fda0c
 	memset(l2, 0, sizeof(*l2));
7fda0c
-	strncpy(l2->ifname, ifname, sizeof(l2->ifname));
7fda0c
+	STRNCPY_TERMINATED(l2->ifname, ifname, sizeof(l2->ifname));
7fda0c
 	l2->rx_callback = rx_callback;
7fda0c
 	l2->rx_callback_ctx = rx_callback_ctx;
7fda0c
 	l2->l2_hdr = l2_hdr;
7fda0c
@@ -183,7 +183,7 @@ struct l2_packet_data * l2_packet_init(
7fda0c
 		return NULL;
7fda0c
 	}
7fda0c
 
7fda0c
-	strncpy(ifr.ifr_name, l2->ifname, sizeof(ifr.ifr_name));
7fda0c
+	STRNCPY_TERMINATED(ifr.ifr_name, l2->ifname, sizeof(ifr.ifr_name));
7fda0c
 	if (ioctl(l2->fd, SIOCGIFINDEX, &ifr) < 0) {
7fda0c
 		perror("ioctl[SIOCGIFINDEX]");
7fda0c
 		close(l2->fd);
7fda0c
diff -upr a/lldp/ports.c b/lldp/ports.c
7fda0c
--- a/lldp/ports.c	2021-06-09 10:58:59.211200590 -0400
7fda0c
+++ b/lldp/ports.c	2020-12-07 13:15:10.579203256 -0500
7fda0c
@@ -264,7 +264,7 @@ struct port *add_port(int ifindex, const
7fda0c
 	memset(newport, 0, sizeof(*newport));
7fda0c
 	newport->ifindex = ifindex;
7fda0c
 	newport->next = NULL;
7fda0c
-	strncpy(newport->ifname, ifname, IFNAMSIZ);
7fda0c
+	strncpy(newport->ifname, ifname, IFNAMSIZ - 1);
7fda0c
 
7fda0c
 	newport->bond_master = is_bond(ifname);
7fda0c
 	/* Initialize relevant port variables */
7fda0c
diff -upr a/lldp/rx.c b/lldp/rx.c
7fda0c
--- a/lldp/rx.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/lldp/rx.c	2021-06-09 11:00:02.480019469 -0400
7fda0c
@@ -139,7 +139,16 @@ void rxProcessFrame(struct port *port, s
7fda0c
 	int err;
7fda0c
 	struct lldp_module *np;
7fda0c
 
7fda0c
-	assert(agent->rx.framein && agent->rx.sizein);
7fda0c
+	if (!agent->rx.framein) {
7fda0c
+		LLDPAD_DBG("ERROR - agent framein not set, "
7fda0c
+			   "has the neighbour MAC changed? "
7fda0c
+			   "Ignoring packet.\n");
7fda0c
+		return;
7fda0c
+	}
7fda0c
+	if (!agent->rx.sizein) {
7fda0c
+		LLDPAD_DBG("Size-0 packet received, ignoring packet\n");
7fda0c
+		return;
7fda0c
+	}
7fda0c
 	agent->lldpdu = 0;
7fda0c
 	agent->rx.dupTlvs = 0;
7fda0c
 
7fda0c
@@ -359,7 +368,7 @@ void rxProcessFrame(struct port *port, s
7fda0c
 		}
7fda0c
 
7fda0c
 		/* rx per lldp module */
7fda0c
-		LIST_FOREACH(np, &lldp_head, lldp) {
7fda0c
+		LIST_FOREACH(np, &lldp_mod_head, lldp) {
7fda0c
 			if (!np->ops || !np->ops->lldp_mod_rchange)
7fda0c
 				continue;
7fda0c
 
7fda0c
@@ -377,7 +386,7 @@ void rxProcessFrame(struct port *port, s
7fda0c
 		if (!tlv_stored) {
7fda0c
 			LLDPAD_INFO("%s: allocated TLV %u was not stored! %p\n",
7fda0c
 				   __func__, tlv->type, tlv);
7fda0c
-			tlv = free_unpkd_tlv(tlv);
7fda0c
+			free_unpkd_tlv(tlv);
7fda0c
 			agent->stats.statsTLVsUnrecognizedTotal++;
7fda0c
 		}
7fda0c
 		tlv = NULL;
7fda0c
@@ -402,7 +411,7 @@ u8 mibDeleteObjects(struct port *port, s
7fda0c
 {
7fda0c
 	struct lldp_module *np;
7fda0c
 
7fda0c
-	LIST_FOREACH(np, &lldp_head, lldp) {
7fda0c
+	LIST_FOREACH(np, &lldp_mod_head, lldp) {
7fda0c
 		if (!np->ops || !np->ops->lldp_mod_mibdelete)
7fda0c
 			continue;
7fda0c
 		np->ops->lldp_mod_mibdelete(port, agent);
7fda0c
@@ -638,29 +647,21 @@ void rx_change_state(struct lldp_agent *
7fda0c
 void clear_manifest(struct lldp_agent *agent)
7fda0c
 {
7fda0c
 	if (agent->rx.manifest->mgmtadd)
7fda0c
-		agent->rx.manifest->mgmtadd =
7fda0c
-			free_unpkd_tlv(agent->rx.manifest->mgmtadd);
7fda0c
+		free_unpkd_tlv(agent->rx.manifest->mgmtadd);
7fda0c
 	if (agent->rx.manifest->syscap)
7fda0c
-		agent->rx.manifest->syscap =
7fda0c
-			free_unpkd_tlv(agent->rx.manifest->syscap);
7fda0c
+		free_unpkd_tlv(agent->rx.manifest->syscap);
7fda0c
 	if (agent->rx.manifest->sysdesc)
7fda0c
-		agent->rx.manifest->sysdesc =
7fda0c
-			free_unpkd_tlv(agent->rx.manifest->sysdesc);
7fda0c
+		free_unpkd_tlv(agent->rx.manifest->sysdesc);
7fda0c
 	if (agent->rx.manifest->sysname)
7fda0c
-		agent->rx.manifest->sysname =
7fda0c
-			free_unpkd_tlv(agent->rx.manifest->sysname);
7fda0c
+		free_unpkd_tlv(agent->rx.manifest->sysname);
7fda0c
 	if (agent->rx.manifest->portdesc)
7fda0c
-		agent->rx.manifest->portdesc =
7fda0c
-			free_unpkd_tlv(agent->rx.manifest->portdesc);
7fda0c
+		free_unpkd_tlv(agent->rx.manifest->portdesc);
7fda0c
 	if (agent->rx.manifest->ttl)
7fda0c
-		agent->rx.manifest->ttl =
7fda0c
-			free_unpkd_tlv(agent->rx.manifest->ttl);
7fda0c
+		free_unpkd_tlv(agent->rx.manifest->ttl);
7fda0c
 	if (agent->rx.manifest->portid)
7fda0c
-		agent->rx.manifest->portid =
7fda0c
-			free_unpkd_tlv(agent->rx.manifest->portid);
7fda0c
+		free_unpkd_tlv(agent->rx.manifest->portid);
7fda0c
 	if (agent->rx.manifest->chassis)
7fda0c
-		agent->rx.manifest->chassis =
7fda0c
-			free_unpkd_tlv(agent->rx.manifest->chassis);
7fda0c
+		free_unpkd_tlv(agent->rx.manifest->chassis);
7fda0c
 	free(agent->rx.manifest);
7fda0c
 	agent->rx.manifest = NULL;
7fda0c
 }
7fda0c
diff -upr a/lldp/states.h b/lldp/states.h
7fda0c
--- a/lldp/states.h	2021-06-09 10:58:59.211200590 -0400
7fda0c
+++ b/lldp/states.h	2021-01-06 11:05:30.811649451 -0500
7fda0c
@@ -85,7 +85,7 @@ u8 txFrame(struct port *port, struct lld
7fda0c
 void run_tx_sm(struct port *, struct lldp_agent *);
7fda0c
 void process_tx_initialize_sm(struct port *);
7fda0c
 void process_tx_idle(struct lldp_agent *);
7fda0c
-void process_tx_shutdown_frame(struct port *, struct lldp_agent *);
7fda0c
+void process_tx_shutdown_frame(struct port *, struct lldp_agent *, bool);
7fda0c
 void process_tx_info_frame(struct port *, struct lldp_agent *);
7fda0c
 void update_tx_timers(struct lldp_agent *);
7fda0c
 void run_tx_timers_sm(struct port *, struct lldp_agent *);
7fda0c
diff -upr a/lldp/tx.c b/lldp/tx.c
7fda0c
--- a/lldp/tx.c	2021-06-09 10:58:59.211200590 -0400
7fda0c
+++ b/lldp/tx.c	2021-01-06 11:05:30.812649467 -0500
7fda0c
@@ -71,7 +71,7 @@ bool mibConstrInfoLLDPDU(struct port *po
7fda0c
 	fb_offset += sizeof(struct l2_ethhdr);
7fda0c
 
7fda0c
 	/* Generic TLV Pack */
7fda0c
-	LIST_FOREACH(np, &lldp_head, lldp) {
7fda0c
+	LIST_FOREACH(np, &lldp_mod_head, lldp) {
7fda0c
 		if (!np->ops || !np->ops->lldp_mod_gettlv)
7fda0c
 			continue;
7fda0c
 
7fda0c
@@ -83,7 +83,7 @@ bool mibConstrInfoLLDPDU(struct port *po
7fda0c
 			       ptlv->tlv, ptlv->size);
7fda0c
 			datasize += ptlv->size;
7fda0c
 			fb_offset += ptlv->size;
7fda0c
-			ptlv =  free_pkd_tlv(ptlv);
7fda0c
+			free_pkd_tlv(ptlv);
7fda0c
 		}
7fda0c
 	}
7fda0c
 
7fda0c
@@ -94,7 +94,7 @@ bool mibConstrInfoLLDPDU(struct port *po
7fda0c
 	memcpy(agent->tx.frameout + fb_offset, ptlv->tlv, ptlv->size);
7fda0c
 	datasize += ptlv->size;
7fda0c
 	fb_offset += ptlv->size;
7fda0c
-	ptlv =  free_pkd_tlv(ptlv);
7fda0c
+	free_pkd_tlv(ptlv);
7fda0c
 
7fda0c
 	if (datasize < ETH_MIN_DATA_LEN)
7fda0c
 		agent->tx.sizeout = ETH_ZLEN;
7fda0c
@@ -104,7 +104,7 @@ bool mibConstrInfoLLDPDU(struct port *po
7fda0c
 	return true;
7fda0c
 
7fda0c
 error:
7fda0c
-	ptlv = free_pkd_tlv(ptlv);
7fda0c
+	free_pkd_tlv(ptlv);
7fda0c
 	if (agent->tx.frameout)
7fda0c
 		free(agent->tx.frameout);
7fda0c
 	agent->tx.frameout = NULL;
7fda0c
@@ -206,7 +206,7 @@ bool mibConstrShutdownLLDPDU(struct port
7fda0c
 	memcpy(agent->tx.frameout, (void *)&eth, sizeof(struct l2_ethhdr));
7fda0c
 	fb_offset += sizeof(struct l2_ethhdr);
7fda0c
 
7fda0c
-	np = find_module_by_id(&lldp_head, LLDP_MOD_MAND);
7fda0c
+	np = find_module_by_id(&lldp_mod_head, LLDP_MOD_MAND);
7fda0c
 	if (!np)
7fda0c
 		goto error;
7fda0c
 	if (!np->ops || !np->ops->lldp_mod_gettlv)
7fda0c
@@ -220,7 +220,7 @@ bool mibConstrShutdownLLDPDU(struct port
7fda0c
 		memcpy(agent->tx.frameout + fb_offset, ptlv->tlv, ptlv->size);
7fda0c
 		datasize += ptlv->size;
7fda0c
 		fb_offset += ptlv->size;
7fda0c
-		ptlv =  free_pkd_tlv(ptlv);
7fda0c
+		free_pkd_tlv(ptlv);
7fda0c
 	}
7fda0c
 
7fda0c
 	/* The End TLV marks the end of the LLDP PDU */
7fda0c
@@ -230,7 +230,7 @@ bool mibConstrShutdownLLDPDU(struct port
7fda0c
 	memcpy(agent->tx.frameout + fb_offset, ptlv->tlv, ptlv->size);
7fda0c
 	datasize += ptlv->size;
7fda0c
 	fb_offset += ptlv->size;
7fda0c
-	ptlv = free_pkd_tlv(ptlv);
7fda0c
+	free_pkd_tlv(ptlv);
7fda0c
 
7fda0c
 	if (datasize < ETH_MIN_DATA_LEN)
7fda0c
 		agent->tx.sizeout = ETH_ZLEN;
7fda0c
@@ -239,7 +239,7 @@ bool mibConstrShutdownLLDPDU(struct port
7fda0c
 	return true;
7fda0c
 
7fda0c
 error:
7fda0c
-	ptlv = free_pkd_tlv(ptlv);
7fda0c
+	free_pkd_tlv(ptlv);
7fda0c
 	if (agent->tx.frameout)
7fda0c
 		free(agent->tx.frameout);
7fda0c
 	agent->tx.frameout = NULL;
7fda0c
@@ -270,7 +270,7 @@ void run_tx_sm(struct port *port, struct
7fda0c
 			process_tx_idle(agent);
7fda0c
 			break;
7fda0c
 		case TX_SHUTDOWN_FRAME:
7fda0c
-			process_tx_shutdown_frame(port, agent);
7fda0c
+			process_tx_shutdown_frame(port, agent, true);
7fda0c
 			break;
7fda0c
 		case TX_INFO_FRAME:
7fda0c
 			process_tx_info_frame(port, agent);
7fda0c
@@ -330,8 +330,19 @@ void process_tx_idle(UNUSED struct lldp_
7fda0c
 	return;
7fda0c
 }
7fda0c
 
7fda0c
-void process_tx_shutdown_frame(struct port *port, struct lldp_agent *agent)
7fda0c
+/* we ignore 'adminStatus' in the case that we have recently transitioned
7fda0c
+ * to the shutdown state (in the case of the 'tx' state change) to allow
7fda0c
+ * for transmitting the ttl==0 as required by the IEEE standard. */
7fda0c
+void process_tx_shutdown_frame(struct port *port, struct lldp_agent *agent,
7fda0c
+				bool ignoreStatus)
7fda0c
 {
7fda0c
+	if (agent->adminStatus != enabledRxTx &&
7fda0c
+	    agent->adminStatus != enabledTxOnly) {
7fda0c
+		if (!ignoreStatus) {
7fda0c
+			return;
7fda0c
+		}
7fda0c
+	}
7fda0c
+
7fda0c
 	if (agent->timers.txShutdownWhile == 0) {
7fda0c
 		if (mibConstrShutdownLLDPDU(port, agent))
7fda0c
 			txFrame(port, agent);
7fda0c
diff -upr a/lldp_8021qaz.c b/lldp_8021qaz.c
7fda0c
--- a/lldp_8021qaz.c	2021-06-09 10:58:59.217200668 -0400
7fda0c
+++ b/lldp_8021qaz.c	2020-11-03 09:08:48.059229036 -0500
7fda0c
@@ -48,8 +48,8 @@
7fda0c
 #include "lldp_dcbx.h"
7fda0c
 
7fda0c
 
7fda0c
-struct lldp_head lldp_head;
7fda0c
-struct config_t lldpad_cfg;
7fda0c
+extern config_t lldpad_cfg;
7fda0c
+extern bool read_only_8021qaz;
7fda0c
 
7fda0c
 static int ieee8021qaz_check_pending(struct port *port, struct lldp_agent *);
7fda0c
 static void run_all_sm(struct port *port, struct lldp_agent *agent);
7fda0c
@@ -83,7 +83,7 @@ static int ieee8021qaz_check_pending(str
7fda0c
 	if (!port->portEnabled)
7fda0c
 		return 0;
7fda0c
 
7fda0c
-	iud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_8021QAZ);
7fda0c
+	iud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_8021QAZ);
7fda0c
 	if (iud) {
7fda0c
 		LIST_FOREACH(tlv, &iud->head, entry) {
7fda0c
 			if (!strncmp(port->ifname, tlv->ifname, IFNAMSIZ)) {
7fda0c
@@ -111,14 +111,14 @@ struct lldp_module *ieee8021qaz_register
7fda0c
 
7fda0c
 	mod = malloc(sizeof(*mod));
7fda0c
 	if (!mod) {
7fda0c
-		LLDPAD_ERR("Failed to malloc LLDP-8021QAZ module data");
7fda0c
+		LLDPAD_ERR("Failed to malloc LLDP-8021QAZ module data\n");
7fda0c
 		goto out_err;
7fda0c
 	}
7fda0c
 
7fda0c
 	iud = malloc(sizeof(*iud));
7fda0c
 	if (!iud) {
7fda0c
 		free(mod);
7fda0c
-		LLDPAD_ERR("Failed to malloc LLDP-8021QAZ module user data");
7fda0c
+		LLDPAD_ERR("Failed to malloc LLDP-8021QAZ module user data\n");
7fda0c
 		goto out_err;
7fda0c
 	}
7fda0c
 	memset((void *) iud, 0, sizeof(struct ieee8021qaz_user_data));
7fda0c
@@ -142,7 +142,7 @@ struct ieee8021qaz_tlvs *ieee8021qaz_dat
7fda0c
 	struct ieee8021qaz_user_data *iud;
7fda0c
 	struct ieee8021qaz_tlvs *tlv = NULL;
7fda0c
 
7fda0c
-	iud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_8021QAZ);
7fda0c
+	iud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_8021QAZ);
7fda0c
 	if (iud) {
7fda0c
 		LIST_FOREACH(tlv, &iud->head, entry) {
7fda0c
 			if (!strncmp(tlv->ifname, ifname, IFNAMSIZ))
7fda0c
@@ -396,7 +396,7 @@ static int read_cfg_file(char *ifname, s
7fda0c
 	return 0;
7fda0c
 }
7fda0c
 
7fda0c
-inline int get_prio_map(u32 prio_map, int prio)
7fda0c
+static int get_prio_map(u32 prio_map, int prio)
7fda0c
 {
7fda0c
 	if (prio > 7)
7fda0c
 		return 0;
7fda0c
@@ -404,7 +404,7 @@ inline int get_prio_map(u32 prio_map, in
7fda0c
 	return (prio_map >> (4 * (7-prio))) & 0xF;
7fda0c
 }
7fda0c
 
7fda0c
-inline void set_prio_map(u32 *prio_map, u8 prio, int tc)
7fda0c
+static void set_prio_map(u32 *prio_map, u8 prio, int tc)
7fda0c
 {
7fda0c
 	u32 mask = ~(0xffffffff & (0xF << (4 * (7-prio))));
7fda0c
 	*prio_map &= mask;
7fda0c
@@ -590,7 +590,7 @@ void ieee8021qaz_ifup(char *ifname, stru
7fda0c
 	memset(tlvs->rx, 0, sizeof(*tlvs->rx));
7fda0c
 
7fda0c
 	/* Initializing the ieee8021qaz_tlvs struct */
7fda0c
-	strncpy(tlvs->ifname, ifname, IFNAMSIZ);
7fda0c
+	STRNCPY_TERMINATED(tlvs->ifname, ifname, IFNAMSIZ);
7fda0c
 	tlvs->port = port;
7fda0c
 	tlvs->ieee8021qazdu = 0;
7fda0c
 	l2_packet_get_own_src_addr(port->l2, tlvs->local_mac);
7fda0c
@@ -628,7 +628,7 @@ void ieee8021qaz_ifup(char *ifname, stru
7fda0c
 	LIST_INIT(&tlvs->app_head);
7fda0c
 	read_cfg_file(port->ifname, agent, tlvs);
7fda0c
 
7fda0c
-	iud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_8021QAZ);
7fda0c
+	iud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_8021QAZ);
7fda0c
 	LIST_INSERT_HEAD(&iud->head, tlvs, entry);
7fda0c
 
7fda0c
 initialized:
7fda0c
@@ -959,6 +959,9 @@ static int del_ieee_hw(const char *ifnam
7fda0c
 			   .dcb_pad = 0
7fda0c
 			  };
7fda0c
 
7fda0c
+	if (read_only_8021qaz)
7fda0c
+		return 0;
7fda0c
+
7fda0c
 	nlsocket = nl_socket_alloc();
7fda0c
 	if (!nlsocket) {
7fda0c
 		LLDPAD_WARN("%s: %s: nl_handle_alloc failed\n",
7fda0c
@@ -1042,6 +1045,9 @@ static int set_ieee_hw(const char *ifnam
7fda0c
 			   .dcb_pad = 0
7fda0c
 			  };
7fda0c
 
7fda0c
+	if (read_only_8021qaz)
7fda0c
+		return 0;
7fda0c
+
7fda0c
 	nlsocket = nl_socket_alloc();
7fda0c
 	if (!nlsocket) {
7fda0c
 		LLDPAD_WARN("%s: %s: nl_handle_alloc failed\n",
7fda0c
@@ -1618,15 +1624,15 @@ static void clear_ieee8021qaz_rx(struct
7fda0c
 		return;
7fda0c
 
7fda0c
 	if (tlvs->rx->ieee8021qaz)
7fda0c
-		tlvs->rx->ieee8021qaz = free_unpkd_tlv(tlvs->rx->ieee8021qaz);
7fda0c
+		free_unpkd_tlv(tlvs->rx->ieee8021qaz);
7fda0c
 	if (tlvs->rx->etscfg)
7fda0c
-		tlvs->rx->etscfg = free_unpkd_tlv(tlvs->rx->etscfg);
7fda0c
+		free_unpkd_tlv(tlvs->rx->etscfg);
7fda0c
 	if (tlvs->rx->etsrec)
7fda0c
-		tlvs->rx->etsrec = free_unpkd_tlv(tlvs->rx->etsrec);
7fda0c
+		free_unpkd_tlv(tlvs->rx->etsrec);
7fda0c
 	if (tlvs->rx->pfc)
7fda0c
-		tlvs->rx->pfc = free_unpkd_tlv(tlvs->rx->pfc);
7fda0c
+		free_unpkd_tlv(tlvs->rx->pfc);
7fda0c
 	if (tlvs->rx->app)
7fda0c
-		tlvs->rx->app =	free_unpkd_tlv(tlvs->rx->app);
7fda0c
+		free_unpkd_tlv(tlvs->rx->app);
7fda0c
 
7fda0c
 	free(tlvs->rx);
7fda0c
 	tlvs->rx = NULL;
7fda0c
@@ -2014,13 +2020,13 @@ static void ieee8021qaz_free_rx(struct i
7fda0c
 		return;
7fda0c
 
7fda0c
 	if (rx->etscfg)
7fda0c
-		rx->etscfg = free_unpkd_tlv(rx->etscfg);
7fda0c
+		free_unpkd_tlv(rx->etscfg);
7fda0c
 	if (rx->etsrec)
7fda0c
-		rx->etsrec = free_unpkd_tlv(rx->etsrec);
7fda0c
+		free_unpkd_tlv(rx->etsrec);
7fda0c
 	if (rx->pfc)
7fda0c
-		rx->pfc = free_unpkd_tlv(rx->pfc);
7fda0c
+		free_unpkd_tlv(rx->pfc);
7fda0c
 	if (rx->app)
7fda0c
-		rx->app = free_unpkd_tlv(rx->app);
7fda0c
+		free_unpkd_tlv(rx->app);
7fda0c
 
7fda0c
 	return;
7fda0c
 }
7fda0c
@@ -2106,9 +2112,9 @@ static void ieee8021qaz_free_tlv(struct
7fda0c
 		return;
7fda0c
 
7fda0c
 	if (tlvs->ets)
7fda0c
-		tlvs->ets = free_ets_tlv(tlvs->ets);
7fda0c
+		free_ets_tlv(tlvs->ets);
7fda0c
 	if (tlvs->pfc)
7fda0c
-		tlvs->pfc = free_pfc_tlv(tlvs->pfc);
7fda0c
+		free_pfc_tlv(tlvs->pfc);
7fda0c
 
7fda0c
 	/* Remove _all_ existing application data */
7fda0c
 	LIST_FOREACH(np, &tlvs->app_head, entry)
7fda0c
@@ -2172,7 +2178,7 @@ int ieee8021qaz_tlvs_rxed(const char *if
7fda0c
 	struct ieee8021qaz_user_data *iud;
7fda0c
 	struct ieee8021qaz_tlvs *tlv = NULL;
7fda0c
 
7fda0c
-	iud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_8021QAZ);
7fda0c
+	iud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_8021QAZ);
7fda0c
 	if (iud) {
7fda0c
 		LIST_FOREACH(tlv, &iud->head, entry) {
7fda0c
 			if (!strncmp(tlv->ifname, ifname, IFNAMSIZ))
7fda0c
@@ -2191,7 +2197,7 @@ int ieee8021qaz_check_active(const char
7fda0c
 	struct ieee8021qaz_user_data *iud;
7fda0c
 	struct ieee8021qaz_tlvs *tlv = NULL;
7fda0c
 
7fda0c
-	iud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_8021QAZ);
7fda0c
+	iud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_8021QAZ);
7fda0c
 	if (iud) {
7fda0c
 		LIST_FOREACH(tlv, &iud->head, entry) {
7fda0c
 			if (!strncmp(tlv->ifname, ifname, IFNAMSIZ))
7fda0c
diff -upr a/lldp_8021qaz_clif.c b/lldp_8021qaz_clif.c
7fda0c
--- a/lldp_8021qaz_clif.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/lldp_8021qaz_clif.c	2020-09-23 08:50:52.650813901 -0400
7fda0c
@@ -251,40 +251,70 @@ static void ieee8021qaz_print_pfc_tlv(UN
7fda0c
 
7fda0c
 static void ieee8021qaz_print_app_tlv(u16 len, char *info)
7fda0c
 {
7fda0c
-	u8 offset = 2;
7fda0c
-	u8 app;
7fda0c
-	u16 proto;
7fda0c
+	u8 app, app_idx, app_prio, app_sel;
7fda0c
+	u16 proto, offset = 2;
7fda0c
+	u8 dscp[MAX_USER_PRIORITIES][MAX_APP_ENTRIES];
7fda0c
+	u8 dscp_count[MAX_USER_PRIORITIES] = {0};
7fda0c
+	u8 i, j;
7fda0c
+	bool first_app = true;
7fda0c
 
7fda0c
 	while (offset < len*2) {
7fda0c
 		hexstr2bin(info + offset, &app, 1);
7fda0c
 		hexstr2bin(info + offset + 2, (u8 *)&proto, 2);
7fda0c
 
7fda0c
-		if (offset > 6)
7fda0c
-			printf("\t");
7fda0c
-		printf("App#%i:\n", offset/6);
7fda0c
-		printf("\t Priority: %i\n", (app & 0xE0) >> 5);
7fda0c
-		printf("\t Sel: %i\n", app & 0x07);
7fda0c
-		switch (app & 0x07) {
7fda0c
-		case 1:
7fda0c
-			printf("\t Ethertype: 0x%04x\n", ntohs(proto));
7fda0c
-			break;
7fda0c
-		case 2:
7fda0c
-			printf("\t {S}TCP Port: %i\n", ntohs(proto));
7fda0c
-			break;
7fda0c
-		case 3:
7fda0c
-			printf("\t UDP or DCCP Port: %i\n", ntohs(proto));
7fda0c
-			break;
7fda0c
-		case 4:
7fda0c
-			printf("\t TCP/STCP/UDP/DCCP Port: %i\n", ntohs(proto));
7fda0c
-			break;
7fda0c
-		default:
7fda0c
-			printf("\t Reserved Port: %i\n", ntohs(proto));
7fda0c
-			break;
7fda0c
+		app_idx = offset/6;
7fda0c
+		app_prio = (app & 0xE0) >> 5;
7fda0c
+		app_sel = app & 0x07;
7fda0c
+
7fda0c
+		// Selector five is DSCP. Save value to print table at the end
7fda0c
+		if (app_sel == 5) {
7fda0c
+			dscp[app_prio][dscp_count[app_prio]] = ntohs(proto) & 0x3F;
7fda0c
+			dscp_count[app_prio]++;
7fda0c
+		} else {
7fda0c
+			if (first_app)
7fda0c
+				first_app = false;
7fda0c
+			else
7fda0c
+				printf("\t");
7fda0c
+			printf("App# %3i \t Prio %1i \t Sel %1i \t P-ID", 
7fda0c
+				app_idx, app_prio, app_sel);
7fda0c
+	
7fda0c
+			switch (app_sel) {
7fda0c
+			case 1:
7fda0c
+				printf("\t Ethertype: 0x%04x\n", ntohs(proto));
7fda0c
+				break;
7fda0c
+			case 2:
7fda0c
+				printf("\t {S}TCP Port: %i\n", ntohs(proto));
7fda0c
+				break;
7fda0c
+			case 3:
7fda0c
+				printf("\t UDP or DCCP Port: %i\n", ntohs(proto));
7fda0c
+				break;
7fda0c
+			case 4:
7fda0c
+				printf("\t TCP/STCP/UDP/DCCP Port: %i\n", ntohs(proto));
7fda0c
+				break;
7fda0c
+			default:
7fda0c
+				printf("\t Reserved Port: %i\n", ntohs(proto));
7fda0c
+				break;
7fda0c
+			}
7fda0c
 		}
7fda0c
 
7fda0c
-		printf("\n");
7fda0c
 		offset += 6;
7fda0c
 	}
7fda0c
+
7fda0c
+	for(i=0; i
7fda0c
+		if (dscp_count[i] == 0)
7fda0c
+			continue;
7fda0c
+
7fda0c
+		if (first_app)
7fda0c
+		        first_app = false;
7fda0c
+		else
7fda0c
+		        printf("\t");
7fda0c
+		printf("Prio:%i \t dscp: ", i);
7fda0c
+
7fda0c
+		for(j=0; j
7fda0c
+			printf(" %02i,", dscp[i][j]);
7fda0c
+		}
7fda0c
+		printf("\b \n");
7fda0c
+	}
7fda0c
 }
7fda0c
 
7fda0c
 int ieee8021qaz_print_tlv(u32 tlvid, u16 len, char *info)
7fda0c
diff -upr a/lldp_8021qaz_cmds.c b/lldp_8021qaz_cmds.c
7fda0c
--- a/lldp_8021qaz_cmds.c	2021-06-09 10:58:59.218200681 -0400
7fda0c
+++ b/lldp_8021qaz_cmds.c	2020-09-23 08:50:52.651813919 -0400
7fda0c
@@ -665,7 +665,7 @@ _set_arg_tcbw(struct cmd *cmd, char *arg
7fda0c
 
7fda0c
 	strncat(obuf, "tcbw = ", obuf_len - strlen(obuf) - 1);
7fda0c
 	for (i = 0; i < 8; i++) {
7fda0c
-		char cat[5];
7fda0c
+		char cat[6];
7fda0c
 		snprintf(cat, sizeof(cat), "%i%% ", percent[i]);
7fda0c
 		printf("%i%% ", percent[i]);
7fda0c
 		strncat(obuf, cat, obuf_len - strlen(obuf) - 1);
7fda0c
diff -upr a/lldp_8023.c b/lldp_8023.c
7fda0c
--- a/lldp_8023.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/lldp_8023.c	2020-11-03 09:08:48.059229036 -0500
7fda0c
@@ -39,8 +39,6 @@
7fda0c
 #include "lldp_8023_clif.h"
7fda0c
 #include "lldp_8023_cmds.h"
7fda0c
 
7fda0c
-extern struct lldp_head lldp_head;
7fda0c
-
7fda0c
 struct tlv_info_8023_maccfg {
7fda0c
 	u8 oui[3];
7fda0c
 	u8 sub;
7fda0c
@@ -84,7 +82,7 @@ static struct ieee8023_data *ieee8023_da
7fda0c
 	struct ieee8023_user_data *ud;
7fda0c
 	struct ieee8023_data *bd = NULL;
7fda0c
 
7fda0c
-	ud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_8023);
7fda0c
+	ud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_8023);
7fda0c
 	if (ud) {
7fda0c
 		LIST_FOREACH(bd, &ud->head, entry) {
7fda0c
 			if (!strncmp(ifname, bd->ifname, IFNAMSIZ) &&
7fda0c
@@ -401,7 +399,7 @@ struct packed_tlv *ieee8023_gettlv(struc
7fda0c
 	PACK_TLV_AFTER(bd->maxfs, ptlv, size, out_free);
7fda0c
 	return ptlv;
7fda0c
 out_free:
7fda0c
-	ptlv = free_pkd_tlv(ptlv);
7fda0c
+	free_pkd_tlv(ptlv);
7fda0c
 out_err:
7fda0c
 	LLDPAD_DBG("%s:%s: failed\n", __func__, port->ifname);
7fda0c
 	return NULL;
7fda0c
@@ -447,7 +445,7 @@ void ieee8023_ifup(char *ifname, struct
7fda0c
 		goto out_err;
7fda0c
 	}
7fda0c
 	memset(bd, 0, sizeof(struct ieee8023_data));
7fda0c
-	strncpy(bd->ifname, ifname, IFNAMSIZ);
7fda0c
+	STRNCPY_TERMINATED(bd->ifname, ifname, IFNAMSIZ);
7fda0c
 	bd->agenttype = agent->type;
7fda0c
 
7fda0c
 	if (ieee8023_bld_tlv(bd, agent)) {
7fda0c
@@ -456,7 +454,7 @@ void ieee8023_ifup(char *ifname, struct
7fda0c
 		goto out_err;
7fda0c
 	}
7fda0c
 
7fda0c
-	ud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_8023);
7fda0c
+	ud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_8023);
7fda0c
 	LIST_INSERT_HEAD(&ud->head, bd, entry);
7fda0c
 	LLDPAD_INFO("%s:port %s added\n", __func__, ifname);
7fda0c
 	return;
7fda0c
@@ -472,13 +470,13 @@ struct lldp_module *ieee8023_register(vo
7fda0c
 
7fda0c
 	mod = malloc(sizeof(*mod));
7fda0c
 	if (!mod) {
7fda0c
-		LLDPAD_ERR("failed to malloc LLDP 802.3 module data");
7fda0c
+		LLDPAD_ERR("failed to malloc LLDP 802.3 module data\n");
7fda0c
 		goto out_err;
7fda0c
 	}
7fda0c
 	ud = malloc(sizeof(struct ieee8023_user_data));
7fda0c
 	if (!ud) {
7fda0c
 		free(mod);
7fda0c
-		LLDPAD_ERR("failed to malloc LLDP 802.3 module user data");
7fda0c
+		LLDPAD_ERR("failed to malloc LLDP 802.3 module user data\n");
7fda0c
 		goto out_err;
7fda0c
 	}
7fda0c
 	LIST_INIT(&ud->head);
7fda0c
diff -upr a/lldpad.c b/lldpad.c
7fda0c
--- a/lldpad.c	2021-06-09 10:58:59.208200552 -0400
7fda0c
+++ b/lldpad.c	2021-04-05 12:02:17.320590536 -0400
7fda0c
@@ -80,10 +80,13 @@ struct lldp_module *(*register_tlv_table
7fda0c
 	NULL,
7fda0c
 };
7fda0c
 
7fda0c
+struct lldp_head lldp_mod_head;
7fda0c
+
7fda0c
 char *cfg_file_name = NULL;
7fda0c
 bool daemonize = 0;
7fda0c
 int loglvl = LOG_WARNING;
7fda0c
 int omit_tstamp;
7fda0c
+bool read_only_8021qaz = false;
7fda0c
 
7fda0c
 static const char *lldpad_version =
7fda0c
 "lldpad v" VERSION_STR "\n"
7fda0c
@@ -97,7 +100,7 @@ static void init_modules(void)
7fda0c
 	struct lldp_module *premod = NULL;
7fda0c
 	int i = 0;
7fda0c
 
7fda0c
-	LIST_INIT(&lldp_head);
7fda0c
+	LIST_INIT(&lldp_mod_head);
7fda0c
 	for (i = 0; register_tlv_table[i]; i++) {
7fda0c
 		module = register_tlv_table[i]();
7fda0c
 		if (!module)
7fda0c
@@ -105,7 +108,7 @@ static void init_modules(void)
7fda0c
 		if (premod)
7fda0c
 			LIST_INSERT_AFTER(premod, module, lldp);
7fda0c
 		else
7fda0c
-			LIST_INSERT_HEAD(&lldp_head, module, lldp);
7fda0c
+			LIST_INSERT_HEAD(&lldp_mod_head, module, lldp);
7fda0c
 		premod = module;
7fda0c
 	}
7fda0c
 }
7fda0c
@@ -114,9 +117,9 @@ void deinit_modules(void)
7fda0c
 {
7fda0c
 	struct lldp_module *module;
7fda0c
 
7fda0c
-	while (lldp_head.lh_first != NULL) {
7fda0c
-		module = lldp_head.lh_first;
7fda0c
-		LIST_REMOVE(lldp_head.lh_first, lldp);
7fda0c
+	while (lldp_mod_head.lh_first != NULL) {
7fda0c
+		module = lldp_mod_head.lh_first;
7fda0c
+		LIST_REMOVE(lldp_mod_head.lh_first, lldp);
7fda0c
 		module->ops->lldp_mod_unregister(module);
7fda0c
 	}
7fda0c
 }
7fda0c
@@ -136,7 +139,8 @@ static void usage(void)
7fda0c
 		"   -t  omit timestamps in log messages\n"
7fda0c
 		"   -v  show version\n"
7fda0c
 		"   -f  use configfile instead of default\n"
7fda0c
-		"   -V  set syslog level\n");
7fda0c
+		"   -V  set syslog level\n"
7fda0c
+		"   -R  run 8021qaz module in read_only mode\n");
7fda0c
 
7fda0c
 	exit(1);
7fda0c
 }
7fda0c
@@ -236,7 +240,7 @@ int main(int argc, char *argv[])
7fda0c
 	int rc = 1;
7fda0c
 
7fda0c
 	for (;;) {
7fda0c
-		c = getopt(argc, argv, "hdksptvf:V:");
7fda0c
+		c = getopt(argc, argv, "hdksptvf:RV:");
7fda0c
 		if (c < 0)
7fda0c
 			break;
7fda0c
 		switch (c) {
7fda0c
@@ -259,6 +263,9 @@ int main(int argc, char *argv[])
7fda0c
 		case 'p':
7fda0c
 			pid_file = 0;
7fda0c
 			break;
7fda0c
+		case 'R':
7fda0c
+			read_only_8021qaz = true;
7fda0c
+			break;
7fda0c
 		case 't':
7fda0c
 			omit_tstamp = 1;
7fda0c
 			break;
7fda0c
diff -upr a/lldpad.service b/lldpad.service
7fda0c
--- a/lldpad.service	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/lldpad.service	2020-09-23 08:50:52.655813990 -0400
7fda0c
@@ -1,9 +1,11 @@
7fda0c
 [Unit]
7fda0c
 Description=Link Layer Discovery Protocol Agent Daemon.
7fda0c
 After=syslog.target network.target
7fda0c
+Requires=lldpad.socket
7fda0c
 
7fda0c
 [Service]
7fda0c
 Type=simple
7fda0c
+Restart=always
7fda0c
 ExecStart=/usr/sbin/lldpad -t
7fda0c
 ExecReload=/bin/kill -HUP $MAINPID
7fda0c
 
7fda0c
diff -upr a/lldpad.socket b/lldpad.socket
7fda0c
--- a/lldpad.socket	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/lldpad.socket	2020-09-23 08:50:52.655813990 -0400
7fda0c
@@ -1,3 +1,6 @@
7fda0c
+[Unit]
7fda0c
+Description=Link Layer Discovery Protocol Agent Socket.
7fda0c
+
7fda0c
 [Socket]
7fda0c
 ListenDatagram=@/com/intel/lldpad
7fda0c
 PassCredentials=true
7fda0c
diff -upr a/lldpad.spec.in b/lldpad.spec.in
7fda0c
--- a/lldpad.spec.in	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/lldpad.spec.in	2020-09-23 08:50:52.655813990 -0400
7fda0c
@@ -10,9 +10,9 @@ Source0:        http://downloads.sourcef
7fda0c
 BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
7fda0c
 
7fda0c
 # BuildRequires:  
7fda0c
-Requires(post):   chkconfig
7fda0c
-Requires(preun):  chkconfig initscripts
7fda0c
-Requires(postun): initscripts
7fda0c
+Requires(post):   @SPEC_BUILD_REQUIRES_POST@
7fda0c
+Requires(preun):  @SPEC_BUILD_REQUIRES_PREUN@
7fda0c
+Requires(postun): @SPEC_BUILD_REQUIRES_POSTUN@
7fda0c
 
7fda0c
 %description
7fda0c
 This package contains the Linux user space daemon and configuration tool for
7fda0c
@@ -46,20 +46,36 @@ rm -rf $RPM_BUILD_ROOT
7fda0c
 
7fda0c
 
7fda0c
 %post
7fda0c
-/sbin/chkconfig --add lldpad 
7fda0c
+if [ -e /etc/init.d/%{name} ] && [ -e /sbin/chkconfig ]; then
7fda0c
+	/sbin/chkconfig --add %{name}
7fda0c
+fi
7fda0c
+if type systemctl >/dev/null 2>&1; then
7fda0c
+	# Scriplet only runs preset. Run enable/start manually
7fda0c
+	%systemd_post %{name}.socket %{name}.service
7fda0c
+fi
7fda0c
 
7fda0c
 %preun
7fda0c
 if [ $1 = 0 ]; then
7fda0c
-        /sbin/service lldpad stop
7fda0c
-        /sbin/chkconfig --del lldpad 
7fda0c
+	if [ -e /etc/init.d/%{name} ] && [ -e /sbin/chkconfig ]; then
7fda0c
+		/sbin/service %{name} stop
7fda0c
+		/sbin/chkconfig --del %{name}
7fda0c
+	fi
7fda0c
+	if type systemctl >/dev/null 2>&1; then
7fda0c
+		%systemd_preun %{name}.service %{name}.socket
7fda0c
+	fi
7fda0c
 fi
7fda0c
 
7fda0c
 %postun
7fda0c
 if [ $1 = 1 ]; then
7fda0c
-        /sbin/service lldpad condrestart
7fda0c
+	# Package upgrade, not uninstall
7fda0c
+	if [ -e /etc/init.d/%{name} ] && [ -e /sbin/chkconfig ]; then
7fda0c
+		/sbin/service %{name} condrestart
7fda0c
+	fi
7fda0c
+	if type systemctl >/dev/null 2>&1; then
7fda0c
+		%systemd_postun_with_restart %{name}.socket %{name}.service
7fda0c
+	fi
7fda0c
 fi
7fda0c
 
7fda0c
-
7fda0c
 %files
7fda0c
 %defattr(-,root,root,-)
7fda0c
 %doc COPYING
7fda0c
@@ -67,11 +83,13 @@ fi
7fda0c
 %doc ChangeLog
7fda0c
 %{_sbindir}/*
7fda0c
 %dir /var/lib/lldpad
7fda0c
-%{_sysconfdir}/init.d/lldpad
7fda0c
+@SPEC_FILE_LLDPAD_SERVICE@
7fda0c
+@SPEC_FILE_LLDPAD_SOCKET@
7fda0c
 %{_sysconfdir}/bash_completion.d/lldpad
7fda0c
 %{_sysconfdir}/bash_completion.d/lldptool
7fda0c
 %{_mandir}/man8/*
7fda0c
 %{_libdir}/liblldp_clif.*
7fda0c
+%{_mandir}/man3/liblldp_clif-vdp22.*
7fda0c
 
7fda0c
 %files devel
7fda0c
 %defattr(-,root,root,-)
7fda0c
diff -upr a/lldp_basman.c b/lldp_basman.c
7fda0c
--- a/lldp_basman.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/lldp_basman.c	2020-11-03 09:08:48.059229036 -0500
7fda0c
@@ -75,8 +75,6 @@ struct tlv_info_manaddr {
7fda0c
 	struct tlv_info_maoid o;
7fda0c
 } __attribute__ ((__packed__));
7fda0c
 
7fda0c
-extern struct lldp_head lldp_head;
7fda0c
-
7fda0c
 static const struct lldp_mod_ops basman_ops =  {
7fda0c
 	.lldp_mod_register 	= basman_register,
7fda0c
 	.lldp_mod_unregister 	= basman_unregister,
7fda0c
@@ -91,7 +89,7 @@ static struct basman_data *basman_data(c
7fda0c
 	struct basman_user_data *bud;
7fda0c
 	struct basman_data *bd = NULL;
7fda0c
 
7fda0c
-	bud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_BASIC);
7fda0c
+	bud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_BASIC);
7fda0c
 	if (bud) {
7fda0c
 		LIST_FOREACH(bd, &bud->head, entry) {
7fda0c
 			if (!strncmp(ifname, bd->ifname, IFNAMSIZ) &&
7fda0c
@@ -636,7 +634,7 @@ struct packed_tlv *basman_gettlv(struct
7fda0c
 		PACK_TLV_AFTER(bd->manaddr[i], ptlv, size, out_free);
7fda0c
 	return ptlv;
7fda0c
 out_free:
7fda0c
-	ptlv = free_pkd_tlv(ptlv);
7fda0c
+	free_pkd_tlv(ptlv);
7fda0c
 out_err:
7fda0c
 	LLDPAD_DBG("%s:%s: failed\n", __func__, port->ifname);
7fda0c
 	return NULL;
7fda0c
@@ -679,7 +677,7 @@ void basman_ifup(char *ifname, struct ll
7fda0c
 		goto out_err;
7fda0c
 	}
7fda0c
 	memset(bd, 0, sizeof(struct basman_data));
7fda0c
-	strncpy(bd->ifname, ifname, IFNAMSIZ);
7fda0c
+	STRNCPY_TERMINATED(bd->ifname, ifname, IFNAMSIZ);
7fda0c
 	bd->agenttype = agent->type;
7fda0c
 
7fda0c
 	if (basman_bld_tlv(bd, agent)) {
7fda0c
@@ -688,7 +686,7 @@ void basman_ifup(char *ifname, struct ll
7fda0c
 		goto out_err;
7fda0c
 	}
7fda0c
 
7fda0c
-	bud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_BASIC);
7fda0c
+	bud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_BASIC);
7fda0c
 	LIST_INSERT_HEAD(&bud->head, bd, entry);
7fda0c
 	LLDPAD_DBG("%s:port %s added\n", __func__, ifname);
7fda0c
 	return;
7fda0c
diff -upr a/lldp_basman_cmds.c b/lldp_basman_cmds.c
7fda0c
--- a/lldp_basman_cmds.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/lldp_basman_cmds.c	2020-09-23 08:50:52.652813936 -0400
7fda0c
@@ -51,6 +51,9 @@ static int test_arg_ipv6(struct cmd *, c
7fda0c
 static int get_arg_tlvtxenable(struct cmd *, char *, char *, char *, int);
7fda0c
 static int set_arg_tlvtxenable(struct cmd *, char *, char *, char *, int);
7fda0c
 static int test_arg_tlvtxenable(struct cmd *, char *, char *, char *, int);
7fda0c
+static int get_arg_info(struct cmd *, char *, char *, char *, int);
7fda0c
+static int set_arg_info(struct cmd *, char *, char *, char *, int);
7fda0c
+static int test_arg_info(struct cmd *, char *, char *, char *, int);
7fda0c
 
7fda0c
 static struct arg_handlers arg_handlers[] = {
7fda0c
 	{	.arg = ARG_IPV4_ADDR, .arg_class = TLV_ARG,
7fda0c
@@ -65,6 +68,10 @@ static struct arg_handlers arg_handlers[
7fda0c
 		.handle_get = get_arg_tlvtxenable,
7fda0c
 		.handle_set = set_arg_tlvtxenable,
7fda0c
 		.handle_test = test_arg_tlvtxenable },
7fda0c
+	{	.arg = ARG_TLVINFO, .arg_class = TLV_ARG,
7fda0c
+		.handle_get = get_arg_info,
7fda0c
+		.handle_set = set_arg_info,
7fda0c
+		.handle_test = test_arg_info },
7fda0c
 	{	.arg = 0 }
7fda0c
 };
7fda0c
 
7fda0c
@@ -166,6 +173,89 @@ static int test_arg_tlvtxenable(struct c
7fda0c
 	return _set_arg_tlvtxenable(cmd, arg, argvalue, obuf, obuf_len, true);
7fda0c
 }
7fda0c
 
7fda0c
+static int get_arg_info(struct cmd *cmd, char *arg, UNUSED char *argvalue,
7fda0c
+			char *obuf, int obuf_len)
7fda0c
+{
7fda0c
+	const char *info_str = NULL;
7fda0c
+	char arg_path[256];
7fda0c
+
7fda0c
+	if (cmd->cmd != cmd_gettlv)
7fda0c
+		return cmd_invalid;
7fda0c
+
7fda0c
+	switch (cmd->tlvid) {
7fda0c
+	case PORT_DESCRIPTION_TLV:
7fda0c
+	case SYSTEM_NAME_TLV:
7fda0c
+	case SYSTEM_DESCRIPTION_TLV:
7fda0c
+	case SYSTEM_CAPABILITIES_TLV:
7fda0c
+	case MANAGEMENT_ADDRESS_TLV:
7fda0c
+		snprintf(arg_path, sizeof(arg_path), "%s%08x.%s",
7fda0c
+			 TLVID_PREFIX, cmd->tlvid, arg);
7fda0c
+
7fda0c
+		get_config_setting(cmd->ifname, cmd->type, arg_path,
7fda0c
+				   &info_str, CONFIG_TYPE_STRING);
7fda0c
+		break;
7fda0c
+	case INVALID_TLVID:
7fda0c
+		return cmd_invalid;
7fda0c
+	default:
7fda0c
+		return cmd_not_applicable;
7fda0c
+	}
7fda0c
+
7fda0c
+	if (info_str)
7fda0c
+		snprintf(obuf, obuf_len, "%02x%s%04x%s",
7fda0c
+			 (unsigned int)strlen(arg), arg,
7fda0c
+			 (unsigned int)strlen(info_str), info_str);
7fda0c
+
7fda0c
+	return cmd_success;
7fda0c
+}
7fda0c
+
7fda0c
+static int _set_arg_info(struct cmd *cmd, UNUSED char *arg, char *argvalue, 
7fda0c
+			 char *obuf, int obuf_len, bool test)
7fda0c
+{
7fda0c
+	if (cmd->cmd != cmd_settlv)
7fda0c
+		return cmd_invalid;
7fda0c
+
7fda0c
+	switch (cmd->tlvid) {
7fda0c
+	case PORT_DESCRIPTION_TLV:
7fda0c
+	case SYSTEM_NAME_TLV:
7fda0c
+	case SYSTEM_DESCRIPTION_TLV:
7fda0c
+	case SYSTEM_CAPABILITIES_TLV:
7fda0c
+	case MANAGEMENT_ADDRESS_TLV:
7fda0c
+		break;
7fda0c
+	case INVALID_TLVID:
7fda0c
+		return cmd_invalid;
7fda0c
+	default:
7fda0c
+		return cmd_not_applicable;
7fda0c
+	}
7fda0c
+
7fda0c
+        if (strlen(argvalue) < 1)
7fda0c
+		return cmd_invalid;
7fda0c
+
7fda0c
+	if (test)
7fda0c
+		return cmd_success;
7fda0c
+
7fda0c
+	if (set_config_tlvinfo_str(cmd->ifname, cmd->type, 
7fda0c
+				   cmd->tlvid, argvalue))
7fda0c
+		return cmd_failed;
7fda0c
+
7fda0c
+	snprintf(obuf, obuf_len, "enableTx = %s\n", argvalue);
7fda0c
+
7fda0c
+	somethingChangedLocal(cmd->ifname, cmd->type);
7fda0c
+
7fda0c
+	return cmd_success;
7fda0c
+}
7fda0c
+
7fda0c
+static int set_arg_info(struct cmd *cmd, char *arg, char *argvalue, 
7fda0c
+			char *obuf, int obuf_len)
7fda0c
+{
7fda0c
+	return _set_arg_info(cmd, arg, argvalue, obuf, obuf_len, false);
7fda0c
+}
7fda0c
+
7fda0c
+static int test_arg_info(struct cmd *cmd, char *arg, char *argvalue,
7fda0c
+			 char *obuf, int obuf_len)
7fda0c
+{
7fda0c
+	return _set_arg_info(cmd, arg, argvalue, obuf, obuf_len, true);
7fda0c
+}
7fda0c
+
7fda0c
 struct arg_handlers *basman_get_arg_handlers()
7fda0c
 {
7fda0c
 	return &arg_handlers[0];
7fda0c
diff -upr a/lldp_dcbx.c b/lldp_dcbx.c
7fda0c
--- a/lldp_dcbx.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/lldp_dcbx.c	2020-10-23 14:12:58.975289310 -0400
7fda0c
@@ -129,7 +129,7 @@ struct dcbx_tlvs *dcbx_data(const char *
7fda0c
 	struct dcbd_user_data *dud;
7fda0c
 	struct dcbx_tlvs *tlv = NULL;
7fda0c
 
7fda0c
-	dud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_DCBX);
7fda0c
+	dud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_DCBX);
7fda0c
 	if (dud) {
7fda0c
 		LIST_FOREACH(tlv, &dud->head, entry) {
7fda0c
 			if (!strncmp(tlv->ifname, ifname, IFNAMSIZ))
7fda0c
@@ -148,7 +148,7 @@ int dcbx_tlvs_rxed(const char *ifname, s
7fda0c
 	if (agent->type != NEAREST_BRIDGE)
7fda0c
 		return 0;
7fda0c
 
7fda0c
-	dud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_DCBX);
7fda0c
+	dud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_DCBX);
7fda0c
 	if (dud) {
7fda0c
 		LIST_FOREACH(tlv, &dud->head, entry) {
7fda0c
 			if (!strncmp(tlv->ifname, ifname, IFNAMSIZ))
7fda0c
@@ -172,7 +172,7 @@ int dcbx_check_active(const char *ifname
7fda0c
 	struct dcbd_user_data *dud;
7fda0c
 	struct dcbx_tlvs *tlv = NULL;
7fda0c
 
7fda0c
-	dud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_DCBX);
7fda0c
+	dud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_DCBX);
7fda0c
 	if (dud) {
7fda0c
 		LIST_FOREACH(tlv, &dud->head, entry) {
7fda0c
 			if (!strncmp(tlv->ifname, ifname, IFNAMSIZ))
7fda0c
@@ -194,6 +194,8 @@ int dcbx_bld_tlv(struct port *newport, s
7fda0c
 		return 0;
7fda0c
 
7fda0c
 	tlvs = dcbx_data(newport->ifname);
7fda0c
+	if (!tlvs)
7fda0c
+		return 0;
7fda0c
 
7fda0c
 	get_config_setting(newport->ifname, agent->type, ARG_ADMINSTATUS,
7fda0c
 			  &adminstatus, CONFIG_TYPE_INT);
7fda0c
@@ -283,20 +285,20 @@ void dcbx_free_manifest(struct dcbx_mani
7fda0c
 		return;
7fda0c
 
7fda0c
 	if (manifest->dcbx1)
7fda0c
-		manifest->dcbx1 = free_unpkd_tlv(manifest->dcbx1);
7fda0c
+		free_unpkd_tlv(manifest->dcbx1);
7fda0c
 	if (manifest->dcbx2)
7fda0c
-		manifest->dcbx2 = free_unpkd_tlv(manifest->dcbx2);
7fda0c
+		free_unpkd_tlv(manifest->dcbx2);
7fda0c
 	if (manifest->dcbx_ctrl)
7fda0c
-		manifest->dcbx_ctrl = free_unpkd_tlv(manifest->dcbx_ctrl);
7fda0c
+		free_unpkd_tlv(manifest->dcbx_ctrl);
7fda0c
 	if (manifest->dcbx_pg)
7fda0c
-		manifest->dcbx_pg = free_unpkd_tlv(manifest->dcbx_pg);
7fda0c
+		free_unpkd_tlv(manifest->dcbx_pg);
7fda0c
 	if (manifest->dcbx_pfc)
7fda0c
-		manifest->dcbx_pfc = free_unpkd_tlv(manifest->dcbx_pfc);
7fda0c
+		free_unpkd_tlv(manifest->dcbx_pfc);
7fda0c
 	if (manifest->dcbx_app)
7fda0c
-		manifest->dcbx_app = free_unpkd_tlv(manifest->dcbx_app);
7fda0c
+		free_unpkd_tlv(manifest->dcbx_app);
7fda0c
 	if (manifest->dcbx_llink)
7fda0c
-		manifest->dcbx_llink = free_unpkd_tlv(manifest->dcbx_llink);
7fda0c
-
7fda0c
+		free_unpkd_tlv(manifest->dcbx_llink);
7fda0c
+	free(manifest);
7fda0c
 	return;
7fda0c
 }
7fda0c
 
7fda0c
@@ -305,44 +307,27 @@ void dcbx_free_tlv(struct dcbx_tlvs *tlv
7fda0c
 	if (!tlvs)
7fda0c
 		return;
7fda0c
 
7fda0c
-	if (tlvs->control != NULL) {
7fda0c
-		tlvs->control = free_unpkd_tlv(tlvs->control);
7fda0c
-	}
7fda0c
-
7fda0c
-	if (tlvs->pg1 != NULL) {
7fda0c
-		tlvs->pg1 = free_unpkd_tlv(tlvs->pg1);
7fda0c
-	}
7fda0c
-
7fda0c
-	if (tlvs->pg2 != NULL) {
7fda0c
-		tlvs->pg2 = free_unpkd_tlv(tlvs->pg2);
7fda0c
-	}
7fda0c
-
7fda0c
-	if (tlvs->pfc1 != NULL) {
7fda0c
-		tlvs->pfc1 = free_unpkd_tlv(tlvs->pfc1);
7fda0c
-	}
7fda0c
-
7fda0c
-	if (tlvs->pfc2 != NULL) {
7fda0c
-		tlvs->pfc2 = free_unpkd_tlv(tlvs->pfc2);
7fda0c
-	}
7fda0c
-
7fda0c
-	if (tlvs->app1 != NULL) {
7fda0c
-		tlvs->app1 = free_unpkd_tlv(tlvs->app1);
7fda0c
-	}
7fda0c
-
7fda0c
-	if (tlvs->app2 != NULL)
7fda0c
-		tlvs->app2 = free_unpkd_tlv(tlvs->app2);
7fda0c
+	if (tlvs->control)
7fda0c
+		free_unpkd_tlv(tlvs->control);
7fda0c
+	if (tlvs->pg1)
7fda0c
+		free_unpkd_tlv(tlvs->pg1);
7fda0c
+	if (tlvs->pg2)
7fda0c
+		free_unpkd_tlv(tlvs->pg2);
7fda0c
+	if (tlvs->pfc1)
7fda0c
+		free_unpkd_tlv(tlvs->pfc1);
7fda0c
+	if (tlvs->pfc2)
7fda0c
+		free_unpkd_tlv(tlvs->pfc2);
7fda0c
+	if (tlvs->app1)
7fda0c
+		free_unpkd_tlv(tlvs->app1);
7fda0c
+	if (tlvs->app2)
7fda0c
+		free_unpkd_tlv(tlvs->app2);
7fda0c
+	if (tlvs->llink)
7fda0c
+		free_unpkd_tlv(tlvs->llink);
7fda0c
+	if (tlvs->dcbx1)
7fda0c
+		free_unpkd_tlv(tlvs->dcbx1);
7fda0c
+	if (tlvs->dcbx2)
7fda0c
+		free_unpkd_tlv(tlvs->dcbx2);
7fda0c
 
7fda0c
-	if (tlvs->llink != NULL) {
7fda0c
-		tlvs->llink = free_unpkd_tlv(tlvs->llink);
7fda0c
-	}
7fda0c
-
7fda0c
-	if (tlvs->dcbx1 != NULL) {
7fda0c
-		tlvs->dcbx1 = free_unpkd_tlv(tlvs->dcbx1);
7fda0c
-	}
7fda0c
-
7fda0c
-	if (tlvs->dcbx2 != NULL) {
7fda0c
-		tlvs->dcbx2 = free_unpkd_tlv(tlvs->dcbx2);
7fda0c
-	}
7fda0c
 	return;
7fda0c
 }
7fda0c
 
7fda0c
@@ -362,6 +347,7 @@ struct packed_tlv* dcbx_gettlv(struct po
7fda0c
 		return NULL;
7fda0c
 
7fda0c
 	dcbx_free_tlv(tlvs);
7fda0c
+	memset(tlvs, 0, sizeof(struct dcbx_tlvs));
7fda0c
 
7fda0c
 	dcbx_bld_tlv(port, agent);
7fda0c
 	if (tlvs->dcbx_st == DCBX_SUBTYPE2) {
7fda0c
@@ -386,7 +372,6 @@ static void dcbx_free_data(struct dcbd_u
7fda0c
 			LIST_REMOVE(dd, entry);
7fda0c
 			dcbx_free_tlv(dd);
7fda0c
 			dcbx_free_manifest(dd->manifest);
7fda0c
-			free(dd->manifest);
7fda0c
 			free(dd);
7fda0c
 		}
7fda0c
 	}
7fda0c
@@ -408,7 +393,7 @@ struct lldp_module * dcbx_register(void)
7fda0c
 	if (get_dcbx_version(&dcbx_version)) {
7fda0c
 		gdcbx_subtype = dcbx_version;
7fda0c
 	} else {
7fda0c
-		LLDPAD_ERR("failed to get DCBX version");
7fda0c
+		LLDPAD_ERR("failed to get DCBX version\n");
7fda0c
 		goto out_err;
7fda0c
 	}
7fda0c
 
7fda0c
@@ -505,7 +490,7 @@ void dcbx_ifup(char *ifname, struct lldp
7fda0c
 	ifindex = get_ifidx(ifname);
7fda0c
 	port = port_find_by_ifindex(ifindex);
7fda0c
 
7fda0c
-	dud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_DCBX);
7fda0c
+	dud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_DCBX);
7fda0c
 	tlvs = dcbx_data(ifname);
7fda0c
 
7fda0c
 	if (!port)
7fda0c
@@ -582,7 +567,7 @@ void dcbx_ifup(char *ifname, struct lldp
7fda0c
 	memset(manifest, 0, sizeof(*manifest));
7fda0c
 
7fda0c
 	tlvs->manifest = manifest;
7fda0c
-	strncpy(tlvs->ifname, ifname, IFNAMSIZ);
7fda0c
+	STRNCPY_TERMINATED(tlvs->ifname, ifname, IFNAMSIZ);
7fda0c
 	tlvs->port = port;
7fda0c
 	tlvs->dcbdu = 0;
7fda0c
 	tlvs->dcbx_st = gdcbx_subtype & MASK_DCBX_FORCE;
7fda0c
@@ -654,7 +639,6 @@ void dcbx_ifdown(char *device_name, stru
7fda0c
 	LIST_REMOVE(tlvs, entry);
7fda0c
 	dcbx_free_tlv(tlvs);
7fda0c
 	dcbx_free_manifest(tlvs->manifest);
7fda0c
-	free(tlvs->manifest);
7fda0c
 	free(tlvs);
7fda0c
 }
7fda0c
 
7fda0c
@@ -664,26 +648,19 @@ void clear_dcbx_manifest(struct dcbx_tlv
7fda0c
 		return;
7fda0c
 
7fda0c
 	if (dcbx->manifest->dcbx_llink)
7fda0c
-		dcbx->manifest->dcbx_llink =
7fda0c
-			free_unpkd_tlv(dcbx->manifest->dcbx_llink);
7fda0c
+		free_unpkd_tlv(dcbx->manifest->dcbx_llink);
7fda0c
 	if (dcbx->manifest->dcbx_app)
7fda0c
-		dcbx->manifest->dcbx_app =
7fda0c
-			free_unpkd_tlv(dcbx->manifest->dcbx_app);
7fda0c
+		free_unpkd_tlv(dcbx->manifest->dcbx_app);
7fda0c
 	if (dcbx->manifest->dcbx_pfc)
7fda0c
-		dcbx->manifest->dcbx_pfc =
7fda0c
-			free_unpkd_tlv(dcbx->manifest->dcbx_pfc);
7fda0c
+		free_unpkd_tlv(dcbx->manifest->dcbx_pfc);
7fda0c
 	if (dcbx->manifest->dcbx_pg)
7fda0c
-		dcbx->manifest->dcbx_pg =
7fda0c
-			free_unpkd_tlv(dcbx->manifest->dcbx_pg);
7fda0c
+		free_unpkd_tlv(dcbx->manifest->dcbx_pg);
7fda0c
 	if (dcbx->manifest->dcbx_ctrl)
7fda0c
-		dcbx->manifest->dcbx_ctrl =
7fda0c
-			free_unpkd_tlv(dcbx->manifest->dcbx_ctrl);
7fda0c
+		free_unpkd_tlv(dcbx->manifest->dcbx_ctrl);
7fda0c
 	if (dcbx->manifest->dcbx1)
7fda0c
-		dcbx->manifest->dcbx1 =
7fda0c
-			free_unpkd_tlv(dcbx->manifest->dcbx1);
7fda0c
+		free_unpkd_tlv(dcbx->manifest->dcbx1);
7fda0c
 	if (dcbx->manifest->dcbx2)
7fda0c
-		dcbx->manifest->dcbx2 =
7fda0c
-			free_unpkd_tlv(dcbx->manifest->dcbx2);
7fda0c
+		free_unpkd_tlv(dcbx->manifest->dcbx2);
7fda0c
 	free(dcbx->manifest);
7fda0c
 	dcbx->manifest = NULL;
7fda0c
 }
7fda0c
diff -upr a/lldp_dcbx_cfg.c b/lldp_dcbx_cfg.c
7fda0c
--- a/lldp_dcbx_cfg.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/lldp_dcbx_cfg.c	2020-09-23 08:50:52.652813936 -0400
7fda0c
@@ -99,12 +99,15 @@ static config_setting_t *construct_new_s
7fda0c
 	config_setting_t *tmp2_setting = NULL;
7fda0c
 	char abuf[32];
7fda0c
 	int i;
7fda0c
+	char device_name_sanitized[IFNAMSIZ];
7fda0c
 
7fda0c
 	dcbx_setting = config_lookup(&lldpad_cfg, DCBX_SETTING);
7fda0c
 	if (!dcbx_setting)
7fda0c
 		return NULL;
7fda0c
 
7fda0c
-	eth_setting = config_setting_add(dcbx_setting, device_name,
7fda0c
+	config_ifkey(device_name, device_name_sanitized);
7fda0c
+
7fda0c
+	eth_setting = config_setting_add(dcbx_setting, device_name_sanitized,
7fda0c
 		CONFIG_TYPE_GROUP);
7fda0c
 	if (!eth_setting)
7fda0c
 		goto set_error;
7fda0c
@@ -371,11 +374,13 @@ static int _set_persistent(char *device_
7fda0c
 	config_setting_t *setting_value = NULL;
7fda0c
 	char abuf[2*DCB_MAX_TLV_LENGTH + 1];
7fda0c
 	int result, i;
7fda0c
+	char device_name_sanitized[IFNAMSIZ];
7fda0c
 
7fda0c
 	dcbx_setting = config_lookup(&lldpad_cfg, DCBX_SETTING);
7fda0c
+	config_ifkey(device_name, device_name_sanitized);
7fda0c
 	if (dcbx_setting)
7fda0c
 		eth_settings = config_setting_get_member(dcbx_setting,
7fda0c
-							 device_name);
7fda0c
+							 device_name_sanitized);
7fda0c
 
7fda0c
 	/* init the internal data store for device_name */
7fda0c
 	if (NULL == eth_settings) {
7fda0c
@@ -698,7 +703,7 @@ static int _set_persistent(char *device_
7fda0c
 	return 0;
7fda0c
 
7fda0c
 set_error:
7fda0c
-	LLDPAD_ERR("update of config file %s failed for %s",
7fda0c
+	LLDPAD_ERR("update of config file %s failed for %s\n",
7fda0c
 		   cfg_file_name, device_name);
7fda0c
 	return cmd_failed;
7fda0c
 }
7fda0c
@@ -782,22 +787,20 @@ int get_persistent(char *device_name, fu
7fda0c
 	int result = cmd_failed, i;
7fda0c
 	int results[MAX_USER_PRIORITIES];
7fda0c
 	int len;
7fda0c
-	char abuf[32];
7fda0c
+	char abuf[32], device_name_sanitized[IFNAMSIZ];
7fda0c
 
7fda0c
 	memset(attribs, 0, sizeof(*attribs));
7fda0c
 	dcbx_setting = config_lookup(&lldpad_cfg, DCBX_SETTING);
7fda0c
+
7fda0c
+	config_ifkey(device_name, device_name_sanitized);
7fda0c
 	if (dcbx_setting)
7fda0c
-		eth_settings = config_setting_get_member(dcbx_setting,
7fda0c
-							 device_name);
7fda0c
+		eth_settings = config_setting_get_member(dcbx_setting, 
7fda0c
+							 device_name_sanitized);
7fda0c
 
7fda0c
 	/* init the internal data store for device_name */
7fda0c
 	result = get_default_persistent(device_name, attribs);
7fda0c
-	if (NULL == eth_settings) {
7fda0c
-		assert(memcmp(device_name, DEF_CFG_STORE, 
7fda0c
-			strlen(DEF_CFG_STORE)));
7fda0c
-
7fda0c
+	if (NULL == eth_settings)
7fda0c
 		return result;
7fda0c
-	}
7fda0c
 
7fda0c
 	/* Read pfc setting */
7fda0c
 	if (get_int_config(eth_settings, "pfc_enable", TYPE_BOOL,
7fda0c
@@ -1071,13 +1074,16 @@ int get_dcb_enable_state(char *ifname, i
7fda0c
 	int rc = EINVAL;
7fda0c
 	config_setting_t *settings = NULL;
7fda0c
 	char path[sizeof(DCBX_SETTING) + IFNAMSIZ + 16];
7fda0c
+	char ifkey[IFNAMSIZ];
7fda0c
+
7fda0c
+	config_ifkey(ifname, ifkey);
7fda0c
 
7fda0c
 	memset(path, 0, sizeof(path));
7fda0c
-	snprintf(path, sizeof(path), "%s.%s.dcb_enable", DCBX_SETTING, ifname);
7fda0c
+	snprintf(path, sizeof(path), "%s.%s.dcb_enable", DCBX_SETTING, ifkey); 
7fda0c
 	settings = config_lookup(&lldpad_cfg, path);
7fda0c
 	if (!settings) {
7fda0c
 		LLDPAD_INFO("### %s:%s:failed on %s\n", __func__, ifname, path);
7fda0c
-		snprintf(path, sizeof(path), "%s.dcb_enable", ifname);
7fda0c
+		snprintf(path, sizeof(path), "%s.dcb_enable", ifkey); 
7fda0c
 		settings = config_lookup(&lldpad_cfg, path);
7fda0c
 		if (!settings) {
7fda0c
 			LLDPAD_INFO("### %s:%s:failed again %s\n", __func__, ifname, path);
7fda0c
diff -upr a/lldp_dcbx_cmds.c b/lldp_dcbx_cmds.c
7fda0c
--- a/lldp_dcbx_cmds.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/lldp_dcbx_cmds.c	2020-09-23 08:50:52.653813954 -0400
7fda0c
@@ -259,8 +259,12 @@ static cmd_status set_dcb_state(char *po
7fda0c
 
7fda0c
 	if (ilen == (off + CFG_DCB_DLEN)) {
7fda0c
 		state = (*(ibuf+off+DCB_STATE)) ^ '0';
7fda0c
-		set_hw_state(port_id, state);
7fda0c
-		rval = save_dcb_enable_state(port_id, state);
7fda0c
+
7fda0c
+		if(set_hw_state(port_id, state) < 0) {
7fda0c
+		    rval = cmd_not_capable;
7fda0c
+		} else {
7fda0c
+		    rval = save_dcb_enable_state(port_id, state);
7fda0c
+		}
7fda0c
 	} else {
7fda0c
 		printf("error - setcommand has invalid argument length\n");
7fda0c
 		rval = cmd_bad_params;
7fda0c
@@ -943,6 +947,10 @@ static int set_pg_config(pg_attribs *pg_
7fda0c
 	bool used[MAX_BANDWIDTH_GROUPS];
7fda0c
 	bool uppcts_changed = false;
7fda0c
 
7fda0c
+	/* If PG is disabled, skip changing any other attributes */
7fda0c
+	if (!(pg_data->protocol.Enable))
7fda0c
+		goto done;
7fda0c
+
7fda0c
 	plen=strlen(port_id);
7fda0c
 	off = DCB_PORT_OFF + plen + CFG_LEN;
7fda0c
 
7fda0c
@@ -1067,6 +1075,7 @@ static int set_pg_config(pg_attribs *pg_
7fda0c
 		return status;
7fda0c
 	}
7fda0c
 
7fda0c
+done:
7fda0c
 	is_pfc = get_pfc(port_id, &pfc_data);
7fda0c
 	if (is_pfc == cmd_success)
7fda0c
 		status = put_pg(port_id, pg_data, &pfc_data);
7fda0c
diff -upr a/lldp_dcbx_nl.c b/lldp_dcbx_nl.c
7fda0c
--- a/lldp_dcbx_nl.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/lldp_dcbx_nl.c	2020-09-23 08:50:52.653813954 -0400
7fda0c
@@ -152,16 +152,17 @@ static int send_msg(struct nlmsghdr *nlh
7fda0c
 {
7fda0c
 	struct sockaddr_nl nladdr;
7fda0c
 	void *buf = (void *)nlh;
7fda0c
-	int r, len = nlh->nlmsg_len;
7fda0c
+	int r;
7fda0c
 
7fda0c
 	if (nlh == NULL)
7fda0c
 		return 1;
7fda0c
 
7fda0c
 	memset(&nladdr, 0, sizeof(nladdr));
7fda0c
 	nladdr.nl_family = AF_NETLINK;
7fda0c
-	
7fda0c
+
7fda0c
 	do {
7fda0c
-		r = sendto(nl_sd, buf, len, 0, (struct sockaddr *)&nladdr,
7fda0c
+		r = sendto(nl_sd, buf, nlh->nlmsg_len, 0,
7fda0c
+			   (struct sockaddr *)&nladdr,
7fda0c
 			sizeof(nladdr));
7fda0c
 		LLDPAD_DBG("send_msg: sendto = %d\n", r);
7fda0c
 
7fda0c
@@ -561,7 +562,7 @@ int get_dcb_numtcs(const char *ifname, u
7fda0c
 
7fda0c
 	seq = nlh->nlmsg_seq;
7fda0c
 
7fda0c
-	strncpy(name, ifname, sizeof(name));
7fda0c
+	STRNCPY_TERMINATED (name, ifname, sizeof(name));
7fda0c
 	add_rta(nlh, DCB_ATTR_IFNAME, (void *)name, strlen(name) + 1);
7fda0c
 	rta_parent = add_rta(nlh, DCB_ATTR_NUMTCS, NULL, 0);
7fda0c
 
7fda0c
@@ -801,17 +802,6 @@ int set_hw_app(char *ifname, appgroup_at
7fda0c
 	return(recv_msg(DCB_CMD_SAPP, DCB_ATTR_APP, seq));
7fda0c
 }
7fda0c
 
7fda0c
-int run_cmd(char *cmd, ...)
7fda0c
-{
7fda0c
-	char cbuf[128];
7fda0c
-	va_list args;
7fda0c
-
7fda0c
-	va_start(args, cmd);
7fda0c
-	vsprintf(cbuf, cmd, args);
7fda0c
-	va_end(args);
7fda0c
-	return system(cbuf);
7fda0c
-}
7fda0c
-
7fda0c
 int set_hw_all(char *ifname)
7fda0c
 {
7fda0c
 	struct nlmsghdr *nlh;
7fda0c
diff -upr a/lldp_evb22.c b/lldp_evb22.c
7fda0c
--- a/lldp_evb22.c	2021-06-09 10:58:59.218200681 -0400
7fda0c
+++ b/lldp_evb22.c	2020-11-03 09:08:48.060229053 -0500
7fda0c
@@ -37,14 +37,12 @@
7fda0c
 #include "messages.h"
7fda0c
 #include "config.h"
7fda0c
 
7fda0c
-extern struct lldp_head lldp_head;
7fda0c
-
7fda0c
 struct evb22_data *evb22_data(char *ifname, enum agent_type type)
7fda0c
 {
7fda0c
 	struct evb22_user_data *ud;
7fda0c
 	struct evb22_data *ed = NULL;
7fda0c
 
7fda0c
-	ud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_EVB22);
7fda0c
+	ud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_EVB22);
7fda0c
 	if (ud) {
7fda0c
 		LIST_FOREACH(ed, &ud->head, entry) {
7fda0c
 			if (!strncmp(ifname, ed->ifname, IFNAMSIZ) &&
7fda0c
@@ -450,10 +448,10 @@ static void evb22_ifup(char *ifname, str
7fda0c
 			   __func__, ifname, agent->type, sizeof *ed);
7fda0c
 		return;
7fda0c
 	}
7fda0c
-	strncpy(ed->ifname, ifname, IFNAMSIZ);
7fda0c
+	STRNCPY_TERMINATED(ed->ifname, ifname, IFNAMSIZ);
7fda0c
 	ed->agenttype = agent->type;
7fda0c
 	evb22_init_tlv(ed, agent);
7fda0c
-	ud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_EVB22);
7fda0c
+	ud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_EVB22);
7fda0c
 	LIST_INSERT_HEAD(&ud->head, ed, entry);
7fda0c
 	LLDPAD_DBG("%s:%s agent %d added\n", __func__, ifname, agent->type);
7fda0c
 }
7fda0c
diff -upr a/lldp_evb22_cmds.c b/lldp_evb22_cmds.c
7fda0c
--- a/lldp_evb22_cmds.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/lldp_evb22_cmds.c	2020-09-23 08:50:52.653813954 -0400
7fda0c
@@ -225,7 +225,7 @@ int evb22_conf_enabletx(char *ifname, en
7fda0c
 				TLVID(OUI_IEEE_8021Qbg22, LLDP_EVB22_SUBTYPE));
7fda0c
 }
7fda0c
 
7fda0c
-static int evb22_cmdok(struct cmd *cmd, cmd_status expected)
7fda0c
+static int evb22_cmdok(struct cmd *cmd, int expected)
7fda0c
 {
7fda0c
 	if (cmd->cmd != expected)
7fda0c
 		return cmd_invalid;
7fda0c
diff -upr a/lldp_evb.c b/lldp_evb.c
7fda0c
--- a/lldp_evb.c	2021-06-09 10:58:59.217200668 -0400
7fda0c
+++ b/lldp_evb.c	2021-04-05 12:02:17.318590504 -0400
7fda0c
@@ -36,14 +36,12 @@
7fda0c
 #include "messages.h"
7fda0c
 #include "config.h"
7fda0c
 
7fda0c
-extern struct lldp_head lldp_head;
7fda0c
-
7fda0c
 struct evb_data *evb_data(char *ifname, enum agent_type type)
7fda0c
 {
7fda0c
 	struct evb_user_data *ud;
7fda0c
 	struct evb_data *ed = NULL;
7fda0c
 
7fda0c
-	ud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_EVB);
7fda0c
+	ud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_EVB);
7fda0c
 	if (ud) {
7fda0c
 		LIST_FOREACH(ed, &ud->head, entry) {
7fda0c
 			if (!strncmp(ifname, ed->ifname, IFNAMSIZ) &&
7fda0c
@@ -342,12 +340,12 @@ static void evb_ifup(char *ifname, struc
7fda0c
 			   __func__, ifname, agent->type, sizeof(*ed));
7fda0c
 		return;
7fda0c
 	}
7fda0c
-	strncpy(ed->ifname, ifname, IFNAMSIZ);
7fda0c
+	STRNCPY_TERMINATED(ed->ifname, ifname, IFNAMSIZ);
7fda0c
 	ed->agenttype = agent->type;
7fda0c
 
7fda0c
 	evb_init_tlv(ed, agent);
7fda0c
 
7fda0c
-	ud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_EVB);
7fda0c
+	ud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_EVB);
7fda0c
 	LIST_INSERT_HEAD(&ud->head, ed, entry);
7fda0c
 	LLDPAD_DBG("%s:%s agent %d added\n", __func__, ifname, agent->type);
7fda0c
 }
7fda0c
diff -upr a/lldp_evb_cmds.c b/lldp_evb_cmds.c
7fda0c
--- a/lldp_evb_cmds.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/lldp_evb_cmds.c	2020-09-23 08:50:52.653813954 -0400
7fda0c
@@ -163,7 +163,7 @@ int evb_conf_enabletx(char *ifname, enum
7fda0c
 	return is_tlv_txenabled(ifname, type, TLVID_8021Qbg(LLDP_EVB_SUBTYPE));
7fda0c
 }
7fda0c
 
7fda0c
-static int evb_cmdok(struct cmd *cmd, cmd_status expected)
7fda0c
+static int evb_cmdok(struct cmd *cmd, int expected)
7fda0c
 {
7fda0c
 	if (cmd->cmd != expected)
7fda0c
 		return cmd_invalid;
7fda0c
diff -upr a/lldp_mand.c b/lldp_mand.c
7fda0c
--- a/lldp_mand.c	2021-06-09 10:58:59.211200590 -0400
7fda0c
+++ b/lldp_mand.c	2020-11-03 09:08:48.061229070 -0500
7fda0c
@@ -42,8 +42,6 @@
7fda0c
 #include "lldp/l2_packet.h"
7fda0c
 #include "lldp_tlv.h"
7fda0c
 
7fda0c
-extern struct lldp_head lldp_head;
7fda0c
-
7fda0c
 static const struct lldp_mod_ops mand_ops = {
7fda0c
 	.lldp_mod_register 	= mand_register,
7fda0c
 	.lldp_mod_unregister 	= mand_unregister,
7fda0c
@@ -59,7 +57,7 @@ struct mand_data *mand_data(const char *
7fda0c
 	struct mand_user_data *mud;
7fda0c
 	struct mand_data *md = NULL;
7fda0c
 
7fda0c
-	mud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_MAND);
7fda0c
+	mud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_MAND);
7fda0c
 	if (mud) {
7fda0c
 		LIST_FOREACH(md, &mud->head, entry) {
7fda0c
 			if (!strncmp(ifname, md->ifname, IFNAMSIZ) &&
7fda0c
@@ -100,7 +98,7 @@ static int mand_bld_end_tlv(struct mand_
7fda0c
 static int mand_bld_mac_chassis(struct mand_data *md,
7fda0c
 				struct tlv_info_chassis *chassis)
7fda0c
 {
7fda0c
-	get_mac(md->ifname, chassis->id.mac);
7fda0c
+	get_mac(md->ifname, chassis->id.mac, false);
7fda0c
 	if (is_valid_mac(chassis->id.mac))
7fda0c
 		chassis->sub = CHASSIS_ID_MAC_ADDRESS;
7fda0c
 	return sizeof(chassis->id.mac) + sizeof(chassis->sub);
7fda0c
@@ -112,11 +110,13 @@ static int mand_bld_ip_chassis(struct ma
7fda0c
 {
7fda0c
 	unsigned int len;
7fda0c
 
7fda0c
-	if (!get_ipaddr(md->ifname, &chassis->id.na.ip.v4)) {
7fda0c
+	void *v4_ptr = &chassis->id.na.ip.v4;
7fda0c
+	void *v6_ptr = &chassis->id.na.ip.v6;
7fda0c
+	if (!get_ipaddr(md->ifname, v4_ptr)) {
7fda0c
 		chassis->sub = CHASSIS_ID_NETWORK_ADDRESS;
7fda0c
 		chassis->id.na.type = MANADDR_IPV4;
7fda0c
 		len = sizeof(chassis->id.na.ip.v4);
7fda0c
-	} else  if (!get_ipaddr6(md->ifname, &chassis->id.na.ip.v6)) {
7fda0c
+	} else  if (!get_ipaddr6(md->ifname, v6_ptr)) {
7fda0c
 		chassis->sub = CHASSIS_ID_NETWORK_ADDRESS;
7fda0c
 		chassis->id.na.type = MANADDR_IPV6;
7fda0c
 		len = sizeof(chassis->id.na.ip.v6);
7fda0c
@@ -217,6 +217,7 @@ static int mand_bld_chassis_tlv(struct m
7fda0c
 			if (length > 0)
7fda0c
 				break;
7fda0c
 			/* Fall through on IP error */
7fda0c
+			/* FALLTHROUGH */ 
7fda0c
 		case CHASSIS_ID_MAC_ADDRESS:
7fda0c
 		default:
7fda0c
 			length = mand_bld_mac_chassis(md, &chassis);
7fda0c
@@ -234,6 +235,7 @@ static int mand_bld_chassis_tlv(struct m
7fda0c
 			if (length > 0)
7fda0c
 				break;
7fda0c
 			/* Fall through on IP error */
7fda0c
+			/* FALLTHROUGH */
7fda0c
 		case LLDP_MED_DEVTYPE_NETWORK_CONNECTIVITY:
7fda0c
 		default:
7fda0c
 			length =  mand_bld_ifname_chassis(md, &chassis);
7fda0c
@@ -361,16 +363,18 @@ static int mand_bld_portid_tlv(struct ma
7fda0c
 	switch (subtype) {
7fda0c
 	default:
7fda0c
 	case PORT_ID_MAC_ADDRESS:
7fda0c
-		get_mac(md->ifname, portid.id.mac);
7fda0c
+		get_mac(md->ifname, portid.id.mac, true);
7fda0c
 		if (is_valid_mac(portid.id.mac)) {
7fda0c
 			portid.sub = PORT_ID_MAC_ADDRESS;
7fda0c
 			length = sizeof(portid.id.mac) +
7fda0c
 				 sizeof(portid.sub);
7fda0c
 			break;
7fda0c
 		}
7fda0c
-	case PORT_ID_NETWORK_ADDRESS:
7fda0c
+		/* FALLTHROUGH */
7fda0c
+	case PORT_ID_NETWORK_ADDRESS: {
7fda0c
 		/* uses ipv4 first */
7fda0c
-		if (!get_ipaddr(md->ifname, &portid.id.na.ip.v4)) {
7fda0c
+		void *v4_ptr = &portid.id.na.ip.v4;
7fda0c
+		if (!get_ipaddr(md->ifname, v4_ptr)) {
7fda0c
 			portid.sub = PORT_ID_NETWORK_ADDRESS;
7fda0c
 			portid.id.na.type = MANADDR_IPV4;
7fda0c
 			length = sizeof(portid.id.na.type) +
7fda0c
@@ -379,7 +383,8 @@ static int mand_bld_portid_tlv(struct ma
7fda0c
 			break;
7fda0c
 		}
7fda0c
 		/* ipv4 fails, get ipv6 */
7fda0c
-		if (!get_ipaddr6(md->ifname, &portid.id.na.ip.v6)) {
7fda0c
+		void *v6_ptr = &portid.id.na.ip.v6;
7fda0c
+		if (!get_ipaddr6(md->ifname, v6_ptr)) {
7fda0c
 			portid.sub = PORT_ID_NETWORK_ADDRESS;
7fda0c
 			portid.id.na.type = MANADDR_IPV6;
7fda0c
 			length = sizeof(portid.id.na.type) +
7fda0c
@@ -387,6 +392,8 @@ static int mand_bld_portid_tlv(struct ma
7fda0c
 				 sizeof(portid.sub);
7fda0c
 			break;
7fda0c
 		}
7fda0c
+  }
7fda0c
+		/* FALLTHROUGH */
7fda0c
 	case PORT_ID_INTERFACE_NAME:
7fda0c
 		portid.sub = PORT_ID_INTERFACE_NAME;
7fda0c
 		strncpy((char *)portid.id.ifname, md->ifname, IFNAMSIZ);
7fda0c
@@ -508,9 +515,11 @@ struct packed_tlv *mand_gettlv(struct po
7fda0c
 	}
7fda0c
 
7fda0c
 	err = mand_bld_tlv(md, agent);
7fda0c
-	if (err)
7fda0c
+	if (err) {
7fda0c
 		LLDPAD_DBG("%s:%s: building mandotory TLV error.\n",
7fda0c
 			   __func__, port->ifname);
7fda0c
+		goto out_err;
7fda0c
+	}
7fda0c
 
7fda0c
 	size = TLVSIZE(md->chassis)
7fda0c
 		+ TLVSIZE(md->portid)
7fda0c
@@ -532,7 +541,7 @@ struct packed_tlv *mand_gettlv(struct po
7fda0c
 	PACK_TLV_AFTER(md->ttl, ptlv, size, out_free);
7fda0c
 	return ptlv;
7fda0c
 out_free:
7fda0c
-	ptlv = free_pkd_tlv(ptlv);
7fda0c
+	free_pkd_tlv(ptlv);
7fda0c
 out_err:
7fda0c
 	LLDPAD_DBG("%s:%s: failed\n", __func__, port->ifname);
7fda0c
 	return NULL;
7fda0c
@@ -596,10 +605,10 @@ void mand_ifup(char *ifname, struct lldp
7fda0c
 			return;
7fda0c
 		}
7fda0c
 		memset(md, 0, sizeof(struct mand_data));
7fda0c
-		strncpy(md->ifname, ifname, IFNAMSIZ);
7fda0c
+		STRNCPY_TERMINATED(md->ifname, ifname, IFNAMSIZ);
7fda0c
 		md->agenttype = agent->type;
7fda0c
 
7fda0c
-		mud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_MAND);
7fda0c
+		mud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_MAND);
7fda0c
 		LIST_INSERT_HEAD(&mud->head, md, entry);
7fda0c
 	}
7fda0c
 
7fda0c
@@ -627,7 +636,7 @@ struct lldp_module *mand_register(void)
7fda0c
 		LLDPAD_ERR("failed to malloc LLDP Mandatory module data\n");
7fda0c
 		goto out_err;
7fda0c
 	}
7fda0c
-	mud = malloc(sizeof(struct mand_user_data));
7fda0c
+    mud = malloc(sizeof(struct mand_user_data));
7fda0c
 	if (!mud) {
7fda0c
 		free(mod);
7fda0c
 		LLDPAD_ERR("failed to malloc LLDP Mandatory module user data\n");
7fda0c
@@ -635,8 +644,8 @@ struct lldp_module *mand_register(void)
7fda0c
 	}
7fda0c
 	LIST_INIT(&mud->head);
7fda0c
  	mod->id = LLDP_MOD_MAND;
7fda0c
+    mod->data = mud;
7fda0c
 	mod->ops = &mand_ops;
7fda0c
-	mod->data = mud;
7fda0c
 	LLDPAD_INFO("%s:done\n", __func__);
7fda0c
 	return mod;
7fda0c
 out_err:
7fda0c
diff -upr a/lldp_mand_cmds.c b/lldp_mand_cmds.c
7fda0c
--- a/lldp_mand_cmds.c	2021-06-09 10:58:59.211200590 -0400
7fda0c
+++ b/lldp_mand_cmds.c	2020-10-23 14:12:58.975289310 -0400
7fda0c
@@ -44,6 +44,9 @@
7fda0c
 #include "lldp/states.h"
7fda0c
 #include "lldp_util.h"
7fda0c
 #include "messages.h"
7fda0c
+#include "lldp_8021qaz.h"
7fda0c
+
7fda0c
+extern bool read_only_8021qaz;
7fda0c
 
7fda0c
 static int get_arg_adminstatus(struct cmd *, char *, char *, char *, int);
7fda0c
 static int set_arg_adminstatus(struct cmd *, char *, char *, char *, int);
7fda0c
@@ -463,7 +466,7 @@ int handle_get_args(struct cmd *cmd, UNU
7fda0c
 	nbuf = obuf;
7fda0c
 	nbuf_len = obuf_len;
7fda0c
 
7fda0c
-	LIST_FOREACH(np, &lldp_head, lldp) {
7fda0c
+	LIST_FOREACH(np, &lldp_mod_head, lldp) {
7fda0c
 		if (!np->ops->get_arg_handler)
7fda0c
 			continue;
7fda0c
 		if (!(ah = np->ops->get_arg_handler()))
7fda0c
@@ -493,7 +496,7 @@ int handle_get_arg(struct cmd *cmd, char
7fda0c
 	struct arg_handlers *ah;
7fda0c
 	int rval, status = cmd_not_applicable;
7fda0c
 
7fda0c
-	LIST_FOREACH(np, &lldp_head, lldp) {
7fda0c
+	LIST_FOREACH(np, &lldp_mod_head, lldp) {
7fda0c
 		if (!np->ops->get_arg_handler)
7fda0c
 			continue;
7fda0c
 		if (!(ah = np->ops->get_arg_handler()))
7fda0c
@@ -590,11 +593,14 @@ int handle_test_arg(struct cmd *cmd, cha
7fda0c
 	struct arg_handlers *ah;
7fda0c
 	int rval, status = cmd_not_applicable;
7fda0c
 
7fda0c
-	LIST_FOREACH(np, &lldp_head, lldp) {
7fda0c
+	LIST_FOREACH(np, &lldp_mod_head, lldp) {
7fda0c
 		if (!np->ops->get_arg_handler)
7fda0c
 			continue;
7fda0c
 		if (!(ah = np->ops->get_arg_handler()))
7fda0c
 			continue;
7fda0c
+		/* 8021QAZ set operations not allowed in read-only mode */
7fda0c
+		if (np->id == LLDP_MOD_8021QAZ && read_only_8021qaz)
7fda0c
+			return cmd_no_access;
7fda0c
 		while (ah->arg) {
7fda0c
 			if (!strcasecmp(ah->arg, arg) && ah->handle_test) {
7fda0c
 				rval = ah->handle_test(cmd, ah->arg, argvalue,
7fda0c
@@ -620,11 +626,14 @@ int handle_set_arg(struct cmd *cmd, char
7fda0c
 	struct arg_handlers *ah;
7fda0c
 	int rval, status = cmd_not_applicable;
7fda0c
 
7fda0c
-	LIST_FOREACH(np, &lldp_head, lldp) {
7fda0c
+	LIST_FOREACH(np, &lldp_mod_head, lldp) {
7fda0c
 		if (!np->ops->get_arg_handler)
7fda0c
 			continue;
7fda0c
 		if (!(ah = np->ops->get_arg_handler()))
7fda0c
 			continue;
7fda0c
+		/* 8021QAZ set operations not allowed in read-only mode */
7fda0c
+		if (np->id == LLDP_MOD_8021QAZ && read_only_8021qaz)
7fda0c
+			return cmd_no_access;
7fda0c
 		while (ah->arg) {
7fda0c
 			if (!strcasecmp(ah->arg, arg) && ah->handle_set) {
7fda0c
 				rval = ah->handle_set(cmd, ah->arg, argvalue,
7fda0c
diff -upr a/lldp_med.c b/lldp_med.c
7fda0c
--- a/lldp_med.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/lldp_med.c	2020-11-03 09:08:48.061229070 -0500
7fda0c
@@ -40,8 +40,6 @@
7fda0c
 #include "lldp_mand_clif.h"
7fda0c
 #include "lldp_med_cmds.h"
7fda0c
 
7fda0c
-extern struct lldp_head lldp_head;
7fda0c
-
7fda0c
 struct tlv_info_medcaps {
7fda0c
 	u8 oui[OUI_SIZE];
7fda0c
 	u8 subtype;
7fda0c
@@ -95,7 +93,7 @@ static struct med_data *med_data(const c
7fda0c
 	struct med_user_data *mud;
7fda0c
 	struct med_data *md = NULL;
7fda0c
 
7fda0c
-	mud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_MED);
7fda0c
+	mud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_MED);
7fda0c
 	if (mud) {
7fda0c
 		LIST_FOREACH(md, &mud->head, entry) {
7fda0c
 			if (!strncmp(ifname, md->ifname, IFNAMSIZ) &&
7fda0c
@@ -905,7 +903,7 @@ void med_ifup(char *ifname, struct lldp_
7fda0c
 		goto out_err;
7fda0c
 	}
7fda0c
 	memset(md, 0, sizeof(struct med_data));
7fda0c
-	strncpy(md->ifname, ifname, IFNAMSIZ);
7fda0c
+	STRNCPY_TERMINATED(md->ifname, ifname, IFNAMSIZ);
7fda0c
 	md->agenttype = agent->type;
7fda0c
 
7fda0c
 	if (med_bld_tlv(md, agent)) {
7fda0c
@@ -914,7 +912,7 @@ void med_ifup(char *ifname, struct lldp_
7fda0c
 		free(md);
7fda0c
 		goto out_err;
7fda0c
 	}
7fda0c
-	mud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_MED);
7fda0c
+	mud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_MED);
7fda0c
 	LIST_INSERT_HEAD(&mud->head, md, entry);
7fda0c
 	LLDPAD_INFO("%s:port %s added\n", __func__, ifname);
7fda0c
 	return;
7fda0c
diff -upr a/lldp_med_cmds.c b/lldp_med_cmds.c
7fda0c
--- a/lldp_med_cmds.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/lldp_med_cmds.c	2020-09-23 08:50:52.654813972 -0400
7fda0c
@@ -303,6 +303,7 @@ static int _set_arg_med_devtype(struct c
7fda0c
 	case LLDP_MED_DEVTYPE_ENDPOINT_CLASS_III:
7fda0c
 	case LLDP_MED_DEVTYPE_ENDPOINT_CLASS_II:
7fda0c
 		tlv_enabletx(cmd->ifname, cmd->type, (OUI_TIA_TR41 << 8) | LLDP_MED_NETWORK_POLICY);
7fda0c
+		/* FALLTHROUGH */
7fda0c
 	case LLDP_MED_DEVTYPE_ENDPOINT_CLASS_I:
7fda0c
 	case LLDP_MED_DEVTYPE_NETWORK_CONNECTIVITY:
7fda0c
 		tlv_enabletx(cmd->ifname, cmd->type, (OUI_TIA_TR41 << 8) | LLDP_MED_RESERVED);
7fda0c
diff -upr a/lldp_rtnl.c b/lldp_rtnl.c
7fda0c
--- a/lldp_rtnl.c	2021-06-09 10:58:59.213200616 -0400
7fda0c
+++ b/lldp_rtnl.c	2021-04-05 12:02:17.319590520 -0400
7fda0c
@@ -103,7 +103,8 @@ static void add_rtattr(struct nlmsghdr *
7fda0c
 
7fda0c
 	rta->rta_type = type;
7fda0c
 	rta->rta_len = len;
7fda0c
-	memcpy(RTA_DATA(rta), data, alen);
7fda0c
+	if (data)
7fda0c
+		memcpy(RTA_DATA(rta), data, alen);
7fda0c
 	n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
7fda0c
 }
7fda0c
 
7fda0c
diff -upr a/lldp_tlv.c b/lldp_tlv.c
7fda0c
--- a/lldp_tlv.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/lldp_tlv.c	2020-09-23 08:50:52.654813972 -0400
7fda0c
@@ -112,13 +112,13 @@ int pack_tlv_after(struct unpacked_tlv *
7fda0c
 		return -1;
7fda0c
 
7fda0c
 	if (ptlv->size + mtlv->size > length) {
7fda0c
-		ptlv = free_pkd_tlv(ptlv);
7fda0c
+		free_pkd_tlv(ptlv);
7fda0c
 		return -1;
7fda0c
 	}
7fda0c
 
7fda0c
 	memcpy(&mtlv->tlv[mtlv->size], ptlv->tlv, ptlv->size);
7fda0c
 	mtlv->size += ptlv->size;
7fda0c
-	ptlv = free_pkd_tlv(ptlv);
7fda0c
+	free_pkd_tlv(ptlv);
7fda0c
 	return 0;
7fda0c
 }
7fda0c
 
7fda0c
@@ -158,7 +158,7 @@ struct unpacked_tlv *unpack_tlv(struct p
7fda0c
 	return upkd_tlv;
7fda0c
 }
7fda0c
 
7fda0c
-struct unpacked_tlv *free_unpkd_tlv(struct unpacked_tlv *tlv)
7fda0c
+void free_unpkd_tlv(struct unpacked_tlv *tlv)
7fda0c
 {
7fda0c
 	if (tlv != NULL) {
7fda0c
 		if (tlv->info != NULL) {
7fda0c
@@ -166,12 +166,10 @@ struct unpacked_tlv *free_unpkd_tlv(stru
7fda0c
 			tlv->info = NULL;
7fda0c
 		}
7fda0c
 		free(tlv);
7fda0c
-		tlv = NULL;
7fda0c
 	}
7fda0c
-	return NULL;
7fda0c
 }
7fda0c
 
7fda0c
-struct packed_tlv *free_pkd_tlv(struct packed_tlv *tlv)
7fda0c
+void free_pkd_tlv(struct packed_tlv *tlv)
7fda0c
 {
7fda0c
 	if (tlv != NULL) {
7fda0c
 		if (tlv->tlv != NULL) {
7fda0c
@@ -179,9 +177,7 @@ struct packed_tlv *free_pkd_tlv(struct p
7fda0c
 			tlv->tlv = NULL;
7fda0c
 		}
7fda0c
 		free(tlv);
7fda0c
-		tlv = NULL;
7fda0c
 	}
7fda0c
-	return NULL;
7fda0c
 }
7fda0c
 
7fda0c
 struct packed_tlv *create_ptlv()
7fda0c
diff -upr a/lldptool.c b/lldptool.c
7fda0c
--- a/lldptool.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/lldptool.c	2020-10-30 09:35:19.614361934 -0400
7fda0c
@@ -64,6 +64,9 @@
7fda0c
 #include "lldp_util.h"
7fda0c
 #include "lldpad_status.h"
7fda0c
 
7fda0c
+struct lldp_head lldp_cli_head;
7fda0c
+struct lldp_head lldp_mod_head;
7fda0c
+extern void close_history(void);
7fda0c
 static int show_raw;
7fda0c
 
7fda0c
 static const char *cli_version =
7fda0c
@@ -199,7 +202,7 @@ static void init_modules(void)
7fda0c
 		if (premod)
7fda0c
 			LIST_INSERT_AFTER(premod, module, lldp);
7fda0c
 		else
7fda0c
-			LIST_INSERT_HEAD(&lldp_head, module, lldp);
7fda0c
+			LIST_INSERT_HEAD(&lldp_mod_head, module, lldp);
7fda0c
 		premod = module;
7fda0c
 	}
7fda0c
 }
7fda0c
@@ -208,9 +211,9 @@ void deinit_modules(void)
7fda0c
 {
7fda0c
 	struct lldp_module *module;
7fda0c
 
7fda0c
-	while (lldp_head.lh_first != NULL) {
7fda0c
-		module = lldp_head.lh_first;
7fda0c
-		LIST_REMOVE(lldp_head.lh_first, lldp);
7fda0c
+	while (lldp_mod_head.lh_first != NULL) {
7fda0c
+		module = lldp_mod_head.lh_first;
7fda0c
+		LIST_REMOVE(lldp_mod_head.lh_first, lldp);
7fda0c
 		module->ops->lldp_mod_unregister(module);
7fda0c
 	}
7fda0c
 }
7fda0c
@@ -222,28 +225,6 @@ static void usage(void)
7fda0c
 		commands_usage, commands_options, commands_help);
7fda0c
 }
7fda0c
 
7fda0c
-/* assumes input is pointer to two hex digits */
7fda0c
-/* returns -1 on error */
7fda0c
-int hex2int(char *b)
7fda0c
-{
7fda0c
-	int i;
7fda0c
-	int n=0;
7fda0c
-	int m;
7fda0c
-
7fda0c
-	for (i=0,m=1; i<2; i++,m--) {
7fda0c
-		if (isxdigit(*(b+i))) {
7fda0c
-			if (*(b+i) <= '9')
7fda0c
-				n |= (*(b+i) & 0x0f) << (4*m);
7fda0c
-			else
7fda0c
-				n |= ((*(b+i) & 0x0f) + 9) << (4*m);
7fda0c
-		}
7fda0c
-		else {
7fda0c
-			return -1;
7fda0c
-		}
7fda0c
-	}
7fda0c
-	return n;
7fda0c
-}
7fda0c
-
7fda0c
 void print_raw_message(char *msg, int print)
7fda0c
 {
7fda0c
 	if (!print || !(print & SHOW_RAW))
7fda0c
@@ -368,7 +349,7 @@ cli_cmd_help(UNUSED struct clif *clif, U
7fda0c
 	printf("%s\n%s\n%s", commands_usage, commands_options, commands_help);
7fda0c
 
7fda0c
 	printf("\nTLV identifiers:\n");
7fda0c
-	LIST_FOREACH(np, &lldp_head, lldp)
7fda0c
+	LIST_FOREACH(np, &lldp_mod_head, lldp)
7fda0c
 		if (np->ops->print_help)
7fda0c
 			np->ops->print_help();
7fda0c
 	return 0;
7fda0c
@@ -428,7 +409,7 @@ u32 lookup_tlvid(char *tlvid_str)
7fda0c
 	struct lldp_module *np;
7fda0c
 	u32 tlvid = INVALID_TLVID;
7fda0c
 
7fda0c
-	LIST_FOREACH(np, &lldp_head, lldp) {
7fda0c
+	LIST_FOREACH(np, &lldp_mod_head, lldp) {
7fda0c
 		if (np->ops->lookup_tlv_name) {
7fda0c
 			tlvid = np->ops->lookup_tlv_name(tlvid_str);
7fda0c
 			if (tlvid != INVALID_TLVID)
7fda0c
@@ -711,6 +692,7 @@ static void cli_interactive()
7fda0c
 		}
7fda0c
 		free(cmd);
7fda0c
 	} while (!cli_quit);
7fda0c
+	close_history();
7fda0c
 }
7fda0c
 
7fda0c
 static void cli_terminate(UNUSED int sig)
7fda0c
diff -upr a/lldptool_cmds.c b/lldptool_cmds.c
7fda0c
--- a/lldptool_cmds.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/lldptool_cmds.c	2020-10-23 14:12:58.976289329 -0400
7fda0c
@@ -27,6 +27,7 @@
7fda0c
 #include <stdio.h>
7fda0c
 #include <stdlib.h>
7fda0c
 #include <ctype.h>
7fda0c
+#include <sys/types.h>
7fda0c
 #include "clif.h"
7fda0c
 #include "dcb_types.h"
7fda0c
 #include "lldptool.h"
7fda0c
@@ -464,7 +465,7 @@ static void print_tlvs(struct cmd *cmd,
7fda0c
 			offset += 8;
7fda0c
 		
7fda0c
 		printed = 0;
7fda0c
-		LIST_FOREACH(np, &lldp_head, lldp) {
7fda0c
+		LIST_FOREACH(np, &lldp_mod_head, lldp) {
7fda0c
 			if (np->ops->print_tlv(tlvid, tlv_len, ibuf+offset)) {
7fda0c
 					printed = 1;
7fda0c
 					break;
7fda0c
diff -upr a/lldp_util.c b/lldp_util.c
7fda0c
--- a/lldp_util.c	2021-06-09 10:58:59.215200642 -0400
7fda0c
+++ b/lldp_util.c	2020-09-23 08:50:52.654813972 -0400
7fda0c
@@ -24,6 +24,7 @@
7fda0c
 
7fda0c
 *******************************************************************************/
7fda0c
 
7fda0c
+#include <ctype.h>
7fda0c
 #include <stdlib.h>
7fda0c
 #include <stdio.h>
7fda0c
 #include <string.h>
7fda0c
@@ -122,6 +123,28 @@ int hexstr2bin(const char *hex, u8 *buf,
7fda0c
 	return 0;
7fda0c
 }
7fda0c
 
7fda0c
+/* assumes input is pointer to two hex digits */
7fda0c
+/* returns -1 on error */
7fda0c
+int hex2int(char *b)
7fda0c
+{
7fda0c
+	int i;
7fda0c
+	int n=0;
7fda0c
+	int m;
7fda0c
+
7fda0c
+	for (i=0,m=1; i<2; i++,m--) {
7fda0c
+		if (isxdigit(*(b+i))) {
7fda0c
+			if (*(b+i) <= '9')
7fda0c
+				n |= (*(b+i) & 0x0f) << (4*m);
7fda0c
+			else
7fda0c
+				n |= ((*(b+i) & 0x0f) + 9) << (4*m);
7fda0c
+		}
7fda0c
+		else {
7fda0c
+			return -1;
7fda0c
+		}
7fda0c
+	}
7fda0c
+	return n;
7fda0c
+}
7fda0c
+
7fda0c
 char *print_mac(char *mac, char *buf)
7fda0c
 {
7fda0c
 	sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
7fda0c
@@ -189,26 +212,6 @@ int is_bond(const char *ifname)
7fda0c
 }
7fda0c
 
7fda0c
 /**
7fda0c
- *	is_san_mac - check if address is a san mac addr
7fda0c
- *	@addr: san mac address
7fda0c
- *
7fda0c
- *	Returns 0 if addr is NOT san mac, 1 if it is a san mac.
7fda0c
- *
7fda0c
- *	BUG: this does not do anything to prove it's a sanmac!!!!
7fda0c
- *	SAN MAC is no different than LAN MAC, no way to tell!!!
7fda0c
- */
7fda0c
-int is_san_mac(u8 *addr)
7fda0c
-{
7fda0c
-	int i;
7fda0c
-
7fda0c
-	for ( i = 0; i < ETH_ALEN; i++) {
7fda0c
-		if ( addr[i]!= 0xff )
7fda0c
-			return 1;
7fda0c
-	}
7fda0c
-	return 0;
7fda0c
-}
7fda0c
-
7fda0c
-/**
7fda0c
  *	get_src_mac_from_bond - select a source MAC to use for slave
7fda0c
  *	@bond_port: pointer to port structure for a bond interface
7fda0c
  *	@ifname: interface name of the slave port
7fda0c
@@ -314,11 +317,24 @@ int	get_src_mac_from_bond(struct port *b
7fda0c
  */
7fda0c
 int is_valid_mac(const u8 *mac)
7fda0c
 {
7fda0c
-	if (0 == (mac[0] | mac[1] | mac[2] | mac[3] | mac[4] | mac[5]))
7fda0c
-		return 0;
7fda0c
-	if (0xff == (mac[0] & mac[1] & mac[2] & mac[3] & mac[4] & mac[5]))
7fda0c
-		return 0;
7fda0c
-	return 1;
7fda0c
+	static const u8 zero_mac[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
7fda0c
+	static const u8 ff_mac[ETH_ALEN]   = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
7fda0c
+	static const u8 iana_mcast[ETH_ALEN] = {0x01, 0x00, 0x5E};
7fda0c
+	static const u8 ipv6_mcast[ETH_ALEN] = {0x33, 0x33};
7fda0c
+
7fda0c
+        if(memcmp(mac, zero_mac, ETH_ALEN) == 0 ||
7fda0c
+	   memcmp(mac, ff_mac, ETH_ALEN)   == 0)
7fda0c
+                return 0;
7fda0c
+
7fda0c
+	/* IANA multicast and ipv6 multicast mac address
7fda0c
+	 * For reference check document: 
7fda0c
+	 * https://www.iana.org/assignments/ethernet-numbers/ethernet-numbers.xhtml
7fda0c
+	 */
7fda0c
+        if(memcmp(mac, iana_mcast, 3) == 0 ||
7fda0c
+           memcmp(mac, ipv6_mcast, 2) == 0)
7fda0c
+                return 0;
7fda0c
+	
7fda0c
+        return 1;
7fda0c
 }
7fda0c
 
7fda0c
 int read_int(const char *path)
7fda0c
@@ -350,7 +366,7 @@ int get_ifflags(const char *ifname)
7fda0c
 	fd = get_ioctl_socket();
7fda0c
 	if (fd >= 0) {
7fda0c
 		memset(&ifr, 0, sizeof(ifr));
7fda0c
-		strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
7fda0c
+		STRNCPY_TERMINATED(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
7fda0c
 		if (ioctl(fd, SIOCGIFFLAGS, &ifr) == 0)
7fda0c
 			flags = ifr.ifr_flags;
7fda0c
 	}
7fda0c
@@ -386,7 +402,7 @@ int get_ifpflags(const char *ifname)
7fda0c
 	fd = get_ioctl_socket();
7fda0c
 	if (fd >= 0) {
7fda0c
 		memset(&ifr, 0, sizeof(ifr));
7fda0c
-		strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
7fda0c
+		STRNCPY_TERMINATED(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
7fda0c
 		if (ioctl(fd, SIOCGIFPFLAGS, &ifr) == 0)
7fda0c
 			flags = ifr.ifr_flags;
7fda0c
 	}
7fda0c
@@ -470,7 +486,7 @@ int is_slave(const char *ifmaster, const
7fda0c
 
7fda0c
 	memset(&ifr, 0, sizeof(ifr));
7fda0c
 	memset(&ifb, 0, sizeof(ifb));
7fda0c
-	strncpy(ifr.ifr_name, ifmaster, IFNAMSIZ);
7fda0c
+	STRNCPY_TERMINATED(ifr.ifr_name, ifmaster, IFNAMSIZ);
7fda0c
 	ifr.ifr_data = (caddr_t)&ifb;
7fda0c
 	if (ioctl(fd, SIOCBONDINFOQUERY, &ifr))
7fda0c
 		goto out_done;
7fda0c
@@ -500,7 +516,7 @@ int get_ifidx(const char *ifname)
7fda0c
 	fd = get_ioctl_socket();
7fda0c
 	if (fd >= 0) {
7fda0c
 		memset(&ifreq, 0, sizeof(ifreq));
7fda0c
-		strncpy(ifreq.ifr_name, ifname, IFNAMSIZ);
7fda0c
+		STRNCPY_TERMINATED(ifreq.ifr_name, ifname, IFNAMSIZ);
7fda0c
 		if (ioctl(fd, SIOCGIFINDEX, &ifreq) == 0)
7fda0c
 			idx = ifreq.ifr_ifindex;
7fda0c
 	}
7fda0c
@@ -572,7 +588,7 @@ int is_bridge(const char *ifname)
7fda0c
 						 (unsigned long) &bi, 0, 0 };
7fda0c
 
7fda0c
 			ifr.ifr_data = (char *)args;
7fda0c
-			strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
7fda0c
+			STRNCPY_TERMINATED(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
7fda0c
 			if (ioctl(fd, SIOCDEVPRIVATE, &ifr) == 0)
7fda0c
 				rc = 1;
7fda0c
 		}
7fda0c
@@ -610,7 +626,7 @@ int is_vlan(const char *ifname)
7fda0c
 	if (fd >= 0) {
7fda0c
 		memset(&ifv, 0, sizeof(ifv));
7fda0c
 		ifv.cmd = GET_VLAN_REALDEV_NAME_CMD;
7fda0c
-		strncpy(ifv.device1, ifname, sizeof(ifv.device1));
7fda0c
+		STRNCPY_TERMINATED(ifv.device1, ifname, sizeof(ifv.device1));
7fda0c
 		if (ioctl(fd, SIOCGIFVLAN, &ifv) == 0)
7fda0c
 			rc = 1;
7fda0c
 	}
7fda0c
@@ -637,7 +653,7 @@ int is_wlan(const char *ifname)
7fda0c
 	fd = get_ioctl_socket();
7fda0c
 	if (fd >= 0) {
7fda0c
 		memset(&iwreq, 0, sizeof(iwreq));
7fda0c
-		strncpy(iwreq.ifr_name, ifname, sizeof(iwreq.ifr_name));
7fda0c
+		STRNCPY_TERMINATED(iwreq.ifr_name, ifname, sizeof(iwreq.ifr_name));
7fda0c
 		if (ioctl(fd, SIOCGIWNAME, &iwreq) == 0)
7fda0c
 			rc = 1;
7fda0c
 	}
7fda0c
@@ -650,6 +666,8 @@ static struct nla_policy ifla_info_polic
7fda0c
 {
7fda0c
   [IFLA_INFO_KIND]       = { .type = NLA_STRING},
7fda0c
   [IFLA_INFO_DATA]       = { .type = NLA_NESTED },
7fda0c
+  [IFLA_INFO_SLAVE_KIND] = { .type = NLA_STRING},
7fda0c
+  [IFLA_INFO_SLAVE_DATA] = { .type = NLA_NESTED },
7fda0c
 };
7fda0c
 
7fda0c
 int is_macvtap(const char *ifname)
7fda0c
@@ -754,7 +772,7 @@ int is_active(const char *ifname)
7fda0c
 	fd = get_ioctl_socket();
7fda0c
 	if (fd >= 0) {
7fda0c
 		memset(&ifr, 0, sizeof(ifr));
7fda0c
-		strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
7fda0c
+		STRNCPY_TERMINATED(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
7fda0c
 		if (ioctl(fd, SIOCGIFFLAGS, &ifr) == 0)
7fda0c
 			if (ifr.ifr_flags & IFF_UP)
7fda0c
 				rc = 1;
7fda0c
@@ -775,7 +793,7 @@ int is_autoneg_supported(const char *ifn
7fda0c
 		memset(&cmd, 0, sizeof(cmd));
7fda0c
 		cmd.cmd = ETHTOOL_GSET;
7fda0c
 		ifr.ifr_data = &cm;;
7fda0c
-		strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
7fda0c
+		STRNCPY_TERMINATED(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
7fda0c
 		if (ioctl(fd, SIOCETHTOOL, &ifr) == 0)
7fda0c
 			if (cmd.supported & SUPPORTED_Autoneg)
7fda0c
 				rc = 1;
7fda0c
@@ -796,7 +814,7 @@ int is_autoneg_enabled(const char *ifnam
7fda0c
 		memset(&cmd, 0, sizeof(cmd));
7fda0c
 		cmd.cmd = ETHTOOL_GSET;
7fda0c
 		ifr.ifr_data = &cm;;
7fda0c
-		strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
7fda0c
+		STRNCPY_TERMINATED(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
7fda0c
 		if (ioctl(fd, SIOCETHTOOL, &ifr) == 0)
7fda0c
 			rc = cmd.autoneg;
7fda0c
 	}
7fda0c
@@ -833,7 +851,7 @@ int get_maucaps(const char *ifname)
7fda0c
 		memset(&cmd, 0, sizeof(cmd));
7fda0c
 		cmd.cmd = ETHTOOL_GSET;
7fda0c
 		ifr.ifr_data = &cm;;
7fda0c
-		strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
7fda0c
+		STRNCPY_TERMINATED(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
7fda0c
 		if (ioctl(fd, SIOCETHTOOL, &ifr) == 0) {
7fda0c
 			if (cmd.advertising & ADVERTISED_10baseT_Half)
7fda0c
 				caps |= MAUCAPADV_b10baseT;
7fda0c
@@ -872,7 +890,7 @@ int get_mautype(const char *ifname)
7fda0c
 		memset(&cmd, 0, sizeof(cmd));
7fda0c
 		cmd.cmd = ETHTOOL_GSET;
7fda0c
 		ifr.ifr_data = &cm;;
7fda0c
-		strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
7fda0c
+		STRNCPY_TERMINATED(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
7fda0c
 		if (ioctl(fd, SIOCETHTOOL, &ifr) == 0) {
7fda0c
 			/* TODO: too many dot3MauTypes,
7fda0c
 			 * should check duplex, speed, and port */
7fda0c
@@ -899,7 +917,7 @@ int get_mtu(const char *ifname)
7fda0c
 	fd = get_ioctl_socket();
7fda0c
 	if (fd >= 0) {
7fda0c
 		memset(&ifr, 0, sizeof(ifr));
7fda0c
-		strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
7fda0c
+		STRNCPY_TERMINATED(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
7fda0c
 		if (ioctl(fd, SIOCGIFMTU, &ifr) == 0)
7fda0c
 			rc = ifr.ifr_mtu;
7fda0c
 	}
7fda0c
@@ -921,38 +939,86 @@ int get_mfs(const char *ifname)
7fda0c
 	return mfs;
7fda0c
 }
7fda0c
 
7fda0c
-int get_mac(const char *ifname, u8 mac[])
7fda0c
+int get_mac(const char *ifname, u8 mac[], bool perm_mac)
7fda0c
 {
7fda0c
-	int fd;
7fda0c
-	int rc = EINVAL;
7fda0c
-	struct ifreq ifr;
7fda0c
+	int ret, s;
7fda0c
+	struct nlmsghdr *nlh;
7fda0c
+	struct ifinfomsg *ifinfo;
7fda0c
+	struct nlattr *tb[IFLA_MAX+1],
7fda0c
+		*tb2[IFLA_INFO_MAX+1];
7fda0c
 
7fda0c
-	memset(mac, 0, 6);
7fda0c
-	fd = get_ioctl_socket();
7fda0c
-	if (fd >= 0) {
7fda0c
-		ifr.ifr_addr.sa_family = AF_INET;
7fda0c
-		strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
7fda0c
-		if (!ioctl(fd, SIOCGIFHWADDR, &ifr)) {
7fda0c
-			memcpy(mac, ifr.ifr_hwaddr.sa_data, 6);
7fda0c
-			rc = 0;
7fda0c
-		}
7fda0c
+	s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
7fda0c
+
7fda0c
+	if (s < 0) {
7fda0c
+		goto out;
7fda0c
 	}
7fda0c
-	return rc;
7fda0c
-}
7fda0c
 
7fda0c
-int get_macstr(const char *ifname, char *addr, size_t size)
7fda0c
-{
7fda0c
-	u8 mac[6];
7fda0c
-	int rc;
7fda0c
+	nlh = malloc(NLMSG_SIZE);
7fda0c
 
7fda0c
-	rc = get_mac(ifname, mac);
7fda0c
-	if (rc == 0) {
7fda0c
-		snprintf(addr, size, "%02x:%02x:%02x:%02x:%02x:%02x",
7fda0c
-			mac[0], mac[1],	mac[2],	mac[3],	mac[4],	mac[5]);
7fda0c
+	if (!nlh) {
7fda0c
+		goto out;
7fda0c
 	}
7fda0c
-	return rc;
7fda0c
-}
7fda0c
 
7fda0c
+	memset(nlh, 0, NLMSG_SIZE);
7fda0c
+
7fda0c
+	nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
7fda0c
+	nlh->nlmsg_type = RTM_GETLINK;
7fda0c
+	nlh->nlmsg_flags = NLM_F_REQUEST;
7fda0c
+
7fda0c
+	ifinfo = NLMSG_DATA(nlh);
7fda0c
+	ifinfo->ifi_family = AF_UNSPEC;
7fda0c
+	ifinfo->ifi_index = get_ifidx(ifname);
7fda0c
+
7fda0c
+	ret = send(s, nlh, nlh->nlmsg_len, 0);
7fda0c
+
7fda0c
+	if (ret < 0) {
7fda0c
+		goto out_free;
7fda0c
+	}
7fda0c
+
7fda0c
+	memset(nlh, 0, NLMSG_SIZE);
7fda0c
+
7fda0c
+	do {
7fda0c
+		ret = recv(s, (void *) nlh, NLMSG_SIZE, MSG_DONTWAIT);
7fda0c
+	} while ((ret < 0) && errno == EINTR);
7fda0c
+
7fda0c
+	if (nlmsg_parse(nlh, sizeof(struct ifinfomsg),
7fda0c
+			(struct nlattr **)&tb, IFLA_MAX, NULL)) {
7fda0c
+		goto out_free;
7fda0c
+	}
7fda0c
+
7fda0c
+	if (tb[IFLA_ADDRESS])
7fda0c
+		memcpy(mac, (char*)(RTA_DATA(tb[IFLA_ADDRESS])), 6);
7fda0c
+
7fda0c
+	/* Check for the permanent mac address on bonding slaves */
7fda0c
+	if (perm_mac && tb[IFLA_LINKINFO]) {
7fda0c
+		char *kind;
7fda0c
+		struct nlattr *tb3;
7fda0c
+		int off = 0;
7fda0c
+
7fda0c
+		if (nla_parse_nested(tb2, IFLA_INFO_MAX, tb[IFLA_LINKINFO],
7fda0c
+				     ifla_info_policy)) {
7fda0c
+			goto out_free;
7fda0c
+		}
7fda0c
+		if (!tb2[IFLA_INFO_SLAVE_KIND])
7fda0c
+			goto out_free;
7fda0c
+
7fda0c
+		kind = (char*)(RTA_DATA(tb2[IFLA_INFO_SLAVE_KIND]));
7fda0c
+		if (strcmp(kind, "bond") && !tb2[IFLA_INFO_SLAVE_DATA])
7fda0c
+			goto out_free;
7fda0c
+
7fda0c
+		nla_for_each_nested(tb3, tb2[IFLA_INFO_SLAVE_DATA], off) {
7fda0c
+			if (nla_type(tb3) == IFLA_BOND_SLAVE_PERM_HWADDR) {
7fda0c
+				memcpy(mac, nla_data(tb3), nla_len(tb3));
7fda0c
+			}
7fda0c
+		}
7fda0c
+	}
7fda0c
+
7fda0c
+out_free:
7fda0c
+	free(nlh);
7fda0c
+out:
7fda0c
+	close(s);
7fda0c
+	return 0;
7fda0c
+}
7fda0c
 
7fda0c
 u16 get_caps(const char *ifname)
7fda0c
 {
7fda0c
@@ -998,7 +1064,7 @@ int get_saddr(const char *ifname, struct
7fda0c
 	fd = get_ioctl_socket();
7fda0c
 	if (fd >= 0) {
7fda0c
 		ifr.ifr_addr.sa_family = AF_INET;
7fda0c
-		strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
7fda0c
+		STRNCPY_TERMINATED(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
7fda0c
 		if (ioctl(fd, SIOCGIFADDR, &ifr) == 0) {
7fda0c
 			memcpy(saddr, &ifr.ifr_addr, sizeof(*saddr));
7fda0c
 			rc = 0;
7fda0c
@@ -1039,9 +1105,11 @@ int get_saddr6(const char *ifname, struc
7fda0c
 
7fda0c
 	rc = getifaddrs(&ifaddr);
7fda0c
 	if (rc == 0) {
7fda0c
+		rc = -1;
7fda0c
 		for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
7fda0c
-			if ((ifa->ifa_addr->sa_family == AF_INET6) &&
7fda0c
-			    (strncmp(ifa->ifa_name, ifname, IFNAMSIZ) == 0)) {
7fda0c
+			if (strncmp(ifa->ifa_name, ifname, IFNAMSIZ))
7fda0c
+				continue;
7fda0c
+			if (ifa->ifa_addr && (ifa->ifa_addr->sa_family == AF_INET6)) {
7fda0c
 				memcpy(saddr, ifa->ifa_addr, sizeof(*saddr));
7fda0c
 				rc = 0;
7fda0c
 				break;
7fda0c
@@ -1092,7 +1160,7 @@ int get_addr(const char *ifname, int dom
7fda0c
 	else if (domain == AF_INET6)
7fda0c
 		return get_ipaddr6(ifname, (struct in6_addr *)buf);
7fda0c
 	else if (domain == AF_UNSPEC)
7fda0c
-		return get_mac(ifname, (u8 *)buf);
7fda0c
+		return get_mac(ifname, (u8 *)buf, false);
7fda0c
 	else
7fda0c
 		return -1;
7fda0c
 }
7fda0c
@@ -1227,7 +1295,7 @@ int get_arg_val_list(char *ibuf, int ile
7fda0c
 		}
7fda0c
 		hexstr2bin(ibuf+*ioff, &arglen, sizeof(arglen));
7fda0c
 		*ioff += 2 * (int)sizeof(arglen);
7fda0c
-		if (ilen - *ioff >= arglen) {
7fda0c
+		if (ilen - *ioff >= 0) {
7fda0c
 			args[i] = ibuf+*ioff;
7fda0c
 			*ioff += arglen;
7fda0c
 			*(arglens+i) = arglen;
7fda0c
@@ -1237,7 +1305,7 @@ int get_arg_val_list(char *ibuf, int ile
7fda0c
 					   sizeof(argvalue_len));
7fda0c
 				argvalue_len = ntohs(argvalue_len);
7fda0c
 				*ioff += 2*sizeof(argvalue_len);
7fda0c
-				if (ilen - *ioff >= argvalue_len) {
7fda0c
+				if (ilen - *ioff >= 0) {
7fda0c
 					argvals[i] = ibuf+*ioff;
7fda0c
 					*ioff += argvalue_len;
7fda0c
 					*(argvallens+i) = argvalue_len;
7fda0c
diff -upr a/log.c b/log.c
7fda0c
--- a/log.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/log.c	2020-09-23 08:50:52.655813990 -0400
7fda0c
@@ -65,4 +65,5 @@ void log_message(int level, const char *
7fda0c
 		bypass_time = strchr(format, '\n') == 0;
7fda0c
 	}
7fda0c
 	va_end(va);
7fda0c
+	va_end(vb);
7fda0c
 }
7fda0c
diff -upr a/Makefile.am b/Makefile.am
7fda0c
--- a/Makefile.am	2021-06-09 10:58:59.212200603 -0400
7fda0c
+++ b/Makefile.am	2021-04-05 12:02:17.315590455 -0400
7fda0c
@@ -1,6 +1,9 @@
7fda0c
 # target programs to be installed in ${sbindir}
7fda0c
 sbin_PROGRAMS = lldpad dcbtool lldptool vdptool
7fda0c
 
7fda0c
+check_PROGRAMS = lldp_clif_test
7fda0c
+TESTS = $(check_PROGRAMS)
7fda0c
+
7fda0c
 # package nltest and vdptest, but do not install it anywhere
7fda0c
 if BUILD_DEBUG
7fda0c
 noinst_PROGRAMS = nltest vdptest qbg22sim
7fda0c
@@ -16,7 +19,7 @@ ACLOCAL_AMFLAGS = -I m4
7fda0c
 parse_cli.o: CFLAGS+=-U_FORTIFY_SOURCE -Wno-error
7fda0c
 
7fda0c
 ## system requires a shared libconfig
7fda0c
-AM_CFLAGS = -Wall -Werror -Wextra -Wformat=2 $(LIBCONFIG_CFLAGS) $(LIBNL_CFLAGS)
7fda0c
+AM_CFLAGS = $(LIBCONFIG_CFLAGS) $(LIBNL_CFLAGS)
7fda0c
 AM_LDFLAGS = $(LIBCONFIG_LIBS) $(LIBNL_LIBS) -lrt
7fda0c
 
7fda0c
 ## header files to be installed, for programs using the client interface to lldpad 
7fda0c
@@ -86,9 +89,11 @@ vdptool_LDADD = liblldp_clif.la
7fda0c
 vdptool_LDFLAGS = -llldp_clif $(LIBNL_LIBS)
7fda0c
 
7fda0c
 dcbtool_SOURCES = dcbtool.c dcbtool_cmds.c parse_cli.l \
7fda0c
-weak_readline.c $(lldpad_include_HEADERS) $(noinst_HEADERS)
7fda0c
+	weak_readline.c lldp_rtnl.c lldp_util.c \
7fda0c
+	$(lldpad_include_HEADERS) $(noinst_HEADERS)
7fda0c
+
7fda0c
 dcbtool_LDADD = liblldp_clif.la
7fda0c
-dcbtool_LDFLAGS = -ldl -llldp_clif
7fda0c
+dcbtool_LDFLAGS = -ldl -llldp_clif $(LIBNL_LIBS)
7fda0c
 
7fda0c
 lldptool_SOURCES = lldptool.c lldptool_cmds.c lldp_rtnl.c \
7fda0c
 		   lldp_mand_clif.c lldp_basman_clif.c lldp_med_clif.c \
7fda0c
@@ -140,3 +145,18 @@ bashcompletiondir = $(sysconfdir)/bash_c
7fda0c
 dist_bashcompletion_DATA = contrib/bash_completion/lldpad contrib/bash_completion/lldptool
7fda0c
 
7fda0c
 AM_DISTCHECK_CONFIGURE_FLAGS = --enable-debug
7fda0c
+
7fda0c
+lldp_clif_test_SOURCES = test/lldp_clif_test.c lldp_basman_clif.c lldp_util.c \
7fda0c
+	lldp_rtnl.c
7fda0c
+lldp_clif_test_LDFLAGS = -lrt $(LIBNL_LIBS)
7fda0c
+
7fda0c
+RPMBUILD_TOP = $(abs_top_builddir)/rpm/rpmbuild
7fda0c
+RPMBUILD_OPT ?= --without check
7fda0c
+
7fda0c
+# Build user-space RPMs
7fda0c
+rpm: dist $(srcdir)/lldpad.spec
7fda0c
+	${MKDIR_P} ${RPMBUILD_TOP}/SOURCES
7fda0c
+	cp ${DIST_ARCHIVES} ${RPMBUILD_TOP}/SOURCES
7fda0c
+	rpmbuild ${RPMBUILD_OPT} \
7fda0c
+                 -D "_topdir ${RPMBUILD_TOP}" \
7fda0c
+                 -ba $(srcdir)/lldpad.spec
7fda0c
diff -upr a/parse_cli.l b/parse_cli.l
7fda0c
--- a/parse_cli.l	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/parse_cli.l	2020-09-23 08:50:52.655813990 -0400
7fda0c
@@ -494,7 +494,8 @@ gp	{ if (!cmd) {
7fda0c
 					yyless(0);
7fda0c
 					}
7fda0c
 
7fda0c
-<getup2tc>[0-7]			{ up2tc_a[up2tc_idx++] = atoi(yytext);
7fda0c
+<getup2tc>[0-7]			{ up2tc_a[up2tc_idx] = atoi(yytext);
7fda0c
+				up2tc_idx++;
7fda0c
 				if (up2tc_idx == 8) {
7fda0c
 					BEGIN(getpgargs);
7fda0c
 				}
7fda0c
diff -upr a/qbg/ecp22.c b/qbg/ecp22.c
7fda0c
--- a/qbg/ecp22.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/qbg/ecp22.c	2020-10-23 14:12:58.976289329 -0400
7fda0c
@@ -119,7 +119,8 @@ static void ecp22_append(u8 *buffer, u32
7fda0c
  */
7fda0c
 void ecp22_putnode(struct ecp22_freelist *list, struct ecp22_payload_node *elm)
7fda0c
 {
7fda0c
-	elm->ptlv = free_pkd_tlv(elm->ptlv);
7fda0c
+	free_pkd_tlv(elm->ptlv);
7fda0c
+	elm->ptlv = NULL;
7fda0c
 	if (list->freecnt > ecp22_maxpayload)
7fda0c
 		free(elm);
7fda0c
 	else {
7fda0c
@@ -154,6 +155,7 @@ static bool ecp22_build_ecpdu(struct ecp
7fda0c
 	memset(ecp->tx.frame, 0, sizeof ecp->tx.frame);
7fda0c
 	ecp22_append(ecp->tx.frame, &fb_offset, (void *)&eth, sizeof eth);
7fda0c
 
7fda0c
+	memset(&ecph, 0, sizeof(struct ecp22_hdr));
7fda0c
 	ecp22_hdr_set_version(&ecph, 1);
7fda0c
 	ecp22_hdr_set_op(&ecph, ECP22_REQUEST);
7fda0c
 	ecp22_hdr_set_subtype(&ecph, ECP22_VDP);
7fda0c
@@ -749,7 +751,7 @@ static struct ecp22 *ecp22_create(char *
7fda0c
 			   ifname);
7fda0c
 		return NULL;
7fda0c
 	}
7fda0c
-	strncpy(ecp->ifname, ifname, sizeof ecp->ifname);
7fda0c
+	STRNCPY_TERMINATED(ecp->ifname, ifname, sizeof ecp->ifname);
7fda0c
 	ecp->l2 = l2_packet_init(ecp->ifname, 0, ETH_P_ECP22,
7fda0c
 				 ecp22_rx_receiveframe, ecp, 1);
7fda0c
 
7fda0c
@@ -774,7 +776,7 @@ void ecp22_start(char *ifname)
7fda0c
 	struct ecp22 *ecp;
7fda0c
 
7fda0c
 	LLDPAD_DBG("%s:%s start ecp\n", __func__, ifname);
7fda0c
-	eud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_ECP22);
7fda0c
+	eud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_ECP22);
7fda0c
 	if (!eud) {
7fda0c
 		LLDPAD_DBG("%s:%s no ECP module\n", __func__, ifname);
7fda0c
 		return;
7fda0c
@@ -782,6 +784,10 @@ void ecp22_start(char *ifname)
7fda0c
 	ecp = find_ecpdata(ifname, eud);
7fda0c
 	if (!ecp)
7fda0c
 		ecp = ecp22_create(ifname, eud);
7fda0c
+	if (!ecp) {
7fda0c
+		LLDPAD_DBG("%s:%s failed creating ECP22 instance\n", __func__, ifname);
7fda0c
+		return;
7fda0c
+	}
7fda0c
 	ecp->max_retries = ECP22_MAX_RETRIES_DEFAULT;
7fda0c
 	ecp->max_rte = ECP22_ACK_TIMER_DEFAULT;
7fda0c
 	LIST_INIT(&ecp->inuse.head);
7fda0c
@@ -803,7 +809,7 @@ static void ecp22_removelist(ecp22_list
7fda0c
 
7fda0c
 	while ((np = LIST_FIRST(ptr))) {
7fda0c
 		LIST_REMOVE(np, node);
7fda0c
-		np->ptlv = free_pkd_tlv(np->ptlv);
7fda0c
+		free_pkd_tlv(np->ptlv);
7fda0c
 		free(np);
7fda0c
 	}
7fda0c
 }
7fda0c
@@ -816,6 +822,7 @@ static void ecp22_remove(struct ecp22 *e
7fda0c
 	ecp22_removelist(&ecp->isfree.head);
7fda0c
 	ecp->isfree.freecnt = 0;
7fda0c
 	LIST_REMOVE(ecp, node);
7fda0c
+	l2_packet_deinit(ecp->l2);
7fda0c
 	free(ecp);
7fda0c
 }
7fda0c
 
7fda0c
@@ -832,7 +839,7 @@ void ecp22_stop(char *ifname)
7fda0c
 	struct ecp22 *ecp;
7fda0c
 
7fda0c
 	LLDPAD_DBG("%s:%s stop ecp\n", __func__, ifname);
7fda0c
-	eud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_ECP22);
7fda0c
+	eud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_ECP22);
7fda0c
 	ecp = find_ecpdata(ifname, eud);
7fda0c
 	if (ecp)
7fda0c
 		ecp22_remove(ecp);
7fda0c
@@ -847,7 +854,7 @@ static int ecp22_data_from_evb(char *ifn
7fda0c
 	struct ecp22_user_data *eud;
7fda0c
 	struct ecp22 *ecp;
7fda0c
 
7fda0c
-	eud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_ECP22);
7fda0c
+	eud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_ECP22);
7fda0c
 	ecp = find_ecpdata(ifname, eud);
7fda0c
 	if (ecp) {
7fda0c
 		ecp->max_rte = ptr->max_rte;
7fda0c
@@ -925,7 +932,7 @@ static int ecp22_req2send(char *ifname,
7fda0c
 
7fda0c
 	LLDPAD_DBG("%s:%s subtype:%d\n", __func__, ifname, subtype);
7fda0c
 
7fda0c
-	eud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_ECP22);
7fda0c
+	eud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_ECP22);
7fda0c
 	ecp = find_ecpdata(ifname, eud);
7fda0c
 	if (!ecp) {
7fda0c
 		rc = -ENODEV;
7fda0c
diff -upr a/qbg/ecp.c b/qbg/ecp.c
7fda0c
--- a/qbg/ecp.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/qbg/ecp.c	2020-09-23 08:50:52.656814007 -0400
7fda0c
@@ -299,7 +299,7 @@ static bool ecp_build_ECPDU(struct vdp_d
7fda0c
 
7fda0c
 		rc = ecp_append(vd->ecp.tx.frame, &fb_offset, ptlv->tlv,
7fda0c
 				ptlv->size);
7fda0c
-		ptlv = free_pkd_tlv(ptlv);
7fda0c
+		free_pkd_tlv(ptlv);
7fda0c
 		if (rc)
7fda0c
 			p->seqnr = vd->ecp.lastSequence;
7fda0c
 		else
7fda0c
@@ -682,7 +682,7 @@ static void ecp_rx_ReceiveFrame(void *ct
7fda0c
 	}
7fda0c
 
7fda0c
 	if (hdr->h_proto != example_hdr.h_proto) {
7fda0c
-		LLDPAD_ERR("%s:%s ERROR ethertype %#x not ECP ethertype",
7fda0c
+		LLDPAD_ERR("%s:%s ERROR ethertype %#x not ECP ethertype\n",
7fda0c
 			    __func__, vd->ecp.ifname, htons(hdr->h_proto));
7fda0c
 		frame_error++;
7fda0c
 		return;
7fda0c
@@ -795,7 +795,7 @@ int ecp_init(char *ifname)
7fda0c
 			   __func__, ifname);
7fda0c
 		return -1;
7fda0c
 	}
7fda0c
-	strncpy(vd->ecp.ifname, ifname, sizeof vd->ecp.ifname);
7fda0c
+	STRNCPY_TERMINATED(vd->ecp.ifname, ifname, sizeof vd->ecp.ifname);
7fda0c
 	ecp_rx_change_state(vd, ECP_RX_IDLE);
7fda0c
 	ecp_rx_run_sm(vd);
7fda0c
 	ecp_somethingChangedLocal(vd, true);
7fda0c
@@ -969,7 +969,7 @@ static void ecp_rx_ProcessFrame(struct v
7fda0c
 		if ((tlv->type != TYPE_0) && !tlv_stored) {
7fda0c
 			LLDPAD_DBG("%s:%s TLV (%u) was not stored (%p)\n",
7fda0c
 				   __func__, vd->ecp.ifname, tlv->type, tlv);
7fda0c
-			tlv = free_unpkd_tlv(tlv);
7fda0c
+			free_unpkd_tlv(tlv);
7fda0c
 			vd->ecp.stats.statsTLVsUnrecognizedTotal++;
7fda0c
 		}
7fda0c
 		tlv = NULL;
7fda0c
diff -upr a/qbg/vdp22.c b/qbg/vdp22.c
7fda0c
--- a/qbg/vdp22.c	2021-06-09 10:58:59.210200578 -0400
7fda0c
+++ b/qbg/vdp22.c	2020-10-23 14:12:58.977289347 -0400
7fda0c
@@ -455,10 +455,10 @@ static void copy_filter(unsigned char fi
7fda0c
 		fp->grpid = from->gpid;
7fda0c
 		if (fif == VDP22_FFMT_GROUPVID)
7fda0c
 			goto vid;
7fda0c
-		/* Fall through intended */
7fda0c
+		/* FALLTHROUGH */
7fda0c
 	case VDP22_FFMT_MACVID:
7fda0c
 		memcpy(fp->mac, from->mac, sizeof(fp->mac));
7fda0c
-		/* Fall through intended */
7fda0c
+		/* FALLTHROUGH */
7fda0c
 	case VDP22_FFMT_VID:
7fda0c
 vid:
7fda0c
 		fp->vlan = vdp22_set_vlanid(from->vlan)
7fda0c
@@ -694,7 +694,7 @@ static struct vdp22 *vdp22_findif(const
7fda0c
 	struct vdp22 *vdp = 0;
7fda0c
 
7fda0c
 	if (!ud) {
7fda0c
-		ud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_VDP22);
7fda0c
+		ud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_VDP22);
7fda0c
 		if (!ud)
7fda0c
 			LLDPAD_DBG("%s:%s no VDP22 module\n", __func__,
7fda0c
 				   ifname);
7fda0c
@@ -794,7 +794,7 @@ void vdp22_stop(char *ifname)
7fda0c
 	struct vsi22 *vsi;
7fda0c
 
7fda0c
 	LLDPAD_DBG("%s:%s stop vdp\n", __func__, ifname);
7fda0c
-	vud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_VDP22);
7fda0c
+	vud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_VDP22);
7fda0c
 	if (!vud) {
7fda0c
 		LLDPAD_ERR("%s:%s no VDP22 module\n", __func__, ifname);
7fda0c
 		return;
7fda0c
@@ -834,7 +834,7 @@ static struct vdp22 *vdp22_create(const
7fda0c
 			   ifname);
7fda0c
 		return NULL;
7fda0c
 	}
7fda0c
-	strncpy(vdp->ifname, ifname, sizeof vdp->ifname);
7fda0c
+	STRNCPY_TERMINATED(vdp->ifname, ifname, sizeof vdp->ifname);
7fda0c
 	vdp->myrole = role;
7fda0c
 	LIST_INIT(&vdp->vsi22_que);
7fda0c
 	LIST_INSERT_HEAD(&eud->head, vdp, node);
7fda0c
@@ -874,7 +874,7 @@ void vdp22_start(const char *ifname, int
7fda0c
 	struct vsi22 *vsi;
7fda0c
 
7fda0c
 	LLDPAD_DBG("%s:%s start vdp\n", __func__, ifname);
7fda0c
-	vud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_VDP22);
7fda0c
+	vud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_VDP22);
7fda0c
 	if (!vud) {
7fda0c
 		LLDPAD_ERR("%s:%s no VDP22 module\n", __func__, ifname);
7fda0c
 		return;
7fda0c
diff -upr a/qbg/vdp22_cmds.c b/qbg/vdp22_cmds.c
7fda0c
--- a/qbg/vdp22_cmds.c	2021-06-09 10:58:59.201200461 -0400
7fda0c
+++ b/qbg/vdp22_cmds.c	2020-10-23 14:12:58.977289347 -0400
7fda0c
@@ -57,7 +57,7 @@ static struct lldp_module *get_my_module
7fda0c
 {
7fda0c
 	struct lldp_module *np = NULL;
7fda0c
 
7fda0c
-	LIST_FOREACH(np, &lldp_head, lldp)
7fda0c
+	LIST_FOREACH(np, &lldp_mod_head, lldp)
7fda0c
 		if (thisid == np->id)
7fda0c
 			break;
7fda0c
 	return np;
7fda0c
@@ -296,7 +296,7 @@ int vdp22_sendevent(struct vdpnl_vsi *p)
7fda0c
 	return 0;
7fda0c
 }
7fda0c
 
7fda0c
-static int vdp22_cmdok(struct cmd *cmd, cmd_status expected)
7fda0c
+static int vdp22_cmdok(struct cmd *cmd, int expected)
7fda0c
 {
7fda0c
 	if (cmd->cmd != expected)
7fda0c
 		return cmd_invalid;
7fda0c
@@ -473,6 +473,7 @@ static bool vdp22_partial_vsi_equal(stru
7fda0c
 			if (memcmp(p1->mgrid, p2->mgrid,
7fda0c
 				   sizeof(p2->mgrid)))
7fda0c
 				return false;
7fda0c
+			/* FALLTHROUGH */
7fda0c
 		case VSI_TYPEID_ARG:
7fda0c
 			if (p1->type_id != p2->type_id)
7fda0c
 				return false;
7fda0c
@@ -576,7 +577,7 @@ static int get_arg_vsi(struct cmd *cmd,
7fda0c
 	memset(&vsi, 0, sizeof(vsi));
7fda0c
 	memset(vsi_str, 0, sizeof(vsi_str));
7fda0c
 	vsi.request = cmd->tlvid;
7fda0c
-	strncpy(vsi.ifname, cmd->ifname, sizeof(vsi.ifname) - 1);
7fda0c
+	strncpy(vsi.ifname, cmd->ifname, sizeof(vsi.ifname));
7fda0c
 	good_cmd = cmd_failed;
7fda0c
 	if ((cmd->ops & op_config) && (cmd->ops & op_arg)) {
7fda0c
 		memset(&mac, 0, sizeof(mac));
7fda0c
diff -upr a/qbg/vdp22sm.c b/qbg/vdp22sm.c
7fda0c
--- a/qbg/vdp22sm.c	2021-06-09 10:58:59.210200578 -0400
7fda0c
+++ b/qbg/vdp22sm.c	2020-09-23 08:50:52.657814025 -0400
7fda0c
@@ -1521,7 +1521,7 @@ static void vdp22br_process(struct vsi22
7fda0c
 	case VDP22_RESP_DEASSOC:
7fda0c
 		if (error > VDP22_STATUS_MASK)
7fda0c
 			p->status = VDP22_HARDBIT;
7fda0c
-		/* Fall through intended */
7fda0c
+		/* FALLTHROUGH */
7fda0c
 	case VDP22_RESP_SUCCESS:
7fda0c
 rest:
7fda0c
 		p->status |= VDP22_ACKBIT | make_status(error);
7fda0c
@@ -1768,7 +1768,7 @@ static void vdp22br_run(struct vsi22 *p)
7fda0c
 			break;
7fda0c
 		case VDP22_BR_END:
7fda0c
 			vdp22br_end(p);
7fda0c
-			break;
7fda0c
+			return;
7fda0c
 		}
7fda0c
 	} while (vdp22br_move_state(p) == true);
7fda0c
 }
7fda0c
diff -upr a/qbg/vdp.c b/qbg/vdp.c
7fda0c
--- a/qbg/vdp.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/qbg/vdp.c	2020-10-23 14:12:58.977289347 -0400
7fda0c
@@ -188,7 +188,7 @@ struct vdp_data *vdp_data(char *ifname)
7fda0c
 	struct vdp_user_data *ud;
7fda0c
 	struct vdp_data *vd = NULL;
7fda0c
 
7fda0c
-	ud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_VDP02);
7fda0c
+	ud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_VDP02);
7fda0c
 	if (ud) {
7fda0c
 		LIST_FOREACH(vd, &ud->head, entry) {
7fda0c
 			if (!strncmp(ifname, vd->ifname, IFNAMSIZ))
7fda0c
@@ -879,7 +879,7 @@ static bool vdp_vsi_set_bridge_state(str
7fda0c
 {
7fda0c
 	switch(profile->state) {
7fda0c
 	case VSI_UNASSOCIATED:
7fda0c
-		if ((profile->mode == VDP_MODE_DEASSOCIATE)) /* || (INACTIVE)) */ {
7fda0c
+		if (profile->mode == VDP_MODE_DEASSOCIATE) {
7fda0c
 			vdp_vsi_change_bridge_state(profile, VSI_DEASSOC_PROCESSING);
7fda0c
 			return true;
7fda0c
 		} else if (profile->mode == VDP_MODE_ASSOCIATE) {
7fda0c
@@ -1198,9 +1198,9 @@ int vdp_indicate(struct vdp_data *vd, st
7fda0c
 			/* put it in the list  */
7fda0c
 			profile->state = VSI_UNASSOCIATED;
7fda0c
 			LIST_INSERT_HEAD(&vd->profile_head, profile, profile);
7fda0c
-		}
7fda0c
 
7fda0c
-		vdp_vsi_sm_bridge(profile);
7fda0c
+			vdp_vsi_sm_bridge(profile);
7fda0c
+		}
7fda0c
 	}
7fda0c
 
7fda0c
 	return 0;
7fda0c
@@ -1357,7 +1357,7 @@ struct packed_tlv *vdp_gettlv(struct vdp
7fda0c
 	return ptlv;
7fda0c
 
7fda0c
 out_free:
7fda0c
-	ptlv = free_pkd_tlv(ptlv);
7fda0c
+	free_pkd_tlv(ptlv);
7fda0c
 out_err:
7fda0c
 	LLDPAD_ERR("%s: %s failed\n", __func__, vd->ifname);
7fda0c
 	return NULL;
7fda0c
@@ -1607,7 +1607,7 @@ void vdp_ifup(char *ifname, struct lldp_
7fda0c
 			 __func__, ifname, sizeof(*vd));
7fda0c
 		goto out_err;
7fda0c
 	}
7fda0c
-	strncpy(vd->ifname, ifname, IFNAMSIZ);
7fda0c
+	STRNCPY_TERMINATED(vd->ifname, ifname, IFNAMSIZ);
7fda0c
 
7fda0c
 	vd->role = VDP_ROLE_STATION;
7fda0c
 	vd->enabletx = enabletx;
7fda0c
@@ -1624,7 +1624,7 @@ void vdp_ifup(char *ifname, struct lldp_
7fda0c
 
7fda0c
 	LIST_INIT(&vd->profile_head);
7fda0c
 
7fda0c
-	ud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_VDP02);
7fda0c
+	ud = find_module_user_data_by_id(&lldp_mod_head, LLDP_MOD_VDP02);
7fda0c
 	LIST_INSERT_HEAD(&ud->head, vd, entry);
7fda0c
 
7fda0c
 out_start_again:
7fda0c
@@ -1882,7 +1882,7 @@ int vdp_trigger(struct vsi_profile *prof
7fda0c
 	if (!macp->req_pid)
7fda0c
 		return 0;
7fda0c
 	sleep(1);		/* Delay message notification */
7fda0c
-	if (!profile->port || !profile->port->ifname) {
7fda0c
+	if (!profile->port || !profile->port->ifname[0]) {
7fda0c
 		LLDPAD_ERR("%s: no ifname found for profile %p:\n", __func__,
7fda0c
 			   profile);
7fda0c
 		goto error_exit;
7fda0c
diff -upr a/qbg/vdp_cmds.c b/qbg/vdp_cmds.c
7fda0c
--- a/qbg/vdp_cmds.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/qbg/vdp_cmds.c	2020-09-23 08:50:52.658814043 -0400
7fda0c
@@ -85,7 +85,7 @@ static char *print_mode(char *s, size_t
7fda0c
 	return s;
7fda0c
 }
7fda0c
 
7fda0c
-static int vdp_cmdok(struct cmd *cmd, cmd_status expected)
7fda0c
+static int vdp_cmdok(struct cmd *cmd, int expected)
7fda0c
 {
7fda0c
 	if (cmd->cmd != expected)
7fda0c
 		return cmd_invalid;
7fda0c
diff -upr a/qbg/vdpnl.c b/qbg/vdpnl.c
7fda0c
--- a/qbg/vdpnl.c	2021-06-09 10:58:59.201200461 -0400
7fda0c
+++ b/qbg/vdpnl.c	2020-09-23 08:50:52.658814043 -0400
7fda0c
@@ -233,7 +233,7 @@ static int vdpnl_set(struct nlmsghdr *nl
7fda0c
 
7fda0c
 	vsi->ifindex = ifinfo->ifi_index;
7fda0c
 	if (tb[IFLA_IFNAME])
7fda0c
-		strncpy(vsi->ifname, (char *)RTA_DATA(tb[IFLA_IFNAME]),
7fda0c
+		STRNCPY_TERMINATED(vsi->ifname, (char *)RTA_DATA(tb[IFLA_IFNAME]),
7fda0c
 			sizeof vsi->ifname);
7fda0c
 	else {
7fda0c
 		if (!if_indextoname(ifinfo->ifi_index, vsi->ifname)) {
7fda0c
@@ -304,9 +304,9 @@ static size_t vdp_nllen(void)
7fda0c
 	size_t needed;
7fda0c
 
7fda0c
 	needed = nla_total_size(sizeof(struct nlattr)) /* IFLA_VF_PORT */
7fda0c
-		+ nla_total_size(4);	/* IFLA_PORT_VF */
7fda0c
-		+ nla_total_size(PORT_UUID_MAX); /* IFLA_PORT_INSTANCE_UUID */
7fda0c
-		+ nla_total_size(2);	/* IFLA_PORT_RESPONSE */
7fda0c
+		+ nla_total_size(4) /* IFLA_PORT_VF */
7fda0c
+		+ nla_total_size(PORT_UUID_MAX) /* IFLA_PORT_INSTANCE_UUID */
7fda0c
+		+ nla_total_size(2); /* IFLA_PORT_RESPONSE */
7fda0c
 	return needed;
7fda0c
 }
7fda0c
 
7fda0c
diff -upr a/qbg_utils.c b/qbg_utils.c
7fda0c
--- a/qbg_utils.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/qbg_utils.c	2020-11-03 09:08:48.062229088 -0500
7fda0c
@@ -36,7 +36,6 @@
7fda0c
 #include "qbg_utils.h"
7fda0c
 
7fda0c
 extern int loglvl;			/* Global lldpad log level */
7fda0c
-extern struct lldp_head lldp_head;
7fda0c
 
7fda0c
 /*
7fda0c
  * hexdump_frame - print raw evb/ecp/vdp frame
7fda0c
@@ -73,7 +72,7 @@ void hexdump_frame(const char *ifname, c
7fda0c
  */
7fda0c
 int modules_notify(int id, int sender_id, char *ifname, void *data)
7fda0c
 {
7fda0c
-	struct lldp_module *mp = find_module_by_id(&lldp_head, id);
7fda0c
+	struct lldp_module *mp = find_module_by_id(&lldp_mod_head, id);
7fda0c
 	int rc = 0;
7fda0c
 
7fda0c
 	if (mp && mp->ops->lldp_mod_notify)
7fda0c
diff -upr a/README b/README
7fda0c
--- a/README	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/README	2020-09-23 08:50:52.646813830 -0400
7fda0c
@@ -186,7 +186,9 @@ lldpad Application Install
7fda0c
    lldpad will create the lldpad.conf file if it does not exist.
7fda0c
 
7fda0c
    For development purposes, 'lldpad' can be run directly from the build 
7fda0c
-   directory.
7fda0c
+   directory.  To run the unit tests associated with openlldpd, execute:
7fda0c
+
7fda0c
+     ./bootstrap.sh; ./configure; make check
7fda0c
 
7fda0c
 Options
7fda0c
 -------
7fda0c
diff -upr a/tlv_dcbx.c b/tlv_dcbx.c
7fda0c
--- a/tlv_dcbx.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/tlv_dcbx.c	2020-09-23 08:50:52.659814061 -0400
7fda0c
@@ -154,7 +154,8 @@ struct unpacked_tlv *bld_dcbx1_tlv(struc
7fda0c
 			goto error;
7fda0c
 		memcpy(&tlv->info[offset], ptlv->tlv, ptlv->size);
7fda0c
 		offset += ptlv->size;
7fda0c
-		ptlv = free_pkd_tlv(ptlv);
7fda0c
+		free_pkd_tlv(ptlv);
7fda0c
+		ptlv = NULL;
7fda0c
 	}
7fda0c
 	if (tlv_ok(dcbx->pg1)) {
7fda0c
 		ptlv = pack_tlv(dcbx->pg1);
7fda0c
@@ -162,7 +163,8 @@ struct unpacked_tlv *bld_dcbx1_tlv(struc
7fda0c
 			goto error;
7fda0c
 		memcpy(&tlv->info[offset], ptlv->tlv, ptlv->size);
7fda0c
 		offset += ptlv->size;
7fda0c
-		ptlv = free_pkd_tlv(ptlv);
7fda0c
+		free_pkd_tlv(ptlv);
7fda0c
+		ptlv = NULL;
7fda0c
 	}
7fda0c
 	if (tlv_ok(dcbx->pfc1)) {
7fda0c
 		ptlv = pack_tlv(dcbx->pfc1);
7fda0c
@@ -170,7 +172,8 @@ struct unpacked_tlv *bld_dcbx1_tlv(struc
7fda0c
 			goto error;
7fda0c
 		memcpy(&tlv->info[offset], ptlv->tlv, ptlv->size);
7fda0c
 		offset += ptlv->size;
7fda0c
-		ptlv = free_pkd_tlv(ptlv);
7fda0c
+		free_pkd_tlv(ptlv);
7fda0c
+		ptlv = NULL;
7fda0c
 	}
7fda0c
 	if (tlv_ok(dcbx->app1)) {
7fda0c
 		ptlv = pack_tlv(dcbx->app1);
7fda0c
@@ -178,7 +181,8 @@ struct unpacked_tlv *bld_dcbx1_tlv(struc
7fda0c
 			goto error;
7fda0c
 		memcpy(&tlv->info[offset], ptlv->tlv, ptlv->size);
7fda0c
 		offset += ptlv->size;
7fda0c
-		ptlv = free_pkd_tlv(ptlv);
7fda0c
+		free_pkd_tlv(ptlv);
7fda0c
+		ptlv = NULL;
7fda0c
 	}
7fda0c
 
7fda0c
 	if (tlv_ok(dcbx->llink)) {
7fda0c
@@ -187,7 +191,8 @@ struct unpacked_tlv *bld_dcbx1_tlv(struc
7fda0c
 			goto error;
7fda0c
 		memcpy(&tlv->info[offset], ptlv->tlv, ptlv->size);
7fda0c
 		offset += ptlv->size;
7fda0c
-		ptlv = free_pkd_tlv(ptlv);
7fda0c
+		free_pkd_tlv(ptlv);
7fda0c
+		ptlv = NULL;
7fda0c
 	}
7fda0c
 
7fda0c
 	if (offset != tlv->length)
7fda0c
@@ -196,7 +201,8 @@ struct unpacked_tlv *bld_dcbx1_tlv(struc
7fda0c
 	return tlv;
7fda0c
 
7fda0c
 error:
7fda0c
-	ptlv = free_pkd_tlv(ptlv);
7fda0c
+	if (ptlv)
7fda0c
+		free_pkd_tlv(ptlv);
7fda0c
 	if (tlv) {
7fda0c
 		if (tlv->info)
7fda0c
 			free(tlv->info);
7fda0c
@@ -254,7 +260,8 @@ struct unpacked_tlv *bld_dcbx2_tlv(struc
7fda0c
 			goto error;
7fda0c
 		memcpy(&tlv->info[offset], ptlv->tlv, ptlv->size);
7fda0c
 		offset += ptlv->size;
7fda0c
-		ptlv = free_pkd_tlv(ptlv);
7fda0c
+		free_pkd_tlv(ptlv);
7fda0c
+		ptlv = NULL;
7fda0c
 	}
7fda0c
 	if (tlv_ok(dcbx->pg2)) {
7fda0c
 		ptlv = pack_tlv(dcbx->pg2);
7fda0c
@@ -262,7 +269,8 @@ struct unpacked_tlv *bld_dcbx2_tlv(struc
7fda0c
 			goto error;
7fda0c
 		memcpy(&tlv->info[offset], ptlv->tlv, ptlv->size);
7fda0c
 		offset += ptlv->size;
7fda0c
-		ptlv = free_pkd_tlv(ptlv);
7fda0c
+		free_pkd_tlv(ptlv);
7fda0c
+		ptlv = NULL;
7fda0c
 	}
7fda0c
 	if (tlv_ok(dcbx->pfc2)) {
7fda0c
 		ptlv = pack_tlv(dcbx->pfc2);
7fda0c
@@ -270,7 +278,8 @@ struct unpacked_tlv *bld_dcbx2_tlv(struc
7fda0c
 			goto error;
7fda0c
 		memcpy(&tlv->info[offset], ptlv->tlv, ptlv->size);
7fda0c
 		offset += ptlv->size;
7fda0c
-		ptlv = free_pkd_tlv(ptlv);
7fda0c
+		free_pkd_tlv(ptlv);
7fda0c
+		ptlv = NULL;
7fda0c
 	}
7fda0c
 	if (tlv_ok(dcbx->app2)) {
7fda0c
 		ptlv = pack_tlv(dcbx->app2);
7fda0c
@@ -278,7 +287,8 @@ struct unpacked_tlv *bld_dcbx2_tlv(struc
7fda0c
 			goto error;
7fda0c
 		memcpy(&tlv->info[offset], ptlv->tlv, ptlv->size);
7fda0c
 		offset += ptlv->size;
7fda0c
-		ptlv = free_pkd_tlv(ptlv);
7fda0c
+		free_pkd_tlv(ptlv);
7fda0c
+		ptlv = NULL;
7fda0c
 	}
7fda0c
 
7fda0c
 	if (offset != tlv->length)
7fda0c
@@ -287,7 +297,8 @@ struct unpacked_tlv *bld_dcbx2_tlv(struc
7fda0c
 	return tlv;
7fda0c
 
7fda0c
 error:
7fda0c
-	ptlv = free_pkd_tlv(ptlv);
7fda0c
+	if (ptlv)
7fda0c
+		free_pkd_tlv(ptlv);
7fda0c
 	if (tlv) {
7fda0c
 		if (tlv->info)
7fda0c
 			free(tlv->info);
7fda0c
diff -upr a/vdptool.c b/vdptool.c
7fda0c
--- a/vdptool.c	2021-06-09 10:58:59.202200474 -0400
7fda0c
+++ b/vdptool.c	2020-10-23 14:12:58.978289365 -0400
7fda0c
@@ -36,6 +36,7 @@
7fda0c
  * set and query VSI profile settings.
7fda0c
  */
7fda0c
 
7fda0c
+#define _GNU_SOURCE
7fda0c
 #include <stdlib.h>
7fda0c
 #include <stdio.h>
7fda0c
 #include <unistd.h>
7fda0c
@@ -60,6 +61,8 @@
7fda0c
 #define OUI_ENCODE_HNDLR(name) name##_oui_encode_hndlr
7fda0c
 #define OUI_PRNT_DECODE_HNDLR(name) name##_oui_print_decode_hndlr
7fda0c
 
7fda0c
+struct lldp_head lldp_mod_head;
7fda0c
+
7fda0c
 #define EXTERN_OUI_FN(name) \
7fda0c
 	extern bool name##_oui_encode_hndlr(char *, char *, size_t); \
7fda0c
 	extern void name##_oui_print_decode_hndlr(char *)
7fda0c
@@ -140,7 +143,7 @@ static char *print_status(cmd_status sta
7fda0c
 		str = "TLV does not support agent type";
7fda0c
 		break;
7fda0c
 	default:
7fda0c
-		str = print_vdp_status(status);
7fda0c
+		str = print_vdp_status((enum vdp22_cmd_status)status);
7fda0c
 		break;
7fda0c
 	}
7fda0c
 	return str;
7fda0c
@@ -178,7 +181,7 @@ static char *get_oui_name(char *argvals)
7fda0c
 
7fda0c
 static void fill_oui_hdr(vdptool_oui_data_t *oui_data, char *oui_name)
7fda0c
 {
7fda0c
-	strncpy(oui_data->oui_name, oui_name, sizeof(oui_data->oui_name));
7fda0c
+	STRNCPY_TERMINATED(oui_data->oui_name, oui_name, sizeof(oui_data->oui_name));
7fda0c
 	snprintf(oui_data->data, sizeof(oui_data->data), "%02x%s",
7fda0c
 		 (unsigned int)strlen(oui_data->oui_name), oui_data->oui_name);
7fda0c
 }
7fda0c
@@ -587,7 +590,7 @@ static void print_all_vsis(char *ibuf, b
7fda0c
 	size_t ilen = strlen(ibuf);
7fda0c
 	u16 vsi_len;
7fda0c
 	int offset = 0, vsi_cnt = 0;
7fda0c
-	char tmp_ibuf[strlen(ibuf)];
7fda0c
+	char tmp_ibuf[strlen(ibuf) + 1];
7fda0c
 
7fda0c
 	while (ilen > 0) {
7fda0c
 		vsi_len = hex2u16(ibuf + offset);
7fda0c
@@ -795,13 +798,13 @@ static void init_modules(void)
7fda0c
 	struct lldp_module *premod = NULL;
7fda0c
 	int i = 0;
7fda0c
 
7fda0c
-	LIST_INIT(&lldp_head);
7fda0c
+	LIST_INIT(&lldp_mod_head);
7fda0c
 	for (i = 0; register_tlv_table[i]; i++) {
7fda0c
 		module = register_tlv_table[i]();
7fda0c
 		if (premod)
7fda0c
 			LIST_INSERT_AFTER(premod, module, lldp);
7fda0c
 		else
7fda0c
-			LIST_INSERT_HEAD(&lldp_head, module, lldp);
7fda0c
+			LIST_INSERT_HEAD(&lldp_mod_head, module, lldp);
7fda0c
 		premod = module;
7fda0c
 	}
7fda0c
 }
7fda0c
@@ -810,9 +813,9 @@ void deinit_modules(void)
7fda0c
 {
7fda0c
 	struct lldp_module *module;
7fda0c
 
7fda0c
-	while (lldp_head.lh_first != NULL) {
7fda0c
-		module = lldp_head.lh_first;
7fda0c
-		LIST_REMOVE(lldp_head.lh_first, lldp);
7fda0c
+	while (lldp_mod_head.lh_first != NULL) {
7fda0c
+		module = lldp_mod_head.lh_first;
7fda0c
+		LIST_REMOVE(lldp_mod_head.lh_first, lldp);
7fda0c
 		module->ops->lldp_mod_unregister(module);
7fda0c
 	}
7fda0c
 }
7fda0c
@@ -952,7 +955,7 @@ cli_cmd_help(UNUSED struct clif *clif, U
7fda0c
 	printf("%s\n%s\n%s", commands_usage, commands_options, commands_help);
7fda0c
 
7fda0c
 	printf("\nTLV identifiers:\n");
7fda0c
-	LIST_FOREACH(np, &lldp_head, lldp)
7fda0c
+	LIST_FOREACH(np, &lldp_mod_head, lldp)
7fda0c
 		if (np->ops->print_help)
7fda0c
 			np->ops->print_help();
7fda0c
 	return 0;
7fda0c
@@ -1005,7 +1008,7 @@ u32 lookup_tlvid(char *tlvid_str)
7fda0c
 	struct lldp_module *np;
7fda0c
 	u32 tlvid = INVALID_TLVID;
7fda0c
 
7fda0c
-	LIST_FOREACH(np, &lldp_head, lldp) {
7fda0c
+	LIST_FOREACH(np, &lldp_mod_head, lldp) {
7fda0c
 		if (np->ops->lookup_tlv_name) {
7fda0c
 			tlvid = np->ops->lookup_tlv_name(tlvid_str);
7fda0c
 			if (tlvid != INVALID_TLVID)
7fda0c
diff -upr a/vdptool_cisco_oui.c b/vdptool_cisco_oui.c
7fda0c
--- a/vdptool_cisco_oui.c	2021-06-09 10:58:59.203200487 -0400
7fda0c
+++ b/vdptool_cisco_oui.c	2020-09-23 08:50:52.660814079 -0400
7fda0c
@@ -28,7 +28,7 @@
7fda0c
 #include "lldp_util.h"
7fda0c
 #include "vdp_cisco.h"
7fda0c
 
7fda0c
-bool cisco_oui_encode_hndlr(char *dst, char *src, int len)
7fda0c
+bool cisco_oui_encode_hndlr(char *dst, char *src, size_t len)
7fda0c
 {
7fda0c
 	char *src_temp = strdup(src);
7fda0c
 	char *key, *data;
7fda0c
diff -upr a/weak_readline.c b/weak_readline.c
7fda0c
--- a/weak_readline.c	2015-01-20 13:42:56.000000000 -0500
7fda0c
+++ b/weak_readline.c	2020-09-23 08:50:52.660814079 -0400
7fda0c
@@ -30,6 +30,9 @@
7fda0c
 #include <dlfcn.h>
7fda0c
 
7fda0c
 static int inited;
7fda0c
+static void *hist_handle;
7fda0c
+static void *rl_handle;
7fda0c
+
7fda0c
 
7fda0c
 static char *(*readline_p)(const char *);
7fda0c
 static void (*using_history_p)(void);
7fda0c
@@ -38,9 +41,6 @@ static void (*add_history_p)(const char
7fda0c
 
7fda0c
 static void weak_readline_init(void)
7fda0c
 {
7fda0c
-	void *hist_handle;
7fda0c
-	void *rl_handle;
7fda0c
-
7fda0c
 	inited = 1;
7fda0c
 	hist_handle = dlopen("libhistory.so", RTLD_LAZY | RTLD_GLOBAL);
7fda0c
 	if (!hist_handle)
7fda0c
@@ -77,6 +77,16 @@ void using_history(void)
7fda0c
 		using_history_p();
7fda0c
 }
7fda0c
 
7fda0c
+void close_history(void)
7fda0c
+{
7fda0c
+	if (inited) {
7fda0c
+		dlclose(rl_handle);
7fda0c
+		rl_handle = NULL;
7fda0c
+		dlclose(hist_handle);
7fda0c
+		hist_handle = NULL;
7fda0c
+	}
7fda0c
+}
7fda0c
+
7fda0c
 void stifle_history(int max)
7fda0c
 {
7fda0c
 	if (!inited)