You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
266 lines
8.1 KiB
266 lines
8.1 KiB
.. _networking_with_qemu: |
|
|
|
Networking with QEMU |
|
#################### |
|
|
|
.. contents:: |
|
:local: |
|
:depth: 2 |
|
|
|
This page describes how to set up a virtual network between a (Linux) host |
|
and a Zephyr application running in a QEMU virtual machine (built for Zephyr |
|
targets such as qemu_x86 and qemu_cortex_m3). Some virtual ARM boards (such as |
|
qemu_cortex_a53) only support a single UART, in this case QEMU Ethernet is |
|
preferred, see :ref:`networking_with_eth_qemu` for details. |
|
|
|
In this example, the :zephyr:code-sample:`sockets-echo-server` sample application from |
|
the Zephyr source distribution is run in QEMU. The QEMU instance is |
|
connected to a Linux host using a serial port, and SLIP is used to |
|
transfer data between the Zephyr application and Linux (over a chain of |
|
virtual connections). |
|
|
|
Prerequisites |
|
************* |
|
|
|
On the Linux Host, find the Zephyr `net-tools`_ project, which can either be |
|
found in a Zephyr standard installation under the ``tools/net-tools`` directory |
|
or installed stand alone from its own git repository: |
|
|
|
.. code-block:: console |
|
|
|
sudo apt install -y socat libpcap-dev |
|
git clone https://github.com/zephyrproject-rtos/net-tools |
|
cd net-tools |
|
make |
|
|
|
.. note:: |
|
|
|
If you get an error about AX_CHECK_COMPILE_FLAG, install package |
|
``autoconf-archive`` package on Debian/Ubuntu. |
|
|
|
Basic Setup |
|
*********** |
|
|
|
For the steps below, you will need at least 4 terminal windows: |
|
|
|
* Terminal #1 is your usual Zephyr development terminal, with the Zephyr environment |
|
initialized. |
|
* Terminals #2, #3, and #4 are terminal windows with net-tools being the current |
|
directory (``cd net-tools``) |
|
|
|
Step 1 - Create helper socket |
|
============================= |
|
|
|
Before starting QEMU with network emulation, a Unix socket for the emulation |
|
should be created. |
|
|
|
In terminal #2, type: |
|
|
|
.. code-block:: console |
|
|
|
./loop-socat.sh |
|
|
|
Step 2 - Start TAP device routing daemon |
|
======================================== |
|
|
|
In terminal #3, type: |
|
|
|
|
|
.. code-block:: console |
|
|
|
sudo ./loop-slip-tap.sh |
|
|
|
For applications requiring DNS, you may need to restart the host's DNS server |
|
at this point, as described in :ref:`networking_internet`. |
|
|
|
Step 3 - Start app in QEMU |
|
========================== |
|
|
|
Build and start the ``echo_server`` sample application. |
|
|
|
In terminal #1, type: |
|
|
|
.. zephyr-app-commands:: |
|
:zephyr-app: samples/net/sockets/echo_server |
|
:host-os: unix |
|
:board: qemu_x86 |
|
:goals: run |
|
:compact: |
|
|
|
If you see an error from QEMU about unix:/tmp/slip.sock, it means you missed Step 1 |
|
above. |
|
|
|
Step 4 - Run apps on host |
|
========================= |
|
|
|
Now in terminal #4, you can run various tools to communicate with the |
|
application running in QEMU. |
|
|
|
You can start with pings: |
|
|
|
.. code-block:: console |
|
|
|
ping 192.0.2.1 |
|
ping6 2001:db8::1 |
|
|
|
You can use the netcat ("nc") utility, connecting using UDP: |
|
|
|
.. code-block:: console |
|
|
|
echo foobar | nc -6 -u 2001:db8::1 4242 |
|
foobar |
|
|
|
.. code-block:: console |
|
|
|
echo foobar | nc -u 192.0.2.1 4242 |
|
foobar |
|
|
|
If echo_server is compiled with TCP support (now enabled by default for |
|
the echo_server sample, CONFIG_NET_TCP=y): |
|
|
|
.. code-block:: console |
|
|
|
echo foobar | nc -6 -q2 2001:db8::1 4242 |
|
foobar |
|
|
|
.. note:: |
|
|
|
Use Ctrl+C to exit. |
|
|
|
You can also use the telnet command to achieve the above. |
|
|
|
Step 5 - Stop supporting daemons |
|
================================ |
|
|
|
When you are finished with network testing using QEMU, you should stop |
|
any daemons or helpers started in the initial steps, to avoid possible |
|
networking or routing problems such as address conflicts in local |
|
network interfaces. For example, stop them if you switch from testing |
|
networking with QEMU to using real hardware, or to return your host |
|
laptop to normal Wi-Fi use. |
|
|
|
To stop the daemons, press Ctrl+C in the corresponding terminal windows |
|
(you need to stop both ``loop-slip-tap.sh`` and ``loop-socat.sh``). |
|
|
|
Exit QEMU by pressing :kbd:`CTRL+A` :kbd:`x`. |
|
|
|
.. _networking_internet: |
|
|
|
Setting up Zephyr and NAT/masquerading on host to access Internet |
|
***************************************************************** |
|
|
|
To access the internet from a Zephyr application, some additional |
|
setup on the host may be required. This setup is common for both |
|
application running in QEMU and on real hardware, assuming that |
|
a development board is connected to the development host. If a |
|
board is connected to a dedicated router, it should not be needed. |
|
|
|
To access the internet from a Zephyr application using IPv4, |
|
a gateway should be set via DHCP or configured manually. |
|
For applications using the "Settings" facility (with the config option |
|
:kconfig:option:`CONFIG_NET_CONFIG_SETTINGS` enabled), |
|
set the :kconfig:option:`CONFIG_NET_CONFIG_MY_IPV4_GW` option to the IP address |
|
of the gateway. For apps not using the "Settings" facility, set up the |
|
gateway by calling the :c:func:`net_if_ipv4_set_gw` at runtime. |
|
For example: ``CONFIG_NET_CONFIG_MY_IPV4_GW="192.0.2.2"`` |
|
|
|
To access the internet from a custom application running in QEMU, NAT |
|
(masquerading) should be set up for QEMU's source address. Assuming ``192.0.2.1`` is |
|
used and the Zephyr network interface is ``zeth``, the following command should be run as root: |
|
|
|
.. code-block:: console |
|
|
|
iptables -t nat -A POSTROUTING -j MASQUERADE -s 192.0.2.1/24 |
|
iptables -I FORWARD 1 -i zeth -j ACCEPT |
|
iptables -I FORWARD 1 -o zeth -m state --state RELATED,ESTABLISHED -j ACCEPT |
|
|
|
Additionally, IPv4 forwarding should be enabled on the host, and you may need to |
|
check that other firewall (iptables) rules don't interfere with masquerading. |
|
To enable IPv4 forwarding the following command should be run as root: |
|
|
|
.. code-block:: console |
|
|
|
sysctl -w net.ipv4.ip_forward=1 |
|
|
|
Some applications may also require a DNS server. A number of Zephyr-provided |
|
samples assume by default that the DNS server is available on the host |
|
(IP ``192.0.2.2``), which, in modern Linux distributions, usually runs at least |
|
a DNS proxy. When running with QEMU, it may be required to restart the host's |
|
DNS, so it can serve requests on the newly created TAP interface. For example, |
|
on Debian-based systems: |
|
|
|
.. code-block:: console |
|
|
|
service dnsmasq restart |
|
|
|
An alternative to relying on the host's DNS server is to use one in the |
|
network. For example, ``8.8.8.8`` is a publicly available DNS server. You can |
|
configure it using :kconfig:option:`CONFIG_DNS_SERVER1` option. |
|
|
|
|
|
Network connection between two QEMU VMs |
|
*************************************** |
|
|
|
Unlike the VM-to-Host setup described above, VM-to-VM setup is |
|
automatic. For sample |
|
applications that support this mode (such as the echo_server and echo_client |
|
samples), you will need two terminal windows, set up for Zephyr development. |
|
|
|
Terminal #1: |
|
============ |
|
|
|
.. zephyr-app-commands:: |
|
:zephyr-app: samples/net/sockets/echo_server |
|
:host-os: unix |
|
:board: qemu_x86 |
|
:goals: build |
|
:build-args: server |
|
:compact: |
|
|
|
This will start QEMU, waiting for a connection from a client QEMU. |
|
|
|
Terminal #2: |
|
============ |
|
|
|
.. zephyr-app-commands:: |
|
:zephyr-app: samples/net/sockets/echo_client |
|
:host-os: unix |
|
:board: qemu_x86 |
|
:goals: build |
|
:build-args: client |
|
:compact: |
|
|
|
This will start a second QEMU instance, where you should see logging of data sent and |
|
received in both. |
|
|
|
Running multiple QEMU VMs of the same sample |
|
******************************************** |
|
|
|
If you find yourself wanting to run multiple instances of the same Zephyr |
|
sample application, which do not need to talk to each other, use the |
|
``QEMU_INSTANCE`` argument. |
|
|
|
Start ``socat`` and ``tunslip6`` manually (instead of using the |
|
``loop-xxx.sh`` scripts) for as many instances as you want. Use the |
|
following as a guide, replacing MAIN or OTHER. |
|
|
|
Terminal #1: |
|
============ |
|
|
|
.. code-block:: console |
|
|
|
socat PTY,link=/tmp/slip.devMAIN UNIX-LISTEN:/tmp/slip.sockMAIN & |
|
sudo $ZEPHYR_BASE/../tools/net-tools/tunslip6 -t tapMAIN -T -s /tmp/slip.devMAIN 2001:db8::1/64 & |
|
# Now run Zephyr |
|
make -Cbuild run QEMU_INSTANCE=MAIN |
|
|
|
Terminal #2: |
|
============ |
|
|
|
.. code-block:: console |
|
|
|
socat PTY,link=/tmp/slip.devOTHER UNIX-LISTEN:/tmp/slip.sockOTHER & |
|
sudo $ZEPHYR_BASE/../tools/net-tools/tunslip6 -t tapOTHER -T -s /tmp/slip.devOTHER 2001:db8::1/64 & |
|
make -Cbuild run QEMU_INSTANCE=OTHER |
|
|
|
.. _`net-tools`: https://github.com/zephyrproject-rtos/net-tools
|
|
|