skbtrace

package module
v0.0.0-...-a7d6218 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 8, 2024 License: MIT Imports: 17 Imported by: 0

README

skbtrace is a helper tool for generating and running BPFTrace scripts which trace and measure timings related to Linux Networking Stack, specifically SocKet Buffer contents (hence the name).

It can be used to:

  • find TCP retransmits even in encapsulated packets;
  • roughly measure packet forwarding times;
  • simple tcpdump replacement which allows to trace some kernel routines which are not accessible by tcpdump.

An example of such routine is kfree_skb which is called when kernel frees (drops) packet.

Go Reference

Usage

For the usage examples see Usage

For full documentation see skbtrace(1)

Building

go get -u github.com/yandex-cloud/skbtrace
go build -o skbtrace 

or

git clone github.com/yandex-cloud/skbtrace
make build

Requirements

skbtrace is tested with Linux Kernel 4.14 and BPFTrace 0.9.2.

Extending

skbtrace can be extended by:

  • Adding extra shortcut commands and root command child while using one of the visitors such as DumpTracerCommand.
  • Extending builder with additional protocols, field and probe descriptions in SetUp() method of cli dependencies structure.
  • Or by simply contributing a patch (see Contributing).

License

See License

Documentation

Index

Constants

View Source
const (
	ErrMsgNotFound     = "not found"
	ErrMsgParseError   = "parse error"
	ErrMsgNotSpecified = "instance name is not specified"
)
View Source
const (
	// Use converters when dumping value or as a key in printed map,
	// default if no mask is specified
	ConverterDump uint = 1 << iota

	// Use converters when generating key in non-printable map
	ConverterHiddenKey

	// Use converter in filters. Not recommended, instead filter
	// preprocessor should process user-supplied constant
	ConverterFilter

	// Use Converter as argument to argument to aggregation function
	// For now it uses same converter as prettifier to apply ntohs
	// conversion (it is absurd to require aggregation on really
	// pretty fields like IP address)
	ConverterAggregateArg = ConverterDump
)
View Source
const (
	TUSecond      = "sec"
	TUMillisecond = "ms"
	TUMicrosecond = "us"
	TUNanosecond  = "ns"
)

Variables

View Source
var AggrFuncList = []AggrFunc{AFCount, AFSum, AFAvg, AFMin, AFMax, AFHist}
View Source
var FeatureBSwapFunction = &Feature{
	Component: FeatureComponentBPFTrace,
	Name:      "bswap",
	Help:      "Allows to use bswap in byte-swapping operations",

	Commit:     "1972e897da6ecb060a6e114e25dd1577e41dee47",
	MinVersion: Version{Major: 0, Submajor: 15, Minor: 0},
}
View Source
var FeatureBuiltinTypes = &Feature{
	Component: FeatureComponentBPFTrace,
	Name:      "builtin_type",
	Help:      "Allows to use builtin type conversions",

	Commit:     "5dd033c7c76dbe2557a64c204b336e65712c1ce8",
	MinVersion: Version{Major: 0, Submajor: 17, Minor: 0},
}
View Source
var FeatureStructKeyword = &Feature{
	Component:  FeatureComponentBPFTrace,
	Name:       "struct",
	Help:       "Enforces usage of struct keyword in cast expressions",
	MinVersion: Version{Major: 0, Submajor: 9, Minor: 4},
}
View Source
var HostEndian = binary.LittleEndian
View Source
var NilExpr = Expr("")

Empty expression used as default value in conjuction with error

Functions

func FppNtohs

func FppNtohs(op, value string) (string, error)

Field preprocessor for ntohs values

func NewArrayConvFmtSpec

func NewArrayConvFmtSpec(size int, fmtkey string) string

func RegisterFeatures

func RegisterFeatures(features ...*Feature)

func Run

func Run(w io.Writer, prog *Program, opt RunnerOptions) error

Types

type AggrFunc

type AggrFunc string
const (
	AFCount AggrFunc = "count"
	AFSum   AggrFunc = "sum"
	AFAvg   AggrFunc = "avg"
	AFMin   AggrFunc = "min"
	AFMax   AggrFunc = "max"
	AFHist  AggrFunc = "hist"
)

type AggregateCommonOptions

type AggregateCommonOptions struct {
	// Interval of aggregation map dumping
	Interval time.Duration

	// Truncate defines number of entries that should be printed when printing
	// the aggregation if set to positive value
	Truncate int
}

type BPFTraceVersionProvider

type BPFTraceVersionProvider struct{}

func (BPFTraceVersionProvider) Get

func (BPFTraceVersionProvider) Get() ([]byte, error)

func (BPFTraceVersionProvider) GetDefault

func (BPFTraceVersionProvider) GetDefault() Version

func (BPFTraceVersionProvider) Parse

func (BPFTraceVersionProvider) Parse(out []byte) (Version, error)

type Block

type Block struct {
	Preamble   string
	Statements []Statement
	// contains filtered or unexported fields
}

Block is an internal representation for BPFTrace block which stores list of semicolon separated statements.

Probe block contains list of BPFTrace statements (and other blocks) to be executed by probe Context is a dictionary which maps objects to local variables produced by casts or predefined variables passed into probe

func (*Block) Add

func (block *Block) Add(stmts ...Statement)

Add adds single-string statements to the block

func (*Block) AddBlock

func (block *Block) AddBlock(preamble string) *Block

AddBlock adds block statement

func (*Block) AddIfBlock

func (block *Block) AddIfBlock(conds ...Expression) *Block

AddIfBlock adds block statement with if preamble containing conditions

func (*Block) Addf

func (block *Block) Addf(format string, args ...interface{})

Addf formats a single-string statement and adds it to the list of block statements

type BlockContext

type BlockContext map[string]struct{}

type Builder

type Builder struct {
	// contains filtered or unexported fields
}

Builder is a central object in skbtrace: it accumulates all knowledge on probes, objects accessible from them and their fields and then builds a trace using one of the Build() methods.

func NewBuilder

func NewBuilder() *Builder

Constructs a new trace script builder

func (*Builder) AddCastFunction

func (b *Builder) AddCastFunction(name string, f interface{})

AddCastFunction registers function accessible from casts.

func (*Builder) AddFieldGroupTemplate

func (b *Builder) AddFieldGroupTemplate(fgBase FieldGroup, rows [][]*Field)

AddFieldGroupTemplate renders multiple filter group rows based on template fgBase which has all fields filled except fields. See AddFieldGroups.

func (*Builder) AddFieldGroups

func (b *Builder) AddFieldGroups(fieldGroups []*FieldGroup)

AddFieldGroups registers fields grouped by roes they're dumped to within a builder. Should be called on program start: might panic.

func (*Builder) AddGlobalVars

func (b *Builder) AddGlobalVars(vars map[string]Expression)

Registers globally available variables and expressions to fetch them. Should be called on program start: might panic.

func (*Builder) AddObjectCasts

func (b *Builder) AddObjectCasts(objCasts []*Object)

AddObjectCasts merges casts supplied by objCasts into already registered objects Should be called on program start: might panic.

func (*Builder) AddObjects

func (b *Builder) AddObjects(objects []*Object)

AddObjects registers object (structure) descriptions within a builder. Should be called on program start: might panic.

func (*Builder) AddProbes

func (b *Builder) AddProbes(probes []*Probe)

AddProbes registers probes and its aliases (including k: and kr: shortcuts) within a builder. Should be called on program start: might panic.

func (*Builder) AddStructDef

func (b *Builder) AddStructDef(typeName string, rawText string)

Registers struct type definition and parses its string. See StructDef for more info.

func (*Builder) BuildAggregate

func (b *Builder) BuildAggregate(opt TraceAggregateOptions) (*Program, error)

func (*Builder) BuildDumpTrace

func (b *Builder) BuildDumpTrace(opt TraceDumpOptions) (*Program, error)

BuildDumpTrace builds a tracer where each probe prints known fields along with timestamp (as defined by time mode) if conditions specified by filters are met.

func (*Builder) BuildDuplicateEvent

func (b *Builder) BuildDuplicateEvent(opt DuplicateEventOptions) (*Program, error)

BuildDuplicateEvent builds a program which attaches to a single probe, but fires only when the probe hits same set of keys second time. Useful for tracking retransmits or measure port reuse time.

func (*Builder) BuildTimeAggregate

func (b *Builder) BuildTimeAggregate(opt TimeAggregateOptions) (*Program, error)

BuildTimeAggregate is a default time mode builder: measures time deltas, puts them into aggregation and periodically dumps aggregation contents.

func (*Builder) BuildTimeEventCount

func (b *Builder) BuildTimeEventCount(opt TimeCommonOptions) (*Program, error)

BuildTimeEventCount builds a program which counts number of times from and to probes are hit. Useful when other time probes do not reveal anything useful because filter is incorrect.

func (*Builder) BuildTimeOutlierDump

func (b *Builder) BuildTimeOutlierDump(opt TimeOutlierDumpOptions) (*Program, error)

BuildTimeOutlierDump builds trace script which mearures time delta, but instead of putting it into an aggregation, it dumps objects that reveal such behaviour, i.e. tcp packet which causes troublingly long handshake.

func (*Builder) FieldGroups

func (b *Builder) FieldGroups() []*FieldGroup

func (*Builder) Objects

func (b *Builder) Objects() []*Object

func (*Builder) Probes

func (b *Builder) Probes() []*Probe

func (*Builder) SetFeatures

func (b *Builder) SetFeatures(mask FeatureFlagMask)

SetFeatures initializes builder based on host BPFTrace version

type BuiltinType

type BuiltinType string
const (
	TBool   BuiltinType = "bool"
	TInt8   BuiltinType = "int8"
	TInt16  BuiltinType = "int16"
	TInt32  BuiltinType = "int32"
	TInt64  BuiltinType = "int64"
	TUInt8  BuiltinType = "uint8"
	TUInt16 BuiltinType = "uint16"
	TUInt32 BuiltinType = "uint32"
	TUInt64 BuiltinType = "uint64"
)

type CastTemplateArgs

type CastTemplateArgs struct {
	// Variable the object is casted from
	Src string

	// Name of the variable object is assigned to
	Dst string
}

type CommonDumpOptions

type CommonDumpOptions struct {
	FieldGroupRows []string

	// Extra printer parameters
	TimeMode TimeMode
	KStack   bool
	UStack   bool
}

type CommonOptions

type CommonOptions struct {
	Timeout time.Duration

	// Hints contains list of row names that are used for resolving weak aliases
	Hints []string

	// Time Unit for measuring times
	TimeUnit string
}

CommonOptions are shared between tracer and time requests

type DuplicateEventOptions

type DuplicateEventOptions struct {
	CommonOptions

	// Specification of the probe
	Spec TimeSpec

	// Specifies if exit() should be called on first duplicate
	Exit bool

	CommonDumpOptions
}

Options for BuildDuplicateEvent.

type Error

type Error interface {
	Level() ErrorLevel
	Ident() string

	NextError() error

	Message() string
}

Helper for prettier unwrapping errors

type ErrorLevel

type ErrorLevel string

Represents skbtrace instance which originated error Useful for tracking chain of errors

const (
	ErrLevelProbe     ErrorLevel = "probe"
	ErrLevelRow       ErrorLevel = "row"
	ErrLevelObject    ErrorLevel = "object"
	ErrLevelFilter    ErrorLevel = "filter"
	ErrLevelField     ErrorLevel = "field"
	ErrLevelStructDef ErrorLevel = "structdef"
)

type Expression

type Expression string

func Expr

func Expr(e string) Expression

Expr converts a string to expression

func ExprField

func ExprField(obj, field string) Expression

ExprField formats an expression for accessing the field

func ExprJoin

func ExprJoin(exprs []Expression) Expression

ExprJoin joins expressions as list separated by comma

func ExprJoinOp

func ExprJoinOp(exprs []Expression, op string) Expression

ExprJoinOp joins expressions using operator op

func Exprf

func Exprf(format string, args ...interface{}) Expression

Exprf formats an expression

func FormatVariableName

func FormatVariableName(field string) Expression

FormatVariableName formats intermediate variable name which can be used for nested fields

type Feature

type Feature struct {
	Component  FeatureComponent
	Name       string
	Help       string
	Commit     string
	MinVersion Version
	// contains filtered or unexported fields
}

func GetKnownFeatures

func GetKnownFeatures(component FeatureComponent) []*Feature

type FeatureComponent

type FeatureComponent int

FeatureComponent groups features by components they are implemented by. FeatureComponentExternal can be used by commands built on top of skbtrace which can use customized kernel module versioned separately from kernel version.

const (
	FeatureComponentKernel FeatureComponent = iota
	FeatureComponentBPFTrace
	FeatureComponentExternal

	FeatureComponentCount
)

type FeatureComponentSpec

type FeatureComponentSpec struct {
	Component FeatureComponent
	Provider  VersionProvider
}

func (FeatureComponentSpec) ProcessFeatures

func (spec FeatureComponentSpec) ProcessFeatures(verArg, maskArg string) (mask FeatureFlagMask, err error)

ProcessFeatures produces feature mask for the current setup. Default is detection by a version, but additionally some features can be disabled (if preceded with !) or enabled via mask argument containing names of the features separated by commas.

type FeatureFlagMask

type FeatureFlagMask struct {
	// contains filtered or unexported fields
}

func (FeatureFlagMask) Supports

func (mask FeatureFlagMask) Supports(feature *Feature) bool

type Field

type Field struct {
	// Name of struct field defined in header file
	Name string

	// Alias for using single-string shortcut without verbose object->field form
	// i.e. 'src' is '$iph->saddr'
	Alias string

	// If specified allows to specify an alias accessible from multiple paths
	// Whichever is more favorable wins
	WeakAlias bool

	// Format key which precedes value when printing. If omitted, Name is used
	FmtKey string

	// Format specifier for BPFTrace printf()
	FmtSpec string

	// Converter function which is used to retrieve field value (which returned as expression)
	// using statements from object obj and its field named field
	Converter FieldConverter

	// ConverterMask overrides contexts in which converter will be used
	ConverterMask uint

	// Preprocessor function is used to convert human-readable value used in filter
	// to machine value
	Preprocessor FieldPreprocessor

	// FilterOperator processes op specified in filter into an expression by filter
	FilterOperator func(expr Expression, op, value string) (Expression, error)

	// SanityFilter produces a template of filter which should be checked
	// when getting the object to avoid printing junk data
	SanityFilter *Filter

	// Help for fields helper subcommand
	Help string
}

Field describes a single position in a printf-statement generated by FieldGroup and used as a handler for structure field name (structure itself is stored in FieldGroup), help (description of field), formatting specifier and text which precedes value and optional converter function which may produce extra statements and expression for field value.

type FieldConverter

type FieldConverter func(obj, field string) ([]Statement, Expression)

FieldConverter is a prototype of Field.Converter field

func NewArrayConvExpr

func NewArrayConvExpr(size int) FieldConverter

func NewBSwapConv

func NewBSwapConv(featureMask FeatureFlagMask, bitSize uint) FieldConverter

func NewConvBitfieldExpr

func NewConvBitfieldExpr(offset uint, mask uint64) FieldConverter

func NewObjectBinOpConvExpr

func NewObjectBinOpConvExpr(left, right string, binOp string, convType BuiltinType, mask FeatureFlagMask) FieldConverter

func NewObjectConvExpr

func NewObjectConvExpr(format string) FieldConverter

type FieldGroup

type FieldGroup struct {
	// Name of the row (might be non-unique, in this case multiple rows will be dumped)
	Row string

	// Object variable name to be dumped. Might be empty for objectless fields
	// taken from probe args or global variables, otherwise must refer to a valid
	// object registered by AddObjects
	Object string

	// List of fields in this group
	Fields []*Field

	// Name of the row for base group (used only for help)
	BaseFieldGroup string

	// Prefix for field aliases: if non empty, field copies will get different
	// aliases prefixed with this string and a dash. Useful for multiple instances
	// of header, or in/out interface logic
	FieldAliasPrefix string
}

FieldGroup produces a single printf statement (and some converter statements from the fields) for a single object. If object is omitted, then fields are interpreted as global variables. NOTE: bpftrace has limitation of 7 format specs per statement, hence splitting fields into rows. Also, it is a bit prettier on my vertical display.

func (FieldGroup) Wrap

func (fg FieldGroup) Wrap(obj, prefix string) FieldGroup

Wraps base field group into prefix. Useful for inner headers

type FieldPreprocessor

type FieldPreprocessor func(op, value string) (string, error)

FieldPreprocessor is a prototype of Field.Preprocessor field

type Filter

type Filter struct {
	Object string
	Field  string
	Op     string
	Value  string
}

type FilterOptions

type FilterOptions struct {
	RawFilters []string
	Filters    []*Filter
}

type KernelVersionProvider

type KernelVersionProvider struct{}

func (*KernelVersionProvider) Get

func (k *KernelVersionProvider) Get() ([]byte, error)

func (*KernelVersionProvider) GetDefault

func (k *KernelVersionProvider) GetDefault() Version

func (*KernelVersionProvider) Parse

func (k *KernelVersionProvider) Parse(verBytes []byte) (Version, error)

type Object

type Object struct {
	// Name of the variable used for this object
	Variable string

	// List of include files which should be included in BPFTrace
	// script for this type to become available in BPFTrace
	HeaderFiles []string

	// Struct definitions to be embedded into codes
	StructDefs []string

	// SanityFilter allows to specify a filter referring an external object
	SanityFilter Filter

	// Maps object variable names this object is inferrable from to
	// templates (see CastTemplateArgs for template arguments)
	Casts map[string]string
}

Object is a representation of an object that can be accessed within a probe and contains necessary actions (casts) to infer it, sanity filters to check its correctness and typing information

type Probe

type Probe struct {
	// Name of the probe in BPFTrace format of "provider:name"
	Name string

	// ReturnName contains explicit name that denotes end of the context probe execution
	ReturnName string

	// List of aliases which could be used in command line
	Aliases []string

	// Context contains initial mapping untyped variable names to probe raw arguments
	Args map[string]string

	// Help string dumped by probes command
	Help string
}

func (*Probe) ReturnProbe

func (p *Probe) ReturnProbe() (string, error)

type ProcessedFilter

type ProcessedFilter struct {
	Filter
	// contains filtered or unexported fields
}

type Program

type Program struct {
	HeaderFiles map[string]struct{}
	StructDefs  map[string]*StructDef
	Blocks      []*Block
}

func NewProgram

func NewProgram() *Program

func (*Program) AddIntervalBlock

func (prog *Program) AddIntervalBlock(d time.Duration) *Block

func (*Program) AddIntervalOrEndBlock

func (prog *Program) AddIntervalOrEndBlock(d time.Duration) *Block

func (*Program) AddProbeBlock

func (prog *Program) AddProbeBlock(probeDef string, probe *Probe) *Block

type RunnerOptions

type RunnerOptions struct {
	DumpScript     bool
	BPFTraceBinary string
}

type Statement

type Statement struct {
	// contains filtered or unexported fields
}

func Stmt

func Stmt(s string) Statement

Stmt creates a new statement that consists from single string

func Stmtf

func Stmtf(format string, args ...interface{}) Statement

Stmtf creates a formats a single-string statement using a format string and its argument

type StructDef

type StructDef struct {
	// Name of the structure
	TypeName string

	// Text of struct definition split by line
	Text []string
	// contains filtered or unexported fields
}

Custom structure definition for use in bpftrace script. They're useful when header file is not part of linux-headers package, or when bpftrace cannot handle some aspects of the type properly, such as arrays or bit fields NOTE: Raw struct defs should be anonymous structs, as they're wrapped into outer structure due to bpftrace parser not handling correctly GCC attributes at top level NOTE: StructDef is not created directly, but spawned by AddStructDef

type TimeAggregateOptions

type TimeAggregateOptions struct {
	TimeCommonOptions
	AggregateCommonOptions

	// Aggregate Func for time and divisor for adjusting from nanoseconds
	Func AggrFunc

	// ToEventCount is a number of to probe firings before we start
	// measuring time delta. Useful for measuring longer handshakes
	// such as TLS handshake for each 2nd ACK is of interest
	ToEventCount int
}

Options for BuildTimeAggregate.

type TimeCommonOptions

type TimeCommonOptions struct {
	CommonOptions

	// Specification of the probe in which start time is collected.
	FromSpec TimeSpec

	// Specification of the probe in which time delta is computed.
	// If filters or keys are omitted in ToSpec, they are derived from FromSpec.
	ToSpec TimeSpec
}

TimeCommonOptions are shared between time options requests.

type TimeMode

type TimeMode string
const (
	TMElapsed TimeMode = "elapsed"
	TMNSecs   TimeMode = "nsecs"
	TMDelta   TimeMode = "delta"
	TMTime    TimeMode = "time"
)

type TimeOutlierDumpOptions

type TimeOutlierDumpOptions struct {
	TimeCommonOptions

	// OutlierThreshold allows to dump events which time exceed specified threshold
	OutlierThreshold time.Duration

	// Specifies if exit() should be called on first outlier
	Exit bool

	CommonDumpOptions
}

Options for BuildTimeOutlierDump.

type TimeSpec

type TimeSpec struct {
	// Name of the probe this probe is refers to
	Probe string

	// Lists of filters applied to this probe
	FilterOptions

	// List of keys used to map requests
	Keys []string

	// Hints for this probe
	Hints []string
}

type TraceAggregateOptions

type TraceAggregateOptions struct {
	TraceCommonOptions
	AggregateCommonOptions

	// Aggregation Func and its argument (optional)
	Func AggrFunc
	Arg  string

	// Keys for aggregation map entry. Optionally, probe name may be added
	Keys []string
}

Options for BuildAggregate

type TraceCommonOptions

type TraceCommonOptions struct {
	CommonOptions

	ContextProbeNames    []string
	ContextFilterOptions FilterOptions
	ContextKey           string

	ProbeNames []string
	FilterOptions
}

type TraceDumpOptions

type TraceDumpOptions struct {
	TraceCommonOptions

	CommonDumpOptions
}

Options for BuildDumpTrace

type Version

type Version struct {
	// Open-Source derived versions
	Major    int
	Submajor int
	Minor    int

	// NOTE: Yandex Cloud derivatives use build numbers and do not alter open-source versions
	Build int
	Date  int
}

func NewVersionFromMatches

func NewVersionFromMatches(matches [][]byte) (ver Version, err error)

func (Version) EqualOrNewer

func (v Version) EqualOrNewer(v2 Version) bool

func (Version) String

func (v Version) String() string

type VersionProvider

type VersionProvider interface {
	Get() ([]byte, error)
	Parse(verBytes []byte) (Version, error)
	GetDefault() Version
}

Directories

Path Synopsis
pkg
cli
skb

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL