Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

udn, allocator: Add masquerade IPs #4458

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions go-controller/pkg/generator/udn/masquerade_ips.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package udn

import (
"fmt"
"net"

"github.com/ovn-org/ovn-kubernetes/go-controller/pkg/config"
ipgenerator "github.com/ovn-org/ovn-kubernetes/go-controller/pkg/generator/ip"
)

const (
masqueradeIPv4IDName = "v4-masquerade-ips"
masqueradeIPv6IDName = "v6-masquerade-ips"
// userDefinedNetworkMasqueradeIPBase define the base to calculate udn
// masquerade IPs
userDefinedNetworkMasqueradeIPBase = 10
)

// MasqueradeIPs contains the Masquerade IPs needed for user defined network
// topology
type MasqueradeIPs struct {
// GatewayRouter is the masquerade IP for gateway router
GatewayRouter *net.IPNet
// ManagementPort is the masquerade IP for management port
ManagementPort *net.IPNet
}

// AllocateV4MasqueradeIPs will return the gateway router and management port masquerade IPv4 addresses calculated from
// the networkID argument
func AllocateV4MasqueradeIPs(networkID int) (*MasqueradeIPs, error) {
return allocateMasqueradeIPs(masqueradeIPv4IDName, config.Gateway.V4MasqueradeSubnet, networkID)
}

// AllocateV4MasqueradeIPs will return the gateway router and management port masquerade IPv6 addresses calculated from
// the networkID argument
func AllocateV6MasqueradeIPs(networkID int) (*MasqueradeIPs, error) {
return allocateMasqueradeIPs(masqueradeIPv6IDName, config.Gateway.V6MasqueradeSubnet, networkID)
}

func allocateMasqueradeIPs(idName string, masqueradeSubnet string, networkID int) (*MasqueradeIPs, error) {
if networkID < 1 {
return nil, fmt.Errorf("invalid argument: network ID should be bigger that 0")
}
ipGenerator, err := ipgenerator.NewIPGenerator(masqueradeSubnet)
if err != nil {
return nil, fmt.Errorf("failed initializing generation of network id '%d' %s IPs: %w", networkID, idName, err)
}
// Let's illustrate the expected IPs for networkID 1 and 2
// with userDefinedNetworkMasqueradeIPBase=10 and subnet=169.254.0.0/16
// networkID=1
// GatewayRouter: 169.254.0.11
// ManagementPort: 169.254.0.12
// networkID=2
// GatewayRouter: 169.254.0.13
// ManagementPort: 169.254.0.14
//
numberOfIPs := 2
masqueradeIPs := &MasqueradeIPs{}
masqueradeIPs.GatewayRouter, err = ipGenerator.GenerateIP(userDefinedNetworkMasqueradeIPBase + networkID*numberOfIPs - 1)
if err != nil {
return nil, fmt.Errorf("failed generating network id '%d' %s gateway router ip: %w", networkID, idName, err)
}
masqueradeIPs.ManagementPort, err = ipGenerator.GenerateIP(userDefinedNetworkMasqueradeIPBase + networkID*numberOfIPs)
if err != nil {
return nil, fmt.Errorf("failed generating network id '%d' %s management port ip: %w", networkID, idName, err)
}
return masqueradeIPs, nil
}
64 changes: 64 additions & 0 deletions go-controller/pkg/generator/udn/masquerade_ips_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package udn

import (
"testing"

. "github.com/onsi/gomega"

"k8s.io/utils/ptr"
)

func TestAllocateMasqueradeIPs(t *testing.T) {
type masqueradeIPs struct {
GatewayRouter, ManagementPort string
}
var testCases = []struct {
description string
networkID int
subnet string
expectedError *string
expectedIPs masqueradeIPs
}{
{
description: "with proper network id 2 should return expected subnets",
networkID: 2,
subnet: "169.254.0.0/16",
expectedIPs: masqueradeIPs{GatewayRouter: "169.254.0.13/16", ManagementPort: "169.254.0.14/16"},
},
{
description: "with proper network id 3 should return expected subnets",
networkID: 3,
subnet: "169.254.0.0/16",
expectedIPs: masqueradeIPs{GatewayRouter: "169.254.0.15/16", ManagementPort: "169.254.0.16/16"},
},
{
description: "with one of the two address beyond the subne should return an error",
networkID: 9,
subnet: "169.254.169.0/29",
expectedError: ptr.To("failed generating network id '9' test gateway router ip: generated ip 169.254.169.27 from the idx 27 is out of range in the network 169.254.169.0/29"),
},
{
description: "with network id 0 should return an error",
networkID: 0,
subnet: "169.254.169.0/29",
expectedError: ptr.To("invalid argument: network ID should be bigger that 0"),
},
}

for _, tc := range testCases {
t.Run(tc.description, func(t *testing.T) {
g := NewWithT(t)
obtainedIPs, err := allocateMasqueradeIPs("test", tc.subnet, tc.networkID)
if tc.expectedError != nil {
g.Expect(err).To(MatchError(*tc.expectedError))
} else {
g.Expect(obtainedIPs).To(WithTransform(func(in *MasqueradeIPs) masqueradeIPs {
return masqueradeIPs{
GatewayRouter: in.GatewayRouter.String(),
ManagementPort: in.ManagementPort.String(),
}
}, Equal(tc.expectedIPs)))
}
})
}
}