---
# System prepended metadata

title: TC (Traffic Control)
tags: [Networking]

---

###### 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 傳輸。

<!-- ![](https://i.imgur.com/tXizJTz.png) -->
![](https://i.imgur.com/urkAxGx.png)


### Element of Traffic Control

#### 1. Classification

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

以下為一個 Classification 的示意圖，封包經過一個 filter 決定要採取哪個 Policy
![](https://i.imgur.com/Pij6qG0.png)

:::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