diff options
Diffstat (limited to 'pkg/tcpip')
-rw-r--r-- | pkg/tcpip/stack/linkaddrcache.go | 9 | ||||
-rw-r--r-- | pkg/tcpip/stack/neighbor_cache.go | 14 | ||||
-rw-r--r-- | pkg/tcpip/stack/route.go | 72 | ||||
-rw-r--r-- | pkg/tcpip/stack/stack.go | 3 |
4 files changed, 47 insertions, 51 deletions
diff --git a/pkg/tcpip/stack/linkaddrcache.go b/pkg/tcpip/stack/linkaddrcache.go index 792f4f170..b600a1cab 100644 --- a/pkg/tcpip/stack/linkaddrcache.go +++ b/pkg/tcpip/stack/linkaddrcache.go @@ -182,15 +182,6 @@ func (c *linkAddrCache) getOrCreateEntryLocked(k tcpip.FullAddress) *linkAddrEnt // get reports any known link address for k. func (c *linkAddrCache) get(k tcpip.FullAddress, linkRes LinkAddressResolver, localAddr tcpip.Address, nic NetworkInterface, onResolve func(tcpip.LinkAddress, bool)) (tcpip.LinkAddress, <-chan struct{}, *tcpip.Error) { - if linkRes != nil { - if addr, ok := linkRes.ResolveStaticAddress(k.Addr); ok { - if onResolve != nil { - onResolve(addr, true) - } - return addr, nil, nil - } - } - c.cache.Lock() defer c.cache.Unlock() entry := c.getOrCreateEntryLocked(k) diff --git a/pkg/tcpip/stack/neighbor_cache.go b/pkg/tcpip/stack/neighbor_cache.go index c15f10e76..acee72572 100644 --- a/pkg/tcpip/stack/neighbor_cache.go +++ b/pkg/tcpip/stack/neighbor_cache.go @@ -127,20 +127,6 @@ func (n *neighborCache) getOrCreateEntry(remoteAddr tcpip.Address, linkRes LinkA // // TODO(gvisor.dev/issue/5151): Don't return the neighbor entry. func (n *neighborCache) entry(remoteAddr, localAddr tcpip.Address, linkRes LinkAddressResolver, onResolve func(tcpip.LinkAddress, bool)) (NeighborEntry, <-chan struct{}, *tcpip.Error) { - // TODO(gvisor.dev/issue/5149): Handle static resolution in route.Resolve. - if linkAddr, ok := linkRes.ResolveStaticAddress(remoteAddr); ok { - e := NeighborEntry{ - Addr: remoteAddr, - LinkAddr: linkAddr, - State: Static, - UpdatedAtNanos: 0, - } - if onResolve != nil { - onResolve(linkAddr, true) - } - return e, nil, nil - } - entry := n.getOrCreateEntry(remoteAddr, linkRes) entry.mu.Lock() defer entry.mu.Unlock() diff --git a/pkg/tcpip/stack/route.go b/pkg/tcpip/stack/route.go index 8dfde488b..1ff7b3a37 100644 --- a/pkg/tcpip/stack/route.go +++ b/pkg/tcpip/stack/route.go @@ -116,6 +116,7 @@ func constructAndValidateRoute(netProto tcpip.NetworkProtocolNumber, addressEndp r := makeRoute( netProto, + gateway, localAddr, remoteAddr, outgoingNIC, @@ -125,20 +126,12 @@ func constructAndValidateRoute(netProto tcpip.NetworkProtocolNumber, addressEndp multicastLoop, ) - // If the route requires us to send a packet through some gateway, do not - // broadcast it. - if len(gateway) > 0 { - r.NextHop = gateway - } else if subnet := addressEndpoint.Subnet(); subnet.IsBroadcast(remoteAddr) { - r.ResolveWith(header.EthernetBroadcastAddress) - } - return r } // makeRoute initializes a new route. It takes ownership of the provided // AssignableAddressEndpoint. -func makeRoute(netProto tcpip.NetworkProtocolNumber, localAddr, remoteAddr tcpip.Address, outgoingNIC, localAddressNIC *NIC, localAddressEndpoint AssignableAddressEndpoint, handleLocal, multicastLoop bool) *Route { +func makeRoute(netProto tcpip.NetworkProtocolNumber, gateway, localAddr, remoteAddr tcpip.Address, outgoingNIC, localAddressNIC *NIC, localAddressEndpoint AssignableAddressEndpoint, handleLocal, multicastLoop bool) *Route { if localAddressNIC.stack != outgoingNIC.stack { panic(fmt.Sprintf("cannot create a route with NICs from different stacks")) } @@ -164,7 +157,44 @@ func makeRoute(netProto tcpip.NetworkProtocolNumber, localAddr, remoteAddr tcpip } } - return makeRouteInner(netProto, localAddr, remoteAddr, outgoingNIC, localAddressNIC, localAddressEndpoint, loop) + r := makeRouteInner(netProto, localAddr, remoteAddr, outgoingNIC, localAddressNIC, localAddressEndpoint, loop) + if r.Loop&PacketOut == 0 { + // Packet will not leave the stack, no need for a gateway or a remote link + // address. + return r + } + + if r.outgoingNIC.LinkEndpoint.Capabilities()&CapabilityResolutionRequired != 0 { + if linkRes, ok := r.outgoingNIC.stack.linkAddrResolvers[r.NetProto]; ok { + r.linkRes = linkRes + } + } + + if len(gateway) > 0 { + r.NextHop = gateway + return r + } + + if r.linkRes == nil { + return r + } + + if linkAddr, ok := r.linkRes.ResolveStaticAddress(r.RemoteAddress); ok { + r.ResolveWith(linkAddr) + return r + } + + if subnet := localAddressEndpoint.Subnet(); subnet.IsBroadcast(remoteAddr) { + r.ResolveWith(header.EthernetBroadcastAddress) + return r + } + + if r.RemoteAddress == r.LocalAddress { + // Local link address is already known. + r.ResolveWith(r.LocalLinkAddress) + } + + return r } func makeRouteInner(netProto tcpip.NetworkProtocolNumber, localAddr, remoteAddr tcpip.Address, outgoingNIC, localAddressNIC *NIC, localAddressEndpoint AssignableAddressEndpoint, loop PacketLooping) *Route { @@ -184,12 +214,6 @@ func makeRouteInner(netProto tcpip.NetworkProtocolNumber, localAddr, remoteAddr r.mu.localAddressEndpoint = localAddressEndpoint r.mu.Unlock() - if r.outgoingNIC.LinkEndpoint.Capabilities()&CapabilityResolutionRequired != 0 { - if linkRes, ok := r.outgoingNIC.stack.linkAddrResolvers[r.NetProto]; ok { - r.linkRes = linkRes - } - } - return r } @@ -300,14 +324,13 @@ func (r *Route) Resolve(afterResolve func()) (<-chan struct{}, *tcpip.Error) { return nil, nil } + // Increment the route's reference count because finishResolution retains a + // reference to the route and releases it when called. + r.acquireLocked() + r.mu.Unlock() + nextAddr := r.NextHop if nextAddr == "" { - // Local link address is already known. - if r.RemoteAddress == r.LocalAddress { - r.mu.remoteLinkAddress = r.LocalLinkAddress - r.mu.Unlock() - return nil, nil - } nextAddr = r.RemoteAddress } @@ -318,11 +341,6 @@ func (r *Route) Resolve(afterResolve func()) (<-chan struct{}, *tcpip.Error) { linkAddressResolutionRequestLocalAddr = r.LocalAddress } - // Increment the route's reference count because finishResolution retains a - // reference to the route and releases it when called. - r.acquireLocked() - r.mu.Unlock() - finishResolution := func(linkAddress tcpip.LinkAddress, ok bool) { if ok { r.ResolveWith(linkAddress) diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go index 281bb7a9d..6d761b125 100644 --- a/pkg/tcpip/stack/stack.go +++ b/pkg/tcpip/stack/stack.go @@ -1329,6 +1329,7 @@ func (s *Stack) FindRoute(id tcpip.NICID, localAddr, remoteAddr tcpip.Address, n if addressEndpoint := s.getAddressEP(nic, localAddr, remoteAddr, netProto); addressEndpoint != nil { return makeRoute( netProto, + "", /* gateway */ localAddr, remoteAddr, nic, /* outboundNIC */ @@ -1518,7 +1519,7 @@ func (s *Stack) AddLinkAddress(nicID tcpip.NICID, addr tcpip.Address, linkAddr t // that AddLinkAddress for a particular address has been called. } -// GetLinkAddress finds the link address corresponding to the remote address. +// GetLinkAddress finds the link address corresponding to a neighbor's address. // // Returns a link address for the remote address, if readily available. // |