diff mbox

mka: Send MKPDUs forever if mode is PSK

Message ID CAGNNFCY+r7TRB-0v7kka+NbKSF19ScDdzqG1JO81avK-Z8DXCw@mail.gmail.com
State Accepted
Headers show

Commit Message

Badrish Adiga H R Feb. 7, 2017, 8:58 a.m. UTC
Issue: When 2 peers are running MACsec in PSK mode with CA
established, if the interface goes down and comes up after
time > 10 seconds, CA does not get re-established.

Root cause: This is because retry_count of both the peers
would have reached MAX_RETRY_CNT and stays idle for other to
respond. This is clear deadlock situation where peer A waits
for MKA packets from peer B to wake up and vice-versa.

Fix: If MACsec is running in PSK mode, we should send MKPDUs
forever for every 2 seconds.

Signed-off-by: Badrish Adiga H R <badrish.adigahr@gmail.com>
---
 src/pae/ieee802_1x_kay.c   | 17 +++++++++++++----
 src/pae/ieee802_1x_kay_i.h |  1 +
 2 files changed, 14 insertions(+), 4 deletions(-)

--
2.6.1.133.gf5b6079

Comments

Jouni Malinen Feb. 10, 2017, 6:09 p.m. UTC | #1
On Tue, Feb 07, 2017 at 02:28:31PM +0530, Badrish Adiga H R wrote:
> Issue: When 2 peers are running MACsec in PSK mode with CA
> established, if the interface goes down and comes up after
> time > 10 seconds, CA does not get re-established.
> 
> Root cause: This is because retry_count of both the peers
> would have reached MAX_RETRY_CNT and stays idle for other to
> respond. This is clear deadlock situation where peer A waits
> for MKA packets from peer B to wake up and vice-versa.
> 
> Fix: If MACsec is running in PSK mode, we should send MKPDUs
> forever for every 2 seconds.

Thanks, applied.
diff mbox

Patch

diff --git a/src/pae/ieee802_1x_kay.c b/src/pae/ieee802_1x_kay.c
index 92fd7ba..09e8998 100644
--- a/src/pae/ieee802_1x_kay.c
+++ b/src/pae/ieee802_1x_kay.c
@@ -2428,9 +2428,13 @@  static void ieee802_1x_participant_timer(void
*eloop_ctx, void *timeout_ctx)
                participant->new_sak = FALSE;
        }

-       if (participant->retry_count < MAX_RETRY_CNT) {
+       if (participant->mode == PSK) {
                ieee802_1x_participant_send_mkpdu(participant);
-               participant->retry_count++;
+       } else {
+               if (participant->retry_count < MAX_RETRY_CNT) {
+                       ieee802_1x_participant_send_mkpdu(participant);
+                       participant->retry_count++;
+               }
        }

        eloop_register_timeout(MKA_HELLO_TIME / 1000, 0,
@@ -2828,9 +2832,13 @@  int ieee802_1x_kay_enable_new_info(struct
ieee802_1x_kay *kay)
        if (!principal)
                return -1;

-       if (principal->retry_count < MAX_RETRY_CNT) {
+       if (principal->mode == PSK) {
                ieee802_1x_participant_send_mkpdu(principal);
-               principal->retry_count++;
+       } else {
+               if (principal->retry_count < MAX_RETRY_CNT) {
+                       ieee802_1x_participant_send_mkpdu(principal);
+                       principal->retry_count++;
+               }
        }

        return 0;
@@ -3368,6 +3376,7 @@  ieee802_1x_kay_create_mka(struct ieee802_1x_kay
*kay, struct mka_key_name *ckn,
                participant->mka_life = MKA_LIFE_TIME / 1000 + time(NULL) +
                        usecs / 1000000;
        }
+       participant->mode = mode;

        return participant;

diff --git a/src/pae/ieee802_1x_kay_i.h b/src/pae/ieee802_1x_kay_i.h
index 0c4bb8e..bc522d8 100644
--- a/src/pae/ieee802_1x_kay_i.h
+++ b/src/pae/ieee802_1x_kay_i.h
@@ -93,6 +93,7 @@  struct ieee802_1x_mka_participant {
        Boolean active;
        Boolean participant;
        Boolean retain;
+       enum mka_created_mode mode;

        enum { DEFAULT, DISABLED, ON_OPER_UP, ALWAYS } activate;