Hi Jon,
Thanks for bringing up my favorite topic!
> I have stumbled across two functions that purport to construct a
> link-local IPv6 address from a MAC address. A laudable goal,
> but the details need some review.
>
> One function can be found in src/vnet/ip/ip6.h:
>
> always_inline void
> ip6_link_local_address_from_ethernet_mac_address (ip6_address_t * ip,
> u8 * mac)
> {
> ip->as_u64[0] = clib_host_to_net_u64 (0xFE80000000000000ULL);
> /* Invert the "u" bit */
> ip->as_u8[8] = mac[0] ^ (1 << 1);
> ip->as_u8[9] = mac[1];
> ip->as_u8[10] = mac[2];
> ip->as_u8[11] = 0xFF;
> ip->as_u8[12] = 0xFE;
> ip->as_u8[13] = mac[3];
> ip->as_u8[14] = mac[4];
> ip->as_u8[15] = mac[5];
> }
>
> I draw your attention to the assignment to ip->as_u8[8], where bit 0x02 is
> XOR'ed in.
>
> The second function is found in src/vnet/ip/ip6_packet.h:
>
> always_inline void
> ip6_link_local_address_from_ethernet_address (ip6_address_t * a,
> const u8 * ethernet_address)
> {
> a->as_u64[0] = a->as_u64[1] = 0;
> a->as_u16[0] = clib_host_to_net_u16 (0xfe80);
> /* Always set locally administered bit (6). */
> a->as_u8[0x8] = ethernet_address[0] | (1 << 6);
> a->as_u8[0x9] = ethernet_address[1];
> a->as_u8[0xa] = ethernet_address[2];
> a->as_u8[0xb] = 0xff;
> a->as_u8[0xc] = 0xfe;
> a->as_u8[0xd] = ethernet_address[3];
> a->as_u8[0xe] = ethernet_address[4];
> a->as_u8[0xf] = ethernet_address[5];
> }
>
> Here, I draw your attention to the similar assignment to a->as_u8[8] where
> bit 0x40 is OR'ed in.
>
> I will grant you that confusion exists in the literature. Let's dispense with
> "counting from 0" and "counting from 1", and guessing if the displayed bits
> are ordered Left to Right as 0 to 7, or 7 to 0. Let's talk powers of 2
> instead.
>
> My understanding, though possibly wrong, is that 2^1 of byte 8 is the
> question.
> So I believe the (1 << 6) is wrong. So we'll talk about 0x02, which I
> believe is correct.
Correct. It’s bit 70 in network byte order of the IPv6 address.
> Now, should the bit be set, or XOR'ed? There are arguments for both cases,
> so I
> do not know which is correct and desired here. Specifically, given a MAC
> address,
> does that 0x02 bit need to be inverted to maintain its Global/Local status as
> it is
> copied to the IPv6 address? Do we even want to maintain its G/L status? Or
> do
> we want to force it to be locally administered by slamming the bit to 1?
Note that the bit is inverted. 0 in MAC means globally unique, while 1 in IPv6
address means globally unique
> I am happy to submit a patch to fix this situation, but I'd like to make sure
> we get it right. :-)
>
> Here's what I think we should do:
> - Remove the function ip6_link_local_address_from_ethernet_address() as it
> contains the incorrect bit, (1 << 6).
> - Replace the one use of that function with a call to
Yes, please!
ip6_link_local_address_from_ethernet_mac_address() instead.
> - Answer the bit-wise XOR vs OR question ...?
XOR is correct.
> Other suggestions or advice?
Now in our infinite wisdom, in the IETF we have deprecated this bit.
This flag was largely there to accommodate a future with 8+8, which didn’t
quite happen.
Still, as long as we build link-locals from mac addresses, I think we should
follow the modified EUI-64 format.
But ensure we do not do any sanity checks or anything else with bit 70. Aka the
U flag.
Cheers
Ole
>
>
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
>
> View/Reply Online (#13280): https://lists.fd.io/g/vpp-dev/message/13280
> Mute This Topic: https://lists.fd.io/mt/32054012/675193
> Group Owner: [email protected]
> Unsubscribe: https://lists.fd.io/g/vpp-dev/unsub [[email protected]]
> -=-=-=-=-=-=-=-=-=-=-=-
-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#13281): https://lists.fd.io/g/vpp-dev/message/13281
Mute This Topic: https://lists.fd.io/mt/32054012/21656
Group Owner: [email protected]
Unsubscribe: https://lists.fd.io/g/vpp-dev/unsub [[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-