オープンソースP4プログラムのRAREをTofinoモデルでテストする環境を構築しました
はじめに
日本P4ユーザ会でも話題がありましたが、RAREというプロジェクトにて、Tofinoデバイス向けのP4プログラムが公開されております。
https://bitbucket.software.geant.org/projects/rare
また、上記のP4プログラムを仮想マシン上で動作可能なTofinoモデル(Tofinoデバイスの動作を模擬するシミュレータ)にて動作させるための方法も以下にて紹介されています。
"My name is TOFINO ... INTEL/BAREFOOT TOFINO and I speak P4 too !"
上記を参考にTofinoシミュレータにてRAREを動かしてみましたので、その方法を本記事にて共有いたします。なお、本記事と同等な環境を構築するためにはTofinoのP4開発環境をお持ちであることが前提条件となります。TofinoのP4開発環境については以下をご参照ください。
https://www.intel.com/content/www/us/en/products/network-io/programmable-ethernet-switch.html
また、TofinoのP4開発環境をお持ちでない場合は、BMv2を使った以下の記事にてP4を使ったRARE環境を作ることも可能です。
"Are you P4 compliant ?"
構築するネットワーク
図1: 構築するRAREの試験環境
Ubuntu18.04の仮想マシン(メモリ8GB、CPUコア数8、ストレージ80GB)を用意し、その中にRAREの環境を用意しました。ピンクの網掛けがRAREのプロジェクトの中で用意されているツールです。freeRouter | ルーティングスタック |
bf_forwarder | Tofinoモデル内のP4テーブルを操作するコントロールプレーン |
RARE P4プログラム | RAREにて開発されたP4データプレーン |
pcapInt.bin | Tofinoモデルで送受信する制御パケットをfreeRouterに中継 |
bfswitchd | Tofinoモデルを制御するツール |
Tofinoモデル | Tofinoのチップの動きを疑似するツール、P4プログラムに従いパケットを中継 |
ツールのインストールと初期設定
KVMホストのBridgeとnetnsの設定
まず、KVMホスト内にて、仮想マシンとhost1、host2の間のネットワークを設定しておきます。この中で、net01とnet02のbridgeを作成し、仮想マシンのNICのens9、ens10をこれらのbridgeに割り当てます。sudo brctl addbr net01 sudo ip link set net01 up sudo brctl addbr net02 sudo ip link set net02 up sudo ip netns add host1 sudo ip netns add host2 sudo ip link add veth11 type veth peer name veth12 sudo brctl addif net01 veth11 sudo ip link set veth12 netns host1 sudo ip link set veth11 up sudo ip netns exec host1 ip addr add 192.168.0.101/24 dev veth12 sudo ip netns exec host1 route add default gw 192.168.0.1 sudo ip netns exec host1 ip link set veth12 up sudo ip link add veth13 type veth peer name veth14 sudo brctl addif net02 veth13 sudo ip link set veth14 netns host2 sudo ip link set veth13 up sudo ip netns exec host2 ip addr add 192.168.1.101/24 dev veth14 sudo ip netns exec host2 route add default gw 192.168.1.1 sudo ip netns exec host2 ip link set veth14 up
freeRouterのインストール
参考記事に従い、仮想マシン内にfreeRouterをセットアップします。mkdir -p ~/freeRouter/bin ~/freeRouter/lib ~/freeRouter/etc ~/freeRouter/log cd ~/freeRouter/lib wget http://freerouter.nop.hu/rtr.jar cd ~ wget freerouter.nop.hu/rtr.tar tar xvf rtr.tar -C ~/freeRouter/bin/
Tofino P4開発環境とRAREのP4プログラムのビルド
参考記事に従い、Tofino P4開発環境のSDE 9.2.0をインストールします(手順は割愛)。その上で、ホームディレクトリにて、以下のようにRAREのP4プログラムをビルドします(p4_build.shはSDEの中に含まれるツールです)。git clone https://bitbucket.software.geant.org/scm/rare/rare.git p4_build.sh -I /root/rare/p4src/ -DHAVE_MPLS /root/rare/p4src/bf_router.p4
freeRouterの設定ファイル
freeRouterは、hardwareとsoftwareの二つの設定ファイルを用意する必要があります。- ~/freeRouter/etc/tna-freerouter-hw.txt
int ethernet0 eth 0000.1111.00fb 127.0.0.1 22710 127.0.0.1 22709 tcp2vrf 2323 v1 23 tcp2vrf 9080 v1 9080
- ~/freeRouter/etc/tna-freerouter-sw.txt
hostname tna-freerouter buggy ! ! vrf definition v1 exit ! interface ethernet0 description freerouter@P4_CPU_PORT[veth251] no shutdown no log-link-change exit ! interface sdn1 description freerouter@sdn1[ens9] mtu 9000 macaddr 020a.0000.1111 vrf forwarding v1 ipv4 address 192.168.0.1 255.255.255.0 ipv6 address 2a01:e0a:159:2850::666 ffff:ffff:ffff:ffff:: ipv6 enable no shutdown no log-link-change exit ! interface sdn2 description freerouter@sdn2[ens10] mtu 9000 macaddr 020b.0000.2222 vrf forwarding v1 ipv4 address 192.168.1.1 255.255.255.0 ipv6 address 2a01:e0a:159:2850::777 ffff:ffff:ffff:ffff:: ipv6 enable no shutdown no log-link-change exit ! server telnet tel security protocol telnet no exec authorization no login authentication vrf v1 exit ! server p4lang p4 export-vrf v1 1 export-port sdn1 0 10 export-port sdn2 1 10 interconnect ethernet0 vrf v1 exit ! client tcp-checksum transmit ! endこの設定の中の以下にて、sdn1をTofinoモデルのPort 0、sdn2をPort 1に対応させています。
server p4lang p4 export-vrf v1 1 export-port sdn1 0 10 export-port sdn2 1 10 interconnect ethernet0 vrf v1
Tofinoモデルのインタフェースの準備
以下のshellスクリプトにてインタフェースを準備します。veth250、veth251はTofinoモデルのCPUポートとpcapInt.binをつなぐpeer仮想インタフェースです。ens9、ens10はKVMホストマシンに作ったbridgeのnet01、net02に接続されている仮想マシン内のインタフェースです。#! /bin/bash echo 1 > /proc/sys/net/ipv6/conf/all/disable_ipv6 echo 1 > /proc/sys/net/ipv6/conf/default/disable_ipv6 ip link add veth251 type veth peer name veth250 ip link set veth250 up ip link set veth251 up ifconfig ens9 promisc ifconfig ens10 promisc ifconfig veth250 promisc ifconfig veth251 promisc ip link set dev veth250 up mtu 10240 ip link set dev veth251 up mtu 10240 ip link set dev ens9 up mtu 4096 ip link set dev ens10 up mtu 4096 export TOE_OPTIONS="rx tx sg tso ufo gso gro lro rxvlan txvlan rxhash" for TOE_OPTION in $TOE_OPTIONS; do /sbin/ethtool --offload veth250 "$TOE_OPTION" off &> /dev/null /sbin/ethtool --offload veth251 "$TOE_OPTION" off &> /dev/null /sbin/ethtool --offload ens9 "$TOE_OPTION" off &> /dev/null /sbin/ethtool --offload ens10 "$TOE_OPTION" off &> /dev/null done
Tofinoモデルのポート設定
RAREを起動する際の、設定ファイルやログファイルの置き場所を用意します。mkdir -p ~/rare-run/etc ~/rare-run/logs ~/rare-run/mibs ~/rare-run/snmpその上で、以下のようにTofinoモデルのポート番号0、1と仮想マシンのインタフェースens9、ens10のマッピングを定義します。
cat ~/rare-run/etc/ports.json { "PortToIf" : [ { "device_port" : 0, "if" : "ens9" }, { "device_port" : 1, "if" : "ens10" }, { "device_port" : 64, "if" : "veth250" } ] }以上にて、ツールのインストールと初期設定は完了です。ここからツールを順次起動して、試験環境を構築していきます。
ツールの起動
freeRouterの起動
以下の通り、用意した二つの設定を指定して、freeRouterを起動します。freeRouterが起動すれば、別ターミナルにて"telnet localhost 2323"を実行することで、freeRouterのCLIに接続することが可能になります。~$ cd freeRouter/ ~/freeRouter$ java -jar lib/rtr.jar routersc etc/tna-freerouter-hw.txt etc/tna-freerouter-sw.txt ####### ################## ## ## ## ## # ## ### ##### ##### ## ### ## ## ### ## # ### ## ## ## ## ## ### ## ## ### ## #### ## ## ####### ####### ## ## ## ## ## ## # ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## #### ## ##### ##### ## ## ## freeRouter v20.12.23-rel, done by cs@nop. place on the web: http://www.freertr.net/ license: http://creativecommons.org/licenses/by-sa/4.0/ quote1: make the world better quote2: if a machine can learn the value of human life, maybe we can too quote3: be liberal in what you accept, and conservative in what you send quote4: the beer-ware license for selected group of people: cs@nop wrote these files. as long as you retain this notice you can do whatever you want with this stuff. if we meet some day, and you think this stuff is worth it, you can buy me a beer in return info cfg.cfgInit.doInit:cfgInit.java:632 booting info cfg.cfgInit.doInit:cfgInit.java:773 initializing hardware info cfg.cfgInit.doInit:cfgInit.java:779 applying defaults info cfg.cfgInit.doInit:cfgInit.java:786 applying configuration info cfg.cfgInit.doInit:cfgInit.java:816 boot completed welcome line ready tna-freerouter#
pcapInt.binの起動
別ターミナルを用意して、freeRouterとTofinoモデルのCPUポートの間のパケットの仲介を行うpcapInt.binを起動します。~$ cd freeRouter/bin/ ~/freeRouter/bin$ sudo ./pcapInt.bin veth251 22709 127.0.0.1 22710 127.0.0.1 binded to local port 127.0.0.1 22709. will send to 127.0.0.1 22710. pcap version: libpcap version 1.8.1 opening interface veth251 serving others >
Tofinoモデルを起動
別ターミナルを用意して、以下のように用意したポート設定を指定して、Tofinoモデルを起動します。なお、-pオプションのbf_routerはロードするビルド済みのP4プログラムの名前です(ログは割愛)。~$ cd $SDE adpro@RARE:~/bf-sde-9.2.0$ ./run_tofino_model.sh -p bf_router -f ~/rare-run/etc/ports.json --log-dir ~/rare-run/logs/ -q
bfswitchdを起動
別ターミナルを用意して、Tofinoモデルと同様にP4プログラム名として、bf_routerを指定して、bfswitchdを起動します(ログは割愛)。~$ cd ~/rare-run/logs/ adpro@RARE:~/rare-run/logs$ $SDE/run_switchd.sh -p bf_router
bf_forwarder(コントロールプレーン)の起動
最後に、別ターミナルにてbf_forwarderを起動します。~$ cd ~/rare/bfrt_python/ adpro@RARE:~/rare/bfrt_python$ ./bf_forwarder.py --ifmibs-dir ~/rare-run/mibs/ --ifindex ~/rare-run/snmp/ifindex sal import failed bf_forwarder.py running on: WEDGE100BF32X GRPC_ADDRESS: 127.0.0.1:50052 P4_NAME: bf_router CLIENT_ID: 0 Subscribe attempt #1 Subscribe response received 0 Received bf_router on GetForwarding Binding with p4_name bf_router Binding with p4_name bf_router successful!! bf_switchd started with no SNMP export Clearing Table pipe.ig_ctl.ig_ctl_mpls.tbl_mpls_fib Clearing Table pipe.ig_ctl.ig_ctl_ipv4.tbl_ipv4_fib_host Clearing Table pipe.ig_ctl.ig_ctl_ipv6.tbl_ipv6_fib_host Clearing Table pipe.ig_ctl.ig_ctl_mpls.tbl_mpls_fib_decap Clearing Table pipe.ig_ctl.ig_ctl_nexthop.tbl_nexthop Clearing Table pipe.ig_ctl.ig_ctl_vlan_out.tbl_vlan_out Clearing Table pipe.ig_ctl.ig_ctl_vlan_in.tbl_vlan_in Clearing Table pipe.ig_ctl.ig_ctl_ipv4.tbl_ipv4_fib_lpm Clearing Table pipe.ig_ctl.ig_ctl_ipv6.tbl_ipv6_fib_lpm Clearing Table pipe.ig_ctl.ig_ctl_vrf.tbl_vrf ...これで、RAREの実験をするために必要なツールが全て起動しました。
ホスト間の通信確認
ping通信確認
host1からfreeRouterのsdn1ポート(192.168.0.1)へのpingが成功することを確認しました。~$ sudo ip netns exec host1 ping 192.168.0.1 -c 1 PING 192.168.0.1 (192.168.0.1) 56(84) bytes of data. 64 bytes from 192.168.0.1: icmp_seq=1 ttl=255 time=82.5 ms --- 192.168.0.1 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 82.532/82.532/82.532/0.000 ms同様にhost2からfreeRouterのsdn2ポート(192.168.1.1 )へのpingも成功しました。
~$ sudo ip netns exec host2 ping 192.168.1.1 -c 1 PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data. 64 bytes from 192.168.1.1: icmp_seq=1 ttl=255 time=79.1 ms --- 192.168.1.1 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 79.126/79.126/79.126/0.000 msまた、host1 -> freeRouter -> host2(192.168.1.101)のpingも成功しました。
~$ sudo ip netns exec host1 ping 192.168.1.101 -c 1 PING 192.168.1.101 (192.168.1.101) 56(84) bytes of data. 64 bytes from 192.168.1.101: icmp_seq=1 ttl=64 time=46.3 ms --- 192.168.1.101 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 46.356/46.356/46.356/0.000 ms最後に、host2 -> freeRouter -> host1(192.168.0.101)のpingも成功することを確認しました。
~$ sudo ip netns exec host2 ping 192.168.0.101 -c 1 PING 192.168.0.101 (192.168.0.101) 56(84) bytes of data. 64 bytes from 192.168.0.101: icmp_seq=1 ttl=64 time=39.3 ms --- 192.168.0.101 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 39.389/39.389/39.389/0.000 msfreeRouterのCLIにて、host1とhost2のARP情報が登録されていることが確認できます。この情報はbf_forwarderを介して、TofinoモデルのP4プログラムにも反映されているため、host1とhost2の通信が成立します。
tna-freerouter#show ipv4 arp sdn1 mac address time static 06eb.a2b5.52ab 192.168.0.101 00:02:45 false tna-freerouter#show ipv4 arp sdn2 mac address time static d29c.685e.9b0f 192.168.1.101 00:00:48 false
まとめ
RAREをTofinoモデルで動作させるための環境構築の方法をご紹介させていただきました。今回のTofinoモデルを使いましたが、Wedge100BF-32XなどのTofinoデバイスを搭載したハードウェアスイッチでもRAREを動作させることができます。本記事ではRAREの動作環境を構築することに主眼を置いて紹介させていただきましたが、RAREのP4プログラムやコントロールプレーンの実装方法については、日本P4ユーザ会にて解説ページを後日掲載する予定です。
日本P4ユーザ会 技術コンテンツ
ここまで読み進めていただき、ありがとうございました。