Hidden interfaces, last-seen pings, activity by subnet

- interfaces.exclude in steward.yaml (names or shell patterns) leaves
  interfaces out of GET /interfaces, the web UI's picker and
  'steward interface list'. Subnets on them are still served.
- With the ping check on, active leases are pinged every minute; a
  client that answers gets a last-seen time (leases.last_seen,
  migration 4). Not answering never takes a client offline.
- The activity log filters by subnet (--subnet, the Activity page,
  GET /events?subnet=).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
abrown38andClaude Opus 5.5 committed 2026-10-18 17:50:21 +01:00
1 parent 6ad1bb9a0d
commit 5e6c61cc8e
31 files changed
+358 -39

No files matched your search

+2 -2
View File
@@ -31,7 +31,7 @@ func (p *ICMPPinger) Ping(ctx context.Context, a netip.Addr, timeout time.Durati
conn, err := icmp.ListenPacket("udp4", "0.0.0.0")
if err != nil {
p.once.Do(func() {
msg := "can't send pings, so addresses aren't checked before they are offered: " + err.Error() + " (check net.ipv4.ping_group_range)"
msg := "can't send pings, so addresses aren't checked before they are offered and clients' last-seen times aren't known: " + err.Error() + " (check net.ipv4.ping_group_range)"
p.Unavailable.Store(msg)
if p.Log != nil {
p.Log.Warn(msg)
@@ -41,7 +41,7 @@ func (p *ICMPPinger) Ping(ctx context.Context, a netip.Addr, timeout time.Durati
}
defer conn.Close()
seq := int(p.seq.Add(1) & 0xffff)
msg := icmp.Message{Type: ipv4.ICMPTypeEcho, Body: &icmp.Echo{ID: os.Getpid() & 0xffff, Seq: seq, Data: []byte("steward conflict check")}}
msg := icmp.Message{Type: ipv4.ICMPTypeEcho, Body: &icmp.Echo{ID: os.Getpid() & 0xffff, Seq: seq, Data: []byte("steward")}}
b, err := msg.Marshal(nil)
if err != nil {
return false