# Actions

> moat actions: pass, drop, add to a set with an expiry, and per-source rate limits with a burst and on exceed actions, and how the limits work in the kernel.

Source: https://moatfw.dev/docs/actions

| Action | Meaning |
|--------|---------|
| `pass`, `drop` | Final verdict. Must be the last action of its list. |
| `add ip.src to SET [ttl D]` | Insert the source (or `ip.dst`) into an addresses set. |
| `limit RATE [per ip.src[/N]] burst B [on exceed ACTIONS]` | Token bucket. Without `per`, one bucket is shared by all packets. |

`per ip.src/N` (N from 1 to 32) groups IPv4 sources by their /N; IPv6
sources are then grouped by /64. `on exceed` must end with `pass` or
`drop` and cannot contain `limit`. The burst is counted in packets for
packet rates and in bytes for bit rates.

Packet rates go up to 1000000000/s. Each packet costs a whole number of
nanoseconds, so rates above about 100000000/s are approximate:
400000000/s costs 3 ns a packet and lets about 333000000/s through.

```moat
rule udp_flood {
    when udp
    then limit 5000/s per ip.src burst 10000
        on exceed add ip.src to banned, drop
}
```

## How limits work

Limits follow the generic cell rate algorithm: each key keeps the time
at which its next packet is due. A burst of B packets can arrive at
once; after that packets fit at the rate. The state is shared by all
CPUs, so the rate holds for the whole machine, and it lives in one map of
65536 keys that forgets the least recently seen ones.

A `per ip.src` limit puts packets that have no IP header in one shared
bucket of the rule; guard the rule with `ip` to keep them out. Rate
limit state starts afresh when the rules are loaded or reloaded.

## Adding to sets

`add` never shortens an entry: an address already in the set without an
expiry, or with a later one, keeps it. In audit mode `add` does nothing,
so turning audit off never starts with sets filled by traffic that was
only being observed.

> moat decides whether a packet goes on into the host; it never sends one
> anywhere. There is no action to answer, bounce or redirect a packet.
