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: vpp-dev+ow...@lists.fd.io > Unsubscribe: https://lists.fd.io/g/vpp-dev/unsub [otr...@employees.org] > -=-=-=-=-=-=-=-=-=-=-=-
-=-=-=-=-=-=-=-=-=-=-=- 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: vpp-dev+ow...@lists.fd.io Unsubscribe: https://lists.fd.io/g/vpp-dev/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-