### Install cnitool and plugins Source: https://github.com/containernetworking/cni/blob/main/cnitool/README.md Install the cnitool binary and build the CNI plugins. Ensure you are in the plugins directory after cloning. ```bash go get github.com/containernetworking/cni go install github.com/containernetworking/cni/cnitool ``` ```bash git clone https://github.com/containernetworking/plugins.git cd plugins ./build_linux.sh # or ./build_windows.sh ``` -------------------------------- ### Example CNI Configuration with Debug Plugin Source: https://github.com/containernetworking/cni/blob/main/plugins/debug/README.md This configuration demonstrates how to integrate the debug plugin into a CNI setup. It specifies an output file for CNI requests and defines hooks to be executed. ```json { "cniVersion": "0.3.1", "name": "mynet", "plugins": [ { "type": "ptp", "ipMasq": true, "ipam": { "type": "host-local", "subnet": "172.16.30.0/24", "routes": [ { "dst": "0.0.0.0/0" } ] } }, { "type": "debug", "cniOutput": "/tmp/cni_output.txt", "addHooks": [ [ "sh", "-c", "ip link set $CNI_IFNAME promisc on" ] ] }, { "type": "portmap", "capabilities": {"portMappings": true}, "externalSetMarkChain": "KUBE-MARK-MASQ" } ] } ``` -------------------------------- ### Runtime Populated Configuration Source: https://github.com/containernetworking/cni/blob/main/CONVENTIONS.md Example of how a runtime populates the 'runtimeConfig' section with dynamic port mapping data. This is the configuration the plugin will actually receive. ```json { "name" : "ExamplePlugin", "type" : "port-mapper", "runtimeConfig": { "portMappings": [ {"hostPort": 8080, "containerPort": 80, "protocol": "tcp"} ] } } ``` -------------------------------- ### Plugin Configuration with Capabilities Source: https://github.com/containernetworking/cni/blob/main/CONVENTIONS.md Example of a plugin configuration specifying capabilities for port mappings. This indicates to the runtime that the plugin can handle port mapping functionality. ```json { "name" : "ExamplePlugin", "type" : "port-mapper", "capabilities": {"portMappings": true} } ``` -------------------------------- ### Add Network Configuration with Chaining Source: https://context7.com/containernetworking/cni/llms.txt Executes ADD commands sequentially for plugins in a list, passing results between them. Caches the final configuration. Use for complex network setups requiring multiple plugins. ```go result, err := cni.AddNetworkList(ctx, netconf, rt) if err != nil { // Wrapped error includes plugin type and name: // "plugin type=\"bridge\" name=\"mynet\" failed (add): ..." return err } fmt.Printf("Assigned IP: %v\n", result) ``` -------------------------------- ### CNI 'args' Labels Example Source: https://github.com/containernetworking/cni/blob/main/CONVENTIONS.md An example of the 'labels' structure within the 'args' field for passing key-value labels to CNI plugins. ```json "labels" : [ { "key" : "app", "value" : "myapp" }, { "key" : "env", "value" : "prod" } ] ``` -------------------------------- ### Run Docker Container with CNI Network Setup Source: https://github.com/containernetworking/cni/blob/main/README.md Use the `docker-run.sh` script to launch a Docker container with its network namespace configured by CNI plugins. This script wraps `docker run` and executes CNI plugins before starting the container. ```bash $ CNI_PATH=$GOPATH/src/github.com/containernetworking/plugins/bin $ cd $GOPATH/src/github.com/containernetworking/cni/scripts $ sudo CNI_PATH=$CNI_PATH ./docker-run.sh --rm busybox:latest ifconfig ``` -------------------------------- ### CNI 'args' IPs Example Source: https://github.com/containernetworking/cni/blob/main/CONVENTIONS.md Illustrates how to request specific IP addresses or CIDR ranges using the 'ips' field within the 'args' configuration. The plugin may require a prefix length. ```json "ips": ["10.2.2.42/24", "2001:db8::5"] ``` -------------------------------- ### Example CNI Network Configuration Source: https://github.com/containernetworking/cni/blob/main/SPEC.md This JSON configuration defines a network named 'dbnet' with three plugins: 'bridge', 'tuning', and 'portmap'. It includes IPAM and DNS settings for the bridge plugin. ```json { "cniVersion": "1.1.0", "cniVersions": ["0.3.1", "0.4.0", "1.0.0", "1.1.0"], "name": "dbnet", "plugins": [ { "type": "bridge", // plugin specific parameters "bridge": "cni0", "keyA": ["some more", "plugin specific", "configuration"], "ipam": { "type": "host-local", // ipam specific "subnet": "10.1.0.0/16", "gateway": "10.1.0.1", "routes": [ {"dst": "0.0.0.0/0"} ] }, "dns": { "nameservers": [ "10.1.0.1" ] } }, { "type": "tuning", "capabilities": { "mac": true }, "sysctl": { "net.core.somaxconn": "500" } }, { "type": "portmap", "capabilities": {"portMappings": true} } ] } ``` -------------------------------- ### CNI_ARGS IP Field Example Source: https://github.com/containernetworking/cni/blob/main/CONVENTIONS.md Shows the deprecated CNI_ARGS format for requesting a specific IP address, including an optional prefix length. Use 'args' instead. ```shell IP=192.168.10.4/24 ``` -------------------------------- ### Get CNI Plugin Version Info with GetVersionInfo Source: https://context7.com/containernetworking/cni/llms.txt Invoke a plugin's VERSION command using `GetVersionInfo` to retrieve its supported CNI spec versions. Falls back to `["0.1.0"]` for older plugins. ```go info, err := invoke.GetVersionInfo(ctx, "/opt/cni/bin/bridge", nil) if err != nil { log.Fatal(err) } fmt.Println(info.SupportedVersions()) // [0.3.0 0.3.1 0.4.0 1.0.0 1.1.0] ``` -------------------------------- ### Version Utilities Source: https://context7.com/containernetworking/cni/llms.txt Utilities for managing and comparing CNI specification versions. Includes functions to get the current supported version, check plugin support, and perform version comparisons. ```APIDOC ## pkg/version — Version Utilities ### `Current` / `PluginSupports` / `All` `Current()` returns the highest spec version this library implements (`"1.1.0"`). `PluginSupports` constructs a `PluginInfo` value for use with `skel.PluginMainFuncs`. `All` is a pre-built `PluginInfo` covering every spec version from 0.1.0 to 1.1.0. ```go import "github.com/containernetworking/cni/pkg/version" fmt.Println(version.Current()) // 1.1.0 // Plugin supporting only modern versions: vi := version.PluginSupports("0.4.0", "1.0.0", "1.1.0") fmt.Println(vi.SupportedVersions()) // [0.4.0 1.0.0 1.1.0] // Plugin supporting everything (most common): skel.PluginMainFuncs(funcs, version.All, "my-plugin v1.0.0") ``` ### `GreaterThanOrEqualTo` / `GreaterThan` / `ParseVersion` Semver-aware comparison helpers used by both `libcni` and `skel` to gate spec-version-dependent behaviour (e.g., enabling CHECK at ≥ 0.4.0, GC at ≥ 1.1.0). ```go ok, err := version.GreaterThanOrEqualTo("1.1.0", "0.4.0") fmt.Println(ok, err) // true ok2, _ := version.GreaterThan("0.3.1", "1.0.0") fmt.Println(ok2) // false major, minor, micro, _ := version.ParseVersion("1.1.0") fmt.Println(major, minor, micro) // 1 1 0 ``` ``` -------------------------------- ### Discover CNI Configuration Files Source: https://context7.com/containernetworking/cni/llms.txt Use `ConfFiles` to get a list of files in a directory that match specified extensions. This function is useful for custom discovery mechanisms and is used by CNI configuration loaders. ```go files, err := libcni.ConfFiles("/etc/cni/net.d", []string{'.conflist', '.conf'}) if err != nil { log.Fatal(err) } for _, f := range files { fmt.Println(f) } ``` -------------------------------- ### Query Network Plugin Readiness Source: https://context7.com/containernetworking/cni/llms.txt Use `GetStatusNetworkList` to query the readiness of network plugins. It returns an error immediately if any plugin is not ready, allowing for runtime scheduling decisions. ```go if err := cni.GetStatusNetworkList(ctx, netconf); err != nil { log.Printf("network not ready: %v", err) // Retry after a delay } ``` -------------------------------- ### Implement CNI Plugin Entry Point with PluginMainFuncs Source: https://context7.com/containernetworking/cni/llms.txt Use `PluginMainFuncs` as the primary entry point for CNI plugins. It handles reading environment variables and stdin, dispatching to callbacks, and serializing errors to stdout. ```go package main import ( "encoding/json" "fmt" "net" "github.com/containernetworking/cni/pkg/skel" "github.com/containernetworking/cni/pkg/types" types100 "github.com/containernetworking/cni/pkg/types/100" "github.com/containernetworking/cni/pkg/version" ) type NetConf struct { types.PluginConf Bridge string `json:"bridge"` } func cmdAdd(args *skel.CmdArgs) error { conf := &NetConf{} if err := json.Unmarshal(args.StdinData, conf); err != nil { return fmt.Errorf("failed to parse config: %w", err) } // ... set up network interface in args.Netns ... result := &types100.Result{ CNIVersion: conf.CNIVersion, Interfaces: []*types100.Interface{ {Name: args.IfName, Sandbox: args.Netns}, }, IPs: []*types100.IPConfig{ { Interface: types100.Int(0), Address: net.IPNet{IP: net.ParseIP("10.22.0.2"), Mask: net.CIDRMask(16, 32)}, Gateway: net.ParseIP("10.22.0.1"), }, }, } return types.PrintResult(result, conf.CNIVersion) } func cmdDel(args *skel.CmdArgs) error { // ... tear down interface ... return nil } func cmdCheck(args *skel.CmdArgs) error { // ... verify interface still matches config ... return nil } func main() { skel.PluginMainFuncs( skel.CNIFuncs{ Add: cmdAdd, Del: cmdDel, Check: cmdCheck, }, version.All, // support all spec versions: 0.1.0–1.1.0 "CNI my-bridge plugin v1.0.0", ) } ``` -------------------------------- ### Infiniband GUID Assignment Source: https://github.com/containernetworking/cni/blob/main/CONVENTIONS.md Assigns an Infiniband GUID to a network interface. This is relevant for plugins that need to configure Infiniband devices. ```json "c2:11:22:33:44:55:66:77" ``` -------------------------------- ### Use All Supported CNI Versions for Plugin Source: https://context7.com/containernetworking/cni/llms.txt Employ `version.All` as a pre-built `PluginInfo` to indicate support for all CNI spec versions from 0.1.0 to 1.1.0. This is commonly used with `skel.PluginMainFuncs`. ```go skel.PluginMainFuncs(funcs, version.All, "my-plugin v1.0.0") ``` -------------------------------- ### Load Network Configuration from File Source: https://context7.com/containernetworking/cni/llms.txt Use `NetworkConfFromFile` to load a `.conflist` file and `LoadNetworkConf` to search a directory for a conflist matching a given network name. These functions parse the configuration and optionally load per-plugin configurations. ```go // Load directly from a known file path list, err := libcni.NetworkConfFromFile("/etc/cni/net.d/10-mynet.conflist") if err != nil { log.Fatal(err) } fmt.Printf("Loaded network %q with %d plugins, CNI version %s\n", list.Name, len(list.Plugins), list.CNIVersion) // Or search a directory by network name list2, err := libcni.LoadNetworkConf("/etc/cni/net.d", "mynet") ``` -------------------------------- ### Device ID Specification Source: https://github.com/containernetworking/cni/blob/main/CONVENTIONS.md Provides a device identifier for network configuration. CNI plugins can use this to perform device-specific network setup. ```json "0000:04:00.5" ``` -------------------------------- ### Get Current CNI Spec Version Source: https://context7.com/containernetworking/cni/llms.txt Retrieve the highest CNI specification version implemented by the library using `version.Current()`. This is useful for compatibility checks. ```go import "github.com/containernetworking/cni/pkg/version" fmt.Println(version.Current()) // 1.1.0 ``` -------------------------------- ### Build CNI Plugins Source: https://github.com/containernetworking/cni/blob/main/README.md Build the CNI plugins using the provided build script. Ensure you are in the correct directory within your Go workspace. ```bash $ cd $GOPATH/src/github.com/containernetworking/plugins $ ./build_linux.sh # or build_windows.sh ``` -------------------------------- ### Run CNI Test Suite with Vagrant Source: https://github.com/containernetworking/cni/blob/main/CONTRIBUTING.md Instructions for setting up a virtual environment using Vagrant to run the CNI test suite. This ensures tests can be executed on various operating systems. ```bash vagrant up vagrant ssh # you're now in a shell in a virtual machine sudo su cd /go/src/github.com/containernetworking/cni # to run the full test suite ./test.sh # to focus on a particular test suite cd libcni go test ``` -------------------------------- ### Get Cached Network Attachments Source: https://context7.com/containernetworking/cni/llms.txt Use `GetCachedAttachments` to retrieve all cached network attachments, optionally filtering by container ID. This is useful for implementing garbage collection or auditing live attachments. ```go attachments, err := cni.GetCachedAttachments("abc123") if err != nil { log.Fatal(err) } for _, a := range attachments { fmt.Printf("network=%s ifname=%s containerID=%s\n", a.Network, a.IfName, a.ContainerID) } ``` -------------------------------- ### Create CNI Network Configuration Source: https://github.com/containernetworking/cni/blob/main/cnitool/README.md Create a CNI configuration file for a network named 'myptp' using the 'ptp' plugin and 'host-local' IPAM. This configuration is saved to /etc/cni/net.d/. ```bash echo '{"cniVersion":"0.4.0","name":"myptp","type":"ptp","ipMasq":true,"ipam":{"type":"host-local","subnet":"172.16.29.0/24","routes":[{"dst":"0.0.0.0/0"}]}}' | sudo tee /etc/cni/net.d/10-myptp.conf ``` -------------------------------- ### Create Network Namespace Source: https://github.com/containernetworking/cni/blob/main/cnitool/README.md Create a network namespace named 'testing' using the 'ip netns add' command. ```bash sudo ip netns add testing ``` -------------------------------- ### GetStatusNetworkList Source: https://context7.com/containernetworking/cni/llms.txt Queries each plugin's readiness via the STATUS command. Returns an error as soon as one plugin reports not-ready, allowing a runtime to defer scheduling. ```APIDOC ## GetStatusNetworkList ### Description Queries each plugin's readiness via the STATUS command (spec ≥ 1.1.0). Returns an error as soon as one plugin reports not-ready; this lets a runtime decide whether to defer scheduling. ### Method (Not specified, likely a Go function call) ### Parameters - **ctx**: context.Context - The context for the request. - **netconf**: *NetworkConfig - The network configuration to check. ### Request Example ```go if err := cni.GetStatusNetworkList(ctx, netconf); err != nil { log.Printf("network not ready: %v", err) // Retry after a delay } ``` ### Response (Not specified, returns an error if any plugin is not ready) ``` -------------------------------- ### Result Interface for Versioned CNI Results Source: https://context7.com/containernetworking/cni/llms.txt The Result interface enables cross-version conversion of CNI results. Implementations provide methods to get the version, convert to a specific version, and print the result. ```go type Result interface { Version() string GetAsVersion(version string) (Result, error) Print() error PrintTo(writer io.Writer) error } // Convert an arbitrary result to 1.1.0: r100, err := someResult.GetAsVersion("1.1.0") if err != nil { log.Fatal(err) } _ = r100.Print() ``` -------------------------------- ### Initialize CNI Config and Add Network Source: https://context7.com/containernetworking/cni/llms.txt Creates a CNIConfig instance to invoke plugins, loads network configuration, and adds a network for a container. Caches the result for subsequent operations. Use when a container runtime needs to manage container network attachments. ```go import ( "context" "fmt" "github.com/containernetworking/cni/libcni" ) // Search for plugins in two directories; use default executor; cache in /tmp/cni-cache cni := libcni.NewCNIConfigWithCacheDir( []string{"/opt/cni/bin", "/usr/lib/cni"}, "/tmp/cni-cache", nil, ) ctx := context.Background() // Load a conflist from disk netconf, err := libcni.LoadNetworkConf("/etc/cni/net.d", "mynet") if err != nil { panic(err) } rt := &libcni.RuntimeConf{ ContainerID: "abc123", NetNS: "/var/run/netns/abc123", IfName: "eth0", Args: [][2]string{{"K8S_POD_NAME", "mypod"}}, CapabilityArgs: map[string]interface{}{ "portMappings": []map[string]interface{}{ {"hostPort": 8080, "containerPort": 80, "protocol": "tcp"}, }, }, } result, err := cni.AddNetworkList(ctx, netconf, rt) if err != nil { panic(fmt.Sprintf("ADD failed: %v", err)) } // result is a types.Result — print as JSON to stdout _ = result.Print() // Output example: // { // "cniVersion": "1.1.0", // "interfaces": [{"name":"eth0","mac":"0a:58:0a:f4:00:06","sandbox":"/var/run/netns/abc123"}], // "ips": [{"interface": 0, "address": "10.244.0.6/24", "gateway": "10.244.0.1"}], // "routes": [{"dst": "0.0.0.0/0"}], // "dns": {} // } ``` -------------------------------- ### Using 'args' for CNI Labels Source: https://github.com/containernetworking/cni/blob/main/CONVENTIONS.md Demonstrates how to pass structured label data to CNI plugins using the 'args' field in the network configuration. Plugins that do not understand the data should ignore it. ```json { "cniVersion":"0.2.0", "name":"net", "args":{ "cni":{ "labels": [{"key": "app", "value": "myapp"}] } }, // "ipam":{ // } } ``` -------------------------------- ### Runtime Configuration with Port Mapping Source: https://github.com/containernetworking/cni/blob/main/SPEC.md This JSON snippet illustrates a runtime configuration derived from a plugin's capabilities. It includes specific port mapping details that the runtime provides to the plugin. ```json { "type": "myPlugin", "runtimeConfig": { "portMappings": [ { "hostPort": 8080, "containerPort": 80, "protocol": "tcp" } ] } ... } ``` -------------------------------- ### Create CNI Network Configuration Files Source: https://github.com/containernetworking/cni/blob/main/README.md Create netconf files in `/etc/cni/net.d` to define network settings. The `10-mynet.conf` defines a bridge network with IPAM, and `99-loopback.conf` configures a loopback interface. ```bash $ mkdir -p /etc/cni/net.d $ cat >/etc/cni/net.d/10-mynet.conf </etc/cni/net.d/99-loopback.conf <= 1.1.0) NETCONFPATH=/tmp/cni-conf CNI_PATH=/opt/cni/bin \ cnitool status mynet /var/run/netns/testing ``` -------------------------------- ### NetworkConfFromFile / LoadNetworkConf Source: https://context7.com/containernetworking/cni/llms.txt Reads a `.conflist` file from disk, parses it into a `NetworkConfigList`, and optionally loads per-plugin `.conf` files from a subdirectory named after the network. `LoadNetworkConf` searches an entire directory for the first conflist whose `name` field matches. ```APIDOC ## NetworkConfFromFile / LoadNetworkConf ### Description Reads a `.conflist` file from disk, parses it into a `NetworkConfigList`, and optionally loads per-plugin `.conf` files from a subdirectory named after the network. `LoadNetworkConf` searches an entire directory for the first conflist whose `name` field matches. ### Method (Not specified, likely a Go function call) ### Parameters - **path**: string - The path to the `.conflist` file or directory. - **name**: string - Optional. The name of the network to search for in a directory. ### Request Example ```go // Load directly from a known file path list, err := libcni.NetworkConfFromFile("/etc/cni/net.d/10-mynet.conflist") if err != nil { log.Fatal(err) } fmt.Printf("Loaded network %q with %d plugins, CNI version %s\n", list.Name, len(list.Plugins), list.CNIVersion) // Or search a directory by network name list2, err := libcni.LoadNetworkConf("/etc/cni/net.d", "mynet") ``` ### Response - **list**: *NetworkConfigList - The loaded network configuration list. ``` -------------------------------- ### ArgsFromEnv Source: https://context7.com/containernetworking/cni/llms.txt Provides CNIArgs that inherit the full environment of the current process unchanged, suitable for re-invoking a plugin without modifications. ```APIDOC ## ArgsFromEnv ### Description Returns a `CNIArgs` implementation that inherits the full environment of the current process unchanged. Suitable for cases where a plugin is re-invoking itself with no modifications. ### Example Usage ```go result, err := invoke.ExecPluginWithResult(ctx, pluginPath, netconf, invoke.ArgsFromEnv(), exec) ``` ``` -------------------------------- ### Delete Network Interface and Namespace Source: https://github.com/containernetworking/cni/blob/main/cnitool/README.md Clean up by deleting the 'myptp' network interface from the 'testing' namespace and then deleting the namespace itself. ```bash sudo CNI_PATH=./bin cnitool del myptp /var/run/netns/testing ``` ```bash sudo ip netns del testing ``` -------------------------------- ### ExecPluginWithResult Using Environment Variables Source: https://context7.com/containernetworking/cni/llms.txt ExecPluginWithResult is suitable for plugins that re-invoke themselves without modifications, inheriting the full environment of the current process unchanged via ArgsFromEnv. ```go result, err := invoke.ExecPluginWithResult(ctx, pluginPath, netconf, invoke.ArgsFromEnv(), exec) ``` -------------------------------- ### Compare CNI Versions Source: https://context7.com/containernetworking/cni/llms.txt Utilize `version.GreaterThanOrEqualTo` and `version.GreaterThan` for semver-aware comparisons of CNI specification versions. These helpers are crucial for implementing version-dependent behavior. ```go ok, err := version.GreaterThanOrEqualTo("1.1.0", "0.4.0") fmt.Println(ok, err) // true ok2, _ := version.GreaterThan("0.3.1", "1.0.0") fmt.Println(ok2) // false ``` -------------------------------- ### Execute CNI Plugin with Result using ExecPluginWithResult Source: https://context7.com/containernetworking/cni/llms.txt Use `ExecPluginWithResult` to execute a CNI plugin binary, passing configuration via stdin and environment variables. It returns the plugin's stdout parsed as a `types.Result` and handles version fixups. ```go import ( "context" "github.com/containernetworking/cni/pkg/invoke" ) args := &invoke.Args{ Command: "ADD", ContainerID: "abc123", NetNS: "/var/run/netns/abc123", IfName: "eth0", Path: "/opt/cni/bin", } result, err := invoke.ExecPluginWithResult( context.Background(), "/opt/cni/bin/bridge", netconfBytes, args, nil, // nil uses DefaultExec ) if err != nil { log.Fatal(err) } _ = result.Print() ``` -------------------------------- ### GetVersionInfo Source: https://context7.com/containernetworking/cni/llms.txt Queries a plugin binary with the VERSION command and returns the set of CNI spec versions it supports. Handles legacy plugins that don't recognise VERSION by returning `["0.1.0"]`. ```APIDOC ## GetVersionInfo ### Description Queries a plugin binary with the VERSION command and returns the set of CNI spec versions it supports. Handles legacy plugins that don't recognise VERSION by returning `["0.1.0"]`. ### Method (Not specified, likely a Go function call) ### Parameters - **ctx**: context.Context - The context for the request. - **pluginName**: string - The name of the plugin to query. ### Request Example ```go info, err := cni.GetVersionInfo(ctx, "bridge") if err != nil { log.Fatal(err) } fmt.Println("Plugin supports:", info.SupportedVersions()) // e.g. [0.3.0 0.3.1 0.4.0 1.0.0 1.1.0] ``` ### Response - **info**: VersionInfo - An object containing supported versions. ``` -------------------------------- ### Check Network Interface Configuration Source: https://github.com/containernetworking/cni/blob/main/cnitool/README.md Verify the network interface configuration within the 'testing' namespace for the 'myptp' network. This command is only supported for CNI spec v0.4.0 and later. ```bash sudo CNI_PATH=./bin cnitool check myptp /var/run/netns/testing ``` -------------------------------- ### Define Plugin Supported CNI Versions Source: https://context7.com/containernetworking/cni/llms.txt Construct a `PluginInfo` value using `version.PluginSupports` to specify the CNI versions a plugin is compatible with. This is used with `skel.PluginMainFuncs`. ```go vi := version.PluginSupports("0.4.0", "1.0.0", "1.1.0") fmt.Println(vi.SupportedVersions()) // [0.4.0 1.0.0 1.1.0] ``` -------------------------------- ### DelegateAdd for Chaining CNI Plugins Source: https://context7.com/containernetworking/cni/llms.txt Use DelegateAdd from within a CNI plugin to chain to a sub-plugin, such as an IPAM plugin. The environment is inherited from the parent process, with only CNI_COMMAND being overridden. ```go func cmdAdd(args *skel.CmdArgs) error { conf := &NetConf{} _ = json.Unmarshal(args.StdinData, conf) // Delegate to host-local IPAM plugin ipamResult, err := invoke.DelegateAdd(context.TODO(), conf.IPAM.Type, args.StdinData, nil) if err != nil { return fmt.Errorf("ipam ADD failed: %w", err) } // Convert to current result type result, err := types100.GetResult(ipamResult) if err != nil { return err } fmt.Printf("Got IP: %v\n", result.IPs[0].Address) return types.PrintResult(result, conf.CNIVersion) } ``` -------------------------------- ### Validate Network Configuration and Capabilities Source: https://context7.com/containernetworking/cni/llms.txt Use `ValidateNetworkList` to check if all referenced plugin binaries exist and support the specified CNI spec version. It returns the union of all advertised capabilities upon success. ```go caps, err := cni.ValidateNetworkList(ctx, netconf) if err != nil { log.Fatalf("invalid config: %v", err) } fmt.Println("Supported capabilities:", caps) // e.g. [portMappings bandwidth] ``` -------------------------------- ### Add Network Interface to Namespace Source: https://github.com/containernetworking/cni/blob/main/cnitool/README.md Add the 'myptp' network interface to the 'testing' network namespace. The CNI_PATH environment variable specifies the location of the CNI plugins. ```bash sudo CNI_PATH=./bin cnitool add myptp /var/run/netns/testing ``` -------------------------------- ### ConfFiles Source: https://context7.com/containernetworking/cni/llms.txt Returns all files in a directory whose extension matches one of the supplied list. Used by configuration loaders but also directly useful for implementing custom discovery. ```APIDOC ## ConfFiles ### Description Returns all files in a directory whose extension matches one of the supplied list. Used by configuration loaders but also directly useful for implementing custom discovery. ### Method (Not specified, likely a Go function call) ### Parameters - **dir**: string - The directory to search. - **extensions**: []string - A list of file extensions to match. ### Request Example ```go files, err := libcni.ConfFiles("/etc/cni/net.d", []string{".conflist", ".conf"}) if err != nil { log.Fatal(err) } for _, f := range files { fmt.Println(f) } ``` ### Response - **files**: []string - A slice of file paths matching the extensions. ``` -------------------------------- ### Importing CNI v1.0 Types in Go Source: https://github.com/containernetworking/cni/blob/main/Documentation/spec-upgrades.md When upgrading to CNI v1.0, the `/pkg/types/current` path is removed. Runtimes must explicitly select a supported version, such as v1.0.0, by updating their Go imports. ```go import ( cniv1 "github.com/containernetworking/cni/pkg/types/100" ) ``` -------------------------------- ### Go Plugin: Use Delegated IPAM Result Source: https://github.com/containernetworking/cni/blob/main/Documentation/spec-upgrades.md This Go code snippet shows how to obtain a result from a delegated IPAM plugin and then convert it into the current spec version format. This is useful when an external IPAM plugin is used. ```go ipamResult, err := ipam.ExecAdd(netConf.IPAM.Type, args.StdinData) result, err := current.NewResultFromResult(ipamResult) ``` -------------------------------- ### Tuning Plugin Add Operation Input Source: https://github.com/containernetworking/cni/blob/main/SPEC.md Input JSON for the tuning plugin, which receives the previous result and applies system tuning parameters like sysctl values. Note the updated MAC address in runtimeConfig. ```json { "cniVersion": "1.1.0", "name": "dbnet", "type": "tuning", "sysctl": { "net.core.somaxconn": "500" }, "runtimeConfig": { "mac": "00:11:22:33:44:66" }, "prevResult": { "ips": [ { "address": "10.1.0.5/16", "gateway": "10.1.0.1", "interface": 2 } ], "routes": [ { "dst": "0.0.0.0/0" } ], "interfaces": [ { "name": "cni0", "mac": "00:11:22:33:44:55" }, { "name": "veth3243", "mac": "55:44:33:22:11:11" }, { "name": "eth0", "mac": "99:88:77:66:55:44", "sandbox": "/var/run/netns/blue" } ], "dns": { "nameservers": [ "10.1.0.1" ] } } } ``` -------------------------------- ### NewCNIConfig / NewCNIConfigWithCacheDir Source: https://context7.com/containernetworking/cni/llms.txt Creates a CNIConfig instance for invoking CNI plugins. Supports specifying plugin search paths, an optional custom executor, and a cache directory for ADD results. ```APIDOC ## NewCNIConfig / NewCNIConfigWithCacheDir ### Description Creates a `CNIConfig` instance used by container runtimes to invoke plugins. Accepts one or more plugin search paths and an optional custom `Exec` implementation; pass `nil` for the default disk-based executor. `NewCNIConfigWithCacheDir` additionally sets the directory used to persist ADD results for later CHECK/DEL operations. ### Usage Example ```go import ( "context" "fmt" "github.com/containernetworking/cni/libcni" ) // Search for plugins in two directories; use default executor; cache in /tmp/cni-cache cni := libcni.NewCNIConfigWithCacheDir( []string{"/opt/cni/bin", "/usr/lib/cni"}, "/tmp/cni-cache", nil, ) ctx := context.Background() // Load a conflist from disk netconf, err := libcni.LoadNetworkConf("/etc/cni/net.d", "mynet") if err != nil { panic(err) } rt := &libcni.RuntimeConf{ ContainerID: "abc123", NetNS: "/var/run/netns/abc123", IfName: "eth0", Args: [][2]string{{"K8S_POD_NAME", "mypod"}}, CapabilityArgs: map[string]interface{}{ "portMappings": []map[string]interface{}{ {"hostPort": 8080, "containerPort": 80, "protocol": "tcp"}, }, }, } result, err := cni.AddNetworkList(ctx, netconf, rt) if err != nil { panic(fmt.Sprintf("ADD failed: %v", err)) } // result is a types.Result — print as JSON to stdout _ = result.Print() // Output example: // { // "cniVersion": "1.1.0", // "interfaces": [{"name":"eth0","mac":"0a:58:0a:f4:00:06","sandbox":"/var/run/netns/abc123"}], // "ips": [{"interface": 0, "address": "10.244.0.6/24", "gateway": "10.244.0.1"}], // "routes": [{"dst": "0.0.0.0/0"}], // "dns": {} // } ``` ``` -------------------------------- ### cnitool - Command-line Testing Tool Source: https://context7.com/containernetworking/cni/llms.txt A developer utility for testing CNI plugins. It allows invoking CNI operations like add, del, check, gc, and status against a network namespace without a container runtime, using environment variables for configuration. ```APIDOC ## cnitool — Command-line Testing Tool ### `cnitool add / del / check / gc / status` A developer utility that invokes CNI plugins against an already-existing network namespace without requiring a container runtime. Configuration is controlled entirely through environment variables. ```bash # Create a test network namespace ip netns add testing # Write a conflist mkdir -p /tmp/cni-conf cat > /tmp/cni-conf/10-mynet.conflist <= 1.1.0) NETCONFPATH=/tmp/cni-conf CNI_PATH=/opt/cni/bin \ cnitool status mynet /var/run/netns/testing # GC: remove stale attachments NETCONFPATH=/tmp/cni-conf CNI_PATH=/opt/cni/bin \ cnitool gc mynet /var/run/netns/testing # Optional overrides: # CNI_IFNAME=net1 — use non-default interface name # CNI_ARGS=K8S_POD_NAME=mypod — pass extra key=value args # CAP_ARGS='{"portMappings":[...]}}' — pass capability args as JSON ``` ``` -------------------------------- ### Bandwidth Limit Configuration Source: https://github.com/containernetworking/cni/blob/main/CONVENTIONS.md Configures ingress and egress bandwidth limits for network interfaces. Rates and burst values are specified in bits per second and bits, respectively. ```json { "ingressRate": 2048, "ingressBurst": 1600, "egressRate": 4096, "egressBurst": 1600 } ``` -------------------------------- ### Test Network Connectivity Source: https://github.com/containernetworking/cni/blob/main/cnitool/README.md Test network connectivity from within the 'testing' namespace by checking IP addresses and pinging an external address. ```bash sudo ip -n testing addr ``` ```bash sudo ip netns exec testing ping -c 1 4.2.2.2 ``` -------------------------------- ### Advertise Supported CNI Versions Source: https://github.com/containernetworking/cni/blob/main/Documentation/spec-upgrades.md Plugins should advertise the CNI spec versions they support by responding to the VERSION command with this JSON data. This ensures compatibility with different CNI spec versions. ```json { "cniVersion": "1.0.0", "supportedVersions": [ "0.1.0", "0.2.0", "0.3.0", "0.3.1", "0.4.0", "1.0.0" ] } ``` -------------------------------- ### ValidateNetworkList Source: https://context7.com/containernetworking/cni/llms.txt Checks that all plugin binaries referenced by the config exist on disk and support the requested CNI spec version. Returns the union of all advertised capabilities on success. ```APIDOC ## ValidateNetworkList ### Description Checks that all plugin binaries referenced by the config exist on disk and support the requested CNI spec version. Returns the union of all advertised capabilities on success. ### Method (Not specified, likely a Go function call) ### Parameters - **ctx**: context.Context - The context for the request. - **netconf**: *NetworkConfig - The network configuration to validate. ### Request Example ```go caps, err := cni.ValidateNetworkList(ctx, netconf) if err != nil { log.Fatalf("invalid config: %v", err) } fmt.Println("Supported capabilities:", caps) // e.g. [portMappings bandwidth] ``` ### Response - **caps** ([]string) - The union of all advertised capabilities on success. ``` -------------------------------- ### Check Network Attachment using cnitool Source: https://context7.com/containernetworking/cni/llms.txt Verify the correctness of a network attachment using `cnitool check`. Ensure `NETCONFPATH` and `CNI_PATH` are set. ```bash # CHECK: verify the attachment is still correct NETCONFPATH=/tmp/cni-conf CNI_PATH=/opt/cni/bin \ cnitool check mynet /var/run/netns/testing ``` -------------------------------- ### Check Network Configuration Source: https://context7.com/containernetworking/cni/llms.txt Verifies network configuration by executing the CHECK command on plugins using cached ADD results. Requires CNI spec version >= 0.4.0. Use to ensure network state consistency. ```go if err := cni.CheckNetworkList(ctx, netconf, rt); err != nil { // err == libcni.ErrorCheckNotSupp if spec version < 0.4.0 fmt.Fprintf(os.Stderr, "network check failed: %v\n", err) } ``` -------------------------------- ### Parse Single Plugin Configuration from Bytes Source: https://context7.com/containernetworking/cni/llms.txt Use `NetworkPluginConfFromBytes` to parse a single plugin configuration from JSON bytes. It returns a `PluginConfig` containing raw bytes and the decoded configuration, suitable for plugin stdin. ```go pluginBytes := []byte(`{ "cniVersion": "1.1.0", "type": "bridge", "bridge": "cni0", "isGateway": true, "ipMasq": true, "ipam": {"type": "host-local", "subnet": "10.22.0.0/16"} }`) pc, err := libcni.NetworkPluginConfFromBytes(pluginBytes) if err != nil { log.Fatal(err) } fmt.Println("Plugin type:", pc.Network.Type) // bridge ```