mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
ConfirmReachable with the cached neighbor entry
This avoids a map lookup (RLock) in the TCP data path. PiperOrigin-RevId: 479659280
This commit is contained in:
committed by
gVisor bot
parent
10a1cadd73
commit
39ac7df1b7
@@ -294,19 +294,6 @@ func (n *neighborCache) handleConfirmation(addr tcpip.Address, linkAddr tcpip.Li
|
||||
}
|
||||
}
|
||||
|
||||
// handleUpperLevelConfirmation processes a confirmation of reachablity from
|
||||
// some protocol that operates at a layer above the IP/link layer.
|
||||
func (n *neighborCache) handleUpperLevelConfirmation(addr tcpip.Address) {
|
||||
n.mu.RLock()
|
||||
entry, ok := n.mu.cache[addr]
|
||||
n.mu.RUnlock()
|
||||
if ok {
|
||||
entry.mu.Lock()
|
||||
entry.handleUpperLevelConfirmationLocked()
|
||||
entry.mu.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func (n *neighborCache) init(nic *nic, r LinkAddressResolver) {
|
||||
*n = neighborCache{
|
||||
nic: nic,
|
||||
|
||||
@@ -589,11 +589,12 @@ func (e *neighborEntry) handleConfirmationLocked(linkAddr tcpip.LinkAddress, fla
|
||||
}
|
||||
}
|
||||
|
||||
// handleUpperLevelConfirmationLocked processes an incoming upper-level protocol
|
||||
// handleUpperLevelConfirmation processes an incoming upper-level protocol
|
||||
// (e.g. TCP acknowledgements) reachability confirmation.
|
||||
//
|
||||
// Precondition: e.mu MUST be locked.
|
||||
func (e *neighborEntry) handleUpperLevelConfirmationLocked() {
|
||||
func (e *neighborEntry) handleUpperLevelConfirmation() {
|
||||
e.mu.Lock()
|
||||
defer e.mu.Unlock()
|
||||
|
||||
switch e.mu.neigh.State {
|
||||
case Stale, Delay, Probe:
|
||||
e.setStateLocked(Reachable)
|
||||
|
||||
@@ -1415,12 +1415,12 @@ func TestEntryDelayToReachableWhenUpperLevelConfirmation(t *testing.T) {
|
||||
t.Fatalf("staleToDelay(...) = %s", err)
|
||||
}
|
||||
|
||||
e.mu.Lock()
|
||||
e.handleUpperLevelConfirmationLocked()
|
||||
e.handleUpperLevelConfirmation()
|
||||
e.mu.RLock()
|
||||
if e.mu.neigh.State != Reachable {
|
||||
t.Errorf("got e.mu.neigh.State = %q, want = %q", e.mu.neigh.State, Reachable)
|
||||
}
|
||||
e.mu.Unlock()
|
||||
e.mu.RUnlock()
|
||||
|
||||
// No probes should have been sent.
|
||||
runImmediatelyScheduledJobs(clock)
|
||||
|
||||
@@ -30,10 +30,6 @@ type linkResolver struct {
|
||||
neigh neighborCache
|
||||
}
|
||||
|
||||
func (l *linkResolver) confirmReachable(addr tcpip.Address) {
|
||||
l.neigh.handleUpperLevelConfirmation(addr)
|
||||
}
|
||||
|
||||
var _ NetworkInterface = (*nic)(nil)
|
||||
var _ NetworkDispatcher = (*nic)(nil)
|
||||
|
||||
|
||||
@@ -581,7 +581,7 @@ func (r *Route) IsOutboundBroadcast() bool {
|
||||
// "Reachable" is defined as having full-duplex communication between the
|
||||
// local and remote ends of the route.
|
||||
func (r *Route) ConfirmReachable() {
|
||||
if r.linkRes != nil {
|
||||
r.linkRes.confirmReachable(r.nextHop())
|
||||
if entry := r.getCachedNeighborEntry(); entry != nil {
|
||||
entry.handleUpperLevelConfirmation()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1391,8 +1391,20 @@ func TestTCPConfirmNeighborReachability(t *testing.T) {
|
||||
if err := listenerEP.Bind(listenerAddr); err != nil {
|
||||
t.Fatalf("listenerEP.Bind(%#v): %s", listenerAddr, err)
|
||||
}
|
||||
if err := listenerEP.Listen(1); err != nil {
|
||||
t.Fatalf("listenerEP.Listen(1): %s", err)
|
||||
// A backlog of 1 results in SYN cookies being used for all passive
|
||||
// connections to make sure the only spot in the accept queue is not
|
||||
// taken by a connection that never completes the handshake. We use
|
||||
// a backlog of 2 to make sure SYN cookies are not used.
|
||||
//
|
||||
// We avoid SYN cookies to make sure that an accepted endpoint is able
|
||||
// to confirm the neighbor's reachability through the cached neighbor
|
||||
// entry in the endpoint's route. When SYN cookies are used, the
|
||||
// accepted endpoint is constructed when the handshake has already been
|
||||
// established and such an endpoint's route will not have a cached
|
||||
// neighbor entry as it was not used to send any of packets for the
|
||||
// handshake.
|
||||
if err := listenerEP.Listen(2); err != nil {
|
||||
t.Fatalf("listenerEP.Listen(2): %s", err)
|
||||
}
|
||||
{
|
||||
err := clientEP.Connect(listenerAddr)
|
||||
|
||||
Reference in New Issue
Block a user