From 949461f2b3624329b4c02744e10c631dabd53eaa Mon Sep 17 00:00:00 2001 From: Lucas Manning Date: Tue, 19 Sep 2023 13:43:39 -0700 Subject: [PATCH] Automated rollback of changelist 558922801 PiperOrigin-RevId: 566731014 --- pkg/tcpip/network/ipv4/ipv4.go | 18 +---------- pkg/tcpip/stack/addressable_endpoint_state.go | 30 +++++++++++++++++-- pkg/tcpip/stack/stack_test.go | 2 +- pkg/tcpip/transport/udp/udp_test.go | 29 ++++++------------ 4 files changed, 38 insertions(+), 41 deletions(-) diff --git a/pkg/tcpip/network/ipv4/ipv4.go b/pkg/tcpip/network/ipv4/ipv4.go index de58ca304..2e5ab0264 100644 --- a/pkg/tcpip/network/ipv4/ipv4.go +++ b/pkg/tcpip/network/ipv4/ipv4.go @@ -1424,23 +1424,7 @@ func (e *endpoint) AcquireOutgoingPrimaryAddress(remoteAddr tcpip.Address, allow // // +checklocksread:e.mu func (e *endpoint) acquireOutgoingPrimaryAddressRLocked(remoteAddr tcpip.Address, allowExpired bool) stack.AddressEndpoint { - if remoteAddr.BitLen() == 0 { - return e.addressableEndpointState.AcquireOutgoingPrimaryAddress(remoteAddr, allowExpired) - } - - var best stack.AddressEndpoint - var bestLen uint8 - e.addressableEndpointState.ForEachPrimaryEndpoint(func(ep stack.AddressEndpoint) bool { - if matchLen := ep.AddressWithPrefix().Address.MatchingPrefix(remoteAddr); best == nil || bestLen < matchLen { - best = ep - bestLen = matchLen - } - return true - }) - if best != nil { - best.IncRef() - } - return best + return e.addressableEndpointState.AcquireOutgoingPrimaryAddress(remoteAddr, allowExpired) } // PrimaryAddresses implements stack.AddressableEndpoint. diff --git a/pkg/tcpip/stack/addressable_endpoint_state.go b/pkg/tcpip/stack/addressable_endpoint_state.go index 91b615eb6..e1c151ebf 100644 --- a/pkg/tcpip/stack/addressable_endpoint_state.go +++ b/pkg/tcpip/stack/addressable_endpoint_state.go @@ -18,6 +18,7 @@ import ( "fmt" "gvisor.dev/gvisor/pkg/tcpip" + "gvisor.dev/gvisor/pkg/tcpip/header" ) func (lifetimes *AddressLifetimes) sanitize() { @@ -433,7 +434,7 @@ func (a *AddressableEndpointState) MainAddress() tcpip.AddressWithPrefix { a.mu.RLock() defer a.mu.RUnlock() - ep := a.acquirePrimaryAddressRLocked(func(ep *addressState) bool { + ep := a.acquirePrimaryAddressRLocked(tcpip.Address{}, func(ep *addressState) bool { switch kind := ep.GetKind(); kind { case Permanent: return a.networkEndpoint.Enabled() || !a.options.HiddenWhileDisabled @@ -461,7 +462,30 @@ func (a *AddressableEndpointState) MainAddress() tcpip.AddressWithPrefix { // valid according to isValid. // // +checklocksread:a.mu -func (a *AddressableEndpointState) acquirePrimaryAddressRLocked(isValid func(*addressState) bool) *addressState { +func (a *AddressableEndpointState) acquirePrimaryAddressRLocked(remoteAddr tcpip.Address, isValid func(*addressState) bool) *addressState { + // TODO: Move this out into IPv4-specific code. + // IPv6 handles source IP selection elsewhere. We have to do source + // selection only for IPv4, in which case ep is never deprecated. Thus + // we don't have to worry about refcounts. + if remoteAddr.Len() == header.IPv4AddressSize && remoteAddr != (tcpip.Address{}) { + var best *addressState + var bestLen uint8 + for _, state := range a.primary { + if !isValid(state) { + continue + } + stateLen := state.addr.Address.MatchingPrefix(remoteAddr) + if best == nil || bestLen < stateLen { + best = state + bestLen = stateLen + } + } + if best != nil { + best.IncRef() + } + return best + } + var deprecatedEndpoint *addressState for _, ep := range a.primary { if !isValid(ep) { @@ -599,7 +623,7 @@ func (a *AddressableEndpointState) AcquireOutgoingPrimaryAddress(remoteAddr tcpi a.mu.Lock() defer a.mu.Unlock() - ep := a.acquirePrimaryAddressRLocked(func(ep *addressState) bool { + ep := a.acquirePrimaryAddressRLocked(remoteAddr, func(ep *addressState) bool { return ep.IsAssigned(allowExpired) }) diff --git a/pkg/tcpip/stack/stack_test.go b/pkg/tcpip/stack/stack_test.go index baa052721..16bb05119 100644 --- a/pkg/tcpip/stack/stack_test.go +++ b/pkg/tcpip/stack/stack_test.go @@ -1310,7 +1310,7 @@ func TestRoutes(t *testing.T) { testRoute(t, s, 1, tcpip.AddrFromSlice([]byte("\x03\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x05\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x03\x00\x00\x00"))) // Test routes to even address. - testRoute(t, s, 0, tcpip.Address{}, tcpip.AddrFromSlice([]byte("\x06\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x02\x00\x00\x00"))) + testRoute(t, s, 0, tcpip.Address{}, tcpip.AddrFromSlice([]byte("\x06\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x04\x00\x00\x00"))) testRoute(t, s, 0, tcpip.AddrFromSlice([]byte("\x02\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x06\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x02\x00\x00\x00"))) testRoute(t, s, 2, tcpip.AddrFromSlice([]byte("\x02\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x06\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x02\x00\x00\x00"))) testRoute(t, s, 0, tcpip.AddrFromSlice([]byte("\x04\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x06\x00\x00\x00")), tcpip.AddrFromSlice([]byte("\x04\x00\x00\x00"))) diff --git a/pkg/tcpip/transport/udp/udp_test.go b/pkg/tcpip/transport/udp/udp_test.go index 21c8529e7..750c77091 100644 --- a/pkg/tcpip/transport/udp/udp_test.go +++ b/pkg/tcpip/transport/udp/udp_test.go @@ -725,31 +725,20 @@ func TestDualWriteConnectedToV4Mapped(t *testing.T) { } func TestPreflightBindsEndpoint(t *testing.T) { - tcs := []struct { - name string - proto tcpip.NetworkProtocolNumber - flow context.TestFlow - }{ - { - name: "ipv4", - proto: ipv4.ProtocolNumber, - flow: context.UnicastV4, - }, - { - name: "ipv6", - proto: ipv6.ProtocolNumber, - flow: context.UnicastV6, - }, + protocols := map[string]tcpip.NetworkProtocolNumber{ + "ipv4": ipv4.ProtocolNumber, + "ipv6": ipv6.ProtocolNumber, } - for _, tc := range tcs { - t.Run(tc.name, func(t *testing.T) { + for name, ipProtocolNumber := range protocols { + t.Run(name, func(t *testing.T) { c := context.New(t, []stack.TransportProtocolFactory{udp.NewProtocol}) defer c.Cleanup() - c.CreateEndpoint(tc.proto, udp.ProtocolNumber) + c.CreateEndpoint(ipProtocolNumber, udp.ProtocolNumber) - h := tc.flow.MakeHeader4Tuple(context.Outgoing) - writeDstAddr := tc.flow.MapAddrIfApplicable(h.Dst.Addr) + flow := context.UnicastV6 + h := flow.MakeHeader4Tuple(context.Outgoing) + writeDstAddr := flow.MapAddrIfApplicable(h.Dst.Addr) writeOpts := tcpip.WriteOptions{ To: &tcpip.FullAddress{Addr: writeDstAddr, Port: h.Dst.Port}, }