diff --git a/pkg/tcpip/stack/addressable_endpoint_state.go b/pkg/tcpip/stack/addressable_endpoint_state.go index 4aa734377..91b615eb6 100644 --- a/pkg/tcpip/stack/addressable_endpoint_state.go +++ b/pkg/tcpip/stack/addressable_endpoint_state.go @@ -271,7 +271,6 @@ func (a *AddressableEndpointState) addAndAcquireAddressLocked(addr tcpip.Address // We never promote an address to temporary - it can only be added as such. // If we are actually adding a permanent address, it is promoted below. addrState.kind = Temporary - addrState.disp = properties.Disp } // At this point we have an address we are either promoting from an expired or @@ -295,6 +294,7 @@ func (a *AddressableEndpointState) addAndAcquireAddressLocked(addr tcpip.Address lifetimes := properties.Lifetimes lifetimes.sanitize() addrState.lifetimes = lifetimes + addrState.disp = properties.Disp if attemptAddToPrimary { switch properties.PEB { diff --git a/pkg/tcpip/stack/addressable_endpoint_state_test.go b/pkg/tcpip/stack/addressable_endpoint_state_test.go index 55c4b0432..1798f0e84 100644 --- a/pkg/tcpip/stack/addressable_endpoint_state_test.go +++ b/pkg/tcpip/stack/addressable_endpoint_state_test.go @@ -60,3 +60,47 @@ func TestAddressableEndpointStateCleanup(t *testing.T) { t.Fatalf("got s.AcquireAssignedAddress(%s, false, NeverPrimaryEndpoint) = %s, want = nil", addr.Address, ep.AddressWithPrefix()) } } + +func TestAddressDispatcherExpiredToAssigned(t *testing.T) { + var networkEp fakeNetworkEndpoint + if err := networkEp.Enable(); err != nil { + t.Fatalf("ep.Enable(): %s", err) + } + + var s stack.AddressableEndpointState + s.Init(&networkEp, stack.AddressableEndpointStateOptions{HiddenWhileDisabled: false}) + + addr := tcpip.AddressWithPrefix{ + Address: "\x01", + PrefixLen: 8, + } + + ep, err := s.AddAndAcquirePermanentAddress(addr, stack.AddressProperties{}) + if err != nil { + t.Fatalf("s.AddAndAcquirePermanentAddress(%s, {}): %s", addr, err) + } + defer ep.DecRef() + if !ep.IncRef() { + t.Fatalf("failed to increase ref count of address endpoint") + } + + if err := s.RemovePermanentEndpoint(ep, stack.AddressRemovalManualAction); err != nil { + ep.DecRef() + t.Fatalf("s.RemovePermanentEndpoint(ep, stack.AddressRemovalManualAction): %s", err) + } + + addrDisp := &addressDispatcher{ + changedCh: make(chan addressChangedEvent, 1), + removedCh: make(chan stack.AddressRemovalReason, 1), + addr: addr, + } + properties := stack.AddressProperties{Disp: addrDisp} + readdedEp, err := s.AddAndAcquirePermanentAddress(addr, properties) + if err != nil { + t.Fatalf("s.AddAndAcquirePermanentAddress(%s, %+v): %s", addr, properties, err) + } + defer readdedEp.DecRef() + if err := addrDisp.expectChanged(stack.AddressLifetimes{}, stack.AddressAssigned); err != nil { + t.Fatalf("expect to observe address added: %s", err) + } +}