One of IPv6's key benefits over IPv4 is its capability for automatic interface addressing. By implementing the IEEE's 64-bit Extended Unique Identifier (EUI-64) format, a host can automatically assign itself a unique 64-bit IPv6 interface identifier without the need for manual configuration or DHCP. This is accomplished on Ethernet interfaces by referencing the already unique 48-bit MAC address, and reformatting that value to match the EUI-64 specification.
RFC 2373 dictates the conversion process, which can be described as having two steps. The first step is to convert the 48-bit MAC address to a 64-bit value. To do this, we break the MAC address into its two 24-bit halves: the Organizationally Unique Identifier (OUI) and the NIC specific part. The 16-bit hex value
0xFFFE is then inserted between these two halves to form a 64-bit address.
0xFFFE? As explained in the IEEE's Guidelines for EUI-64 Registration Authority, this is a reserved value which equipment manufacturers cannot include in "real" EUI-64 address assignments. In other words, any EUI-64 address having
0xFFFE immediately following its OUI portion can be recognized as having been generated from an EUI-48 (or MAC) address.
The second step is to invert the universal/local (U/L) flag (bit 7) in the OUI portion of the address. Globally unique addresses assigned by the IEEE originally have this bit set to zero, indicating global uniqueness. Likewise, locally created addresses, such as those used for virtual interfaces or a MAC address manually configured by an administrator, will have this bit set to one. The U/L bit is inverted when using an EUI-64 address as an IPv6 interface ID.
Again, you're probably wondering why this is done. The answer lies buried in section 2.5.1 of RFC 2373:
The motivation for inverting the "u" bit when forming the interface identifier is to make it easy for system administrators to hand configure local scope identifiers when hardware tokens are not available. This is expected to be case for serial links, tunnel end-points, etc. The alternative would have been for these to be of the form 0200:0:0:1, 0200:0:0:2, etc., instead of the much simpler ::1, ::2, etc.
The important part to remember here is that the scope of the address never changes: global addresses are still global and local addresses are still local. Rather, the meaning of the bit is inverted for convenience, so the value of the bit must be inverted as well.
We can see this conversion in action when we assign an IPv6 address to a router interface. First, take note of the interface's MAC address (this is typically the same as its burned-in address, or BIA).
Router# show interface f0/0 FastEthernet0/0 is up, line protocol is down Hardware is Gt96k FE, address is 0012.7feb.6b40 (bia 0012.7feb.6b40) ...
After assigning an EUI-64-designated IPv6 address to the interface, we can verify that the interface ID has been drawn from the MAC address in the process described for both the assigned and the link local address:
Router(config)# interface f0/0 Router(config-if)# ipv6 address 2001:db8::/64 eui-64 Router(config-if)# do show ipv6 interface f0/0 FastEthernet0/0 is up, line protocol is down IPv6 is enabled, link-local address is FE80::212:7FFF:FEEB:6B40 [TEN] No Virtual link-local address(es): Global unicast address(es): 2001:DB8::212:7FFF:FEEB:6B40, subnet is 2001:DB8::/64 [EUI/TEN] ...