###### tags: `Networking`
# TC (Traffic Control)
Overview 介紹 tc 的功能和目的,不詳細解釋 tc 內部的元件或實作,改編自 Criteo 的文章。[^1]
## Overview[^1][^2]
網路跟其他電腦元件如 CPU, RAM 一樣都是一項資源,CPU 由排程器達成分時多工,讓不同應用使用 CPU 資源,而網路在 Linux 中是由 tc 子系統管理,tc 架構中包含了一系列的演算法,可以讓使用者調整網路流量、延遲、抖動等。使用情境例如
- 保留 1Gpbs 頻寬給 HTTP (*traffic classification)*
- 給予 DNS 封包流量優先權 (*prioritization*)
- 限制 brust size (*rate shaping*)
tc 可以處理出境 (egress) 和入境 (ingress) 的封包,以下圖為 engress 的示意圖,可以看到 queueing discipline (qdisc) 夾在 IP stack 和 driver queue 中間,qdisc 是 tc 最重要的功能,當 IP stack 產生封包時 (可能是來自本機的應用程式或來自其他網路界面) 會經過 qdisc 這個物件,由 qdisc 做上述三種類型的網路流量管理,最後把封包放到 driver queue 再由 NIC 傳輸。
<!--  -->

### Element of Traffic Control
#### 1. Classification
網路流量管理的一的最基本的功能是要能夠分類以及過濾封包,包括入境及出境,藉由讀取通訊協定的表頭 (如 IP, TCP Header) 或封包內容 (如 HTTP),決定要對這個封包採取什麼樣的動作。在 tc 裡已經有相當多現成的 filter 工具可以直接使用,也可以自己編寫一個 eBPF 程式做更細緻的分類。
以下為一個 Classification 的示意圖,封包經過一個 filter 決定要採取哪個 Policy

:::info
近年來因為網路頻寬的升高,也增加了高速過濾封包的需求,現在某些 SmartNIC 可以做 Hardware offloading,意思是把原本過濾封包的 eBPF 程式,轉譯成網卡可執行的指令,直接在硬體上執行。得益於網卡的硬體加速,netronome 的網卡一秒可以過濾近六千萬個封包 (60Mpp/s)!
https://www.netronome.com/blog/bpf-ebpf-xdp-and-bpfilter-what-are-these-things-and-what-do-they-mean-enterprise/
:::
#### 2. Scheduling
## TC Objects[^3]
以下講解 tc 的主要元件,包括 qdics, class, filter, policy。
1. qdisc (Queueing Discipline)
2. class
3. filter, policy (有些書上會寫 classifier, action)
### qdics
來使用看看 qdics 囉,以下命令會把一個 qdics 加到 eno2 上
```bash
tc qdisc add dev eno2 root pfifo_fast
```
來看看 `tc qdisc show` 輸出什麼
```
❯ tc qdisc show
qdisc pfifo_fast 8002: dev eno2 root refcnt 5 bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
...
```
先解釋一下
qdisc pfifo_fast 8001: This indicates that the qdisc attached is a pfifo_fast, which stands for Priority FIFO (First In, First Out). The number 8001 is the handle identifier for this qdisc.
dev eno2: This indicates that the qdisc is attached to the network interface named eno2.
root: This means the qdisc is attached at the root of the network interface's queuing discipline hierarchy.
refcnt 5: This is the reference count, which indicates how many elements (like classes or filters) are referencing this qdisc.
bands 3: In pfifo_fast, packets are classified into bands (essentially separate queues) according to their Type of Service (ToS) Priority. This indicates that there are 3 bands or queues. By default, pfifo_fast has three bands: 0, 1, and 2.
priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1: This is a map that indicates how incoming packets should be prioritized. The values are indices to the bands. Each number in the priomap corresponds to a different Linux internal packet priority. These range from 0 to 15, and the mapping assigns each of these priorities to a band (0, 1, or 2).
## Functions
### Add a Filter
filter 只能加到 qdisc,要加到 class 必須先有 qdisc
filters are: per interface + per qdisc + per protocal (+ per priority)
```
# tc filter add dev eth0 parent 100: protocal ipv6 matchall \
action drop
```
命令解釋:
- matchall 為 filter 的名稱,會匹配所有封包
- matchall 之前的 protocal 代表要匹配的協議,是由 tc 架構提供的過濾功能
### Network Emulation (netem)
netem 可以模擬真實網路會遇到各種狀況
[^1]: Demystification of TC:
https://medium.com/criteo-labs/demystification-of-tc-de3dfe4067c2
[^2]: Queueing in the Linux Network Stack
https://www.linuxjournal.com/content/queueing-linux-network-stack
[^3]: Linux Network Traffic - Implementation Overview https://www.almesberger.net/cv/papers/tcio8.pdf