diff options
author | Ghanan Gowripalan <ghanan@google.com> | 2020-12-21 22:23:18 -0800 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2020-12-21 22:26:10 -0800 |
commit | 620de250a48ac6a0f1c46b6ea22eb94e4c907a8e (patch) | |
tree | 33927c23fc2de19015fa9bbc98ea3726bac2fa66 /pkg/tcpip/tcpip.go | |
parent | 946cb909e62e0aaca9e3bbb7cf059dd6b0eab2ce (diff) |
Prefer matching labels and longest matching prefix
...when performing source address selection for IPv6.
These are defined in RFC 6724 section 5 rule 6 (prefer matching label)
and rule 8 (use longest matching prefix).
This change also considers ULA of global scope instead of its own scope,
as per RFC 6724 section 3.1:
Also, note that ULAs are considered as global, not
site-local, scope but are handled via the prefix policy table as
discussed in Section 10.6.
Test: stack_test.TestIPv6SourceAddressSelectionScope
Startblock:
has LGTM from peterjohnston
and then
add reviewer brunodalbo
PiperOrigin-RevId: 348580996
Diffstat (limited to 'pkg/tcpip/tcpip.go')
-rw-r--r-- | pkg/tcpip/tcpip.go | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/pkg/tcpip/tcpip.go b/pkg/tcpip/tcpip.go index a488cc108..d195304be 100644 --- a/pkg/tcpip/tcpip.go +++ b/pkg/tcpip/tcpip.go @@ -258,6 +258,44 @@ func (a Address) Unspecified() bool { return true } +// MatchingPrefix returns the matching prefix length in bits. +// +// Panics if b and a have different lengths. +func (a Address) MatchingPrefix(b Address) uint8 { + const bitsInAByte = 8 + + if len(a) != len(b) { + panic(fmt.Sprintf("addresses %s and %s do not have the same length", a, b)) + } + + var prefix uint8 + for i := range a { + aByte := a[i] + bByte := b[i] + + if aByte == bByte { + prefix += bitsInAByte + continue + } + + // Count the remaining matching bits in the byte from MSbit to LSBbit. + mask := uint8(1) << (bitsInAByte - 1) + for { + if aByte&mask == bByte&mask { + prefix++ + mask >>= 1 + continue + } + + break + } + + break + } + + return prefix +} + // AddressMask is a bitmask for an address. type AddressMask string |