struct vnet_nic_state {
char mac[6];
struct guest_info * core;
-
- void *frontend_data;
- int (*frontend_input)(struct v3_vm_info *info,
- uchar_t * buf,
- uint32_t size,
- void *private_data);
+ struct v3_dev_net_ops net_ops;
};
//used when virtio_nic get a packet from guest and send it to the backend
struct v3_vnet_pkt * pkt = NULL;
// fill in packet
+ pkt = (struct v3_vnet_pkt *)V3_Malloc(sizeof(struct v3_vnet_pkt));
+
+ if(pkt == NULL){
+ PrintError("Malloc() fails");
+ return -1;
+ }
+
+ pkt->size = len;
+ memcpy(pkt->data, buf, pkt->size);
+
+ //TODO:
v3_vnet_send_pkt(pkt);
return 0;
// We need to make this dynamically allocated
-static struct v3_dev_net_ops net_ops = {
- .send = vnet_send,
-};
+//static struct v3_dev_net_ops net_ops = {
+// .send = vnet_send,
+//};
static int virtio_input(struct v3_vm_info *info, struct v3_vnet_pkt * pkt, void * private_data){
- // struct vnet_nic_state *vnetnic = (struct vnet_nic_state *)private_data;
+ struct vnet_nic_state *vnetnic = (struct vnet_nic_state *)private_data;
- // PrintDebug("Vnet-nic: In input: vnet_nic state %p\n", vnetnic);
+ PrintDebug("Vnet-nic: In input: vnet_nic state %p\n", vnetnic);
- return net_ops.recv(pkt->data, pkt->size, net_ops.frontend_data);
+ return vnetnic->net_ops.recv(pkt->data, pkt->size, vnetnic->net_ops.frontend_data);
}
#if 0
v3_vnet_add_dev(vm, mac, virtio_input, (void *)vnet_nic);
-
-
return 0;
}
return -1;
}
+ vnetnic->net_ops.send = vnet_send;
if (v3_dev_connect_net(vm, v3_cfg_val(frontend_cfg, "tag"),
- &net_ops, frontend_cfg, vnetnic) == -1) {
+ &(vnetnic->net_ops), frontend_cfg, vnetnic) == -1) {
PrintError("Could not connect %s to frontend %s\n",
name, v3_cfg_val(frontend_cfg, "tag"));
return -1;
#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
+#ifdef CONFIG_DEBUG_VNET
+
+static void print_packet(struct v3_vnet_pkt * pkt) {
+ PrintDebug("Vnet: data_packet: size: %d\n", pkt->size);
+ v3_hexdump(pkt->data, pkt->size, NULL, 0);
+}
+
+
+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]);
+}
+
+#endif
+
+
/*
* 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
*/
// MAKE SURE YOU DELETE the route_list entries
+ struct hashtable_iter * ht_iter = v3_create_htable_iter(vnet_state.route_cache);
+
+ if (!ht_iter) {
+ PrintError("NULL iterator in vnet cache!\n");
+ }
+
+ while (ht_iter->entry) {
+ struct route_list * route_list_ptr = (struct route_list *)v3_htable_get_iter_value(ht_iter);
+ V3_Free(route_list_ptr);
+ v3_htable_iter_advance(ht_iter);
+ }
+
+ V3_Free(ht_iter);
+
+ //v3_free_htable(vnet_state.route_cache, 0, 1);
return 0;
}
-
-
-
int v3_vnet_add_route(struct v3_vnet_route route) {
struct vnet_route_info * new_route = NULL;
unsigned long flags;
/* TODO: Find devices */
if (new_route->route_def.dst_type == LINK_INTERFACE) {
- // new_route->dst_dev = FIND_DEV();
+ //new_route->dst_dev = FIND_DEV();
}
if (new_route->route_def.src_type == LINK_INTERFACE) {
char src_str[18];
mac_to_string(hdr->src_mac, src_str);
- mac_to_string(hdr->dst_mac, dest_str);
- PrintDebug("Vnet: match_route. pkt: SRC(%s), DEST(%s)\n", src_str, dest_str);
+ mac_to_string(hdr->dst_mac, dst_str);
+ PrintDebug("Vnet: match_route. pkt: SRC(%s), DEST(%s)\n", src_str, dst_str);
}
#endif
} while (0)
-
list_for_each_entry(route, &(vnet_state.routes), node) {
struct v3_vnet_route * route_def = &(route->route_def);
#ifdef CONFIG_DEBUG_VNET
- char dest_str[18];
- char src_str[18];
+ {
+ struct eth_hdr * hdr = (struct eth_hdr *)(pkt->data);
+ char dest_str[18];
+ char src_str[18];
- mac_to_string(hdr->src, src_str);
- mac_to_string(hdr->dst, dest_str);
- PrintDebug("Vnet: HandleDataOverLink. SRC(%s), DEST(%s)\n", src_str, dest_str);
+ mac_to_string(hdr->src_mac, src_str);
+ mac_to_string(hdr->dst_mac, dest_str);
+ PrintDebug("Vnet: HandleDataOverLink. SRC(%s), DEST(%s)\n", src_str, dest_str);
+ }
#endif
look_into_cache(pkt, &matched_routes);
if (matched_routes == NULL) {
matched_routes = match_route(pkt);
- if (matched_routes) {
- add_route_to_cache(pkt, matched_routes);
+ if (matched_routes) {
+ add_route_to_cache(pkt, matched_routes);
} else {
PrintError("Could not find route for packet...\n");
return -1;
int v3_vnet_send_pkt(struct v3_vnet_pkt * pkt) {
// find the destination and call the send packet function, passing pkt *
-
+
+ if (handle_one_pkt(pkt) != -1) {
+ PrintDebug("VNET: send one packet! pt length %d\n", pkt->size);
+ } else {
+ PrintDebug("VNET: Fail to forward one packet, discard it!\n");
+ }
+
#ifdef CONFIG_DEBUG_VNET
- PrintDebug("VNET: send_pkt: transmitting packet: (size:%d)\n", (int)pkt->size);
print_packet(pkt);
#endif
return 0;
}
-
-/*
-static struct vnet_dev * find_dev_by_id(int idx) {
+struct vnet_dev * find_dev_by_id(int idx) {
+ struct vnet_dev * dev = NULL;
+ list_for_each_entry(dev, &(vnet_state.devs), node) {
+ int dev_id = dev->dev_id;
+
+ if (dev_id == idx)
+ return dev;
+ }
- // scan device list
return NULL;
}
-*/
static struct vnet_dev * find_dev_by_mac(char * name) {
+ struct vnet_dev * dev = NULL;
+
+ list_for_each_entry(dev, &(vnet_state.devs), node) {
+ if (!memcmp(dev->mac_addr, name, 6))
+ return dev;
+ }
return NULL;
}
new_dev = find_dev_by_mac(mac);
if (new_dev) {
- PrintDebug("VNET: register device: Already has device with the name %s\n", dev_name);
+ PrintDebug("VNET: register device: Already has device with the same mac\n");
return -1;
}
// ADD TO dev list
// increment dev count
+
+ list_add(&(new_dev->node), &(vnet_state.devs));
+ vnet_state.num_devs ++;
+ new_dev->dev_id = vnet_state.num_devs;
return 0;
}
while ((pkt = (struct v3_vnet_pkt *)v3_dequeue(vnet_state.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);
+ PrintDebug("VNET: vnet_check: handle one packet! pt length %d\n", (int)pkt->size);
} else {
PrintDebug("VNET: vnet_check: Fail to forward one packet, discard it!\n");
}
INIT_LIST_HEAD(&(vnet_state.routes));
INIT_LIST_HEAD(&(vnet_state.devs));
+ vnet_state.num_devs = 0;
+ vnet_state.num_routes = 0;
+
if (v3_lock_init(&(vnet_state.lock)) == -1){
PrintError("VNET: Failure to init lock for routes table\n");
}
return 0;
}
-
-
-
-#ifdef CONFIG_DEBUG_VNET
-
-static void print_packet(struct v3_vnet_pkt * pkt) {
- PrintDebug("Vnet: data_packet: size: %d\n", pkt->size);
- v3_hexdump(pkt->data, pkt->size, NULL, 0);
-}
-
-
-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]);
-}
-
-
-static void print_route(struct routing_entry *route){
- char dest_str[18];
- char src_str[18];
-
- mac_to_string(route->src_mac, src_str);
- mac_to_string(route->dest_mac, dest_str);
-
- 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_id,
- route->src_type,
- route->dst_id,
- route->dst_type);
-}
-
-
-static void dump_routes(struct routing_entry **route_tables) {
- int i;
-
- PrintDebug("\nVnet: route table dump start =====\n");
-
- for(i = 0; i < MAX_ROUTES; i++) {
- if (route_tables[i] != NULL){
- print_route(route_tables[i]);
- }
- }
-
- PrintDebug("\nVnet: route table dump end =====\n");
-}
-
-#endif