github.com/cilium/cilium@v1.16.2/pkg/hubble/parser/debug/parser.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Hubble 3 4 package debug 5 6 import ( 7 "fmt" 8 9 "github.com/sirupsen/logrus" 10 "google.golang.org/protobuf/types/known/wrapperspb" 11 12 flowpb "github.com/cilium/cilium/api/v1/flow" 13 "github.com/cilium/cilium/pkg/hubble/parser/errors" 14 "github.com/cilium/cilium/pkg/hubble/parser/getters" 15 "github.com/cilium/cilium/pkg/monitor" 16 "github.com/cilium/cilium/pkg/monitor/api" 17 ) 18 19 // Parser is a parser for debug payloads 20 type Parser struct { 21 log logrus.FieldLogger 22 endpointGetter getters.EndpointGetter 23 linkMonitor getters.LinkGetter 24 } 25 26 // New creates a new parser 27 func New(log logrus.FieldLogger, endpointGetter getters.EndpointGetter) (*Parser, error) { 28 return &Parser{ 29 log: log, 30 endpointGetter: endpointGetter, 31 }, nil 32 } 33 34 // Decode takes the a debug event payload obtained from the perf event ring 35 // buffer and decodes it 36 func (p *Parser) Decode(data []byte, cpu int) (*flowpb.DebugEvent, error) { 37 if len(data) == 0 { 38 return nil, errors.ErrEmptyData 39 } 40 41 eventType := data[0] 42 if eventType != api.MessageTypeDebug { 43 return nil, errors.NewErrInvalidType(eventType) 44 } 45 46 dbg := &monitor.DebugMsg{} 47 if err := monitor.DecodeDebugMsg(data, dbg); err != nil { 48 return nil, fmt.Errorf("failed to parse debug event: %w", err) 49 } 50 51 decoded := &flowpb.DebugEvent{ 52 Type: flowpb.DebugEventType(dbg.SubType), 53 Source: p.decodeEndpoint(dbg.Source), 54 Hash: wrapperspb.UInt32(dbg.Hash), 55 Arg1: wrapperspb.UInt32(dbg.Arg1), 56 Arg2: wrapperspb.UInt32(dbg.Arg2), 57 Arg3: wrapperspb.UInt32(dbg.Arg3), 58 Cpu: wrapperspb.Int32(int32(cpu)), 59 Message: dbg.Message(p.linkMonitor), 60 } 61 62 return decoded, nil 63 } 64 65 func (p *Parser) decodeEndpoint(id uint16) *flowpb.Endpoint { 66 if id == 0 { 67 return nil 68 } 69 70 epId := uint32(id) 71 if p.endpointGetter != nil { 72 if ep, ok := p.endpointGetter.GetEndpointInfoByID(id); ok { 73 return &flowpb.Endpoint{ 74 ID: epId, 75 Identity: uint32(ep.GetIdentity()), 76 Namespace: ep.GetK8sNamespace(), 77 Labels: ep.GetLabels(), 78 PodName: ep.GetK8sPodName(), 79 } 80 } 81 } 82 83 return &flowpb.Endpoint{ 84 ID: epId, 85 } 86 }