net: adding a loopback interface
authorAdam Turowski <adam.turowski@inf.ethz.ch>
Fri, 14 Jul 2017 11:40:08 +0000 (13:40 +0200)
committerAdam Turowski <adam.turowski@inf.ethz.ch>
Fri, 14 Jul 2017 11:40:44 +0000 (13:40 +0200)
Signed-off-by: Adam Turowski <adam.turowski@inf.ethz.ch>

include/net/net.h
include/net_sockets/net_sockets.h
lib/barrelfish/notificator.c
lib/devif/backends/net/e1000/e1000.c
lib/lwip2/src/core/netif.c
lib/lwip2/src/sys_arch.c
lib/net/net.c
lib/net/netif.c
lib/net_sockets/net_sockets.c
usr/drivers/net_socket_server/e1000_net_sockets_server.c
usr/webserver/http_cache.c

index b4fb4a8..59a99a2 100644 (file)
@@ -155,4 +155,15 @@ errval_t networking_install_ip_filter(bool tcp, struct in_addr *src,
 errval_t networking_remove_ip_filter(bool tcp, struct in_addr *src,
                                      uint16_t src_port, uint16_t dst_port);
 
+
+/**
+ * @brief Trigger a poll of the loopback interface
+ */
+void net_if_trigger_loopback(void);
+
+/**
+ * @brief Process LWIP timeouts
+ */
+void net_lwip_timeout(void);
+
 #endif /* LIB_NET_INCLUDE_NETWORKING_H_ */
index 0b58e7b..28a1cae 100644 (file)
@@ -24,7 +24,6 @@ struct net_socket {
     struct net_socket *prev, *next;
 };
 
-// synchronous calls
 struct net_socket * net_udp_socket(void);
 struct net_socket * net_tcp_socket(void);
 void net_set_user_state(struct net_socket *socket, void *user_state);
@@ -32,7 +31,9 @@ void net_close(struct net_socket *socket);
 
 errval_t net_bind(struct net_socket *socket, struct in_addr ip_address, uint16_t port);
 errval_t net_listen(struct net_socket *socket, uint8_t backlog);
+errval_t net_print_log(void);
 
+// data must be allocated using net_alloc, it can be freed, when on_sent is called (i.e. actually sent)
 errval_t net_send(struct net_socket *socket, void *data, size_t size);
 errval_t net_send_to(struct net_socket *socket, void *data, size_t size, struct in_addr ip_address, uint16_t port);
 
index 29b51b0..0e74100 100644 (file)
@@ -79,5 +79,6 @@ void check_notificators_disabled(dispatcher_handle_t handle)
                 assert(err_is_ok(err)); // should not fail
             }
         }
+        n = n->next;
     } while (n != dp->notificators);
 }
index 5eb551c..a478fd0 100644 (file)
@@ -12,6 +12,7 @@
 #include "../../../queue_interface_internal.h"
 #include "e1000.h"
 #include <net_interfaces/flags.h>
+#include <debug_log/debug_log.h>
 
 #define DRIVER_RECEIVE_BUFFERS      (16384)
 #define DRIVER_TRANSMIT_BUFFERS     (16384)
index 428b148..37318bc 100644 (file)
@@ -1,16 +1,16 @@
 /**
  * @file
  * lwIP network interface abstraction
- * 
+ *
  * @defgroup netif Network interface (NETIF)
  * @ingroup callbackstyle_api
- * 
+ *
  * @defgroup netif_ip4 IPv4 address handling
  * @ingroup netif
- * 
+ *
  * @defgroup netif_ip6 IPv6 address handling
  * @ingroup netif
- * 
+ *
  * @defgroup netif_cd Client data handling
  * Store data (void*) on a netif for application usage.
  * @see @ref LWIP_NUM_NETIF_CLIENT_DATA
@@ -51,6 +51,7 @@
 #include "lwip/opt.h"
 
 #include <string.h>
+#include <net/net.h>
 
 #include "lwip/def.h"
 #include "lwip/ip_addr.h"
@@ -196,7 +197,7 @@ netif_init(void)
  * ethernet_input() or ip_input() depending on netif flags.
  * Don't call directly, pass to netif_add() and call
  * netif->input().
- * Only works if the netif driver correctly sets 
+ * Only works if the netif driver correctly sets
  * NETIF_FLAG_ETHARP and/or NETIF_FLAG_ETHERNET flag!
  */
 err_t
@@ -229,12 +230,12 @@ netif_input(struct pbuf *p, struct netif *inp)
  * to decide whether to forward to ethernet_input() or ip_input().
  * In other words, the functions only work when the netif
  * driver is implemented correctly!\n
- * Most members of struct netif should be be initialized by the 
+ * Most members of struct netif should be be initialized by the
  * netif init function = netif driver (init parameter of this function).\n
  * IPv6: Don't forget to call netif_create_ip6_linklocal_address() after
  * setting the MAC address in struct netif.hwaddr
  * (IPv6 requires a link-local address).
- * 
+ *
  * @return netif, or NULL if failed.
  */
 struct netif *
@@ -870,6 +871,7 @@ netif_loop_output(struct netif *netif, struct pbuf *p)
   /* For multithreading environment, schedule a call to netif_poll */
   tcpip_callback_with_block((tcpip_callback_fn)netif_poll, netif, 0);
 #endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */
+  net_if_trigger_loopback();
 
   return ERR_OK;
 }
index f6ada52..abd7df5 100644 (file)
@@ -25,7 +25,7 @@ unsigned char debug_flags;
 u32_t sys_now(void)
 {
     uint64_t ns = systime_to_ns(systime_now());
-    return ns / 1000;
+    return ns / 1000000;
 }
 
 #if 0
index d3ae9a6..d6edc0f 100644 (file)
 #include "lwip/ip.h"
 #include "lwip/dhcp.h"
 #include "lwip/prot/ethernet.h"
+#include "lwip/timeouts.h"
 
 #include <barrelfish/barrelfish.h>
 #include <barrelfish/deferred.h>
+#include <barrelfish/waitset.h>
+#include <barrelfish/waitset_chan.h>
 
 #include <net/net_filter.h>
 #include <net_interfaces/flags.h>
 #include "networking_internal.h"
 
 struct net_state state = {0};
+struct waitset_chanstate net_loopback_poll_channel;
+struct deferred_event net_lwip_timer;
 
 #define NETWORKING_DEFAULT_QUEUE_ID 0
 #define NETWORKING_BUFFER_COUNT (4096 * 3)
@@ -61,6 +66,37 @@ static void int_handler(void* args)
     struct net_state *st = devq_get_state(args);
 
     net_if_poll(&st->netif);
+    net_lwip_timeout();
+}
+
+static void net_loopback_poll(void *arg)
+{
+    netif_poll_all();
+    net_lwip_timeout();
+}
+
+void net_if_trigger_loopback(void)
+{
+    errval_t err;
+    
+    err = waitset_chan_trigger(&net_loopback_poll_channel);
+    assert(err_is_ok(err));
+}
+
+void net_lwip_timeout(void)
+{
+    errval_t err;
+
+    deferred_event_cancel(&net_lwip_timer);
+
+    sys_check_timeouts();
+
+    uint32_t delay = sys_timeouts_sleeptime();
+    if (delay != 0xffffffff) {
+        err = deferred_event_register(&net_lwip_timer, get_default_waitset(),
+            delay * 1000, MKCLOSURE((void (*)(void *))net_lwip_timeout, NULL));
+        assert(err_is_ok(err));
+    }
 }
 
 static errval_t create_loopback_queue (struct net_state *st, uint64_t* queueid,
@@ -244,6 +280,7 @@ static errval_t networking_init_with_queue_st(struct net_state *st, struct devq
         goto out_err1;
     }
 
+    deferred_event_init(&net_lwip_timer);
     /* initialize the device queue */
     NETDEBUG("initializing LWIP...\n");
     lwip_init();
@@ -308,6 +345,11 @@ static errval_t networking_init_with_queue_st(struct net_state *st, struct devq
         }
     }
 
+    waitset_chanstate_init(&net_loopback_poll_channel, CHANTYPE_OTHER);
+    net_loopback_poll_channel.persistent = true;
+    err = waitset_chan_register(get_default_waitset(), &net_loopback_poll_channel,
+                               MKCLOSURE(net_loopback_poll, NULL));
+
     NETDEBUG("initialization complete.\n");
 
     return SYS_ERR_OK;
index 08c95d6..8b7a8b0 100644 (file)
@@ -399,8 +399,6 @@ errval_t net_if_poll(struct netif *netif)
 
     errval_t err;
 
-    sys_check_timeouts();
-
     struct net_state *st = netif->state;
     if (st == NULL) {
         /* XXX: return an error code ?? */
@@ -524,10 +522,6 @@ errval_t net_if_poll(struct netif *netif)
             debug_printf("WARNING: got buffer without a flag\n");
         }
     }
-
-
-
-
     return SYS_ERR_OK;
 }
 
@@ -542,11 +536,13 @@ errval_t net_if_poll_all(void)
 
     errval_t err;
     struct netif *netif = netif_list;
-    while(netif) {
+    while (netif) {
         err = net_if_poll(netif);
         if (err_is_fail(err)) {
             DEBUG_ERR(err, "failed to poll network interface");
         }
     }
+    netif_poll_all();
+    net_lwip_timeout();
     return SYS_ERR_OK;
 }
index 9103ace..9aa8b43 100644 (file)
@@ -178,6 +178,16 @@ errval_t net_listen(struct net_socket *socket, uint8_t backlog)
     return error;
 }
 
+errval_t net_print_log(void)
+{
+    errval_t err, error;
+
+    err = binding->rpc_tx_vtbl.listen(binding, -1, 0, &error);
+    assert(err_is_ok(err));
+
+    return error;
+}
+
 void * net_alloc(size_t size)
 {
     assert(size < (BUFFER_SIZE - sizeof(struct net_buffer)));
@@ -242,7 +252,7 @@ errval_t net_send_to(struct net_socket *socket, void *data, size_t size, struct
     nb->descriptor = socket->descriptor;
     nb->host_address = ip_address;
     nb->port = port;
-    // debug_printf("%s: enqueue 2 %lx:%ld\n", __func__, buffer - buffer_start, sizeof(struct net_buffer) + size);
+    // debug_printf_to_log("%s: enqueue %ld  %lx:%ld\n", __func__, size, buffer - buffer_start, sizeof(struct net_buffer) + size);
     err = devq_enqueue((struct devq *)descq_queue, regionid, buffer - buffer_start, sizeof(struct net_buffer) + size,
                        0, 0, NET_EVENT_SEND);
     assert(err_is_ok(err));
@@ -369,6 +379,7 @@ static errval_t q_notify(struct descq* q)
                 if (socket && !socket->is_closing) {
                     if (socket->received) {
                         // debug_printf("net_received(%d): %d\n", nb->descriptor, nb->size);
+                        // debug_printf_to_log("%s: dequeue %ld  %lx:%ld\n", __func__, nb->size, offset, length);
                         socket->received(socket->user_state, socket, shb_data, nb->size, nb->host_address, nb->port);
                     // debug_printf("%s: enqueue 1< %lx:%d\n", __func__, offset, 2048);
                     }
index d5f177b..96c26b6 100644 (file)
@@ -352,6 +352,8 @@ static err_t net_tcp_accepted(void *arg, struct tcp_pcb *newpcb, err_t error)
     struct network_connection *nc = socket->connection;
     struct socket_connection *accepted_socket;
 
+    newpcb->flags |= TF_NODELAY;
+
     accepted_socket = allocate_socket(nc);
     accepted_socket->udp_socket = NULL;
     accepted_socket->tcp_socket = newpcb;
@@ -438,6 +440,7 @@ static errval_t net_tcp_socket(struct net_sockets_binding *binding, uint32_t *de
 
     struct tcp_pcb *pcb = tcp_new();
     assert(pcb);
+    pcb->flags |= TF_NODELAY;
     socket->tcp_socket = pcb;
     tcp_arg(pcb, socket);
     tcp_recv(socket->tcp_socket, net_tcp_receive);
@@ -462,8 +465,6 @@ static errval_t net_bind(struct net_sockets_binding *binding, uint32_t descripto
         assert(err_is_ok(*error));
         *bound_port = socket->udp_socket->local_port;
         *error = SYS_ERR_OK;
-
-        debug_printf("UDP ECHO bind done.\n");
     } else if (socket->tcp_socket) {
         ip_addr_t ip;
 
@@ -473,8 +474,6 @@ static errval_t net_bind(struct net_sockets_binding *binding, uint32_t descripto
         assert(err_is_ok(*error));
         *bound_port = socket->tcp_socket->local_port;
         *error = SYS_ERR_OK;
-
-        debug_printf("TCP ECHO bind done.\n");
     }
     return SYS_ERR_OK;
 }
@@ -913,7 +912,6 @@ int main(int argc, char *argv[])
 
     while(1) {
         event_dispatch(get_default_waitset());
-
         // networking_poll();
     }
 
index 64d0be9..d06dbab 100644 (file)
@@ -359,7 +359,7 @@ static void lookup_callback (void *arg, struct nfs_client *client,
         /* Set the size of the how much data is read till now. */
         e->copied = 0;
 
-        r = nfs_read (client, e->file_handle, 0, MAX_NFS_READ,
+        r = nfs_read(client, e->file_handle, 0, MAX_NFS_READ,
                 read_callback, e);
         assert (r == SYS_ERR_OK);