github.com/cilium/ebpf@v0.16.0/link/netfilter.go (about)

     1  package link
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/cilium/ebpf"
     7  	"github.com/cilium/ebpf/internal/sys"
     8  )
     9  
    10  const NetfilterIPDefrag NetfilterAttachFlags = 0 // Enable IP packet defragmentation
    11  
    12  type NetfilterAttachFlags uint32
    13  
    14  type NetfilterOptions struct {
    15  	// Program must be a netfilter BPF program.
    16  	Program *ebpf.Program
    17  	// The protocol family.
    18  	ProtocolFamily uint32
    19  	// The number of the hook you are interested in.
    20  	HookNumber uint32
    21  	// Priority within hook
    22  	Priority int32
    23  	// Extra link flags
    24  	Flags uint32
    25  	// Netfilter flags
    26  	NetfilterFlags NetfilterAttachFlags
    27  }
    28  
    29  type netfilterLink struct {
    30  	RawLink
    31  }
    32  
    33  // AttachNetfilter links a netfilter BPF program to a netfilter hook.
    34  func AttachNetfilter(opts NetfilterOptions) (Link, error) {
    35  	if opts.Program == nil {
    36  		return nil, fmt.Errorf("netfilter program is nil")
    37  	}
    38  
    39  	if t := opts.Program.Type(); t != ebpf.Netfilter {
    40  		return nil, fmt.Errorf("invalid program type %s, expected netfilter", t)
    41  	}
    42  
    43  	progFd := opts.Program.FD()
    44  	if progFd < 0 {
    45  		return nil, fmt.Errorf("invalid program: %s", sys.ErrClosedFd)
    46  	}
    47  
    48  	attr := sys.LinkCreateNetfilterAttr{
    49  		ProgFd:         uint32(opts.Program.FD()),
    50  		AttachType:     sys.BPF_NETFILTER,
    51  		Flags:          opts.Flags,
    52  		Pf:             uint32(opts.ProtocolFamily),
    53  		Hooknum:        uint32(opts.HookNumber),
    54  		Priority:       opts.Priority,
    55  		NetfilterFlags: uint32(opts.NetfilterFlags),
    56  	}
    57  
    58  	fd, err := sys.LinkCreateNetfilter(&attr)
    59  	if err != nil {
    60  		return nil, fmt.Errorf("attach netfilter link: %w", err)
    61  	}
    62  
    63  	return &netfilterLink{RawLink{fd, ""}}, nil
    64  }
    65  
    66  func (*netfilterLink) Update(new *ebpf.Program) error {
    67  	return fmt.Errorf("netfilter update: %w", ErrNotSupported)
    68  }
    69  
    70  func (nf *netfilterLink) Info() (*Info, error) {
    71  	var info sys.NetfilterLinkInfo
    72  	if err := sys.ObjInfo(nf.fd, &info); err != nil {
    73  		return nil, fmt.Errorf("netfilter link info: %s", err)
    74  	}
    75  	extra := &NetfilterInfo{
    76  		Pf:       info.Pf,
    77  		Hooknum:  info.Hooknum,
    78  		Priority: info.Priority,
    79  		Flags:    info.Flags,
    80  	}
    81  
    82  	return &Info{
    83  		info.Type,
    84  		info.Id,
    85  		ebpf.ProgramID(info.ProgId),
    86  		extra,
    87  	}, nil
    88  }
    89  
    90  var _ Link = (*netfilterLink)(nil)