Commit Graph

15 Commits

Author SHA1 Message Date
Tamir Duberstein 6bc27946a6 Plumb link address request errors up to requester
Prevent the situation where callers to (*stack).GetLinkAddress provide
incorrect arguments and are unable to observe this condition.

Updates #5583.

PiperOrigin-RevId: 360481557
2021-03-02 11:58:12 -08:00
Ghanan Gowripalan 9530f624e9 Unexpose NIC
The NIC structure is not to be used outside of the stack package
directly.

PiperOrigin-RevId: 356036737
2021-02-06 09:49:14 -08:00
Ghanan Gowripalan d6a39734c4 Avoid locking when route doesn't require resolution
When a route does not need to resolve a remote link address to send a
packet, avoid having to obtain the pending packets queue's lock.

PiperOrigin-RevId: 354456280
2021-01-28 20:32:09 -08:00
Tamir Duberstein 8d1afb4185 Change tcpip.Error to an interface
This makes it possible to add data to types that implement tcpip.Error.
ErrBadLinkEndpoint is removed as it is unused.

PiperOrigin-RevId: 354437314
2021-01-28 17:59:58 -08:00
Ghanan Gowripalan f190e13a74 Pass RouteInfo to the route resolve callback
The route resolution callback will be called with a
stack.ResolvedFieldsResult which will hold the route info so callers
can avoid attempting resolution again to check if a previous resolution
attempt succeeded or not.

Test: integration_test.TestRouteResolvedFields
PiperOrigin-RevId: 353319019
2021-01-22 14:25:46 -08:00
Ghanan Gowripalan 8ecff18902 Do not cache remote link address in Route
...unless explicitly requested via ResolveWith.

Remove cancelled channels from pending packets as we can use the link
resolution channel in a FIFO to limit the number of maximum pending
resolutions we should queue packets for.

This change also defers starting the goroutine that handles link
resolution completion to when link resolution succeeds, fails or
gets cancelled due to the max number of pending resolutions being
reached.

Fixes #751.

PiperOrigin-RevId: 353130577
2021-01-21 16:40:06 -08:00
Ghanan Gowripalan 89df5a681c Queue packets in WritePackets when resolving link address
Test: integration_test.TestWritePacketsLinkResolution

Fixes #4458.

PiperOrigin-RevId: 353108826
2021-01-21 14:54:14 -08:00
Arthur Sfez be17b94446 Per NIC NetworkEndpoint statistics
To facilitate the debugging of multi-homed setup, track Network
protocols statistics for each endpoint. Note that the original
stack-wide stats still exist.

A new type of statistic counter is introduced, which track two
versions of a stat at the same time. This lets a network endpoint
increment both the local stat and the stack-wide stat at the same
time.

Fixes #4605

PiperOrigin-RevId: 352663276
2021-01-19 15:07:39 -08:00
Ghanan Gowripalan fd5b52c87f Only pass stack.Route's fields to LinkEndpoints
stack.Route is used to send network packets and resolve link addresses.
A LinkEndpoint does not need to do either of these and only needs the
route's fields at the time of the packet write request.

Since LinkEndpoints only need the route's fields when writing packets,
pass a stack.RouteInfo instead.

PiperOrigin-RevId: 352108405
2021-01-15 16:49:15 -08:00
Ghanan Gowripalan 25b5ec7135 Do not resolve remote link address at transport layer
Link address resolution is performed at the link layer (if required) so
we can defer it from the transport layer. When link resolution is
required, packets will be queued and sent once link resolution
completes. If link resolution fails, the transport layer will receive a
control message indicating that the stack failed to route the packet.

tcpip.Endpoint.Write no longer returns a channel now that writes do not
wait for link resolution at the transport layer.

tcpip.ErrNoLinkAddress is no longer used so it is removed.

Removed calls to stack.Route.ResolveWith from the transport layer so
that link resolution is performed when a route is created in response
to an incoming packet (e.g. to complete TCP handshakes or send a RST).

Tests:
- integration_test.TestForwarding
- integration_test.TestTCPLinkResolutionFailure

Fixes #4458

RELNOTES: n/a
PiperOrigin-RevId: 351684158
2021-01-13 16:04:33 -08:00
Peter Johnston fee2cd640f Invoke address resolution upon subsequent traffic to Failed neighbor
Removes the period of time in which subseqeuent traffic to a Failed neighbor
immediately fails with ErrNoLinkAddress. A Failed neighbor is one in which
address resolution fails; or in other words, the neighbor's IP address cannot
be translated to a MAC address.

This means removing the Failed state for linkAddrCache and allowing transitiong
out of Failed into Incomplete for neighborCache. Previously, both caches would
transition entries to Failed after address resolution fails. In this state, any
subsequent traffic requested within an unreachable time would immediately fail
with ErrNoLinkAddress. This does not follow RFC 4861 section 7.3.3:

  If address resolution fails, the entry SHOULD be deleted, so that subsequent
  traffic to that neighbor invokes the next-hop determination procedure again.
  Invoking next-hop determination at this point ensures that alternate default
  routers are tried.

The API for getting a link address for a given address, whether through the link
address cache or the neighbor table, is updated to optionally take a callback
which will be called when address resolution completes. This allows `Route` to
handle completing link resolution internally, so callers of (*Route).Resolve
(e.g. endpoints) don’t have to keep track of when it completes and update the
Route accordingly.

This change also removes the wakers from LinkAddressCache, NeighborCache, and
Route in favor of the callbacks, and callers that previously used a waker can
now just pass a callback to (*Route).Resolve that will notify the waker on
resolution completion.

Fixes #4796

Startblock:
  has LGTM from sbalana
  and then
  add reviewer ghanan
PiperOrigin-RevId: 348597478
2020-12-22 01:37:05 -08:00
Ghanan Gowripalan 8c0701462a Use stack.Route exclusively for writing packets
* Remove stack.Route from incoming packet path.
There is no need to pass around a stack.Route during the incoming path
of a packet. Instead, pass around the packet's link/network layer
information in the packet buffer since all layers may need this
information.

* Support address bound and outgoing packet NIC in routes.
When forwarding is enabled, the source address of a packet may be bound
to a different interface than the outgoing interface. This change
updates stack.Route to hold both NICs so that one can be used to write
packets while the other is used to check if the route's bound address
is valid. Note, we need to hold the address's interface so we can check
if the address is a spoofed address.

* Introduce the concept of a local route.
Local routes are routes where the packet never needs to leave the stack;
the destination is stack-local. We can now route between interfaces
within a stack if the packet never needs to leave the stack, even when
forwarding is disabled.

* Always obtain a route from the stack before sending a packet.
If a packet needs to be sent in response to an incoming packet, a route
must be obtained from the stack to ensure the stack is configured to
send packets to the packet's source from the packet's destination.

* Enable spoofing if a stack may send packets from unowned addresses.
This change required changes to some netgophers since previously,
promiscuous mode was enough to let the netstack respond to all
incoming packets regardless of the packet's destination address. Now
that a stack.Route is not held for each incoming packet, finding a route
may fail with local addresses we don't own but accepted packets for
while in promiscuous mode. Since we also want to be able to send from
any address (in response the received promiscuous mode packets), we need
to enable spoofing.

* Skip transport layer checksum checks for locally generated packets.
If a packet is locally generated, the stack can safely assume that no
errors were introduced while being locally routed since the packet is
never sent out the wire.

Some bugs fixed:
- transport layer checksum was never calculated after NAT.
- handleLocal didn't handle routing across interfaces.
- stack didn't support forwarding across interfaces.
- always consult the routing table before creating an endpoint.

Updates #4688
Fixes #3906

PiperOrigin-RevId: 340943442
2020-11-05 15:52:16 -08:00
Ghanan Gowripalan 257703c050 Automated rollback of changelist 336304024
PiperOrigin-RevId: 336339194
2020-10-09 12:09:12 -07:00
Bhasker Hariharan 8566decab0 Automated rollback of changelist 336185457
PiperOrigin-RevId: 336304024
2020-10-09 09:11:18 -07:00
Ghanan Gowripalan 6768e6c59e Do not resolve routes immediately
When a response needs to be sent to an incoming packet, the stack should
consult its neighbour table to determine the remote address's link
address.

When an entry does not exist in the stack's neighbor table, the stack
should queue the packet while link resolution completes. See comments.

PiperOrigin-RevId: 336185457
2020-10-08 16:15:59 -07:00