mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-18 12:52:44 +01:00
gnrc_ipv6: fix multi-interface packet duplication
This commit is contained in:
parent
f334a9aa1b
commit
a19b0d8262
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user