2 * This file is part of the Palacios Virtual Machine Monitor developed
3 * by the V3VEE Project with funding from the United States National
4 * Science Foundation and the Department of Energy.
6 * The V3VEE Project is a joint project between Northwestern University
7 * and the University of New Mexico. You can find out more at
10 * Copyright (c) 2012, Peter Dinda <pdindal@northwestern.edu>
11 * Copyright (c) 2012, The V3VEE Project <http://www.v3vee.org>
12 * All rights reserved.
14 * Author: Peter Dinda <pdinda@northwestern.edu>
16 * This is free software. You are permitted to use,
17 * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
20 #include <palacios/vmm.h>
21 #include <palacios/vmm_dev_mgr.h>
22 #include <palacios/vm_guest_mem.h>
23 #include <vnet/vnet.h>
24 #include <palacios/vmm_sprintf.h>
25 #include <devices/pci.h>
29 The purpose of this device is to act as a back-end for
30 in-guest implementations of the VNET forwarding and encapsulation engine.
32 Via the hypercall hanging off this device, the guest can
33 ask for the appropriate header to use for encapsulation (if any).
35 All control-plane work remains in the VNET implementation in Palacios and
39 #ifndef V3_CONFIG_DEBUG_VNET_GUEST_IFACE
41 #define PrintDebug(fmt, args...)
55 r8 = 0 => send, 1=>recv
57 returns rax=negative on error. 0 if successful
60 static int handle_header_query_hcall(struct guest_info * info, uint_t hcall_id, void * priv_data)
64 addr_t header_ptr_gva;
73 struct v3_vnet_header vnet_header;
75 if (hcall_id != VNET_HEADER_QUERY_HCALL) {
76 PrintError("Unknown hcall 0x%x in vnet_stub\n",hcall_id);
80 src_mac_gva = info->vm_regs.rcx;
81 dest_mac_gva = info->vm_regs.rdx;
82 header_ptr_gva = info->vm_regs.rsi;
83 header_len = info->vm_regs.rdi;
84 recv = info->vm_regs.r8;
86 if (v3_read_gva_memory(info,src_mac_gva,6,src_mac)!=6) {
87 PrintError("Cannot read src mac in query\n");
92 if (v3_read_gva_memory(info,(addr_t)dest_mac_gva,6,dest_mac)!=6) {
93 PrintError("Cannot read src mac in query\n");
98 if (v3_vnet_query_header(src_mac,dest_mac,recv,&vnet_header) < 0 ) {
99 PrintError("Failed to lookup header\n");
100 info->vm_regs.rax=-1;
104 copy_len = (sizeof(vnet_header)<header_len) ? sizeof(vnet_header) : header_len;
106 if (v3_write_gva_memory(info,header_ptr_gva,copy_len,(uchar_t*)&vnet_header) != copy_len) {
107 PrintError("Failed to write back header\n");
108 info->vm_regs.rax=-1;
117 static int vnet_guest_iface_free(void *priv_data) {
123 static struct v3_device_ops dev_ops = {
124 .free = vnet_guest_iface_free,
127 static int dev_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg)
129 char * name = v3_cfg_val(cfg, "name");
131 PrintDebug("VNET guest interface: Initializing as device: %s\n", name);
133 struct vm_device * dev = v3_add_device(vm, name, &dev_ops, NULL);
136 PrintError("Could not attach device %s\n", name);
140 v3_register_hypercall(vm, VNET_HEADER_QUERY_HCALL, handle_header_query_hcall, NULL);
146 device_register("VNET_GUEST_IFACE", dev_init)