From 5bf9892bb31da969f6751d15e26e2e51390a5e57 Mon Sep 17 00:00:00 2001 From: "Martine S. Lenders" Date: Tue, 1 Oct 2019 16:36:14 +0200 Subject: [PATCH] gnrc_sixlowpan_frag_rb: add new functions for SFR --- sys/include/net/gnrc/sixlowpan/frag/rb.h | 39 ++++++++++++++++ .../frag/rb/gnrc_sixlowpan_frag_rb.c | 44 +++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/sys/include/net/gnrc/sixlowpan/frag/rb.h b/sys/include/net/gnrc/sixlowpan/frag/rb.h index b66b1d31d1..76091e270e 100644 --- a/sys/include/net/gnrc/sixlowpan/frag/rb.h +++ b/sys/include/net/gnrc/sixlowpan/frag/rb.h @@ -114,6 +114,45 @@ gnrc_sixlowpan_frag_rb_t *gnrc_sixlowpan_frag_rb_add(gnrc_netif_hdr_t *netif_hdr gnrc_pktsnip_t *frag, size_t offset, unsigned page); +/** + * @brief Checks if a reassembly buffer entry with a given link-layer address + * pair and tag exists + * + * @pre `netif_hdr != NULL` + * + * @param[in] netif_hdr An interface header to provide the (source, destination) + * link-layer address pair. Must not be NULL. + * @param[in] tag Tag to search for. + * + * @note datagram_size is not a search parameter as the primary use case + * for this function is [Selective Fragment Recovery] + * (https://tools.ietf.org/html/draft-ietf-6lo-fragment-recovery-05) + * where this information only exists in the first fragment. + * + * @return true, if an entry with the given tuple exist. + * @return false, if no entry with the given tuple exist. + */ +bool gnrc_sixlowpan_frag_rb_exists(const gnrc_netif_hdr_t *netif_hdr, + uint16_t tag); + +/** + * @brief Removes a reassembly buffer entry with a given link-layer address + * pair and tag + * + * @pre `netif_hdr != NULL` + * + * @param[in] netif_hdr An interface header to provide the (source, destination) + * link-layer address pair. Must not be NULL. + * @param[in] tag Tag to search for. + * + * @note datagram_size is not a search parameter as the primary use case + * for this function is [Selective Fragment Recovery] + * (https://tools.ietf.org/html/draft-ietf-6lo-fragment-recovery-05) + * where this information only exists in the first fragment. + */ +void gnrc_sixlowpan_frag_rb_rm_by_datagram(const gnrc_netif_hdr_t *netif_hdr, + uint16_t tag); + /** * @brief Checks if a reassembly buffer entry is unset * diff --git a/sys/net/gnrc/network_layer/sixlowpan/frag/rb/gnrc_sixlowpan_frag_rb.c b/sys/net/gnrc/network_layer/sixlowpan/frag/rb/gnrc_sixlowpan_frag_rb.c index d0c8856fa4..d51dfb216d 100644 --- a/sys/net/gnrc/network_layer/sixlowpan/frag/rb/gnrc_sixlowpan_frag_rb.c +++ b/sys/net/gnrc/network_layer/sixlowpan/frag/rb/gnrc_sixlowpan_frag_rb.c @@ -73,6 +73,9 @@ static int _rbuf_get(const void *src, size_t src_len, const void *dst, size_t dst_len, size_t size, uint16_t tag, unsigned page); +/* gets an entry only by link-layer information and tag */ +static gnrc_sixlowpan_frag_rb_t *_rbuf_get_by_tag(const gnrc_netif_hdr_t *netif_hdr, + uint16_t tag); /* internal add to repeat add when fragments overlapped */ static int _rbuf_add(gnrc_netif_hdr_t *netif_hdr, gnrc_pktsnip_t *pkt, size_t offset, unsigned page); @@ -138,6 +141,47 @@ gnrc_sixlowpan_frag_rb_t *gnrc_sixlowpan_frag_rb_add(gnrc_netif_hdr_t *netif_hdr return (res < 0) ? NULL : &rbuf[res]; } + + +bool gnrc_sixlowpan_frag_rb_exists(const gnrc_netif_hdr_t *netif_hdr, + uint16_t tag) +{ + return (_rbuf_get_by_tag(netif_hdr, tag) != NULL); +} + +void gnrc_sixlowpan_frag_rb_rm_by_datagram(const gnrc_netif_hdr_t *netif_hdr, + uint16_t tag) +{ + gnrc_sixlowpan_frag_rb_t *e = _rbuf_get_by_tag(netif_hdr, tag); + + if (e != NULL) { + gnrc_sixlowpan_frag_rb_remove(e); + } +} + +static gnrc_sixlowpan_frag_rb_t *_rbuf_get_by_tag(const gnrc_netif_hdr_t *netif_hdr, + uint16_t tag) +{ + assert(netif_hdr != NULL); + const uint8_t *src = gnrc_netif_hdr_get_src_addr(netif_hdr); + const uint8_t *dst = gnrc_netif_hdr_get_dst_addr(netif_hdr); + const uint8_t src_len = netif_hdr->src_l2addr_len; + const uint8_t dst_len = netif_hdr->dst_l2addr_len; + + for (unsigned i = 0; i < GNRC_SIXLOWPAN_FRAG_RBUF_SIZE; i++) { + gnrc_sixlowpan_frag_rb_t *e = &rbuf[i]; + + if ((e->pkt != NULL) && (e->super.tag == tag) && + (e->super.src_len == src_len) && + (e->super.dst_len == dst_len) && + (memcmp(e->super.src, src, src_len) == 0) && + (memcmp(e->super.dst, dst, dst_len) == 0)) { + return e; + } + } + return NULL; +} + #ifndef NDEBUG static bool _valid_offset(gnrc_pktsnip_t *pkt, size_t offset) {