Skip to content

Commit 61b34a8

Browse files
committed
Bluetooth: Mesh: Make network msg cache netkey aware
Improve the network message cache to be aware of network keys to prevent false duplicate detection across different subnets. This ensures that messages with the same source address and sequence number but from different network keys are not incorrectly identified as duplicates, as it can happen in certain cases. See ES-27446. The approach uses credential pointer which never changes during runtime of the node as a proxy for netkey identification. This approach is simplified but still solves the need and avoids major changes to msg_cache_add() function as NID/NetKey index information is not sufficiently unambiguous at the time when this API is called. Because the information is hidden in two sub[] arrays within rx context and to decipher this info (to arrive at correct NID/NetKey) you will need several checks to figure out which state of the key refresh procedure is active, and which friendship/LPN function is active, and exactly which credential is being used. Signed-off-by: Omkar Kulkarni <omkar.kulkarni@nordicsemi.no>
1 parent 06daf0e commit 61b34a8

File tree

2 files changed

+19
-8
lines changed

2 files changed

+19
-8
lines changed

subsys/bluetooth/mesh/net.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ struct iv_val {
8282

8383
static struct {
8484
uint32_t src : 15, /* MSb of source is always 0 */
85-
seq : 17;
85+
seq : 17;
86+
const struct bt_mesh_net_cred *cred;
8687
} msg_cache[CONFIG_BT_MESH_MSG_CACHE_SIZE];
8788
static uint16_t msg_cache_next;
8889

@@ -145,20 +146,22 @@ static bool check_dup(struct net_buf_simple *data)
145146
return false;
146147
}
147148

148-
static bool msg_cache_match(struct net_buf_simple *pdu)
149+
static bool msg_cache_match(struct net_buf_simple *pdu, const struct bt_mesh_net_cred *cred)
149150
{
150151
uint16_t i;
151152

152153
for (i = msg_cache_next; i > 0U;) {
153154
if (msg_cache[--i].src == SRC(pdu->data) &&
154-
msg_cache[i].seq == (SEQ(pdu->data) & BIT_MASK(17))) {
155+
msg_cache[i].seq == (SEQ(pdu->data) & BIT_MASK(17)) &&
156+
msg_cache[i].cred == cred) {
155157
return true;
156158
}
157159
}
158160

159161
for (i = ARRAY_SIZE(msg_cache); i > msg_cache_next;) {
160162
if (msg_cache[--i].src == SRC(pdu->data) &&
161-
msg_cache[i].seq == (SEQ(pdu->data) & BIT_MASK(17))) {
163+
msg_cache[i].seq == (SEQ(pdu->data) & BIT_MASK(17)) &&
164+
msg_cache[i].cred == cred) {
162165
return true;
163166
}
164167
}
@@ -171,6 +174,7 @@ static void msg_cache_add(struct bt_mesh_net_rx *rx)
171174
msg_cache_next %= ARRAY_SIZE(msg_cache);
172175
msg_cache[msg_cache_next].src = rx->ctx.addr;
173176
msg_cache[msg_cache_next].seq = rx->seq;
177+
msg_cache[msg_cache_next].cred = rx->cred;
174178
msg_cache_next++;
175179
}
176180

@@ -402,6 +406,7 @@ static void bt_mesh_net_local(struct k_work *work)
402406
while ((node = sys_slist_get(&bt_mesh.local_queue))) {
403407
struct loopback_buf *buf = CONTAINER_OF(node, struct loopback_buf, node);
404408
struct bt_mesh_net_rx rx = {
409+
.cred = &buf->sub->keys[SUBNET_KEY_TX_IDX(buf->sub)].msg,
405410
.ctx = {
406411
.net_idx = buf->sub->net_idx,
407412
/* Initialize AppIdx to a sane value */
@@ -653,15 +658,20 @@ static bool net_decrypt(struct bt_mesh_net_rx *rx, struct net_buf_simple *in,
653658
return false;
654659
}
655660

656-
if (rx->net_if == BT_MESH_NET_IF_ADV && msg_cache_match(out)) {
661+
if (rx->net_if == BT_MESH_NET_IF_ADV && msg_cache_match(out, cred)) {
657662
LOG_DBG("Duplicate found in Network Message Cache");
658663
return false;
659664
}
660665

661666
LOG_DBG("src 0x%04x", rx->ctx.addr);
662667

663-
return bt_mesh_net_decrypt(&cred->enc, out, BT_MESH_NET_IVI_RX(rx),
664-
proxy) == 0;
668+
int err = bt_mesh_net_decrypt(&cred->enc, out, BT_MESH_NET_IVI_RX(rx), proxy);
669+
670+
if (!err) {
671+
rx->cred = cred;
672+
}
673+
674+
return err == 0;
665675
}
666676

667677
/* Relaying from advertising to the advertising bearer should only happen
@@ -865,7 +875,7 @@ void bt_mesh_net_recv(struct net_buf_simple *data, int8_t rssi,
865875
enum bt_mesh_net_if net_if)
866876
{
867877
NET_BUF_SIMPLE_DEFINE(buf, BT_MESH_NET_MAX_PDU_LEN);
868-
struct bt_mesh_net_rx rx = { .ctx.recv_rssi = rssi };
878+
struct bt_mesh_net_rx rx = { .cred = NULL, .ctx.recv_rssi = rssi };
869879
struct net_buf_simple_state state;
870880
int err;
871881

subsys/bluetooth/mesh/net.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ enum bt_mesh_net_if {
260260
/* Decoding context for Network/Transport data */
261261
struct bt_mesh_net_rx {
262262
struct bt_mesh_subnet *sub;
263+
const struct bt_mesh_net_cred *cred;
263264
struct bt_mesh_msg_ctx ctx;
264265
uint32_t seq; /* Sequence Number */
265266
uint8_t old_iv:1, /* iv_index - 1 was used */

0 commit comments

Comments
 (0)