LinuxのBPFで何ができるのか? BPFの「プログラムタイプ」とは:Berkeley Packet Filter(BPF)入門(4)(1/2 ページ)
Linuxにおける利用が急速に増えている「Berkeley Packet Filter(BPF)」について、基礎から応用まで幅広く紹介する連載。今回は、BPFでできること、BPFのプログラムタイプについて。
Linuxにおける利用が急速に増えている「Berkeley Packet Filter(BPF)」について、基礎から応用まで幅広く紹介する連載「Berkeley Packet Filter(BPF)入門」。前回までは、BPFの基本やBPFのプログラムの作成方法を説明しました。今回から、「LinuxのBPFで何ができるのか」について詳しく見ていきます。
なお本稿では、Linux 5.3のソースコードを参照しています。
BPFでできること
BPFプログラム実行の流れをおさらいしましょう。
ユーザーはBPFプログラムを作成し、システムコールを利用してそれをLinuxカーネル内に登録します(図の【1】)。そうして登録されたBPFプログラムは、対応するイベントが発生すると、Linuxの中で引数が1つ、戻り値も1つの関数として実行されます(図の【2】)。BPFプログラムは実行中にカーネル内のヘルパー関数を呼び出すことができます。例えば、ヘルパー関数を利用して「BPFマップ」と呼ばれるユーザー空間と共有できるデータ構造にアクセスすることが可能です(図の【3】)。
BPFプログラムの実行が終了すると、BPFプログラムの戻り値に応じてカーネルは処理を継続します。BPFプログラム自体は状態を持ちませんが、BPFマップを利用することで情報を記録できます。
このとき、「BPFが何を行うのか」「BPFで何ができるのか」は以下の項目で決まります。
- どこでBPFプログラムが呼び出されるのか
- どんな引数(コンテキスト)が渡されるのか
- BPFプログラム内から引数のポインタデータは変更可能か
- BPFから呼び出し可能なヘルパー関数(BPF_CALLできる関数)には何があるのか
- 戻り値はどのような意味を持つのか
LinuxのBPFには「プログラムタイプ」があり、そのプログラムタイプごとに上記の項目が定義されます。また、BPFをカーネル内にロードする際は、検証機はプログラムタイプに応じた検証を実施します。
BPFのプログラムタイプは「include/uapi/linux/bpf.h」で定義されています。
Linux 5.3で利用可能なBPFのプログラムタイプには、下記の26種類があります。
enum bpf_prog_type { BPF_PROG_TYPE_UNSPEC, BPF_PROG_TYPE_SOCKET_FILTER, BPF_PROG_TYPE_KPROBE, BPF_PROG_TYPE_SCHED_CLS, BPF_PROG_TYPE_SCHED_ACT, BPF_PROG_TYPE_TRACEPOINT, BPF_PROG_TYPE_XDP, BPF_PROG_TYPE_PERF_EVENT, BPF_PROG_TYPE_CGROUP_SKB, BPF_PROG_TYPE_CGROUP_SOCK, BPF_PROG_TYPE_LWT_IN, BPF_PROG_TYPE_LWT_OUT, BPF_PROG_TYPE_LWT_XMIT, BPF_PROG_TYPE_SOCK_OPS, BPF_PROG_TYPE_SK_SKB, BPF_PROG_TYPE_CGROUP_DEVICE, BPF_PROG_TYPE_SK_MSG, BPF_PROG_TYPE_RAW_TRACEPOINT, BPF_PROG_TYPE_CGROUP_SOCK_ADDR, BPF_PROG_TYPE_LWT_SEG6LOCAL, BPF_PROG_TYPE_LIRC_MODE2, BPF_PROG_TYPE_SK_REUSEPORT, BPF_PROG_TYPE_FLOW_DISSECTOR, BPF_PROG_TYPE_CGROUP_SYSCTL, BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE, BPF_PROG_TYPE_CGROUP_SOCKOPT, };
それぞれのプログラムタイプについて残念ながら、「何が引数として与えられるのか」「戻りは何を意味するのか」などの情報はあまりまとまっていません。カーネルのサンプルプログラムを見たり、ヘルパー関数の引数から推測したり、カーネルのソースを直接確認したりするといいでしょう。
それぞれのプログラムタイプで利用可能なヘルパー関数に関しては下記に情報があります。
以降、主要なプログラムタイプについて、どこで何に利用されているのか見ていきます。
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
- 2018年上半期に話題になったSpectreとその変異、Linuxカーネルでの対応まとめ
連載「OSS脆弱性ウォッチ」では、さまざまなオープンソースソフトウェアの脆弱性に関する情報を取り上げ、解説していく。2018年の上半期は、「Meltdown」「Spectre」とその変異(Variant)の脆弱性に悩まされた。今回はいつもとは異なり、上半期のまとめも兼ねて、Meltdown/Spectreの各変異をバージョンを追いかけながら整理する。 - 2017年版Linuxカーネル開発レポート公開――支援している企業トップ10とは?
The Linux Foundationは2017年版Linuxカーネル開発レポートを公開した。Linuxカーネル4.8から4.13までの開発に焦点を当て、カーネル開発に携わった開発者や変更数などについて言及した。 - Linuxカーネルのソースコードを読んで、システムコールを探る
C言語の「Hello World!」プログラムで使われる、「printf()」「main()」関数の中身を、デバッガによる解析と逆アセンブル、ソースコード読解などのさまざまな側面から探る連載。前回まで、printf()内の中身をさまざまな方法で探り、write()やint $0x80の呼び出しまでたどり着いた。今回は、さらにその先にあるLinuxカーネル側のシステムコールを見ていく。