lwip/linux: Add lwip support for networking component under linux

linux/lwip: Wrap some IO posix functions
* to workaourd the FreeRTOS EINTR issue (when building without lwip)
* to correctly choose the sub-system based on fd (when building with
lwip) -- passing control to either linux/system or to lwip
This commit also addapts tapio-if to provide DHCP client by default and
configurable settings for static IP
This commit is contained in:
David Cermak
2023-04-03 20:31:51 +02:00
committed by David Čermák
parent 0bfffa0160
commit b2af4d9689
31 changed files with 277 additions and 88 deletions

View File

@@ -3,7 +3,7 @@ menu "Example Connection Configuration"
config EXAMPLE_CONNECT_LWIP_TAPIF
bool "connect using lwip to linux tap interface"
depends on IDF_TARGET_LINUX && ESP_NETIF_TCPIP_LWIP
default n
default y
if EXAMPLE_CONNECT_LWIP_TAPIF
config EXAMPLE_CONNECT_IPV4
@@ -18,24 +18,28 @@ menu "Example Connection Configuration"
help
Set to true to setup link local address and wait until it's valid
config EXAMPLE_CONNECT_WAIT_FOR_IP
bool "run DHCP and wait for IP"
default y
config EXAMPLE_CONNECT_TAPIF_IP_ADDR
string "Static IP address"
default "192.168.5.100"
depends on EXAMPLE_CONNECT_IPV4
depends on EXAMPLE_CONNECT_IPV4 && !EXAMPLE_CONNECT_WAIT_FOR_IP
help
Set static IP address.
config EXAMPLE_CONNECT_TAPIF_NETMASK
string "Static netmask address"
default "255.255.255.0"
depends on EXAMPLE_CONNECT_IPV4
depends on EXAMPLE_CONNECT_IPV4 && !EXAMPLE_CONNECT_WAIT_FOR_IP
help
Set static netmask address.
config EXAMPLE_CONNECT_TAPIF_GW
string "Static gateway address"
default "192.168.5.1"
depends on EXAMPLE_CONNECT_IPV4
depends on EXAMPLE_CONNECT_IPV4 && !EXAMPLE_CONNECT_WAIT_FOR_IP
help
Set static gateway address.

View File

@@ -110,6 +110,8 @@ 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:
1) **Configure and set the `esp-netif` up**
* Same as in [API usage](#Usage-of-the-API), but update the base esp-netif config `3c)` to enable DHCP client
@@ -125,14 +127,17 @@ and set up a DHCP server on the host machine to assign the IP address dynamicall
esp_netif_action_connected(tap_netif, 0, 0, 0);
```
* Wait for the IP address to be assigned.
This could be implemented as a wait loop below, as the esp-event currently doesn't support IP events on Linux target.
This could be implemented using an event handler
```cpp
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 = {};
while (ip_info.ip.addr == 0) {
ESP_LOGI("tap-init", "No IP assigned, waiting...");
usleep(1000000);
esp_netif_get_ip_info(tap_netif, &ip_info);
}
ESP_LOGI("tap-init", "Assigned IP address:"IPSTR ",", IP2STR(&ip_info.ip));
```

View File

@@ -4,26 +4,25 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdlib.h>
#include "esp_err.h"
#include "esp_log.h"
#include <stdlib.h>
#include "esp_netif.h"
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "esp_err.h"
#include "esp_log.h"
#include "esp_netif.h"
// Use linux system sockets to connect to tap interface
#define LWIP_HDR_LINUX_SYS_SOCKETS_H
#include <sys/socket.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <lwip/sys.h>
#include "errno.h"
#define LWIP_HDR_LINUX_SYS_SOCKETS_H
#include <linux/if.h>
#include <linux/if_tun.h>
#include <esp_netif_net_stack.h>
#define DEVTAP "/dev/net/tun"
#define DEVTAP_NAME "tap0"

View File

@@ -7,6 +7,26 @@
#include "esp_netif.h" // esp-netif
#include "tapio.h" // esp-netif's driver side
#include "lwip/tapif.h" // esp-netif's network stack side
#include "esp_log.h"
#if CONFIG_EXAMPLE_CONNECT_WAIT_FOR_IP
#include "esp_event.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
static const char *TAG = "linux_connect";
static EventGroupHandle_t s_events;
static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
{
xEventGroupSetBits(s_events, 1);
}
#endif // CONFIG_EXAMPLE_CONNECT_WAIT_FOR_IP
#define TAP0_GOT_IP (0x1234)
esp_err_t example_connect(void)
{
@@ -25,14 +45,20 @@ esp_err_t example_connect(void)
};
// configure inherent esp-netif parameters
esp_netif_ip_info_t ip_info = {};
esp_netif_flags_t netif_flags = (ESP_NETIF_FLAG_EVENT_IP_MODIFIED | ESP_NETIF_FLAG_AUTOUP);
#if !CONFIG_EXAMPLE_CONNECT_WAIT_FOR_IP
ip_info.ip.addr = ipaddr_addr(CONFIG_EXAMPLE_CONNECT_TAPIF_IP_ADDR);
ip_info.netmask.addr = ipaddr_addr(CONFIG_EXAMPLE_CONNECT_TAPIF_NETMASK);
ip_info.gw.addr = ipaddr_addr(CONFIG_EXAMPLE_CONNECT_TAPIF_GW);
#else
netif_flags |= ESP_NETIF_DHCP_CLIENT;
#endif
esp_netif_inherent_config_t base_cfg = {
.if_key = "TAP",
.flags = ESP_NETIF_FLAG_AUTOUP,
.ip_info = &ip_info,
.flags = netif_flags,
.get_ip_event = TAP0_GOT_IP,
.route_prio = 100
};
@@ -46,6 +72,15 @@ esp_err_t example_connect(void)
// create the interface and attach it to the tapio-handle
esp_netif_t *tap_netif = esp_netif_new(&cfg);
esp_netif_attach(tap_netif, driver_cfg.handle);
#if CONFIG_EXAMPLE_CONNECT_WAIT_FOR_IP
ESP_LOGI(TAG, "Waiting for IP addresses...");
esp_netif_action_connected(tap_netif, 0, 0, 0);
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, TAP0_GOT_IP, event_handler, NULL));
s_events = xEventGroupCreate();
xEventGroupWaitBits(s_events, 1, pdFALSE, pdFALSE, portMAX_DELAY);
esp_netif_get_ip_info(tap_netif, &ip_info);
ESP_LOGI(TAG, "Assigned IP address:"IPSTR ",", IP2STR(&ip_info.ip));
#endif // CONFIG_EXAMPLE_CONNECT_WAIT_FOR_IP
#endif // EXAMPLE_CONNECT_LWIP_TAPIF
return ESP_OK;
}