diff --git a/pkg/controllers/routing/network_routes_controller.go b/pkg/controllers/routing/network_routes_controller.go index a280fb87..0f6c8de4 100644 --- a/pkg/controllers/routing/network_routes_controller.go +++ b/pkg/controllers/routing/network_routes_controller.go @@ -1099,13 +1099,40 @@ func (nrc *NetworkRoutingController) startBgpServer(grpcServer bool) error { var localAddressList []string - if ipv4IsEnabled() { - localAddressList = append(localAddressList, nrc.localAddressList...) + if nrc.isIPv4Capable && !utils.ContainsIPv4Address(nrc.localAddressList) { + klog.Warningf("List of local addresses did not contain a valid IPv4 address, but IPv4 was " + + "enabled in kube-router's CLI options. BGP may not work as expected!") } - if ipv6IsEnabled() { - ip := utils.FindBestIPv6NodeAddress(nrc.primaryIP, nrc.nodeIPv6Addrs) - localAddressList = append(localAddressList, ip.String()) + if nrc.isIPv6Capable && !utils.ContainsIPv6Address(nrc.localAddressList) { + klog.Warningf("List of local addresses did not contain a valid IPv6 address, but IPv6 was " + + "enabled in kube-router's CLI options. BGP may not work as expected!") + } + + for _, addr := range nrc.localAddressList { + ip := net.ParseIP(addr) + // This should have been caught in NewNetworkRoutingController, but we'll check once more just to be sure + if ip == nil { + klog.Warningf("was configured to listen on %s, but address was not valid, skipping (this should "+ + "have been caught earlier in execution, please report upstream!)", addr) + continue + } + + // Make sure that the address type matches what we're capable of before listening + if ip.To4() != nil { + if !nrc.isIPv4Capable { + klog.Warningf("was configured to listen on %s, but node is not enabled for IPv4 or does not "+ + "have any IPv4 addresses configured for it, skipping", addr) + continue + } + } else { + if !nrc.isIPv6Capable { + klog.Warningf("was configured to listen on %s, but node is not enabled for IPv6 or does not "+ + "have any IPv6 addresses configured for it, skipping", addr) + continue + } + } + localAddressList = append(localAddressList, addr) } global := &gobgpapi.Global{ @@ -1485,9 +1512,16 @@ func NewNetworkRoutingController(clientset kubernetes.Interface, bgpLocalAddressListAnnotation, ok := node.ObjectMeta.Annotations[bgpLocalAddressAnnotation] if !ok { + if nrc.isIPv4Capable { + nrc.localAddressList = append(nrc.localAddressList, + utils.FindBestIPv4NodeAddress(nrc.primaryIP, nrc.nodeIPv4Addrs).String()) + } + if nrc.isIPv6Capable { + nrc.localAddressList = append(nrc.localAddressList, + utils.FindBestIPv6NodeAddress(nrc.primaryIP, nrc.nodeIPv6Addrs).String()) + } klog.Infof("Could not find annotation `kube-router.io/bgp-local-addresses` on node object so BGP "+ - "will listen on node IP: %s address.", nrc.primaryIP.String()) - nrc.localAddressList = append(nrc.localAddressList, nrc.primaryIP.String()) + "will listen on node IP: %s addresses.", nrc.localAddressList) } else { klog.Infof("Found annotation `kube-router.io/bgp-local-addresses` on node object so BGP will listen "+ "on local IP's: %s", bgpLocalAddressListAnnotation) diff --git a/pkg/controllers/routing/utils.go b/pkg/controllers/routing/utils.go index 7d3e0f12..33809000 100644 --- a/pkg/controllers/routing/utils.go +++ b/pkg/controllers/routing/utils.go @@ -85,33 +85,6 @@ func stringSliceB64Decode(s []string) ([]string, error) { return ss, nil } -func ipv4IsEnabled() bool { - l, err := net.Listen("tcp4", "") - if err != nil { - return false - } - _ = l.Close() - - return true -} - -func ipv6IsEnabled() bool { - // If ipv6 is disabled with; - // - // sysctl -w net.ipv6.conf.all.disable_ipv6=1 - // - // It is still possible to listen on the any-address "::". So this - // function tries the loopback address "::1" which must be present - // if ipv6 is enabled. - l, err := net.Listen("tcp6", "[::1]:0") - if err != nil { - return false - } - _ = l.Close() - - return true -} - func getNodeSubnet(nodeIP net.IP) (net.IPNet, string, error) { links, err := netlink.LinkList() if err != nil { diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 51f4395f..37a7d3cc 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -2,6 +2,7 @@ package utils import ( "io" + "net" "sync" ) @@ -43,3 +44,34 @@ func (b *Broadcaster) Notify(instance interface{}) { func CloseCloserDisregardError(handler io.Closer) { _ = handler.Close() } + +// 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 +}