summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/stack/nic.go
AgeCommit message (Collapse)Author
2021-04-21Only carry GSO options in the packet bufferGhanan Gowripalan
With this change, GSO options no longer needs to be passed around as a function argument in the write path. This change is done in preparation for a later change that defers segmentation, and may change GSO options for a packet as it flows down the stack. Updates #170. PiperOrigin-RevId: 369774872
2021-03-16Do not call into Stack from LinkAddressRequestGhanan Gowripalan
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-03Make dedicated methods for data operations in PacketBufferTing-Yu Wang
One of the preparation to decouple underlying buffer implementation. There are still some methods that tie to VectorisedView, and they will be changed gradually in later CLs. This CL also introduce a new ICMPv6ChecksumParams to replace long list of parameters when calling ICMPv6Checksum, aiming to be more descriptive. PiperOrigin-RevId: 360778149
2021-03-02Plumb link address request errors up to requesterTamir Duberstein
Prevent the situation where callers to (*stack).GetLinkAddress provide incorrect arguments and are unable to observe this condition. Updates #5583. PiperOrigin-RevId: 360481557
2021-02-08Support performing DAD for any addressGhanan Gowripalan
...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-06Remove linkAddrCacheGhanan Gowripalan
It was replaced by NUD/neighborCache. Fixes #4658. PiperOrigin-RevId: 356085221
2021-02-06Use embedded mutex pattern in neighbor cache/entryGhanan Gowripalan
Also while I'm here, update neighbor cahce/entry tests to use the stack's RNG instead of creating a neigbor cache/entry specific one. PiperOrigin-RevId: 356040581
2021-02-06Unexpose NICGhanan Gowripalan
The NIC structure is not to be used outside of the stack package directly. PiperOrigin-RevId: 356036737
2021-02-06Check local address directly through NICGhanan Gowripalan
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-05Refactor locally delivered packetsGhanan Gowripalan
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-01Refactor HandleControlPacket/SockErrorGhanan Gowripalan
...to remove the need for the transport layer to deduce the type of error it received. Rename HandleControlPacket to HandleError as HandleControlPacket only handles errors. tcpip.SockError now holds a tcpip.SockErrorCause interface that different errors can implement. PiperOrigin-RevId: 354994306
2021-01-31Use different neighbor tables per network endpointGhanan Gowripalan
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-31Hide neighbor table kind from NetworkEndpointGhanan Gowripalan
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-30Implement LinkAddressResolver on NetworkEndpointsGhanan Gowripalan
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-28Avoid locking when route doesn't require resolutionGhanan Gowripalan
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-28Change tcpip.Error to an interfaceTamir Duberstein
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-27Confirm neighbor reachability with TCP ACKsGhanan Gowripalan
As per RFC 4861 section 7.3.1, A neighbor is considered reachable if the node has recently received a confirmation that packets sent recently to the neighbor were received by its IP layer. Positive confirmation can be gathered in two ways: hints from upper-layer protocols that indicate a connection is making "forward progress", or receipt of a Neighbor Advertisement message that is a response to a Neighbor Solicitation message. This change adds support for TCP to let the IP/link layers know that a neighbor is reachable. Test: integration_test.TestTCPConfirmNeighborReachability PiperOrigin-RevId: 354222833
2021-01-21Only use callback for GetLinkAddressGhanan Gowripalan
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-21Do not cache remote link address in RouteGhanan Gowripalan
...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-21Queue packets in WritePackets when resolving link addressGhanan Gowripalan
Test: integration_test.TestWritePacketsLinkResolution Fixes #4458. PiperOrigin-RevId: 353108826
2021-01-21Populate EgressRoute, GSO, Netproto in NICGhanan Gowripalan
fdbased and qdisc layers expect these fields to already be populated before being reached. PiperOrigin-RevId: 353099492
2021-01-19Do not have a stack-wide linkAddressCacheGhanan Gowripalan
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-17Do not use a stack-wide queue of pending packetsGhanan Gowripalan
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-15Support GetLinkAddress with neighborCacheGhanan Gowripalan
Test: integration_test.TestGetLinkAddress PiperOrigin-RevId: 352119404
2021-01-15Only pass stack.Route's fields to LinkEndpointsGhanan Gowripalan
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-13Clear neighbor table on NIC downGhanan Gowripalan
Note, this includes static entries to match linux's behaviour. ``` $ ip neigh show dev eth0 192.168.42.1 lladdr fc:ec:da:70:6e:f9 STALE $ sudo ip neigh add 192.168.42.172 lladdr 22:33:44:55:66:77 dev eth0 $ ip neigh show dev eth0 192.168.42.1 lladdr fc:ec:da:70:6e:f9 STALE 192.168.42.172 lladdr 22:33:44:55:66:77 PERMANENT $ sudo ifconfig eth0 down $ ip neigh show dev eth0 $ sudo ifconfig eth0 up $ ip neigh show dev eth0 ``` Test: stack_test.TestClearNeighborCacheOnNICDisable PiperOrigin-RevId: 351696306
2020-12-22Invoke address resolution upon subsequent traffic to Failed neighborPeter Johnston
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-15Fix a data race in packetEPsTing-Yu Wang
packetEPs may get into a state that `len < cap`, casuing append() modifying the original slice storage. Reported-by: syzbot+978dd0e9c2600ab7a76b@syzkaller.appspotmail.com PiperOrigin-RevId: 347634351
2020-12-10Use specified source address for IGMP/MLD packetsGhanan Gowripalan
This change also considers interfaces and network endpoints enabled up up to the point all work to disable them are complete. This was needed so that protocols can perform shutdown work while being disabled (e.g. sending a packet which requires the endpoint to be enabled to obtain a source address). Bug #4682, #4861 Fixes #4888 Startblock: has LGTM from peterjohnston and then add reviewer brunodalbo PiperOrigin-RevId: 346869702
2020-12-03Make `stack.Route` thread safePeter Johnston
Currently we rely on the user to take the lock on the endpoint that owns the route, in order to modify it safely. We can instead move `Route.RemoteLinkAddress` under `Route`'s mutex, and allow non-locking and thread-safe access to other fields of `Route`. PiperOrigin-RevId: 345461586
2020-12-01Track join count in multicast group protocol stateGhanan Gowripalan
Before this change, the join count and the state for IGMP/MLD was held across different types which required multiple locks to be held when accessing a multicast group's state. Bug #4682, #4861 Fixes #4916 PiperOrigin-RevId: 345019091
2020-11-25Make stack.Route safe to access concurrentlyGhanan Gowripalan
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-24Track number of packets queued to Failed neighborsSam Balana
Add a NIC-specific neighbor table statistic so we can determine how many packets have been queued to Failed neighbors, indicating an unhealthy local network. This change assists us to debug in-field issues where subsequent traffic to a neighbor fails. Fixes #4819 PiperOrigin-RevId: 344131119
2020-11-16Remove ARP address workaroundGhanan Gowripalan
- Make AddressableEndpoint optional for NetworkEndpoint. Not all NetworkEndpoints need to support addressing (e.g. ARP), so AddressableEndpoint should only be implemented for protocols that support addressing such as IPv4 and IPv6. With this change, tcpip.ErrNotSupported will be returned by the stack when attempting to modify addresses on a network endpoint that does not support addressing. Now that packets are fully handled at the network layer, and (with this change) addresses are optional for network endpoints, we no longer need the workaround for ARP where a fake ARP address was added to each NIC that performs ARP so that packets would be delivered to the ARP layer. PiperOrigin-RevId: 342722547
2020-11-12Move packet handling to NetworkEndpointGhanan Gowripalan
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-05Use stack.Route exclusively for writing packetsGhanan Gowripalan
* 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-10-30Automated rollback of changelist 339750876Dean Deng
PiperOrigin-RevId: 339945377
2020-10-29Automated rollback of changelist 339675182Dean Deng
PiperOrigin-RevId: 339750876
2020-10-29Delay goroutine creation during TCP handshake for accept/connect.Dean Deng
Refactor TCP handshake code so that when connect is initiated, the initial SYN is sent before creating a goroutine to handle the rest of the handshake (which blocks). Similarly, the initial SYN-ACK is sent inline when SYN is received during accept. Some additional cleanup is done as well. Eventually we would like to complete connections in the dispatcher without requiring a wakeup to complete the handshake. This refactor makes that easier. Updates #231 PiperOrigin-RevId: 339675182
2020-10-27Add support for Timestamp and RecordRoute IP optionsJulian Elischer
IPv4 options extend the size of the IP header and have a basic known format. The framework can process that format without needing to know about every possible option. We can add more code to handle additional option types as we need them. Bad options or mangled option entries can result in ICMP Parameter Problem packets. The first types we support are the Timestamp option and the Record Route option, included in this change. The options are processed at several points in the packet flow within the Network stack, with slightly different requirements. The framework includes a mechanism to control this at each point. Support has been added for such points which are only present in upcoming CLs such as during packet forwarding and fragmentation. With this change, 'ping -R' and 'ping -T' work against gVisor and Fuchsia. $ ping -R 192.168.1.2 PING 192.168.1.2 (192.168.1.2) 56(124) bytes of data. 64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=0.990 ms NOP RR: 192.168.1.1 192.168.1.2 192.168.1.1 $ ping -T tsprespec 192.168.1.2 192.168.1.1 192.168.1.2 PING 192.168.1.2 (192.168.1.2) 56(124) bytes of data. 64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=1.20 ms TS: 192.168.1.2 71486821 absolute 192.168.1.1 746 Unit tests included for generic options, Timestamp options and Record Route options. PiperOrigin-RevId: 339379076
2020-10-22Pass NetworkInterface to LinkAddressRequestGhanan Gowripalan
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-16Don't include link header when forwarding packetsGhanan Gowripalan
Before this change, if a link header was included in an incoming packet that is forwarded, the packet that gets sent out will take the original packet and add a link header to it while keeping the old link header. This would make the sent packet look like: OUTGOING LINK HDR | INCOMING LINK HDR | NETWORK HDR | ... Obviously this is incorrect as we should drop the incoming link header and only include the outgoing link header. This change fixes this bug. Test: integration_test.TestForwarding PiperOrigin-RevId: 337571447
2020-10-09Automated rollback of changelist 336304024Ghanan Gowripalan
PiperOrigin-RevId: 336339194
2020-10-09Automated rollback of changelist 336185457Bhasker Hariharan
PiperOrigin-RevId: 336304024
2020-10-08Do not resolve routes immediatelyGhanan Gowripalan
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-05Remove AssignableAddressEndpoint.NetworkEndpointGhanan Gowripalan
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-09-30Use the ICMP error response facilityJulian Elischer
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-29Return permanent addresses when NIC is downGhanan Gowripalan
Test: stack_test.TestGetMainNICAddressWhenNICDisabled PiperOrigin-RevId: 334513286
2020-09-29Trim Network/Transport Endpoint/ProtocolGhanan Gowripalan
* 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-29Move IP state from NIC to NetworkEndpoint/ProtocolGhanan Gowripalan
* 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