bpf(2) - wariua/manpages-ko GitHub Wiki
bpf - ํ์ฅ BPF ๋งต๊ณผ ํ๋ก๊ทธ๋จ์ ๋ํ ๋ช ๋ น ์ํํ๊ธฐ
#include <linux/bpf.h>
int bpf(int cmd, union bpf_attr *attr, unsigned int size);
bpf()
์์คํ
ํธ์ถ์ ํ์ฅ ๋ฒํด๋ฆฌ ํจํท ํํฐ(extended Berkeley Packet Filter)์ ๊ด๋ จ๋ ๋ค์ํ ์์
์ ์ํํ๋ค. ํ์ฅ BPF(eBPF)๋ ๋คํธ์ํฌ ํจํท ํํฐ๋ง์ ์ฐ๋ ์๋์ ("์ ํต์ ") BPF(cBPF)์ ๋น์ทํ๋ค. cBPF ํ๋ก๊ทธ๋จ๊ณผ eBPF ํ๋ก๊ทธ๋จ ๋ชจ๋ ์ ์ฌ ์ ์ ์ปค๋์ด ์ ์ ๋ถ์์ ํ์ฌ ์คํ ์์คํ
์ ํด๋ฅผ ๋ผ์น์ง ์๋๋ก ํ๋ค.
eBPF๋ cBPF๋ฅผ ์ฌ๋ฌ ๋ฐฉ์์ผ๋ก ํ์ฅํ ๊ฒ์ด๋ค. (eBPF์์ ์ ๊ณตํ๋ BPF_CALL
๋ช
๋ น ์ฝ๋ ํ์ฅ์ ํตํด) ์ ํด์ง ์ปค๋ ๋ด ํจ์๋ค์ ํธ์ถํ ์ ์์ผ๋ฉฐ eBPF ๋งต ๊ฐ์ ๊ณต์ ์๋ฃ ๊ตฌ์กฐ์ ์ ๊ทผํ ์ ์๋ค.
eBPF ๋งต์ ๋ค์ํ ์ข ๋ฅ์ ๋ฐ์ดํฐ ์ ์ฅ์ ์ํ ๋ฒ์ฉ ์๋ฃ ๊ตฌ์กฐ์ด๋ค. ๋ฐ์ดํฐ ํ์ ๋ค์ ์ผ๋ฐ์ ์ผ๋ก ์ด์ง ๋ฐ์ดํธ ์ด๋ก ๋ค๋ฃจ๋ฉฐ, ๊ทธ๋์ ์ฌ์ฉ์๊ฐ ๋งต ์์ฑ ์์ ์ ํค์ ํฌ๊ธฐ์ ๊ฐ์ ํฌ๊ธฐ๋ฅผ ์ง์ ํ ๋ฟ์ด๋ค. ๋ค์ ๋งํด ๋งต์ด ์์ ๋ ๊ทธ ํค/๊ฐ์ ์ด๋ค ๊ตฌ์กฐ๋ ๊ฐ์ง ์ ์๋ค.
์ฌ์ฉ์ ํ๋ก์ธ์ค์์ (๋ถํฌ๋ช ๋ฐ์ดํฐ์ธ ํค/๊ฐ ์์ ๊ฐ์ง) ์ฌ๋ฌ ๋งต์ ๋ง๋ค๊ณ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ ํตํด ์ ๊ทผํ ์ ์๋ค. ์ฌ๋ฌ eBPF ํ๋ก๊ทธ๋จ๋ค์ด ๊ฐ์ ๋งต์ ๋ณ๋ ฌ๋ก ์ ๊ทผํ ์ ์๋ค. ๋งต ์์ ๋ฌด์์ ์ ์ฅํ ์ง๋ ์ฌ์ฉ์ ํ๋ก์ธ์ค์ eBPF ํ๋ก๊ทธ๋จ์ ๊ฒฐ์ ์ ๋ฌ๋ ค ์๋ค.
ํน์ํ ์ข
๋ฅ์ ๋งต์ด ํ๋ ์๋๋ฐ, ํ๋ก๊ทธ๋จ ๋ฐฐ์ด์ด๋ผ๋ ๊ฒ์ด๋ค. ์ด ๋งต์ ๋ค๋ฅธ eBPF ํ๋ก๊ทธ๋จ๋ค์ ๊ฐ๋ฆฌํค๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ค์ ์ ์ฅํ๋ค. ๊ทธ ๋งต์์ ํ์ ์ํ ์ ํ๋ก๊ทธ๋จ ํ๋ฆ์ด ๋ค๋ฅธ eBPF ํ๋ก๊ทธ๋จ์ ์์์ ์ผ๋ก ๊ทธ๋๋ก ์ฎ๊ฒจ์ง๋ฉฐ ํธ์ถ ํ๋ก๊ทธ๋จ์ผ๋ก ๋๋์ ์ค์ง ์๋๋ค. ๋ค์ด๊ฐ๋ ๊น์ด์ 32๋ฒ์ด๋ผ๋ ๊ณ ์ ์ ํ์ด ์์ด์ ๋ฌดํ ๋ฃจํ๊ฐ ์๊ธธ ์ ์๊ฒ ํ๋ค. ๋ฐํ์์ ๋งต์ ์ ์ฅ๋ ํ๋ก๊ทธ๋จ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ค์ ๋ณ๊ฒฝํ ์ ์์ผ๋ฏ๋ก ๊ตฌ์ฒด์ ์๊ตฌ์ ๋ฐ๋ผ ํ๋ก๊ทธ๋จ ๊ธฐ๋ฅ์ ๋ฐ๊ฟ ์ ์๋ค. ํ๋ก๊ทธ๋จ ๋ฐฐ์ด ๋งต์์ ์ฐธ์กฐํ๋ ๋ชจ๋ ํ๋ก๊ทธ๋จ์ bpf()
๋ฅผ ํตํด ์ปค๋๋ก ๋ฏธ๋ฆฌ ์ ์ฌํด ๋์ด์ผ ํ๋ค. ๋งต ํ์์ด ์คํจํ๋ฉด ํ์ฌ ํ๋ก๊ทธ๋จ์ด ์คํ์ ๊ณ์ํ๋ค. ๋ ์์ธํ ๊ฑด ์๋์ BPF_MAP_TYPE_PROG_ARRAY
์ค๋ช
์ ๋ณด๋ผ.
์ผ๋ฐ์ ์ผ๋ก eBPF ํ๋ก๊ทธ๋จ์ ์ฌ์ฉ์ ํ๋ก๊ทธ๋จ์ ์ํด ์ ์ฌ๋๋ฉฐ ๊ทธ ํ๋ก์ธ์ค๊ฐ ๋๋ ๋ ์๋์ผ๋ก ๋ด๋ ค๊ฐ๋ค. tc-bpf(8) ๊ฐ์ ์ผ๋ถ ๊ฒฝ์ฐ์์๋ ํ๋ก๊ทธ๋จ์ ์ ์ฌํ ํ๋ก์ธ์ค๊ฐ ๋๋ ํ์๋ ํ๋ก๊ทธ๋จ์ด ์ปค๋ ๋ด์ ๊ณ์ ์ด์ ์๋ค. ๊ทธ ๊ฒฝ์ฐ์๋ ์ฌ์ฉ์ ๊ณต๊ฐ ํ๋ก๊ทธ๋จ์ด ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ ๋ซ์ ํ์ tc ์๋ธ์์คํ
์ด eBPF ํ๋ก๊ทธ๋จ์ ๋ํ ์ฐธ์กฐ๋ฅผ ์ก๊ณ ์๋๋ค. ์ฆ, ํน์ ํ๋ก๊ทธ๋จ์ด ์ปค๋ ๋ด์ ๊ณ์ ์ด์ ์๋์ง ์ฌ๋ถ๋ bpf()
๋ฅผ ํตํด ์ ์ฌ๋ ํ์ ํด๋น ์ปค๋ ์๋ธ์์คํ
์ ์ด๋ป๊ฒ ๋ถ๋๊ฐ์ ๋ฐ๋ผ ์ ํด์ง๋ค.
๊ฐ eBPF ํ๋ก๊ทธ๋จ์ ์๋ฃ ๋๊น์ง ์์ ํ๊ฒ ์คํํ ์ ์๋ ์ธ์คํธ๋ญ์ ๋ค์ ์งํฉ์ด๋ค. eBPF ํ๋ก๊ทธ๋จ์ ๋์ด ์๊ณ ์คํํ๊ธฐ์ ์์ ํ์ง๋ฅผ ์ปค๋ ๋ด ๊ฒ์ฆ๊ธฐ๊ฐ ์ ์ ์ผ๋ก ํ๋จํ๋ค. ๊ฒ์ฆํ๋ ๋์ ์ปค๋์ ๊ทธ eBPF ํ๋ก๊ทธ๋จ์์ ์ฌ์ฉํ๋ ๋งต๋ค ๊ฐ๊ฐ์ ๋ํ ์ฐธ์กฐ ์นด์ดํฐ๋ฅผ ์ฌ๋ ค์ ํ๋ก๊ทธ๋จ์ ๋ด๋ฆด ๋๊น์ง ๊ด๋ จ ๋งต๋ค์ด ์ ๊ฑฐ๋์ง ์๋๋ก ํ๋ค.
eBPF ํ๋ก๊ทธ๋จ์ ๋ค์ํ ์ด๋ฒคํธ์ ์ฐ๊ณํ ์ ์๋ค. ๊ทธ ์ด๋ฒคํธ๋ ๋คํธ์ํฌ ํจํท ๋์ฐฉ์ผ ์๋ ์๊ณ , ์ถ์ ์ด๋ฒคํธ, ๋คํธ์ํฌ ํ ๊ท์ ์ ๋ถ๋ฅ ์ด๋ฒคํธ (tc(8)
๋ถ๋ฅ์์ ์ฐ๊ณ๋ eBPF ํ๋ก๊ทธ๋จ์ ๊ฒฝ์ฐ), ๊ทธ๋ฆฌ๊ณ ํฅํ ์ถ๊ฐ๋ ๋ค๋ฅธ ์ข
๋ฅ์ผ ์ ์๋ค. ์ ์ด๋ฒคํธ๊ฐ eBPF ํ๋ก๊ทธ๋จ ์คํ์ ์ผ์ผํค๊ณ , ๊ทธ๋ฌ๋ฉด ํ๋ก๊ทธ๋จ์์ eBPF ๋งต์ ๊ทธ ์ด๋ฒคํธ์ ๋ํ ์ ๋ณด๋ฅผ ์ ์ฅํ ์๋ ์๋ค. ๋ฐ์ดํฐ ์ ์ฅ ์ธ์ eBPF ํ๋ก๊ทธ๋จ์ด ํ์ ๋ ์ปค๋ ๋ด ํฌํผ ํจ์๋ค์ ํธ์ถํ ์๋ ์๋ค.
๋์ผํ eBPF ํ๋ก๊ทธ๋จ์ ์ฌ๋ฌ ์ด๋ฒคํธ์ ์ฐ๊ณํ ์ ์๊ณ ์์ดํ eBPF ํ๋ก๊ทธ๋จ์ด ๋์ผ ๋งต์ ์ ๊ทผํ ์ ์๋ค.
์ถ์ ์ถ์ ์ถ์ eth0์ eth1์ eth2์
์ด๋ฒคํธ A ์ด๋ฒคํธ B ์ด๋ฒคํธ C ํจํท ํจํท ํจํท
| | | | | ^
| | | | v |
--> ์ถ์ <-- ์ถ์ ์์ผ tc ์
๊ตฌ tc ์ถ๊ตฌ
prog_1 prog_2 prog_3 ๋ถ๋ฅ์ ํ์
| | | | prog_4 prog_5
|--- -----| |------| map_3 | |
map_1 map_2 --| map_4 |--
cmd
์ธ์๊ฐ bpf()
์์คํ
ํธ์ถ์ด ์ํํ ์์
์ ๊ฒฐ์ ํ๋ค. ๊ฐ ์์
์ bpf_attr
ํ์
๊ณต์ฉ์ฒด์ ๋ํ ํฌ์ธํฐ์ธ attr
์ ํตํด ์ถ๊ฐ ์ธ์๋ฅผ ๋ฐ๋๋ค (์๋ ์ฐธ๊ณ ). size
์ธ์๋ attr
์ด ๊ฐ๋ฆฌํค๋ ๊ณต์ฉ์ฒด์ ํฌ๊ธฐ์ด๋ค.
cmd
๋ก ์ฃผ๋ ๊ฐ์ ๋ค์ ์ค ํ๋์ด๋ค.
BPF_MAP_CREATE
- ๋งต์ ์์ฑํ๊ณ ๊ทธ ๋งต์ ๊ฐ๋ฆฌํค๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ ๋ฐํํ๋ค. ์ ํ์ผ ๋์คํฌ๋ฆฝํฐ์๋ 'exec์์ ๋ซ๊ธฐ' ํ์ผ ๋์คํฌ๋ฆฝํฐ ํ๋๊ทธ(fcntl(2) ์ฐธ๊ณ )๊ฐ ์๋์ผ๋ก ์ผ์ง๋ค.
BPF_MAP_LOOKUP_ELEM
- ์ง์ ํ ๋งต์์ ํค๋ก ํญ๋ชฉ์ ์ฐพ์์ ๊ทธ ๊ฐ์ ๋ฐํํ๋ค.
BPF_MAP_UPDATE_ELEM
- ์ง์ ํ ๋งต์์ ํญ๋ชฉ(ํค/๊ฐ ์)์ ์์ฑํ๊ฑฐ๋ ๊ฐฑ์ ํ๋ค.
BPF_MAP_DELETE_ELEM
- ์ง์ ํ ๋งต์์ ํค๋ก ํญ๋ชฉ์ ์ฐพ์์ ์ญ์ ํ๋ค.
BPF_MAP_GET_NEXT_KEY
- ์ง์ ํ ๋งต์์ ํค๋ก ํญ๋ชฉ์ ์ฐพ์์ ๋ค์ ํญ๋ชฉ์ ํค๋ฅผ ๋ฐํํ๋ค.
BPF_PROG_LOAD
- eBPF ํ๋ก๊ทธ๋จ์ ๊ฒ์ฆ ๋ฐ ์ ์ฌํ๊ณ ํ๋ก๊ทธ๋จ๊ณผ ์ฐ๊ณ๋ ์ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ ๋ฐํํ๋ค. ์ ํ์ผ ๋์คํฌ๋ฆฝํฐ์๋ 'exec์์ ๋ซ๊ธฐ' ํ์ผ ๋์คํฌ๋ฆฝํฐ ํ๋๊ทธ(fcntl(2) ์ฐธ๊ณ )๊ฐ ์๋์ผ๋ก ์ผ์ง๋ค.
bpf_attr
๊ณต์ฉ์ฒด๋ ์ฌ๋ฌ bpf()
๋ช
๋ น์์ ์ฐ๋ ๋ค์ํ ์ต๋ช
๊ตฌ์กฐ์ฒด๋ค๋ก ์ด๋ค์ ธ ์๋ค.
union bpf_attr {
struct { /* BPF_MAP_CREATE์ ์ฌ์ฉ */
__u32 map_type;
__u32 key_size; /* ํค ํฌ๊ธฐ, ๋ฐ์ดํธ ๋จ์ */
__u32 value_size; /* ๊ฐ ํฌ๊ธฐ, ๋ฐ์ดํธ ๋จ์ */
__u32 max_entries; /* ๋งต ๋ด์ ํญ๋ชฉ ์ต๋ ๊ฐ์ */
};
struct { /* BPF_MAP_*_ELEM ๋ฐ BPF_MAP_GET_NEXT_KEY
๋ช
๋ น์ ์ฌ์ฉ */
__u32 map_fd;
__aligned_u64 key;
union {
__aligned_u64 value;
__aligned_u64 next_key;
};
__u64 flags;
};
struct { /* BPF_PROG_LOAD์ ์ฌ์ฉ */
__u32 prog_type;
__u32 insn_cnt;
__aligned_u64 insns; /* 'const struct bpf_insn *' */
__aligned_u64 license; /* 'const char *' */
__u32 log_level; /* ๊ฒ์ฆ๊ธฐ์ ์์ธ๋ ์์ค */
__u32 log_size; /* ์ฌ์ฉ์ ๋ฒํผ ํฌ๊ธฐ */
__aligned_u64 log_buf; /* ์ฌ์ฉ์๊ฐ ์ ๊ณตํ๋ 'char *'
๋ฒํผ */
__u32 kern_version;
/* prog_type=kprobe์ผ ๋ ๊ฒ์ฌ
(๋ฆฌ๋
์ค 4.1๋ถํฐ) */
};
} __attribute__((aligned(8)));
๋งต์ ๋ค์ํ ๋ฐ์ดํฐ ํ์ ์ ์ ์ฅํ ์ ์๋ ๋ฒ์ฉ ์๋ฃ ๊ตฌ์กฐ์ด๋ค. ์ด๋ฅผ ํตํด eBPF ์ปค๋ ํ๋ก๊ทธ๋จ๋ค ์ฌ์ด์์, ๊ทธ๋ฆฌ๊ณ ์ปค๋๊ณผ ์ฌ์ฉ์ ๊ณต๊ฐ ์์ฉ ์ฌ์ด์์ ๋ฐ์ดํฐ ๊ณต์ ๊ฐ ๊ฐ๋ฅํ๋ค.
๊ฐ ๋งต์๋ ๋ค์ ์์ฑ์ด ์๋ค.
-
์ข ๋ฅ
-
ํญ๋ชฉ ์ต๋ ๊ฐ์
-
ํค์ ๋ฐ์ดํธ ๋จ์ ํฌ๊ธฐ
-
๊ฐ์ ๋ฐ์ดํธ ๋จ์ ํฌ๊ธฐ
๋ค์ํ bpf()
๋ช
๋ น์ผ๋ก ๋งต์ ์ ๊ทผํ๋ ๋ฐฉ๋ฒ์ ์๋ ๋ํผ ํจ์๋ค์ด ๋ณด์ฌ ์ค๋ค. ์ด ํจ์๋ค์ cmd
์ธ์๋ฅผ ์ด์ฉํด ๊ฐ๊ธฐ ๋ค๋ฅธ ์์
์ ํธ์ถํ๋ค.
BPF_MAP_CREATE
๋ช
๋ น์ ์๋ก์ด ๋งต์ ๋ง๋ค๊ณ ๊ทธ ๋งต์ ๊ฐ๋ฆฌํค๋ ์ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ ๋ฐํํ๋ค.
int
bpf_create_map(enum bpf_map_type map_type,
unsigned int key_size,
unsigned int value_size,
unsigned int max_entries)
{
union bpf_attr attr = {
.map_type = map_type,
.key_size = key_size,
.value_size = value_size,
.max_entries = max_entries
};
return bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
}
์ ๋งต์ map_type
์ผ๋ก ์ง์ ํ ์ข
๋ฅ์ด๊ณ key_size
, value_size
, max_entries
๋ก ์ง์ ํ ์์ฑ์ ๊ฐ์ง๋ค. ์ฑ๊ณต ์ ์ด ๋์์ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ ๋ฐํํ๋ค. ์ค๋ฅ ์ -1์ ๋ฐํํ๋ฉฐ errno
๋ฅผ EINVAL
์ด๋ EPERM
, ENOMEM
์ผ๋ก ์ค์ ํ๋ค.
ํ๋ก๊ทธ๋จ ์ ์ฌ ๊ณผ์ ์์ ํ๋ก๊ทธ๋จ์ด ์ฌ๋ฐ๋ก ์ด๊ธฐํ ํ key
๋ก bpf_map_*_elem()
ํฌํผ ํจ์๋ฅผ ํธ์ถํ๋ฉฐ ๋งต ํญ๋ชฉ value
๋ฅผ ์ง์ ํ value_size
๋๋จธ๋ก ์ ๊ทผํ์ง ์์์ ๊ฒ์ฆ๊ธฐ์์ ํ์ธํ๋ ๋ฐ key_size
์ value_size
์์ฑ์ ์ฌ์ฉํ๋ค. ์๋ฅผ ๋ค์ด key_size
๋ฅผ 8๋ก ํด์ ๋งต์ ์์ฑํ๋๋ฐ eBPF ํ๋ก๊ทธ๋จ์์ ๋ค์ ํธ์ถ์ ํ๋ฉด ํ๋ก๊ทธ๋จ์ด ๊ฑฐ๋ถ๋ ๊ฒ์ด๋ค.
bpf_map_lookup_elem(map_fd, fp - 4)
์ปค๋ ๋ด ํฌํผ ํจ์์ธ
bpf_map_lookup_elem(map_fd, void *key)
์์๋ key
๊ฐ ๊ฐ๋ฆฌํค๋ ์์น์์ 8๋ฐ์ดํธ๋ฅผ ์ฝ๊ธฐ๋ฅผ ๊ธฐ๋ํ๋๋ฐ fp - 4
(fp
๋ ์คํ ์๋จ)๋ผ๋ ์์ ์ฃผ์๋ ๋ฒ์๋ฅผ ๋ฒ์ด๋ ์คํ ์ ๊ทผ์ ์ ๋ฐํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ด๋ค.
๋ง์ฐฌ๊ฐ์ง๋ก value_size
๋ฅผ 1๋ก ํด์ ๋งต์ ์์ฑํ๋๋ฐ eBPF ํ๋ก๊ทธ๋จ์ ๋ค์ ๋ด์ฉ์ด ์์ผ๋ฉด ํ๋ก๊ทธ๋จ์ด ๊ฑฐ๋ถ๋ ๊ฒ์ด๋ค.
value = bpf_map_lookup_elem(...);
*(u32 *) value = 1;
์ง์ ํ 1๋ฐ์ดํธ value_size
์ ํ ๋๋จธ๋ก value
ํฌ์ธํฐ์ ์ ๊ทผํ๊ธฐ ๋๋ฌธ์ด๋ค.
ํ์ฌ map_type
์ผ๋ก ๋ค์ ๊ฐ๋ค์ ์ง์ํ๋ค.
enum bpf_map_type {
BPF_MAP_TYPE_UNSPEC, /* 0์ ์ ํจํ์ง ์์ ๋งต ์ข
๋ฅ๋ก ์์ฝ */
BPF_MAP_TYPE_HASH,
BPF_MAP_TYPE_ARRAY,
BPF_MAP_TYPE_PROG_ARRAY,
BPF_MAP_TYPE_PERF_EVENT_ARRAY,
BPF_MAP_TYPE_PERCPU_HASH,
BPF_MAP_TYPE_PERCPU_ARRAY,
BPF_MAP_TYPE_STACK_TRACE,
BPF_MAP_TYPE_CGROUP_ARRAY,
BPF_MAP_TYPE_LRU_HASH,
BPF_MAP_TYPE_LRU_PERCPU_HASH,
BPF_MAP_TYPE_LPM_TRIE,
BPF_MAP_TYPE_ARRAY_OF_MAPS,
BPF_MAP_TYPE_HASH_OF_MAPS,
BPF_MAP_TYPE_DEVMAP,
BPF_MAP_TYPE_SOCKMAP,
BPF_MAP_TYPE_CPUMAP,
};
map_type
์ด ์ปค๋์์ ์ฌ์ฉ ๊ฐ๋ฅํ ๋งต ๊ตฌํ๋ค ์ค ํ๋๋ฅผ ์ ํํ๋ค. eBPF ํ๋ก๊ทธ๋จ์ ๋ชจ๋ ๋งต ์ข
๋ฅ์ ๋์ผํ bpf_map_lookup_elem()
๋ฐ bpf_map_update_elem()
ํฌํผ ํจ์๋ฅผ ์ฌ์ฉํด ์ ๊ทผํ๋ค. ์๋์ ์ฌ๋ฌ ๋งต ์ข
๋ฅ์ ๋ํ ์์ธํ ๋ด์ฉ์ด ์๋ค.
BPF_MAP_LOOKUP_ELEM
๋ช
๋ น์ ํ์ผ ๋์คํฌ๋ฆฝํฐ fd
๊ฐ ๊ฐ๋ฆฌํค๋ ๋งต์์ ์ฃผ์ด์ง key
๋ก ํญ๋ชฉ์ ์ฐพ๋๋ค.
int
bpf_lookup_elem(int fd, const void *key, void *value)
{
union bpf_attr attr = {
.map_fd = fd,
.key = ptr_to_u64(key),
.value = ptr_to_u64(value),
};
return bpf(BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr));
}
ํญ๋ชฉ์ ์ฐพ์ผ๋ฉด ๋์์ด 0์ ๋ฐํํ๋ฉฐ ํญ๋ชฉ์ ๊ฐ์ value
์ ์ ์ฅํ๋ค. value
๋ value_size
๋ฐ์ดํธ ํฌ๊ธฐ์ ๋ฒํผ๋ฅผ ๊ฐ๋ฆฌ์ผ์ผ ํ๋ค.
ํญ๋ชฉ์ ์ฐพ์ง ๋ชปํ๋ฉด ๋์์ด -1์ ๋ฐํํ๋ฉฐ errno
๋ฅผ ENOENT
๋ก ์ค์ ํ๋ค.
BPF_MAP_UPDATE_ELEM
๋ช
๋ น์ ํ์ผ ๋์คํฌ๋ฆฝํฐ fd
๊ฐ ๊ฐ๋ฆฌํค๋ ๋งต์์ ์ฃผ์ด์ง key
/value
๋ก ํญ๋ชฉ์ ์์ฑ ๋๋ ๊ฐฑ์ ํ๋ค.
int
bpf_update_elem(int fd, const void *key, const void *value,
uint64_t flags)
{
union bpf_attr attr = {
.map_fd = fd,
.key = ptr_to_u64(key),
.value = ptr_to_u64(value),
.flags = flags,
};
return bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
}
flags
์ธ์๋ ๋ค์ ์ค ํ๋๋ก ์ง์ ํด์ผ ํ๋ค.
BPF_ANY
- ์ ํญ๋ชฉ์ ์์ฑํ๊ฑฐ๋ ๊ธฐ์กด ํญ๋ชฉ์ ๊ฐฑ์ ํ๋ค.
BPF_NOEXIST
- ์กด์ฌํ์ง ์์ ๋ ์ ํญ๋ชฉ์ ์์ฑํ๊ธฐ๋ง ํ๋ค.
BPF_EXIST
- ๊ธฐ์กด ํญ๋ชฉ์ ๊ฐฑ์ ํ๋ค.
์ฑ๊ณต ์ ๋์์ด 0์ ๋ฐํํ๋ค. ์ค๋ฅ ์ -1์ ๋ฐํํ๋ฉฐ errno
๋ฅผ EINVAL
์ด๋ EPERM
, ENOMEM
, E2BIG
์ผ๋ก ์ค์ ํ๋ค. E2BIG
์ ๋งต ๋ด์ ํญ๋ชฉ ์๊ฐ ๋งต ์์ฑ ์ ์ง์ ํ max_entries
์ ํ์ ๋๋ฌํ๋ค๋ ๋ป์ด๋ค. flags
๊ฐ BPF_NOEXIST
์ธ๋ฐ key
๋ฅผ ๊ฐ์ง ํญ๋ชฉ์ด ์ด๋ฏธ ๋งต์ ์กด์ฌํ๋ฉด EEXIST
๋ฅผ ๋ฐํํ๋ค. flags
๊ฐ BPF_EXIST
์ธ๋ฐ key
๋ฅผ ๊ฐ์ง ํญ๋ชฉ์ด ๋งต์ ์กด์ฌํ์ง ์์ผ๋ฉด ENOENT
๋ฅผ ๋ฐํํ๋ค.
BPF_MAP_DELETE_ELEM
๋ช
๋ น์ ํ์ผ ๋์คํฌ๋ฆฝํฐ fd
๊ฐ ๊ฐ๋ฆฌํค๋ ๋งต์์ ํค๊ฐ key
์ธ ํญ๋ชฉ์ ์ญ์ ํ๋ค.
int
bpf_delete_elem(int fd, const void *key)
{
union bpf_attr attr = {
.map_fd = fd,
.key = ptr_to_u64(key),
};
return bpf(BPF_MAP_DELETE_ELEM, &attr, sizeof(attr));
}
์ฑ๊ณต ์ 0์ ๋ฐํํ๋ค. ํญ๋ชฉ์ ์ฐพ์ง ๋ชปํ๋ฉด -1์ ๋ฐํํ๋ฉฐ errno
๋ฅผ ENOENT
๋ก ์ค์ ํ๋ค.
BPF_MAP_GET_NEXT_KEY
๋ช
๋ น์ ํ์ผ ๋์คํฌ๋ฆฝํฐ fd
๊ฐ ๊ฐ๋ฆฌํค๋ ๋งต์์ key
๋ก ํญ๋ชฉ์ ์ฐพ์์ next_key
๊ฐ ๊ฐ๋ฆฌํค๋ ๋ฒํผ๋ฅผ ๊ทธ ๋ค์ ํญ๋ชฉ์ ํค๋ก ์ค์ ํ๋ค.
int
bpf_get_next_key(int fd, const void *key, void *next_key)
{
union bpf_attr attr = {
.map_fd = fd,
.key = ptr_to_u64(key),
.next_key = ptr_to_u64(next_key),
};
return bpf(BPF_MAP_GET_NEXT_KEY, &attr, sizeof(attr));
}
key
๋ฅผ ์ฐพ์ผ๋ฉด ๋์์ด 0์ ๋ฐํํ๋ฉฐ next_key
๊ฐ ๊ฐ๋ฆฌํค๋ ๋ฒํผ๋ฅผ ๋ค์ ํญ๋ชฉ์ ํค๋ก ์ค์ ํ๋ค. key
๋ฅผ ์ฐพ์ง ๋ชปํ๋ฉด ๋์์ด 0์ ๋ฐํํ๋ฉฐ next_key
๊ฐ ๊ฐ๋ฆฌํค๋ ๋ฒํผ๋ฅผ ์ฒซ ๋ฒ์งธ ํญ๋ชฉ์ ํค๋ก ์ค์ ํ๋ค. key
๊ฐ ๋ง์ง๋ง ํญ๋ชฉ์ด๋ฉด -1์ ๋ฐํํ๋ฉฐ errno
๋ฅผ ENOENT
๋ก ์ค์ ํ๋ค. ๊ฐ๋ฅํ ๋ค๋ฅธ errno
๊ฐ์ ENOMEM
, EFAULT
, EPERM
, EINVAL
์ด๋ค. ์ด ๋ฐฉ๋ฒ์ ์ฌ์ฉํด ๋งต์ ํญ๋ชฉ ์ ์ฒด๋ฅผ ์ํํ ์ ์๋ค.
ํ์ผ ๋์คํฌ๋ฆฝํฐ fd
๊ฐ ๊ฐ๋ฆฌํค๋ ๋งต์ ์ญ์ ํ๋ค. ๋งต์ ์์ฑํ ์ฌ์ฉ์ ๊ณต๊ฐ ํ๋ก๊ทธ๋จ์ด ์ข
๋ฃํ ๋ ๋ชจ๋ ๋งต๋ค์ด ์๋์ผ๋ก ์ญ์ ๋๋ค. (ํ์ง๋ง NOTES๋ฅผ ๋ณด๋ผ.)
๋ค์ ์ข ๋ฅ์ ๋งต์ ์ง์ํ๋ค.
BPF_MAP_TYPE_HASH
-
ํด์ ํ ์ด๋ธ ๋งต์ ํน์ง์ ๋ค์๊ณผ ๊ฐ๋ค.
-
์ฌ์ฉ์ ๊ณต๊ฐ ํ๋ก๊ทธ๋จ์ด ๋งต์ ์์ฑํ๊ณ ์์ค๋ค. ์ฌ์ฉ์ ๊ณต๊ฐ ํ๋ก๊ทธ๋จ๊ณผ eBPF ํ๋ก๊ทธ๋จ ๋ชจ๋ ๊ฒ์, ๊ฐฑ์ , ์ญ์ ์์ ์ ์ํํ ์ ์๋ค.
-
์ปค๋์ด ํค/๊ฐ ์์ ํ ๋น๊ณผ ํด์ ๋ฅผ ๋งก๋๋ค.
-
max_entries
ํ๊ณ์ ๋๋ฌํ๋ฉดmap_update_elem()
ํฌํผ๊ฐ ์ฝ์ ์ ์คํจํ๊ฒ ๋๋ค. (๊ทธ๋์ eBPF ํ๋ก๊ทธ๋จ์ด ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ณ ๊ฐ์ํค์ง ๋ชปํ๋ค.) -
map_update_elem()
์ด ๊ธฐ์กด ํญ๋ชฉ์ ์์์ ์ผ๋ก ๊ต์ฒดํ๋ค.
ํด์ ํ ์ด๋ธ ๋งต์ ๊ฒ์ ์๋์ ์ต์ ํ๋์ด ์๋ค.
-
BPF_MAP_TYPE_ARRAY
-
๋ฐฐ์ด ๋งต์ ํน์ง์ ๋ค์๊ณผ ๊ฐ๋ค.
-
๊ฐ๋ฅํ ์ต๊ณ ์๋์ ๊ฒ์์ ์ต์ ํ๋์ด ์๋ค. ํฅํ์ ๊ฒ์ฆ๊ธฐ/JIT ์ปดํ์ผ๋ฌ๊ฐ ์์ ํค๋ฅผ ์ฌ์ฉํ๋
lookup()
์์ ์ ์ธ์ํด์ ์ด๋ฅผ ์์ ํฌ์ธํฐ๋ก ์ต์ ํํ ์๋ ์๋ค. ์์ ์๋ ํค๋ฅผ ํฌ์ธํฐ ์ง์ ๊ณ์ฐ์ผ๋ก ์ต์ ํํ๋ ๊ฒ๋ ๊ฐ๋ฅํ๋ฐ, eBPF ํ๋ก๊ทธ๋จ์ ์๋ช ๋์ ํฌ์ธํฐ์value_size
๊ฐ ๊ณ ์ ๋ผ ์๊ธฐ ๋๋ฌธ์ด๋ค. ๋ค์ ๋งํด ๊ฒ์ฆ๊ธฐ/JIT ์ปดํ์ผ๋ฌ๊ฐarray_map_lookup_elem()
์ '์ธ๋ผ์ธ'์ผ๋ก ๋ง๋ค๋ฉด์๋ ์ฌ์ ํ ์ฌ์ฉ์ ๊ณต๊ฐ์์ ์ด ๋งต์ ๋์ ์ ๊ทผ ๊ฐ๋ฅํ๋๋ก ํ ์ ์๋ค. -
๋ชจ๋ ๋ฐฐ์ด ํญ๋ชฉ๋ค์ ์ฌ์ ํ ๋น๋๋ฉฐ ์ด๊ธฐํ ์์ ์ 0์ผ๋ก ์ด๊ธฐํ ๋๋ค.
-
ํค๋ ๋ฐฐ์ด ์์ธ์ด๋ฉฐ ์ ํํ 4๋ฐ์ดํธ์ฌ์ผ ํ๋ค.
-
map_delete_elem()
์ดEINVAL
์ค๋ฅ๋ก ์คํจํ๋ค. ํญ๋ชฉ๋ค์ ์ญ์ ํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค. -
map_update_elem()
์ด ๋น์์์ ๋ฐฉ์์ผ๋ก ํญ๋ชฉ์ ๊ต์ฒดํ๋ค. ์์์ ๊ฐฑ์ ์ ์ํ๋ฉด ํด์ ํ ์ด๋ธ ๋งต์ ์ฌ์ฉํด์ผ ํ๋ค. ํ์ง๋ง ๋ฐฐ์ด์์๋ ๊ฐ๋ฅํ ํน๋ณํ ๊ฒฝ์ฐ๊ฐ ์๋๋ฐ, 32๋นํธ ๋ฐ 64๋นํธ ์์ ์นด์ดํฐ์ ์์์ ์ธ ๋ด์ฅ__sync_fetch_and_add()
๋ฅผ ์ฌ์ฉํ ์ ์๋ค. ์๋ฅผ ๋ค์ด ๊ฐ์ด ๋จ์ผ ์นด์ดํฐ๋ฅผ ๋ํ๋ธ๋ค๋ฉด ๊ฐ ์ ์ฒด์ ์ ์ฉํ ์ ์์ผ๋ฉฐ ์ฌ๋ฌ ์นด์ดํฐ๋ฅผ ๋ด์ ๊ตฌ์กฐ์ฒด์ธ ๊ฒฝ์ฐ์๋ ๊ฐ๋ณ ์นด์ดํฐ์ ์ฌ์ฉํ ์ ์์ ๊ฒ์ด๋ค. ์ด๋ฒคํธ ํฉ์ฐ ๋ฐ ๊ณ์์ ์ข ์ข ์ ์ฉํ๋ค.
๋ฐฐ์ด ๋งต์ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์๋ค.
-
eBPF "์ ์ญ" ๋ณ์: ํ ํญ๋ชฉ์ง๋ฆฌ ๋ฐฐ์ด์ ํค๋ฅผ (์์ธ) 0์ผ๋ก ํ๊ณ ๊ฐ์ '์ ์ญ' ๋ณ์๋ค์ ์งํฉ์ผ๋ก ํด์ eBPF ํ๋ก๊ทธ๋จ์ด ์ด๋ฅผ ์ด์ฉํด ์ด๋ฒคํธ ๊ฐ์ ์ํ๋ฅผ ์ ์งํ ์ ์๋ค.
-
๊ณ ์ ํญ๋ชฉ๋ค์ ์ถ์ ์ด๋ฒคํธ ํฉ์ฐํด ๋ฃ๊ธฐ.
-
ํจํท ์๋ ํจํท ํฌ๊ธฐ ๊ฐ์ ๋คํธ์ํน ์ด๋ฒคํธ ๊ณ์.
-
-
BPF_MAP_TYPE_PROG_ARRAY
(๋ฆฌ๋ ์ค 4.2๋ถํฐ) -
ํ๋ก๊ทธ๋จ ๋ฐฐ์ด ๋งต์ ํน๋ณํ ์ข ๋ฅ์ ๋ฐฐ์ด ๋งต์ธ๋ฐ, ๊ฐ์ผ๋ก ๋ค๋ฅธ eBPF ํ๋ก๊ทธ๋จ์ ๊ฐ๋ฆฌํค๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ง ๋ด๋๋ค. ๋ฐ๋ผ์
key_size
์value_size
๋ชจ๋ ์ ํํ 4๋ฐ์ดํธ์ฌ์ผ ํ๋ค. ์ด ๋งต์bpf_tail_call()
ํฌํผ์ ๊ฒฐํฉํด์ ์ฌ์ฉํ๋ค.์ด๊ฒ ๋ปํ๋ ๋ฐ๋ ํ๋ก๊ทธ๋จ ๋ฐฐ์ด ๋งต์ด ์๋ eBPF ํ๋ก๊ทธ๋จ์ด ์ปค๋ ์ชฝ์์ ๋ค์์ ํธ์ถํ์ฌ ์๊ธฐ ํ๋ก๊ทธ๋จ ํ๋ฆ์ ํด๋น ํ๋ก๊ทธ๋จ ๋ฐฐ์ด ์ฌ๋กฏ์ ์๋ ํ๋ก๊ทธ๋จ์ ํ๋ฆ์ผ๋ก ๊ต์ฒดํ ์ ์๋ค๋ ๊ฒ์ด๋ค.
void bpf_tail_call(void *context, void *prog_map, unsigned int index);
์ด ๋ฐฐ์ด์ ๋ค๋ฅธ eBPF ํ๋ก๊ทธ๋จ์ผ๋ก ๊ฐ๋ ์ผ์ข ์ ์ ํ ํ ์ด๋ธ๋ก ๋ณผ ์ ์๋ค. ๊ทธ๋ ๊ฒ ํธ์ถ๋ ํ๋ก๊ทธ๋จ์ ๊ฐ์ ์คํ์ ์ฌ์ฌ์ฉํ๊ฒ ๋๋ค. ์ ํ๋ก๊ทธ๋จ์ผ๋ก ์ ํ๋ฅผ ์ํํ๊ณ ๋๋ฉด ์ด์ ํ๋ก๊ทธ๋จ์ผ๋ก๋ ๋ ์ด์ ๋์์ค์ง ์๋๋ค.
(๋งต ์ฌ๋กฏ์ ์ ํจํ ํ๋ก๊ทธ๋จ ํ์ผ ๋์คํฌ๋ฆฝํฐ๊ฐ ์๊ฑฐ๋, ์ง์ ํ ๊ฒ์ ์์ธ/ํค๊ฐ ๋ฒ์ ๋ฐ์ด๊ฑฐ๋, ํธ์ถ ๊น์ด ์ ํ 32๋ฒ์ ์ด๊ณผํด์) ํ๋ก๊ทธ๋จ ๋ฐฐ์ด์ ์ฃผ์ด์ง ์์ธ์์ eBPF ํ๋ก๊ทธ๋จ์ ์ฐพ์ ์ ์์ผ๋ฉด ํ์ฌ eBPF ํ๋ก๊ทธ๋จ ์คํ์ ๊ณ์ํ๋ค. ์ด ๋์ ๋ฐฉ์์ ์ด์ฉํด ๊ธฐ๋ณธ ๊ฒฝ์ฐ๋ก ๋จ์ด์ง๋ ๊ฒ์ ๊ตฌํํ ์ ์๋ค.
ํ๋ก๊ทธ๋จ ๋ฐฐ์ด ๋งต์ด ์ ์ฉํ ๊ฒฝ์ฐ๋ก ์ถ์ ์ด๋ ๋คํธ์ํน์ด ์๋๋ฐ, ๊ฐ๋ณ ์์คํ ํธ์ถ์ด๋ ํ๋กํ ์ฝ์ ๋ณ๊ฐ์ ํ์ ํ๋ก๊ทธ๋จ์์ ๋ค๋ฃจ๊ณ ์๋ณ์๋ฅผ ๋งต ์์ธ์ผ๋ก ์ฌ์ฉํ ์ ์๋ค. ์ด ๋ฐฉ์์ผ๋ก ์ธํด ์ฑ๋ฅ์ด ํฅ์๋ ์๋ ์์ผ๋ฉฐ ๋จ์ผ eBPF ํ๋ก๊ทธ๋จ์ ์ต๋ ์ธ์คํธ๋ญ์ ์ ์ ํ์ ๋์ด์ค ์ ์๊ธฐ๋ ํ๋ค. ๊ฐ๋ณ์ ์ธ ํ๊ฒฝ์์ ์ฌ์ฉ์ ๊ณต๊ฐ ๋ฐ๋ชฌ์ด ์๋ฅผ ๋ค์ด ์ ์ญ ์ ์ฑ ์ด ๋ฐ๋์์ ๋ ๋ฐํ์์ ์์์ ์ผ๋ก ๊ฐ๋ณ ํ์ ํ๋ก๊ทธ๋จ๋ค์ ์ ๋ฒ์ ์ผ๋ก ๊ต์ฒดํ์ฌ ์ ์ฒด ํ๋ก๊ทธ๋จ ๋์์ ๋ฐ๊ฟ ์๋ ์์ ๊ฒ์ด๋ค.
BPF_PROG_LOAD
๋ช
๋ น์ ์ฌ์ฉํด eBPF ํ๋ก๊ทธ๋จ์ ์ปค๋๋ก ์ ์ฌํ๋ค. ์ด ๋ช
๋ น์ ๋ฐํ ๊ฐ์ ๊ทธ eBPF ํ๋ก๊ทธ๋จ์ ์ฐ๊ณ๋ ์ ํ์ผ ๋์คํฌ๋ฆฝํฐ์ด๋ค.
char bpf_log_buf[LOG_BUF_SIZE];
int
bpf_prog_load(enum bpf_prog_type type,
const struct bpf_insn *insns, int insn_cnt,
const char *license)
{
union bpf_attr attr = {
.prog_type = type,
.insns = ptr_to_u64(insns),
.insn_cnt = insn_cnt,
.license = ptr_to_u64(license),
.log_buf = ptr_to_u64(bpf_log_buf),
.log_size = LOG_BUF_SIZE,
.log_level = 1,
};
return bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
}
prog_type
์ ์ฌ์ฉ ๊ฐ๋ฅํ ํ๋ก๊ทธ๋จ ์ข
๋ฅ๋ค ์ค ํ๋์ด๋ค.
enum bpf_prog_type {
BPF_PROG_TYPE_UNSPEC, /* 0์ ์ ํจํ์ง ์์
ํ๋ก๊ทธ๋จ ์ข
๋ฅ๋ก ์์ฝ */
BPF_PROG_TYPE_SOCKET_FILTER,
BPF_PROG_TYPE_KPROBE,
BPF_PROG_TYPE_SCHED_CLS,
BPF_PROG_TYPE_SCHED_ACT,
};
eBPF ํ๋ก๊ทธ๋จ ์ข ๋ฅ์ ๋ํ ์์ธํ ๋ด์ฉ์ ์๋๋ฅผ ๋ณด๋ผ.
bpf_attr
์ ๋๋จธ์ง ๋นํธ๋ค์ ๋ค์๊ณผ ๊ฐ์ด ์ค์ ํ๋ค.
-
insns
๋struct bpf_insn
์ธ์คํธ๋ญ์ ์ ๋ฐฐ์ด์ด๋ค. -
insn_cnt
๋insns
๊ฐ ๊ฐ๋ฆฌํค๋ ํ๋ก๊ทธ๋จ ๋ด ์ธ์คํธ๋ญ์ ๊ฐ์์ด๋ค. -
license
๋ ๋ผ์ด์ ์ค ๋ฌธ์์ด์ด๋ฉฐ,gpl_only
๋ก ํ์๋ ํฌํผ ํจ์๋ค์ ํธ์ถํ๋ ค๋ฉด GPL ํธํ์ด์ด์ผ ํ๋ค. (๋ผ์ด์ ์ค ๊ท์น์ด ์ปค๋ ๋ชจ๋๊ณผ ๊ฐ์ผ๋ฏ๋ก "Dual BSD/GPL" ๊ฐ์ ์ด์ค ๋ผ์ด์ ์ค๋ฅผ ์ฌ์ฉํ ์๋ ์๋ค.) -
log_buf
๋ ํธ์ถ์๊ฐ ํ ๋นํ ๋ฒํผ์ ๋ํ ํฌ์ธํฐ์ด๋ฉฐ ์ปค๋ ๋ด ๊ฒ์ฆ๊ธฐ๊ฐ ์ฌ๊ธฐ์ ๊ฒ์ฆ ๋ก๊ทธ๋ฅผ ์ ์ฅํ ์ ์๋ค. ๊ทธ ๋ก๊ทธ๋ ์ฌ๋ฌ ํ์ ๋ฌธ์์ด์ด๋ฉฐ ํ๋ก๊ทธ๋จ ์์ฑ์๊ฐ ์ด๋ฅผ ํ์ธํ์ฌ ๊ฒ์ฆ๊ธฐ๊ฐ ์ด๋ป๊ฒ ๊ทธ eBPF ํ๋ก๊ทธ๋จ์ด ์์ ํ์ง ์๋ค๋ ๊ฒฐ๋ก ์ ๋๋ฌํ๋์ง ์ ์ ์๋ค. ๊ฒ์ฆ๊ธฐ๊ฐ ๋ฐ์ ํจ์ ๋ฐ๋ผ ์ถ๋ ฅ ํ์์ด ์ธ์ ๋ ๋ฐ๋ ์ ์๋ค. -
log_size
๋log_buf
๊ฐ ๊ฐ๋ฆฌํค๋ ๋ฒํผ์ ํฌ๊ธฐ์ด๋ค. ๋ฒํผ ํฌ๊ธฐ๊ฐ ๊ฒ์ฆ๊ธฐ ๋ฉ์์ง๋ฅผ ๋ชจ๋ ๋ด๊ธฐ์ ์ถฉ๋ถํ์ง ์์ผ๋ฉด -1์ ๋ฐํํ๊ณerrno
๋ฅผENOSPC
๋ก ์ค์ ํ๋ค. -
log_level
์ ๊ฒ์ฆ๊ธฐ์ ์ถ๋ ฅ ์์ธ ์ ๋์ด๋ค. 0 ๊ฐ์ ๊ฒ์ฆ๊ธฐ๊ฐ ๋ก๊ทธ๋ฅผ ์ ๊ณตํ์ง ์๋๋ค๋ ๋ป์ด๋ค. ์ด ๊ฒฝ์ฐlog_buf
๊ฐ NULL ํฌ์ธํฐ์ฌ์ผ ํ๊ณlog_size
๊ฐ 0์ด์ด์ผ ํ๋ค.
BPF_PROG_LOAD
๊ฐ ๋ฐํํ ํ์ผ ๋์คํฌ๋ฆฝํฐ์ close(2)๋ฅผ ์ ์ฉํ๋ฉด ๊ทธ eBPF ํ๋ก๊ทธ๋จ์ ์ ๊ฑฐํ๊ฒ ๋๋ค. (ํ์ง๋ง NOTES๋ฅผ ๋ณด๋ผ.)
eBPF ํ๋ก๊ทธ๋จ์์ ๋งต์ ์ ๊ทผํ ์ ์์ผ๋ฏ๋ก eBPF ํ๋ก๊ทธ๋จ๋ค ์ฌ์ด์์, ๊ทธ๋ฆฌ๊ณ eBPF ํ๋ก๊ทธ๋จ๊ณผ ์ฌ์ฉ์ ๊ณต๊ฐ ํ๋ก๊ทธ๋จ ์ฌ์ด์์ ๋ฐ์ดํฐ๋ฅผ ๊ตํํ๋ ๋ฐ ๋งต์ ์ด๋ค. ์๋ฅผ ๋ค์ด eBPF ํ๋ก๊ทธ๋จ์ด (kprobe, ํจํท ๊ฐ์) ๋ค์ํ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ๊ณ ์ ๋งต์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ์ ์๊ณ , ๊ทธ๋ฌ๋ฉด ์ฌ์ฉ์ ๊ณต๊ฐ ํ๋ก๊ทธ๋จ์ด ๊ทธ ๋งต์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋ค. ๋ฐ๋๋ก ์ฌ์ฉ์ ๊ณต๊ฐ ํ๋ก๊ทธ๋จ์ด ๋งต์ ์ค์ ๋ฉ์ปค๋์ฆ์ผ๋ก ์ฌ์ฉํ ์ ์๋ค. ๋งต์ ์ด๋ค ๊ฐ๋ค๋ก ์ฑ์ฐ๋ฉด eBPF ํ๋ก๊ทธ๋จ์ด ๊ทธ๊ฑธ ํ์ธํด์ ๊ทธ ๊ฐ์ ๋ฐ๋ผ ๋์ค์ ๋์ ๋ฐฉ์์ ๋ณ๊ฒฝํ ์ ์๋ค.
eBPF ํ๋ก๊ทธ๋จ ์ข
๋ฅ(prog_type
)๊ฐ ํ๋ก๊ทธ๋จ์์ ํธ์ถํ ์ ์๋ ์ปค๋ ํฌํผ ํจ์๋ค์ ์งํฉ์ ๊ฒฐ์ ํ๋ค. ๋ํ ํ๋ก๊ทธ๋จ ์ข
๋ฅ๊ฐ ํ๋ก๊ทธ๋จ ์
๋ ฅ(๋ฌธ๋งฅ)์, ์ฆ (eBPF ํ๋ก๊ทธ๋จ์๊ฒ ์ฒซ ๋ฒ์งธ ์ธ์๋ก ์ ๋ฌ๋๋ ๋ฐ์ดํฐ ๋ฉ์ด๋ฆฌ์ธ) struct bpf_context
์ ํ์์ ๊ฒฐ์ ํ๋ค.
์๋ฅผ ๋ค์ด ์ถ์ ํ๋ก๊ทธ๋จ์ ํฌํผ ํจ์ ์งํฉ์ ์์ผ ํํฐ ํ๋ก๊ทธ๋จ๊ณผ ๊ฐ์ง ์๋ค. (๋ฌผ๋ก ์ผ๋ถ ํฌํผ๋ค์ ๊ณตํต์ผ ์ ์๋ค.) ๋ ์ถ์ ํ๋ก๊ทธ๋จ์ ์ ๋ ฅ(๋ฌธ๋งฅ)์ ๋ ์ง์คํฐ ๊ฐ๋ค์ ์งํฉ์ธ ๋ฐ๋ฉด ์์ผ ํํฐ์์๋ ๋คํธ์ํฌ ํจํท์ด๋ค.
์ด๋ค ์ข ๋ฅ์ eBPF ํ๋ก๊ทธ๋จ์์ ์ฌ์ฉ ๊ฐ๋ฅํ ํจ์๋ค์ ์งํฉ์ ํฅํ ์ปค์ง ์๋ ์๋ค.
๋ค์ ์ข ๋ฅ์ ํ๋ก๊ทธ๋จ์ ์ง์ํ๋ค.
-
BPF_PROG_TYPE_SOCKET_FILTER
(๋ฆฌ๋ ์ค 3.19๋ถํฐ) -
ํ์ฌ
BPF_PROG_TYPE_SOCKET_FILTER
์์ ์ธ ์ ์๋ ํจ์๋ค์ ๋ค์๊ณผ ๊ฐ๋ค.bpf_map_lookup_elem(map_fd, void *key) /* map_fd์์ ํค ๊ฒ์ */ bpf_map_update_elem(map_fd, void *key, void *value) /* ํค/๊ฐ ๊ฐฑ์ */ bpf_map_delete_elem(map_fd, void *key) /* map_fd์์ ํค ์ญ์ */
bpf_context
์ธ์๋struct __sk_buff
์ ๋ํ ํฌ์ธํฐ์ด๋ค. -
BPF_PROG_TYPE_KPROBE
(๋ฆฌ๋ ์ค 4.1๋ถํฐ) - [์์ฑ ์์ ]
-
BPF_PROG_TYPE_SCHED_CLS
(๋ฆฌ๋ ์ค 4.1๋ถํฐ) - [์์ฑ ์์ ]
-
BPF_PROG_TYPE_SCHED_ACT
(๋ฆฌ๋ ์ค 4.1๋ถํฐ) - [์์ฑ ์์ ]
ํ๋ก๊ทธ๋จ์ ์ ์ฌํ๊ณ ๋๋ฉด ์ด๋ฅผ ์ด๋ฒคํธ์ ์ฐ๊ณํ ์ ์๋ค. ๋ค์ํ ์ปค๋ ์๋ธ์์คํ ๋ง๋ค ์ด๋ฅผ ์ํ ๊ฐ์์ ๋ฐฉ๋ฒ์ด ์๋ค.
๋ฆฌ๋
์ค 3.19๋ถํฐ ๋ค์๊ณผ ๊ฐ์ด ํธ์ถํ๋ฉด ์์ socket(2) ํธ์ถ๋ก ์์ฑํ ์์ผ sockfd
์ ํ๋ก๊ทธ๋จ prog_fd
๋ฅผ ๋ถ์ด๊ฒ ๋๋ค.
setsockopt(sockfd, SOL_SOCKET, SO_ATTACH_BPF,
&prog_fd, sizeof(prog_fd));
๋ฆฌ๋
์ค 4.1๋ถํฐ ๋ค์๊ณผ ๊ฐ์ด ํธ์ถํ์ฌ ์์ perf_event_open(2) ํธ์ถ๋ก ์์ฑํ perf ์ด๋ฒคํธ ํ์ผ ๋์คํฌ๋ฆฝํฐ event_fd
์ ํ์ผ ๋์คํฌ๋ฆฝํฐ prog_fd
๊ฐ ๊ฐ๋ฆฌํค๋ eBPF ํ๋ก๊ทธ๋จ์ ๋ถ์ผ ์ ์๋ค.
ioctl(event_fd, PERF_EVENT_IOC_SET_BPF, prog_fd);
/* bpf+์์ผ ์์:
* 1. 256๊ฐ ํญ๋ชฉ์ ๋ฐฐ์ด ๋งต ์์ฑ
* 2. ์์ ํจํท ์๋ฅผ ์ธ๋ ํ๋ก๊ทธ๋จ ์ ์ฌ
* r0 = skb->data[ETH_HLEN + offsetof(struct iphdr, protocol)]
* map[r0]++
* 3. setsockopt()๋ฅผ ํตํด raw ์์ผ์ prog_fd ์ฐ๊ณ
* 4. ๋งค์ด๋ง๋ค ์์ ํ TCP/UDP ํจํท ๊ฐ์ ์ถ๋ ฅ
*/
int
main(int argc, char **argv)
{
int sock, map_fd, prog_fd, key;
long long value = 0, tcp_cnt, udp_cnt;
map_fd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(key),
sizeof(value), 256);
if (map_fd < 0) {
printf("failed to create map '%s'\n", strerror(errno));
/* ์๋ง ๋ฃจํธ๋ก ์คํํ์ง ์์์ */
return 1;
}
struct bpf_insn prog[] = {
BPF_MOV64_REG(BPF_REG_6, BPF_REG_1), /* r6 = r1 */
BPF_LD_ABS(BPF_B, ETH_HLEN + offsetof(struct iphdr, protocol)),
/* r0 = ip->proto */
BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_0, -4),
/* *(u32 *)(fp - 4) = r0 */
BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), /* r2 = fp */
BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4), /* r2 = r2 - 4 */
BPF_LD_MAP_FD(BPF_REG_1, map_fd), /* r1 = map_fd */
BPF_CALL_FUNC(BPF_FUNC_map_lookup_elem),
/* r0 = map_lookup(r1, r2) */
BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
/* if (r0 == 0) goto pc+2 */
BPF_MOV64_IMM(BPF_REG_1, 1), /* r1 = 1 */
BPF_XADD(BPF_DW, BPF_REG_0, BPF_REG_1, 0, 0),
/* lock *(u64 *) r0 += r1 */
BPF_MOV64_IMM(BPF_REG_0, 0), /* r0 = 0 */
BPF_EXIT_INSN(), /* return r0 */
};
prog_fd = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, prog,
sizeof(prog) / sizeof(prog[0]), "GPL");
sock = open_raw_sock("lo");
assert(setsockopt(sock, SOL_SOCKET, SO_ATTACH_BPF, &prog_fd,
sizeof(prog_fd)) == 0);
for (;;) {
key = IPPROTO_TCP;
assert(bpf_lookup_elem(map_fd, &key, &tcp_cnt) == 0);
key = IPPROTO_UDP;
assert(bpf_lookup_elem(map_fd, &key, &udp_cnt) == 0);
printf("TCP %lld UDP %lld packets\n", tcp_cnt, udp_cnt);
sleep(1);
}
return 0;
}
์ปค๋ ์์ค ํธ๋ฆฌ์ samples/bpf
๋๋ ํฐ๋ฆฌ์ ์์ ํ ๋์ ์ฝ๋๋ค์ด ์ข ์๋ค.
์ฑ๊ณต ํธ์ถ ์ ๋ฐํ ๊ฐ์ ์์ ์ ๋ฐ๋ผ ๋ค๋ฅด๋ค.
BPF_MAP_CREATE
- eBPF ๋งต์ ์ฐ๊ณ๋ ์ ํ์ผ ๋์คํฌ๋ฆฝํฐ.
BPF_PROG_LOAD
- eBPF ํ๋ก๊ทธ๋จ์ ์ฐ๊ณ๋ ์ ํ์ผ ๋์คํฌ๋ฆฝํฐ.
- ๋ค๋ฅธ ๋ช ๋ น๋ค
- 0.
์ค๋ฅ ์ -1์ ๋ฐํํ๋ฉฐ errno
๋ฅผ ์ ์ ํ ์ค์ ํ๋ค.
E2BIG
- eBPF ํ๋ก๊ทธ๋จ์ด ๋๋ฌด ํฌ๊ฑฐ๋ ๋งต์ด
max_entries
์ ํ(์ต๋ ํญ๋ชฉ ์)์ ๋๋ฌํ๋ค. EACCES
-
BPF_PROG_LOAD
์์, ๋ชจ๋ ํ๋ก๊ทธ๋จ ์ธ์คํธ๋ญ์ ์ด ์ ํจํ์ง๋ง ํ๋ก๊ทธ๋จ์ด ์์ ํ์ง ์์ ๋ณด์ฌ์ ๊ฑฐ๋ถ๋์๋ค. ํ์ฉ ์ ๋ ๋ฉ๋ชจ๋ฆฌ ์์ญ์ด๋ ์ด๊ธฐํ ์ ๋ ์คํ/๋ ์ง์คํฐ์ ์ ๊ทผํด์์ผ ์๋ ์๊ณ ํจ์ ์ ์ฝ์ด ์ค์ ์ข ๋ฅ์ ์ผ์นํ์ง ์์์์ผ ์๋ ์๊ณ ์ ๋ ฌ ์ ๋ ๋ฉ๋ชจ๋ฆฌ ์ ๊ทผ์ด ์์ด์์ผ ์๋ ์๋ค. ์ด ๊ฒฝ์ฐlog_level = 1
๋กbpf()
๋ฅผ ๋ค์ ํธ์ถํด์ ๊ฒ์ฆ๊ธฐ๊ฐ ์ ์ํ ๊ตฌ์ฒด์ ์ด์ ๋ฅผlog_buf
์์ ํ์ธํด ๋ณด๋ ๊ฒ ์ข๋ค. EBADF
-
fd
๊ฐ ์ด๋ฆฐ ํ์ผ ๋์คํฌ๋ฆฝํฐ๊ฐ ์๋๋ค. EFAULT
- ํฌ์ธํฐ๋ค(
key
,value
,log_buf
,insns
) ์ค ํ๋๊ฐ ์ ๊ทผ ๊ฐ๋ฅํ ์ฃผ์ ๊ณต๊ฐ ๋ฐ์ด๋ค. EINVAL
-
cmd
์ ์ง์ ํ ๊ฐ์ ์ด ์ปค๋์ด ์์ง ๋ชปํ๋ค. EINVAL
-
BPF_MAP_CREATE
์์,map_type
์ด๋ ์์ฑ์ด ์ ํจํ์ง ์๋ค. EINVAL
-
BPF_MAP_*_ELEM
๋ช ๋ น๋ค์์,union bpf_attr
์ ํ๋๋ค ์ค ์ผ๋ถ๋ฅผ ์ด ๋ช ๋ น์์ ์ฌ์ฉํ์ง ์๋๋ฐ 0์ผ๋ก ์ค์ ๋ผ ์์ง ์๋ค. EINVAL
-
BPF_PROG_LOAD
์์, ์ ํจํ์ง ์์ ํ๋ก๊ทธ๋จ ์ ์ฌ ์๋๋ฅผ ๋ํ๋ธ๋ค. ์ธ์ ๋ถ๊ฐ๋ฅํ ์ธ์คํธ๋ญ์ , ์์ฝ๋ ํ๋ ์ฌ์ฉ, ๋ฒ์ ๋ฐ์ผ๋ก์ ์ ํ, ๋ฌดํ ๋ฃจํ, ์ ์ ์๋ ํจ์ ํธ์ถ ๋๋ฌธ์ eBPF ํ๋ก๊ทธ๋จ์ด ์ ํจํ์ง ์๋ค๊ณ ๋ณผ ์ ์๋ค. ENOENT
-
BPF_MAP_LOOKUP_ELEM
์ด๋BPF_MAP_DELETE_ELEM
์์, ํด๋นkey
๋ฅผ ๊ฐ์ง ํญ๋ชฉ์ ์ฐพ์ ์ ์์์ ๋ํ๋ธ๋ค. ENOMEM
- ์ถฉ๋ถํ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ ๋นํ ์ ์๋ค.
EPERM
- ์ถฉ๋ถํ ํน๊ถ ์์ด (
CAP_SYS_ADMIN
์ญ๋ฅ ์์ด) ํธ์ถ์ ํ๋ค.
๋ฆฌ๋
์ค 3.18์์ bpf()
์์คํ
ํธ์ถ์ด ์ฒ์ ๋ฑ์ฅํ๋ค.
bpf()
์์คํ
ํธ์ถ์ ๋ฆฌ๋
์ค ์ ์ฉ์ด๋ค.
ํ์ฌ ๊ตฌํ์์๋ ๋ชจ๋ bpf()
๋ช
๋ น์์ ํธ์ถ์์๊ฒ CAP_SYS_ADMIN
์ญ๋ฅ์ด ํ์ํ๋ค.
eBPF ๊ฐ์ฒด(๋งต, ํ๋ก๊ทธ๋จ)๋ฅผ ํ๋ก์ธ์ค๋ค ๊ฐ์ ๊ณต์ ํ ์ ์๋ค. ์๋ฅผ ๋ค๋ฉด fork(2) ํ์ ์์์ด ๊ฐ์ eBPF ๊ฐ์ฒด๋ค์ ๊ฐ๋ฆฌํค๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ค์ ๋ฌผ๋ ค๋ฐ๋๋ค. ๋๋ถ์ด eBPF ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํค๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ ์ ๋์ค ๋๋ฉ์ธ ์์ผ์ ํตํด ์ ๋ฌํ ์ ์๋ค. ๊ทธ๋ฆฌ๊ณ eBPF ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํค๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ ํ์์์ฒ๋ผ dup(2)์ด๋ ๋น์ทํ ํธ์ถ์ ์ด์ฉํด ๋ณต์ ํ ์ ์๋ค. eBPF ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํค๋ ๋ชจ๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ๊ฐ ๋ซํ ํ์๋ง ๊ทธ ๊ฐ์ฒด๊ฐ ํ ๋น ํด์ ๋๋ค.
eBPF ํ๋ก๊ทธ๋จ์ ์ ์ฝ๋ C๋ก ์์ฑํด์ (clang
์ปดํ์ผ๋ฌ๋ฅผ ์ด์ฉํด) eBPF ๋ฐ์ดํธ์ฝ๋๋ก ์ปดํ์ผ ํ ์ ์๋ค. ๊ทธ ์ ์ฝ๋ C์๋ ๋ฃจํ, ์ ์ญ ๋ณ์, ๊ฐ๋ณ ์ธ์ ํจ์, ๋ถ๋ ์์์ , ํจ์ ์ธ์๋ก ๊ตฌ์กฐ์ฒด ์ ๋ฌํ๊ธฐ ๊ฐ์ ์ฌ๋ฌ ๊ธฐ๋ฅ๋ค์ด ๋น ์ ธ ์๋ค. ์ปค๋ ์์ค ํธ๋ฆฌ์ samples/bpf/*_kern.c
ํ์ผ๋ค์์ ์๋ฅผ ๋ณผ ์ ์๋ค.
์ปค๋์๋ ์ฑ๋ฅ ํฅ์์ ์ํด eBPF ๋ฐ์ดํธ์ฝ๋๋ฅผ ๋ค์ดํฐ๋ธ ๋จธ์ ์ฝ๋๋ก ๋ณํํ๋ JIT(just-in-time) ์ปดํ์ผ๋ฌ๊ฐ ํฌํจ๋ผ ์๋ค. ๋ฆฌ๋
์ค 4.15 ์ ์ ์ปค๋์์๋ JIT ์ปดํ์ผ๋ฌ๊ฐ ๊ธฐ๋ณธ์ ์ผ๋ก ๊บผ์ ธ ์์ผ๋ฉฐ /proc/sys/net/core/bpf_jit_enable
ํ์ผ์ ๋ค์ ์ ์ ๋ฌธ์์ด ์ค ํ๋๋ฅผ ์จ๋ฃ์ด์ ๋์ ๋ฐฉ์์ ์ ์ดํ ์ ์๋ค.
- 0
- JIT ์ปดํ์ผ ๋๊ธฐ. (๊ธฐ๋ณธ๊ฐ)
- 1
- ์ผ๋ฐ ์ปดํ์ผ.
- 2
- ๋๋ฒ๊น
๋ชจ๋. ์์ฑ๋ ๋ช
๋ น ์ฝ๋๋ฅผ ์ญ์ก์ง์๋ก ์ปค๋ ๋ก๊ทธ๋ก ์ฐ๋๋ค. ๊ทธ๋ฌ๋ฉด ์ปค๋ ์์ค ํธ๋ฆฌ์์ ์ ๊ณตํ๋
tools/net/bpf_jit_disasm.c
ํ๋ก๊ทธ๋จ์ ์ด์ฉํด ๊ทธ ๋ช ๋ น ์ฝ๋๋ฅผ ์ญ์ด์ ๋ธ ํ ์ ์๋ค.
๋ฆฌ๋
์ค 4.15๋ถํฐ ์ปค๋ ๊ตฌ์ฑ์ CONFIG_BPF_JIT_ALWAYS_ON
์ต์
์ ์ธ ์ ์๋ค. ๊ทธ๋ ๊ฒ ํ๋ฉด JIT ์ปดํ์ผ๋ฌ๊ฐ ํญ์ ์ผ์ง๋ฉฐ bpf_jit_enable
์ 1๋ก ์ด๊ธฐํ ๋๊ณ ๋ณ๊ฒฝ ๋ถ๊ฐ๋ฅํ๋ค. (์ด ์ปค๋ ๊ตฌ์ฑ ์ต์
์ BPF ์ธํฐํ๋ฆฌํฐ๋ฅผ ๋์์ผ๋ก ํ๋ ์ด๋ ์คํํฐ ๊ณต๊ฒฉ์ ๋ํ ์ํ์ฑ
์ผ๋ก ๋์จ ๊ฒ์ด๋ค.)
ํ์ฌ ๋ค์ ์ํคํ ์ฒ๋ค์์ eBPF JIT ์ปดํ์ผ๋ฌ๊ฐ ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
- x86-64 (๋ฆฌ๋ ์ค 3.18๋ถํฐ, cBPF๋ ๋ฆฌ๋ ์ค 3.0๋ถํฐ)
- ARM32 (๋ฆฌ๋ ์ค 3.18๋ถํฐ, cBPF๋ ๋ฆฌ๋ ์ค 3.4๋ถํฐ)
- SPARC 32 (๋ฆฌ๋ ์ค 3.18๋ถํฐ, cBPF๋ ๋ฆฌ๋ ์ค 3.5๋ถํฐ)
- ARM-64 (๋ฆฌ๋ ์ค 3.18๋ถํฐ)
- s390 (๋ฆฌ๋ ์ค 4.1๋ถํฐ, cBPF๋ ๋ฆฌ๋ ์ค 3.7๋ถํฐ)
- PowerPC 64 (๋ฆฌ๋ ์ค 4.8๋ถํฐ, cBPF๋ ๋ฆฌ๋ ์ค 3.1๋ถํฐ)
- SPARC 64 (๋ฆฌ๋ ์ค 4.12๋ถํฐ)
- x86-32 (๋ฆฌ๋ ์ค 4.18๋ถํฐ)
- MIPS 64 (๋ฆฌ๋ ์ค 4.18๋ถํฐ, cBPF๋ ๋ฆฌ๋ ์ค 3.16๋ถํฐ)
- riscv (๋ฆฌ๋ ์ค 5.1๋ถํฐ)
seccomp(2), bpf-helpers(7), socket(7), tc(8)
, tc-bpf(8)
์ปค๋ ์์ค ํ์ผ Documentation/networking/filter.txt
์์ ์ ํต์ BPF์ ํ์ฅ BPF ๋ชจ๋๋ฅผ ์ค๋ช
ํ๋ค.
2019-08-02