From 114d1caf55777efae653935be88404ccdc92c2da Mon Sep 17 00:00:00 2001 From: James Tucker Date: Fri, 28 Jun 2024 14:26:55 -0700 Subject: [PATCH] derp/xdp: retain the link so that the fd is not closed BPF links require that the owning FD remains open, this FD is embedded into the RawLink returned by the attach function and must live for the duration of the server. Updates ENG-4274 Signed-off-by: James Tucker --- derp/xdp/xdp_linux.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/derp/xdp/xdp_linux.go b/derp/xdp/xdp_linux.go index aa6559842..3ebe0a052 100644 --- a/derp/xdp/xdp_linux.go +++ b/derp/xdp/xdp_linux.go @@ -14,6 +14,7 @@ import ( "github.com/cilium/ebpf" "github.com/cilium/ebpf/link" "github.com/prometheus/client_golang/prometheus" + "tailscale.com/util/multierr" ) //go:generate go run github.com/cilium/ebpf/cmd/bpf2go -type config -type counters_key -type counter_key_af -type counter_key_packets_bytes_action -type counter_key_prog_end bpf xdp.c -- -I headers @@ -27,6 +28,7 @@ type STUNServer struct { metrics *stunServerMetrics dstPort int dropSTUN bool + link link.Link } //lint:ignore U1000 used in xdp_linux_test.go, which has a build tag @@ -87,7 +89,7 @@ func NewSTUNServer(config *STUNServerConfig, opts ...STUNServerOption) (*STUNSer if err != nil { return nil, fmt.Errorf("error finding device: %w", err) } - _, err = link.AttachXDP(link.XDPOptions{ + link, err := link.AttachXDP(link.XDPOptions{ Program: objs.XdpProgFunc, Interface: iface.Index, Flags: link.XDPAttachFlags(config.AttachFlags), @@ -95,6 +97,7 @@ func NewSTUNServer(config *STUNServerConfig, opts ...STUNServerOption) (*STUNSer if err != nil { return nil, fmt.Errorf("error attaching XDP program to dev: %w", err) } + server.link = link return server, nil } @@ -102,7 +105,12 @@ func NewSTUNServer(config *STUNServerConfig, opts ...STUNServerOption) (*STUNSer func (s *STUNServer) Close() error { s.mu.Lock() defer s.mu.Unlock() - return s.objs.Close() + var errs []error + if s.link != nil { + errs = append(errs, s.link.Close()) + } + errs = append(errs, s.objs.Close()) + return multierr.New(errs...) } type stunServerMetrics struct {