github.com/cilium/ebpf@v0.15.1-0.20240517100537-8079b37aa138/link/raw_tracepoint.go (about)

     1  package link
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  
     7  	"github.com/cilium/ebpf"
     8  	"github.com/cilium/ebpf/internal/sys"
     9  )
    10  
    11  type RawTracepointOptions struct {
    12  	// Tracepoint name.
    13  	Name string
    14  	// Program must be of type RawTracepoint*
    15  	Program *ebpf.Program
    16  }
    17  
    18  // AttachRawTracepoint links a BPF program to a raw_tracepoint.
    19  //
    20  // Requires at least Linux 4.17.
    21  func AttachRawTracepoint(opts RawTracepointOptions) (Link, error) {
    22  	if t := opts.Program.Type(); t != ebpf.RawTracepoint && t != ebpf.RawTracepointWritable {
    23  		return nil, fmt.Errorf("invalid program type %s, expected RawTracepoint(Writable)", t)
    24  	}
    25  	if opts.Program.FD() < 0 {
    26  		return nil, fmt.Errorf("invalid program: %w", sys.ErrClosedFd)
    27  	}
    28  
    29  	fd, err := sys.RawTracepointOpen(&sys.RawTracepointOpenAttr{
    30  		Name:   sys.NewStringPointer(opts.Name),
    31  		ProgFd: uint32(opts.Program.FD()),
    32  	})
    33  	if err != nil {
    34  		return nil, err
    35  	}
    36  
    37  	err = haveBPFLink()
    38  	if errors.Is(err, ErrNotSupported) {
    39  		// Prior to commit 70ed506c3bbc ("bpf: Introduce pinnable bpf_link abstraction")
    40  		// raw_tracepoints are just a plain fd.
    41  		return &simpleRawTracepoint{fd}, nil
    42  	}
    43  
    44  	if err != nil {
    45  		return nil, err
    46  	}
    47  
    48  	return &rawTracepoint{RawLink{fd: fd}}, nil
    49  }
    50  
    51  type simpleRawTracepoint struct {
    52  	fd *sys.FD
    53  }
    54  
    55  var _ Link = (*simpleRawTracepoint)(nil)
    56  
    57  func (frt *simpleRawTracepoint) isLink() {}
    58  
    59  func (frt *simpleRawTracepoint) Close() error {
    60  	return frt.fd.Close()
    61  }
    62  
    63  func (frt *simpleRawTracepoint) Update(_ *ebpf.Program) error {
    64  	return fmt.Errorf("update raw_tracepoint: %w", ErrNotSupported)
    65  }
    66  
    67  func (frt *simpleRawTracepoint) Pin(string) error {
    68  	return fmt.Errorf("pin raw_tracepoint: %w", ErrNotSupported)
    69  }
    70  
    71  func (frt *simpleRawTracepoint) Unpin() error {
    72  	return fmt.Errorf("unpin raw_tracepoint: %w", ErrNotSupported)
    73  }
    74  
    75  func (frt *simpleRawTracepoint) Info() (*Info, error) {
    76  	return nil, fmt.Errorf("can't get raw_tracepoint info: %w", ErrNotSupported)
    77  }
    78  
    79  type rawTracepoint struct {
    80  	RawLink
    81  }
    82  
    83  var _ Link = (*rawTracepoint)(nil)
    84  
    85  func (rt *rawTracepoint) Update(_ *ebpf.Program) error {
    86  	return fmt.Errorf("update raw_tracepoint: %w", ErrNotSupported)
    87  }