Ana içeriğe geç

Bölüm 22: Ağ Interface Kartı

10 dakikalık okumaGüncelleme:

Ağlar'a “Sen”i Katmak kitabının bir bölümü: adres çubuğuna yazdığın tek bir isteğin peşinden bakırla fiberin fiziğine inip karşı taraftan geri dönen uzun bir teknik yolculuk.

Kısım 4: Makineden Yerel Ağa (Bölüm 18-29)

Tüm bölümler
  1. Giriş
  2. Adres Çubuğundan İsteğe
  3. Paket Anahtarlamalı Yol
  4. İsimden Adrese
  5. DNS Kayıtları
  6. Önbellek, Tazelik ve Güven
  7. Port Numarası ve Soket
  8. Bağlantısız Taşıma: UDP
  9. Üç Adımlı El Sıkışma
  10. Simetrik Şifreleme
  11. Açık Anahtarlı Kriptografi
  12. TLS El Sıkışması
  13. Sertifika Zinciri
  14. HTTP Mesajının Anatomisi
  15. Durum, Çerez ve Oturum
  16. HTTP/2'den HTTP/3'e
  17. İçerik Dağıtım Ağları
  18. Diğer Uygulama Protokolleri
  19. Katmanlı Mimari
  20. Hizmet ve Protokol
  21. Encapsulation ve Başlıklar
  22. Paket Yakalama ve Çözümleme
  23. Ağ Interface Kartı
  24. Fiziksel Adresleme
  25. Hata Sezme ve CRC
  26. Adres Çözümleme: ARP
  27. Ortam Erişimi: CSMA/CD
  28. Switch'ler
  29. Ağ Topolojileri
  30. Sanal Yerel Ağlar
  31. Kablosuz Erişim: 802.11
  32. Radyo Kanalı ve Kapasite
  33. Kablosuz Ağ Güvenliği
  34. Hücresel Ağlar
  35. Spektrum ve Kuşaklar
  36. Hareketlilik ve Aktarma
  37. Adres Kiralama: DHCP
  38. Adresin Anatomisi
  39. Adres Tükenmesi ve IPv6
  40. Router Mimarisi
  41. Kuyruk Yönetimi
  42. Cihaz Yapılandırma
  43. Routing Protokolleri
  44. Kontrol Düzlemi ve SDN
  45. Ağ İzleme ve Yönetimi
  46. Alanlar Arası Routing
  47. Adres Çevirisi
  48. Ara Kutular
  49. Tünelleme ve IPsec
  50. Firewall'lar
  51. Ağ Saldırıları
  52. Operatör ve Metro Ağları
  53. Bitten Sinyale
  54. Sembol Hızı ve Kanal Kapasitesi
  55. Multiplexing Teknikleri
  56. İletim Ortamları
  57. Bakır Kablo Sonlandırma
  58. Fiber Sonlandırma
  59. Fiber Optik İletim
  60. Bakır Erişim Ağı: DSL
  61. DSL'de Hız ve Mesafe
  62. Pasif Optik Ağlar
  63. Kablo Erişim Ağları
  64. Kablo Modem ve CMTS
  65. Denizaltı Kabloları
  66. Veri Merkezi Ağları
  67. Encapsulation Çözme
  68. Güvenilir Aktarım
  69. Tıkanıklık Denetimi
  70. Trafik Çözümleme
  71. Gecikme Bütçesi
  72. Soket Programlama
  73. Eşten Eşe ve Protokol Tasarımı
  74. Uyarlanır Video Akışı
  75. Gerçek Zamanlı Ses ve Görüntü
  76. Kablosuz Sensör Ağlarının Mimarisi
  77. Sensör Ağlarında Ortam Erişimi
  78. Sensör Ağlarında Yönlendirme ve IP
  79. Zaman Eşitleme ve Konum Bulma
  80. Sensör Ağı Uygulamaları
  81. Mobil Kablosuz Sensör Ağları
  82. Son Söz

Yakalama aracında her satırı bayt bayt sayıp zarfları tek tek gördün. Frame’i tele koyacak şeyi ise henüz adlandırmadım.

O şey bir program değil. Kablonun ucundaki ağ kartı, kendi işlemcisiyle çalışan ayrı bir bilgisayar. Peki bu kartın sınırı nerede başlıyor?

Kart nerede duruyor?

Ağ kartı, bilgisayarı ağa fiziksel olarak bağlayan parça. Tam adı ağ interface kartı (network interface card); Türkçe kaynaklarda ağ arayüz kartı, ağ adaptörü ya da ağ bağdaştırıcısı diye de geçiyor. Kısaltması NIC.

Kart makinenin sistem veriyoluna takılıyor ve diğer bileşenlerin gözünde sıradan bir giriş/çıkış aygıtından farkı olmuyor; klasik yuvası PCI, bugünkü karşılığı PCI Express. Ethernet’in ilk günlerinde üstü yongalarla kaplı kocaman bir devre kartı olarak duruyordu. Bugün aynı işi tek bir yongada ya da daha büyük bir sistem yongasının içindeki bir bölümde bitiriyorlar. Anakarta tümleşiği de var, USB’den takılanı da. Kart yine de tek bir parçadan ibaret değil; donanım, yazılım ve firmware birlikte çalışıyor.

Asıl ayrımı kartın hangi katmanları taşıdığında bulacaksın. Kart ikisini birden gerçekliyor, data link layer’ı ve physical layer’ı; üstündeki her şey yazılımda kalıyor. 19. bölümde sınırın çipte olduğunu söylemiştim ama orada adını vermediğim bir şey vardı: bu iki katman arasındaki iç interface.

Soket four-tuple’ını kurarken kernel’ın altında ne olduğunu kapalı kutu bırakmıştım. Kutuyu şimdi açıyorum. Soket katmanını kullanıcı alanı ile kernel alanının tam sınırında buluyorsun. Altında TCP ve UDP duruyor, onun altında IP, en altta da fiziksel ağa bakan sürücü.

Frame’i kim kuruyor?

Kartın kalbinde, MAC protokolünü de taşıyan tek bir özel amaçlı denetleyici yonga var. Framing, hatta erişim ve hata sezme bu yonganın işi. Üçünü de donanımda yapıyor.

Ucuz bir Ethernet kartının devre kartı: yüzeydeki en büyük kare parça, MAC ile physical layer'ı birlikte taşıyan denetleyici yonga. Frame'i kurmak, hatta ne zaman gönderileceğine karar vermek ve hatayı sezmek işletim sistemine hiç uğramadan orada biter.

Yonganın içi de ikiye bölünmüş durumda. MAC bölümü frame’le ilgileniyor, physical layer bölümü sinyalle. İşte o iç interface’in adı hıza göre değişiyor: 100 Mbit/s’te MII, gigabitte GMII, on gigabitte XGMII. Physical layer tarafı kendi içinde ayrıca katmanlı. Orada bir kodlama alt katmanı ile ortama bağlanan ve ortama bağımlı alt katmanlar duruyor; standarttaki adları PCS, PMA ve PMD.

Framing, datagramın önüne başlık arkasına kuyruk eklemek demek. Encapsulation merdivenini çıkarken bu basamağı dışarıdan, yani başlık ve kuyruk eklenmiş hâliyle görmüştük. Gönderme tarafında denetleyici, üst katmanların ana bellekte hazırlayıp bıraktığı datagramı oradan alıyor ve frame’i kendisi kuruyor.

Ama framing’in asıl zorluğu ekleme değil, ayırma. Physical layer’ın alıcıya verdiği şey kesintisiz bir bit dizisi; içinde nokta, boşluk ya da satır sonu yok. Alıcı bu stream’de bir frame’in nerede başlayıp nerede bittiğini bilmek zorunda, yoksa elindeki baytların hangisinin adres hangisinin veri olduğunu söyleyemez. Sorunun adı frame sınırlandırma ve tarih boyunca dört ayrı çözümü denendi.

Bayt sayısı. Frame’in başına uzunluğu yazarsın, alıcı o kadar bayt sayar. Zarif ama kırılgan: o sayıyı taşıyan bayt bozulursa alıcı sınırı kaçırır ve bir daha asla bulamaz; sonraki bütün frame’ler kayar. Tek bir bit hatası kalıcı bir hizasızlık üretiyor.

Bayrak baytı ve bayt doldurma. Frame’in iki ucuna özel bir bayrak baytı konur. PPP’de bu değer 0x7E. Peki veri içinde aynı bayt geçerse? Gönderen onun önüne bir kaçış baytı (0x7D) ekler ve baytı değiştirir; alıcı kaçışı görünce sonraki baytı ham veri sayar. Kaçış baytının kendisi de kaçırılır. Bedeli değişken: rastgele veride yaklaşık %1 şişme, ama en kötü durumda frame iki katına çıkabilir.

Bayrak dizisi ve bit doldurma. Aynı fikrin bit ölçeğindeki hâli. HDLC’de bayrak 01111110, yani altı ardışık bir. Gönderen veride beş ardışık bir gördüğü anda araya zorla bir sıfır sokar; böylece veri içinde altı ardışık bir asla oluşamaz. Alıcı beş birden sonra gelen sıfırı sessizce atar.

veri                 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0
telde (doldurulmuş)  0 1 1 1 1 1 [0] 1 0 1 1 1 1 1 [0] 1 1 0

Köşeli parantezler gönderenin eklediği, alıcının atacağı bitler. Şişme en kötü durumda %20’de kalıyor; bit doldurmanın bayt doldurmadan üstün olduğu yer burası.

Physical layer ihlali. Dördüncüsü Ethernet’in kullandığı yol. Hat kodlaması bazı sinyal desenlerini veri için kullanmıyorsa, o kullanılmayan desen sınır işareti olur. Veri içinde geçmesi fiziksel olarak imkânsız olduğu için doldurmaya hiç gerek kalmıyor. 53. bölümde blok kodlamaya indiğimizde göreceksin: 4B/5B, 32 desenden yalnızca 16’sını veriye ayırıyor ve artan desenlerin bir kısmı bunun için duruyor.

Ethernet aslında üç yöntemi birden kullanıyor. Önsöz ile frame başlangıç sınırlayıcısı başlangıcı işaretliyor, uzunluk alanı ile taşıyıcının kesilmesi sonu; frame’ler arası boşluk da iki frame’in birbirine karışmamasını sağlıyor.

Hata sezme bitlerini de gönderen taraftaki denetleyici koyuyor. Alan taraftaki denetleyici aynı bitleri denetliyor. İki uçtaki yonga, işletim sistemine hiç sormadan anlaşıyor.

Yazılımın devreye girdiği tek nokta alış tarafında. Kart bir frame aldığında işlemciyi kesiyor. Kesmeye yanıt veren sürücü yazılımı hata durumlarını ele alıyor ve datagramı network layer’a yukarı veriyor. Donanımın bittiği çizgi orası.

Frame’in üstündeki adres de kartın kendi adresi ve kart bu kimliği üstündeki ROM’da taşıyor. Kartın hem birinci hem ikinci katmanın aygıtı sayılması bu yüzden: sinyali o üretiyor, frame’in adresini de o taşıyor. Bu adresin nasıl kurulduğunu, yani MAC adresinin biçimini 23. bölümde tek tek açacağız.

Kernel işi karta nasıl devrediyor?

Paket stream’i interface’e girip çıkarken doğrudan bellek erişimiyle yönetiliyor; kısaltması DMA (Direct Memory Access). Kart ana belleği kendisi okuyup yazıyor. Kopyalama işini CPU yapmıyor.

İkisinin buluştuğu yer bir halka tampon. Halka, sabit sayıda tanımlayıcıdan oluşan bir dizi. Her tanımlayıcı bellekteki bir paket tamponunun adresini ve o tamponun kime ait olduğunu taşıyor. Kernel sıradaki boş tanımlayıcıyı dolduruyor ve sahipliği karta bırakıyor. Kart sırası gelince tanımlayıcıyı okuyor, veriyi DMA ile çekiyor, işi bitince sahipliği geri veriyor.

Tanımlayıcının kart ile kernel arasında nasıl el değiştirdiğini izleyelim:

Kernel ile kartın paylaştığı gönderme halkası
kernel · sürücüağ kartı · link denetleyicisiframe'i kuran ve hatayı sezen yongapaket tamponuana bellek · gönderme halkasıdoludoludoluboştanımlayıcıDMAtelekesme
Halka ikisinin ortasında. Halka ana bellekte duruyor ve iki tarafın da eriştiği tek yer orası. Her tanımlayıcı bir paket tamponunun adresini ve o tamponun kime ait olduğunu taşıyor.
  1. Halka ikisinin ortasında. Halka ana bellekte duruyor ve iki tarafın da eriştiği tek yer orası. Her tanımlayıcı bir paket tamponunun adresini ve o tamponun kime ait olduğunu taşıyor.
  2. Kernel tanımlayıcıyı yazar. Kernel sıradaki boş girişi dolduruyor ve sahiplik bitini karta çeviriyor. Devretme bundan ibaret: paketin kendisi kopyalanmıyor, yalnızca adresi yazılıyor.
  3. Kart sırayı kendisi okur. Kart, sırası gelen tanımlayıcıyı ana bellekten kendisi okuyor. İşletim sistemine sorulmuyor, çünkü halkanın hangi girişinde olduğunu kart da sayıyor.
  4. Veriyi kart çeker. Paket, tanımlayıcının gösterdiği tampondan doğrudan bellek erişimiyle alınıyor. Kopyalamayı CPU yapmıyor; veri ana bellekten kartın tamponuna gidiyor.
  5. Frame çıkar, kesme döner. Denetleyici frame'i kurup tele veriyor ve sahipliği kernel'a iade ediyor. Kesme en sonda geliyor; birleştirme açıksa tek kesme birden çok girişi kapatıyor.

Halkanın derinliği kartlarda tipik olarak 256 ile 4.096 tanımlayıcı arasında. En küçük frame’lerle tam yükte, saniyede bir gigabit taşıyan bir hatta 256 girişli alma halkası 172 µs’de doluyor. Derinlik bellek gibi görünüyor ama kernel’a tanınan süreyi ölçüyor.

Süre yetmezse ne oluyor? Kuyruğa alınmış paketleri tutacak bellek dolduğunda gelen paket düşüyor. Kayıp orada oluyor, kablonun ortasında bir yerde değil.

Halkanın öbür ucundaki kesme de bedava değil. Saniyede bir gigabit taşıyan bir hatta en küçük frame 64 bayt, ama telde 84 bayt yer kaplıyor. Yanına 7 baytlık önsöz, 1 baytlık ayraç ve 12 baytlık frame’ler arası boşluk ekleniyor. Toplamı 672 bit eder. Tam yükte saniyede 1.488.095 frame geçiyor. Her frame için bir kesme, saniyede 1,49 milyon kesme demek. Tek bir işlemci çekirdeği zamanının çoğunu yalnızca kesmeye cevap vermekle geçirirdi.

Kartlar bu yüzden kesme birleştirme yapıyor: sürücü ya da kart, işlemciyi kesmeden önce birkaç frame biriktiriyor. 32 frame’de bir kesme verildiğinde aynı yük saniyede 46.503 kesmeye iniyor. Frame’ler yine aynı halkada birikiyor. Değişen tek şey, kernel’ın kaç kez rahatsız edildiği.

Bedeli de aynı bölme işleminden çıkıyor. 32 frame’de bir kesme veren kart, gruptaki ilk frame’i en kötü durumda 31 frame süresi bekletiyor. Boş bir hatta durum daha kötü: grup hiç dolmazsa kesme de hiç gelmiyor. Yalnızca frame sayan bir politika bu yüzden tek başına kullanılamıyor.

Kartlar ikinci bir politika daha taşıyor. İlk frame halkaya düştüğü anda bir zamanlayıcı başlıyor ve süre dolunca kesme veriliyor, grup dolsun dolmasın. ethtool -c eth0 çıktısında yan yana duran iki ayar bunlar: biri frame sayıyor, biri mikrosaniye. 200 µs’ye ayarlanmış bir zamanlayıcı, boş bir hatta gelen tek frame’e 0,2 ms’ye kadar gecikme ekliyor; aynı ayar tam yükte gecikmeyi düşürüyor, çünkü işlemci kesme işlemekten kurtulunca kuyruklar daha çabuk boşalıyor. Ayarın işareti yüke bağlı.

Linux bunun üstüne bir adım daha atıyor. Yük yükseldiğinde kesmeleri tümden kapatıp halkayı kendisi yokluyor ve bir turda onlarca frame topluyor; yük düşünce kesmelere geri dönüyor. Bu karma düzenin adı NAPI. Kesme, trafik seyrekken tepki hızı veriyor; yoklama, trafik yoğunken verim.

Darboğaz gerçekten kartta mı?

Her Ethernet interface yongası, desteklediği ortamın tam frame hızında gönderip alabiliyor. Darboğaz yongada değil.

Toplam başarımı dört şey belirliyor. İşlemci gücü, işlemci ile kart arasındaki iç sinyal yolunun hızı, kart üstündeki tampon bellek miktarı ve sürücünün kalitesi. Dördü de Ethernet standardının dışında kalıyor. Makine yetişemezse frame’ler interface’te düşürülüyor ya da yok sayılıyor; standart bunu kusur saymıyor. Sebebi açık. Standart bir bilgisayarın ne kadar hızlı olacağını tanımlamaya çalışmıyor.

Sayılar farkı gösteriyor. Az önce saydığımız 1.488.095 frame’lik tavan en küçük frame’lere aitti. Aynı hatta en büyük frame’lerle tavan saniyede 81.274 frame’e iniyor. Frame sayısı on sekiz kat azalıyor, taşınan veri artıyor.

Bir frame’in telde ne kadar durduğu tek bir bölmeden çıkıyor. L bitlik bir paketi R bit/s hızındaki bir hatta itmek L/R saniye sürüyor. 1.518 baytlık bir frame için bu, gigabitlik hatta 12,1 µs. On kat hızlı bir hatta aynı iş 1,21 µs’ye iniyor. 2. bölümde gecikme bileşenlerini ayırırken buna iletim gecikmesi demiştik.

Rakamların ucu bugün bile açık. On gigabitlik bir kanalın tam frame hızına piyasadaki masaüstü ve sunucuların bir kısmı hâlâ yetişemiyor.

Bu yüzden bazı üreticiler üst katman protokol işlemesini kartın üstünde yapan interface’ler satıyor. Boşaltma motorlarının (offload) çıkış noktası bu. Somut bir örnek, TCP segmentasyon boşaltması (TSO): kernel karta 65.535 baytlık tek bir tampon veriyor, kart onu 1.460 baytlık parçalara bölüyor. 44 tam parça ve 1.295 baytlık bir artık çıkıyor, toplam 45 parça. Yazılımın 45 kez yapacağı iş bir kez yapılıyor.

Kendi makinende bakmak istersen Linux’ta ethtool bu işin aracı.

ethtool eth0
ethtool -g eth0
ethtool -c eth0
ethtool -k eth0
ip -s link show eth0

İlk komut interface’in hızını ve çalıştığı kipi yazıyor. İkincisi halka tamponunun azami ve o anki derinliğini, üçüncüsü kesme birleştirme ayarlarını, dördüncüsü açık olan boşaltma özelliklerini döküyor. Sonuncudaki düşen frame sayacı sıfırdan büyükse bu çoğu zaman makinenin kartın hızına yetişemediğini gösteriyor.

İlk satırdaki kip de kendi başına bir başarım ayarı. Bir hattın verinin hangi yönde ve ne zaman akabileceğine dair üç seçeneği var ve üçünün de adı var:

kipveri yönüörnek
tek yönlü (simplex)yalnızca tek yön, hiç dönüş yokradyo yayını, klavyeden bilgisayara
yarım çift yönlü (half duplex)iki yön de mümkün ama aynı anda değiltelsiz, hub’a bağlı Ethernet
tam çift yönlü (full duplex)iki yön aynı andaswitch’e bağlı Ethernet, telefon

Ortadaki kip ile alttaki arasındaki fark yalnızca hız değil. Yarım çift yönlü bir hatta iki taraf aynı anda konuşmaya kalkabildiği için collision diye bir olasılık vardır ve o olasılığı yönetecek bir kurala ihtiyaç duyulur. Tam çift yönlü hatta böyle bir kural gerekmez, çünkü gönderme ve alma ayrı yollarda yürür.

Tam çift yönlü çalışmanın iki koşulu var: ortamın aynı anda işleyen ayrı gönderme ve alma yolları olması ve hatta yalnızca iki istasyon bulunması. Koşullar sağlanınca collision diye bir olasılık kalmıyor. Kip 1997’de standartlaştı ve bugün bağlantıların neredeyse tamamı böyle çalışıyor. Hızı ve kipi seçen şey Auto-Negotiation, yani iki cihazın da desteklediği en yükseğini kendiliğinden bulan protokol.

Bir arıza tam burada saklanıyor. Hattın yalnızca bir ucunda Auto-Negotiation açıksa, uzlaşmaya çalışan taraf yarım çift yönlü kipe düşüyor. Diğer uç elle tam çift yönlüye sabitlenmişse kip uyuşmazlığı kaçınılmaz oluyor. Bu arıza sıradan web trafiğinde hiç görünmüyor. Bandı gerçekten dolduran bir başarım testinde ortaya çıkıyor.

Özet

  • Ağ kartı iki katmanı birden gerçekliyor: data link layer ile physical layer kartın üstünde, geri kalan her şey yazılımda; yığının donanımla buluştuğu çizgi orası.
  • Frame’i denetleyici yonga kuruyor: framing, hatta erişim ve hata sezme donanımda bitiyor ve ana işlemciye hiç uğramıyor.
  • Halka tampon ile DMA işi devrediyor: kernel tanımlayıcıyı dolduruyor, kart veriyi bellekten kendisi çekiyor; halkanın derinliği de aslında kernel’a tanınan süredir.
  • Kesme birleştirme çekirdeği kurtarıyor: frame başına bir kesme tam yükte ulaşılamaz bir sayıya çıktığı için kart birkaç frame’i biriktirip tek kesme veriyor.

Kart hazır. Halkayı okuyor, frame’i kuruyor, hatayı donanımda seziyor. Ama frame’in üstünde iki alan hâlâ boş duruyor. Kart oraya kimin adını yazacak?

23. bölüme devam et: Fiziksel Adresleme