2 * This file is part of the Palacios Virtual Machine Monitor developed
3 * by the V3VEE Project with funding from the United States National
4 * Science Foundation and the Department of Energy.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2010, Lei Xia <lxia@northwestern.edu>
11 * Copyright (c) 2010, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * This is free software. You are permitted to use, redistribute,
15 * and modify it under the terms of the GNU General Public License
16 * Version 2 (GPLv2). The accompanying COPYING file contains the
17 * full text of the license.
20 #include <interfaces/vmm_socket.h>
22 #include <linux/spinlock.h>
23 #include <asm/uaccess.h>
24 #include <linux/inet.h>
25 #include <linux/kthread.h>
26 #include <linux/netdevice.h>
29 #include <linux/string.h>
30 #include <linux/preempt.h>
31 #include <linux/sched.h>
32 #include <linux/list.h>
37 struct palacios_socket {
40 struct v3_guest * guest;
41 struct list_head sock_node;
44 static struct list_head global_sockets;
46 //ignore the arguments given here currently
51 const int nonblocking,
55 struct v3_guest * guest = (struct v3_guest *)private_data;
56 struct palacios_socket * sock = NULL;
59 sock = kmalloc(sizeof(struct palacios_socket), GFP_KERNEL);
60 memset(sock, 0, sizeof(struct palacios_socket));
62 err = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &(sock->sock));
72 list_add(&(sock->sock_node), &global_sockets);
74 list_add(&(sock->sock_node), &(guest->sockets));
80 //ignore the arguments given here currently
84 const int nonblocking,
88 struct v3_guest * guest = (struct v3_guest *)private_data;
89 struct palacios_socket * sock = NULL;
92 sock = kmalloc(sizeof(struct palacios_socket), GFP_KERNEL);
93 memset(sock, 0, sizeof(struct palacios_socket));
95 err = sock_create(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &(sock->sock)) ;
106 list_add(&(sock->sock_node), &global_sockets);
108 list_add(&(sock->sock_node), &(guest->sockets));
116 palacios_close(void * sock_ptr)
118 struct palacios_socket * sock = (struct palacios_socket *)sock_ptr;
121 sock->sock->ops->release(sock->sock);
123 list_del(&(sock->sock_node));
129 palacios_bind_socket(
130 const void * sock_ptr,
134 struct sockaddr_in addr;
135 struct palacios_socket * sock = (struct palacios_socket *)sock_ptr;
141 addr.sin_family = AF_INET;
142 addr.sin_port = htons(port);
143 addr.sin_addr.s_addr = INADDR_ANY;
145 return sock->sock->ops->bind(sock->sock, (struct sockaddr *)&addr, sizeof(addr));
150 const void * sock_ptr,
154 struct palacios_socket * sock = (struct palacios_socket *)sock_ptr;
160 return sock->sock->ops->listen(sock->sock, backlog);
165 const void * sock_ptr,
166 unsigned int * remote_ip,
170 struct palacios_socket * sock = (struct palacios_socket *)sock_ptr;
171 struct palacios_socket * newsock = NULL;
178 newsock = kmalloc(sizeof(struct palacios_socket), GFP_KERNEL);
180 err = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &(newsock->sock));
187 newsock->sock->type = sock->sock->type;
188 newsock->sock->ops = sock->sock->ops;
190 err = newsock->sock->ops->accept(sock->sock, newsock->sock, 0);
197 //TODO: How do we get ip & port?
200 newsock->guest = sock->guest;
202 if (sock->guest == NULL) {
203 list_add(&(newsock->sock_node), &global_sockets);
205 list_add(&(newsock->sock_node), &(sock->guest->sockets));
213 struct v3_sock_set * rset,
214 struct v3_sock_set * wset,
215 struct v3_sock_set * eset,
216 struct v3_timeval tv)
224 palacios_connect_to_ip(
225 const void * sock_ptr,
230 struct sockaddr_in client;
231 struct palacios_socket * sock = (struct palacios_socket *)sock_ptr;
237 client.sin_family = AF_INET;
238 client.sin_port = htons(port);
239 client.sin_addr.s_addr = htonl(hostip);
241 return sock->sock->ops->connect(sock->sock, (struct sockaddr *)&client, sizeof(client), 0);
246 const void * sock_ptr,
251 struct palacios_socket * sock = (struct palacios_socket *)sock_ptr;
261 msg.msg_flags = MSG_NOSIGNAL;//0/*MSG_DONTWAIT*/;;
264 msg.msg_control = NULL;
265 msg.msg_controllen = 0;
269 iov.iov_base = (char *)buf;
270 iov.iov_len = (size_t)len;
275 err = sock_sendmsg(sock->sock, &msg, (size_t)len);
284 const void * sock_ptr,
290 struct palacios_socket * sock = (struct palacios_socket *)sock_ptr;
303 msg.msg_control = NULL;
304 msg.msg_controllen = 0;
308 iov.iov_base = (void *)&buf[0];
309 iov.iov_len = (size_t)len;
314 err = sock_recvmsg(sock->sock, &msg, (size_t)len, 0/*MSG_DONTWAIT*/);
323 const void * sock_ptr,
330 struct palacios_socket * sock = (struct palacios_socket *)sock_ptr;
334 struct sockaddr_in dst;
341 dst.sin_family = AF_INET;
342 dst.sin_port = htons(port);
343 dst.sin_addr.s_addr = htonl(ip_addr);
345 msg.msg_flags = MSG_NOSIGNAL;//0/*MSG_DONTWAIT*/;;
347 msg.msg_namelen = sizeof(struct sockaddr_in);
348 msg.msg_control = NULL;
349 msg.msg_controllen = 0;
353 iov.iov_base = (char *)buf;
354 iov.iov_len = (size_t)len;
359 err = sock_sendmsg(sock->sock, &msg, (size_t)len);
369 palacios_recvfrom_ip(
370 const void * sock_ptr,
377 struct palacios_socket * sock = (struct palacios_socket *)sock_ptr;
378 struct sockaddr_in src;
389 src.sin_family = AF_INET;
390 src.sin_port = htons(port);
391 src.sin_addr.s_addr = htonl(ip_addr);
397 msg.msg_namelen = sizeof(struct sockaddr_in);
398 msg.msg_control = NULL;
399 msg.msg_controllen = 0;
403 iov.iov_base = (void *)&buf[0];
404 iov.iov_len = (size_t)len;
409 err = sock_recvmsg(sock->sock, &msg, (size_t)len, 0/*MSG_DONTWAIT*/);
416 struct v3_socket_hooks palacios_sock_hooks = {
417 .tcp_socket = palacios_tcp_socket,
418 .udp_socket = palacios_udp_socket,
419 .close = palacios_close,
420 .bind = palacios_bind_socket,
421 .listen = palacios_listen,
422 .accept = palacios_accept,
423 .select = palacios_select,
424 .connect_to_ip = palacios_connect_to_ip,
425 .connect_to_host = NULL,
426 .send = palacios_send,
427 .recv = palacios_recv,
429 .sendto_ip = palacios_sendto_ip,
430 .recvfrom_host = NULL,
431 .recvfrom_ip = palacios_recvfrom_ip,
434 int palacios_socket_init( void ) {
435 V3_Init_Sockets(&palacios_sock_hooks);
436 INIT_LIST_HEAD(&global_sockets);
440 void palacios_socket_deinit() {
441 if (!list_empty(&(global_sockets))) {
442 printk("Error removing module with open sockets\n");