kopia lustrzana https://github.com/espressif/esp-idf
114 wiersze
3.8 KiB
C
114 wiersze
3.8 KiB
C
/*
|
|
* SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
#include "esp_netif.h"
|
|
#include "esp_eth_netif_glue.h"
|
|
#include "esp_netif_net_stack.h"
|
|
#include "esp_event.h"
|
|
#include "esp_log.h"
|
|
#include "esp_check.h"
|
|
#include "lwip/esp_netif_net_stack.h"
|
|
#include "sdkconfig.h"
|
|
#include "lwip/prot/ethernet.h"
|
|
#include "lwip/prot/ieee.h"
|
|
#include "eth_vlan_utils.h"
|
|
#if CONFIG_ESP_NETIF_L2_TAP
|
|
#include "esp_vfs_l2tap.h"
|
|
#endif
|
|
|
|
|
|
/**
|
|
* @brief This function gets invoked when Ethernet receive a new packets.
|
|
*
|
|
* @note This function is to be registered as a callback function which get invoked when Ethernet receive a new packets.
|
|
*
|
|
* @param eth_handle handle of Ethernet driver
|
|
* @param buffer buffer of the received packet
|
|
* @param length length of the received packet
|
|
* @param priv private pointer
|
|
*
|
|
* @return
|
|
* - ESP_OK: input frame buffer to upper stack successfully
|
|
* - ESP_FAIL: error occurred when inputting buffer to upper stack
|
|
*/
|
|
esp_err_t eth_input_to_netif(esp_eth_handle_t eth_handle, uint8_t *buffer, uint32_t length, void *priv)
|
|
{
|
|
struct netif *lwip_netif;
|
|
u16_t netif_vlan_id;
|
|
struct eth_hdr *ethhdr = (struct eth_hdr *)buffer;
|
|
struct eth_vlan_hdr *vlan;
|
|
esp_vlan_netifs *vlan_netifs = (esp_vlan_netifs *)priv;
|
|
|
|
if (PP_HTONS(ETHTYPE_VLAN) != ethhdr->type) {
|
|
// L2 tap after VLAN is not supported.
|
|
#if CONFIG_ESP_NETIF_L2_TAP
|
|
esp_err_t ret = ESP_OK;
|
|
ret = esp_vfs_l2tap_eth_filter(eth_handle, buffer, (size_t *)&length);
|
|
if (length == 0) {
|
|
return ret;
|
|
}
|
|
#endif
|
|
return esp_netif_receive(vlan_netifs->esp_netif[0], buffer, length, NULL);
|
|
} else {
|
|
for (int i = 1; i < vlan_netifs->netif_count; i++) {
|
|
lwip_netif = esp_netif_get_netif_impl(vlan_netifs->esp_netif[i]);
|
|
netif_vlan_id = *((uint16_t *)netif_get_client_data(lwip_netif, LWIP_NETIF_CLIENT_DATA_INDEX_MAX + 1));
|
|
|
|
vlan = (struct eth_vlan_hdr *)(((char *)ethhdr) + SIZEOF_ETH_HDR);
|
|
|
|
if (VLAN_ID(vlan) == netif_vlan_id) {
|
|
return esp_netif_receive(vlan_netifs->esp_netif[i], buffer, length, NULL);
|
|
}
|
|
}
|
|
|
|
// If the vlan id of the incoming frame doesn't match with any of the interface send it to the default interface.
|
|
return esp_netif_receive(vlan_netifs->esp_netif[0], buffer, length, NULL);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief This function creates configuration for esp-netif Ethernet
|
|
*
|
|
* @param vlan_id handle of Ethernet driver, used to name the interface key.
|
|
* @param vlan_eth_cfg_o output parameter returning the esp-netif ethernet configuration.
|
|
*
|
|
* @return ESP_OK or ESP_FAIL
|
|
*/
|
|
esp_err_t get_vlan_netif_config(uint16_t vlan_id, esp_netif_config_t *vlan_eth_cfg_o)
|
|
{
|
|
// Create new default instance of VLAN esp-netif for Ethernet
|
|
char *if_key;
|
|
if (asprintf(&if_key, "ETH_VLAN%d", vlan_id) == -1) {
|
|
return ESP_FAIL;
|
|
}
|
|
|
|
esp_netif_inherent_config_t *esp_eth_vlan_base_config = malloc(sizeof(esp_netif_inherent_config_t));
|
|
if (NULL == esp_eth_vlan_base_config) {
|
|
return ESP_FAIL;
|
|
}
|
|
*esp_eth_vlan_base_config = (esp_netif_inherent_config_t)ESP_NETIF_INHERENT_DEFAULT_ETH();
|
|
esp_eth_vlan_base_config->if_key = if_key;
|
|
|
|
vlan_eth_cfg_o->base = esp_eth_vlan_base_config;
|
|
vlan_eth_cfg_o->driver = NULL;
|
|
vlan_eth_cfg_o->stack = ESP_NETIF_NETSTACK_DEFAULT_ETH;
|
|
|
|
return ESP_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief This function frees the memory allocated for configuration for esp-netif Ethernet
|
|
*
|
|
* @param vlan_eth_cfg configuration for esp-netif Ethernet
|
|
*/
|
|
void free_vlan_config(esp_netif_config_t *vlan_eth_cfg)
|
|
{
|
|
if ((NULL != vlan_eth_cfg) && (NULL != vlan_eth_cfg->base)) {
|
|
free((void *)(vlan_eth_cfg->base->if_key));
|
|
free((void *)(vlan_eth_cfg->base));
|
|
}
|
|
}
|