From fe3faa517e1bbc3b2e82afaae32d8712c844fdae Mon Sep 17 00:00:00 2001 From: baude Date: Tue, 6 Oct 2020 12:24:21 -0500 Subject: prevent unpredictable results with network create|remove due to a lack of "locking" on cni operations, we could get ourselves in trouble when doing rapid creation or removal of networks. added a simple file lock to deal with the collision and because it is not considered a performent path, use of the file lock should be ok. if proven otherwise in the future, some generic shared memory lock should be implemented for libpod and also used here. moved pkog/network to libpod/network because libpod is now being pulled into the package and it has therefore lost its generic nature. this will make it easier to absorb into libpod as we try to make the network closer to core operations. Fixes: #7807 Signed-off-by: baude --- libpod/network/devices.go | 63 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 libpod/network/devices.go (limited to 'libpod/network/devices.go') diff --git a/libpod/network/devices.go b/libpod/network/devices.go new file mode 100644 index 000000000..a5d23fae4 --- /dev/null +++ b/libpod/network/devices.go @@ -0,0 +1,63 @@ +package network + +import ( + "fmt" + "os/exec" + + "github.com/containers/common/pkg/config" + "github.com/containers/podman/v2/pkg/util" + "github.com/containers/podman/v2/utils" + "github.com/sirupsen/logrus" +) + +// GetFreeDeviceName returns a device name that is unused; used when no network +// name is provided by user +func GetFreeDeviceName(config *config.Config) (string, error) { + var ( + deviceNum uint + deviceName string + ) + networkNames, err := GetNetworkNamesFromFileSystem(config) + if err != nil { + return "", err + } + liveNetworksNames, err := GetLiveNetworkNames() + if err != nil { + return "", err + } + bridgeNames, err := GetBridgeNamesFromFileSystem(config) + if err != nil { + return "", err + } + for { + deviceName = fmt.Sprintf("%s%d", CNIDeviceName, deviceNum) + logrus.Debugf("checking if device name %q exists in other cni networks", deviceName) + if util.StringInSlice(deviceName, networkNames) { + deviceNum++ + continue + } + logrus.Debugf("checking if device name %q exists in live networks", deviceName) + if util.StringInSlice(deviceName, liveNetworksNames) { + deviceNum++ + continue + } + logrus.Debugf("checking if device name %q already exists as a bridge name ", deviceName) + if !util.StringInSlice(deviceName, bridgeNames) { + break + } + deviceNum++ + } + return deviceName, nil +} + +// RemoveInterface removes an interface by the given name +func RemoveInterface(interfaceName string) error { + // Make sure we have the ip command on the system + ipPath, err := exec.LookPath("ip") + if err != nil { + return err + } + // Delete the network interface + _, err = utils.ExecCmd(ipPath, []string{"link", "del", interfaceName}...) + return err +} -- cgit v1.2.3-54-g00ecf