ืžื™ืจ ืฉืจื™ื™ื‘ืŸ ืฉื•ืฅ ืงืขื’ืŸ DDoS ืื ืคืืœืŸ ืื•ื™ืฃ XDP. ื™ืึธื“ืขืจ ื˜ื™ื™ืœ

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 ื”ืขืœืคึผืขืจืก) ื–ืขื ืขืŸ ืขืจืœื•ื™ื‘ื˜.

ื“ื™ื–ื™ื™ื ื™ื ื’ ืื•ืŸ ื™ื ืกื˜ืึธืœื™ื ื’ ืึท ืคื™ืœื˜ืขืจ ืงื•ืงื˜ ื•ื•ื™ ื“ืึธืก:

  1. ืžืงื•ืจ ืงืึธื“ (ืœืžืฉืœ kernel.c) ืื™ื– ืฆื•ื ื•ื™ืคื’ืขืฉื˜ืขืœื˜ ืื™ืŸ ื›ื™ื™ืคืขืฅ (kernel.o) ืคึฟืึทืจ ื“ื™ eBPF ื•ื•ื™ืจื˜ื•ืึทืœ ืžืึทืฉื™ืŸ ืึทืจืงืึทื˜ืขืงื˜ืฉืขืจ. ื–ื™ื ื˜ ืืงื˜ืื‘ืขืจ 2019, ื–ืึทืžืœื•ื ื’ ืฆื• eBPF ืื™ื– ื’ืขืฉื˜ื™ืฆื˜ ื“ื•ืจืš ืงืœืึทื ื’ ืื•ืŸ ืฆื•ื’ืขื–ืื’ื˜ ืื™ืŸ GCC 10.1.
  2. ืื•ื™ื‘ ื“ืขื ื›ื™ื™ืคืขืฅ ืงืึธื“ ื›ึผื•ืœืœ ืงืึทืœืœืก ืฆื• ืงืขืจืŸ ืกื˜ืจืึทืงื˜ืฉืขืจื– (ืœืžืฉืœ, ื˜ื™ืฉืŸ ืื•ืŸ ืงืึธื•ื ื˜ืขืจืก), ื–ื™ื™ืขืจ IDs ื–ืขื ืขืŸ ืจื™ืคึผืœื™ื™ืกื˜ ื“ื•ืจืš ื–ืขืจืึธืก, ื•ื•ืึธืก ืžื™ื˜ืœ ืึทื– ืึทื–ืึท ืงืึธื“ ืงืขื ืขืŸ ื ื™ื˜ ื–ื™ื™ืŸ ืขืงืกืึทืงื™ื•ื˜ืึทื“. ืื™ื™ื“ืขืจ ืื™ืจ ืœืึธื•ื“ื™ื ื’ ืื™ืŸ ื“ื™ ืงืขืจืŸ, ืื™ืจ ื“ืึทืจืคึฟืŸ ืฆื• ืคืึทืจื‘ื™ื™ึทื˜ืŸ ื“ื™ ื–ืขืจืึธืก ืžื™ื˜ ื“ื™ IDs ืคื•ืŸ ืกืคึผืขืฆื™ืคื™ืฉ ืึทื‘ื“ื–ืฉืขืงืฅ ื‘ืืฉืืคืŸ ื“ื•ืจืš ืงืขืจืŸ ืงืึทืœืœืก (ืœื™ื ืง ื“ื™ ืงืึธื“). ืื™ืจ ืงืขื ืขืŸ ื˜ืึธืŸ ื“ืึธืก ืžื™ื˜ ืคื•ื ื“ืจื•ื™ืกื ื“ื™ืง ื™ื•ื˜ื™ืœืึทื˜ื™ื–, ืึธื“ืขืจ ืื™ืจ ืงืขื ืขืŸ ืฉืจื™ื™ึทื‘ืŸ ืึท ืคึผืจืึธื’ืจืึทื ื•ื•ืึธืก ื•ื•ืขื˜ ืœื™ื ืง ืื•ืŸ ืœืึธื“ืŸ ืึท ืกืคึผืขืฆื™ืคื™ืฉ ืคื™ืœื˜ืขืจ.
  3. ื“ืขืจ ืงืขืจืŸ ื•ื•ืขืจืึทืคื™ื™ื– ื“ื™ ืœืึธื•ื“ื™ื“ ืคึผืจืึธื’ืจืึทื. ื“ืขืจ ืึทื•ื•ืขืง ืคื•ืŸ ืกื™ื™ืงืึทืœื– ืื•ืŸ ื“ื•ืจื›ืคืึทืœ ืฆื• ื™ืงืกื™ื“ ืคึผืึทืงืึทื˜ ืื•ืŸ ืึธื ืœื™ื™ื’ืŸ ื‘ืึทื•ื ื“ืจื™ื– ืื™ื– ืึธืคึผื’ืขืฉื˜ืขืœื˜. ืื•ื™ื‘ ื“ืขืจ ื•ื•ืขืจืึทืคื™ื™ืขืจ ืงืขืŸ ื ื™ืฉื˜ ื‘ืึทื•ื•ื™ื™ึทื–ืŸ ืึทื– ื“ื™ ืงืึธื“ ืื™ื– ืจื™ื›ื˜ื™ืง, ื“ื™ ืคึผืจืึธื’ืจืึทื ืื™ื– ืคืืจื•ื•ืืจืคืŸ - ืื™ืจ ื“ืึทืจืคึฟืŸ ืฆื• ื–ื™ื™ืŸ ืฆื•ืคืจื™ื“ืŸ ืžื™ื˜ ืื™ื.
  4. ื ืึธืš ื’ืขืจืึธื˜ืŸ ื•ื•ืขืจืึทืคืึทืงื™ื™ืฉืึทืŸ, ื“ื™ ืงืขืจืŸ ืงืึทืžืคึผื™ื™ืœื– ื“ื™ eBPF ืึทืจืงืึทื˜ืขืงื˜ืฉืขืจ ืึทื‘ื“ื–ืฉืขืงื˜ ืงืึธื“ ืื™ืŸ ืžืึทืฉื™ืŸ ืงืึธื“ ืคึฟืึทืจ ื“ื™ ืกื™ืกื˜ืขื ืึทืจืงืึทื˜ืขืงื˜ืฉืขืจ (ืคึผื•ื ืงื˜-ืื™ืŸ-ืฆื™ื™ื˜).
  5. ื“ืขืจ ืคึผืจืึธื’ืจืึทื ืึทื˜ืึทื˜ืฉื™ื– ืฆื• ื“ื™ ืฆื•ื‘ื™ื ื“ ืื•ืŸ ื”ื™ื™ื‘ื˜ ืคึผืจืึทืกืขืกื™ื ื’ ืคึผืึทืงื™ืฅ.

ื–ื™ื ื˜ XDP ืœื•ื™ืคื˜ ืื™ืŸ ื“ื™ ืงืขืจืŸ, ื“ื™ื‘ืึทื’ื™ื ื’ ืื™ื– ื“ื•ืจื›ื’ืขืงืึธื›ื˜ ืžื™ื˜ ืฉืคึผื•ืจ ืœืึธื’ืก ืื•ืŸ, ืื™ืŸ ืคืึทืงื˜, ืคึผืึทืงื™ืฅ ื•ื•ืึธืก ื“ื™ ืคึผืจืึธื’ืจืึทื ืคื™ืœื˜ืขืจืก ืึธื“ืขืจ ื“ื–ืฉืขื ืขืจื™ื™ืฅ. ืึธื‘ืขืจ, eBPF ื™ื ืฉื•ืจื– ืึทื– ื“ื™ ื“ืึทื•ื ืœืึธื•ื“ื™ื“ ืงืึธื“ ืื™ื– ื–ื™ื›ืขืจ ืคึฟืึทืจ ื“ื™ ืกื™ืกื˜ืขื, ืึทื–ื•ื™ ืื™ืจ ืงืขื ืขืŸ ืขืงืกืคึผืขืจื™ืžืขื ื˜ ืžื™ื˜ XDP ื’ืœื™ื™ึทืš ืื•ื™ืฃ ื“ื™ื™ืŸ ื”ื™ื’ืข ืœื™ื ื•ืงืก.

ืคึผืจื™ืคึผืขืจื™ื ื’ ื“ื™ ืกื•ื•ื™ื•ื•ืข

Assembly

ืงืœืึทื ื’ ืงืขื ืขืŸ ื ื™ืฉื˜ ื’ืœื™ื™ืš ืคึผืจืึธื“ื•ืฆื™ืจืŸ ื›ื™ื™ืคืขืฅ ืงืึธื“ ืคึฟืึทืจ ื“ื™ eBPF ืึทืจืงืึทื˜ืขืงื˜ืฉืขืจ, ืึทื–ื•ื™ ื“ืขืจ ืคึผืจืึธืฆืขืก ื‘ืืฉื˜ื™ื™ื˜ ืคื•ืŸ ืฆื•ื•ื™ื™ ืกื˜ืขืคึผืก:

  1. ืงืึธืžืคึผื™ืœื™ืจืŸ C ืงืึธื“ ืฆื• LLVM ื‘ื™ื˜ืขืงืึธื“ืข (clang -emit-llvm).
  2. ื’ืขืจ ื‘ื™ื˜ืขืงืึธื“ืข ืฆื• 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 ืื•ื™ ืš ื ืคืจืื’ืจื ื ืื™ ื– ืฆื•ื’ืขื˜ืฒืœ ื˜ ื’ืขืฐืืจืŸ , ืืคื™ืœ ื• ื– ื™ ืื™ ื– ื’ืขืฐืข ืŸ ืœืฒื“ื™ืง , ืื• ืŸ ืข ืจ ืื™ ื– ืื•ื™ืคื’ืขื”ื•ื™ื‘ ืŸ ื’ืขืฐืืจืŸ .

ื•ื•ื™ ื”ืื‘ ืื™ืš ื“ืืก ื’ืขื•ื•ืื•ืกื˜?

ืฉืคึผื•ืจ ื“ื™ ื“ืจืš ืคื•ืŸ ืึท ืคึผืขืงืœ ืื™ืŸ ื“ื™ ืงืขืจืŸ ื“ื™ ืžืขืงืึทื ื™ื–ืึทื ืคื•ืŸ ืคึผืขืจืฃ ื’ืขืฉืขืขื ื™ืฉืŸ ืึทืœืึทื•ื–, ื“ื•ืจืš ื“ืขื ื•ื•ืขื’, ื ื™ืฆืŸ ื“ื™ ื–ืขืœื‘ืข ื•ื•ื™ืจื˜ื•ืึทืœ ืžืึทืฉื™ืŸ, ื“ืึธืก ืื™ื–, eBPF ืื™ื– ื’ืขื ื™ืฆื˜ ืคึฟืึทืจ ื“ื™ืกืึทืกืกืขืžื‘ืœื™ ืžื™ื˜ eBPF.

ื“ื• ืžื•ื–ื˜ ืžืื›ืŸ ื’ื•ื˜ืก ืคื•ืŸ ืฉืœืขื›ื˜ืก, ื•ื•ื™ื™ืœ ืขืก ืื™ื– ื’ืืจื ื™ืฉื˜ ืื ื“ืขืจืฉ ืฆื• ืžืื›ืŸ.

$ 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 ืจื™ืกืคึผืึทื ื“ ื ื™ืฉื˜ ืฆื• ืคืึทืœืฉ ื˜ืฉืขืงืกืึทืžื–.

ืคึฟื•ืŸ ืึท 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 ืึทืœืึทื•ื– ืื™ืจ ืฆื• ื™ื ืกื˜ืจื•ืžืขื ื˜ ื’ืึทื ืฅ ืงืึธืžืคึผืœื™ืฆื™ืจื˜ ืœืึธื’ื™ืง, ื•ื•ืึธืก, ื“ืขืจืฆื•, ืื™ื– ื’ืจื™ื ื’ ืฆื• ื“ืขืจื”ื™ื™ึทื ื˜ื™ืงืŸ ืึธืŸ ื™ื‘ืขืจืจื™ื™ึทืก ืื™ืŸ ืคืึทืจืงืขืจ ืคึผืจืึทืกืขืกื™ื ื’. ื“ืขืจ ื•ื•ืขืจืึทืคื™ื™ืขืจ ื˜ื•ื˜ ื ื™ืฉื˜ ืžืึทื›ืŸ ื’ืจื•ื™ืก ืคึผืจืึธื‘ืœืขืžืก; ืคึผืขืจืกื ืึทืœื™, ืื™ืš ื•ื•ืึธืœื˜ ื ื™ืฉื˜ ืึธืคึผื–ืึธื’ืŸ ื“ืขื ืคึฟืึทืจ ืคึผืึทืจืฅ ืคื•ืŸ ื‘ืึทื ื™ืฆืขืจ ืคึผืœืึทืฅ ืงืึธื“.

ืื™ืŸ ื“ื™ ืจื’ืข ื˜ื™ื™ืœ, ืื•ื™ื‘ ื“ื™ ื˜ืขืžืข ืื™ื– ื˜ืฉื™ืงืึทื•ื•ืข, ืžื™ืจ ื•ื•ืขืœืŸ ืคืึทืจืขื ื“ื™ืงืŸ ื“ื™ ื˜ื™ืฉ ืคื•ืŸ ื•ื•ืขืจืึทืคื™ื™ื“ ืงืœื™ื™ืึทื ืฅ ืื•ืŸ ื“ื™ืกืงืึทื ืขืงืฉืึทื ื–, ื™ื ืกื˜ืจื•ืžืขื ื˜ ืงืึธื•ื ื˜ืขืจืก ืื•ืŸ ืฉืจื™ื™ึทื‘ืŸ ืึท ื‘ืึทื ื™ืฆืขืจ-ืกืคึผืึทืกืข ื ื•ืฆืŸ ืฆื• ืคื™ืจืŸ ื“ื™ ืคื™ืœื˜ืขืจ.

ืœื™ื ืงืก:

ืžืงื•ืจ: www.habr.com

ืœื™ื™ื’ืŸ ืึท ื‘ืึทืžืขืจืงื•ื ื’