github.com/inspektor-gadget/inspektor-gadget@v0.28.1/docs/design/002-containerized-gadgets.md (about)

     1  # Containerized Gadgets Support Inspektor Gadget
     2  
     3  The gadgets we provide are heavily coupled to Inspektor Gadget as they are all developed on the same
     4  repository and maintained by our team. Adding new gadgets implies that they have to be reviewed and
     5  approved by us. This approach presents some disadvantages:
     6  - Users need to install new versions of Inspektor Gadget to get new gadgets (or updates to them).
     7  - Too specific gadgets can't be added to our code base.
     8  - Users can't have private gadgets.
     9  
    10  The [containerized gadgets idea](https://github.com/inspektor-gadget/inspektor-gadget/issues/1669)
    11  aims to make Inspektor Gadget a framework to run eBPF programs (gadgets), like Docker does for
    12  containers. This approach decouples the gadgets from Inspektor Gadget solving the issues mentioned
    13  above.
    14  
    15  Many ideas of this design document are based on [bumblebee](https://github.com/solo-io/bumblebee)
    16  and [ebpf_exporter](https://github.com/cloudflare/ebpf_exporter) projects.
    17  
    18  ## User Experience
    19  
    20  The UX we provide should be very close to the existing container runtimes like Docker. This document
    21  considers the client-server setup for ig described in
    22  https://github.com/inspektor-gadget/inspektor-gadget/issues/1681. It's being implemented at the time
    23  of writing this document.
    24  
    25  ### `run`
    26  
    27  The run command starts a gadget:
    28  
    29  ```bash
    30  $ gadgetctl run mygadgetimage:latest
    31  # print output to terminal
    32  ```
    33  
    34  `mygadgetimage:latest` is a gadget OCI image.
    35  This command should provide a flag to run on detached mode:
    36  
    37  ```bash
    38  $ gadgetctl run mygadgetimage:latest --detach
    39  a3397355fc4b2ba49cdc1ab2d36f728cbda65f0ef979854186f2ea780e8659e1
    40  ```
    41  
    42  This command automatically pulls the image if it is not available in the local image cache.
    43  
    44  ### `list`
    45  
    46  List print the running gadgets
    47  
    48  ```bash
    49  $ gadgetctl list
    50  ...
    51  ```
    52  
    53  ### `attach`
    54  
    55  Attach to a running gadget
    56  
    57  ```bash
    58  $ gadgetctl attach mygadget
    59  # gets terminal attached to the gadget
    60  ```
    61  
    62  ### `pull`
    63  
    64  Pulls a gadget image
    65  
    66  ```bash
    67  $ gadgetctl pull mygadgetimage:latest
    68  ```
    69  
    70  ### `build`
    71  
    72  Builds and packages a gadget as an OCI image
    73  
    74  ```bash
    75  $ gadgetctl build --prog foo.bpf.c --definition foo.yaml mygadgetimage:latest
    76  ```
    77  
    78  Details of this command are still to be defined. Like other flags that are supported.
    79  
    80  ### `tag`
    81  
    82  Tag an image
    83  
    84  ```bash
    85  $ gadgetctl tag mygadgetimage:latest ghcr.io/foo/mygadgetimage:v1
    86  ```
    87  
    88  ### `login`
    89  
    90  Login into a container registry
    91  
    92  ```bash
    93  $ gadgetctl login -u admin -p 1234
    94  ```
    95  
    96  ### `image`
    97  
    98  Different commands to handle images
    99  
   100  - `image list`
   101  - `image delete`
   102  etc...
   103  
   104  TODO: Should commands like `ig pull`, `ig build`, `ig push` be aliases of `ig image ...` ones?
   105  
   106  ## Gadget Packaging
   107  
   108  Gadgets should be packed as [OCI](https://github.com/opencontainers/image-spec) images.
   109  It is expected that the first manifest is an image index `application/vnd.oci.image.index.v1+json`.
   110  All supported architectures has to be listed here
   111  ```bash
   112  $ crane manifest ghcr.io/inspektor-gadget/tcp-connect:test | jq .
   113  {
   114    "schemaVersion": 2,
   115    "mediaType": "application/vnd.oci.image.index.v1+json",
   116    "manifests": [
   117      {
   118        "mediaType": "application/vnd.oci.image.manifest.v1+json",
   119        "digest": "sha256:7138dd1d4599d3e2c010a08e2609d53bea0764809563ff4554b9f4c8116fafef",
   120        "size": 590,
   121        "platform": {
   122          "architecture": "amd64",
   123          "os": "linux"
   124        }
   125      },
   126      {
   127        "mediaType": "application/vnd.oci.image.manifest.v1+json",
   128        "digest": "sha256:9ecb3e8284068ce53d6c359b046ff20febf39f2d05ffa219e4665bd29fef1954",
   129        "size": 590,
   130        "platform": {
   131          "architecture": "arm64",
   132          "os": "linux"
   133        }
   134      }
   135    ]
   136  }
   137  ```
   138  
   139  The manifest referenced by the digest of a specific architecture has a config and a single layer. The content of the config is [the definition file](#def-file).
   140  The currently single layer contains the compiled eBPF program. It supports configurable annotations for the author and description
   141  
   142  Example:
   143  ```bash
   144  $ crane manifest ghcr.io/inspektor-gadget/tcp-connect@sha256:9ecb3e8284068ce53d6c359b046ff20febf39f2d05ffa219e4665bd29fef1954 | jq .
   145  {
   146    "schemaVersion": 2,
   147    "config": {
   148      "mediaType": "application/vnd.gadget.config.v1+yaml",
   149      "digest": "sha256:eb71861c0a5d5ca9a706fffa20fead54f64a1624dfeef5d334a8a3c2462c4c37",
   150      "size": 628,
   151      "annotations": {
   152        "org.opencontainers.image.title": "config.yaml"
   153      }
   154    },
   155    "layers": [
   156      {
   157        "mediaType": "application/vnd.gadget.ebpf.program.v1+binary",
   158        "digest": "sha256:a2e1f232e675b1a8d83f94fc646b40e885564f8346273c3257ac76003545880b",
   159        "size": 873256,
   160        "annotations": {
   161          "org.opencontainers.image.authors": "Burak Ok",
   162          "org.opencontainers.image.description": "A simple tcpconnect program",
   163          "org.opencontainers.image.title": "program.o"
   164        }
   165      }
   166    ]
   167  }
   168  
   169  ```
   170  
   171  
   172  TODO: How the user could specify these annotations when using the build command?
   173  
   174  ### Definition File <a name="def-file"></a>
   175  
   176  The definition file contains the following information for a gadget:
   177  - `documentation`: Long text describing how to use the gadget. This should describe the different
   178    parameters supported and can contain some practical examples about how to use it.
   179  - `columns`: Information about the event that the gadget provides. Each element represents a columns
   180    attribute as defined in pkg/columns/columninfo.go.
   181  
   182  This definition file is mandatory in the early implementation stage, but later on it'll be
   183  optional.
   184  
   185  ## Gadget Implementation
   186  
   187  A gadget is composed by eBPF programs and maps that are compiled into an eBPF ELF object. According
   188  to the names of the maps and programs, and the types used, Inspektor Gadget is able to understand
   189  how to parse, enrich and print information from the gadget.
   190  Inspektor Gadget requires the ELF file to have sections named according to the convention defined in
   191  libbpf and cilium/ebpf.
   192  
   193  Currently the built-in gadgets have a strong categorization, however in this new containerized
   194  gadgets approach that categorization is softer, each gadget defines how it behaves according to the
   195  maps / types they use and it's possible that the same gadget implements different behaviors, like
   196  tracer and topper, etc.
   197  
   198  ### Maps
   199  
   200  #### `RingBuf` and `PerfEventArray` with `print_` Prefix (a.k.a tracers)
   201  
   202  These maps indicate that the gadget produces a stream of events. Inspektor Gadget uses the BTF
   203  information to format and print the events.
   204  
   205  ```c
   206  // taken from gadgets/trace_open.bpf.c
   207  struct event {
   208  	__u64 timestamp;
   209  	__u32 pid;
   210  	__u32 uid;
   211  	__u32 gid;
   212  	gadget_mntns_id mntns_id;
   213  	int ret;
   214  	int flags;
   215  	__u16 mode;
   216  	__u8 comm[TASK_COMM_LEN];
   217  	__u8 fname[NAME_MAX];
   218  };
   219  
   220  struct {
   221  	__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
   222  	__uint(key_size, sizeof(u32));
   223  	__type(value, struct event);
   224  } print_events SEC(".maps");
   225  ```
   226  
   227  NOTE: In libbpf and cilium/ebpf, maps of type RingBuf and PerfEventArray normally have an explicit
   228  definition with:
   229  
   230  ```c
   231  __uint(value_size, sizeof(u32));
   232  ```
   233  
   234  Or an implicit one (when value_size is not defined, the bpf loader understands that RingBuf and
   235  PerfEventArray store a file descriptor, i.e. an integer of size 4).
   236  
   237  However, for containerized gadgets, Inspektor Gadget changes the semantic of the value field in the
   238  map definition to be able to carry the expected BTF type sent to the ring buffers. This idea
   239  initially comes from Bumblebee.
   240  
   241  As a consequence, BPF programs written in this way will not be loadable by generic bpf loaders but
   242  only by Inspektor Gadget.
   243  
   244  TODO: Revisit this appproach and check if there is a way to remove the limitation of being loaded by
   245  other projects.
   246  
   247  #### `HashMap` with `stats_` Prefix (a.k.a toppers)
   248  
   249  These maps are used to implement toppers, i.e. gadgets that print a list of elements sorted by
   250  specific parameters, like TCP connections by sent bytes.
   251  
   252  Inspektor Gadget automatically reads and sorts those maps according to the configuration provided by the user:
   253  - Interval: How often to print the map contents
   254  - Sort by: Field within the event type to sort by
   255  
   256  #### BPF Iterators (a.k.a snapshotters)
   257  
   258  Programs of type `iter/` are automatically loaded and attached by Inspektor Gadget, then they are
   259  triggered one time and its output is parsed according to the BTF information provided by it.
   260  
   261  In order to have BTF information available, the programs have to define an unused variable with the
   262  type they output in the iterator:
   263  
   264  ```c
   265  const volatile event_t myiterator_output = {};
   266  
   267  const struct myevent *gadget_iter_type __attribute__((unused));
   268  
   269  SEC("iter/task_file")
   270  int myiterator(struct bpf_iter__task_file *ctx)
   271  ```
   272  
   273  According to the type of iterator, it's run in different ways:
   274  - iter/task, iter/task_file: relative to the current pid namespace. Inspektor Gadget switches to the
   275    host pid namespace as appropriate to get all processes.
   276  - iter/tcp, iter/udp: relative to the current network namespace. Inspektor Gadget iterates over all
   277    network namespaces of interest and triggers the program in each of them. (containers selected with
   278    the usual filter flags like --container)
   279  - iter/bpf_map_elem: relative to a map. Unsupported.
   280  
   281  #### `HashMap` with `hist_` Prefix (a.k.a profilers)
   282  
   283  These maps are used to implement profilers: gadgets that output a histogram. The histogram collection
   284  starts when the gadget is run, and it's printed when the gadgets stops.
   285  
   286  TODO1: It's possible to also print the histogram periodically, however it's not explored yet.
   287  
   288  TODO2: There is probably some overlap with histogram metrics support for Prometheus. It's very
   289  likely that the same gadget can be used for both purposes.
   290  
   291  #### Prometheus
   292  
   293  TODO: We can heavily base this on https://github.com/cloudflare/ebpf_exporter.
   294  
   295  ##### Counters
   296  
   297  ##### Histograms
   298  
   299  ##### Gauges
   300  
   301  
   302  ### Inspektor Gadget API for Gadgets Developers
   303  
   304  Inspektor Gadget provides some C header defining some types and functions to be used by gadgets.
   305  Those types and functions are used to enable some of the features described below.
   306  
   307  Please check the note in [Support Inspektor Gadget API
   308  changes](#support-inspektor-gadget-api-changes) to get further details about handling changes in
   309  this API.
   310  
   311  #### Data Types and Helper Headers
   312  
   313  Types provided in pkg/gadgets/common/types.h are used to format data in a specific way.
   314  
   315  - `endpoint_t`: Represent an L3 or L4 endpoint. Inspektor Gadget automatically enriches it
   316    with the Kubernetes Pod and/or Service details corresponding to that IP address.
   317  - pkg/gadgets/common/mntns_filter.h: used to filter and enrich data by mount namespace
   318  
   319  ### Types of eBPF programs
   320  
   321  Inspektor Gadget automatically loads and attaches the eBPF programs. The following table describes
   322  the current support and the future plans:
   323  
   324  Symbols:
   325  - ✅: implemented
   326  - 👷: work in progress
   327  - 📅: desired feature, we should plan it
   328  
   329  | ebpf program type     | Support | Difficulty |
   330  |-----------------------|---------|------------|
   331  | socket_filter         |   👷    |            |
   332  | sk_reuseport/migrate  |         |            |
   333  | sk_reuseport          |         |            |
   334  | kprobe/               |   ✅    |            |
   335  | uprobe/               |         |            |
   336  | kretprobe/            |   ✅    |            |
   337  | uretprobe/            |         |            |
   338  | tc                    |         |            |
   339  | classifier            |         |            |
   340  | action                |         |            |
   341  | tracepoint/           |   ✅    |            |
   342  | tp/                   |         |            |
   343  | raw_tracepoint/       |         |            |
   344  | raw_tp/               |         |            |
   345  | raw_tracepoint.w/     |         |            |
   346  | raw_tp.w/             |         |            |
   347  | tp_btf/               |         |            |
   348  | fentry/               |   📅    |            |
   349  | fmod_ret/             |         |            |
   350  | fexit/                |   📅    |            |
   351  | fentry.s/             |         |            |
   352  | fmod_ret.s/           |         |            |
   353  | fexit.s/              |         |            |
   354  | freplace/             |         |            |
   355  | lsm/                  |         |            |
   356  | lsm.s/                |         |            |
   357  | iter/                 |   📅    |            |
   358  | iter.s/               |   📅    |            |
   359  | syscall               |         |            |
   360  | xdp_devmap/           |         |            |
   361  | xdp_cpumap/           |         |            |
   362  | xdp                   |         |            |
   363  | perf_event            |         |            |
   364  | lwt_in                |         |            |
   365  | lwt_out               |         |            |
   366  | lwt_xmit              |         |            |
   367  | lwt_seg6local         |         |            |
   368  | cgroup_skb/ingress    |         |            |
   369  | cgroup_skb/egress     |         |            |
   370  | cgroup/skb            |         |            |
   371  | cgroup/sock_create    |         |            |
   372  | cgroup/sock_release   |         |            |
   373  | cgroup/sock           |         |            |
   374  | cgroup/post_bind4     |         |            |
   375  | cgroup/post_bind6     |         |            |
   376  | cgroup/dev            |         |            |
   377  | sockops               |         |            |
   378  | sk_skb/stream_parser  |         |            |
   379  | sk_skb/stream_verdict |         |            |
   380  | sk_skb                |         |            |
   381  | sk_msg                |         |            |
   382  | lirc_mode2            |         |            |
   383  | flow_dissector        |         |            |
   384  | cgroup/bind4          |         |            |
   385  | cgroup/bind6          |         |            |
   386  | cgroup/connect4       |         |            |
   387  | cgroup/connect6       |         |            |
   388  | cgroup/sendmsg4       |         |            |
   389  | cgroup/sendmsg6       |         |            |
   390  | cgroup/recvmsg4       |         |            |
   391  | cgroup/recvmsg6       |         |            |
   392  | cgroup/getpeername4   |         |            |
   393  | cgroup/getpeername6   |         |            |
   394  | cgroup/getsockname4   |         |            |
   395  | cgroup/getsockname6   |         |            |
   396  | cgroup/sysctl         |         |            |
   397  | cgroup/getsockopt     |         |            |
   398  | cgroup/setsockopt     |         |            |
   399  | struct_ops+           |         |            |
   400  | sk_lookup/            |         |            |
   401  | seccomp               |         |            |
   402  | kprobe.multi          |         |            |
   403  | kretprobe.multi       |         |            |
   404  
   405  List of categories:
   406  * https://github.com/cilium/ebpf/blob/v0.10.0/elf_reader.go#L1073
   407  * https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/tools/lib/bpf/libbpf.c
   408  
   409  ## Gadgets Testing
   410  
   411  Each gadget should take care of its own testing. Inspektor Gadget will provide some framework to
   412  help gadget developers with this, like:
   413  - Integration testing:
   414    https://github.com/inspektor-gadget/inspektor-gadget/blob/main/integration/helpers.go
   415  - Unit tests: https://github.com/inspektor-gadget/inspektor-gadget/tree/main/internal/test
   416  
   417  Inspektor Gadget will use some specific design gadgets for testing purposes to test that all the
   418  APIs and functionality it provides to gadgets is working fine.
   419  
   420  TODO: We need to double check this. IMO we shouldn't be testing external gadgets in Inspektor
   421  Gadget, but there could be different opinions.
   422  
   423  ## Gadgets API
   424  
   425  There are different ways for external applications to consume data provided by gadgets.
   426  
   427  ### Use Inspektor Gadget Daemon / Agent
   428  
   429  NOTE: This is still under big discussion as the API for builtin gadgets is under development at the
   430  time of writing this document.
   431  
   432  In this case, Inspektor Gadget runs as an independent process, as an agent (`ig` case) or as a
   433  DaemonSet (`ig-k8s` case), and the external applications communicates with IG by using its grpc or
   434  other APIs. Those APIs should allow the external application to run a containerized gadget by
   435  passing its image and parameters, and to consume the data the gadget generates.
   436  
   437  The data the gadget generates don't have a specific format as it changes from gadget to gadget,
   438  hence we'll need to use JSON or a similar protocol that allows us to encode unstructured data.
   439  
   440  ### Running Gadgets Directly
   441  
   442  There are some cases where external applications want to run gadgets directly in their processes,
   443  i.e. by using gadgets as a library. Currently, the different builtin gadgets provide golang packages
   444  that can be consumed by external applications. Some examples are available in ../../examples. In the
   445  containerized gadgets the same approach can't be used as these gadgets don't provide a golang
   446  package.
   447  
   448  In order to support this case with containerized gadgets, Inspektor Gadget should provide a golang
   449  package that provides the primitives for applications to run and consume data generated by gadgets.
   450  
   451  The following code snippet shows a raw idea of the API we should provide:
   452  
   453  #### Running a Gadget from an OCI Image
   454  
   455  ```go
   456  package main
   457  
   458  import (
   459  	"fmt"
   460  
   461  	"ig.io/runner"
   462  )
   463  
   464  func main() {
   465  	opts := runner.Opts{
   466  		// Authentication options
   467  		// Gadget parameters
   468  		// etc.
   469  	}
   470  	gadget := runner.RunOCI("ghcr.io/foo/mygadget:v1", opts)
   471  	defer gadget.Close()
   472  
   473  	for !gadget.Done() {
   474  		fmt.Print("event received: %+v\n", gadget.Next())
   475  	}
   476  }
   477  ```
   478  
   479  #### Running a Gadget from is eBPF Object
   480  
   481  ```go
   482  package main
   483  
   484  import (
   485  	"fmt"
   486  	"io"
   487  
   488  	"ig.io/runner"
   489  )
   490  
   491  func main() {
   492  	myeBPFObject := io.ReadAll()
   493  	// Or from a go:embed variable
   494  
   495  	opts := runner.Opts{
   496  		// Authentication options
   497  		// Gadget parameters
   498  		// etc.
   499  	}
   500  
   501  	gadget := runner.RunObject(myeBPFObject, opts)
   502  	defer gadget.Close()
   503  
   504  	for !gadget.Done() {
   505  		fmt.Print("event received: %+v\n", gadget.Next())
   506  	}
   507  }
   508  ```
   509  
   510  ## Reimplementing existing gadgets as containerized gadgets
   511  
   512  A long term vision of this support is to reimplement all gadgets as containerized gadgets, then
   513  deprecated the built-in ones. This section presents the features Inspektor Gadget should support for
   514  it and checks additional challenges by existing gadgets.
   515  
   516  ### Features
   517  
   518  This section describes additional features needed by containerized containers in Inspektor Gadget.
   519  Some of them are already supported and others are planned.
   520  
   521  #### Filtering and enrichment by mount namespace id
   522  
   523  Inspektor Gadget provides a set of helper functions in pkg/gadgets/common/mntns_filter.h for gadgets
   524  that want to filter and enrich events based on the mount namespace inode id information. Inspektor
   525  Gadget detects the presence of the `gadget_mntns_filter_map` map and populates it with the matching
   526  containers to filter. Enriching is done by looking for the presence of a field with `gadget_mntns_id`
   527  type in the event.
   528  
   529  #### Endpoint enrichment
   530  
   531  Networking gadgets that want to enrich IP addresses with Pod and Services name can use the `gadget_l3endpoint_t` and `gadget_l4endpoint_t` types provided by Inspektor Gadget.
   532  
   533  NOTE: It's under development at the time of writing this document in
   534  https://github.com/inspektor-gadget/inspektor-gadget/pull/1825.
   535  
   536  #### `socket_filter` programs
   537  
   538  Attach ebpf programs of type `BPF_PROG_TYPE_SOCKET_FILTER`. These programs need to be attached in
   539  each network namespace of interest. Currently it's handled by the
   540  `pkg/networktracer` package. Somehow the same logic needs to be used for
   541  containerized gadgets.
   542  
   543  #### Socket enricher
   544  
   545  Use the socket enricher from the ebpf code. This can be done in a very similar way to the
   546  `gadget_mntns_filter_map`: Inspektor Gadget automatically keeps the sockets map updated and the
   547  gadget can perform lookups in the map to get additional information about the socket.
   548  
   549  Initially, this will be done in a static way, meaning that changing the way Inspektor Gadget does
   550  the enriching would mean recompiling the containerised gadgets. Later we will need to implement
   551  backward compatibility as discussed in [Support Inspektor Gadget API
   552  changes](#support-inspektor-gadget-api-changes).
   553  
   554  #### Custom parameters
   555  
   556  Some gadgets define parameters in the eBPF code to change its behavior. They are declared with the
   557  `const volatile` keywords. Those constants should be exposed to the user as parameters.
   558  
   559  It could be implemented by using the pkg/params package.
   560  
   561  #### Enum convert
   562  
   563  Convert an enum to a string. Examples: pktTypeNames, qTypeNames, rCodeNames, etc. The BTF
   564  information from the kernel and the eBPF program can be used. When using the one from the kernel, it
   565  needs to be relocated to the current kernel.
   566  
   567  #### String edit
   568  
   569  string manipulation routines. Example: parseLabelSequence to replace dns strings to dotted names.
   570  
   571  #### Bitfield
   572  
   573  Convert bitfield from an event to a human readable string. Example: bind's [optionsToString](https://github.com/inspektor-gadget/inspektor-gadget/blob/b57f2bae31a46b40d8e0204b85099ae37f15d21d/pkg/gadgets/trace/bind/tracer/tracer.go#L154).
   574  
   575  #### Iface index
   576  
   577  Convert network interface index to string. Example: bind's [BoundDevIf](https://github.com/inspektor-gadget/inspektor-gadget/blob/b57f2bae31a46b40d8e0204b85099ae37f15d21d/pkg/gadgets/trace/bind/tracer/tracer.go#L236-L250).
   578  
   579  #### Custom user space logic
   580  
   581  There are some gadgets that have a lot of logic in user space. To support those gadgets, we'll need
   582  to run custom code they provide. The design of this feature will be done later on once the features
   583  described in this document are completed.
   584  
   585  ### Gadgets
   586  
   587  This is the list of the existing gadgets and the considerations to port them to containerized
   588  gadgets. The purpose of this section is to describe the needed features and not to provide a
   589  solution for them.
   590  
   591  #### advise network-policy
   592  
   593  This one has a lot of custom logic in user space, it requires [custom user space
   594  logic](#custom-user-space-logic)
   595  
   596  #### advise seccomp-profile
   597  
   598  TODO
   599  
   600  #### audit seccomp
   601  
   602  TODO
   603  
   604  #### profile block-io
   605  
   606  TODO
   607  
   608  #### profile cpu
   609  
   610  TODO
   611  
   612  #### profile tcprtt
   613  
   614  TODO
   615  
   616  #### snapshot process
   617  
   618  It supports a compatibility mode to get processes when iterators are not available ->
   619  https://github.com/inspektor-gadget/inspektor-gadget/blob/e91a93bb2c0a7d05ed6ac2689b89ec7465923dcf/pkg/gadgets/snapshot/process/tracer/tracer.go#L216.
   620  We'll lose that in the containerized version.
   621  
   622  #### snapshot socket
   623  
   624  Inspektor Gadget should automatically run the iter/ programs on the different network namespaces of
   625  the containers.
   626  
   627  #### top block-io
   628  
   629  It has some logic to change the kprobe name based on the kernel support https://github.com/inspektor-gadget/inspektor-gadget/blob/9d8f024001c38d5677308b8d67289c5bcaf90d43/pkg/gadgets/top/block-io/tracer/tracer.go#L117-L130
   630  
   631  #### top ebpf
   632  
   633  - [Custom user space logic](#custom-user-space-logic).
   634  
   635  #### top file
   636  
   637  Nothing special is needed.
   638  
   639  #### top tcp
   640  
   641  - [Endpoint enrichment](#endpoint-enrichment)
   642  
   643  #### trace bind
   644  
   645  - [Enum convert](#enum-convert)
   646  - [Bitfield](#bitfield)
   647  - [Custom Parameters](#custom-parameters)
   648  - [Iface index](#iface-index)
   649  
   650  #### trace capabilities
   651  
   652  - [Enum convert](#enum-convert)
   653  - int to system call name conversion. Can we implement this as enum_convert given that syscalls are
   654    different per architecture?
   655  
   656  #### trace dns
   657  
   658  - [Socket filter](#socketfilter-programs)
   659  - [Socket enricher](#socket-enricher)
   660  - [Enum convert](#enum-convert)
   661  - [Endpoint enrichment](#endpoint-enrichment)
   662  
   663  #### trace exec
   664  
   665  This gadget puts all arguments in an char array separated by null chars. `arg0\0arg1\0arg2\0...argN\0':
   666  https://github.com/inspektor-gadget/inspektor-gadget/blob/b8cd8a7354952de416657279f3a49a89557bc0b1/pkg/gadgets/trace/exec/tracer/bpf/execsnoop.bpf.c#L90-L105
   667  and then in user space those are divided into an slice of strings:
   668  https://github.com/inspektor-gadget/inspektor-gadget/blob/b8cd8a7354952de416657279f3a49a89557bc0b1/pkg/gadgets/trace/exec/tracer/tracer.go#L158-L167
   669  Perhaps we can generalize this?
   670  
   671  #### trace fsslower
   672  
   673  - [Enum convert](#enum-convert)
   674  - The point where the probes of this gadget are attached to depends on a `--filesystem` flag. Those
   675    are defined as `k[ret]probe/dummy_...` and the real attach point is stored [in this
   676    map](https://github.com/inspektor-gadget/inspektor-gadget/blob/9d8f024001c38d5677308b8d67289c5bcaf90d43/pkg/gadgets/trace/fsslower/tracer/tracer.go#L68).
   677  
   678  #### trace mount
   679  
   680  - [Enum convert](#enum-convert)
   681  - Similar to `bitfield_column`. It converts an integer to a list of strings in https://github.com/inspektor-gadget/inspektor-gadget/blob/8d034d79f422d5adaf971447860cc4e1299f7865/pkg/gadgets/trace/mount/tracer/utils.go#L52-L63. However this is not exactly the same as the mechanism used in "trace bind", in that case the result is a single string.
   682  
   683  #### trace oomkill
   684  
   685  Nothing
   686  
   687  #### trace open
   688  
   689  Already ported in gadgets/trace_open.bpf.c.
   690  
   691  #### trace signal
   692  
   693  - [Enum convert](#enum-convert)
   694  - Attach programs based on parameters
   695    https://github.com/inspektor-gadget/inspektor-gadget/blob/efd6f979506ff446674d7b587cca0693bd1dd92c/pkg/gadgets/trace/signal/tracer/tracer.go#L136
   696  
   697  #### trace sni
   698  
   699  - [Socket filter](#socketfilter-programs)
   700  - [Socket enricher](#socket-enricher)
   701  - [Endpoint enrichment](#endpoint-enrichment)
   702  
   703  #### trace tcp
   704  
   705  - [Enum convert](#enum-convert)
   706  
   707  #### trace tcpconnect
   708  
   709  - Attach programs based on parameters. (Latency)
   710  
   711  #### trace tcpdrop
   712  
   713  - [Socket enricher](#socket-enricher)
   714  - [Enum convert](#enum-convert)
   715  - [Endpoint enrichment](#endpoint-enrichment)
   716  - [Bitfield](#bitfield)
   717  
   718  #### trace tcpretrans
   719  
   720  - [Socket enricher](#socket-enricher)
   721  - [Enum convert](#enum-convert)
   722  - [Endpoint enrichment](#endpoint-enrichment)
   723  - [Bitfield](#bitfield)
   724  
   725  
   726  #### traceloop
   727  
   728  TODO
   729  
   730  ## Future Work
   731  
   732  This section explicitly describes the things that we don't want to support right now but that we'll
   733  revisit later on:
   734  
   735  ### Support Inspektor Gadget API changes
   736  
   737  Inspektor Gadget exposes a small [API](#inspektor-gadget-api) composed by some C headers to gadget
   738  developers. Gadgets have to be compiled against it. In this iteration, we don't want to introduce
   739  additional complexity by supporting changes to that API, i.e. gadgets need to be recompiled to take
   740  changes in that API.
   741  
   742  Later on we will consider solutions like bpf extensions or other forms of dynamic loading to solve
   743  this problem.
   744  
   745  ### Supporting custom user space logic for gadgets
   746  
   747  As exposed in [custom user space logic](#custom-user-space-logic), there are some gadgets that need
   748  this to be implemented. However we consider that this is something very complicated and don't want
   749  to tackle this right now.