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.


added bounds checking for bitmap updates
[palacios.git] / linux_module / palacios-vnet.c
index ad51ee5..a955379 100644 (file)
 /* 
-   Palacios VNET interface
-   (c) Lei Xia, 2010
+ * Palacios VNET Host Hooks Implementations 
+ * Lei Xia 2010
  */
-#include <linux/spinlock.h>
-#include <linux/seq_file.h>
-#include <linux/proc_fs.h>
-#include <asm/uaccess.h>
-#include <linux/inet.h>
-#include <linux/kthread.h>
 
-#include <linux/netdevice.h>
-#include <linux/ip.h>
-#include <linux/in.h>
-#include <linux/string.h>
-#include <linux/preempt.h>
+#include <linux/kernel.h>
+#include <linux/kthread.h>
+#include <linux/spinlock.h>
+#include <linux/gfp.h>
 #include <linux/sched.h>
-#include <asm/msr.h>
-
-#include <palacios/vmm_vnet.h>
+#include <linux/uaccess.h>
+#include <linux/init.h>
+#include <linux/smp_lock.h>
+#include <asm/delay.h>
+#include <linux/timer.h>
+
+#include <vnet/vnet.h>
+#include "mm.h"
 #include "palacios-vnet.h"
+#include "linux-exts.h"
 
-//#define DEBUG_VNET_BRIGE
-
-#define VNET_UDP_PORT 9000
-
-struct vnet_route {
-    struct v3_vnet_route route;
-
-    int route_idx;
+static void host_print(const char *    fmt, ...) {
 
-    struct list_head node;
-};
-
-
-struct vnet_link {
-    uint32_t dst_ip;
-    uint16_t dst_port;
-    
-    struct socket * sock;
-    struct sockaddr_in sock_addr;
-
-    int link_idx;
-
-    struct list_head node;
-};
+    va_list ap;
+    va_start(ap, fmt);
+    vprintk(fmt, ap);
+    va_end(ap);
 
-struct palacios_vnet_state {
-    uint32_t num_routes;
-    uint32_t num_links; 
-
-    struct list_head route_list;
-    struct list_head link_list;
-
-    struct socket * serv_sock;
-    struct sockaddr_in serv_addr;
-
-    /* The thread recving pkts from sockets. */
-    struct task_struct * serv_thread;
-    spinlock_t lock;
-
-    unsigned long pkt_sent, pkt_recv, pkt_drop, pkt_udp_recv, pkt_udp_send;
-};
-
-
-static struct palacios_vnet_state vnet_state;
-
-
-struct vnet_link * find_link_by_ip(uint32_t ip) {
-    struct vnet_link * link = NULL;
-
-    list_for_each_entry(link, &(vnet_state.link_list), node) {
-
-       if (link->dst_ip == ip) {
-           return link;
-       }
-    }
-
-    return NULL;
+    return;
 }
 
-struct vnet_link * find_link_by_idx(int idx) {
-    struct vnet_link * link = NULL;
 
-    list_for_each_entry(link, &(vnet_state.link_list), node) {
-
-       if (link->link_idx == idx) {
-           return link;
-       }
-    }
-    return NULL;
+static void * host_allocate_pages(int num_pages, unsigned int alignment){
+    uintptr_t addr = 0; 
+    struct page * pgs = NULL;
+    int order = get_order(num_pages * PAGE_SIZE);
+        
+    pgs = alloc_pages(GFP_KERNEL, order);
+    
+    WARN(!pgs, "Could not allocate pages\n");
+       
+    addr = page_to_pfn(pgs) << PAGE_SHIFT; 
+   
+    return (void *)addr;
 }
 
-struct vnet_route * find_route_by_idx(int idx) {
-    struct vnet_route * route = NULL;
-
-    list_for_each_entry(route, &(vnet_state.route_list), node) {
 
-       if (route->route_idx == idx) {
-           return route;
-       }
-    }
-
-    return NULL;
+static void host_free_pages(void * page_paddr, int num_pages) {
+    uintptr_t pg_addr = (uintptr_t)page_paddr;
+       
+    __free_pages(pfn_to_page(pg_addr >> PAGE_SHIFT), get_order(num_pages * PAGE_SIZE));
 }
 
 
-static int parse_mac_str(char * str, uint8_t * qual, uint8_t * mac) {
-    char * token;
-
-    printk("Parsing MAC (%s)\n", str);
+static void *
+host_alloc(unsigned int size) {
+    void * addr;
+    addr =  kmalloc(size, GFP_KERNEL);
 
-    if (strstr(str, "-")) {
-       token = strsep(&str, "-");
-
-       if (strnicmp("not", token, strlen("not")) == 0) {
-           *qual = MAC_NOT;
-       } else {
-           printk("Invalid MAC String token (%s)\n", token);
-           return -1;
-       }
-    }
-
-    if (!strstr(str, ":")) {
-       if (strnicmp("any", str, strlen("any")) == 0) {
-           printk("qual = any\n");
-           *qual = MAC_ANY;
-       } else if (strnicmp("none", str, strlen("none")) == 0) {
-           printk("qual = None\n");
-           *qual = MAC_NONE;
-       } else {
-           printk("Invalid MAC Qual token (%s)\n", str);
-           return -1;
-       }
-
-    } else {
-       int i = 0;
-
-       *qual = MAC_ADDR;
-
-       for (i = 0; i < 6; i++) {
-           token = strsep(&str, ":");
-           mac[i] = simple_strtol(token, &token, 16);
-       }
-    }
-
-    return 0;
+    return addr;
 }
 
-static int parse_route_str(char * str, struct v3_vnet_route * route) {
-    char * token = NULL;
-    struct vnet_link *link = NULL;
-
-    // src MAC
-    token = strsep(&str, " ");
-
-    if (!token) {
-       return -1;
-    }
-
-    parse_mac_str(token, &(route->src_mac_qual), route->src_mac);
-
-    // dst MAC
-    token = strsep(&str, " ");
-
-    if (!token) {
-       return -1;
-    }
-
-    parse_mac_str(token, &(route->dst_mac_qual), route->dst_mac);
-
-    // dst LINK type
-    token = strsep(&str, " ");
-
-    if (!token) {
-       return -1;
-    }
-    
-    if (strnicmp("interface", token, strlen("interface")) == 0) {
-       route->dst_type = LINK_INTERFACE;
-       printk("DST type = INTERFACE\n");
-    } else if (strnicmp("edge", token, strlen("edge")) == 0) {
-       route->dst_type = LINK_EDGE;
-       printk("DST type = EDGE\n");
-    } else {
-       printk("Invalid Destination Link Type (%s)\n", token);
-       return -1;
-    }
-
-
-    // dst link ID
-    token = strsep(&str, " ");
-
-    if (!token) {
-       return -1;
-    }
-
-    printk("dst link ID=%s\n", token);
-
-    // Figure out link ID here
-    if (route->dst_type == LINK_EDGE) {
-       uint32_t link_ip;
-
-
-       // Figure out Link Here
-       if (in4_pton(token, strlen(token), (uint8_t *)&(link_ip), '\0', NULL) != 1) {
-           printk("Invalid Dst IP address (%s)\n", token);
-           return -EFAULT;
-       }
-
-
-       printk("link_ip = %d\n", link_ip);
-       link = find_link_by_ip(link_ip);
-       if (link != NULL){
-           route->dst_id = link->link_idx;
-       }else{
-           printk("can not find dst link %s\n", token);
-           return -1;
-       }
-    } else {
-       printk("Unsupported dst link type\n");
-       return -1;
-    }
-
-    // src LINK
-    token = strsep(&str, " ");
-
-    printk("SRC type = %s\n", token);
-
-    if (!token) {
-       return -1;
-    }
-
-    if (strnicmp("interface", token, strlen("interface")) == 0) {
-       route->src_type = LINK_INTERFACE;
-       printk("SRC type = INTERFACE\n");
-    } else if (strnicmp("edge", token, strlen("edge")) == 0) {
-       route->src_type = LINK_EDGE;
-       printk("SRC type = EDGE\n");
-    } else if (strnicmp("any", token, strlen("any")) == 0) {
-       route->src_type = LINK_ANY;
-       printk("SRC type = ANY\n");
-    } else {
-       printk("Invalid Src link type (%s)\n", token);
-       return -1;
-    }
-
-
-    if (route->src_type == LINK_ANY) {
-       route->src_id = (uint32_t)-1;
-    } else if (route->src_type == LINK_EDGE) {
-       uint32_t src_ip;
-       token = strsep(&str, " ");
-
-       if (!token) {
-           return -1;
-       }
-
-       // Figure out Link Here
-       if (in4_pton(token, strlen(token), (uint8_t *)&(src_ip), '\0', NULL) != 1) {
-           printk("Invalid SRC IP address (%s)\n", token);
-           return -EFAULT;
-       }
-
-       link = find_link_by_ip(src_ip);
-       if (link != NULL){
-           route->src_id = link->link_idx;
-       }else{
-           printk("can not find src link %s\n", token);
-           return -1;
-       }
-    } else {
-       printk("Invalid link type\n");
-       return -1;
-    }
-
-
-    return 0;
+static void
+host_free(
+       void *                  addr
+)
+{
+    kfree(addr);
+    return;
 }
 
+static void *
+host_vaddr_to_paddr(void * vaddr)
+{
+    return (void*) __pa(vaddr);
 
-
-
-static void * route_seq_start(struct seq_file * s, loff_t * pos) {
-    struct vnet_route * route_iter = NULL;
-    loff_t i = 0;
-
-
-    if (*pos >= vnet_state.num_routes) {
-       return NULL;
-    }
-
-    list_for_each_entry(route_iter, &(vnet_state.route_list), node) {
-
-       if (i == *pos) {
-           break;
-       }
-
-       i++;
-    }
-
-    return route_iter;
 }
 
-
-static void * link_seq_start(struct seq_file * s, loff_t * pos) {
-    struct vnet_link * link_iter = NULL;
-    loff_t i = 0;
-
-
-    if (*pos >= vnet_state.num_links) {
-       return NULL;
-    }
-
-    list_for_each_entry(link_iter, &(vnet_state.link_list), node) {
-
-       if (i == *pos) {
-           break;
-       }
-
-       i++;
-    }
-
-    return link_iter;
+static void *
+host_paddr_to_vaddr(void * paddr)
+{
+    return __va(paddr);
 }
 
 
+static void *
+host_start_kernel_thread(
+       int (*fn)(void * arg),
+       void * arg,
+       char * thread_name) {
+    struct task_struct * thread = NULL;
 
-static void * route_seq_next(struct seq_file * s, void * v, loff_t * pos) {
-    struct vnet_route * route_iter = NULL;
-
-    route_iter = list_entry(((struct vnet_route *)v)->node.next, struct vnet_route, node);
-
-    // Check if the list has looped
-    if (&(route_iter->node) == &(vnet_state.route_list)) {
-       return NULL;
-    }
-
-    *pos += 1;
+    thread = kthread_run(fn, arg, thread_name );
 
-    return route_iter;
+    return thread;
 }
 
+static void host_kthread_sleep(long timeout){
+    set_current_state(TASK_INTERRUPTIBLE);
 
-static void * link_seq_next(struct seq_file * s, void * v, loff_t * pos) {
-    struct vnet_link * link_iter = NULL;
-
-    link_iter = list_entry(((struct vnet_link *)v)->node.next, struct vnet_link, node);
-
-    // Check if the list has looped
-    if (&(link_iter->node) == &(vnet_state.link_list)) {
-       return NULL;
+    if(timeout <= 0){
+       schedule();
+    }else {
+       schedule_timeout(timeout);
     }
 
-    *pos += 1;
-
-    return link_iter;
-}
-
-
-static void route_seq_stop(struct seq_file * s, void * v) {
-    printk("route_seq_stop\n");
-
-    return;
-}
-
-
-static void link_seq_stop(struct seq_file * s, void * v) {
-    printk("link_seq_stop\n");
-
     return;
 }
 
-static int route_seq_show(struct seq_file * s, void * v) {
-    struct vnet_route * route_iter = v;
-    struct v3_vnet_route * route = &(route_iter->route);
-
-
-    seq_printf(s, "%d:\t", route_iter->route_idx);
-
-    switch (route->src_mac_qual) {
-       case MAC_ANY:
-           seq_printf(s, "any ");
-           break;
-       case MAC_NONE:
-           seq_printf(s, "none ");
-           break;
-       case MAC_NOT:
-           seq_printf(s, "not-%x:%x:%x:%x:%x:%x ", 
-                      route->src_mac[0], route->src_mac[1], route->src_mac[2],
-                      route->src_mac[3], route->src_mac[4], route->src_mac[5]);
-           break;
-       default:
-           seq_printf(s, "%x:%x:%x:%x:%x:%x ", 
-                      route->src_mac[0], route->src_mac[1], route->src_mac[2],
-                      route->src_mac[3], route->src_mac[4], route->src_mac[5]);
-           break;
-    }
-
-    switch (route->dst_mac_qual) {
-       case MAC_ANY:
-           seq_printf(s, "any ");
-           break;
-       case MAC_NONE:
-           seq_printf(s, "none ");
-           break;
-       case MAC_NOT:
-           seq_printf(s, "not-%x:%x:%x:%x:%x:%x ", 
-                      route->src_mac[0], route->src_mac[1], route->src_mac[2],
-                      route->src_mac[3], route->src_mac[4], route->src_mac[5]);
-           break;
-       default:
-           seq_printf(s, "%x:%x:%x:%x:%x:%x ", 
-                      route->src_mac[0], route->src_mac[1], route->src_mac[2],
-                      route->src_mac[3], route->src_mac[4], route->src_mac[5]);
-           break;
-    }
-
-
-    switch (route->dst_type) {
-       case LINK_EDGE: {
-           struct vnet_link * link = (struct vnet_link *)find_link_by_idx(route->dst_id);
-           seq_printf(s, "EDGE %pI4", &link->dst_ip);
-           break;
-       }
-       case LINK_INTERFACE: {
-           seq_printf(s, "INTERFACE ");
-           seq_printf(s, "%d ", route->dst_id);
-           break;
-       }
-       default:
-           seq_printf(s, "Invalid Dst Link Type (%d) ", route->dst_type);
-           break;
-    }
-
-
-
-
-
-    switch (route->src_type) {
-       case LINK_EDGE: {
-           struct vnet_link * link = (struct vnet_link *)find_link_by_idx(route->src_id);
-           seq_printf(s, "EDGE %pI4", &link->dst_ip);
-           break;
-       }
-       case LINK_INTERFACE: {
-           seq_printf(s, "INTERFACE %d", route->src_id);
-           break;
-       }
-       case LINK_ANY:
-           seq_printf(s, "ANY");
-           break;
-       default:
-           seq_printf(s, "Invalid Src Link Type (%d) ", route->src_type);
-           break;
-    }
-
-
-    seq_printf(s, "\n");
-
-    return 0;
+static void host_kthread_wakeup(void * thread){
+    struct task_struct * kthread = (struct task_struct *)thread;
+       
+    wake_up_process(kthread);
 }
 
+static void host_kthread_stop(void * thread){
+    struct task_struct * kthread = (struct task_struct *)thread;
 
-static int link_seq_show(struct seq_file * s, void * v) {
-    struct vnet_link * link_iter = v;
-
-    seq_printf(s, "%d:\t%pI4\t%d\n", 
-              link_iter->link_idx,
-              &link_iter->dst_ip,
-              link_iter->dst_port);
-
-    return 0;
+    kthread_stop(kthread);
 }
 
-
-static struct seq_operations route_seq_ops = {
-    .start = route_seq_start, 
-    .next = route_seq_next,
-    .stop = route_seq_stop,
-    .show = route_seq_show
-};
-
-
-static struct seq_operations link_seq_ops = {
-    .start = link_seq_start,
-    .next = link_seq_next,
-    .stop = link_seq_stop,
-    .show = link_seq_show
-};
-
-
-static int route_open(struct inode * inode, struct file * file) {
-    return seq_open(file, &route_seq_ops);
+static int host_kthread_should_stop(void){
+    return kthread_should_stop();
 }
 
 
-static int link_open(struct inode * inode, struct file * file) {
-    return seq_open(file, &link_seq_ops);
+static void host_udelay(unsigned long usecs){
+    udelay(usecs);
 }
 
-static int inject_route(struct vnet_route * route) {
-    v3_vnet_add_route(route->route);
 
-    printk("Palacios-vnet: One route added to VNET core\n");
 
-    return 0;
+static void
+host_yield_cpu(void)
+{
+    schedule();
+    return;
 }
 
-static ssize_t 
-route_write(struct file * file, 
-           const char * buf, 
-           size_t size, 
-           loff_t * ppos) {
-    char route_buf[256];
-    char * buf_iter = NULL;
-    char * line_str = route_buf;
-    char * token = NULL;
-
-    if (size >= 256) {
-       return -EFAULT;
-    }
+static void *
+host_mutex_alloc(void)
+{
+    spinlock_t * lock = kmalloc(sizeof(spinlock_t), GFP_KERNEL);
 
-    if (copy_from_user(route_buf, buf, size)) {
-       return -EFAULT;
+    if (lock) {
+       spin_lock_init(lock);
     }
 
-    printk("Route written: %s\n", route_buf);
-
-    while ((buf_iter = strsep(&line_str, "\r\n"))) {
-
-       token = strsep(&buf_iter, " ");
-       if (!token) {
-           return -EFAULT;
-       }
-       
-       if (strnicmp("ADD", token, strlen("ADD")) == 0) {
-           struct vnet_route * new_route = NULL;
-           new_route = kmalloc(sizeof(struct vnet_route), GFP_KERNEL);
-           
-           if (!new_route) {
-               return -ENOMEM;
-           }
-           
-           memset(new_route, 0, sizeof(struct vnet_route));
-           
-           if (parse_route_str(buf_iter, &(new_route->route)) == -1) {
-               kfree(new_route);
-               return -EFAULT;
-           }
-           
-           if (inject_route(new_route) != 0) {
-               return -EFAULT;
-           }
-       } else if (strnicmp("DEL", token, strlen("DEL")) == 0) {
-           printk("I should delete the route here\n");
-       } else {
-           printk("Invalid Route command string\n");
-       }
-    }
-
-    return size;
+    return lock;
 }
 
-
-static int create_link(struct vnet_link * link) {
-    int err;
-    unsigned long flags;
-
-    if ( (err = sock_create(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &link->sock)) < 0) {
-       printk("Could not create socket\n");
-       return -1;
-    }
-
-    memset(&link->sock_addr, 0, sizeof(struct sockaddr));
-
-    link->sock_addr.sin_family = AF_INET;
-    link->sock_addr.sin_addr.s_addr = link->dst_ip;
-    link->sock_addr.sin_port = htons(link->dst_port);
-
-    if ((err = link->sock->ops->connect(link->sock, (struct sockaddr *)&(link->sock_addr), sizeof(struct sockaddr), 0) < 0)) {
-       printk("Could not connect to remote host\n");
-       return -1;
-    }
-
-    // We use the file pointer because we are in the kernel
-    // This is only used to assigned File Descriptors for user space, so it is available here
-    // link->sock->file = link;
-
-    spin_lock_irqsave(&(vnet_state.lock), flags);
-    list_add(&(link->node), &(vnet_state.link_list));
-    link->link_idx = vnet_state.num_links++;
-    spin_unlock_irqrestore(&(vnet_state.lock), flags);
-
-    printk("VNET Bridge: Link created, ip %d, port: %d, idx: %d, link: %p\n", 
-          link->dst_ip, 
-          link->dst_port, 
-          link->link_idx, 
-          link);
-
-    return 0;
+static void
+host_mutex_free(
+       void * mutex
+) 
+{
+    kfree(mutex);
 }
 
-static ssize_t 
-link_write(struct file * file, const char * buf, size_t size, loff_t * ppos) {
-    char link_buf[256];
-    char * link_iter = NULL;
-    char * line_str = link_buf;
-    char * token = NULL;
-
-    if (size >= 256) {
-       return -EFAULT;
-    }
-
-    if (copy_from_user(link_buf, buf, size)) {
-       return -EFAULT;
-    }
-
-    while ((link_iter = strsep(&line_str, "\r\n"))) {
-       printk("Link written: %s\n", link_buf);
-       
-       token = strsep(&link_iter, " ");
-       
-       if (!token) {
-           return -EFAULT;
-       }
-       
-       if (strnicmp("ADD", token, strlen("ADD")) == 0) {
-           struct vnet_link * new_link = NULL;
-           char * ip_str = NULL;
-           uint32_t ip;
-           
-           ip_str = strsep(&link_iter, " ");
-           
-           if ((!ip_str) || (!link_iter)) {
-               printk("Missing fields in ADD Link command\n");
-               return -EFAULT;
-           }
-           
-           if (in4_pton(ip_str, strlen(ip_str), (uint8_t *)&(ip), '\0', NULL) != 1) {
-               printk("Invalid Dst IP address (%s)\n", ip_str);
-               return -EFAULT;
-           }
-
-           new_link = kmalloc(sizeof(struct vnet_link), GFP_KERNEL);
-
-           if (!new_link) {
-               return -ENOMEM;
-           }
-
-           memset(new_link, 0, sizeof(struct vnet_link));
-
-           new_link->dst_ip = ip;
-           new_link->dst_port = simple_strtol(link_iter, &link_iter, 10);
-           
-           if (create_link(new_link) != 0) {
-               printk("Could not create link\n");
-               kfree(new_link);
-               return -EFAULT;
-           }
-
-       } else if (strnicmp("DEL", token, strlen("DEL")) == 0) {
-           printk("Link deletion not supported\n");
-       } else {
-           printk("Invalid Link command string\n");
-       }
-    }
-
-    return size;
+static void 
+host_mutex_lock(void * mutex, 
+               int must_spin)
+{
+    spin_lock((spinlock_t *)mutex);
 }
 
-
-static struct file_operations route_fops = {
-    .owner = THIS_MODULE,
-    .open = route_open, 
-    .read = seq_read,
-    .write = route_write,
-    .llseek = seq_lseek,
-    .release = seq_release
-};
-
-
-static struct file_operations link_fops = {
-    .owner = THIS_MODULE,
-    .open = link_open, 
-    .read = seq_read,
-    .write = link_write,
-    .llseek = seq_lseek,
-    .release = seq_release
-};
-
-
-static int init_proc_files(void) {
-    struct proc_dir_entry * route_entry = NULL;
-    struct proc_dir_entry * link_entry = NULL;
-    struct proc_dir_entry * vnet_root = NULL;
+static void 
+host_mutex_unlock(void * mutex) 
+{
+    spin_unlock((spinlock_t *)mutex);
+}
 
 
-    vnet_root = proc_mkdir("vnet", NULL);
-    if (vnet_root == NULL) {
-       return -1;
-    }
 
-    route_entry = create_proc_entry("routes", 0, vnet_root);
 
-    if (route_entry == NULL) {
-       remove_proc_entry("vnet", NULL);
-       return -1;
-    }
+struct host_timer {
+    struct timer_list timer;
+    unsigned long interval;
 
-    route_entry->proc_fops = &route_fops;
+    int active;
+    void (* timer_fun)(void * private_data);
+    void * pri_data;
+};
 
 
-    link_entry = create_proc_entry("links", 0, vnet_root);
+void timeout_fn(unsigned long arg){
+    struct host_timer * timer = (struct host_timer *)arg;
 
-    if (link_entry == NULL) {
-       remove_proc_entry("routes", vnet_root);
-       remove_proc_entry("vnet", NULL);
-       return -1;
+    if(timer->active){
+       timer->timer_fun(timer->pri_data);
+       
+       mod_timer(&(timer->timer), timer->interval);
     }
-
-    link_entry->proc_fops = &link_fops;
-
-    return 0;
-
 }
 
+static void *
+host_create_timer(unsigned long interval, 
+                 void (* timer_fun)(void * priv_data), 
+                 void * data){
+    struct host_timer * timer = (struct host_timer *)kmalloc(sizeof(struct host_timer), GFP_KERNEL);
 
+    timer->interval = interval;
+    timer->timer_fun = timer_fun;
+    timer->pri_data = data;
 
-static int 
-udp_send(struct socket * sock, 
-        struct sockaddr_in * addr,
-        unsigned char * buf,  int len) {
-    struct msghdr msg;
-    struct iovec iov;
-    mm_segment_t oldfs;
-    int size = 0;
-
-         
-    if (sock->sk == NULL) {
-       return 0;
-    }
-
-    iov.iov_base = buf;
-    iov.iov_len = len;
-
-    msg.msg_flags = 0;
-    msg.msg_name = addr;
-    msg.msg_namelen = sizeof(struct sockaddr_in);
-    msg.msg_control = NULL;
-    msg.msg_controllen = 0;
-    msg.msg_iov = &iov;
-    msg.msg_iovlen = 1;
-    msg.msg_control = NULL;
+    init_timer(&(timer->timer));
 
-    oldfs = get_fs();
-    set_fs(KERNEL_DS);
-    size = sock_sendmsg(sock, &msg, len);
-    set_fs(oldfs);
+    timer->timer.data = (unsigned long)timer;
+    timer->timer.function = timeout_fn;
+    timer->timer.expires = interval;
 
-    return size;
+    return timer;
 }
 
+static void
+host_start_timer(void * vnet_timer){
+    struct host_timer * timer = (struct host_timer *)vnet_timer;
 
-
-static int 
-udp_recv(struct socket * sock, 
-        struct sockaddr_in * addr,
-        unsigned char * buf, int len) {
-    struct msghdr msg;
-    struct iovec iov;
-    mm_segment_t oldfs;
-    int size = 0;
-    
-    if (sock->sk == NULL) {
-       return 0;
-    }
-
-    iov.iov_base = buf;
-    iov.iov_len = len;
-    
-    msg.msg_flags = 0;
-    msg.msg_name = addr;
-    msg.msg_namelen = sizeof(struct sockaddr_in);
-    msg.msg_control = NULL;
-    msg.msg_controllen = 0;
-    msg.msg_iov = &iov;
-    msg.msg_iovlen = 1;
-    msg.msg_control = NULL;
-    
-    oldfs = get_fs();
-    set_fs(KERNEL_DS);
-    size = sock_recvmsg(sock, &msg, len, msg.msg_flags);
-       
-    set_fs(oldfs);
-    
-    return size;
+    timer->active = 1;
+    add_timer(&(timer->timer));
 }
 
-//send packets from Network to VNET core
-static int 
-send_to_palacios(unsigned char * buf, 
-                int len,
-                int link_id){
-    struct v3_vnet_pkt pkt;
-    pkt.size = len;
-    pkt.src_type = LINK_EDGE;
-    pkt.src_id = link_id;
-    memcpy(pkt.header, buf, ETHERNET_HEADER_LEN);
-    pkt.data = buf;
-
-#ifdef DEBUG_VNET_BRIGE
-    {
-       printk("VNET Lnx Bridge: send pkt to VNET core (size: %d, src_id: %d, src_type: %d)\n", 
-                       pkt.size,  pkt.src_id, pkt.src_type);
-
-       print_hex_dump(NULL, "pkt_data: ", 0, 20, 20, pkt.data, pkt.size, 0);
-    }
-#endif
+static void
+host_reset_timer(void * vnet_timer, unsigned long interval){
+    struct host_timer * timer = (struct host_timer *)timer;
 
-    return v3_vnet_send_pkt(&pkt, NULL);;
+    timer->interval = interval;
 }
 
+static void
+host_stop_timer(void * vnet_timer){
+    struct host_timer * timer = (struct host_timer *)vnet_timer;
 
-//send packet from VNET core to Network
-static int 
-bridge_send_pkt(struct v3_vm_info * vm, 
-               struct v3_vnet_pkt * pkt, 
-               void * private_data) {
-    struct vnet_link * link;
-
-    #ifdef DEBUG_VNET_BRIGE
-          {
-               printk("VNET Lnx Host Bridge: packet received from VNET Core ... len: %d, pkt size: %d, link: %d\n",
-                       len,
-                       pkt->size,
-                       pkt->dst_id);
-
-               print_hex_dump(NULL, "pkt_data: ", 0, 20, 20, pkt->data, pkt->size, 0);
-          }
-    #endif
-
-    vnet_state.pkt_recv ++;
-
-    link = find_link_by_idx(pkt->dst_id);
-    if (link != NULL) {
-       udp_send(link->sock, &(link->sock_addr), pkt->data, pkt->size);
-       vnet_state.pkt_udp_send ++;
-    } else {
-       printk("VNET Bridge Linux Host: wrong dst link, idx: %d, discards the packet\n", pkt->dst_id);
-       vnet_state.pkt_drop ++;
-    }
-
-    return 0;
+    timer->active = 0;
+    del_timer(&(timer->timer));
 }
 
+static void
+host_del_timer(void * vnet_timer){
+    struct host_timer * timer = (struct host_timer *)vnet_timer;
 
-static void 
-poll_pkt(struct v3_vm_info * vm, 
-        void * private_data) {
-
+    del_timer(&(timer->timer));
 
+    kfree(timer);
 }
 
 
 
-static int init_vnet_serv(void) {
-     
-    if (sock_create(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &vnet_state.serv_sock) < 0) {
-       printk("Could not create socket\n");
-       return -1;
-    }
 
-    memset(&vnet_state.serv_addr, 0, sizeof(struct sockaddr));
 
-    vnet_state.serv_addr.sin_family = AF_INET;
-    vnet_state.serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
-    vnet_state.serv_addr.sin_port = htons(VNET_UDP_PORT);
+static struct vnet_host_hooks vnet_host_hooks = {
+    .timer_create      = host_create_timer,
+    .timer_del         = host_del_timer,
+    .timer_start               = host_start_timer,
+    .timer_stop                = host_stop_timer,
+    .timer_reset       = host_reset_timer,
 
-    if (vnet_state.serv_sock->ops->bind(vnet_state.serv_sock, (struct sockaddr *)&(vnet_state.serv_addr), sizeof(struct sockaddr)) < 0) {
-       printk("Could not bind VNET server socket to port %d\n", VNET_UDP_PORT);
-       return -1;
-    }
+    .thread_start      = host_start_kernel_thread,
+    .thread_sleep      = host_kthread_sleep,
+    .thread_wakeup     = host_kthread_wakeup,
+    .thread_stop       = host_kthread_stop,
+    .thread_should_stop        = host_kthread_should_stop,
+    .udelay    = host_udelay,
 
-    printk("VNET server bind to port: %d\n", VNET_UDP_PORT);
+    .yield_cpu         = host_yield_cpu,
+    .mutex_alloc       = host_mutex_alloc,
+    .mutex_free        = host_mutex_free,
+    .mutex_lock        = host_mutex_lock, 
+    .mutex_unlock      = host_mutex_unlock,
 
-    return 0;
-}
+    .print                     = host_print,
+    .allocate_pages    = host_allocate_pages,
+    .free_pages        = host_free_pages,
+    .malloc            = host_alloc,
+    .free                      = host_free,
+    .vaddr_to_paddr            = host_vaddr_to_paddr,
+    .paddr_to_vaddr            = host_paddr_to_vaddr,
+};
 
-static int vnet_server(void * arg) {
-    unsigned char pkt[ETHERNET_PACKET_LEN];
-    struct sockaddr_in pkt_addr;
-    struct vnet_link *link = NULL;
-    int len;
-    int link_id;
 
-    printk("Palacios VNET Bridge: UDP receiving server ..... \n");
 
-    while (!kthread_should_stop()) {
-       
-       len = udp_recv(vnet_state.serv_sock, &pkt_addr, pkt, ETHERNET_PACKET_LEN); 
-       if(len < 0) {
-           printk("Receive error: Could not get packet, error %d\n", len);
-           continue;
-       }
-
-       link = find_link_by_ip(ntohl(pkt_addr.sin_addr.s_addr));
-       if (link != NULL){
-           link_id= link->link_idx;
-       }
-       else { 
-           link_id= 0;
-       }
+static int vnet_init( void ) {
+    init_vnet(&vnet_host_hooks);
        
-       vnet_state.pkt_udp_recv ++;
-
-       send_to_palacios(pkt, len, link_id);
-    }
+    vnet_bridge_init();
+    vnet_ctrl_init();
 
+    printk("V3 VNET Inited\n");
+        
     return 0;
 }
 
-#if 0
-static int profiling(void *args) {
-   static unsigned long long last_time=0;
-   unsigned long long cur_time=0;
-   set_user_nice(current, MAX_PRIO-1);
-
-   while (!kthread_should_stop()) {
-       rdtscll(cur_time);
-       if((cur_time - last_time) > 50000000000) {
-           last_time = cur_time;
-           printk("Palacios Linux VNET Bridge - profiling: sent: %ld, rxed: %ld, dropped: %ld, upd send: %ld, udp recv: %ld\n",
-                  vnet_state.pkt_sent,
-                  vnet_state.pkt_recv,
-                  vnet_state.pkt_drop,
-                  vnet_state.pkt_udp_send,
-                  vnet_state.pkt_udp_recv);
-       }
-       schedule();
-    }
-
-    return 0;
-}
-#endif
-
-int  palacios_init_vnet(void) {
-    struct v3_vnet_bridge_ops bridge_ops;
-       
-    memset(&vnet_state, 0, sizeof(struct palacios_vnet_state));
-
-    INIT_LIST_HEAD(&(vnet_state.link_list));
-    INIT_LIST_HEAD(&(vnet_state.route_list));
-    spin_lock_init(&(vnet_state.lock));
-
-    init_proc_files();
-    if(init_vnet_serv() < 0){
-       printk("Failure to initiate VNET server\n");
-       return -1;
-    }
 
-    vnet_state.serv_thread = kthread_run(vnet_server, NULL, "vnet-server");
+static int vnet_deinit( void ) {
+    deinit_vnet();
 
-    //kthread_run(profiling, NULL, "Profiling");
+    vnet_bridge_deinit();
+    vnet_ctrl_deinit();
 
-    bridge_ops.input = bridge_send_pkt;
-    bridge_ops.poll = poll_pkt;
-       
-    v3_vnet_add_bridge(NULL, &bridge_ops, HOST_LNX_BRIDGE, NULL);
-
-    printk("Palacios VNET Linux Bridge initiated\n");
+    printk("V3 VNET Deinited\n");
 
     return 0;
 }
 
+static struct linux_ext vnet_ext = {
+    .name = "VNET",
+    .init = vnet_init,
+    .deinit = vnet_deinit,
+    .guest_init = NULL,
+    .guest_deinit = NULL
+};
+
+register_extension(&vnet_ext);