Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

Wakamonog13 LT: VPPで始めるHigh Performance BGPルーター

Wakamonog13 LT: VPPで始めるHigh Performance BGPルーター

Wakamonog13 LTで話したVPPで始めるHigh Performance BGPルーターについてです。
イベントはこちら: https://wakamonog.connpass.com/event/304815/

Takeru Hayasaka

January 16, 2024
Tweet

More Decks by Takeru Hayasaka

Other Decks in Technology

Transcript

  1. 自己紹介 - はやさかたける(早坂彪流) - インターネットではtakemio,takehayaとか - さくらインターネットとBBSakura Networksに所属 - 京都市在住,

    宮城県出身,社会人3年目,25歳児 - 初めてのWakamonog参加 - 普段はモバイルコアの開発やってる - 最近の悩み: ルーターが高い
  2. VPPとは? - FD.ioでCisco主体で作ってるOSSのソフトウェアSwitch - Vector Packet Processingの略でパケット処理をベクトル単位で行うこと でCPUラインキャッシュの最適化をして高速化する手法名から来ている - DPDKを使ってるのでLinuxのプロトコルスタックよりも高速

    - OSSなので改造できて、自由度が高くて便利! - 自分も3つパッチを投げて取り込まれた - https://github.com/search?q=repo%3AFDio%2Fvpp+takeru+hayasaka&type=commits - いろんな会社さんが使ってる(使ってた) - 日本だとYahoo JAPAN!が載ってる - Dplaneの機能だけなので BGPとか自体は話すことができない -> FRRというdynamic routing suiteを使う (今日はそっちは何も説明しません...) - 従来のLinuxでFRRを使うよりも高速なルーター 実装が使えるってワケ 公式ホームページに書かれているユーザーたち 入れてもらったパッチたち
  3. VPPの問題点: Cplane動かない問題 - DPDKで書かれてる。即ちLinuxのプロトコルスタックでは無い。 - 従来のFRR, BIRD, GoBGP等のdynamic routing suiteはLinuxの

    プロトコルスタックをターゲットにしてる。しかしDPDKで書かれた VPPをターゲットにしてるわけでは無いので既存の環境に乗っかるの が難しい
  4. - https://github.com/pimvanpelt/lcpng - VPPとしてのIfaceとLinuxのIface等を ミラーリングするPlugin - 基本的にtap-injecterを使うのは同じ - netlinkを監視しhookすることでミラーを実現 -

    Iface以外にもVLANやVRFも対応してる - Linux上でIface のアドレスを追加したらそれが VPPで追従し、逆にVPPでアドレスを削除で Linuxも追従する。これは経路情報も同じように 行われる。 - つまり、FRR等Linuxしか対象にしてなかった モノでもミラーしてくれるので問題なく動く! 救世主: linux-cp(Linux Control Plane Integration) Linux CPの対応状況
  5. - linux-cp は IPng Networks という ドイツの小規模ISPの会社に中の人がいる - その会社のBGPルーターはなんと VPP

    + FRRで動いてるとのこと - cf. VPP Linux CP - Part7 - Juniperルーター買いたいけど、 そんな金はないが技術はあるのでVPPを しばき倒してなんとかしようと思いま す!(意訳)みたいなことを書いてて すごい。早くこれになりたい。 - cf. Introduction to IPng Networks 余談: linux-cpは実はproduction readyらしい プロダクションではどんな構成にし てるかを書いてておもろい
  6. - iproute2コマンドからVPPのFibに入るのか? - BGPで経路広報してみた時はどうか? - 他のルーティングプロトコルも動くか?(e.g. OSPF) 実験してみた VPP+FRR Node-01

    VPP+FRR Node-02 AS65001 AS65002 192.168.10.1 Area 0 192.168.10.2 実験トポロジー図 ⇐ 192.168.20.0/24をBGPで広報 192.168.30.0/24をOSPFで広報
  7. 有効化方法 - VPP自体はapt install で入れれる - cf. Ubuntu - Setup

    the FD.io Repository - FRRは apt で一発なのでよしなに入れる - BGPd, OSPFdも有効化する - startup.conf を入れて restart とりあえず最低限これだけ入れたら動く - vppctl で適用済みかチェックする plugin が load 済みならOK - nl: Netlinkを監視する これでlinux側の経路等の設定をミラーできる - cp: Ifaceの対応付けをする これでlinuxの持つIfaceとVPPのIfaceを対応 付けることができる(転送してくれる) - 困った時はcliリファレンスを見る sudo vim /etc/vpp/startup.conf - - - plugins { plugin dpdk_plugin.so { enable } plugin linux_nl_plugin.so { enable } plugin linux_cp_plugin.so { enable } } linux-cp { lcp-sync lcp-auto-subint } - - - $ sudo systemctl restart vpp $ sudo vppctl show plugins |grep linux_ 58. linux_nl_plugin.so 23.10-release linux Control Plane - Netlink listener 71. linux_cp_plugin.so 23.10-release Linux Control Plane - Interface Mirror plugin設定を入れて VPPを再起動してplugin reloadして  loadの状態を確認している様子 自動でlinuxとsync するか等を設定できる
  8. iproute2コマンドからVPPのFibに入るのか? - interfaceをlinuxで操作可能にする 設定を入れる - 内部的にはtapが生えてて以下のように GE0/4/0(VPP)<->tap1<->e0(Linux) - linuxからip addrを叩き込んでみる

    - VPP側のFIBをみるとちゃんとある! - つまりVPP, Linux双方向でミラー されてる $ sudo vppctl lcp create GigabitEthernet0/4/0 host-if e0 $ ip a show e0 4: e0: <BROADCAST,MULTICAST> mtu 9000 qdisc mq state DOWN group default qlen 1000 link/ether 9c:a3:ba:32:be:7c brd ff:ff:ff:ff:ff:ff $ sudo vppctl show int GigabitEthernet0/4/0 1 down 9000/0/0/0 tap1 2 up 9000/0/0/0 - - - $ sudo ip link set up dev e0 && sudo ip addr add 192.168.10.1/24 dev e0 && ip a show e0 4: e0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc mq state UP group default qlen 1000 inet 192.168.10.1/24 scope global e0 valid_lft forever preferred_lft forever (中略) - - - $ sudo vppctl show ip fib | grep GigabitEthernet0/4/0 [0] [@4]: ipv4-glean: [src:192.168.10.0/24] GigabitEthernet0/4/0: mtu:9000 next:1 flags:[] ffffffffffff9ca3ba3266ce0806 [0] [@13]: dpo-receive: 192.168.10.1 on GigabitEthernet0/4/0
  9. BGPで経路広報してみた時はどうか? - FRRでeBGP peerを張って、 192.168.20.0/24を広報してみる - VPPのFibをみると無事広報された経路 を使えるようになっている! router bgp

    65002 no bgp ebgp-requires-policy neighbor 192.168.10.1 remote-as 65001 ! address-family ipv4 unicast network 192.168.20.0/24 exit-address-family exit ! end sudo ip addr add 192.168.20.0/24 dev lo - - - $sudo vppctl show ip fib (中略) 192.168.20.0/24 unicast-ip4-chain [@0]: dpo-load-balance: [proto:ip4 index:17 buckets:1 uRPF:17 to:[0:0]] [0] [@5]: ipv4 via 192.168.10.2 GigabitEthernet0/4/0: mtu:9000 next:5 flags:[] 9ca3ba32be7c9ca3ba3266ce0800 Node02からBGPで経路広報して VPPのFibに入ってる様子 実験なのでloopback にとりあえず付ける
  10. 他のルーティングプロトコルも動くか?(e.g. OSPF) - FRRでOSPF peerを張って、 192.168.30.0/24を広報してみる - VPPのFibをみると無事広報された経路 を使えるようになっている! router

    ospf ospf router-id 192.168.10.2 network 192.168.10.0/24 area 0 network 192.168.30.0/24 area 0 exit sudo ip addr add 192.168.30.0/24 dev lo - - - $sudo vppctl show ip fib (中略) 192.168.30.0/32 unicast-ip4-chain [@0]: dpo-load-balance: [proto:ip4 index:18 buckets:1 uRPF:17 to:[0:0]] [0] [@5]: ipv4 via 192.168.10.2 GigabitEthernet0/4/0: mtu:9000 next:5 flags:[] 9ca3ba32be7c9ca3ba3266ce0800 Node02からOSPFで経路広報して VPPのFibに入ってる図
  11. フルルート叩き込んでみた - GoBGPとzebraを使って叩き込んでみる - Node2に対して直接叩き込んでみた - MRT Format(RFC6396)をGoBGPは直接読めるので フルルートを流すのにはFRR使うより便利 -

    BGPのフルルートはRoute Views Archive Projectで公開されて る。今回は以下を叩き込んだ - https://archive.routeviews.org/route-views.wide/bgpdata/2024.01/R IBS/rib.20240115.1600.bz2 - メモリ使用量的には12Gぐらい! - 余談 - 真面目にチューニングしないとVPPが死んでしまい、 全然うまくいかないのでhugepageやVPPのメモリ割り当てに注意 - おそらくはこういう理由 - mappingしているIfaceに対して経路を入れます - VPPに経路を叩き込みます - 大量の経路を叩き込んだ結果VPPが死にます - mappingしてるマネージャー(linux-cp)が死ぬのでIfaceも 死んで、Ifaceに紐づくので同時に経路も吹き飛びます😇 - ちゃんとフルルート食えたのでピアリングもできるね! gobgp mrt inject global rib.20240115.1600 --nexthop 192.168.10.2 --no-ipv6 --only-best - - - $ free -h total used free shared buff/cache available Mem: 62Gi 12Gi 48Gi 1.0Mi 1.0Gi 49Gi $sudo vppctl show fib mem |grep Entry | head -n 1 Entry 72 957207 / 957207 68918904/68918904 $sudo ip r | wc -l 957195 IPv4のBestpath だけを突っ込む linuxのfibとVPPのfibが(ほぼ) 一致してるので無事動いてる! (VPPの方にプリセット経路があるの で多くなる
  12. おまけ(VPP関連の設定例) memory { main-heap-size 1536M main-heap-page-size default-hugepage } buffers {

    buffers-per-numa 128000 default data-size 2048 page-size default-hugepage } statseg { size 1G page-size default-hugepage per-node-counters off } logging { default-log-level info default-syslog-log-level notice class linux-cp/if { rate-limit 10000 level debug syslog-level debug } class linux-cp/nl { rate-limit 10000 level debug syslog-level debug } } ## Reserve 6GB of memory for hugepages cat << EOF | sudo tee /etc/sysctl.d/80-vpp.conf vm.nr_hugepages=3072 vm.max_map_count=7168 vm.hugetlb_shm_group=0 kernel.shmmax=6442450944 EOF ## Set 64MB netlink buffer size cat << EOF | sudo tee /etc/sysctl.d/81-vpp-netlink.conf net.core.rmem_default=67108864 net.core.wmem_default=67108864 net.core.rmem_max=67108864 net.core.wmem_max=67108864 EOF sudo sysctl -p -f /etc/sysctl.d/80-vpp.conf sudo sysctl -p -f /etc/sysctl.d/81-vpp-netlink.conf netlinkとhugepageの設定例 vpp/startup.confの メモリ割り当て設定例 VPP Linux CP - Part7 を参考にしてる
  13. おまけ(GoBGP関連) cat <<EOF > /etc/gobgpd.conf [global.config] as = 65002 router-id

    = "192.168.10.2" [[neighbors]] [neighbors.config] peer-as = 65001 neighbor-address = "192.168.10.1" [zebra] [zebra.config] enabled = true url = "unix:/var/run/frr/zserv.api" redistribute-route-type-list = ["connect"] software-name = "frr8.1" version = 6 EOF GoBGPとZebraに関するコンフィグ - FRRのバージョンによって動作するか が決まるので注意 - 例えばFRR8.2と8.4.3で異なるとか なのでここではFRR8.1を利用してる - https://github.com/osrg/gobgp/issues/2681 #issuecomment-1678993198 - ちなみにフルルートを叩き込むと3回 に一回ぐらいはZebraとのやりとりが (ネゴシエーションはうまくいってそうな のに)失敗して上手く入らない時があるの で注意