mirror of
https://github.com/cloudnativelabs/kube-router.git
synced 2026-05-04 22:26:16 +02:00
Moves all Service VIP range configurations into pkg/svcip this is where validation and querying of ranges goes rather than passing each range to each controller. It also centralizes the validation logic since NRC and NSC need basically equivalent logic. It additionally adds a RangeQuerier interface for the NPC and LBC controllers which require knowing the literal ranges.
128 lines
3.0 KiB
Go
128 lines
3.0 KiB
Go
package utils
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"net"
|
|
)
|
|
|
|
const (
|
|
IPv4DefaultRoute = "0.0.0.0/0"
|
|
IPv6DefaultRoute = "::/0"
|
|
|
|
ipv4NetMaskBits = 32
|
|
ipv6NetMaskBits = 128
|
|
)
|
|
|
|
// GetSingleIPNet returns an IPNet object that represents a subnet containing a single IP address for a given IP address
|
|
// with proper handling for IPv4 and IPv6 addresses.
|
|
func GetSingleIPNet(ip net.IP) *net.IPNet {
|
|
if ip.To4() != nil {
|
|
return &net.IPNet{
|
|
IP: ip,
|
|
Mask: net.CIDRMask(ipv4NetMaskBits, ipv4NetMaskBits),
|
|
}
|
|
} else {
|
|
return &net.IPNet{
|
|
IP: ip,
|
|
Mask: net.CIDRMask(ipv6NetMaskBits, ipv6NetMaskBits),
|
|
}
|
|
}
|
|
}
|
|
|
|
// GetIPv4NetMaxMaskBits returns the maximum mask bits for an IPv4 address
|
|
func GetIPv4NetMaxMaskBits() uint32 {
|
|
return ipv4NetMaskBits
|
|
}
|
|
|
|
// GetIPv6NetMaxMaskBits returns the maximum mask bits for an IPv6 address
|
|
func GetIPv6NetMaxMaskBits() uint32 {
|
|
return ipv6NetMaskBits
|
|
}
|
|
|
|
// ContainsIPv4Address checks a given string array to see if it contains a valid IPv4 address within it
|
|
func ContainsIPv4Address(addrs []string) bool {
|
|
for _, addr := range addrs {
|
|
ip := net.ParseIP(addr)
|
|
if ip == nil {
|
|
continue
|
|
}
|
|
if ip.To4() != nil {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// ContainsIPv6Address checks a given string array to see if it contains a valid IPv6 address within it
|
|
func ContainsIPv6Address(addrs []string) bool {
|
|
for _, addr := range addrs {
|
|
ip := net.ParseIP(addr)
|
|
if ip == nil {
|
|
continue
|
|
}
|
|
if ip.To4() != nil {
|
|
continue
|
|
}
|
|
if ip.To16() != nil {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// GetDefaultIPv4Route returns the default IPv4 route
|
|
func GetDefaultIPv4Route() *net.IPNet {
|
|
_, defaultPrefixCIDR, err := net.ParseCIDR(IPv4DefaultRoute)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
return defaultPrefixCIDR
|
|
}
|
|
|
|
// GetDefaultIPv6Route returns the default IPv6 route
|
|
func GetDefaultIPv6Route() *net.IPNet {
|
|
_, defaultPrefixCIDR, err := net.ParseCIDR(IPv6DefaultRoute)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
return defaultPrefixCIDR
|
|
}
|
|
|
|
// IPNetEqual checks if two IPNet objects are equal by comparing the IP and Mask
|
|
func IPNetEqual(a, b *net.IPNet) bool {
|
|
if a == nil || b == nil {
|
|
return a == b
|
|
}
|
|
return a.IP.Equal(b.IP) && bytes.Equal(a.Mask, b.Mask)
|
|
}
|
|
|
|
// IsIPInRanges returns true if the given IP is contained within any of the provided CIDR ranges.
|
|
func IsIPInRanges(ip net.IP, ranges []net.IPNet) bool {
|
|
for i := range ranges {
|
|
if ranges[i].Contains(ip) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// IsDefaultRoute checks if a given CIDR is a default route by comparing it to the default routes for IPv4 and IPv6
|
|
func IsDefaultRoute(cidr *net.IPNet) (bool, error) {
|
|
var defaultPrefixCIDR *net.IPNet
|
|
var err error
|
|
|
|
if cidr.IP.To4() != nil {
|
|
_, defaultPrefixCIDR, err = net.ParseCIDR(IPv4DefaultRoute)
|
|
if err != nil {
|
|
return false, fmt.Errorf("failed to parse default route: %s", err.Error())
|
|
}
|
|
} else {
|
|
_, defaultPrefixCIDR, err = net.ParseCIDR(IPv6DefaultRoute)
|
|
if err != nil {
|
|
return false, fmt.Errorf("failed to parse default route: %s", err.Error())
|
|
}
|
|
}
|
|
return IPNetEqual(defaultPrefixCIDR, cidr), nil
|
|
}
|