From 891450d29d5f4c5f7f9e4eafc30c10fedd1786e3 Mon Sep 17 00:00:00 2001 From: Martine Lenders Date: Tue, 29 Sep 2015 16:58:08 +0200 Subject: [PATCH] gnrc_netapi: recover from message send errors --- .../gnrc/link_layer/netdev2/gnrc_netdev2.c | 15 +------------- sys/net/gnrc/netapi/gnrc_netapi.c | 5 ++++- .../icmpv6/echo/gnrc_icmpv6_echo.c | 5 ++++- .../gnrc/network_layer/icmpv6/gnrc_icmpv6.c | 7 +++++-- sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c | 15 +++++++++++--- sys/net/gnrc/network_layer/ndp/gnrc_ndp.c | 5 ++++- .../ndp/internal/gnrc_ndp_internal.c | 20 ++++++++++++++----- .../sixlowpan/frag/gnrc_sixlowpan_frag.c | 10 ++++++++-- .../network_layer/sixlowpan/gnrc_sixlowpan.c | 5 ++++- sys/shell/commands/sc_icmpv6_echo.c | 6 +++++- sys/shell/commands/sc_netif.c | 6 +++++- 11 files changed, 67 insertions(+), 32 deletions(-) diff --git a/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2.c b/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2.c index 320079cc37..f71c839054 100644 --- a/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2.c +++ b/sys/net/gnrc/link_layer/netdev2/gnrc_netdev2.c @@ -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) { - 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 */ - 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); gnrc_pktbuf_release(pkt); 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); - } } /** diff --git a/sys/net/gnrc/netapi/gnrc_netapi.c b/sys/net/gnrc/netapi/gnrc_netapi.c index 99d067a4aa..d6cfac215d 100644 --- a/sys/net/gnrc/netapi/gnrc_netapi.c +++ b/sys/net/gnrc/netapi/gnrc_netapi.c @@ -77,7 +77,10 @@ int gnrc_netapi_dispatch(gnrc_nettype_t type, uint32_t demux_ctx, gnrc_pktbuf_hold(pkt, numof - 1); 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); } } diff --git a/sys/net/gnrc/network_layer/icmpv6/echo/gnrc_icmpv6_echo.c b/sys/net/gnrc/network_layer/icmpv6/echo/gnrc_icmpv6_echo.c index 970a5ba46c..085684d30b 100644 --- a/sys/net/gnrc/network_layer/icmpv6/echo/gnrc_icmpv6_echo.c +++ b/sys/net/gnrc/network_layer/icmpv6/echo/gnrc_icmpv6_echo.c @@ -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); 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); } } diff --git a/sys/net/gnrc/network_layer/icmpv6/gnrc_icmpv6.c b/sys/net/gnrc/network_layer/icmpv6/gnrc_icmpv6.c index b750f8be3f..b85e7166db 100644 --- a/sys/net/gnrc/network_layer/icmpv6/gnrc_icmpv6.c +++ b/sys/net/gnrc/network_layer/icmpv6/gnrc_icmpv6.c @@ -136,11 +136,14 @@ void gnrc_icmpv6_demux(kernel_pid_t iface, gnrc_pktsnip_t *pkt) 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)); 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); } } diff --git a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c index 4d89ec1941..fc30a04c37 100644 --- a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c +++ b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c @@ -291,7 +291,10 @@ static void _send_to_iface(kernel_pid_t iface, gnrc_pktsnip_t *pkt) return; } #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 */ @@ -628,7 +631,10 @@ static void _send(gnrc_pktsnip_t *pkt, bool prep_hdr) 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 { uint8_t l2addr_len = GNRC_IPV6_NC_L2_ADDR_MAX; @@ -677,7 +683,10 @@ static void _dispatch_rcv_pkt(gnrc_nettype_t type, uint32_t demux_ctx, while (entry) { DEBUG("ipv6: Send receive command for %p to %" PRIu16 "\n", (void *)pkt, 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); } } diff --git a/sys/net/gnrc/network_layer/ndp/gnrc_ndp.c b/sys/net/gnrc/network_layer/ndp/gnrc_ndp.c index 33c44ba45f..308a161250 100644 --- a/sys/net/gnrc/network_layer/ndp/gnrc_ndp.c +++ b/sys/net/gnrc/network_layer/ndp/gnrc_ndp.c @@ -317,7 +317,10 @@ void gnrc_ndp_nbr_adv_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt, #ifdef MODULE_GNRC_NDP_NODE gnrc_pktqueue_t *queued_pkt; 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; } #endif diff --git a/sys/net/gnrc/network_layer/ndp/internal/gnrc_ndp_internal.c b/sys/net/gnrc/network_layer/ndp/internal/gnrc_ndp_internal.c index 6ec23314ad..c59d8937a7 100644 --- a/sys/net/gnrc/network_layer/ndp/internal/gnrc_ndp_internal.c +++ b/sys/net/gnrc/network_layer/ndp/internal/gnrc_ndp_internal.c @@ -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 */ _send_delayed(&nc_entry->nbr_adv_timer, delay, hdr); } - else { - gnrc_netapi_send(gnrc_ipv6_pid, hdr); + else if (gnrc_netapi_send(gnrc_ipv6_pid, hdr) < 1) { + 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); 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) @@ -342,7 +346,10 @@ void gnrc_ndp_internal_send_rtr_sol(kernel_pid_t iface, ipv6_addr_t *dst) gnrc_pktbuf_release(pkt); 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)) @@ -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); 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 diff --git a/sys/net/gnrc/network_layer/sixlowpan/frag/gnrc_sixlowpan_frag.c b/sys/net/gnrc/network_layer/sixlowpan/frag/gnrc_sixlowpan_frag.c index 454a8c1890..9cc407a619 100644 --- a/sys/net/gnrc/network_layer/sixlowpan/frag/gnrc_sixlowpan_frag.c +++ b/sys/net/gnrc/network_layer/sixlowpan/frag/gnrc_sixlowpan_frag.c @@ -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, " "datagram tag: %" PRIu16 ", fragment size: %" PRIu16 ")\n", (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; } @@ -201,7 +204,10 @@ static uint16_t _send_nth_fragment(gnrc_sixlowpan_netif_t *iface, gnrc_pktsnip_t "fragment size: %" PRIu16 ")\n", (unsigned int)datagram_size, _tag, hdr->offset, hdr->offset << 3, 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; } diff --git a/sys/net/gnrc/network_layer/sixlowpan/gnrc_sixlowpan.c b/sys/net/gnrc/network_layer/sixlowpan/gnrc_sixlowpan.c index 5c7c23eeb0..caee0895a9 100644 --- a/sys/net/gnrc/network_layer/sixlowpan/gnrc_sixlowpan.c +++ b/sys/net/gnrc/network_layer/sixlowpan/gnrc_sixlowpan.c @@ -262,7 +262,10 @@ static void _send(gnrc_pktsnip_t *pkt) if (gnrc_pkt_len(pkt2->next) <= iface->max_frag_size) { DEBUG("6lo: Send SND command for %p to %" PRIu16 "\n", (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; } diff --git a/sys/shell/commands/sc_icmpv6_echo.c b/sys/shell/commands/sc_icmpv6_echo.c index 913a662d3e..61af94b193 100644 --- a/sys/shell/commands/sc_icmpv6_echo.c +++ b/sys/shell/commands/sc_icmpv6_echo.c @@ -234,7 +234,11 @@ int _icmpv6_ping(int argc, char **argv) } 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) { switch (msg.type) { diff --git a/sys/shell/commands/sc_netif.c b/sys/shell/commands/sc_netif.c index 0ade6e5912..28b7478c63 100644 --- a/sys/shell/commands/sc_netif.c +++ b/sys/shell/commands/sc_netif.c @@ -834,7 +834,11 @@ int _netif_send(int argc, char **argv) gnrc_netif_hdr_set_dst_addr(nethdr, addr, addr_len); nethdr->flags = flags; /* 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; }