> 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/experiment-sdn/ovs-on-openwrt.md).

# 在 OpenWRT 上架設 Open vSwitch (OVS)

## Open vSwitch 介紹

Open vSwitch (OVS) 是一個在用以提供虛擬網路交換機的軟體，目的是實現網路的虛擬化。OVS 在 2010 年由 Citrix (XenServer 的母公司) 所提出，一開始主要專注於虛擬平台 (hypervisor) 的網路虛擬化，並以開放式的架構，支援不同的虛擬平台 (如: KVM、VirtualBox等) 獲取各方的投入。

![OVS 的架構圖 (來自: https://en.wikipedia.org/wiki/Open\_vSwitch)](/files/-Lb8_BO1fzhGjgKG7sHy)

{% hint style="info" %}
如果需要在 ubuntu 16.04 的 VM 中建立一個 OVS 測試環境，可以參考以下教學: <https://github.com/OSE-Lab/Learning-SDN/tree/master/Switch/OpenvSwitch/InstallwithSourceCode>
{% endhint %}

時到今日，OVS 已經是虛擬網路的主要選擇，在 Linux 3.3 版之後，也加入了原生的 Kernel 支援。同時，OVS 透過對於 OpenFlow 通訊協定的支援，許多軟體定義網路 (Software-Defined Network，SDN) 的架構也使用 OVS 作為其開發的套件。為了能夠了解 OVS 的運作方式，我們先找出 OVS 的系統架構圖，並說明各元件的功能。

![來自: http://hustcat.github.io/an-introduction-to-ovs-architecture/](/files/-Lb8umqHA_Iy4XQaACnU)

在此架構圖中，我們看到三個主要的原件: Datapath、vswitchd、ovsdb。其中，ovs-vswitchd 為  OVS 的主要模組，用以實現虛擬 switch 的 daemon (常駐程式)，此程式也負責和 Datapath 溝通。Datapath 則是 OVS  在 Linux Kernel 中的模組，用以接收來自網卡裝置的封包 *(1)*，並回報定義封包規則需求 *(2)*。此需求的決定 *(3)* 由 OpenFlow 告知 vswitchd，並寫入 flow table *(4)*。同時，vswitchd 也會通知 Datapath flow table 的更新 *(5)*，使 Datapath 可以根據更新的 flow table *(6)*，來傳導封包 *(7)*。

考慮到如果每一次封包的傳導都要詢問一次 OpenFlow 將導致網路的延遲與沒有效率，已經得知的規則將記錄在 flow table 中，供之後的封包使用。至於 ovsdb 則是用以搭配 vswitchd ，提供資料的暫存與設定。

至於其他管理的功能介面，我們表列如下:

* ovs-dpctl: 用來配置 Datapath (OVS Kernel 模組)
* ovs-ofctl: 查詢和控制 OpenFlow 的規則 (policy)
* ovsdb-tool: ovsdb 的設定工具
* ovs-vsctl: 查詢和更新 vswitchd 的配置

參考資訊:

* <https://www.openvswitch.org/>
* [https://github.com/openvswitch/ovs/blob/master/Documentation/tutorials/\
  ovs-advanced.rst](https://github.com/openvswitch/ovs/blob/master/Documentation/tutorials/ovs-advanced.rst)
* <https://github.com/OSE-Lab/Learning-SDN/tree/master/Switch/OpenvSwitch/Walkthrough>
* <http://myblog-maurice.blogspot.com/2011/12/open-vswitch.html>
* <https://en.wikipedia.org/wiki/Open_vSwitch>
* <http://hustcat.github.io/an-introduction-to-ovs-architecture/>

## 在 OpenWRT 上安裝 Open vSwitch

在 OpenWRT 上，假使 Kernel 有支援，就可以透過 .ipk 檔或是 opkg 的方式安裝 OVS，假如沒有的話，就必須和 LXC 一樣，重新編譯 OpenWRT 的映像檔，並燒入 WiFi AP 中。透過 opkg 的安裝指令如下:

```
# opkg install openvswitch
Installing openvswitch (2.8.2-1) to root...
Downloading http://download.gl-inet.com/releases/packages-3.x/ar71xx/packages/openvswitch_2.8.2-1_mips_24kc.ipk
Installing kmod-lib-crc32c (4.9.109-1) to root...
Downloading http://download.gl-inet.com/releases/kmod-3.0/ar71xx/nand/kmod-lib-crc32c_4.9.109-1_mips_24kc.ipk
Installing kmod-mpls (4.9.109-1) to root...
Downloading http://download.gl-inet.com/releases/kmod-3.0/ar71xx/nand/kmod-mpls_4.9.109-1_mips_24kc.ipk
Installing kmod-nf-nat6 (4.9.109-1) to root...
Downloading http://download.gl-inet.com/releases/kmod-3.0/ar71xx/nand/kmod-nf-nat6_4.9.109-1_mips_24kc.ipk
Installing kmod-openvswitch (4.9.109+2.8.2-1) to root...
Downloading http://download.gl-inet.com/releases/kmod-3.0/ar71xx/nand/kmod-openvswitch_4.9.109%2b2.8.2-1_mips_24kc.ipk
Installing openvswitch-base (2.8.2-1) to root...
Downloading http://download.gl-inet.com/releases/packages-3.x/ar71xx/packages/openvswitch-base_2.8.2-1_mips_24kc.ipk
Installing openvswitch-ovsdb-client (2.8.2-1) to root...
Downloading http://download.gl-inet.com/releases/packages-3.x/ar71xx/packages/openvswitch-ovsdb-client_2.8.2-1_mips_24kc.ipk
Installing openvswitch-ovs-l3ping (2.8.2-1) to root...
Downloading http://download.gl-inet.com/releases/packages-3.x/ar71xx/packages/openvswitch-ovs-l3ping_2.8.2-1_mips_24kc.ipk
Installing openvswitch-ovs-dpctl-top (2.8.2-1) to root...
Downloading http://download.gl-inet.com/releases/packages-3.x/ar71xx/packages/openvswitch-ovs-dpctl-top_2.8.2-1_mips_24kc.ipk
Installing openvswitch-ovs-tcpdump (2.8.2-1) to root...
Downloading http://download.gl-inet.com/releases/packages-3.x/ar71xx/packages/openvswitch-ovs-tcpdump_2.8.2-1_mips_24kc.ipk
Installing openvswitch-ovs-tcpundump (2.8.2-1) to root...
Downloading http://download.gl-inet.com/releases/packages-3.x/ar71xx/packages/openvswitch-ovs-tcpundump_2.8.2-1_mips_24kc.ipk
Installing openvswitch-ovs-pcap (2.8.2-1) to root...
Downloading http://download.gl-inet.com/releases/packages-3.x/ar71xx/packages/openvswitch-ovs-pcap_2.8.2-1_mips_24kc.ipk
Installing openvswitch-ovs-parse-backtrace (2.8.2-1) to root...
Downloading http://download.gl-inet.com/releases/packages-3.x/ar71xx/packages/openvswitch-ovs-parse-backtrace_2.8.2-1_mips_24kc.ipk
Configuring kmod-nf-nat6.
Configuring kmod-lib-crc32c.
Configuring kmod-mpls.
Configuring kmod-openvswitch.
Configuring openvswitch-base.
/etc/openvswitch/conf.db does not exist ... (warning).
Creating empty database /etc/openvswitch/conf.db.
BusyBox v1.28.3 () multi-call binary.

Usage: chmod [-R] MODE[,MODE]... FILE...

Each MODE is one or more of the letters ugoa, one of the
symbols +-= and one or more of the letters rwxst

        -R      Recurse
BusyBox v1.28.3 () multi-call binary.

Usage: chmod [-R] MODE[,MODE]... FILE...

Each MODE is one or more of the letters ugoa, one of the
symbols +-= and one or more of the letters rwxst

        -R      Recurse
Starting ovsdb-server.
system ID not configured, please use --system-id ... failed!
Configuring Open vSwitch system IDs.
Starting ovs-vswitchd.
Enabling remote OVSDB managers.
Configuring openvswitch-ovs-pcap.
Configuring openvswitch-ovsdb-client.
Configuring openvswitch-ovs-dpctl-top.
Configuring openvswitch-ovs-l3ping.
Configuring openvswitch-ovs-tcpundump.
Configuring openvswitch-ovs-parse-backtrace.
Configuring openvswitch-ovs-tcpdump.
Configuring openvswitch.
```

透過`opkg install openvswitch`指令，就可以安裝完和 OVS 相關的套件，我們可以  tab 一下，看看有那些 OVS 相關的套件:

```
# ovs
ovs-appctl           ovs-parse-backtrace  ovs-vsctl
ovs-dpctl            ovs-pcap             ovs-vswitchd
ovs-dpctl-top        ovs-pki              ovsdb-client
ovs-l3ping           ovs-tcpdump          ovsdb-server
ovs-ofctl            ovs-tcpundump        ovsdb-tool
```

我們可以看到在上一節中說到的 4 個主要控制介面: ovs-dpctl、ovs-ofctl、ovs-vsctl 以及 ovsdb-tool 都存在。我們可以先用`show`指令來看一下目前原始的設定:

```
# ovs-vsctl show
3fd8c47e-dc7d-459c-902d-759d693a0e6f
    ovs_version: "2.8.2"
```

接著，為了操作 OVS 的虛擬網路功能，我們透過`add-br br0`的指令，加入一個虛擬的 bridge (br0)，並再次查看 vswitchd 的配置:

```
# ovs-vsctl add-br br0
# ovs-vsctl show
3fd8c47e-dc7d-459c-902d-759d693a0e6f
    Bridge "br0"
        Port "br0"
            Interface "br0"
                type: internal
    ovs_version: "2.8.2"
```

結果可以看到，有一個新增的`br0`出現，但是只有一個 port 連到自己，因此，實際上來說，並無法實現任何虛擬網路的功能，只能驗證 OVS 的設定是正確的。在之後的內容中，我們將會繼續 OVS 在 OpenWRT 上的設定，並和 pica8 上的 OpenFlow 控制器偕同工作，使其完成 SDN 的功能。

參考資料:

* <https://openwrt.org/packages/pkgdata/openvswitch>
* <http://worldend.logdown.com/posts/257810-configure-open-vswitch-in-openwrt>
* <https://fantinyang.github.io/2018/06/16/post5/>
