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 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
package link
import (
"fmt"
"github.com/cilium/ebpf"
"github.com/cilium/ebpf/internal/sys"
)
const NetfilterIPDefrag NetfilterAttachFlags = 0 // Enable IP packet defragmentation
type NetfilterAttachFlags uint32
type NetfilterOptions struct {
// Program must be a netfilter BPF program.
Program *ebpf.Program
// The protocol family.
ProtocolFamily uint32
// The number of the hook you are interested in.
HookNumber uint32
// Priority within hook
Priority int32
// Extra link flags
Flags uint32
// Netfilter flags
NetfilterFlags NetfilterAttachFlags
}
type netfilterLink struct {
RawLink
}
// AttachNetfilter links a netfilter BPF program to a netfilter hook.
func AttachNetfilter(opts NetfilterOptions) (Link, error) {
if opts.Program == nil {
return nil, fmt.Errorf("netfilter program is nil")
}
if t := opts.Program.Type(); t != ebpf.Netfilter {
return nil, fmt.Errorf("invalid program type %s, expected netfilter", t)
}
progFd := opts.Program.FD()
if progFd < 0 {
return nil, fmt.Errorf("invalid program: %s", sys.ErrClosedFd)
}
attr := sys.LinkCreateNetfilterAttr{
ProgFd: uint32(opts.Program.FD()),
AttachType: sys.BPF_NETFILTER,
Flags: opts.Flags,
Pf: uint32(opts.ProtocolFamily),
Hooknum: uint32(opts.HookNumber),
Priority: opts.Priority,
NetfilterFlags: uint32(opts.NetfilterFlags),
}
fd, err := sys.LinkCreateNetfilter(&attr)
if err != nil {
return nil, fmt.Errorf("attach netfilter link: %w", err)
}
return &netfilterLink{RawLink{fd, ""}}, nil
}
func (*netfilterLink) Update(_ *ebpf.Program) error {
return fmt.Errorf("netfilter update: %w", ErrNotSupported)
}
func (nf *netfilterLink) Info() (*Info, error) {
var info sys.NetfilterLinkInfo
if err := sys.ObjInfo(nf.fd, &info); err != nil {
return nil, fmt.Errorf("netfilter link info: %s", err)
}
extra := &NetfilterInfo{
Pf: info.Pf,
Hooknum: info.Hooknum,
Priority: info.Priority,
Flags: info.Flags,
}
return &Info{
info.Type,
info.Id,
ebpf.ProgramID(info.ProgId),
extra,
}, nil
}
var _ Link = (*netfilterLink)(nil)
|