diff --git a/arch/sim/src/up_uipdriver.c b/arch/sim/src/up_uipdriver.c
index 82e740bc03d6a51548c10a18e882c11e2f0418f1..d7425f82f3e54ab9dd7f857766d8cfddf8ec4adb 100644
--- a/arch/sim/src/up_uipdriver.c
+++ b/arch/sim/src/up_uipdriver.c
@@ -87,7 +87,7 @@ static struct uip_driver_s g_sim_dev;
  * Private Functions
  ****************************************************************************/
 
-static void timer_set( struct timer *t, unsigned int interval )
+static void timer_set(struct timer *t, unsigned int interval)
 {
   t->interval = interval;
   t->start    = up_getwalltime();
@@ -104,9 +104,9 @@ void timer_reset(struct timer *t)
 }
 
 #ifdef CONFIG_NET_PROMISCUOUS
-# define uipdriver_comparemac(a,b) (0)
+# define up_comparemac(a,b) (0)
 #else
-static inline int uip_comparemac(struct uip_eth_addr *paddr1, struct uip_eth_addr *paddr2)
+static inline int up_comparemac(struct uip_eth_addr *paddr1, struct uip_eth_addr *paddr2)
 {
   return memcmp(paddr1, paddr2, sizeof(struct uip_eth_addr));
 }
@@ -155,7 +155,7 @@ void uipdriver_loop(void)
        * MAC address
        */
 
-      if (g_sim_dev.d_len > UIP_LLH_LEN && uip_comparemac( &BUF->dest, &g_sim_dev.d_mac) == 0)
+      if (g_sim_dev.d_len > UIP_LLH_LEN && up_comparemac( &BUF->dest, &g_sim_dev.d_mac) == 0)
         {
           /* We only accept IP packets of the configured type and ARP packets */
 
@@ -201,7 +201,7 @@ void uipdriver_loop(void)
   else if (timer_expired(&g_periodic_timer))
     {
       timer_reset(&g_periodic_timer);
-      uip_poll(&g_sim_dev, sim_uiptxpoll, UIP_DRV_TIMER);
+      uip_poll(&g_sim_dev, sim_uiptxpoll, 1);
     }
   sched_unlock();
 }
diff --git a/include/net/uip/uip.h b/include/net/uip/uip.h
index 15c72b22c499a909d414410715b0106e29e8ca51..155f0e6a77eef71b80f0a80dda59d0d993a788b6 100644
--- a/include/net/uip/uip.h
+++ b/include/net/uip/uip.h
@@ -58,11 +58,9 @@
  * Definitions
  ****************************************************************************/
 
-/* The following flags may be set in the global variable uip_flags before
- * calling the application callback. The UIP_ACKDATA, UIP_NEWDATA, and
- * UIP_CLOSE flags may both be set at the same time, whereas the others are
- * mutualy exclusive. Note that these flags should *NOT* be accessed directly,
- * but only through the uIP functions/macros.
+/* The following flags may be set in the set of flags before calling the
+ * application callback. The UIP_ACKDATA, UIP_NEWDATA, and UIP_CLOSE flags
+ * may be set at the same time, whereas the others are mutualy exclusive.
  */
 
 #define UIP_ACKDATA    (1 << 0) /* Signifies that the outstanding data was acked and the
@@ -87,7 +85,7 @@
 #define UIP_DATA_EVENTS (UIP_ACKDATA|UIP_NEWDATA|UIP_REXMIT|UIP_POLL)
 #define UIP_CONN_EVENTS (UIP_CLOSE|UIP_ABORT|UIP_CONNECTED|UIP_TIMEDOUT)
 
-/* The TCP states used in the uip_conn->tcpstateflags. */
+/* The TCP states used in the struct uip_conn tcpstateflags field. */
 
 #define UIP_CLOSED      0 /* The connection is not in use and available */
 #define UIP_ALLOCATED   1 /* The connection is allocated, but not yet initialized */
@@ -186,14 +184,20 @@ struct uip_conn
 
   /* Higher level logic can retain application specific information
    * in the following:
+   *
+   *   data_event() is called on all events.
+   *   accept() is called when the TCP logic has created a connection
+   *   connection_event() is called on any of the subset of connection-related events
    */
 
   void *data_private;
-  void (*data_event)(struct uip_driver_s *dev, void *private);
+  uint8 (*data_event)(struct uip_driver_s *dev, struct uip_conn *conn, uint8 flags);
+
   void *accept_private;
-  int (*accept)(void *private, struct uip_conn *conn);
+  int (*accept)(struct uip_conn *listener, struct uip_conn *conn);
+
   void *connection_private;
-  void (*connection_event)(void *private);
+  void (*connection_event)(struct uip_conn *conn, uint8 flags);
 };
 
 #ifdef CONFIG_NET_UDP
@@ -210,7 +214,7 @@ struct uip_udp_conn
   /* Defines the UDP callback */
 
   void *private;
-  void (*event)(struct uip_driver_s *dev, void *private);
+  void (*event)(struct uip_driver_s *dev, struct uip_udp_conn *conn, uint8 flags);
 };
 #endif  /* CONFIG_NET_UDP */
 
@@ -451,14 +455,6 @@ extern void *uip_urgdata;
 extern uint16 uip_urglen; /* Length of (received) urgent data */
 #endif /* UIP_URGDATA > 0 */
 
-/* Pointer to the current TCP connection.
- *
- * The uip_conn pointer can be used to access the current TCP
- * connection.
- */
-
-extern struct uip_conn *uip_conn;
-
 /* The current UDP connection. */
 
 #ifdef CONFIG_NET_UDP
@@ -472,15 +468,6 @@ extern struct uip_udp_conn *uip_udp_conn;
 
 extern struct uip_stats uip_stat;
 
-/* uint8 uip_flags:
- *
- * When the application is called, uip_flags will contain the flags
- * that are defined in this file. Please read below for more
- * infomation.
- */
-
-extern uint8 uip_flags;
-
 /****************************************************************************
  * Public Function Prototypes
  ****************************************************************************/
@@ -573,10 +560,7 @@ int uip_listen(uint16 port);
 
 int uip_unlisten(uint16 port);
 
-/* Check if a connection has outstanding (i.e., unacknowledged) data.
- *
- * conn A pointer to the uip_conn structure for the connection.
- */
+/* Check if a connection has outstanding (i.e., unacknowledged) data. */
 
 #define uip_outstanding(conn) ((conn)->len)
 
@@ -623,29 +607,13 @@ void uip_send(struct uip_driver_s *dev, const void *buf, int len);
 
 #define uip_urgdatalen()    uip_urglen
 
-/* Close the current connection.
- *
- * This function will close the current connection in a nice way.
- */
-
-#define uip_close()         (uip_flags = UIP_CLOSE)
-
-/* Abort the current connection.
- *
- * This function will abort (reset) the current connection, and is
- * usually used when an error has occured that prevents using the
- * uip_close() function.
- */
-
-#define uip_abort()         (uip_flags = UIP_ABORT)
-
 /* Tell the sending host to stop sending data.
  *
  * This function will close our receiver's window so that we stop
  * receiving data for the current connection.
  */
 
-#define uip_stop()          (uip_conn->tcpstateflags |= UIP_STOPPED)
+#define uip_stop(conn)          ((conn)->tcpstateflags |= UIP_STOPPED)
 
 /* Find out if the current connection has been previously stopped with
  * uip_stop().
@@ -660,29 +628,24 @@ void uip_send(struct uip_driver_s *dev, const void *buf, int len);
  * start receiving data for the current connection.
  */
 
-#define uip_restart()         do { uip_flags |= UIP_NEWDATA; \
-                                   uip_conn->tcpstateflags &= ~UIP_STOPPED; \
-                              } while(0)
+#define uip_restart(conn,f) \
+  do { \
+    (f) |= UIP_NEWDATA; \
+    (conn)->tcpstateflags &= ~UIP_STOPPED; \
+  } while(0)
 
 
 /* uIP tests that can be made to determine in what state the current
  * connection is, and what the application function should do.
  *
- * Is the current connection a UDP connection?
- *
- * This function checks whether the current connection is a UDP connection.
- */
-
-#define uip_udpconnection() (uip_conn == NULL)
-
-/* Is new incoming data available?
+ * Is new incoming data available?
  *
  * Will reduce to non-zero if there is new data for the application
  * present at the d_appdata pointer. The size of the data is
  * avaliable through the d_len element.
  */
 
-#define uip_newdata_event() (uip_flags & UIP_NEWDATA)
+#define uip_newdata_event(f) ((f) & UIP_NEWDATA)
 
 /* Has previously sent data been acknowledged?
  *
@@ -691,7 +654,7 @@ void uip_send(struct uip_driver_s *dev, const void *buf, int len);
  * can send new data.
  */
 
-#define uip_ack_event() (uip_flags & UIP_ACKDATA)
+#define uip_ack_event(f) ((f) & UIP_ACKDATA)
 
 /* Has the connection just been connected?
  *
@@ -701,7 +664,7 @@ void uip_send(struct uip_driver_s *dev, const void *buf, int len);
  * uip_listen()).
  */
 
-#define uip_connected_event() (uip_flags & UIP_CONNECTED)
+#define uip_connected_event(f) ((f) & UIP_CONNECTED)
 
 /* Has the connection been closed by the other end?
  *
@@ -709,7 +672,7 @@ void uip_send(struct uip_driver_s *dev, const void *buf, int len);
  * host. The application may then do the necessary clean-ups.
  */
 
-#define uip_close_event() (uip_flags & UIP_CLOSE)
+#define uip_close_event(f) ((f) & UIP_CLOSE)
 
 /* Has the connection been aborted by the other end?
  *
@@ -717,7 +680,7 @@ void uip_send(struct uip_driver_s *dev, const void *buf, int len);
  * remote host.
  */
 
-#define uip_abort_event() (uip_flags & UIP_ABORT)
+#define uip_abort_event(f) ((f) & UIP_ABORT)
 
 /* Has the connection timed out?
  *
@@ -725,7 +688,7 @@ void uip_send(struct uip_driver_s *dev, const void *buf, int len);
  * retransmissions.
  */
 
-#define uip_timeout_event() (uip_flags & UIP_TIMEDOUT)
+#define uip_timeout_event(f) ((f) & UIP_TIMEDOUT)
 
 /* Do we need to retransmit previously data?
  *
@@ -735,7 +698,7 @@ void uip_send(struct uip_driver_s *dev, const void *buf, int len);
  * time, using the uip_send() function.
  */
 
-#define uip_rexmit_event() (uip_flags & UIP_REXMIT)
+#define uip_rexmit_event(f) ((f) & UIP_REXMIT)
 
 /* Is the connection being polled by uIP?
  *
@@ -747,13 +710,13 @@ void uip_send(struct uip_driver_s *dev, const void *buf, int len);
  * wait for the remote host to send data.
  */
 
-#define uip_poll_event() (uip_flags & UIP_POLL)
+#define uip_poll_event(f) ((f) & UIP_POLL)
 
 /* Get the initial maxium segment size (MSS) of the current
  * connection.
  */
 
-#define uip_initialmss() (uip_conn->initialmss)
+#define uip_initialmss(conn) ((conn)->initialmss)
 
 /* Get the current maxium segment size that can be sent on the current
  * connection.
@@ -764,7 +727,7 @@ void uip_send(struct uip_driver_s *dev, const void *buf, int len);
  * uip_initialmss()).
  */
 
-#define uip_mss() (uip_conn->mss)
+#define uip_mss(conn) ((conn)->mss)
 
 /* Bind a UDP connection to a local address */
 
diff --git a/net/accept.c b/net/accept.c
index 66c05e989a01e858a44ea818a75f1045e636f158..34318190da507d8ecab7e1ecf92c0f75897459d7 100644
--- a/net/accept.c
+++ b/net/accept.c
@@ -61,7 +61,6 @@ struct accept_s
 #else
   FAR const struct sockaddr_in  *acpt_addr;       /* Return connection adress */
 #endif
-  FAR struct uip_conn           *acpt_listenconn; /* The listener connection */
   FAR struct uip_conn           *acpt_newconn;    /* The accepted connection */
   int                            acpt_result;     /* The result of the wait */
 };
@@ -80,11 +79,21 @@ struct accept_s
  * Description:
  *   Receive interrupt level callbacks when connections occur
  *
+ * Parameters:
+ *   listener The conection stucture of the listener
+ *   conn     The connection stucture that was just accepted
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   Running at the interrupt level
+ *
  ****************************************************************************/
 
-static int accept_interrupt(void *private, struct uip_conn *conn)
+static int accept_interrupt(struct uip_conn *listener, struct uip_conn *conn)
 {
-  struct accept_s *pstate = (struct accept_s *)private;
+  struct accept_s *pstate = (struct accept_s *)listener->accept_private;
   int ret = -EINVAL;
   if (pstate)
     {
@@ -92,16 +101,16 @@ static int accept_interrupt(void *private, struct uip_conn *conn)
 #warning "need to return the address of the connection"
 
       /* Save the connection structure */
-      
-      pstate->acpt_newconn = conn;
-      pstate->acpt_result  = OK;
+
+      pstate->acpt_newconn     = conn;
+      pstate->acpt_result      = OK;
       sem_post(&pstate->acpt_sem);
-      
+
       /* Stop any further callbacks */
 
-      pstate->acpt_listenconn->accept_private = NULL;
-      pstate->acpt_listenconn->accept         = NULL;
-      ret = OK;
+      listener->accept_private = NULL;
+      listener->accept         = NULL;
+      ret                      = OK;
   }
   return ret;
 }
@@ -275,7 +284,6 @@ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
 
   save                  = irqsave();
   state.acpt_addr       = inaddr;
-  state.acpt_listenconn = psock->s_conn;
   state.acpt_newconn    = NULL;
   state.acpt_result     = OK;
 
diff --git a/net/connect.c b/net/connect.c
index 47047b3cf349103e8b6d632a9c705985d8dd3520..56aee612c858db764af6fbae317f7bedfd078a2c 100644
--- a/net/connect.c
+++ b/net/connect.c
@@ -65,11 +65,12 @@ struct tcp_connect_s
  * Private Function Prototypes
  ****************************************************************************/
 
-static void connection_event(void *private);
+static void connection_event(struct uip_conn *conn, uint8 flags);
 static inline void tcp_setup_callbacks(struct uip_conn *conn, FAR struct socket *psock,
                                        FAR struct tcp_connect_s *pstate);
 static inline void tcp_teardown_callbacks(struct uip_conn *conn, int status);
-static void tcp_connect_interrupt(struct uip_driver_s *dev, void *private);
+static uint8 tcp_connect_interrupt(struct uip_driver_s *dev,
+                                   struct uip_conn *conn, uint8 flags);
 #ifdef CONFIG_NET_IPv6
 static inline int tcp_connect(FAR struct socket *psock, const struct sockaddr_in6 *inaddr);
 #else
@@ -87,7 +88,8 @@ static inline int tcp_connect(FAR struct socket *psock, const struct sockaddr_in
  *
  * Parameters:
  *   dev      The sructure of the network driver that caused the interrupt
- *   private  An instance of struct recvfrom_s cast to void*
+ *   conn     The connection structure associated with the socket
+ *   flags    Set of events describing why the callback was invoked
  *
  * Returned Value:
  *   None
@@ -97,19 +99,19 @@ static inline int tcp_connect(FAR struct socket *psock, const struct sockaddr_in
  *
  ****************************************************************************/
 
-static void connection_event(void *private)
+static void connection_event(struct uip_conn *conn, uint8 flags)
 {
-  FAR struct socket *psock = (FAR struct socket *)private;
+  FAR struct socket *psock = (FAR struct socket *)conn->connection_private;
 
   if (psock)
     {
-      vdbg("uip_flags: %02x s_flags: %02x\n", uip_flags, psock->s_flags);
+      vdbg("flags: %02x s_flags: %02x\n", flags, psock->s_flags);
 
       /* UIP_CLOSE: The remote host has closed the connection
        * UIP_ABORT: The remote host has aborted the connection
        * UIP_TIMEDOUT: Connection aborted due to too many retransmissions.
        */
-      if ((uip_flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
+      if ((flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
         {
           /* Indicate that the socket is no longer connected */
 
@@ -118,7 +120,7 @@ static void connection_event(void *private)
 
       /* UIP_CONNECTED: The socket is successfully connected */
 
-      else if ((uip_flags & UIP_CONNECTED) != 0)
+      else if ((flags & UIP_CONNECTED) != 0)
         {
           /* Indicate that the socket is now connected */
 
@@ -178,7 +180,8 @@ static inline void tcp_teardown_callbacks(struct uip_conn *conn, int status)
  *
  * Parameters:
  *   dev      The sructure of the network driver that caused the interrupt
- *   private  An instance of struct recvfrom_s cast to void*
+ *   conn     The connection structure associated with the socket
+ *   flags    Set of events describing why the callback was invoked
  *
  * Returned Value:
  *   None
@@ -188,11 +191,12 @@ static inline void tcp_teardown_callbacks(struct uip_conn *conn, int status)
  *
  ****************************************************************************/
 
-static void tcp_connect_interrupt(struct uip_driver_s *dev, void *private)
+static uint8 tcp_connect_interrupt(struct uip_driver_s *dev,
+                                   struct uip_conn *conn, uint8 flags)
 {
-  struct tcp_connect_s *pstate = (struct tcp_connect_s *)private;
+  struct tcp_connect_s *pstate = (struct tcp_connect_s *)conn->data_private;
 
-  vdbg("uip_flags: %02x\n", uip_flags);
+  vdbg("flags: %02x\n", flags);
 
   /* 'private' might be null in some race conditions (?) */
 
@@ -213,7 +217,7 @@ static void tcp_connect_interrupt(struct uip_driver_s *dev, void *private)
        * UIP_ABORT: The remote host has aborted the connection
        */
 
-      if ((uip_flags & (UIP_CLOSE|UIP_ABORT)) != 0)
+      if ((flags & (UIP_CLOSE|UIP_ABORT)) != 0)
         {
           /* Indicate that remote host refused the connection */
 
@@ -222,7 +226,7 @@ static void tcp_connect_interrupt(struct uip_driver_s *dev, void *private)
 
       /* UIP_TIMEDOUT: Connection aborted due to too many retransmissions. */
 
-      else if ((uip_flags & UIP_TIMEDOUT) != 0)
+      else if ((flags & UIP_TIMEDOUT) != 0)
         {
           /* Indicate that the remote host is unreachable (or should this be timedout?) */
 
@@ -231,7 +235,7 @@ static void tcp_connect_interrupt(struct uip_driver_s *dev, void *private)
 
       /* UIP_CONNECTED: The socket is successfully connected */
 
-      else if ((uip_flags & UIP_CONNECTED) != 0)
+      else if ((flags & UIP_CONNECTED) != 0)
         {
           /* Indicate that the socket is no longer connected */
 
@@ -242,7 +246,7 @@ static void tcp_connect_interrupt(struct uip_driver_s *dev, void *private)
 
       else
         {
-          return;
+          return 0;
         }
 
       vdbg("Resuming: %d\n", pstate->tc_result);
@@ -255,6 +259,7 @@ static void tcp_connect_interrupt(struct uip_driver_s *dev, void *private)
 
       sem_post(&pstate->tc_sem);
     }
+  return 0;
 }
 
 /****************************************************************************
diff --git a/net/recvfrom.c b/net/recvfrom.c
index 149abc10b6a77a60431cab4776bb5d8936bcd25a..5790139132d5a1e0446af8ada4165621639de85b 100644
--- a/net/recvfrom.c
+++ b/net/recvfrom.c
@@ -81,15 +81,14 @@ struct recvfrom_s
  ****************************************************************************/
 
 /****************************************************************************
- * Function: recvfrom_interrupt
+ * Function: recvfrom_newdata
  *
  * Description:
- *   This function is called from the interrupt level to perform the actual
- *   receive operation via by the uIP layer.
+ *   Copy the read data from the packet
  *
  * Parameters:
  *   dev      The sructure of the network driver that caused the interrupt
- *   private  An instance of struct recvfrom_s cast to void*
+ *   pstate   recvfrom state structure
  *
  * Returned Value:
  *   None
@@ -99,81 +98,140 @@ struct recvfrom_s
  *
  ****************************************************************************/
 
-static void recvfrom_interrupt(struct uip_driver_s *dev, void *private)
+static void recvfrom_newdata(struct uip_driver_s *dev, struct recvfrom_s *pstate)
 {
-  struct recvfrom_s *pstate = (struct recvfrom_s *)private;
-#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK)
-  FAR struct socket *psock;
-#endif
   size_t recvlen;
 
-  vdbg("uip_flags: %02x\n", uip_flags);
-
-  /* 'private' might be null in some race conditions (?) */
+  /* Get the length of the data to return */
 
-  if (pstate)
+  if (dev->d_len > pstate->rf_buflen)
     {
+      recvlen = pstate->rf_buflen;
+    }
+  else
+    {
+      recvlen = dev->d_len;
+    }
+
+  /* Copy the new appdata into the user buffer */
+
+  memcpy(pstate->rf_buffer, dev->d_appdata, recvlen);
+  vdbg("Received %d bytes (of %d)\n", recvlen, dev->d_len);
+
+  /* Update the accumulated size of the data read */
+
+  pstate->rf_recvlen += recvlen;
+  pstate->rf_buffer  += recvlen;
+  pstate->rf_buflen  -= recvlen;
+}
+
+/****************************************************************************
+ * Function: recvfrom_timeout
+ *
+ * Description:
+ *   Check for recvfrom timeout.
+ *
+ * Parameters:
+ *   pstate   recvfrom state structure
+ *
+ * Returned Value:
+ *   TRUE:timeout FALSE:no timeout
+ *
+ * Assumptions:
+ *   Running at the interrupt level
+ *
+ ****************************************************************************/
+
 #if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK)
+static int recvfrom_timeout(struct recvfrom_s *pstate)
+{
+  FAR struct socket *psock = 0;
+  socktimeo_t        timeo = 0;
+
+  /* If this is a TCP socket that has already received some data,
+   * than we will always use a short timeout.
+   */
+
+  if (pstate->rf_recvlen > 0)
+    {
+      /* Use the short timeout */
+
+      timeo = TCP_TIMEO;
+    }
+
+  /* No.. check for a timeout configured via setsockopts(SO_RCVTIMEO).
+   * If none... we well let the read hang forever.
+   */
+
+  else
+    {
       /* Get the socket reference from the private data */
 
       psock = pstate->rf_sock;
-#endif
+      if (psock)
+        {
+          timeo = psock->s_rcvtimeo;
+        }
+    }
 
-      /* If new data is available, then complete the read action. */
+  /* Is there an effective timeout? */
 
-      if (uip_newdata_event())
-        {
-          /* Get the length of the data to return */
+  if (timeo)
+    {
+      /* Yes.. Check if the timeout has elapsed */
 
-          if (dev->d_len > pstate->rf_buflen)
-            {
-              recvlen = pstate->rf_buflen;
-            }
-          else
-            {
-              recvlen = dev->d_len;
-            }
+      return net_timeo(pstate->rf_starttime, timeo);
+    }
 
-          /* Copy the new appdata into the user buffer */
+  /* No timeout */
 
-          memcpy(pstate->rf_buffer, dev->d_appdata, recvlen);
-          vdbg("Received %d bytes (of %d)\n", recvlen, dev->d_len);
+  return FALSE;
+}
+#endif /* CONFIG_NET_SOCKOPTS && !CONFIG_DISABLE_CLOCK */
 
-          /* Update the accumulated size of the data read */
+/****************************************************************************
+ * Function: recvfrom_tcpinterrupt
+ *
+ * Description:
+ *   This function is called from the interrupt level to perform the actual
+ *   TCP receive operation via by the uIP layer.
+ *
+ * Parameters:
+ *   dev      The sructure of the network driver that caused the interrupt
+ *   conn     The connection structure associated with the socket
+ *   flags    Set of events describing why the callback was invoked
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   Running at the interrupt level
+ *
+ ****************************************************************************/
 
-          pstate->rf_recvlen += recvlen;
-          pstate->rf_buffer  += recvlen;
-          pstate->rf_buflen  -= recvlen;
+static uint8 recvfrom_tcpinterrupt(struct uip_driver_s *dev,
+                                   struct uip_conn *conn, uint8 flags)
+{
+  struct recvfrom_s *pstate = (struct recvfrom_s *)conn->data_private;
 
-          /* Are we finished?  If this is a UDP socket or if the user
-           * buffer has been filled, then we are finished.
-           */
+  vdbg("flags: %02x\n", flags);
 
-#ifdef CONFIG_NET_UDP
-          if (psock->s_type == SOCK_DGRAM)
-            {
-              struct uip_udp_conn *udp_conn;
+  /* 'private' might be null in some race conditions (?) */
 
-              vdbg("UDP resume\n");
+  if (pstate)
+    {
+      /* If new data is available, then complete the read action. */
 
-              /* Don't allow any further UDP call backs. */
+      if (uip_newdata_event(flags))
+        {
+          /* Copy the data from the packet */
 
-              udp_conn          = (struct uip_udp_conn *)psock->s_conn;
-              udp_conn->private = NULL;
-              udp_conn->event   = NULL;
+          recvfrom_newdata(dev, pstate);
 
-              /* Wake up the waiting thread, returning the number of bytes
-               * actually read.
-               */
+          /* If the user buffer has been filled, then we are finished. */
 
-              sem_post(&pstate->rf_sem);
-            }
-          else
-#endif
           if (pstate->rf_buflen == 0)
             {
-              struct uip_conn *conn;
-
               vdbg("TCP resume\n");
 
               /* The TCP receive buffer is full.  Return now, perhaps truncating
@@ -182,7 +240,6 @@ static void recvfrom_interrupt(struct uip_driver_s *dev, void *private)
                * Don't allow any further TCP call backs.
                */
 
-              conn               = (struct uip_conn *)psock->s_conn;
               conn->data_private = NULL;
               conn->data_event   = NULL;
 
@@ -204,26 +261,14 @@ static void recvfrom_interrupt(struct uip_driver_s *dev, void *private)
 
       /* Check for a loss of connection */
 
-      else if ((uip_flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
+      else if ((flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
         {
           vdbg("error\n");
 
           /* Stop further callbacks */
 
-#ifdef CONFIG_NET_UDP
-          if (psock->s_type == SOCK_DGRAM)
-            {
-              struct uip_udp_conn *udp_conn = (struct uip_udp_conn *)psock->s_conn;
-              udp_conn->private  = NULL;
-              udp_conn->event    = NULL;
-            }
-          else
-#endif
-            {
-              struct uip_conn *conn = (struct uip_conn *)psock->s_conn;
-              conn->data_private = NULL;
-              conn->data_event   = NULL;
-            }
+          conn->data_private = NULL;
+          conn->data_event   = NULL;
 
           /* Report not connected */
 
@@ -239,92 +284,140 @@ static void recvfrom_interrupt(struct uip_driver_s *dev, void *private)
        */
 
 #if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK)
-      else
+      else if (recvfrom_timeout(pstate))
         {
-          socktimeo_t timeo;
-
-          /* If this is a TCP socket that has already received some data,
-           * than we will always use a short timeout.
+          /* Yes.. the timeout has elapsed... do not allow any further
+           * callbacks
            */
 
-          if (pstate->rf_recvlen > 0)
-            {
-              /* Use the short timeout */
+          vdbg("TCP timeout\n");
 
-              timeo = TCP_TIMEO;
-            }
+          conn->data_private = NULL;
+          conn->data_event   = NULL;
 
-          /* No.. check for a timeout configured via setsockopts(SO_RCVTIMEO).
-           * If none... we well let the read hang forever.
-           */
+          /* Report an error only if no data has been received */
 
-          else
+          if (pstate->rf_recvlen == 0)
             {
-              timeo = psock->s_rcvtimeo;
+              /* Report the timeout error */
+
+              pstate->rf_result = -EAGAIN;
             }
 
-          /* Is there an effective timeout? */
+          /* Wake up the waiting thread, returning either the error -EAGAIN
+           * that signals the timeout event or the data received up to
+           * the point tht the timeout occured (no error).
+           */
 
-          if (timeo)
-            {
-              /* Yes.. Check if the timeout has elapsed */
+          sem_post(&pstate->rf_sem);
+        }
+#endif /* CONFIG_NET_SOCKOPTS && !CONFIG_DISABLE_CLOCK */
+    }
+  return 0;
+}
 
-              if (net_timeo(pstate->rf_starttime, timeo))
-                {
-                  /* Yes.. the timeout has elapsed... do not allow any further
-                   * callbacks
-                   */
+/****************************************************************************
+ * Function: recvfrom_udpinterrupt
+ *
+ * Description:
+ *   This function is called from the interrupt level to perform the actual
+ *   UDP receive operation via by the uIP layer.
+ *
+ * Parameters:
+ *   dev      The sructure of the network driver that caused the interrupt
+ *   conn     The connection structure associated with the socket
+ *   flags    Set of events describing why the callback was invoked
+ *
+ * Returned Value:
+ *   None
+ *
+ * Assumptions:
+ *   Running at the interrupt level
+ *
+ ****************************************************************************/
 
 #ifdef CONFIG_NET_UDP
-                  if (psock->s_type == SOCK_DGRAM)
-                    {
-                      struct uip_udp_conn *udp_conn;
+static void recvfrom_udpinterrupt(struct uip_driver_s *dev,
+                                  struct uip_udp_conn *conn, uint8 flags)
+{
+  struct recvfrom_s *pstate = (struct recvfrom_s *)conn->private;
 
-                      vdbg("UDP timeout\n");
+  vdbg("flags: %02x\n", flags);
 
-                      /* Stop further callbacks */
+  /* 'private' might be null in some race conditions (?) */
 
-                      udp_conn          = (struct uip_udp_conn *)psock->s_conn;
-                      udp_conn->private = NULL;
-                      udp_conn->event   = NULL;
+  if (pstate)
+    {
+      /* If new data is available, then complete the read action. */
 
-                      /* Report a timeout error */
+      if (uip_newdata_event(flags))
+        {
+          /* Copy the data from the packet */
 
-                      pstate->rf_result = -EAGAIN;
-                    }
-                  else
-#endif
-                    {
-                      struct uip_conn *conn;
+          recvfrom_newdata(dev, pstate);
+
+          /* We are finished. */
 
-                      vdbg("TCP timeout\n");
+          vdbg("UDP resume\n");
 
-                      conn               = (struct uip_conn *)psock->s_conn;
-                      conn->data_private = NULL;
-                      conn->data_event   = NULL;
+          /* Don't allow any further UDP call backs. */
 
-                      /* Report an error only if no data has been received */
+          conn->private = NULL;
+          conn->event   = NULL;
 
-                      if (pstate->rf_recvlen == 0)
-                        {
-                          /* Report the timeout error */
+          /* Wake up the waiting thread, returning the number of bytes
+           * actually read.
+           */
 
-                          pstate->rf_result = -EAGAIN;
-                        }
-                    }
+          sem_post(&pstate->rf_sem);
+        }
 
-                  /* Wake up the waiting thread, returning either the error -EAGAIN
-                   * that signals the timeout event or the data received up to
-                   * the point tht the timeout occured (no error).
-                   */
+      /* Check for a loss of connection */
 
-                  sem_post(&pstate->rf_sem);
-                }
-            }
+      else if ((flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
+        {
+          vdbg("error\n");
+
+          /* Stop further callbacks */
+
+          conn->private  = NULL;
+          conn->event    = NULL;
+
+          /* Report not connected */
+
+          pstate->rf_result = -ENOTCONN;
+
+          /* Wake up the waiting thread */
+
+          sem_post(&pstate->rf_sem);
         }
-#endif
+
+      /* No data has been received -- this is some other event... probably a
+       * poll -- check for a timeout.
+       */
+
+#if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK)
+      else if (recvfrom_timeout(pstate))
+        {
+          /* Yes.. the timeout has elapsed... do not allow any further
+           * callbacks
+           */
+
+          vdbg("UDP timeout\n");
+
+          /* Stop further callbacks */
+
+          conn->private = NULL;
+          conn->event   = NULL;
+
+          /* Report a timeout error */
+
+          pstate->rf_result = -EAGAIN;
+        }
+#endif /* CONFIG_NET_SOCKOPTS && !CONFIG_DISABLE_CLOCK */
     }
 }
+#endif
 
 /****************************************************************************
  * Function: recvfrom_init
@@ -468,7 +561,7 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
 
   udp_conn          = (struct uip_udp_conn *)psock->s_conn;
   udp_conn->private = (void*)&state;
-  udp_conn->event   = recvfrom_interrupt;
+  udp_conn->event   = recvfrom_udpinterrupt;
 
   /* Enable the UDP socket */
 
@@ -549,7 +642,7 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len,
 
   conn               = (struct uip_conn *)psock->s_conn;
   conn->data_private = (void*)&state;
-  conn->data_event   = recvfrom_interrupt;
+  conn->data_event   = recvfrom_tcpinterrupt;
 
   /* Wait for either the receive to complete or for an error/timeout to occur.
    * NOTES:  (1) sem_wait will also terminate if a signal is received, (2)
diff --git a/net/send.c b/net/send.c
index 84c6757b0d51efa5ac7601ccdb44536284f4c780..98dcec35210416610984476fee7fb98ab47c8d74 100644
--- a/net/send.c
+++ b/net/send.c
@@ -89,7 +89,8 @@ struct send_s
  *
  * Parameters:
  *   dev      The sructure of the network driver that caused the interrupt
- *   private  An instance of struct send_s cast to void*
+ *   conn     The connection structure associated with the socket
+ *   flags    Set of events describing why the callback was invoked
  *
  * Returned Value:
  *   None
@@ -99,22 +100,21 @@ struct send_s
  *
  ****************************************************************************/
 
-static void send_interrupt(struct uip_driver_s *dev, void *private)
+static uint8 send_interrupt(struct uip_driver_s *dev, struct uip_conn *conn, uint8 flags)
 {
-  struct send_s *pstate = (struct send_s *)private;
-  struct uip_conn *conn;
+  struct send_s *pstate = (struct send_s *)conn->data_private;
 
-  vdbg("uip_flags: %02x state: %d\n", uip_flags, pstate->snd_state);
+  vdbg("flags: %02x state: %d\n", flags, pstate->snd_state);
 
   /* If the data has not been sent OR if it needs to be retransmitted,
    * then send it now.
    */
 
-  if (pstate->snd_state != STATE_DATA_SENT || uip_rexmit_event())
+  if (pstate->snd_state != STATE_DATA_SENT || uip_rexmit_event(flags))
     {
-      if (pstate->snd_buflen > uip_mss())
+      if (pstate->snd_buflen > uip_mss(conn))
         {
-          uip_send(dev, pstate->snd_buffer, uip_mss());
+          uip_send(dev, pstate->snd_buffer, uip_mss(conn));
         }
       else
         {
@@ -126,17 +126,17 @@ static void send_interrupt(struct uip_driver_s *dev, void *private)
 
   /* Check if all data has been sent and acknowledged */
 
-  else if (pstate->snd_state == STATE_DATA_SENT && uip_ack_event())
+  else if (pstate->snd_state == STATE_DATA_SENT && uip_ack_event(flags))
     {
       /* Yes.. the data has been sent AND acknowledged */
 
-      if (pstate->snd_buflen > uip_mss())
+      if (pstate->snd_buflen > uip_mss(conn))
         {
           /* Not all data has been sent */
 
-          pstate->snd_sent   += uip_mss();
-          pstate->snd_buflen -= uip_mss();
-          pstate->snd_buffer += uip_mss();
+          pstate->snd_sent   += uip_mss(conn);
+          pstate->snd_buflen -= uip_mss(conn);
+          pstate->snd_buffer += uip_mss(conn);
 
           /* Send again on the next poll */
 
@@ -152,7 +152,6 @@ static void send_interrupt(struct uip_driver_s *dev, void *private)
 
           /* Don't allow any further call backs. */
 
-          conn               = (struct uip_conn *)pstate->snd_sock->s_conn;
           conn->data_private = NULL;
           conn->data_event   = NULL;
 
@@ -166,11 +165,10 @@ static void send_interrupt(struct uip_driver_s *dev, void *private)
 
  /* Check for a loss of connection */
 
-  else if ((uip_flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
+  else if ((flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
     {
       /* Stop further callbacks */
 
-      conn               = (struct uip_conn *)pstate->snd_sock->s_conn;
       conn->data_private = NULL;
       conn->data_event   = NULL;
 
@@ -182,6 +180,7 @@ static void send_interrupt(struct uip_driver_s *dev, void *private)
 
       sem_post(&pstate->snd_sem);
     }
+  return 0;
 }
 
 /****************************************************************************
diff --git a/net/sendto.c b/net/sendto.c
index 0d03252f591dc3a2a7f80ea344d15f8b7e1d75e2..d18ea8e3d810f2cf410d6486517fc7dea2366c32 100644
--- a/net/sendto.c
+++ b/net/sendto.c
@@ -79,6 +79,7 @@ struct sendto_s
  * Parameters:
  *   dev      The sructure of the network driver that caused the interrupt
  *   private  An instance of struct sendto_s cast to void*
+ *   flags    Set of events describing why the callback was invoked
  *
  * Returned Value:
  *   None
@@ -89,14 +90,14 @@ struct sendto_s
  ****************************************************************************/
 
 #ifdef CONFIG_NET_UDP
-void sendto_interrupt(struct uip_driver_s *dev, void *private)
+void sendto_interrupt(struct uip_driver_s *dev, struct uip_udp_conn *conn, uint8 flags)
 {
-  struct sendto_s *pstate = (struct sendto_s *)private;
-  if (private)
+  struct sendto_s *pstate = (struct sendto_s *)conn->private;
+  if (pstate)
     {
       /* Check if the connectin was rejected */
 
-      if ((uip_flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
+      if ((flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
         {
           pstate->st_sndlen = -ENOTCONN;
         }
@@ -111,8 +112,8 @@ void sendto_interrupt(struct uip_driver_s *dev, void *private)
 
       /* Don't allow any further call backs. */
 
-      uip_udp_conn->private = NULL;
-      uip_udp_conn->event   = NULL;
+      conn->private = NULL;
+      conn->event   = NULL;
 
       /* Wake up the waiting thread */
 
diff --git a/net/uip/uip-initialize.c b/net/uip/uip-initialize.c
index 42778d2c1364427ecff11382a0dda143c43a42c3..baed0f878fcdfc14909d5d69ddc18fe89c3aabce 100644
--- a/net/uip/uip-initialize.c
+++ b/net/uip/uip-initialize.c
@@ -62,20 +62,6 @@ void *uip_urgdata;           /* urgent data (out-of-band data), if present. */
 uint16 uip_urglen;           /* Length of (received) urgent data */
 #endif
 
-/* The uip_flags variable is used for communication between the TCP/IP
- * stack and the application program.
- */
-
-uint8 uip_flags;
-
-/* uip_conn always points to the current connection. */
-
-struct uip_conn *uip_conn;
-
-#ifdef CONFIG_NET_UDP
-struct uip_udp_conn *uip_udp_conn;
-#endif   /* CONFIG_NET_UDP */
-
 #ifdef CONFIG_NET_STATISTICS
 struct uip_stats uip_stat;
 #endif
diff --git a/net/uip/uip-internal.h b/net/uip/uip-internal.h
index 4d7309f29839ddd3cff47da5802d492a17e316e8..118ccd53f009bc092e166e3d85a8b21a002bfce1 100644
--- a/net/uip/uip-internal.h
+++ b/net/uip/uip-internal.h
@@ -160,9 +160,10 @@ EXTERN void uip_tcprexmit(struct uip_driver_s *dev, struct uip_conn *conn,
 
 EXTERN void uip_tcpinput(struct uip_driver_s *dev);
 
-/* Defined in uip_uipcallback.c *********************************************/
+/* Defined in uip_tcpcallback.c *********************************************/
 
-EXTERN void uip_tcpcallback(struct uip_driver_s *dev);
+EXTERN uint8 uip_tcpcallback(struct uip_driver_s *dev,
+                             struct uip_conn *conn, uint8 flags);
 
 #ifdef CONFIG_NET_UDP
 /* Defined in uip_udpconn.c *************************************************/
@@ -185,7 +186,8 @@ EXTERN void uip_udpinput(struct uip_driver_s *dev);
 
 /* Defined in uip_uipcallback.c *********************************************/
 
-EXTERN void uip_udpcallback(struct uip_driver_s *dev);
+EXTERN void uip_udpcallback(struct uip_driver_s *dev,
+                            struct uip_udp_conn *conn, uint8 flags);
 #endif /* CONFIG_NET_UDP */
 
 /* Defined in uip-icmpinput.c ***********************************************/
diff --git a/net/uip/uip-listen.c b/net/uip/uip-listen.c
index edbb9d469d133681cc53f04963879f8267c6d7f8..f1097c40c732b1adb4bbe2fd9f66725998fd4aac 100644
--- a/net/uip/uip-listen.c
+++ b/net/uip/uip-listen.c
@@ -187,7 +187,7 @@ int uip_accept(struct uip_conn *conn, uint16 portno)
 {
   struct uip_conn *listener;
   int ret = ERROR;
-  
+
   /* The interrupt logic has already allocated and initialized a TCP
    * connection -- now check if is an application in place to accept the
    * connection.
@@ -198,7 +198,7 @@ int uip_accept(struct uip_conn *conn, uint16 portno)
     {
       /* Yes.. accept the connection */
 
-      ret = listener->accept(listener->accept_private, conn);
+      ret = listener->accept(listener, conn);
     }
    return ret;
 }
diff --git a/net/uip/uip-poll.c b/net/uip/uip-poll.c
index d80b77995aa3a8743d2d9eeeb9609731930439b6..f17f42e75a75f653fd4e9375253d47f60f3d4a1b 100644
--- a/net/uip/uip-poll.c
+++ b/net/uip/uip-poll.c
@@ -83,7 +83,6 @@ static int uip_polludpconnections(struct uip_driver_s *dev,
     {
       /* Perform the UDP TX poll */
 
-      uip_udp_conn = udp_conn;
       uip_udppoll(dev, udp_conn);
 
       /* Call back into the driver */
@@ -91,7 +90,6 @@ static int uip_polludpconnections(struct uip_driver_s *dev,
       bstop = callback(dev);
     }
 
-  uip_udp_conn = NULL;
   return bstop;
 }
 #else
@@ -122,7 +120,6 @@ static inline int uip_polltcpconnections(struct uip_driver_s *dev,
     {
       /* Perform the TCP TX poll */
 
-      uip_conn = conn;
       uip_tcppoll(dev, conn);
 
       /* Call back into the driver */
@@ -130,7 +127,6 @@ static inline int uip_polltcpconnections(struct uip_driver_s *dev,
       bstop = callback(dev);
     }
 
-  uip_conn = NULL;
   return bstop;
 }
 
@@ -159,7 +155,6 @@ static inline int uip_polltcptimer(struct uip_driver_s *dev,
     {
       /* Perform the TCP timer poll */
 
-      uip_conn = conn;
       uip_tcptimer(dev, conn, hsec);
 
       /* Call back into the driver */
@@ -167,7 +162,6 @@ static inline int uip_polltcptimer(struct uip_driver_s *dev,
       bstop = callback(dev);
     }
 
-  uip_conn = NULL;
   return bstop;
 }
 
diff --git a/net/uip/uip-tcpcallback.c b/net/uip/uip-tcpcallback.c
index ad182271240b03f8358c13bccf186bf09e98daa4..4a314e9974ce287992d44cb2c78b1cf0cfde0f48 100644
--- a/net/uip/uip-tcpcallback.c
+++ b/net/uip/uip-tcpcallback.c
@@ -73,33 +73,33 @@
  *
  ****************************************************************************/
 
-void uip_tcpcallback(struct uip_driver_s *dev)
+uint8 uip_tcpcallback(struct uip_driver_s *dev, struct uip_conn *conn, uint8 flags)
 {
-  vdbg("uip_flags: %02x\n", uip_flags);
+  uint8 ret = 0;
 
-  /* Some sanity checking */
+  vdbg("flags: %02x\n", flags);
 
-  if (uip_conn)
+  /* Check if there is a data callback */
+
+  if (conn->data_event)
     {
-      /* Check if there is a data callback */
+      /* Perform the callback */
 
-      if (uip_conn->data_event)
-      {
-        /* Perform the callback */
+      ret = conn->data_event(dev, conn, flags);
+    }
 
-        uip_conn->data_event(dev, uip_conn->data_private);
-      }
+  /* Check if there is a connection-related event and a connection
+   * callback.
+   */
 
-      /* Check if there is a connection-related event and a connection
-       * callback.
-       */
-      if (((uip_flags & UIP_CONN_EVENTS) != 0) && uip_conn->connection_event)
-        {
-          /* Perform the callback */
+  if (((flags & UIP_CONN_EVENTS) != 0) && conn->connection_event)
+    {
+      /* Perform the callback */
 
-          uip_conn->connection_event(uip_conn->connection_private);
-        }
+      conn->connection_event(conn, flags);
     }
+
+  return ret;
 }
 
 #endif /* CONFIG_NET */
diff --git a/net/uip/uip-tcpinput.c b/net/uip/uip-tcpinput.c
index 71cd54d9e13d855b055033268f8655be8ffdf84e..2ecd23d98fd85e08dacf8f2b0bad042cefd07e80 100644
--- a/net/uip/uip-tcpinput.c
+++ b/net/uip/uip-tcpinput.c
@@ -95,9 +95,11 @@
 
 void uip_tcpinput(struct uip_driver_s *dev)
 {
-  register struct uip_conn *uip_connr = uip_conn;
+  struct uip_conn *conn = NULL;
   uint16 tmp16;
   uint8  opt;
+  uint8  flags;
+  uint8  result;
   int    len;
   int    i;
 
@@ -121,8 +123,8 @@ void uip_tcpinput(struct uip_driver_s *dev)
 
   /* Demultiplex this segment. First check any active connections. */
 
-  uip_connr = uip_tcpactive(BUF);
-  if (uip_connr)
+  conn = uip_tcpactive(BUF);
+  if (conn)
     {
       goto found;
     }
@@ -135,40 +137,40 @@ void uip_tcpinput(struct uip_driver_s *dev)
 
   if ((BUF->flags & TCP_CTL) == TCP_SYN)
     {
-        /* This is a SYN packet for a connection.  Find the connection
-         * listening on this port.
-         */
+      /* This is a SYN packet for a connection.  Find the connection
+       * listening on this port.
+       */
 
-        tmp16 = BUF->destport;
-        if (uip_islistener(tmp16))
-          {
-            /* We matched the incoming packet with a connection in LISTEN.
-             * We now need to create a new connection and send a SYNACK in
-             * response.
-             */
+      tmp16 = BUF->destport;
+      if (uip_islistener(tmp16))
+        {
+          /* We matched the incoming packet with a connection in LISTEN.
+           * We now need to create a new connection and send a SYNACK in
+           * response.
+           */
 
           /* First allocate a new connection structure and see if there is any
            * user application to accept it.
            */
 
-          uip_connr = uip_tcpaccept(BUF);
-          if (uip_connr)
+          conn = uip_tcpaccept(BUF);
+          if (conn)
             {
               /* The connection structure was successfully allocated.  Now see
                * there is an application waiting to accept the connection (or at
                * least queue it it for acceptance).
                */
 
-              if (uip_accept(uip_connr, tmp16) != OK)
+              if (uip_accept(conn, tmp16) != OK)
                 {
                   /* No, then we have to give the connection back */
 
-                  uip_tcpfree(uip_connr);
-                  uip_connr = NULL;
+                  uip_tcpfree(conn);
+                  conn = NULL;
                 }
             }
 
-          if (!uip_connr)
+          if (!conn)
             {
               /* Either (1) all available connections are in use, or (2) there is no
                * application in place to accept the connection.  We drop packet and hope that
@@ -183,8 +185,7 @@ void uip_tcpinput(struct uip_driver_s *dev)
               goto drop;
             }
 
-          uip_incr32(uip_conn->rcv_nxt, 1);
-          uip_conn = uip_connr;
+          uip_incr32(conn->rcv_nxt, 1);
 
           /* Parse the TCP MSS option, if present. */
 
@@ -212,7 +213,7 @@ void uip_tcpinput(struct uip_driver_s *dev)
 
                       tmp16 = ((uint16)dev->d_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + i] << 8) |
                                (uint16)dev->d_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + i];
-                      uip_connr->initialmss = uip_connr->mss =
+                      conn->initialmss = conn->mss =
                               tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
 
                       /* And we are done processing options. */
@@ -240,8 +241,8 @@ void uip_tcpinput(struct uip_driver_s *dev)
 
           /* Our response will be a SYNACK. */
 
-          uip_tcpack(dev, uip_connr, TCP_ACK | TCP_SYN);
-          goto done;
+          uip_tcpack(dev, conn, TCP_ACK | TCP_SYN);
+          return;
         }
     }
 
@@ -260,12 +261,11 @@ void uip_tcpinput(struct uip_driver_s *dev)
   uip_stat.tcp.synrst++;
 #endif
   uip_tcpreset(dev);
-  goto done;
+  return;
 
 found:
 
-  uip_conn = uip_connr;
-  uip_flags = 0;
+  flags    = 0;
 
   /* We do a very naive form of TCP reset processing; we just accept
    * any RST and kill our connection. We should in fact check if the
@@ -275,11 +275,10 @@ found:
 
   if (BUF->flags & TCP_RST)
     {
-      uip_connr->tcpstateflags = UIP_CLOSED;
+      conn->tcpstateflags = UIP_CLOSED;
       dbg("Recvd reset - TCP state: UIP_CLOSED\n");
 
-      uip_flags = UIP_ABORT;
-      uip_tcpcallback(dev);
+      (void)uip_tcpcallback(dev, conn, UIP_ABORT);
       goto drop;
     }
 
@@ -301,17 +300,17 @@ found:
    * correct numbers in.
    */
 
-  if (!(((uip_connr->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&
+  if (!(((conn->tcpstateflags & UIP_TS_MASK) == UIP_SYN_SENT) &&
       ((BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))))
     {
       if ((dev->d_len > 0 || ((BUF->flags & (TCP_SYN | TCP_FIN)) != 0)) &&
-          (BUF->seqno[0] != uip_connr->rcv_nxt[0] ||
-           BUF->seqno[1] != uip_connr->rcv_nxt[1] ||
-           BUF->seqno[2] != uip_connr->rcv_nxt[2] ||
-           BUF->seqno[3] != uip_connr->rcv_nxt[3]))
+          (BUF->seqno[0] != conn->rcv_nxt[0] ||
+           BUF->seqno[1] != conn->rcv_nxt[1] ||
+           BUF->seqno[2] != conn->rcv_nxt[2] ||
+           BUF->seqno[3] != conn->rcv_nxt[3]))
         {
-            uip_tcpsend(dev, uip_connr, TCP_ACK, UIP_IPTCPH_LEN);
-            goto done;
+            uip_tcpsend(dev, conn, TCP_ACK, UIP_IPTCPH_LEN);
+            return;
         }
     }
 
@@ -321,61 +320,61 @@ found:
    * retransmission timer.
    */
 
-  if ((BUF->flags & TCP_ACK) && uip_outstanding(uip_connr))
+  if ((BUF->flags & TCP_ACK) && uip_outstanding(conn))
     {
       /* Temporary variables. */
 
       uint8 acc32[4];
-      uip_add32(uip_connr->snd_nxt, uip_connr->len, acc32);
+      uip_add32(conn->snd_nxt, conn->len, acc32);
 
       if (BUF->ackno[0] == acc32[0] && BUF->ackno[1] == acc32[1] &&
           BUF->ackno[2] == acc32[2] && BUF->ackno[3] == acc32[3])
         {
           /* Update sequence number. */
 
-          uip_connr->snd_nxt[0] = acc32[0];
-          uip_connr->snd_nxt[1] = acc32[1];
-          uip_connr->snd_nxt[2] = acc32[2];
-          uip_connr->snd_nxt[3] = acc32[3];
+          conn->snd_nxt[0] = acc32[0];
+          conn->snd_nxt[1] = acc32[1];
+          conn->snd_nxt[2] = acc32[2];
+          conn->snd_nxt[3] = acc32[3];
 
           /* Do RTT estimation, unless we have done retransmissions. */
 
-          if (uip_connr->nrtx == 0)
+          if (conn->nrtx == 0)
             {
               signed char m;
-              m = uip_connr->rto - uip_connr->timer;
+              m = conn->rto - conn->timer;
 
               /* This is taken directly from VJs original code in his paper */
 
-              m = m - (uip_connr->sa >> 3);
-              uip_connr->sa += m;
+              m = m - (conn->sa >> 3);
+              conn->sa += m;
               if (m < 0)
                 {
                   m = -m;
                 }
 
-              m = m - (uip_connr->sv >> 2);
-              uip_connr->sv += m;
-              uip_connr->rto = (uip_connr->sa >> 3) + uip_connr->sv;
+              m = m - (conn->sv >> 2);
+              conn->sv += m;
+              conn->rto = (conn->sa >> 3) + conn->sv;
             }
 
           /* Set the acknowledged flag. */
 
-          uip_flags = UIP_ACKDATA;
+          flags = UIP_ACKDATA;
 
           /* Reset the retransmission timer. */
 
-          uip_connr->timer = uip_connr->rto;
+          conn->timer = conn->rto;
 
           /* Reset length of outstanding data. */
 
-          uip_connr->len = 0;
+          conn->len = 0;
         }
     }
 
   /* Do different things depending on in what state the connection is. */
 
-  switch(uip_connr->tcpstateflags & UIP_TS_MASK)
+  switch (conn->tcpstateflags & UIP_TS_MASK)
     {
       /* CLOSED and LISTEN are not handled here. CLOSE_WAIT is not
        * implemented, since we force the application to close when the
@@ -390,24 +389,24 @@ found:
          * flag set. If so, we enter the ESTABLISHED state.
          */
 
-        if (uip_flags & UIP_ACKDATA)
+        if (flags & UIP_ACKDATA)
           {
-            uip_connr->tcpstateflags = UIP_ESTABLISHED;
-            uip_connr->len           = 0;
+            conn->tcpstateflags = UIP_ESTABLISHED;
+            conn->len           = 0;
             vdbg("TCP state: UIP_ESTABLISHED\n");
 
-            uip_flags                = UIP_CONNECTED;
+            flags               = UIP_CONNECTED;
 
             if (dev->d_len > 0)
               {
-                uip_flags           |= UIP_NEWDATA;
-                uip_incr32(uip_conn->rcv_nxt, dev->d_len);
+                flags          |= UIP_NEWDATA;
+                uip_incr32(conn->rcv_nxt, dev->d_len);
               }
 
-            dev->d_sndlen            = 0;
-            uip_tcpcallback(dev);
-            uip_tcpappsend(dev, uip_connr, uip_flags);
-            goto done;
+            dev->d_sndlen       = 0;
+            result              = uip_tcpcallback(dev, conn, flags);
+            uip_tcpappsend(dev, conn, result);
+            return;
           }
         goto drop;
 
@@ -418,8 +417,7 @@ found:
          * state.
          */
 
-        if ((uip_flags & UIP_ACKDATA) &&
-            (BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))
+        if ((flags & UIP_ACKDATA) && (BUF->flags & TCP_CTL) == (TCP_SYN | TCP_ACK))
           {
             /* Parse the TCP MSS option, if present. */
 
@@ -448,8 +446,8 @@ found:
                         tmp16 =
                           (dev->d_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + i] << 8) |
                           dev->d_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + i];
-                        uip_connr->initialmss =
-                          uip_connr->mss =
+                        conn->initialmss =
+                          conn->mss =
                           tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
 
                         /* And we are done processing options. */
@@ -475,31 +473,29 @@ found:
                   }
               }
 
-            uip_connr->tcpstateflags = UIP_ESTABLISHED;
-            uip_connr->rcv_nxt[0]    = BUF->seqno[0];
-            uip_connr->rcv_nxt[1]    = BUF->seqno[1];
-            uip_connr->rcv_nxt[2]    = BUF->seqno[2];
-            uip_connr->rcv_nxt[3]    = BUF->seqno[3];
+            conn->tcpstateflags = UIP_ESTABLISHED;
+            conn->rcv_nxt[0]    = BUF->seqno[0];
+            conn->rcv_nxt[1]    = BUF->seqno[1];
+            conn->rcv_nxt[2]    = BUF->seqno[2];
+            conn->rcv_nxt[3]    = BUF->seqno[3];
             vdbg("TCP state: UIP_ESTABLISHED\n");
 
-            uip_incr32(uip_conn->rcv_nxt, 1);
-            uip_flags      = UIP_CONNECTED | UIP_NEWDATA;
-            uip_connr->len = 0;
-            dev->d_len     = 0;
-            dev->d_sndlen  = 0;
-            uip_tcpcallback(dev);
-            uip_tcpappsend(dev, uip_connr, uip_flags);
-            goto done;
+            uip_incr32(conn->rcv_nxt, 1);
+            conn->len           = 0;
+            dev->d_len          = 0;
+            dev->d_sndlen       = 0;
+            result = uip_tcpcallback(dev, conn, UIP_CONNECTED | UIP_NEWDATA);
+            uip_tcpappsend(dev, conn, result);
+            return;
           }
 
         /* Inform the application that the connection failed */
 
-        uip_flags = UIP_ABORT;
-        uip_tcpcallback(dev);
+        (void)uip_tcpcallback(dev, conn, UIP_ABORT);
 
         /* The connection is closed after we send the RST */
 
-        uip_conn->tcpstateflags = UIP_CLOSED;
+        conn->tcpstateflags = UIP_CLOSED;
         vdbg("TCP state: UIP_CLOSED\n");
 
         /* We do not send resets in response to resets. */
@@ -509,7 +505,7 @@ found:
             goto drop;
           }
         uip_tcpreset(dev);
-        goto done;
+        return;
 
       case UIP_ESTABLISHED:
         /* In the ESTABLISHED state, we call upon the application to feed
@@ -524,30 +520,30 @@ found:
          * sequence numbers will be screwed up.
          */
 
-        if (BUF->flags & TCP_FIN && !(uip_connr->tcpstateflags & UIP_STOPPED))
+        if (BUF->flags & TCP_FIN && !(conn->tcpstateflags & UIP_STOPPED))
           {
-            if (uip_outstanding(uip_connr))
+            if (uip_outstanding(conn))
               {
                 goto drop;
               }
 
-            uip_incr32(uip_conn->rcv_nxt, dev->d_len + 1);
-            uip_flags |= UIP_CLOSE;
+            uip_incr32(conn->rcv_nxt, dev->d_len + 1);
+            flags |= UIP_CLOSE;
 
             if (dev->d_len > 0)
               {
-                uip_flags |= UIP_NEWDATA;
+                flags |= UIP_NEWDATA;
               }
 
-            uip_tcpcallback(dev);
+            (void)uip_tcpcallback(dev, conn, flags);
 
-            uip_connr->tcpstateflags = UIP_LAST_ACK;
-            uip_connr->len = 1;
-            uip_connr->nrtx = 0;
+            conn->tcpstateflags = UIP_LAST_ACK;
+            conn->len           = 1;
+            conn->nrtx          = 0;
             vdbg("TCP state: UIP_LAST_ACK\n");
 
-            uip_tcpsend(dev, uip_connr, TCP_FIN | TCP_ACK, UIP_IPTCPH_LEN);
-            goto done;
+            uip_tcpsend(dev, conn, TCP_FIN | TCP_ACK, UIP_IPTCPH_LEN);
+            return;
           }
 
         /* Check the URG flag. If this is set, the segment carries urgent
@@ -563,7 +559,7 @@ found:
                 uip_urglen = dev->d_len;
               }
 
-            uip_incr32(uip_conn->rcv_nxt, uip_urglen);
+            uip_incr32(conn->rcv_nxt, uip_urglen);
             dev->d_len     -= uip_urglen;
             uip_urgdata     = dev->d_appdata;
             dev->d_appdata += uip_urglen;
@@ -586,10 +582,10 @@ found:
          * remote host.
          */
 
-        if (dev->d_len > 0 && !(uip_connr->tcpstateflags & UIP_STOPPED))
+        if (dev->d_len > 0 && !(conn->tcpstateflags & UIP_STOPPED))
           {
-            uip_flags |= UIP_NEWDATA;
-            uip_incr32(uip_conn->rcv_nxt, dev->d_len);
+            flags |= UIP_NEWDATA;
+            uip_incr32(conn->rcv_nxt, dev->d_len);
           }
 
         /* Check if the available buffer space advertised by the other end
@@ -606,11 +602,11 @@ found:
          */
 
         tmp16 = ((uint16)BUF->wnd[0] << 8) + (uint16)BUF->wnd[1];
-        if (tmp16 > uip_connr->initialmss || tmp16 == 0)
+        if (tmp16 > conn->initialmss || tmp16 == 0)
           {
-            tmp16 = uip_connr->initialmss;
+            tmp16 = conn->initialmss;
           }
-        uip_connr->mss = tmp16;
+        conn->mss = tmp16;
 
         /* If this packet constitutes an ACK for outstanding data (flagged
          * by the UIP_ACKDATA flag, we should call the application since it
@@ -630,12 +626,12 @@ found:
          * send, d_len must be set to 0.
          */
 
-        if (uip_flags & (UIP_NEWDATA | UIP_ACKDATA))
+        if (flags & (UIP_NEWDATA | UIP_ACKDATA))
           {
             dev->d_sndlen = 0;
-            uip_tcpcallback(dev);
-            uip_tcpappsend(dev, uip_connr, uip_flags);
-            goto done;
+            result        = uip_tcpcallback(dev, conn, flags);
+            uip_tcpappsend(dev, conn, result);
+            return;
           }
         goto drop;
 
@@ -644,13 +640,12 @@ found:
          * FIN. This is indicated by the UIP_ACKDATA flag.
          */
 
-        if (uip_flags & UIP_ACKDATA)
+        if (flags & UIP_ACKDATA)
           {
-            uip_connr->tcpstateflags = UIP_CLOSED;
+            conn->tcpstateflags = UIP_CLOSED;
             vdbg("TCP state: UIP_CLOSED\n");
 
-            uip_flags = UIP_CLOSE;
-            uip_tcpcallback(dev);
+            (void)uip_tcpcallback(dev, conn, UIP_CLOSE);
           }
         break;
 
@@ -662,90 +657,85 @@ found:
 
         if (dev->d_len > 0)
           {
-            uip_incr32(uip_conn->rcv_nxt, dev->d_len);
+            uip_incr32(conn->rcv_nxt, dev->d_len);
           }
         if (BUF->flags & TCP_FIN)
           {
-            if (uip_flags & UIP_ACKDATA)
+            if (flags & UIP_ACKDATA)
               {
-                uip_connr->tcpstateflags = UIP_TIME_WAIT;
-                uip_connr->timer = 0;
-                uip_connr->len = 0;
+                conn->tcpstateflags = UIP_TIME_WAIT;
+                conn->timer         = 0;
+                conn->len           = 0;
                 vdbg("TCP state: UIP_TIME_WAIT\n");
               }
             else
               {
-                uip_connr->tcpstateflags = UIP_CLOSING;
+                conn->tcpstateflags = UIP_CLOSING;
                 vdbg("TCP state: UIP_CLOSING\n");
               }
 
-            uip_incr32(uip_conn->rcv_nxt, 1);
-            uip_flags = UIP_CLOSE;
-            uip_tcpcallback(dev);
-            uip_tcpsend(dev, uip_connr, TCP_ACK, UIP_IPTCPH_LEN);
-            goto done;
+            uip_incr32(conn->rcv_nxt, 1);
+            (void)uip_tcpcallback(dev, conn, UIP_CLOSE);
+            uip_tcpsend(dev, conn, TCP_ACK, UIP_IPTCPH_LEN);
+            return;
           }
-        else if (uip_flags & UIP_ACKDATA)
+        else if (flags & UIP_ACKDATA)
           {
-            uip_connr->tcpstateflags = UIP_FIN_WAIT_2;
-            uip_connr->len = 0;
+            conn->tcpstateflags = UIP_FIN_WAIT_2;
+            conn->len = 0;
             vdbg("TCP state: UIP_FIN_WAIT_2\n");
             goto drop;
           }
 
         if (dev->d_len > 0)
           {
-            uip_tcpsend(dev, uip_connr, TCP_ACK, UIP_IPTCPH_LEN);
-            goto done;
+            uip_tcpsend(dev, conn, TCP_ACK, UIP_IPTCPH_LEN);
+            return;
           }
         goto drop;
 
       case UIP_FIN_WAIT_2:
         if (dev->d_len > 0)
           {
-            uip_incr32(uip_conn->rcv_nxt, dev->d_len);
+            uip_incr32(conn->rcv_nxt, dev->d_len);
           }
 
         if (BUF->flags & TCP_FIN)
           {
-            uip_connr->tcpstateflags = UIP_TIME_WAIT;
-            uip_connr->timer = 0;
+            conn->tcpstateflags = UIP_TIME_WAIT;
+            conn->timer         = 0;
             vdbg("TCP state: UIP_TIME_WAIT\n");
 
-            uip_incr32(uip_conn->rcv_nxt, 1);
-            uip_flags = UIP_CLOSE;
-            uip_tcpcallback(dev);
-            uip_tcpsend(dev, uip_connr, TCP_ACK, UIP_IPTCPH_LEN);
-            goto done;
+            uip_incr32(conn->rcv_nxt, 1);
+            (void)uip_tcpcallback(dev, conn, UIP_CLOSE);
+            uip_tcpsend(dev, conn, TCP_ACK, UIP_IPTCPH_LEN);
+            return;
           }
 
         if (dev->d_len > 0)
           {
-            uip_tcpsend(dev, uip_connr, TCP_ACK, UIP_IPTCPH_LEN);
-            goto done;
+            uip_tcpsend(dev, conn, TCP_ACK, UIP_IPTCPH_LEN);
+            return;
           }
         goto drop;
 
       case UIP_TIME_WAIT:
-        uip_tcpsend(dev, uip_connr, TCP_ACK, UIP_IPTCPH_LEN);
-        goto done;
+        uip_tcpsend(dev, conn, TCP_ACK, UIP_IPTCPH_LEN);
+        return;
 
       case UIP_CLOSING:
-        if (uip_flags & UIP_ACKDATA)
+        if (flags & UIP_ACKDATA)
           {
-            uip_connr->tcpstateflags = UIP_TIME_WAIT;
-            uip_connr->timer = 0;
+            conn->tcpstateflags = UIP_TIME_WAIT;
+            conn->timer        = 0;
             vdbg("TCP state: UIP_TIME_WAIT\n");
           }
-    }
-  goto drop;
 
-done:
-  uip_flags = 0;
-  return;
+      default:
+        break;
+    }
 
 drop:
-  uip_flags  = 0;
   dev->d_len = 0;
 }
 
diff --git a/net/uip/uip-tcppoll.c b/net/uip/uip-tcppoll.c
index f2deac0faa22bd8582d614c1a361440550f0e3bd..9b66ef70722a159ca836c2dd3b0502035f8a99ff 100644
--- a/net/uip/uip-tcppoll.c
+++ b/net/uip/uip-tcppoll.c
@@ -94,6 +94,8 @@
 
 void uip_tcppoll(struct uip_driver_s *dev, struct uip_conn *conn)
 {
+  uint8 result;
+
   /* Verify that the connection is established and if the connection has
    * oustanding (unacknowledged) sent data.
    */
@@ -111,12 +113,11 @@ void uip_tcppoll(struct uip_driver_s *dev, struct uip_conn *conn)
 
       /* Perfom the callback */
 
-      uip_flags = UIP_POLL;
-      uip_tcpcallback(dev);
+      result = uip_tcpcallback(dev, conn, UIP_POLL);
 
       /* Handle the callback response */
 
-      uip_tcpappsend(dev, conn, uip_flags);
+      uip_tcpappsend(dev, conn, result);
     }
   else
     {
diff --git a/net/uip/uip-tcptimer.c b/net/uip/uip-tcptimer.c
index 66210e2466dc92a8cb3bf57e418cb17fa08239c7..beb16bc0f3ccf0ec951ad37c1346e6ab77064509 100644
--- a/net/uip/uip-tcptimer.c
+++ b/net/uip/uip-tcptimer.c
@@ -95,6 +95,8 @@
 
 void uip_tcptimer(struct uip_driver_s *dev, struct uip_conn *conn, int hsec)
 {
+  uint8 result;
+
   dev->d_snddata = &dev->d_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN];
   dev->d_appdata = &dev->d_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN];
 
@@ -157,13 +159,12 @@ void uip_tcptimer(struct uip_driver_s *dev, struct uip_conn *conn, int hsec)
                   conn->tcpstateflags = UIP_CLOSED;
                   vdbg("TCP state: UIP_CLOSED\n");
 
-                  /* We call uip_tcpcallback() with uip_flags set to
-                   * UIP_TIMEDOUT to inform the application that the
-                   * connection has timed out.
+                  /* We call uip_tcpcallback() with UIP_TIMEDOUT to
+                   * inform the application that the connection has
+                   * timed out.
                    */
 
-                  uip_flags = UIP_TIMEDOUT;
-                  uip_tcpcallback(dev);
+                  result = uip_tcpcallback(dev, conn, UIP_TIMEDOUT);
 
                   /* We also send a reset packet to the remote host. */
 
@@ -209,9 +210,8 @@ void uip_tcptimer(struct uip_driver_s *dev, struct uip_conn *conn, int hsec)
                      * the code for sending out the packet.
                      */
 
-                    uip_flags = UIP_REXMIT;
-                    uip_tcpcallback(dev);
-                    uip_tcprexmit(dev, conn, uip_flags);
+                    result = uip_tcpcallback(dev, conn, UIP_REXMIT);
+                    uip_tcprexmit(dev, conn, result);
                     goto done;
 
                   case UIP_FIN_WAIT_1:
@@ -233,9 +233,8 @@ void uip_tcptimer(struct uip_driver_s *dev, struct uip_conn *conn, int hsec)
            * application for new data.
            */
 
-          uip_flags = UIP_POLL;
-          uip_tcpcallback(dev);
-          uip_tcpappsend(dev, conn, uip_flags);
+          result = uip_tcpcallback(dev, conn, UIP_POLL);
+          uip_tcpappsend(dev, conn, result);
           goto done;
         }
     }
@@ -245,7 +244,6 @@ void uip_tcptimer(struct uip_driver_s *dev, struct uip_conn *conn, int hsec)
   dev->d_len = 0;
 
 done:
-  uip_flags = 0;
   return;
 }
 
diff --git a/net/uip/uip-udpcallback.c b/net/uip/uip-udpcallback.c
index ed283d19391ef5a1e9251418fae081198966ede1..29ee7d73698bde113f268db8eed467924e01e813 100644
--- a/net/uip/uip-udpcallback.c
+++ b/net/uip/uip-udpcallback.c
@@ -73,17 +73,18 @@
  *
  ****************************************************************************/
 
-void uip_udpcallback(struct uip_driver_s *dev)
+void uip_udpcallback(struct uip_driver_s *dev, struct uip_udp_conn *conn,
+                     uint8 flags)
 {
-  vdbg("uip_flags: %02x\n", uip_flags);
+  vdbg("flags: %02x\n", flags);
 
   /* Some sanity checking */
 
-  if (uip_udp_conn && uip_udp_conn->event)
+  if (conn && conn->event)
     {
       /* Perform the callback */
 
-      uip_udp_conn->event(dev, uip_udp_conn->private);
+      conn->event(dev, conn, flags);
     }
 }
 
diff --git a/net/uip/uip-udpinput.c b/net/uip/uip-udpinput.c
index 6bd347355d55195da263e162279ac123608d5c94..46e673402d1c6314764ce4543680b3c02818a84d 100644
--- a/net/uip/uip-udpinput.c
+++ b/net/uip/uip-udpinput.c
@@ -95,6 +95,8 @@
 
 void uip_udpinput(struct uip_driver_s *dev)
 {
+  struct uip_udp_conn *conn;
+
   /* UDP processing is really just a hack. We don't do anything to the UDP/IP
    * headers, but let the UDP application do all the hard work. If the
    * application sets d_sndlen, it has a packet to send.
@@ -117,31 +119,25 @@ void uip_udpinput(struct uip_driver_s *dev)
     {
       /* Demultiplex this UDP packet between the UDP "connections". */
 
-      uip_udp_conn = uip_udpactive(UDPBUF);
-      if (uip_udp_conn)
+      conn = uip_udpactive(UDPBUF);
+      if (conn)
         {
           /* Setup for the application callback */
 
-          uip_conn       = NULL;
-
           dev->d_appdata = &dev->d_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
           dev->d_snddata = &dev->d_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
           dev->d_sndlen  = 0;
 
           /* Perform the application callback */
 
-          uip_flags      = UIP_NEWDATA;
-          uip_udpcallback(dev);
-          uip_flags      = 0;
+          uip_udpcallback(dev, conn, UIP_NEWDATA);
 
           /* If the application has data to send, setup the UDP/IP header */
 
           if (dev->d_sndlen > 0)
             {
-              uip_udpsend(dev, uip_udp_conn);
+              uip_udpsend(dev, conn);
             }
-
-          uip_udp_conn = NULL;
         }
       else
         {
diff --git a/net/uip/uip-udppoll.c b/net/uip/uip-udppoll.c
index aa5a205bc8c2e1dae4fa20b0f8fab78d2bf2037e..e664fcd738e55b49782c6ff083bb514efd3f65df 100644
--- a/net/uip/uip-udppoll.c
+++ b/net/uip/uip-udppoll.c
@@ -100,9 +100,6 @@ void uip_udppoll(struct uip_driver_s *dev, struct uip_udp_conn *conn)
     {
       /* Setup for the application callback */
 
-      uip_conn       = NULL;
-      uip_udp_conn   = conn;
-
       dev->d_appdata = &dev->d_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
       dev->d_snddata = &dev->d_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN];
 
@@ -111,16 +108,13 @@ void uip_udppoll(struct uip_driver_s *dev, struct uip_udp_conn *conn)
 
       /* Perform the application callback */
 
-      uip_flags      = UIP_POLL;
-      uip_udpcallback(dev);
+      uip_udpcallback(dev, conn, UIP_POLL);
 
       /* If the application has data to send, setup the UDP/IP header */
 
       if (dev->d_sndlen > 0)
         {
           uip_udpsend(dev, conn);
-          uip_udp_conn = NULL;
-          uip_flags    = 0;
           return;
         }
     }
@@ -128,8 +122,6 @@ void uip_udppoll(struct uip_driver_s *dev, struct uip_udp_conn *conn)
   /* Make sure that d_len is zerp meaning that there is nothing to be sent */
 
   dev->d_len   = 0;
-  uip_udp_conn = NULL;
-  uip_flags    = 0;
 }
 
 #endif /* CONFIG_NET && CONFIG_NET_UDP */
diff --git a/netutils/telnetd/telnetd.c b/netutils/telnetd/telnetd.c
index 07539348496715e50f89abb84e8ff2668e7d4d7e..8efeac5cdb5e4f1ee518d99eafa860863c160aa6 100644
--- a/netutils/telnetd/telnetd.c
+++ b/netutils/telnetd/telnetd.c
@@ -138,7 +138,7 @@ static void acked(void)
     }
 }
 
-static void senddata(struct uip_driver_s *dev)
+static void senddata(struct uip_driver_s *dev, struct uip_conn *conn)
 {
   char *bufptr, *lineptr;
   int buflen, linelen;
@@ -155,7 +155,7 @@ static void senddata(struct uip_driver_s *dev)
         {
           linelen = TELNETD_CONF_LINELEN;
         }
-      if (buflen + linelen < uip_mss())
+      if (buflen + linelen < uip_mss(conn))
         {
           memcpy(bufptr, lineptr, linelen);
           bufptr += linelen;
@@ -302,11 +302,12 @@ static void newdata(struct uip_driver_s *dev)
  * event of interest occurs.
  */
 
-void uip_interrupt_event(struct uip_driver_s *dev, void *private)
+uint8 uip_interrupt_event(struct uip_driver_s *dev, struct uip_conn *conn, uint8 flags)
 {
 #warning OBSOLETE -- needs to be redesigned
   unsigned int i;
-  if (uip_connected_event())
+
+  if (uip_connected_event(flags))
     {
       for (i = 0; i < TELNETD_CONF_NUMLINES; ++i)
       {
@@ -321,28 +322,28 @@ void uip_interrupt_event(struct uip_driver_s *dev, void *private)
   if (s.state == STATE_CLOSE)
   {
     s.state = STATE_NORMAL;
-    uip_close();
-    return;
+    return UIP_CLOSE;
   }
 
-  if (uip_close_event() || uip_abort_event() || uip_timeout_event())
+  if (uip_close_event(flags) || uip_abort_event(flags) || uip_timeout_event(flags))
   {
     closed();
   }
 
-  if (uip_ack_event())
+  if (uip_ack_event(flags))
   {
     acked();
   }
 
-  if (uip_newdata_event())
+  if (uip_newdata_event(flags))
   {
     newdata(dev);
   }
 
-  if (uip_rexmit_event() || uip_newdata_event() || uip_ack_event() ||
-      uip_connected_event() || uip_poll_event())
+  if (uip_rexmit_event(flags) || uip_newdata_event(flags) || uip_ack_event(flags) ||
+      uip_connected_event(flags) || uip_poll_event(flags))
   {
-    senddata(dev);
+    senddata(dev, conn);
   }
+  return 0;
 }
diff --git a/netutils/webclient/webclient.c b/netutils/webclient/webclient.c
index f285c3f41bf60bd3ccadfa96ba37e75653279428..0c13c6c62dcbd5aa94fea618d06cef3e759721f8 100644
--- a/netutils/webclient/webclient.c
+++ b/netutils/webclient/webclient.c
@@ -78,6 +78,8 @@
 #define ISO_cr       0x0d
 #define ISO_space    0x20
 
+static uint8 g_return; /* Kludge for now */
+
 
 static struct webclient_state s;
 
@@ -180,7 +182,7 @@ static char *copy_string(char *dest, const char *src, int len)
   return dest + len;
 }
 
-static void senddata(struct uip_driver_s *dev)
+static void senddata(struct uip_driver_s *dev, struct uip_conn *conn)
 {
   uint16 len;
   char *getrequest;
@@ -203,20 +205,20 @@ static void senddata(struct uip_driver_s *dev)
     cptr = copy_string(cptr, http_user_agent_fields,
 		       strlen(http_user_agent_fields));
 
-    len = s.getrequestleft > uip_mss()?
-      uip_mss():
+    len = s.getrequestleft > uip_mss(conn)?
+      uip_mss(conn):
       s.getrequestleft;
     uip_send(dev, &(getrequest[s.getrequestptr]), len);
   }
 }
 
-static void acked(void)
+static void acked(struct uip_conn *conn)
 {
   uint16 len;
 
   if (s.getrequestleft > 0) {
-    len = s.getrequestleft > uip_mss()?
-      uip_mss():
+    len = s.getrequestleft > uip_mss(conn)?
+      uip_mss(conn):
       s.getrequestleft;
     s.getrequestleft -= len;
     s.getrequestptr += len;
@@ -262,7 +264,7 @@ static uint16 parse_statusline(struct uip_driver_s *dev, uint16 len)
             }
           else
             {
-              uip_abort();
+              g_return = UIP_ABORT;
               webclient_aborted();
               return 0;
             }
@@ -404,63 +406,63 @@ static void newdata(struct uip_driver_s *dev)
  * event of interest occurs.
  */
 
-void uip_interrupt_event(struct uip_driver_s *dev)
+uint8 uip_interrupt_event(struct uip_driver_s *dev, struct uip_conn *conn, uint8 flags)
 {
 #warning OBSOLETE -- needs to be redesigned
-  if (uip_connected_event())
+  g_return = 0;
+
+  if (uip_connected_event(flags))
     {
       s.timer = 0;
       s.state = WEBCLIENT_STATE_STATUSLINE;
-      senddata(dev);
+      senddata(dev, conn);
       webclient_connected();
-      return;
+      return g_return;
     }
 
   if (s.state == WEBCLIENT_STATE_CLOSE)
     {
       webclient_closed();
-      uip_abort();
-      return;
+      return UIP_ABORT;
     }
 
-  if (uip_abort_event())
+  if (uip_abort_event(flags))
     {
       webclient_aborted();
     }
 
-  if (uip_timeout_event())
+  if (uip_timeout_event(flags))
     {
       webclient_timedout();
     }
 
-  if (uip_ack_event())
+  if (uip_ack_event(flags))
     {
       s.timer = 0;
-      acked();
+      acked(conn);
     }
 
-  if (uip_newdata_event())
+  if (uip_newdata_event(flags))
     {
       s.timer = 0;
       newdata(dev);
     }
 
-  if (uip_rexmit_event() || uip_newdata_event() || uip_ack_event())
+  if (uip_rexmit_event(flags) || uip_newdata_event(flags) || uip_ack_event(flags))
     {
-      senddata(dev);
+      senddata(dev, conn);
     }
-  else if (uip_poll_event())
+  else if (uip_poll_event(flags))
     {
       ++s.timer;
       if (s.timer == WEBCLIENT_TIMEOUT)
         {
           webclient_timedout();
-          uip_abort();
-          return;
+          return UIP_ABORT;
         }
     }
 
-  if (uip_close_event())
+  if (uip_close_event(flags))
     {
       if (s.httpflag != HTTPFLAG_MOVED)
         {
@@ -476,9 +478,10 @@ void uip_interrupt_event(struct uip_driver_s *dev)
 #endif
           if (resolv_query(s.host, &addr) < 0)
             {
-              return;
+              return g_return;
             }
           webclient_get(s.host, s.port, s.file);
         }
     }
+  return g_return;
 }
diff --git a/netutils/webserver/httpd.c b/netutils/webserver/httpd.c
index 1f6f58df8bc2085f6c579b94cdfe9dd746844e8f..57e60f8723042c30e3e5da90ed60e7dcfb532ca3 100644
--- a/netutils/webserver/httpd.c
+++ b/netutils/webserver/httpd.c
@@ -95,7 +95,7 @@ static void next_scriptstate(struct httpd_state *pstate)
   pstate->scriptptr = p;
 }
 
-static void handle_script(struct httpd_state *pstate)
+static void handle_script(struct httpd_state *pstate, struct uip_conn *conn)
 {
   char *ptr;
 
@@ -122,8 +122,8 @@ static void handle_script(struct httpd_state *pstate)
       /* See if we find the start of script marker in the block of HTML
 	 to be sent. */
 
-      if (pstate->file.len > uip_mss()) {
-	pstate->len = uip_mss();
+      if (pstate->file.len > uip_mss(conn)) {
+	pstate->len = uip_mss(conn);
       } else {
 	pstate->len = pstate->file.len;
       }
@@ -136,8 +136,8 @@ static void handle_script(struct httpd_state *pstate)
       if (ptr != NULL &&
 	 ptr != pstate->file.data) {
 	pstate->len = (int)(ptr - pstate->file.data);
-	if (pstate->len >= uip_mss()) {
-	  pstate->len = uip_mss();
+	if (pstate->len >= uip_mss(conn)) {
+	  pstate->len = uip_mss(conn);
 	}
       }
       send_part_of_file(pstate);
@@ -186,7 +186,7 @@ static int send_headers(struct httpd_state *pstate, const char *statushdr)
   return ret;
 }
 
-static void handle_output(struct httpd_state *pstate)
+static void handle_output(struct httpd_state *pstate, struct uip_conn *conn)
 {
   char *ptr;
 
@@ -203,7 +203,7 @@ static void handle_output(struct httpd_state *pstate)
       ptr = strchr(pstate->filename, ISO_period);
       if (ptr != NULL && strncmp(ptr, http_shtml, 6) == 0)
         {
-          handle_script(pstate);
+          handle_script(pstate, conn);
         }
       else
         {
@@ -266,11 +266,11 @@ static int handle_input(struct httpd_state *pstate)
   return OK;
 }
 
-static void handle_connection(struct httpd_state *pstate)
+static void handle_connection(struct httpd_state *pstate, struct uip_conn *conn)
 {
   handle_input(pstate);
   if (pstate->state == STATE_OUTPUT) {
-    handle_output(pstate);
+    handle_output(pstate, conn);
   }
 }