Merge pull request #3991 from authmillenon/gnrc_netapi/fix/recover_msg

gnrc_netapi: recover from message send errors
This commit is contained in:
Oleg Hahm 2015-09-30 17:08:13 +02:00
commit dbfe1c03cd
11 changed files with 67 additions and 32 deletions

View File

@ -84,25 +84,12 @@ static void _event_cb(netdev2_t *dev, netdev2_event_t event, void *data)
static void _pass_on_packet(gnrc_pktsnip_t *pkt) static void _pass_on_packet(gnrc_pktsnip_t *pkt)
{ {
gnrc_netreg_entry_t *sendto;
/* find out, who to send the packet to */
sendto = gnrc_netreg_lookup(pkt->type, GNRC_NETREG_DEMUX_CTX_ALL);
/* throw away packet if no one is interested */ /* throw away packet if no one is interested */
if (sendto == NULL) { if (!gnrc_netapi_dispatch_receive(pkt->type, GNRC_NETREG_DEMUX_CTX_ALL, pkt)) {
DEBUG("gnrc_netdev2: unable to forward packet of type %i\n", pkt->type); DEBUG("gnrc_netdev2: unable to forward packet of type %i\n", pkt->type);
gnrc_pktbuf_release(pkt); gnrc_pktbuf_release(pkt);
return; return;
} }
/* send the packet to everyone interested in it's type */
gnrc_pktbuf_hold(pkt, gnrc_netreg_num(pkt->type, GNRC_NETREG_DEMUX_CTX_ALL) - 1);
while (sendto != NULL) {
DEBUG("gnrc_netdev2: sending pkt %p to PID %u\n", (void*)pkt, sendto->pid);
gnrc_netapi_receive(sendto->pid, pkt);
sendto = gnrc_netreg_getnext(sendto);
}
} }
/** /**

View File

@ -77,7 +77,10 @@ int gnrc_netapi_dispatch(gnrc_nettype_t type, uint32_t demux_ctx,
gnrc_pktbuf_hold(pkt, numof - 1); gnrc_pktbuf_hold(pkt, numof - 1);
while (sendto) { while (sendto) {
_snd_rcv(sendto->pid, cmd, pkt); if (_snd_rcv(sendto->pid, cmd, pkt) < 1) {
/* unable to dispatch packet */
gnrc_pktbuf_release(pkt);
}
sendto = gnrc_netreg_getnext(sendto); sendto = gnrc_netreg_getnext(sendto);
} }
} }

View File

@ -118,7 +118,10 @@ void gnrc_icmpv6_echo_req_handle(kernel_pid_t iface, ipv6_hdr_t *ipv6_hdr,
gnrc_pktbuf_hold(pkt, gnrc_netreg_num(GNRC_NETTYPE_IPV6, GNRC_NETREG_DEMUX_CTX_ALL) - 1); gnrc_pktbuf_hold(pkt, gnrc_netreg_num(GNRC_NETTYPE_IPV6, GNRC_NETREG_DEMUX_CTX_ALL) - 1);
while (sendto != NULL) { while (sendto != NULL) {
gnrc_netapi_send(sendto->pid, pkt); if (gnrc_netapi_send(sendto->pid, pkt) < 1) {
DEBUG("icmpv6_echo: unable to send packet\n");
gnrc_pktbuf_release(pkt);
}
sendto = gnrc_netreg_getnext(sendto); sendto = gnrc_netreg_getnext(sendto);
} }
} }

View File

@ -136,11 +136,14 @@ void gnrc_icmpv6_demux(kernel_pid_t iface, gnrc_pktsnip_t *pkt)
return; return;
} }
/* ICMPv6 is not interested anymore so `- 1` */ /* IPv6 might still do stuff to the packet, so no `- 1` */
gnrc_pktbuf_hold(pkt, gnrc_netreg_num(GNRC_NETTYPE_ICMPV6, hdr->type)); gnrc_pktbuf_hold(pkt, gnrc_netreg_num(GNRC_NETTYPE_ICMPV6, hdr->type));
while (sendto != NULL) { while (sendto != NULL) {
gnrc_netapi_receive(sendto->pid, pkt); if (gnrc_netapi_receive(sendto->pid, pkt) < 1) {
DEBUG("icmpv6: unable to deliver packet\n");
gnrc_pktbuf_release(pkt);
}
sendto = gnrc_netreg_getnext(sendto); sendto = gnrc_netreg_getnext(sendto);
} }
} }

View File

@ -292,7 +292,10 @@ static void _send_to_iface(kernel_pid_t iface, gnrc_pktsnip_t *pkt)
return; return;
} }
#endif #endif
gnrc_netapi_send(iface, pkt); if (gnrc_netapi_send(iface, pkt) < 1) {
DEBUG("ipv6: unable to send packet\n");
gnrc_pktbuf_release(pkt);
}
} }
/* functions for sending */ /* functions for sending */
@ -629,7 +632,10 @@ static void _send(gnrc_pktsnip_t *pkt, bool prep_hdr)
DEBUG("ipv6: packet is addressed to myself => loopback\n"); DEBUG("ipv6: packet is addressed to myself => loopback\n");
gnrc_netapi_receive(gnrc_ipv6_pid, rcv_pkt); if (gnrc_netapi_receive(gnrc_ipv6_pid, rcv_pkt) < 1) {
DEBUG("ipv6: unable to deliver packet\n");
gnrc_pktbuf_release(pkt);
}
} }
else { else {
uint8_t l2addr_len = GNRC_IPV6_NC_L2_ADDR_MAX; uint8_t l2addr_len = GNRC_IPV6_NC_L2_ADDR_MAX;
@ -678,7 +684,10 @@ static void _dispatch_rcv_pkt(gnrc_nettype_t type, uint32_t demux_ctx,
while (entry) { while (entry) {
DEBUG("ipv6: Send receive command for %p to %" PRIu16 "\n", (void *)pkt, DEBUG("ipv6: Send receive command for %p to %" PRIu16 "\n", (void *)pkt,
entry->pid); entry->pid);
gnrc_netapi_receive(entry->pid, pkt); if (gnrc_netapi_receive(entry->pid, pkt) < 1) {
DEBUG("ipv6: unable to deliver packet\n");
gnrc_pktbuf_release(pkt);
}
entry = gnrc_netreg_getnext(entry); entry = gnrc_netreg_getnext(entry);
} }
} }

View File

@ -317,7 +317,10 @@ void gnrc_ndp_nbr_adv_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt,
#ifdef MODULE_GNRC_NDP_NODE #ifdef MODULE_GNRC_NDP_NODE
gnrc_pktqueue_t *queued_pkt; gnrc_pktqueue_t *queued_pkt;
while ((queued_pkt = gnrc_pktqueue_remove_head(&nc_entry->pkts)) != NULL) { while ((queued_pkt = gnrc_pktqueue_remove_head(&nc_entry->pkts)) != NULL) {
gnrc_netapi_send(gnrc_ipv6_pid, queued_pkt->pkt); if (gnrc_netapi_send(gnrc_ipv6_pid, queued_pkt->pkt) < 1) {
DEBUG("ndp: unable to send queued packet\n");
gnrc_pktbuf_release(queued_pkt->pkt);
}
queued_pkt->pkt = NULL; queued_pkt->pkt = NULL;
} }
#endif #endif

View File

@ -223,8 +223,9 @@ void gnrc_ndp_internal_send_nbr_adv(kernel_pid_t iface, ipv6_addr_t *tgt, ipv6_a
/* nc_entry must be set so no need to check it */ /* nc_entry must be set so no need to check it */
_send_delayed(&nc_entry->nbr_adv_timer, delay, hdr); _send_delayed(&nc_entry->nbr_adv_timer, delay, hdr);
} }
else { else if (gnrc_netapi_send(gnrc_ipv6_pid, hdr) < 1) {
gnrc_netapi_send(gnrc_ipv6_pid, hdr); DEBUG("ndp internal: unable to send neighbor advertisement\n");
gnrc_pktbuf_release(hdr);
} }
} }
@ -301,7 +302,10 @@ void gnrc_ndp_internal_send_nbr_sol(kernel_pid_t iface, ipv6_addr_t *src, ipv6_a
gnrc_pktbuf_release(pkt); gnrc_pktbuf_release(pkt);
return; return;
} }
gnrc_netapi_send(gnrc_ipv6_pid, hdr); else if (gnrc_netapi_send(gnrc_ipv6_pid, hdr) < 1) {
DEBUG("ndp internal: unable to send neighbor solicitation\n");
gnrc_pktbuf_release(hdr);
}
} }
void gnrc_ndp_internal_send_rtr_sol(kernel_pid_t iface, ipv6_addr_t *dst) void gnrc_ndp_internal_send_rtr_sol(kernel_pid_t iface, ipv6_addr_t *dst)
@ -342,7 +346,10 @@ void gnrc_ndp_internal_send_rtr_sol(kernel_pid_t iface, ipv6_addr_t *dst)
gnrc_pktbuf_release(pkt); gnrc_pktbuf_release(pkt);
return; return;
} }
gnrc_netapi_send(gnrc_ipv6_pid, hdr); else if (gnrc_netapi_send(gnrc_ipv6_pid, hdr) < 1) {
DEBUG("ndp internal: unable to send router solicitation\n");
gnrc_pktbuf_release(hdr);
}
} }
#if (defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER)) #if (defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_ROUTER))
@ -575,7 +582,10 @@ void gnrc_ndp_internal_send_rtr_adv(kernel_pid_t iface, ipv6_addr_t *src, ipv6_a
gnrc_pktbuf_release(pkt); gnrc_pktbuf_release(pkt);
return; return;
} }
gnrc_netapi_send(gnrc_ipv6_pid, hdr); else if (gnrc_netapi_send(gnrc_ipv6_pid, hdr) < 1) {
DEBUG("ndp internal: unable to send router advertisement\n");
gnrc_pktbuf_release(hdr);
}
} }
#endif #endif

View File

@ -126,7 +126,10 @@ static uint16_t _send_1st_fragment(gnrc_sixlowpan_netif_t *iface, gnrc_pktsnip_t
DEBUG("6lo frag: send first fragment (datagram size: %u, " DEBUG("6lo frag: send first fragment (datagram size: %u, "
"datagram tag: %" PRIu16 ", fragment size: %" PRIu16 ")\n", "datagram tag: %" PRIu16 ", fragment size: %" PRIu16 ")\n",
(unsigned int)datagram_size, _tag, local_offset); (unsigned int)datagram_size, _tag, local_offset);
gnrc_netapi_send(iface->pid, frag); if (gnrc_netapi_send(iface->pid, frag) < 1) {
DEBUG("6lo frag: unable to send first fragment\n");
gnrc_pktbuf_release(frag);
}
return local_offset; return local_offset;
} }
@ -201,7 +204,10 @@ static uint16_t _send_nth_fragment(gnrc_sixlowpan_netif_t *iface, gnrc_pktsnip_t
"fragment size: %" PRIu16 ")\n", "fragment size: %" PRIu16 ")\n",
(unsigned int)datagram_size, _tag, hdr->offset, hdr->offset << 3, (unsigned int)datagram_size, _tag, hdr->offset, hdr->offset << 3,
local_offset); local_offset);
gnrc_netapi_send(iface->pid, frag); if (gnrc_netapi_send(iface->pid, frag) < 1) {
DEBUG("6lo frag: unable to send subsequent fragment\n");
gnrc_pktbuf_release(frag);
}
return local_offset; return local_offset;
} }

View File

@ -262,7 +262,10 @@ static void _send(gnrc_pktsnip_t *pkt)
if (gnrc_pkt_len(pkt2->next) <= iface->max_frag_size) { if (gnrc_pkt_len(pkt2->next) <= iface->max_frag_size) {
DEBUG("6lo: Send SND command for %p to %" PRIu16 "\n", DEBUG("6lo: Send SND command for %p to %" PRIu16 "\n",
(void *)pkt2, hdr->if_pid); (void *)pkt2, hdr->if_pid);
gnrc_netapi_send(hdr->if_pid, pkt2); if (gnrc_netapi_send(hdr->if_pid, pkt2) < 1) {
DEBUG("6lo: unable to send %p over %" PRIu16 "\n", (void *)pkt, hdr->if_pid);
gnrc_pktbuf_release(pkt2);
}
return; return;
} }

View File

@ -234,7 +234,11 @@ int _icmpv6_ping(int argc, char **argv)
} }
vtimer_now(&start); vtimer_now(&start);
gnrc_netapi_send(ipv6_entry->pid, pkt); if (gnrc_netapi_send(ipv6_entry->pid, pkt) < 1) {
puts("error: unable to send ICMPv6 echo request\n");
gnrc_pktbuf_release(pkt);
continue;
}
if (vtimer_msg_receive_timeout(&msg, timeout) >= 0) { if (vtimer_msg_receive_timeout(&msg, timeout) >= 0) {
switch (msg.type) { switch (msg.type) {

View File

@ -834,7 +834,11 @@ int _netif_send(int argc, char **argv)
gnrc_netif_hdr_set_dst_addr(nethdr, addr, addr_len); gnrc_netif_hdr_set_dst_addr(nethdr, addr, addr_len);
nethdr->flags = flags; nethdr->flags = flags;
/* and send it */ /* and send it */
gnrc_netapi_send(dev, pkt); if (gnrc_netapi_send(dev, pkt) < 1) {
puts("error: unable to send\n");
gnrc_pktbuf_release(pkt);
return 1;
}
return 0; return 0;
} }