рдЖрдореНрд╣реА XDP рд╡рд░ DDoS рд╣рд▓реНрд▓реНрдпрд╛рдВрдкрд╛рд╕реВрди рд╕рдВрд░рдХреНрд╖рдг рд▓рд┐рд╣рд┐рддреЛ. рдЖрдгреНрд╡рд┐рдХ рднрд╛рдЧ

рдПрдХреНрд╕реНрдкреНрд░реЗрд╕ рдбреЗрдЯрд╛ рдкрде (XDP) рддрдВрддреНрд░рдЬреНрдЮрд╛рди рдкреЕрдХреЗрдЯреНрд╕ рдХрд░реНрдирд▓ рдиреЗрдЯрд╡рд░реНрдХ рд╕реНрдЯреЕрдХрдордзреНрдпреЗ рдкреНрд░рд╡реЗрд╢ рдХрд░рдгреНрдпрд╛рдкреВрд░реНрд╡реА рд▓рд┐рдирдХреНрд╕ рдЗрдВрдЯрд░рдлреЗрд╕рд╡рд░ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рд░рд╣рджрд╛рд░реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд░рдгреНрдпрд╛рд╕ рдЕрдиреБрдорддреА рджреЗрддреЗ. XDP рдЪреЗ рдНрдкреНрд▓рд┐рдХреЗрд╢рди - DDoS рд╣рд▓реНрд▓реНрдпрд╛рдВрдкрд╛рд╕реВрди рд╕рдВрд░рдХреНрд╖рдг (рдХреНрд▓рд╛рдЙрдбрдлреНрд▓реЗрдЕрд░), рдЬрдЯрд┐рд▓ рдлрд┐рд▓реНрдЯрд░, рдЖрдХрдбреЗрд╡рд╛рд░реА рд╕рдВрдЧреНрд░рд╣ (рдиреЗрдЯрдлреНрд▓рд┐рдХреНрд╕). XDP рдкреНрд░реЛрдЧреНрд░рд╛рдореНрд╕ eBPF рд╡реНрд╣рд░реНрдЪреНрдпреБрдЕрд▓ рдорд╢реАрдирджреНрд╡рд╛рд░реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХреЗрд▓реЗ рдЬрд╛рддрд╛рдд, рддреНрдпрд╛рдореБрд│реЗ рдлрд┐рд▓реНрдЯрд░ рдкреНрд░рдХрд╛рд░рд╛рд╡рд░ рдЕрд╡рд▓рдВрдмреВрди рддреНрдпрд╛рдВрдЪреНрдпрд╛ рдХреЛрдб рдЖрдгрд┐ рдЙрдкрд▓рдмреНрдз рдХрд░реНрдирд▓ рдлрдВрдХреНрд╢рдиреНрд╕рд╡рд░ рдирд┐рд░реНрдмрдВрдз рдЕрд╕рддрд╛рдд.

рд▓реЗрдЦрд╛рдЪрд╛ рдЙрджреНрджреЗрд╢ XDP рд╡рд░реАрд▓ рдЕрд╕рдВрдЦреНрдп рд╕рд╛рдордЧреНрд░реАрддреАрд▓ рдХрдорддрд░рддрд╛ рднрд░реВрди рдХрд╛рдврдгреНрдпрд╛рдЪрд╛ рдЖрд╣реЗ. рдкреНрд░рдердо, рддреЗ рд░реЗрдбреАрдореЗрдб рдХреЛрдб рдкреНрд░рджрд╛рди рдХрд░рддрд╛рдд рдЬреЗ рддреНрд╡рд░рд┐рдд XDP рдЪреНрдпрд╛ рд╡реИрд╢рд┐рд╖реНрдЯреНрдпрд╛рдВрдирд╛ рдмрд╛рдпрдкрд╛рд╕ рдХрд░рддреЗ: рддреЗ рд╕рддреНрдпрд╛рдкрдирд╛рд╕рд╛рдареА рддрдпрд╛рд░ рдХреЗрд▓реЗрд▓реЗ рдЖрд╣реЗ рдХрд┐рдВрд╡рд╛ рд╕рдорд╕реНрдпрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдЦреВрдк рд╕реЛрдкреЗ рдЖрд╣реЗ. рдЬреЗрд╡реНрд╣рд╛ рддреБрдореНрд╣реА рддреБрдордЪрд╛ рдХреЛрдб рд╕реБрд░рд╡рд╛рддреАрдкрд╛рд╕реВрди рд▓рд┐рд╣рд┐рдгреНрдпрд╛рдЪрд╛ рдкреНрд░рдпрддреНрди рдХрд░рддрд╛, рддреЗрд╡реНрд╣рд╛ рддреБрдореНрд╣рд╛рд▓рд╛ рдард░рд╛рд╡рд┐рдХ рддреНрд░реБрдЯреАрдВрдЪреЗ рдХрд╛рдп рдХрд░рд╛рд╡реЗ рд╣реЗ рдХрд│рдд рдирд╛рд╣реА. рджреБрд╕рд░реЗ рдореНрд╣рдгрдЬреЗ, рд╡реНрд╣реАрдПрдо рдЖрдгрд┐ рд╣рд╛рд░реНрдбрд╡реЗрдЕрд░рд╢рд┐рд╡рд╛рдп рд╕реНрдерд╛рдирд┐рдХ рдкрд╛рддрд│реАрд╡рд░ XDP рдЪреА рдЪрд╛рдЪрдгреА рдХрд░рдгреНрдпрд╛рдЪреЗ рдорд╛рд░реНрдЧ рдХрд╡реНрд╣рд░ рдХреЗрд▓реЗрд▓реЗ рдирд╛рд╣реАрдд, рддреНрдпрд╛рдВрдЪреНрдпрд╛ рд╕реНрд╡рддрдГрдЪреЗ рдиреБрдХрд╕рд╛рди рдЕрд╕реВрдирд╣реА. рдордЬрдХреВрд░ рдиреЗрдЯрд╡рд░реНрдХрд┐рдВрдЧ рдЖрдгрд┐ рд▓рд┐рдирдХреНрд╕рд╢реА рдкрд░рд┐рдЪрд┐рдд рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░рд╕рд╛рдареА рдЖрд╣реЗ рдЬреНрдпрд╛рдВрдирд╛ XDP рдЖрдгрд┐ eBPF рдордзреНрдпреЗ рд╕реНрд╡рд╛рд░рд╕реНрдп рдЖрд╣реЗ.

рдпрд╛ рднрд╛рдЧрд╛рдд, XDP рдлрд┐рд▓реНрдЯрд░ рдХрд╕реЗ рдПрдХрддреНрд░ рдХреЗрд▓реЗ рдЬрд╛рддреЗ рдЖрдгрд┐ рддреНрдпрд╛рдЪреА рдЪрд╛рдЪрдгреА рдХрд╢реА рдХрд░рд╛рдпрдЪреА рд╣реЗ рдЖрдореНрд╣реА рддрдкрд╢реАрд▓рд╡рд╛рд░ рд╕рдордЬреВрди рдШреЗрдК, рддреНрдпрд╛рдирдВрддрд░ рдЖрдореНрд╣реА рдкреЕрдХреЗрдЯ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╕реНрддрд░рд╛рд╡рд░ рд╕реБрдкреНрд░рд╕рд┐рджреНрдз SYN рдХреБрдХреАрдЬ рдпрдВрддреНрд░рдгреЗрдЪреА рдПрдХ рд╕реЛрдкреА рдЖрд╡реГрддреНрддреА рд▓рд┐рд╣реВ. рдЖрдореНрд╣реА рдЕрджреНрдпрд╛рдк "рд╢реНрд╡реЗрдд рдпрд╛рджреА" рддрдпрд╛рд░ рдХрд░рдгрд╛рд░ рдирд╛рд╣реА
рд╕рддреНрдпрд╛рдкрд┐рдд рдХреНрд▓рд╛рдпрдВрдЯ, рдХрд╛рдЙрдВрдЯрд░ рдареЗрд╡рд╛ рдЖрдгрд┐ рдлрд┐рд▓реНрдЯрд░ рд╡реНрдпрд╡рд╕реНрдерд╛рдкрд┐рдд рдХрд░рд╛ - рдкреБрд░реЗрд╕реЗ рд▓реЙрдЧ.

рдЖрдореНрд╣реА рд╕реА рдордзреНрдпреЗ рд▓рд┐рд╣реВ - рддреЗ рдлреЕрд╢рдиреЗрдмрд▓ рдирд╛рд╣реА, рдкрд░рдВрддреБ рддреЗ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдЖрд╣реЗ. рд╕рд░реНрд╡ рдХреЛрдб GitHub рд╡рд░ рд╢реЗрд╡рдЯреА рд▓рд┐рдВрдХрджреНрд╡рд╛рд░реЗ рдЙрдкрд▓рдмреНрдз рдЖрд╣реЗрдд рдЖрдгрд┐ рд▓реЗрдЦрд╛рдд рд╡рд░реНрдгрди рдХреЗрд▓реЗрд▓реНрдпрд╛ рдЪрд░рдгрд╛рдВрдиреБрд╕рд╛рд░ рдХрдорд┐рдЯрдордзреНрдпреЗ рд╡рд┐рднрд╛рдЧрд▓реЗ рдЧреЗрд▓реЗ рдЖрд╣реЗрдд.

рдЕрд╕реНрд╡реАрдХрд░рдг. рдпрд╛ рд▓реЗрдЦрд╛рдЪреНрдпрд╛ рджрд░рдореНрдпрд╛рди, рдореА 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 рдЪреЗ рд╕рдВрдХрд▓рди Clang рджреНрд╡рд╛рд░реЗ рд╕рдорд░реНрдерд┐рдд рдЖрд╣реЗ рдЖрдгрд┐ GCC 10.1 рдордзреНрдпреЗ рд╡рдЪрди рджрд┐рд▓реЗ рдЖрд╣реЗ.
  2. рдпрд╛ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛрдбрдордзреНрдпреЗ рдХрд░реНрдирд▓ рд╕реНрдЯреНрд░рдХреНрдЪрд░реНрд╕ (рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдЯреЗрдмрд▓реНрд╕ рдЖрдгрд┐ рдХрд╛рдЙрдВрдЯрд░) рдХреЙрд▓ рдЕрд╕рд▓реНрдпрд╛рд╕, рддреНрдпрд╛рдВрдЪреЗ рдЖрдпрдбреА рд╢реВрдиреНрдпрд╛рдиреЗ рдмрджрд▓рд▓реЗ рдЬрд╛рддрд╛рдд, рдпрд╛рдЪрд╛ рдЕрд░реНрде рдЕрд╕рд╛ рдХреЛрдб рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХреЗрд▓рд╛ рдЬрд╛рдК рд╢рдХрдд рдирд╛рд╣реА. рдХрд░реНрдирд▓рдордзреНрдпреЗ рд▓реЛрдб рдХрд░рдгреНрдпрд╛рдкреВрд░реНрд╡реА, рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд░реНрдирд▓ рдХреЙрд▓рджреНрд╡рд╛рд░реЗ рддрдпрд╛рд░ рдХреЗрд▓реЗрд▓реНрдпрд╛ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕рдЪреНрдпрд╛ рдЖрдпрдбреАрд╕рд╣ рд╣реЗ рд╢реВрдиреНрдп рдмрджрд▓рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ (рдХреЛрдб рд▓рд┐рдВрдХ рдХрд░рд╛). рддреБрдореНрд╣реА рд╣реЗ рдмрд╛рд╣реНрдп рдпреБрдЯрд┐рд▓рд┐рдЯреАрдЬрд╕рд╣ рдХрд░реВ рд╢рдХрддрд╛ рдХрд┐рдВрд╡рд╛ рддреБрдореНрд╣реА рдПрдЦрд╛рджрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓рд┐рд╣реВ рд╢рдХрддрд╛ рдЬреЛ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдлрд┐рд▓реНрдЯрд░ рд▓рд┐рдВрдХ рдХрд░реЗрд▓ рдЖрдгрд┐ рд▓реЛрдб рдХрд░реЗрд▓.
  3. рдХрд░реНрдирд▓ рд▓реЛрдб рдХреЗрд▓реЗрд▓реНрдпрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдордЪреА рдкрдбрддрд╛рд│рдгреА рдХрд░рддреЗ. рд╕рд╛рдпрдХрд▓рдЪреА рдЕрдиреБрдкрд╕реНрдерд┐рддреА рдЖрдгрд┐ рдкреЕрдХреЗрдЯ рдЖрдгрд┐ рд╕реНрдЯреЕрдХ рд╕реАрдорд╛ рдУрд▓рд╛рдВрдбрдгреНрдпрд╛рдд рдЕрдкрдпрд╢ рддрдкрд╛рд╕рд▓реЗ рдЬрд╛рддреЗ. рдЬрд░ рд╕рддреНрдпрд╛рдкрдирдХрд░реНрддрд╛ рдХреЛрдб рдпреЛрдЧреНрдп рдЕрд╕рд▓реНрдпрд╛рдЪреЗ рд╕рд┐рджреНрдз рдХрд░реВ рд╢рдХрдд рдирд╛рд╣реА, рддрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдирд╛рдХрд╛рд░рд▓рд╛ рдЬрд╛рдИрд▓ - рдЖрдкрдг рддреНрдпрд╛рд▓рд╛ рд╕рдВрддреБрд╖реНрдЯ рдХрд░рдгреНрдпрд╛рд╕ рд╕рдХреНрд╖рдо рдЕрд╕рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ.
  4. рдпрд╢рд╕реНрд╡реА рдкрдбрддрд╛рд│рдгреАрдирдВрддрд░, рдХрд░реНрдирд▓ рд╕рд┐рд╕реНрдЯрдо рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ (рдлрдХреНрдд рд╡реЗрд│реЗрдд) рд╕рд╛рдареА рдорд╢реАрди рдХреЛрдбрдордзреНрдпреЗ eBPF рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛрдб рд╕рдВрдХрд▓рд┐рдд рдХрд░рддреЛ.
  5. рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЗрдВрдЯрд░рдлреЗрд╕рд▓рд╛ рдЬреЛрдбрддреЛ рдЖрдгрд┐ рдкреЕрдХреЗрдЯреНрд╕рд╡рд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд░рдгреНрдпрд╛рд╕ рд╕реБрд░рд╡рд╛рдд рдХрд░рддреЛ.

XDP рдХрд░реНрдирд▓рдордзреНрдпреЗ рдЪрд╛рд▓рдд рдЕрд╕рд▓реНрдпрд╛рдиреЗ, рдбреАрдмрдЧрд┐рдВрдЧ рдЯреНрд░реЗрд╕ рд▓реЙрдЧ рд╡рд╛рдкрд░реВрди рдХреЗрд▓реЗ рдЬрд╛рддреЗ рдЖрдгрд┐ рдЦрд░реЗрддрд░, рдкреНрд░реЛрдЧреНрд░рд╛рдо рдлрд┐рд▓реНрдЯрд░ рдХрд░рддреЗ рдХрд┐рдВрд╡рд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рддреЗ. рддрдерд╛рдкрд┐, eBPF рд╣реЗ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддреЗ рдХреА рдбрд╛рдЙрдирд▓реЛрдб рдХреЗрд▓реЗрд▓рд╛ рдХреЛрдб рд╕рд┐рд╕реНрдЯрдорд╕рд╛рдареА рд╕реБрд░рдХреНрд╖рд┐рдд рдЖрд╣реЗ, рддреНрдпрд╛рдореБрд│реЗ рддреБрдореНрд╣реА рдереЗрдЯ рддреБрдордЪреНрдпрд╛ рд╕реНрдерд╛рдирд┐рдХ Linux рд╡рд░ XDP рдЪрд╛ рдкреНрд░рдпреЛрдЧ рдХрд░реВ рд╢рдХрддрд╛.

рд╡рд╛рддрд╛рд╡рд░рдг рддрдпрд╛рд░ рдХрд░рдгреЗ

рдЕрд╕реЗрдВрдмреНрд▓реА

рдХреНрд▓рдБрдЧ рдереЗрдЯ рдИрдмреАрдкреАрдПрдл рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░рд╕рд╛рдареА рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛрдб рддрдпрд╛рд░ рдХрд░реВ рд╢рдХрдд рдирд╛рд╣реА, рдореНрд╣рдгреВрди рдкреНрд░рдХреНрд░рд┐рдпреЗрдордзреНрдпреЗ рджреЛрди рдЪрд░рдг рдЕрд╕рддрд╛рдд:

  1. LLVM рдмрд╛рдЗрдЯрдХреЛрдбрд╡рд░ C рдХреЛрдб рд╕рдВрдХрд▓рд┐рдд рдХрд░рд╛ (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. рдЖрддрд╛ рдХреБрдареЗ рдкреНрд░рдпрддреНрди рдХрд░рд╛рдпрдЪрд╛?

рдЪрд╛рдЪрдгреА рд╕реНрдЯрдБрдб

рд╕реНрдЯрдБрдбрдордзреНрдпреЗ рджреЛрди рдЗрдВрдЯрд░рдлреЗрд╕ рдЕрд╕рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ: рдЬреНрдпрд╛рд╡рд░ рдПрдХ рдлрд┐рд▓реНрдЯрд░ рдЕрд╕реЗрд▓ рдЖрдгрд┐ рдЬреНрдпрд╛рдордзреВрди рдкреЕрдХреЗрдЯ рдкрд╛рдард╡рд▓реЗ рдЬрд╛рддреАрд▓. рдЖрдордЪреНрдпрд╛ рдлрд┐рд▓реНрдЯрд░рд╕рд╣ рдирд┐рдпрдорд┐рдд рдНрдкреНрд▓рд┐рдХреЗрд╢рдиреНрд╕ рдХрд╕реЗ рдХрд╛рд░реНрдп рдХрд░рддрд╛рдд рд╣реЗ рддрдкрд╛рд╕рдгреНрдпрд╛рд╕рд╛рдареА рддреНрдпрд╛рдВрдЪреНрдпрд╛ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ IP рд╕рд╣ рдкреВрд░реНрдг рд╡рд┐рдХрд╕рд┐рдд Linux рдбрд┐рд╡реНрд╣рд╛рдЗрд╕ рдЕрд╕рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ.

рд╡реНрд╣реЗрде (рд╡реНрд╣рд░реНрдЪреНрдпреБрдЕрд▓ рдЗрдерд░рдиреЗрдЯ) рдкреНрд░рдХрд╛рд░рд╛рддреАрд▓ рдЙрдкрдХрд░рдгреЗ рдЖрдордЪреНрдпрд╛рд╕рд╛рдареА рдпреЛрдЧреНрдп рдЖрд╣реЗрдд: рд╣реА рд╡реНрд╣рд░реНрдЪреНрдпреБрдЕрд▓ рдиреЗрдЯрд╡рд░реНрдХ рдЗрдВрдЯрд░рдлреЗрд╕рдЪреА рдЬреЛрдбреА рдЖрд╣реЗрдд рдЬреА рдПрдХрдореЗрдХрд╛рдВрд╢реА рдереЗрдЯ тАЬрдХрдиреЗрдХреНрдЯтАЭ рдЖрд╣реЗрдд. рддреБрдореНрд╣реА рддреНрдпрд╛рдВрдирд╛ рдпрд╛рдкреНрд░рдорд╛рдгреЗ рддрдпрд╛рд░ рдХрд░реВ рд╢рдХрддрд╛ (рдпрд╛ рд╡рд┐рднрд╛рдЧрд╛рдд рд╕рд░реНрд╡ рдХрдорд╛рдВрдб 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, рдкрд░рдВрддреБ рддреНрдпрд╛рдВрдирд╛ рдкреЕрдХреЗрдЬреЗрд╕ рдмрджрд▓рд╛рд╡реА рд▓рд╛рдЧрддреАрд▓, рдЬреЗ рдбреАрдмрдЧрд┐рдВрдЧрд╕рд╛рдареА рдЧреИрд░рд╕реЛрдпреАрдЪреЗ рдЖрд╣реЗ. рдиреЗрдЯрд╡рд░реНрдХ рдиреЗрдорд╕реНрдкреЗрд╕реЗрд╕ (рдпрд╛рдкреБрдвреЗ netns) рд╡рд╛рдкрд░рдгреЗ рдЪрд╛рдВрдЧрд▓реЗ.

рдиреЗрдЯрд╡рд░реНрдХ рдиреЗрдорд╕реНрдкреЗрд╕рдордзреНрдпреЗ рдЗрдВрдЯрд░рдлреЗрд╕рдЪрд╛ рд╕рдВрдЪ, рд░рд╛рдЙрдЯрд┐рдВрдЧ рдЯреЗрдмрд▓реНрд╕ рдЖрдгрд┐ рдиреЗрдЯрдлрд┐рд▓реНрдЯрд░ рдирд┐рдпрдо рдЕрд╕рддрд╛рдд рдЬреЗ рдЗрддрд░ рдиреЗрдЯрдиреНрд╕рдордзреАрд▓ рд╕рдорд╛рди рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕рдкрд╛рд╕реВрди рд╡реЗрдЧрд│реЗ рдХреЗрд▓реЗ рдЬрд╛рддрд╛рдд. рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдиреЗрдорд╕реНрдкреЗрд╕рдордзреНрдпреЗ рдЪрд╛рд▓рддреЗ рдЖрдгрд┐ рдлрдХреНрдд рддреНрдпрд╛ рдиреЗрдЯрдиреНрд╕рдЪреНрдпрд╛ рд╡рд╕реНрддреВрдВрдордзреНрдпреЗ рдкреНрд░рд╡реЗрд╢ рдЕрд╕рддреЛ. рдбреАрдлреЙрд▓реНрдЯрдиреБрд╕рд╛рд░, рд╕рд┐рд╕реНрдЯрдордордзреНрдпреЗ рд╕рд░реНрд╡ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕рд╕рд╛рдареА рдПрдХрдЪ рдиреЗрдЯрд╡рд░реНрдХ рдиреЗрдорд╕реНрдкреЗрд╕ рдЖрд╣реЗ, рддреНрдпрд╛рдореБрд│реЗ рддреБрдореНрд╣реА рд▓рд┐рдирдХреНрд╕рдордзреНрдпреЗ рдХрд╛рдо рдХрд░реВ рд╢рдХрддрд╛ рдЖрдгрд┐ netns рдмрджреНрджрд▓ рдорд╛рд╣рд┐рддреА рдирд╛рд╣реА.

рдЪрд▓рд╛ рдирд╡реАрди рдиреЗрдорд╕реНрдкреЗрд╕ рддрдпрд╛рд░ рдХрд░реВрдпрд╛ 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 рджрд░рдореНрдпрд╛рди рдлрд┐рд░рддрд╛рдирд╛, рдЗрдВрдЯрд░рдлреЗрд╕ рдЦрд╛рд▓реА рдЬрд╛рддреЛ рдЖрдгрд┐ рддреНрдпрд╛рдЪрд╛ рдкрддреНрддрд╛ рдЧрдорд╛рд╡рддреЛ. 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 рдЗрдХреЛ рд░рд┐рдХреНрд╡реЗрд╕реНрдЯ рджрд╛рдЦрд╡рд▓реЗ рдкрд╛рд╣рд┐рдЬреЗ рдЖрдгрд┐ ICMP рдЗрдХреЛ рд░рд┐рдкреНрд▓рд╛рдп рджрд╛рдЦрд╡рдгреЗ рдерд╛рдВрдмрд╡рд╛рд╡реЗ. рдкрдг рддреЗ рджрд╛рдЦрд╡рдд рдирд╛рд╣реА. рд╣реЗ рдХрд╛рдорд╛рд╕рд╛рдареА рдмрд╛рд╣реЗрд░ рд╡рд│рддреЗ XDP_TX рд╡рд░ рдХрд╛рд░реНрдпрдХреНрд░рдорд╛рдд xdp-local рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗрдЬреЛрдбреА рдЗрдВрдЯрд░рдлреЗрд╕рд╡рд░ xdp-remote рдПрдХ рдХрд╛рд░реНрдпрдХреНрд░рдо рджреЗрдЦреАрд▓ рдирд┐рдпреБрдХреНрдд рдХреЗрд▓рд╛ рдЧреЗрд▓рд╛, рдЬрд░реА рддреЛ рд░рд┐рдХрд╛рдорд╛ рдЕрд╕рд▓рд╛ рддрд░реАрд╣реА, рдЖрдгрд┐ рддреНрдпрд╛рд▓рд╛ рдЙрдард╡рд▓реЗ рдЧреЗрд▓реЗ.

рдорд▓рд╛ рд╣реЗ рдХрд╕реЗ рдХрд│рд▓реЗ?

рдХрд░реНрдирд▓рдордзреАрд▓ рдкреЕрдХреЗрдЬрдЪрд╛ рдорд╛рд░реНрдЧ рдЯреНрд░реЗрд╕ рдХрд░рд╛ рдкрд░рдл рдЗрд╡реНрд╣реЗрдВрдЯ рдореЗрдХреЕрдирд┐рдЭрдо, рддрд╕реЗ, рд╕рдорд╛рди рд╡реНрд╣рд░реНрдЪреНрдпреБрдЕрд▓ рдорд╢реАрди рд╡рд╛рдкрд░реВрди рдкрд░рд╡рд╛рдирдЧреА рджреЗрддреЗ, рдореНрд╣рдгрдЬреЗ, eBPF рд╕рд╣ disassemblies рд╕рд╛рдареА 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, рдореЗрдХрдлрд╛рдЗрд▓рдордзреНрдпреЗ рдЬреЛрдбрд╛, рддреНрдпрд╛рд╕ рдмрд╛рдВрдзрд╛ 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

рддреНрдпрд╛рдРрд╡рдЬреА рдлрдХреНрдд рдПрдЖрд░рдкреА рджрд╛рдЦрд╡рд▓реЗ рдЕрд╕рд▓реНрдпрд╛рд╕, рддреБрдореНрд╣рд╛рд▓рд╛ рдлрд┐рд▓реНрдЯрд░ рдХрд╛рдврд╛рд╡реЗ рд▓рд╛рдЧрддреАрд▓ (рд╣реЗ рдХрд░рддреЗ sudo ./stand detach), рдЬрд╛рдК рджреНрдпрд╛ ping, рдирдВрддрд░ рдлрд┐рд▓реНрдЯрд░ рд╕реЗрдЯ рдХрд░рд╛ рдЖрдгрд┐ рдкреБрдиреНрд╣рд╛ рдкреНрд░рдпрддреНрди рдХрд░рд╛. рд╕рдорд╕реНрдпрд╛ рдлрд┐рд▓реНрдЯрд░рдЪреА рдЖрд╣реЗ XDP_TX рдПрдЖрд░рдкреА рдЖрдгрд┐ рд╕реНрдЯреЕрдХрд╡рд░ рджреЛрдиреНрд╣реА рд╡реИрдз
рдиреЗрдорд╕реНрдкреЗрд╕ xdp-test MAC рдкрддреНрддрд╛ 192.0.2.1 "рд╡рд┐рд╕рд░рдгреЗ" рд╡реНрдпрд╡рд╕реНрдерд╛рдкрд┐рдд рдХреЗрд▓реЗ рдЖрд╣реЗ, рддреЛ рдпрд╛ рдЖрдпрдкреАрдЪреЗ рдирд┐рд░рд╛рдХрд░рдг рдХрд░рдгреНрдпрд╛рдд рд╕рдХреНрд╖рдо рд╣реЛрдгрд╛рд░ рдирд╛рд╣реА.

рд╕рдорд╕реНрдпреЗрдЪреА рдирд┐рд░реНрдорд┐рддреА

рдЪрд▓рд╛ рдирдореВрдж рдХреЗрд▓реЗрд▓реНрдпрд╛ рдХрд╛рд░реНрдпрд╛рдХрдбреЗ рд╡рд│реВ: XDP рд╡рд░ SYN рдХреБрдХреАрдЬ рдпрдВрддреНрд░рдгрд╛ рд▓рд┐рд╣рд╛.

SYN рдлреНрд▓рдб рд╣рд╛ рд▓реЛрдХрдкреНрд░рд┐рдп DDoS рд╣рд▓реНрд▓рд╛ рд░рд╛рд╣рд┐рд▓рд╛ рдЖрд╣реЗ, рдЬреНрдпрд╛рдЪрд╛ рд╕рд╛рд░ рдЦрд╛рд▓реАрд▓рдкреНрд░рдорд╛рдгреЗ рдЖрд╣реЗ. рдЬреЗрд╡реНрд╣рд╛ рдХрдиреЗрдХреНрд╢рди рд╕реНрдерд╛рдкрд┐рдд рдХреЗрд▓реЗ рдЬрд╛рддреЗ (TCP рд╣рдБрдбрд╢реЗрдХ), рд╕рд░реНрд╡реНрд╣рд░рд▓рд╛ рдПрдХ SYN рдкреНрд░рд╛рдкреНрдд рд╣реЛрддреЛ, рднрд╡рд┐рд╖реНрдпрд╛рддреАрд▓ рдХрдиреЗрдХреНрд╢рдирд╕рд╛рдареА рд╕рдВрд╕рд╛рдзрдиреЗ рд╡рд╛рдЯрдк рдХрд░рддрд╛рдд, SYNACK рдкреЕрдХреЗрдЯрд╕рд╣ рдкреНрд░рддрд┐рд╕рд╛рдж рджреЗрддрд╛рдд рдЖрдгрд┐ ACK рдЪреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рддрд╛рдд. рдЖрдХреНрд░рдордгрдХрд░реНрддрд╛ рдмрд╣реБ-рд╣рдЬрд╛рд░-рдордЬрдмреВрдд рдмреЙрдЯрдиреЗрдЯрдордзреНрдпреЗ рдкреНрд░рддреНрдпреЗрдХ рд╣реЛрд╕реНрдЯрдХрдбреВрди рдлрд╕рд╡рдгреВрдХ рдХреЗрд▓реЗрд▓реНрдпрд╛ рдкрддреНрддреНрдпрд╛рдВрдордзреВрди рдкреНрд░рддрд┐ рд╕реЗрдХрдВрдж рд╣рдЬрд╛рд░реЛ SYN рдкреЕрдХреЗрдЯ рдкрд╛рдард╡рддреЛ. рдкреЕрдХреЗрдЯ рдЖрд▓реНрдпрд╛рд╡рд░ рд╕рд░реНрд╡реНрд╣рд░рд▓рд╛ рддрд╛рдмрдбрддреЛрдм рд╕рдВрд╕рд╛рдзрдиреЗ рд╡рд╛рдЯрдк рдХрд░рдгреНрдпрд╛рд╕ рднрд╛рдЧ рдкрд╛рдбрд▓реЗ рдЬрд╛рддреЗ, рдкрд░рдВрддреБ рдореЛрдареНрдпрд╛ рдХрд╛рд▓рдмрд╛рд╣реНрдпрддреЗрдирдВрддрд░ рддреЗ рд╕реЛрдбрд▓реЗ рдЬрд╛рддреЗ, рдкрд░рд┐рдгрд╛рдореА, рдореЗрдорд░реА рдХрд┐рдВрд╡рд╛ рдорд░реНрдпрд╛рджрд╛ рд╕рдВрдкрддрд╛рдд, рдирд╡реАрди рдХрдиреЗрдХреНрд╢рди рд╕реНрд╡реАрдХрд╛рд░рд▓реЗ рдЬрд╛рдд рдирд╛рд╣реАрдд рдЖрдгрд┐ рд╕реЗрд╡рд╛ рдЕрдиреБрдкрд▓рдмреНрдз рдЕрд╕рддреЗ.

рдЬрд░ рддреБрдореНрд╣реА SYN рдкреЕрдХреЗрдЯрд╡рд░ рдЖрдзрд╛рд░рд┐рдд рд╕рдВрд╕рд╛рдзрдиреЗ рд╡рд╛рдЯрдк рдХреЗрд▓реА рдирд╛рд╣реАрдд, рдкрд░рдВрддреБ рдлрдХреНрдд SYNACK рдкреЕрдХреЗрдЯрдиреЗ рдкреНрд░рддрд┐рд╕рд╛рдж рджрд┐рд▓рд╛, рддрд░ рд╕рд░реНрд╡реНрд╣рд░рд▓рд╛ рдХрд╕реЗ рд╕рдордЬреЗрд▓ рдХреА рдирдВрддрд░ рдЖрд▓реЗрд▓реЗ ACK рдкреЕрдХреЗрдЯ рд╕реЗрд╡реНрд╣ рди рдХреЗрд▓реЗрд▓реНрдпрд╛ SYN рдкреЕрдХреЗрдЯрдЪрд╛ рд╕рдВрджрд░реНрдн рджреЗрддреЗ? рд╢реЗрд╡рдЯреА, рдЖрдХреНрд░рдордгрдХрд░реНрддрд╛ рдмрдирд╛рд╡рдЯ ACKs рджреЗрдЦреАрд▓ рддрдпрд╛рд░ рдХрд░реВ рд╢рдХрддреЛ. SYN рдХреБрдХреАрдЪрд╛ рдореБрджреНрджрд╛ рддреНрдпрд╛рдд рдПрдиреНрдХреЛрдб рдХрд░рдгреЗ рдЖрд╣реЗ seqnum рдкрддреНрддреЗ, рдкреЛрд░реНрдЯ рдЖрдгрд┐ рдмрджрд▓рдгрд╛рд░реЗ рдореАрда рдпрд╛рдВрдЪрд╛ рд╣реЕрд╢ рдореНрд╣рдгреВрди рдХрдиреЗрдХреНрд╢рди рдкреЕрд░рд╛рдореАрдЯрд░реНрд╕. рдЬрд░ рдореАрда рдмрджрд▓рдгреНрдпрд╛рдкреВрд░реНрд╡реА ACK рдкреЛрд╣реЛрдЪрд▓рд╛, рддрд░ рддреБрдореНрд╣реА рдкреБрдиреНрд╣рд╛ рд╣реЕрд╢рдЪреА рдЧрдгрдирд╛ рдХрд░реВ рд╢рдХрддрд╛ рдЖрдгрд┐ рддреНрдпрд╛рдЪреА рддреБрд▓рдирд╛ рдХрд░реВ рд╢рдХрддрд╛ acknum. рдлреЛрд░реНрдЬ acknum рд╣рд▓реНрд▓реЗрдЦреЛрд░ рдХрд░реВ рд╢рдХрдд рдирд╛рд╣реА, рдХрд╛рд░рдг рдорд┐рдард╛рдд рдЧреБрдкрд┐рдд рд╕рдорд╛рд╡рд┐рд╖реНрдЯ рдЖрд╣реЗ рдЖрдгрд┐ рдорд░реНрдпрд╛рджрд┐рдд рдЪреЕрдиреЗрд▓рдореБрд│реЗ рддреНрдпрд╛рд╕ рдХреНрд░рдорд╡рд╛рд░реА рд▓рд╛рд╡рдгреНрдпрд╛рд╕рд╛рдареА рд╡реЗрд│ рдорд┐рд│рдгрд╛рд░ рдирд╛рд╣реА.

рд▓рд┐рдирдХреНрд╕ рдХрд░реНрдирд▓рдордзреНрдпреЗ SYN рдХреБрдХреА рдмрд░реНрдпрд╛рдЪ рдХрд╛рд│рд╛рдкрд╛рд╕реВрди рд▓рд╛рдЧреВ рдХреЗрд▓реА рдЧреЗрд▓реА рдЖрд╣реЗ рдЖрдгрд┐ SYN рдЦреВрдк рд▓рд╡рдХрд░ рдЖрдгрд┐ рдПрдХрддреНрд░рд┐рддрдкрдгреЗ рдкреЛрд╣реЛрдЪрд▓реНрдпрд╛рд╕ рд╕реНрд╡рдпрдВрдЪрд▓рд┐рддрдкрдгреЗ рд╕рдХреНрд╖рдо рдХреЗрд▓реА рдЬрд╛рдК рд╢рдХрддреЗ.

рдЯреАрд╕реАрдкреА рд╣рдБрдбрд╢реЗрдХрд╡рд░ рд╢реИрдХреНрд╖рдгрд┐рдХ рдХрд╛рд░реНрдпрдХреНрд░рдо

TCP рдмрд╛рдЗрдЯреНрд╕рдЪрд╛ рдкреНрд░рд╡рд╛рд╣ рдореНрд╣рдгреВрди рдбреЗрдЯрд╛ рдЯреНрд░рд╛рдиреНрд╕рдорд┐рд╢рди рдкреНрд░рджрд╛рди рдХрд░рддреЗ, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, HTTP рд╡рд┐рдирдВрддреНрдпрд╛ TCP рд╡рд░ рдкреНрд░рд╕рд╛рд░рд┐рдд рдХреЗрд▓реНрдпрд╛ рдЬрд╛рддрд╛рдд. рдкреНрд░рд╡рд╛рд╣ рдкреЕрдХреЗрдЯрдордзреНрдпреЗ рддреБрдХрдбреНрдпрд╛рдВрдордзреНрдпреЗ рдкреНрд░рд╕рд╛рд░рд┐рдд рдХреЗрд▓рд╛ рдЬрд╛рддреЛ. рд╕рд░реНрд╡ TCP рдкреЕрдХреЗрдЯрдордзреНрдпреЗ рддрд╛рд░реНрдХрд┐рдХ рдзреНрд╡рдЬ рдЖрдгрд┐ 32-рдмрд┐рдЯ рдЕрдиреБрдХреНрд░рдо рдХреНрд░рдорд╛рдВрдХ рдЖрд╣реЗрдд:

  • рдзреНрд╡рдЬрд╛рдВрдЪреЗ рд╕рдВрдпреЛрдЬрди рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреЕрдХреЗрдЬрдЪреА рднреВрдорд┐рдХрд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ. SYN рдзреНрд╡рдЬ рд╕реВрдЪрд┐рдд рдХрд░рддреЛ рдХреА рд╣реЗ рдХрдиреЗрдХреНрд╢рдирд╡рд░реАрд▓ рдкреНрд░реЗрд╖рдХрд╛рдЪреЗ рдкрд╣рд┐рд▓реЗ рдкреЕрдХреЗрдЯ рдЖрд╣реЗ. ACK рдзреНрд╡рдЬрд╛рдЪрд╛ рдЕрд░реНрде рдЕрд╕рд╛ рдЖрд╣реЗ рдХреА рдкреНрд░реЗрд╖рдХрд╛рдиреЗ рдмрд╛рдЗрдЯрдкрд░реНрдпрдВрдд рд╕рд░реНрд╡ рдХрдиреЗрдХреНрд╢рди рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХреЗрд▓рд╛ рдЖрд╣реЗ acknum. рдПрдХрд╛ рдкреЕрдХреЗрдЯрдордзреНрдпреЗ рдЕрдиреЗрдХ рдзреНрд╡рдЬ рдЕрд╕реВ рд╢рдХрддрд╛рдд рдЖрдгрд┐ рддреНрдпрд╛рдВрдЪреНрдпрд╛ рд╕рдВрдпреЛрдЧрд╛рдиреЗ рдореНрд╣рдгрддрд╛рдд, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, SYNACK рдкреЕрдХреЗрдЯ.

  • рдЕрдиреБрдХреНрд░рдо рдХреНрд░рдорд╛рдВрдХ (seqnum) рдпрд╛ рдкреЕрдХреЗрдЯрдордзреНрдпреЗ рдкреНрд░рд╕рд╛рд░рд┐рдд рдХреЗрд▓реЗрд▓реНрдпрд╛ рдкрд╣рд┐рд▓реНрдпрд╛ рдмрд╛рдЗрдЯрд╕рд╛рдареА рдбреЗрдЯрд╛ рдкреНрд░рд╡рд╛рд╣рд╛рддреАрд▓ рдСрдлрд╕реЗрдЯ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ. рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдЬрд░ рдкрд╣рд┐рд▓реНрдпрд╛ рдкреЕрдХреЗрдЯрдордзреНрдпреЗ X рдмрд╛рдЗрдЯреНрд╕рдЪреНрдпрд╛ рдбреЗрдЯрд╛рд╕рд╣ рд╣рд╛ рдХреНрд░рдорд╛рдВрдХ N рдЕрд╕реЗрд▓, рддрд░ рдирд╡реАрди рдбреЗрдЯрд╛рд╕рд╣ рдкреБрдвреАрд▓ рдкреЕрдХреЗрдЯрдордзреНрдпреЗ рддреЛ N+X рдЕрд╕реЗрд▓. рдХрдиреЗрдХреНрд╢рдирдЪреНрдпрд╛ рд╕реБрд░реВрд╡рд╛рддреАрд╕, рдкреНрд░рддреНрдпреЗрдХ рдмрд╛рдЬреВ рдпрд╛рджреГрдЪреНрдЫрд┐рдХрдкрдгреЗ рд╣реА рд╕рдВрдЦреНрдпрд╛ рдирд┐рд╡рдбрддреЗ.

  • рдкреЛрдЪрдкрд╛рд╡рддреА рдХреНрд░рдорд╛рдВрдХ (ре▓рдХреНрдирдо) - 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 рдкреНрд░реЛрдЧреНрд░рд╛рдордиреЗ рдЦрд╛рд▓реАрд▓ рдЧреЛрд╖реНрдЯреА рдХреЗрд▓реНрдпрд╛ рдкрд╛рд╣рд┐рдЬреЗрдд:

  • рдХреБрдХреАрд╕рд╣ SYNACK рд╕рд╣ SYN рд▓рд╛ рдкреНрд░рддрд┐рд╕рд╛рдж рджреНрдпрд╛;
  • ACK рд▓рд╛ RST рд╕рд╣ рдкреНрд░рддрд┐рд╕рд╛рдж рджреНрдпрд╛ (рдбрд┐рд╕реНрдХрдиреЗрдХреНрдЯ рдХрд░рд╛);
  • рдЙрд░реНрд╡рд░рд┐рдд рдкреЕрдХреЗрдЯ рдЯрд╛рдХреВрди рджреНрдпрд╛.

рдкреЕрдХреЗрдЬ рдкрд╛рд░реНрд╕рд┐рдВрдЧрд╕рд╣ рдЕрд▓реНрдЧреЛрд░рд┐рджрдордЪрд╛ рд╕реНрдпреВрдбреЛрдХреЛрдб:

╨Х╤Б╨╗╨╕ ╤Н╤В╨╛ ╨╜╨╡ Ethernet,
    ╨┐╤А╨╛╨┐╤Г╤Б╤В╨╕╤В╤М ╨┐╨░╨║╨╡╤В.
╨Х╤Б╨╗╨╕ ╤Н╤В╨╛ ╨╜╨╡ IPv4,
    ╨┐╤А╨╛╨┐╤Г╤Б╤В╨╕╤В╤М ╨┐╨░╨║╨╡╤В.
╨Х╤Б╨╗╨╕ ╨░╨┤╤А╨╡╤Б ╨▓ ╤В╨░╨▒╨╗╨╕╤Ж╨╡ ╨┐╤А╨╛╨▓╨╡╤А╨╡╨╜╨╜╤Л╤Е,               (*)
        ╤Г╨╝╨╡╨╜╤М╤И╨╕╤В╤М ╤Б╤З╨╡╤В╤З╨╕╨║ ╨╛╤Б╤В╨░╨▓╤И╨╕╤Е╤Б╤П ╨┐╤А╨╛╨▓╨╡╤А╨╛╨║,
        ╨┐╤А╨╛╨┐╤Г╤Б╤В╨╕╤В╤М ╨┐╨░╨║╨╡╤В.
╨Х╤Б╨╗╨╕ ╤Н╤В╨╛ ╨╜╨╡ TCP,
    ╤Б╨▒╤А╨╛╤Б╨╕╤В╤М ╨┐╨░╨║╨╡╤В.     (**)
╨Х╤Б╨╗╨╕ ╤Н╤В╨╛ SYN,
    ╨╛╤В╨▓╨╡╤В╨╕╤В╤М SYN-ACK ╤Б cookie.
╨Х╤Б╨╗╨╕ ╤Н╤В╨╛ ACK,
    ╨╡╤Б╨╗╨╕ ╨▓ acknum ╨╗╨╡╨╢╨╕╤В ╨╜╨╡ cookie,
        ╤Б╨▒╤А╨╛╤Б╨╕╤В╤М ╨┐╨░╨║╨╡╤В.
    ╨Ч╨░╨╜╨╡╤Б╤В╨╕ ╨▓ ╤В╨░╨▒╨╗╨╕╤Ж╤Г ╨░╨┤╤А╨╡╤Б ╤Б N ╨╛╤Б╤В╨░╨▓╤И╨╕╤Е╤Б╤П ╨┐╤А╨╛╨▓╨╡╤А╨╛╨║.    (*)
    ╨Ю╤В╨▓╨╡╤В╨╕╤В╤М RST.   (**)
╨Т ╨╛╤Б╤В╨░╨╗╤М╨╜╤Л╤Е ╤Б╨╗╤Г╤З╨░╤П╤Е ╤Б╨▒╤А╨╛╤Б╨╕╤В╤М ╨┐╨░╨║╨╡╤В.

рдПрдХ (*) рддреБрдореНрд╣рд╛рд▓рд╛ рд╕рд┐рд╕реНрдЯреАрдордЪреА рд╕реНрдерд┐рддреА рд╡реНрдпрд╡рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдгреНрдпрд╛рдЪреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЕрд╕рд▓реЗрд▓реЗ рдмрд┐рдВрджреВ рдЪрд┐рдиреНрд╣рд╛рдВрдХрд┐рдд рдХреЗрд▓реЗ рдЖрд╣реЗрдд - рдкрд╣рд┐рд▓реНрдпрд╛ рдЯрдкреНрдкреНрдпрд╛рд╡рд░ рддреБрдореНрд╣реА рд╕реАрдХреНрдирдо рдореНрд╣рдгреВрди SYN рдХреБрдХреАрдЪреНрдпрд╛ рдирд┐рд░реНрдорд┐рддреАрд╕рд╣ TCP рд╣рдБрдбрд╢реЗрдХ рд▓рд╛рдЧреВ рдХрд░реВрди рддреНрдпрд╛рдВрдЪреНрдпрд╛рд╢рд┐рд╡рд╛рдп рдХрд░реВ рд╢рдХрддрд╛.

рдЬрд╛рдЧреЗрд╡рд░ (**), рдЖрдордЪреНрдпрд╛рдХрдбреЗ рдЯреЗрдмрд▓ рдирд╕рддрд╛рдирд╛, рдЖрдореНрд╣реА рдкреЕрдХреЗрдЯ рд╡рдЧрд│реВ.

TCP рд╣рдБрдбрд╢реЗрдХрдЪреА рдЕрдВрдорд▓рдмрдЬрд╛рд╡рдгреА рдХрд░рдд рдЖрд╣реЗ

рдкреЕрдХреЗрдЬ рдкрд╛рд░реНрд╕ рдХрд░рдгреЗ рдЖрдгрд┐ рдХреЛрдб рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рдгреЗ

рдЖрдореНрд╣рд╛рд▓рд╛ рдиреЗрдЯрд╡рд░реНрдХ рд╣реЗрдбрд░ рд╕реНрдЯреНрд░рдХреНрдЪрд░реНрд╕рдЪреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЕрд╕реЗрд▓: рдЗрдерд░рдиреЗрдЯ (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 рдмрд╛рдЗрдЯреНрд╕ рдкрд░реНрдпрдВрдд. рдЖрдкрдг рдкреБрдирд░рд╛рд╡реГрддреНрддреАрдЪреНрдпрд╛ рдирд┐рд╢реНрдЪрд┐рдд рд╕рдВрдЦреНрдпреЗрд╕рд╣ рд▓реВрдк рдмрдирд╡реВ рд╢рдХрддрд╛, рдЬреЗ рд▓рд╡рдХрд░ рд╕рдорд╛рдкреНрдд рд╣реЛрдК рд╢рдХрддреЗ.

рдореА рдЖрд╣реЗ рдХреА рд▓рдХреНрд╖рд╛рдд рдареЗрд╡рд╛ рдЖрд░рдПрдлрд╕реА 1624 рдЬрд░ рдлрдХреНрдд рдкреЕрдХреЗрдЬреЗрд╕рдЪреЗ рдирд┐рд╢реНрдЪрд┐рдд рд╢рдмреНрдж рдмрджрд▓рд▓реЗ рдЕрд╕рддреАрд▓ рддрд░ рдЪреЗрдХрд╕рдордЪреА рдЕрдВрд╢рддрдГ рдкреБрдирд░реНрдЧрдгрдирд╛ рдХрд╢реА рдХрд░рд╛рд╡реА. рддрдерд╛рдкрд┐, рдкрджреНрдзрдд рд╕рд╛рд░реНрд╡рддреНрд░рд┐рдХ рдирд╛рд╣реА, рдЖрдгрд┐ рдЕрдВрдорд▓рдмрдЬрд╛рд╡рдгреА рд░рд╛рдЦрдгреЗ рдЕрдзрд┐рдХ рдХрдареАрдг рд╣реЛрдИрд▓.

рдЪреЗрдХрд╕рдо рдЧрдгрдирд╛ рдХрд╛рд░реНрдп:

#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() RFC 32 рдиреБрд╕рд╛рд░, 16-рдмрд┐рдЯ рд╢рдмреНрджрд╛рдВрдЪреНрдпрд╛ 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 рд╡рд░ xdp-remote рдХрд╛рд░рдг, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, hping3 рдЪреБрдХреАрдЪреНрдпрд╛ рдЪреЗрдХрд╕рдорд▓рд╛ рдкреНрд░рддрд┐рд╕рд╛рдж рджреЗрдд рдирд╛рд╣реА.

XDP рджреГрд╖реНрдЯрд┐рдХреЛрдирд╛рддреВрди, рд╕рддреНрдпрд╛рдкрди рд╕реНрд╡рддрдГрдЪ рдХреНрд╖реБрд▓реНрд▓рдХ рдЖрд╣реЗ. рдЧрдгрдирд╛ рдЕрд▓реНрдЧреЛрд░рд┐рджрдо рдЖрджрд┐рдо рдЖрд╣реЗ рдЖрдгрд┐ рдЕрддреНрдпрд╛рдзреБрдирд┐рдХ рдЖрдХреНрд░рдордгрдХрд░реНрддреНрдпрд╛рд╕рд╛рдареА рдЕрд╕реБрд░рдХреНрд╖рд┐рдд рдЖрд╣реЗ. рд▓рд┐рдирдХреНрд╕ рдХрд░реНрдирд▓, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдХреНрд░рд┐рдкреНрдЯреЛрдЧреНрд░рд╛рдлрд┐рдХ рд╕рд┐рдкрд╣реЕрд╢ рд╡рд╛рдкрд░рддреЗ, рдкрд░рдВрддреБ 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 рддреБрдореНрд╣рд╛рд▓рд╛ рдмрд▒реНрдпрд╛рдЪ рдЬрдЯрд┐рд▓ рддрд░реНрдХрд╢рд╛рд╕реНрддреНрд░рд╛рдЪреА рдЕрдВрдорд▓рдмрдЬрд╛рд╡рдгреА рдХрд░рдгреНрдпрд╛рд╕ рдЕрдиреБрдорддреА рджреЗрддреЗ, рдЬреЗ рд╢рд┐рд╡рд╛рдп, рд░рд╣рджрд╛рд░реА рдкреНрд░рдХреНрд░рд┐рдпреЗрдд рд╡реНрдпрддреНрдпрдп рди рдЖрдгрддрд╛ рдЕрджреНрдпрддрдирд┐рдд рдХрд░рдгреЗ рд╕реЛрдкреЗ рдЖрд╣реЗ. рд╡реНрд╣реЗрд░рд┐рдлрд╛рдпрд░ рд╡реИрдпрдХреНрддрд┐рдХрд░рд┐рддреНрдпрд╛ рдореЛрдареНрдпрд╛ рд╕рдорд╕реНрдпрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рдд рдирд╛рд╣реА, рдореА рдпреВрдЬрд░рд╕реНрдкреЗрд╕ рдХреЛрдбрдЪреНрдпрд╛ рдХрд╛рд╣реА рднрд╛рдЧрд╛рдВрд╕рд╛рдареА рд╣реЗ рдирд╛рдХрд╛рд░рдгрд╛рд░ рдирд╛рд╣реА.

рджреБрд╕рд▒реНрдпрд╛ рднрд╛рдЧрд╛рдд, рдЬрд░ рд╡рд┐рд╖рдп рдордиреЛрд░рдВрдЬрдХ рдЕрд╕реЗрд▓, рддрд░ рдЖрдореНрд╣реА рд╕рддреНрдпрд╛рдкрд┐рдд рдХреНрд▓рд╛рдпрдВрдЯ рдЖрдгрд┐ рдбрд┐рд╕реНрдХрдиреЗрдХреНрд╢рдиреНрд╕рдЪреЗ рд╕рд╛рд░рдгреА рдкреВрд░реНрдг рдХрд░реВ, рдХрд╛рдЙрдВрдЯрд░ рд▓рд╛рдЧреВ рдХрд░реВ рдЖрдгрд┐ рдлрд┐рд▓реНрдЯрд░ рд╡реНрдпрд╡рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рд╡рд╛рдкрд░рдХрд░реНрддрд╛ рд╕реНрдерд╛рди рдЙрдкрдпреБрдХреНрддрддрд╛ рд▓рд┐рд╣реВ.

рджреБрд╡реЗ:

рд╕реНрддреНрд░реЛрдд: www.habr.com

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдЬреЛрдбрд╛