eXpress Data Path (XDP) ืืขืื ืึธืืึธืืืข ืึทืืึทืื ืืจืึทืค ืคืึทืจืงืขืจ ืคึผืจืึทืกืขืกืื ื ืืืืฃ ืืื ืืงืก ืื ืืขืจืคืืืกืื ืืืืืขืจ ืื ืคึผืึทืงืืฅ ืึทืจืืึทื ืื ืงืขืจื ื ืขืฅ ืึธื ืืืืื. ืึทืคึผืคึผืืืงืึทืืืึธื ืคืื XDP - ืฉืืฅ ืงืขืื DDoS ืื ืคืืื (CloudFlare), ืงืึธืืคึผืืขืงืก ืคืืืืขืจืก, ืกืืึทืืืกืืืง ืืึทืืืื ื (ื ืขืืคืืืงืก). XDP ืืืืื ืืขื ืขื ืขืงืกืึทืงืืืืึทื ืืืจื ืื eBPF ืืืืจืืืึทื ืืึทืฉืื, ืึทืืื ืืื ืืึธืื ืจืืกืืจืืงืฉืึทื ื ืืืืฃ ืืืืืข ืืืืขืจ ืงืึธื ืืื ืื ืื ืืืฆื ืงืขืจื ืคืึทื ืืงืฉืึทื ื ืืืคึผืขื ืืื ื ืืืืฃ ืื ืคืืืืขืจ ืืืคึผ.
ืืขืจ ืึทืจืืืงื ืืื ืืืขื ืฆื ืคึผืืึธืืืืจื ืื ืืืกืึธืจื ืคืื ืคืืืข ืืึทืืขืจืืึทืืก ืืืืฃ XDP. ืคืืจืกืืื, ืืื ืฆืืฉืืขืื ืคืึทืจืืืง ืงืึธื ืืืึธืก ืืืืื ืืืืคึผืึทืกืื ืื ืคึฟืขืึดืงืืืื ืคืื XDP: ืขืก ืืื ืฆืืืขืืจืืื ืคึฟืึทืจ ืืืขืจืึทืคืึทืงืืืฉืึทื ืึธืืขืจ ืืื ืืืื ืคึผืฉืื ืฆื ืคืึทืจืฉืึทืคื ืคึผืจืึธืืืขืืก. ืืืขื ืืืจ ืคึผืจืืืืจื ืฆื ืฉืจืืึทืื ืืืื ืงืึธื ืคึฟืื ืงืจืึทืฆื, ืืืจ ืืึธื ืงืืื ืืขืืึทื ืง ืืืึธืก ืฆื ืืึธื ืืื ืืืคึผืืฉ ืขืจืจืึธืจืก. ืฆืืืืืื ืก, ืืืขืื ืฆื ืืึธืืงืึทืื ืคึผืจืืืืจื XDP ืึธื ืึท VM ืืื ืืึทืื ืืืึทืจื ืืขื ืขื ื ืืฉื ืืืืขืงื, ืืจืึธืฅ ืืขื ืคืึทืงื ืึทื ืืื ืืึธืื ืืืืขืจ ืืืืื ืคึผืืืคืึธืื. ืืขืจ ืืขืงืกื ืืื ืืืขื ืคึฟืึทืจ ืคึผืจืึธืืืจืึทืืขืจื ืืึทืงืึทื ื ืืื ื ืขืืืืึธืจืงืื ื ืืื ืืื ืืงืก ืืืึธืก ืืขื ืขื ืืื ืืขืจืขืกืืจื ืืื XDP ืืื eBPF.
ืืื ืืขื ืืืื, ืืืจ ืืืขืื ืคึฟืึทืจืฉืืืื ืืื ืืขืืึทื ืืื ืื XDP ืคืืืืขืจ ืืื ืคืืจืืืืื ืืื ืืื ืฆื ืคึผืจืืืืจื ืขืก, ืืื ืืืจ ืืืขืื ืฉืจืืึทืื ืึท ืคึผืฉืื ืืืขืจืกืืข ืคืื โโืื ืืึทืืืืกื SYN ืงืืืืขื ืืขืงืึทื ืืืึทื ืืืืฃ ืื ืคึผืึทืงืึทื ืคึผืจืึทืกืขืกืื ื ืืืจืื. ืืืจ ืืืขืื ื ืืฉื ืืึทืื ืึท "ืืืืึทืก ืจืฉืืื" ื ืึธื
ืืืขืจืึทืคืืื ืงืืืืึทื ืฅ, ืืึทืืื ืงืึธืื ืืขืจืก ืืื ืคืืจื ืื ืคืืืืขืจ - ืืขื ืื ืืึธืืก.
ืืืจ ืืืขืื ืฉืจืืึทืื ืืื C - ืขืก ืืื ื ืืฉื ืืึธืืขืจื, ืึธืืขืจ ืขืก ืืื ืคึผืจืึทืงืืืฉ. ืื ืงืึธื ืืื ืื ืืืฆื ืืืืฃ GitHub ืืืจื ืื ืืื ืง ืืื ืื ืกืืฃ ืืื ืืื ืฆืขืืืืื ืืื ืงืึทืืืฅ ืืืื ืื ืกืืึทืืขืก ืืืกืงืจืืืื ืืื ืืขื ืึทืจืืืงื.
Disclaimer. ืืื ืืขื ืืึทื ื ืคืื ืืขื ืึทืจืืืงื, ืืื ืืืขื ืึทื ืืืืืงืืขื ืึท ืืื ื ืืืืืื ื ืฆื ืึธืคึผืืึทืืื 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 ืืื ืืขืฉืืืฆื ืืืจื ืงืืึทื ื ืืื ืฆืืืขืืืื ืืื GCC 10.1. - ืืืื ืืขื ืืืืคืขืฅ ืงืึธื ืึผืืื ืงืึทืืืก ืฆื ืงืขืจื ืกืืจืึทืงืืฉืขืจื (ืืืฉื, ืืืฉื ืืื ืงืึธืื ืืขืจืก), ืืืืขืจ IDs ืืขื ืขื ืจืืคึผืืืืกื ืืืจื ืืขืจืึธืก, ืืืึธืก ืืืื ืึทื ืึทืืึท ืงืึธื ืงืขื ืขื ื ืื ืืืื ืขืงืกืึทืงืืืืึทื. ืืืืืขืจ ืืืจ ืืึธืืืื ื ืืื ืื ืงืขืจื, ืืืจ ืืึทืจืคึฟื ืฆื ืคืึทืจืืืึทืื ืื ืืขืจืึธืก ืืื ืื IDs ืคืื ืกืคึผืขืฆืืคืืฉ ืึทืืืืฉืขืงืฅ ืืืฉืืคื ืืืจื ืงืขืจื ืงืึทืืืก (ืืื ืง ืื ืงืึธื). ืืืจ ืงืขื ืขื ืืึธื ืืึธืก ืืื ืคืื ืืจืืืกื ืืืง ืืืืืืึทืืื, ืึธืืขืจ ืืืจ ืงืขื ืขื ืฉืจืืึทืื ืึท ืคึผืจืึธืืจืึทื ืืืึธืก ืืืขื ืืื ืง ืืื ืืึธืื ืึท ืกืคึผืขืฆืืคืืฉ ืคืืืืขืจ.
- ืืขืจ ืงืขืจื ืืืขืจืึทืคืืื ืื ืืึธืืืื ืคึผืจืึธืืจืึทื. ืืขืจ ืึทืืืขืง ืคืื ืกืืืงืึทืื ืืื ืืืจืืคืึทื ืฆื ืืงืกืื ืคึผืึทืงืึทื ืืื ืึธื ืืืืื ืืึทืื ืืจืื ืืื ืึธืคึผืืขืฉืืขืื. ืืืื ืืขืจ ืืืขืจืึทืคืืืขืจ ืงืขื ื ืืฉื ืืึทืืืืึทืื ืึทื ืื ืงืึธื ืืื ืจืืืืืง, ืื ืคึผืจืึธืืจืึทื ืืื ืคืืจืืืืจืคื - ืืืจ ืืึทืจืคึฟื ืฆื ืืืื ืฆืืคืจืืื ืืื ืืื.
- ื ืึธื ืืขืจืึธืื ืืืขืจืึทืคืึทืงืืืฉืึทื, ืื ืงืขืจื ืงืึทืืคึผืืืื ืื eBPF ืึทืจืงืึทืืขืงืืฉืขืจ ืึทืืืืฉืขืงื ืงืึธื ืืื ืืึทืฉืื ืงืึธื ืคึฟืึทืจ ืื ืกืืกืืขื ืึทืจืงืึทืืขืงืืฉืขืจ (ืคึผืื ืงื-ืืื-ืฆืืื).
- ืืขืจ ืคึผืจืึธืืจืึทื ืึทืืึทืืฉืื ืฆื ืื ืฆืืืื ื ืืื ืืืืื ืคึผืจืึทืกืขืกืื ื ืคึผืึทืงืืฅ.
ืืื ื XDP ืืืืคื ืืื ืื ืงืขืจื, ืืืืึทืืื ื ืืื ืืืจืืืขืงืึธืื ืืื ืฉืคึผืืจ ืืึธืืก ืืื, ืืื ืคืึทืงื, ืคึผืึทืงืืฅ ืืืึธืก ืื ืคึผืจืึธืืจืึทื ืคืืืืขืจืก ืึธืืขืจ ืืืฉืขื ืขืจืืืฅ. ืึธืืขืจ, eBPF ืื ืฉืืจื ืึทื ืื ืืึทืื ืืึธืืืื ืงืึธื ืืื ืืืืขืจ ืคึฟืึทืจ ืื ืกืืกืืขื, ืึทืืื ืืืจ ืงืขื ืขื ืขืงืกืคึผืขืจืืืขื ื ืืื XDP ืืืืึทื ืืืืฃ ืืืื ืืืืข ืืื ืืงืก.
ืคึผืจืืคึผืขืจืื ื ืื ืกืืืืืืข
Assembly
ืงืืึทื ื ืงืขื ืขื ื ืืฉื ืืืืื ืคึผืจืึธืืืฆืืจื ืืืืคืขืฅ ืงืึธื ืคึฟืึทืจ ืื 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
ืืึทืงืขืคืืืข ืคึฟืึทืจ ืึทืจืืฉ ืืื ืืงืก (ืงืขืจื ืขื 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
- ืกืืกืืขื ืึทืจืงืึทืืขืงืืฉืขืจ. ืคึผืึทืืก ืืื ืืืฉืืจืื ืงืขื ืืืื ืึท ืืืกื ืึทื ืืขืจืฉ ืฆืืืืฉื ืืืกืืจืืืืืฉืึทื ื.
ืืืึทืฉืคึผืื ืคืื ืืืคืขืจืึทื ืกืื ืคึฟืึทืจ ืืขืืืึทื 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
. ืืื ืฆื ืคึผืจืืืืจื ืขืก ืืืฆื?
ืืขืกื ืฉืืืื
ืืขืจ ืฉืืืื ืืืื ืึทืจืืึทื ื ืขืืขื ืฆืืืื ืื ืืขืจืคืืืกืื: ืืืืฃ ืืืึธืก ืขืก ืืืขื ืืืื ืึท ืคืืืืขืจ ืืื ืคืื ืืืึธืก ืคึผืึทืงืืฅ ืืืขื ืืืื ืืขืฉืืงื. ืื ืืืื ืืืื ืคืื-ืคืืขืืืฉื ืืื ืืงืก ืืขืืืืกืขืก ืืื ืืืืขืจ ืืืืืขื ืข IPs ืืื ืกืืจ ืฆื ืงืึธื ืืจืึธืืืจื ืืื ืจืขืืืืขืจ ืึทืคึผืืึทืงืืืฉืึทื ื ืึทืจืืขื ืืื ืืื ืืืขืจ ืคืืืืขืจ.
ืืืืืืืกืึทื ืคืื ืื ืืืขืื (ืืืืจืืืึทื ืขืืืขืจื ืขื) ืืืคึผ ืืขื ืขื ืคึผืึทืกืืง ืคึฟืึทืจ ืืื ืื: ืืึธืก ืืขื ืขื ืึท ืคึผืึธืจ ืคืื ืืืืจืืืึทื ื ืขืฅ ืื ืืขืจืคืืืกืื "ืคืืจืืื ืื" ืืืืึทื ืฆื ืืขืืขืจ ืื ืืขืจืขืจ. ืืืจ ืงืขื ืขื ืืึทืื ืืื ืืื ืืึธืก (ืืื ืืขื ืึธืคึผืืืืืื ื ืึทืืข ืงืึทืืึทื ืื 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) ืื ืงืึทืืื ื ืคืึทืจืงืขืจ ืืืขื ืืืื ืืขืฉืืงื. ืึธืืขืจ, ืขืก ืืื ืึท ืคึผืจืึธืืืขื: ืื ืื ืืขืจืคืืืกืื ืืขื ืขื ืืืืฃ ืืขืจ ืืขืืืืงืขืจ ืืึทืฉืื, ืืื ืืื ืืงืก ืืืขื ื ืืฉื ืฉืืงื ืคืึทืจืงืขืจ ืฆื ืืืื ืขืจ ืคืื ืืื ืืืจื ืื ืื ืืขืจืข. ืืืจ ืงืขื ืขื ืกืึธืืืืข ืืขื ืืื ืืจืืงื ืึผืืืื iptables
, ืึธืืขืจ ืืื ืืืขืื ืืึธืื ืฆื ืืืืฉื ืคึผืึทืงืึทืืืฉืึทื, ืืืึธืก ืืื ืืืืึทืงืืืขื ืคึฟืึทืจ ืืืืึทืืื ื. ืขืก ืืื ืืขืกืขืจ ืฆื ื ืืฆื ื ืขืฅ ื ืึธืืขื ืกืคึผืืืกืึทื (ืืขืจื ืึธื ื ืขืื ืก).
ื ื ืขืฅ ื ืึทืืขืกืคึผืึทืกืข ืึผืืื ืึท ืกืืื ืคืื ืื ืืขืจืคืืืกืื, ืจืืืื ื ืืืฉื ืืื ื ืขืืคืืืืขืจ ืึผืืืื ืืืึธืก ืืขื ืขื ืืคืืขืืื ืืขืจื ืคืื ืขื ืืขื ืึทืืืืฉืขืงืฅ ืืื ืื ืืขืจืข ื ืขืฅ. ืืขืืขืจ ืคึผืจืึธืฆืขืก ืืืืคื ืืื ืึท ื ืึทืืขืกืคึผืึทืกืข ืืื ืืื ืืืืื ืึทืงืกืขืก ืฆื ืื ืึทืืืืฉืขืงืฅ ืคืื ืื ื ืขืฅ. ืืืจื ืคืขืืืงืืึทื, ืื ืกืืกืืขื ืืื ืึท ืืืื ื ืขืฅ ื ืึทืืขืกืคึผืึทืกืข ืคึฟืึทืจ ืึทืืข ืึทืืืืฉืขืงืฅ, ืึทืืื ืืืจ ืงืขื ืขื ืึทืจืืขืื ืืื ืืื ืืงืก ืืื ื ืืฉื ืืืืกื ืืืขืื ื ืขืื ืก.
ืืึธืืืจ ืฉืึทืคึฟื ืึท ื ืืึทืข ื ืึธืืขื 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 ืฆืืืจืืืืขื ืฆื ืืขื ืคึผืจืึธืฆืขืก. ืืึธืก ืืืื ืึทืจืืขื ืืื ืื ืคืึทืจืงืขืจื ืจืืืืื ื.
ืืืขื ืืึธืืืื ื ืฆืืืืฉื ื ืขืื ืก, ืื ืฆืืืื ื ืืืื ืึทืจืึธืคึผ ืืื ืคืืจืืืจื ืืืึทื ืึทืืจืขืก. ืฆื ืงืึทื ืคืืืืขืจ ืื ืฆืืืื ื ืืื Netns, ืืืจ ืืึทืจืคึฟื ืฆื ืืืืคื 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
ืืืจืฃ ืฆื ืคึฟืึทืจืืื ืื ืึท ื ืืึทืข ืคึผืจืึธืืจืึทื ืืืื ืื ืื ืืขืจ ืืืื ืขืจ ืืื ืฉืืื ืืื ืืงื. "ืงืืื ื ืืึทืขืก ืืื ืืื ื ืืึทืขืก" ืืื ื ืืฉื ืืืขืื ืืขื ืืึทืคึฟืขื, ืื ืืกืงื ื ืืื ืืืึทืืืืึทื ืึทืก ืืื ืงืืื ืคืึทื. ืึธื ืืืืึทืื 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
.
ืคึผืื ื ืืึธื ืืืฆื ืฆืื ืื ืึทืจืืืงืืขื ืืื ืืึธืก:
<...>-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
ืืืืฃ xdp-remote
. ืขืก ืืึธื ืืืืึทืื ืืืืขื ืืงืึทื ืึทืืืืึธืืื ื ืืื ืื ืงืึทืืื ื ICMP Echo Request ืืื ืืึทืืื ืืืืึทืืื ื 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
ืืืื ืืืืื ARPs ืืขื ืขื ืืขืืืืื ืึทื ืฉืืึธื, ืืืจ ืืึทืจืคึฟื ืฆื ืืึทืืืึทืืืงื ืื ืคืืืืขืจืก (ืืึธืก ืืื sudo ./stand detach
), ืืื ืืืื ping
, ืืขืืึธืื ืฉืืขืื ืคืืืืขืจืก ืืื ืคึผืจืืืืจื ืืืืืขืจ. ืื ืคึผืจืึธืืืขื ืืื ืึทื ืื ืคืืืืขืจ XDP_TX
ืืืืืืง ืืืืืข ืืืืฃ ARP ืืื ืืืื ืื ืึธื ืืืืื
ื ืึธืืขื ืกืคึผืืืกืึทื xdp-test
ืืขืจืืื ืฆื "ืคืึทืจืืขืกื" ืื MAC ืึทืืจืขืก 192.0.2.1, ืขืก ืืืขื ื ืืฉื ืงืขื ืขื ืฆื ืกืึธืืืืข ืืขื IP.
ืืืกืืึธืืื ื ืคืื ืื ืคึผืจืึธืืืขื
ืืึธืืืจ ืืืื ืฆื ืื ืกืืืืืื ืึทืจืืขื: ืฉืจืืึทืื ืึท SYN ืงืืืืขื ืืขืงืึทื ืืืึทื ืืืืฃ XDP.
SYN ืืืื ืืืืืื ืึท ืคืึธืืงืก DDoS ืืึทืคืึทืื, ืื ืขืกืึทื ืก ืคืื ืืืึธืก ืืื ืืื ืืืื. ืืืขื ืึท ืคึฟืึทืจืืื ืืื ื ืืื ืืขืืจืื ืืขื (TCP ืืึทื ืืฉืืืง), ืืขืจ ืกืขืจืืืขืจ ืืืงืืื ืึท SYN, ืึทืืึทืงืืืฅ ืจืขืกืืจืกื ืคึฟืึทืจ ืื ืฆืืงืื ืคึฟื ืงืฉืจ, ืจืืกืคึผืึทื ืื ืืื ืึท SYNACK ืคึผืึทืงืึทื ืืื ืืืืจืื ืคึฟืึทืจ ืึท ACK. ืืขืจ ืึทืืึทืงืขืจ ืคืฉืื ืกืขื ืื ืืืืื ืืขืจ ืคืื SYN ืคึผืึทืงืืฅ ืคึผืขืจ ืกืขืงืื ืืข ืคึฟืื ืกืคึผืึธืึธืคืขื ืึทืืจืขืกืขืก ืคืื ืืขืืขืจ ืืึทืืขืืึธืก ืืื ืึท ืืึทืืื-ืืืืื ื-ืฉืืึทืจืง ืืึธืื ืขื. ืืขืจ ืกืขืจืืืขืจ ืืื ืืขืฆืืืื ืืขื ืฆื ืึทืืึทืงืืื ืจืขืกืืจืกื ืืืืื ื ืึธื ืืขื ืึธื ืงืืืขื ืคืื ืื ืคึผืึทืงืึทื, ืึธืืขืจ ืจืืืืกืื ืืื ื ืึธื ืึท ืืจืืืก ืืืืืึทืื; ืืื ืึท ืจืขืืืืืึทื, ืืืงืึธืจื ืึธืืขืจ ืืืืึทืฅ ืืขื ืขื ืืืกืืขืืึทืืขืจื, ื ืืึท ืงืึทื ืขืงืฉืึทื ื ืืขื ืขื ื ืืฉื ืื ืืขื ืืืขื ืืื ืื ืืื ืกื ืืื ืึทื ืึทืืืืืืึทืืึทื.
ืืืื ืืืจ ืืึธื ื ืื ืึทืืึทืงืืื ืจืขืกืืจืกื ืืืืืจื ืืืืฃ ืื SYN ืคึผืึทืงืึทื, ืึธืืขืจ ืืืืื ืจืืกืคึผืึทื ื ืืื ืึท SYNACK ืคึผืึทืงืึทื, ืืื ืงืขื ืืขืจ ืกืขืจืืืขืจ ืคึฟืึทืจืฉืืืื ืึทื ืื ACK ืคึผืึทืงืึทื ืืืึธืก ืืื ืื ืืขืงืืืขื ืฉืคึผืขืืขืจ ืจืขืคืขืจืก ืฆื ืึท SYN ืคึผืึทืงืึทื ืืืึธืก ืืื ื ืืฉื ืืขืจืืืขืืืขื? ื ืึธื ืึทืืข, ืึท ืึทืืึทืงืขืจ ืงืขื ืขื ืืืื ืืืฉืขื ืขืจืืื ืฉืืืื ืื ACKs. ืื ืคืื ื ืคืื ืื SYN ืงืืื ืืื ืฆื ืขื ืงืึธืื ืขืก ืืื seqnum
ืงืฉืจ ืคึผืึทืจืึทืืขืืขืจืก ืืื ืึท ืืึทืฉ ืคืื ืึทืืจืขืกืขืก, ืคึผืึธืจืฅ ืืื ืืฉืึทื ืืื ื ืืึทืืฅ. ืืืื ืื ACK ืืื ืืขืจืืื ืฆื ืึธื ืงืืืขื ืืืืืขืจ ืื ืืึทืืฅ ืืื ืืฉืืื ืืืฉื, ืืืจ ืงืขื ืขื ืจืขืืขื ืขื ืื ืืึทืฉ ืืืืืขืจ ืืื ืคืึทืจืืืืึทืื ืขืก ืืื acknum
. ืคืึธืจืืข acknum
ืืขืจ ืึทืืึทืงืขืจ ืงืขื ื ืืฉื, ืืืืึทื ืื ืืึทืืฅ ืืืื ืื ืกืื, ืืื ืืืขื ื ืืฉื ืืึธืื ืฆืืื ืฆื ืกืึธืจื ืืืจื ืขืก ืจืขืื ืฆื ืืขืจ ืืืืืืขื ืงืึทื ืึทื.
ืื SYN ืงืืื ืืื ืืึทื ื ืืืคึผืืึทืืขื ืึทื ืืื ืื ืืื ืืงืก ืงืขืจื ืืื ืงืขื ืขื ืืคืืื ืืืื ืืืืืึธืืึทืืืฉ ืขื ืืืืึทืื ืืืื SYN ืก ืึธื ืงืืืขื ืฆื ืืขืฉืืืื ื ืืื ืืึทืกืืื.
ืืืืืื ืืงืจืืื ืคึผืจืึธืืจืึทื ืืืืฃ TCP ืืึทื ืืฉืืืง
ืืงืคึผ ืืื ืืึทืื ืืจืึทื ืกืืืกืืข ืืื ืึท ืืืึทื ืคืื ืืืืขืก, ืืืฉื, ืืืืคึผ ืจืืงืืืขืก ืืขื ืขื ืืจืึทื ืกืืืืืขื ืืืืขืจ ืืงืคึผ. ืืขืจ ืืืึทื ืืื ืืจืึทื ืกืืืืืขื ืืื ืืจืขืงืืขื ืืื ืคึผืึทืงืึทืฅ. ืื ืืงืคึผ ืคึผืึทืงืืฅ ืืึธืื ืืึทืืืฉืืงืึทื ืคืืึทืืก ืืื 32-ืืืกื ืกืืงืืืึทื ืก ื ืืืขืจื:
-
ืื ืงืึธืืืื ืึทืฆืืข ืคืื โโืคืืึทืืก ืืืืขืจืืึทื ื ืื ืจืึธืืข ืคืื โโืึท ืืึทืืื ืืขืจ ืคึผืขืงื. ืื SYN ืคืึธื ืื ืืืงืืืฅ ืึทื ืืึธืก ืืื ืื ืกืขื ืืขืจ ืก ืขืจืฉืืขืจ ืคึผืึทืงืึทื ืืืืฃ ืื ืงืฉืจ. ืื ACK ืคืึธื ืืืื ืึทื ืืขืจ ืกืขื ืืขืจ ืืื ืืืงืืืขื ืึทืืข ืื ืงืฉืจ ืืึทืื ืึทืจืืืฃ ืฆื ืื ืืืื
acknum
. ื ืคึผืึทืงืึทื ืงืขื ืขื ืืึธืื ืขืืืขืืข ืคืืึทืืก ืืื ืืื ืืขืจืืคึฟื ืืืจื ืืืืขืจ ืงืึธืืืื ืึทืฆืืข, ืืืฉื, ืึท SYNACK ืคึผืึทืงืึทื. -
ืกืืงืืืึทื ืก ื ืืืขืจ (ืกืขืงืืืึทื) ืกืคึผืขืฆืืคืืฆืืจื ืื ืคืึธืืึธ ืืื ืื ืืึทืื ืืืึทื ืคึฟืึทืจ ืืขืจ ืขืจืฉืืขืจ ืืืืข ืืืึธืก ืืื ืืจืึทื ืกืืืืืขื ืืื ืืขื ืคึผืึทืงืึทื. ืคึฟืึทืจ ืืืึทืฉืคึผืื, ืืืื ืืื ืืขืจ ืขืจืฉืืขืจ ืคึผืึทืงืึทื ืืื X ืืืืขืก ืคืื ืืึทืื ืืขื ื ืืืขืจ ืืื ืืขืืืขื N, ืืื ืืขืจ ืืืืึทืืขืจ ืคึผืึทืงืึทื ืืื ื ืืึทืข ืืึทืื ืขืก ืืืขื ืืืื N + X. ืืื ืื ืึธื ืืืื ืคืื ืื ืงืฉืจ, ืืขืืขืจ ืืืึทื ืืฉืืืื ืืขื ื ืืืขืจ ืจืึทื ืืึทืืื.
-
ืืขืจืงืขื ืืขื ืืฉ ื ืืืขืจ (ืึทืงืงื ืื) - ืืขืจ ืืขืืืืงืขืจ ืึธืคืกืขื ืืื ืกืขืงืืื, ืึธืืขืจ ืขืก ืืื ื ืืฉื ืืึทืฉืืืืขื ืื ื ืืืขืจ ืคืื ืื ืืืื ืืืึธืก ืืื ืืจืึทื ืกืืืืืขื, ืึธืืขืจ ืื ื ืืืขืจ ืคืื ืืขืจ ืขืจืฉืืขืจ ืืืื ืคืื ืื ืืึทืงืืืขืจ, ืืืึธืก ืืขืจ ืึธืคึผืฉืืงืขืจ ืืื ื ืืฉื ืืขื.
ืืื ืื ืึธื ืืืื ืคืื ืื ืงืฉืจ, ืื ืคึผืึทืจืืืขืก ืืืื ืฉืืืืขื 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 ืงืืื ืืื ืึท ืกืขืงื ืื.
ืืืืฃ ืืขื ืึธืจื (**)
, ืืฉืขืช ืืืจ ืืึธื ื ืื ืืึธืื ืึท ืืืฉ, ืืืจ ืืืขืื ืืึธืคึผืงืขื ืืขื ืคึผืึทืงืึทื.
ืืืคึผืืึทืืขื ืืื ื ืืงืคึผ ืืึทื ืืฉืืืง
ืคึผืึทืจืกืื ื ืืขื ืคึผืขืงื ืืื ืืืขืจืึทืคืืืื ื ืื ืงืึธื
ืืืจ ืืืขืื ืืึทืจืคึฟื ื ืขืฅ ืืขืืขืจ ืกืืจืึทืงืืฉืขืจื: ืขืืืขืจื ืขื (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);
}
ืืื ืฆืืขื ืืืื ืืคืืขืจืงืืึทืืงืืื ืฆื ืื ืืฉืขืงืก ืื ืืขืฆืืืื ื ื ืืื ื. ืืืื ืืืจ ืืึทืืขืจืงื ื, ืื ืคึผืจืึธืืจืึทื ืืืขื ืืืืขื, ืึธืืขืจ ืขืก ืืืขื ืืืื ืึท ืืืขืจืึทืคืึทืงืืืฉืึทื ืืขืืช ืืืขื ืืึธืืืื ื:
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;
ืืืกืืืึทืื ืืงืคึผ ืคึผืึธืจืฅ, IP ืึทืืจืขืก ืืื ืืขืง ืึทืืจืขืกืขืก. ืืขืจ ื ืึธืจืืึทื ืืืืืืึธืืขืง ืืื ื ืื ืฆืืืจืืืืขื ืคึฟืื ืื 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, ืฆื ืืืึธืก ืืื ืืงืก ืจืืกืคึผืึทื ืืื ืืื ืึท RST ืคึผืึทืงืึทื, ืืื ื ืื ื ืขืฅ ืกืืึทืง ืืื ื ืืฉื ืืึทืงืืืขื SYN - ืขืก ืืื ืงืึธื ืืืขืจืืขื ืฆื SYNACK ืืื ืืขืฉืืงื ืฆืืจืืง - ืืื ืคึฟืื ืื ืึทืก ืคืื ื ืคืื ืืืื ืื ื, ืึท ืคึผืึทืงืึทื ืื ืืขืงืืืขื ืืืึธืก ืืื ื ืืฉื ืฉืืื ืฆื ืขืคืขื ืขื ืงืึทื ืขืงืฉืึทื ื.
$ sudo ip netns exec xdp-test nc -nv 192.0.2.1 6666
192.0.2.1 6666: Connection reset by peer
ืขืก ืืื ืืืืืืืง ืฆื ืงืึธื ืืจืึธืืืจื ืืื ืคืื-ืคืืขืืืฉื ืึทืคึผืืึทืงืืืฉืึทื ื ืืื ืึธืืกืขืจืืืืจื tcpdump
ืืืืฃ xdp-remote
ืืืืื, ืืืฉื, hping3
ืจืืกืคึผืึทื ื ื ืืฉื ืฆื ืคืึทืืฉ ืืฉืขืงืกืึทืื.
SYN ืงืืื
ืคึฟืื ืึท XDP ืคืื ื ืคืื ืืืื ืื ื, ืื ืืืขืจืึทืคืึทืงืืืฉืึทื ืืื ืืื ื ืืฉืืืง. ืืขืจ ืืขืืฉืื ืึทืืืขืจืืืึทื ืืื ืคึผืจืืืืืืื ืืื ืืกืชึผืื ืฉืคึผืืจืขืืืืืง ืคึฟืึทืจ ืึท ืกืึทืคืืกืืึทืงืืืืื ืึทืืึทืงืขืจ. ืืขืจ ืืื ืืงืก ืงืขืจื, ืคึฟืึทืจ ืืืึทืฉืคึผืื, ื ืืฆื ืื ืงืจืืคึผืืึธืืจืึทืคืืง ืกืืคึผืืึทืฉ, ืึธืืขืจ ืืืึทื ืืืคึผืืึทืืขื ืืืืฉืึทื ืคึฟืึทืจ XDP ืืื ืงืืืจ ืืืืึทืืขืจ ืคืื ืืขื ืคืึทืจื ืขื ืคืื ืืขื ืึทืจืืืงื.
ืืึทืงืขื ืขื ืคึฟืึทืจ ื ืืึทืข ืืึธืืึธ ืฉืืึทืืืช ืฆื ืคืื ืืจืืืกื ืืืง ืงืึธืืื ืืงืึทืฆืืข:
-
XDP ืคึผืจืึธืืจืึทื ืงืขื ื ืืฉื ืงืจืึธื
cookie_seed
(ืืขืจ ืกืื ืืืื ืคืื ืื ืืึทืืฅ) ืืื ืึท ืืืืืืืข ืืืึทืืขืืืืืง, ืืืจ ืืึทืจืคึฟื ืกืืึธืจืืืืฉ ืืื ืื ืงืขืจื, ืื ืืืขืจื ืคืื ืืืึธืก ืืืขื ืืืื ืคึผืืจืืึทืืืงืื ืืขืจืืืึทื ืืืงื ืคึฟืื ืึท ืคืึทืจืืึธืืืขื ืืขื ืขืจืึทืืึธืจ. -
ืืืื ืื SYN ืงืืื ืฉืืืขืืขืืขื ืืื ืื ACK ืคึผืึทืงืึทื, ืืืจ ืืึธื ื ืื ืืึทืจืคึฟื ืฆื ืืจืืงื ืึท ืึธื ืืึธื, ืึธืืขืจ ืืขืืขื ืงืขื ืื 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 ืึทืืึทืื ืืืจ ืฆื ืื ืกืืจืืืขื ื ืืึทื ืฅ ืงืึธืืคึผืืืฆืืจื ืืึธืืืง, ืืืึธืก, ืืขืจืฆื, ืืื ืืจืื ื ืฆื ืืขืจืืืึทื ืืืงื ืึธื ืืืขืจืจืืึทืก ืืื ืคืึทืจืงืขืจ ืคึผืจืึทืกืขืกืื ื. ืืขืจ ืืืขืจืึทืคืืืขืจ ืืื ื ืืฉื ืืึทืื ืืจืืืก ืคึผืจืึธืืืขืืก; ืคึผืขืจืกื ืึทืื, ืืื ืืืึธืื ื ืืฉื ืึธืคึผืืึธืื ืืขื ืคึฟืึทืจ ืคึผืึทืจืฅ ืคืื ืืึทื ืืฆืขืจ ืคึผืืึทืฅ ืงืึธื.
ืืื ืื ืจืืข ืืืื, ืืืื ืื ืืขืืข ืืื ืืฉืืงืึทืืืข, ืืืจ ืืืขืื ืคืึทืจืขื ืืืงื ืื ืืืฉ ืคืื ืืืขืจืึทืคืืื ืงืืืืึทื ืฅ ืืื ืืืกืงืึทื ืขืงืฉืึทื ื, ืื ืกืืจืืืขื ื ืงืึธืื ืืขืจืก ืืื ืฉืจืืึทืื ืึท ืืึทื ืืฆืขืจ-ืกืคึผืึทืกืข ื ืืฆื ืฆื ืคืืจื ืื ืคืืืืขืจ.
ืืื ืงืก:
ืืึทื ืฅ ืงืึธื ืืืืฃ GitHub bpftrace ืึธืคึผื ืึทืจื ืืืึทื BPF ืืื XDP ืจืขืคืขืจืขื ืฅ ืืืื XDP ืืืืึธืจืืึทื PoC: ืงืึทืืคึผืืืืื ื ืฆื eBPF ืคึฟืื Rust
ืืงืืจ: www.habr.com