Page 1 of 1

Ping session starts, no callbacks or results

Posted: Sun Mar 31, 2024 12:08 am
by MikeMyhre
I am using the KSZ8863RLL in two port mode. I have two ethernet ports each with a different IP address on my LAN.
IDF version 5.2.1 and am using the ping example code with a couple changes for debugging and binding to network interfaces. It appears to work without errors, but results in no pings reaching the target computer or ping success/fail callbacks being called.

Code: Select all

Output from monitor:
I (20605) net_action: Sending Ping
I (20605) ping: Interface eth1
I (20605) ping: Interface eth0
I (20605) net: Ping Initiated. Host: 192.168.0.163, IP: 192.168.0.163

Code: Select all

Ping initialization code:
send_ping("192.168.0.163");

void send_ping(char *host)
{
	// Get the interface keys
	uint8_t eth_idx = 0;
	esp_netif_t *ifscan = esp_netif_next(NULL);
	while (ifscan != NULL && u8KeyIndex < 3) {
		eth_idx = esp_netif_get_netif_impl_index(ifscan);
		char *desc = esp_netif_get_desc(ifscan);
		ESP_LOGI("ping","Interface %s",desc);
		ifscan = esp_netif_next(ifscan);
	}

    /* convert URL to IP address */
    ip_addr_t target_addr;
    struct addrinfo hint;
    struct addrinfo *res = NULL;
    memset(&hint, 0, sizeof(hint));
    memset(&target_addr, 0, sizeof(target_addr));
    getaddrinfo(host, NULL, &hint, &res);
    struct in_addr addr4 = ((struct sockaddr_in *) (res->ai_addr))->sin_addr;
    inet_addr_to_ip4addr(ip_2_ip4(&target_addr), &addr4);
    freeaddrinfo(res);

    esp_ping_config_t ping_config = ESP_PING_DEFAULT_CONFIG();
    ping_config.target_addr = target_addr;          // target IP address
    ping_config.count = 10; //ESP_PING_COUNT_INFINITE;    // ping in infinite mode, esp_ping_stop can stop it
    ping_config.interface = eth_idx;

    /* set callback functions */
    esp_ping_callbacks_t cbs;
    cbs.on_ping_success = test_on_ping_success;
    cbs.on_ping_timeout = test_on_ping_timeout;
    cbs.on_ping_end = test_on_ping_end;
    cbs.cb_args = "foo";  // arguments that feeds to all callback functions, can be NULL
    //cbs.cb_args = eth_event_group;

    esp_ping_handle_t ping;
    ESP_ERROR_CHECK(esp_ping_new_session(&ping_config, &cbs, &ping));

    ESP_LOGI("net","Ping Initiated. Host: %s, IP: %s",host, ip4addr_ntoa(&target_addr.u_addr.ip4));
}
I loop through the interfaces to show each of their names and use the last one to send the ping (last eth_idx found from ifscan).
I am successfully able to send broadcast messages (type 0x7000) and UDP packets to the same machine. Both IP addresses on my ESP32 board are pingable from the target host (192.168.0.163). Something is stuck internally in the ESP32 ping code.

Re: Ping session starts, no callbacks or results

Posted: Sun Aug 11, 2024 5:24 pm
by MikeMyhre
Using the new echo_example_main.c in the idf 5.2.1 code the pings work correctly with one exception:
I see them come back to the /dev/net/tap interfaces, but are not routed to the host stack for processing.
In other words: I can use a read() to grab the returned packet, but the ping function counts it as a timeout.
I have tried no opening the /dev/net/tab interfaces and changing the packet filter to a different number (than IP4 (0x800)) and it still shows not received.
How can I force the ping program to receive the packet (route it to the ping function)?

Re: Ping session starts, no callbacks or results

Posted: Mon Aug 12, 2024 7:19 am
by ESP_ondrej
Once you open tap interface for specific ethertype, these frames are then only accepted by the tap interface. They are not passed to the IP stack. It's described at: https://docs.espressif.com/projects/esp ... -interface
Please let me know if the documentation needed to be updated to make it clearer.

If you really really wanted to have opened tap for specific ethertype and pass it to bot both tap and IP stack, remove `return` at https://github.com/espressif/esp-idf/bl ... glue.c#L38

Re: Ping session starts, no callbacks or results

Posted: Mon Aug 12, 2024 2:25 pm
by MikeMyhre
ESP_ondrej wrote:
Mon Aug 12, 2024 7:19 am
Once you open tap interface for specific ethertype, these frames are then only accepted by the tap interface. They are not passed to the IP stack. It's described at: https://docs.espressif.com/projects/esp ... -interface
Please let me know if the documentation needed to be updated to make it clearer.

If you really really wanted to have opened tap for specific ethertype and pass it to bot both tap and IP stack, remove `return` at https://github.com/espressif/esp-idf/bl ... glue.c#L38
I am fine with most packets not being passed to the IP stack. In this part of the doc however it sounds like certain packets that don't match the filer should be passed to the stack (I am filtering by 0x800 or IP4 packets and changing that to a different number doesn't change the ping situation):
Filtering only specific frames is crucial since the ESP-NETIF L2 TAP needs to exist along with the IP stack and so the IP-related traffic (IP, ARP, etc.) should not be passed directly to the user application. Even though this option is still configurable, it is not recommended in standard use cases. Filtering is also advantageous from the perspective of the user's application, as it only gets access to the frame types it is interested in, and the remaining traffic is either passed to other L2 TAP file descriptors or to the IP stack.
in my case, I am able to send pings out any interface. If I send them out one of the Tap ports, I get that packet back as a raw L2 packet, which is nice because I can extract some information from the raw packet, but for ping to be effective in the results, I need a way to forward this packet onto the stack so the ping success statistics are right. If I can't do that, I need to reinvent the receive ping code. I thought the esp_netif_receive() function would do that but forwarding the packet to that function results in a block_is_free(block) exception and reboot.

Re: Ping session starts, no callbacks or results

Posted: Mon Aug 12, 2024 5:26 pm
by MikeMyhre
I found a work around but not sure if it is complete.
When calling eth_netif_receive() it wants to free the buffer, but my buffer is static and doesn't need to be freed.
I created my own empty function and assigned it to myNetif->driver_free_rx_buffer to override the default. Now the pings work and the statistics is correct. I wonder if other calls may need to have a buffer freed. Calls that I don't make to eth_netif_recieve() like ARP replies.
For now, I am going to check if the buffer points to my ping buffer and call the default free function if it doesn't.
Any hints on this?
Am I safe not freeing anything on that netif?

Re: Ping session starts, no callbacks or results

Posted: Mon Aug 12, 2024 5:38 pm
by MikeMyhre
I put in a log statement and see lots of buffers that need to be freed.
So I guess I need to identify my packets that don't need to be freed or I need to allocate a buffer that can be freed (preferred).

Re: Ping session starts, no callbacks or results

Posted: Tue Aug 13, 2024 6:46 am
by ESP_ondrej
I don't know details about your code so I cannot give you much more detailed answer. However, you need to free memory allocated for Ethernet frames (https://github.com/espressif/esp-idf/bl ... esp.c#L337)