Blame lldpad-0.9.41-prevent-forgotten-ECP-frame-for-vsi-type.patch

c639191
From 4749b5abad3dabb802b34dddf6dbfb9ac6d180ff Mon Sep 17 00:00:00 2001
c639191
From: Jens Osterkamp <jens@linux.vnet.ibm.com>
c639191
Date: Sun, 6 Mar 2011 21:39:05 -0800
c639191
Subject: [PATCH 22/51] prevent "forgotten" ECP frame for vsi type
c639191
c639191
We have seen cases where an ecp frame for a profile is "forgotten" to be
c639191
sent out if the ecp tx state machine is still waiting for an ack for a
c639191
previous frame.
c639191
c639191
The sequence which leads to this is as follows:
c639191
c639191
1) ecp frame for vsi type 1 is sent out
c639191
2) ecp tx state machine is switched to ECP_TX_WAIT_FOR_ACK_FRAME
c639191
3) keepalive timer for vsi type 2 times out, vsi type 2 is marked fo
c639191
4) ecp tx state machine switches to ECP_TX_REQUEST_PDU
c639191
5) ecp frame for vsi type 2 is not sent out
c639191
6) vdp ack timer for vsi type 2 times out
c639191
7) vsi type 2 is removed
c639191
c639191
It can take between hours and days until this behaviour can be observed.
c639191
This patch fixes it by checking for pending vsi type when switching to
c639191
ECP_TX_REQUEST_PDU.
c639191
c639191
Signed-off-by: Jens Osterkamp <jens@linux.vnet.ibm.com>
c639191
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
c639191
Signed-off-by: Petr Sabata <psabata@redhat.com>
c639191
---
c639191
 ecp/ecp_tx.c |    7 ++++++-
c639191
 lldp_vdp.c   |   20 ++++++++++++++++++++
c639191
 2 files changed, 26 insertions(+), 1 deletions(-)
c639191
c639191
diff --git a/ecp/ecp_tx.c b/ecp/ecp_tx.c
c639191
index 99d5cae..ebf9e4b 100644
c639191
--- a/ecp/ecp_tx.c
c639191
+++ b/ecp/ecp_tx.c
c639191
@@ -53,7 +53,7 @@ void ecp_somethingChangedLocal(struct vdp_data *vd, bool flag)
c639191
 	if (!vd)
c639191
 		return;
c639191
 
c639191
-	LLDPAD_DBG("%s(%i): setting vd->ecp.tx.localChange to %s.", __func__,
c639191
+	LLDPAD_DBG("%s(%i): vd->ecp.tx.localChange to %s.", __func__,
c639191
 		   __LINE__, (flag == true) ? "true" : "false");
c639191
 
c639191
 	vd->ecp.tx.localChange = flag;
c639191
@@ -412,6 +412,11 @@ static bool ecp_set_tx_state(struct vdp_data *vd)
c639191
 		}
c639191
 		if (vd->ecp.ackReceived && vd->ecp.seqECPDU == vd->ecp.lastSequence) {
c639191
 			vd->ecp.ackReceived = false;
c639191
+			if (vdp_vsis_pending(vd)) {
c639191
+				LLDPAD_DBG("%s(%i)-%s: still work pending !\n",
c639191
+					   __func__, __LINE__, vd->ifname);
c639191
+				ecp_somethingChangedLocal(vd, true);
c639191
+			}
c639191
 			ecp_tx_change_state(vd, ECP_TX_REQUEST_PDU);
c639191
 			return true;
c639191
 		}
c639191
diff --git a/lldp_vdp.c b/lldp_vdp.c
c639191
index e6ee7e8..b3c7726 100644
c639191
--- a/lldp_vdp.c
c639191
+++ b/lldp_vdp.c
c639191
@@ -149,6 +149,26 @@ void vdp_ack_profiles(struct vdp_data *vd, int seqnr)
c639191
 
c639191
 }
c639191
 
c639191
+/* vdp_vsis_pending - check for pending VSIs
c639191
+ * @vd: vdp data for the interface
c639191
+ *
c639191
+ * returns the number of VSIs found
c639191
+ *
c639191
+ * walk through the list of VSIs and return the count.
c639191
+ */
c639191
+int vdp_vsis_pending(struct vdp_data *vd)
c639191
+{
c639191
+	struct vsi_profile *p;
c639191
+	int count = 0;
c639191
+
c639191
+	LIST_FOREACH(p, &vd->profile_head, profile) {
c639191
+		if (p->localChange && (p->ackReceived == false))
c639191
+			count++;
c639191
+	}
c639191
+
c639191
+	return count;
c639191
+}
c639191
+
c639191
 /* vdp_somethingChangedLocal - set flag if profile has changed
c639191
  * @profile: profile to set the flag for
c639191
  * @flag: set the flag to true or false
c639191
-- 
c639191
1.7.4.4
c639191