1.. _networking_with_qemu:
2
3Networking with QEMU
4####################
5
6.. contents::
7    :local:
8    :depth: 2
9
10This page describes how to set up a virtual network between a (Linux) host
11and a Zephyr application running in a QEMU virtual machine (built for Zephyr
12targets such as qemu_x86 and qemu_cortex_m3). Some virtual ARM boards (such as
13qemu_cortex_a53) only support a single UART, in this case QEMU Ethernet is
14preferred, see :ref:`networking_with_eth_qemu` for details.
15
16In this example, the :zephyr:code-sample:`sockets-echo-server` sample application from
17the Zephyr source distribution is run in QEMU. The QEMU instance is
18connected to a Linux host using a serial port, and SLIP is used to
19transfer data between the Zephyr application and Linux (over a chain of
20virtual connections).
21
22Prerequisites
23*************
24
25On the Linux Host, find the Zephyr `net-tools`_ project, which can either be
26found in a Zephyr standard installation under the ``tools/net-tools`` directory
27or installed stand alone from its own git repository:
28
29.. code-block:: console
30
31   sudo apt install -y socat libpcap-dev
32   git clone https://github.com/zephyrproject-rtos/net-tools
33   cd net-tools
34   make
35
36.. note::
37
38   If you get an error about AX_CHECK_COMPILE_FLAG, install package
39   ``autoconf-archive`` package on Debian/Ubuntu.
40
41Basic Setup
42***********
43
44For the steps below, you will need at least 4 terminal windows:
45
46* Terminal #1 is your usual Zephyr development terminal, with the Zephyr environment
47  initialized.
48* Terminals #2, #3, and #4 are terminal windows with net-tools being the current
49  directory (``cd net-tools``)
50
51Step 1 - Create helper socket
52=============================
53
54Before starting QEMU with network emulation, a Unix socket for the emulation
55should be created.
56
57In terminal #2, type:
58
59.. code-block:: console
60
61   ./loop-socat.sh
62
63Step 2 - Start TAP device routing daemon
64========================================
65
66In terminal #3, type:
67
68
69.. code-block:: console
70
71   sudo ./loop-slip-tap.sh
72
73For applications requiring DNS, you may need to restart the host's DNS server
74at this point, as described in :ref:`networking_internet`.
75
76Step 3 - Start app in QEMU
77==========================
78
79Build and start the ``echo_server`` sample application.
80
81In terminal #1, type:
82
83.. zephyr-app-commands::
84   :zephyr-app: samples/net/sockets/echo_server
85   :host-os: unix
86   :board: qemu_x86
87   :goals: run
88   :compact:
89
90If you see an error from QEMU about unix:/tmp/slip.sock, it means you missed Step 1
91above.
92
93Step 4 - Run apps on host
94=========================
95
96Now in terminal #4, you can run various tools to communicate with the
97application running in QEMU.
98
99You can start with pings:
100
101.. code-block:: console
102
103   ping 192.0.2.1
104   ping6 2001:db8::1
105
106You can use the netcat ("nc") utility, connecting using UDP:
107
108.. code-block:: console
109
110   echo foobar | nc -6 -u 2001:db8::1 4242
111   foobar
112
113.. code-block:: console
114
115   echo foobar | nc -u 192.0.2.1 4242
116   foobar
117
118If echo_server is compiled with TCP support (now enabled by default for
119the echo_server sample, CONFIG_NET_TCP=y):
120
121.. code-block:: console
122
123   echo foobar | nc -6 -q2 2001:db8::1 4242
124   foobar
125
126.. note::
127
128   Use Ctrl+C to exit.
129
130You can also use the telnet command to achieve the above.
131
132Step 5 - Stop supporting daemons
133================================
134
135When you are finished with network testing using QEMU, you should stop
136any daemons or helpers started in the initial steps, to avoid possible
137networking or routing problems such as address conflicts in local
138network interfaces. For example, stop them if you switch from testing
139networking with QEMU to using real hardware, or to return your host
140laptop to normal Wi-Fi use.
141
142To stop the daemons, press Ctrl+C in the corresponding terminal windows
143(you need to stop both ``loop-slip-tap.sh`` and ``loop-socat.sh``).
144
145Exit QEMU by pressing :kbd:`CTRL+A` :kbd:`x`.
146
147.. _networking_internet:
148
149Setting up Zephyr and NAT/masquerading on host to access Internet
150*****************************************************************
151
152To access the internet from a Zephyr application, some additional
153setup on the host may be required. This setup is common for both
154application running in QEMU and on real hardware, assuming that
155a development board is connected to the development host. If a
156board is connected to a dedicated router, it should not be needed.
157
158To access the internet from a Zephyr application using IPv4,
159a gateway should be set via DHCP or configured manually.
160For applications using the "Settings" facility (with the config option
161:kconfig:option:`CONFIG_NET_CONFIG_SETTINGS` enabled),
162set the :kconfig:option:`CONFIG_NET_CONFIG_MY_IPV4_GW` option to the IP address
163of the gateway. For apps not using the "Settings" facility, set up the
164gateway by calling the :c:func:`net_if_ipv4_set_gw` at runtime.
165For example: ``CONFIG_NET_CONFIG_MY_IPV4_GW="192.0.2.2"``
166
167To access the internet from a custom application running in QEMU, NAT
168(masquerading) should be set up for QEMU's source address. Assuming ``192.0.2.1`` is
169used and the Zephyr network interface is ``zeth``, the following command should be run as root:
170
171.. code-block:: console
172
173   iptables -t nat -A POSTROUTING -j MASQUERADE -s 192.0.2.1/24
174   iptables -I FORWARD 1 -i zeth -j ACCEPT
175   iptables -I FORWARD 1 -o zeth -m state --state RELATED,ESTABLISHED -j ACCEPT
176
177Additionally, IPv4 forwarding should be enabled on the host, and you may need to
178check that other firewall (iptables) rules don't interfere with masquerading.
179To enable IPv4 forwarding the following command should be run as root:
180
181.. code-block:: console
182
183   sysctl -w net.ipv4.ip_forward=1
184
185Some applications may also require a DNS server. A number of Zephyr-provided
186samples assume by default that the DNS server is available on the host
187(IP ``192.0.2.2``), which, in modern Linux distributions, usually runs at least
188a DNS proxy. When running with QEMU, it may be required to restart the host's
189DNS, so it can serve requests on the newly created TAP interface. For example,
190on Debian-based systems:
191
192.. code-block:: console
193
194   service dnsmasq restart
195
196An alternative to relying on the host's DNS server is to use one in the
197network. For example, ``8.8.8.8`` is a publicly available DNS server. You can
198configure it using :kconfig:option:`CONFIG_DNS_SERVER1` option.
199
200
201Network connection between two QEMU VMs
202***************************************
203
204Unlike the VM-to-Host setup described above, VM-to-VM setup is
205automatic. For sample
206applications that support this mode (such as the echo_server and echo_client
207samples), you will need two terminal windows, set up for Zephyr development.
208
209Terminal #1:
210============
211
212.. zephyr-app-commands::
213   :zephyr-app: samples/net/sockets/echo_server
214   :host-os: unix
215   :board: qemu_x86
216   :goals: build
217   :build-args: server
218   :compact:
219
220This will start QEMU, waiting for a connection from a client QEMU.
221
222Terminal #2:
223============
224
225.. zephyr-app-commands::
226   :zephyr-app: samples/net/sockets/echo_client
227   :host-os: unix
228   :board: qemu_x86
229   :goals: build
230   :build-args: client
231   :compact:
232
233This will start a second QEMU instance, where you should see logging of data sent and
234received in both.
235
236Running multiple QEMU VMs of the same sample
237********************************************
238
239If you find yourself wanting to run multiple instances of the same Zephyr
240sample application, which do not need to talk to each other, use the
241``QEMU_INSTANCE`` argument.
242
243Start ``socat`` and ``tunslip6`` manually (instead of using the
244``loop-xxx.sh`` scripts) for as many instances as you want. Use the
245following as a guide, replacing MAIN or OTHER.
246
247Terminal #1:
248============
249
250.. code-block:: console
251
252   socat PTY,link=/tmp/slip.devMAIN UNIX-LISTEN:/tmp/slip.sockMAIN &
253   sudo $ZEPHYR_BASE/../tools/net-tools/tunslip6 -t tapMAIN -T -s /tmp/slip.devMAIN 2001:db8::1/64 &
254   # Now run Zephyr
255   make -Cbuild run QEMU_INSTANCE=MAIN
256
257Terminal #2:
258============
259
260.. code-block:: console
261
262   socat PTY,link=/tmp/slip.devOTHER UNIX-LISTEN:/tmp/slip.sockOTHER &
263   sudo $ZEPHYR_BASE/../tools/net-tools/tunslip6 -t tapOTHER -T -s /tmp/slip.devOTHER 2001:db8::1/64 &
264   make -Cbuild run QEMU_INSTANCE=OTHER
265
266.. _`net-tools`: https://github.com/zephyrproject-rtos/net-tools
267