Blob Blame History Raw
From 626a6d414fe8292cf599777317a9347e813c7c01 Mon Sep 17 00:00:00 2001
From: Jens Osterkamp <jens@linux.vnet.ibm.com>
Date: Wed, 6 Apr 2011 08:34:14 -0700
Subject: [PATCH 32/51] avoid duplicate deassociation

In case a deassociation is received, the VSI state machine should not send
out a duplicate deassociate. Deassociate should only be sent if requested
via netlink by libvirt, by commandline with lldptool or if a negative
response was received by the switch as response to a previous request.

Signed-off-by: Jens Osterkamp <jens@linux.vnet.ibm.com>
Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
Signed-off-by: Petr Sabata <psabata@redhat.com>
---
 include/lldp_vdp.h |    1 +
 lldp_vdp.c         |   17 ++++++++++++-----
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/include/lldp_vdp.h b/include/lldp_vdp.h
index 60d87c9..4b7054b 100644
--- a/include/lldp_vdp.h
+++ b/include/lldp_vdp.h
@@ -128,6 +128,7 @@ struct vsi_profile {
 	int state;
 	int seqnr;
 	bool localChange;
+	bool remoteChange;
 	LIST_ENTRY(vsi_profile) profile;
 };
 
diff --git a/lldp_vdp.c b/lldp_vdp.c
index c530c0d..7be0b1c 100644
--- a/lldp_vdp.c
+++ b/lldp_vdp.c
@@ -480,8 +480,10 @@ static bool vdp_vsi_set_station_state(struct vsi_profile *profile)
 		if (profile->mode == VDP_MODE_PREASSOCIATE) {
 			vdp_vsi_change_station_state(profile, VSI_PREASSOC_PROCESSING);
 			return true;
-		} else if ((profile->mode == VDP_MODE_DEASSOCIATE) ||
-			   vdp_vsi_negative_response(profile)) {
+		} else if (profile->mode == VDP_MODE_DEASSOCIATE) {
+			vdp_vsi_change_station_state(profile, VSI_DEASSOC_PROCESSING);
+			return true;
+		} else if (vdp_vsi_negative_response(profile)) {
 			vdp_vsi_change_station_state(profile, VSI_DEASSOC_PROCESSING);
 			vdp_somethingChangedLocal(profile, true);
 			return true;
@@ -518,7 +520,8 @@ static bool vdp_vsi_set_station_state(struct vsi_profile *profile)
 		}
 		return false;
 	case VSI_DEASSOC_PROCESSING:
-		if ((profile->ackReceived) || vdp_ackTimer_expired(profile)) {
+		if ((profile->ackReceived) || vdp_ackTimer_expired(profile) ||
+		    profile->remoteChange) {
 			vdp_vsi_change_station_state(profile, VSI_EXIT);
 			return true;
 		}
@@ -590,7 +593,6 @@ void vdp_vsi_sm_station(struct vsi_profile *profile)
 			}
 			break;
 		case VSI_EXIT:
-			/* TODO: send DEASSOC here ? */
 			vdp_stop_ackTimer(profile);
 			vdp_stop_keepaliveTimer(profile);
 			vdp_remove_profile(profile);
@@ -927,7 +929,12 @@ int vdp_indicate(struct vdp_data *vd, struct unpacked_tlv *tlv, int ecp_mode)
 
 				p->ackReceived = true;
 				p->keepaliveTimer = VDP_KEEPALIVE_TIMER_DEFAULT;
-				p->mode = vdp->mode;
+				if (vdp->mode != p->mode) {
+					p->mode = vdp->mode;
+					p->remoteChange = true;
+					LLDPAD_DBG("%s(%i): station: remoteChange %i !\n",
+						   __func__, __LINE__, p->remoteChange);
+				}
 				p->response = vdp->response;
 
 				if (vdp_vsi_negative_response(p))
-- 
1.7.4.4