FD.io VPP 事始め
Tetsuhiro Sato
自己紹介
 佐藤 哲大(tetz)
 某ネットワークベンダで、SDN(っぽい)仕事をしてます
 ネットワークプログラマビリティ勉強会の企画、運営をしてます
http://network-programmability.connpass.com/
2
FD.io
 FD.io
 Fast Data – Input/Output に関
連する複数のプロジェクトを運営する
Apache Foundation傘下のプロ
ジェクト
 VPPの他に、VPPの管理、VPPを用
いたユースケース、Testing等のプロ
ジェクトも管理
3
https://wiki.fd.io/view/VPP/Features
FD.io VPP
 VPP
 FD.ioの中核プロジェクト
 高性能かつ高機能な仮想スイッチ&ルータ
 DPDKを活用し、ユーザー空間のアプリケー
ションとして動作
4
Vector Packet Processing
 通常のコンピューティング処理にないパケット処理に
固有の難しさ(Instructionの観点から)
 10Gbps ラインレート=14.88Mfps = 67nsec per フレーム
 2GHz CPUコアのクロックサイクル= 0.5 nsec
 つまり、1フレームあたり134クロックサイクルの余地
 DRAM にアクセスしてしまうと、CPU サイクルがおよそ 60ns
ストールしてしまう
 Scalar Packet Processing
 パケット毎に処理
 割り込み
 コールスタックのトラバース(一連の機能を適用)
 ACL, NAT, QoS, VXLAN, etc
 Punt, drop, or rewrite/forward
 問題点
 I-cacheのスラッシング
 パケット毎に同様のI-cacheミスを繰り返す
 I-cacheを大きくしない限り、上記の問題は解決しない
 Vector Packet Processing
 複数のパケットを同時に処理
 先頭のパケットがI-cacheをWarm up
 後続のパケットにはI-cacheにHit!
5
http://stackoverflow.com/questions/4087280/approximate-cost-to-access-various-
caches-and-main-memory
豊富な機能
6
! とりあえず、いろんな機能をサポート
https://wiki.fd.io/view/VPP/Features
インストール
7
$ export UBUNTU="trusty"
$ export RELEASE=".stable.1609"
$ sudo rm /etc/apt/sources.list.d/99fd.io.list
$ echo "deb [trusted=yes] https://nexus.fd.io/content/repositories/fd.io$RELEASE.ubuntu.$UBUNTU.main/ ./" 
| sudo tee -a /etc/apt/sources.list.d/99fd.io.list
$ sudo apt-get update
$ sudo apt-get install vpp vpp-dpdk-dkms
 Yum、Aptなどのパッケージマネージャからインストールできる
https://wiki.fd.io/view/VPP/Installing_VPP_binaries_from_packages
(Ubuntu14.04の例)
コマンドライン接続
8
unix {
...
cli-listen localhost:5002
...
}
 /etc/vpp/startup.confに以下のように書いておくと、telnetでVPPのコマンドラインに接続できる
$ telnet localhost 5002
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
_______ _ _ _____ ___
__/ __/ _  (_)__ | | / / _ / _ 
_/ _// // / / / _  | |/ / ___/ ___/
/_/ /____(_)_/___/ |___/_/ /_/
vpp#
$ sudo vppctl show ver
vpp v17.04-rc0~227-g614ac5d built by tetsusat on ubuntu at Tue Feb 7 08:43:33 JST 2017
 もしくは、ホストLinux上で、vppctlに続けてVPPのコマンド実行できる
接続方法
 外部に接続するVPPインターフェイスの種類
9
接続方法 ユースケース(たぶん)
DPDK PDM(w/ Intel NIC, VMXNET3) ホストマシンのインターフェイスの利用
vhost KVMとの接続
veth コンテナとの接続
tap ホストマシンのLinuxサービス(DHCP等)を利用
DPDKの設定
10
$ sudo lshw -class network -businfo
Bus info Device Class Description
====================================================
pci@0000:02:00.0 eth1 network 82545EM Gigabit Ethernet Controller (Copper)
pci@0000:02:01.0 eth2 network 82545EM Gigabit Ethernet Controller (Copper)
pci@0000:03:00.0 eth0 network VMXNET3 Ethernet Controller
 DPDK対応NICのPCI IDを確認
$ sudo ifconfig eth1 down
$ sudo ifconfig eth2 down
$ sudo ip addr flush dev eth1
$ sudo ip addr flush dev eth2
 インターフェイスの設定をクリア
DPDK の設定(つづき)
dpdk {
socket-mem 1024
dev 0000:02:00.0
dev 0000:02:01.0
}
 /etc/vpp/startup.confにdpdkに関する設定を追加して、VPPを起動
 socket-memはパケットバッファ、hugepagesからアロケートされる
 socket-memは明示的に指定しないと、CPUソケット(NUMAノード)毎に512Mを確保
 VPP側では、GigabitEthernetX/X/Xとして認識される
vpp# show int
Name Idx State Counter Count
GigabitEthernet2/0/0 1 down
GigabitEthernet2/1/0 2 down
...
vhostの設定
vpp# create vhost socket /tmp/sock0.sock server
 vhost socketを作成
vpp# show int
Name Idx State Counter Count
VirtualEthernet0/0/0 3 down
...
<qemu:commandline>
<!-- vhost-user -->
<qemu:arg value='-chardev'/>
<qemu:arg value='socket,id=char0,path=/tmp/sock0.sock’/>
<qemu:arg value=’-netdev’/>
<qemu:arg value=’vhost-user,id=mynet,chardev=char0'/>
<qemu:arg value='-device'/>
<qemu:arg value='virtio-net-pci,netdev=mynet,mac=52:54:00:01:00:33'/>
<qemu:arg value='-object'/>
<qemu:arg value='memory-backend-file,id=mem,size=16384M,mem-path=/run/hugepages/kvm,share=on'/>
<qemu:arg value='-numa'/>
<qemu:arg value='node,memdev=mem'/>
<qemu:arg value='-mem-prealloc'/>
</qemu:commandline>
 livbirt XML定義ファイルでvhost-userの設定(XRvの場合)
 VPP側では VirtualEthernet0/0/Xと認識される
vethの設定
$ sudo ip link add vpp1 type veth peer name veth1
 ホストでvpp1とveth1というvethペアを作成
vpp# create host-interface name vpp1
host-vpp1
 VPP側ではhost-vpp1と認識される
 veth1をコンテナ等に接続
vpp# show int
Name Idx State Counter Count
host-vpp1 4 down
…
 VPP側ではhost-vpp1と認識される
tapの設定
vpp# tap connect taphost
tap-0
 taphostというtapインターフェイスを作成
vpp# show int
Name Idx State Counter Count
tap-0 5 down
...
 VPP側ではtap-Xと認識される
 ホスト側ではtaphostとして認識される
$ ip link
...
7: taphost: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state
UNKNOWN mode DEFAULT group default qlen 1000
link/ether 4e:00:94:42:8d:35 brd ff:ff:ff:ff:ff:ff
デモ L2設定
15
vpp# create host-interface name vpp1
host-vpp1
vpp# set interface state host-vpp1 up
vpp# set interface l2 bridge host-vpp1 1
vpp# create host-interface name vpp2
host-vpp2
vpp# set interface state host-vpp2 up
vpp# set interface l2 bridge host-vpp2 1
 VPPにvethを認識させ、L2ポートとしてBridge
Domain 1に接続
L3ポートL2ポート
Bridge Domain 1
C1 C2
veth
pair
veth
pair
eth0 eth0
Network Namespace: default
Network Namespace:
ns1
Network Namespace:
ns2
10.0.0.1 10.0.0.2
host-vpp1 host-vpp2
デモ L3設定
16
vpp# create loopback interface
loop0
vpp# set interface l2 bridge loop0 1 bvi
vpp# set interface state loop0 up
vpp# set interface ip address loop0 10.0.0.254/24
vpp# create host-interface name vpp3
host-vpp3
vpp# set interface state host-vpp3 up
vpp# set interface ip address host-vpp3 10.0.1.254/24
 Bridge Domain 1 に BVI インターフェイスを設定
 VPPにvethを認識させ、L3ポートとして設定
VPP Router
L3ポートL2ポート
Bridge Domain 1
C1 C2 C3
veth
pair
veth
pair
veth
pair
eth0 eth0 eth0
Network Namespace: default
Network Namespace:
ns1
Network Namespace:
ns2
Network Namespace:
ns3
10.0.0.254
10.0.1.254
10.0.0.1 10.0.0.2 10.0.1.1
host-vpp1 host-vpp2 host-vpp3
loop0(bvi)
落穂拾い
17
unix {
...
startup-config /home/userid/setup.cfg
...
}
 起動時に(仮想スイッチ&ルータとしての)VPPの設定を読み込ませるに
は、/etc/vpp/startup.confのunix句で設定ファイルを指定
落穂拾い(cont.)
18
vpp# show trace
------------------- Start of thread 0 vpp_main -------------------
Packet 1
00:13:25:316687: af-packet-input
af_packet: hw_if_index 1 next-index 1
tpacket2_hdr:
status 0x1 len 98 snaplen 98 mac 66 net 80
sec 0x5890503a nsec 0x22819a55 vlan 0
00:13:25:316712: ethernet-input
IP4: 06:28:d8:1d:3c:f2 -> 4a:74:64:4d:bd:0a
00:13:25:316721: l2-input
l2-input: sw_if_index 1 dst 4a:74:64:4d:bd:0a src 06:28:d8:1d:3c:f2
00:13:25:316725: l2-learn
l2-learn: sw_if_index 1 dst 4a:74:64:4d:bd:0a src 06:28:d8:1d:3c:f2 bd_index
1
00:13:25:316728: l2-fwd
l2-fwd: sw_if_index 1 dst 4a:74:64:4d:bd:0a src 06:28:d8:1d:3c:f2 bd_index
1
00:13:25:316730: l2-output
l2-output: sw_if_index 2 dst 4a:74:64:4d:bd:0a src 06:28:d8:1d:3c:f2
00:13:25:316733: host-vpp2-output
host-vpp2
IP4: 06:28:d8:1d:3c:f2 -> 4a:74:64:4d:bd:0a
ICMP: 10.0.0.1 -> 10.0.0.2
tos 0x00, ttl 64, length 84, checksum 0x476a
fragment id 0xdf3c, flags DONT_FRAGMENT
ICMP echo_request checksum 0xebee
 /etc/vpp/startup.confのapi-trace
をonに編集
api-trace {
on
}
vpp# trace add af-packet-input 10
 traceを有効化
vpp# clear trace
 trace結果をクリア
 trace結果の確認
おわり
ご清聴、ありがとうございました
m(_ _)m
19

VPP事始め

  • 1.
  • 2.
    自己紹介  佐藤 哲大(tetz) 某ネットワークベンダで、SDN(っぽい)仕事をしてます  ネットワークプログラマビリティ勉強会の企画、運営をしてます http://network-programmability.connpass.com/ 2
  • 3.
    FD.io  FD.io  FastData – Input/Output に関 連する複数のプロジェクトを運営する Apache Foundation傘下のプロ ジェクト  VPPの他に、VPPの管理、VPPを用 いたユースケース、Testing等のプロ ジェクトも管理 3 https://wiki.fd.io/view/VPP/Features
  • 4.
    FD.io VPP  VPP FD.ioの中核プロジェクト  高性能かつ高機能な仮想スイッチ&ルータ  DPDKを活用し、ユーザー空間のアプリケー ションとして動作 4
  • 5.
    Vector Packet Processing 通常のコンピューティング処理にないパケット処理に 固有の難しさ(Instructionの観点から)  10Gbps ラインレート=14.88Mfps = 67nsec per フレーム  2GHz CPUコアのクロックサイクル= 0.5 nsec  つまり、1フレームあたり134クロックサイクルの余地  DRAM にアクセスしてしまうと、CPU サイクルがおよそ 60ns ストールしてしまう  Scalar Packet Processing  パケット毎に処理  割り込み  コールスタックのトラバース(一連の機能を適用)  ACL, NAT, QoS, VXLAN, etc  Punt, drop, or rewrite/forward  問題点  I-cacheのスラッシング  パケット毎に同様のI-cacheミスを繰り返す  I-cacheを大きくしない限り、上記の問題は解決しない  Vector Packet Processing  複数のパケットを同時に処理  先頭のパケットがI-cacheをWarm up  後続のパケットにはI-cacheにHit! 5 http://stackoverflow.com/questions/4087280/approximate-cost-to-access-various- caches-and-main-memory
  • 6.
  • 7.
    インストール 7 $ export UBUNTU="trusty" $export RELEASE=".stable.1609" $ sudo rm /etc/apt/sources.list.d/99fd.io.list $ echo "deb [trusted=yes] https://nexus.fd.io/content/repositories/fd.io$RELEASE.ubuntu.$UBUNTU.main/ ./" | sudo tee -a /etc/apt/sources.list.d/99fd.io.list $ sudo apt-get update $ sudo apt-get install vpp vpp-dpdk-dkms  Yum、Aptなどのパッケージマネージャからインストールできる https://wiki.fd.io/view/VPP/Installing_VPP_binaries_from_packages (Ubuntu14.04の例)
  • 8.
    コマンドライン接続 8 unix { ... cli-listen localhost:5002 ... } /etc/vpp/startup.confに以下のように書いておくと、telnetでVPPのコマンドラインに接続できる $ telnet localhost 5002 Trying ::1... Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. _______ _ _ _____ ___ __/ __/ _ (_)__ | | / / _ / _ _/ _// // / / / _ | |/ / ___/ ___/ /_/ /____(_)_/___/ |___/_/ /_/ vpp# $ sudo vppctl show ver vpp v17.04-rc0~227-g614ac5d built by tetsusat on ubuntu at Tue Feb 7 08:43:33 JST 2017  もしくは、ホストLinux上で、vppctlに続けてVPPのコマンド実行できる
  • 9.
    接続方法  外部に接続するVPPインターフェイスの種類 9 接続方法 ユースケース(たぶん) DPDKPDM(w/ Intel NIC, VMXNET3) ホストマシンのインターフェイスの利用 vhost KVMとの接続 veth コンテナとの接続 tap ホストマシンのLinuxサービス(DHCP等)を利用
  • 10.
    DPDKの設定 10 $ sudo lshw-class network -businfo Bus info Device Class Description ==================================================== pci@0000:02:00.0 eth1 network 82545EM Gigabit Ethernet Controller (Copper) pci@0000:02:01.0 eth2 network 82545EM Gigabit Ethernet Controller (Copper) pci@0000:03:00.0 eth0 network VMXNET3 Ethernet Controller  DPDK対応NICのPCI IDを確認 $ sudo ifconfig eth1 down $ sudo ifconfig eth2 down $ sudo ip addr flush dev eth1 $ sudo ip addr flush dev eth2  インターフェイスの設定をクリア
  • 11.
    DPDK の設定(つづき) dpdk { socket-mem1024 dev 0000:02:00.0 dev 0000:02:01.0 }  /etc/vpp/startup.confにdpdkに関する設定を追加して、VPPを起動  socket-memはパケットバッファ、hugepagesからアロケートされる  socket-memは明示的に指定しないと、CPUソケット(NUMAノード)毎に512Mを確保  VPP側では、GigabitEthernetX/X/Xとして認識される vpp# show int Name Idx State Counter Count GigabitEthernet2/0/0 1 down GigabitEthernet2/1/0 2 down ...
  • 12.
    vhostの設定 vpp# create vhostsocket /tmp/sock0.sock server  vhost socketを作成 vpp# show int Name Idx State Counter Count VirtualEthernet0/0/0 3 down ... <qemu:commandline> <!-- vhost-user --> <qemu:arg value='-chardev'/> <qemu:arg value='socket,id=char0,path=/tmp/sock0.sock’/> <qemu:arg value=’-netdev’/> <qemu:arg value=’vhost-user,id=mynet,chardev=char0'/> <qemu:arg value='-device'/> <qemu:arg value='virtio-net-pci,netdev=mynet,mac=52:54:00:01:00:33'/> <qemu:arg value='-object'/> <qemu:arg value='memory-backend-file,id=mem,size=16384M,mem-path=/run/hugepages/kvm,share=on'/> <qemu:arg value='-numa'/> <qemu:arg value='node,memdev=mem'/> <qemu:arg value='-mem-prealloc'/> </qemu:commandline>  livbirt XML定義ファイルでvhost-userの設定(XRvの場合)  VPP側では VirtualEthernet0/0/Xと認識される
  • 13.
    vethの設定 $ sudo iplink add vpp1 type veth peer name veth1  ホストでvpp1とveth1というvethペアを作成 vpp# create host-interface name vpp1 host-vpp1  VPP側ではhost-vpp1と認識される  veth1をコンテナ等に接続 vpp# show int Name Idx State Counter Count host-vpp1 4 down …  VPP側ではhost-vpp1と認識される
  • 14.
    tapの設定 vpp# tap connecttaphost tap-0  taphostというtapインターフェイスを作成 vpp# show int Name Idx State Counter Count tap-0 5 down ...  VPP側ではtap-Xと認識される  ホスト側ではtaphostとして認識される $ ip link ... 7: taphost: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 1000 link/ether 4e:00:94:42:8d:35 brd ff:ff:ff:ff:ff:ff
  • 15.
    デモ L2設定 15 vpp# createhost-interface name vpp1 host-vpp1 vpp# set interface state host-vpp1 up vpp# set interface l2 bridge host-vpp1 1 vpp# create host-interface name vpp2 host-vpp2 vpp# set interface state host-vpp2 up vpp# set interface l2 bridge host-vpp2 1  VPPにvethを認識させ、L2ポートとしてBridge Domain 1に接続 L3ポートL2ポート Bridge Domain 1 C1 C2 veth pair veth pair eth0 eth0 Network Namespace: default Network Namespace: ns1 Network Namespace: ns2 10.0.0.1 10.0.0.2 host-vpp1 host-vpp2
  • 16.
    デモ L3設定 16 vpp# createloopback interface loop0 vpp# set interface l2 bridge loop0 1 bvi vpp# set interface state loop0 up vpp# set interface ip address loop0 10.0.0.254/24 vpp# create host-interface name vpp3 host-vpp3 vpp# set interface state host-vpp3 up vpp# set interface ip address host-vpp3 10.0.1.254/24  Bridge Domain 1 に BVI インターフェイスを設定  VPPにvethを認識させ、L3ポートとして設定 VPP Router L3ポートL2ポート Bridge Domain 1 C1 C2 C3 veth pair veth pair veth pair eth0 eth0 eth0 Network Namespace: default Network Namespace: ns1 Network Namespace: ns2 Network Namespace: ns3 10.0.0.254 10.0.1.254 10.0.0.1 10.0.0.2 10.0.1.1 host-vpp1 host-vpp2 host-vpp3 loop0(bvi)
  • 17.
    落穂拾い 17 unix { ... startup-config /home/userid/setup.cfg ... } 起動時に(仮想スイッチ&ルータとしての)VPPの設定を読み込ませるに は、/etc/vpp/startup.confのunix句で設定ファイルを指定
  • 18.
    落穂拾い(cont.) 18 vpp# show trace -------------------Start of thread 0 vpp_main ------------------- Packet 1 00:13:25:316687: af-packet-input af_packet: hw_if_index 1 next-index 1 tpacket2_hdr: status 0x1 len 98 snaplen 98 mac 66 net 80 sec 0x5890503a nsec 0x22819a55 vlan 0 00:13:25:316712: ethernet-input IP4: 06:28:d8:1d:3c:f2 -> 4a:74:64:4d:bd:0a 00:13:25:316721: l2-input l2-input: sw_if_index 1 dst 4a:74:64:4d:bd:0a src 06:28:d8:1d:3c:f2 00:13:25:316725: l2-learn l2-learn: sw_if_index 1 dst 4a:74:64:4d:bd:0a src 06:28:d8:1d:3c:f2 bd_index 1 00:13:25:316728: l2-fwd l2-fwd: sw_if_index 1 dst 4a:74:64:4d:bd:0a src 06:28:d8:1d:3c:f2 bd_index 1 00:13:25:316730: l2-output l2-output: sw_if_index 2 dst 4a:74:64:4d:bd:0a src 06:28:d8:1d:3c:f2 00:13:25:316733: host-vpp2-output host-vpp2 IP4: 06:28:d8:1d:3c:f2 -> 4a:74:64:4d:bd:0a ICMP: 10.0.0.1 -> 10.0.0.2 tos 0x00, ttl 64, length 84, checksum 0x476a fragment id 0xdf3c, flags DONT_FRAGMENT ICMP echo_request checksum 0xebee  /etc/vpp/startup.confのapi-trace をonに編集 api-trace { on } vpp# trace add af-packet-input 10  traceを有効化 vpp# clear trace  trace結果をクリア  trace結果の確認
  • 19.