# 在 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/>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://openwrt-nctu.gitbook.io/project/experiment-sdn/ovs-on-openwrt.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
