mirror of
https://github.com/espressif/esp-idf.git
synced 2026-04-27 19:13:21 +00:00
feat(esp_netif): Add support for initial MTU in netif config
Closes https://github.com/espressif/esp-idf/issues/15319
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -52,7 +52,8 @@ extern "C" {
|
||||
.if_key = "WIFI_STA_DEF", \
|
||||
.if_desc = "sta", \
|
||||
.route_prio = 100, \
|
||||
.bridge_info = NULL \
|
||||
.bridge_info = NULL, \
|
||||
.mtu = 0 \
|
||||
} \
|
||||
|
||||
#ifdef CONFIG_ESP_WIFI_SOFTAP_SUPPORT
|
||||
@@ -66,7 +67,8 @@ extern "C" {
|
||||
.if_key = "WIFI_AP_DEF", \
|
||||
.if_desc = "ap", \
|
||||
.route_prio = 10, \
|
||||
.bridge_info = NULL \
|
||||
.bridge_info = NULL, \
|
||||
.mtu = 0 \
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -79,7 +81,8 @@ extern "C" {
|
||||
.lost_ip_event = 0, \
|
||||
.if_key = "WIFI_NAN_DEF", \
|
||||
.if_desc = "nan", \
|
||||
.route_prio = 10 \
|
||||
.route_prio = 10, \
|
||||
.mtu = 0 \
|
||||
};
|
||||
|
||||
#define ESP_NETIF_INHERENT_DEFAULT_ETH() \
|
||||
@@ -92,7 +95,8 @@ extern "C" {
|
||||
.if_key = "ETH_DEF", \
|
||||
.if_desc = "eth", \
|
||||
.route_prio = 50, \
|
||||
.bridge_info = NULL \
|
||||
.bridge_info = NULL, \
|
||||
.mtu = 0 \
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPP_SUPPORT
|
||||
@@ -106,7 +110,8 @@ extern "C" {
|
||||
.if_key = "PPP_DEF", \
|
||||
.if_desc = "ppp", \
|
||||
.route_prio = 20, \
|
||||
.bridge_info = NULL \
|
||||
.bridge_info = NULL, \
|
||||
.mtu = 0 \
|
||||
}
|
||||
#endif /* CONFIG_PPP_SUPPORT */
|
||||
|
||||
@@ -120,7 +125,8 @@ extern "C" {
|
||||
.if_key = "BR0", \
|
||||
.if_desc = "br0", \
|
||||
.route_prio = 70, \
|
||||
.bridge_info = NULL \
|
||||
.bridge_info = NULL, \
|
||||
.mtu = 0 \
|
||||
}
|
||||
|
||||
#define ESP_NETIF_INHERENT_DEFAULT_BR_DHCPS() \
|
||||
@@ -133,7 +139,8 @@ extern "C" {
|
||||
.if_key = "BR1", \
|
||||
.if_desc = "br1", \
|
||||
.route_prio = 70, \
|
||||
.bridge_info = NULL \
|
||||
.bridge_info = NULL, \
|
||||
.mtu = 0 \
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -255,6 +255,7 @@ typedef struct esp_netif_inherent_config {
|
||||
A higher value of route_prio indicates
|
||||
a higher priority */
|
||||
bridgeif_config_t *bridge_info; /*!< LwIP bridge configuration */
|
||||
uint16_t mtu; /*!< Optional initial MTU (bytes). 0 = use stack default */
|
||||
} esp_netif_inherent_config_t;
|
||||
|
||||
typedef struct esp_netif_config esp_netif_config_t;
|
||||
|
||||
@@ -488,13 +488,11 @@ esp_netif_t *esp_netif_get_handle_from_ifkey(const char *if_key)
|
||||
// MTU control is not supported in loopback build.
|
||||
esp_err_t esp_netif_set_mtu(esp_netif_t *esp_netif, uint16_t mtu)
|
||||
{
|
||||
ESP_LOGD(TAG, "%s esp_netif:%p mtu:%u", __func__, esp_netif, (unsigned)mtu);
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
esp_err_t esp_netif_get_mtu(esp_netif_t *esp_netif, uint16_t *mtu)
|
||||
{
|
||||
ESP_LOGD(TAG, "%s esp_netif:%p", __func__, esp_netif);
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
#endif /* CONFIG_ESP_NETIF_LOOPBACK */
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "lwip/priv/tcpip_priv.h"
|
||||
#include "lwip/netif.h"
|
||||
#include "lwip/etharp.h"
|
||||
#include "lwip/prot/ip4.h"
|
||||
#if CONFIG_ESP_NETIF_BRIDGE_EN
|
||||
#include "netif/bridgeif.h"
|
||||
#endif // CONFIG_ESP_NETIF_BRIDGE_EN
|
||||
@@ -672,6 +673,9 @@ static err_t netif_mld_mac_filter_cb(struct netif *netif, const ip6_addr_t *grou
|
||||
|
||||
static esp_err_t esp_netif_init_configuration(esp_netif_t *esp_netif, const esp_netif_config_t *cfg)
|
||||
{
|
||||
#define MAX_MTU_SIZE 9000 /* lwip doesn't have a global maximum, 9000 is selected as a reasonable max MTU for most cases
|
||||
it is possible to override this upper bound by runtime configuration esp_netif_set_mtu() */
|
||||
|
||||
// Basic esp_netif and lwip is a mandatory configuration and cannot be updated after esp_netif_new()
|
||||
if (cfg == NULL || cfg->base == NULL || cfg->stack == NULL) {
|
||||
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
|
||||
@@ -703,6 +707,12 @@ static esp_err_t esp_netif_init_configuration(esp_netif_t *esp_netif, const esp_
|
||||
if (cfg->base->route_prio) {
|
||||
esp_netif->route_prio = cfg->base->route_prio;
|
||||
}
|
||||
// Store initial MTU preference (applied after netif_add()). 0 keeps stack default.
|
||||
if (cfg->base->mtu >= IP_HLEN && cfg->base->mtu <= MAX_MTU_SIZE) {
|
||||
esp_netif->configured_mtu = cfg->base->mtu;
|
||||
} else {
|
||||
esp_netif->configured_mtu = 0;
|
||||
}
|
||||
|
||||
#if CONFIG_ESP_NETIF_BRIDGE_EN
|
||||
// Setup bridge configuration if the interface is to be bridge
|
||||
@@ -1001,6 +1011,10 @@ static esp_err_t esp_netif_lwip_add(esp_netif_t *esp_netif)
|
||||
#if CONFIG_ESP_NETIF_BRIDGE_EN
|
||||
}
|
||||
#endif // CONFIG_ESP_NETIF_BRIDGE_EN
|
||||
// Apply configured MTU (if provided) after netif has been added and initialized
|
||||
if (esp_netif->configured_mtu) {
|
||||
esp_netif->lwip_netif->mtu = esp_netif->configured_mtu;
|
||||
}
|
||||
if (esp_netif->driver_set_mac_filter) {
|
||||
#if LWIP_IPV4 && LWIP_IGMP
|
||||
netif_set_igmp_mac_filter(esp_netif->lwip_netif, netif_igmp_mac_filter_cb);
|
||||
@@ -2701,9 +2715,6 @@ esp_err_t esp_netif_get_netif_impl_name(esp_netif_t *esp_netif, char* name)
|
||||
static esp_err_t esp_netif_set_mtu_api(esp_netif_api_msg_t *msg)
|
||||
{
|
||||
esp_netif_t *esp_netif = msg->esp_netif;
|
||||
if (esp_netif == NULL || esp_netif->lwip_netif == NULL || msg->data == NULL) {
|
||||
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
|
||||
}
|
||||
uint16_t mtu = *(uint16_t *)msg->data;
|
||||
esp_netif->lwip_netif->mtu = mtu;
|
||||
return ESP_OK;
|
||||
@@ -2715,6 +2726,11 @@ esp_err_t esp_netif_set_mtu(esp_netif_t *esp_netif, uint16_t mtu)
|
||||
if (esp_netif == NULL || esp_netif->lwip_netif == NULL) {
|
||||
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
|
||||
}
|
||||
/* Validate MTU is at least large enough for IP header */
|
||||
if (mtu < IP_HLEN) {
|
||||
ESP_LOGE(TAG, "MTU is too small, must be at least %d", IP_HLEN);
|
||||
return ESP_ERR_ESP_NETIF_INVALID_PARAMS;
|
||||
}
|
||||
return esp_netif_lwip_ipc_call(esp_netif_set_mtu_api, esp_netif, &mtu);
|
||||
}
|
||||
|
||||
|
||||
@@ -123,6 +123,8 @@ struct esp_netif_obj {
|
||||
#ifdef CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF
|
||||
ip_addr_t dns[DNS_MAX_SERVERS];
|
||||
#endif
|
||||
// initial MTU preference to apply after netif_add(); 0 means use stack default
|
||||
uint16_t configured_mtu;
|
||||
};
|
||||
|
||||
typedef enum esp_netif_set_default_state {
|
||||
|
||||
@@ -658,6 +658,48 @@ TEST(esp_netif, set_get_dnsserver)
|
||||
}
|
||||
}
|
||||
|
||||
TEST(esp_netif, initial_mtu_config_applied)
|
||||
{
|
||||
// Ensure TCP/IP stack is initialized
|
||||
test_case_uses_tcpip();
|
||||
|
||||
// Minimal driver config to satisfy start-time sanity checks
|
||||
esp_netif_driver_ifconfig_t driver_config = { .handle = (void*)1, .transmit = dummy_transmit };
|
||||
|
||||
// Case 1: explicit MTU configured
|
||||
uint16_t mtu_out = 0;
|
||||
esp_netif_inherent_config_t base1 = { .if_key = "mtu_if0" };
|
||||
base1.mtu = 1400;
|
||||
esp_netif_config_t cfg1 = {
|
||||
.base = &base1,
|
||||
.stack = ESP_NETIF_NETSTACK_DEFAULT_WIFI_STA,
|
||||
.driver = &driver_config,
|
||||
};
|
||||
esp_netif_t *n1 = esp_netif_new(&cfg1);
|
||||
TEST_ASSERT_NOT_NULL(n1);
|
||||
esp_netif_action_start(n1, NULL, 0, NULL);
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_netif_get_mtu(n1, &mtu_out));
|
||||
TEST_ASSERT_EQUAL_UINT16(1400, mtu_out);
|
||||
esp_netif_destroy(n1);
|
||||
|
||||
// Case 2: default MTU (0 means use stack default, e.g., 1500)
|
||||
esp_netif_inherent_config_t base2 = { .if_key = "mtu_if1" };
|
||||
// base2.mtu intentionally left 0
|
||||
esp_netif_config_t cfg2 = {
|
||||
.base = &base2,
|
||||
.stack = ESP_NETIF_NETSTACK_DEFAULT_WIFI_STA,
|
||||
.driver = &driver_config,
|
||||
};
|
||||
esp_netif_t *n2 = esp_netif_new(&cfg2);
|
||||
TEST_ASSERT_NOT_NULL(n2);
|
||||
esp_netif_action_start(n2, NULL, 0, NULL);
|
||||
TEST_ASSERT_EQUAL(ESP_OK, esp_netif_get_mtu(n2, &mtu_out));
|
||||
TEST_ASSERT_EQUAL_UINT16(1500, mtu_out);
|
||||
struct netif *netif = esp_netif_get_netif_impl(n2);
|
||||
TEST_ASSERT_EQUAL_UINT16(1500, netif->mtu);
|
||||
esp_netif_destroy(n2);
|
||||
}
|
||||
|
||||
TEST_GROUP_RUNNER(esp_netif)
|
||||
{
|
||||
/**
|
||||
@@ -686,6 +728,7 @@ TEST_GROUP_RUNNER(esp_netif)
|
||||
RUN_TEST_CASE(esp_netif, dhcp_server_state_transitions_wifi_ap)
|
||||
RUN_TEST_CASE(esp_netif, dhcp_server_state_transitions_mesh)
|
||||
#endif
|
||||
RUN_TEST_CASE(esp_netif, initial_mtu_config_applied)
|
||||
RUN_TEST_CASE(esp_netif, route_priority)
|
||||
RUN_TEST_CASE(esp_netif, set_get_dnsserver)
|
||||
RUN_TEST_CASE(esp_netif, unified_netif_status_event)
|
||||
|
||||
@@ -23,18 +23,30 @@ Notes:
|
||||
|
||||
3) Example output:
|
||||
```
|
||||
I (xxx) pmtu_probe: Connecting network...
|
||||
I (xxx) pmtu_probe: Probing PMTU to host www.espressif.com (IPv4)
|
||||
I (xxx) pmtu_probe: Search range payload=[0, 1472]
|
||||
I (xxx) pmtu_probe: Best payload=1392 -> MTU=1420
|
||||
I (xxx) pmtu_probe: Applying MTU 1420 to default netif
|
||||
I (8236) example_common: Connected to example_netif_sta
|
||||
I (8246) example_common: - IPv4 address: 192.168.0.35,
|
||||
I (8276) pmtu_probe: Probing PMTU to host www.espressif.com (IPv4)
|
||||
I (8276) pmtu_probe: Search range payload=[0, 1472]
|
||||
I (8286) pmtu_probe: Trying payload once with size 736
|
||||
I (8436) pmtu_probe: Trying payload once with size 1104
|
||||
I (8586) pmtu_probe: Trying payload once with size 1288
|
||||
I (8736) pmtu_probe: Trying payload once with size 1380
|
||||
I (8886) pmtu_probe: Trying payload once with size 1426
|
||||
I (9036) pmtu_probe: Trying payload once with size 1449
|
||||
I (9186) pmtu_probe: Trying payload once with size 1461
|
||||
I (9336) pmtu_probe: Trying payload once with size 1467
|
||||
I (9486) pmtu_probe: Trying payload once with size 1470
|
||||
I (9636) pmtu_probe: Trying payload once with size 1471
|
||||
I (9786) pmtu_probe: Trying payload once with size 1472
|
||||
I (9936) pmtu_probe: Best payload=1472 -> MTU=1500
|
||||
I (9936) pmtu_probe: Applying MTU 1500 to default netif
|
||||
I (9936) main_task: Returned from app_main()
|
||||
```
|
||||
|
||||
## Implementation details
|
||||
|
||||
- Uses `esp_ping` (ping_sock) to attempt 1 echo per payload size and waits synchronously for success/timeout.
|
||||
- Bounds the search using the current interface MTU when available, otherwise falls back to `1472`.
|
||||
- Applies MTU via new API:
|
||||
- Applies MTU via these API:
|
||||
- `esp_netif_set_mtu(esp_netif_t *netif, uint16_t mtu)`
|
||||
- `esp_netif_get_mtu(esp_netif_t *netif, uint16_t *mtu)`
|
||||
|
||||
|
||||
@@ -47,8 +47,9 @@ static void on_ping_end(esp_ping_handle_t hdl, void *args)
|
||||
}
|
||||
}
|
||||
|
||||
static bool try_payload_once(const ip_addr_t *target, uint32_t payload)
|
||||
static bool try_payload_once(const ip_addr_t *target, uint32_t payload_size)
|
||||
{
|
||||
ESP_LOGI(TAG, "Trying payload once with size %u", payload_size);
|
||||
probe_ctx_t ctx = { .done = xSemaphoreCreateBinary(), .got_reply = false };
|
||||
if (!ctx.done) {
|
||||
return false;
|
||||
@@ -58,7 +59,7 @@ static bool try_payload_once(const ip_addr_t *target, uint32_t payload)
|
||||
cfg.count = 1;
|
||||
cfg.timeout_ms = 1000; // 1s timeout
|
||||
cfg.interval_ms = 100; // not used for count=1
|
||||
cfg.data_size = payload;
|
||||
cfg.data_size = payload_size;
|
||||
esp_ping_callbacks_t cbs = {
|
||||
.cb_args = &ctx,
|
||||
.on_ping_success = on_ping_success,
|
||||
@@ -106,7 +107,9 @@ static bool resolve_host(const char *host, ip_addr_t *out)
|
||||
void app_main(void)
|
||||
{
|
||||
ESP_ERROR_CHECK(nvs_flash_init());
|
||||
ESP_ERROR_CHECK(esp_netif_init());
|
||||
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
||||
|
||||
ESP_LOGI(TAG, "Connecting network...");
|
||||
ESP_ERROR_CHECK(example_connect());
|
||||
|
||||
@@ -123,7 +126,7 @@ void app_main(void)
|
||||
return;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Probing PMTU to host %s (IPv4)");
|
||||
ESP_LOGI(TAG, "Probing PMTU to host %s (IPv4)", host);
|
||||
|
||||
uint16_t if_mtu = 0;
|
||||
uint32_t lo = 0;
|
||||
|
||||
Reference in New Issue
Block a user