mirror of
https://github.com/esphome/esphome.git
synced 2026-10-09 21:13:12 +00:00
[wireguard] Keep allowed IPs in a shared flash table (#20087)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
pre-commit-ci-lite[bot]
parent
f7b80e6d44
commit
5cd7bf5993
@@ -121,16 +121,19 @@ async def to_code(config):
|
||||
)
|
||||
)
|
||||
|
||||
# Shared flash table ended by an empty entry, so the component stores only a pointer.
|
||||
entries = [
|
||||
cg.StructInitializer(
|
||||
AllowedIP,
|
||||
("ip", str(ip.network_address)),
|
||||
("netmask", str(ip.netmask)),
|
||||
)
|
||||
for ip in allowed_ips
|
||||
]
|
||||
end = cg.StructInitializer(AllowedIP, ("ip", cg.nullptr), ("netmask", cg.nullptr))
|
||||
cg.add(
|
||||
var.set_allowed_ips(
|
||||
[
|
||||
cg.StructInitializer(
|
||||
AllowedIP,
|
||||
("ip", str(ip.network_address)),
|
||||
("netmask", str(ip.netmask)),
|
||||
)
|
||||
for ip in allowed_ips
|
||||
]
|
||||
cg.shared_progmem_array("wireguard_allowed_ips", AllowedIP, [*entries, end])
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -154,8 +154,8 @@ void Wireguard::dump_config() {
|
||||
(this->preshared_key_ != nullptr ? preshared_key_masked : LOG_STR_LITERAL("NOT IN USE")));
|
||||
// clang-format on
|
||||
ESP_LOGCONFIG(TAG, " Peer Allowed IPs:");
|
||||
for (const AllowedIP &allowed_ip : this->allowed_ips_) {
|
||||
ESP_LOGCONFIG(TAG, " - %s/%s", allowed_ip.ip, allowed_ip.netmask);
|
||||
for (const AllowedIP *it = this->allowed_ips_; it != nullptr && it->ip != nullptr; it++) {
|
||||
ESP_LOGCONFIG(TAG, " - %s/%s", it->ip, it->netmask);
|
||||
}
|
||||
ESP_LOGCONFIG(TAG, " Peer Persistent Keepalive: %d%s", this->keepalive_,
|
||||
(this->keepalive_ > 0 ? LOG_STR_LITERAL("s") : LOG_STR_LITERAL(" (DISABLED)")));
|
||||
@@ -249,8 +249,8 @@ void Wireguard::start_connection_() {
|
||||
|
||||
ESP_LOGD(TAG, "Configuring allowed IPs list");
|
||||
bool allowed_ips_ok = true;
|
||||
for (const AllowedIP &ip : this->allowed_ips_) {
|
||||
allowed_ips_ok &= (esp_wireguard_add_allowed_ip(&(this->wg_ctx_), ip.ip, ip.netmask) == ESP_OK);
|
||||
for (const AllowedIP *it = this->allowed_ips_; it != nullptr && it->ip != nullptr; it++) {
|
||||
allowed_ips_ok &= (esp_wireguard_add_allowed_ip(&(this->wg_ctx_), it->ip, it->netmask) == ESP_OK);
|
||||
}
|
||||
|
||||
if (allowed_ips_ok) {
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include "esphome/core/defines.h"
|
||||
#ifdef USE_WIREGUARD
|
||||
#include <ctime>
|
||||
#include <initializer_list>
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
@@ -58,9 +57,8 @@ class Wireguard final : public PollingComponent {
|
||||
void set_peer_public_key(const std::string &key) = delete;
|
||||
void set_preshared_key(const std::string &key) = delete;
|
||||
|
||||
void set_allowed_ips(std::initializer_list<AllowedIP> ips) { this->allowed_ips_ = ips; }
|
||||
/// Prevent accidental use of std::string which would dangle
|
||||
void set_allowed_ips(std::initializer_list<std::tuple<std::string, std::string>> ips) = delete;
|
||||
/// Table ended by an entry with a null ip; must outlive the component.
|
||||
void set_allowed_ips(const AllowedIP *ips) { this->allowed_ips_ = ips; }
|
||||
|
||||
void set_keepalive(const uint16_t seconds) { this->keepalive_ = seconds; }
|
||||
void set_reboot_timeout(const uint32_t seconds) { this->reboot_timeout_ = seconds; }
|
||||
@@ -105,7 +103,7 @@ class Wireguard final : public PollingComponent {
|
||||
const char *peer_public_key_{nullptr};
|
||||
const char *preshared_key_{nullptr};
|
||||
|
||||
FixedVector<AllowedIP> allowed_ips_;
|
||||
const AllowedIP *allowed_ips_{nullptr};
|
||||
|
||||
uint16_t peer_port_;
|
||||
uint16_t keepalive_;
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
esphome:
|
||||
name: test
|
||||
|
||||
esp32:
|
||||
board: esp32dev
|
||||
framework:
|
||||
type: esp-idf
|
||||
|
||||
wifi:
|
||||
ssid: test
|
||||
password: password1
|
||||
|
||||
time:
|
||||
- platform: sntp
|
||||
id: sntp_time
|
||||
|
||||
wireguard:
|
||||
time_id: sntp_time
|
||||
address: 172.16.34.100
|
||||
netmask: 255.255.255.0
|
||||
private_key: wPBMxtNYH3mChicrbpsRpZIasIdPq3yZuthn23FbGG8=
|
||||
peer_public_key: Hs2JfikvYU03/Kv3YoAs1hrUIPPTEkpsZKSPUljE9yc=
|
||||
peer_endpoint: wg.server.example
|
||||
peer_allowed_ips:
|
||||
- 172.16.34.0/24
|
||||
- 192.168.0.0/16
|
||||
@@ -0,0 +1,21 @@
|
||||
"""Tests for the wireguard allowed IPs codegen."""
|
||||
|
||||
from collections.abc import Callable
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def test_allowed_ips_are_a_progmem_table(
|
||||
generate_main: Callable[[str | Path], str],
|
||||
component_config_path: Callable[[str], Path],
|
||||
) -> None:
|
||||
"""Allowed IPs live in a flash table ended by an empty entry instead of a heap vector."""
|
||||
main_cpp = generate_main(component_config_path("allowed_ips.yaml"))
|
||||
|
||||
table = main_cpp.split(
|
||||
"wireguard::AllowedIP wireguard_allowed_ips[] PROGMEM = ", 1
|
||||
)[1]
|
||||
table = table.split(";", 1)[0]
|
||||
assert '.ip = "172.16.34.0"' in table
|
||||
assert '.netmask = "255.255.0.0"' in table
|
||||
assert ".ip = nullptr" in table
|
||||
assert "->set_allowed_ips(wireguard_allowed_ips);" in main_cpp
|
||||
Reference in New Issue
Block a user