ESP NETIF Custom I/O Driver with vfs_l2tap

mikckylmz
Posts: 1
Joined: Fri Jul 26, 2024 9:18 am

ESP NETIF Custom I/O Driver with vfs_l2tap

Postby mikckylmz » Fri Jul 26, 2024 9:43 am

Hello,
I am developing custom netif IO driver for Homeplug Modem. As described in https://docs.espressif.com/projects/esp ... river.html, I implemented function below with netif postattach function callback.
esp_netif_transmit()
esp_netif_free_rx_buffer()
esp_netif_receive()

Code: Select all

static esp_err_t qca_modem_post_attach(esp_netif_t *esp_netif, void *args)
{
    ESP_LOGI(TAG, "qca_modem_post_attach");

    esp_netif_driver_base_t *driver                   = args;
    const esp_netif_driver_ifconfig_t driver_ifconfig = {
        .driver_free_rx_buffer = qca_free,
        .transmit              = qca_modem_transmit,
        .handle                = (void *)1,
    };

    driver->netif = esp_netif;

    ESP_ERROR_CHECK(esp_netif_set_driver_config(esp_netif, &driver_ifconfig));

    qca_start();
    return ESP_OK;
}

// Initialise the QCA interface
esp_netif_t *qca_if_init(void)
{
    ESP_LOGI(TAG, "Initialising QCA interface");

    esp_netif_inherent_config_t base_cfg = ESP_NETIF_INHERENT_DEFAULT_ETH_QCA();
    esp_netif_config_t cfg = {.base = &base_cfg, .driver = NULL, .stack = ESP_NETIF_NETSTACK_DEFAULT_ETH};
    esp_netif_t *qca_netif = esp_netif_new(&cfg);
    IP6_ADDR(&qca_handle->addr, lwip_htonl(0xfd0000), lwip_htonl(0x00000000), lwip_htonl(0x00000000),
             lwip_htonl(0x00000001));

    ESP_LOGI(TAG, "Initialising QCA modem");
    qca_handle->netif_base.post_attach = qca_modem_post_attach;
    qca_handle->netif_base.netif       = qca_netif;

    ESP_ERROR_CHECK(esp_netif_attach(qca_netif, &qca_handle->netif_base));

    ESP_LOGI(TAG, "QCA if init complete");
    return qca_netif;
}
I tested with udp server and it is working properly. So packets transport to the network stack as expected.
My problem starts when I try to use l2tap interface to send homeplug configuration messages with ethernet type 0x88E1.
L2Tap Write Function calls esp_eth_transmit() and because of NULL ethernet driver I receive
"Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled."

Should I implement custom L2 write function to send raw packages?
Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled.

Core 0 register dump:
PC : 0x42026ccf PS : 0x00060830 A0 : 0x820258bc A1 : 0x3fcae2b0
0x42026ccf: esp_eth_transmit at C:/Espressif/frameworks/esp-idf-v5.2.2/components/esp_eth/src/esp_eth.c:353

A2 : 0x00000001 A3 : 0x3fcae38c A4 : 0x0000003c A5 : 0x0000000c
A6 : 0x00000000 A7 : 0x00000001 A8 : 0x3fc97fe4 A9 : 0x3fcaded0
A10 : 0x00000073 A11 : 0x00000000 A12 : 0x00000000 A13 : 0x3c048ee1
A14 : 0x00000005 A15 : 0x00000003 SAR : 0x00000004 EXCCAUSE: 0x0000001c
EXCVADDR: 0x0000002d LBEG : 0x400556d5 LEND : 0x400556e5 LCOUNT : 0xffffffec
0x400556d5: strlen in ROM
0x400556e5: strlen in ROM



Backtrace: 0x42026ccc:0x3fcae2b0 0x420258b9:0x3fcae2e0 0x42007dca:0x3fcae300 0x4202ab2e:0x3fcae320 0x42009a7b:0x3fcae340 0x4037bea6:0x3fcae860
0x42026ccc: esp_eth_transmit at C:/Espressif/frameworks/esp-idf-v5.2.2/components/esp_eth/src/esp_eth.c:353
0x420258b9: l2tap_write at C:/Espressif/frameworks/esp-idf-v5.2.2/components/esp_netif/vfs_l2tap/esp_vfs_l2tap.c:248
0x42007dca: esp_vfs_write at C:/Espressif/frameworks/esp-idf-v5.2.2/components/vfs/vfs.c:482 (discriminator 4)
0x4202ab2e: write at /builds/idf/crosstool-NG/.build/HOST-x86_64-w64-mingw32/xtensa-esp-elf/src/newlib/newlib/libc/syscalls/syswrite.c:11 (discriminator 1)
0x42009a7b: hello_tx_l2tap_task at D:/Work/Software/SECC-Test/main/SECC-Test.c:129
0x4037bea6: vPortTaskWrapper at C:/Espressif/frameworks/esp-idf-v5.2.2/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:134

Code: Select all

  
{ 
    int eth_tap_fd;
    uint16_t eth_type_filter = (0x88E1);

    if ((eth_tap_fd = init_l2tap_fd(0, eth_type_filter)) == INVALID_FD)
    {
        ESP_LOGI(TAG, "Error l2tap_fd");
    }

    op_attr_req_t msg = {0};

    memcpy(msg.dest, SLAC_BROADCAST_MAC_ADDRESS, 6);
    memcpy(msg.src, dummy_mac, 6);
    msg.ethertype     = htons(0x88E1);
    msg.mmv           = AV_1_0;
    msg.mmtype        = MMTYPE_OP_ATTR | MMTYPE_MODE_REQ;
    msg.vendor_mme[0] = 0x00;
    msg.vendor_mme[1] = 0xb0;
    msg.vendor_mme[2] = 0x52;
    msg.cookie        = 0x12345;
    msg.report_type   = 0;

    while (1)
    {
        // Send the Hello frame
        ssize_t ret = write(eth_tap_fd, tx.pucEthernetBuffer, tx.xDataLength);
        if (ret == -1)
        {
            ESP_LOGE(TAG, "L2 TAP fd %d write error: errno: %d", eth_tap_fd, errno);
            break;
        }
        vTaskDelay(pdMS_TO_TICKS(3000));
    }
 }

ESP_ondrej
Posts: 196
Joined: Fri May 07, 2021 10:35 am

Re: ESP NETIF Custom I/O Driver with vfs_l2tap

Postby ESP_ondrej » Fri Jul 26, 2024 12:04 pm

Hi mikckylmz,

the problem is the current L2TAP is hardcoded to be used only with Ethernet. However, it's written in a way it should be easily modifiable if the underlining physical layer uses Ethernet frames.

Try the following:
1) Replace transmit and free functions with your equivalents at https://github.com/espressif/esp-idf/bl ... tap.c#L223 If the same TX IO function is going to be used by both L2TAP and by LwIP (which looks like is the case), please do not forget for mutex in your IO function. It's going to be shared resource, see https://github.com/espressif/esp-idf/bl ... eth.c#L356 as example.
2) Update your input function to call `esp_vfs_l2tap_eth_filter()` prior calling `esp_netif_receive()` in similar way as done in eth_netif_glue https://github.com/espressif/esp-idf/bl ... glue.c#L36

If you needed any further assistance, please let me know. Anyway, this is very nice exercise even for me, since it should prove the L2TAP readiness to support custom IO. It would be great if you succeed and share your feedback. We could update the L2TAP based on your experience!

Who is online

Users browsing this forum: Google [Bot] and 50 guests