diff options
Diffstat (limited to 'vendor/github.com')
-rw-r--r-- | vendor/github.com/cri-o/ocicni/LICENSE | 191 | ||||
-rw-r--r-- | vendor/github.com/cri-o/ocicni/pkg/ocicni/ocicni.go | 870 | ||||
-rw-r--r-- | vendor/github.com/cri-o/ocicni/pkg/ocicni/types.go | 152 | ||||
-rw-r--r-- | vendor/github.com/cri-o/ocicni/pkg/ocicni/types_unix.go | 10 | ||||
-rw-r--r-- | vendor/github.com/cri-o/ocicni/pkg/ocicni/types_windows.go | 10 | ||||
-rw-r--r-- | vendor/github.com/cri-o/ocicni/pkg/ocicni/util.go | 8 | ||||
-rw-r--r-- | vendor/github.com/cri-o/ocicni/pkg/ocicni/util_linux.go | 150 | ||||
-rw-r--r-- | vendor/github.com/cri-o/ocicni/pkg/ocicni/util_unsupported.go | 34 |
8 files changed, 0 insertions, 1425 deletions
diff --git a/vendor/github.com/cri-o/ocicni/LICENSE b/vendor/github.com/cri-o/ocicni/LICENSE deleted file mode 100644 index 3fd703072..000000000 --- a/vendor/github.com/cri-o/ocicni/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2016 Red Hat, Inc. - - 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. diff --git a/vendor/github.com/cri-o/ocicni/pkg/ocicni/ocicni.go b/vendor/github.com/cri-o/ocicni/pkg/ocicni/ocicni.go deleted file mode 100644 index 90d5b6c50..000000000 --- a/vendor/github.com/cri-o/ocicni/pkg/ocicni/ocicni.go +++ /dev/null @@ -1,870 +0,0 @@ -package ocicni - -import ( - "context" - "encoding/json" - "fmt" - "io/ioutil" - "net" - "os" - "path" - "path/filepath" - "sort" - "strings" - "sync" - - "github.com/containernetworking/cni/libcni" - cniinvoke "github.com/containernetworking/cni/pkg/invoke" - cnitypes "github.com/containernetworking/cni/pkg/types" - cnicurrent "github.com/containernetworking/cni/pkg/types/current" - cniversion "github.com/containernetworking/cni/pkg/version" - "github.com/fsnotify/fsnotify" - "github.com/sirupsen/logrus" -) - -type cniNetworkPlugin struct { - cniConfig *libcni.CNIConfig - - sync.RWMutex - defaultNetName netName - networks map[string]*cniNetwork - - nsManager *nsManager - confDir string - binDirs []string - - shutdownChan chan struct{} - watcher *fsnotify.Watcher - done *sync.WaitGroup - - // The pod map provides synchronization for a given pod's network - // operations. Each pod's setup/teardown/status operations - // are synchronized against each other, but network operations of other - // pods can proceed in parallel. - podsLock sync.Mutex - pods map[string]*podLock - - // For testcases - exec cniinvoke.Exec - cacheDir string -} - -type netName struct { - name string - changeable bool -} - -type cniNetwork struct { - name string - filePath string - config *libcni.NetworkConfigList -} - -var errMissingDefaultNetwork = "No CNI configuration file in %s. Has your network provider started?" - -type podLock struct { - // Count of in-flight operations for this pod; when this reaches zero - // the lock can be removed from the pod map - refcount uint - - // Lock to synchronize operations for this specific pod - mu sync.Mutex -} - -func buildFullPodName(podNetwork PodNetwork) string { - return podNetwork.Namespace + "_" + podNetwork.Name -} - -// Lock network operations for a specific pod. If that pod is not yet in -// the pod map, it will be added. The reference count for the pod will -// be increased. -func (plugin *cniNetworkPlugin) podLock(podNetwork PodNetwork) *sync.Mutex { - plugin.podsLock.Lock() - defer plugin.podsLock.Unlock() - - fullPodName := buildFullPodName(podNetwork) - lock, ok := plugin.pods[fullPodName] - if !ok { - lock = &podLock{} - plugin.pods[fullPodName] = lock - } - lock.refcount++ - return &lock.mu -} - -// Unlock network operations for a specific pod. The reference count for the -// pod will be decreased. If the reference count reaches zero, the pod will be -// removed from the pod map. -func (plugin *cniNetworkPlugin) podUnlock(podNetwork PodNetwork) { - plugin.podsLock.Lock() - defer plugin.podsLock.Unlock() - - fullPodName := buildFullPodName(podNetwork) - lock, ok := plugin.pods[fullPodName] - if !ok { - logrus.Errorf("Cannot find reference in refcount map for %s. Refcount cannot be determined.", fullPodName) - return - } else if lock.refcount == 0 { - // This should never ever happen, but handle it anyway - delete(plugin.pods, fullPodName) - logrus.Errorf("Pod lock for %s still in map with zero refcount", fullPodName) - return - } - lock.refcount-- - lock.mu.Unlock() - if lock.refcount == 0 { - delete(plugin.pods, fullPodName) - } -} - -func newWatcher(confDir string) (*fsnotify.Watcher, error) { - // Ensure plugin directory exists, because the following monitoring logic - // relies on that. - if err := os.MkdirAll(confDir, 0755); err != nil { - return nil, fmt.Errorf("failed to create directory %q: %v", confDir, err) - } - - watcher, err := fsnotify.NewWatcher() - if err != nil { - return nil, fmt.Errorf("failed to create new watcher %v", err) - } - defer func() { - // Close watcher on error - if err != nil { - watcher.Close() - } - }() - - if err = watcher.Add(confDir); err != nil { - return nil, fmt.Errorf("failed to add watch on %q: %v", confDir, err) - } - - return watcher, nil -} - -func (plugin *cniNetworkPlugin) monitorConfDir(start *sync.WaitGroup) { - start.Done() - plugin.done.Add(1) - defer plugin.done.Done() - for { - select { - case event := <-plugin.watcher.Events: - logrus.Infof("CNI monitoring event %v", event) - - var defaultDeleted bool - createWrite := (event.Op&fsnotify.Create == fsnotify.Create || - event.Op&fsnotify.Write == fsnotify.Write) - if event.Op&fsnotify.Remove == fsnotify.Remove { - // Care about the event if the default network - // was just deleted - defNet := plugin.getDefaultNetwork() - if defNet != nil && event.Name == defNet.filePath { - defaultDeleted = true - } - - } - if !createWrite && !defaultDeleted { - continue - } - - if err := plugin.syncNetworkConfig(); err != nil { - logrus.Errorf("CNI config loading failed, continue monitoring: %v", err) - continue - } - - case err := <-plugin.watcher.Errors: - if err == nil { - continue - } - logrus.Errorf("CNI monitoring error %v", err) - return - - case <-plugin.shutdownChan: - return - } - } -} - -// InitCNI takes a binary directory in which to search for CNI plugins, and -// a configuration directory in which to search for CNI JSON config files. -// If no valid CNI configs exist, network requests will fail until valid CNI -// config files are present in the config directory. -// If defaultNetName is not empty, a CNI config with that network name will -// be used as the default CNI network, and container network operations will -// fail until that network config is present and valid. -// If defaultNetName is empty, CNI config files should be reloaded real-time and -// defaultNetName should be changeable and determined by file sorting. -func InitCNI(defaultNetName string, confDir string, binDirs ...string) (CNIPlugin, error) { - return initCNI(nil, "", defaultNetName, confDir, true, binDirs...) -} - -// InitCNIWithCache works like InitCNI except that it takes the cni cache directory as third param. -func InitCNIWithCache(defaultNetName, confDir, cacheDir string, binDirs ...string) (CNIPlugin, error) { - return initCNI(nil, cacheDir, defaultNetName, confDir, true, binDirs...) -} - -// InitCNINoInotify works like InitCNI except that it does not use inotify to watch for changes in the CNI config dir. -func InitCNINoInotify(defaultNetName, confDir, cacheDir string, binDirs ...string) (CNIPlugin, error) { - return initCNI(nil, cacheDir, defaultNetName, confDir, false, binDirs...) -} - -// Internal function to allow faking out exec functions for testing -func initCNI(exec cniinvoke.Exec, cacheDir, defaultNetName string, confDir string, useInotify bool, binDirs ...string) (CNIPlugin, error) { - if confDir == "" { - confDir = DefaultConfDir - } - if len(binDirs) == 0 { - binDirs = []string{DefaultBinDir} - } - - plugin := &cniNetworkPlugin{ - cniConfig: libcni.NewCNIConfigWithCacheDir(binDirs, cacheDir, exec), - defaultNetName: netName{ - name: defaultNetName, - // If defaultNetName is not assigned in initialization, - // it should be changeable - changeable: defaultNetName == "", - }, - networks: make(map[string]*cniNetwork), - confDir: confDir, - binDirs: binDirs, - shutdownChan: make(chan struct{}), - done: &sync.WaitGroup{}, - pods: make(map[string]*podLock), - exec: exec, - cacheDir: cacheDir, - } - - if exec == nil { - exec = &cniinvoke.DefaultExec{ - RawExec: &cniinvoke.RawExec{Stderr: os.Stderr}, - PluginDecoder: cniversion.PluginDecoder{}, - } - } - - nsm, err := newNSManager() - if err != nil { - return nil, err - } - plugin.nsManager = nsm - - plugin.syncNetworkConfig() - - if useInotify { - plugin.watcher, err = newWatcher(plugin.confDir) - if err != nil { - return nil, err - } - - startWg := sync.WaitGroup{} - startWg.Add(1) - go plugin.monitorConfDir(&startWg) - startWg.Wait() - } - - return plugin, nil -} - -func (plugin *cniNetworkPlugin) Shutdown() error { - close(plugin.shutdownChan) - if plugin.watcher != nil { - plugin.watcher.Close() - } - plugin.done.Wait() - return nil -} - -func loadNetworks(confDir string, cni *libcni.CNIConfig) (map[string]*cniNetwork, string, error) { - files, err := libcni.ConfFiles(confDir, []string{".conf", ".conflist", ".json"}) - if err != nil { - return nil, "", err - } - - networks := make(map[string]*cniNetwork) - defaultNetName := "" - - sort.Strings(files) - for _, confFile := range files { - var confList *libcni.NetworkConfigList - if strings.HasSuffix(confFile, ".conflist") { - confList, err = libcni.ConfListFromFile(confFile) - if err != nil { - // do not log ENOENT errors - if !os.IsNotExist(err) { - logrus.Errorf("Error loading CNI config list file %s: %v", confFile, err) - } - continue - } - } else { - conf, err := libcni.ConfFromFile(confFile) - if err != nil { - // do not log ENOENT errors - if !os.IsNotExist(err) { - logrus.Errorf("Error loading CNI config file %s: %v", confFile, err) - } - continue - } - if conf.Network.Type == "" { - logrus.Warningf("Error loading CNI config file %s: no 'type'; perhaps this is a .conflist?", confFile) - continue - } - confList, err = libcni.ConfListFromConf(conf) - if err != nil { - logrus.Errorf("Error converting CNI config file %s to list: %v", confFile, err) - continue - } - } - if len(confList.Plugins) == 0 { - logrus.Infof("CNI config list %s has no networks, skipping", confFile) - continue - } - - // Validation on CNI config should be done to pre-check presence - // of plugins which are necessary. - if _, err := cni.ValidateNetworkList(context.TODO(), confList); err != nil { - logrus.Warningf("Error validating CNI config file %s: %v", confFile, err) - continue - } - - if confList.Name == "" { - confList.Name = path.Base(confFile) - } - - cniNet := &cniNetwork{ - name: confList.Name, - filePath: confFile, - config: confList, - } - - logrus.Infof("Found CNI network %s (type=%v) at %s", confList.Name, confList.Plugins[0].Network.Type, confFile) - - if _, ok := networks[confList.Name]; !ok { - networks[confList.Name] = cniNet - } else { - logrus.Infof("Ignored CNI network %s (type=%v) at %s because already exists", confList.Name, confList.Plugins[0].Network.Type, confFile) - } - - if defaultNetName == "" { - defaultNetName = confList.Name - } - } - - return networks, defaultNetName, nil -} - -const ( - loIfname string = "lo" -) - -func (plugin *cniNetworkPlugin) syncNetworkConfig() error { - networks, defaultNetName, err := loadNetworks(plugin.confDir, plugin.cniConfig) - if err != nil { - return err - } - - plugin.Lock() - defer plugin.Unlock() - - // Update defaultNetName if it is changeable - if plugin.defaultNetName.changeable { - plugin.defaultNetName.name = defaultNetName - logrus.Infof("Updated default CNI network name to %s", defaultNetName) - } else { - logrus.Debugf("Default CNI network name %s is unchangeable", plugin.defaultNetName.name) - } - - plugin.networks = networks - - return nil -} - -func (plugin *cniNetworkPlugin) getNetwork(name string) (*cniNetwork, error) { - plugin.RLock() - defer plugin.RUnlock() - net, ok := plugin.networks[name] - if !ok { - return nil, fmt.Errorf("CNI network %q not found", name) - } - return net, nil -} - -func (plugin *cniNetworkPlugin) GetDefaultNetworkName() string { - plugin.RLock() - defer plugin.RUnlock() - return plugin.defaultNetName.name -} - -func (plugin *cniNetworkPlugin) getDefaultNetwork() *cniNetwork { - defaultNetName := plugin.GetDefaultNetworkName() - if defaultNetName == "" { - return nil - } - network, _ := plugin.getNetwork(defaultNetName) - return network -} - -// networksAvailable returns an error if the pod requests no networks and the -// plugin has no default network, and thus the plugin has no idea what network -// to attach the pod to. -func (plugin *cniNetworkPlugin) networksAvailable(podNetwork *PodNetwork) error { - if len(podNetwork.Networks) == 0 && plugin.getDefaultNetwork() == nil { - return fmt.Errorf(errMissingDefaultNetwork, plugin.confDir) - } - return nil -} - -func (plugin *cniNetworkPlugin) Name() string { - return CNIPluginName -} - -func (plugin *cniNetworkPlugin) loadNetworkFromCache(name string, rt *libcni.RuntimeConf) (*cniNetwork, *libcni.RuntimeConf, error) { - cniNet := &cniNetwork{ - name: name, - config: &libcni.NetworkConfigList{ - Name: name, - }, - } - - var confBytes []byte - var err error - confBytes, rt, err = plugin.cniConfig.GetNetworkListCachedConfig(cniNet.config, rt) - if err != nil { - return nil, nil, err - } else if confBytes == nil { - return nil, nil, fmt.Errorf("network %q not found in CNI cache", name) - } - - cniNet.config, err = libcni.ConfListFromBytes(confBytes) - if err != nil { - // Might be a plain NetworkConfig - netConf, err := libcni.ConfFromBytes(confBytes) - if err != nil { - return nil, nil, err - } - // Up-convert to a NetworkConfigList - cniNet.config, err = libcni.ConfListFromConf(netConf) - if err != nil { - return nil, nil, err - } - } - - return cniNet, rt, nil -} - -type forEachNetworkFn func(*cniNetwork, *PodNetwork, *libcni.RuntimeConf) error - -func (plugin *cniNetworkPlugin) forEachNetwork(podNetwork *PodNetwork, fromCache bool, actionFn forEachNetworkFn) error { - networks := podNetwork.Networks - if len(networks) == 0 { - networks = append(networks, NetAttachment{ - Name: plugin.GetDefaultNetworkName(), - }) - } - - allIfNames := make(map[string]bool) - for _, req := range networks { - if req.Ifname != "" { - // Make sure the requested name isn't already assigned - if allIfNames[req.Ifname] { - return fmt.Errorf("network %q requested interface name %q already assigned", req.Name, req.Ifname) - } - allIfNames[req.Ifname] = true - } - } - - for _, network := range networks { - ifName := network.Ifname - if ifName == "" { - for i := 0; i < 10000; i++ { - candidate := fmt.Sprintf("eth%d", i) - if !allIfNames[candidate] { - allIfNames[candidate] = true - ifName = candidate - break - } - } - if ifName == "" { - return fmt.Errorf("failed to find free interface name for network %q", network.Name) - } - } - - rt, err := buildCNIRuntimeConf(podNetwork, ifName, podNetwork.RuntimeConfig[network.Name]) - if err != nil { - logrus.Errorf("error building CNI runtime config: %v", err) - return err - } - - var cniNet *cniNetwork - if fromCache { - var newRt *libcni.RuntimeConf - cniNet, newRt, err = plugin.loadNetworkFromCache(network.Name, rt) - if err != nil { - logrus.Errorf("error loading cached network config: %v", err) - logrus.Warningf("falling back to loading from existing plugins on disk") - } else { - // Use the updated RuntimeConf - rt = newRt - } - } - if cniNet == nil { - cniNet, err = plugin.getNetwork(network.Name) - if err != nil { - // try to load the networks again - if err2 := plugin.syncNetworkConfig(); err2 != nil { - logrus.Error(err2) - return err - } - cniNet, err = plugin.getNetwork(network.Name) - if err != nil { - return err - } - } - } - - if err := actionFn(cniNet, podNetwork, rt); err != nil { - return err - } - } - return nil -} - -func (plugin *cniNetworkPlugin) SetUpPod(podNetwork PodNetwork) ([]NetResult, error) { - return plugin.SetUpPodWithContext(context.Background(), podNetwork) -} - -func (plugin *cniNetworkPlugin) SetUpPodWithContext(ctx context.Context, podNetwork PodNetwork) ([]NetResult, error) { - if err := plugin.networksAvailable(&podNetwork); err != nil { - return nil, err - } - - plugin.podLock(podNetwork).Lock() - defer plugin.podUnlock(podNetwork) - - // Set up loopback interface - if err := bringUpLoopback(podNetwork.NetNS); err != nil { - logrus.Errorf(err.Error()) - return nil, err - } - - results := make([]NetResult, 0) - if err := plugin.forEachNetwork(&podNetwork, false, func(network *cniNetwork, podNetwork *PodNetwork, rt *libcni.RuntimeConf) error { - fullPodName := buildFullPodName(*podNetwork) - logrus.Infof("Adding pod %s to CNI network %q (type=%v)", fullPodName, network.name, network.config.Plugins[0].Network.Type) - result, err := network.addToNetwork(ctx, rt, plugin.cniConfig) - if err != nil { - return fmt.Errorf("error adding pod %s to CNI network %q: %v", fullPodName, network.name, err) - } - results = append(results, NetResult{ - Result: result, - NetAttachment: NetAttachment{ - Name: network.name, - Ifname: rt.IfName, - }, - }) - return nil - }); err != nil { - return nil, err - } - - return results, nil -} - -func (plugin *cniNetworkPlugin) getCachedNetworkInfo(containerID string) ([]NetAttachment, error) { - cacheDir := libcni.CacheDir - if plugin.cacheDir != "" { - cacheDir = plugin.cacheDir - } - - dirPath := filepath.Join(cacheDir, "results") - entries, err := ioutil.ReadDir(dirPath) - if err != nil { - return nil, err - } - - fileNames := make([]string, 0, len(entries)) - for _, e := range entries { - fileNames = append(fileNames, e.Name()) - } - sort.Strings(fileNames) - - attachments := []NetAttachment{} - for _, fname := range fileNames { - part := fmt.Sprintf("-%s-", containerID) - pos := strings.Index(fname, part) - if pos <= 0 || pos+len(part) >= len(fname) { - continue - } - - cacheFile := filepath.Join(dirPath, fname) - bytes, err := ioutil.ReadFile(cacheFile) - if err != nil { - logrus.Errorf("failed to read CNI cache file %s: %v", cacheFile, err) - continue - } - - cachedInfo := struct { - Kind string `json:"kind"` - IfName string `json:"ifName"` - ContainerID string `json:"containerID"` - NetName string `json:"networkName"` - }{} - - if err := json.Unmarshal(bytes, &cachedInfo); err != nil { - logrus.Errorf("failed to unmarshal CNI cache file %s: %v", cacheFile, err) - continue - } - if cachedInfo.Kind != libcni.CNICacheV1 { - logrus.Warningf("unknown CNI cache file %s kind %q", cacheFile, cachedInfo.Kind) - continue - } - if cachedInfo.ContainerID != containerID { - continue - } - // Ignore the loopback interface; it's handled separately - if cachedInfo.IfName == loIfname && cachedInfo.NetName == "cni-loopback" { - continue - } - if cachedInfo.IfName == "" || cachedInfo.NetName == "" { - logrus.Warningf("missing CNI cache file %s ifname %q or netname %q", cacheFile, cachedInfo.IfName, cachedInfo.NetName) - continue - } - - attachments = append(attachments, NetAttachment{ - Name: cachedInfo.NetName, - Ifname: cachedInfo.IfName, - }) - } - return attachments, nil -} - -// TearDownPod tears down pod networks. Prefers cached pod attachment information -// but falls back to given network attachment information. -func (plugin *cniNetworkPlugin) TearDownPod(podNetwork PodNetwork) error { - return plugin.TearDownPodWithContext(context.Background(), podNetwork) -} - -func (plugin *cniNetworkPlugin) TearDownPodWithContext(ctx context.Context, podNetwork PodNetwork) error { - if len(podNetwork.Networks) == 0 { - attachments, err := plugin.getCachedNetworkInfo(podNetwork.ID) - if err == nil && len(attachments) > 0 { - podNetwork.Networks = attachments - } - } - - if err := plugin.networksAvailable(&podNetwork); err != nil { - return err - } - - plugin.podLock(podNetwork).Lock() - defer plugin.podUnlock(podNetwork) - - if err := tearDownLoopback(podNetwork.NetNS); err != nil { - // ignore error - logrus.Warningf("Ignoring error tearing down loopback interface: %v", err) - } - - return plugin.forEachNetwork(&podNetwork, true, func(network *cniNetwork, podNetwork *PodNetwork, rt *libcni.RuntimeConf) error { - fullPodName := buildFullPodName(*podNetwork) - logrus.Infof("Deleting pod %s from CNI network %q (type=%v)", fullPodName, network.name, network.config.Plugins[0].Network.Type) - if err := network.deleteFromNetwork(ctx, rt, plugin.cniConfig); err != nil { - return fmt.Errorf("error removing pod %s from CNI network %q: %v", fullPodName, network.name, err) - } - return nil - }) -} - -// GetPodNetworkStatus returns IP addressing and interface details for all -// networks attached to the pod. -func (plugin *cniNetworkPlugin) GetPodNetworkStatus(podNetwork PodNetwork) ([]NetResult, error) { - return plugin.GetPodNetworkStatusWithContext(context.Background(), podNetwork) -} - -// GetPodNetworkStatusWithContext returns IP addressing and interface details for all -// networks attached to the pod. -func (plugin *cniNetworkPlugin) GetPodNetworkStatusWithContext(ctx context.Context, podNetwork PodNetwork) ([]NetResult, error) { - plugin.podLock(podNetwork).Lock() - defer plugin.podUnlock(podNetwork) - - if err := checkLoopback(podNetwork.NetNS); err != nil { - logrus.Errorf(err.Error()) - return nil, err - } - - results := make([]NetResult, 0) - if err := plugin.forEachNetwork(&podNetwork, true, func(network *cniNetwork, podNetwork *PodNetwork, rt *libcni.RuntimeConf) error { - fullPodName := buildFullPodName(*podNetwork) - logrus.Infof("Checking pod %s for CNI network %s (type=%v)", fullPodName, network.name, network.config.Plugins[0].Network.Type) - result, err := network.checkNetwork(ctx, rt, plugin.cniConfig, plugin.nsManager, podNetwork.NetNS) - if err != nil { - return fmt.Errorf("error checking pod %s for CNI network %q: %v", fullPodName, network.name, err) - } - if result != nil { - results = append(results, NetResult{ - Result: result, - NetAttachment: NetAttachment{ - Name: network.name, - Ifname: rt.IfName, - }, - }) - } - return nil - }); err != nil { - return nil, err - } - - return results, nil -} - -func (network *cniNetwork) addToNetwork(ctx context.Context, rt *libcni.RuntimeConf, cni *libcni.CNIConfig) (cnitypes.Result, error) { - return cni.AddNetworkList(ctx, network.config, rt) -} - -func (network *cniNetwork) checkNetwork(ctx context.Context, rt *libcni.RuntimeConf, cni *libcni.CNIConfig, nsManager *nsManager, netns string) (cnitypes.Result, error) { - gtet, err := cniversion.GreaterThanOrEqualTo(network.config.CNIVersion, "0.4.0") - if err != nil { - return nil, err - } - - var result cnitypes.Result - - // When CNIVersion supports Check, use it. Otherwise fall back on what was done initially. - if gtet { - err = cni.CheckNetworkList(ctx, network.config, rt) - logrus.Infof("Checking CNI network %s (config version=%v)", network.name, network.config.CNIVersion) - if err != nil { - logrus.Errorf("Error checking network: %v", err) - return nil, err - } - } - - result, err = cni.GetNetworkListCachedResult(network.config, rt) - if err != nil { - logrus.Errorf("Error getting network list cached result: %v", err) - return nil, err - } else if result != nil { - return result, nil - } - - // result doesn't exist, create one - logrus.Infof("Checking CNI network %s (config version=%v) nsManager=%v", network.name, network.config.CNIVersion, nsManager) - - var cniInterface *cnicurrent.Interface - ips := []*cnicurrent.IPConfig{} - errs := []error{} - for _, version := range []string{"4", "6"} { - ip, mac, err := getContainerDetails(nsManager, netns, rt.IfName, "-"+version) - if err == nil { - if cniInterface == nil { - cniInterface = &cnicurrent.Interface{ - Name: rt.IfName, - Mac: mac.String(), - Sandbox: netns, - } - } - ips = append(ips, &cnicurrent.IPConfig{ - Version: version, - Interface: cnicurrent.Int(0), - Address: *ip, - }) - } else { - errs = append(errs, err) - } - } - if cniInterface == nil || len(ips) == 0 { - return nil, fmt.Errorf("neither IPv4 nor IPv6 found when retrieving network status: %v", errs) - } - - result = &cnicurrent.Result{ - CNIVersion: network.config.CNIVersion, - Interfaces: []*cnicurrent.Interface{cniInterface}, - IPs: ips, - } - - // Result must be the same CNIVersion as the CNI config - converted, err := result.GetAsVersion(network.config.CNIVersion) - if err != nil { - return nil, err - } - - return converted, nil -} - -func (network *cniNetwork) deleteFromNetwork(ctx context.Context, rt *libcni.RuntimeConf, cni *libcni.CNIConfig) error { - return cni.DelNetworkList(ctx, network.config, rt) -} - -func buildCNIRuntimeConf(podNetwork *PodNetwork, ifName string, runtimeConfig RuntimeConfig) (*libcni.RuntimeConf, error) { - logrus.Infof("Got pod network %+v", podNetwork) - - rt := &libcni.RuntimeConf{ - ContainerID: podNetwork.ID, - NetNS: podNetwork.NetNS, - IfName: ifName, - Args: [][2]string{ - {"IgnoreUnknown", "1"}, - {"K8S_POD_NAMESPACE", podNetwork.Namespace}, - {"K8S_POD_NAME", podNetwork.Name}, - {"K8S_POD_INFRA_CONTAINER_ID", podNetwork.ID}, - }, - CapabilityArgs: map[string]interface{}{}, - } - - // Propagate existing CNI_ARGS to non-k8s consumers - for _, kvpairs := range strings.Split(os.Getenv("CNI_ARGS"), ";") { - if keyval := strings.SplitN(kvpairs, "=", 2); len(keyval) == 2 { - rt.Args = append(rt.Args, [2]string{keyval[0], keyval[1]}) - } - } - - // Add requested static IP to CNI_ARGS - ip := runtimeConfig.IP - if ip != "" { - if tstIP := net.ParseIP(ip); tstIP == nil { - return nil, fmt.Errorf("unable to parse IP address %q", ip) - } - rt.Args = append(rt.Args, [2]string{"IP", ip}) - } - - // Add the requested static MAC to CNI_ARGS - mac := runtimeConfig.MAC - if mac != "" { - _, err := net.ParseMAC(mac) - if err != nil { - return nil, fmt.Errorf("unable to parse MAC address %q: %v", mac, err) - } - rt.Args = append(rt.Args, [2]string{"MAC", mac}) - } - - // Set PortMappings in Capabilities - if len(runtimeConfig.PortMappings) != 0 { - rt.CapabilityArgs["portMappings"] = runtimeConfig.PortMappings - } - - // Set Bandwidth in Capabilities - if runtimeConfig.Bandwidth != nil { - rt.CapabilityArgs["bandwidth"] = map[string]uint64{ - "ingressRate": runtimeConfig.Bandwidth.IngressRate, - "ingressBurst": runtimeConfig.Bandwidth.IngressBurst, - "egressRate": runtimeConfig.Bandwidth.EgressRate, - "egressBurst": runtimeConfig.Bandwidth.EgressBurst, - } - } - - // Set IpRanges in Capabilities - if len(runtimeConfig.IpRanges) > 0 { - rt.CapabilityArgs["ipRanges"] = runtimeConfig.IpRanges - } - - // Set Aliases in Capabilities - if len(podNetwork.Aliases) > 0 { - rt.CapabilityArgs["aliases"] = podNetwork.Aliases - } - return rt, nil -} - -func (plugin *cniNetworkPlugin) Status() error { - if plugin.getDefaultNetwork() == nil { - return fmt.Errorf(errMissingDefaultNetwork, plugin.confDir) - } - return nil -} diff --git a/vendor/github.com/cri-o/ocicni/pkg/ocicni/types.go b/vendor/github.com/cri-o/ocicni/pkg/ocicni/types.go deleted file mode 100644 index 7326b4b40..000000000 --- a/vendor/github.com/cri-o/ocicni/pkg/ocicni/types.go +++ /dev/null @@ -1,152 +0,0 @@ -package ocicni - -import ( - "context" - - "github.com/containernetworking/cni/pkg/types" -) - -const ( - // DefaultInterfaceName is the string to be used for the interface name inside the net namespace - DefaultInterfaceName = "eth0" - // CNIPluginName is the default name of the plugin - CNIPluginName = "cni" -) - -// PortMapping maps to the standard CNI portmapping Capability -// see: https://github.com/containernetworking/cni/blob/master/CONVENTIONS.md -type PortMapping struct { - // HostPort is the port number on the host. - HostPort int32 `json:"hostPort"` - // ContainerPort is the port number inside the sandbox. - ContainerPort int32 `json:"containerPort"` - // Protocol is the protocol of the port mapping. - Protocol string `json:"protocol"` - // HostIP is the host ip to use. - HostIP string `json:"hostIP"` -} - -// IpRange maps to the standard CNI ipRanges Capability -// see: https://github.com/containernetworking/cni/blob/master/CONVENTIONS.md -type IpRange struct { - // Subnet is the whole CIDR - Subnet string `json:"subnet"` - // RangeStart is the first available IP in subnet - RangeStart string `json:"rangeStart,omitempty"` - // RangeEnd is the last available IP in subnet - RangeEnd string `json:"rangeEnd,omitempty"` - // Gateway is the gateway of subnet - Gateway string `json:"gateway,omitempty"` -} - -// RuntimeConfig is additional configuration for a single CNI network that -// is pod-specific rather than general to the network. -type RuntimeConfig struct { - // IP is a static IP to be specified in the network. Can only be used - // with the hostlocal IP allocator. If left unset, an IP will be - // dynamically allocated. - IP string - // MAC is a static MAC address to be assigned to the network interface. - // If left unset, a MAC will be dynamically allocated. - MAC string - // PortMappings is the port mapping of the sandbox. - PortMappings []PortMapping - // Bandwidth is the bandwidth limiting of the pod - Bandwidth *BandwidthConfig - // IpRanges is the ip range gather which is used for address allocation - IpRanges [][]IpRange -} - -// BandwidthConfig maps to the standard CNI bandwidth Capability -// see: https://github.com/containernetworking/cni/blob/master/CONVENTIONS.md -type BandwidthConfig struct { - // IngressRate is a limit for incoming traffic in bps - IngressRate uint64 - IngressBurst uint64 - - // EgressRate is a limit for outgoing traffic in bps - EgressRate uint64 - EgressBurst uint64 -} - -// PodNetwork configures the network of a pod sandbox. -type PodNetwork struct { - // Name is the name of the sandbox. - Name string - // Namespace is the namespace of the sandbox. - Namespace string - // ID is the id of the sandbox container. - ID string - // NetNS is the network namespace path of the sandbox. - NetNS string - - // Networks is a list of CNI network names (and optional interface - // names) to attach to the sandbox. Leave this list empty to attach the - // default network to the sandbox - Networks []NetAttachment - - // NetworkConfig is configuration specific to a single CNI network. - // It is optional, and can be omitted for some or all specified networks - // without issue. - RuntimeConfig map[string]RuntimeConfig - - // Aliases are network-scoped names for resolving a container - // by name. The key value is the network name and the value is - // is a string slice of aliases - Aliases map[string][]string -} - -// NetAttachment describes a container network attachment -type NetAttachment struct { - // NetName contains the name of the CNI network to which the container - // should be or is attached - Name string - // Ifname contains the optional interface name of the attachment - Ifname string -} - -// NetResult contains the result the network attachment operation -type NetResult struct { - // Result is the CNI Result - Result types.Result - // NetAttachment contains the network and interface names of this - // network attachment - NetAttachment -} - -// CNIPlugin is the interface that needs to be implemented by a plugin -type CNIPlugin interface { - // Name returns the plugin's name. This will be used when searching - // for a plugin by name, e.g. - Name() string - - // GetDefaultNetworkName returns the name of the plugin's default - // network. - GetDefaultNetworkName() string - - // SetUpPod is the method called after the sandbox container of - // the pod has been created but before the other containers of the - // pod are launched. - SetUpPod(network PodNetwork) ([]NetResult, error) - - // SetUpPodWithContext is the same as SetUpPod but takes a context - SetUpPodWithContext(ctx context.Context, network PodNetwork) ([]NetResult, error) - - // TearDownPod is the method called before a pod's sandbox container will be deleted - TearDownPod(network PodNetwork) error - - // TearDownPodWithContext is the same as TearDownPod but takes a context - TearDownPodWithContext(ctx context.Context, network PodNetwork) error - - // GetPodNetworkStatus is the method called to obtain the ipv4 or ipv6 addresses of the pod sandbox - GetPodNetworkStatus(network PodNetwork) ([]NetResult, error) - - // GetPodNetworkStatusWithContext is the same as GetPodNetworkStatus but takes a context - GetPodNetworkStatusWithContext(ctx context.Context, network PodNetwork) ([]NetResult, error) - - // NetworkStatus returns error if the network plugin is in error state - Status() error - - // Shutdown terminates all driver operations - Shutdown() error -} diff --git a/vendor/github.com/cri-o/ocicni/pkg/ocicni/types_unix.go b/vendor/github.com/cri-o/ocicni/pkg/ocicni/types_unix.go deleted file mode 100644 index 88010f737..000000000 --- a/vendor/github.com/cri-o/ocicni/pkg/ocicni/types_unix.go +++ /dev/null @@ -1,10 +0,0 @@ -// +build !windows - -package ocicni - -const ( - // DefaultConfDir is the default place to look for CNI Network - DefaultConfDir = "/etc/cni/net.d" - // DefaultBinDir is the default place to look for CNI config files - DefaultBinDir = "/opt/cni/bin" -) diff --git a/vendor/github.com/cri-o/ocicni/pkg/ocicni/types_windows.go b/vendor/github.com/cri-o/ocicni/pkg/ocicni/types_windows.go deleted file mode 100644 index 061ecae5c..000000000 --- a/vendor/github.com/cri-o/ocicni/pkg/ocicni/types_windows.go +++ /dev/null @@ -1,10 +0,0 @@ -// +build windows - -package ocicni - -const ( - // DefaultConfDir is the default place to look for CNI Network - DefaultConfDir = "C:\\cni\\etc\\net.d" - // DefaultBinDir is the default place to look for cni config files - DefaultBinDir = "C:\\cni\\bin" -) diff --git a/vendor/github.com/cri-o/ocicni/pkg/ocicni/util.go b/vendor/github.com/cri-o/ocicni/pkg/ocicni/util.go deleted file mode 100644 index 2af786593..000000000 --- a/vendor/github.com/cri-o/ocicni/pkg/ocicni/util.go +++ /dev/null @@ -1,8 +0,0 @@ -package ocicni - -// newNSManager initializes a new namespace manager, which is a platform dependent struct. -func newNSManager() (*nsManager, error) { - nsm := &nsManager{} - err := nsm.init() - return nsm, err -} diff --git a/vendor/github.com/cri-o/ocicni/pkg/ocicni/util_linux.go b/vendor/github.com/cri-o/ocicni/pkg/ocicni/util_linux.go deleted file mode 100644 index 53c22f83f..000000000 --- a/vendor/github.com/cri-o/ocicni/pkg/ocicni/util_linux.go +++ /dev/null @@ -1,150 +0,0 @@ -// +build linux - -package ocicni - -import ( - "fmt" - "net" - "os/exec" - "strings" - - "github.com/containernetworking/plugins/pkg/ns" - "github.com/vishvananda/netlink" -) - -var defaultNamespaceEnterCommandName = "nsenter" - -type nsManager struct { - nsenterPath string -} - -func (nsm *nsManager) init() error { - var err error - nsm.nsenterPath, err = exec.LookPath(defaultNamespaceEnterCommandName) - return err -} - -func getContainerDetails(nsm *nsManager, netnsPath, interfaceName, addrType string) (*net.IPNet, *net.HardwareAddr, error) { - // Try to retrieve ip inside container network namespace - output, err := exec.Command(nsm.nsenterPath, fmt.Sprintf("--net=%s", netnsPath), "-F", "--", - "ip", "-o", addrType, "addr", "show", "dev", interfaceName, "scope", "global").CombinedOutput() - if err != nil { - return nil, nil, fmt.Errorf("Unexpected command output %s with error: %v", output, err) - } - - lines := strings.Split(string(output), "\n") - if len(lines) < 1 { - return nil, nil, fmt.Errorf("Unexpected command output %s", output) - } - fields := strings.Fields(lines[0]) - if len(fields) < 4 { - return nil, nil, fmt.Errorf("Unexpected address output %s ", lines[0]) - } - ip, ipNet, err := net.ParseCIDR(fields[3]) - if err != nil { - return nil, nil, fmt.Errorf("CNI failed to parse ip from output %s due to %v", output, err) - } - if ip.To4() == nil { - ipNet.IP = ip - } else { - ipNet.IP = ip.To4() - } - - // Try to retrieve MAC inside container network namespace - output, err = exec.Command(nsm.nsenterPath, fmt.Sprintf("--net=%s", netnsPath), "-F", "--", - "ip", "link", "show", "dev", interfaceName).CombinedOutput() - if err != nil { - return nil, nil, fmt.Errorf("unexpected 'ip link' command output %s with error: %v", output, err) - } - - lines = strings.Split(string(output), "\n") - if len(lines) < 2 { - return nil, nil, fmt.Errorf("unexpected 'ip link' command output %s", output) - } - fields = strings.Fields(lines[1]) - if len(fields) < 4 { - return nil, nil, fmt.Errorf("unexpected link output %s ", lines[0]) - } - mac, err := net.ParseMAC(fields[1]) - if err != nil { - return nil, nil, fmt.Errorf("failed to parse MAC from output %s due to %v", output, err) - } - - return ipNet, &mac, nil -} - -func tearDownLoopback(netns string) error { - return ns.WithNetNSPath(netns, func(_ ns.NetNS) error { - link, err := netlink.LinkByName(loIfname) - if err != nil { - return err // not tested - } - err = netlink.LinkSetDown(link) - if err != nil { - return err // not tested - } - return nil - }) -} - -func bringUpLoopback(netns string) error { - if err := ns.WithNetNSPath(netns, func(_ ns.NetNS) error { - link, err := netlink.LinkByName(loIfname) - if err == nil { - err = netlink.LinkSetUp(link) - } - if err != nil { - return err - } - - v4Addrs, err := netlink.AddrList(link, netlink.FAMILY_V4) - if err != nil { - return err - } - if len(v4Addrs) != 0 { - // sanity check that this is a loopback address - for _, addr := range v4Addrs { - if !addr.IP.IsLoopback() { - return fmt.Errorf("loopback interface found with non-loopback address %q", addr.IP) - } - } - } - - v6Addrs, err := netlink.AddrList(link, netlink.FAMILY_V6) - if err != nil { - return err - } - if len(v6Addrs) != 0 { - // sanity check that this is a loopback address - for _, addr := range v6Addrs { - if !addr.IP.IsLoopback() { - return fmt.Errorf("loopback interface found with non-loopback address %q", addr.IP) - } - } - } - - return nil - }); err != nil { - return fmt.Errorf("error adding loopback interface: %s", err) - } - return nil -} - -func checkLoopback(netns string) error { - // Make sure loopback interface is up - if err := ns.WithNetNSPath(netns, func(_ ns.NetNS) error { - link, err := netlink.LinkByName(loIfname) - if err != nil { - return err - } - - if link.Attrs().Flags&net.FlagUp != net.FlagUp { - return fmt.Errorf("loopback interface is down") - } - - return nil - }); err != nil { - return fmt.Errorf("error checking loopback interface: %v", err) - } - return nil -} diff --git a/vendor/github.com/cri-o/ocicni/pkg/ocicni/util_unsupported.go b/vendor/github.com/cri-o/ocicni/pkg/ocicni/util_unsupported.go deleted file mode 100644 index b87f0d373..000000000 --- a/vendor/github.com/cri-o/ocicni/pkg/ocicni/util_unsupported.go +++ /dev/null @@ -1,34 +0,0 @@ -// +build !linux - -package ocicni - -import ( - "errors" - "net" -) - -type nsManager struct { -} - -var errUnsupportedPlatform = errors.New("unsupported platform") - -func (nsm *nsManager) init() error { - return nil -} - -func getContainerDetails(nsm *nsManager, netnsPath, interfaceName, addrType string) (*net.IPNet, *net.HardwareAddr, error) { - return nil, nil, errUnsupportedPlatform -} - -func tearDownLoopback(netns string) error { - return errUnsupportedPlatform -} - -func bringUpLoopback(netns string) error { - return errUnsupportedPlatform -} - -func checkLoopback(netns string) error { - return errUnsupportedPlatform - -} |