[lldp-devel] [PATCH 1/2] ecp fix endless loop issue

Thomas Richter tmricht at linux.vnet.ibm.com
Tue Mar 12 10:59:42 UTC 2013

The ECP protocol calls the ECP_TX_INIT_TRANSMIT
in an endless loop under certain conditions. The bug appears on
RHEL 6.3 and RHEL 6.4 (probably on RHEL 6.2 too), but not on
Fedora 18. I have not tested any other distribution.

The problem shows up when a link is down *and* has QBG enabled in
the lldpad configuration file.
When you start lldpad, you get endless messages of:
16:13:34.979858 ecp_tx_run_sm-eth1: ecp_tx - ECP_TX_INIT_TRANSMIT
16:13:34.979861 ecp_somethingChangedLocal:eth1 vd->ecp.tx.localChange to true
16:13:34.980938 ecp_localchange_handler:eth1 ecp.tx.localChange 1
16:13:34.980942 ecp_tx_run_sm-eth1: ecp_tx - ECP_TX_INIT_TRANSMIT
16:13:34.980945 ecp_somethingChangedLocal:eth1 vd->ecp.tx.localChange to true
16:13:34.982013 ecp_localchange_handler:eth1 ecp.tx.localChange 1

Those messages appear on the screen with -V7 option only, but in an
extremely high frequency. Without this option you do not see the
messages, but the problem is still there.

The basic problem is that the VDP module is started and triggers
ECP communication. But when the link is down the function
ecp_tx_run_sm() does not advance to the next state. Instead if
keeps going for ever in state TX_INIT_TRANSMIT.

To remedy this situation, remove the check for link active. It also
changes the portEnabled variable to false when the link is not
active. The change of the portEnable variable to false prevents
the state machine from advancing to the next state.

Reported-by: Mijo Safradin <mijo at linux.vnet.ibm.com>
Signed-off-by: Thomas Richter <tmricht at linux.vnet.ibm.com>
 lldp_ecp.c | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/lldp_ecp.c b/lldp_ecp.c
index f21c619..8e92253 100644
--- a/lldp_ecp.c
+++ b/lldp_ecp.c
@@ -319,19 +319,12 @@ static bool ecp_build_ECPDU(struct vdp_data *vd)
 static void ecp_tx_Initialize(struct vdp_data *vd)
-	struct port *port = port_find_by_name(vd->ifname);
-	if (!port)
-		return;
 	memset(vd->ecp.tx.frame, 0, sizeof vd->ecp.tx.frame);
 	ecp_somethingChangedLocal(vd, true);
 	vd->ecp.lastSequence = ECP_SEQUENCE_NR_START;
 	vd->ecp.stats.statsFramesOutTotal = 0;
 	vd->ecp.ackTimer = ECP_ACK_TIMER_STOPPED;
 	vd->ecp.retries = 0;
-	l2_packet_get_port_state(vd->ecp.l2, (u8 *)&(port->portEnabled));
 /* ecp_txFrame - transmit ecp frame

More information about the lldp-devel mailing list