summaryrefslogtreecommitdiff
path: root/libpod/network/cni/config.go
diff options
context:
space:
mode:
authorPaul Holzinger <pholzing@redhat.com>2021-10-13 21:52:55 +0200
committerPaul Holzinger <pholzing@redhat.com>2021-11-11 15:54:02 +0100
commit12c62b92ff2f63cb34dcb9c0555b96983e6aad94 (patch)
tree01e489ea273813b8ae0bd7302c9f91bda5c2f23a /libpod/network/cni/config.go
parent8fd31c674b02b800267b2a759e2406902fdb2723 (diff)
downloadpodman-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.go152
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
-}