diff options
Diffstat (limited to 'libpod/network/internal')
-rw-r--r-- | libpod/network/internal/util/bridge.go | 69 | ||||
-rw-r--r-- | libpod/network/internal/util/create.go | 42 | ||||
-rw-r--r-- | libpod/network/internal/util/interface.go | 19 | ||||
-rw-r--r-- | libpod/network/internal/util/interfaces.go | 34 | ||||
-rw-r--r-- | libpod/network/internal/util/ip.go | 70 | ||||
-rw-r--r-- | libpod/network/internal/util/ip_test.go | 63 | ||||
-rw-r--r-- | libpod/network/internal/util/parse.go | 37 | ||||
-rw-r--r-- | libpod/network/internal/util/util.go | 123 | ||||
-rw-r--r-- | libpod/network/internal/util/validate.go | 121 |
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 -} |