Skip to content

Commit 79adc52

Browse files
Florian Grandelfabiobaltieri
authored andcommitted
net: l2: ieee802154: ensure L2/L3 recv package handover
Issue #53630 proved that we didn't have sufficient test coverage for L2/L3 package handover on the RX side. This commit creates additional test coverage to reproduce the problem found in #53630 and avoid future regressions. Signed-off-by: Florian Grandel <[email protected]>
1 parent fadb1fd commit 79adc52

File tree

2 files changed

+123
-23
lines changed

2 files changed

+123
-23
lines changed

tests/net/ieee802154/l2/prj.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ CONFIG_NET_L2_IEEE802154_ACK_REPLY=y
1616
CONFIG_NET_SOCKETS=y
1717
CONFIG_NET_SOCKETS_PACKET=y
1818
CONFIG_NET_SOCKETS_PACKET_DGRAM=y
19+
CONFIG_NET_CONTEXT_RCVTIMEO=y
1920

2021
CONFIG_MBEDTLS=y
2122
CONFIG_MBEDTLS_BUILTIN=y

tests/net/ieee802154/l2/src/ieee802154_test.c

Lines changed: 122 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -444,36 +444,128 @@ static bool test_raw_packet_sending(void)
444444
return result;
445445
}
446446

447-
static bool test_ack_reply(struct ieee802154_pkt_test *t)
447+
static bool test_recv_and_ack_reply(struct ieee802154_pkt_test *t)
448448
{
449+
/* Incoming IEEE 802.15.4 packet with payload header compression. */
449450
static uint8_t data_pkt[] = {
450-
0x61, 0xdc, 0x16, 0xcd, 0xab, 0xc2, 0xa3, 0x9e, 0x00, 0x00, 0x4b,
451-
0x12, 0x00, 0x26, 0x18, 0x32, 0x00, 0x00, 0x4b, 0x12, 0x00, 0x7b,
452-
0x00, 0x3a, 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00,
453-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x01, 0x0d, 0xb8,
454-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
455-
0x02, 0x87, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01,
456-
0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
457-
0x16, 0xf0, 0x02, 0xff, 0x16, 0xf0, 0x12, 0xff, 0x16, 0xf0, 0x32,
458-
0xff, 0x16, 0xf0, 0x00, 0xff, 0x16, 0xf0, 0x00, 0xff, 0x16
451+
/* IEEE 802.15.4 MHR */
452+
0x61, 0xd8, /* FCF with AR bit set */
453+
0x16, /* Sequence */
454+
0xcd, 0xab, /* Destination PAN */
455+
0xff, 0xff, /* Destination Address */
456+
0xc2, 0xa3, 0x9e, 0x00, 0x00, 0x4b, 0x12, 0x00, /* Source Address */
457+
/* IEEE 802.15.4 MAC Payload */
458+
0x7b, 0x39, /* IPHC header, SAM: compressed, DAM: 48-bits inline */
459+
0x3a, /* Next header: ICMPv6 */
460+
0x02, 0x01, 0xff, 0x4b, 0x12, 0x00, /* IPv6 Destination */
461+
0x87, /* Type: NS */
462+
0x00, /* Code*/
463+
0xb7, 0x45, /* Checksum */
464+
0x00, 0x00, 0x00, 0x00, /* Reserved */
465+
0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x14, 0xa6, 0x1c, 0x00, 0x4b,
466+
0x12, 0x00, /* Target Address */
467+
0x01, /* ICMPv6 Option: Source LL address */
468+
0x02, /* Length */
469+
0xe5, 0xac, 0xa1, 0x1c, 0x00, 0x4b, 0x12, 0x00, /* LL address */
470+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Padding */
471+
};
472+
/* Expected uncompressed IPv6 payload. */
473+
static uint8_t expected_rx_pkt[] = {
474+
0x60, 0x00, 0x00, 0x00, /* IPv6, Traffic Class, Flow Label */
475+
0x00, 0x28, /* Payload Length */
476+
0x3a, /* Next header: ICMPv6 */
477+
0xff, /* Hop Limit */
478+
0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
479+
0x02, 0x12, 0x4b, 0x00, 0x00, 0x9e, 0xa3, 0xc2, /* Source */
480+
0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
481+
0x00, 0x00, 0x00, 0x01, 0xff, 0x4b, 0x12, 0x00, /* Destination */
482+
0x87, /* Type: NS */
483+
0x00, /* Code*/
484+
0xb7, 0x45, /* Checksum */
485+
0x00, 0x00, 0x00, 0x00, /* Reserved */
486+
0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
487+
0x70, 0x14, 0xa6, 0x1c, 0x00, 0x4b, 0x12, 0x00, /* Target Address */
488+
0x01, /* ICMPv6 Option: Source LL address */
489+
0x02, /* Length */
490+
0xe5, 0xac, 0xa1, 0x1c, 0x00, 0x4b, 0x12, 0x00, /* LL address */
491+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Padding */
492+
};
493+
struct ieee802154_context *ctx = net_if_l2_data(iface);
494+
struct sockaddr_ll recv_src_sll = {0};
495+
struct sockaddr_ll socket_sll = {
496+
.sll_ifindex = net_if_get_by_iface(iface),
497+
.sll_family = AF_PACKET,
498+
.sll_protocol = ETH_P_IEEE802154,
499+
};
500+
uint8_t received_payload[80] = {0};
501+
struct timeval timeo_optval = {
502+
.tv_sec = 1,
503+
.tv_usec = 0,
459504
};
460505
struct ieee802154_mpdu mpdu;
461-
struct net_pkt *pkt;
506+
socklen_t recv_src_sll_len;
462507
struct net_buf *frag;
508+
struct net_pkt *rx_pkt;
509+
bool result = false;
510+
uint8_t mac_be[8];
511+
int received_len;
512+
int fd;
463513

464514
NET_INFO("- Sending ACK reply to a data packet\n");
465515

466-
pkt = net_pkt_rx_alloc(K_FOREVER);
467-
frag = net_pkt_get_frag(pkt, sizeof(data_pkt), K_FOREVER);
516+
fd = socket(AF_PACKET, SOCK_DGRAM, ETH_P_IEEE802154);
517+
if (fd < 0) {
518+
NET_ERR("*** Failed to create DGRAM socket : %d\n", errno);
519+
goto out;
520+
}
521+
522+
if (bind(fd, (const struct sockaddr *)&socket_sll, sizeof(struct sockaddr_ll))) {
523+
NET_ERR("*** Failed to bind packet socket : %d\n", errno);
524+
goto release_fd;
525+
}
526+
527+
if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeo_optval, sizeof(timeo_optval))) {
528+
NET_ERR("*** Failed to set reception timeout on packet socket : %d\n", errno);
529+
goto release_fd;
530+
}
531+
532+
rx_pkt = net_pkt_rx_alloc(K_FOREVER);
533+
frag = net_pkt_get_frag(rx_pkt, sizeof(data_pkt), K_FOREVER);
468534

469535
memcpy(frag->data, data_pkt, sizeof(data_pkt));
470536
frag->len = sizeof(data_pkt);
471537

472-
net_pkt_frag_add(pkt, frag);
538+
net_pkt_frag_add(rx_pkt, frag);
473539

474-
if (net_recv_data(iface, pkt) < 0) {
540+
if (net_recv_data(iface, rx_pkt) < 0) {
475541
NET_ERR("Recv data failed");
476-
return false;
542+
goto release_rx_pkt;
543+
}
544+
545+
recv_src_sll_len = sizeof(recv_src_sll);
546+
received_len = recvfrom(fd, received_payload, sizeof(received_payload), 0,
547+
(struct sockaddr *)&recv_src_sll, &recv_src_sll_len);
548+
if (received_len < 0) {
549+
NET_ERR("*** Failed to receive packet, errno %d\n", errno);
550+
goto release_rx_pkt;
551+
}
552+
553+
sys_memcpy_swap(mac_be, ctx->ext_addr, IEEE802154_EXT_ADDR_LENGTH);
554+
if (recv_src_sll_len != sizeof(struct sockaddr_ll) ||
555+
recv_src_sll.sll_ifindex != net_if_get_by_iface(iface) ||
556+
recv_src_sll.sll_family != AF_PACKET || recv_src_sll.sll_protocol != ETH_P_IEEE802154 ||
557+
recv_src_sll.sll_halen != IEEE802154_EXT_ADDR_LENGTH ||
558+
memcmp(recv_src_sll.sll_addr, mac_be, IEEE802154_EXT_ADDR_LENGTH)) {
559+
NET_ERR("*** Received socket address does not compare\n", errno);
560+
goto release_rx_pkt;
561+
}
562+
563+
pkt_hexdump(received_payload, received_len);
564+
565+
if (memcmp(expected_rx_pkt, received_payload,
566+
sizeof(expected_rx_pkt))) {
567+
NET_ERR("*** Received uncompressed IPv6 payload does not compare\n");
568+
goto release_rx_pkt;
477569
}
478570

479571
k_yield();
@@ -482,27 +574,34 @@ static bool test_ack_reply(struct ieee802154_pkt_test *t)
482574
/* an ACK packet should be in current_pkt */
483575
if (!current_pkt->frags) {
484576
NET_ERR("*** No ACK reply sent\n");
485-
return false;
577+
goto release_rx_pkt;
486578
}
487579

488580
pkt_hexdump(net_pkt_data(current_pkt), net_pkt_get_len(current_pkt));
489581

490582
if (!ieee802154_validate_frame(net_pkt_data(current_pkt),
491583
net_pkt_get_len(current_pkt), &mpdu)) {
492584
NET_ERR("*** ACK Reply is invalid\n");
493-
return false;
585+
goto release_tx_frag;
494586
}
495587

496588
if (memcmp(mpdu.mhr.fs, t->mhr_check.fc_seq,
497589
sizeof(struct ieee802154_fcf_seq))) {
498590
NET_ERR("*** ACK Reply does not compare\n");
499-
return false;
591+
goto release_tx_frag;
500592
}
501593

594+
result = true;
595+
596+
release_tx_frag:
502597
net_pkt_frag_unref(current_pkt->frags);
503598
current_pkt->frags = NULL;
504-
505-
return true;
599+
release_rx_pkt:
600+
net_pkt_unref(rx_pkt);
601+
release_fd:
602+
close(fd);
603+
out:
604+
return result;
506605
}
507606

508607
static bool test_packet_cloning_with_cb(void)
@@ -609,11 +708,11 @@ ZTEST(ieee802154_l2, test_parsing_ack_pkt)
609708
zassert_true(ret, "ACK parsed");
610709
}
611710

612-
ZTEST(ieee802154_l2, test_replying_ack_pkt)
711+
ZTEST(ieee802154_l2, test_receiving_pkt_and_replying_ack_pkt)
613712
{
614713
bool ret;
615714

616-
ret = test_ack_reply(&test_ack_pkt);
715+
ret = test_recv_and_ack_reply(&test_ack_pkt);
617716

618717
zassert_true(ret, "ACK replied");
619718
}

0 commit comments

Comments
 (0)