Skip to content

Commit 1ce1d19

Browse files
mniestrojcfriedt
authored andcommitted
net: pkt: introduce net_pkt_remove_tail()
Introduce a helper function for being able to remove any arbitrary length from tail of packet. This is handy in cases when removing unneeded data, like CRC once it was verified. Signed-off-by: Marcin Niestroj <[email protected]>
1 parent aedc51a commit 1ce1d19

File tree

3 files changed

+132
-1
lines changed

3 files changed

+132
-1
lines changed

include/net/net_pkt.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1705,6 +1705,22 @@ size_t net_pkt_available_payload_buffer(struct net_pkt *pkt,
17051705
*/
17061706
void net_pkt_trim_buffer(struct net_pkt *pkt);
17071707

1708+
/**
1709+
* @brief Remove @a length bytes from tail of packet
1710+
*
1711+
* @details This function does not take packet cursor into account. It is a
1712+
* helper to remove unneeded bytes from tail of packet (like appended
1713+
* CRC). It takes care of buffer deallocation if removed bytes span
1714+
* whole buffer(s).
1715+
*
1716+
* @param pkt Network packet
1717+
* @param length Number of bytes to be removed
1718+
*
1719+
* @retval 0 On success.
1720+
* @retval -EINVAL If packet length is shorter than @a length.
1721+
*/
1722+
int net_pkt_remove_tail(struct net_pkt *pkt, size_t length);
1723+
17081724
/**
17091725
* @brief Initialize net_pkt cursor
17101726
*

subsys/net/ip/net_pkt.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,6 +1089,36 @@ void net_pkt_trim_buffer(struct net_pkt *pkt)
10891089
}
10901090
}
10911091

1092+
int net_pkt_remove_tail(struct net_pkt *pkt, size_t length)
1093+
{
1094+
struct net_buf *buf = pkt->buffer;
1095+
size_t remaining_len = net_pkt_get_len(pkt);
1096+
1097+
if (remaining_len < length) {
1098+
return -EINVAL;
1099+
}
1100+
1101+
remaining_len -= length;
1102+
1103+
while (buf) {
1104+
if (buf->len >= remaining_len) {
1105+
buf->len = remaining_len;
1106+
1107+
if (buf->frags) {
1108+
net_pkt_frag_unref(buf->frags);
1109+
buf->frags = NULL;
1110+
}
1111+
1112+
break;
1113+
}
1114+
1115+
remaining_len -= buf->len;
1116+
buf = buf->frags;
1117+
}
1118+
1119+
return 0;
1120+
}
1121+
10921122
#if NET_LOG_LEVEL >= LOG_LEVEL_DBG
10931123
int net_pkt_alloc_buffer_debug(struct net_pkt *pkt,
10941124
size_t size,

tests/net/net_pkt/src/main.c

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -974,6 +974,90 @@ static void test_net_pkt_get_contiguous_len(void)
974974
net_pkt_unref(pkt);
975975
}
976976

977+
void test_net_pkt_remove_tail(void)
978+
{
979+
struct net_pkt *pkt;
980+
int err;
981+
982+
pkt = net_pkt_alloc_with_buffer(NULL,
983+
CONFIG_NET_BUF_DATA_SIZE * 2 + 3,
984+
AF_UNSPEC, 0, K_NO_WAIT);
985+
zassert_true(pkt != NULL, "Pkt not allocated");
986+
987+
net_pkt_cursor_init(pkt);
988+
net_pkt_write(pkt, small_buffer, CONFIG_NET_BUF_DATA_SIZE * 2 + 3);
989+
990+
zassert_equal(net_pkt_get_len(pkt), CONFIG_NET_BUF_DATA_SIZE * 2 + 3,
991+
"Pkt length is invalid");
992+
zassert_equal(pkt->frags->frags->frags->len, 3,
993+
"3rd buffer length is invalid");
994+
995+
/* Remove some bytes from last buffer */
996+
err = net_pkt_remove_tail(pkt, 2);
997+
zassert_equal(err, 0, "Failed to remove tail");
998+
999+
zassert_equal(net_pkt_get_len(pkt), CONFIG_NET_BUF_DATA_SIZE * 2 + 1,
1000+
"Pkt length is invalid");
1001+
zassert_not_equal(pkt->frags->frags->frags, NULL,
1002+
"3rd buffer was removed");
1003+
zassert_equal(pkt->frags->frags->frags->len, 1,
1004+
"3rd buffer length is invalid");
1005+
1006+
/* Remove last byte from last buffer */
1007+
err = net_pkt_remove_tail(pkt, 1);
1008+
zassert_equal(err, 0, "Failed to remove tail");
1009+
1010+
zassert_equal(net_pkt_get_len(pkt), CONFIG_NET_BUF_DATA_SIZE * 2,
1011+
"Pkt length is invalid");
1012+
zassert_equal(pkt->frags->frags->frags, NULL,
1013+
"3rd buffer was not removed");
1014+
zassert_equal(pkt->frags->frags->len, CONFIG_NET_BUF_DATA_SIZE,
1015+
"2nd buffer length is invalid");
1016+
1017+
/* Remove 2nd buffer and one byte from 1st buffer */
1018+
err = net_pkt_remove_tail(pkt, CONFIG_NET_BUF_DATA_SIZE + 1);
1019+
zassert_equal(err, 0, "Failed to remove tail");
1020+
1021+
zassert_equal(net_pkt_get_len(pkt), CONFIG_NET_BUF_DATA_SIZE - 1,
1022+
"Pkt length is invalid");
1023+
zassert_equal(pkt->frags->frags, NULL,
1024+
"2nd buffer was not removed");
1025+
zassert_equal(pkt->frags->len, CONFIG_NET_BUF_DATA_SIZE - 1,
1026+
"1st buffer length is invalid");
1027+
1028+
net_pkt_unref(pkt);
1029+
1030+
pkt = net_pkt_rx_alloc_with_buffer(NULL,
1031+
CONFIG_NET_BUF_DATA_SIZE * 2 + 3,
1032+
AF_UNSPEC, 0, K_NO_WAIT);
1033+
1034+
net_pkt_cursor_init(pkt);
1035+
net_pkt_write(pkt, small_buffer, CONFIG_NET_BUF_DATA_SIZE * 2 + 3);
1036+
1037+
zassert_equal(net_pkt_get_len(pkt), CONFIG_NET_BUF_DATA_SIZE * 2 + 3,
1038+
"Pkt length is invalid");
1039+
zassert_equal(pkt->frags->frags->frags->len, 3,
1040+
"3rd buffer length is invalid");
1041+
1042+
/* Remove bytes spanning 3 buffers */
1043+
err = net_pkt_remove_tail(pkt, CONFIG_NET_BUF_DATA_SIZE + 5);
1044+
zassert_equal(err, 0, "Failed to remove tail");
1045+
1046+
zassert_equal(net_pkt_get_len(pkt), CONFIG_NET_BUF_DATA_SIZE - 2,
1047+
"Pkt length is invalid");
1048+
zassert_equal(pkt->frags->frags, NULL,
1049+
"2nd buffer was not removed");
1050+
zassert_equal(pkt->frags->len, CONFIG_NET_BUF_DATA_SIZE - 2,
1051+
"1st buffer length is invalid");
1052+
1053+
/* Try to remove more bytes than packet has */
1054+
err = net_pkt_remove_tail(pkt, CONFIG_NET_BUF_DATA_SIZE);
1055+
zassert_equal(err, -EINVAL,
1056+
"Removing more bytes than available should fail");
1057+
1058+
net_pkt_unref(pkt);
1059+
}
1060+
9771061
void test_main(void)
9781062
{
9791063
eth_if = net_if_get_default();
@@ -989,7 +1073,8 @@ void test_main(void)
9891073
ztest_unit_test(test_net_pkt_clone),
9901074
ztest_unit_test(test_net_pkt_headroom),
9911075
ztest_unit_test(test_net_pkt_headroom_copy),
992-
ztest_unit_test(test_net_pkt_get_contiguous_len)
1076+
ztest_unit_test(test_net_pkt_get_contiguous_len),
1077+
ztest_unit_test(test_net_pkt_remove_tail)
9931078
);
9941079

9951080
ztest_run_test_suite(net_pkt_tests);

0 commit comments

Comments
 (0)