summaryrefslogtreecommitdiff
path: root/libpod/network/create.go
diff options
context:
space:
mode:
Diffstat (limited to 'libpod/network/create.go')
-rw-r--r--libpod/network/create.go310
1 files changed, 0 insertions, 310 deletions
diff --git a/libpod/network/create.go b/libpod/network/create.go
deleted file mode 100644
index aca8150b5..000000000
--- a/libpod/network/create.go
+++ /dev/null
@@ -1,310 +0,0 @@
-package network
-
-import (
- "encoding/json"
- "fmt"
- "io/ioutil"
- "os"
- "path/filepath"
- "strconv"
-
- "github.com/containernetworking/cni/pkg/version"
- "github.com/containers/common/pkg/config"
- "github.com/containers/podman/v3/pkg/domain/entities"
- "github.com/containers/podman/v3/pkg/util"
- "github.com/pkg/errors"
- "github.com/sirupsen/logrus"
-)
-
-// Create the CNI network
-func Create(name string, options entities.NetworkCreateOptions, runtimeConfig *config.Config) (*entities.NetworkCreateReport, error) {
- var fileName string
- if err := isSupportedDriver(options.Driver); err != nil {
- return nil, err
- }
- // Acquire a lock for CNI
- l, err := acquireCNILock(runtimeConfig)
- if err != nil {
- return nil, err
- }
- defer l.releaseCNILock()
- if len(options.MacVLAN) > 0 || options.Driver == MacVLANNetworkDriver {
- fileName, err = createMacVLAN(name, options, runtimeConfig)
- } else {
- fileName, err = createBridge(name, options, runtimeConfig)
- }
- if err != nil {
- return nil, err
- }
- return &entities.NetworkCreateReport{Filename: fileName}, nil
-}
-
-// validateBridgeOptions validate the bridge networking options
-func validateBridgeOptions(options entities.NetworkCreateOptions) error {
- subnet := &options.Subnet
- ipRange := &options.Range
- gateway := options.Gateway
- // if IPv6 is set an IPv6 subnet MUST be specified
- if options.IPv6 && ((subnet.IP == nil) || (subnet.IP != nil && !IsIPv6(subnet.IP))) {
- return errors.Errorf("ipv6 option requires an IPv6 --subnet to be provided")
- }
- // range and gateway depend on subnet
- if subnet.IP == nil && (ipRange.IP != nil || gateway != nil) {
- return errors.Errorf("every ip-range or gateway must have a corresponding subnet")
- }
-
- // if a range is given, we need to ensure it is "in" the network range.
- if ipRange.IP != nil {
- firstIP, err := FirstIPInSubnet(ipRange)
- if err != nil {
- return errors.Wrapf(err, "failed to get first IP address from ip-range")
- }
- lastIP, err := LastIPInSubnet(ipRange)
- if err != nil {
- return errors.Wrapf(err, "failed to get last IP address from ip-range")
- }
- if !subnet.Contains(firstIP) || !subnet.Contains(lastIP) {
- return errors.Errorf("the ip range %s does not fall within the subnet range %s", ipRange.String(), subnet.String())
- }
- }
-
- // if network is provided and if gateway is provided, make sure it is "in" network
- if gateway != nil && !subnet.Contains(gateway) {
- return errors.Errorf("gateway %s is not in valid for subnet %s", gateway.String(), subnet.String())
- }
-
- return nil
-}
-
-// parseMTU parses the mtu option
-func parseMTU(mtu string) (int, error) {
- if mtu == "" {
- return 0, nil // default
- }
- m, err := strconv.Atoi(mtu)
- if err != nil {
- return 0, err
- }
- if m < 0 {
- return 0, errors.Errorf("the value %d for mtu is less than zero", m)
- }
- return m, nil
-}
-
-// parseVlan parses the vlan option
-func parseVlan(vlan string) (int, error) {
- if vlan == "" {
- return 0, nil // default
- }
- return strconv.Atoi(vlan)
-}
-
-// createBridge creates a CNI network
-func createBridge(name string, options entities.NetworkCreateOptions, runtimeConfig *config.Config) (string, error) {
- var (
- ipamRanges [][]IPAMLocalHostRangeConf
- err error
- routes []IPAMRoute
- )
- isGateway := true
- ipMasq := true
-
- // validate options
- if err := validateBridgeOptions(options); err != nil {
- return "", err
- }
-
- // For compatibility with the docker implementation:
- // if IPv6 is enabled (it really means dual-stack) then an IPv6 subnet has to be provided, and one free network is allocated for IPv4
- // if IPv6 is not specified the subnet may be specified and can be either IPv4 or IPv6 (podman, unlike docker, allows IPv6 only networks)
- // If not subnet is specified an IPv4 subnet will be allocated
- subnet := &options.Subnet
- ipRange := &options.Range
- gateway := options.Gateway
- if subnet.IP != nil {
- // if network is provided, does it conflict with existing CNI or live networks
- err = ValidateUserNetworkIsAvailable(runtimeConfig, subnet)
- if err != nil {
- return "", err
- }
- // obtain CNI subnet default route
- defaultRoute, err := NewIPAMDefaultRoute(IsIPv6(subnet.IP))
- if err != nil {
- return "", err
- }
- routes = append(routes, defaultRoute)
- // obtain CNI range
- ipamRange, err := NewIPAMLocalHostRange(subnet, ipRange, gateway)
- if err != nil {
- return "", err
- }
- ipamRanges = append(ipamRanges, ipamRange)
- }
- // if no network is provided or IPv6 flag used, figure out the IPv4 network
- if options.IPv6 || len(routes) == 0 {
- subnetV4, err := GetFreeNetwork(runtimeConfig)
- if err != nil {
- return "", err
- }
- // obtain IPv4 default route
- defaultRoute, err := NewIPAMDefaultRoute(false)
- if err != nil {
- return "", err
- }
- routes = append(routes, defaultRoute)
- // the CNI bridge plugin does not need to set
- // the range or gateway options explicitly
- ipamRange, err := NewIPAMLocalHostRange(subnetV4, nil, nil)
- if err != nil {
- return "", err
- }
- ipamRanges = append(ipamRanges, ipamRange)
- }
-
- // create CNI config
- ipamConfig, err := NewIPAMHostLocalConf(routes, ipamRanges)
- if err != nil {
- return "", err
- }
-
- if options.Internal {
- isGateway = false
- ipMasq = false
- }
-
- var mtu int
- var vlan int
- for k, v := range options.Options {
- var err error
- switch k {
- case "mtu":
- mtu, err = parseMTU(v)
- if err != nil {
- return "", err
- }
-
- case "vlan":
- vlan, err = parseVlan(v)
- if err != nil {
- return "", err
- }
-
- default:
- return "", errors.Errorf("unsupported option %s", k)
- }
- }
-
- // obtain host bridge name
- bridgeDeviceName, err := GetFreeDeviceName(runtimeConfig)
- if err != nil {
- return "", err
- }
-
- if len(name) > 0 {
- netNames, err := GetNetworkNamesFromFileSystem(runtimeConfig)
- if err != nil {
- return "", err
- }
- if util.StringInSlice(name, netNames) {
- return "", errors.Errorf("the network name %s is already used", name)
- }
- } else {
- // If no name is given, we give the name of the bridge device
- name = bridgeDeviceName
- }
-
- // create CNI plugin configuration
- ncList := NewNcList(name, version.Current(), options.Labels)
- var plugins []CNIPlugins
- // TODO need to iron out the role of isDefaultGW and IPMasq
- bridge := NewHostLocalBridge(bridgeDeviceName, isGateway, false, ipMasq, mtu, vlan, ipamConfig)
- plugins = append(plugins, bridge)
- plugins = append(plugins, NewPortMapPlugin())
- plugins = append(plugins, NewFirewallPlugin())
- plugins = append(plugins, NewTuningPlugin())
- // if we find the dnsname plugin we add configuration for it
- if HasDNSNamePlugin(runtimeConfig.Network.CNIPluginDirs) && !options.DisableDNS {
- if options.Internal {
- logrus.Warnf("dnsname and --internal networks are incompatible. dnsname plugin not configured for network %s", name)
- } else {
- // Note: in the future we might like to allow for dynamic domain names
- plugins = append(plugins, NewDNSNamePlugin(DefaultPodmanDomainName))
- }
- }
- // Add the podman-machine CNI plugin if we are in a machine
- if runtimeConfig.MachineEnabled() { // check if we are in a machine vm
- plugins = append(plugins, NewPodmanMachinePlugin())
- }
- ncList["plugins"] = plugins
- b, err := json.MarshalIndent(ncList, "", " ")
- if err != nil {
- return "", err
- }
- if err := os.MkdirAll(GetCNIConfDir(runtimeConfig), 0755); err != nil {
- return "", err
- }
- cniPathName := filepath.Join(GetCNIConfDir(runtimeConfig), fmt.Sprintf("%s.conflist", name))
- err = ioutil.WriteFile(cniPathName, b, 0644)
- return cniPathName, err
-}
-
-func createMacVLAN(name string, options entities.NetworkCreateOptions, runtimeConfig *config.Config) (string, error) {
- var (
- mtu int
- plugins []CNIPlugins
- )
- liveNetNames, err := GetLiveNetworkNames()
- if err != nil {
- return "", err
- }
-
- // The parent can be defined with --macvlan or as an option (-o parent:device)
- parentNetworkDevice := options.MacVLAN
- if len(parentNetworkDevice) < 1 {
- if parent, ok := options.Options["parent"]; ok {
- parentNetworkDevice = parent
- }
- }
-
- // Make sure the host-device exists if provided
- if len(parentNetworkDevice) > 0 && !util.StringInSlice(parentNetworkDevice, liveNetNames) {
- return "", errors.Errorf("failed to find network interface %q", parentNetworkDevice)
- }
- if len(name) > 0 {
- netNames, err := GetNetworkNamesFromFileSystem(runtimeConfig)
- if err != nil {
- return "", err
- }
- if util.StringInSlice(name, netNames) {
- return "", errors.Errorf("the network name %s is already used", name)
- }
- } else {
- name, err = GetFreeDeviceName(runtimeConfig)
- if err != nil {
- return "", err
- }
- }
- ncList := NewNcList(name, version.Current(), options.Labels)
- if val, ok := options.Options["mtu"]; ok {
- intVal, err := strconv.Atoi(val)
- if err != nil {
- return "", err
- }
- if intVal > 0 {
- mtu = intVal
- }
- }
- macvlan, err := NewMacVLANPlugin(parentNetworkDevice, options.Gateway, &options.Range, &options.Subnet, mtu)
- if err != nil {
- return "", err
- }
- plugins = append(plugins, macvlan)
- ncList["plugins"] = plugins
- b, err := json.MarshalIndent(ncList, "", " ")
- if err != nil {
- return "", err
- }
- cniPathName := filepath.Join(GetCNIConfDir(runtimeConfig), fmt.Sprintf("%s.conflist", name))
- err = ioutil.WriteFile(cniPathName, b, 0644)
- return cniPathName, err
-}