examples/common_components/protocol_examples_tapif_io/README.md
This component implements a tap networking interface that provides connectivity to host network using tuntap interface in Linux.
It could be used to route lwip traffic to host side network, typically when working with the Linux target.
main component of your project using the following idf_component.yml file:dependencies:
tapif_io:
path: ${IDF_PATH}/examples/common_components/tapif_io
#include "esp_netif.h" // esp-netif
#include "tapio.h" // esp-netif's driver side
#include "lwip/tapif.h" // esp-netif's network stack side
esp_netif_driver_ifconfig_t driver_cfg = {
.handle = tapio_create(),
.transmit = tapio_output,
};
b) configure the lwip netif for the tap interface
struct esp_netif_netstack_config stack_cfg = {
.lwip = {
.init_fn = lwip_tapif_init,
.input_fn = lwip_tapif_input,
}
};
c) configure the esp-netif basic parameters
esp_netif_inherent_config_t base_cfg = {
.if_key = "TAP", // unique name of the interface
.flags = ESP_NETIF_FLAG_AUTOUP, // no dhcp client, starts when it's set up
.ip_info = &ip_info, // add static IP info
.route_prio = 100 // priority for setting default gateway
};
esp_netif_t *tap_netif = esp_netif_new(&cfg);
esp_netif_attach(tap_netif, driver_cfg.handle);
Create a new tun/tap interface type named tap0
a) You can run the script ./make_tap_netif
b) Update the IP address of the interface to correspond to the configured static IP in previous step
Start the application and send/receive the packets via tap0 interface
Is useful to experiment with one interface with no intention to connect to internet or external facilities.
Typically, when we want to create a server listening on the tap0 interface and run a client in lwip, e.g. the default tcp_client socket example in IDF.
./make_tap_netif and set the IP address not to overlap with any other IPv4 network range (e.g. ip addr add 192.168.5.1/24 dev tap0)tapif_io component to use static address from that range (e.g. 192.168.5.x)tcp_client example to connect to the tap interface IP address (e.g. 192.168.5.1)nc -l 3333)tcp_client example to send and receive data between the server created in the previous step.This allows using full-featured network facilities of your host network, but a care must be taken to the selected IP addresses to avoid potential conflicts.
tap0 interface from the range used by your host system's default gateway (e.g. ip addr add 192.168.0.123/24 dev tap0, assuming the default netif is eth0 with IP range of 192.168.0.x and this address doesn't overlap with any other IP address in this network)tapif_io with another address from the same range, e.g.CONFIG_EXAMPLE_CONNECT_TAPIF_IP_ADDR="192.168.0.100"
CONFIG_EXAMPLE_CONNECT_TAPIF_NETMASK="255.255.255.0"
CONFIG_EXAMPLE_CONNECT_TAPIF_GW="192.168.0.1"
assuming that the default gateway of your host network is configured to 192.168.0.1
(Note, that the IP forwarding must be enabled in the host system:
echo 1 > /proc/sys/net/ipv4/ip_forward
)
Uses an isolated interface with routing and NAT-ing between interfaces
tap0 interface address not to overlap with any other IPv4 network range.MASQUERADE target to route network traffic between tap0 and your default network interface (eth0 in the below example).sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -i eth0 -o tap0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i tap0 -o eth0 -j ACCEPT
It's also possible to configure the lwip interface to use DHCP client (common setup for most default network interfaces, such as Ethernet or WiFi station) and set up a DHCP server on the host machine to assign the IP address dynamically.
This component sets up a DHCP client if CONFIG_EXAMPLE_CONNECT_WAIT_FOR_IP is enabled and waits for assigning an IP address. See below the description of DHCP client workflow for tap interface:
esp-netif up3c) to enable DHCP client esp_netif_inherent_config_t base_cfg = {
.if_key = "TAP",
.flags = (esp_netif_flags_t)(ESP_NETIF_DHCP_CLIENT | ESP_NETIF_FLAG_EVENT_IP_MODIFIED | ESP_NETIF_FLAG_AUTOUP),
.route_prio = 100
};
esp_netif_action_connected(tap_netif, 0, 0, 0);
esp_netif_inherent_config_t base_cfg = {
...
.get_ip_event = TAP0_GOT_IP,
...
};
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, TAP0_GOT_IP, event_handler, NULL));
// wait for the IP event (e.g. using signalling semaphores from the handler)
// ...
esp_netif_ip_info_t ip_info = {};
ESP_LOGI("tap-init", "Assigned IP address:"IPSTR ",", IP2STR(&ip_info.ip));
Configure forwarding/routing if needed based on the previous sections.
Configure the DHCP server on the host machine
Example for isc-dhcp-server
INTERFACES="tap0";
authoritative;
subnet 192.168.5.0 netmask 255.255.255.0 {
range 192.168.5.2 192.168.5.200;
option routers 192.168.5.1;
option domain-name-servers 8.8.8.8;
}