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

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

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

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

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

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

XDP рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдЕрд╡рд▓реЛрдХрди

рдо рдХреЗрд╡рд▓ рдореБрдЦреНрдп рдмреБрдБрджрд╛рд╣рд░реВрд▓рд╛рдИ рд░реВрдкрд░реЗрдЦрд╛ рджрд┐рдиреЗрдЫреБ рддрд╛рдХрд┐ рдХрд╛рдЧрдЬрд╛рддрд╣рд░реВ рд░ рдЕрд╡рд╕реНрдерд┐рдд рд▓реЗрдЦрд╣рд░реВ рдирдХреНрдХрд▓ рдирдЧрд░реНрдиреБрд╣реЛрд╕реНред

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

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

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

рдлрд┐рд▓реНрдЯрд░ рдбрд┐рдЬрд╛рдЗрди рд░ рд╕реНрдерд╛рдкрдирд╛ рдпреЛ рдЬрд╕реНрддреЛ рджреЗрдЦрд┐рдиреНрдЫ:

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

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

рд╡рд╛рддрд╛рд╡рд░рдг рддрдпрд╛рд░ рдЧрд░реНрджреИ

рд╡рд┐рдзрд╛рдирд╕рднрд╛

рдХреНрд▓реНрдпрд╛рдЩрд▓реЗ eBPF рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░рдХреЛ рд▓рд╛рдЧрд┐ рд╡рд╕реНрддреБрдХреЛ рдХреЛрдб рд╕реАрдзрд╛ рдЙрддреНрдкрд╛рджрди рдЧрд░реНрди рд╕рдХреНрджреИрди, рддреНрдпрд╕реИрд▓реЗ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдорд╛ рджреБрдИ рдЪрд░рдгрд╣рд░реВ рд╣реБрдиреНрдЫрдиреН:

  1. LLVM рдмрд╛рдЗрдЯрдХреЛрдбрдорд╛ C рдХреЛрдб рдХрдореНрдкрд╛рдЗрд▓ рдЧрд░реНрдиреБрд╣реЛрд╕реН (clang -emit-llvm).
  2. рдмрд╛рдЗрдЯрдХреЛрдбрд▓рд╛рдИ eBPF рд╡рд╕реНрддреБ рдХреЛрдбрдорд╛ рд░реВрдкрд╛рдиреНрддрд░рдг рдЧрд░реНрдиреБрд╣реЛрд╕реН (llc -march=bpf -filetype=obj).

рдлрд┐рд▓реНрдЯрд░ рд▓реЗрдЦреНрджрд╛, рд╕рд╣рд╛рдпрдХ рдкреНрд░рдХрд╛рд░реНрдпрд╣рд░реВ рд░ рдореНрдпрд╛рдХреНрд░реЛрд╣рд░реВ рднрдПрдХрд╛ рдлрд╛рдЗрд▓рд╣рд░реВрдХреЛ рдПрдХ рдЬреЛрдбреА рдЙрдкрдпреЛрдЧреА рд╣реБрдиреЗрдЫ рдХрд░реНрдиреЗрд▓ рдкрд░реАрдХреНрд╖рдгрдмрд╛рдЯред рдпреЛ рдорд╣рддреНрддреНрд╡рдкреВрд░реНрдг рдЫ рдХрд┐ рддрд┐рдиреАрд╣рд░реВ рдХрд░реНрдиреЗрд▓ рд╕рдВрд╕реНрдХрд░рдг (KVER)ред рддрд┐рдиреАрд╣рд░реВрд▓рд╛рдИ рдбрд╛рдЙрдирд▓реЛрдб рдЧрд░реНрдиреБрд╣реЛрд╕реН helpers/:

export KVER=v5.3.7
export BASE=https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/plain/tools/testing/selftests/bpf
wget -P helpers --content-disposition "${BASE}/bpf_helpers.h?h=${KVER}" "${BASE}/bpf_endian.h?h=${KVER}"
unset KVER BASE

рдЖрд░реНрдХ рд▓рд┐рдирдХреНрд╕рдХреЛ рд▓рд╛рдЧрд┐ рдореЗрдХрдлрд╛рдЗрд▓ (рдХрд░реНрдиреЗрд▓ 5.3.7):

CLANG ?= clang
LLC ?= llc

KDIR ?= /lib/modules/$(shell uname -r)/build
ARCH ?= $(subst x86_64,x86,$(shell uname -m))

CFLAGS = 
    -Ihelpers 
    
    -I$(KDIR)/include 
    -I$(KDIR)/include/uapi 
    -I$(KDIR)/include/generated/uapi 
    -I$(KDIR)/arch/$(ARCH)/include 
    -I$(KDIR)/arch/$(ARCH)/include/generated 
    -I$(KDIR)/arch/$(ARCH)/include/uapi 
    -I$(KDIR)/arch/$(ARCH)/include/generated/uapi 
    -D__KERNEL__ 
    
    -fno-stack-protector -O2 -g

xdp_%.o: xdp_%.c Makefile
    $(CLANG) -c -emit-llvm $(CFLAGS) $< -o - | 
    $(LLC) -march=bpf -filetype=obj -o $@

.PHONY: all clean

all: xdp_filter.o

clean:
    rm -f ./*.o

KDIR рдХрд░реНрдиреЗрд▓ рд╣реЗрдбрд░рдорд╛ рдорд╛рд░реНрдЧ рд╕рдорд╛рд╡реЗрд╢ рдЧрд░реНрджрдЫ, ARCH - рдкреНрд░рдгрд╛рд▓реА рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ред рд╡рд┐рддрд░рдгрд╣рд░реВ рдмреАрдЪ рдмрд╛рдЯреЛ рд░ рдЙрдкрдХрд░рдгрд╣рд░реВ рдереЛрд░реИ рдлрд░рдХ рд╣реБрди рд╕рдХреНрдЫред

рдбреЗрдмрд┐рдпрди 10 (рдХрд░реНрдиреЗрд▓ 4.19.67) рдХреЛ рд▓рд╛рдЧрд┐ рднрд┐рдиреНрдирддрд╛рд╣рд░реВрдХреЛ рдЙрджрд╛рд╣рд░рдг

# ╨┤╤А╤Г╨│╨░╤П ╨║╨╛╨╝╨░╨╜╨┤╨░
CLANG ?= clang
LLC ?= llc-7

# ╨┤╤А╤Г╨│╨╛╨╣ ╨║╨░╤В╨░╨╗╨╛╨│
KDIR ?= /usr/src/linux-headers-$(shell uname -r)
ARCH ?= $(subst x86_64,x86,$(shell uname -m))

# ╨┤╨▓╨░ ╨┤╨╛╨┐╨╛╨╗╨╜╨╕╤В╨╡╨╗╤М╨╜╤Л╤Е ╨║╨░╤В╨░╨╗╨╛╨│╨░ -I
CFLAGS = 
    -Ihelpers 
    
    -I/usr/src/linux-headers-4.19.0-6-common/include 
    -I/usr/src/linux-headers-4.19.0-6-common/arch/$(ARCH)/include 
    # ╨┤╨░╨╗╨╡╨╡ ╨▒╨╡╨╖ ╨╕╨╖╨╝╨╡╨╜╨╡╨╜╨╕╨╣

CFLAGS рд╕рд╣рд╛рдпрдХ рд╣реЗрдбрд░рд╣рд░реВ рд░ рдХрд░реНрдиреЗрд▓ рд╣реЗрдбрд░рд╣рд░реВрд╕рдБрдЧ рдзреЗрд░реИ рдбрд╛рдЗрд░реЗрдХреНрдЯрд░реАрд╣рд░реВрд╕рдБрдЧ рдбрд╛рдЗрд░реЗрдХреНрдЯрд░реА рдЬрдбрд╛рди рдЧрд░реНрдиреБрд╣реЛрд╕реНред рдкреНрд░рддреАрдХ __KERNEL__ рдпрд╕рдХреЛ рдЕрд░реНрде UAPI (userspace API) рд╣реЗрдбрд░рд╣рд░реВ рдХрд░реНрдиреЗрд▓ рдХреЛрдбрдХрд╛ рд▓рд╛рдЧрд┐ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдЧрд░рд┐рдПрдХреЛ рдЫ, рдХрд┐рдирднрдиреЗ рдлрд┐рд▓реНрдЯрд░ рдХрд░реНрдиреЗрд▓рдорд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реБрдиреНрдЫред

рд╕реНрдЯреНрдпрд╛рдХ рд╕реБрд░рдХреНрд╖рд╛ рдЕрд╕рдХреНрд╖рдо рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫ (-fno-stack-protector), рдХрд┐рдирднрдиреЗ eBPF рдХреЛрдб рдкреНрд░рдорд╛рдгрд┐рдХрд░рдгрдХрд░реНрддрд╛рд▓реЗ рдЕрдЭреИ рдкрдирд┐ рд╕реНрдЯреНрдпрд╛рдХ-рдмрд╛рдЙрдиреНрдб рдЙрд▓реНрд▓рдЩреНрдШрдирд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐ рдЬрд╛рдБрдЪ рдЧрд░реНрджрдЫред рдпреЛ рддреБрд░реБрдиреНрддреИ рдЕрдкреНрдЯрд┐рдорд╛рдЗрдЬреЗрд╕рдирд╣рд░реВ рдЦреЛрд▓реНрди рд▓рд╛рдпрдХ рдЫ, рдХрд┐рдирдХрд┐ eBPF bytecode рдХреЛ рдЖрдХрд╛рд░ рд╕реАрдорд┐рдд рдЫред

рд╕рдмреИ рдкреНрдпрд╛рдХреЗрдЯрд╣рд░реВ рдкрд╛рд╕ рдЧрд░реНрдиреЗ рд░ рдХреЗрд╣реА рдирдЧрд░реНрдиреЗ рдлрд┐рд▓реНрдЯрд░рдХреЛ рд╕рд╛рде рд╕реБрд░реВ рдЧрд░реМрдВ:

#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ред рдЕрдм рдХрд╣рд╛рдБ рдкреНрд░рдпрд╛рд╕ рдЧрд░реНрдиреЗ?

рдкрд░реАрдХреНрд╖рдг рд╕реНрдЯреНрдпрд╛рдиреНрдб

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

Veth (рднрд░реНрдЪреБрдЕрд▓ рдЗрдерд░рдиреЗрдЯ) рдкреНрд░рдХрд╛рд░рдХрд╛ рдпрдиреНрддреНрд░рд╣рд░реВ рд╣рд╛рдореНрд░реЛ рд▓рд╛рдЧрд┐ рдЙрдкрдпреБрдХреНрдд рдЫрдиреН: рдпреА рднрд░реНрдЪреБрдЕрд▓ рдиреЗрдЯрд╡рд░реНрдХ рдЗрдиреНрдЯрд░рдлреЗрд╕рд╣рд░реВрдХреЛ рдПрдХ рдЬреЛрдбреА рд╣реБрдиреН рдЬреБрди "рдЬрдбрд┐рдд" рдПрдХ рдЕрд░реНрдХрд╛рдорд╛ рд╕реАрдзрд╛ред рддрдкрд╛рдИрдВрд▓реЗ рддрд┐рдиреАрд╣рд░реВрд▓рд╛рдИ рдпрд╕рд░реА рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ (рдпрд╕ рдЦрдгреНрдбрдорд╛ рд╕рдмреИ рдЖрджреЗрд╢рд╣рд░реВ ip рдмрд╛рдЯ рдЧрд░рд┐рдиреНрдЫ root):

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

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

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

рдирдпрд╛рдБ рдиреЗрдорд╕реНрдкреЗрд╕ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реМрдВ xdp-test рд░ рддреНрдпрд╣рд╛рдБ рд╕рд╛рд░реНрдиреБрд╣реЛрд╕реН xdp-remote.

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

рддреНрдпрд╕рдкрдЫрд┐ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдЕрдШрд┐ рдмрдвреНрдЫ xdp-test, "рджреЗрдЦреНрджреИрди" xdp-local (рдпреЛ рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд░реВрдкрдорд╛ netns рдорд╛ рд░рд╣рдиреЗрдЫ) рд░ 192.0.2.1 рдорд╛ рдкреНрдпрд╛рдХреЗрдЯ рдкрдард╛рдЙрдБрджрд╛ рдпрд╕рд▓реЗ рдпрд╕рд▓рд╛рдИ рдкрд╛рд╕ рдЧрд░реНрдиреЗрдЫред xdp-remoteрдХрд┐рдирднрдиреЗ рдпреЛ 192.0.2.0/24 рдорд╛ рдорд╛рддреНрд░ рдЗрдиреНрдЯрд░рдлреЗрд╕ рдпреЛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдкрд╣реБрдБрдЪрдпреЛрдЧреНрдп рдЫред рдпреЛ рдкрдирд┐ рд╡рд┐рдкрд░реАрдд рджрд┐рд╢рд╛ рдорд╛ рдХрд╛рдо рдЧрд░реНрджрдЫред

netns рдХреЛ рдмреАрдЪрдорд╛ рд╕рд╛рд░реНрджрд╛, рдЗрдиреНрдЯрд░рдлреЗрд╕ рддрд▓ рдЬрд╛рдиреНрдЫ рд░ рдпрд╕рдХреЛ рдареЗрдЧрд╛рдирд╛ рдЧреБрдорд╛рдЙрдБрдЫред netns рдорд╛ рдЗрдиреНрдЯрд░рдлреЗрд╕ рдХрдиреНрдлрд┐рдЧрд░ рдЧрд░реНрди, рддрдкрд╛рдИрдБрд▓реЗ рдЪрд▓рд╛рдЙрди рдЖрд╡рд╢реНрдпрдХ рдЫ ip ... рдпреЛ рдЖрджреЗрд╢ рдирд╛рдо рд╕реНрдерд╛рдирдорд╛ ip netns exec:

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

рддрдкрд╛рдИрд▓реЗ рджреЗрдЦреНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ, рдпреЛ рд╕реЗрдЯрд┐рдЩ рднрдиреНрджрд╛ рдлрд░рдХ рдЫреИрди xdp-local рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдирд╛рдо рд╕реНрдерд╛рдирдорд╛:

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

рдпрджрд┐ рддрдкрд╛рдИрдВ рджреМрдбрдиреБрд╣реБрдиреНрдЫ tcpdump -tnevi xdp-local, рддрдкрд╛рдИрд▓реЗ рдкрдард╛рдПрдХреЛ рдкреНрдпрд╛рдХреЗрдЯ рджреЗрдЦреНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ xdp-test, рдпрд╕ рдЗрдиреНрдЯрд░рдлреЗрд╕рдорд╛ рдкрдард╛рдЗрдиреНрдЫ:

ip netns exec xdp-test   ping 192.0.2.1

рд╢реЗрд▓ рднрд┐рддреНрд░ рд╕реБрд░реБ рдЧрд░реНрди рдпреЛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдЫ xdp-testред рднрдгреНрдбрд╛рд░рдХреЛ рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЫ рдЬрд╕рд▓реЗ рд╕реНрдЯреНрдпрд╛рдиреНрдбрд╕рдБрдЧ рдХрд╛рдорд▓рд╛рдИ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдмрдирд╛рдЙрдБрдЫ; рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐, рддрдкрд╛рдЗрдБ рдЖрджреЗрд╢рдХреЛ рд╕рд╛рде рд╕реНрдЯреНрдпрд╛рдиреНрдб рдХрдиреНрдлрд┐рдЧрд░ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫред sudo ./stand up рд░ рдпрд╕рд▓рд╛рдИ рдореЗрдЯрд╛рдЙрдиреБрд╣реЛрд╕реН sudo ./stand down.

рдЯреНрд░реЗрд╕рд┐рдЩ

рдлрд┐рд▓реНрдЯрд░ рдпрд╕ рдпрдиреНрддреНрд░рд╕рдБрдЧ рд╕рдореНрдмрдиреНрдзрд┐рдд рдЫ:

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

рдХреБрдЮреНрдЬреА -force рдпрджрд┐ рдЕрд░реНрдХреЛ рдкрд╣рд┐рд▓реЗ рдиреИ рд▓рд┐рдЩреНрдХ рдЧрд░рд┐рдПрдХреЛ рдЫ рднрдиреЗ рдирдпрд╛рдБ рдХрд╛рд░реНрдпрдХреНрд░рдо рд▓рд┐рдЩреНрдХ рдЧрд░реНрди рдЖрд╡рд╢реНрдпрдХ рдЫред "рдХреБрдиреИ рдкрдирд┐ рд╕рдорд╛рдЪрд╛рд░ рд░рд╛рдореНрд░реЛ рд╕рдорд╛рдЪрд╛рд░ рд╣реЛрдЗрди" рдпреЛ рдЖрджреЗрд╢рдХреЛ рдмрд╛рд░реЗрдорд╛ рд╣реЛрдЗрди, рдирд┐рд╖реНрдХрд░реНрд╖ рдХреБрдиреИ рдкрдирд┐ рдЕрд╡рд╕реНрдерд╛рдорд╛ рдареВрд▓реЛ рдЫред рд╕рдВрдХреЗрдд рдЧрд░реНрдиреБрд╣реЛрд╕реН verbose рд╡реИрдХрд▓реНрдкрд┐рдХ, рддрд░ рдпреЛ рд╕рдВрдЧ рдПрдХ рд░рд┐рдкреЛрд░реНрдЯ рдПрдХ рд╡рд┐рдзрд╛рдирд╕рднрд╛ рд╕реВрдЪреА рд╕рдВрдЧ рдХреЛрдб рдкреНрд░рдорд╛рдгрдХ рдХреЛ рдХрд╛рдо рдорд╛ рджреЗрдЦрд╛ рдкрд░реНрдЫ:

Verifier analysis:

0: (b7) r0 = 2
1: (95) exit

рдЗрдиреНрдЯрд░рдлреЗрд╕рдмрд╛рдЯ рдХрд╛рд░реНрдпрдХреНрд░рдо рдЕрдирд▓рд┐рдВрдХ рдЧрд░реНрдиреБрд╣реЛрд╕реН:

ip link set dev xdp-local xdp off

рд▓рд┐рдкрд┐рдорд╛ рдпреА рдЖрджреЗрд╢рд╣рд░реВ рдЫрдиреН sudo ./stand attach ╨╕ sudo ./stand detach.

рдлрд┐рд▓реНрдЯрд░ рд╕рдВрд▓рдЧреНрди рдЧрд░реЗрд░, рддрдкрд╛рдЗрдБ рдпреЛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ ping рдЪрд▓реНрди рдЬрд╛рд░реА рдЫ, рддрд░ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд╛рдо рдЧрд░реНрдЫ? рд▓рдЧрд╣рд░реВ рдердкреМрдВред рд╕рдорд╛рд░реЛрд╣ bpf_trace_printk() рдЬрд╕реНрддреИ printf(), рддрд░ рдврд╛рдБрдЪрд╛ рдмрд╛рд╣реЗрдХ рдЕрдиреНрдп рддреАрди рддрд░реНрдХ рд╕рдореНрдо рдорд╛рддреНрд░ рд╕рдорд░реНрдерди рдЧрд░реНрджрдЫ, рд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯрдХрд░реНрддрд╛рд╣рд░реВрдХреЛ рд╕реАрдорд┐рдд рд╕реВрдЪреАред рдореНрдпрд╛рдХреНрд░реЛ bpf_printk() рдХрд▓рд▓рд╛рдИ рд╕рд░рд▓ рдмрдирд╛рдЙрдБрдЫред

   SEC("prog")
   int xdp_main(struct xdp_md* ctx) {
+      bpf_printk("got packet: %pn", ctx);
       return XDP_PASS;
   }

рдЖрдЙрдЯрдкреБрдЯ рдХрд░реНрдиреЗрд▓ рдЯреНрд░реЗрд╕ рдЪреНрдпрд╛рдирд▓рдорд╛ рдЬрд╛рдиреНрдЫ, рдЬрд╕рд▓рд╛рдИ рд╕рдХреНрд╖рдо рдЧрд░реНрди рдЖрд╡рд╢реНрдпрдХ рдЫ:

echo -n 1 | sudo tee /sys/kernel/debug/tracing/options/trace_printk

рд╕рдиреНрджреЗрд╢ рдереНрд░реЗрдб рд╣реЗрд░реНрдиреБрд╣реЛрд╕реН:

cat /sys/kernel/debug/tracing/trace_pipe

рдпреА рджреБрдмреИ рдЖрджреЗрд╢рд╣рд░реВрд▓реЗ рдХрд▓ рдЧрд░реНрджрдЫ sudo ./stand log.

рдкрд┐рдЩрд▓реЗ рдЕрдм рдпрд╕реНрддреЛ рд╕рдиреНрджреЗрд╢рд╣рд░реВ рдЯреНрд░рд┐рдЧрд░ рдЧрд░реНрдиреБрдкрд░реНрдЫ:

<...>-110930 [004] ..s1 78803.244967: 0: got packet: 00000000ac510377

рдпрджрд┐ рддрдкрд╛рдИрдВрд▓реЗ рдкреНрд░рдорд╛рдгрд┐рдХрд░рдгрдХрд░реНрддрд╛рдХреЛ рдЖрдЙрдЯрдкреБрдЯрд▓рд╛рдИ рдирдЬрд┐рдХрдмрд╛рдЯ рд╣реЗрд░реНрдиреБрднрдпреЛ рднрдиреЗ, рддрдкрд╛рдИрдВрд▓реЗ рдЕрдиреМрдареЛ рдЧрдгрдирд╛рд╣рд░реВ рджреЗрдЦреНрдиреБрд╣реБрдиреЗрдЫ:

0: (bf) r3 = r1
1: (18) r1 = 0xa7025203a7465
3: (7b) *(u64 *)(r10 -8) = r1
4: (18) r1 = 0x6b63617020746f67
6: (7b) *(u64 *)(r10 -16) = r1
7: (bf) r1 = r10
8: (07) r1 += -16
9: (b7) r2 = 16
10: (85) call bpf_trace_printk#6
<...>

рддрдереНрдп рдпреЛ рд╣реЛ рдХрд┐ eBPF рдХрд╛рд░реНрдпрдХреНрд░рдорд╣рд░реВрдорд╛ рдбреЗрдЯрд╛ рдЦрдгреНрдб рдЫреИрди, рддреНрдпрд╕реИрд▓реЗ рдврд╛рдБрдЪрд╛ рд╕реНрдЯреНрд░рд┐рдЩрд▓рд╛рдИ рд╕рдЩреНрдХреЗрдд рдЧрд░реНрдиреЗ рдПрдХ рдорд╛рддреНрд░ рддрд░рд┐рдХрд╛ VM рдЖрджреЗрд╢рд╣рд░реВрдХреЛ рддрддреНрдХрд╛рд▓ рддрд░реНрдХрд╣рд░реВ рд╣реЛ:

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

рдпрд╕ рдХрд╛рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐, рдбрд┐рдмрдЧ рдЖрдЙрдЯрдкреБрдЯрд▓реЗ рдкрд░рд┐рдгрд╛рдорд┐рдд рдХреЛрдбрд▓рд╛рдИ рдзреЗрд░реИ рдмреНрд▓реЛрдЯ рдЧрд░реНрдЫред

XDP рдкреНрдпрд╛рдХреЗрдЯрд╣рд░реВ рдкрдард╛рдЙрдБрджреИ

рдлрд┐рд▓реНрдЯрд░ рдкрд░рд┐рд╡рд░реНрддрди рдЧрд░реМрдВ: рдпрд╕рд▓рд╛рдИ рд╕рдмреИ рдЖрдЧрдорди рдкреНрдпрд╛рдХреЗрдЯрд╣рд░реВ рдлрд┐рд░реНрддрд╛ рдкрдард╛рдЙрди рджрд┐рдиреБрд╣реЛрд╕реНред рдпреЛ рдиреЗрдЯрд╡рд░реНрдХрдХреЛ рджреГрд╖реНрдЯрд┐рдХреЛрдгрдмрд╛рдЯ рдЧрд▓рдд рдЫ, рдХрд┐рдирдХрд┐ рд╣реЗрдбрд░рд╣рд░реВрдорд╛ рдареЗрдЧрд╛рдирд╛рд╣рд░реВ рдкрд░рд┐рд╡рд░реНрддрди рдЧрд░реНрди рдЖрд╡рд╢реНрдпрдХ рд╣реБрдиреЗрдЫ, рддрд░ рдЕрдм рд╕рд┐рджреНрдзрд╛рдиреНрддрдорд╛ рдХрд╛рдо рдорд╣рддреНрддреНрд╡рдкреВрд░реНрдг рдЫред

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

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

рдорд▓рд╛рдИ рдпреЛ рдХрд╕рд░реА рдерд╛рд╣рд╛ рднрдпреЛ?

рдХрд░реНрдиреЗрд▓рдорд╛ рдкреНрдпрд╛рдХреЗрдЬрдХреЛ рдорд╛рд░реНрдЧ рдЯреНрд░реЗрд╕ рдЧрд░реНрдиреБрд╣реЛрд╕реН perf рдШрдЯрдирд╛ рд╕рдВрдпрдиреНрддреНрд░рд▓реЗ рдЕрдиреБрдорддрд┐ рджрд┐рдиреНрдЫ, рд╡реИрд╕реЗ, рдЙрд╣реА рднрд░реНрдЪреБрдЕрд▓ рдореЗрд╕рд┐рди рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░, рддреНрдпреЛ рд╣реЛ, eBPF рдХреЛ рд╕рд╛рде disassemblies рдХреЛ рд▓рд╛рдЧреА eBPF рдкреНрд░рдпреЛрдЧ рдЧрд░рд┐рдиреНрдЫред

рддрдкрд╛рдИрдВрд▓реЗ рдЦрд░рд╛рдмрдмрд╛рдЯ рд░рд╛рдореНрд░реЛ рдмрдирд╛рдЙрдиреБ рдкрд░реНрдЫ, рдХрд┐рдирдХрд┐ рдпрд╕рд▓рд╛рдИ рдмрд╛рд╣рд┐рд░ рдмрдирд╛рдЙрди рдЕрд░реВ рдХреЗрд╣реА рдЫреИрдиред

$ sudo perf trace --call-graph dwarf -e 'xdp:*'
   0.000 ping/123455 xdp:xdp_bulk_tx:ifindex=19 action=TX sent=0 drops=1 err=-6
                                     veth_xdp_flush_bq ([veth])
                                     veth_xdp_flush_bq ([veth])
                                     veth_poll ([veth])
                                     <...>

рдХреЛрдб 6 рдХреЗ рд╣реЛ?

$ errno 6
ENXIO 6 No such device or address

рд╕рдорд╛рд░реЛрд╣ veth_xdp_flush_bq() рдмрд╛рдЯ рддреНрд░реБрдЯрд┐ рдХреЛрдб рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрджрдЫ veth_xdp_xmit(), рдЬрд╣рд╛рдБ рдЦреЛрдЬреНрдиреБрд╣реЛрд╕реН ENXIO рд░ рдЯрд┐рдкреНрдкрдгреА рдлреЗрд▓рд╛ рдкрд╛рд░реНрдиреБрд╣реЛрд╕реНред

рдиреНрдпреВрдирддрдо рдлрд┐рд▓реНрдЯрд░ рдкреБрдирд░реНрд╕реНрдерд╛рдкрдирд╛ рдЧрд░реМрдВ (XDP_PASS) рдлрд╛рдЗрд▓рдорд╛ xdp_dummy.c, рдпрд╕рд▓рд╛рдИ рдореЗрдХрдлрд╛рдЗрд▓рдорд╛ рдердкреНрдиреБрд╣реЛрд╕реН, рдпрд╕рд▓рд╛рдИ рдмрд╛рдБрдзреНрдиреБрд╣реЛрд╕реН xdp-remote:

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

рдЕрд╣рд┐рд▓реЗ tcpdump рдХреЗ рдЕрдкреЗрдХреНрд╖рд┐рдд рдЫ рджреЗрдЦрд╛рдЙрдБрдЫ:

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

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

рд╕рдорд╕реНрдпрд╛рдХреЛ рдЧрдарди

рднрдирд┐рдПрдХреЛ рдХрд╛рд░реНрдпрдорд╛ рдЬрд╛рдФрдВ: XDP рдорд╛ SYN рдХреБрдХреАрдЬ рдореЗрдХрд╛рдирд┐рдЬреНрдо рд▓реЗрдЦреНрдиреБрд╣реЛрд╕реНред

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

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

SYN рдХреБрдХреА рд▓рд╛рдореЛ рд╕рдордпрджреЗрдЦрд┐ рд▓рд┐рдирдХреНрд╕ рдХрд░реНрдиреЗрд▓рдорд╛ рд▓рд╛рдЧреВ рдЧрд░рд┐рдПрдХреЛ рдЫ рд░ рдпрджрд┐ SYN рд╣рд░реВ рдзреЗрд░реИ рдЫрд┐рдЯреЛ рд░ рд╕рд╛рдореВрд╣рд┐рдХ рд░реВрдкрдорд╛ рдЖрдЗрдкреБрдЧреНрдЫрдиреН рднрдиреЗ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдкрдорд╛ рд╕рдХреНрд╖рдо рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫред

TCP рд╣реНрдпрд╛рдиреНрдбрд╢реЗрдХрдорд╛ рд╢реИрдХреНрд╖рд┐рдХ рдХрд╛рд░реНрдпрдХреНрд░рдо

TCP рд▓реЗ рдмрд╛рдЗрдЯрд╣рд░реВрдХреЛ рд╕реНрдЯреНрд░рд┐рдордХреЛ рд░реВрдкрдорд╛ рдбреЗрдЯрд╛ рдкреНрд░рд╕рд╛рд░рдг рдкреНрд░рджрд╛рди рдЧрд░реНрджрдЫ, рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐, HTTP рдЕрдиреБрд░реЛрдзрд╣рд░реВ TCP рдорд╛рд░реНрдлрдд рдкреНрд░рд╕рд╛рд░рд┐рдд рд╣реБрдиреНрдЫрдиреНред рд╕реНрдЯреНрд░рд┐рдо рдкреНрдпрд╛рдХреЗрдЯрд╣рд░реВрдорд╛ рдЯреБрдХреНрд░рд╛рд╣рд░реВрдорд╛ рдкреНрд░рд╕рд╛рд░рд┐рдд рд╣реБрдиреНрдЫред рд╕рдмреИ TCP рдкреНрдпрд╛рдХреЗрдЯрд╣рд░реВрдорд╛ рддрд╛рд░реНрдХрд┐рдХ рдЭрдгреНрдбрд╛ рд░ 32-рдмрд┐рдЯ рдЕрдиреБрдХреНрд░рдо рд╕рдВрдЦреНрдпрд╛рд╣рд░реВ рдЫрдиреН:

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

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

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

рдЬрдбрд╛рдирдХреЛ рд╕реБрд░реБрдорд╛, рдкрдХреНрд╖рд╣рд░реВ рд╕рд╣рдордд рд╣реБрдиреБрдкрд░реНрдЫ seqnum ╨╕ acknumред рдЧреНрд░рд╛рд╣рдХрд▓реЗ рдпрд╕рдХреЛ рд╕рд╛рде рдПрдХ SYN рдкреНрдпрд╛рдХреЗрдЯ рдкрдард╛рдЙрдБрдЫ seqnum = Xред рд╕рд░реНрднрд░рд▓реЗ SYNACK рдкреНрдпрд╛рдХреЗрдЯрдХреЛ рд╕рд╛рде рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджрд┐рдиреНрдЫ, рдЬрд╣рд╛рдБ рдпрд╕рд▓реЗ рдпрд╕рдХреЛ рд░реЗрдХрд░реНрдб рдЧрд░реНрджрдЫ seqnum = Y рд░ рдЙрдЬрд╛рдЧрд░ рдЧрд░реНрджрдЫ acknum = X + 1ред рдЧреНрд░рд╛рд╣рдХрд▓реЗ ACK рдкреНрдпрд╛рдХреЗрдЯрдХреЛ рд╕рд╛рде SYNACK рд▓рд╛рдИ рдЬрд╡рд╛рдл рджрд┐рдиреНрдЫ, рдЬрд╣рд╛рдБ seqnum = X + 1, acknum = Y + 1ред рдпрд╕ рдкрдЫрд┐, рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдбрд╛рдЯрд╛ рд╕реНрдерд╛рдирд╛рдиреНрддрд░рдг рд╕реБрд░реБ рд╣реБрдиреНрдЫред

рдпрджрд┐ рд╕рд╛рдереАрд▓реЗ рдкреНрдпрд╛рдХреЗрдЯрдХреЛ рд░рд╕рд┐рдж рд╕реНрд╡реАрдХрд╛рд░ рдЧрд░реНрджреИрди рднрдиреЗ, TCP рд▓реЗ рд╕рдордп рд╕рдорд╛рдкреНрдд рднрдПрдкрдЫрд┐ рдпрд╕рд▓рд╛рдИ рдкреБрди: рдкрдард╛рдЙрдБрдЫред

рдХрд┐рди SYN рдХреБрдХреАрд╣рд░реВ рд╕рдзреИрдВ рдкреНрд░рдпреЛрдЧ рдЧрд░рд┐рдБрджреИрдирдиреН?

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

рдкреНрдпрд╛рдХреЗрдЬ рдкрд░рд┐рдкреНрд░реЗрдХреНрд╖реНрдпрдмрд╛рдЯ, рдПрдХ XDP рдХрд╛рд░реНрдпрдХреНрд░рдорд▓реЗ рдирд┐рдореНрди рдЧрд░реНрдиреБрдкрд░реНрджрдЫ:

  • рдХреБрдХреАрдХреЛ рд╕рд╛рде SYNACK рд╕рдБрдЧ SYN рд▓рд╛рдИ рдЬрд╡рд╛рдл рджрд┐рдиреБрд╣реЛрд╕реН;
  • ACK рд▓рд╛рдИ RST рд╕рдБрдЧ рдЬрд╡рд╛рдл рджрд┐рдиреБрд╣реЛрд╕реН (рд╡рд┐рдЪреНрдЫреЗрдж рдЧрд░реНрдиреБрд╣реЛрд╕реН);
  • рдмрд╛рдБрдХреА рдкреНрдпрд╛рдХреЗрдЯрд╣рд░реВ рдЦрд╛рд░реЗрдЬ рдЧрд░реНрдиреБрд╣реЛрд╕реНред

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

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

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

рдард╛рдЙрдБрдХреЛ рдард╛рдЙрдБ (**), рдЬрдм рд╣рд╛рдореАрд╕рдБрдЧ рдЯреЗрдмрд▓ рдЫреИрди, рд╣рд╛рдореА рдкреНрдпрд╛рдХреЗрдЯ рдЫреЛрдбреНрдиреЗрдЫреМрдВред

TCP рд╣реНрдпрд╛рдиреНрдбрд╢реЗрдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЧрд░реНрджреИ

рдкреНрдпрд╛рдХреЗрдЬ рдкрд╛рд░реНрд╕ рдЧрд░реНрджреИ рд░ рдХреЛрдб рдкреНрд░рдорд╛рдгрд┐рдд рдЧрд░реНрджреИ

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

рдкрдардиреАрдпрддрд╛рдХреЛ рд▓рд╛рдЧрд┐ C рдорд╛ рд╣рд╛рдЗрд▓рд╛рдЗрдЯ рдЧрд░рд┐рдПрдХрд╛ рд╕рдмреИ рдкреНрд░рдХрд╛рд░реНрдпрд╣рд░реВ рдХрд▓рдХреЛ рдмрд┐рдиреНрджреБрдорд╛ рдЗрдирд▓рд╛рдЗрди рд╣реБрдиреБрдкрд░реНрдЫ, рдХрд┐рдирдХрд┐ рдХрд░реНрдиреЗрд▓рдорд╛ eBPF рдкреНрд░рдорд╛рдгрд┐рдХрд░рдгрд▓реЗ рдмреНрдпрд╛рдХрдЯреНрд░реНрдпрд╛рдХрд┐рдЩрд▓рд╛рдИ рдирд┐рд╖реЗрдз рдЧрд░реНрджрдЫ, рдЬреБрди рд╡рд╛рд╕реНрддрд╡рдорд╛, рд▓реБрдкрд╣рд░реВ рд░ рдкреНрд░рдХрд╛рд░реНрдп рдХрд▓рд╣рд░реВ рдЫрдиреНред

#define INTERNAL static __attribute__((always_inline))

рдореНрдпрд╛рдХреНрд░реЛ LOG() рд░рд┐рд▓реАрдЬ рдмрд┐рд▓реНрдбрдорд╛ рдореБрджреНрд░рдг рдЕрд╕рдХреНрд╖рдо рдкрд╛рд░реНрдЫред

рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд╛рд░реНрдпрд╣рд░реВрдХреЛ рдХрдиреНрд╡реЗрдпрд░ рд╣реЛред рдкреНрд░рддреНрдпреЗрдХрд▓реЗ рдПрдХ рдкреНрдпрд╛рдХреЗрдЯ рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрджрдЫ рдЬрд╕рдорд╛ рд╕рдореНрдмрдиреНрдзрд┐рдд рд╕реНрддрд░ рд╣реЗрдбрд░ рд╣рд╛рдЗрд▓рд╛рдЗрдЯ рдЧрд░рд┐рдПрдХреЛ рдЫ, рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐, process_ether() рднрд░рд┐рдиреЗ рдЕрдкреЗрдХреНрд╖рд╛ рдЧрд░реНрджрдЫ etherред рдХреНрд╖реЗрддреНрд░ рд╡рд┐рд╢реНрд▓реЗрд╖рдгрдХреЛ рдирддрд┐рдЬрд╛рдХреЛ рдЖрдзрд╛рд░рдорд╛, рдкреНрд░рдХрд╛рд░реНрдпрд▓реЗ рдкреНрдпрд╛рдХреЗрдЯрд▓рд╛рдИ рдЙрдЪреНрдЪ рд╕реНрддрд░рдорд╛ рдкрд╛рд╕ рдЧрд░реНрди рд╕рдХреНрдЫред рдкреНрд░рдХрд╛рд░реНрдпрдХреЛ рдкрд░рд┐рдгрд╛рдо XDP рдХрд╛рд░реНрдп рд╣реЛред рдЕрд╣рд┐рд▓реЗрдХреЛ рд▓рд╛рдЧрд┐, SYN рд░ ACK рд╣реНрдпрд╛рдиреНрдбрд▓рд░рд╣рд░реВрд▓реЗ рд╕рдмреИ рдкреНрдпрд╛рдХреЗрдЯрд╣рд░реВ рдкрд╛рд╕ рдЧрд░реНрдЫрдиреНред

struct Packet {
    struct xdp_md* ctx;

    struct ethhdr* ether;
    struct iphdr* ip;
    struct tcphdr* tcp;
};

INTERNAL int process_tcp_syn(struct Packet* packet) { return XDP_PASS; }
INTERNAL int process_tcp_ack(struct Packet* packet) { return XDP_PASS; }
INTERNAL int process_tcp(struct Packet* packet) { ... }
INTERNAL int process_ip(struct Packet* packet) { ... }

INTERNAL int
process_ether(struct Packet* packet) {
    struct ethhdr* ether = packet->ether;

    LOG("Ether(proto=0x%x)", bpf_ntohs(ether->h_proto));

    if (ether->h_proto != bpf_ntohs(ETH_P_IP)) {
        return XDP_PASS;
    }

    // B
    struct iphdr* ip = (struct iphdr*)(ether + 1);
    if ((void*)(ip + 1) > (void*)packet->ctx->data_end) {
        return XDP_DROP; /* malformed packet */
    }

    packet->ip = ip;
    return process_ip(packet);
}

SEC("prog")
int xdp_main(struct xdp_md* ctx) {
    struct Packet packet;
    packet.ctx = ctx;

    // A
    struct ethhdr* ether = (struct ethhdr*)(void*)ctx->data;
    if ((void*)(ether + 1) > (void*)ctx->data_end) {
        return XDP_PASS;
    }

    packet.ether = ether;
    return process_ether(&packet);
}

рдо рддрдкрд╛рдИрдВрдХреЛ рдзреНрдпрд╛рди A рд░ B рдЪрд┐рдиреНрд╣рд┐рдд рдЪреЗрдХрд╣рд░реВрдорд╛ рдЦрд┐рдЪреНрджрдЫреБред рдпрджрд┐ рддрдкрд╛рдИрдВрд▓реЗ A рдЯрд┐рдкреНрдкрдгреА рдЧрд░реНрдиреБрднрдпреЛ рднрдиреЗ, рдХрд╛рд░реНрдпрдХреНрд░рдо рдирд┐рд░реНрдорд╛рдг рд╣реБрдиреЗрдЫ, рддрд░ рд▓реЛрдб рдЧрд░реНрджрд╛ рдкреНрд░рдорд╛рдгреАрдХрд░рдг рддреНрд░реБрдЯрд┐ рд╣реБрдиреЗрдЫ:

Verifier analysis:

<...>
11: (7b) *(u64 *)(r10 -48) = r1
12: (71) r3 = *(u8 *)(r7 +13)
invalid access to packet, off=13 size=1, R7(id=0,off=0,r=0)
R7 offset is outside of the packet
processed 11 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0

Error fetching program/map!

рдХреБрдЮреНрдЬреА рд╕реНрдЯреНрд░рд┐рдЩ invalid access to packet, off=13 size=1, R7(id=0,off=0,r=0): рддреНрдпрд╣рд╛рдБ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрдерд╣рд░реВ рдЫрдиреН рдЬрдм рдмрдлрд░рдХреЛ рд╕реБрд░реБрдмрд╛рдЯ рддреЗрд╣реНрд░реМрдВ рдмрд╛рдЗрдЯ рдкреНрдпрд╛рдХреЗрдЯ рдмрд╛рд╣рд┐рд░ рд╣реБрдиреНрдЫред рд╣рд╛рдореА рдХреБрди рд▓рд╛рдЗрдирдХреЛ рдмрд╛рд░реЗрдорд╛ рдХреБрд░рд╛ рдЧрд░реНрджреИрдЫреМрдВ рддреНрдпреЛ рд╕реВрдЪреАрдмрд╛рдЯ рдмреБрдЭреНрди рдЧрд╛рд╣реНрд░реЛ рдЫ, рддрд░ рддреНрдпрд╣рд╛рдБ рдПрдХ рдирд┐рд░реНрджреЗрд╢рди рдирдореНрдмрд░ (12) рд░ рд╕реНрд░реЛрдд рдХреЛрдбрдХреЛ рд▓рд╛рдЗрдирд╣рд░реВ рджреЗрдЦрд╛рдЙрдиреЗ рдПрдХ рдбрд┐рд╕реЗрдореНрдмрд▓рд░ рдЫ:

llvm-objdump -S xdp_filter.o | less

рдпрд╕ рдЕрд╡рд╕реНрдерд╛рдорд╛ рдпрд╕рд▓реЗ рд░реЗрдЦрд╛рд▓рд╛рдИ рд╕рдВрдХреЗрдд рдЧрд░реНрджрдЫ

LOG("Ether(proto=0x%x)", bpf_ntohs(ether->h_proto));

рдЬрд╕рд▓реЗ рд╕рдорд╕реНрдпрд╛ рднрдПрдХреЛ рдкреНрд░рд╖реНрдЯ рдкрд╛рд░реНрдЫ etherред рдпреЛ рд╕рдзреИрдВ рдпрд╕реНрддреИ рд╣реБрдиреЗрдЫред

SYN рд▓рд╛рдИ рдЬрд╡рд╛рдл рджрд┐рдиреБрд╣реЛрд╕реН

рдпрд╕ рдЪрд░рдгрдорд╛ рд▓рдХреНрд╖реНрдп рдирд┐рд╢реНрдЪрд┐рддрдХреЛ рд╕рд╛рде рд╕рд╣реА SYNACK рдкреНрдпрд╛рдХреЗрдЯ рдЙрддреНрдкрдиреНрди рдЧрд░реНрдиреБ рд╣реЛ seqnum, рдЬреБрди рднрд╡рд┐рд╖реНрдпрдорд╛ SYN рдХреБрдХреАрджреНрд╡рд╛рд░рд╛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рд╣реБрдиреЗрдЫред рд╕рдмреИ рдкрд░рд┐рд╡рд░реНрддрдирд╣рд░реВ рдорд╛ рд╣реБрдиреНрдЫрдиреН process_tcp_syn() рд░ рд╡рд░рдкрд░рдХрд╛ рдХреНрд╖реЗрддреНрд░рд╣рд░реВред

рдкреНрдпрд╛рдХреЗрдЬ рдкреНрд░рдорд╛рдгрд┐рдХрд░рдг

рдЕрдЪрдореНрдордХреЛ рдХреБрд░рд╛, рдпрд╣рд╛рдБ рд╕рдмреИрднрдиреНрджрд╛ рдЙрд▓реНрд▓реЗрдЦрдиреАрдп рд░реЗрдЦрд╛ рд╣реЛ, рд╡рд╛ рдмрд░реБ, рдпрд╕рдХреЛ рдЯрд┐рдкреНрдкрдгреА:

/* Required to verify checksum calculation */
const void* data_end = (const void*)ctx->data_end;

рдХреЛрдбрдХреЛ рдкрд╣рд┐рд▓реЛ рд╕рдВрд╕реНрдХрд░рдг рд▓реЗрдЦреНрджрд╛, 5.1 рдХрд░реНрдиреЗрд▓ рдкреНрд░рдпреЛрдЧ рдЧрд░рд┐рдПрдХреЛ рдерд┐рдпреЛ, рдЬрд╕рдХреЛ рдкреНрд░рдорд╛рдгрд┐рдХрд░рдгрдХрд╛ рд▓рд╛рдЧрд┐ рдмреАрдЪрдорд╛ рднрд┐рдиреНрдирддрд╛ рдерд┐рдпреЛред data_end ╨╕ (const void*)ctx->data_endред рд▓реЗрдЦреНрдиреЗ рд╕рдордпрдорд╛, рдХрд░реНрдиреЗрд▓ 5.3.1 рдорд╛ рдпреЛ рд╕рдорд╕реНрдпрд╛ рдерд┐рдПрдиред рдпреЛ рд╕рдореНрднрд╡ рдЫ рдХрд┐ рдХрдореНрдкрд╛рдЗрд▓рд░рд▓реЗ рдлрд┐рд▓реНрдб рднрдиреНрджрд╛ рдлрд░рдХ рд░реВрдкрдорд╛ рд╕реНрдерд╛рдиреАрдп рдЪрд░ рдкрд╣реБрдБрдЪ рдЧрд░рд┐рд░рд╣реЗрдХреЛ рдерд┐рдпреЛред рдХрдерд╛рдХреЛ рдиреИрддрд┐рдХрддрд╛: рдзреЗрд░реИ рдиреЗрд╕реНрдЯрд┐рдЩ рд╣реБрдБрджрд╛ рдХреЛрдбрд▓рд╛рдИ рд╕рд░рд▓ рдмрдирд╛рдЙрди рдорджреНрджрдд рдЧрд░реНрди рд╕рдХреНрдЫред

рддреНрдпрд╕рдкрдЫрд┐ рдкреНрд░рдорд╛рдгрд┐рдХрд░рдгрдХреЛ рдорд╣рд┐рдорд╛рдХреЛ рд▓рд╛рдЧрд┐ рдирд┐рдпрдорд┐рдд рд▓рдореНрдмрд╛рдЗ рдЬрд╛рдБрдЪрд╣рд░реВ рдЫрдиреН; рдУ MAX_CSUM_BYTES рддрд▓

const u32 ip_len = ip->ihl * 4;
if ((void*)ip + ip_len > data_end) {
    return XDP_DROP; /* malformed packet */
}
if (ip_len > MAX_CSUM_BYTES) {
    return XDP_ABORTED; /* implementation limitation */
}

const u32 tcp_len = tcp->doff * 4;
if ((void*)tcp + tcp_len > (void*)ctx->data_end) {
    return XDP_DROP; /* malformed packet */
}
if (tcp_len > MAX_CSUM_BYTES) {
    return XDP_ABORTED; /* implementation limitation */
}

рдкреНрдпрд╛рдХреЗрдЬ рдЦреЛрд▓реНрджреИ

рд╣рд╛рдореА рднрд░реНрдЫреМрдВ seqnum ╨╕ acknum, ACK рд╕реЗрдЯ рдЧрд░реНрдиреБрд╣реЛрд╕реН (SYN рдкрд╣рд┐рд▓реЗ рдиреИ рд╕реЗрдЯ рдЧрд░рд┐рдПрдХреЛ рдЫ):

const u32 cookie = 42;
tcp->ack_seq = bpf_htonl(bpf_ntohl(tcp->seq) + 1);
tcp->seq = bpf_htonl(cookie);
tcp->ack = 1;

TCP рдкреЛрд░реНрдЯрд╣рд░реВ, IP рдареЗрдЧрд╛рдирд╛ рд░ MAC рдареЗрдЧрд╛рдирд╛рд╣рд░реВ рд╕реНрд╡реИрдк рдЧрд░реНрдиреБрд╣реЛрд╕реНред рдорд╛рдирдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп XDP рдХрд╛рд░реНрдпрдХреНрд░рдордмрд╛рдЯ рдкрд╣реБрдБрдЪрдпреЛрдЧреНрдп рдЫреИрди, рддреНрдпрд╕реИрд▓реЗ memcpy() - рдПрдЙрдЯрд╛ рдореНрдпрд╛рдХреНрд░реЛ рдЬрд╕рд▓реЗ рдХреНрд▓реНрдпрд╛рдЩреНрдЧ рднрд┐рддреНрд░реА рдХреБрд░рд╛рд╣рд░реВ рд▓реБрдХрд╛рдЙрдБрдЫред

const u16 temp_port = tcp->source;
tcp->source = tcp->dest;
tcp->dest = temp_port;

const u32 temp_ip = ip->saddr;
ip->saddr = ip->daddr;
ip->daddr = temp_ip;

struct ethhdr temp_ether = *ether;
memcpy(ether->h_dest, temp_ether.h_source, ETH_ALEN);
memcpy(ether->h_source, temp_ether.h_dest, ETH_ALEN);

рдЪреЗрдХрд╕рдорд╣рд░реВрдХреЛ рдкреБрди: рдЧрдгрдирд╛

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

рдо рдиреЛрдЯ рдЧрд░реНрдЫреБ рдХрд┐ рддреНрдпрд╣рд╛рдБ рдЫ 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-рдмрд┐рдЯ рдпреЛрдЧрдмрд╛рдЯ рдЪреЗрдХрд╕рдо рдмрдирд╛рдЙрдБрдЫред

TCP рд╣реНрдпрд╛рдиреНрдбрд╢реЗрдХ рдкреНрд░рдорд╛рдгреАрдХрд░рдг

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

рдмрд╛рд╣реНрдп рд╕рдЮреНрдЪрд╛рд░рд╕рдБрдЧ рд╕рдореНрдмрдиреНрдзрд┐рдд рдирдпрд╛рдБ TODOs рдХреЛ рд▓рд╛рдЧрд┐ рдкрд░рд┐рдЪрдп:

  • XDP рдХрд╛рд░реНрдпрдХреНрд░рдо рднрдгреНрдбрд╛рд░рдг рдЧрд░реНрди рд╕рдХреНрджреИрди cookie_seed (рдиреБрдирдХреЛ рдЧреЛрдкреНрдп рднрд╛рдЧ) рдПрдХ рд╡реИрд╢реНрд╡рд┐рдХ рдЪрд░рдорд╛, рддрдкрд╛рдИрдВрд▓рд╛рдИ рдХрд░реНрдиреЗрд▓рдорд╛ рднрдгреНрдбрд╛рд░рдг рдЪрд╛рд╣рд┐рдиреНрдЫ, рдЬрд╕рдХреЛ рдореВрд▓реНрдп рдЖрд╡рдзрд┐рдХ рд░реВрдкрдорд╛ рднрд░рдкрд░реНрджреЛ рдЬрдирд░реЗрдЯрд░рдмрд╛рдЯ рдЕрджреНрдпрд╛рд╡рдзрд┐рдХ рд╣реБрдиреЗрдЫред

  • рдпрджрд┐ SYN рдХреБрдХреА ACK рдкреНрдпрд╛рдХреЗрдЯрдорд╛ рдореЗрд▓ рдЦрд╛рдиреНрдЫ рднрдиреЗ, рддрдкрд╛рдИрдВрд▓реЗ рд╕рдиреНрджреЗрд╢ рдкреНрд░рд┐рдиреНрдЯ рдЧрд░реНрди рдЖрд╡рд╢реНрдпрдХ рдкрд░реНрджреИрди, рддрд░ рддреНрдпрд╕рдмрд╛рдЯ рдкреНрдпрд╛рдХреЗрдЯрд╣рд░реВ рдкрд╛рд╕ рдЧрд░реНрди рдЬрд╛рд░реА рд░рд╛рдЦреНрдирдХреЛ рд▓рд╛рдЧрд┐ рдкреНрд░рдорд╛рдгрд┐рдд рдЧреНрд░рд╛рд╣рдХрдХреЛ рдЖрдИрдкреА рд╕рдореНрдЭрдиреБрд╣реЛрд╕реНред

рд╡реИрдз рдЧреНрд░рд╛рд╣рдХ рдкреНрд░рдорд╛рдгрд┐рдХрд░рдг:

$ 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

рдЬрдм рддреНрдпрд╣рд╛рдБ рдкреНрд░рдорд╛рдгрд┐рдд рдЖрдИрдкреАрд╣рд░реВрдХреЛ рдХреБрдиреИ рд╕реВрдЪреА рдЫреИрди, рддреНрдпрд╣рд╛рдБ 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

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдердкреНрди