Age | Commit message (Collapse) | Author |
|
...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
|
|
It was replaced by NUD/neighborCache.
Fixes #4658.
PiperOrigin-RevId: 356085221
|
|
After IPTables checks a batch of packets, we can write packets that are
not dropped or locally destined as a batch instead of individually.
This previously caused a bug since WritePacket* functions expect to take
ownership of passed PacketBuffer{List}. WritePackets assumed the list of
PacketBuffers will not be invalidated when calling WritePacket for each
PacketBuffer in the list, but this is not true. WritePacket may add the
passed PacketBuffer into a different list which would modify the
PacketBuffer in such a way that it no longer points to the next
PacketBuffer to write.
Example: Given a PB list of
PB_a -> PB_b -> PB_c
WritePackets may be iterating over the list and calling WritePacket for
each PB. When WritePacket takes PB_a, it may add it to a new list which
would update pointers such that PB_a no longer points to PB_b.
Test: integration_test.TestIPTableWritePackets
PiperOrigin-RevId: 355969560
|
|
...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
|
|
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
|
|
This makes it possible to add data to types that implement tcpip.Error.
ErrBadLinkEndpoint is removed as it is unused.
PiperOrigin-RevId: 354437314
|
|
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
|
|
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
|
|
Fixes #1509.
PiperOrigin-RevId: 353295589
|
|
We have support for the output interface name, but not for the input
interface name.
This change adds the support for the input interface name, and adds the
test cases for it.
Fixes #5300
PiperOrigin-RevId: 353179389
|
|
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
|
|
Test: integration_test.TestWritePacketsLinkResolution
Fixes #4458.
PiperOrigin-RevId: 353108826
|
|
Test: integration_test.TestGetLinkAddress
PiperOrigin-RevId: 352119404
|
|
The same intent can be specified via the io.Writer.
PiperOrigin-RevId: 352098747
|
|
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
|
|
These are primarily simplification and lint mistakes. However, minor
fixes are also included and tests added where appropriate.
PiperOrigin-RevId: 351425971
|
|
Read now takes a destination io.Writer, count, options. Keeping the method name
Read, in contrast to the Write method.
This enables:
* direct transfer of views under VV
* zero copy
It also eliminates the need for sentry to keep a slice of view because
userspace had requested a read that is smaller than the view returned, removing
the complexity there.
Read/Peek/ReadPacket are now consolidated together and some duplicate code is
removed.
PiperOrigin-RevId: 350636322
|
|
Ethernet frames are usually filtered at the hardware-level so there is
no need to filter the frames in software.
For test purposes, a new link endpoint was introduced to filter frames
based on their destination.
PiperOrigin-RevId: 350422941
|
|
IPv4 was always supported but UDP never supported joining/leaving IPv6
multicast groups via socket options.
Add: IPPROTO_IPV6, IPV6_JOIN_GROUP/IPV6_ADD_MEMBERSHIP
Remove: IPPROTO_IPV6, IPV6_LEAVE_GROUP/IPV6_DROP_MEMBERSHIP
Test: integration_test.TestUDPAddRemoveMembershipSocketOption
PiperOrigin-RevId: 350396072
|
|
Adds IPv6 extension header serializer and Hop by Hop options serializer.
Add RouterAlert option serializer and use it in MLD.
Fixed #4996
Startblock:
has LGTM from marinaciocea
and then
add reviewer ghanan
PiperOrigin-RevId: 347174537
|
|
PiperOrigin-RevId: 344009602
|
|
This changes also introduces:
- `SocketOptionsHandler` interface which can be implemented by endpoints to
handle endpoint specific behavior on SetSockOpt. This is analogous to what
Linux does.
- `DefaultSocketOptionsHandler` which is a default implementation of the above.
This is embedded in all endpoints so that we don't have to uselessly
implement empty functions. Endpoints with specific behavior can override the
embedded method by manually defining its own implementation.
PiperOrigin-RevId: 343158301
|
|
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
|
|
- 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
|
|
Store all the socket level options in a struct and call {Get/Set}SockOpt on
this struct. This will avoid implementing socket level options on all
endpoints. This CL contains implementing one socket level option for tcp and
udp endpoints.
PiperOrigin-RevId: 342203981
|
|
Most packets don't have options but they are an integral part of the
standard. Teaching the ipv4 code how to handle them will simplify future
testing and use. Because Options are so rare it is worth making sure
that the extra work is kept out of the fast path as much as possible.
Prior to this change, all usages of the IHL field of the IPv4Fields/Encode
system set it to the same constant value except in a couple of tests
for bad values. From this change IHL will not be a constant as it will
depend on the size of any Options. Since ipv4.Encode() now handles the
options it becomes a possible source of errors to let the callers set
this value, so remove it entirely and calculate the value from the size
of the Options if present (or not) therefore guaranteeing a correct value.
Fixes #4709
RELNOTES: n/a
PiperOrigin-RevId: 341864765
|
|
* 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
|
|
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
|
|
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
|
|
PiperOrigin-RevId: 336339194
|
|
PiperOrigin-RevId: 336304024
|
|
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
|
|
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
|
|
Linux doesn't generate a link-local address for the loopback interface.
Test: integration_test.TestInitialLoopbackAddresses
PiperOrigin-RevId: 334453182
|
|
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
|
|
The lifetime of addreses in a loopback interface's associated subnets
should be bound to their respective permanent addresses.
This change also fixes a race when the stack attempts to get an IPv4
rereferencedNetworkEndpoint for an address in an associated subnet on
a loopback interface. Before this change, the stack would only check
if an IPv4 address is contained in an associated subnet while holding
a read lock but wouldn't do this same check after releasing the read
lock for a write lock to create a temporary address. This may cause
the stack to bind the lifetime of the address to a new (temporary)
endpoint instead of the associated subnet's permanent address.
Test: integration_test.TestLoopbackSubnetLifetimeBoundToAddr
PiperOrigin-RevId: 332094719
|
|
When a broadcast packet is received by the stack, the packet should be
delivered to each endpoint that may be interested in the packet. This
includes all any address and specified broadcast address listeners.
Test: integration_test.TestReuseAddrAndBroadcast
PiperOrigin-RevId: 332060652
|
|
An earlier change considered the loopback bound to all addresses in an
assigned subnet. This should have only be done for IPv4 to maintain
compatability with Linux:
```
$ ip addr show dev lo
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group ...
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
$ ping 2001:db8::1
PING 2001:db8::1(2001:db8::1) 56 data bytes
^C
--- 2001:db8::1 ping statistics ---
4 packets transmitted, 0 received, 100% packet loss, time 3062ms
$ ping 2001:db8::2
PING 2001:db8::2(2001:db8::2) 56 data bytes
^C
--- 2001:db8::2 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2030ms
$ sudo ip addr add 2001:db8::1/64 dev lo
$ ping 2001:db8::1
PING 2001:db8::1(2001:db8::1) 56 data bytes
64 bytes from 2001:db8::1: icmp_seq=1 ttl=64 time=0.055 ms
64 bytes from 2001:db8::1: icmp_seq=2 ttl=64 time=0.074 ms
64 bytes from 2001:db8::1: icmp_seq=3 ttl=64 time=0.073 ms
64 bytes from 2001:db8::1: icmp_seq=4 ttl=64 time=0.071 ms
^C
--- 2001:db8::1 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3075ms
rtt min/avg/max/mdev = 0.055/0.068/0.074/0.007 ms
$ ping 2001:db8::2
PING 2001:db8::2(2001:db8::2) 56 data bytes
From 2001:db8::1 icmp_seq=1 Destination unreachable: No route
From 2001:db8::1 icmp_seq=2 Destination unreachable: No route
From 2001:db8::1 icmp_seq=3 Destination unreachable: No route
From 2001:db8::1 icmp_seq=4 Destination unreachable: No route
^C
--- 2001:db8::2 ping statistics ---
4 packets transmitted, 0 received, +4 errors, 100% packet loss, time 3070ms
```
Test: integration_test.TestLoopbackAcceptAllInSubnet
PiperOrigin-RevId: 329011566
|
|
When a loopback interface is configurd with an address and associated
subnet, the loopback should treat all addresses in that subnet as an
address it owns.
This is mimicking linux behaviour as seen below:
```
$ ip addr show dev lo
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group ...
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
$ ping 192.0.2.1
PING 192.0.2.1 (192.0.2.1) 56(84) bytes of data.
^C
--- 192.0.2.1 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1018ms
$ ping 192.0.2.2
PING 192.0.2.2 (192.0.2.2) 56(84) bytes of data.
^C
--- 192.0.2.2 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2039ms
$ sudo ip addr add 192.0.2.1/24 dev lo
$ ip addr show dev lo
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group ...
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet 192.0.2.1/24 scope global lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
$ ping 192.0.2.1
PING 192.0.2.1 (192.0.2.1) 56(84) bytes of data.
64 bytes from 192.0.2.1: icmp_seq=1 ttl=64 time=0.131 ms
64 bytes from 192.0.2.1: icmp_seq=2 ttl=64 time=0.046 ms
64 bytes from 192.0.2.1: icmp_seq=3 ttl=64 time=0.048 ms
^C
--- 192.0.2.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2042ms
rtt min/avg/max/mdev = 0.046/0.075/0.131/0.039 ms
$ ping 192.0.2.2
PING 192.0.2.2 (192.0.2.2) 56(84) bytes of data.
64 bytes from 192.0.2.2: icmp_seq=1 ttl=64 time=0.131 ms
64 bytes from 192.0.2.2: icmp_seq=2 ttl=64 time=0.069 ms
64 bytes from 192.0.2.2: icmp_seq=3 ttl=64 time=0.049 ms
64 bytes from 192.0.2.2: icmp_seq=4 ttl=64 time=0.035 ms
^C
--- 192.0.2.2 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3049ms
rtt min/avg/max/mdev = 0.035/0.071/0.131/0.036 ms
```
Test: integration_test.TestLoopbackAcceptAllInSubnet
PiperOrigin-RevId: 328188546
|
|
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
|
|
Packets MUST NOT use a non-unicast source address for ICMP
Echo Replies.
Test: integration_test.TestPingMulticastBroadcast
PiperOrigin-RevId: 325634380
|
|
Test:
- stack_test.TestJoinLeaveMulticastOnNICEnableDisable
- integration_test.TestIncomingMulticastAndBroadcast
PiperOrigin-RevId: 325185259
|
|
Test: integration_test.TestIncomingSubnetBroadcast
PiperOrigin-RevId: 325135617
|