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  }