diff --git a/calico-vpp-agent/common/common.go b/calico-vpp-agent/common/common.go index ee27a14d..b0a4cb5b 100644 --- a/calico-vpp-agent/common/common.go +++ b/calico-vpp-agent/common/common.go @@ -212,6 +212,19 @@ func FullyQualified(addr net.IP) *net.IPNet { } } +var ( + ErrNoNodeIPv4 = errors.New("no ip4 address for node") + ErrNoNodeIPv6 = errors.New("no ip6 address for node") +) + +func IsMissingNodeIP(err error) bool { + if err == nil { + return false + } + cause := errors.Cause(err) + return cause == ErrNoNodeIPv4 || cause == ErrNoNodeIPv6 +} + const ( aggregatedPrefixSetBaseName = "aggregated" hostPrefixSetBaseName = "host" @@ -289,7 +302,7 @@ func MakePath(prefix string, isWithdrawal bool, nodeIPv4 *net.IP, nodeIPv6 *net. if ipNet.IP.To4() != nil { if nodeIPv4 == nil { - return nil, fmt.Errorf("no ip4 address for node") + return nil, ErrNoNodeIPv4 } family = &BgpFamilyUnicastIPv4 if vni != 0 { @@ -298,6 +311,9 @@ func MakePath(prefix string, isWithdrawal bool, nodeIPv4 *net.IP, nodeIPv6 *net. var nhAttr *apb.Any if *config.GetCalicoVppFeatureGates().SRv6Enabled { + if nodeIPv6 == nil { + return nil, ErrNoNodeIPv6 + } nhAttr, err = apb.New(&bgpapi.NextHopAttribute{ NextHop: nodeIPv6.String(), }) @@ -312,7 +328,7 @@ func MakePath(prefix string, isWithdrawal bool, nodeIPv4 *net.IP, nodeIPv6 *net. attrs = append(attrs, nhAttr) } else { if nodeIPv6 == nil { - return nil, fmt.Errorf("no ip6 address for node") + return nil, ErrNoNodeIPv6 } family = &BgpFamilyUnicastIPv6 if vni != 0 { diff --git a/calico-vpp-agent/routing/routing_server.go b/calico-vpp-agent/routing/routing_server.go index 5ad4ae55..7defdf82 100644 --- a/calico-vpp-agent/routing/routing_server.go +++ b/calico-vpp-agent/routing/routing_server.go @@ -258,6 +258,11 @@ func (s *Server) announceLocalAddress(addr *net.IPNet, vni uint32) error { nodeIP4, nodeIP6 := common.GetBGPSpecAddresses(s.nodeBGPSpec) path, err := common.MakePath(addr.String(), false /* isWithdrawal */, nodeIP4, nodeIP6, vni, uint32(*s.BGPConf.ASNumber)) if err != nil { + if common.IsMissingNodeIP(err) { + s.log.WithError(err).Warnf("Skipping BGP announce for %s: node IP missing", addr.String()) + s.localAddressMap[addr.String()] = localAddress{ipNet: addr, vni: vni} + return nil + } return errors.Wrap(err, "error making path to announce") } s.localAddressMap[addr.String()] = localAddress{ipNet: addr, vni: vni} @@ -273,6 +278,11 @@ func (s *Server) withdrawLocalAddress(addr *net.IPNet, vni uint32) error { nodeIP4, nodeIP6 := common.GetBGPSpecAddresses(s.nodeBGPSpec) path, err := common.MakePath(addr.String(), true /* isWithdrawal */, nodeIP4, nodeIP6, vni, uint32(*s.BGPConf.ASNumber)) if err != nil { + if common.IsMissingNodeIP(err) { + s.log.WithError(err).Warnf("Skipping BGP withdraw for %s: node IP missing", addr.String()) + delete(s.localAddressMap, addr.String()) + return nil + } return errors.Wrap(err, "error making path to withdraw") } delete(s.localAddressMap, addr.String()) diff --git a/calico-vpp-agent/watchers/prefix_watcher.go b/calico-vpp-agent/watchers/prefix_watcher.go index 17ae07f6..a5049156 100644 --- a/calico-vpp-agent/watchers/prefix_watcher.go +++ b/calico-vpp-agent/watchers/prefix_watcher.go @@ -74,6 +74,10 @@ func (w *PrefixWatcher) WatchPrefix(t *tomb.Tomb) error { ip4, ip6 := common.GetBGPSpecAddresses(w.nodeBGPSpec) path, err := common.MakePath(prefix, false /* isWithdrawal */, ip4, ip6, 0, 0) if err != nil { + if common.IsMissingNodeIP(err) { + w.log.WithError(err).Warnf("Skipping prefix announcement for %s: node IP missing", prefix) + continue + } return errors.Wrap(err, "error making new path for assigned prefix") } toAdd = append(toAdd, path) @@ -90,6 +94,10 @@ func (w *PrefixWatcher) WatchPrefix(t *tomb.Tomb) error { ip4, ip6 := common.GetBGPSpecAddresses(w.nodeBGPSpec) path, err := common.MakePath(p, true /* isWithdrawal */, ip4, ip6, 0, 0) if err != nil { + if common.IsMissingNodeIP(err) { + w.log.WithError(err).Warnf("Skipping prefix withdrawal for %s: node IP missing", p) + continue + } return errors.Wrap(err, "error making new path for removed prefix") } toRemove = append(toRemove, path)