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 full-size slide

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

    View full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size slide

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

    View full-size 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 full-size 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 full-size 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 full-size slide

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

    View full-size slide

  13. BPF MAP
    ● 種類
    – BPF_TABLE

    BPF_HASH

    BPF_HISTOGRAM

    BPF_STACK_TRACE
    – BPF_TABLE_PUBLIC
    – BPF_PERF_OUTPUT
    – BPF_PERF_ARRAY
    root@ubuntu:/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 full-size 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 full-size slide

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

    View full-size slide