tc bpf(8) - wariua/manpages-ko GitHub Wiki
BPF - μ λ ₯/μΆλ ₯ ν κ·μ λ₯Ό μν BPF νλ‘κ·Έλ¨ λΆλ₯μ λ° νμ
eBPF λΆλ₯μ(νν°) λλ νμ:
tc filter ... bpf [ object-file OBJ_FILE ] [ section CLS_NAME ] [ export UDS_FILE ] [ verbose ] [ skip_hw | skip_sw ] [ police POLICE_SPEC ] [ action ACTION_SPEC ] [ classid CLASSID ] tc action ... bpf [ object-file OBJ_FILE ] [ section CLS_NAME ] [ export UDS_FILE ] [ verbose ]
cBPF λΆλ₯μ(νν°) λλ νμ:
tc filter ... bpf [ bytecode-file BPF_FILE | bytecode BPF_BYTECODE ] [ police POLICE_SPEC ] [ action ACTION_SPEC ] [ classid CLASSID ] tc action ... bpf [ bytecode-file BPF_FILE | bytecode BPF_BYTECODE ]
νμ₯ λ²ν΄λ¦¬ ν¨ν· νν°(eBPF)μ μ ν΅μ λ²ν΄λ¦¬ ν¨ν· νν°(μλλ κ·Έλ₯ BPFμ§λ§ ꡬλ³μ μν΄ μ¬κΈ°μ cBPFλΌκ³ λΆλ¦) λͺ¨λλ₯Ό μμ ν νλ‘κ·Έλλ° κ°λ₯νκ³ λ§€μ° ν¨μ¨μ μΈ λΆλ₯μ(classifier) λ° νμ(action)λ‘ μ¬μ©ν μ μλ€. λ λͺ¨λλ κ°λ¨ν νλ‘κ·Έλ¨ κ΅¬νμ μν μμ μΈμ€νΈλμ μΈνΈλ₯Ό μ 곡νλ©°, κ·Έ νλ‘κ·Έλ¨μ 컀λλ‘ μμ νκ² μ μ¬νμ¬ μ»€λ 곡κ°μ μμ κ°μ λ¨Έμ μμ μ€νν μ μλ€. μ§μ ν νλ‘κ·Έλ¨μ΄ νμ μ’ λ£νλ©° μ£½κ±°λ 컀λ λ°μ΄ν°λ₯Ό λμΆμν€μ§ μμμ 컀λ λ΄ κ²μ¦κΈ°κ° 보μ₯νλ€.
리λ μ€μμλ μΌλ°μ μΌλ‘ eBPFκ° cBPFμ λ€λ₯Ό μλλ€κ³ λ³Έλ€. 컀λ λ΄λΆμμλ cBPF ννμμ eBPF ννμμΌλ‘ λ³ννμ¬ μ€ννλ€. μ€νμ μΈν°ν리ν°κ° μνν μλ μκ³ κ΅¬μ± μμ μ μ μ€νΈμΈνμ(JIT) μ»΄νμΌ λμ΄ λ€μ΄ν°λΈ κΈ°κ³μ΄λ‘ λ μλ μλ€. νμ¬ x86_64, ARM64, s390, ppc64, sparc64 μν€ν μ²μμ eBPF JITλ₯Ό μ§μνλ©° PPC, SPARC, ARM, MIPSμλ cBPFλ μ§μνμ§λ§ (μμ§) eBPF JIT μ§μμΌλ‘ μ ννμ§ μμλ€.
eBPF μΈμ€νΈλμ μΈνΈμ κΈ°λ° μ리λ cBPF μΈμ€νΈλμ μΈνΈμ λΉμ·νλ λ λμ λ°νμ μ±λ₯μ μ»κΈ° μν΄ κΈ°λ° μν€ν μ²μ μ’ λ κ°κΉκ² μ€κ³ν΄μ λ€μ΄ν°λΈ μΈμ€νΈλμ μΈνΈλ₯Ό λ μ νλ΄λΌ μ μλλ‘ νμλ€. μΌλμΌ λ§€νμΌλ‘ JIT ν μ μκ² μ€κ³λμλλ°, λλΆμ μ»΄νμΌλ¬κ° eBPF λ°±μλλ₯Ό ν΅ν΄ λ€μ΄ν°λΈ μ»΄νμΌ μ½λμ κ°κΉκ² λΉ λ₯΄κ² λμνλ μ΅μ νλ eBPF μ½λλ₯Ό μμ±ν κ°λ₯μ±κΉμ§ μ΄λ¦°λ€. LLVMμμ κ·Έλ° eBPF λ°±μλλ₯Ό μ 곡νλ―λ‘ eBPF νλ‘κ·Έλ¨μ μ νμ C μΈμ΄λ‘ μ½κ² μμ±ν μ μλ€. μ΄ μΈμλ eBPF κΈ°λ° κ΅¬μ‘°μλ "λ§΅"μ΄λΌλ μμκ° μλ€. eBPF λ§΅μ ν€/κ° μ μ₯μμΈλ°, μ΄λ₯Ό μ¬λ¬ eBPF νλ‘κ·Έλ¨λ€ μ¬μ΄λΏ μλλΌ eBPF νλ‘κ·Έλ¨κ³Ό μ¬μ©μ κ³΅κ° μμ© μ¬μ΄μμλ 곡μ νλ€.
νΈλν½ μ μ΄ μλΈμμ€ν μμ μ λ ₯ λ° μΆλ ₯ qdiscμ λΆμΌ μ μλ λΆλ₯μμ νμλ₯Ό eBPFλ cBPFλ‘ μμ±ν μ μλ€. λ€λ₯Έ λΆλ₯μμ νμλ€μ λν μ₯μ μ eBPF/cBPFλ λ²μ©μ νλ μμν¬λ₯Ό μ 곡νκ³ μ¬μ©μκ° νΉνλ μ©λμ λ°λΌ ν¨μ¨μ μΌλ‘ ꡬνν μ μλ€λ μ μ΄λ€. κ·Έλ κ² μμ±ν λΆλ₯μ λ΄μ§ νμλ κ³Όμ κΈ°λ₯μΌλ‘ κ³ μνμ§ μμ κ²μ΄κ³ , λ°λΌμ μκΈ° ν μΌμ λ§€μ° ν¨μ¨μ μΌλ‘ μ€νν μ μλ€. κ·Έλ¦¬κ³ λΉμ ν λΆλ₯κ° κ°λ₯ν΄μ§κ³ μ¬μ§μ΄ νμ λΆλΆμ λΆλ₯λ‘ λ³ν©νλ κ²λ κ°λ₯νλ€. μ΄λ₯Ό ν¨μ¨μ μΈ eBPF λ§΅ μλ£ κ΅¬μ‘°μ κ²°ν©νλ©΄ μλ₯Ό λ€μ΄ μ¬μ©μ 곡κ°μμ λΆλ₯μ μ¬μ μ¬ μμ΄ μ»€λλ‘ classid κ°μ μ μ μ± μ λ°μ΄λ£κ±°λ, μ΄λ λ§΅μ μ μ₯λ ν΅κ³λ₯Ό μμ§ν΄μ λΆνλ₯Ό μμλ΄κ³ λ€λ₯Έ λ§΅μ μ΄μ©ν΄ λμ μΌλ‘ λΆν λΆμ°μ ν μ μλ€.
μ€ν λ° λ§ν¬ κ°λ₯ νμ(ELF)μ΄κ³ eBPF λͺ
λ Ή μ½λμ eBPF λ§΅ μ μλ₯Ό λ΄μ μ€λΈμ νΈ νμΌμ κ°λ¦¬ν¨λ€. eBPF λΆλ₯μμ μ€ μ μλ eBPF μ€λΈμ νΈ μμ±μ μ§μνλ νλ‘μ νΈλ‘λ clang(1)
μ C μΈμ΄ νλ‘ νΈμλλ‘ νλ LLVM μ»΄νμΌλ¬ μΈνλΌκ° μλ€. (μμΈν λ΄μ©μ EXAMPLES μ μ°Έκ³ .) eBPF λΆλ₯μ λ΄μ§ νμλ₯Ό μ μ¬ν λ μ΄ μ΅μ
μ νμμ΄λ€.
μ€λΈμ νΈ νμΌμμ eBPF λΆλ₯μ λ΄μ§ νμκ° μμΉν ELF μΉμ μ μ΄λ¦μ΄λ€. λΆλ₯μλ κΈ°λ³Έ μΉμ μ΄λ¦μ΄ "classifier"μ΄κ³ νμλ "action"μ΄λ€. ν μ€λΈμ νΈ νμΌμ μ¬λ¬ λΆλ₯μμ νμλ€μ λ£μ μ μμΌλ―λ‘ κΈ°λ³Έκ³Ό λ€λ₯Έ κ²½μ° ν΄λΉ μΉμ μ΄λ¦μ λͺ μν΄μΌ νλ€.
μ λμ€ λλ©μΈ μμΌ νμΌμ κ°λ¦¬ν¨λ€. eBPF μ€λΈμ νΈ νμΌμ eBPF λ§΅ λͺ μΈλ₯Ό λ΄μ "maps"λΌλ μΉμ μ΄ μλ κ²½μ° λ§΅ νμΌ λμ€ν¬λ¦½ν°λ₯Ό μ λμ€ λλ©μΈ μμΌμ ν΅ν΄ tc μ’ λ£ ν νμΌ λμ€ν¬λ¦½ν°λ€μ κ΄λ¦¬νλ eBPF "μμ΄μ νΈ"μκ² λκ²¨μ€ μ μλ€. importλ₯Ό μν IPC λμμ ꡬννλ©° κ·Έ λμ€ν¬λ¦½ν°λ€μ bpf(2) νΈμΆμ μ¬μ©ν΄μ κ°λ Ή λͺ¨λν°λ§μ΄λ μ μ μ± μ λ΄λ¦¬κΈ° μν΄ μ¬μ©μ 곡κ°μμ eBPF λ§΅ λ°μ΄ν°λ₯Ό μ½κ±°λ κ°±μ νλ μ 3μ μμ© νλ‘κ·Έλ¨μ΄ μμ΄μ νΈκ° λ μ μλ€.
μ€μ νλ©΄ eBPF νλ‘κ·Έλ¨ μ μ¬κ° μ±κ³΅ν κ²½μ°μλ eBPF κ²μ¦κΈ° μΆλ ₯μ μ°λλ€. κΈ°λ³Έμ μΌλ‘λ μ€λ₯ μμλ§ μ¬μ©μμκ² κ²μ¦κΈ° λ‘κ·Έλ₯Ό μΆλ ₯νλ€.
νλμ¨μ΄ μ€νλ‘λ μ μ΄ νλκ·Έ. κΈ°λ³Έμ μΌλ‘ TCλ κ°λ₯ν κ²½μ° νν°λ₯Ό νλμ¨μ΄λ‘ μ€νλ‘λ νλ €κ³ μλνλ€. skip_hw
λ μ€νλ‘λ μλλ₯Ό λͺ
μμ μΌλ‘ λΉνμ±ννλ€. skip_sw
λ μ€νλ‘λλ₯Ό κ°μ νκ³ μ»€λ λ΄ eBPF νλ‘κ·Έλ¨ μ€νμ λΉνμ±ννλ€. μ΄ νλκ·Έλ₯Ό μ€μ νλλ° νλμ¨μ΄ μ€νλ‘λκ° κ°λ₯νμ§ μμΌλ©΄ 컀λμ΄ μ€λ₯λ₯Ό μλ¦¬κ³ νν°κ° μμ μ€μΉλμ§ μλλ€.
eBPF/cBPF λΆλ₯μλ₯Ό μν μ νμ λ§€κ°λ³μμ΄λ©°, κ°λ Ή μ
λ ₯ qdisc μμ λΆλ₯μμ λΆμΌ tc(1)
λ΄ policeλ₯Ό μ§μ νλ€.
eBPF/cBPF λΆλ₯μλ₯Ό μν μ νμ λ§€κ°λ³μμ΄λ©°, λΆλ₯μμ λΆμΌ tc(1)
λ΄ νμ νμλ₯Ό μ§μ νλ€.
μ΄ eBPF/cBPF λΆλ₯μλ₯Ό μν κΈ°λ³Έ νΈλν½ μ μ΄ ν΄λμ€ μλ³μμ΄λ€. μ΄ κΈ°λ³Έ ν΄λμ€ μλ³μλ₯Ό eBPF/cBPF νλ‘κ·Έλ¨ λ°ν μ½λλ‘ λ체ν μλ μλ€. κΈ°λ³Έ λ°ν μ½λ -1
μ μ¬κΈ° μ 곡ν κΈ°λ³Έ ν΄λμ€ μλ³μλ₯Ό μ¬μ©νλΌλ λ»μ΄λ€. κ·Έλ¦¬κ³ eBPF/cBPF νλ‘κ·Έλ¨ λ°ν μ½λκ° 0μ΄λ©΄ μΌμΉκ° μμλ€λ μλ―Έλ€. μ΄ λ μΈμ λ€λ₯Έ λ°ν μ½λκ° κΈ°λ³Έ classidλ₯Ό λμ νκ² λλ€. μ΄λ₯Ό ν΅ν΄ eBPF/cBPF νλ‘κ·Έλ¨ νλλ§μΌλ‘ ν¨μ¨μ μΈ λΉμ ν λΆλ₯κ° κ°λ₯νλ€. μ¬λ¬ ν΄λμ€ μλ³μλ₯Ό μν΄ νλ‘κ·Έλ¨μ μ¬λ¬ κ° μ¬μ©ν΄μ νλ‘κ·Έλ¨λ§λ€ ν¨ν· λ΄μ©μ λ€μ νμ± νμ§ μμλ λλ€.
cBPF λΆλ₯μ λ° νμ μ μ¬μλ§ μ¬μ©νκ³ μλ€. cBPF λ°μ΄νΈμ½λλ₯Ό 's,c t f k,c t f k,c t f k,...
' ννμ ν
μ€νΈ λ¬Έμμ΄λ‘ μ§μ μ λ¬νλ€. μ¬κΈ°μ s
λ μ΄μ΄μ§λ 4ννλ€μ κ°μλ₯Ό λνλΈλ€. 4νλΈ νλλ μμ§μλ‘ λ c t f k
λ‘ μ΄λ€μ§λλ°, c
λ cBPF λͺ
λ Ή μ½λ(opcode)λ₯Ό, t
λ μ°ΈμΌ λ μ ν λμ μ€νμ
μ, f
λ κ±°μ§μΌ λ μ ν λμ μ€νμ
μ, k
λ μ¦μμ μμ/리ν°λ΄μ λνλΈλ€. μ΄λ° νμμΌλ‘ μ½λλ₯Ό μμ±ν΄ μ£Όλ μ¬λ¬ λꡬλ€μ΄ μλλ°, μλ₯Ό λ€μ΄ 리λ
μ€ μ»€λ μμ€ νΈλ¦¬μ tools/net/
μλμ bpf_asm
μ΄ μλ€. λ°λΌμ μμΌλ‘ μ§μ μμ±ν νμκ° μλ€. cBPF λΆλ₯μλ νμλ₯Ό μ μ¬νλ € ν λλ bytecode
λ bytecode-file
μ΅μ
μ΄ νμμ΄λ€.
λ§μ°¬κ°μ§λ‘ cBPF λΆλ₯μ λ΄μ§ νμλ₯Ό μ μ¬νλ λ° μ°μΈλ€. ν¨κ³Όλ bytecode
μ κ°λ€. cBPF λ°μ΄νΈμ½λκ° λͺ
λ ΉνμΌλ‘ μ§μ μ λ¬λλ κ² μλλΌ ν
μ€νΈ νμΌ μμ μμ λΏμ΄λ€.
eBPF μμ΄μ νΈ μ½λλ₯Ό ν¬ν¨ν μ λλ‘ λ μλ₯Ό iproute2 μμ€ ν¨ν€μ§μ examples/bpf/
μμ μ°Ύμ μ μλ€.
μ μ 쑰건μΌλ‘ 컀λμ bpf(2)λΌλ eBPF μμ€ν
νΈμΆμ΄ νμ±νλμ΄ μμ΄μΌ νκ³ νΈλν½ μ μ΄ μλΈμμ€ν
μ μν cls_bpf
λ° act_bpf
컀λ λͺ¨λμ΄ μμ΄μΌ νλ€. μν€ν
μ²μμ μ§μνλ λλ‘ eBPF/cBPF JIT μ§μμ μΌλ €λ©΄ λ€μκ³Ό κ°μ΄ νλ€.
echo 1 > /proc/sys/net/core/bpf_jit_enable
LLVMμ ν΅ν΄ μ μ½λ C νμΌμ μ»΄νμΌ ν μ μλ€.
clang -O2 -emit-llvm -c bpf.c -o - | llc -march=bpf -filetype=obj -o bpf.o
ν₯ν μ»΄νμΌλ¬ νΈμΆ λ°©λ²μ΄ λ κ°λ¨ν΄μ§ μλ μμ ν μ§λ§ λΉλΆκ°μ λ€μκ³Ό κ°μ΄ μμΌλ¦¬μ΄μ€ ν΄ λλ κ² κ°νΈνλ€.
__bcc() {
clang -O2 -emit-llvm -c $1 -o - | \
llc -march=bpf -filetype=obj -o "`basename $1 .c` .o"
}
alias bcc=__bcc
λͺ¨λ νΈλν½μ΄ κΈ°λ³Έ classidλ‘ (λ°ν μ½λ -1) 걸리λ κ°μ₯ μμ λ¨λ μ½λλ λ€μκ³Ό κ°λ€.
#include <linux/bpf.h>
#ifndef __section
# define __section(x) __attribute__((section(x), used))
#endif
__section("classifier") int cls_main(struct __sk_buff *skb)
{
return -1;
}
char __license[] __section("license") = "GPL";
μλ eBPF νλ‘κ·Έλλ° λΆμ μμ λ λ§μ μλ₯Ό λ³Ό μ μλ€. μ¬κΈ°μ λꡬμ μ§μ€νλ€.
νμ λ±μ μν λ€μν μΉμ λ€μ΄ λ μμ μ μλ€. κ·Έλμ eBPFλ‘ λ μ€λΈμ νΈ νμΌμ μ¬λ¬ μ§μ μ μ΄ μμ μ μλ€. νμ§λ§ tcλ‘ μ€μ ν λλ ꡬ체μ μ§μ μ μ λͺ μν΄μΌ νλ€. κ·Έλ¦¬κ³ μ μ½λ C μ½λμ λΌμ΄μ μ€κ° ν¬ν¨λμ΄μΌ νλ©° λΌμ΄μ μ€ λ¬Έμμ΄ λ¬Έλ²μ 리λ μ€ μ»€λ λͺ¨λμμμ κ°λ€. 컀λμ μΌλΆ eBPF ν¨μλ€μ GPL νΈν λΌμ΄μ μ€λ‘λ§ μ μ½ν κΆνμ κ°μ§λ©°, κ·Έλμ κ·Έλ° λΌμ΄μ μ€ λΆμΌμΉ λ°μ μ νλ‘κ·Έλ¨μ 컀λλ‘ μ μ¬νλ κ²μ κ±°μ ν μλ μλ€.
μ»΄νμΌ ν΄μ λμ€λ μ€λΈμ νΈ νμΌμ μΌλ° μ€λΈμ νΈ νμΌμ μ¬μ©νλ νλ²ν λꡬλ€λ‘ μ΄ν΄λ³Ό μ μλ€. κ°λ Ή objdump(1)λ‘ ELF μΉμ ν€λλ€μ μ΄ν΄λ³Ό μ μλ€.
objdump -h bpf.o
[...]
3 classifier 000007f8 0000000000000000 0000000000000000 00000040 2**3
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
4 action-mark 00000088 0000000000000000 0000000000000000 00000838 2**3
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
5 action-rand 00000098 0000000000000000 0000000000000000 000008c0 2**3
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
6 maps 00000030 0000000000000000 0000000000000000 00000958 2**2
CONTENTS, ALLOC, LOAD, DATA
7 license 00000004 0000000000000000 0000000000000000 00000988 2**0
CONTENTS, ALLOC, LOAD, DATA
[...]
κΈ°λ³Έ ELF μΉμ μ λΆλ₯μκ° λ΄κΈ΄ μ€λΈμ νΈ νμΌμ κ°μ§κ³ eBPF λΆλ₯μλ₯Ό μΆκ°νλ 건 κ°λ¨νλ€. (μ°Έκ³ λ‘ "object-file" λμ "obj"μ²λΌ μ€μ¬ μΈ μλ μλ€.)
bcc bpf.c
tc filter add dev em1 parent 1: bpf obj bpf.o flowid 1:1
λΆλ₯μκ° "mycls"λΌλ ELF μΉμ μ μλ κ²½μ° κ°μ λͺ λ Ήμ λ€μκ³Ό κ°μ΄ νΈμΆν΄μΌ νλ€.
tc filter add dev em1 parent 1: bpf obj bpf.o sec mycls flowid 1:1
ν΄λμ€ μ€μ μ μ°μΌλ©΄ μλ³μμ μμΉκ° λμ¨λ€. μ¦, μ€λΈμ νΈ νμΌ "bpf.o"μ "mycls" μΉμ μμ μλ€κ³ μλ €μ€λ€.
tc filter show dev em1
filter parent 1: protocol all pref 49152 bpf
filter parent 1: protocol all pref 49152 bpf handle 0x1 flowid 1:1 bpf.o:[mycls]
κ°μ νλ‘κ·Έλ¨μ μΆλ ₯μ΄ μλλΌ μ λ ₯ qdiscμ μ€μΉν μλ μλ€.
tc qdisc add dev em1 handle ffff: ingress
tc filter add dev em1 parent ffff: bpf obj bpf.o sec mycls flowid ffff:1
λ§μ°¬κ°μ§λ‘ μ°μ΄ λ³Ό μ μλ€.
tc filter show dev em1 parent ffff:
filter protocol all pref 49152 bpf
filter protocol all pref 49152 bpf handle 0x1 flowid ffff:1 bpf.o:[mycls]
λΆλ₯μ λ° νμλ₯Ό μ
λ ₯μ λΆμΌ λλ μ€μ κΈ°λ° ν κ·μ κ° μλ€λ μ μ½μ΄ μλ€. μ
λ ₯μμ ν μ μλ 건 ν¨ν·μ λΆλ₯νκ±°λ, λ³μ‘°νκ±°λ, μ¬μ§ν₯νκ±°λ, λ²λ¦¬λ κ²μ΄λ€. μ
λ ₯ μͺ½μμ ν μ¬μ©μ΄ νμν λλ μ
λ ₯μμ ν¨ν·μ ifb
μ₯λΉλ‘ μ¬μ§ν₯ν΄μΌ νλ€. μλλ©΄ policingμ μΈ μ μλ€. μ΄ μΈμλ μμΉ μλ ν¨ν·μ΄ λ€νΈμν¬ μ€ν μμ κ³μΈ΅μ κ°κΈ° μ μ μΌμ° λ²λ¦¬λ μ§μ μ λκ±°λ, μΆλ ₯κ³Ό 곡μ ν μ μλ eBPF λ§΅λ€λ‘ λ€νΈμν¬ μ¬μ© ν΅κ³λ₯Ό κΈ°λ‘νκ±°λ, μ΄λ₯΄κ² μ‘°μνκ±°λ λ€λ₯Έ λ€νΈμν¬ μ₯μΉλ‘ μ¬μ§ν₯ν μ μλ μ§μ μ λλ λ° μ
λ ₯μ μ΄μ©ν μ μλ€.
μ¬λ¬ eBPF νμμ λΆλ₯μλ€μ ν νμΌ λ΄μ μ¬λ¬ μΉμ μ λ£μ μ μλ€. μ΄ κ²½μ° κΈ°λ³Έκ³Ό λ€λ₯Έ μΉμ μ΄λ¦μ μλ € μ£Όμ΄μΌ νλλ°, λ€μ μμμ λ νμ λͺ¨λκ° κ·Έλ λ€.
tc filter add dev em1 parent 1: bpf obj bpf.o flowid 1:1 \
action bpf obj bpf.o sec action-mark \
action bpf obj bpf.o sec action-rand ok
μ΄ λ°©μμ μ₯μ μ νλ‘κ·Έλ¨μ eBPF λ§΅μ΄ κ΅¬νλμ΄ μλ κ²½μ° λΆλ₯μμ λ νμμμ 곡μ ν μ μλ€λ μ μ΄λ€.
tc(8)
μ€μ νμλ μ¬μ©μ 곡κ°μμ eBPF λ§΅μ μ κ·Όν μ μλλ‘ νκΈ° μν΄ μ λμ€ λλ©μΈ μμΌμ ν΅ν΄ eBPF μμ΄μ νΈλ‘ μμ κΆμ μ΄μ ν μ μλ€. μ΄λ₯Ό ꡬνν μ μλ λ°©λ²μ΄ λ κ°μ§ μλ€.
-
μ체 eBPF μμ΄μ νΈλ₯Ό λ§λ€μ΄μ μ§μ μ λμ€ λλ©μΈ μμΌμ μ€λΉνκ³
tc(8)
κ° μꡬνλ νλ‘ν μ½μ ꡬννκΈ°. iproute2 μμ€ ν¨ν€μ§μexamples/bpf/
μμμ μ΄λ₯Ό μν μμ μ½λλ₯Ό λ³Ό μ μλ€. -
tc exec
λ₯Ό μ¬μ©ν΄μ μ λμ€ λλ©μΈ μμΌμΌλ‘ eBPF λ§΅ νμΌ λμ€ν¬λ¦½ν°κ° μ΄μ λλ©΄sh(1)
κ°μ μμ© νλ‘μΈμ€κ° μμ±λκ² νκΈ°. μ΄ λ°©μμ μ₯μ μ tcκ° νμΌ λμ€ν¬λ¦½ν°λ€μ μ€ν νκ²½μ μ§μ΄λ£μ΄ μ£Όλ―λ‘ stdin, stdout, stderr νμΌ λμ€ν¬λ¦½ν°μ²λΌ μΈ μ μλ€λ μ μ΄λ€. μ΄λ κ² νλ©΄ κ·Έ fd μμ μ Έ μμμ μ¬μ©μ μμ©μ μ’ λ£νκ³ μ¬μμν΄λ eBPF λ§΅ νμΌ λμ€ν¬λ¦½ν°κ° μ¬λΌμ§μ§ μλλ€. μμ λΆλ₯μμ νμ μ‘°ν©μΌλ‘ μλ₯Ό λ€μλ©΄ λ€μκ³Ό κ°λ€.
tc exec bpf imp /tmp/bpf
tc filter add dev em1 parent 1: bpf obj bpf.o exp /tmp/bpf flowid 1:1 \
action bpf obj bpf.o sec action-mark \
action bpf obj bpf.o sec action-rand ok
eBPF λ§΅μ λΆλ₯μμ νμμμ 곡μ νλ€κ³ νλ©΄ λΆλ₯μλ νμ λͺ λ Ήμμ ν λ²λ§ λ΄λ³΄μ΄λ©΄ μΆ©λΆνλ€. μ€λΈμ νΈ νμΌμ μ²μ νμ± νλ μμ μ tcκ° eBPF λ§΅ νμΌ λμ€ν¬λ¦½ν°λ€μ λͺ¨λ μ€λΉν΄ μ€ κ²μ΄λ€.
μ
Έμ΄ μλ‘ μμ±λ λ κ·Έ νκ²½μ λ κ°μ§ eBPF κ΄λ ¨ λ³μκ° μλ€. BPF_NUM_MAPS
λ μ λμ€ λλ©μΈ μμΌμ ν΅ν΄ μ΄μ λ λ§΅λ€μ μ΄κ°μλ₯Ό μλ € μ€λ€. κ·Έλ¦¬κ³ BPF_MAP<X>
μ κ°μ eBPF μμ΄μ νΈ μμ©μμ μ κ·Όν μ μλ νμΌ λμ€ν¬λ¦½ν° λ²νΈμ΄λ€. μ¦ μ΄ κ°μ bpf(2) μμ€ν
νΈμΆμ κ·Έλλ‘ νμΌ λμ€ν¬λ¦½ν°λ‘ μ¬μ©ν΄μ eBPF λ§΅ κ°λ€μ μ‘°ννκ±°λ λ³κ²½ν μ μλ€. <X>
λ eBPF λ§΅μ μλ³μλ₯Ό λνλΈλ€. tc eBPF λ§΅ λͺ
μΈμμ struct bpf_elf_map
μ id
λ©€λ²μ ν΄λΉνλ€.
μ΄ μμμλ νκ²½μ΄ λ€μκ³Ό κ°μ΄ λλ€.
sh# env | grep BPF
BPF_NUM_MAPS=3
BPF_MAP1=6
BPF_MAP0=5
BPF_MAP2=7
sh# ls -la /proc/self/fd
[...]
lrwx------. 1 root root 64 Apr 14 16:46 5 -> anon_inode:bpf-map
lrwx------. 1 root root 64 Apr 14 16:46 6 -> anon_inode:bpf-map
lrwx------. 1 root root 64 Apr 14 16:46 7 -> anon_inode:bpf-map
sh# my_bpf_agent
eBPF μμ΄μ νΈλ₯Ό μ΄μ©νλ©΄ μ¬μ©μ 곡κ°μμ eBPF λ§΅μ 미리 μ±μ°κ³ λ§΅μ ν΅ν΄ ν΅κ³λ₯Ό κ΄μ°°νμ¬ κ·Έ νΌλλ°±μ λ°λΌμ κ°λ Ή λ°νμ μ€μ eBPF λ§΅ κ°μ classidλ₯Ό λ°κΏ μΈ μ μλ€. eBPF μμ΄μ νΈλ μΌλ°μ μΈ μμ©μ²λΌ ꡬννλ―λ‘ λμ μΌλ‘ μΈλΆ 컨νΈλ‘€λ¬μκ²μ νΈλν½ μ μ΄ μ μ± μ λ°μμ eBPF λ§΅μΌλ‘ λ΄λ € μ£Όμ΄ λ§ μ‘°κ±΄μ λμ μΌλ‘ μ μν μλ μλ€. λν eBPF λ§΅μ λ€λ₯Έ μ’ λ₯μ (κ°λ Ή μΆμ μ μν) eBPF νλ‘κ·Έλ¨λ€κ³Ό 곡μ ν μλ μμΌλ―λ‘ μμ£Ό κ°λ ₯ν μ‘°ν©μ ꡬνν μ μλ€.
eBPF λΆλ₯μμ νμλ μ μ½λ C λ¬Έλ²μΌλ‘ ꡬννλ€. (ν₯ν μλ‘μ΄ μΈμ΄ νλ‘ νΈμλκ° μΆκ°λ‘ μ§μλ μλ μλ€.)
ν€λ νμΌ linux/bpf.h
μ eBPF νλ‘κ·Έλ¨μμ νΈμΆν μ μλ eBPF ν¬νΌ ν¨μλ€μ΄ μλ€. μ΄ λ§¨ νμ΄μ§μμλ μ΅μνμ λ¨λ
μμ λ κ°μ§λ§ μ 곡νλ€. eBPFμ κ°λ₯μ±μ λ μ λ³΄μ¬ μ£Όλ μ λλ‘ λ νλ¦ λΆμ νλ‘κ·Έλ¨μ λ³΄λ €λ©΄ iproute2 μμ€ ν¨ν€μ§μ examples/bpf
λ₯Ό μ΄ν΄λ³΄λ©΄ λλ€.
μ§μνλ C νλ‘κ·Έλ¨ 32λΉνΈ λΆλ₯μ λ°ν μ½λμ κ·Έ μλ―Έ:
- 0: λΆμΌμΉλ₯Ό λνλΈλ€.
- -1: λͺ λ Ήνμμ μ€μ ν κΈ°λ³Έ classidλ₯Ό λνλΈλ€.
- κ·Έ μΈ: κΈ°λ³Έ classidλ₯Ό λμ νμ¬ λΉμ ν μΌμΉ κ²μ¬κ° κ°λ₯νκ² ν΄ μ€λ€.
μ§μνλ C νλ‘κ·Έλ¨ 32λΉνΈ νμ λ°ν μ½λμ κ·Έ μλ―Έ (linux/pkt_cls.h
):
-
TC_ACT_OK
(0): ν¨ν· μ²λ¦¬ νμ΄νλΌμΈμ μ’ λ£νκ² λλ©° ν¨ν·μ΄ κ³μ μ§ννλλ‘ νλ€. -
TC_ACT_SHOT
(2): ν¨ν· μ²λ¦¬ νμ΄νλΌμΈμ μ’ λ£νκ² λλ©° ν¨ν·μ λ²λ¦°λ€. -
TC_ACT_UNSPEC
(-1): tcμμ μ€μ ν κΈ°λ³Έ νμλ₯Ό μ¬μ©νλ€. (λΆλ₯μμ -1 λ°νκ³Ό λΉμ·νλ€.) -
TC_ACT_PIPE
(3): λ€μ νμκ° μμΌλ©΄ κ±°κΈ°λ‘ λμ΄κ°κ² λλ€. -
TC_ACT_RECLASSIFY
(1): ν¨ν· μ²λ¦¬ νμ΄νλΌμΈμ μ’ λ£νκ² λλ©° ν¨ν· λΆλ₯λ₯Ό μ²μλΆν° μμνλ€. - κ·Έ μΈ: λ€λ₯Έ κ°μ λͺ¨λ λΉλͺ μΈ λ°ν μ½λμ΄λ€.
λΆλ₯μ λ°ν μ½λμ νμ λ°ν μ½λ λͺ¨λλ₯Ό eBPF λ° eBPF νλ‘κ·Έλ¨μμ μ¬μ©ν μ μλ€.
μ‘°κ·Έλ§ λΆλ₯κΈ° μμλ₯Ό ν΅ν΄ μ μ½λ C λ¬Έλ²μ μ΄ν΄λ³΄μ. μ¬κΈ°μ κ°λ Ή 컨ν μ΄λμμ μΆλ°ν μΆλ ₯ ν¨ν·λ€μ [0, 255] λ²μλ‘ μ΄λ―Έ νμκ° λμ΄ μλ€κ³ κ°μ νλ€. μ΄ νλ‘κ·Έλ¨μ μ¬μ©μ 곡κ°μ μν΄ νμ κ°μ λν ν΅κ³λ₯Ό λ΄λ©° νμ κ° μ체λ₯Ό λΆ νΈλ€λ‘ ν΄μ λ£¨νΈ qdiscλ‘ classidλ₯Ό λ§€ν νλ€.
#include <stdint.h>
#include <asm/types.h>
#include <linux/bpf.h>
#include <linux/pkt_sched.h>
#include "helpers.h"
struct tuple {
long packets;
long bytes;
};
#define BPF_MAP_ID_STATS 1 /* μμ΄μ νΈμ λ§΅ μλ³μ */
#define BPF_MAX_MARK 256
struct bpf_elf_map __section("maps") map_stats = {
.type = BPF_MAP_TYPE_ARRAY,
.id = BPF_MAP_ID_STATS,
.size_key = sizeof(uint32_t),
.size_value = sizeof(struct tuple),
.max_elem = BPF_MAX_MARK,
};
static inline void cls_update_stats(const struct __sk_buff *skb,
uint32_t mark)
{
struct tuple *tu;
tu = bpf_map_lookup_elem(&map_stats, &mark);
if (likely(tu)) {
__sync_fetch_and_add(&tu->packets, 1);
__sync_fetch_and_add(&tu->bytes, skb->len);
}
}
__section("cls") int cls_main(struct __sk_buff *skb)
{
uint32_t mark = skb->mark;
if (unlikely(mark >= BPF_MAX_MARK))
return 0;
cls_update_stats(skb, mark);
return TC_H_MAKE(TC_H_ROOT, mark);
}
char __license[] __section("license") = "GPL";
λ λ€λ₯Έ μμ μλ λͺ©μ ν¬νΈ 80μ RSS κ²°κ³Όμ λ°λΌ [8080, 8087] ꡬκ°μΌλ‘ μλ€μ€ννλ ν¬νΈ 리λ€μ΄λ ν°μΈλ° μ λ ₯ qdiscμ λΆμΌ μ μλ€. μΆλ ₯ μͺ½κ³Ό IPv6 μ§μμ μΆκ°νλ κ²μ λ μμκ² μ°μ΅μΌλ‘ λ¨κ²¨λλ€.
#include <asm/types.h>
#include <asm/byteorder.h>
#include <linux/bpf.h>
#include <linux/filter.h>
#include <linux/in.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include "helpers.h"
static inline void set_tcp_dport(struct __sk_buff *skb, int nh_off,
__u16 old_port, __u16 new_port)
{
bpf_l4_csum_replace(skb, nh_off + offsetof(struct tcphdr, check),
old_port, new_port, sizeof(new_port));
bpf_skb_store_bytes(skb, nh_off + offsetof(struct tcphdr, dest),
&new_port, sizeof(new_port), 0);
}
static inline int lb_do_ipv4(struct __sk_buff *skb, int nh_off)
{
__u16 dport, dport_new = 8080, off;
__u8 ip_proto, ip_vl;
ip_proto = load_byte(skb, nh_off +
offsetof(struct iphdr, protocol));
if (ip_proto != IPPROTO_TCP)
return 0;
ip_vl = load_byte(skb, nh_off);
if (likely(ip_vl == 0x45))
nh_off += sizeof(struct iphdr);
else
nh_off += (ip_vl & 0xF) << 2;
dport = load_half(skb, nh_off + offsetof(struct tcphdr, dest));
if (dport != 80)
return 0;
off = skb->queue_mapping & 7;
set_tcp_dport(skb, nh_off - BPF_LL_OFF, __constant_htons(80),
__cpu_to_be16(dport_new + off));
return -1;
}
__section("lb") int lb_main(struct __sk_buff *skb)
{
int ret = 0, nh_off = BPF_LL_OFF + ETH_HLEN;
if (likely(skb->protocol == __constant_htons(ETH_P_IP)))
ret = lb_do_ipv4(skb, nh_off);
return ret;
}
char __license[] __section("license") = "GPL";
λ λͺ¨λμμ μ¬μ©νλ ν¬νΌ ν€λ νμΌ helpers.h
λ λ€μκ³Ό κ°λ€.
/* κΈ°ν ν¬νΌ λ§€ν¬λ‘ */
#define __section(x) __attribute__((section(x), used))
#define offsetof(x, y) __builtin_offsetof(x, y)
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
/* μ¬μ© λ§΅ ꡬ쑰 */
struct bpf_elf_map {
__u32 type;
__u32 size_key;
__u32 size_value;
__u32 max_elem;
__u32 id;
};
/* μ¬μ© BPF ν¨μ λͺ κ°μ§ */
static int (*bpf_skb_store_bytes)(void *ctx, int off, void *from,
int len, int flags) =
(void *) BPF_FUNC_skb_store_bytes;
static int (*bpf_l4_csum_replace)(void *ctx, int off, int from,
int to, int flags) =
(void *) BPF_FUNC_l4_csum_replace;
static void *(*bpf_map_lookup_elem)(void *map, void *key) =
(void *) BPF_FUNC_map_lookup_elem;
/* μ¬μ© BPF λ΄λΆ ν¨μ λͺ κ°μ§ */
unsigned long long load_byte(void *skb, unsigned long long off)
asm ("llvm.bpf.load.byte");
unsigned long long load_half(void *skb, unsigned long long off)
asm ("llvm.bpf.load.half");
μ΅μ κ΄νμΌλ‘ κΆνλ κ²μ κ°λ³ λΆλ₯μμ λ³λμ νμλ€μ λ§λλ λμ eBPF λΆλ₯μ νλλ§ tcλ‘ μ μ¬ν΄μ κ±°κΈ°μ νμν κ²μ¬μ μ‘°μμ λͺ¨λ μννλ κ²μ΄λ€. μ£Όμ΄μ§ μ©λμ λ§μΆ°μ§ λΆλ₯μ νλλ§ μ€ννλ κ² κ°μ₯ ν¨μ¨μ μΌ κ²μ΄λ€.
bpf
λ₯Ό μν tcμ filter
μ action
λͺ
λ Ή λͺ¨λμ μ νμ μΈ verbose
λ§€κ°λ³μκ° μμ΄μ μ΄λ₯Ό μ΄μ©ν΄ eBPF κ²μ¦κΈ° λ‘κ·Έλ₯Ό μ‘°μ¬ν μ μλ€. μ€λ₯ μμλ κΈ°λ³ΈμΌλ‘ μ°νλ€.
eBPF/cBPF JIT μ»΄νμΌλ¬λ₯Ό μΌ κ²½μ°μ λ§λ€μ΄μ§ λͺ
λ Ή μ½λ μ΄λ―Έμ§μ λλ²κ·Έ μΆλ ₯μ 컀λ λ‘κ·Έλ‘ μ°λλ‘ ν μλ μμΌλ©° dmesg(1)
λ₯Ό ν΅ν΄ μ΄λ₯Ό μ½μ μ μλ€.
echo 2 > /proc/sys/net/core/bpf_jit_enable
리λ
μ€ μ»€λ μμ€ νΈλ¦¬μ tools/net/
μλ bpf_jit_disasm
μ΄λΌλ μμ ν¬νΌ νλ‘κ·Έλ¨μ΄ μλ€. 컀λ λ‘κ·Έμμ λͺ
λ Ή μ½λ μ΄λ―Έμ§ λ€νλ₯Ό μ½μ΄μ μμ΄μ
λΈ κ²°κ³Όλ₯Ό μ°μ΄ μ€λ€.
bpf_jit_disasm -o
κ·Έ μΈμλ 리λ
μ€ μ»€λμλ test_bpf
λΌλ κ΄λ²μν eBPF/cBPF ν
μ€νΈ μ€μνΈ λͺ¨λλ ν¬ν¨λΌ μλ€.
modprobe test_bpf
μ΄λ κ² νλ©΄ λ€μν ν
μ€νΈ μΌμ΄μ€λ€μ μνν΄μ κ²°κ³Όλ₯Ό 컀λ λ‘κ·Έλ‘ μ°λλ€. dmesg(1)
λ‘ μ΄λ₯Ό μ‘°μ¬ν μ μλ€. JIT μ»΄νμΌλ¬κ° μΌμ Έ μλμ§ μ¬λΆμ λ°λΌ κ²°κ³Όκ° λ€λ₯Ό μ μλ€. μ€ν¨ν ν
μ€νΈ μΌμ΄μ€κ° μλ κ²½μ° λͺ¨λ μ μ¬κ° μ€ν¨νκ² λλ€. κ·Έ κ²½μ° κ΄λ ¨ JIT μμ±μλ€κ³Ό 리λ
μ€ μ»€λ λ° λ€νΈμνΉ λ©μΌλ§ 리μ€νΈλ‘ λ²κ·Έλ₯Ό λ³΄κ³ ν΄ μ£ΌκΈ°λ₯Ό κ°λ ₯ν κΆνλ€.
μΌλ°μ μΌλ‘ λΆλ₯μμ νμλ₯Ό eBPFλ‘ κ΅¬ννλ κ±Έλ‘ μ ννκΈ°λ₯Ό κΆνλ€. λ€λ§ μμ μ±μ μν΄ cBPF νλ‘κ·Έλ¨ μμ±μ λν μ¬κΈ° λͺ λ§λλ₯Ό λ¨κΈ΄λ€.
λ§μ°¬κ°μ§λ‘ μμ μΈκΈν κ²μ²λΌ bpf_jit_enable
μ€μμΉλ₯Ό μΌ€ μ μλ€. bpf_jit_disasm
κ°μ λꡬλ eBPFμ cBPF μ΄λ μͺ½ μ½λλ₯Ό μ μ¬νλ €λμ§μ 무κ΄νλ€.
eBPFμμμ²λΌ λΆλ₯μμ νμλ₯Ό μ μ½λ Cλ‘ κ΅¬ννμ§ μκ³ λ¨μν μ΄μ λΈλ¦¬ λΉμ·ν μΈμ΄λ‘, λλ λ€λ₯Έ λꡬμ λμμΌλ‘ ꡬννλ€.
tcμ μ μμ€ μΈν°νμ΄μ€λ λͺ λ Ή μ½λλ₯Ό μ§μ λ°λλ€. μλ₯Ό λ€μ΄ λͺ¨λ ν¨ν·μ κ±Έλ €μ κΈ°λ³Έ classid 1:1μ λ°ννλ κ°μ₯ λ¨μν λΆλ₯μλ λ€μκ³Ό κ°λ€.
tc filter add dev em1 parent 1: bpf bytecode '1,6 0 0 4294967295,' flowid 1:1
λ°μ΄νΈμ½λ μ΄μ 첫 λ²μ§Έ μμ§μ μλ μ΄μ΄μ§λ 4νν cBPF λͺ
λ Ή μ½λλ€μ κ°μλ₯Ό λνλΈλ€. μΈκΈν κ²μ²λΌ 4ννμ c t f k
λΌλ μμ§μλ€λ‘ μ΄λ€μ§λ©°, c
λ cBPF λͺ
λ Ή μ½λλ₯Ό, t
λ μ°ΈμΌ λ μ ν λμ μ€νμ
μ, f
λ κ±°μ§μΌ λ μ ν λμ μ€νμ
μ, k
λ μ¦μμ μμ/리ν°λ΄μ λνλΈλ€. μ λͺ
λ Ή μ½λλ μ¦μ κ° -1λ‘ νλ‘κ·Έλ¨μμ 무쑰건 λ°ννλ κ²μ λνλΈλ€.
μΆλ ₯ λΆλ₯μ μμ΄μ , Willem de Bruijnμ΄ iptables(8)
BPF νμ₯μ μν΄ GNU μΌλ° κ³΅μ€ μ¬μ© νκ°μ λ²μ 2λ‘ κ΅¬νν κ°λ¨ν λ¨λ
ν ν¬νΌ νλ‘κ·Έλ¨μ΄ μλλ° libpcap
λ΄λΆμ μ ν΅μ BPF μ»΄νμΌλ¬λ₯Ό μ΄μ©νλ€. μ¬κΈ° μ½λλ tc(8)
μμ μ¬μ©μ μν΄ κ·Έμ μ½λμμ νμλ κ²μ΄λ€.
#include <pcap.h>
#include <stdio.h>
int main(int argc, char **argv)
{
struct bpf_program prog;
struct bpf_insn *ins;
int i, ret, dlt = DLT_RAW;
if (argc < 2 || argc > 3)
return 1;
if (argc == 3) {
dlt = pcap_datalink_name_to_val(argv[1]);
if (dlt == -1)
return 1;
}
ret = pcap_compile_nopcap(-1, dlt, &prog, argv[argc - 1],
1, PCAP_NETMASK_UNKNOWN);
if (ret)
return 1;
printf("%d,", prog.bf_len);
ins = prog.bf_insns;
for (i = 0; i < prog.bh_len - 1; ++ins, ++i)
printf("%u %u %u %u,", ins->code,
ins->jt, ins->jf, ins->k);
printf("%u %u %u %u",
ins->code, ins->jt, ins->jf, ins->k);
pcap_freecode(&prog);
return 0;
}
μ΄ μμ ν¬νΌκ° μμΌλ©΄ λΆλ₯μμ μ΄λ€ tcpdump(8)
νν° μλ μ¬μ©ν μ μλ€. μΌμΉνλ©΄ κΈ°λ³Έ classidλ₯Ό λ°ννλ€.
bpftool EN10MB 'tcp[tcpflags] & tcp-syn != 0' > /var/bpf/tcp-syn
tc filter add dev em1 parent 1: bpf bytecode-file /var/bpf/tcp-syn flowid 1:1
κΈ°λ³Έμ μΌλ‘ μ΄ μμ μμ±κΈ°λ λ€μκ³Ό λλ±νλ€.
tcpdump -iem1 -ddd 'tcp[tcpflags] & tcp-syn != 0' | tr '\n' ',' > /var/bpf/tcp-syn
libpcap
μ μ»΄νμΌλ¬μμλ 리λ
μ€ νμ cBPF νμ₯λ€μ λͺ¨λ μ§μνμ§ μλλ€. κ·Έλμ 리λ
μ€ μ»€λμλ tools/net/
μλμ bpf_asm
μ΄λΌλ κ°λ¨ν BPF μ΄μ
λΈλ¬κ° μμ΄μ μμ ν μ μ΄κ° κ°λ₯νκ² ν΄ μ€λ€. κ·Έλ° νλ‘κ·Έλ¨μ μ§μ μμ±νκΈ° μν μμΈν λ¬Έλ²κ³Ό μλ―Έλ‘ μ FURTHER READINGμ μ°Έκ³ μλ£λ₯Ό 보λΌ.
IPv4/TCP ν¨ν·μ λΆλ₯νκΈ° μν bpf_asm
νμμ κ°λ¨ν μκ° foobar
λΌλ ν
μ€νΈ νμΌμ μ μ₯λμ΄ μλ€κ³ νμ.
ldh [12]
jne #0x800, drop
ldb [23]
jneq #6, drop
ret #-1
drop: ret #0
λ§μ°¬κ°μ§λ‘ λ€μκ³Ό κ°μ΄ κ·Έ λΆλ₯μλ₯Ό μ μ¬ν μ μλ€.
bpf_asm foobar > /var/bpf/tcp-syn
tc filter add dev em1 parent 1: bpf bytecode-file /var/bpf/tcp-sync flowid 1:1
BPF λΆλ₯μλ₯Ό μν΄ λ¦¬λ
μ€ μ»€λμμλ tools/net/
μλμ bpf_dbg
λΌλ μμ BPF λλ²κ±°λ₯Ό μΆκ°λ‘ μ 곡νλ€. μ΄λ₯Ό μ΄μ©ν΄ pcap νμΌμ λΆλ₯μλ₯Ό λλ € λ³΄κ³ , μ ν΅μ νλ‘κ·Έλ¨μ λ¨κ³ μ€ν νκ±°λ λ€μν μ€μ§μ μ μΆκ°νκ³ , λ°νμμ λ μ§μ€ν° λ΄μ©μ μ°μ΄ λ³Ό μ μλ€.
μ ν΅μ BPFλ‘ νμλ₯Ό ꡬννλ κ²μλ μλΉν μ μ½μ΄ μλ€. ν¨ν· λ³κ²½μ μ§μνμ§ μκΈ° λλ¬Έμ΄λ€. λ°λΌμ κ°λ₯νλ€λ©΄ eBPFλ‘ μ ννκΈ°λ₯Ό μΌλ°μ μΌλ‘ κΆμ₯νλ€.
리λ
μ€ μ»€λ μμ€ νΈλ¦¬μ Documentation/networking/filter.txt
μμ BPF 체κ³μ λν λ λ§μ κΈ°μ μ μΈλΆ λ΄μ©μ λ³Ό μ μλ€.
iproute2 μμ€ νΈλ¦¬μ examples/bpf/
λ΄μμ λ μμΈν eBPF tc(8)
μλ€μ λ³Ό μ μλ€.
tc(8)
, tc-ematch(8)
, bpf(2), bpf(4)
Daniel Borkmannμ΄ λ§¨ νμ΄μ§ μμ±ν¨.
μμ λ΄μ§ κ°μ μ¬νμ 리λ μ€ μ»€λ λ€νΈμνΉ λ©μΌλ§ 리μ€νΈ [email protected]λ‘ μλ € μ£ΌκΈ° λ°λλ€.
2015λ 5μ 18μΌ