rtnetlink rtattr Attribute'larını Iterate Etme

Bir NETLINK_ROUTE soketinden RTM_NEWLINK (veya herhangi bir rtnetlink yanıtı) mesajı aldığında, sabit header’ı (link mesajları için struct ifinfomsg, adres mesajları için struct ifaddrmsg vb.) değişken uzunluklu bir route attribute dizisi (struct rtattr) takip eder.

Her rtattr, 16-bit rta_type (IFLA_IFNAME veya IFLA_MTU gibi protokole özgü bir sabit) ve uzunluğu rta_len ile belirtilen bir payload taşır. Attribute’ların boyutları hepsi aynı değildir, bu yüzden kernel’in sağladığı makrolarla tek tek gezmen gerekir.

Iterate etme deseni

Standart deyim, <linux/rtnetlink.h>‘dan üç makro etrafında kurulu bir for döngüsü:

  • RTA_OK(rta, remaining) — remaining bayt hâlâ geçerli bir attribute tuttuğu sürece true döndürür.
  • RTA_NEXT(rta, remaining) — rta‘yı sonraki attribute’a ilerletir ve remaining‘i azaltır.
  • RTA_DATA(rta) / RTA_PAYLOAD(rta) — attribute’un payload baytlarına ve uzunluğuna erişir.

Attribute’lar sabit mesaj header’ının hemen ardından başlar. Link mesajları için kernel IFLA_RTA(ifi) verir (NLMSG_DATA(nlh) + sizeof(ifinfomsg)‘in tipli cast’i) ve kalan baytlar için IFLA_PAYLOAD(nlh); adres mesajları için eşdeğerleri IFA_RTA(ifa) ve IFA_PAYLOAD(nlh)‘dir.

Kısmi örnek

attr_len‘in iç for‘un dışında bildirildiğine ve RTA_NEXT tarafından yerinde değiştirildiğine dikkat et — bir döngü sayacı değil, attribute bloğundaki kalan baytları izler. Döngü header’ında bildirmek veya ikinci bir değişkene kopyalamak iterasyonu bozar.

Tipli payload’ları okuma

RTA_DATA(rta) void* döndürür; kernel’in o rta_type için belgelediği türe cast edersin. Link attribute’ları için yaygın durumlar:

rta_typePayload türüNotlar
IFLA_IFNAMEchar[]NUL-sonlandırmalı arayüz adı
IFLA_MTUuint32_t
IFLA_ADDRESSunsigned char[6]L2 adresi; uzunluk RTA_PAYLOAD(rta)
IFLA_OPERSTATEuint8_tIF_OPER_* değeri
IFLA_STATS64struct rtnl_link_stats64

IFLA_ADDRESS gibi değişken uzunluklu payload’ları okumadan önce her zaman RTA_PAYLOAD(rta)‘yı kontrol et — uzunluk link türüne bağlıdır (Ethernet 6 bayt, ama diğer link katmanları farklıdır).

İç içe attribute’lar

Bazı attribute’lar (ör. IFLA_LINKINFO) kendileri konteynerdir: payload’ları başka bir rtattr dizisidir. RTA_DATA(rta)‘yı yeni bir attribute bloğunun başlangıcı, RTA_PAYLOAD(rta)‘yı da uzunluğu olarak değerlendirip recurslarsın:

Aynı RTA_OK / RTA_NEXT çifti her iç içe seviyeyi yönetir — değişen yalnızca başlangıç pointer’ı ve uzunluktur.

Ayrıca bu deyimi kullanarak tüm link attribute’larını dump’layan tam bir program için rtnetlink API ile tüm ağ linklerini listeleme, fiziksel kablolu NIC’leri filtreleme için rtnetlink ile fiziksel ethernet linklerini filtreleme ve VLAN arayüzlerini filtreleme için rtnetlink ile VLAN arayüzlerini filtreleme yazılarına bak.


Check out similar posts by category: C/C++ Linux