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