Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


fixed up include directories for new interfaces locations
[palacios.releases.git] / linux_module / palacios-socket.c
1 /*
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.
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2010, Lei Xia <lxia@northwestern.edu>
11  * Copyright (c) 2010, The V3VEE Project <http://www.v3vee.org>
12  * All rights reserved.
13  *
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.
18  */
19
20 #include <interfaces/vmm_socket.h>
21
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>
27 #include <linux/ip.h>
28 #include <linux/in.h>
29 #include <linux/string.h>
30 #include <linux/preempt.h>
31 #include <linux/sched.h>
32 #include <linux/list.h>
33
34 #include "palacios.h"
35
36
37 struct palacios_socket {
38     struct socket * sock;
39     
40     struct v3_guest * guest;
41     struct list_head sock_node;
42 };
43
44 static struct list_head global_sockets;
45
46 //ignore the arguments given here currently
47 static void * 
48 palacios_tcp_socket(
49         const int bufsize,
50         const int nodelay,
51         const int nonblocking,
52         void * private_data
53 )
54 {
55     struct v3_guest * guest = (struct v3_guest *)private_data;
56     struct palacios_socket * sock = NULL;
57     int err;
58
59     sock = kmalloc(sizeof(struct palacios_socket), GFP_KERNEL);
60     memset(sock, 0, sizeof(struct palacios_socket));
61
62     err = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &(sock->sock));
63
64     if (err < 0) {
65         kfree(sock);
66         return NULL;
67     }
68        
69     sock->guest = guest;
70     
71     if (guest == NULL) {
72         list_add(&(sock->sock_node), &global_sockets);
73     } else {
74         list_add(&(sock->sock_node), &(guest->sockets));
75     }
76     
77     return sock;
78 }
79
80 //ignore the arguments given here currently
81 static void *
82 palacios_udp_socket(
83         const int bufsize,
84         const int nonblocking,
85         void * private_data
86 )
87 {
88     struct v3_guest * guest = (struct v3_guest *)private_data;
89     struct palacios_socket * sock = NULL;
90     int err;
91
92     sock = kmalloc(sizeof(struct palacios_socket), GFP_KERNEL);
93     memset(sock, 0, sizeof(struct palacios_socket));
94
95     err = sock_create(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &(sock->sock)) ;
96         
97     if (err < 0){
98         kfree(sock);
99         return NULL;
100     }
101     
102     
103     sock->guest = guest;
104     
105     if (guest == NULL) {
106         list_add(&(sock->sock_node), &global_sockets);
107     } else {
108         list_add(&(sock->sock_node), &(guest->sockets));
109     }
110
111     return sock;
112 }
113
114
115 static void 
116 palacios_close(void * sock_ptr)
117 {
118     struct palacios_socket * sock = (struct palacios_socket *)sock_ptr;
119
120     if (sock != NULL) {
121         sock->sock->ops->release(sock->sock);
122         
123         list_del(&(sock->sock_node));
124         kfree(sock);
125     }
126 }
127
128 static int 
129 palacios_bind_socket(
130         const void * sock_ptr,
131         const int port
132 )
133 {
134         struct sockaddr_in addr;
135         struct palacios_socket * sock = (struct palacios_socket *)sock_ptr;
136
137         if (sock == NULL) {
138             return -1;
139         }
140
141         addr.sin_family = AF_INET;
142         addr.sin_port = htons(port);
143         addr.sin_addr.s_addr = INADDR_ANY;
144
145         return sock->sock->ops->bind(sock->sock, (struct sockaddr *)&addr, sizeof(addr));
146 }
147
148 static int 
149 palacios_listen(
150         const void * sock_ptr,
151         int backlog
152 )
153 {
154         struct palacios_socket * sock = (struct palacios_socket *)sock_ptr;
155
156         if (sock == NULL) {
157             return -1;
158         }
159
160         return sock->sock->ops->listen(sock->sock, backlog);
161 }
162
163 static void * 
164 palacios_accept(
165         const void * sock_ptr,
166         unsigned int * remote_ip,
167         unsigned int * port
168 )
169 {
170     struct palacios_socket * sock = (struct palacios_socket *)sock_ptr;
171     struct palacios_socket * newsock = NULL;
172     int err;
173
174     if (sock == NULL) {
175         return NULL;
176     }
177     
178     newsock = kmalloc(sizeof(struct palacios_socket), GFP_KERNEL);
179
180     err = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &(newsock->sock));
181
182     if (err < 0) {
183         kfree(newsock);
184         return NULL;
185     }
186
187     newsock->sock->type = sock->sock->type;
188     newsock->sock->ops = sock->sock->ops;
189
190     err = newsock->sock->ops->accept(sock->sock, newsock->sock, 0);
191
192     if (err < 0){
193         kfree(newsock);
194         return NULL;
195     }
196
197     //TODO: How do we get ip & port?
198
199         
200     newsock->guest = sock->guest;
201     
202     if (sock->guest == NULL) {
203         list_add(&(newsock->sock_node), &global_sockets);
204     } else {
205         list_add(&(newsock->sock_node), &(sock->guest->sockets));
206     }
207
208     return newsock;
209 }
210
211 static int 
212 palacios_select(
213         struct v3_sock_set * rset,
214         struct v3_sock_set * wset,
215         struct v3_sock_set * eset,
216         struct v3_timeval tv)
217 {
218         //TODO:
219
220         return 0;
221 }
222
223 static int 
224 palacios_connect_to_ip(
225         const void * sock_ptr,
226         const int hostip,
227         const int port
228 )
229 {
230         struct sockaddr_in client;
231         struct palacios_socket * sock = (struct palacios_socket *)sock_ptr;
232
233         if (sock == NULL) {
234             return -1;
235         }
236
237         client.sin_family = AF_INET;
238         client.sin_port = htons(port);
239         client.sin_addr.s_addr = htonl(hostip);
240
241         return sock->sock->ops->connect(sock->sock, (struct sockaddr *)&client, sizeof(client), 0);
242 }
243
244 static int 
245 palacios_send(
246         const void * sock_ptr,
247         const char * buf,
248         const int len
249 )
250 {
251         struct palacios_socket * sock = (struct palacios_socket *)sock_ptr;
252         struct msghdr msg;
253         mm_segment_t oldfs;
254         struct iovec iov;
255         int err = 0;
256
257         if (sock == NULL) {
258             return -1;
259         }
260
261         msg.msg_flags = MSG_NOSIGNAL;//0/*MSG_DONTWAIT*/;;
262         msg.msg_name = 0;
263         msg.msg_namelen = 0;
264         msg.msg_control = NULL;
265         msg.msg_controllen = 0;
266         msg.msg_iov = &iov;
267         msg.msg_iovlen = 1;
268
269         iov.iov_base = (char *)buf;
270         iov.iov_len = (size_t)len;
271
272         oldfs = get_fs();
273         set_fs(KERNEL_DS);
274
275         err = sock_sendmsg(sock->sock, &msg, (size_t)len);
276
277         set_fs(oldfs);
278
279         return err;
280 }
281
282 static int 
283 palacios_recv(
284         const void * sock_ptr,
285         char * buf,
286         const int len
287 )
288 {
289
290         struct palacios_socket * sock = (struct palacios_socket *)sock_ptr;
291         struct msghdr msg;
292         mm_segment_t oldfs;
293         struct iovec iov;
294         int err;
295
296         if (sock == NULL) {
297             return -1;
298         }
299
300         msg.msg_flags = 0;
301         msg.msg_name = 0;
302         msg.msg_namelen = 0;
303         msg.msg_control = NULL;
304         msg.msg_controllen = 0;
305         msg.msg_iov = &iov;
306         msg.msg_iovlen = 1;
307
308         iov.iov_base = (void *)&buf[0];
309         iov.iov_len = (size_t)len;
310
311         oldfs = get_fs();
312         set_fs(KERNEL_DS);
313
314         err = sock_recvmsg(sock->sock, &msg, (size_t)len, 0/*MSG_DONTWAIT*/);
315
316         set_fs(oldfs);
317
318         return err;
319 }
320
321 static int 
322 palacios_sendto_ip(
323         const void * sock_ptr,
324         const int ip_addr,
325         const int port,
326         const char * buf,
327         const int len
328 )
329 {
330         struct palacios_socket * sock = (struct palacios_socket *)sock_ptr;
331         struct msghdr msg;
332         mm_segment_t oldfs;
333         struct iovec iov;
334         struct sockaddr_in dst;
335         int err = 0;
336
337         if (sock == NULL) {
338             return -1;
339         }
340
341         dst.sin_family = AF_INET;
342         dst.sin_port = htons(port);
343         dst.sin_addr.s_addr = htonl(ip_addr);
344
345         msg.msg_flags = MSG_NOSIGNAL;//0/*MSG_DONTWAIT*/;;
346         msg.msg_name = &dst;
347         msg.msg_namelen = sizeof(struct sockaddr_in);
348         msg.msg_control = NULL;
349         msg.msg_controllen = 0;
350         msg.msg_iov = &iov;
351         msg.msg_iovlen = 1;
352
353         iov.iov_base = (char *)buf;
354         iov.iov_len = (size_t)len;
355
356         oldfs = get_fs();
357         set_fs(KERNEL_DS);
358
359         err = sock_sendmsg(sock->sock, &msg, (size_t)len);
360
361         set_fs(oldfs);
362
363         return err;
364 }
365
366
367 // TODO:
368 static int 
369 palacios_recvfrom_ip(
370         const void * sock_ptr,
371         const int ip_addr,
372         const int port,
373         char * buf,
374         const int len
375 )
376 {
377         struct palacios_socket * sock = (struct palacios_socket *)sock_ptr;
378         struct sockaddr_in src;
379         int alen;
380         struct msghdr msg;
381         mm_segment_t oldfs;
382         struct iovec iov;
383         int err;
384
385         if (sock == NULL) {
386             return -1;
387         }
388
389         src.sin_family = AF_INET;
390         src.sin_port = htons(port);
391         src.sin_addr.s_addr = htonl(ip_addr);
392         alen = sizeof(src);
393
394
395         msg.msg_flags = 0;
396         msg.msg_name = &src;
397         msg.msg_namelen = sizeof(struct sockaddr_in);
398         msg.msg_control = NULL;
399         msg.msg_controllen = 0;
400         msg.msg_iov = &iov;
401         msg.msg_iovlen = 1;
402
403         iov.iov_base = (void *)&buf[0];
404         iov.iov_len = (size_t)len;
405
406         oldfs = get_fs();
407         set_fs(KERNEL_DS);
408
409         err = sock_recvmsg(sock->sock, &msg, (size_t)len, 0/*MSG_DONTWAIT*/);
410
411         set_fs(oldfs);
412
413         return err;
414 }
415
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,
428         .sendto_host = NULL,
429         .sendto_ip = palacios_sendto_ip,
430         .recvfrom_host = NULL,
431         .recvfrom_ip = palacios_recvfrom_ip,
432 };
433
434 int palacios_socket_init( void ) {
435         V3_Init_Sockets(&palacios_sock_hooks);
436         INIT_LIST_HEAD(&global_sockets);
437         return 0;
438 }