> For the complete documentation index, see [llms.txt](https://openwrt-nctu.gitbook.io/project/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://openwrt-nctu.gitbook.io/project/openwrt-functions/openwrt-qos-scheduling.md).

# 實驗: 封包排程與 QoS

關於 OpenWRT 如何進行封包排程

這個實驗的目標是希望可以得到目前封包的排程狀況，因此，我們就可以知道下一個要傳出去的封包是要傳送給哪一個裝置。不過，一直沒有找到相關的資訊，倒是找到 Linux 中如何管理資料封包排程的資訊，記錄在此，作為之後參考。

從 Linux 的角度出發，說到封包排程直覺會想到 Queueing Discipline (QDisc) 這個指令，不過，查詢該指令和 OpenWRT 相關的資料後，多數的應用都在 QoS 的控制以及流量限制。在 OpenWRT 官方網站上可以找到以下兩篇資訊:

1. <https://wiki.openwrt.org/doc/howto/packet.scheduler/packet.scheduler.theory>
2. <https://wiki.openwrt.org/doc/howto/packet.scheduler/packet.scheduler>

按照所提供的資訊，我們可以先查看 OpenWRT 上的 QDisc 設定，如下所示:

```
root@GL-AR750S:~# tc qdisc show
qdisc noqueue 0: dev lo root refcnt 2
qdisc fq_codel 0: dev eth0 root refcnt 2 limit 10240p flows 1024 quantum 1514 target 5.0ms interval 100.0ms memory_limit 4Mb ecn
qdisc noqueue 0: dev br-lan root refcnt 2
qdisc noqueue 0: dev eth0.1 root refcnt 2
qdisc noqueue 0: dev eth0.2 root refcnt 2
qdisc noqueue 0: dev wlan1-2 root refcnt 2
qdisc noqueue 0: dev wlan0-2 root refcnt 2
qdisc noqueue 0: dev wlan1 root refcnt 2
qdisc noqueue 0: dev wlan0 root refcnt 2
```

看起來的確可以看到所有有限和無線的介面，同時，我們可以注意`eth0`的設定，在`eth0`上設定了額外的流量限制，這也是 QDisc 在 OpenWRT 上常見的應用。然而，若我們進一步去查詢每一個裝置的資訊，我們可以得到以下的成果:

```
root@GL-AR750S:~# tc -s qdisc show dev eth0
qdisc fq_codel 0: root refcnt 2 limit 10240p flows 1024 quantum 1514 target 5.0ms interval 100.0ms memory_limit 4Mb ecn
 Sent 1922621977 bytes 15414519 pkts (dropped 0, overlimits 0)
  maxpacket 1456 drop_overlimit 0 new_flow_count 447 ecn_mark 0
  new_flows_len 0 old_flows_len 0
root@GL-AR750S:~# tc -s qdisc show dev wlan0
qdisc noqueue 0: root refcnt 2
 Sent 0 bytes 0 pkts (dropped 0, overlimits 0)
root@GL-AR750S:~# tc -s qdisc show dev wlan1
qdisc noqueue 0: root refcnt 2
 Sent 0 bytes 0 pkts (dropped 0, overlimits 0)
```

對`eth0`而言，可以看到封包的統計量，但仍然看不到詳細的封包排程，而對 `wlan0` 和 `wlan1` 兩張網卡而言，卻沒有任何資訊，這是因為在這兩張網卡上並沒有定義相對應的規則。我們先在`wlan0`上加上一個 QDisc 試試看，指令為:

```
tc qdisc add dev wlan0 root handle 1: htb default 20
```

此時，再執行查詢，可以得到以下的結果:

```
root@GL-AR750S:~# tc qdisc show
qdisc noqueue 0: dev lo root refcnt 2
qdisc fq_codel 0: dev eth0 root refcnt 2 limit 10240p flows 1024 quantum 1514 target 5.0ms interval 100.0ms memory_limit 4Mb ecn
qdisc noqueue 0: dev br-lan root refcnt 2
qdisc noqueue 0: dev eth0.1 root refcnt 2
qdisc noqueue 0: dev eth0.2 root refcnt 2
qdisc noqueue 0: dev wlan1-2 root refcnt 2
qdisc noqueue 0: dev wlan0-2 root refcnt 2
qdisc noqueue 0: dev wlan1 root refcnt 2
qdisc htb 1: dev wlan0 root refcnt 5 r2q 10 default 32 direct_packets_stat 0 direct_qlen 1000
```

可以看到此時`wlan0`已經連上一個 QDisc 物件 (`htb1`)，我們可以藉由更改此物件，來對網路進行限流或是塑型，當一個 WiFi AP 服務多個無線網路時，這是十分好用的功能。同時，當我們查詢`wlan0`的資訊時，就可以看到查詢的結果。

```
root@GL-AR750S:~# tc -s qdisc show dev wlan0
qdisc htb 1: root refcnt 5 r2q 10 default 32 direct_packets_stat 201 direct_qlen 1000
 Sent 31945 bytes 201 pkts (dropped 0, overlimits 0)
```

此時，我們可以看到封包的統計量，但仍然看不到詳細的封包排程。若有興趣進行 QDisc 的設計，可以進一步參考以下資訊:

* <http://puremonkey2010.blogspot.com/2015/01/linux-tc-traffic-control.html>
* <http://shofan.blogspot.com/2017/08/linux-tctraffic-control.html>
* <http://shofan.blogspot.com/2017/08/linux-tctraffic-control2.html>
