eth_vlan_utils.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. /*
  2. * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #include "esp_netif.h"
  7. #include "esp_eth_netif_glue.h"
  8. #include "esp_netif_net_stack.h"
  9. #include "esp_event.h"
  10. #include "esp_log.h"
  11. #include "esp_check.h"
  12. #include "lwip/esp_netif_net_stack.h"
  13. #include "sdkconfig.h"
  14. #include "lwip/prot/ethernet.h"
  15. #include "lwip/prot/ieee.h"
  16. #include "eth_vlan_utils.h"
  17. #if CONFIG_ESP_NETIF_L2_TAP
  18. #include "esp_vfs_l2tap.h"
  19. #endif
  20. /**
  21. * @brief This function gets invoked when Ethernet receive a new packets.
  22. *
  23. * @note This function is to be registered as a callback function which get invoked when Ethernet receive a new packets.
  24. *
  25. * @param eth_handle handle of Ethernet driver
  26. * @param buffer buffer of the received packet
  27. * @param length length of the received packet
  28. * @param priv private pointer
  29. *
  30. * @return
  31. * - ESP_OK: input frame buffer to upper stack successfully
  32. * - ESP_FAIL: error occurred when inputting buffer to upper stack
  33. */
  34. esp_err_t eth_input_to_netif(esp_eth_handle_t eth_handle, uint8_t *buffer, uint32_t length, void *priv)
  35. {
  36. struct netif *lwip_netif;
  37. u16_t netif_vlan_id;
  38. struct eth_hdr *ethhdr = (struct eth_hdr *)buffer;
  39. struct eth_vlan_hdr *vlan;
  40. esp_vlan_netifs *vlan_netifs = (esp_vlan_netifs *)priv;
  41. if (PP_HTONS(ETHTYPE_VLAN) != ethhdr->type) {
  42. // L2 tap after VLAN is not supported.
  43. #if CONFIG_ESP_NETIF_L2_TAP
  44. esp_err_t ret = ESP_OK;
  45. ret = esp_vfs_l2tap_eth_filter(eth_handle, buffer, (size_t *)&length);
  46. if (length == 0) {
  47. return ret;
  48. }
  49. #endif
  50. return esp_netif_receive(vlan_netifs->esp_netif[0], buffer, length, NULL);
  51. } else {
  52. for (int i = 1; i < vlan_netifs->netif_count; i++) {
  53. lwip_netif = esp_netif_get_netif_impl(vlan_netifs->esp_netif[i]);
  54. netif_vlan_id = *((uint16_t *)netif_get_client_data(lwip_netif, LWIP_NETIF_CLIENT_DATA_INDEX_MAX + 1));
  55. vlan = (struct eth_vlan_hdr *)(((char *)ethhdr) + SIZEOF_ETH_HDR);
  56. if (VLAN_ID(vlan) == netif_vlan_id) {
  57. return esp_netif_receive(vlan_netifs->esp_netif[i], buffer, length, NULL);
  58. }
  59. }
  60. // If the vlan id of the incoming frame doesn't match with any of the interface send it to the default interface.
  61. return esp_netif_receive(vlan_netifs->esp_netif[0], buffer, length, NULL);
  62. }
  63. }
  64. /**
  65. * @brief This function creates configuration for esp-netif Ethernet
  66. *
  67. * @param vlan_id handle of Ethernet driver, used to name the interface key.
  68. * @param vlan_eth_cfg_o output parameter returning the esp-netif ethernet configuration.
  69. *
  70. * @return ESP_OK or ESP_FAIL
  71. */
  72. esp_err_t get_vlan_netif_config(uint16_t vlan_id, esp_netif_config_t *vlan_eth_cfg_o)
  73. {
  74. // Create new default instance of VLAN esp-netif for Ethernet
  75. char *if_key;
  76. if (asprintf(&if_key, "ETH_VLAN%d", vlan_id) == -1) {
  77. return ESP_FAIL;
  78. }
  79. esp_netif_inherent_config_t *esp_eth_vlan_base_config = malloc(sizeof(esp_netif_inherent_config_t));
  80. if (NULL == esp_eth_vlan_base_config) {
  81. return ESP_FAIL;
  82. }
  83. *esp_eth_vlan_base_config = (esp_netif_inherent_config_t)ESP_NETIF_INHERENT_DEFAULT_ETH();
  84. esp_eth_vlan_base_config->if_key = if_key;
  85. vlan_eth_cfg_o->base = esp_eth_vlan_base_config;
  86. vlan_eth_cfg_o->driver = NULL;
  87. vlan_eth_cfg_o->stack = ESP_NETIF_NETSTACK_DEFAULT_ETH;
  88. return ESP_OK;
  89. }
  90. /**
  91. * @brief This function frees the memory allocated for configuration for esp-netif Ethernet
  92. *
  93. * @param vlan_eth_cfg configuration for esp-netif Ethernet
  94. */
  95. void free_vlan_config(esp_netif_config_t *vlan_eth_cfg)
  96. {
  97. if ((NULL != vlan_eth_cfg) && (NULL != vlan_eth_cfg->base)) {
  98. free((void *)(vlan_eth_cfg->base->if_key));
  99. free((void *)(vlan_eth_cfg->base));
  100. }
  101. }