github.com/inspektor-gadget/inspektor-gadget@v0.28.1/pkg/operators/socketenricher/socketenricher.go (about) 1 // Copyright 2023-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 socketenricher creates an eBPF map exposing processes owning each socket. 16 // 17 // This makes it possible for network gadgets to access that information and display it directly 18 // from the BPF code. Example of such code in the dns and sni gadgets. 19 package socketenricher 20 21 import ( 22 "fmt" 23 "sync" 24 25 "github.com/cilium/ebpf" 26 log "github.com/sirupsen/logrus" 27 28 "github.com/inspektor-gadget/inspektor-gadget/pkg/gadget-service/api" 29 "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets" 30 "github.com/inspektor-gadget/inspektor-gadget/pkg/operators" 31 "github.com/inspektor-gadget/inspektor-gadget/pkg/params" 32 tracer "github.com/inspektor-gadget/inspektor-gadget/pkg/socketenricher" 33 ) 34 35 const ( 36 OperatorName = "SocketEnricher" 37 ) 38 39 type SocketEnricherInterface interface { 40 SetSocketEnricherMap(*ebpf.Map) 41 } 42 43 type SocketEnricher struct { 44 mu sync.Mutex 45 socketEnricher *tracer.SocketEnricher 46 refCount int 47 } 48 49 func (s *SocketEnricher) Name() string { 50 return OperatorName 51 } 52 53 func (s *SocketEnricher) Description() string { 54 return "Socket enricher provides process information for sockets" 55 } 56 57 func (s *SocketEnricher) GlobalParamDescs() params.ParamDescs { 58 return nil 59 } 60 61 func (s *SocketEnricher) ParamDescs() params.ParamDescs { 62 return nil 63 } 64 65 func (s *SocketEnricher) Dependencies() []string { 66 return nil 67 } 68 69 func (s *SocketEnricher) CanOperateOn(gadget gadgets.GadgetDesc) bool { 70 gi, ok := gadget.(gadgets.GadgetInstantiate) 71 if !ok { 72 return false 73 } 74 75 instance, err := gi.NewInstance() 76 if err != nil { 77 log.Warnf("failed to create dummy %s instance: %s", OperatorName, err) 78 return false 79 } 80 81 _, hasSocketEnricherInterface := instance.(SocketEnricherInterface) 82 return hasSocketEnricherInterface 83 } 84 85 func (s *SocketEnricher) Init(params *params.Params) error { 86 return nil 87 } 88 89 func (s *SocketEnricher) Close() error { 90 s.mu.Lock() 91 defer s.mu.Unlock() 92 93 if s.socketEnricher != nil { 94 s.socketEnricher.Close() 95 s.socketEnricher = nil 96 } 97 return nil 98 } 99 100 func (s *SocketEnricher) Instantiate(gadgetCtx operators.GadgetContext, gadgetInstance any, params *params.Params) (operators.OperatorInstance, error) { 101 return &SocketEnricherInstance{ 102 gadgetCtx: gadgetCtx, 103 manager: s, 104 gadgetInstance: gadgetInstance, 105 }, nil 106 } 107 108 type SocketEnricherInstance struct { 109 gadgetCtx operators.GadgetContext 110 manager *SocketEnricher 111 gadgetInstance any 112 } 113 114 func (i *SocketEnricherInstance) Name() string { 115 return "SocketEnricherInstance" 116 } 117 118 func (i *SocketEnricherInstance) PreGadgetRun() error { 119 setter, ok := i.gadgetInstance.(SocketEnricherInterface) 120 if !ok { 121 return fmt.Errorf("gadget doesn't implement socket enricher interface") 122 } 123 124 i.manager.mu.Lock() 125 defer i.manager.mu.Unlock() 126 127 if i.manager.refCount == 0 { 128 t, err := tracer.NewSocketEnricher() 129 if err != nil { 130 return err 131 } 132 i.manager.socketEnricher = t 133 } 134 135 i.manager.refCount++ 136 137 setter.SetSocketEnricherMap(i.manager.socketEnricher.SocketsMap()) 138 139 return nil 140 } 141 142 func (i *SocketEnricherInstance) PostGadgetRun() error { 143 i.manager.mu.Lock() 144 defer i.manager.mu.Unlock() 145 146 i.manager.refCount-- 147 if i.manager.refCount == 0 { 148 i.manager.socketEnricher.Close() 149 i.manager.socketEnricher = nil 150 } 151 152 return nil 153 } 154 155 func (i *SocketEnricherInstance) EnrichEvent(ev any) error { 156 return nil 157 } 158 159 func (s *SocketEnricher) GlobalParams() api.Params { 160 return nil 161 } 162 163 func (s *SocketEnricher) InstanceParams() api.Params { 164 return nil 165 } 166 167 func (s *SocketEnricher) InstantiateDataOperator(gadgetCtx operators.GadgetContext, instanceParamValues api.ParamValues) (operators.DataOperatorInstance, error) { 168 if _, ok := gadgetCtx.GetVar(tracer.SocketsMapName); !ok { 169 return nil, nil 170 } 171 172 instance := &SocketEnricherInstance{ 173 gadgetCtx: gadgetCtx, 174 manager: s, 175 } 176 instance.gadgetInstance = instance 177 return instance, nil 178 } 179 180 func (s *SocketEnricher) Priority() int { 181 return 10 182 } 183 184 func (i *SocketEnricherInstance) PreStart(gadgetCtx operators.GadgetContext) error { 185 return i.PreGadgetRun() 186 } 187 188 func (i *SocketEnricherInstance) Start(gadgetCtx operators.GadgetContext) error { 189 return nil 190 } 191 192 func (i *SocketEnricherInstance) Stop(gadgetCtx operators.GadgetContext) error { 193 return i.PostGadgetRun() 194 } 195 196 func (i *SocketEnricherInstance) SetSocketEnricherMap(m *ebpf.Map) { 197 i.gadgetCtx.Logger().Debugf("setting sockets map") 198 i.gadgetCtx.SetVar(tracer.SocketsMapName, m) 199 } 200 201 func init() { 202 op := &SocketEnricher{} 203 operators.Register(op) 204 operators.RegisterDataOperator(op) 205 }