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

BPFの現在

kwi
January 13, 2017

 BPFの現在

Linux eBPFをネットワーク機能まわりで使う使い方について。

kwi

January 13, 2017
Tweet

More Decks by kwi

Other Decks in Technology

Transcript

  1. BPF の現在
    Kawai, Hiroaki

    View Slide

  2. cBPF, eBPF
    ● BPF = Berkeley Packet Filter
    ● cBPF = Classic BPF
    – eBPF と区別するとき
    ● tcpdump/libpcap
    – フィルタ式
    – nfbpf_compile
    [email protected]:~# tcpdump -d arp
    (000) ldh [12]
    (001) jeq #0x806 jt 2 jf 3
    (002) ret #262144
    (003) ret #0
    [email protected]:~# tcpdump -dd arp
    { 0x28, 0, 0, 0x0000000c },
    { 0x15, 0, 1, 0x00000806 },
    { 0x6, 0, 0, 0x00040000 },
    { 0x6, 0, 0, 0x00000000 },
    [email protected]:~# tcpdump -ddd arp
    4
    40 0 0 12
    21 0 1 2054
    6 0 0 262144
    6 0 0 0

    View Slide

  3. cBPF
    ● フィルタ式
    – pcap_compile
    ● C macro (linux/filter.h)
    – ex: BPF_STMT(BPF_LD | BPF_IMM, 1)
    ● libseccomp
    – ex: seccomp_rule_add(SCMP_ACT_ALLOW,
    SCMP_SYS(close), 0);

    View Slide

  4. eBPF
    ● eBPF = 命令セットとして整備(別物)
    – ISA (Instruction Set Architecture)
    – 64bit(x86_64, ARM64と整ってきたので)
    ● JIT in kernel
    – CPU 命令セットにマッピング
    – cBPF も eBPF 経由で JIT される
    https://events.linuxfoundation.org/sites/events/files/slides/ebpf_on_the_mainframe_lcon_2015.pdf

    View Slide

  5. eBPF compiler
    ● フィルタ式 = DSL から C 言語(限定版)へ
    ● clang でコンパイル
    – eBPF / ELF オブジェクトファイル
    – tc はこれを使ったりする
    clang -O2 -emit-llvm -c bpf.c -o - \
    | llc -march=bpf -filetype=obj -o bpf.o
    Ref: samples/bpf/README.rst

    View Slide

  6. LLVM_P4
    ● P4実行環境としてのeBPF
    – CではなくP4で
    # p4llvm switch1.p4
    # opt –O2 switch1.ll –o switch1.ll
    # llc –march=bpf –filetype=obj –o switch1.o switch1.ll
    # tc qdisc add dev eth3 ingress
    # tc filter add dev eth3 parent ffff: bpf obj switch1.o exp /tmp/p4cli
    https://schd.ws/hosted_files/2016p4workshop/1d/Intel%20Fastabend-P4%20on%20the%20Edge.pdf

    View Slide

  7. 実行環境
    ● Linux kernel
    – socket filter
    – seccomp2
    – tc filter&action, iptables bpf module
    – tracing, perf
    – cgroup
    ● Userland
    – iovisor/ubpf (Big switch)
    Chrome : packet=syscall引数
    tcpdump
    libpcap
    iovisor

    View Slide

  8. Load into kernel
    ● 設定方法
    – cBPF Bytecode バイト列を設定する
    ● cBPF (w/ extension) Bytecode は内部で eBPF 化
    – eBPF/ELF ファイルから読み込む
    ● Persistent (pinned) bpf object
    – Kernel /sys/fs/bpf で保持できる
    – “FD” が出てきたらこれを指していることも

    View Slide

  9. networking
    ● socket : ingress only, cBPF & eBPF
    ● tc : ingress & egress, cBPF & eBPF
    ● iptables(netfilter) xt_bpf : socket 相当
    ● xdp : ingress only, eBPF
    ● Lwt : pinned bpf, eBPF
    新しいkernelでないと
    ダメなやつも多々…

    View Slide

  10. Linux kernel
    ● setsockopt SOL_SOCKET SO_ATTACH_BPF
    – SO_ATTACH_FILTER : cBPF
    ● rtnetlink
    – struct tcmsg/TCA_KIND=”bpf”, TCA_ACT_BPF
    – stcuct ifinfomsg/IFLA_XDP
    – struct rtmsg/LWT_BPF_IN, LWT_BPF_OUT, …
    ● bpf(2) : fd 使う

    View Slide

  11. bpf_prog_type
    ● in-kernel での制限チェックで使われる
    ● Packet data にアクセスできるか等
    ● きちんと完了するプログラムか等
    ● BPF fd の属性値として保持される
    ● linux/bpf.h
    – BPF_PROG_TYPE_*
    – fdinfo (4.8~)
    SOCKET_FILTER
    KPROBE
    SCHED_CLS, SCHED_ACT
    TRACEPOINT
    XDP
    PERF_EVENT
    CGROUP_SKB, CGROUP_SOCK
    LWT_IN, LWT_OUT, LWT_XMIT

    View Slide

  12. eBPF in C
    ● 引数と返値
    – tc : struct __sk_buff
    ● filter classifier と filter action で返値の意味が異なる
    – xdp : struct xdp_md : sk_buff に似せてある
    ● BPF MAP
    – パケット数えたり
    – ルールを保持したり

    View Slide

  13. BPF MAP
    ● 種類
    – BPF_TABLE

    BPF_HASH

    BPF_HISTOGRAM

    BPF_STACK_TRACE
    – BPF_TABLE_PUBLIC
    – BPF_PERF_OUTPUT
    – BPF_PERF_ARRAY
    [email protected]:/proc/3463/fd# ls -l
    total 0
    lrwx------ 1 root root 64 Dec 22 02:21 0 -> /dev/pts/17
    lrwx------ 1 root root 64 Dec 22 02:21 1 -> /dev/pts/17
    lrwx------ 1 root root 64 Dec 22 02:21 10 -> anon_inode:bpf-map
    lrwx------ 1 root root 64 Dec 22 02:21 11 -> anon_inode:bpf-map
    lrwx------ 1 root root 64 Dec 22 02:21 12 -> anon_inode:bpf-prog
    lrwx------ 1 root root 64 Dec 22 02:21 13 -> anon_inode:bpf-prog
    lrwx------ 1 root root 64 Dec 22 02:21 14 -> anon_inode:bpf-prog
    lrwx------ 1 root root 64 Dec 22 02:21 15 -> anon_inode:bpf-prog
    lrwx------ 1 root root 64 Dec 22 02:21 2 -> /dev/pts/17
    lr-x------ 1 root root 64 Dec 22 02:21 3 -> /dev/urandom
    lr-x------ 1 root root 64 Dec 22 02:21 4 -> pipe:[35440]
    l-wx------ 1 root root 64 Dec 22 02:21 5 -> pipe:[35440]
    lrwx------ 1 root root 64 Dec 22 02:21 6 -> socket:[35441]
    lr-x------ 1 root root 64 Dec 22 02:21 7 -> pipe:[35442]
    l-wx------ 1 root root 64 Dec 22 02:21 8 -> pipe:[35442]
    lrwx------ 1 root root 64 Dec 22 02:21 9 -> socket:[35443]

    View Slide

  14. Writing eBPF
    ● iovisor/bcc 使う(依存は増える)
    – BPF_MAP_GET_NEXT_KEY 無かったりとかもある
    ● tc filter classifier 使うのが現実的な選択
    ● C言語はコンパイラのココロを読みながら書く
    – prog_load失敗する=ココロが通じなかったとき
    ● bpf_trace_printk
    – cat /sys/kernel/debug/tracing/trace_pipe

    View Slide

  15. Tools
    ● ubpf-disassembler (ubpf)
    – eBPF
    ● bpfc (netsniff-ng)
    – cBPF (w/ extension)
    ● bpf_dbg (kernel)
    – eBPF

    View Slide