Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package cni for openSUSE:Factory checked in 
at 2026-09-08 16:58:15
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/cni (Old)
 and      /work/SRC/openSUSE:Factory/.cni.new.1265 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "cni"

Tue Sep  8 16:58:15 2026 rev:23 rq:1376337 version:1.3.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/cni/cni.changes  2025-04-22 17:28:48.100389091 
+0200
+++ /work/SRC/openSUSE:Factory/.cni.new.1265/cni.changes        2026-09-08 
17:01:56.757571397 +0200
@@ -1,0 +2,20 @@
+Mon Sep 07 04:57:18 UTC 2026 - Bharti Gautam <[email protected]>
+
+- Update to version 1.3.1:
+  * pkg/invoke: add OpenTelemetry trace context propagation
+  * docs: Fix broken link to "Version considerations" in SPEC.md
+  * README: change meeting to 10:00 US/East.
+  * Update test expectations to tolerate error
+  * Tolerate invalid cni cache for DelNetwork
+  * spec: update number of specifically defined terms
+  * moving meeting to bi-weekly
+  * Fix golangci and ci lint error
+  * Add exec error when stderr is present
+  * Update my email
+  * refactor: cni-tool with cobra
+  * update MAINTAINERS
+  * Clarify some language around `DEL` and `prevResult`
+  * remove archived 3rd party plugins
+  * Add error codes for STATUS verb to `types.go` and `SPEC.md`
+
+-------------------------------------------------------------------

Old:
----
  cni-1.3.0.obscpio

New:
----
  cni-1.3.1.obscpio

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ cni.spec ++++++
--- /var/tmp/diff_new_pack.LdBSQ4/_old  2026-09-08 17:01:57.990622937 +0200
+++ /var/tmp/diff_new_pack.LdBSQ4/_new  2026-09-08 17:01:57.993623063 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package cni
 #
-# Copyright (c) 2023 SUSE LLC
+# Copyright (c) 2026 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -22,7 +22,7 @@
 %define         cni_bin_dir  %{_libexecdir}/cni
 %define         cni_doc_dir  %{_docdir}/cni
 Name:           cni
-Version:        1.3.0
+Version:        1.3.1
 Release:        0
 Summary:        Container Network Interface - networking for Linux containers
 License:        Apache-2.0
@@ -34,8 +34,8 @@
 BuildRequires:  golang-packaging
 BuildRequires:  shadow
 BuildRequires:  systemd-rpm-macros
-BuildRequires:  golang(API) >= 1.21
 BuildRequires:  zstd
+BuildRequires:  golang(API) >= 1.21
 Requires(post): %fillup_prereq
 Recommends:     cni-plugins
 %{?systemd_requires}

++++++ _service ++++++
--- /var/tmp/diff_new_pack.LdBSQ4/_old  2026-09-08 17:01:58.050625445 +0200
+++ /var/tmp/diff_new_pack.LdBSQ4/_new  2026-09-08 17:01:58.053625571 +0200
@@ -2,7 +2,7 @@
   <service name="obs_scm" mode="manual">
     <param name="url">https://github.com/containernetworking/cni.git</param>
     <param name="scm">git</param>
-    <param name="revision">v1.3.0</param>
+    <param name="revision">v1.3.1</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="versionrewrite-pattern">v(.*)</param>
     <!-- filter out spec-vN.M.O tags -->

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.LdBSQ4/_old  2026-09-08 17:01:58.084626867 +0200
+++ /var/tmp/diff_new_pack.LdBSQ4/_new  2026-09-08 17:01:58.089627076 +0200
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param 
name="url">https://github.com/containernetworking/cni.git</param>
-              <param 
name="changesrevision">a28faab92684aed3af64d5085733c34550ce9877</param></service></servicedata>
+              <param 
name="changesrevision">3f51e8803ebbdba0ebeed735b42137e4c7302403</param></service></servicedata>
 (No newline at EOF)
 

++++++ cni-1.3.0.obscpio -> cni-1.3.1.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cni-1.3.0/.golangci.yml new/cni-1.3.1/.golangci.yml
--- old/cni-1.3.0/.golangci.yml 2025-04-07 17:37:53.000000000 +0200
+++ new/cni-1.3.1/.golangci.yml 2026-08-13 02:47:07.000000000 +0200
@@ -1,30 +1,42 @@
+version: "2"
+
 linters:
   enable:
     - contextcheck
-    - errcheck
     - errorlint
-    - gci
     - ginkgolinter
     - gocritic
-    - gofumpt
-    - govet
-    - ineffassign
     - misspell
     - nolintlint
     - nonamedreturns
     - predeclared
-    - staticcheck
-    - typecheck
     - unconvert
-    - unused
     - whitespace
+  exclusions:
+    generated: lax
+    presets:
+      - comments
+      - common-false-positives
+      - legacy
+      - std-error-handling
+    paths:
+      - third_party$
+      - builtin$
+      - examples$
 
-linters-settings:
-  gci:
-    sections:
-      - standard
-      - default
-      - prefix(github.com/containernetworking)
-
-run:
-  timeout: 5m
+formatters:
+  enable:
+    - gci
+    - gofumpt
+  settings:
+    gci:
+      sections:
+        - standard
+        - default
+        - prefix(github.com/containernetworking)
+  exclusions:
+    generated: lax
+    paths:
+      - third_party$
+      - builtin$
+      - examples$
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cni-1.3.0/MAINTAINERS new/cni-1.3.1/MAINTAINERS
--- old/cni-1.3.0/MAINTAINERS   2025-04-07 17:37:53.000000000 +0200
+++ new/cni-1.3.1/MAINTAINERS   2026-08-13 02:47:07.000000000 +0200
@@ -1,10 +1,14 @@
 Bruce Ma <[email protected]> (@mars1024)
 Casey Callendrello <[email protected]> (@squeed)
-Dan Williams <[email protected]> (@dcbw)
-Matt Dupre <[email protected]> (@matthewdupre)
 Michael Cambria <[email protected]> (@mccv1r0)
 Michael Zappa <[email protected]> (@MikeZappa87)
-Piotr Skamruk <[email protected]> (@jellonek)
-Tomofumi Hayashi <[email protected]> (@s1061123)
+Tomofumi Hayashi <[email protected]> (@s1061123)
 Lionel Jouin <[email protected]> (@LionelJouin)
-Ben Leggett <[email protected]> (@bleggett)
+Ben Leggett <[email protected]> (@bleggett)
+Marcelo Guerrero <[email protected]> (@mlguerrero12)
+Doug Smith <[email protected]> (@dougbtv)
+
+Emeritus:
+Dan Williams <[email protected]> (@dcbw)
+Matt Dupre <[email protected]> (@matthewdupre)
+Piotr Skamruk <[email protected]> (@jellonek)
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cni-1.3.0/README.md new/cni-1.3.1/README.md
--- old/cni-1.3.0/README.md     2025-04-07 17:37:53.000000000 +0200
+++ new/cni-1.3.1/README.md     2026-08-13 02:47:07.000000000 +0200
@@ -29,7 +29,7 @@
 We welcome contributions, including [bug 
reports](https://github.com/containernetworking/cni/issues), and code and 
documentation improvements.
 If you intend to contribute to code or documentation, please read 
[CONTRIBUTING.md](CONTRIBUTING.md). Also see the [contact section](#contact) in 
this README.
 
-The CNI project has a [weekly 
meeting](https://meet.jit.si/CNIMaintainersMeeting). It takes place Mondays at 
11:00 US/Eastern. All are welcome to join.
+The CNI project has a [biweekly 
meeting](https://calendar.google.com/calendar/event?action=TEMPLATE&tmeid=Yzg1NDlibnA5Y2c0Nm5scDI4ZG5udWpmY2JfMjAyNTEwMTNUMTQwMDAwWiAyMmM0NjU1ZjFjMjkzZTg0NDRhNTU2OTVmNDIxODg3MDgwYzc1OWU0YTQ1MjVhYmQ2NTFmYmI2MGVlYTc2YzE5QGc&tmsrc=22c4655f1c293e8444a55695f421887080c759e4a4525abd651fbb60eea76c19%40group.calendar.google.com&scp=ALL)
 on [jitsi](https://meet.jit.si/CNIMaintainersMeeting) 
([notes](https://github.com/containernetworking/meeting-notes)). It takes place 
Mondays at 10:00 US/Eastern. All are welcome to join.
 
 ## Why develop CNI?
 
@@ -40,7 +40,6 @@
 
 ## Who is using CNI?
 ### Container runtimes
-- [rkt - container engine](https://coreos.com/blog/rkt-cni-networking.html)
 - [Kubernetes - a system to simplify container 
operations](https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/)
 - [OpenShift - Kubernetes with additional enterprise 
features](https://github.com/openshift/origin/blob/master/docs/openshift_networking_requirements.md)
 - [Cloud Foundry - a platform for cloud 
applications](https://github.com/cloudfoundry-incubator/cf-networking-release)
@@ -51,16 +50,13 @@
 
 ### 3rd party plugins
 - [Project Calico - a layer 3 virtual 
network](https://github.com/projectcalico/calico)
-- [Weave - a multi-host Docker network](https://github.com/weaveworks/weave)
 - [Contiv Networking - policy networking for various use 
cases](https://github.com/contiv/netplugin)
 - [SR-IOV](https://github.com/hustcat/sriov-cni)
-- [Cilium - BPF & XDP for containers](https://github.com/cilium/cilium)
-- [Infoblox - enterprise IP address management for 
containers](https://github.com/infobloxopen/cni-infoblox)
+- [Cilium - eBPF & XDP for containers](https://github.com/cilium/cilium)
 - [Multus - a Multi plugin](https://github.com/k8snetworkplumbingwg/multus-cni)
 - [Romana - Layer 3 CNI plugin supporting network policy for 
Kubernetes](https://github.com/romana/kube)
 - [CNI-Genie - generic CNI network 
plugin](https://github.com/Huawei-PaaS/CNI-Genie)
 - [Nuage CNI - Nuage Networks SDN plugin for network policy kubernetes support 
](https://github.com/nuagenetworks/nuage-cni)
-- [Silk - a CNI plugin designed for Cloud 
Foundry](https://github.com/cloudfoundry-incubator/silk)
 - [Linen - a CNI plugin designed for overlay networks with Open vSwitch and 
fit in SDN/OpenFlow network environment](https://github.com/John-Lin/linen-cni)
 - [Vhostuser - a Dataplane network plugin - Supports OVS-DPDK & 
VPP](https://github.com/intel/vhost-user-net-plugin)
 - [Amazon ECS CNI Plugins - a collection of CNI Plugins to configure 
containers with Amazon EC2 elastic network interfaces 
(ENIs)](https://github.com/aws/amazon-ecs-cni-plugins)
@@ -69,13 +65,11 @@
 - [Juniper Contrail](https://www.juniper.net/cloud) / 
[TungstenFabric](https://tungstenfabric.io) -  Provides overlay SDN solution, 
delivering multicloud networking, hybrid cloud networking, simultaneous 
overlay-underlay support, network policy enforcement, network isolation, 
service chaining and flexible load balancing
 - [Knitter - a CNI plugin supporting multiple networking for 
Kubernetes](https://github.com/ZTE/Knitter)
 - [DANM - a CNI-compliant networking solution for TelCo workloads running on 
Kubernetes](https://github.com/nokia/danm)
-- [VMware NSX – a CNI plugin that enables automated NSX L2/L3 networking and 
L4/L7 Load Balancing; network isolation at the pod, node, and cluster level; 
and zero-trust security policy for your Kubernetes 
cluster.](https://docs.vmware.com/en/VMware-NSX-T/2.2/com.vmware.nsxt.ncp_kubernetes.doc/GUID-6AFA724E-BB62-4693-B95C-321E8DDEA7E1.html)
 - [cni-route-override - a meta CNI plugin that override route 
information](https://github.com/redhat-nfvpe/cni-route-override)
 - [Terway - a collection of CNI Plugins based on alibaba cloud VPC/ECS network 
product](https://github.com/AliyunContainerService/terway)
 - [Cisco ACI CNI - for on-prem and cloud container networking with consistent 
policy and security model.](https://github.com/noironetworks/aci-containers)
 - [Kube-OVN - a CNI plugin that bases on OVN/OVS and provides advanced 
features like subnet, static ip, ACL, QoS, 
etc.](https://github.com/kubeovn/kube-ovn)
 - [Project Antrea - an Open vSwitch k8s 
CNI](https://github.com/vmware-tanzu/antrea)
-- [OVN4NFV-K8S-Plugin - a OVN based CNI controller plugin to provide cloud 
native based Service function chaining (SFC), Multiple OVN overlay 
networking](https://github.com/opnfv/ovn4nfv-k8s-plugin)
 - [Azure CNI - a CNI plugin that natively extends Azure Virtual Networks to 
containers](https://github.com/Azure/azure-container-networking)
 - [Hybridnet - a CNI plugin designed for hybrid clouds which provides both 
overlay and underlay networking for containers in one or more clusters. Overlay 
and underlay containers can run on the same node and have cluster-wide 
bidirectional network connectivity.](https://github.com/alibaba/hybridnet)
 - [Spiderpool - An IP Address Management (IPAM) CNI plugin of Kubernetes for 
managing static ip for underlay 
network](https://github.com/spidernet-io/spiderpool)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cni-1.3.0/SPEC.md new/cni-1.3.1/SPEC.md
--- old/cni-1.3.0/SPEC.md       2025-04-07 17:37:53.000000000 +0200
+++ new/cni-1.3.1/SPEC.md       2026-08-13 02:47:07.000000000 +0200
@@ -69,7 +69,7 @@
 
 This document proposes a generic plugin-based networking solution for 
application containers on Linux, the _Container Networking Interface_, or _CNI_.
 
-For the purposes of this proposal, we define three terms very specifically:
+For the purposes of this proposal, we define four terms very specifically:
 - _container_ is a network isolation domain, though the actual isolation 
technology is not defined by the specification. This could be a [network 
namespace][namespaces] or a virtual machine, for example.
 - _network_ refers to a group of endpoints 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.
 - _runtime_ is the program responsible for executing CNI plugins.
@@ -108,7 +108,7 @@
 A network configuration consists of a JSON object with the following keys:
 
 - `cniVersion` (string): [Semantic Version 2.0](https://semver.org) of CNI 
specification to which this configuration list and all the individual 
configurations conform. Currently "1.1.0"
-- `cniVersions` (string list): List of all CNI versions which this 
configuration supports. See [version selection](#version-selection) below.
+- `cniVersions` (string list): List of all CNI versions which this 
configuration supports. See [version selection](#version-considerations) below.
 - `name` (string): Network name. This should be unique across all network 
configurations on a host (or other administrative domain).  Must start with an 
alphanumeric character, optionally followed by any combination of one or more 
alphanumeric characters, underscore, dot (.) or hyphen (-). Must not contain 
characters disallowed in file paths.
 - `disableCheck` (boolean): Either `true` or `false`.  If `disableCheck` is 
`true`, runtimes must not call `CHECK` for this network configuration list.  
This allows an administrator to prevent `CHECK`ing where a combination of 
plugins is known to return spurious errors.
 - `disableGC` (boolean): Either `true` or `false`.  If `disableGC` is `true`, 
runtimes must not call `GC` for this network configuration list.  This allows 
an administrator to prevent `GC`ing when it is known that garbage collection 
may have undesired effects (e.g. shared configuration between multiple 
runtimes).
@@ -268,7 +268,10 @@
 - delete the interface defined by `CNI_IFNAME` inside the container at 
`CNI_NETNS`, or
 - undo any modifications applied in the plugin's `ADD` functionality
 
-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 if this action fails. For 
another example, the `bridge` plugin should delegate the DEL action to the IPAM 
plugin and clean up its own resources even if the container network namespace 
and/or container network interface no longer exist.
+A `prevResult` must be supplied to CNI plugins as part of a `DEL` command. For 
the first plugin in the `DEL` command plugin chain, this `prevResult` will be 
the final result of the previous `ADD` command.
+Plugins should still return without error if `prevResult` is empty for a `DEL` 
command, however.
+
+`DEL` command invocations are always considered best-effort - plugins should 
always complete a `DEL` action without error to the fullest extent possible, 
even if some resources or state 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 if this 
action fails. For another example, the `bridge` plugin should delegate the DEL 
action to the IPAM plugin and clean up its own resources even if the container 
network namespace and/or container network interface no longer exist.
 
 Plugins MUST accept multiple `DEL` calls for the same (`CNI_CONTAINERID`, 
`CNI_IFNAME`) pair, and return success if the interface in question, or any 
modifications added, are missing.
 
@@ -648,6 +651,8 @@
  `6`|Failed to decode content. For example, failed to unmarshal network config 
from bytes or failed to decode version info from string.
  `7`|Invalid network config. If some validations on network configs do not 
pass, this error will be raised.
  `11`|Try again later. If the plugin detects some transient condition that 
should clear up, it can use this code to notify the runtime it should re-try 
the operation later.
+ `50`|The plugin is not available (i.e. cannot service `ADD` requests)
+ `51`|The plugin is not available, and existing containers in the network may 
have limited connectivity.
 
 In addition, stderr can be used for unstructured output such as logs.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cni-1.3.0/cnitool/README.md 
new/cni-1.3.1/cnitool/README.md
--- old/cni-1.3.0/cnitool/README.md     2025-04-07 17:37:53.000000000 +0200
+++ new/cni-1.3.1/cnitool/README.md     2026-08-13 02:47:07.000000000 +0200
@@ -1,7 +1,7 @@
 # cnitool
 
 `cnitool` is a simple program that executes a CNI configuration. It will
-add or remove an interface in an already-created network namespace.
+add, check, remove, gc, or get status of an interface in an already-created 
network namespace.
 
 ## Environment Variables
 
@@ -9,15 +9,42 @@
   directory. It defaults to `/etc/cni/net.d`. The `cnitool` searches
   for CNI configuration files in this directory according to the following 
priorities:
   1. Search files with the extension `*.conflist`, representing a list of 
plugin configurations.
-  2. If there are no `*.conflist` files in the directory, search files with 
the extension `*.conf` or `*.json`, 
+  2. If there are no `*.conflist` files in the directory, search files with 
the extension `*.conf` or `*.json`,
   representing a single plugin configuration.
-  
+
   It loads all the CNI configuration files in
   this directory and if it finds a CNI configuration with the `network
   name` given to the cnitool it returns the corresponding CNI
   configuration, else it returns `nil`.
 * `CNI_PATH`: For a given CNI configuration `cnitool` will search for
   the corresponding CNI plugin in this path.
+* `CNI_ARGS`: Optional arguments in the format "KEY1=VALUE1;KEY2=VALUE2;..." 
passed to the CNI plugin.
+* `CAP_ARGS`: Optional capability arguments in JSON format passed to the CNI 
plugin.
+* `CNI_IFNAME`: Interface name to be configured. Defaults to "eth0" if not 
specified.
+
+## Command Line Usage
+
+```bash
+cnitool: CNI Tool for managing network interfaces in a network namespace
+
+Usage:
+  cnitool [command]
+
+Available Commands:
+  add         Add network interface to a network namespace
+  check       Check network interface in a network namespace
+  completion  Generate the autocompletion script for the specified shell
+  del         Delete network interface from a network namespace
+  gc          Garbage collect network interfaces
+  help        Help about any command
+  status      Get status of network interfaces
+
+Flags:
+  -h, --help            help for cnitool
+  -i, --ifname string   Interface name (defaults to env var CNI_IFNAME or 
'eth0')
+
+Use "cnitool [command] --help" for more information about a command.
+```
 
 ## Example invocation
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cni-1.3.0/cnitool/cmd/add.go 
new/cni-1.3.1/cnitool/cmd/add.go
--- old/cni-1.3.0/cnitool/cmd/add.go    1970-01-01 01:00:00.000000000 +0100
+++ new/cni-1.3.1/cnitool/cmd/add.go    2026-08-13 02:47:07.000000000 +0200
@@ -0,0 +1,51 @@
+// Copyright 2015 CNI authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cmd
+
+import (
+       "context"
+
+       "github.com/spf13/cobra"
+)
+
+// addCmd represents the add command
+var addCmd = &cobra.Command{
+       Use:   "add <network-name> <netns>",
+       Short: "Add network interface to a network namespace",
+       Long: `Add network interface to a network namespace.
+This command will create a new network interface and add it to the specified 
network namespace.`,
+       Args: cobra.MinimumNArgs(2),
+       RunE: func(cmd *cobra.Command, args []string) error {
+               netconf, rt, err := setupRuntimeConfig(cmd, args)
+               if err != nil {
+                       return err
+               }
+
+               cninet := getCNIConfig()
+               result, err := cninet.AddNetworkList(context.TODO(), netconf, 
rt)
+               if err != nil {
+                       return err
+               }
+
+               if result != nil {
+                       _ = result.Print()
+               }
+               return nil
+       },
+}
+
+func init() {
+       rootCmd.AddCommand(addCmd)
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cni-1.3.0/cnitool/cmd/check.go 
new/cni-1.3.1/cnitool/cmd/check.go
--- old/cni-1.3.0/cnitool/cmd/check.go  1970-01-01 01:00:00.000000000 +0100
+++ new/cni-1.3.1/cnitool/cmd/check.go  2026-08-13 02:47:07.000000000 +0200
@@ -0,0 +1,43 @@
+// Copyright 2015 CNI authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cmd
+
+import (
+       "context"
+
+       "github.com/spf13/cobra"
+)
+
+// checkCmd represents the check command
+var checkCmd = &cobra.Command{
+       Use:   "check <network-name> <netns>",
+       Short: "Check network interface in a network namespace",
+       Long: `Check network interface in a network namespace.
+This command will check if the network interface is properly configured in the 
specified network namespace.`,
+       Args: cobra.MinimumNArgs(2),
+       RunE: func(cmd *cobra.Command, args []string) error {
+               netconf, rt, err := setupRuntimeConfig(cmd, args)
+               if err != nil {
+                       return err
+               }
+
+               cninet := getCNIConfig()
+               return cninet.CheckNetworkList(context.TODO(), netconf, rt)
+       },
+}
+
+func init() {
+       rootCmd.AddCommand(checkCmd)
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cni-1.3.0/cnitool/cmd/del.go 
new/cni-1.3.1/cnitool/cmd/del.go
--- old/cni-1.3.0/cnitool/cmd/del.go    1970-01-01 01:00:00.000000000 +0100
+++ new/cni-1.3.1/cnitool/cmd/del.go    2026-08-13 02:47:07.000000000 +0200
@@ -0,0 +1,43 @@
+// Copyright 2015 CNI authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cmd
+
+import (
+       "context"
+
+       "github.com/spf13/cobra"
+)
+
+// delCmd represents the del command
+var delCmd = &cobra.Command{
+       Use:   "del <network-name> <netns>",
+       Short: "Delete network interface from a network namespace",
+       Long: `Delete network interface from a network namespace.
+This command will remove the network interface from the specified network 
namespace.`,
+       Args: cobra.MinimumNArgs(2),
+       RunE: func(cmd *cobra.Command, args []string) error {
+               netconf, rt, err := setupRuntimeConfig(cmd, args)
+               if err != nil {
+                       return err
+               }
+
+               cninet := getCNIConfig()
+               return cninet.DelNetworkList(context.TODO(), netconf, rt)
+       },
+}
+
+func init() {
+       rootCmd.AddCommand(delCmd)
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cni-1.3.0/cnitool/cmd/gc.go 
new/cni-1.3.1/cnitool/cmd/gc.go
--- old/cni-1.3.0/cnitool/cmd/gc.go     1970-01-01 01:00:00.000000000 +0100
+++ new/cni-1.3.1/cnitool/cmd/gc.go     2026-08-13 02:47:07.000000000 +0200
@@ -0,0 +1,44 @@
+// Copyright 2015 CNI authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cmd
+
+import (
+       "context"
+
+       "github.com/spf13/cobra"
+)
+
+// gcCmd represents the gc command
+var gcCmd = &cobra.Command{
+       Use:   "gc <network-name> <netns>",
+       Short: "Garbage collect network interfaces",
+       Long: `Garbage collect network interfaces.
+This command will clean up unused network interfaces in the specified network 
namespace.`,
+       Args: cobra.MinimumNArgs(2),
+       RunE: func(cmd *cobra.Command, args []string) error {
+               netconf, _, err := setupRuntimeConfig(cmd, args)
+               if err != nil {
+                       return err
+               }
+
+               cninet := getCNIConfig()
+               // Currently just invoke GC without args, hence all network 
interface should be GC'ed!
+               return cninet.GCNetworkList(context.TODO(), netconf, nil)
+       },
+}
+
+func init() {
+       rootCmd.AddCommand(gcCmd)
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cni-1.3.0/cnitool/cmd/root.go 
new/cni-1.3.1/cnitool/cmd/root.go
--- old/cni-1.3.0/cnitool/cmd/root.go   1970-01-01 01:00:00.000000000 +0100
+++ new/cni-1.3.1/cnitool/cmd/root.go   2026-08-13 02:47:07.000000000 +0200
@@ -0,0 +1,155 @@
+// Copyright 2015 CNI authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cmd
+
+import (
+       "crypto/sha512"
+       "encoding/json"
+       "fmt"
+       "os"
+       "path/filepath"
+       "strings"
+
+       "github.com/spf13/cobra"
+
+       "github.com/containernetworking/cni/libcni"
+)
+
+// Protocol parameters are passed to the plugins via OS environment variables.
+const (
+       EnvCNIPath        = "CNI_PATH"
+       EnvNetDir         = "NETCONFPATH"
+       EnvCapabilityArgs = "CAP_ARGS"
+       EnvCNIArgs        = "CNI_ARGS"
+       EnvCNIIfname      = "CNI_IFNAME"
+
+       DefaultNetDir = "/etc/cni/net.d"
+)
+
+var (
+       // Used for flags
+       netName string
+       netNS   string
+       ifName  string
+
+       rootCmd = &cobra.Command{
+               Use:   "cnitool",
+               Short: "CNI Tool for managing network interfaces in a network 
namespace",
+               Long: `CNI Tool is a simple program that executes a CNI 
configuration.
+It will add, check, remove, gc, or get status of an interface in an 
already-created network namespace.`,
+       }
+)
+
+// Execute executes the root command.
+func Execute() error {
+       return rootCmd.Execute()
+}
+
+func init() {
+       // Global flags
+       rootCmd.PersistentFlags().StringVarP(&ifName, "ifname", "i", "", 
"Interface name (defaults to env var CNI_IFNAME or 'eth0')")
+}
+
+// parseArgs parses CNI_ARGS environment variable into key-value pairs
+func parseArgs(args string) ([][2]string, error) {
+       var result [][2]string
+
+       pairs := strings.Split(args, ";")
+       for _, pair := range pairs {
+               kv := strings.Split(pair, "=")
+               if len(kv) != 2 || kv[0] == "" || kv[1] == "" {
+                       return nil, fmt.Errorf("invalid CNI_ARGS pair %q", pair)
+               }
+
+               result = append(result, [2]string{kv[0], kv[1]})
+       }
+
+       return result, nil
+}
+
+// setupRuntimeConfig prepares the runtime configuration for CNI operations
+func setupRuntimeConfig(cmd *cobra.Command, args []string) 
(*libcni.NetworkConfigList, *libcni.RuntimeConf, error) {
+       if len(args) < 2 {
+               return nil, nil, fmt.Errorf("network name and namespace are 
required")
+       }
+
+       netName = args[0]
+       netNS = args[1]
+
+       // Get network configuration directory
+       netdir := os.Getenv(EnvNetDir)
+       if netdir == "" {
+               netdir = DefaultNetDir
+       }
+
+       // Load network configuration
+       netconf, err := libcni.LoadNetworkConf(netdir, netName)
+       if err != nil {
+               return nil, nil, err
+       }
+
+       // Parse capability arguments
+       var capabilityArgs map[string]interface{}
+       capabilityArgsValue := os.Getenv(EnvCapabilityArgs)
+       if len(capabilityArgsValue) > 0 {
+               if err = json.Unmarshal([]byte(capabilityArgsValue), 
&capabilityArgs); err != nil {
+                       return nil, nil, err
+               }
+       }
+
+       // Parse CNI arguments
+       var cniArgs [][2]string
+       args_env := os.Getenv(EnvCNIArgs)
+       if len(args_env) > 0 {
+               cniArgs, err = parseArgs(args_env)
+               if err != nil {
+                       return nil, nil, err
+               }
+       }
+
+       // Get interface name from flag or environment variable
+       if ifName == "" {
+               ifName, _ = os.LookupEnv(EnvCNIIfname)
+               if ifName == "" {
+                       ifName = "eth0"
+               }
+       }
+
+       // Get absolute path of network namespace
+       netNS, err = filepath.Abs(netNS)
+       if err != nil {
+               return nil, nil, err
+       }
+
+       // Generate the containerid by hashing the netns path
+       s := sha512.Sum512([]byte(netNS))
+       containerID := fmt.Sprintf("cnitool-%x", s[:10])
+
+       // Create runtime configuration
+       rt := &libcni.RuntimeConf{
+               ContainerID:    containerID,
+               NetNS:          netNS,
+               IfName:         ifName,
+               Args:           cniArgs,
+               CapabilityArgs: capabilityArgs,
+       }
+
+       return netconf, rt, nil
+}
+
+// getCNIConfig returns a CNI configuration
+func getCNIConfig() *libcni.CNIConfig {
+       return libcni.NewCNIConfig(filepath.SplitList(os.Getenv(EnvCNIPath)), 
nil)
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cni-1.3.0/cnitool/cmd/status.go 
new/cni-1.3.1/cnitool/cmd/status.go
--- old/cni-1.3.0/cnitool/cmd/status.go 1970-01-01 01:00:00.000000000 +0100
+++ new/cni-1.3.1/cnitool/cmd/status.go 2026-08-13 02:47:07.000000000 +0200
@@ -0,0 +1,43 @@
+// Copyright 2015 CNI authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cmd
+
+import (
+       "context"
+
+       "github.com/spf13/cobra"
+)
+
+// statusCmd represents the status command
+var statusCmd = &cobra.Command{
+       Use:   "status <network-name> <netns>",
+       Short: "Get status of network interfaces",
+       Long: `Get status of network interfaces.
+This command will retrieve the status of network interfaces in the specified 
network namespace.`,
+       Args: cobra.MinimumNArgs(2),
+       RunE: func(cmd *cobra.Command, args []string) error {
+               netconf, _, err := setupRuntimeConfig(cmd, args)
+               if err != nil {
+                       return err
+               }
+
+               cninet := getCNIConfig()
+               return cninet.GetStatusNetworkList(context.TODO(), netconf)
+       },
+}
+
+func init() {
+       rootCmd.AddCommand(statusCmd)
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cni-1.3.0/cnitool/cnitool.go 
new/cni-1.3.1/cnitool/cnitool.go
--- old/cni-1.3.0/cnitool/cnitool.go    2025-04-07 17:37:53.000000000 +0200
+++ new/cni-1.3.1/cnitool/cnitool.go    1970-01-01 01:00:00.000000000 +0100
@@ -1,156 +0,0 @@
-// Copyright 2015 CNI authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package main
-
-import (
-       "context"
-       "crypto/sha512"
-       "encoding/json"
-       "fmt"
-       "os"
-       "path/filepath"
-       "strings"
-
-       "github.com/containernetworking/cni/libcni"
-)
-
-// Protocol parameters are passed to the plugins via OS environment variables.
-const (
-       EnvCNIPath        = "CNI_PATH"
-       EnvNetDir         = "NETCONFPATH"
-       EnvCapabilityArgs = "CAP_ARGS"
-       EnvCNIArgs        = "CNI_ARGS"
-       EnvCNIIfname      = "CNI_IFNAME"
-
-       DefaultNetDir = "/etc/cni/net.d"
-
-       CmdAdd    = "add"
-       CmdCheck  = "check"
-       CmdDel    = "del"
-       CmdGC     = "gc"
-       CmdStatus = "status"
-)
-
-func parseArgs(args string) ([][2]string, error) {
-       var result [][2]string
-
-       pairs := strings.Split(args, ";")
-       for _, pair := range pairs {
-               kv := strings.Split(pair, "=")
-               if len(kv) != 2 || kv[0] == "" || kv[1] == "" {
-                       return nil, fmt.Errorf("invalid CNI_ARGS pair %q", pair)
-               }
-
-               result = append(result, [2]string{kv[0], kv[1]})
-       }
-
-       return result, nil
-}
-
-func main() {
-       if len(os.Args) < 4 {
-               usage()
-       }
-
-       netdir := os.Getenv(EnvNetDir)
-       if netdir == "" {
-               netdir = DefaultNetDir
-       }
-       netconf, err := libcni.LoadNetworkConf(netdir, os.Args[2])
-       if err != nil {
-               exit(err)
-       }
-
-       var capabilityArgs map[string]interface{}
-       capabilityArgsValue := os.Getenv(EnvCapabilityArgs)
-       if len(capabilityArgsValue) > 0 {
-               if err = json.Unmarshal([]byte(capabilityArgsValue), 
&capabilityArgs); err != nil {
-                       exit(err)
-               }
-       }
-
-       var cniArgs [][2]string
-       args := os.Getenv(EnvCNIArgs)
-       if len(args) > 0 {
-               cniArgs, err = parseArgs(args)
-               if err != nil {
-                       exit(err)
-               }
-       }
-
-       ifName, ok := os.LookupEnv(EnvCNIIfname)
-       if !ok {
-               ifName = "eth0"
-       }
-
-       netns := os.Args[3]
-       netns, err = filepath.Abs(netns)
-       if err != nil {
-               exit(err)
-       }
-
-       // Generate the containerid by hashing the netns path
-       s := sha512.Sum512([]byte(netns))
-       containerID := fmt.Sprintf("cnitool-%x", s[:10])
-
-       cninet := 
libcni.NewCNIConfig(filepath.SplitList(os.Getenv(EnvCNIPath)), nil)
-
-       rt := &libcni.RuntimeConf{
-               ContainerID:    containerID,
-               NetNS:          netns,
-               IfName:         ifName,
-               Args:           cniArgs,
-               CapabilityArgs: capabilityArgs,
-       }
-
-       switch os.Args[1] {
-       case CmdAdd:
-               result, err := cninet.AddNetworkList(context.TODO(), netconf, 
rt)
-               if result != nil {
-                       _ = result.Print()
-               }
-               exit(err)
-       case CmdCheck:
-               err := cninet.CheckNetworkList(context.TODO(), netconf, rt)
-               exit(err)
-       case CmdDel:
-               exit(cninet.DelNetworkList(context.TODO(), netconf, rt))
-       case CmdGC:
-               // Currently just invoke GC without args, hence all network 
interface should be GC'ed!
-               exit(cninet.GCNetworkList(context.TODO(), netconf, nil))
-       case CmdStatus:
-               exit(cninet.GetStatusNetworkList(context.TODO(), netconf))
-       }
-}
-
-func usage() {
-       exe := filepath.Base(os.Args[0])
-
-       fmt.Fprintf(os.Stderr, "%s: Add, check, remove, gc or status network 
interfaces from a network namespace\n", exe)
-       fmt.Fprintf(os.Stderr, "  %s add    <net> <netns>\n", exe)
-       fmt.Fprintf(os.Stderr, "  %s check  <net> <netns>\n", exe)
-       fmt.Fprintf(os.Stderr, "  %s del    <net> <netns>\n", exe)
-       fmt.Fprintf(os.Stderr, "  %s gc     <net> <netns>\n", exe)
-       fmt.Fprintf(os.Stderr, "  %s status <net> <netns>\n", exe)
-       os.Exit(1)
-}
-
-func exit(err error) {
-       if err != nil {
-               fmt.Fprintf(os.Stderr, "%s\n", err)
-               os.Exit(1)
-       }
-       os.Exit(0)
-}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cni-1.3.0/cnitool/main.go 
new/cni-1.3.1/cnitool/main.go
--- old/cni-1.3.0/cnitool/main.go       1970-01-01 01:00:00.000000000 +0100
+++ new/cni-1.3.1/cnitool/main.go       2026-08-13 02:47:07.000000000 +0200
@@ -0,0 +1,29 @@
+// Copyright 2015 CNI authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package main
+
+import (
+       "fmt"
+       "os"
+
+       "github.com/containernetworking/cni/cnitool/cmd"
+)
+
+func main() {
+       if err := cmd.Execute(); err != nil {
+               fmt.Fprintf(os.Stderr, "%s\n", err)
+               os.Exit(1)
+       }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cni-1.3.0/go.mod new/cni-1.3.1/go.mod
--- old/cni-1.3.0/go.mod        2025-04-07 17:37:53.000000000 +0200
+++ new/cni-1.3.1/go.mod        2026-08-13 02:47:07.000000000 +0200
@@ -5,14 +5,19 @@
 require (
        github.com/onsi/ginkgo/v2 v2.20.1
        github.com/onsi/gomega v1.34.1
+       github.com/spf13/cobra v1.9.1
        github.com/vishvananda/netns v0.0.4
+       go.opentelemetry.io/otel v1.29.0
+       go.opentelemetry.io/otel/trace v1.29.0
 )
 
 require (
-       github.com/go-logr/logr v1.4.2 // indirect
+       github.com/go-logr/logr v1.4.3 // indirect
        github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
-       github.com/google/go-cmp v0.6.0 // indirect
+       github.com/google/go-cmp v0.7.0 // indirect
        github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect
+       github.com/inconshreveable/mousetrap v1.1.0 // indirect
+       github.com/spf13/pflag v1.0.6 // indirect
        golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
        golang.org/x/net v0.28.0 // indirect
        golang.org/x/sys v0.23.0 // indirect
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cni-1.3.0/go.sum new/cni-1.3.1/go.sum
--- old/cni-1.3.0/go.sum        2025-04-07 17:37:53.000000000 +0200
+++ new/cni-1.3.1/go.sum        2026-08-13 02:47:07.000000000 +0200
@@ -1,23 +1,39 @@
+github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod 
h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
 github.com/davecgh/go-spew v1.1.1 
h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod 
h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
-github.com/go-logr/logr v1.4.2/go.mod 
h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
+github.com/go-logr/logr v1.4.3/go.mod 
h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
+github.com/go-logr/stdr v1.2.2/go.mod 
h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
 github.com/go-task/slim-sprig/v3 v3.0.0 
h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
 github.com/go-task/slim-sprig/v3 v3.0.0/go.mod 
h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
-github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
-github.com/google/go-cmp v0.6.0/go.mod 
h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
+github.com/google/go-cmp v0.7.0/go.mod 
h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
 github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 
h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k=
 github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod 
h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
+github.com/inconshreveable/mousetrap v1.1.0 
h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
+github.com/inconshreveable/mousetrap v1.1.0/go.mod 
h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
 github.com/onsi/ginkgo/v2 v2.20.1 
h1:YlVIbqct+ZmnEph770q9Q7NVAz4wwIiVNahee6JyUzo=
 github.com/onsi/ginkgo/v2 v2.20.1/go.mod 
h1:lG9ey2Z29hR41WMVthyJBGUBcBhGOtoPF2VFMvBXFCI=
 github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
 github.com/onsi/gomega v1.34.1/go.mod 
h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
 github.com/pmezard/go-difflib v1.0.0 
h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod 
h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/stretchr/testify v1.8.4 
h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
-github.com/stretchr/testify v1.8.4/go.mod 
h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
+github.com/russross/blackfriday/v2 v2.1.0/go.mod 
h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
+github.com/spf13/cobra v1.9.1/go.mod 
h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
+github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
+github.com/spf13/pflag v1.0.6/go.mod 
h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/stretchr/testify v1.9.0 
h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
+github.com/stretchr/testify v1.9.0/go.mod 
h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
 github.com/vishvananda/netns v0.0.4 
h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
 github.com/vishvananda/netns v0.0.4/go.mod 
h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
+go.opentelemetry.io/otel v1.29.0 
h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw=
+go.opentelemetry.io/otel v1.29.0/go.mod 
h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8=
+go.opentelemetry.io/otel/metric v1.29.0 
h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc=
+go.opentelemetry.io/otel/metric v1.29.0/go.mod 
h1:auu/QWieFVWx+DmQOUMgj0F8LHWdgalxXqvp7BII/W8=
+go.opentelemetry.io/otel/trace v1.29.0 
h1:J/8ZNK4XgR7a21DZUAsbF8pZ5Jcw1VhACmnYt39JTi4=
+go.opentelemetry.io/otel/trace v1.29.0/go.mod 
h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ=
 golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 
h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
 golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod 
h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
 golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE=
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cni-1.3.0/libcni/api.go new/cni-1.3.1/libcni/api.go
--- old/cni-1.3.0/libcni/api.go 2025-04-07 17:37:53.000000000 +0200
+++ new/cni-1.3.1/libcni/api.go 2026-08-13 02:47:07.000000000 +0200
@@ -663,9 +663,9 @@
        if gtet, err := version.GreaterThanOrEqualTo(net.Network.CNIVersion, 
"0.4.0"); err != nil {
                return err
        } else if gtet {
-               cachedResult, err = c.getCachedResult(net.Network.Name, 
net.Network.CNIVersion, rt)
-               if err != nil {
-                       return fmt.Errorf("failed to get network %q cached 
result: %w", net.Network.Name, err)
+               if cachedResult, err = c.getCachedResult(net.Network.Name, 
net.Network.CNIVersion, rt); err != nil {
+                       _ = c.cacheDel(net.Network.Name, rt)
+                       cachedResult = nil
                }
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cni-1.3.0/libcni/api_test.go 
new/cni-1.3.1/libcni/api_test.go
--- old/cni-1.3.0/libcni/api_test.go    2025-04-07 17:37:53.000000000 +0200
+++ new/cni-1.3.1/libcni/api_test.go    2026-08-13 02:47:07.000000000 +0200
@@ -837,12 +837,12 @@
                                })
 
                                Context("result is invalid JSON", func() {
-                                       It("returns an error", func() {
+                                       It("tolerates the error", func() {
                                                err := os.WriteFile(cacheFile, 
[]byte("adfadsfasdfasfdsafaf"), 0o600)
                                                
Expect(err).NotTo(HaveOccurred())
 
                                                err = cniConfig.DelNetwork(ctx, 
netConfig, runtimeConfig)
-                                               
Expect(err).To(MatchError("failed to get network \"apitest\" cached result: 
decoding version from network config: invalid character 'a' looking for 
beginning of value"))
+                                               
Expect(err).NotTo(HaveOccurred())
                                        })
                                })
 
@@ -859,7 +859,7 @@
                                                
Expect(err).NotTo(HaveOccurred())
                                        })
 
-                                       It("returns an error when the cached 
result cannot be converted", func() {
+                                       It("tolerates the error when the cached 
result cannot be converted", func() {
                                                err := os.WriteFile(cacheFile, 
[]byte(`{
                                                        "cniVersion": 
"0.4567.0",
                                                        "ips": [{"version": 
"4", "address": "10.1.2.3/24"}],
@@ -868,7 +868,7 @@
                                                
Expect(err).NotTo(HaveOccurred())
 
                                                err = cniConfig.DelNetwork(ctx, 
netConfig, runtimeConfig)
-                                               
Expect(err).To(MatchError("failed to get network \"apitest\" cached result: 
unsupported CNI result version \"0.4567.0\""))
+                                               
Expect(err).NotTo(HaveOccurred())
                                        })
                                })
                        })
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cni-1.3.0/pkg/invoke/raw_exec.go 
new/cni-1.3.1/pkg/invoke/raw_exec.go
--- old/cni-1.3.0/pkg/invoke/raw_exec.go        2025-04-07 17:37:53.000000000 
+0200
+++ new/cni-1.3.1/pkg/invoke/raw_exec.go        2026-08-13 02:47:07.000000000 
+0200
@@ -25,6 +25,9 @@
        "time"
 
        "github.com/containernetworking/cni/pkg/types"
+       "go.opentelemetry.io/otel/baggage"
+       "go.opentelemetry.io/otel/propagation"
+       "go.opentelemetry.io/otel/trace"
 )
 
 type RawExec struct {
@@ -35,7 +38,7 @@
        stdout := &bytes.Buffer{}
        stderr := &bytes.Buffer{}
        c := exec.CommandContext(ctx, pluginPath)
-       c.Env = environ
+       c.Env = injectTraceContext(ctx, environ)
        c.Stdin = bytes.NewBuffer(stdinData)
        c.Stdout = stdout
        c.Stderr = stderr
@@ -69,13 +72,42 @@
        return stdout.Bytes(), nil
 }
 
+// injectTraceContext will add OpenTelemetry trace context to the environment 
variables based on
+// 
https://github.com/open-telemetry/opentelemetry-specification/blob/main/oteps/0258-env-context-baggage-carriers.md
+func injectTraceContext(ctx context.Context, environ []string) []string {
+       sc := trace.SpanContextFromContext(ctx)
+       if !sc.IsValid() {
+               return environ
+       }
+
+       ctx = trace.ContextWithRemoteSpanContext(ctx, sc)
+       mc := propagation.MapCarrier{}
+       (propagation.TraceContext{}).Inject(ctx, mc)
+
+       // Currently, both traceparent and tracestate are not exported 
variables,
+       // 
https://github.com/open-telemetry/opentelemetry-go/blob/bcf8234d0c9c48b626cad85367a3681f3fc0c0fd/propagation/trace_context.go#L18-L19
+       // so we have to use the string literals here.
+       if traceparent := mc.Get("traceparent"); traceparent != "" {
+               environ = append(environ, "TRACEPARENT"+"="+traceparent)
+       }
+
+       if tracestate := mc.Get("tracestate"); tracestate != "" {
+               environ = append(environ, "TRACESTATE"+"="+tracestate)
+       }
+
+       if envBaggage := baggage.FromContext(ctx).String(); envBaggage != "" {
+               environ = append(environ, "BAGGAGE"+"="+envBaggage)
+       }
+       return environ
+}
+
 func (e *RawExec) pluginErr(err error, stdout, stderr []byte) error {
        emsg := types.Error{}
        if len(stdout) == 0 {
                if len(stderr) == 0 {
                        emsg.Msg = fmt.Sprintf("netplugin failed with no error 
message: %v", err)
                } else {
-                       emsg.Msg = fmt.Sprintf("netplugin failed: %q", 
string(stderr))
+                       emsg.Msg = fmt.Sprintf("netplugin failed: %q: %v", 
string(stderr), err)
                }
        } else if perr := json.Unmarshal(stdout, &emsg); perr != nil {
                emsg.Msg = fmt.Sprintf("netplugin failed but error parsing its 
diagnostic message %q: %v", string(stdout), perr)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cni-1.3.0/pkg/invoke/raw_exec_test.go 
new/cni-1.3.1/pkg/invoke/raw_exec_test.go
--- old/cni-1.3.0/pkg/invoke/raw_exec_test.go   2025-04-07 17:37:53.000000000 
+0200
+++ new/cni-1.3.1/pkg/invoke/raw_exec_test.go   2026-08-13 02:47:07.000000000 
+0200
@@ -122,7 +122,7 @@
                                
Expect(debug.WriteDebug(debugFileName)).To(Succeed())
                                _, err := execer.ExecPlugin(ctx, pathToPlugin, 
stdin, environ)
                                Expect(err).To(HaveOccurred())
-                               Expect(err).To(MatchError(`netplugin failed: 
"some stderr message"`))
+                               Expect(err).To(MatchError(`netplugin failed: 
"some stderr message": exit status 1`))
                        })
                })
        })
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cni-1.3.0/pkg/types/types.go 
new/cni-1.3.1/pkg/types/types.go
--- old/cni-1.3.0/pkg/types/types.go    2025-04-07 17:37:53.000000000 +0200
+++ new/cni-1.3.1/pkg/types/types.go    2026-08-13 02:47:07.000000000 +0200
@@ -229,7 +229,7 @@
 }
 
 // Well known error codes
-// see 
https://github.com/containernetworking/cni/blob/main/SPEC.md#well-known-error-codes
+// see https://github.com/containernetworking/cni/blob/main/SPEC.md#error
 const (
        ErrUnknown                     uint = iota // 0
        ErrIncompatibleCNIVersion                  // 1
@@ -241,6 +241,8 @@
        ErrInvalidNetworkConfig                    // 7
        ErrInvalidNetNS                            // 8
        ErrTryAgainLater               uint = 11
+       ErrPluginNotAvailable          uint = 50
+       ErrLimitedConnectivity         uint = 51
        ErrInternal                    uint = 999
 )
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cni-1.3.0/pkg/version/version.go 
new/cni-1.3.1/pkg/version/version.go
--- old/cni-1.3.0/pkg/version/version.go        2025-04-07 17:37:53.000000000 
+0200
+++ new/cni-1.3.1/pkg/version/version.go        2026-08-13 02:47:07.000000000 
+0200
@@ -39,13 +39,13 @@
        All    = PluginSupports("0.1.0", "0.2.0", "0.3.0", "0.3.1", "0.4.0", 
"1.0.0", "1.1.0")
 )
 
-// VersionsFrom returns a list of versions starting from min, inclusive
-func VersionsStartingFrom(min string) PluginInfo {
+// VersionsFrom returns a list of versions starting from minVer, inclusive
+func VersionsStartingFrom(minVer string) PluginInfo {
        out := []string{}
        // cheat, just assume ordered
        ok := false
        for _, v := range All.SupportedVersions() {
-               if !ok && v == min {
+               if !ok && v == minVer {
                        ok = true
                }
                if ok {

++++++ cni.obsinfo ++++++
--- /var/tmp/diff_new_pack.LdBSQ4/_old  2026-09-08 17:01:58.307636188 +0200
+++ /var/tmp/diff_new_pack.LdBSQ4/_new  2026-09-08 17:01:58.310636313 +0200
@@ -1,5 +1,5 @@
 name: cni
-version: 1.3.0
-mtime: 1744040273
-commit: a28faab92684aed3af64d5085733c34550ce9877
+version: 1.3.1
+mtime: 1786582027
+commit: 3f51e8803ebbdba0ebeed735b42137e4c7302403
 

++++++ vendor.tar.gz ++++++
++++ 18675 lines of diff (skipped)

Reply via email to