int v3_vnet_add_route(struct v3_vnet_route route) {
struct vnet_route_info * new_route = NULL;
- unsigned long flags;
+ vnet_intr_flags_t flags;
new_route = (struct vnet_route_info *)Vnet_Malloc(sizeof(struct vnet_route_info));
+
+ if (!new_route) {
+ PrintError("Cannot allocate new route\n");
+ return -1;
+ }
+
memset(new_route, 0, sizeof(struct vnet_route_info));
#ifdef V3_CONFIG_DEBUG_VNET
void v3_vnet_del_route(uint32_t route_idx){
struct vnet_route_info * route = NULL;
- unsigned long flags;
+ vnet_intr_flags_t flags;
flags = vnet_lock_irqsave(vnet_state.lock);
/* delete all route entries with specfied src or dst device id */
static void inline del_routes_by_dev(int dev_id){
struct vnet_route_info * route, *tmp_route;
- unsigned long flags;
+ vnet_intr_flags_t flags;
flags = vnet_lock_irqsave(vnet_state.lock);
vnet_unlock_irqrestore(vnet_state.lock, flags);
}
+
+
+
/* At the end allocate a route_list
* This list will be inserted into the cache so we don't need to free it
*/
PrintDebug("VNET/P Core: match_route: Matches=%d\n", num_matches);
- if (num_matches == 0) {
+ if (num_matches <= 0) {
return NULL;
}
matches = (struct route_list *)Vnet_Malloc(sizeof(struct route_list) +
(sizeof(struct vnet_route_info *) * num_matches));
+
+ if (!matches) {
+ PrintError("VNET/P Core: Unable to allocate matches\n");
+ return NULL;
+ }
+
matches->num_routes = num_matches;
{
return matches;
}
+int v3_vnet_query_header(uint8_t src_mac[6],
+ uint8_t dest_mac[6],
+ int recv, // 0 = send, 1=recv
+ struct v3_vnet_header *header)
+{
+ struct route_list *routes;
+ struct vnet_route_info *r;
+ struct v3_vnet_pkt p;
+
+ p.size=14;
+ p.data=p.header;
+ memcpy(p.header,dest_mac,6);
+ memcpy(p.header+6,src_mac,6);
+ memset(p.header+12,0,2);
+
+ p.src_type = LINK_EDGE;
+ p.src_id = 0;
+
+ memcpy(header->src_mac,src_mac,6);
+ memcpy(header->dst_mac,dest_mac,6);
+
+
+ look_into_cache(&p,&routes);
+
+ if (!routes) {
+ routes = match_route(&p);
+ if (!routes) {
+ PrintError("Cannot match route\n");
+ header->header_type=VNET_HEADER_NOMATCH;
+ header->header_len=0;
+ return -1;
+ } else {
+ add_route_to_cache(&p,routes);
+ }
+ }
+
+ if (routes->num_routes<1) {
+ PrintError("Less than one route\n");
+ header->header_type=VNET_HEADER_NOMATCH;
+ header->header_len=0;
+ return -1;
+ }
+
+ if (routes->num_routes>1) {
+ PrintError("More than one route, building header for the first one only\n");
+ }
+
+ r=routes->routes[0];
+
+ switch (r->route_def.dst_type) {
+ case LINK_EDGE: {
+ // switch based on the link type
+ // for mac-in-udp, we would want to generate a mac, ip, and udp header
+ // direct transmission
+
+ // for now we will say we have no encapsulation
+ //
+ header->header_type=VNET_HEADER_NONE;
+ header->header_len=0;
+ header->src_mac_qual=r->route_def.src_mac_qual;
+ header->dst_mac_qual=r->route_def.dst_mac_qual;
+
+ }
+
+ return 0;
+ break;
+
+
+ case LINK_INTERFACE:
+ // direct transmission
+ // let's guess that it goes to the same interface...
+ header->header_type=VNET_HEADER_NONE;
+ header->header_len=0;
+ header->src_mac_qual=r->route_def.src_mac_qual;
+ header->dst_mac_qual=r->route_def.dst_mac_qual;
+
+ return 0;
+ break;
+
+ default:
+ PrintError("Unknown destination type\n");
+ return -1;
+ break;
+
+ }
+
+}
+
+
+
int v3_vnet_send_pkt(struct v3_vnet_pkt * pkt, void * private_data) {
struct route_list * matched_routes = NULL;
- unsigned long flags;
+ vnet_intr_flags_t flags;
int i;
int cpu = V3_Get_CPU();
+
Vnet_Print(2, "VNET/P Core: cpu %d: pkt (size %d, src_id:%d, src_type: %d, dst_id: %d, dst_type: %d)\n",
cpu, pkt->size, pkt->src_id,
pkt->src_type, pkt->dst_id, pkt->dst_type);
+
if(net_debug >= 4){
v3_hexdump(pkt->data, pkt->size, NULL, 0);
}
vnet_state.stats.rx_pkts++;
look_into_cache(pkt, &matched_routes);
+
if (matched_routes == NULL) {
- PrintDebug("VNET/P Core: send pkt Looking into routing table\n");
+ PrintDebug("VNET/P Core: sending pkt - matching route\n");
matched_routes = match_route(pkt);
if (matched_routes) {
add_route_to_cache(pkt, matched_routes);
} else {
- PrintDebug("VNET/P Core: Could not find route for packet... discards packet\n");
+ PrintDebug("VNET/P Core: Could not find route for packet... discarding packet\n");
vnet_unlock_irqrestore(vnet_state.lock, flags);
return 0; /* do we return -1 here?*/
}
struct v3_vnet_dev_ops * ops, int quote, int poll_state,
void * priv_data){
struct vnet_dev * new_dev = NULL;
- unsigned long flags;
+ vnet_intr_flags_t flags;
new_dev = (struct vnet_dev *)Vnet_Malloc(sizeof(struct vnet_dev));
if (new_dev == NULL) {
- Vnet_Print(0, "Malloc fails\n");
+ Vnet_Print(0, "VNET/P Core: Unable to allocate a new device\n");
return -1;
}
new_dev->private_data = priv_data;
new_dev->vm = vm;
new_dev->dev_id = 0;
- new_dev->quote = quote<VNET_MAX_QUOTE?quote:VNET_MAX_QUOTE;
+ new_dev->quote = quote<VNET_MAX_QUOTE ? quote : VNET_MAX_QUOTE;
new_dev->poll = poll_state;
flags = vnet_lock_irqsave(vnet_state.lock);
v3_enqueue(vnet_state.poll_devs, (addr_t)new_dev);
}
} else {
- PrintError("VNET/P: Device with the same MAC is already there\n");
+ PrintError("VNET/P: Device with the same MAC has already been added\n");
}
vnet_unlock_irqrestore(vnet_state.lock, flags);
int v3_vnet_del_dev(int dev_id){
struct vnet_dev * dev = NULL;
- unsigned long flags;
+ vnet_intr_flags_t flags;
flags = vnet_lock_irqsave(vnet_state.lock);
Vnet_Free(dev);
- PrintDebug("VNET/P Core: Remove Device: dev_id %d\n", dev_id);
+ PrintDebug("VNET/P Core: Removed Device: dev_id %d\n", dev_id);
return 0;
}
struct v3_vnet_bridge_ops * ops,
uint8_t type,
void * priv_data) {
- unsigned long flags;
+ vnet_intr_flags_t flags;
int bridge_free = 0;
struct vnet_brg_dev * tmp_bridge = NULL;
tmp_bridge = (struct vnet_brg_dev *)Vnet_Malloc(sizeof(struct vnet_brg_dev));
if (tmp_bridge == NULL) {
- PrintError("Malloc Fails\n");
+ PrintError("VNET/P Core: Unable to allocate new bridge\n");
vnet_state.bridge = NULL;
return -1;
}
void v3_vnet_del_bridge(uint8_t type) {
- unsigned long flags;
+ vnet_intr_flags_t flags;
struct vnet_brg_dev * tmp_bridge = NULL;
flags = vnet_lock_irqsave(vnet_state.lock);
if (vnet_state.bridge != NULL && vnet_state.bridge->type == type) {
tmp_bridge = vnet_state.bridge;
- vnet_state.bridge = NULL;
+ vnet_state.bridge = NULL;
}
vnet_unlock_irqrestore(vnet_state.lock, flags);
}
}
+
+ Vnet_Free(tq);
Vnet_Print(0, "VNET/P Polling Thread Done.\n");
}
-void v3_deinit_vnet(){
+void v3_deinit_vnet() {
+
+ v3_deinit_queue(vnet_state.poll_devs);
+ Vnet_Free(vnet_state.poll_devs);
PrintDebug("Stopping flush thread\n");
// This will pause until the flush thread is gone
vnet_thread_stop(vnet_state.pkt_flush_thread);
// At this point there should be no lock-holder
+ Vnet_Free(vnet_state.poll_devs);
+
+
PrintDebug("Deiniting Device List\n");
// close any devices we have open
deinit_devices_list();