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.


add the virtual console input as a host event
[palacios.git] / palacios / src / palacios / vmm_vnet.c
index e7a1a8d..e263735 100644 (file)
@@ -7,7 +7,7 @@
  * and the University of New Mexico.  You can find out more at 
  * http://www.v3vee.org
  *
- * Copyright (c) 2009, Lei Xia <lxia@northwestern.edu> 
+ * Copyright (c) 2010, Lei Xia <lxia@northwestern.edu> 
  * Copyright (c) 2009, Yuan Tang <ytang@northwestern.edu>  
  * Copyright (c) 2009, The V3VEE Project <http://www.v3vee.org> 
  * All rights reserved.
  */
  
 #include <palacios/vmm_vnet.h>
-#include <palacios/vmm_hypercall.h>
 #include <palacios/vm_guest_mem.h>
 #include <palacios/vmm_lock.h>
+#include <palacios/vmm_queue.h>
+#include <palacios/vmm_sprintf.h>
 
 #ifndef CONFIG_DEBUG_VNET
 #undef PrintDebug
 #endif
 
 
-#define ETHERNET_HEADER_LEN 14
-#define ETHERNET_DATA_MIN   46
-#define ETHERNET_DATA_MAX   1500
-#define ETHERNET_PACKET_LEN (ETHERNET_HEADER_LEN + ETHERNET_DATA_MAX)
-
-
-typedef enum {TCP_TYPE, UDP_TYPE, NONE_TYPE} prot_type_t;
-
-#define VNET_INITAB_HCALL 0xca00
-
+/* for UDP encapuslation */
 struct eth_header {
     uchar_t dest[6];
     uchar_t src[6];
-    uint16_t type; // indicates layer 3 protocol type
+    uint16_t type;
 }__attribute__((packed));
 
 struct ip_header {
@@ -73,771 +65,684 @@ struct udp_link_header {
     struct ip_header ip_hdr;
     struct udp_header udp_hdr;
 }__attribute__((packed));
+/* end with UDP encapuslation structures */
 
 
-struct ethernet_pkt {
-    uint32_t size; //size of data field
-    uint16_t type;
-    uint8_t use_header;
-    struct udp_link_header ext_hdr;
-    char data[ETHERNET_PACKET_LEN];
-}__attribute__((packed));
 
 
-#define DEVICE_NAME_LEN 20
-struct vnet_if_device {
-    char name[DEVICE_NAME_LEN];
-    uchar_t mac_addr[6];
-    struct v3_vm_info *vm;
-    
-    int (*input)(struct v3_vm_info *vm, uchar_t *data, uint32_t len, void *private_data);
-    
-    void *private_data;
-}__attribute__((packed));
+struct eth_hdr {
+    uint8_t dst_mac[6];
+    uint8_t src_mac[6];
+    uint16_t type; /* indicates layer 3 protocol type */
+} __attribute__((packed));
 
-struct vnet_if_link {
-    prot_type_t pro_type; //transport layer protocal type of this link
-    unsigned long dest_ip;
-    uint16_t dest_port;
 
-    struct udp_link_header vnet_header; //header applied to the packet in/out from this link
+struct vnet_dev {
+    int dev_id;
+    uint8_t mac_addr[6];
+    struct v3_vm_info * vm;
+    struct v3_vnet_dev_ops dev_ops;
+    void * private_data;
 
-    int (*input)(uchar_t *data, uint32_t len, void *private_data);
+    int rx_disabled;
     
-    void *private_data;
-}__attribute__((packed));
+    struct list_head node;
+} __attribute__((packed));
 
 
-struct link_entry {
-    link_type_t type;
-  
-    union {
-       struct vnet_if_device *dst_dev;
-       struct vnet_if_link *dst_link;
-    } __attribute__((packed));
+struct vnet_brg_dev {
+    struct v3_vm_info * vm;
+    struct v3_vnet_bridge_ops brg_ops;
 
-    int use;
-}__attribute__((packed));
+    int disabled;
+    void * private_data;
+} __attribute__((packed));
 
-//routing table entry
-struct routing_entry {
-    char src_mac[6];
-    char dest_mac[6];
 
-    mac_type_t src_mac_qual;
-    mac_type_t dest_mac_qual;
 
-    int link_idx; //link[dest] is the link to be used to send pkt
-    link_type_t link_type; //EDGE|INTERFACE|ANY
-    int src_link_idx;
-    link_type_t src_type; //EDGE|INTERFACE|ANY
+struct vnet_route_info {
+    struct v3_vnet_route route_def;
+
+    struct vnet_dev * dst_dev;
+    struct vnet_dev * src_dev;
+
+    struct list_head node;
+    struct list_head match_node; // used for route matching
 };
 
 
-// 14 (ethernet frame) + 20 bytes
-struct in_pkt_header {
-    uchar_t ethernetdest[6];
-    uchar_t ethernetsrc[6];
-    uchar_t ethernettype[2]; //layer 3 protocol type
-    char ip[20];
-}__attribute__((packed));
+struct route_list {
+    uint8_t hash_buf[VNET_HASH_SIZE];
 
+    uint32_t num_routes;
+    struct vnet_route_info * routes[0];
+} __attribute__((packed));
 
-#define MAX_LINKS 10
-#define MAX_ROUTES 10
-#define HASH_KEY_LEN 16
-#define MIN_CACHE_SIZE 100
-#define HASH_KEY_SIZE 16
 
-struct link_table {
-    struct link_entry * links[MAX_LINKS];
-    uint16_t size;
+#define BUF_SIZE 4096
+struct pkts_buf {
+    int start, end;
+    int num; 
     v3_lock_t lock;
-}__attribute__((packed));
+    struct v3_vnet_pkt pkts[BUF_SIZE];
+};
 
-struct routing_table {
-    struct routing_entry * routes[MAX_ROUTES];
-    uint16_t size;
-    v3_lock_t lock;
-}__attribute__((packed));
 
-typedef char * route_hashkey_t;
+static struct {
+    struct list_head routes;
+    struct list_head devs;
+    
+    int num_routes;
+    int num_devs;
 
-struct route_cache_entry {
-    int num_matched_routes;
-    int * matches; 
-};
+    struct vnet_brg_dev *bridge;
 
-struct vnet_state_t {
-    struct link_table g_links;
-    struct routing_table g_routes;
-    struct gen_queue * g_inpkt_q;
-    struct hashtable * g_route_cache;
-    v3_lock_t cache_lock;
-};
+    v3_lock_t lock;
 
-static struct vnet_state_t g_vnet_state;//global state for vnet
+    uint8_t sidecores; /* 0 -vnet not running on sidecore, > 0, number of extra cores that can be used by VNET */
+    uint64_t cores_map; /* bitmaps for which cores can be used by VNET for sidecore, maxium 64 */
 
-static uint16_t ip_xsum(struct ip_header *ip_hdr, int hdr_len){
-    long sum = 0;
+    struct hashtable * route_cache;
+} vnet_state;
 
-    uint16_t *p = (uint16_t*) ip_hdr;
-    while(hdr_len > 1){
-        sum += *(p++);
-        if(sum & 0x80000000)
-            sum = (sum & 0xFFFF) + (sum >> 16);
-            hdr_len -= 2;
-        }
-    if(hdr_len) 
-        sum += (uint16_t) *(uchar_t *)p;
-          
-    while(sum>>16)
-        sum = (sum & 0xFFFF) + (sum >> 16);
 
-    return (uint16_t)~sum;
-}
 
-static void ethernet_packet_init(struct ethernet_pkt *pt, 
-                                                              uchar_t *data, 
-                                                              const size_t size) {
-    pt->size = size;
-    pt->use_header = 0;
-    memset(&pt->ext_hdr, 0, sizeof(struct udp_link_header));
-    memcpy(pt->data, data, size);
-}
 
-static inline uint_t hash_from_key_fn(addr_t hashkey) {    
-    return v3_hash_buffer((uint8_t *)hashkey, HASH_KEY_LEN);
+#ifdef CONFIG_DEBUG_VNET
+static inline void mac_to_string(char mac[6], char * buf) {
+    snprintf(buf, 100, "%d:%d:%d:%d:%d:%d", 
+            mac[0], mac[1], mac[2],
+            mac[3], mac[4], mac[5]);
 }
 
-static inline int hash_key_equal(addr_t key1, addr_t key2) {
-    return (memcmp((uint8_t *)key1, (uint8_t *)key2, HASH_KEY_LEN) == 0);
+static void print_route(struct vnet_route_info *route){
+    char str[50];
+
+    mac_to_string(route->route_def.src_mac, str);
+    PrintDebug("Src Mac (%s),  src_qual (%d)\n", 
+                       str, route->route_def.src_mac_qual);
+    mac_to_string(route->route_def.dst_mac, str);
+    PrintDebug("Dst Mac (%s),  dst_qual (%d)\n", 
+                       str, route->route_def.dst_mac_qual);
+    PrintDebug("Src dev id (%d), src type (%d)", 
+                       route->route_def.src_id, 
+                       route->route_def.src_type);
+    PrintDebug("Dst dev id (%d), dst type (%d)\n", 
+                       route->route_def.dst_id, 
+                       route->route_def.dst_type);
+    if (route->route_def.dst_type == LINK_INTERFACE) {
+       PrintDebug("dst_dev (%p), dst_dev_id (%d), dst_dev_ops(%p), dst_dev_data (%p)\n",
+                                       route->dst_dev,
+                                       route->dst_dev->dev_id,
+                                       (void *)&(route->dst_dev->dev_ops),
+                                       route->dst_dev->private_data);
+    }
 }
 
-static int init_route_cache(struct vnet_state_t *vnet_state) { 
-    vnet_state->g_route_cache = v3_create_htable(MIN_CACHE_SIZE, 
-                                                                      &hash_from_key_fn, 
-                                                                      &hash_key_equal);
-
-    if (vnet_state->g_route_cache == NULL) {
-        PrintError("Vnet: Route Cache Init Fails\n");
-        return -1;
-    }
+static void dump_routes(){
+       struct vnet_route_info *route;
 
-    return 0;
+       int i = 0;
+       PrintDebug("\n========Dump routes starts ============\n");
+       list_for_each_entry(route, &(vnet_state.routes), node) {
+               PrintDebug("\nroute %d:\n", ++i);
+               
+               print_route(route);
+       }
+       PrintDebug("\n========Dump routes end ============\n");
 }
 
-static void make_hash_key(route_hashkey_t hashkey,
-                                               char src_addr[6],
-                                               char dest_addr[6],
-                                               char src_type,
-                                               int src_index) {
-    int j;
+#endif
 
-    for (j = 0; j < 6; j++) {
-       hashkey[j] = src_addr[j];
-       hashkey[j + 6] = dest_addr[j] + 1;
-    }
 
-    hashkey[12] = src_type;
+/* 
+ * A VNET packet is a packed struct with the hashed fields grouped together.
+ * This means we can generate the hash from an offset into the pkt struct
+ */
+static inline uint_t hash_fn(addr_t hdr_ptr) {    
+    uint8_t * hdr_buf = (uint8_t *)hdr_ptr;
 
-    *(int *)(hashkey + 12) = src_index;
+    return v3_hash_buffer(hdr_buf, VNET_HASH_SIZE);
 }
 
-static int add_route_to_cache(route_hashkey_t hashkey, 
-                                                       int num_matched_r, 
-                                                       int * matches) {
-    struct route_cache_entry * new_entry = NULL;
-    struct vnet_state_t *vnet_state = &g_vnet_state;
-    int i;
-    
-    new_entry = (struct route_cache_entry *)V3_Malloc(sizeof(struct route_cache_entry));
-    if (new_entry == NULL) {
-       PrintError("Vnet: Malloc fails\n");
-       return -1;
-    }
-    
-    new_entry->num_matched_routes = num_matched_r;
-    new_entry->matches = (int *)V3_Malloc(num_matched_r * sizeof(int));
-    
-    if (new_entry->matches == NULL) {
-       PrintError("Vnet: Malloc fails\n");
-       return -1;
-    }
-    
-    for (i = 0; i < num_matched_r; i++) {
-       new_entry->matches[i] = matches[i];
-    }
-    
-    if (v3_htable_insert(vnet_state->g_route_cache, (addr_t)hashkey, (addr_t)new_entry) == 0) {
+static inline int hash_eq(addr_t key1, addr_t key2) {  
+    return (memcmp((uint8_t *)key1, (uint8_t *)key2, VNET_HASH_SIZE) == 0);
+}
+
+static int add_route_to_cache(const struct v3_vnet_pkt * pkt, struct route_list * routes) {
+    memcpy(routes->hash_buf, pkt->hash_buf, VNET_HASH_SIZE);    
+
+    if (v3_htable_insert(vnet_state.route_cache, (addr_t)routes->hash_buf, (addr_t)routes) == 0) {
        PrintError("Vnet: Failed to insert new route entry to the cache\n");
-       V3_Free(new_entry->matches);
-       V3_Free(new_entry);
+       return -1;
     }
     
     return 0;
 }
 
 static int clear_hash_cache() {
-    struct vnet_state_t *vnet_state = &g_vnet_state;
 
-    v3_free_htable(vnet_state->g_route_cache, 1, 1);           
-    vnet_state->g_route_cache = v3_create_htable(MIN_CACHE_SIZE, 
-                                                                        hash_from_key_fn, 
-                                                                        hash_key_equal);
-    
-    if (vnet_state->g_route_cache == NULL) {
-        PrintError("Vnet: Route Cache Create Failurely\n");
-        return -1;
-    }
+    v3_free_htable(vnet_state.route_cache, 1, 1);
+    vnet_state.route_cache = v3_create_htable(0, &hash_fn, &hash_eq);
 
     return 0;
 }
 
-static int look_into_cache(route_hashkey_t hashkey, int * matches) {
-    struct route_cache_entry * found = NULL;
-    int n_matches = -1;
-    int i = 0;
-    struct vnet_state_t *vnet_state = &g_vnet_state;
+static int look_into_cache(const struct v3_vnet_pkt * pkt, struct route_list ** routes) {
     
-    found = (struct route_cache_entry *)v3_htable_search(vnet_state->g_route_cache, 
-                                                                               (addr_t)hashkey);
+    *routes = (struct route_list *)v3_htable_search(vnet_state.route_cache, (addr_t)(pkt->hash_buf));
    
-    if (found != NULL) {
-        n_matches = found->num_matched_routes;
-
-        for (i = 0; i < n_matches; i++) {
-            matches[i] = found->matches[i];
-       }
-    }
-
-    return n_matches;
+    return 0;
 }
 
 
-#ifdef CONFIG_DEBUG_VNET
+static struct vnet_dev * find_dev_by_id(int idx) {
+    struct vnet_dev * dev = NULL; 
 
-static void print_packet(uchar_t *pkt, int size) {
-    PrintDebug("Vnet: data_packet: size: %d\n", size);
-    v3_hexdump(pkt, size, NULL, 0);
-}
+    list_for_each_entry(dev, &(vnet_state.devs), node) {
+       int dev_id = dev->dev_id;
 
-static inline uint8_t hex_nybble_to_nybble(const uint8_t hexnybble) {
-    uint8_t x = toupper(hexnybble);
-
-    if (isdigit(x)) {
-       return x - '0';
-    } else {
-       return 10 + (x - 'A');
+       if (dev_id == idx)
+           return dev;
     }
-}
 
-static inline uint8_t hex_byte_to_byte(const uint8_t hexbyte[2]) {
-    return ((hex_nybble_to_nybble(hexbyte[0]) << 4) + 
-           (hex_nybble_to_nybble(hexbyte[1]) & 0xf));
+    return NULL;
 }
 
-static inline void string_to_mac(const char *str, uint8_t mac[6]) {
-    int k;
-
-    for (k = 0; k < 6; k++) {
-       mac[k] = hex_byte_to_byte(&(str[(2 * k) + k]));
+static struct vnet_dev * find_dev_by_mac(char mac[6]) {
+    struct vnet_dev * dev = NULL; 
+    
+    list_for_each_entry(dev, &(vnet_state.devs), node) {
+       if (!memcmp(dev->mac_addr, mac, 6))
+           return dev;
     }
-}
 
-static inline void mac_to_string(char mac[6], char * buf) {
-    snprintf(buf, 20, "%02x:%02x:%02x:%02x:%02x:%02x", 
-            mac[0], mac[1], mac[2],
-            mac[3], mac[4], mac[5]);
+    return NULL;
 }
 
+int v3_vnet_id_by_mac(char mac[6]){
 
-static void print_route(struct routing_entry *route){
-    char dest_str[18];
-    char src_str[18];
+    struct vnet_dev *dev = find_dev_by_mac(mac);
 
-    mac_to_string(route->src_mac, src_str);  
-    mac_to_string(route->dest_mac, dest_str);
+    if (dev == NULL)
+       return -1;
 
-    PrintDebug("SRC(%s), DEST(%s), src_mac_qual(%d), dst_mac_qual(%d)\n", 
-                 src_str, 
-                 dest_str, 
-                 route->src_mac_qual, 
-                 route->dest_mac_qual);
-    PrintDebug("Src_Link(%d), src_type(%d), dst_link(%d), dst_type(%d)\n\n", 
-                 route->src_link_idx, 
-                 route->src_type, 
-                 route->link_idx, 
-                 route->link_type);
+    return dev->dev_id;
 }
-       
 
-static void dump_routes(struct routing_entry **route_tables) {
-    int i;
 
-    PrintDebug("\nVnet: route table dump start =====\n");
+int v3_vnet_add_route(struct v3_vnet_route route) {
+    struct vnet_route_info * new_route = NULL;
+    unsigned long flags; 
 
-    for(i = 0; i < MAX_ROUTES; i++) {
-        if (route_tables[i] != NULL){
-            print_route(route_tables[i]);
-        }
+    new_route = (struct vnet_route_info *)V3_Malloc(sizeof(struct vnet_route_info));
+    memset(new_route, 0, sizeof(struct vnet_route_info));
+
+    PrintDebug("Vnet: vnet_add_route_entry: dst_id: %d, dst_type: %d\n",
+                       route.dst_id, route.dst_type);  
+    
+    memcpy(new_route->route_def.src_mac, route.src_mac, 6);
+    memcpy(new_route->route_def.dst_mac, route.dst_mac, 6);
+    new_route->route_def.src_mac_qual = route.src_mac_qual;
+    new_route->route_def.dst_mac_qual = route.dst_mac_qual;
+    new_route->route_def.dst_id = route.dst_id;
+    new_route->route_def.dst_type = route.dst_type;
+    new_route->route_def.src_id = route.src_id;
+    new_route->route_def.src_type = route.src_type;
+
+    if (new_route->route_def.dst_type == LINK_INTERFACE) {
+       new_route->dst_dev = find_dev_by_id(new_route->route_def.dst_id);
     }
 
-    PrintDebug("\nVnet: route table dump end =====\n");
-}
+    if (new_route->route_def.src_type == LINK_INTERFACE) {
+       new_route->src_dev = find_dev_by_id(new_route->route_def.src_id);
+    }
 
-static void dump_dom0_routes(struct routing_entry routes[], int size) {
-    int i;
+    flags = v3_lock_irqsave(vnet_state.lock);
 
-    PrintDebug("\nVnet: route table from dom0 guest =====\n");
+    list_add(&(new_route->node), &(vnet_state.routes));
+    clear_hash_cache();
 
-    for(i = 0; i <size; i++) {
-        print_route(&routes[i]);
-    }
+    v3_unlock_irqrestore(vnet_state.lock, flags);
+   
+
+#ifdef CONFIG_DEBUG_VNET
+    dump_routes();
+#endif
 
-    PrintDebug("\nVnet: route table dom0 guest end =====\n");
+    return 0;
 }
 
-static void dump_dom0_links(struct vnet_if_link links[], int size) {
-    struct vnet_if_link *link = NULL;
-    int i;
 
-    PrintDebug("\nVnet: link table from dom0 guest =====\n");
-
-    for(i = 0; i <size; i++) {
-        link = &links[i];
-        PrintDebug("link: %d\n", i);
-        PrintDebug("dest_ip(%ld), dst_port(%d), prot_type(%d)\n", 
-                     link->dest_ip, 
-                     link->dest_port, 
-                     link->pro_type);
-        PrintDebug("vnet_header:\n");
-        v3_hexdump(&link->vnet_header, sizeof(struct udp_link_header), NULL, 0);
-    }
 
-    PrintDebug("\nVnet: link table dom0 guest end =====\n");
-}
+/* At the end allocate a route_list
+ * This list will be inserted into the cache so we don't need to free it
+ */
+static struct route_list * match_route(const struct v3_vnet_pkt * pkt) {
+    struct vnet_route_info * route = NULL; 
+    struct route_list * matches = NULL;
+    int num_matches = 0;
+    int max_rank = 0;
+    struct list_head match_list;
+    struct eth_hdr * hdr = (struct eth_hdr *)(pkt->data);
+    uint8_t src_type = pkt->src_type;
+    uint32_t src_link = pkt->src_id;
 
+#ifdef CONFIG_DEBUG_VNET
+    {
+       char dst_str[100];
+       char src_str[100];
+
+       mac_to_string(hdr->src_mac, src_str);  
+       mac_to_string(hdr->dst_mac, dst_str);
+       PrintDebug("Vnet: match_route. pkt: SRC(%s), DEST(%s)\n", src_str, dst_str);
+    }
 #endif
 
-static int __add_link_entry(struct link_entry * link) {
-    int idx;
-    struct vnet_state_t *vnet_state = &g_vnet_state;
+    INIT_LIST_HEAD(&match_list);
+    
+#define UPDATE_MATCHES(rank) do {                              \
+       if (max_rank < (rank)) {                                \
+           max_rank = (rank);                                  \
+           INIT_LIST_HEAD(&match_list);                        \
+                                                               \
+           list_add(&(route->match_node), &match_list);        \
+           num_matches = 1;                                    \
+       } else if (max_rank == (rank)) {                        \
+           list_add(&(route->match_node), &match_list);        \
+           num_matches++;                                      \
+       }                                                       \
+    } while (0)
+    
 
-    v3_lock(vnet_state->g_links.lock);
-    for (idx = 0; idx < MAX_LINKS; idx++) {
-       if (vnet_state->g_links.links[idx] == NULL) {
-           vnet_state->g_links.links[idx] = link;
-           vnet_state->g_links.size++;
-           break;
+    list_for_each_entry(route, &(vnet_state.routes), node) {
+       struct v3_vnet_route * route_def = &(route->route_def);
+
+       // CHECK SOURCE TYPE HERE
+       if ( (route_def->src_type != LINK_ANY) && 
+            ( (route_def->src_type != src_type) || 
+              ( (route_def->src_id != src_link) &&
+                (route_def->src_id != (uint32_t)-1)))) {
+           continue;
+       }
+
+
+       if ((route_def->dst_mac_qual == MAC_ANY) &&
+           (route_def->src_mac_qual == MAC_ANY)) {      
+           UPDATE_MATCHES(3);
+       }
+       
+       if (memcmp(route_def->src_mac, hdr->src_mac, 6) == 0) {
+           if (route_def->src_mac_qual != MAC_NOT) {
+               if (route_def->dst_mac_qual == MAC_ANY) {
+                   UPDATE_MATCHES(6);
+               } else if (route_def->dst_mac_qual != MAC_NOT &&
+                          memcmp(route_def->dst_mac, hdr->dst_mac, 6) == 0) {
+                   UPDATE_MATCHES(8);
+               }
+           }
+       }
+           
+       if (memcmp(route_def->dst_mac, hdr->dst_mac, 6) == 0) {
+           if (route_def->dst_mac_qual != MAC_NOT) {
+               if (route_def->src_mac_qual == MAC_ANY) {
+                   UPDATE_MATCHES(6);
+               } else if ((route_def->src_mac_qual != MAC_NOT) && 
+                          (memcmp(route_def->src_mac, hdr->src_mac, 6) == 0)) {
+                   UPDATE_MATCHES(8);
+               }
+           }
+       }
+           
+       if ((route_def->dst_mac_qual == MAC_NOT) &&
+           (memcmp(route_def->dst_mac, hdr->dst_mac, 6) != 0)) {
+           if (route_def->src_mac_qual == MAC_ANY) {
+               UPDATE_MATCHES(5);
+           } else if ((route_def->src_mac_qual != MAC_NOT) && 
+                      (memcmp(route_def->src_mac, hdr->src_mac, 6) == 0)) {     
+               UPDATE_MATCHES(7);
+           }
+       }
+       
+       if ((route_def->src_mac_qual == MAC_NOT) &&
+           (memcmp(route_def->src_mac, hdr->src_mac, 6) != 0)) {
+           if (route_def->dst_mac_qual == MAC_ANY) {
+               UPDATE_MATCHES(5);
+           } else if ((route_def->dst_mac_qual != MAC_NOT) &&
+                      (memcmp(route_def->dst_mac, hdr->dst_mac, 6) == 0)) {
+               UPDATE_MATCHES(7);
+           }
+       }
+       
+       // Default route
+       if ( (memcmp(route_def->src_mac, hdr->src_mac, 6) == 0) &&
+            (route_def->dst_mac_qual == MAC_NONE)) {
+           UPDATE_MATCHES(4);
        }
     }
-    v3_unlock(vnet_state->g_links.lock);
 
-    if (idx == MAX_LINKS) {
-       PrintDebug("VNET: No available Link entry for new link\n");
-       return -1;
+    PrintDebug("Vnet: match_route: Matches=%d\n", num_matches);
+
+    if (num_matches == 0) {
+       return NULL;
     }
 
-    return idx;
-}
+    matches = (struct route_list *)V3_Malloc(sizeof(struct route_list) + 
+                               (sizeof(struct vnet_route_info *) * num_matches));
 
-static int __add_route_entry(struct routing_entry * route) {
-    int idx;
-    struct vnet_state_t *vnet_state = &g_vnet_state;
+    matches->num_routes = num_matches;
 
-    v3_lock(vnet_state->g_routes.lock);
-    for (idx = 0; idx < MAX_ROUTES; idx++) {
-       if (vnet_state->g_routes.routes[idx] == NULL) {
-           vnet_state->g_routes.routes[idx] = route;
-           vnet_state->g_routes.size++;
-          break;
+    {
+       int i = 0;
+       list_for_each_entry(route, &match_list, match_node) {
+           matches->routes[i++] = route;
        }
     }
-    v3_unlock(vnet_state->g_routes.lock);
 
-    if(idx == MAX_LINKS){
-        PrintDebug("VNET: No available route entry for new route\n");
-        return -1;
-    }
+    return matches;
+}
 
-#ifdef CONFIG_DEBUG_VNET
-    dump_routes(vnet_state->g_routes.routes);
-#endif
+static int send_to_bridge(struct v3_vnet_pkt * pkt){
+    struct vnet_brg_dev *bridge = vnet_state.bridge;
+
+    if (bridge == NULL) {
+       PrintError("VNET: No bridge to sent data to links\n");
+       return -1;
+    }
 
-    return idx;
+    return bridge->brg_ops.input(bridge->vm, pkt, bridge->private_data);
 }
 
-int v3_vnet_add_route(struct v3_vnet_route *route){
-    struct routing_entry * new_route = (struct routing_entry *)V3_Malloc(sizeof(struct routing_entry));
-    int idx = -1;
 
-    PrintDebug("Vnet: vnet_add_route_entry\n");
-       
-    memset(new_route, 0, sizeof(struct routing_entry));
-    if ((route->src_mac_qual != MAC_ANY)) {
-        memcpy(new_route->src_mac, route->src_mac, 6);
-    }
-           
-    if ((route->dest_mac_qual != MAC_ANY)) {
-        memcpy(new_route->dest_mac, route->dest_mac, 6);
-    }
-           
-    new_route->src_mac_qual = route->src_mac_qual;
-    new_route->dest_mac_qual = route->dest_mac_qual;
-    new_route->link_idx= route->link_idx;
-    new_route->link_type = route->link_type;
-    new_route->src_link_idx = route->src_link_idx;
-    new_route->src_type = route->src_type;
-
-    if ((idx = __add_route_entry(new_route)) == -1) {
-       PrintError("Could not add route entry\n");
-        return -1;
+/* enable a vnet device, notify VNET it can send pkts to it */
+int v3_vnet_enable_device(int dev_id){
+    struct vnet_dev *dev = find_dev_by_id(dev_id);
+    unsigned long flags;
+
+    if(!dev)
+       return -1;
+
+    if(!dev->rx_disabled)
+       return 0;
+
+    flags = v3_lock_irqsave(vnet_state.lock);
+    dev->rx_disabled = 0;
+    v3_unlock_irqrestore(vnet_state.lock, flags);
+
+    /* TODO: Wake up all other guests who are trying to send pkts */
+    dev = NULL;
+    list_for_each_entry(dev, &(vnet_state.devs), node) {
+       if (dev->dev_id != dev_id)
+           dev->dev_ops.start_tx(dev->private_data);
     }
-    
-    clear_hash_cache();
 
-    return idx;
+    return 0;
 }
 
-static int match_route(uint8_t * src_mac, 
-                      uint8_t * dst_mac, 
-                      link_type_t src_type, 
-                      int src_index, 
-                      int * matches) {
-    struct routing_entry *route = NULL; 
-    struct vnet_state_t *vnet_state = &g_vnet_state;
-    int matched_routes[MAX_ROUTES];
-    int num_matches = 0;
-    int i;
-
-#ifdef CONFIG_DEBUG_VNET
-    char dest_str[18];
-    char src_str[18];
+/* Notify VNET to stop sending pkts to it */
+int v3_vnet_disable_device(int dev_id){
+    struct vnet_dev *dev = find_dev_by_id(dev_id);
+    unsigned long flags;
 
-    mac_to_string(src_mac, src_str);  
-    mac_to_string(dst_mac, dest_str);
-    PrintDebug("Vnet: match_route. pkt: SRC(%s), DEST(%s)\n", src_str, dest_str);
-#endif
+    if(!dev)
+       return -1;
 
-    for(i = 0; i < MAX_ROUTES; i++) {
-        if (vnet_state->g_routes.routes[i] != NULL){
-            route = vnet_state->g_routes.routes[i];
+    flags = v3_lock_irqsave(vnet_state.lock);
+    dev->rx_disabled = 1;
+    v3_unlock_irqrestore(vnet_state.lock, flags);
 
-            if(src_type == LINK_ANY && src_index == -1) {
-                if ((route->dest_mac_qual == MAC_ANY) &&
-                      (route->src_mac_qual == MAC_ANY)) {      
-                    matched_routes[num_matches] = i;
-                    num_matches++;
-                }
-       
-                if (memcmp((void *)&route->src_mac, (void *)src_mac, 6) == 0) {
-                    if (route->src_mac_qual !=  MAC_NOT) {
-                         if (route->dest_mac_qual == MAC_ANY) {
-                             matched_routes[num_matches] = i;
-                             num_matches++;
-                         } else if (route->dest_mac_qual != MAC_NOT &&
-                                     memcmp((void *)&route->dest_mac, (void *)dst_mac, 6) == 0) {
-                            matched_routes[num_matches] = i;
-                            num_matches++;
-                        }
-                    }
-                }
-
-                if (memcmp((void *)&route->dest_mac, (void *)dst_mac, 6) == 0) {
-                    if (route->dest_mac_qual != MAC_NOT) {
-                        if (route->src_mac_qual == MAC_ANY) {
-                            matched_routes[num_matches] = i;
-                            num_matches++;
-                        } else if ((route->src_mac_qual != MAC_NOT) && 
-                                       (memcmp((void *)&route->src_mac, (void *)src_mac, 6) == 0)) {
-                            matched_routes[num_matches] = i;
-                            num_matches++;
-                        }
-                     }
-                }
-
-                if ((route->dest_mac_qual == MAC_NOT) &&
-                      (memcmp((void *)&route->dest_mac, (void *)dst_mac, 6) != 0)) {
-                    if (route->src_mac_qual == MAC_ANY) {
-                        matched_routes[num_matches] = i;           
-                        num_matches++;    
-                    } else if ((route->src_mac_qual != MAC_NOT) && 
-                                   (memcmp((void *)&route->src_mac, (void *)src_mac, 6) == 0)) {     
-                        matched_routes[num_matches] = i;     
-                        num_matches++;
-                     }
-                }
-
-                if ((route->src_mac_qual == MAC_NOT) &&
-                      (memcmp((void *)&route->src_mac, (void *)src_mac, 6) != 0)) {
-                    if (route->dest_mac_qual == MAC_ANY) {
-                        matched_routes[num_matches] = i;   
-                        num_matches++;
-                    } else if ((route->dest_mac_qual != MAC_NOT) &&
-                                   (memcmp((void *)&route->dest_mac, (void *)dst_mac, 6) == 0)) {
-                        matched_routes[num_matches] = i;
-                        num_matches++;
-                    }
-                }
-            }//end if src_type == Link_any
-        }      
-    }//end for
 
-    PrintDebug("Vnet: match_route: Matches=%d\n", num_matches);
-       
-    for (i = 0; i < num_matches; i++) {
-        matches[i] = matched_routes[i];
+    /* TODO: Notify all other guests to stop send pkts */
+    dev = NULL;
+    list_for_each_entry(dev, &(vnet_state.devs), node) {
+       if (dev->dev_id != dev_id)
+           dev->dev_ops.stop_tx(dev->private_data);
     }
-    
-    return num_matches;
+
+    return 0;
 }
 
-static int handle_one_pkt(struct ethernet_pkt *pkt) {
-    int src_link_index = -1;   //the value of src_link_index of udp always is 0
-    char src_mac[6];
-    char dst_mac[6];
-    int matches[MAX_ROUTES];
-    int num_matched_routes = 0;
-    struct in_pkt_header header;
-    char hash_key[HASH_KEY_SIZE];
-    struct vnet_state_t *vnet_state = &g_vnet_state;
+int v3_vnet_send_pkt(struct v3_vnet_pkt * pkt, void * private_data) {
+    struct route_list * matched_routes = NULL;
+    unsigned long flags;
     int i;
 
-    // get the ethernet and ip headers from the packet
-    memcpy((void *)&header, (void *)pkt->data, sizeof(header));
-    memcpy(src_mac, header.ethernetsrc, 6);
-    memcpy(dst_mac, header.ethernetdest, 6);
-
 #ifdef CONFIG_DEBUG_VNET
-    char dest_str[18];
-    char src_str[18];
-
-    mac_to_string(src_mac, src_str);  
-    mac_to_string(dst_mac, dest_str);
-    PrintDebug("Vnet: HandleDataOverLink. SRC(%s), DEST(%s)\n", src_str, dest_str);
+   {
+       struct eth_hdr * hdr = (struct eth_hdr *)(pkt->header);
+       char dest_str[100];
+       char src_str[100];
+
+       mac_to_string(hdr->src_mac, src_str);  
+       mac_to_string(hdr->dst_mac, dest_str);
+       int cpu = V3_Get_CPU();
+       PrintDebug("Vnet: on cpu %d, HandleDataOverLink. SRC(%s), DEST(%s), pkt size: %d\n", cpu, src_str, dest_str, pkt->size);
+   }
 #endif
 
-    make_hash_key(hash_key, src_mac, dst_mac, LINK_EDGE, src_link_index); 
-    num_matched_routes = look_into_cache((route_hashkey_t)hash_key, matches);
-    
-    if (num_matched_routes == -1) {  
-        num_matched_routes = match_route(src_mac, dst_mac, LINK_ANY, src_link_index, matches); 
-        if (num_matched_routes > 0) {
-            add_route_to_cache(hash_key, num_matched_routes,matches);      
-        }
-    }
-    
-    PrintDebug("Vnet: HandleDataOverLink: Matches=%d\n", num_matched_routes);
+    flags = v3_lock_irqsave(vnet_state.lock);
 
-    if (num_matched_routes == 0) {
-        return -1;
+    look_into_cache(pkt, &matched_routes);
+       
+    if (matched_routes == NULL) {  
+       PrintError("Vnet: send pkt Looking into routing table\n");
+       
+       matched_routes = match_route(pkt);
+       
+       if (matched_routes) {
+           add_route_to_cache(pkt, matched_routes);
+       } else {
+           PrintDebug("Could not find route for packet... discards packet\n");
+           v3_unlock_irqrestore(vnet_state.lock, flags);
+           return 0; /* do we return -1 here?*/
+       }
     }
-    
-    for (i = 0; i < num_matched_routes; i++) {//send packet to all destinations
-        int route_index = -1;
-        int link_index = -1;
-        int pkt_len = 0;
-        struct link_entry * link = NULL;
-
-        route_index = matches[i];
-        link_index = vnet_state->g_routes.routes[route_index]->link_idx;
-
-        if ((link_index < 0) || (link_index > MAX_LINKS) || 
-            (vnet_state->g_links.links[link_index] == NULL)) {
-            continue;
-        }
+
+    v3_unlock_irqrestore(vnet_state.lock, flags);
+
+    PrintDebug("Vnet: send pkt route matches %d\n", matched_routes->num_routes);
+
+    for (i = 0; i < matched_routes->num_routes; i++) {
+        struct vnet_route_info * route = matched_routes->routes[i];
        
-        link = vnet_state->g_links.links[link_index];
-        pkt_len = pkt->size;
-        if (link->type == LINK_EDGE) {
-
-             //apply the header in the beginning of the packet to be sent
-            if (link->dst_link->pro_type == UDP_TYPE) {
-                struct udp_link_header *hdr = &(link->dst_link->vnet_header);
-                struct ip_header *ip = &hdr->ip_hdr;
-                struct udp_header *udp = &hdr->udp_hdr;
-                  udp->len = pkt_len + sizeof(struct udp_header);
-                  ip->total_len = pkt_len + sizeof(struct udp_header) + sizeof(struct ip_header);
-                  ip->cksum = ip_xsum(ip, sizeof(struct ip_header));
-               
-                int hdr_size = sizeof(struct udp_link_header);
-                memcpy(&pkt->ext_hdr, hdr, hdr_size);
-
-                pkt_len += hdr_size;
-                if ((link->dst_link->input((uchar_t *)&pkt->ext_hdr, pkt_len, link->dst_link->private_data)) != pkt_len) {
-                    PrintDebug("VNET: Packet not sent properly to link: %d\n", link_index);
-                    continue;
-                }
-            }else {
-                PrintDebug("VNET: Link protocol type not support\n");
-                continue;
-            }
-        } else if (link->type == LINK_INTERFACE) {
-            if ((link->dst_dev->input(link->dst_dev->vm, pkt->data, pkt_len, link->dst_dev->private_data)) != pkt_len) {
-                PrintDebug("VNET: Packet not sent properly to link: %d\n", link_index);
+        if (route->route_def.dst_type == LINK_EDGE) {                  
+            pkt->dst_type = LINK_EDGE;
+            pkt->dst_id = route->route_def.dst_id;
+
+            if (send_to_bridge(pkt) == -1) {
+                PrintDebug("VNET: Packet not sent properly to bridge\n");
                 continue;
+            }         
+        } else if (route->route_def.dst_type == LINK_INTERFACE) {
+            if (!route->dst_dev->rx_disabled){ 
+                 if(route->dst_dev->dev_ops.input(route->dst_dev->vm, pkt, route->dst_dev->private_data) == -1) {
+                       PrintDebug("VNET: Packet not sent properly\n");
+                       continue;
+                 }
             }
         } else {
-            PrintDebug("Vnet: Wrong Edge type of link: %d\n", link_index);
-            continue;
+            PrintError("VNET: Wrong Edge type\n");
         }
 
-        PrintDebug("Vnet: HandleDataOverLink: Forward packet according to Route entry %d to link %d\n", route_index, link_index);
+        PrintDebug("VNET: Forward one packet according to Route %d\n", i);
     }
     
     return 0;
 }
 
-static int send_ethernet_pkt(uchar_t *data, int len, void *private_data) {
-    struct ethernet_pkt *pkt;
-    struct vnet_state_t *vnet_state = &g_vnet_state;
+int v3_vnet_add_dev(struct v3_vm_info *vm, uint8_t mac[6], 
+                   struct v3_vnet_dev_ops *ops,
+                   void * priv_data){
+    struct vnet_dev * new_dev = NULL;
+    unsigned long flags;
 
-    pkt = (struct ethernet_pkt *)V3_Malloc(sizeof(struct ethernet_pkt));
-    if(pkt == NULL){
-        PrintError("VNET: Memory allocate fails\n");
-        return -1;
+    new_dev = (struct vnet_dev *)V3_Malloc(sizeof(struct vnet_dev)); 
+
+    if (new_dev == NULL) {
+       PrintError("VNET: Malloc fails\n");
+       return -1;
     }
+   
+    memcpy(new_dev->mac_addr, mac, 6);
+    new_dev->dev_ops.input = ops->input;
+    new_dev->dev_ops.poll = ops->poll;
+    new_dev->private_data = priv_data;
+    new_dev->vm = vm;
+    new_dev->dev_id = 0;       
 
-    memset(pkt, 0, sizeof(struct ethernet_pkt));
-    ethernet_packet_init(pkt, data, len);
-    v3_enqueue(vnet_state->g_inpkt_q, (addr_t)pkt);
-  
-#ifdef CONFIG_DEBUG_VNET
-    PrintDebug("VNET: send_pkt: transmitting packet: (size:%d)\n", (int)pkt->size);
-    print_packet((char *)data, len);
-#endif
+    flags = v3_lock_irqsave(vnet_state.lock);
 
-    return 0;
-}
+    if (!find_dev_by_mac(mac)) {
+       list_add(&(new_dev->node), &(vnet_state.devs));
+       new_dev->dev_id = ++vnet_state.num_devs;
+    }
 
-int v3_vnet_send_rawpkt(uchar_t * buf, 
-                                          int len, 
-                                          void *private_data) {
-    PrintDebug("VNET: In v3_vnet_send_rawpkt: pkt length %d\n", len);
-    
-    return send_ethernet_pkt(buf, len, private_data);
-}
+    v3_unlock_irqrestore(vnet_state.lock, flags);
 
-//sending the packet from Dom0, should remove the link header
-int v3_vnet_send_udppkt(uchar_t * buf, 
-                                           int len, 
-                                           void *private_data) {
-    uint_t hdr_len = sizeof(struct udp_link_header);
-       
-    PrintDebug("VNET: In v3_vnet_send_udppkt: pkt length %d\n", len);
-   
-    return send_ethernet_pkt((uchar_t *)(buf+hdr_len), len - hdr_len, private_data);
+    /* if the device was found previosly the id should still be 0 */
+    if (new_dev->dev_id == 0) {
+       PrintError("Device Alrady exists\n");
+       return -1;
+    }
+
+    PrintDebug("Vnet: Add Device: dev_id %d\n", new_dev->dev_id);
+
+    return new_dev->dev_id;
 }
 
-static int search_device(char * device_name) {
-    struct vnet_state_t *vnet_state = &g_vnet_state;
-    int i;
 
-    for (i = 0; i < MAX_LINKS; i++) {
-        if ((vnet_state->g_links.links[i] != NULL) && (vnet_state->g_links.links[i]->type == LINK_INTERFACE)) {
-           if (strcmp(device_name, vnet_state->g_links.links[i]->dst_dev->name) == 0) {
-               return i;
+/* TODO: Still need to figure out how to handle this multicore part --Lei
+  */
+void  v3_vnet_poll(struct v3_vm_info *vm){
+    struct vnet_dev * dev = NULL; 
+
+    switch (vnet_state.sidecores) {
+       case 0:
+               list_for_each_entry(dev, &(vnet_state.devs), node) {
+                   if(dev->vm == vm){
+                       dev->dev_ops.poll(vm, dev->private_data);
+                   }
+              }
+               break;
+       case 1:
+               break;
+       case 2:
+           list_for_each_entry(dev, &(vnet_state.devs), node) {
+               int cpu_id = vm->cores[0].cpu_id + 2; /* temporary here, should use vnet_state.cores_map */
+                struct v3_vnet_dev_xcall_args dev_args; /* could cause problem here -LX */
+                dev_args.vm = vm;
+               dev_args.private_data = dev->private_data;
+               V3_Call_On_CPU(cpu_id, dev->dev_ops.poll_xcall, (void *)&dev_args);
            }
-        }
+           break;
+       default:
+           break;
     }
-
-    return -1;
 }
 
-int v3_vnet_add_node(struct v3_vm_info *info, 
-                  char * dev_name, 
-                  uchar_t mac[6], 
-                   int (*netif_input)(struct v3_vm_info * vm, uchar_t * pkt, uint_t size, void * private_data), 
-                   void * priv_data){
-    struct vnet_if_device * if_dev;
+int v3_vnet_add_bridge(struct v3_vm_info * vm,
+                      struct v3_vnet_bridge_ops *ops,
+                      void * priv_data) {
+    unsigned long flags;
+    int bridge_free = 0;
+    struct vnet_brg_dev * tmp_bridge = NULL;    
+    
+    flags = v3_lock_irqsave(vnet_state.lock);
 
-    int idx = search_device(dev_name);
-    if (idx != -1) {
-       PrintDebug("VNET: register device: Already has device with the name %s\n", dev_name);
+    if (vnet_state.bridge == NULL) {
+       bridge_free = 1;
+       vnet_state.bridge = (void *)1;
+    }
+
+    v3_unlock_irqrestore(vnet_state.lock, flags);
+
+    if (bridge_free == 0) {
+       PrintError("Bridge already set\n");
        return -1;
     }
-    
-    if_dev = (struct vnet_if_device *)V3_Malloc(sizeof(struct vnet_if_device)); 
-    if (if_dev == NULL) {
-       PrintError("VNET: Malloc fails\n");
+
+    tmp_bridge = (struct vnet_brg_dev *)V3_Malloc(sizeof(struct vnet_brg_dev));
+
+    if (tmp_bridge == NULL) {
+       PrintError("Malloc Fails\n");
+       vnet_state.bridge = NULL;
        return -1;
     }
     
-    strcpy(if_dev->name, dev_name);
-    strncpy(if_dev->mac_addr, mac, 6);
-    if_dev->input = netif_input;
-    if_dev->private_data = priv_data;
-    if_dev->vm = info;
+    tmp_bridge->vm = vm;
+    tmp_bridge->brg_ops.input = ops->input;
+    tmp_bridge->brg_ops.xcall_input = ops->xcall_input;
+    tmp_bridge->brg_ops.polling_pkt = ops->polling_pkt;
+    tmp_bridge->private_data = priv_data;
+    tmp_bridge->disabled = 0;
+       
+    /* make this atomic to avoid possible race conditions */
+    flags = v3_lock_irqsave(vnet_state.lock);
+    vnet_state.bridge = tmp_bridge;
+    v3_unlock_irqrestore(vnet_state.lock, flags);
 
-    struct link_entry * link = (struct link_entry *)V3_Malloc(sizeof(struct link_entry));
-    link->type = LINK_INTERFACE;
-    link->dst_dev = if_dev;
+    return 0;
+}
+
+
+#if 0
+int v3_vnet_disable_bridge() {
+    unsigned long flags; 
+    
+    flags = v3_lock_irqsave(vnet_state.lock);
 
-    idx = __add_link_entry(link);
+    if (vnet_state.bridge != NULL) {
+       vnet_state.bridge->disabled = 1;
+    }
 
-    if (idx < 0) return -1;
+    v3_unlock_irqrestore(vnet_state.lock, flags);
 
-    return idx;
+    return 0;
 }
 
-int v3_vnet_pkt_process() {
-    struct ethernet_pkt * pkt;
-    struct vnet_state_t *vnet_state = &g_vnet_state;
 
-    while ((pkt = (struct ethernet_pkt *)v3_dequeue(vnet_state->g_inpkt_q))!= NULL) {
-        if (handle_one_pkt(pkt) != -1) {
-            PrintDebug("VNET: vnet_check: handle one packet! pt length %d, pt type %d\n", (int)pkt->size, (int)pkt->type);  
-        } else {
-            PrintDebug("VNET: vnet_check: Fail to forward one packet, discard it!\n"); 
-        }
-       
-        V3_Free(pkt); // be careful here
-    }
+int v3_vnet_enable_bridge() {
+    unsigned long flags; 
     
+    flags = v3_lock_irqsave(vnet_state.lock);
+
+    if (vnet_state.bridge != NULL) {
+       vnet_state.bridge->disabled = 0;
+    }
+
+    v3_unlock_irqrestore(vnet_state.lock, flags);
+
     return 0;
 }
+#endif
 
-static void vnet_state_init(struct vnet_state_t *vnet_state) {
-    int i;
+int v3_init_vnet() {
+    memset(&vnet_state, 0, sizeof(vnet_state));
+       
+    INIT_LIST_HEAD(&(vnet_state.routes));
+    INIT_LIST_HEAD(&(vnet_state.devs));
 
-    /*initial links table */
-    for (i = 0; i < MAX_LINKS; i++) {
-        vnet_state->g_links.links[i] = NULL;
-    }
-    vnet_state->g_links.size = 0;
-    if(v3_lock_init(&(vnet_state->g_links.lock)) == -1){
-        PrintError("VNET: Failure to init lock for links table\n");
-    }
-    PrintDebug("VNET: Links table initiated\n");
+    vnet_state.num_devs = 0;
+    vnet_state.num_routes = 0;
 
-    /*initial routes table */
-    for (i = 0; i < MAX_ROUTES; i++) {
-        vnet_state->g_routes.routes[i] = NULL;
-    }
-    vnet_state->g_routes.size = 0;
-    if(v3_lock_init(&(vnet_state->g_routes.lock)) == -1){
+    PrintDebug("VNET: Links and Routes tables initiated\n");
+
+    if (v3_lock_init(&(vnet_state.lock)) == -1){
         PrintError("VNET: Failure to init lock for routes table\n");
     }
-    PrintDebug("VNET: Routes table initiated\n");
+    PrintDebug("VNET: Locks initiated\n");
 
-    /*initial pkt receiving queue */
-    vnet_state->g_inpkt_q = v3_create_queue();
-    v3_init_queue(vnet_state->g_inpkt_q);
-    PrintDebug("VNET: Receiving queue initiated\n");
+    vnet_state.route_cache = v3_create_htable(0, &hash_fn, &hash_eq);
 
-    /*initial routing cache */
-    init_route_cache(vnet_state);
-}
+    if (vnet_state.route_cache == NULL) {
+        PrintError("Vnet: Route Cache Init Fails\n");
+        return -1;
+    }
 
+    vnet_state.sidecores = 0;
+    vnet_state.cores_map = 0;
 
-int v3_init_vnet() {
-    vnet_state_init(&g_vnet_state);
-       
-    PrintDebug("VNET Initialized\n");
+    PrintDebug("VNET: initiated\n");
 
     return 0;
 }
-