Skip to content
Closed
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
3 changes: 3 additions & 0 deletions go-controller/pkg/libovsdbops/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -885,6 +885,9 @@ func CreateOrUpdateNATs(nbClient libovsdbclient.Client, router *nbdb.LogicalRout
// logical router and returns the corresponding ops
func DeleteNATsOps(nbClient libovsdbclient.Client, ops []libovsdb.Operation, router *nbdb.LogicalRouter, nats ...*nbdb.NAT) ([]libovsdb.Operation, error) {
routerNats, err := getRouterNATs(nbClient, router)
if err == libovsdbclient.ErrNotFound {
return ops, nil
}
if err != nil {
return ops, fmt.Errorf("unable to get NAT entries for router %+v: %w", router, err)
}
Expand Down
8 changes: 8 additions & 0 deletions go-controller/pkg/ovn/egressgw.go
Original file line number Diff line number Diff line change
Expand Up @@ -1015,6 +1015,10 @@ func (oc *Controller) buildClusterECMPCacheFromNamespaces(clusterRouteCache map[
}
for _, gwIP := range gwIPs {
for _, nsPod := range nsPods {
// ignore completed pods, host networked pods, pods not scheduled
if !util.PodWantsNetwork(nsPod) || util.PodCompleted(nsPod) || !util.PodScheduled(nsPod) {
continue
}
for _, podIP := range nsPod.Status.PodIPs {
if utilnet.IsIPv6(gwIP) != utilnet.IsIPv6String(podIP.IP) {
continue
Expand Down Expand Up @@ -1068,6 +1072,10 @@ func (oc *Controller) buildClusterECMPCacheFromPods(clusterRouteCache map[string
}
for _, gwIP := range gwIPs {
for _, nsPod := range nsPods {
// ignore completed pods, host networked pods, pods not scheduled
if !util.PodWantsNetwork(nsPod) || util.PodCompleted(nsPod) || !util.PodScheduled(nsPod) {
continue
}
for _, podIP := range nsPod.Status.PodIPs {
if utilnet.IsIPv6(gwIP) != utilnet.IsIPv6String(podIP.IP) {
continue
Expand Down
17 changes: 7 additions & 10 deletions go-controller/pkg/ovn/ipallocator/allocator.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,15 @@ import (
type Interface interface {
Allocate(net.IP) error
AllocateNext() (net.IP, error)
Release(net.IP) error
Release(net.IP)
ForEach(func(net.IP))
CIDR() net.IPNet

// For testing
Has(ip net.IP) bool
}

var (
ErrFull = errors.New("range is full")
ErrAllocated = errors.New("provided IP is already allocated")
ErrMismatchedNetwork = errors.New("the provided network does not match the current range")
ErrFull = errors.New("range is full")
ErrAllocated = errors.New("provided IP is already allocated")
)

type ErrNotInRange struct {
Expand Down Expand Up @@ -109,7 +106,7 @@ func NewAllocatorCIDRRange(cidr *net.IPNet, allocatorFactory allocator.Allocator
return &r, err
}

// Helper that wraps NewAllocatorCIDRRange, for creating a range backed by an in-memory store.
// NewCIDRRange is a helper that wraps NewAllocatorCIDRRange, for creating a range backed by an in-memory store.
func NewCIDRRange(cidr *net.IPNet) (*Range, error) {
return NewAllocatorCIDRRange(cidr, func(max int, rangeSpec string) (allocator.Interface, error) {
return allocator.NewAllocationMap(max, rangeSpec), nil
Expand Down Expand Up @@ -174,13 +171,13 @@ func (r *Range) AllocateNext() (net.IP, error) {
// Release releases the IP back to the pool. Releasing an
// unallocated IP or an IP out of the range is a no-op and
// returns no error.
func (r *Range) Release(ip net.IP) error {
func (r *Range) Release(ip net.IP) {
ok, offset := r.contains(ip)
if !ok {
return nil
return
}

return r.alloc.Release(offset)
r.alloc.Release(offset)
}

// ForEach calls the provided function for each allocated IP.
Expand Down
5 changes: 2 additions & 3 deletions go-controller/pkg/ovn/ipallocator/allocator/bitmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,17 +129,16 @@ func (r *AllocationBitmap) AllocateNext() (int, bool, error) {
// Release releases the item back to the pool. Releasing an
// unallocated item or an item out of the range is a no-op and
// returns no error.
func (r *AllocationBitmap) Release(offset int) error {
func (r *AllocationBitmap) Release(offset int) {
r.lock.Lock()
defer r.lock.Unlock()

if r.allocated.Bit(offset) == 0 {
return nil
return
}

r.allocated = r.allocated.SetBit(r.allocated, offset, 0)
r.count--
return nil
}

const (
Expand Down
16 changes: 4 additions & 12 deletions go-controller/pkg/ovn/ipallocator/allocator/bitmap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,7 @@ func TestRelease(t *testing.T) {
t.Errorf("expect offset %v allocated", offset)
}

if err := m.Release(offset); err != nil {
t.Errorf("unexpected error: %v", err)
}
m.Release(offset)

if m.Has(offset) {
t.Errorf("expect offset %v not allocated", offset)
Expand Down Expand Up @@ -196,9 +194,7 @@ func TestRoundRobinAllocationOrdering(t *testing.T) {
}

// Release one of the pre-allocated entries
if err := m.Release(0); err != nil {
t.Fatalf("unexpected error: %v", err)
}
m.Release(0)

// Next allocation should be after the most recently allocated entry,
// not one of the just-released ones
Expand Down Expand Up @@ -264,9 +260,7 @@ func TestRoundRobinRelease(t *testing.T) {
t.Fatalf("expect offset %d allocated", offset)
}

if err := m.Release(offset); err != nil {
t.Fatalf("unexpected error: %v", err)
}
m.Release(offset)

if m.Has(offset) {
t.Fatalf("expect offset %d not allocated", offset)
Expand All @@ -289,9 +283,7 @@ func TestRoundRobinWrapAround(t *testing.T) {
t.Fatalf("got offset %d but expected offset %d", offset, i)
}

if err := m.Release(offset); err != nil {
t.Fatalf("unexpected release error: %v", err)
}
m.Release(offset)
}
}

Expand Down
2 changes: 1 addition & 1 deletion go-controller/pkg/ovn/ipallocator/allocator/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ package allocator
type Interface interface {
Allocate(int) (bool, error)
AllocateNext() (int, bool, error)
Release(int) error
Release(int)
ForEach(func(int))

// For testing
Expand Down
8 changes: 2 additions & 6 deletions go-controller/pkg/ovn/ipallocator/allocator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,7 @@ func TestAllocate(t *testing.T) {
t.Fatal(err)
}
released := net.ParseIP(tc.released)
if err := r.Release(released); err != nil {
t.Fatal(err)
}
r.Release(released)
if f := r.Free(); f != 1 {
t.Errorf("Test %s unexpected free %d", tc.name, f)
}
Expand All @@ -131,9 +129,7 @@ func TestAllocate(t *testing.T) {
t.Errorf("Test %s unexpected %s : %s", tc.name, ip, released)
}

if err := r.Release(released); err != nil {
t.Fatal(err)
}
r.Release(released)
for _, outOfRange := range tc.outOfRange {
err = r.Allocate(net.ParseIP(outOfRange))
if _, ok := err.(*ErrNotInRange); !ok {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,8 @@ func (manager *LogicalSwitchManager) AllocateIPs(nodeName string, ipnets []*net.
// iterate over range of already allocated indices and release
// ips allocated before the error occurred.
for relIdx, relIPNet := range allocated {
if relErr := lsi.ipams[relIdx].Release(relIPNet.IP); relErr != nil {
klog.Errorf("Error while releasing IP: %s, err: %v", relIPNet.IP, relErr)
} else if relIPNet.IP != nil {
lsi.ipams[relIdx].Release(relIPNet.IP)
if relIPNet.IP != nil {
klog.Warningf("Reserved IP: %s was released", relIPNet.IP.String())
}
}
Expand Down Expand Up @@ -271,9 +270,8 @@ func (manager *LogicalSwitchManager) AllocateNextIPs(nodeName string) ([]*net.IP
// iterate over range of already allocated indices and release
// ips allocated before the error occurred.
for relIdx, relIPNet := range ipnets {
if relErr := lsi.ipams[relIdx].Release(relIPNet.IP); relErr != nil {
klog.Errorf("Error while releasing IP: %s, err: %v", relIPNet.IP, relErr)
} else if relIPNet.IP != nil {
lsi.ipams[relIdx].Release(relIPNet.IP)
if relIPNet.IP != nil {
klog.Warningf("Reserved IP: %s was released", relIPNet.IP.String())
}
}
Expand Down Expand Up @@ -315,16 +313,48 @@ func (manager *LogicalSwitchManager) ReleaseIPs(nodeName string, ipnets []*net.I
for _, ipam := range lsi.ipams {
cidr := ipam.CIDR()
if cidr.Contains(ipnet.IP) {
if err := ipam.Release(ipnet.IP); err != nil {
return err
}
ipam.Release(ipnet.IP)
break
}
}
}
return nil
}

// ConditionalIPRelease determines if any IP is available to be released from an IPAM conditionally if func is true.
// It guarantees state of the allocator will not change while executing the predicate function
// TODO(trozet): add unit testing for this function
func (manager *LogicalSwitchManager) ConditionalIPRelease(nodeName string, ipnets []*net.IPNet, predicate func() (bool, error)) (bool, error) {
manager.RLock()
defer manager.RUnlock()
if ipnets == nil || nodeName == "" {
klog.V(5).Infof("Node name is empty or ip slice to release is nil")
return false, nil
}
lsi, ok := manager.cache[nodeName]
if !ok {
return false, nil
}
if len(lsi.ipams) == 0 {
return false, nil
}

// check if ipam has one of the ip addresses, and then execute the predicate function to determine
// if this IP should be released or not
for _, ipnet := range ipnets {
for _, ipam := range lsi.ipams {
cidr := ipam.CIDR()
if cidr.Contains(ipnet.IP) {
if ipam.Has(ipnet.IP) {
return predicate()
}
}
}
}

return false, nil
}

// IP allocator manager for join switch's IPv4 and IPv6 subnets.
type JoinSwitchIPManager struct {
lsm *LogicalSwitchManager
Expand Down
3 changes: 3 additions & 0 deletions go-controller/pkg/ovn/master.go
Original file line number Diff line number Diff line change
Expand Up @@ -1374,6 +1374,9 @@ func (oc *Controller) addUpdateNodeEvent(node *kapi.Node, nSyncs *nodeSyncs) err
klog.V(5).Infof("When adding node %s, found %d pods to add to retryPods", node.Name, len(pods.Items))
for _, pod := range pods.Items {
pod := pod
if util.PodCompleted(&pod) {
continue
}
klog.V(5).Infof("Adding pod %s/%s to retryPods", pod.Namespace, pod.Name)
oc.retryPods.addRetryObj(&pod)
}
Expand Down
2 changes: 1 addition & 1 deletion go-controller/pkg/ovn/namespace.go
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,7 @@ func (oc *Controller) createNamespaceAddrSetAllPods(ns string) (addressset.Addre
} else {
ips = make([]net.IP, 0, len(existingPods))
for _, pod := range existingPods {
if !pod.Spec.HostNetwork {
if util.PodWantsNetwork(pod) && !util.PodCompleted(pod) && util.PodScheduled(pod) {
podIPs, err := util.GetAllPodIPs(pod)
if err != nil {
klog.Warningf(err.Error())
Expand Down
12 changes: 9 additions & 3 deletions go-controller/pkg/ovn/obj_retry.go
Original file line number Diff line number Diff line change
Expand Up @@ -997,7 +997,7 @@ func (oc *Controller) WatchResource(objectsToRetry *retryObjs) *factory.Handler
klog.Errorf("Upon add event: %v", err)
return
}
klog.Infof("Add event received for resource %v, key=%s", objectsToRetry.oType, key)
klog.V(5).Infof("Add event received for resource %v, key=%s", objectsToRetry.oType, key)

objectsToRetry.initRetryObjWithAdd(obj, key)
objectsToRetry.skipRetryObj(key)
Expand Down Expand Up @@ -1074,7 +1074,7 @@ func (oc *Controller) WatchResource(objectsToRetry *retryObjs) *factory.Handler
return
}

klog.Infof("Update event received for resource %v, oldKey=%s, newKey=%s",
klog.V(5).Infof("Update event received for resource %v, oldKey=%s, newKey=%s",
objectsToRetry.oType, oldKey, newKey)

objectsToRetry.skipRetryObj(newKey)
Expand Down Expand Up @@ -1165,7 +1165,13 @@ func (oc *Controller) WatchResource(objectsToRetry *retryObjs) *factory.Handler
klog.Errorf("Delete of resource %v failed: %v", objectsToRetry.oType, err)
return
}
klog.Infof("Delete event received for resource %v %s", objectsToRetry.oType, key)
klog.V(5).Infof("Delete event received for resource %v %s", objectsToRetry.oType, key)
// If object is in terminal state, we would have already deleted it during update.
// No reason to attempt to delete it here again.
if oc.isObjectInTerminalState(objectsToRetry.oType, obj) {
klog.Infof("Ignoring delete event for completed resource %v %s", objectsToRetry.oType, key)
return
}
objectsToRetry.skipRetryObj(key)
internalCacheEntry := oc.getInternalCacheEntry(objectsToRetry.oType, obj)
objectsToRetry.initRetryObjWithDelete(obj, key, internalCacheEntry) // set up the retry obj for deletion
Expand Down
Loading