diff options
author | Ghanan Gowripalan <ghanan@google.com> | 2021-06-18 12:41:08 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-06-18 12:43:25 -0700 |
commit | 081c463ad865e741f461baad349bc72a15fa04f0 (patch) | |
tree | ff6669594a96c65cda11b420b22e3214ddc67405 /pkg/tcpip/network | |
parent | 1f2ce9f46100d6ff958f7c257d3c0a949ede4f4c (diff) |
Include off-link route's preference in update events
RFC 4191 supports the notion of a preference value for default routers
and more-specific routes, so update the OffLinkRouteUpdate event to
include this preference value so integrators may prioritize routes
based on a route's advertised preference value.
Note, more-specific route discovery is not supported yet, but will be in
a later change.
Updates #6172.
Test: ndp_test.TestRouterDiscovery
PiperOrigin-RevId: 380243716
Diffstat (limited to 'pkg/tcpip/network')
-rw-r--r-- | pkg/tcpip/network/ipv6/ndp.go | 32 | ||||
-rw-r--r-- | pkg/tcpip/network/ipv6/ndp_test.go | 4 |
2 files changed, 30 insertions, 6 deletions
diff --git a/pkg/tcpip/network/ipv6/ndp.go b/pkg/tcpip/network/ipv6/ndp.go index ee36ed254..57d4afd4d 100644 --- a/pkg/tcpip/network/ipv6/ndp.go +++ b/pkg/tcpip/network/ipv6/ndp.go @@ -218,7 +218,7 @@ type NDPDispatcher interface { // // This function is not permitted to block indefinitely. This function // is also not permitted to call into the stack. - OnOffLinkRouteUpdated(tcpip.NICID, tcpip.Subnet, tcpip.Address) + OnOffLinkRouteUpdated(tcpip.NICID, tcpip.Subnet, tcpip.Address, header.NDPRoutePreference) // OnOffLinkRouteInvalidated is called when an off-link route is invalidated. // @@ -508,6 +508,8 @@ type ndpState struct { // defaultRouterState holds data associated with a default router discovered by // a Router Advertisement (RA). type defaultRouterState struct { + prf header.NDPRoutePreference + // Job to invalidate the default router. // // Must not be nil. @@ -726,6 +728,19 @@ func (ndp *ndpState) handleRA(ip tcpip.Address, ra header.NDPRouterAdvert) { // Is the IPv6 endpoint configured to discover default routers? if ndp.configs.DiscoverDefaultRouters { + prf := ra.DefaultRouterPreference() + if prf == header.ReservedRoutePreference { + // As per RFC 4191 section 2.2, + // + // Prf (Default Router Preference) + // + // If the Reserved (10) value is received, the receiver MUST treat the + // value as if it were (00). + // + // Note that the value 00 is the medium (default) router preference value. + prf = header.MediumRoutePreference + } + rtr, ok := ndp.defaultRouters[ip] rl := ra.RouterLifetime() switch { @@ -735,7 +750,7 @@ func (ndp *ndpState) handleRA(ip tcpip.Address, ra header.NDPRouterAdvert) { // Only remember it if we currently know about less than // MaxDiscoveredDefaultRouters routers. if len(ndp.defaultRouters) < MaxDiscoveredDefaultRouters { - ndp.rememberDefaultRouter(ip, rl) + ndp.rememberDefaultRouter(ip, rl, prf) } case ok && rl != 0: @@ -743,6 +758,14 @@ func (ndp *ndpState) handleRA(ip tcpip.Address, ra header.NDPRouterAdvert) { // the invalidation job. rtr.invalidationJob.Cancel() rtr.invalidationJob.Schedule(rl) + + if prf != rtr.prf { + rtr.prf = prf + + // Inform the integrator about router preference updates. + ndp.ep.protocol.options.NDPDisp.OnOffLinkRouteUpdated(ndp.ep.nic.ID(), header.IPv6EmptySubnet, ip, prf) + } + ndp.defaultRouters[ip] = rtr case ok && rl == 0: @@ -834,16 +857,17 @@ func (ndp *ndpState) invalidateDefaultRouter(ip tcpip.Address) { // The router identified by ip MUST NOT already be known by the IPv6 endpoint. // // The IPv6 endpoint that ndp belongs to MUST be locked. -func (ndp *ndpState) rememberDefaultRouter(ip tcpip.Address, rl time.Duration) { +func (ndp *ndpState) rememberDefaultRouter(ip tcpip.Address, rl time.Duration, prf header.NDPRoutePreference) { ndpDisp := ndp.ep.protocol.options.NDPDisp if ndpDisp == nil { return } // Inform the integrator when we discovered a default router. - ndpDisp.OnOffLinkRouteUpdated(ndp.ep.nic.ID(), header.IPv6EmptySubnet, ip) + ndpDisp.OnOffLinkRouteUpdated(ndp.ep.nic.ID(), header.IPv6EmptySubnet, ip, prf) state := defaultRouterState{ + prf: prf, invalidationJob: ndp.ep.protocol.stack.NewJob(&ndp.ep.mu, func() { ndp.invalidateDefaultRouter(ip) }), diff --git a/pkg/tcpip/network/ipv6/ndp_test.go b/pkg/tcpip/network/ipv6/ndp_test.go index 95d23f200..130438f3b 100644 --- a/pkg/tcpip/network/ipv6/ndp_test.go +++ b/pkg/tcpip/network/ipv6/ndp_test.go @@ -42,7 +42,7 @@ type testNDPDispatcher struct { func (*testNDPDispatcher) OnDuplicateAddressDetectionResult(tcpip.NICID, tcpip.Address, stack.DADResult) { } -func (t *testNDPDispatcher) OnOffLinkRouteUpdated(_ tcpip.NICID, _ tcpip.Subnet, addr tcpip.Address) { +func (t *testNDPDispatcher) OnOffLinkRouteUpdated(_ tcpip.NICID, _ tcpip.Subnet, addr tcpip.Address, _ header.NDPRoutePreference) { t.addr = addr } @@ -93,7 +93,7 @@ func TestStackNDPEndpointInvalidateDefaultRouter(t *testing.T) { ipv6EP := ep.(*endpoint) ipv6EP.mu.Lock() - ipv6EP.mu.ndp.rememberDefaultRouter(lladdr1, time.Hour) + ipv6EP.mu.ndp.rememberDefaultRouter(lladdr1, time.Hour, header.MediumRoutePreference) ipv6EP.mu.Unlock() if ndpDisp.addr != lladdr1 { |