7 * Copyright (c) 2017, ETH Zurich.
10 * This file is distributed under the terms in the attached LICENSE file.
11 * If you do not find this file, copies can be found by writing to:
12 * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
17 #include <barrelfish/barrelfish.h>
18 #include <barrelfish/deferred.h>
19 #include <barrelfish/nameservice_client.h>
20 #include <driverkit/driverkit.h>
22 #include <arpa/inet.h>
27 #include <barrelfish/waitset_chan.h>
29 #include <octopus/octopus.h>
31 #include <devif/queue_interface.h>
32 #include <devif/backends/descq.h>
34 #include <if/net_sockets_defs.h>
35 #include <net_sockets/net_sockets_types.h>
36 #include <debug_log/debug_log.h>
41 #include <lwip/pbuf.h>
45 struct socket_connection;
47 struct network_connection {
48 struct network_connection *next;
50 struct capref buffer_cap;
57 void *buffers[NO_OF_BUFFERS];
58 uint64_t next_free, next_used;
60 struct net_sockets_binding *binding;
62 struct descq *buffer_queue;
63 struct socket_connection *sockets;
68 genoffset_t sent, length;
71 struct socket_connection {
72 struct socket_connection *next;
73 struct network_connection *connection;
75 struct send_frame send_frames[MAX_SEND_FRAMES];
77 struct udp_pcb *udp_socket;
78 struct tcp_pcb *tcp_socket;
82 struct network_connection* ns;
83 char service_name[128];
87 static struct network_connection *network_connections = NULL;
88 static struct descq *exp_queue;
90 static struct socket_connection * find_socket_connection(struct network_connection *nc, uint32_t descriptor)
92 struct socket_connection *socket;
96 if (socket->descriptor == descriptor)
98 socket = socket->next;
103 static struct socket_connection * allocate_socket(struct network_connection *nc)
105 struct socket_connection *last, *socket;
106 uint32_t last_descriptor = 0;
109 socket = nc->sockets;
111 if (socket->descriptor != last_descriptor + 1)
114 last_descriptor = last->descriptor;
115 socket = socket->next;
118 socket = malloc(sizeof(struct socket_connection));
120 memset(socket, 0, sizeof(struct socket_connection));
123 socket->next = last->next;
126 nc->sockets = socket;
129 socket->descriptor = last_descriptor + 1;
131 socket->connection = nc;
132 socket->udp_socket = NULL;
133 socket->tcp_socket = NULL;
135 memset(socket->send_frames, 0, sizeof(socket->send_frames));
140 static void net_udp_receive(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
142 struct socket_connection *connection = arg;
143 struct network_connection *nc = connection->connection;
146 assert(p->tot_len + sizeof(struct net_buffer) <= BUFFER_SIZE);
148 uint32_t length = p->tot_len;
149 void *buffer = nc->buffers[nc->next_free];
152 NET_SOCK_DEBUG("%s: drop\n", __func__);
158 nc->buffers[nc->next_free] = NULL;
159 nc->next_free = (nc->next_free + 1) % NO_OF_BUFFERS;
160 assert(sizeof(struct net_buffer) + length <= BUFFER_SIZE);
161 struct net_buffer *nb = buffer;
164 nb->descriptor = connection->descriptor;
165 nb->host_address.s_addr = addr->addr;
167 NET_SOCK_DEBUG("%s(%d): %p -> %p %p %d\n", __func__, connection->descriptor,
168 buffer, nb->user_callback, nb->user_state, nb->size);
170 void *shb_data = buffer + sizeof(struct net_buffer);
176 for (pos = 0; pos < length; ) {
178 memcpy((void *)shb_data + pos, it->payload, it->len);
183 err = devq_enqueue((struct devq *)nc->queue, nc->region_id, buffer - nc->buffer_start,
184 sizeof(struct net_buffer) + length, 0, 0, NET_EVENT_RECEIVED);
185 assert(err_is_ok(err));
186 err = devq_notify((struct devq *)nc->queue);
187 assert(err_is_ok(err));
191 static err_t net_tcp_receive(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t error)
193 struct socket_connection *socket = arg;
194 struct network_connection *nc = socket->connection;
197 void *buffer = nc->buffers[nc->next_free];
198 struct net_buffer *nb = buffer;
200 NET_SOCK_DEBUG("%s(%d): pcb:%p p:%p\n", __func__, socket->descriptor, pcb, p);
202 NET_SOCK_DEBUG("%s(%d): %d\n", __func__, socket->descriptor, p->tot_len);
203 assert(p->len == p->tot_len);
207 NET_SOCK_DEBUG("%s: drop\n", __func__);
213 nb->descriptor = socket->descriptor;
214 nb->accepted_descriptor = 0;
215 nb->host_address.s_addr = 0;
217 NET_SOCK_DEBUG("%s(%d): %p -> %d\n", __func__, socket->descriptor, buffer,
220 void *shb_data = buffer + sizeof(struct net_buffer);
221 memcpy((void *)shb_data, p->payload, length);
222 tcp_recved(pcb, p->tot_len);
227 nb->descriptor = socket->descriptor;
228 nb->accepted_descriptor = 0;
229 nb->host_address.s_addr = 0;
231 tcp_err(socket->tcp_socket, NULL);
233 nc->buffers[nc->next_free] = NULL;
234 nc->next_free = (nc->next_free + 1) % NO_OF_BUFFERS;
235 assert(sizeof(struct net_buffer) + length <= BUFFER_SIZE);
237 NET_SOCK_DEBUG("%s.%d: enqueue 1 %lx:%ld %d\n", __func__, __LINE__,
238 buffer - nc->buffer_start, sizeof(struct net_buffer) + length,
240 err = devq_enqueue((struct devq *)nc->queue, nc->region_id, buffer - nc->buffer_start,
241 sizeof(struct net_buffer) + length, 0, 0, NET_EVENT_RECEIVED);
243 assert(err_is_ok(err));
244 err = devq_notify((struct devq *)nc->queue);
245 assert(err_is_ok(err));
250 static void net_tcp_error(void *arg, err_t tcp_err)
252 struct socket_connection *socket = arg;
253 struct network_connection *nc = socket->connection;
256 NET_SOCK_DEBUG("%s(%d): error %d\n", __func__, socket->descriptor, tcp_err);
257 tcp_sent(socket->tcp_socket, NULL);
258 tcp_recv(socket->tcp_socket, NULL);
259 socket->tcp_socket = NULL; // invalidate
261 void *buffer = nc->buffers[nc->next_free];
263 struct net_buffer *nb = buffer;
265 nb->descriptor = socket->descriptor;
266 nb->accepted_descriptor = 0;
267 nb->host_address.s_addr = 0;
269 nc->buffers[nc->next_free] = NULL;
270 nc->next_free = (nc->next_free + 1) % NO_OF_BUFFERS;
272 err = devq_enqueue((struct devq *)nc->queue, nc->region_id, buffer - nc->buffer_start, sizeof(struct net_buffer),
273 0, 0, NET_EVENT_RECEIVED);
274 assert(err_is_ok(err));
276 err = devq_notify((struct devq *)nc->queue);
277 assert(err_is_ok(err));
280 static err_t net_tcp_sent(void *arg, struct tcp_pcb *pcb, uint16_t len)
282 struct socket_connection *socket = arg;
283 struct network_connection *nc = socket->connection;
288 if (!socket->send_frames[0].length)
290 assert(socket->send_frames[0].length);
291 if (len < (socket->send_frames[0].length - socket->send_frames[0].sent)) {
292 socket->send_frames[0].sent += len;
295 len -= socket->send_frames[0].length - socket->send_frames[0].sent;
297 socket->send_frames[0].length += sizeof(struct net_buffer);
298 err = devq_enqueue((struct devq *)nc->queue, nc->region_id,
299 socket->send_frames[0].offset,
300 socket->send_frames[0].length, 0, 0,
303 NET_SOCK_DEBUG("%s: err %zd\n", __func__, err);
304 assert(err_is_ok(err));
306 socket->send_frames[0] = socket->send_frames[1];
307 socket->send_frames[1].sent = 0;
308 socket->send_frames[1].length = 0;
309 socket->send_frames[1].offset = 0;
313 err = devq_notify((struct devq *)nc->queue);
314 assert(err_is_ok(err));
319 static err_t net_tcp_accepted(void *arg, struct tcp_pcb *newpcb, err_t error)
321 struct socket_connection *socket = arg;
322 struct network_connection *nc = socket->connection;
323 struct socket_connection *accepted_socket;
325 newpcb->flags |= TF_NODELAY;
327 accepted_socket = allocate_socket(nc);
328 accepted_socket->udp_socket = NULL;
329 accepted_socket->tcp_socket = newpcb;
330 tcp_arg(accepted_socket->tcp_socket, accepted_socket);
331 tcp_recv(accepted_socket->tcp_socket, net_tcp_receive);
332 tcp_err(accepted_socket->tcp_socket, net_tcp_error);
333 tcp_sent(accepted_socket->tcp_socket, net_tcp_sent);
335 NET_SOCK_DEBUG("%s(%d): -> %d\n", __func__, socket->descriptor, accepted_socket->descriptor);
339 void *buffer = nc->buffers[nc->next_free];
340 struct net_buffer *nb = buffer;
343 nb->descriptor = socket->descriptor;
344 nb->accepted_descriptor = accepted_socket->descriptor;
345 nb->host_address.s_addr = newpcb->remote_ip.addr;
346 nb->port = newpcb->remote_port;
348 nc->buffers[nc->next_free] = NULL;
349 nc->next_free = (nc->next_free + 1) % NO_OF_BUFFERS;
350 assert(sizeof(struct net_buffer) + length <= BUFFER_SIZE);
352 NET_SOCK_DEBUG("%s.%d: enqueue 1 %lx:%ld %d\n", __func__, __LINE__,
353 buffer - nc->buffer_start, sizeof(struct net_buffer) + length,
355 err = devq_enqueue((struct devq *)nc->queue, nc->region_id, buffer - nc->buffer_start,
356 sizeof(struct net_buffer) + length,
357 0, 0, NET_EVENT_ACCEPT);
358 assert(err_is_ok(err));
359 err = devq_notify((struct devq *)nc->queue);
360 assert(err_is_ok(err));
365 static errval_t net_request_descq_ep_rpc(struct net_sockets_binding *binding, uint16_t core,
369 err = slot_alloc(ep);
370 if (err_is_fail(err)) {
374 err = descq_create_ep(exp_queue, core, ep);
375 if (err_is_fail(err)) {
381 static void net_request_descq_ep(struct net_sockets_binding *binding, uint16_t core)
386 err = net_request_descq_ep_rpc(binding, core, &ep);
387 err = binding->tx_vtbl.request_descq_ep_response(binding, NOP_CONT, ep);
388 assert(err_is_ok(err));
391 static errval_t net_register_queue_rpc(struct net_sockets_binding *binding, uint64_t queue_id)
393 struct network_connection *nc;
395 nc = network_connections;
397 if (nc->queue_id == queue_id)
404 nc->binding = binding;
405 devq_set_state((struct devq *)nc->queue, nc);
410 static void net_register_queue(struct net_sockets_binding *binding, uint64_t queue_id)
413 err = net_register_queue_rpc(binding, queue_id);
414 err = binding->tx_vtbl.register_queue_response(binding, NOP_CONT);
415 assert(err_is_ok(err));
418 static errval_t net_udp_socket_rpc(struct net_sockets_binding *binding,
419 uint32_t *descriptor)
421 struct network_connection *nc;
422 struct socket_connection *socket;
425 socket = allocate_socket(nc);
426 *descriptor = socket->descriptor;
428 struct udp_pcb *pcb = udp_new();
430 socket->udp_socket = pcb;
431 udp_recv(socket->udp_socket, net_udp_receive, socket);
436 static void net_udp_socket(struct net_sockets_binding *binding)
440 err = net_udp_socket_rpc(binding, &desc);
441 err = binding->tx_vtbl.new_udp_socket_response(binding, NOP_CONT, desc);
442 assert(err_is_ok(err));
445 static errval_t net_tcp_socket_rpc(struct net_sockets_binding *binding, uint32_t *descriptor)
447 struct network_connection *nc;
448 struct socket_connection *socket;
451 socket = allocate_socket(nc);
452 *descriptor = socket->descriptor;
454 struct tcp_pcb *pcb = tcp_new();
456 pcb->flags |= TF_NODELAY;
457 socket->tcp_socket = pcb;
458 tcp_arg(pcb, socket);
459 tcp_recv(socket->tcp_socket, net_tcp_receive);
464 static void net_tcp_socket(struct net_sockets_binding *binding)
468 err = net_tcp_socket_rpc(binding, &desc);
469 err = binding->tx_vtbl.new_tcp_socket_response(binding, NOP_CONT, desc);
470 assert(err_is_ok(err));
473 static errval_t net_bind_rpc(struct net_sockets_binding *binding, uint32_t descriptor,
474 uint32_t ip_address, uint16_t port, errval_t *error,
475 uint16_t *bound_port)
477 struct network_connection *nc;
478 struct socket_connection *socket;
481 socket = find_socket_connection(nc, descriptor);
484 if (socket->udp_socket) {
487 ip.addr = ip_address;
488 *error = udp_bind(socket->udp_socket, &ip, port);
489 assert(err_is_ok(*error));
490 *bound_port = socket->udp_socket->local_port;
492 } else if (socket->tcp_socket) {
495 ip.addr = ip_address;
496 NET_SOCK_DEBUG("%s(%d): %x %d\n", __func__, socket->descriptor, ip.addr, port);
497 *error = tcp_bind(socket->tcp_socket, &ip, port);
498 assert(err_is_ok(*error));
499 *bound_port = socket->tcp_socket->local_port;
505 static void net_bind(struct net_sockets_binding *binding, uint32_t descriptor,
506 uint32_t ip_address, uint16_t port)
510 err = net_bind_rpc(binding, descriptor, ip_address , port, &err, &bound_port);
511 err = binding->tx_vtbl.bind_response(binding, NOP_CONT, err, bound_port);
512 assert(err_is_ok(err));
515 static errval_t net_listen_rpc(struct net_sockets_binding *binding,
516 uint32_t descriptor, uint8_t backlog,
519 struct network_connection *nc;
520 struct socket_connection *socket;
522 if (descriptor == -1) {
527 socket = find_socket_connection(nc, descriptor);
529 assert(socket->tcp_socket);
530 socket->tcp_socket = tcp_listen(socket->tcp_socket);
531 NET_SOCK_DEBUG("%s(%d): listen %p\n", __func__, descriptor, socket->tcp_socket);
532 tcp_accept(socket->tcp_socket, net_tcp_accepted);
533 tcp_err(socket->tcp_socket, net_tcp_error);
534 // socket->tcp_socket = tcp_listen_with_backlog(socket->tcp_socket, backlog);
535 assert(socket->tcp_socket);
541 static void net_listen(struct net_sockets_binding *binding,
542 uint32_t descriptor, uint8_t backlog)
545 err = net_listen_rpc(binding, descriptor, backlog, &err2);
546 err = binding->tx_vtbl.listen_response(binding, NOP_CONT, err2);
547 assert(err_is_ok(err));
551 static err_t net_tcp_connected(void *arg, struct tcp_pcb *tpcb, err_t error)
553 struct socket_connection *socket = arg;
554 struct network_connection *nc = socket->connection;
556 errval_t err = nc->binding->tx_vtbl.connected(nc->binding, BLOCKING_CONT, socket->descriptor, SYS_ERR_OK, tpcb->remote_ip.addr, tpcb->remote_port);
557 assert(err_is_ok(err));
562 static errval_t net_connect_rpc(struct net_sockets_binding *binding,
563 uint32_t descriptor, uint32_t ip_address,
564 uint16_t port, errval_t *error)
566 struct network_connection *nc;
567 struct socket_connection *socket;
570 socket = find_socket_connection(nc, descriptor);
573 if (socket->udp_socket) {
577 addr.addr = ip_address;
578 e = udp_connect(socket->udp_socket, &addr, port);
581 } else if (socket->tcp_socket) {
585 addr.addr = ip_address;
586 e = tcp_connect(socket->tcp_socket, &addr, port, net_tcp_connected);
594 static void net_connect(struct net_sockets_binding *binding,
595 uint32_t descriptor, uint32_t ip_address,
599 err = net_connect_rpc(binding, descriptor, ip_address, port, &err2);
600 err = binding->tx_vtbl.connect_response(binding, NOP_CONT, err2);
601 assert(err_is_ok(err));
604 static void net_delete_socket(struct network_connection *nc, uint32_t descriptor)
606 struct socket_connection *socket, *last;
609 NET_SOCK_DEBUG("%s(%d): tcp_close", __func__, descriptor);
610 socket = nc->sockets;
613 if (socket->descriptor == descriptor)
616 socket = socket->next;
621 if (socket->udp_socket) {
622 udp_recv(socket->udp_socket, NULL, NULL);
623 udp_remove(socket->udp_socket);
624 } else if (socket->tcp_socket) {
625 tcp_recv(socket->tcp_socket, NULL); // you can receive packets after you close the socket
626 tcp_sent(socket->tcp_socket, NULL);
627 // tcp_accept(socket->tcp_socket, NULL);
629 e = tcp_close(socket->tcp_socket);
633 while (socket->send_frames[0].length) { // invaldate all sent frames
635 struct net_buffer *nb;
637 socket->send_frames[0].length += sizeof(struct net_buffer);
638 buffer = socket->send_frames[0].offset + nc->buffer_start;
640 nb->descriptor = descriptor;
641 err = devq_enqueue((struct devq *)nc->queue, nc->region_id, socket->send_frames[0].offset, socket->send_frames[0].length, 0, 0, NET_EVENT_SENT);
642 assert(err_is_ok(err));
643 socket->send_frames[0] = socket->send_frames[1];
644 socket->send_frames[1].sent = 0;
645 socket->send_frames[1].length = 0;
646 socket->send_frames[1].offset = 0;
648 NET_SOCK_DEBUG("%s: %ld:%p %ld:%p\n", __func__, nc->next_free,
649 nc->buffers[nc->next_free], nc->next_used,
650 nc->buffers[nc->next_used]);
652 last->next = socket->next;
654 nc->sockets = socket->next;
658 static uint64_t qid = 1;
660 static errval_t q_create(struct descq* q, uint64_t* queue_id)
662 struct network_connection *nc;
664 nc = malloc(sizeof(struct network_connection));
666 nc->next = network_connections;
667 network_connections = nc;
673 nc->queue_id = *queue_id;
674 memset(nc->buffers, 0, sizeof(nc->buffers));
680 static errval_t q_destroy(struct descq* q)
686 static errval_t q_notify(struct descq* q)
688 struct devq* queue = (struct devq *)q;
689 errval_t err = SYS_ERR_OK;
690 //errval_t err2 = SYS_ERR_OK;
694 genoffset_t valid_data;
695 genoffset_t valid_length;
697 struct network_connection *nc;
700 nc = devq_get_state(queue);
701 for (int i = 0; i < NETSOCKET_LOOP_ITER; i++) {
702 err = devq_dequeue(queue, &rid, &offset, &length,
703 &valid_data, &valid_length, &event);
704 if (err_is_fail(err)) {
708 buffer = offset + nc->buffer_start;
709 struct net_buffer *nb = buffer;
711 NET_SOCK_DEBUG(" offset %lu length %lu \n", offset, length);
712 if (event == NET_EVENT_RECEIVE) {
713 assert(!nc->buffers[nc->next_used]);
714 nc->buffers[nc->next_used] = nc->buffer_start + offset;
715 nc->next_used = (nc->next_used + 1) % NO_OF_BUFFERS;
716 } else if (event == NET_EVENT_SEND) {
717 struct socket_connection *socket;
718 void *shb_data = (void *)buffer + sizeof(struct net_buffer);
720 NET_SOCK_DEBUG("%s: %p\n", __func__, buffer);
722 socket = find_socket_connection(nc, nb->descriptor);
724 NET_SOCK_DEBUG("%s(%d): %p\n", __func__, nb->descriptor, socket);
727 NET_SOCK_DEBUG("buffer: %d %d %x %d %p %p\n", nb->size, nb->descriptor,
728 nb->host_address, nb->port, socket->udp_socket,
730 if (socket->udp_socket) {
731 struct udp_pcb *pcb = socket->udp_socket;
734 p = pbuf_alloc(PBUF_TRANSPORT, nb->size, PBUF_RAM);
736 memcpy(p->payload, shb_data, nb->size);
741 addr.addr = nb->host_address.s_addr;
742 NET_SOCK_DEBUG("%s.%d: enqueue 2 %lx:%d\n", __func__, __LINE__, offset, nb->size);
743 err = devq_enqueue(queue, rid, offset, length, 0, 0, NET_EVENT_SENT);
744 assert(err_is_ok(err));
746 NET_SOCK_DEBUG("%s(%d): %d\n", __func__, socket->descriptor, p->tot_len);
747 if (port && addr.addr) {
750 e = udp_sendto(pcb, p, &addr, port);
752 NET_SOCK_DEBUG("%s(%d): err:%d\n", __func__, socket->descriptor, e);
757 e = udp_send(pcb, p);
759 NET_SOCK_DEBUG("%s(%d): err:%d\n", __func__, socket->descriptor, e);
763 } else if (socket->tcp_socket) {
765 NET_SOCK_DEBUG("%s: dequeue %lx:%ld %ld\n", __func__, offset, length, event);
767 if (socket->send_frames[0].length == 0) {
770 assert(socket->send_frames[1].length == 0);
772 NET_SOCK_DEBUG("%s: tcp_write %d %d\n", __func__, tcp_sndbuf(socket->tcp_socket), nb->size);
773 e = tcp_write(socket->tcp_socket, shb_data, nb->size, TCP_WRITE_FLAG_COPY);
775 NET_SOCK_DEBUG("%s: e=%d\n", __func__, e);
777 e = tcp_output(socket->tcp_socket);
780 if (socket->send_frames[0].length == 0) {
781 socket->send_frames[0].offset = offset;
782 socket->send_frames[0].length = length - sizeof(struct net_buffer);
784 socket->send_frames[1].offset = offset;
785 socket->send_frames[1].length = length - sizeof(struct net_buffer);
788 err = devq_enqueue(queue, rid, offset, length, 0, 0, NET_EVENT_SENT);
789 assert(err_is_ok(err));
792 } else if (event == NET_EVENT_CLOSE) {
793 net_delete_socket(nc, nb->descriptor);
794 err = devq_enqueue(queue, rid, offset, length, 0, 0, NET_EVENT_CLOSED);
795 assert(err_is_ok(err));
798 NET_SOCK_DEBUG("%s: unknown event %ld!", __func__, event);
805 // NET_SOCK_DEBUG("notify>\n");
806 err = devq_notify(queue);
807 // NET_SOCK_DEBUG("notify<\n");
808 assert(err_is_ok(err));
814 static errval_t q_reg(struct descq* q, struct capref cap,
817 struct frame_identity pa;
818 struct network_connection *nc;
820 nc = devq_get_state((struct devq *)q);
822 errval_t err = frame_identify(cap, &pa);
823 assert(err_is_ok(err));
824 nc->buffer_cap = cap;
827 nc->buffer_size = pa.bytes;
828 err = vspace_map_one_frame(&nc->buffer_start, pa.bytes, cap, NULL, NULL);
829 assert(err_is_ok(err));
835 static errval_t q_dereg(struct descq* q, regionid_t rid)
841 static errval_t q_control(struct descq* q, uint64_t cmd, uint64_t value, uint64_t* res)
847 static struct net_sockets_rpc_rx_vtbl rpc_rx_vtbl = {
848 .request_descq_ep_call = net_request_descq_ep_rpc,
849 .register_queue_call = net_register_queue_rpc,
850 .new_udp_socket_call = net_udp_socket_rpc,
851 .new_tcp_socket_call = net_tcp_socket_rpc,
852 .bind_call = net_bind_rpc,
853 .connect_call = net_connect_rpc,
854 .listen_call = net_listen_rpc,
857 static struct net_sockets_rx_vtbl rx_vtbl = {
858 .request_descq_ep_call = net_request_descq_ep,
859 .register_queue_call = net_register_queue,
860 .new_udp_socket_call = net_udp_socket,
861 .new_tcp_socket_call = net_tcp_socket,
862 .bind_call = net_bind,
863 .connect_call = net_connect,
864 .listen_call = net_listen,
867 static errval_t connect_cb(void *st, struct net_sockets_binding *binding)
869 binding->rx_vtbl = rx_vtbl;
870 binding->rpc_rx_vtbl = rpc_rx_vtbl;
875 static void export_cb(void *st, errval_t err, iref_t iref)
877 struct netss_state* state = (struct netss_state* ) st;
878 debug_printf("service_name %s: err %s \n", state->service_name, err_getstring(err));
879 assert(err_is_ok(err));
880 err = nameservice_register(state->service_name, iref);
881 debug_printf("nameservice register err %s \n", err_getstring(err));
882 assert(err_is_ok(err));
883 state->exported = true;
887 * Driver initialization function. This function is called by the driver domain
888 * (see also 'create_handler' in ddomain_service.c).
889 * Typically through a request from the device manager.
891 * The init function is supposed to set `dev` to the exported service iref.
892 * The init function may use `bfi->dstate` to store additional state about the device.
894 * \param[in] bfi The instance of this driver.
895 * \param[in] name The name of this driver instance.
896 * \param[in] flags Additional flags (The exact flags supported is device/driver specific).
897 * \param[in] c Capabilities (for registers etc.) as provided by the device manager.
898 * The exact layout of the `c` is device specific.
899 * \param[out] dev The service iref over which the device can be contacted.
901 * \retval SYS_ERR_OK Device initialized successfully.
902 * \retval LIB_ERR_MALLOC_FAIL Unable to allocate memory for the driver.
904 static errval_t init(struct bfdriver_instance *bfi, uint64_t flags, iref_t *dev)
906 //barrelfish_usleep(10*1000*1000);
907 NET_SOCK_DEBUG("Netsock init\n");
912 printf("%s: missing arguments! \n", bfi->argv[0]);
916 debug_printf("Net socket server started for %s.\n", bfi->argv[bfi->argc - 2]);
919 snprintf(card_name, sizeof(card_name), "%s:%s", bfi->argv[bfi->argc - 2], bfi->argv[bfi->argc - 1]);
922 char *netmask = NULL;
926 int option_index = 0;
928 static struct option long_options[] = {
929 {"ip", required_argument, 0, 1},
930 {"netmask", required_argument, 0, 2},
931 {"gw", required_argument, 0, 3},
935 c = getopt_long_only(bfi->argc, bfi->argv, "", long_options, &option_index);
955 printf("option ip [%s]\n", ip);
957 printf("option nm [%s]\n", netmask);
959 printf("option gw [%s]\n", gw);
961 if (ip) { // setting static IP, no DHCP
963 assert(err_is_ok(err));
964 err = oct_set(NET_CONFIG_STATIC_IP_RECORD_FORMAT, inet_addr(ip),
965 gw ? inet_addr(gw): 0, netmask ? inet_addr(netmask): 0);
966 assert(err_is_ok(err));
970 if (strncmp(card_name, "mlx4", 4) == 0) {
971 // MLX4 driver needs to creat argcn + copy the interrupt cap
972 // since we still use the old PCI code
973 struct capref dst_cap;
975 // TODO check if cnode already exists etc.
977 struct cnoderef argcn_ref;
978 err = cnode_create_l2(&argcn, &argcn_ref);
979 assert(err_is_ok(err));
980 err = cap_copy(cap_argcn, argcn);
981 assert(err_is_ok(err));
983 dst_cap.slot = 1; // TODO should not be hard coded
984 dst_cap.cnode = build_cnoderef(cap_argcn, CNODE_TYPE_OTHER);
986 err = cap_copy(dst_cap, bfi->caps[0]);
987 assert(err_is_ok(err));
989 /* connect to the network */
991 debug_printf("Net socket server polling \n");
993 err = networking_init_with_ep(card_name, bfi->caps[0], (!ip ? NET_FLAGS_DO_DHCP: 0)
994 | NET_FLAGS_DEFAULT_QUEUE | NET_FLAGS_BLOCKING_INIT
995 | NET_FLAGS_POLLING );
997 debug_printf("Net socket server using interrupts \n");
998 err = networking_init_with_ep(card_name, bfi->caps[0], (!ip ? NET_FLAGS_DO_DHCP: 0)
999 | NET_FLAGS_DEFAULT_QUEUE | NET_FLAGS_BLOCKING_INIT);
1001 if (err_is_fail(err)) {
1002 USER_PANIC_ERR(err, "Failed to initialize the network");
1005 struct descq_func_pointer f;
1007 f.notify = q_notify;
1008 f.create = q_create;
1009 f.destroy = q_destroy;
1012 f.control = q_control;
1014 char queue_name[128];
1015 struct netss_state* st = (struct netss_state*) malloc(sizeof(struct netss_state));
1017 sprintf(queue_name, "net_sockets_queue_%s", bfi->argv[bfi->argc - 2]);
1018 sprintf(st->service_name, "net_sockets_service_%s", bfi->argv[bfi->argc - 2]);
1020 err = descq_create(&exp_queue, DESCQ_DEFAULT_SIZE, queue_name,
1022 assert(err_is_ok(err));
1024 st->exported = false;
1026 err = net_sockets_export(st, export_cb, connect_cb, get_default_waitset(),
1027 IDC_EXPORT_FLAGS_DEFAULT);
1028 assert(err_is_ok(err));
1030 while(!st->exported) {
1031 event_dispatch(get_default_waitset());
1039 * Instructs driver to attach to the device.
1040 * This function is only called if the driver has previously detached
1041 * from the device (see also detach).
1043 * \note After detachment the driver can not assume anything about the
1044 * configuration of the device.
1046 * \param[in] bfi The instance of this driver.
1047 * \retval SYS_ERR_OK Device initialized successfully.
1049 static errval_t attach(struct bfdriver_instance* bfi) {
1054 * Instructs driver to detach from the device.
1055 * The driver must yield any control over to the device after this function returns.
1056 * The device may be left in any state.
1058 * \param[in] bfi The instance of this driver.
1059 * \retval SYS_ERR_OK Device initialized successfully.
1061 static errval_t detach(struct bfdriver_instance* bfi) {
1066 * Instructs the driver to go in a particular sleep state.
1067 * Supported states are platform/device specific.
1069 * \param[in] bfi The instance of this driver.
1070 * \retval SYS_ERR_OK Device initialized successfully.
1072 static errval_t set_sleep_level(struct bfdriver_instance* bfi, uint32_t level) {
1077 * Destroys this driver instance. The driver will yield any
1078 * control over the device and free any state allocated.
1080 * \param[in] bfi The instance of this driver.
1081 * \retval SYS_ERR_OK Device initialized successfully.
1083 static errval_t destroy(struct bfdriver_instance* bfi) {
1084 USER_PANIC("NIY \n");
1088 static errval_t get_ep(struct bfdriver_instance* bfi, bool lmp, struct capref* ret_cap)
1091 struct net_sockets_binding* b;
1092 err = net_sockets_create_endpoint(lmp? IDC_ENDPOINT_LMP: IDC_ENDPOINT_UMP,
1094 get_default_waitset(),
1095 IDC_ENDPOINT_FLAGS_DUMMY,
1101 * Registers the driver module with the system.
1103 * To link this particular module in your driver domain,
1104 * add it to the addModules list in the Hakefile.
1106 DEFINE_MODULE(net_sockets_server_module, init, attach, detach, set_sleep_level, destroy, get_ep);