summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/header/eth.go
diff options
context:
space:
mode:
authorGhanan Gowripalan <ghanan@google.com>2019-10-22 07:25:35 -0700
committergVisor bot <gvisor-bot@google.com>2019-10-22 07:26:54 -0700
commitfb69de696be5d5ebfd427867fe387c2f93845bfa (patch)
tree179570706465adc4d23cc849b68fb23d0761bc8a /pkg/tcpip/header/eth.go
parent070a8c2d4ca3547304a0ab7539208cca44b1ba86 (diff)
Auto-generate an IPv6 link-local address based on the NIC's MAC Address.
This change adds support for optionally auto-generating an IPv6 link-local address based on the NIC's MAC Address on NIC enable. 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 a link-local address will not be auto-generated unless the stack is explicitly configured. See `stack.Options` for more details. Specifically, see `stack.Options.AutoGenIPv6LinkLocal`. Tests: Tests to make sure that the IPb6 link-local address is only auto-generated if the stack is specifically configured to do so. Also tests to make sure that an auto-generated address goes through the DAD process. PiperOrigin-RevId: 276059813
Diffstat (limited to 'pkg/tcpip/header/eth.go')
-rw-r--r--pkg/tcpip/header/eth.go44
1 files changed, 44 insertions, 0 deletions
diff --git a/pkg/tcpip/header/eth.go b/pkg/tcpip/header/eth.go
index 1bb3bb5e6..f5d2c127f 100644
--- a/pkg/tcpip/header/eth.go
+++ b/pkg/tcpip/header/eth.go
@@ -48,6 +48,28 @@ const (
// EthernetAddressSize is the size, in bytes, of an ethernet address.
EthernetAddressSize = 6
+
+ // unspecifiedEthernetAddress is the unspecified ethernet address
+ // (all bits set to 0).
+ unspecifiedEthernetAddress = tcpip.LinkAddress("\x00\x00\x00\x00\x00\x00")
+
+ // unicastMulticastFlagMask is the mask of the least significant bit in
+ // the first octet (in network byte order) of an ethernet address that
+ // determines whether the ethernet address is a unicast or multicast. If
+ // the masked bit is a 1, then the address is a multicast, unicast
+ // otherwise.
+ //
+ // See the IEEE Std 802-2001 document for more details. Specifically,
+ // section 9.2.1 of http://ieee802.org/secmail/pdfocSP2xXA6d.pdf:
+ // "A 48-bit universal address consists of two parts. The first 24 bits
+ // correspond to the OUI as assigned by the IEEE, expect that the
+ // assignee may set the LSB of the first octet to 1 for group addresses
+ // or set it to 0 for individual addresses."
+ unicastMulticastFlagMask = 1
+
+ // unicastMulticastFlagByteIdx is the byte that holds the
+ // unicast/multicast flag. See unicastMulticastFlagMask.
+ unicastMulticastFlagByteIdx = 0
)
const (
@@ -90,3 +112,25 @@ func (b Ethernet) Encode(e *EthernetFields) {
copy(b[srcMAC:][:EthernetAddressSize], e.SrcAddr)
copy(b[dstMAC:][:EthernetAddressSize], e.DstAddr)
}
+
+// IsValidUnicastEthernetAddress returns true if addr is a valid unicast
+// ethernet address.
+func IsValidUnicastEthernetAddress(addr tcpip.LinkAddress) bool {
+ // Must be of the right length.
+ if len(addr) != EthernetAddressSize {
+ return false
+ }
+
+ // Must not be unspecified.
+ if addr == unspecifiedEthernetAddress {
+ return false
+ }
+
+ // Must not be a multicast.
+ if addr[unicastMulticastFlagByteIdx]&unicastMulticastFlagMask != 0 {
+ return false
+ }
+
+ // addr is a valid unicast ethernet address.
+ return true
+}