diff --git a/go.mod b/go.mod
index fa1ff38970..a053c6f5d0 100644
--- a/go.mod
+++ b/go.mod
@@ -6,7 +6,7 @@ require (
 	github.com/agiledragon/gomonkey/v2 v2.11.0
 	github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2
 	github.com/cilium/cilium v1.14.1
-	github.com/containernetworking/cni v1.1.2
+	github.com/containernetworking/cni v1.2.0-rc1
 	github.com/containernetworking/plugins v1.5.1
 	github.com/go-openapi/errors v0.22.0
 	github.com/go-openapi/loads v0.21.2
@@ -21,7 +21,7 @@ require (
 	github.com/google/gops v0.3.27
 	github.com/grafana/pyroscope-go v1.2.0
 	github.com/jessevdk/go-flags v1.5.0
-	github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.4.0
+	github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.7.5
 	github.com/kdoctor-io/kdoctor v0.2.0
 	github.com/mdlayher/ndp v1.0.1
 	github.com/onsi/ginkgo/v2 v2.22.1
@@ -81,7 +81,7 @@ require (
 
 require (
 	github.com/Masterminds/goutils v1.1.1 // indirect
-	github.com/Masterminds/semver/v3 v3.2.0 // indirect
+	github.com/Masterminds/semver/v3 v3.2.1 // indirect
 	github.com/Masterminds/sprig/v3 v3.2.3 // indirect
 	github.com/beorn7/perks v1.0.1 // indirect
 	github.com/blang/semver/v4 v4.0.0 // indirect
diff --git a/go.sum b/go.sum
index 2d92cac42c..6867e90934 100644
--- a/go.sum
+++ b/go.sum
@@ -52,8 +52,9 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
 github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
 github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
-github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g=
 github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
+github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=
+github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
 github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
 github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
 github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
@@ -91,8 +92,8 @@ github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnht
 github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
 github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ=
 github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM=
-github.com/containernetworking/cni v1.1.2 h1:wtRGZVv7olUHMOqouPpn3cXJWpJgM6+EUl31EQbXALQ=
-github.com/containernetworking/cni v1.1.2/go.mod h1:sDpYKmGVENF3s6uvMvGgldDWeG8dMxakj/u+i9ht9vw=
+github.com/containernetworking/cni v1.2.0-rc1 h1:AKI3+pXtgY4PDLN9+50o9IaywWVuey0Jkw3Lvzp0HCY=
+github.com/containernetworking/cni v1.2.0-rc1/go.mod h1:Lt0TQcZQVDju64fYxUhDziTgXCDe3Olzi9I4zZJLWHg=
 github.com/containernetworking/plugins v1.5.1 h1:T5ji+LPYjjgW0QM+KyrigZbLsZ8jaX+E5J/EcKOE4gQ=
 github.com/containernetworking/plugins v1.5.1/go.mod h1:MIQfgMayGuHYs0XdNudf31cLLAC+i242hNm6KuDGqCM=
 github.com/coreos/go-iptables v0.7.0 h1:XWM3V+MPRr5/q51NuWSgU0fqMad64Zyxs8ZUoMsamr8=
@@ -338,8 +339,8 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm
 github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
-github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.4.0 h1:VzM3TYHDgqPkettiP6I6q2jOeQFL4nrJM+UcAc4f6Fs=
-github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.4.0/go.mod h1:nqCI7aelBJU61wiBeeZWJ6oi4bJy5nrjkM6lWIMA4j0=
+github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.7.5 h1:CELpSMPSyicFBaVsxROmfrWlu9yr3Dduk+y7vGrIsx8=
+github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.7.5/go.mod h1:CM7HAH5PNuIsqjMN0fGc1ydM74Uj+0VZFhob620nklw=
 github.com/kdoctor-io/kdoctor v0.2.0 h1:X2XHrTZ+RDuAJ+HiKZ1UHzIvFM3/Al6JDyg2nxtziAU=
 github.com/kdoctor-io/kdoctor v0.2.0/go.mod h1:TxkjBwM4sdnOTHABxgL1gO68tlzHUnbiuRYBHRLKYTc=
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
@@ -418,7 +419,6 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv
 github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
 github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
 github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
-github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
 github.com/onsi/ginkgo/v2 v2.22.1 h1:QW7tbJAUDyVDVOM5dFa7qaybo+CRfR7bemlQUN6Z8aM=
 github.com/onsi/ginkgo/v2 v2.22.1/go.mod h1:S6aTpoRsSq2cZOd+pssHAlKW/Q/jZt6cPrPlnj4a1xM=
 github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
diff --git a/vendor/github.com/Masterminds/semver/v3/.golangci.yml b/vendor/github.com/Masterminds/semver/v3/.golangci.yml
index c87d1c4b90..fbc6332592 100644
--- a/vendor/github.com/Masterminds/semver/v3/.golangci.yml
+++ b/vendor/github.com/Masterminds/semver/v3/.golangci.yml
@@ -5,12 +5,9 @@ linters:
   disable-all: true
   enable:
     - misspell
-    - structcheck
     - govet
     - staticcheck
-    - deadcode
     - errcheck
-    - varcheck
     - unparam
     - ineffassign
     - nakedret
diff --git a/vendor/github.com/Masterminds/semver/v3/Makefile b/vendor/github.com/Masterminds/semver/v3/Makefile
index eac19178fb..0e7b5c7138 100644
--- a/vendor/github.com/Masterminds/semver/v3/Makefile
+++ b/vendor/github.com/Masterminds/semver/v3/Makefile
@@ -1,7 +1,5 @@
 GOPATH=$(shell go env GOPATH)
 GOLANGCI_LINT=$(GOPATH)/bin/golangci-lint
-GOFUZZBUILD = $(GOPATH)/bin/go-fuzz-build
-GOFUZZ = $(GOPATH)/bin/go-fuzz
 
 .PHONY: lint
 lint: $(GOLANGCI_LINT)
@@ -19,19 +17,14 @@ test-cover:
 	GO111MODULE=on go test -cover .
 
 .PHONY: fuzz
-fuzz: $(GOFUZZBUILD) $(GOFUZZ)
-	@echo "==> Fuzz testing"
-	$(GOFUZZBUILD)
-	$(GOFUZZ) -workdir=_fuzz
+fuzz:
+	@echo "==> Running Fuzz Tests"
+	go test -fuzz=FuzzNewVersion -fuzztime=15s .
+	go test -fuzz=FuzzStrictNewVersion -fuzztime=15s .
+	go test -fuzz=FuzzNewConstraint -fuzztime=15s .
 
 $(GOLANGCI_LINT):
 	# Install golangci-lint. The configuration for it is in the .golangci.yml
 	# file in the root of the repository
 	echo ${GOPATH}
 	curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(GOPATH)/bin v1.17.1
-
-$(GOFUZZBUILD):
-	cd / && go get -u github.com/dvyukov/go-fuzz/go-fuzz-build
-
-$(GOFUZZ):
-	cd / && go get -u github.com/dvyukov/go-fuzz/go-fuzz github.com/dvyukov/go-fuzz/go-fuzz-dep
\ No newline at end of file
diff --git a/vendor/github.com/Masterminds/semver/v3/README.md b/vendor/github.com/Masterminds/semver/v3/README.md
index d8f54dcbd3..eab8cac3b7 100644
--- a/vendor/github.com/Masterminds/semver/v3/README.md
+++ b/vendor/github.com/Masterminds/semver/v3/README.md
@@ -18,18 +18,20 @@ If you are looking for a command line tool for version comparisons please see
 
 ## Package Versions
 
+Note, import `github.com/github.com/Masterminds/semver/v3` to use the latest version.
+
 There are three major versions fo the `semver` package.
 
-* 3.x.x is the new stable and active version. This version is focused on constraint
+* 3.x.x is the stable and active version. This version is focused on constraint
   compatibility for range handling in other tools from other languages. It has
   a similar API to the v1 releases. The development of this version is on the master
   branch. The documentation for this version is below.
 * 2.x was developed primarily for [dep](https://github.com/golang/dep). There are
   no tagged releases and the development was performed by [@sdboyer](https://github.com/sdboyer).
   There are API breaking changes from v1. This version lives on the [2.x branch](https://github.com/Masterminds/semver/tree/2.x).
-* 1.x.x is the most widely used version with numerous tagged releases. This is the
-  previous stable and is still maintained for bug fixes. The development, to fix
-  bugs, occurs on the release-1 branch. You can read the documentation [here](https://github.com/Masterminds/semver/blob/release-1/README.md).
+* 1.x.x is the original release. It is no longer maintained. You should use the
+  v3 release instead. You can read the documentation for the 1.x.x release
+  [here](https://github.com/Masterminds/semver/blob/release-1/README.md).
 
 ## Parsing Semantic Versions
 
@@ -242,3 +244,15 @@ for _, m := range msgs {
 
 If you find an issue or want to contribute please file an [issue](https://github.com/Masterminds/semver/issues)
 or [create a pull request](https://github.com/Masterminds/semver/pulls).
+
+## Security
+
+Security is an important consideration for this project. The project currently
+uses the following tools to help discover security issues:
+
+* [CodeQL](https://github.com/Masterminds/semver)
+* [gosec](https://github.com/securego/gosec)
+* Daily Fuzz testing
+
+If you believe you have found a security vulnerability you can privately disclose
+it through the [GitHub security page](https://github.com/Masterminds/semver/security).
diff --git a/vendor/github.com/Masterminds/semver/v3/SECURITY.md b/vendor/github.com/Masterminds/semver/v3/SECURITY.md
new file mode 100644
index 0000000000..a30a66b1f7
--- /dev/null
+++ b/vendor/github.com/Masterminds/semver/v3/SECURITY.md
@@ -0,0 +1,19 @@
+# Security Policy
+
+## Supported Versions
+
+The following versions of semver are currently supported:
+
+| Version | Supported          |
+| ------- | ------------------ |
+| 3.x     | :white_check_mark: |
+| 2.x     | :x:                |
+| 1.x     | :x:                |
+
+Fixes are only released for the latest minor version in the form of a patch release.
+
+## Reporting a Vulnerability
+
+You can privately disclose a vulnerability through GitHubs
+[private vulnerability reporting](https://github.com/Masterminds/semver/security/advisories)
+mechanism.
diff --git a/vendor/github.com/Masterminds/semver/v3/constraints.go b/vendor/github.com/Masterminds/semver/v3/constraints.go
index 203072e464..8461c7ed90 100644
--- a/vendor/github.com/Masterminds/semver/v3/constraints.go
+++ b/vendor/github.com/Masterminds/semver/v3/constraints.go
@@ -586,7 +586,7 @@ func rewriteRange(i string) string {
 	}
 	o := i
 	for _, v := range m {
-		t := fmt.Sprintf(">= %s, <= %s", v[1], v[11])
+		t := fmt.Sprintf(">= %s, <= %s ", v[1], v[11])
 		o = strings.Replace(o, v[0], t, 1)
 	}
 
diff --git a/vendor/github.com/Masterminds/semver/v3/fuzz.go b/vendor/github.com/Masterminds/semver/v3/fuzz.go
deleted file mode 100644
index a242ad7058..0000000000
--- a/vendor/github.com/Masterminds/semver/v3/fuzz.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// +build gofuzz
-
-package semver
-
-func Fuzz(data []byte) int {
-	d := string(data)
-
-	// Test NewVersion
-	_, _ = NewVersion(d)
-
-	// Test StrictNewVersion
-	_, _ = StrictNewVersion(d)
-
-	// Test NewConstraint
-	_, _ = NewConstraint(d)
-
-	// The return value should be 0 normally, 1 if the priority in future tests
-	// should be increased, and -1 if future tests should skip passing in that
-	// data. We do not have a reason to change priority so 0 is always returned.
-	// There are example tests that do this.
-	return 0
-}
diff --git a/vendor/github.com/containernetworking/cni/libcni/api.go b/vendor/github.com/containernetworking/cni/libcni/api.go
index 0d82a2dd3c..5c7f3b028c 100644
--- a/vendor/github.com/containernetworking/cni/libcni/api.go
+++ b/vendor/github.com/containernetworking/cni/libcni/api.go
@@ -15,7 +15,7 @@
 package libcni
 
 // Note this is the actual implementation of the CNI specification, which
-// is reflected in the https://github.com/containernetworking/cni/blob/master/SPEC.md file
+// is reflected in the SPEC.md file.
 // it is typically bundled into runtime providers (i.e. containerd or cri-o would use this
 // before calling runc or hcsshim).  It is also bundled into CNI providers as well, for example,
 // to add an IP to a container, to parse the configuration of the CNI and so on.
@@ -24,9 +24,9 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
-	"io/ioutil"
 	"os"
 	"path/filepath"
+	"sort"
 	"strings"
 
 	"github.com/containernetworking/cni/pkg/invoke"
@@ -38,6 +38,8 @@ import (
 
 var (
 	CacheDir = "/var/lib/cni"
+	// slightly awkward wording to preserve anyone matching on error strings
+	ErrorCheckNotSupp = fmt.Errorf("does not support the CHECK command")
 )
 
 const (
@@ -77,6 +79,20 @@ type NetworkConfigList struct {
 	Bytes        []byte
 }
 
+type NetworkAttachment struct {
+	ContainerID    string
+	Network        string
+	IfName         string
+	Config         []byte
+	NetNS          string
+	CniArgs        [][2]string
+	CapabilityArgs map[string]interface{}
+}
+
+type GCArgs struct {
+	ValidAttachments []types.GCAttachment
+}
+
 type CNI interface {
 	AddNetworkList(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) (types.Result, error)
 	CheckNetworkList(ctx context.Context, net *NetworkConfigList, rt *RuntimeConf) error
@@ -92,6 +108,11 @@ type CNI interface {
 
 	ValidateNetworkList(ctx context.Context, net *NetworkConfigList) ([]string, error)
 	ValidateNetwork(ctx context.Context, net *NetworkConfig) ([]string, error)
+
+	GCNetworkList(ctx context.Context, net *NetworkConfigList, args *GCArgs) error
+	GetStatusNetworkList(ctx context.Context, net *NetworkConfigList) error
+
+	GetCachedAttachments(containerID string) ([]*NetworkAttachment, error)
 }
 
 type CNIConfig struct {
@@ -139,8 +160,11 @@ func buildOneConfig(name, cniVersion string, orig *NetworkConfig, prevResult typ
 	if err != nil {
 		return nil, err
 	}
+	if rt != nil {
+		return injectRuntimeConfig(orig, rt)
+	}
 
-	return injectRuntimeConfig(orig, rt)
+	return orig, nil
 }
 
 // This function takes a libcni RuntimeConf structure and injects values into
@@ -195,6 +219,7 @@ type cachedInfo struct {
 	Config         []byte                 `json:"config"`
 	IfName         string                 `json:"ifName"`
 	NetworkName    string                 `json:"networkName"`
+	NetNS          string                 `json:"netns,omitempty"`
 	CniArgs        [][2]string            `json:"cniArgs,omitempty"`
 	CapabilityArgs map[string]interface{} `json:"capabilityArgs,omitempty"`
 	RawResult      map[string]interface{} `json:"result,omitempty"`
@@ -229,6 +254,7 @@ func (c *CNIConfig) cacheAdd(result types.Result, config []byte, netName string,
 		Config:         config,
 		IfName:         rt.IfName,
 		NetworkName:    netName,
+		NetNS:          rt.NetNS,
 		CniArgs:        rt.Args,
 		CapabilityArgs: rt.CapabilityArgs,
 	}
@@ -254,11 +280,11 @@ func (c *CNIConfig) cacheAdd(result types.Result, config []byte, netName string,
 	if err != nil {
 		return err
 	}
-	if err := os.MkdirAll(filepath.Dir(fname), 0700); err != nil {
+	if err := os.MkdirAll(filepath.Dir(fname), 0o700); err != nil {
 		return err
 	}
 
-	return ioutil.WriteFile(fname, newBytes, 0600)
+	return os.WriteFile(fname, newBytes, 0o600)
 }
 
 func (c *CNIConfig) cacheDel(netName string, rt *RuntimeConf) error {
@@ -277,7 +303,7 @@ func (c *CNIConfig) getCachedConfig(netName string, rt *RuntimeConf) ([]byte, *R
 	if err != nil {
 		return nil, nil, err
 	}
-	bytes, err = ioutil.ReadFile(fname)
+	bytes, err = os.ReadFile(fname)
 	if err != nil {
 		// Ignore read errors; the cached result may not exist on-disk
 		return nil, nil, nil
@@ -305,7 +331,7 @@ func (c *CNIConfig) getLegacyCachedResult(netName, cniVersion string, rt *Runtim
 	if err != nil {
 		return nil, err
 	}
-	data, err := ioutil.ReadFile(fname)
+	data, err := os.ReadFile(fname)
 	if err != nil {
 		// Ignore read errors; the cached result may not exist on-disk
 		return nil, nil
@@ -333,7 +359,7 @@ func (c *CNIConfig) getCachedResult(netName, cniVersion string, rt *RuntimeConf)
 	if err != nil {
 		return nil, err
 	}
-	fdata, err := ioutil.ReadFile(fname)
+	fdata, err := os.ReadFile(fname)
 	if err != nil {
 		// Ignore read errors; the cached result may not exist on-disk
 		return nil, nil
@@ -390,6 +416,65 @@ func (c *CNIConfig) GetNetworkCachedConfig(net *NetworkConfig, rt *RuntimeConf)
 	return c.getCachedConfig(net.Network.Name, rt)
 }
 
+// GetCachedAttachments returns a list of network attachments from the cache.
+// The returned list will be filtered by the containerID if the value is not empty.
+func (c *CNIConfig) GetCachedAttachments(containerID string) ([]*NetworkAttachment, error) {
+	dirPath := filepath.Join(c.getCacheDir(&RuntimeConf{}), "results")
+	entries, err := os.ReadDir(dirPath)
+	if err != nil {
+		return nil, err
+	}
+
+	fileNames := make([]string, 0, len(entries))
+	for _, e := range entries {
+		fileNames = append(fileNames, e.Name())
+	}
+	sort.Strings(fileNames)
+
+	attachments := []*NetworkAttachment{}
+	for _, fname := range fileNames {
+		if len(containerID) > 0 {
+			part := fmt.Sprintf("-%s-", containerID)
+			pos := strings.Index(fname, part)
+			if pos <= 0 || pos+len(part) >= len(fname) {
+				continue
+			}
+		}
+
+		cacheFile := filepath.Join(dirPath, fname)
+		bytes, err := os.ReadFile(cacheFile)
+		if err != nil {
+			continue
+		}
+
+		cachedInfo := cachedInfo{}
+
+		if err := json.Unmarshal(bytes, &cachedInfo); err != nil {
+			continue
+		}
+		if cachedInfo.Kind != CNICacheV1 {
+			continue
+		}
+		if len(containerID) > 0 && cachedInfo.ContainerID != containerID {
+			continue
+		}
+		if cachedInfo.IfName == "" || cachedInfo.NetworkName == "" {
+			continue
+		}
+
+		attachments = append(attachments, &NetworkAttachment{
+			ContainerID:    cachedInfo.ContainerID,
+			Network:        cachedInfo.NetworkName,
+			IfName:         cachedInfo.IfName,
+			Config:         cachedInfo.Config,
+			NetNS:          cachedInfo.NetNS,
+			CniArgs:        cachedInfo.CniArgs,
+			CapabilityArgs: cachedInfo.CapabilityArgs,
+		})
+	}
+	return attachments, nil
+}
+
 func (c *CNIConfig) addNetwork(ctx context.Context, name, cniVersion string, net *NetworkConfig, prevResult types.Result, rt *RuntimeConf) (types.Result, error) {
 	c.ensureExec()
 	pluginPath, err := c.exec.FindInPath(net.Network.Type, c.Path)
@@ -453,7 +538,7 @@ func (c *CNIConfig) CheckNetworkList(ctx context.Context, list *NetworkConfigLis
 	if gtet, err := version.GreaterThanOrEqualTo(list.CNIVersion, "0.4.0"); err != nil {
 		return err
 	} else if !gtet {
-		return fmt.Errorf("configuration version %q does not support the CHECK command", list.CNIVersion)
+		return fmt.Errorf("configuration version %q %w", list.CNIVersion, ErrorCheckNotSupp)
 	}
 
 	if list.DisableCheck {
@@ -497,9 +582,9 @@ func (c *CNIConfig) DelNetworkList(ctx context.Context, list *NetworkConfigList,
 	if gtet, err := version.GreaterThanOrEqualTo(list.CNIVersion, "0.4.0"); err != nil {
 		return err
 	} else if gtet {
-		cachedResult, err = c.getCachedResult(list.Name, list.CNIVersion, rt)
-		if err != nil {
-			return fmt.Errorf("failed to get network %q cached result: %w", list.Name, err)
+		if cachedResult, err = c.getCachedResult(list.Name, list.CNIVersion, rt); err != nil {
+			_ = c.cacheDel(list.Name, rt)
+			cachedResult = nil
 		}
 	}
 
@@ -509,7 +594,10 @@ func (c *CNIConfig) DelNetworkList(ctx context.Context, list *NetworkConfigList,
 			return fmt.Errorf("plugin %s failed (delete): %w", pluginDescription(net.Network), err)
 		}
 	}
-	_ = c.cacheDel(list.Name, rt)
+
+	if cachedResult != nil {
+		_ = c.cacheDel(list.Name, rt)
+	}
 
 	return nil
 }
@@ -547,7 +635,7 @@ func (c *CNIConfig) CheckNetwork(ctx context.Context, net *NetworkConfig, rt *Ru
 	if gtet, err := version.GreaterThanOrEqualTo(net.Network.CNIVersion, "0.4.0"); err != nil {
 		return err
 	} else if !gtet {
-		return fmt.Errorf("configuration version %q does not support the CHECK command", net.Network.CNIVersion)
+		return fmt.Errorf("configuration version %q %w", net.Network.CNIVersion, ErrorCheckNotSupp)
 	}
 
 	cachedResult, err := c.getCachedResult(net.Network.Name, net.Network.CNIVersion, rt)
@@ -666,6 +754,116 @@ func (c *CNIConfig) GetVersionInfo(ctx context.Context, pluginType string) (vers
 	return invoke.GetVersionInfo(ctx, pluginPath, c.exec)
 }
 
+// GCNetworkList will do two things
+// - dump the list of cached attachments, and issue deletes as necessary
+// - issue a GC to the underlying plugins (if the version is high enough)
+func (c *CNIConfig) GCNetworkList(ctx context.Context, list *NetworkConfigList, args *GCArgs) error {
+	// First, get the list of cached attachments
+	cachedAttachments, err := c.GetCachedAttachments("")
+	if err != nil {
+		return nil
+	}
+
+	validAttachments := make(map[types.GCAttachment]interface{}, len(args.ValidAttachments))
+	for _, a := range args.ValidAttachments {
+		validAttachments[a] = nil
+	}
+
+	var errs []error
+
+	for _, cachedAttachment := range cachedAttachments {
+		if cachedAttachment.Network != list.Name {
+			continue
+		}
+		// we found this attachment
+		gca := types.GCAttachment{
+			ContainerID: cachedAttachment.ContainerID,
+			IfName:      cachedAttachment.IfName,
+		}
+		if _, ok := validAttachments[gca]; ok {
+			continue
+		}
+		// otherwise, this attachment wasn't valid and we should issue a CNI DEL
+		rt := RuntimeConf{
+			ContainerID:    cachedAttachment.ContainerID,
+			NetNS:          cachedAttachment.NetNS,
+			IfName:         cachedAttachment.IfName,
+			Args:           cachedAttachment.CniArgs,
+			CapabilityArgs: cachedAttachment.CapabilityArgs,
+		}
+		if err := c.DelNetworkList(ctx, list, &rt); err != nil {
+			errs = append(errs, fmt.Errorf("failed to delete stale attachment %s %s: %w", rt.ContainerID, rt.IfName, err))
+		}
+	}
+
+	// now, if the version supports it, issue a GC
+	if gt, _ := version.GreaterThanOrEqualTo(list.CNIVersion, "1.1.0"); gt {
+		inject := map[string]interface{}{
+			"name":                      list.Name,
+			"cniVersion":                list.CNIVersion,
+			"cni.dev/valid-attachments": args.ValidAttachments,
+		}
+		for _, plugin := range list.Plugins {
+			// build config here
+			pluginConfig, err := InjectConf(plugin, inject)
+			if err != nil {
+				errs = append(errs, fmt.Errorf("failed to generate configuration to GC plugin %s: %w", plugin.Network.Type, err))
+			}
+			if err := c.gcNetwork(ctx, pluginConfig); err != nil {
+				errs = append(errs, fmt.Errorf("failed to GC plugin %s: %w", plugin.Network.Type, err))
+			}
+		}
+	}
+
+	return joinErrors(errs...)
+}
+
+func (c *CNIConfig) gcNetwork(ctx context.Context, net *NetworkConfig) error {
+	c.ensureExec()
+	pluginPath, err := c.exec.FindInPath(net.Network.Type, c.Path)
+	if err != nil {
+		return err
+	}
+	args := c.args("GC", &RuntimeConf{})
+
+	return invoke.ExecPluginWithoutResult(ctx, pluginPath, net.Bytes, args, c.exec)
+}
+
+func (c *CNIConfig) GetStatusNetworkList(ctx context.Context, list *NetworkConfigList) error {
+	// If the version doesn't support status, abort.
+	if gt, _ := version.GreaterThanOrEqualTo(list.CNIVersion, "1.1.0"); !gt {
+		return nil
+	}
+
+	inject := map[string]interface{}{
+		"name":       list.Name,
+		"cniVersion": list.CNIVersion,
+	}
+
+	for _, plugin := range list.Plugins {
+		// build config here
+		pluginConfig, err := InjectConf(plugin, inject)
+		if err != nil {
+			return fmt.Errorf("failed to generate configuration to get plugin STATUS %s: %w", plugin.Network.Type, err)
+		}
+		if err := c.getStatusNetwork(ctx, pluginConfig); err != nil {
+			return err // Don't collect errors here, so we return a clean error code.
+		}
+	}
+	return nil
+}
+
+func (c *CNIConfig) getStatusNetwork(ctx context.Context, net *NetworkConfig) error {
+	c.ensureExec()
+	pluginPath, err := c.exec.FindInPath(net.Network.Type, c.Path)
+	if err != nil {
+		return err
+	}
+	args := c.args("STATUS", &RuntimeConf{})
+
+	return invoke.ExecPluginWithoutResult(ctx, pluginPath, net.Bytes, args, c.exec)
+}
+
 // =====
 func (c *CNIConfig) args(action string, rt *RuntimeConf) *invoke.Args {
 	return &invoke.Args{
diff --git a/vendor/github.com/containernetworking/cni/libcni/conf.go b/vendor/github.com/containernetworking/cni/libcni/conf.go
index 3cd6a59d1c..6c5d99de98 100644
--- a/vendor/github.com/containernetworking/cni/libcni/conf.go
+++ b/vendor/github.com/containernetworking/cni/libcni/conf.go
@@ -16,13 +16,17 @@ package libcni
 
 import (
 	"encoding/json"
+	"errors"
 	"fmt"
-	"io/ioutil"
 	"os"
 	"path/filepath"
 	"sort"
+	"strings"
+
+	"github.com/Masterminds/semver/v3"
 
 	"github.com/containernetworking/cni/pkg/types"
+	"github.com/containernetworking/cni/pkg/version"
 )
 
 type NotFoundError struct {
@@ -54,7 +58,7 @@ func ConfFromBytes(bytes []byte) (*NetworkConfig, error) {
 }
 
 func ConfFromFile(filename string) (*NetworkConfig, error) {
-	bytes, err := ioutil.ReadFile(filename)
+	bytes, err := os.ReadFile(filename)
 	if err != nil {
 		return nil, fmt.Errorf("error reading %s: %w", filename, err)
 	}
@@ -85,11 +89,63 @@ func ConfListFromBytes(bytes []byte) (*NetworkConfigList, error) {
 		}
 	}
 
+	rawVersions, ok := rawList["cniVersions"]
+	if ok {
+		// Parse the current package CNI version
+		currentVersion, err := semver.NewVersion(version.Current())
+		if err != nil {
+			panic("CNI version is invalid semver!")
+		}
+
+		rvs, ok := rawVersions.([]interface{})
+		if !ok {
+			return nil, fmt.Errorf("error parsing configuration list: invalid type for cniVersions: %T", rvs)
+		}
+		vs := make([]*semver.Version, 0, len(rvs))
+		for i, rv := range rvs {
+			v, ok := rv.(string)
+			if !ok {
+				return nil, fmt.Errorf("error parsing configuration list: invalid type for cniVersions index %d: %T", i, rv)
+			}
+			if v, err := semver.NewVersion(v); err != nil {
+				return nil, fmt.Errorf("error parsing configuration list: invalid cniVersions entry %s at index %d: %w", v, i, err)
+			} else if !v.GreaterThan(currentVersion) {
+				// Skip versions "greater" than this implementation of the spec
+				vs = append(vs, v)
+			}
+		}
+
+		// if cniVersion was already set, append it to the list for sorting.
+		if cniVersion != "" {
+			if v, err := semver.NewVersion(cniVersion); err != nil {
+				return nil, fmt.Errorf("error parsing configuration list: invalid cniVersion %s: %w", cniVersion, err)
+			} else if !v.GreaterThan(currentVersion) {
+				// ignore any versions higher than the current implemented spec version
+				vs = append(vs, v)
+			}
+		}
+		sort.Sort(semver.Collection(vs))
+		if len(vs) > 0 {
+			cniVersion = vs[len(vs)-1].String()
+		}
+	}
+
 	disableCheck := false
 	if rawDisableCheck, ok := rawList["disableCheck"]; ok {
 		disableCheck, ok = rawDisableCheck.(bool)
 		if !ok {
-			return nil, fmt.Errorf("error parsing configuration list: invalid disableCheck type %T", rawDisableCheck)
+			disableCheckStr, ok := rawDisableCheck.(string)
+			if !ok {
+				return nil, fmt.Errorf("error parsing configuration list: invalid disableCheck type %T", rawDisableCheck)
+			}
+			switch {
+			case strings.ToLower(disableCheckStr) == "false":
+				disableCheck = false
+			case strings.ToLower(disableCheckStr) == "true":
+				disableCheck = true
+			default:
+				return nil, fmt.Errorf("error parsing configuration list: invalid disableCheck value %q", disableCheckStr)
+			}
 		}
 	}
 
@@ -129,7 +185,7 @@ func ConfListFromBytes(bytes []byte) (*NetworkConfigList, error) {
 }
 
 func ConfListFromFile(filename string) (*NetworkConfigList, error) {
-	bytes, err := ioutil.ReadFile(filename)
+	bytes, err := os.ReadFile(filename)
 	if err != nil {
 		return nil, fmt.Errorf("error reading %s: %w", filename, err)
 	}
@@ -138,7 +194,7 @@ func ConfListFromFile(filename string) (*NetworkConfigList, error) {
 
 func ConfFiles(dir string, extensions []string) ([]string, error) {
 	// In part, adapted from rkt/networking/podenv.go#listFiles
-	files, err := ioutil.ReadDir(dir)
+	files, err := os.ReadDir(dir)
 	switch {
 	case err == nil: // break
 	case os.IsNotExist(err):
@@ -206,7 +262,8 @@ func LoadConfList(dir, name string) (*NetworkConfigList, error) {
 	singleConf, err := LoadConf(dir, name)
 	if err != nil {
 		// A little extra logic so the error makes sense
-		if _, ok := err.(NoConfigsFoundError); len(files) != 0 && ok {
+		var ncfErr NoConfigsFoundError
+		if len(files) != 0 && errors.As(err, &ncfErr) {
 			// Config lists found but no config files found
 			return nil, NotFoundError{dir, name}
 		}
diff --git a/vendor/github.com/containernetworking/cni/libcni/multierror.go b/vendor/github.com/containernetworking/cni/libcni/multierror.go
new file mode 100644
index 0000000000..100fb8392d
--- /dev/null
+++ b/vendor/github.com/containernetworking/cni/libcni/multierror.go
@@ -0,0 +1,58 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Copyright the 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.
+//
+// Adapted from errors/join.go from go 1.20
+// This package can be removed once the toolchain is updated to 1.20
+
+package libcni
+
+func joinErrors(errs ...error) error {
+	n := 0
+	for _, err := range errs {
+		if err != nil {
+			n++
+		}
+	}
+	if n == 0 {
+		return nil
+	}
+	e := &multiError{
+		errs: make([]error, 0, n),
+	}
+	for _, err := range errs {
+		if err != nil {
+			e.errs = append(e.errs, err)
+		}
+	}
+	return e
+}
+
+type multiError struct {
+	errs []error
+}
+
+func (e *multiError) Error() string {
+	var b []byte
+	for i, err := range e.errs {
+		if i > 0 {
+			b = append(b, '\n')
+		}
+		b = append(b, err.Error()...)
+	}
+	return string(b)
+}
diff --git a/vendor/github.com/containernetworking/cni/pkg/invoke/delegate.go b/vendor/github.com/containernetworking/cni/pkg/invoke/delegate.go
index 8defe4dd39..c8b548e7c6 100644
--- a/vendor/github.com/containernetworking/cni/pkg/invoke/delegate.go
+++ b/vendor/github.com/containernetworking/cni/pkg/invoke/delegate.go
@@ -51,25 +51,34 @@ func DelegateAdd(ctx context.Context, delegatePlugin string, netconf []byte, exe
 // DelegateCheck calls the given delegate plugin with the CNI CHECK action and
 // JSON configuration
 func DelegateCheck(ctx context.Context, delegatePlugin string, netconf []byte, exec Exec) error {
+	return delegateNoResult(ctx, delegatePlugin, netconf, exec, "CHECK")
+}
+
+func delegateNoResult(ctx context.Context, delegatePlugin string, netconf []byte, exec Exec, verb string) error {
 	pluginPath, realExec, err := delegateCommon(delegatePlugin, exec)
 	if err != nil {
 		return err
 	}
 
-	// DelegateCheck will override the original CNI_COMMAND env from process with CHECK
-	return ExecPluginWithoutResult(ctx, pluginPath, netconf, delegateArgs("CHECK"), realExec)
+	return ExecPluginWithoutResult(ctx, pluginPath, netconf, delegateArgs(verb), realExec)
 }
 
 // DelegateDel calls the given delegate plugin with the CNI DEL action and
 // JSON configuration
 func DelegateDel(ctx context.Context, delegatePlugin string, netconf []byte, exec Exec) error {
-	pluginPath, realExec, err := delegateCommon(delegatePlugin, exec)
-	if err != nil {
-		return err
-	}
+	return delegateNoResult(ctx, delegatePlugin, netconf, exec, "DEL")
+}
 
-	// DelegateDel will override the original CNI_COMMAND env from process with DEL
-	return ExecPluginWithoutResult(ctx, pluginPath, netconf, delegateArgs("DEL"), realExec)
+// DelegateStatus calls the given delegate plugin with the CNI STATUS action and
+// JSON configuration
+func DelegateStatus(ctx context.Context, delegatePlugin string, netconf []byte, exec Exec) error {
+	return delegateNoResult(ctx, delegatePlugin, netconf, exec, "STATUS")
+}
+
+// DelegateGC calls the given delegate plugin with the CNI GC action and
+// JSON configuration
+func DelegateGC(ctx context.Context, delegatePlugin string, netconf []byte, exec Exec) error {
+	return delegateNoResult(ctx, delegatePlugin, netconf, exec, "GC")
 }
 
 // return CNIArgs used by delegation
diff --git a/vendor/github.com/containernetworking/cni/pkg/invoke/exec.go b/vendor/github.com/containernetworking/cni/pkg/invoke/exec.go
index 3ad07aa8f2..a5e015fc92 100644
--- a/vendor/github.com/containernetworking/cni/pkg/invoke/exec.go
+++ b/vendor/github.com/containernetworking/cni/pkg/invoke/exec.go
@@ -81,17 +81,17 @@ func fixupResultVersion(netconf, result []byte) (string, []byte, error) {
 // object to ExecPluginWithResult() to verify the incoming stdin and environment
 // and provide a tailored response:
 //
-//import (
+// import (
 //	"encoding/json"
 //	"path"
 //	"strings"
-//)
+// )
 //
-//type fakeExec struct {
+// type fakeExec struct {
 //	version.PluginDecoder
-//}
+// }
 //
-//func (f *fakeExec) ExecPlugin(pluginPath string, stdinData []byte, environ []string) ([]byte, error) {
+// func (f *fakeExec) ExecPlugin(pluginPath string, stdinData []byte, environ []string) ([]byte, error) {
 //	net := &types.NetConf{}
 //	err := json.Unmarshal(stdinData, net)
 //	if err != nil {
@@ -109,14 +109,14 @@ func fixupResultVersion(netconf, result []byte) (string, []byte, error) {
 //		}
 //	}
 //	return []byte("{\"CNIVersion\":\"0.4.0\"}"), nil
-//}
+// }
 //
-//func (f *fakeExec) FindInPath(plugin string, paths []string) (string, error) {
+// func (f *fakeExec) FindInPath(plugin string, paths []string) (string, error) {
 //	if len(paths) > 0 {
 //		return path.Join(paths[0], plugin), nil
 //	}
 //	return "", fmt.Errorf("failed to find plugin %s in paths %v", plugin, paths)
-//}
+// }
 
 func ExecPluginWithResult(ctx context.Context, pluginPath string, netconf []byte, args CNIArgs, exec Exec) (types.Result, error) {
 	if exec == nil {
diff --git a/vendor/github.com/containernetworking/cni/pkg/invoke/os_unix.go b/vendor/github.com/containernetworking/cni/pkg/invoke/os_unix.go
index 9bcfb45536..ed0999bd0e 100644
--- a/vendor/github.com/containernetworking/cni/pkg/invoke/os_unix.go
+++ b/vendor/github.com/containernetworking/cni/pkg/invoke/os_unix.go
@@ -12,6 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
 // +build darwin dragonfly freebsd linux netbsd openbsd solaris
 
 package invoke
diff --git a/vendor/github.com/containernetworking/cni/pkg/ns/ns_linux.go b/vendor/github.com/containernetworking/cni/pkg/ns/ns_linux.go
new file mode 100644
index 0000000000..3d58e75d6c
--- /dev/null
+++ b/vendor/github.com/containernetworking/cni/pkg/ns/ns_linux.go
@@ -0,0 +1,50 @@
+// Copyright 2022 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 ns
+
+import (
+	"runtime"
+
+	"github.com/vishvananda/netns"
+
+	"github.com/containernetworking/cni/pkg/types"
+)
+
+// Returns an object representing the current OS thread's network namespace
+func getCurrentNS() (netns.NsHandle, error) {
+	// Lock the thread in case other goroutine executes in it and changes its
+	// network namespace after getCurrentThreadNetNSPath(), otherwise it might
+	// return an unexpected network namespace.
+	runtime.LockOSThread()
+	defer runtime.UnlockOSThread()
+	return netns.Get()
+}
+
+func CheckNetNS(nsPath string) (bool, *types.Error) {
+	ns, err := netns.GetFromPath(nsPath)
+	// Let plugins check whether nsPath from args is valid. Also support CNI DEL for empty nsPath as already-deleted nsPath.
+	if err != nil {
+		return false, nil
+	}
+	defer ns.Close()
+
+	pluginNS, err := getCurrentNS()
+	if err != nil {
+		return false, types.NewError(types.ErrInvalidNetNS, "get plugin's netns failed", "")
+	}
+	defer pluginNS.Close()
+
+	return pluginNS.Equal(ns), nil
+}
diff --git a/vendor/github.com/containernetworking/cni/pkg/ns/ns_windows.go b/vendor/github.com/containernetworking/cni/pkg/ns/ns_windows.go
new file mode 100644
index 0000000000..cffe136178
--- /dev/null
+++ b/vendor/github.com/containernetworking/cni/pkg/ns/ns_windows.go
@@ -0,0 +1,21 @@
+// Copyright 2022 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 ns
+
+import "github.com/containernetworking/cni/pkg/types"
+
+func CheckNetNS(nsPath string) (bool, *types.Error) {
+	return false, nil
+}
diff --git a/vendor/github.com/containernetworking/cni/pkg/skel/skel.go b/vendor/github.com/containernetworking/cni/pkg/skel/skel.go
index cb8781972d..f29cf34594 100644
--- a/vendor/github.com/containernetworking/cni/pkg/skel/skel.go
+++ b/vendor/github.com/containernetworking/cni/pkg/skel/skel.go
@@ -19,13 +19,14 @@ package skel
 import (
 	"bytes"
 	"encoding/json"
+	"errors"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"log"
 	"os"
 	"strings"
 
+	"github.com/containernetworking/cni/pkg/ns"
 	"github.com/containernetworking/cni/pkg/types"
 	"github.com/containernetworking/cni/pkg/utils"
 	"github.com/containernetworking/cni/pkg/version"
@@ -34,12 +35,13 @@ import (
 // CmdArgs captures all the arguments passed in to the plugin
 // via both env vars and stdin
 type CmdArgs struct {
-	ContainerID string
-	Netns       string
-	IfName      string
-	Args        string
-	Path        string
-	StdinData   []byte
+	ContainerID   string
+	Netns         string
+	IfName        string
+	Args          string
+	Path          string
+	NetnsOverride string
+	StdinData     []byte
 }
 
 type dispatcher struct {
@@ -55,21 +57,25 @@ type dispatcher struct {
 type reqForCmdEntry map[string]bool
 
 func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, *types.Error) {
-	var cmd, contID, netns, ifName, args, path string
+	var cmd, contID, netns, ifName, args, path, netnsOverride string
 
 	vars := []struct {
-		name      string
-		val       *string
-		reqForCmd reqForCmdEntry
+		name       string
+		val        *string
+		reqForCmd  reqForCmdEntry
+		validateFn func(string) *types.Error
 	}{
 		{
 			"CNI_COMMAND",
 			&cmd,
 			reqForCmdEntry{
-				"ADD":   true,
-				"CHECK": true,
-				"DEL":   true,
+				"ADD":    true,
+				"CHECK":  true,
+				"DEL":    true,
+				"GC":     true,
+				"STATUS": true,
 			},
+			nil,
 		},
 		{
 			"CNI_CONTAINERID",
@@ -79,6 +85,7 @@ func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, *types.Error) {
 				"CHECK": true,
 				"DEL":   true,
 			},
+			utils.ValidateContainerID,
 		},
 		{
 			"CNI_NETNS",
@@ -88,6 +95,7 @@ func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, *types.Error) {
 				"CHECK": true,
 				"DEL":   false,
 			},
+			nil,
 		},
 		{
 			"CNI_IFNAME",
@@ -97,6 +105,7 @@ func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, *types.Error) {
 				"CHECK": true,
 				"DEL":   true,
 			},
+			utils.ValidateInterfaceName,
 		},
 		{
 			"CNI_ARGS",
@@ -106,15 +115,29 @@ func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, *types.Error) {
 				"CHECK": false,
 				"DEL":   false,
 			},
+			nil,
 		},
 		{
 			"CNI_PATH",
 			&path,
 			reqForCmdEntry{
-				"ADD":   true,
-				"CHECK": true,
-				"DEL":   true,
+				"ADD":    true,
+				"CHECK":  true,
+				"DEL":    true,
+				"GC":     true,
+				"STATUS": true,
+			},
+			nil,
+		},
+		{
+			"CNI_NETNS_OVERRIDE",
+			&netnsOverride,
+			reqForCmdEntry{
+				"ADD":   false,
+				"CHECK": false,
+				"DEL":   false,
 			},
+			nil,
 		},
 	}
 
@@ -125,6 +148,10 @@ func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, *types.Error) {
 			if v.reqForCmd[cmd] || v.name == "CNI_COMMAND" {
 				argsMissing = append(argsMissing, v.name)
 			}
+		} else if v.reqForCmd[cmd] && v.validateFn != nil {
+			if err := v.validateFn(*v.val); err != nil {
+				return "", nil, err
+			}
 		}
 	}
 
@@ -137,18 +164,25 @@ func (t *dispatcher) getCmdArgsFromEnv() (string, *CmdArgs, *types.Error) {
 		t.Stdin = bytes.NewReader(nil)
 	}
 
-	stdinData, err := ioutil.ReadAll(t.Stdin)
+	stdinData, err := io.ReadAll(t.Stdin)
 	if err != nil {
 		return "", nil, types.NewError(types.ErrIOFailure, fmt.Sprintf("error reading from stdin: %v", err), "")
 	}
 
+	if cmd != "VERSION" {
+		if err := validateConfig(stdinData); err != nil {
+			return "", nil, err
+		}
+	}
+
 	cmdArgs := &CmdArgs{
-		ContainerID: contID,
-		Netns:       netns,
-		IfName:      ifName,
-		Args:        args,
-		Path:        path,
-		StdinData:   stdinData,
+		ContainerID:   contID,
+		Netns:         netns,
+		IfName:        ifName,
+		Args:          args,
+		Path:          path,
+		StdinData:     stdinData,
+		NetnsOverride: netnsOverride,
 	}
 	return cmd, cmdArgs, nil
 }
@@ -163,8 +197,13 @@ func (t *dispatcher) checkVersionAndCall(cmdArgs *CmdArgs, pluginVersionInfo ver
 		return types.NewError(types.ErrIncompatibleCNIVersion, "incompatible CNI versions", verErr.Details())
 	}
 
+	if toCall == nil {
+		return nil
+	}
+
 	if err = toCall(cmdArgs); err != nil {
-		if e, ok := err.(*types.Error); ok {
+		var e *types.Error
+		if errors.As(err, &e) {
 			// don't wrap Error in Error
 			return e
 		}
@@ -190,7 +229,7 @@ func validateConfig(jsonBytes []byte) *types.Error {
 	return nil
 }
 
-func (t *dispatcher) pluginMain(cmdAdd, cmdCheck, cmdDel func(_ *CmdArgs) error, versionInfo version.PluginInfo, about string) *types.Error {
+func (t *dispatcher) pluginMain(funcs CNIFuncs, versionInfo version.PluginInfo, about string) *types.Error {
 	cmd, cmdArgs, err := t.getCmdArgsFromEnv()
 	if err != nil {
 		// Print the about string to stderr when no command is set
@@ -202,21 +241,20 @@ func (t *dispatcher) pluginMain(cmdAdd, cmdCheck, cmdDel func(_ *CmdArgs) error,
 		return err
 	}
 
-	if cmd != "VERSION" {
-		if err = validateConfig(cmdArgs.StdinData); err != nil {
-			return err
-		}
-		if err = utils.ValidateContainerID(cmdArgs.ContainerID); err != nil {
+	switch cmd {
+	case "ADD":
+		err = t.checkVersionAndCall(cmdArgs, versionInfo, funcs.Add)
+		if err != nil {
 			return err
 		}
-		if err = utils.ValidateInterfaceName(cmdArgs.IfName); err != nil {
-			return err
+		if strings.ToUpper(cmdArgs.NetnsOverride) != "TRUE" && cmdArgs.NetnsOverride != "1" {
+			isPluginNetNS, checkErr := ns.CheckNetNS(cmdArgs.Netns)
+			if checkErr != nil {
+				return checkErr
+			} else if isPluginNetNS {
+				return types.NewError(types.ErrInvalidNetNS, "plugin's netns and netns from CNI_NETNS should not be the same", "")
+			}
 		}
-	}
-
-	switch cmd {
-	case "ADD":
-		err = t.checkVersionAndCall(cmdArgs, versionInfo, cmdAdd)
 	case "CHECK":
 		configVersion, err := t.ConfVersionDecoder.Decode(cmdArgs.StdinData)
 		if err != nil {
@@ -232,7 +270,7 @@ func (t *dispatcher) pluginMain(cmdAdd, cmdCheck, cmdDel func(_ *CmdArgs) error,
 			if err != nil {
 				return types.NewError(types.ErrDecodingFailure, err.Error(), "")
 			} else if gtet {
-				if err := t.checkVersionAndCall(cmdArgs, versionInfo, cmdCheck); err != nil {
+				if err := t.checkVersionAndCall(cmdArgs, versionInfo, funcs.Check); err != nil {
 					return err
 				}
 				return nil
@@ -240,7 +278,62 @@ func (t *dispatcher) pluginMain(cmdAdd, cmdCheck, cmdDel func(_ *CmdArgs) error,
 		}
 		return types.NewError(types.ErrIncompatibleCNIVersion, "plugin version does not allow CHECK", "")
 	case "DEL":
-		err = t.checkVersionAndCall(cmdArgs, versionInfo, cmdDel)
+		err = t.checkVersionAndCall(cmdArgs, versionInfo, funcs.Del)
+		if err != nil {
+			return err
+		}
+		if strings.ToUpper(cmdArgs.NetnsOverride) != "TRUE" && cmdArgs.NetnsOverride != "1" {
+			isPluginNetNS, checkErr := ns.CheckNetNS(cmdArgs.Netns)
+			if checkErr != nil {
+				return checkErr
+			} else if isPluginNetNS {
+				return types.NewError(types.ErrInvalidNetNS, "plugin's netns and netns from CNI_NETNS should not be the same", "")
+			}
+		}
+	case "GC":
+		configVersion, err := t.ConfVersionDecoder.Decode(cmdArgs.StdinData)
+		if err != nil {
+			return types.NewError(types.ErrDecodingFailure, err.Error(), "")
+		}
+		if gtet, err := version.GreaterThanOrEqualTo(configVersion, "1.1.0"); err != nil {
+			return types.NewError(types.ErrDecodingFailure, err.Error(), "")
+		} else if !gtet {
+			return types.NewError(types.ErrIncompatibleCNIVersion, "config version does not allow GC", "")
+		}
+		for _, pluginVersion := range versionInfo.SupportedVersions() {
+			gtet, err := version.GreaterThanOrEqualTo(pluginVersion, configVersion)
+			if err != nil {
+				return types.NewError(types.ErrDecodingFailure, err.Error(), "")
+			} else if gtet {
+				if err := t.checkVersionAndCall(cmdArgs, versionInfo, funcs.GC); err != nil {
+					return err
+				}
+				return nil
+			}
+		}
+		return types.NewError(types.ErrIncompatibleCNIVersion, "plugin version does not allow GC", "")
+	case "STATUS":
+		configVersion, err := t.ConfVersionDecoder.Decode(cmdArgs.StdinData)
+		if err != nil {
+			return types.NewError(types.ErrDecodingFailure, err.Error(), "")
+		}
+		if gtet, err := version.GreaterThanOrEqualTo(configVersion, "1.1.0"); err != nil {
+			return types.NewError(types.ErrDecodingFailure, err.Error(), "")
+		} else if !gtet {
+			return types.NewError(types.ErrIncompatibleCNIVersion, "config version does not allow STATUS", "")
+		}
+		for _, pluginVersion := range versionInfo.SupportedVersions() {
+			gtet, err := version.GreaterThanOrEqualTo(pluginVersion, configVersion)
+			if err != nil {
+				return types.NewError(types.ErrDecodingFailure, err.Error(), "")
+			} else if gtet {
+				if err := t.checkVersionAndCall(cmdArgs, versionInfo, funcs.Status); err != nil {
+					return err
+				}
+				return nil
+			}
+		}
+		return types.NewError(types.ErrIncompatibleCNIVersion, "plugin version does not allow STATUS", "")
 	case "VERSION":
 		if err := versionInfo.Encode(t.Stdout); err != nil {
 			return types.NewError(types.ErrIOFailure, err.Error(), "")
@@ -264,13 +357,63 @@ func (t *dispatcher) pluginMain(cmdAdd, cmdCheck, cmdDel func(_ *CmdArgs) error,
 //
 // To let this package automatically handle errors and call os.Exit(1) for you,
 // use PluginMain() instead.
+//
+// Deprecated: Use github.com/containernetworking/cni/pkg/skel.PluginMainFuncsWithError instead.
 func PluginMainWithError(cmdAdd, cmdCheck, cmdDel func(_ *CmdArgs) error, versionInfo version.PluginInfo, about string) *types.Error {
+	return PluginMainFuncsWithError(CNIFuncs{Add: cmdAdd, Check: cmdCheck, Del: cmdDel}, versionInfo, about)
+}
+
+// CNIFuncs contains a group of callback command funcs to be passed in as
+// parameters to the core "main" for a plugin.
+type CNIFuncs struct {
+	Add    func(_ *CmdArgs) error
+	Del    func(_ *CmdArgs) error
+	Check  func(_ *CmdArgs) error
+	GC     func(_ *CmdArgs) error
+	Status func(_ *CmdArgs) error
+}
+
+// PluginMainFuncsWithError is the core "main" for a plugin. It accepts
+// callback functions defined within CNIFuncs and returns an error.
+//
+// The caller must also specify what CNI spec versions the plugin supports.
+//
+// It is the responsibility of the caller to check for non-nil error return.
+//
+// For a plugin to comply with the CNI spec, it must print any error to stdout
+// as JSON and then exit with nonzero status code.
+//
+// To let this package automatically handle errors and call os.Exit(1) for you,
+// use PluginMainFuncs() instead.
+func PluginMainFuncsWithError(funcs CNIFuncs, versionInfo version.PluginInfo, about string) *types.Error {
 	return (&dispatcher{
 		Getenv: os.Getenv,
 		Stdin:  os.Stdin,
 		Stdout: os.Stdout,
 		Stderr: os.Stderr,
-	}).pluginMain(cmdAdd, cmdCheck, cmdDel, versionInfo, about)
+	}).pluginMain(funcs, versionInfo, about)
+}
+
+// PluginMainFuncs is the core "main" for a plugin which includes automatic error handling.
+// This is a newer alternative func to PluginMain which abstracts CNI commands within a
+// CNIFuncs interface.
+//
+// The caller must also specify what CNI spec versions the plugin supports.
+//
+// The caller can specify an "about" string, which is printed on stderr
+// when no CNI_COMMAND is specified. The recommended output is "CNI plugin <foo> v<version>"
+//
+// When an error occurs in any func in CNIFuncs, PluginMainFuncs will print the error
+// as JSON to stdout and call os.Exit(1).
+//
+// To have more control over error handling, use PluginMainFuncsWithError() instead.
+func PluginMainFuncs(funcs CNIFuncs, versionInfo version.PluginInfo, about string) {
+	if e := PluginMainFuncsWithError(funcs, versionInfo, about); e != nil {
+		if err := e.Print(); err != nil {
+			log.Print("Error writing error JSON to stdout: ", err)
+		}
+		os.Exit(1)
+	}
 }
 
 // PluginMain is the core "main" for a plugin which includes automatic error handling.
@@ -284,6 +427,8 @@ func PluginMainWithError(cmdAdd, cmdCheck, cmdDel func(_ *CmdArgs) error, versio
 // as JSON to stdout and call os.Exit(1).
 //
 // To have more control over error handling, use PluginMainWithError() instead.
+//
+// Deprecated: Use github.com/containernetworking/cni/pkg/skel.PluginMainFuncs instead.
 func PluginMain(cmdAdd, cmdCheck, cmdDel func(_ *CmdArgs) error, versionInfo version.PluginInfo, about string) {
 	if e := PluginMainWithError(cmdAdd, cmdCheck, cmdDel, versionInfo, about); e != nil {
 		if err := e.Print(); err != nil {
diff --git a/vendor/github.com/containernetworking/cni/pkg/types/100/types.go b/vendor/github.com/containernetworking/cni/pkg/types/100/types.go
index 0e1e8b857b..f58b91206d 100644
--- a/vendor/github.com/containernetworking/cni/pkg/types/100/types.go
+++ b/vendor/github.com/containernetworking/cni/pkg/types/100/types.go
@@ -26,9 +26,10 @@ import (
 	convert "github.com/containernetworking/cni/pkg/types/internal"
 )
 
-const ImplementedSpecVersion string = "1.0.0"
+// The types did not change between v1.0 and v1.1
+const ImplementedSpecVersion string = "1.1.0"
 
-var supportedVersions = []string{ImplementedSpecVersion}
+var supportedVersions = []string{"1.0.0", "1.1.0"}
 
 // Register converters for all versions less than the implemented spec version
 func init() {
@@ -38,10 +39,14 @@ func init() {
 	convert.RegisterConverter("0.3.0", supportedVersions, convertFrom04x)
 	convert.RegisterConverter("0.3.1", supportedVersions, convertFrom04x)
 	convert.RegisterConverter("0.4.0", supportedVersions, convertFrom04x)
+	convert.RegisterConverter("1.0.0", []string{"1.1.0"}, convertFrom100)
 
 	// Down-converters
 	convert.RegisterConverter("1.0.0", []string{"0.3.0", "0.3.1", "0.4.0"}, convertTo04x)
 	convert.RegisterConverter("1.0.0", []string{"0.1.0", "0.2.0"}, convertTo02x)
+	convert.RegisterConverter("1.1.0", []string{"0.3.0", "0.3.1", "0.4.0"}, convertTo04x)
+	convert.RegisterConverter("1.1.0", []string{"0.1.0", "0.2.0"}, convertTo02x)
+	convert.RegisterConverter("1.1.0", []string{"1.0.0"}, convertFrom100)
 
 	// Creator
 	convert.RegisterCreator(supportedVersions, NewResult)
@@ -90,12 +95,49 @@ type Result struct {
 	DNS        types.DNS      `json:"dns,omitempty"`
 }
 
+// Note: DNS should be omit if DNS is empty but default Marshal function
+// will output empty structure hence need to write a Marshal function
+func (r *Result) MarshalJSON() ([]byte, error) {
+	// use type alias to escape recursion for json.Marshal() to MarshalJSON()
+	type fixObjType = Result
+
+	bytes, err := json.Marshal(fixObjType(*r)) //nolint:all
+	if err != nil {
+		return nil, err
+	}
+
+	fixupObj := make(map[string]interface{})
+	if err := json.Unmarshal(bytes, &fixupObj); err != nil {
+		return nil, err
+	}
+
+	if r.DNS.IsEmpty() {
+		delete(fixupObj, "dns")
+	}
+
+	return json.Marshal(fixupObj)
+}
+
+// convertFrom100 does nothing except set the version; the types are the same
+func convertFrom100(from types.Result, toVersion string) (types.Result, error) {
+	fromResult := from.(*Result)
+
+	result := &Result{
+		CNIVersion: toVersion,
+		Interfaces: fromResult.Interfaces,
+		IPs:        fromResult.IPs,
+		Routes:     fromResult.Routes,
+		DNS:        fromResult.DNS,
+	}
+	return result, nil
+}
+
 func convertFrom02x(from types.Result, toVersion string) (types.Result, error) {
 	result040, err := convert.Convert(from, "0.4.0")
 	if err != nil {
 		return nil, err
 	}
-	result100, err := convertFrom04x(result040, ImplementedSpecVersion)
+	result100, err := convertFrom04x(result040, toVersion)
 	if err != nil {
 		return nil, err
 	}
@@ -226,9 +268,12 @@ func (r *Result) PrintTo(writer io.Writer) error {
 
 // Interface contains values about the created interfaces
 type Interface struct {
-	Name    string `json:"name"`
-	Mac     string `json:"mac,omitempty"`
-	Sandbox string `json:"sandbox,omitempty"`
+	Name       string `json:"name"`
+	Mac        string `json:"mac,omitempty"`
+	Mtu        int    `json:"mtu,omitempty"`
+	Sandbox    string `json:"sandbox,omitempty"`
+	SocketPath string `json:"socketPath,omitempty"`
+	PciID      string `json:"pciID,omitempty"`
 }
 
 func (i *Interface) String() string {
diff --git a/vendor/github.com/containernetworking/cni/pkg/types/args.go b/vendor/github.com/containernetworking/cni/pkg/types/args.go
index 7516f03ef5..68a602bfdb 100644
--- a/vendor/github.com/containernetworking/cni/pkg/types/args.go
+++ b/vendor/github.com/containernetworking/cni/pkg/types/args.go
@@ -26,8 +26,8 @@ import (
 type UnmarshallableBool bool
 
 // UnmarshalText implements the encoding.TextUnmarshaler interface.
-// Returns boolean true if the string is "1" or "[Tt]rue"
-// Returns boolean false if the string is "0" or "[Ff]alse"
+// Returns boolean true if the string is "1" or "true" or "True"
+// Returns boolean false if the string is "0" or "false" or "Falseā€
 func (b *UnmarshallableBool) UnmarshalText(data []byte) error {
 	s := strings.ToLower(string(data))
 	switch s {
diff --git a/vendor/github.com/containernetworking/cni/pkg/types/create/create.go b/vendor/github.com/containernetworking/cni/pkg/types/create/create.go
index ed28b33e8e..452cb62201 100644
--- a/vendor/github.com/containernetworking/cni/pkg/types/create/create.go
+++ b/vendor/github.com/containernetworking/cni/pkg/types/create/create.go
@@ -19,6 +19,9 @@ import (
 	"fmt"
 
 	"github.com/containernetworking/cni/pkg/types"
+	_ "github.com/containernetworking/cni/pkg/types/020"
+	_ "github.com/containernetworking/cni/pkg/types/040"
+	_ "github.com/containernetworking/cni/pkg/types/100"
 	convert "github.com/containernetworking/cni/pkg/types/internal"
 )
 
diff --git a/vendor/github.com/containernetworking/cni/pkg/types/types.go b/vendor/github.com/containernetworking/cni/pkg/types/types.go
index fba17dfc0f..193ac46ef8 100644
--- a/vendor/github.com/containernetworking/cni/pkg/types/types.go
+++ b/vendor/github.com/containernetworking/cni/pkg/types/types.go
@@ -64,16 +64,55 @@ type NetConf struct {
 	Type         string          `json:"type,omitempty"`
 	Capabilities map[string]bool `json:"capabilities,omitempty"`
 	IPAM         IPAM            `json:"ipam,omitempty"`
-	DNS          DNS             `json:"dns"`
+	DNS          DNS             `json:"dns,omitempty"`
 
 	RawPrevResult map[string]interface{} `json:"prevResult,omitempty"`
 	PrevResult    Result                 `json:"-"`
+
+	// ValidAttachments is only supplied when executing a GC operation
+	ValidAttachments []GCAttachment `json:"cni.dev/valid-attachments,omitempty"`
+}
+
+// GCAttachment is the parameters to a GC call -- namely,
+// the container ID and ifname pair that represents a
+// still-valid attachment.
+type GCAttachment struct {
+	ContainerID string `json:"containerID"`
+	IfName      string `json:"ifname"`
+}
+
+// Note: DNS should be omit if DNS is empty but default Marshal function
+// will output empty structure hence need to write a Marshal function
+func (n *NetConf) MarshalJSON() ([]byte, error) {
+	// use type alias to escape recursion for json.Marshal() to MarshalJSON()
+	type fixObjType = NetConf
+
+	bytes, err := json.Marshal(fixObjType(*n)) //nolint:all
+	if err != nil {
+		return nil, err
+	}
+
+	fixupObj := make(map[string]interface{})
+	if err := json.Unmarshal(bytes, &fixupObj); err != nil {
+		return nil, err
+	}
+
+	if n.DNS.IsEmpty() {
+		delete(fixupObj, "dns")
+	}
+
+	return json.Marshal(fixupObj)
 }
 
 type IPAM struct {
 	Type string `json:"type,omitempty"`
 }
 
+// IsEmpty returns true if IPAM structure has no value, otherwise return false
+func (i *IPAM) IsEmpty() bool {
+	return i.Type == ""
+}
+
 // NetConfList describes an ordered list of networks.
 type NetConfList struct {
 	CNIVersion string `json:"cniVersion,omitempty"`
@@ -116,31 +155,48 @@ type DNS struct {
 	Options     []string `json:"options,omitempty"`
 }
 
+// IsEmpty returns true if DNS structure has no value, otherwise return false
+func (d *DNS) IsEmpty() bool {
+	if len(d.Nameservers) == 0 && d.Domain == "" && len(d.Search) == 0 && len(d.Options) == 0 {
+		return true
+	}
+	return false
+}
+
 func (d *DNS) Copy() *DNS {
 	if d == nil {
 		return nil
 	}
 
 	to := &DNS{Domain: d.Domain}
-	for _, ns := range d.Nameservers {
-		to.Nameservers = append(to.Nameservers, ns)
-	}
-	for _, s := range d.Search {
-		to.Search = append(to.Search, s)
-	}
-	for _, o := range d.Options {
-		to.Options = append(to.Options, o)
-	}
+	to.Nameservers = append(to.Nameservers, d.Nameservers...)
+	to.Search = append(to.Search, d.Search...)
+	to.Options = append(to.Options, d.Options...)
 	return to
 }
 
 type Route struct {
-	Dst net.IPNet
-	GW  net.IP
+	Dst      net.IPNet
+	GW       net.IP
+	MTU      int
+	AdvMSS   int
+	Priority int
+	Table    *int
+	Scope    *int
 }
 
 func (r *Route) String() string {
-	return fmt.Sprintf("%+v", *r)
+	table := "<nil>"
+	if r.Table != nil {
+		table = fmt.Sprintf("%d", *r.Table)
+	}
+
+	scope := "<nil>"
+	if r.Scope != nil {
+		scope = fmt.Sprintf("%d", *r.Scope)
+	}
+
+	return fmt.Sprintf("{Dst:%+v GW:%v MTU:%d AdvMSS:%d Priority:%d Table:%s Scope:%s}", r.Dst, r.GW, r.MTU, r.AdvMSS, r.Priority, table, scope)
 }
 
 func (r *Route) Copy() *Route {
@@ -148,14 +204,30 @@ func (r *Route) Copy() *Route {
 		return nil
 	}
 
-	return &Route{
-		Dst: r.Dst,
-		GW:  r.GW,
+	route := &Route{
+		Dst:      r.Dst,
+		GW:       r.GW,
+		MTU:      r.MTU,
+		AdvMSS:   r.AdvMSS,
+		Priority: r.Priority,
+		Scope:    r.Scope,
+	}
+
+	if r.Table != nil {
+		table := *r.Table
+		route.Table = &table
 	}
+
+	if r.Scope != nil {
+		scope := *r.Scope
+		route.Scope = &scope
+	}
+
+	return route
 }
 
 // Well known error codes
-// see https://github.com/containernetworking/cni/blob/master/SPEC.md#well-known-error-codes
+// see https://github.com/containernetworking/cni/blob/main/SPEC.md#well-known-error-codes
 const (
 	ErrUnknown                     uint = iota // 0
 	ErrIncompatibleCNIVersion                  // 1
@@ -165,6 +237,7 @@ const (
 	ErrIOFailure                               // 5
 	ErrDecodingFailure                         // 6
 	ErrInvalidNetworkConfig                    // 7
+	ErrInvalidNetNS                            // 8
 	ErrTryAgainLater               uint = 11
 	ErrInternal                    uint = 999
 )
@@ -200,8 +273,13 @@ func (e *Error) Print() error {
 
 // JSON (un)marshallable types
 type route struct {
-	Dst IPNet  `json:"dst"`
-	GW  net.IP `json:"gw,omitempty"`
+	Dst      IPNet  `json:"dst"`
+	GW       net.IP `json:"gw,omitempty"`
+	MTU      int    `json:"mtu,omitempty"`
+	AdvMSS   int    `json:"advmss,omitempty"`
+	Priority int    `json:"priority,omitempty"`
+	Table    *int   `json:"table,omitempty"`
+	Scope    *int   `json:"scope,omitempty"`
 }
 
 func (r *Route) UnmarshalJSON(data []byte) error {
@@ -212,13 +290,24 @@ func (r *Route) UnmarshalJSON(data []byte) error {
 
 	r.Dst = net.IPNet(rt.Dst)
 	r.GW = rt.GW
+	r.MTU = rt.MTU
+	r.AdvMSS = rt.AdvMSS
+	r.Priority = rt.Priority
+	r.Table = rt.Table
+	r.Scope = rt.Scope
+
 	return nil
 }
 
 func (r Route) MarshalJSON() ([]byte, error) {
 	rt := route{
-		Dst: IPNet(r.Dst),
-		GW:  r.GW,
+		Dst:      IPNet(r.Dst),
+		GW:       r.GW,
+		MTU:      r.MTU,
+		AdvMSS:   r.AdvMSS,
+		Priority: r.Priority,
+		Table:    r.Table,
+		Scope:    r.Scope,
 	}
 
 	return json.Marshal(rt)
diff --git a/vendor/github.com/containernetworking/cni/pkg/utils/utils.go b/vendor/github.com/containernetworking/cni/pkg/utils/utils.go
index b8ec388745..1981d25569 100644
--- a/vendor/github.com/containernetworking/cni/pkg/utils/utils.go
+++ b/vendor/github.com/containernetworking/cni/pkg/utils/utils.go
@@ -36,7 +36,6 @@ var cniReg = regexp.MustCompile(`^` + cniValidNameChars + `*$`)
 
 // ValidateContainerID will validate that the supplied containerID is not empty does not contain invalid characters
 func ValidateContainerID(containerID string) *types.Error {
-
 	if containerID == "" {
 		return types.NewError(types.ErrUnknownContainer, "missing containerID", "")
 	}
@@ -48,7 +47,6 @@ func ValidateContainerID(containerID string) *types.Error {
 
 // ValidateNetworkName will validate that the supplied networkName does not contain invalid characters
 func ValidateNetworkName(networkName string) *types.Error {
-
 	if networkName == "" {
 		return types.NewError(types.ErrInvalidNetworkConfig, "missing network name:", "")
 	}
@@ -58,11 +56,11 @@ func ValidateNetworkName(networkName string) *types.Error {
 	return nil
 }
 
-// ValidateInterfaceName will validate the interface name based on the three rules below
+// ValidateInterfaceName will validate the interface name based on the four rules below
 // 1. The name must not be empty
 // 2. The name must be less than 16 characters
 // 3. The name must not be "." or ".."
-// 3. The name must not contain / or : or any whitespace characters
+// 4. The name must not contain / or : or any whitespace characters
 // ref to https://github.com/torvalds/linux/blob/master/net/core/dev.c#L1024
 func ValidateInterfaceName(ifName string) *types.Error {
 	if len(ifName) == 0 {
diff --git a/vendor/github.com/containernetworking/cni/pkg/version/version.go b/vendor/github.com/containernetworking/cni/pkg/version/version.go
index 1326f8038e..a4d442c8ec 100644
--- a/vendor/github.com/containernetworking/cni/pkg/version/version.go
+++ b/vendor/github.com/containernetworking/cni/pkg/version/version.go
@@ -19,13 +19,12 @@ import (
 	"fmt"
 
 	"github.com/containernetworking/cni/pkg/types"
-	types100 "github.com/containernetworking/cni/pkg/types/100"
 	"github.com/containernetworking/cni/pkg/types/create"
 )
 
 // Current reports the version of the CNI spec implemented by this library
 func Current() string {
-	return types100.ImplementedSpecVersion
+	return "1.1.0"
 }
 
 // Legacy PluginInfo describes a plugin that is backwards compatible with the
@@ -35,8 +34,10 @@ func Current() string {
 //
 // Any future CNI spec versions which meet this definition should be added to
 // this list.
-var Legacy = PluginSupports("0.1.0", "0.2.0")
-var All = PluginSupports("0.1.0", "0.2.0", "0.3.0", "0.3.1", "0.4.0", "1.0.0")
+var (
+	Legacy = PluginSupports("0.1.0", "0.2.0")
+	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 {
diff --git a/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/NOTICE b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/NOTICE
new file mode 100644
index 0000000000..3e2901b3a6
--- /dev/null
+++ b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/NOTICE
@@ -0,0 +1 @@
+Copyright 2018 Kubernetes Network Plumbing Working Group
diff --git a/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/types.go b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/types.go
index 2b81d04827..f96016baf6 100644
--- a/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/types.go
+++ b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1/types.go
@@ -1,6 +1,8 @@
 package v1
 
 import (
+	"encoding/json"
+	"errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"net"
 )
@@ -105,6 +107,7 @@ type NetworkStatus struct {
 	Interface  string      `json:"interface,omitempty"`
 	IPs        []string    `json:"ips,omitempty"`
 	Mac        string      `json:"mac,omitempty"`
+	Mtu        int         `json:"mtu,omitempty"`
 	Default    bool        `json:"default,omitempty"`
 	DNS        DNS         `json:"dns,omitempty"`
 	DeviceInfo *DeviceInfo `json:"device-info,omitempty"`
@@ -162,6 +165,23 @@ type NetworkSelectionElement struct {
 	CNIArgs *map[string]interface{} `json:"cni-args,omitempty"`
 	// GatewayRequest contains default route IP address for the pod
 	GatewayRequest []net.IP `json:"default-route,omitempty"`
+	// IPAMClaimReference container the IPAMClaim name where the IPs for this
+	// attachment will be located.
+	IPAMClaimReference string `json:"ipam-claim-reference,omitempty"`
+}
+
+func (nse *NetworkSelectionElement) UnmarshalJSON(b []byte) error {
+	type networkSelectionElement NetworkSelectionElement
+
+	var netSelectionElement networkSelectionElement
+	if err := json.Unmarshal(b, &netSelectionElement); err != nil {
+		return err
+	}
+	if len(netSelectionElement.IPRequest) > 0 && netSelectionElement.IPAMClaimReference != "" {
+		return TooManyIPSources
+	}
+	*nse = NetworkSelectionElement(netSelectionElement)
+	return nil
 }
 
 const (
@@ -178,3 +198,5 @@ type NoK8sNetworkError struct {
 }
 
 func (e *NoK8sNetworkError) Error() string { return string(e.Message) }
+
+var TooManyIPSources = errors.New("cannot provide a static IP and a reference of an IPAM claim in the same network selection element")
diff --git a/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils/net-attach-def.go b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils/net-attach-def.go
index 4bca1645fb..97e6be1cb4 100644
--- a/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils/net-attach-def.go
+++ b/vendor/github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils/net-attach-def.go
@@ -122,6 +122,105 @@ func GetNetworkStatus(pod *corev1.Pod) ([]v1.NetworkStatus, error) {
 	return netStatuses, err
 }
 
+// gatewayInterfaceIndex determines the index of the first interface that has a gateway
+func gatewayInterfaceIndex(ips []*cni100.IPConfig) int {
+	for _, ipConfig := range ips {
+		if ipConfig.Gateway != nil && ipConfig.Interface != nil {
+			return *ipConfig.Interface
+		}
+	}
+	return -1
+}
+
+// CreateNetworkStatuses creates an array of NetworkStatus from CNI result
+// Not to be confused with CreateNetworkStatus (singular)
+// This is the preferred method and picks up when CNI ADD results contain multiple container interfaces
+func CreateNetworkStatuses(r cnitypes.Result, networkName string, defaultNetwork bool, dev *v1.DeviceInfo) ([]*v1.NetworkStatus, error) {
+	var networkStatuses []*v1.NetworkStatus
+	// indexMap is from original CNI result index to networkStatuses index
+	indexMap := make(map[int]int)
+
+	// Convert whatever the IPAM result was into the current Result type
+	result, err := cni100.NewResultFromResult(r)
+	if err != nil {
+		return nil, fmt.Errorf("error converting the type.Result to cni100.Result: %v", err)
+	}
+
+	if len(result.Interfaces) == 1 {
+		networkStatus, err := CreateNetworkStatus(r, networkName, defaultNetwork, dev)
+		return []*v1.NetworkStatus{networkStatus}, err
+	}
+
+	// Discover default routes upfront and reuse them if necessary.
+	var useDefaultRoute []string
+	for _, route := range result.Routes {
+		if isDefaultRoute(route) {
+			useDefaultRoute = append(useDefaultRoute, route.GW.String())
+		}
+	}
+
+	// Same for DNS
+	v1dns := convertDNS(result.DNS)
+
+	// Check for a gateway-associated interface, we'll use this later if we did to mark as the default.
+	gwInterfaceIdx := -1
+	if defaultNetwork {
+		gwInterfaceIdx = gatewayInterfaceIndex(result.IPs)
+	}
+
+	// Initialize NetworkStatus for each container interface (e.g. with sandbox present)
+	indexOfFoundPodInterface := 0
+	foundFirstSandboxIface := false
+	didSetDefault := false
+	for i, iface := range result.Interfaces {
+		if iface.Sandbox != "" {
+			isDefault := false
+
+			// If there's a gateway listed for this interface index found in the ips, we mark that interface as default
+			// notably, we use the first one we find.
+			if defaultNetwork && i == gwInterfaceIdx && !didSetDefault {
+				isDefault = true
+				didSetDefault = true
+			}
+
+			// Otherwise, if we didn't find it, we use the first sandbox interface.
+			if defaultNetwork && gwInterfaceIdx == -1 && !foundFirstSandboxIface {
+				isDefault = true
+				foundFirstSandboxIface = true
+			}
+
+			ns := &v1.NetworkStatus{
+				Name:       networkName,
+				Default:    isDefault,
+				Interface:  iface.Name,
+				Mac:        iface.Mac,
+				Mtu:        iface.Mtu,
+				IPs:        []string{},
+				Gateway:    useDefaultRoute,
+				DeviceInfo: dev,
+				DNS:        *v1dns,
+			}
+			networkStatuses = append(networkStatuses, ns)
+			// Map original index to the new slice index
+			indexMap[i] = indexOfFoundPodInterface
+			indexOfFoundPodInterface++
+		}
+	}
+
+	// Map IPs to network interface based on index
+	for _, ipConfig := range result.IPs {
+		if ipConfig.Interface != nil {
+			originalIndex := *ipConfig.Interface
+			if newIndex, ok := indexMap[originalIndex]; ok {
+				ns := networkStatuses[newIndex]
+				ns.IPs = append(ns.IPs, ipConfig.Address.IP.String())
+			}
+		}
+	}
+
+	return networkStatuses, nil
+}
+
 // CreateNetworkStatus create NetworkStatus from CNI result
 func CreateNetworkStatus(r cnitypes.Result, networkName string, defaultNetwork bool, dev *v1.DeviceInfo) (*v1.NetworkStatus, error) {
 	netStatus := &v1.NetworkStatus{}
@@ -139,6 +238,7 @@ func CreateNetworkStatus(r cnitypes.Result, networkName string, defaultNetwork b
 		if ifs.Sandbox != "" {
 			netStatus.Interface = ifs.Name
 			netStatus.Mac = ifs.Mac
+			netStatus.Mtu = ifs.Mtu
 		}
 	}
 
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 523c64b540..b785929ab3 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -1,7 +1,7 @@
 # github.com/Masterminds/goutils v1.1.1
 ## explicit
 github.com/Masterminds/goutils
-# github.com/Masterminds/semver/v3 v3.2.0
+# github.com/Masterminds/semver/v3 v3.2.1
 ## explicit; go 1.18
 github.com/Masterminds/semver/v3
 # github.com/Masterminds/sprig/v3 v3.2.3
@@ -109,10 +109,11 @@ github.com/cilium/cilium/pkg/versioncheck
 github.com/cilium/proxy/pkg/policy/api/kafka
 # github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa
 ## explicit; go 1.19
-# github.com/containernetworking/cni v1.1.2
-## explicit; go 1.14
+# github.com/containernetworking/cni v1.2.0-rc1
+## explicit; go 1.18
 github.com/containernetworking/cni/libcni
 github.com/containernetworking/cni/pkg/invoke
+github.com/containernetworking/cni/pkg/ns
 github.com/containernetworking/cni/pkg/skel
 github.com/containernetworking/cni/pkg/types
 github.com/containernetworking/cni/pkg/types/020
@@ -337,8 +338,8 @@ github.com/josharian/intern
 # github.com/json-iterator/go v1.1.12
 ## explicit; go 1.12
 github.com/json-iterator/go
-# github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.4.0
-## explicit; go 1.17
+# github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.7.5
+## explicit; go 1.21
 github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io
 github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1
 github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/utils