summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYacine Belkadi2013-04-02 17:19:37 +0200
committerYacine Belkadi2013-05-22 10:53:35 +0200
commitea60421c65baf82304c3b461d8bfb60106b4a404 (patch)
tree3f7396d019f98f6eeb58e8384db1b4ca9c12f562
parent7d5605d2370e0bf0ef1227cba9e4f5d7b37e839c (diff)
cesar/{bsu,cp/beacon}: let the bsu clear the previous NEK, refs #3794
After a NEK change, the previous NEK needs to be cleared. This was done by the cp. But: 1) The cp may run long after the NEK change, and may get interrupted. This delays the removal of the old key. 2) The cp only _guesses_ when the NEK change is done (see cp_beacon_countdowns()). If, for some reasons, the guess is wrong because the NEK change didn't happen yet, then the cp will actually clear the new key before it's used. It seems more reliable to let the bsu clear the old key, because the bsu is the one doing the NEK change.
-rw-r--r--cesar/bsu/inc/context.h3
-rw-r--r--cesar/bsu/src/bsu.c17
-rw-r--r--cesar/bsu/test/utest/src/bsut.c20
-rw-r--r--cesar/cp/av/beacon/test/utest/src/beacon.c2
-rw-r--r--cesar/cp/beacon/src/beacon.c2
5 files changed, 39 insertions, 5 deletions
diff --git a/cesar/bsu/inc/context.h b/cesar/bsu/inc/context.h
index 58c2f87316..9bcc4a1410 100644
--- a/cesar/bsu/inc/context.h
+++ b/cesar/bsu/inc/context.h
@@ -120,6 +120,9 @@ struct bsu_t
u32 beacon_nb_recv[BSU_BEACON_TYPE_NB];
/** NEK switch. */
uint nek_switch;
+ /** Previous value of nek_switch.
+ * Used to detect a change to nek_switch. */
+ uint prev_nek_switch;
/** Station's discover info updated by CP. */
bsu_beacon_bmi_discover_info_t discover_info;
/** NTB clock synchronization weight configuration. k is for 1/2^k. */
diff --git a/cesar/bsu/src/bsu.c b/cesar/bsu/src/bsu.c
index 0e82455c95..59c6c97b5b 100644
--- a/cesar/bsu/src/bsu.c
+++ b/cesar/bsu/src/bsu.c
@@ -701,6 +701,21 @@ bsu_handle_key_change (bsu_t *ctx)
else
avln->beacon.bmis.eks.present = false;
}
+ else
+ {
+ /* No key change to handle.
+ * But did we change nek_switch on the previous run of this function? */
+ if (ctx->nek_switch != ctx->prev_nek_switch)
+ {
+ /* On the previous run of this function, we changed nek_switch.
+ * This means that a NEK change occured at the start of the current
+ * beacon period. The new NEK (if we had it) should now be in use,
+ * and we can remove the old NEK. */
+ ctx->mac_config->nek[!ctx->nek_switch].eks = MAC_EKS_CLEAR;
+
+ ctx->prev_nek_switch = ctx->nek_switch;
+ }
+ }
}
/**
@@ -1335,7 +1350,7 @@ bsu_power_on (bsu_t *ctx, u8 snid)
arch_dsr_lock ();
ctx->sta_avln = &ctx->poweron;
ctx->sta_avln->snid = snid;
- ctx->nek_switch = 0;
+ ctx->prev_nek_switch = ctx->nek_switch = 0;
dbg_assert (ctx->sta_avln->beacon.bmis.ps.nb != 0
|| ctx->sta_avln->beacon.bmis.nps.ns != 0);
arch_dsr_unlock ();
diff --git a/cesar/bsu/test/utest/src/bsut.c b/cesar/bsu/test/utest/src/bsut.c
index 08d2ad206a..6a90df5d57 100644
--- a/cesar/bsu/test/utest/src/bsut.c
+++ b/cesar/bsu/test/utest/src/bsut.c
@@ -897,6 +897,26 @@ test_case_bsu_handle_key_change (test_t test)
test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.kccd == 1);
}
test_end;
+ test_begin (test, "Delete previous NEK after NEK change");
+ {
+ t.bsu->nek_switch = 0;
+ t.mac_config.nek[0].eks = MAC_EKS_MIN;
+ t.mac_config.nek[1].eks = MAC_EKS_MAX;
+ t.bsu->sta_avln->beacon.bmis.eks.present = true;
+ t.bsu->sta_avln->beacon.bmis.eks.kbc = BSU_BEACON_EKS_KBC_NEK;
+ t.bsu->sta_avln->beacon.bmis.eks.kccd = 1;
+
+ bsu_handle_key_change (t.bsu);
+
+ test_fail_unless (t.mac_config.nek[0].eks == MAC_EKS_MIN);
+ test_fail_unless (t.mac_config.nek[1].eks == MAC_EKS_MAX);
+
+ bsu_handle_key_change (t.bsu);
+
+ test_fail_unless (t.mac_config.nek[0].eks == MAC_EKS_CLEAR);
+ test_fail_unless (t.mac_config.nek[1].eks == MAC_EKS_MAX);
+ }
+ test_end;
bsu_test_uninit (&t);
}
diff --git a/cesar/cp/av/beacon/test/utest/src/beacon.c b/cesar/cp/av/beacon/test/utest/src/beacon.c
index 9b1e5d8de5..3be921f164 100644
--- a/cesar/cp/av/beacon/test/utest/src/beacon.c
+++ b/cesar/cp/av/beacon/test/utest/src/beacon.c
@@ -640,8 +640,6 @@ test_case_beacon_eks_change_sta (test_t test)
test_fail_unless (
ctx.mac_config.nek[bsu_nek_index_current (INVALID_PTR)].eks ==
ref_eks_current);
- test_fail_unless (ctx.mac_config.nek[bsu_nek_index_next (INVALID_PTR)].eks ==
- MAC_EKS_CLEAR);
dbg_check (mac_store_sta_remove (ctx.cp.mac_store, 1));
test_beacon_uninit (&ctx);
}
diff --git a/cesar/cp/beacon/src/beacon.c b/cesar/cp/beacon/src/beacon.c
index 34223e7942..90371a6620 100644
--- a/cesar/cp/beacon/src/beacon.c
+++ b/cesar/cp/beacon/src/beacon.c
@@ -468,8 +468,6 @@ cp_beacon_countdowns (cp_t *ctx)
cp_fsm_trigger_new_event (ctx, bare, to_leave);
ctx->beacon.eks.kbc = BSU_BEACON_EKS_KBC_NB;
- ctx->mac_config->nek[bsu_nek_index_next (ctx->bsu)].eks =
- MAC_EKS_CLEAR;
}
}
}