summaryrefslogtreecommitdiff
path: root/libpod/network/internal/util/ip.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/internal/util/ip.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/internal/util/ip.go')
-rw-r--r--libpod/network/internal/util/ip.go70
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
+}