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/internal/util/ip.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/internal/util/ip.go')
-rw-r--r-- | libpod/network/internal/util/ip.go | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/libpod/network/internal/util/ip.go b/libpod/network/internal/util/ip.go new file mode 100644 index 000000000..7fe35d3d4 --- /dev/null +++ b/libpod/network/internal/util/ip.go @@ -0,0 +1,70 @@ +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 +} |