You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
lnvps_fw_service (the XDP/eBPF DDoS daemon) exposes GET /api/v1/events?since=<cursor> from a bounded in-memory ring buffer — it holds no database by design (docs/agents/fw-api.md; work/ddos-protection.md Increment 7). lnvps_api was always meant to be the poller and source of truth; that half was explicitly deferred out of Increment 7: "the database schema for rules/incident logs, the rules-push client, the event-poll-and-persist loop, and the admin API/UI that reads them." Nothing on the lnvps_api side exists yet — checked lnvps_db/lnvps_api_admin for fw_host/FwHost/ProtectedHost, none found.
What's already there to build on
Event (lnvps_fw_service/src/api.rs:156-166): seq (u64, per-daemon monotonic cursor — not globally unique once there's more than one router, pair it with the layer's own id), kind (EventKind::{Start,Flags,Stop}), cidr (String — see below), flags (protection bitmask), ts_unix, pps/bps/syn_pps.
ip_assignment (lnvps_db) already maps IP → VM. An event's cidr is not always a single IP: CIDR escalation (Increment 5) and prefix-level carpet-bomb detection can mitigate a /24, /64, or a whole protected prefix — resolve by CIDR-contains against ip_assignment, not exact match, and expect zero-to-many VMs per event.
lnvps_api_admin/src/admin/hosts.rs (admin_list_hosts/admin_get_host/admin_create_host/admin_update_host + a disk sub-resource) is the existing pattern for a hardware-registry CRUD — the shape to follow for a new protection-layer registry, not a new convention.
Protection-layer registry (admin CRUD, pattern per hosts.rs): each lnvps_fw_service instance (a router/host running it) registered with its API URL, bearer token, and which IP range(s) it protects.
Poller: lnvps_api polls /api/v1/events?since=<cursor> per registered layer, persists into a new table keyed by at minimum (layer_id, seq) — not seq alone, it collides across layers — plus kind, cidr, ts_unix, flags, rates.
Customer API: surface events for a customer's own VM(s), resolved via ip_assignment against the event's cidr.
Poll interval, and how a layer's token/URL gets paired with its self-signed cert (fw-api.md: "lnvps_api pins/accepts the self-signed cert over the private management link"). This is epic-sized — work/ddos-protection.md already tracks the fw_service side in numbered increments with its own "commit direct, no PR per increment" workflow; a companion work file for this side fits this org's own XL task-sizing rule better than one PR.
Problem
lnvps_fw_service(the XDP/eBPF DDoS daemon) exposesGET /api/v1/events?since=<cursor>from a bounded in-memory ring buffer — it holds no database by design (docs/agents/fw-api.md;work/ddos-protection.mdIncrement 7).lnvps_apiwas always meant to be the poller and source of truth; that half was explicitly deferred out of Increment 7: "the database schema for rules/incident logs, the rules-push client, the event-poll-and-persist loop, and the admin API/UI that reads them." Nothing on thelnvps_apiside exists yet — checkedlnvps_db/lnvps_api_adminforfw_host/FwHost/ProtectedHost, none found.What's already there to build on
Event(lnvps_fw_service/src/api.rs:156-166):seq(u64, per-daemon monotonic cursor — not globally unique once there's more than one router, pair it with the layer's own id),kind(EventKind::{Start,Flags,Stop}),cidr(String — see below),flags(protection bitmask),ts_unix,pps/bps/syn_pps.ip_assignment(lnvps_db) already maps IP → VM. An event'scidris not always a single IP: CIDR escalation (Increment 5) and prefix-level carpet-bomb detection can mitigate a /24, /64, or a whole protected prefix — resolve by CIDR-contains againstip_assignment, not exact match, and expect zero-to-many VMs per event.lnvps_api_admin/src/admin/hosts.rs(admin_list_hosts/admin_get_host/admin_create_host/admin_update_host+ a disk sub-resource) is the existing pattern for a hardware-registry CRUD — the shape to follow for a new protection-layer registry, not a new convention.WorkJob::SendAdminNotificationalready exists and is used elsewhere in the worker (per Refused (over-ceiling) referral payouts are only visible in the log #327) — reuse it for the alerting ask.Wanted
hosts.rs): eachlnvps_fw_serviceinstance (a router/host running it) registered with its API URL, bearer token, and which IP range(s) it protects.lnvps_apipolls/api/v1/events?since=<cursor>per registered layer, persists into a new table keyed by at minimum(layer_id, seq)— notseqalone, it collides across layers — pluskind,cidr,ts_unix,flags, rates.ip_assignmentagainst the event'scidr.Start), fireWorkJob::SendAdminNotification— dedupe on the transition into the state, not every poll, same requirement as Refused (over-ceiling) referral payouts are only visible in the log #327.Not settled here
Poll interval, and how a layer's token/URL gets paired with its self-signed cert (
fw-api.md: "lnvps_apipins/accepts the self-signed cert over the private management link"). This is epic-sized —work/ddos-protection.mdalready tracks the fw_service side in numbered increments with its own "commit direct, no PR per increment" workflow; a companion work file for this side fits this org's own XL task-sizing rule better than one PR.-- PM: Alejandra