summaryrefslogtreecommitdiff
path: root/libpod/network/internal
diff options
context:
space:
mode:
Diffstat (limited to 'libpod/network/internal')
-rw-r--r--libpod/network/internal/util/bridge.go69
-rw-r--r--libpod/network/internal/util/create.go42
-rw-r--r--libpod/network/internal/util/interface.go19
-rw-r--r--libpod/network/internal/util/interfaces.go34
-rw-r--r--libpod/network/internal/util/ip.go70
-rw-r--r--libpod/network/internal/util/ip_test.go63
-rw-r--r--libpod/network/internal/util/parse.go37
-rw-r--r--libpod/network/internal/util/util.go123
-rw-r--r--libpod/network/internal/util/validate.go121
9 files changed, 0 insertions, 578 deletions
diff --git a/libpod/network/internal/util/bridge.go b/libpod/network/internal/util/bridge.go
deleted file mode 100644
index 476557050..000000000
--- a/libpod/network/internal/util/bridge.go
+++ /dev/null
@@ -1,69 +0,0 @@
-package util
-
-import (
- "net"
-
- "github.com/containers/podman/v3/libpod/define"
- "github.com/containers/podman/v3/libpod/network/types"
- "github.com/containers/podman/v3/libpod/network/util"
- pkgutil "github.com/containers/podman/v3/pkg/util"
- "github.com/pkg/errors"
-)
-
-func CreateBridge(n NetUtil, network *types.Network, usedNetworks []*net.IPNet) error {
- if network.NetworkInterface != "" {
- bridges := GetBridgeInterfaceNames(n)
- 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 = GetFreeDeviceName(n)
- if err != nil {
- return err
- }
- }
-
- if network.IPAMOptions["driver"] != types.DHCPIPAMDriver {
- if len(network.Subnets) == 0 {
- freeSubnet, err := 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 := GetFreeIPv4NetworkSubnet(usedNetworks)
- if err != nil {
- return err
- }
- network.Subnets = append(network.Subnets, *freeSubnet)
- }
- if !ipv6 {
- freeSubnet, err := GetFreeIPv6NetworkSubnet(usedNetworks)
- if err != nil {
- return err
- }
- network.Subnets = append(network.Subnets, *freeSubnet)
- }
- }
- network.IPAMOptions["driver"] = types.HostLocalIPAMDriver
- }
- return nil
-}
diff --git a/libpod/network/internal/util/create.go b/libpod/network/internal/util/create.go
deleted file mode 100644
index cecfd7133..000000000
--- a/libpod/network/internal/util/create.go
+++ /dev/null
@@ -1,42 +0,0 @@
-package util
-
-import (
- "github.com/containers/podman/v3/libpod/define"
- "github.com/containers/podman/v3/libpod/network/types"
- "github.com/pkg/errors"
-)
-
-func CommonNetworkCreate(n NetUtil, network *types.Network) error {
- if network.Labels == nil {
- network.Labels = map[string]string{}
- }
- if network.Options == nil {
- network.Options = map[string]string{}
- }
- if network.IPAMOptions == nil {
- network.IPAMOptions = map[string]string{}
- }
-
- var name string
- var err error
- // validate the name when given
- if network.Name != "" {
- if !define.NameRegex.MatchString(network.Name) {
- return errors.Wrapf(define.RegexError, "network name %s invalid", network.Name)
- }
- if _, err := n.Network(network.Name); err == nil {
- return errors.Wrapf(define.ErrNetworkExists, "network name %s already used", network.Name)
- }
- } else {
- name, err = GetFreeDeviceName(n)
- if err != nil {
- return err
- }
- network.Name = name
- // also use the name as interface name when we create a bridge network
- if network.Driver == types.BridgeNetworkDriver && network.NetworkInterface == "" {
- network.NetworkInterface = name
- }
- }
- return nil
-}
diff --git a/libpod/network/internal/util/interface.go b/libpod/network/internal/util/interface.go
deleted file mode 100644
index 4b01a09b8..000000000
--- a/libpod/network/internal/util/interface.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package util
-
-import "github.com/containers/podman/v3/libpod/network/types"
-
-// This is a helper package to allow code sharing between the different
-// network interfaces.
-
-// NetUtil is a helper interface which all network interfaces should implement to allow easy code sharing
-type NetUtil interface {
- // ForEach eaxecutes the given function for each network
- ForEach(func(types.Network))
- // Len returns the number of networks
- Len() int
- // DefaultInterfaceName return the default interface name, this will be suffixed by a number
- DefaultInterfaceName() string
- // Network returns the network with the given name or ID.
- // It returns an error if the network is not found
- Network(nameOrID string) (*types.Network, error)
-}
diff --git a/libpod/network/internal/util/interfaces.go b/libpod/network/internal/util/interfaces.go
deleted file mode 100644
index 20819f756..000000000
--- a/libpod/network/internal/util/interfaces.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package util
-
-import "net"
-
-// getLiveNetworkSubnets returns a slice of subnets representing what the system
-// has defined as network interfaces
-func getLiveNetworkSubnets() ([]*net.IPNet, error) {
- addrs, err := net.InterfaceAddrs()
- if err != nil {
- return nil, err
- }
- nets := make([]*net.IPNet, 0, len(addrs))
- for _, address := range addrs {
- _, n, err := net.ParseCIDR(address.String())
- if err != nil {
- return nil, err
- }
- nets = append(nets, n)
- }
- return nets, nil
-}
-
-// GetLiveNetworkNames returns a list of network interface names on the system
-func GetLiveNetworkNames() ([]string, error) {
- liveInterfaces, err := net.Interfaces()
- if err != nil {
- return nil, err
- }
- interfaceNames := make([]string, 0, len(liveInterfaces))
- for _, i := range liveInterfaces {
- interfaceNames = append(interfaceNames, i.Name)
- }
- return interfaceNames, nil
-}
diff --git a/libpod/network/internal/util/ip.go b/libpod/network/internal/util/ip.go
deleted file mode 100644
index 7fe35d3d4..000000000
--- a/libpod/network/internal/util/ip.go
+++ /dev/null
@@ -1,70 +0,0 @@
-package util
-
-import (
- "crypto/rand"
- "net"
-
- "github.com/pkg/errors"
-)
-
-func incByte(subnet *net.IPNet, idx int, shift uint) error {
- if idx < 0 {
- return errors.New("no more subnets left")
- }
- if subnet.IP[idx] == 255 {
- subnet.IP[idx] = 0
- return incByte(subnet, idx-1, 0)
- }
- subnet.IP[idx] += 1 << shift
- return nil
-}
-
-// NextSubnet returns subnet incremented by 1
-func NextSubnet(subnet *net.IPNet) (*net.IPNet, error) {
- newSubnet := &net.IPNet{
- IP: subnet.IP,
- Mask: subnet.Mask,
- }
- ones, bits := newSubnet.Mask.Size()
- if ones == 0 {
- return nil, errors.Errorf("%s has only one subnet", subnet.String())
- }
- zeroes := uint(bits - ones)
- shift := zeroes % 8
- idx := ones/8 - 1
- if idx < 0 {
- idx = 0
- }
- if err := incByte(newSubnet, idx, shift); err != nil {
- return nil, err
- }
- return newSubnet, nil
-}
-
-func NetworkIntersectsWithNetworks(n *net.IPNet, networklist []*net.IPNet) bool {
- for _, nw := range networklist {
- if networkIntersect(n, nw) {
- return true
- }
- }
- return false
-}
-
-func networkIntersect(n1, n2 *net.IPNet) bool {
- return n2.Contains(n1.IP) || n1.Contains(n2.IP)
-}
-
-// getRandomIPv6Subnet returns a random internal ipv6 subnet as described in RFC3879.
-func getRandomIPv6Subnet() (net.IPNet, error) {
- ip := make(net.IP, 8, net.IPv6len)
- // read 8 random bytes
- _, err := rand.Read(ip)
- if err != nil {
- return net.IPNet{}, nil
- }
- // first byte must be FD as per RFC3879
- ip[0] = 0xfd
- // add 8 zero bytes
- ip = append(ip, make([]byte, 8)...)
- return net.IPNet{IP: ip, Mask: net.CIDRMask(64, 128)}, nil
-}
diff --git a/libpod/network/internal/util/ip_test.go b/libpod/network/internal/util/ip_test.go
deleted file mode 100644
index eaed769d7..000000000
--- a/libpod/network/internal/util/ip_test.go
+++ /dev/null
@@ -1,63 +0,0 @@
-package util
-
-import (
- "fmt"
- "net"
- "reflect"
- "testing"
-)
-
-func parseCIDR(n string) *net.IPNet {
- _, parsedNet, _ := net.ParseCIDR(n)
- return parsedNet
-}
-
-func TestNextSubnet(t *testing.T) {
- type args struct {
- subnet *net.IPNet
- }
- tests := []struct {
- name string
- args args
- want *net.IPNet
- wantErr bool
- }{
- {"class b", args{subnet: parseCIDR("192.168.0.0/16")}, parseCIDR("192.169.0.0/16"), false},
- {"class c", args{subnet: parseCIDR("192.168.1.0/24")}, parseCIDR("192.168.2.0/24"), false},
- }
- for _, tt := range tests {
- test := tt
- t.Run(test.name, func(t *testing.T) {
- got, err := NextSubnet(test.args.subnet)
- if (err != nil) != test.wantErr {
- t.Errorf("NextSubnet() error = %v, wantErr %v", err, test.wantErr)
- return
- }
- if !reflect.DeepEqual(got, test.want) {
- t.Errorf("NextSubnet() got = %v, want %v", got, test.want)
- }
- })
- }
-}
-
-func TestGetRandomIPv6Subnet(t *testing.T) {
- for i := 0; i < 1000; i++ {
- t.Run(fmt.Sprintf("GetRandomIPv6Subnet %d", i), func(t *testing.T) {
- sub, err := getRandomIPv6Subnet()
- if err != nil {
- t.Errorf("GetRandomIPv6Subnet() error should be nil: %v", err)
- return
- }
- if sub.IP.To4() != nil {
- t.Errorf("ip %s is not an ipv6 address", sub.IP)
- }
- if sub.IP[0] != 0xfd {
- t.Errorf("ipv6 %s does not start with fd", sub.IP)
- }
- ones, bytes := sub.Mask.Size()
- if ones != 64 || bytes != 128 {
- t.Errorf("wrong network mask %v, it should be /64", sub.Mask)
- }
- })
- }
-}
diff --git a/libpod/network/internal/util/parse.go b/libpod/network/internal/util/parse.go
deleted file mode 100644
index 1f68df0bb..000000000
--- a/libpod/network/internal/util/parse.go
+++ /dev/null
@@ -1,37 +0,0 @@
-package util
-
-import (
- "strconv"
-
- "github.com/pkg/errors"
-)
-
-// 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("mtu %d 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
- }
- v, err := strconv.Atoi(vlan)
- if err != nil {
- return 0, err
- }
- if v < 0 || v > 4094 {
- return 0, errors.Errorf("vlan ID %d must be between 0 and 4094", v)
- }
- return v, nil
-}
diff --git a/libpod/network/internal/util/util.go b/libpod/network/internal/util/util.go
deleted file mode 100644
index d9b9a8dc0..000000000
--- a/libpod/network/internal/util/util.go
+++ /dev/null
@@ -1,123 +0,0 @@
-package util
-
-import (
- "errors"
- "fmt"
- "net"
-
- "github.com/containers/podman/v3/libpod/network/types"
- "github.com/containers/podman/v3/pkg/util"
- "github.com/sirupsen/logrus"
-)
-
-// GetBridgeInterfaceNames returns all bridge interface names
-// already used by network configs
-func GetBridgeInterfaceNames(n NetUtil) []string {
- names := make([]string, 0, n.Len())
- n.ForEach(func(net types.Network) {
- if net.Driver == types.BridgeNetworkDriver {
- names = append(names, net.NetworkInterface)
- }
- })
- return names
-}
-
-// GetUsedNetworkNames returns all network names already used
-// by network configs
-func GetUsedNetworkNames(n NetUtil) []string {
- names := make([]string, 0, n.Len())
- n.ForEach(func(net types.Network) {
- if net.Driver == types.BridgeNetworkDriver {
- names = append(names, net.NetworkInterface)
- }
- })
- return names
-}
-
-// GetFreeDeviceName returns a free device name which can
-// be used for new configs as name and bridge interface name.
-// The base name is suffixed by a number
-func GetFreeDeviceName(n NetUtil) (string, error) {
- bridgeNames := GetBridgeInterfaceNames(n)
- netNames := GetUsedNetworkNames(n)
- liveInterfaces, err := GetLiveNetworkNames()
- if err != nil {
- return "", nil
- }
- names := make([]string, 0, len(bridgeNames)+len(netNames)+len(liveInterfaces))
- names = append(names, bridgeNames...)
- names = append(names, netNames...)
- names = append(names, liveInterfaces...)
- // FIXME: Is a limit fine?
- // Start by 1, 0 is reserved for the default network
- for i := 1; i < 1000000; i++ {
- deviceName := fmt.Sprintf("%s%d", n.DefaultInterfaceName(), i)
- if !util.StringInSlice(deviceName, names) {
- logrus.Debugf("found free device name %s", deviceName)
- return deviceName, nil
- }
- }
- return "", errors.New("could not find free device name, to many iterations")
-}
-
-// GetUsedSubnets returns a list of all used subnets by network
-// configs and interfaces on the host.
-func GetUsedSubnets(n NetUtil) ([]*net.IPNet, error) {
- // first, load all used subnets from network configs
- subnets := make([]*net.IPNet, 0, n.Len())
- n.ForEach(func(n types.Network) {
- for i := range n.Subnets {
- subnets = append(subnets, &n.Subnets[i].Subnet.IPNet)
- }
- })
- // second, load networks from the current system
- liveSubnets, err := getLiveNetworkSubnets()
- if err != nil {
- return nil, err
- }
- return append(subnets, liveSubnets...), nil
-}
-
-// GetFreeIPv4NetworkSubnet returns a unused ipv4 subnet
-func GetFreeIPv4NetworkSubnet(usedNetworks []*net.IPNet) (*types.Subnet, error) {
- // the default podman network is 10.88.0.0/16
- // start locking for free /24 networks
- network := &net.IPNet{
- IP: net.IP{10, 89, 0, 0},
- Mask: net.IPMask{255, 255, 255, 0},
- }
-
- // TODO: make sure to not use public subnets
- for {
- if intersectsConfig := NetworkIntersectsWithNetworks(network, usedNetworks); !intersectsConfig {
- logrus.Debugf("found free ipv4 network subnet %s", network.String())
- return &types.Subnet{
- Subnet: types.IPNet{IPNet: *network},
- }, nil
- }
- var err error
- network, err = NextSubnet(network)
- if err != nil {
- return nil, err
- }
- }
-}
-
-// GetFreeIPv6NetworkSubnet returns a unused ipv6 subnet
-func GetFreeIPv6NetworkSubnet(usedNetworks []*net.IPNet) (*types.Subnet, error) {
- // FIXME: Is 10000 fine as limit? We should prevent an endless loop.
- for i := 0; i < 10000; i++ {
- // RFC4193: Choose the ipv6 subnet random and NOT sequentially.
- network, err := getRandomIPv6Subnet()
- if err != nil {
- return nil, err
- }
- if intersectsConfig := NetworkIntersectsWithNetworks(&network, usedNetworks); !intersectsConfig {
- logrus.Debugf("found free ipv6 network subnet %s", network.String())
- return &types.Subnet{
- Subnet: types.IPNet{IPNet: network},
- }, nil
- }
- }
- return nil, errors.New("failed to get random ipv6 subnet")
-}
diff --git a/libpod/network/internal/util/validate.go b/libpod/network/internal/util/validate.go
deleted file mode 100644
index 62c3f3951..000000000
--- a/libpod/network/internal/util/validate.go
+++ /dev/null
@@ -1,121 +0,0 @@
-package util
-
-import (
- "net"
-
- "github.com/containers/podman/v3/libpod/network/types"
- "github.com/containers/podman/v3/libpod/network/util"
- "github.com/pkg/errors"
-)
-
-// 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 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)
- }
- util.NormalizeIP(&s.Gateway)
- } 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 {
- if !s.Subnet.Contains(s.LeaseRange.StartIP) {
- return errors.Errorf("lease range start ip %s not in subnet %s", s.LeaseRange.StartIP, &s.Subnet)
- }
- util.NormalizeIP(&s.LeaseRange.StartIP)
- }
- if s.LeaseRange.EndIP != nil {
- if !s.Subnet.Contains(s.LeaseRange.EndIP) {
- return errors.Errorf("lease range end ip %s not in subnet %s", s.LeaseRange.EndIP, &s.Subnet)
- }
- util.NormalizeIP(&s.LeaseRange.EndIP)
- }
- }
- return nil
-}
-
-// ValidateSubnets will validate the subnets for this network.
-// It also sets the gateway if the gateway is empty and it sets
-// IPv6Enabled to true if at least one subnet is ipv6.
-func ValidateSubnets(network *types.Network, usedNetworks []*net.IPNet) error {
- for i := range network.Subnets {
- err := ValidateSubnet(&network.Subnets[i], !network.Internal, usedNetworks)
- if err != nil {
- return err
- }
- if util.IsIPv6(network.Subnets[i].Subnet.IP) {
- network.IPv6Enabled = true
- }
- }
- return nil
-}
-
-func ValidateSetupOptions(n NetUtil, namespacePath string, options types.SetupOptions) error {
- if namespacePath == "" {
- return errors.New("namespacePath is empty")
- }
- if options.ContainerID == "" {
- return errors.New("ContainerID is empty")
- }
- if len(options.Networks) == 0 {
- return errors.New("must specify at least one network")
- }
- for name, netOpts := range options.Networks {
- network, err := n.Network(name)
- if err != nil {
- return err
- }
- err = validatePerNetworkOpts(network, netOpts)
- if err != nil {
- return err
- }
- }
- return nil
-}
-
-// validatePerNetworkOpts checks that all given static ips are in a subnet on this network
-func validatePerNetworkOpts(network *types.Network, netOpts types.PerNetworkOptions) error {
- if netOpts.InterfaceName == "" {
- return errors.Errorf("interface name on network %s is empty", network.Name)
- }
-outer:
- for _, ip := range netOpts.StaticIPs {
- for _, s := range network.Subnets {
- if s.Subnet.Contains(ip) {
- continue outer
- }
- }
- return errors.Errorf("requested static ip %s not in any subnet on network %s", ip.String(), network.Name)
- }
- return nil
-}