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