#include <devices/pci.h>
-#ifndef CONFIG_LINUX_VIRTIO_VNET_DEBUG
+#ifndef CONFIG_DEBUG_LINUX_VIRTIO_VNET
#undef PrintDebug
#define PrintDebug(fmt, args...)
#endif
struct vnet_virtio_pkt {
uint32_t link_id;
uint32_t pkt_size;
- uint8_t pkt[1500];
-};
+ uint8_t pkt[ETHERNET_PACKET_LEN];
+}__attribute__((packed));
+
static int virtio_reset(struct virtio_vnet_state * vnet_state) {
flags = v3_lock_irqsave(vnet_state->lock);
- PrintDebug("VNET Bridge: RX: pkt sent to guest size: %d\n, pkt_header_len: %d\n", data_len, pkt_head_len);
-
if (q->ring_avail_addr == 0) {
PrintError("Queue is not set\n");
goto exit;
return -1;
}
+ PrintDebug("VNET Bridge: RX: pkt sent to guest pkt size: %d, dst link: %d\n", pkt->size, pkt->dst_id);
+
// Fill in dst packet buffer
virtio_pkt->link_id = pkt->dst_id;
virtio_pkt->pkt_size = pkt->size;
memcpy(virtio_pkt->pkt, pkt->data, pkt->size);
-
q->used->ring[q->used->index % q->queue_size].id = q->avail->ring[q->cur_avail_idx % q->queue_size];
q->used->ring[q->used->index % q->queue_size].length = sizeof(struct vnet_virtio_pkt); // This should be the total length of data sent to guest (header+pkt_data)
q->used->index++;
q->cur_avail_idx++;
} else {
- PrintError("Packet buffer overflow in the guest\n");
+ PrintError("Packet buffer overflow in the guest: cur_avai_idx %d, idx: %d\n", q->cur_avail_idx, q->avail->index);
}
if (!(q->avail->flags & VIRTIO_NO_IRQ_FLAG)) {
PrintDebug("Raising IRQ %d\n", vnet_state->pci_dev->config_header.intr_line);
}
-
ret_val = 0;
exit:
static int handle_pkt_kick(struct guest_info *core, struct virtio_vnet_state * vnet_state)
{
struct virtio_queue * q = &(vnet_state->queue[XMIT_QUEUE]);
-
- PrintDebug("VNET Bridge Device: Handle TX\n");
+ struct v3_vnet_pkt pkt;
while (q->cur_avail_idx != q->avail->index) {
uint16_t desc_idx = q->avail->ring[q->cur_avail_idx % q->queue_size];
pkt_desc = &(q->desc[desc_idx]);
- PrintDebug("VNET Bridge: Handle TX buf_len: %d\n", pkt_desc->length);
+ PrintDebug("VNET Bridge: Handle TX desc buf_len: %d\n", pkt_desc->length);
+
+ //PrintDebug("q: %p, %p, %p, %d\n", q, vnet_state->queue, &vnet_state->queue[XMIT_QUEUE], XMIT_QUEUE);
+ //PrintDebug("q->used: %p\n", q->used);
+ //PrintDebug("q->used->ring %p\n", q->used->ring);
if (guest_pa_to_host_va(core, pkt_desc->addr_gpa, (addr_t *)&(virtio_pkt)) == -1) {
PrintError("Could not translate buffer address\n");
return -1;
}
- //TODO: SETUP VNET PACKET data structure
+ PrintDebug("VNET Bridge: TX: pkt size: %d, dst link: %d\n", virtio_pkt->pkt_size, virtio_pkt->link_id);
- /*
- if (v3_vnet_send_pkt(pkt, (void *)core) == -1) {
- PrintError("Error sending packet to vnet\n");
- return -1;
- }
- */
+ pkt.size = virtio_pkt->pkt_size;
+ pkt.src_id = virtio_pkt->link_id;
+ pkt.src_type = LINK_EDGE;
+ memcpy(pkt.header, virtio_pkt->pkt, ETHERNET_HEADER_LEN);
+ pkt.data = virtio_pkt->pkt;
+
+ v3_vnet_send_pkt(&pkt, NULL);
+
+ q = (struct virtio_queue *)((addr_t)vnet_state->queue + XMIT_QUEUE*sizeof(struct virtio_queue));
+
+ PrintDebug("After q: %p, , %p, %p, %d\n", q, vnet_state->queue, &(vnet_state->queue[XMIT_QUEUE]), XMIT_QUEUE);
+ //PrintDebug("After q->used: %p\n", q->used);
+ //PrintDebug("After q->used->ring %p\n", q->used->ring);
+
q->used->ring[q->used->index % q->queue_size].id = q->avail->ring[q->cur_avail_idx % q->queue_size];
q->used->ring[q->used->index % q->queue_size].length = pkt_desc->length; // What do we set this to????
q->used->index++;
}
-static int add_route_to_cache(struct v3_vnet_pkt * pkt, struct route_list * routes) {
+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) {
return 0;
}
-static int look_into_cache(struct v3_vnet_pkt * pkt, struct route_list ** routes) {
+static int look_into_cache(const struct v3_vnet_pkt * pkt, struct route_list ** routes) {
*routes = (struct route_list *)v3_htable_search(vnet_state.route_cache, (addr_t)(pkt->hash_buf));
// 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(struct v3_vnet_pkt * pkt) {
+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;
#ifdef CONFIG_DEBUG_VNET
{
- struct eth_hdr * hdr = (struct eth_hdr *)(pkt->data);
+ struct eth_hdr * hdr = (struct eth_hdr *)(pkt->header);
char dest_str[30];
char src_str[30];
look_into_cache(pkt, &matched_routes);
if (matched_routes == NULL) {
- PrintDebug("Vnet: can not find route in cache, looking into routing table\n");
+ PrintDebug("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...\n");
+ PrintDebug("Could not find route for packet... discards packet\n");
v3_unlock_irqrestore(vnet_state.lock, flags);
return -1;
}
v3_unlock_irqrestore(vnet_state.lock, flags);
- PrintDebug("Vnet: HandleOnePacket: route matches %d\n", matched_routes->num_routes);
+ 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];