[lldp-devel] [PATCH 2/8] introduce support for multiple agents per port

Jens Osterkamp jens at linux.vnet.ibm.com
Fri Aug 5 15:35:38 UTC 2011


This patch introduces support for multiple agents per port.
Each agent sends and receives frames to and from different group mac
addresses. Right now these are nearest bridge, nearest customer bridge and
nearest non-twoport mac-relaying bridge.

It splits out most of the agent specific variables from the port structure
to an agent structure. This requires changes in the rx and tx state
machines.

With the changes for the multi-agent support, adminStatus has moved from the
port to the agent. As port->adminStatus has been used to control the VDP
state machines as well, a new mechanism was needed here.
The VDP module does not have agent support, so port->adminStatus is replaced
by the vdp->enableTx flag. If this is set to yes by lldptool, VDP will be
active, and will be inactive if set to no.

Signed-off-by: Jens Osterkamp <jens at linux.vnet.ibm.com>
---
 config.c               |  115 ++++++++++--
 dcb_protocol.c         |    9 +-
 ecp/ecp.h              |    6 +-
 ecp/ecp_rx.c           |   15 +-
 ecp/ecp_tx.c           |   14 +-
 event_iface.c          |   45 +++--
 include/clif_msgs.h    |    2 +
 include/config.h       |    8 +-
 include/lldp.h         |    2 +-
 include/lldp_8021qaz.h |   11 +-
 include/lldp_8023.h    |    7 +-
 include/lldp_basman.h  |    7 +-
 include/lldp_dcbx.h    |   10 +-
 include/lldp_evb.h     |    9 +-
 include/lldp_mand.h    |    7 +-
 include/lldp_med.h     |    7 +-
 include/lldp_mod.h     |   12 +-
 include/lldp_vdp.h     |    1 +
 include/tlv_dcbx.h     |   14 +-
 lldp/agent.c           |  159 ++++++++++++++--
 lldp/agent.h           |  143 ++++++++++++++-
 lldp/l2_packet.h       |    9 +-
 lldp/l2_packet_linux.c |   16 +-
 lldp/ports.c           |  285 +++++++++++++---------------
 lldp/ports.h           |  108 ++---------
 lldp/rx.c              |  496 ++++++++++++++++++++++++------------------------
 lldp/states.h          |   57 +++---
 lldp/tx.c              |  327 +++++++++++++++++---------------
 lldp_8021qaz.c         |  134 ++++++++-----
 lldp_8021qaz_cmds.c    |   16 +-
 lldp_8023.c            |   22 ++-
 lldp_8023_cmds.c       |    2 +-
 lldp_basman.c          |   19 +-
 lldp_basman_cmds.c     |    6 +-
 lldp_dcbx.c            |   82 ++++----
 lldp_dcbx_cmds.c       |   16 +-
 lldp_evb.c             |   36 ++--
 lldp_evb_cmds.c        |   26 ++--
 lldp_mand.c            |   33 ++--
 lldp_mand_cmds.c       |   19 ++-
 lldp_med.c             |   19 +-
 lldp_med_cmds.c        |    4 +-
 lldp_tlv.c             |   17 +-
 lldp_vdp.c             |   43 ++--
 lldpad.c               |   11 +-
 tlv_dcbx.c             |  133 ++++++++------
 46 files changed, 1455 insertions(+), 1084 deletions(-)

diff --git a/config.c b/config.c
index 4c82bb6..041db49 100644
--- a/config.c
+++ b/config.c
@@ -38,6 +38,9 @@
 #include "eloop.h"
 #include "lldpad.h"
 #include "lldp.h"
+#include "lldp/ports.h"
+#include "lldp/agent.h"
+#include "lldp/l2_packet.h"
 #include "lldp_util.h"
 #include "lldp_mod.h"
 #include "lldp_mand_clif.h"
@@ -47,7 +50,6 @@
 #include "messages.h"
 #include "config.h"
 #include "clif_msgs.h"
-#include "lldp/l2_packet.h"
 #include "lldp_mod.h"
 #include "event_iface.h"
 
@@ -153,17 +155,23 @@ void scan_port(void *eloop_data, void *user_ctx)
 		struct lldp_module *np;
 		const struct lldp_mod_ops *ops;
 		char *ifname = p->if_name;
+		struct lldp_agent *agent;
 
 		if (is_valid_lldp_device(ifname)) {
 			if (check_link_status(ifname))
 				oper_add_device(ifname);
 			else {
-				LIST_FOREACH(np, &lldp_head, lldp) {
-					ops = np->ops;
-					if (ops->lldp_mod_ifdown)
-						ops->lldp_mod_ifdown(ifname);
+
+				LIST_FOREACH(agent, &port->agent_head, entry) {
+					LLDPAD_DBG("%s: calling ifdown for agent %p.\n",
+						   __func__, agent);
+					LIST_FOREACH(np, &lldp_head, lldp) {
+						ops = np->ops;
+						if (ops->lldp_mod_ifdown)
+							ops->lldp_mod_ifdown(ifname, agent);
+					}
 				}
-				set_lldp_port_enable_state(ifname, 0);
+				set_lldp_port_enable(ifname, 0);
 			}
 		}
 		p++;
@@ -337,6 +345,8 @@ void init_ports(void)
 {
 	struct lldp_module *np;
 	struct if_nameindex *nameidx, *p;
+	struct port *port;
+	struct lldp_agent *agent;
 
 	nameidx = if_nameindex();
 	if (nameidx == NULL) {
@@ -347,7 +357,6 @@ void init_ports(void)
 	p = nameidx;
 	while (p->if_index != 0) {
 		int valid = is_valid_lldp_device(p->if_name);
-		int err;
 
 		if (!valid) {
 			p++;
@@ -355,19 +364,27 @@ void init_ports(void)
 		}
 
 		if (is_bond(p->if_name))
-			err = add_bond_port(p->if_name);
+			port = add_bond_port(p->if_name);
 		else
-			err = add_port(p->if_name);
+			port = add_port(p->if_name);
 
-		if (err) {
+		if (port == NULL) {
 			LLDPAD_ERR("%s: Error adding device %s\n",
 				     __func__, p->if_name);
 		} else if (check_link_status(p->if_name)) {
-			LIST_FOREACH(np, &lldp_head, lldp) {
-				if (np->ops->lldp_mod_ifup)
-					np->ops->lldp_mod_ifup(p->if_name);
+			lldp_add_agent(p->if_name, NEAREST_BRIDGE);
+			lldp_add_agent(p->if_name, NEAREST_NONTPMR_BRIDGE);
+			lldp_add_agent(p->if_name, NEAREST_CUSTOMER_BRIDGE);
+
+			LIST_FOREACH(agent, &port->agent_head, entry) {
+				LLDPAD_DBG("%s: calling ifup for agent %p.\n",
+					   __func__, agent);
+				LIST_FOREACH(np, &lldp_head, lldp) {
+					if (np->ops->lldp_mod_ifup)
+						np->ops->lldp_mod_ifup(p->if_name, agent);
+				}
 			}
-			set_lldp_port_enable_state(p->if_name, 1);
+			set_lldp_port_enable(p->if_name, 1);
 		}
 		p++;
 	}
@@ -413,6 +430,76 @@ static int lookup_config_value(char *path, void *value, int type)
 	}
 }
 
+
+/*
+ * get_config_setting_by_agent - get the setting from the given config file path by type
+ * @ifname: interface name
+ * @agenttype: type of agent this needs to be retrieved from
+ * @path: relative to LLDP_COMMON or ifname section of LLDP configuration.
+ * @value: pointer to the value to be retrieved
+ * @type: libconfig value types
+ *
+ * Returns cmd_success(0) for success, otherwise for failure.
+ *
+ * This function assumes init_cfg() has been called.
+ */
+int get_config_setting_by_agent(const char *ifname, int agenttype, char *path,
+				void *value, int type)
+{
+	char p[1024];
+	int rval = CONFIG_FALSE;
+
+	/* look for setting in ifname areas first */
+	if (ifname) {
+		switch(agenttype) {
+		case NEAREST_BRIDGE:
+			snprintf(p, sizeof(p), "%s.%s.%s",
+				 LLDP_SETTING, ifname, path);
+			rval = lookup_config_value(p, value, type);
+			if (rval == CONFIG_FALSE) {
+				snprintf(p, sizeof(p), "%s.%s.%s",
+					 LLDP_NB, ifname, path);
+			}
+			break;
+		case NEAREST_CUSTOMER_BRIDGE:
+			snprintf(p, sizeof(p), "%s.%s.%s",
+				 LLDP_NCB, ifname, path);
+			break;
+		case NEAREST_NONTPMR_BRIDGE:
+			snprintf(p, sizeof(p), "%s.%s.%s",
+				 LLDP_NNTPB, ifname, path);
+			break;
+		}
+		rval = lookup_config_value(p, value, type);
+	}
+
+	/* if not found look for setting in common area */
+	if (rval == CONFIG_FALSE) {
+		switch(agenttype) {
+		case NEAREST_BRIDGE:
+			snprintf(p, sizeof(p), "%s.%s.%s",
+				 LLDP_SETTING, LLDP_COMMON, path);
+			rval = lookup_config_value(p, value, type);
+			if (rval == CONFIG_FALSE) {
+				snprintf(p, sizeof(p), "%s.%s.%s",
+					 LLDP_NB, LLDP_COMMON, path);
+			}
+			break;
+		case NEAREST_CUSTOMER_BRIDGE:
+			snprintf(p, sizeof(p), "%s.%s.%s",
+				 LLDP_NCB, LLDP_COMMON, path);
+			break;
+		case NEAREST_NONTPMR_BRIDGE:
+			snprintf(p, sizeof(p), "%s.%s.%s",
+				 LLDP_NNTPB, LLDP_COMMON, path);
+			break;
+		}
+		rval = lookup_config_value(p, value, type);
+	}
+
+	return (rval == CONFIG_FALSE) ? cmd_failed : cmd_success;
+}
+
 /*
  * get_config_setting - get the setting from the given config file path by type
  * @ifname: interface name
diff --git a/dcb_protocol.c b/dcb_protocol.c
index fec437d..2405a96 100644
--- a/dcb_protocol.c
+++ b/dcb_protocol.c
@@ -358,9 +358,6 @@ void features_erase(features_it *p)
 	*p = NULL;
 }
 
-int add_port(const char *device_name);
-int remove_port(const char *device_name);
-
 /* Add the store pointer to init_pg, i.e. memset store to 0,
  * then copy attribs to store
  */
@@ -3772,7 +3769,7 @@ dcb_result run_control_protocol(char *device_name, u32 EventFlag)
 						ctrl_prot->second->AckNo);
 
 					/* Send new DCB ctrl & feature TLVs */
-					somethingChangedLocal(device_name);
+					somethingChangedLocal(device_name, NEAREST_BRIDGE);
 				}
 			}
 			return dcb_success;
@@ -3887,7 +3884,7 @@ send:
 					ctrl_prot->second->SeqNo,
 					ctrl_prot->second->AckNo);
 				/* Send new DCB control & feature TLVs*/
-				somethingChangedLocal(device_name);
+				somethingChangedLocal(device_name, NEAREST_BRIDGE);
 				return dcb_success;
 			}
 
@@ -3900,7 +3897,7 @@ send:
 					ctrl_prot->second->SeqNo,
 					ctrl_prot->second->AckNo);
 				/* Send new DCB TLVs with old feature TLVs. */
-				somethingChangedLocal(device_name);
+				somethingChangedLocal(device_name, NEAREST_BRIDGE);
 			}
 		}
 	}
diff --git a/ecp/ecp.h b/ecp/ecp.h
index a454e4c..2bafd60 100644
--- a/ecp/ecp.h
+++ b/ecp/ecp.h
@@ -55,9 +55,9 @@ struct ecp {
 	int ackTimer;
 	u16 lastSequence;
 	u16 seqECPDU;
-	struct portrx rx;
-	struct porttx tx;
-	struct portstats stats;
+	struct agentrx rx;
+	struct agenttx tx;
+	struct agentstats stats;
 };
 
 struct ecp_hdr {
diff --git a/ecp/ecp_rx.c b/ecp/ecp_rx.c
index 74e9f32..1ab88c5 100644
--- a/ecp/ecp_rx.c
+++ b/ecp/ecp_rx.c
@@ -208,12 +208,13 @@ void ecp_rx_ReceiveFrame(void *ctx, unsigned int ifindex, const u8 *buf, size_t
 
 	port = port_find_by_name(vd->ifname);
 
+	if (port == NULL)
+		return;
+
 	LLDPAD_DBG("%s(%i)-%s: received packet with size %i\n", __func__, __LINE__,
 	       vd->ifname, (int) len);
 
-	if (!port ||
-	    port->adminStatus == disabled ||
-	    port->adminStatus == enabledTxOnly)
+	if (vd->enabletx == false)
 		return;
 
 	if (vd->ecp.rx.framein &&
@@ -236,7 +237,7 @@ void ecp_rx_ReceiveFrame(void *ctx, unsigned int ifindex, const u8 *buf, size_t
 
 	vd->ecp.rx.sizein = (u16)len;
 	ex = &example_hdr;
-	memcpy(ex->h_dest, multi_cast_source, ETH_ALEN);
+	memcpy(ex->h_dest, nearest_bridge, ETH_ALEN);
 	ex->h_proto = htons(ETH_P_ECP);
 	hdr = (struct l2_ethhdr *)vd->ecp.rx.framein;
 
@@ -551,15 +552,13 @@ bool ecp_set_rx_state(struct vdp_data *vd)
 		}
 		return false;
 	case ECP_RX_INIT_RECEIVE:
-		if ((port->adminStatus == enabledRxTx) ||
-			(port->adminStatus == enabledRxOnly)) {
+		if (vd->enabletx == true) {
 			ecp_rx_change_state(vd, ECP_RX_RECEIVE_WAIT);
 			return true;
 		}
 		return false;
 	case ECP_RX_RECEIVE_WAIT:
-		if ((port->adminStatus == disabled) ||
-			(port->adminStatus == enabledTxOnly)) {
+		if (vd->enabletx == false) {
 			ecp_rx_change_state(vd, ECP_RX_IDLE);
 			return true;
 		}
diff --git a/ecp/ecp_tx.c b/ecp/ecp_tx.c
index f9ee3d7..11529eb 100644
--- a/ecp/ecp_tx.c
+++ b/ecp/ecp_tx.c
@@ -133,9 +133,8 @@ bool ecp_build_ECPDU(struct vdp_data *vd)
 	struct packed_tlv *ptlv =  NULL;
 	struct vsi_profile *p;
 
-	/* TODO: different multicast address for sending ECP over S-channel (multi_cast_source_s)
-	 * S-channels to implement later */
-	memcpy(eth.h_dest, multi_cast_source, ETH_ALEN);
+	/* TODO: use LLDP group MAC addresses to support S-channels/multichannel*/
+	memcpy(eth.h_dest, nearest_bridge, ETH_ALEN);
 	l2_packet_get_own_src_addr(vd->ecp.l2,(u8 *)&own_addr);
 	memcpy(eth.h_source, &own_addr, ETH_ALEN);
 	eth.h_proto = htons(ETH_P_ECP);
@@ -267,7 +266,7 @@ u8 ecp_txFrame(struct vdp_data *vd)
 {
 	int status = 0;
 
-	status = l2_packet_send(vd->ecp.l2, (u8 *)&multi_cast_source,
+	status = l2_packet_send(vd->ecp.l2, (u8 *)&nearest_bridge,
 		htons(ETH_P_ECP),vd->ecp.tx.frameout,vd->ecp.tx.sizeout);
 	vd->ecp.stats.statsFramesOutTotal++;
 
@@ -414,15 +413,14 @@ static bool ecp_set_tx_state(struct vdp_data *vd)
 
 	switch (vd->ecp.tx.state) {
 	case ECP_TX_INIT_TRANSMIT:
-		if (port->portEnabled && ((port->adminStatus == enabledRxTx) ||
-			(port->adminStatus == enabledTxOnly)) && vd->ecp.tx.localChange) {
+		if (port->portEnabled && (vd->enabletx == true)
+					  && vd->ecp.tx.localChange) {
 			ecp_tx_change_state(vd, ECP_TX_TRANSMIT_ECPDU);
 			return true;
 		}
 		return false;
 	case ECP_TX_TRANSMIT_ECPDU:
-		if ((port->adminStatus == disabled) ||
-			(port->adminStatus == enabledRxOnly)) {
+		if (vd->enabletx == false) {
 			ecp_tx_change_state(vd, ECP_TX_INIT_TRANSMIT);
 			return true;
 		}
diff --git a/event_iface.c b/event_iface.c
index e581bce..d923a9e 100644
--- a/event_iface.c
+++ b/event_iface.c
@@ -183,8 +183,8 @@ static void event_if_decode_rta(int type, struct rtattr *rta, int *ls, char *d)
 int oper_add_device(char *device_name)
 {
 	struct lldp_module *np;
-	const struct lldp_mod_ops *ops;
-	struct port *port;
+	struct port *port, *newport;
+	struct lldp_agent *agent;
 	int err;
 
 	port = porthead;
@@ -196,11 +196,11 @@ int oper_add_device(char *device_name)
 
 	if (!port) {
 		if (is_bond(device_name))
-			err = add_bond_port(device_name);
+			newport = add_bond_port(device_name);
 		else
-			err = add_port(device_name);
+			newport = add_port(device_name);
 
-		if (err) {
+		if (newport) {
 			LLDPAD_INFO("%s: Error adding device %s\n",
 				__func__, device_name);
 			return err;
@@ -210,13 +210,20 @@ int oper_add_device(char *device_name)
 	} else if (!port->portEnabled)
 		reinit_port(device_name);
 
-	LIST_FOREACH(np, &lldp_head, lldp) {
-		ops = np->ops;
-		if (ops->lldp_mod_ifup)
-			ops->lldp_mod_ifup(device_name);
+	lldp_add_agent(device_name, NEAREST_BRIDGE);
+	lldp_add_agent(device_name, NEAREST_NONTPMR_BRIDGE);
+	lldp_add_agent(device_name, NEAREST_CUSTOMER_BRIDGE);
+
+	LIST_FOREACH(agent, &port->agent_head, entry) {
+		LLDPAD_DBG("%s: calling ifup for agent %p.\n",
+			   __func__, agent);
+		LIST_FOREACH(np, &lldp_head, lldp) {
+			if (np->ops->lldp_mod_ifup)
+				np->ops->lldp_mod_ifup(device_name, agent);
+		}
 	}
 
-	set_lldp_port_enable_state(device_name, 1);
+	set_lldp_port_enable(device_name, 1);
 	return 0;
 }
 
@@ -226,6 +233,7 @@ static void event_if_decode_nlmsg(int route_type, void *data, int len)
 	const struct lldp_mod_ops *ops;
 	struct rtattr *rta;
 	char device_name[IFNAMSIZ];
+	struct lldp_agent *agent;
 	int attrlen;
 	int valid;
 	int link_status = IF_OPER_UNKNOWN;
@@ -268,14 +276,21 @@ static void event_if_decode_nlmsg(int route_type, void *data, int len)
 			if (!valid)
 				break;
 
-			LIST_FOREACH(np, &lldp_head, lldp) {
-				ops = np->ops;
-				if (ops->lldp_mod_ifdown)
-					ops->lldp_mod_ifdown(device_name);
+			struct port *port = port_find_by_name(device_name);
+
+			LIST_FOREACH(agent, &port->agent_head, entry) {
+				LLDPAD_DBG("%s: calling ifdown for agent %p.\n",
+					   __func__, agent);
+				LIST_FOREACH(np, &lldp_head, lldp) {
+					ops = np->ops;
+					if (ops->lldp_mod_ifdown)
+						ops->lldp_mod_ifdown(device_name,
+								     agent);
+				}
 			}
 
 			/* Disable Port */
-			set_lldp_port_enable_state(device_name, 0);
+			set_lldp_port_enable(device_name, 0);
 
 			if (route_type == RTM_DELLINK) {
 				LLDPAD_INFO("%s: %s: device removed!\n",
diff --git a/include/clif_msgs.h b/include/clif_msgs.h
index 856ab98..0fa000a 100644
--- a/include/clif_msgs.h
+++ b/include/clif_msgs.h
@@ -98,6 +98,7 @@ struct cmd {
 	__u32 module_id;
 	__u32 ops;
 	__u32 tlvid;
+	__u8 type;
 	char ifname[IFNAMSIZ+1];
 	char obuf[MAX_CLIF_MSGBUF];
 };
@@ -117,6 +118,7 @@ typedef enum {
     cmd_success = 0,
     cmd_failed,
     cmd_device_not_found,
+    cmd_agent_not_found,
     cmd_invalid,
     cmd_bad_params,
     cmd_peer_not_present,
diff --git a/include/config.h b/include/config.h
index 33c1021..553149d 100644
--- a/include/config.h
+++ b/include/config.h
@@ -32,8 +32,11 @@
 
 #define DEFAULT_CFG_FILE "/var/lib/lldpad/lldpad.conf"
 
-#define LLDP_SETTING "lldp"
-#define LLDP_COMMON  "common"
+#define LLDP_SETTING	"lldp"
+#define LLDP_NB		"nearest_bridge"
+#define LLDP_NCB	"nearest_customer_bridge"
+#define LLDP_NNTPB	"nearest_nontpmr_bridge"
+#define LLDP_COMMON	"common"
 
 #define INI_TIMER	5
 
@@ -50,6 +53,7 @@ void scan_port(void *eloop_data, void *user_ctx);
 int get_cfg(const char *ifname, char *path, void *value, int type);
 int set_cfg(const char *ifname, char *path, void *value, int type);
 int get_config_setting(const char *ifname, char *path, void *value, int type);
+int get_config_setting_by_agent(const char *ifname, int agenttype, char *path, void *value, int type);
 int set_config_setting(const char *ifname, char *path, void *value, int type);
 int remove_config_setting(const char *ifname, char *parent, char *name);
 int get_config_tlvfield(const char *ifname, u32 tlvid, const char *field, void *value, int type);
diff --git a/include/lldp.h b/include/lldp.h
index d89978c..5d185a3 100644
--- a/include/lldp.h
+++ b/include/lldp.h
@@ -231,5 +231,5 @@ enum {
 #define LLDP_EVB_DEFAULT_SVSI				3295
 #define LLDP_EVB_DEFAULT_RTE				15
 
-void somethingChangedLocal(const char *ifname);
+void somethingChangedLocal(const char *ifname, int type);
 #endif /* _LLDP_H */
diff --git a/include/lldp_8021qaz.h b/include/lldp_8021qaz.h
index 8f5cf56..0cf2ac1 100644
--- a/include/lldp_8021qaz.h
+++ b/include/lldp_8021qaz.h
@@ -228,11 +228,12 @@ int ieee8021qaz_check_active(const char *ifname);
 
 struct lldp_module *ieee8021qaz_register(void);
 void ieee8021qaz_unregister(struct lldp_module *mod);
-struct packed_tlv *ieee8021qaz_gettlv(struct port *port);
-int ieee8021qaz_rchange(struct port *port, struct unpacked_tlv *tlv);
-void ieee8021qaz_ifup(char *ifname);
-void ieee8021qaz_ifdown(char *ifname);
-u8 ieee8021qaz_mibDeleteObject(struct port *port);
+struct packed_tlv *ieee8021qaz_gettlv(struct port *port, struct lldp_agent *);
+int ieee8021qaz_rchange(struct port *port, struct lldp_agent *,
+			struct unpacked_tlv *tlv);
+void ieee8021qaz_ifup(char *ifname, struct lldp_agent *);
+void ieee8021qaz_ifdown(char *ifname, struct lldp_agent *);
+u8 ieee8021qaz_mibDeleteObject(struct port *port, struct lldp_agent *);
 inline int ieee8021qaz_clif_cmd(void *data, struct sockaddr_un *from,
 				socklen_t fromlen, char *ibuf, int ilen,
 				char *rbuf);
diff --git a/include/lldp_8023.h b/include/lldp_8023.h
index 193802a..4330d09 100644
--- a/include/lldp_8023.h
+++ b/include/lldp_8023.h
@@ -34,6 +34,7 @@
 
 struct ieee8023_data {
 	char ifname[IFNAMSIZ];
+	enum agent_type agenttype;
 	struct unpacked_tlv *maccfg;
 	struct unpacked_tlv *powvmdi;
 	struct unpacked_tlv *linkagg;
@@ -47,8 +48,8 @@ struct ieee8023_user_data {
 
 struct lldp_module *ieee8023_register(void);
 void ieee8023_unregister(struct lldp_module *mod);
-struct packed_tlv *ieee8023_gettlv(struct port *port);
-void ieee8023_ifdown(char *);
-void ieee8023_ifup(char *);
+struct packed_tlv *ieee8023_gettlv(struct port *, struct lldp_agent *);
+void ieee8023_ifdown(char *, struct lldp_agent *);
+void ieee8023_ifup(char *, struct lldp_agent *);
 
 #endif /* _LLDP_8023_H */
diff --git a/include/lldp_basman.h b/include/lldp_basman.h
index 22520f8..104516c 100644
--- a/include/lldp_basman.h
+++ b/include/lldp_basman.h
@@ -35,6 +35,7 @@
 
 struct basman_data {
 	char ifname[IFNAMSIZ];
+	enum agent_type agenttype;
 	struct unpacked_tlv *portdesc;
 	struct unpacked_tlv *sysname;
 	struct unpacked_tlv *sysdesc;
@@ -50,8 +51,8 @@ struct basman_user_data {
 
 struct lldp_module *basman_register(void);
 void basman_unregister(struct lldp_module *mod);
-struct packed_tlv *basman_gettlv(struct port *port);
-void basman_ifdown(char *);
-void basman_ifup(char *);
+struct packed_tlv *basman_gettlv(struct port *, struct lldp_agent *);
+void basman_ifdown(char *, struct lldp_agent *);
+void basman_ifup(char *, struct lldp_agent *);
 
 #endif /* _LLDP_BASMAN_H */
diff --git a/include/lldp_dcbx.h b/include/lldp_dcbx.h
index e8633fd..e7a69e8 100644
--- a/include/lldp_dcbx.h
+++ b/include/lldp_dcbx.h
@@ -80,11 +80,11 @@ int dcbx_tlvs_rxed(const char *ifname);
 int dcbx_check_active(const char *ifname);
 int dcbx_get_legacy_version();
 
-struct packed_tlv *dcbx_gettlv(struct port *port);
-int dcbx_rchange(struct port *port,  struct unpacked_tlv *tlv);
-u8 dcbx_mibDeleteObjects(struct port *port);
-void dcbx_ifup(char *device_name);
-void dcbx_ifdown(char *device_name);
+struct packed_tlv *dcbx_gettlv(struct port *, struct lldp_agent *);
+int dcbx_rchange(struct port *, struct lldp_agent *, struct unpacked_tlv *);
+u8 dcbx_mibDeleteObjects(struct port *, struct lldp_agent *);
+void dcbx_ifup(char *, struct lldp_agent *);
+void dcbx_ifdown(char *, struct lldp_agent *);
 struct lldp_module *dcbx_register(void);
 void dcbx_unregister(struct lldp_module *);
 int dcbx_clif_cmd(void *, struct sockaddr_un *,
diff --git a/include/lldp_evb.h b/include/lldp_evb.h
index 9e11824..2acbbc5 100644
--- a/include/lldp_evb.h
+++ b/include/lldp_evb.h
@@ -64,6 +64,7 @@ struct tlv_info_evb {
 
 struct evb_data {
 	char ifname[IFNAMSIZ];
+	enum agent_type agenttype;
 	struct unpacked_tlv *evb;
 	struct tlv_info_evb *tie;
 	struct tlv_info_evb *last;
@@ -78,10 +79,10 @@ struct evb_user_data {
 
 struct lldp_module *evb_register(void);
 void evb_unregister(struct lldp_module *mod);
-struct packed_tlv *evb_gettlv(struct port *port);
-void evb_ifdown(char *);
-void evb_ifup(char *);
-struct evb_data *evb_data(char *ifname);
+struct packed_tlv *evb_gettlv(struct port *, struct lldp_agent *);
+void evb_ifdown(char *, struct lldp_agent *);
+void evb_ifup(char *, struct lldp_agent *);
+struct evb_data *evb_data(char *ifname, enum agent_type);
 
 int evb_check_and_fill(struct evb_data *ed, struct tlv_info_evb *tie);
 
diff --git a/include/lldp_mand.h b/include/lldp_mand.h
index 5f96b93..36e02d3 100644
--- a/include/lldp_mand.h
+++ b/include/lldp_mand.h
@@ -34,6 +34,7 @@
 
 struct mand_data {
 	char ifname[IFNAMSIZ];
+	enum agent_type agenttype;
 	struct unpacked_tlv *chassis;
 	struct unpacked_tlv *portid;
 	struct unpacked_tlv *ttl;
@@ -49,7 +50,7 @@ struct mand_user_data {
 
 struct lldp_module *mand_register(void);
 void mand_unregister(struct lldp_module *mod);
-struct packed_tlv *mand_gettlv(struct port *port);
-void mand_ifdown(char *);
-void mand_ifup(char *);
+struct packed_tlv *mand_gettlv(struct port *, struct lldp_agent *);
+void mand_ifdown(char *, struct lldp_agent *);
+void mand_ifup(char *, struct lldp_agent *);
 #endif /* _LLDP_MAND_H */
diff --git a/include/lldp_med.h b/include/lldp_med.h
index c3aeaad..118100c 100644
--- a/include/lldp_med.h
+++ b/include/lldp_med.h
@@ -35,6 +35,7 @@
 
 struct med_data {
 	char ifname[IFNAMSIZ];
+	enum agent_type agenttype;
 	struct unpacked_tlv *medcaps;
 	struct unpacked_tlv *netpoli;
 	struct unpacked_tlv *locid;
@@ -55,8 +56,8 @@ struct med_user_data {
 
 struct lldp_module *med_register(void);
 void med_unregister(struct lldp_module *mod);
-struct packed_tlv *med_gettlv(struct port *port);
-void med_ifdown(char *);
-void med_ifup(char *);
+struct packed_tlv *med_gettlv(struct port *, struct lldp_agent *);
+void med_ifdown(char *, struct lldp_agent *);
+void med_ifup(char *, struct lldp_agent *);
 
 #endif /* _LLDP_MED_H */
diff --git a/include/lldp_mod.h b/include/lldp_mod.h
index 208bdd4..009734d 100644
--- a/include/lldp_mod.h
+++ b/include/lldp_mod.h
@@ -55,13 +55,14 @@
 struct lldp_mod_ops {
 	struct lldp_module * 	(* lldp_mod_register)(void);
 	void 			(* lldp_mod_unregister)(struct lldp_module *);
-	struct packed_tlv * 	(* lldp_mod_gettlv)(struct port *);
+	struct packed_tlv * 	(* lldp_mod_gettlv)(struct port *, struct lldp_agent *);
 	int  			(* lldp_mod_rchange)(struct port *,
+						     struct lldp_agent *,
 						    struct unpacked_tlv *);
 	void  			(* lldp_mod_utlv)(struct port *);
-	void  			(* lldp_mod_ifup)(char *); 
-	void			(* lldp_mod_ifdown)(char *);
-	u8 			(* lldp_mod_mibdelete)(struct port *port);
+	void  			(* lldp_mod_ifup)(char *, struct lldp_agent *); 
+	void			(* lldp_mod_ifdown)(char *, struct lldp_agent *);
+	u8 			(* lldp_mod_mibdelete)(struct port *port, struct lldp_agent *);
 	u32			(* client_register)(void);
 	int  			(* client_cmd)(void *data,
 					      struct sockaddr_un *from,
@@ -70,7 +71,7 @@ struct lldp_mod_ops {
 	int  			(* print_tlv)(u32, u16, char *);
 	u32			(* lookup_tlv_name)(char *);
 	int			(* print_help)();
-	int			(* timer)();
+	int			(* timer)(struct port *, struct lldp_agent *);
 	struct arg_handlers *	(* get_arg_handler)(void);
 };
 
@@ -95,7 +96,6 @@ struct lldp_module {
 LIST_HEAD(lldp_head, lldp_module);
 struct lldp_head lldp_head;
 
-
 static inline struct lldp_module *find_module_by_id(struct lldp_head *head, int id)
 {
  	struct lldp_module *mod;
diff --git a/include/lldp_vdp.h b/include/lldp_vdp.h
index 2f6adf8..f9cdee2 100644
--- a/include/lldp_vdp.h
+++ b/include/lldp_vdp.h
@@ -111,6 +111,7 @@ struct vsi_profile {
 
 struct vdp_data {
 	char ifname[IFNAMSIZ];
+	u8 enabletx;
 	struct ecp ecp;
 	struct unpacked_tlv *vdp;
 	int role;
diff --git a/include/tlv_dcbx.h b/include/tlv_dcbx.h
index d64d7b4..eb9ba38 100644
--- a/include/tlv_dcbx.h
+++ b/include/tlv_dcbx.h
@@ -241,13 +241,13 @@ struct unpacked_tlv *bld_dcbx2_app_tlv(struct dcbx_tlvs *, u32 sub_type,
 struct unpacked_tlv *bld_dcbx_llink_tlv(struct dcbx_tlvs *, u32 sub_type,
 					bool *success);
 
-bool   unpack_dcbx1_tlvs(struct port *, struct unpacked_tlv *);
-bool   unpack_dcbx2_tlvs(struct port *, struct unpacked_tlv *);
-bool   process_dcbx_ctrl_tlv(struct port *);
-bool   process_dcbx_pg_tlv(struct port *);
-bool   process_dcbx_pfc_tlv(struct port *);
-bool   process_dcbx_app_tlv(struct port *, int);
-bool   process_dcbx_llink_tlv(struct port *);
+bool   unpack_dcbx1_tlvs(struct port *, struct lldp_agent *, struct unpacked_tlv *);
+bool   unpack_dcbx2_tlvs(struct port *, struct lldp_agent *, struct unpacked_tlv *);
+bool   process_dcbx_ctrl_tlv(struct port *, struct lldp_agent *);
+bool   process_dcbx_pg_tlv(struct port *, struct lldp_agent *);
+bool   process_dcbx_pfc_tlv(struct port *, struct lldp_agent *);
+bool   process_dcbx_app_tlv(struct port *, struct lldp_agent *, int);
+bool   process_dcbx_llink_tlv(struct port *, struct lldp_agent *);
 
 #ifdef __cplusplus
 }
diff --git a/lldp/agent.c b/lldp/agent.c
index 8e6572b..65aa809 100644
--- a/lldp/agent.c
+++ b/lldp/agent.c
@@ -25,7 +25,6 @@
 *******************************************************************************/
 
 #include <stdlib.h>
-#include "agent.h"
 #include "ports.h"
 #include "eloop.h"
 #include "states.h"
@@ -33,24 +32,153 @@
 #include "messages.h"
 #include "lldp/l2_packet.h"
 #include "lldp_mod.h"
+#include "config.h"
+#include "lldp_mand_clif.h"
+
+struct lldp_agent *lldp_agent_find_by_type(const char *ifname, int type)
+{
+	struct port *port;
+	struct lldp_agent *agent;
+
+	port = port_find_by_name(ifname);
+
+	if (port == NULL)
+		return NULL;
+
+	LIST_FOREACH(agent, &port->agent_head, entry) {
+		if (agent->type == type)
+			return agent;
+	}
+
+	return NULL;
+}
+
+void lldp_init_agent(struct port *port, struct lldp_agent *agent, int type)
+{
+	char macstring[30];
+
+	memset(agent, 0, sizeof(struct lldp_agent));
+
+	memcpy(&agent->mac_addr, groupmacs[type], ETH_ALEN);
+
+	mac2str(agent->mac_addr, macstring, 30);
+	LLDPAD_DBG("%s: creating new agent for %s (%s).\n", __func__,
+		   port->ifname, macstring);
+
+	/* Initialize relevant agent variables */
+	agent->tx.state  = TX_LLDP_INITIALIZE;
+	agent->rx.state = LLDP_WAIT_PORT_OPERATIONAL;
+	agent->type = type;
+
+	if (get_config_setting_by_agent(port->ifname, type, ARG_ADMINSTATUS,
+			(void *)&agent->adminStatus, CONFIG_TYPE_INT)) {
+		LLDPAD_DBG("%s: agent->adminStatus = disabled.\n", __func__);
+		agent->adminStatus = disabled;
+	}
+
+	/* init & enable RX path */
+	rxInitializeLLDP(port, agent);
+
+	/* init TX path */
+	txInitializeTimers(agent);
+	txInitializeLLDP(agent);
+}
+
+int lldp_add_agent(char *ifname, int type)
+{
+	int count;
+	struct port *port;
+	struct lldp_agent *agent, *newagent;
+
+	port = port_find_by_name(ifname);
+
+	if (port == NULL)
+		return -1;
+
+	/* check if lldp_agents for this if already exist */
+	LIST_FOREACH(agent, &port->agent_head, entry) {
+		if (agent->type != type)
+			continue;
+		else
+			return -1;
+	}
+
+	/* if not, create one and initialize it */
+	LLDPAD_DBG("%s(%i): creating new agent for port %s.\n", __func__,
+		   __LINE__, ifname);
+	newagent  = (struct lldp_agent *)malloc(sizeof(struct lldp_agent));
+	if (newagent == NULL) {
+		LLDPAD_DBG("%s(%i): creation of new agent failed !.\n",
+			   __func__,  __LINE__);
+		return -1;
+	}
+
+	lldp_init_agent(port, newagent, type);
+
+	if (get_config_setting_by_agent(ifname, newagent->type, ARG_ADMINSTATUS,
+			(void *)&newagent->adminStatus, CONFIG_TYPE_INT))
+			newagent->adminStatus = disabled;
+
+	LLDPAD_DBG("%s(%i): agent->adminStatus = %s (%i).\n", __func__,
+		   __LINE__, (newagent->adminStatus == disabled) ? "disabled" : "enabled",
+		   newagent->adminStatus);
+
+	LIST_INSERT_HEAD(&port->agent_head, newagent, entry);
+
+	count = 0;
+	LIST_FOREACH(agent, &port->agent_head, entry) {
+		count++;
+	}
+
+	LLDPAD_DBG("%s: %i agents on if %s.\n", __func__, count, port->ifname);
+
+	return 0;
+}
+
+int lldp_remove_agent(char *ifname, int type)
+{
+	struct lldp_agent *agent;
+
+	agent = lldp_agent_find_by_type(ifname, type);
+
+	if (agent == NULL)
+		return 0;
+
+	LIST_REMOVE(agent, entry);
+
+	free(agent);
+
+	return 0;
+}
 
 static void timer(void *eloop_data, void *user_ctx)
 {
-	struct port *port = porthead;
 	struct lldp_module *n;
+	struct lldp_agent *agent;
+	struct port *port = porthead;
 
 	while (port != NULL) {
-		update_tx_timers(port);
-		run_tx_timers_sm(port);
-		run_tx_sm(port);
-		run_rx_sm(port);
-		update_rx_timers(port);
+		/* execute rx and tx sm for all agents on a port */
+		LIST_FOREACH(agent, &port->agent_head, entry) {
+			char macstring[30];
+			mac2str(&agent->mac_addr[0], macstring, 29);
+
+			update_tx_timers(agent);
+			run_tx_timers_sm(port, agent);
+			run_tx_sm(port, agent);
+			run_rx_sm(port, agent);
+			update_rx_timers(agent);
+
 		LIST_FOREACH(n, &lldp_head, lldp) {
 			if (n->ops && n->ops->timer)
-				n->ops->timer(port);
+				n->ops->timer(port, agent);
+		}
+
 		}
-		if (port->timers.dormantDelay)
-			port->timers.dormantDelay--;
+
+		if (port->dormantDelay)
+			port->dormantDelay--;
+
 		port = port->next;
 	};
 
@@ -58,26 +186,29 @@ static void timer(void *eloop_data, void *user_ctx)
 	eloop_register_timeout(1, 0, timer, NULL, NULL);
 }
 
-int start_lldp_agent(void)
+int start_lldp_agents(void)
 {
 	eloop_register_timeout(1, 0, timer, NULL, NULL);
 	return 1;
 }
 
-void stop_lldp_agent(void)
+void stop_lldp_agents(void)
 {
 	eloop_cancel_timeout(timer, NULL, NULL);
 }
 
-void clean_lldp_agent(void)
+void clean_lldp_agents(void)
 {
 	struct port *port = porthead;
+	struct lldp_agent *agent;
 
 	while (port != NULL) {
 		if (port_needs_shutdown(port)) {
 			LLDPAD_DBG("Send shutdown frame on port %s\n",
 				port->ifname);
-			process_tx_shutdown_frame(port);
+			LIST_FOREACH(agent, &port->agent_head, entry) {
+				process_tx_shutdown_frame(port, agent);
+			}
 		} else {
 			LLDPAD_DBG("No shutdown frame is sent on port %s\n",
 				port->ifname);
diff --git a/lldp/agent.h b/lldp/agent.h
index 96c6bef..27d2d1c 100644
--- a/lldp/agent.h
+++ b/lldp/agent.h
@@ -27,8 +27,145 @@
 #ifndef AGENT_H
 #define AGENT_H
 
-int start_lldp_agent(void);
-void stop_lldp_agent(void);
-void clean_lldp_agent(void);
+#include "lldp.h"
+#include "mibdata.h"
+
+#ifndef ETH_ALEN
+#define ETH_ALEN    6
+#endif
+#ifndef IFNAMSIZ
+#define IFNAMSIZ    16  /* must match MAX_DEVICE_NAME_LEN */
+#endif
+#ifndef ETH_P_ALL
+#define ETH_P_ALL   0x0003
+#endif
+
+enum agent_type {
+	NEAREST_BRIDGE = 0,
+	NEAREST_NONTPMR_BRIDGE,
+	NEAREST_CUSTOMER_BRIDGE,
+	AGENT_MAX,
+};
+
+/* IEEE 802.1AB-2009 - Table 7-1: group MAC addresses used by LLDP */
+static const u8 nearest_bridge[ETH_ALEN] = {0x01,0x80,0xc2,0x00,0x00,0x0e};
+static const u8 nearest_nontpmr_bridge[ETH_ALEN] = {0x01,0x80,0xc2,0x00,0x00,0x03};
+static const u8 nearest_customer_bridge[ETH_ALEN] = {0x01,0x80,0xc2,0x00,0x00,0x00};
+
+static const u8 groupmacs[AGENT_MAX][ETH_ALEN] = {
+	[NEAREST_BRIDGE] = {0x01,0x80,0xc2,0x00,0x00,0x0e},
+	[NEAREST_NONTPMR_BRIDGE] = {0x01,0x80,0xc2,0x00,0x00,0x03},
+	[NEAREST_CUSTOMER_BRIDGE] = {0x01,0x80,0xc2,0x00,0x00,0x00},
+};
+
+struct agenttimers {
+/* Tx */
+	u16 state;
+	u16 reinitDelay;
+	u16 msgTxHold;
+	u16 msgTxInterval;
+	u16 msgFastTx;
+	u16 txFastInit;
+	u16 txTTR;
+	u16 txShutdownWhile;
+	u16 txCredit;
+	u16 txMaxCredit;
+	bool txTick;
+/* Rx */
+	u16 tooManyNghbrsTimer;
+	u16 rxTTL;
+	u16 lastrxTTL;  /* cache last received */
+};
+
+struct agenttx {
+	u8 *frameout;
+	u32 sizeout;
+	u8 state;
+	u8 localChange;
+	u16 txTTL;
+	bool txNow;
+	u16 txFast;
+};
+
+/* per agent statistical counter as in chapter 9.2.6
+ * of IEEE 802.1AB-2009 */
+struct agentstats {
+/* Tx */
+	u32 statsFramesOutTotal;
+/* Rx */
+	u32 statsAgeoutsTotal;
+	u32 statsFramesDiscardedTotal;
+	u32 statsFramesInErrorsTotal;
+	u32 statsFramesInTotal;
+	u32 statsTLVsDiscardedTotal;
+	u32 statsTLVsUnrecognizedTotal;
+};
+
+typedef struct rxmanifest{
+	struct unpacked_tlv *chassis;
+	struct unpacked_tlv *portid;
+	struct unpacked_tlv *ttl;
+	struct unpacked_tlv *portdesc;
+	struct unpacked_tlv *sysname;
+	struct unpacked_tlv *sysdesc;
+	struct unpacked_tlv *syscap;
+	struct unpacked_tlv *mgmtadd;
+}rxmanifest;
+
+struct agentrx {
+	u8 *framein;
+	u16 sizein;
+	u8 state;
+	u8 badFrame;
+	u8 rcvFrame;
+	u8 rxInfoAge;
+	u8 remoteChange;
+	u8 tooManyNghbrs;
+	u8 dupTlvs;
+	u8 dcbx_st;
+	bool newNeighbor;
+	rxmanifest *manifest;
+};
+
+enum agentAdminStatus {
+	disabled,
+	enabledTxOnly,
+	enabledRxOnly,
+	enabledRxTx,
+};
+
+/* lldp agent specific structure as in chapter 9.2.5
+ * of IEEE 802.1AB-2009 */
+struct lldp_agent {
+	int	adminStatus;
+
+	int	pad;
+
+	u8	mac_addr[ETH_ALEN];
+
+	struct	agentrx rx;
+	struct	agenttx tx;
+	struct	agentstats stats;
+	struct	agenttimers timers;
+	u8	rxChanges;
+	u16	lldpdu;
+	struct	msap msap;
+
+	enum	agent_type type;
+
+        LIST_ENTRY(lldp_agent) entry;
+};
+
+struct lldp_agent *lldp_agent_find_by_type(const char *, int);
+int lldp_add_agent(char *ifname, int type);
+int lldp_remove_agent(char *ifname, int type);
+
+void set_lldp_agent_admin(const char *ifname, int type, int enable);
+int get_lldp_agent_admin(const char *ifname, int type);
+int get_lldp_agent_statistics(char *ifname, struct agentstats *, int);
+
+int start_lldp_agents(void);
+void stop_lldp_agents(void);
+void clean_lldp_agents(void);
 
 #endif /* AGENT_H */
diff --git a/lldp/l2_packet.h b/lldp/l2_packet.h
index 763b3f6..c1428ad 100644
--- a/lldp/l2_packet.h
+++ b/lldp/l2_packet.h
@@ -60,11 +60,6 @@
 #define ETH_MIN_PKT_LEN     (ETH_MIN_DATA_LEN + ETH_HDR_LEN)
 #endif
 
-#define LLDP_MULTICAST_MAC 0x0180c200000e
-
-
-static const u8 multi_cast_source[ETH_ALEN] = {0x01,0x80,0xc2,0x00,0x00,0x0e};
-
 /**
  * struct l2_packet_data - Internal l2_packet data structure
  *
@@ -129,7 +124,7 @@ int l2_packet_get_own_src_addr(struct l2_packet_data *l2, u8 *addr);
  */
 int l2_packet_get_own_addr(struct l2_packet_data *l2, u8 *addr);
 
-void get_remote_peer_mac_addr(struct port *port);
+void get_remote_peer_mac_addr(struct port *port, struct lldp_agent *);
 void l2_packet_get_remote_addr(struct l2_packet_data *l2, u8 *addr);
 
 /**
@@ -149,7 +144,7 @@ int l2_packet_send(struct l2_packet_data *l2, const u8 *dst_addr, u16 proto,
 
 void l2_packet_get_port_state(struct l2_packet_data *, u8 *);
 
-int add_bond_port(const char *ifname);
+struct port * add_bond_port(const char *ifname);
 int remove_bond_port(const char *ifname);
 void recv_on_bond(void *ctx, unsigned int ifindex, const u8 *buf, size_t len);
 void remove_all_bond_ports(void);
diff --git a/lldp/l2_packet_linux.c b/lldp/l2_packet_linux.c
index 6e99c26..f94cd31 100644
--- a/lldp/l2_packet_linux.c
+++ b/lldp/l2_packet_linux.c
@@ -85,10 +85,10 @@ int l2_packet_get_own_src_addr(struct l2_packet_data *l2, u8 *addr)
  * Extracts the remote peer's MAC address from the rx frame  and
  * puts it in the l2_packet_data
  */
-void get_remote_peer_mac_addr(struct port *port)
+void get_remote_peer_mac_addr(struct port *port, struct lldp_agent *agent)
 {
 	int offset = ETH_ALEN;  /* points to remote MAC address in RX frame */
-	memcpy(port->l2->remote_mac_addr, &port->rx.framein[offset], ETH_ALEN);
+	memcpy(port->l2->remote_mac_addr, &agent->rx.framein[offset], ETH_ALEN);
 }
 
 void l2_packet_get_remote_addr(struct l2_packet_data *l2, u8 *addr)
@@ -219,7 +219,7 @@ struct l2_packet_data * l2_packet_init(
 	memset(&mr, 0, sizeof(mr));
 	mr.mr_ifindex = l2->ifindex;
 	mr.mr_alen = ETH_ALEN;
-	memcpy(mr.mr_address, multi_cast_source, ETH_ALEN);
+	memcpy(mr.mr_address, &nearest_bridge, ETH_ALEN);
 	mr.mr_type = PACKET_MR_MULTICAST;
 	if (setsockopt(l2->fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr,
 		sizeof(mr)) < 0) {
@@ -296,7 +296,7 @@ void l2_packet_get_port_state(struct l2_packet_data *l2, u8  *portEnabled)
 }
 
 
-int add_bond_port(const char *ifname)
+struct port *add_bond_port(const char *ifname)
 {
 	struct port *bond_newport;
 
@@ -304,14 +304,14 @@ int add_bond_port(const char *ifname)
 	while (bond_newport != NULL) {
 		if(!strncmp(ifname, bond_newport->ifname,
 			MAX_DEVICE_NAME_LEN))
-			return 0;
+			return bond_newport;
 		bond_newport = bond_newport->next;
 	}
 
 	bond_newport  = (struct port *)malloc(sizeof(struct port));
 	if (bond_newport == NULL) {
 		syslog(LOG_ERR, "failed to malloc bond port %s", ifname);
-		return -1;
+		return NULL;
 	}
 	memset(bond_newport,0,sizeof(struct port));	
 	bond_newport->next = NULL;
@@ -334,7 +334,7 @@ int add_bond_port(const char *ifname)
 		bond_newport->next = bond_porthead;
 	bond_porthead = bond_newport;
 
-	return 0;
+	return bond_newport;
 
 fail2:
 	free(bond_newport->ifname);
@@ -342,7 +342,7 @@ fail2:
 fail1:
 	free(bond_newport);
 	bond_newport = NULL;
-	return -1;
+	return NULL;
 }
 
 
diff --git a/lldp/ports.c b/lldp/ports.c
index 925a2ad..fbb880d 100644
--- a/lldp/ports.c
+++ b/lldp/ports.c
@@ -28,6 +28,7 @@
 #include <string.h>
 #include "states.h"
 #include "lldp_tlv.h"
+#include "lldp_rtnl.h"
 #include "ports.h"
 #include "l2_packet.h"
 #include "libconfig.h"
@@ -38,87 +39,91 @@
 #include "clif_msgs.h"
 #include "lldp_rtnl.h"
 #include "lldp_dcbx_nl.h"
+#include "agent.h"
 
-struct port *porthead = NULL; /* Head pointer */
-struct port *portcurrent = NULL; /* Working  pointer loaded from ports or
-				  * port->next */
+struct port *porthead = NULL; /* port Head pointer */
 
 void agent_receive(void *, const u8 *, const u8 *, size_t);
 
 /* Port routines used for command processing -- return cmd_xxx codes */
 
-int get_lldp_port_statistics(char *ifname, struct portstats *stats)
+int get_lldp_agent_statistics(char *ifname, struct agentstats *stats, int type)
 {
-	struct port *port;
+	struct lldp_agent *agent;
 
-	port = port_find_by_name(ifname);
-	if (!port)
-		return cmd_device_not_found;
-	memcpy((void *)stats, (void *)&port->stats, sizeof(struct portstats));
-	return cmd_success;
+	agent = lldp_agent_find_by_type(ifname, type);
+	if (!agent)
+		return cmd_agent_not_found;
+
+	memcpy((void *)stats, (void *)&agent->stats, sizeof(struct agentstats));
+
+	return 0;
 }
 
-int get_local_tlvs(char *ifname, unsigned char *tlvs, int *size)
+int get_local_tlvs(char *ifname, int type, unsigned char *tlvs, int *size)
 {
-	struct port *port;
+	struct lldp_agent *agent;
 
-	port = port_find_by_name(ifname);
-	if (!port)
-		return cmd_device_not_found;
+	agent = lldp_agent_find_by_type(ifname, type);
+	if (!agent)
+		return cmd_agent_not_found;
 
-	if (port->tx.frameout == NULL) {
+	if (agent->tx.frameout == NULL) {
 		*size = 0;
 		return cmd_success;
 	}
 
-	*size = port->tx.sizeout - sizeof(struct l2_ethhdr);
+	*size = agent->tx.sizeout - sizeof(struct l2_ethhdr);
 	if (*size < 0)
 		return cmd_invalid;
 	memcpy((void *)tlvs,
-	       (void *)port->tx.frameout + sizeof(struct l2_ethhdr), *size);
+	       (void *)agent->tx.frameout + sizeof(struct l2_ethhdr), *size);
 
 	return cmd_success;
 }
 
-int get_neighbor_tlvs(char *ifname, unsigned char *tlvs, int *size)
+int get_neighbor_tlvs(char *ifname, int type, unsigned char *tlvs, int *size)
 {
-	struct port *port;
+	struct lldp_agent *agent;
 
-	port = port_find_by_name(ifname);
-	if (!port)
-		return cmd_device_not_found;
+	agent = lldp_agent_find_by_type(ifname, type);
+	if (!agent)
+		return cmd_agent_not_found;
 
-	if (port->rx.framein == NULL) {
+	if (agent->rx.framein == NULL) {
 		*size = 0;
 		return cmd_success;
 	}
 
-	*size = port->rx.sizein - sizeof(struct l2_ethhdr);
+	*size = agent->rx.sizein - sizeof(struct l2_ethhdr);
+
 	if (*size < 0)
 		return cmd_invalid;
+
 	memcpy((void *)tlvs,
-	       (void *)port->rx.framein + sizeof(struct l2_ethhdr), *size);
+	       (void *)agent->rx.framein + sizeof(struct l2_ethhdr), *size);
+
 	return cmd_success;
 }
 
 /* Routines used for managing interfaces -- return std C return values */
 
-int get_lldp_port_admin(const char *ifname)
+int get_lldp_agent_admin(const char *ifname, int type)
 {
-	struct port *port = NULL;
+	struct lldp_agent *agent = NULL;
 
-	port = porthead;
-	while (port != NULL) {
-		if (!strncmp(ifname, port->ifname, IFNAMSIZ))
-			return port->adminStatus;
-		port = port->next;
-	}
-	return disabled;
+	agent = lldp_agent_find_by_type(ifname, type);
+
+	if (agent == NULL)
+		return disabled;
+
+	return agent->adminStatus;
 }
 
-void set_lldp_port_admin(const char *ifname, int admin)
+void set_lldp_agent_admin(const char *ifname, int type, int admin)
 {
 	struct port *port = NULL;
+	struct lldp_agent *agent;
 	int all = 0;
 	int tmp;
 
@@ -138,11 +143,15 @@ void set_lldp_port_admin(const char *ifname, int admin)
 				continue;
 			}
 
-			if (port->adminStatus != admin) {
-				port->adminStatus = admin;
-				somethingChangedLocal(ifname);
-				run_tx_sm(port);
-				run_rx_sm(port);
+			agent = lldp_agent_find_by_type(port->ifname, type);
+			if (agent == NULL)
+				continue;
+
+			if (agent->adminStatus != admin) {
+				agent->adminStatus = admin;
+				somethingChangedLocal(ifname, type);
+				run_tx_sm(port, agent);
+				run_rx_sm(port, agent);
 			}
 
 			if (!all)
@@ -152,45 +161,39 @@ void set_lldp_port_admin(const char *ifname, int admin)
 	}
 }
 
-void set_lldp_port_enable_state(const char *ifname, int enable)
+void set_lldp_port_enable(const char *ifname, int enable)
 {
 	struct port *port = NULL;
+	struct lldp_agent *agent = NULL;
 
-	port = porthead;
-	while (port != NULL) {
-		if (!strncmp(ifname, port->ifname, IFNAMSIZ))
-			break;
-		port = port->next;
-	}
+	port = port_find_by_name(ifname);
 
-	if (port == NULL) {
+	if (port == NULL)
 		return;
-	}
 
 	port->portEnabled = (u8)enable;
 
-	if (!enable) /* port->adminStatus = disabled; */
-		port->rx.rxInfoAge = false;
+	if (!enable) { /* port->adminStatus = disabled; */
+		LIST_FOREACH(agent, &port->agent_head, entry) {
+			agent->rx.rxInfoAge = false;
+		}
+	}
 
-	run_tx_sm(port);
-	run_rx_sm(port);
+	LIST_FOREACH(agent, &port->agent_head, entry) {
+		run_tx_sm(port, agent);
+		run_rx_sm(port, agent);
+	}
 }
 
 void set_port_oper_delay(const char *ifname)
 {
-	struct port *port = NULL;
-
-	port = porthead;
-	while (port != NULL) {
-		if (!strncmp(ifname, port->ifname, IFNAMSIZ))
-			break;
-		port = port->next;
-	}
+	struct port *port = port_find_by_name(ifname);
 
 	if (port == NULL)
 		return;
 
-	port->timers.dormantDelay = DORMANT_DELAY;
+	port->dormantDelay = DORMANT_DELAY;
+
 	return;
 }
 
@@ -198,13 +201,7 @@ int set_port_hw_resetting(const char *ifname, int resetting)
 {
 	struct port *port = NULL;
 
-	port = porthead;
-	while (port != NULL) {
-		if (!strncmp(ifname, port->ifname, IFNAMSIZ)) {
-			break;
-		}
-		port = port->next;
-	}
+	port = port_find_by_name(ifname);
 
 	if (port == NULL)
 		return -1;
@@ -218,12 +215,7 @@ int get_port_hw_resetting(const char *ifname)
 {
 	struct port *port = NULL;
 
-	port = porthead;
-	while (port != NULL) {
-		if (!strncmp(ifname, port->ifname, IFNAMSIZ))
-			break;
-		port = port->next;
-	}
+	port = port_find_by_name(ifname);
 
 	if (port)
 		return port->hw_resetting;
@@ -233,43 +225,45 @@ int get_port_hw_resetting(const char *ifname)
 
 int reinit_port(const char *ifname)
 {
+	struct lldp_agent *agent;
 	struct port *port;
 
-	port = porthead;
-	while (port != NULL) {
-		if (!strncmp(ifname, port->ifname, IFNAMSIZ))
-			break;
-		port = port->next;
-	}
+	port = port_find_by_name(ifname);
 
-	if (!port)
+	if (port == NULL)
 		return -1;
 
 	/* Reset relevant port variables */
-	port->tx.state  = TX_LLDP_INITIALIZE;
-	port->timers.state  = TX_TIMER_BEGIN;
-	port->rx.state = LLDP_WAIT_PORT_OPERATIONAL;
 	port->hw_resetting = false;
 	port->portEnabled = false;
-	port->tx.txTTL = 0;
-	port->msap.length1 = 0;
-	port->msap.msap1 = NULL;
-	port->msap.length2 = 0;
-	port->msap.msap2 = NULL;
-	port->lldpdu = false;
-	port->timers.dormantDelay = DORMANT_DELAY;
-
-	/* init & enable RX path */
-	rxInitializeLLDP(port);
-
-	/* init TX path */
-	txInitializeTimers(port);
-	txInitializeLLDP(port);
+	port->dormantDelay = DORMANT_DELAY;
+
+	LIST_FOREACH(agent, &port->agent_head, entry) {
+		/* init TX path */
+
+		/* Reset relevant state variables */
+		agent->tx.state  = TX_LLDP_INITIALIZE;
+		agent->rx.state = LLDP_WAIT_PORT_OPERATIONAL;
+		agent->tx.txTTL = 0;
+		agent->msap.length1 = 0;
+		agent->msap.msap1 = NULL;
+		agent->msap.length2 = 0;
+		agent->msap.msap2 = NULL;
+		agent->lldpdu = false;
+		agent->timers.state  = TX_TIMER_BEGIN;
+
+		/* init & enable RX path */
+		rxInitializeLLDP(port, agent);
+
+		/* init TX path */
+		txInitializeTimers(agent);
+		txInitializeLLDP(agent);
+	}
 
 	return 0;
 }
 
-int add_port(const char *ifname)
+struct port *add_port(const char *ifname)
 {
 	struct port *newport;
 
@@ -294,26 +288,11 @@ int add_port(const char *ifname)
 	}
 
 	/* Initialize relevant port variables */
-	newport->tx.state  = TX_LLDP_INITIALIZE;
-	newport->timers.state = TX_TIMER_BEGIN;
-	newport->rx.state = LLDP_WAIT_PORT_OPERATIONAL;
 	newport->hw_resetting = false;
 	newport->portEnabled = false;
 
-	if (get_config_setting(newport->ifname, ARG_ADMINSTATUS,
-			(void *)&newport->adminStatus, CONFIG_TYPE_INT))
-			newport->adminStatus = disabled;
-
-	newport->tx.txTTL = 0;
-	newport->msap.length1 = 0;
-	newport->msap.msap1 = NULL;
-	newport->msap.length2 = 0;
-	newport->msap.msap2 = NULL;
-	newport->lldpdu = false;
-	newport->timers.dormantDelay = DORMANT_DELAY;
+	LIST_INIT(&newport->agent_head);
 
-	/* init & enable RX path */
-	rxInitializeLLDP(newport);
 	newport->l2 = l2_packet_init(newport->ifname, NULL, ETH_P_LLDP,
 		rxReceiveFrame, newport, 1);
 	if (newport->l2 == NULL) {
@@ -323,15 +302,14 @@ int add_port(const char *ifname)
 	}
 
 	/* init TX path */
-	txInitializeTimers(newport);
-	txInitializeLLDP(newport);
+	newport->dormantDelay = DORMANT_DELAY;
 
 	/* enable TX path */
 	if (porthead)
 		newport->next = porthead;
 
 	porthead = newport;
-	return 0;
+	return newport;
 
 fail:
 	if(newport) {
@@ -339,42 +317,59 @@ fail:
 			free(newport->ifname);
 		free(newport);
 	}
-	return -1;
+	return NULL;
 }
 
 int remove_port(const char *ifname)
 {
 	struct port *port = NULL;    /* Pointer to port to remove */
 	struct port *parent = NULL;  /* Pointer to previous on port stack */
+	struct lldp_agent *agent = NULL;
 
-	port = porthead;
-	while (port != NULL) {
-		if (!strncmp(ifname, port->ifname, IFNAMSIZ)) {
-			LLDPAD_DBG("In remove_port: Found port %s\n",port->ifname);
-			break;
-		}
-		parent = port;
-		port = port->next;
-	}
+	port = port_find_by_name(ifname);
 
 	if (port == NULL) {
 		LLDPAD_DBG("remove_port: port not present\n");
 		return -1;
 	}
 
+	LLDPAD_DBG("In remove_port: Found port %s\n", port->ifname);
+
 	/* Set linkmode to off */
 	set_linkmode(ifname, 0);
 
 	/* Close down the socket */
 	l2_packet_deinit(port->l2);
 
-	/* Re-initialize relevant port variables */
-	port->tx.state = TX_LLDP_INITIALIZE;
-	port->timers.state = TX_TIMER_BEGIN;
-	port->rx.state = LLDP_WAIT_PORT_OPERATIONAL;
 	port->portEnabled  = false;
-	port->adminStatus  = disabled;
-	port->tx.txTTL = 0;
+
+	LIST_FOREACH(agent, &port->agent_head, entry) {
+		/* Re-initialize relevant port variables */
+		agent->tx.state = TX_LLDP_INITIALIZE;
+		agent->rx.state = LLDP_WAIT_PORT_OPERATIONAL;
+		agent->timers.state = TX_TIMER_BEGIN;
+		agent->adminStatus  = disabled;
+		agent->tx.txTTL = 0;
+
+		/* Remove the tlvs */
+		if (agent->msap.msap1) {
+			free(agent->msap.msap1);
+			agent->msap.msap1 = NULL;
+		}
+
+		if (agent->msap.msap2) {
+			free(agent->msap.msap2);
+			agent->msap.msap2 = NULL;
+		}
+
+		if (agent->rx.framein)
+			free(agent->rx.framein);
+
+		if (agent->tx.frameout)
+			free(agent->tx.frameout);
+
+		lldp_remove_agent(port->ifname, agent->type);
+	}
 
 	/* Take this port out of the chain */
 	if (parent == NULL)
@@ -384,27 +379,11 @@ int remove_port(const char *ifname)
 	else
 		return -1;
 
-	/* Remove the tlvs */
-	if (port->msap.msap1) {
-		free(port->msap.msap1);
-		port->msap.msap1 = NULL;
-	}
-
-	if (port->msap.msap2) {
-		free(port->msap.msap2);
-		port->msap.msap2 = NULL;
-	}
-
-	if (port->rx.framein)
-		free(port->rx.framein);
-
-	if (port->tx.frameout)
-		free(port->tx.frameout);
-
 	if (port->ifname)
 		free(port->ifname);
 
 	free(port);
+
 	return 0;
 }
 
diff --git a/lldp/ports.h b/lldp/ports.h
index 9c244d8..845e40f 100644
--- a/lldp/ports.h
+++ b/lldp/ports.h
@@ -27,9 +27,10 @@
 #ifndef PORTS_H
 #define PORTS_H
 
+#include <sys/queue.h>
 #include <string.h>
 #include "lldp.h"
-#include "mibdata.h"
+#include "agent.h"
 
 #ifndef ETH_ALEN
 #define ETH_ALEN    6
@@ -60,70 +61,6 @@
 
 struct porttimers {
 	u16 dormantDelay;
-/* Tx */
-	u16 state;
-	u16 reinitDelay;
-	u16 msgTxHold;
-	u16 msgTxInterval;
-	u16 msgFastTx;
-	u16 txFastInit;
-	u16 txTTR;
-	u16 txShutdownWhile;
-	u16 txCredit;
-	u16 txMaxCredit;
-	bool txTick;
-/* Rx */
-	u16 tooManyNghbrsTimer;
-	u16 rxTTL;
-	u16 lastrxTTL;  /* cache last received */
-};
-
-struct porttx {
-	u8 *frameout;
-	u32 sizeout;
-	u8 state;
-	u8 localChange;
-	u16 txTTL;
-	bool txNow;
-	u16 txFast;
-};
-
-struct portstats {
-/* Tx */
-	u32 statsFramesOutTotal;
-/* Rx */
-	u32 statsAgeoutsTotal;
-	u32 statsFramesDiscardedTotal;
-	u32 statsFramesInErrorsTotal;
-	u32 statsFramesInTotal;
-	u32 statsTLVsDiscardedTotal;
-	u32 statsTLVsUnrecognizedTotal;
-};
-
-typedef struct rxmanifest{
-	struct unpacked_tlv *chassis;
-	struct unpacked_tlv *portid;
-	struct unpacked_tlv *ttl;
-	struct unpacked_tlv *portdesc;
-	struct unpacked_tlv *sysname;
-	struct unpacked_tlv *sysdesc;
-	struct unpacked_tlv *syscap;
-	struct unpacked_tlv *mgmtadd;
-}rxmanifest;
-
-struct portrx {
-	u8 *framein;
-	u16 sizein;
-	u8 state;
-	u8 badFrame;
-	u8 rcvFrame;
-	u8 rxInfoAge;
-	u8 remoteChange;
-	u8 tooManyNghbrs;
-	u8 dupTlvs;
-	u8 dcbx_st;
-	bool newNeighbor;
-	rxmanifest *manifest;
 };
 
 struct eth_hdr {
@@ -132,64 +69,54 @@ struct eth_hdr {
 	u16 ethertype;
 };
 
-enum portAdminStatus {
-	disabled,
-	enabledTxOnly,
-	enabledRxOnly,
-	enabledRxTx,
+enum portEnableStatus {
+	no = 0,
+	yes,
 };
 
+/* lldp port specific structure */
 struct port {
 	char *ifname;
 	u8 hw_resetting;
 	u8 portEnabled;
 	u8 prevPortEnabled;
-	u8 adminStatus;
+	struct porttimers *timers;
 
-	/* protocol specific */
+	u16 dormantDelay;
+
+	LIST_HEAD(agent_head, lldp_agent) agent_head;
 	struct l2_packet_data *l2;
-	struct portrx rx;
-	struct porttx tx;
-	struct portstats stats;
-	struct porttimers timers;
-	u8 rxChanges;
-	u16   lldpdu;
-	struct msap msap;
 
 	struct port *next;
 };
 
 extern struct port *porthead;
-extern struct port *portcurrent;
-extern struct port *porttail;
 
 #ifdef __cplusplus
 extern "C" {
 #endif
-int add_port(const char *);
+struct port *add_port(const char *);
 int remove_port(const char *);
 #ifdef __cplusplus
 }
 #endif
 int set_port_hw_resetting(const char *ifname, int resetting);
 int get_port_hw_resetting(const char *ifname);
-void set_lldp_port_enable_state(const char *ifname, int enable);
-void set_lldp_port_admin(const char *ifname, int enable);
-int get_lldp_port_admin(const char *ifname);
-
-int get_lldp_port_statistics(char *ifname, struct portstats *stats);
+void set_lldp_port_enable(const char *ifname, int enable);
 
-int get_local_tlvs(char *ifname, unsigned char *tlvs, int *size);
-int get_neighbor_tlvs(char *ifname, unsigned char *tlvs, int *size);
+int get_local_tlvs(char *ifname, int type, unsigned char *tlvs, int *size);
+int get_neighbor_tlvs(char *ifname, int type, unsigned char *tlvs, int *size);
 
 int port_needs_shutdown(struct port *port);
 
 void set_port_operstate(const char *ifname, int operstate);
 int get_port_operstate(const char *ifname);
 
-int reinit_port(const char *ifname);
 void set_port_oper_delay(const char *ifname);
 
+int reinit_port(const char *ifname);
+void set_agent_oper_delay(const char *ifname, int type);
+
 static inline struct port *port_find_by_name(const char *ifname)
 {
 	struct port *port = porthead;
@@ -201,4 +128,5 @@ static inline struct port *port_find_by_name(const char *ifname)
 	}
 	return NULL;
 }
+
 #endif /* PORTS_H */
diff --git a/lldp/rx.c b/lldp/rx.c
index bbb2e2f..0606589 100644
--- a/lldp/rx.c
+++ b/lldp/rx.c
@@ -39,27 +39,28 @@
 #include "clif_msgs.h"
 #include "lldp_mand.h"
 #include "lldp_tlv.h"
+#include "agent.h"
 
-void rxInitializeLLDP(struct port *port)
+void rxInitializeLLDP(struct port *port, struct lldp_agent *agent)
 {
-
-	port->rx.rcvFrame = false;
-	port->rx.badFrame = false;
-	port->rx.tooManyNghbrs = false;
-	port->rx.rxInfoAge = false;
-	if (port->rx.framein) {
-		free(port->rx.framein);
-		port->rx.framein = NULL;
+	agent->rx.rcvFrame = false;
+	agent->rx.badFrame = false;
+	agent->rx.tooManyNghbrs = false;
+	agent->rx.rxInfoAge = false;
+	if (agent->rx.framein) {
+		free(agent->rx.framein);
+		agent->rx.framein = NULL;
 	}
-	port->rx.sizein = 0;
+	agent->rx.sizein = 0;
 
-	mibDeleteObjects(port);
+	mibDeleteObjects(port, agent);
 	return;
 }
 
 void rxReceiveFrame(void *ctx, unsigned int ifindex, const u8 *buf, size_t len)
 {
 	struct port * port;
+	struct lldp_agent *agent;
 	u8  frame_error = 0;
 	struct l2_ethhdr *hdr;
 	struct l2_ethhdr example_hdr,*ex;
@@ -67,64 +68,63 @@ void rxReceiveFrame(void *ctx, unsigned int ifindex, const u8 *buf, size_t len)
 
 	port = (struct port *)ctx;
 
-	if (port->adminStatus == disabled || port->adminStatus == enabledTxOnly)
-		return;
-
-	if (port->rx.framein &&
-	    port->rx.sizein == len &&
-	    (memcmp(buf, port->rx.framein, len) == 0)) {
-		port->timers.rxTTL = port->timers.lastrxTTL;
-		port->stats.statsFramesInTotal++;
-		return;
-	}
-
 	snprintf(msg, sizeof(msg), "%i", LLDP_RCHANGE);
 	send_event(MSG_EVENT, LLDP_MOD_MAND, msg);
 
-	if (port->rx.framein)
-		free(port->rx.framein);
+	/* walk through the list of agents for this interface and see if we
+	 * can find a matching agent */
+	LIST_FOREACH(agent, &port->agent_head, entry) {
+		if (agent->rx.framein &&
+		    agent->rx.sizein == len &&
+		    (memcmp(buf, agent->rx.framein, len) == 0)) {
+			agent->timers.rxTTL = agent->timers.lastrxTTL;
+			agent->stats.statsFramesInTotal++;
+			return;
+		}
 
-	port->rx.framein = (u8 *)malloc(len);
-	if (port->rx.framein == NULL) {
-		LLDPAD_DBG("ERROR - could not allocate memory for rx'ed frame\n");
-		return;
+		ex = &example_hdr;
+		memcpy(ex->h_dest, agent->mac_addr, ETH_ALEN);
+		ex->h_proto = htons(ETH_P_LLDP);
+		hdr = (struct l2_ethhdr *)buf;
+
+		if (hdr->h_proto != example_hdr.h_proto) {
+			LLDPAD_INFO("ERROR Ethertype not LLDP ethertype but ethertype "
+				"'%x' in incoming frame.\n", htons(hdr->h_proto));
+			frame_error++;
+			return;
+		}
+
+		if ((!memcmp(hdr->h_dest,ex->h_dest, ETH_ALEN)))
+			break;
 	}
-	memcpy(port->rx.framein, buf, len);
-
-	port->rx.sizein = (u16)len;
-	ex = &example_hdr;
-	memcpy(ex->h_dest, multi_cast_source, ETH_ALEN);
-	ex->h_proto = htons(ETH_P_LLDP);
-	hdr = (struct l2_ethhdr *)port->rx.framein;
-
-	if ((memcmp(hdr->h_dest,ex->h_dest, ETH_ALEN) != 0)) {
-		LLDPAD_INFO("ERROR LLDP multicast address error in incoming frame. "
-			"Dropping frame.\n");
-		frame_error++;
-		free(port->rx.framein);
-		port->rx.framein = NULL;
-		port->rx.sizein = 0;
+
+	if (agent == NULL)
 		return;
-	}
 
-	if (hdr->h_proto != example_hdr.h_proto) {
-		LLDPAD_INFO("ERROR Ethertype not LLDP ethertype but ethertype "
-			"'%x' in incoming frame.\n", htons(hdr->h_proto));
-		frame_error++;
-		free(port->rx.framein);
-		port->rx.framein = NULL;
-		port->rx.sizein = 0;
+	if (agent->adminStatus == disabled || agent->adminStatus == enabledTxOnly)
+		return;
+
+	if (agent->rx.framein)
+		free(agent->rx.framein);
+
+	agent->rx.sizein = (u16)len;
+	agent->rx.framein = (u8 *)malloc(len);
+
+	if (agent->rx.framein == NULL) {
+		LLDPAD_DBG("ERROR - could not allocate memory for rx'ed frame\n");
 		return;
 	}
+	memcpy(agent->rx.framein, buf, len);
 
 	if (!frame_error) {
-		port->stats.statsFramesInTotal++;
-		port->rx.rcvFrame = 1;
+		agent->stats.statsFramesInTotal++;
+		agent->rx.rcvFrame = 1;
 	}
-	run_rx_sm(port);
+
+	run_rx_sm(port, agent);
 }
 
-void rxProcessFrame(struct port * port)
+void rxProcessFrame(struct port *port, struct lldp_agent *agent)
 {
 	u16 tlv_cnt = 0;
 	u8  tlv_type = 0;
@@ -139,30 +139,30 @@ void rxProcessFrame(struct port * port)
 	int err;
 	struct lldp_module *np;
 
-	assert(port->rx.framein && port->rx.sizein);
-	port->lldpdu = 0;
-	port->rx.dupTlvs = 0;
+	assert(agent->rx.framein && agent->rx.sizein);
+	agent->lldpdu = 0;
+	agent->rx.dupTlvs = 0;
 
-	port->rx.dcbx_st = 0;
-	port->rx.manifest = (rxmanifest *)malloc(sizeof(rxmanifest));
-	if (port->rx.manifest == NULL) {
+	agent->rx.dcbx_st = 0;
+	agent->rx.manifest = (rxmanifest *)malloc(sizeof(rxmanifest));
+	if (agent->rx.manifest == NULL) {
 		LLDPAD_DBG("ERROR - could not allocate memory for receive "
 			"manifest\n");
 		return;
 	}
-	memset(port->rx.manifest,0, sizeof(rxmanifest));
-	get_remote_peer_mac_addr(port);
+	memset(agent->rx.manifest, 0, sizeof(rxmanifest));
+	get_remote_peer_mac_addr(port, agent);
 	tlv_offset = sizeof(struct l2_ethhdr);  /* Points to 1st TLV */
 
 	do {
 		tlv_cnt++;
-		if (tlv_offset > port->rx.sizein) {
+		if (tlv_offset > agent->rx.sizein) {
 			LLDPAD_INFO("ERROR: Frame overrun!\n");
 			frame_error++;
 			goto out;
 		}
 
-		tlv_head_ptr = (u16 *)&port->rx.framein[tlv_offset];
+		tlv_head_ptr = (u16 *)&agent->rx.framein[tlv_offset];
 		tlv_length = htons(*tlv_head_ptr) & 0x01FF;
 		tlv_type = (u8)(htons(*tlv_head_ptr) >> 9);
 
@@ -192,14 +192,14 @@ void rxProcessFrame(struct port * port)
 		}
 
 		u16 tmp_offset = tlv_offset + tlv_length;
-		if (tmp_offset > port->rx.sizein) {
+		if (tmp_offset > agent->rx.sizein) {
 			LLDPAD_INFO("ERROR: Frame overflow error: offset=%d, "
-				"rx.size=%d \n", tmp_offset, port->rx.sizein);
+				"rx.size=%d \n", tmp_offset, agent->rx.sizein);
 			frame_error++;
 			goto out;
 		}
 
-		u8 *info = (u8 *)&port->rx.framein[tlv_offset +
+		u8 *info = (u8 *)&agent->rx.framein[tlv_offset +
 					sizeof(*tlv_head_ptr)];
 
 		struct unpacked_tlv *tlv = create_tlv();
@@ -209,7 +209,7 @@ void rxProcessFrame(struct port * port)
 				"incoming TLV. \n");
 			goto out;
 		}
-	
+
 		if ((tlv_length == 0) && (tlv->type != TYPE_0)) {
 				LLDPAD_INFO("ERROR: tlv_length == 0\n");
 				free_unpkd_tlv(tlv);
@@ -232,64 +232,64 @@ void rxProcessFrame(struct port * port)
 		tlv_offset += sizeof(*tlv_head_ptr) + tlv_length;
 		/* Get MSAP info */
 		if (tlv->type == TYPE_1) { /* chassis ID */
-			if (port->lldpdu & RCVD_LLDP_TLV_TYPE1) {
+			if (agent->lldpdu & RCVD_LLDP_TLV_TYPE1) {
 				LLDPAD_INFO("Received multiple Chassis ID"
 					    "TLVs in this LLDPDU\n");
 				frame_error++;
 				free_unpkd_tlv(tlv);
 				goto out;
 			} else {
-				port->lldpdu |= RCVD_LLDP_TLV_TYPE1;
-				port->rx.manifest->chassis = tlv;
+				agent->lldpdu |= RCVD_LLDP_TLV_TYPE1;
+				agent->rx.manifest->chassis = tlv;
 				tlv_stored = true;
 			}
 
-			if (port->msap.msap1 == NULL) {
-				port->msap.length1 = tlv->length;
-				port->msap.msap1 = (u8 *)malloc(tlv->length);
-				if (!(port->msap.msap1)) {
+			if (agent->msap.msap1 == NULL) {
+				agent->msap.length1 = tlv->length;
+				agent->msap.msap1 = (u8 *)malloc(tlv->length);
+				if (!(agent->msap.msap1)) {
 					LLDPAD_DBG("ERROR: Failed to malloc "
 						"space for msap1\n");
 					free_unpkd_tlv(tlv);
 					goto out;
 				}
-				memcpy(port->msap.msap1, tlv->info,
+				memcpy(agent->msap.msap1, tlv->info,
 					tlv->length);
 			} else {
-				if (tlv->length == port->msap.length1) {
-					if ((memcmp(tlv->info,port->msap.msap1,
+				if (tlv->length == agent->msap.length1) {
+					if ((memcmp(tlv->info,agent->msap.msap1,
 						tlv->length) == 0))
 						msap_compare_1 = true;
 				}
 			}
 		}
 		if (tlv->type == TYPE_2) { /* port ID */
-			if (port->lldpdu & RCVD_LLDP_TLV_TYPE2) {
+			if (agent->lldpdu & RCVD_LLDP_TLV_TYPE2) {
 				LLDPAD_INFO("Received multiple Port ID "
 					"TLVs in this LLDPDU\n");
 				frame_error++;
 				free_unpkd_tlv(tlv);
 				goto out;
 			} else {
-				port->lldpdu |= RCVD_LLDP_TLV_TYPE2;
-				port->rx.manifest->portid = tlv;
+				agent->lldpdu |= RCVD_LLDP_TLV_TYPE2;
+				agent->rx.manifest->portid = tlv;
 				tlv_stored = true;
 			}
 
-			if (port->msap.msap2 == NULL) {
-				port->msap.length2 = tlv->length;
-				port->msap.msap2 = (u8 *)malloc(tlv->length);
-				if (!(port->msap.msap2)) {
+			if (agent->msap.msap2 == NULL) {
+				agent->msap.length2 = tlv->length;
+				agent->msap.msap2 = (u8 *)malloc(tlv->length);
+				if (!(agent->msap.msap2)) {
 					LLDPAD_DBG("ERROR: Failed to malloc "
 						"space for msap2\n");
 					free_unpkd_tlv(tlv);
 					goto out;
 				}
-				memcpy(port->msap.msap2, tlv->info, tlv->length);
-				port->rx.newNeighbor = true;
+				memcpy(agent->msap.msap2, tlv->info, tlv->length);
+				agent->rx.newNeighbor = true;
 			} else {
-				if (tlv->length == port->msap.length2) {
-					if ((memcmp(tlv->info,port->msap.msap2,
+				if (tlv->length == agent->msap.length2) {
+					if ((memcmp(tlv->info,agent->msap.msap2,
 						tlv->length) == 0))
 						msap_compare_2 = true;
 				}
@@ -300,61 +300,61 @@ void rxProcessFrame(struct port * port)
 					good_neighbor = true;
 				} else {
 					/* New neighbor */
-					port->rx.tooManyNghbrs = true;
-					port->rx.newNeighbor = true;
+					agent->rx.tooManyNghbrs = true;
+					agent->rx.newNeighbor = true;
 					LLDPAD_INFO("** TOO_MANY_NGHBRS\n");
 				}
 			}
 		}
 		if (tlv->type == TYPE_3) { /* time to live */
-			if (port->lldpdu & RCVD_LLDP_TLV_TYPE3) {
+			if (agent->lldpdu & RCVD_LLDP_TLV_TYPE3) {
 				LLDPAD_INFO("Received multiple TTL TLVs in this"
 					" LLDPDU\n");
 				frame_error++;
 				free_unpkd_tlv(tlv);
 				goto out;
 			} else {
-				port->lldpdu |= RCVD_LLDP_TLV_TYPE3;
-				port->rx.manifest->ttl = tlv;
+				agent->lldpdu |= RCVD_LLDP_TLV_TYPE3;
+				agent->rx.manifest->ttl = tlv;
 				tlv_stored = true;
 			}
-			if ((port->rx.tooManyNghbrs == true) &&
+			if ((agent->rx.tooManyNghbrs == true) &&
 				(good_neighbor == false)) {
 				LLDPAD_INFO("** set tooManyNghbrsTimer\n");
-				port->timers.tooManyNghbrsTimer =
-					max(ntohs(*(u16 *)tlv->info), 
-					port->timers.tooManyNghbrsTimer);
+				agent->timers.tooManyNghbrsTimer =
+					max(ntohs(*(u16 *)tlv->info),
+					agent->timers.tooManyNghbrsTimer);
 				msap_compare_1 = false;
 				msap_compare_2 = false;
 			} else {
-				port->timers.rxTTL = ntohs(*(u16 *)tlv->info);
-				port->timers.lastrxTTL = port->timers.rxTTL;
+				agent->timers.rxTTL = ntohs(*(u16 *)tlv->info);
+				agent->timers.lastrxTTL = agent->timers.rxTTL;
 				good_neighbor = false;
 			}
 		}
 		if (tlv->type == TYPE_4) { /* port description */
-			port->lldpdu |= RCVD_LLDP_TLV_TYPE4;
-			port->rx.manifest->portdesc = tlv;
+			agent->lldpdu |= RCVD_LLDP_TLV_TYPE4;
+			agent->rx.manifest->portdesc = tlv;
 			tlv_stored = true;
 		}
 		if (tlv->type == TYPE_5) { /* system name */
-			port->lldpdu |= RCVD_LLDP_TLV_TYPE5;
-			port->rx.manifest->sysname = tlv;
+			agent->lldpdu |= RCVD_LLDP_TLV_TYPE5;
+			agent->rx.manifest->sysname = tlv;
 			tlv_stored = true;
 		}
 		if (tlv->type == TYPE_6) { /* system description */
-			port->lldpdu |= RCVD_LLDP_TLV_TYPE6;
-			port->rx.manifest->sysdesc = tlv;
+			agent->lldpdu |= RCVD_LLDP_TLV_TYPE6;
+			agent->rx.manifest->sysdesc = tlv;
 			tlv_stored = true;
 		}
 		if (tlv->type == TYPE_7) { /* system capabilities */
-			port->lldpdu |= RCVD_LLDP_TLV_TYPE7;
-			port->rx.manifest->syscap = tlv;
+			agent->lldpdu |= RCVD_LLDP_TLV_TYPE7;
+			agent->rx.manifest->syscap = tlv;
 			tlv_stored = true;
 		}
 		if (tlv->type == TYPE_8) { /* mgmt address */
-			port->lldpdu |= RCVD_LLDP_TLV_TYPE8;
-			port->rx.manifest->mgmtadd = tlv;
+			agent->lldpdu |= RCVD_LLDP_TLV_TYPE8;
+			agent->rx.manifest->mgmtadd = tlv;
 			tlv_stored = true;
 		}
 
@@ -363,7 +363,7 @@ void rxProcessFrame(struct port * port)
 			if (!np->ops || !np->ops->lldp_mod_rchange)
 				continue;
 
-			err = np->ops->lldp_mod_rchange(port, tlv);
+			err = np->ops->lldp_mod_rchange(port, agent, tlv);
 
 			if (!err)
 				tlv_stored = true;
@@ -371,14 +371,14 @@ void rxProcessFrame(struct port * port)
 				frame_error++;
 				free_unpkd_tlv(tlv);
 				goto out;
-			} 
+			}
 		}
 
 		if (!tlv_stored) {
 			LLDPAD_INFO("\nrxProcessFrame: allocated TLV (%lu) "
 				   " was not stored! (%p)\n", tlv->type, tlv);
 			tlv = free_unpkd_tlv(tlv);
-			port->stats.statsTLVsUnrecognizedTotal++;
+			agent->stats.statsTLVsUnrecognizedTotal++;
 		}
 		tlv = NULL;
 		tlv_stored = false;
@@ -387,130 +387,130 @@ void rxProcessFrame(struct port * port)
 out:
 	if (frame_error) {
 		/* discard the frame because of errors. */
-		port->stats.statsFramesDiscardedTotal++;
-		port->stats.statsFramesInErrorsTotal++;
-		port->rx.badFrame = true;
+		agent->stats.statsFramesDiscardedTotal++;
+		agent->stats.statsFramesInErrorsTotal++;
+		agent->rx.badFrame = true;
 	}
 
-	port->lldpdu = 0;
-	clear_manifest(port);
+	agent->lldpdu = 0;
+	clear_manifest(agent);
 
 	return;
 }
 
-u8 mibDeleteObjects(struct port *port)
+u8 mibDeleteObjects(struct port *port, struct lldp_agent *agent)
 {
 	struct lldp_module *np;
 
 	LIST_FOREACH(np, &lldp_head, lldp) {
 		if (!np->ops || !np->ops->lldp_mod_mibdelete)
 			continue;
-		np->ops->lldp_mod_mibdelete(port);
+		np->ops->lldp_mod_mibdelete(port, agent);
 	}
 
 	/* Clear history */
-	port->msap.length1 = 0;
-	if (port->msap.msap1) {
-		free(port->msap.msap1);
-		port->msap.msap1 = NULL;
+	agent->msap.length1 = 0;
+	if (agent->msap.msap1) {
+		free(agent->msap.msap1);
+		agent->msap.msap1 = NULL;
 	}
 
-	port->msap.length2 = 0;
-	if (port->msap.msap2) {
-		free(port->msap.msap2);
-		port->msap.msap2 = NULL;
+	agent->msap.length2 = 0;
+	if (agent->msap.msap2) {
+		free(agent->msap.msap2);
+		agent->msap.msap2 = NULL;
 	}
 	return 0;
 }
 
-void run_rx_sm(struct port *port)
+void run_rx_sm(struct port *port, struct lldp_agent *agent)
 {
-	set_rx_state(port);
+	set_rx_state(port, agent);
 	do {
-		switch(port->rx.state) {
+		switch(agent->rx.state) {
 		case LLDP_WAIT_PORT_OPERATIONAL:
 			process_wait_port_operational(port);
 			break;
 		case DELETE_AGED_INFO:
-			process_delete_aged_info(port);
+			process_delete_aged_info(port, agent);
 			break;
 		case RX_LLDP_INITIALIZE:
-			process_rx_lldp_initialize(port);
+			process_rx_lldp_initialize(port, agent);
 			break;
 		case RX_WAIT_FOR_FRAME:
-			process_wait_for_frame(port);
+			process_wait_for_frame(agent);
 			break;
 		case RX_FRAME:
-			process_rx_frame(port);
+			process_rx_frame(port, agent);
 			break;
 		case DELETE_INFO:
-			process_delete_info(port);
+			process_delete_info(port, agent);
 			break;
 		case UPDATE_INFO:
-			process_update_info(port);
+			process_update_info(agent);
 			break;
 		default:
 			LLDPAD_DBG("ERROR: The RX State Machine is broken!\n");
 		}
-	} while (set_rx_state(port) == true);
+	} while (set_rx_state(port, agent) == true);
 }
 
-bool set_rx_state(struct port *port)
+bool set_rx_state(struct port *port, struct lldp_agent *agent)
 {
-	if ((port->rx.rxInfoAge == false) && (port->portEnabled == false)) {
-		rx_change_state(port, LLDP_WAIT_PORT_OPERATIONAL);
+	if ((agent->rx.rxInfoAge == false) && (port->portEnabled == false)) {
+		rx_change_state(agent, LLDP_WAIT_PORT_OPERATIONAL);
 	}
 
-	switch(port->rx.state) {
+	switch(agent->rx.state) {
 	case LLDP_WAIT_PORT_OPERATIONAL:
-		if (port->rx.rxInfoAge == true) {
-			rx_change_state(port, DELETE_AGED_INFO);
+		if (agent->rx.rxInfoAge == true) {
+			rx_change_state(agent, DELETE_AGED_INFO);
 			return true;
 		} else if (port->portEnabled == true) {
-			rx_change_state(port, RX_LLDP_INITIALIZE);
+			rx_change_state(agent, RX_LLDP_INITIALIZE);
 			return true;
 		}
 		return false;
 	case DELETE_AGED_INFO:
-		rx_change_state(port, LLDP_WAIT_PORT_OPERATIONAL);
+		rx_change_state(agent, LLDP_WAIT_PORT_OPERATIONAL);
 		return true;
 	case RX_LLDP_INITIALIZE:
-		if ((port->adminStatus == enabledRxTx) ||
-			(port->adminStatus == enabledRxOnly)) {
-			rx_change_state(port, RX_WAIT_FOR_FRAME);
+		if ((agent->adminStatus == enabledRxTx) ||
+			(agent->adminStatus == enabledRxOnly)) {
+			rx_change_state(agent, RX_WAIT_FOR_FRAME);
 			return true;
 		}
 		return false;
 	case RX_WAIT_FOR_FRAME:
-		if ((port->adminStatus == disabled) ||
-			(port->adminStatus == enabledTxOnly)) {
-			rx_change_state(port, RX_LLDP_INITIALIZE);
+		if ((agent->adminStatus == disabled) ||
+			(agent->adminStatus == enabledTxOnly)) {
+			rx_change_state(agent, RX_LLDP_INITIALIZE);
 			return true;
 		}
-		if (port->rx.rxInfoAge == true) {
-			rx_change_state(port, DELETE_INFO);
+		if (agent->rx.rxInfoAge == true) {
+			rx_change_state(agent, DELETE_INFO);
 			return true;
-		} else if (port->rx.rcvFrame == true) {
-			rx_change_state(port, RX_FRAME);
+		} else if (agent->rx.rcvFrame == true) {
+			rx_change_state(agent, RX_FRAME);
 			return true;
 		}
 		return false;
 	case DELETE_INFO:
-		rx_change_state(port, RX_WAIT_FOR_FRAME);
+		rx_change_state(agent, RX_WAIT_FOR_FRAME);
 		return true;
 	case RX_FRAME:
-		if (port->timers.rxTTL == 0) {
-			rx_change_state(port, DELETE_INFO);
+		if (agent->timers.rxTTL == 0) {
+			rx_change_state(agent, DELETE_INFO);
 			return true;
-		} else if ((port->timers.rxTTL != 0) &&
-			(port->rxChanges == true)) {
-			rx_change_state(port, UPDATE_INFO);
+		} else if ((agent->timers.rxTTL != 0) &&
+			(agent->rxChanges == true)) {
+			rx_change_state(agent, UPDATE_INFO);
 			return true;
 		}
-		rx_change_state(port, RX_WAIT_FOR_FRAME);
+		rx_change_state(agent, RX_WAIT_FOR_FRAME);
 		return true;
 	case UPDATE_INFO:
-		rx_change_state(port, RX_WAIT_FOR_FRAME);
+		rx_change_state(agent, RX_WAIT_FOR_FRAME);
 		return true;
 	default:
 		LLDPAD_DBG("ERROR: The RX State Machine is broken!\n");
@@ -523,148 +523,150 @@ void process_wait_port_operational(struct port *port)
 	return;
 }
 
-void process_delete_aged_info(struct port *port)
+void process_delete_aged_info(struct port *port, struct lldp_agent *agent)
 {
-	mibDeleteObjects(port);
-	port->rx.rxInfoAge = false;
-	port->rx.remoteChange = true;
+	mibDeleteObjects(port, agent);
+	agent->rx.rxInfoAge = false;
+	agent->rx.remoteChange = true;
 	return;
 }
 
-void process_rx_lldp_initialize(struct port *port)
+void process_rx_lldp_initialize(struct port *port, struct lldp_agent *agent)
 {
-	rxInitializeLLDP(port);
-	port->rx.rcvFrame = false;
+	rxInitializeLLDP(port, agent);
+	agent->rx.rcvFrame = false;
 	return;
 }
 
-void process_wait_for_frame(struct port *port)
+void process_wait_for_frame(struct lldp_agent *agent)
 {
-	port->rx.badFrame  = false;
-	port->rx.rxInfoAge = false;
+	agent->rx.badFrame  = false;
+	agent->rx.rxInfoAge = false;
 	return;
 }
 
-void process_rx_frame(struct port *port)
+void process_rx_frame(struct port *port, struct lldp_agent *agent)
 {
-	port->rx.remoteChange = false;
-	port->rxChanges = false;
-	port->rx.rcvFrame = false;
-	rxProcessFrame(port);
+	agent->rx.remoteChange = false;
+	agent->rxChanges = false;
+	agent->rx.rcvFrame = false;
+	rxProcessFrame(port, agent);
 	return;
 }
 
-void process_delete_info(struct port *port)
+void process_delete_info(struct port *port, struct lldp_agent *agent)
 {
-	mibDeleteObjects(port);
+	mibDeleteObjects(port, agent);
 
-	if (port->rx.framein) {
-		free(port->rx.framein);
-		port->rx.framein = NULL;
+	if (agent->rx.framein) {
+		free(agent->rx.framein);
+		agent->rx.framein = NULL;
 	}
 
-	port->rx.sizein = 0;
-	port->rx.remoteChange = true;
+	agent->rx.sizein = 0;
+	agent->rx.remoteChange = true;
 	return;
 }
 
-void process_update_info(struct port *port)
+void process_update_info(struct lldp_agent *agent)
 {
-	port->rx.remoteChange = true;
+	agent->rx.remoteChange = true;
 	return;
 }
 
-void update_rx_timers(struct port *port)
+void update_rx_timers(struct lldp_agent *agent)
 {
 
-	if (port->timers.rxTTL) {
-		port->timers.rxTTL--;
-		if (port->timers.rxTTL == 0) {
-			port->rx.rxInfoAge = true;
-			if (port->timers.tooManyNghbrsTimer != 0) {
+	if (agent->timers.rxTTL) {
+		agent->timers.rxTTL--;
+		if (agent->timers.rxTTL == 0) {
+			agent->rx.rxInfoAge = true;
+			if (agent->timers.tooManyNghbrsTimer != 0) {
 				LLDPAD_DBG("** clear tooManyNghbrsTimer\n");
-				port->timers.tooManyNghbrsTimer = 0;
-				port->rx.tooManyNghbrs = false;
+				agent->timers.tooManyNghbrsTimer = 0;
+				agent->rx.tooManyNghbrs = false;
 			}
 		}
 	}
-	if (port->timers.tooManyNghbrsTimer) {
-		port->timers.tooManyNghbrsTimer--;
-		if (port->timers.tooManyNghbrsTimer == 0) {
+	if (agent->timers.tooManyNghbrsTimer) {
+		agent->timers.tooManyNghbrsTimer--;
+		if (agent->timers.tooManyNghbrsTimer == 0) {
 			LLDPAD_DBG("** tooManyNghbrsTimer timeout\n");
-			port->rx.tooManyNghbrs = false;
+			agent->rx.tooManyNghbrs = false;
 		}
 	}
 }
 
-void rx_change_state(struct port *port, u8 newstate) {
+void rx_change_state(struct lldp_agent *agent, u8 newstate)
+{
 	switch(newstate) {
 		case LLDP_WAIT_PORT_OPERATIONAL:
 			break;
 		case RX_LLDP_INITIALIZE:
-			assert((port->rx.state == LLDP_WAIT_PORT_OPERATIONAL) ||
-			       (port->rx.state == RX_WAIT_FOR_FRAME));
+			assert((agent->rx.state == LLDP_WAIT_PORT_OPERATIONAL) ||
+			       (agent->rx.state == RX_WAIT_FOR_FRAME));
 			break;
 		case DELETE_AGED_INFO:
-			assert(port->rx.state ==
+			assert(agent->rx.state ==
 				LLDP_WAIT_PORT_OPERATIONAL);
 			break;
 		case RX_WAIT_FOR_FRAME:
-			if (!(port->rx.state == RX_LLDP_INITIALIZE ||
-				port->rx.state == DELETE_INFO ||
-				port->rx.state == UPDATE_INFO ||
-				port->rx.state == RX_FRAME)) {
-				assert(port->rx.state !=
+			if (!(agent->rx.state == RX_LLDP_INITIALIZE ||
+				agent->rx.state == DELETE_INFO ||
+				agent->rx.state == UPDATE_INFO ||
+				agent->rx.state == RX_FRAME)) {
+				assert(agent->rx.state !=
 					RX_LLDP_INITIALIZE);
-				assert(port->rx.state != DELETE_INFO);
-				assert(port->rx.state != UPDATE_INFO);
-				assert(port->rx.state != RX_FRAME);
+				assert(agent->rx.state != DELETE_INFO);
+				assert(agent->rx.state != UPDATE_INFO);
+				assert(agent->rx.state != RX_FRAME);
 			}
 			break;
 		case RX_FRAME:
-			assert(port->rx.state == RX_WAIT_FOR_FRAME);
+			assert(agent->rx.state == RX_WAIT_FOR_FRAME);
 			break;
 		case DELETE_INFO:
-			if (!(port->rx.state == RX_WAIT_FOR_FRAME ||
-				port->rx.state == RX_FRAME)) {
-				assert(port->rx.state == RX_WAIT_FOR_FRAME);
-				assert(port->rx.state == RX_FRAME);
+			if (!(agent->rx.state == RX_WAIT_FOR_FRAME ||
+				agent->rx.state == RX_FRAME)) {
+				assert(agent->rx.state == RX_WAIT_FOR_FRAME);
+				assert(agent->rx.state == RX_FRAME);
 			}
 			break;
 		case UPDATE_INFO:
-			assert(port->rx.state == RX_FRAME);
+			assert(agent->rx.state == RX_FRAME);
 			break;
 		default:
 			LLDPAD_DBG("ERROR: The RX State Machine is broken!\n");
 	}
-	port->rx.state = newstate;
+	agent->rx.state = newstate;
 }
 
-void clear_manifest(struct port *port) {
-	if (port->rx.manifest->mgmtadd)
-		port->rx.manifest->mgmtadd =
-			free_unpkd_tlv(port->rx.manifest->mgmtadd);
-	if (port->rx.manifest->syscap)
-		port->rx.manifest->syscap =
-			free_unpkd_tlv(port->rx.manifest->syscap);
-	if (port->rx.manifest->sysdesc)
-		port->rx.manifest->sysdesc =
-			free_unpkd_tlv(port->rx.manifest->sysdesc);
-	if (port->rx.manifest->sysname)
-		port->rx.manifest->sysname =
-			free_unpkd_tlv(port->rx.manifest->sysname);
-	if (port->rx.manifest->portdesc)
-		port->rx.manifest->portdesc =
-			free_unpkd_tlv(port->rx.manifest->portdesc);
-	if (port->rx.manifest->ttl)
-		port->rx.manifest->ttl =
-			free_unpkd_tlv(port->rx.manifest->ttl);
-	if (port->rx.manifest->portid)
-		port->rx.manifest->portid =
-			free_unpkd_tlv(port->rx.manifest->portid);
-	if (port->rx.manifest->chassis)
-		port->rx.manifest->chassis =
-			free_unpkd_tlv(port->rx.manifest->chassis);
-	free(port->rx.manifest);
-	port->rx.manifest = NULL;
+void clear_manifest(struct lldp_agent *agent)
+{
+	if (agent->rx.manifest->mgmtadd)
+		agent->rx.manifest->mgmtadd =
+			free_unpkd_tlv(agent->rx.manifest->mgmtadd);
+	if (agent->rx.manifest->syscap)
+		agent->rx.manifest->syscap =
+			free_unpkd_tlv(agent->rx.manifest->syscap);
+	if (agent->rx.manifest->sysdesc)
+		agent->rx.manifest->sysdesc =
+			free_unpkd_tlv(agent->rx.manifest->sysdesc);
+	if (agent->rx.manifest->sysname)
+		agent->rx.manifest->sysname =
+			free_unpkd_tlv(agent->rx.manifest->sysname);
+	if (agent->rx.manifest->portdesc)
+		agent->rx.manifest->portdesc =
+			free_unpkd_tlv(agent->rx.manifest->portdesc);
+	if (agent->rx.manifest->ttl)
+		agent->rx.manifest->ttl =
+			free_unpkd_tlv(agent->rx.manifest->ttl);
+	if (agent->rx.manifest->portid)
+		agent->rx.manifest->portid =
+			free_unpkd_tlv(agent->rx.manifest->portid);
+	if (agent->rx.manifest->chassis)
+		agent->rx.manifest->chassis =
+			free_unpkd_tlv(agent->rx.manifest->chassis);
+	free(agent->rx.manifest);
+	agent->rx.manifest = NULL;
 }
diff --git a/lldp/states.h b/lldp/states.h
index d9aed9e..d5e7c58 100644
--- a/lldp/states.h
+++ b/lldp/states.h
@@ -52,7 +52,7 @@ enum {
  * The txInitializeLLDP () procedure initializes the LLDP transmit module as
  * defined in 10.1.1.
 */
-void txInitializeLLDP(struct port *port);
+void txInitializeLLDP(struct lldp_agent *agent);
 
 /**
  * The mibConstrInfoLLDPDU () procedure constructs an information LLDPDU as
@@ -66,32 +66,32 @@ void txInitializeLLDP(struct port *port);
  * LLDP MIB management function, the transmit state machine does not include a
  * separate procedure for this purpose (see 10.2.1.1).
 */
-bool mibConstrInfoLLDPDU(struct port *port);
+bool mibConstrInfoLLDPDU(struct port *, struct lldp_agent *);
 
 /**
  * The mibConstrShutdownLLDPDU () procedure constructs a shutdown LLDPDU as
  * defined in 10.2.1.2 and according to the LLDPDU and the associated TLV
  * formats specified in 9.2 and 9.5.
 */ 
-bool mibConstrShutdownLLDPDU(struct port *port);
+bool mibConstrShutdownLLDPDU(struct port *, struct lldp_agent *);
 
 /**
  * The txFrame () procedure prepends the source and destinations addresses
  * and the LLDP Ethertype to each LLDPDU as defined in 10.2.2 before it is
  * sent to the MAC for transmission.
 */ 
-void txFrame(struct port *port);
+u8 txFrame(struct port *port, struct lldp_agent *);
 
-void run_tx_sm(struct port *);
+void run_tx_sm(struct port *, struct lldp_agent *);
 void process_tx_initialize_sm(struct port *);
-void process_tx_idle(struct port *);
-void process_tx_shutdown_frame(struct port *);
-void process_tx_info_frame(struct port *);
-void update_tx_timers(struct port *);
-void run_tx_timers_sm(struct port *);
-bool set_tx_state(struct port *);
-void txInitializeTimers(struct port *);
-void tx_change_state(struct port *, u8 );
+void process_tx_idle(struct lldp_agent *);
+void process_tx_shutdown_frame(struct port *, struct lldp_agent *);
+void process_tx_info_frame(struct port *, struct lldp_agent *);
+void update_tx_timers(struct lldp_agent *);
+void run_tx_timers_sm(struct port *, struct lldp_agent *);
+bool set_tx_state(struct port *, struct lldp_agent *);
+void txInitializeTimers(struct lldp_agent *);
+void tx_change_state(struct port *, struct lldp_agent *, u8 );
 
 /******************************************************************************/
 /* Rx States */
@@ -109,7 +109,7 @@ enum {
  * The rxInitializeLLDP () procedure initializes the LLDP receive module
  * as defined in 10.1.2.
 */
-void rxInitializeLLDP(struct port *port);
+void rxInitializeLLDP(struct port *port, struct lldp_agent *);
 
 /**
  * The rxProcessFrame () procedure:
@@ -136,7 +136,7 @@ void rxInitializeLLDP(struct port *port);
  *    tooManyNghbrsTimer expires.
 */
 void rxReceiveFrame(void *, unsigned int, const u8 *, size_t );
-void rxProcessFrame(struct port *);
+void rxProcessFrame(struct port *, struct lldp_agent *);
 
 /**
  * The mibDeleteObjects () procedure deletes all information in the LLDP
@@ -144,7 +144,7 @@ void rxProcessFrame(struct port *);
  * received with an rxTTL value of zero (see 10.3.2) or the timing counter
  * rxInfoTTL expires. (see 10.3.6).
 */
-u8 mibDeleteObjects(struct port *port);
+u8 mibDeleteObjects(struct port *port, struct lldp_agent *);
 
 /**
  * The mibUpdateObjects () procedure updates the MIB objects corresponding to
@@ -154,19 +154,18 @@ u8 mibDeleteObjects(struct port *port);
  * is not set to TRUE until after the information in the LLDP remote systems
  * MIB has been updated.
 */
-void mibUpdateObjects(struct port *);
+void mibUpdateObjects(struct port *, struct lldp_agent *);
 
-void run_rx_sm(struct port *);
-bool set_rx_state(struct port *);
-void rx_change_state(struct port *, u8 );
+void run_rx_sm(struct port *, struct lldp_agent *);
+bool set_rx_state(struct port *, struct lldp_agent *);
+void rx_change_state(struct lldp_agent *, u8 );
 void process_wait_port_operational(struct port *);
-void process_delete_aged_info(struct port *);
-void process_rx_lldp_initialize(struct port *);
-void process_wait_for_frame(struct port *);
-void process_rx_frame(struct port *);
-void process_delete_info(struct port *);
-void process_update_info(struct port *);
-void update_rx_timers(struct port *);
-void load_peer_tlvs(struct port *,struct unpacked_tlv *, int);
-void clear_manifest(struct port *);
+void process_delete_aged_info(struct port *, struct lldp_agent *);
+void process_rx_lldp_initialize(struct port *, struct lldp_agent *);
+void process_wait_for_frame(struct lldp_agent *);
+void process_rx_frame(struct port *, struct lldp_agent *);
+void process_delete_info(struct port *, struct lldp_agent *);
+void process_update_info(struct lldp_agent *);
+void update_rx_timers(struct lldp_agent *);
+void clear_manifest(struct lldp_agent *);
 #endif /* STATES_H */
diff --git a/lldp/tx.c b/lldp/tx.c
index 6783ba8..0d53218 100644
--- a/lldp/tx.c
+++ b/lldp/tx.c
@@ -35,7 +35,7 @@
 #include "lldp_mod.h"
 #include "lldp_mand.h"
 
-bool mibConstrInfoLLDPDU(struct port *port)
+bool mibConstrInfoLLDPDU(struct port *port, struct lldp_agent *agent)
 {
 	struct l2_ethhdr eth;
 	u8  own_addr[ETH_ALEN];
@@ -43,23 +43,29 @@ bool mibConstrInfoLLDPDU(struct port *port)
 	u32 datasize = 0;
 	struct packed_tlv *ptlv =  NULL;
 	struct lldp_module *np;
+	char macstring[30];
 
-	if (port->tx.frameout) {
-		free(port->tx.frameout);
-		port->tx.frameout = NULL;
+	if (agent->tx.frameout) {
+		free(agent->tx.frameout);
+		agent->tx.frameout = NULL;
 	}
 
-	memcpy(eth.h_dest, multi_cast_source, ETH_ALEN);
+	mac2str(agent->mac_addr, macstring, 30);
+	LLDPAD_DBG("%s: port %s mac %s type %i.\n", __func__, port->ifname,
+		   macstring, agent->type);
+
+	memcpy(eth.h_dest, agent->mac_addr, ETH_ALEN);
 	l2_packet_get_own_src_addr(port->l2,(u8 *)&own_addr);
 	memcpy(eth.h_source, &own_addr, ETH_ALEN);
 	eth.h_proto = htons(ETH_P_LLDP);
-	port->tx.frameout =  (u8 *)malloc(ETH_FRAME_LEN);
-	if (port->tx.frameout == NULL) {
+	agent->tx.frameout =  (u8 *)malloc(ETH_FRAME_LEN);
+	if (agent->tx.frameout == NULL) {
 		LLDPAD_DBG("InfoLLDPDU: Failed to malloc frame buffer \n");
 		return false;
 	}
-	memset(port->tx.frameout,0,ETH_FRAME_LEN);
-	memcpy(port->tx.frameout, (void *)&eth, sizeof(struct l2_ethhdr));
+
+	memset(agent->tx.frameout, 0, ETH_FRAME_LEN);
+	memcpy(agent->tx.frameout, (void *)&eth, sizeof(struct l2_ethhdr));
 	fb_offset += sizeof(struct l2_ethhdr);
 
 	/* Generic TLV Pack */
@@ -67,11 +73,11 @@ bool mibConstrInfoLLDPDU(struct port *port)
 		if (!np->ops || !np->ops->lldp_mod_gettlv)
 			continue;
 
-		ptlv = np->ops->lldp_mod_gettlv(port);
+		ptlv = np->ops->lldp_mod_gettlv(port, agent);
 		if (ptlv) {
 			if ((ptlv->size+fb_offset) > ETH_MAX_DATA_LEN)
 				goto error;
-			memcpy(port->tx.frameout+fb_offset,
+			memcpy(agent->tx.frameout+fb_offset,
 			       ptlv->tlv, ptlv->size);
 			datasize += ptlv->size;
 			fb_offset += ptlv->size;
@@ -83,58 +89,71 @@ bool mibConstrInfoLLDPDU(struct port *port)
 	ptlv = pack_end_tlv();
 	if (!ptlv || ((ptlv->size + fb_offset) > ETH_MAX_DATA_LEN))
 		goto error;
-	memcpy(port->tx.frameout + fb_offset, ptlv->tlv, ptlv->size);
+	memcpy(agent->tx.frameout + fb_offset, ptlv->tlv, ptlv->size);
 	datasize += ptlv->size;
 	fb_offset += ptlv->size;
 	ptlv =  free_pkd_tlv(ptlv);
 
 	if (datasize < ETH_MIN_DATA_LEN)
-		port->tx.sizeout = ETH_MIN_PKT_LEN;
+		agent->tx.sizeout = ETH_MIN_PKT_LEN;
 	else
-		port->tx.sizeout = fb_offset;
+		agent->tx.sizeout = fb_offset;
 
 	return true;
 
 error:
 	ptlv = free_pkd_tlv(ptlv);
-	if (port->tx.frameout)
-		free(port->tx.frameout);
-	port->tx.frameout = NULL;
+	if (agent->tx.frameout)
+		free(agent->tx.frameout);
+	agent->tx.frameout = NULL;
 	LLDPAD_DBG("InfoLLDPDU: packed TLV too large for tx frame\n");
 	return false;
 }
 
-void txInitializeLLDP(struct port *port)
+void txInitializeLLDP(struct lldp_agent *agent)
 {
-	if (port->tx.frameout) {
-		free(port->tx.frameout);
-		port->tx.frameout = NULL;
+	if (agent->tx.frameout) {
+		free(agent->tx.frameout);
+		agent->tx.frameout = NULL;
 	}
-	port->tx.localChange = false;
-	port->stats.statsFramesOutTotal = 0;
-	port->timers.reinitDelay   = REINIT_DELAY;
-	port->timers.msgTxHold     = DEFAULT_TX_HOLD;
-	port->timers.msgTxInterval = DEFAULT_TX_INTERVAL;
-	port->timers.msgFastTx     = FAST_TX_INTERVAL;
+
+	agent->tx.state  = TX_LLDP_INITIALIZE;
+	agent->rx.state = LLDP_WAIT_PORT_OPERATIONAL;
+
+	agent->tx.localChange = false;
+	agent->stats.statsFramesOutTotal = 0;
+	agent->timers.reinitDelay   = REINIT_DELAY;
+	agent->timers.msgTxHold     = DEFAULT_TX_HOLD;
+	agent->timers.msgTxInterval = DEFAULT_TX_INTERVAL;
+	agent->timers.msgFastTx     = FAST_TX_INTERVAL;
+
+	agent->tx.txTTL = 0;
+	agent->msap.length1 = 0;
+	agent->msap.msap1 = NULL;
+	agent->msap.length2 = 0;
+	agent->msap.msap2 = NULL;
+	agent->lldpdu = false;
+
 	return;
 }
 
-void txInitializeTimers(struct port *port)
+void txInitializeTimers(struct lldp_agent *agent)
 {
-	port->timers.txTick = false;
-	port->tx.txNow = false;
-	port->tx.localChange = false;
-	port->timers.txTTR = 0;
-	port->tx.txFast = 0;
-	port->timers.txShutdownWhile = 0;
-	port->rx.newNeighbor = false;
-	port->timers.txMaxCredit = TX_CREDIT_MAX;
-	port->timers.txCredit = TX_CREDIT_MAX;
-	port->timers.txFastInit = TX_FAST_INIT;
+	agent->timers.txTick = false;
+	agent->tx.txNow = false;
+	agent->tx.localChange = false;
+	agent->timers.txTTR = 0;
+	agent->tx.txFast = 0;
+	agent->timers.txShutdownWhile = 0;
+	agent->rx.newNeighbor = false;
+	agent->timers.txMaxCredit = TX_CREDIT_MAX;
+	agent->timers.txCredit = TX_CREDIT_MAX;
+	agent->timers.txFastInit = TX_FAST_INIT;
+	agent->timers.state = TX_TIMER_BEGIN;
 	return;
 }
 
-bool mibConstrShutdownLLDPDU(struct port *port)
+bool mibConstrShutdownLLDPDU(struct port *port, struct lldp_agent *agent)
 {
 	struct l2_ethhdr eth;
 	u8  own_addr[ETH_ALEN];
@@ -142,23 +161,27 @@ bool mibConstrShutdownLLDPDU(struct port *port)
 	u32 datasize = 0;
 	struct packed_tlv *ptlv =  NULL;
 	struct lldp_module *np;
+	char macstring[30];
 
-	if (port->tx.frameout) {
-		free(port->tx.frameout);
-		port->tx.frameout = NULL;
+	if (agent->tx.frameout) {
+		free(agent->tx.frameout);
+		agent->tx.frameout = NULL;
 	}
 
-	memcpy(eth.h_dest, multi_cast_source, ETH_ALEN);
+	mac2str(agent->mac_addr, macstring, 30);
+	LLDPAD_DBG("%s: mac %s.\n", __func__, macstring);
+
+	memcpy(eth.h_dest, agent->mac_addr, ETH_ALEN);
 	l2_packet_get_own_src_addr(port->l2,(u8 *)&own_addr);
 	memcpy(eth.h_source, &own_addr, ETH_ALEN);
 	eth.h_proto = htons(ETH_P_LLDP);
-	port->tx.frameout =  (u8 *)malloc(ETH_FRAME_LEN);
-	if (port->tx.frameout == NULL) {
+	agent->tx.frameout =  (u8 *)malloc(ETH_FRAME_LEN);
+	if (agent->tx.frameout == NULL) {
 		LLDPAD_DBG("ShutdownLLDPDU: Failed to malloc frame buffer \n");
 		return false;
 	}
-	memset(port->tx.frameout,0,ETH_FRAME_LEN);
-	memcpy(port->tx.frameout, (void *)&eth, sizeof(struct l2_ethhdr));
+	memset(agent->tx.frameout,0,ETH_FRAME_LEN);
+	memcpy(agent->tx.frameout, (void *)&eth, sizeof(struct l2_ethhdr));
 	fb_offset += sizeof(struct l2_ethhdr);
 
 	np = find_module_by_id(&lldp_head, LLDP_MOD_MAND);
@@ -166,13 +189,13 @@ bool mibConstrShutdownLLDPDU(struct port *port)
 		goto error;
 	if (!np->ops || !np->ops->lldp_mod_gettlv)
 		goto error;
-	ptlv = np->ops->lldp_mod_gettlv(port);
+	ptlv = np->ops->lldp_mod_gettlv(port, agent);
 	if (ptlv) {
 		if ((ptlv->size + fb_offset) > ETH_MAX_DATA_LEN)
 			goto error;
 		/* set the TTL to be 0 TTL TLV */
 		memset(&ptlv->tlv[ptlv->size - 2], 0, 2);
-		memcpy(port->tx.frameout + fb_offset, ptlv->tlv, ptlv->size);
+		memcpy(agent->tx.frameout + fb_offset, ptlv->tlv, ptlv->size);
 		datasize += ptlv->size;
 		fb_offset += ptlv->size;
 		ptlv =  free_pkd_tlv(ptlv);
@@ -182,94 +205,99 @@ bool mibConstrShutdownLLDPDU(struct port *port)
 	ptlv = pack_end_tlv();
 	if (!ptlv || ((ptlv->size + fb_offset) > ETH_MAX_DATA_LEN))
 		goto error;
-	memcpy(port->tx.frameout + fb_offset, ptlv->tlv, ptlv->size);
+	memcpy(agent->tx.frameout + fb_offset, ptlv->tlv, ptlv->size);
 	datasize += ptlv->size;
 	fb_offset += ptlv->size;
 	ptlv = free_pkd_tlv(ptlv);
 
 	if (datasize < ETH_MIN_DATA_LEN)
-		port->tx.sizeout = ETH_MIN_PKT_LEN;
+		agent->tx.sizeout = ETH_MIN_PKT_LEN;
 	else
-		port->tx.sizeout = fb_offset;
+		agent->tx.sizeout = fb_offset;
 	return true;
 
 error:
 	ptlv = free_pkd_tlv(ptlv);
-	if (port->tx.frameout)
-		free(port->tx.frameout);
-	port->tx.frameout = NULL;
+	if (agent->tx.frameout)
+		free(agent->tx.frameout);
+	agent->tx.frameout = NULL;
 	LLDPAD_DBG("InfoLLDPDU: packed TLV too large for tx frame\n");
 	return false;
 }
 
-void txFrame(struct port *port)
+u8 txFrame(struct port *port, struct lldp_agent *agent)
 {
-	l2_packet_send(port->l2, (u8 *)&multi_cast_source,
-		htons(ETH_P_LLDP),port->tx.frameout,port->tx.sizeout);
-	port->stats.statsFramesOutTotal++;
+	int status = 0;
+
+	status = l2_packet_send(port->l2, agent->mac_addr,
+		htons(ETH_P_LLDP), agent->tx.frameout, agent->tx.sizeout);
+
+	agent->stats.statsFramesOutTotal++;
+
+	return 0;
 }
 
 
-void run_tx_sm(struct port *port)
+void run_tx_sm(struct port *port, struct lldp_agent *agent)
 {
-	set_tx_state(port);
+	set_tx_state(port, agent);
 	do {
-		switch(port->tx.state) {
+		switch(agent->tx.state) {
 		case TX_LLDP_INITIALIZE:
-			txInitializeLLDP(port);
+			txInitializeLLDP(agent);
 			break;
 		case TX_IDLE:
-			process_tx_idle(port);
+			process_tx_idle(agent);
 			break;
 		case TX_SHUTDOWN_FRAME:
-			process_tx_shutdown_frame(port);
+			process_tx_shutdown_frame(port, agent);
 			break;
 		case TX_INFO_FRAME:
-			process_tx_info_frame(port);
+			process_tx_info_frame(port, agent);
 			break;
 		default:
 			LLDPAD_DBG("ERROR The TX State Machine is broken!\n");
 		}
-	} while (set_tx_state(port) == true);
+	} while (set_tx_state(port, agent) == true);
 
 	return;
 }
 
-bool set_tx_state(struct port *port)
+bool set_tx_state(struct port *port, struct lldp_agent *agent)
 {
 	if ((port->portEnabled == false) && (port->prevPortEnabled == true)) {
 		LLDPAD_DBG("set_tx_state: port was disabled\n");
-		tx_change_state(port, TX_LLDP_INITIALIZE);
+		tx_change_state(port, agent, TX_LLDP_INITIALIZE);
 	}
 	port->prevPortEnabled = port->portEnabled;
 
-	switch (port->tx.state) {
+	switch (agent->tx.state) {
 	case TX_LLDP_INITIALIZE:
-		if (port->portEnabled && ((port->adminStatus == enabledRxTx) ||
-			(port->adminStatus == enabledTxOnly))) {
-			tx_change_state(port, TX_IDLE);
+		if (port->portEnabled && ((agent->adminStatus == enabledRxTx) ||
+			(agent->adminStatus == enabledTxOnly))) {
+			tx_change_state(port, agent, TX_IDLE);
 			return true;
 		}
 		return false;
 	case TX_IDLE:
-		if ((port->adminStatus == disabled) ||
-			(port->adminStatus == enabledRxOnly)) {
-			tx_change_state(port, TX_SHUTDOWN_FRAME);
+		if ((agent->adminStatus == disabled) ||
+			(agent->adminStatus == enabledRxOnly)) {
+			tx_change_state(port, agent, TX_SHUTDOWN_FRAME);
 			return true;
 		}
-		if ((port->tx.txNow) && ((port->timers.txCredit > 0))) {
-			tx_change_state(port, TX_INFO_FRAME);
+		if ((agent->tx.txNow) && ((agent->timers.txCredit > 0))) {
+			tx_change_state(port, agent, TX_INFO_FRAME);
 			return true;
 		}
 		return false;
 	case TX_SHUTDOWN_FRAME:
-		if (port->timers.txShutdownWhile == 0) {
-			tx_change_state(port, TX_LLDP_INITIALIZE);
+		if (agent->timers.txShutdownWhile == 0) {
+			tx_change_state(port, agent, TX_LLDP_INITIALIZE);
 			return true;
 		}
 		return false;
 	case TX_INFO_FRAME:
-		tx_change_state(port, TX_IDLE);
+		tx_change_state(port, agent, TX_IDLE);
 		return true;
 	default:
 		LLDPAD_DBG("ERROR: The TX State Machine is broken!\n");
@@ -277,54 +305,51 @@ bool set_tx_state(struct port *port)
 	}
 }
 
-void process_tx_idle(struct port *port)
+void process_tx_idle(struct lldp_agent *agent)
 {
 	u32 tmpTTL;
 
-	tmpTTL = DEFAULT_TX_INTERVAL * port->timers.msgTxHold + 1;
+	tmpTTL = DEFAULT_TX_INTERVAL * agent->timers.msgTxHold + 1;
 
 	if (tmpTTL < 65535)
-		port->tx.txTTL = htons(65535);
+		agent->tx.txTTL = htons(65535);
 	else
-		port->tx.txTTL = htons((u16)tmpTTL);
+		agent->tx.txTTL = htons((u16)tmpTTL);
 
 	return;
 }
 
-void process_tx_shutdown_frame(struct port *port)
+void process_tx_shutdown_frame(struct port *port, struct lldp_agent *agent)
 {
-	if (port->timers.txShutdownWhile == 0) {
-		if (mibConstrShutdownLLDPDU(port))
-			txFrame(port);
-		port->timers.txShutdownWhile = port->timers.reinitDelay;
+	if (agent->timers.txShutdownWhile == 0) {
+		if (mibConstrShutdownLLDPDU(port, agent))
+			txFrame(port, agent);
+		agent->timers.txShutdownWhile = agent->timers.reinitDelay;
 	}
 	return;
 }
 
-void process_tx_info_frame(struct port *port)
+void process_tx_info_frame(struct port *port, struct lldp_agent *agent)
 {
-	mibConstrInfoLLDPDU(port);
+	mibConstrInfoLLDPDU(port, agent);
 
-	txFrame(port);
-	if (port->timers.txCredit > 0)
-		port->timers.txCredit--;
-	port->tx.txNow = false;
+	txFrame(port, agent);
+	if (agent->timers.txCredit > 0)
+		agent->timers.txCredit--;
+	agent->tx.txNow = false;
 	return;
 }
 
-void	update_tx_timers(struct port *port)
+void update_tx_timers(struct lldp_agent *agent)
 {
-	if (port->timers.txShutdownWhile)
-		port->timers.txShutdownWhile--;
-
-	if (port->timers.txTTR)
-		port->timers.txTTR--;
+	if (agent->timers.txTTR)
+		agent->timers.txTTR--;
 
-	port->timers.txTick = true;
+	agent->timers.txTick = true;
 	return;
 }
 
-void	tx_timer_change_state(struct port *port, u8 newstate)
+void	tx_timer_change_state(struct lldp_agent *agent, u8 newstate)
 {
 	switch(newstate) {
 	case TX_TIMER_INITIALIZE:
@@ -343,56 +368,56 @@ void	tx_timer_change_state(struct port *port, u8 newstate)
 		LLDPAD_DBG("ERROR: tx_timer_change_state:  default\n");
 	}
 
-	port->timers.state = newstate;
+	agent->timers.state = newstate;
 	return;
 }
 
-bool	set_tx_timers_state(struct port *port)
+bool	set_tx_timers_state(struct port *port, struct lldp_agent *agent)
 {
-	if ((port->timers.state == TX_TIMER_BEGIN) ||
-	    (port->portEnabled == false) || (port->adminStatus == disabled) ||
-	    (port->adminStatus == enabledRxOnly)) {
-		tx_timer_change_state(port, TX_TIMER_INITIALIZE);
+	if ((agent->timers.state == TX_TIMER_BEGIN) ||
+	    (port->portEnabled == false) || (agent->adminStatus == disabled) ||
+	    (agent->adminStatus == enabledRxOnly)) {
+		tx_timer_change_state(agent, TX_TIMER_INITIALIZE);
 	}
 
-	switch (port->timers.state) {
+	switch (agent->timers.state) {
 	case TX_TIMER_INITIALIZE:
-		if (port->portEnabled && ((port->adminStatus == enabledRxTx) ||
-			(port->adminStatus == enabledTxOnly))) {
-			tx_timer_change_state(port, TX_TIMER_IDLE);
+		if (port->portEnabled && ((agent->adminStatus == enabledRxTx) ||
+			(agent->adminStatus == enabledTxOnly))) {
+			tx_timer_change_state(agent, TX_TIMER_IDLE);
 			return true;
 		}
 		return false;
 	case TX_TIMER_IDLE:
-		if (port->tx.localChange) {
-			tx_timer_change_state(port, SIGNAL_TX);
+		if (agent->tx.localChange) {
+			tx_timer_change_state(agent, SIGNAL_TX);
 			return true;
 		}
 
-		if (port->timers.txTTR == 0) {
-			tx_timer_change_state(port, TX_TIMER_EXPIRES);
+		if (agent->timers.txTTR == 0) {
+			tx_timer_change_state(agent, TX_TIMER_EXPIRES);
 			return true;
 		}
 
-		if (port->rx.newNeighbor) {
-			tx_timer_change_state(port, TX_FAST_START);
+		if (agent->rx.newNeighbor) {
+			tx_timer_change_state(agent, TX_FAST_START);
 			return true;
 		}
 
-		if (port->timers.txTick) {
-			tx_timer_change_state(port, TX_TICK);
+		if (agent->timers.txTick) {
+			tx_timer_change_state(agent, TX_TICK);
 			return true;
 		}
 		return false;
 	case TX_TIMER_EXPIRES:
-		tx_timer_change_state(port, SIGNAL_TX);
+		tx_timer_change_state(agent, SIGNAL_TX);
 		return true;
 	case SIGNAL_TX:
 	case TX_TICK:
-		tx_timer_change_state(port, TX_TIMER_IDLE);
+		tx_timer_change_state(agent, TX_TIMER_IDLE);
 		return true;
 	case TX_FAST_START:
-		tx_timer_change_state(port, TX_TIMER_EXPIRES);
+		tx_timer_change_state(agent, TX_TIMER_EXPIRES);
 		return true;
 	default:
 		LLDPAD_DBG("ERROR: The TX State Machine is broken!\n");
@@ -400,71 +425,71 @@ bool	set_tx_timers_state(struct port *port)
 	}
 }
 
-void	run_tx_timers_sm(struct port *port)
+void	run_tx_timers_sm(struct port *port, struct lldp_agent *agent)
 {
-	set_tx_timers_state(port);
+	set_tx_timers_state(port, agent);
 	do {
-		switch(port->timers.state) {
+		switch(agent->timers.state) {
 		case TX_TIMER_INITIALIZE:
-			txInitializeTimers(port);
+			txInitializeTimers(agent);
 			break;
 		case TX_TIMER_IDLE:
 			break;
 		case TX_TIMER_EXPIRES:
-			if (port->tx.txFast)
-				port->tx.txFast--;
+			if (agent->tx.txFast)
+				agent->tx.txFast--;
 			break;
 		case TX_TICK:
-			port->timers.txTick = false;
-			if (port->timers.txCredit < port->timers.txMaxCredit)
-				port->timers.txCredit++;
+			agent->timers.txTick = false;
+			if (agent->timers.txCredit < agent->timers.txMaxCredit)
+				agent->timers.txCredit++;
 			break;
 		case SIGNAL_TX:
-			port->tx.txNow = true;
-			port->tx.localChange = false;
-			if (port->tx.txFast)
-				port->timers.txTTR = port->timers.msgFastTx;
+			agent->tx.txNow = true;
+			agent->tx.localChange = false;
+			if (agent->tx.txFast)
+				agent->timers.txTTR = agent->timers.msgFastTx;
 			else
-				port->timers.txTTR = port->timers.msgTxInterval;
+				agent->timers.txTTR = agent->timers.msgTxInterval;
 			break;
 		case TX_FAST_START:
-			port->rx.newNeighbor = false;
-			if (port->tx.txFast == 0)
-				port->tx.txFast = port->timers.txFastInit;
+			agent->rx.newNeighbor = false;
+			if (agent->tx.txFast == 0)
+				agent->tx.txFast = agent->timers.txFastInit;
 			break;
 		default:
 			LLDPAD_DBG("ERROR The TX Timer State Machine "
 				   "is broken!\n");
 		}
-	} while (set_tx_timers_state(port) == true);
+	} while (set_tx_timers_state(port, agent) == true);
 
 	return;
 }
 
-void tx_change_state(struct port *port, u8 newstate)
+void tx_change_state(struct port *port, struct lldp_agent *agent, u8 newstate)
 {
 	switch(newstate) {
 	case TX_LLDP_INITIALIZE:
-		if ((port->tx.state != TX_SHUTDOWN_FRAME) &&
+		if ((agent->tx.state != TX_SHUTDOWN_FRAME) &&
 			port->portEnabled) {
 			assert(port->portEnabled);
 		}
 		break;
 	case TX_IDLE:
-		if (!(port->tx.state == TX_LLDP_INITIALIZE ||
-			port->tx.state == TX_INFO_FRAME)) {
-			assert(port->tx.state == TX_LLDP_INITIALIZE);
-			assert(port->tx.state == TX_INFO_FRAME);
+		if (!(agent->tx.state == TX_LLDP_INITIALIZE ||
+			agent->tx.state == TX_INFO_FRAME)) {
+			assert(agent->tx.state == TX_LLDP_INITIALIZE);
+			assert(agent->tx.state == TX_INFO_FRAME);
 		}
 		break;
 	case TX_SHUTDOWN_FRAME:
 	case TX_INFO_FRAME:
-		assert(port->tx.state == TX_IDLE);
+		assert(agent->tx.state == TX_IDLE);
 		break;
 	default:
 		LLDPAD_DBG("ERROR: tx_change_state:  default\n");
 	}
 
-	port->tx.state = newstate;
+	agent->tx.state = newstate;
 	return;
 }
diff --git a/lldp_8021qaz.c b/lldp_8021qaz.c
index 2a6685b..0be1dad 100644
--- a/lldp_8021qaz.c
+++ b/lldp_8021qaz.c
@@ -51,8 +51,8 @@
 struct lldp_head lldp_head;
 struct config_t lldpad_cfg;
 
-static int ieee8021qaz_check_pending(struct port *port);
-static void run_all_sm(struct port *port);
+static int ieee8021qaz_check_pending(struct port *port, struct lldp_agent *);
+static void run_all_sm(struct port *port, struct lldp_agent *agent);
 static void ieee8021qaz_mibUpdateObjects(struct port *port);
 static void ieee8021qaz_app_reset(struct app_tlv_head *head);
 
@@ -68,7 +68,8 @@ static const struct lldp_mod_ops ieee8021qaz_ops = {
 	.timer			= ieee8021qaz_check_pending,
 };
 
-static int ieee8021qaz_check_pending(struct port *port)
+static int ieee8021qaz_check_pending(struct port *port,
+				     struct lldp_agent *agent)
 {
 	struct ieee8021qaz_user_data *iud;
 	struct ieee8021qaz_tlvs *tlv = NULL;
@@ -81,11 +82,12 @@ static int ieee8021qaz_check_pending(struct port *port)
 		LIST_FOREACH(tlv, &iud->head, entry) {
 			if (!strncmp(port->ifname, tlv->ifname, IFNAMSIZ)) {
 				if (tlv->active && tlv->pending &&
-				    port->timers.dormantDelay == 1) {
+				    port->dormantDelay == 1) {
 					tlv->pending = false;
 					ieee8021qaz_app_reset(&tlv->app_head);
-					run_all_sm(port);
-					somethingChangedLocal(port->ifname);
+					run_all_sm(port, agent);
+					somethingChangedLocal(port->ifname,
+							      agent->type);
 				}
 				break;
 			}
@@ -195,8 +197,9 @@ static void set_ets_tsa_map(char *arg, u8 *tsa_map)
 	free(argcpy);
 }
 
-static int read_cfg_file(char *ifname, struct ieee8021qaz_tlvs *tlvs,
-		  feature_support *dcb_support)
+static int read_cfg_file(char *ifname, struct lldp_agent *agent,
+			 struct ieee8021qaz_tlvs *tlvs,
+			 feature_support *dcb_support)
 {
 	char *arg, arg_path[256];
 	int res = 0, i;
@@ -205,7 +208,8 @@ static int read_cfg_file(char *ifname, struct ieee8021qaz_tlvs *tlvs,
 	/* Read ETS-CFG willing bit -- default willing enabled */
 	snprintf(arg_path, sizeof(arg_path), "%s%08x.%s", TLVID_PREFIX,
 		 TLVID_8021(LLDP_8021QAZ_ETSCFG), ARG_WILLING);
-	res = get_config_setting(ifname, arg_path, &willing, CONFIG_TYPE_INT);
+	res = get_config_setting_by_agent(ifname, agent->type, arg_path, &willing,
+				 CONFIG_TYPE_INT);
 	if (!res)
 		tlvs->ets->cfgl->willing = !!willing;
 	else
@@ -214,7 +218,8 @@ static int read_cfg_file(char *ifname, struct ieee8021qaz_tlvs *tlvs,
 	/* Read PFC willing bit -- default willing enabled */
 	snprintf(arg_path, sizeof(arg_path), "%s%08x.%s", TLVID_PREFIX,
 		 TLVID_8021(LLDP_8021QAZ_PFC), ARG_WILLING);
-	res = get_config_setting(ifname, arg_path, &willing, CONFIG_TYPE_INT);
+	res = get_config_setting_by_agent(ifname, agent->type, arg_path, &willing,
+				 CONFIG_TYPE_INT);
 	if (!res)
 		tlvs->pfc->local.willing = !!willing;
 	else
@@ -225,7 +230,8 @@ static int read_cfg_file(char *ifname, struct ieee8021qaz_tlvs *tlvs,
 	 */
 	snprintf(arg_path, sizeof(arg_path), "%s%08x.%s", TLVID_PREFIX,
 		 TLVID_8021(LLDP_8021QAZ_ETSCFG), ARG_ETS_UP2TC);
-	res = get_config_setting(ifname, arg_path, &arg, CONFIG_TYPE_STRING);
+	res = get_config_setting_by_agent(ifname, agent->type, arg_path, &arg,
+				 CONFIG_TYPE_STRING);
 	if (!res)
 		set_ets_prio_map(arg, &tlvs->ets->cfgl->prio_map);
 	else
@@ -237,7 +243,8 @@ static int read_cfg_file(char *ifname, struct ieee8021qaz_tlvs *tlvs,
 	 */
 	snprintf(arg_path, sizeof(arg_path), "%s%08x.%s", TLVID_PREFIX,
 		 TLVID_8021(LLDP_8021QAZ_ETSREC), ARG_ETS_UP2TC);
-	res = get_config_setting(ifname, arg_path, &arg, CONFIG_TYPE_STRING);
+	res = get_config_setting_by_agent(ifname, agent->type, arg_path, &arg,
+				 CONFIG_TYPE_STRING);
 	if (!res)
 		set_ets_prio_map(arg, &tlvs->ets->recl->prio_map);
 	else
@@ -248,7 +255,8 @@ static int read_cfg_file(char *ifname, struct ieee8021qaz_tlvs *tlvs,
 	 */
 	snprintf(arg_path, sizeof(arg_path), "%s%08x.%s", TLVID_PREFIX,
 		 TLVID_8021(LLDP_8021QAZ_ETSCFG), ARG_ETS_TCBW);
-	res = get_config_setting(ifname, arg_path, &arg, CONFIG_TYPE_STRING);
+	res = get_config_setting_by_agent(ifname, agent->type, arg_path, &arg,
+				 CONFIG_TYPE_STRING);
 	if (!res) {
 		char *argcpy = strdup(arg);
 		char *tokens;
@@ -269,7 +277,8 @@ static int read_cfg_file(char *ifname, struct ieee8021qaz_tlvs *tlvs,
 	 */
 	snprintf(arg_path, sizeof(arg_path), "%s%08x.%s", TLVID_PREFIX,
 		 TLVID_8021(LLDP_8021QAZ_ETSREC), ARG_ETS_TCBW);
-	res = get_config_setting(ifname, arg_path, &arg, CONFIG_TYPE_STRING);
+	res = get_config_setting_by_agent(ifname, agent->type, arg_path, &arg,
+				 CONFIG_TYPE_STRING);
 	if (!res) {
 		char *argcpy = strdup(arg);
 		char *tokens;
@@ -294,7 +303,8 @@ static int read_cfg_file(char *ifname, struct ieee8021qaz_tlvs *tlvs,
 	for (i = 0x80, numtcs = 8; i > 0; i = i>>1, numtcs--)
 		if (i & dcb_support->traffic_classes)
 			break;
-	res = get_config_setting(ifname, arg_path, &numtcs, CONFIG_TYPE_INT);
+	res = get_config_setting_by_agent(ifname, agent->type, arg_path, &numtcs,
+				 CONFIG_TYPE_INT);
 	tlvs->ets->cfgl->max_tcs = numtcs;
 
 	/* Read and parse ETS-CFG tc transmission selction algorithm map
@@ -302,7 +312,8 @@ static int read_cfg_file(char *ifname, struct ieee8021qaz_tlvs *tlvs,
 	 */
 	snprintf(arg_path, sizeof(arg_path), "%s%08x.%s", TLVID_PREFIX,
 		 TLVID_8021(LLDP_8021QAZ_ETSCFG), ARG_ETS_TSA);
-	res = get_config_setting(ifname, arg_path, &arg, CONFIG_TYPE_STRING);
+	res = get_config_setting_by_agent(ifname, agent->type, arg_path, &arg,
+				 CONFIG_TYPE_STRING);
 	if (!res) {
 		set_ets_tsa_map(arg, tlvs->ets->cfgl->tsa_map);
 	} else {
@@ -315,7 +326,8 @@ static int read_cfg_file(char *ifname, struct ieee8021qaz_tlvs *tlvs,
 	 */
 	snprintf(arg_path, sizeof(arg_path), "%s%08x.%s", TLVID_PREFIX,
 		 TLVID_8021(LLDP_8021QAZ_ETSREC), ARG_ETS_TSA);
-	res = get_config_setting(ifname, arg_path, &arg, CONFIG_TYPE_STRING);
+	res = get_config_setting_by_agent(ifname, agent->type, arg_path, &arg,
+				 CONFIG_TYPE_STRING);
 	if (!res) {
 		set_ets_tsa_map(arg, tlvs->ets->recl->tsa_map);
 	} else {
@@ -326,14 +338,16 @@ static int read_cfg_file(char *ifname, struct ieee8021qaz_tlvs *tlvs,
 	/* Read and parse PFC enable bitmask -- default 0x00 */
 	snprintf(arg_path, sizeof(arg_path), "%s%08x.%s", TLVID_PREFIX,
 		 TLVID_8021(LLDP_8021QAZ_PFC), ARG_PFC_ENABLED);
-	res = get_config_setting(ifname, arg_path, &pfc_mask, CONFIG_TYPE_INT);
+	res = get_config_setting_by_agent(ifname, agent->type, arg_path, &pfc_mask,
+				 CONFIG_TYPE_INT);
 	if (!res)
 		tlvs->pfc->local.pfc_enable = pfc_mask;
 
 	/* Read and parse PFC delay -- default 0x00 */
 	snprintf(arg_path, sizeof(arg_path), "%s%08x.%s", TLVID_PREFIX,
 		 TLVID_8021(LLDP_8021QAZ_PFC), ARG_PFC_DELAY);
-	res = get_config_setting(ifname, arg_path, &delay, CONFIG_TYPE_INT);
+	res = get_config_setting_by_agent(ifname, agent->type, arg_path, &delay,
+				 CONFIG_TYPE_INT);
 	if (!res)
 		tlvs->pfc->local.delay = delay;
 
@@ -346,7 +360,8 @@ static int read_cfg_file(char *ifname, struct ieee8021qaz_tlvs *tlvs,
 	for (i = 0x80, numtcs = 8; i > 0; i = i>>1, numtcs--)
 		if (i & dcb_support->pfc_traffic_classes)
 			break;
-	res = get_config_setting(ifname, arg_path, &numtcs, CONFIG_TYPE_INT);
+	res = get_config_setting_by_agent(ifname, agent->type, arg_path, &numtcs,
+				 CONFIG_TYPE_INT);
 	tlvs->pfc->local.pfc_cap = numtcs;
 
 	/* Read and add APP data to internal lldpad APP ring */
@@ -358,7 +373,8 @@ static int read_cfg_file(char *ifname, struct ieee8021qaz_tlvs *tlvs,
 
 		snprintf(arg_path, sizeof(arg_path), "%s%08x.%s%i", TLVID_PREFIX,
 			 TLVID_8021(LLDP_8021QAZ_APP), ARG_APP, i);
-		res = get_config_setting(ifname, arg_path, &arg, CONFIG_TYPE_STRING);
+		res = get_config_setting_by_agent(ifname, agent->type, arg_path, &arg,
+					 CONFIG_TYPE_STRING);
 
 		if (res)
 			continue;
@@ -417,7 +433,7 @@ inline void set_prio_map(u32 *prio_map, u8 prio, int tc)
  * as new defaults. If NO, load defaults. Also, check for TLV values via cmd
  * prompt. Then initialize FSMs for each tlv and finally build the tlvs
  */
-void ieee8021qaz_ifup(char *ifname)
+void ieee8021qaz_ifup(char *ifname, struct lldp_agent *agent)
 {
 	struct port *port = NULL;
 	struct ieee8021qaz_tlvs *tlvs;
@@ -448,9 +464,9 @@ void ieee8021qaz_ifup(char *ifname)
 	/* if there is no persistent adminStatus setting then set to enabledRx
 	 * but do not persist that as a setting.
 	 */
-	if (get_config_setting(ifname, ARG_ADMINSTATUS, (void *)&adminstatus,
-				CONFIG_TYPE_INT)) {
-		set_lldp_port_admin(ifname, enabledRxOnly);
+	if (get_config_setting_by_agent(ifname, agent->type, ARG_ADMINSTATUS,
+			       (void *)&adminstatus, CONFIG_TYPE_INT)) {
+		set_lldp_agent_admin(ifname, agent->type, enabledRxOnly);
 	}
 
 	/* lookup port data */
@@ -521,7 +537,7 @@ void ieee8021qaz_ifup(char *ifname)
 	tlvs->pfc->remote_param = 0;
 
 	LIST_INIT(&tlvs->app_head);
-	read_cfg_file(port->ifname, tlvs, &dcb_support);
+	read_cfg_file(port->ifname, agent, tlvs, &dcb_support);
 
 	iud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_8021QAZ);
 	LIST_INSERT_HEAD(&iud->head, tlvs, entry);
@@ -992,7 +1008,7 @@ static void ets_rec_to_ieee(struct ieee_ets *ieee, struct etsrec_obj *rec)
 	return;
 }
 
-void run_all_sm(struct port *port)
+void run_all_sm(struct port *port, struct lldp_agent *agent)
 {
 	struct ieee8021qaz_tlvs *tlvs;
 	struct ieee_ets *ets;
@@ -1004,7 +1020,8 @@ void run_all_sm(struct port *port)
 	if (!tlvs)
 		return;
 
-	if (!is_tlv_txdisabled(port->ifname, TLVID_8021(LLDP_8021QAZ_ETSCFG))) {
+	if (!is_tlv_txdisabled(port->ifname,
+			       TLVID_8021(LLDP_8021QAZ_ETSCFG))) {
 		ets_sm(tlvs->ets->cfgl, tlvs->ets->recr,
 		       &tlvs->ets->current_state);
 	}
@@ -1023,7 +1040,8 @@ void run_all_sm(struct port *port)
 	else
 		ets_cfg_to_ieee(ets, tlvs->ets->cfgl);
 
-	if (!is_tlv_txdisabled(port->ifname, TLVID_8021(LLDP_8021QAZ_PFC)))
+	if (!is_tlv_txdisabled(port->ifname,
+			       TLVID_8021(LLDP_8021QAZ_PFC)))
 		pfc_sm(tlvs);
 
 	if (tlvs->pfc->current_state == RX_RECOMMEND)
@@ -1281,7 +1299,8 @@ error:
  * ieee8021qaz_bld_tlv - builds all IEEE8021QAZ TLVs
  * Returns 1 on success, NULL if any of the TLVs fail to build correctly.
  */
-static struct packed_tlv *ieee8021qaz_bld_tlv(struct port *port)
+static struct packed_tlv *ieee8021qaz_bld_tlv(struct port *port,
+					      struct lldp_agent *agent)
 {
 	struct ieee8021qaz_tlvs *data;
 	struct packed_tlv *ptlv = NULL;
@@ -1297,13 +1316,17 @@ static struct packed_tlv *ieee8021qaz_bld_tlv(struct port *port)
 	if (!data->active)
 		return ptlv;
 
-	if (!is_tlv_txdisabled(port->ifname, TLVID_8021(LLDP_8021QAZ_ETSCFG)))
+	if (!is_tlv_txdisabled(port->ifname,
+			       TLVID_8021(LLDP_8021QAZ_ETSCFG)))
 		etscfg_tlv = bld_ieee8021qaz_etscfg_tlv(data);
-	if (is_tlv_txenabled(port->ifname, TLVID_8021(LLDP_8021QAZ_ETSREC)))
+	if (is_tlv_txenabled(port->ifname,
+			     TLVID_8021(LLDP_8021QAZ_ETSREC)))
 		etsrec_tlv = bld_ieee8021qaz_etsrec_tlv(data);
-	if (!is_tlv_txdisabled(port->ifname, TLVID_8021(LLDP_8021QAZ_PFC)))
+	if (!is_tlv_txdisabled(port->ifname,
+			       TLVID_8021(LLDP_8021QAZ_PFC)))
 		pfc_tlv = bld_ieee8021qaz_pfc_tlv(data);
-	if (is_tlv_txenabled(port->ifname, TLVID_8021(LLDP_8021QAZ_APP)))
+	if (is_tlv_txenabled(port->ifname,
+			     TLVID_8021(LLDP_8021QAZ_APP)))
 		app_tlv = bld_ieee8021qaz_app_tlv(port->ifname);
 
 	size = TLVSIZE(etscfg_tlv)
@@ -1333,18 +1356,21 @@ err:
 }
 
 /* LLDP_8021QAZ_MOD_OPS - GETTLV */
-struct packed_tlv *ieee8021qaz_gettlv(struct port *port)
+struct packed_tlv *ieee8021qaz_gettlv(struct port *port,
+				      struct lldp_agent *agent)
 {
 	struct packed_tlv *ptlv = NULL;
 
 	/* Update TLV State Machines */
-	run_all_sm(port);
+	run_all_sm(port, agent);
 	/* Build TLVs */
-	ptlv = ieee8021qaz_bld_tlv(port);
+	ptlv = ieee8021qaz_bld_tlv(port, agent);
 	return ptlv;
 }
 
-static bool unpack_ieee8021qaz_tlvs(struct port *port, struct unpacked_tlv *tlv)
+static bool unpack_ieee8021qaz_tlvs(struct port *port,
+				    struct lldp_agent *agent,
+				    struct unpacked_tlv *tlv)
 {
 	/* Unpack tlvs and store in rx */
 	struct ieee8021qaz_tlvs *tlvs;
@@ -1360,7 +1386,7 @@ static bool unpack_ieee8021qaz_tlvs(struct port *port, struct unpacked_tlv *tlv)
 		} else {
 			LLDPAD_WARN("%s: %s: 802.1Qaz Duplicate ETSCFG TLV\n",
 				__func__, port->ifname);
-			port->rx.dupTlvs |= DUP_IEEE8021QAZ_TLV_ETSCFG;
+			agent->rx.dupTlvs |= DUP_IEEE8021QAZ_TLV_ETSCFG;
 			return false;
 		}
 		break;
@@ -1371,7 +1397,7 @@ static bool unpack_ieee8021qaz_tlvs(struct port *port, struct unpacked_tlv *tlv)
 		} else {
 			LLDPAD_WARN("%s: %s: 802.1Qaz Duplicate ETSREC TLV\n",
 				__func__, port->ifname);
-			port->rx.dupTlvs |= DUP_IEEE8021QAZ_TLV_ETSREC;
+			agent->rx.dupTlvs |= DUP_IEEE8021QAZ_TLV_ETSREC;
 			return false;
 		}
 		break;
@@ -1383,7 +1409,7 @@ static bool unpack_ieee8021qaz_tlvs(struct port *port, struct unpacked_tlv *tlv)
 		} else {
 			LLDPAD_WARN("%s: %s: 802.1Qaz Duplicate PFC TLV\n",
 				__func__, port->ifname);
-			port->rx.dupTlvs |= DUP_IEEE8021QAZ_TLV_PFC;
+			agent->rx.dupTlvs |= DUP_IEEE8021QAZ_TLV_PFC;
 			return false;
 		}
 		break;
@@ -1394,7 +1420,7 @@ static bool unpack_ieee8021qaz_tlvs(struct port *port, struct unpacked_tlv *tlv)
 		} else {
 			LLDPAD_WARN("%s: %s: 802.1Qaz Duplicate APP TLV\n",
 				    __func__, port->ifname);
-			port->rx.dupTlvs |= DUP_IEEE8021QAZ_TLV_APP;
+			agent->rx.dupTlvs |= DUP_IEEE8021QAZ_TLV_APP;
 			return false;
 		}
 		break;
@@ -1701,7 +1727,8 @@ static void ieee8021qaz_mibUpdateObjects(struct port *port)
  * TLVs not consumed on error otherwise it is either free'd or stored
  * internally in the module.
  */
-int ieee8021qaz_rchange(struct port *port, struct unpacked_tlv *tlv)
+int ieee8021qaz_rchange(struct port *port, struct lldp_agent *agent,
+			struct unpacked_tlv *tlv)
 {
 	u8 oui[OUI_SIZE] = INIT_IEEE8021QAZ_OUI;
 	struct ieee8021qaz_tlvs *qaz_tlvs;
@@ -1738,7 +1765,7 @@ int ieee8021qaz_rchange(struct port *port, struct unpacked_tlv *tlv)
 			return SUBTYPE_INVALID;
 
 		l2_packet_get_remote_addr(port->l2, qaz_tlvs->remote_mac);
-		res = unpack_ieee8021qaz_tlvs(port, tlv);
+		res = unpack_ieee8021qaz_tlvs(port, agent, tlv);
 		if (!res)
 			LLDPAD_WARN("Error unpacking 8021 tlvs");
 		else
@@ -1761,11 +1788,13 @@ int ieee8021qaz_rchange(struct port *port, struct unpacked_tlv *tlv)
 			 */
 			long adminstatus;
 			if (qaz_tlvs->ieee8021qazdu &&
-				get_config_setting(qaz_tlvs->ifname,
+				get_config_setting_by_agent(qaz_tlvs->ifname,
+						   agent->type,
 						   ARG_ADMINSTATUS,
 						   (void *)&adminstatus,
 						   CONFIG_TYPE_INT) &&
-				get_lldp_port_admin(qaz_tlvs->ifname) ==
+				get_lldp_agent_admin(qaz_tlvs->ifname,
+						     agent->type) ==
 						    enabledRxOnly) {
 				adminstatus = enabledRxTx;
 				if (set_config_setting(qaz_tlvs->ifname,
@@ -1773,7 +1802,8 @@ int ieee8021qaz_rchange(struct port *port, struct unpacked_tlv *tlv)
 						      (void *)&adminstatus,
 						       CONFIG_TYPE_INT) ==
 						       cmd_success)
-					set_lldp_port_admin(qaz_tlvs->ifname,
+					set_lldp_agent_admin(qaz_tlvs->ifname,
+							     agent->type,
 							    (int)adminstatus);
 			}
 			if (qaz_tlvs->ieee8021qazdu)
@@ -1781,9 +1811,9 @@ int ieee8021qaz_rchange(struct port *port, struct unpacked_tlv *tlv)
 
 			/* Update TLV State Machines */
 			ieee8021qaz_mibUpdateObjects(port);
-			run_all_sm(port);
+			run_all_sm(port, agent);
 			clear_ieee8021qaz_rx(qaz_tlvs);
-			somethingChangedLocal(port->ifname);
+			somethingChangedLocal(port->ifname, agent->type);
 		}
 	}
 
@@ -1816,7 +1846,7 @@ static void ieee8021qaz_free_rx(struct ieee8021qaz_unpkd_tlvs *rx)
  *     - If yes, set it as absent (delete it?)
  * Same for PFC and APP.
  */
-u8 ieee8021qaz_mibDeleteObject(struct port *port)
+u8 ieee8021qaz_mibDeleteObject(struct port *port, struct lldp_agent *agent)
 {
 	struct ieee8021qaz_tlvs *tlvs;
 
@@ -1849,7 +1879,7 @@ u8 ieee8021qaz_mibDeleteObject(struct port *port)
 	ieee8021qaz_app_reset(&tlvs->app_head);
 
 	/* Kick Tx State Machine */
-	somethingChangedLocal(port->ifname);
+	somethingChangedLocal(port->ifname, agent->type);
 	return 0;
 }
 
@@ -1927,7 +1957,7 @@ void ieee8021qaz_unregister(struct lldp_module *mod)
 /*
  * LLDP_8021QAZ_MOD_OPS - IFDOWN
  */
-void ieee8021qaz_ifdown(char *device_name)
+void ieee8021qaz_ifdown(char *device_name, struct lldp_agent *agent)
 {
 	struct port *port = NULL;
 	struct ieee8021qaz_tlvs *tlvs;
diff --git a/lldp_8021qaz_cmds.c b/lldp_8021qaz_cmds.c
index 04556c2..1a64c24 100644
--- a/lldp_8021qaz_cmds.c
+++ b/lldp_8021qaz_cmds.c
@@ -200,7 +200,7 @@ static int _set_arg_willing(struct cmd *cmd, char *args,
 	snprintf(arg_path, sizeof(arg_path), "%s%08x.%s", TLVID_PREFIX,
 		 cmd->tlvid, args);
 	set_config_setting(cmd->ifname, arg_path, &willing, CONFIG_TYPE_INT);
-	somethingChangedLocal(cmd->ifname);
+	somethingChangedLocal(cmd->ifname, cmd->type);
 
 	return cmd_success;
 }
@@ -384,7 +384,7 @@ static int _set_arg_up2tc(struct cmd *cmd, char *args,
 		 cmd->tlvid, args);
 	set_config_setting(cmd->ifname, arg_path, &arg_value,
 			   CONFIG_TYPE_STRING);
-	somethingChangedLocal(cmd->ifname);
+	somethingChangedLocal(cmd->ifname, cmd->type);
 invalid:
 	free(parse);
 	return err;
@@ -511,7 +511,7 @@ static int _set_arg_tcbw(struct cmd *cmd, char *args,
 		 cmd->tlvid, args);
 	set_config_setting(cmd->ifname, arg_path, &arg_value,
 			   CONFIG_TYPE_STRING);
-	somethingChangedLocal(cmd->ifname);
+	somethingChangedLocal(cmd->ifname, cmd->type);
 invalid:
 	free(parse);
 	return err;
@@ -705,7 +705,7 @@ static int _set_arg_tsa(struct cmd *cmd, char *args, char *arg_value,
 		 TLVID_PREFIX, cmd->tlvid, args);
 	set_config_setting(cmd->ifname, arg_path, &arg_value,
 			   CONFIG_TYPE_STRING);
-	somethingChangedLocal(cmd->ifname);
+	somethingChangedLocal(cmd->ifname, cmd->type);
 invalid:
 	free(parse);
 	return err;
@@ -846,7 +846,7 @@ static int _set_arg_enabled(struct cmd *cmd, char *args,
 		 "%s%08x.%s", TLVID_PREFIX, cmd->tlvid, args);
 	set_config_setting(cmd->ifname, arg_path, &mask, CONFIG_TYPE_INT);
 	tlvs->pfc->local.pfc_enable = mask;
-	somethingChangedLocal(cmd->ifname);
+	somethingChangedLocal(cmd->ifname, cmd->type);
 invalid:
 	free(parse);
 	return err;
@@ -927,7 +927,7 @@ static int _set_arg_delay(struct cmd *cmd, char *args,
 		 "%s%08x.%s", TLVID_PREFIX, cmd->tlvid, args);
 	set_config_setting(cmd->ifname, arg_path, &delay, CONFIG_TYPE_INT);
 
-	somethingChangedLocal(cmd->ifname);
+	somethingChangedLocal(cmd->ifname, cmd->type);
 
 	return cmd_success;
 }
@@ -1173,7 +1173,7 @@ static int _set_arg_app(struct cmd *cmd, char *args, char *arg_value,
 		i++;
 	}
 
-	somethingChangedLocal(cmd->ifname);
+	somethingChangedLocal(cmd->ifname, cmd->type);
 
 	if (cmd->ops & op_delete)
 		return cmd_success;
@@ -1299,7 +1299,7 @@ static int _set_arg_tlvtxenable(struct cmd *cmd, char *arg, char *argvalue,
 		return cmd_failed;
 
 
-	somethingChangedLocal(cmd->ifname);
+	somethingChangedLocal(cmd->ifname, cmd->type);
 
 	return cmd_success;
 }
diff --git a/lldp_8023.c b/lldp_8023.c
index 2f521b3..a6c2eb8 100644
--- a/lldp_8023.c
+++ b/lldp_8023.c
@@ -79,7 +79,7 @@ static const struct lldp_mod_ops ieee8023_ops =  {
 	.get_arg_handler	= ieee8023_get_arg_handlers,
 };
 
-static struct ieee8023_data *ieee8023_data(const char *ifname)
+static struct ieee8023_data *ieee8023_data(const char *ifname, enum agent_type type)
 {
 	struct ieee8023_user_data *ud;
 	struct ieee8023_data *bd = NULL;
@@ -87,7 +87,8 @@ static struct ieee8023_data *ieee8023_data(const char *ifname)
 	ud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_8023);
 	if (ud) {
 		LIST_FOREACH(bd, &ud->head, entry) {
-			if (!strncmp(ifname, bd->ifname, IFNAMSIZ))
+			if (!strncmp(ifname, bd->ifname, IFNAMSIZ) &&
+			    (type == bd->agenttype))
 				return bd;
 		}
 	}
@@ -350,17 +351,18 @@ static void ieee8023_free_data(struct ieee8023_user_data *ud)
 			LIST_REMOVE(bd, entry);
 			ieee8023_free_tlv(bd);
 			free(bd);
- 		}
+		}
 	}
 }
 
-struct packed_tlv *ieee8023_gettlv(struct port *port)
+struct packed_tlv *ieee8023_gettlv(struct port *port,
+				   struct lldp_agent *agent)
 {
 	int size;
 	struct ieee8023_data *bd;
 	struct packed_tlv *ptlv = NULL;
 
-	bd = ieee8023_data(port->ifname);
+	bd = ieee8023_data(port->ifname, agent->type);
 	if (!bd)
 		goto out_err;
 
@@ -401,11 +403,11 @@ out_err:
 }
 
 
-void ieee8023_ifdown(char *ifname)
+void ieee8023_ifdown(char *ifname, struct lldp_agent *agent)
 {
 	struct ieee8023_data *bd;
 
-	bd = ieee8023_data(ifname);
+	bd = ieee8023_data(ifname, agent->type);
 	if (!bd)
 		goto out_err;
 
@@ -420,12 +422,12 @@ out_err:
 	return;
 }
 
-void ieee8023_ifup(char *ifname)
+void ieee8023_ifup(char *ifname, struct lldp_agent *agent)
 {
 	struct ieee8023_data *bd;
 	struct ieee8023_user_data *ud;
 
-	bd = ieee8023_data(ifname);
+	bd = ieee8023_data(ifname, agent->type);
 	if (bd) {
 		LLDPAD_INFO("%s:%s exists\n", __func__, ifname);
 		goto out_err;
@@ -440,6 +442,8 @@ void ieee8023_ifup(char *ifname)
 	}
 	memset(bd, 0, sizeof(struct ieee8023_data));
 	strncpy(bd->ifname, ifname, IFNAMSIZ);
+	bd->agenttype = agent->type;
+
 	if (ieee8023_bld_tlv(bd)) {
 		LLDPAD_INFO("%s:%s mand_bld_tlv failed\n", __func__, ifname);
 		free(bd);
diff --git a/lldp_8023_cmds.c b/lldp_8023_cmds.c
index 08927a7..e7d16a4 100644
--- a/lldp_8023_cmds.c
+++ b/lldp_8023_cmds.c
@@ -129,7 +129,7 @@ static int _set_arg_tlvtxenable(struct cmd *cmd, char *arg, char *argvalue,
 		return cmd_failed;
 
 	sprintf(obuf + strlen(obuf), "enableTx = %s\n", value ? "yes" : "no");
-	somethingChangedLocal(cmd->ifname);
+	somethingChangedLocal(cmd->ifname, cmd->type);
 
 	return cmd_success;
 }
diff --git a/lldp_basman.c b/lldp_basman.c
index 2de70e6..13b7d38 100644
--- a/lldp_basman.c
+++ b/lldp_basman.c
@@ -86,7 +86,7 @@ static const struct lldp_mod_ops basman_ops =  {
 	.get_arg_handler	= basman_get_arg_handlers,
 };
 
-static struct basman_data *basman_data(const char *ifname)
+static struct basman_data *basman_data(const char *ifname, enum agent_type type)
 {
 	struct basman_user_data *bud;
 	struct basman_data *bd = NULL;
@@ -94,7 +94,8 @@ static struct basman_data *basman_data(const char *ifname)
 	bud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_BASIC);
 	if (bud) {
 		LIST_FOREACH(bd, &bud->head, entry) {
-			if (!strncmp(ifname, bd->ifname, IFNAMSIZ))
+			if (!strncmp(ifname, bd->ifname, IFNAMSIZ) &&
+			    (type == bd->agenttype))
 				return bd;
 		}
 	}
@@ -573,14 +574,14 @@ static void basman_free_data(struct basman_user_data *bud)
 	}
 }
 
-struct packed_tlv *basman_gettlv(struct port *port)
+struct packed_tlv *basman_gettlv(struct port *port, struct lldp_agent *agent)
 {
 	int i;
 	int size;
 	struct basman_data *bd;
 	struct packed_tlv *ptlv = NULL;
 
-	bd = basman_data(port->ifname);
+	bd = basman_data(port->ifname, agent->type);
 	if (!bd)
 		goto out_err;
 
@@ -630,11 +631,11 @@ out_err:
 	return NULL;
 }
 
-void basman_ifdown(char *ifname)
+void basman_ifdown(char *ifname, struct lldp_agent *agent)
 {
 	struct basman_data *bd;
 
-	bd = basman_data(ifname);
+	bd = basman_data(ifname, agent->type);
 	if (!bd)
 		goto out_err;
 
@@ -648,12 +649,12 @@ out_err:
 	return;
 }
 
-void basman_ifup(char *ifname)
+void basman_ifup(char *ifname, struct lldp_agent *agent)
 {
 	struct basman_data *bd;
 	struct basman_user_data *bud;
 
-	bd = basman_data(ifname);
+	bd = basman_data(ifname, agent->type);
 	if (bd) {
 		LLDPAD_DBG("%s:%s exists\n", __func__, ifname);
 		goto out_err;
@@ -668,6 +669,8 @@ void basman_ifup(char *ifname)
 	}
 	memset(bd, 0, sizeof(struct basman_data));
 	strncpy(bd->ifname, ifname, IFNAMSIZ);
+	bd->agenttype = agent->type;
+
 	if (basman_bld_tlv(bd)) {
 		LLDPAD_DBG("%s:%s mand_bld_tlv failed\n", __func__, ifname);
 		free(bd);
diff --git a/lldp_basman_cmds.c b/lldp_basman_cmds.c
index b04ff48..bb3e5be 100644
--- a/lldp_basman_cmds.c
+++ b/lldp_basman_cmds.c
@@ -142,7 +142,7 @@ static int _set_arg_tlvtxenable(struct cmd *cmd, char *arg, char *argvalue,
 
 	sprintf(obuf + strlen(obuf), "enableTx = %s\n", value ? "yes" : "no");
 
-	somethingChangedLocal(cmd->ifname);
+	somethingChangedLocal(cmd->ifname, cmd->type);
 
 	return cmd_success;
 }
@@ -239,7 +239,7 @@ int _set_arg_ipv4(struct cmd *cmd, char *arg, char *argvalue,
 
 	sprintf(obuf + strlen(obuf), "ipv4 = %s", argvalue);
 
-	somethingChangedLocal(cmd->ifname);
+	somethingChangedLocal(cmd->ifname, cmd->type);
 
 	return cmd_success;
 }
@@ -281,7 +281,7 @@ int _set_arg_ipv6(struct cmd *cmd, char *arg, char *argvalue,
 		return cmd_failed;
 
 	sprintf(obuf + strlen(obuf), "ipv6 = %s", argvalue);
-	somethingChangedLocal(cmd->ifname);
+	somethingChangedLocal(cmd->ifname, cmd->type);
 
 	return cmd_success;
 }
diff --git a/lldp_dcbx.c b/lldp_dcbx.c
index 7949147..c2011ff 100644
--- a/lldp_dcbx.c
+++ b/lldp_dcbx.c
@@ -30,6 +30,8 @@
 #include "linux/if.h"
 #include "include/linux/dcbnl.h"
 #include "lldp.h"
+#include "lldp/ports.h"
+#include "lldp/states.h"
 #include "dcb_types.h"
 #include "lldp_dcbx.h"
 #include "dcb_protocol.h"
@@ -41,8 +43,6 @@
 #include "clif_msgs.h"
 #include "lldp_mod.h"
 #include "lldp_mand_clif.h"
-#include "lldp/ports.h"
-#include "lldp/states.h"
 #include "lldp_dcbx_nl.h"
 #include "lldp_dcbx_cfg.h"
 #include "lldp_dcbx_cmds.h"
@@ -55,11 +55,11 @@
 extern u8 gdcbx_subtype;
 
 void dcbx_free_tlv(struct dcbx_tlvs *tlvs);
-static int dcbx_check_operstate(struct port *port);
+static int dcbx_check_operstate(struct port *port, struct lldp_agent *agent);
 
 const struct lldp_mod_ops dcbx_ops = {
-	.lldp_mod_register 	= dcbx_register,
-	.lldp_mod_unregister 	= dcbx_unregister,
+	.lldp_mod_register	= dcbx_register,
+	.lldp_mod_unregister	= dcbx_unregister,
 	.lldp_mod_gettlv	= dcbx_gettlv,
 	.lldp_mod_rchange	= dcbx_rchange,
 	.lldp_mod_ifup		= dcbx_ifup,
@@ -70,7 +70,7 @@ const struct lldp_mod_ops dcbx_ops = {
 	.timer			= dcbx_check_operstate,
 };
 
-static int dcbx_check_operstate(struct port *port)
+static int dcbx_check_operstate(struct port *port, struct lldp_agent *agent)
 {
 	int err;
 	u8 app_good = 0;
@@ -78,7 +78,7 @@ static int dcbx_check_operstate(struct port *port)
 	app_attribs app_data;
 	pfc_attribs pfc_data;
 
-	if (!port->portEnabled || !port->timers.dormantDelay)
+	if (!port->portEnabled || !port->dormantDelay)
 		return 0;
 
 	err = get_app(port->ifname, 0, &app_data);
@@ -95,10 +95,10 @@ static int dcbx_check_operstate(struct port *port)
 	    !app_data.protocol.Enable)
 		app_good = 1;
 
-	if ((pfc_good && app_good) || port->timers.dormantDelay == 1) {
+	if ((pfc_good && app_good) || port->dormantDelay == 1) {
 		LLDPAD_DBG("%s: %s: IF_OPER_UP delay, %u pfc oper %u"
 			   "app oper %u\n",
-			__func__, port->ifname, port->timers.dormantDelay,
+			__func__, port->ifname, port->dormantDelay,
 			pfc_data.protocol.OperMode,
 			app_data.protocol.OperMode);
 		set_operstate(port->ifname, IF_OPER_UP);
@@ -122,7 +122,7 @@ struct dcbx_tlvs *dcbx_data(const char *ifname)
 				return tlv;
 		}
 	}
-	
+
 	return NULL;
 }
 
@@ -258,7 +258,7 @@ void dcbx_free_manifest(struct dcbx_manifest *manifest)
 {
 	if (!manifest)
 		return;
-	
+
 	if (manifest->dcbx1)
 		manifest->dcbx1 = free_unpkd_tlv(manifest->dcbx1);
 	if (manifest->dcbx2)
@@ -323,7 +323,7 @@ void dcbx_free_tlv(struct dcbx_tlvs *tlvs)
 	return;
 }
 
-struct packed_tlv* dcbx_gettlv(struct port *port)
+struct packed_tlv* dcbx_gettlv(struct port *port, struct lldp_agent *agent)
 {
 	struct packed_tlv *ptlv = NULL;
 	struct dcbx_tlvs *tlvs;
@@ -453,7 +453,7 @@ void dcbx_unregister(struct lldp_module *mod)
 	LLDPAD_DBG("%s: unregister dcbx complete.\n", __func__);
 }
 
-void dcbx_ifup(char *ifname)
+void dcbx_ifup(char *ifname, struct lldp_agent *agent)
 {
 	struct port *port = NULL;
 	struct dcbx_tlvs *tlvs;
@@ -469,15 +469,10 @@ void dcbx_ifup(char *ifname)
 	if (is_bond(ifname) || is_vlan(ifname))
 		return;
 
-	port = porthead;
-	while (port != NULL) {
-		if (!strncmp(ifname, port->ifname, MAX_DEVICE_NAME_LEN))
-			break;
-		port = port->next;
-	}
+	port = port_find_by_name(ifname);
 
 	dud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_DCBX);
-	tlvs = dcbx_data(ifname);	
+	tlvs = dcbx_data(ifname);
 
 	if (!port)
 		return;
@@ -522,7 +517,7 @@ void dcbx_ifup(char *ifname)
 		if (set_config_setting(ifname, ARG_ADMINSTATUS,
 			              (void *)&adminstatus, CONFIG_TYPE_INT) ==
 				       cmd_success)
-			set_lldp_port_admin(ifname, (int)adminstatus);
+			set_lldp_agent_admin(ifname, agent->type, (int)adminstatus);
 	}
 
 	tlvs = malloc(sizeof(*tlvs));
@@ -531,7 +526,7 @@ void dcbx_ifup(char *ifname)
 		return;
 	}
 	memset(tlvs, 0, sizeof(*tlvs));
-		
+
 	manifest = malloc(sizeof(*manifest));
 	if (!manifest) {
 		free(tlvs);
@@ -545,7 +540,7 @@ void dcbx_ifup(char *ifname)
 	tlvs->port = port;
 	tlvs->dcbdu = 0;
 	tlvs->dcbx_st = gdcbx_subtype & MASK_DCBX_FORCE;
-	LIST_INSERT_HEAD(&dud->head, tlvs, entry);		
+	LIST_INSERT_HEAD(&dud->head, tlvs, entry);
 
 initialized:
 	dcbx_add_adapter(ifname);
@@ -586,7 +581,7 @@ initialized:
 	return;
 }
 
-void dcbx_ifdown(char *device_name)
+void dcbx_ifdown(char *device_name, struct lldp_agent *agent)
 {
 	struct port *port = NULL;
 	struct dcbx_tlvs *tlvs;
@@ -658,7 +653,7 @@ void clear_dcbx_manifest(struct dcbx_tlvs *dcbx)
  * TLV not consumed on error otherwise it is either free'd or stored
  * internally in the module.
  */
-int dcbx_rchange(struct port *port,  struct unpacked_tlv *tlv)
+int dcbx_rchange(struct port *port, struct lldp_agent *agent, struct unpacked_tlv *tlv)
 {
 	u8 oui[DCB_OUI_LEN] = INIT_DCB_OUI;
 	struct dcbx_tlvs *dcbx;
@@ -667,15 +662,18 @@ int dcbx_rchange(struct port *port,  struct unpacked_tlv *tlv)
 
 	dcbx = dcbx_data(port->ifname);
 
+	if (agent == NULL)
+		return SUBTYPE_INVALID;
+
 	if (!dcbx)
 		return SUBTYPE_INVALID;
 
-	/* 
- 	 * TYPE_1 is _mandatory_ and will always be before the 
- 	 * DCBX TLV so we can use it to mark the begining of a
- 	 * pdu for dcbx to verify only a single DCBX TLV is 
- 	 * present
- 	 */ 
+	/*
+	 * TYPE_1 is _mandatory_ and will always be before the
+	 * DCBX TLV so we can use it to mark the begining of a
+	 * pdu for dcbx to verify only a single DCBX TLV is
+	 * present
+	 */
 	if (tlv->type == TYPE_1) {
 		manifest = malloc(sizeof(*manifest));
 		memset(manifest, 0, sizeof(*manifest));
@@ -695,25 +693,25 @@ int dcbx_rchange(struct port *port,  struct unpacked_tlv *tlv)
 
 		if (dcbx->dcbx_st == dcbx_subtype2) {
 			if ((tlv->info[DCB_OUI_LEN] == dcbx_subtype2)
-				&& (port->lldpdu & RCVD_LLDP_DCBX2_TLV)){
+				&& (agent->lldpdu & RCVD_LLDP_DCBX2_TLV)){
 				LLDPAD_INFO("Received duplicate DCBX TLVs\n");
 				return TLV_ERR;
 			}
 		}
 		if ((tlv->info[DCB_OUI_LEN] == dcbx_subtype1)
-			&& (port->lldpdu & RCVD_LLDP_DCBX1_TLV)) {
+			&& (agent->lldpdu & RCVD_LLDP_DCBX1_TLV)) {
 			LLDPAD_INFO("Received duplicate DCBX TLVs\n");
 			return TLV_ERR;
 		}
 
 		if ((dcbx->dcbx_st == dcbx_subtype2) &&
 			(tlv->info[DCB_OUI_LEN] == dcbx_subtype2)) {
-			port->lldpdu |= RCVD_LLDP_DCBX2_TLV;
+			agent->lldpdu |= RCVD_LLDP_DCBX2_TLV;
 			dcbx->manifest->dcbx2 = tlv;
 			dcbx->rxed_tlvs = true;
 			return TLV_OK;
 		} else if (tlv->info[DCB_OUI_LEN] == dcbx_subtype1) {
-			port->lldpdu |= RCVD_LLDP_DCBX1_TLV;
+			agent->lldpdu |= RCVD_LLDP_DCBX1_TLV;
 			dcbx->manifest->dcbx1 = tlv;
 			dcbx->rxed_tlvs = true;
 			return TLV_OK;
@@ -735,7 +733,7 @@ int dcbx_rchange(struct port *port,  struct unpacked_tlv *tlv)
 				      DCB_CAP_DCBX_HOST | DCB_CAP_DCBX_VER_CEE);
 			set_hw_state(port->ifname, 1);
 			dcbx->active = true;
-			somethingChangedLocal(port->ifname);
+			somethingChangedLocal(port->ifname, agent->type);
 		}
 
 		/* Only process DCBXv2 or DCBXv1 but not both this
@@ -744,21 +742,21 @@ int dcbx_rchange(struct port *port,  struct unpacked_tlv *tlv)
 		 * not match across versions.
 		 */
 		if (dcbx->manifest->dcbx2) {
-			res = unpack_dcbx2_tlvs(port, dcbx->manifest->dcbx2);
+			res = unpack_dcbx2_tlvs(port, agent, dcbx->manifest->dcbx2);
 			if (!res) {
 				LLDPAD_DBG("Error unpacking the DCBX2"
 					"TLVs - Discarding LLDPDU\n");
 				return TLV_ERR;
 			}
-			mibUpdateObjects(port);
+			mibUpdateObjects(port, agent);
 		} else if (dcbx->manifest->dcbx1) {
-			res = unpack_dcbx1_tlvs(port, dcbx->manifest->dcbx1);
+			res = unpack_dcbx1_tlvs(port, agent, dcbx->manifest->dcbx1);
 			if (!res) {
 				LLDPAD_DBG("Error unpacking the DCBX1"
 					"TLVs - Discarding LLDPDU\n");
 				return TLV_ERR;
 			}
-			mibUpdateObjects(port);
+			mibUpdateObjects(port, agent);
 		}
 
 		clear_dcbx_manifest(dcbx);
@@ -771,7 +769,7 @@ int dcbx_rchange(struct port *port,  struct unpacked_tlv *tlv)
 	return SUBTYPE_INVALID;
 }
 
-u8 dcbx_mibDeleteObjects(struct port *port)
+u8 dcbx_mibDeleteObjects(struct port *port, struct lldp_agent *agent)
 {
 	control_protocol_attribs  peer_control;
 	pg_attribs  peer_pg;
@@ -814,7 +812,7 @@ u8 dcbx_mibDeleteObjects(struct port *port)
 			}
 		} else {
 			return (u8)-1;
-  		}
+		}
 	}
 
 	if (get_peer_llink(port->ifname, subtype, &peer_llink) == dcb_success) {
diff --git a/lldp_dcbx_cmds.c b/lldp_dcbx_cmds.c
index 9ec671e..ee9dbcf 100644
--- a/lldp_dcbx_cmds.c
+++ b/lldp_dcbx_cmds.c
@@ -73,7 +73,7 @@ static int get_llink_data(llink_attribs *llink_data, int cmd, char *port_id,
 static dcb_result get_bwg_desc(char *port_id, char *ibuf, int ilen, char *rbuf);
 static dcb_result set_bwg_desc(char *port_id, char *ibuf, int ilen);
 static void set_protocol_data(feature_protocol_attribs *protocol, char *ifname,
-		char *ibuf, int plen);
+		char *ibuf, int plen, int agenttype);
 static dcb_result get_cmd_protocol_data(feature_protocol_attribs *protocol,
 	u8 cmd, char *rbuf);
 
@@ -207,7 +207,7 @@ static int _set_arg_tlvtxenable(struct cmd *cmd, char *arg, char *argvalue,
 		return cmd_failed;
 
 	dont_advertise_dcbx_all(cmd->ifname, value);
-	somethingChangedLocal(cmd->ifname);
+	somethingChangedLocal(cmd->ifname, cmd->type);
 
 	return cmd_success;
 }
@@ -377,7 +377,7 @@ static dcb_result set_bwg_desc(char *port_id, char *ibuf, int ilen)
 }
 
 static void set_protocol_data(feature_protocol_attribs *protocol, char *ifname,
-			      char *ibuf, int plen)
+			      char *ibuf, int plen, int type)
 {
 	u8 flag;
 	int last;
@@ -393,7 +393,7 @@ static void set_protocol_data(feature_protocol_attribs *protocol, char *ifname,
 		if (last != protocol->Advertise && protocol->Advertise) {
 			tlv_enabletx(ifname, (OUI_CEE_DCBX << 8) |
 				     protocol->dcbx_st);
-			somethingChangedLocal(ifname);
+			somethingChangedLocal(ifname, type);
 		}
 	}
 
@@ -563,7 +563,7 @@ int dcbx_clif_cmd(void *data,
 				status = dcb_invalid_cmd;
 			} else {
 				set_protocol_data(&pg_data.protocol, port_id,
-						  ibuf, plen);
+						  ibuf, plen, NEAREST_BRIDGE);
 				status = set_pg_config(&pg_data, port_id, ibuf,
 					ilen);
 			}
@@ -596,7 +596,7 @@ int dcbx_clif_cmd(void *data,
 				status = dcb_failed;
 			} else {
 				set_protocol_data(&pfc_data.protocol, port_id,
-						  ibuf, plen);
+						  ibuf, plen, NEAREST_BRIDGE);
 				status = set_pfc_config(&pfc_data, port_id,
 					ibuf, ilen);
 			}
@@ -630,7 +630,7 @@ int dcbx_clif_cmd(void *data,
 				status = dcb_failed;
 			} else {
 				set_protocol_data(&app_data.protocol, port_id,
-						  ibuf, plen);
+						  ibuf, plen, NEAREST_BRIDGE);
 				status = set_app_config(&app_data, port_id,
 					(u32)subtype, ibuf, ilen);
 			}
@@ -664,7 +664,7 @@ int dcbx_clif_cmd(void *data,
 				status = dcb_failed;
 			} else {
 				set_protocol_data(&llink_data.protocol, port_id,
-						  ibuf, plen);
+						  ibuf, plen, NEAREST_BRIDGE);
 				status = set_llink_config(&llink_data, port_id,
 					(u32)subtype, ibuf, ilen);
 			}
diff --git a/lldp_evb.c b/lldp_evb.c
index fe43af5..b1f170d 100644
--- a/lldp_evb.c
+++ b/lldp_evb.c
@@ -47,7 +47,7 @@
 
 extern struct lldp_head lldp_head;
 
-struct evb_data *evb_data(char *ifname)
+struct evb_data *evb_data(char *ifname, enum agent_type type)
 {
 	struct evb_user_data *ud;
 	struct evb_data *ed = NULL;
@@ -55,7 +55,8 @@ struct evb_data *evb_data(char *ifname)
 	ud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_EVB);
 	if (ud) {
 		LIST_FOREACH(ed, &ud->head, entry) {
-			if (!strncmp(ifname, ed->ifname, IFNAMSIZ))
+			if (!strncmp(ifname, ed->ifname, IFNAMSIZ) &&
+			    (type == ed->agenttype))
 				return ed;
 		}
 	}
@@ -99,7 +100,7 @@ static void evb_dump_tlv(struct unpacked_tlv *tlv)
 
 unsigned int evb_get_rte(char *ifname)
 {
-	struct evb_data *ed = evb_data(ifname);
+	struct evb_data *ed = evb_data(ifname, NEAREST_CUSTOMER_BRIDGE);
 
 	return (unsigned int) ed->tie->rte;
 }
@@ -356,13 +357,13 @@ static void evb_free_data(struct evb_user_data *ud)
 	}
 }
 
-struct packed_tlv *evb_gettlv(struct port *port)
+struct packed_tlv *evb_gettlv(struct port *port, struct lldp_agent *agent)
 {
 	int size;
 	struct evb_data *ed;
 	struct packed_tlv *ptlv = NULL;
 
-	ed = evb_data(port->ifname);
+	ed = evb_data(port->ifname, agent->type);
 	if (!ed)
 		goto out_err;
 
@@ -490,12 +491,13 @@ int evb_check_and_fill(struct evb_data *ed, struct tlv_info_evb *tie)
  *
  * TLV not consumed on error
  */
-static int evb_rchange(struct port *port, struct unpacked_tlv *tlv)
+static int evb_rchange(struct port *port, struct lldp_agent *agent,
+		       struct unpacked_tlv *tlv)
 {
 	struct evb_data *ed;
 	u8 oui_subtype[OUI_SUB_SIZE] = LLDP_OUI_SUBTYPE;
 
-	ed = evb_data(port->ifname);
+	ed = evb_data(port->ifname, agent->type);
 
 	if (!ed)
 		return SUBTYPE_INVALID;
@@ -524,7 +526,7 @@ static int evb_rchange(struct port *port, struct unpacked_tlv *tlv)
 		evb_print_tlvinfo(ed->last);
 
 		evb_update_tlv(ed);
-		somethingChangedLocal(ed->ifname);
+		somethingChangedLocal(ed->ifname, agent->type);
 
 		LLDPAD_DBG("%s(%i): new tlv:\n", __func__, __LINE__);
 		evb_print_tlvinfo(ed->tie);
@@ -533,13 +535,13 @@ static int evb_rchange(struct port *port, struct unpacked_tlv *tlv)
 	return TLV_OK;
 }
 
-void evb_ifdown(char *ifname)
+void evb_ifdown(char *ifname, struct lldp_agent *agent)
 {
 	struct evb_data *ed;
 
 	LLDPAD_DBG("%s called !\n", __func__);
 
-	ed = evb_data(ifname);
+	ed = evb_data(ifname, agent->type);
 	if (!ed)
 		goto out_err;
 
@@ -556,14 +558,14 @@ out_err:
 	return;
 }
 
-void evb_ifup(char *ifname)
+void evb_ifup(char *ifname, struct lldp_agent *agent)
 {
 	struct evb_data *ed;
 	struct evb_user_data *ud;
 
-	ed = evb_data(ifname);
+	ed = evb_data(ifname, agent->type);
 	if (ed) {
-		LLDPAD_DBG("%s:%s exists\n", __func__, ifname);
+		LLDPAD_DBG("%s:%s already exists\n", __func__, ifname);
 		goto out_err;
 	}
 
@@ -575,6 +577,7 @@ void evb_ifup(char *ifname)
 		goto out_err;
 	}
 	strncpy(ed->ifname, ifname, IFNAMSIZ);
+	ed->agenttype = agent->type;
 
 	if (evb_init_cfg_tlv(ed)) {
 		LLDPAD_ERR("%s:%s evb_init_cfg_tlv failed\n", __func__, ifname);
@@ -598,7 +601,7 @@ out_err:
 	return;
 }
 
-u8 evb_mibdelete(struct port *port)
+u8 evb_mibdelete(struct port *port, struct lldp_agent *agent)
 {
 	struct evb_data *ed;
 
@@ -606,10 +609,7 @@ u8 evb_mibdelete(struct port *port)
 		goto out_err;
 	}
 
-	LLDPAD_DBG("%s(%i): mibdelete triggered for port %s.\n", __func__,
-		   __LINE__, port->ifname);
-
-	ed = evb_data(port->ifname);
+	ed = evb_data(port->ifname, agent->type);
 	if (!ed) {
 		LLDPAD_DBG("%s:%s does not exist.\n", __func__, port->ifname);
 		goto out_err;
diff --git a/lldp_evb_cmds.c b/lldp_evb_cmds.c
index 90e578c..18db0d9 100644
--- a/lldp_evb_cmds.c
+++ b/lldp_evb_cmds.c
@@ -151,7 +151,7 @@ static int _set_arg_tlvtxenable(struct cmd *cmd, char *arg, char *argvalue,
 	if (set_cfg(cmd->ifname, arg_path, (void *)&value, CONFIG_TYPE_BOOL))
 		return cmd_failed;
 
-	somethingChangedLocal(cmd->ifname);
+	somethingChangedLocal(cmd->ifname, cmd->type);
 
 	return cmd_success;
 }
@@ -186,7 +186,7 @@ static int get_arg_fmode(struct cmd *cmd, char *arg, char *argvalue,
 		return cmd_not_applicable;
 	}
 
-	ed = evb_data((char *) &cmd->ifname);
+	ed = evb_data((char *) &cmd->ifname, cmd->type);
 
 	if (!ed)
 		return cmd_invalid;
@@ -221,7 +221,7 @@ static int _set_arg_fmode(struct cmd *cmd, char *arg, char *argvalue,
 		return cmd_not_applicable;
 	}
 
-	ed = evb_data((char *) &cmd->ifname);
+	ed = evb_data((char *) &cmd->ifname, cmd->type);
 
 	if (!ed)
 		return cmd_invalid;
@@ -253,7 +253,7 @@ static int _set_arg_fmode(struct cmd *cmd, char *arg, char *argvalue,
 		return cmd_invalid;
 	}
 
-	somethingChangedLocal(cmd->ifname);
+	somethingChangedLocal(cmd->ifname, cmd->type);
 
 	return cmd_success;
 }
@@ -299,7 +299,7 @@ static int get_arg_capabilities(struct cmd *cmd, char *arg, char *argvalue,
 		return cmd_not_applicable;
 	}
 
-	ed = evb_data((char *) &cmd->ifname);
+	ed = evb_data((char *) &cmd->ifname, cmd->type);
 	if (!ed)
 		goto out_free;
 
@@ -354,7 +354,7 @@ static int _set_arg_capabilities(struct cmd *cmd, char *arg, char *argvalue,
 		return cmd_not_applicable;
 	}
 
-	ed = evb_data((char *) &cmd->ifname);
+	ed = evb_data((char *) &cmd->ifname, cmd->type);
 
 	if (!ed)
 		return cmd_invalid;
@@ -385,7 +385,7 @@ static int _set_arg_capabilities(struct cmd *cmd, char *arg, char *argvalue,
 		return cmd_invalid;
 	}
 
-	somethingChangedLocal(cmd->ifname);
+	somethingChangedLocal(cmd->ifname, cmd->type);
 
 	return cmd_success;
 }
@@ -420,7 +420,7 @@ static int get_arg_rte(struct cmd *cmd, char *arg, char *argvalue,
 		return cmd_not_applicable;
 	}
 
-	ed = evb_data((char *) &cmd->ifname);
+	ed = evb_data((char *) &cmd->ifname, cmd->type);
 	if (!ed)
 		return cmd_invalid;
 
@@ -452,7 +452,7 @@ static int _set_arg_rte(struct cmd *cmd, char *arg, char *argvalue,
 		return cmd_not_applicable;
 	}
 
-	ed = evb_data((char *) &cmd->ifname);
+	ed = evb_data((char *) &cmd->ifname, cmd->type);
 
 	if (!ed)
 		return cmd_invalid;
@@ -479,7 +479,7 @@ static int _set_arg_rte(struct cmd *cmd, char *arg, char *argvalue,
 	if (set_cfg(ed->ifname, arg_path, (void *) &argvalue, CONFIG_TYPE_STRING))
 		goto out_err;
 
-	somethingChangedLocal(cmd->ifname);
+	somethingChangedLocal(cmd->ifname, cmd->type);
 
 	return cmd_success;
 
@@ -518,7 +518,7 @@ static int get_arg_vsis(struct cmd *cmd, char *arg, char *argvalue,
 		return cmd_not_applicable;
 	}
 
-	ed = evb_data((char *) &cmd->ifname);
+	ed = evb_data((char *) &cmd->ifname, cmd->type);
 	if (!ed)
 		return cmd_invalid;
 
@@ -540,7 +540,7 @@ static int _set_arg_vsis(struct cmd *cmd, char *arg, char *argvalue,
 	char *sv;
 	struct evb_data *ed = NULL;
 
-	ed = evb_data((char *) &cmd->ifname);
+	ed = evb_data((char *) &cmd->ifname, cmd->type);
 
 	if (!ed)
 		return cmd_invalid;
@@ -583,7 +583,7 @@ static int _set_arg_vsis(struct cmd *cmd, char *arg, char *argvalue,
 	if (set_cfg(ed->ifname, arg_path, (void *) &sv, CONFIG_TYPE_STRING))
 		goto out_err;
 
-	somethingChangedLocal(cmd->ifname);
+	somethingChangedLocal(cmd->ifname, cmd->type);
 
 	return cmd_success;
 
diff --git a/lldp_mand.c b/lldp_mand.c
index b5e8092..00630ec 100644
--- a/lldp_mand.c
+++ b/lldp_mand.c
@@ -91,7 +91,7 @@ static const struct lldp_mod_ops mand_ops = {
 	.get_arg_handler	= mand_get_arg_handlers,
 };
 
-static struct mand_data *mand_data(const char *ifname)
+static struct mand_data *mand_data(const char *ifname, enum agent_type type)
 {
 	struct mand_user_data *mud;
 	struct mand_data *md = NULL;
@@ -99,7 +99,8 @@ static struct mand_data *mand_data(const char *ifname)
 	mud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_MAND);
 	if (mud) {
 		LIST_FOREACH(md, &mud->head, entry) {
-			if (!strncmp(ifname, md->ifname, IFNAMSIZ))
+			if (!strncmp(ifname, md->ifname, IFNAMSIZ) &&
+			    (type == md->agenttype))
 				return md;
 		}
 	}
@@ -425,12 +426,11 @@ out_err:
 	return rc;
 }
 
-static int mand_bld_ttl_tlv(struct mand_data *md)
+static int mand_bld_ttl_tlv(struct mand_data *md, struct lldp_agent *agent)
 {
 	int rc = EINVAL;
 	u16 ttl;
 	struct unpacked_tlv *tlv;
-	struct port *port;
 
 	tlv = create_tlv();
 	if (!tlv)
@@ -445,9 +445,8 @@ static int mand_bld_ttl_tlv(struct mand_data *md)
 	}
 	memset(tlv->info, 0, tlv->length);
 
-	port = port_find_by_name(md->ifname);
-	if (port->tx.txTTL)
-		ttl = htons(port->tx.txTTL);
+	if (agent->tx.txTTL)
+		ttl = htons(agent->tx.txTTL);
 	else
 		ttl = htons(DEFAULT_TX_HOLD * DEFAULT_TX_INTERVAL);
 
@@ -460,13 +459,13 @@ out_err:
 	return rc;
 }
 
-struct packed_tlv *mand_gettlv(struct port *port)
+struct packed_tlv *mand_gettlv(struct port *port, struct lldp_agent *agent)
 {
 	struct mand_data *md;
 	struct packed_tlv *ptlv = NULL;
 	size_t size;
 
-	md = mand_data(port->ifname);
+	md = mand_data(port->ifname, agent->type);
 	if (!md) {
 		LLDPAD_DBG("%s:%s: not found port\n", __func__, port->ifname);
 		goto out_err;
@@ -510,7 +509,7 @@ static void mand_free_tlv(struct mand_data *md)
 }
 
 /* build unpacked tlvs */
-static int mand_bld_tlv(struct mand_data *md)
+static int mand_bld_tlv(struct mand_data *md, struct lldp_agent *agent)
 {
 	int rc = EPERM;
 
@@ -529,7 +528,7 @@ static int mand_bld_tlv(struct mand_data *md)
 				__func__, md->ifname);
 		goto out_err;
 	}
-	if (mand_bld_ttl_tlv(md)) {
+	if (mand_bld_ttl_tlv(md, agent)) {
 		LLDPAD_DBG("%s:%s:mand_bld_ttl_tlv() failed\n",
 				__func__, md->ifname);
 		goto out_err;
@@ -559,11 +558,11 @@ static void mand_free_data(struct mand_user_data *mud)
 	}
 }
 
-void mand_ifdown(char *ifname)
+void mand_ifdown(char *ifname, struct lldp_agent *agent)
 {
 	struct mand_data *md;
 
-	md = mand_data(ifname);
+	md = mand_data(ifname, agent->type);
 	if (!md)
 		goto out_err;
 
@@ -577,12 +576,12 @@ out_err:
 	return;
 }
 
-void mand_ifup(char *ifname)
+void mand_ifup(char *ifname, struct lldp_agent *agent)
 {
 	struct mand_data *md;
 	struct mand_user_data *mud;
 
-	md = mand_data(ifname);
+	md = mand_data(ifname, agent->type);
 	if (md) {
 		LLDPAD_INFO("%s:%s exists\n", __func__, ifname); 
 		goto out_err;
@@ -595,7 +594,9 @@ void mand_ifup(char *ifname)
 	}
 	memset(md, 0, sizeof(struct mand_data));
 	strncpy(md->ifname, ifname, IFNAMSIZ);
-	if (mand_bld_tlv(md)) {
+	md->agenttype = agent->type;
+
+	if (mand_bld_tlv(md, agent)) {
 		LLDPAD_INFO("%s:%s mand_bld_tlv failed\n", __func__, ifname); 
 		free(md);
 		goto out_err;
diff --git a/lldp_mand_cmds.c b/lldp_mand_cmds.c
index d09d6a5..8c36787 100644
--- a/lldp_mand_cmds.c
+++ b/lldp_mand_cmds.c
@@ -40,6 +40,7 @@
 #include "clif_msgs.h"
 #include "lldp/states.h"
 #include "lldp_util.h"
+#include "messages.h"
 
 static int get_arg_adminstatus(struct cmd *, char *, char *, char *, int);
 static int set_arg_adminstatus(struct cmd *, char *, char *, char *, int);
@@ -230,7 +231,7 @@ int _set_arg_adminstatus(struct cmd *cmd, char *arg, char *argvalue,
 		return cmd_failed;
 	}
 
-	set_lldp_port_admin(cmd->ifname, value);
+	set_lldp_agent_admin(cmd->ifname, cmd->type, value);
 
 	sprintf(obuf + strlen(obuf), "adminStatus = %s\n", argvalue);
 
@@ -343,11 +344,11 @@ int get_tlvs(struct cmd *cmd, char *rbuf, int rlen)
 	int res;
 
 	if (cmd->ops & op_local) {
-		res = get_local_tlvs(cmd->ifname, &tlvs[0], &size);
+		res = get_local_tlvs(cmd->ifname, cmd->type, &tlvs[0], &size);
 		if (res)
 			return res;
 	} else if (cmd->ops & op_neighbor) {
-		res = get_neighbor_tlvs(cmd->ifname, &tlvs[0], &size);
+		res = get_neighbor_tlvs(cmd->ifname, cmd->type, &tlvs[0], &size);
 		if (res)
 			return res;
 	} else
@@ -381,15 +382,16 @@ int get_tlvs(struct cmd *cmd, char *rbuf, int rlen)
 	for (i = 0; i < size; i++) {
 		snprintf(rbuf + 2*i, rlen - strlen(rbuf), "%02x", tlvs[i]);
 	}
+
 	return cmd_success;
 }
 
-int get_port_stats(struct cmd *cmd, char *rbuf, int rlen)
+int get_agent_stats(struct cmd *cmd, char *rbuf, int rlen)
 {
 	int offset=0;
-	struct portstats stats;
+	struct agentstats stats;
 
-	if (get_lldp_port_statistics(cmd->ifname, &stats))
+	if (get_lldp_agent_statistics(cmd->ifname, &stats, cmd->type))
 		return cmd_device_not_found;
 
 	snprintf(rbuf+offset, rlen - strlen(rbuf),
@@ -447,6 +449,9 @@ int mand_clif_cmd(void  *data,
 	cmd.ifname[len] = '\0';
 	ioff += len;
 
+	hexstr2bin(ibuf+ioff, &cmd.type, sizeof(cmd.type));
+	ioff += 2*sizeof(cmd.type);
+
 	if (cmd.cmd == cmd_gettlv || cmd.cmd == cmd_settlv) {
 		hexstr2bin(ibuf+ioff, (u8 *)&cmd.tlvid, sizeof(cmd.tlvid));
 		cmd.tlvid = ntohl(cmd.tlvid);
@@ -499,7 +504,7 @@ int mand_clif_cmd(void  *data,
 	case cmd_getstats:
 		if (numargs)
 			break;
-		rstatus = get_port_stats(&cmd, rbuf + roff, rlen - roff);
+		rstatus = get_agent_stats(&cmd, rbuf + roff, rlen - roff);
 		break;
 	case cmd_gettlv:
 		snprintf(rbuf + roff, rlen - roff, "%08x", cmd.tlvid);
diff --git a/lldp_med.c b/lldp_med.c
index eae1b45..ca79b7e 100644
--- a/lldp_med.c
+++ b/lldp_med.c
@@ -90,7 +90,7 @@ static const struct lldp_mod_ops med_ops =  {
 	.get_arg_handler	= med_get_arg_handlers,
 };
 
-static struct med_data *med_data(const char *ifname)
+static struct med_data *med_data(const char *ifname, enum agent_type type)
 {
 	struct med_user_data *mud;
 	struct med_data *md = NULL;
@@ -98,7 +98,8 @@ static struct med_data *med_data(const char *ifname)
 	mud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_MED);
 	if (mud) {
 		LIST_FOREACH(md, &mud->head, entry) {
-			if (!strncmp(ifname, md->ifname, IFNAMSIZ))
+			if (!strncmp(ifname, md->ifname, IFNAMSIZ) &&
+			    (type == md->agenttype))
 				return md;
 		}
 	}
@@ -797,13 +798,14 @@ static void med_free_data(struct med_user_data *mud)
 	}
 }
 
-struct packed_tlv *med_gettlv(struct port *port)
+struct packed_tlv *med_gettlv(struct port *port,
+			      struct lldp_agent *agent)
 {
 	size_t size;
 	struct med_data *md;
 	struct packed_tlv *ptlv = NULL;
 
-	md = med_data(port->ifname);
+	md = med_data(port->ifname, agent->type);
 	if (!md)
 		goto out_err;
 
@@ -856,11 +858,11 @@ out_err:
 	return NULL;
 }
 
-void med_ifdown(char *ifname)
+void med_ifdown(char *ifname, struct lldp_agent *agent)
 {
 	struct med_data *md;
 
-	md = med_data(ifname);
+	md = med_data(ifname, agent->type);
 	if (!md)
 		goto out_err;
 
@@ -874,12 +876,12 @@ out_err:
 	return;
 }
 
-void med_ifup(char *ifname)
+void med_ifup(char *ifname, struct lldp_agent *agent)
 {
 	struct med_data *md;
 	struct med_user_data *mud;
 
-	md = med_data(ifname);
+	md = med_data(ifname, agent->type);
 	if (md) {
 		LLDPAD_DBG("%s:%s exists\n", __func__, ifname);
 		goto out_err;
@@ -894,6 +896,7 @@ void med_ifup(char *ifname)
 	}
 	memset(md, 0, sizeof(struct med_data));
 	strncpy(md->ifname, ifname, IFNAMSIZ);
+	md->agenttype = agent->type;
 
 	if (med_bld_tlv(md)) {
 		LLDPAD_DBG("%s:%s med_bld_tlv failed\n",
diff --git a/lldp_med_cmds.c b/lldp_med_cmds.c
index 72f2c6f..a5a4db8 100644
--- a/lldp_med_cmds.c
+++ b/lldp_med_cmds.c
@@ -154,7 +154,7 @@ static int _set_arg_tlvtxenable(struct cmd *cmd, char *arg, char *argvalue,
 
 	snprintf(obuf, obuf_len, "enableTx = %s\n", value ? "yes" : "no");
 
-	somethingChangedLocal(cmd->ifname);
+	somethingChangedLocal(cmd->ifname, cmd->type);
 
 	return cmd_success;
 }
@@ -318,7 +318,7 @@ static int _set_arg_med_devtype(struct cmd *cmd, char *arg, char *argvalue,
 
 	snprintf(obuf, obuf_len, "devtype = %li\n", value);
 
-	somethingChangedLocal(cmd->ifname);
+	somethingChangedLocal(cmd->ifname, cmd->type);
 
 	return cmd_success;
 }
diff --git a/lldp_tlv.c b/lldp_tlv.c
index 47d9b4e..9e891c2 100644
--- a/lldp_tlv.c
+++ b/lldp_tlv.c
@@ -34,21 +34,18 @@
 #include "dcb_types.h"
 #include "messages.h"
 
-void somethingChangedLocal(const char *ifname)
+void somethingChangedLocal(const char *ifname, int type)
 {
-	struct port *port = porthead;
+	struct lldp_agent *agent;
 
-	while (port != NULL) {
-		if (!strncmp(ifname, port->ifname, MAX_DEVICE_NAME_LEN))
-			break;
-		port = port->next;
-	}
+	agent = lldp_agent_find_by_type(ifname, type);
 
-	if (!port)
+	if (agent == NULL)
 		return;
 
-	port->tx.localChange = 1;
-	port->tx.txFast = port->timers.txFastInit;
+	agent->tx.localChange = 1;
+	agent->tx.txFast = agent->timers.txFastInit;
+
 	return;
 }
 
diff --git a/lldp_vdp.c b/lldp_vdp.c
index 2875bf5..20e7a26 100644
--- a/lldp_vdp.c
+++ b/lldp_vdp.c
@@ -42,6 +42,8 @@
 #include "config.h"
 #include "lldp_tlv.h"
 #include "lldp_vdp_cmds.h"
+#include "lldp_vdp_clif.h"
+#include "lldp_mand_clif.h"
 
 const char * const vsi_responses[] = {
 	[VDP_RESPONSE_SUCCESS] = "success",
@@ -1304,7 +1306,7 @@ int vdp_remove_profile(struct vsi_profile *profile)
  * interface function to lldpad. tears down vdp specific structures if
  * interface "ifname" goes down.
  */
-void vdp_ifdown(char *ifname)
+void vdp_ifdown(char *ifname, struct lldp_agent *agent)
 {
 	struct vdp_data *vd;
 	struct vsi_profile *p;
@@ -1341,12 +1343,12 @@ out_err:
  * interface function to lldpad. builds up vdp specific structures if
  * interface "ifname" goes down.
  */
-void vdp_ifup(char *ifname)
+void vdp_ifup(char *ifname, struct lldp_agent *agent)
 {
-	char *string;
+	char *role;
+	char config_path[64];
 	struct vdp_data *vd;
 	struct vdp_user_data *ud;
-	struct port *port;
 	struct vsi_profile *p;
 
 	/* VDP does not support bonded devices */
@@ -1370,11 +1372,24 @@ void vdp_ifup(char *ifname)
 	}
 	strncpy(vd->ifname, ifname, IFNAMSIZ);
 
+	snprintf(config_path, sizeof(config_path), "%s.%s",
+		 VDP_PREFIX, ARG_TLVTXENABLE);
+
+	if (get_cfg(vd->ifname, config_path, (void *)&vd->enabletx,
+		    CONFIG_TYPE_BOOL))
+			vd->enabletx = false;
+
+	if (vd->enabletx == false) {
+		LLDPAD_WARN("%s(%i): port %s not enabled for VDP (%i) !\n",
+			    __func__, __LINE__, ifname, vd->enabletx);
+		return;
+	}
+
 	vd->role = VDP_ROLE_STATION;
 
-	if (!get_cfg(ifname, "vdp.role", (void *)&string,
+	if (!get_cfg(ifname, "vdp.role", (void *)&role,
 		    CONFIG_TYPE_STRING)) {
-		if (!strcasecmp(string, VAL_BRIDGE)) {
+		if (!strcasecmp(role, VAL_BRIDGE)) {
 			vd->role = VDP_ROLE_BRIDGE;
 		}
 	}
@@ -1387,24 +1402,10 @@ void vdp_ifup(char *ifname)
 	ud = find_module_user_data_by_id(&lldp_head, LLDP_MOD_VDP);
 	LIST_INSERT_HEAD(&ud->head, vd, entry);
 
-	port = port_find_by_name(ifname);
-
-	if (!port) {
-		LLDPAD_ERR("%s(%i): could not find port for %s!\n",
-			   __func__, __LINE__, ifname);
-		goto out_err;
-	}
-
-	if (port->adminStatus != enabledRxTx) {
-		LLDPAD_WARN("%s(%i): port %s not enabled for RxTx (%i) !\n",
-			    __func__, __LINE__, ifname, port->adminStatus);
-		return;
-	}
-
 out_start_again:
 	if (ecp_init(ifname)) {
 		LLDPAD_ERR("%s:%s unable to init ecp !\n", __func__, ifname);
-		vdp_ifdown(ifname);
+		vdp_ifdown(ifname, agent);
 		goto out_err;
 	}
 
diff --git a/lldpad.c b/lldpad.c
index 6105985..648b799 100644
--- a/lldpad.c
+++ b/lldpad.c
@@ -43,6 +43,8 @@
 #include "event_iface.h"
 #include "messages.h"
 #include "version.h"
+#include "lldp/ports.h"
+#include "lldp/l2_packet.h"
 #include "lldp_mand.h"
 #include "lldp_basman.h"
 #include "lldp_dcbx.h"
@@ -55,6 +57,7 @@
 #include "lldpad_shm.h"
 #include "lldp/agent.h"
 #include "lldp/l2_packet.h"
+#include "clif.h"
 
 /*
  * insert to head, so first one is last
@@ -147,7 +150,7 @@ void lldpad_reconfig(int sig, void *eloop_ctx, void *signal_ctx)
 {
 	LLDPAD_WARN("lldpad: SIGHUP received reinit...");
 	/* Send LLDP SHUTDOWN frames and deinit modules */
-	clean_lldp_agent();
+	clean_lldp_agents();
 	deinit_modules();
 	remove_all_adapters();
 	remove_all_bond_ports();
@@ -381,7 +384,7 @@ int main(int argc, char *argv[])
 	eloop_register_signal_reconfig(lldpad_reconfig, NULL); 
 
 	/* setup LLDP agent */
-	if (!start_lldp_agent()) {
+	if (!start_lldp_agents()) {
 		LLDPAD_ERR("failed to initialize LLDP agent\n");
 		exit(1);
 	}
@@ -405,13 +408,13 @@ int main(int argc, char *argv[])
 
 	eloop_run();
 
-	clean_lldp_agent();
+	clean_lldp_agents();
 	deinit_modules();
 	remove_all_adapters();
 	remove_all_bond_ports();
 	ctrl_iface_deinit(clifd);  /* free's clifd */
 	event_iface_deinit();
-	stop_lldp_agent();
+	stop_lldp_agents();
  out:
 	destroy_cfg();
 	closelog();
diff --git a/tlv_dcbx.c b/tlv_dcbx.c
index 18b1492..2e1464f 100644
--- a/tlv_dcbx.c
+++ b/tlv_dcbx.c
@@ -33,14 +33,9 @@
 #include "dcb_protocol.h"
 #include "lldp_dcbx.h"
 #include "lldp/states.h"
+#include "lldp/agent.h"
 #include "messages.h"
 
-bool process_dcbx_ctrl_tlv(struct port *port);
-bool process_dcbx_pg_tlv(struct port *port);
-bool process_dcbx_pfc_tlv(struct port *port);
-bool process_dcbx_app_tlv(struct port *port, int subtype);
-bool process_dcbx_llink_tlv(struct port *port);
-
 /* for the specified remote feature, if the feature is not present in the
  * EventFlag parameter (indicating it was not received in the DCB TLV), then
  * check and update the peer data store object for the feature if it is
@@ -799,7 +794,8 @@ struct unpacked_tlv *bld_dcbx_llink_tlv(struct dcbx_tlvs *dcbx, u32 sub_type,
 	return tlv;
 }
 
-bool unpack_dcbx1_tlvs(struct port *port, struct unpacked_tlv *tlv)
+bool unpack_dcbx1_tlvs(struct port *port, struct lldp_agent *agent,
+		       struct unpacked_tlv *tlv)
 {
 	/* unpack the tlvs and store in manifest */
 	u8 *offset = NULL;   /* iterator */
@@ -810,9 +806,12 @@ bool unpack_dcbx1_tlvs(struct port *port, struct unpacked_tlv *tlv)
 
 	tlvs = dcbx_data(port->ifname);
 
+	if (agent == NULL)
+		return false;
+
 	/* store highest dcbx subtype received */
-	if (port->rx.dcbx_st < tlv->info[DCB_OUI_LEN]) {
-		port->rx.dcbx_st = tlv->info[DCB_OUI_LEN];
+	if (agent->rx.dcbx_st < tlv->info[DCB_OUI_LEN]) {
+		agent->rx.dcbx_st = tlv->info[DCB_OUI_LEN];
 	}
 	/* OUI + subtype sizes equal the start of data blob */
 	offset = (u8  *)&tlv->info[OUI_SUBTYPE_LEN + DCB_OUI_LEN];
@@ -854,19 +853,19 @@ bool unpack_dcbx1_tlvs(struct port *port, struct unpacked_tlv *tlv)
 				tlvs->manifest->dcbx_ctrl = dcbtlv;
 			} else {
 				LLDPAD_DBG("** ERROR: DUP Ctrl TLV1 \n");
-				port->rx.dupTlvs |= DUP_DCBX_TLV_CTRL;
+				agent->rx.dupTlvs |= DUP_DCBX_TLV_CTRL;
 				free_unpkd_tlv(dcbtlv);
 			}
 			break;
 		case DCB_PRIORITY_GROUPS_TLV:
 			/* store if subtype 2 is not present */
-			if (port->rx.dcbx_st == dcbx_subtype1) {
+			if (agent->rx.dcbx_st == dcbx_subtype1) {
 				if (tlvs->manifest->dcbx_pg == NULL) {
 					tlvs->dcbdu |= RCVD_DCBX_TLV_PG;
 					tlvs->manifest->dcbx_pg = dcbtlv;
 				} else {
 					LLDPAD_DBG("** ERROR: DUP PG TLV1 \n");
-					port->rx.dupTlvs |= DUP_DCBX_TLV_PG;
+					agent->rx.dupTlvs |= DUP_DCBX_TLV_PG;
 					free_unpkd_tlv(dcbtlv);
 				}
 			} else {
@@ -875,13 +874,13 @@ bool unpack_dcbx1_tlvs(struct port *port, struct unpacked_tlv *tlv)
 			break;
 		case DCB_PRIORITY_FLOW_CONTROL_TLV:
 			/* store if subtype 2 is not present */
-			if (port->rx.dcbx_st == dcbx_subtype1) {
+			if (agent->rx.dcbx_st == dcbx_subtype1) {
 				if (tlvs->manifest->dcbx_pfc == NULL) {
 					tlvs->dcbdu |= RCVD_DCBX_TLV_PFC;
 					tlvs->manifest->dcbx_pfc = dcbtlv;
 				} else {
 					LLDPAD_DBG("** ERROR: DUP PFC TLV1 \n");
-					port->rx.dupTlvs |= DUP_DCBX_TLV_PFC;
+					agent->rx.dupTlvs |= DUP_DCBX_TLV_PFC;
 					free_unpkd_tlv(dcbtlv);
 				}
 			} else {
@@ -890,7 +889,7 @@ bool unpack_dcbx1_tlvs(struct port *port, struct unpacked_tlv *tlv)
 			break;
 		case DCB_APPLICATION_TLV:
 			/* store if subtype 2 is not present */
-			if ((port->rx.dcbx_st == dcbx_subtype1) &&
+			if ((agent->rx.dcbx_st == dcbx_subtype1) &&
 				(dcbtlv->info[DCBX_HDR_SUB_TYPE_OFFSET]
 					== APP_FCOE_STYPE)) {
 				if (tlvs->manifest->dcbx_app == NULL) {
@@ -898,7 +897,7 @@ bool unpack_dcbx1_tlvs(struct port *port, struct unpacked_tlv *tlv)
 					tlvs->manifest->dcbx_app = dcbtlv;
 				} else {
 					LLDPAD_DBG("** ERROR: DUP APP TLV1 \n");
-					port->rx.dupTlvs |= DUP_DCBX_TLV_APP;
+					agent->rx.dupTlvs |= DUP_DCBX_TLV_APP;
 					free_unpkd_tlv(dcbtlv);
 				}
 			} else {
@@ -913,7 +912,7 @@ bool unpack_dcbx1_tlvs(struct port *port, struct unpacked_tlv *tlv)
 					tlvs->manifest->dcbx_llink = dcbtlv;
 				} else {
 					LLDPAD_DBG("** ERROR: DUP LLINK TLV1 \n");
-					port->rx.dupTlvs |= DUP_DCBX_TLV_LLINK;
+					agent->rx.dupTlvs |= DUP_DCBX_TLV_LLINK;
 					free_unpkd_tlv(dcbtlv);
 				}
 			} else {
@@ -930,7 +929,8 @@ bool unpack_dcbx1_tlvs(struct port *port, struct unpacked_tlv *tlv)
 	return true;
 }
 
-bool unpack_dcbx2_tlvs(struct port *port, struct unpacked_tlv *tlv)
+bool unpack_dcbx2_tlvs(struct port *port, struct lldp_agent *agent,
+		       struct unpacked_tlv *tlv)
 {
 	/* unpack the tlvs and store in manifest */
 	u8 *offset = NULL;   /* iterator */
@@ -942,9 +942,12 @@ bool unpack_dcbx2_tlvs(struct port *port, struct unpacked_tlv *tlv)
 
 	tlvs = dcbx_data(port->ifname);
 
+	if (agent == NULL)
+		return false;
+
 	/* store highest dcbx subtype received */
-	if (port->rx.dcbx_st < tlv->info[DCB_OUI_LEN]) {
-		port->rx.dcbx_st = tlv->info[DCB_OUI_LEN];
+	if (agent->rx.dcbx_st < tlv->info[DCB_OUI_LEN]) {
+		agent->rx.dcbx_st = tlv->info[DCB_OUI_LEN];
 	}
 	/* OUI + subtype sizes equal the start of data blob */
 	offset = (u8  *)&tlv->info[OUI_SUBTYPE_LEN + DCB_OUI_LEN];
@@ -987,7 +990,7 @@ bool unpack_dcbx2_tlvs(struct port *port, struct unpacked_tlv *tlv)
 					tlvs->manifest->dcbx_ctrl = dcbtlv;
 				} else if (tlvs->dcbdu & RCVD_DCBX2_TLV_CTRL) {
 					LLDPAD_DBG("** ERROR: DUP CTRL TLV2 \n");
-					port->rx.dupTlvs |= DUP_DCBX_TLV_CTRL;
+					agent->rx.dupTlvs |= DUP_DCBX_TLV_CTRL;
 					free_unpkd_tlv(dcbtlv);
 				}
 			} else {
@@ -1000,7 +1003,7 @@ bool unpack_dcbx2_tlvs(struct port *port, struct unpacked_tlv *tlv)
 				tlvs->manifest->dcbx_pg = dcbtlv;
 			} else {
 				LLDPAD_DBG("** ERROR: DUP PG TLV2 \n");
-				port->rx.dupTlvs |= DUP_DCBX_TLV_PG;
+				agent->rx.dupTlvs |= DUP_DCBX_TLV_PG;
 				free_unpkd_tlv(dcbtlv);
 			}
 			break;
@@ -1010,7 +1013,7 @@ bool unpack_dcbx2_tlvs(struct port *port, struct unpacked_tlv *tlv)
 				tlvs->manifest->dcbx_pfc = dcbtlv;
 			} else {
 				LLDPAD_DBG("** ERROR: DUP PFC TLV2 \n");
-				port->rx.dupTlvs |= DUP_DCBX_TLV_PFC;
+				agent->rx.dupTlvs |= DUP_DCBX_TLV_PFC;
 				free_unpkd_tlv(dcbtlv);
 			}
 			break;
@@ -1022,7 +1025,7 @@ bool unpack_dcbx2_tlvs(struct port *port, struct unpacked_tlv *tlv)
 					tlvs->manifest->dcbx_app = dcbtlv;
 				} else {
 					LLDPAD_DBG("** ERROR: DUP APP TLV2 \n");
-					port->rx.dupTlvs |= DUP_DCBX_TLV_APP;
+					agent->rx.dupTlvs |= DUP_DCBX_TLV_APP;
 					free_unpkd_tlv(dcbtlv);
 				}
 			} else {
@@ -1039,7 +1042,7 @@ bool unpack_dcbx2_tlvs(struct port *port, struct unpacked_tlv *tlv)
 	return true;
 }
 
-void  mibUpdateObjects(struct port *port)
+void  mibUpdateObjects(struct port *port, struct lldp_agent *agent)
 {
 	struct dcbx_tlvs *tlvs;
 	u32 EventFlag = 0;
@@ -1047,8 +1050,11 @@ void  mibUpdateObjects(struct port *port)
 
 	tlvs = dcbx_data(port->ifname);
 
+	if (agent == NULL)
+		return;
+
 	if (tlvs->manifest->dcbx_ctrl) {
-		if (process_dcbx_ctrl_tlv(port) != true) {
+		if (process_dcbx_ctrl_tlv(port, agent) != true) {
 			/* Error Set error condition for all features
 			 * on this port and trash DCB TLV */
 		}
@@ -1057,7 +1063,7 @@ void  mibUpdateObjects(struct port *port)
 		 * on this port and trash DCB TLV */
 	}
 	if (tlvs->manifest->dcbx_pg) {
-		if (process_dcbx_pg_tlv(port) != true) {
+		if (process_dcbx_pg_tlv(port, agent) != true) {
 			 /* mark feature not present */
 			if (check_feature_not_present(port->ifname, 0,
 				EventFlag, DCB_REMOTE_CHANGE_PG)) {
@@ -1073,7 +1079,7 @@ void  mibUpdateObjects(struct port *port)
 		}
 	}
 	if (tlvs->manifest->dcbx_pfc) {
-		if (process_dcbx_pfc_tlv(port) != true) {
+		if (process_dcbx_pfc_tlv(port, agent) != true) {
 			/* mark feature not present */
 			if (check_feature_not_present(port->ifname, 0,
 				EventFlag, DCB_REMOTE_CHANGE_PFC)) {
@@ -1090,7 +1096,7 @@ void  mibUpdateObjects(struct port *port)
 	}
 
 	if (tlvs->manifest->dcbx_app) {
-		if (process_dcbx_app_tlv(port, 0) != true) {
+		if (process_dcbx_app_tlv(port, agent, 0) != true) {
 			/* mark feature not present */
 			if (check_feature_not_present(port->ifname, 0,
 				EventFlag, DCB_REMOTE_CHANGE_APPTLV(0))) {
@@ -1110,7 +1116,7 @@ void  mibUpdateObjects(struct port *port)
 	}
 
 	if (tlvs->manifest->dcbx_llink) {
-		if (process_dcbx_llink_tlv(port) != true) {
+		if (process_dcbx_llink_tlv(port, agent) != true) {
 			/* mark feature not present */
 			if (check_feature_not_present(port->ifname, 0,
 				EventFlag, DCB_REMOTE_CHANGE_LLINK)) {
@@ -1130,17 +1136,20 @@ void  mibUpdateObjects(struct port *port)
 	/* Run the feature & control protocol for all features and subtypes */
 	run_dcb_protocol(port->ifname, EventFlag, DCB_MAX_APPTLV+1);
 	EventFlag = 0;
-	port->rxChanges = true;
+	agent->rxChanges = true;
 	return;
 }
 
-bool process_dcbx_ctrl_tlv(struct port *port)
+bool process_dcbx_ctrl_tlv(struct port *port, struct lldp_agent *agent)
 {
 	struct dcbx_tlvs *tlvs;
 	control_protocol_attribs  peer_control;
 
 	tlvs = dcbx_data(port->ifname);
 
+	if (agent == NULL)
+		return false;
+
 	if (tlvs->manifest->dcbx_ctrl->length != DCBX_CTRL_LEN) {
 		LLDPAD_DBG("process_dcbx_ctrl_tlv: ERROR - len\n");
 		return(false);
@@ -1164,11 +1173,11 @@ bool process_dcbx_ctrl_tlv(struct port *port)
 		peer_control.SeqNo, peer_control.AckNo);
 	peer_control.RxDCBTLVState = DCB_PEER_PRESENT;
 
-	if (port->rx.dupTlvs & DUP_DCBX_TLV_CTRL) {
+	if (agent->rx.dupTlvs & DUP_DCBX_TLV_CTRL) {
 		LLDPAD_INFO("** STORE: DUP CTRL TLV \n");
 		peer_control.Error_Flag |= DUP_DCBX_TLV_CTRL;
 	}
-	if (port->rx.tooManyNghbrs) {
+	if (agent->rx.tooManyNghbrs) {
 		LLDPAD_INFO("** STORE: TOO_MANY_NGHBRS\n");
 		peer_control.Error_Flag |= TOO_MANY_NGHBRS;
 	}
@@ -1178,7 +1187,7 @@ bool process_dcbx_ctrl_tlv(struct port *port)
 	return(true);
 }
 
-bool 	process_dcbx_pg_tlv(struct port *port)
+bool process_dcbx_pg_tlv(struct port *port, struct lldp_agent *agent)
 {
 	pg_attribs   peer_pg;
 	struct dcbx_tlvs *tlvs;
@@ -1188,7 +1197,10 @@ bool 	process_dcbx_pg_tlv(struct port *port)
 
 	tlvs = dcbx_data(port->ifname);
 
-	if (port->rx.dcbx_st == dcbx_subtype2) {
+	if (agent == NULL)
+		return false;
+
+	if (agent->rx.dcbx_st == dcbx_subtype2) {
 		if (tlvs->manifest->dcbx_pg->length != DCBX2_PG_LEN) {
 			LLDPAD_DBG("process_dcbx2_pg_tlv: ERROR - len\n");
 			return(false);
@@ -1221,19 +1233,19 @@ bool 	process_dcbx_pg_tlv(struct port *port)
 	} else {
 		peer_pg.protocol.Error = false;
 	}
-	peer_pg.protocol.dcbx_st = port->rx.dcbx_st;
+	peer_pg.protocol.dcbx_st = agent->rx.dcbx_st;
 	peer_pg.protocol.TLVPresent = true;
 
-	if (port->rx.dupTlvs & DUP_DCBX_TLV_CTRL) {
+	if (agent->rx.dupTlvs & DUP_DCBX_TLV_CTRL) {
 		LLDPAD_INFO("** STORE: DUP CTRL TLV \n");
 		peer_pg.protocol.Error_Flag |= DUP_DCBX_TLV_CTRL;
 	}
-	if (port->rx.dupTlvs & DUP_DCBX_TLV_PG) {
+	if (agent->rx.dupTlvs & DUP_DCBX_TLV_PG) {
 		LLDPAD_INFO("** STORE: DUP PG TLV \n");
 		peer_pg.protocol.Error_Flag |= DUP_DCBX_TLV_PG;
 	}
 
-	if (port->rx.dcbx_st == dcbx_subtype2) {
+	if (agent->rx.dcbx_st == dcbx_subtype2) {
 		memset(used, false, sizeof(used));
 		for (j=0,k=0 ; k < MAX_BANDWIDTH_GROUPS; j++, k=k+2) {
 			u8 tmpbyte = tlvs->manifest->dcbx_pg->info
@@ -1319,7 +1331,7 @@ bool 	process_dcbx_pg_tlv(struct port *port)
 	return(true);
 }
 
-bool process_dcbx_pfc_tlv(struct port *port)
+bool process_dcbx_pfc_tlv(struct port *port, struct lldp_agent *agent)
 {
 	pfc_attribs  peer_pfc;
 	struct dcbx_tlvs *tlvs;
@@ -1327,7 +1339,10 @@ bool process_dcbx_pfc_tlv(struct port *port)
 
 	tlvs = dcbx_data(port->ifname);
 
-	if (port->rx.dcbx_st == dcbx_subtype2) {
+	if (agent == NULL)
+		return false;
+
+	if (agent->rx.dcbx_st == dcbx_subtype2) {
 		if (tlvs->manifest->dcbx_pfc->length != DCBX2_PFC_LEN) {
 			LLDPAD_DBG("process_dcbx2_pfc_tlv: ERROR - len\n");
 			return(false);
@@ -1360,14 +1375,14 @@ bool process_dcbx_pfc_tlv(struct port *port)
 	} else {
 		peer_pfc.protocol.Error = false;
 	}
-	peer_pfc.protocol.dcbx_st = port->rx.dcbx_st;
+	peer_pfc.protocol.dcbx_st = agent->rx.dcbx_st;
 	peer_pfc.protocol.TLVPresent = true;
 
-	if (port->rx.dupTlvs & DUP_DCBX_TLV_CTRL) {
+	if (agent->rx.dupTlvs & DUP_DCBX_TLV_CTRL) {
 		LLDPAD_INFO("** STORE: DUP CTRL TLV \n");
 		peer_pfc.protocol.Error_Flag |= DUP_DCBX_TLV_CTRL;
 	}
-	if (port->rx.dupTlvs & DUP_DCBX_TLV_PFC) {
+	if (agent->rx.dupTlvs & DUP_DCBX_TLV_PFC) {
 		LLDPAD_INFO("** STORE: DUP PFC TLV \n");
 		peer_pfc.protocol.Error_Flag |= DUP_DCBX_TLV_PFC;
 	}
@@ -1377,7 +1392,7 @@ bool process_dcbx_pfc_tlv(struct port *port)
 		temp = tlvs->manifest->dcbx_pfc->info[DCBX_PFC_MAP_OFFSET];
 		peer_pfc.admin[i] = (pfc_type)((temp >> i) & BIT0);
 	}
-	if (port->rx.dcbx_st == dcbx_subtype2) {
+	if (agent->rx.dcbx_st == dcbx_subtype2) {
 		peer_pfc.num_tcs = tlvs->manifest->dcbx_pfc->info
 				[DCBX2_PFC__NUM_TC_OFFSET];
 	}
@@ -1386,7 +1401,7 @@ bool process_dcbx_pfc_tlv(struct port *port)
 	return(true);
 }
 
-bool process_dcbx_app_tlv(struct port *port, int stype)
+bool process_dcbx_app_tlv(struct port *port, struct lldp_agent *agent, int stype)
 {
 	app_attribs peer_app;
 	u32         i=0, len=0;
@@ -1398,8 +1413,11 @@ bool process_dcbx_app_tlv(struct port *port, int stype)
 
 	tlvs = dcbx_data(port->ifname);
 
+	if (agent == NULL)
+		return false;
+
 	len = tlvs->manifest->dcbx_app->length;
-	if (port->rx.dcbx_st == dcbx_subtype2) {
+	if (agent->rx.dcbx_st == dcbx_subtype2) {
 		if (len < DCBX2_APP_LEN) {
 			LLDPAD_DBG("process_dcbx2_app_tlv: ERROR - len\n");
 			return(false);
@@ -1432,18 +1450,18 @@ bool process_dcbx_app_tlv(struct port *port, int stype)
 	} else {
 		peer_app.protocol.Error = false;
 	}
-	peer_app.protocol.dcbx_st = port->rx.dcbx_st;
+	peer_app.protocol.dcbx_st = agent->rx.dcbx_st;
 
-	if (port->rx.dupTlvs & DUP_DCBX_TLV_CTRL) {
+	if (agent->rx.dupTlvs & DUP_DCBX_TLV_CTRL) {
 		LLDPAD_INFO("** STORE: DUP CTRL TLV \n");
 		peer_app.protocol.Error_Flag |= DUP_DCBX_TLV_CTRL;
 	}
-	if (port->rx.dupTlvs & DUP_DCBX_TLV_APP) {
+	if (agent->rx.dupTlvs & DUP_DCBX_TLV_APP) {
 		LLDPAD_INFO("** STORE: DUP APP TLV \n");
 		peer_app.protocol.Error_Flag |= DUP_DCBX_TLV_APP;
 	}
 
-	if (port->rx.dcbx_st == dcbx_subtype2) {
+	if (agent->rx.dcbx_st == dcbx_subtype2) {
 		/* processs upper layer protocol IDs until we 
 		 * match Selector Field, FCoE or FIP ID and OUI */
 		len -= DCBX2_APP_DATA_OFFSET;
@@ -1508,13 +1526,16 @@ bool process_dcbx_app_tlv(struct port *port, int stype)
 	return(false);
 }
 
-bool process_dcbx_llink_tlv(struct port *port)
+bool process_dcbx_llink_tlv(struct port *port, struct lldp_agent *agent)
 {
 	llink_attribs   peer_llk;
 	struct dcbx_tlvs *tlvs;
 
 	tlvs = dcbx_data(port->ifname);
 
+	if (agent == NULL)
+		return false;
+
 	if (tlvs->manifest->dcbx_llink->length != DCBX_LLINK_LEN) {
 		LLDPAD_DBG("process_dcbx_llink_tlv: ERROR - len\n");
 		return(false);
@@ -1541,14 +1562,14 @@ bool process_dcbx_llink_tlv(struct port *port)
 	} else {
 		peer_llk.protocol.Error = false;
 	}
-	peer_llk.protocol.dcbx_st = port->rx.dcbx_st;
+	peer_llk.protocol.dcbx_st = agent->rx.dcbx_st;
 	peer_llk.protocol.TLVPresent = true;
 
-	if (port->rx.dupTlvs & DUP_DCBX_TLV_CTRL) {
+	if (agent->rx.dupTlvs & DUP_DCBX_TLV_CTRL) {
 		LLDPAD_INFO("** STORE: DUP CTRL TLV \n");
 		peer_llk.protocol.Error_Flag |= DUP_DCBX_TLV_CTRL;
 	}
-	if (port->rx.dupTlvs & DUP_DCBX_TLV_LLINK) {
+	if (agent->rx.dupTlvs & DUP_DCBX_TLV_LLINK) {
 		LLDPAD_INFO("** STORE: DUP LLINK TLV \n");
 		peer_llk.protocol.Error_Flag |= DUP_DCBX_TLV_LLINK;
 	}
-- 
1.7.4.4




More information about the lldp-devel mailing list