6c9f0c
From 37e9f511eb0072dbce190cb21e2d48f022173b03 Mon Sep 17 00:00:00 2001
6c9f0c
Message-Id: <37e9f511eb0072dbce190cb21e2d48f022173b03.1488376602.git.dcaratti@redhat.com>
6c9f0c
From: Badrish Adiga H R <badrish.adigahr@gmail.com>
6c9f0c
Date: Tue, 7 Feb 2017 14:28:31 +0530
6c9f0c
Subject: [PATCH] mka: Send MKPDUs forever if mode is PSK
6c9f0c
6c9f0c
Issue: When 2 peers are running MACsec in PSK mode with CA
6c9f0c
established, if the interface goes down and comes up after
6c9f0c
time > 10 seconds, CA does not get re-established.
6c9f0c
6c9f0c
Root cause: This is because retry_count of both the peers
6c9f0c
would have reached MAX_RETRY_CNT and stays idle for other to
6c9f0c
respond. This is clear deadlock situation where peer A waits
6c9f0c
for MKA packets from peer B to wake up and vice-versa.
6c9f0c
6c9f0c
Fix: If MACsec is running in PSK mode, we should send MKPDUs
6c9f0c
forever for every 2 seconds.
6c9f0c
6c9f0c
Signed-off-by: Badrish Adiga H R <badrish.adigahr@gmail.com>
6c9f0c
---
6c9f0c
 src/pae/ieee802_1x_kay.c   | 6 ++++--
6c9f0c
 src/pae/ieee802_1x_kay_i.h | 1 +
6c9f0c
 2 files changed, 5 insertions(+), 2 deletions(-)
6c9f0c
6c9f0c
diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
6c9f0c
index 92fd7ba..e420fc1 100644
6c9f0c
--- a/src/pae/ieee802_1x_kay.c
6c9f0c
+++ b/src/pae/ieee802_1x_kay.c
6c9f0c
@@ -2428,7 +2428,8 @@ static void ieee802_1x_participant_timer(void *eloop_ctx, void *timeout_ctx)
6c9f0c
 		participant->new_sak = FALSE;
6c9f0c
 	}
6c9f0c
 
6c9f0c
-	if (participant->retry_count < MAX_RETRY_CNT) {
6c9f0c
+	if (participant->retry_count < MAX_RETRY_CNT ||
6c9f0c
+	    participant->mode == PSK) {
6c9f0c
 		ieee802_1x_participant_send_mkpdu(participant);
6c9f0c
 		participant->retry_count++;
6c9f0c
 	}
6c9f0c
@@ -2828,7 +2829,7 @@ int ieee802_1x_kay_enable_new_info(struct ieee802_1x_kay *kay)
6c9f0c
 	if (!principal)
6c9f0c
 		return -1;
6c9f0c
 
6c9f0c
-	if (principal->retry_count < MAX_RETRY_CNT) {
6c9f0c
+	if (principal->retry_count < MAX_RETRY_CNT || principal->mode == PSK) {
6c9f0c
 		ieee802_1x_participant_send_mkpdu(principal);
6c9f0c
 		principal->retry_count++;
6c9f0c
 	}
6c9f0c
@@ -3368,6 +3369,7 @@ ieee802_1x_kay_create_mka(struct ieee802_1x_kay *kay, struct mka_key_name *ckn,
6c9f0c
 		participant->mka_life = MKA_LIFE_TIME / 1000 + time(NULL) +
6c9f0c
 			usecs / 1000000;
6c9f0c
 	}
6c9f0c
+	participant->mode = mode;
6c9f0c
 
6c9f0c
 	return participant;
6c9f0c
 
6c9f0c
diff --git a/src/pae/ieee802_1x_kay_i.h b/src/pae/ieee802_1x_kay_i.h
6c9f0c
index 0c4bb8e..bc522d8 100644
6c9f0c
--- a/src/pae/ieee802_1x_kay_i.h
6c9f0c
+++ b/src/pae/ieee802_1x_kay_i.h
6c9f0c
@@ -93,6 +93,7 @@ struct ieee802_1x_mka_participant {
6c9f0c
 	Boolean active;
6c9f0c
 	Boolean participant;
6c9f0c
 	Boolean retain;
6c9f0c
+	enum mka_created_mode mode;
6c9f0c
 
6c9f0c
 	enum { DEFAULT, DISABLED, ON_OPER_UP, ALWAYS } activate;
6c9f0c
 
6c9f0c
-- 
6c9f0c
2.7.4
6c9f0c