diff options
author | Paul Holzinger <pholzing@redhat.com> | 2021-10-13 21:52:55 +0200 |
---|---|---|
committer | Paul Holzinger <pholzing@redhat.com> | 2021-11-11 15:54:02 +0100 |
commit | 12c62b92ff2f63cb34dcb9c0555b96983e6aad94 (patch) | |
tree | 01e489ea273813b8ae0bd7302c9f91bda5c2f23a /libpod/network/cni/config.go | |
parent | 8fd31c674b02b800267b2a759e2406902fdb2723 (diff) | |
download | podman-12c62b92ff2f63cb34dcb9c0555b96983e6aad94.tar.gz podman-12c62b92ff2f63cb34dcb9c0555b96983e6aad94.tar.bz2 podman-12c62b92ff2f63cb34dcb9c0555b96983e6aad94.zip |
Make networking code reusable
To prevent code duplication when creating new network backends move
reusable code into a separate internal package.
This allows all network backends to use the same code as long as they
implement the new NetUtil interface.
Signed-off-by: Paul Holzinger <pholzing@redhat.com>
Diffstat (limited to 'libpod/network/cni/config.go')
-rw-r--r-- | libpod/network/cni/config.go | 152 |
1 files changed, 8 insertions, 144 deletions
diff --git a/libpod/network/cni/config.go b/libpod/network/cni/config.go index 3df155637..a63574f25 100644 --- a/libpod/network/cni/config.go +++ b/libpod/network/cni/config.go @@ -7,6 +7,7 @@ import ( "os" "github.com/containers/podman/v3/libpod/define" + internalutil "github.com/containers/podman/v3/libpod/network/internal/util" "github.com/containers/podman/v3/libpod/network/types" "github.com/containers/podman/v3/libpod/network/util" pkgutil "github.com/containers/podman/v3/pkg/util" @@ -41,38 +42,9 @@ func (n *cniNetwork) networkCreate(newNetwork types.Network, defaultNet bool) (* newNetwork.Driver = types.DefaultNetworkDriver } - // FIXME: Should we use a different type for network create without the ID field? - // the caller is not allowed to set a specific ID - if newNetwork.ID != "" { - return nil, errors.Wrap(define.ErrInvalidArg, "ID can not be set for network create") - } - - if newNetwork.Labels == nil { - newNetwork.Labels = map[string]string{} - } - if newNetwork.Options == nil { - newNetwork.Options = map[string]string{} - } - if newNetwork.IPAMOptions == nil { - newNetwork.IPAMOptions = map[string]string{} - } - - var name string - var err error - // validate the name when given - if newNetwork.Name != "" { - if !define.NameRegex.MatchString(newNetwork.Name) { - return nil, errors.Wrapf(define.RegexError, "network name %s invalid", newNetwork.Name) - } - if _, ok := n.networks[newNetwork.Name]; ok { - return nil, errors.Wrapf(define.ErrNetworkExists, "network name %s already used", newNetwork.Name) - } - } else { - name, err = n.getFreeDeviceName() - if err != nil { - return nil, err - } - newNetwork.Name = name + err := internalutil.CommonNetworkCreate(n, &newNetwork) + if err != nil { + return nil, err } // Only get the used networks for validation if we do not create the default network. @@ -84,7 +56,7 @@ func (n *cniNetwork) networkCreate(newNetwork types.Network, defaultNet bool) (* // fail because it thinks the network is used on the host. var usedNetworks []*net.IPNet if !defaultNet { - usedNetworks, err = n.getUsedSubnets() + usedNetworks, err = internalutil.GetUsedSubnets(n) if err != nil { return nil, err } @@ -92,11 +64,7 @@ func (n *cniNetwork) networkCreate(newNetwork types.Network, defaultNet bool) (* switch newNetwork.Driver { case types.BridgeNetworkDriver: - // if the name was created with getFreeDeviceName set the interface to it as well - if name != "" && newNetwork.NetworkInterface == "" { - newNetwork.NetworkInterface = name - } - err = n.createBridge(&newNetwork, usedNetworks) + err = internalutil.CreateBridge(n, &newNetwork, usedNetworks) if err != nil { return nil, err } @@ -110,7 +78,7 @@ func (n *cniNetwork) networkCreate(newNetwork types.Network, defaultNet bool) (* } for i := range newNetwork.Subnets { - err := validateSubnet(&newNetwork.Subnets[i], !newNetwork.Internal, usedNetworks) + err := internalutil.ValidateSubnet(&newNetwork.Subnets[i], !newNetwork.Internal, usedNetworks) if err != nil { return nil, err } @@ -223,7 +191,7 @@ func createIPMACVLAN(network *types.Network) error { return errors.New("internal is not supported with macvlan") } if network.NetworkInterface != "" { - interfaceNames, err := util.GetLiveNetworkNames() + interfaceNames, err := internalutil.GetLiveNetworkNames() if err != nil { return err } @@ -238,107 +206,3 @@ func createIPMACVLAN(network *types.Network) error { } return nil } - -func (n *cniNetwork) createBridge(network *types.Network, usedNetworks []*net.IPNet) error { - if network.NetworkInterface != "" { - bridges := n.getBridgeInterfaceNames() - if pkgutil.StringInSlice(network.NetworkInterface, bridges) { - return errors.Errorf("bridge name %s already in use", network.NetworkInterface) - } - if !define.NameRegex.MatchString(network.NetworkInterface) { - return errors.Wrapf(define.RegexError, "bridge name %s invalid", network.NetworkInterface) - } - } else { - var err error - network.NetworkInterface, err = n.getFreeDeviceName() - if err != nil { - return err - } - } - - if len(network.Subnets) == 0 { - freeSubnet, err := n.getFreeIPv4NetworkSubnet(usedNetworks) - if err != nil { - return err - } - network.Subnets = append(network.Subnets, *freeSubnet) - } - // ipv6 enabled means dual stack, check if we already have - // a ipv4 or ipv6 subnet and add one if not. - if network.IPv6Enabled { - ipv4 := false - ipv6 := false - for _, subnet := range network.Subnets { - if util.IsIPv6(subnet.Subnet.IP) { - ipv6 = true - } - if util.IsIPv4(subnet.Subnet.IP) { - ipv4 = true - } - } - if !ipv4 { - freeSubnet, err := n.getFreeIPv4NetworkSubnet(usedNetworks) - if err != nil { - return err - } - network.Subnets = append(network.Subnets, *freeSubnet) - } - if !ipv6 { - freeSubnet, err := n.getFreeIPv6NetworkSubnet(usedNetworks) - if err != nil { - return err - } - network.Subnets = append(network.Subnets, *freeSubnet) - } - } - network.IPAMOptions["driver"] = types.HostLocalIPAMDriver - return nil -} - -// validateSubnet will validate a given Subnet. It checks if the -// given gateway and lease range are part of this subnet. If the -// gateway is empty and addGateway is true it will get the first -// available ip in the subnet assigned. -func validateSubnet(s *types.Subnet, addGateway bool, usedNetworks []*net.IPNet) error { - if s == nil { - return errors.New("subnet is nil") - } - if s.Subnet.IP == nil { - return errors.New("subnet ip is nil") - } - - // Reparse to ensure subnet is valid. - // Do not use types.ParseCIDR() because we want the ip to be - // the network address and not a random ip in the subnet. - _, net, err := net.ParseCIDR(s.Subnet.String()) - if err != nil { - return errors.Wrap(err, "subnet invalid") - } - - // check that the new subnet does not conflict with existing ones - if util.NetworkIntersectsWithNetworks(net, usedNetworks) { - return errors.Errorf("subnet %s is already used on the host or by another config", net.String()) - } - - s.Subnet = types.IPNet{IPNet: *net} - if s.Gateway != nil { - if !s.Subnet.Contains(s.Gateway) { - return errors.Errorf("gateway %s not in subnet %s", s.Gateway, &s.Subnet) - } - } else if addGateway { - ip, err := util.FirstIPInSubnet(net) - if err != nil { - return err - } - s.Gateway = ip - } - if s.LeaseRange != nil { - if s.LeaseRange.StartIP != nil && !s.Subnet.Contains(s.LeaseRange.StartIP) { - return errors.Errorf("lease range start ip %s not in subnet %s", s.LeaseRange.StartIP, &s.Subnet) - } - if s.LeaseRange.EndIP != nil && !s.Subnet.Contains(s.LeaseRange.EndIP) { - return errors.Errorf("lease range end ip %s not in subnet %s", s.LeaseRange.EndIP, &s.Subnet) - } - } - return nil -} |