JANOG45 パケット処理の独自実装や高速化手法の比較と実践 独自パケット処理の実装方法の解説(XDP)

>100 Views

January 24, 20

スライド概要

JANOG45 パケット処理の独自実装や高速化手法の比較と実践 の登壇資料です。
https://www.janog.gr.jp/meeting/janog45/program/pktfwd/
https://www.janog.gr.jp/meeting/janog45/application/files/1615/7984/1029/008_pktfwd-xdp_kusakabe_00.pdf

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

パケット処理の独自実装や高速化手法の 比較と実践 独自パケット処理の実装方法の解説(XDP) 日下部雄也 BBSakura Networks株式会社 小樽市在住 パケット処理の独自実装や高速化手法の比較と実践| JANOG45@札幌|2020/01/24

2.

XDPとは Application Userspace AF_XDP Socket Socket Protocol Stack Kernel XDP_REDIRECT XDP_PASS eBPF Map XDP XDP_DROP Driver XDP_REDIRECT XDP_TX HW NIC NIC ※XDP_REDIRECTはbpf_redirect(), bpf_redirect_map()を経由して使う パケット処理の独自実装や高速化手法の比較と実践| JANOG45@札幌|2020/01/24

3.

ユースケース(再掲) ● ● ● ● ● ● ● bpfilter: iptablesをXDPにオフロード Cloudflare(DDoS Mitigation) Facebook(Katran): L4LB Cilium: Kubernetes上での透過的なセキュリティ、ネットワーク、LB XFLAG(Static NATなど) LINE(L4LB, SRv6) BBSakura Networks(Mobile Core) ○ ○ ● ● さくらのクラウドで XDPを使えるようになっている サーバのタグに @nic-double-queue と入れると使える OvS-AF_XDP DPDK-AF_XDP パケット処理の独自実装や高速化手法の比較と実践| JANOG45@札幌|2020/01/24

4.

XDPで使える機能(関数) ● bpf_map_{lookup,update,delete}_elem ○ ● bpf_fib_lookup ○ ● ● eBPF Mapの参照、更新、削除 FIB(Forwarding Information Base、ルーティングテーブル )の参照 bpf_xdp_adjust_head ○ パケットデータの先頭をずらす ○ encap/decapで使う bpf_xdp_adjust_tail ○ パケットデータの末尾をずらす ○ パケットのヘッダだけ欲しいときに使うらしい (例: XFLAG ペイロードカッター )

5.

XDPで使える機能(関数) ● ● bpf_xdp_adjust_meta ○ パケットデータの先頭にメタデータの領域を確保する ○ XDP_PASS後にtc-bpfでskb->markに入れてtcやiptablesと連携するのによく使う ○ ちなみにvirtio_netなど非対応NICが多いので注意 ○ ■ xdp_set_data_meta_invalidでdriversフォルダをgrepするとわかる ■ virtio_netのパッチはある 4.18まではVLANのパケットだと動かなかったが 4.19から直ってる bpf_tail_call ○ 別のプログラムを呼んで引き続きパケットを処理させる ○ xdpcapのようなキャプチャ用のプログラムや、メトリクス収集用、フィルタだけ先にやりたいので独 立させるなどの用途がある ○ プログラムの命令数制限が緩和されたのと有限ループがサポートされたのでプログラムが大きくて 渋々分けてtail_callというのはなくなりそう

6.

XDPで使えるeBPF Mapの種類 ● 普通のMap ○ ○ ○ ○ ○ ○ ● Map in Map ○ ○ ● BPF_MAP_TYPE_ARRAY_OF_MAPS BPF_MAP_TYPE_HASH_OF_MAPS 特殊なMap ○ ○ ○ ○ ○ ○ ● BPF_MAP_TYPE_HASH BPF_MAP_TYPE_ARRAY BPF_MAP_TYPE_PERCPU_HASH: PERCPUなのでロックがなくなり性能が良い BPF_MAP_TYPE_PERCPU_ARRAY BPF_MAP_TYPE_LRU_HASH: LRU(マップが溢れたときにあまり使われないデータから消してくれる) BPF_MAP_TYPE_LRU_PERCPU_HASH BPF_MAP_TYPE_LPM_TRIE: ルートテーブルのようなテーブルを作りたいときに使う BPF_MAP_TYPE_PROG_ARRAY: bpf_tail_callで使う BPF_MAP_TYPE_PERF_EVENT_ARRAY: ユーザスペースに対してイベントを送りたいときに使う BPF_MAP_TYPE_DEVMAP: XDP_REDIRECTで別のNICにパケットを渡すときに使う BPF_MAP_TYPE_CPUMAP: XDP_REDIRECTで別のCPUにパケットを渡すときに使う BPF_MAP_TYPE_XSKMAP: AF_XDPで使う 使い方はLinuxの samples/bpf

7.

開発の流れ 1. わりと制限のあるCでソースコードを書く 2. LLVMを使ってバイトコードにコンパイル 3. コンパイルしたオブジェクトファイルをNICにアタッチ

8.

わりと制限のあるC ● 命令数制限 ○ 4.13までは4096 ○ 4.14から128K https://patchwork.ozlabs.org/patch/798665/ ○ 5.3から1M https://patchwork.ozlabs.org/patch/1073794/ ○ ※iproute2でロードしたときは今のところ、常に 4096まで https://git.kernel.org/pub/scm/network/iproute2/iproute2.git/tree/lib/bpf.c?h=v5.4.0&#n305 ● ● ループ制限 ○ 無限ループは禁止 ○ 5.2から有限ループ OK https://lwn.net/Articles/794934/ ○ 5.1まではunrollする必要がある ←プログラムサイズが大きくなりがち その他 ○ 到達不可能な命令がないこと ○ 有効なメモリにのみアクセスする(明示的に有効かどうかのチェックが必要)

9.

コンパイル方法 ● ● シンプルなプログラムの場合 ○ clang -O2 -target bpf -c example.c -o example.o ○ ただし、 linux/if_ether.h などをincludeしたらエラーになるため、ほぼ使えない 実用的なプログラムの場合 ○ clang -I./include -DDEBUG -D__KERNEL__ -Wno-unused-value -Wno-pointer-sign -Wno-compare-distinct-pointer-types -O2 -emit-llvm -c -g src/example.c -o -| llc -march=bpf -filetype=obj -o src/example.o ○ ● サンプル https://github.com/higebu/ebpf-template BCCの場合はソースを読み込むのが普通 ○ 詳細はリンク先参照 パケット処理の独自実装や高速化手法の比較と実践| JANOG45@札幌|2020/01/24

10.

テスト ● BPF_PROG_TEST_RUNを使うと実際にNICにアタッチすることなくテストすること ができる ● libbpfを使った場合の例 ○ ● https://github.com/higebu/ebpf-template/blob/master/test/test_xdp.c ただし、カーネルのバージョンや、NICのドライバによって、対応している機能が異 なっていたり、特有のバグがあったりするので、本番で動かす前には必ず本番と同 じ環境でテストする パケット処理の独自実装や高速化手法の比較と実践| JANOG45@札幌|2020/01/24

11.

デバッグ方法 ● llvm-objdump -S --no-show-raw-insn example.o ○ Verifierに怒られたときはとりあえずこれ ○ clangでコンパイルするときに -g を付けていればバイトコードに 対応したソースコードも表示される ● bpf_trace_printk() ○ 性能に影響があるので、本番用のプログラムでは実行されな いようにする ○ 普段は trace-cmd record -e 'xdp:*' -O trace_printk という 感じで出力された trace.dat をkernelsharkで見ている ○ trace-cmd stream は動かないことが多い。。。 パケット処理の独自実装や高速化手法の比較と実践| JANOG45@札幌|2020/01/24

12.

アタッチの前に気をつけること ● 本番では /proc/sys/net/core/bpf_jit_enable を 1 にしておく ● フォワーディングするプログラムでは /proc/sys/net/ipv4.ip_forward や /proc/sys/net/ipv6/conf/all/forwarding を 1 にしておく ● ethtool -L eth0 combined 2 のようにしてNICのキューの数を調整しておく ● ethtool -kで有効なオフロード機能を確認し、-Kでオフにしておく ● MapはLocked Memoryを使うため、ulimit -l unlimitedやsystemdのunitファイル でLimitMEMLOCK=infinityしておく(デフォルトは64KB) ● オブジェクトをPinしたいときはbpffsをマウントしておく mount bpffs /sys/fs/bpf -t bpf パケット処理の独自実装や高速化手法の比較と実践| JANOG45@札幌|2020/01/24

13.

アタッチ/デタッチ ● iproute2の場合 ○ ○ ● libbpfの場合 ○ ○ ● ip link set dev eth0 xdp obj example.o sec xdp_prog ip link set dev eth0 xdp off bpf_prog_load()でロードして、 bpf_set_link_xdp_fd()でアタッチ/デタッチ 参考 https://github.com/xdp-project/xdp-tutorial/blob/master/basic01-xdp-pass/xdp_pass_user.c bpftoolの場合(5.4以上 https://patchwork.ozlabs.org/cover/1145981/ ○ ○ ○ ○ bpftool prog load ./example.o /sys/fs/bpf/prog ■ CONFIG_DEBUG_INFO_BTF=yなカーネルでないと libbpfのエラー(22)が表示されるが ロードはされる bpftool prog list でidを確認 bpftool net attach xdp id 10 dev eth0 bpftool net detach xdp dev eth0 パケット処理の独自実装や高速化手法の比較と実践| JANOG45@札幌|2020/01/24

14.

アタッチ/デタッチ ● ● その他 ○ BCC ■ 便利なマクロなどが定義されていて、少しプログラムを書きやすい ■ トレーシング方面で使われている ■ 新機能を追えてないことがあるので注意 ○ iovisor/gobpf ■ Go言語で書かれた BCCのラッパー ■ cgoを使うことになるのと新機能を追えてないことがあるので注意 ○ newtools/ebpf ■ pure Goで、libbpfと同様のことができるライブラリ ■ libbpf経由でなく、直接 syscallを実行してロードしたりアタッチしたり Mapの読み書きをしたりで きる おすすめはbpftool、またはCなどからlibbpfを使う方法で、 CプレーンをGoで書く場合は、 newtools/ebpf パケット処理の独自実装や高速化手法の比較と実践| JANOG45@札幌|2020/01/24

15.

パケットキャプチャ ● 問題が起きたときやデバッグのために XDPで処理されたパケットをキャプチャしたくなりますが、カーネル が処理する前に落としたり、返したりしてしまうので、 tcpdumpでは追えない ● そこで、 xdpcap(https://github.com/cloudflare/xdpcap) を使う ● 詳しくはリンク先を参照 ● Wiresharkで見ると、プログラムのリターンコードもわかって便利 パケット処理の独自実装や高速化手法の比較と実践| JANOG45@札幌|2020/01/24

16.

コード解説(XDP編) パケット処理の独自実装や高速化手法の比較と実践| JANOG45@札幌|2020/01/24

17.

コード解説 大変申し訳ありませんが、動くコードを実装 できませんでした🙇🙇🙇 ※開発はアルバイトで来ている東北学院大学3年生の早坂彪流さ んにご協力いただきました。 ありがとうございました🙇🙇🙇 パケット処理の独自実装や高速化手法の比較と実践| JANOG45@札幌|2020/01/24

18.

コード解説 Endは動くのでEnd部分の解説をします ソー ス:https://github.com/takehaya/srv6-gtp/b lob/feature/t_m_GTP4_D/src/srv6.c パケット処理の独自実装や高速化手法の比較と実践| JANOG45@札幌|2020/01/24

19.

コード解説 パケットの先頭と末尾のポインタ ヘッダのパース パケット処理の独自実装や高速化手法の比較と実践| JANOG45@札幌|2020/01/24

20.

コード解説 パケットの先頭と末尾のポインタ ヘッダのパース パケット処理の独自実装や高速化手法の比較と実践| JANOG45@札幌|2020/01/24

21.

コード解説 IPv6で、nexthdrがNEXTHDR_ROUTING で、SEG6_LOCAL_ACTION_END のときにaction_end()を実行 パケット処理の独自実装や高速化手法の比較と実践| JANOG45@札幌|2020/01/24

22.

コード解説(End) SRヘッダのパースと内容チェック segmentのパース パケット書き換え及び REDIRECT パケット処理の独自実装や高速化手法の比較と実践| JANOG45@札幌|2020/01/24

23.

コード解説(REDIRECT辺り) bpf_fib_lookupしてる REDIRECT パケット処理の独自実装や高速化手法の比較と実践| JANOG45@札幌|2020/01/24

24.

コード解説(bpf_fib_lookup辺り) これが動かない パケット処理の独自実装や高速化手法の比較と実践| JANOG45@札幌|2020/01/24

25.

コード解説 プルリクエスト、アドバイス、お待ちしており ます🙇🙇🙇 パケット処理の独自実装や高速化手法の比較と実践| JANOG45@札幌|2020/01/24

26.

XDPの開発でつらかったところ ● ロード時のエラーがわかりにくい reference to missing symbolなどよくある ● 使っているカーネルのバージョンによってエラーの箇所が変わる ● bpf_trace_printkを足しただけでロードできなくなった printkの行とは関係ない箇所でreference to missing symbolになる ● netns内からbpffsをマウントできない→開発しづらい ● bpf_fib_lookupが動かないときに原因がわかりにくい v6のlookup結局動かなかった。。。 パケット処理の独自実装や高速化手法の比較と実践| JANOG45@札幌|2020/01/24

27.

以下おまけ パケット処理の独自実装や高速化手法の比較と実践| JANOG45@札幌|2020/01/24

28.

最近のXDP関連の開発の様子 ● bpf: add bpf_ct_lookup_{tcp,udp}() helpers ○ ● xdp: Introduce bulking for non-map XDP_REDIRECT Accepted ○ ● ● ● ● ● bpf_redirect_mapの方がbpf_redirectより速かったが、差がなくなる XDP in tx path RFC Introduce the BPF dispatcher Accepted xdp_flow: Flow offload to XDP RFC virtio_net XDP offload RFC Introduce XDP to ena ○ ● conntrack tableの参照ができるようになりそう EC2のElastic Network AdapterのXDP対応 sfc: Add XDP support ○ SolarflareのNICのXDP対応

29.

XDPを使うときによく見る資料 ● ● ● ● Cilium BPF and XDP Reference Guide Suricata eBPF and XDP Linux Documantation/bpf Linux samples/bpf ○ ● ● XDP Hands-On Tutorial BPF Features by Linux Kernel Version ○ ● ● この機能どのバージョンから使える?というときに見る Linux Observability with BPF(本) (sysdigのサイトに情報登録すると無料でダウン ロードできる) yunazuno.log ○ ● ● 見るときは使うカーネルのバージョンに合わせて見る 日本語で検索すると大抵このブログがヒットする @IT Berkeley Packet Filter(BPF)入門 あとはドライバなどのソースコードを見る。。。 パケット処理の独自実装や高速化手法の比較と実践| JANOG45@札幌|2020/01/24

30.

EOF パケット処理の独自実装や高速化手法の比較と実践| JANOG45@札幌|2020/01/24