1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-18 12:52:44 +01:00

gnrc_sixlowpan_iphc: add rudimentary forwarding routine

This commit is contained in:
Martine Lenders 2019-11-04 13:31:54 +01:00 committed by Martine S. Lenders
parent e31394536b
commit a689f51e9a
No known key found for this signature in database
GPG Key ID: CCD317364F63286F

View File

@ -33,6 +33,7 @@
#include "utlist.h"
#include "net/gnrc/nettype.h"
#include "net/gnrc/udp.h"
#include "od.h"
#include "net/gnrc/sixlowpan/iphc.h"
@ -95,6 +96,12 @@
#define NHC_UDP_8BIT_PORT (0xF000)
#define NHC_UDP_8BIT_MASK (0xFF00)
/* currently only used with forwarding output, remove guard if more debug info
* is added */
#ifdef MODULE_GNRC_SIXLOWPAN_FRAG_VRB
static char addr_str[IPV6_ADDR_MAX_STR_LEN];
#endif /* MODULE_GNRC_SIXLOWPAN_FRAG_VRB */
static inline bool _context_overlaps_iid(gnrc_sixlowpan_ctx_t *ctx,
ipv6_addr_t *addr,
eui64_t *iid)
@ -120,6 +127,13 @@ static gnrc_pktsnip_t *_iphc_encode(gnrc_pktsnip_t *pkt,
const gnrc_netif_hdr_t *netif_hdr,
gnrc_netif_t *netif);
#ifdef MODULE_GNRC_SIXLOWPAN_FRAG_VRB
static gnrc_pktsnip_t *_encode_frag_for_forwarding(gnrc_pktsnip_t *decoded_pkt,
gnrc_sixlowpan_frag_vrb_t *vrbe);
static int _forward_frag(gnrc_pktsnip_t *pkt, gnrc_pktsnip_t *frag_hdr,
gnrc_sixlowpan_frag_vrb_t *vrbe, unsigned page);
#endif /* MODULE_GNRC_SIXLOWPAN_FRAG_VRB */
#ifdef MODULE_GNRC_SIXLOWPAN_IPHC_NHC
/**
* @brief Decodes UDP NHC
@ -626,12 +640,26 @@ void gnrc_sixlowpan_iphc_recv(gnrc_pktsnip_t *sixlo, void *rbuf_ptr,
rbuf->super.current_size += (uncomp_hdr_len - payload_offset);
#ifdef MODULE_GNRC_SIXLOWPAN_FRAG_VRB
if (vrbe != NULL) {
int res = -1;
DEBUG("6lo iphc: found route, trying to forward\n");
ipv6_hdr->hl--;
vrbe->super.current_size = rbuf->super.current_size;
/* forward here according to forwarding scheme here */
if ((ipv6 = _encode_frag_for_forwarding(ipv6, vrbe))) {
if ((res = _forward_frag(ipv6, sixlo->next, vrbe, page)) == 0) {
DEBUG("6lo iphc: successfully recompressed and forwarded "
"1st fragment\n");
/* empty list, as it should be in VRB now */
rbuf->super.ints = NULL;
}
}
if ((ipv6 == NULL) || (res < 0)) {
gnrc_sixlowpan_frag_vrb_rm(vrbe);
}
gnrc_pktbuf_release(sixlo);
/* don't remove `rbuf->pkt` (aka ipv6) as it was forwarded */
gnrc_sixlowpan_frag_rb_remove(rbuf);
return;
}
DEBUG("6lo iphc: no route found, reassemble datagram normally\n");
#endif /* MODULE_GNRC_SIXLOWPAN_FRAG_VRB */
}
@ -644,6 +672,74 @@ void gnrc_sixlowpan_iphc_recv(gnrc_pktsnip_t *sixlo, void *rbuf_ptr,
return;
}
#ifdef MODULE_GNRC_SIXLOWPAN_FRAG_VRB
static gnrc_pktsnip_t *_encode_frag_for_forwarding(gnrc_pktsnip_t *decoded_pkt,
gnrc_sixlowpan_frag_vrb_t *vrbe)
{
gnrc_pktsnip_t *res;
gnrc_netif_hdr_t *netif_hdr;
/* mark IPv6 header to allow for next header compression */
res = gnrc_pktbuf_mark(decoded_pkt, sizeof(ipv6_hdr_t), GNRC_NETTYPE_IPV6);
if (res == NULL) {
DEBUG("6lo iphc: unable to mark IPv6 header for forwarding\n");
gnrc_pktbuf_release(decoded_pkt);
return NULL;
}
res = gnrc_pktbuf_reverse_snips(decoded_pkt);
if (res == NULL) {
DEBUG("6lo iphc: unable to reverse packet for forwarding\n");
/* decoded_pkt is released in gnrc_pktbuf_reverse_snips() */
return NULL;
}
/* set netif header from VRB for correct encoding */
netif_hdr = res->data;
/* _iphc_encode only checks the destination address, so leave src
* untouched */
netif_hdr->dst_l2addr_len = vrbe->super.dst_len;
gnrc_netif_hdr_set_dst_addr(netif_hdr, vrbe->super.dst,
vrbe->super.dst_len);
gnrc_netif_hdr_set_netif(netif_hdr, vrbe->out_netif);
decoded_pkt = res;
if ((res = _iphc_encode(decoded_pkt, netif_hdr, vrbe->out_netif))) {
return res;
}
else {
DEBUG("6lo iphc: unable to compress packet for forwarding\n");
gnrc_pktbuf_release(decoded_pkt);
return NULL;
}
}
static int _forward_frag(gnrc_pktsnip_t *pkt, gnrc_pktsnip_t *frag_hdr,
gnrc_sixlowpan_frag_vrb_t *vrbe, unsigned page)
{
/* remove rewritten netif header (forwarding implementation must do this
* anyway) */
pkt = gnrc_pktbuf_remove_snip(pkt, pkt);
DEBUG("6lo iphc: Do not know how to forward fragment from (%s, %u) ",
gnrc_netif_addr_to_str(vrbe->super.src, vrbe->super.src_len,
addr_str), vrbe->super.tag);
DEBUG("to (%s, %u)\n",
gnrc_netif_addr_to_str(vrbe->super.dst, vrbe->super.dst_len,
addr_str), vrbe->out_tag);
#if ENABLE_DEBUG && defined(MODULE_OD)
DEBUG("Original fragmentation header:\n");
od_hex_dump(frag_hdr->data, frag_hdr->size, OD_WIDTH_DEFAULT);
DEBUG("IPHC headers + payload:\n");
frag_hdr = pkt;
while (frag_hdr) {
od_hex_dump(frag_hdr->data, frag_hdr->size, OD_WIDTH_DEFAULT);
frag_hdr = frag_hdr->next;
}
#endif
gnrc_pktbuf_release(pkt);
(void)frag_hdr;
(void)page;
return -ENOTSUP;
}
#endif /* MODULE_GNRC_SIXLOWPAN_FRAG_VRB */
#ifdef MODULE_GNRC_SIXLOWPAN_IPHC_NHC
static inline size_t iphc_nhc_udp_encode(uint8_t *nhc_data,
const gnrc_pktsnip_t *udp)