uint8_t mac_addr[6];
struct v3_vm_info * vm;
- int (*input)(struct v3_vm_info * vm, struct v3_vnet_pkt * pkt, void * private_data);
+ int (*input)(struct v3_vm_info * vm, struct v3_vnet_pkt * pkt, void * private_data);
void * private_data;
int dev_id;
} __attribute__((packed));
+struct vnet_brg_dev {
+ struct v3_vm_info * vm;
+
+ int (*input)(struct v3_vm_info * vm, struct v3_vnet_pkt * pkt, void * private_data);
+ void * private_data;
+} __attribute__((packed));
+
+
static struct {
struct list_head routes;
struct list_head devs;
-
+
int num_routes;
int num_devs;
+ struct vnet_brg_dev *bridge;
+
v3_lock_t lock;
struct gen_queue * inpkt_q;
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)",
+ PrintDebug("Dst dev id (%d), dst type (%d)\n",
route->route_def.dst_id,
route->route_def.dst_type);
- PrintDebug("dst_dev (%p), dst_dev_id (%d), dst_dev_input (%p), dst_dev_data (%p)\n",
+ if (route->route_def.dst_type == LINK_INTERFACE) {
+ PrintDebug("dst_dev (%p), dst_dev_id (%d), dst_dev_input (%p), dst_dev_data (%p)\n",
route->dst_dev,
route->dst_dev->dev_id,
route->dst_dev->input,
route->dst_dev->private_data);
-
+ }
}
static void dump_routes(){
* 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);
-
+ uint8_t * hdr_buf = (uint8_t *)hdr_ptr;
+
return v3_hash_buffer(hdr_buf, VNET_HASH_SIZE);
}
-static inline int hash_eq(addr_t key1, addr_t key2) {
+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 look_into_cache(struct v3_vnet_pkt * pkt, struct route_list ** routes) {
- *routes = (struct route_list *)v3_htable_search(vnet_state.route_cache, (addr_t)pkt);
+ *routes = (struct route_list *)v3_htable_search(vnet_state.route_cache, (addr_t)(pkt->hash_buf));
return 0;
}
look_into_cache(pkt, &matched_routes);
if (matched_routes == NULL) {
+ PrintDebug("Vnet: can not find route in cache, looking into routing table\n");
+
matched_routes = match_route(pkt);
if (matched_routes) {
}
#endif
- PrintDebug("Vnet: HandleOnePacket: %d\n", matched_routes->num_routes);
+ PrintDebug("Vnet: HandleOnePacket: 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];
if (route->route_def.dst_type == LINK_EDGE) {
-
+ pkt->dst_type = LINK_EDGE;
+ pkt->dst_id = route->route_def.dst_id;
+ if (vnet_state.bridge == NULL) {
+ PrintDebug("VNET: No bridge to sent data to links\n");
+ continue;
+ }
+ if (vnet_state.bridge->input(vnet_state.bridge->vm, pkt, vnet_state.bridge->private_data) == -1) {
+ PrintDebug("VNET: Packet not sent properly\n");
+ continue;
+ }
} else if (route->route_def.dst_type == LINK_INTERFACE) {
if (route->dst_dev->input(route->dst_dev->vm, pkt, route->dst_dev->private_data) == -1) {
PrintDebug("VNET: Packet not sent properly\n");
}
+int v3_vnet_add_bridge(struct v3_vm_info * vm,
+ int (*input)(struct v3_vm_info * vm, struct v3_vnet_pkt * pkt, void * private_data),
+ void * priv_data){
+ unsigned long flags;
+
+ flags = v3_lock_irqsave(vnet_state.lock);
+
+ if(vnet_state.bridge != NULL){
+ PrintDebug("Vnet: Replace current bridge with a new one\n");
+ } else {
+ vnet_state.bridge = (struct vnet_brg_dev *)V3_Malloc(sizeof(struct vnet_brg_dev));
+ if (vnet_state.bridge == NULL) {
+ PrintError("Malloc Fails\n");
+ return -1;
+ }
+ }
+
+ vnet_state.bridge->vm = vm;
+ vnet_state.bridge->input = input;
+ vnet_state.bridge->private_data = priv_data;
+
+ v3_unlock_irqrestore(vnet_state.lock, flags);
+
+ return 0;
+}
+
int V3_init_vnet() {
INIT_LIST_HEAD(&(vnet_state.routes));