This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 4fead15769610e9b1481a8b6e6790d8dfe841c29 Author: raiden00pl <[email protected]> AuthorDate: Thu Oct 22 13:53:53 2026 +0200 net/sixlowpan: keep the datagram tag in the radio driver The datagram tag of the next fragmented packet was kept in the reassembly buffer structure at d_buf. During a poll, a reply or a forward d_buf points into the IOB of the packet, so the tag was read from and incremented in memory past the end of that IOB, and the frames of a packet got a wrong tag. Keep the tag in struct radio_driver_s. Assisted-by: Claude Code Signed-off-by: raiden00pl <[email protected]> --- include/nuttx/net/radiodev.h | 4 ++++ include/nuttx/net/sixlowpan.h | 16 ---------------- net/sixlowpan/sixlowpan_framelist.c | 18 ++++++------------ 3 files changed, 10 insertions(+), 28 deletions(-) diff --git a/include/nuttx/net/radiodev.h b/include/nuttx/net/radiodev.h index 5baf18e0968..3f352c40bca 100644 --- a/include/nuttx/net/radiodev.h +++ b/include/nuttx/net/radiodev.h @@ -152,6 +152,10 @@ struct radio_driver_s /* Radio network driver-specific definitions follow. */ + /* Datagram tag of the next fragmented packet sent (RFC 4944 5.3) */ + + uint16_t r_dgramtag; + #ifdef CONFIG_WIRELESS_IEEE802154 /* The msdu_handle is basically an id for the frame. The standard just * says that the next highest layer should determine it. It is used in diff --git a/include/nuttx/net/sixlowpan.h b/include/nuttx/net/sixlowpan.h index 7c8475313f2..72ac1392f0b 100644 --- a/include/nuttx/net/sixlowpan.h +++ b/include/nuttx/net/sixlowpan.h @@ -389,24 +389,8 @@ struct sixlowpan_reassbuf_s * information follows the externally visible packet buffer. */ - /* rb_dgramtag. Datagram tag to be put in the header of the set of - * fragments. It is used by the recipient to match fragments of the - * same payload. - * - * This is the sender's copy of the tag. It is incremented after each - * fragmented packet is sent so that it will be unique to that - * sequence fragmentation. Its value is then persistent, the values of - * other fragmentation variables are valid on during a single - * fragmentation sequence (while rb_accumlen > 0) - */ - - uint16_t rb_dgramtag; - /* rb_reasstag. Each frame in the reassembly has a tag. That tag must * match the reassembly tag in the fragments being merged. - * - * This is the same tag as rb_dgramtag but is saved on the receiving - * side to match all of the fragments of the packet. */ uint16_t rb_reasstag; diff --git a/net/sixlowpan/sixlowpan_framelist.c b/net/sixlowpan/sixlowpan_framelist.c index 6ee5693d2b7..ef28c50f6db 100644 --- a/net/sixlowpan/sixlowpan_framelist.c +++ b/net/sixlowpan/sixlowpan_framelist.c @@ -525,18 +525,12 @@ int sixlowpan_queue_frames(FAR struct radio_driver_s *radio, * added at qtail. */ - FAR struct sixlowpan_reassbuf_s *reass; FAR struct iob_s *qhead; FAR struct iob_s *qtail; FAR uint8_t *frame1; FAR uint8_t *fragptr; uint16_t frag1_hdrlen; - /* Recover the reassembly buffer from the driver d_buf. */ - - reass = (FAR struct sixlowpan_reassbuf_s *)radio->r_dev.d_buf; - DEBUGASSERT(reass != NULL); - /* The outbound IPv6 packet is too large to fit into a single 15.4 * packet, so we fragment it into multiple packets and send them. * The first fragment contains frag1 dispatch, then @@ -574,7 +568,7 @@ int sixlowpan_queue_frames(FAR struct radio_driver_s *radio, pktlen = buflen + g_uncomp_hdrlen + protosize; PUTHOST16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE, ((SIXLOWPAN_DISPATCH_FRAG1 << 8) | pktlen)); - PUTHOST16(fragptr, SIXLOWPAN_FRAG_TAG, reass->rb_dgramtag); + PUTHOST16(fragptr, SIXLOWPAN_FRAG_TAG, radio->r_dgramtag); g_frame_hdrlen += SIXLOWPAN_FRAG1_HDR_LEN; @@ -602,7 +596,7 @@ int sixlowpan_queue_frames(FAR struct radio_driver_s *radio, outlen = paysize; ninfo("First fragment: length %d, tag %d\n", - paysize, reass->rb_dgramtag); + paysize, radio->r_dgramtag); sixlowpan_dumpbuffer("Outgoing frame", (FAR const uint8_t *)iob->io_data, iob->io_len); @@ -654,7 +648,7 @@ int sixlowpan_queue_frames(FAR struct radio_driver_s *radio, PUTHOST16(fragptr, SIXLOWPAN_FRAG_DISPATCH_SIZE, ((SIXLOWPAN_DISPATCH_FRAGN << 8) | pktlen)); - PUTHOST16(fragptr, SIXLOWPAN_FRAG_TAG, reass->rb_dgramtag); + PUTHOST16(fragptr, SIXLOWPAN_FRAG_TAG, radio->r_dgramtag); fragptr[SIXLOWPAN_FRAG_OFFSET] = outlen >> 3; fragn_hdrlen += SIXLOWPAN_FRAGN_HDR_LEN; @@ -679,8 +673,8 @@ int sixlowpan_queue_frames(FAR struct radio_driver_s *radio, iob->io_len = paysize + fragn_hdrlen; outlen += paysize; - ninfo("Fragment offset=%d, paysize=%d, rb_dgramtag=%d\n", - outlen >> 3, paysize, reass->rb_dgramtag); + ninfo("Fragment offset=%d, paysize=%d, dgramtag=%d\n", + outlen >> 3, paysize, radio->r_dgramtag); sixlowpan_dumpbuffer("Outgoing frame", (FAR const uint8_t *)iob->io_data, @@ -723,7 +717,7 @@ int sixlowpan_queue_frames(FAR struct radio_driver_s *radio, /* Update the datagram TAG value */ - reass->rb_dgramtag++; + radio->r_dgramtag++; } else {
