mirror of
https://github.com/mikecarper/MeshCore.git
synced 2026-11-04 15:38:24 +00:00
4161 lines
118 KiB
HTML
4161 lines
118 KiB
HTML
|
||
<!doctype html>
|
||
<html lang="en" class="no-js">
|
||
<head>
|
||
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
|
||
<meta name="description" content="Documentation for the open source MeshCore firmware">
|
||
|
||
|
||
|
||
<link rel="canonical" href="https://mikecarper.github.io/MeshCore/flood_filtering/">
|
||
|
||
|
||
<link rel="prev" href="../WiFi/">
|
||
|
||
|
||
<link rel="next" href="../gps_tracking/">
|
||
|
||
|
||
|
||
|
||
|
||
<link rel="icon" href="../assets/images/favicon.png">
|
||
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.7">
|
||
|
||
|
||
|
||
<title>Flood filtering - MeshCore Docs</title>
|
||
|
||
|
||
|
||
<link rel="stylesheet" href="../assets/stylesheets/main.ec1eaa64.min.css">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
|
||
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
|
||
|
||
|
||
|
||
<link rel="stylesheet" href="../_stylesheets/notification_builder.css?v=20261006-channel9">
|
||
|
||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css">
|
||
|
||
<link rel="stylesheet" href="../_stylesheets/extra.css">
|
||
|
||
<link rel="stylesheet" href="../_stylesheets/firmware_picker.css?v=20261001-feedback-1">
|
||
|
||
<link rel="stylesheet" href="../_stylesheets/telemetry_decoder.css">
|
||
|
||
<link rel="stylesheet" href="../_stylesheets/management_decoder.css">
|
||
|
||
<link rel="stylesheet" href="../_stylesheets/filter_tool.css">
|
||
|
||
<link rel="stylesheet" href="../_stylesheets/preset_test.css?v=20260923-2">
|
||
|
||
<link rel="stylesheet" href="../_stylesheets/esp32_partition_catalog.css?v=20261001-1">
|
||
|
||
<script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
|
||
|
||
|
||
|
||
|
||
|
||
</head>
|
||
|
||
|
||
<body dir="ltr">
|
||
|
||
|
||
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
|
||
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
|
||
<label class="md-overlay" for="__drawer"></label>
|
||
<div data-md-component="skip">
|
||
|
||
|
||
<a href="#flood-filtering-and-moderation" class="md-skip">
|
||
Skip to content
|
||
</a>
|
||
|
||
</div>
|
||
<div data-md-component="announce">
|
||
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<header class="md-header md-header--shadow" data-md-component="header">
|
||
<nav class="md-header__inner md-grid" aria-label="Header">
|
||
<a href=".." title="MeshCore Docs" class="md-header__button md-logo" aria-label="MeshCore Docs" data-md-component="logo">
|
||
|
||
<img src="../_assets/meshcore.svg" alt="logo">
|
||
|
||
</a>
|
||
<label class="md-header__button md-icon" for="__drawer">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
|
||
</label>
|
||
<div class="md-header__title" data-md-component="header-title">
|
||
<div class="md-header__ellipsis">
|
||
<div class="md-header__topic">
|
||
<span class="md-ellipsis">
|
||
MeshCore Docs
|
||
</span>
|
||
</div>
|
||
<div class="md-header__topic" data-md-component="header-topic">
|
||
<span class="md-ellipsis">
|
||
|
||
Flood filtering
|
||
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
|
||
|
||
|
||
|
||
|
||
|
||
<label class="md-header__button md-icon" for="__search">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
|
||
</label>
|
||
<div class="md-search" data-md-component="search" role="dialog">
|
||
<label class="md-search__overlay" for="__search"></label>
|
||
<div class="md-search__inner" role="search">
|
||
<form class="md-search__form" name="search">
|
||
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
|
||
<label class="md-search__icon md-icon" for="__search">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
|
||
</label>
|
||
<nav class="md-search__options" aria-label="Search">
|
||
|
||
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
|
||
</button>
|
||
</nav>
|
||
|
||
<div class="md-search__suggest" data-md-component="search-suggest"></div>
|
||
|
||
</form>
|
||
<div class="md-search__output">
|
||
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
|
||
<div class="md-search-result" data-md-component="search-result">
|
||
<div class="md-search-result__meta">
|
||
Initializing search
|
||
</div>
|
||
<ol class="md-search-result__list" role="presentation"></ol>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
|
||
<div class="md-header__source">
|
||
<a href="https://github.com/mikecarper/MeshCore/" title="Go to repository" class="md-source" data-md-component="source">
|
||
<div class="md-source__icon md-icon">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
|
||
</div>
|
||
<div class="md-source__repository">
|
||
mikecarper/MeshCore
|
||
</div>
|
||
</a>
|
||
</div>
|
||
|
||
</nav>
|
||
|
||
</header>
|
||
|
||
<div class="md-container" data-md-component="container">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<main class="md-main" data-md-component="main">
|
||
<div class="md-main__inner md-grid">
|
||
|
||
|
||
|
||
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
|
||
<div class="md-sidebar__scrollwrap">
|
||
<div class="md-sidebar__inner">
|
||
|
||
|
||
|
||
|
||
<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
|
||
<label class="md-nav__title" for="__drawer">
|
||
<a href=".." title="MeshCore Docs" class="md-nav__button md-logo" aria-label="MeshCore Docs" data-md-component="logo">
|
||
|
||
<img src="../_assets/meshcore.svg" alt="logo">
|
||
|
||
</a>
|
||
MeshCore Docs
|
||
</label>
|
||
|
||
<div class="md-nav__source">
|
||
<a href="https://github.com/mikecarper/MeshCore/" title="Go to repository" class="md-source" data-md-component="source">
|
||
<div class="md-source__icon md-icon">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
|
||
</div>
|
||
<div class="md-source__repository">
|
||
mikecarper/MeshCore
|
||
</div>
|
||
</a>
|
||
</div>
|
||
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href=".." class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Home
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--nested">
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2" >
|
||
|
||
|
||
<label class="md-nav__link" for="__nav_2" id="__nav_2_label" tabindex="0">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Firmware and tools
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="false">
|
||
<label class="md-nav__title" for="__nav_2">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
|
||
Firmware and tools
|
||
|
||
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../firmware_picker/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Firmware picker
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../notifications/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Notifications
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../preset_test/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Preset test
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../filter_tool/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Filter tool
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../telemetry_decoder/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Telemetry decoder
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../management_decoder/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Management decoder
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3" checked>
|
||
|
||
|
||
<label class="md-nav__link" for="__nav_3" id="__nav_3_label" tabindex="0">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Documentation
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="true">
|
||
<label class="md-nav__title" for="__nav_3">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
|
||
Documentation
|
||
|
||
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--nested">
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3_1" >
|
||
|
||
|
||
<label class="md-nav__link" for="__nav_3_1" id="__nav_3_1_label" tabindex="0">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Getting started and features
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_3_1_label" aria-expanded="false">
|
||
<label class="md-nav__title" for="__nav_3_1">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
|
||
Getting started and features
|
||
|
||
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../faq/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Faq
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../full_profiles/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Full profiles
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../role_feature_switches/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Role feature switches
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../full_companion_features/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Full companion features
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../companion_radio_full/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Companion radio full
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../full_companion_usb_switcher/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Full companion usb switcher
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../companion_offline_queue/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Companion offline queue
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../halo_keymind_settings/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Halo keymind settings
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--nested">
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3_2" >
|
||
|
||
|
||
<label class="md-nav__link" for="__nav_3_2" id="__nav_3_2_label" tabindex="0">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Firmware updates and partitions
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_3_2_label" aria-expanded="false">
|
||
<label class="md-nav__title" for="__nav_3_2">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
|
||
Firmware updates and partitions
|
||
|
||
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../upgrading_1.17.1.8_to_1.17.1.9/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Upgrading 1.17.1.8 to 1.17.1.9
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../ota_user_guide/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Ota user guide
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../ota_easy/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Ota easy
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../lora_ota_automation/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Lora ota automation
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../ota_nrf52_bootloader_update/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Ota nrf52 bootloader update
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../ota_nrf52_qspi/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Ota nrf52 qspi
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../ota_meshtower_v2_sdcard/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Ota meshtower v2 sdcard
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../esp32_partition_catalog/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Esp32 partition catalog
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../esp32_wifi_partition_migration/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Esp32 wifi partition migration
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../heltec_v4_wifi_partition_migration/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Heltec v4 wifi partition migration
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../host_cli_service/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Host cli service
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3_3" checked>
|
||
|
||
|
||
<label class="md-nav__link" for="__nav_3_3" id="__nav_3_3_label" tabindex="0">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Radio, networking, and power
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_3_3_label" aria-expanded="true">
|
||
<label class="md-nav__title" for="__nav_3_3">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
|
||
Radio, networking, and power
|
||
|
||
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../radio_profiles/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Radio profiles
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../fleet_management/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Private fleet management
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../room_services/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Room services
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../carrier_wave/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Carrier wave
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../espnow_bridge_setup/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Espnow bridge setup
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../WiFi/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
WiFi
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--active">
|
||
|
||
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
|
||
|
||
|
||
|
||
|
||
|
||
<label class="md-nav__link md-nav__link--active" for="__toc">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Flood filtering
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
<a href="./" class="md-nav__link md-nav__link--active">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Flood filtering
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
|
||
|
||
|
||
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<label class="md-nav__title" for="__toc">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
Table of contents
|
||
</label>
|
||
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#automatic-flood-advert-limits" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Automatic flood-advert limits
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Automatic flood-advert limits">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#continuing-abuse-and-recovery" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Continuing abuse and recovery
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#inspect-the-current-limits" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Inspect the current limits
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#clear-history" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Clear history
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#scope-and-resource-bounds" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Scope and resource bounds
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#before-making-changes" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Before making changes
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#force-floods-into-a-transport-scope" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Force floods into a transport scope
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#require-valid-incoming-scopes-only-on-selected-channels" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Require valid incoming scopes only on selected channels
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Require valid incoming scopes only on selected channels">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#interaction-with-duplicate-detection" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Interaction with duplicate detection
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#runtime-flood-rules" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Runtime flood rules
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Runtime flood rules">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#shorthand-for-copying-rules" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Shorthand for copying rules
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#filter-every-1-byte-flood-path" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Filter every 1-byte flood path
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#scope-actions-and-legacy-rules" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Scope actions and legacy rules
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#remote-administration-lockout-warning" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Remote-administration lockout warning
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#high-traffic-mesh-example" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
High-traffic mesh example
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#moderate-group-text-by-channel-and-username" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Moderate group text by channel and username
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Moderate group text by channel and username">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#per-user-per-channel-rate-limits" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Per-user, per-channel rate limits
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#match-the-start-of-a-path" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Match the start of a path
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#how-the-forwarding-controls-combine" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
How the forwarding controls combine
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#delegate-filter-management" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Delegate filter management
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#security-limitations" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Security limitations
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#filter-bridge-and-radio-crossover-traffic" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Filter bridge and radio crossover traffic
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#restore-the-factory-seeded-rows" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Restore the factory-seeded rows
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#remove-the-custom-rules" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Remove the custom rules
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../gps_tracking/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Gps tracking
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../nrf52_power_management/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Nrf52 power management
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--nested">
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3_4" >
|
||
|
||
|
||
<label class="md-nav__link" for="__nav_3_4" id="__nav_3_4_label" tabindex="0">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
CLI and protocol reference
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_3_4_label" aria-expanded="false">
|
||
<label class="md-nav__title" for="__nav_3_4">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
|
||
CLI and protocol reference
|
||
|
||
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../cli_commands/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Cli commands
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../cli_build_matrix/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Cli build matrix
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../cli_command_availability/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Cli command availability
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../terminal_chat_cli/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Terminal chat cli
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../companion_protocol/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Companion protocol
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../kiss_modem_protocol/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Kiss modem protocol
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../packet_format/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Packet format
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../payloads/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Payloads
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../ota_protocol/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Ota protocol
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../management_reports/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Management reports
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../stats_binary_frames/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Stats binary frames
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../number_allocations/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Number allocations
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../qr_codes/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Qr codes
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../docs/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Docs
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../research/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Research
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--nested">
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5" >
|
||
|
||
|
||
<label class="md-nav__link" for="__nav_5" id="__nav_5_label" tabindex="0">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Releases
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_5_label" aria-expanded="false">
|
||
<label class="md-nav__title" for="__nav_5">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
|
||
Releases
|
||
|
||
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--nested">
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_5_1" >
|
||
|
||
|
||
<label class="md-nav__link" for="__nav_5_1" id="__nav_5_1_label" tabindex="0">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Current release
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_5_1_label" aria-expanded="false">
|
||
<label class="md-nav__title" for="__nav_5_1">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
|
||
Current release
|
||
|
||
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../releases/1.17.1.9/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
1.17.1.9 USA Cascade
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../releases/1.17.1.8/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
1.17.1.8 USA Cascade
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../test-results/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Test Results
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../old-releases/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Old Releases
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
|
||
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
|
||
<div class="md-sidebar__scrollwrap">
|
||
<div class="md-sidebar__inner">
|
||
|
||
|
||
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<label class="md-nav__title" for="__toc">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
Table of contents
|
||
</label>
|
||
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#automatic-flood-advert-limits" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Automatic flood-advert limits
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Automatic flood-advert limits">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#continuing-abuse-and-recovery" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Continuing abuse and recovery
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#inspect-the-current-limits" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Inspect the current limits
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#clear-history" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Clear history
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#scope-and-resource-bounds" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Scope and resource bounds
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#before-making-changes" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Before making changes
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#force-floods-into-a-transport-scope" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Force floods into a transport scope
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#require-valid-incoming-scopes-only-on-selected-channels" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Require valid incoming scopes only on selected channels
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Require valid incoming scopes only on selected channels">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#interaction-with-duplicate-detection" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Interaction with duplicate detection
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#runtime-flood-rules" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Runtime flood rules
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Runtime flood rules">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#shorthand-for-copying-rules" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Shorthand for copying rules
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#filter-every-1-byte-flood-path" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Filter every 1-byte flood path
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#scope-actions-and-legacy-rules" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Scope actions and legacy rules
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#remote-administration-lockout-warning" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Remote-administration lockout warning
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#high-traffic-mesh-example" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
High-traffic mesh example
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#moderate-group-text-by-channel-and-username" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Moderate group text by channel and username
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Moderate group text by channel and username">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#per-user-per-channel-rate-limits" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Per-user, per-channel rate limits
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#match-the-start-of-a-path" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Match the start of a path
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#how-the-forwarding-controls-combine" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
How the forwarding controls combine
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#delegate-filter-management" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Delegate filter management
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#security-limitations" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Security limitations
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#filter-bridge-and-radio-crossover-traffic" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Filter bridge and radio crossover traffic
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#restore-the-factory-seeded-rows" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Restore the factory-seeded rows
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#remove-the-custom-rules" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Remove the custom rules
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
|
||
</nav>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
|
||
<div class="md-content" data-md-component="content">
|
||
|
||
<article class="md-content__inner md-typeset">
|
||
|
||
|
||
|
||
|
||
|
||
<a href="https://github.com/mikecarper/MeshCore/edit/keymindCascade/docs/flood_filtering.md" title="Edit this page" class="md-content__button md-icon" rel="edit">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 20H6V4h7v5h5v3.1l2-2V8l-6-6H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h4zm10.2-7c.1 0 .3.1.4.2l1.3 1.3c.2.2.2.6 0 .8l-1 1-2.1-2.1 1-1c.1-.1.2-.2.4-.2m0 3.9L14.1 23H12v-2.1l6.1-6.1z"/></svg>
|
||
</a>
|
||
|
||
|
||
|
||
|
||
<!-- meshcore-hosted-doc-link:start -->
|
||
<p class="meshcore-hosted-doc-link"><a href="https://mikecarper.github.io/MeshCore/flood_filtering/">View this page on MeshCore Docs</a>.</p>
|
||
<!-- meshcore-hosted-doc-link:end -->
|
||
|
||
<h1 id="flood-filtering-and-moderation">Flood Filtering and Moderation</h1>
|
||
<p>This guide explains the Keymind forwarding filters. Repeaters expose the full
|
||
set of channel, rule, blacklist, and moderation controls described here.
|
||
FULL-profile ESP32 room servers expose the generalized <code>flood.rule</code> table (and
|
||
its <code>flood.filter</code> alias) with 31 forward-rule slots, but not the repeater's
|
||
scope-rewrite, passive-blacklist, or text-moderation phases. Standard room-server profiles do
|
||
not compile the rule table. Filters decide whether the node retransmits a
|
||
packet and can assign a transport scope before that decision. They do not stop
|
||
local reception, packet logging, or MQTT observation.</p>
|
||
<p>Only flood routes are filtered:</p>
|
||
<ul>
|
||
<li><code>0x00</code> / <code>ROUTE_TYPE_TRANSPORT_FLOOD</code> - flood routing with transport codes</li>
|
||
<li><code>0x01</code> / <code>ROUTE_TYPE_FLOOD</code> - unscoped flood routing</li>
|
||
</ul>
|
||
<p>Direct routes <code>0x02</code> and <code>0x03</code> are never affected by these rules.
|
||
The route and payload values follow the upstream
|
||
<a href="https://docs.meshcore.io/packet_format/">packet-format reference</a> and
|
||
<a href="https://docs.meshcore.io/payloads/">payload layouts</a>, with this fork's LoRa
|
||
OTA assignment noted below.</p>
|
||
<h2 id="automatic-flood-advert-limits">Automatic flood-advert limits</h2>
|
||
<p>Repeaters, room servers (including non-FULL builds), and forwarding sensors
|
||
automatically limit relayed <code>ADVERT</code> packets. No CLI rule is needed. Companions
|
||
and the repeater's receive-only MQTT observer do not allocate this history.
|
||
This is separate from discovery-response limits, self-advert timers, hop caps,
|
||
and the per-rule <code>rate=N/min</code> setting below.</p>
|
||
<p>The ordinary quota is shared by the <strong>first 12 public-key hex characters</strong>
|
||
(six bytes of the advertised origin key, not a path hash). Each prefix has a
|
||
fixed 180-minute window starting with its first tracked valid flood advert.</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Shortest received hops in that window</th>
|
||
<th>Distinct adverts forwarded per 180 minutes</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>0–1</td>
|
||
<td>10</td>
|
||
</tr>
|
||
<tr>
|
||
<td>2</td>
|
||
<td>9</td>
|
||
</tr>
|
||
<tr>
|
||
<td>3</td>
|
||
<td>8</td>
|
||
</tr>
|
||
<tr>
|
||
<td>4</td>
|
||
<td>6</td>
|
||
</tr>
|
||
<tr>
|
||
<td>5</td>
|
||
<td>5</td>
|
||
</tr>
|
||
<tr>
|
||
<td>6</td>
|
||
<td>4</td>
|
||
</tr>
|
||
<tr>
|
||
<td>7</td>
|
||
<td>3</td>
|
||
</tr>
|
||
<tr>
|
||
<td>8+</td>
|
||
<td>2</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>The minimum received hop <strong>count</strong>, before adding this relay, sets the quota;
|
||
one-, two-, and three-byte path hashes have the same policy. A shorter valid
|
||
duplicate may increase the quota without restarting the window or clearing
|
||
its count. Longer routes never decrease the allowance during that window.
|
||
The payload signature must verify before any history changes. Path metadata
|
||
itself is not signed, so this is a received-distance heuristic, not proof of
|
||
physical distance.</p>
|
||
<h3 id="continuing-abuse-and-recovery">Continuing abuse and recovery</h3>
|
||
<ul>
|
||
<li>A full public key that exceeds the normal level in one window receives a
|
||
first strike. If it exceeds that level again in the immediately following
|
||
window, it enters the bad list. A quiet intervening window breaks this chain.</li>
|
||
<li>Escalation is deliberately conservative: once a key enters the bad list,
|
||
a later shorter route does <strong>not</strong> undo that decision, even if the increased
|
||
quota makes the current window fall below the normal level. This applies to
|
||
shorter duplicate and new adverts, including a matching-prefix key's route.
|
||
The existing restriction remains until seven-day recovery, manual clear, or
|
||
reboot; a shorter route alone never erases a recorded violation.</li>
|
||
<li>The bad list matches <strong>all 32 public-key bytes</strong>, not the prefix. Different
|
||
full keys sharing a prefix share the ordinary forwarding quota, but their
|
||
received counts are not combined to accuse an innocent key of ongoing abuse.</li>
|
||
<li>A bad-listed key may have at most one distinct advert forwarded every
|
||
<strong>12 hours</strong>, measured from its last admitted forward (including before
|
||
escalation). Ordinary forwarding filters still apply.</li>
|
||
<li>Removal requires <strong>seven uninterrupted days without exceeding the normal
|
||
hop-based level</strong>. Recovery is measured against received distinct adverts,
|
||
not the much smaller number allowed to be forwarded. Silence also qualifies.</li>
|
||
<li>Each over-limit window restarts recovery from that window's end. Continued
|
||
abuse can therefore extend the restriction indefinitely; it does not expire
|
||
automatically seven days after the first offence.</li>
|
||
</ul>
|
||
<h3 id="inspect-the-current-limits">Inspect the current limits</h3>
|
||
<p>Use <code>get flood.advert</code> to list rate-limited origins, three per page. Continue
|
||
with <code>get flood.advert 2</code>, etc. Rows show a 12-hex public-key prefix, the reason
|
||
(<code>quota</code>, <code>history</code>, or <code>bad</code>), and the wait before another new advert is
|
||
eligible under the automatic limiter. <code>get flood.advert key 1</code> shows the full
|
||
key and counters for row 1, including the remaining bad-list recovery time.
|
||
A bad-listed key remains visible with <code>wait=0s</code> when its next single forward
|
||
is due. Prefix collisions appear as separate full-key entries.</p>
|
||
<p>This is a live, read-only view: expiry can change row indices between queries,
|
||
but reading never resets quotas or extends recovery. Sources rejected solely
|
||
because the protected-history table is full are not retained, so they cannot
|
||
be listed. See the <a href="../cli_commands/#list-rate-limited-flood-adverts">CLI reference</a>.</p>
|
||
<h3 id="clear-history">Clear history</h3>
|
||
<p>All timers use rollover-safe uptime, so setting the clock forward or backward
|
||
cannot clear the restriction. This history is currently RAM-only: rebooting
|
||
the relay clears it, and time while powered off is not tracked. A manual clear
|
||
also resets both the ordinary quota and abuse history for its selected target:</p>
|
||
<pre><code class="language-text">clear flood.advert all
|
||
clear flood.advert <64-hex-full-public-key>
|
||
</code></pre>
|
||
<p>These use the ordinary local/admin CLI authorization, including authenticated
|
||
admin LoRa CLI. A prefix is never accepted for a targeted clear; missing or
|
||
invalid selectors do not clear anything. Clearing an exact key preserves other
|
||
full keys even when their 12-hex prefixes match. No preferences, contacts,
|
||
neighbours, replay timestamps, or manually configured flood rules are erased.</p>
|
||
<h3 id="scope-and-resource-bounds">Scope and resource bounds</h3>
|
||
<p>Only forwarding is suppressed. Valid adverts remain available to local
|
||
contact/neighbour handling and can still appear in raw RX logs or MQTT. This
|
||
cannot prevent the origin or upstream repeaters from transmitting. Direct
|
||
adverts, discovery control responses, messages, OTA packets, and this node's
|
||
own scheduled adverts are not charged. Existing physical retry attempts of
|
||
an admitted advert are not additional <strong>distinct</strong> adverts.</p>
|
||
<p>The limiter retains up to eleven 64-bit payload hashes per full key per
|
||
window: ten possible ordinary admissions plus evidence of exceeding the
|
||
largest quota. Paths and transport scopes do not change these hashes.
|
||
Retained duplicate hashes cannot consume additional quota even if the general
|
||
packet-seen cache has evicted them. Once the eleven distinct receive slots are
|
||
full, additional unretained payloads are suppressed until the next window.
|
||
Only packets passing all ordinary forwarding gates consume forwarding quota;
|
||
valid received traffic still supplies abuse evidence when another gate blocks it.</p>
|
||
<p>The default is 128 full-key slots (18,432 bytes of entry storage plus small
|
||
bookkeeping), 96 on nRF52 (13,824 bytes, preserving the mOTA runtime RAM
|
||
reserve), or eight on RAM-constrained STM32 builds (1,152 bytes).
|
||
<code>FLOOD_ADVERT_SOURCE_SLOTS</code> overrides the capacity at compile time. When full,
|
||
the <strong>least-recently-heard normal key is removed first</strong>. Valid retained
|
||
duplicates update last-heard too. Evicting a normal key discards its ordinary
|
||
quota history, so capacity should still be sized for the deployment's active
|
||
origins. First-strike evidence and bad-list entries are protected from eviction:
|
||
if every slot protects abuse history, untracked origins are not forwarded until
|
||
a slot expires or an administrator clears history. Table churn cannot erase an
|
||
existing bad-list penalty. No heap allocation or per-packet filesystem writes
|
||
are used.</p>
|
||
<h2 id="before-making-changes">Before making changes</h2>
|
||
<p>On a repeater, show the current forwarding controls:</p>
|
||
<pre><code class="language-text">get repeat
|
||
get flood.max
|
||
get flood.max.unscoped
|
||
get flood.max.advert
|
||
get flood.channel.data
|
||
get flood.channel.data.hops
|
||
get flood.channel.scope
|
||
get flood.channel.scope.require
|
||
get flood.filter
|
||
get flood.rule
|
||
get flood.filter.blacklist
|
||
get flood.moderation
|
||
</code></pre>
|
||
<p><code>flood.rule</code> is an alias for <code>flood.filter</code>, not another table. Generalized
|
||
repeater FPF7 has 63 forward-rule slots plus scope-rewrite and shared-blacklist
|
||
sections in the same atomic policy file. FULL room servers have 31 forward
|
||
slots and empty repeater-only sections. Compact target profiles retain their
|
||
separate FPF6-era controls. <code>flood.moderation</code> has 16 slots. A new
|
||
repeater FPF7 table starts with <code>ota all suspend=tempradio</code> in slot 1 and an
|
||
authenticated <code>#wardriving hops=5+</code> radio drop in slot 2, and an authenticated
|
||
<code>#wardriving hops=all mode=bridge,cross</code> drop in slot 3. FULL room servers seed
|
||
only the OTA row; their generalized engine also accepts transport-mode rules. <code>flood.moderation</code> starts empty. A row can opt into
|
||
<code>suspend=tempradio</code>;
|
||
temporary radio is not synonymous with OTA and can carry normal packet types
|
||
too. A corrupt or truncated table fails open, so corrupt storage does not
|
||
silently enable blocking.</p>
|
||
<p>On a FULL ESP32 room server, use <code>get flood.rule</code> (or <code>get flood.filter</code>) for
|
||
the available table. Remote rule changes require room-server administrator
|
||
access. <code>flood.filter.blacklist*</code> and <code>path=blacklist</code> are repeater-only; use
|
||
the ordered <code>prefix=</code> condition on a room server.</p>
|
||
<h2 id="force-floods-into-a-transport-scope">Force floods into a transport scope</h2>
|
||
<p><code>flood.channel.scope</code> can add a scope to a received unscoped flood or replace
|
||
the scope of a transport-scoped flood before this repeater forwards it:</p>
|
||
<pre><code class="language-text">set flood.channel.scope <channel|txt:*|login:*|other:*> <region|scope=name> [path=blacklist|path=bucket:1-6] [tx=slow]
|
||
set flood.channel.scope.<slot> <channel|txt:*|login:*|other:*> <region|scope=name> [path=blacklist|path=bucket:1-6] [tx=slow]
|
||
get flood.channel.scope
|
||
get flood.channel.scope.<slot>
|
||
del flood.channel.scope.<slot>
|
||
del flood.channel.scope all
|
||
</code></pre>
|
||
<p>The channel may be <code>public</code>, <code>#channel</code>, or a 128/256-bit hex key. A bare
|
||
target names an existing region with a usable transport key. Use
|
||
<code>scope=<name></code> instead to derive a regionless public hashtag scope exactly as
|
||
<code>flood.filter scope=<name></code> does. The direct name is normalized with a leading
|
||
<code>#</code>, may contain up to 30 characters, and does not need a region-list entry.
|
||
Keyed rules first check the one-byte channel hash carried in the packet, then
|
||
validate the MAC by decrypting with the configured channel key. A hash
|
||
collision alone cannot force a scope.</p>
|
||
<p>For example, this authenticates only <code>#rgdata</code> and rewrites it to
|
||
<code>#BlackHole86</code> without creating a region:</p>
|
||
<pre><code class="language-text">set flood.channel.scope #rgdata scope=BlackHole86
|
||
get flood.channel.scope.1
|
||
</code></pre>
|
||
<p>If that channel arrives scoped to <code>#usa</code>, the rule replaces <code>#usa</code> with
|
||
<code>#BlackHole86</code>. It also handles unscoped packets and replaces any other
|
||
incoming scope; the source scope is not a condition on the rule.</p>
|
||
<p>Add <code>path=blacklist</code> to make a channel-scope row eligible only when the
|
||
received path matches the passive <code>flood.filter.blacklist</code> ID table. It does
|
||
not require an enabled <code>flood.filter</code> drop row. With 3-byte paths, one exact
|
||
listed ID qualifies. With 2-byte paths, two received path entries must match
|
||
the first two bytes of listed IDs. A 1-byte path never qualifies.</p>
|
||
<p>Use <code>path=bucket:<1-6></code> to match one of the existing
|
||
<code>flood.retry.bucket</code> tables instead. Each bridge bucket holds up to 17
|
||
three-byte IDs and remains usable by channel scoping while
|
||
<code>flood.retry.bridge</code> is off. Bucket matching uses the same thresholds as the
|
||
blacklist: one exact hit for 3-byte paths, two qualifying entries for 2-byte
|
||
paths, and no matches for 1-byte paths. Channel scoping reads the configured
|
||
IDs directly; <code>recent.repeater</code> freshness and <code>flood.retry.ignore</code> do not
|
||
change this match.</p>
|
||
<p>There are three independent wildcard classes:</p>
|
||
<ul>
|
||
<li><code>txt:*</code> handles otherwise-unmatched <code>GRP_TXT</code> and <code>GRP_DATA</code>; plain <code>*</code> is
|
||
its alias.</li>
|
||
<li><code>login:*</code> handles <code>REQ</code>, <code>RESPONSE</code>, <code>TXT_MSG</code>, <code>ANON_REQ</code>, and <code>PATH</code>.</li>
|
||
<li><code>other:*</code> handles every remaining flood payload type, including flood-form
|
||
TRACE and OTA.</li>
|
||
</ul>
|
||
<p><code>login:*</code> and <code>other:*</code> classify only the visible outer payload type; they do
|
||
not authenticate its contents. Exact channel rows with usable targets
|
||
always take precedence over <code>txt:*</code>, even if that wildcard has a lower slot
|
||
number. Within the exact class, matching path-qualified rows are tried before
|
||
ordinary fallback rows. The same qualified-then-fallback order applies within
|
||
each wildcard class. A missing or unusable target is skipped, so later rows
|
||
remain eligible. The lowest usable slot wins within each priority tier.</p>
|
||
<p>For example, this uses bridge bucket 1 to assign <code>east</code> to <code>public</code> packets
|
||
whose received 3-byte path contains <code>7576FB</code>, and assigns <code>west</code> to all other
|
||
authenticated <code>public</code> packets:</p>
|
||
<pre><code class="language-text">set flood.retry.bucket 1 7576FB
|
||
set flood.channel.scope public west
|
||
set flood.channel.scope public east path=bucket:1
|
||
</code></pre>
|
||
<p>More 3-byte IDs can be added to bucket 1 later. Any one of them qualifies the
|
||
<code>east</code> row. Replacing or clearing that bucket changes which paths qualify but
|
||
leaves both channel-scope rows intact. Bridge retry does not need to be
|
||
enabled.</p>
|
||
<p>On a successful match, an unscoped route changes from <code>ROUTE_TYPE_FLOOD</code> to
|
||
<code>ROUTE_TYPE_TRANSPORT_FLOOD</code>; an already-scoped route remains transport-flood
|
||
but receives replacement codes. Transport code 0 is calculated with the target
|
||
region or direct hashtag key over the payload type and payload, and code 1 becomes zero. The
|
||
change happens before region enforcement, forwarding filters, and
|
||
deduplication. Consequently <code>flood.max.unscoped</code> no longer applies to a packet
|
||
converted from unscoped, while <code>flood.max</code>, <code>flood.filter</code>, loop detection, and
|
||
moderation still apply to every rewritten packet. A region
|
||
target must be flood-allowed. A regionless target is trusted for this matched
|
||
receive pass, but it neither creates a region nor changes how unrelated packets
|
||
with the same transport code pass the region gate. By default, if the selected scope differs and the
|
||
rewritten packet passes those checks, its initial retransmission uses zero
|
||
<code>txdelay</code> and the highest outbound queue priority so the newly scoped copy can
|
||
win at the next hop. Add <code>tx=slow</code> to use an effective inbound <code>rxdelay</code> base
|
||
of <code>max(2, configured rxdelay * 2)</code>, retain normal outbound queue priority, and
|
||
force the maximum <code>txdelay</code> factor of <code>2.0</code>. The actual transmit delay is still
|
||
randomized, from zero through ten packet airtimes.
|
||
It does not preempt an active radio transmission or bypass CAD and
|
||
airtime-budget limits. Selecting the scope already present is a no-op and does
|
||
not grant special treatment.</p>
|
||
<p>Direct routes are never rewritten. Standard traceroute is direct-routed and
|
||
therefore remains outside this flood-only table. A custom flood-form TRACE is
|
||
treated like every other flood: an applicable wildcard may rewrite it and the
|
||
normal region/unknown-code gates still apply. Scope assignment does not
|
||
override normal payload validation or make an otherwise non-forwardable
|
||
packet type forwardable.</p>
|
||
<p>LoRa OTA (<code>0x0C</code>) falls under <code>other:*</code>. A matching row adds the selected
|
||
transport code or replaces the existing one, but OTA still operates normally
|
||
during the temporary-radio window because the OTA handler accepts both
|
||
unscoped and transport-scoped flood routes. A region target must allow
|
||
flooding; a direct target uses the regionless trust behavior above. A new
|
||
repeater also seeds <code>ota all suspend=tempradio</code> in flood-filter
|
||
slot 1. That visible rule blocks OTA forwarding at every received hop outside
|
||
temporary-radio operation and is skipped while temporary radio is active.
|
||
Independently, the OTA core refuses OTA receive, relay, and transmit outside an
|
||
actually active temporary-radio window, even if the seeded row is deleted or
|
||
replaced.</p>
|
||
<p>Capacity is selected at build time:</p>
|
||
<ul>
|
||
<li>Roomy ESP32 builds: 255 rewrite slots and 32 regionless-target slots, 10,204
|
||
bytes RAM.</li>
|
||
<li>Classic ESP32 repeaters, nRF52, and other normal
|
||
constrained builds: 31 rewrite and regionless-target slots, 2,108 bytes RAM.</li>
|
||
<li>Very-tight STM32WL builds: 15 rewrite slots and one reusable regionless-target
|
||
slot, 572 bytes RAM.</li>
|
||
<li>The no-PSRAM LilyGo T-LoRa V2.1 repeater/observer: 4 rewrite and
|
||
regionless-target slots, 272 bytes RAM. This minimum holds the
|
||
three wildcard classes and one exact channel mapping.</li>
|
||
</ul>
|
||
<p>Classic ESP32 uses the 31-slot default even on boards with PSRAM because these
|
||
tables live in internal static DRAM. The separate channel-requirement table
|
||
defaults to the same capacity and uses another 34 bytes per slot. Together,
|
||
the 31-slot defaults save 15,712 bytes of static RAM compared with 255 slots.
|
||
Custom builds can override <code>FLOOD_CHANNEL_SCOPE_SLOTS</code> and
|
||
<code>FLOOD_CHANNEL_SCOPE_REQUIRE_SLOTS</code> with build flags.</p>
|
||
<p>Each rule retains its 36-byte record. A separate table holds 32-byte normalized
|
||
names for up to the smaller of the rule count or 32 distinct regionless
|
||
targets, except that very-tight STM32WL builds retain one reusable direct
|
||
target. Both configured regions and regionless targets can be reused by any
|
||
number of rules.</p>
|
||
<p>On generalized builds these records are the FPF7 rewrite phase, and the file
|
||
stores only through the highest occupied slot. Compact FPF6 builds retain the
|
||
standalone FCS5 file and the file sizes described by their build profile.</p>
|
||
<h2 id="require-valid-incoming-scopes-only-on-selected-channels">Require valid incoming scopes only on selected channels</h2>
|
||
<p><code>flood.channel.scope.require</code> changes region enforcement for received flood
|
||
<code>GRP_TXT</code> and <code>GRP_DATA</code> packets from a global policy to a channel opt-in
|
||
policy:</p>
|
||
<pre><code class="language-text">set flood.channel.scope.require <public|#channel|128/256-bit-key>
|
||
set flood.channel.scope.require.<slot> <public|#channel|128/256-bit-key>
|
||
get flood.channel.scope.require
|
||
get flood.channel.scope.require.<slot>
|
||
del flood.channel.scope.require.<slot>
|
||
del flood.channel.scope.require all
|
||
</code></pre>
|
||
<p>An empty table preserves the normal global region behavior. Once at least one
|
||
row exists, a group-channel packet that authenticates against a listed key must
|
||
arrive as <code>ROUTE_TYPE_TRANSPORT_FLOOD</code> with a transport code matching a locally
|
||
flood-allowed region. An unscoped packet, an unknown transport code, or a code
|
||
for a denied region is not retransmitted. The check uses the original incoming
|
||
scope before <code>flood.channel.scope</code> or <code>flood.filter scope=</code> can rewrite it.
|
||
Those rewrite actions are skipped for a rejected listed channel, so they
|
||
cannot rescue it or grant special receive/transmit timing.</p>
|
||
<p>Group-channel packets that do not authenticate against any listed key bypass
|
||
the region/unknown-code forwarding gate. They still pass through <code>repeat</code>,
|
||
<code>flood.max*</code>, <code>flood.filter</code>, loop detection, payload
|
||
validation, and moderation. Non-channel flood payload types retain the normal
|
||
global region behavior. A one-byte channel-hash collision is only a prefilter;
|
||
the packet must also pass MAC validation/decryption with the configured key.</p>
|
||
<p>Without <code>.slot</code>, setting an existing key updates its row and a new key uses the
|
||
first empty row. Numbered <code>set</code> replaces that slot. Detail output displays only
|
||
the first four derived hash bytes and key size, never the secret. The table has
|
||
the same build-dependent slot count as <code>flood.channel.scope</code>; each row consumes
|
||
34 bytes of RAM and storage, plus a five-byte file header. ACL permission <code>4</code>
|
||
can manage it.</p>
|
||
<p>For example, this requires an allowed incoming scope on <code>#bot</code>, while every
|
||
other group channel bypasses region enforcement:</p>
|
||
<pre><code class="language-text">set flood.channel.scope.require #bot
|
||
get flood.channel.scope.require
|
||
</code></pre>
|
||
<h3 id="interaction-with-duplicate-detection">Interaction with duplicate detection</h3>
|
||
<p>The seen-packet hash contains the payload type and exact payload bytes. It does
|
||
not contain the route type, either transport code, or the ordinary flood path.
|
||
For <code>TRACE</code> only, the encoded <code>path_len</code> byte is also included. Therefore an
|
||
unscoped packet and the same packet after this repeater adds a transport code
|
||
are the same duplicate. A later copy with a different scope is also the same
|
||
duplicate; changing or adding scope cannot evade the seen table.</p>
|
||
<p>When equivalent non-TRACE flood copies overlap in <code>rxdelay</code>, the normal
|
||
receive-quality timing still chooses the packet to process, but that winner
|
||
takes a scope from the queued copies whose transport code matches an allowed
|
||
region in this repeater.
|
||
Unknown and denied scopes are ignored. If eligible copies have different
|
||
scopes, the shortest received path supplies the scope. Equal path lengths
|
||
prefer the deepest matching child region (the narrowest configured scope). A
|
||
remaining tie keeps queue order. The winner keeps its own path, SNR, and delay
|
||
schedule; only its route and transport codes can change, including replacement
|
||
of a less-preferred scope it already carried.</p>
|
||
<p>Scope selection happens at dequeue so the original scopes remain available for
|
||
comparison. It applies only while copies are queued and cannot alter a copy
|
||
already processed into the seen table. Flood-form TRACE participates in the
|
||
same arbitration. Direct traceroute never enters this flood queue.</p>
|
||
<p>A packet that already matches a configured fast <code>flood.channel.scope</code> or
|
||
<code>flood.filter scope=</code> action and needs its scope changed bypasses this inbound
|
||
<code>rxdelay</code> queue entirely. A <code>tx=slow</code> row remains in the queue with twice the
|
||
configured base, floored at <code>2.0</code>, and participates in normal queued-copy
|
||
scope arbitration.</p>
|
||
<h2 id="runtime-flood-rules">Runtime flood rules</h2>
|
||
<p>On repeaters with the rule engine enabled and on FULL-profile ESP32 room
|
||
servers, <code>fr</code>, <code>flood.rule</code>, and <code>flood.filter</code> name the same persistent
|
||
table. The evaluator is fixed firmware, but every row is data, so an
|
||
authenticated operator can add, replace, inspect, or delete a row without an
|
||
OTA or reboot. Existing <code>flood.filter</code> commands remain compatible. Only FPF6
|
||
and FPF7 files are accepted; FPF1-FPF5 files are rejected and filtering fails
|
||
open. A row saved by the extended engine uses FPF7.
|
||
Older firmware cannot preserve an FPF7 table containing the packed <code>retry</code>
|
||
action, one-byte <code>hash:XX</code> matcher, or <code>mode=bridge</code>/<code>cross</code> flags; remove those
|
||
rows before downgrading. Old firmware rejects such a table and fails open,
|
||
which disables its other filter rows too. New firmware loads older rows as
|
||
<code>mode=radio</code> without changing their behavior.</p>
|
||
<p>The former <code>flood.channel.block</code> table is now represented by ordinary FPF7
|
||
rows. On a generalized repeater, an existing FCB2 file is imported once into
|
||
free FPF7 slots and then removed. For example, an old <code>#wardriving h=4</code> row
|
||
becomes <code>type=any channel=#wardriving hops=5+ drop</code>. The 63-row table can hold
|
||
all 31 former general filter rows, all 15 legacy channel-block rows, and the
|
||
migrated global <code>flood.channel.data</code> gate. Compact STM32WL FPF6 builds cannot
|
||
match authenticated channels and retain the older separate gate.</p>
|
||
<p>On generalized repeaters, <code>flood.channel.data*</code> is a compatibility view over
|
||
one ordinary visible FPF7 <code>type=grp_data ... drop</code> row. Turning it off creates
|
||
or updates that row; turning it on removes the row. Its hop setting maps to
|
||
<code>hops=all</code> or <code>hops=N+1+</code>. There is no hidden GRP_DATA forwarding check ahead
|
||
of FPF7. Normal ordering applies, so a matching higher-priority <code>stop</code> row can
|
||
exempt selected traffic. The compact rule list marks the managed row with
|
||
<code>~data</code>.</p>
|
||
<p>FPF7 binds <code>in=region:<name></code> and <code>region=<name></code> to canonical region names,
|
||
not numeric region IDs. Removing, reordering, or reusing a region ID cannot
|
||
silently redirect a rule. If the saved name is missing, an input-region match
|
||
does not match and a target-region rewrite is skipped. Re-adding the same name
|
||
reactivates the rule.</p>
|
||
<p>The extended form is:</p>
|
||
<pre><code class="language-text">set flood.rule[.<slot>] type=<type> [mode=radio|bridge|cross|bridge,cross]
|
||
[hops=<range>] [channel=<channel>] [hashbytes=any|1|2|2+|3]
|
||
[prefix=<ID[,ID...]>] [in=<input-scope>] <action> [rate=<N>/min]
|
||
[priority=<0-255>] [stop] [tx=fast|slow] [suspend=tempradio]
|
||
get flood.rule
|
||
get flood.rule.<slot>
|
||
del flood.rule.<slot>
|
||
del flood.rule all
|
||
</code></pre>
|
||
<p>The command must be entered on one line. Match fields in one row are ANDed.
|
||
Radio rows are matched against the same immutable packet state captured on
|
||
receive, before any rule rewrites its scope. Bridge/cross rows match at their
|
||
transport boundary. Only rows for the current mode participate in ordering
|
||
and stop processing. Matching rows are then processed
|
||
by descending numeric <code>priority</code>. At an equal numeric priority, authenticated
|
||
channel matches run before raw <code>hash:XX</code> matches, raw hashes run before
|
||
<code>channel=*</code>, and lower slot number breaks the remaining tie. Priority defaults
|
||
to <code>0</code>; an explicitly higher numeric priority overrides specificity.</p>
|
||
<p>Numbered examples replace the selected slots, including factory defaults.
|
||
Omit the slot number to add a rule without replacing an occupied slot.</p>
|
||
<p>The first matching <code>stop</code> row ends the FPF7 forward phase after that row. Higher-order
|
||
matches and the stop row still apply; lower-order matches do not. A stop-only
|
||
row is therefore an exception to lower-priority FPF7 rows. It cannot undo a
|
||
higher-priority drop and it does not bypass hard forwarding gates or the
|
||
scope-rewrite and moderation phases. Without a stop row, matching drop and rate rows remain
|
||
independent and the highest-order matching scope or region rewrite wins.</p>
|
||
<p>Match fields:</p>
|
||
<ul>
|
||
<li><code>type=</code> accepts the same packet names and numeric values as legacy
|
||
<code>flood.filter</code>. The positional form remains accepted.</li>
|
||
<li><code>hops=</code> accepts <code>all</code>, <code>N</code>, <code>N+</code>, or <code>N-M</code>. The positional form remains
|
||
accepted. Received hops over 3 are written as <code>hops=4+</code>.</li>
|
||
<li><code>mode=radio|bridge|cross|bridge,cross</code> selects the admission phase; omitted
|
||
means <code>radio</code>. See <a href="#filter-bridge-and-radio-crossover-traffic">bridge and crossover filtering</a>.</li>
|
||
<li><code>channel=*|public|#name|hash:XX|128-bit-key|256-bit-key</code> optionally narrows by
|
||
channel. <code>channel=*</code> is an unconstrained wildcard: it performs no channel
|
||
authentication and matches every payload selected by <code>type=</code>. Thus
|
||
<code>type=any channel=*</code> means every flood payload type. <code>public</code>, <code>#name</code>, and
|
||
raw keys authenticate one channel and narrow the row to <code>GRP_TXT</code> or
|
||
<code>GRP_DATA</code>. <code>hash:XX</code> compares only the visible one-byte group-channel hash.
|
||
<code>short:XX</code> and a bare two-digit byte are aliases; saved output uses
|
||
<code>hash:XX</code>. This matcher is unauthenticated, has a 1-in-256 collision space,
|
||
and can be selected by a sender, so prefer an exact name or key when known.
|
||
<code>hash:11</code> is not an alias for Public: it includes Public and every <code>0x11</code>
|
||
collision, while <code>public</code> verifies and decrypts with the Public key. This is
|
||
channel authentication, not sender authentication: the group MAC is two
|
||
bytes and the Public key is shared.</li>
|
||
<li><code>hashbytes=any|1|2|2+|3</code> matches the encoded width of each path hash, independent
|
||
of its value or the hop count. Omitted or <code>any</code> means any width; <code>*</code> is an
|
||
alias for <code>any</code>. It includes zero-hop packets carrying the selected width.
|
||
<code>2+</code> matches the supported 2- and 3-byte widths in one rule; a rate limit is
|
||
shared across both widths. Four-byte path hashes are reserved and unsupported.
|
||
Combine this with other match fields as needed; a <code>prefix=</code> must satisfy the
|
||
width selector. With <code>2+</code>, a 2- or 3-byte prefix narrows the rule to that exact
|
||
width, and saved output shows the prefix. The compact alias is <code>pb=</code>.</li>
|
||
<li><code>prefix=</code> is a source-path prefix containing one to three comma-separated
|
||
pbyte IDs. Every ID must use the packet's pbyte width: 2, 4, or 6 hex
|
||
characters for 1-, 2-, or 3-byte paths. Order matters and matching begins at
|
||
the first received path entry. <code>path=<prefix></code> is an alias;
|
||
<code>path=blacklist</code> retains its separate unordered-list behavior.</li>
|
||
<li><code>in=any|none|scoped|allowed|unknown|scope:<name>|region:<name></code> tests the
|
||
original incoming route before any rewrite. <code>none</code> means an unscoped flood;
|
||
<code>scoped</code> means any transport flood; <code>scope:name</code> compares the exact public
|
||
hashtag-derived scope; and <code>region:name</code> compares an allowed configured
|
||
region. <code>allowed</code> is the legacy <code>require=region</code> test and includes an
|
||
unscoped packet when the wildcard region allows it. <code>unknown</code> means a scoped
|
||
packet that does not resolve to an allowed local region.</li>
|
||
</ul>
|
||
<p>Actions:</p>
|
||
<ul>
|
||
<li><code>drop</code> prevents retransmission when the row matches. The strict
|
||
<code>flood.rule</code> form requires an explicit action. For backward compatibility,
|
||
only a legacy <code>flood.filter</code> row with no rewrite, rate, or stop action means
|
||
drop implicitly.</li>
|
||
<li><code>scope=<name></code> derives a public transport scope directly from the name; no
|
||
region entry is consulted. <code>scope=BlackHole86</code> is therefore a valid
|
||
regionless sink. <code>region=<name></code> is different: it resolves a configured,
|
||
flood-allowed region and one of that region's transport keys.</li>
|
||
<li>A <code>stop</code> on a row whose <code>region=</code> target is currently unusable is also inert,
|
||
allowing lower-priority safety rules to run. Direct <code>scope=</code> targets do not
|
||
have this configuration dependency.</li>
|
||
<li><code>rate=N/min</code> is a per-node, per-row fixed one-minute forwarding limit. It can
|
||
stand alone or accompany a scope/region rewrite. Quota is charged only after
|
||
every other forwarding gate, including moderation, accepts the packet. It is
|
||
not keyed per sender; use <code>flood.moderation</code> when a group-text rate must be
|
||
tied to an exact display name.</li>
|
||
<li><code>retry</code> allows a matching received flood to start the configured retry
|
||
sequence. <code>retry=on</code>, <code>retry=allow</code>, and <code>action=retry</code> are aliases. If the
|
||
table has no active <code>retry</code> rows, global retry behavior is unchanged. If it
|
||
has one or more, those rows are a retry allow-list: at least one must remain
|
||
in the ordered, stop-truncated match set. The action may accompany rewrite,
|
||
rate, or stop, but not <code>drop</code>; its compact flag is <code>f=r</code>.</li>
|
||
<li><code>priority=0-255</code> controls the primary processing order. Higher values run
|
||
first. Equal values use automatic channel specificity (authenticated, then
|
||
raw hash, then wildcard) before slot order. <code>pri=</code> is the compact alias.</li>
|
||
<li><code>stop</code> (or <code>action=stop</code>) applies this row and prevents lower-order FPF7 rows
|
||
from acting. It can stand alone or accompany drop, rewrite, or rate.</li>
|
||
</ul>
|
||
<p>When several rows use the same channel key, authentication is performed once
|
||
for that packet and reused by those rows. This cache lives only for the current
|
||
receive evaluation; it is not persisted and never stores plaintext or a
|
||
password. A <code>hash:XX</code> row deliberately skips authentication and uses only the
|
||
one visible byte.</p>
|
||
<p>The global retry controls remain hard gates. A <code>retry</code> row does not override a
|
||
zero <code>flood.retry.count</code>, path/type attempt caps, disabled forwarding,
|
||
<code>flood.retry.advert</code>, a drop verdict, or any other forwarding rejection.
|
||
<code>flood.retry.bridge</code> independently chooses ordinary retry or bridge-bucket
|
||
completion for an allowed packet. The selector applies to received floods;
|
||
locally originated floods retain the normal global behavior.</p>
|
||
<p>The exact requested examples are:</p>
|
||
<pre><code class="language-text"># If #rgdata arrives unscoped with more than 3 received hops, add
|
||
# the regionless #BlackHole86 scope.
|
||
set flood.rule.2 type=grp_data hops=4+ channel=#rgdata in=none scope=BlackHole86
|
||
|
||
# Rewrite the exact incoming #usa scope to #BlackHole86 for #rgdata.
|
||
set flood.rule.3 type=grp_data channel=#rgdata in=scope:usa scope=BlackHole86
|
||
|
||
# Match a two-byte source-path prefix and cap forwarding at 10 per minute.
|
||
set flood.rule.4 type=any prefix=860C rate=10/min
|
||
|
||
# Keep authenticated #rgdata at two hops or less out of lower-priority FPF7
|
||
# rules. Hard gates and separate tables still apply.
|
||
set flood.rule.5 type=grp_data hops=0-2 channel=#rgdata priority=200 stop
|
||
|
||
# Retry received Public and #hamradio floods, using bridge completion.
|
||
# Once these rows exist, other received floods are not retried.
|
||
set flood.retry.bridge on
|
||
set flood.rule.6 type=any channel=public retry
|
||
set flood.rule.7 type=any channel=#hamradio retry
|
||
|
||
# Fall back to an unauthenticated one-byte match if only the visible hash is known.
|
||
set flood.rule.8 type=any channel=hash:A7 retry
|
||
|
||
get flood.rule.2
|
||
get flood.rule.3
|
||
get flood.rule.4
|
||
</code></pre>
|
||
<p>Public's visible channel hash is <code>0x11</code>, so a <code>hash:11 drop</code> row also matches
|
||
Public unless an earlier exact-channel rule stops it. This standalone example
|
||
preserves authenticated Public while dropping other packets that use the same
|
||
visible byte:</p>
|
||
<pre><code class="language-text">set flood.rule.2 type=any channel=public retry stop
|
||
set flood.rule.3 type=any channel=hash:11 drop
|
||
</code></pre>
|
||
<p>The Public rule's MAC/decrypt check must succeed before its <code>stop</code> applies. A
|
||
colliding channel misses that rule and reaches the hash drop. With equal
|
||
numeric priorities, authenticated-channel specificity automatically puts the
|
||
Public rule first regardless of slot order. Without <code>stop</code>, both rows match
|
||
Public and the sticky drop wins. Remove <code>retry</code> from the Public row if the
|
||
exemption should not also opt Public into flood retry. An explicitly higher
|
||
numeric priority on the hash rule remains an operator override.</p>
|
||
<p>The 240 KB STM32WL profiles keep <code>MESH_ENABLE_FLOOD_RULE_ENGINE=0</code> and retain
|
||
the persistent compact FPF6 <code>flood.filter</code> and blacklist syntax below. They
|
||
still perform filtering, but omit the generalized <code>flood.rule</code> parser and
|
||
extended fields. No partition size is changed by this feature.</p>
|
||
<p>The compatible filter and blacklist commands are:</p>
|
||
<pre><code class="language-text">set flood.filter.blacklist <ID[,ID...]>
|
||
set flood.filter.blacklist.<slot> <ID[,ID...]>
|
||
get flood.filter.blacklist
|
||
get flood.filter.blacklist.<slot>
|
||
del flood.filter.blacklist
|
||
del flood.filter.blacklist.<slot>
|
||
set flood.filter <type> [hops] [path=blacklist] [scope=<name>] [require=region] [tx=slow] [suspend=tempradio]
|
||
set flood.filter.<slot> <type> [hops] [path=blacklist] [scope=<name>] [require=region] [tx=slow] [suspend=tempradio]
|
||
get flood.filter
|
||
get flood.filter.<slot>
|
||
del flood.filter.<slot>
|
||
del flood.filter all
|
||
</code></pre>
|
||
<p>The blacklist holds up to 255 unique 3-byte repeater IDs on ESP32 builds and
|
||
18 on other builds. Each is written as six hexadecimal digits. For example:</p>
|
||
<pre><code class="language-text">set flood.filter.blacklist A1B2C3,D4E5F6,112233
|
||
set flood.filter.blacklist.4 445566
|
||
set flood.filter any all path=blacklist
|
||
</code></pre>
|
||
<p>This is intended for abuse containment, such as refusing to retransmit floods
|
||
that repeatedly enter the mesh through known internet gateways dumping bulk
|
||
traffic. The list is shared by every FPF7 row and scope-rewrite row that uses
|
||
<code>path=blacklist</code>; it is not copied into each rule.</p>
|
||
<p>An unnumbered <code>set</code> replaces the list with up to 18 IDs, the largest command
|
||
that fits every CLI transport. A numbered <code>set</code> writes a batch of up to 18 IDs
|
||
beginning at an existing slot or the next consecutive slot. This is how an
|
||
ESP32 list grows beyond 18. Deleting a numbered entry compacts the entries
|
||
after it. Unnumbered <code>get</code> reports the total and prints the leading IDs that
|
||
fit; numbered <code>get</code> retrieves one specific entry.</p>
|
||
<p><code>path=blacklist</code> is an unordered precondition on that row. With 3-byte path
|
||
hashes, one or more exact blacklist hits qualifies the packet. With 2-byte
|
||
path hashes, two or more received path entries must match the first two bytes
|
||
of listed IDs. Each received entry is counted at most once. A 1-byte path
|
||
never qualifies. The IDs may occur anywhere in the received path; neither
|
||
their list order nor their path order matters.</p>
|
||
<p>Without a slot number, <code>set</code> reuses an identical row or selects the first empty
|
||
slot. Use a slot number to replace a row whose match or action is changing.
|
||
Omitting the hop expression means <code>all</code> (<code>0-63</code>).</p>
|
||
<p>Numbered <code>get flood.rule.N</code> and <code>get flood.filter.N</code> normally use descriptive
|
||
field names. On generalized builds, a reply that would be too long uses the
|
||
complete <code>set fr.N ...</code> spelling below. <code>get fr.N</code> always requests that spelling.
|
||
If even the short command exceeds one reply, it returns
|
||
<code>Err - compact command exceeds reply size</code> instead of a partial command.
|
||
Saving such a rule still succeeds and reports that its details exceed the
|
||
reply size.</p>
|
||
<h3 id="shorthand-for-copying-rules">Shorthand for copying rules</h3>
|
||
<p>On generalized repeaters and FULL ESP32 room servers, <code>fr</code> is a shorter name
|
||
for <code>flood.rule</code>. Both forms use the same parser, validation, permissions, and
|
||
saved rows. Short and full field names can be mixed in either command.
|
||
<code>fr</code> requires an explicit action, just like <code>flood.rule</code>.</p>
|
||
<p>These commands set exactly the same rule:</p>
|
||
<pre><code class="language-text">set flood.rule.3 type=any channel=#wardriving hops=all mode=bridge,cross drop
|
||
set fr.3 any c=#wardriving m=bc d
|
||
</code></pre>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Full form</th>
|
||
<th>Short form</th>
|
||
<th>Meaning</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><code>flood.rule[.N]</code></td>
|
||
<td><code>fr[.N]</code></td>
|
||
<td>Same rule table for <code>get</code>, <code>set</code>, and <code>del</code>.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>type=any</code></td>
|
||
<td><code>any</code> or <code>*</code></td>
|
||
<td>First token: any payload type. Named/numeric types also work, with optional <code>t=</code>.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>hops=N</code>, <code>N+</code>, <code>N-M</code>, or <code>all</code></td>
|
||
<td><code>h=N</code>, <code>h=N+</code>, <code>h=N-M</code>, or <code>h=*</code></td>
|
||
<td>Hop condition; a bare range also works. Omitted means all hops.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>mode=radio</code>, <code>bridge</code>, <code>cross</code>, <code>bridge,cross</code></td>
|
||
<td><code>m=r</code>, <code>m=b</code>, <code>m=c</code>, <code>m=bc</code></td>
|
||
<td>Select the admission path. Omitted means radio; <code>cb</code>, <code>b,c</code>, and <code>c,b</code> also mean both transport paths.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>channel=...</code></td>
|
||
<td><code>c=...</code></td>
|
||
<td>Same authenticated name/key or explicit <code>hash:XX</code> matcher.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>prefix=...</code></td>
|
||
<td><code>p=...</code></td>
|
||
<td>Ordered path prefix.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>hashbytes=any</code>, <code>1</code>, <code>2</code>, <code>2+</code>, or <code>3</code></td>
|
||
<td><code>pb=*</code>, <code>1</code>, <code>2</code>, <code>2+</code>, or <code>3</code></td>
|
||
<td>Encoded path-hash width, even with zero hops; <code>2+</code> matches 2 and 3.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>path=blacklist</code></td>
|
||
<td><code>p=bl</code></td>
|
||
<td>Shared unordered blacklist; repeater only.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>in=any</code>, <code>none</code>, <code>scoped</code>, <code>allowed</code>, <code>unknown</code></td>
|
||
<td><code>i=*</code>, <code>i=n</code>, <code>i=s</code>, <code>i=a</code>, <code>i=u</code></td>
|
||
<td>Incoming scope condition.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>in=scope:name</code>, <code>in=region:name</code></td>
|
||
<td><code>i=s:name</code>, <code>i=r:name</code></td>
|
||
<td>Match a specific incoming scope or region.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>drop</code></td>
|
||
<td><code>d</code></td>
|
||
<td>Drop matching traffic.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>scope=name</code>, <code>region=name</code></td>
|
||
<td><code>s=name</code>, <code>r=name</code></td>
|
||
<td>Rewrite to a public scope or configured region.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>rate=N/min</code></td>
|
||
<td><code>q=N</code></td>
|
||
<td>Per-row forwarding allowance.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>priority=N</code></td>
|
||
<td><code>pri=N</code></td>
|
||
<td>Higher values run first.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>stop</code>, <code>retry</code></td>
|
||
<td><code>s</code>, <code>r</code></td>
|
||
<td>Stop later rules or allow the configured flood retry.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>tx=slow</code>, <code>suspend=tempradio</code>, <code>retry</code></td>
|
||
<td><code>f=s</code>, <code>f=t</code>, <code>f=r</code></td>
|
||
<td>Flags can combine, for example <code>f=str</code>.</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>The <code>=</code> distinguishes <code>s=name</code> (scope) from <code>s</code> (stop), and <code>r=name</code>
|
||
(region) from <code>r</code> (retry). Short forms keep the same action restrictions;
|
||
for example, <code>m=bc r</code> is rejected because transport rules cannot enable retries.</p>
|
||
<h3 id="filter-every-1-byte-flood-path">Filter every 1-byte flood path</h3>
|
||
<pre><code class="language-text">set flood.rule type=any hashbytes=1 drop
|
||
</code></pre>
|
||
<p>The equivalent short command is <code>set fr any pb=1 d</code>. This adds a rule in a free
|
||
slot without replacing the default rules. It stops this node forwarding all
|
||
1-byte flood packets, including advertisements and relayed login/admin traffic;
|
||
direct routes and local delivery are unchanged. Use a narrower <code>type=</code> or
|
||
<code>channel=</code> if those floods must remain reachable. Use <code>hashbytes=2</code> or <code>3</code> for
|
||
an exact width, or <code>set fr any pb=2+ d</code> to drop both larger supported widths with
|
||
one rule. Use <code>get fr.<slot></code> to copy the saved command.</p>
|
||
<p>Width-only rules require updated firmware. Existing rules remain unchanged and
|
||
the table uses no additional RAM or storage. Before downgrading to firmware
|
||
without this selector, remove width-only rules: its older reader considers them
|
||
invalid and can reset the rule table to defaults.</p>
|
||
<pre><code class="language-text">get fr.3
|
||
</code></pre>
|
||
<p>Returns a complete command ready to copy:</p>
|
||
<pre><code class="language-text">set fr.3 any m=bc c=#wardriving d
|
||
</code></pre>
|
||
<p>The compact reply omits default values and prints specific payload types as
|
||
numbers. <code>get fr</code> lists the table. <code>set fr ...</code> without a slot reuses an
|
||
identical rule or adds it to the first empty slot. <code>del fr.3</code> removes slot 3;
|
||
<code>del fr all</code> clears the forward rules.</p>
|
||
<p>Private keys are still hidden in replies. A displayed <code>c=key:XXXXXXXX</code> is a
|
||
local reference to the exact key in an active rule on that device, so it can
|
||
be pasted to edit or copy a rule there. On another device, or after deleting
|
||
the last rule holding that key, supply the original key instead. An unknown
|
||
or ambiguous reference is rejected; it never becomes an unauthenticated
|
||
channel-hash match.</p>
|
||
<p>The shorthand does not rename <code>flood.channel.scope</code>, <code>flood.moderation</code>, or
|
||
the blacklist-management commands. Companions and compact FPF6 profiles do
|
||
not expose <code>fr</code>.</p>
|
||
<h3 id="scope-actions-and-legacy-rules">Scope actions and legacy rules</h3>
|
||
<p>A legacy row without <code>scope=</code> is the existing drop action. On extended builds,
|
||
an explicit <code>drop</code> has the same result, while <code>rate=</code> by itself creates a
|
||
rate-only row. A row with <code>scope=</code> adds transport scope to an unscoped packet
|
||
or replaces the codes on an already-scoped packet. The scope name is normalized
|
||
with a leading <code>#</code>, and the 128-bit transport key is derived directly from that
|
||
hashtag. The name does not need to exist in the region list and is not added to
|
||
it. Public names up to 30 characters are accepted; private <code>$</code> scopes are not.</p>
|
||
<p><code>require=region</code> is the legacy spelling of <code>in=allowed</code>. The repeater evaluates the packet's
|
||
original route before any rewrite in that receive pass. An incoming transport
|
||
scope must match a locally allowed region; an unscoped flood must be allowed by
|
||
the wildcard region. If the check fails, that row is skipped, the filter does
|
||
not grant a region bypass, and the unchanged packet is allowed to fail
|
||
normal region enforcement. Other independently configured scope rows still
|
||
apply in their normal order.</p>
|
||
<p>When multiple scope or region rows match, the highest numeric-priority row
|
||
wins. Equal priorities use authenticated channel, raw hash, then wildcard
|
||
specificity before the slot-number tie-break.
|
||
Rewrite rows do not approve a packet: any matching drop row and every remaining forwarding gate can
|
||
still reject it. A filter-assigned scope is trusted without local region-list
|
||
validation, but <code>repeat</code>, <code>flood.max</code>, loop detection, and
|
||
moderation still apply. By default, a changed scope bypasses inbound <code>rxdelay</code>,
|
||
then is retransmitted with zero <code>txdelay</code> and the highest outbound queue
|
||
priority. Add <code>tx=slow</code> to use an effective inbound <code>rxdelay</code> base of
|
||
<code>max(2, configured rxdelay * 2)</code>, retain normal queue priority, and force the
|
||
maximum <code>txdelay</code> factor of <code>2.0</code>; the randomized transmit delay ranges from
|
||
zero through ten packet airtimes. <code>tx=fast</code> explicitly restores the default.
|
||
Selecting the scope already present does not grant special treatment. Active
|
||
radio transmission, CAD, and airtime-budget limits are unchanged.</p>
|
||
<p>On generalized repeaters, forward rules, <code>flood.channel.scope</code> rewrite rows,
|
||
the shared blacklist, and the <code>flood.channel.data</code> compatibility state are one
|
||
atomic FPF7 policy image. Existing <code>/flood_ch_scope</code>, <code>/flood_filter_bl</code>, FPF6,
|
||
and FCB2 data is imported once; the old files are removed only after the new
|
||
image verifies and commits. Compact FPF6 repeaters retain separate files.
|
||
Deleting the blacklist leaves <code>path=blacklist</code> rows in place but dormant until
|
||
IDs are configured again. Path hashes are truncated routing identifiers and
|
||
are not authenticated proof that a particular repeater—or a particular
|
||
person—handled a packet. FULL room servers reject blacklist commands.</p>
|
||
<p>On first initialization, flood-filter slot 1 is seeded with:</p>
|
||
<pre><code class="language-text">set flood.filter.1 0x0C all suspend=tempradio
|
||
</code></pre>
|
||
<p>This is a normal editable row. After the table has been saved, deleting it
|
||
remains persistent across reboot; the firmware does not recreate it. Run the
|
||
same command to restore the exact seeded row, or omit <code>.1</code> to preserve existing
|
||
slot assignments and use the first empty slot. Operators may add
|
||
<code>suspend=tempradio</code> to any other row that should be skipped while either
|
||
<code>tempradio</code> or <code>tempradio2</code> is active. This includes scheduled temporary
|
||
profiles. The row resumes once both temporary sessions have ended.</p>
|
||
<p>Suspension does not approve a packet or bypass the rest of the filter table. It
|
||
skips that row, then evaluation continues with the next row and the remaining
|
||
forwarding gates. An ordinary drop <code>any</code> row therefore still applies during
|
||
the temporary-radio window unless an earlier matching stop row ends FPF7
|
||
processing. <code>repeat</code>, <code>flood.max*</code>, region handling, loop detection, and the OTA
|
||
subsystem's own hop limit also remain in force.</p>
|
||
<p>Standard traceroute uses direct routing and bypasses <code>mode=radio</code> filters.
|
||
Explicit bridge/cross filters can also match direct traffic at those transport
|
||
boundaries; the built-in channel rule does not match TRACE packets. For a
|
||
custom flood-form trace, <code>type=any</code>, explicit <code>trace</code>, scope, region, rate, and
|
||
drop rows all behave normally. The stock core does not normally flood-forward
|
||
TRACE packets.</p>
|
||
<h3 id="remote-administration-lockout-warning">Remote-administration lockout warning</h3>
|
||
<p>There are no hidden payload-type or short-hop exemptions in FPF7. Drop and
|
||
rate rules can block <code>req</code>, <code>response</code>, <code>txt_msg</code>, <code>anon_req</code>, <code>path</code>, ACK, and
|
||
multipart traffic beginning at hop <code>0</code> when their match fields say so.</p>
|
||
<p>A flooded login starts as <code>ANON_REQ</code>; its reply is commonly a <code>PATH</code> packet
|
||
carrying an encrypted <code>RESPONSE</code>. Before a direct return path is established,
|
||
administrative replies and CLI text can also be flooded. Transit repeaters do
|
||
not have the session key and cannot distinguish those encrypted admin exchanges
|
||
from ordinary peer packets with the same outer type. A rule therefore affects
|
||
the complete outer packet class, not only packets that ultimately authenticate
|
||
as administrators. Keep a serial or other recovery path and stage broad
|
||
deny/rate rules carefully.</p>
|
||
<p>Hop expressions are based on the path count when this repeater receives the
|
||
packet:</p>
|
||
<ul>
|
||
<li><code>N</code> matches exactly <code>N</code> received hops.</li>
|
||
<li><code>N+</code> matches <code>N</code> or more received hops.</li>
|
||
<li><code>N-M</code> matches the inclusive range.</li>
|
||
<li><code>all</code> matches <code>0</code> through <code>63</code> hops.</li>
|
||
<li><code>0+</code>, <code>all</code>, and omitting the hop expression are equivalent. <code>get</code> reports
|
||
the stored range using the canonical spelling <code>all</code>.</li>
|
||
</ul>
|
||
<p>Examples:</p>
|
||
<pre><code class="language-text"># Stop forwarding group data once it arrives with four or more path entries.
|
||
set flood.filter grp_data 4+
|
||
|
||
# Stop long adverts, while still allowing shorter adverts.
|
||
set flood.filter.2 advert 6+
|
||
|
||
# Keep LoRa OTA floods from crossing this repeater at path counts 2 through 4.
|
||
set flood.filter.3 ota 2-4
|
||
|
||
# Assign #local scope to group text without requiring #local in the region map.
|
||
set flood.filter grp_txt all scope=local
|
||
|
||
# Rewrite only packets whose incoming region was already acceptable.
|
||
set flood.filter grp_data all scope=local require=region
|
||
|
||
# Rewrite matching blacklisted paths without fast-tracking their retransmission.
|
||
set flood.filter grp_data all path=blacklist scope=local tx=slow
|
||
|
||
# Drop matching flood types after the unordered path blacklist qualifies.
|
||
set flood.filter.blacklist A1B2C3,D4E5F6,112233
|
||
set flood.filter any all path=blacklist
|
||
|
||
# Apply a hard ceiling to flood payload types at 12 or more received hops.
|
||
set flood.filter any 12+
|
||
</code></pre>
|
||
<h3 id="high-traffic-mesh-example">High-traffic mesh example</h3>
|
||
<p>This preset limits request and group-data propagation early while allowing the
|
||
login-capable response, anonymous-request, and path types to travel farther:</p>
|
||
<pre><code class="language-text">set flood.filter req 3+
|
||
set flood.filter response 9+
|
||
set flood.filter 0x06 3+
|
||
set flood.filter 0x07 9+
|
||
set flood.filter path 9+
|
||
set flood.filter control 1+
|
||
get flood.filter
|
||
</code></pre>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Rule</th>
|
||
<th>Stops retransmission when received with</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><code>req 3+</code></td>
|
||
<td>3 or more path entries</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>response 9+</code></td>
|
||
<td>9 or more path entries</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>0x06 3+</code> (<code>grp_data</code>)</td>
|
||
<td>3 or more path entries</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>0x07 9+</code> (<code>anon_req</code>)</td>
|
||
<td>9 or more path entries</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>path 9+</code></td>
|
||
<td>9 or more path entries</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>control 1+</code></td>
|
||
<td>1 or more path entries</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>On a new generalized repeater table, the three factory rules occupy slots
|
||
1 through 3, so these unnumbered commands normally fill slots 4 through 9.
|
||
FULL room servers and compact tables seed only OTA and use slots 2 through 7.
|
||
Existing tables may choose different
|
||
free slots. All six rules take effect at the thresholds shown; there are no
|
||
hidden short-hop exceptions. The Control rule allows a flood received with
|
||
path count <code>0</code> to be forwarded
|
||
once, then stops it at the next repeater. Normal node-discovery Control packets
|
||
are direct zero-hop packets and bypass these <code>mode=radio</code> rules. These rules affect
|
||
only retransmission by the repeater; local reception and logging remain
|
||
unchanged.</p>
|
||
<p>Accepted payload names are:</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Value</th>
|
||
<th>Short name</th>
|
||
<th>Full name</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><code>0x00</code></td>
|
||
<td><code>req</code></td>
|
||
<td><code>PAYLOAD_TYPE_REQ</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>0x01</code></td>
|
||
<td><code>response</code></td>
|
||
<td><code>PAYLOAD_TYPE_RESPONSE</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>0x02</code></td>
|
||
<td><code>txt_msg</code></td>
|
||
<td><code>PAYLOAD_TYPE_TXT_MSG</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>0x03</code></td>
|
||
<td><code>ack</code></td>
|
||
<td><code>PAYLOAD_TYPE_ACK</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>0x04</code></td>
|
||
<td><code>advert</code></td>
|
||
<td><code>PAYLOAD_TYPE_ADVERT</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>0x05</code></td>
|
||
<td><code>grp_txt</code></td>
|
||
<td><code>PAYLOAD_TYPE_GRP_TXT</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>0x06</code></td>
|
||
<td><code>grp_data</code></td>
|
||
<td><code>PAYLOAD_TYPE_GRP_DATA</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>0x07</code></td>
|
||
<td><code>anon_req</code></td>
|
||
<td><code>PAYLOAD_TYPE_ANON_REQ</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>0x08</code></td>
|
||
<td><code>path</code></td>
|
||
<td><code>PAYLOAD_TYPE_PATH</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>0x09</code></td>
|
||
<td><code>trace</code></td>
|
||
<td><code>PAYLOAD_TYPE_TRACE</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>0x0A</code></td>
|
||
<td><code>multipart</code></td>
|
||
<td><code>PAYLOAD_TYPE_MULTIPART</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>0x0B</code></td>
|
||
<td><code>control</code></td>
|
||
<td><code>PAYLOAD_TYPE_CONTROL</code></td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>0x0C</code></td>
|
||
<td><code>ota</code></td>
|
||
<td><code>PAYLOAD_TYPE_OTA</code> in this fork</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>0x0D</code></td>
|
||
<td><code>13</code></td>
|
||
<td>reserved</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>0x0E</code></td>
|
||
<td><code>14</code></td>
|
||
<td>reserved</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>0x0F</code></td>
|
||
<td><code>raw_custom</code></td>
|
||
<td><code>PAYLOAD_TYPE_RAW_CUSTOM</code></td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>Decimal values <code>0</code> through <code>15</code>, hexadecimal values <code>0x00</code> through <code>0x0F</code>, the
|
||
full <code>PAYLOAD_TYPE_*</code> names, and <code>any</code> are also accepted. Upstream currently
|
||
reserves <code>0x0C</code>; this fork assigns it to LoRa OTA. Rows are suspended during
|
||
temporary-radio operation only when explicitly configured that way.</p>
|
||
<h2 id="moderate-group-text-by-channel-and-username">Moderate group text by channel and username</h2>
|
||
<p>Use <code>flood.moderation</code> for flood <code>GRP_TXT</code> messages. The repeater validates and
|
||
decrypts the selected channel, extracts the display name before the first <code>:</code>,
|
||
then applies the rule:</p>
|
||
<pre><code class="language-text">set flood.moderation <channel> <sender> <action> [action...]
|
||
set flood.moderation.<slot> <channel> <sender> <action> [action...]
|
||
get flood.moderation
|
||
get flood.moderation.<slot>
|
||
del flood.moderation.<slot>
|
||
del flood.moderation all
|
||
</code></pre>
|
||
<p>Channels can be specified as:</p>
|
||
<ul>
|
||
<li><code>public</code> for the built-in Public channel</li>
|
||
<li><code>#name</code> for a well-known hashtag channel</li>
|
||
<li>a 128-bit or 256-bit channel key in hexadecimal</li>
|
||
</ul>
|
||
<p>The key is stored locally so packets can be authenticated and decrypted. It is
|
||
not included in <code>get flood.moderation</code> output.</p>
|
||
<p>Available actions are:</p>
|
||
<ul>
|
||
<li><code>drop</code> - do not retransmit any matching message</li>
|
||
<li><code>rate=X/min</code> - retransmit at most <code>X</code> messages per local 60-second window</li>
|
||
<li><code>hops=N</code> - do not retransmit when the received path count is <code>N</code> or higher</li>
|
||
<li><code>path=H1[,H2,H3]</code> - require the first one to three path hashes to match</li>
|
||
<li><code>path=*</code> - match every path; this is the default</li>
|
||
</ul>
|
||
<p>At least one of <code>drop</code>, <code>rate=X/min</code>, or <code>hops=N</code> is required. Rate and hop
|
||
limits can be combined. <code>rate=0/min</code> is equivalent to <code>drop</code>.</p>
|
||
<h3 id="per-user-per-channel-rate-limits">Per-user, per-channel rate limits</h3>
|
||
<p>Rate limits require an exact username; <code>*</code> is not accepted for a rate rule.
|
||
Username comparison is ASCII case-insensitive, and names containing spaces must
|
||
be quoted. A rule's counter is independent from rules for the same name on
|
||
other channels, so this directly supports "X messages per minute from user X
|
||
on channel Y." Counters are local to this repeater and reset on reboot.</p>
|
||
<pre><code class="language-text"># At most five Public-channel messages per minute from this display name.
|
||
set flood.moderation public "Noisy User" rate=5/min
|
||
|
||
# A separate limit for the same name on #local.
|
||
set flood.moderation #local "Noisy User" rate=10/min
|
||
|
||
# Combine a rate limit with a maximum forwarding distance.
|
||
set flood.moderation public alice rate=4/min hops=5
|
||
</code></pre>
|
||
<h3 id="match-the-start-of-a-path">Match the start of a path</h3>
|
||
<p>Path matching accepts one-, two-, or three-byte hashes. Every hash in one rule
|
||
must use the same width, and matching always starts at the beginning of the
|
||
received path:</p>
|
||
<pre><code class="language-text">set flood.moderation #local bot drop path=A1B2C3,D4E5F6
|
||
set flood.moderation public alice rate=3/min path=71
|
||
</code></pre>
|
||
<p>A path-qualified rule cannot match a zero-hop packet and does not match until
|
||
the packet contains all path entries listed by the rule.</p>
|
||
<h2 id="how-the-forwarding-controls-combine">How the forwarding controls combine</h2>
|
||
<p>A flood packet is retransmitted only if it passes every applicable control. In
|
||
other words, the controls combine as deny rules:</p>
|
||
<ol>
|
||
<li><code>flood.channel.scope.require</code> evaluates a listed group channel against the
|
||
original incoming scope; unlisted group channels bypass the later region
|
||
gate while the table is active.</li>
|
||
<li><code>flood.channel.scope</code> tries a path-qualified channel row before that
|
||
channel's ordinary fallback, then adds or replaces the scope from either a
|
||
configured region or a direct <code>scope=<name></code> target.</li>
|
||
<li>All extended <code>flood.rule</code> match fields are evaluated against the same
|
||
original incoming packet. Matches are ordered by descending numeric
|
||
priority, then authenticated/raw-hash/wildcard channel specificity, then
|
||
ascending slot. The first matching <code>stop</code> row removes every later FPF7
|
||
match. The highest-order remaining <code>scope=</code> or <code>region=</code> row may replace the
|
||
channel-scope result; a direct scope does not require a region-list entry.</li>
|
||
<li><code>repeat</code> and <code>flood.max*</code> are checked.</li>
|
||
<li>The FPF7 forward phase, including any row managed through
|
||
<code>flood.channel.data*</code>, applies drop and rate decisions using that saved
|
||
match result. No packet type or short-hop range is silently exempted.</li>
|
||
<li>Region and loop-detection rules are checked; a regionless scope assigned by
|
||
either table is already trusted when it has no region-list match, except
|
||
that it cannot rescue a channel rejected by
|
||
<code>flood.channel.scope.require</code>.</li>
|
||
<li><code>flood.moderation</code> checks decrypted group text, username, rate, hops, and
|
||
path. If it accepts the packet, matching general-rule rate counters are
|
||
charged immediately before retransmission is approved.</li>
|
||
</ol>
|
||
<p>The first denial is enough to prevent retransmission. A packet that is denied
|
||
can still appear in local logs or MQTT output, unless a separate
|
||
<code>mode=bridge</code> rule blocks MQTT packet publication. Moderation runs last because its
|
||
rate counters are charged only for packets that pass every other forwarding
|
||
control and will actually be retransmitted.</p>
|
||
<h2 id="delegate-filter-management">Delegate filter management</h2>
|
||
<p>On repeaters, ACL permission <code>5</code> is the filter-manager role:</p>
|
||
<pre><code class="language-text">setperm <companion-public-key-hex> 5
|
||
</code></pre>
|
||
<p>A filter manager can read non-secret operational status and manage <code>repeat</code>,
|
||
<code>loop.detect</code>, <code>flood.max*</code>, <code>flood.channel.data*</code>,
|
||
<code>flood.filter*</code>, <code>flood.rule*</code>, <code>fr[.N]</code>, and <code>flood.moderation*</code>. Delegated <code>get</code> access uses an
|
||
explicit allowlist: it cannot retrieve guest, WiFi, MQTT, bridge, or other
|
||
credentials, and it cannot change regions, ACL entries, radio settings, or
|
||
unrelated administrator settings. Because <code>flood.filter scope=</code> derives a
|
||
public hashtag key directly, a filter manager can configure that action without
|
||
region-manager permission; it still cannot edit the region hierarchy.</p>
|
||
<p>FULL ESP32 room servers use their existing administrator check for remote
|
||
<code>fr</code>, <code>flood.rule</code>, and <code>flood.filter</code> commands; they do not grant this table through
|
||
permission <code>5</code>.</p>
|
||
<p>ACL permission <code>4</code>, the region/scope-manager role, can read, add, replace, and
|
||
delete <code>flood.channel.scope</code> and <code>flood.channel.scope.require</code> rows and manage
|
||
regions. This lets the same delegate create target regions, assign forced
|
||
scopes from regions or direct hashtag names, and select the channels that
|
||
require valid incoming scopes.</p>
|
||
<h2 id="security-limitations">Security limitations</h2>
|
||
<p>Public and hashtag channels use shared, well-known keys. A valid channel MAC
|
||
proves that the sender knew the channel key; it does not identify a person.
|
||
The <code><sender></code> value is an unverified display name and can be spoofed. Path
|
||
hashes are truncated routing hints and can collide or be manipulated; they are
|
||
not authenticated user identities.</p>
|
||
<p>Use username and path rules as traffic moderation, not as an authorization
|
||
boundary. For a strict network boundary, combine these tools with region ACLs,
|
||
private transport/channel keys, and controlled device access.</p>
|
||
<h2 id="filter-bridge-and-radio-crossover-traffic">Filter bridge and radio crossover traffic</h2>
|
||
<p>The <code>mode=</code> matcher selects a separate admission phase within the same
|
||
<code>flood.rule</code> / <code>flood.filter</code> table:</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Mode</th>
|
||
<th>Where the rule applies</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td><code>radio</code></td>
|
||
<td>Ordinary LoRa flood forwarding. This is the default when <code>mode=</code> is omitted.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>bridge</code></td>
|
||
<td>Packets entering or leaving an RS232 or ESP-NOW bridge, and MeshCore RX/TX packet publication through MQTT.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>cross</code></td>
|
||
<td>Transmissions copied to the other radio profile, including a copy's retries. The same-profile transmission remains eligible.</td>
|
||
</tr>
|
||
<tr>
|
||
<td><code>bridge,cross</code></td>
|
||
<td>Both transport paths using one rule. <code>cross,bridge</code> is equivalent.</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>The third built-in repeater filter is:</p>
|
||
<pre><code class="language-text">set flood.rule.3 type=any channel=#wardriving hops=all mode=bridge,cross drop
|
||
get flood.rule.3
|
||
</code></pre>
|
||
<p>The equivalent short command is <code>set fr.3 any c=#wardriving m=bc d</code>.
|
||
Use <code>m=b</code> for bridge only or <code>m=c</code> for crossover only.</p>
|
||
<p>It authenticates both <code>GRP_TXT</code> and <code>GRP_DATA</code> against the public <code>#wardriving</code>
|
||
channel key. A different channel with the same one-byte hash is not blocked.
|
||
It covers every hop count, including zero-hop/local messages, flood routes and
|
||
direct routes. It remains active during temporary-radio sessions and with
|
||
<code>radio2.cross on</code>: enabling crossover makes a copy eligible, but does not
|
||
override the filter. The second built-in rule still permits ordinary
|
||
<code>#wardriving</code> forwarding through four received hops; the third rule keeps
|
||
those messages on their originating radio profile.</p>
|
||
<p>Bridge filtering runs in both directions before bridge deduplication, inbound
|
||
queueing, serial writes, ESP-NOW queueing, or MQTT packet publication. It
|
||
applies with either <code>bridge.source rx</code> or <code>bridge.source tx</code> and with wrapped or raw
|
||
ESP-NOW framing. MQTT here is the observer packet output; this does not add
|
||
MQTT-to-LoRa injection or filter MQTT status/telemetry. Local reception and
|
||
local packet logs remain available. Switching one radio between profiles is
|
||
covered by <code>cross</code>; the bridge's WiFi channel is a separate setting.</p>
|
||
<p>Transport modes support <code>drop</code>, <code>rate=X/min</code>, <code>priority=</code>, and <code>stop</code>, with the
|
||
existing type, channel, hops, prefix, blacklist, incoming-scope and
|
||
<code>suspend=tempradio</code> matchers. Scope/region rewrites, retry actions, and TX
|
||
timing actions are rejected in these modes. Ordering and <code>stop</code> apply only to
|
||
rules in the current mode: a radio exception cannot bypass a bridge/cross
|
||
drop. A combined rule shares one rate counter across bridge and cross
|
||
admission attempts; retries count too. A rejected queue insertion can consume
|
||
an admission allowance. Queued packets already admitted are not recalled by
|
||
editing a rule. Same-profile transmissions use the ordinary radio policy.</p>
|
||
<p><code>get flood.rule.N</code> shows <code>mode=</code>; the overview marks each row with its mode.
|
||
Modes are persistent, case-insensitive, and apply immediately to new admission
|
||
attempts. <code>radio</code> cannot be combined with <code>bridge</code> or <code>cross</code> in a single row.
|
||
For transport rules, hop and scope matchers see the packet at that boundary:
|
||
a TX/crossover packet can already contain an appended hop or rewritten scope.
|
||
The built-in rule uses all hops and any scope, so these changes cannot bypass it.
|
||
On FULL room servers, add a transport rule explicitly; their factory table
|
||
still has only the OTA row. Companions and compact FPF6 builds do not expose
|
||
this generalized filter table.</p>
|
||
<p>Saved tables, occupied slots, and deleted defaults are preserved on upgrade.
|
||
To add the new default to an existing table without replacing another rule,
|
||
omit the slot number (repeating the identical command reuses its row):</p>
|
||
<pre><code class="language-text">set flood.rule type=any channel=#wardriving hops=all mode=bridge,cross drop
|
||
get flood.rule
|
||
</code></pre>
|
||
<p>To allow only bridge traffic while retaining the crossover block, replace the
|
||
third rule with <code>mode=cross</code>. Use <code>mode=bridge</code> to retain only the bridge block.
|
||
Use <code>del flood.rule.3</code> to remove both, after checking that slot 3 is still the
|
||
built-in rule. Removing it does not change the separate LoRa hop-limit rule.</p>
|
||
<h2 id="restore-the-factory-seeded-rows">Restore the factory-seeded rows</h2>
|
||
<p>The repeater's factory-seeded forwarding rows can be restored through the CLI:</p>
|
||
<pre><code class="language-text">set flood.rule.1 type=ota hops=all drop suspend=tempradio
|
||
set flood.rule.2 type=any channel=#wardriving hops=5+ drop
|
||
set flood.rule.3 type=any channel=#wardriving hops=all mode=bridge,cross drop
|
||
</code></pre>
|
||
<p>Or use the equivalent short forms:</p>
|
||
<pre><code class="language-text">set fr.1 ota d f=t
|
||
set fr.2 any 5+ c=#wardriving d
|
||
set fr.3 any c=#wardriving m=bc d
|
||
</code></pre>
|
||
<p>These commands explicitly replace the three seeded generalized-repeater slots.
|
||
Inspect them first if they may now contain other rules. Compact FPF6 builds use
|
||
only the first command's <code>flood.filter.1 0x0C all suspend=tempradio</code> form.</p>
|
||
<h2 id="remove-the-custom-rules">Remove the custom rules</h2>
|
||
<p>To save both tables in an empty state:</p>
|
||
<pre><code class="language-text">del flood.filter all
|
||
del flood.moderation all
|
||
get flood.filter
|
||
get flood.moderation
|
||
</code></pre>
|
||
<p>This does not change the older <code>flood.max*</code>, loop-detection, or region settings;
|
||
inspect or reset those separately when troubleshooting.</p>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</article>
|
||
</div>
|
||
|
||
|
||
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
|
||
</div>
|
||
|
||
</main>
|
||
|
||
<footer class="md-footer">
|
||
|
||
<div class="md-footer-meta md-typeset">
|
||
<div class="md-footer-meta__inner md-grid">
|
||
<div class="md-copyright">
|
||
|
||
|
||
Made with
|
||
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
|
||
Material for MkDocs
|
||
</a>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</footer>
|
||
|
||
</div>
|
||
<div class="md-dialog" data-md-component="dialog">
|
||
<div class="md-dialog__inner md-typeset"></div>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
<script id="__config" type="application/json">{"annotate": null, "base": "..", "features": ["content.action.edit", "content.code.copy", "search.highlight", "search.suggest"], "search": "../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
|
||
|
||
|
||
<script src="../assets/javascripts/bundle.d7400e89.min.js"></script>
|
||
|
||
<script src="../_javascript/hosted_doc_links.js?v=20261007-1"></script>
|
||
|
||
<script src="../_javascript/notification_builder.js?v=20261006-channel9"></script>
|
||
|
||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
||
|
||
<script src="../_javascript/firmware_picker.js?v=20261008-rak-uart2-1"></script>
|
||
|
||
<script src="../_javascript/telemetry_decoder.js?v=20261007-hosted-form"></script>
|
||
|
||
<script src="../_javascript/management_decoder.js"></script>
|
||
|
||
<script src="../_javascript/filter_tool.js?v=20261002-hashbytes-2plus"></script>
|
||
|
||
<script src="../_javascript/preset_test.js?v=20260923-2"></script>
|
||
|
||
<script src="../_javascript/esp32_partition_catalog.js?v=20261001-1"></script>
|
||
|
||
|
||
</body>
|
||
</html> |