diff --git a/bpf/process/types/basic.h b/bpf/process/types/basic.h index 62dd8bfa6c4..80b0c61bc35 100644 --- a/bpf/process/types/basic.h +++ b/bpf/process/types/basic.h @@ -2375,7 +2375,7 @@ filter_read_arg(void *ctx, struct bpf_map_def *heap, } tail_call(ctx, tailcalls, TAIL_CALL_SEND); - return 1; + return 0; } static inline __attribute__((always_inline)) long @@ -2417,7 +2417,7 @@ generic_actions(void *ctx, struct bpf_map_def *heap, postit = do_actions(ctx, e, actions, override_tasks); if (postit) tail_call(ctx, tailcalls, TAIL_CALL_SEND); - return 1; + return 0; } static inline __attribute__((always_inline)) long @@ -2468,7 +2468,7 @@ generic_output(void *ctx, struct bpf_map_def *heap, u8 op) : [total] "+r"(total) :); perf_event_output_metric(ctx, op, &tcpmon_map, BPF_F_CURRENT_CPU, e, total); - return 1; + return 0; } /** diff --git a/pkg/sensors/tracing/genericuprobe.go b/pkg/sensors/tracing/genericuprobe.go index ac8b069707e..d6c118e0177 100644 --- a/pkg/sensors/tracing/genericuprobe.go +++ b/pkg/sensors/tracing/genericuprobe.go @@ -170,6 +170,11 @@ func isValidUprobeSelectors(selectors []v1alpha1.KProbeSelector) error { return nil } +type addUprobeIn struct { + sensorPath string + policyName string +} + func createGenericUprobeSensor( name string, uprobes []v1alpha1.UProbeSpec, @@ -177,129 +182,171 @@ func createGenericUprobeSensor( ) (*sensors.Sensor, error) { var progs []*program.Program var maps []*program.Map + var ids []idtable.EntryID + var err error - sensorPath := name - - loadProgName := "bpf_generic_uprobe.o" - if kernels.EnableV61Progs() { - loadProgName = "bpf_generic_uprobe_v61.o" - } else if kernels.EnableLargeProgs() { - loadProgName = "bpf_generic_uprobe_v53.o" + in := addUprobeIn{ + sensorPath: name, + policyName: policyName, } for _, spec := range uprobes { - var args []v1alpha1.KProbeArg - - if err := isValidUprobeSelectors(spec.Selectors); err != nil { + ids, err = addUprobe(&spec, ids, &in) + if err != nil { return nil, err } + } + + progs, maps, err = createSingleUprobeSensor(ids) + if err != nil { + return nil, err + } - // Parse Filters into kernel filter logic - uprobeSelectorState, err := selectors.InitKernelSelectorState(spec.Selectors, args, nil, nil, nil) + return &sensors.Sensor{ + Name: name, + Progs: progs, + Maps: maps, + }, nil +} + +func addUprobe(spec *v1alpha1.UProbeSpec, ids []idtable.EntryID, in *addUprobeIn) ([]idtable.EntryID, error) { + var args []v1alpha1.KProbeArg + + if err := isValidUprobeSelectors(spec.Selectors); err != nil { + return nil, err + } + + // Parse Filters into kernel filter logic + uprobeSelectorState, err := selectors.InitKernelSelectorState(spec.Selectors, args, nil, nil, nil) + if err != nil { + return nil, err + } + + msgField, err := getPolicyMessage(spec.Message) + if errors.Is(err, ErrMsgSyntaxShort) || errors.Is(err, ErrMsgSyntaxEscape) { + return nil, err + } else if errors.Is(err, ErrMsgSyntaxLong) { + logger.GetLogger().WithField("policy-name", in.policyName). + Warnf("TracingPolicy 'message' field too long, truncated to %d characters", TpMaxMessageLen) + } + + var ( + argTypes [api.EventConfigMaxArgs]int32 + argMeta [api.EventConfigMaxArgs]uint32 + argSet [api.EventConfigMaxArgs]bool + + argPrinters []argPrinter + ) + + // Parse Arguments + for i, a := range spec.Args { + argType := gt.GenericTypeFromString(a.Type) + if argType == gt.GenericInvalidType { + return nil, fmt.Errorf("Arg(%d) type '%s' unsupported", i, a.Type) + } + argMValue, err := getMetaValue(&a) if err != nil { return nil, err } + if a.Index > 4 { + return nil, fmt.Errorf("Error add arg: ArgType %s Index %d out of bounds", + a.Type, int(a.Index)) + } + argTypes[a.Index] = int32(argType) + argMeta[a.Index] = uint32(argMValue) + argSet[a.Index] = true - msgField, err := getPolicyMessage(spec.Message) - if errors.Is(err, ErrMsgSyntaxShort) || errors.Is(err, ErrMsgSyntaxEscape) { - return nil, err - } else if errors.Is(err, ErrMsgSyntaxLong) { - logger.GetLogger().WithField("policy-name", policyName).Warnf("TracingPolicy 'message' field too long, truncated to %d characters", TpMaxMessageLen) + argPrinters = append(argPrinters, argPrinter{index: i, ty: argType}) + } + + // Mark remaining arguments as 'nops' the kernel side will skip + // copying 'nop' args. + for i, a := range argSet { + if !a { + argTypes[i] = gt.GenericNopType + argMeta[i] = 0 } + } - var ( - argTypes [api.EventConfigMaxArgs]int32 - argMeta [api.EventConfigMaxArgs]uint32 - argSet [api.EventConfigMaxArgs]bool - - argPrinters []argPrinter - ) - - // Parse Arguments - for i, a := range spec.Args { - argType := gt.GenericTypeFromString(a.Type) - if argType == gt.GenericInvalidType { - return nil, fmt.Errorf("Arg(%d) type '%s' unsupported", i, a.Type) - } - argMValue, err := getMetaValue(&a) - if err != nil { - return nil, err - } - if a.Index > 4 { - return nil, fmt.Errorf("Error add arg: ArgType %s Index %d out of bounds", - a.Type, int(a.Index)) - } - argTypes[a.Index] = int32(argType) - argMeta[a.Index] = uint32(argMValue) - argSet[a.Index] = true - - argPrinters = append(argPrinters, argPrinter{index: i, ty: argType}) + for _, sym := range spec.Symbols { + config := &api.EventConfig{ + Arg: argTypes, + ArgM: argMeta, } - // Mark remaining arguments as 'nops' the kernel side will skip - // copying 'nop' args. - for i, a := range argSet { - if !a { - argTypes[i] = gt.GenericNopType - argMeta[i] = 0 - } + uprobeEntry := &genericUprobe{ + tableId: idtable.UninitializedEntryID, + config: config, + path: spec.Path, + symbol: sym, + selectors: uprobeSelectorState, + policyName: in.policyName, + message: msgField, + argPrinters: argPrinters, } - for _, sym := range spec.Symbols { - config := &api.EventConfig{ - Arg: argTypes, - ArgM: argMeta, - } - - uprobeEntry := &genericUprobe{ - tableId: idtable.UninitializedEntryID, - config: config, - path: spec.Path, - symbol: sym, - selectors: uprobeSelectorState, - policyName: policyName, - message: msgField, - argPrinters: argPrinters, - } - - uprobeTable.AddEntry(uprobeEntry) - id := uprobeEntry.tableId.ID - - uprobeEntry.pinPathPrefix = sensors.PathJoin(sensorPath, fmt.Sprintf("%d", id)) - config.FuncId = uint32(id) - - pinPath := uprobeEntry.pinPathPrefix - pinProg := sensors.PathJoin(pinPath, "prog") - - attachData := &program.UprobeAttachData{ - Path: spec.Path, - Symbol: sym, - } - - load := program.Builder( - path.Join(option.Config.HubbleLib, loadProgName), - "", - "uprobe/generic_uprobe", - pinProg, - "generic_uprobe"). - SetAttachData(attachData). - SetLoaderData(uprobeEntry) - - progs = append(progs, load) - - configMap := program.MapBuilderPin("config_map", sensors.PathJoin(pinPath, "config_map"), load) - tailCalls := program.MapBuilderPin("uprobe_calls", sensors.PathJoin(pinPath, "up_calls"), load) - filterMap := program.MapBuilderPin("filter_map", sensors.PathJoin(pinPath, "filter_map"), load) - selMatchBinariesMap := program.MapBuilderPin("tg_mb_sel_opts", sensors.PathJoin(pinPath, "tg_mb_sel_opts"), load) - maps = append(maps, configMap, tailCalls, filterMap, selMatchBinariesMap) + uprobeTable.AddEntry(uprobeEntry) + id := uprobeEntry.tableId + + uprobeEntry.pinPathPrefix = sensors.PathJoin(in.sensorPath, fmt.Sprintf("%d", id.ID)) + config.FuncId = uint32(id.ID) + + ids = append(ids, id) + } + + return ids, nil +} + +func createSingleUprobeSensor(ids []idtable.EntryID) ([]*program.Program, []*program.Map, error) { + var progs []*program.Program + var maps []*program.Map + + for _, id := range ids { + uprobeEntry, err := genericUprobeTableGet(id) + if err != nil { + return nil, nil, err } + progs, maps = createUprobeSensorFromEntry(uprobeEntry, progs, maps) } - return &sensors.Sensor{ - Name: name, - Progs: progs, - Maps: maps, - }, nil + return progs, maps, nil +} + +func createUprobeSensorFromEntry(uprobeEntry *genericUprobe, + progs []*program.Program, maps []*program.Map) ([]*program.Program, []*program.Map) { + + loadProgName := "bpf_generic_uprobe.o" + if kernels.EnableV61Progs() { + loadProgName = "bpf_generic_uprobe_v61.o" + } else if kernels.EnableLargeProgs() { + loadProgName = "bpf_generic_uprobe_v53.o" + } + + pinPath := uprobeEntry.pinPathPrefix + pinProg := sensors.PathJoin(pinPath, "prog") + + attachData := &program.UprobeAttachData{ + Path: uprobeEntry.path, + Symbol: uprobeEntry.symbol, + } + + load := program.Builder( + path.Join(option.Config.HubbleLib, loadProgName), + "", + "uprobe/generic_uprobe", + pinProg, + "generic_uprobe"). + SetAttachData(attachData). + SetLoaderData(uprobeEntry) + + progs = append(progs, load) + + configMap := program.MapBuilderPin("config_map", sensors.PathJoin(pinPath, "config_map"), load) + tailCalls := program.MapBuilderPin("uprobe_calls", sensors.PathJoin(pinPath, "up_calls"), load) + filterMap := program.MapBuilderPin("filter_map", sensors.PathJoin(pinPath, "filter_map"), load) + selMatchBinariesMap := program.MapBuilderPin("tg_mb_sel_opts", sensors.PathJoin(pinPath, "tg_mb_sel_opts"), load) + maps = append(maps, configMap, tailCalls, filterMap, selMatchBinariesMap) + return progs, maps } func (k *observerUprobeSensor) PolicyHandler(