github.com/dylandreimerink/gobpfld@v0.6.1-0.20220205171531-e79c330ad608/bpftypes/bpf_types.go (about)

     1  package bpftypes
     2  
     3  import (
     4  	"strings"
     5  	"unsafe"
     6  )
     7  
     8  const (
     9  	// BPF_OBJ_NAME_LEN the max length of an object name as defined by the linux kernel
    10  	// The actual size of the string is 16 bytes, but the last byte must always be 0x00
    11  	BPF_OBJ_NAME_LEN = 16
    12  )
    13  
    14  // BPFCommand is a enum which describes a number of different commands which can be sent to the kernel
    15  // via the bpf syscall.
    16  // From bpf_cmd https://github.com/torvalds/linux/blob/master/include/uapi/linux/bpf.h#L838
    17  type BPFCommand int
    18  
    19  const (
    20  	// BPF_MAP_CREATE creates a new map
    21  	BPF_MAP_CREATE BPFCommand = iota
    22  	// BPF_MAP_LOOKUP_ELEM looks up the value stored in a map for a given key
    23  	BPF_MAP_LOOKUP_ELEM
    24  	// BPF_MAP_UPDATE_ELEM changes the value in a map for a given key
    25  	BPF_MAP_UPDATE_ELEM
    26  	// BPF_MAP_DELETE_ELEM deletes a key and value form a map
    27  	BPF_MAP_DELETE_ELEM
    28  	// BPF_MAP_GET_NEXT_KEY is used to iterate over all keys in a map one key at a time
    29  	BPF_MAP_GET_NEXT_KEY
    30  	// BPF_PROG_LOAD loads a program into the kernel
    31  	BPF_PROG_LOAD
    32  	// BPF_OBJ_PIN pins a eBPF object(map, program, BTF, link) to the bpf filesystem
    33  	BPF_OBJ_PIN
    34  	// BPF_OBJ_GET gets a file descriptor for a pinned object
    35  	BPF_OBJ_GET
    36  	// BPF_PROG_ATTACH attaches certain program types to a specified location
    37  	BPF_PROG_ATTACH
    38  	// BPF_PROG_DETACH detaches certain program types from their attached locations
    39  	BPF_PROG_DETACH
    40  	// BPF_PROG_TEST_RUN test a loaded program without attaching it
    41  	BPF_PROG_TEST_RUN
    42  	// BPF_PROG_GET_NEXT_ID is used to iterate over loaded programs
    43  	BPF_PROG_GET_NEXT_ID
    44  	// BPF_MAP_GET_NEXT_ID is used to iterate over loaded maps
    45  	BPF_MAP_GET_NEXT_ID
    46  	// BPF_PROG_GET_FD_BY_ID returns a file descriptor of a loaded program by its ID
    47  	BPF_PROG_GET_FD_BY_ID
    48  	// BPF_MAP_GET_FD_BY_ID returns a file descriptor of a loaded map by its ID
    49  	BPF_MAP_GET_FD_BY_ID
    50  	// BPF_OBJ_GET_INFO_BY_FD returns info about loaded eBPF objects by their file descriptor
    51  	BPF_OBJ_GET_INFO_BY_FD
    52  	// BPF_PROG_QUERY is used to query program information in relation to cgroups
    53  	// https://patchwork.ozlabs.org/project/netdev/patch/20171002234857.3707580-3-ast@fb.com/
    54  	BPF_PROG_QUERY
    55  	// BPF_RAW_TRACEPOINT_OPEN is used to attach a raw tracepoint program to a tracepoint
    56  	// https://patchwork.ozlabs.org/project/netdev/cover/20180328190540.370956-1-ast@kernel.org/
    57  	BPF_RAW_TRACEPOINT_OPEN
    58  	// BPF_BTF_LOAD is used to load BTF(debug symbols) into the kernel
    59  	BPF_BTF_LOAD
    60  	// BPF_BTF_GET_FD_BY_ID is used to get a file descriptor for a loaded BTF object by ID
    61  	BPF_BTF_GET_FD_BY_ID
    62  	// BPF_TASK_FD_QUERY us used to get information about the attachment point of tracing programs by their fd
    63  	// https://patchwork.ozlabs.org/project/netdev/patch/20180524001844.1175727-3-yhs@fb.com/
    64  	BPF_TASK_FD_QUERY
    65  	// BPF_MAP_LOOKUP_AND_DELETE_ELEM get the value of a key in a map and deletes it at the same time
    66  	// like in pop operations of a stack or queue
    67  	BPF_MAP_LOOKUP_AND_DELETE_ELEM
    68  	// BPF_MAP_FREEZE freezes a map so its contents can't be changed anymore
    69  	BPF_MAP_FREEZE
    70  	// BPF_BTF_GET_NEXT_ID is used to iterate over loaded BTF objects
    71  	BPF_BTF_GET_NEXT_ID
    72  	// BPF_MAP_LOOKUP_BATCH is used to lookup a batch of keys/values in one syscall
    73  	BPF_MAP_LOOKUP_BATCH
    74  	// BPF_MAP_LOOKUP_AND_DELETE_BATCH is used to dequeue/pop a batch of values in one syscall
    75  	BPF_MAP_LOOKUP_AND_DELETE_BATCH
    76  	// BPF_MAP_UPDATE_BATCH is used to update a batch of values in one syscall
    77  	BPF_MAP_UPDATE_BATCH
    78  	// BPF_MAP_DELETE_BATCH is used to delete a btach of keys/values in one syscall
    79  	BPF_MAP_DELETE_BATCH
    80  	// BPF_LINK_CREATE is yet another way to attach bpf programs, a link links a program
    81  	// to an attachment point and generates its own file descriptor which with to manage
    82  	// the link in the future.
    83  	// https://patchwork.ozlabs.org/project/netdev/patch/20200427201240.2994985-1-yhs@fb.com/
    84  	BPF_LINK_CREATE
    85  	// BPF_LINK_UPDATE is used to update the program of a link
    86  	BPF_LINK_UPDATE
    87  	// BPF_LINK_GET_FD_BY_ID is used to get a file descriptor of a link by its id
    88  	BPF_LINK_GET_FD_BY_ID
    89  	// BPF_LINK_GET_NEXT_ID is used to iterate over all links
    90  	BPF_LINK_GET_NEXT_ID
    91  	// BPF_ENABLE_STATS is used to enable/disable eBPF statistics collection by the kernel
    92  	BPF_ENABLE_STATS
    93  	// BPF_ITER_CREATE creates a kernel data iterator (custom /proc)
    94  	BPF_ITER_CREATE
    95  	// BPF_LINK_DETACH is used to detach a link
    96  	BPF_LINK_DETACH
    97  	// BPF_PROG_BIND_MAP binds a map to a program even when the program doesn't use that map.
    98  	BPF_PROG_BIND_MAP
    99  )
   100  
   101  var bpfCommandToStr = map[BPFCommand]string{
   102  	BPF_MAP_CREATE:                  "BPF_MAP_CREATE",
   103  	BPF_MAP_LOOKUP_ELEM:             "BPF_MAP_LOOKUP_ELEM",
   104  	BPF_MAP_UPDATE_ELEM:             "BPF_MAP_UPDATE_ELEM",
   105  	BPF_MAP_DELETE_ELEM:             "BPF_MAP_DELETE_ELEM",
   106  	BPF_MAP_GET_NEXT_KEY:            "BPF_MAP_GET_NEXT_KEY",
   107  	BPF_PROG_LOAD:                   "BPF_PROG_LOAD",
   108  	BPF_OBJ_PIN:                     "BPF_OBJ_PIN",
   109  	BPF_OBJ_GET:                     "BPF_OBJ_GET",
   110  	BPF_PROG_ATTACH:                 "BPF_PROG_ATTACH",
   111  	BPF_PROG_DETACH:                 "BPF_PROG_DETACH",
   112  	BPF_PROG_TEST_RUN:               "BPF_PROG_TEST_RUN",
   113  	BPF_PROG_GET_NEXT_ID:            "BPF_PROG_GET_NEXT_ID",
   114  	BPF_MAP_GET_NEXT_ID:             "BPF_MAP_GET_NEXT_ID",
   115  	BPF_PROG_GET_FD_BY_ID:           "BPF_PROG_GET_FD_BY_ID",
   116  	BPF_MAP_GET_FD_BY_ID:            "BPF_MAP_GET_FD_BY_ID",
   117  	BPF_OBJ_GET_INFO_BY_FD:          "BPF_OBJ_GET_INFO_BY_FD",
   118  	BPF_PROG_QUERY:                  "BPF_PROG_QUERY",
   119  	BPF_RAW_TRACEPOINT_OPEN:         "BPF_RAW_TRACEPOINT_OPEN",
   120  	BPF_BTF_LOAD:                    "BPF_BTF_LOAD",
   121  	BPF_BTF_GET_FD_BY_ID:            "BPF_BTF_GET_FD_BY_ID",
   122  	BPF_TASK_FD_QUERY:               "BPF_TASK_FD_QUERY",
   123  	BPF_MAP_LOOKUP_AND_DELETE_ELEM:  "BPF_MAP_LOOKUP_AND_DELETE_ELEM",
   124  	BPF_MAP_FREEZE:                  "BPF_MAP_FREEZE",
   125  	BPF_BTF_GET_NEXT_ID:             "BPF_BTF_GET_NEXT_ID",
   126  	BPF_MAP_LOOKUP_BATCH:            "BPF_MAP_LOOKUP_BATCH",
   127  	BPF_MAP_LOOKUP_AND_DELETE_BATCH: "BPF_MAP_LOOKUP_AND_DELETE_BATCH",
   128  	BPF_MAP_UPDATE_BATCH:            "BPF_MAP_UPDATE_BATCH",
   129  	BPF_MAP_DELETE_BATCH:            "BPF_MAP_DELETE_BATCH",
   130  	BPF_LINK_CREATE:                 "BPF_LINK_CREATE",
   131  	BPF_LINK_UPDATE:                 "BPF_LINK_UPDATE",
   132  	BPF_LINK_GET_FD_BY_ID:           "BPF_LINK_GET_FD_BY_ID",
   133  	BPF_LINK_GET_NEXT_ID:            "BPF_LINK_GET_NEXT_ID",
   134  	BPF_ENABLE_STATS:                "BPF_ENABLE_STATS",
   135  	BPF_ITER_CREATE:                 "BPF_ITER_CREATE",
   136  	BPF_LINK_DETACH:                 "BPF_LINK_DETACH",
   137  	BPF_PROG_BIND_MAP:               "BPF_PROG_BIND_MAP",
   138  }
   139  
   140  func (cmd BPFCommand) String() string {
   141  	str := bpfCommandToStr[cmd]
   142  	if str == "" {
   143  		return "UNKNOWN"
   144  	}
   145  
   146  	return str
   147  }
   148  
   149  // BPFMapType is an enum type which describes a type of map
   150  // From bpf_map_type https://github.com/torvalds/linux/blob/master/include/uapi/linux/bpf.h#L878
   151  //
   152  // There are generic map types which allow a user to use any key and value type they wish (within limits) and
   153  // specialized map types which typically have only one or a few purposes, must have specific keys or values, and/or
   154  // can only be used in conjunction with specific helper functions.
   155  type BPFMapType uint32
   156  
   157  const (
   158  	// BPF_MAP_TYPE_UNSPEC is a invalid map type with the numeric value of 0, so map types are always unspecified
   159  	// if not initialized.
   160  	BPF_MAP_TYPE_UNSPEC BPFMapType = iota
   161  	// BPF_MAP_TYPE_HASH is a generic map type which has no key or value memory layout restrictions. Memory for
   162  	// this map is not pre-allocated unless requested with an additional flag. The value of the key is hashed
   163  	// and looked up in a hashmap.
   164  	BPF_MAP_TYPE_HASH
   165  	// BPF_MAP_TYPE_ARRAY is a generic map type which has no key or value memory layout restrictions. Memory for
   166  	// this map is pre-allocated in a contiguous memory region. The value of key is interpreted as an offset aka
   167  	// index.
   168  	BPF_MAP_TYPE_ARRAY
   169  	// BPF_MAP_TYPE_PROG_ARRAY is a specialized map type which is used in conjunction with the bpf_tail_call
   170  	// helper function to "tail call" into another eBPF program.
   171  	// The key of this map is an array index (0 to 'max_entries').
   172  	// The value of this map is a eBPF program file descriptor gotten from the bpf syscall
   173  	BPF_MAP_TYPE_PROG_ARRAY
   174  	// BPF_MAP_TYPE_PERF_EVENT_ARRAY is a specialized map type that is used in conjunction with the
   175  	// bpf_perf_event_read, bpf_perf_event_output, bpf_perf_event_read_value, bpf_skb_output, or bpf_xdp_output
   176  	// helper functions. This allows eBPF programs to generate events in the 'perf' linux profiler which can be
   177  	// read by a userspace program. The key is an array inex (0 to 'max_entires')
   178  	// The value is a file descriptor returned by the perf_event_open syscall
   179  	BPF_MAP_TYPE_PERF_EVENT_ARRAY
   180  	// BPF_MAP_TYPE_PERCPU_HASH is a generic map type which has no key or value memory layout restrictions.
   181  	// It is similar to the BPF_MAP_TYPE_HASH map type, however, for every logical CPU a separate map is created
   182  	// and maintained. A eBPF program can only interact with the version of the map allocated to the CPU it is
   183  	// running on.The advantage of this scheme is that no race conditions can ever occur so no locking is required and
   184  	// no CPUcaches have to be kept in sync, this makes it very fast. The downside is that since every CPU has a unique
   185  	// copy the memory usage is multiplied by the CPU core count of the machine (trading of speed for memory usage).
   186  	//
   187  	// When interacting with this map from the syscall/userspace side all values for every version of the map is
   188  	// returned at once as an array. This may seem confusing since the buffer size in userspace needs to be way larger
   189  	// than the value size in the map definition indicates. Getting a u8 values from a per cpu map on a 16 logical CPU
   190  	// core machine takes 16 bytes. The returned array is indexed by CPU number.
   191  	BPF_MAP_TYPE_PERCPU_HASH
   192  	// BPF_MAP_TYPE_PERCPU_ARRAY is a generic map type which has no key or value memory layout restrictions.
   193  	// It works the same as the BPF_MAP_TYPE_PERCPU_HASH map except it has been pre-allocated and the key is
   194  	// interpreted as an array index so from 0 to 'max_entires'
   195  	BPF_MAP_TYPE_PERCPU_ARRAY
   196  	// BPF_MAP_TYPE_STACK_TRACE is a specialized map type which is used to store a stacktrace which can be accessed
   197  	// by eBPF programs to to tracing or make metrics.
   198  	//
   199  	// TODO figure out the key and value types of this maps. The kernel samples seem to suggest this map is
   200  	// automatically when a program is called and has to be cleaned by a userspace application which also has
   201  	// a chance to access the trace.
   202  	BPF_MAP_TYPE_STACK_TRACE
   203  	// BPF_MAP_TYPE_CGROUP_ARRAY is a specialized map type that is used in conjunction with the bpf_skb_under_cgroup
   204  	// or bpf_current_task_under_cgroup helper functions. It can be used to check if the eBPF program is running in
   205  	// the context of a specific cgroup.
   206  	// The key is an array index (0 to 'max_entries').
   207  	// The value is a cgroup file descriptor.
   208  	BPF_MAP_TYPE_CGROUP_ARRAY
   209  	// BPF_MAP_TYPE_LRU_HASH is a generic map type which has no key or value memory layout restrictions. It is
   210  	// similar to the BPF_MAP_TYPE_HASH type with one exception. When the map is full and a value is written to it
   211  	// the least recently used element of the map is replaced with the new element.
   212  	// This is useful for use cases like caches or statistics where losing data is not the end of the world.
   213  	BPF_MAP_TYPE_LRU_HASH
   214  	// BPF_MAP_TYPE_LRU_PERCPU_HASH is a generic map type which has no key or value memory layout restrictions.
   215  	// It is the per cpu variant of the BPF_MAP_TYPE_LRU_HASH map type and combines both features.
   216  	// Please look at the description of the BPF_MAP_TYPE_PERCPU_HASH type for the per cpu features and
   217  	// the BPF_MAP_TYPE_LRU_HASH map type for lru features
   218  	BPF_MAP_TYPE_LRU_PERCPU_HASH
   219  	// BPF_MAP_TYPE_LPM_TRIE is a specialized map type which uses longest prefix matching when looking up elements
   220  	// in the map. This is mainly useful for IP range lookups where more specific IP prefixes take precedence over
   221  	// less specific IP prefixes.
   222  	// The key must start with a unsigned 32 bit integer which denotes the amount of bits to consider followed by
   223  	// a user determined number of bytes containing the actual data to be matches.
   224  	// The value type is arbitrary.
   225  	BPF_MAP_TYPE_LPM_TRIE
   226  	// BPF_MAP_TYPE_ARRAY_OF_MAPS is a specialized map type that refers to other maps.
   227  	// The key of this map type is an array index(0 to 'max_entires').
   228  	// The value of this map type is a pointer to another map.
   229  	BPF_MAP_TYPE_ARRAY_OF_MAPS
   230  	// BPF_MAP_TYPE_HASH_OF_MAPS is a specialized map type that refers to other maps.
   231  	// The key of this map type is hashed and can my any type.
   232  	// The value of this map is a pointer to another map.
   233  	BPF_MAP_TYPE_HASH_OF_MAPS
   234  	// BPF_MAP_TYPE_DEVMAP is a specialized map type that is used in conjunction with the bpf_redirect_map
   235  	// helper function to redirect a XDP frame to a specific network device which sends it out of its associated
   236  	// port. This allows us to implement driver level switching.
   237  	// The key of a devmap is an array index (0 to 'max_entries')
   238  	// The value of a devmap must follow the bpf_devmap_val memory layout
   239  	// https://elixir.bootlin.com/linux/v5.11.15/source/include/uapi/linux/bpf.h#L4390
   240  	BPF_MAP_TYPE_DEVMAP
   241  	// BPF_MAP_TYPE_SOCKMAP is a specialized map type that is used in conjunction with the bpf_sk_redirect_map or
   242  	// bpf_msg_redirect_map map helper functions to redirect packets to sockets.
   243  	// The key of a sockmap is an array index (0 to 'max_entries')
   244  	// The value of a sockmap is a file descriptor to a socket, returned by the socket(2) syscall
   245  	BPF_MAP_TYPE_SOCKMAP
   246  	// BPF_MAP_TYPE_CPUMAP is a specialized map type that is used in conjunction with the bpf_redirect_map
   247  	// helper function to redirect a XDP frame to a specific CPU for further processing by the kernel
   248  	// network stack. This essentially allows an XDP to do RPS(Receive Packet Steering).
   249  	// Example: https://github.com/torvalds/linux/blob/master/samples/bpf/xdp_redirect_cpu_kern.c
   250  	// The key of a cpumap is an array index (0 to 'max_entries')
   251  	// The value of a cpumap must follow the bpf_cpumap_val memory layout
   252  	// https://elixir.bootlin.com/linux/v5.11.15/source/include/uapi/linux/bpf.h#L4403
   253  	BPF_MAP_TYPE_CPUMAP
   254  	// BPF_MAP_TYPE_XSKMAP is a specialized map type that is used in conjunction with the bpf_redirect_map
   255  	// helper function to pass a XDP frame to a AF_XDP socket thus bypassing the kernel network stack.
   256  	// Using AF_XDP is complicated and requires a lot of setup from the loader.
   257  	// https://github.com/torvalds/linux/blob/master/Documentation/networking/af_xdp.rst
   258  	BPF_MAP_TYPE_XSKMAP
   259  	// BPF_MAP_TYPE_SOCKHASH is a specialized map type that is used in conjunction with the bpf_sk_redirect_hash
   260  	// and bpf_msg_redirect_hash helper function to redirect packets to sockets. It is almost identical to
   261  	// BPF_MAP_TYPE_SOCKMAP but is implemented with a hashmap instead of an array.
   262  	BPF_MAP_TYPE_SOCKHASH
   263  	// BPF_MAP_TYPE_CGROUP_STORAGE is a specialized map type that is used in conjunction with the bpf_get_local_storage
   264  	// helper function. This map is used to store arbitrary data in a memory area linked to the cgroup.
   265  	// The key of the map is the cgroup_inode_id(uint64) or bpf_cgroup_storage_key.
   266  	// The value of the map is arbitrary.
   267  	// https://github.com/torvalds/linux/blob/master/Documentation/bpf/map_cgroup_storage.rst
   268  	BPF_MAP_TYPE_CGROUP_STORAGE
   269  	// BPF_MAP_TYPE_REUSEPORT_SOCKARRAY is a specialized map type that is used in conjunction with the
   270  	// sk_select_reuseport helper function to redirect a packet to a specific socket which is bound to the a port
   271  	// using the SO_REUSEPORT socket option. The SO_REUSEPORT socket option allows multiple sockets to listen on
   272  	// the same port which are typically placed on different threads, this scheme can improve performance.
   273  	// https://lwn.net/Articles/542629/.
   274  	BPF_MAP_TYPE_REUSEPORT_SOCKARRAY
   275  	// BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE is the per cpu version of BPF_MAP_TYPE_CGROUP_STORAGE.
   276  	// https://github.com/torvalds/linux/blob/master/Documentation/bpf/map_cgroup_storage.rst
   277  	BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE
   278  	// BPF_MAP_TYPE_QUEUE is a specialized map type that is used in conjunction with the bpf_map_push_elem,
   279  	// bpf_map_pop_elem, and bpf_map_peek_elem helper functions. This map type implements a LIFO/FIFO queue
   280  	// which does not allow for arbitrary access and does not use keys.
   281  	// The value of the map is arbitrary.
   282  	BPF_MAP_TYPE_QUEUE
   283  	// BPF_MAP_TYPE_STACK is a specialized map type that is used in conjunction with the bpf_map_push_elem,
   284  	// bpf_map_pop_elem, and bpf_map_peek_elem helper functions. This map type implements a stack
   285  	// which does not allow for arbitrary access and does not use keys.
   286  	// The value of the map is arbitrary.
   287  	BPF_MAP_TYPE_STACK
   288  	// BPF_MAP_TYPE_SK_STORAGE is a specialized map type that is used in conjunction with the bpf_sk_storage_get
   289  	// helper function. This map allows a program to attach stored data to a socket. This has the advantage
   290  	// of not having to manage this memory since it will be freed when the socket closes.
   291  	// The key of the map is not used since a program can only access data for the socket on which
   292  	// it was triggered.
   293  	// The value type is arbitrary.
   294  	BPF_MAP_TYPE_SK_STORAGE
   295  	// BPF_MAP_TYPE_DEVMAP_HASH is a specialized map type that is used in conjunction with the bpf_redirect_map
   296  	// helper function. It it almost the same as the BPF_MAP_TYPE_DEVMAP type except the key is hashed so
   297  	// non-contiguous keys can be used without wasting memory.
   298  	BPF_MAP_TYPE_DEVMAP_HASH
   299  	// BPF_MAP_TYPE_STRUCT_OPS is used in BPF_PROG_TYPE_STRUCT_OPS programs.
   300  	// TODO figure out how BPF_PROG_TYPE_STRUCT_OPS programs work and how the map should be used
   301  	BPF_MAP_TYPE_STRUCT_OPS
   302  	// BPF_MAP_TYPE_RINGBUF is a specialized map type that is used in conjunction with the bpf_ringbuf_output,
   303  	// bpf_ringbuf_reserve, bpf_ringbuf_submit, bpf_ringbuf_discard, and bpf_ringbuf_query helper function.
   304  	// https://github.com/torvalds/linux/blob/master/Documentation/bpf/ringbuf.rst
   305  	BPF_MAP_TYPE_RINGBUF
   306  	// BPF_MAP_TYPE_INODE_STORAGE is a specialized map type that is used in conjunction with the bpf_inode_storage_get
   307  	// and bpf_inode_storage_delete helper functions. This can be used to attach data to a inode. This is especially
   308  	// useful for eBPF programs that deal with files like LSM programs. When the inode is deleted, the associated data
   309  	// is also deleted.
   310  	BPF_MAP_TYPE_INODE_STORAGE
   311  	// BPF_MAP_TYPE_TASK_STORAGE is a specialized map type that is used in conjunction with the bpf_task_storage_get
   312  	// and bpf_task_storage_delete helper functions. This can be used to attach data to a task.
   313  	// When the task ends, the data is deleted.
   314  	BPF_MAP_TYPE_TASK_STORAGE
   315  )
   316  
   317  var bpfMapTypeToStr = map[BPFMapType]string{
   318  	BPF_MAP_TYPE_UNSPEC:                "BPF_MAP_TYPE_UNSPEC",
   319  	BPF_MAP_TYPE_HASH:                  "BPF_MAP_TYPE_HASH",
   320  	BPF_MAP_TYPE_ARRAY:                 "BPF_MAP_TYPE_ARRAY",
   321  	BPF_MAP_TYPE_PROG_ARRAY:            "BPF_MAP_TYPE_PROG_ARRAY",
   322  	BPF_MAP_TYPE_PERF_EVENT_ARRAY:      "BPF_MAP_TYPE_PERF_EVENT_ARRAY",
   323  	BPF_MAP_TYPE_PERCPU_HASH:           "BPF_MAP_TYPE_PERCPU_HASH",
   324  	BPF_MAP_TYPE_PERCPU_ARRAY:          "BPF_MAP_TYPE_PERCPU_ARRAY",
   325  	BPF_MAP_TYPE_STACK_TRACE:           "BPF_MAP_TYPE_STACK_TRACE",
   326  	BPF_MAP_TYPE_CGROUP_ARRAY:          "BPF_MAP_TYPE_CGROUP_ARRAY",
   327  	BPF_MAP_TYPE_LRU_HASH:              "BPF_MAP_TYPE_LRU_HASH",
   328  	BPF_MAP_TYPE_LRU_PERCPU_HASH:       "BPF_MAP_TYPE_LRU_PERCPU_HASH",
   329  	BPF_MAP_TYPE_LPM_TRIE:              "BPF_MAP_TYPE_LPM_TRIE",
   330  	BPF_MAP_TYPE_ARRAY_OF_MAPS:         "BPF_MAP_TYPE_ARRAY_OF_MAPS",
   331  	BPF_MAP_TYPE_HASH_OF_MAPS:          "BPF_MAP_TYPE_HASH_OF_MAPS",
   332  	BPF_MAP_TYPE_DEVMAP:                "BPF_MAP_TYPE_DEVMAP",
   333  	BPF_MAP_TYPE_SOCKMAP:               "BPF_MAP_TYPE_SOCKMAP",
   334  	BPF_MAP_TYPE_CPUMAP:                "BPF_MAP_TYPE_CPUMAP",
   335  	BPF_MAP_TYPE_XSKMAP:                "BPF_MAP_TYPE_XSKMAP",
   336  	BPF_MAP_TYPE_SOCKHASH:              "BPF_MAP_TYPE_SOCKHASH",
   337  	BPF_MAP_TYPE_CGROUP_STORAGE:        "BPF_MAP_TYPE_CGROUP_STORAGE",
   338  	BPF_MAP_TYPE_REUSEPORT_SOCKARRAY:   "BPF_MAP_TYPE_REUSEPORT_SOCKARRAY",
   339  	BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE: "BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE",
   340  	BPF_MAP_TYPE_QUEUE:                 "BPF_MAP_TYPE_QUEUE",
   341  	BPF_MAP_TYPE_STACK:                 "BPF_MAP_TYPE_STACK",
   342  	BPF_MAP_TYPE_SK_STORAGE:            "BPF_MAP_TYPE_SK_STORAGE",
   343  	BPF_MAP_TYPE_DEVMAP_HASH:           "BPF_MAP_TYPE_DEVMAP_HASH",
   344  	BPF_MAP_TYPE_STRUCT_OPS:            "BPF_MAP_TYPE_STRUCT_OPS",
   345  	BPF_MAP_TYPE_RINGBUF:               "BPF_MAP_TYPE_RINGBUF",
   346  	BPF_MAP_TYPE_INODE_STORAGE:         "BPF_MAP_TYPE_INODE_STORAGE",
   347  	BPF_MAP_TYPE_TASK_STORAGE:          "BPF_MAP_TYPE_TASK_STORAGE",
   348  }
   349  
   350  func (mt BPFMapType) String() string {
   351  	str := bpfMapTypeToStr[mt]
   352  	if str == "" {
   353  		return "UNKNOWN"
   354  	}
   355  
   356  	return str
   357  }
   358  
   359  // BPFProgType describes what kind of eBPF program we are dealing with. The type of program will restrict
   360  // where it can be attached, which attributes go into the program, what helper functions can be executed
   361  // in the program, and what the meaning of the return value is.
   362  type BPFProgType uint32
   363  
   364  //nolint:revive // not every program type is known to me yet, until then ignore missing comments
   365  const (
   366  	// BPF_PROG_TYPE_UNSPEC is the default/zero value and is invalid in most cases
   367  	BPF_PROG_TYPE_UNSPEC BPFProgType = iota
   368  	// BPF_PROG_TYPE_SOCKET_FILTER program type can be attached to a socket using the SO_ATTACH_BPF
   369  	// option via the setsockopt syscall. The program is called for inbound packet and can be used to filter,
   370  	// trim, and modify packets. The program is given a pointer to __sk_buff and should return the amount of
   371  	// bytes of the packet to keep, all remaining bytes will be trimmed. A return value of 0 means drop.
   372  	BPF_PROG_TYPE_SOCKET_FILTER
   373  	// BPF_PROG_TYPE_KPROBE program type can be attached to kprobes and uprobes.
   374  	// The main purpose of this is to collect information and/or to debug the kernel. The program is executed
   375  	// every time the breakpoint it is attached to is hit while that breakpoint is enabled.
   376  	// You can find more info about kprobes here: https://lwn.net/Articles/132196/
   377  	BPF_PROG_TYPE_KPROBE
   378  	// BPF_PROG_TYPE_SCHED_CLS program type can be attached to tc(traffic control) and acts as a traffic
   379  	// classifier. For more details on this program type check out the tc-bpf manpage
   380  	// https://man7.org/linux/man-pages/man8/tc-bpf.8.html
   381  	BPF_PROG_TYPE_SCHED_CLS
   382  	// BPF_PROG_TYPE_SCHED_ACT program type can be attached to tc(traffic control) and can tell tc to perform
   383  	// a certain action on. For more details on this program type check out the tc-bpf manpage
   384  	// https://man7.org/linux/man-pages/man8/tc-bpf.8.html
   385  	BPF_PROG_TYPE_SCHED_ACT
   386  	// BPF_PROG_TYPE_TRACEPOINT program type can be attached to kernel tracepoints. Tracepoints are predefined
   387  	// places in the kernel which are interesting to monitor. The program is called every time the kernel executes
   388  	// code with a enabled tracepoint to which the eBPF program is attached.
   389  	// You can read more about this program type here: https://lwn.net/Articles/683504/
   390  	BPF_PROG_TYPE_TRACEPOINT
   391  	// BPF_PROG_TYPE_XDP program type can be attached to network interfaces. A XDP program is triggered for every
   392  	// incoming data frame that is received on the network interface the program is attached to. The program is
   393  	// typically called from a network driver as soon as possible, before the kernel network stack.
   394  	// XDP programs can modify, redirect, or pass frames which can be used for very high performance network programs.
   395  	BPF_PROG_TYPE_XDP
   396  	// BPF_PROG_TYPE_PERF_EVENT program type can be attached to hardware and softwate perf events.
   397  	// The program is triggered for every perf event it is attached to within a given scope.
   398  	// It is mainly used for collecting information and monitoring.
   399  	// https://github.com/torvalds/linux/commit/0515e5999a466dfe6e1924f460da599bb6821487
   400  	// You can read more about perf and perf_events here: http://www.brendangregg.com/perf.html
   401  	BPF_PROG_TYPE_PERF_EVENT
   402  	// BPF_PROG_TYPE_CGROUP_SKB program type can be attached to cgroups and is triggered on IP ingress/egress.
   403  	// The program can then allow or deny the ip packet to pass thus restricting network access for programs running
   404  	// in that cgroup programmatically.
   405  	BPF_PROG_TYPE_CGROUP_SKB
   406  	// BPF_PROG_TYPE_CGROUP_SOCK program type can be attached to cgroups and is triggered when a new socket is
   407  	// requested. The program can then allow or deny for example a program in a cgroup from listening on a specific
   408  	// network port.
   409  	BPF_PROG_TYPE_CGROUP_SOCK
   410  	// BPF_PROG_TYPE_LWT_IN program type can be attached to specific network routes. The program is called for every
   411  	// incoming packet to that route to decapsulate it. This allows a eBPF program to implement a tunneling
   412  	// protocol which is not supported by default by linux or to dynamically change its behavior using maps.
   413  	BPF_PROG_TYPE_LWT_IN
   414  	BPF_PROG_TYPE_LWT_OUT
   415  	BPF_PROG_TYPE_LWT_XMIT
   416  	// BPF_PROG_TYPE_SOCK_OPS program type can be attached to cgroups and is triggered on a number of socket
   417  	// operations like TCP connection state changes, connection timeout, and new listening sockets.
   418  	// This program type can change the options of the socket with the bpf_setsockopt helper function,
   419  	// for example to change MTU or buffer sizes of the socket.
   420  	BPF_PROG_TYPE_SOCK_OPS
   421  	BPF_PROG_TYPE_SK_SKB
   422  	BPF_PROG_TYPE_CGROUP_DEVICE
   423  	BPF_PROG_TYPE_SK_MSG
   424  	// BPF_PROG_TYPE_RAW_TRACEPOINT program type attaches to tracepoints like the BPF_PROG_TYPE_TRACEPOINT type
   425  	// accept the context passed into the eBPF function can be used to access kernel internal arguments of the
   426  	// tracepoint in their raw form.
   427  	// https://github.com/torvalds/linux/commit/c4f6699dfcb8558d138fe838f741b2c10f416cf9
   428  	BPF_PROG_TYPE_RAW_TRACEPOINT
   429  	BPF_PROG_TYPE_CGROUP_SOCK_ADDR
   430  	BPF_PROG_TYPE_LWT_SEG6LOCAL
   431  	// BPF_PROG_TYPE_LIRC_MODE2 program type attaches to a LIRC(Linux Infra Red Controller) device.
   432  	// The main purpose of this program type is to allow for custom IR encoding/decoding implemented in eBPF.
   433  	// https://github.com/torvalds/linux/commit/f4364dcfc86df7c1ca47b256eaf6b6d0cdd0d936
   434  	BPF_PROG_TYPE_LIRC_MODE2
   435  	// BPF_PROG_TYPE_SK_REUSEPORT program type attaches to a socket with the SO_REUSEPORT option set. The eBPF program
   436  	// is triggered on every connection/datagram and can descide which sockets gets it, whereas without a eBPF program
   437  	// the process is based on round-robin balancing.
   438  	// https://github.com/torvalds/linux/commit/2dbb9b9e6df67d444fbe425c7f6014858d337adf
   439  	BPF_PROG_TYPE_SK_REUSEPORT
   440  	BPF_PROG_TYPE_FLOW_DISSECTOR
   441  	BPF_PROG_TYPE_CGROUP_SYSCTL
   442  	// BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE is almost identical to BPF_PROG_TYPE_RAW_TRACEPOINT accept it allows
   443  	// the eBPF program to write into a buffer provided by the tracepoint.
   444  	// The purpose of this is not clear at the moment.
   445  	// https://github.com/torvalds/linux/commit/9df1c28bb75217b244257152ab7d788bb2a386d0
   446  	BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE
   447  	BPF_PROG_TYPE_CGROUP_SOCKOPT
   448  	// BPF_PROG_TYPE_TRACING program type replaces BPF_PROG_TYPE_RAW_TRACEPOINT+BTF information.
   449  	// https://github.com/torvalds/linux/commit/f1b9509c2fb0ef4db8d22dac9aef8e856a5d81f6
   450  	BPF_PROG_TYPE_TRACING
   451  	// BPF_PROG_TYPE_STRUCT_OPS program type allows us to replace certain kernel's struct ops (i.e. func ptr) with
   452  	// our own eBPF programs. Main purpose is to change default kernel behavior, the first use case cited is to replace
   453  	// functions in struct tcp_congestion_ops thus changeing kernel behavior during TCP congestion.
   454  	// https://github.com/torvalds/linux/commit/27ae7997a66174cb8afd6a75b3989f5e0c1b9e5a
   455  	BPF_PROG_TYPE_STRUCT_OPS
   456  	// BPF_PROG_TYPE_EXT program type can be used to extend/replace logic in eBPF programs that are loaded into the
   457  	// kernel. This presumably allows you to swap out functions in running programs instead of having the replace the
   458  	// full program.
   459  	// https://github.com/torvalds/linux/commit/be8704ff07d2374bcc5c675526f95e70c6459683
   460  	BPF_PROG_TYPE_EXT
   461  	// BPF_PROG_TYPE_LSM program type attaches to LSM(Linux security module) hooks, these are the same hooks as used
   462  	// by AppArmour and SELinux. This basically means this allows userspace applications to implement security features
   463  	// akin to AppArmour and SELinux but without the need for kernel modules or kernel changes.
   464  	// https://github.com/torvalds/linux/commit/fc611f47f2188ade2b48ff6902d5cce8baac0c58
   465  	BPF_PROG_TYPE_LSM
   466  	// BPF_PROG_TYPE_SK_LOOKUP program types attaches to a network namespace. It can be used to overwrite the native
   467  	// socket lookup process for connection oriented protocols. This gives us the ability to for example send traffic
   468  	// for a specific IP to a socket no matter the destination port, something that is impossible with regular port
   469  	// lookups.
   470  	// https://github.com/torvalds/linux/commit/e9ddbb7707ff5891616240026062b8c1e29864ca
   471  	BPF_PROG_TYPE_SK_LOOKUP
   472  	BPF_PROG_TYPE_SYSCALL
   473  )
   474  
   475  var bpfProgTypeToStr = map[BPFProgType]string{
   476  	BPF_PROG_TYPE_UNSPEC:                  "BPF_PROG_TYPE_UNSPEC",
   477  	BPF_PROG_TYPE_SOCKET_FILTER:           "BPF_PROG_TYPE_SOCKET_FILTER",
   478  	BPF_PROG_TYPE_KPROBE:                  "BPF_PROG_TYPE_KPROBE",
   479  	BPF_PROG_TYPE_SCHED_CLS:               "BPF_PROG_TYPE_SCHED_CLS",
   480  	BPF_PROG_TYPE_SCHED_ACT:               "BPF_PROG_TYPE_SCHED_ACT",
   481  	BPF_PROG_TYPE_TRACEPOINT:              "BPF_PROG_TYPE_TRACEPOINT",
   482  	BPF_PROG_TYPE_XDP:                     "BPF_PROG_TYPE_XDP",
   483  	BPF_PROG_TYPE_PERF_EVENT:              "BPF_PROG_TYPE_PERF_EVENT",
   484  	BPF_PROG_TYPE_CGROUP_SKB:              "BPF_PROG_TYPE_CGROUP_SKB",
   485  	BPF_PROG_TYPE_CGROUP_SOCK:             "BPF_PROG_TYPE_CGROUP_SOCK",
   486  	BPF_PROG_TYPE_LWT_IN:                  "BPF_PROG_TYPE_LWT_IN",
   487  	BPF_PROG_TYPE_LWT_OUT:                 "BPF_PROG_TYPE_LWT_OUT",
   488  	BPF_PROG_TYPE_LWT_XMIT:                "BPF_PROG_TYPE_LWT_XMIT",
   489  	BPF_PROG_TYPE_SOCK_OPS:                "BPF_PROG_TYPE_SOCK_OPS",
   490  	BPF_PROG_TYPE_SK_SKB:                  "BPF_PROG_TYPE_SK_SKB",
   491  	BPF_PROG_TYPE_CGROUP_DEVICE:           "BPF_PROG_TYPE_CGROUP_DEVICE",
   492  	BPF_PROG_TYPE_SK_MSG:                  "BPF_PROG_TYPE_SK_MSG",
   493  	BPF_PROG_TYPE_RAW_TRACEPOINT:          "BPF_PROG_TYPE_RAW_TRACEPOINT",
   494  	BPF_PROG_TYPE_CGROUP_SOCK_ADDR:        "BPF_PROG_TYPE_CGROUP_SOCK_ADDR",
   495  	BPF_PROG_TYPE_LWT_SEG6LOCAL:           "BPF_PROG_TYPE_LWT_SEG6LOCAL",
   496  	BPF_PROG_TYPE_LIRC_MODE2:              "BPF_PROG_TYPE_LIRC_MODE2",
   497  	BPF_PROG_TYPE_SK_REUSEPORT:            "BPF_PROG_TYPE_SK_REUSEPORT",
   498  	BPF_PROG_TYPE_FLOW_DISSECTOR:          "BPF_PROG_TYPE_FLOW_DISSECTOR",
   499  	BPF_PROG_TYPE_CGROUP_SYSCTL:           "BPF_PROG_TYPE_CGROUP_SYSCTL",
   500  	BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE: "BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE",
   501  	BPF_PROG_TYPE_CGROUP_SOCKOPT:          "BPF_PROG_TYPE_CGROUP_SOCKOPT",
   502  	BPF_PROG_TYPE_TRACING:                 "BPF_PROG_TYPE_TRACING",
   503  	BPF_PROG_TYPE_STRUCT_OPS:              "BPF_PROG_TYPE_STRUCT_OPS",
   504  	BPF_PROG_TYPE_EXT:                     "BPF_PROG_TYPE_EXT",
   505  	BPF_PROG_TYPE_LSM:                     "BPF_PROG_TYPE_LSM",
   506  	BPF_PROG_TYPE_SK_LOOKUP:               "BPF_PROG_TYPE_SK_LOOKUP",
   507  	BPF_PROG_TYPE_SYSCALL:                 "BPF_PROG_TYPE_SYSCALL",
   508  }
   509  
   510  func (pt BPFProgType) String() string {
   511  	str := bpfProgTypeToStr[pt]
   512  	if str == "" {
   513  		return "UNKNOWN"
   514  	}
   515  
   516  	return str
   517  }
   518  
   519  // BPFAttachType describes to what type of hook the eBPF program will attach to.
   520  // https://github.com/torvalds/linux/blob/master/include/uapi/linux/bpf.h#L211
   521  type BPFAttachType uint32
   522  
   523  //nolint:revive // I don't know the meaning of all of these consts yet
   524  const (
   525  	// BPF_CGROUP_INET_INGRESS is used to attach a BPF_PROG_TYPE_CGROUP_SKB program to the ingress IP traffic
   526  	// of a cgroup
   527  	BPF_CGROUP_INET_INGRESS BPFAttachType = iota
   528  	// BPF_CGROUP_INET_EGRESS is used to attach a BPF_PROG_TYPE_CGROUP_SKB program to the egress IP traffic
   529  	// of a cgroup
   530  	BPF_CGROUP_INET_EGRESS
   531  	// BPF_CGROUP_INET_SOCK_CREATE is used to attach a BPF_PROG_TYPE_CGROUP_SOCK program to the socket create
   532  	// operation of a cgroup. Meaning the program will be called for every socket to be created.
   533  	BPF_CGROUP_INET_SOCK_CREATE
   534  	BPF_CGROUP_SOCK_OPS
   535  	BPF_SK_SKB_STREAM_PARSER
   536  	BPF_SK_SKB_STREAM_VERDICT
   537  	BPF_CGROUP_DEVICE
   538  	BPF_SK_MSG_VERDICT
   539  	BPF_CGROUP_INET4_BIND
   540  	BPF_CGROUP_INET6_BIND
   541  	BPF_CGROUP_INET4_CONNECT
   542  	BPF_CGROUP_INET6_CONNECT
   543  	BPF_CGROUP_INET4_POST_BIND
   544  	BPF_CGROUP_INET6_POST_BIND
   545  	BPF_CGROUP_UDP4_SENDMSG
   546  	BPF_CGROUP_UDP6_SENDMSG
   547  	BPF_LIRC_MODE2
   548  	BPF_FLOW_DISSECTOR
   549  	BPF_CGROUP_SYSCTL
   550  	BPF_CGROUP_UDP4_RECVMSG
   551  	BPF_CGROUP_UDP6_RECVMSG
   552  	BPF_CGROUP_GETSOCKOPT
   553  	BPF_CGROUP_SETSOCKOPT
   554  	BPF_TRACE_RAW_TP
   555  	BPF_TRACE_FENTRY
   556  	BPF_TRACE_FEXIT
   557  	BPF_MODIFY_RETURN
   558  	BPF_LSM_MAC
   559  	BPF_TRACE_ITER
   560  	BPF_CGROUP_INET4_GETPEERNAME
   561  	BPF_CGROUP_INET6_GETPEERNAME
   562  	BPF_CGROUP_INET4_GETSOCKNAME
   563  	BPF_CGROUP_INET6_GETSOCKNAME
   564  	// BPF_XDP_DEVMAP is set in the expectred attach type of a XDP program when it wants to use a BPF_XDP_DEVMAP.
   565  	BPF_XDP_DEVMAP
   566  	// BPF_CGROUP_INET_SOCK_RELEASE is used to attach a BPF_PROG_TYPE_CGROUP_SOCK program to the socket release
   567  	// operation of a cgroup. Meaning the program will be called for every socket that is released.
   568  	BPF_CGROUP_INET_SOCK_RELEASE
   569  	// BPF_XDP_CPUMAP is set in the expectred attach type of a XDP program when it wants to use a BPF_MAP_TYPE_CPUMAP.
   570  	BPF_XDP_CPUMAP
   571  	BPF_SK_LOOKUP
   572  	// BPF_XDP is used to attach a BPF_PROG_TYPE_XDP program using a link.
   573  	BPF_XDP
   574  	BPF_SK_SKB_VERDICT
   575  	BPF_SK_REUSEPORT_SELECT
   576  	BPF_SK_REUSEPORT_SELECT_OR_MIGRATE
   577  	BPF_PERF_EVENT
   578  )
   579  
   580  var bpfAttachTypeToStr = map[BPFAttachType]string{
   581  	BPF_CGROUP_INET_INGRESS:            "BPF_CGROUP_INET_INGRESS",
   582  	BPF_CGROUP_INET_EGRESS:             "BPF_CGROUP_INET_EGRESS",
   583  	BPF_CGROUP_INET_SOCK_CREATE:        "BPF_CGROUP_INET_SOCK_CREATE",
   584  	BPF_CGROUP_SOCK_OPS:                "BPF_CGROUP_SOCK_OPS",
   585  	BPF_SK_SKB_STREAM_PARSER:           "BPF_SK_SKB_STREAM_PARSER",
   586  	BPF_SK_SKB_STREAM_VERDICT:          "BPF_SK_SKB_STREAM_VERDICT",
   587  	BPF_CGROUP_DEVICE:                  "BPF_CGROUP_DEVICE",
   588  	BPF_SK_MSG_VERDICT:                 "BPF_SK_MSG_VERDICT",
   589  	BPF_CGROUP_INET4_BIND:              "BPF_CGROUP_INET4_BIND",
   590  	BPF_CGROUP_INET6_BIND:              "BPF_CGROUP_INET6_BIND",
   591  	BPF_CGROUP_INET4_CONNECT:           "BPF_CGROUP_INET4_CONNECT",
   592  	BPF_CGROUP_INET6_CONNECT:           "BPF_CGROUP_INET6_CONNECT",
   593  	BPF_CGROUP_INET4_POST_BIND:         "BPF_CGROUP_INET4_POST_BIND",
   594  	BPF_CGROUP_INET6_POST_BIND:         "BPF_CGROUP_INET6_POST_BIND",
   595  	BPF_CGROUP_UDP4_SENDMSG:            "BPF_CGROUP_UDP4_SENDMSG",
   596  	BPF_CGROUP_UDP6_SENDMSG:            "BPF_CGROUP_UDP6_SENDMSG",
   597  	BPF_LIRC_MODE2:                     "BPF_LIRC_MODE2",
   598  	BPF_FLOW_DISSECTOR:                 "BPF_FLOW_DISSECTOR",
   599  	BPF_CGROUP_SYSCTL:                  "BPF_CGROUP_SYSCTL",
   600  	BPF_CGROUP_UDP4_RECVMSG:            "BPF_CGROUP_UDP4_RECVMSG",
   601  	BPF_CGROUP_UDP6_RECVMSG:            "BPF_CGROUP_UDP6_RECVMSG",
   602  	BPF_CGROUP_GETSOCKOPT:              "BPF_CGROUP_GETSOCKOPT",
   603  	BPF_CGROUP_SETSOCKOPT:              "BPF_CGROUP_SETSOCKOPT",
   604  	BPF_TRACE_RAW_TP:                   "BPF_TRACE_RAW_TP",
   605  	BPF_TRACE_FENTRY:                   "BPF_TRACE_FENTRY",
   606  	BPF_TRACE_FEXIT:                    "BPF_TRACE_FEXIT",
   607  	BPF_MODIFY_RETURN:                  "BPF_MODIFY_RETURN",
   608  	BPF_LSM_MAC:                        "BPF_LSM_MAC",
   609  	BPF_TRACE_ITER:                     "BPF_TRACE_ITER",
   610  	BPF_CGROUP_INET4_GETPEERNAME:       "BPF_CGROUP_INET4_GETPEERNAME",
   611  	BPF_CGROUP_INET6_GETPEERNAME:       "BPF_CGROUP_INET6_GETPEERNAME",
   612  	BPF_CGROUP_INET4_GETSOCKNAME:       "BPF_CGROUP_INET4_GETSOCKNAME",
   613  	BPF_CGROUP_INET6_GETSOCKNAME:       "BPF_CGROUP_INET6_GETSOCKNAME",
   614  	BPF_XDP_DEVMAP:                     "BPF_XDP_DEVMAP",
   615  	BPF_CGROUP_INET_SOCK_RELEASE:       "BPF_CGROUP_INET_SOCK_RELEASE",
   616  	BPF_XDP_CPUMAP:                     "BPF_XDP_CPUMAP",
   617  	BPF_SK_LOOKUP:                      "BPF_SK_LOOKUP",
   618  	BPF_XDP:                            "BPF_XDP",
   619  	BPF_SK_SKB_VERDICT:                 "BPF_SK_SKB_VERDICT",
   620  	BPF_SK_REUSEPORT_SELECT:            "BPF_SK_REUSEPORT_SELECT",
   621  	BPF_SK_REUSEPORT_SELECT_OR_MIGRATE: "BPF_SK_REUSEPORT_SELECT_OR_MIGRATE",
   622  	BPF_PERF_EVENT:                     "BPF_PERF_EVENT",
   623  }
   624  
   625  func (at BPFAttachType) String() string {
   626  	str := bpfAttachTypeToStr[at]
   627  	if str == "" {
   628  		return "UNKNOWN"
   629  	}
   630  
   631  	return str
   632  }
   633  
   634  // BPFLinkType describes how a program should be link in attributes for the BPF_LINK_* commands
   635  type BPFLinkType uint32
   636  
   637  const (
   638  	// BPF_LINK_TYPE_UNSPEC zero/default value which is invalid
   639  	BPF_LINK_TYPE_UNSPEC BPFLinkType = iota
   640  	// BPF_LINK_TYPE_RAW_TRACEPOINT a program should be attached to a raw tracepoint
   641  	BPF_LINK_TYPE_RAW_TRACEPOINT
   642  	// BPF_LINK_TYPE_TRACING a program should be attached as tracing program.
   643  	// Can be a few program types like kprobe and LSM.
   644  	BPF_LINK_TYPE_TRACING
   645  	// BPF_LINK_TYPE_CGROUP a program should be attached to a cGroup
   646  	BPF_LINK_TYPE_CGROUP
   647  	// BPF_LINK_TYPE_ITER a program should be attached as a kernel structure iterator
   648  	BPF_LINK_TYPE_ITER
   649  	// BPF_LINK_TYPE_NETNS a program should be attached to a network namespace
   650  	BPF_LINK_TYPE_NETNS
   651  	// BPF_LINK_TYPE_XDP a program should be attached to a network device
   652  	BPF_LINK_TYPE_XDP
   653  	// BPF_LINK_TYPE_PERF_EVENT a program should be attached to a hardware or software perf event
   654  	BPF_LINK_TYPE_PERF_EVENT
   655  )
   656  
   657  var bpfLinkTypeToStr = map[BPFLinkType]string{
   658  	BPF_LINK_TYPE_UNSPEC:         "BPF_LINK_TYPE_UNSPEC",
   659  	BPF_LINK_TYPE_RAW_TRACEPOINT: "BPF_LINK_TYPE_RAW_TRACEPOINT",
   660  	BPF_LINK_TYPE_TRACING:        "BPF_LINK_TYPE_TRACING",
   661  	BPF_LINK_TYPE_CGROUP:         "BPF_LINK_TYPE_CGROUP",
   662  	BPF_LINK_TYPE_ITER:           "BPF_LINK_TYPE_ITER",
   663  	BPF_LINK_TYPE_NETNS:          "BPF_LINK_TYPE_NETNS",
   664  	BPF_LINK_TYPE_XDP:            "BPF_LINK_TYPE_XDP",
   665  	BPF_LINK_TYPE_PERF_EVENT:     "BPF_LINK_TYPE_PERF_EVENT",
   666  }
   667  
   668  func (lt BPFLinkType) String() string {
   669  	str := bpfLinkTypeToStr[lt]
   670  	if str == "" {
   671  		return "UNKNOWN"
   672  	}
   673  
   674  	return str
   675  }
   676  
   677  type BPFTaskFDType uint32
   678  
   679  //nolint:revive // i don't fully understand the meaning of these consts yet
   680  const (
   681  	BPF_FD_TYPE_RAW_TRACEPOINT BPFTaskFDType = iota
   682  	BPF_FD_TYPE_TRACEPOINT
   683  	BPF_FD_TYPE_KPROBE
   684  	BPF_FD_TYPE_KRETPROBE
   685  	BPF_FD_TYPE_UPROBE
   686  	BPF_FD_TYPE_URETPROBE
   687  )
   688  
   689  var bpfTaskFDTypeToStr = map[BPFTaskFDType]string{
   690  	BPF_FD_TYPE_RAW_TRACEPOINT: "BPF_FD_TYPE_RAW_TRACEPOINT",
   691  	BPF_FD_TYPE_TRACEPOINT:     "BPF_FD_TYPE_TRACEPOINT",
   692  	BPF_FD_TYPE_KPROBE:         "BPF_FD_TYPE_KPROBE",
   693  	BPF_FD_TYPE_KRETPROBE:      "BPF_FD_TYPE_KRETPROBE",
   694  	BPF_FD_TYPE_UPROBE:         "BPF_FD_TYPE_UPROBE",
   695  	BPF_FD_TYPE_URETPROBE:      "BPF_FD_TYPE_URETPROBE",
   696  }
   697  
   698  func (ft BPFTaskFDType) String() string {
   699  	str := bpfTaskFDTypeToStr[ft]
   700  	if str == "" {
   701  		return "UNKNOWN"
   702  	}
   703  
   704  	return str
   705  }
   706  
   707  /* BPFProgAttachFlags cgroup-bpf attach flags used in BPF_PROG_ATTACH command
   708   *
   709   * NONE(default): No further bpf programs allowed in the subtree.
   710   *
   711   * BPF_F_ALLOW_OVERRIDE: If a sub-cgroup installs some bpf program,
   712   * the program in this cgroup yields to sub-cgroup program.
   713   *
   714   * BPF_F_ALLOW_MULTI: If a sub-cgroup installs some bpf program,
   715   * that cgroup program gets run in addition to the program in this cgroup.
   716   *
   717   * Only one program is allowed to be attached to a cgroup with
   718   * NONE or BPF_F_ALLOW_OVERRIDE flag.
   719   * Attaching another program on top of NONE or BPF_F_ALLOW_OVERRIDE will
   720   * release old program and attach the new one. Attach flags has to match.
   721   *
   722   * Multiple programs are allowed to be attached to a cgroup with
   723   * BPF_F_ALLOW_MULTI flag. They are executed in FIFO order
   724   * (those that were attached first, run first)
   725   * The programs of sub-cgroup are executed first, then programs of
   726   * this cgroup and then programs of parent cgroup.
   727   * When children program makes decision (like picking TCP CA or sock bind)
   728   * parent program has a chance to override it.
   729   *
   730   * With BPF_F_ALLOW_MULTI a new program is added to the end of the list of
   731   * programs for a cgroup. Though it's possible to replace an old program at
   732   * any position by also specifying BPF_F_REPLACE flag and position itself in
   733   * replace_bpf_fd attribute. Old program at this position will be released.
   734   *
   735   * A cgroup with MULTI or OVERRIDE flag allows any attach flags in sub-cgroups.
   736   * A cgroup with NONE doesn't allow any programs in sub-cgroups.
   737   * Ex1:
   738   * cgrp1 (MULTI progs A, B) ->
   739   *    cgrp2 (OVERRIDE prog C) ->
   740   *      cgrp3 (MULTI prog D) ->
   741   *        cgrp4 (OVERRIDE prog E) ->
   742   *          cgrp5 (NONE prog F)
   743   * the event in cgrp5 triggers execution of F,D,A,B in that order.
   744   * if prog F is detached, the execution is E,D,A,B
   745   * if prog F and D are detached, the execution is E,A,B
   746   * if prog F, E and D are detached, the execution is C,A,B
   747   *
   748   * All eligible programs are executed regardless of return code from
   749   * earlier programs.
   750   */
   751  type BPFProgAttachFlags uint32
   752  
   753  const (
   754  	// BPFProgAttachAllowOverride if a sub-cgroup installs some bpf program, the program in this cgroup yields
   755  	// to sub-cgroup program.
   756  	BPFProgAttachAllowOverride BPFProgAttachFlags = 1 << iota
   757  	// BPFProgAttachAllowMulti If a sub-cgroup installs some bpf program,
   758  	// that cgroup program gets run in addition to the program in this cgroup.
   759  	BPFProgAttachAllowMulti
   760  	// BPFProgAttachReplace with BPF_F_ALLOW_MULTI a new program is added to the end of the list of
   761  	// programs for a cgroup. Though it's possible to replace an old program at
   762  	// any position by also specifying BPF_F_REPLACE flag and position itself in
   763  	// replace_bpf_fd attribute. Old program at this position will be released.
   764  	BPFProgAttachReplace
   765  )
   766  
   767  // BPFLogLevel the verifier log level
   768  // https://github.com/torvalds/linux/blob/master/include/linux/bpf_verifier.h#L360
   769  type BPFLogLevel uint32
   770  
   771  const (
   772  	// BPFLogLevelDisabled disables the verifier log
   773  	BPFLogLevelDisabled BPFLogLevel = iota
   774  	// BPFLogLevelBasic instructs the verifier to output basic logs
   775  	BPFLogLevelBasic
   776  	// BPFLogLevelVerbose the most verbose log level available
   777  	BPFLogLevelVerbose
   778  )
   779  
   780  type BPFProgLoadFlags uint32
   781  
   782  const (
   783  	/* BPFProgLoadStrictAlignment is used in BPF_PROG_LOAD command, the
   784  	* verifier will perform strict alignment checking as if the kernel
   785  	* has been built with CONFIG_EFFICIENT_UNALIGNED_ACCESS not set,
   786  	* and NET_IP_ALIGN defined to 2.
   787  	 */
   788  	BPFProgLoadStrictAlignment BPFProgLoadFlags = 1 << iota
   789  
   790  	/* BPFProgLoadAnyAlignment is used in BPF_PROF_LOAD command, the
   791  	 * verifier will allow any alignment whatsoever.  On platforms
   792  	 * with strict alignment requirements for loads ands stores (such
   793  	 * as sparc and mips) the verifier validates that all loads and
   794  	 * stores provably follow this requirement.  This flag turns that
   795  	 * checking and enforcement off.
   796  	 *
   797  	 * It is mostly used for testing when we want to validate the
   798  	 * context and memory access aspects of the verifier, but because
   799  	 * of an unaligned access the alignment check would trigger before
   800  	 * the one we are interested in.
   801  	 */
   802  	BPFProgLoadAnyAlignment
   803  
   804  	/* BPFProgLoadTestRndHI32 is used in BPF_PROG_LOAD command for testing purpose.
   805  	 * Verifier does sub-register def/use analysis and identifies instructions whose
   806  	 * def only matters for low 32-bit, high 32-bit is never referenced later
   807  	 * through implicit zero extension. Therefore verifier notifies JIT back-ends
   808  	 * that it is safe to ignore clearing high 32-bit for these instructions. This
   809  	 * saves some back-ends a lot of code-gen. However such optimization is not
   810  	 * necessary on some arches, for example x86_64, arm64 etc, whose JIT back-ends
   811  	 * hence hasn't used verifier's analysis result. But, we really want to have a
   812  	 * way to be able to verify the correctness of the described optimization on
   813  	 * x86_64 on which testsuites are frequently exercised.
   814  	 *
   815  	 * So, this flag is introduced. Once it is set, verifier will randomize high
   816  	 * 32-bit for those instructions who has been identified as safe to ignore them.
   817  	 * Then, if verifier is not doing correct analysis, such randomization will
   818  	 * regress tests to expose bugs.
   819  	 */
   820  	BPFProgLoadTestRndHI32
   821  
   822  	/* BPFProgLoadTestStateFreq is the verifier internal test flag. Behavior is undefined */
   823  	BPFProgLoadTestStateFreq
   824  
   825  	/* BPFProgLoadSleepable can be used in BPF_PROG_LOAD command, the verifier will
   826  	 * restrict map and helper usage for such programs. Sleepable BPF programs can
   827  	 * only be attached to hooks where kernel execution context allows sleeping.
   828  	 * Such programs are allowed to use helpers that may sleep like
   829  	 * bpf_copy_from_user().
   830  	 */
   831  	BPFProgLoadSleepable
   832  )
   833  
   834  const BPF_TAG_SIZE = 8
   835  
   836  // BPFProgInfoSize is the size of BPFProgInfo in bytes
   837  var BPFProgInfoSize = int(unsafe.Sizeof(BPFProgInfo{}))
   838  
   839  // BPFProgInfo is the structure used by the kernel to communicate program information back to
   840  // userspace when calling the BPF_OBJ_GET_INFO_BY_FD command with a program file descriptor. Based on
   841  // https://github.com/torvalds/linux/blob/e49d033bddf5b565044e2abe4241353959bc9120/include/uapi/linux/bpf.h#L4548
   842  type BPFProgInfo struct {
   843  	Type                 BPFProgType
   844  	ID                   uint32
   845  	Tag                  [BPF_TAG_SIZE]byte
   846  	JitedProgLen         uint32
   847  	XlatedProgLen        uint32
   848  	JitedProgInsns       uintptr
   849  	XlatedProgInsns      uintptr
   850  	LoadTime             uint64
   851  	CreatedByUID         uint32
   852  	NumMapIDs            uint32
   853  	MapIDs               uintptr
   854  	Name                 [BPF_OBJ_NAME_LEN]byte
   855  	IfIndex              uint32
   856  	Flags                BPFProgInfoFlags
   857  	NetNSDev             uint64
   858  	NetNSIno             uint64
   859  	NumJitedKSyms        uint32
   860  	NumJitedFuncLens     uint32
   861  	JitedKsyms           uintptr
   862  	JitedFuncLens        uintptr
   863  	BTFID                uint32
   864  	FuncInfoRecSize      uint32
   865  	FuncInfo             uintptr
   866  	NumFuncInfo          uint32
   867  	NumLineInfo          uint32
   868  	LineInfo             uintptr
   869  	JitedLineInfo        uintptr
   870  	NumJitedLineInfo     uint32
   871  	LineInfoRecSize      uint32
   872  	JitedLineInfoRecSize uint32
   873  	NumProgTags          uint32
   874  	ProgTags             uintptr
   875  	RunTimeNs            uint64
   876  	RunCnt               uint64
   877  	RecursionMisses      uint64
   878  }
   879  
   880  // BPFProgInfoFlags a alignment hole was used for additional flags, since the comment says
   881  // this value may contain extra flags in the future this custom type was created.
   882  // This will hopefully allow for more compatibility
   883  // https://github.com/torvalds/linux/commit/b85fab0e67b162014cd328cb4e2a8e8ae382cb8a
   884  type BPFProgInfoFlags uint32
   885  
   886  const (
   887  	// ProgInfoFlagGPLCompatible indicates that a program is GPL compatible
   888  	ProgInfoFlagGPLCompatible BPFProgInfoFlags = 1 << iota
   889  )
   890  
   891  // BPFMapInfoSize is the size of the BPFMapInfo struct in bytes
   892  var BPFMapInfoSize = int(unsafe.Sizeof(BPFMapInfo{}))
   893  
   894  type BPFMapInfo struct {
   895  	Type       BPFMapType
   896  	ID         uint32
   897  	KeySize    uint32
   898  	ValueSize  uint32
   899  	MaxEntries uint32
   900  	MapFlags   uint32
   901  	Name       [BPF_OBJ_NAME_LEN]byte
   902  	IfIndex    uint32
   903  	NetNSDev   uint64
   904  	NetNSIno   uint64
   905  }
   906  
   907  type BPFFuncInfo struct {
   908  	InstructionOffset uint32
   909  	TypeID            uint32
   910  }
   911  
   912  type BPFLineInfo struct {
   913  	InstructionOffset uint32
   914  	FileNameOffset    uint32
   915  	LineOffset        uint32
   916  	ColumnOffset      uint32
   917  }
   918  
   919  type BPFMapFlags uint32
   920  
   921  const (
   922  	// BPFMapFlagsNoPreAlloc is a flag that signals that the memory for a map should not be allocated when it is
   923  	// created but rather at runtime. NOTE this only works for non-array maps
   924  	BPFMapFlagsNoPreAlloc BPFMapFlags = 1 << iota
   925  	// BPFMapFlagsNoCommonLRU is a flag that signals that instead of having one common LRU list in the
   926  	// BPF_MAP_TYPE_LRU_[PERCPU_]HASH map, use a percpu LRU list which can scale and perform better.
   927  	// Note, the LRU nodes (including free nodes) cannot be moved across different LRU lists.
   928  	BPFMapFlagsNoCommonLRU
   929  	// BPFMapFlagsNUMANode is a flag that signals that a numa node may be specified during map creation
   930  	BPFMapFlagsNUMANode
   931  	// BPFMapFlagsReadOnly is a flag that signals that the userspace may not write to this map
   932  	BPFMapFlagsReadOnly
   933  	// BPFMapFlagsWriteOnly is a flag that signals that the userspace may not read from this map
   934  	BPFMapFlagsWriteOnly
   935  	// BPFMapFlagsStackBuildID is a flag for stack_map that signals to store build_id+offset instead of pointer
   936  	BPFMapFlagsStackBuildID
   937  	// BPFMapFlagsZeroSeed is a flag that signals to zero-initialize hash function seed.
   938  	// This should only be used for testing.
   939  	BPFMapFlagsZeroSeed
   940  	// BPFMapFlagsReadOnlyProg is a flag that signals that the eBPF program may not write to this map
   941  	BPFMapFlagsReadOnlyProg
   942  	// BPFMapFlagsWriteOnlyProg is a flag that signals that the eBPF program may not write to this map
   943  	BPFMapFlagsWriteOnlyProg
   944  	// BPFMapFlagsClone is a flag that signals to clone the map from listener for newly accepted socket
   945  	BPFMapFlagsClone
   946  	// BPFMapFlagsMMapable is a flag that enables memory-mapping BPF map
   947  	BPFMapFlagsMMapable
   948  	// BPFMapFlagsPreserveElems is a flag that signals the kernel to share perf_event among processes
   949  	BPFMapFlagsPreserveElems
   950  	// BPFMapFlagsInnerMap  is a flag that signals the kernel to create a map that is suitable to be an inner map
   951  	// with dynamic max entries. Map-in-map types created without this flag can only ever contain maps with
   952  	// a number of max entries equal to the inner map definition used during loading of the outer map.
   953  	BPFMapFlagsInnerMap
   954  	// BPFMapFlagsMax is a pseudo flag used for iteration within the library and should not be used
   955  	BPFMapFlagsMax
   956  )
   957  
   958  var mapDefFlagToStr = map[BPFMapFlags]string{
   959  	BPFMapFlagsNoPreAlloc:    "BPFMapFlagsNoPreAlloc",
   960  	BPFMapFlagsNoCommonLRU:   "BPFMapFlagsNoCommonLRU",
   961  	BPFMapFlagsNUMANode:      "BPFMapFlagsNUMANode",
   962  	BPFMapFlagsReadOnly:      "BPFMapFlagsReadOnly",
   963  	BPFMapFlagsWriteOnly:     "BPFMapFlagsWriteOnly",
   964  	BPFMapFlagsStackBuildID:  "BPFMapFlagsStackBuildID",
   965  	BPFMapFlagsZeroSeed:      "BPFMapFlagsZeroSeed",
   966  	BPFMapFlagsReadOnlyProg:  "BPFMapFlagsReadOnlyProg",
   967  	BPFMapFlagsWriteOnlyProg: "BPFMapFlagsWriteOnlyProg",
   968  	BPFMapFlagsClone:         "BPFMapFlagsClone",
   969  	BPFMapFlagsMMapable:      "BPFMapFlagsMMapable",
   970  	BPFMapFlagsPreserveElems: "BPFMapFlagsPreserveElems",
   971  	BPFMapFlagsInnerMap:      "BPFMapFlagsInnerMap",
   972  }
   973  
   974  func (f BPFMapFlags) String() string {
   975  	var flags []string
   976  
   977  	for flag := BPFMapFlagsNoPreAlloc; flag < BPFMapFlagsMax; flag = flag << 1 {
   978  		if f&flag > 0 {
   979  			flags = append(flags, mapDefFlagToStr[flag])
   980  		}
   981  	}
   982  
   983  	if len(flags) == 0 {
   984  		return "(none)"
   985  	}
   986  
   987  	return strings.Join(flags, "|")
   988  }