Skip to content

Commit

Permalink
cmd/microcloud: Show a warning if the OVN underlay, OVN uplink, Micro…
Browse files Browse the repository at this point in the history
…Ceph cluster network, MicroCloud public network share traffic on the same network interface

Signed-off-by: Gabriel Mougard <[email protected]>

SQUASH with cmd/microcloud: Show a warning if the OVN underlay network and the MicroCeph cluster network share traffic on the same network interface

Signed-off-by: Gabriel Mougard <[email protected]>
  • Loading branch information
gabrielmougard committed Dec 3, 2024
1 parent 0c42707 commit eb8c057
Showing 1 changed file with 71 additions and 7 deletions.
78 changes: 71 additions & 7 deletions cmd/microcloud/main_init.go
Original file line number Diff line number Diff line change
Expand Up @@ -525,19 +525,83 @@ func (c *initConfig) validateSystems(s *service.Handler) (err error) {
continue
}

_, subnet, err := net.ParseCIDR(sys.MicroCephInternalNetworkSubnet)
ovnUnderlayIP := net.ParseIP(sys.OVNGeneveAddr)
if ovnUnderlayIP == nil {
return fmt.Errorf("OVN underlay IP %q is invalid", sys.OVNGeneveAddr)
}

// Get the UPLINK network's gateway IP. This is used to check for interface collisions and print eventual warnings
// to the user.
var ovnUplinkIP net.IP
var err error
for _, network := range c.systems[s.Name].Networks {
if network.Type == "physical" && network.Name == service.DefaultUplinkNetwork {
if network.Config["ipv4.gateway"] != "" {
ovnUplinkIP, _, err = net.ParseCIDR(network.Config["ipv4.gateway"])
if err != nil {
return fmt.Errorf("Failed to parse gateway IPv4 for UPLINK network %q: %w", service.DefaultUplinkNetwork, err)
}
}

if ovnUplinkIP == nil && network.Config["ipv6.gateway"] != "" {
ovnUplinkIP, _, err = net.ParseCIDR(network.Config["ipv6.gateway"])
if err != nil {
return fmt.Errorf("Failed to parse gateway IPv6 for UPLINK network %q: %w", service.DefaultUplinkNetwork, err)
}
}

if ovnUplinkIP == nil {
return fmt.Errorf("Failed to find gateway IP for UPLINK network %q", service.DefaultUplinkNetwork)
}

break
}
}

internalCephIP, subnet, err := net.ParseCIDR(sys.MicroCephInternalNetworkSubnet)
if err != nil {
return fmt.Errorf("Failed to parse available network interface CIDR address: %q: %w", subnet, err)
return fmt.Errorf("Failed to parse available network interface CIDR address for internal Ceph network: %q: %w", subnet, err)
}

underlayIP := net.ParseIP(sys.OVNGeneveAddr)
if underlayIP == nil {
return fmt.Errorf("OVN underlay IP %q is invalid", sys.OVNGeneveAddr)
// Check for interface collisions
allInterfaces := map[string]*ipWithIface{
"Ceph cluster network": {ifaceName: sys.MicroCephInternalNetworkIface, ip: internalCephIP},
"OVN underlay": {ifaceName: sys.OVNGeneveIface, ip: ovnUnderlayIP},
"OVN uplink": {ifaceName: sys.OVNUplinkIface, ip: ovnUplinkIP},
}

// The public Ceph network is not always present (partially disaggregated setup) but we still
// wish to check for interface collisions between OVN and the Ceph cluster network.
// If it is present though, add it to the list of interfaces to check for collisions.
if sys.MicroCephPublicNetworkSubnet != "" {
publicCephIP, subnet, err := net.ParseCIDR(sys.MicroCephPublicNetworkSubnet)
if err != nil {
return fmt.Errorf("Failed to parse available network interface CIDR address for public Ceph network: %q: %w", subnet, err)
}

allInterfaces["Ceph public network"] = &ipWithIface{ifaceName: sys.MicroCephPublicNetworkIface, ip: publicCephIP}
}

if subnet.Contains(underlayIP) {
fmt.Printf("Warning: OVN underlay IP (%s) is shared with the Ceph cluster network (%s)\n", underlayIP.String(), subnet.String())
interfaceCollision := false
for netNameLeft, ipWithIfaceLeft := range allInterfaces {
for netNameRight, ipWithIfaceRight := range allInterfaces {
// Skip self-comparison and already processed pairs
// (e.g. if we already compared "A vs B", we don't need to compare "B vs A").
if netNameLeft >= netNameRight {
continue
}

if ipWithIfaceLeft.ifaceName == ipWithIfaceRight.ifaceName {
if !interfaceCollision {
interfaceCollision = true
}

fmt.Printf("Warning: %s (IP: %s) is shared on the same network interface %q with the %s (IP: %s)\n", netNameLeft, ipWithIfaceLeft.ip.String(), ipWithIfaceLeft.ifaceName, netNameRight, ipWithIfaceRight.ip.String())
}
}
}

if interfaceCollision {
break
}
}
Expand Down

0 comments on commit eb8c057

Please sign in to comment.