Upgrade to Pro — share decks privately, control downloads, hide ads and more …

JANOG45 パケット処理の独自実装や高速化手法の比較と実践 独自パケット処理の実装方法...

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

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

Avatar for Yuya Kusakabe

Yuya Kusakabe

January 24, 2020
Tweet

More Decks by Yuya Kusakabe

Other Decks in Programming

Transcript

  1. XDPとは パケット処理の独自実装や高速化手法の比較と実践| JANOG45@札幌|2020/01/24 NIC Driver Protocol Stack Application Userspace Kernel

    HW XDP NIC XDP_PASS XDP_TX XDP_REDIRECT XDP_DROP XDP_REDIRECT Socket AF_XDP Socket ※XDP_REDIRECTはbpf_redirect(), bpf_redirect_map()を経由して使う eBPF Map
  2. ユースケース(再掲) パケット処理の独自実装や高速化手法の比較と実践| JANOG45@札幌|2020/01/24 • 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
  3. • bpf_map_{lookup,update,delete}_elem ◦ eBPF Mapの参照、更新、削除 • bpf_fib_lookup ◦ FIB(Forwarding Information

    Base、ルーティングテーブル )の参照 • bpf_xdp_adjust_head ◦ パケットデータの先頭をずらす ◦ encap/decapで使う • bpf_xdp_adjust_tail ◦ パケットデータの末尾をずらす ◦ パケットのヘッダだけ欲しいときに使うらしい (例: XFLAG ペイロードカッター) XDPで使える機能(関数)
  4. • 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というのはなくなりそう XDPで使える機能(関数)
  5. • 普通の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 • Map in Map ◦ BPF_MAP_TYPE_ARRAY_OF_MAPS ◦ BPF_MAP_TYPE_HASH_OF_MAPS • 特殊なMap ◦ 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 XDPで使えるeBPF Mapの種類
  6. • 命令数制限 ◦ 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する必要がある←プログラムサイズが大きくなりがち • その他 ◦ 到達不可能な命令がないこと ◦ 有効なメモリにのみアクセスする(明示的に有効かどうかのチェックが必要) わりと制限のあるC
  7. • シンプルなプログラムの場合 ◦ 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
  8. • 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
  9. • 本番では /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
  10. • iproute2の場合 ◦ ip link set dev eth0 xdp obj

    example.o sec xdp_prog ◦ ip link set dev eth0 xdp off • libbpfの場合 ◦ 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
  11. • その他 ◦ 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
  12. • 問題が起きたときやデバッグのために XDPで処理されたパケットをキャプチャしたくなりますが、カーネル が処理する前に落としたり、返したりしてしまうので、 tcpdumpでは追えない • そこで、 xdpcap(https://github.com/cloudflare/xdpcap) を使う •

    詳しくはリンク先を参照 • Wiresharkで見ると、プログラムのリターンコードもわかって便利 パケットキャプチャ パケット処理の独自実装や高速化手法の比較と実践| JANOG45@札幌|2020/01/24
  13. • ロード時のエラーがわかりにくい reference to missing symbolなどよくある • 使っているカーネルのバージョンによってエラーの箇所が変わる • bpf_trace_printkを足しただけでロードできなくなった

    printkの行とは関係ない箇所でreference to missing symbolになる • netns内からbpffsをマウントできない→開発しづらい • bpf_fib_lookupが動かないときに原因がわかりにくい v6のlookup結局動かなかった。。。 パケット処理の独自実装や高速化手法の比較と実践| JANOG45@札幌|2020/01/24 XDPの開発でつらかったところ
  14. • bpf: add bpf_ct_lookup_{tcp,udp}() helpers ◦ conntrack tableの参照ができるようになりそう • 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 ◦ EC2のElastic Network AdapterのXDP対応 • sfc: Add XDP support ◦ SolarflareのNICのXDP対応 最近のXDP関連の開発の様子
  15. • 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)入門 • あとはドライバなどのソースコードを見る。。。 XDPを使うときによく見る資料 パケット処理の独自実装や高速化手法の比較と実践| JANOG45@札幌|2020/01/24