feat: repeater VLAN-style region tagging for untagged flood packets

Repeaters with a home region configured now automatically tag untagged
flood packets (ROUTE_TYPE_FLOOD) with the home region's transport code,
converting them to ROUTE_TYPE_TRANSPORT_FLOOD. Also adds TRANSPORT_CODE_ALL
(0xFFFF) as a reserved code that bypasses region filtering, allowing
mesh-wide flooding when explicitly requested.
This commit is contained in:
Dale Ruane 2026-03-17 15:59:52 +00:00
parent a22c4b6270
commit 85a3b1d6db
2 changed files with 36 additions and 4 deletions

View file

@ -416,7 +416,9 @@ bool MyMesh::isLooped(const mesh::Packet* packet, const uint8_t max_counters[])
bool MyMesh::allowPacketForward(const mesh::Packet *packet) {
if (_prefs.disable_fwd) return false;
if (packet->isRouteFlood() && packet->getPathHashCount() >= _prefs.flood_max) return false;
if (packet->isRouteFlood() && recv_pkt_region == NULL) {
if (packet->isRouteFlood() && packet->hasTransportCodes() && packet->transport_codes[0] == TRANSPORT_CODE_ALL) {
// ALL region: always forward regardless of region config
} else if (packet->isRouteFlood() && recv_pkt_region == NULL) {
MESH_DEBUG_PRINTLN("allowPacketForward: unknown transport code, or wildcard not allowed for FLOOD packet");
return false;
}
@ -535,12 +537,40 @@ uint32_t MyMesh::getDirectRetransmitDelay(const mesh::Packet *packet) {
bool MyMesh::filterRecvFloodPacket(mesh::Packet* pkt) {
// just try to determine region for packet (apply later in allowPacketForward())
if (pkt->getRouteType() == ROUTE_TYPE_TRANSPORT_FLOOD) {
recv_pkt_region = region_map.findMatch(pkt, REGION_DENY_FLOOD);
if (pkt->transport_codes[0] == TRANSPORT_CODE_ALL) {
recv_pkt_region = &region_map.getWildcard(); // ALL: always allow
} else {
recv_pkt_region = region_map.findMatch(pkt, REGION_DENY_FLOOD);
}
} else if (pkt->getRouteType() == ROUTE_TYPE_FLOOD) {
if (region_map.getWildcard().flags & REGION_DENY_FLOOD) {
// untagged packet: tag with home region if one is configured
RegionEntry* home = region_map.getHomeRegion();
if (home && home->id != 0) {
// calculate transport code for home region and stamp onto packet
TransportKey key;
if (home->name[0] == '$') {
// private region: load key from store
if (key_store.loadKeysFor(home->id, &key, 1) < 1) {
recv_pkt_region = NULL;
return false;
}
} else if (home->name[0] == '#') {
key_store.getAutoKeyFor(home->id, home->name, key);
} else {
char tmp[sizeof(home->name) + 1];
tmp[0] = '#';
strcpy(&tmp[1], home->name);
key_store.getAutoKeyFor(home->id, tmp, key);
}
pkt->transport_codes[0] = key.calcTransportCode(pkt);
pkt->transport_codes[1] = 0;
pkt->header = (pkt->header & ~PH_ROUTE_MASK) | ROUTE_TYPE_TRANSPORT_FLOOD;
recv_pkt_region = home;
} else if (region_map.getWildcard().flags & REGION_DENY_FLOOD) {
recv_pkt_region = NULL;
} else {
recv_pkt_region = &region_map.getWildcard();
recv_pkt_region = &region_map.getWildcard();
}
} else {
recv_pkt_region = NULL;

View file

@ -16,6 +16,8 @@ namespace mesh {
#define ROUTE_TYPE_DIRECT 0x02 // direct route, 'path' is supplied
#define ROUTE_TYPE_TRANSPORT_DIRECT 0x03 // direct route + transport codes
#define TRANSPORT_CODE_ALL 0xFFFF // special transport code: forward to all regions
#define PAYLOAD_TYPE_REQ 0x00 // request (prefixed with dest/src hashes, MAC) (enc data: timestamp, blob)
#define PAYLOAD_TYPE_RESPONSE 0x01 // response to REQ or ANON_REQ (prefixed with dest/src hashes, MAC) (enc data: timestamp, blob)
#define PAYLOAD_TYPE_TXT_MSG 0x02 // a plain text message (prefixed with dest/src hashes, MAC) (enc data: timestamp, text)