Fix not setting AddressDispatcher on promotion

AddressDispatcher was being set when adding an address only for new
addresses, resulting in cases such as when an expired addresses is
re-added to lose the AddressDispatcher that is passed.

Added a regression test.

PiperOrigin-RevId: 494220872
This commit is contained in:
Tony Gong
2022-12-09 11:25:53 -08:00
committed by gVisor bot
parent 1338761211
commit 1cbabd8225
2 changed files with 45 additions and 1 deletions
@@ -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 {
@@ -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)
}
}