From: Lei Xia Date: Mon, 22 Nov 2010 02:24:28 +0000 (-0600) Subject: add backend device for direct host network bridge X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=bc5ee3e07affac4810227d61c407011c05298518;p=palacios.git add backend device for direct host network bridge --- diff --git a/palacios/include/palacios/vmm_packet.h b/palacios/include/palacios/vmm_packet.h index 8f696e2..f343821 100644 --- a/palacios/include/palacios/vmm_packet.h +++ b/palacios/include/palacios/vmm_packet.h @@ -25,13 +25,13 @@ #ifdef __V3VEE__ -int V3_send_raw(const char * pkt, const int len); +int V3_send_raw(const char * pkt, uint32_t len); #endif struct v3_packet_hooks { - int (*send)(const char * pkt, const int size, void * private_data); + int (*send)(const char * pkt, unsigned int size, void * private_data); }; diff --git a/palacios/src/devices/Kconfig b/palacios/src/devices/Kconfig index b449d34..7222c48 100644 --- a/palacios/src/devices/Kconfig +++ b/palacios/src/devices/Kconfig @@ -181,6 +181,20 @@ config DEBUG_NE2k Enable debugging for the NE2K +config NIC_BRIDGE + bool "Enable Direct Bridge to Host network" + default n + depends on EXPERIMENTAL && PACKET + help + Enable Host Direct Network Bridge backend device for all network front devices + +config DEBUG_NIC_BRIDGE + bool "Debugging Direct Bridge to Host network" + default n + depends on NIC_BRIDGE && DEBUG_ON + help + Enable Debugging on Host Direct Network Bridge backend device + diff --git a/palacios/src/devices/Makefile b/palacios/src/devices/Makefile index 88356e1..2c5a066 100644 --- a/palacios/src/devices/Makefile +++ b/palacios/src/devices/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_PIIX3) += piix3.o obj-$(CONFIG_SWAPBYPASS_DISK_CACHE) += swapbypass_cache.o obj-$(CONFIG_SWAPBYPASS_DISK_CACHE2) += swapbypass_cache2.o obj-$(CONFIG_DISK_MODEL) += disk_model.o +obj-$(CONFIG_NIC_BRIDGE) += nic_bridge.o obj-$(CONFIG_NE2K) += ne2k.o diff --git a/palacios/src/devices/nic_bridge.c b/palacios/src/devices/nic_bridge.c new file mode 100644 index 0000000..4ed1d50 --- /dev/null +++ b/palacios/src/devices/nic_bridge.c @@ -0,0 +1,117 @@ +/* + * This file is part of the Palacios Virtual Machine Monitor developed + * by the V3VEE Project with funding from the United States National + * Science Foundation and the Department of Energy. + * + * The V3VEE Project is a joint project between Northwestern University + * and the University of New Mexico. You can find out more at + * http://www.v3vee.org + * + * Copyright (c) 2010, Lei Xia + * Copyright (c) 2010, The V3VEE Project + * All rights reserved. + * + * Author: Lei Xia + * + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ +//backend device for Virtio NIC, Direct Network Bridge + +#include +#include +#include +#include +#include + +#ifndef CONFIG_DEBUG_NIC_BRIDGE +#undef PrintDebug +#define PrintDebug(fmt, args...) +#endif + +struct nic_bridge_state { + struct v3_vm_info * vm; + struct v3_dev_net_ops net_ops; +}; + +static int bridge_send(uint8_t * buf, uint32_t len, + void * private_data, struct vm_device *dev){ + //struct nic_bridge_state *bridge = (struct nic_bridge_state *)private_data; + +#ifdef CONFIG_DEBUG_NIC_BRIDGE + { + PrintDebug("NIC Bridge: send pkt size: %d\n", len); + v3_hexdump(buf, len, NULL, 0); + } +#endif + + return V3_send_raw(buf, len); +} + + +static int packet_input(struct v3_vm_info * vm, + struct v3_packet_event * evt, + void * private_data) { + struct nic_bridge_state *bridge = (struct nic_bridge_state *)private_data; + + PrintDebug("NIC_BRIDGE: Incoming packet size: %d\n", evt->size); + + return bridge->net_ops.recv(evt->pkt, + evt->size, + bridge->net_ops.frontend_data); +} + + +static int vnet_nic_free(struct vm_device * dev) { + struct nic_bridge_state * bridge = dev->private_data; + + /*detach from front device */ + + V3_Free(bridge); + + return 0; +} + +static struct v3_device_ops dev_ops = { + .free = vnet_nic_free, + .reset = NULL, + .start = NULL, + .stop = NULL, +}; + +static int vnet_nic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { + struct nic_bridge_state * bridge = NULL; + char * dev_id = v3_cfg_val(cfg, "ID"); + + v3_cfg_tree_t * frontend_cfg = v3_cfg_subtree(cfg, "frontend"); + + bridge = (struct nic_bridge_state *)V3_Malloc(sizeof(struct nic_bridge_state)); + memset(bridge, 0, sizeof(struct nic_bridge_state)); + + struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, bridge); + + if (v3_attach_device(vm, dev) == -1) { + PrintError("Could not attach device %s\n", dev_id); + return -1; + } + + bridge->net_ops.send = bridge_send; + bridge->vm = vm; + + if (v3_dev_connect_net(vm, v3_cfg_val(frontend_cfg, "tag"), + &(bridge->net_ops), frontend_cfg, bridge) == -1) { + PrintError("Could not connect %s to frontend %s\n", + dev_id, v3_cfg_val(frontend_cfg, "tag")); + return -1; + } + + PrintDebug("NIC-Bridge: Connect %s to frontend %s\n", + dev_id, v3_cfg_val(frontend_cfg, "tag")); + + v3_hook_host_event(vm, HOST_PACKET_EVT, V3_HOST_EVENT_HANDLER(packet_input), dev); + + return 0; +} + +device_register("NIC_BRIDGE", vnet_nic_init) diff --git a/palacios/src/palacios/vmm_packet.c b/palacios/src/palacios/vmm_packet.c index f6fd6bb..252bf11 100644 --- a/palacios/src/palacios/vmm_packet.c +++ b/palacios/src/palacios/vmm_packet.c @@ -24,7 +24,7 @@ static struct v3_packet_hooks * packet_hooks = 0; -int V3_send_raw(const char * pkt, const int len) { +int V3_send_raw(const char * pkt, uint32_t len) { V3_ASSERT(packet_hooks); V3_ASSERT(packet_hooks->send);