From 26e02e84a62d270c8baafb77599254c84eabd6d5 Mon Sep 17 00:00:00 2001 From: Dirk Ziegelmeier Date: Fri, 9 Dec 2016 21:26:21 +0100 Subject: [PATCH] Fix bug #48963: ip6_frag does not support LWIP_NETIF_TX_SINGLE_PBUF Implemented. --- src/core/ipv6/ip6_frag.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/core/ipv6/ip6_frag.c b/src/core/ipv6/ip6_frag.c index b374f691..cbb9868e 100644 --- a/src/core/ipv6/ip6_frag.c +++ b/src/core/ipv6/ip6_frag.c @@ -610,6 +610,7 @@ nullreturn: #if LWIP_IPV6 && LWIP_IPV6_FRAG +#if !LWIP_NETIF_TX_SINGLE_PBUF /** Allocate a new struct pbuf_custom_ref */ static struct pbuf_custom_ref* ip6_frag_alloc_pbuf_custom_ref(void) @@ -638,6 +639,7 @@ ip6_frag_free_pbuf_custom(struct pbuf *p) } ip6_frag_free_pbuf_custom_ref(pcr); } +#endif /* !LWIP_NETIF_TX_SINGLE_PBUF */ /** * Fragment an IPv6 datagram if too large for the netif or path MTU. @@ -658,7 +660,11 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest) struct ip6_hdr *ip6hdr; struct ip6_frag_hdr *frag_hdr; struct pbuf *rambuf; +#if !LWIP_NETIF_TX_SINGLE_PBUF struct pbuf *newpbuf; + u16_t newpbuflen = 0; + u16_t left_to_copy; +#endif static u32_t identification; u16_t nfb; u16_t left, cop; @@ -666,8 +672,6 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest) u16_t fragment_offset = 0; u16_t last; u16_t poff = IP6_HLEN; - u16_t newpbuflen = 0; - u16_t left_to_copy; identification++; @@ -686,6 +690,26 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest) /* Fill this fragment */ cop = last ? left : nfb; +#if LWIP_NETIF_TX_SINGLE_PBUF + rambuf = pbuf_alloc(PBUF_IP, cop + IP6_FRAG_HLEN, PBUF_RAM); + if (rambuf == NULL) { + IP6_FRAG_STATS_INC(ip6_frag.memerr); + return ERR_MEM; + } + LWIP_ASSERT("this needs a pbuf in one piece!", + (rambuf->len == rambuf->tot_len) && (rambuf->next == NULL)); + poff += pbuf_copy_partial(p, (u8_t*)rambuf->payload + IP6_FRAG_HLEN, cop, poff); + /* make room for the IP header */ + if (pbuf_header(rambuf, IP6_HLEN)) { + pbuf_free(rambuf); + IP6_FRAG_STATS_INC(ip6_frag.memerr); + return ERR_MEM; + } + /* fill in the IP header */ + SMEMCPY(rambuf->payload, original_ip6hdr, IP6_HLEN); + ip6hdr = (struct ip6_hdr *)rambuf->payload; + frag_hdr = (struct ip6_frag_hdr *)((u8_t*)rambuf->payload + IP6_HLEN); +#else /* When not using a static buffer, create a chain of pbufs. * The first will be a PBUF_RAM holding the link, IPv6, and Fragment header. * The rest will be PBUF_REFs mirroring the pbuf chain to be fragged, @@ -744,6 +768,7 @@ ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest) } } poff = newpbuflen; +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ /* Set headers */ frag_hdr->_nexth = original_ip6hdr->_nexth;