diff --git a/internal/ebpf/attach.go b/internal/ebpf/attach.go index cda454b..712bc86 100644 --- a/internal/ebpf/attach.go +++ b/internal/ebpf/attach.go @@ -3,6 +3,7 @@ package ebpf import ( "fmt" "net" + "time" "github.com/cilium/ebpf/link" ) @@ -14,18 +15,31 @@ var ( ErrNoAttach = fmt.Errorf("not attached to the interface") ) -// Attach attaches eBPF program to the kernel. +// Attach attaches the eBPF program to the kernel with retry logic. func (e *EBPF) Attach(iface *net.Interface) error { + const maxRetries = 3 + const retryDelay = 100 * time.Millisecond + if e.L != nil { return fmt.Errorf( "%w: %s", ErrAlreadyAttached, iface.Name, ) } - l, err := link.AttachXDP(link.XDPOptions{ - Program: e.Objects.XdpDurdurFunc, - Interface: iface.Index, - }) + var l link.Link + var err error + for i := 0; i < maxRetries; i++ { + l, err = link.AttachXDP(link.XDPOptions{ + Program: e.Objects.XdpDurdurFunc, + Interface: iface.Index, + }) + if err == nil { + break + } + if i < maxRetries-1 { + time.Sleep(retryDelay) + } + } if err != nil { return fmt.Errorf("attach: %w", err) }