how QEMU guest can send packets to NIC of the host? - qemu

i'm trying to test XDP program but the test environment was provided by the client consists of one server and qemu guest running on it and act as a traffic generator ( using scapy or DPDK ). and to have this test run successfully,the packets from the guest should arrive/be injected to the NIC driver ( XDP working in native mode ) of the host. is there's any configs/hacks that can make the traffic goes from the guest to the host driver?
edit :
some points to be cleared as #vipin suggested,
on the host, the NIC is connected to virbr0 on kernel.
the XDP is running on the physical NIC.
i'm using bpf_redirect_map for redirecting as we still in simple stage.
anyway, i got a work around is just to add a physical router to the lab setup and it's enough for this stage of test.

XDP (Express Data Path) supported in Linux is for RX side, and there were patches for TX but not integrated. Based on the current update XDP-eBPF is on Physical NIC. So all RX packet on physical NIC is processed.
But as per the question shared packets from the guest should arrive/be injected to the NIC driver ( XDP working in native mode ) of the host.. If one needs to run the logic for traffic coming from GUEST OS, XDP has to be loaded to emulator or TAP or Bridge interface. This will allow to redirect packets based on Kernel NIC id to Physcial NIC.

Related

Can I use DPDK as a packet capture module for a network monitoring application?

My passive network monitoring application needs packets to be captured from network interface (at higher packet rates). The packet capture module should be able to call a monitoring function upon capture of each packet (and also write the packet in to pcap file).
I thought of using DPDK as the packet capture module in my monitoring application (as we use pcap_loop and pfring_loop in libpcap and pfring respectively), but I am not sure whether this is one of the use cases of DPDK, or, is DPDK meant to be used like this?.
So my questions are..
Can I use DPDK to fulfill my requirements?, If yes how to start?.
OS: Linux.
Karnal version: 4.
DPDK version: Latest stable.
Capture on physical device.
The capturing application has root privileges and will be used by the network administrator (as part of passive asset discovery).
I want to use DPDK because it supports capture at line rate upto 10 Gbps
Thank you.
Based on the updates and clarification in comment the request is Can one replace an existing application which PF_RING API calls with DPDK API which is written in C?. Simple answer to it is yes it can be done.
Here is how one should start
identify the Platform (preferably Linux/BSD, windows 21.02 is still work in progress)
identify the processor list of supported CPU
Identify a NIC to use from LIST of DPDK NIC
Set up the Linux environment with Linux Enviroment
Explore basic example/skeleton for basicfwd usage
get the start of ethernet header for packet using DPDK API rte_pktmbuf_mtod. There are many samples in DPDK/examples folder which does the same.
Invoke the packet processing function logic between rx_burst and tx_burst of example/skeleton.
Newer versions of libpcap can themselves use DPDK, at least on Linux. The libpcap on your system might, or might not, be configured to use it. (There are also versions of libpcap modified to use PF_RING.)

Hyper-V and physical switch trunk port SPAN/mirroring

I'm new to the Hyper-V and trying to setup a lab. Here is my setup:
Cisco switch with a SPAN port (configured to mirror in/out, replicate the encapsulation, source port for the span is a trunk). I verified that I see all packets on the SPAN port
Server with Hyper-V VM that has two NICs. One is for general connectivity, the other is configured as a mirror destination. Vlan identification is disabled. Mapped to a virtual switch
Virtual switch is mapped to a dedicated server port connected to the Cisco SPAN port. OS sharing is allowed. VLAN identification is disabled. NDIS capture is enabled but NDIF also lists an errors in the window: "The Selected Extension is not operating correctly. Check the event logs for further information. If this is a non-Microsoft Extention, contact the vendor for further troubleshooting steps."
Server NIC is configured as a Hyper-V source as explained here: https://cloudbase.it/hyper-v-promiscuous-mode/
I can only see traffic from the server on the VM port. Nothing from the SPAN.
Is it even possible to setup what I'm trying to achieve? If so, am I missing something?
Thank you very much
VM NIC:
VSwitch:

How to configure a new host and virtual machine on opennebula?

We're using OpenNebula to simulate a simple replicated JBoss application.
We've installed all opennebula packages, qemu and kvm and libvirt.
We have created a simple ethernet network ad hoc between my pc (a node) and the one of my friend (which is both node and front-end) by plugging an ethernet cable between me and him (10.0.0.1 and 10.0.0.2).
So we can ping each other correctly, we've set everything to that we can ssh without a password to each other with "oneadmin" user.
We've configured all files such as below:
/etc/libvirt/libvirtd.conf
/etc/default/libvirtd-bin
And so on...
kvm and kvm-intel are both enabled.
The daemon
libvirtd -d -l
seems to start correctly.
In fact, from the gui of opennebula in the front end, we can see both the hosts monitored.
Anyway there's a problem when we try to start the virtual machine on the node which is not the front-end. I mean when we try to do a deploy of a VM on the other node. The error is something like this
cannot stat `/var/lib/one/datastores/1/f5394317d377beaa09fc07697df9ff68
but if, from the front end which has virtual machine n°1 we perform,
cd /var/lib/one/datastores/1
then we can see that file, we've also given all the permissions to it...
Any idea? :(
This may be related with the datastore configuration. If you left the default values, OpenNebula expects a shared filesystem (ie NFS) between the front-end and the virtualization nodes.
More context on the error (which I believe can be found in /var/lib/one/oned.log) would help analysing this problem.

qemu guest automation

I've not been able to find any documentation stating the existence of an API that can be used to automate things inside of a qemu guest.
For example, I would like to launch a process inside of the guest machine from the host machine. Libvirt does not appear to contain such functionality.
[Note: Automation without using any virtualization API. From my blog post.]
Step 1:
By default, QEMU uses SDL to display the VGA output. So, the first step is make this interaction with QEMU through standard I/O. QEMU provides an option for this.
From QEMU docs:
-nographic Normally, QEMU uses SDL to display the VGA output. With this option, you can totally disable graphical output so that QEMU is
a simple command line application. The emulated serial port is
redirected on the console. Therefore, you can still use QEMU to debug
a Linux kernel with a serial console.
So, all you have to do is invoke QEMU with -nographic.
qemu -nographic -hda guest.disk
Step 2:
Now that you can interact with your guest (or QEMU process) through command line, you have to automate this interaction. The obvious way to do this in python is start the QEMU process (with -nographic) with subprocess module and then communicate with that process. But to my surprise, this just didn’t work out for me. So, I looked for some other way.
Later, I found out that the most awesome tool for this kind of jobs is Expect. It is an automation tool for interactive applications written in TCL.
This guide should help you in getting started with Expect. Here is the script to run a guest with QEMU using Expect.
#!/usr/bin/expect -f
#starts guest vm, run benchmarks, poweroff
set timeout -1
#Assign a variable to the log file
set log [lindex $argv 0]
#Start the guest VM
spawn qemu -nographic -hda guest.disk
#Login process
expect "login: "
#Enter username
send "user\r"
#Enter Password
expect "Password: "
send "user\r"
#Do whatever you want to do with in the guest VM. ( Run a process and write result to log )
#poweroff the Guest VM
expect "# "
send "shutdown -h now\r"
The QEMU Monitor can interact with guest systems to a limited extent using it's own console. This includes reading registers, controlling the mouse/keyboard, and getting screen dumps.
There is a QEMU Monitor Protocol (QMP) that let's you pass JSON commands to and read values from the guest system.
As far as I know, the only way to communicate to the guest is through the network bridge.
I use python with pexpect to interact with spawned VMs using their serial consoles. I generally automate scenarios that have up to 128VMs this way, its reasonably swift. I generally use virt-install to instantiate guests, and use "virsh console (domainname)" using pexpect to get a "handle" to each console, so I can send commands to configure networking, startup tools/utilities/scripts, monitor operation, etc. Pretty sweet in terms of simplicity, and since the scripts are just issuing shell commands, you aren't exposed to APIs that change from version to version, e.g. the serial console will always be there. Sometimes I use qemu directly, (lately I am working with a QEMU that libvirt doesn't support since its too new), in that case I will have the guest console use a telnet port so I can "telnet localhost portnumber" to make a console connection instead of "virsh console (domainname)". Either way, python scripts with the pexpect module for interacting with VMs is great.
PyQemu can theoretically do this. I've used it in the past, although it looks like a stale project now. It provides a python agent (the equivalent of VMWare guest tools) to run on the guest, communicating with the host via serial port. You can get proxies to python modules running in the context of the VM, and any communication with them is marshaled over the serial port. In the following example, AutoIt is being used to automate Notepad:
machine = PyQemu.GetProxy("win2k")
# Wrap the machine object in another proxy representing the 'os'
# module running inside the VM.
os = PyQemu.vm.Module(machine,"os")
# NOTE: This is running on the VM!
os.system("notepad")
# Get an IDispatch object representing the autoit ActiveX control
autoit = PyQemu.vm.Dispatch(machine,"AutoItX3.Control")
# See if a window is active on the VM
state = autoit.WinActive("Untitled -")
Caveat: Due to using the serial port it is far from quick (regardless of serial speed settings), so perhaps best to transfer any bulk data by other means, e.g. Virtual FAT disk image.
You can create a reverse ssh tunnel from guest to host, which will redirect each request to host on specific port to guest. This way will help you to control guest from host.
If you're running Linux in the guest, couldn't you just use ssh/screen to launch remote processes on the guest?
Alternatively, I have seen people write python wrappers that use popen() to grab stdin/stdout and use those to automate some commands (i.e. when you see the login prompt, send the login name to stdin of QEMU.

Performance of local domain vs localhost

Is there a performance difference between TCP connections to:
localhost / 127.0.0.1
a domain which resolves to the local machine
Or more specifically, do the latter connections go through the loopback device, or over the actual network?
The reason I'm asking is I'm thinking about changing database settings in many PHP apps so they use a full domain instead of localhost. That way we could more easily move the database to a different server, if the need arises.
This is implementation and operating system dependent. On Windows, anything connecting to a local IP address, even if it is an outside-facing IP, will go over loopback. This is a documented problem for applications such as packet sniffers, because you can't sniff the loopback. (Windows doesn't treat loopback as a "device" -- it is handled at the network level.) However, in this case it would work in your favor.
Linux, in contrast, will follow whatever you have in your routing table, so packets that are destined to your local machine will go to your local machine over the network if the routing table isn't properly configured. However, in 99% of the cases the routing will be configured properly. Your packets won't go over the loopback device, but the TCP/IP stack will know that you are contacting a local IP and it will virtually go out and back in the proper ethernet device.
In a properly configured environment, the only bottleneck for using a domain name would be DNS resolution time. Contacting an outside DNS can add additional latency into your configuration. However, if you add in the domain name into your /etc/hosts file (C:\Windows\System32\drivers\etc\hosts on Windows), your system will skip the DNS resolution phase and obtain an IP directly, making this time cost moot.
That depends on how the names are resolved. The procedure is typically /etc/hosts first and then DNS if that fails. If localhost is in your /etc/hosts, putting whatever.wherever in the file as well will make it resolve with the same speed.