summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/header/ipv6.go
diff options
context:
space:
mode:
authorGhanan Gowripalan <ghanan@google.com>2020-01-13 17:56:44 -0800
committergVisor bot <gvisor-bot@google.com>2020-01-13 17:58:28 -0800
commit1ad8381eac108304f7b96162674624b34b95ec7b (patch)
treecf7628b5c60d4599077bac101126187971f892cf /pkg/tcpip/header/ipv6.go
parentdebd213da61cf35d7c91346820e93fc87bfa5896 (diff)
Do Source Address Selection when choosing an IPv6 source address
Do Source Address Selection when choosing an IPv6 source address as per RFC 6724 section 5 rules 1-3: 1) Prefer same address 2) Prefer appropriate scope 3) Avoid deprecated addresses. A later change will update Source Address Selection to follow rules 4-8. Tests: Rule 1 & 2: stack.TestIPv6SourceAddressSelectionScopeAndSameAddress, Rule 3: stack.TestAutoGenAddrTimerDeprecation, stack.TestAutoGenAddrDeprecateFromPI PiperOrigin-RevId: 289559373
Diffstat (limited to 'pkg/tcpip/header/ipv6.go')
-rw-r--r--pkg/tcpip/header/ipv6.go43
1 files changed, 43 insertions, 0 deletions
diff --git a/pkg/tcpip/header/ipv6.go b/pkg/tcpip/header/ipv6.go
index 135a60b12..83425c614 100644
--- a/pkg/tcpip/header/ipv6.go
+++ b/pkg/tcpip/header/ipv6.go
@@ -333,6 +333,17 @@ func IsV6LinkLocalAddress(addr tcpip.Address) bool {
return addr[0] == 0xfe && (addr[1]&0xc0) == 0x80
}
+// IsV6UniqueLocalAddress determines if the provided address is an IPv6
+// unique-local address (within the prefix FC00::/7).
+func IsV6UniqueLocalAddress(addr tcpip.Address) bool {
+ if len(addr) != IPv6AddressSize {
+ return false
+ }
+ // According to RFC 4193 section 3.1, a unique local address has the prefix
+ // FC00::/7.
+ return (addr[0] & 0xfe) == 0xfc
+}
+
// AppendOpaqueInterfaceIdentifier appends a 64 bit opaque interface identifier
// (IID) to buf as outlined by RFC 7217 and returns the extended buffer.
//
@@ -371,3 +382,35 @@ func LinkLocalAddrWithOpaqueIID(nicName string, dadCounter uint8, secretKey []by
return tcpip.Address(AppendOpaqueInterfaceIdentifier(lladdrb[:IIDOffsetInIPv6Address], IPv6LinkLocalPrefix.Subnet(), nicName, dadCounter, secretKey))
}
+
+// IPv6AddressScope is the scope of an IPv6 address.
+type IPv6AddressScope int
+
+const (
+ // LinkLocalScope indicates a link-local address.
+ LinkLocalScope IPv6AddressScope = iota
+
+ // UniqueLocalScope indicates a unique-local address.
+ UniqueLocalScope
+
+ // GlobalScope indicates a global address.
+ GlobalScope
+)
+
+// ScopeForIPv6Address returns the scope for an IPv6 address.
+func ScopeForIPv6Address(addr tcpip.Address) (IPv6AddressScope, *tcpip.Error) {
+ if len(addr) != IPv6AddressSize {
+ return GlobalScope, tcpip.ErrBadAddress
+ }
+
+ switch {
+ case IsV6LinkLocalAddress(addr):
+ return LinkLocalScope, nil
+
+ case IsV6UniqueLocalAddress(addr):
+ return UniqueLocalScope, nil
+
+ default:
+ return GlobalScope, nil
+ }
+}