IPv6: Generowanie interface ID przy użyciu EUI-64 

 

64-bit Extended Unique Identifier (EUI-64) jest zdefiniowanym przez organizację IEEE formatem zapisu identyfikatorów. Identyfikatory te mogą być wykorzystywane do różnych celów. W naszym przypadku, skorzystamy z EUI-64 do wygenerowania 64 bitowego identyfikatora interfejsu adresu IPv6. Poniżej został przypomniana struktura adresu Global Unicast IPv6. W tym przypadku global routing prefix + subnet ID ma 64 bity.

 

   |         n bits         |   m bits  |       128-n-m bits         |

   +------------------------+-----------+----------------------------+

   | global routing prefix  | subnet ID |       interface ID         |

   +------------------------+-----------+----------------------------+

 

Wykorzystywane wartości w polu interface ID mogą mieć zakres uniwersalny lub lokalny. Jeżeli zostały one wygenerowane automatycznie, na skutek opisanej poniżej procedury zamiany IEEE MAC-48 na IEEE EUI-64, to będzie to zakres uniwersalny. Jeżeli nie, to powinny posiadać zakres lokalny.

Do automatycznego wygenerowania interface ID z użyciu EUI-64 może dojść tylko wtedy, kiedy mamy dostępny tzw. token. Jest nim jedna z unikalnych wartości opisanych w specyfikacji EUI-64 (np. 48 bitowy adres MAC standardów IEEE 802). Powstały w ten sposób adres ma zakres universal. 

Jeżeli takiego tokena nie ma (np. połączenia szeregowe lub końce tuneli) lub kiedy wykorzystanie takiego tokena nie jest z jakiś powodów pożądane (np. ze względu na prywatność) to mamy możliwość przypisywania ostatnim 64 bitom dowolnej wartości. Przy czym powstały w ten sposób adres powinien mieć zakres local.

Kiedy dochodzi do automatycznego tworzenia identyfikatora bazującego na formacie EUI-64, następuje inwersja bitu "u" (bit universal/local w terminologii IEEE). W adresie warstwy dostępu do sieci, jest to drugi najmniej znaczący bit pierwszego oktetu (widać jego umiejscowienie poniżej). Zgodnie z IEEE, bit ten posiada wartość 1 (local), kiedy adres przypisywany jest lokalnie przez administratora i 0 (universal), kiedy adres przypisywany jest globalnie przez IEEE - odnosi się to do IEEE MAC-48. Poniżej zostały przedstawione pierwsze 24 bity adresu IEEE MAC-48 (pierwsze 24 bity nazywane są też OUI - Organizationally Unique Identifier).

          0       0 0       1 1       2

         |0       7 8       5 6       3|

         +----+----+----+----+----+----+

         |cccc|ccug|cccc|cccc|cccc|cccc| 

         +----+----+----+----+----+----+

                 ^ u = 0 (universal), u = 1 (local) 

 

Zgodnie z IEEE, bit "g" definiuje czy jest to adres grupowy czy indywidualny, a pozostałe bity "c" reszty 24 bitów adresu tworzą identyfikator firmy (OUI), która zarządza dystrybucją dalszej jego części (niewidocznej powyżej).

Powiedzieliśmy, że podczas konwersji do EUI-64 dokonujemy inwersji bitu "u". Zatem w IEEE EUI-64, wartość bitu "u" ma dokładnie odwrotne znaczenie niż w IEEE MAC-48. Kiedy ma on wartość 1 (universal), oznacza unikalny globalnie identyfikator interfejsu (interface ID) - w związku z tym, że wygenerowany na bazie unikalnego tokena (np. IEEE MAC-48). Kiedy ma on wartość 0 (local), oznacza nieunikalny identyfikator interfejsu (interface ID) - jest on ustawiony ręcznie przez administratora lub wygenerowany na podstawie czegoś co nie jest unikalne, stąd w ramach globalnej sieci może się powtórzyć (mowa o samej części interface ID).

Po co ta inwersja bitu "u"? Dla naszej wygody. Dzięki niej, kiedy ustawiamy ręcznie adres IPv6, w ostatnich 64 bitach możemy wpisać po prostu wartość 0000:0000:0000:0001 (0:0:0:1), zamiast 0200:0000:0000:0001 (200:0:0:1) i będzie ona zgodna z przyjętą konwencją - bit "u" ma wartość 0, co dla EUI-64 oznacza local. Konwersja IEEE MAC-48 do IEEE EUI-64 jest realizowana automatycznie przez system operacyjny, któremu łatwiej jest pamiętać o odpowiednim ustawianiu bitu "u" na 1 - jest to zaszyte w kod tej procedury, więc nikt o tym nie zapomni. 

Jak wygląda generowanie identyfikatora w formacie EUI-64?

Załóżmy, że posiadamy 48 bitowy adres MAC, którego struktura znajduje się poniżej.

   |0              1|1              3|3              4|

   |0              5|6              1|2              7|

   +----------------+----------------+----------------+

   |cccccc0gcccccccc|ccccccccmmmmmmmm|mmmmmmmmmmmmmmmm|

   +----------------+----------------+----------------+

          ^ u = 0 (universal)

 

Bit 'u' jest ustawiony na 0 (universal), więc jest to adres unikalny globalnie. Bity 'm' są nadawane kolejno przez producenta sprzętu. Adres jest dzielony na dwie równe części, po 24 bity każda (granica pomiędzy bitami 'c' i 'm'). Następnie w środek wstawiana jest wartość 0xFF 0xFE i dokonywana jest inwersja bitu 'u'. Końcowy adres w formacie EUI-64 wygląda jak poniżej.

   |0              1|1              3|3              4|4              6|

   |0              5|6              1|2              7|8              3|

   +----------------+----------------+----------------+----------------+

   |cccccc1gcccccccc|cccccccc11111111|11111110mmmmmmmm|mmmmmmmmmmmmmmmm|

   +----------------+----------------+----------------+----------------+

          ^ u = 1 (universal)

 

Warto tutaj zaznaczyć, że według IEEE EUI-64, dla identyfikatorów IEEE MAC-48 powinno wstawiać się w środek wartość 0xFF 0xFF, a nie 0xFF 0xFE. Wartość 0xFF 0xFE powinno się używać tylko do rozszerzenia identyfikatorów IEEE EUI-48. W związku z błędem w interpretacji, podczas tworzenia wczesnych wersji specyfikacji, RFC definiuje użycie wartości 0xFF 0xFE także dla IEEE MAC-48. W związku z tym, że identyfikatory IEEE EUI-48 i MAC-48 są składniowo równoważne, nie powinno to sprawiać żadnych problemów.

Zobaczmy jak odbywa się konwersja IEEE MAC-48 do IEEE EUI-64 na przykładzie adresu MAC 28:cf:e9:15:25:a9 (0). W pierwszym kroku realizowane jest wstawienie w środek wartości 0xFF 0xFE (1). W drugim inwersja bitu "u" (2). Końcowa postać identyfikatora w formacie IEEE EUI-64 została przedstawiona binarnie (3) i szesnastkowo (4).

(0)

IEEE MAC-48: 28:cf:e9:15:25:a9

(1)         

00101000:11001111:11101001:00010101:00100101:10101001

                          ^ miejsce wstawienia 0xFF 0xFE

(2)

00101000:11001111:11101001:11111111:11111110:00010101:00100101:10101001

      ^ inwersja bitu "u"      

(3)           

00101010:11001111:11101001:11111111:11111110:00010101:00100101:10101001

      ^ u = 1 (universal)  ^ 0xFF   ^ 0xFE

(4)

IEEE EUI-64: 2a:cf:e9:ff:fe:15:25:a9

 
 

Wybrany adres MAC pochodzi z komputera na którym działa IPv6. Dzięki temu możemy łatwo sprawdzić poprawność powyższych wyliczeń. 

# ifconfig en0
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether 28:cf:e9:15:25:a9 
inet6 fe80::2acf:e9ff:fe15:25a9%en0 prefixlen 64 scopeid 0x4 
inet 10.0.1.5 netmask 0xffffff00 broadcast 10.0.1.255
nd6 options=1<PERFORMNUD>
media: autoselect
status: active
 

Widać, że dla adresu MAC 28:cf:e9:15:25:a9 system używa adresu IPv6 zgodnego z IEEE EUI-64 fe80::2acf:e9ff:fe15:25a9. Ostatnie 64 bity tego adresu zgadzają się z wynikiem naszych wyliczeń.

Należy jeszcze zwrócić uwagę na to, że zdarza się iż niektórzy producenci nadają ten sam adres MAC produkowanym interfejsom. Również w środowiskach, gdzie dochodzi do wirtualizacji możemy natrafić na interfejsy od tym samym adresie MAC. O ile te interfejsy są w różnych segmentach sieci, nie sprawia to oczywiście żadnego problemu. Poza tym, nigdy nie wiemy czy adres IPv6 został wygenerowany przy użyciu EUI-64. Powyższe oznacza, iż nie zawsze możemy traktować bit "u" jako niezawodną metodę gwarancji unikalności interface ID. Zgodnie z RFC 7136, bit ten ma wyżej opisane znaczenie tylko w przypadku, kiedy interface ID jest generowany przy użyciu EUI-64. Jeśli nadajemy go statycznie lub korzystamy z innej metody generowania interface ID traci on opisane tutaj znaczenie.


Zapraszamy do kontaktu drogą mailową This email address is being protected from spambots. You need JavaScript enabled to view it. lub telefonicznie +48 797 004 932.