パケットをカウントするために、次の eBPF プログラムを作成しました。
#include <linux/version.h>
#include <uapi/linux/bpf.h>
#include "include/bpf_map.h"
#include "include/bpf_helpers.h"
struct bpf_map_def SEC("maps/count") count_map = {
.type = BPF_MAP_TYPE_ARRAY,
.key_size = sizeof(int),
.value_size = sizeof(__u64),
.max_entries = 1024,
};
SEC("cgroup/skb")
int count_packets(struct __sk_buff *skb) {
char debug[] = "count_packets\n";
bpf_trace_printk(debug, sizeof(debug));
int packets_key = 0;
__u64 *packets = 0;
packets = bpf_map_lookup_elem(&count_map, &packets_key);
if (packets == 0)
return 0;
*packets += 1;
// allow access
return 1;
}
char _license[] SEC("license") = "GPL";
u32 _version SEC("version") = LINUX_VERSION_CODE;
また、プログラムを としてロードし、 attach type を使用BPF_PROG_TYPE_CGROUP_SKB
して v2 cgroup ( ) にアタッチし、独自の PID をその cgroup に追加して、ネットワーク トラフィックの作成を開始するユーザー空間コンポーネントもあります。/sys/fs/cgroup/unified/foo
BPF_CGROUP_INET_EGRESS
このユーザー空間コンポーネントをコンテナーの外で実行すると、期待どおりに動作し、実行によってプログラムが呼び出されていることがわかりますcat /sys/kernel/debug/tracing/trace_pipe
。
ただし、コンテナー内でプログラムを実行すると、出力が表示されません。
次のようにコンテナを実行しています。
docker run -it \
--privileged \
--pid=host \
--net=host \
-v /sys/fs/cgroup/unified:/sys/fs/cgroup/unified \
${IMAGE}
ホスト ネットワークと PID 名前空間を使用して、それ以外の場合に発生する可能性のある問題を回避しています。
私のプログラムがコンテナー内から動作しないように見えるのはなぜですか?
uname -a
: Linux ubuntu-bionic 4.18.0-16-generic #17~18.04.1-Ubuntu SMP Tue Feb 12 13:35:51 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux