summaryrefslogtreecommitdiff
path: root/vendor
diff options
context:
space:
mode:
authorPaul Holzinger <pholzing@redhat.com>2021-09-17 15:39:16 +0200
committerPaul Holzinger <pholzing@redhat.com>2021-09-22 11:51:40 +0200
commitaf49810a6e08ed084294ce03e1c8a5efb8d1a705 (patch)
tree719dbe463ccfbfc54914869576b2f1bbcf4c6680 /vendor
parent8e2d25e93706190acf25bcf74bd18cdf98fb3a12 (diff)
downloadpodman-af49810a6e08ed084294ce03e1c8a5efb8d1a705.tar.gz
podman-af49810a6e08ed084294ce03e1c8a5efb8d1a705.tar.bz2
podman-af49810a6e08ed084294ce03e1c8a5efb8d1a705.zip
Bump CNI to v1.0.1
Update CNI so we can match wrapped errors. This should silence ENOENT warnings when trying to read the cni conflist files. Fixes #10926 Because CNI v1.0.0 contains breaking changes we have to change some import paths. Also we cannot update the CNI version used for the conflist files created by `podman network create` because this would require at least containernetwork-plugins v1.0.1 and a updated dnsname plugin. Because this will take a while until it lands in most distros we should not use this version. So keep using v0.4.0 for now. The update from checkpoint-restore/checkpointctl is also required to make sure it no longer uses CNI to read the network status. [NO TESTS NEEDED] Signed-off-by: Paul Holzinger <pholzing@redhat.com>
Diffstat (limited to 'vendor')
-rw-r--r--vendor/github.com/checkpoint-restore/checkpointctl/lib/metadata.go108
-rw-r--r--vendor/github.com/containernetworking/cni/libcni/api.go74
-rw-r--r--vendor/github.com/containernetworking/cni/libcni/conf.go14
-rw-r--r--vendor/github.com/containernetworking/cni/pkg/invoke/exec.go10
-rw-r--r--vendor/github.com/containernetworking/cni/pkg/types/020/types.go85
-rw-r--r--vendor/github.com/containernetworking/cni/pkg/types/040/types.go306
-rw-r--r--vendor/github.com/containernetworking/cni/pkg/types/100/types.go307
-rw-r--r--vendor/github.com/containernetworking/cni/pkg/types/args.go18
-rw-r--r--vendor/github.com/containernetworking/cni/pkg/types/create/create.go56
-rw-r--r--vendor/github.com/containernetworking/cni/pkg/types/current/types.go276
-rw-r--r--vendor/github.com/containernetworking/cni/pkg/types/internal/convert.go92
-rw-r--r--vendor/github.com/containernetworking/cni/pkg/types/internal/create.go66
-rw-r--r--vendor/github.com/containernetworking/cni/pkg/types/types.go31
-rw-r--r--vendor/github.com/containernetworking/cni/pkg/version/conf.go15
-rw-r--r--vendor/github.com/containernetworking/cni/pkg/version/plugin.go8
-rw-r--r--vendor/github.com/containernetworking/cni/pkg/version/version.go52
-rw-r--r--vendor/github.com/vishvananda/netlink/class_linux.go10
-rw-r--r--vendor/github.com/vishvananda/netlink/devlink_linux.go121
-rw-r--r--vendor/github.com/vishvananda/netlink/filter_linux.go6
-rw-r--r--vendor/github.com/vishvananda/netlink/handle_linux.go16
-rw-r--r--vendor/github.com/vishvananda/netlink/handle_unspecified.go4
-rw-r--r--vendor/github.com/vishvananda/netlink/inet_diag.go1
-rw-r--r--vendor/github.com/vishvananda/netlink/ipset_linux.go60
-rw-r--r--vendor/github.com/vishvananda/netlink/link.go195
-rw-r--r--vendor/github.com/vishvananda/netlink/link_linux.go131
-rw-r--r--vendor/github.com/vishvananda/netlink/nl/devlink_linux.go23
-rw-r--r--vendor/github.com/vishvananda/netlink/nl/link_linux.go36
-rw-r--r--vendor/github.com/vishvananda/netlink/nl/nl_linux.go11
-rw-r--r--vendor/github.com/vishvananda/netlink/nl/parse_attr_linux.go (renamed from vendor/github.com/vishvananda/netlink/nl/parse_attr.go)14
-rw-r--r--vendor/github.com/vishvananda/netlink/qdisc.go16
-rw-r--r--vendor/github.com/vishvananda/netlink/qdisc_linux.go16
-rw-r--r--vendor/github.com/vishvananda/netlink/route.go14
-rw-r--r--vendor/github.com/vishvananda/netlink/route_linux.go218
-rw-r--r--vendor/github.com/vishvananda/netlink/route_unspecified.go10
-rw-r--r--vendor/github.com/vishvananda/netlink/socket_linux.go47
-rw-r--r--vendor/github.com/vishvananda/netlink/tcp.go66
-rw-r--r--vendor/github.com/vishvananda/netlink/tcp_linux.go76
-rw-r--r--vendor/github.com/vishvananda/netlink/xfrm_policy.go13
-rw-r--r--vendor/github.com/vishvananda/netlink/xfrm_policy_linux.go2
-rw-r--r--vendor/github.com/vishvananda/netlink/xfrm_state.go4
-rw-r--r--vendor/github.com/vishvananda/netlink/xfrm_state_linux.go23
-rw-r--r--vendor/github.com/vishvananda/netns/README.md11
-rw-r--r--vendor/github.com/vishvananda/netns/netns_linux.go18
-rw-r--r--vendor/modules.txt15
44 files changed, 2125 insertions, 570 deletions
diff --git a/vendor/github.com/checkpoint-restore/checkpointctl/lib/metadata.go b/vendor/github.com/checkpoint-restore/checkpointctl/lib/metadata.go
index 1c74903ad..7c59ed23f 100644
--- a/vendor/github.com/checkpoint-restore/checkpointctl/lib/metadata.go
+++ b/vendor/github.com/checkpoint-restore/checkpointctl/lib/metadata.go
@@ -6,12 +6,10 @@ import (
"encoding/json"
"fmt"
"io/ioutil"
- "net"
"os"
"path/filepath"
"time"
- cnitypes "github.com/containernetworking/cni/pkg/types/current"
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
)
@@ -91,16 +89,73 @@ type CheckpointedPodOptions struct {
ProcessLabel string `json:"processLabel"`
}
-func DetectCheckpointArchiveType(checkpointDirectory string) (CheckpointType, error) {
- _, err := os.Stat(filepath.Join(checkpointDirectory, CheckpointedPodsFile))
+// This is metadata stored inside of Pod checkpoint archive
+type PodSandboxConfig struct {
+ Metadata SandboxMetadta `json:"metadata"`
+ Hostname string `json:"hostname"`
+}
+
+type SandboxMetadta struct {
+ Name string `json:"name"`
+ UID string `json:"uid"`
+ Namespace string `json:"namespace"`
+}
+
+func checkForFile(checkpointDirectory, file string) (bool, error) {
+ _, err := os.Stat(filepath.Join(checkpointDirectory, file))
if err != nil && !os.IsNotExist(err) {
- return Unknown, errors.Wrapf(err, "Failed to access %q\n", CheckpointedPodsFile)
+ return false, errors.Wrapf(err, "Failed to access %q\n", file)
+ }
+ if os.IsNotExist(err) {
+ return false, nil
+ }
+
+ return true, nil
+}
+
+func DetectCheckpointArchiveType(checkpointDirectory string) (CheckpointType, error) {
+ kubelet, err := checkForFile(checkpointDirectory, CheckpointedPodsFile)
+ if os.IsNotExist(err) {
+ return Unknown, err
+ }
+
+ container, err := checkForFile(checkpointDirectory, ConfigDumpFile)
+ if os.IsNotExist(err) {
+ return Unknown, err
}
+
+ pod, err := checkForFile(checkpointDirectory, PodDumpFile)
if os.IsNotExist(err) {
+ return Unknown, err
+ }
+
+ if pod && !container && !kubelet {
+ return Pod, nil
+ }
+
+ if !pod && container && !kubelet {
return Container, nil
}
- return Kubelet, nil
+ if !pod && !container && kubelet {
+ return Kubelet, nil
+ }
+
+ return Unknown, nil
+}
+
+func ReadPodCheckpointDumpFile(checkpointDirectory string) (*PodSandboxConfig, string, error) {
+ var podSandboxConfig PodSandboxConfig
+ podDumpFile, err := ReadJSONFile(&podSandboxConfig, checkpointDirectory, PodDumpFile)
+
+ return &podSandboxConfig, podDumpFile, err
+}
+
+func ReadPodCheckpointOptionsFile(checkpointDirectory string) (*CheckpointedPodOptions, string, error) {
+ var checkpointedPodOptions CheckpointedPodOptions
+ podOptionsFile, err := ReadJSONFile(&checkpointedPodOptions, checkpointDirectory, PodOptionsFile)
+
+ return &checkpointedPodOptions, podOptionsFile, err
}
func ReadContainerCheckpointSpecDump(checkpointDirectory string) (*spec.Spec, string, error) {
@@ -124,13 +179,6 @@ func ReadContainerCheckpointDeletedFiles(checkpointDirectory string) ([]string,
return deletedFiles, deletedFilesFile, err
}
-func ReadContainerCheckpointNetworkStatus(checkpointDirectory string) ([]*cnitypes.Result, string, error) {
- var networkStatus []*cnitypes.Result
- networkStatusFile, err := ReadJSONFile(&networkStatus, checkpointDirectory, NetworkStatusFile)
-
- return networkStatus, networkStatusFile, err
-}
-
func ReadKubeletCheckpoints(checkpointsDirectory string) (*CheckpointMetadata, string, error) {
var checkpointMetadata CheckpointMetadata
checkpointMetadataPath, err := ReadJSONFile(&checkpointMetadata, checkpointsDirectory, CheckpointedPodsFile)
@@ -138,40 +186,6 @@ func ReadKubeletCheckpoints(checkpointsDirectory string) (*CheckpointMetadata, s
return &checkpointMetadata, checkpointMetadataPath, err
}
-func GetIPFromNetworkStatus(networkStatus []*cnitypes.Result) net.IP {
- if len(networkStatus) == 0 {
- return nil
- }
- // Take the first IP address
- if len(networkStatus[0].IPs) == 0 {
- return nil
- }
- IP := networkStatus[0].IPs[0].Address.IP
-
- return IP
-}
-
-func GetMACFromNetworkStatus(networkStatus []*cnitypes.Result) net.HardwareAddr {
- if len(networkStatus) == 0 {
- return nil
- }
- // Take the first device with a defined sandbox
- if len(networkStatus[0].Interfaces) == 0 {
- return nil
- }
- var MAC net.HardwareAddr
- MAC = nil
- for _, n := range networkStatus[0].Interfaces {
- if n.Sandbox != "" {
- MAC, _ = net.ParseMAC(n.Mac)
-
- break
- }
- }
-
- return MAC
-}
-
// WriteJSONFile marshalls and writes the given data to a JSON file
func WriteJSONFile(v interface{}, dir, file string) (string, error) {
fileJSON, err := json.MarshalIndent(v, "", " ")
diff --git a/vendor/github.com/containernetworking/cni/libcni/api.go b/vendor/github.com/containernetworking/cni/libcni/api.go
index 7e52bd838..0d82a2dd3 100644
--- a/vendor/github.com/containernetworking/cni/libcni/api.go
+++ b/vendor/github.com/containernetworking/cni/libcni/api.go
@@ -14,6 +14,12 @@
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
+// 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.
+
import (
"context"
"encoding/json"
@@ -25,6 +31,7 @@ import (
"github.com/containernetworking/cni/pkg/invoke"
"github.com/containernetworking/cni/pkg/types"
+ "github.com/containernetworking/cni/pkg/types/create"
"github.com/containernetworking/cni/pkg/utils"
"github.com/containernetworking/cni/pkg/version"
)
@@ -278,7 +285,7 @@ func (c *CNIConfig) getCachedConfig(netName string, rt *RuntimeConf) ([]byte, *R
unmarshaled := cachedInfo{}
if err := json.Unmarshal(bytes, &unmarshaled); err != nil {
- return nil, nil, fmt.Errorf("failed to unmarshal cached network %q config: %v", netName, err)
+ return nil, nil, fmt.Errorf("failed to unmarshal cached network %q config: %w", netName, err)
}
if unmarshaled.Kind != CNICacheV1 {
return nil, nil, fmt.Errorf("read cached network %q config has wrong kind: %v", netName, unmarshaled.Kind)
@@ -304,15 +311,8 @@ func (c *CNIConfig) getLegacyCachedResult(netName, cniVersion string, rt *Runtim
return nil, nil
}
- // Read the version of the cached result
- decoder := version.ConfigDecoder{}
- resultCniVersion, err := decoder.Decode(data)
- if err != nil {
- return nil, err
- }
-
- // Ensure we can understand the result
- result, err := version.NewResult(resultCniVersion, data)
+ // Load the cached result
+ result, err := create.CreateFromBytes(data)
if err != nil {
return nil, err
}
@@ -322,10 +322,10 @@ func (c *CNIConfig) getLegacyCachedResult(netName, cniVersion string, rt *Runtim
// should match the config version unless the config was changed
// while the container was running.
result, err = result.GetAsVersion(cniVersion)
- if err != nil && resultCniVersion != cniVersion {
- return nil, fmt.Errorf("failed to convert cached result version %q to config version %q: %v", resultCniVersion, cniVersion, err)
+ if err != nil {
+ return nil, fmt.Errorf("failed to convert cached result to config version %q: %w", cniVersion, err)
}
- return result, err
+ return result, nil
}
func (c *CNIConfig) getCachedResult(netName, cniVersion string, rt *RuntimeConf) (types.Result, error) {
@@ -346,18 +346,11 @@ func (c *CNIConfig) getCachedResult(netName, cniVersion string, rt *RuntimeConf)
newBytes, err := json.Marshal(&cachedInfo.RawResult)
if err != nil {
- return nil, fmt.Errorf("failed to marshal cached network %q config: %v", netName, err)
+ return nil, fmt.Errorf("failed to marshal cached network %q config: %w", netName, err)
}
- // Read the version of the cached result
- decoder := version.ConfigDecoder{}
- resultCniVersion, err := decoder.Decode(newBytes)
- if err != nil {
- return nil, err
- }
-
- // Ensure we can understand the result
- result, err := version.NewResult(resultCniVersion, newBytes)
+ // Load the cached result
+ result, err := create.CreateFromBytes(newBytes)
if err != nil {
return nil, err
}
@@ -367,10 +360,10 @@ func (c *CNIConfig) getCachedResult(netName, cniVersion string, rt *RuntimeConf)
// should match the config version unless the config was changed
// while the container was running.
result, err = result.GetAsVersion(cniVersion)
- if err != nil && resultCniVersion != cniVersion {
- return nil, fmt.Errorf("failed to convert cached result version %q to config version %q: %v", resultCniVersion, cniVersion, err)
+ if err != nil {
+ return nil, fmt.Errorf("failed to convert cached result to config version %q: %w", cniVersion, err)
}
- return result, err
+ return result, nil
}
// GetNetworkListCachedResult returns the cached Result of the previous
@@ -428,12 +421,12 @@ func (c *CNIConfig) AddNetworkList(ctx context.Context, list *NetworkConfigList,
for _, net := range list.Plugins {
result, err = c.addNetwork(ctx, list.Name, list.CNIVersion, net, result, rt)
if err != nil {
- return nil, err
+ return nil, fmt.Errorf("plugin %s failed (add): %w", pluginDescription(net.Network), err)
}
}
if err = c.cacheAdd(result, list.Bytes, list.Name, rt); err != nil {
- return nil, fmt.Errorf("failed to set network %q cached result: %v", list.Name, err)
+ return nil, fmt.Errorf("failed to set network %q cached result: %w", list.Name, err)
}
return result, nil
@@ -469,7 +462,7 @@ func (c *CNIConfig) CheckNetworkList(ctx context.Context, list *NetworkConfigLis
cachedResult, err := c.getCachedResult(list.Name, list.CNIVersion, rt)
if err != nil {
- return fmt.Errorf("failed to get network %q cached result: %v", list.Name, err)
+ return fmt.Errorf("failed to get network %q cached result: %w", list.Name, err)
}
for _, net := range list.Plugins {
@@ -506,14 +499,14 @@ func (c *CNIConfig) DelNetworkList(ctx context.Context, list *NetworkConfigList,
} 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: %v", list.Name, err)
+ return fmt.Errorf("failed to get network %q cached result: %w", list.Name, err)
}
}
for i := len(list.Plugins) - 1; i >= 0; i-- {
net := list.Plugins[i]
if err := c.delNetwork(ctx, list.Name, list.CNIVersion, net, cachedResult, rt); err != nil {
- return err
+ return fmt.Errorf("plugin %s failed (delete): %w", pluginDescription(net.Network), err)
}
}
_ = c.cacheDel(list.Name, rt)
@@ -521,6 +514,19 @@ func (c *CNIConfig) DelNetworkList(ctx context.Context, list *NetworkConfigList,
return nil
}
+func pluginDescription(net *types.NetConf) string {
+ if net == nil {
+ return "<missing>"
+ }
+ pluginType := net.Type
+ out := fmt.Sprintf("type=%q", pluginType)
+ name := net.Name
+ if name != "" {
+ out += fmt.Sprintf(" name=%q", name)
+ }
+ return out
+}
+
// AddNetwork executes the plugin with the ADD command
func (c *CNIConfig) AddNetwork(ctx context.Context, net *NetworkConfig, rt *RuntimeConf) (types.Result, error) {
result, err := c.addNetwork(ctx, net.Network.Name, net.Network.CNIVersion, net, nil, rt)
@@ -529,7 +535,7 @@ func (c *CNIConfig) AddNetwork(ctx context.Context, net *NetworkConfig, rt *Runt
}
if err = c.cacheAdd(result, net.Bytes, net.Network.Name, rt); err != nil {
- return nil, fmt.Errorf("failed to set network %q cached result: %v", net.Network.Name, err)
+ return nil, fmt.Errorf("failed to set network %q cached result: %w", net.Network.Name, err)
}
return result, nil
@@ -546,7 +552,7 @@ func (c *CNIConfig) CheckNetwork(ctx context.Context, net *NetworkConfig, rt *Ru
cachedResult, err := c.getCachedResult(net.Network.Name, net.Network.CNIVersion, rt)
if err != nil {
- return fmt.Errorf("failed to get network %q cached result: %v", net.Network.Name, err)
+ return fmt.Errorf("failed to get network %q cached result: %w", net.Network.Name, err)
}
return c.checkNetwork(ctx, net.Network.Name, net.Network.CNIVersion, net, cachedResult, rt)
}
@@ -561,7 +567,7 @@ func (c *CNIConfig) DelNetwork(ctx context.Context, net *NetworkConfig, rt *Runt
} 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: %v", net.Network.Name, err)
+ return fmt.Errorf("failed to get network %q cached result: %w", net.Network.Name, err)
}
}
diff --git a/vendor/github.com/containernetworking/cni/libcni/conf.go b/vendor/github.com/containernetworking/cni/libcni/conf.go
index d8920cf8c..d28135ff3 100644
--- a/vendor/github.com/containernetworking/cni/libcni/conf.go
+++ b/vendor/github.com/containernetworking/cni/libcni/conf.go
@@ -43,7 +43,7 @@ func (e NoConfigsFoundError) Error() string {
func ConfFromBytes(bytes []byte) (*NetworkConfig, error) {
conf := &NetworkConfig{Bytes: bytes}
if err := json.Unmarshal(bytes, &conf.Network); err != nil {
- return nil, fmt.Errorf("error parsing configuration: %s", err)
+ return nil, fmt.Errorf("error parsing configuration: %w", err)
}
if conf.Network.Type == "" {
return nil, fmt.Errorf("error parsing configuration: missing 'type'")
@@ -54,7 +54,7 @@ func ConfFromBytes(bytes []byte) (*NetworkConfig, error) {
func ConfFromFile(filename string) (*NetworkConfig, error) {
bytes, err := ioutil.ReadFile(filename)
if err != nil {
- return nil, fmt.Errorf("error reading %s: %s", filename, err)
+ return nil, fmt.Errorf("error reading %s: %w", filename, err)
}
return ConfFromBytes(bytes)
}
@@ -62,7 +62,7 @@ func ConfFromFile(filename string) (*NetworkConfig, error) {
func ConfListFromBytes(bytes []byte) (*NetworkConfigList, error) {
rawList := make(map[string]interface{})
if err := json.Unmarshal(bytes, &rawList); err != nil {
- return nil, fmt.Errorf("error parsing configuration list: %s", err)
+ return nil, fmt.Errorf("error parsing configuration list: %w", err)
}
rawName, ok := rawList["name"]
@@ -114,11 +114,11 @@ func ConfListFromBytes(bytes []byte) (*NetworkConfigList, error) {
for i, conf := range plugins {
newBytes, err := json.Marshal(conf)
if err != nil {
- return nil, fmt.Errorf("failed to marshal plugin config %d: %v", i, err)
+ return nil, fmt.Errorf("failed to marshal plugin config %d: %w", i, err)
}
netConf, err := ConfFromBytes(newBytes)
if err != nil {
- return nil, fmt.Errorf("failed to parse plugin config %d: %v", i, err)
+ return nil, fmt.Errorf("failed to parse plugin config %d: %w", i, err)
}
list.Plugins = append(list.Plugins, netConf)
}
@@ -129,7 +129,7 @@ func ConfListFromBytes(bytes []byte) (*NetworkConfigList, error) {
func ConfListFromFile(filename string) (*NetworkConfigList, error) {
bytes, err := ioutil.ReadFile(filename)
if err != nil {
- return nil, fmt.Errorf("error reading %s: %s", filename, err)
+ return nil, fmt.Errorf("error reading %s: %w", filename, err)
}
return ConfListFromBytes(bytes)
}
@@ -218,7 +218,7 @@ func InjectConf(original *NetworkConfig, newValues map[string]interface{}) (*Net
config := make(map[string]interface{})
err := json.Unmarshal(original.Bytes, &config)
if err != nil {
- return nil, fmt.Errorf("unmarshal existing network bytes: %s", err)
+ return nil, fmt.Errorf("unmarshal existing network bytes: %w", err)
}
for key, value := range newValues {
diff --git a/vendor/github.com/containernetworking/cni/pkg/invoke/exec.go b/vendor/github.com/containernetworking/cni/pkg/invoke/exec.go
index 8e6d30b82..e79bffe63 100644
--- a/vendor/github.com/containernetworking/cni/pkg/invoke/exec.go
+++ b/vendor/github.com/containernetworking/cni/pkg/invoke/exec.go
@@ -20,6 +20,7 @@ import (
"os"
"github.com/containernetworking/cni/pkg/types"
+ "github.com/containernetworking/cni/pkg/types/create"
"github.com/containernetworking/cni/pkg/version"
)
@@ -83,14 +84,7 @@ func ExecPluginWithResult(ctx context.Context, pluginPath string, netconf []byte
return nil, err
}
- // Plugin must return result in same version as specified in netconf
- versionDecoder := &version.ConfigDecoder{}
- confVersion, err := versionDecoder.Decode(netconf)
- if err != nil {
- return nil, err
- }
-
- return version.NewResult(confVersion, stdoutBytes)
+ return create.CreateFromBytes(stdoutBytes)
}
func ExecPluginWithoutResult(ctx context.Context, pluginPath string, netconf []byte, args CNIArgs, exec Exec) error {
diff --git a/vendor/github.com/containernetworking/cni/pkg/types/020/types.go b/vendor/github.com/containernetworking/cni/pkg/types/020/types.go
index 36f31678a..99b151ff2 100644
--- a/vendor/github.com/containernetworking/cni/pkg/types/020/types.go
+++ b/vendor/github.com/containernetworking/cni/pkg/types/020/types.go
@@ -22,25 +22,47 @@ import (
"os"
"github.com/containernetworking/cni/pkg/types"
+ convert "github.com/containernetworking/cni/pkg/types/internal"
)
const ImplementedSpecVersion string = "0.2.0"
-var SupportedVersions = []string{"", "0.1.0", ImplementedSpecVersion}
+var supportedVersions = []string{"", "0.1.0", ImplementedSpecVersion}
+
+// Register converters for all versions less than the implemented spec version
+func init() {
+ convert.RegisterConverter("0.1.0", []string{ImplementedSpecVersion}, convertFrom010)
+ convert.RegisterConverter(ImplementedSpecVersion, []string{"0.1.0"}, convertTo010)
+
+ // Creator
+ convert.RegisterCreator(supportedVersions, NewResult)
+}
// Compatibility types for CNI version 0.1.0 and 0.2.0
+// NewResult creates a new Result object from JSON data. The JSON data
+// must be compatible with the CNI versions implemented by this type.
func NewResult(data []byte) (types.Result, error) {
result := &Result{}
if err := json.Unmarshal(data, result); err != nil {
return nil, err
}
- return result, nil
+ for _, v := range supportedVersions {
+ if result.CNIVersion == v {
+ if result.CNIVersion == "" {
+ result.CNIVersion = "0.1.0"
+ }
+ return result, nil
+ }
+ }
+ return nil, fmt.Errorf("result type supports %v but unmarshalled CNIVersion is %q",
+ supportedVersions, result.CNIVersion)
}
+// GetResult converts the given Result object to the ImplementedSpecVersion
+// and returns the concrete type or an error
func GetResult(r types.Result) (*Result, error) {
- // We expect version 0.1.0/0.2.0 results
- result020, err := r.GetAsVersion(ImplementedSpecVersion)
+ result020, err := convert.Convert(r, ImplementedSpecVersion)
if err != nil {
return nil, err
}
@@ -51,6 +73,32 @@ func GetResult(r types.Result) (*Result, error) {
return result, nil
}
+func convertFrom010(from types.Result, toVersion string) (types.Result, error) {
+ if toVersion != "0.2.0" {
+ panic("only converts to version 0.2.0")
+ }
+ fromResult := from.(*Result)
+ return &Result{
+ CNIVersion: ImplementedSpecVersion,
+ IP4: fromResult.IP4.Copy(),
+ IP6: fromResult.IP6.Copy(),
+ DNS: *fromResult.DNS.Copy(),
+ }, nil
+}
+
+func convertTo010(from types.Result, toVersion string) (types.Result, error) {
+ if toVersion != "0.1.0" {
+ panic("only converts to version 0.1.0")
+ }
+ fromResult := from.(*Result)
+ return &Result{
+ CNIVersion: "0.1.0",
+ IP4: fromResult.IP4.Copy(),
+ IP6: fromResult.IP6.Copy(),
+ DNS: *fromResult.DNS.Copy(),
+ }, nil
+}
+
// Result is what gets returned from the plugin (via stdout) to the caller
type Result struct {
CNIVersion string `json:"cniVersion,omitempty"`
@@ -60,17 +108,16 @@ type Result struct {
}
func (r *Result) Version() string {
- return ImplementedSpecVersion
+ return r.CNIVersion
}
func (r *Result) GetAsVersion(version string) (types.Result, error) {
- for _, supportedVersion := range SupportedVersions {
- if version == supportedVersion {
- r.CNIVersion = version
- return r, nil
- }
+ // If the creator of the result did not set the CNIVersion, assume it
+ // should be the highest spec version implemented by this Result
+ if r.CNIVersion == "" {
+ r.CNIVersion = ImplementedSpecVersion
}
- return nil, fmt.Errorf("cannot convert version %q to %s", SupportedVersions, version)
+ return convert.Convert(r, version)
}
func (r *Result) Print() error {
@@ -93,6 +140,22 @@ type IPConfig struct {
Routes []types.Route
}
+func (i *IPConfig) Copy() *IPConfig {
+ if i == nil {
+ return nil
+ }
+
+ var routes []types.Route
+ for _, fromRoute := range i.Routes {
+ routes = append(routes, *fromRoute.Copy())
+ }
+ return &IPConfig{
+ IP: i.IP,
+ Gateway: i.Gateway,
+ Routes: routes,
+ }
+}
+
// net.IPNet is not JSON (un)marshallable so this duality is needed
// for our custom IPNet type
diff --git a/vendor/github.com/containernetworking/cni/pkg/types/040/types.go b/vendor/github.com/containernetworking/cni/pkg/types/040/types.go
new file mode 100644
index 000000000..3633b0eaa
--- /dev/null
+++ b/vendor/github.com/containernetworking/cni/pkg/types/040/types.go
@@ -0,0 +1,306 @@
+// Copyright 2016 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 types040
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "net"
+ "os"
+
+ "github.com/containernetworking/cni/pkg/types"
+ types020 "github.com/containernetworking/cni/pkg/types/020"
+ convert "github.com/containernetworking/cni/pkg/types/internal"
+)
+
+const ImplementedSpecVersion string = "0.4.0"
+
+var supportedVersions = []string{"0.3.0", "0.3.1", ImplementedSpecVersion}
+
+// Register converters for all versions less than the implemented spec version
+func init() {
+ // Up-converters
+ convert.RegisterConverter("0.1.0", supportedVersions, convertFrom02x)
+ convert.RegisterConverter("0.2.0", supportedVersions, convertFrom02x)
+ convert.RegisterConverter("0.3.0", supportedVersions, convertInternal)
+ convert.RegisterConverter("0.3.1", supportedVersions, convertInternal)
+
+ // Down-converters
+ convert.RegisterConverter("0.4.0", []string{"0.3.0", "0.3.1"}, convertInternal)
+ convert.RegisterConverter("0.4.0", []string{"0.1.0", "0.2.0"}, convertTo02x)
+ convert.RegisterConverter("0.3.1", []string{"0.1.0", "0.2.0"}, convertTo02x)
+ convert.RegisterConverter("0.3.0", []string{"0.1.0", "0.2.0"}, convertTo02x)
+
+ // Creator
+ convert.RegisterCreator(supportedVersions, NewResult)
+}
+
+func NewResult(data []byte) (types.Result, error) {
+ result := &Result{}
+ if err := json.Unmarshal(data, result); err != nil {
+ return nil, err
+ }
+ for _, v := range supportedVersions {
+ if result.CNIVersion == v {
+ return result, nil
+ }
+ }
+ return nil, fmt.Errorf("result type supports %v but unmarshalled CNIVersion is %q",
+ supportedVersions, result.CNIVersion)
+}
+
+func GetResult(r types.Result) (*Result, error) {
+ resultCurrent, err := r.GetAsVersion(ImplementedSpecVersion)
+ if err != nil {
+ return nil, err
+ }
+ result, ok := resultCurrent.(*Result)
+ if !ok {
+ return nil, fmt.Errorf("failed to convert result")
+ }
+ return result, nil
+}
+
+func NewResultFromResult(result types.Result) (*Result, error) {
+ newResult, err := convert.Convert(result, ImplementedSpecVersion)
+ if err != nil {
+ return nil, err
+ }
+ return newResult.(*Result), nil
+}
+
+// Result is what gets returned from the plugin (via stdout) to the caller
+type Result struct {
+ CNIVersion string `json:"cniVersion,omitempty"`
+ Interfaces []*Interface `json:"interfaces,omitempty"`
+ IPs []*IPConfig `json:"ips,omitempty"`
+ Routes []*types.Route `json:"routes,omitempty"`
+ DNS types.DNS `json:"dns,omitempty"`
+}
+
+func convert020IPConfig(from *types020.IPConfig, ipVersion string) *IPConfig {
+ return &IPConfig{
+ Version: ipVersion,
+ Address: from.IP,
+ Gateway: from.Gateway,
+ }
+}
+
+func convertFrom02x(from types.Result, toVersion string) (types.Result, error) {
+ fromResult := from.(*types020.Result)
+ toResult := &Result{
+ CNIVersion: toVersion,
+ DNS: *fromResult.DNS.Copy(),
+ Routes: []*types.Route{},
+ }
+ if fromResult.IP4 != nil {
+ toResult.IPs = append(toResult.IPs, convert020IPConfig(fromResult.IP4, "4"))
+ for _, fromRoute := range fromResult.IP4.Routes {
+ toResult.Routes = append(toResult.Routes, fromRoute.Copy())
+ }
+ }
+
+ if fromResult.IP6 != nil {
+ toResult.IPs = append(toResult.IPs, convert020IPConfig(fromResult.IP6, "6"))
+ for _, fromRoute := range fromResult.IP6.Routes {
+ toResult.Routes = append(toResult.Routes, fromRoute.Copy())
+ }
+ }
+
+ return toResult, nil
+}
+
+func convertInternal(from types.Result, toVersion string) (types.Result, error) {
+ fromResult := from.(*Result)
+ toResult := &Result{
+ CNIVersion: toVersion,
+ DNS: *fromResult.DNS.Copy(),
+ Routes: []*types.Route{},
+ }
+ for _, fromIntf := range fromResult.Interfaces {
+ toResult.Interfaces = append(toResult.Interfaces, fromIntf.Copy())
+ }
+ for _, fromIPC := range fromResult.IPs {
+ toResult.IPs = append(toResult.IPs, fromIPC.Copy())
+ }
+ for _, fromRoute := range fromResult.Routes {
+ toResult.Routes = append(toResult.Routes, fromRoute.Copy())
+ }
+ return toResult, nil
+}
+
+func convertTo02x(from types.Result, toVersion string) (types.Result, error) {
+ fromResult := from.(*Result)
+ toResult := &types020.Result{
+ CNIVersion: toVersion,
+ DNS: *fromResult.DNS.Copy(),
+ }
+
+ for _, fromIP := range fromResult.IPs {
+ // Only convert the first IP address of each version as 0.2.0
+ // and earlier cannot handle multiple IP addresses
+ if fromIP.Version == "4" && toResult.IP4 == nil {
+ toResult.IP4 = &types020.IPConfig{
+ IP: fromIP.Address,
+ Gateway: fromIP.Gateway,
+ }
+ } else if fromIP.Version == "6" && toResult.IP6 == nil {
+ toResult.IP6 = &types020.IPConfig{
+ IP: fromIP.Address,
+ Gateway: fromIP.Gateway,
+ }
+ }
+ if toResult.IP4 != nil && toResult.IP6 != nil {
+ break
+ }
+ }
+
+ for _, fromRoute := range fromResult.Routes {
+ is4 := fromRoute.Dst.IP.To4() != nil
+ if is4 && toResult.IP4 != nil {
+ toResult.IP4.Routes = append(toResult.IP4.Routes, types.Route{
+ Dst: fromRoute.Dst,
+ GW: fromRoute.GW,
+ })
+ } else if !is4 && toResult.IP6 != nil {
+ toResult.IP6.Routes = append(toResult.IP6.Routes, types.Route{
+ Dst: fromRoute.Dst,
+ GW: fromRoute.GW,
+ })
+ }
+ }
+
+ // 0.2.0 and earlier require at least one IP address in the Result
+ if toResult.IP4 == nil && toResult.IP6 == nil {
+ return nil, fmt.Errorf("cannot convert: no valid IP addresses")
+ }
+
+ return toResult, nil
+}
+
+func (r *Result) Version() string {
+ return r.CNIVersion
+}
+
+func (r *Result) GetAsVersion(version string) (types.Result, error) {
+ // If the creator of the result did not set the CNIVersion, assume it
+ // should be the highest spec version implemented by this Result
+ if r.CNIVersion == "" {
+ r.CNIVersion = ImplementedSpecVersion
+ }
+ return convert.Convert(r, version)
+}
+
+func (r *Result) Print() error {
+ return r.PrintTo(os.Stdout)
+}
+
+func (r *Result) PrintTo(writer io.Writer) error {
+ data, err := json.MarshalIndent(r, "", " ")
+ if err != nil {
+ return err
+ }
+ _, err = writer.Write(data)
+ return err
+}
+
+// Interface contains values about the created interfaces
+type Interface struct {
+ Name string `json:"name"`
+ Mac string `json:"mac,omitempty"`
+ Sandbox string `json:"sandbox,omitempty"`
+}
+
+func (i *Interface) String() string {
+ return fmt.Sprintf("%+v", *i)
+}
+
+func (i *Interface) Copy() *Interface {
+ if i == nil {
+ return nil
+ }
+ newIntf := *i
+ return &newIntf
+}
+
+// Int returns a pointer to the int value passed in. Used to
+// set the IPConfig.Interface field.
+func Int(v int) *int {
+ return &v
+}
+
+// IPConfig contains values necessary to configure an IP address on an interface
+type IPConfig struct {
+ // IP version, either "4" or "6"
+ Version string
+ // Index into Result structs Interfaces list
+ Interface *int
+ Address net.IPNet
+ Gateway net.IP
+}
+
+func (i *IPConfig) String() string {
+ return fmt.Sprintf("%+v", *i)
+}
+
+func (i *IPConfig) Copy() *IPConfig {
+ if i == nil {
+ return nil
+ }
+
+ ipc := &IPConfig{
+ Version: i.Version,
+ Address: i.Address,
+ Gateway: i.Gateway,
+ }
+ if i.Interface != nil {
+ intf := *i.Interface
+ ipc.Interface = &intf
+ }
+ return ipc
+}
+
+// JSON (un)marshallable types
+type ipConfig struct {
+ Version string `json:"version"`
+ Interface *int `json:"interface,omitempty"`
+ Address types.IPNet `json:"address"`
+ Gateway net.IP `json:"gateway,omitempty"`
+}
+
+func (c *IPConfig) MarshalJSON() ([]byte, error) {
+ ipc := ipConfig{
+ Version: c.Version,
+ Interface: c.Interface,
+ Address: types.IPNet(c.Address),
+ Gateway: c.Gateway,
+ }
+
+ return json.Marshal(ipc)
+}
+
+func (c *IPConfig) UnmarshalJSON(data []byte) error {
+ ipc := ipConfig{}
+ if err := json.Unmarshal(data, &ipc); err != nil {
+ return err
+ }
+
+ c.Version = ipc.Version
+ c.Interface = ipc.Interface
+ c.Address = net.IPNet(ipc.Address)
+ c.Gateway = ipc.Gateway
+ return 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
new file mode 100644
index 000000000..0e1e8b857
--- /dev/null
+++ b/vendor/github.com/containernetworking/cni/pkg/types/100/types.go
@@ -0,0 +1,307 @@
+// Copyright 2016 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 types100
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "net"
+ "os"
+
+ "github.com/containernetworking/cni/pkg/types"
+ types040 "github.com/containernetworking/cni/pkg/types/040"
+ convert "github.com/containernetworking/cni/pkg/types/internal"
+)
+
+const ImplementedSpecVersion string = "1.0.0"
+
+var supportedVersions = []string{ImplementedSpecVersion}
+
+// Register converters for all versions less than the implemented spec version
+func init() {
+ // Up-converters
+ convert.RegisterConverter("0.1.0", supportedVersions, convertFrom02x)
+ convert.RegisterConverter("0.2.0", supportedVersions, convertFrom02x)
+ convert.RegisterConverter("0.3.0", supportedVersions, convertFrom04x)
+ convert.RegisterConverter("0.3.1", supportedVersions, convertFrom04x)
+ convert.RegisterConverter("0.4.0", supportedVersions, convertFrom04x)
+
+ // 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)
+
+ // Creator
+ convert.RegisterCreator(supportedVersions, NewResult)
+}
+
+func NewResult(data []byte) (types.Result, error) {
+ result := &Result{}
+ if err := json.Unmarshal(data, result); err != nil {
+ return nil, err
+ }
+ for _, v := range supportedVersions {
+ if result.CNIVersion == v {
+ return result, nil
+ }
+ }
+ return nil, fmt.Errorf("result type supports %v but unmarshalled CNIVersion is %q",
+ supportedVersions, result.CNIVersion)
+}
+
+func GetResult(r types.Result) (*Result, error) {
+ resultCurrent, err := r.GetAsVersion(ImplementedSpecVersion)
+ if err != nil {
+ return nil, err
+ }
+ result, ok := resultCurrent.(*Result)
+ if !ok {
+ return nil, fmt.Errorf("failed to convert result")
+ }
+ return result, nil
+}
+
+func NewResultFromResult(result types.Result) (*Result, error) {
+ newResult, err := convert.Convert(result, ImplementedSpecVersion)
+ if err != nil {
+ return nil, err
+ }
+ return newResult.(*Result), nil
+}
+
+// Result is what gets returned from the plugin (via stdout) to the caller
+type Result struct {
+ CNIVersion string `json:"cniVersion,omitempty"`
+ Interfaces []*Interface `json:"interfaces,omitempty"`
+ IPs []*IPConfig `json:"ips,omitempty"`
+ Routes []*types.Route `json:"routes,omitempty"`
+ DNS types.DNS `json:"dns,omitempty"`
+}
+
+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)
+ if err != nil {
+ return nil, err
+ }
+ return result100, nil
+}
+
+func convertIPConfigFrom040(from *types040.IPConfig) *IPConfig {
+ to := &IPConfig{
+ Address: from.Address,
+ Gateway: from.Gateway,
+ }
+ if from.Interface != nil {
+ intf := *from.Interface
+ to.Interface = &intf
+ }
+ return to
+}
+
+func convertInterfaceFrom040(from *types040.Interface) *Interface {
+ return &Interface{
+ Name: from.Name,
+ Mac: from.Mac,
+ Sandbox: from.Sandbox,
+ }
+}
+
+func convertFrom04x(from types.Result, toVersion string) (types.Result, error) {
+ fromResult := from.(*types040.Result)
+ toResult := &Result{
+ CNIVersion: toVersion,
+ DNS: *fromResult.DNS.Copy(),
+ Routes: []*types.Route{},
+ }
+ for _, fromIntf := range fromResult.Interfaces {
+ toResult.Interfaces = append(toResult.Interfaces, convertInterfaceFrom040(fromIntf))
+ }
+ for _, fromIPC := range fromResult.IPs {
+ toResult.IPs = append(toResult.IPs, convertIPConfigFrom040(fromIPC))
+ }
+ for _, fromRoute := range fromResult.Routes {
+ toResult.Routes = append(toResult.Routes, fromRoute.Copy())
+ }
+ return toResult, nil
+}
+
+func convertIPConfigTo040(from *IPConfig) *types040.IPConfig {
+ version := "6"
+ if from.Address.IP.To4() != nil {
+ version = "4"
+ }
+ to := &types040.IPConfig{
+ Version: version,
+ Address: from.Address,
+ Gateway: from.Gateway,
+ }
+ if from.Interface != nil {
+ intf := *from.Interface
+ to.Interface = &intf
+ }
+ return to
+}
+
+func convertInterfaceTo040(from *Interface) *types040.Interface {
+ return &types040.Interface{
+ Name: from.Name,
+ Mac: from.Mac,
+ Sandbox: from.Sandbox,
+ }
+}
+
+func convertTo04x(from types.Result, toVersion string) (types.Result, error) {
+ fromResult := from.(*Result)
+ toResult := &types040.Result{
+ CNIVersion: toVersion,
+ DNS: *fromResult.DNS.Copy(),
+ Routes: []*types.Route{},
+ }
+ for _, fromIntf := range fromResult.Interfaces {
+ toResult.Interfaces = append(toResult.Interfaces, convertInterfaceTo040(fromIntf))
+ }
+ for _, fromIPC := range fromResult.IPs {
+ toResult.IPs = append(toResult.IPs, convertIPConfigTo040(fromIPC))
+ }
+ for _, fromRoute := range fromResult.Routes {
+ toResult.Routes = append(toResult.Routes, fromRoute.Copy())
+ }
+ return toResult, nil
+}
+
+func convertTo02x(from types.Result, toVersion string) (types.Result, error) {
+ // First convert to 0.4.0
+ result040, err := convertTo04x(from, "0.4.0")
+ if err != nil {
+ return nil, err
+ }
+ result02x, err := convert.Convert(result040, toVersion)
+ if err != nil {
+ return nil, err
+ }
+ return result02x, nil
+}
+
+func (r *Result) Version() string {
+ return r.CNIVersion
+}
+
+func (r *Result) GetAsVersion(version string) (types.Result, error) {
+ // If the creator of the result did not set the CNIVersion, assume it
+ // should be the highest spec version implemented by this Result
+ if r.CNIVersion == "" {
+ r.CNIVersion = ImplementedSpecVersion
+ }
+ return convert.Convert(r, version)
+}
+
+func (r *Result) Print() error {
+ return r.PrintTo(os.Stdout)
+}
+
+func (r *Result) PrintTo(writer io.Writer) error {
+ data, err := json.MarshalIndent(r, "", " ")
+ if err != nil {
+ return err
+ }
+ _, err = writer.Write(data)
+ return err
+}
+
+// Interface contains values about the created interfaces
+type Interface struct {
+ Name string `json:"name"`
+ Mac string `json:"mac,omitempty"`
+ Sandbox string `json:"sandbox,omitempty"`
+}
+
+func (i *Interface) String() string {
+ return fmt.Sprintf("%+v", *i)
+}
+
+func (i *Interface) Copy() *Interface {
+ if i == nil {
+ return nil
+ }
+ newIntf := *i
+ return &newIntf
+}
+
+// Int returns a pointer to the int value passed in. Used to
+// set the IPConfig.Interface field.
+func Int(v int) *int {
+ return &v
+}
+
+// IPConfig contains values necessary to configure an IP address on an interface
+type IPConfig struct {
+ // Index into Result structs Interfaces list
+ Interface *int
+ Address net.IPNet
+ Gateway net.IP
+}
+
+func (i *IPConfig) String() string {
+ return fmt.Sprintf("%+v", *i)
+}
+
+func (i *IPConfig) Copy() *IPConfig {
+ if i == nil {
+ return nil
+ }
+
+ ipc := &IPConfig{
+ Address: i.Address,
+ Gateway: i.Gateway,
+ }
+ if i.Interface != nil {
+ intf := *i.Interface
+ ipc.Interface = &intf
+ }
+ return ipc
+}
+
+// JSON (un)marshallable types
+type ipConfig struct {
+ Interface *int `json:"interface,omitempty"`
+ Address types.IPNet `json:"address"`
+ Gateway net.IP `json:"gateway,omitempty"`
+}
+
+func (c *IPConfig) MarshalJSON() ([]byte, error) {
+ ipc := ipConfig{
+ Interface: c.Interface,
+ Address: types.IPNet(c.Address),
+ Gateway: c.Gateway,
+ }
+
+ return json.Marshal(ipc)
+}
+
+func (c *IPConfig) UnmarshalJSON(data []byte) error {
+ ipc := ipConfig{}
+ if err := json.Unmarshal(data, &ipc); err != nil {
+ return err
+ }
+
+ c.Interface = ipc.Interface
+ c.Address = net.IPNet(ipc.Address)
+ c.Gateway = ipc.Gateway
+ return nil
+}
diff --git a/vendor/github.com/containernetworking/cni/pkg/types/args.go b/vendor/github.com/containernetworking/cni/pkg/types/args.go
index 4eac64899..7516f03ef 100644
--- a/vendor/github.com/containernetworking/cni/pkg/types/args.go
+++ b/vendor/github.com/containernetworking/cni/pkg/types/args.go
@@ -91,16 +91,26 @@ func LoadArgs(args string, container interface{}) error {
unknownArgs = append(unknownArgs, pair)
continue
}
- keyFieldIface := keyField.Addr().Interface()
- u, ok := keyFieldIface.(encoding.TextUnmarshaler)
+
+ var keyFieldInterface interface{}
+ switch {
+ case keyField.Kind() == reflect.Ptr:
+ keyField.Set(reflect.New(keyField.Type().Elem()))
+ keyFieldInterface = keyField.Interface()
+ case keyField.CanAddr() && keyField.Addr().CanInterface():
+ keyFieldInterface = keyField.Addr().Interface()
+ default:
+ return UnmarshalableArgsError{fmt.Errorf("field '%s' has no valid interface", keyString)}
+ }
+ u, ok := keyFieldInterface.(encoding.TextUnmarshaler)
if !ok {
return UnmarshalableArgsError{fmt.Errorf(
"ARGS: cannot unmarshal into field '%s' - type '%s' does not implement encoding.TextUnmarshaler",
- keyString, reflect.TypeOf(keyFieldIface))}
+ keyString, reflect.TypeOf(keyFieldInterface))}
}
err := u.UnmarshalText([]byte(valueString))
if err != nil {
- return fmt.Errorf("ARGS: error parsing value of pair %q: %v)", pair, err)
+ return fmt.Errorf("ARGS: error parsing value of pair %q: %w", pair, err)
}
}
diff --git a/vendor/github.com/containernetworking/cni/pkg/types/create/create.go b/vendor/github.com/containernetworking/cni/pkg/types/create/create.go
new file mode 100644
index 000000000..ed28b33e8
--- /dev/null
+++ b/vendor/github.com/containernetworking/cni/pkg/types/create/create.go
@@ -0,0 +1,56 @@
+// Copyright 2016 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 create
+
+import (
+ "encoding/json"
+ "fmt"
+
+ "github.com/containernetworking/cni/pkg/types"
+ convert "github.com/containernetworking/cni/pkg/types/internal"
+)
+
+// DecodeVersion returns the CNI version from CNI configuration or result JSON,
+// or an error if the operation could not be performed.
+func DecodeVersion(jsonBytes []byte) (string, error) {
+ var conf struct {
+ CNIVersion string `json:"cniVersion"`
+ }
+ err := json.Unmarshal(jsonBytes, &conf)
+ if err != nil {
+ return "", fmt.Errorf("decoding version from network config: %w", err)
+ }
+ if conf.CNIVersion == "" {
+ return "0.1.0", nil
+ }
+ return conf.CNIVersion, nil
+}
+
+// Create creates a CNI Result using the given JSON with the expected
+// version, or an error if the creation could not be performed
+func Create(version string, bytes []byte) (types.Result, error) {
+ return convert.Create(version, bytes)
+}
+
+// CreateFromBytes creates a CNI Result from the given JSON, automatically
+// detecting the CNI spec version of the result. An error is returned if the
+// operation could not be performed.
+func CreateFromBytes(bytes []byte) (types.Result, error) {
+ version, err := DecodeVersion(bytes)
+ if err != nil {
+ return nil, err
+ }
+ return convert.Create(version, bytes)
+}
diff --git a/vendor/github.com/containernetworking/cni/pkg/types/current/types.go b/vendor/github.com/containernetworking/cni/pkg/types/current/types.go
deleted file mode 100644
index 754cc6e72..000000000
--- a/vendor/github.com/containernetworking/cni/pkg/types/current/types.go
+++ /dev/null
@@ -1,276 +0,0 @@
-// Copyright 2016 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 current
-
-import (
- "encoding/json"
- "fmt"
- "io"
- "net"
- "os"
-
- "github.com/containernetworking/cni/pkg/types"
- "github.com/containernetworking/cni/pkg/types/020"
-)
-
-const ImplementedSpecVersion string = "0.4.0"
-
-var SupportedVersions = []string{"0.3.0", "0.3.1", ImplementedSpecVersion}
-
-func NewResult(data []byte) (types.Result, error) {
- result := &Result{}
- if err := json.Unmarshal(data, result); err != nil {
- return nil, err
- }
- return result, nil
-}
-
-func GetResult(r types.Result) (*Result, error) {
- resultCurrent, err := r.GetAsVersion(ImplementedSpecVersion)
- if err != nil {
- return nil, err
- }
- result, ok := resultCurrent.(*Result)
- if !ok {
- return nil, fmt.Errorf("failed to convert result")
- }
- return result, nil
-}
-
-var resultConverters = []struct {
- versions []string
- convert func(types.Result) (*Result, error)
-}{
- {types020.SupportedVersions, convertFrom020},
- {SupportedVersions, convertFrom030},
-}
-
-func convertFrom020(result types.Result) (*Result, error) {
- oldResult, err := types020.GetResult(result)
- if err != nil {
- return nil, err
- }
-
- newResult := &Result{
- CNIVersion: ImplementedSpecVersion,
- DNS: oldResult.DNS,
- Routes: []*types.Route{},
- }
-
- if oldResult.IP4 != nil {
- newResult.IPs = append(newResult.IPs, &IPConfig{
- Version: "4",
- Address: oldResult.IP4.IP,
- Gateway: oldResult.IP4.Gateway,
- })
- for _, route := range oldResult.IP4.Routes {
- newResult.Routes = append(newResult.Routes, &types.Route{
- Dst: route.Dst,
- GW: route.GW,
- })
- }
- }
-
- if oldResult.IP6 != nil {
- newResult.IPs = append(newResult.IPs, &IPConfig{
- Version: "6",
- Address: oldResult.IP6.IP,
- Gateway: oldResult.IP6.Gateway,
- })
- for _, route := range oldResult.IP6.Routes {
- newResult.Routes = append(newResult.Routes, &types.Route{
- Dst: route.Dst,
- GW: route.GW,
- })
- }
- }
-
- return newResult, nil
-}
-
-func convertFrom030(result types.Result) (*Result, error) {
- newResult, ok := result.(*Result)
- if !ok {
- return nil, fmt.Errorf("failed to convert result")
- }
- newResult.CNIVersion = ImplementedSpecVersion
- return newResult, nil
-}
-
-func NewResultFromResult(result types.Result) (*Result, error) {
- version := result.Version()
- for _, converter := range resultConverters {
- for _, supportedVersion := range converter.versions {
- if version == supportedVersion {
- return converter.convert(result)
- }
- }
- }
- return nil, fmt.Errorf("unsupported CNI result22 version %q", version)
-}
-
-// Result is what gets returned from the plugin (via stdout) to the caller
-type Result struct {
- CNIVersion string `json:"cniVersion,omitempty"`
- Interfaces []*Interface `json:"interfaces,omitempty"`
- IPs []*IPConfig `json:"ips,omitempty"`
- Routes []*types.Route `json:"routes,omitempty"`
- DNS types.DNS `json:"dns,omitempty"`
-}
-
-// Convert to the older 0.2.0 CNI spec Result type
-func (r *Result) convertTo020() (*types020.Result, error) {
- oldResult := &types020.Result{
- CNIVersion: types020.ImplementedSpecVersion,
- DNS: r.DNS,
- }
-
- for _, ip := range r.IPs {
- // Only convert the first IP address of each version as 0.2.0
- // and earlier cannot handle multiple IP addresses
- if ip.Version == "4" && oldResult.IP4 == nil {
- oldResult.IP4 = &types020.IPConfig{
- IP: ip.Address,
- Gateway: ip.Gateway,
- }
- } else if ip.Version == "6" && oldResult.IP6 == nil {
- oldResult.IP6 = &types020.IPConfig{
- IP: ip.Address,
- Gateway: ip.Gateway,
- }
- }
-
- if oldResult.IP4 != nil && oldResult.IP6 != nil {
- break
- }
- }
-
- for _, route := range r.Routes {
- is4 := route.Dst.IP.To4() != nil
- if is4 && oldResult.IP4 != nil {
- oldResult.IP4.Routes = append(oldResult.IP4.Routes, types.Route{
- Dst: route.Dst,
- GW: route.GW,
- })
- } else if !is4 && oldResult.IP6 != nil {
- oldResult.IP6.Routes = append(oldResult.IP6.Routes, types.Route{
- Dst: route.Dst,
- GW: route.GW,
- })
- }
- }
-
- if oldResult.IP4 == nil && oldResult.IP6 == nil {
- return nil, fmt.Errorf("cannot convert: no valid IP addresses")
- }
-
- return oldResult, nil
-}
-
-func (r *Result) Version() string {
- return ImplementedSpecVersion
-}
-
-func (r *Result) GetAsVersion(version string) (types.Result, error) {
- switch version {
- case "0.3.0", "0.3.1", ImplementedSpecVersion:
- r.CNIVersion = version
- return r, nil
- case types020.SupportedVersions[0], types020.SupportedVersions[1], types020.SupportedVersions[2]:
- return r.convertTo020()
- }
- return nil, fmt.Errorf("cannot convert version 0.3.x to %q", version)
-}
-
-func (r *Result) Print() error {
- return r.PrintTo(os.Stdout)
-}
-
-func (r *Result) PrintTo(writer io.Writer) error {
- data, err := json.MarshalIndent(r, "", " ")
- if err != nil {
- return err
- }
- _, err = writer.Write(data)
- return err
-}
-
-// Convert this old version result to the current CNI version result
-func (r *Result) Convert() (*Result, error) {
- return r, nil
-}
-
-// Interface contains values about the created interfaces
-type Interface struct {
- Name string `json:"name"`
- Mac string `json:"mac,omitempty"`
- Sandbox string `json:"sandbox,omitempty"`
-}
-
-func (i *Interface) String() string {
- return fmt.Sprintf("%+v", *i)
-}
-
-// Int returns a pointer to the int value passed in. Used to
-// set the IPConfig.Interface field.
-func Int(v int) *int {
- return &v
-}
-
-// IPConfig contains values necessary to configure an IP address on an interface
-type IPConfig struct {
- // IP version, either "4" or "6"
- Version string
- // Index into Result structs Interfaces list
- Interface *int
- Address net.IPNet
- Gateway net.IP
-}
-
-func (i *IPConfig) String() string {
- return fmt.Sprintf("%+v", *i)
-}
-
-// JSON (un)marshallable types
-type ipConfig struct {
- Version string `json:"version"`
- Interface *int `json:"interface,omitempty"`
- Address types.IPNet `json:"address"`
- Gateway net.IP `json:"gateway,omitempty"`
-}
-
-func (c *IPConfig) MarshalJSON() ([]byte, error) {
- ipc := ipConfig{
- Version: c.Version,
- Interface: c.Interface,
- Address: types.IPNet(c.Address),
- Gateway: c.Gateway,
- }
-
- return json.Marshal(ipc)
-}
-
-func (c *IPConfig) UnmarshalJSON(data []byte) error {
- ipc := ipConfig{}
- if err := json.Unmarshal(data, &ipc); err != nil {
- return err
- }
-
- c.Version = ipc.Version
- c.Interface = ipc.Interface
- c.Address = net.IPNet(ipc.Address)
- c.Gateway = ipc.Gateway
- return nil
-}
diff --git a/vendor/github.com/containernetworking/cni/pkg/types/internal/convert.go b/vendor/github.com/containernetworking/cni/pkg/types/internal/convert.go
new file mode 100644
index 000000000..bdbe4b0a5
--- /dev/null
+++ b/vendor/github.com/containernetworking/cni/pkg/types/internal/convert.go
@@ -0,0 +1,92 @@
+// Copyright 2016 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 convert
+
+import (
+ "fmt"
+
+ "github.com/containernetworking/cni/pkg/types"
+)
+
+// ConvertFn should convert from the given arbitrary Result type into a
+// Result implementing CNI specification version passed in toVersion.
+// The function is guaranteed to be passed a Result type matching the
+// fromVersion it was registered with, and is guaranteed to be
+// passed a toVersion matching one of the toVersions it was registered with.
+type ConvertFn func(from types.Result, toVersion string) (types.Result, error)
+
+type converter struct {
+ // fromVersion is the CNI Result spec version that convertFn accepts
+ fromVersion string
+ // toVersions is a list of versions that convertFn can convert to
+ toVersions []string
+ convertFn ConvertFn
+}
+
+var converters []*converter
+
+func findConverter(fromVersion, toVersion string) *converter {
+ for _, c := range converters {
+ if c.fromVersion == fromVersion {
+ for _, v := range c.toVersions {
+ if v == toVersion {
+ return c
+ }
+ }
+ }
+ }
+ return nil
+}
+
+// Convert converts a CNI Result to the requested CNI specification version,
+// or returns an error if the conversion could not be performed or failed
+func Convert(from types.Result, toVersion string) (types.Result, error) {
+ if toVersion == "" {
+ toVersion = "0.1.0"
+ }
+
+ fromVersion := from.Version()
+
+ // Shortcut for same version
+ if fromVersion == toVersion {
+ return from, nil
+ }
+
+ // Otherwise find the right converter
+ c := findConverter(fromVersion, toVersion)
+ if c == nil {
+ return nil, fmt.Errorf("no converter for CNI result version %s to %s",
+ fromVersion, toVersion)
+ }
+ return c.convertFn(from, toVersion)
+}
+
+// RegisterConverter registers a CNI Result converter. SHOULD NOT BE CALLED
+// EXCEPT FROM CNI ITSELF.
+func RegisterConverter(fromVersion string, toVersions []string, convertFn ConvertFn) {
+ // Make sure there is no converter already registered for these
+ // from and to versions
+ for _, v := range toVersions {
+ if findConverter(fromVersion, v) != nil {
+ panic(fmt.Sprintf("converter already registered for %s to %s",
+ fromVersion, v))
+ }
+ }
+ converters = append(converters, &converter{
+ fromVersion: fromVersion,
+ toVersions: toVersions,
+ convertFn: convertFn,
+ })
+}
diff --git a/vendor/github.com/containernetworking/cni/pkg/types/internal/create.go b/vendor/github.com/containernetworking/cni/pkg/types/internal/create.go
new file mode 100644
index 000000000..963630912
--- /dev/null
+++ b/vendor/github.com/containernetworking/cni/pkg/types/internal/create.go
@@ -0,0 +1,66 @@
+// Copyright 2016 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 convert
+
+import (
+ "fmt"
+
+ "github.com/containernetworking/cni/pkg/types"
+)
+
+type ResultFactoryFunc func([]byte) (types.Result, error)
+
+type creator struct {
+ // CNI Result spec versions that createFn can create a Result for
+ versions []string
+ createFn ResultFactoryFunc
+}
+
+var creators []*creator
+
+func findCreator(version string) *creator {
+ for _, c := range creators {
+ for _, v := range c.versions {
+ if v == version {
+ return c
+ }
+ }
+ }
+ return nil
+}
+
+// Create creates a CNI Result using the given JSON, or an error if the creation
+// could not be performed
+func Create(version string, bytes []byte) (types.Result, error) {
+ if c := findCreator(version); c != nil {
+ return c.createFn(bytes)
+ }
+ return nil, fmt.Errorf("unsupported CNI result version %q", version)
+}
+
+// RegisterCreator registers a CNI Result creator. SHOULD NOT BE CALLED
+// EXCEPT FROM CNI ITSELF.
+func RegisterCreator(versions []string, createFn ResultFactoryFunc) {
+ // Make sure there is no creator already registered for these versions
+ for _, v := range versions {
+ if findCreator(v) != nil {
+ panic(fmt.Sprintf("creator already registered for %s", v))
+ }
+ }
+ creators = append(creators, &creator{
+ versions: versions,
+ createFn: createFn,
+ })
+}
diff --git a/vendor/github.com/containernetworking/cni/pkg/types/types.go b/vendor/github.com/containernetworking/cni/pkg/types/types.go
index 3fa757a5d..fba17dfc0 100644
--- a/vendor/github.com/containernetworking/cni/pkg/types/types.go
+++ b/vendor/github.com/containernetworking/cni/pkg/types/types.go
@@ -83,8 +83,6 @@ type NetConfList struct {
Plugins []*NetConf `json:"plugins,omitempty"`
}
-type ResultFactoryFunc func([]byte) (Result, error)
-
// Result is an interface that provides the result of plugin execution
type Result interface {
// The highest CNI specification result version the result supports
@@ -118,6 +116,24 @@ type DNS struct {
Options []string `json:"options,omitempty"`
}
+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)
+ }
+ return to
+}
+
type Route struct {
Dst net.IPNet
GW net.IP
@@ -127,6 +143,17 @@ func (r *Route) String() string {
return fmt.Sprintf("%+v", *r)
}
+func (r *Route) Copy() *Route {
+ if r == nil {
+ return nil
+ }
+
+ return &Route{
+ Dst: r.Dst,
+ GW: r.GW,
+ }
+}
+
// Well known error codes
// see https://github.com/containernetworking/cni/blob/master/SPEC.md#well-known-error-codes
const (
diff --git a/vendor/github.com/containernetworking/cni/pkg/version/conf.go b/vendor/github.com/containernetworking/cni/pkg/version/conf.go
index 3cca58bbe..808c33b83 100644
--- a/vendor/github.com/containernetworking/cni/pkg/version/conf.go
+++ b/vendor/github.com/containernetworking/cni/pkg/version/conf.go
@@ -15,23 +15,12 @@
package version
import (
- "encoding/json"
- "fmt"
+ "github.com/containernetworking/cni/pkg/types/create"
)
// ConfigDecoder can decode the CNI version available in network config data
type ConfigDecoder struct{}
func (*ConfigDecoder) Decode(jsonBytes []byte) (string, error) {
- var conf struct {
- CNIVersion string `json:"cniVersion"`
- }
- err := json.Unmarshal(jsonBytes, &conf)
- if err != nil {
- return "", fmt.Errorf("decoding version from network config: %s", err)
- }
- if conf.CNIVersion == "" {
- return "0.1.0", nil
- }
- return conf.CNIVersion, nil
+ return create.DecodeVersion(jsonBytes)
}
diff --git a/vendor/github.com/containernetworking/cni/pkg/version/plugin.go b/vendor/github.com/containernetworking/cni/pkg/version/plugin.go
index 1df427243..d4bc9d169 100644
--- a/vendor/github.com/containernetworking/cni/pkg/version/plugin.go
+++ b/vendor/github.com/containernetworking/cni/pkg/version/plugin.go
@@ -68,7 +68,7 @@ func (*PluginDecoder) Decode(jsonBytes []byte) (PluginInfo, error) {
var info pluginInfo
err := json.Unmarshal(jsonBytes, &info)
if err != nil {
- return nil, fmt.Errorf("decoding version info: %s", err)
+ return nil, fmt.Errorf("decoding version info: %w", err)
}
if info.CNIVersion_ == "" {
return nil, fmt.Errorf("decoding version info: missing field cniVersion")
@@ -97,20 +97,20 @@ func ParseVersion(version string) (int, int, int, error) {
major, err := strconv.Atoi(parts[0])
if err != nil {
- return -1, -1, -1, fmt.Errorf("failed to convert major version part %q: %v", parts[0], err)
+ return -1, -1, -1, fmt.Errorf("failed to convert major version part %q: %w", parts[0], err)
}
if len(parts) >= 2 {
minor, err = strconv.Atoi(parts[1])
if err != nil {
- return -1, -1, -1, fmt.Errorf("failed to convert minor version part %q: %v", parts[1], err)
+ return -1, -1, -1, fmt.Errorf("failed to convert minor version part %q: %w", parts[1], err)
}
}
if len(parts) >= 3 {
micro, err = strconv.Atoi(parts[2])
if err != nil {
- return -1, -1, -1, fmt.Errorf("failed to convert micro version part %q: %v", parts[2], err)
+ return -1, -1, -1, fmt.Errorf("failed to convert micro version part %q: %w", parts[2], err)
}
}
diff --git a/vendor/github.com/containernetworking/cni/pkg/version/version.go b/vendor/github.com/containernetworking/cni/pkg/version/version.go
index 8f3508e61..1326f8038 100644
--- a/vendor/github.com/containernetworking/cni/pkg/version/version.go
+++ b/vendor/github.com/containernetworking/cni/pkg/version/version.go
@@ -19,13 +19,13 @@ import (
"fmt"
"github.com/containernetworking/cni/pkg/types"
- "github.com/containernetworking/cni/pkg/types/020"
- "github.com/containernetworking/cni/pkg/types/current"
+ 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 "0.4.0"
+ return types100.ImplementedSpecVersion
}
// Legacy PluginInfo describes a plugin that is backwards compatible with the
@@ -36,29 +36,28 @@ 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")
+var All = PluginSupports("0.1.0", "0.2.0", "0.3.0", "0.3.1", "0.4.0", "1.0.0")
-var resultFactories = []struct {
- supportedVersions []string
- newResult types.ResultFactoryFunc
-}{
- {current.SupportedVersions, current.NewResult},
- {types020.SupportedVersions, types020.NewResult},
+// VersionsFrom returns a list of versions starting from min, inclusive
+func VersionsStartingFrom(min string) PluginInfo {
+ out := []string{}
+ // cheat, just assume ordered
+ ok := false
+ for _, v := range All.SupportedVersions() {
+ if !ok && v == min {
+ ok = true
+ }
+ if ok {
+ out = append(out, v)
+ }
+ }
+ return PluginSupports(out...)
}
// Finds a Result object matching the requested version (if any) and asks
// that object to parse the plugin result, returning an error if parsing failed.
func NewResult(version string, resultBytes []byte) (types.Result, error) {
- reconciler := &Reconciler{}
- for _, resultFactory := range resultFactories {
- err := reconciler.CheckRaw(version, resultFactory.supportedVersions)
- if err == nil {
- // Result supports this version
- return resultFactory.newResult(resultBytes)
- }
- }
-
- return nil, fmt.Errorf("unsupported CNI result version %q", version)
+ return create.Create(version, resultBytes)
}
// ParsePrevResult parses a prevResult in a NetConf structure and sets
@@ -68,15 +67,22 @@ func ParsePrevResult(conf *types.NetConf) error {
return nil
}
+ // Prior to 1.0.0, Result types may not marshal a CNIVersion. Since the
+ // result version must match the config version, if the Result's version
+ // is empty, inject the config version.
+ if ver, ok := conf.RawPrevResult["CNIVersion"]; !ok || ver == "" {
+ conf.RawPrevResult["CNIVersion"] = conf.CNIVersion
+ }
+
resultBytes, err := json.Marshal(conf.RawPrevResult)
if err != nil {
- return fmt.Errorf("could not serialize prevResult: %v", err)
+ return fmt.Errorf("could not serialize prevResult: %w", err)
}
conf.RawPrevResult = nil
- conf.PrevResult, err = NewResult(conf.CNIVersion, resultBytes)
+ conf.PrevResult, err = create.Create(conf.CNIVersion, resultBytes)
if err != nil {
- return fmt.Errorf("could not parse prevResult: %v", err)
+ return fmt.Errorf("could not parse prevResult: %w", err)
}
return nil
diff --git a/vendor/github.com/vishvananda/netlink/class_linux.go b/vendor/github.com/vishvananda/netlink/class_linux.go
index e664ade7f..029568a3f 100644
--- a/vendor/github.com/vishvananda/netlink/class_linux.go
+++ b/vendor/github.com/vishvananda/netlink/class_linux.go
@@ -176,6 +176,12 @@ func classPayload(req *nl.NetlinkRequest, class Class) error {
options.AddRtAttr(nl.TCA_HTB_PARMS, opt.Serialize())
options.AddRtAttr(nl.TCA_HTB_RTAB, SerializeRtab(rtab))
options.AddRtAttr(nl.TCA_HTB_CTAB, SerializeRtab(ctab))
+ if htb.Rate >= uint64(1<<32) {
+ options.AddRtAttr(nl.TCA_HTB_RATE64, nl.Uint64Attr(htb.Rate))
+ }
+ if htb.Ceil >= uint64(1<<32) {
+ options.AddRtAttr(nl.TCA_HTB_CEIL64, nl.Uint64Attr(htb.Ceil))
+ }
case "hfsc":
hfsc := class.(*HfscClass)
opt := nl.HfscCopt{}
@@ -306,6 +312,10 @@ func parseHtbClassData(class Class, data []syscall.NetlinkRouteAttr) (bool, erro
htb.Quantum = opt.Quantum
htb.Level = opt.Level
htb.Prio = opt.Prio
+ case nl.TCA_HTB_RATE64:
+ htb.Rate = native.Uint64(datum.Value[0:8])
+ case nl.TCA_HTB_CEIL64:
+ htb.Ceil = native.Uint64(datum.Value[0:8])
}
}
return detailed, nil
diff --git a/vendor/github.com/vishvananda/netlink/devlink_linux.go b/vendor/github.com/vishvananda/netlink/devlink_linux.go
index 29b3f8ec1..7d57080e8 100644
--- a/vendor/github.com/vishvananda/netlink/devlink_linux.go
+++ b/vendor/github.com/vishvananda/netlink/devlink_linux.go
@@ -27,6 +27,18 @@ type DevlinkDevice struct {
Attrs DevlinkDevAttrs
}
+// DevlinkPort represents port and its attributes
+type DevlinkPort struct {
+ BusName string
+ DeviceName string
+ PortIndex uint32
+ PortType uint16
+ NetdeviceName string
+ NetdevIfIndex uint32
+ RdmaDeviceName string
+ PortFlavour uint16
+}
+
func parseDevLinkDeviceList(msgs [][]byte) ([]*DevlinkDevice, error) {
devices := make([]*DevlinkDevice, 0, len(msgs))
for _, m := range msgs {
@@ -270,3 +282,112 @@ func (h *Handle) DevLinkSetEswitchMode(Dev *DevlinkDevice, NewMode string) error
func DevLinkSetEswitchMode(Dev *DevlinkDevice, NewMode string) error {
return pkgHandle.DevLinkSetEswitchMode(Dev, NewMode)
}
+
+func (port *DevlinkPort) parseAttributes(attrs []syscall.NetlinkRouteAttr) error {
+ for _, a := range attrs {
+ switch a.Attr.Type {
+ case nl.DEVLINK_ATTR_BUS_NAME:
+ port.BusName = string(a.Value)
+ case nl.DEVLINK_ATTR_DEV_NAME:
+ port.DeviceName = string(a.Value)
+ case nl.DEVLINK_ATTR_PORT_INDEX:
+ port.PortIndex = native.Uint32(a.Value)
+ case nl.DEVLINK_ATTR_PORT_TYPE:
+ port.PortType = native.Uint16(a.Value)
+ case nl.DEVLINK_ATTR_PORT_NETDEV_NAME:
+ port.NetdeviceName = string(a.Value)
+ case nl.DEVLINK_ATTR_PORT_NETDEV_IFINDEX:
+ port.NetdevIfIndex = native.Uint32(a.Value)
+ case nl.DEVLINK_ATTR_PORT_IBDEV_NAME:
+ port.RdmaDeviceName = string(a.Value)
+ case nl.DEVLINK_ATTR_PORT_FLAVOUR:
+ port.PortFlavour = native.Uint16(a.Value)
+ }
+ }
+ return nil
+}
+
+func parseDevLinkAllPortList(msgs [][]byte) ([]*DevlinkPort, error) {
+ ports := make([]*DevlinkPort, 0, len(msgs))
+ for _, m := range msgs {
+ attrs, err := nl.ParseRouteAttr(m[nl.SizeofGenlmsg:])
+ if err != nil {
+ return nil, err
+ }
+ port := &DevlinkPort{}
+ if err = port.parseAttributes(attrs); err != nil {
+ return nil, err
+ }
+ ports = append(ports, port)
+ }
+ return ports, nil
+}
+
+// DevLinkGetPortList provides a pointer to devlink ports and nil error,
+// otherwise returns an error code.
+func (h *Handle) DevLinkGetAllPortList() ([]*DevlinkPort, error) {
+ f, err := h.GenlFamilyGet(nl.GENL_DEVLINK_NAME)
+ if err != nil {
+ return nil, err
+ }
+ msg := &nl.Genlmsg{
+ Command: nl.DEVLINK_CMD_PORT_GET,
+ Version: nl.GENL_DEVLINK_VERSION,
+ }
+ req := h.newNetlinkRequest(int(f.ID),
+ unix.NLM_F_REQUEST|unix.NLM_F_ACK|unix.NLM_F_DUMP)
+ req.AddData(msg)
+ msgs, err := req.Execute(unix.NETLINK_GENERIC, 0)
+ if err != nil {
+ return nil, err
+ }
+ ports, err := parseDevLinkAllPortList(msgs)
+ if err != nil {
+ return nil, err
+ }
+ return ports, nil
+}
+
+// DevLinkGetPortList provides a pointer to devlink ports and nil error,
+// otherwise returns an error code.
+func DevLinkGetAllPortList() ([]*DevlinkPort, error) {
+ return pkgHandle.DevLinkGetAllPortList()
+}
+
+func parseDevlinkPortMsg(msgs [][]byte) (*DevlinkPort, error) {
+ m := msgs[0]
+ attrs, err := nl.ParseRouteAttr(m[nl.SizeofGenlmsg:])
+ if err != nil {
+ return nil, err
+ }
+ port := &DevlinkPort{}
+ if err = port.parseAttributes(attrs); err != nil {
+ return nil, err
+ }
+ return port, nil
+}
+
+// DevLinkGetPortByIndexprovides a pointer to devlink device and nil error,
+// otherwise returns an error code.
+func (h *Handle) DevLinkGetPortByIndex(Bus string, Device string, PortIndex uint32) (*DevlinkPort, error) {
+
+ _, req, err := h.createCmdReq(nl.DEVLINK_CMD_PORT_GET, Bus, Device)
+ if err != nil {
+ return nil, err
+ }
+
+ req.AddData(nl.NewRtAttr(nl.DEVLINK_ATTR_PORT_INDEX, nl.Uint32Attr(PortIndex)))
+
+ respmsg, err := req.Execute(unix.NETLINK_GENERIC, 0)
+ if err != nil {
+ return nil, err
+ }
+ port, err := parseDevlinkPortMsg(respmsg)
+ return port, err
+}
+
+// DevLinkGetPortByIndex provides a pointer to devlink portand nil error,
+// otherwise returns an error code.
+func DevLinkGetPortByIndex(Bus string, Device string, PortIndex uint32) (*DevlinkPort, error) {
+ return pkgHandle.DevLinkGetPortByIndex(Bus, Device, PortIndex)
+}
diff --git a/vendor/github.com/vishvananda/netlink/filter_linux.go b/vendor/github.com/vishvananda/netlink/filter_linux.go
index ef6fabe81..2cd46266c 100644
--- a/vendor/github.com/vishvananda/netlink/filter_linux.go
+++ b/vendor/github.com/vishvananda/netlink/filter_linux.go
@@ -36,6 +36,7 @@ type U32 struct {
ClassId uint32
Divisor uint32 // Divisor MUST be power of 2.
Hash uint32
+ Link uint32
RedirIndex int
Sel *TcU32Sel
Actions []Action
@@ -225,6 +226,9 @@ func (h *Handle) filterModify(filter Filter, flags int) error {
if filter.Hash != 0 {
options.AddRtAttr(nl.TCA_U32_HASH, nl.Uint32Attr(filter.Hash))
}
+ if filter.Link != 0 {
+ options.AddRtAttr(nl.TCA_U32_LINK, nl.Uint32Attr(filter.Link))
+ }
actionsAttr := options.AddRtAttr(nl.TCA_U32_ACT, nil)
// backwards compatibility
if filter.RedirIndex != 0 {
@@ -666,6 +670,8 @@ func parseU32Data(filter Filter, data []syscall.NetlinkRouteAttr) (bool, error)
u32.Divisor = native.Uint32(datum.Value)
case nl.TCA_U32_HASH:
u32.Hash = native.Uint32(datum.Value)
+ case nl.TCA_U32_LINK:
+ u32.Link = native.Uint32(datum.Value)
}
}
return detailed, nil
diff --git a/vendor/github.com/vishvananda/netlink/handle_linux.go b/vendor/github.com/vishvananda/netlink/handle_linux.go
index 26887b759..65356679d 100644
--- a/vendor/github.com/vishvananda/netlink/handle_linux.go
+++ b/vendor/github.com/vishvananda/netlink/handle_linux.go
@@ -21,6 +21,22 @@ type Handle struct {
lookupByDump bool
}
+// SetSocketTimeout configures timeout for default netlink sockets
+func SetSocketTimeout(to time.Duration) error {
+ if to < time.Microsecond {
+ return fmt.Errorf("invalid timeout, minimul value is %s", time.Microsecond)
+ }
+
+ nl.SocketTimeoutTv = unix.NsecToTimeval(to.Nanoseconds())
+ return nil
+}
+
+// GetSocketTimeout returns the timeout value used by default netlink sockets
+func GetSocketTimeout() time.Duration {
+ nsec := unix.TimevalToNsec(nl.SocketTimeoutTv)
+ return time.Duration(nsec) * time.Nanosecond
+}
+
// SupportsNetlinkFamily reports whether the passed netlink family is supported by this Handle
func (h *Handle) SupportsNetlinkFamily(nlFamily int) bool {
_, ok := h.sockets[nlFamily]
diff --git a/vendor/github.com/vishvananda/netlink/handle_unspecified.go b/vendor/github.com/vishvananda/netlink/handle_unspecified.go
index df341f706..3a6db8137 100644
--- a/vendor/github.com/vishvananda/netlink/handle_unspecified.go
+++ b/vendor/github.com/vishvananda/netlink/handle_unspecified.go
@@ -237,6 +237,10 @@ func (h *Handle) RouteAdd(route *Route) error {
return ErrNotImplemented
}
+func (h *Handle) RouteAppend(route *Route) error {
+ return ErrNotImplemented
+}
+
func (h *Handle) RouteDel(route *Route) error {
return ErrNotImplemented
}
diff --git a/vendor/github.com/vishvananda/netlink/inet_diag.go b/vendor/github.com/vishvananda/netlink/inet_diag.go
index 72c1fcb59..bee391a80 100644
--- a/vendor/github.com/vishvananda/netlink/inet_diag.go
+++ b/vendor/github.com/vishvananda/netlink/inet_diag.go
@@ -27,4 +27,5 @@ const (
type InetDiagTCPInfoResp struct {
InetDiagMsg *Socket
TCPInfo *TCPInfo
+ TCPBBRInfo *TCPBBRInfo
}
diff --git a/vendor/github.com/vishvananda/netlink/ipset_linux.go b/vendor/github.com/vishvananda/netlink/ipset_linux.go
index 5487fc1cc..2adc2440a 100644
--- a/vendor/github.com/vishvananda/netlink/ipset_linux.go
+++ b/vendor/github.com/vishvananda/netlink/ipset_linux.go
@@ -23,13 +23,15 @@ type IPSetEntry struct {
// IPSetResult is the result of a dump request for a set
type IPSetResult struct {
- Nfgenmsg *nl.Nfgenmsg
- Protocol uint8
- Revision uint8
- Family uint8
- Flags uint8
- SetName string
- TypeName string
+ Nfgenmsg *nl.Nfgenmsg
+ Protocol uint8
+ ProtocolMinVersion uint8
+ Revision uint8
+ Family uint8
+ Flags uint8
+ SetName string
+ TypeName string
+ Comment string
HashSize uint32
NumEntries uint32
@@ -38,6 +40,7 @@ type IPSetResult struct {
SizeInMemory uint32
CadtFlags uint32
Timeout *uint32
+ LineNo uint32
Entries []IPSetEntry
}
@@ -52,7 +55,7 @@ type IpsetCreateOptions struct {
}
// IpsetProtocol returns the ipset protocol version from the kernel
-func IpsetProtocol() (uint8, error) {
+func IpsetProtocol() (uint8, uint8, error) {
return pkgHandle.IpsetProtocol()
}
@@ -86,20 +89,20 @@ func IpsetAdd(setname string, entry *IPSetEntry) error {
return pkgHandle.ipsetAddDel(nl.IPSET_CMD_ADD, setname, entry)
}
-// IpsetDele deletes an entry from an existing ipset.
+// IpsetDel deletes an entry from an existing ipset.
func IpsetDel(setname string, entry *IPSetEntry) error {
return pkgHandle.ipsetAddDel(nl.IPSET_CMD_DEL, setname, entry)
}
-func (h *Handle) IpsetProtocol() (uint8, error) {
+func (h *Handle) IpsetProtocol() (protocol uint8, minVersion uint8, err error) {
req := h.newIpsetRequest(nl.IPSET_CMD_PROTOCOL)
msgs, err := req.Execute(unix.NETLINK_NETFILTER, 0)
if err != nil {
- return 0, err
+ return 0, 0, err
}
-
- return ipsetUnserialize(msgs).Protocol, nil
+ response := ipsetUnserialize(msgs)
+ return response.Protocol, response.ProtocolMinVersion, nil
}
func (h *Handle) IpsetCreate(setname, typename string, options IpsetCreateOptions) error {
@@ -112,7 +115,7 @@ func (h *Handle) IpsetCreate(setname, typename string, options IpsetCreateOption
req.AddData(nl.NewRtAttr(nl.IPSET_ATTR_SETNAME, nl.ZeroTerminated(setname)))
req.AddData(nl.NewRtAttr(nl.IPSET_ATTR_TYPENAME, nl.ZeroTerminated(typename)))
req.AddData(nl.NewRtAttr(nl.IPSET_ATTR_REVISION, nl.Uint8Attr(0)))
- req.AddData(nl.NewRtAttr(nl.IPSET_ATTR_FAMILY, nl.Uint8Attr(0)))
+ req.AddData(nl.NewRtAttr(nl.IPSET_ATTR_FAMILY, nl.Uint8Attr(2))) // 2 == inet
data := nl.NewRtAttr(nl.IPSET_ATTR_DATA|int(nl.NLA_F_NESTED), nil)
@@ -187,6 +190,11 @@ func (h *Handle) IpsetListAll() ([]IPSetResult, error) {
func (h *Handle) ipsetAddDel(nlCmd int, setname string, entry *IPSetEntry) error {
req := h.newIpsetRequest(nlCmd)
req.AddData(nl.NewRtAttr(nl.IPSET_ATTR_SETNAME, nl.ZeroTerminated(setname)))
+
+ if entry.Comment != "" {
+ req.AddData(nl.NewRtAttr(nl.IPSET_ATTR_COMMENT, nl.ZeroTerminated(entry.Comment)))
+ }
+
data := nl.NewRtAttr(nl.IPSET_ATTR_DATA|int(nl.NLA_F_NESTED), nil)
if !entry.Replace {
@@ -197,7 +205,12 @@ func (h *Handle) ipsetAddDel(nlCmd int, setname string, entry *IPSetEntry) error
data.AddChild(&nl.Uint32Attribute{Type: nl.IPSET_ATTR_TIMEOUT | nl.NLA_F_NET_BYTEORDER, Value: *entry.Timeout})
}
if entry.MAC != nil {
- data.AddChild(nl.NewRtAttr(nl.IPSET_ATTR_ETHER, entry.MAC))
+ nestedData := nl.NewRtAttr(nl.IPSET_ATTR_ETHER|int(nl.NLA_F_NET_BYTEORDER), entry.MAC)
+ data.AddChild(nl.NewRtAttr(nl.IPSET_ATTR_ETHER|int(nl.NLA_F_NESTED), nestedData.Serialize()))
+ }
+ if entry.IP != nil {
+ nestedData := nl.NewRtAttr(nl.IPSET_ATTR_IP|int(nl.NLA_F_NET_BYTEORDER), entry.IP)
+ data.AddChild(nl.NewRtAttr(nl.IPSET_ATTR_IP|int(nl.NLA_F_NESTED), nestedData.Serialize()))
}
data.AddChild(&nl.Uint32Attribute{Type: nl.IPSET_ATTR_LINENO | nl.NLA_F_NET_BYTEORDER, Value: 0})
@@ -249,6 +262,8 @@ func (result *IPSetResult) unserialize(msg []byte) {
result.Protocol = attr.Value[0]
case nl.IPSET_ATTR_SETNAME:
result.SetName = nl.BytesToString(attr.Value)
+ case nl.IPSET_ATTR_COMMENT:
+ result.Comment = nl.BytesToString(attr.Value)
case nl.IPSET_ATTR_TYPENAME:
result.TypeName = nl.BytesToString(attr.Value)
case nl.IPSET_ATTR_REVISION:
@@ -261,6 +276,8 @@ func (result *IPSetResult) unserialize(msg []byte) {
result.parseAttrData(attr.Value)
case nl.IPSET_ATTR_ADT | nl.NLA_F_NESTED:
result.parseAttrADT(attr.Value)
+ case nl.IPSET_ATTR_PROTOCOL_MIN:
+ result.ProtocolMinVersion = attr.Value[0]
default:
log.Printf("unknown ipset attribute from kernel: %+v %v", attr, attr.Type&nl.NLA_TYPE_MASK)
}
@@ -285,6 +302,17 @@ func (result *IPSetResult) parseAttrData(data []byte) {
result.SizeInMemory = attr.Uint32()
case nl.IPSET_ATTR_CADT_FLAGS | nl.NLA_F_NET_BYTEORDER:
result.CadtFlags = attr.Uint32()
+ case nl.IPSET_ATTR_IP | nl.NLA_F_NESTED:
+ for nested := range nl.ParseAttributes(attr.Value) {
+ switch nested.Type {
+ case nl.IPSET_ATTR_IP | nl.NLA_F_NET_BYTEORDER:
+ result.Entries = append(result.Entries, IPSetEntry{IP: nested.Value})
+ }
+ }
+ case nl.IPSET_ATTR_CADT_LINENO | nl.NLA_F_NET_BYTEORDER:
+ result.LineNo = attr.Uint32()
+ case nl.IPSET_ATTR_COMMENT:
+ result.Comment = nl.BytesToString(attr.Value)
default:
log.Printf("unknown ipset data attribute from kernel: %+v %v", attr, attr.Type&nl.NLA_TYPE_MASK)
}
@@ -316,6 +344,8 @@ func parseIPSetEntry(data []byte) (entry IPSetEntry) {
entry.Packets = &val
case nl.IPSET_ATTR_ETHER:
entry.MAC = net.HardwareAddr(attr.Value)
+ case nl.IPSET_ATTR_IP:
+ entry.IP = net.IP(attr.Value)
case nl.IPSET_ATTR_COMMENT:
entry.Comment = nl.BytesToString(attr.Value)
case nl.IPSET_ATTR_IP | nl.NLA_F_NESTED:
diff --git a/vendor/github.com/vishvananda/netlink/link.go b/vendor/github.com/vishvananda/netlink/link.go
index e2441bd71..32ca7cd64 100644
--- a/vendor/github.com/vishvananda/netlink/link.go
+++ b/vendor/github.com/vishvananda/netlink/link.go
@@ -555,6 +555,27 @@ const (
BOND_ARP_VALIDATE_ALL
)
+var bondArpValidateToString = map[BondArpValidate]string{
+ BOND_ARP_VALIDATE_NONE: "none",
+ BOND_ARP_VALIDATE_ACTIVE: "active",
+ BOND_ARP_VALIDATE_BACKUP: "backup",
+ BOND_ARP_VALIDATE_ALL: "none",
+}
+var StringToBondArpValidateMap = map[string]BondArpValidate{
+ "none": BOND_ARP_VALIDATE_NONE,
+ "active": BOND_ARP_VALIDATE_ACTIVE,
+ "backup": BOND_ARP_VALIDATE_BACKUP,
+ "all": BOND_ARP_VALIDATE_ALL,
+}
+
+func (b BondArpValidate) String() string {
+ s, ok := bondArpValidateToString[b]
+ if !ok {
+ return fmt.Sprintf("BondArpValidate(%d)", b)
+ }
+ return s
+}
+
// BondPrimaryReselect type
type BondPrimaryReselect int
@@ -565,6 +586,25 @@ const (
BOND_PRIMARY_RESELECT_FAILURE
)
+var bondPrimaryReselectToString = map[BondPrimaryReselect]string{
+ BOND_PRIMARY_RESELECT_ALWAYS: "always",
+ BOND_PRIMARY_RESELECT_BETTER: "better",
+ BOND_PRIMARY_RESELECT_FAILURE: "failure",
+}
+var StringToBondPrimaryReselectMap = map[string]BondPrimaryReselect{
+ "always": BOND_PRIMARY_RESELECT_ALWAYS,
+ "better": BOND_PRIMARY_RESELECT_BETTER,
+ "failure": BOND_PRIMARY_RESELECT_FAILURE,
+}
+
+func (b BondPrimaryReselect) String() string {
+ s, ok := bondPrimaryReselectToString[b]
+ if !ok {
+ return fmt.Sprintf("BondPrimaryReselect(%d)", b)
+ }
+ return s
+}
+
// BondArpAllTargets type
type BondArpAllTargets int
@@ -574,6 +614,23 @@ const (
BOND_ARP_ALL_TARGETS_ALL
)
+var bondArpAllTargetsToString = map[BondArpAllTargets]string{
+ BOND_ARP_ALL_TARGETS_ANY: "any",
+ BOND_ARP_ALL_TARGETS_ALL: "all",
+}
+var StringToBondArpAllTargetsMap = map[string]BondArpAllTargets{
+ "any": BOND_ARP_ALL_TARGETS_ANY,
+ "all": BOND_ARP_ALL_TARGETS_ALL,
+}
+
+func (b BondArpAllTargets) String() string {
+ s, ok := bondArpAllTargetsToString[b]
+ if !ok {
+ return fmt.Sprintf("BondArpAllTargets(%d)", b)
+ }
+ return s
+}
+
// BondFailOverMac type
type BondFailOverMac int
@@ -584,6 +641,25 @@ const (
BOND_FAIL_OVER_MAC_FOLLOW
)
+var bondFailOverMacToString = map[BondFailOverMac]string{
+ BOND_FAIL_OVER_MAC_NONE: "none",
+ BOND_FAIL_OVER_MAC_ACTIVE: "active",
+ BOND_FAIL_OVER_MAC_FOLLOW: "follow",
+}
+var StringToBondFailOverMacMap = map[string]BondFailOverMac{
+ "none": BOND_FAIL_OVER_MAC_NONE,
+ "active": BOND_FAIL_OVER_MAC_ACTIVE,
+ "follow": BOND_FAIL_OVER_MAC_FOLLOW,
+}
+
+func (b BondFailOverMac) String() string {
+ s, ok := bondFailOverMacToString[b]
+ if !ok {
+ return fmt.Sprintf("BondFailOverMac(%d)", b)
+ }
+ return s
+}
+
// BondXmitHashPolicy type
type BondXmitHashPolicy int
@@ -675,6 +751,25 @@ const (
BOND_AD_SELECT_COUNT
)
+var bondAdSelectToString = map[BondAdSelect]string{
+ BOND_AD_SELECT_STABLE: "stable",
+ BOND_AD_SELECT_BANDWIDTH: "bandwidth",
+ BOND_AD_SELECT_COUNT: "count",
+}
+var StringToBondAdSelectMap = map[string]BondAdSelect{
+ "stable": BOND_AD_SELECT_STABLE,
+ "bandwidth": BOND_AD_SELECT_BANDWIDTH,
+ "count": BOND_AD_SELECT_COUNT,
+}
+
+func (b BondAdSelect) String() string {
+ s, ok := bondAdSelectToString[b]
+ if !ok {
+ return fmt.Sprintf("BondAdSelect(%d)", b)
+ }
+ return s
+}
+
// BondAdInfo represents ad info for bond
type BondAdInfo struct {
AggregatorId int
@@ -706,7 +801,7 @@ type Bond struct {
AllSlavesActive int
MinLinks int
LpInterval int
- PackersPerSlave int
+ PacketsPerSlave int
LacpRate BondLacpRate
AdSelect BondAdSelect
// looking at iproute tool AdInfo can only be retrived. It can't be set.
@@ -739,7 +834,7 @@ func NewLinkBond(atr LinkAttrs) *Bond {
AllSlavesActive: -1,
MinLinks: -1,
LpInterval: -1,
- PackersPerSlave: -1,
+ PacketsPerSlave: -1,
LacpRate: -1,
AdSelect: -1,
AdActorSysPrio: -1,
@@ -789,8 +884,10 @@ func (bond *Bond) Type() string {
type BondSlaveState uint8
const (
- BondStateActive = iota // Link is active.
- BondStateBackup // Link is backup.
+ //BondStateActive Link is active.
+ BondStateActive BondSlaveState = iota
+ //BondStateBackup Link is backup.
+ BondStateBackup
)
func (s BondSlaveState) String() string {
@@ -804,15 +901,19 @@ func (s BondSlaveState) String() string {
}
}
-// BondSlaveState represents the values of the IFLA_BOND_SLAVE_MII_STATUS bond slave
+// BondSlaveMiiStatus represents the values of the IFLA_BOND_SLAVE_MII_STATUS bond slave
// attribute, which contains the status of MII link monitoring
type BondSlaveMiiStatus uint8
const (
- BondLinkUp = iota // link is up and running.
- BondLinkFail // link has just gone down.
- BondLinkDown // link has been down for too long time.
- BondLinkBack // link is going back.
+ //BondLinkUp link is up and running.
+ BondLinkUp BondSlaveMiiStatus = iota
+ //BondLinkFail link has just gone down.
+ BondLinkFail
+ //BondLinkDown link has been down for too long time.
+ BondLinkDown
+ //BondLinkBack link is going back.
+ BondLinkBack
)
func (s BondSlaveMiiStatus) String() string {
@@ -845,6 +946,30 @@ func (b *BondSlave) SlaveType() string {
return "bond"
}
+// Geneve devices must specify RemoteIP and ID (VNI) on create
+// https://github.com/torvalds/linux/blob/47ec5303d73ea344e84f46660fff693c57641386/drivers/net/geneve.c#L1209-L1223
+type Geneve struct {
+ LinkAttrs
+ ID uint32 // vni
+ Remote net.IP
+ Ttl uint8
+ Tos uint8
+ Dport uint16
+ UdpCsum uint8
+ UdpZeroCsum6Tx uint8
+ UdpZeroCsum6Rx uint8
+ Link uint32
+ FlowBased bool
+}
+
+func (geneve *Geneve) Attrs() *LinkAttrs {
+ return &geneve.LinkAttrs
+}
+
+func (geneve *Geneve) Type() string {
+ return "geneve"
+}
+
// Gretap devices must specify LocalIP and RemoteIP on create
type Gretap struct {
LinkAttrs
@@ -1068,6 +1193,58 @@ var StringToIPoIBMode = map[string]IPoIBMode{
"connected": IPOIB_MODE_CONNECTED,
}
+const (
+ CAN_STATE_ERROR_ACTIVE = iota
+ CAN_STATE_ERROR_WARNING
+ CAN_STATE_ERROR_PASSIVE
+ CAN_STATE_BUS_OFF
+ CAN_STATE_STOPPED
+ CAN_STATE_SLEEPING
+)
+
+type Can struct {
+ LinkAttrs
+
+ BitRate uint32
+ SamplePoint uint32
+ TimeQuanta uint32
+ PropagationSegment uint32
+ PhaseSegment1 uint32
+ PhaseSegment2 uint32
+ SyncJumpWidth uint32
+ BitRatePreScaler uint32
+
+ Name string
+ TimeSegment1Min uint32
+ TimeSegment1Max uint32
+ TimeSegment2Min uint32
+ TimeSegment2Max uint32
+ SyncJumpWidthMax uint32
+ BitRatePreScalerMin uint32
+ BitRatePreScalerMax uint32
+ BitRatePreScalerInc uint32
+
+ ClockFrequency uint32
+
+ State uint32
+
+ Mask uint32
+ Flags uint32
+
+ TxError uint16
+ RxError uint16
+
+ RestartMs uint32
+}
+
+func (can *Can) Attrs() *LinkAttrs {
+ return &can.LinkAttrs
+}
+
+func (can *Can) Type() string {
+ return "can"
+}
+
type IPoIB struct {
LinkAttrs
Pkey uint16
diff --git a/vendor/github.com/vishvananda/netlink/link_linux.go b/vendor/github.com/vishvananda/netlink/link_linux.go
index c02fa63b8..3b959299c 100644
--- a/vendor/github.com/vishvananda/netlink/link_linux.go
+++ b/vendor/github.com/vishvananda/netlink/link_linux.go
@@ -34,6 +34,21 @@ const (
TUNTAP_MULTI_QUEUE_DEFAULTS TuntapFlag = TUNTAP_MULTI_QUEUE | TUNTAP_NO_PI
)
+var StringToTuntapModeMap = map[string]TuntapMode{
+ "tun": TUNTAP_MODE_TUN,
+ "tap": TUNTAP_MODE_TAP,
+}
+
+func (ttm TuntapMode) String() string {
+ switch ttm {
+ case TUNTAP_MODE_TUN:
+ return "tun"
+ case TUNTAP_MODE_TAP:
+ return "tap"
+ }
+ return "unknown"
+}
+
const (
VF_LINK_STATE_AUTO uint32 = 0
VF_LINK_STATE_ENABLE uint32 = 1
@@ -1046,8 +1061,8 @@ func addBondAttrs(bond *Bond, linkInfo *nl.RtAttr) {
if bond.LpInterval >= 0 {
data.AddRtAttr(nl.IFLA_BOND_LP_INTERVAL, nl.Uint32Attr(uint32(bond.LpInterval)))
}
- if bond.PackersPerSlave >= 0 {
- data.AddRtAttr(nl.IFLA_BOND_PACKETS_PER_SLAVE, nl.Uint32Attr(uint32(bond.PackersPerSlave)))
+ if bond.PacketsPerSlave >= 0 {
+ data.AddRtAttr(nl.IFLA_BOND_PACKETS_PER_SLAVE, nl.Uint32Attr(uint32(bond.PacketsPerSlave)))
}
if bond.LacpRate >= 0 {
data.AddRtAttr(nl.IFLA_BOND_AD_LACP_RATE, nl.Uint8Attr(uint8(bond.LacpRate)))
@@ -1404,6 +1419,8 @@ func (h *Handle) linkModify(link Link, flags int) error {
data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
data.AddRtAttr(nl.IFLA_MACVLAN_MODE, nl.Uint32Attr(macvlanModes[link.Mode]))
}
+ case *Geneve:
+ addGeneveAttrs(link, linkInfo)
case *Gretap:
addGretapAttrs(link, linkInfo)
case *Iptun:
@@ -1667,6 +1684,8 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
link = &Macvlan{}
case "macvtap":
link = &Macvtap{}
+ case "geneve":
+ link = &Geneve{}
case "gretap":
link = &Gretap{}
case "ip6gretap":
@@ -1693,6 +1712,8 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
link = &Tuntap{}
case "ipoib":
link = &IPoIB{}
+ case "can":
+ link = &Can{}
default:
link = &GenericLink{LinkType: linkType}
}
@@ -1714,6 +1735,8 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
parseMacvlanData(link, data)
case "macvtap":
parseMacvtapData(link, data)
+ case "geneve":
+ parseGeneveData(link, data)
case "gretap":
parseGretapData(link, data)
case "ip6gretap":
@@ -1742,6 +1765,8 @@ func LinkDeserialize(hdr *unix.NlMsghdr, m []byte) (Link, error) {
parseTuntapData(link, data)
case "ipoib":
parseIPoIBData(link, data)
+ case "can":
+ parseCanData(link, data)
}
case nl.IFLA_INFO_SLAVE_KIND:
slaveType = string(info.Value[:len(info.Value)-1])
@@ -2299,7 +2324,7 @@ func parseBondData(link Link, data []syscall.NetlinkRouteAttr) {
case nl.IFLA_BOND_LP_INTERVAL:
bond.LpInterval = int(native.Uint32(data[i].Value[0:4]))
case nl.IFLA_BOND_PACKETS_PER_SLAVE:
- bond.PackersPerSlave = int(native.Uint32(data[i].Value[0:4]))
+ bond.PacketsPerSlave = int(native.Uint32(data[i].Value[0:4]))
case nl.IFLA_BOND_AD_LACP_RATE:
bond.LacpRate = BondLacpRate(data[i].Value[0])
case nl.IFLA_BOND_AD_SELECT:
@@ -2448,6 +2473,58 @@ func linkFlags(rawFlags uint32) net.Flags {
return f
}
+func addGeneveAttrs(geneve *Geneve, linkInfo *nl.RtAttr) {
+ data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
+
+ if geneve.FlowBased {
+ // In flow based mode, no other attributes need to be configured
+ linkInfo.AddRtAttr(nl.IFLA_GENEVE_COLLECT_METADATA, boolAttr(geneve.FlowBased))
+ return
+ }
+
+ if ip := geneve.Remote; ip != nil {
+ if ip4 := ip.To4(); ip4 != nil {
+ data.AddRtAttr(nl.IFLA_GENEVE_REMOTE, ip.To4())
+ } else {
+ data.AddRtAttr(nl.IFLA_GENEVE_REMOTE6, []byte(ip))
+ }
+ }
+
+ if geneve.ID != 0 {
+ data.AddRtAttr(nl.IFLA_GENEVE_ID, nl.Uint32Attr(geneve.ID))
+ }
+
+ if geneve.Dport != 0 {
+ data.AddRtAttr(nl.IFLA_GENEVE_PORT, htons(geneve.Dport))
+ }
+
+ if geneve.Ttl != 0 {
+ data.AddRtAttr(nl.IFLA_GENEVE_TTL, nl.Uint8Attr(geneve.Ttl))
+ }
+
+ if geneve.Tos != 0 {
+ data.AddRtAttr(nl.IFLA_GENEVE_TOS, nl.Uint8Attr(geneve.Tos))
+ }
+}
+
+func parseGeneveData(link Link, data []syscall.NetlinkRouteAttr) {
+ geneve := link.(*Geneve)
+ for _, datum := range data {
+ switch datum.Attr.Type {
+ case nl.IFLA_GENEVE_ID:
+ geneve.ID = native.Uint32(datum.Value[0:4])
+ case nl.IFLA_GENEVE_REMOTE, nl.IFLA_GENEVE_REMOTE6:
+ geneve.Remote = datum.Value
+ case nl.IFLA_GENEVE_PORT:
+ geneve.Dport = ntohs(datum.Value[0:2])
+ case nl.IFLA_GENEVE_TTL:
+ geneve.Ttl = uint8(datum.Value[0])
+ case nl.IFLA_GENEVE_TOS:
+ geneve.Tos = uint8(datum.Value[0])
+ }
+ }
+}
+
func addGretapAttrs(gretap *Gretap, linkInfo *nl.RtAttr) {
data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
@@ -3172,6 +3249,54 @@ func parseIPoIBData(link Link, data []syscall.NetlinkRouteAttr) {
}
}
+func parseCanData(link Link, data []syscall.NetlinkRouteAttr) {
+ can := link.(*Can)
+ for _, datum := range data {
+
+ switch datum.Attr.Type {
+ case nl.IFLA_CAN_BITTIMING:
+ can.BitRate = native.Uint32(datum.Value)
+ can.SamplePoint = native.Uint32(datum.Value[4:])
+ can.TimeQuanta = native.Uint32(datum.Value[8:])
+ can.PropagationSegment = native.Uint32(datum.Value[12:])
+ can.PhaseSegment1 = native.Uint32(datum.Value[16:])
+ can.PhaseSegment2 = native.Uint32(datum.Value[20:])
+ can.SyncJumpWidth = native.Uint32(datum.Value[24:])
+ can.BitRatePreScaler = native.Uint32(datum.Value[28:])
+ case nl.IFLA_CAN_BITTIMING_CONST:
+ can.Name = string(datum.Value[:16])
+ can.TimeSegment1Min = native.Uint32(datum.Value[16:])
+ can.TimeSegment1Max = native.Uint32(datum.Value[20:])
+ can.TimeSegment2Min = native.Uint32(datum.Value[24:])
+ can.TimeSegment2Max = native.Uint32(datum.Value[28:])
+ can.SyncJumpWidthMax = native.Uint32(datum.Value[32:])
+ can.BitRatePreScalerMin = native.Uint32(datum.Value[36:])
+ can.BitRatePreScalerMax = native.Uint32(datum.Value[40:])
+ can.BitRatePreScalerInc = native.Uint32(datum.Value[44:])
+ case nl.IFLA_CAN_CLOCK:
+ can.ClockFrequency = native.Uint32(datum.Value)
+ case nl.IFLA_CAN_STATE:
+ can.State = native.Uint32(datum.Value)
+ case nl.IFLA_CAN_CTRLMODE:
+ can.Mask = native.Uint32(datum.Value)
+ can.Flags = native.Uint32(datum.Value[4:])
+ case nl.IFLA_CAN_BERR_COUNTER:
+ can.TxError = native.Uint16(datum.Value)
+ can.RxError = native.Uint16(datum.Value[2:])
+ case nl.IFLA_CAN_RESTART_MS:
+ can.RestartMs = native.Uint32(datum.Value)
+ case nl.IFLA_CAN_DATA_BITTIMING_CONST:
+ case nl.IFLA_CAN_RESTART:
+ case nl.IFLA_CAN_DATA_BITTIMING:
+ case nl.IFLA_CAN_TERMINATION:
+ case nl.IFLA_CAN_TERMINATION_CONST:
+ case nl.IFLA_CAN_BITRATE_CONST:
+ case nl.IFLA_CAN_DATA_BITRATE_CONST:
+ case nl.IFLA_CAN_BITRATE_MAX:
+ }
+ }
+}
+
func addIPoIBAttrs(ipoib *IPoIB, linkInfo *nl.RtAttr) {
data := linkInfo.AddRtAttr(nl.IFLA_INFO_DATA, nil)
data.AddRtAttr(nl.IFLA_IPOIB_PKEY, nl.Uint16Attr(uint16(ipoib.Pkey)))
diff --git a/vendor/github.com/vishvananda/netlink/nl/devlink_linux.go b/vendor/github.com/vishvananda/netlink/nl/devlink_linux.go
index db66faaad..aa6155e21 100644
--- a/vendor/github.com/vishvananda/netlink/nl/devlink_linux.go
+++ b/vendor/github.com/vishvananda/netlink/nl/devlink_linux.go
@@ -10,6 +10,7 @@ const (
const (
DEVLINK_CMD_GET = 1
+ DEVLINK_CMD_PORT_GET = 5
DEVLINK_CMD_ESWITCH_GET = 29
DEVLINK_CMD_ESWITCH_SET = 30
)
@@ -17,9 +18,15 @@ const (
const (
DEVLINK_ATTR_BUS_NAME = 1
DEVLINK_ATTR_DEV_NAME = 2
+ DEVLINK_ATTR_PORT_INDEX = 3
+ DEVLINK_ATTR_PORT_TYPE = 4
+ DEVLINK_ATTR_PORT_NETDEV_IFINDEX = 6
+ DEVLINK_ATTR_PORT_NETDEV_NAME = 7
+ DEVLINK_ATTR_PORT_IBDEV_NAME = 8
DEVLINK_ATTR_ESWITCH_MODE = 25
DEVLINK_ATTR_ESWITCH_INLINE_MODE = 26
DEVLINK_ATTR_ESWITCH_ENCAP_MODE = 62
+ DEVLINK_ATTR_PORT_FLAVOUR = 77
)
const (
@@ -38,3 +45,19 @@ const (
DEVLINK_ESWITCH_ENCAP_MODE_NONE = 0
DEVLINK_ESWITCH_ENCAP_MODE_BASIC = 1
)
+
+const (
+ DEVLINK_PORT_FLAVOUR_PHYSICAL = 0
+ DEVLINK_PORT_FLAVOUR_CPU = 1
+ DEVLINK_PORT_FLAVOUR_DSA = 2
+ DEVLINK_PORT_FLAVOUR_PCI_PF = 3
+ DEVLINK_PORT_FLAVOUR_PCI_VF = 4
+ DEVLINK_PORT_FLAVOUR_VIRTUAL = 5
+)
+
+const (
+ DEVLINK_PORT_TYPE_NOTSET = 0
+ DEVLINK_PORT_TYPE_AUTO = 1
+ DEVLINK_PORT_TYPE_ETH = 2
+ DEVLINK_PORT_TYPE_IB = 3
+)
diff --git a/vendor/github.com/vishvananda/netlink/nl/link_linux.go b/vendor/github.com/vishvananda/netlink/nl/link_linux.go
index faee2fa03..c72cc436e 100644
--- a/vendor/github.com/vishvananda/netlink/nl/link_linux.go
+++ b/vendor/github.com/vishvananda/netlink/nl/link_linux.go
@@ -174,6 +174,22 @@ const (
)
const (
+ IFLA_GENEVE_UNSPEC = iota
+ IFLA_GENEVE_ID // vni
+ IFLA_GENEVE_REMOTE
+ IFLA_GENEVE_TTL
+ IFLA_GENEVE_TOS
+ IFLA_GENEVE_PORT // destination port
+ IFLA_GENEVE_COLLECT_METADATA
+ IFLA_GENEVE_REMOTE6
+ IFLA_GENEVE_UDP_CSUM
+ IFLA_GENEVE_UDP_ZERO_CSUM6_TX
+ IFLA_GENEVE_UDP_ZERO_CSUM6_RX
+ IFLA_GENEVE_LABEL
+ IFLA_GENEVE_MAX = IFLA_GENEVE_LABEL
+)
+
+const (
IFLA_GRE_UNSPEC = iota
IFLA_GRE_LINK
IFLA_GRE_IFLAGS
@@ -673,3 +689,23 @@ const (
IFLA_IPOIB_UMCAST
IFLA_IPOIB_MAX = IFLA_IPOIB_UMCAST
)
+
+const (
+ IFLA_CAN_UNSPEC = iota
+ IFLA_CAN_BITTIMING
+ IFLA_CAN_BITTIMING_CONST
+ IFLA_CAN_CLOCK
+ IFLA_CAN_STATE
+ IFLA_CAN_CTRLMODE
+ IFLA_CAN_RESTART_MS
+ IFLA_CAN_RESTART
+ IFLA_CAN_BERR_COUNTER
+ IFLA_CAN_DATA_BITTIMING
+ IFLA_CAN_DATA_BITTIMING_CONST
+ IFLA_CAN_TERMINATION
+ IFLA_CAN_TERMINATION_CONST
+ IFLA_CAN_BITRATE_CONST
+ IFLA_CAN_DATA_BITRATE_CONST
+ IFLA_CAN_BITRATE_MAX
+ IFLA_CAN_MAX = IFLA_CAN_BITRATE_MAX
+)
diff --git a/vendor/github.com/vishvananda/netlink/nl/nl_linux.go b/vendor/github.com/vishvananda/netlink/nl/nl_linux.go
index cef64b82e..dcd4b9469 100644
--- a/vendor/github.com/vishvananda/netlink/nl/nl_linux.go
+++ b/vendor/github.com/vishvananda/netlink/nl/nl_linux.go
@@ -35,6 +35,9 @@ var SupportedNlFamilies = []int{unix.NETLINK_ROUTE, unix.NETLINK_XFRM, unix.NETL
var nextSeqNr uint32
+// Default netlink socket timeout, 60s
+var SocketTimeoutTv = unix.Timeval{Sec: 60, Usec: 0}
+
// GetIPFamily returns the family type of a net.IP.
func GetIPFamily(ip net.IP) int {
if len(ip) <= net.IPv4len {
@@ -426,6 +429,14 @@ func (req *NetlinkRequest) Execute(sockType int, resType uint16) ([][]byte, erro
if err != nil {
return nil, err
}
+
+ if err := s.SetSendTimeout(&SocketTimeoutTv); err != nil {
+ return nil, err
+ }
+ if err := s.SetReceiveTimeout(&SocketTimeoutTv); err != nil {
+ return nil, err
+ }
+
defer s.Close()
} else {
s.Lock()
diff --git a/vendor/github.com/vishvananda/netlink/nl/parse_attr.go b/vendor/github.com/vishvananda/netlink/nl/parse_attr_linux.go
index 19eb8f28e..7f49125cf 100644
--- a/vendor/github.com/vishvananda/netlink/nl/parse_attr.go
+++ b/vendor/github.com/vishvananda/netlink/nl/parse_attr_linux.go
@@ -3,6 +3,7 @@ package nl
import (
"encoding/binary"
"fmt"
+ "log"
)
type Attribute struct {
@@ -18,9 +19,20 @@ func ParseAttributes(data []byte) <-chan Attribute {
i := 0
for i+4 < len(data) {
length := int(native.Uint16(data[i : i+2]))
+ attrType := native.Uint16(data[i+2 : i+4])
+
+ if length < 4 {
+ log.Printf("attribute 0x%02x has invalid length of %d bytes", attrType, length)
+ break
+ }
+
+ if len(data) < i+length {
+ log.Printf("attribute 0x%02x of length %d is truncated, only %d bytes remaining", attrType, length, len(data)-i)
+ break
+ }
result <- Attribute{
- Type: native.Uint16(data[i+2 : i+4]),
+ Type: attrType,
Value: data[i+4 : i+length],
}
i += rtaAlignOf(length)
diff --git a/vendor/github.com/vishvananda/netlink/qdisc.go b/vendor/github.com/vishvananda/netlink/qdisc.go
index 8418569ee..f594c9c21 100644
--- a/vendor/github.com/vishvananda/netlink/qdisc.go
+++ b/vendor/github.com/vishvananda/netlink/qdisc.go
@@ -308,13 +308,15 @@ func (qdisc *Fq) Type() string {
// FQ_Codel (Fair Queuing Controlled Delay) is queuing discipline that combines Fair Queuing with the CoDel AQM scheme.
type FqCodel struct {
QdiscAttrs
- Target uint32
- Limit uint32
- Interval uint32
- ECN uint32
- Flows uint32
- Quantum uint32
- // There are some more attributes here, but support for them seems not ubiquitous
+ Target uint32
+ Limit uint32
+ Interval uint32
+ ECN uint32
+ Flows uint32
+ Quantum uint32
+ CEThreshold uint32
+ DropBatchSize uint32
+ MemoryLimit uint32
}
func (fqcodel *FqCodel) String() string {
diff --git a/vendor/github.com/vishvananda/netlink/qdisc_linux.go b/vendor/github.com/vishvananda/netlink/qdisc_linux.go
index d0e1ca194..edc4b726a 100644
--- a/vendor/github.com/vishvananda/netlink/qdisc_linux.go
+++ b/vendor/github.com/vishvananda/netlink/qdisc_linux.go
@@ -250,7 +250,15 @@ func qdiscPayload(req *nl.NetlinkRequest, qdisc Qdisc) error {
if qdisc.Quantum > 0 {
options.AddRtAttr(nl.TCA_FQ_CODEL_QUANTUM, nl.Uint32Attr((uint32(qdisc.Quantum))))
}
-
+ if qdisc.CEThreshold > 0 {
+ options.AddRtAttr(nl.TCA_FQ_CODEL_CE_THRESHOLD, nl.Uint32Attr(qdisc.CEThreshold))
+ }
+ if qdisc.DropBatchSize > 0 {
+ options.AddRtAttr(nl.TCA_FQ_CODEL_DROP_BATCH_SIZE, nl.Uint32Attr(qdisc.DropBatchSize))
+ }
+ if qdisc.MemoryLimit > 0 {
+ options.AddRtAttr(nl.TCA_FQ_CODEL_MEMORY_LIMIT, nl.Uint32Attr(qdisc.MemoryLimit))
+ }
case *Fq:
options.AddRtAttr(nl.TCA_FQ_RATE_ENABLE, nl.Uint32Attr((uint32(qdisc.Pacing))))
@@ -497,6 +505,12 @@ func parseFqCodelData(qdisc Qdisc, data []syscall.NetlinkRouteAttr) error {
fqCodel.Flows = native.Uint32(datum.Value)
case nl.TCA_FQ_CODEL_QUANTUM:
fqCodel.Quantum = native.Uint32(datum.Value)
+ case nl.TCA_FQ_CODEL_CE_THRESHOLD:
+ fqCodel.CEThreshold = native.Uint32(datum.Value)
+ case nl.TCA_FQ_CODEL_DROP_BATCH_SIZE:
+ fqCodel.DropBatchSize = native.Uint32(datum.Value)
+ case nl.TCA_FQ_CODEL_MEMORY_LIMIT:
+ fqCodel.MemoryLimit = native.Uint32(datum.Value)
}
}
return nil
diff --git a/vendor/github.com/vishvananda/netlink/route.go b/vendor/github.com/vishvananda/netlink/route.go
index b16254174..845f41808 100644
--- a/vendor/github.com/vishvananda/netlink/route.go
+++ b/vendor/github.com/vishvananda/netlink/route.go
@@ -27,6 +27,9 @@ type Encap interface {
Equal(Encap) bool
}
+//Protocol describe what was the originator of the route
+type RouteProtocol int
+
// Route represents a netlink route.
type Route struct {
LinkIndex int
@@ -36,7 +39,7 @@ type Route struct {
Src net.IP
Gw net.IP
MultiPath []*NexthopInfo
- Protocol int
+ Protocol RouteProtocol
Priority int
Table int
Type int
@@ -45,6 +48,7 @@ type Route struct {
MPLSDst *int
NewDst Destination
Encap Encap
+ Via Destination
MTU int
Window int
Rtt int
@@ -79,6 +83,9 @@ func (r Route) String() string {
if r.Encap != nil {
elems = append(elems, fmt.Sprintf("Encap: %s", r.Encap))
}
+ if r.Via != nil {
+ elems = append(elems, fmt.Sprintf("Via: %s", r.Via))
+ }
elems = append(elems, fmt.Sprintf("Src: %s", r.Src))
if len(r.MultiPath) > 0 {
elems = append(elems, fmt.Sprintf("Gw: %s", r.MultiPath))
@@ -107,6 +114,7 @@ func (r Route) Equal(x Route) bool {
r.Flags == x.Flags &&
(r.MPLSDst == x.MPLSDst || (r.MPLSDst != nil && x.MPLSDst != nil && *r.MPLSDst == *x.MPLSDst)) &&
(r.NewDst == x.NewDst || (r.NewDst != nil && r.NewDst.Equal(x.NewDst))) &&
+ (r.Via == x.Via || (r.Via != nil && r.Via.Equal(x.Via))) &&
(r.Encap == x.Encap || (r.Encap != nil && r.Encap.Equal(x.Encap)))
}
@@ -136,6 +144,7 @@ type NexthopInfo struct {
Flags int
NewDst Destination
Encap Encap
+ Via Destination
}
func (n *NexthopInfo) String() string {
@@ -147,6 +156,9 @@ func (n *NexthopInfo) String() string {
if n.Encap != nil {
elems = append(elems, fmt.Sprintf("Encap: %s", n.Encap))
}
+ if n.Via != nil {
+ elems = append(elems, fmt.Sprintf("Via: %s", n.Via))
+ }
elems = append(elems, fmt.Sprintf("Weight: %d", n.Hops+1))
elems = append(elems, fmt.Sprintf("Gw: %s", n.Gw))
elems = append(elems, fmt.Sprintf("Flags: %s", n.ListFlags()))
diff --git a/vendor/github.com/vishvananda/netlink/route_linux.go b/vendor/github.com/vishvananda/netlink/route_linux.go
index 4e778a417..32641cb0d 100644
--- a/vendor/github.com/vishvananda/netlink/route_linux.go
+++ b/vendor/github.com/vishvananda/netlink/route_linux.go
@@ -1,8 +1,11 @@
package netlink
import (
+ "bytes"
+ "encoding/binary"
"fmt"
"net"
+ "strconv"
"strings"
"syscall"
@@ -21,6 +24,23 @@ const (
SCOPE_NOWHERE Scope = unix.RT_SCOPE_NOWHERE
)
+func (s Scope) String() string {
+ switch s {
+ case SCOPE_UNIVERSE:
+ return "universe"
+ case SCOPE_SITE:
+ return "site"
+ case SCOPE_LINK:
+ return "link"
+ case SCOPE_HOST:
+ return "host"
+ case SCOPE_NOWHERE:
+ return "nowhere"
+ default:
+ return "unknown"
+ }
+}
+
const (
RT_FILTER_PROTOCOL uint64 = 1 << (1 + iota)
RT_FILTER_SCOPE
@@ -446,6 +466,62 @@ func (e *SEG6LocalEncap) Equal(x Encap) bool {
return true
}
+type Via struct {
+ AddrFamily int
+ Addr net.IP
+}
+
+func (v *Via) Equal(x Destination) bool {
+ o, ok := x.(*Via)
+ if !ok {
+ return false
+ }
+ if v.AddrFamily == x.Family() && v.Addr.Equal(o.Addr) {
+ return true
+ }
+ return false
+}
+
+func (v *Via) String() string {
+ return fmt.Sprintf("Family: %d, Address: %s", v.AddrFamily, v.Addr.String())
+}
+
+func (v *Via) Family() int {
+ return v.AddrFamily
+}
+
+func (v *Via) Encode() ([]byte, error) {
+ buf := &bytes.Buffer{}
+ err := binary.Write(buf, native, uint16(v.AddrFamily))
+ if err != nil {
+ return nil, err
+ }
+ err = binary.Write(buf, native, v.Addr)
+ if err != nil {
+ return nil, err
+ }
+ return buf.Bytes(), nil
+}
+
+func (v *Via) Decode(b []byte) error {
+ native := nl.NativeEndian()
+ if len(b) < 6 {
+ return fmt.Errorf("decoding failed: buffer too small (%d bytes)", len(b))
+ }
+ v.AddrFamily = int(native.Uint16(b[0:2]))
+ if v.AddrFamily == nl.FAMILY_V4 {
+ v.Addr = net.IP(b[2:6])
+ return nil
+ } else if v.AddrFamily == nl.FAMILY_V6 {
+ if len(b) < 18 {
+ return fmt.Errorf("decoding failed: buffer too small (%d bytes)", len(b))
+ }
+ v.Addr = net.IP(b[2:])
+ return nil
+ }
+ return fmt.Errorf("decoding failed: address family %d unknown", v.AddrFamily)
+}
+
// RouteAdd will add a route to the system.
// Equivalent to: `ip route add $route`
func RouteAdd(route *Route) error {
@@ -460,6 +536,32 @@ func (h *Handle) RouteAdd(route *Route) error {
return h.routeHandle(route, req, nl.NewRtMsg())
}
+// RouteAppend will append a route to the system.
+// Equivalent to: `ip route append $route`
+func RouteAppend(route *Route) error {
+ return pkgHandle.RouteAppend(route)
+}
+
+// RouteAppend will append a route to the system.
+// Equivalent to: `ip route append $route`
+func (h *Handle) RouteAppend(route *Route) error {
+ flags := unix.NLM_F_CREATE | unix.NLM_F_APPEND | unix.NLM_F_ACK
+ req := h.newNetlinkRequest(unix.RTM_NEWROUTE, flags)
+ return h.routeHandle(route, req, nl.NewRtMsg())
+}
+
+// RouteAddEcmp will add a route to the system.
+func RouteAddEcmp(route *Route) error {
+ return pkgHandle.RouteAddEcmp(route)
+}
+
+// RouteAddEcmp will add a route to the system.
+func (h *Handle) RouteAddEcmp(route *Route) error {
+ flags := unix.NLM_F_CREATE | unix.NLM_F_ACK
+ req := h.newNetlinkRequest(unix.RTM_NEWROUTE, flags)
+ return h.routeHandle(route, req, nl.NewRtMsg())
+}
+
// RouteReplace will add a route to the system.
// Equivalent to: `ip route replace $route`
func RouteReplace(route *Route) error {
@@ -567,6 +669,14 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_GATEWAY, gwData))
}
+ if route.Via != nil {
+ buf, err := route.Via.Encode()
+ if err != nil {
+ return fmt.Errorf("failed to encode RTA_VIA: %v", err)
+ }
+ rtAttrs = append(rtAttrs, nl.NewRtAttr(unix.RTA_VIA, buf))
+ }
+
if len(route.MultiPath) > 0 {
buf := []byte{}
for _, nh := range route.MultiPath {
@@ -609,6 +719,13 @@ func (h *Handle) routeHandle(route *Route, req *nl.NetlinkRequest, msg *nl.RtMsg
}
children = append(children, nl.NewRtAttr(unix.RTA_ENCAP, buf))
}
+ if nh.Via != nil {
+ buf, err := nh.Via.Encode()
+ if err != nil {
+ return err
+ }
+ children = append(children, nl.NewRtAttr(unix.RTA_VIA, buf))
+ }
rtnh.Children = children
buf = append(buf, rtnh.Serialize()...)
}
@@ -834,7 +951,7 @@ func deserializeRoute(m []byte) (Route, error) {
}
route := Route{
Scope: Scope(msg.Scope),
- Protocol: int(msg.Protocol),
+ Protocol: RouteProtocol(int(msg.Protocol)),
Table: int(msg.Table),
Type: int(msg.Type),
Tos: int(msg.Tos),
@@ -907,6 +1024,12 @@ func deserializeRoute(m []byte) (Route, error) {
encapType = attr
case unix.RTA_ENCAP:
encap = attr
+ case unix.RTA_VIA:
+ d := &Via{}
+ if err := d.Decode(attr.Value); err != nil {
+ return nil, nil, err
+ }
+ info.Via = d
}
}
@@ -944,6 +1067,12 @@ func deserializeRoute(m []byte) (Route, error) {
return route, err
}
route.NewDst = d
+ case unix.RTA_VIA:
+ v := &Via{}
+ if err := v.Decode(attr.Value); err != nil {
+ return route, err
+ }
+ route.Via = v
case unix.RTA_ENCAP_TYPE:
encapType = attr
case unix.RTA_ENCAP:
@@ -1022,6 +1151,7 @@ func deserializeRoute(m []byte) (Route, error) {
// RouteGetWithOptions
type RouteGetOptions struct {
VrfName string
+ SrcAddr net.IP
}
// RouteGetWithOptions gets a route to a specific destination from the host system.
@@ -1053,23 +1183,40 @@ func (h *Handle) RouteGetWithOptions(destination net.IP, options *RouteGetOption
msg := &nl.RtMsg{}
msg.Family = uint8(family)
msg.Dst_len = bitlen
+ if options != nil && options.SrcAddr != nil {
+ msg.Src_len = bitlen
+ }
+ msg.Flags = unix.RTM_F_LOOKUP_TABLE
req.AddData(msg)
rtaDst := nl.NewRtAttr(unix.RTA_DST, destinationData)
req.AddData(rtaDst)
if options != nil {
- link, err := LinkByName(options.VrfName)
- if err != nil {
- return nil, err
+ if options.VrfName != "" {
+ link, err := LinkByName(options.VrfName)
+ if err != nil {
+ return nil, err
+ }
+ var (
+ b = make([]byte, 4)
+ native = nl.NativeEndian()
+ )
+ native.PutUint32(b, uint32(link.Attrs().Index))
+
+ req.AddData(nl.NewRtAttr(unix.RTA_OIF, b))
}
- var (
- b = make([]byte, 4)
- native = nl.NativeEndian()
- )
- native.PutUint32(b, uint32(link.Attrs().Index))
- req.AddData(nl.NewRtAttr(unix.RTA_OIF, b))
+ if options.SrcAddr != nil {
+ var srcAddr []byte
+ if family == FAMILY_V4 {
+ srcAddr = options.SrcAddr.To4()
+ } else {
+ srcAddr = options.SrcAddr.To16()
+ }
+
+ req.AddData(nl.NewRtAttr(unix.RTA_SRC, srcAddr))
+ }
}
msgs, err := req.Execute(unix.NETLINK_ROUTE, unix.RTM_NEWROUTE)
@@ -1190,3 +1337,54 @@ func routeSubscribeAt(newNs, curNs netns.NsHandle, ch chan<- RouteUpdate, done <
return nil
}
+
+func (p RouteProtocol) String() string {
+ switch int(p) {
+ case unix.RTPROT_BABEL:
+ return "babel"
+ case unix.RTPROT_BGP:
+ return "bgp"
+ case unix.RTPROT_BIRD:
+ return "bird"
+ case unix.RTPROT_BOOT:
+ return "boot"
+ case unix.RTPROT_DHCP:
+ return "dhcp"
+ case unix.RTPROT_DNROUTED:
+ return "dnrouted"
+ case unix.RTPROT_EIGRP:
+ return "eigrp"
+ case unix.RTPROT_GATED:
+ return "gated"
+ case unix.RTPROT_ISIS:
+ return "isis"
+ //case unix.RTPROT_KEEPALIVED:
+ // return "keepalived"
+ case unix.RTPROT_KERNEL:
+ return "kernel"
+ case unix.RTPROT_MROUTED:
+ return "mrouted"
+ case unix.RTPROT_MRT:
+ return "mrt"
+ case unix.RTPROT_NTK:
+ return "ntk"
+ case unix.RTPROT_OSPF:
+ return "ospf"
+ case unix.RTPROT_RA:
+ return "ra"
+ case unix.RTPROT_REDIRECT:
+ return "redirect"
+ case unix.RTPROT_RIP:
+ return "rip"
+ case unix.RTPROT_STATIC:
+ return "static"
+ case unix.RTPROT_UNSPEC:
+ return "unspec"
+ case unix.RTPROT_XORP:
+ return "xorp"
+ case unix.RTPROT_ZEBRA:
+ return "zebra"
+ default:
+ return strconv.Itoa(int(p))
+ }
+}
diff --git a/vendor/github.com/vishvananda/netlink/route_unspecified.go b/vendor/github.com/vishvananda/netlink/route_unspecified.go
index 2701862b4..db7372689 100644
--- a/vendor/github.com/vishvananda/netlink/route_unspecified.go
+++ b/vendor/github.com/vishvananda/netlink/route_unspecified.go
@@ -2,6 +2,8 @@
package netlink
+import "strconv"
+
func (r *Route) ListFlags() []string {
return []string{}
}
@@ -9,3 +11,11 @@ func (r *Route) ListFlags() []string {
func (n *NexthopInfo) ListFlags() []string {
return []string{}
}
+
+func (s Scope) String() string {
+ return "unknown"
+}
+
+func (p RouteProtocol) String() string {
+ return strconv.Itoa(int(p))
+}
diff --git a/vendor/github.com/vishvananda/netlink/socket_linux.go b/vendor/github.com/vishvananda/netlink/socket_linux.go
index e4e7f7ac3..9b0f4a081 100644
--- a/vendor/github.com/vishvananda/netlink/socket_linux.go
+++ b/vendor/github.com/vishvananda/netlink/socket_linux.go
@@ -184,7 +184,7 @@ func SocketDiagTCPInfo(family uint8) ([]*InetDiagTCPInfoResp, error) {
req.AddData(&socketRequest{
Family: family,
Protocol: unix.IPPROTO_TCP,
- Ext: INET_DIAG_INFO,
+ Ext: (1 << (INET_DIAG_VEGASINFO - 1)) | (1 << (INET_DIAG_INFO - 1)),
States: uint32(0xfff), // All TCP states
})
s.Send(req)
@@ -220,19 +220,42 @@ loop:
if err != nil {
return nil, err
}
- var tcpInfo *TCPInfo
- for _, a := range attrs {
- if a.Attr.Type == INET_DIAG_INFO {
- tcpInfo = &TCPInfo{}
- if err := tcpInfo.deserialize(a.Value); err != nil {
- return nil, err
- }
- break
- }
+
+ res, err := attrsToInetDiagTCPInfoResp(attrs, sockInfo)
+ if err != nil {
+ return nil, err
}
- r := &InetDiagTCPInfoResp{InetDiagMsg: sockInfo, TCPInfo: tcpInfo}
- result = append(result, r)
+
+ result = append(result, res)
}
}
return result, nil
}
+
+func attrsToInetDiagTCPInfoResp(attrs []syscall.NetlinkRouteAttr, sockInfo *Socket) (*InetDiagTCPInfoResp, error) {
+ var tcpInfo *TCPInfo
+ var tcpBBRInfo *TCPBBRInfo
+ for _, a := range attrs {
+ if a.Attr.Type == INET_DIAG_INFO {
+ tcpInfo = &TCPInfo{}
+ if err := tcpInfo.deserialize(a.Value); err != nil {
+ return nil, err
+ }
+ continue
+ }
+
+ if a.Attr.Type == INET_DIAG_BBRINFO {
+ tcpBBRInfo = &TCPBBRInfo{}
+ if err := tcpBBRInfo.deserialize(a.Value); err != nil {
+ return nil, err
+ }
+ continue
+ }
+ }
+
+ return &InetDiagTCPInfoResp{
+ InetDiagMsg: sockInfo,
+ TCPInfo: tcpInfo,
+ TCPBBRInfo: tcpBBRInfo,
+ }, nil
+}
diff --git a/vendor/github.com/vishvananda/netlink/tcp.go b/vendor/github.com/vishvananda/netlink/tcp.go
index 4a42ee5a6..23ca014d4 100644
--- a/vendor/github.com/vishvananda/netlink/tcp.go
+++ b/vendor/github.com/vishvananda/netlink/tcp.go
@@ -16,3 +16,69 @@ const (
TCP_NEW_SYN_REC
TCP_MAX_STATES
)
+
+type TCPInfo struct {
+ State uint8
+ Ca_state uint8
+ Retransmits uint8
+ Probes uint8
+ Backoff uint8
+ Options uint8
+ Snd_wscale uint8 // no uint4
+ Rcv_wscale uint8
+ Delivery_rate_app_limited uint8
+ Fastopen_client_fail uint8
+ Rto uint32
+ Ato uint32
+ Snd_mss uint32
+ Rcv_mss uint32
+ Unacked uint32
+ Sacked uint32
+ Lost uint32
+ Retrans uint32
+ Fackets uint32
+ Last_data_sent uint32
+ Last_ack_sent uint32
+ Last_data_recv uint32
+ Last_ack_recv uint32
+ Pmtu uint32
+ Rcv_ssthresh uint32
+ Rtt uint32
+ Rttvar uint32
+ Snd_ssthresh uint32
+ Snd_cwnd uint32
+ Advmss uint32
+ Reordering uint32
+ Rcv_rtt uint32
+ Rcv_space uint32
+ Total_retrans uint32
+ Pacing_rate uint64
+ Max_pacing_rate uint64
+ Bytes_acked uint64 /* RFC4898 tcpEStatsAppHCThruOctetsAcked */
+ Bytes_received uint64 /* RFC4898 tcpEStatsAppHCThruOctetsReceived */
+ Segs_out uint32 /* RFC4898 tcpEStatsPerfSegsOut */
+ Segs_in uint32 /* RFC4898 tcpEStatsPerfSegsIn */
+ Notsent_bytes uint32
+ Min_rtt uint32
+ Data_segs_in uint32 /* RFC4898 tcpEStatsDataSegsIn */
+ Data_segs_out uint32 /* RFC4898 tcpEStatsDataSegsOut */
+ Delivery_rate uint64
+ Busy_time uint64 /* Time (usec) busy sending data */
+ Rwnd_limited uint64 /* Time (usec) limited by receive window */
+ Sndbuf_limited uint64 /* Time (usec) limited by send buffer */
+ Delivered uint32
+ Delivered_ce uint32
+ Bytes_sent uint64 /* RFC4898 tcpEStatsPerfHCDataOctetsOut */
+ Bytes_retrans uint64 /* RFC4898 tcpEStatsPerfOctetsRetrans */
+ Dsack_dups uint32 /* RFC4898 tcpEStatsStackDSACKDups */
+ Reord_seen uint32 /* reordering events seen */
+ Rcv_ooopack uint32 /* Out-of-order packets received */
+ Snd_wnd uint32 /* peer's advertised receive window after * scaling (bytes) */
+}
+
+type TCPBBRInfo struct {
+ BBRBW uint64
+ BBRMinRTT uint32
+ BBRPacingGain uint32
+ BBRCwndGain uint32
+}
diff --git a/vendor/github.com/vishvananda/netlink/tcp_linux.go b/vendor/github.com/vishvananda/netlink/tcp_linux.go
index 741ea1655..293858738 100644
--- a/vendor/github.com/vishvananda/netlink/tcp_linux.go
+++ b/vendor/github.com/vishvananda/netlink/tcp_linux.go
@@ -2,67 +2,13 @@ package netlink
import (
"bytes"
+ "errors"
"io"
)
-type TCPInfo struct {
- State uint8
- Ca_state uint8
- Retransmits uint8
- Probes uint8
- Backoff uint8
- Options uint8
- Snd_wscale uint8 // no uint4
- Rcv_wscale uint8
- Delivery_rate_app_limited uint8
- Fastopen_client_fail uint8
- Rto uint32
- Ato uint32
- Snd_mss uint32
- Rcv_mss uint32
- Unacked uint32
- Sacked uint32
- Lost uint32
- Retrans uint32
- Fackets uint32
- Last_data_sent uint32
- Last_ack_sent uint32
- Last_data_recv uint32
- Last_ack_recv uint32
- Pmtu uint32
- Rcv_ssthresh uint32
- Rtt uint32
- Rttvar uint32
- Snd_ssthresh uint32
- Snd_cwnd uint32
- Advmss uint32
- Reordering uint32
- Rcv_rtt uint32
- Rcv_space uint32
- Total_retrans uint32
- Pacing_rate uint64
- Max_pacing_rate uint64
- Bytes_acked uint64 /* RFC4898 tcpEStatsAppHCThruOctetsAcked */
- Bytes_received uint64 /* RFC4898 tcpEStatsAppHCThruOctetsReceived */
- Segs_out uint32 /* RFC4898 tcpEStatsPerfSegsOut */
- Segs_in uint32 /* RFC4898 tcpEStatsPerfSegsIn */
- Notsent_bytes uint32
- Min_rtt uint32
- Data_segs_in uint32 /* RFC4898 tcpEStatsDataSegsIn */
- Data_segs_out uint32 /* RFC4898 tcpEStatsDataSegsOut */
- Delivery_rate uint64
- Busy_time uint64 /* Time (usec) busy sending data */
- Rwnd_limited uint64 /* Time (usec) limited by receive window */
- Sndbuf_limited uint64 /* Time (usec) limited by send buffer */
- Delivered uint32
- Delivered_ce uint32
- Bytes_sent uint64 /* RFC4898 tcpEStatsPerfHCDataOctetsOut */
- Bytes_retrans uint64 /* RFC4898 tcpEStatsPerfOctetsRetrans */
- Dsack_dups uint32 /* RFC4898 tcpEStatsStackDSACKDups */
- Reord_seen uint32 /* reordering events seen */
- Rcv_ooopack uint32 /* Out-of-order packets received */
- Snd_wnd uint32 /* peer's advertised receive window after * scaling (bytes) */
-}
+const (
+ tcpBBRInfoLen = 20
+)
func checkDeserErr(err error) error {
if err == io.EOF {
@@ -391,3 +337,17 @@ func (t *TCPInfo) deserialize(b []byte) error {
t.Snd_wnd = native.Uint32(next)
return nil
}
+
+func (t *TCPBBRInfo) deserialize(b []byte) error {
+ if len(b) != tcpBBRInfoLen {
+ return errors.New("Invalid length")
+ }
+
+ rb := bytes.NewBuffer(b)
+ t.BBRBW = native.Uint64(rb.Next(8))
+ t.BBRMinRTT = native.Uint32(rb.Next(4))
+ t.BBRPacingGain = native.Uint32(rb.Next(4))
+ t.BBRCwndGain = native.Uint32(rb.Next(4))
+
+ return nil
+}
diff --git a/vendor/github.com/vishvananda/netlink/xfrm_policy.go b/vendor/github.com/vishvananda/netlink/xfrm_policy.go
index 6219d2772..b7532b092 100644
--- a/vendor/github.com/vishvananda/netlink/xfrm_policy.go
+++ b/vendor/github.com/vishvananda/netlink/xfrm_policy.go
@@ -58,12 +58,13 @@ func (a PolicyAction) String() string {
// policy. These rules are matched with XfrmState to determine encryption
// and authentication algorithms.
type XfrmPolicyTmpl struct {
- Dst net.IP
- Src net.IP
- Proto Proto
- Mode Mode
- Spi int
- Reqid int
+ Dst net.IP
+ Src net.IP
+ Proto Proto
+ Mode Mode
+ Spi int
+ Reqid int
+ Optional int
}
func (t XfrmPolicyTmpl) String() string {
diff --git a/vendor/github.com/vishvananda/netlink/xfrm_policy_linux.go b/vendor/github.com/vishvananda/netlink/xfrm_policy_linux.go
index a4e132ef5..694bd74e6 100644
--- a/vendor/github.com/vishvananda/netlink/xfrm_policy_linux.go
+++ b/vendor/github.com/vishvananda/netlink/xfrm_policy_linux.go
@@ -79,6 +79,7 @@ func (h *Handle) xfrmPolicyAddOrUpdate(policy *XfrmPolicy, nlProto int) error {
userTmpl.XfrmId.Spi = nl.Swap32(uint32(tmpl.Spi))
userTmpl.Mode = uint8(tmpl.Mode)
userTmpl.Reqid = uint32(tmpl.Reqid)
+ userTmpl.Optional = uint8(tmpl.Optional)
userTmpl.Aalgos = ^uint32(0)
userTmpl.Ealgos = ^uint32(0)
userTmpl.Calgos = ^uint32(0)
@@ -247,6 +248,7 @@ func parseXfrmPolicy(m []byte, family int) (*XfrmPolicy, error) {
resTmpl.Mode = Mode(tmpl.Mode)
resTmpl.Spi = int(nl.Swap32(tmpl.XfrmId.Spi))
resTmpl.Reqid = int(tmpl.Reqid)
+ resTmpl.Optional = int(tmpl.Optional)
policy.Tmpls = append(policy.Tmpls, resTmpl)
}
case nl.XFRMA_MARK:
diff --git a/vendor/github.com/vishvananda/netlink/xfrm_state.go b/vendor/github.com/vishvananda/netlink/xfrm_state.go
index 483d8934a..19df82c76 100644
--- a/vendor/github.com/vishvananda/netlink/xfrm_state.go
+++ b/vendor/github.com/vishvananda/netlink/xfrm_state.go
@@ -94,7 +94,7 @@ type XfrmState struct {
Limits XfrmStateLimits
Statistics XfrmStateStats
Mark *XfrmMark
- OutputMark int
+ OutputMark *XfrmMark
Ifid int
Auth *XfrmStateAlgo
Crypt *XfrmStateAlgo
@@ -104,7 +104,7 @@ type XfrmState struct {
}
func (sa XfrmState) String() string {
- return fmt.Sprintf("Dst: %v, Src: %v, Proto: %s, Mode: %s, SPI: 0x%x, ReqID: 0x%x, ReplayWindow: %d, Mark: %v, OutputMark: %d, Ifid: %d, Auth: %v, Crypt: %v, Aead: %v, Encap: %v, ESN: %t",
+ return fmt.Sprintf("Dst: %v, Src: %v, Proto: %s, Mode: %s, SPI: 0x%x, ReqID: 0x%x, ReplayWindow: %d, Mark: %v, OutputMark: %v, Ifid: %d, Auth: %v, Crypt: %v, Aead: %v, Encap: %v, ESN: %t",
sa.Dst, sa.Src, sa.Proto, sa.Mode, sa.Spi, sa.Reqid, sa.ReplayWindow, sa.Mark, sa.OutputMark, sa.Ifid, sa.Auth, sa.Crypt, sa.Aead, sa.Encap, sa.ESN)
}
func (sa XfrmState) Print(stats bool) string {
diff --git a/vendor/github.com/vishvananda/netlink/xfrm_state_linux.go b/vendor/github.com/vishvananda/netlink/xfrm_state_linux.go
index 66c99423c..5b1b6c31a 100644
--- a/vendor/github.com/vishvananda/netlink/xfrm_state_linux.go
+++ b/vendor/github.com/vishvananda/netlink/xfrm_state_linux.go
@@ -158,9 +158,13 @@ func (h *Handle) xfrmStateAddOrUpdate(state *XfrmState, nlProto int) error {
out := nl.NewRtAttr(nl.XFRMA_REPLAY_ESN_VAL, writeReplayEsn(state.ReplayWindow))
req.AddData(out)
}
- if state.OutputMark != 0 {
- out := nl.NewRtAttr(nl.XFRMA_OUTPUT_MARK, nl.Uint32Attr(uint32(state.OutputMark)))
+ if state.OutputMark != nil {
+ out := nl.NewRtAttr(nl.XFRMA_SET_MARK, nl.Uint32Attr(state.OutputMark.Value))
req.AddData(out)
+ if state.OutputMark.Mask != 0 {
+ out = nl.NewRtAttr(nl.XFRMA_SET_MARK_MASK, nl.Uint32Attr(state.OutputMark.Mask))
+ req.AddData(out)
+ }
}
ifId := nl.NewRtAttr(nl.XFRMA_IF_ID, nl.Uint32Attr(uint32(state.Ifid)))
@@ -377,8 +381,19 @@ func parseXfrmState(m []byte, family int) (*XfrmState, error) {
state.Mark = new(XfrmMark)
state.Mark.Value = mark.Value
state.Mark.Mask = mark.Mask
- case nl.XFRMA_OUTPUT_MARK:
- state.OutputMark = int(native.Uint32(attr.Value))
+ case nl.XFRMA_SET_MARK:
+ if state.OutputMark == nil {
+ state.OutputMark = new(XfrmMark)
+ }
+ state.OutputMark.Value = native.Uint32(attr.Value)
+ case nl.XFRMA_SET_MARK_MASK:
+ if state.OutputMark == nil {
+ state.OutputMark = new(XfrmMark)
+ }
+ state.OutputMark.Mask = native.Uint32(attr.Value)
+ if state.OutputMark.Mask == 0xffffffff {
+ state.OutputMark.Mask = 0
+ }
case nl.XFRMA_IF_ID:
state.Ifid = int(native.Uint32(attr.Value))
}
diff --git a/vendor/github.com/vishvananda/netns/README.md b/vendor/github.com/vishvananda/netns/README.md
index 6b45cfb89..1fdb2d3e4 100644
--- a/vendor/github.com/vishvananda/netns/README.md
+++ b/vendor/github.com/vishvananda/netns/README.md
@@ -48,3 +48,14 @@ func main() {
}
```
+
+## NOTE
+
+The library can be safely used only with Go >= 1.10 due to [golang/go#20676](https://github.com/golang/go/issues/20676).
+
+After locking a goroutine to its current OS thread with `runtime.LockOSThread()`
+and changing its network namespace, any new subsequent goroutine won't be
+scheduled on that thread while it's locked. Therefore, the new goroutine
+will run in a different namespace leading to unexpected results.
+
+See [here](https://www.weave.works/blog/linux-namespaces-golang-followup) for more details.
diff --git a/vendor/github.com/vishvananda/netns/netns_linux.go b/vendor/github.com/vishvananda/netns/netns_linux.go
index c76acd087..36e64906b 100644
--- a/vendor/github.com/vishvananda/netns/netns_linux.go
+++ b/vendor/github.com/vishvananda/netns/netns_linux.go
@@ -1,4 +1,4 @@
-// +build linux
+// +build linux,go1.10
package netns
@@ -218,12 +218,18 @@ func getPidForContainer(id string) (int, error) {
filepath.Join(cgroupRoot, "system.slice", "docker-"+id+".scope", "tasks"),
// Even more recent docker versions under cgroup/systemd/docker/<id>/
filepath.Join(cgroupRoot, "..", "systemd", "docker", id, "tasks"),
- // Kubernetes with docker and CNI is even more different
+ // Kubernetes with docker and CNI is even more different. Works for BestEffort and Burstable QoS
filepath.Join(cgroupRoot, "..", "systemd", "kubepods", "*", "pod*", id, "tasks"),
- // Another flavor of containers location in recent kubernetes 1.11+
- filepath.Join(cgroupRoot, cgroupThis, "kubepods.slice", "kubepods-besteffort.slice", "*", "docker-"+id+".scope", "tasks"),
- // When runs inside of a container with recent kubernetes 1.11+
- filepath.Join(cgroupRoot, "kubepods.slice", "kubepods-besteffort.slice", "*", "docker-"+id+".scope", "tasks"),
+ // Same as above but for Guaranteed QoS
+ filepath.Join(cgroupRoot, "..", "systemd", "kubepods", "pod*", id, "tasks"),
+ // Another flavor of containers location in recent kubernetes 1.11+. Works for BestEffort and Burstable QoS
+ filepath.Join(cgroupRoot, cgroupThis, "kubepods.slice", "*.slice", "*", "docker-"+id+".scope", "tasks"),
+ // Same as above but for Guaranteed QoS
+ filepath.Join(cgroupRoot, cgroupThis, "kubepods.slice", "*", "docker-"+id+".scope", "tasks"),
+ // When runs inside of a container with recent kubernetes 1.11+. Works for BestEffort and Burstable QoS
+ filepath.Join(cgroupRoot, "kubepods.slice", "*.slice", "*", "docker-"+id+".scope", "tasks"),
+ // Same as above but for Guaranteed QoS
+ filepath.Join(cgroupRoot, "kubepods.slice", "*", "docker-"+id+".scope", "tasks"),
}
var filename string
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 5e82b9977..f7990917e 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -45,7 +45,7 @@ github.com/blang/semver
github.com/buger/goterm
# github.com/cespare/xxhash/v2 v2.1.1
github.com/cespare/xxhash/v2
-# github.com/checkpoint-restore/checkpointctl v0.0.0-20210301084134-a2024f5584e7
+# github.com/checkpoint-restore/checkpointctl v0.0.0-20210922093614-c31748bec9f2
github.com/checkpoint-restore/checkpointctl/lib
# github.com/checkpoint-restore/go-criu/v5 v5.1.0
github.com/checkpoint-restore/go-criu/v5
@@ -66,15 +66,18 @@ github.com/containerd/containerd/sys
# github.com/containerd/stargz-snapshotter/estargz v0.8.0
github.com/containerd/stargz-snapshotter/estargz
github.com/containerd/stargz-snapshotter/estargz/errorutil
-# github.com/containernetworking/cni v0.8.1
+# github.com/containernetworking/cni v1.0.1
github.com/containernetworking/cni/libcni
github.com/containernetworking/cni/pkg/invoke
github.com/containernetworking/cni/pkg/types
github.com/containernetworking/cni/pkg/types/020
-github.com/containernetworking/cni/pkg/types/current
+github.com/containernetworking/cni/pkg/types/040
+github.com/containernetworking/cni/pkg/types/100
+github.com/containernetworking/cni/pkg/types/create
+github.com/containernetworking/cni/pkg/types/internal
github.com/containernetworking/cni/pkg/utils
github.com/containernetworking/cni/pkg/version
-# github.com/containernetworking/plugins v0.9.1
+# github.com/containernetworking/plugins v1.0.1
github.com/containernetworking/plugins/pkg/ns
# github.com/containers/buildah v1.23.0
github.com/containers/buildah
@@ -614,10 +617,10 @@ github.com/vbauerster/mpb/v7
github.com/vbauerster/mpb/v7/cwriter
github.com/vbauerster/mpb/v7/decor
github.com/vbauerster/mpb/v7/internal
-# github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852
+# github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5
github.com/vishvananda/netlink
github.com/vishvananda/netlink/nl
-# github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae
+# github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f
github.com/vishvananda/netns
# github.com/xeipuuv/gojsonpointer v0.0.0-20190809123943-df4f5c81cb3b
github.com/xeipuuv/gojsonpointer