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.


Implementation of resource control host os interface for Linux
[palacios.git] / linux_module / palacios-vnet.c
index ad51ee5..446bd73 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 <asm/delay.h>
+#include <linux/timer.h>
+
+#include <vnet/vnet.h>
+#include "palacios.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;
-
-    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;
-};
-
-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;
+static void host_kthread_sleep(long timeout){
+    set_current_state(TASK_INTERRUPTIBLE);
 
-    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;
-       }
+    if(timeout <= 0){
+       schedule();
+    }else {
+       schedule_timeout(timeout);
     }
 
-    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_kthread_wakeup(void * thread){
+    struct task_struct * kthread = (struct task_struct *)thread;
+       
+    wake_up_process(kthread);
 }
 
-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;
-       }
-    }
+static void host_kthread_stop(void * thread){
+    struct task_struct * kthread = (struct task_struct *)thread;
 
-    return NULL;
+    while (kthread_stop(kthread)==-EINTR)
+       ;
 }
 
-
-static int parse_mac_str(char * str, uint8_t * qual, uint8_t * mac) {
-    char * token;
-
-    printk("Parsing MAC (%s)\n", str);
-
-    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;
+static int host_kthread_should_stop(void){
+    return kthread_should_stop();
 }
 
-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_udelay(unsigned long usecs){
+    udelay(usecs);
 }
 
 
 
 
-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;
 
+struct host_timer {
+    struct timer_list timer;
+    unsigned long interval;
 
-    if (*pos >= vnet_state.num_links) {
-       return NULL;
-    }
+    int active;
+    void (* timer_fun)(void * private_data);
+    void * pri_data;
+};
 
-    list_for_each_entry(link_iter, &(vnet_state.link_list), node) {
 
-       if (i == *pos) {
-           break;
-       }
+void timeout_fn(unsigned long arg){
+    struct host_timer * timer = (struct host_timer *)arg;
 
-       i++;
+    if(timer->active){
+       timer->timer_fun(timer->pri_data);
+       
+       mod_timer(&(timer->timer), timer->interval);
     }
-
-    return link_iter;
 }
 
+static void *
+host_create_timer(unsigned long interval, 
+                 void (* timer_fun)(void * priv_data), 
+                 void * data){
+    struct host_timer * timer = (struct host_timer *)palacios_alloc(sizeof(struct host_timer));
 
-
-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)) {
+    if (!timer) { 
+       ERROR("Unable to allocate timer in VNET\n");
        return NULL;
     }
 
-    *pos += 1;
-
-    return route_iter;
-}
-
+    timer->interval = interval;
+    timer->timer_fun = timer_fun;
+    timer->pri_data = data;
 
-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;
-    }
+    init_timer(&(timer->timer));
 
-    *pos += 1;
+    timer->timer.data = (unsigned long)timer;
+    timer->timer.function = timeout_fn;
+    timer->timer.expires = interval;
 
-    return link_iter;
+    return timer;
 }
 
+static void
+host_start_timer(void * vnet_timer){
+    struct host_timer * timer = (struct host_timer *)vnet_timer;
 
-static void route_seq_stop(struct seq_file * s, void * v) {
-    printk("route_seq_stop\n");
-
-    return;
+    timer->active = 1;
+    add_timer(&(timer->timer));
 }
 
+static void
+host_reset_timer(void * vnet_timer, unsigned long interval){
+    struct host_timer * timer = (struct host_timer *)vnet_timer;
 
-static void link_seq_stop(struct seq_file * s, void * v) {
-    printk("link_seq_stop\n");
-
-    return;
+    timer->interval = interval;
 }
 
-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;
-    }
-
+static void
+host_stop_timer(void * vnet_timer){
+    struct host_timer * timer = (struct host_timer *)vnet_timer;
 
-
-
-
-    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;
+    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 int link_seq_show(struct seq_file * s, void * v) {
-    struct vnet_link * link_iter = v;
+    del_timer(&(timer->timer));
 
-    seq_printf(s, "%d:\t%pI4\t%d\n", 
-              link_iter->link_idx,
-              &link_iter->dst_ip,
-              link_iter->dst_port);
-
-    return 0;
+    palacios_free(timer);
 }
 
 
-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 link_open(struct inode * inode, struct file * file) {
-    return seq_open(file, &link_seq_ops);
-}
-
-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 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;
-    }
-
-    if (copy_from_user(route_buf, buf, size)) {
-       return -EFAULT;
-    }
-
-    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;
-}
-
-
-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_allocate_pages(int num_pages, unsigned int alignment, int node_id)
+{
+    // allocates pages preferentially on the caller's node
+    return palacios_allocate_pages(num_pages, alignment, node_id, 0, 0);
 }
 
-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 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,
 
-static struct file_operations route_fops = {
-    .owner = THIS_MODULE,
-    .open = route_open, 
-    .read = seq_read,
-    .write = route_write,
-    .llseek = seq_lseek,
-    .release = seq_release
-};
+    .thread_start              = palacios_create_and_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,
 
+    .yield_cpu                 = palacios_yield_cpu,
+    .mutex_alloc               = palacios_mutex_alloc,
+    .mutex_free                        = palacios_mutex_free,
+    .mutex_lock                        = palacios_mutex_lock, 
+    .mutex_unlock              = palacios_mutex_unlock,
+    .mutex_lock_irqsave         = palacios_mutex_lock_irqsave, 
+    .mutex_unlock_irqrestore    = palacios_mutex_unlock_irqrestore,
 
-static struct file_operations link_fops = {
-    .owner = THIS_MODULE,
-    .open = link_open, 
-    .read = seq_read,
-    .write = link_write,
-    .llseek = seq_lseek,
-    .release = seq_release
+    .print                     = palacios_print_scoped,
+    .allocate_pages            = host_allocate_pages,
+    .free_pages                        = palacios_free_pages,
+    .malloc                    = palacios_alloc,
+    .free                      = palacios_free,
+    .vaddr_to_paddr            = palacios_vaddr_to_paddr,
+    .paddr_to_vaddr            = palacios_paddr_to_vaddr,
 };
 
 
-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;
-
-
-    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;
-    }
-
-    route_entry->proc_fops = &route_fops;
-
-
-    link_entry = create_proc_entry("links", 0, vnet_root);
-
-    if (link_entry == NULL) {
-       remove_proc_entry("routes", vnet_root);
-       remove_proc_entry("vnet", NULL);
-       return -1;
-    }
-
-    link_entry->proc_fops = &link_fops;
-
-    return 0;
-
-}
-
-
-
-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;
-
-    oldfs = get_fs();
-    set_fs(KERNEL_DS);
-    size = sock_sendmsg(sock, &msg, len);
-    set_fs(oldfs);
-
-    return size;
-}
-
-
-
-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);
+static int vnet_init( void ) {
+    init_vnet(&vnet_host_hooks);
        
-    set_fs(oldfs);
-    
-    return size;
-}
-
-//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
-
-    return v3_vnet_send_pkt(&pkt, NULL);;
-}
-
-
-//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 ++;
-    }
+    vnet_bridge_init();
+    vnet_ctrl_init();
 
+    INFO("V3 VNET Inited\n");
+        
     return 0;
 }
 
 
-static void 
-poll_pkt(struct v3_vm_info * vm, 
-        void * private_data) {
-
-
-}
-
-
-
-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));
+static int vnet_deinit( void ) {
 
-    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);
+    INFO("V3 Control Deinit Start\n");
 
-    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;
-    }
+    vnet_ctrl_deinit();
 
-    printk("VNET server bind to port: %d\n", VNET_UDP_PORT);
+    INFO("V3 Bridge Deinit Start\n");
 
-    return 0;
-}
+    vnet_bridge_deinit();
 
-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;
+    INFO("V3 VNET Deinit Start\n");
 
-    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;
-       }
-       
-       vnet_state.pkt_udp_recv ++;
-
-       send_to_palacios(pkt, len, link_id);
-    }
-
-    return 0;
-}
+    deinit_vnet();
 
-#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();
-    }
+    INFO("V3 VNET Deinited\n");
 
     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");
 
-    //kthread_run(profiling, NULL, "Profiling");
-
-    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");
-
-    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);