summaryrefslogtreecommitdiff
path: root/cesar/bsu
diff options
context:
space:
mode:
authorNélio Laranjeiro2011-03-15 16:25:18 +0100
committerNélio Laranjeiro2011-03-15 17:12:38 +0100
commit0c4b0dac6040f36507026ac12891bc09921e5b09 (patch)
tree8c28c4645b01791688a09908e7a0425d8316c447 /cesar/bsu
parent7ae842f5334731fccb674fe8e4e4764ec0f52dd6 (diff)
cesar/bsu: save sta_avln when positioned after the removed avln, closes #2399
bsu_avln_remove corrupts the sta_avln pointer when it removes the AVLN in positions before in the table.
Diffstat (limited to 'cesar/bsu')
-rw-r--r--cesar/bsu/src/bsu.c5
-rw-r--r--cesar/bsu/test/utest/src/bsut.c36
2 files changed, 41 insertions, 0 deletions
diff --git a/cesar/bsu/src/bsu.c b/cesar/bsu/src/bsu.c
index 50893eb929..03ef287843 100644
--- a/cesar/bsu/src/bsu.c
+++ b/cesar/bsu/src/bsu.c
@@ -247,10 +247,15 @@ bsu_avln_remove (u64 nid, u8 snid, mac_t mac)
}
if (to_remove)
{
+ /* Station's AVLN is the removed one. */
if (to_remove == ctx->sta_avln)
bsu_track_avln_identify (ctx, NULL);
for (i = pos; i < ctx->avlns_nb - 1; i++)
+ {
+ if (ctx->sta_avln == &ctx->avlns[i+1])
+ ctx->sta_avln = &ctx->avlns[i];
ctx->avlns[i] = ctx->avlns[i+1];
+ }
ctx->avlns_nb--;
}
}
diff --git a/cesar/bsu/test/utest/src/bsut.c b/cesar/bsu/test/utest/src/bsut.c
index eb437fb717..7e22d519cc 100644
--- a/cesar/bsu/test/utest/src/bsut.c
+++ b/cesar/bsu/test/utest/src/bsut.c
@@ -850,6 +850,41 @@ test_case_bsu_add_avln_array_full (test_t t)
}
void
+test_case_bsu_avln_remove (test_t t)
+{
+ test_case_begin (t, "AVLN remove");
+ test_begin (
+ t, "add and remove avlns with sta_avln setted before and after")
+ {
+ bsu_test_t ctx;
+ bsu_test_init (&ctx);
+ bool added;
+ uint i;
+ for (i = 0; i < BSU_FOREIGN_AVLNS_NB; i++)
+ {
+ bsu_avln_add (ctx.bsu, i, i, i, &added);
+ test_fail_unless (added);
+ }
+ /* sta_avln is the one removed. */
+ ctx.bsu->sta_avln = &ctx.bsu->avlns[1];
+ /* Reinitialise the sync information wrote by bsu_test_init. */
+ bsu_ntb_init (&ctx.bsu->poweron.sync);
+ bsu_avln_remove (1, 1, 1);
+ test_fail_unless (ctx.bsu->sta_avln == &ctx.bsu->poweron);
+ /* sta_avln is the first one. */
+ ctx.bsu->sta_avln = &ctx.bsu->avlns[0];
+ bsu_avln_remove (2, 2, 2);
+ test_fail_unless (ctx.bsu->sta_avln == &ctx.bsu->avlns[0]);
+ /* sta_avln is the 4th one. */
+ ctx.bsu->sta_avln = &ctx.bsu->avlns[4];
+ bsu_avln_remove (3, 3, 3);
+ test_fail_unless (ctx.bsu->sta_avln == &ctx.bsu->avlns[3]);
+ bsu_test_uninit (&ctx);
+ }
+ test_end;
+}
+
+void
test_suite_bsu (test_t t)
{
test_suite_begin (t, "BSU test");
@@ -863,4 +898,5 @@ test_suite_bsu (test_t t)
test_case_bsu_nek_index (t);
test_case_bsu_discover_update (t);
test_case_bsu_add_avln_array_full (t);
+ test_case_bsu_avln_remove (t);
}