cmd/xdpderper,derp/xdp: implement mode that drops STUN packets (#12527)

This is useful during maintenance as a method for shedding home client
load.

Updates tailscale/corp#20689

Signed-off-by: Jordan Whited <jordan@tailscale.com>
This commit is contained in:
Jordan Whited
2024-06-18 14:06:00 -07:00
committed by GitHub
parent d55b105dae
commit a93173b56a
9 changed files with 128 additions and 10 deletions

View File

@@ -22,9 +22,11 @@ import (
// the STUN protocol. It exports statistics for the XDP program via its
// implementation of the prometheus.Collector interface.
type STUNServer struct {
mu sync.Mutex
objs *bpfObjects
metrics *stunServerMetrics
mu sync.Mutex
objs *bpfObjects
metrics *stunServerMetrics
dstPort int
dropSTUN bool
}
//lint:ignore U1000 used in xdp_linux_test.go, which has a build tag
@@ -68,12 +70,13 @@ func NewSTUNServer(config *STUNServerConfig, opts ...STUNServerOption) (*STUNSer
server := &STUNServer{
objs: objs,
metrics: newSTUNServerMetrics(),
dstPort: config.DstPort,
}
var key uint32
xdpConfig := bpfConfig{
xdpConfig := &bpfConfig{
DstPort: uint16(config.DstPort),
}
err = objs.ConfigMap.Put(key, &xdpConfig)
err = objs.ConfigMap.Put(key, xdpConfig)
if err != nil {
return nil, fmt.Errorf("error loading config in eBPF map: %w", err)
}
@@ -181,6 +184,7 @@ var (
bpfCounterKeyProgEndCOUNTER_KEY_END_INVALID_IP_CSUM: "invalid_ip_csum",
bpfCounterKeyProgEndCOUNTER_KEY_END_NOT_STUN_PORT: "not_stun_port",
bpfCounterKeyProgEndCOUNTER_KEY_END_INVALID_SW_ATTR_VAL: "invalid_sw_attr_val",
bpfCounterKeyProgEndCOUNTER_KEY_END_DROP_STUN: "drop_stun",
}
packetCounterKeys = map[bpfCounterKeyPacketsBytesAction]bool{
@@ -262,6 +266,31 @@ func (s *STUNServer) Collect(metricCh chan<- prometheus.Metric) {
s.metrics.registry.Collect(metricCh)
}
func (s *STUNServer) SetDropSTUN(v bool) error {
s.mu.Lock()
defer s.mu.Unlock()
dropSTUN := 0
if v {
dropSTUN = 1
}
xdpConfig := &bpfConfig{
DstPort: uint16(s.dstPort),
DropStun: uint16(dropSTUN),
}
var key uint32
err := s.objs.ConfigMap.Put(key, xdpConfig)
if err == nil {
s.dropSTUN = v
}
return err
}
func (s *STUNServer) GetDropSTUN() bool {
s.mu.Lock()
defer s.mu.Unlock()
return s.dropSTUN
}
func (s *STUNServer) updateMetrics() error {
s.mu.Lock()
defer s.mu.Unlock()