aboutsummaryrefslogtreecommitdiff
path: root/libpod/network/internal/util/validate.go
diff options
context:
space:
mode:
Diffstat (limited to 'libpod/network/internal/util/validate.go')
-rw-r--r--libpod/network/internal/util/validate.go97
1 files changed, 97 insertions, 0 deletions
diff --git a/libpod/network/internal/util/validate.go b/libpod/network/internal/util/validate.go
new file mode 100644
index 000000000..03a985043
--- /dev/null
+++ b/libpod/network/internal/util/validate.go
@@ -0,0 +1,97 @@
+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)
+ }
+ } 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
+}
+
+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
+}