You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/01/13 08:41:17 UTC

[nuttx] branch master updated (bcb0abc05d -> 8a63d29c6e)

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


    from bcb0abc05d sim/posix/sim_linuxspi.c: fix select not work and incorrect behaviour
     new 0cbbbb9215 net/devif: reuse devif_send() for can/pkt/icmp stack
     new 8a63d29c6e net/devif_poll: optimize device buffer alloc in txpoll

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 net/arp/arp_format.c            | 14 ++++++-
 net/can/can_poll.c              |  5 +--
 net/can/can_sendmsg.c           |  2 +-
 net/devif/Make.defs             |  9 ----
 net/devif/devif.h               | 42 -------------------
 net/devif/devif_cansend.c       | 91 -----------------------------------------
 net/devif/devif_pktsend.c       | 91 -----------------------------------------
 net/devif/devif_poll.c          | 16 --------
 net/devif/devif_send.c          | 11 ++++-
 net/icmp/icmp_poll.c            |  5 +--
 net/icmp/icmp_sendmsg.c         | 36 ++++++++--------
 net/icmpv6/icmpv6_autoconfig.c  |  7 ++++
 net/icmpv6/icmpv6_neighbor.c    |  7 ++++
 net/icmpv6/icmpv6_poll.c        |  5 +--
 net/icmpv6/icmpv6_sendmsg.c     | 26 ++++++------
 net/igmp/igmp_poll.c            |  8 +---
 net/igmp/igmp_send.c            |  7 ++++
 net/ipforward/ipfwd_forward.c   |  9 ++--
 net/mld/mld_poll.c              |  5 +--
 net/mld/mld_send.c              |  7 ++++
 net/netdev/netdev_iob.c         |  1 +
 net/pkt/pkt_poll.c              |  5 +--
 net/pkt/pkt_sendmsg.c           |  2 +-
 net/tcp/tcp_devpoll.c           |  7 ++++
 net/udp/udp_devpoll.c           | 15 +------
 net/udp/udp_sendto_buffered.c   | 21 ++++------
 net/udp/udp_sendto_unbuffered.c | 24 +++++------
 27 files changed, 131 insertions(+), 347 deletions(-)
 delete mode 100644 net/devif/devif_cansend.c
 delete mode 100644 net/devif/devif_pktsend.c


[nuttx] 01/02: net/devif: reuse devif_send() for can/pkt/icmp stack

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 0cbbbb92153283f2727dbd2c0077443c7cdda85d
Author: chao an <an...@xiaomi.com>
AuthorDate: Wed Jan 11 13:57:05 2023 +0800

    net/devif: reuse devif_send() for can/pkt/icmp stack
    
    Signed-off-by: chao an <an...@xiaomi.com>
---
 net/can/can_sendmsg.c       |  2 +-
 net/devif/Make.defs         |  9 -----
 net/devif/devif.h           | 42 ---------------------
 net/devif/devif_cansend.c   | 91 ---------------------------------------------
 net/devif/devif_pktsend.c   | 91 ---------------------------------------------
 net/icmp/icmp_sendmsg.c     | 36 +++++++++---------
 net/icmpv6/icmpv6_sendmsg.c | 26 +++++++------
 net/pkt/pkt_sendmsg.c       |  2 +-
 8 files changed, 35 insertions(+), 264 deletions(-)

diff --git a/net/can/can_sendmsg.c b/net/can/can_sendmsg.c
index c07742639a..e86f82afed 100644
--- a/net/can/can_sendmsg.c
+++ b/net/can/can_sendmsg.c
@@ -106,7 +106,7 @@ static uint16_t psock_send_eventhandler(FAR struct net_driver_s *dev,
         {
           /* Copy the packet data into the device packet buffer and send it */
 
-          devif_can_send(dev, pstate->snd_buffer, pstate->snd_buflen);
+          devif_send(dev, pstate->snd_buffer, pstate->snd_buflen, 0);
           if (dev->d_sndlen == 0)
             {
               return flags;
diff --git a/net/devif/Make.defs b/net/devif/Make.defs
index 89460d80c5..c95b585d65 100644
--- a/net/devif/Make.defs
+++ b/net/devif/Make.defs
@@ -49,15 +49,6 @@ ifeq ($(CONFIG_MM_IOB),y)
   NET_CSRCS += devif_poll.c
   NET_CSRCS += devif_iobsend.c
 
-  # Raw packet socket support
-
-  ifeq ($(CONFIG_NET_PKT),y)
-    NET_CSRCS += devif_pktsend.c
-  endif
-
-  ifeq ($(CONFIG_NET_CAN),y)
-    NET_CSRCS += devif_cansend.c
-  endif
 endif
 
 # Include network device interface build support
diff --git a/net/devif/devif.h b/net/devif/devif.h
index e820c523c3..2378b76ee1 100644
--- a/net/devif/devif.h
+++ b/net/devif/devif.h
@@ -482,48 +482,6 @@ void devif_iob_send(FAR struct net_driver_s *dev, FAR struct iob_s *buf,
                     unsigned int target_offset);
 #endif
 
-/****************************************************************************
- * Name: devif_pkt_send
- *
- * Description:
- *   Called from socket logic in order to send a raw packet in response to
- *   an xmit or poll request from the network interface driver.
- *
- *   This is almost identical to calling devif_send() except that the data to
- *   be sent is copied into dev->d_buf (vs. dev->d_appdata), since there is
- *   no header on the data.
- *
- * Assumptions:
- *   This function must be called with the network locked.
- *
- ****************************************************************************/
-
-#if defined(CONFIG_NET_PKT)
-void devif_pkt_send(FAR struct net_driver_s *dev, FAR const void *buf,
-                    unsigned int len);
-#endif
-
-/****************************************************************************
- * Name: devif_can_send
- *
- * Description:
- *   Called from socket logic in order to send a raw packet in response to
- *   an xmit or poll request from the network interface driver.
- *
- *   This is almost identical to calling devif_send() except that the data to
- *   be sent is copied into dev->d_buf (vs. dev->d_appdata), since there is
- *   no header on the data.
- *
- * Assumptions:
- *   This function must be called with the network locked.
- *
- ****************************************************************************/
-
-#if defined(CONFIG_NET_CAN)
-void devif_can_send(FAR struct net_driver_s *dev, FAR const void *buf,
-                    unsigned int len);
-#endif
-
 /****************************************************************************
  * Name: devif_out
  *
diff --git a/net/devif/devif_cansend.c b/net/devif/devif_cansend.c
deleted file mode 100644
index 9d80dda3c3..0000000000
--- a/net/devif/devif_cansend.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/****************************************************************************
- * net/devif/devif_cansend.c
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.  The
- * ASF licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the
- * License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- ****************************************************************************/
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <string.h>
-#include <assert.h>
-#include <debug.h>
-
-#include <nuttx/net/netdev.h>
-
-#if defined(CONFIG_NET_CAN)
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: devif_can_send
- *
- * Description:
- *   Called from socket logic in order to send a can packet in response to
- *   an xmit or poll request from the network interface driver.
- *
- *   This is almost identical to calling devif_send() except that the data to
- *   be sent is copied into dev->d_buf (vs. dev->d_appdata), since there is
- *   no header on the data.
- *
- * Assumptions:
- *   Called with the network locked.
- *
- ****************************************************************************/
-
-void devif_can_send(FAR struct net_driver_s *dev, FAR const void *buf,
-                    unsigned int len)
-{
-  unsigned int limit = NETDEV_PKTSIZE(dev) - NET_LL_HDRLEN(dev);
-
-  if (dev == NULL || len == 0 || len > limit)
-    {
-      nerr("ERROR: devif_pkt_send fail: %p, sndlen: %u, pktlen: %u\n",
-           dev, len, limit);
-      return;
-    }
-
-  iob_update_pktlen(dev->d_iob, 0);
-
-  /* Copy the data into the device packet buffer and set the number of
-   * bytes to send
-   */
-
-  if (len <= iob_navail(false) * CONFIG_IOB_BUFSIZE)
-    {
-      dev->d_sndlen = iob_trycopyin(dev->d_iob, buf, len, 0, false);
-    }
-  else
-    {
-      dev->d_sndlen = 0;
-    }
-
-  if (dev->d_sndlen != len)
-    {
-      netdev_iob_release(dev);
-      dev->d_sndlen = 0;
-    }
-
-  dev->d_len = dev->d_sndlen;
-}
-
-#endif /* CONFIG_NET_CAN */
diff --git a/net/devif/devif_pktsend.c b/net/devif/devif_pktsend.c
deleted file mode 100644
index 28f8e8308e..0000000000
--- a/net/devif/devif_pktsend.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/****************************************************************************
- * net/devif/devif_pktsend.c
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.  The
- * ASF licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the
- * License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- ****************************************************************************/
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <nuttx/config.h>
-
-#include <string.h>
-#include <assert.h>
-#include <debug.h>
-
-#include <nuttx/net/netdev.h>
-
-#ifdef CONFIG_NET_PKT
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name: devif_pkt_send
- *
- * Description:
- *   Called from socket logic in order to send a raw packet in response to
- *   an xmit or poll request from the network interface driver.
- *
- *   This is almost identical to calling devif_send() except that the data to
- *   be sent is copied into dev->d_buf (vs. dev->d_appdata), since there is
- *   no header on the data.
- *
- * Assumptions:
- *   Called with the network locked.
- *
- ****************************************************************************/
-
-void devif_pkt_send(FAR struct net_driver_s *dev, FAR const void *buf,
-                    unsigned int len)
-{
-  unsigned int limit = NETDEV_PKTSIZE(dev) - NET_LL_HDRLEN(dev);
-
-  if (dev == NULL || len == 0 || len > limit)
-    {
-      nerr("ERROR: devif_pkt_send fail: %p, sndlen: %u, pktlen: %u\n",
-           dev, len, limit);
-      return;
-    }
-
-  iob_update_pktlen(dev->d_iob, 0);
-
-  /* Copy the data into the device packet buffer and set the number of
-   * bytes to send
-   */
-
-  if (len <= iob_navail(false) * CONFIG_IOB_BUFSIZE)
-    {
-      dev->d_sndlen = iob_trycopyin(dev->d_iob, buf, len, 0, false);
-    }
-  else
-    {
-      dev->d_sndlen = 0;
-    }
-
-  if (dev->d_sndlen != len)
-    {
-      netdev_iob_release(dev);
-      dev->d_sndlen = 0;
-    }
-
-  dev->d_len = dev->d_sndlen;
-}
-
-#endif /* CONFIG_NET_PKT */
diff --git a/net/icmp/icmp_sendmsg.c b/net/icmp/icmp_sendmsg.c
index 7e50f92774..97ad179af2 100644
--- a/net/icmp/icmp_sendmsg.c
+++ b/net/icmp/icmp_sendmsg.c
@@ -99,6 +99,14 @@ static void sendto_request(FAR struct net_driver_s *dev,
 {
   FAR struct icmp_hdr_s *icmp;
 
+  /* Set-up to send that amount of data. */
+
+  devif_send(dev, pstate->snd_buf, pstate->snd_buflen, IPv4_HDRLEN);
+  if (dev->d_sndlen != pstate->snd_buflen)
+    {
+      return;
+    }
+
   IFF_SET_IPv4(dev->d_flags);
 
   /* The total length to send is the size of the application data plus the
@@ -107,29 +115,20 @@ static void sendto_request(FAR struct net_driver_s *dev,
 
   dev->d_len = IPv4_HDRLEN + pstate->snd_buflen;
 
-  /* The total size of the data (including the size of the ICMP header) */
-
-  dev->d_sndlen += pstate->snd_buflen;
-
-  /* Copy the ICMP header and payload into place after the IPv4 header */
-
-  icmp              = IPBUF(IPv4_HDRLEN);
-
-  iob_update_pktlen(dev->d_iob, IPv4_HDRLEN);
-
-  iob_copyin(dev->d_iob, pstate->snd_buf,
-             pstate->snd_buflen, IPv4_HDRLEN, false);
-
   /* Initialize the IP header. */
 
   ipv4_build_header(IPv4BUF, dev->d_len, IP_PROTO_ICMP,
                     &dev->d_ipaddr, &pstate->snd_toaddr,
                     IP_TTL_DEFAULT, NULL);
 
+  /* Copy the ICMP header and payload into place after the IPv4 header */
+
+  icmp = IPBUF(IPv4_HDRLEN);
+
   /* Calculate the ICMP checksum. */
 
-  icmp->icmpchksum  = 0;
-  icmp->icmpchksum  = ~icmp_chksum_iob(dev->d_iob);
+  icmp->icmpchksum = 0;
+  icmp->icmpchksum = ~icmp_chksum_iob(dev->d_iob);
   if (icmp->icmpchksum == 0)
     {
       icmp->icmpchksum = 0xffff;
@@ -204,8 +203,11 @@ static uint16_t sendto_eventhandler(FAR struct net_driver_s *dev,
           ninfo("Send ICMP request\n");
 
           sendto_request(dev, pstate);
-          pstate->snd_result = OK;
-          goto end_wait;
+          if (dev->d_sndlen > 0)
+            {
+              pstate->snd_result = OK;
+              goto end_wait;
+            }
         }
 
       /* Continue waiting */
diff --git a/net/icmpv6/icmpv6_sendmsg.c b/net/icmpv6/icmpv6_sendmsg.c
index 70bd8eefa1..fe291359b2 100644
--- a/net/icmpv6/icmpv6_sendmsg.c
+++ b/net/icmpv6/icmpv6_sendmsg.c
@@ -98,6 +98,14 @@ static void sendto_request(FAR struct net_driver_s *dev,
 {
   FAR struct icmpv6_echo_request_s *icmpv6;
 
+  /* Set-up to send that amount of data. */
+
+  devif_send(dev, pstate->snd_buf, pstate->snd_buflen, IPv6_HDRLEN);
+  if (dev->d_sndlen != pstate->snd_buflen)
+    {
+      return;
+    }
+
   IFF_SET_IPv6(dev->d_flags);
 
   /* The total length to send is the size of the application data plus the
@@ -106,21 +114,12 @@ static void sendto_request(FAR struct net_driver_s *dev,
 
   dev->d_len = IPv6_HDRLEN + pstate->snd_buflen;
 
-  /* The total size of the data (including the size of the ICMPv6 header) */
-
-  dev->d_sndlen += pstate->snd_buflen;
-
   ipv6_build_header(IPv6BUF, pstate->snd_buflen, IP_PROTO_ICMP6,
                     dev->d_ipv6addr, pstate->snd_toaddr.s6_addr16, 255);
 
   /* Copy the ICMPv6 request and payload into place after the IPv6 header */
 
-  icmpv6         = IPBUF(IPv6_HDRLEN);
-
-  iob_update_pktlen(dev->d_iob, IPv6_HDRLEN);
-
-  iob_copyin(dev->d_iob, pstate->snd_buf,
-             pstate->snd_buflen, IPv6_HDRLEN, false);
+  icmpv6 = IPBUF(IPv6_HDRLEN);
 
   /* Calculate the ICMPv6 checksum over the ICMPv6 header and payload. */
 
@@ -200,8 +199,11 @@ static uint16_t sendto_eventhandler(FAR struct net_driver_s *dev,
           ninfo("Send ICMPv6 ECHO request\n");
 
           sendto_request(dev, pstate);
-          pstate->snd_result = OK;
-          goto end_wait;
+          if (dev->d_sndlen > 0)
+            {
+              pstate->snd_result = OK;
+              goto end_wait;
+            }
         }
 
       /* Continue waiting */
diff --git a/net/pkt/pkt_sendmsg.c b/net/pkt/pkt_sendmsg.c
index 1e1a500077..f7618c97bd 100644
--- a/net/pkt/pkt_sendmsg.c
+++ b/net/pkt/pkt_sendmsg.c
@@ -105,7 +105,7 @@ static uint16_t psock_send_eventhandler(FAR struct net_driver_s *dev,
         {
           /* Copy the packet data into the device packet buffer and send it */
 
-          devif_pkt_send(dev, pstate->snd_buffer, pstate->snd_buflen);
+          devif_send(dev, pstate->snd_buffer, pstate->snd_buflen, 0);
           if (dev->d_sndlen == 0)
             {
               return flags;


[nuttx] 02/02: net/devif_poll: optimize device buffer alloc in txpoll

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 8a63d29c6edb3056bb2ab89e0eb16896bcf2d57c
Author: chao an <an...@xiaomi.com>
AuthorDate: Wed Jan 11 16:09:20 2023 +0800

    net/devif_poll: optimize device buffer alloc in txpoll
    
    Allocate the device buffer only if the protocol really need to send data.
    not all protocols require the driver to prepare additional iob before
    sending, especially UDP, each iob reserves l2/l3 header in advance
    after prepare write buffer, net device could reuse this entry to send directly
    
    Signed-off-by: chao an <an...@xiaomi.com>
---
 net/arp/arp_format.c            | 14 ++++++++++++--
 net/can/can_poll.c              |  5 ++---
 net/devif/devif_poll.c          | 16 ----------------
 net/devif/devif_send.c          | 11 +++++++++--
 net/icmp/icmp_poll.c            |  5 ++---
 net/icmpv6/icmpv6_autoconfig.c  |  7 +++++++
 net/icmpv6/icmpv6_neighbor.c    |  7 +++++++
 net/icmpv6/icmpv6_poll.c        |  5 ++---
 net/igmp/igmp_poll.c            |  8 ++------
 net/igmp/igmp_send.c            |  7 +++++++
 net/ipforward/ipfwd_forward.c   |  9 +++++----
 net/mld/mld_poll.c              |  5 ++---
 net/mld/mld_send.c              |  7 +++++++
 net/netdev/netdev_iob.c         |  1 +
 net/pkt/pkt_poll.c              |  5 ++---
 net/tcp/tcp_devpoll.c           |  7 +++++++
 net/udp/udp_devpoll.c           | 15 ++-------------
 net/udp/udp_sendto_buffered.c   | 21 ++++++++-------------
 net/udp/udp_sendto_unbuffered.c | 24 ++++++++++++------------
 19 files changed, 96 insertions(+), 83 deletions(-)

diff --git a/net/arp/arp_format.c b/net/arp/arp_format.c
index 6cca53a7f9..2b5db120bb 100644
--- a/net/arp/arp_format.c
+++ b/net/arp/arp_format.c
@@ -75,8 +75,18 @@
 
 void arp_format(FAR struct net_driver_s *dev, in_addr_t ipaddr)
 {
-  FAR struct arp_hdr_s *arp = ARPBUF;
-  FAR struct eth_hdr_s *eth = ETHBUF;
+  FAR struct arp_hdr_s *arp;
+  FAR struct eth_hdr_s *eth;
+
+  /* Prepare device buffer before format arp */
+
+  if (netdev_iob_prepare(dev, false, 0) != OK)
+    {
+      return;
+    }
+
+  arp = ARPBUF;
+  eth = ETHBUF;
 
   /* Construct the ARP packet.  Creating both the Ethernet and ARP headers */
 
diff --git a/net/can/can_poll.c b/net/can/can_poll.c
index 1c7b95019d..2def213a5d 100644
--- a/net/can/can_poll.c
+++ b/net/can/can_poll.c
@@ -66,9 +66,8 @@ void can_poll(FAR struct net_driver_s *dev, FAR struct can_conn_s *conn)
 
   /* Setup for the application callback */
 
-  dev->d_appdata = IPBUF(0);
-  dev->d_len     = 0;
-  dev->d_sndlen  = 0;
+  dev->d_len    = 0;
+  dev->d_sndlen = 0;
 
   /* Perform the application callback */
 
diff --git a/net/devif/devif_poll.c b/net/devif/devif_poll.c
index 4b77fbe218..2fdf462acb 100644
--- a/net/devif/devif_poll.c
+++ b/net/devif/devif_poll.c
@@ -821,13 +821,6 @@ static int devif_iob_poll(FAR struct net_driver_s *dev,
 {
   int bstop;
 
-  /* Device polling, prepare iob buffer */
-
-  if (netdev_iob_prepare(dev, false, 0) != OK)
-    {
-      return true;
-    }
-
   /* Perform all connections poll */
 
   bstop = devif_poll_connections(dev, callback);
@@ -920,15 +913,6 @@ int devif_poll(FAR struct net_driver_s *dev, devif_poll_callback_t callback)
 
   do
     {
-      /* Device polling, prepare iob buffer */
-
-      if (netdev_iob_prepare(dev, false, 0) != OK)
-        {
-          nwarn("WARNING: IOB Prepare failed for dev %s!\n", dev->d_ifname);
-          bstop = true;
-          break;
-        }
-
       /* Perform all connections poll */
 
       bstop = devif_poll_connections(dev, devif_poll_callback);
diff --git a/net/devif/devif_send.c b/net/devif/devif_send.c
index 5e076d0ff8..ea2d5cad41 100644
--- a/net/devif/devif_send.c
+++ b/net/devif/devif_send.c
@@ -78,12 +78,19 @@ void devif_send(FAR struct net_driver_s *dev, FAR const void *buf,
       return;
     }
 
-  iob_update_pktlen(dev->d_iob, offset);
-
   /* Copy in iob to target device buffer */
 
   if (len <= iob_navail(false) * CONFIG_IOB_BUFSIZE)
     {
+      /* Prepare device buffer before poll callback */
+
+      if (netdev_iob_prepare(dev, false, 0) != OK)
+        {
+          return;
+        }
+
+      iob_update_pktlen(dev->d_iob, offset);
+
       dev->d_sndlen = iob_trycopyin(dev->d_iob, buf, len, offset, false);
     }
   else
diff --git a/net/icmp/icmp_poll.c b/net/icmp/icmp_poll.c
index 290c129cd4..09d80d570f 100644
--- a/net/icmp/icmp_poll.c
+++ b/net/icmp/icmp_poll.c
@@ -66,9 +66,8 @@ void icmp_poll(FAR struct net_driver_s *dev, FAR struct icmp_conn_s *conn)
 
   /* Setup for the application callback */
 
-  dev->d_appdata = IPBUF(IPICMP_HDRLEN);
-  dev->d_len     = 0;
-  dev->d_sndlen  = 0;
+  dev->d_len    = 0;
+  dev->d_sndlen = 0;
 
   /* Perform the application callback */
 
diff --git a/net/icmpv6/icmpv6_autoconfig.c b/net/icmpv6/icmpv6_autoconfig.c
index 0d899ad4e1..a8021bd224 100644
--- a/net/icmpv6/icmpv6_autoconfig.c
+++ b/net/icmpv6/icmpv6_autoconfig.c
@@ -125,6 +125,13 @@ static uint16_t icmpv6_router_eventhandler(FAR struct net_driver_s *dev,
           return flags;
         }
 
+      /* Prepare device buffer */
+
+      if (netdev_iob_prepare(dev, false, 0) != OK)
+        {
+          return flags;
+        }
+
       /* It looks like we are good to send the data.
        *
        * Copy the packet data into the device packet buffer and send it.
diff --git a/net/icmpv6/icmpv6_neighbor.c b/net/icmpv6/icmpv6_neighbor.c
index 9b2e4f18b4..1612865bad 100644
--- a/net/icmpv6/icmpv6_neighbor.c
+++ b/net/icmpv6/icmpv6_neighbor.c
@@ -109,6 +109,13 @@ static uint16_t icmpv6_neighbor_eventhandler(FAR struct net_driver_s *dev,
           return flags;
         }
 
+      /* Prepare device buffer */
+
+      if (netdev_iob_prepare(dev, false, 0) != OK)
+        {
+          return flags;
+        }
+
       /* It looks like we are good to send the data.
        *
        * Copy the packet data into the device packet buffer and send it.
diff --git a/net/icmpv6/icmpv6_poll.c b/net/icmpv6/icmpv6_poll.c
index 7da0cd005e..278c3f48b7 100644
--- a/net/icmpv6/icmpv6_poll.c
+++ b/net/icmpv6/icmpv6_poll.c
@@ -67,9 +67,8 @@ void icmpv6_poll(FAR struct net_driver_s *dev,
 
   /* Setup for the application callback */
 
-  dev->d_appdata = IPBUF(IPICMPv6_HDRLEN);
-  dev->d_len     = 0;
-  dev->d_sndlen  = 0;
+  dev->d_len    = 0;
+  dev->d_sndlen = 0;
 
   /* Perform the application callback */
 
diff --git a/net/igmp/igmp_poll.c b/net/igmp/igmp_poll.c
index 47ef3d34d6..b7f71f2fbe 100644
--- a/net/igmp/igmp_poll.c
+++ b/net/igmp/igmp_poll.c
@@ -151,15 +151,11 @@ static inline void igmp_sched_send(FAR struct net_driver_s *dev,
 void igmp_poll(FAR struct net_driver_s *dev)
 {
   FAR struct igmp_group_s *group;
-  uint16_t iphdrlen;
 
   /* Setup the poll operation */
 
-  iphdrlen       = IPv4_HDRLEN + RASIZE;
-
-  dev->d_appdata = IPBUF(iphdrlen + IGMP_HDRLEN);
-  dev->d_len     = 0;
-  dev->d_sndlen  = 0;
+  dev->d_len    = 0;
+  dev->d_sndlen = 0;
 
   /* Check each member of the group */
 
diff --git a/net/igmp/igmp_send.c b/net/igmp/igmp_send.c
index c15a695f77..d60a49a21f 100644
--- a/net/igmp/igmp_send.c
+++ b/net/igmp/igmp_send.c
@@ -109,6 +109,13 @@ void igmp_send(FAR struct net_driver_s *dev, FAR struct igmp_group_s *group,
 
   ninfo("msgid: %02x destipaddr: %08x\n", msgid, (int)*destipaddr);
 
+  /* Prepare device buffer */
+
+  if (netdev_iob_prepare(dev, false, 0) != OK)
+    {
+      return;
+    }
+
   /* The IGMP header immediately follows the IP header */
 
   iphdrlen          = IPv4_HDRLEN + RASIZE;
diff --git a/net/ipforward/ipfwd_forward.c b/net/ipforward/ipfwd_forward.c
index 00d7034030..94a933c38a 100644
--- a/net/ipforward/ipfwd_forward.c
+++ b/net/ipforward/ipfwd_forward.c
@@ -161,6 +161,11 @@ static uint16_t ipfwd_eventhandler(FAR struct net_driver_s *dev,
 
       else
         {
+          /* Copy the user data into d_appdata and send it. */
+
+          devif_forward(fwd);
+          flags &= ~DEVPOLL_MASK;
+
 #if defined(CONFIG_NET_IPv4) && defined(CONFIG_NET_IPv6)
           /* If both IPv4 and IPv6 support are enabled, then we will need to
            * select which one to use when generating the outgoing packet.
@@ -170,10 +175,6 @@ static uint16_t ipfwd_eventhandler(FAR struct net_driver_s *dev,
 
           forward_ipselect(fwd);
 #endif
-          /* Copy the user data into d_appdata and send it. */
-
-          devif_forward(fwd);
-          flags &= ~DEVPOLL_MASK;
         }
 
       /* Free the allocated callback structure */
diff --git a/net/mld/mld_poll.c b/net/mld/mld_poll.c
index d0cd926419..d706ffb29a 100644
--- a/net/mld/mld_poll.c
+++ b/net/mld/mld_poll.c
@@ -60,9 +60,8 @@ void mld_poll(FAR struct net_driver_s *dev)
 
   /* Setup the poll operation */
 
-  dev->d_appdata = IPBUF(IPv6_HDRLEN);
-  dev->d_len     = 0;
-  dev->d_sndlen  = 0;
+  dev->d_len    = 0;
+  dev->d_sndlen = 0;
 
   /* Check if a general query is pending */
 
diff --git a/net/mld/mld_send.c b/net/mld/mld_send.c
index f3fab001d8..8364808f7c 100644
--- a/net/mld/mld_send.c
+++ b/net/mld/mld_send.c
@@ -96,6 +96,13 @@ void mld_send(FAR struct net_driver_s *dev, FAR struct mld_group_s *group,
   DEBUGASSERT(dev != NULL);
   DEBUGASSERT(msgtype == MLD_SEND_GENQUERY || group != NULL);
 
+  /* Prepare device buffer */
+
+  if (netdev_iob_prepare(dev, false, 0) != OK)
+    {
+      return;
+    }
+
   /* Select IPv6 */
 
   IFF_SET_IPv6(dev->d_flags);
diff --git a/net/netdev/netdev_iob.c b/net/netdev/netdev_iob.c
index d6ebbd87de..f6159c4f54 100644
--- a/net/netdev/netdev_iob.c
+++ b/net/netdev/netdev_iob.c
@@ -69,6 +69,7 @@ int netdev_iob_prepare(FAR struct net_driver_s *dev, bool throttled,
 
   if (dev->d_iob == NULL)
     {
+      nwarn("WARNING: IOB Prepare failed for dev %s!\n", dev->d_ifname);
       return -ENOMEM;
     }
 
diff --git a/net/pkt/pkt_poll.c b/net/pkt/pkt_poll.c
index 7d6978fe84..6901ee324b 100644
--- a/net/pkt/pkt_poll.c
+++ b/net/pkt/pkt_poll.c
@@ -65,9 +65,8 @@ void pkt_poll(FAR struct net_driver_s *dev, FAR struct pkt_conn_s *conn)
     {
       /* Setup for the application callback */
 
-      dev->d_appdata = IPBUF(0);
-      dev->d_len     = 0;
-      dev->d_sndlen  = 0;
+      dev->d_len    = 0;
+      dev->d_sndlen = 0;
 
       /* Perform the application callback */
 
diff --git a/net/tcp/tcp_devpoll.c b/net/tcp/tcp_devpoll.c
index 51e022aa30..3d7206c9b4 100644
--- a/net/tcp/tcp_devpoll.c
+++ b/net/tcp/tcp_devpoll.c
@@ -87,6 +87,13 @@ void tcp_poll(FAR struct net_driver_s *dev, FAR struct tcp_conn_s *conn)
 
   DEBUGASSERT(dev != NULL && conn != NULL && dev == conn->dev);
 
+  /* Prepare device buffer */
+
+  if (netdev_iob_prepare(dev, false, 0) != OK)
+    {
+      return;
+    }
+
   /* Discard any currently buffered data */
 
   if (conn->timeout)
diff --git a/net/udp/udp_devpoll.c b/net/udp/udp_devpoll.c
index 7796f8f5e1..d317147f9e 100644
--- a/net/udp/udp_devpoll.c
+++ b/net/udp/udp_devpoll.c
@@ -93,19 +93,8 @@ void udp_poll(FAR struct net_driver_s *dev, FAR struct udp_conn_s *conn)
 
   if (conn->lport != 0)
     {
-      /* Set up for the callback.  We can't know in advance if the
-       * application is going to send a IPv4 or an IPv6 packet, so this setup
-       * may not actually be used.
-       */
-
-#if defined(CONFIG_NET_IPv4)
-      udp_ipv4_select(dev);
-#else /* if defined(CONFIG_NET_IPv6) */
-      udp_ipv6_select(dev);
-#endif
-
-      dev->d_len     = 0;
-      dev->d_sndlen  = 0;
+      dev->d_len    = 0;
+      dev->d_sndlen = 0;
 
       /* Perform the application callback */
 
diff --git a/net/udp/udp_sendto_buffered.c b/net/udp/udp_sendto_buffered.c
index e5c36898fc..7263edb1c0 100644
--- a/net/udp/udp_sendto_buffered.c
+++ b/net/udp/udp_sendto_buffered.c
@@ -406,7 +406,6 @@ static uint16_t sendto_eventhandler(FAR struct net_driver_s *dev,
     {
       uint16_t udpiplen = udpip_hdrsize(conn);
       FAR struct udp_wrbuffer_s *wrb;
-      size_t sndlen;
 
       /* Peek at the head of the write queue (but don't remove anything
        * from the write queue yet).  We know from the above test that
@@ -424,14 +423,20 @@ static uint16_t sendto_eventhandler(FAR struct net_driver_s *dev,
 
       udp_connect(conn, (FAR const struct sockaddr *)&wrb->wb_dest);
 
+      /* Then set-up to send that amount of data with the offset
+       * corresponding to the size of the IP-dependent address structure.
+       */
+
+      netdev_iob_replace(dev, wrb->wb_iob);
+
       /* Get the amount of data that we can send in the next packet.
        * We will send either the remaining data in the buffer I/O
        * buffer chain, or as much as will fit given the MSS and current
        * window size.
        */
 
-      sndlen = wrb->wb_iob->io_pktlen - udpiplen;
-      ninfo("wrb=%p sndlen=%zu\n", wrb, sndlen);
+      dev->d_sndlen = wrb->wb_iob->io_pktlen - udpiplen;
+      ninfo("wrb=%p sndlen=%d\n", wrb, dev->d_sndlen);
 
 #ifdef NEED_IPDOMAIN_SUPPORT
       /* If both IPv4 and IPv6 support are enabled, then we will need to
@@ -443,16 +448,6 @@ static uint16_t sendto_eventhandler(FAR struct net_driver_s *dev,
       sendto_ipselect(dev, conn);
 #endif
 
-      /* Release current device buffer and bypass the iob to l2 driver */
-
-      netdev_iob_release(dev);
-
-      /* Then set-up to send that amount of data with the offset
-       * corresponding to the size of the IP-dependent address structure.
-       */
-
-      devif_iob_send(dev, wrb->wb_iob, sndlen, 0, udpiplen);
-
       /* Free the write buffer at the head of the queue and attempt to
        * setup the next transfer.
        */
diff --git a/net/udp/udp_sendto_unbuffered.c b/net/udp/udp_sendto_unbuffered.c
index ae629bc91d..db1d6ad030 100644
--- a/net/udp/udp_sendto_unbuffered.c
+++ b/net/udp/udp_sendto_unbuffered.c
@@ -192,6 +192,15 @@ static uint16_t sendto_eventhandler(FAR struct net_driver_s *dev,
 
       else
         {
+          /* Copy the user data into d_appdata and send it */
+
+          devif_send(dev, pstate->st_buffer,
+                     pstate->st_buflen, udpip_hdrsize(pstate->st_conn));
+          if (dev->d_sndlen == 0)
+            {
+              return flags;
+            }
+
 #ifdef NEED_IPDOMAIN_SUPPORT
           /* If both IPv4 and IPv6 support are enabled, then we will need to
            * select which one to use when generating the outgoing packet.
@@ -202,23 +211,14 @@ static uint16_t sendto_eventhandler(FAR struct net_driver_s *dev,
           sendto_ipselect(dev, pstate);
 #endif
 
-          /* Copy the user data into d_appdata and send it */
-
-          devif_send(dev, pstate->st_buffer,
-                     pstate->st_buflen, udpip_hdrsize(pstate->st_conn));
-          if (dev->d_sndlen == 0)
-            {
-              return flags;
-            }
-
           pstate->st_sndlen = pstate->st_buflen;
         }
 
       /* Don't allow any further call backs. */
 
-      pstate->st_cb->flags   = 0;
-      pstate->st_cb->priv    = NULL;
-      pstate->st_cb->event   = NULL;
+      pstate->st_cb->flags = 0;
+      pstate->st_cb->priv  = NULL;
+      pstate->st_cb->event = NULL;
 
       /* Wake up the waiting thread */