Documentation
¶
Overview ¶
Package nft は、Plan から VPS の table inet wgft を組み立てて適用する(仕様 6.1 節、設計文書 7a.2 節)。 internal/dataplane/linuxkernel の nftables 実装で、internal/vpsd を import しない(設計文書 7a.7 節)。
Apply/emit は internal/planner.Plan と、frontend が実際に待ち受けている Relay ポートの集合 (design.md 7a.2 節の dataplane.Desired.RelayListening に当たる Runtime 側の入力)だけから組み立てる。 Plan は無効なルールとエージェントが未登録のルールを既に除いているので、ここでは検査し直さない (設計文書 7a.8 節 Phase 3:「ルール集合から nftables を組み立てる」から「Plan から組み立てる」への移行)。
nft が暗黙に足す条件(udp dport の前の meta l4proto、ip saddr の前の meta nfproto)を 自分で入れ、ポート範囲は nft と同じく gte / lte の 2 つの比較で表す。 これで生成したテーブルの `nft list` が、同じ内容を `nft -f` で流したものと一致する(実験で確認)。
Index ¶
Constants ¶
const TableName = "wgft"
TableName は vpsd 専用のテーブル名。他のテーブルには一切触れない。
Variables ¶
This section is empty.
Functions ¶
func Apply ¶
Apply はテーブル全体を 1 トランザクションで差し替える。 「空テーブルの追加 → 削除 → 定義」の順にするので、テーブルがまだない初回でも失敗しない。 conntrack のエントリは差し替えの影響を受けず、既存のセッションは切れない。 生成の途中で失敗すると未送信のメッセージが Conn に残るので、Conn は呼び出しごとに作って捨てる。
relayListening は、vpsd がプロキシモードの待ち受けを実際に開いているポート(design.md 7a.2 節の dataplane.Desired.RelayListening)。Relay のルールは、ここにあるポートだけに Admission Policy の 行を持つ。bind に失敗したポートでは、同じポートの別のプロセスへの通信に wgft の判定を掛けて しまうため(仕様 6.1 節)。nil なら行を持たない。
Apply は Stage と Flush を続けて行う。kernel backend は 2 つを Prepare と Commit に分けて呼ぶ (design.md 7a.2 節)。
func Comment ¶
Comment はルールの行に付けるコメント。差し替えのたびにハンドルは振り直されるので、 カウンタの持ち主はこのコメントで特定する。 形式は internal/policy/nftables.Comment が決める。
func DeleteTable ¶
func DeleteTable() error
DeleteTable は table inet wgft を削除する。他のテーブルには触れない。 すでに無ければ何もしない(撤去を手作業の途中からでも走らせられるように)。
func Fingerprint ¶ added in v0.5.0
Fingerprint reads table inet wgft back from the kernel and returns a digest of what wgft wrote into it (design.md 7a.3 節: 実際の状態への収束). present is false when the table does not exist.
The digest covers, per chain (by name): its type, hook and priority, and per rule its handle, its comment and its expressions; plus the elements of every set wgft fills itself (deny_N, allow_N). It leaves out what changes while forwarding without the declaration changing: counter values (set to zero before hashing) and the elements of sets packets add to (meters and flows_udp/flows_tcp, flags dynamic). A rule deleted, added or replaced, a chain or set removed, or the table recreated with other contents therefore changes the digest; traffic does not.
It is a handful of netlink dumps (tables, chains, one per chain for its rules, sets, one per static set for its elements), cheap enough to run after every Commit and on every Observe.
Types ¶
type Drop ¶
type Drop struct {
RuleID string
Kind string // deny | allow | per_source | src_flow | new_flow | packet
Packets uint64
Bytes uint64
}
Drop はルールごと・種類ごとの累積 drop 数(コメントで識別する)。
type Staged ¶ added in v0.5.0
type Staged struct {
// contains filtered or unexported fields
}
Staged は、組み立て終えてまだ送っていないテーブルの差し替え(1 トランザクション分のメッセージ)。
func Stage ¶ added in v0.5.0
Stage はテーブルの差し替えを組み立てるが、送らない(kernel backend の Prepare。design.md 7a.2 節)。 組み立ての誤りはここで返り、何も公開されない。捨てるときは何もしなくてよい(Conn は送るまで カーネルに何も書かない)。
func (*Staged) Flush ¶ added in v0.5.0
Flush は組み立てた差し替えを 1 トランザクションで送り、wgft が要素を書く set をカーネルから 読み直して、送った要素がそのまま入っているかを確かめる(kernel backend の Commit)。 カーネル側の差し替え自体は不可分である。ただし、誤りが返ったときに旧いテーブルが残っているとは 限らない。カーネルは commit の後に応答を返すので、応答の受信に失敗した場合(ENOBUFS)は、 テーブルが差し替わった後で誤りが返る。読み直した set が送った要素と一致しない場合も、差し替わった 後で誤りが返る。送信が拒まれた場合(EMSGSIZE)とカーネルがバッチを拒んだ場合は、旧いテーブルが 残る。実際の状態との食い違いは、reconciler の Observe による drift の検出で収束させる(設計文書 6.1 節、7a.3 節)。