2 Palacios VNET Host Bridge
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>
12 #include <linux/netdevice.h>
15 #include <linux/net.h>
16 #include <linux/string.h>
17 #include <linux/preempt.h>
18 #include <linux/sched.h>
21 #include <vnet/vnet.h>
22 #include <vnet/vnet_hashtable.h>
23 #include "palacios-vnet.h"
25 #define VNET_SERVER_PORT 9000
27 struct palacios_vnet_route {
28 struct v3_vnet_route route;
32 struct list_head node;
35 typedef enum {UDP, TCP, RAW, NONE} vnet_bridge_proto_t;
42 struct sockaddr_in sock_addr;
43 vnet_bridge_proto_t sock_proto;
45 unsigned int pkt_rx, pkt_tx;
46 uint64_t bytes_rx, bytes_tx;
50 struct list_head node;
54 struct palacios_vnet_state {
62 struct list_head route_list;
63 struct list_head link_list;
65 struct hashtable *ip2link; /* map IP to its Link */
69 struct socket * serv_sock;
70 struct sockaddr_in serv_addr;
71 vnet_bridge_proto_t serv_proto;
73 /* Socket Receiving Thread */
74 struct task_struct * serv_thread;
76 struct proc_dir_entry * vnet_proc_root;
78 unsigned int pkt_from_vmm, pkt_to_vmm, pkt_drop_vmm;
79 unsigned int pkt_from_phy, pkt_to_phy, pkt_drop_phy;
83 static struct palacios_vnet_state vnet_state;
86 static inline struct vnet_link * link_by_ip(uint32_t ip) {
87 return (struct vnet_link *)vnet_htable_search(vnet_state.ip2link, (addr_t)&ip);
90 static inline struct vnet_link * link_by_idx(int idx) {
91 struct vnet_link * link = NULL;
93 list_for_each_entry(link, &(vnet_state.link_list), node) {
95 if (link->idx == idx) {
102 static inline struct palacios_vnet_route * route_by_idx(int idx) {
103 struct palacios_vnet_route * route = NULL;
105 list_for_each_entry(route, &(vnet_state.route_list), node) {
107 if (route->idx == idx) {
116 static int parse_mac_str(char * str, uint8_t * qual, uint8_t * mac) {
119 printk("Parsing MAC (%s)\n", str);
122 if(strnicmp("any", str, strlen(str)) == 0){
125 }else if(strnicmp("none", str, strlen(str)) == 0){
129 if (strstr(str, "-")) {
130 token = strsep(&str, "-");
132 if (strnicmp("not", token, strlen("not")) == 0) {
135 printk("Invalid MAC String token (%s)\n", token);
140 if (strstr(str, ":")) {
143 if(*qual == MAC_NOSET){
147 for (i = 0; i < 6; i++) {
148 token = strsep(&str, ":");
150 printk("Invalid MAC String token (%s)\n", token);
153 mac[i] = simple_strtol(token, &token, 16);
155 printk("MAC: %2x:%2x:%2x:%2x:%2x:%2x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
158 printk("Invalid MAC String token (%s)\n", token);
168 static int str2mac(char * str, uint8_t * mac){
172 for (i = 0; i < ETH_ALEN; i++) {
173 hex = strsep(&str, ":");
175 printk("Invalid MAC String token (%s)\n", str);
178 mac[i] = simple_strtol(hex, &hex, 16);
186 * add src-MAC dst-MAC dst-TYPE [dst-ID] src-TYPE [src-ID]
188 * src-MAC = dst-MAC = not-MAC|any|none|MAC
189 * dst-TYPE = edge|interface
190 * src-TYPE = edge|interface|any
191 * dst-ID = src-ID = IP|MAC
192 * MAC=xx:xx:xx:xx:xx:xx
193 * IP = xxx.xxx.xxx.xxx
195 static int parse_route_str(char * str, struct v3_vnet_route * route) {
197 struct vnet_link *link = NULL;
200 token = strsep(&str, " ");
204 parse_mac_str(token, &(route->src_mac_qual), route->src_mac);
207 token = strsep(&str, " ");
211 parse_mac_str(token, &(route->dst_mac_qual), route->dst_mac);
214 token = strsep(&str, " ");
218 printk("dst type =(%s)\n", token);
220 if (strnicmp("interface", token, strlen("interface")) == 0) {
221 route->dst_type = LINK_INTERFACE;
222 } else if (strnicmp("edge", token, strlen("edge")) == 0) {
223 route->dst_type = LINK_EDGE;
225 printk("Invalid Destination Link Type (%s)\n", token);
230 token = strsep(&str, " ");
234 printk("dst ID=(%s)\n", token);
236 // Figure out link here
237 if (route->dst_type == LINK_EDGE) {
240 // Figure out Link Here
241 if (in4_pton(token, strlen(token), (uint8_t *)&(link_ip), '\0', NULL) != 1) {
242 printk("Invalid Dst IP address (%s)\n", token);
246 link = link_by_ip(link_ip);
248 route->dst_id = link->idx;
250 printk("can not find dst link %s\n", token);
254 printk("link_ip = %d, link_id = %d\n", link_ip, link->idx);
255 } else if (route->dst_type == LINK_INTERFACE) {
256 uint8_t mac[ETH_ALEN];
258 if(str2mac(token, mac) == -1){
259 printk("wrong MAC format (%s)\n", token);
263 route->dst_id = v3_vnet_find_dev(mac);
264 if (route->dst_id == -1){
265 printk("can not find dst device %s\n", token);
269 printk("Unsupported dst link type\n");
274 route->src_type = -1;
277 token = strsep(&str, " ");
279 printk("SRC type = %s\n", token);
285 if (strnicmp("interface", token, strlen("interface")) == 0) {
286 route->src_type = LINK_INTERFACE;
287 } else if (strnicmp("edge", token, strlen("edge")) == 0) {
288 route->src_type = LINK_EDGE;
289 } else if (strnicmp("any", token, strlen("any")) == 0) {
290 route->src_type = LINK_ANY;
292 printk("Invalid Src link type (%s)\n", token);
297 if (route->src_type == LINK_ANY) {
299 } else if (route->src_type == LINK_EDGE) {
301 token = strsep(&str, " ");
307 // Figure out Link Here
308 if (in4_pton(token, strlen(token), (uint8_t *)&(src_ip), '\0', NULL) != 1) {
309 printk("Invalid SRC IP address (%s)\n", token);
313 link = link_by_ip(src_ip);
315 route->src_id = link->idx;
317 printk("can not find src link %s\n", token);
320 } else if(route->src_type == LINK_INTERFACE){
321 uint8_t mac[ETH_ALEN];
323 if(str2mac(token, mac) == -1){
324 printk("wrong MAC format (%s)\n", token);
328 route->src_id = v3_vnet_find_dev(mac);
329 if (route->src_id == -1){
330 printk("can not find dst device %s\n", token);
334 printk("Invalid link type\n");
344 static void * route_seq_start(struct seq_file * s, loff_t * pos) {
345 struct palacios_vnet_route * route_iter = NULL;
349 if (*pos >= vnet_state.num_routes) {
353 list_for_each_entry(route_iter, &(vnet_state.route_list), node) {
366 static void * link_seq_start(struct seq_file * s, loff_t * pos) {
367 struct vnet_link * link_iter = NULL;
370 if (*pos >= vnet_state.num_links) {
374 list_for_each_entry(link_iter, &(vnet_state.link_list), node) {
388 static void * route_seq_next(struct seq_file * s, void * v, loff_t * pos) {
389 struct palacios_vnet_route * route_iter = NULL;
391 route_iter = list_entry(((struct palacios_vnet_route *)v)->node.next, struct palacios_vnet_route, node);
393 // Check if the list has looped
394 if (&(route_iter->node) == &(vnet_state.route_list)) {
404 static void * link_seq_next(struct seq_file * s, void * v, loff_t * pos) {
405 struct vnet_link * link_iter = NULL;
408 link_iter = list_entry(((struct vnet_link *)v)->node.next, struct vnet_link, node);
410 // Check if the list has looped
411 if (&(link_iter->node) == &(vnet_state.link_list)) {
421 static void route_seq_stop(struct seq_file * s, void * v) {
427 static void link_seq_stop(struct seq_file * s, void * v) {
432 static int route_seq_show(struct seq_file * s, void * v) {
433 struct palacios_vnet_route * route_iter = v;
434 struct v3_vnet_route * route = &(route_iter->route);
436 seq_printf(s, "%d:\t", route_iter->idx);
438 seq_printf(s, "\nSrc:\t");
439 switch (route->src_mac_qual) {
441 seq_printf(s, "any ");
444 seq_printf(s, "none ");
447 seq_printf(s, "not-%2x:%2x:%2x:%2x:%2x:%2x ",
448 route->src_mac[0], route->src_mac[1], route->src_mac[2],
449 route->src_mac[3], route->src_mac[4], route->src_mac[5]);
452 seq_printf(s, "%x:%x:%x:%x:%x:%x ",
453 route->src_mac[0], route->src_mac[1], route->src_mac[2],
454 route->src_mac[3], route->src_mac[4], route->src_mac[5]);
458 seq_printf(s, "\nDst:\t");
459 switch (route->dst_mac_qual) {
461 seq_printf(s, "any ");
464 seq_printf(s, "none ");
467 seq_printf(s, "not-%x:%x:%x:%x:%x:%x ",
468 route->src_mac[0], route->src_mac[1], route->src_mac[2],
469 route->src_mac[3], route->src_mac[4], route->src_mac[5]);
472 seq_printf(s, "%x:%x:%x:%x:%x:%x ",
473 route->src_mac[0], route->src_mac[1], route->src_mac[2],
474 route->src_mac[3], route->src_mac[4], route->src_mac[5]);
478 seq_printf(s, "\nDst-Type:\t");
479 switch (route->dst_type) {
481 struct vnet_link * link = (struct vnet_link *)link_by_idx(route->dst_id);
482 seq_printf(s, "EDGE %pI4", &link->dst_ip);
485 case LINK_INTERFACE: {
486 seq_printf(s, "INTERFACE ");
487 seq_printf(s, "%d ", route->dst_id);
491 seq_printf(s, "Invalid Dst Link Type (%d) ", route->dst_type);
495 seq_printf(s, "\nSrc-Type:\t");
496 switch (route->src_type) {
498 struct vnet_link * link = (struct vnet_link *)link_by_idx(route->src_id);
499 seq_printf(s, "EDGE %pI4", &link->dst_ip);
502 case LINK_INTERFACE: {
503 seq_printf(s, "INTERFACE %d", route->src_id);
507 seq_printf(s, "ANY");
510 seq_printf(s, "Invalid Src Link Type (%d) ", route->src_type);
521 static int link_seq_show(struct seq_file * s, void * v) {
522 struct vnet_link * link_iter = v;
524 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",
531 link_iter->bytes_tx);
537 static struct seq_operations route_seq_ops = {
538 .start = route_seq_start,
539 .next = route_seq_next,
540 .stop = route_seq_stop,
541 .show = route_seq_show
545 static struct seq_operations link_seq_ops = {
546 .start = link_seq_start,
547 .next = link_seq_next,
548 .stop = link_seq_stop,
549 .show = link_seq_show
553 static int route_open(struct inode * inode, struct file * file) {
554 return seq_open(file, &route_seq_ops);
558 static int link_open(struct inode * inode, struct file * file) {
559 return seq_open(file, &link_seq_ops);
562 static int inject_route(struct palacios_vnet_route * route) {
565 v3_vnet_add_route(route->route);
567 spin_lock_irqsave(&(vnet_state.lock), flags);
568 list_add(&(route->node), &(vnet_state.route_list));
569 vnet_state.num_routes++;
570 route->idx = vnet_state.route_idx ++;
571 spin_unlock_irqrestore(&(vnet_state.lock), flags);
573 printk("Palacios-vnet: One route added to VNET core\n");
579 static int delete_route(struct palacios_vnet_route * route) {
582 //v3_vnet_del_route(route->route);
584 spin_lock_irqsave(&(vnet_state.lock), flags);
585 list_del(&(route->node));
586 vnet_state.num_routes --;
587 spin_unlock_irqrestore(&(vnet_state.lock), flags);
589 printk("Palacios-vnet: Route %d deleted from VNET\n", route->idx);
597 route_write(struct file * file,
602 char * buf_iter = NULL;
603 char * line_str = route_buf;
610 if (copy_from_user(route_buf, buf, size)) {
614 route_buf[size] = '\0';
615 printk("Route written: %s\n", route_buf);
617 while ((buf_iter = strsep(&line_str, "\r\n"))) {
619 token = strsep(&buf_iter, " ");
624 if (strnicmp("ADD", token, strlen("ADD")) == 0) {
625 struct palacios_vnet_route * new_route = NULL;
626 new_route = kmalloc(sizeof(struct palacios_vnet_route), GFP_KERNEL);
632 memset(new_route, 0, sizeof(struct palacios_vnet_route));
634 if (parse_route_str(buf_iter, &(new_route->route)) == -1) {
639 if (inject_route(new_route) != 0) {
643 } else if (strnicmp("DEL", token, strlen("DEL")) == 0) {
644 printk("I should delete the route here\n");
646 printk("Invalid Route command string\n");
654 static void delete_link(struct vnet_link * link){
657 link->sock->ops->release(link->sock);
659 spin_lock_irqsave(&(vnet_state.lock), flags);
660 list_del(&(link->node));
661 vnet_htable_remove(vnet_state.ip2link, (addr_t)&(link->dst_ip), 0);
662 vnet_state.num_links --;
663 spin_unlock_irqrestore(&(vnet_state.lock), flags);
665 printk("VNET Bridge: Link deleted, ip 0x%x, port: %d, idx: %d\n",
675 static void deinit_links_list(void){
676 struct vnet_link * link;
678 list_for_each_entry(link, &(vnet_state.link_list), node) {
683 static void deinit_routes_list(void){
684 struct palacios_vnet_route * route;
686 list_for_each_entry(route, &(vnet_state.route_list), node) {
693 static int create_link(struct vnet_link * link) {
698 switch(link->sock_proto){
700 protocol = IPPROTO_UDP;
703 protocol = IPPROTO_TCP;
707 printk("Unsupported VNET Server Protocol\n");
711 if ((err = sock_create(AF_INET, SOCK_DGRAM, protocol, &link->sock)) < 0) {
712 printk("Could not create socket for VNET Link, error %d\n", err);
716 memset(&link->sock_addr, 0, sizeof(struct sockaddr));
718 link->sock_addr.sin_family = AF_INET;
719 link->sock_addr.sin_addr.s_addr = link->dst_ip;
720 link->sock_addr.sin_port = htons(link->dst_port);
722 if ((err = link->sock->ops->connect(link->sock, (struct sockaddr *)&(link->sock_addr), sizeof(struct sockaddr), 0) < 0)) {
723 printk("Could not connect to remote VNET Server, error %d\n", err);
727 spin_lock_irqsave(&(vnet_state.lock), flags);
728 list_add(&(link->node), &(vnet_state.link_list));
729 vnet_state.num_links ++;
730 link->idx = vnet_state.link_idx ++;
731 vnet_htable_insert(vnet_state.ip2link, (addr_t)&(link->dst_ip), (addr_t)link);
732 spin_unlock_irqrestore(&(vnet_state.lock), flags);
734 printk("VNET Bridge: Link created, ip 0x%x, port: %d, idx: %d, link: %p, protocol: %s\n",
739 ((link->sock_proto==UDP)?"UDP":"TCP"));
745 /* ADD dst-ip 9000 [udp|tcp] */
747 link_write(struct file * file, const char * buf, size_t size, loff_t * ppos) {
749 char * link_iter = NULL;
750 char * line_str = link_buf;
757 if (copy_from_user(link_buf, buf, size)) {
761 while ((link_iter = strsep(&line_str, "\r\n"))) {
762 printk("Link written: %s\n", link_buf);
764 token = strsep(&link_iter, " ");
770 if (strnicmp("ADD", token, strlen("ADD")) == 0) {
771 struct vnet_link * new_link = NULL;
772 char * ip_str = NULL;
775 ip_str = strsep(&link_iter, " ");
777 if ((!ip_str) || (!link_iter)) {
778 printk("Missing fields in ADD Link command\n");
782 if (in4_pton(ip_str, strlen(ip_str), (uint8_t *)&(ip), '\0', NULL) != 1) {
783 printk("Invalid Dst IP address (%s)\n", ip_str);
787 new_link = kmalloc(sizeof(struct vnet_link), GFP_KERNEL);
792 memset(new_link, 0, sizeof(struct vnet_link));
794 new_link->dst_ip = ip;
795 new_link->dst_port = simple_strtol(link_iter, &link_iter, 10);
797 //TODO: Parse UDP|TCP
798 new_link->sock_proto = UDP;
800 if (create_link(new_link) != 0) {
801 printk("Could not create link\n");
806 } else if (strnicmp("DEL", token, strlen("DEL")) == 0) {
807 printk("Link deletion not supported\n");
809 printk("Invalid Link command string\n");
817 static struct file_operations route_fops = {
818 .owner = THIS_MODULE,
821 .write = route_write,
823 .release = seq_release
827 static struct file_operations link_fops = {
828 .owner = THIS_MODULE,
833 .release = seq_release
838 debug_write(struct file * file, const char * buf, size_t size, loff_t * ppos) {
840 char * link_iter = NULL;
841 char * line_str = link_buf;
848 if (copy_from_user(link_buf, buf, size)) {
852 link_iter = strsep(&line_str, "\r\n");
853 level = simple_strtol(link_iter, &link_iter, 10);
855 printk("Set VNET Debug level to %d\n", level);
865 static int debug_show(struct seq_file * file, void * v){
866 seq_printf(file, "Current VNET Debug Level: %d\n", net_debug);
871 static int debug_open(struct inode * inode, struct file * file) {
872 return single_open(file, debug_show, NULL);
875 static struct file_operations debug_fops = {
876 .owner = THIS_MODULE,
879 .write = debug_write,
881 .release = seq_release
884 static int stat_show(struct seq_file * file, void * v){
885 struct vnet_stat stats;
887 v3_vnet_stat(&stats);
889 seq_printf(file, "VNET Core\n");
890 seq_printf(file, "\tReceived Packets: %d\n", stats.rx_pkts);
891 seq_printf(file, "\tReceived Bytes: %lld\n", stats.rx_bytes);
892 seq_printf(file, "\tTransmitted Packets: %d\n", stats.tx_pkts);
893 seq_printf(file, "\tTransmitted Bytes: %lld\n", stats.tx_bytes);
896 seq_printf(file, "\nVNET Bridge Server\n");
897 seq_printf(file, "\tReceived From VMM: %d\n", vnet_state.pkt_from_vmm);
898 seq_printf(file, "\tSent To VMM: %d\n", vnet_state.pkt_to_vmm);
899 seq_printf(file, "\tDropped From VMM: %d\n", vnet_state.pkt_drop_vmm);
900 seq_printf(file, "\tReceived From Extern Network: %d\n", vnet_state.pkt_from_phy);
901 seq_printf(file, "\tSent To Extern Network: %d\n", vnet_state.pkt_to_phy);
902 seq_printf(file, "\tDropped From Extern Network: %d\n", vnet_state.pkt_drop_phy);
907 static int stat_open(struct inode * inode, struct file * file) {
908 return single_open(file, stat_show, NULL);
911 static struct file_operations stat_fops = {
912 .owner = THIS_MODULE,
916 .release = seq_release
920 static int init_proc_files(void) {
921 struct proc_dir_entry * route_entry = NULL;
922 struct proc_dir_entry * link_entry = NULL;
923 struct proc_dir_entry * stat_entry = NULL;
924 struct proc_dir_entry * debug_entry = NULL;
925 struct proc_dir_entry * vnet_root = NULL;
927 vnet_root = proc_mkdir("vnet", NULL);
928 if (vnet_root == NULL) {
932 route_entry = create_proc_entry("routes", 0, vnet_root);
933 if (route_entry == NULL) {
934 remove_proc_entry("vnet", NULL);
937 route_entry->proc_fops = &route_fops;
940 link_entry = create_proc_entry("links", 0, vnet_root);
941 if (link_entry == NULL) {
942 remove_proc_entry("routes", vnet_root);
943 remove_proc_entry("vnet", NULL);
946 link_entry->proc_fops = &link_fops;
949 stat_entry = create_proc_entry("stats", 0, vnet_root);
950 if(stat_entry == NULL) {
951 remove_proc_entry("links", vnet_root);
952 remove_proc_entry("routes", vnet_root);
953 remove_proc_entry("vnet", NULL);
956 stat_entry->proc_fops = &stat_fops;
959 debug_entry = create_proc_entry("debug", 0, vnet_root);
960 if(debug_entry == NULL) {
961 remove_proc_entry("links", vnet_root);
962 remove_proc_entry("routes", vnet_root);
963 remove_proc_entry("stats", vnet_root);
964 remove_proc_entry("vnet", NULL);
967 debug_entry->proc_fops = &debug_fops;
969 vnet_state.vnet_proc_root = vnet_root;
975 static void destroy_proc_files(void) {
976 struct proc_dir_entry * vnet_root = vnet_state.vnet_proc_root;
978 remove_proc_entry("debug", vnet_root);
979 remove_proc_entry("links", vnet_root);
980 remove_proc_entry("routes", vnet_root);
981 remove_proc_entry("stats", vnet_root);
982 remove_proc_entry("vnet", NULL);
987 udp_send(struct socket * sock,
988 struct sockaddr_in * addr,
989 unsigned char * buf, int len) {
996 if (sock->sk == NULL) {
1004 msg.msg_name = addr;
1005 msg.msg_namelen = sizeof(struct sockaddr_in);
1006 msg.msg_control = NULL;
1007 msg.msg_controllen = 0;
1010 msg.msg_control = NULL;
1014 size = sock_sendmsg(sock, &msg, len);
1023 udp_recv(struct socket * sock,
1024 struct sockaddr_in * addr,
1025 unsigned char * buf, int len) {
1031 if (sock->sk == NULL) {
1039 msg.msg_name = addr;
1040 msg.msg_namelen = sizeof(struct sockaddr_in);
1041 msg.msg_control = NULL;
1042 msg.msg_controllen = 0;
1045 msg.msg_control = NULL;
1049 size = sock_recvmsg(sock, &msg, len, msg.msg_flags);
1056 /* send packets to VNET core */
1058 send_to_palacios(unsigned char * buf,
1061 struct v3_vnet_pkt pkt;
1063 pkt.src_type = LINK_EDGE;
1064 pkt.src_id = link_id;
1065 memcpy(pkt.header, buf, ETHERNET_HEADER_LEN);
1069 printk("VNET Lnx Bridge: send pkt to VNET core (size: %d, src_id: %d, src_type: %d)\n",
1070 pkt.size, pkt.src_id, pkt.src_type);
1072 print_hex_dump(NULL, "pkt_data: ", 0, 20, 20, pkt.data, pkt.size, 0);
1076 vnet_state.pkt_to_vmm ++;
1078 return v3_vnet_send_pkt(&pkt, NULL, 1);
1082 /* send packet to extern network */
1084 bridge_send_pkt(struct v3_vm_info * vm,
1085 struct v3_vnet_pkt * pkt,
1086 void * private_data) {
1087 struct vnet_link * link;
1090 printk("VNET Lnx Host Bridge: packet received from VNET Core ... pkt size: %d, link: %d\n",
1094 print_hex_dump(NULL, "pkt_data: ", 0, 20, 20, pkt->data, pkt->size, 0);
1098 vnet_state.pkt_from_vmm ++;
1100 link = link_by_idx(pkt->dst_id);
1102 switch(link->sock_proto){
1104 udp_send(link->sock, &(link->sock_addr), pkt->data, pkt->size);
1105 vnet_state.pkt_to_phy ++;
1108 vnet_state.pkt_to_phy ++;
1112 printk("VNET Server: Invalid Link Protocol\n");
1113 vnet_state.pkt_drop_vmm ++;
1115 link->bytes_tx += pkt->size;
1118 printk("VNET Bridge Linux Host: wrong dst link, idx: %d, discards the packet\n", pkt->dst_id);
1119 vnet_state.pkt_drop_vmm ++;
1126 static int init_vnet_serv(void) {
1130 switch(vnet_state.serv_proto){
1132 protocol = IPPROTO_UDP;
1135 protocol = IPPROTO_TCP;
1139 printk("Unsupported VNET Server Protocol\n");
1143 if ((err = sock_create(AF_INET, SOCK_DGRAM, protocol, &vnet_state.serv_sock)) < 0) {
1144 printk("Could not create VNET server socket, error: %d\n", err);
1148 memset(&vnet_state.serv_addr, 0, sizeof(struct sockaddr));
1150 vnet_state.serv_addr.sin_family = AF_INET;
1151 vnet_state.serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
1152 vnet_state.serv_addr.sin_port = htons(VNET_SERVER_PORT);
1154 if ((err = vnet_state.serv_sock->ops->bind(vnet_state.serv_sock, (struct sockaddr *)&(vnet_state.serv_addr), sizeof(struct sockaddr))) < 0) {
1155 printk("Could not bind VNET server socket to port %d, error: %d\n", VNET_SERVER_PORT, err);
1159 printk("VNET server bind to port: %d\n", VNET_SERVER_PORT);
1161 if(vnet_state.serv_proto == TCP){
1162 if((err = vnet_state.serv_sock->ops->listen(vnet_state.serv_sock, 32)) < 0){
1163 printk("VNET Server error listening on port %d, error %d\n", VNET_SERVER_PORT, err);
1171 static int vnet_udp_server(void * arg) {
1172 unsigned char * pkt;
1173 struct sockaddr_in pkt_addr;
1174 struct vnet_link * link = NULL;
1177 printk("Palacios VNET Bridge: UDP receiving server ..... \n");
1179 pkt = kmalloc(MAX_PACKET_LEN, GFP_KERNEL);
1180 while (!kthread_should_stop()) {
1182 len = udp_recv(vnet_state.serv_sock, &pkt_addr, pkt, MAX_PACKET_LEN);
1184 printk("Receive error: Could not get packet, error %d\n", len);
1188 link = link_by_ip(pkt_addr.sin_addr.s_addr);
1190 printk("VNET Server: No VNET Link match the src IP\n");
1191 vnet_state.pkt_drop_phy ++;
1195 vnet_state.pkt_from_phy ++;
1196 link->bytes_rx += len;
1199 send_to_palacios(pkt, len, link->idx);
1209 static int vnet_server(void * arg) {
1211 if(vnet_state.serv_proto == UDP){
1212 vnet_udp_server(NULL);
1213 }else if(vnet_state.serv_proto == TCP) {
1214 //accept new connection
1215 //use select to receive pkt from physical network
1216 //or create new kthread to handle each connection?
1218 printk ("VNET Server: Unsupported Protocol\n");
1225 static inline unsigned int hash_fn(addr_t hdr_ptr) {
1226 return vnet_hash_buffer((uint8_t *)hdr_ptr, sizeof(uint32_t));
1229 static inline int hash_eq(addr_t key1, addr_t key2) {
1230 return (memcmp((uint8_t *)key1, (uint8_t *)key2, sizeof(uint32_t)) == 0);
1234 int palacios_init_vnet_bridge(void) {
1235 struct v3_vnet_bridge_ops bridge_ops;
1238 if(vnet_state.status != 0) {
1241 vnet_state.status = 1;
1243 memset(&vnet_state, 0, sizeof(struct palacios_vnet_state));
1245 INIT_LIST_HEAD(&(vnet_state.link_list));
1246 INIT_LIST_HEAD(&(vnet_state.route_list));
1247 spin_lock_init(&(vnet_state.lock));
1251 vnet_state.serv_proto = UDP;
1253 vnet_state.ip2link = vnet_create_htable(10, hash_fn, hash_eq);
1254 if(vnet_state.ip2link == NULL){
1255 printk("Failure to initiate VNET link hashtable\n");
1259 if(init_vnet_serv() < 0){
1260 printk("Failure to initiate VNET server\n");
1264 vnet_state.serv_thread = kthread_run(vnet_server, NULL, "vnet-server");
1266 bridge_ops.input = bridge_send_pkt;
1267 bridge_ops.poll = NULL;
1269 v3_vnet_add_bridge(NULL, &bridge_ops, HOST_LNX_BRIDGE, NULL);
1271 printk("Palacios VNET Linux Bridge initiated\n");
1277 void palacios_deinit_vnet_bridge(void){
1279 destroy_proc_files();
1281 //v3_vnet_delete_bridge(NULL, &bridge_ops, HOST_LNX_BRIDGE, NULL);
1282 kthread_stop(vnet_state.serv_thread);
1283 vnet_state.serv_sock->ops->release(vnet_state.serv_sock);
1285 deinit_links_list();
1286 deinit_routes_list();
1288 vnet_free_htable(vnet_state.ip2link, 0, 0);
1290 vnet_state.status = 0;