Skip to content

Commit 3f0e1ae

Browse files
authored
Merge pull request #1534 from kmesh-net/copilot/fix-waypoint-address-bug
Fix waypoint address missing in ebpf/endpoints when LocalityInfo is nil
2 parents 6c2b4d1 + 7500f9e commit 3f0e1ae

File tree

2 files changed

+77
-2
lines changed

2 files changed

+77
-2
lines changed

pkg/controller/workload/workload_processor.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -458,8 +458,16 @@ func (p *Processor) handleWorkloadNewBoundServices(workload *workloadapi.Workloa
458458
}
459459
} else { // locality mode
460460
service := p.ServiceCache.GetService(p.hashName.NumToStr(svcUid))
461-
if p.locality.LocalityInfo != nil && service != nil {
462-
prio := p.locality.CalcLocalityLBPrio(workload, service.LoadBalancing.GetRoutingPreference())
461+
if service != nil {
462+
var prio uint32
463+
if p.locality.LocalityInfo != nil {
464+
prio = p.locality.CalcLocalityLBPrio(workload, service.LoadBalancing.GetRoutingPreference())
465+
} else {
466+
// If locality is not yet initialized, use highest priority (0)
467+
// This ensures the workload is added to the endpoint map and will be recalculated
468+
// when locality is eventually set
469+
prio = 0
470+
}
463471
if _, err = p.addWorkloadToService(&sk, &sv, workloadId, prio); err != nil {
464472
log.Errorf("addWorkloadToService workload %d service %d priority %d failed: %v", workloadId, sk.ServiceId, prio, err)
465473
return err

pkg/controller/workload/workload_processor_test.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -784,3 +784,70 @@ func TestUpdateWorkloadInFrontendMap(t *testing.T) {
784784
assert.NoError(t, err)
785785
})
786786
}
787+
788+
// TestLocalityLBWithNilLocalityInfo verifies that workloads are correctly added
789+
// to service endpoints even when LocalityInfo is nil in locality LB mode.
790+
// This tests the fix for the issue where waypoint addresses were missing in
791+
// ebpf/endpoints because LocalityInfo was not initialized when workloads from
792+
// other nodes arrived before any local workload.
793+
func TestLocalityLBWithNilLocalityInfo(t *testing.T) {
794+
workloadMap := bpfcache.NewFakeWorkloadMap(t)
795+
defer bpfcache.CleanupFakeWorkloadMap(workloadMap)
796+
797+
p := NewProcessor(workloadMap)
798+
799+
// Ensure LocalityInfo is nil (simulating no local workload has been processed yet)
800+
assert.Nil(t, p.locality.LocalityInfo)
801+
802+
res := &service_discovery_v3.DeltaDiscoveryResponse{}
803+
804+
// Create a service with locality LB (FAILOVER mode, which is the default for waypoints)
805+
localityLBScope := []workloadapi.LoadBalancing_Scope{
806+
workloadapi.LoadBalancing_REGION,
807+
workloadapi.LoadBalancing_ZONE,
808+
workloadapi.LoadBalancing_SUBZONE,
809+
}
810+
localityLoadBalancing := createLoadBalancing(workloadapi.LoadBalancing_FAILOVER, localityLBScope)
811+
svc := common.CreateFakeService("svc1", "10.240.10.1", "10.240.10.200", localityLoadBalancing)
812+
813+
addr := serviceToAddress(svc)
814+
res.Resources = append(res.Resources, &service_discovery_v3.Resource{
815+
Resource: protoconv.MessageToAny(addr),
816+
})
817+
818+
// Add a workload from a different node (simulating waypoint workload)
819+
// This workload arrives before any local workload, so LocalityInfo is still nil
820+
wl := createWorkload("waypoint1", "10.244.0.1", "other-node", workloadapi.NetworkMode_STANDARD, createLocality("r1", "z1", "s1"), "svc1")
821+
wlAddr := workloadToAddress(wl)
822+
res.Resources = append(res.Resources, &service_discovery_v3.Resource{
823+
Resource: protoconv.MessageToAny(wlAddr),
824+
})
825+
826+
err := p.handleAddressTypeResponse(res)
827+
assert.NoError(t, err)
828+
829+
// LocalityInfo should still be nil since no local workload was processed
830+
assert.Nil(t, p.locality.LocalityInfo)
831+
832+
// Verify the workload is in the frontend map
833+
workloadID := checkFrontEndMap(t, wl.Addresses[0], p)
834+
835+
// Verify the service is in the frontend map
836+
svcID := checkFrontEndMap(t, svc.Addresses[0].Address, p)
837+
838+
// Verify the endpoint was added to the service
839+
// When LocalityInfo is nil, the workload should be added with the highest priority (0)
840+
var ek bpfcache.EndpointKey
841+
var ev bpfcache.EndpointValue
842+
ek.ServiceId = svcID
843+
ek.Prio = 0 // highest priority when LocalityInfo is nil
844+
ek.BackendIndex = 1
845+
err = p.bpf.EndpointLookup(&ek, &ev)
846+
assert.NoError(t, err, "Endpoint should exist in endpoint map with highest priority")
847+
assert.Equal(t, workloadID, ev.BackendUid)
848+
849+
// Verify the endpoint count in the service map
850+
checkServiceMap(t, p, svcID, svc, 0, 1)
851+
852+
hashNameClean(p)
853+
}

0 commit comments

Comments
 (0)