github.com/john-lin/cni@v0.6.0-rc1.0.20170712150331-b69e640cc0e2/SPEC.md (about)

     1  # Container Networking Interface Specification
     2  
     3  ## Version
     4  This is CNI **spec** version **0.3.1**.
     5  
     6  Note that this is **independent from the version of the CNI library and plugins** in this repository (e.g. the versions of [releases](https://github.com/containernetworking/cni/releases)).
     7  
     8  ## Overview
     9  
    10  This document proposes a generic plugin-based networking solution for application containers on Linux, the _Container Networking Interface_, or _CNI_.
    11  It is derived from the [rkt Networking Proposal][rkt-networking-proposal], which aimed to satisfy many of the [design considerations][rkt-networking-design] for networking in [rkt][rkt-github].
    12  
    13  For the purposes of this proposal, we define two terms very specifically:
    14  - _container_ can be considered synonymous with a [Linux _network namespace_][namespaces]. What unit this corresponds to depends on a particular container runtime implementation: for example, in implementations of the [App Container Spec][appc-github] like rkt, each _pod_ runs in a unique network namespace. In [Docker][docker], on the other hand, network namespaces generally exist for each separate Docker container.
    15  - _network_ refers to a group of entities that are uniquely addressable that can communicate amongst each other. This could be either an individual container (as specified above), a machine, or some other network device (e.g. a router). Containers can be conceptually _added to_ or _removed from_ one or more networks.
    16  
    17  [rkt-networking-proposal]: https://docs.google.com/a/coreos.com/document/d/1PUeV68q9muEmkHmRuW10HQ6cHgd4819_67pIxDRVNlM/edit#heading=h.ievko3xsjwxd
    18  [rkt-networking-design]: 
    19  https://docs.google.com/a/coreos.com/document/d/1CTAL4gwqRofjxyp4tTkbgHtAwb2YCcP14UEbHNizd8g
    20  [rkt-github]: https://github.com/coreos/rkt
    21  [namespaces]: http://man7.org/linux/man-pages/man7/namespaces.7.html 
    22  [appc-github]: https://github.com/appc/spec
    23  [docker]: https://docker.com 
    24  
    25  This document aims to specify the interface between "runtimes" and "plugins". Whilst there are certain well known fields, runtimes may wish to pass additional information to plugins. These extentions are not part of this specification but are documented as [conventions](CONVENTIONS.md).
    26  
    27  ## General considerations
    28  
    29  The intention is for the container runtime to first create a new network namespace for the container.
    30  It then determines which networks this container should belong to and for each network, which plugin must be executed.
    31  The network configuration is in JSON format and can easily be stored in a file.
    32  The network configuration includes mandatory fields such as "name" and "type" as well as plugin (type) specific ones.
    33  The network configuration allows for fields to change values between invocations. For this purpose there is an optional field "args" which should contain the varying information.
    34  The container runtime sequentially sets up the networks by executing the corresponding plugin for each network.
    35  Upon completion of the container lifecycle, the runtime executes the plugins in reverse order (relative to the order in which they were added) to disconnect them from the networks.
    36  
    37  ## CNI Plugin
    38  
    39  ### Overview
    40  
    41  Each CNI plugin is implemented as an executable that is invoked by the container management system (e.g. rkt or Docker).
    42  
    43  A CNI plugin is responsible for inserting a network interface into the container network namespace (e.g. one end of a veth pair) and making any necessary changes on the host (e.g. attaching other end of veth into a bridge).
    44  It should then assign the IP to the interface and setup the routes consistent with IP Address Management section by invoking appropriate IPAM plugin.
    45  
    46  ### Parameters
    47  
    48  The operations that the CNI plugin needs to support are:
    49  
    50  
    51  - Add container to network
    52    - Parameters:
    53      - **Version**. The version of CNI spec that the caller is using (container management system or the invoking plugin).
    54      - **Container ID**. This is optional but recommended, and should be unique across an administrative domain while the container is live (it may be reused in the future). For example, an environment with an IPAM system may require that each container is allocated a unique ID and that each IP allocation can thus be correlated back to a particular container. As another example, in appc implementations this would be the _pod ID_.
    55      - **Network namespace path**. This represents the path to the network namespace to be added, i.e. /proc/[pid]/ns/net or a bind-mount/link to it.
    56      - **Network configuration**. This is a JSON document describing a network to which a container can be joined. The schema is described below.
    57      - **Extra arguments**. This provides an alternative mechanism to allow simple configuration of CNI plugins on a per-container basis.
    58      - **Name of the interface inside the container**. This is the name that should be assigned to the interface created inside the container (network namespace); consequently it must comply with the standard Linux restrictions on interface names.
    59    - Result:
    60      - **Interfaces list**. Depending on the plugin, this can include the sandbox (eg, container or hypervisor) interface name and/or the host interface name, the hardware addresses of each interface, and details about the sandbox (if any) the interface is in.
    61      - **IP configuration assigned to each interface**. The IPv4 and/or IPv6 addresses, gateways, and routes assigned to sandbox and/or host interfaces.
    62      - **DNS information**. Dictionary that includes DNS information for nameservers, domain, search domains and options.
    63  
    64  - Delete container from network
    65    - Parameters:
    66      - **Version**. The version of CNI spec that the caller is using (container management system or the invoking plugin).
    67      - **Container ID**, as defined above.
    68      - **Network namespace path**, as defined above.
    69      - **Network configuration**, as defined above.
    70      - **Extra arguments**, as defined above.
    71      - **Name of the interface inside the container**, as defined above.
    72  
    73  - Report version
    74    - Parameters: NONE.
    75    - Result: information about the CNI spec versions supported by the plugin
    76  
    77        ```
    78        {
    79          "cniVersion": "0.3.1", // the version of the CNI spec in use for this output
    80          "supportedVersions": [ "0.1.0", "0.2.0", "0.3.0", "0.3.1" ] // the list of CNI spec versions that this plugin supports
    81        }
    82        ```
    83  
    84  The executable command-line API uses the type of network (see [Network Configuration](#network-configuration) below) as the name of the executable to invoke.
    85  It will then look for this executable in a list of predefined directories. Once found, it will invoke the executable using the following environment variables for argument passing:
    86  - `CNI_COMMAND`: indicates the desired operation; `ADD`, `DEL` or `VERSION`.
    87  - `CNI_CONTAINERID`: Container ID
    88  - `CNI_NETNS`: Path to network namespace file
    89  - `CNI_IFNAME`: Interface name to set up; plugin must honor this interface name or return an error
    90  - `CNI_ARGS`: Extra arguments passed in by the user at invocation time. Alphanumeric key-value pairs separated by semicolons; for example, "FOO=BAR;ABC=123"
    91  - `CNI_PATH`: List of paths to search for CNI plugin executables. Paths are separated by an OS-specific list separator; for example ':' on Linux and ';' on Windows
    92  
    93  Network configuration in JSON format is streamed to the plugin through stdin. This means it is not tied to a particular file on disk and can contain information which changes between invocations.
    94  
    95  
    96  ### Result
    97  
    98  Note that IPAM plugins return an abbreviated `Result` structure as described in [IP Allocation](#ip-allocation).
    99  
   100  Success is indicated by a return code of zero and the following JSON printed to stdout in the case of the ADD command. The `ips` and `dns` items should be the same output as was returned by the IPAM plugin (see [IP Allocation](#ip-allocation) for details) except that the plugin should fill in the `interface` indexes appropriately, which are missing from IPAM plugin output since IPAM plugins should be unaware of interfaces.
   101  
   102  ```
   103  {
   104    "cniVersion": "0.3.1",
   105    "interfaces": [                                            (this key omitted by IPAM plugins)
   106        {
   107            "name": "<name>",
   108            "mac": "<MAC address>",                            (required if L2 addresses are meaningful)
   109            "sandbox": "<netns path or hypervisor identifier>" (required for container/hypervisor interfaces, empty/omitted for host interfaces)
   110        }
   111    ],
   112    "ips": [
   113        {
   114            "version": "<4-or-6>",
   115            "address": "<ip-and-prefix-in-CIDR>",
   116            "gateway": "<ip-address-of-the-gateway>",          (optional)
   117            "interface": <numeric index into 'interfaces' list>
   118        },
   119        ...
   120    ],
   121    "routes": [                                                (optional)
   122        {
   123            "dst": "<ip-and-prefix-in-cidr>",
   124            "gw": "<ip-of-next-hop>"                           (optional)
   125        },
   126        ...
   127    ]
   128    "dns": {
   129      "nameservers": <list-of-nameservers>                     (optional)
   130      "domain": <name-of-local-domain>                         (optional)
   131      "search": <list-of-additional-search-domains>            (optional)
   132      "options": <list-of-options>                             (optional)
   133    }
   134  }
   135  ```
   136  
   137  `cniVersion` specifies a [Semantic Version 2.0](http://semver.org) of CNI specification used by the plugin.
   138  `interfaces` describes specific network interfaces the plugin created.
   139  If the `CNI_IFNAME` variable exists the plugin must use that name for the sandbox/hypervisor interface or return an error if it cannot.
   140  - `mac` (string): the hardware address of the interface.
   141     If L2 addresses are not meaningful for the plugin then this field is optional.
   142  - `sandbox` (string): container/namespace-based environments should return the full filesystem path to the network namespace of that sandbox.
   143     Hypervisor/VM-based plugins should return an ID unique to the virtualized sandbox the interface was created in.
   144     This item must be provided for interfaces created or moved into a sandbox like a network namespace or a hypervisor/VM.
   145  
   146  The `ips` field is a list of IP configuration information.
   147  See the [IP well-known structure](#ips) section for more information.
   148  
   149  The `dns` field contains a dictionary consisting of common DNS information.
   150  See the [DNS well-known structure](#dns) section for more information.
   151  
   152  The specification does not declare how this information must be processed by CNI consumers.
   153  Examples include generating an `/etc/resolv.conf` file to be injected into the container filesystem or running a DNS forwarder on the host.
   154  
   155  Errors are indicated by a non-zero return code and the following JSON being printed to stdout:
   156  ```
   157  {
   158    "cniVersion": "0.3.1",
   159    "code": <numeric-error-code>,
   160    "msg": <short-error-message>,
   161    "details": <long-error-message> (optional)
   162  }
   163  ```
   164  
   165  `cniVersion` specifies a [Semantic Version 2.0](http://semver.org) of CNI specification used by the plugin.
   166  Error codes 0-99 are reserved for well-known errors (see [Well-known Error Codes](#well-known-error-codes) section).
   167  Values of 100+ can be freely used for plugin specific errors. 
   168  
   169  In addition, stderr can be used for unstructured output such as logs.
   170  
   171  ### Network Configuration
   172  
   173  The network configuration is described in JSON form. The configuration can be stored on disk or generated from other sources by the container runtime. The following fields are well-known and have the following meaning:
   174  - `cniVersion` (string): [Semantic Version 2.0](http://semver.org) of CNI specification to which this configuration conforms.
   175  - `name` (string): Network name. This should be unique across all containers on the host (or other administrative domain).
   176  - `type` (string): Refers to the filename of the CNI plugin executable.
   177  - `args` (dictionary): Optional additional arguments provided by the container runtime. For example a dictionary of labels could be passed to CNI plugins by adding them to a labels field under `args`.
   178  - `ipMasq` (boolean): Optional (if supported by the plugin). Set up an IP masquerade on the host for this network. This is necessary if the host will act as a gateway to subnets that are not able to route to the IP assigned to the container.
   179  - `ipam`: Dictionary with IPAM specific values:
   180    - `type` (string): Refers to the filename of the IPAM plugin executable.
   181  - `dns`: Dictionary with DNS specific values:
   182    - `nameservers` (list of strings): list of a priority-ordered list of DNS nameservers that this network is aware of. Each entry in the list is a string containing either an IPv4 or an IPv6 address.
   183    - `domain` (string): the local domain used for short hostname lookups.
   184    - `search` (list of strings): list of priority ordered search domains for short hostname lookups. Will be preferred over `domain` by most resolvers.
   185    - `options` (list of strings): list of options that can be passed to the resolver
   186  
   187  Plugins may define additional fields that they accept and may generate an error if called with unknown fields. The exception to this is the `args` field may be used to pass arbitrary data which may be ignored by plugins.
   188  
   189  ### Example configurations
   190  
   191  ```json
   192  {
   193    "cniVersion": "0.3.1",
   194    "name": "dbnet",
   195    "type": "bridge",
   196    // type (plugin) specific
   197    "bridge": "cni0",
   198    "ipam": {
   199      "type": "host-local",
   200      // ipam specific
   201      "subnet": "10.1.0.0/16",
   202      "gateway": "10.1.0.1"
   203    },
   204    "dns": {
   205      "nameservers": [ "10.1.0.1" ]
   206    }
   207  }
   208  ```
   209  
   210  ```json
   211  {
   212    "cniVersion": "0.3.1",
   213    "name": "pci",
   214    "type": "ovs",
   215    // type (plugin) specific
   216    "bridge": "ovs0",
   217    "vxlanID": 42,
   218    "ipam": {
   219      "type": "dhcp",
   220      "routes": [ { "dst": "10.3.0.0/16" }, { "dst": "10.4.0.0/16" } ]
   221    }
   222    // args may be ignored by plugins
   223    "args": {
   224      "labels" : {
   225          "appVersion" : "1.0"
   226      }
   227    }
   228  }
   229  ```
   230  
   231  ```json
   232  {
   233    "cniVersion": "0.3.1",
   234    "name": "wan",
   235    "type": "macvlan",
   236    // ipam specific
   237    "ipam": {
   238      "type": "dhcp",
   239      "routes": [ { "dst": "10.0.0.0/8", "gw": "10.0.0.1" } ]
   240    },
   241    "dns": {
   242      "nameservers": [ "10.0.0.1" ]
   243    }
   244  }
   245  ```
   246  
   247  ### Network Configuration Lists
   248  
   249  Network configuration lists provide a mechanism to run multiple CNI plugins for a single container in a defined order, passing the result of each plugin to the next plugin.
   250  The list is composed of well-known fields and list of one or more standard CNI network configurations (see above).
   251  
   252  The list is described in JSON form, and can be stored on disk or generated from other sources by the container runtime. The following fields are well-known and have the following meaning:
   253  - `cniVersion` (string): [Semantic Version 2.0](http://semver.org) of CNI specification to which this configuration list and all the individual configurations conform.
   254  - `name` (string): Network name. This should be unique across all containers on the host (or other administrative domain).
   255  - `plugins` (list): A list of standard CNI network configuration dictionaries (see above).
   256  
   257  When executing a plugin list, the runtime MUST replace the `name` and `cniVersion` fields in each individual network configuration in the list with the `name` and `cniVersion` field of the list itself. This ensures that the name and CNI version is the same for all plugin executions in the list, preventing versioning conflicts between plugins.
   258  The runtime may also pass capability-based keys as a map in the top-level `runtimeConfig` key of the plugin's config JSON if a plugin advertises it supports a specific capability via the `capabilities` key of its network configuration.  The key passed in `runtimeConfig` MUST match the name of the specific capability from the `capabilities` key of the plugins network configuration. See CONVENTIONS.md for more information on capabilities and how they are sent to plugins via the `runtimeConfig` key.
   259  
   260  For the ADD action, the runtime MUST also add a `prevResult` field to the configuration JSON of any plugin after the first one, which MUST be the Result of the previous plugin (if any) in JSON format ([see below](#network-configuration-list-runtime-examples)).
   261  For the ADD action, plugins SHOULD echo the contents of the `prevResult` field to their stdout to allow subsequent plugins (and the runtime) to receive the result, unless they wish to modify or suppress a previous result.
   262  Plugins are allowed to modify or suppress all or part of a `prevResult`.
   263  However, plugins that support a version of the CNI specification that includes the `prevResult` field MUST handle `prevResult` by either passing it through, modifying it, or suppressing it explicitly.
   264  It is a violation of this specification to be unaware of the `prevResult` field.
   265  
   266  The runtime MUST also execute each plugin in the list with the same environment.
   267  
   268  For the DEL action, the runtime MUST execute the plugins in reverse-order.
   269  
   270  #### Network Configuration List Error Handling
   271  
   272  When an error occurs while executing an action on a plugin list (eg, either ADD or DEL) the runtime MUST stop execution of the list.
   273  
   274  If an ADD action fails, when the runtime decides to handle the failure it should execute the DEL action (in reverse order from the ADD as specified above) for all plugins in the list, even if some were not called during the ADD action.
   275  
   276  Plugins should generally complete a DEL action without error even if some resources are missing.  For example, an IPAM plugin should generally release an IP allocation and return success even if the container network namespace no longer exists, unless that network namespace is critical for IPAM management. While DHCP may usually send a 'release' message on the container network interface, since DHCP leases have a lifetime this release action would not be considered critical and no error should be returned. For another example, the `bridge` plugin should delegate the DEL action to the IPAM plugin and clean up its own resources (if present) even if the container network namespace and/or container network interface no longer exist.
   277  
   278  #### Example network configuration lists
   279  
   280  ```json
   281  {
   282    "cniVersion": "0.3.1",
   283    "name": "dbnet",
   284    "plugins": [
   285      {
   286        "type": "bridge",
   287        // type (plugin) specific
   288        "bridge": "cni0",
   289        // args may be ignored by plugins
   290        "args": {
   291          "labels" : {
   292              "appVersion" : "1.0"
   293          }
   294        },
   295        "ipam": {
   296          "type": "host-local",
   297          // ipam specific
   298          "subnet": "10.1.0.0/16",
   299          "gateway": "10.1.0.1"
   300        },
   301        "dns": {
   302          "nameservers": [ "10.1.0.1" ]
   303        }
   304      },
   305      {
   306        "type": "tuning",
   307        "sysctl": {
   308          "net.core.somaxconn": "500"
   309        }
   310      }
   311    ]
   312  }
   313  ```
   314  
   315  #### Network configuration list runtime examples
   316  
   317  Given the network configuration list JSON [shown above](#example-network-configuration-lists) the container runtime would perform the following steps for the ADD action.
   318  Note that the runtime adds the `cniVersion` and `name` fields from configuration list to the configuration JSON passed to each plugin, to ensure consistent versioning and names for all plugins in the list.
   319  
   320  1) first call the `bridge` plugin with the following JSON:
   321  
   322  ```json
   323  {
   324    "cniVersion": "0.3.1",
   325    "name": "dbnet",
   326    "type": "bridge",
   327    "bridge": "cni0",
   328    "args": {
   329      "labels" : {
   330          "appVersion" : "1.0"
   331      }
   332    },
   333    "ipam": {
   334      "type": "host-local",
   335      // ipam specific
   336      "subnet": "10.1.0.0/16",
   337      "gateway": "10.1.0.1"
   338    },
   339    "dns": {
   340      "nameservers": [ "10.1.0.1" ]
   341    }
   342  }
   343  ```
   344  
   345  2) next call the `tuning` plugin with the following JSON, including the `prevResult` field containing the JSON response from the `bridge` plugin:
   346  
   347  ```json
   348  {
   349    "cniVersion": "0.3.1",
   350    "name": "dbnet",
   351    "type": "tuning",
   352    "sysctl": {
   353      "net.core.somaxconn": "500"
   354    },
   355    "prevResult": {
   356      "ips": [
   357          {
   358            "version": "4",
   359            "address": "10.0.0.5/32",
   360            "interface": 0
   361          }
   362      ],
   363      "dns": {
   364        "nameservers": [ "10.1.0.1" ]
   365      }
   366    }
   367  }
   368  ```
   369  
   370  Given the same network configuration JSON list, the container runtime would perform the following steps for the DEL action.
   371  Note that no `prevResult` field is required as the DEL action does not return any result.
   372  Also note that plugins are executed in reverse order from the ADD action.
   373  
   374  1) first call the `tuning` plugin with the following JSON:
   375  
   376  ```json
   377  {
   378    "cniVersion": "0.3.1",
   379    "name": "dbnet",
   380    "type": "tuning",
   381    "sysctl": {
   382      "net.core.somaxconn": "500"
   383    }
   384  }
   385  ```
   386  
   387  2) next call the `bridge` plugin with the following JSON:
   388  
   389  ```json
   390  {
   391    "cniVersion": "0.3.1",
   392    "name": "dbnet",
   393    "type": "bridge",
   394    "bridge": "cni0",
   395    "args": {
   396      "labels" : {
   397          "appVersion" : "1.0"
   398      }
   399    },
   400    "ipam": {
   401      "type": "host-local",
   402      // ipam specific
   403      "subnet": "10.1.0.0/16",
   404      "gateway": "10.1.0.1"
   405    },
   406    "dns": {
   407      "nameservers": [ "10.1.0.1" ]
   408    }
   409  }
   410  ```
   411  
   412  ### IP Allocation
   413  
   414  As part of its operation, a CNI plugin is expected to assign (and maintain) an IP address to the interface and install any necessary routes relevant for that interface. This gives the CNI plugin great flexibility but also places a large burden on it. Many CNI plugins would need to have the same code to support several IP management schemes that users may desire (e.g. dhcp, host-local). 
   415  
   416  To lessen the burden and make IP management strategy be orthogonal to the type of CNI plugin, we define a second type of plugin -- IP Address Management Plugin (IPAM plugin). It is however the responsibility of the CNI plugin to invoke the IPAM plugin at the proper moment in its execution. The IPAM plugin is expected to determine the interface IP/subnet, Gateway and Routes and return this information to the "main" plugin to apply. The IPAM plugin may obtain the information via a protocol (e.g. dhcp), data stored on a local filesystem, the "ipam" section of the Network Configuration file or a combination of the above.
   417  
   418  #### IP Address Management (IPAM) Interface
   419  
   420  Like CNI plugins, the IPAM plugins are invoked by running an executable. The executable is searched for in a predefined list of paths, indicated to the CNI plugin via `CNI_PATH`. The IPAM Plugin receives all the same environment variables that were passed in to the CNI plugin. Just like the CNI plugin, IPAM receives the network configuration via stdin.
   421  
   422  Success is indicated by a zero return code and the following JSON being printed to stdout (in the case of the ADD command):
   423  
   424  ```
   425  {
   426    "cniVersion": "0.3.1",
   427    "ips": [
   428        {
   429            "version": "<4-or-6>",
   430            "address": "<ip-and-prefix-in-CIDR>",
   431            "gateway": "<ip-address-of-the-gateway>"  (optional)
   432        },
   433        ...
   434    ],
   435    "routes": [                                       (optional)
   436        {
   437            "dst": "<ip-and-prefix-in-cidr>",
   438            "gw": "<ip-of-next-hop>"                  (optional)
   439        },
   440        ...
   441    ]
   442    "dns": {
   443      "nameservers": <list-of-nameservers>            (optional)
   444      "domain": <name-of-local-domain>                (optional)
   445      "search": <list-of-search-domains>              (optional)
   446      "options": <list-of-options>                    (optional)
   447    }
   448  }
   449  ```
   450  
   451  Note that unlike regular CNI plugins, IPAM plugins return an abbreviated `Result` structure that does not include the `interfaces` key, since IPAM plugins should be unaware of interfaces configured by their parent plugin except those specifically required for IPAM (eg, like the `dhcp` IPAM plugin).
   452  
   453  `cniVersion` specifies a [Semantic Version 2.0](http://semver.org) of CNI specification used by the plugin.
   454  
   455  The `ips` field is a list of IP configuration information.
   456  See the [IP well-known structure](#ips) section for more information.
   457  
   458  The `dns` field contains a dictionary consisting of common DNS information.
   459  See the [DNS well-known structure](#dns) section for more information.
   460  
   461  Errors and logs are communicated in the same way as the CNI plugin. See [CNI Plugin Result](#result) section for details.
   462  
   463  IPAM plugin examples:
   464   - **host-local**: Select an unused (by other containers on the same host) IP within the specified range.
   465   - **dhcp**: Use DHCP protocol to acquire and maintain a lease. The DHCP requests will be sent via the created container interface; therefore, the associated network must support broadcast.
   466  
   467  #### Notes
   468   - Routes are expected to be added with a 0 metric.
   469   - A default route may be specified via "0.0.0.0/0". Since another network might have already configured the default route, the CNI plugin should be prepared to skip over its default route definition.
   470  
   471  ### Well-known Structures
   472  
   473  #### IPs
   474  
   475  ```
   476    "ips": [
   477        {
   478            "version": "<4-or-6>",
   479            "address": "<ip-and-prefix-in-CIDR>",
   480            "gateway": "<ip-address-of-the-gateway>",      (optional)
   481            "interface": <numeric index into 'interfaces' list> (not required for IPAM plugins)
   482        },
   483        ...
   484    ]
   485  ```
   486  
   487  The `ips` field is a list of IP configuration information determined by the plugin. Each item is a dictionary describing of IP configuration for a network interface.
   488  IP configuration for multiple network interfaces and multiple IP configurations for a single interface may be returned as separate items in the `ips` list.
   489  All properties known to the plugin should be provided, even if not strictly required.
   490  - `version` (string): either "4" or "6" and corresponds to the IP version of the addresses in the entry.
   491     All IP addresses and gateways provided must be valid for the given `version`.
   492  - `address` (string): an IP address in CIDR notation (eg "192.168.1.3/24").
   493  - `gateway` (string): the default gateway for this subnet, if one exists.
   494     It does not instruct the CNI plugin to add any routes with this gateway: routes to add are specified separately via the `routes` field.
   495     An example use of this value is for the CNI `bridge` plugin to add this IP address to the Linux bridge to make it a gateway.
   496  - `interface` (uint): the index into the `interfaces` list for a [CNI Plugin Result](#result) indicating which interface this IP configuration should be applied to.
   497     IPAM plugins should not return this key since they have no information about network interfaces.
   498  
   499  #### Routes
   500  
   501  ```
   502    "routes": [
   503        {
   504            "dst": "<ip-and-prefix-in-cidr>",
   505            "gw": "<ip-of-next-hop>"               (optional)
   506        },
   507        ...
   508    ]
   509  ```
   510  
   511  - Each `routes` entry is a dictionary with the following fields.  All IP addresses in the `routes` entry must be the same IP version, either 4 or 6.
   512    - `dst` (string): destination subnet specified in CIDR notation.
   513    - `gw` (string): IP of the gateway. If omitted, a default gateway is assumed (as determined by the CNI plugin).
   514  
   515  #### DNS
   516  
   517  ```
   518    "dns": {
   519      "nameservers": <list-of-nameservers>                 (optional)
   520      "domain": <name-of-local-domain>                     (optional)
   521      "search": <list-of-additional-search-domains>        (optional)
   522      "options": <list-of-options>                         (optional)
   523    }
   524  ```
   525  
   526  The `dns` field contains a dictionary consisting of common DNS information.
   527  - `nameservers` (list of strings): list of a priority-ordered list of DNS nameservers that this network is aware of. Each entry in the list is a string containing either an IPv4 or an IPv6 address.
   528  - `domain` (string): the local domain used for short hostname lookups.
   529  - `search` (list of strings): list of priority ordered search domains for short hostname lookups. Will be preferred over `domain` by most resolvers.
   530  - `options` (list of strings): list of options that can be passed to the resolver.
   531    See [CNI Plugin Result](#result) section for more information.
   532  
   533  ## Well-known Error Codes
   534  - `1` - Incompatible CNI version
   535  - `2` - Unsupported field in network configuration. The error message must contain the key and value of the unsupported field.