github.com/inspektor-gadget/inspektor-gadget@v0.28.1/pkg/operators/ebpf/attach.go (about) 1 // Copyright 2024 The Inspektor Gadget authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package ebpfoperator 16 17 import ( 18 "fmt" 19 "net" 20 "strings" 21 22 "github.com/cilium/ebpf" 23 "github.com/cilium/ebpf/link" 24 25 "github.com/inspektor-gadget/inspektor-gadget/pkg/operators" 26 "github.com/inspektor-gadget/inspektor-gadget/pkg/uprobetracer" 27 ) 28 29 const ( 30 kprobePrefix = "kprobe/" 31 kretprobePrefix = "kretprobe/" 32 iterPrefix = "iter/" 33 fentryPrefix = "fentry/" 34 fexitPrefix = "fexit/" 35 uprobePrefix = "uprobe/" 36 uretprobePrefix = "uretprobe/" 37 usdtPrefix = "usdt/" 38 ) 39 40 func (i *ebpfInstance) attachProgram(gadgetCtx operators.GadgetContext, p *ebpf.ProgramSpec, prog *ebpf.Program) (link.Link, error) { 41 switch p.Type { 42 case ebpf.Kprobe: 43 switch { 44 case strings.HasPrefix(p.SectionName, kprobePrefix): 45 i.logger.Debugf("Attaching kprobe %q to %q", p.Name, p.AttachTo) 46 return link.Kprobe(p.AttachTo, prog, nil) 47 case strings.HasPrefix(p.SectionName, kretprobePrefix): 48 i.logger.Debugf("Attaching kretprobe %q to %q", p.Name, p.AttachTo) 49 return link.Kretprobe(p.AttachTo, prog, nil) 50 case strings.HasPrefix(p.SectionName, uprobePrefix) || 51 strings.HasPrefix(p.SectionName, uretprobePrefix) || 52 strings.HasPrefix(p.SectionName, usdtPrefix): 53 uprobeTracer := i.uprobeTracers[p.Name] 54 switch strings.Split(p.SectionName, "/")[0] { 55 case "uprobe": 56 return nil, uprobeTracer.AttachProg(p.Name, uprobetracer.ProgUprobe, p.AttachTo, prog) 57 case "uretprobe": 58 return nil, uprobeTracer.AttachProg(p.Name, uprobetracer.ProgUretprobe, p.AttachTo, prog) 59 case "usdt": 60 return nil, uprobeTracer.AttachProg(p.Name, uprobetracer.ProgUSDT, p.AttachTo, prog) 61 } 62 } 63 return nil, fmt.Errorf("unsupported section name %q for program %q", p.SectionName, p.Name) 64 case ebpf.TracePoint: 65 i.logger.Debugf("Attaching tracepoint %q to %q", p.Name, p.AttachTo) 66 parts := strings.Split(p.AttachTo, "/") 67 return link.Tracepoint(parts[0], parts[1], prog, nil) 68 case ebpf.SocketFilter: 69 i.logger.Debugf("Attaching socket filter %q to %q", p.Name, p.AttachTo) 70 networkTracer := i.networkTracers[p.Name] 71 return nil, networkTracer.AttachProg(prog) 72 case ebpf.Tracing: 73 switch { 74 case strings.HasPrefix(p.SectionName, iterPrefix): 75 i.logger.Debugf("Attaching iter %q to %q", p.Name, p.AttachTo) 76 switch p.AttachTo { 77 case "task", "tcp", "udp": 78 return link.AttachIter(link.IterOptions{ 79 Program: prog, 80 }) 81 } 82 return nil, fmt.Errorf("unsupported iter type %q", p.AttachTo) 83 case strings.HasPrefix(p.SectionName, fentryPrefix): 84 i.logger.Debugf("Attaching fentry %q to %q", p.Name, p.AttachTo) 85 return link.AttachTracing(link.TracingOptions{ 86 Program: prog, 87 AttachType: ebpf.AttachTraceFEntry, 88 }) 89 case strings.HasPrefix(p.SectionName, fexitPrefix): 90 i.logger.Debugf("Attaching fexit %q to %q", p.Name, p.AttachTo) 91 return link.AttachTracing(link.TracingOptions{ 92 Program: prog, 93 AttachType: ebpf.AttachTraceFExit, 94 }) 95 } 96 return nil, fmt.Errorf("unsupported section name %q for program %q as type ebpf.Tracing", p.SectionName, p.Name) 97 case ebpf.RawTracepoint: 98 i.logger.Debugf("Attaching raw tracepoint %q to %q", p.Name, p.AttachTo) 99 return link.AttachRawTracepoint(link.RawTracepointOptions{ 100 Name: p.AttachTo, 101 Program: prog, 102 }) 103 case ebpf.SchedCLS: 104 handler := i.tcHandlers[p.Name] 105 106 ifaceName := i.paramValues[ParamIface] 107 if ifaceName != "" { 108 iface, err := net.InterfaceByName(ifaceName) 109 if err != nil { 110 return nil, fmt.Errorf("getting interface %q: %w", ifaceName, err) 111 } 112 113 if err := handler.AttachIface(iface); err != nil { 114 return nil, fmt.Errorf("attaching iface %q: %w", ifaceName, err) 115 } 116 } 117 118 i.logger.Debugf("Attaching sched_cls %q", p.Name) 119 return nil, handler.AttachProg(prog) 120 case ebpf.LSM: 121 i.logger.Debugf("Attaching LSM %q to %q", p.Name, p.AttachTo) 122 return link.AttachLSM(link.LSMOptions{ 123 Program: prog, 124 }) 125 default: 126 return nil, fmt.Errorf("unsupported program %q of type %q", p.Name, p.Type) 127 } 128 }