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.


Merge branch 'devel' of palacios@newskysaw.cs.northwestern.edu:/home/palacios/palacio...
[palacios.git] / linux_module / palacios-vnet-bridge.c
1 /* 
2    Palacios VNET Host Bridge
3    (c) Lei Xia, 2010
4  */
5 #include <linux/spinlock.h>
6 #include <linux/seq_file.h>
7 #include <linux/proc_fs.h>
8 #include <asm/uaccess.h>
9 #include <linux/inet.h>
10 #include <linux/kthread.h>
11
12 #include <linux/netdevice.h>
13 #include <linux/ip.h>
14 #include <linux/in.h>
15 #include <linux/net.h>
16 #include <linux/string.h>
17 #include <linux/preempt.h>
18 #include <linux/sched.h>
19 #include <asm/msr.h>
20
21 #include <vnet/vnet.h>
22 #include <vnet/vnet_hashtable.h>
23 #include "palacios-vnet.h"
24
25 #define VNET_SERVER_PORT 9000
26
27 struct palacios_vnet_route {
28     struct v3_vnet_route route;
29
30     int route_idx;
31
32     struct list_head node;
33 };
34
35 typedef enum {UDP, TCP, RAW, NONE} vnet_bridge_proto_t;
36
37 struct vnet_link {
38     uint32_t dst_ip;
39     uint16_t dst_port;
40     
41     struct socket * sock;
42     struct sockaddr_in sock_addr;
43     vnet_bridge_proto_t sock_proto;
44
45     unsigned int pkt_rx, pkt_tx;
46     uint64_t bytes_rx, bytes_tx;
47
48     int link_idx;
49
50     struct list_head node;
51 };
52
53
54 struct palacios_vnet_state {
55     uint32_t num_routes;
56     uint32_t num_links; 
57
58     uint8_t status;
59
60     struct list_head route_list;
61     struct list_head link_list;
62
63     struct hashtable *ip2link; /* map IP to its Link */
64
65     spinlock_t lock;
66
67     struct socket * serv_sock;
68     struct sockaddr_in serv_addr;
69     vnet_bridge_proto_t serv_proto;
70
71     /* Socket Receiving Thread */
72     struct task_struct * serv_thread;
73
74     unsigned int pkt_from_vmm, pkt_to_vmm, pkt_drop_vmm;
75     unsigned int pkt_from_phy, pkt_to_phy, pkt_drop_phy;
76 };
77
78
79 static struct palacios_vnet_state vnet_state;
80
81
82 static inline struct vnet_link * link_by_ip(uint32_t ip) {
83     return (struct vnet_link *)vnet_htable_search(vnet_state.ip2link, (addr_t)&ip);
84 }
85
86 static inline struct vnet_link * link_by_idx(int idx) {
87     struct vnet_link * link = NULL;
88
89     list_for_each_entry(link, &(vnet_state.link_list), node) {
90
91         if (link->link_idx == idx) {
92             return link;
93         }
94     }
95     return NULL;
96 }
97
98 static inline struct palacios_vnet_route * route_by_idx(int idx) {
99     struct palacios_vnet_route * route = NULL;
100
101     list_for_each_entry(route, &(vnet_state.route_list), node) {
102
103         if (route->route_idx == idx) {
104             return route;
105         }
106     }
107
108     return NULL;
109 }
110
111
112 static int parse_mac_str(char * str, uint8_t * qual, uint8_t * mac) {
113     char * token;
114
115     printk("Parsing MAC (%s)\n", str);
116         
117     *qual = MAC_NOSET;
118     if(strnicmp("any", str, strlen(str)) == 0){
119         *qual = MAC_ANY;
120         return 0;
121     }else if(strnicmp("none", str, strlen(str)) == 0){
122        *qual = MAC_NONE;
123         return 0;
124     }else{
125         if (strstr(str, "-")) {
126             token = strsep(&str, "-");
127
128             if (strnicmp("not", token, strlen("not")) == 0) {
129                 *qual = MAC_NOT;
130             } else {
131                 printk("Invalid MAC String token (%s)\n", token);
132                 return -1;
133             }
134         }
135
136         if (strstr(str, ":")) {
137             int i = 0;
138
139             if(*qual == MAC_NOSET){
140                 *qual = MAC_ADDR;
141             }
142
143             for (i = 0; i < 6; i++) {
144                 token = strsep(&str, ":");
145                 if (!token) {
146                     printk("Invalid MAC String token (%s)\n", token);
147                     return -1;
148                 }
149                 mac[i] = simple_strtol(token, &token, 16);
150             }
151            printk("MAC: %2x:%2x:%2x:%2x:%2x:%2x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
152                 
153         }else {
154             printk("Invalid MAC String token (%s)\n", token);
155             return -1;
156         }
157                 
158     }
159
160     return 0;
161 }
162
163
164 static int str2mac(char * str, uint8_t * mac){
165     int i = 0;
166     char *hex = NULL;
167         
168     for (i = 0; i < ETH_ALEN; i++) {            
169         hex = strsep(&str, ":");
170         if (!hex) {
171             printk("Invalid MAC String token (%s)\n", str);
172             return -1;
173         }
174         mac[i] = simple_strtol(hex, &hex, 16);
175     }
176         
177     return 0;
178 }
179
180
181 /* Format:
182   * add src-MAC dst-MAC dst-TYPE [dst-ID] src-TYPE [src-ID]
183   *
184   * src-MAC = dst-MAC = not-MAC|any|none|MAC 
185   * dst-TYPE = edge|interface 
186   * src-TYPE = edge|interface|any
187   * dst-ID = src-ID = IP|MAC
188   * MAC=xx:xx:xx:xx:xx:xx
189   * IP = xxx.xxx.xxx.xxx
190   */
191 static int parse_route_str(char * str, struct v3_vnet_route * route) {
192     char * token = NULL;
193     struct vnet_link *link = NULL;
194
195     // src MAC
196     token = strsep(&str, " ");
197     if (!token) {
198         return -1;
199     }
200     parse_mac_str(token, &(route->src_mac_qual), route->src_mac);
201
202     // dst MAC
203     token = strsep(&str, " ");
204     if (!token) {
205         return -1;
206     }
207     parse_mac_str(token, &(route->dst_mac_qual), route->dst_mac);
208
209     // dst LINK type
210     token = strsep(&str, " ");
211     if (!token) {
212         return -1;
213     }
214     printk("dst type =(%s)\n", token);
215     
216     if (strnicmp("interface", token, strlen("interface")) == 0) {
217         route->dst_type = LINK_INTERFACE;
218     } else if (strnicmp("edge", token, strlen("edge")) == 0) {
219         route->dst_type = LINK_EDGE;
220     } else {
221         printk("Invalid Destination Link Type (%s)\n", token);
222         return -1;
223     }
224
225     // dst link
226     token = strsep(&str, " ");
227     if (!token) {
228         return -1;
229     }
230     printk("dst ID=(%s)\n", token);
231
232     // Figure out link here
233     if (route->dst_type == LINK_EDGE) {
234         uint32_t link_ip;
235
236         // Figure out Link Here
237         if (in4_pton(token, strlen(token), (uint8_t *)&(link_ip), '\0', NULL) != 1) {
238             printk("Invalid Dst IP address (%s)\n", token);
239             return -EFAULT;
240         }
241
242         link = link_by_ip(link_ip);
243         if (link != NULL){
244             route->dst_id = link->link_idx;
245         }else{
246             printk("can not find dst link %s\n", token);
247             return -1;
248         }
249
250         printk("link_ip = %d, link_id = %d\n", link_ip, link->link_idx);        
251     } else if (route->dst_type == LINK_INTERFACE) {
252         uint8_t mac[ETH_ALEN];
253         
254        if(str2mac(token, mac) == -1){
255            printk("wrong MAC format (%s)\n", token);
256            return -1;
257        }
258            
259         route->dst_id = v3_vnet_find_dev(mac);
260         if (route->dst_id == -1){
261             printk("can not find dst device %s\n", token);
262             return -1;
263         }               
264     } else {
265         printk("Unsupported dst link type\n");
266         return -1;
267     }
268
269     route->src_id = -1;
270     route->src_type = -1;
271
272     // src LINK
273     token = strsep(&str, " ");
274
275     printk("SRC type = %s\n", token);
276
277     if (!token) {
278         return -1;
279     }
280
281     if (strnicmp("interface", token, strlen("interface")) == 0) {
282         route->src_type = LINK_INTERFACE;
283     } else if (strnicmp("edge", token, strlen("edge")) == 0) {
284         route->src_type = LINK_EDGE;
285     } else if (strnicmp("any", token, strlen("any")) == 0) {
286         route->src_type = LINK_ANY;
287     } else {
288         printk("Invalid Src link type (%s)\n", token);
289         return -1;
290     }
291
292
293     if (route->src_type == LINK_ANY) {
294         route->src_id = -1;
295     } else if (route->src_type == LINK_EDGE) {
296         uint32_t src_ip;
297         token = strsep(&str, " ");
298
299         if (!token) {
300             return -1;
301         }
302
303         // Figure out Link Here
304         if (in4_pton(token, strlen(token), (uint8_t *)&(src_ip), '\0', NULL) != 1) {
305             printk("Invalid SRC IP address (%s)\n", token);
306             return -EFAULT;
307         }
308
309         link = link_by_ip(src_ip);
310         if (link != NULL){
311             route->src_id = link->link_idx;
312         }else{
313             printk("can not find src link %s\n", token);
314             return -1;
315         }
316     } else if(route->src_type == LINK_INTERFACE){
317        uint8_t mac[ETH_ALEN];
318         
319        if(str2mac(token, mac) == -1){
320            printk("wrong MAC format (%s)\n", token);
321            return -1;
322        }
323            
324         route->src_id = v3_vnet_find_dev(mac);
325         if (route->src_id == -1){
326             printk("can not find dst device %s\n", token);
327             return -1;
328         }               
329     } else {
330         printk("Invalid link type\n");
331         return -1;
332     }
333
334     return 0;
335 }
336
337
338
339
340 static void * route_seq_start(struct seq_file * s, loff_t * pos) {
341     struct palacios_vnet_route * route_iter = NULL;
342     loff_t i = 0;
343
344
345     if (*pos >= vnet_state.num_routes) {
346         return NULL;
347     }
348
349     list_for_each_entry(route_iter, &(vnet_state.route_list), node) {
350
351         if (i == *pos) {
352             break;
353         }
354
355         i++;
356     }
357
358     return route_iter;
359 }
360
361
362 static void * link_seq_start(struct seq_file * s, loff_t * pos) {
363     struct vnet_link * link_iter = NULL;
364     loff_t i = 0;
365
366     if (*pos >= vnet_state.num_links) {
367         return NULL;
368     }
369
370     list_for_each_entry(link_iter, &(vnet_state.link_list), node) {
371
372         if (i == *pos) {
373             break;
374         }
375
376         i++;
377     }
378
379     return link_iter;
380 }
381
382
383
384 static void * route_seq_next(struct seq_file * s, void * v, loff_t * pos) {
385     struct palacios_vnet_route * route_iter = NULL;
386
387     route_iter = list_entry(((struct palacios_vnet_route *)v)->node.next, struct palacios_vnet_route, node);
388
389     // Check if the list has looped
390     if (&(route_iter->node) == &(vnet_state.route_list)) {
391         return NULL;
392     }
393
394     *pos += 1;
395
396     return route_iter;
397 }
398
399
400 static void * link_seq_next(struct seq_file * s, void * v, loff_t * pos) {
401     struct vnet_link * link_iter = NULL;
402
403  
404     link_iter = list_entry(((struct vnet_link *)v)->node.next, struct vnet_link, node);
405
406     // Check if the list has looped
407     if (&(link_iter->node) == &(vnet_state.link_list)) {
408         return NULL;
409     }
410
411     *pos += 1;
412
413     return link_iter;
414 }
415
416
417 static void route_seq_stop(struct seq_file * s, void * v) {
418
419     return;
420 }
421
422
423 static void link_seq_stop(struct seq_file * s, void * v) {
424
425     return;
426 }
427
428 static int route_seq_show(struct seq_file * s, void * v) {
429     struct palacios_vnet_route * route_iter = v;
430     struct v3_vnet_route * route = &(route_iter->route);
431
432     seq_printf(s, "%d:\t", route_iter->route_idx);
433
434     seq_printf(s, "\nSrc:\t");
435     switch (route->src_mac_qual) {
436         case MAC_ANY:
437             seq_printf(s, "any ");
438             break;
439         case MAC_NONE:
440             seq_printf(s, "none ");
441             break;
442         case MAC_NOT:
443             seq_printf(s, "not-%2x:%2x:%2x:%2x:%2x:%2x ", 
444                        route->src_mac[0], route->src_mac[1], route->src_mac[2],
445                        route->src_mac[3], route->src_mac[4], route->src_mac[5]);
446             break;
447         default:
448             seq_printf(s, "%x:%x:%x:%x:%x:%x ", 
449                        route->src_mac[0], route->src_mac[1], route->src_mac[2],
450                        route->src_mac[3], route->src_mac[4], route->src_mac[5]);
451             break;
452     }
453
454     seq_printf(s, "\nDst:\t");
455     switch (route->dst_mac_qual) {
456         case MAC_ANY:
457             seq_printf(s, "any ");
458             break;
459         case MAC_NONE:
460             seq_printf(s, "none ");
461             break;
462         case MAC_NOT:
463             seq_printf(s, "not-%x:%x:%x:%x:%x:%x ", 
464                        route->src_mac[0], route->src_mac[1], route->src_mac[2],
465                        route->src_mac[3], route->src_mac[4], route->src_mac[5]);
466             break;
467         default:
468             seq_printf(s, "%x:%x:%x:%x:%x:%x ", 
469                        route->src_mac[0], route->src_mac[1], route->src_mac[2],
470                        route->src_mac[3], route->src_mac[4], route->src_mac[5]);
471             break;
472     }
473
474     seq_printf(s, "\nDst-Type:\t");
475     switch (route->dst_type) {
476         case LINK_EDGE: {
477             struct vnet_link * link = (struct vnet_link *)link_by_idx(route->dst_id);
478             seq_printf(s, "EDGE %pI4", &link->dst_ip);
479             break;
480         }
481         case LINK_INTERFACE: {
482             seq_printf(s, "INTERFACE ");
483             seq_printf(s, "%d ", route->dst_id);
484             break;
485         }
486         default:
487             seq_printf(s, "Invalid Dst Link Type (%d) ", route->dst_type);
488             break;
489     }
490
491     seq_printf(s, "\nSrc-Type:\t");
492     switch (route->src_type) {
493         case LINK_EDGE: {
494             struct vnet_link * link = (struct vnet_link *)link_by_idx(route->src_id);
495             seq_printf(s, "EDGE %pI4", &link->dst_ip);
496             break;
497         }
498         case LINK_INTERFACE: {
499             seq_printf(s, "INTERFACE %d", route->src_id);
500             break;
501         }
502         case LINK_ANY:
503             seq_printf(s, "ANY");
504             break;
505         default:
506             seq_printf(s, "Invalid Src Link Type (%d) ", route->src_type);
507             break;
508     }
509
510
511     seq_printf(s, "\n");
512
513     return 0;
514 }
515
516
517 static int link_seq_show(struct seq_file * s, void * v) {
518     struct vnet_link * link_iter = v;
519
520     seq_printf(s, "%d:\t%pI4\t%d\n\t\tReceived Pkts: %d, Received Bytes %lld\n\t\tSent Pkts: %d, Sent Bytes: %lld\n\n", 
521                link_iter->link_idx,
522                &link_iter->dst_ip,
523                link_iter->dst_port,
524                link_iter->pkt_rx,
525                link_iter->bytes_rx,
526                link_iter->pkt_tx,
527                link_iter->bytes_tx);
528
529     return 0;
530 }
531
532
533 static struct seq_operations route_seq_ops = {
534     .start = route_seq_start, 
535     .next = route_seq_next,
536     .stop = route_seq_stop,
537     .show = route_seq_show
538 };
539
540
541 static struct seq_operations link_seq_ops = {
542     .start = link_seq_start,
543     .next = link_seq_next,
544     .stop = link_seq_stop,
545     .show = link_seq_show
546 };
547
548
549 static int route_open(struct inode * inode, struct file * file) {
550     return seq_open(file, &route_seq_ops);
551 }
552
553
554 static int link_open(struct inode * inode, struct file * file) {
555     return seq_open(file, &link_seq_ops);
556 }
557
558 static int inject_route(struct palacios_vnet_route * route) {
559     unsigned long flags;
560
561     v3_vnet_add_route(route->route);
562
563     spin_lock_irqsave(&(vnet_state.lock), flags);
564     list_add(&(route->node), &(vnet_state.route_list));
565     route->route_idx = vnet_state.num_routes++;
566     spin_unlock_irqrestore(&(vnet_state.lock), flags);
567
568     printk("Palacios-vnet: One route added to VNET core\n");
569
570     return 0;
571 }
572
573 static ssize_t 
574 route_write(struct file * file, 
575             const char * buf, 
576             size_t size, 
577             loff_t * ppos) {
578     char route_buf[256];
579     char * buf_iter = NULL;
580     char * line_str = route_buf;
581     char * token = NULL;
582
583     if (size >= 256) {
584         return -EFAULT;
585     }
586
587     if (copy_from_user(route_buf, buf, size)) {
588         return -EFAULT;
589     }
590
591     route_buf[size] = '\0';
592     printk("Route written: %s\n", route_buf);
593
594     while ((buf_iter = strsep(&line_str, "\r\n"))) {
595
596         token = strsep(&buf_iter, " ");
597         if (!token) {
598             return -EFAULT;
599         }
600         
601         if (strnicmp("ADD", token, strlen("ADD")) == 0) {
602             struct palacios_vnet_route * new_route = NULL;
603             new_route = kmalloc(sizeof(struct palacios_vnet_route), GFP_KERNEL);
604             
605             if (!new_route) {
606                 return -ENOMEM;
607             }
608             
609             memset(new_route, 0, sizeof(struct palacios_vnet_route));
610             
611             if (parse_route_str(buf_iter, &(new_route->route)) == -1) {
612                 kfree(new_route);
613                 return -EFAULT;
614             }
615             
616             if (inject_route(new_route) != 0) {
617                 return -EFAULT;
618             }
619         } else if (strnicmp("DEL", token, strlen("DEL")) == 0) {
620             printk("I should delete the route here\n");
621         } else {
622             printk("Invalid Route command string\n");
623         }
624     }
625
626     return size;
627 }
628
629 static int create_link(struct vnet_link * link) {
630     int err;
631     unsigned long flags;
632     int protocol;
633
634     switch(link->sock_proto){
635         case UDP:
636             protocol = IPPROTO_UDP;
637             break;
638         case TCP:
639             protocol = IPPROTO_TCP;
640             break;
641
642         default:
643            printk("Unsupported VNET Server Protocol\n");
644             return -1;
645     }
646    
647     if ((err = sock_create(AF_INET, SOCK_DGRAM, protocol, &link->sock)) < 0) {
648         printk("Could not create socket for VNET Link, error %d\n", err);
649         return -1;
650     }
651
652     memset(&link->sock_addr, 0, sizeof(struct sockaddr));
653
654     link->sock_addr.sin_family = AF_INET;
655     link->sock_addr.sin_addr.s_addr = link->dst_ip;
656     link->sock_addr.sin_port = htons(link->dst_port);
657
658     if ((err = link->sock->ops->connect(link->sock, (struct sockaddr *)&(link->sock_addr), sizeof(struct sockaddr), 0) < 0)) {
659         printk("Could not connect to remote VNET Server, error %d\n", err);
660         return -1;
661     }
662
663     // We use the file pointer because we are in the kernel
664     // This is only used to assigned File Descriptors for user space, so it is available here
665     // link->sock->file = link;
666
667     spin_lock_irqsave(&(vnet_state.lock), flags);
668     list_add(&(link->node), &(vnet_state.link_list));
669     link->link_idx = vnet_state.num_links++;
670     vnet_htable_insert(vnet_state.ip2link, (addr_t)&(link->dst_ip), (addr_t)link);
671     spin_unlock_irqrestore(&(vnet_state.lock), flags);
672
673     printk("VNET Bridge: Link created, ip 0x%x, port: %d, idx: %d, link: %p, protocol: %s\n", 
674            link->dst_ip, 
675            link->dst_port, 
676            link->link_idx, 
677            link,
678            ((link->sock_proto==UDP)?"UDP":"TCP"));
679
680     return 0;
681 }
682
683
684 /* ADD dst-ip 9000 [udp|tcp] */
685 static ssize_t 
686 link_write(struct file * file, const char * buf, size_t size, loff_t * ppos) {
687     char link_buf[256];
688     char * link_iter = NULL;
689     char * line_str = link_buf;
690     char * token = NULL;
691
692     if (size >= 256) {
693         return -EFAULT;
694     }
695
696     if (copy_from_user(link_buf, buf, size)) {
697         return -EFAULT;
698     }
699
700     while ((link_iter = strsep(&line_str, "\r\n"))) {
701         printk("Link written: %s\n", link_buf);
702         
703         token = strsep(&link_iter, " ");
704         
705         if (!token) {
706             return -EFAULT;
707         }
708         
709         if (strnicmp("ADD", token, strlen("ADD")) == 0) {
710             struct vnet_link * new_link = NULL;
711             char * ip_str = NULL;
712             uint32_t ip;
713             
714             ip_str = strsep(&link_iter, " ");
715             
716             if ((!ip_str) || (!link_iter)) {
717                 printk("Missing fields in ADD Link command\n");
718                 return -EFAULT;
719             }
720             
721             if (in4_pton(ip_str, strlen(ip_str), (uint8_t *)&(ip), '\0', NULL) != 1) {
722                 printk("Invalid Dst IP address (%s)\n", ip_str);
723                 return -EFAULT;
724             }
725
726             new_link = kmalloc(sizeof(struct vnet_link), GFP_KERNEL);
727             if (!new_link) {
728                 return -ENOMEM;
729             }
730         
731             memset(new_link, 0, sizeof(struct vnet_link));
732
733             new_link->dst_ip = ip;
734             new_link->dst_port = simple_strtol(link_iter, &link_iter, 10);
735
736             //TODO: Parse UDP|TCP
737             new_link->sock_proto = UDP;
738             
739             if (create_link(new_link) != 0) {
740                 printk("Could not create link\n");
741                 kfree(new_link);
742                 return -EFAULT;
743             }
744
745         } else if (strnicmp("DEL", token, strlen("DEL")) == 0) {
746             printk("Link deletion not supported\n");
747         } else {
748             printk("Invalid Link command string\n");
749         }
750     }
751
752     return size;
753 }
754
755
756 static struct file_operations route_fops = {
757     .owner = THIS_MODULE,
758     .open = route_open, 
759     .read = seq_read,
760     .write = route_write,
761     .llseek = seq_lseek,
762     .release = seq_release
763 };
764
765
766 static struct file_operations link_fops = {
767     .owner = THIS_MODULE,
768     .open = link_open, 
769     .read = seq_read,
770     .write = link_write,
771     .llseek = seq_lseek,
772     .release = seq_release
773 };
774
775
776 static ssize_t 
777 debug_write(struct file * file, const char * buf, size_t size, loff_t * ppos) {
778     char link_buf[32];
779     char * link_iter = NULL;
780     char * line_str = link_buf;
781     int level = -1; 
782
783     if (size >= 32) {
784         return -EFAULT;
785     }
786
787     if (copy_from_user(link_buf, buf, size)) {
788         return -EFAULT;
789     }
790
791     link_iter = strsep(&line_str, "\r\n");
792     level = simple_strtol(link_iter, &link_iter, 10);
793
794     printk("Set VNET Debug level to %d\n", level);
795
796     if(level >= 0){
797         vnet_debug = level;
798     }
799
800     return size;
801 }
802
803
804 static int debug_show(struct seq_file * file, void * v){
805     seq_printf(file, "Current VNET Debug Level: %d\n", vnet_debug);
806         
807     return 0;
808 }
809
810 static int debug_open(struct inode * inode, struct file * file) {
811     return single_open(file, debug_show, NULL);
812 }
813
814 static struct file_operations debug_fops = {
815     .owner = THIS_MODULE,
816     .open = debug_open, 
817     .read = seq_read,
818     .write = debug_write,
819     .llseek = seq_lseek,
820     .release = seq_release
821 };
822
823 static int stat_show(struct seq_file * file, void * v){
824     struct vnet_stat stats;
825
826     v3_vnet_stat(&stats);
827
828     seq_printf(file, "VNET Core\n");
829     seq_printf(file, "\tReceived Packets: %d\n", stats.rx_pkts);
830     seq_printf(file, "\tReceived Bytes: %lld\n", stats.rx_bytes);
831     seq_printf(file, "\tTransmitted Packets: %d\n", stats.tx_pkts);
832     seq_printf(file, "\tTransmitted Bytes: %lld\n", stats.tx_bytes);
833
834
835     seq_printf(file, "\nVNET Bridge Server\n");
836     seq_printf(file, "\tReceived From VMM: %d\n", vnet_state.pkt_from_vmm);
837     seq_printf(file, "\tSent To VMM: %d\n", vnet_state.pkt_to_vmm);
838     seq_printf(file, "\tDropped From VMM: %d\n", vnet_state.pkt_drop_vmm);
839     seq_printf(file, "\tReceived From Extern Network: %d\n", vnet_state.pkt_from_phy);
840     seq_printf(file, "\tSent To Extern Network: %d\n", vnet_state.pkt_to_phy);
841     seq_printf(file, "\tDropped From Extern Network: %d\n", vnet_state.pkt_drop_phy);
842
843     return 0;
844 }
845
846 static int stat_open(struct inode * inode, struct file * file) {
847     return single_open(file, stat_show, NULL);
848 }
849
850 static struct file_operations stat_fops = {
851     .owner = THIS_MODULE,
852     .open = stat_open, 
853     .read = seq_read,
854     .llseek = seq_lseek,
855     .release = seq_release
856 };
857
858
859 static int init_proc_files(void) {
860     struct proc_dir_entry * route_entry = NULL;
861     struct proc_dir_entry * link_entry = NULL;
862     struct proc_dir_entry * stat_entry = NULL;
863     struct proc_dir_entry * debug_entry = NULL;
864     struct proc_dir_entry * vnet_root = NULL;
865
866     vnet_root = proc_mkdir("vnet", NULL);
867     if (vnet_root == NULL) {
868         return -1;
869     }
870
871     route_entry = create_proc_entry("routes", 0, vnet_root);
872     if (route_entry == NULL) {
873         remove_proc_entry("vnet", NULL);
874         return -1;
875     }
876     route_entry->proc_fops = &route_fops;
877         
878
879     link_entry = create_proc_entry("links", 0, vnet_root);
880     if (link_entry == NULL) {
881         remove_proc_entry("routes", vnet_root);
882         remove_proc_entry("vnet", NULL);
883         return -1;
884     }
885     link_entry->proc_fops = &link_fops;
886         
887
888     stat_entry = create_proc_entry("stats", 0, vnet_root);
889     if(stat_entry == NULL) {
890         remove_proc_entry("links", vnet_root);
891         remove_proc_entry("routes", vnet_root);
892         remove_proc_entry("vnet", NULL);
893         return -1;
894     }
895     stat_entry->proc_fops = &stat_fops;
896
897
898     debug_entry = create_proc_entry("debug", 0, vnet_root);
899     if(debug_entry == NULL) {
900         remove_proc_entry("links", vnet_root);
901         remove_proc_entry("routes", vnet_root);
902         remove_proc_entry("stats", vnet_root);
903         remove_proc_entry("vnet", NULL);
904         return -1;
905     }
906     debug_entry->proc_fops = &debug_fops;
907         
908
909     return 0;
910 }
911
912
913
914 static int 
915 udp_send(struct socket * sock, 
916          struct sockaddr_in * addr,
917          unsigned char * buf,  int len) {
918     struct msghdr msg;
919     struct iovec iov;
920     mm_segment_t oldfs;
921     int size = 0;
922
923           
924     if (sock->sk == NULL) {
925         return 0;
926     }
927
928     iov.iov_base = buf;
929     iov.iov_len = len;
930
931     msg.msg_flags = 0;
932     msg.msg_name = addr;
933     msg.msg_namelen = sizeof(struct sockaddr_in);
934     msg.msg_control = NULL;
935     msg.msg_controllen = 0;
936     msg.msg_iov = &iov;
937     msg.msg_iovlen = 1;
938     msg.msg_control = NULL;
939
940     oldfs = get_fs();
941     set_fs(KERNEL_DS);
942     size = sock_sendmsg(sock, &msg, len);
943     set_fs(oldfs);
944
945     return size;
946 }
947
948
949
950 static int 
951 udp_recv(struct socket * sock, 
952          struct sockaddr_in * addr,
953          unsigned char * buf, int len) {
954     struct msghdr msg;
955     struct iovec iov;
956     mm_segment_t oldfs;
957     int size = 0;
958     
959     if (sock->sk == NULL) {
960         return 0;
961     }
962
963     iov.iov_base = buf;
964     iov.iov_len = len;
965     
966     msg.msg_flags = 0;
967     msg.msg_name = addr;
968     msg.msg_namelen = sizeof(struct sockaddr_in);
969     msg.msg_control = NULL;
970     msg.msg_controllen = 0;
971     msg.msg_iov = &iov;
972     msg.msg_iovlen = 1;
973     msg.msg_control = NULL;
974     
975     oldfs = get_fs();
976     set_fs(KERNEL_DS);
977     size = sock_recvmsg(sock, &msg, len, msg.msg_flags);
978         
979     set_fs(oldfs);
980     
981     return size;
982 }
983
984 /* send packets to VNET core */
985 static int 
986 send_to_palacios(unsigned char * buf, 
987                  int len,
988                  int link_id){
989     struct v3_vnet_pkt pkt;
990     pkt.size = len;
991     pkt.src_type = LINK_EDGE;
992     pkt.src_id = link_id;
993     memcpy(pkt.header, buf, ETHERNET_HEADER_LEN);
994     pkt.data = buf;
995
996     if(vnet_debug >= 2){
997         printk("VNET Lnx Bridge: send pkt to VNET core (size: %d, src_id: %d, src_type: %d)\n", 
998                         pkt.size,  pkt.src_id, pkt.src_type);
999         if(vnet_debug >= 4){
1000             print_hex_dump(NULL, "pkt_data: ", 0, 20, 20, pkt.data, pkt.size, 0);
1001         }
1002     }
1003
1004     vnet_state.pkt_to_vmm ++;
1005
1006     return v3_vnet_send_pkt(&pkt, NULL, 1);
1007 }
1008
1009
1010 /* send packet to extern network */
1011 static int 
1012 bridge_send_pkt(struct v3_vm_info * vm, 
1013                 struct v3_vnet_pkt * pkt, 
1014                 void * private_data) {
1015     struct vnet_link * link;
1016
1017     if(vnet_debug >= 2){
1018         printk("VNET Lnx Host Bridge: packet received from VNET Core ... pkt size: %d, link: %d\n",
1019                         pkt->size,
1020                         pkt->dst_id);
1021         if(vnet_debug >= 4){
1022             print_hex_dump(NULL, "pkt_data: ", 0, 20, 20, pkt->data, pkt->size, 0);
1023         }
1024     }
1025
1026     vnet_state.pkt_from_vmm ++;
1027
1028     link = link_by_idx(pkt->dst_id);
1029     if (link != NULL) {
1030         switch(link->sock_proto){
1031             case UDP:
1032                 udp_send(link->sock, &(link->sock_addr), pkt->data, pkt->size);
1033                 vnet_state.pkt_to_phy ++;
1034                 break;
1035             case TCP:
1036                 vnet_state.pkt_to_phy ++;
1037                 break;  
1038
1039             default:
1040                 printk("VNET Server: Invalid Link Protocol\n");
1041                 vnet_state.pkt_drop_vmm ++;
1042         }
1043         link->bytes_tx += pkt->size;
1044         link->pkt_tx ++;
1045     } else {
1046         printk("VNET Bridge Linux Host: wrong dst link, idx: %d, discards the packet\n", pkt->dst_id);
1047         vnet_state.pkt_drop_vmm ++;
1048     }
1049
1050     return 0;
1051 }
1052
1053
1054 static int init_vnet_serv(void) {
1055     int protocol;
1056     int err;
1057
1058     switch(vnet_state.serv_proto){
1059         case UDP:
1060             protocol = IPPROTO_UDP;
1061             break;
1062         case TCP:
1063             protocol = IPPROTO_TCP;
1064             break;
1065
1066         default:
1067            printk("Unsupported VNET Server Protocol\n");
1068             return -1;
1069     }
1070          
1071     if ((err = sock_create(AF_INET, SOCK_DGRAM, protocol, &vnet_state.serv_sock)) < 0) {
1072         printk("Could not create VNET server socket, error: %d\n", err);
1073         return -1;
1074     }
1075
1076     memset(&vnet_state.serv_addr, 0, sizeof(struct sockaddr));
1077
1078     vnet_state.serv_addr.sin_family = AF_INET;
1079     vnet_state.serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
1080     vnet_state.serv_addr.sin_port = htons(VNET_SERVER_PORT);
1081
1082     if ((err = vnet_state.serv_sock->ops->bind(vnet_state.serv_sock, (struct sockaddr *)&(vnet_state.serv_addr), sizeof(struct sockaddr))) < 0) {
1083         printk("Could not bind VNET server socket to port %d, error: %d\n", VNET_SERVER_PORT, err);
1084         return -1;
1085     }
1086
1087     printk("VNET server bind to port: %d\n", VNET_SERVER_PORT);
1088
1089     if(vnet_state.serv_proto == TCP){
1090         if((err = vnet_state.serv_sock->ops->listen(vnet_state.serv_sock, 32)) < 0){
1091             printk("VNET Server error listening on port %d, error %d\n", VNET_SERVER_PORT, err);
1092             return -1;
1093         }
1094     }
1095
1096     return 0;
1097 }
1098
1099 static int vnet_udp_server(void * arg) {
1100     unsigned char * pkt;
1101     struct sockaddr_in pkt_addr;
1102     struct vnet_link * link = NULL;
1103     int len;
1104
1105     printk("Palacios VNET Bridge: UDP receiving server ..... \n");
1106
1107     pkt = kmalloc(MAX_PACKET_LEN, GFP_KERNEL);
1108     while (!kthread_should_stop()) {
1109         
1110         len = udp_recv(vnet_state.serv_sock, &pkt_addr, pkt, MAX_PACKET_LEN); 
1111         if(len < 0) {
1112             printk("Receive error: Could not get packet, error %d\n", len);
1113             continue;
1114         }
1115
1116         link = link_by_ip(pkt_addr.sin_addr.s_addr);
1117         if (link == NULL){
1118             printk("VNET Server: No VNET Link match the src IP\n");
1119             vnet_state.pkt_drop_phy ++;
1120             continue;
1121         }
1122         
1123         vnet_state.pkt_from_phy ++;
1124         link->bytes_rx += len;
1125         link->pkt_rx ++;
1126
1127         send_to_palacios(pkt, len, link->link_idx);
1128     }
1129
1130     kfree(pkt);
1131
1132     return 0;
1133 }
1134
1135
1136
1137 static int vnet_server(void * arg) {
1138     
1139     if(vnet_state.serv_proto == UDP){
1140         vnet_udp_server(NULL);
1141     }else if(vnet_state.serv_proto == TCP) {
1142         //accept new connection
1143         //use select to receive pkt from physical network
1144         //or create new kthread to handle each connection?
1145     }else {
1146         printk ("VNET Server: Unsupported Protocol\n");
1147         return -1;
1148     }
1149
1150     return 0;
1151 }
1152
1153 static inline unsigned int hash_fn(addr_t hdr_ptr) {    
1154     return vnet_hash_buffer((uint8_t *)hdr_ptr, sizeof(uint32_t));
1155 }
1156
1157 static inline int hash_eq(addr_t key1, addr_t key2) {   
1158     return (memcmp((uint8_t *)key1, (uint8_t *)key2, sizeof(uint32_t)) == 0);
1159 }
1160
1161
1162 int  palacios_init_vnet(void) {
1163     struct v3_vnet_bridge_ops bridge_ops;
1164
1165
1166     if(vnet_state.status != 0) {
1167         return -1;
1168     }   
1169     vnet_state.status = 1;      
1170         
1171     memset(&vnet_state, 0, sizeof(struct palacios_vnet_state));
1172
1173     INIT_LIST_HEAD(&(vnet_state.link_list));
1174     INIT_LIST_HEAD(&(vnet_state.route_list));
1175     spin_lock_init(&(vnet_state.lock));
1176
1177     init_proc_files();
1178
1179     vnet_state.serv_proto = UDP;
1180
1181     vnet_state.ip2link = vnet_create_htable(10, hash_fn, hash_eq);
1182     if(vnet_state.ip2link == NULL){
1183         printk("Failure to initiate VNET link hashtable\n");
1184         return -1;
1185     }
1186         
1187     if(init_vnet_serv() < 0){
1188         printk("Failure to initiate VNET server\n");
1189         return -1;
1190     }
1191
1192     vnet_state.serv_thread = kthread_run(vnet_server, NULL, "vnet-server");
1193
1194     bridge_ops.input = bridge_send_pkt;
1195     bridge_ops.poll = NULL;
1196         
1197     v3_vnet_add_bridge(NULL, &bridge_ops, HOST_LNX_BRIDGE, NULL);
1198
1199     printk("Palacios VNET Linux Bridge initiated\n");
1200
1201     return 0;
1202 }
1203