Commit Graph

182 Commits

Author SHA1 Message Date
Ghanan Gowripalan a073d76979 Return tcpip.Error from (*Stack).GetMainNICAddress
PiperOrigin-RevId: 364381970
2021-03-22 12:31:46 -07:00
Ghanan Gowripalan 68065d1ceb Detect looped-back NDP DAD messages
...as per RFC 7527.

If a looped-back DAD message is received, do not fail DAD since our own
DAD message does not indicate that a neighbor has the address assigned.

Test: ndp_test.TestDADResolveLoopback
PiperOrigin-RevId: 363224288
2021-03-16 11:09:26 -07:00
Ghanan Gowripalan ebd7c1b889 Do not call into Stack from LinkAddressRequest
Calling into the stack from LinkAddressRequest is not needed as we
already have a reference to the network endpoint (IPv6) or network
interface (IPv4/ARP).

PiperOrigin-RevId: 363213973
2021-03-16 10:29:49 -07:00
Kevin Krakauer abbdcebc54 Implement /proc/sys/net/ipv4/ip_local_port_range
Speeds up the socket stress tests by a couple orders of magnitude.

PiperOrigin-RevId: 361721050
2021-03-08 20:40:34 -08:00
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 39251f31cb Support performing DAD for any address
...as long as the network protocol supports duplicate address detection.

This CL provides the facilities for a netstack integrator to perform
DAD.

DHCP recommends that clients effectively perform DAD before accepting an
offer. As per RFC 2131 section 4.4.1 pg 38,

  The client SHOULD perform a check on the suggested address to ensure
  that the address is not already in use.  For example, if the client
  is on a network that supports ARP, the client may issue an ARP request
  for the suggested request.

The implementation of ARP-based IPv4 DAD effectively operates the same
as IPv6's NDP DAD - using ARP requests and responses in place of
NDP neighbour solicitations and advertisements, respectively.

DAD performed by calls to (*Stack).CheckDuplicateAddress don't interfere
with DAD performed when a new IPv6 address is added. This is so that
integrator requests to check for duplicate addresses aren't unexpectedly
aborted when addresses are removed.

A network package internal package provides protocol agnostic DAD state
management that specific protocols that provide DAD can use.

Fixes #4550.

Tests:
  - internal/ip_test.*
  - integration_test.TestDAD
  - arp_test.TestDADARPRequestPacket
  - ipv6.TestCheckDuplicateAddress
PiperOrigin-RevId: 356405593
2021-02-08 19:05:45 -08:00
Ghanan Gowripalan 3853a94f10 Remove linkAddrCache
It was replaced by NUD/neighborCache.

Fixes #4658.

PiperOrigin-RevId: 356085221
2021-02-06 21:37:15 -08:00
Ghanan Gowripalan c5afaf2854 Remove (*stack.Stack).FindNetworkEndpoint
The network endpoints only look for other network endpoints of the
same kind. Since the network protocols keeps track of all endpoints,
go through the protocol to find an endpoint with an address instead
of the stack.

PiperOrigin-RevId: 356051498
2021-02-06 13:25:28 -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 c19e049f2c Check local address directly through NIC
Network endpoints that wish to check addresses on another NIC-local
network endpoint may now do so through the NetworkInterface.

This fixes a lock ordering issue between NIC removal and link
resolution. Before this change:

  NIC Removal takes the stack lock, neighbor cache lock then neighbor
  entries' locks.

  When performing IPv4 link resolution, we take the entry lock then ARP
  would try check IPv4 local addresses through the stack which tries to
  obtain the stack's lock.

Now that ARP can check IPv4 addreses through the NIC, we avoid the lock
ordering issue, while also removing the need for stack to lookup the
NIC.

PiperOrigin-RevId: 356034245
2021-02-06 09:09:19 -08:00
Ghanan Gowripalan 24416032ab Refactor locally delivered packets
Make it clear that failing to parse a looped back is not a packet
sending error but a malformed received packet error.

FindNetworkEndpoint returns nil when no network endpoint is found
instead of an error.

PiperOrigin-RevId: 355954946
2021-02-05 16:47:11 -08:00
Bhasker Hariharan 8c7c5abafb Add support for rate limiting out of window ACKs.
Netstack today will send dupACK's with no rate limit for incoming out of
window segments. This can result in ACK loops for example if a TCP socket
connects to itself (actually permitted by TCP). Where the ACK sent in
response to packets being out of order itself gets considered as an out
of window segment resulting in another ACK being generated.

PiperOrigin-RevId: 355206877
2021-02-02 11:05:28 -08:00
Ghanan Gowripalan d930def27a Default to NUD/neighborCache instead of linkAddrCache
This change flips gvisor to use Neighbor unreachability detection by
default to populate the neighbor table as defined by RFC 4861 section 7.
Although RFC 4861 is targeted at IPv6, the same algorithm is used for
link resolution on IPv4 networks using ARP.

Integrators may still use the legacy link address cache by setting
stack.Options.UseLinkAddrCache to true; stack.Options.UseNeighborCache
is now unused and will be removed.

A later change will remove linkAddrCache and associated code.

Updates #4658.

PiperOrigin-RevId: 354850531
2021-01-31 18:48:26 -08:00
Ghanan Gowripalan 4ee8cf8734 Use different neighbor tables per network endpoint
This stores each protocol's neighbor state separately.

This change also removes the need for each neighbor entry to keep
track of their own link address resolver now that all the entries
in a cache will use the same resolver.

PiperOrigin-RevId: 354818155
2021-01-31 11:33:46 -08:00
Ghanan Gowripalan daeb06d2cb Hide neighbor table kind from NetworkEndpoint
The network endpoint should not need to have logic to handle different
kinds of neighbor tables. Network endpoints can let the NIC know about
differnt neighbor discovery messages and let the NIC decide which table
to update.

This allows us to remove the LinkAddressCache interface.

PiperOrigin-RevId: 354812584
2021-01-31 10:03:46 -08:00
Tamir Duberstein 8dda226542 Extract route table from Stack lock
PiperOrigin-RevId: 354746864
2021-01-30 17:53:41 -08:00
Ghanan Gowripalan 2d90bc5480 Implement LinkAddressResolver on NetworkEndpoints
This removes the need to provide the link address request with the NIC
the request is being performed on since the NetworkEndpoints already
have a reference to the NIC.

PiperOrigin-RevId: 354721940
2021-01-30 11:37:29 -08:00
Nayana Bidari ff4fc42784 RACK: Update reorder window.
After receiving an ACK(cumulative or selective), RACK will update the reorder
window which is used as a settling time before marking the packet as lost.
This change will add an init function to initialize the variables in RACK and
also store the reference to sender in rackControl.
The reorder window is calculated as per rfc:
https://tools.ietf.org/html/draft-ietf-tcpm-rack-08#section-7.2 Step 4.

PiperOrigin-RevId: 354453528
2021-01-28 20:08:23 -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 9ba24d449f Drop nicID from transport endpoint reg/cleanup fns
...as it is unused.

PiperOrigin-RevId: 353896981
2021-01-26 10:35:14 -08:00
Nayana Bidari daf0d3f6ca Move SO_SNDBUF to socketops.
This CL moves {S,G}etsockopt of SO_SNDBUF from all endpoints to socketops. For
unix sockets, we do not support setting of this option.

PiperOrigin-RevId: 353871484
2021-01-26 08:25:34 -08:00
Arthur Sfez 18ebec0ec9 Refactor GetMainNICAddress
It previously returned an error but it could only be UnknownNICID. It now
returns a boolean to indicate whether the nic exists or not.

PiperOrigin-RevId: 353337489
2021-01-22 16:12:12 -08:00
Ghanan Gowripalan e0f4e46e34 Resolve static link addresses in GetLinkAddress
If a network address has a static mapping to a link address, calculate
it in GetLinkAddress.

Test: stack_test.TestStaticGetLinkAddress
PiperOrigin-RevId: 353179616
2021-01-21 23:26:40 -08:00
Ghanan Gowripalan 9f46328e11 Only use callback for GetLinkAddress
GetLinkAddress's callback will be called immediately with a
stack.LinkResolutionResult which will hold the link address
so no need to also return the link address from the function.

Fixes #5151.

PiperOrigin-RevId: 353157857
2021-01-21 19:55:37 -08:00
Ghanan Gowripalan 7ff5ceaeae Do not have a stack-wide linkAddressCache
Link addresses are cached on a per NIC basis so instead of having a
single cache that includes the NIC ID for neighbor entry lookups,
use a single cache per NIC.

PiperOrigin-RevId: 352684111
2021-01-19 16:56:49 -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 f5736fa2bf Do not use a stack-wide queue of pending packets
Packets may be pending on link resolution to complete before being sent.
Link resolution is performed for neighbors which are unique to a NIC so
hold link resolution related state under the NIC, not the stack.

Note, this change may result in more queued packets but that is okay as
RFC 4861 section 7.2.2 recommends that the stack maintain a queue of
packets for each neighbor that is waiting for link resolution to
complete, not a fixed limit per stack.

PiperOrigin-RevId: 352322155
2021-01-17 18:14:28 -08:00
Ghanan Gowripalan cd75bb163f Resolve known link address on route creation
If a Route is being created through a link that requires link address
resolution and a remote address that has a known mapping to a link
address, populate the link address when the route is created.

This removes the need for neighbor/link address caches to perform this
check.

Fixes #5149

PiperOrigin-RevId: 352122401
2021-01-15 18:49:22 -08:00
Ghanan Gowripalan 2814a032be Support GetLinkAddress with neighborCache
Test: integration_test.TestGetLinkAddress
PiperOrigin-RevId: 352119404
2021-01-15 18:15:26 -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
Nayana Bidari 0c92b3782a Add support to count the number of packets SACKed.
sacked_out is required in RACK to check the number of duplicate
acknowledgements during updating the reorder window. If there is no reordering
and the value for sacked_out is greater than the classic threshold value 3,
then reorder window is set to zero.
It is calculated by counting the number of segments sacked in the ACK and is
reduced when a cumulative ACK is received which covers the SACK blocks. This
value is set to zero when the connection enters recovery.

PiperOrigin-RevId: 347872246
2020-12-16 12:19:21 -08:00
Ghanan Gowripalan 2485a4e2cb Make stack.Route safe to access concurrently
Multiple goroutines may use the same stack.Route concurrently so
the stack.Route should make sure that any functions called on it
are thread-safe.

Fixes #4073

PiperOrigin-RevId: 344320491
2020-11-25 14:52:59 -08:00
Ryan Heacock fbc4a8dbd1 Perform IGMPv2 when joining IPv4 multicast groups
Added headers, stats, checksum parsing capabilities from RFC 2236 describing
IGMPv2.

IGMPv2 state machine is implemented for each condition, sending and receiving
IGMP Membership Reports and Leave Group messages with backwards compatibility
with IGMPv1 routers.

Test:
* Implemented igmp header parser and checksum calculator in header/igmp_test.go
* ipv4/igmp_test.go tests incoming and outgoing IGMP messages and pathways.
* Added unit test coverage for IGMPv2 RFC behavior + IGMPv1 backwards
   compatibility in ipv4/igmp_test.go.

Fixes #4682

PiperOrigin-RevId: 343408809
2020-11-19 18:15:25 -08:00
Fabricio Voznika 209a95a35a Propagate IP address prefix from host to netstack
Closes #4022

PiperOrigin-RevId: 343378647
2020-11-19 15:11:17 -08:00
Ghanan Gowripalan 60b97bfda6 Fix loopback subnet routing error
Packets should be properly routed when sending packets to addresses
in the loopback subnet which are not explicitly assigned to the loopback
interface.

Tests:
- integration_test.TestLoopbackAcceptAllInSubnetUDP
- integration_test.TestLoopbackAcceptAllInSubnetTCP
PiperOrigin-RevId: 343135643
2020-11-18 12:45:57 -08:00
Bruno Dal Bo 9d148627f8 Introduce stack.WritePacketToRemote, remove LinkEndpoint.WriteRawPacket
Redefine stack.WritePacket into stack.WritePacketToRemote which lets the NIC
decide whether to append link headers.

PiperOrigin-RevId: 343071742
2020-11-18 07:05:59 -08:00
Nayana Bidari 839dd97008 RACK: Detect DSACK
Detect if the ACK is a duplicate and update in RACK.

PiperOrigin-RevId: 342332569
2020-11-13 13:59:43 -08:00
Ghanan Gowripalan 1a972411b3 Move packet handling to NetworkEndpoint
The NIC should not hold network-layer state or logic - network packet
handling/forwarding should be performed at the network layer instead
of the NIC.

Fixes #4688

PiperOrigin-RevId: 342166985
2020-11-12 17:33:21 -08:00
Andrei Vagin 2fcca60a7b net: connect to the ipv4 localhost returns ENETUNREACH if the address isn't set
cl/340002915 modified the code to return EADDRNOTAVAIL if connect
is called for a localhost address which isn't set.

But actually, Linux returns EADDRNOTAVAIL for ipv6 addresses and ENETUNREACH
for ipv4 addresses.

Updates #4735

PiperOrigin-RevId: 341479129
2020-11-09 13:57:51 -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
Andrei Vagin df88f223bb net/tcpip: connect to unset loopback address has to return EADDRNOTAVAIL
In the docker container, the ipv6 loopback address is not set,
and connect("::1") has to return ENEADDRNOTAVAIL in this case.

Without this fix, it returns EHOSTUNREACH.

PiperOrigin-RevId: 340002915
2020-10-31 01:19:40 -07:00
Kevin Krakauer 02fe467b47 Keep magic constants out of netstack
PiperOrigin-RevId: 339721152
2020-10-29 12:22:21 -07:00
Ian Lewis 59e2c9f16a Add basic address deletion to netlink
Updates #3921

PiperOrigin-RevId: 339195417
2020-10-27 00:18:10 -07:00
Ghanan Gowripalan c1a6ba06ab Pass NetworkInterface to LinkAddressRequest
Previously a link endpoint was passed to
stack.LinkAddressResolver.LinkAddressRequest. With this change,
implementations that want a route for the link address request may
find one through the stack. Other implementations that want to send
a packet without a route may continue to do so using the network
interface directly.

Test: - arp_test.TestLinkAddressRequest
      - ipv6.TestLinkAddressRequest
PiperOrigin-RevId: 338577474
2020-10-22 17:02:29 -07: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
Ghanan Gowripalan 91e2d15a62 Remove AssignableAddressEndpoint.NetworkEndpoint
We can get the network endpoint directly from the NIC.

This is a preparatory CL for when a Route needs to hold a dedicated NIC
as its output interface. This is because when forwarding is enabled,
packets may be sent from a NIC different from the NIC a route's local
address is associated with.

PiperOrigin-RevId: 335484500
2020-10-05 13:18:57 -07:00
Ghanan Gowripalan 5075d0342f Trim Network/Transport Endpoint/Protocol
* Remove Capabilities and NICID methods from NetworkEndpoint.

* Remove linkEP and stack parameters from NetworkProtocol.NewEndpoint.
The LinkEndpoint can be fetched from the NetworkInterface. The stack
is passed to the NetworkProtocol when it is created so the
NetworkEndpoint can get it from its protocol.

* Remove stack parameter from TransportProtocol.NewEndpoint.
Like the NetworkProtocol/Endpoint, the stack is passed to the
TransportProtocol when it is created.

PiperOrigin-RevId: 334332721
2020-09-29 02:05:50 -07:00
Ghanan Gowripalan 48915bdedb Move IP state from NIC to NetworkEndpoint/Protocol
* Add network address to network endpoints.
Hold network-specific state in the NetworkEndpoint instead of the stack.
This results in the stack no longer needing to "know" about the network
endpoints and special case certain work for various endpoints
(e.g. IPv6 DAD).

* Provide NetworkEndpoints with an NetworkInterface interface.
Instead of just passing the NIC ID of a NIC, pass an interface so the
network endpoint may query other information about the NIC such as
whether or not it is a loopback device.

* Move NDP code and state to the IPv6 package.
NDP is IPv6 specific so there is no need for it to live in the stack.

* Control forwarding through NetworkProtocols instead of Stack
Forwarding should be controlled on a per-network protocol basis so
forwarding configurations are now controlled through network protocols.

* Remove stack.referencedNetworkEndpoint.
Now that addresses are exposed via AddressEndpoint and only one
NetworkEndpoint is created per interface, there is no need for a
referenced NetworkEndpoint.

* Assume network teardown methods are infallible.

Fixes #3871, #3916

PiperOrigin-RevId: 334319433
2020-09-29 00:20:41 -07:00