Ortamımda, VoIP trafiğinin WAN’a ulaşmadan önce gerektiği şekilde ele alınmasını sağlamak için Linux tc’ye güveniyorum. Doğru işaretleme ve kuyruk yapılandırması olmadan, ses paketleri büyük veri akışlarıyla rekabet eder ve bu da gecikmeyi artırır, aramaları kesintiye uğratır. Burada, giden arayüzde DSCP EF işaretleme ve öncelik kuyruklamasını nasıl yapılandırdığımı paylaşıyorum; böylece ses akışı sorunsuz kalır.
DSCP EF’nin VoIP için Önemi Nedir?
VoIP, yeniden iletim mekanizması olmayan UDP üzerinden çalışır. Küçük miktarda gecikme veya kayıp bile kaliteyi ciddi şekilde düşürür. DSCP EF (Expedited Forwarding) kod noktası (0b101110), ağ cihazlarına bu paketlerin düşük gecikmeli ve yüksek öncelikli trafik olarak ele alınmasını söyler. Ben bu paketleri kaynakta işaretlerim; böylece downstream yönlendiriciler ve switchler derin paket incelemesi yapmadan bu etiketi saygı gösterir.
tc filter ile VoIP Trafiğini İşaretleme
İlk olarak, VoIP trafiğini portlara göre tanımlıyorum. Kurulumumda, SIP sinyali 5060/5061 portlarını kullanırken, RTP medyası 10000-20000 UDP aralığında değişir. Bu eşleşmeleri yapıp DSCP alanını ayarlamak için bir tc filter oluşturuyorum:
# eth0 üzerindeki mevcut qdisc’i temizle (kendi arayüzün için ayarla)
tc qdisc del dev eth0 root 2>/dev/null || true
# Varsayılan sınıf ile root HTB oluştur
tc qdisc add dev eth0 root handle 1: htb default 30
# VoIP için sınıf ekle (%10 garanti, tavan %100)
tc class add dev eth0 parent 1: classid 1:10 htb rate 1mbit ceil 100mbit
# Diğer tüm trafik için bulk sınıf ekle
tc class add dev eth0 parent 1: classid 1:30 htb rate 4mbit ceil 100mbit
# VoIP paketlerini DSCP EF (0x2e) ile işaretle ve VoIP sınıfına yönlendir
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \
match ip dport 5060 0xffff flowid 1:10 \
action pedit munge ip dscp set 0x2e
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \
match ip dport 5061 0xffff flowid 1:10 \
action pedit munge ip dscp set 0x2e
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \
match ip sport 5060 0xffff flowid 1:10 \
action pedit munge ip dscp set 0x2e
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \
match ip sport 5061 0xffff flowid 1:10 \
action pedit munge ip dscp set 0x2e
# RTP medya aralığı (örnek: 10000-20000)
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \
match ip dport 10000 0xfc00 flowid 1:10 \
action pedit munge ip dscp set 0x2e
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 \
match ip sport 10000 0xfc00 flowid 1:10 \
action pedit munge ip dscp set 0x2e
Bu filtre, eşleşen paketleri DSCP EF ile işaretleyip VoIP sınıfına (1:10) yönlendirir. HTB zamanlayıcısı bu sınıfa garantili 1 Mbps verir ancak bant genişliği boşsa hat hızıyla patlama yapmasına izin verir.
İşaretlemeyi Doğrulama
DSCP alanının doğru şekilde ayarlandığını kontrol etmek için tcpdump kullanıyorum. IP başlığındaki ToS baytında 0x2e değerini arıyorum:
tcpdump -i eth0 -nn -vvv 'udp portrange 10000-20000 or port 5060 or port 5061' -c 5
Örnek çıktı şu şekilde görünür:
IP (tos 0x2e, ect 0), ttl 64, id 12345, offset 0, flags [none], proto UDP (17), length 200
10.0.0.5.12345 > 10.0.0.10.5060: UDP, length 172
tos 0x2e kısmı EF işaretlemesini onaylar. Bu değeri görmüyorsanız, filtre sırasını ve sözdizimini kontrol edin—tc filtreleri sırasıyla değerlendirilir ve yanlış yerleştirilmiş default sınıfı trafiği çalabilir.
HTB ve pfifo_fast ile Önceliklendirme
İşaretleme downstream yönlendiriciler için faydalı olsa da, yerel kuyruklama tx ring’in dolmasını ve paket düşürülmesini önlemek için gereklidir. Ben HTB ile pfifo_fast yaprağı kullanırım (varsayılan) fakat txqueuelen’i aşırı gecikmeye yol açmadan patlamaları absorbe edecek şekilde ayarlarım:
# Tx kuyruk uzunluğunu patlamaları absorbe edecek şekilde ayarla (varsayılan genellikle 1000)
ip link set dev eth0 txqueuelen 2000
# Mevcut qdisc istatistiklerini göster
tc -s qdisc show dev eth0
Çıktı şöyle görünür:
qdisc htb 1: root refcnt 2 r2q 10 default 30 direct_packets 1234
Sent 567890 bytes 1234 pkt (dropped 0, overlimits 0)
qdisc pfifo_fast 10: parent 1:10 limit 1000p packets 1234 bytes 567890 lost 0
qdisc pfifo_fast 30: parent 1:30 limit 1000p packets 9876 bytes 432100 lost 2
VoIP sınıfı (1:10)’nda düşürülen paket sıfırken, bulk sınıfı (1:30)’nda bazı kayıp gözlemlenebiliyor—bu da şekillendirme işinin doğru çalıştığını gösterir.
Gecikme ve Kaybı İzleme
Bu yapılandırmayı pasif izlemeyle birleştiriyorum. tc -s class show komutu gerçek zamanlı istatistikler sunar:
watch -n 1 'tc -s class show dev eth0'
VoIP sınıfındaki delayed veya overlimits sayaçlarının artışını izleyin; eğer artıyorsa, rate veya ceil değeri belİki düşük olabilir. Gerçek arama hacmine göre ayarlama yapın; tipik bir G.711 araması ~87 kbps gerektirir, bu yüzden 1 Mbps baş başına ~10 eşzamanlı aramayı destekleyebilir ve başta boşluk bırakır.
Yaygın Hatalar
- Giriş trafiğini unutmak: Bu yapılandırma sadece giden trafiği işaretler. VoIP sunucunuz çağrı alıyorsa, gelen medyayı önceliklendirmek için giriş arayüzlerinde eşleşen kurallar da olmalı.
- Aşırı şekillendirme:
ratedeğeri çok düşükse, bağlantı boşsa bile VoIP açlık çeker. Patlama izni vermek içinceilkullanın. - VLANları göz ardı etmek: Eğer eth0.100 üzerinden VoIP gidiyorsa, qdisc’i fiziksel eth0 değil VLAN alt arayüzüne uygulayın.
Son Notlar
Bu deseni, Asterisk ve Kamailio kurulumları çalıştıran Proxmox konaklarında kullanıyorum. Hafif, çekirdek yaması gerektirmez ve var olan DSCP duyarlı ağlarla entegre çalışır. WAN koşullarını simüle ederek bu yapılandırmayı test etmek için [netem ile gecikme ekleme](https://furkanikkan.com/urun/linux-tc-netem-kullanarak-gercekci-wan-simulasyonu-icin-jitter-ekleme-126) konulu yazıma da bakabilirsiniz.
Yapılandırıldıktan sonra, MOS skorlarını veya çağrı günlüklerini izleyin—yoğun veri transferleri sırasında da tek yönlü ses şikayetleri azalmalı ve konuşmalar daha stabil olmalıdır.
Kapak görseli: Unknown · CC0 (Openverse / kamu malı) · https://www.rawpixel.com/image/6038427/photo-image-public-domain-technology-line
