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

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

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

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

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

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

рдПрдХреНрд╕рдбреАрдкреА рдХрд╛ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдЕрд╡рд▓реЛрдХрди

рдореИрдВ рдХреЗрд╡рд▓ рдореБрдЦреНрдп рдмрд┐рдВрджреБ рдмрддрд╛рдКрдВрдЧрд╛ рддрд╛рдХрд┐ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рдФрд░ рдореМрдЬреВрджрд╛ рд▓реЗрдЦреЛрдВ рдХреА рдирдХрд▓ рди рд╣реЛред

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

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

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

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

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

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

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

рд╕рднрд╛

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

  1. рд╕реА рдХреЛрдб рдХреЛ рдПрд▓рдПрд▓рд╡реАрдПрдо рдмрд╛рдЗрдЯрдХреЛрдб рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд рдХрд░реЗрдВ (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__ рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдпреВрдПрдкреАрдЖрдИ (рдпреВрдЬрд░рд╕реНрдкреЗрд╕ рдПрдкреАрдЖрдИ) рд╣реЗрдбрд░ рдХреЛ рдХрд░реНрдиреЗрд▓ рдХреЛрдб рдХреЗ рд▓рд┐рдП рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд░реНрдиреЗрд▓ рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛрддрд╛ рд╣реИред

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

ip link add xdp-remote type veth peer name xdp-local

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

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

рдЖрдЗрдП рдПрдХ рдирдпрд╛ рдиреЗрдорд╕реНрдкреЗрд╕ рдмрдирд╛рдПрдВ xdp-test рдФрд░ рд╡рд╣рд╛рдВ рдЪрд▓реЗ рдЬрд╛рдУ xdp-remote.

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

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

рдиреЗрдЯрдПрди рдХреЗ рдмреАрдЪ рдЪрд▓рддреЗ рд╕рдордп, рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдиреАрдЪреЗ рдЪрд▓рд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдкрддрд╛ рдЦреЛ рджреЗрддрд╛ рд╣реИред рдиреЗрдЯрдиреНрд╕ рдореЗрдВ рдПрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдЪрд▓рд╛рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ ip ... рдЗрд╕ рдХрдорд╛рдВрдб рдиреЗрдорд╕реНрдкреЗрд╕ рдореЗрдВ ip netns exec:

ip netns exec xdp-test 
    ip address add 192.0.2.2/24 dev xdp-remote
ip netns exec xdp-test 
    ip link set xdp-remote up

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╣ рд╕реЗрдЯрд┐рдВрдЧ рд╕реЗ рдЕрд▓рдЧ рдирд╣реАрдВ рд╣реИ xdp-local рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдирд╛рдорд╕реНрдерд╛рди рдореЗрдВ:

    ip address add 192.0.2.1/24 dev xdp-local
    ip link set xdp-local up

рдЕрдЧрд░ рдЪрд▓рд╛рдУ tcpdump -tnevi xdp-local, рдЖрдк рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдкреИрдХреЗрдЯ рдХрд╣рд╛рдВ рд╕реЗ рднреЗрдЬреЗ рдЧрдП рд╣реИрдВ xdp-test, рдЗрд╕ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкрд░ рд╡рд┐рддрд░рд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ:

ip netns exec xdp-test   ping 192.0.2.1

рдЗрд╕рдореЗрдВ рд╢реЗрд▓ рдЪрд▓рд╛рдирд╛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИ xdp-test. рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рдПрдХ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рд╣реЛрддреА рд╣реИ рдЬреЛ рд╕реНрдЯреИрдВрдб рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдХрд░рддреА рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рдХрдорд╛рдВрдб рдХреЗ рд╕рд╛рде рд╕реНрдЯреИрдВрдб рд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ sudo ./stand up рдФрд░ рдЗрд╕реЗ рд╣рдЯрд╛ рджреЗрдВ sudo ./stand down.

рдЕрдиреБрд░реЗрдЦрдг

рдлрд╝рд┐рд▓реНрдЯрд░ рдбрд┐рд╡рд╛рдЗрд╕ рд╕реЗ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИ:

ip -force link set dev xdp-local xdp object xdp_filter.o verbose

рдХреБрдВрдЬреА -force рдпрджрд┐ рдХреЛрдИ рдЕрдиреНрдп рдкреНрд░реЛрдЧреНрд░рд╛рдо рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд▓рд┐рдВрдХ рд╣реИ рддреЛ рдЙрд╕реЗ рдПрдХ рдирдП рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛ рд▓рд┐рдВрдХ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред "рдХреЛрдИ рдЦрдмрд░ рдЕрдЪреНрдЫреА рдЦрдмрд░ рдирд╣реАрдВ рд╣реИ" рдЗрд╕ рдЖрджреЗрд╢ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╣реАрдВ рд╣реИ, рд╡реИрд╕реЗ рднреА рдЖрдЙрдЯрдкреБрдЯ рдмрд╣реБрдд рдмрдбрд╝рд╛ рд╣реИред рд╕рдВрдХреЗрдд рджреЗрдирд╛ 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
<...>

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

$ 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 рдХрд╛ рдЙрдкрдпреЛрдЧ 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

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

рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдирд┐рд░реВрдкрдг

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

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

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

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

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

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

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

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

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

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

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

SYN рдХреБрдХреАрдЬрд╝ рдХрд╛ рд╣рдореЗрд╢рд╛ рдЙрдкрдпреЛрдЧ рдХреНрдпреЛрдВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛?

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

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

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

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

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

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

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

рдЯреАрд╕реАрдкреА рд╣реИрдВрдбрд╢реЗрдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди

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

рд╣рдореЗрдВ рдиреЗрдЯрд╡рд░реНрдХ рд╣реЗрдбрд░ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ: рдИрдерд░рдиреЗрдЯ (uapi/linux/if_ether.h), рдЖрдИрдкреАрд╡реА4 (uapi/linux/ip.h) рдФрд░ рдЯреАрд╕реАрдкреА (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 рдХреЛ рдЙрддреНрддрд░ рджреЗрдВ

рдЗрд╕ рд╕реНрддрд░ рдкрд░ рд▓рдХреНрд╖реНрдп рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдХреЗ рд╕рд╛рде рдПрдХ рд╕рд╣реА 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;

рдЯреАрд╕реАрдкреА рдкреЛрд░реНрдЯ, рдЖрдИрдкреА рдФрд░ рдореИрдХ рдкрддреЗ рд╕реНрд╡реИрдк рдХрд░реЗрдВред рдорд╛рдирдХ рд▓рд╛рдЗрдмреНрд░реЗрд░реА 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() RFC 32 рдХреЗ рдЕрдиреБрд╕рд╛рд░, 16-рдмрд┐рдЯ рд╢рдмреНрджреЛрдВ рдХреЗ 791-рдмрд┐рдЯ рдпреЛрдЧ рд╕реЗ рдПрдХ рдЪреЗрдХрд╕рдо рдмрдирд╛рддрд╛ рд╣реИред

рдЯреАрд╕реАрдкреА рд╣реИрдВрдбрд╢реЗрдХ рдЬрд╛рдВрдЪ

рдлрд╝рд┐рд▓реНрдЯрд░ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрдиреЗрдХреНрд╢рди рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддрд╛ рд╣реИ 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 рдПрд╕реАрдХреЗ рд╣реИ):

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

рдЬрдм рддрдХ рдЬрд╛рдВрдЪреЗ рдЧрдП рдЖрдИрдкреА рдХреА рдХреЛрдИ рд╕реВрдЪреА рдирд╣реАрдВ рд╣реИ, рддрдм рддрдХ 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

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдЬреЛрдбрд╝реЗрдВ