diff --git a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c index 72da35e8d7..4d89ec1941 100644 --- a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c +++ b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c @@ -376,27 +376,6 @@ static int _fill_ipv6_hdr(kernel_pid_t iface, gnrc_pktsnip_t *ipv6, DEBUG("ipv6: calculate checksum for upper header.\n"); -#if GNRC_NETIF_NUMOF > 1 - if (payload->users > 1) { - gnrc_pktsnip_t *ptr = ipv6; - - /* We deal with multiple interfaces here (multicast) => possible - * different source addresses => duplication of payload needed */ - while (ptr != payload->next) { - gnrc_pktsnip_t *old = ptr->next; - /* duplicate everything including payload */ - ptr->next = gnrc_pktbuf_start_write(ptr->next); - - if (ptr->next == NULL) { - DEBUG("ipv6: unable to get write access to payload, drop it\n"); - return -ENOBUFS; - } - - ptr = old; - } - } -#endif /* GNRC_NETIF_NUMOF */ - if ((res = gnrc_netreg_calc_csum(payload, ipv6)) < 0) { if (res != -ENOENT) { /* if there is no checksum we are okay */ DEBUG("ipv6: checksum calculation failed.\n"); @@ -439,6 +418,7 @@ static void _send_multicast(kernel_pid_t iface, gnrc_pktsnip_t *pkt, #if GNRC_NETIF_NUMOF > 1 /* netif header not present: send over all interfaces */ if (iface == KERNEL_PID_UNDEF) { + assert(pkt == ipv6); /* send packet to link layer */ gnrc_pktbuf_hold(pkt, ifnum - 1); @@ -447,7 +427,9 @@ static void _send_multicast(kernel_pid_t iface, gnrc_pktsnip_t *pkt, if (prep_hdr) { /* need to get second write access (duplication) to fill IPv6 * header interface-local */ - ipv6 = gnrc_pktbuf_start_write(ipv6); + gnrc_pktsnip_t *tmp = gnrc_pktbuf_start_write(pkt); + gnrc_pktsnip_t *ptr = tmp->next; + ipv6 = tmp; if (ipv6 == NULL) { DEBUG("ipv6: unable to get write access to IPv6 header, " @@ -456,9 +438,23 @@ static void _send_multicast(kernel_pid_t iface, gnrc_pktsnip_t *pkt, return; } - if (_fill_ipv6_hdr(ifs[i], ipv6, payload) < 0) { + /* multiple interfaces => possibly different source addresses + * => different checksums => duplication of payload needed */ + while (ptr != payload->next) { + /* duplicate everything including payload */ + tmp->next = gnrc_pktbuf_start_write(ptr); + if (tmp->next == NULL) { + DEBUG("ipv6: unable to get write access to payload, drop it\n"); + gnrc_pktbuf_release(ipv6); + return; + } + tmp = tmp->next; + ptr = ptr->next; + } + + if (_fill_ipv6_hdr(ifs[i], ipv6, tmp) < 0) { /* error on filling up header */ - gnrc_pktbuf_release(pkt); + gnrc_pktbuf_release(ipv6); return; } } @@ -469,17 +465,18 @@ static void _send_multicast(kernel_pid_t iface, gnrc_pktsnip_t *pkt, if (netif == NULL) { DEBUG("ipv6: error on interface header allocation, " "dropping packet\n"); - gnrc_pktbuf_release(pkt); + gnrc_pktbuf_release(ipv6); return; } - LL_PREPEND(pkt, netif); + LL_PREPEND(ipv6, netif); _send_multicast_over_iface(ifs[i], ipv6); } } else { /* iface != KERNEL_PID_UNDEF implies that netif header is present */ + assert(pkt != ipv6); if (prep_hdr) { if (_fill_ipv6_hdr(iface, ipv6, payload) < 0) { /* error on filling up header */