diff --git a/helpers_test.go b/helpers_test.go new file mode 100644 index 0000000..311e2e4 --- /dev/null +++ b/helpers_test.go @@ -0,0 +1,59 @@ +package libbpfgo + +import ( + "testing" + + "github.com/aquasecurity/libbpfgo/helpers" +) + +func TestFuncSupportbyType(t *testing.T) { + tt := []struct { + progType BPFProgType + funcId helpers.BPFFunc + supported bool + }{ + { + progType: BPFProgTypeKprobe, + funcId: helpers.BPFFuncMapLookupElem, + supported: true, + }, + { + progType: BPFProgTypeKprobe, + funcId: helpers.BPFFuncLoop, + supported: true, + }, + { + progType: BPFProgTypeKprobe, + funcId: helpers.BPFFuncKtimeGetNs, + supported: true, + }, + { + progType: BPFProgTypeKprobe, + funcId: helpers.BPFFuncSysBpf, + supported: false, + }, + { + progType: BPFProgTypeLsm, + funcId: helpers.BPFFuncGetCurrentCgroupId, + supported: false, + }, + { + progType: BPFProgTypeSkLookup, + funcId: helpers.BPFFuncGetCurrentCgroupId, + supported: true, + }, + { + progType: BPFProgTypeKprobe, + funcId: helpers.BPFFuncSockMapUpdate, + supported: false, + }, + } + + for _, tc := range tt { + support, _ := BPFHelperIsSupported(tc.progType, tc.funcId) + // This may fail if the bpf helper support for a specific program changes in future. + if support != tc.supported { + t.Errorf("expected %v, got %v", tc.supported, support) + } + } +} diff --git a/libbpfgo.go b/libbpfgo.go index 9d017fe..ba6a82f 100644 --- a/libbpfgo.go +++ b/libbpfgo.go @@ -9,6 +9,8 @@ import "C" import ( "fmt" "syscall" + + "github.com/aquasecurity/libbpfgo/helpers" ) // @@ -96,6 +98,15 @@ func BPFMapTypeIsSupported(mapType MapType) (bool, error) { return supportedC == 1, nil } +func BPFHelperIsSupported(progType BPFProgType, funcId helpers.BPFFunc) (bool, error) { + supportedC := C.libbpf_probe_bpf_helper(C.enum_bpf_prog_type(int(progType)), C.enum_bpf_func_id(int(funcId)), nil) + if supportedC < 0 { + return false, syscall.Errno(-supportedC) + } + + return supportedC == 1, nil +} + // // Misc //