Skip to content

Commit dc4889e

Browse files
PavelVPVcarlescufi
authored andcommitted
tests: bluetooth: mesh: Test RPL fragmentation
Ensure that RPL fragmentation doesn't occur. Signed-off-by: Pavel Vasilyev <[email protected]>
1 parent 953f8ee commit dc4889e

File tree

2 files changed

+232
-0
lines changed

2 files changed

+232
-0
lines changed

tests/bluetooth/bsim_bt/bsim_test_mesh/src/test_replay_cache.c

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include "settings_test_backend.h"
88
#include "mesh/mesh.h"
99
#include "mesh/net.h"
10+
#include "mesh/rpl.h"
11+
#include "mesh/transport.h"
1012

1113
#define LOG_MODULE_NAME test_rpc
1214

@@ -192,6 +194,214 @@ static void test_rx_power_replay_attack(void)
192194
PASS();
193195
}
194196

197+
static void send_end_cb(int err, void *cb_data)
198+
{
199+
struct k_sem *sem = cb_data;
200+
201+
ASSERT_EQUAL(err, 0);
202+
k_sem_give(sem);
203+
}
204+
205+
static bool msg_send(uint16_t src, uint16_t dst)
206+
{
207+
struct bt_mesh_send_cb cb = {
208+
.end = send_end_cb,
209+
};
210+
struct bt_mesh_msg_ctx ctx = {
211+
.net_idx = 0,
212+
.app_idx = 0,
213+
.addr = dst,
214+
.send_rel = false,
215+
.send_ttl = BT_MESH_TTL_DEFAULT,
216+
};
217+
struct bt_mesh_net_tx tx = {
218+
.ctx = &ctx,
219+
.src = src,
220+
};
221+
struct k_sem sem;
222+
int err;
223+
224+
k_sem_init(&sem, 0, 1);
225+
BT_MESH_MODEL_BUF_DEFINE(msg, TEST_MSG_OP_1, 0);
226+
227+
bt_mesh_model_msg_init(&msg, TEST_MSG_OP_1);
228+
229+
err = bt_mesh_trans_send(&tx, &msg, &cb, &sem);
230+
if (err) {
231+
LOG_ERR("Failed to send message (err %d)", err);
232+
return false;
233+
}
234+
235+
err = k_sem_take(&sem, K_SECONDS(10));
236+
if (err) {
237+
LOG_ERR("Send timed out (err %d)", err);
238+
return false;
239+
}
240+
241+
return true;
242+
}
243+
244+
static bool msg_recv(uint16_t expected_addr)
245+
{
246+
struct bt_mesh_test_msg msg;
247+
int err;
248+
249+
err = bt_mesh_test_recv_msg(&msg, K_SECONDS(10));
250+
if (err) {
251+
LOG_ERR("Failed to receive message from %u (err %d)", expected_addr, err);
252+
return false;
253+
}
254+
255+
LOG_DBG("Received msg from %u", msg.ctx.addr);
256+
ASSERT_EQUAL(expected_addr, msg.ctx.addr);
257+
258+
return true;
259+
}
260+
261+
static bool ivi_update_toggle(void)
262+
{
263+
bool res;
264+
265+
bt_mesh_iv_update_test(true);
266+
res = bt_mesh_iv_update();
267+
bt_mesh_iv_update_test(false);
268+
269+
return res;
270+
}
271+
272+
static void test_rx_rpl_frag(void)
273+
{
274+
settings_test_backend_clear();
275+
bt_mesh_test_setup();
276+
277+
k_sleep(K_SECONDS(10));
278+
279+
/* Wait 3 messages from different sources. */
280+
for (int i = 0; i < 3; i++) {
281+
ASSERT_TRUE(msg_recv(100 + i));
282+
}
283+
284+
/* Ask tx node to proceed to next test step. */
285+
ASSERT_TRUE(msg_send(rx_cfg.addr, tx_cfg.addr));
286+
287+
/* Start IVI Update. This will set old_iv for all entries in RPL to 1. */
288+
ASSERT_TRUE(ivi_update_toggle());
289+
290+
/* Receive messages from even nodes with new IVI. RPL entry with odd address will stay
291+
* with old IVI.
292+
*/
293+
ASSERT_TRUE(msg_recv(100));
294+
ASSERT_TRUE(msg_recv(102));
295+
296+
/* Ask tx node to proceed to next test step. */
297+
ASSERT_TRUE(msg_send(rx_cfg.addr, tx_cfg.addr));
298+
299+
/* Complete IVI Update. */
300+
ASSERT_FALSE(ivi_update_toggle());
301+
302+
/* Bump SeqNum in RPL for even addresses. */
303+
ASSERT_TRUE(msg_recv(100));
304+
ASSERT_TRUE(msg_recv(102));
305+
306+
/* Start IVI Update again. */
307+
/* RPL entry with odd address should be removed causing fragmentation in RPL. old_iv flag
308+
* for even entries will be set to 1.
309+
*/
310+
ASSERT_TRUE(ivi_update_toggle());
311+
312+
/* Ask tx node to proceed to next test step. */
313+
ASSERT_TRUE(msg_send(rx_cfg.addr, tx_cfg.addr));
314+
315+
/* Complete IVI Update. */
316+
ASSERT_FALSE(ivi_update_toggle());
317+
318+
/* Odd address entry should have been removed keeping even addresses accessible. */
319+
struct bt_mesh_rpl *rpl = NULL;
320+
struct bt_mesh_net_rx rx = {
321+
.old_iv = 1,
322+
.seq = 0,
323+
.ctx.addr = 100,
324+
.local_match = 1,
325+
};
326+
ASSERT_TRUE(bt_mesh_rpl_check(&rx, &rpl));
327+
rx.ctx.addr = 101;
328+
ASSERT_FALSE(bt_mesh_rpl_check(&rx, &rpl));
329+
rx.ctx.addr = 102;
330+
ASSERT_TRUE(bt_mesh_rpl_check(&rx, &rpl));
331+
332+
/* Let the settings store RPL. */
333+
k_sleep(K_SECONDS(CONFIG_BT_MESH_RPL_STORE_TIMEOUT));
334+
335+
PASS();
336+
}
337+
338+
static void test_tx_rpl_frag(void)
339+
{
340+
settings_test_backend_clear();
341+
bt_mesh_test_setup();
342+
343+
k_sleep(K_SECONDS(10));
344+
345+
/* Send message for 3 different addresses. */
346+
for (size_t i = 0; i < 3; i++) {
347+
ASSERT_TRUE(msg_send(100 + i, rx_cfg.addr));
348+
}
349+
350+
k_sleep(K_SECONDS(3));
351+
352+
/* Wait for the rx node. */
353+
ASSERT_TRUE(msg_recv(rx_cfg.addr));
354+
355+
/* Start IVI Update. */
356+
ASSERT_TRUE(ivi_update_toggle());
357+
358+
/* Send msg from elem 1 and 3 with new IVI. 2nd elem should have old IVI. */
359+
ASSERT_TRUE(msg_send(100, rx_cfg.addr));
360+
ASSERT_TRUE(msg_send(102, rx_cfg.addr));
361+
362+
/* Wait for the rx node. */
363+
ASSERT_TRUE(msg_recv(rx_cfg.addr));
364+
365+
/* Complete IVI Update. */
366+
ASSERT_FALSE(ivi_update_toggle());
367+
368+
/* Send message from even addresses with new IVI keeping odd address with old IVI. */
369+
ASSERT_TRUE(msg_send(100, rx_cfg.addr));
370+
ASSERT_TRUE(msg_send(102, rx_cfg.addr));
371+
372+
/* Start IVI Update again to be in sync with rx node. */
373+
ASSERT_TRUE(ivi_update_toggle());
374+
375+
/* Wait for rx node. */
376+
ASSERT_TRUE(msg_recv(rx_cfg.addr));
377+
378+
/* Complete IVI Update. */
379+
ASSERT_FALSE(ivi_update_toggle());
380+
381+
PASS();
382+
}
383+
384+
static void test_rx_reboot_after_defrag(void)
385+
{
386+
bt_mesh_test_setup();
387+
388+
/* Test that RPL entries are restored correctly after defrag and reboot. */
389+
struct bt_mesh_rpl *rpl = NULL;
390+
struct bt_mesh_net_rx rx = {
391+
.old_iv = 1,
392+
.seq = 0,
393+
.ctx.addr = 100,
394+
.local_match = 1,
395+
};
396+
ASSERT_TRUE(bt_mesh_rpl_check(&rx, &rpl));
397+
rx.ctx.addr = 101;
398+
ASSERT_FALSE(bt_mesh_rpl_check(&rx, &rpl));
399+
rx.ctx.addr = 102;
400+
ASSERT_TRUE(bt_mesh_rpl_check(&rx, &rpl));
401+
402+
PASS();
403+
}
404+
195405
#define TEST_CASE(role, name, description) \
196406
{ \
197407
.test_id = "rpc_" #role "_" #name, \
@@ -204,9 +414,12 @@ static void test_rx_power_replay_attack(void)
204414
static const struct bst_test_instance test_rpc[] = {
205415
TEST_CASE(tx, immediate_replay_attack, "RPC: perform replay attack immediately"),
206416
TEST_CASE(tx, power_replay_attack, "RPC: perform replay attack after power cycle"),
417+
TEST_CASE(tx, rpl_frag, "RPC: Send messages after double IVI Update"),
207418

208419
TEST_CASE(rx, immediate_replay_attack, "RPC: device under immediate attack"),
209420
TEST_CASE(rx, power_replay_attack, "RPC: device under power cycle reply attack"),
421+
TEST_CASE(rx, rpl_frag, "RPC: Test RPL fragmentation after double IVI Update"),
422+
TEST_CASE(rx, reboot_after_defrag, "RPC: Test PRL after defrag and reboot"),
210423
BSTEST_END_MARKER
211424
};
212425

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/usr/bin/env bash
2+
# Copyright 2022 Nordic Semiconductor
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
source $(dirname "${BASH_SOURCE[0]}")/../../_mesh_test.sh
6+
7+
# Test fragmentation of RPL:
8+
# 1. Send a message from 3 different consecutive nodes starting from address 100;
9+
# 2. Toggle IV index update;
10+
# 3. Send a new message from even addresses. This should update IVI index of RPL for these nodes.
11+
# The RPL entry odd address should stay unchanged;
12+
# 4. Complete IVI Update;
13+
# 5. Repeate steps 2 - 4 to remove RPL entry with odd address from RPL and cause fragmentation;
14+
conf=prj_pst_conf
15+
RunTest mesh_replay_fragmentation rpc_rx_rpl_frag rpc_tx_rpl_frag
16+
17+
# Simulate reboot and test that RPL entries are restored correctly after defragmentation
18+
conf=prj_pst_conf
19+
RunTest mesh_replay_fragmentation rpc_rx_reboot_after_defrag

0 commit comments

Comments
 (0)