eXpress แแแแแชแแแแ แแแแแแแก (XDP) แขแแฅแแแแแแแ แกแแจแฃแแแแแแก แแซแแแแ แขแ แแคแแแแก แแแแแแแแฃแ แ แแแแฃแจแแแแแ Linux แแแขแแ แคแแแกแแแแ, แกแแแแ แแแแแขแแแ แจแแแ แแแ แแแแก แฅแกแแแแก แแแกแขแแจแ. XDP-แแก แแแแแงแแแแแ - แแแชแแ DDoS แจแแขแแแแแแกแแแ (CloudFlare), แ แแฃแแ แคแแแขแ แแแ, แกแขแแขแแกแขแแแแก แจแแแ แแแแแ (Netflix). XDP แแ แแแ แแแแแ แจแแกแ แฃแแแแฃแแแ eBPF แแแ แขแฃแแแฃแ แ แแแแฅแแแแก แแแแ แแ, แจแแกแแแแแแกแแ, แแฅแแก แจแแแฆแฃแแแแแ แ แแแแ แช แแแ แแแแแ, แแกแแแ แแแ แแแแก แฎแแแแแกแแฌแแแแ แคแฃแแฅแชแแแแแ, แคแแแขแ แแก แขแแแแก แแแฎแแแแแ.
แกแขแแขแแ แแแแแแ แแกแแฎแแแก XDP-แแ แแ แกแแแฃแแ แแ แแแแแ แแแกแแแแก แแแแแแแแแแแแก แแแแแฆแแฃแ แแแแก. แแแ แแแ แ แแแจแ, แแกแแแ แฃแแ แฃแแแแแงแแคแแ แแแ แแแแก, แ แแแแแแช แแแฃแงแแแแแแแแ แแแแ แแก แฃแแแแก XDP-แแก แแแฎแแกแแแแแแแแแก: แแแแแแแแแฃแแแ แแแแแแแฌแแแแแกแแแแก แแ แซแแแแแ แแแ แขแแแแ แแ แแแแแแแแแก แฌแแ แแแจแแแแกแแแแก. แ แแแแกแแช แแแแแแแแแแแ แชแแแแแแ แแแฌแแ แแ แแฅแแแแ แกแแแฃแแแ แ แแแแ แแฃแแแแแ, แแ แแแกแแแ, แ แ แฃแแแ แแแแแแแแ แขแแแแฃแ แจแแชแแแแแแแแ. แแแแ แแช, แแก แแ แแแแชแแแก XDP แแแแแแแแ แแแแ แขแแกแขแแ แแแแก แแแแแก VM-แแกแ แแ แแแแ แแขแฃแ แแก แแแ แแจแ, แแแฃแฎแแแแแแ แแแแกแ, แ แแ แแแ แแฅแแ แกแแแฃแแแ แ แฎแแ แแแแแแ. แขแแฅแกแขแ แแแแแฃแแแแแแแ แแ แแแ แแแแกแขแแแแกแแแแก, แ แแแแแแแช แแแ แแแ แแชแแแแแ แฅแกแแแแแกแ แแ Linux-แก, แ แแแแแแแช แแแแแขแแ แแกแแแฃแแแ แแ แแแ XDP-แแ แแ eBPF-แแ.
แแ แแแฌแแแจแ แฉแแแ แแแขแแแฃแ แแ แแแแแแแแ, แแฃ แ แแแแ แแ แแก แแฌแงแแแแแ XDP แคแแแขแ แ แแ แ แแแแ แจแแแแแแฌแแแ แแแ, แจแแแแแ แแแแฌแแ แ แชแแแแแแ SYN แฅแฃแฅแแแแแก แแแฅแแแแแแแก แแแ แขแแ แแแ แกแแแก แแแแแขแแก แแแแฃแจแแแแแแก แแแแแแ. แกแแแแ แแ แจแแแฅแแแแ "แแแแ แกแแแก"
แแแแแฌแแแแฃแแ แแแแแแขแแแ, แจแแแแแฎแแ แแ แแชแฎแแแแแแ แแ แแแ แแแ แคแแแขแ แ - แกแแแแแ แแกแ แแฃแ แแแแ.
แฉแแแ แแแแฌแแ แ C - แแก แแ แแ แแก แแแแฃแ แ, แแแแ แแ แแ แแฅแขแแแฃแแ. แงแแแแ แแแแ แฎแแแแแกแแฌแแแแแแ GitHub-แแ แแแแ แแแฃแแแ แแ แแแงแแคแแแแ แแแแแแแฃแแแแแแแ แกแขแแขแแแจแ แแฆแฌแแ แแแ แแแแแฏแแแแก แแแฎแแแแแ.
แแแกแฃแฎแแกแแแแแแแแแก แฃแแ แงแแคแ. แกแขแแขแแแก แแกแแแแแแแแกแแก แจแแแฃแจแแแแแแ แแแแ แแแแแฌแงแแแขแ DDoS แจแแขแแแแแแก แแแกแแแแ แแแแแแ, แ แแแแแ แแก แแ แแก แ แแแแแกแขแฃแ แ แแแแชแแแ XDP-แกแแแแก แแ แฉแแแ แขแแ แแขแแ แแแกแแแแก. แแฃแแชแ, แแแแแแ แ แแแแแแ แขแแฅแแแแแแแแก แแแแแแแ, แแก แแ แแ แแก แแแ แแแชแแแก แจแแฅแแแแก แกแแฎแแแแซแฆแแแแแแ. แกแแแแฃแ แแแ แแแแ แแ แแ แแก แแแขแแแแแแแฃแแ แแ แแแแแขแแแแแก แแแแแแ แ แแแฃแแแกแก.
XDP-แแก แแแแแ แแแแแฎแแแแ
แแแแแกแแฎแแแแ แแฎแแแแ แซแแ แแแแ แแฃแแฅแขแแแก, แ แแแ แแ แแแฎแแแก แแแแฃแแแแขแแชแแแก แแ แแ แกแแแฃแแ แกแขแแขแแแแแก แแฃแแแแ แแแ.
แแกแ แ แแ, แคแแแขแ แแก แแแแ แแขแแแ แแแแ แแแ แแแจแ. แคแแแขแ แก แแแแแแชแแแ แจแแแแแแแแแ แแแแแขแแแ. แจแแแแแแ, แคแแแขแ แแ แฃแแแ แแแแฆแแก แแแแแฌแงแแแขแแแแแ: แแแแแกแชแแก แแแแแขแ แแแ แแแก (XDP_PASS
), แฉแแแแแแแ แแแแแขแ (XDP_DROP
) แแ แแแฃแแแแแแ แฃแแแ (XDP_TX
). แคแแแขแ แก แจแแฃแซแแแ แจแแชแแแแแก แแแแแขแ, แแก แแแแกแแแฃแแ แแแแ แแฎแแแ XDP_TX
. แแฅแแแ แแกแแแ แจแแแแซแแแแ แแแจแแแแ แแ แแแ แแแ (XDP_ABORTED
) แแ แฉแแแแแแแแ แแแแแขแ, แแแแ แแ แแก แแแแแแแแฃแ แแ assert(0)
- แแแแแ แแแแกแแแแก.
eBPF (แแแคแแ แแแแแฃแแ แแแ แแแแก แแแแแขแแก แคแแแขแ แ) แแแ แขแฃแแแฃแ แ แแแแฅแแแ แแแแแ แแฎ แแแแแ แขแแแแแฃแแแ แแกแ, แ แแ แแแ แแแแ แจแแซแแแก แจแแแแแฌแแแก, แ แแ แแแแ แแ แฎแแแแแ แแ แแ แแแแแแแแก แกแฎแแ แแแแแแแแแแแก แแแฎแกแแแ แแแแก. แแฃแแฃแแแชแแฃแ แ แจแแแฆแฃแแแแแ แแ แจแแแแฌแแแแแแ:
- แแแ แงแฃแแแแ (แฃแแแ แแแแแฎแขแแแ) แแแ แซแแแฃแแแ.
- แแ แกแแแแแก แแแแแชแแแแแแก แแแกแขแ, แแแแ แแ แคแฃแแฅแชแแแแ แแ แแ แแก (แงแแแแ C แคแฃแแฅแชแแ แฃแแแ แแงแแก แฉแแกแแฃแแ).
- แแแ แซแแแฃแแแ แฌแแแแแ แแแฎแกแแแ แแแแแ แกแขแแแแกแ แแ แแแแแขแแแแก แแฃแคแแ แแก แแแ แแ.
- แแแแแก แแแแ แจแแแฆแฃแแฃแแแ, แแแแ แแ แแ แแฅแขแแแแจแ แแก แแ แแ แแก แซแแแแแ แแแแจแแแแแแแแแ.
- แแแกแแจแแแแแ แแฎแแแแ แแแ แแแแก แกแแแชแแแแฃแ แ แคแฃแแฅแชแแแแ (eBPF แแแแฎแแแ แแแแ).
แคแแแขแ แแก แจแแแฃแจแแแแแ แแ แแแงแแแแแ แแกแ แแแแแแงแฃแ แแแ:
- แฌแงแแ แแก แแแแ (แแแ.
kernel.c
) แแฌแงแแแก แแแแแฅแขแก (kernel.o
) eBPF แแแ แขแฃแแแฃแ แ แแแแฅแแแแก แแ แฅแแขแแฅแขแฃแ แแกแแแแก. 2019 แฌแแแก แแฅแขแแแแ แแก แแแแแแแ แแแแแ, eBPF-แจแ แจแแแแแแแก แแฎแแ แก แฃแญแแ แก Clang แแ แแแแแ แแแฃแแแ GCC 10.1-แจแ. - แแฃ แแ แแแแแฅแขแแก แแแแจแ แแ แแก แแแ แแแ แแแ แแแแก แกแขแ แฃแฅแขแฃแ แแแแ (แแแแแแแแแ, แชแฎแ แแแแแกแ แแ แแ แแชแฎแแแแแแแ), แแแแ ID-แแแแก แแแชแแแแ แแ แแก แแฃแแแแ, แแแฃ แแกแแแ แแแแ แแ แจแแแซแแแแ แจแแกแ แฃแแแแก. แแแ แแแจแ แฉแแขแแแ แแแแแแ, แแก แแฃแแแแ แฃแแแ แจแแแชแแแแแก แแแ แแแแก แแแแแซแแฎแแแแ แจแแฅแแแแแ แแแแแ แแขแฃแแ แแแแแฅแขแแแแก ID-แแแแ (แแแแแแแจแแ แแ แแแแ). แแแแก แแแแแแแแ แจแแแแซแแแแ แแแ แ แแแแฃแแแแฃแ แ แกแแจแฃแแแแแแแแ, แแ แจแแแแซแแแแ แแแฌแแ แแ แแ แแแ แแแ, แ แแแแแแช แแแแแแแจแแ แแแก แแ แฉแแขแแแ แแแแก แแแแแ แแขแฃแ แคแแแขแ แก.
- แแแ แแแ แแแแฌแแแแก แแ แแแ แแแแก แฉแแขแแแ แแแแก. แแก แแแแฌแแแแก แชแแแแแแแก แแ แแ แกแแแแแแก แแ แแแแแขแแกแ แแ แกแขแแแแก แกแแแฆแแ แแแแแแ แแ แแแกแแแแก. แแฃ แจแแแแแฌแแแแแแก แแ แจแแฃแซแแแ แแแแแขแแแชแแก, แ แแ แแแแ แกแฌแแ แแ, แแ แแแ แแแ แฃแแ แงแแคแแแแ - แแแก แฃแแแ แแแแฌแแแแก.
- แฌแแ แแแขแแแฃแแ แแแแแแแฌแแแแแก แจแแแแแ, แแแ แแแ แแแ แแแแแก eBPF แแ แฅแแขแแฅแขแฃแ แแก แแแแแฅแขแแก แแแแก แกแแกแขแแแแก แแ แฅแแขแแฅแขแฃแ แแก แแแแฅแแแแก แแแแจแ (แฃแแ แแแแ แแ แแฃแแแ).
- แแ แแแ แแแ แแ แแแแก แแแขแแ แคแแแกแก แแ แแฌแงแแแก แแแแแขแแแแก แแแแฃแจแแแแแแก.
แแแแแแแแ XDP แแฃแจแแแแก แแแ แแแจแ, แแแแแ แแแ แแคแฃแซแแแแ แแแแแแก แแฃแ แแแแแแก แแ, แคแแฅแขแแแ แแแแ, แแแแแขแแแก, แ แแแแแแกแแช แแ แแแ แแแ แคแแแขแ แแแก แแ แฅแแแแก. แแฃแแชแ, eBPF แแแแฎแแแก แฉแแแแขแแแ แแฃแ แแแแก แกแแกแขแแแแกแแแแก, แแกแ แ แแ แแฅแแแ แจแแแแซแแแแ แแฅแกแแแ แแแแแขแ XDP-แแ แแแ แแแแแ แแฅแแแแก แแแแแแแแ แแ Linux-แแ.
แแแ แแแแก แแแแแแแแแ
แแกแแแแแแ
Clang-แก แแ แจแแฃแซแแแ แแแ แแแแแ แแแกแชแแก แแแแแฅแขแแก แแแแ eBPF แแ แฅแแขแแฅแขแฃแ แแกแแแแก, แแแแขแแ แแ แแชแแกแ แจแแแแแแ แแ แ แแขแแแแกแแแ:
- C แแแแแก แจแแแแแแ LLVM แแแแขแแแแแจแ (
clang -emit-llvm
). - แแแแแแงแแแแแ แแแแขแแแแแ eBPF แแแแแฅแขแแก แแแแจแ (
llc -march=bpf -filetype=obj
).
แคแแแขแ แแก แแแฌแแ แแกแแก แกแแกแแ แแแแแ แแฅแแแแ แ แแแแแแแแ แคแแแแ แแแแฎแแแ แ แคแฃแแฅแชแแแแแแ แแ แแแแ แแแแแ KVER
). แฉแแแแขแแแ แแแ แแกแแแ helpers/
:
export KVER=v5.3.7
export BASE=https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/plain/tools/testing/selftests/bpf
wget -P helpers --content-disposition "${BASE}/bpf_helpers.h?h=${KVER}" "${BASE}/bpf_endian.h?h=${KVER}"
unset KVER BASE
Makefile Arch Linux-แแกแแแแก (แแแ แแแแ 5.3.7):
CLANG ?= clang
LLC ?= llc
KDIR ?= /lib/modules/$(shell uname -r)/build
ARCH ?= $(subst x86_64,x86,$(shell uname -m))
CFLAGS =
-Ihelpers
-I$(KDIR)/include
-I$(KDIR)/include/uapi
-I$(KDIR)/include/generated/uapi
-I$(KDIR)/arch/$(ARCH)/include
-I$(KDIR)/arch/$(ARCH)/include/generated
-I$(KDIR)/arch/$(ARCH)/include/uapi
-I$(KDIR)/arch/$(ARCH)/include/generated/uapi
-D__KERNEL__
-fno-stack-protector -O2 -g
xdp_%.o: xdp_%.c Makefile
$(CLANG) -c -emit-llvm $(CFLAGS) $< -o - |
$(LLC) -march=bpf -filetype=obj -o $@
.PHONY: all clean
all: xdp_filter.o
clean:
rm -f ./*.o
KDIR
แจแแแชแแแก แแแแก แแแ แแแแก แกแแแแฃแ แแแแกแแแ, ARCH
- แกแแกแขแแแฃแ แ แแ แฅแแขแแฅแขแฃแ แ. แแแแแแแแ แแ แฎแแแกแแฌแงแแแแ แจแแแซแแแแ แแแแแ แแแแกแฎแแแแแแแแแแก แแแแแฌแแแแแแแก แจแแ แแก.
แแแแกแฎแแแแแแแก แแแแแแแแ Debian 10-แแกแแแแก (แแแ แแแแ 4.19.67)
# ะดััะณะฐั ะบะพะผะฐะฝะดะฐ
CLANG ?= clang
LLC ?= llc-7
# ะดััะณะพะน ะบะฐัะฐะปะพะณ
KDIR ?= /usr/src/linux-headers-$(shell uname -r)
ARCH ?= $(subst x86_64,x86,$(shell uname -m))
# ะดะฒะฐ ะดะพะฟะพะปะฝะธัะตะปัะฝัั
ะบะฐัะฐะปะพะณะฐ -I
CFLAGS =
-Ihelpers
-I/usr/src/linux-headers-4.19.0-6-common/include
-I/usr/src/linux-headers-4.19.0-6-common/arch/$(ARCH)/include
# ะดะฐะปะตะต ะฑะตะท ะธะทะผะตะฝะตะฝะธะน
CFLAGS
แแแแชแแแก แแแ แแฅแขแแ แแแก แแแแฎแแแ แ แกแแแแฃแ แแแแ แแ แ แแแแแแแแ แแแ แแฅแขแแ แแแก แแแ แแแแก แกแแแแฃแ แแแแ. แกแแแแแแ __KERNEL__
แแแจแแแแก, แ แแ UAPI (userspace API) แกแแแแฃแ แแแ แแแแกแแแฆแแ แฃแแแ แแแ แแแแก แแแแแกแแแแก, แแแแแแแแ แคแแแขแ แ แจแแกแ แฃแแแแฃแแแ แแแ แแแจแ.
แแแกแขแแก แแแชแแ แจแแแซแแแแ แแแแแ แแแ (-fno-stack-protector
) แแแแขแแ, แ แแ eBPF แแแแแก แจแแแแแฌแแแแแแ แแแแแช แแแแฌแแแแก แแแขแแก แกแแแฆแแ แแแก แแ แแแกแชแแแก. แแแฃแงแแแแแแแแ แฃแแแ แฉแแ แแแ แแแขแแแแแแชแแ, แ แแแแแ eBPF แแแแขแแแแแแก แแแแ แจแแแฆแฃแแฃแแแ.
แแแแแฌแงแแ แคแแแขแ แแ, แ แแแแแแช แแแแแก แงแแแแ แแแแแขแก แแ แแ แแคแแ แก แแแแแแแก:
#include <uapi/linux/bpf.h>
#include <bpf_helpers.h>
SEC("prog")
int xdp_main(struct xdp_md* ctx) {
return XDP_PASS;
}
char _license[] SEC("license") = "GPL";
แแฃแแแ make
แแแ แแแแแก xdp_filter.o
. แกแแ แจแแแซแแแแ แแฎแแ แขแแกแขแแ แแแ?
แกแแขแแกแขแ แกแขแแแแ
แกแขแแแแ แฃแแแ แจแแแชแแแแแก แแ แแแขแแ แคแแแกแก: แ แแแแแแแแแช แแฅแแแแ แคแแแขแ แ แแ แกแแแแแแแช แแแแแแแแแแแ แแแแแขแแแ. แแก แฃแแแ แแงแแก แกแ แฃแแ Linux แแแฌแงแแแแแแแแแ แกแแแฃแแแ แ IP-แแแแ, แ แแแ แจแแแแแฌแแแ แ แแแแ แแฃแจแแแแก แ แแแฃแแแ แฃแแ แแแแแแแชแแแแ แฉแแแแก แคแแแขแ แแแ.
แฉแแแแแแแก แจแแกแแคแแ แแกแแ แแกแแแ แแแฌแงแแแแแแแแแ, แ แแแแ แแชแแ veth (แแแ แขแฃแแแฃแ แ แแแแ แแแขแ): แแก แแ แแก แฌแงแแแแ แแแ แขแฃแแแฃแ แ แฅแกแแแแก แแแขแแ แคแแแกแ, แ แแแแแแช แแแ แแแแแ "แแแแแแจแแ แแแฃแแแ" แแ แแแแแแแแแ. แแฅแแแ แจแแแแซแแแแ แจแแฅแแแแ แแกแแแ แแกแ (แแ แแแแงแแคแแแแแแจแ แงแแแแ แแ แซแแแแแ ip
แจแแกแ แฃแแแแฃแแ แกแแฌแงแแกแ root
):
ip link add xdp-remote type veth peer name xdp-local
แแฅ xdp-remote
ะธ xdp-local
- แแแฌแงแแแแแแแแแแก แกแแฎแแแแแ. แฉแแ แแฃแแแ xdp-local
(192.0.2.1/24) แแแแแแ แแแแ แคแแแขแ แ, แแแ xdp-remote
(192.0.2.2/24) แจแแแแแแแแแ แขแ แแคแแแ แแแแแแแแแแแ. แแฃแแชแ, แแ แแก แแ แแแแแแ: แแแขแแ แคแแแกแแแ แแ แแกแ แแ แแแแแ แแแแฅแแแแแแ แแ Linux แแ แแแฃแแแแแแแก แขแ แแคแแแก แแ แ แแแแแแแก แแแแ แแก แแแจแแแแแแ. แแฅแแแ แจแแแแซแแแแ แแแแแญแ แแ แ แแฃแแ แฌแแกแแแแ iptables
, แแแแ แแ แแแ แแแฃแฌแแแ แแแแแขแแแแก แจแแชแแแ, แ แแช แแแฃแฎแแ แฎแแแแแแ แแแแแ แแแแกแแก. แฃแแฏแแแแกแแ แแแแแแงแแแแ แฅแกแแแแก แกแแฎแแแแ แกแแแ แชแแแแ (แฅแกแแแแก แกแแฎแแแแ แกแแแ แชแแแแ, แจแแแแแแแ แฅแกแแแแแ).
แฅแกแแแแก แกแแฎแแแแ แกแแแ แชแ แจแแแชแแแก แแแขแแ แคแแแกแแแแก แแแแแแแฅแขแก, แแแ แจแ แฃแขแแแแชแแแก แชแฎแ แแแแแก แแ NetFilter-แแก แฌแแกแแแก, แ แแแแแแแช แแแแแแ แแแฃแแแ แกแฎแแ แฅแกแแแแแแก แแกแแแแกแ แแแแแฅแขแแแแกแแแ. แแแแแแฃแแ แแ แแชแแกแ แแแแแก แแแ แแแแฃแ แกแแฎแแแแ แกแแแ แชแแจแ แแ แแแกแแแแก แฎแแแแแกแแฌแแแแแแ แแฎแแแแ แแ แฅแกแแแแก แแแแแฅแขแแแ. แแแแฃแแแกแฎแแแแแ, แกแแกแขแแแแก แแฅแแก แแ แแแแแ แฅแกแแแแก แกแแฎแแแแแแก แกแแแ แชแ แงแแแแ แแแแแฅแขแแกแแแแก, แแกแ แ แแ แแฅแแแ แจแแแแซแแแแ แแแฃแจแแแ Linux-แแ แแ แแ แแชแแแแ แฅแกแแแแแแก แจแแกแแฎแแ.
แแแแแ แจแแแฅแแแแ แแฎแแแ แกแแฎแแแแ แกแแแ แชแ xdp-test
แแ แแฅ แแแแแแแแแแแแ xdp-remote
.
ip netns add xdp-test
ip link set dev xdp-remote netns xdp-test
แจแแแแแ แแ แแชแแกแ แแแแแแแแ แแแแก xdp-test
, แแ "แแแแฎแแ" xdp-local
(แแแแฃแแแกแฎแแแแแ แแแ แฉแแแ netns-แจแ) แแ 192.0.2.1-แแ แแแแแขแแก แแแแแแแแแกแแก แแแแแแแก แแแก xdp-remote
, แ แแแแแ แแก แแ แแก แแ แแแแแ แแ แแแขแแ แคแแแกแ 192.0.2.0/24-แแ, แ แแแแแแช แฎแแแแแกแแฌแแแแแแ แแ แแ แแชแแกแแกแแแแก. แแก แแกแแแ แแฃแจแแแแก แกแแแแ แแกแแแ แแ.
แฅแกแแแแแก แจแแ แแก แแแแแแแแแแแแแกแแก, แแแขแแ แคแแแกแ แแจแแแแ แแ แแแ แแแแก แแแกแแแแ แแก. แฅแกแแแแแจแ แแแขแแ แคแแแกแแก แแแกแแงแแแแแแแ, แแฅแแแ แฃแแแ แแแฃแจแแแ ip ...
แแ แแ แซแแแแแแก แกแแฎแแแแ แกแแแ แชแแจแ ip netns exec
:
ip netns exec xdp-test
ip address add 192.0.2.2/24 dev xdp-remote
ip netns exec xdp-test
ip link set xdp-remote up
แ แแแแ แช แฎแแแแแ, แแก แแ แแแแกแฎแแแแแแแ แแแ แแแแขแ แแกแแแ xdp-local
แแแแฃแแแกแฎแแแแ แกแแฎแแแแแแก แกแแแ แชแแจแ:
ip address add 192.0.2.1/24 dev xdp-local
ip link set xdp-local up
แแฃ แแแแฅแชแแแ tcpdump -tnevi xdp-local
, แแฅแแแ แฎแแแแแ, แ แแ แแแแแขแแแ แแแแแแแแแแแ xdp-test
, แแแแฌแแแแแ แแ แแแขแแ แคแแแกแก:
ip netns exec xdp-test ping 192.0.2.1
แแแกแแฎแแ แฎแแแแแแ แญแฃแ แแแก แแแจแแแแ xdp-test
. แกแแชแแแก แแฅแแก แกแแ แแแขแ, แ แแแแแแช แแแขแแแแขแแแแ แแแก แกแขแแแแแแ แแฃแจแแแแแก, แแแแแแแแแ, แจแแแแซแแแแ แแแแงแแแแ แกแขแแแแ แแ แซแแแแแแ sudo ./stand up
แแ แแแแแฆแแ แแแ sudo ./stand down
.
แแแแแแแแ
แคแแแขแ แ แแแแแแ แแแฃแแแ แแแฌแงแแแแแแแแแ แจแแแแแแแแแ แแ:
ip -force link set dev xdp-local xdp object xdp_filter.o verbose
แงแแแแแแ -force
แกแแญแแ แแ แแฎแแแ แแ แแแ แแแแก แแแกแแแแแจแแ แแแแแ, แแฃ แกแฎแแ แฃแแแ แแแแแแจแแ แแแฃแแแ. "No news is good news" แแ แแ แแก แแ แแ แซแแแแแแก แจแแกแแฎแแ, แแแแแแแแแแ แแแแแช แแแชแฃแแแแแแแ. แแแฃแแแแแ verbose
แกแฃแ แแแแแกแแแแแ , แแแแ แแ แแแกแแแ แแ แแแ แฉแแแแแ แแแแแ แแจแ แแแแแก แแแแแแแกแขแฃแ แแแแแ แแฃแจแแแแแก แจแแกแแฎแแ แแกแแแแแแ แแก แฉแแแแแแแแแแแ:
Verifier analysis:
0: (b7) r0 = 2
1: (95) exit
แแแแแฆแแ แแ แแแ แแแ แแแขแแ แคแแแกแแแแ:
ip link set dev xdp-local xdp off
แกแแ แแแขแจแ แแก แแ แแก แแ แซแแแแแแแ sudo ./stand attach
ะธ sudo ./stand detach
.
แคแแแขแ แแก แจแแแแ แแ แจแแแแซแแแแ แแแ แฌแแฃแแแแ แแแแจแ ping
แแแ แซแแแแแก แแฃแจแแแแแก, แแแแ แแ แแฃแจแแแแก แแฃ แแ แ แแ แแแ แแแ? แแแแแ แแแแแแแขแแ แแแแแแแ. แคแฃแแฅแชแแ bpf_trace_printk()
printf()
, แแแแ แแ แแฎแแ แก แฃแญแแ แก แแฎแแแแ แกแแ แแ แแฃแแแแขแก, แแแ แแ แจแแแแแแแกแ แแ แกแแแชแแคแแแแขแแ แแแแก แจแแแฆแฃแแฃแ แกแแแก. แแแแ แ bpf_printk()
แแแแ แขแแแแแก แแแ แก.
SEC("prog")
int xdp_main(struct xdp_md* ctx) {
+ bpf_printk("got packet: %pn", ctx);
return XDP_PASS;
}
แแแแแแแแแแ แแแแแก แแแ แแแแก แแแแแแก แแ แฎแแ, แ แแแแแแช แฃแแแ แแงแแก แฉแแ แแฃแแ:
echo -n 1 | sudo tee /sys/kernel/debug/tracing/options/trace_printk
แจแแขแงแแแแแแแแแแก แแแแแแแก แแแฎแแ:
cat /sys/kernel/debug/tracing/trace_pipe
แแ แแแ แแก แแฃแแแ แแแ แก แแแแแแแก sudo ./stand log
.
Ping-แแ แแฎแแ แฃแแแ แแฌแแ แแแแก แแแกแจแ แแกแแแแกแ แจแแขแงแแแแแแแแแ:
<...>-110930 [004] ..s1 78803.244967: 0: got packet: 00000000ac510377
แแฃ แงแฃแ แแแฆแแแแ แแแแแแแ แแแแแ แแแ แแคแแแแขแแ แแก แแแแแแแแแแก, แจแแแแซแแแแ แจแแแแฉแแแแ แฃแชแแแฃแ แ แแแแแแแแแแ:
0: (bf) r3 = r1
1: (18) r1 = 0xa7025203a7465
3: (7b) *(u64 *)(r10 -8) = r1
4: (18) r1 = 0x6b63617020746f67
6: (7b) *(u64 *)(r10 -16) = r1
7: (bf) r1 = r10
8: (07) r1 += -16
9: (b7) r2 = 16
10: (85) call bpf_trace_printk#6
<...>
แคแแฅแขแแ, แ แแ eBPF แแ แแแ แแแแแก แแ แแฅแแ แแแแแชแแแแ แแแแงแแคแแแแแ, แแแแขแแ แคแแ แแแขแแก แกแขแ แแฅแแแแก แแแแแ แแแแก แแ แแแแแ แแ แแแ แแ แแก VM แแ แซแแแแแแแแก แฃแจแฃแแแ แแ แแฃแแแแขแแแ:
$ python -c "import binascii; print(bytes(reversed(binascii.unhexlify('0a7025203a74656b63617020746f67'))))"
b'got packet: %pn'
แแ แแแแแแแ, แแแแแ แแแแก แแแแแแแแแแ แแแแจแแแแแแแแแ แแคแฃแญแแแก แจแแแแแแ แแแแก.
XDP แแแแแขแแแแก แแแแแแแแ
แแแแแ แจแแแชแแแแแ แคแแแขแ แ: แแแแ แแแแชแแ แแแก แฃแแแ แแแแแแแแแแแแก แงแแแแ แจแแแแแแแแแ แแแแแขแ. แแก แแ แแกแฌแแ แแ แฅแกแแแแก แแแแแกแแแ แแกแแ, แ แแแแแ แกแแญแแ แ แแฅแแแแแแ แแแกแแแแ แแแแแก แจแแชแแแ แกแแแแฃแ แแแจแ, แแแแ แแ แแฎแแ แแ แแแชแแแจแ แแฃแจแแแแ แแแแจแแแแแแแแแแ.
bpf_printk("got packet: %pn", ctx);
- return XDP_PASS;
+ return XDP_TX;
}
แแแจแแแแ tcpdump
on xdp-remote
. แแแ แฃแแแ แแฉแแแแแก แแแแแขแฃแ แ แแแแแแแแ แแ แจแแแแแแแแแ ICMP Echo แแแแฎแแแแ แแ แจแแฌแงแแแขแแก ICMP Echo Reply-แแก แฉแแแแแแ. แแแแ แแ แแ แฉแแแก. แแฃแจแแแแก XDP_TX
แแ แแแ แแแแจแ xdp-local
xdp-remote
แแ แแแ แแแแช แแแแแแจแแ, แแฃแแแแช แชแแ แแแแ แแงแ แแ แแแแฆแแแ.
แกแแแแแ แแแชแแแ?
แแแ แแขแแแแกแแแ แกแแแแแ แฃแแแ แแแแแแแฃแจแแแ, แ แแแแแ แกแฎแแ แแ แแคแแ แแ แแแกแแแแแแแแแ.
$ sudo perf trace --call-graph dwarf -e 'xdp:*'
0.000 ping/123455 xdp:xdp_bulk_tx:ifindex=19 action=TX sent=0 drops=1 err=-6
veth_xdp_flush_bq ([veth])
veth_xdp_flush_bq ([veth])
veth_poll ([veth])
<...>
แ แ แแ แแก แแแแ 6?
$ errno 6
ENXIO 6 No such device or address
แคแฃแแฅแชแแ veth_xdp_flush_bq()
แแฆแแแก แจแแชแแแแแก แแแแก veth_xdp_xmit()
, แกแแแแช แซแแแแ ENXIO
แแ แแแแแแแ แแแแแแขแแ แ.
แแฆแแแแแแแ แแแแแแแแฃแ แ แคแแแขแ แ (XDP_PASS
) แคแแแแจแ xdp_dummy.c
, แแแแแแขแแ แแแ Makefile-แจแ, แแแแแแแจแแ แแ xdp-remote
:
ip netns exec remote
ip link set dev int xdp object dummy.o
แแฎแแ tcpdump
แแฉแแแแแแก แ แ แแ แแก แแแกแแแแแแแแ:
62:57:8e:70:44:64 > 26:0e:25:37:8f:96, ethertype IPv4 (0x0800), length 98: (tos 0x0, ttl 64, id 13762, offset 0, flags [DF], proto ICMP (1), length 84)
192.0.2.2 > 192.0.2.1: ICMP echo request, id 46966, seq 1, length 64
62:57:8e:70:44:64 > 26:0e:25:37:8f:96, ethertype IPv4 (0x0800), length 98: (tos 0x0, ttl 64, id 13762, offset 0, flags [DF], proto ICMP (1), length 84)
192.0.2.2 > 192.0.2.1: ICMP echo request, id 46966, seq 1, length 64
แแฃ แแแก แแแชแแแแ แแแฉแแแแแแแ แแฎแแแแ ARP, แแฅแแแ แฃแแแ แแแแแฆแแ แคแแแขแ แแแ (แแก แฎแแแก sudo ./stand detach
), แแแแแ ping
, แจแแแแแ แแแแแแกแขแแแแ แแ แคแแแขแ แแแ แแ แกแชแแแแ แฎแแแแฎแแ. แแ แแแแแแ แแก แแ แแก, แ แแ แคแแแขแ แ XDP_TX
แแแแแแแแก แแฎแแแแก ARP-แแแช แแ แแฃ แกแขแแแ
แกแแฎแแแแ แกแแแ แชแแแแ xdp-test
แแแแฎแแ แฎแ MAC แแแกแแแแ แแแก "แแแแแฌแงแแแ" 192.0.2.1, แแก แแแ แจแแซแแแแก แแ IP-แก แแแแแญแ แแก.
แแ แแแแแแแก แจแแกแแฎแแ แแแแชแฎแแแแแ
แแแแแ แแแแแแแแแ แแแแแแแแฃแ แแแแชแแแแแ: แฉแแฌแแ แแ SYN แฅแฃแฅแ-แฉแแแแฌแแ แแก แแแฅแแแแแแ XDP-แแ.
แแ แแ แแแแ, SYN flood แ แฉแแแ แแแแฃแแแ แฃแ DDoS แจแแขแแแแ, แ แแแแแก แแ แกแ แจแแแแแแแ. แ แแแแกแแช แแแแจแแ แ แแแแงแแ แแแแ (TCP แฎแแแแก แฉแแแแ แแแแแ), แกแแ แแแ แ แแฆแแแก SYN-แก, แแแแแงแแคแก แ แแกแฃแ แกแแแก แแแแแแแแ แแแแจแแ แแกแแแแก, แแแกแฃแฎแแแก SYNACK แแแแแขแแ แแ แแแแแแแ ACK-แก. แแแแแแแกแฎแแแแ แฃแแ แแแแ แแแแแแแแก SYN แแแแแขแแแก แงแแแแ แแแกแแแแ แแแแแแแ แฌแแแจแ แแแแกแแแแ แแแแแแแแ แแแแแแฃแแ แฐแแกแขแแแแ แแ แแแแแแแแกแแแ แแแขแแแขแจแ. แกแแ แแแ แ แแซแฃแแแแฃแแแ แแแแแงแแก แ แแกแฃแ แกแแแ แแแแแขแแก แฉแแแแกแแแแกแแแแแแ, แแแแ แแ แแแแแแกแฃแคแแแแก แแแก แแแแ แฎแแแก แแแแแแแแแแแจแ, แ แแก แจแแแแแแแแช แแแฎแกแแแ แแแ แแ แแแแแขแแแ แแแแแฌแฃแ แแแ, แแฎแแแ แแแแจแแ แแแ แแ แแแแฆแแแ, แกแแ แแแกแ แแแฃแฌแแแแแแแแ.
แแฃ แแฅแแแ แแ แแแแฌแแแแแ แ แแกแฃแ แกแแแก SYN แแแแแขแแ, แแแแ แแ แแแกแฃแฎแแแ แแฎแแแแ SYNACK แแแแแขแแ, แแแจแแ แ แแแแ แจแแแซแแแแ แกแแ แแแ แแ แแแแแแก, แ แแ แแแแแแแแแแแ แแแกแฃแ ACK แแแแแขแ แแแฃแแแแแก SYN แแแแแขแก, แ แแแแแแช แแ แแงแ แจแแแแฎแฃแแ? แงแแแแแแแ แแแแก แจแแแแแ, แแแแแแแกแฎแแแแก แแกแแแ แจแแฃแซแแแ แจแแฅแแแแก แงแแแแ ACK-แแแ. SYN แฅแฃแฅแ-แคแแแแแก แแ แกแ แแ แแก แแแจแแคแแ แ seqnum
แแแแจแแ แแก แแแ แแแแขแ แแแ, แ แแแแ แช แแแกแแแแ แแแแแก แฐแแจแ, แแแ แขแแแ แแ แชแแแแแแแแ แแแ แแแ. แแฃ ACK-แแ แแแแฎแแ แฎแ แแแ แแแแก แจแแชแแแแแแ แฉแแแแกแแแ, แจแแแแซแแแแ แแแแแ แแแแแแแแแแ แฐแแจแ แแ แจแแแแแ แแ acknum
. แงแแแแ acknum
แแแแแแแกแฎแแแแก แแ แจแแฃแซแแแ, แ แแแแแ แแแ แแแ แจแแแชแแแก แกแแแแฃแแแแก แแ แแ แแฅแแแแ แแ แ แแแกแ แแแแแแแแแก แจแแแฆแฃแแฃแแ แแ แฎแแก แแแแ.
SYN แฅแฃแฅแ-แคแแแแแแ แแแแ แฎแแแแ แแแแแ แแแแแ Linux-แแก แแแ แแแจแ แแ แแแแ แแแขแแแแขแฃแ แแ แฉแแ แแแแช แแ แจแแกแแซแแแแแแแ, แแฃ SYN-แแแ แซแแแแแ แกแฌแ แแคแแ แแ แแแกแแแ แแแแ แฉแแแแแ.
แกแแแแแแแแแแแแแแ แแ แแแ แแแ TCP แฎแแแแก แฉแแแแ แแแแแแก แจแแกแแฎแแ
TCP แฃแแ แฃแแแแแงแแคแก แแแแแชแแแแ แแแแแชแแแแก แแแแขแแแแก แแแแแแแก แกแแฎแแ, แแแแแแแแแ, HTTP แแแแฎแแแแแแ แแแแแแชแแแ TCP-แแ. แแแแแแ แแแฌแแ-แแแฌแแ แแแแแแชแแแ แแแแแขแแแจแ. แงแแแแ TCP แแแแแขแก แแฅแแก แแแแแแฃแ แ แแ แแจแแแ แแ 32-แแแขแแแแ แแแแแแแ แแแแก แแแแ แแแ:
-
แแ แแจแแแแก แแแแแแแแชแแ แแแแกแแแฆแแ แแแก แแแแแ แแขแฃแแ แแแแแขแแก แ แแแก. SYN แแ แแจแ แแแจแแแแก, แ แแ แแก แแ แแก แแแแแแแแแแก แแแ แแแแ แแแแแขแ แแแแจแแ แแ. ACK แแ แแจแ แแแจแแแแก, แ แแ แแแแแแแแแแ แแแแฆแ แแแแจแแ แแก แงแแแแ แแแแแชแแแ แแแแขแแแแ.
acknum
. แแแแแขแก แจแแแซแแแแ แฐแฅแแแแแก แ แแแแแแแแ แแ แแจแ แแ แแแกแแฎแแแแแฃแแแ แแแแ แแแแแแแแชแแแก แแแฎแแแแแ, แแแแแแแแแ, SYNACK แแแแแขแ. -
แแแแแแแ แแแแก แแแแแ แ (seqnum) แแแแกแแแฆแแ แแแก แแคแกแแขแก แแแแแชแแแแ แแแแแแจแ แแแ แแแแ แแแแขแแกแแแแก, แ แแแแแแช แแแแแแแแแแแ แแ แแแแแขแจแ. แแแแแแแแแ, แแฃ แแแ แแแ แแแแแขแจแ X แแแแขแ แแแแแชแแแแแแ แแก แ แแชแฎแแ แแงแ N, แจแแแแแ แแแแแขแจแ แแฎแแแ แแแแแชแแแแแแ แแฅแแแแ N+X. แแแแจแแ แแก แแแกแแฌแงแแกแจแ แแแแแแฃแแ แแฎแแ แ แจแแแแฎแแแแแ แแ แฉแแแก แแ แ แแชแฎแแก.
-
แแแแแกแขแฃแ แแแแก แแแแแ แ (acknum) - แแแแแ แแคแกแแขแ, แ แแแแ แช seqnum, แแแแ แแ แแก แแแแกแแแฆแแ แแแก แแ แ แแแแแชแแแฃแแ แแแแขแแก แ แแแแแแแแแก, แแ แแแแ แแแแฆแแแแก แแแ แแแแ แแแแขแแก แ แแแแแแแแแก, แ แแแแแแช แแแแแแแแแแ แแแ แแแฎแ.
แแแแจแแ แแก แแแกแแฌแงแแกแจแ แแฎแแ แแแแ แฃแแแ แจแแแแแฎแแแแแ seqnum
ะธ acknum
. แแแแแแขแ แแแแแกแแแ แแ แแแ แแแแแแแแก SYN แแแแแขแก seqnum = X
. แกแแ แแแ แ แแแกแฃแฎแแแก SYNACK แแแแแขแแ, แกแแแแช แแก แฌแแ แก แกแแแฃแแแ แก seqnum = Y
แแ แแแฎแแแก acknum = X + 1
. แแแแแแขแ แแแกแฃแฎแแแก SYNACK-แก ACK แแแแแขแแ, แกแแแแช seqnum = X + 1
, acknum = Y + 1
. แแแแก แจแแแแแ, แแแแแชแแแแ แคแแฅแขแแแ แแแ แแแแแชแแแ แแฌแงแแแ.
แแฃ แแแแแแแกแแฃแแ แ แแ แแแแกแขแฃแ แแแก แแแแแขแแก แแแฆแแแแก, TCP แฎแแแแฎแแ แแแแแแแแก แแแก แแ แแแก แแแแฌแฃแ แแแ.
แ แแขแแ แแ แแแแแแงแแแแแ SYN แฅแฃแฅแแแแ แงแแแแแแแแก?
แแแ แแแแ, แแฃ SYNACK แแ ACK แแแแแแ แแแแ, แแแแแฌแแแ แแแแแแแ แฎแแแแฎแแ แแแแแแแแแก - แแแแจแแ แแก แแแแงแแ แแแ แจแแแแแแแแ. แแแแ แแช, SYN แแแแแขแจแ - แแ แแฎแแแแ แแแกแจแ! - แแแแแชแแแฃแแแ แแ แแแแแ แแแ แแแแขแ, แ แแแแแแช แแแแแแแแก แแฎแแแแก แแแแจแแ แแก แจแแแแแแ แแฃแจแแแแแแ. แแ แแฎแกแแแก แจแแแแแแแแแ SYN แแแแแขแแแ, แกแแ แแแ แ แฃแแฃแแแแแแงแแคแก แแ แแแ แแแแขแ แแแก, แจแแแแแ แแแแแขแแแจแ แแแแแแขแ แแแ แแฆแแ แแแฃแแแแแแแก. TCP แจแแแซแแแแ แแแฃแจแแแก แแ แจแแแแฎแแแแแจแ, แแแแ แแ แกแแฌแงแแก แแขแแแแ แแแแแช แจแแแชแแ แแแแ แแแแจแแ แแก แฎแแ แแกแฎแ.
แแแแแขแแแแก แแแแแกแแแ แแกแแ, XDP แแ แแแ แแแแ แฃแแแ แแแแแแแแก แจแแแแแแ:
- แฃแแแกแฃแฎแแ SYN-แก SYNACK-แแ แฅแฃแฅแแแ;
- แฃแแแกแฃแฎแแ ACK RST-แแ (แแแขแแฎแแ แแแแจแแ แ);
- แฉแแแแแแแแก แกแฎแแ แแแแแขแแแ.
แแแแแ แแแแแก แคแกแแแแแแแแ แแแแแขแแก แแแแแแแแแ แแ แแแ:
ะัะปะธ ััะพ ะฝะต Ethernet,
ะฟัะพะฟัััะธัั ะฟะฐะบะตั.
ะัะปะธ ััะพ ะฝะต IPv4,
ะฟัะพะฟัััะธัั ะฟะฐะบะตั.
ะัะปะธ ะฐะดัะตั ะฒ ัะฐะฑะปะธัะต ะฟัะพะฒะตัะตะฝะฝัั
, (*)
ัะผะตะฝััะธัั ััะตััะธะบ ะพััะฐะฒัะธั
ัั ะฟัะพะฒะตัะพะบ,
ะฟัะพะฟัััะธัั ะฟะฐะบะตั.
ะัะปะธ ััะพ ะฝะต TCP,
ัะฑัะพัะธัั ะฟะฐะบะตั. (**)
ะัะปะธ ััะพ SYN,
ะพัะฒะตัะธัั SYN-ACK ั cookie.
ะัะปะธ ััะพ ACK,
ะตัะปะธ ะฒ acknum ะปะตะถะธั ะฝะต cookie,
ัะฑัะพัะธัั ะฟะฐะบะตั.
ะะฐะฝะตััะธ ะฒ ัะฐะฑะปะธัั ะฐะดัะตั ั N ะพััะฐะฒัะธั
ัั ะฟัะพะฒะตัะพะบ. (*)
ะัะฒะตัะธัั RST. (**)
ะ ะพััะฐะปัะฝัั
ัะปััะฐัั
ัะฑัะพัะธัั ะฟะฐะบะตั.
แแ แแ (*)
แแแแแจแแฃแแแ แฌแแ แขแแแแแ, แกแแแแช แกแแญแแ แแ แกแแกแขแแแแก แแแแแแแ แแแแแก แแแ แแแ - แแแ แแแ แแขแแแแ, แแฅแแแ แจแแแแซแแแแ แแแแแแแแ แแแ แแแ แแจแ แฃแแ แแแแ TCP แฎแแแแก แฉแแแแ แแแแแแก แแแแแ แแแแ SYN แฅแฃแฅแ-แคแแแแแก, แ แแแแ แช seqnum-แแก แแแแแ แแ แแแแ.
แฒกแแแขแแ (**)
, แกแแแแ แแแแแแ แแ แแแแฅแแก, แฉแแแ แแแแแแขแแแแแ แแแแแขแก.
TCP แฎแแแแก แฉแแแแ แแแแแแก แแแแฎแแ แชแแแแแแ
แแแแแขแแก แแแแแแแ แแ แแแแแก แแแแแแแฌแแแแ
แฉแแแ แแแญแแ แแแแ แฅแกแแแแก แกแแแแฃแ แแก แกแขแ แฃแฅแขแฃแ แแแ: Ethernet (uapi/linux/if_ether.h
), IPv4 (uapi/linux/ip.h
) แแ TCP (uapi/linux/tcp.h
). แแแแ แแ แแแ แแแแแแแแจแแ แ แจแแชแแแแแแแก แแแแ atomic64_t
แแ แแแแแฌแแ แกแแญแแ แ แแแแแแ แขแแแแแแก แแแแแ แแแ แแแแจแ.
แงแแแแ แคแฃแแฅแชแแ, แ แแแแแแช แแแแแแ แฉแแแ C-แจแ แฌแแแแแฎแแแกแแแแก, แฃแแแ แแงแแก แฉแแกแแฃแแ แแแ แแก แแแแแแแ, แ แแแแแ แแแ แแแจแ eBPF แแแ แแคแแแแขแแ แ แแ แซแแแแแก แฃแแแแ แแแฎแขแแแแแก, แแแฃ แคแแฅแขแแแ แแแแ แแแ แงแฃแแแแก แแ แคแฃแแฅแชแแแแแก แแแแแซแแฎแแแแก.
#define INTERNAL static __attribute__((always_inline))
แแแแ แ LOG()
แแแแแ แแแแก แแแญแแแแก แแแแแจแแแแแก แแแ แกแแแจแ.
แแ แแแ แแแ แแ แแก แคแฃแแฅแชแแแแแก แแแแกแแแแแ. แแแแแแฃแแ แแฆแแแก แแแแแขแก, แ แแแแแจแแช แแแแแจแแฃแแแ แจแแกแแแแแแกแ แแแแแก แกแแแแฃแ แ, แแแแแแแแแ, process_ether()
แแแแแแแ แจแแแกแแแแก ether
. แกแแแแแ แแแแแแแแก แจแแแแแแแแ แแแงแ แแแแแแ, แคแฃแแฅแชแแแก แจแแฃแซแแแ แแแแแขแแก แแแแแขแแแ แฃแคแ แ แแแฆแแ แแแแแแ. แคแฃแแฅแชแแแก แจแแแแแ แแ แแก XDP แแแฅแแแแแแ. แกแแแแ SYN แแ ACK แแแแแฃแจแแแแแแแแ แฃแจแแแแแ แงแแแแ แแแแแขแก.
struct Packet {
struct xdp_md* ctx;
struct ethhdr* ether;
struct iphdr* ip;
struct tcphdr* tcp;
};
INTERNAL int process_tcp_syn(struct Packet* packet) { return XDP_PASS; }
INTERNAL int process_tcp_ack(struct Packet* packet) { return XDP_PASS; }
INTERNAL int process_tcp(struct Packet* packet) { ... }
INTERNAL int process_ip(struct Packet* packet) { ... }
INTERNAL int
process_ether(struct Packet* packet) {
struct ethhdr* ether = packet->ether;
LOG("Ether(proto=0x%x)", bpf_ntohs(ether->h_proto));
if (ether->h_proto != bpf_ntohs(ETH_P_IP)) {
return XDP_PASS;
}
// B
struct iphdr* ip = (struct iphdr*)(ether + 1);
if ((void*)(ip + 1) > (void*)packet->ctx->data_end) {
return XDP_DROP; /* malformed packet */
}
packet->ip = ip;
return process_ip(packet);
}
SEC("prog")
int xdp_main(struct xdp_md* ctx) {
struct Packet packet;
packet.ctx = ctx;
// A
struct ethhdr* ether = (struct ethhdr*)(void*)ctx->data;
if ((void*)(ether + 1) > (void*)ctx->data_end) {
return XDP_PASS;
}
packet.ether = ether;
return process_ether(&packet);
}
แงแฃแ แแแฆแแแแก แแแฅแชแแ A แแ B แแแแแจแแฃแ แฉแแแแแก. แแฃ แแแแแแขแแ แก แแแแแแแแแ A, แแ แแแ แแแ แแจแแแแแแ, แแแแ แแ แฉแแขแแแ แแแแกแแก แแฅแแแแ แแแแแแแฌแแแแแก แจแแชแแแแ:
Verifier analysis:
<...>
11: (7b) *(u64 *)(r10 -48) = r1
12: (71) r3 = *(u8 *)(r7 +13)
invalid access to packet, off=13 size=1, R7(id=0,off=0,r=0)
R7 offset is outside of the packet
processed 11 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
Error fetching program/map!
แแแกแแฆแแแแก แกแขแ แแฅแแแ invalid access to packet, off=13 size=1, R7(id=0,off=0,r=0)
: แแ แแก แจแแกแ แฃแแแแแก แแแแแแแแ, แ แแแแกแแช แแฃแคแแ แแก แแแฌแงแแแแแแ แแแชแแแแขแ แแแแขแ แแ แแก แแแแแขแแก แแแ แแ. แกแแแแแ แซแแแแแ แแแแก แแฅแแ, แ แแแแ แฎแแแแ แแกแแฃแแ แแแ, แแแแ แแ แแ แแก แแแกแขแ แฃแฅแชแแแก แแแแแ แ (12) แแ แแแแแแขแแแ, แ แแแแแแช แแฉแแแแแแก แฌแงแแ แแก แแแแแก แฎแแแแแก:
llvm-objdump -S xdp_filter.o | less
แแ แจแแแแฎแแแแแจแ, แแก แแแฃแแแแแแก แฎแแแแ
LOG("Ether(proto=0x%x)", bpf_ntohs(ether->h_proto));
แ แแช แชแฎแแแงแแคแก, แ แแ แแ แแแแแแ แแ แแก ether
. แงแแแแแแแแก แแกแ แแฅแแแแแแ.
แแแกแฃแฎแ SYN-แแ
แแแแแแ แแ แแขแแแแ แแ แแก แกแฌแแ แ SYNACK แแแแแขแแก แแแแแ แแ แแแ แคแแฅแกแแ แแแฃแแ seqnum
, แ แแแแแแช แแแแแแแแจแ แจแแแชแแแแแ SYN แฅแฃแฅแแแ. แงแแแแ แชแแแแแแแ แฎแแแแ process_tcp_syn()
แแ แจแแแแแแ แแแ.
แแแแแขแแก แจแแแแฌแแแแ
แฃแชแแแฃแ แแ แกแแแแแ แแกแแ, แแฅ แแ แแก แงแแแแแแ แฆแแ แกแจแแกแแแแจแแแแ แฎแแแ, แฃแคแ แ แกแฌแแ แแ, แแแแแแขแแ แ แแแกแแ:
/* Required to verify checksum calculation */
const void* data_end = (const void*)ctx->data_end;
แแแแแก แแแ แแแแ แแแ แกแแแก แแแฌแแ แแกแแก แแแแแงแแแแแฃแแ แแฅแแ 5.1 แแแ แแแ, แ แแแแแก แแแแแแแฌแแแแแกแแแแกแแช แแงแ แแแแกแฎแแแแแแ data_end
ะธ (const void*)ctx->data_end
. แฌแแ แแก แแ แแก 5.3.1 แแแ แแแก แแก แแ แแแแแแ แแ แฅแแแแ. แจแแกแแซแแแ, แจแแแแแแแแแ แแแแแแฃแ แชแแแแแแ แฌแแแแแแก แกแฎแแแแแแ แแ แฌแแแแแแแ, แแแแ แ แแแแแ. แแแ แแแ - แแแ แแฃแแแแ, แแแแแก แแแแแ แขแแแแแ แแแแแฎแแแ แแแแ.
แกแแแ แซแแก แจแแแแแแแ แ แฃแขแแแฃแแ แจแแแแฌแแแแ แแแ แแคแแแแขแแ แแก แแแแแแแกแแแแก; แ MAX_CSUM_BYTES
ะะธะถะต.
const u32 ip_len = ip->ihl * 4;
if ((void*)ip + ip_len > data_end) {
return XDP_DROP; /* malformed packet */
}
if (ip_len > MAX_CSUM_BYTES) {
return XDP_ABORTED; /* implementation limitation */
}
const u32 tcp_len = tcp->doff * 4;
if ((void*)tcp + tcp_len > (void*)ctx->data_end) {
return XDP_DROP; /* malformed packet */
}
if (tcp_len > MAX_CSUM_BYTES) {
return XDP_ABORTED; /* implementation limitation */
}
แแแแแขแแก แแแแ แชแแแแแ
แฉแแแ แแแแกแแแ seqnum
ะธ acknum
, แแแแงแแแแ ACK (SYN แฃแแแ แแแงแแแแแฃแแแ):
const u32 cookie = 42;
tcp->ack_seq = bpf_htonl(bpf_ntohl(tcp->seq) + 1);
tcp->seq = bpf_htonl(cookie);
tcp->ack = 1;
แจแแชแแแแแ TCP แแแ แขแแแ, IP แแ MAC แแแกแแแแ แแแแ. แกแขแแแแแ แขแฃแแ แแแแแแแแแแ แแ แแ แแก แฎแแแแแกแแฌแแแแแ XDP แแ แแแ แแแแแแ, แแแแขแแ memcpy()
- แแแแ แ, แ แแแแแแช แแแแแแก แแแแแแแก แจแแแแแแกแก.
const u16 temp_port = tcp->source;
tcp->source = tcp->dest;
tcp->dest = temp_port;
const u32 temp_ip = ip->saddr;
ip->saddr = ip->daddr;
ip->daddr = temp_ip;
struct ethhdr temp_ether = *ether;
memcpy(ether->h_dest, temp_ether.h_source, ETH_ALEN);
memcpy(ether->h_source, temp_ether.h_dest, ETH_ALEN);
แกแแแแแขแ แแแ แฏแแแแก แฎแแแแฎแแแ แแแแแแแ แแจแแแ
IPv4 แแ TCP แกแแแแแขแ แแแ แฏแแแแแ แแแแแฎแแแก แกแแแแฃแ แแแจแ แงแแแแ 16-แแแขแแแแ แกแแขแงแแแก แแแแแขแแแแก แแ แแแแจแ แแฌแแ แแแ แกแแแแฃแ แแแแก แแแแ, แแแฃ แจแแแแแแแก แแ แแก แฃแชแแแแแ. แแก แแ แแแแแแแ, แ แแแแแ แแแ แแคแแแแขแแ แ แแ แแแแแขแแแแแก แแแ แแแแฃแ แชแแแแก แกแแกแแแฆแแ แ แชแแแแแแแแ. แแแแ แแ แกแแแแฃแ แแแแก แแแแ แจแแแฆแฃแแฃแแแ: แแแแแแฃแแ 64 แแแแขแแแแ. แจแแแแซแแแแ แแแแแแแแ แแแ แงแฃแแ แคแแฅแกแแ แแแฃแแ แ แแแแแแแแแก แแแแแแ แแแแ, แ แแแแแแช แจแแแซแแแแ แแแ แ แแแกแ แฃแแแแก.
แแฆแแแแจแแแ, แ แแ แแ แกแแแแแก
แกแแแแแขแ แแแ แฏแแแแก แแแแแแแแแก แคแฃแแฅแชแแ:
#define MAX_CSUM_WORDS 32
#define MAX_CSUM_BYTES (MAX_CSUM_WORDS * 2)
INTERNAL u32
sum16(const void* data, u32 size, const void* data_end) {
u32 s = 0;
#pragma unroll
for (u32 i = 0; i < MAX_CSUM_WORDS; i++) {
if (2*i >= size) {
return s; /* normal exit */
}
if (data + 2*i + 1 + 1 > data_end) {
return 0; /* should be unreachable */
}
s += ((const u16*)data)[i];
}
return s;
}
แแแฃแฎแแแแแแ แแแแกแ size
แจแแแแฌแแแแฃแแแ แแแแแซแแฎแแแแก แแแแแ, แแแแ แ แแแกแแกแแแแแ แแแ แแแแ แกแแญแแ แ, แ แแแ แจแแแแแฌแแแแแแแ แแแแแขแแแชแแก แแแ แงแฃแแแก แแแกแแกแ แฃแแ.
32-แแแขแแแแ แกแแขแงแแแแแกแแแแก แแแแแ แแแแแ แฃแคแ แ แแแ แขแแแ แแแ แกแแ:
INTERNAL u32
sum16_32(u32 v) {
return (v >> 16) + (v & 0xffff);
}
แ แแแแฃแ แแ แจแแแแฌแแแแฃแแ แฏแแแแแแก แฎแแแแฎแแแ แแแแแแแแ แแ แแแแแขแแก แฃแแแ แแแแแแแแ:
ip->check = 0;
ip->check = carry(sum16(ip, ip_len, data_end));
u32 tcp_csum = 0;
tcp_csum += sum16_32(ip->saddr);
tcp_csum += sum16_32(ip->daddr);
tcp_csum += 0x0600;
tcp_csum += tcp_len << 8;
tcp->check = 0;
tcp_csum += sum16(tcp, tcp_len, data_end);
tcp->check = carry(tcp_csum);
return XDP_TX;
แคแฃแแฅแชแแ carry()
แแแแแแแก แกแแแแแขแ แแแ แฏแแแก 32-แแแขแแแแ แกแแขแงแแแแแก 16-แแแขแแแแ แฏแแแแแแ, RFC 791-แแก แแแฎแแแแแ.
TCP แฎแแแแก แฉแแแแ แแแแแแก แจแแแแฌแแแแ
แคแแแขแ แ แกแฌแแ แแ แแแงแแ แแแก แแแแจแแ แก netcat
แกแแแแแแ ACK-แแก แแแแแขแแแแแ, แ แแแแช Linux-แแ แฃแแแกแฃแฎแ RST แแแแแขแแ, แ แแแแแ แฅแกแแแแก แแแกแขแแก แแ แแแฃแฆแแ SYN - แแก แแแแแแแแแ SYNACK-แจแ แแ แฃแแแ แแแแแแแแแ - แแ OS-แแก แแแแแกแแแ แแกแแ, แฉแแแแแแแ แแแแแขแ, แ แแแแแแช แแ แแงแ. แฆแแ แแแแจแแ แแแแแ แแแแแแจแแ แแแฃแแ.
$ sudo ip netns exec xdp-test nc -nv 192.0.2.1 6666
192.0.2.1 6666: Connection reset by peer
แแแแจแแแแแแแแแแ แกแ แฃแแคแแกแแแแแ แแแแแแแชแแแแแก แจแแแแฌแแแแ แแ แแแแแแ แแแแ tcpdump
on xdp-remote
แ แแแแแ, แแแแแแแแแ, hping3
แแ แแแกแฃแฎแแแก แแ แแกแฌแแ แจแแแแฌแแแแแก.
SYN แฅแฃแฅแ
XDP-แแก แแแแแกแแแ แแกแแ, แแแแ แจแแแแฌแแแแ แขแ แแแแแแฃแ แแ. แแแแแแแ แแจแแแแก แแแแแ แแแแ แแ แแแแขแแฃแแแ แแ แกแแแแ แแฃแแแ แแแฃแชแแแแแ แแแฎแแแฌแแแ แแแแแแแกแฎแแแแแก แแแแแ แ. แแแแแแแแแ, Linux-แแก แแแ แแแ แแงแแแแแก แแ แแแขแแแ แแคแแฃแ SipHash-แก, แแแแ แแ แแแกแ แแแแฎแแ แชแแแแแแ XDP-แกแแแแก แแจแแแ แแ แกแชแแแแแแ แแ แกแขแแขแแแก แคแแ แแแแแก.
แแแแแฉแแแ แแฎแแแ TODO-แแแแกแแแแก, แ แแแแแแแช แแแแแแจแแ แแแฃแแแ แแแ แ แฃแ แแแแ แแฅแแแแแแแแแแ:
-
XDP แแ แแแ แแแ แแแ แแแแฎแแแก
cookie_seed
(แแแ แแแแก แกแแแแฃแแแ แแแฌแแแ) แแแแแแแฃแ แชแแแแแจแ, แแญแแ แแแแแ แแแ แแแแก แแแฆแแแแ, แ แแแแแก แฆแแ แแแฃแแแแ แแแ แแแแฃแแแ แแแแแฎแแแแแ แกแแแแแแ แแแแแ แแขแแ แแกแแแ. -
แแฃ ACK แแแแแขแจแ SYN แฅแฃแฅแ-แคแแแแ แแแแฎแแแแ, แแฅแแแ แแ แแญแแ แแแแแ แจแแขแงแแแแแแแแก แแแแแญแแแ, แแแแ แแ แแแฎแกแแแแแ แแแแแฌแแแแฃแแ แแแแแแขแแก IP, แ แแแ แจแแแแแแ แแแแแขแแแแ แแแแแขแแแ แแแกแแแ.
แแแแแกแขแฃแ แแแ แแแแแขแแแฃแ แ แแแแแแขแแก แแแแ :
$ sudoip netns exec xdp-test nc -nv 192.0.2.1 6666
192.0.2.1 6666: Connection reset by peer
แแฃแ แแแแแแแ แฉแแฌแแ แแก แจแแแแฌแแแแแก แแแแแ (flags=0x2
แแ แแก SYN, flags=0x10
แแ แแก ACK):
Ether(proto=0x800)
IP(src=0x20e6e11a dst=0x20e6e11e proto=6)
TCP(sport=50836 dport=6666 flags=0x2)
Ether(proto=0x800)
IP(src=0xfe2cb11a dst=0xfe2cb11e proto=6)
TCP(sport=50836 dport=6666 flags=0x10)
cookie matches for client 20200c0
แกแแแแ แแ แแ แแก แจแแแแฌแแแแฃแแ IP-แแแแก แกแแ, แแ แแฅแแแแ แแแชแแ แแแแแ SYN แฌแงแแแแแแแแแกแแแ, แแแแ แแ แแฅ แแ แแก แ แแแฅแชแแ แแ แแ แซแแแแแแ แแแจแแแแฃแ ACK แฌแงแแแแแแแแแแ:
sudo ip netns exec xdp-test hping3 --flood -A -s 1111 -p 2222 192.0.2.1
แแฃแ แแแแแก แฉแแแแฌแแ แแแ:
Ether(proto=0x800)
IP(src=0x15bd11a dst=0x15bd11e proto=6)
TCP(sport=3236 dport=2222 flags=0x10)
cookie mismatch
แแแกแแแแ
แแแแฏแแ eBPF แแแแแแแ แแ XDP แแแแแ แแขแฃแแแ แฌแแ แแแแแแแแแแ แ แแแแ แช แฃแคแ แ แแแฌแแแแแ แแแแแแแกแขแ แแขแแ แแก แแแกแขแ แฃแแแแขแ, แแแแ แ แแแแแแแแ แแแแก แแแแขแคแแ แแ. แแแ แแแแช, XDP แแ แแก แแแ แแแแก แแแแแขแแก แแแแฃแจแแแแแแจแ แฉแแ แแแแก แแแกแขแ แฃแแแแขแ แแ แแ แ แแแ แแแแก แกแขแแแแก แแแขแแ แแแขแแแ, แ แแแแ แแชแแ DPDK แแ แแแ แแแแก แจแแแแแแแแ แกแฎแแ แแแ แแแแขแแแ. แแแแ แแก แแฎแ แแ, XDP แกแแจแฃแแแแแแก แแแซแแแแ แแแแแฎแแ แชแแแแแ แกแแแแแแ แ แแฃแแ แแแแแแ, แ แแช, แฃแคแ แ แแแขแแช, แแแ แขแแแแ แแแแแฎแแแแ แขแ แแคแแแแก แแแแฃแจแแแแแแก แแแฃแแแก แแแ แแจแ. แแแ แแคแแแแขแแ แ แแแ แแ แแแแแแแแก แแ แฅแแแแก, แแแ แแแแ แแ แฃแแ แก แแ แแแขแงแแแ แแแแฎแแแ แแแแแก แกแแแ แชแแก แแแแแก แแแฌแแแแแแ.
แแแแ แ แแแฌแแแจแ, แแฃ แแแแ แกแแแแขแแ แแกแแ, แจแแแแแกแแแ แแแ แแคแแชแแ แแแฃแแ แแแแแแขแแแแก แชแฎแ แแแก แแ แแแ แฆแแแแ แแแแจแแ แแแก, แแแแแแฎแแ แชแแแแแแ แแ แแชแฎแแแแแแก แแ แแแแฌแแ แ userspace แฃแขแแแแขแแก แคแแแขแ แแก แกแแแแ แแแแแ.
แแแฃแแแแ:
แกแ แฃแแ แแแแ GitHub-แแ bpftrace แแแขแงแฃแแแแก แคแฃแ แชแแแ BPF แแ XDP แกแแชแแแแแ แ แแแแแแแแแแ XDP แแแแแแแแแ PoC: แจแแแแแแ eBPF-แจแ Rust-แแแ
แฌแงแแ แ: www.habr.com