рд╣рдо XDP рдкрд░ DDoS рдХреЗ рд╣рдорд▓реЛрдВ рдХреЗ рдЦрд┐рд▓рд╛рдл рд╕реБрд░рдХреНрд╖рд╛ рд▓рд┐рдЦрддреЗ рд╣реИрдВред рдкрд░рдорд╛рдгреБ рднрд╛рдЧ

EXpress рдбреЗрдЯрд╛ рдкрд╛рде (XDP) рддрдХрдиреАрдХ рдХрд░реНрдиреЗрд▓ рдиреЗрдЯрд╡рд░реНрдХ рд╕реНрдЯреИрдХ рдкрд░ рдкреИрдХреЗрдЯ рдЖрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд▓рд┐рдирдХреНрд╕ рдЗрдВрдЯрд░рдлреЗрд╕ рдкрд░ рдпрд╛рддрд╛рдпрд╛рдд рдХреА рдордирдорд╛рдиреА рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИред XDP рдХрд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧ - DDoS рд╣рдорд▓реЛрдВ (CloudFlare), рдкрд░рд┐рд╖реНрдХреГрдд рдлрд╝рд┐рд▓реНрдЯрд░, рд╕рд╛рдВрдЦреНрдпрд┐рдХреА рд╕рдВрдЧреНрд░рд╣ (Netflix) рдХреЗ рд╡рд┐рд░реБрджреНрдз рд╕реБрд░рдХреНрд╖рд╛ред XDP рдкреНрд░реЛрдЧреНрд░рд╛рдореНрд╕ рдХреЛ EBPF рд╡рд░реНрдЪреБрдЕрд▓ рдорд╢реАрди рджреНрд╡рд╛рд░рд╛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП, рдЙрдирдХреЗ рдлрд╝рд┐рд▓реНрдЯрд░ рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдЙрдирдХреЗ рдХреЛрдб рдФрд░ рдЙрдкрд▓рдмреНрдз рдХрд░реНрдиреЗрд▓ рдлрд╝рдВрдХреНрд╢рди рджреЛрдиреЛрдВ рдкрд░ рдкреНрд░рддрд┐рдмрдВрдз рд╣реИред


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


рдЗрд╕ рднрд╛рдЧ рдореЗрдВ, рд╣рдо рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдЬрд╛рдВрдЪ рдХрд░реЗрдВрдЧреЗ рдХрд┐ XDP рдлрд╝рд┐рд▓реНрдЯрд░ рдХреЛ рдХреИрд╕реЗ рдЗрдХрдЯреНрдард╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╣рдо рдкреИрдХреЗрдЯ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рд╕реНрддрд░ рдкрд░ рдкреНрд░рд╕рд┐рджреНрдз SYN рдХреБрдХреА рддрдВрддреНрд░ рдХрд╛ рдПрдХ рд╕рд░рд▓ рд╕рдВрд╕реНрдХрд░рдг рд▓рд┐рдЦреЗрдВрдЧреЗред рдЬрдмрдХрд┐ рд╣рдо "рд╢реНрд╡реЗрдд рд╕реВрдЪреА" рдирд╣реАрдВ рдмрдирд╛рдПрдВрдЧреЗ
рд╕рддреНрдпрд╛рдкрд┐рдд рдЧреНрд░рд╛рд╣рдХ, рдХрд╛рдЙрдВрдЯрд░ рд░рдЦреЗрдВ рдФрд░ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд╛ рдкреНрд░рдмрдВрдзрди рдХрд░реЗрдВ - рдкрд░реНрдпрд╛рдкреНрдд рд▓реЙрдЧред


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


рдЕрд╕реНрд╡реАрдХрд░рдгред рд▓реЗрдЦ рдХреЗ рджреМрд░рд╛рди, DDoS рд╣рдорд▓реЛрдВ рд╕реЗ repelling рдХреЗ рд▓рд┐рдП рдПрдХ рдорд┐рдиреА-рд╕рдорд╛рдзрд╛рди рд╡рд┐рдХрд╕рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ XDP рдФрд░ рдореЗрд░реЗ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдпрдерд╛рд░реНрдерд╡рд╛рджреА рдХрд╛рд░реНрдп рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдореБрдЦреНрдп рд▓рдХреНрд╖реНрдп рдкреНрд░реМрджреНрдпреЛрдЧрд┐рдХреА рд╕реЗ рдирд┐рдкрдЯрдирд╛ рд╣реИ, рдпрд╣ рдПрдХ рддреИрдпрд╛рд░-рдирд┐рд░реНрдорд┐рдд рд╕реБрд░рдХреНрд╖рд╛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЧрд╛рдЗрдб рдирд╣реАрдВ рд╣реИред рдкреНрд░рд╢рд┐рдХреНрд╖рдг рдХреЛрдб рдЕрдиреБрдХреВрд▓рд┐рдд рдирд╣реАрдВ рд╣реИ рдФрд░ рдХреБрдЫ рдмрд╛рд░реАрдХрд┐рдпреЛрдВ рдХреЛ рдЫреЛрдбрд╝ рджреЗрддрд╛ рд╣реИред


рдПрдХ рдирдЬрд╝рд░ рдореЗрдВ XDP


рдореИрдВ рдХреЗрд╡рд▓ рдореБрдЦреНрдп рдмрд┐рдВрджреБрдУрдВ рдХреЛ рд░реЗрдЦрд╛рдВрдХрд┐рдд рдХрд░реВрдВрдЧрд╛ рддрд╛рдХрд┐ рдбреЙрдХреНрдпреВрдореЗрдВрдЯреЗрд╢рди рдФрд░ рдореМрдЬреВрджрд╛ рд▓реЗрдЦреЛрдВ рдХреА рдирдХрд▓ рди рдХреА рдЬрд╛ рд╕рдХреЗред


рддреЛ, рдлрд╝рд┐рд▓реНрдЯрд░ рдХреЛрдб рдХреЛ рдХрд░реНрдиреЗрд▓ рдореЗрдВ рд▓реЛрдб рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрдирдмрд╛рдЙрдВрдб рдкреИрдХреЗрдЯ рдлрд╝рд┐рд▓реНрдЯрд░ рдХреЗ рд▓рд┐рдП рднреЗрдЬреЗ рдЬрд╛рддреЗ рд╣реИрдВред рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдлрд╝рд┐рд▓реНрдЯрд░ рдХреЛ рдПрдХ рдирд┐рд░реНрдгрдп рд▓реЗрдирд╛ рдЪрд╛рд╣рд┐рдП: рдкреИрдХреЗрдЯ рдХреЛ рдХрд░реНрдиреЗрд▓ ( XDP_PASS ) рдкрд░ рдЫреЛрдбрд╝реЗрдВ, рдкреИрдХреЗрдЯ рдХреЛ рдЫреЛрдбрд╝реЗрдВ ( XDP_DROP ) рдпрд╛ рдЗрд╕реЗ рд╡рд╛рдкрд╕ рднреЗрдЬреЗрдВ ( XDP_TX )ред рдлрд╝рд┐рд▓реНрдЯрд░ рдкреИрдХреЗрдЬ рдХреЛ рдмрджрд▓ рд╕рдХрддрд╛ рд╣реИ, рдпрд╣ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ XDP_TX рд▓рд┐рдП XDP_TX ред рдЖрдк рдкреНрд░реЛрдЧреНрд░рд╛рдо ( XDP_ABORTED ) рдХреЛ рднреА рдХреНрд░реИрд╢ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдкреИрдХреЗрдЬ рдХреЛ рдЫреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдбреАрдмрдЧрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП XDP_ABORTED assert(0) рдХрд╛ рдПрдХ рдПрдирд╛рд▓реЙрдЧ рд╣реИред


EBPF рд╡рд░реНрдЪреБрдЕрд▓ рдорд╢реАрди (рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдмрд░реНрдХрд▓реЗ рдкреИрдХреЗрдЯ рдлрд╝рд┐рд▓реНрдЯрд░) рдХреЛ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд╕рд░рд▓ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рддрд╛рдХрд┐ рдХрд░реНрдиреЗрд▓ рдпрд╣ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░ рд╕рдХреЗ рдХрд┐ рдХреЛрдб рд▓реВрдк рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдХрд┐рд╕реА рдФрд░ рдХреА рдореЗрдореЛрд░реА рдХреЛ рдиреБрдХрд╕рд╛рди рдирд╣реАрдВ рдкрд╣реБрдВрдЪрд╛рддрд╛ рд╣реИред рдкреНрд░рддрд┐рдмрдВрдзреЛрдВ рдФрд░ рдЬрд╛рдБрдЪреЛрдВ рдХреЛ рдЕрд▓рдЧ рдХрд░реЗрдВ:


  • рдирд┐рд╖рд┐рджреНрдз рдЪрдХреНрд░ (рд╡рд╛рдкрд╕ рдХреВрджреЛ)ред
  • рдбреЗрдЯрд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реНрдЯреИрдХ рд╣реИ, рд▓реЗрдХрд┐рди рдХреЛрдИ рдлрд╝рдВрдХреНрд╢рдВрд╕ (рд╕рднреА рд╕реА рдлрд╝рдВрдХреНрд╢рди рдЗрдирд▓рд╛рдЗрди рдирд╣реАрдВ рд╣реЛрдиреЗ рдЪрд╛рд╣рд┐рдП)ред
  • рд╕реНрдЯреИрдХ рдФрд░ рдкреИрдХреЗрдЯ рдмрдлрд╝рд░ рдХреЗ рдмрд╛рд╣рд░ рдореЗрдореЛрд░реА рддрдХ рдкрд╣реБрдБрдЪ рдирд┐рд╖рд┐рджреНрдз рд╣реИред
  • рдХреЛрдб рдХрд╛ рдЖрдХрд╛рд░ рд╕реАрдорд┐рдд рд╣реИ, рд▓реЗрдХрд┐рди рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ рдпрд╣ рдмрд╣реБрдд рдорд╣рддреНрд╡рдкреВрд░реНрдг рдирд╣реАрдВ рд╣реИред
  • рдХреЙрд▓ рдХреЗрд╡рд▓ рд╡рд┐рд╢реЗрд╖ рдХрд░реНрдиреЗрд▓ рдлрд╝рдВрдХреНрд╢рдВрд╕ (eBPF рд╕рд╣рд╛рдпрдХреЛрдВ) рдХреЛ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рд╣реИред

рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд╛ рдбрд┐рдЬрд╝рд╛рдЗрди рдФрд░ рд╕реНрдерд╛рдкрдирд╛ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:


  1. рд╕реНрд░реЛрдд рдХреЛрдб (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, kernel.c ) рдХреЛ EBPP рд╡рд░реНрдЪреБрдЕрд▓ рдорд╢реАрди рдХреЗ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреЗ рддрд╣рдд рдСрдмреНрдЬреЗрдХреНрдЯ ( kernel.o ) рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЕрдХреНрдЯреВрдмрд░ 2019 рддрдХ, EBPF рдореЗрдВ рд╕рдВрдХрд▓рди рдХреНрд▓реИрдВрдЧ рджреНрд╡рд╛рд░рд╛ рд╕рдорд░реНрдерд┐рдд рд╣реИ рдФрд░ рдЬреАрд╕реАрд╕реА 10.1 рдореЗрдВ рд╡рд╛рджрд╛ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
  2. рдпрджрд┐ рдЗрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛрдб рдореЗрдВ рдХрд░реНрдиреЗрд▓ рд╕реНрдЯреНрд░рдХреНрдЪрд░реНрд╕ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЯреЗрдмрд▓ рдФрд░ рдХрд╛рдЙрдВрдЯрд░) рдХреЗ рд▓рд┐рдП рдХреЙрд▓ рдЖрддреЗ рд╣реИрдВ, рддреЛ рдЙрдирдХреЗ рдЖрдИрдбреА рдХреЗ рдмрдЬрд╛рдп рд╢реВрдиреНрдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рдд рдРрд╕реЗ рдХреЛрдб рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдХрд░реНрдиреЗрд▓ рдореЗрдВ рд▓реЛрдб рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдЖрдкрдХреЛ рдХрд░реНрдиреЗрд▓ рдХреЙрд▓ (рд▓рд┐рдВрдХ рдХреЛрдб) рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдмрдирд╛рдИ рдЧрдИ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╡рд╕реНрддреБрдУрдВ рдХреА рдЖрдИрдбреА рдХреЗ рд╕рд╛рде рдЗрди рд╢реВрдиреНрдп рдХреЛ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЖрдк рдмрд╛рд╣рд░реА рдЙрдкрдпреЛрдЧрд┐рддрд╛рдУрдВ рдХреЗ рд╕рд╛рде рдРрд╕рд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╛ рдЖрдк рдПрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдлрд┐рд▓реНрдЯрд░ рдХреЛ рд▓рд┐рдВрдХ рдФрд░ рд▓реЛрдб рдХрд░реЗрдЧрд╛ред
  3. рдХрд░реНрдиреЗрд▓ рд▓реЛрдб рдХрд┐рдП рдЧрдП рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреА рдкреБрд╖реНрдЯрд┐ рдХрд░рддрд╛ рд╣реИред рдкреИрдХреЗрдЯ рдФрд░ рд╕реНрдЯреИрдХ рдХреА рд╕реАрдорд╛рдУрдВ рд╕реЗ рдкрд░реЗ рдЫреЛрд░реЛрдВ рдФрд░ рдЕрдиреБрдкрд╕реНрдерд┐рддрд┐ рдХреА рдЕрдиреБрдкрд╕реНрдерд┐рддрд┐ рдХреА рдЬрд╛рдВрдЪ рдХреА рдЬрд╛рддреА рд╣реИред рдпрджрд┐ рд╕рддреНрдпрд╛рдкрдирдХрд░реНрддрд╛ рдпрд╣ рд╕рд╛рдмрд┐рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдХреЛрдб рд╕рд╣реА рд╣реИ, рддреЛ рдХрд╛рд░реНрдпрдХреНрд░рдо рдЕрд╕реНрд╡реАрдХрд╛рд░ рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ - рдЖрдкрдХреЛ рдЗрд╕реЗ рдЦреБрд╢ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
  4. рд╕рдлрд▓ рд╕рддреНрдпрд╛рдкрди рдХреЗ рдмрд╛рдж, рдХрд░реНрдиреЗрд▓ eBPF рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛрдб рдХреЛ рд╕рд┐рд╕реНрдЯрдо рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдорд╢реАрди рдХреЛрдб (рдмрд╕-рдЗрди-рдЯрд╛рдЗрдо) рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд рдХрд░рддрд╛ рд╣реИред
  5. рдХрд╛рд░реНрдпрдХреНрд░рдо рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╕реЗ рдЬреБрдбрд╝рддрд╛ рд╣реИ рдФрд░ рдкреИрдХреЗрдЯ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░рддрд╛ рд╣реИред

рдЪреВрдВрдХрд┐ XDP рдХрд░реНрдиреЗрд▓ рдореЗрдВ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЯреНрд░реЗрд╕рд┐рдВрдЧ рд▓реЙрдЧреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдбрд┐рдмрдЧрд┐рдВрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдкреИрдХреЗрдЯ рджреНрд╡рд╛рд░рд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдлрд╝рд┐рд▓реНрдЯрд░ рдпрд╛ рдЬреЗрдирд░реЗрдЯ рдХрд░рддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, eBPF рд╕рд┐рд╕реНрдЯрдо рдХреЗ рд▓рд┐рдП рд▓реЛрдб рдХрд┐рдП рдЧрдП рдХреЛрдб рдХреЗ рд▓рд┐рдП рд╕реБрд░рдХреНрд╖рд╛ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЖрдк XDP рдХреЗ рд╕рд╛рде рд╕реАрдзреЗ рд╕реНрдерд╛рдиреАрдп рд▓рд┐рдирдХреНрд╕ рдкрд░ рдкреНрд░рдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


рдкрд░реНрдпрд╛рд╡рд░рдг рдХреА рддреИрдпрд╛рд░реА


рд╕рднрд╛


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


  1. LLVM bytecode ( clang -emit-llvm ) рдореЗрдВ C рдХреЛрдб рд╕рдВрдХрд▓рд┐рдд рдХрд░реЗрдВред
  2. рдмрд╛рдЗрдЯрдХреЛрдб рдХреЛ eBPF рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЛрдб ( llc -march=bpf -filetype=obj ) рдореЗрдВ llc -march=bpf -filetype=obj ред

рдлрд╝рд┐рд▓реНрдЯрд░ рд▓рд┐рдЦрддреЗ рд╕рдордп, рдХрд░реНрдиреЗрд▓ рдкрд░реАрдХреНрд╖рдгреЛрдВ рд╕реЗ рд╕рд╣рд╛рдпрдХ рдХрд╛рд░реНрдпреЛрдВ рдФрд░ рдореИрдХреНрд░реЛ рдХреЗ рд╕рд╛рде рдХреБрдЫ рдлрд╛рдЗрд▓реЗрдВ рдХрд╛рдо рдореЗрдВ рдЖрддреА рд╣реИрдВред рдпрд╣ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ рд╡реЗ рдХрд░реНрдиреЗрд▓ рд╕рдВрд╕реНрдХрд░рдг ( KVER ) рд╕реЗ рдореЗрд▓ рдЦрд╛рддреЗ рд╣реЛрдВред рдЙрдиреНрд╣реЗрдВ helpers/ рдореЗрдВ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░реЗрдВ 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 рдореЗрдВ рдХрд░реНрдиреЗрд▓ рд╣реЗрдбрд░, KDIR - рд╕рд┐рд╕реНрдЯрдо рдХреА рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рд╢рд╛рдорд┐рд▓ рд╣реИред рд╡рд┐рддрд░рдг рдХреЗ рдмреАрдЪ рдкрде рдФрд░ рдЙрдкрдХрд░рдг рдереЛрдбрд╝рд╛ рднрд┐рдиреНрди рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред


рдбреЗрдмрд┐рдпрди 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 рд╣реЗрдбрд░ (рдпреВрдЬрд░рд╕реНрдкреЗрд╕ 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 рдХреЗ рд╕рд╛рде рдкреВрд░реНрдг рд▓рд┐рдирдХреНрд╕ рдбрд┐рд╡рд╛рдЗрд╕ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред


рд╡реЗрде (рд╡рд░реНрдЪреБрдЕрд▓ рдИрдерд░рдиреЗрдЯ) рдЬреИрд╕реЗ рдбрд┐рд╡рд╛рдЗрд╕ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рд╣реИрдВ: рд╡реЗ рдПрдХ рдЬреЛрдбрд╝реА рд╡рд░реНрдЪреБрдЕрд▓ рдиреЗрдЯрд╡рд░реНрдХ рдЗрдВрдЯрд░рдлреЗрд╕ рд╣реИрдВ рдЬреЛ рд╕реАрдзреЗ рдПрдХ рджреВрд╕рд░реЗ рд╕реЗ "рдХрдиреЗрдХреНрдЯ" рд╣реЛрддреЗ рд╣реИрдВред рдЖрдк рдЙрдиреНрд╣реЗрдВ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ (рдЗрд╕ рдЕрдиреБрднрд╛рдЧ рдореЗрдВ, рд╕рднреА ip рдХрдорд╛рдВрдб рдХреЛ root рд░реВрдк рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ 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 рд▓реЗ xdp-remote ред


 ip netns add xdp-test ip link set dev xdp-remote netns xdp-test 

рдлрд┐рд░ xdp-test рдореЗрдВ рдЪрд▓рдиреЗ рд╡рд╛рд▓реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ xdp-test рдХреЛ рдирд╣реАрдВ xdp-local (рдпрд╣ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдиреЗрдЯрд╡рдиреНрд╕ рдореЗрдВ рд░рд╣реЗрдЧреА) рдФрд░ 192.0.2.1 рдХреЛ рдХреЗрд╡рд▓ рдПрдХ рдкреИрдХреЗрдЯ рднреЗрдЬрддреЗ рд╕рдордп рдЗрд╕реЗ xdp-remote рдорд╛рдзреНрдпрдо рд╕реЗ xdp-remote , рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ 192.0.2.0/ рдореЗрдВ рдПрдХрдорд╛рддреНрд░ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╣реИ 24 рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдЙрдкрд▓рдмреНрдз рд╣реИред рдпрд╣ рд╡рд┐рдкрд░реАрдд рджрд┐рд╢рд╛ рдореЗрдВ рднреА рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред


рдиреЗрдЯрдиреНрд╕ рдХреЗ рдмреАрдЪ рдЬрд╛рдиреЗ рдкрд░, рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдбреНрд░реЙрдк рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдкрддрд╛ рдЦреЛ рджреЗрддрд╛ рд╣реИред Netns рдореЗрдВ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ ip ... рдЪрд▓рд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ ip ... рдЗрд╕ ip netns exec рдХрдорд╛рдВрдб рдиреЗрдорд╕реНрдкреЗрд╕ 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 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() рдлрд╝рдВрдХреНрд╢рди bpf_trace_printk() рд╕рдорд╛рди рд╣реИ, рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рддреАрди рддрд░реНрдХреЛрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ, рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЛ рдЫреЛрдбрд╝рдХрд░, рдФрд░ рдХреНрд╡рд╛рд▓реАрдлрд╛рдпрд░ рдХреА рдПрдХ рд╕реАрдорд┐рдд рд╕реВрдЪреАред bpf_printk() рдореИрдХреНрд░реЛ рдХреЙрд▓ рдХреЛ рд╕рд░рд▓ рдХрд░рддрд╛ рд╣реИред


  SEC("prog") int xdp_main(struct xdp_md* ctx) { + bpf_printk("got packet: %p\n", 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 <...> 

рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рдИрдПрдХреНрд╕рдкреАрдПрдл рдХрд╛рд░реНрдпрдХреНрд░рдореЛрдВ рдореЗрдВ рдбреЗрдЯрд╛ рдЦрдВрдб рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдкреНрд░рд╛рд░реВрдк рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ рдПрдиреНрдХреЛрдб рдХрд░рдиреЗ рдХрд╛ рдПрдХрдорд╛рддреНрд░ рддрд░реАрдХрд╛ рд╡реАрдПрдо рдХрдорд╛рдВрдбреЛрдВ рдХреЗ рддрддреНрдХрд╛рд▓ рддрд░реНрдХреЛрдВ рдХреЗ рд╕рд╛рде рд╣реИ:


 $ python -c "import binascii; print(bytes(reversed(binascii.unhexlify('0a7025203a74656b63617020746f67'))))" b'got packet: %p\n' 

рдЗрд╕ рдХрд╛рд░рдг рд╕реЗ, рдбрд┐рдмрдЧ рдЖрдЙрдЯрдкреБрдЯ рдкрд░рд┐рдгрд╛рдореА рдХреЛрдб рдХреЛ рдмрд╣реБрдд рдмрдврд╝рд╛рддрд╛ рд╣реИред


XDP рдкреИрдХреЗрдЬ рднреЗрдЬрдирд╛


рдЪрд▓реЛ рдлрд╝рд┐рд▓реНрдЯрд░ рдХреЛ рдмрджрд▓рддреЗ рд╣реИрдВ: рдЗрд╕реЗ рд╕рднреА рдЖрдиреЗ рд╡рд╛рд▓реЗ рдкреИрдХреЗрдЯ рд╡рд╛рдкрд╕ рднреЗрдЬрдиреЗ рджреЗрдВред рдпрд╣ рдиреЗрдЯрд╡рд░реНрдХ рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ рдЧрд▓рдд рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рд╣реЗрдбрд░ рдореЗрдВ рдкрддреЛрдВ рдХреЛ рдмрджрд▓рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдЕрдм рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ рдХрд╛рдо рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИред


  bpf_printk("got packet: %p\n", ctx); - return XDP_PASS; + return XDP_TX; } 

xdp-remote рдкрд░ tcpdump рдЪрд▓рд╛рдПрдБред рдпрд╣ рд╕рдорд╛рди рдЖрдЙрдЯрдЧреЛрдЗрдВрдЧ рдФрд░ рдЗрдирдХрдорд┐рдВрдЧ ICMP рдЗрдХреЛ рд░рд┐рдХреНрд╡реЗрд╕реНрдЯ рджрд┐рдЦрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ ICMP рдЗрдХреЛ рд░рд┐рдкреНрд▓рд╛рдИ рджрд┐рдЦрд╛рдирд╛ рдмрдВрдж рдХрд░ рджреЗрдирд╛ рдЪрд╛рд╣рд┐рдПред рд▓реЗрдХрд┐рди рджрд┐рдЦрд╛ рдирд╣реАрдВред рдпрд╣ рдкрддрд╛ рдЪрд▓рд╛ рд╣реИ рдХрд┐ XDP_TX рд▓рд┐рдП xdp-local рдкрд░ рдПрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдореЗрдВ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП xdp-local рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХрд┐ xdp-remote рдЗрдВрдЯрд░рдлрд╝реЗрд╕ xdp-remote рдЗрдВрдЯрд░рдлрд╝реЗрд╕ xdp-remote , рднрд▓реЗ рд╣реА рд╡рд╣ рдЦрд╛рд▓реА рд╣реЛ, рдФрд░ рдЙрд╕реЗ рдЙрдард╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред


рдореБрдЭреЗ рдХреИрд╕реЗ рдкрддрд╛ рдЪрд▓рд╛?

рд╕рдВрдкреВрд░реНрдг рдИрд╡реЗрдВрдЯ рддрдВрддреНрд░, рд╡реИрд╕реЗ, рдПрдХ рд╣реА рд╡рд░реНрдЪреБрдЕрд▓ рдорд╢реАрди рдХреЗ рдЙрдкрдпреЛрдЧ рд╕реЗ рдХрд░реНрдиреЗрд▓ рдореЗрдВ рдкреИрдХреЗрдЬ рдкрде рдХреЛ рдЯреНрд░реЗрд╕ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдорд┐рд▓рддреА рд╣реИ, рдЕрд░реНрдерд╛рдд, 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_flush_bq() рд╕реЗ рдПрдХ рддреНрд░реБрдЯрд┐ рдХреЛрдб рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ, рдЬрд╣рд╛рдВ рд╣рдо ENXIO рджреНрд╡рд╛рд░рд╛ ENXIO рдФрд░ рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдкрд╛рддреЗ рд╣реИрдВред


xdp_dummy.c рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдиреНрдпреВрдирддрдо рдлрд╝рд┐рд▓реНрдЯрд░ ( XDP_PASS ) рдХреЛ рдкреБрдирд░реНрд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ, рдЗрд╕реЗ Makefile рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ, рдЗрд╕реЗ xdp-remote рд╕рдВрд▓рдЧреНрди рдХрд░реЗрдВ:


 ip netns exec remote \ ip link set dev int xdp object dummy.o 

рдЕрдм tcpdump рджрд┐рдЦрд╛рддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдЕрдкреЗрдХреНрд╖рд┐рдд рд╣реИ:


 62:57:8e:70:44:64 > 26:0e:25:37:8f:96, ethertype IPv4 (0x0800), length 98: (tos 0x0, ttl 64, id 13762, offset 0, flags [DF], proto ICMP (1), length 84) 192.0.2.2 > 192.0.2.1: ICMP echo request, id 46966, seq 1, length 64 62:57:8e:70:44:64 > 26:0e:25:37:8f:96, ethertype IPv4 (0x0800), length 98: (tos 0x0, ttl 64, id 13762, offset 0, flags [DF], proto ICMP (1), length 84) 192.0.2.2 > 192.0.2.1: ICMP echo request, id 46966, seq 1, length 64 

рдпрджрд┐ рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдХреЗрд╡рд▓ ARP рджрд┐рдЦрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдЖрдкрдХреЛ рдлрд╝рд┐рд▓реНрдЯрд░ рд╣рдЯрд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ (рдпрд╣ sudo ./stand detach рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ), ping рдкреНрд░рд╛рд░рдВрдн рдХрд░реЗрдВ, рдлрд┐рд░ рдлрд╝рд┐рд▓реНрдЯрд░ рд╕реЗрдЯ рдХрд░реЗрдВ рдФрд░ рдлрд┐рд░ рд╕реЗ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ XDP_TX рдлрд╝рд┐рд▓реНрдЯрд░ ARP рдФрд░ рдпрджрд┐ рд╕реНрдЯреИрдХ рджреЛрдиреЛрдВ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддрд╛ рд╣реИ
xdp-test рдиреЗрдорд╕реНрдкреЗрд╕ рдореИрдХ рдПрдбреНрд░реЗрд╕ 192.0.2.1 рдХреЛ "рднреВрд▓" рдХрд░рдиреЗ рдореЗрдВ рдХрд╛рдордпрд╛рдм рд░рд╣рд╛, рдпрд╣ рдЗрд╕ рдЖрдИрдкреА рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдирд╣реАрдВ рд╣реЛрдЧрд╛ред


рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдмрдпрд╛рди


рдЖрдЗрдП рдмрддрд╛рдП рдЧрдП рдХрд╛рд░реНрдп рдкрд░ рдЖрдЧреЗ рдмрдврд╝реЗрдВ: XDP рдкрд░ SYN рдХреБрдХреАрдЬрд╝ рддрдВрддреНрд░ рд▓рд┐рдЦреЗрдВред


рдЕрдм рддрдХ, SYN рдмрд╛рдврд╝ рдПрдХ рд▓реЛрдХрдкреНрд░рд┐рдп DDoS рд╣рдорд▓рд╛ рдмрдирд╛ рд╣реБрдЖ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рд╕рд╛рд░ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИред рдХрдиреЗрдХреНрд╢рди (рдЯреАрд╕реАрдкреА рд╣реИрдВрдбрд╢реЗрдХ) рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддреЗ рд╕рдордп, рд╕рд░реНрд╡рд░ рдПрдХ SYN рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИ, рднрд╡рд┐рд╖реНрдп рдХреЗ рдХрдиреЗрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рд╕рдВрд╕рд╛рдзрди рдЖрд╡рдВрдЯрд┐рдд рдХрд░рддрд╛ рд╣реИ, рдПрдХ SYNACK рдкреИрдХреЗрдЯ рдХреЗ рд╕рд╛рде рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХрд░рддрд╛ рд╣реИ, рдФрд░ ACK рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рддрд╛ рд╣реИред рд╣рдорд▓рд╛рд╡рд░ рдмрд╕ рдорд▓реНрдЯреА-рд╣рдЬрд╛рд░ рдмреЙрдЯрдиреЗрдЯ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдореЗрдЬрдмрд╛рди рд╕реЗ рд╣рдЬрд╛рд░реЛрдВ рдкреНрд░рддрд┐ рд╕реЗрдХрдВрдб рдХреА рдорд╛рддреНрд░рд╛ рдореЗрдВ рдирдХрд▓реА рдкрддреЗ рд╕реЗ SYN рдкреИрдХреЗрдЯ рднреЗрдЬрддрд╛ рд╣реИред рд╕рд░реНрд╡рд░ рдХреЛ рдкреИрдХреЗрдЯ рдХреЗ рдЖрдЧрдорди рдкрд░ рддреБрд░рдВрдд рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЛ рдЖрд╡рдВрдЯрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдПрдХ рдмрдбрд╝реЗ рд╕рдордп рд╕рдорд╛рдкреНрдд рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдореЗрдореЛрд░реА рдпрд╛ рд╕реАрдорд╛ рд╕рдорд╛рдкреНрдд рд╣реЛ рдЬрд╛рддреА рд╣реИ, рдирдП рдХрдиреЗрдХреНрд╢рди рд╕реНрд╡реАрдХрд╛рд░ рдирд╣реАрдВ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рд╕реЗрд╡рд╛ рдЕрдиреБрдкрд▓рдмреНрдз рд╣реИред


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


SYN рдХреБрдХреА рдХреЛ рд▓рдВрдмреЗ рд╕рдордп рддрдХ рд▓рд┐рдирдХреНрд╕ рдХрд░реНрдиреЗрд▓ рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЕрдЧрд░ SYN рдмрд╣реБрдд рдЬрд▓реНрджреА рдФрд░ рдереЛрдХ рдореЗрдВ рдЖ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рдпрд╣ рд╕реНрд╡рддрдГ рд╣реА рдЪрд╛рд▓реВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред


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

рдЯреАрд╕реАрдкреА рдмрд╛рдЗрдЯреНрд╕ рдХреА рдПрдХ рдзрд╛рд░рд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдбреЗрдЯрд╛ рдЯреНрд░рд╛рдВрд╕рдлрд░ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, HTTP рдЕрдиреБрд░реЛрдз рдЯреАрд╕реАрдкреА рдкрд░ рднреЗрдЬреЗ рдЬрд╛рддреЗ рд╣реИрдВред рдкреИрдХреЗрдЯ рдореЗрдВ рдЯреБрдХрдбрд╝реЛрдВ рдореЗрдВ рдзрд╛рд░рд╛ рдХрд╛ рд╕рдВрдЪрд╛рд░ рд╣реЛрддрд╛ рд╣реИред рд╕рднреА рдЯреАрд╕реАрдкреА рдкреИрдХреЗрдЯ рдореЗрдВ рддрд╛рд░реНрдХрд┐рдХ рдЭрдВрдбреЗ рдФрд░ 32-рдмрд┐рдЯ рдЕрдиреБрдХреНрд░рдо рд╕рдВрдЦреНрдпрд╛ рд╣реЛрддреА рд╣реИ:


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


  • рдЕрдиреБрдХреНрд░рдо рд╕рдВрдЦреНрдпрд╛ (seqnum) рдЗрд╕ рдкреИрдХреЗрдЯ рдореЗрдВ рдкреНрд░рд╕рд╛рд░рд┐рдд рд╣реЛрдиреЗ рд╡рд╛рд▓реА рдкрд╣рд▓реА рдмрд╛рдЗрдЯ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рд╕реНрдЯреНрд░реАрдо рдореЗрдВ рдСрдлрд╕реЗрдЯ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдбреЗрдЯрд╛ рдХреЗ X рдмрд╛рдЗрдЯреНрд╕ рд╡рд╛рд▓реЗ рдкрд╣рд▓реЗ рдкреИрдХреЗрдЯ рдореЗрдВ рдпрд╣ рд╕рдВрдЦреНрдпрд╛ N рдереА, рддреЛ рдЕрдЧрд▓реЗ рдкреИрдХреЗрдЯ рдореЗрдВ рдирдП рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдпрд╣ N + X рд╣реЛрдЧрд╛ред рдХрдиреЗрдХреНрд╢рди рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ, рдкреНрд░рддреНрдпреЗрдХ рдкрдХреНрд╖ рдЗрд╕ рд╕рдВрдЦреНрдпрд╛ рдХрд╛ рдЪрдпрди рдордирдорд╛рдиреЗ рдврдВрдЧ рд╕реЗ рдХрд░рддрд╛ рд╣реИред


  • рдкрд╛рд╡рддреА рд╕рдВрдЦреНрдпрд╛ (acknum) - seqnum рдХреЗ рд╕рдорд╛рди рдСрдлрд╕реЗрдЯ, рд▓реЗрдХрд┐рди рдкреНрд░реЗрд╖рд┐рдд рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдмрд╛рдЗрдЯреНрд╕ рдХреА рд╕рдВрдЦреНрдпрд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдкреНрд░рд╛рдкреНрддрдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛ рдкрд╣рд▓реЗ рдмрд╛рдЗрдЯ рдХреА рд╕рдВрдЦреНрдпрд╛ рдЬреЛ рдкреНрд░реЗрд╖рдХ рдиреЗ рдирд╣реАрдВ рджреЗрдЦреА рдереАред



рдХрдиреЗрдХреНрд╢рди рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ, рдкрд╛рд░реНрдЯрд┐рдпреЛрдВ рдХреЛ seqnum рдФрд░ acknum рдкрд░ рд╕рд╣рдордд рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдЧреНрд░рд╛рд╣рдХ рдЕрдкрдиреЗ seqnum = X рд╕рд╛рде рдПрдХ SYN рдкреИрдХреЗрдЯ рднреЗрдЬрддрд╛ рд╣реИред рд╕рд░реНрд╡рд░ рдПрдХ SYNACK рдкреИрдХреЗрдЯ рдХреЗ рд╕рд╛рде рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХрд░рддрд╛ рд╣реИ, рдЬрд╣рд╛рдВ рд╡рд╣ рдЕрдкрдирд╛ seqnum = Y рд▓рд┐рдЦрддрд╛ рд╣реИ рдФрд░ acknum = X + 1 рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИред рдЧреНрд░рд╛рд╣рдХ рдПрдХ рдПрд╕реАрдХреЗ рдкреИрдХреЗрдЯ рдХреЗ рд╕рд╛рде SYNACK рдкрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреЗрддрд╛ рд╣реИ, рдЬрд╣рд╛рдВ seqnum = X + 1 , acknum = Y + 1 ред рдЙрд╕рдХреЗ рдмрд╛рдж, рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдбреЗрдЯрд╛ рд╕реНрдерд╛рдирд╛рдВрддрд░рдг рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИред


рдпрджрд┐ рд╡рд╛рд░реНрддрд╛рдХрд╛рд░ рдкреИрдХреЗрдЯ рдХреА рдкреНрд░рд╛рдкреНрддрд┐ рдХреА рдкреБрд╖реНрдЯрд┐ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдЯреАрд╕реАрдкреА рдЯрд╛рдЗрдордЖрдЙрдЯ рджреНрд╡рд╛рд░рд╛ рдЗрд╕реЗ рдлрд┐рд░ рд╕реЗ рднреЗрдЬрддрд╛ рд╣реИред


SYN рдХреБрдХреАрдЬрд╝ рд╣рдореЗрд╢рд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХреНрдпреЛрдВ рдирд╣реАрдВ рдХреА рдЬрд╛рддреА рд╣реИрдВ?

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


рдкреИрдХреЗрдЬ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ, рдПрдХ XDP рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛ рдирд┐рдореНрди рдХрд╛рд░реНрдп рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП:


  • SYN рдкрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдХреА рдХреЗ рд╕рд╛рде SYNACK;
  • ACK RST (рдбрд┐рд╕реНрдХрдиреЗрдХреНрдЯ) рдХрд╛ рдЬрд╡рд╛рдм;
  • рдЕрдиреНрдп рдкреИрдХреЗрдЯ рддреНрдпрд╛рдЧреЗрдВред

рдкреИрдХреЗрдЬ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреЗ рд╕рд╛рде рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдЫрджреНрдордХреЛрдб:


    Ethernet,  .    IPv4,  .     , (*)    ,  .    TCP,  . (**)   SYN,  SYN-ACK  cookie.   ACK,   acknum   cookie,  .      N  . (*)  RST. (**)     . 

рдПрдХ (*) рдЙрди рдмрд┐рдВрджреБрдУрдВ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╕рд┐рд╕реНрдЯрдо рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП - рдкрд╣рд▓реЗ рдЪрд░рдг рдореЗрдВ, рдЖрдк рдЙрдирдХреЗ рдмрд┐рдирд╛ рдмрд╕ рдПрдХ рдЯреАрд╕реАрдкреА рд╣реИрдВрдбрд╢реЗрдХ рдХреЛ SYN рдХреБрдХреА рдХреА рдкреАрдврд╝реА рдХреЗ рд╕рд╛рде seqnum рдХреЗ рд░реВрдк рдореЗрдВ рд▓рд╛рдЧреВ рдХрд░рдХреЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


рдЬрдЧрд╣ (**) , рдЬрдмрдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдореЗрдЬ рдирд╣реАрдВ рд╣реИ, рд╣рдо рдкреИрдХреЗрдЯ рдХреЛ рдЫреЛрдбрд╝ рджреЗрдВрдЧреЗред


рдЯреАрд╕реАрдкреА рд╣рд╛рде рдорд┐рд▓рд╛рдирд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди


рдкреИрдХреЗрдЬ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░реЗрдВ рдФрд░ рдХреЛрдб рдХреЛ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░реЗрдВ


рд╣рдореЗрдВ рдиреЗрдЯрд╡рд░реНрдХ рд╣реЗрдбрд░ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ: рдИрдерд░рдиреЗрдЯ ( uapi/linux/if_ether.h ), IPv4 ( uapi/linux/ip.h ) рдФрд░ TCP ( uapi/linux/tcp.h )ред рдкрд┐рдЫрд▓реЗ рдПрдХ рдореИрдВ atomic64_t рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рдХрд╛рд░рдг рдХрдиреЗрдХреНрдЯ рдирд╣реАрдВ рдХрд░ рд╕рдХрд╛, рдореБрдЭреЗ рдЖрд╡рд╢реНрдпрдХ рдкрд░рд┐рднрд╛рд╖рд╛рдУрдВ рдХреЛ рдХреЛрдб рдореЗрдВ рдХреЙрдкреА рдХрд░рдирд╛ рдкрдбрд╝рд╛ред


рдкрдардиреАрдпрддрд╛ рдХреЗ рд▓рд┐рдП рд╕реА рдореЗрдВ рдЖрд╡рдВрдЯрд┐рдд рдХрд┐рдП рдЧрдП рд╕рднреА рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдХреЙрд▓ рдХреЗ рд╕реНрдерд╛рди рдкрд░ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдХреНрдпреЛрдВрдХрд┐ рдХрд░реНрдиреЗрд▓ рдореЗрдВ рдИрдмреАрдкреАрдПрдл рд╕рддреНрдпрд╛рдкрдирдХрд░реНрддрд╛ рд╕рдВрдХреНрд░рдордг рдХреЛ рд╡рд╛рдкрд╕ рд░реЛрдХ рджреЗрддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рдд, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд▓реВрдк рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ред


 #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 рдХреЛ рдЙрддреНрддрд░ рджреЗрдВ


рдЗрд╕ рд╕реНрддрд░ рдкрд░ рд▓рдХреНрд╖реНрдп рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд seqnum рд╕рд╛рде рдПрдХ рд╕рд╣реА 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 рдХрд░реНрдиреЗрд▓ рдХреЛ рдРрд╕реА рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рдереАред рд╢рд╛рдпрдж рд╕рдВрдХрд▓рдХ рдиреЗ рд╕реНрдерд╛рдиреАрдп рдЪрд░ рдХреЛ рдХреНрд╖реЗрддреНрд░ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЕрд▓рдЧ рддрд░реАрдХреЗ рд╕реЗ рдПрдХреНрд╕реЗрд╕ рдХрд┐рдпрд╛ред Moral - рд╕рд░рд▓реАрдХреГрдд рдХреЛрдб рдмрд╣реБрдд рд╕рд╛рд░реЗ рдШреЛрдВрд╕рд▓реЗ рдХреЗ рд╢рд┐рдХрд╛рд░ рдореЗрдВ рдорджрдж рдХрд░ рд╕рдХрддрд╛ рд╣реИред


рд╕рддреНрдпрд╛рдкрдирдХрд░реНрддрд╛ рдХреЗ рд╕рдореНрдорд╛рди рдореЗрдВ рд▓рдВрдмрд╛рдИ рдХреА рдЖрдЧреЗ рдХреА рдирд┐рдпрдорд┐рдд рдЬрд╛рдБрдЪ; рдиреАрдЪреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ 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; 

рдЯреАрд╕реАрдкреА рдкреЛрд░реНрдЯ, рдЖрдИрдкреА рдПрдбреНрд░реЗрд╕ рдФрд░ рдореИрдХ рдПрдбреНрд░реЗрд╕ рд╕реНрд╡реИрдк рдХрд░реЗрдВред рдорд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп 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); 

рдЪреЗрдХрд╕рдо рдкреБрдирд░реНрдЧрдгрдирд╛


рдЖрдИрдкреАрд╡реА 4 рдФрд░ рдЯреАрд╕реАрдкреА рдЪреЗрдХрд╕рдо рдХреЛ рд╣реЗрдбрд░ рдореЗрдВ рд╕рднреА 16-рдмрд┐рдЯ рд╢рдмреНрджреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдФрд░ рд╣реЗрдбрд░ рдХрд╛ рдЖрдХрд╛рд░ рдЙрди рдореЗрдВ рд▓рд┐рдЦрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рдд рд╕рдВрдХрд▓рди рдХреЗ рд╕рдордп рдпрд╣ рдЕрдЬреНрдЮрд╛рдд рд╣реИред рдпрд╣ рдПрдХ рд╕рдорд╕реНрдпрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рд╕рддреНрдпрд╛рдкрдирдХрд░реНрддрд╛ рдПрдХ рдирд┐рдпрдорд┐рдд рд╕реАрдорд╛ рдХреЛ рдПрдХ рдЪрд░ рд╕реАрдорд╛ рдкрд░ рдирд╣реАрдВ рдЫреЛрдбрд╝реЗрдВрдЧреЗред рд▓реЗрдХрд┐рди рд╣реЗрдбрд░ рдХрд╛ рдЖрдХрд╛рд░ рд╕реАрдорд┐рдд рд╣реИ: рдкреНрд░рддреНрдпреЗрдХ рдХреЛ 64 рдмрд╛рдЗрдЯреНрд╕ рддрдХред рдЖрдк рдирд┐рд╢реНрдЪрд┐рдд рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рд▓реВрдк рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рдХрд┐ рд╕рдордп рд╕реЗ рдкрд╣рд▓реЗ рд╕рдорд╛рдкреНрдд рд╣реЛ рд╕рдХрддрд╛ рд╣реИред


рдореИрдВ рдиреЛрдЯ рдХрд░рддрд╛ рд╣реВрдВ рдХрд┐ RFC 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() 32- 16- , RFC 791.


TCP


netcat , ACK, Linux 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 . , , . Linux, , SipHash, XDP .


TODO, :


  • XDP- cookie_seed ( ) , , .


  • SYN cookie 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 flood , ACK flood, :


 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 kernel bypass. , XDP , , , . , userspace-.


, , , userspace- .


рд╕рдВрджрд░реНрдн:


Source: https://habr.com/ru/post/hi473286/


All Articles