2 * Palacios Socket Interface Implementation
7 #include <interfaces/vmm_socket.h>
9 #include <linux/spinlock.h>
10 #include <asm/uaccess.h>
11 #include <linux/inet.h>
12 #include <linux/kthread.h>
13 #include <linux/netdevice.h>
16 #include <linux/string.h>
17 #include <linux/preempt.h>
18 #include <linux/sched.h>
19 #include <linux/list.h>
22 #include "linux-exts.h"
25 struct palacios_socket {
28 struct v3_guest * guest;
29 struct list_head sock_node;
32 static struct list_head global_sockets;
35 // currently just the list of created sockets
36 struct vm_socket_state {
37 struct list_head socket_list;
41 //ignore the arguments given here currently
43 palacios_tcp_socket(const int bufsize, const int nodelay,
44 const int nonblocking, void * private_data) {
45 struct v3_guest * guest = (struct v3_guest *)private_data;
46 struct palacios_socket * sock = NULL;
47 struct vm_socket_state * vm_state = NULL;
51 vm_state = get_vm_ext_data(guest, "SOCKET_INTERFACE");
53 if (vm_state == NULL) {
54 printk("ERROR: Could not locate vm socket state for extension SOCKET_INTERFACE\n");
60 sock = kmalloc(sizeof(struct palacios_socket), GFP_KERNEL);
61 memset(sock, 0, sizeof(struct palacios_socket));
63 err = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &(sock->sock));
73 list_add(&(sock->sock_node), &global_sockets);
75 list_add(&(sock->sock_node), &(vm_state->socket_list));
81 //ignore the arguments given here currently
85 const int nonblocking,
89 struct v3_guest * guest = (struct v3_guest *)private_data;
90 struct palacios_socket * sock = NULL;
91 struct vm_socket_state * vm_state = NULL;
95 vm_state = get_vm_ext_data(guest, "SOCKET_INTERFACE");
97 if (vm_state == NULL) {
98 printk("ERROR: Could not locate vm socket state for extension SOCKET_INTERFACE\n");
104 sock = kmalloc(sizeof(struct palacios_socket), GFP_KERNEL);
105 memset(sock, 0, sizeof(struct palacios_socket));
107 err = sock_create(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &(sock->sock)) ;
118 list_add(&(sock->sock_node), &global_sockets);
120 list_add(&(sock->sock_node), &(vm_state->socket_list));
128 palacios_close(void * sock_ptr)
130 struct palacios_socket * sock = (struct palacios_socket *)sock_ptr;
133 sock->sock->ops->release(sock->sock);
135 list_del(&(sock->sock_node));
141 palacios_bind_socket(
142 const void * sock_ptr,
146 struct sockaddr_in addr;
147 struct palacios_socket * sock = (struct palacios_socket *)sock_ptr;
153 addr.sin_family = AF_INET;
154 addr.sin_port = htons(port);
155 addr.sin_addr.s_addr = INADDR_ANY;
157 return sock->sock->ops->bind(sock->sock, (struct sockaddr *)&addr, sizeof(addr));
162 const void * sock_ptr,
166 struct palacios_socket * sock = (struct palacios_socket *)sock_ptr;
172 return sock->sock->ops->listen(sock->sock, backlog);
175 static void * palacios_accept(const void * sock_ptr, unsigned int * remote_ip, unsigned int * port) {
177 struct palacios_socket * sock = (struct palacios_socket *)sock_ptr;
178 struct palacios_socket * newsock = NULL;
179 struct vm_socket_state * vm_state = NULL;
186 if (sock->guest != NULL) {
187 vm_state = get_vm_ext_data(sock->guest, "SOCKET_INTERFACE");
189 if (vm_state == NULL) {
190 printk("ERROR: Could not locate vm socket state for extension SOCKET_INTERFACE\n");
196 newsock = kmalloc(sizeof(struct palacios_socket), GFP_KERNEL);
198 err = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &(newsock->sock));
205 newsock->sock->type = sock->sock->type;
206 newsock->sock->ops = sock->sock->ops;
208 err = newsock->sock->ops->accept(sock->sock, newsock->sock, 0);
215 //TODO: How do we get ip & port?
218 newsock->guest = sock->guest;
220 if (sock->guest == NULL) {
221 list_add(&(newsock->sock_node), &global_sockets);
223 list_add(&(newsock->sock_node), &(vm_state->socket_list));
231 struct v3_sock_set * rset,
232 struct v3_sock_set * wset,
233 struct v3_sock_set * eset,
234 struct v3_timeval tv)
242 palacios_connect_to_ip(
243 const void * sock_ptr,
248 struct sockaddr_in client;
249 struct palacios_socket * sock = (struct palacios_socket *)sock_ptr;
255 client.sin_family = AF_INET;
256 client.sin_port = htons(port);
257 client.sin_addr.s_addr = htonl(hostip);
259 return sock->sock->ops->connect(sock->sock, (struct sockaddr *)&client, sizeof(client), 0);
264 const void * sock_ptr,
269 struct palacios_socket * sock = (struct palacios_socket *)sock_ptr;
279 msg.msg_flags = MSG_NOSIGNAL;//0/*MSG_DONTWAIT*/;;
282 msg.msg_control = NULL;
283 msg.msg_controllen = 0;
287 iov.iov_base = (char *)buf;
288 iov.iov_len = (size_t)len;
293 err = sock_sendmsg(sock->sock, &msg, (size_t)len);
302 const void * sock_ptr,
308 struct palacios_socket * sock = (struct palacios_socket *)sock_ptr;
321 msg.msg_control = NULL;
322 msg.msg_controllen = 0;
326 iov.iov_base = (void *)&buf[0];
327 iov.iov_len = (size_t)len;
332 err = sock_recvmsg(sock->sock, &msg, (size_t)len, 0/*MSG_DONTWAIT*/);
341 const void * sock_ptr,
348 struct palacios_socket * sock = (struct palacios_socket *)sock_ptr;
352 struct sockaddr_in dst;
359 dst.sin_family = AF_INET;
360 dst.sin_port = htons(port);
361 dst.sin_addr.s_addr = htonl(ip_addr);
363 msg.msg_flags = MSG_NOSIGNAL;//0/*MSG_DONTWAIT*/;;
365 msg.msg_namelen = sizeof(struct sockaddr_in);
366 msg.msg_control = NULL;
367 msg.msg_controllen = 0;
371 iov.iov_base = (char *)buf;
372 iov.iov_len = (size_t)len;
377 err = sock_sendmsg(sock->sock, &msg, (size_t)len);
387 palacios_recvfrom_ip(
388 const void * sock_ptr,
395 struct palacios_socket * sock = (struct palacios_socket *)sock_ptr;
396 struct sockaddr_in src;
407 src.sin_family = AF_INET;
408 src.sin_port = htons(port);
409 src.sin_addr.s_addr = htonl(ip_addr);
415 msg.msg_namelen = sizeof(struct sockaddr_in);
416 msg.msg_control = NULL;
417 msg.msg_controllen = 0;
421 iov.iov_base = (void *)&buf[0];
422 iov.iov_len = (size_t)len;
427 err = sock_recvmsg(sock->sock, &msg, (size_t)len, 0/*MSG_DONTWAIT*/);
434 static struct v3_socket_hooks palacios_sock_hooks = {
435 .tcp_socket = palacios_tcp_socket,
436 .udp_socket = palacios_udp_socket,
437 .close = palacios_close,
438 .bind = palacios_bind_socket,
439 .listen = palacios_listen,
440 .accept = palacios_accept,
441 .select = palacios_select,
442 .connect_to_ip = palacios_connect_to_ip,
443 .connect_to_host = NULL,
444 .send = palacios_send,
445 .recv = palacios_recv,
447 .sendto_ip = palacios_sendto_ip,
448 .recvfrom_host = NULL,
449 .recvfrom_ip = palacios_recvfrom_ip,
452 static int socket_init( void ) {
453 V3_Init_Sockets(&palacios_sock_hooks);
454 INIT_LIST_HEAD(&global_sockets);
458 static int socket_deinit( void ) {
459 if (!list_empty(&(global_sockets))) {
460 printk("Error removing module with open sockets\n");
467 static struct linux_ext socket_ext = {
468 .name = "SOCKET_INTERFACE",
470 .deinit = socket_deinit,
475 register_extension(&socket_ext);