void * private_data;
int active;
- uint8_t mode; //vmm_drivern or guest_drivern
+
+ uint64_t bytes_tx, bytes_rx;
+ uint32_t pkts_tx, pkt_rx;
struct list_head node;
} __attribute__((packed));
struct v3_vnet_bridge_ops brg_ops;
uint8_t type;
- uint8_t mode;
+
int active;
void * private_data;
} __attribute__((packed));
int num_routes;
int num_devs;
- struct vnet_brg_dev *bridge;
+ struct vnet_brg_dev * bridge;
v3_lock_t lock;
+ struct vnet_stat stats;
struct hashtable * route_cache;
} vnet_state;
if (!compare_ethaddr(dev->mac_addr, mac)){
return dev;
}
-
- char *dmac = dev->mac_addr;
- PrintDebug("device %d: %2x:%2x:%2x:%2x:%2x:%2x\n", dev->dev_id, dmac[0], dmac[1], dmac[2], dmac[3], dmac[4], dmac[5]);
}
return NULL;
int v3_vnet_find_dev(uint8_t * mac) {
struct vnet_dev * dev = NULL;
- PrintDebug("find_dev: %2x:%2x:%2x:%2x:%2x:%2x\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
-
dev = dev_by_mac(mac);
if(dev != NULL) {
new_route = (struct vnet_route_info *)V3_Malloc(sizeof(struct vnet_route_info));
memset(new_route, 0, sizeof(struct vnet_route_info));
+#ifdef CONFIG_DEBUG_VNET
PrintDebug("VNET/P Core: add_route_entry:\n");
print_route(&route);
+#endif
memcpy(new_route->route_def.src_mac, route.src_mac, ETH_ALEN);
memcpy(new_route->route_def.dst_mac, route.dst_mac, ETH_ALEN);
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;
+// uint8_t src_type = pkt->src_type;
+ // uint32_t src_link = pkt->src_id;
#ifdef CONFIG_DEBUG_VNET
{
PrintDebug("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);
- //v3_hexdump(pkt->data, pkt->size, NULL, 0);
}
#endif
flags = v3_lock_irqsave(vnet_state.lock);
+ vnet_state.stats.rx_bytes += pkt->size;
+ 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: Packet not sent properly to bridge\n");
continue;
}
+ vnet_state.stats.tx_bytes += pkt->size;
+ vnet_state.stats.tx_pkts ++;
} else if (route->route_def.dst_type == LINK_INTERFACE) {
if (route->dst_dev == NULL || route->dst_dev->active == 0){
PrintDebug("VNET/P Core: No active device to sent data to\n");
PrintDebug("VNET/P Core: Packet not sent properly\n");
continue;
}
+ vnet_state.stats.tx_bytes += pkt->size;
+ vnet_state.stats.tx_pkts ++;
} else {
PrintError("VNET/P Core: Wrong dst type\n");
}
new_dev->vm = vm;
new_dev->dev_id = 0;
new_dev->active = 1;
- new_dev->mode = GUEST_DRIVERN;
flags = v3_lock_irqsave(vnet_state.lock);
return 0;
}
+int v3_vnet_stat(struct vnet_stat * stats){
+
+ stats->rx_bytes = vnet_state.stats.rx_bytes;
+ stats->rx_pkts = vnet_state.stats.rx_pkts;
+ stats->tx_bytes = vnet_state.stats.tx_bytes;
+ stats->tx_pkts = vnet_state.stats.tx_pkts;
+
+ return 0;
+}
static void free_devices(){
struct vnet_dev * dev = NULL;
tmp_bridge->brg_ops.poll = ops->poll;
tmp_bridge->private_data = priv_data;
tmp_bridge->active = 1;
- tmp_bridge->mode = GUEST_DRIVERN;
tmp_bridge->type = type;
/* make this atomic to avoid possible race conditions */
}
+void v3_vnet_do_poll(struct v3_vm_info * vm){
+ struct vnet_dev * dev = NULL;
+
+ /* TODO: run this on separate threads
+ * round-robin schedule, with maximal budget for each poll
+ */
+ list_for_each_entry(dev, &(vnet_state.devs), node) {
+ if(dev->dev_ops.poll != NULL){
+ dev->dev_ops.poll(vm, -1, dev->private_data);
+ }
+ }
+}
+
+
int v3_init_vnet() {
memset(&vnet_state, 0, sizeof(vnet_state));