forked from DataDog/ebpf-manager
-
Notifications
You must be signed in to change notification settings - Fork 0
/
xdp.go
74 lines (64 loc) · 2.02 KB
/
xdp.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package manager
import (
"errors"
"fmt"
"io"
"github.com/cilium/ebpf/link"
"github.com/vishvananda/netlink"
)
// XdpAttachMode selects a way how XDP program will be attached to interface
type XdpAttachMode int
const (
// XdpAttachModeNone stands for "best effort" - the kernel automatically
// selects the best mode (would try Drv first, then fallback to Generic).
// NOTE: Kernel will not fall back to Generic XDP if NIC driver failed
// to install XDP program.
XdpAttachModeNone XdpAttachMode = 0
// XdpAttachModeSkb is "generic", kernel mode, less performant comparing to native,
// but does not requires driver support.
XdpAttachModeSkb XdpAttachMode = 1 << 1
// XdpAttachModeDrv is native, driver mode (support from driver side required)
XdpAttachModeDrv XdpAttachMode = 1 << 2
// XdpAttachModeHw suitable for NICs with hardware XDP support
XdpAttachModeHw XdpAttachMode = 1 << 3
)
var _ io.Closer = (*netlinkXDPLink)(nil)
type netlinkXDPLink struct {
link netlink.Link
ifIndex int
mode int
}
func (l *netlinkXDPLink) Close() error {
err := netlink.LinkSetXdpFdWithFlags(l.link, -1, l.mode)
if err != nil {
return fmt.Errorf("detach XDP program from interface %d: %w", l.ifIndex, err)
}
return nil
}
// attachXDP - Attaches the probe to an interface with an XDP hook point
func (p *Probe) attachXDP() error {
var err error
if _, err = p.resolveLink(); err != nil {
return err
}
p.progLink, err = link.AttachXDP(link.XDPOptions{
Program: p.program,
Interface: p.IfIndex,
Flags: link.XDPAttachFlags(p.XDPAttachMode),
})
if err != nil {
if !errors.Is(err, link.ErrNotSupported) {
return fmt.Errorf("link xdp to interface %v: %w", p.IfIndex, err)
}
err = netlink.LinkSetXdpFdWithFlags(p.link, p.program.FD(), int(p.XDPAttachMode))
if err != nil {
return fmt.Errorf("attach XDP program %v to interface %v: %w", p.ProbeIdentificationPair, p.IfIndex, err)
}
p.progLink = &netlinkXDPLink{
link: p.link,
ifIndex: p.IfIndex,
mode: int(p.XDPAttachMode),
}
}
return nil
}