bridge_console_cmd.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /*
  2. * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Unlicense OR CC0-1.0
  5. */
  6. #include <string.h>
  7. #include <inttypes.h>
  8. #include "esp_log.h"
  9. #include "esp_check.h"
  10. #include "esp_console.h"
  11. #include "argtable3/argtable3.h"
  12. #include "esp_eth_spec.h"
  13. #include "bridge_console_cmd.h"
  14. typedef struct {
  15. struct arg_str *addr;
  16. struct arg_int *port;
  17. struct arg_lit *drop;
  18. struct arg_lit *flood;
  19. struct arg_lit *cpu;
  20. struct arg_end *end;
  21. } br_add_fdb_args_t;
  22. typedef struct {
  23. struct arg_str *addr;
  24. struct arg_end *end;
  25. } br_remove_fdb_args_t;
  26. static const char *TAG = "br_config_console";
  27. static br_add_fdb_args_t s_add_args;
  28. static br_remove_fdb_args_t s_remove_args;
  29. static esp_netif_t *s_br_netif;
  30. static uint8_t s_br_port_cnt;
  31. static esp_err_t str2mac(const char *str, uint8_t *mac_addr)
  32. {
  33. unsigned int mac_tmp[ETH_ADDR_LEN];
  34. if (ETH_ADDR_LEN != sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x%*c",
  35. &mac_tmp[0], &mac_tmp[1], &mac_tmp[2],
  36. &mac_tmp[3], &mac_tmp[4], &mac_tmp[5])) {
  37. return ESP_ERR_INVALID_MAC;
  38. }
  39. for (int i = 0; i < ETH_ADDR_LEN; i++) {
  40. mac_addr[i] = (uint8_t)mac_tmp[i];
  41. }
  42. return ESP_OK;
  43. }
  44. static int cmd_br_fdb_add(int argc, char **argv)
  45. {
  46. int nerrors = arg_parse(argc, argv, (void **) &s_add_args);
  47. if (nerrors != 0) {
  48. arg_print_errors(stderr, s_add_args.end, argv[0]);
  49. return 1;
  50. }
  51. int exp_argc = 2;
  52. if (s_add_args.port->count > 0) {
  53. exp_argc += 2 * s_add_args.port->count;
  54. if (s_add_args.cpu->count > 0) {
  55. exp_argc++;
  56. }
  57. } else {
  58. exp_argc++;
  59. }
  60. ESP_RETURN_ON_FALSE(argc == exp_argc, 1, TAG, "Invalid number or combination of arguments");
  61. uint64_t port_mask = ESP_NETIF_BR_DROP;
  62. for (int i = 0; i < s_add_args.port->count; i++) {
  63. ESP_RETURN_ON_FALSE(s_add_args.port->ival[i] > 0 && s_add_args.port->ival[i] <= s_br_port_cnt, 1, TAG, "Invalid port number");
  64. port_mask |= 1 << ((uint64_t)(s_add_args.port->ival[i]) - 1);
  65. }
  66. if (s_add_args.drop->count > 0) {
  67. port_mask = ESP_NETIF_BR_DROP;
  68. }
  69. if (s_add_args.flood->count > 0) {
  70. port_mask = ESP_NETIF_BR_FLOOD;
  71. }
  72. if (s_add_args.cpu->count > 0) {
  73. port_mask |= ESP_NETIF_BR_FDW_CPU;
  74. }
  75. uint8_t mac_addr[ETH_ADDR_LEN];
  76. ESP_RETURN_ON_FALSE(str2mac(s_add_args.addr->sval[0], mac_addr) == ESP_OK,
  77. 1, TAG, "Ivalid MAC address format (expected xx:xx:xx:xx:xx:xx)");
  78. ESP_RETURN_ON_FALSE(esp_netif_bridge_fdb_add(s_br_netif, mac_addr, port_mask) == ESP_OK,
  79. 1, TAG, "Adding FDB entry failed");
  80. ESP_LOG_BUFFER_HEX_LEVEL(TAG, mac_addr, ETH_ADDR_LEN, ESP_LOG_DEBUG);
  81. ESP_LOGD(TAG, "portmask 0x%" PRIu64, port_mask);
  82. ESP_LOGI(TAG, "Bridge Config OK!");
  83. return 0;
  84. }
  85. static int cmd_br_fdb_remove(int argc, char **argv)
  86. {
  87. int nerrors = arg_parse(argc, argv, (void **) &s_remove_args);
  88. if (nerrors != 0) {
  89. arg_print_errors(stderr, s_remove_args.end, argv[0]);
  90. return 1;
  91. }
  92. uint8_t mac_addr[ETH_ADDR_LEN];
  93. ESP_RETURN_ON_FALSE(str2mac(s_remove_args.addr->sval[0], mac_addr) == ESP_OK,
  94. 1, TAG, "Ivalid MAC address format (expected xx:xx:xx:xx:xx:xx)");
  95. ESP_RETURN_ON_FALSE(esp_netif_bridge_fdb_remove(s_br_netif, mac_addr) == ESP_OK,
  96. 1, TAG, "Removing FDB entry failed");
  97. ESP_LOG_BUFFER_HEX_LEVEL(TAG, mac_addr, ETH_ADDR_LEN, ESP_LOG_DEBUG);
  98. ESP_LOGI(TAG, "Bridge Config OK!");
  99. return 0;
  100. }
  101. void example_register_br_config_commands(esp_netif_t *br_netif, uint8_t br_port_cnt)
  102. {
  103. ESP_LOGI(TAG, "Registering Bridge config commands.");
  104. s_add_args.addr = arg_str1(NULL, "addr", "<MAC address>", "MAC address to be added in expected xx:xx:xx:xx:xx:xx format");
  105. s_add_args.port = arg_intn("p", "port", "<port_num>", 0, br_port_cnt + 1, "Forward to Port Number");
  106. s_add_args.drop = arg_lit0("d", "drop", "Drop");
  107. s_add_args.flood = arg_lit0("f", "flood", "Flood to all ports");
  108. s_add_args.cpu = arg_lit0("c", "cpu", "Forward to CPU");
  109. s_add_args.end = arg_end(2);
  110. const esp_console_cmd_t br_add_fdb_cmd = {
  111. .command = "add",
  112. .help = "Add Forwarding Database entry",
  113. .hint = NULL,
  114. .func = &cmd_br_fdb_add,
  115. .argtable = &s_add_args
  116. };
  117. ESP_ERROR_CHECK(esp_console_cmd_register(&br_add_fdb_cmd));
  118. s_remove_args.addr = arg_str1(NULL, "addr", "<MAC address>", "MAC address to be removed in expected xx:xx:xx:xx:xx:xx format");
  119. s_remove_args.end = arg_end(1);
  120. const esp_console_cmd_t br_remove_fdb_cmd = {
  121. .command = "remove",
  122. .help = "Remove Forwarding Database entry",
  123. .hint = NULL,
  124. .func = &cmd_br_fdb_remove,
  125. .argtable = &s_remove_args
  126. };
  127. ESP_ERROR_CHECK(esp_console_cmd_register(&br_remove_fdb_cmd));
  128. s_br_netif = br_netif;
  129. s_br_port_cnt = br_port_cnt;
  130. }