Commit Graph

24 Commits

Author SHA1 Message Date
Ghanan Gowripalan 1d97adaa6d Use embedded mutex pattern for stack.NIC
- Wrap NIC's fields that should only be accessed while holding the mutex in
  an anonymous struct with the embedded mutex.
- Make sure NIC's spoofing and promiscuous mode flags are only read while
  holding the NIC's mutex.
- Use the correct endpoint when sending DAD messages.
- Do not hold the NIC's lock when sending DAD messages.

This change does not introduce any behaviour changes.

Tests: Existing tests continue to pass.
PiperOrigin-RevId: 291036251
2020-01-22 14:51:53 -08:00
Tamir Duberstein 23fa847910 Remove addPermanentAddressLocked
It was possible to use this function incorrectly, and its separation
wasn't buying us anything.

PiperOrigin-RevId: 290311100
2020-01-17 11:48:06 -08:00
Ghanan Gowripalan a7a1f00425 Support upgrading expired/removed IPv6 addresses to permanent SLAAC addresses
If a previously added IPv6 address (statically or via SLAAC) was removed, it
would be left in an expired state waiting to be cleaned up if any references to
it were still held. During this time, the same address could be regenerated via
SLAAC, which should be allowed. This change supports this scenario.

When upgrading an endpoint from temporary or permanentExpired to permanent,
respect the new configuration type (static or SLAAC) and deprecated status,
along with the new PrimaryEndpointBehavior (which was already supported).

Test: stack.TestAutoGenAddrAfterRemoval
PiperOrigin-RevId: 289990168
2020-01-15 20:23:06 -08:00
Ghanan Gowripalan 815df2959a Solicit IPv6 routers when a NIC becomes enabled as a host
This change adds support to send NDP Router Solicitation messages when a NIC
becomes enabled as a host, as per RFC 4861 section 6.3.7.

Note, Router Solicitations will only be sent when the stack has forwarding
disabled.

Tests: Unittests to make sure that the initial Router Solicitations are sent
as configured. The tests also validate the sent Router Solicitations' fields.
PiperOrigin-RevId: 289964095
2020-01-15 17:10:48 -08:00
Ghanan Gowripalan 26c5653bb5 Inform NDPDispatcher when Stack learns about available configurations via DHCPv6
Inform the Stack's NDPDispatcher when it receives an NDP Router Advertisement
that updates the available configurations via DHCPv6. The Stack makes sure that
its NDPDispatcher isn't informed unless the avaiable configurations via DHCPv6
for a NIC is updated.

Tests: Test that a Stack's NDPDispatcher is informed when it receives an NDP
Router Advertisement that informs it of new configurations available via DHCPv6.
PiperOrigin-RevId: 289001283
2020-01-09 16:56:28 -08:00
Ghanan Gowripalan d057871f41 CancellableTimer to encapsulate the work of safely stopping timers
Add a new CancellableTimer type to encapsulate the work of safely stopping
timers when it fires at the same time some "related work" is being handled. The
term "related work" is some work that needs to be done while having obtained
some common lock (L).

Example: Say we have an invalidation timer that may be extended or cancelled by
some event. Creating a normal timer and simply cancelling may not be sufficient
as the timer may have already fired when the event handler attemps to cancel it.
Even if the timer and event handler obtains L before doing work, once the event
handler releases L, the timer will eventually obtain L and do some unwanted
work.

To prevent the timer from doing unwanted work, it checks if it should early
return instead of doing the normal work after obtaining L. When stopping the
timer callers must have L locked so the timer can be safely informed that it
should early return.

Test: Tests that CancellableTimer fires and resets properly. Test to make sure
the timer fn is not called after being stopped within the lock L.
PiperOrigin-RevId: 288806984
2020-01-08 17:50:54 -08:00
Ghanan Gowripalan 4e19d165cc Support deprecating SLAAC addresses after the preferred lifetime
Support deprecating network endpoints on a NIC. If an endpoint is deprecated, it
should not be used for new connections unless a more preferred endpoint is not
available, or unless the deprecated endpoint was explicitly requested.

Test: Test that deprecated endpoints are only returned when more preferred
endpoints are not available and SLAAC addresses are deprecated after its
preferred lifetime
PiperOrigin-RevId: 288562705
2020-01-07 13:42:08 -08:00
Ghanan Gowripalan 8dfd922840 Pass the NIC-internal name to the NIC name function when generating opaque IIDs
Pass the NIC-internal name to the NIC name function when generating opaque IIDs
so implementations can use the name that was provided when the NIC was created.
Previously, explicit NICID to NIC name resolution was required from the netstack
integrator.

Tests: Test that the name provided when creating a NIC is passed to the NIC name
function when generating opaque IIDs.
PiperOrigin-RevId: 288395359
2020-01-06 16:21:31 -08:00
Ghanan Gowripalan 83ab47e87b Use opaque interface identifiers when generating IPv6 addresses via SLAAC
Support using opaque interface identifiers when generating IPv6 addresses via
SLAAC when configured to do so.

Note, this change does not handle retries in response to DAD conflicts yet.
That will also come in a later change.

Test: Test that when SLAAC addresses are generated, they use opaque interface
identifiers when configured to do so.
PiperOrigin-RevId: 288078605
2020-01-03 18:28:22 -08:00
Ghanan Gowripalan 5bc4ae9d57 Clear any host-specific NDP state when becoming a router
This change supports clearing all host-only NDP state when NICs become routers.
All discovered routers, discovered on-link prefixes and auto-generated addresses
will be invalidated when becoming a router. This is because normally, routers do
not process Router Advertisements to discover routers or on-link prefixes, and
do not do SLAAC.

Tests: Unittest to make sure that all discovered routers, discovered prefixes
and auto-generated addresses get invalidated when transitioning from a host to
a router.
PiperOrigin-RevId: 286902309
2019-12-23 08:55:25 -08:00
Ghanan Gowripalan 8e6e87f8e8 Allow 'out-of-line' routing table updates for Router and Prefix discovery events
This change removes the requirement that a new routing table be provided when a
router or prefix discovery event happens so that an updated routing table may
be provided to the stack at a later time from the event.

This change is to address the use case where the netstack integrator may need to
obtain a lock before providing updated routes in response to the events above.

As an example, say we have an integrator that performs the below two operations
operations as described:
A. Normal route update:
  1. Obtain integrator lock
  2. Update routes in the integrator
  3. Call Stack.SetRouteTable with the updated routes
    3.1. Obtain Stack lock
    3.2. Update routes in Stack
    3.3. Release Stack lock
  4. Release integrator lock
B. NDP event triggered route update:
  1. Obtain Stack lock
  2. Call event handler
    2.1. Obtain integrator lock
    2.2. Update routes in the integrator
    2.3. Release integrator lock
    2.4. Return updated routes to update Stack
  3. Update routes in Stack
  4. Release Stack lock

A deadlock may occur if a Normal route update was attemped at the same time an
NDP event triggered route update was attempted. With threads T1 and T2:
1) T1 -> A.1, A.2
2) T2 -> B.1
3) T1 -> A.3 (hangs at A.3.1 since Stack lock is taken in step 2)
4) T2 -> B.2 (hangs at B.2.1 since integrator lock is taken in step 1)

Test: Existing tests were modified to not provide or expect routing table
changes in response to Router and Prefix discovery events.
PiperOrigin-RevId: 286274712
2019-12-18 15:18:33 -08:00
Ghanan Gowripalan ad80dcf470 Properly generate the EUI64 interface identifier from an Ethernet address
Fixed a bug where the interface identifier was not properly generated from an
Ethernet address.

Tests: Unittests to make sure the functions generating the EUI64 interface
identifier are correct.
PiperOrigin-RevId: 285494562
2019-12-13 16:41:41 -08:00
Ghanan Gowripalan 4ff71b5be4 Inform the integrator on receipt of an NDP Recursive DNS Server option
This change adds support to let an integrator know when it receives an NDP
Router Advertisement message with the NDP Recursive DNS Server option with at
least one DNS server's address. The stack will not maintain any state related to
the DNS servers - the integrator is expected to maintain any required state and
invalidate the servers after its valid lifetime expires, or refresh the lifetime
when a new one is received for a known DNS server.

Test: Unittest to make sure that an event is sent to the integrator when an NDP
Recursive DNS Server option is received with at least one address.
PiperOrigin-RevId: 284890502
2019-12-10 18:05:23 -08:00
Ghanan Gowripalan ab3f7bc393 Do IPv6 Stateless Address Auto-Configuration (SLAAC)
This change allows the netstack to do SLAAC as outlined by RFC 4862 section 5.5.

Note, this change will not break existing uses of netstack as the default
configuration for the stack options is set in such a way that SLAAC
will not be performed. See `stack.Options` and `stack.NDPConfigurations` for
more details.

This change reuses 1 option and introduces a new one that is required to take
advantage of SLAAC, all available under NDPConfigurations:
- HandleRAs: Whether or not NDP RAs are processes
- AutoGenGlobalAddresses: Whether or not SLAAC is performed.

Also note, this change does not deprecate SLAAC generated addresses after the
preferred lifetime. That will come in a later change (b/143713887). Currently,
only the valid lifetime is honoured.

Tests: Unittest to make sure that SLAAC generates and adds addresses only when
configured to do so. Tests also makes sure that conflicts with static addresses
do not modify the static address.
PiperOrigin-RevId: 284265317
2019-12-06 14:41:30 -08:00
Ghanan Gowripalan 10f7b109ab Add a type to represent the NDP Recursive DNS Server option
This change adds a type to represent the NDP Recursive DNS Server option, as
defined by RFC 8106 section 5.1.

PiperOrigin-RevId: 284005493
2019-12-05 10:41:45 -08:00
Kevin Krakauer 3f7d937090 Use PacketBuffers for outgoing packets.
PiperOrigin-RevId: 280455453
2019-11-14 10:15:38 -08:00
Ghanan Gowripalan 5398530e45 Discover on-link prefixes from Router Advertisements' Prefix Information options
This change allows the netstack to do NDP's Prefix Discovery as outlined by
RFC 4861 section 6.3.4. If configured to do so, when a new on-link prefix is
discovered, the routing table will be updated with a device route through
the nic the RA arrived at. Likewise, when such a prefix gets invalidated, the
device route will be removed.

Note, this change will not break existing uses of netstack as the default
configuration for the stack options is set in such a way that Prefix Discovery
will not be performed. See `stack.Options` and `stack.NDPConfigurations` for
more details.

This change reuses 1 option and introduces a new one that is required to take
advantage of Prefix Discovery, all available under NDPConfigurations:
- HandleRAs: Whether or not NDP RAs are processes
- DiscoverOnLinkPrefixes: Whether or not Prefix Discovery is performed (new)

Another note: for a NIC to process Prefix Information options (in Router
Advertisements), it must not be a router itself. Currently the netstack does not
have per-interface routing configuration; the routing/forwarding configuration
is controlled stack-wide. Therefore, if the stack is configured to enable
forwarding/routing, no router Advertisements (and by extension the Prefix
Information options) will be processed.

Tests: Unittest to make sure that Prefix Discovery and updates to the routing
table only occur if explicitly configured to do so. Unittest to make sure at
max stack.MaxDiscoveredOnLinkPrefixes discovered on-link prefixes are
remembered.
PiperOrigin-RevId: 280049278
2019-11-12 14:09:43 -08:00
Ghanan Gowripalan 0c424ea731 Rename nicid to nicID to follow go-readability initialisms
https://github.com/golang/go/wiki/CodeReviewComments#initialisms

This change does not introduce any new functionality. It just renames variables
from `nicid` to `nicID`.

PiperOrigin-RevId: 278992966
2019-11-06 19:41:25 -08:00
Ghanan Gowripalan e63db5e7bb Discover default routers from Router Advertisements
This change allows the netstack to do NDP's Router Discovery as outlined by
RFC 4861 section 6.3.4.

Note, this change will not break existing uses of netstack as the default
configuration for the stack options is set in such a way that Router Discovery
will not be performed. See `stack.Options` and `stack.NDPConfigurations` for
more details.

This change introduces 2 options required to take advantage of Router Discovery,
all available under NDPConfigurations:
- HandleRAs: Whether or not NDP RAs are processes
- DiscoverDefaultRouters: Whether or not Router Discovery is performed

Another note: for a NIC to process Router Advertisements, it must not be a
router itself. Currently the netstack does not have per-interface routing
configuration; the routing/forwarding configuration is controlled stack-wide.
Therefore, if the stack is configured to enable forwarding/routing, no Router
Advertisements will be processed.

Tests: Unittest to make sure that Router Discovery and updates to the routing
table only occur if explicitly configured to do so. Unittest to make sure at
max stack.MaxDiscoveredDefaultRouters discovered default routers are remembered.
PiperOrigin-RevId: 278965143
2019-11-06 16:29:58 -08:00
Ghanan Gowripalan a824b48cea Validate incoming NDP Router Advertisements, as per RFC 4861 section 6.1.2
This change validates incoming NDP Router Advertisements as per RFC 4861 section
6.1.2. It also includes the skeleton to handle Router Advertiements that arrive
on some NIC.

Tests: Unittest to make sure only valid NDP Router Advertisements are received/
not dropped.
PiperOrigin-RevId: 278891972
2019-11-06 10:39:29 -08:00
Ghanan Gowripalan f034790ad8 Use interface-specific NDP configurations instead of the stack-wide default.
This change makes it so that NDP work is done using the per-interface NDP
configurations instead of the stack-wide default NDP configurations to correctly
implement RFC 4861 section 6.3.2 (note here, a host is a single NIC operating
as a host device), and RFC 4862 section 5.1.

Test: Test that we can set NDP configurations on a per-interface basis without
affecting the configurations of other interfaces or the stack-wide default. Also
make sure that after the configurations are updated, the updated configurations
are used for NDP processes (e.g. Duplicate Address Detection).
PiperOrigin-RevId: 276525661
2019-10-24 11:09:18 -07:00
Ghanan Gowripalan de3dbf8a09 Inform netstack integrator when Duplicate Address Detection completes
This change introduces a new interface, stack.NDPDispatcher. It can be
implemented by the netstack integrator to receive NDP related events. As of this
change, only DAD related events are supported.

Tests: Existing tests were modified to use the NDPDispatcher's DAD events for
DAD tests where it needed to wait for DAD completing (failing and resolving).
PiperOrigin-RevId: 276338733
2019-10-23 13:26:35 -07:00
Ghanan Gowripalan 962aa235de NDP Neighbor Solicitations sent during DAD must have an IP hop limit of 255
NDP Neighbor Solicitations sent during Duplicate Address Detection must have an
IP hop limit of 255, as all NDP Neighbor Solicitations should have.

Test: Test that DAD messages have the IPv6 hop limit field set to 255.
PiperOrigin-RevId: 275321680
2019-10-17 13:06:15 -07:00
Ghanan Gowripalan 06ed9e329d Do Duplicate Address Detection on permanent IPv6 addresses.
This change adds support for Duplicate Address Detection on IPv6 addresses
as defined by RFC 4862 section 5.4.

Note, this change will not break existing uses of netstack as the default
configuration for the stack options is set in such a way that DAD will not be
performed. See `stack.Options` and `stack.NDPConfigurations` for more details.

Tests: Tests to make sure that the DAD process properly resolves or fails.
That is, tests make sure that DAD resolves only if:
  - No other node is performing DAD for the same address
  - No other node owns the same address
PiperOrigin-RevId: 275189471
2019-10-16 22:54:45 -07:00