mirror of
https://github.com/lgcosta/pf-linux-port.git
synced 2026-11-15 11:24:45 -03:00
docs: patches helpers are in tree (verified PATCHES_APPLIED=0 / UNPATCH_DONE); route pool gate 10 written
This commit is contained in:
1 parent
b3e7358868
commit
80396e0b36
3 files changed
+76
-10
No files matched your search
+5
-5
@@ -20,11 +20,11 @@ used.
|
|||||||
`patches/kernel/` therefore contains no `000N-*.patch` today, and applying
|
`patches/kernel/` therefore contains no `000N-*.patch` today, and applying
|
||||||
the (empty) set is a no-op.
|
the (empty) set is a no-op.
|
||||||
|
|
||||||
> Honest note: install.md and the design mention `scripts/apply-patches.sh`,
|
> Honest note: `scripts/apply-patches.sh`, `scripts/unpatch.sh` and
|
||||||
> `scripts/unpatch.sh` and `patches/kernel/series`. Those helpers are **not
|
> `patches/kernel/series` **are in the tree** and are exercised by
|
||||||
> in the tree yet**; until they land, "apply the patch set" is by definition
|
> `make test`-adjacent scripts; the series is empty by design, so applying it
|
||||||
> nothing to do. When a real patch is needed, the first commit that adds it
|
> is a verified no-op (`PATCHES_APPLIED=0`). When a real patch is needed, the
|
||||||
> MUST also add the two scripts and the `series` file (see rules below).
|
> commit that adds it MUST also extend the series file and the rules below.
|
||||||
|
|
||||||
## The mechanism (how the set is meant to work)
|
## The mechanism (how the set is meant to work)
|
||||||
|
|
||||||
|
|||||||
@@ -21,11 +21,11 @@ Portanto, `patches/kernel/` não contém nenhum `000N-*.patch` hoje, e aplicar
|
|||||||
o conjunto (vazio) é um no-op.
|
o conjunto (vazio) é um no-op.
|
||||||
|
|
||||||
> Nota honesta: o install.md e o design mencionam `scripts/apply-patches.sh`,
|
> Nota honesta: o install.md e o design mencionam `scripts/apply-patches.sh`,
|
||||||
> `scripts/unpatch.sh` e `patches/kernel/series`. Esses helpers **ainda não
|
> Nota honesta: `scripts/apply-patches.sh`, `scripts/unpatch.sh` e
|
||||||
> estão na árvore**; até entrarem, "aplicar o conjunto de patches" é, por
|
> `patches/kernel/series` **estão na árvore**. O `series` é vazio por projeto,
|
||||||
> definição, nada a fazer. Quando um patch real for necessário, o primeiro
|
> então aplicá-lo é um no-op verificado (`PATCHES_APPLIED=0`). Quando um patch
|
||||||
> commit que o adicionar DEVE também adicionar os dois scripts e o arquivo
|
> real for necessário, o commit que o adiciona também atualiza o `series` e
|
||||||
> `series` (ver as regras abaixo).
|
> as regras abaixo.
|
||||||
|
|
||||||
## O mecanismo (como o conjunto deve funcionar)
|
## O mecanismo (como o conjunto deve funcionar)
|
||||||
|
|
||||||
|
|||||||
Executable
+66
@@ -0,0 +1,66 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# M4 gate: route-to pools - round-robin vs source-hash (pf_lb).
|
||||||
|
#
|
||||||
|
# Two gateways live on two different firewall links:
|
||||||
|
# 10.0.3.2 via $IF_GW (gw2's 10.0.3 side)
|
||||||
|
# 10.0.2.2 via $IF_SRV (gw2's 10.0.2 side)
|
||||||
|
# Each ping is a separate flow (own state), so the pool choice is made per
|
||||||
|
# flow: round-robin must spread the flows over both links, source-hash must
|
||||||
|
# keep them on one (same source address -> same bucket).
|
||||||
|
set -uo pipefail; cd "$(dirname "$0")"; . ./lib.sh
|
||||||
|
|
||||||
|
GW1=$GW2_IP # 10.0.3.2
|
||||||
|
GW2=10.0.2.2
|
||||||
|
|
||||||
|
pf0 'insmod /opt/pf/pf.ko 2>/dev/null || insmod /tmp/pf.ko; true'
|
||||||
|
pf0 '/opt/pf/pfctl -e; /opt/pf/pfctl -f /dev/null' >/dev/null
|
||||||
|
|
||||||
|
IF_GW=$(pf0 "ip route get $GW1 | grep -o 'dev [a-z0-9]*' | cut -d' ' -f2")
|
||||||
|
IF_SRV=$(pf0 "ip route get $SRV_IP | grep -o 'dev [a-z0-9]*' | cut -d' ' -f2")
|
||||||
|
[ -n "$IF_GW" ] && [ -n "$IF_SRV" ] || { bad "interface resolution"; finish; }
|
||||||
|
[ "$IF_GW" != "$IF_SRV" ] || { bad "the two gateways share a link"; finish; }
|
||||||
|
ok "pool links: $IF_GW ($GW1) and $IF_SRV ($GW2)"
|
||||||
|
|
||||||
|
count_on() { # count echo requests captured on an interface
|
||||||
|
local n
|
||||||
|
n=$(pf0 "grep -c '$CLI_IP > $SRV_IP' /tmp/pool_$1.td 2>/dev/null; true" | tr -dc '0-9')
|
||||||
|
[ -n "$n" ] || n=0
|
||||||
|
printf '%s' "$n"
|
||||||
|
}
|
||||||
|
|
||||||
|
run_flows() { # $1 = ruleset file, four separate ICMP flows
|
||||||
|
pf0 "pkill tcpdump; (tcpdump -ni $IF_GW -c 8 -e icmp > /tmp/pool_gw.td 2>&1 &); (tcpdump -ni $IF_SRV -c 8 -e icmp > /tmp/pool_srv.td 2>&1 &); sleep 1" >/dev/null
|
||||||
|
cli "for i in 1 2 3 4; do ping -c1 -W2 $SRV_IP >/dev/null 2>&1; done"
|
||||||
|
sleep 2
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- round-robin: the flows must spread over both links ---
|
||||||
|
cat > /tmp/g10a.conf <<C
|
||||||
|
pass in quick proto icmp from $CLI_IP to $SRV_IP route-to { $GW1, $GW2 } round-robin keep state
|
||||||
|
pass out quick keep state
|
||||||
|
C
|
||||||
|
pfload /tmp/g10a.conf || { bad "rr rule load"; finish; }
|
||||||
|
run_flows
|
||||||
|
A=$(count_on gw); B=$(count_on srv)
|
||||||
|
if [ "$A" -gt 0 ] && [ "$B" -gt 0 ]; then
|
||||||
|
ok "round-robin spread the flows ($A on $IF_GW, $B on $IF_SRV)"
|
||||||
|
else
|
||||||
|
bad "round-robin did not spread ($A on $IF_GW, $B on $IF_SRV)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- source-hash: the same source sticks to one gateway ---
|
||||||
|
cat > /tmp/g10b.conf <<C
|
||||||
|
pass in quick proto icmp from $CLI_IP to $SRV_IP route-to { $GW1, $GW2 } source-hash keep state
|
||||||
|
pass out quick keep state
|
||||||
|
C
|
||||||
|
pfload /tmp/g10b.conf || { bad "source-hash rule load"; finish; }
|
||||||
|
run_flows
|
||||||
|
A=$(count_on gw); B=$(count_on srv)
|
||||||
|
if [ "$((A + B))" -ge 3 ] && { [ "$A" -eq 0 ] || [ "$B" -eq 0 ]; }; then
|
||||||
|
ok "source-hash pinned the flows to one link ($A/$B)"
|
||||||
|
else
|
||||||
|
bad "source-hash spread the flows ($A on $IF_GW, $B on $IF_SRV)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
pf0 'pkill tcpdump; /opt/pf/pfctl -d' >/dev/null
|
||||||
|
finish
|
||||||
Reference in new issue
Block a user