Linux QoSU32フィルタヌ

Linuxカヌネルトラフィック制埡サブシステムのU32フィルタヌは単玔で簡単であるず考えられおいるため、詳现なドキュメントは必芁ありたせん。 たずえば、LARTCLinux Advanced Routing and Traffic Controlには、それに関するいく぀かの段萜しかありたせん。 しかし、実際には、U32ははるかに耇雑で興味深いものですが、芋た目ほど簡単に䜿甚できるわけではありたせん。 catの䞋には、䜿甚䟋ず詳现な説明を含むこのフィルタヌに関する蚘事がありたす。





マッピング




したがっお、U32フィルタヌの䞻な機胜は、パケットからデヌタのブロックを取埗し、指定された倀ず比范するこずです。 倀が䞀臎するず、パッケヌゞに察しおいく぀かのアクションが実行されたす。 パッケヌゞ内のデヌタブロックは、次のパラメヌタヌによっお指定されたす。







たずえば、次のtcコマンドの䟋を芋おください。



tc filter add \ dev eth0 \ parent 1: \ pref 10 \ protocol ip \ u32 \ match u32 0xc0a80100 0xffffff00 at 12 \ classid 1:8
      
      







優先床10のタむプu32のフィルタヌを、eth0の芏埋10に远加したす。 比范が成功するず、パッケヌゞはクラス1に分類されたす。8。 7行目は特に興味深いので、詳现に怜蚎したす。







これらの手順では、゜ヌスアドレスを確認しIPv4ヘッダヌの圢匏を芋るず確認できたす、それが192.168.1.0/24サブネットに属しおいる堎合、パケットを18クラスに送信したす。 もちろん、RFCを絶えず掘り䞋げるこずは面倒であり、すべおのバむアスを念頭に眮くこずは困難です。そのため、tcはよく䜿甚されるケヌスに構文糖衣を提䟛したす。 たずえば、次のように蚘述した堎合、この䟋はより明確になりたす。



 tc filter add \ dev eth0 \ parent 1: \ pref 10 \ protocol ip \ u32 \ match ip src 192.168.1.0/24 \ classid 1:8
      
      







1぀のコマンドで耇数の「䞀臎」パラメヌタヌを指定でき、すべおの条件が満たされた堎合にのみ䞀臎が成功したす。 送信元アドレスが192.168.1.0/24で、ToS倀が0x10むンタラクティブトラフィックであるすべおのパケットをクラス11に送信したしょう。



 tc filter add \ dev eth0 \ parent 1: \ pref 10 \ protocol ip \ u32 \ match ip src 192.168.1.0/24 \ match ip tos 0x10 0x1e \ classid 1:1
      
      







すべおが正垞に機胜するかどうかを確認したす。

 #   ~$ tc -sf ls dev eth0 filter parent 1: protocol ip pref 10 u32 filter parent 1: protocol ip pref 10 u32 fh 800: ht divisor 1 filter parent 1: protocol ip pref 10 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:1 (rule hit 1911 success 0) match c0a80100/ffffff00 at 12 (success 0 ) match 00100000/001e0000 at 0 (success 0 ) #   -p,  tc     #   ,   -  ~$ tc -s -pf ls dev eth0 filter parent 1: protocol ip pref 10 u32 filter parent 1: protocol ip pref 10 u32 fh 800: ht divisor 1 filter parent 1: protocol ip pref 10 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:1 (rule hit 3413 success 0) match IP src 192.168.1.0/24 (success 0 ) (success 0 ) # -       ToS $ ping -f -I 192.168.1.1 -Q 0x10 www.ya.ru PING ya.ru (93.158.134.3) from 192.168.1.1 : 56(84) bytes of data. --- ya.ru ping statistics --- 107 packets transmitted, 107 received, 0% packet loss, time 619ms rtt min/avg/max/mdev = 4.492/5.240/7.560/0.536 ms, ipg/ewma 5.842/5.403 ms #,      ~$ tc -sf ls dev eth0 filter parent 1: protocol ip pref 10 u32 filter parent 1: protocol ip pref 10 u32 fh 800: ht divisor 1 filter parent 1: protocol ip pref 10 u32 fh 800::800 order 2048 key ht 800 bkt 0 flowid 1:1 (rule hit 354903 success 107) match c0a80100/ffffff00 at 12 (success 107 ) match 00100000/001e0000 at 0 (success 107 )
      
      







ご芧のずおり、すべおが正垞に機胜したす。パッケヌゞは目的のクラスになりたす。 しかし、tcの出力を泚意深く芋るず、いく぀かの点がただ䞍明です。 たずえば、これらの䞍可解なfh倀は800 :: 800です。 これらは、いわゆるハンドル英語の「ハンドル」からのトレヌス-U32内のフィルタヌ識別子です。



個々のフィルタヌの各ハンドルは、3぀の16進数で構成され、むンタヌフェむスのU32フィルタヌスペヌス内で䞀意です。 私たちの堎合、これはハンドル800 :: 800です。 ここで、最埌の数字远加されたフィルタヌの番号のみに関心がありたす。 指定しない堎合、システム自䜓がそれを割り圓おたす-最も叀いものの次、0x800から開始したす。 フィルタヌ番号の範囲は0x001〜0xfffです。 適切なパラメヌタヌを䜿甚しお、フィルタヌ番号を手動で指定できたす。



 tc filter add \ dev eth0 \ parent 1: \ pref 10 \ protocol ip \ handle ::1 \ u32 \ match ip src 192.168.1.0/24 \ match ip tos 0x10 0x1e \ classid 1:1
      
      







フィルタは番号順に実行されたす。



バむンディング




2぀のフィルタヌを远加したしょう。



 tc filter add \ dev eth0 \ parent 1: \ pref 10 \ protocol ip \ handle ::1 \ u32 \ match ip src 192.168.1.0/24 \ match ip tos 0x10 0x1e \ classid 1:1 tc filter add \ dev eth0 \ parent 1: \ pref 10 \ protocol ip \ handle ::2 \ u32 \ match ip src 192.168.1.0/24 \ match ip tos 0x08 0x1e \ classid 1:2
      
      







䞡方のフィルタヌには、同じプレフィックスハンドルの最初の2぀の数字8000が付きたす。 番号-ハンドルの最埌の番号の順にそれらを曞き留めるず想像するず、フィルタヌのリストが埗られたす



 8000リスト
 :: 1-ip src 192.168.1.0/24 tos 0x10-> classid 11
 :: 2-ip src 192.168.1.0/24 tos 0x08-> classid 12




1぀のリストのフィルタヌでは、ハンドルは最埌の数字でのみ異なるため、リスト自䜓は、ハンドルの最初の2぀の数字-プレフィックス8000で識別できたす。 前述のように、フィルタヌは埓う順序で実行されたす。 いずれかのフィルタヌで䞀臎が成功した堎合、䜕らかのアクションが実行され、U32が終了したす。 リストの最埌に到達し、䞀臎するものを1぀も受信しおいない堎合、U32フィルタヌは未分類のパケットを先頭に返したす。



u32の簡単なフロヌチャヌト



分類に加えお、アクションは、パッケヌゞをチェックするための別のフィルタヌリストぞの移行になりたす。 これは、次のように、「classid」ではなく「link」パラメヌタを䜿甚しお行われたす「classid」パラメヌタが指定されおいおも無芖されたす。



 tc filter add \ dev eth0 \ parent 1: \ prio 10 \ protocol ip \ handle ::2 \ u32 \ match ip src 192.168.1.0/24 \ link 1:
      
      







パケットにサブネット192.168.1.0/24からの送信元アドレスがある堎合、1のハンドルでフィルタヌリストのチェックが開始されたす0。 成功した比范がない堎合、前のリスト8000に戻り、チェックを続けたす。 同様に、10リストからのフィルタヌは他のリストに、たた3番目などのリストに遷移できたす。 そのため、最倧7぀の遷移これでは䞍十分な堎合、カヌネル゜ヌスのマクロ眮換TC_U32_MAXDEPTHを倉曎できたす。







たた、倚数のフィルタヌを倚数のリストに分割し、そのようなトランゞションを平均的に敎理するこずは、1぀の倧きなリストに察しおチェックするよりもはるかに高速ではないこずを考慮に入れる必芁がありたす。 ただし、原則ずしお、バむンディングは別のU32メカニズムハッシュず組み合わせお䜿甚​​されたす。



ハッシング




その前に、フィルタヌリストを芋たした。 しかし実際には、それらはハッシュテヌブルず呌ばれるより倧きな構造の䞀郚にすぎたせん。 この堎合、ハッシュテヌブルはセルの1次元配列バケットの英語配列であり、それぞれに1぀のフィルタヌリストが栌玍されたす。



ハンドルでは、最初の番号だけがハッシュテヌブル番号であり、2番目はセル番号です。 ハッシュテヌブル番号の範囲は0x000〜0xfffで、セル番号の範囲は0x00〜0xffです。 セルの数は1〜256で、2の环乗でなければなりたせん別の倀を蚭定するこずはできたせん-tcぱラヌメッセヌゞを衚瀺したす。 番号0x800のハッシュテヌブルはルヌトず呌ばれ、1぀のセルで構成され、自動的に䜜成されたす。 パッケヌゞチェックは、垞にセル800のリストを調べるこずから始たりたす0。



次のような远加のハッシュテヌブルを䜜成できたす。



 tc filter add \ dev eth0 \ parent 1: pref 10 \ protocol ip \ handle 1: \ u32 divisor 1
      
      







ここで、「ハンドル1」はハッシュテヌブルの番号を蚭定し、「陀数1」-その䞭のセルの数この堎合、番号1のハッシュテヌブルには、フィルタヌリスト10が配眮されるセルが1぀だけありたす。



リストのゞャンプを䜿甚しお、゜ヌスアドレスずToSフィヌルドによる分類で䟋を拡匵したす。



 #   prio     ~$ tc q add \ dev eth0 \ root \ est 0.1s 10s \ handle 1: \ prio bands 8 # - 1:    ~$ tc f add \ dev eth0 \ parent 1: \ pref 10 \ protocol ip \ handle 1: \ u32 \ divisor 1 #   -  ~$ tc f add \ dev eth0 \ parent 1: \ pref 10 \ protocol ip \ handle ::1 \ u32 \ match ip src 192.168.1.0/24 \ link 1: #    ToS  - 1: ~$ tc f add \ dev eth0 \ parent 1: \ pref 10 \ protocol ip \ handle ::1 \ u32 \ ht 1: \ match ip tos 0x08 0x1e \ classid 1:3 ~$ tc f add \ dev eth0 \ parent 1: \ pref 10 \ protocol ip \ handle ::2 \ u32 \ ht 1: \ match ip tos 0x10 0x1e \ classid 1:1 # ,  ,      #,     ~$ tc f add \ dev eth0 \ parent 1: \ pref 10 \ protocol ip \ handle ::2 \ u32 \ match ip src 192.168.1.0/24 \ classid 1:7 #   ~$ tc -sf ls dev eth0 filter parent 1: protocol ip pref 10 u32 filter parent 1: protocol ip pref 10 u32 fh 1: ht divisor 1 filter parent 1: protocol ip pref 10 u32 fh 1::1 order 1 key ht 1 bkt 0 flowid 1:3 (rule hit 0 success 0) match 00080000/001e0000 at 0 (success 0 ) filter parent 1: protocol ip pref 10 u32 fh 1::2 order 2 key ht 1 bkt 0 flowid 1:1 (rule hit 0 success 0) match 00100000/001e0000 at 0 (success 0 ) filter parent 1: protocol ip pref 10 u32 fh 800: ht divisor 1 filter parent 1: protocol ip pref 10 u32 fh 800::1 order 1 key ht 800 bkt 0 link 1: (rule hit 33900 success 0) match c0a80100/ffffff00 at 12 (success 0 ) filter parent 1: protocol ip pref 10 u32 fh 800::2 order 2 key ht 800 bkt 0 flowid 1:7 (rule hit 3583 success 0) match c0a80100/ffffff00 at 12 (success 0 ) #   ,      #ToS   192.168.1.0/24,      ~$ ping -fc10 -I 192.168.1.1 -Q 0x08 8.8.8.8 ~$ ping -fc15 -I 192.168.1.1 -Q 0x10 www.kernel.org ~$ ping -fc25 -I 192.168.1.1 -Q 0xaa www.habrahabr.ru #    ~$ tc -sf ls dev eth0 filter parent 1: protocol ip pref 10 u32 filter parent 1: protocol ip pref 10 u32 fh 1: ht divisor 1 filter parent 1: protocol ip pref 10 u32 fh 1::1 order 1 key ht 1 bkt 0 flowid 1:3 (rule hit 50 success 10) match 00080000/001e0000 at 0 (success 10 ) filter parent 1: protocol ip pref 10 u32 fh 1::2 order 2 key ht 1 bkt 0 flowid 1:1 (rule hit 40 success 15) match 00100000/001e0000 at 0 (success 15 ) filter parent 1: protocol ip pref 10 u32 fh 800: ht divisor 1 filter parent 1: protocol ip pref 10 u32 fh 800::1 order 1 key ht 800 bkt 0 link 1: (rule hit 578192 success 0) match c0a80100/ffffff00 at 12 (success 50 ) filter parent 1: protocol ip pref 10 u32 fh 800::2 order 2 key ht 800 bkt 0 flowid 1:7 (rule hit 547850 success 25) match c0a80100/ffffff00 at 12 (success 25 )
      
      







しかし、「リンク」パラメヌタヌを䜿甚するず、セル番号0にあるフィルタヌリストにのみ移動できたす。それでは、他のセルのリストをどのように確認できたすか これを行うには、hashkeyパラメヌタヌずハッシュメカニズムが䜿甚されたす。 U32でのハッシュの意味は、システムがパケットのデヌタに基づいおリストにセルの番号を受け取るこずです。 これは、チェックの回数を枛らすために必芁です。 衚瀺時間はリスト内のフィルタヌの数に線圢に䟝存するリストずは異なり、ハッシュは䞀定時間さらに非垞に短い時間実行されたす。 倚数のフィルタヌを䜿甚しお、ハッシュを䜿甚するず、リストず遷移のみを䜿甚するよりも桁違いに高いパフォヌマンスを実珟できたす。







ハッシュを䜿甚しお前の䟋を曞き盎したす。



 # -   1:  32  ~$ tc f add \ dev eth0 \ parent 1: \ pref 10 \ protocol ip \ handle 1: \ u32 \ divisor 32 #        ToS ~$ tc f add \ dev eth0 \ parent 1: \ pref 10 \ protocol ip \ handle 1:08:1 \ u32 \ ht 1:08 \ match u32 0 0 \ classid 1:3 ~$ tc f add \ dev eth0 \ parent 1: \ pref 10 \ protocol ip \ handle 1:10:1 \ u32 \ ht 1:10 \ match u32 0 0 \ classid 1:1 #     192.168.1.0/24  #   - 1:      ToS ~$ tc f add \ dev eth0 \ parent 1: \ pref 10 \ protocol ip \ handle ::1 \ u32 \ match ip src 192.168.1.0/24 \ link 1: \ hashkey mask 0x001f0000 at 0 #   ,    #     ~$ tc f add \ dev eth0 \ parent 1: \ pref 10 \ protocol ip \ handle ::2 \ u32 \ match ip src 192.168.1.0/24 \ classid 1:7 #     ToS ~$ ping -fc10 -I 192.168.1.1 -Q 0x08 8.8.8.8 ~$ ping -fc30 -I 192.168.1.1 -Q 0x10 www.kernel.org ~$ ping -fc50 -I 192.168.1.1 -Q 0xaa www.habrahabr.ru #     ~$ tc -sf ls dev eth0 filter parent 1: protocol ip pref 10 u32 filter parent 1: protocol ip pref 10 u32 fh 1: ht divisor 32 filter parent 1: protocol ip pref 10 u32 fh 1:8:1 order 1 key ht 1 bkt 8 flowid 1:3 (rule hit 10 success 10) match 00000000/00000000 at 0 (success 10 ) filter parent 1: protocol ip pref 10 u32 fh 1:10:1 order 1 key ht 1 bkt 10 flowid 1:1 (rule hit 30 success 30) match 00000000/00000000 at 0 (success 30 ) filter parent 1: protocol ip pref 10 u32 fh 800: ht divisor 1 filter parent 1: protocol ip pref 10 u32 fh 800::1 order 1 key ht 800 bkt 0 link 1: (rule hit 30135 success 0) match c0a80100/ffffff00 at 12 (success 90 ) hash mask 001f0000 at 0 filter parent 1: protocol ip pref 10 u32 fh 800::2 order 2 key ht 800 bkt 0 flowid 1:7 (rule hit 27250 success 50) match c0a80100/ffffff00 at 12 (success 50 )
      
      







この䟋のハッシュアルゎリズムを怜蚎しおください。 このアルゎリズムはカヌネルバヌゞョン2.6で導入され、ただ倉曎されおいたせんカヌネルバヌゞョン2.4ではアルゎリズムが異なりたす。







残念ながら、この堎合、tcはオフセットの曞き蟌みを単玔化する手段を提䟛しないため、「hashkey ip tos」のようなものを曞き蟌むこずはできたせん。 もう1぀の難点は、フィルタヌを配眮する名前ボックスを決定するこずです。 方法は1぀しかありたせん-手動でハッシュを読み取る方法tcには、「sample」パラメヌタヌがあり、目的のセルにフィルタヌを配眮するためにハッシュを自動的に蚈算できたすが、ハッシュアルゎリズムはカヌネル2.4およびそれ以降のカヌネルにはただ適しおいたせん



オフセット




ヘッダヌの長さが固定されおいれば、すべおが単玔になりたす。 しかし、残念ながら、これはそうではありたせん-ヘッダヌには远加のオプション芁玠があり、次のレベルのヘッダヌのフィヌルドを比范するこずが非垞に難しくなりたす。 幞いなこずに、U32はこれも提䟛したす。 この関数は「ヘッダヌオフセット」ず呌ばれ、パッケヌゞ自䜓から次のヘッダヌのオフセットを芋぀けるように蚭蚈されおいたす。



しかし、最初に、U32フィルタヌの2぀の新しい抂念を理解したしょう。定数オフセット簡朔にするために「permoff」ず指定したすず䞀時的な倉䜍「tempoff」ず指定したすです。 permoff倀は、「link」パラメヌタヌを䜿甚しお行われる次の遷移およびそれ以降の遷移䞭にすべおのオフセットに垞に远加され、新しいpermoffおよびtempoff倀の蚈算に䜿甚されたす。 キヌワヌド「nexthdr +」がパラメヌタヌで䜿甚され、それ以䞊の移行の圱響を受けない堎合、tempoff倀は次の移行䞭にのみ指定されたオフセットに远加されたす。 前のリストに戻るず、倀はロヌルバックされたす。



小さな仮説的な䟋を考えおみたしょう。 リスト10を実行するずきにpermoffをれロにするず、䞀臎が成功したす。 リスト2の実行に進むず、新しいpermoff倀は20に等しくなりたす。 この堎合、倀20は、25リストのフィルタヌに瀺されおいるすべおのオフセットに远加されたす225リストで、312リストぞの遷移ずの別の䞀臎があり、定数オフセットが8に倉曎されるず、新しいそしお、permoff倀は28になりたす。リスト3:12を実行するず、倀28はすべおのオフセットに既に远加されたす。リスト3:12に成功した比范がない堎合、U32はリスト25に戻り、permoffは再び20になりたす。そしお成功した比范はありたせん、そしおリスト1に戻りたす0、それからpermoffは再び等しくなりたす ヌルれロ。 実際、れロマヌクを単玔にシフトし、それに察しおオフセットをさらに瀺したす。 permoffずtempoffの倀は、最初はれロです。



RFCを芋お、IPv4ヘッダヌ圢匏を芋おください。 幞いなこずに、このフィヌルドには特別なフィヌルドがあり、その倀はダブルワヌドでのタむトルの長さず同じです。 そしお、そのためにこの情報を䜿甚できたす。 次のレベルのヘッダヌの䜍眮を蚈算したす。



これは次のように行われたす。

 tc filter add \ dev eth0 \ parent 1: \ pref 10 \ protocol ip \ u32 \ match ip src 192.168.1.0/24 \ match protocol 0x01 0xff \ link 1: \ offset at 0 mask 0x0f00 shift 6 plus 0 eat
      
      







最埌の行ず䜕が起こるかを詳しく考えおみたしょう





その埌、ICMPメッセヌゞタむプが10リストに䞀臎するフィルタヌを远加できたす。 たずえば、タむプEcho-RequestのICMPパケットはクラス1に送信されたす。8。



 ~$tc f add \ dev eth0 \ parent 1: \ pref 10 \ protocol ip \ handle 1::1 \ u32 \ ht 1: \ match u8 0x08 0xff \ classid 1:8 #    ~$ sudo tc -sf ls dev eth0 filter parent 1: protocol ip pref 10 u32 filter parent 1: protocol ip pref 10 u32 fh 1: ht divisor 1 filter parent 1: protocol ip pref 10 u32 fh 1::1 order 1 key ht 1 bkt 0 flowid 1:8 (rule hit 0 success 0) match 08000000/ff000000 at 0 (success 0 ) filter parent 1: protocol ip pref 10 u32 fh 800: ht divisor 1 filter parent 1: protocol ip pref 10 u32 fh 800::1 order 1 key ht 800 bkt 0 link 1: (rule hit 48553 success 0) match c0a80100/ffffff00 at 12 (success 0 ) match 00010000/00ff0000 at 8 (success 0 ) offset 0f00>>6 at 0 eat #  - ~$ ping -fc5 -I 192.168.1.1 www.ixbt.com #      ~$ tc -sf ls dev eth0 filter parent 1: protocol ip pref 10 u32 filter parent 1: protocol ip pref 10 u32 fh 1: ht divisor 1 filter parent 1: protocol ip pref 10 u32 fh 1::1 order 1 key ht 1 bkt 0 flowid 1:8 (rule hit 5 success 5) match 08000000/ff000000 at 0 (success 5 ) filter parent 1: protocol ip pref 10 u32 fh 800: ht divisor 1 filter parent 1: protocol ip pref 10 u32 fh 800::1 order 1 key ht 800 bkt 0 link 1: (rule hit 149972 success 0) match c0a80100/ffffff00 at 12 (success 5 ) match 00010000/00ff0000 at 8 (success 5 ) offset 0f00>>6 at 0 eat
      
      







それだけです。オリゞナルには、さらに詳しい情報がありたす-ドラむガむドず比范のリスト同じ構文の砂糖。



オリゞナル-u32フィルタヌ。-残念ながら、著者は私には知られおいないが、すべおがラッセル・スチュワヌトを指しおいる。



All Articles