esp-mesh-lite icon indicating copy to clipboard operation
esp-mesh-lite copied to clipboard

API to Determine the Next-Hop Neighbor for a Destination MAC (AEGHB-1113)

Open RubenKelevra opened this issue 8 months ago • 7 comments

Checklist

  • [x] Checked the issue tracker for similar issues to ensure this is not a duplicate.
  • [x] Described the feature in detail and justified the reason for the request.
  • [x] Provided specific use cases and examples.

Feature description

The current ESP-MESH-LITE API provides a flat list of all nodes in the mesh via esp_mesh_lite_get_nodes_list(), but it does not expose the parent-child relationships required to reconstruct the mesh's tree topology.

This makes it impossible for an application to determine the immediate next-hop neighbor for a packet destined for another node within the mesh.

We request a mechanism to get this next-hop information. This could be implemented in one of two ways:

  1. A new API function that directly returns the next hop for a given final destination, for example: esp_err_t esp_mesh_lite_get_next_hop(const uint8_t* final_dest_mac, uint8_t* next_hop_mac);

  2. Enhancing the existing node info struct to include the parent's MAC address, which would allow an application to build the topology itself and determine the path.

Use cases

The primary use case for this feature is to enable advanced, topology-aware applications that need to apply per-neighbor logic before a packet is transmitted. This includes:

  • Active Queue Management (AQM): Implementing schedulers that calculate traffic budget based on the next hop to not overload single nodes
  • Link Cost Estimation: Allowing an application to monitor the health and performance of individual mesh links by associating TX/RX statistics with a specific parent or child.
  • Advanced Diagnostics: Building tools that can accurately visualize the real-time topology of the mesh, including parent-child relationships, for easier debugging and analysis.

Alternatives

We considered enabling promiscuous mode: An application could enable promiscuous Wi-Fi mode to capture all raw 802.11 frames and extract the necessary metadata. This is an overly complex and resource-intensive solution that would require re-implementing significant parts of the network stack just to get this one piece of information.

Additional context

No response

RubenKelevra avatar Jun 15 '25 07:06 RubenKelevra

The esp_mesh_lite_get_nodes_list functionality is part of our application demo code, which was specifically created to demonstrate the usage patterns of internal communication interfaces.

For reference, see: https://github.com/espressif/esp-mesh-lite/blob/master/components/mesh_lite/src/esp_mesh_lite.c

The current mesh topology information feature may not cover all use cases. If you have improvement suggestions or additional requirements, you can directly modify and extend this implementation.

tswen avatar Jun 16 '25 04:06 tswen

Thank you for pointing me to esp_mesh_lite.c. I've studied the implementation carefully.

The current node list implementation collects MAC, IP, and level information from nodes. However, I notice that the parent-child relationship is not included in the esp_mesh_lite_node_info_t structure.

Unfortunately, this routing information appears to be maintained internally by the ESP-MESH-LITE core library, so I cannot extend the current implementation to add this feature myself.

What I'm looking for is quite simple: When my application wants to send a packet to a specific MAC address in the mesh, I need to know which immediate neighbor-mac ESP-MESH-LITE will send it to.

For example:

  • If I got an package addressed to say MAC 11:22:33:44:55:66
  • And ESP-MESH-LITE will route it through my parent (AA:BB:CC:DD:EE:FF)
  • I need to know that AA:BB:CC:DD:EE:FF is the next hop

This would be used in my open source application to determine the amount of traffic shaping.

Would it be possible to provide a simple query function to get the next-hop MAC for a given destination?


I suggested adding parent_mac to esp_mesh_lite_node_info_t because this would benefit many use cases beyond mine - for example, applications could visualize the complete mesh topology as a tree diagram. However, for my specific use case, I only need the next-hop information. Maintaining a complete duplicate of the mesh routing table in application memory would be significant overhead when I just need to query "which neighbor handles packets to this destination?"

RubenKelevra avatar Jun 16 '25 06:06 RubenKelevra

https://github.com/espressif/esp-mesh-lite/blob/master/components/mesh_lite/include/esp_mesh_lite.h#L46-L56

The esp_mesh_lite.c file contains open-source application code that you can modify directly if needed. For parent node information, you can use the esp_wifi_sta_get_ap_info(&ap_info) interface to retrieve it.

tswen avatar Jun 16 '25 08:06 tswen

Thank you for your patience, @tswen. I think you're visualizing a different use case.

To my understanding, ESP-MESH-LITE uses the standard LwIP forwarding mechanism, so I can install hooks like this:

// Acquire the LwIP netif for the Wi‑Fi station interface
esp_netif_t *netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF");
struct netif *lwip_netif = esp_netif_get_netif_impl(netif);

// Keep the original callback
static netif_linkoutput_fn original_linkoutput = NULL;

static err_t my_linkoutput_hook(struct netif *netif, struct pbuf *p)
{
    // TODO: Inspect p->payload for next-hop or QoS fields (if applicable)

    // Insert your QoS logic here…

    // Forward to the original driver
    return original_linkoutput ? original_linkoutput(netif, p) : ERR_IF;
}

void install_qos_hook(void)
{
    if (!original_linkoutput) {
        original_linkoutput = lwip_netif->linkoutput;
        lwip_netif->linkoutput = my_linkoutput_hook;
    }
}

The reason I need this is that I intercept packages via LwIP hook on the bridge and do traffic shaping before I let them continue on their journey.

So say I send data from Node A to Node D, and in between is Node B and C: A -> B -> C -> D

My code running on Node B will now “see” traffic for Node D but won't be able to determine to which neighbor the traffic will be routed next, only that it's not an immediate neighbor.

This information however, is necessary for the type of shaping I'm doing: It implements airtime fairness for communication partners talking across the mesh.

So I need to know to which neighbor the package is routed next, and at which TX rate (roughly), to calculate how much airtime each package used up.

Hence, my question how I query ESP-MESH-LITE for either a full tree structure of the mesh, meaning I require the parent information for all nodes on every node, to calculate the next hop in my code. This approach has the benefit of allowing to build a map of the mesh, which could be seen as an additional use case.

Or I need a way to query ESP-MESH-LITE "I got traffic for this MAC address, give me the MAC address of the mesh node you will send this package next", which would be the lightweight option, where I don't need the parents of all nodes on all nodes.

Hope this makes my use case and the information I require more clear.

And yes, my code currently does fetch the local parent, too, but that's sadly not enough to determine the next hop in all cases.

RubenKelevra avatar Jun 16 '25 11:06 RubenKelevra

Currently, the mesh-lite internally has preliminarily implemented the functionality to obtain the entire mesh tree topology, but it is still in the final testing phase. Since updates on GitHub have been temporarily suspended, if you remain interested in the mesh-lite solution, you can check #186 for future developments.

Of course, as you mentioned earlier, this can also be fully implemented at the application layer.

tswen avatar Aug 05 '25 08:08 tswen

@tswen I'm definitely still interested, thanks a lot for the update! However since the support is needed for an Open Source Project: ESPHome, the solution to become a customer is not an option here.

It would be nice if this preliminarily function can be provided with a public API, so open source projects can use it too.

Would that be possible?

RubenKelevra avatar Aug 05 '25 19:08 RubenKelevra

Hi @RubenKelevra, As mentioned in this post: https://github.com/espressif/esp-mesh-lite/issues/186#issue-3283635312, the ESP-Mesh-Lite open-source repository will enter Maintenance Mode, during which only essential security patches and critical bug fixes will be provided.

Therefore, no new feature updates will be made on GitHub in the future.

But I believe this feature can be implemented at the application layer through inter-node reporting communication.

tswen avatar Aug 07 '25 09:08 tswen