Commit Graph

186 Commits

Author SHA1 Message Date
Julian Elischer 4d27f33b09 Make IPv4 check the IP header checksum
The IPv4 header checksum has not been checked, at least in recent times,
so add code to do so. Fix all the tests that fail because they never
needed to set the checksum.

Fixes #4484

PiperOrigin-RevId: 337556243
2020-10-16 12:31:05 -07:00
Arthur Sfez edc1068244 Enable IPv4 fragmentation for every code path.
Currently, fragmentation can only occur during WritePacket(). This enables
it for WritePackets() and WriteIncludedHeaderPacket() as well.

IPv4 unit tests were refactored to be consistent with the IPv6 unit tests.

This removes the extraHeaderReserveLength field and the related
"prependable bytes" unit tests (for both IPv4 and IPv6) because it was only
testing a panic condition when the value was too low.

Fixes #3796

PiperOrigin-RevId: 337550061
2020-10-16 11:57:27 -07:00
Ghanan Gowripalan fbfcf8144c Enable IPv6 WriteHeaderIncludedPacket
Allow writing an IPv6 packet where the IPv6 header is a provided by
the user.

* Introduce an error to let callers know a header is malformed.
We previously useed tcpip.ErrInvalidOptionValue but that did not seem
appropriate for generic malformed header errors.

* Populate network header in WriteHeaderIncludedPacket
IPv4's implementation of WriteHeaderIncludedPacket did not previously
populate the packet buffer's network header. This change fixes that.

Fixes #4527

Test: ip_test.TestWriteHeaderIncludedPacket
PiperOrigin-RevId: 337534548
2020-10-16 10:42:34 -07:00
Sam Balana 3269cefd6f Process NAs without target link-layer addresses
RFC 4861 section 4.4 comments the Target link-layer address option is sometimes
optional in a Neighbor Advertisement packet:

  "When responding to a unicast Neighbor Solicitation this option SHOULD be
  included."

Tests:
 pkg/tcpip/stack:stack_test
 - TestEntryStaleToReachableWhenSolicitedConfirmationWithoutAddress
 - TestEntryDelayToReachableWhenSolicitedConfirmationWithoutAddress
 - TestEntryProbeToReachableWhenSolicitedConfirmationWithoutAddress
 pkg/tcpip/network/ipv6:ipv6_test
 - TestCallsToNeighborCache
PiperOrigin-RevId: 337396493
2020-10-15 15:37:01 -07:00
Arthur Sfez 8f70c6ef35 Refactor compareFragments to follow Go style
Test helpers should be used for test setup/teardown, not actual
testing. Use cmp.Diff instead of bytes.Equal to improve readability.

PiperOrigin-RevId: 337323242
2020-10-15 09:29:01 -07:00
Ghanan Gowripalan 6e6a9d3f3d Find route before sending NA response
This change also brings back the stack.Route.ResolveWith method so that
we can immediately resolve a route when sending an NA in response to a
a NS with a source link layer address option.

Test: ipv6_test.TestNeighorSolicitationResponse
PiperOrigin-RevId: 337185461
2020-10-14 15:29:47 -07:00
Sam Balana 51913ba400 Correct NA minimum size
Remove the duplicate NA size variable while I'm here.

See https://tools.ietf.org/html/rfc4861#section-4.4 for the packet format.

PiperOrigin-RevId: 336943206
2020-10-13 13:28:26 -07:00
Tamir Duberstein 7053f17859 Use NDP option serializer instead of handcrafting the NS
Use the correct constant (Solicit, not Advert) while I'm here.

PiperOrigin-RevId: 336924605
2020-10-13 12:00:20 -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 40269d0c24 Send unicast probes when link address is known
When the neighbor table already has link address for a neighbor but is
trying to confirm reachability, it may send unicast probes to the
neighbor.

PiperOrigin-RevId: 336166711
2020-10-08 14:36:14 -07:00
Arthur Sfez 0c3134028d Change IPv6 reassembly timeout to 60s
It was originally set to 30s for IPv6 (same as IPv4) but this is not
what RFC 8200 prescibes. Linux also defaults to 60s [1].

[1] 47ec5303d7/include/net/ipv6.h (L456)

PiperOrigin-RevId: 336034636
2020-10-08 00:56:16 -07:00
Peter Johnston 95cac27d0d Discard invalid Neighbor Solicitations
...per RFC 4861 s7.1.1.

PiperOrigin-RevId: 335742851
2020-10-06 16:17:24 -07:00
Arthur Sfez 99bf022c2a Add support for IPv6 fragmentation
Most of the IPv4 fragmentation code was moved in the fragmentation
package and it is reused by IPv6 fragmentation.

Test:
  - pkg/tcpip/network/ipv4:ipv4_test
  - pkg/tcpip/network/ipv6:ipv6_test
  - pkg/tcpip/network/fragmentation:fragmentation_test

Fixes #4389

PiperOrigin-RevId: 335714280
2020-10-06 14:03:39 -07:00
Julian Elischer 798cc6b04d Fix IPv4 ICMP echo handler to copy options
The IPv4 RFCs are specific (though obtuse) that an echo response
packet needs to contain all the options from the echo request,
much as if it been routed back to the sender, though apparently
with a new TTL. They suggest copying the incoming packet header
to achieve this so that is what this patch does.

PiperOrigin-RevId: 335559176
2020-10-05 20:43:55 -07:00
Arthur Sfez 7f9e13053e Count IP OutgoingPacketErrors in the NetworkEndpoint methods
Before this change, OutgoingPacketErrors was incremented in the
stack.Route methods. This was going to be a problem once
IPv4/IPv6 WritePackets support fragmentation because Route.WritePackets
might now know how many packets are left after an error occurs.

Test:
  - pkg/tcpip/network/ipv4:ipv4_test
  - pkg/tcpip/network/ipv6:ipv6_test
PiperOrigin-RevId: 334687983
2020-09-30 15:09:38 -07:00
Julian Elischer 694d6ae32f Use the ICMP error response facility
Add code in IPv6 to send ICMP packets while processing extension headers.

Add some accounting in processing IPV6 Extension headers which
allows us to report meaningful information back in ICMP parameter
problem packets.

IPv4 also needs to send a message when an unsupported protocol
is requested.

Add some tests to generate both ipv4 and ipv6 packets with
various errors and check the responses.

Add some new checkers and cleanup some inconsistencies in
the messages in that file.

Add new error types for the ICMPv4/6 generators.

Fix a bug in the ICMPv4 generator that stopped it from generating
"Unknown protocol" messages.

Updates #2211

PiperOrigin-RevId: 334661716
2020-09-30 13:05:14 -07:00
Ghanan Gowripalan e5ece9aea7 Return permanent addresses when NIC is down
Test: stack_test.TestGetMainNICAddressWhenNICDisabled
PiperOrigin-RevId: 334513286
2020-09-29 19:46:50 -07:00
Ghanan Gowripalan 6ae83404af Don't allow broadcast/multicast source address
As per relevant IP RFCS (see code comments), broadcast (for IPv4) and
multicast addresses are not allowed. Currently checks for these are
done at the transport layer, but since it is explicitly forbidden at
the IP layers, check for them there.

This change also removes the UDP.InvalidSourceAddress stat since there
is no longer a need for it.

Test: ip_test.TestSourceAddressValidation
PiperOrigin-RevId: 334490971
2020-09-29 16:54:23 -07:00
Kevin Krakauer 7fbb45e8ed iptables: refactor to make targets extendable
Like matchers, targets should use a module-like register/lookup system. This
replaces the brittle switch statements we had before.

The only behavior change is supporing IPT_GET_REVISION_TARGET. This makes it
much easier to add IPv6 redirect in the next change.

Updates #3549.

PiperOrigin-RevId: 334469418
2020-09-29 15:02:25 -07:00
Ghanan Gowripalan 1d88bce55e Don't generate link-local IPv6 for loopback
Linux doesn't generate a link-local address for the loopback interface.

Test: integration_test.TestInitialLoopbackAddresses
PiperOrigin-RevId: 334453182
2020-09-29 13:45:36 -07:00
Toshi Kikuchi f15182243e Discard IP fragments as soon as it expires
Currently expired IP fragments are discarded only if another fragment for the
same IP datagram is received after timeout or the total size of the fragment
queue exceeded a predefined value.

Test: fragmentation.TestReassemblingTimeout

Fixes #3960

PiperOrigin-RevId: 334423710
2020-09-29 11:29:50 -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
Ghanan Gowripalan a5acc0616c Support creating protocol instances with Stack ref
Network or transport protocols may want to reach the stack. Support this
by letting the stack create the protocol instances so it can pass a
reference to itself at protocol creation time.

Note, protocols do not yet use the stack in this CL but later CLs will
make use of the stack from protocols.

PiperOrigin-RevId: 334260210
2020-09-28 16:24:04 -07:00
Ghanan Gowripalan a376a0baf3 Remove generic ICMP errors
Generic ICMP errors were required because the transport dispatcher was
given the responsibility of sending ICMP errors in response to transport
packet delivery failures. Instead, the transport dispatcher should let
network layer know it failed to deliver a packet (and why) and let the
network layer make the decision as to what error to send (if any).

Fixes #4068

PiperOrigin-RevId: 333962333
2020-09-26 19:24:41 -07:00
Julian Elischer 99decaadd6 Extract ICMP error sender from UDP
Store transport protocol number on packet buffers for use in ICMP error
generation.

Updates #2211.

PiperOrigin-RevId: 333252762
2020-09-23 02:28:43 -07:00
Arthur Sfez cf3cef1171 Refactor testutil.TestEndpoint and use it instead of limitedEP
The new testutil.MockLinkEndpoint implementation is not composed by
channel.Channel anymore because none of its features were used.

PiperOrigin-RevId: 333167753
2020-09-22 15:06:16 -07:00
gVisor bot ca30874720 Merge pull request #3651 from ianlewis:ip-forwarding
PiperOrigin-RevId: 332760843
2020-09-20 18:17:20 -07:00
Kevin Krakauer bd69afdcd1 Count packets dropped by iptables in IPStats
PiperOrigin-RevId: 332486383
2020-09-18 11:13:19 -07:00
Ghanan Gowripalan 360006d894 Use common parsing utilities when sniffing
Extract parsing utilities so they can be used by the sniffer.

Fixes #3930

PiperOrigin-RevId: 332401880
2020-09-18 00:48:09 -07:00
Kevin Krakauer 2fbd31e726 Test IPv4 WritePackets stats
IPv6 tests will be added in another CL along with ip6tables.

PiperOrigin-RevId: 332389102
2020-09-17 22:50:53 -07:00
Kevin Krakauer 0b8d306e64 ip6tables: filter table support
`ip6tables -t filter` is now usable. NAT support will come in a future CL.

#3549

PiperOrigin-RevId: 332381801
2020-09-17 21:54:48 -07:00
Arthur Sfez 72a30b1148 Move reusable IPv4 test code into a testutil module and refactor it
The refactor aims to simplify the package, by replacing the Go channel with a
PacketBuffer slice.

This code will be reused by tests for IPv6 fragmentation.

PiperOrigin-RevId: 331860411
2020-09-15 14:49:29 -07:00
Toshi Kikuchi b6ca96b9b9 Cap reassembled IPv6 packets at 65535 octets
IPv4 can accept 65536-octet reassembled packets.

Test:
- ipv4_test.TestInvalidFragments
- ipv4_test.TestReceiveFragments
- ipv6.TestInvalidIPv6Fragments
- ipv6.TestReceiveIPv6Fragments

Fixes #3770

PiperOrigin-RevId: 331382977
2020-09-12 23:21:27 -07:00
Ghanan Gowripalan bdd5996a73 Improve type safety for network protocol options
The existing implementation for NetworkProtocol.{Set}Option take
arguments of an empty interface type which all types (implicitly)
implement; any type may be passed to the functions.

This change introduces marker interfaces for network protocol options
that may be set or queried which network protocol option types implement
to ensure that invalid types are caught at compile time. Different
interfaces are used to allow the compiler to enforce read-only or
set-only socket options.

PiperOrigin-RevId: 328980359
2020-08-28 11:50:17 -07:00
Sam Balana a174aa7597 Add option to replace linkAddrCache with neighborCache
This change adds an option to replace the current implementation of ARP through
linkAddrCache, with an implementation of NUD through neighborCache. Switching
to using NUD for both ARP and NDP is beneficial for the reasons described by
RFC 4861 Section 3.1:

  "[Using NUD] significantly improves the robustness of packet delivery in the
  presence of failing routers, partially failing or partitioned links, or nodes
  that change their link-layer addresses. For instance, mobile nodes can move
  off-link without losing any connectivity due to stale ARP caches."

  "Unlike ARP, Neighbor Unreachability Detection detects half-link failures and
  avoids sending traffic to neighbors with which two-way connectivity is
  absent."

Along with these changes exposes the API for querying and operating the
neighbor cache. Operations include:
  - Create a static entry
  - List all entries
  - Delete all entries
  - Remove an entry by address

This also exposes the API to change the NUD protocol constants on a per-NIC
basis to allow Neighbor Discovery to operate over links with widely varying
performance characteristics. See [RFC 4861 Section 10][1] for the list of
constants.

Finally, an API for subscribing to NUD state changes is exposed through
NUDDispatcher. See [RFC 4861 Appendix C][3] for the list of edges.

Tests:
 pkg/tcpip/network/arp:arp_test
 + TestDirectRequest

 pkg/tcpip/network/ipv6:ipv6_test
 + TestLinkResolution
 + TestNDPValidation
 + TestNeighorAdvertisementWithTargetLinkLayerOption
 + TestNeighorSolicitationResponse
 + TestNeighorSolicitationWithSourceLinkLayerOption
 + TestRouterAdvertValidation

 pkg/tcpip/stack:stack_test
 + TestCacheWaker
 + TestForwardingWithFakeResolver
 + TestForwardingWithFakeResolverManyPackets
 + TestForwardingWithFakeResolverManyResolutions
 + TestForwardingWithFakeResolverPartialTimeout
 + TestForwardingWithFakeResolverTwoPackets
 + TestIPv6SourceAddressSelectionScopeAndSameAddress

[1]: https://tools.ietf.org/html/rfc4861#section-10
[2]: https://tools.ietf.org/html/rfc4861#appendix-C

Fixes #1889
Fixes #1894
Fixes #1895
Fixes #1947
Fixes #1948
Fixes #1949
Fixes #1950

PiperOrigin-RevId: 328365034
2020-08-25 11:09:33 -07:00
Arthur Sfez 7ca62b9daa Only use the NextHeader value of the first IPv6 fragment extension header.
As per RFC 8200 Section 4.5:
  The Next Header field of the last header of the Per-Fragment
  headers is obtained from the Next Header field of the first
  fragment's Fragment header.

Test:
  - pkg/tcpip/network/ipv6:ipv6_test
  - pkg/tcpip/network/ipv4:ipv4_test
  - pkg/tcpip/network/fragmentation:fragmentation_test

Updates #2197

PiperOrigin-RevId: 327671635
2020-08-20 12:06:45 -07:00
Arthur Sfez 58154194b3 Add a unit test for out of order IP reassembly
PiperOrigin-RevId: 327042869
2020-08-17 10:19:11 -07:00
Ghanan Gowripalan 1736b2208f Use a single NetworkEndpoint per NIC per protocol
The NetworkEndpoint does not need to be created for each address.
Most of the work the NetworkEndpoint does is address agnostic.

PiperOrigin-RevId: 326759605
2020-08-14 17:30:01 -07:00
Julian Elischer 190634e0fc Give the ICMP Code its own type
This is  a preparatory commit for a larger commit working on
ICMP generation in error cases.
This is removal of technical debt and cleanup in the gvisor code
as part of gvisor issue 2211.

Updates #2211.

PiperOrigin-RevId: 326615389
2020-08-14 02:07:36 -07:00
Ting-Yu Wang 47515f4751 Migrate to PacketHeader API for PacketBuffer.
Formerly, when a packet is constructed or parsed, all headers are set by the
client code. This almost always involved prepending to pk.Header buffer or
trimming pk.Data portion. This is known to prone to bugs, due to the complexity
and number of the invariants assumed across netstack to maintain.

In the new PacketHeader API, client will call Push()/Consume() method to
construct/parse an outgoing/incoming packet. All invariants, such as slicing
and trimming, are maintained by the API itself.

NewPacketBuffer() is introduced to create new PacketBuffer. Zero value is no
longer valid.

PacketBuffer now assumes the packet is a concatenation of following portions:
* LinkHeader
* NetworkHeader
* TransportHeader
* Data
Any of them could be empty, or zero-length.

PiperOrigin-RevId: 326507688
2020-08-13 13:08:57 -07:00
Kevin Krakauer 8e31f0dc57 Set the NetworkProtocolNumber of all PacketBuffers.
NetworkEndpoints set the number on outgoing packets in Write() and
NetworkProtocols set them on incoming packets in Parse().

Needed for #3549.

PiperOrigin-RevId: 325938745
2020-08-10 19:34:28 -07:00
Ghanan Gowripalan b404b5c255 Use unicast source for ICMP echo replies
Packets MUST NOT use a non-unicast source address for ICMP
Echo Replies.

Test: integration_test.TestPingMulticastBroadcast
PiperOrigin-RevId: 325634380
2020-08-08 17:45:19 -07:00
Ghanan Gowripalan 00993130e5 Use 1 fragmentation component per IP stack
This will help manage memory consumption by IP reassembly when
receiving IP fragments on multiple network endpoints. Previously,
each endpoint would cap memory consumption at 4MB, but with this
change, each IP stack will cap memory consumption at 4MB.

No behaviour changes.

PiperOrigin-RevId: 324913904
2020-08-04 16:27:00 -07:00
Ghanan Gowripalan ade4ff95fc Support fragments from different sources
Prevent fragments with different source-destination pairs from
conflicting with each other.

Test:
    - ipv6_test.TestReceiveIPv6Fragments
    - ipv4_test.TestReceiveIPv6Fragments
PiperOrigin-RevId: 324283246
2020-07-31 14:19:49 -07:00
Ghanan Gowripalan 9960a816a9 Enforce fragment block size and validate args
Allow configuring fragmentation.Fragmentation with a fragment
block size which will be enforced when processing fragments. Also
validate arguments when processing fragments.

Test:
    - fragmentation.TestErrors
    - ipv6_test.TestReceiveIPv6Fragments
    - ipv4_test.TestReceiveIPv6Fragments
PiperOrigin-RevId: 324081521
2020-07-30 14:25:53 -07:00
Sam Balana 8dbf428a12 Add ability to send unicast ARP requests and Neighbor Solicitations
The previous implementation of LinkAddressRequest only supported sending
broadcast ARP requests and multicast Neighbor Solicitations. The ability to
send these packets as unicast is required for Neighbor Unreachability
Detection.

Tests:
 pkg/tcpip/network/arp:arp_test
 - TestLinkAddressRequest

 pkg/tcpip/network/ipv6:ipv6_test
 - TestLinkAddressRequest

Updates #1889
Updates #1894
Updates #1895
Updates #1947
Updates #1948
Updates #1949
Updates #1950

PiperOrigin-RevId: 323451569
2020-07-27 15:21:17 -07:00
Kevin Krakauer fb8be7e627 make connect(2) fail when dest is unreachable
Previously, ICMP destination unreachable datagrams were ignored by TCP
endpoints. This caused connect to hang when an intermediate router
couldn't find a route to the host.

This manifested as a Kokoro error when Docker IPv6 was enabled. The Ruby
image test would try to install the sinatra gem and hang indefinitely
attempting to use an IPv6 address.

Fixes #3079.
2020-07-22 16:51:42 -07:00