如何將Linux打造成OpenFlow Switch:Lagopus

上次介紹的部份是利用 openvswitch 來打造 OpenFlow switch,這也是大部份目前市面上買的到的 OpenFlow switch 所使用的軟體。問題是,它的傳輸效率不太好,畢竟它是透過 Linux kernel 來處理 Flow Entry。有人可能會說:「不會啊,我買的 switch 傳輸速度沒有問題啊,幾乎都可以達到 line rate」,OK,這是因為這些市面上賣的 switch 大部份都移植 Flow Entry 到處理程序到硬體平台上(像是 Broadcom 的晶片),所以傳輸速度當然不差,可是!很多 OpenFlow 的功能就不支援了,畢竟那些晶片本來就沒有提供這些功能啊(通常是Set Field)。我們可以將目前 OpenFlow switch 的狀況大概整理如下:

  1. Software-based OpenFlow switch
    功能支援度高,容易升級,但傳輸速度慢
  2. Hardware-based OpenFlow switch
    傳輸速度快,但功能並不完善
有沒有能夠兼顧兩者的設備呢?今天要介紹的這套 Lagopus 就是一個可能的選項。Lagopus 是 NTT 所開發的 Software OpenFlow switch。Software?那傳輸速率呢?為了解決這個問題,Lagopus 採用了 Intel 所推出的 Data Plane Development Kit (DPDK) 技術。下面我們就先來介紹什麼是 DPDK。

DPDK簡介

DPDK 這個技術的概念可以用下圖來表達:
DPDK(資料來源:Intel)
這張圖說明了 Intel 的 DPDK 技術是如何加速封包的處理。大概解釋一下。傳統 Linux 封包處理流程,是硬體收到封包後觸發 interrupt 後導到 Linux Kernel,如果還要進入 user space,就要通過 copy_to_user/copy_from_user 這樣的機制,而這會牽扯到記憶體拷貝的問題,這是因為不能讓 user space 直接讀到 kernel space 的記憶體管理,免得造成系統錯誤,所以作業系統會用一塊虛擬化的記憶體位置來給 user space 的 process,而這種記憶體保護機制以及拷貝很吃系統資源,這也是為什麼傳統上在處理 Linux 的 Data Plane 的時候都盡可能在 Kernel 處理,減少 user space 和 kernel space 記憶體拷貝所造成效率低下。而從這個圖來看,應該可以發現封包根本不通過 Linux Kernel 就直接打到 user space,因此可以有比較好的效能。怎麼做的?不知道,但因為 DPDK 技術必須要使用 Intel 的 CPU 以及網卡,所以我猜 Intel 有可能直接讓網卡發出的 interrupt 直接用記憶體映射到 CPU 裏面然後偷渡到 user space(以上純屬猜測,目前還沒空去研究)

總結一下, Lagopus 是一套 Software OpenFlow switch,使用 Intel DPDK 的技術來加速封包處理。這也意味著兩件事情:第1,你非要使用 Intel 的 CPU 和網卡不可。第2,封包的處理是在 user space(這對程式設計師來說是優點)。

安裝 Lagopus

現在來看看怎麼安裝 Lagopus,主要參考內容是 Lagopus 的 Quickstart.md,作業系統是 ubuntu。收先要先安裝 DPDK。

$ sudo apt-get install make coreutils gcc binutils
$ sudo apt-get install linux-headers-`uname -r`
$ wget https://downloads.sourceforge.net/project/lagopus/Intel-DPDK/DPDK-1.6.0-18.zip
$ unzip DPDK-1.6.0-18.zip
$ export RTE_SDK="/home/user/DPDK-1.6.0"
$ export RTE_TARGET="x86_64-default-linuxapp-gcc"
$ make config T=${RTE_TARGET}
$ make install T=${RTE_TARGET}

應該算是很好明白,所以就不多做解釋了。不過安裝完以後還要設定 hugepages。首先去編輯 /etc/default/grub,設定如下:

GRUB_CMDLINE_LINUX="" --> GRUB_CMDLINE_LINUX="hugepages=1024"

然後使用 hugepages。

$ sudo update-grub
$ sudo mkdir -p /mnt/huge
$ sudo joe /etc/fstab
    nodev /mnt/huge hugetlbfs defaults 0 0
$ sudo reboot

接下來就輪到 Lagopus 了。安裝步驟如下:

# sudo apt-get install unzip build-essential libexpat1-dev libgmp-dev libncurses5-dev libssl-dev libpcap-dev byacc flex libreadline-dev python-dev python-pastedeploy python-paste python-twisted git python-setuptools python-pip python-dev libxml2-dev libxslt1-dev
$ export RTE_SDK="/home/user/DPDK-1.6.0"
$ export RTE_TARGET="x86_64-default-linuxapp-gcc"
$ git clone https://github.com/lagopus/lagopus.git
$ cd lagopus
$ ./configure --with-dpdk-dir=${RTE_SDK}
$ make
$ sudo make install

上面的安裝也很直覺,就不多做解釋了。可能有人會看這篇文章,也會按照這篇文章進行操作,但請注意文章是有時間性的,新版的不見得能順利操作。

設定並操作 Lagopus

安裝好以後就要開始用了。 首先要先載入 DPDK Kernel Module 並把網卡只派去使用 DPDK 的機制。


$ sudo modprobe uio
$ sudo insmod ${RTE_SDK}/${RTE_TARGET}/kmod/igb_uio.ko
$ sudo insmod ${RTE_SDK}/${RTE_TARGET}/kmod/rte_kni.ko
$ sudo $(RTE_SDK}/tools./pci_unbind.py --status

        Network devices using IGB_UIO driver

        ====================================

        

        Network devices using kernel driver

        ===================================

        0000:02:01.0 '82545EM Gigabit Ethernet Controller (Copper)' if=eth0 drv=e1000 unused=igb_uio *Active*

        0000:02:02.0 '82545EM Gigabit Ethernet Controller (Copper)' if=eth1 drv=e1000 unused=igb_uio

        0000:02:03.0 '82545EM Gigabit Ethernet Controller (Copper)' if=eth2 drv=e1000 unused=igb_uio

        0000:02:04.0 '82545EM Gigabit Ethernet Controller (Copper)' if=eth3 drv=e1000 unused=igb_uio

        Other network devices

        =====================

        

$ sudo ${RTE_SDK}/pci_unbind.py -b igb_uio 0000:02:02.0 0000:02:03.0 0000:02:04.0
$ sudo ${RTE_SDK}/pci_unbind.py --status

        Network devices using IGB_UIO driver

        ====================================

        0000:02:02.0 '82545EM Gigabit Ethernet Controller (Copper)' drv=igb_uio unused=e1000

        0000:02:03.0 '82545EM Gigabit Ethernet Controller (Copper)' drv=igb_uio unused=e1000

        0000:02:04.0 '82545EM Gigabit Ethernet Controller (Copper)' drv=igb_uio unused=e1000

        Network devices using kernel driver

        ===================================

        0000:02:01.0 '82545EM Gigabit Ethernet Controller (Copper)' if=eth0 drv=e1000 unused=igb_uio *Active*

        Other network devices

        =====================

        

從上面的指令可以很輕易的發現,這台設備有 4 個網卡,其中 3 個會使用 DPDK 的機制,剩下一個(eth0)則還是採用原來 Linux 的 Kernel Module,這也是我們之後後用來連接 controller 的。我們可以利用 ifconfig 來確認目前網卡,應該會發現只剩下一張 eth0 了那其他的呢?因為 DPDK 已經接管了,所以就不在 Linux 系統的管理範圍

接下來要設定 Lagopus,編輯 lagopus.conf。範例如下:

interface {
    ethernet {
        eth0;
        eth1;
        eth2;
    }
}
bridge-domains {
    br0 {
        port {
            eth0;
            eth1;
            eth2;
        }
        controller {
            192.168.8.10;
        }
    }
}

要注意這裡的 eth0 和系統的 eth0 是不一樣的!剛剛我們把三張網卡納入 DPDK 的機制中,所以這邊就是從 eth0 到 eth2。

最後就是執行指令:

$ sudo lagopus -d -- -c3 -n1 -- -p3

參數的意義可以直接查詢 Lagopus 相關文件。要注意的事,這裡的數字都是 16 進位唷,而且還是用 bitmask 的方式呈獻

留言

這個網誌中的熱門文章

如何將Linux打造成OpenFlow Switch:Openvswitch

我弟家的新居感恩禮拜分享:善頌善禱

Linux Virtual Interface: TUN/TAP