рд▓рд╣рд╛рди рдореБрд▓рд╛рдВрд╕рд╛рдареА рдмреАрдкреАрдПрдл, рднрд╛рдЧ рдПрдХ: рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдмреАрдкреАрдПрдл

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

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

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

рд▓реЗрдЦрд╛рдЪрд╛ рд╕рд╛рд░рд╛рдВрд╢

рдмреАрдкреАрдПрдл рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░рдЪрд╛ рдкрд░рд┐рдЪрдп. рдкреНрд░рдердо, рдЖрдореНрд╣реА BPF рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░рдЪреЗ рдмрд░реНрдбреНрд╕ рдЖрдп рд╡реНрд╣реНрдпреВ рдШреЗрдК рдЖрдгрд┐ рдореБрдЦреНрдп рдШрдЯрдХрд╛рдВрдЪреА рд░реВрдкрд░реЗрд╖рд╛ рджреЗрдК.

BPF рд╡реНрд╣рд░реНрдЪреНрдпреБрдЕрд▓ рдорд╢реАрдирдЪреА рд░рдЬрд┐рд╕реНрдЯрд░реНрд╕ рдЖрдгрд┐ рдХрдорд╛рдВрдб рд╕рд┐рд╕реНрдЯрдо. рдЖрдзреАрдЪ рд╕рдВрдкреВрд░реНрдг рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░рдЪреА рдХрд▓реНрдкрдирд╛ рдЕрд╕рд▓реНрдпрд╛рдиреЗ, рдЖрдореНрд╣реА BPF рд╡реНрд╣рд░реНрдЪреНрдпреБрдЕрд▓ рдорд╢реАрдирдЪреНрдпрд╛ рд╕рдВрд░рдЪрдиреЗрдЪреЗ рд╡рд░реНрдгрди рдХрд░реВ.

рдмреАрдкреАрдПрдл рд╡рд╕реНрддреВрдВрдЪреЗ рдЬреАрд╡рди рдЪрдХреНрд░, рдмреАрдкреАрдПрдлрдПрд╕ рдлрд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо. рдпрд╛ рд╡рд┐рднрд╛рдЧрд╛рдд, рдЖрдореНрд╣реА BPF рд╡рд╕реНрддреВрдВрдЪреЗ рдЬреАрд╡рди рдЪрдХреНрд░ рдЬрд╡рд│реВрди рдкрд╛рд╣реВ - рдХрд╛рд░реНрдпрдХреНрд░рдо рдЖрдгрд┐ рдирдХрд╛рд╢реЗ.

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

╨Я╨╕╤И╨╡╨╝ ╨┐╤А╨╛╨│╤А╨░╨╝╨╝╤Л BPF ╤Б ╨┐╨╛╨╝╨╛╤Й╤М╤О libbpf. рдЕрд░реНрдерд╛рдд, рдЖрдкрдг рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рд╡рд╛рдкрд░реВрди рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓рд┐рд╣реВ рд╢рдХрддрд╛. рдкрдг рдЕрд╡рдШрдб рдЖрд╣реЗ. рдЕрдзрд┐рдХ рд╡рд╛рд╕реНрддрд╡рд╡рд╛рджреА рдкрд░рд┐рд╕реНрдерд┐рддреАрд╕рд╛рдареА, рдЖрдгреНрд╡рд┐рдХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░рдиреА рдПрдХ рд▓рд╛рдпрдмреНрд░рд░реА рд╡рд┐рдХрд╕рд┐рдд рдХреЗрд▓реА libbpf. рдЖрдореНрд╣реА рдПрдХ рдореВрд▓рднреВрдд BPF рдНрдкреНрд▓рд┐рдХреЗрд╢рди рд╕реНрдХреЗрд▓реЗрдЯрди рддрдпрд╛рд░ рдХрд░реВ рдЬреНрдпрд╛рдЪрд╛ рдЖрдореНрд╣реА рдкреБрдвреАрд▓ рдЙрджрд╛рд╣рд░рдгрд╛рдВрдордзреНрдпреЗ рд╡рд╛рдкрд░ рдХрд░реВ.

рдХрд░реНрдирд▓ рдорджрддрдиреАрд╕. рдпреЗрдереЗ рдЖрдкрдг BPF рдкреНрд░реЛрдЧреНрд░рд╛рдореНрд╕ рдХрд░реНрдирд▓ рд╣реЗрд▓реНрдкрд░ рдлрдВрдХреНрд╢рдиреНрд╕рдордзреНрдпреЗ рдХрд╕реЗ рдкреНрд░рд╡реЗрд╢ рдХрд░реВ рд╢рдХрддрд╛рдд рддреЗ рд╢рд┐рдХреВ - рдПрдХ рд╕рд╛рдзрди рдЬреЗ рдирдХрд╛рд╢рд╛рдВрд╕рд╣, рдХреНрд▓рд╛рд╕рд┐рдХрдЪреНрдпрд╛ рддреБрд▓рдиреЗрдд рдирд╡реАрди BPF рдЪреНрдпрд╛ рдХреНрд╖рдорддрд╛рдВрдЪрд╛ рдореВрд▓рднреВрддрдкрдгреЗ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рддреЗ.

BPF рдкреНрд░реЛрдЧреНрд░рд╛рдордордзреВрди рдирдХрд╛рд╢рд╛рдВрдордзреНрдпреЗ рдкреНрд░рд╡реЗрд╢. рдпрд╛ рдЯрдкреНрдкреНрдпрд╛рдкрд░реНрдпрдВрдд, рдЖрдореНрд╣реА рдирдХрд╛рд╢реЗ рд╡рд╛рдкрд░рдгрд╛рд░реЗ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд╕реЗ рддрдпрд╛рд░ рдХрд░реВ рд╢рдХрддреЛ рд╣реЗ рд╕рдордЬреВрди рдШреЗрдгреНрдпрд╛рд╕рд╛рдареА рдЖрдореНрд╣рд╛рд▓рд╛ рдкреБрд░реЗрд╕реЗ рд╕рдордЬреЗрд▓. рдЖрдгрд┐ рдорд╣рд╛рди рдЖрдгрд┐ рдкрд░рд╛рдХреНрд░рдореА рдкрдбрддрд╛рд│рдХрд╛рдордзреНрдпреЗ рдПрдХ рдЭрдЯрдкрдЯ рдбреЛрдХрд╛рд╡реВ.

рд╡рд┐рдХрд╛рд╕ рд╕рд╛рдзрдиреЗ. рдкреНрд░рдпреЛрдЧрд╛рдВрд╕рд╛рдареА рдЖрд╡рд╢реНрдпрдХ рдпреБрдЯрд┐рд▓рд┐рдЯреАрдЬ рдЖрдгрд┐ рдХрд░реНрдирд▓ рдХрд╕реЗ рдПрдХрддреНрд░ рдХрд░рд╛рдпрдЪреЗ рдпрд╛рд╡рд░реАрд▓ рдорджрдд рд╡рд┐рднрд╛рдЧ.

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

рдмреАрдкреАрдПрдл рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░рдЪрд╛ рдкрд░рд┐рдЪрдп

рдЖрдореНрд╣реА рдмреАрдкреАрдПрдл рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░рдЪрд╛ рд╡рд┐рдЪрд╛рд░ рдХрд░рдгреНрдпрд╛рд╕ рд╕реБрд░реБрд╡рд╛рдд рдХрд░рдгреНрдпрд╛рдкреВрд░реНрд╡реА, рдЖрдореНрд╣реА рд╢реЗрд╡рдЯрдЪреНрдпрд╛ рд╡реЗрд│реА (рдУрд╣) рдпрд╛рдЪрд╛ рд╕рдВрджрд░реНрдн рдШреЗрдК рдХреНрд▓рд╛рд╕рд┐рдХ BPF, рдЬреЗ RISC рдорд╢реАрдирдЪреНрдпрд╛ рдЖрдЧрдордирд╛рд▓рд╛ рдкреНрд░рддрд┐рд╕рд╛рдж рдореНрд╣рдгреВрди рд╡рд┐рдХрд╕рд┐рдд рдХреЗрд▓реЗ рдЧреЗрд▓реЗ рдЖрдгрд┐ рдХрд╛рд░реНрдпрдХреНрд╖рдо рдкреЕрдХреЗрдЯ рдлрд┐рд▓реНрдЯрд░рд┐рдВрдЧрдЪреА рд╕рдорд╕реНрдпрд╛ рд╕реЛрдбрд╡рд▓реА. рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдЗрддрдХреЗ рдпрд╢рд╕реНрд╡реА рдард░рд▓реЗ рдХреА, рдмрд░реНрдХрд▓реЗ UNIX рдордзреНрдпреЗ рдирд╡реНрд╡рджрдЪреНрдпрд╛ рджрд╢рдХрд╛рдд рдЬрдиреНрдорд╛рд▓рд╛ рдЖрд▓реНрдпрд╛рдиреЗ, рддреЗ рдмрд╣реБрддреЗрдХ рд╡рд┐рджреНрдпрдорд╛рди рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдорд╡рд░ рдкреЛрд░реНрдЯ рдХреЗрд▓реЗ рдЧреЗрд▓реЗ, рд╡рд┐рд╕рд╛рд╡реНрдпрд╛ рджрд╢рдХрд╛рдд рдЯрд┐рдХреВрди рд░рд╛рд╣рд┐рд▓реЗ рдЖрдгрд┐ рдЕрдЬреВрдирд╣реА рдирд╡реАрди рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╢реЛрдзрдд рдЖрд╣реЗ.

рдирд╡реАрди BPF 64-рдмрд┐рдЯ рдорд╢реАрдиреНрд╕, рдХреНрд▓рд╛рдЙрдб рд╕реЗрд╡рд╛ рдЖрдгрд┐ SDN рддрдпрд╛рд░ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рд╕рд╛рдзрдирд╛рдВрдЪреА рд╡рд╛рдврддреА рдЧрд░рдЬ рдпрд╛рдВрдЪреНрдпрд╛ рд╕рд░реНрд╡рд╡реНрдпрд╛рдкреАрддреЗрд▓рд╛ рдкреНрд░рддрд┐рд╕рд╛рдж рдореНрд╣рдгреВрди рд╡рд┐рдХрд╕рд┐рдд рдХреЗрд▓реЗ рдЧреЗрд▓реЗ.SрдСрдлрд░-dрдкрд░рд┐рд╖реНрдХреГрдд nрдХрд╛рдо рдХрд░рдгреЗ). рдХреНрд▓рд╛рд╕рд┐рдХ BPF рд╕рд╛рдареА рд╕реБрдзрд╛рд░рд┐рдд рдмрджрд▓реА рдореНрд╣рдгреВрди рдХрд░реНрдирд▓ рдиреЗрдЯрд╡рд░реНрдХ рдЕрднрд┐рдпрдВрддреНрдпрд╛рдВрдиреА рд╡рд┐рдХрд╕рд┐рдд рдХреЗрд▓реЗрд▓реЗ, рдирд╡реАрди BPF рдЕрдХреНрд╖рд░рд╢рдГ рд╕рд╣рд╛ рдорд╣рд┐рдиреНрдпрд╛рдВрдирдВрддрд░ рд▓рд┐рдирдХреНрд╕ рд╕рд┐рд╕реНрдЯрдо рдЯреНрд░реЗрд╕ рдХрд░рдгреНрдпрд╛рдЪреНрдпрд╛ рдХрдареАрдг рдХрд╛рдорд╛рдд рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╕рд╛рдкрдбрд▓реЗ рдЖрдгрд┐ рдЖрддрд╛, рд╕рд╣рд╛ рд╡рд░реНрд╖рд╛рдирдВрддрд░, рдЖрдореНрд╣рд╛рд▓рд╛ рдлрдХреНрдд рдкреБрдвреАрд▓ рд▓реЗрдЦрд╛рдЪреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЕрд╕реЗрд▓. рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░рдЪреНрдпрд╛ рдХрд╛рд░реНрдпрдХреНрд░рдорд╛рдВрдЪреА рдпрд╛рджреА рдХрд░рд╛.

рдордЬреЗрджрд╛рд░ рдЪрд┐рддреНрд░реЗ

рддреНрдпрд╛рдЪреНрдпрд╛ рдореБрд│рд╛рдд, BPF рд╣реЗ рд╕рдБрдбрдмреЙрдХреНрд╕ рд╡реНрд╣рд░реНрдЪреНрдпреБрдЕрд▓ рдорд╢реАрди рдЖрд╣реЗ рдЬреЗ рддреБрдореНрд╣рд╛рд▓рд╛ рд╕реБрд░рдХреНрд╖реЗрд╢реА рддрдбрдЬреЛрдб рди рдХрд░рддрд╛ рдХрд░реНрдирд▓ рд╕реНрдкреЗрд╕рдордзреНрдпреЗ тАЬрдЖрд░рдмрд┐рдЯреНрд░рд░реАтАЭ рдХреЛрдб рдЪрд╛рд▓рд╡рдгреНрдпрд╛рдЪреА рдкрд░рд╡рд╛рдирдЧреА рджреЗрддреЗ. BPF рдкреНрд░реЛрдЧреНрд░рд╛рдореНрд╕ рд╡рд╛рдкрд░рдХрд░реНрддреНрдпрд╛рдЪреНрдпрд╛ рдЬрд╛рдЧреЗрдд рддрдпрд╛рд░ рдХреЗрд▓реЗ рдЬрд╛рддрд╛рдд, рдХрд░реНрдирд▓рдордзреНрдпреЗ рд▓реЛрдб рдХреЗрд▓реЗ рдЬрд╛рддрд╛рдд рдЖрдгрд┐ рдХрд╛рд╣реА рдЗрд╡реНрд╣реЗрдВрдЯ рд╕реНрддреНрд░реЛрддрд╛рд╢реА рдЬреЛрдбрд▓реЗрд▓реЗ рдЕрд╕рддрд╛рдд. рдПрдЦрд╛рджреА рдШрдЯрдирд╛ рдЕрд╕реВ рд╢рдХрддреЗ, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдиреЗрдЯрд╡рд░реНрдХ рдЗрдВрдЯрд░рдлреЗрд╕рд╡рд░ рдкреЕрдХреЗрдЯрдЪреЗ рд╡рд┐рддрд░рдг, рдХрд╛рд╣реА рдХрд░реНрдирд▓ рдлрдВрдХреНрд╢рди рд▓реЙрдиреНрдЪ рдХрд░рдгреЗ рдЗ. рдкреЕрдХреЗрдЬрдЪреНрдпрд╛ рдмрд╛рдмрддреАрдд, BPF рдкреНрд░реЛрдЧреНрд░рд╛рдорд▓рд╛ рдкреЕрдХреЗрдЬрдЪреНрдпрд╛ рдбреЗрдЯрд╛ рдЖрдгрд┐ рдореЗрдЯрд╛рдбреЗрдЯрд╛рдордзреНрдпреЗ рдкреНрд░рд╡реЗрд╢ рдЕрд╕реЗрд▓ (рд╡рд╛рдЪрдирд╛рд╕рд╛рдареА рдЖрдгрд┐ рд╢рдХреНрдпрддреЛ, рдкреНрд░реЛрдЧреНрд░рд╛рдордЪреНрдпрд╛ рдкреНрд░рдХрд╛рд░рд╛рдиреБрд╕рд╛рд░ рд▓реЗрдЦрдирд╛рд╕рд╛рдареА); рдХрд░реНрдирд▓ рдлрдВрдХреНрд╢рди рдЪрд╛рд▓рд╡рдгреНрдпрд╛рдЪреНрдпрд╛ рдмрд╛рдмрддреАрдд, рд╡рд┐рддрд░реНрдХ рдлрдВрдХреНрд╢рди, рдХрд░реНрдирд▓ рдореЗрдорд░реАрд╕рд╛рдареА рдкреЙрдЗрдВрдЯрд░ рдЗ.

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

рд▓рд╣рд╛рди рдореБрд▓рд╛рдВрд╕рд╛рдареА рдмреАрдкреАрдПрдл, рднрд╛рдЧ рдПрдХ: рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдмреАрдкреАрдПрдл

BPF рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░рдЪреА рд░рдЪрдирд╛, рдХрд╛рд╣реА рдкреНрд░рдорд╛рдгрд╛рдд, рдЖрдзреБрдирд┐рдХ рдорд╢реАрдирд╡рд░ рдХрд╛рд░реНрдпрдХреНрд╖рдорддреЗрдиреЗ рдЪрд╛рд▓рдгреНрдпрд╛рд╕рд╛рдареА рдХреЗрд▓реА рдЧреЗрд▓реА рд╣реЛрддреА. рд╣реЗ рдХрд╛рд░реНрдп рд╡реНрдпрд╡рд╣рд╛рд░рд╛рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА, BPF рдмрд╛рдИрдЯреЗрдХреЛрдб, рдПрдХрджрд╛ рдХрд░реНрдирд▓рдордзреНрдпреЗ рд▓реЛрдб рдХреЗрд▓реНрдпрд╛рдирдВрддрд░, JIT рдХрдВрдкрд╛рдЗрд▓рд░ рдирд╛рд╡рд╛рдЪреНрдпрд╛ рдШрдЯрдХрд╛рдЪрд╛ рд╡рд╛рдкрд░ рдХрд░реВрди рдореВрд│ рдХреЛрдбрдордзреНрдпреЗ рдЕрдиреБрд╡рд╛рджрд┐рдд рдХреЗрд▓реЗ рдЬрд╛рддреЗJUst In Time). рдкреБрдвреЗ, рдЬрд░ рддреБрдореНрд╣рд╛рд▓рд╛ рдЖрдард╡рдд рдЕрд╕реЗрд▓, рддрд░ рдХреНрд▓рд╛рд╕рд┐рдХ BPF рдордзреНрдпреЗ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд░реНрдирд▓рдордзреНрдпреЗ рд▓реЛрдб рдХреЗрд▓рд╛ рдЧреЗрд▓рд╛ рд╣реЛрддрд╛ рдЖрдгрд┐ рдЗрд╡реНрд╣реЗрдВрдЯ рд╕реНрддреНрд░реЛрддрд╛рд╢реА рдЕрдгреБрд░реАрддреНрдпрд╛ рдЬреЛрдбрд▓рд╛ рдЧреЗрд▓рд╛ рд╣реЛрддрд╛ - рд╕рд┐рдВрдЧрд▓ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓рдЪреНрдпрд╛ рд╕рдВрджрд░реНрднрд╛рдд. рдирд╡реАрди рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░рдордзреНрдпреЗ, рд╣реЗ рджреЛрди рдЯрдкреНрдкреНрдпрд╛рдВрдд рдШрдбрддреЗ - рдкреНрд░рдердо, рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рд╡рд╛рдкрд░реВрди рдХреЛрдб рдХрд░реНрдирд▓рдордзреНрдпреЗ рд▓реЛрдб рдХреЗрд▓рд╛ рдЬрд╛рддреЛ. bpf(2)рдЖрдгрд┐ рдирдВрддрд░, рдирдВрддрд░, рдкреНрд░реЛрдЧреНрд░рд╛рдордЪреНрдпрд╛ рдкреНрд░рдХрд╛рд░рд╛рдиреБрд╕рд╛рд░ рдмрджрд▓рдгрд╛рд░реНтАНрдпрд╛ рдЗрддрд░ рдпрдВрддреНрд░рдгрд╛рдВрджреНрд╡рд╛рд░реЗ, рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЗрд╡реНрд╣реЗрдВрдЯ рд╕реНрддреНрд░реЛрддрд╛рд╢реА рд╕рдВрд▓рдЧреНрди рд╣реЛрддреЛ.

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

рд▓рд╣рд╛рди рдореБрд▓рд╛рдВрд╕рд╛рдареА рдмреАрдкреАрдПрдл, рднрд╛рдЧ рдПрдХ: рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдмреАрдкреАрдПрдл

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

рдордЧ рдЖрдкрдг рдЖрддрд╛рдкрд░реНрдпрдВрдд рдХрд╛рдп рд╢рд┐рдХрд▓реЛ? рд╡рд╛рдкрд░рдХрд░реНрддрд╛ C рдордзреНрдпреЗ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓рд┐рд╣рд┐рддреЛ, рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рд╡рд╛рдкрд░реВрди рдХрд░реНрдирд▓рдордзреНрдпреЗ рд▓реЛрдб рдХрд░рддреЛ bpf(2), рдЬрд┐рдереЗ рддреЗ рдПрдХрд╛ рдкрдбрддрд╛рд│рдХрд╛рджреНрд╡рд╛рд░реЗ рддрдкрд╛рд╕рд▓реЗ рдЬрд╛рддреЗ рдЖрдгрд┐ рдореВрд│ рдмрд╛рдпрдХреЛрдбрдордзреНрдпреЗ рднрд╛рд╖рд╛рдВрддрд░рд┐рдд рдХреЗрд▓реЗ рдЬрд╛рддреЗ. рдордЧ рддреЛрдЪ рдХрд┐рдВрд╡рд╛ рджреБрд╕рд░рд╛ рд╡рд╛рдкрд░рдХрд░реНрддрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдорд▓рд╛ рдЗрд╡реНрд╣реЗрдВрдЯ рд╕реНрддреНрд░реЛрддрд╛рд╢реА рдЬреЛрдбрддреЛ рдЖрдгрд┐ рддреЛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рдгреНрдпрд╛рд╕ рд╕реБрд░рд╡рд╛рдд рдХрд░рддреЛ. рдЕрдиреЗрдХ рдХрд╛рд░рдгрд╛рдВрд╕рд╛рдареА рдмреВрдЯ рдЖрдгрд┐ рдХрдиреЗрдХреНрд╢рди рд╡реЗрдЧрд│реЗ рдХрд░рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ. рдкреНрд░рдердо, рд╕рддреНрдпрд╛рдкрдирдХрд░реНрддрд╛ рдЪрд╛рд▓рд╡рдгреЗ рддреБрд▓рдиреЗрдиреЗ рдорд╣рд╛рдЧ рдЖрд╣реЗ рдЖрдгрд┐ рддреЛрдЪ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЕрдиреЗрдХ рд╡реЗрд│рд╛ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░реВрди рдЖрдкрдг рд╕рдВрдЧрдгрдХрд╛рдЪрд╛ рд╡реЗрд│ рд╡рд╛рдпрд╛ рдШрд╛рд▓рд╡рддреЛ. рджреБрд╕рд░реЗ рдореНрд╣рдгрдЬреЗ, рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд╕рд╛ рдЬреЛрдбрд▓рд╛ рдЬрд╛рддреЛ рд╣реЗ рддреНрдпрд╛рдЪреНрдпрд╛ рдкреНрд░рдХрд╛рд░рд╛рд╡рд░ рдЕрд╡рд▓рдВрдмреВрди рдЕрд╕рддреЗ рдЖрдгрд┐ рдПрдХ рд╡рд░реНрд╖рд╛рдкреВрд░реНрд╡реА рд╡рд┐рдХрд╕рд┐рдд рдХреЗрд▓реЗрд▓рд╛ рдПрдХ "рд╕рд╛рд░реНрд╡рддреНрд░рд┐рдХ" рдЗрдВрдЯрд░рдлреЗрд╕ рдирд╡реАрди рдкреНрд░рдХрд╛рд░рдЪреНрдпрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдорд╕рд╛рдареА рдпреЛрдЧреНрдп рдирд╕реВ рд╢рдХрддреЛ. (рдЬрд░реА рдЖрддрд╛ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдЕрдзрд┐рдХ рдкрд░рд┐рдкрдХреНрд╡ рд╣реЛрдд рдЪрд╛рд▓рд▓реЗ рдЖрд╣реЗ, рддрд░реАрд╣реА рд╣рд╛ рдЗрдВрдЯрд░рдлреЗрд╕ рд╕реНрддрд░рд╛рд╡рд░ рдПрдХрддреНрд░рд┐рдд рдХрд░рдгреНрдпрд╛рдЪрд╛ рд╡рд┐рдЪрд╛рд░ рдЖрд╣реЗ. libbpf.)

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

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

рд▓рд╣рд╛рди рдореБрд▓рд╛рдВрд╕рд╛рдареА рдмреАрдкреАрдПрдл, рднрд╛рдЧ рдПрдХ: рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдмреАрдкреАрдПрдл

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

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

рдЕрд╢рд╛ рдХреНрд╖рдорддреЗрдЪреА рдЙрдкрд╕реНрдерд┐рддреА рдмреАрдкреАрдПрдлрд▓рд╛ рдХрд░реНрдирд▓рдЪрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдПрдХ рд╕рд╛рд░реНрд╡рддреНрд░рд┐рдХ рд╕рд╛рдзрди рдмрдирд╡рддреЗ, рдЬреНрдпрд╛рдЪреА рд╕рд░рд╛рд╡рд╛рдиреЗ рдкреБрд╖реНрдЯреА рдХреЗрд▓реА рдЬрд╛рддреЗ: рдмреАрдкреАрдПрдлрдордзреНрдпреЗ рдЕрдзрд┐рдХрд╛рдзрд┐рдХ рдирд╡реАрди рдкреНрд░рдХрд╛рд░рдЪреЗ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЬреЛрдбрд▓реЗ рдЬрд╛рддрд╛рдд, рдЕрдзрд┐рдХрд╛рдзрд┐рдХ рдореЛрдареНрдпрд╛ рдХрдВрдкрдиреНрдпрд╛ 24├Ч7 рд▓рдврд╛рдК рд╕рд░реНрд╡реНрд╣рд░рд╡рд░ рдмреАрдкреАрдПрдл рд╡рд╛рдкрд░рддрд╛рдд, рдЕрдзрд┐рдХрд╛рдзрд┐рдХ. рд╕реНрдЯрд╛рд░реНрдЯрдЕрдкреНрд╕ рддреНрдпрд╛рдВрдЪрд╛ рд╡реНрдпрд╡рд╕рд╛рдп рдмреАрдкреАрдПрдлрд╡рд░ рдЖрдзрд╛рд░рд┐рдд рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рд╕реЛрд▓реНрдпреВрд╢рдиреНрд╕рд╡рд░ рддрдпрд╛рд░ рдХрд░рддрд╛рдд. BPF рд╕рд░реНрд╡рддреНрд░ рд╡рд╛рдкрд░рд▓рд╛ рдЬрд╛рддреЛ: DDoS рд╣рд▓реНрд▓реНрдпрд╛рдВрдкрд╛рд╕реВрди рд╕рдВрд░рдХреНрд╖рдг рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА, SDN рддрдпрд╛рд░ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА (рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, kubernetes рд╕рд╛рдареА рдиреЗрдЯрд╡рд░реНрдХ рд▓рд╛рдЧреВ рдХрд░рдгреЗ), рдореБрдЦреНрдп рд╕рд┐рд╕реНрдЯрдо рдЯреНрд░реЗрд╕рд┐рдВрдЧ рдЯреВрд▓ рдЖрдгрд┐ рд╕реНрдЯреЕрдЯрд┐рд╕реНрдЯрд┐рдХреНрд╕ рдХрд▓реЗрдХреНрдЯрд░ рдореНрд╣рдгреВрди, рдШреБрд╕рдЦреЛрд░реА рд╢реЛрдз рдкреНрд░рдгрд╛рд▓реА рдЖрдгрд┐ рд╕рдБрдбрдмреЙрдХреНрд╕ рд╕рд┐рд╕реНрдЯрдо рдЗ.

рд▓реЗрдЦрд╛рдЪрд╛ рд╡рд┐рд╣рдВрдЧрд╛рд╡рд▓реЛрдХрди рднрд╛рдЧ рдпреЗрдереЗ рдкреВрд░реНрдг рдХрд░реВ рдЖрдгрд┐ рд╡реНрд╣рд░реНрдЪреНрдпреБрдЕрд▓ рдорд╢реАрди рдЖрдгрд┐ BPF рдЗрдХреЛрд╕рд┐рд╕реНрдЯрдо рдЕрдзрд┐рдХ рддрдкрд╢реАрд▓рд╡рд╛рд░ рдкрд╛рд╣реВ.

рд╡рд┐рд╖рдпрд╛рдВрддрд░: рдЙрдкрдпреБрдХреНрддрддрд╛

рдЦрд╛рд▓реАрд▓ рд╡рд┐рднрд╛рдЧрд╛рдВрдордзреАрд▓ рдЙрджрд╛рд╣рд░рдгреЗ рдЪрд╛рд▓рд╡рдгреНрдпрд╛рд╕ рд╕рдХреНрд╖рдо рд╣реЛрдгреНрдпрд╛рд╕рд╛рдареА, рддреБрдореНрд╣рд╛рд▓рд╛ рдЕрдиреЗрдХ рдЙрдкрдпреБрдХреНрддрддрд╛ рдЖрд╡рд╢реНрдпрдХ рдЕрд╕реВ рд╢рдХрддрд╛рдд, рдХрд┐рдорд╛рди llvm/clang bpf рд╕рдорд░реНрдердирд╛рд╕рд╣ рдЖрдгрд┐ bpftool. рд╡рд┐рднрд╛рдЧрд╛рдд рд╡рд┐рдХрд╛рд╕ рд╕рд╛рдзрдиреЗ рддреБрдореНрд╣реА рдпреБрдЯрд┐рд▓рд┐рдЯреАрдЬ рдПрдХрддреНрд░ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рд╕реВрдЪрдирд╛ рд╡рд╛рдЪреВ рд╢рдХрддрд╛, рддрд╕реЗрдЪ рддреБрдордЪреЗ рдХрд░реНрдирд▓. рдЖрдордЪреНрдпрд╛ рд╕рд╛рджрд░реАрдХрд░рдгрд╛рддреАрд▓ рд╕реБрд╕рдВрд╡рд╛рдж рдмрд┐рдШрдбреВ рдирдпреЗ рдореНрд╣рдгреВрди рд╣рд╛ рд╡рд┐рднрд╛рдЧ рдЦрд╛рд▓реА рдареЗрд╡рд▓рд╛ рдЖрд╣реЗ.

рдмреАрдкреАрдПрдл рд╡реНрд╣рд░реНрдЪреНрдпреБрдЕрд▓ рдорд╢реАрди рд░рдЬрд┐рд╕реНрдЯрд░реНрд╕ рдЖрдгрд┐ рдЗрдВрд╕реНрдЯреНрд░рдХреНрд╢рди рд╕рд┐рд╕реНрдЯрдо

рдмреАрдкреАрдПрдлрдЪреЗ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдЖрдгрд┐ рдХрдорд╛рдВрдб рд╕рд┐рд╕реНрдЯрдо рд╣реЗ рд▓рдХреНрд╖рд╛рдд рдШреЗрдКрди рд╡рд┐рдХрд╕рд┐рдд рдХреЗрд▓реЗ рдЧреЗрд▓реЗ рдЖрд╣реЗ рдХреА рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╕реА рднрд╛рд╖реЗрдд рд▓рд┐рд╣рд┐рд▓реЗ рдЬрд╛рддреАрд▓ рдЖрдгрд┐ рдХрд░реНрдирд▓рдордзреНрдпреЗ рд▓реЛрдб рдХреЗрд▓реНрдпрд╛рдирдВрддрд░, рдореВрд│ рдХреЛрдбрдордзреНрдпреЗ рдЕрдиреБрд╡рд╛рджрд┐рдд рдХреЗрд▓реЗ рдЬрд╛рддреАрд▓. рдореНрд╣рдгреВрди, рдЖрдзреБрдирд┐рдХ рдорд╢реАрдиреНрд╕рдЪреНрдпрд╛ рдХреНрд╖рдорддрд╛рдВрдЪрд╛ рдЧрдгрд┐рддреА рдЕрд░реНрдерд╛рдиреЗ рдЫреЗрджрдирдмрд┐рдВрджреВрдХрдбреЗ рд▓рдХреНрд╖ рджреЗрдКрди, рд░рдЬрд┐рд╕реНрдЯрд░реНрд╕рдЪреА рд╕рдВрдЦреНрдпрд╛ рдЖрдгрд┐ рдЖрджреЗрд╢рд╛рдВрдЪрд╛ рд╕рдВрдЪ рдирд┐рд╡рдбрд▓рд╛ рдЧреЗрд▓рд╛. рдпрд╛рд╡реНрдпрддрд┐рд░рд┐рдХреНрдд, рдкреНрд░реЛрдЧреНрд░рд╛рдореНрд╕рд╡рд░ рд╡рд┐рд╡рд┐рдз рдирд┐рд░реНрдмрдВрдз рд▓рд╛рджрдгреНрдпрд╛рдд рдЖрд▓реЗ рд╣реЛрддреЗ, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдЕрд▓реАрдХрдбреЗ рдкрд░реНрдпрдВрдд рд▓реВрдк рдЖрдгрд┐ рд╕рдмрд░реВрдЯреАрди рд▓рд┐рд╣рд┐рдгреЗ рд╢рдХреНрдп рдирд╡реНрд╣рддреЗ рдЖрдгрд┐ рд╕реВрдЪрдирд╛рдВрдЪреА рд╕рдВрдЦреНрдпрд╛ 4096 рдкрд░реНрдпрдВрдд рдорд░реНрдпрд╛рджрд┐рдд рд╣реЛрддреА (рдЖрддрд╛ рд╡рд┐рд╢реЗрд╖рд╛рдзрд┐рдХрд╛рд░ рдкреНрд░рд╛рдкреНрдд рдкреНрд░реЛрдЧреНрд░рд╛рдо рдПрдХ рджрд╢рд▓рдХреНрд╖ рд╕реВрдЪрдирд╛ рд▓реЛрдб рдХрд░реВ рд╢рдХрддрд╛рдд).

BPF рдордзреНрдпреЗ рдЕрдХрд░рд╛ рд╡рд╛рдкрд░рдХрд░реНрддрд╛-рдкреНрд░рд╡реЗрд╢рдпреЛрдЧреНрдп 64-рдмрд┐рдЯ рдиреЛрдВрджрдгреА рдЖрд╣реЗрдд r0-r10 рдЖрдгрд┐ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд╛рдЙрдВрдЯрд░. рдиреЛрдВрджрдгреА рдХрд░рд╛ r10 рдлреНрд░реЗрдо рдкреЙрдЗрдВрдЯрд░ рдЖрд╣реЗ рдЖрдгрд┐ рддреЗ рдХреЗрд╡рд│ рд╡рд╛рдЪрдиреАрдп рдЖрд╣реЗ. рдкреНрд░реЛрдЧреНрд░рд╛рдореНрд╕рдирд╛ рд░рдирдЯрд╛рдЗрдорд╡рд░ 512-рдмрд╛рдЗрдЯ рд╕реНрдЯреЕрдХ рдЖрдгрд┐ рдирдХрд╛рд╢рд╛рдВрдЪреНрдпрд╛ рд╕реНрд╡рд░реВрдкрд╛рдд рдЕрдорд░реНрдпрд╛рджрд┐рдд рд╕рд╛рдорд╛рдпрд┐рдХ рдореЗрдорд░реАрдордзреНрдпреЗ рдкреНрд░рд╡реЗрд╢ рдЕрд╕рддреЛ.

BPF рдкреНрд░реЛрдЧреНрд░рд╛рдореНрд╕рдирд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо-рдкреНрд░рдХрд╛рд░ рдХрд░реНрдирд▓ рдорджрддрдиреАрд╕рд╛рдВрдЪрд╛ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕рдВрдЪ рдЖрдгрд┐ рдЕрдЧрджреА рдЕрд▓реАрдХрдбреЗ, рдирд┐рдпрдорд┐рдд рдХрд╛рд░реНрдпреЗ рдЪрд╛рд▓рд╡рдгреНрдпрд╛рдЪреА рдкрд░рд╡рд╛рдирдЧреА рдЖрд╣реЗ. рдкреНрд░рддреНрдпреЗрдХ рдХреЙрд▓ рдлрдВрдХреНрд╢рди рдкрд╛рдЪ рд╡рд┐рддрд░реНрдХ рдШреЗрдК рд╢рдХрддрд╛рдд, рдЬреЗ рд░рдЬрд┐рд╕реНрдЯрд░рдордзреНрдпреЗ рдкрд╛рд╕ рдХреЗрд▓реЗ рдЬрд╛рддрд╛рдд r1-r5, рдЖрдгрд┐ рдкрд░рддрд╛рд╡рд╛ рдореВрд▓реНрдп рдХрдбреЗ рдкрд╛рд╕ рдХреЗрд▓реЗ рдЬрд╛рддреЗ r0. рдлрдВрдХреНрд╢рдирдордзреВрди рдкрд░рдд рдЖрд▓реНрдпрд╛рдирдВрддрд░, рд░рдЬрд┐рд╕реНрдЯрд░рдордзреАрд▓ рд╕рд╛рдордЧреНрд░реАрдЪреА рд╣рдореА рджрд┐рд▓реА рдЬрд╛рддреЗ r6-r9 рдмрджрд▓рдгрд╛рд░ рдирд╛рд╣реА.

рдХрд╛рд░реНрдпрдХреНрд╖рдо рдкреНрд░реЛрдЧреНрд░рд╛рдо рднрд╛рд╖рд╛рдВрддрд░рд╛рд╕рд╛рдареА, рдиреЛрдВрджрдгреА r0-r11 рд╕рдзреНрдпрд╛рдЪреНрдпрд╛ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░рдЪреА ABI рд╡реИрд╢рд┐рд╖реНрдЯреНрдпреЗ рд╡рд┐рдЪрд╛рд░рд╛рдд рдШреЗрдКрди, рд╕рд░реНрд╡ рд╕рдорд░реНрдерд┐рдд рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░реНрд╕ рд░рд┐рдЕрд▓ рд░рдЬрд┐рд╕реНрдЯрд░реНрд╕рдордзреНрдпреЗ рдЕрдирдиреНрдпрдкрдгреЗ рдореЕрдк рдХреЗрд▓реНрдпрд╛ рдЬрд╛рддрд╛рдд. рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рд╕рд╛рдареА x86_64 рдиреЛрдВрджрдгреА r1-r5, рдлрдВрдХреНрд╢рди рдкреЕрд░рд╛рдореАрдЯрд░реНрд╕ рдкрд╛рд╕ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рд╡рд╛рдкрд░рд▓реЗ рдЬрд╛рддреЗ, рд╡рд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХреЗрд▓реЗ рдЬрд╛рддреЗ rdi, rsi, rdx, rcx, r8, рдЬреЗ рдлрдВрдХреНрд╢рдиреНрд╕рд╡рд░ рдкреЕрд░рд╛рдореАрдЯрд░реНрд╕ рдкрд╛рд╕ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рд╡рд╛рдкрд░рд▓реЗ рдЬрд╛рддрд╛рдд x86_64. рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдбрд╛рд╡реАрдХрдбреАрд▓ рдХреЛрдб рдЙрдЬрд╡реАрдХрдбреАрд▓ рдХреЛрдбрдордзреНрдпреЗ рдпрд╛рдкреНрд░рдорд╛рдгреЗ рдЕрдиреБрд╡рд╛рджрд┐рдд рд╣реЛрддреЛ:

1:  (b7) r1 = 1                    mov    $0x1,%rdi
2:  (b7) r2 = 2                    mov    $0x2,%rsi
3:  (b7) r3 = 3                    mov    $0x3,%rdx
4:  (b7) r4 = 4                    mov    $0x4,%rcx
5:  (b7) r5 = 5                    mov    $0x5,%r8
6:  (85) call pc+1                 callq  0x0000000000001ee8

рдиреЛрдВрджрдгреА рдХрд░рд╛ r0 рдкреНрд░реЛрдЧреНрд░рд╛рдордЪреНрдпрд╛ рдЕрдВрдорд▓рдмрдЬрд╛рд╡рдгреАрдЪрд╛ рдкрд░рд┐рдгрд╛рдо рдЖрдгрд┐ рд░рдЬрд┐рд╕реНрдЯрд░рдордзреНрдпреЗ рдкрд░рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рджреЗрдЦреАрд▓ рд╡рд╛рдкрд░рд▓реЗ рдЬрд╛рддреЗ r1 рдкреНрд░реЛрдЧреНрд░рд╛рдорд▓рд╛ рд╕рдВрджрд░реНрднрд╛рд╕рд╛рдареА рдПрдХ рдкреЙрдЗрдВрдЯрд░ рдкрд╛рд╕ рдХреЗрд▓рд╛ рдЬрд╛рддреЛ - рдкреНрд░реЛрдЧреНрд░рд╛рдордЪреНрдпрд╛ рдкреНрд░рдХрд╛рд░рд╛рд╡рд░ рдЕрд╡рд▓рдВрдмреВрди, рд╣реЗ рдЕрд╕реВ рд╢рдХрддреЗ, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдПрдХ рд░рдЪрдирд╛ struct xdp_md (XDP рд╕рд╛рдареА) рдХрд┐рдВрд╡рд╛ рд░рдЪрдирд╛ struct __sk_buff (рд╡реЗрдЧрд╡реЗрдЧрд│реНрдпрд╛ рдиреЗрдЯрд╡рд░реНрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд╕рд╛рдареА) рдХрд┐рдВрд╡рд╛ рд╕рдВрд░рдЪрдирд╛ struct pt_regs (рд╡рд┐рд╡рд┐рдз рдкреНрд░рдХрд╛рд░рдЪреНрдпрд╛ рдЯреНрд░реЗрд╕рд┐рдВрдЧ рдкреНрд░реЛрдЧреНрд░рд╛рдорд╕рд╛рдареА), рдЗ.

рддрд░, рдЖрдордЪреНрдпрд╛рдХрдбреЗ рд░рдЬрд┐рд╕реНрдЯрд░реНрд╕, рдХрд░реНрдирд▓ рд╣реЗрд▓реНрдкрд░, рд╕реНрдЯреЕрдХ, рдХреЙрдиреНрдЯреЗрдХреНрд╕реНрдЯ рдкреЙрдЗрдВрдЯрд░ рдЖрдгрд┐ рд╕рд╛рдорд╛рдпрд┐рдХ рдореЗрдорд░реА рдирдХрд╛рд╢рд╛рдВрдЪреНрдпрд╛ рд╕реНрд╡рд░реВрдкрд╛рдд рд╣реЛрддреА. рдкреНрд░рд╡рд╛рд╕рд╛рдд рд╣реЗ рд╕рд░реНрд╡ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ рдЕрд╕реЗ рдирд╛рд╣реА, рдкрдг...

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

рд▓рд╣рд╛рди рдореБрд▓рд╛рдВрд╕рд╛рдареА рдмреАрдкреАрдПрдл, рднрд╛рдЧ рдПрдХ: рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдмреАрдкреАрдПрдл

рддреЛ рдЖрд╣реЗ Code - рд╣реЗ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдЪреЗ рдПрдиреНрдХреЛрдбрд┐рдВрдЧ рдЖрд╣реЗ, Dst/Src рдЕрдиреБрдХреНрд░рдореЗ рдкреНрд░рд╛рдкреНрддрдХрд░реНрддрд╛ рдЖрдгрд┐ рд╕реНрддреНрд░реЛрддрд╛рдЪреЗ рдПрдиреНрдХреЛрдбрд┐рдВрдЧ рдЖрд╣реЗрдд, Off - 16-рдмрд┐рдЯ рд╕реНрд╡рд╛рдХреНрд╖рд░реА рдХреЗрд▓реЗрд▓реЗ рдЗрдВрдбреЗрдВрдЯреЗрд╢рди, рдЖрдгрд┐ Imm рдХрд╛рд╣реА рд╕реВрдЪрдирд╛рдВрдордзреНрдпреЗ (cBPF рд╕реНрдерд┐рд░ K рдкреНрд░рдорд╛рдгреЗ) рд╡рд╛рдкрд░рд▓реЗрд▓рд╛ 32-рдмрд┐рдЯ рд╕реНрд╡рд╛рдХреНрд╖рд░реА рдХреЗрд▓реЗрд▓рд╛ рдкреВрд░реНрдгрд╛рдВрдХ рдЖрд╣реЗ. рдПрдиреНрдХреЛрдбрд┐рдВрдЧ Code рджреЛрди рдкреНрд░рдХрд╛рд░рд╛рдВрдкреИрдХреА рдПрдХ рдЖрд╣реЗ:

рд▓рд╣рд╛рди рдореБрд▓рд╛рдВрд╕рд╛рдареА рдмреАрдкреАрдПрдл, рднрд╛рдЧ рдПрдХ: рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдмреАрдкреАрдПрдл

рд╕реВрдЪрдирд╛ рд╡рд░реНрдЧ 0, 1, 2, 3 рдореЗрдорд░реАрд╕рд╣ рдХрд╛рд░реНрдп рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдХрдорд╛рдВрдб рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛рдд. рддреЗ рдореНрд╣рдЯрд▓реЗ рдЬрд╛рддреЗ, BPF_LD, BPF_LDX, BPF_ST, BPF_STX, рдЕрдиреБрдХреНрд░рдореЗ. рдЗрдпрддреНрддрд╛ 4, 7 (BPF_ALU, BPF_ALU64) ALU рд╕реВрдЪрдирд╛рдВрдЪрд╛ рд╕рдВрдЪ рддрдпрд╛рд░ рдХрд░рд╛. рдЗрдпрддреНрддрд╛ 5, 6 (BPF_JMP, BPF_JMP32) рдордзреНрдпреЗ рдЬрдВрдк рд╕реВрдЪрдирд╛ рдЕрд╕рддрд╛рдд.

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

рдЬреЗрд╡реНрд╣рд╛ рдЖрдореНрд╣реА рд╡реИрдпрдХреНрддрд┐рдХ рд╕реВрдЪрдирд╛рдВрдмрджреНрджрд▓ рдмреЛрд▓рддреЛ, рддреЗрд╡реНрд╣рд╛ рдЖрдореНрд╣реА рдореБрдЦреНрдп рдлрд╛рдЗрд▓реНрд╕рдЪрд╛ рд╕рдВрджрд░реНрдн рдШреЗрдК bpf.h ╨╕ bpf_common.h, рдЬреЗ BPF рдирд┐рд░реНрджреЗрд╢рд╛рдВрдЪреЗ рд╕рдВрдЦреНрдпрд╛рддреНрдордХ рдХреЛрдб рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛рдд. рддреБрдореНрд╣реА рд╕реНрд╡рддрдГ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░рдЪрд╛ рдЕрднреНрдпрд╛рд╕ рдХрд░рдд рдЕрд╕рддрд╛рдирд╛ рдЖрдгрд┐/рдХрд┐рдВрд╡рд╛ рдмрд╛рдпрдирд░реА рдкрд╛рд░реНрд╕ рдХрд░рдд рдЕрд╕рддрд╛рдирд╛, рддреБрдореНрд╣рд╛рд▓рд╛ рдХреНрд▓рд┐рд╖реНрдЯрддреЗрдЪреНрдпрд╛ рдХреНрд░рдорд╛рдиреЗ рдХреНрд░рдорд╡рд╛рд░реА рд▓рд╛рд╡рд▓реЗрд▓реНрдпрд╛ рдЦрд╛рд▓реАрд▓ рд╕реНрд░реЛрддрд╛рдВрдордзреНрдпреЗ рд╢рдмреНрджрд╛рд░реНрде рд╕рд╛рдкрдбрддреАрд▓: рдЕрдирдзрд┐рдХреГрдд eBPF рддрдкрд╢реАрд▓, BPF рдЖрдгрд┐ XDP рд╕рдВрджрд░реНрдн рдорд╛рд░реНрдЧрджрд░реНрд╢рдХ, рд╕реВрдЪрдирд╛ рд╕рдВрдЪ, Documentation/networking/filter.txt рдЖрдгрд┐, рдЕрд░реНрдерд╛рддрдЪ, рд▓рд┐рдирдХреНрд╕ рд╕реНрддреНрд░реЛрдд рдХреЛрдбрдордзреНрдпреЗ - рд╕рддреНрдпрд╛рдкрдирдХрд░реНрддрд╛, рдЬреЗрдЖрдпрдЯреА, рдмреАрдкреАрдПрдл рдЗрдВрдЯрд░рдкреНрд░рд┐рдЯрд░.

рдЙрджрд╛рд╣рд░рдг: рддреБрдордЪреНрдпрд╛ рдбреЛрдХреНрдпрд╛рдд рдмреАрдкреАрдПрдл рд╡реЗрдЧрд│реЗ рдХрд░рдгреЗ

рдЪрд▓рд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдкрд╛рд╣реВ рдЬреНрдпрд╛рдордзреНрдпреЗ рдЖрдкрдг рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╕рдВрдХрд▓рд┐рдд рдХрд░рддреЛ readelf-example.c рдЖрдгрд┐ рдкрд░рд┐рдгрд╛рдореА рдмрд╛рдпрдирд░реА рдкрд╣рд╛. рдЖрдореНрд╣реА рдореВрд│ рд╕рд╛рдордЧреНрд░реА рдЙрдШрдб рдХрд░реВ readelf-example.c рдЦрд╛рд▓реА, рдЖрдореНрд╣реА рдмрд╛рдпрдирд░реА рдХреЛрдбрдордзреВрди рддреНрдпрд╛рдЪреЗ рддрд░реНрдХ рдкреБрдирд░реНрд╕рдВрдЪрдпрд┐рдд рдХреЗрд▓реНрдпрд╛рдирдВрддрд░:

$ clang -target bpf -c readelf-example.c -o readelf-example.o -O2
$ llvm-readelf -x .text readelf-example.o
Hex dump of section '.text':
0x00000000 b7000000 01000000 15010100 00000000 ................
0x00000010 b7000000 02000000 95000000 00000000 ................

рдЖрдЙрдЯрдкреБрдЯрдордзреАрд▓ рдкрд╣рд┐рд▓рд╛ рд╕реНрддрдВрдн readelf рдПрдХ рдЗрдВрдбреЗрдВрдЯреЗрд╢рди рдЖрд╣реЗ рдЖрдгрд┐ рдЖрдордЪреНрдпрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдордордзреНрдпреЗ рдЕрд╢рд╛ рдкреНрд░рдХрд╛рд░реЗ рдЪрд╛рд░ рдХрдорд╛рдВрдб рдЖрд╣реЗрдд:

Code Dst Src Off  Imm
b7   0   0   0000 01000000
15   0   1   0100 00000000
b7   0   0   0000 02000000
95   0   0   0000 00000000

рдХрдорд╛рдВрдб рдХреЛрдб рд╕рдорд╛рди рдЖрд╣реЗрдд b7, 15, b7 ╨╕ 95. рд▓рдХреНрд╖рд╛рдд рдареЗрд╡рд╛ рдХреА рдХрдореАрдд рдХрдореА рдорд╣рддреНрддреНрд╡рдкреВрд░реНрдг рддреАрди рдмрд┐рдЯреНрд╕ рдирд┐рд░реНрджреЗрд╢ рд╡рд░реНрдЧ рдЖрд╣реЗрдд. рдЖрдордЪреНрдпрд╛ рдмрд╛рдмрддреАрдд, рд╕рд░реНрд╡ рд╕реВрдЪрдирд╛рдВрдЪрд╛ рдЪреМрдерд╛ рднрд╛рдЧ рд░рд┐рдХрд╛рдорд╛ рдЖрд╣реЗ, рддреНрдпрд╛рдореБрд│реЗ рд╕реВрдЪрдирд╛ рд╡рд░реНрдЧ рдЕрдиреБрдХреНрд░рдореЗ 7, 5, 7, 5 рдЖрд╣реЗрдд. рд╡рд░реНрдЧ 7 рдЖрд╣реЗ BPF_ALU64, рдЖрдгрд┐ 5 рдЖрд╣реЗ BPF_JMP. рджреЛрдиреНрд╣реА рд╡рд░реНрдЧрд╛рдВрд╕рд╛рдареА, рд╕реВрдЪрдирд╛рдВрдЪреЗ рд╕реНрд╡рд░реВрдк рд╕рд╛рд░рдЦреЗрдЪ рдЖрд╣реЗ (рд╡рд░ рдкрд╣рд╛) рдЖрдгрд┐ рдЖрдореНрд╣реА рдЖрдордЪрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдпрд╛рдкреНрд░рдорд╛рдгреЗ рдкреБрдиреНрд╣рд╛ рд▓рд┐рд╣реВ рд╢рдХрддреЛ (рддреНрдпрд╛рдЪрд╡реЗрд│реА рдЖрдореНрд╣реА рдЙрд░реНрд╡рд░рд┐рдд рд╕реНрддрдВрдн рдорд╛рдирд╡реА рд╕реНрд╡рд░реВрдкрд╛рдд рдкреБрдиреНрд╣рд╛ рд▓рд┐рд╣реВ):

Op S  Class   Dst Src Off  Imm
b  0  ALU64   0   0   0    1
1  0  JMP     0   1   1    0
b  0  ALU64   0   0   0    2
9  0  JMP     0   0   0    0

рдСрдкрд░реЗрд╢рди b рд╡рд░реНрдЧ ALU64 - рд╣реЗ рдЖрд╣реЗ BPF_MOV. рд╣реЗ рдЧрдВрддрд╡реНрдп рд░рдЬрд┐рд╕реНрдЯрд░рд▓рд╛ рдореВрд▓реНрдп рдирд┐рдпреБрдХреНрдд рдХрд░рддреЗ. рдмрд┐рдЯ рд╕реЗрдЯ рдХреЗрд▓реЗ рдЕрд╕рд▓реНрдпрд╛рд╕ s (рд╕реНрд░реЛрдд), рдирдВрддрд░ рдореВрд▓реНрдп рд╕реНрддреНрд░реЛрдд рд░рдЬрд┐рд╕реНрдЯрд░рдордзреВрди рдШреЗрддрд▓реЗ рдЬрд╛рддреЗ, рдЖрдгрд┐ рдЬрд░, рдЖрдордЪреНрдпрд╛ рдмрд╛рдмрддреАрдд, рддреЗ рд╕реЗрдЯ рдХреЗрд▓реЗрд▓реЗ рдирд╕реЗрд▓, рддрд░ рдореВрд▓реНрдп рдлреАрд▓реНрдбрдордзреВрди рдШреЗрддрд▓реЗ рдЬрд╛рддреЗ Imm. рдореНрд╣рдгреВрди рдкрд╣рд┐рд▓реНрдпрд╛ рдЖрдгрд┐ рддрд┐рд╕рд▒реНрдпрд╛ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдордзреНрдпреЗ рдЖрдореНрд╣реА рдСрдкрд░реЗрд╢рди рдХрд░рддреЛ r0 = Imm. рдкреБрдвреЗ, JMP рд╡рд░реНрдЧ 1 рдСрдкрд░реЗрд╢рди рдЖрд╣реЗ BPF_JEQ (рд╕рдорд╛рди рдЕрд╕рд▓реНрдпрд╛рд╕ рдЙрдбреА рдорд╛рд░рдгреЗ). рдЖрдордЪреНрдпрд╛ рдмрд╛рдмрддреАрдд, рдмрд┐рдЯ рдкрд╛рд╕реВрди S рд╢реВрдиреНрдп рдЖрд╣реЗ, рддреЗ рд╕реНрддреНрд░реЛрдд рд░рдЬрд┐рд╕реНрдЯрд░рдЪреНрдпрд╛ рдореВрд▓реНрдпрд╛рдЪреА рдлреАрд▓реНрдбрд╢реА рддреБрд▓рдирд╛ рдХрд░рддреЗ Imm. рдЬрд░ рдореВрд▓реНрдпреЗ рдЬреБрд│рдд рдЕрд╕рддреАрд▓ рддрд░ рд╕рдВрдХреНрд░рдордг рд╣реЛрддреЗ PC + OffрдХреБрдареЗ PC, рдиреЗрд╣рдореАрдкреНрд░рдорд╛рдгреЗ, рдкреБрдвреАрд▓ рд╕реВрдЪрдирд╛рдВрдЪрд╛ рдкрддреНрддрд╛ рд╕рдорд╛рд╡рд┐рд╖реНрдЯреАрдд рдЖрд╣реЗ. рд╢реЗрд╡рдЯреА, JMP рд╡рд░реНрдЧ 9 рдСрдкрд░реЗрд╢рди рдЖрд╣реЗ BPF_EXIT. рд╣реА рд╕реВрдЪрдирд╛ рдХрд░реНрдирд▓рд╡рд░ рдкрд░рдд рдпреЗрдКрди рдкреНрд░реЛрдЧреНрд░рд╛рдо рдмрдВрдж рдХрд░рддреЗ r0. рдЪрд▓рд╛ рдЖрдордЪреНрдпрд╛ рдЯреЗрдмрд▓рдордзреНрдпреЗ рдПрдХ рдирд╡реАрди рд╕реНрддрдВрдн рдЬреЛрдбреВрдпрд╛:

Op    S  Class   Dst Src Off  Imm    Disassm
MOV   0  ALU64   0   0   0    1      r0 = 1
JEQ   0  JMP     0   1   1    0      if (r1 == 0) goto pc+1
MOV   0  ALU64   0   0   0    2      r0 = 2
EXIT  0  JMP     0   0   0    0      exit

рдЖрдореНрд╣реА рд╣реЗ рдЕрдзрд┐рдХ рд╕реЛрдпреАрд╕реНрдХрд░ рд╕реНрд╡рд░реВрдкрд╛рдд рдкреБрдиреНрд╣рд╛ рд▓рд┐рд╣реВ рд╢рдХрддреЛ:

     r0 = 1
     if (r1 == 0) goto END
     r0 = 2
END:
     exit

рдиреЛрдВрджрд╡рд╣реАрдд рдХрд╛рдп рдЖрд╣реЗ рддреЗ рдЖрдард╡рд▓реЗ рддрд░ r1 рдкреНрд░реЛрдЧреНрд░реЕрдорд▓рд╛ рдХрд░реНрдирд▓ рдЖрдгрд┐ рд░рдЬрд┐рд╕реНрдЯрд░рдордзреВрди рд╕рдВрджрд░реНрднрд╛рдХрдбреЗ рдПрдХ рдкреЙрдЗрдВрдЯрд░ рдкрд╛рд╕ рдХреЗрд▓рд╛ рдЬрд╛рддреЛ r0 рдПрдХ рдореВрд▓реНрдп рдХрд░реНрдирд▓рд▓рд╛ рдкрд░рдд рдХреЗрд▓реЗ рдЬрд╛рддреЗ, рдирдВрддрд░ рдЖрдкрдг рдкрд╛рд╣реВ рд╢рдХрддреЛ рдХреА рдЬрд░ рд╕рдВрджрд░реНрднрд╛рдЪрд╛ рдкреЙрдЗрдВрдЯрд░ рд╢реВрдиреНрдп рдЕрд╕реЗрд▓ рддрд░ рдЖрдкрдг 1 рдкрд░рдд рдХрд░рддреЛ рдЖрдгрд┐ рдЕрдиреНрдпрдерд╛ - 2. рд╕реНрддреНрд░реЛрдд рдмрдШреВрди рдЖрдкрдг рдмрд░реЛрдмрд░ рдЖрд╣реЛрдд рд╣реЗ рддрдкрд╛рд╕реВ:

$ cat readelf-example.c
int foo(void *ctx)
{
        return ctx ? 2 : 1;
}

рд╣реЛрдп, рд╣рд╛ рдПрдХ рдЕрд░реНрдерд╣реАрди рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЖрд╣реЗ, рдкрд░рдВрддреБ рддреЛ рдлрдХреНрдд рдЪрд╛рд░ рд╕реЛрдкреНрдпрд╛ рд╕реВрдЪрдирд╛рдВрдордзреНрдпреЗ рдЕрдиреБрд╡рд╛рджрд┐рдд рдХрд░рддреЛ.

рдЕрдкрд╡рд╛рдж рдЙрджрд╛рд╣рд░рдг: 16-рдмрд╛рдЗрдЯ рд╕реВрдЪрдирд╛

рдЖрдореНрд╣реА рдЖрдзреА рдЙрд▓реНрд▓реЗрдЦ рдХреЗрд▓рд╛ рдЖрд╣реЗ рдХреА рдХрд╛рд╣реА рд╕реВрдЪрдирд╛ 64 рдмрд┐рдЯреНрд╕ рдкреЗрдХреНрд╖рд╛ рдЬрд╛рд╕реНрдд рдШреЗрддрд╛рдд. рд╣реЗ рд▓рд╛рдЧреВ рд╣реЛрддреЗ, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдирд┐рд░реНрджреЗрд╢рд╛рдВрд╡рд░ lddw (рдХреЛрдб = 0x18 = BPF_LD | BPF_DW | BPF_IMM) тАФ рдлреАрд▓реНрдбрдордзреВрди рджреБрд╣реЗрд░реА рд╢рдмреНрдж рд░рдЬрд┐рд╕реНрдЯрд░рдордзреНрдпреЗ рд▓реЛрдб рдХрд░рд╛ Imm... рд╡рд╕реНрддреБрд╕реНрдерд┐рддреА рдЕрд╢реА рдЖрд╣реЗ Imm 32 рдЪрд╛ рдЖрдХрд╛рд░ рдЖрд╣реЗ, рдЖрдгрд┐ рджреБрд╣реЗрд░реА рд╢рдмреНрдж 64 рдмрд┐рдЯреНрд╕ рдЖрд╣реЗ, рдореНрд╣рдгреВрди рдПрдХрд╛ 64-рдмрд┐рдЯ рдирд┐рд░реНрджреЗрд╢рд╛рдордзреНрдпреЗ 64-рдмрд┐рдЯ рддрд╛рддреНрдХрд╛рд│ рдореВрд▓реНрдп рдПрдХрд╛ рд░рдЬрд┐рд╕реНрдЯрд░рдордзреНрдпреЗ рд▓реЛрдб рдХрд░рдгреЗ рдХрд╛рд░реНрдп рдХрд░рдгрд╛рд░ рдирд╛рд╣реА. рд╣реЗ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА, рдлреАрд▓реНрдбрдордзреНрдпреЗ 64-рдмрд┐рдЯ рдореВрд▓реНрдпрд╛рдЪрд╛ рджреБрд╕рд░рд╛ рднрд╛рдЧ рд╕рдВрдЪрдпрд┐рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рджреЛрди рд╕рдореАрдк рд╕реВрдЪрдирд╛ рд╡рд╛рдкрд░рд▓реНрдпрд╛ рдЬрд╛рддрд╛рдд Imm. рдЙрджрд╛рд╣рд░рдгрдГ

$ cat x64.c
long foo(void *ctx)
{
        return 0x11223344aabbccdd;
}
$ clang -target bpf -c x64.c -o x64.o -O2
$ llvm-readelf -x .text x64.o
Hex dump of section '.text':
0x00000000 18000000 ddccbbaa 00000000 44332211 ............D3".
0x00000010 95000000 00000000                   ........

рдмрд╛рдпрдирд░реА рдкреНрд░реЛрдЧреНрд░рд╛рдордордзреНрдпреЗ рдлрдХреНрдд рджреЛрди рд╕реВрдЪрдирд╛ рдЖрд╣реЗрдд:

Binary                                 Disassm
18000000 ddccbbaa 00000000 44332211    r0 = Imm[0]|Imm[1]
95000000 00000000                      exit

рдЖрдореНрд╣реА рд╕реВрдЪрдирд╛рдВрд╕рд╣ рдкреБрдиреНрд╣рд╛ рднреЗрдЯреВ lddw, рдЬреЗрд╡реНрд╣рд╛ рдЖрдкрдг рд╕реНрдерд╛рди рдмрджрд▓рдгреНрдпрд╛рдмрджреНрджрд▓ рдЖрдгрд┐ рдирдХрд╛рд╢рд╛рдВрд╕рд╣ рдХрд╛рд░реНрдп рдХрд░рдгреНрдпрд╛рдмрджреНрджрд▓ рдмреЛрд▓рддреЛ.

рдЙрджрд╛рд╣рд░рдг: рдорд╛рдирдХ рд╕рд╛рдзрдирд╛рдВрдЪрд╛ рд╡рд╛рдкрд░ рдХрд░реВрди BPF рд╡реЗрдЧрд│реЗ рдХрд░рдгреЗ

рдореНрд╣рдгреВрди, рдЖрдореНрд╣реА BPF рдмрд╛рдпрдирд░реА рдХреЛрдб рд╡рд╛рдЪрдгреНрдпрд╛рд╕ рд╢рд┐рдХрд▓реЛ рдЖрд╣реЛрдд рдЖрдгрд┐ рдЖрд╡рд╢реНрдпрдХ рдЕрд╕рд▓реНрдпрд╛рд╕ рдХреЛрдгрддреНрдпрд╛рд╣реА рд╕реВрдЪрдирд╛рдВрдЪреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдгреНрдпрд╛рд╕ рддрдпрд╛рд░ рдЖрд╣реЛрдд. рддрдерд╛рдкрд┐, рд╣реЗ рд╕рд╛рдВрдЧрдгреНрдпрд╛рд╕рд╛рд░рдЦреЗ рдЖрд╣реЗ рдХреА рд╕рд░рд╛рд╡ рдордзреНрдпреЗ рдорд╛рдирдХ рд╕рд╛рдзрдирд╛рдВрдЪрд╛ рд╡рд╛рдкрд░ рдХрд░реВрди рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╡реЗрдЧрд│реЗ рдХрд░рдгреЗ рдЕрдзрд┐рдХ рд╕реЛрдпреАрд╕реНрдХрд░ рдЖрдгрд┐ рд╡реЗрдЧрд╡рд╛рди рдЖрд╣реЗ, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде:

$ llvm-objdump -d x64.o

Disassembly of section .text:

0000000000000000 <foo>:
 0: 18 00 00 00 dd cc bb aa 00 00 00 00 44 33 22 11 r0 = 1234605617868164317 ll
 2: 95 00 00 00 00 00 00 00 exit

рдмреАрдкреАрдПрдл рд╡рд╕реНрддреВрдВрдЪреЗ рдЬреАрд╡рдирдЪрдХреНрд░, рдмреАрдкреАрдПрдлрдПрд╕ рдлрд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо

(рдпрд╛ рдЙрдкрд╡рд┐рднрд╛рдЧрд╛рдд рд╡рд░реНрдгрди рдХреЗрд▓реЗрд▓реЗ рдХрд╛рд╣реА рддрдкрд╢реАрд▓ рдореА рдкреНрд░рдердо рдХрдбреВрди рд╢рд┐рдХрд▓реЗ рдЙрдкрд╡рд╛рд╕ рдЕреЕрд▓реЗрдХреНрд╕реА рд╕реНрдЯрд╛рд░реЛрд╡реЛрдЗрдЯреЛрд╡реНрд╣ рдордзреНрдпреЗ BPF рдмреНрд▓реЙрдЧ.)

BPF рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ - рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЖрдгрд┐ рдирдХрд╛рд╢реЗ - рдХрдорд╛рдВрдб рд╡рд╛рдкрд░реВрди рд╡рд╛рдкрд░рдХрд░реНрддреНрдпрд╛рдЪреНрдпрд╛ рдЬрд╛рдЧреЗрд╡рд░реВрди рддрдпрд╛рд░ рдХреЗрд▓реЗ рдЬрд╛рддрд╛рдд BPF_PROG_LOAD ╨╕ BPF_MAP_CREATE рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ bpf(2)рд╣реЗ рдиреЗрдордХреЗ рдХрд╕реЗ рд╣реЛрддреЗ рдпрд╛рдмрджреНрджрд▓ рдЖрдкрдг рдкреБрдвреАрд▓ рднрд╛рдЧрд╛рдд рдЪрд░реНрдЪрд╛ рдХрд░реВ. рд╣реЗ рдХрд░реНрдирд▓ рдбреЗрдЯрд╛ рд╕реНрдЯреНрд░рдХреНрдЪрд░реНрд╕ рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХрд╛рд╕рд╛рдареА рддрдпрд╛рд░ рдХрд░рддреЗ refcount (рд╕рдВрджрд░реНрдн рд╕рдВрдЦреНрдпрд╛) рдПрдХ рд╡рд░ рд╕реЗрдЯ рдХреЗрд▓реЗ рдЖрд╣реЗ, рдЖрдгрд┐ рдСрдмреНрдЬреЗрдХреНрдЯрдХрдбреЗ рдирд┐рд░реНрджреЗрд╢ рдХрд░рдгрд╛рд░рд╛ рдлрд╛рдЗрд▓ рд╡рд░реНрдгрдирдХрд░реНрддрд╛ рд╡рд╛рдкрд░рдХрд░реНрддреНрдпрд╛рд▓рд╛ рдкрд░рдд рдХреЗрд▓рд╛ рдЬрд╛рддреЛ. рд╣рдБрдбрд▓ рдмрдВрдж рдХреЗрд▓реНрдпрд╛рдирдВрддрд░ refcount рд╡рд╕реНрддреВ рдПрдХрд╛рдиреЗ рдХрдореА рд╣реЛрддреЗ рдЖрдгрд┐ рдЬреЗрд╡реНрд╣рд╛ рддреА рд╢реВрдиреНрдпрд╛рд╡рд░ рдкреЛрд╣реЛрдЪрддреЗ рддреЗрд╡реНрд╣рд╛ рддреА рд╡рд╕реНрддреВ рдирд╖реНрдЯ рд╣реЛрддреЗ.

рдЬрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдирдХрд╛рд╢реЗ рд╡рд╛рдкрд░рдд рдЕрд╕реЗрд▓ рддрд░ refcount рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓реЛрдб рдХреЗрд▓реНрдпрд╛рдирдВрддрд░ рд╣реЗ рдирдХрд╛рд╢реЗ рдПрдХрд╛рдиреЗ рд╡рд╛рдврд╡рд▓реЗ тАЛтАЛрдЬрд╛рддрд╛рдд, рдореНрд╣рдгрдЬреЗ. рддреНрдпрд╛рдВрдЪреЗ рдлрд╛рдЗрд▓ рд╡рд░реНрдгрдирдХрд░реНрддрд╛ рд╡рд╛рдкрд░рдХрд░реНрддрд╛ рдкреНрд░рдХреНрд░рд┐рдпреЗрддреВрди рдмрдВрдж рдХреЗрд▓реЗ рдЬрд╛рдК рд╢рдХрддрд╛рдд рдЖрдгрд┐ рддрд░реАрд╣реА refcount рд╢реВрдиреНрдп рд╣реЛрдгрд╛рд░ рдирд╛рд╣реА:

рд▓рд╣рд╛рди рдореБрд▓рд╛рдВрд╕рд╛рдареА рдмреАрдкреАрдПрдл, рднрд╛рдЧ рдПрдХ: рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдмреАрдкреАрдПрдл

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

рдЖрдкрдг рдЖрддрд╛ рдмреВрдЯрд▓реЛрдбрд░ рдмрдВрдж рдХреЗрд▓реНрдпрд╛рд╕ рдХрд╛рдп рд╣реЛрдИрд▓? рд╣реЗ рдЗрд╡реНрд╣реЗрдВрдЯ рдЬрдирд░реЗрдЯрд░ (рд╣реБрдХ) рдЪреНрдпрд╛ рдкреНрд░рдХрд╛рд░рд╛рд╡рд░ рдЕрд╡рд▓рдВрдмреВрди рдЕрд╕рддреЗ. рд▓реЛрдбрд░ рдкреВрд░реНрдг рдЭрд╛рд▓реНрдпрд╛рдирдВрддрд░ рд╕рд░реНрд╡ рдиреЗрдЯрд╡рд░реНрдХ рд╣реБрдХ рдЕрд╕реНрддрд┐рддреНрд╡рд╛рдд рдЕрд╕рддреАрд▓, рд╣реЗ рддрдерд╛рдХрдерд┐рдд рдЧреНрд▓реЛрдмрд▓ рд╣реБрдХ рдЖрд╣реЗрдд. рдЖрдгрд┐, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдЯреНрд░реЗрд╕ рдкреНрд░реЛрдЧреНрд░рд╛рдореНрд╕ рддрдпрд╛рд░ рдХреЗрд▓реЗрд▓реНрдпрд╛ рдкреНрд░рдХреНрд░рд┐рдпреЗрдЪреНрдпрд╛ рд╕рдорд╛рдкреНрддреАрдирдВрддрд░ рд╕реЛрдбрд▓реЗ рдЬрд╛рддреАрд▓ (рдЖрдгрд┐ рдореНрд╣рдгреВрди рддреНрдпрд╛рдВрдирд╛ рд╕реНрдерд╛рдирд┐рдХ рдореНрд╣рдгрддрд╛рдд, "рд╕реНрдерд╛рдирд┐рдХ рддреЗ рдкреНрд░рдХреНрд░рд┐рдпрд╛"). рддрд╛рдВрддреНрд░рд┐рдХрджреГрд╖реНрдЯреНрдпрд╛, рд╕реНрдерд╛рдирд┐рдХ рд╣реБрдХрдордзреНрдпреЗ рдиреЗрд╣рдореА рд╡рд╛рдкрд░рдХрд░реНрддреНрдпрд╛рдЪреНрдпрд╛ рдЬрд╛рдЧреЗрдд рд╕рдВрдмрдВрдзрд┐рдд рдлрд╛рдЗрд▓ рд╡рд░реНрдгрдирдХрд░реНрддрд╛ рдЕрд╕рддреЛ рдЖрдгрд┐ рдореНрд╣рдгреВрди рдЬреЗрд╡реНрд╣рд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдмрдВрдж рд╣реЛрддреЗ рддреЗрд╡реНрд╣рд╛ рдмрдВрдж рд╣реЛрддреЗ, рдкрд░рдВрддреБ рдЬрд╛рдЧрддрд┐рдХ рд╣реБрдХ рддрд╕реЗ рдХрд░рдд рдирд╛рд╣реАрдд. рдЦрд╛рд▓реАрд▓ рдЖрдХреГрддреАрдордзреНрдпреЗ, рд░реЗрдб рдХреНрд░реЙрд╕ рд╡рд╛рдкрд░реВрди, рдореА рд╣реЗ рджрд╛рдЦрд╡рдгреНрдпрд╛рдЪрд╛ рдкреНрд░рдпрддреНрди рдХрд░рддреЛ рдХреА рд▓реЛрдбрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдордЪреНрдпрд╛ рд╕рдорд╛рдкреНрддреАрдореБрд│реЗ рд╕реНрдерд╛рдирд┐рдХ рдЖрдгрд┐ рдЬрд╛рдЧрддрд┐рдХ рд╣реБрдХрдЪреНрдпрд╛ рдмрд╛рдмрддреАрдд рд╡рд╕реНрддреВрдВрдЪреНрдпрд╛ рдЖрдпреБрд╖реНрдпрд╛рд╡рд░ рдХрд╕рд╛ рдкрд░рд┐рдгрд╛рдо рд╣реЛрддреЛ.

рд▓рд╣рд╛рди рдореБрд▓рд╛рдВрд╕рд╛рдареА рдмреАрдкреАрдПрдл, рднрд╛рдЧ рдПрдХ: рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдмреАрдкреАрдПрдл

рд╕реНрдерд╛рдирд┐рдХ рдЖрдгрд┐ рдЬрд╛рдЧрддрд┐рдХ рд╣реБрдХрдордзреНрдпреЗ рдлрд░рдХ рдХрд╛ рдЖрд╣реЗ? рдХрд╛рд╣реА рдкреНрд░рдХрд╛рд░рдЪреЗ рдиреЗрдЯрд╡рд░реНрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЪрд╛рд▓рд╡рдгреЗ рд╡рд╛рдкрд░рдХрд░реНрддреНрдпрд╛рдЪреНрдпрд╛ рдЬрд╛рдЧреЗрд╢рд┐рд╡рд╛рдп рдЕрд░реНрдердкреВрд░реНрдг рдЖрд╣реЗ, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, DDoS рд╕рдВрд░рдХреНрд╖рдгрд╛рдЪреА рдХрд▓реНрдкрдирд╛ рдХрд░рд╛ - рдмреВрдЯрд▓реЛрдбрд░ рдирд┐рдпрдо рд▓рд┐рд╣рд┐рддреЛ рдЖрдгрд┐ BPF рдкреНрд░реЛрдЧреНрд░рд╛рдорд▓рд╛ рдиреЗрдЯрд╡рд░реНрдХ рдЗрдВрдЯрд░рдлреЗрд╕рд╢реА рдЬреЛрдбрддреЛ, рддреНрдпрд╛рдирдВрддрд░ рдмреВрдЯрд▓реЛрдбрд░ рд╕реНрд╡рддрдГрд▓рд╛ рдЬрд╛рдКрди рдорд╛рд░реВрди рдЯрд╛рдХреВ рд╢рдХрддреЛ. рджреБрд╕рд░реАрдХрдбреЗ, рддреБрдореНрд╣реА рджрд╣рд╛ рдорд┐рдирд┐рдЯрд╛рдВрдд рддреБрдордЪреНрдпрд╛ рдЧреБрдбрдШреНрдпрд╛рдВрд╡рд░ рд▓рд┐рд╣рд┐рд▓реЗрд▓реНрдпрд╛ рдбреАрдмрдЧрд┐рдВрдЧ рдЯреНрд░реЗрд╕ рдкреНрд░реЛрдЧреНрд░рд╛рдордЪреА рдХрд▓реНрдкрдирд╛ рдХрд░рд╛ - рдЬреЗрд╡реНрд╣рд╛ рддреЗ рдкреВрд░реНрдг рд╣реЛрдИрд▓, рддреЗрд╡реНрд╣рд╛ рддреБрдореНрд╣рд╛рд▓рд╛ рд╕рд┐рд╕реНрдЯрдордордзреНрдпреЗ рдХрдЪрд░рд╛ рд╢рд┐рд▓реНрд▓рдХ рд░рд╛рд╣реВ рдирдпреЗ рдЕрд╕реЗ рд╡рд╛рдЯрддреЗ рдЖрдгрд┐ рд╕реНрдерд╛рдирд┐рдХ рд╣реБрдХ рд╣реЗ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддреАрд▓.

рджреБрд╕рд░реАрдХрдбреЗ, рдХрд▓реНрдкрдирд╛ рдХрд░рд╛ рдХреА рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд░реНрдирд▓рдордзреАрд▓ рдЯреНрд░реЗрд╕рдкреЙрдИрдВрдЯрд╢реА рдХрдиреЗрдХреНрдЯ рдХрд░рд╛рдпрдЪреЗ рдЖрд╣реЗ рдЖрдгрд┐ рдЕрдиреЗрдХ рд╡рд░реНрд╖рд╛рдВрдЪреА рдЖрдХрдбреЗрд╡рд╛рд░реА рдЧреЛрд│рд╛ рдХрд░рд╛рдпрдЪреА рдЖрд╣реЗ. рдпрд╛ рдкреНрд░рдХрд░рдгрд╛рдд, рддреБрдореНрд╣рд╛рд▓рд╛ рд╡рд╛рдкрд░рдХрд░реНрддрд╛ рднрд╛рдЧ рдкреВрд░реНрдг рдХрд░рд╛рдпрдЪрд╛ рдЖрд╣реЗ рдЖрдгрд┐ рд╡реЗрд│реЛрд╡реЗрд│реА рдЖрдХрдбреЗрд╡рд╛рд░реАрдХрдбреЗ рдкрд░рдд рдпрд╛рдпрдЪреЗ рдЖрд╣реЗ. bpf рдлрд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рд╣реА рд╕рдВрдзреА рдкреНрд░рджрд╛рди рдХрд░рддреЗ. рд╣реА рдПрдХ рдЗрди-рдореЗрдорд░реА-рдУрдиреНрд▓реА рд╕реНрдпреВрдбреЛ-рдлрд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдЖрд╣реЗ рдЬреА BPF рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕рдЪрд╛ рд╕рдВрджрд░реНрдн рджреЗрдгрд╛рд▒реНрдпрд╛ рдлрд╛рдЗрд▓реНрд╕ рддрдпрд╛рд░ рдХрд░рдгреНрдпрд╛рд╕ рдкрд░рд╡рд╛рдирдЧреА рджреЗрддреЗ рдЖрдгрд┐ рддреНрдпрд╛рдореБрд│реЗ рд╡рд╛рдв рд╣реЛрддреЗ. refcount рд╡рд╕реНрддреВ. рдпрд╛рдирдВрддрд░, рд▓реЛрдбрд░ рдмрд╛рд╣реЗрд░ рдкрдбреВ рд╢рдХрддреЛ рдЖрдгрд┐ рддреНрдпрд╛рдиреЗ рддрдпрд╛рд░ рдХреЗрд▓реЗрд▓реНрдпрд╛ рд╡рд╕реНрддреВ рдЬрд┐рд╡рдВрдд рд░рд╛рд╣рддреАрд▓.

рд▓рд╣рд╛рди рдореБрд▓рд╛рдВрд╕рд╛рдареА рдмреАрдкреАрдПрдл, рднрд╛рдЧ рдПрдХ: рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдмреАрдкреАрдПрдл

BPF рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕рдЪрд╛ рд╕рдВрджрд░реНрдн рджреЗрдгрд╛рд░реНтАНрдпрд╛ bpffs рдордзреНрдпреЗ рдлрд╛рдЗрд▓реНрд╕ рддрдпрд╛рд░ рдХрд░рдгреЗ рдпрд╛рд▓рд╛ "рдкрд┐рдирд┐рдВрдЧ" рдореНрд╣рдгрддрд╛рдд (рдкреБрдвреАрд▓ рд╡рд╛рдХреНрдпрд╛рдВрд╢рд╛рдкреНрд░рдорд╛рдгреЗ: "рдкреНрд░рдХреНрд░рд┐рдпрд╛ BPF рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд┐рдВрд╡рд╛ рдирдХрд╛рд╢рд╛ рдкрд┐рди рдХрд░реВ рд╢рдХрддреЗ"). BPF рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕рд╕рд╛рдареА рдлрд╛рдЗрд▓ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рддрдпрд╛рд░ рдХрд░рдгреЗ рдХреЗрд╡рд│ рд╕реНрдерд╛рдирд┐рдХ рд╡рд╕реНрддреВрдВрдЪреЗ рдЖрдпреБрд╖реНрдп рд╡рд╛рдврд╡рдгреНрдпрд╛рд╕рд╛рдареАрдЪ рдирд╡реНрд╣реЗ рддрд░ рдЬрд╛рдЧрддрд┐рдХ рд╡рд╕реНрддреВрдВрдЪреНрдпрд╛ рд╡рд╛рдкрд░рд╛рд╕рд╛рдареА рджреЗрдЦреАрд▓ рдЕрд░реНрдердкреВрд░реНрдг рдЖрд╣реЗ - рдЬрд╛рдЧрддрд┐рдХ DDoS рд╕рдВрд░рдХреНрд╖рдг рдХрд╛рд░реНрдпрдХреНрд░рдорд╛рдЪреНрдпрд╛ рдЙрджрд╛рд╣рд░рдгрд╛рдХрдбреЗ рдкрд░рдд рдЬрд╛рддрд╛рдирд╛, рдЖрдореНрд╣рд╛рд▓рд╛ рдЖрдХрдбреЗрд╡рд╛рд░реА рдкрд╛рд╣рдгреНрдпрд╛рд╕ рд╕рдХреНрд╖рдо рд╡реНрд╣рд╛рдпрдЪреЗ рдЖрд╣реЗ. рд╡реЗрд│реЛрд╡реЗрд│реА.

BPF рдлрд╛рдИрд▓ рд╕рд┐рд╕реНрдЯреАрдо рд╕рд╣рд╕рд╛ рдордзреНрдпреЗ рдЖрд░реЛрд╣рд┐рдд рдХреЗрд▓реА рдЬрд╛рддреЗ /sys/fs/bpf, рдкрд░рдВрддреБ рддреЗ рд╕реНрдерд╛рдирд┐рдХ рдкрд╛рддрд│реАрд╡рд░ рджреЗрдЦреАрд▓ рдорд╛рдЙрдВрдЯ рдХреЗрд▓реЗ рдЬрд╛рдК рд╢рдХрддреЗ, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдпрд╛рд╕рд╛рд░рдЦреЗ:

$ mkdir bpf-mountpoint
$ sudo mount -t bpf none bpf-mountpoint

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

$ cat test.c
__attribute__((section("xdp"), used))
int test(void *ctx)
{
        return 0;
}

char _license[] __attribute__((section("license"), used)) = "GPL";

рдЪрд▓рд╛ рд╣рд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╕рдВрдХрд▓рд┐рдд рдХрд░реВ рдЖрдгрд┐ рдлрд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдордЪреА рд╕реНрдерд╛рдирд┐рдХ рдкреНрд░рдд рддрдпрд╛рд░ рдХрд░реВ bpffs:

$ clang -target bpf -c test.c -o test.o
$ mkdir bpf-mountpoint
$ sudo mount -t bpf none bpf-mountpoint

рдЖрддрд╛ рдпреБрдЯрд┐рд▓рд┐рдЯреА рд╡рд╛рдкрд░реВрди рдЖрдкрд▓рд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдбрд╛рдЙрдирд▓реЛрдб рдХрд░реВрдпрд╛ bpftool рдЖрдгрд┐ рд╕реЛрдмрддрдЪреЗ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдкрд╣рд╛ bpf(2) (рд╕реНрдЯреНрд░реЗрд╕ рдЖрдЙрдЯрдкреБрдЯрдордзреВрди рдХрд╛рд╣реА рдЕрд╕рдВрдмрджреНрдз рд░реЗрд╖рд╛ рдХрд╛рдвреВрди рдЯрд╛рдХрд▓реНрдпрд╛ рдЖрд╣реЗрдд):

$ sudo strace -e bpf bpftool prog load ./test.o bpf-mountpoint/test
bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_XDP, prog_name="test", ...}, 120) = 3
bpf(BPF_OBJ_PIN, {pathname="bpf-mountpoint/test", bpf_fd=3}, 120) = 0

рдпреЗрдереЗ рдЖрдкрдг рд╡рд╛рдкрд░реВрди рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓реЛрдб рдХреЗрд▓рд╛ рдЖрд╣реЗ BPF_PROG_LOAD, рдХрд░реНрдирд▓рдХрдбреВрди рдлрд╛рдЗрд▓ рд╡рд░реНрдгрдирдХрд░реНрддрд╛ рдкреНрд░рд╛рдкреНрдд рдЭрд╛рд▓рд╛ 3 рдЖрдгрд┐ рдХрдорд╛рдВрдб рд╡рд╛рдкрд░реБрди BPF_OBJ_PIN рд╣рд╛ рдлрд╛рдЗрд▓ рд╡рд░реНрдгрдирдХрд░реНрддрд╛ рдлрд╛рдЗрд▓ рдореНрд╣рдгреВрди рдкрд┐рди рдХреЗрд▓рд╛ "bpf-mountpoint/test". рдпрд╛рдирдВрддрд░ рдмреВрдЯрд▓реЛрдбрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдо bpftool рдХрд╛рдо рдкреВрд░реНрдг рдХреЗрд▓реЗ, рдкрд░рдВрддреБ рдЖрдордЪрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд░реНрдирд▓рдордзреНрдпреЗ рд░рд╛рд╣рд┐рд▓рд╛, рдЬрд░реА рдЖрдореНрд╣реА рддреЛ рдХреЛрдгрддреНрдпрд╛рд╣реА рдиреЗрдЯрд╡рд░реНрдХ рдЗрдВрдЯрд░рдлреЗрд╕рд╢реА рд╕рдВрд▓рдЧреНрди рдХреЗрд▓рд╛ рдирд╛рд╣реА:

$ sudo bpftool prog | tail -3
783: xdp  name test  tag 5c8ba0cf164cb46c  gpl
        loaded_at 2020-05-05T13:27:08+0000  uid 0
        xlated 24B  jited 41B  memlock 4096B

рдЖрдкрдг рдлрд╛рдИрд▓ рдСрдмреНрдЬреЗрдХреНрдЯ рд╕рд╛рдорд╛рдиреНрдпрдкрдгреЗ рд╣рдЯрд╡реВ рд╢рдХрддреЛ unlink(2) рдЖрдгрд┐ рддреНрдпрд╛рдирдВрддрд░ рд╕рдВрдмрдВрдзрд┐рдд рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╣рдЯрд╡рд┐рд▓рд╛ рдЬрд╛рдИрд▓:

$ sudo rm ./bpf-mountpoint/test
$ sudo bpftool prog show id 783
Error: get by id (783): No such file or directory

рд╡рд╕реНрддреВ рд╣рдЯрд╡рдд рдЖрд╣реЗ

рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рд╣рдЯрд╡рд┐рдгреНрдпрд╛рдмрджреНрджрд▓ рдмреЛрд▓рддрд╛рдирд╛, рд╣реЗ рд╕реНрдкрд╖реНрдЯ рдХрд░рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ рдХреА рдЖрдореНрд╣реА рд╣реБрдХ (рдЗрд╡реНрд╣реЗрдВрдЯ рдЬрдирд░реЗрдЯрд░) рд╡рд░реВрди рдкреНрд░реЛрдЧреНрд░рд╛рдо рдбрд┐рд╕реНрдХрдиреЗрдХреНрдЯ рдХреЗрд▓реНрдпрд╛рд╡рд░, рдПрдХрд╣реА рдирд╡реАрди рдЗрд╡реНрд╣реЗрдВрдЯ рд▓реЙрдиреНрдЪ рд╣реЛрдгрд╛рд░ рдирд╛рд╣реА, рддрдерд╛рдкрд┐, рдкреНрд░реЛрдЧреНрд░рд╛рдордЪреНрдпрд╛ рд╕рд░реНрд╡ рд╡рд░реНрддрдорд╛рди рдШрдЯрдирд╛ рд╕рд╛рдорд╛рдиреНрдп рдХреНрд░рдорд╛рдиреЗ рдкреВрд░реНрдг рдХреЗрд▓реНрдпрд╛ рдЬрд╛рддреАрд▓. .

рдХрд╛рд╣реА рдкреНрд░рдХрд╛рд░рдЪреЗ рдмреАрдкреАрдПрдл рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рдлреНрд▓рд╛рдпрд╡рд░ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдмрджрд▓рдгреНрдпрд╛рдЪреА рдкрд░рд╡рд╛рдирдЧреА рджреЗрддрд╛рдд, рдореНрд╣рдгрдЬреЗ. рдЕрдиреБрдХреНрд░рдо рдЖрдгреНрд╡рд┐рдХрддрд╛ рдкреНрд░рджрд╛рди рдХрд░рд╛ replace = detach old program, attach new program. рдпрд╛ рдкреНрд░рдХрд░рдгрд╛рдд, рдкреНрд░реЛрдЧреНрд░рд╛рдордЪреНрдпрд╛ рдЬреБрдиреНрдпрд╛ рдЖрд╡реГрддреНрддреАрдЪреА рд╕рд░реНрд╡ рд╕рдХреНрд░рд┐рдп рдЙрджрд╛рд╣рд░рдгреЗ рддреНрдпрд╛рдВрдЪреЗ рдХрд╛рд░реНрдп рдкреВрд░реНрдг рдХрд░рддреАрд▓ рдЖрдгрд┐ рдирд╡реАрди рдкреНрд░реЛрдЧреНрд░рд╛рдордордзреВрди рдирд╡реАрди рдЗрд╡реНрд╣реЗрдВрдЯ рд╣рдБрдбрд▓рд░ рддрдпрд╛рд░ рдХреЗрд▓реЗ рдЬрд╛рддреАрд▓ рдЖрдгрд┐ рдпреЗрдереЗ "рдЕрдгреБрддреНрд╡" рдореНрд╣рдгрдЬреЗ рдПрдХрд╣реА рдХрд╛рд░реНрдпрдХреНрд░рдо рдЪреБрдХрдгрд╛рд░ рдирд╛рд╣реА.

рдХрд╛рд░реНрдпрдХреНрд░рдорд╛рдВрдирд╛ рдЗрд╡реНрд╣реЗрдВрдЯ рд╕реНрддреНрд░реЛрддрд╛рдВрд╢реА рд╕рдВрд▓рдЧреНрди рдХрд░рдгреЗ

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

рдмреАрдкреАрдПрдл рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рд╡рд╛рдкрд░реВрди рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рд╣рд╛рддрд╛рд│рдгреЗ

рдмреАрдкреАрдПрдл рдХрд╛рд░реНрдпрдХреНрд░рдо

рд╕рд░реНрд╡ BPF рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рд╡рд╛рдкрд░реВрди рд╡рд╛рдкрд░рдХрд░реНрддреНрдпрд╛рдЪреНрдпрд╛ рдЬрд╛рдЧреЗрд╡рд░реВрди рддрдпрд╛рд░ рдЖрдгрд┐ рд╡реНрдпрд╡рд╕реНрдерд╛рдкрд┐рдд рдХреЗрд▓реНрдпрд╛ рдЬрд╛рддрд╛рдд bpf, рдЦрд╛рд▓реАрд▓ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдЕрд╕рд▓реЗрд▓реЗ:

#include <linux/bpf.h>

int bpf(int cmd, union bpf_attr *attr, unsigned int size);

рдпреЗрдереЗ рд╕рдВрдШ рдЖрд╣реЗ cmd рдкреНрд░рдХрд╛рд░рд╛рддреАрд▓ рдореВрд▓реНрдпрд╛рдВрдкреИрдХреА рдПрдХ рдЖрд╣реЗ enum bpf_cmd, attr тАФ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреНрд░реЛрдЧреНрд░рд╛рдорд╕рд╛рдареА рдкреЕрд░рд╛рдореАрдЯрд░реНрд╕рд╕рд╛рдареА рдПрдХ рдкреЙрдЗрдВрдЯрд░ рдЖрдгрд┐ size - рдкреЙрдЗрдВрдЯрд░рдиреБрд╕рд╛рд░ рдСрдмреНрдЬреЗрдХреНрдЯрдЪрд╛ рдЖрдХрд╛рд░, рдореНрд╣рдгрдЬреЗ рд╕рд╣рд╕рд╛ рд╣реЗ sizeof(*attr). рдХрд░реНрдирд▓ 5.8 рдордзреНрдпреЗ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ bpf 34 рднрд┐рдиреНрди рдЖрджреЗрд╢рд╛рдВрдирд╛ рд╕рдорд░реНрдерди рджреЗрддреЗ, рдЖрдгрд┐ рд╡реНрдпрд╛рдЦреНрдпрд╛ union bpf_attr 200 рдУрд│реА рд╡реНрдпрд╛рдкрддрд╛рдд. рдкрд░рдВрддреБ рдЖрдкрдг рдпрд╛рдкрд╛рд╕реВрди рдШрд╛рдмрд░реВ рдирдпреЗ, рдХрд╛рд░рдг рдЖрдкрдг рдЕрдиреЗрдХ рд▓реЗрдЦрд╛рдВрджрд░рдореНрдпрд╛рди рдЖрдЬреНрдЮрд╛ рдЖрдгрд┐ рдорд╛рдкрджрдВрдбрд╛рдВрд╢реА рдкрд░рд┐рдЪрд┐рдд рд╣реЛрдК.

рдЪрд▓рд╛ рд╕рдВрдШрд╛рдкрд╛рд╕реВрди рд╕реБрд░реБрд╡рд╛рдд рдХрд░реВрдпрд╛ BPF_PROG_LOAD, рдЬреЗ BPF рдкреНрд░реЛрдЧреНрд░рд╛рдо рддрдпрд╛рд░ рдХрд░рддреЗ - BPF рд╕реВрдЪрдирд╛рдВрдЪрд╛ рд╕рдВрдЪ рдШреЗрддреЗ рдЖрдгрд┐ рдХрд░реНрдирд▓рдордзреНрдпреЗ рд▓реЛрдб рдХрд░рддреЗ. рд▓реЛрдбрд┐рдВрдЧрдЪреНрдпрд╛ рдХреНрд╖рдгреА, рд╕рддреНрдпрд╛рдкрдирдХрд░реНрддрд╛ рд▓реЙрдиреНрдЪ рдХреЗрд▓рд╛ рдЬрд╛рддреЛ, рдЖрдгрд┐ рдирдВрддрд░ JIT рдХрдВрдкрд╛рдЗрд▓рд░ рдЖрдгрд┐, рдпрд╢рд╕реНрд╡реА рдЕрдВрдорд▓рдмрдЬрд╛рд╡рдгреАрдирдВрддрд░, рдкреНрд░реЛрдЧреНрд░рд╛рдо рдлрд╛рдЗрд▓ рд╡рд░реНрдгрдирдХрд░реНрддрд╛ рд╡рд╛рдкрд░рдХрд░реНрддреНрдпрд╛рд╕ рдкрд░рдд рдХреЗрд▓рд╛ рдЬрд╛рддреЛ. рддреНрдпрд╛рдЪреЗ рдкреБрдвреЗ рдХрд╛рдп рд╣реЛрддреЗ рддреЗ рдЖрдкрдг рдорд╛рдЧреАрд▓ рднрд╛рдЧрд╛рдд рдкрд╛рд╣рд┐рд▓реЗ рдмреАрдкреАрдПрдл рд╡рд╕реНрддреВрдВрдЪреНрдпрд╛ рдЬреАрд╡рди рдЪрдХреНрд░рд╛рд╡рд┐рд╖рдпреА.

рдЖрдореНрд╣реА рдЖрддрд╛ рдПрдХ рд╕рд╛рдиреБрдХреВрд▓ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓рд┐рд╣реВ рдЬреЛ рдПрдХ рд╕рд╛рдзрд╛ BPF рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓реЛрдб рдХрд░реЗрд▓, рдкрд░рдВрддреБ рдкреНрд░рдердо рдЖрдореНрд╣рд╛рд▓рд╛ рдХреЛрдгрддреНрдпрд╛ рдкреНрд░рдХрд╛рд░рдЪрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓реЛрдб рдХрд░рд╛рдпрдЪрд╛ рдЖрд╣реЗ рд╣реЗ рдард░рд╡рд╛рд╡реЗ рд▓рд╛рдЧреЗрд▓ - рдЖрдореНрд╣рд╛рд▓рд╛ рдирд┐рд╡рдбрд╛рд╡реЗ рд▓рд╛рдЧреЗрд▓ рдПрдХ рдкреНрд░рдХрд╛рд░ рдЖрдгрд┐ рдпрд╛ рдкреНрд░рдХрд╛рд░рдЪреНрдпрд╛ рдлреНрд░реЗрдорд╡рд░реНрдХрдордзреНрдпреЗ, рдПрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓рд┐рд╣рд╛ рдЬреЛ рдкрдбрддрд╛рд│рдгреА рдЪрд╛рдЪрдгреА рдЙрддреНрддреАрд░реНрдг рдХрд░реЗрд▓. рддрдерд╛рдкрд┐, рдкреНрд░рдХреНрд░рд┐рдпреЗрд╕ рдЧреБрдВрддрд╛рдЧреБрдВрдд рди рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА, рдпреЗрдереЗ рдПрдХ рддрдпрд╛рд░ рдЙрдкрд╛рдп рдЖрд╣реЗ: рдЖрдореНрд╣реА рдПрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдШреЗрдК BPF_PROG_TYPE_XDP, рдЬреЗ рдореВрд▓реНрдп рдкрд░рдд рдХрд░реЗрд▓ XDP_PASS (рд╕рд░реНрд╡ рдкреЕрдХреЗрдЬреЗрд╕ рд╡рдЧрд│рд╛). рдмреАрдкреАрдПрдл рдЕрд╕реЗрдВрдмрд▓рд░рдордзреНрдпреЗ рд╣реЗ рдЕрдЧрджреА рд╕реЛрдкреЗ рджрд┐рд╕рддреЗ:

r0 = 2
exit

рдЖрдореНрд╣реА рдард░рд╡рд┐рд▓реНрдпрд╛рдирдВрддрд░ рдХреА рдЖрдореНрд╣реА рдЕрдкрд▓реЛрдб рдХрд░реВ, рдЖрдореНрд╣реА рддреЗ рдХрд╕реЗ рдХрд░реВ рддреЗ рдЖрдореНрд╣реА рддреБрдореНрд╣рд╛рд▓рд╛ рд╕рд╛рдВрдЧреВ рд╢рдХрддреЛ:

#define _GNU_SOURCE
#include <string.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/bpf.h>

static inline __u64 ptr_to_u64(const void *ptr)
{
        return (__u64) (unsigned long) ptr;
}

int main(void)
{
    struct bpf_insn insns[] = {
        {
            .code = BPF_ALU64 | BPF_MOV | BPF_K,
            .dst_reg = BPF_REG_0,
            .imm = XDP_PASS
        },
        {
            .code = BPF_JMP | BPF_EXIT
        },
    };

    union bpf_attr attr = {
        .prog_type = BPF_PROG_TYPE_XDP,
        .insns     = ptr_to_u64(insns),
        .insn_cnt  = sizeof(insns)/sizeof(insns[0]),
        .license   = ptr_to_u64("GPL"),
    };

    strncpy(attr.prog_name, "woo", sizeof(attr.prog_name));
    syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));

    for ( ;; )
        pause();
}

рдкреНрд░реЛрдЧреНрд░рд╛рдордордзреАрд▓ рдордиреЛрд░рдВрдЬрдХ рдШрдЯрдирд╛ рдЕреЕрд░реЗрдЪреНрдпрд╛ рд╡реНрдпрд╛рдЦреНрдпреЗрдиреЗ рд╕реБрд░реВ рд╣реЛрддрд╛рдд insns - рдорд╢реАрди рдХреЛрдбрдордзреНрдпреЗ рдЖрдордЪрд╛ рдмреАрдкреАрдПрдл рдкреНрд░реЛрдЧреНрд░рд╛рдо. рдпрд╛ рдкреНрд░рдХрд░рдгрд╛рдд, BPF рдкреНрд░реЛрдЧреНрд░рд╛рдордЪреА рдкреНрд░рддреНрдпреЗрдХ рд╕реВрдЪрдирд╛ рд╕рдВрд░рдЪрдиреЗрдд рдкреЕрдХ рдХреЗрд▓реА рдЬрд╛рддреЗ bpf_insn. рдкрд╣рд┐рд▓рд╛ рдШрдЯрдХ insns рд╕реВрдЪрдирд╛рдВрдЪреЗ рдкрд╛рд▓рди рдХрд░рддреЗ r0 = 2, рджреБрд╕рд░рд╛ - exit.

рдорд╛рдШрд╛рд░. рдХрд░реНрдирд▓ рдорд╢реАрди рдХреЛрдб рд▓рд┐рд╣рд┐рдгреНрдпрд╛рд╕рд╛рдареА рдЖрдгрд┐ рдХрд░реНрдирд▓ рд╣реЗрдбрд░ рдлрд╛рдЗрд▓ рд╡рд╛рдкрд░рдгреНрдпрд╛рд╕рд╛рдареА рдЕрдзрд┐рдХ рд╕реЛрдпреАрд╕реНрдХрд░ рдореЕрдХреНрд░реЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ tools/include/linux/filter.h рдЖрдореНрд╣реА рд▓рд┐рд╣реВ рд╢рдХрддреЛ

struct bpf_insn insns[] = {
    BPF_MOV64_IMM(BPF_REG_0, XDP_PASS),
    BPF_EXIT_INSN()
};

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

BPF рдкреНрд░реЛрдЧреНрд░рд╛рдо рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХреЗрд▓реНрдпрд╛рдирдВрддрд░, рдЖрдореНрд╣реА рддреЗ рдХрд░реНрдирд▓рдордзреНрдпреЗ рд▓реЛрдб рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдкреБрдвреЗ рдЬрд╛рдК. рдЖрдордЪрд╛ рдкреЕрд░рд╛рдореАрдЯрд░реНрд╕рдЪрд╛ рдХрд┐рдорд╛рди рд╕рдВрдЪ attr рдкреНрд░реЛрдЧреНрд░рд╛рдо рдкреНрд░рдХрд╛рд░, рд╕рдВрдЪ рдЖрдгрд┐ рд╕реВрдЪрдирд╛рдВрдЪреА рд╕рдВрдЦреНрдпрд╛, рдЖрд╡рд╢реНрдпрдХ рдкрд░рд╡рд╛рдирд╛ рдЖрдгрд┐ рдирд╛рд╡ рд╕рдорд╛рд╡рд┐рд╖реНрдЯ рдЖрд╣реЗ "woo", рдЬреНрдпрд╛рдЪрд╛ рд╡рд╛рдкрд░ рдЖрдореНрд╣реА рдбрд╛рдЙрдирд▓реЛрдб рдХреЗрд▓реНрдпрд╛рдирдВрддрд░ рд╕рд┐рд╕реНрдЯрдорд╡рд░ рдЖрдордЪрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╢реЛрдзрдгреНрдпрд╛рд╕рд╛рдареА рдХрд░рддреЛ. рдкреНрд░реЛрдЧреНрд░рд╛рдо, рд╡рдЪрди рджрд┐рд▓реНрдпрд╛рдкреНрд░рдорд╛рдгреЗ, рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рд╡рд╛рдкрд░реВрди рд╕рд┐рд╕реНрдЯрдордордзреНрдпреЗ рд▓реЛрдб рдХреЗрд▓рд╛ рдЬрд╛рддреЛ bpf.

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

рдмрд░рдВ, рдЖрдореНрд╣реА рдЪрд╛рдЪрдгреАрд╕рд╛рдареА рддрдпрд╛рд░ рдЖрд╣реЛрдд. рдЪреНрдпрд╛ рдЕрдВрддрд░реНрдЧрдд рдХрд╛рд░реНрдпрдХреНрд░рдо рдПрдХрддреНрд░ рдХрд░реВрди рдЪрд╛рд▓рд╡реВ straceрд╕рд░реНрд╡рдХрд╛рд╣реА рдЬрд╕реЗ рдкрд╛рд╣рд┐рдЬреЗ рддрд╕реЗ рдХрд╛рд░реНрдп рдХрд░рдд рдЖрд╣реЗ рд╣реЗ рддрдкрд╛рд╕рдгреНрдпрд╛рд╕рд╛рдареА:

$ clang -g -O2 simple-prog.c -o simple-prog

$ sudo strace ./simple-prog
execve("./simple-prog", ["./simple-prog"], 0x7ffc7b553480 /* 13 vars */) = 0
...
bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_XDP, insn_cnt=2, insns=0x7ffe03c4ed50, license="GPL", log_level=0, log_size=0, log_buf=NULL, kern_version=KERNEL_V
ERSION(0, 0, 0), prog_flags=0, prog_name="woo", prog_ifindex=0, expected_attach_type=BPF_CGROUP_INET_INGRESS}, 72) = 3
pause(

рд╕рд░реНрд╡ рдХрд╛рд╣реА рдареАрдХ рдЖрд╣реЗ, bpf(2) рд╣рдБрдбрд▓ 3 рдЖрдореНрд╣рд╛рд▓рд╛ рдкрд░рдд рдХреЗрд▓реЗ рдЖрдгрд┐ рдЖрдореНрд╣реА рдПрдХрд╛ рдЕрдирдВрдд рд▓реВрдкрдордзреНрдпреЗ рдЧреЗрд▓реЛ pause(). рдЪрд▓рд╛ рд╕рд┐рд╕реНрдЯрдордордзреНрдпреЗ рдЖрдкрд▓рд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╢реЛрдзрдгреНрдпрд╛рдЪрд╛ рдкреНрд░рдпрддреНрди рдХрд░реВрдпрд╛. рд╣реЗ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдЖрдкрдг рджреБрд╕рд▒реНрдпрд╛ рдЯрд░реНрдорд┐рдирд▓рд╡рд░ рдЬрд╛рдК рдЖрдгрд┐ рдпреБрдЯрд┐рд▓рд┐рдЯреА рд╡рд╛рдкрд░реВ bpftool:

# bpftool prog | grep -A3 woo
390: xdp  name woo  tag 3b185187f1855c4c  gpl
        loaded_at 2020-08-31T24:66:44+0000  uid 0
        xlated 16B  jited 40B  memlock 4096B
        pids simple-prog(10381)

рдЖрдореНрд╣реА рдкрд╛рд╣рддреЛ рдХреА рд╕рд┐рд╕реНрдЯрдорд╡рд░ рдПрдХ рд▓реЛрдб рдХреЗрд▓реЗрд▓рд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЖрд╣реЗ woo рдЬреНрдпрд╛рдЪрд╛ рдЧреНрд▓реЛрдмрд▓ рдЖрдпрдбреА 390 рдЖрд╣реЗ рдЖрдгрд┐ рд╕рдзреНрдпрд╛ рдкреНрд░рдЧрддреАрдкрдерд╛рд╡рд░ рдЖрд╣реЗ simple-prog рдкреНрд░реЛрдЧреНрд░рд╛рдордХрдбреЗ рдирд┐рд░реНрджреЗрд╢ рдХрд░рдгрд╛рд░рд╛ рдПрдХ рдЦреБрд▓рд╛ рдлрд╛рдЗрд▓ рд╡рд░реНрдгрдирдХрд░реНрддрд╛ рдЖрд╣реЗ (рдЖрдгрд┐ рдЬрд░ simple-prog рдирдВрддрд░ рдХрд╛рдо рдкреВрд░реНрдг рдХрд░реЗрд▓ woo рдЕрджреГрд╢реНрдп рд╣реЛрдИрд▓). рдЕрдкреЗрдХреНрд╖реЗрдкреНрд░рдорд╛рдгреЗ рдХрд╛рд░реНрдпрдХреНрд░рдо woo BPF рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░рдордзреАрд▓ рдмрд╛рдпрдирд░реА рдХреЛрдбрдЪреЗ - рджреЛрди рд╕реВрдЪрдирд╛ - 16 рдмрд╛рдЗрдЯреНрд╕ рдШреЗрддреЗ, рдкрд░рдВрддреБ рддреНрдпрд╛рдЪреНрдпрд╛ рдореВрд│ рд╕реНрд╡рд░реВрдкрд╛рдд (x86_64) рддреЗ рдЖрдзреАрдЪ 40 рдмрд╛рдЗрдЯреНрд╕ рдЖрд╣реЗ. рдЪрд▓рд╛ рдЖрдордЪрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рддреНрдпрд╛рдЪреНрдпрд╛ рдореВрд│ рд╕реНрд╡рд░реВрдкрд╛рдд рдкрд╛рд╣реВ:

# bpftool prog dump xlated id 390
   0: (b7) r0 = 2
   1: (95) exit

рдЖрд╢реНрдЪрд░реНрдп рдирд╛рд╣реА. рдЖрддрд╛ рдЬреЗрдЖрдпрдЯреА рдХрдВрдкрд╛рдЗрд▓рд░рдиреЗ рд╡реНрдпреБрддреНрдкрдиреНрди рдХреЗрд▓реЗрд▓рд╛ рдХреЛрдб рдкрд╛рд╣реВ:

# bpftool prog dump jited id 390
bpf_prog_3b185187f1855c4c_woo:
   0:   nopl   0x0(%rax,%rax,1)
   5:   push   %rbp
   6:   mov    %rsp,%rbp
   9:   sub    $0x0,%rsp
  10:   push   %rbx
  11:   push   %r13
  13:   push   %r14
  15:   push   %r15
  17:   pushq  $0x0
  19:   mov    $0x2,%eax
  1e:   pop    %rbx
  1f:   pop    %r15
  21:   pop    %r14
  23:   pop    %r13
  25:   pop    %rbx
  26:   leaveq
  27:   retq

рд╕рд╛рдареА рдлрд╛рд░ рдкреНрд░рднрд╛рд╡реА рдирд╛рд╣реА exit(2), рдкрд░рдВрддреБ рдирд┐рд╖реНрдкрдХреНрд╖рддреЗрдиреЗ, рдЖрдордЪрд╛ рдХрд╛рд░реНрдпрдХреНрд░рдо рдЦреВрдк рд╕реЛрдкрд╛ рдЖрд╣реЗ рдЖрдгрд┐ рдХреНрд╖реБрд▓реНрд▓рдХ рдирд╕рд▓реЗрд▓реНрдпрд╛ рдХрд╛рд░реНрдпрдХреНрд░рдорд╛рдВрд╕рд╛рдареА JIT рдХрдВрдкрд╛рдЗрд▓рд░рдиреЗ рдЬреЛрдбрд▓реЗрд▓реЗ рдкреНрд░рд╕реНрддрд╛рд╡рдирд╛ рдЖрдгрд┐ рдЙрдкрд╕рдВрд╣рд╛рд░ рдЕрд░реНрдерд╛рддрдЪ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗрдд.

рдирдХрд╛рд╢реЗ

BPF рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╕рдВрд░рдЪрд┐рдд рдореЗрдорд░реА рдХреНрд╖реЗрддреНрд░реЗ рд╡рд╛рдкрд░реВ рд╢рдХрддрд╛рдд рдЬреЗ рдЗрддрд░ BPF рдкреНрд░реЛрдЧреНрд░рд╛рдореНрд╕ рдЖрдгрд┐ рд╡рд╛рдкрд░рдХрд░реНрддрд╛ рд╕реНрдкреЗрд╕рдордзреАрд▓ рдкреНрд░реЛрдЧреНрд░рд╛рдореНрд╕рд╕рд╛рдареА рджреЛрдиреНрд╣реА рдкреНрд░рд╡реЗрд╢рдпреЛрдЧреНрдп рдЖрд╣реЗрдд. рдпрд╛ рд╡рд╕реНрддреВрдВрдирд╛ рдирдХрд╛рд╢реЗ рдореНрд╣рдгрддрд╛рдд рдЖрдгрд┐ рдпрд╛ рд╡рд┐рднрд╛рдЧрд╛рдд рдЖрдореНрд╣реА рд╕рд┐рд╕реНрдЯреАрдо рдХреЙрд▓ рд╡рд╛рдкрд░реВрди рддреНрдпрд╛рдВрдЪреА рд╣рд╛рддрд╛рд│рдгреА рдХрд╢реА рдХрд░рд╛рдпрдЪреА рддреЗ рджрд╛рдЦрд╡реВ bpf.

рдЪрд▓рд╛ рд▓рдЧреЗрдЪ рдореНрд╣рдгреВрдпрд╛ рдХреА рдирдХрд╛рд╢рд╛рдВрдЪреА рдХреНрд╖рдорддрд╛ рдХреЗрд╡рд│ рд╕рд╛рдорд╛рдпрд┐рдХ рдореЗрдорд░реАрдордзреНрдпреЗ рдкреНрд░рд╡реЗрд╢ рдХрд░рдгреНрдпрд╛рдкреБрд░рддреА рдорд░реНрдпрд╛рджрд┐рдд рдирд╛рд╣реА. рддреЗрдереЗ рд╡рд┐рд╢реЗрд╖ рд╣реЗрддреВ рдЕрд╕рд▓реЗрд▓реЗ рдирдХрд╛рд╢реЗ рдЖрд╣реЗрдд, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдмреАрдкреАрдПрдл рдкреНрд░реЛрдЧреНрд░рд╛рдордЪреЗ рдкреЙрдЗрдВрдЯрд░ рдХрд┐рдВрд╡рд╛ рдиреЗрдЯрд╡рд░реНрдХ рдЗрдВрдЯрд░рдлреЗрд╕рдЪреЗ рдкреЙрдЗрдВрдЯрд░, рдкрд░рдл рдЗрд╡реНрд╣реЗрдВрдЯрд╕рд╣ рдХрд╛рд░реНрдп рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдирдХрд╛рд╢реЗ рдЗ. рд╡рд╛рдЪрдХрд╛рдВрдЪрд╛ рдЧреЛрдВрдзрд│ рд╣реЛрдК рдирдпреЗ рдореНрд╣рдгреВрди рдЖрдореНрд╣реА рддреНрдпрд╛рдВрдЪреНрдпрд╛рдмрджреНрджрд▓ рдпреЗрдереЗ рдмреЛрд▓рдгрд╛рд░ рдирд╛рд╣реА. рдпрд╛рд╢рд┐рд╡рд╛рдп, рдЖрдореНрд╣реА рд╕рд┐рдВрдХреНрд░реЛрдирд╛рдЗрдЭреЗрд╢рди рд╕рдорд╕реНрдпрд╛рдВрдХрдбреЗ рджреБрд░реНрд▓рдХреНрд╖ рдХрд░рддреЛ, рдХрд╛рд░рдг рд╣реЗ рдЖрдордЪреНрдпрд╛ рдЙрджрд╛рд╣рд░рдгрд╛рдВрд╕рд╛рдареА рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ рдирд╛рд╣реА. рдЙрдкрд▓рдмреНрдз рдирдХрд╛рд╢рд╛ рдкреНрд░рдХрд╛рд░рд╛рдВрдЪреА рд╕рдВрдкреВрд░реНрдг рдпрд╛рджреА рдпрд╛рдордзреНрдпреЗ рдЖрдврд│реВ рд╢рдХрддреЗ <linux/bpf.h>, рдЖрдгрд┐ рдпрд╛ рд╡рд┐рднрд╛рдЧрд╛рдд рдЖрдкрдг рдРрддрд┐рд╣рд╛рд╕рд┐рдХрджреГрд╖реНрдЯреНрдпрд╛ рдкрд╣рд┐рд▓рд╛ рдкреНрд░рдХрд╛рд░, рд╣реЕрд╢ рдЯреЗрдмрд▓рдЪреЗ рдЙрджрд╛рд╣рд░рдг рдШреЗрдК BPF_MAP_TYPE_HASH.

рддреБрдореНрд╣реА C++ рдордзреНрдпреЗ рд╣реЕрд╢ рдЯреЗрдмрд▓ рддрдпрд╛рд░ рдХреЗрд▓реНрдпрд╛рд╕, рддреБрдореНрд╣реА рдореНрд╣рдгрд╛рд▓ unordered_map<int,long> woo, рдЬреНрдпрд╛рдЪрд╛ рд░рд╢рд┐рдпрди рднрд╛рд╖реЗрдд рдЕрд░реНрде рдЖрд╣реЗ тАЬрдорд▓рд╛ рдПрдХ рдЯреЗрдмрд▓ рдкрд╛рд╣рд┐рдЬреЗ рдЖрд╣реЗ woo рдЕрдорд░реНрдпрд╛рджрд┐рдд рдЖрдХрд╛рд░, рдЬреНрдпрд╛рдЪреНрдпрд╛ рдХрд│рд╛ рдкреНрд░рдХрд╛рд░ рдЖрд╣реЗрдд int, рдЖрдгрд┐ рдореВрд▓реНрдпреЗ рдкреНрд░рдХрд╛рд░ рдЖрд╣реЗрдд long" BPF рд╣реЕрд╢ рд╕рд╛рд░рдгреА рддрдпрд╛рд░ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА, рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рд╕рд╛рд░рдгреАрдЪрд╛ рдХрдорд╛рд▓ рдЖрдХрд╛рд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рд╛рд╡рд╛ рд▓рд╛рдЧреЗрд▓ рдЖрдгрд┐ рдХреА рдЖрдгрд┐ рдореВрд▓реНрдпрд╛рдВрдЪреЗ рдкреНрд░рдХрд╛рд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдгреНрдпрд╛рдРрд╡рдЬреА, рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рддреНрдпрд╛рдВрдЪреЗ рдЖрдХрд╛рд░ рдмрд╛рдЗрдЯреНрд╕рдордзреНрдпреЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рд╛рд╡реЗ рд▓рд╛рдЧрддреАрд▓. . рдирдХрд╛рд╢реЗ рддрдпрд╛рд░ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдХрдорд╛рдВрдб рд╡рд╛рдкрд░рд╛ BPF_MAP_CREATE рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ bpf. рдЪрд▓рд╛ рдПрдХ рдХрдореА рдХрд┐рдВрд╡рд╛ рдХрдореА рдкреНрд░реЛрдЧреНрд░рд╛рдо рдкрд╛рд╣реВ рдЬреЛ рдирдХрд╛рд╢рд╛ рддрдпрд╛рд░ рдХрд░рддреЛ. рдмреАрдкреАрдПрдл рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓реЛрдб рдХрд░рдгрд╛рд░реНтАНрдпрд╛ рдорд╛рдЧреАрд▓ рдкреНрд░реЛрдЧреНрд░рд╛рдордирдВрддрд░, рд╣реЗ рддреБрдореНрд╣рд╛рд▓рд╛ рд╕реЛрдкреЗ рд╡рд╛рдЯрд▓реЗ рдкрд╛рд╣рд┐рдЬреЗ:

$ cat simple-map.c
#define _GNU_SOURCE
#include <string.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/bpf.h>

int main(void)
{
    union bpf_attr attr = {
        .map_type = BPF_MAP_TYPE_HASH,
        .key_size = sizeof(int),
        .value_size = sizeof(int),
        .max_entries = 4,
    };
    strncpy(attr.map_name, "woo", sizeof(attr.map_name));
    syscall(__NR_bpf, BPF_MAP_CREATE, &attr, sizeof(attr));

    for ( ;; )
        pause();
}

рдпреЗрдереЗ рдЖрдкрдг рдкреЕрд░рд╛рдореАрдЯрд░реНрд╕рдЪрд╛ рд╕рдВрдЪ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЛ attr, рдЬреНрдпрд╛рдордзреНрдпреЗ рдЖрдкрдг рдореНрд╣рдгрддреЛ тАЬрдорд▓рд╛ рдХреА рдЖрдгрд┐ рдЖрдХрд╛рд░ рдореВрд▓реНрдпрд╛рдВрд╕рд╣ рд╣реЕрд╢ рдЯреЗрдмрд▓рдЪреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЖрд╣реЗ sizeof(int), рдЬреНрдпрд╛рдордзреНрдпреЗ рдореА рдЬрд╛рд╕реНрддреАрдд рдЬрд╛рд╕реНрдд рдЪрд╛рд░ рдШрдЯрдХ рдареЗрд╡реВ рд╢рдХрддреЛ." рдмреАрдкреАрдПрдл рдирдХрд╛рд╢реЗ рддрдпрд╛рд░ рдХрд░рддрд╛рдирд╛, рддреБрдореНрд╣реА рдЗрддрд░ рдкреЕрд░рд╛рдореАрдЯрд░реНрд╕ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реВ рд╢рдХрддрд╛, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдкреНрд░реЛрдЧреНрд░рд╛рдордЪреНрдпрд╛ рдЙрджрд╛рд╣рд░рдгрд╛рдкреНрд░рдорд╛рдгреЗ, рдЖрдореНрд╣реА рдСрдмреНрдЬреЗрдХреНрдЯрдЪреЗ рдирд╛рд╡ рдореНрд╣рдгреВрди рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХреЗрд▓реЗ рдЖрд╣реЗ "woo".

рдЪрд▓рд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╕рдВрдХрд▓рд┐рдд рдХрд░реВ рдЖрдгрд┐ рдЪрд╛рд▓рд╡реВ:

$ clang -g -O2 simple-map.c -o simple-map
$ sudo strace ./simple-map
execve("./simple-map", ["./simple-map"], 0x7ffd40a27070 /* 14 vars */) = 0
...
bpf(BPF_MAP_CREATE, {map_type=BPF_MAP_TYPE_HASH, key_size=4, value_size=4, max_entries=4, map_name="woo", ...}, 72) = 3
pause(

рд╣рд╛ рдЖрд╣реЗ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ bpf(2) рдЖрдореНрд╣рд╛рд▓рд╛ рд╡рд░реНрдгрдирдХрд░реНрддрд╛ рдирдХрд╛рд╢рд╛ рдХреНрд░рдорд╛рдВрдХ рдкрд░рдд рдХреЗрд▓рд╛ 3 рдЖрдгрд┐ рдирдВрддрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдо, рдЕрдкреЗрдХреНрд╖реЗрдкреНрд░рдорд╛рдгреЗ, рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓рдордзреАрд▓ рдкреБрдвреАрд▓ рд╕реВрдЪрдирд╛рдВрдЪреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рддреЛ pause(2).

рдЖрддрд╛ рдЖрдкрд▓рд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдмреЕрдХрдЧреНрд░рд╛рдЙрдВрдбрд╡рд░ рдкрд╛рдард╡реВ рдХрд┐рдВрд╡рд╛ рджреБрд╕рд░реЗ рдЯрд░реНрдорд┐рдирд▓ рдЙрдШрдбреВ рдЖрдгрд┐ рдпреБрдЯрд┐рд▓рд┐рдЯреА рд╡рд╛рдкрд░реВрди рдЖрдкрд▓рд╛ рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд╛рд╣реВ bpftool (рдЖрдореНрд╣реА рдЖрдордЪрд╛ рдирдХрд╛рд╢рд╛ рддреНрдпрд╛рдЪреНрдпрд╛ рдирд╛рд╡рд╛рд╡рд░реВрди рдЗрддрд░рд╛рдВрдкреЗрдХреНрд╖рд╛ рд╡реЗрдЧрд│реЗ рдХрд░реВ рд╢рдХрддреЛ):

$ sudo bpftool map
...
114: hash  name woo  flags 0x0
        key 4B  value 4B  max_entries 4  memlock 4096B
...

рд╕рдВрдЦреНрдпрд╛ 114 рд╣рд╛ рдЖрдордЪреНрдпрд╛ рдСрдмреНрдЬреЗрдХреНрдЯрдЪрд╛ рдЧреНрд▓реЛрдмрд▓ рдЖрдпрдбреА рдЖрд╣реЗ. рдХрдорд╛рдВрдб рд╡рд╛рдкрд░реВрди рд╡рд┐рджреНрдпрдорд╛рди рдирдХрд╛рд╢рд╛ рдЙрдШрдбрдгреНрдпрд╛рд╕рд╛рдареА рд╕рд┐рд╕реНрдЯрдорд╡рд░реАрд▓ рдХреЛрдгрддрд╛рд╣реА рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╣рд╛ рдЖрдпрдбреА рд╡рд╛рдкрд░реВ рд╢рдХрддреЛ BPF_MAP_GET_FD_BY_ID рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ bpf.

рдЖрддрд╛ рдЖрдкрдг рдЖрдкрд▓реНрдпрд╛ рд╣реЕрд╢ рдЯреЗрдмрд▓рд╕рд╣ рдЦреЗрд│реВ рд╢рдХрддреЛ. рдЪрд▓рд╛ рддреНрдпрд╛рддреАрд▓ рд╕рд╛рдордЧреНрд░реА рдкрд╛рд╣реВ:

$ sudo bpftool map dump id 114
Found 0 elements

рд░рд┐рдХрд╛рдореЗ. рдЪрд▓рд╛ рддреНрдпрд╛рдд рдПрдХ рдореВрд▓реНрдп рдареЗрд╡реВрдпрд╛ hash[1] = 1:

$ sudo bpftool map update id 114 key 1 0 0 0 value 1 0 0 0

рдЪрд▓рд╛ рдкреБрдиреНрд╣рд╛ рдЯреЗрдмрд▓ рдкрд╛рд╣реВ:

$ sudo bpftool map dump id 114
key: 01 00 00 00  value: 01 00 00 00
Found 1 element

рд╣реБрд░реНрд░реЗ! рдЖрдореНрд╣реА рдПрдХ рдШрдЯрдХ рдЬреЛрдбрдгреНрдпрд╛рдд рд╡реНрдпрд╡рд╕реНрдерд╛рдкрд┐рдд рдХреЗрд▓реЗ. рд▓рдХреНрд╖рд╛рдд рдШреНрдпрд╛ рдХреА рд╣реЗ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдЖрдореНрд╣рд╛рд▓рд╛ рдмрд╛рдЗрдЯ рд╕реНрддрд░рд╛рд╡рд░ рдХрд╛рдо рдХрд░рд╛рд╡реЗ рд▓рд╛рдЧреЗрд▓, рдкрд╛рд╕реВрди bptftool рд╣реЕрд╢ рдЯреЗрдмрд▓рдордзреАрд▓ рдореВрд▓реНрдпреЗ рдХреЛрдгрддреНрдпрд╛ рдкреНрд░рдХрд╛рд░рдЪреА рдЖрд╣реЗрдд рд╣реЗ рдорд╛рд╣рд┐рдд рдирд╛рд╣реА. (рд╣реЗ рдЬреНрдЮрд╛рди рддрд┐рд▓рд╛ рдмреАрдЯреАрдПрдл рд╡рд╛рдкрд░реВрди рд╣рд╕реНрддрд╛рдВрддрд░рд┐рдд рдХреЗрд▓реЗ рдЬрд╛рдК рд╢рдХрддреЗ, рдкрд░рдВрддреБ рдЖрддрд╛ рддреНрдпрд╛рдмрджреНрджрд▓ рдЕрдзрд┐рдХ.)

bpftool рдирдХреНрдХреА рдХрд╕реЗ рд╡рд╛рдЪрддреЗ рдЖрдгрд┐ рдШрдЯрдХ рдЬреЛрдбрддреЗ? рдЪрд▓рд╛ рд╣реБрдб рдЕрдВрддрд░реНрдЧрдд рдПрдХ рдирдЬрд░ рдЯрд╛рдХреВрдпрд╛:

$ sudo strace -e bpf bpftool map dump id 114
bpf(BPF_MAP_GET_FD_BY_ID, {map_id=114, next_id=0, open_flags=0}, 120) = 3
bpf(BPF_MAP_GET_NEXT_KEY, {map_fd=3, key=NULL, next_key=0x55856ab65280}, 120) = 0
bpf(BPF_MAP_LOOKUP_ELEM, {map_fd=3, key=0x55856ab65280, value=0x55856ab652a0}, 120) = 0
key: 01 00 00 00  value: 01 00 00 00
bpf(BPF_MAP_GET_NEXT_KEY, {map_fd=3, key=0x55856ab65280, next_key=0x55856ab65280}, 120) = -1 ENOENT

рдкреНрд░рдердо рдЖрдореНрд╣реА рдХрдорд╛рдВрдб рд╡рд╛рдкрд░реВрди рдирдХрд╛рд╢рд╛ рддреНрдпрд╛рдЪреНрдпрд╛ рдЧреНрд▓реЛрдмрд▓ рдЖрдпрдбреАрдиреЗ рдЙрдШрдбрд▓рд╛ BPF_MAP_GET_FD_BY_ID ╨╕ bpf(2) рдЖрдореНрд╣рд╛рд▓рд╛ рд╡рд░реНрдгрдирдХрд░реНрддрд╛ 3 рдкрд░рдд рдХреЗрд▓реЗ. рдкреБрдвреЗ рдХрдорд╛рдВрдб рд╡рд╛рдкрд░реВрди BPF_MAP_GET_NEXT_KEY рдкрд╛рд╕ рдХрд░реВрди рдЖрдореНрд╣рд╛рд▓рд╛ рдЯреЗрдмрд▓рдордзреАрд▓ рдкрд╣рд┐рд▓реА рдХреА рд╕рд╛рдкрдбрд▓реА NULL "рдорд╛рдЧреАрд▓" рдХреА рд▓рд╛ рдкреЙрдЗрдВрдЯрд░ рдореНрд╣рдгреВрди. рдЖрдордЪреНрдпрд╛рдХрдбреЗ рдЪрд╛рд╡реА рдЕрд╕реЗрд▓ рддрд░ рдЖрдореНрд╣реА рдХрд░реВ рд╢рдХрддреЛ BPF_MAP_LOOKUP_ELEMрдЬреЗ рдкреЙрдЗрдВрдЯрд░рд▓рд╛ рдореВрд▓реНрдп рдкрд░рдд рдХрд░рддреЗ value. рдкреБрдврдЪреА рдкрд╛рдпрд░реА рдореНрд╣рдгрдЬреЗ рд╕рдзреНрдпрд╛рдЪреНрдпрд╛ рдХреАрд▓рд╛ рдкреЙрдЗрдВрдЯрд░ рджреЗрдКрди рдкреБрдвреАрд▓ рдШрдЯрдХ рд╢реЛрдзрдгреНрдпрд╛рдЪрд╛ рдкреНрд░рдпрддреНрди рдХрд░рддреЛ, рдкрд░рдВрддреБ рдЖрдордЪреНрдпрд╛ рдЯреЗрдмрд▓рдордзреНрдпреЗ рдлрдХреНрдд рдПрдХ рдШрдЯрдХ рдЖрдгрд┐ рдХрдорд╛рдВрдб рдЕрд╕рддреЗ. BPF_MAP_GET_NEXT_KEY рдкрд░рддрд╛рд╡рд╛ ENOENT.

рдареАрдХ рдЖрд╣реЗ, рдХреА 1 рдиреЗ рдореВрд▓реНрдп рдмрджрд▓реВрдпрд╛, рдЕрд╕реЗ рдореНрд╣рдгреВрдпрд╛ рдХреА рдЖрдордЪреНрдпрд╛ рд╡реНрдпрд╡рд╕рд╛рдпрд╛рдЪреНрдпрд╛ рддрд░реНрдХрд╛рд╕рд╛рдареА рдиреЛрдВрджрдгреА рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ hash[1] = 2:

$ sudo strace -e bpf bpftool map update id 114 key 1 0 0 0 value 2 0 0 0
bpf(BPF_MAP_GET_FD_BY_ID, {map_id=114, next_id=0, open_flags=0}, 120) = 3
bpf(BPF_MAP_UPDATE_ELEM, {map_fd=3, key=0x55dcd72be260, value=0x55dcd72be280, flags=BPF_ANY}, 120) = 0

рдЕрдкреЗрдХреНрд╖реЗрдкреНрд░рдорд╛рдгреЗ, рд╣реЗ рдЕрдЧрджреА рд╕реЛрдкреЗ рдЖрд╣реЗ: рдЖрджреЗрд╢ BPF_MAP_GET_FD_BY_ID рдЖрдпрдбреА рдЖрдгрд┐ рдХрдорд╛рдВрдбрджреНрд╡рд╛рд░реЗ рдЖрдордЪрд╛ рдирдХрд╛рд╢рд╛ рдЙрдШрдбрддреЛ BPF_MAP_UPDATE_ELEM рдШрдЯрдХ рдЕрдзрд┐рд▓рд┐рдЦрд┐рдд рдХрд░рддреЗ.

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

  • BPF_MAP_LOOKUP_ELEM: рдХреА рджреНрд╡рд╛рд░реЗ рдореВрд▓реНрдп рд╢реЛрдзрд╛
  • BPF_MAP_UPDATE_ELEM: рдореВрд▓реНрдп рдЕрджреНрдпрддрдирд┐рдд / рддрдпрд╛рд░ рдХрд░рд╛
  • BPF_MAP_DELETE_ELEM: рдХреА рдХрд╛рдврд╛
  • BPF_MAP_GET_NEXT_KEY: рдкреБрдвреАрд▓ (рдХрд┐рдВрд╡рд╛ рдкрд╣рд┐рд▓реА) рдХреА рд╢реЛрдзрд╛
  • BPF_MAP_GET_NEXT_ID: рддреБрдореНрд╣рд╛рд▓рд╛ рд╕рд░реНрд╡ рд╡рд┐рджреНрдпрдорд╛рди рдирдХрд╛рд╢рд╛рдВрдордзреВрди рдЬрд╛рдгреНрдпрд╛рдЪреА рдкрд░рд╡рд╛рдирдЧреА рджреЗрддреЗ, рддреЗ рдХрд╕реЗ рдХрд╛рд░реНрдп рдХрд░рддреЗ bpftool map
  • BPF_MAP_GET_FD_BY_ID: рд╡рд┐рджреНрдпрдорд╛рди рдирдХрд╛рд╢рд╛ рддреНрдпрд╛рдЪреНрдпрд╛ рдЬрд╛рдЧрддрд┐рдХ рдЖрдпрдбреАрджреНрд╡рд╛рд░реЗ рдЙрдШрдбрд╛
  • BPF_MAP_LOOKUP_AND_DELETE_ELEM: рдПрдЦрд╛рджреНрдпрд╛ рд╡рд╕реНрддреВрдЪреЗ рдореВрд▓реНрдп рдЕрдгреБрдЕрджреНрдпрдпрд╛рд╡рдд рдХрд░рд╛ рдЖрдгрд┐ рдЬреБрдиреЗ рдкрд░рдд рдХрд░рд╛
  • BPF_MAP_FREEZE: рд╡рд╛рдкрд░рдХрд░реНрддрд╛ рд╕реНрдерд╛рдирд╛рд╡рд░реВрди рдирдХрд╛рд╢рд╛ рдЕрдкрд░рд┐рд╡рд░реНрддрдиреАрдп рдмрдирд╡рд╛ (рд╣реЗ рдСрдкрд░реЗрд╢рди рдкреВрд░реНрд╡рд╡рдд рдХреЗрд▓реЗ рдЬрд╛рдК рд╢рдХрдд рдирд╛рд╣реА)
  • BPF_MAP_LOOKUP_BATCH, BPF_MAP_LOOKUP_AND_DELETE_BATCH, BPF_MAP_UPDATE_BATCH, BPF_MAP_DELETE_BATCH: рдореЛрдареНрдпрд╛ рдкреНрд░рдорд╛рдгрд╛рд╡рд░ рдСрдкрд░реЗрд╢рдиреНрд╕. рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, BPF_MAP_LOOKUP_AND_DELETE_BATCH - рдирдХрд╛рд╢рд╛рд╡рд░реАрд▓ рд╕рд░реНрд╡ рдореВрд▓реНрдпреЗ рд╡рд╛рдЪрдгреНрдпрд╛рдЪрд╛ рдЖрдгрд┐ рд░реАрд╕реЗрдЯ рдХрд░рдгреНрдпрд╛рдЪрд╛ рд╣рд╛ рдПрдХрдореЗрд╡ рд╡рд┐рд╢реНрд╡рд╛рд╕рд╛рд░реНрд╣ рдорд╛рд░реНрдЧ рдЖрд╣реЗ

рдпрд╛ рд╕рд░реНрд╡ рдЖрдЬреНрдЮрд╛ рд╕рд░реНрд╡ рдирдХрд╛рд╢рд╛ рдкреНрд░рдХрд╛рд░рд╛рдВрд╕рд╛рдареА рдХрд╛рд░реНрдп рдХрд░рдд рдирд╛рд╣реАрдд, рдкрд░рдВрддреБ рд╕рд░реНрд╡рд╕рд╛рдзрд╛рд░рдгрдкрдгреЗ рд╡рд╛рдкрд░рдХрд░реНрддреНрдпрд╛рдЪреНрдпрд╛ рдЬрд╛рдЧреЗрд╡рд░реВрди рдЗрддрд░ рдкреНрд░рдХрд╛рд░рдЪреНрдпрд╛ рдирдХрд╛рд╢рд╛рдВрд╕рд╣ рдХрд╛рд░реНрдп рдХрд░рдгреЗ рд╣реЕрд╢ рдЯреЗрдмрд▓рд╕рд╣ рдХрд╛рд░реНрдп рдХрд░рдгреНрдпрд╛рд╕рд╛рд░рдЦреЗрдЪ рджрд┐рд╕рддреЗ.

рдСрд░реНрдбрд░рдЪреНрдпрд╛ рдлрд╛рдпрджреНрдпрд╛рд╕рд╛рдареА, рдЖрдордЪреЗ рд╣реЕрд╢ рдЯреЗрдмрд▓ рдкреНрд░рдпреЛрдЧ рдкреВрд░реНрдг рдХрд░реВрдпрд╛. рд▓рдХреНрд╖рд╛рдд рдареЗрд╡рд╛ рдХреА рдЖрдореНрд╣реА рдПрдХ рдЯреЗрдмрд▓ рддрдпрд╛рд░ рдХреЗрд▓рд╛ рдЖрд╣реЗ рдЬреНрдпрд╛рдордзреНрдпреЗ рдЪрд╛рд░ рдХреА рдЕрд╕реВ рд╢рдХрддрд╛рдд? рдЪрд▓рд╛ рдЖрдгрдЦреА рдХрд╛рд╣реА рдШрдЯрдХ рдЬреЛрдбреВрдпрд╛:

$ sudo bpftool map update id 114 key 2 0 0 0 value 1 0 0 0
$ sudo bpftool map update id 114 key 3 0 0 0 value 1 0 0 0
$ sudo bpftool map update id 114 key 4 0 0 0 value 1 0 0 0

рдЕрдЬреВрди рддрд░реА рдЫрд╛рди рдЖрд╣реЗ:

$ sudo bpftool map dump id 114
key: 01 00 00 00  value: 01 00 00 00
key: 02 00 00 00  value: 01 00 00 00
key: 04 00 00 00  value: 01 00 00 00
key: 03 00 00 00  value: 01 00 00 00
Found 4 elements

рдЪрд▓рд╛ рдЖрдгрдЦреА рдПрдХ рдЬреЛрдбрдгреНрдпрд╛рдЪрд╛ рдкреНрд░рдпрддреНрди рдХрд░реВрдпрд╛:

$ sudo bpftool map update id 114 key 5 0 0 0 value 1 0 0 0
Error: update failed: Argument list too long

рдЕрдкреЗрдХреНрд╖реЗрдкреНрд░рдорд╛рдгреЗ рдЖрдореНрд╣реА рдпрд╢рд╕реНрд╡реА рдЭрд╛рд▓реЛ рдирд╛рд╣реА. рдЪрд▓рд╛ рдЕрдзрд┐рдХ рддрдкрд╢реАрд▓рд╛рдиреЗ рддреНрд░реБрдЯреА рдкрд╛рд╣реВ:

$ sudo strace -e bpf bpftool map update id 114 key 5 0 0 0 value 1 0 0 0
bpf(BPF_MAP_GET_FD_BY_ID, {map_id=114, next_id=0, open_flags=0}, 120) = 3
bpf(BPF_OBJ_GET_INFO_BY_FD, {info={bpf_fd=3, info_len=80, info=0x7ffe6c626da0}}, 120) = 0
bpf(BPF_MAP_UPDATE_ELEM, {map_fd=3, key=0x56049ded5260, value=0x56049ded5280, flags=BPF_ANY}, 120) = -1 E2BIG (Argument list too long)
Error: update failed: Argument list too long
+++ exited with 255 +++

рд╕рд░реНрд╡ рдХрд╛рд╣реА рдареАрдХ рдЖрд╣реЗ: рдЕрдкреЗрдХреНрд╖реЗрдкреНрд░рдорд╛рдгреЗ, рд╕рдВрдШ BPF_MAP_UPDATE_ELEM рдирд╡реАрди, рдкрд╛рдЪрд╡реА, рдХреА рддрдпрд╛рд░ рдХрд░рдгреНрдпрд╛рдЪрд╛ рдкреНрд░рдпрддреНрди рдХрд░рддреЗ, рдкрд░рдВрддреБ рдХреНрд░реЕрд╢ рд╣реЛрддреЗ E2BIG.

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

(рдирд┐рдореНрди-рд╕реНрддрд░реАрдп рдЙрджрд╛рд╣рд░рдгрд╛рдЪреНрдпрд╛ рдЕрднрд╛рд╡рд╛рдореБрд│реЗ рдЕрд╕рдорд╛рдзрд╛рдиреА рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рд╡рд╛рдЪрдХрд╛рдВрд╕рд╛рдареА: рдЖрдореНрд╣реА рддрдкрд╢реАрд▓рд╡рд╛рд░ рдкреНрд░реЛрдЧреНрд░рд╛рдореНрд╕рдЪреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реВ рдЬреЗ рдирдХрд╛рд╢реЗ рдЖрдгрд┐ рдорджрддрдиреАрд╕ рдХрд╛рд░реНрдпреЗ рд╡рд╛рдкрд░реВрди рддрдпрд╛рд░ рдХреЗрд▓реЗрд▓реЗ libbpf рдЖрдгрд┐ рд╕реВрдЪрдирд╛ рд╕реНрддрд░рд╛рд╡рд░ рдХрд╛рдп рд╣реЛрддреЗ рддреЗ рддреБрдореНрд╣рд╛рд▓рд╛ рд╕рд╛рдВрдЧрддреЛ. рдЕрд╕рдорд╛рдзрд╛рдиреА рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рд╡рд╛рдЪрдХрд╛рдВрд╕рд╛рдареА рдЦреБрдк, рдЖрдореНрд╣реА рдЬреЛрдбрд▓реЗ рдЙрджрд╛рд╣рд░рдг рд▓реЗрдЦрд╛рдд рдпреЛрдЧреНрдп рдард┐рдХрд╛рдгреА.)

libbpf рд╡рд╛рдкрд░реВрди BPF рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓рд┐рд╣рд┐рдгреЗ

рдорд╢реАрди рдХреЛрдб рд╡рд╛рдкрд░реВрди рдмреАрдкреАрдПрдл рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓рд┐рд╣рд┐рдгреЗ рдХреЗрд╡рд│ рдкреНрд░рдердордЪ рдордиреЛрд░рдВрдЬрдХ рдЕрд╕реВ рд╢рдХрддреЗ рдЖрдгрд┐ рдирдВрддрд░ рддреГрдкреНрддрд┐ рд╕реЗрдЯ рд╣реЛрддреЗ. рдпрд╛ рдХреНрд╖рдгреА рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рдЖрдкрд▓реЗ рд▓рдХреНрд╖ рд╡рд│рд╡рдгреНрдпрд╛рдЪреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЖрд╣реЗ llvm, рдЬреНрдпрд╛рдордзреНрдпреЗ BPF рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рддрд╕реЗрдЪ рд▓рд╛рдпрдмреНрд░рд░реАрд╕рд╛рдареА рдХреЛрдб рдЬрдирд░реЗрдЯ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдмреЕрдХрдПрдВрдб рдЖрд╣реЗ libbpf, рдЬреЗ рддреБрдореНрд╣рд╛рд▓рд╛ BPF рдНрдкреНрд▓рд┐рдХреЗрд╢рдиреНрд╕рдЪреА рд╡рд╛рдкрд░рдХрд░реНрддрд╛ рдмрд╛рдЬреВ рд▓рд┐рд╣рд┐рдгреНрдпрд╛рд╕ рдЖрдгрд┐ рд╡рд╛рдкрд░реВрди рддрдпрд╛рд░ рдХреЗрд▓реЗрд▓реНрдпрд╛ BPF рдкреНрд░реЛрдЧреНрд░рд╛рдореНрд╕рдЪрд╛ рдХреЛрдб рд▓реЛрдб рдХрд░рдгреНрдпрд╛рд╕ рдЕрдиреБрдорддреА рджреЗрддреЗ. llvm/clang.

рдЦрд░рдВ рддрд░, рдЬрд╕реЗ рдЖрдкрдг рдпрд╛ рдЖрдгрд┐ рддреНрдпрд╛рдирдВрддрд░рдЪреНрдпрд╛ рд▓реЗрдЦрд╛рдВрдордзреНрдпреЗ рдкрд╛рд╣рдгрд╛рд░ рдЖрд╣реЛрдд, libbpf рддреНрдпрд╛рд╢рд┐рд╡рд╛рдп рдмрд░реЗрдЪ рдХрд╛рдо рдХрд░рддреЗ (рдХрд┐рдВрд╡рд╛ рддрддреНрд╕рдо рд╕рд╛рдзрдиреЗ - iproute2, libbcc, libbpf-go, рдЗ.) рдЬрдЧрдгреЗ рдЕрд╢рдХреНрдп рдЖрд╣реЗ. рдкреНрд░рдХрд▓реНрдкрд╛рдЪреНрдпрд╛ рдХрд┐рд▓рд░ рд╡реИрд╢рд┐рд╖реНрдЯреНрдпрд╛рдВрдкреИрдХреА рдПрдХ libbpf BPF CO-RE (рдПрдХрджрд╛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рд╛, рд╕рд░реНрд╡рддреНрд░ рдЪрд╛рд▓рд╡рд╛) - рд╣рд╛ рдПрдХ рдкреНрд░рдХрд▓реНрдк рдЖрд╣реЗ рдЬреЛ рддреБрдореНрд╣рд╛рд▓рд╛ рдПрдХрд╛ рдХрд░реНрдирд▓рдордзреВрди рджреБрд╕рд▒реНрдпрд╛ рдХрд░реНрдирд▓рд╡рд░ рдкреЛрд░реНрдЯреЗрдмрд▓ рдЕрд╕рд▓реЗрд▓реЗ BPF рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓рд┐рд╣рд┐рдгреНрдпрд╛рдЪреА рдкрд░рд╡рд╛рдирдЧреА рджреЗрддреЛ, рдЬреНрдпрд╛рдордзреНрдпреЗ рд╡реЗрдЧрд╡реЗрдЧрд│реНрдпрд╛ API рд╡рд░ рдЪрд╛рд▓рдгреНрдпрд╛рдЪреА рдХреНрд╖рдорддрд╛ рдЕрд╕рддреЗ (рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдЬреЗрд╡реНрд╣рд╛ рдХрд░реНрдирд▓рдЪреА рд░рдЪрдирд╛ рдЖрд╡реГрддреНрддреАрдордзреВрди рдмрджрд▓рддреЗ. рдЖрд╡реГрддреНрддреАрдкрд░реНрдпрдВрдд). CO-RE рд╕рд╣ рдХрд╛рд░реНрдп рдХрд░рдгреНрдпрд╛рд╕ рд╕рдХреНрд╖рдо рд╣реЛрдгреНрдпрд╛рд╕рд╛рдареА, рддреБрдордЪреЗ рдХрд░реНрдирд▓ BTF рд╕рдкреЛрд░реНрдЯрд╕рд╣ рд╕рдВрдХрд▓рд┐рдд рдХреЗрд▓реЗ рдЬрд╛рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ (рд╣реЗ рдХрд╕реЗ рдХрд░рд╛рдпрдЪреЗ рддреЗ рдЖрдореНрд╣реА рд╡рд┐рднрд╛рдЧрд╛рдд рд╡рд░реНрдгрди рдХрд░рддреЛ. рд╡рд┐рдХрд╛рд╕ рд╕рд╛рдзрдиреЗ. рддреБрдордЪрд╛ рдХрд░реНрдирд▓ BTF рдиреЗ рдмрдирд╡рд▓рд╛ рдЖрд╣реЗ рдХреА рдирд╛рд╣реА рд╣реЗ рддреБрдореНрд╣реА рддрдкрд╛рд╕реВ рд╢рдХрддрд╛ - рдЦрд╛рд▓реАрд▓ рдлрд╛рдЗрд▓рдЪреНрдпрд╛ рдЙрдкрд╕реНрдерд┐рддреАрдиреЗ:

$ ls -lh /sys/kernel/btf/vmlinux
-r--r--r-- 1 root root 2.6M Jul 29 15:30 /sys/kernel/btf/vmlinux

рд╣реА рдлрд╛рдИрд▓ рдХрд░реНрдирд▓рдордзреНрдпреЗ рд╡рд╛рдкрд░рд▓реЗрд▓реНрдпрд╛ рд╕рд░реНрд╡ рдбреЗрдЯрд╛ рдкреНрд░рдХрд╛рд░рд╛рдВрдмрджреНрджрд▓ рдорд╛рд╣рд┐рддреА рд╕рдВрдЧреНрд░рд╣рд┐рдд рдХрд░рддреЗ рдЖрдгрд┐ рд╡рд╛рдкрд░реВрди рдЖрдордЪреНрдпрд╛ рд╕рд░реНрд╡ рдЙрджрд╛рд╣рд░рдгрд╛рдВрдордзреНрдпреЗ рд╡рд╛рдкрд░рд▓реА рдЬрд╛рддреЗ libbpf. рдЖрдореНрд╣реА рдкреБрдвреАрд▓ рд▓реЗрдЦрд╛рдд CO-RE рдмрджреНрджрд▓ рддрдкрд╢реАрд▓рд╡рд╛рд░ рдЪрд░реНрдЪрд╛ рдХрд░реВ, рдкрд░рдВрддреБ рдпрд╛ рд▓реЗрдЦрд╛рдд - рдлрдХреНрдд рд╕реНрд╡рддрдГрд▓рд╛ рдПрдХ рдХрд░реНрдирд▓ рддрдпрд╛рд░ рдХрд░рд╛ CONFIG_DEBUG_INFO_BTF.

рд▓рд╛рдпрдмреНрд░рд░реА libbpf рдереЗрдЯ рдирд┐рд░реНрджреЗрд╢рд┐рдХреЗрдд рд░рд╛рд╣рддреЛ tools/lib/bpf рдХрд░реНрдирд▓ рдЖрдгрд┐ рддреНрдпрд╛рдЪрд╛ рд╡рд┐рдХрд╛рд╕ рдореЗрд▓рд┐рдВрдЧ рд╕реВрдЪреАрджреНрд╡рд╛рд░реЗ рдХреЗрд▓рд╛ рдЬрд╛рддреЛ [email protected]. рддрдерд╛рдкрд┐, рдХрд░реНрдирд▓рдЪреНрдпрд╛ рдмрд╛рд╣реЗрд░ рд░рд╛рд╣рдгрд╛рд░реНтАНрдпрд╛ рдНрдкреНрд▓рд┐рдХреЗрд╢рдиреНрд╕рдЪреНрдпрд╛ рдЧрд░рдЬрд╛рдВрд╕рд╛рдареА рд╡реЗрдЧрд│реЗ рднрд╛рдВрдбрд╛рд░ рд░рд╛рдЦрд▓реЗ рдЬрд╛рддреЗ https://github.com/libbpf/libbpf рдЬреНрдпрд╛рдордзреНрдпреЗ рдХрд░реНрдирд▓ рд▓рд╛рдпрдмреНрд░рд░реА рдХрдореА-рдЕрдзрд┐рдХ рдкреНрд░рдорд╛рдгрд╛рдд рд╡рд╛рдЪрди рдкреНрд░рд╡реЗрд╢рд╛рд╕рд╛рдареА рдорд┐рд░рд░ рдХреЗрд▓реА рдЬрд╛рддреЗ.

рдпрд╛ рд╡рд┐рднрд╛рдЧрд╛рдд рдЖрдкрдг рд╡рд╛рдкрд░рдгрд╛рд░рд╛ рдкреНрд░рдХрд▓реНрдк рдХрд╕рд╛ рддрдпрд╛рд░ рдХрд░реВ рд╢рдХрддреЛ рддреЗ рдкрд╛рд╣реВ libbpf, рдЪрд▓рд╛ рдЕрдиреЗрдХ (рдЕрдзрд┐рдХ рдХрд┐рдВрд╡рд╛ рдХрдореА рдЕрд░реНрдерд╣реАрди) рдЪрд╛рдЪрдгреА рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓рд┐рд╣реВ рдЖрдгрд┐ рд╣реЗ рд╕рд░реНрд╡ рдХрд╕реЗ рдХрд╛рд░реНрдп рдХрд░рддреЗ рдпрд╛рдЪреЗ рддрдкрд╢реАрд▓рд╡рд╛рд░ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реВрдпрд╛. рд╣реЗ BPF рдкреНрд░реЛрдЧреНрд░рд╛рдореНрд╕ рдирдХрд╛рд╢реЗ, рдХрд░реНрдирд▓ рдорджрддрдиреАрд╕, BTF рдЗрддреНрдпрд╛рджреАрдВрд╢реА рдХрд╕реЗ рд╕рдВрд╡рд╛рдж рд╕рд╛рдзрддрд╛рдд рд╣реЗ рдЦрд╛рд▓реАрд▓ рд╡рд┐рднрд╛рдЧрд╛рдВрдордзреНрдпреЗ рдЕрдзрд┐рдХ рд╕рд╣рдЬрдкрдгреЗ рд╕реНрдкрд╖реНрдЯ рдХрд░рдгреНрдпрд╛рд╕ рдЕрдиреБрдорддреА рджреЗрдИрд▓.

рд╕рд╛рдорд╛рдиреНрдпрддрдГ рд╡рд╛рдкрд░реВрди рдкреНрд░рдХрд▓реНрдк libbpf рдЧрд┐рдЯ рд╕рдмрдореЙрдбреНрдпреВрд▓ рдореНрд╣рдгреВрди рдЧрд┐рдЯрд╣рдм рд░реЗрдкреЙрдЬрд┐рдЯрд░реА рдЬреЛрдбрд╛, рдЖрдореНрд╣реА рддреЗрдЪ рдХрд░реВ:

$ mkdir /tmp/libbpf-example
$ cd /tmp/libbpf-example/
$ git init-db
Initialized empty Git repository in /tmp/libbpf-example/.git/
$ git submodule add https://github.com/libbpf/libbpf.git
Cloning into '/tmp/libbpf-example/libbpf'...
remote: Enumerating objects: 200, done.
remote: Counting objects: 100% (200/200), done.
remote: Compressing objects: 100% (103/103), done.
remote: Total 3354 (delta 101), reused 118 (delta 79), pack-reused 3154
Receiving objects: 100% (3354/3354), 2.05 MiB | 10.22 MiB/s, done.
Resolving deltas: 100% (2176/2176), done.

рдЬрд╛рдд libbpf рдЦреВрдк рд╕реЛрдкреЗ:

$ cd libbpf/src
$ mkdir build
$ OBJDIR=build DESTDIR=root make -s install
$ find root
root
root/usr
root/usr/include
root/usr/include/bpf
root/usr/include/bpf/bpf_tracing.h
root/usr/include/bpf/xsk.h
root/usr/include/bpf/libbpf_common.h
root/usr/include/bpf/bpf_endian.h
root/usr/include/bpf/bpf_helpers.h
root/usr/include/bpf/btf.h
root/usr/include/bpf/bpf_helper_defs.h
root/usr/include/bpf/bpf.h
root/usr/include/bpf/libbpf_util.h
root/usr/include/bpf/libbpf.h
root/usr/include/bpf/bpf_core_read.h
root/usr/lib64
root/usr/lib64/libbpf.so.0.1.0
root/usr/lib64/libbpf.so.0
root/usr/lib64/libbpf.a
root/usr/lib64/libbpf.so
root/usr/lib64/pkgconfig
root/usr/lib64/pkgconfig/libbpf.pc

рдпрд╛ рд╡рд┐рднрд╛рдЧрд╛рддреАрд▓ рдЖрдордЪреА рдкреБрдвреАрд▓ рдпреЛрдЬрдирд╛ рдЦрд╛рд▓реАрд▓рдкреНрд░рдорд╛рдгреЗ рдЖрд╣реЗ: рдЖрдореНрд╣реА BPF рдХрд╛рд░реНрдпрдХреНрд░рдо рд▓рд┐рд╣реВ BPF_PROG_TYPE_XDP, рдорд╛рдЧреАрд▓ рдЙрджрд╛рд╣рд░рдгрд╛рдкреНрд░рдорд╛рдгреЗрдЪ, рдкрд░рдВрддреБ C рдордзреНрдпреЗ, рдЖрдореНрд╣реА рддреЗ рд╡рд╛рдкрд░реВрди рд╕рдВрдХрд▓рд┐рдд рдХрд░рддреЛ clang, рдЖрдгрд┐ рдПрдХ рд╣реЗрд▓реНрдкрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓рд┐рд╣рд╛ рдЬреЛ рдХрд░реНрдирд▓рдордзреНрдпреЗ рд▓реЛрдб рдХрд░реЗрд▓. рдкреБрдвреАрд▓ рд╡рд┐рднрд╛рдЧрд╛рдВрдордзреНрдпреЗ рдЖрдореНрд╣реА BPF рдХрд╛рд░реНрдпрдХреНрд░рдо рдЖрдгрд┐ рд╕рд╣рд╛рдпреНрдпрдХ рдХрд╛рд░реНрдпрдХреНрд░рдо рдпрд╛ рджреЛрдиреНрд╣реАрдВрдЪреНрдпрд╛ рдХреНрд╖рдорддрд╛рдВрдЪрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░реВ.

рдЙрджрд╛рд╣рд░рдг: libbpf рд╡рд╛рдкрд░реВрди рдкреВрд░реНрдг ре▓рдкреНрд▓рд┐рдХреЗрд╢рди рддрдпрд╛рд░ рдХрд░рдгреЗ

рд╕реБрд░реБрд╡рд╛рддреАрд▓рд╛, рдЖрдореНрд╣реА рдлрд╛рдЗрд▓ рд╡рд╛рдкрд░рддреЛ /sys/kernel/btf/vmlinux, рдЬреНрдпрд╛рдЪрд╛ рд╡рд░ рдЙрд▓реНрд▓реЗрдЦ рдХреЗрд▓рд╛ рд╣реЛрддрд╛, рдЖрдгрд┐ рддреНрдпрд╛рдЪреНрдпрд╛ рд╕рдорддреБрд▓реНрдп рд╣реЗрдбрд░ рдлрд╛рдЗрд▓рдЪреНрдпрд╛ рд╕реНрд╡рд░реВрдкрд╛рдд рддрдпрд╛рд░ рдХрд░рд╛:

$ bpftool btf dump file /sys/kernel/btf/vmlinux format c > vmlinux.h

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

$ grep -A 12 'struct iphdr {' vmlinux.h
struct iphdr {
    __u8 ihl: 4;
    __u8 version: 4;
    __u8 tos;
    __be16 tot_len;
    __be16 id;
    __be16 frag_off;
    __u8 ttl;
    __u8 protocol;
    __sum16 check;
    __be32 saddr;
    __be32 daddr;
};

рдЖрддрд╛ рдЖрдореНрд╣реА рдЖрдордЪрд╛ BPF рдкреНрд░реЛрдЧреНрд░рд╛рдо C рдордзреНрдпреЗ рд▓рд┐рд╣реВ:

$ cat xdp-simple.bpf.c
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>

SEC("xdp/simple")
int simple(void *ctx)
{
        return XDP_PASS;
}

char LICENSE[] SEC("license") = "GPL";

рдЬрд░реА рдЖрдордЪрд╛ рдХрд╛рд░реНрдпрдХреНрд░рдо рдЕрдЧрджреА рд╕реЛрдкрд╛ рд╣реЛрддрд╛, рддрд░реАрд╣реА рдЖрдореНрд╣рд╛рд▓рд╛ рдмрд░реНрдпрд╛рдЪ рддрдкрд╢реАрд▓рд╛рдВрдХрдбреЗ рд▓рдХреНрд╖ рджреЗрдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ. рдкреНрд░рдердо, рдЖрдореНрд╣реА рд╕рдорд╛рд╡рд┐рд╖реНрдЯ рдХреЗрд▓реЗрд▓реА рдкрд╣рд┐рд▓реА рд╢реАрд░реНрд╖рд▓реЗрдЦ рдлрд╛рдЗрд▓ рдЖрд╣реЗ vmlinux.h, рдЬреЗ рдЖрдореНрд╣реА рд╡рд╛рдкрд░реВрди рддрдпрд╛рд░ рдХреЗрд▓реЗ рдЖрд╣реЗ bpftool btf dump - рдЖрддрд╛ рдХрд░реНрдирд▓ рд╕рдВрд░рдЪрдирд╛ рдХрд╢рд╛ рджрд┐рд╕рддрд╛рдд рд╣реЗ рд╢реЛрдзрдгреНрдпрд╛рд╕рд╛рдареА рдЖрдореНрд╣рд╛рд▓рд╛ рдХрд░реНрдирд▓-рд╣реЗрдбрд░ рдкреЕрдХреЗрдЬ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдгреНрдпрд╛рдЪреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╛рд╣реА. рдЦрд╛рд▓реАрд▓ рд╣реЗрдбрд░ рдлрд╛рдЗрд▓ рд▓рд╛рдпрдмреНрд░рд░реАрддреВрди рдЖрдордЪреНрдпрд╛рдХрдбреЗ рдпреЗрддреЗ libbpf. рдЖрддрд╛ рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рдлрдХреНрдд рдореЕрдХреНрд░реЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рддреНрдпрд╛рдЪреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЖрд╣реЗ SEC, рдЬреЗ рд╡рд░реНрдг ELF рдСрдмреНрдЬреЗрдХреНрдЯ рдлрд╛рдЗрд▓рдЪреНрдпрд╛ рдпреЛрдЧреНрдп рд╡рд┐рднрд╛рдЧрд╛рдд рдкрд╛рдард╡рддреЗ. рдЖрдордЪрд╛ рдХрд╛рд░реНрдпрдХреНрд░рдо рд╡рд┐рднрд╛рдЧрд╛рдд рд╕рдорд╛рд╡рд┐рд╖реНрдЯ рдЖрд╣реЗ xdp/simple, рдЬреЗрдереЗ рд╕реНрд▓реЕрд╢ рдХрд░рдгреНрдпрд╛рдкреВрд░реНрд╡реА рдЖрдореНрд╣реА рдкреНрд░реЛрдЧреНрд░рд╛рдо рдкреНрд░рдХрд╛рд░ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЛ BPF - рд╣реЗ рд╡рд╛рдкрд░рд▓реЗрд▓реЗ рдЕрдзрд┐рд╡реЗрд╢рди рдЖрд╣реЗ libbpf, рд╡рд┐рднрд╛рдЧрд╛рдЪреНрдпрд╛ рдирд╛рд╡рд╛рд╡рд░ рдЖрдзрд╛рд░рд┐рдд рддреЗ рд╕реНрдЯрд╛рд░реНрдЯрдЕрдкрд╡рд░ рдпреЛрдЧреНрдп рдкреНрд░рдХрд╛рд░ рдмрджрд▓реЗрд▓ bpf(2). BPF рдХрд╛рд░реНрдпрдХреНрд░рдо рд╕реНрд╡рддрдГ рдЖрд╣реЗ C - рдЕрддрд┐рд╢рдп рд╕реЛрдкреА рдЖрдгрд┐ рдПрдХрд╛ рдУрд│реАрдЪрд╛ рд╕рдорд╛рд╡реЗрд╢ рдЖрд╣реЗ return XDP_PASS. рд╢реЗрд╡рдЯреА, рдПрдХ рд╕реНрд╡рддрдВрддреНрд░ рд╡рд┐рднрд╛рдЧ "license" рдкрд░рд╡рд╛рдиреНрдпрд╛рдЪреЗ рдирд╛рд╡ рдЖрд╣реЗ.

рдЖрдореНрд╣реА рдЖрдордЪрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо llvm/clang, рдЖрд╡реГрддреНрддреА >= 10.0.0 рд╡рд╛рдкрд░реВрди рд╕рдВрдХрд▓рд┐рдд рдХрд░реВ рд╢рдХрддреЛ рдХрд┐рдВрд╡рд╛ рдЕрдЬреВрди рдЪрд╛рдВрдЧрд▓реЗ, рдореЛрдареЗ (рд╡рд┐рднрд╛рдЧ рдкрд╣рд╛ рд╡рд┐рдХрд╛рд╕ рд╕рд╛рдзрдиреЗ):

$ clang --version
clang version 11.0.0 (https://github.com/llvm/llvm-project.git afc287e0abec710398465ee1f86237513f2b5091)
...

$ clang -O2 -g -c -target bpf -I libbpf/src/root/usr/include xdp-simple.bpf.c -o xdp-simple.bpf.o

рдордиреЛрд░рдВрдЬрдХ рд╡реИрд╢рд┐рд╖реНрдЯреНрдпрд╛рдВрдкреИрдХреА: рдЖрдореНрд╣реА рд▓рдХреНрд╖реНрдп рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рд╕реВрдЪрд┐рдд рдХрд░рддреЛ -target bpf рдЖрдгрд┐ рд╢реАрд░реНрд╖рд▓реЗрдЦрд╛рдВрдЪрд╛ рдорд╛рд░реНрдЧ libbpf, рдЬреЗ рдЖрдореНрд╣реА рдЕрд▓реАрдХрдбреЗ рд╕реНрдерд╛рдкрд┐рдд рдХреЗрд▓реЗ рдЖрд╣реЗ. рддрд╕реЗрдЪ, рдмрджреНрджрд▓ рд╡рд┐рд╕рд░реВ рдирдХрд╛ -O2, рдпрд╛ рдкрд░реНрдпрд╛рдпрд╛рд╢рд┐рд╡рд╛рдп рддреБрдореНрд╣реА рднрд╡рд┐рд╖реНрдпрд╛рдд рдЖрд╢реНрдЪрд░реНрдпрдЪрдХрд┐рдд рд╣реЛрдК рд╢рдХрддрд╛. рдЪрд▓рд╛ рдЖрдордЪрд╛ рдХреЛрдб рдмрдШреВрдпрд╛, рдЖрдореНрд╣рд╛рд▓рд╛ рд╣рд╡рд╛ рддреЛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓рд┐рд╣рд╛рдпрд▓рд╛ рдЖрдореНрд╣реА рд╡реНрдпрд╡рд╕реНрдерд╛рдкрд┐рдд рдХреЗрд▓реЗ рдХрд╛?

$ llvm-objdump --section=xdp/simple --no-show-raw-insn -D xdp-simple.bpf.o

xdp-simple.bpf.o:       file format elf64-bpf

Disassembly of section xdp/simple:

0000000000000000 <simple>:
       0:       r0 = 2
       1:       exit

рд╣реЛрдп, рддреЗ рдХрд╛рдо рдХреЗрд▓реЗ! рдЖрддрд╛, рдЖрдордЪреНрдпрд╛рдХрдбреЗ рдкреНрд░реЛрдЧреНрд░рд╛рдорд╕рд╣ рдмрд╛рдпрдирд░реА рдлрд╛рдЗрд▓ рдЖрд╣реЗ, рдЖрдгрд┐ рдЖрдореНрд╣рд╛рд▓рд╛ рдПрдХ рдНрдкреНрд▓рд┐рдХреЗрд╢рди рддрдпрд╛рд░ рдХрд░рд╛рдпрдЪреЗ рдЖрд╣реЗ рдЬреЗ рддреЗ рдХрд░реНрдирд▓рдордзреНрдпреЗ рд▓реЛрдб рдХрд░реЗрд▓. рдпрд╛рд╕рд╛рдареА рдЧреНрд░рдВрдерд╛рд▓рдп libbpf рдЖрдореНрд╣рд╛рд▓рд╛ рджреЛрди рдкрд░реНрдпрд╛рдп рджреЗрддрд╛рдд - рдЦрд╛рд▓рдЪреНрдпрд╛-рд╕реНрддрд░реАрдп API рдХрд┐рдВрд╡рд╛ рдЙрдЪреНрдЪ-рд╕реНрддрд░реАрдп API рд╡рд╛рдкрд░рд╛. рдЖрдореНрд╣реА рджреБрд╕рд▒реНрдпрд╛ рдорд╛рд░реНрдЧрд╛рд╡рд░ рдЬрд╛рдК, рдХрд╛рд░рдг рдЖрдореНрд╣рд╛рд▓рд╛ BPF рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд╕реЗ рд▓рд┐рд╣рд╛рдпрдЪреЗ, рд▓реЛрдб рдХрд░рд╛рдпрдЪреЗ рдЖрдгрд┐ рддреНрдпрд╛рдВрдЪреНрдпрд╛ рдкреБрдвреАрд▓ рдЕрднреНрдпрд╛рд╕рд╛рд╕рд╛рдареА рдХрдореАрдд рдХрдореА рдкреНрд░рдпрддреНрдирд╛рдд рдХрд╕реЗ рдЬреЛрдбрд╛рдпрдЪреЗ рд╣реЗ рд╢рд┐рдХрд╛рдпрдЪреЗ рдЖрд╣реЗ.

рдкреНрд░рдердо, рддреНрдпрд╛рдЪ рдпреБрдЯрд┐рд▓рд┐рдЯреАрдЪрд╛ рд╡рд╛рдкрд░ рдХрд░реВрди рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рдЖрдкрд▓реНрдпрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдордЪрд╛ рдмрд╛рдпрдирд░реА рдордзреВрди тАЬрд╕реНрдХреЗрд▓реЗрдЯрдитАЭ рддрдпрд╛рд░ рдХрд░рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ. bpftool тАФ BPF рдЬрдЧрд╛рдЪрд╛ рд╕реНрд╡рд┐рд╕ рдЪрд╛рдХреВ (рдЬреНрдпрд╛рд▓рд╛ рд╢рдмреНрджрд╢рдГ рдШреЗрддрд▓реЗ рдЬрд╛рдК рд╢рдХрддреЗ, рдХрд╛рд░рдг рдбреЕрдирд┐рдпрд▓ рдмреЛрд░реНрдХрдорди, BPF рдЪреЗ рдирд┐рд░реНрдорд╛рддреЗ рдЖрдгрд┐ рджреЗрдЦрд░реЗрдЦ рдХрд░рдгрд╛рд░реЗ рдПрдХ рд╕реНрд╡рд┐рд╕ рдЖрд╣реЗрдд):

$ bpftool gen skeleton xdp-simple.bpf.o > xdp-simple.skel.h

рдлрд╛рдИрд▓рдордзреНрдпреЗ xdp-simple.skel.h рдЖрдордЪреНрдпрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдордЪрд╛ рдмрд╛рдпрдирд░реА рдХреЛрдб рдЖрдгрд┐ рд╡реНрдпрд╡рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдХрд╛рд░реНрдпреЗ - рд▓реЛрдб рдХрд░рдгреЗ, рд╕рдВрд▓рдЧреНрди рдХрд░рдгреЗ, рд╣рдЯрд╡рдгреЗ рд╕рдорд╛рд╡рд┐рд╖реНрдЯ рдЖрд╣реЗ. рдЖрдордЪреНрдпрд╛ рд╕рд╛рдзреНрдпрд╛ рдХреЗрд╕рдордзреНрдпреЗ рд╣реЗ рдУрд╡реНрд╣рд░рдХрд┐рд▓рд╕рд╛рд░рдЦреЗ рджрд┐рд╕рддреЗ, рдкрд░рдВрддреБ рдСрдмреНрдЬреЗрдХреНрдЯ рдлрд╛рдЗрд▓рдордзреНрдпреЗ рдЕрдиреЗрдХ рдмреАрдкреАрдПрдл рдкреНрд░реЛрдЧреНрд░рд╛рдореНрд╕ рдЖрдгрд┐ рдирдХрд╛рд╢реЗ рдЕрд╕рддрд╛рдд рдЕрд╢рд╛ рдмрд╛рдмрддреАрддрд╣реА рд╣реЗ рдХрд╛рд░реНрдп рдХрд░рддреЗ рдЖрдгрд┐ рд╣реЗ рд╡рд┐рд╢рд╛рд▓ ELF рд▓реЛрдб рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдЖрдореНрд╣рд╛рд▓рд╛ рдлрдХреНрдд рд╕рд╛рдВрдЧрд╛рдбрд╛ рддрдпрд╛рд░ рдХрд░рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ рдЖрдгрд┐ рдХрд╕реНрдЯрдо рдНрдкреНрд▓рд┐рдХреЗрд╢рдирдордзреВрди рдПрдХ рдХрд┐рдВрд╡рд╛ рджреЛрди рдлрдВрдХреНрд╢рдиреНрд╕ рдХреЙрд▓ рдХрд░рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ. рд▓рд┐рд╣рд┐рдд рдЖрд╣реЗрдд рдЪрд▓рд╛ рдЖрддрд╛ рдкреБрдвреЗ рдЬрд╛рдКрдпрд╛.

рдХрд╛рдЯреЗрдХреЛрд░рдкрдгреЗ рд╕рд╛рдВрдЧрд╛рдпрдЪреЗ рддрд░, рдЖрдордЪрд╛ рд▓реЛрдбрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреНрд╖реБрд▓реНрд▓рдХ рдЖрд╣реЗ:

#include <err.h>
#include <unistd.h>
#include "xdp-simple.skel.h"

int main(int argc, char **argv)
{
    struct xdp_simple_bpf *obj;

    obj = xdp_simple_bpf__open_and_load();
    if (!obj)
        err(1, "failed to open and/or load BPF objectn");

    pause();

    xdp_simple_bpf__destroy(obj);
}

рддреЛ рдЖрд╣реЗ struct xdp_simple_bpf рдлрд╛рдЗрд▓ рдордзреНрдпреЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд xdp-simple.skel.h рдЖрдгрд┐ рдЖрдордЪреНрдпрд╛ рдСрдмреНрдЬреЗрдХреНрдЯ рдлрд╛рдЗрд▓рдЪреЗ рд╡рд░реНрдгрди рдХрд░рддреЗ:

struct xdp_simple_bpf {
    struct bpf_object_skeleton *skeleton;
    struct bpf_object *obj;
    struct {
        struct bpf_program *simple;
    } progs;
    struct {
        struct bpf_link *simple;
    } links;
};

рдЖрдореНрд╣реА рдпреЗрдереЗ рдирд┐рдореНрди-рд╕реНрддрд░реАрдп API рдЪреЗ рдЯреНрд░реЗрд╕ рдкрд╛рд╣реВ рд╢рдХрддреЛ: рд░рдЪрдирд╛ struct bpf_program *simple ╨╕ struct bpf_link *simple. рдкреНрд░рдердо рд░рдЪрдирд╛ рд╡рд┐рд╢реЗрд╖рдд: рд╡рд┐рднрд╛рдЧрд╛рдд рд▓рд┐рд╣рд┐рд▓реЗрд▓реНрдпрд╛ рдЖрдордЪреНрдпрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдордЪреЗ рд╡рд░реНрдгрди рдХрд░рддреЗ xdp/simple, рдЖрдгрд┐ рджреБрд╕рд░рд╛ рдХрд╛рд░реНрдпрдХреНрд░рдо рдЗрд╡реНрд╣реЗрдВрдЯ рд╕реНрддреНрд░реЛрддрд╛рд╢реА рдХрд╕рд╛ рдЬреЛрдбрддреЛ рдпрд╛рдЪреЗ рд╡рд░реНрдгрди рдХрд░рддреЛ.

рдХрд╛рд░реНрдп xdp_simple_bpf__open_and_load, рдПрдЦрд╛рджреЗ рдИрдПрд▓рдПрдл рдСрдмреНрдЬреЗрдХреНрдЯ рдЙрдШрдбрддреЗ, рддреНрдпрд╛рдЪреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рддреЗ, рд╕рд░реНрд╡ рд╕рдВрд░рдЪрдирд╛ рдЖрдгрд┐ рд╕рдмрд╕реНрдЯреНрд░рдХреНрдЪрд░реНрд╕ рддрдпрд╛рд░ рдХрд░рддреЗ (рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╡реНрдпрддрд┐рд░рд┐рдХреНрдд, рдИрдПрд▓рдПрдлрдордзреНрдпреЗ рдЗрддрд░ рд╡рд┐рднрд╛рдЧ рджреЗрдЦреАрд▓ рдЕрд╕рддрд╛рдд - рдбреЗрдЯрд╛, рдХреЗрд╡рд│ рд╡рд╛рдЪрдиреАрдп рдбреЗрдЯрд╛, рдбреАрдмрдЧрд┐рдВрдЧ рдорд╛рд╣рд┐рддреА, рдкрд░рд╡рд╛рдирд╛ рдЗ.), рдЖрдгрд┐ рдирдВрддрд░ рд╕рд┐рд╕реНрдЯрдо рд╡рд╛рдкрд░реВрди рдХрд░реНрдирд▓рдордзреНрдпреЗ рд▓реЛрдб рдХрд░рддреЗ. рдХреЙрд▓ bpf, рдЬреЗ рдЖрдореНрд╣реА рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╕рдВрдХрд▓рд┐рдд рдЖрдгрд┐ рдЪрд╛рд▓рд╡реВрди рддрдкрд╛рд╕реВ рд╢рдХрддреЛ:

$ clang -O2 -I ./libbpf/src/root/usr/include/ xdp-simple.c -o xdp-simple ./libbpf/src/root/usr/lib64/libbpf.a -lelf -lz

$ sudo strace -e bpf ./xdp-simple
...
bpf(BPF_BTF_LOAD, 0x7ffdb8fd9670, 120)  = 3
bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_XDP, insn_cnt=2, insns=0xdfd580, license="GPL", log_level=0, log_size=0, log_buf=NULL, kern_version=KERNEL_VERSION(5, 8, 0), prog_flags=0, prog_name="simple", prog_ifindex=0, expected_attach_type=0x25 /* BPF_??? */, ...}, 120) = 4

рдЪрд▓рд╛ рдЖрддрд╛ рдЖрдордЪрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╡рд╛рдкрд░реВрди рдкрд╛рд╣реВ bpftool. рдЪрд▓рд╛ рддрд┐рдЪрд╛ рдЖрдпрдбреА рд╢реЛрдзреВрдпрд╛:

# bpftool p | grep -A4 simple
463: xdp  name simple  tag 3b185187f1855c4c  gpl
        loaded_at 2020-08-01T01:59:49+0000  uid 0
        xlated 16B  jited 40B  memlock 4096B
        btf_id 185
        pids xdp-simple(16498)

рдЖрдгрд┐ рдбрдВрдк (рдЖрдореНрд╣реА рдХрдорд╛рдВрдбрдЪрд╛ рдПрдХ рдЫреЛрдЯрд╛ рдлреЙрд░реНрдо рд╡рд╛рдкрд░рддреЛ bpftool prog dump xlated):

# bpftool p d x id 463
int simple(void *ctx):
; return XDP_PASS;
   0: (b7) r0 = 2
   1: (95) exit

рдХрд╛рд╣реАрддрд░реА рдирд╡реАрди! рдкреНрд░реЛрдЧреНрд░рд╛рдордиреЗ рдЖрдордЪреНрдпрд╛ C рд╕реНрддреНрд░реЛрдд рдлрд╛рдЗрд▓рдЪреЗ рднрд╛рдЧ рдЫрд╛рдкрд▓реЗ. рд╣реЗ рд▓рд╛рдпрдмреНрд░рд░реАрдиреЗ рдХреЗрд▓реЗ libbpf, рдЬреНрдпрд╛рдиреЗ рдмрд╛рдпрдирд░реАрдордзреНрдпреЗ рдбреАрдмрдЧ рд╡рд┐рднрд╛рдЧ рдЖрдврд│рд▓рд╛, рддреЛ BTF рдСрдмреНрдЬреЗрдХреНрдЯрдордзреНрдпреЗ рд╕рдВрдХрд▓рд┐рдд рдХреЗрд▓рд╛, рд╡рд╛рдкрд░реВрди рдХрд░реНрдирд▓рдордзреНрдпреЗ рд▓реЛрдб рдХреЗрд▓рд╛ BPF_BTF_LOAD, рдЖрдгрд┐ рдирдВрддрд░ рдХрдорд╛рдВрдбрд╕рд╣ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓реЛрдб рдХрд░рддрд╛рдирд╛ рдкрд░рд┐рдгрд╛рдореА рдлрд╛рдЗрд▓ рд╡рд░реНрдгрдирдХрд░реНрддрд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рд╛ BPG_PROG_LOAD.

рдХрд░реНрдирд▓ рдорджрддрдиреАрд╕

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

рдЙрджрд╛рд╣рд░рдг: bpf_get_smp_processor_id

"рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде рд╢рд┐рдХрдгреЗ" рдпрд╛ рдкреНрд░рддрд┐рдорд╛рдирд╛рдЪреНрдпрд╛ рдЪреМрдХрдЯреАрдд, рд╕рд╣рд╛рдпреНрдпрдХ рдХрд╛рд░реНрдпрд╛рдВрдкреИрдХреА рдПрдХрд╛рдЪрд╛ рд╡рд┐рдЪрд╛рд░ рдХрд░реВрдпрд╛, bpf_get_smp_processor_id(), рдирд┐рд╢реНрдЪрд┐рдд рдлрд╛рдЗрд▓ рдордзреНрдпреЗ kernel/bpf/helpers.c. рддреЛ рдкреНрд░реЛрд╕реЗрд╕рд░рдЪрд╛ рдирдВрдмрд░ рджреЗрддреЛ рдЬреНрдпрд╛рд╡рд░ BPF рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЪрд╛рд▓реВ рдЖрд╣реЗ. рдкрд░рдВрддреБ рдЖрдореНрд╣рд╛рд▓рд╛ рддреНрдпрд╛рдЪреНрдпрд╛ рдЕрд░реНрдерд╢рд╛рд╕реНрддреНрд░рд╛рдд рддрд┐рддрдХреЗ рд░рд╕ рдирд╛рд╣реА рдХрд╛рд░рдг рддреНрдпрд╛рдЪреА рдЕрдВрдорд▓рдмрдЬрд╛рд╡рдгреА рдПрдХ рдУрд│ рдШреЗрддреЗ:

BPF_CALL_0(bpf_get_smp_processor_id)
{
    return smp_processor_id();
}

BPF рд╣реЗрд▓реНрдкрд░ рдлрдВрдХреНрд╢рди рд╡реНрдпрд╛рдЦреНрдпрд╛ рд▓рд┐рдирдХреНрд╕ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рд╡реНрдпрд╛рдЦреНрдпреЗрдкреНрд░рдорд╛рдгреЗрдЪ рдЖрд╣реЗрдд. рдпреЗрдереЗ, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдХреЛрдгрддреЗрд╣реА рд╡рд┐рддрд░реНрдХ рдирд╕рд▓реЗрд▓реЗ рдлрдВрдХреНрд╢рди рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХреЗрд▓реЗ рдЖрд╣реЗ. (рдПрдХ рдлрдВрдХреНрд╢рди рдЬреЗ рддреАрди рд╡рд┐рддрд░реНрдХ рдШреЗрддреЗ, рдореНрд╣рдгрд╛, рдореЕрдХреНрд░реЛ рд╡рд╛рдкрд░реВрди рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХреЗрд▓реЗ рдЬрд╛рддреЗ BPF_CALL_3. рд╡рд┐рддрд░реНрдХрд╛рдВрдЪреА рдХрдорд╛рд▓ рд╕рдВрдЦреНрдпрд╛ рдкрд╛рдЪ рдЖрд╣реЗ.) рддрдерд╛рдкрд┐, рд╣рд╛ рдХреЗрд╡рд│ рд╡реНрдпрд╛рдЦреНрдпреЗрдЪрд╛ рдкрд╣рд┐рд▓рд╛ рднрд╛рдЧ рдЖрд╣реЗ. рджреБрд╕рд░рд╛ рднрд╛рдЧ рдкреНрд░рдХрд╛рд░ рд░рдЪрдирд╛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдЖрд╣реЗ struct bpf_func_proto, рдЬреНрдпрд╛рдордзреНрдпреЗ рд╣реЗрд▓реНрдкрд░ рдлрдВрдХреНрд╢рдирдЪреЗ рд╡рд░реНрдгрди рдЖрд╣реЗ рдЬреЗ рдкрдбрддрд╛рд│рдХрд╛рд▓рд╛ рд╕рдордЬрддреЗ:

const struct bpf_func_proto bpf_get_smp_processor_id_proto = {
    .func     = bpf_get_smp_processor_id,
    .gpl_only = false,
    .ret_type = RET_INTEGER,
};

рд╣реЗрд▓реНрдкрд░ рдлрдВрдХреНрд╢рдиреНрд╕рдЪреА рдиреЛрдВрджрдгреА рдХрд░рдгреЗ

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

static const struct bpf_func_proto *
xdp_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
{
    switch (func_id) {
    ...
    case BPF_FUNC_get_smp_processor_id:
        return &bpf_get_smp_processor_id_proto;
    ...
    }
}

рдирд╡реАрди BPF рдкреНрд░реЛрдЧреНрд░рд╛рдо рдкреНрд░рдХрд╛рд░ рдлрд╛рдЗрд▓рдордзреНрдпреЗ "рдкрд░рд┐рднрд╛рд╖рд┐рдд" рдЖрд╣реЗрдд include/linux/bpf_types.h рдореЕрдХреНрд░реЛ рд╡рд╛рдкрд░реВрди BPF_PROG_TYPE. рдЕрд╡рддрд░рдгрд╛рдВрдордзреНрдпреЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХреЗрд▓реЗ рдЖрд╣реЗ рдХрд╛рд░рдг рддреА рддрд╛рд░реНрдХрд┐рдХ рд╡реНрдпрд╛рдЦреНрдпрд╛ рдЖрд╣реЗ, рдЖрдгрд┐ C рднрд╛рд╖реЗрдЪреНрдпрд╛ рдЕрдЯреАрдВрдордзреНрдпреЗ рдХрдВрдХреНрд░реАрдЯ рд╕рдВрд░рдЪрдирд╛рдВрдЪреНрдпрд╛ рд╕рдВрдкреВрд░реНрдг рд╕рдВрдЪрд╛рдЪреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдЗрддрд░ рдард┐рдХрд╛рдгреА рдЖрдврд│рддреЗ. рд╡рд┐рд╢реЗрд╖рддрдГ, рдлрд╛рдЗрд▓рдордзреНрдпреЗ kernel/bpf/verifier.c рдлрд╛рдЗрд▓рдордзреАрд▓ рд╕рд░реНрд╡ рд╡реНрдпрд╛рдЦреНрдпрд╛ bpf_types.h рд╕реНрдЯреНрд░рдХреНрдЪрд░реНрд╕рдЪреА рдЕреЕрд░реЗ рддрдпрд╛рд░ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рд╡рд╛рдкрд░рд▓реА рдЬрд╛рддрд╛рдд bpf_verifier_ops[]:

static const struct bpf_verifier_ops *const bpf_verifier_ops[] = {
#define BPF_PROG_TYPE(_id, _name, prog_ctx_type, kern_ctx_type) 
    [_id] = & _name ## _verifier_ops,
#include <linux/bpf_types.h>
#undef BPF_PROG_TYPE
};

рдореНрд╣рдгрдЬреЗрдЪ, рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рдХрд╛рд░рдЪреНрдпрд╛ BPF рдкреНрд░реЛрдЧреНрд░рд╛рдорд╕рд╛рдареА, рдкреНрд░рдХрд╛рд░рд╛рдЪреНрдпрд╛ рдбреЗрдЯрд╛ рд╕реНрдЯреНрд░рдХреНрдЪрд░рд╕рд╛рдареА рдПрдХ рдкреЙрдЗрдВрдЯрд░ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХреЗрд▓рд╛ рдЬрд╛рддреЛ struct bpf_verifier_ops, рдЬреНрдпрд╛рдЪрд╛ рдкреНрд░рд╛рд░рдВрдн рдореВрд▓реНрдпрд╛рд╕рд╣ рдХреЗрд▓рд╛ рдЬрд╛рддреЛ _name ## _verifier_ops, рдореНрд╣рдгрдЬреЗ, xdp_verifier_ops рддреЗ xdp. рд░рдЪрдирд╛ xdp_verifier_ops рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдлрд╛рдЗрд▓ рдордзреНрдпреЗ net/core/filter.c рдЦрд╛рд▓реАрд▓рдкреНрд░рдорд╛рдгреЗ:

const struct bpf_verifier_ops xdp_verifier_ops = {
    .get_func_proto     = xdp_func_proto,
    .is_valid_access    = xdp_is_valid_access,
    .convert_ctx_access = xdp_convert_ctx_access,
    .gen_prologue       = bpf_noop_prologue,
};

рдпреЗрдереЗ рдЖрдкрдг рдЖрдкрд▓реЗ рдкрд░рд┐рдЪрд┐рдд рдХрд╛рд░реНрдп рдкрд╛рд╣рддреЛ xdp_func_proto, рдЬреЗ рдкреНрд░рддреНрдпреЗрдХ рд╡реЗрд│реА рдЖрд╡реНрд╣рд╛рдирд╛рдЪрд╛ рд╕рд╛рдордирд╛ рдХрд░рддрд╛рдирд╛ рд╕рддреНрдпрд╛рдкрдирдХрд░реНрддрд╛ рдЪрд╛рд▓рд╡реЗрд▓ рдХрд╛рд╣реА рдмреАрдкреАрдПрдл рдкреНрд░реЛрдЧреНрд░рд╛рдордордзреАрд▓ рдХрд╛рд░реНрдпреЗ, рдкрд╣рд╛ verifier.c.

рдХрд╛рд▓реНрдкрдирд┐рдХ BPF рдкреНрд░реЛрдЧреНрд░рд╛рдо рдлрдВрдХреНрд╢рдирдЪрд╛ рд╡рд╛рдкрд░ рдХрд╕рд╛ рдХрд░рддреЛ рддреЗ рдкрд╛рд╣реВ bpf_get_smp_processor_id. рд╣реЗ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА, рдЖрдореНрд╣реА рдЖрдордЪреНрдпрд╛ рдорд╛рдЧреАрд▓ рд╡рд┐рднрд╛рдЧрд╛рддреАрд▓ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЦрд╛рд▓реАрд▓рдкреНрд░рдорд╛рдгреЗ рдкреБрдиреНрд╣рд╛ рд▓рд┐рд╣рд┐рддреЛ:

#include "vmlinux.h"
#include <bpf/bpf_helpers.h>

SEC("xdp/simple")
int simple(void *ctx)
{
    if (bpf_get_smp_processor_id() != 0)
        return XDP_DROP;
    return XDP_PASS;
}

char LICENSE[] SEC("license") = "GPL";

рдкреНрд░рддреАрдХ bpf_get_smp_processor_id рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд ╨▓ <bpf/bpf_helper_defs.h> рдЧреНрд░рдВрдерд╛рд▓рдпреЗ libbpf рдХрд╕реЗ

static u32 (*bpf_get_smp_processor_id)(void) = (void *) 8;

рддреЗ рдЖрд╣реЗ, bpf_get_smp_processor_id рдПрдХ рдлрдВрдХреНрд╢рди рдкреЙрдЗрдВрдЯрд░ рдЖрд╣реЗ рдЬреНрдпрд╛рдЪреЗ рдореВрд▓реНрдп 8 рдЖрд╣реЗ, рдЬреЗрдереЗ 8 рд╣реЗ рдореВрд▓реНрдп рдЖрд╣реЗ BPF_FUNC_get_smp_processor_id рдкреНрд░рдХрд╛рд░ enum bpf_fun_id, рдЬреЗ рдЖрдордЪреНрдпрд╛рд╕рд╛рдареА рдлрд╛рдЗрд▓рдордзреНрдпреЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХреЗрд▓реЗ рдЖрд╣реЗ vmlinux.h (рдлрд╛рдЗрд▓ bpf_helper_defs.h рдХрд░реНрдирд▓рдордзреНрдпреЗ рд╕реНрдХреНрд░рд┐рдкреНрдЯрджреНрд╡рд╛рд░реЗ рд╡реНрдпреБрддреНрдкрдиреНрди рдХреЗрд▓реЗ рдЬрд╛рддреЗ, рдореНрд╣рдгреВрди "рдЬрд╛рджреВ" рд╕рдВрдЦреНрдпрд╛ рдареАрдХ рдЖрд╣реЗрдд). рд╣реЗ рдлрдВрдХреНрд╢рди рдХреЛрдгрддреЗрд╣реА рд╡рд┐рддрд░реНрдХ рдШреЗрдд рдирд╛рд╣реА рдЖрдгрд┐ рдкреНрд░рдХрд╛рд░рд╛рдЪреЗ рдореВрд▓реНрдп рдорд┐рд│рд╡рддреЗ __u32. рдЬреЗрд╡реНрд╣рд╛ рдЖрдореНрд╣реА рддреЗ рдЖрдордЪреНрдпрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдордордзреНрдпреЗ рдЪрд╛рд▓рд╡рддреЛ, clang рдПрдХ рд╕реВрдЪрдирд╛ рд╡реНрдпреБрддреНрдкрдиреНрди рдХрд░рддреЗ BPF_CALL "рдпреЛрдЧреНрдп рдкреНрд░рдХрд╛рд░" рдЪрд▓рд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╕рдВрдХрд▓рд┐рдд рдХрд░реВ рдЖрдгрд┐ рд╡рд┐рднрд╛рдЧ рдкрд╛рд╣реВ xdp/simple:

$ clang -O2 -g -c -target bpf -I libbpf/src/root/usr/include xdp-simple.bpf.c -o xdp-simple.bpf.o
$ llvm-objdump -D --section=xdp/simple xdp-simple.bpf.o

xdp-simple.bpf.o:       file format elf64-bpf

Disassembly of section xdp/simple:

0000000000000000 <simple>:
       0:       85 00 00 00 08 00 00 00 call 8
       1:       bf 01 00 00 00 00 00 00 r1 = r0
       2:       67 01 00 00 20 00 00 00 r1 <<= 32
       3:       77 01 00 00 20 00 00 00 r1 >>= 32
       4:       b7 00 00 00 02 00 00 00 r0 = 2
       5:       15 01 01 00 00 00 00 00 if r1 == 0 goto +1 <LBB0_2>
       6:       b7 00 00 00 01 00 00 00 r0 = 1

0000000000000038 <LBB0_2>:
       7:       95 00 00 00 00 00 00 00 exit

рдкрд╣рд┐рд▓реНрдпрд╛ рдУрд│реАрдд рдЖрдкрдг рд╕реВрдЪрдирд╛ рдкрд╛рд╣рддреЛ call, рдкреЕрд░рд╛рдореАрдЯрд░ IMM рдЬреЗ 8 рдЪреНрдпрд╛ рдмрд░реЛрдмрд░реАрдЪреЗ рдЖрд╣реЗ, рдЖрдгрд┐ SRC_REG - рд╢реВрдиреНрдп. рд╕рддреНрдпрд╛рдкрдирдХрд░реНрддреНрдпрд╛рджреНрд╡рд╛рд░реЗ рд╡рд╛рдкрд░рд▓реНрдпрд╛ рдЬрд╛рдгрд╛рд░реНтАНрдпрд╛ ABI рдХрд░рд╛рд░рд╛рдиреБрд╕рд╛рд░, рд╣реЗ рд╣реЗрд▓реНрдкрд░ рдлрдВрдХреНрд╢рди рдХреНрд░рдорд╛рдВрдХ рдЖрдард▓рд╛ рдХреЙрд▓ рдЖрд╣реЗ. рдПрдХрджрд╛ рддреЗ рд▓рд╛рдБрдЪ рдХреЗрд▓реЗ рдХреА, рддрд░реНрдХ рд╕реЛрдкреЗ рдЖрд╣реЗ. рд░рдЬрд┐рд╕реНрдЯрд░рдордзреВрди рдкрд░рддрд╛рд╡рд╛ рдореВрд▓реНрдп r0 рд╡рд░ рдХреЙрдкреА рдХреЗрд▓реЗ r1 рдЖрдгрд┐ рдУрд│реА 2,3 рд╡рд░ рддреЗ рдЯрд╛рдЗрдкрдордзреНрдпреЗ рд░реВрдкрд╛рдВрддрд░рд┐рдд рдХреЗрд▓реЗ рдЬрд╛рддреЗ u32 - рд╡рд░рдЪреЗ 32 рдмрд┐рдЯ рд╕рд╛рдл рдХреЗрд▓реЗ рдЖрд╣реЗрдд. 4,5,6,7 рдУрд│реАрдВрд╡рд░ рдЖрдореНрд╣реА 2 рдкрд░рдд рдХрд░рддреЛ (XDP_PASS) рдХрд┐рдВрд╡рд╛ 1 (XDP_DROP) рдУрд│ 0 рдордзреАрд▓ рд╣реЗрд▓реНрдкрд░ рдлрдВрдХреНрд╢рдирдиреЗ рд╢реВрдиреНрдп рдХрд┐рдВрд╡рд╛ рд╢реВрдиреНрдп рдирд╕рд▓реЗрд▓реЗ рдореВрд▓реНрдп рдкрд░рдд рдХреЗрд▓реЗ рдпрд╛рд╡рд░ рдЕрд╡рд▓рдВрдмреВрди.

рдЪрд▓рд╛ рд╕реНрд╡рддрдГрдЪреА рдЪрд╛рдЪрдгреА рдШреЗрдК: рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓реЛрдб рдХрд░рд╛ рдЖрдгрд┐ рдЖрдЙрдЯрдкреБрдЯ рдкрд╣рд╛ bpftool prog dump xlated:

$ bpftool gen skeleton xdp-simple.bpf.o > xdp-simple.skel.h
$ clang -O2 -g -I ./libbpf/src/root/usr/include/ -o xdp-simple xdp-simple.c ./libbpf/src/root/usr/lib64/libbpf.a -lelf -lz
$ sudo ./xdp-simple &
[2] 10914

$ sudo bpftool p | grep simple
523: xdp  name simple  tag 44c38a10c657e1b0  gpl
        pids xdp-simple(10915)

$ sudo bpftool p d x id 523
int simple(void *ctx):
; if (bpf_get_smp_processor_id() != 0)
   0: (85) call bpf_get_smp_processor_id#114128
   1: (bf) r1 = r0
   2: (67) r1 <<= 32
   3: (77) r1 >>= 32
   4: (b7) r0 = 2
; }
   5: (15) if r1 == 0x0 goto pc+1
   6: (b7) r0 = 1
   7: (95) exit

рдареАрдХ рдЖрд╣реЗ, рдкрдбрддрд╛рд│рдХрд╛рд▓рд╛ рдпреЛрдЧреНрдп рдХрд░реНрдирд▓-рд╣реЗрд▓реНрдкрд░ рд╕рд╛рдкрдбрд▓рд╛.

рдЙрджрд╛рд╣рд░рдг: рдпреБрдХреНрддрд┐рд╡рд╛рдж рдкрд╛рд╕ рдХрд░рдгреЗ рдЖрдгрд┐ рд╢реЗрд╡рдЯреА рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЪрд╛рд▓рд╡рдгреЗ!

рд╕рд░реНрд╡ рд░рди-рд▓реЗрд╡реНрд╣рд▓ рд╣реЗрд▓реНрдкрд░ рдлрдВрдХреНрд╢рдиреНрд╕рдЪрд╛ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдЕрд╕рддреЛ

u64 fn(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5)

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

рдЪрд▓рд╛ рдирд╡реАрди рдХрд░реНрдирд▓ рд╣реЗрд▓реНрдкрд░ рдЖрдгрд┐ BPF рдкреЕрд░рд╛рдореАрдЯрд░реНрд╕ рдХрд╕реЗ рдкрд╛рд╕ рдХрд░рддреЗ рддреЗ рдкрд╛рд╣реВ. рдЪрд▓рд╛ рдкреБрдиреНрд╣рд╛ рд▓рд┐рд╣реВ xdp-simple.bpf.c рдЦрд╛рд▓реАрд▓рдкреНрд░рдорд╛рдгреЗ (рдЙрд░реНрд╡рд░рд┐рдд рдУрд│реА рдмрджрд▓рд▓реНрдпрд╛ рдирд╛рд╣реАрдд):

SEC("xdp/simple")
int simple(void *ctx)
{
    bpf_printk("running on CPU%un", bpf_get_smp_processor_id());
    return XDP_PASS;
}

рдЖрдордЪрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЬреНрдпрд╛ рд╕реАрдкреАрдпреВрд╡рд░ рдЪрд╛рд▓реВ рдЖрд╣реЗ рддреНрдпрд╛рдЪрд╛ рдирдВрдмрд░ рдкреНрд░рд┐рдВрдЯ рдХрд░рддреЛ. рдЪрд▓рд╛ рддреЗ рд╕рдВрдХрд▓рд┐рдд рдХрд░реВ рдЖрдгрд┐ рдХреЛрдб рдкрд╛рд╣реВ:

$ llvm-objdump -D --section=xdp/simple --no-show-raw-insn xdp-simple.bpf.o

0000000000000000 <simple>:
       0:       r1 = 10
       1:       *(u16 *)(r10 - 8) = r1
       2:       r1 = 8441246879787806319 ll
       4:       *(u64 *)(r10 - 16) = r1
       5:       r1 = 2334956330918245746 ll
       7:       *(u64 *)(r10 - 24) = r1
       8:       call 8
       9:       r1 = r10
      10:       r1 += -24
      11:       r2 = 18
      12:       r3 = r0
      13:       call 6
      14:       r0 = 2
      15:       exit

рдУрд│реА 0-7 рдордзреНрдпреЗ рдЖрдореНрд╣реА рд╕реНрдЯреНрд░рд┐рдВрдЧ рд▓рд┐рд╣рд┐рддреЛ running on CPU%un, рдЖрдгрд┐ рдирдВрддрд░ рдУрд│ 8 рд╡рд░ рдЖрдореНрд╣реА рдкрд░рд┐рдЪрд┐рдд рдПрдХ рдЪрд╛рд▓рд╡рддреЛ bpf_get_smp_processor_id. рдУрд│реА 9-12 рд╡рд░ рдЖрдореНрд╣реА рдорджрддрдиреАрд╕ рдпреБрдХреНрддрд┐рд╡рд╛рдж рддрдпрд╛рд░ рдХрд░рддреЛ bpf_printk - рдиреЛрдВрджрдгреА r1, r2, r3. рддреНрдпрд╛рдкреИрдХреА рддреАрди рдХрд╛ рдЖрд╣реЗрдд рдЖрдгрд┐ рджреЛрди рдирд╛рд╣реАрдд? рдХрд╛рд░рдг bpf_printkрд╣реЗ рдореЕрдХреНрд░реЛ рд░реЕрдкрд░ рдЖрд╣реЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдорджрддрдиреАрд╕рднреЛрд╡рддреА bpf_trace_printk, рдЬреНрдпрд╛рд▓рд╛ рдлреЙрд░рдореЕрдЯ рд╕реНрдЯреНрд░рд┐рдВрдЧрдЪрд╛ рдЖрдХрд╛рд░ рдкрд╛рд╕ рдХрд░рдгреЗ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ.

рдЖрддрд╛ рдпрд╛рдд рджреЛрди рдУрд│реА рдЬреЛрдбреВ xdp-simple.cрдЬреЗрдгреЗрдХрд░реВрди рдЖрдордЪрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЗрдВрдЯрд░рдлреЗрд╕рд╢реА рдХрдиреЗрдХреНрдЯ рд╣реЛрдИрд▓ lo рдЖрдгрд┐ рдЦрд░реЛрдЦрд░ рд╕реБрд░реБрд╡рд╛рдд рдХреЗрд▓реА!

$ cat xdp-simple.c
#include <linux/if_link.h>
#include <err.h>
#include <unistd.h>
#include "xdp-simple.skel.h"

int main(int argc, char **argv)
{
    __u32 flags = XDP_FLAGS_SKB_MODE;
    struct xdp_simple_bpf *obj;

    obj = xdp_simple_bpf__open_and_load();
    if (!obj)
        err(1, "failed to open and/or load BPF objectn");

    bpf_set_link_xdp_fd(1, -1, flags);
    bpf_set_link_xdp_fd(1, bpf_program__fd(obj->progs.simple), flags);

cleanup:
    xdp_simple_bpf__destroy(obj);
}

рдпреЗрдереЗ рдЖрдкрдг рдлрдВрдХреНрд╢рди рд╡рд╛рдкрд░рддреЛ bpf_set_link_xdp_fd, рдЬреЗ XDP-рдкреНрд░рдХрд╛рд░рдЪреЗ BPF рдкреНрд░реЛрдЧреНрд░рд╛рдо рдиреЗрдЯрд╡рд░реНрдХ рдЗрдВрдЯрд░рдлреЗрд╕рд╢реА рдЬреЛрдбрддреЗ. рдЖрдореНрд╣реА рдЗрдВрдЯрд░рдлреЗрд╕ рдирдВрдмрд░ рд╣рд╛рд░реНрдбрдХреЛрдб рдХреЗрд▓рд╛ lo, рдЬреЗ рдиреЗрд╣рдореА 1 рдЕрд╕рддреЗ. рдЬреБрдирд╛ рдкреНрд░реЛрдЧреНрд░реЕрдо рдЬреЛрдбрд▓реЗрд▓рд╛ рдЕрд╕реЗрд▓ рддрд░ рдкреНрд░рдердо рддреЛ рд╡реЗрдЧрд│реЗ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдЖрдореНрд╣реА рдлрдВрдХреНрд╢рди рджреЛрдирджрд╛ рдЪрд╛рд▓рд╡рддреЛ. рд▓рдХреНрд╖рд╛рдд рдШреНрдпрд╛ рдХреА рдЖрддрд╛ рдЖрдореНрд╣рд╛рд▓рд╛ рдЖрд╡реНрд╣рд╛рдирд╛рдЪреА рдЧрд░рдЬ рдирд╛рд╣реА pause рдХрд┐рдВрд╡рд╛ рдЕрдирдВрдд рд▓реВрдк: рдЖрдордЪрд╛ рд▓реЛрдбрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдмрд╛рд╣реЗрд░ рдкрдбреЗрд▓, рдкрд░рдВрддреБ рдмреАрдкреАрдПрдл рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЗрд╡реНрд╣реЗрдВрдЯ рд╕реНрддреНрд░реЛрддрд╛рд╢реА рдЬреЛрдбрд▓реЗрд▓рд╛ рдЕрд╕рд▓реНрдпрд╛рдиреЗ рддреЛ рдорд╛рд░рд▓рд╛ рдЬрд╛рдгрд╛рд░ рдирд╛рд╣реА. рдпрд╢рд╕реНрд╡реА рдбрд╛рдЙрдирд▓реЛрдб рдЖрдгрд┐ рдХрдиреЗрдХреНрд╢рдирдирдВрддрд░, рдкреЛрд╣реЛрдЪрдгрд╛рд▒реНрдпрд╛ рдкреНрд░рддреНрдпреЗрдХ рдиреЗрдЯрд╡рд░реНрдХ рдкреЕрдХреЗрдЯрд╕рд╛рдареА рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓реЙрдиреНрдЪ рдХреЗрд▓рд╛ рдЬрд╛рдИрд▓ lo.

рдЪрд▓рд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдбрд╛рдЙрдирд▓реЛрдб рдХрд░реВ рдЖрдгрд┐ рдЗрдВрдЯрд░рдлреЗрд╕ рдкрд╛рд╣реВ lo:

$ sudo ./xdp-simple
$ sudo bpftool p | grep simple
669: xdp  name simple  tag 4fca62e77ccb43d6  gpl
$ ip l show dev lo
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 xdpgeneric qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    prog/xdp id 669

рдЖрдореНрд╣реА рдбрд╛рдЙрдирд▓реЛрдб рдХреЗрд▓реЗрд▓реНрдпрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдордордзреНрдпреЗ ID 669 рдЖрд╣реЗ рдЖрдгрд┐ рдЖрдореНрд╣рд╛рд▓рд╛ рддреЛрдЪ ID рдЗрдВрдЯрд░рдлреЗрд╕рд╡рд░ рджрд┐рд╕рддреЛ lo. рдЖрдореНрд╣реА рдХрд╛рд╣реА рдкреЕрдХреЗрдЬреЗрд╕ рдкрд╛рдард╡реВ 127.0.0.1 (рд╡рд┐рдирдВрддреА + рдЙрддреНрддрд░):

$ ping -c1 localhost

рдЖрдгрд┐ рдЖрддрд╛ рдбреАрдмрдЧ рд╡реНрд╣рд░реНрдЪреНрдпреБрдЕрд▓ рдлрд╛рдИрд▓рдЪреА рд╕рд╛рдордЧреНрд░реА рдкрд╛рд╣реВ /sys/kernel/debug/tracing/trace_pipe, рдЬреНрдпрд╛рдордзреНрдпреЗ bpf_printk рддреНрдпрд╛рдЪреЗ рд╕рдВрджреЗрд╢ рд▓рд┐рд╣рд┐рддрд╛рдд:

# cat /sys/kernel/debug/tracing/trace_pipe
ping-13937 [000] d.s1 442015.377014: bpf_trace_printk: running on CPU0
ping-13937 [000] d.s1 442015.377027: bpf_trace_printk: running on CPU0

рддреНрдпрд╛рд╡рд░ рджреЛрди рдкреЕрдХреЗрдЬреЗрд╕ рджрд┐рд╕рд▓реНрдпрд╛ lo рдЖрдгрд┐ CPU0 рд╡рд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗрд▓реА - рдЖрдордЪрд╛ рдкрд╣рд┐рд▓рд╛ рдкреВрд░реНрдг рд╡рд╛рдв рдЭрд╛рд▓реЗрд▓рд╛ рдЕрд░реНрдерд╣реАрди BPF рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд╛рдо рдХрд░рддреЛ!

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

BPF рдкреНрд░реЛрдЧреНрд░рд╛рдордордзреВрди рдирдХрд╛рд╢реЗ рдНрдХреНрд╕реЗрд╕ рдХрд░рдгреЗ

рдЙрджрд╛рд╣рд░рдг: BPF рдкреНрд░реЛрдЧреНрд░рд╛рдордордзреАрд▓ рдирдХрд╛рд╢рд╛ рд╡рд╛рдкрд░рдгреЗ

рдорд╛рдЧреАрд▓ рднрд╛рдЧрд╛рдВрдордзреНрдпреЗ рдЖрдкрдг рдпреБрдЬрд░ рд╕реНрдкреЗрд╕рдордзреВрди рдирдХрд╛рд╢реЗ рдХрд╕реЗ рдмрдирд╡рд╛рдпрдЪреЗ рдЖрдгрд┐ рдХрд╕реЗ рд╡рд╛рдкрд░рд╛рдпрдЪреЗ рддреЗ рд╢рд┐рдХрд▓реЛ рдЖрдгрд┐ рдЖрддрд╛ рдХрд░реНрдирд▓рдЪрд╛ рднрд╛рдЧ рдкрд╛рд╣реВ. рдЪрд▓рд╛, рдиреЗрд╣рдореАрдкреНрд░рдорд╛рдгреЗ, рдПрдХрд╛ рдЙрджрд╛рд╣рд░рдгрд╛рд╕рд╣ рдкреНрд░рд╛рд░рдВрдн рдХрд░реВрдпрд╛. рдЪрд▓рд╛ рдЖрдкрд▓рд╛ рдХрд╛рд░реНрдпрдХреНрд░рдо рдкреБрдиреНрд╣рд╛ рд▓рд┐рд╣реВ xdp-simple.bpf.c рдЦрд╛рд▓реАрд▓рдкреНрд░рдорд╛рдгреЗ:

#include "vmlinux.h"
#include <bpf/bpf_helpers.h>

struct {
    __uint(type, BPF_MAP_TYPE_ARRAY);
    __uint(max_entries, 8);
    __type(key, u32);
    __type(value, u64);
} woo SEC(".maps");

SEC("xdp/simple")
int simple(void *ctx)
{
    u32 key = bpf_get_smp_processor_id();
    u32 *val;

    val = bpf_map_lookup_elem(&woo, &key);
    if (!val)
        return XDP_ABORTED;

    *val += 1;

    return XDP_PASS;
}

char LICENSE[] SEC("license") = "GPL";

рдХрд╛рд░реНрдпрдХреНрд░рдорд╛рдЪреНрдпрд╛ рд╕реБрд░реБрд╡рд╛рддреАрд▓рд╛ рдЖрдореНрд╣реА рдирдХрд╛рд╢рд╛рдЪреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдЬреЛрдбрд▓реА woo: рд╣рд╛ 8-рдШрдЯрдХрд╛рдВрдЪрд╛ рдЕреЕрд░реЗ рдЖрд╣реЗ рдЬреЛ рд╕рд╛рд░рдЦреА рдореВрд▓реНрдпреЗ рд╕рд╛рдард╡рддреЛ u64 (C рдордзреНрдпреЗ рдЖрдореНрд╣реА рдЕрд╢рд╛ рдЕреЕрд░реЗрдЪреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХрд░реВ u64 woo[8]). рдПрдХрд╛ рдХрд╛рд░реНрдпрдХреНрд░рдорд╛рдд "xdp/simple" рдЖрдореНрд╣рд╛рд▓рд╛ рд╕рдзреНрдпрд╛рдЪрд╛ рдкреНрд░реЛрд╕реЗрд╕рд░ рдХреНрд░рдорд╛рдВрдХ рд╡реНрд╣реЗрд░рд┐рдПрдмрд▓рдордзреНрдпреЗ рдорд┐рд│рддреЛ key рдЖрдгрд┐ рдирдВрддрд░ рд╣реЗрд▓реНрдкрд░ рдлрдВрдХреНрд╢рди рд╡рд╛рдкрд░реВрди bpf_map_lookup_element рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рдЕреЕрд░реЗрдордзреАрд▓ рд╕рдВрдмрдВрдзрд┐рдд рдПрдВрдЯреНрд░реАрд╕рд╛рдареА рдПрдХ рдкреЙрдЗрдВрдЯрд░ рдорд┐рд│реЗрд▓, рдЬреЛ рдЖрдкрдг рдПрдХрд╛рдиреЗ рд╡рд╛рдврд╡рддреЛ. рд░рд╢рд┐рдпрдирдордзреНрдпреЗ рдЕрдиреБрд╡рд╛рджрд┐рдд: рдЖрдореНрд╣реА рдЖрдХрдбреЗрд╡рд╛рд░реАрдЪреА рдЧрдгрдирд╛ рдХрд░рддреЛ рдЬреНрдпрд╛рд╡рд░ CPU рдиреЗ рдЗрдирдХрдорд┐рдВрдЧ рдкреЕрдХреЗрдЯрд╡рд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗрд▓реА. рдЪрд▓рд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЪрд╛рд▓рд╡рдгреНрдпрд╛рдЪрд╛ рдкреНрд░рдпрддреНрди рдХрд░реВрдпрд╛:

$ clang -O2 -g -c -target bpf -I libbpf/src/root/usr/include xdp-simple.bpf.c -o xdp-simple.bpf.o
$ bpftool gen skeleton xdp-simple.bpf.o > xdp-simple.skel.h
$ clang -O2 -g -I ./libbpf/src/root/usr/include/ -o xdp-simple xdp-simple.c ./libbpf/src/root/usr/lib64/libbpf.a -lelf -lz
$ sudo ./xdp-simple

рдЪрд▓рд╛ рддрдкрд╛рд╕реВрдпрд╛ рдХреА рддрд┐рд▓рд╛ рд╣реБрдХ рдЕрдк рдЖрд╣реЗ lo рдЖрдгрд┐ рдХрд╛рд╣реА рдкреЕрдХреЗрдЯ рдкрд╛рдард╡рд╛:

$ ip l show dev lo
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 xdpgeneric qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    prog/xdp id 108

$ for s in `seq 234`; do sudo ping -f -c 100 127.0.0.1 >/dev/null 2>&1; done

рдЖрддрд╛ рдЕреЕрд░реЗрдЪреА рд╕рд╛рдордЧреНрд░реА рдкрд╛рд╣реВ:

$ sudo bpftool map dump name woo
[
    { "key": 0, "value": 0 },
    { "key": 1, "value": 400 },
    { "key": 2, "value": 0 },
    { "key": 3, "value": 0 },
    { "key": 4, "value": 0 },
    { "key": 5, "value": 0 },
    { "key": 6, "value": 0 },
    { "key": 7, "value": 46400 }
]

рдЬрд╡рд│рдЬрд╡рд│ рд╕рд░реНрд╡ рдкреНрд░рдХреНрд░рд┐рдпрд╛ CPU7 рд╡рд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗрд▓реНрдпрд╛ рдЧреЗрд▓реНрдпрд╛. рд╣реЗ рдЖрдордЪреНрдпрд╛рд╕рд╛рдареА рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ рдирд╛рд╣реА, рдореБрдЦреНрдп рдЧреЛрд╖реНрдЯ рдЕрд╢реА рдЖрд╣реЗ рдХреА рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд╛рд░реНрдп рдХрд░рддреЛ рдЖрдгрд┐ рдЖрдореНрд╣рд╛рд▓рд╛ BPF рдкреНрд░реЛрдЧреНрд░рд╛рдордордзреВрди рдирдХрд╛рд╢реЗ рдХрд╕реЗ рдНрдХреНрд╕реЗрд╕ рдХрд░рд╛рдпрдЪреЗ рд╣реЗ рд╕рдордЬрддреЗ - рд╡рд╛рдкрд░реВрди ╤Е╨╡╨╗╨┐╨╡╤А╨╛╨▓ bpf_mp_*.

рдЧреВрдв рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ

рдореНрд╣рдгреВрди, рдЖрдореНрд╣реА рдХреЙрд▓реНрд╕ рд╡рд╛рдкрд░реВрди BPF рдкреНрд░реЛрдЧреНрд░рд╛рдордордзреВрди рдирдХрд╛рд╢рд╛рд╡рд░ рдкреНрд░рд╡реЗрд╢ рдХрд░реВ рд╢рдХрддреЛ

val = bpf_map_lookup_elem(&woo, &key);

рдЬреЗрдереЗ рд╣реЗрд▓реНрдкрд░ рдлрдВрдХреНрд╢рди рдЕрд╕реЗ рджрд┐рд╕рддреЗ

void *bpf_map_lookup_elem(struct bpf_map *map, const void *key)

рдкрдг рдЖрдореНрд╣реА рдПрдХ рдкреЙрдЗрдВрдЯрд░ рдкрд╛рд╕ рдХрд░рдд рдЖрд╣реЛрдд &woo рдЕрдЬреНрдЮрд╛рдд рд╕рдВрд░рдЪрдиреЗрдХрдбреЗ struct { ... }...

рдЬрд░ рдЖрдкрдг рдкреНрд░реЛрдЧреНрд░реЕрдо рдЕрд╕реЗрдВрдмрд▓рд░ рдкрд╛рд╣рд┐рд▓рд╛ рддрд░ рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рддреЗ рдореВрд▓реНрдп рджрд┐рд╕рддреЗ &woo рдкреНрд░рддреНрдпрдХреНрд╖рд╛рдд рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХреЗрд▓реЗрд▓реЗ рдирд╛рд╣реА (рдУрд│ 4):

llvm-objdump -D --section xdp/simple xdp-simple.bpf.o

xdp-simple.bpf.o:       file format elf64-bpf

Disassembly of section xdp/simple:

0000000000000000 <simple>:
       0:       85 00 00 00 08 00 00 00 call 8
       1:       63 0a fc ff 00 00 00 00 *(u32 *)(r10 - 4) = r0
       2:       bf a2 00 00 00 00 00 00 r2 = r10
       3:       07 02 00 00 fc ff ff ff r2 += -4
       4:       18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0 ll
       6:       85 00 00 00 01 00 00 00 call 1
...

рдЖрдгрд┐ рдкреБрдирд░реНрд╕реНрдерд╛рдкрдирд╛ рдордзреНрдпреЗ рд╕рдорд╛рд╡рд┐рд╖реНрдЯ рдЖрд╣реЗ:

$ llvm-readelf -r xdp-simple.bpf.o | head -4

Relocation section '.relxdp/simple' at offset 0xe18 contains 1 entries:
    Offset             Info             Type               Symbol's Value  Symbol's Name
0000000000000020  0000002700000001 R_BPF_64_64            0000000000000000 woo

рдкрд░рдВрддреБ рдЬрд░ рдЖрдкрдг рдЖрдзреАрдЪ рд▓реЛрдб рдХреЗрд▓реЗрд▓рд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдкрд╛рд╣рд┐рд▓рд╛ рддрд░ рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рдпреЛрдЧреНрдп рдирдХрд╛рд╢рд╛рдХрдбреЗ рдПрдХ рдкреЙрдЗрдВрдЯрд░ рджрд┐рд╕реЗрд▓ (рдУрд│ 4):

$ sudo bpftool prog dump x name simple
int simple(void *ctx):
   0: (85) call bpf_get_smp_processor_id#114128
   1: (63) *(u32 *)(r10 -4) = r0
   2: (bf) r2 = r10
   3: (07) r2 += -4
   4: (18) r1 = map[id:64]
...

рдЕрд╢рд╛рдкреНрд░рдХрд╛рд░реЗ, рдЖрдореНрд╣реА рдЕрд╕рд╛ рдирд┐рд╖реНрдХрд░реНрд╖ рдХрд╛рдвреВ рд╢рдХрддреЛ рдХреА рдЖрдордЪрд╛ рд▓реЛрдбрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓реЙрдиреНрдЪ рдХрд░рдгреНрдпрд╛рдЪреНрдпрд╛ рд╡реЗрд│реА, рдпрд╛рдЪреА рд▓рд┐рдВрдХ &woo рд▓рд╛рдпрдмреНрд░рд░реАрдиреЗ рдХрд╛рд╣реАрддрд░реА рдмрджрд▓рд▓реЗ libbpf. рдкреНрд░рдердо рдЖрдкрдг рдЖрдЙрдЯрдкреБрдЯ рдкрд╛рд╣реВ strace:

$ sudo strace -e bpf ./xdp-simple
...
bpf(BPF_MAP_CREATE, {map_type=BPF_MAP_TYPE_ARRAY, key_size=4, value_size=8, max_entries=8, map_name="woo", ...}, 120) = 4
bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_XDP, prog_name="simple", ...}, 120) = 5

рдЖрдореНрд╣реА рддреЗ рдкрд╛рд╣рддреЛ libbpf рдирдХрд╛рд╢рд╛ рддрдпрд╛рд░ рдХреЗрд▓рд╛ woo рдЖрдгрд┐ рдирдВрддрд░ рдЖрдордЪрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдбрд╛рдЙрдирд▓реЛрдб рдХреЗрд▓рд╛ simple. рдЖрдореНрд╣реА рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд╕рд╛ рд▓реЛрдб рдХрд░рддреЛ рддреЗ рдЬрд╡рд│реВрди рдкрд╛рд╣реВ:

  • рдХреЙрд▓ xdp_simple_bpf__open_and_load рдлрд╛рдИрд▓рдордзреВрди xdp-simple.skel.h
  • рдЬреНрдпрд╛рдореБрд│реЗ xdp_simple_bpf__load рдлрд╛рдИрд▓рдордзреВрди xdp-simple.skel.h
  • рдЬреНрдпрд╛рдореБрд│реЗ bpf_object__load_skeleton рдлрд╛рдИрд▓рдордзреВрди libbpf/src/libbpf.c
  • рдЬреНрдпрд╛рдореБрд│реЗ bpf_object__load_xattr рдкрд╛рд╕реВрди libbpf/src/libbpf.c

рд╢реЗрд╡рдЯрдЪреЗ рдХрд╛рд░реНрдп, рдЗрддрд░ рдЧреЛрд╖реНрдЯреАрдВрдмрд░реЛрдмрд░рдЪ, рдХреЙрд▓ рдХрд░реЗрд▓ bpf_object__create_maps, рдЬреЗ рд╡рд┐рджреНрдпрдорд╛рди рдирдХрд╛рд╢реЗ рддрдпрд╛рд░ рдХрд░рддреЗ рдХрд┐рдВрд╡рд╛ рдЙрдШрдбрддреЗ, рддреНрдпрд╛рдВрдирд╛ рдлрд╛рдЗрд▓ рд╡рд░реНрдгрдирдХрд░реНрддреНрдпрд╛рдВрдордзреНрдпреЗ рдмрджрд▓рддреЗ. (рдЖрдореНрд╣реА рдЗрдереЗрдЪ рдкрд╛рд╣рддреЛ BPF_MAP_CREATE рдЖрдЙрдЯрдкреБрдЯ рдордзреНрдпреЗ strace.) рдкреБрдвреЗ рдлрдВрдХреНрд╢рди рдореНрд╣рдгрддрд╛рдд bpf_object__relocate рдЖрдгрд┐ рддреАрдЪ рдЖрдореНрд╣рд╛рд▓рд╛ рд╕реНрд╡рд╛рд░рд╕реНрдп рдЖрд╣реЗ, рдХрд╛рд░рдг рдЖрдореНрд╣реА рдЬреЗ рдкрд╛рд╣рд┐рд▓реЗ рддреЗ рдЖрдореНрд╣рд╛рд▓рд╛ рдЖрдард╡рддреЗ woo рдкреБрдирд░реНрд╕реНрдерд╛рдкрдирд╛ рдЯреЗрдмрд▓ рдордзреНрдпреЗ. рддреЗ рдПрдХреНрд╕рдкреНрд▓реЛрд░ рдХрд░рддрд╛рдирд╛, рдЖрдореНрд╣реА рд╢реЗрд╡рдЯреА рдлрдВрдХреНрд╢рдирдордзреНрдпреЗ рд╕реНрд╡рддрдГрд▓рд╛ рд╢реЛрдзрддреЛ bpf_program__relocate, рдЬреЗ рдирдХрд╛рд╢рд╛рдЪреНрдпрд╛ рдкреБрдирд░реНрд╕реНрдерд╛рдкрдиреЗрд╢реА рд╕рдВрдмрдВрдзрд┐рдд рдЖрд╣реЗ:

case RELO_LD64:
    insn[0].src_reg = BPF_PSEUDO_MAP_FD;
    insn[0].imm = obj->maps[relo->map_idx].fd;
    break;

рдореНрд╣рдгреВрди рдЖрдореНрд╣реА рдЖрдордЪреНрдпрд╛ рд╕реВрдЪрдирд╛ рдШреЗрддреЛ

18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0 ll

рдЖрдгрд┐ рддреНрдпрд╛рдд рд╕реЛрд░реНрд╕ рд░рдЬрд┐рд╕реНрдЯрд░ рдмрджрд▓рд╛ BPF_PSEUDO_MAP_FD, рдЖрдгрд┐ рдЖрдордЪреНрдпрд╛ рдирдХрд╛рд╢рд╛рдЪреНрдпрд╛ рдлрд╛рдЗрд▓ рд╡рд░реНрдгрдирдХрд░реНрддреНрдпрд╛рдЪреЗ рдкрд╣рд┐рд▓реЗ IMM рдЖрдгрд┐, рдЬрд░ рддреЗ рд╕рдорд╛рди рдЕрд╕реЗрд▓ рддрд░, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, 0xdeadbeef, рдирдВрддрд░ рдкрд░рд┐рдгрд╛рдореА рдЖрдореНрд╣рд╛рд▓рд╛ рд╕реВрдЪрдирд╛ рдкреНрд░рд╛рдкреНрдд рд╣реЛрдИрд▓

18 11 00 00 ef eb ad de 00 00 00 00 00 00 00 00 r1 = 0 ll

рдЕрд╢рд╛ рдкреНрд░рдХрд╛рд░реЗ рдирдХрд╛рд╢рд╛рдЪреА рдорд╛рд╣рд┐рддреА рд╡рд┐рд╢рд┐рд╖реНрдЯ рд▓реЛрдб рдХреЗрд▓реЗрд▓реНрдпрд╛ BPF рдкреНрд░реЛрдЧреНрд░рд╛рдордордзреНрдпреЗ рд╣рд╕реНрддрд╛рдВрддрд░рд┐рдд рдХреЗрд▓реА рдЬрд╛рддреЗ. рдпрд╛ рдкреНрд░рдХрд░рдгрд╛рдд, рдирдХрд╛рд╢рд╛ рд╡рд╛рдкрд░реВрди рддрдпрд╛рд░ рдХреЗрд▓реЗ рдЬрд╛рдК рд╢рдХрддреЗ BPF_MAP_CREATE, рдЖрдгрд┐ рдЖрдпрдбреА рд╡рд╛рдкрд░реВрди рдЙрдШрдбрд▓реЗ BPF_MAP_GET_FD_BY_ID.

рдПрдХреВрдг, рд╡рд╛рдкрд░рддрд╛рдирд╛ libbpf рдЕрд▓реНрдЧреЛрд░рд┐рджрдо рдЦрд╛рд▓реАрд▓рдкреНрд░рдорд╛рдгреЗ рдЖрд╣реЗ:

  • рд╕рдВрдХрд▓рдирд╛рджрд░рдореНрдпрд╛рди, рдирдХрд╛рд╢рд╛рдВрдЪреНрдпрд╛ рджреБрд╡реНрдпрд╛рдВрд╕рд╛рдареА рдкреБрдирд░реНрд╕реНрдерд┐рдд рд╕рд╛рд░рдгреАрдордзреНрдпреЗ рд░реЗрдХреЙрд░реНрдб рддрдпрд╛рд░ рдХреЗрд▓реЗ рдЬрд╛рддрд╛рдд
  • libbpf ELF рдСрдмреНрдЬреЗрдХреНрдЯ рдмреБрдХ рдЙрдШрдбрддреЗ, рд╕рд░реНрд╡ рд╡рд╛рдкрд░рд▓реЗрд▓реЗ рдирдХрд╛рд╢реЗ рд╢реЛрдзрддреЗ рдЖрдгрд┐ рддреНрдпрд╛рдВрдЪреНрдпрд╛рд╕рд╛рдареА рдлрд╛рдЗрд▓ рд╡рд░реНрдгрдирдХрд░реНрддрд╛ рддрдпрд╛рд░ рдХрд░рддреЗ
  • рд╕реВрдЪрдирд╛рдВрдЪрд╛ рднрд╛рдЧ рдореНрд╣рдгреВрди рдлрд╛рдЗрд▓ рд╡рд░реНрдгрдирдХрд░реНрддреЗ рдХрд░реНрдирд▓рдордзреНрдпреЗ рд▓реЛрдб рдХреЗрд▓реЗ рдЬрд╛рддрд╛рдд LD64

рдЬрд╕реЗ рддреБрдореНрд╣реА рдХрд▓реНрдкрдирд╛ рдХрд░реВ рд╢рдХрддрд╛, рдЕрдЬреВрди рдмрд░реЗрдЪ рдХрд╛рд╣реА рдпреЗрдгреЗ рдмрд╛рдХреА рдЖрд╣реЗ рдЖрдгрд┐ рдЖрдореНрд╣рд╛рд▓рд╛ рдЧрд╛рднреНрдпрд╛рдХрдбреЗ рд▓рдХреНрд╖ рджреНрдпрд╛рд╡реЗ рд▓рд╛рдЧреЗрд▓. рд╕реБрджреИрд╡рд╛рдиреЗ, рдЖрдордЪреНрдпрд╛рдХрдбреЗ рдПрдХ рд╕реБрдЧрд╛рд╡рд╛ рдЖрд╣реЗ - рдЖрдореНрд╣реА рдЕрд░реНрде рд▓рд┐рд╣реВрди рдареЗрд╡рд▓рд╛ рдЖрд╣реЗ BPF_PSEUDO_MAP_FD рд╕реНрддреНрд░реЛрдд рд░рдЬрд┐рд╕реНрдЯрд░рдордзреНрдпреЗ рдЖрдгрд┐ рдЖрдореНрд╣реА рддреЗ рджрдлрди рдХрд░реВ рд╢рдХрддреЛ, рдЬреЗ рдЖрдореНрд╣рд╛рд▓рд╛ рд╕рд░реНрд╡ рд╕рдВрддрд╛рдВрдЪреНрдпрд╛ рдкрд╡рд┐рддреНрд░рддреЗрдХрдбреЗ рдиреЗрдИрд▓ - kernel/bpf/verifier.c, рдЬреЗрдереЗ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдирд╛рд╡рд╛рдЪреЗ рдлрдВрдХреНрд╢рди рдлрд╛рдЗрд▓ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░рд▓рд╛ рдПрдХрд╛ рдкреНрд░рдХрд╛рд░рдЪреНрдпрд╛ рд╕рдВрд░рдЪрдиреЗрдЪреНрдпрд╛ рдкрддреНрддреНрдпрд╛рд╕рд╣ рдмрджрд▓рддреЗ struct bpf_map:

static int replace_map_fd_with_map_ptr(struct bpf_verifier_env *env) {
    ...

    f = fdget(insn[0].imm);
    map = __bpf_map_get(f);
    if (insn->src_reg == BPF_PSEUDO_MAP_FD) {
        addr = (unsigned long)map;
    }
    insn[0].imm = (u32)addr;
    insn[1].imm = addr >> 32;

(рд╕рдВрдкреВрд░реНрдг рдХреЛрдб рд╕рд╛рдкрдбреЗрд▓ рджреБрд╡рд╛). рдореНрд╣рдгреВрди рдЖрдореНрд╣реА рдЖрдордЪреЗ рдЕрд▓реНрдЧреЛрд░рд┐рджрдо рд╡рд╛рдврд╡реВ рд╢рдХрддреЛ:

  • рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓реЛрдб рдХрд░рддрд╛рдирд╛, рдкрдбрддрд╛рд│рдХ рдирдХрд╛рд╢рд╛рдЪрд╛ рдпреЛрдЧреНрдп рд╡рд╛рдкрд░ рддрдкрд╛рд╕рддреЛ рдЖрдгрд┐ рд╕рдВрдмрдВрдзрд┐рдд рд╕рдВрд░рдЪрдиреЗрдЪрд╛ рдкрддреНрддрд╛ рд▓рд┐рд╣рд┐рддреЛ struct bpf_map

рд╡рд╛рдкрд░реВрди ELF рдмрд╛рдпрдирд░реА рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рддрд╛рдирд╛ libbpf рдЕрдЬреВрди рдмрд░реЗрдЪ рдХрд╛рд╣реА рдЪрд╛рд▓реВ рдЖрд╣реЗ, рдкрд░рдВрддреБ рдЖрдореНрд╣реА рдЗрддрд░ рд▓реЗрдЦрд╛рдВрдордзреНрдпреЗ рдпрд╛рдмрджреНрджрд▓ рдЪрд░реНрдЪрд╛ рдХрд░реВ.

libbpf рд╢рд┐рд╡рд╛рдп рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЖрдгрд┐ рдирдХрд╛рд╢реЗ рд▓реЛрдб рдХрд░рдд рдЖрд╣реЗ

рд╡рдЪрди рджрд┐рд▓реНрдпрд╛рдкреНрд░рдорд╛рдгреЗ, рдорджрддреАрд╢рд┐рд╡рд╛рдп рдирдХрд╛рд╢реЗ рд╡рд╛рдкрд░рдгрд╛рд░рд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд╕рд╛ рддрдпрд╛рд░ рдХрд░рд╛рдпрдЪрд╛ рдЖрдгрд┐ рд▓реЛрдб рдХрд╕рд╛ рдХрд░рд╛рдпрдЪрд╛ рд╣реЗ рдЬрд╛рдгреВрди рдШреЗрдК рдЗрдЪреНрдЫрд┐рдгрд╛рд▒реНрдпрд╛ рд╡рд╛рдЪрдХрд╛рдВрд╕рд╛рдареА рдпреЗрдереЗ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдЖрд╣реЗ. libbpf. рдЬреЗрд╡реНрд╣рд╛ рддреБрдореНрд╣реА рдЕрд╢рд╛ рд╡рд╛рддрд╛рд╡рд░рдгрд╛рдд рдХрд╛рдо рдХрд░рдд рдЕрд╕рд╛рд▓ рдЬреНрдпрд╛рд╕рд╛рдареА рддреБрдореНрд╣реА рдЕрд╡рд▓рдВрдмрд┐рддреНрд╡ рддрдпрд╛рд░ рдХрд░реВ рд╢рдХрдд рдирд╛рд╣реА, рдХрд┐рдВрд╡рд╛ рдкреНрд░рддреНрдпреЗрдХ рдмрд┐рдЯ рдЬрддрди рдХрд░реВ рд╢рдХрдд рдирд╛рд╣реА рдХрд┐рдВрд╡рд╛ рдПрдЦрд╛рджрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓рд┐рд╣реВ рд╢рдХрддрд╛ рддреЗрд╡реНрд╣рд╛ рд╣реЗ рдЙрдкрдпреБрдХреНрдд рдард░реВ рд╢рдХрддреЗ. ply, рдЬреЗ рдЙрдбрддрд╛рдирд╛ BPF рдмрд╛рдпрдирд░реА рдХреЛрдб рд╡реНрдпреБрддреНрдкрдиреНрди рдХрд░рддреЗ.

рддрд░реНрдХрд╛рдЪреЗ рдЕрдиреБрд╕рд░рдг рдХрд░рдгреЗ рд╕реЛрдкреЗ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА, рдЖрдореНрд╣реА рдпрд╛ рд╣реЗрддреВрдВрд╕рд╛рдареА рдЖрдордЪреЗ рдЙрджрд╛рд╣рд░рдг рдкреБрдиреНрд╣рд╛ рд▓рд┐рд╣реВ xdp-simple. рдпрд╛ рдЙрджрд╛рд╣рд░рдгрд╛рдд рдЪрд░реНрдЪрд╛ рдХреЗрд▓реЗрд▓реНрдпрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдордЪрд╛ рд╕рдВрдкреВрд░реНрдг рдЖрдгрд┐ рдереЛрдбрд╛ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХреЛрдб рдпрд╛рдордзреНрдпреЗ рдЖрдврд│реВ рд╢рдХрддреЛ рд╕рд╛рд░.

рдЖрдордЪреНрдпрд╛ рдЕрд░реНрдЬрд╛рдЪрд╛ рддрд░реНрдХ рдЦрд╛рд▓реАрд▓рдкреНрд░рдорд╛рдгреЗ рдЖрд╣реЗ:

  • рдПрдХ рдкреНрд░рдХрд╛рд░рдЪрд╛ рдирдХрд╛рд╢рд╛ рддрдпрд╛рд░ рдХрд░рд╛ BPF_MAP_TYPE_ARRAY рдХрдорд╛рдВрдб рд╡рд╛рдкрд░реВрди BPF_MAP_CREATE,
  • рд╣рд╛ рдирдХрд╛рд╢рд╛ рд╡рд╛рдкрд░рдгрд╛рд░рд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рддрдпрд╛рд░ рдХрд░рд╛,
  • рдкреНрд░реЛрдЧреНрд░рд╛рдорд▓рд╛ рдЗрдВрдЯрд░рдлреЗрд╕рд╢реА рдХрдиреЗрдХреНрдЯ рдХрд░рд╛ lo,

рдЬреНрдпрд╛рдЪреЗ рднрд╛рд╖рд╛рдВрддрд░ рдорд╛рдгрд╕рд╛рдордзреНрдпреЗ рдЕрд╕реЗ рд╣реЛрддреЗ

int main(void)
{
    int map_fd, prog_fd;

    map_fd = map_create();
    if (map_fd < 0)
        err(1, "bpf: BPF_MAP_CREATE");

    prog_fd = prog_load(map_fd);
    if (prog_fd < 0)
        err(1, "bpf: BPF_PROG_LOAD");

    xdp_attach(1, prog_fd);
}

рддреЛ рдЖрд╣реЗ map_create рдЖрдореНрд╣реА рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓рдмрджреНрджрд▓ рдкрд╣рд┐рд▓реНрдпрд╛ рдЙрджрд╛рд╣рд░рдгрд╛рдд рдмрдирд╡рд▓реНрдпрд╛рдкреНрд░рдорд╛рдгреЗ рдирдХрд╛рд╢рд╛ рддрдпрд╛рд░ рдХрд░рддреЛ bpf - тАЬрдХрд░реНрдирд▓, рдХреГрдкрдпрд╛ рдорд▓рд╛ 8 рдШрдЯрдХрд╛рдВрдЪреНрдпрд╛ рдЕреЕрд░реЗрдЪреНрдпрд╛ рд╕реНрд╡рд░реВрдкрд╛рдд рдирд╡реАрди рдирдХрд╛рд╢рд╛ рдмрдирд╡рд╛ __u64 рдЖрдгрд┐ рдорд▓рд╛ рдлрд╛рдЗрд▓ рд╡рд░реНрдгрдирдХрд░реНрддрд╛ рдкрд░рдд рджреНрдпрд╛":

static int map_create()
{
    union bpf_attr attr;

    memset(&attr, 0, sizeof(attr));
    attr.map_type = BPF_MAP_TYPE_ARRAY,
    attr.key_size = sizeof(__u32),
    attr.value_size = sizeof(__u64),
    attr.max_entries = 8,
    strncpy(attr.map_name, "woo", sizeof(attr.map_name));
    return syscall(__NR_bpf, BPF_MAP_CREATE, &attr, sizeof(attr));
}

рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓реЛрдб рдХрд░рдгреЗ рджреЗрдЦреАрд▓ рд╕реЛрдкреЗ рдЖрд╣реЗ:

static int prog_load(int map_fd)
{
    union bpf_attr attr;
    struct bpf_insn insns[] = {
        ...
    };

    memset(&attr, 0, sizeof(attr));
    attr.prog_type = BPF_PROG_TYPE_XDP;
    attr.insns     = ptr_to_u64(insns);
    attr.insn_cnt  = sizeof(insns)/sizeof(insns[0]);
    attr.license   = ptr_to_u64("GPL");
    strncpy(attr.prog_name, "woo", sizeof(attr.prog_name));
    return syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
}

рдЕрд╡рдШрдб рднрд╛рдЧ prog_load рдЖрдордЪреНрдпрд╛ BPF рдкреНрд░реЛрдЧреНрд░рд╛рдордЪреА рд╕рдВрд░рдЪрдирд╛рдВрдЪреА рдЕреЕрд░реЗ рдореНрд╣рдгреВрди рд╡реНрдпрд╛рдЦреНрдпрд╛ рдЖрд╣реЗ struct bpf_insn insns[]. рдкрд░рдВрддреБ рдЖрдореНрд╣реА C рдордзреНрдпреЗ рдЕрд╕рд▓реЗрд▓рд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╡рд╛рдкрд░рдд рдЕрд╕рд▓реНрдпрд╛рдиреЗ, рдЖрдореНрд╣реА рдереЛрдбреА рдлрд╕рд╡рдгреВрдХ рдХрд░реВ рд╢рдХрддреЛ:

$ llvm-objdump -D --section xdp/simple xdp-simple.bpf.o

0000000000000000 <simple>:
       0:       85 00 00 00 08 00 00 00 call 8
       1:       63 0a fc ff 00 00 00 00 *(u32 *)(r10 - 4) = r0
       2:       bf a2 00 00 00 00 00 00 r2 = r10
       3:       07 02 00 00 fc ff ff ff r2 += -4
       4:       18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0 ll
       6:       85 00 00 00 01 00 00 00 call 1
       7:       b7 01 00 00 00 00 00 00 r1 = 0
       8:       15 00 04 00 00 00 00 00 if r0 == 0 goto +4 <LBB0_2>
       9:       61 01 00 00 00 00 00 00 r1 = *(u32 *)(r0 + 0)
      10:       07 01 00 00 01 00 00 00 r1 += 1
      11:       63 10 00 00 00 00 00 00 *(u32 *)(r0 + 0) = r1
      12:       b7 01 00 00 02 00 00 00 r1 = 2

0000000000000068 <LBB0_2>:
      13:       bf 10 00 00 00 00 00 00 r0 = r1
      14:       95 00 00 00 00 00 00 00 exit

рдПрдХреВрдг, рдЖрдкрд▓реНрдпрд╛рд▓рд╛ 14 рд╕реВрдЪрдирд╛ рд░рдЪрдирд╛рдВрдЪреНрдпрд╛ рд╕реНрд╡рд░реВрдкрд╛рдд рд▓рд┐рд╣рд┐рдгреНрдпрд╛рдЪреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдЖрд╣реЗ struct bpf_insn (рд╕рд▓реНрд▓рд╛: рд╡рд░реВрди рдбрдВрдк рдШреНрдпрд╛, рд╕реВрдЪрдирд╛ рд╡рд┐рднрд╛рдЧ рдкреБрдиреНрд╣рд╛ рд╡рд╛рдЪрд╛, рдЙрдШрдбрд╛ linux/bpf.h ╨╕ linux/bpf_common.h рдЖрдгрд┐ рдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдгреНрдпрд╛рдЪрд╛ рдкреНрд░рдпрддреНрди рдХрд░рд╛ struct bpf_insn insns[] рд╕реНрд╡рддрдГрд╣реВрди):

struct bpf_insn insns[] = {
    /* 85 00 00 00 08 00 00 00 call 8 */
    {
        .code = BPF_JMP | BPF_CALL,
        .imm = 8,
    },

    /* 63 0a fc ff 00 00 00 00 *(u32 *)(r10 - 4) = r0 */
    {
        .code = BPF_MEM | BPF_STX,
        .off = -4,
        .src_reg = BPF_REG_0,
        .dst_reg = BPF_REG_10,
    },

    /* bf a2 00 00 00 00 00 00 r2 = r10 */
    {
        .code = BPF_ALU64 | BPF_MOV | BPF_X,
        .src_reg = BPF_REG_10,
        .dst_reg = BPF_REG_2,
    },

    /* 07 02 00 00 fc ff ff ff r2 += -4 */
    {
        .code = BPF_ALU64 | BPF_ADD | BPF_K,
        .dst_reg = BPF_REG_2,
        .imm = -4,
    },

    /* 18 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 r1 = 0 ll */
    {
        .code = BPF_LD | BPF_DW | BPF_IMM,
        .src_reg = BPF_PSEUDO_MAP_FD,
        .dst_reg = BPF_REG_1,
        .imm = map_fd,
    },
    { }, /* placeholder */

    /* 85 00 00 00 01 00 00 00 call 1 */
    {
        .code = BPF_JMP | BPF_CALL,
        .imm = 1,
    },

    /* b7 01 00 00 00 00 00 00 r1 = 0 */
    {
        .code = BPF_ALU64 | BPF_MOV | BPF_K,
        .dst_reg = BPF_REG_1,
        .imm = 0,
    },

    /* 15 00 04 00 00 00 00 00 if r0 == 0 goto +4 <LBB0_2> */
    {
        .code = BPF_JMP | BPF_JEQ | BPF_K,
        .off = 4,
        .src_reg = BPF_REG_0,
        .imm = 0,
    },

    /* 61 01 00 00 00 00 00 00 r1 = *(u32 *)(r0 + 0) */
    {
        .code = BPF_MEM | BPF_LDX,
        .off = 0,
        .src_reg = BPF_REG_0,
        .dst_reg = BPF_REG_1,
    },

    /* 07 01 00 00 01 00 00 00 r1 += 1 */
    {
        .code = BPF_ALU64 | BPF_ADD | BPF_K,
        .dst_reg = BPF_REG_1,
        .imm = 1,
    },

    /* 63 10 00 00 00 00 00 00 *(u32 *)(r0 + 0) = r1 */
    {
        .code = BPF_MEM | BPF_STX,
        .src_reg = BPF_REG_1,
        .dst_reg = BPF_REG_0,
    },

    /* b7 01 00 00 02 00 00 00 r1 = 2 */
    {
        .code = BPF_ALU64 | BPF_MOV | BPF_K,
        .dst_reg = BPF_REG_1,
        .imm = 2,
    },

    /* <LBB0_2>: bf 10 00 00 00 00 00 00 r0 = r1 */
    {
        .code = BPF_ALU64 | BPF_MOV | BPF_X,
        .src_reg = BPF_REG_1,
        .dst_reg = BPF_REG_0,
    },

    /* 95 00 00 00 00 00 00 00 exit */
    {
        .code = BPF_JMP | BPF_EXIT
    },
};

рдЬреНрдпрд╛рдВрдиреА рд╣реЗ рд╕реНрд╡рддрдГ рд▓рд┐рд╣рд┐рд▓реЗ рдирд╛рд╣реА рддреНрдпрд╛рдВрдЪреНрдпрд╛рд╕рд╛рдареА рдПрдХ рд╡реНрдпрд╛рдпрд╛рдо - рд╢реЛрдзрд╛ map_fd.

рдЖрдордЪреНрдпрд╛ рдХрд╛рд░реНрдпрдХреНрд░рдорд╛рдд рдЕрдЬреВрди рдПрдХ рдЕрдЬреНрдЮрд╛рдд рднрд╛рдЧ рд╢рд┐рд▓реНрд▓рдХ рдЖрд╣реЗ - xdp_attach. рджреБрд░реНрджреИрд╡рд╛рдиреЗ, XDP рд╕рд╛рд░рдЦреЗ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рд╡рд╛рдкрд░реВрди рдХрдиреЗрдХреНрдЯ рдХреЗрд▓реЗ рдЬрд╛рдК рд╢рдХрдд рдирд╛рд╣реАрдд bpf. рдЬреНрдпрд╛ рд▓реЛрдХрд╛рдВрдиреА рдмреАрдкреАрдПрдл рдЖрдгрд┐ рдПрдХреНрд╕рдбреАрдкреА рддрдпрд╛рд░ рдХреЗрд▓реЗ рддреЗ рдСрдирд▓рд╛рдЗрди рд▓рд┐рдирдХреНрд╕ рд╕рдореБрджрд╛рдпрд╛рддреАрд▓ рд╣реЛрддреЗ, рдпрд╛рдЪрд╛ рдЕрд░реНрде рддреНрдпрд╛рдВрдиреА рддреНрдпрд╛рдВрдЪреНрдпрд╛рд╕рд╛рдареА рд╕рд░реНрд╡рд╛рдд рдкрд░рд┐рдЪрд┐рдд рдПрдХ рд╡рд╛рдкрд░рд▓рд╛ (рдкрд░рдВрддреБ рдирд╛рд╣реА рд╕рд╛рдорд╛рдиреНрдп рд▓реЛрдХ) рдХрд░реНрдирд▓рд╢реА рд╕рдВрд╡рд╛рдж рд╕рд╛рдзрдгреНрдпрд╛рд╕рд╛рдареА рдЗрдВрдЯрд░рдлреЗрд╕: рдиреЗрдЯрд▓рд┐рдВрдХ рд╕реЙрдХреЗрдЯреНрд╕, рджреЗрдЦреАрд▓ рдкрд╣рд╛ рдЖрд░рдПрдлрд╕реА 3549. рдЕрдВрдорд▓рдмрдЬрд╛рд╡рдгреА рдХрд░рдгреНрдпрд╛рдЪрд╛ рд╕рд░реНрд╡рд╛рдд рд╕реЛрдкрд╛ рдорд╛рд░реНрдЧ xdp_attach рдкрд╛рд╕реВрди рдХреЛрдб рдХреЙрдкреА рдХрд░рдд рдЖрд╣реЗ libbpf, рдореНрд╣рдгрдЬреЗ, рдлрд╛рдЗрд▓рдордзреВрди netlink.c, рдЬреЗ рдЖрдореНрд╣реА рдХреЗрд▓реЗ рддреЗ рдереЛрдбреЗрд╕реЗ рд▓рд╣рд╛рди рдХрд░реВрди:

рдиреЗрдЯрд▓рд┐рдВрдХ рд╕реЙрдХреЗрдЯреНрд╕рдЪреНрдпрд╛ рдЬрдЧрд╛рдд рдЖрдкрд▓реЗ рд╕реНрд╡рд╛рдЧрдд рдЖрд╣реЗ

рдиреЗрдЯрд▓рд┐рдВрдХ рд╕реЙрдХреЗрдЯ рдкреНрд░рдХрд╛рд░ рдЙрдШрдбрд╛ NETLINK_ROUTE:

int netlink_open(__u32 *nl_pid)
{
    struct sockaddr_nl sa;
    socklen_t addrlen;
    int one = 1, ret;
    int sock;

    memset(&sa, 0, sizeof(sa));
    sa.nl_family = AF_NETLINK;

    sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
    if (sock < 0)
        err(1, "socket");

    if (setsockopt(sock, SOL_NETLINK, NETLINK_EXT_ACK, &one, sizeof(one)) < 0)
        warnx("netlink error reporting not supported");

    if (bind(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0)
        err(1, "bind");

    addrlen = sizeof(sa);
    if (getsockname(sock, (struct sockaddr *)&sa, &addrlen) < 0)
        err(1, "getsockname");

    *nl_pid = sa.nl_pid;
    return sock;
}

рдЖрдореНрд╣реА рдпрд╛ рд╕реЙрдХреЗрдЯрдордзреВрди рд╡рд╛рдЪрддреЛ:

static int bpf_netlink_recv(int sock, __u32 nl_pid, int seq)
{
    bool multipart = true;
    struct nlmsgerr *errm;
    struct nlmsghdr *nh;
    char buf[4096];
    int len, ret;

    while (multipart) {
        multipart = false;
        len = recv(sock, buf, sizeof(buf), 0);
        if (len < 0)
            err(1, "recv");

        if (len == 0)
            break;

        for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len);
                nh = NLMSG_NEXT(nh, len)) {
            if (nh->nlmsg_pid != nl_pid)
                errx(1, "wrong pid");
            if (nh->nlmsg_seq != seq)
                errx(1, "INVSEQ");
            if (nh->nlmsg_flags & NLM_F_MULTI)
                multipart = true;
            switch (nh->nlmsg_type) {
                case NLMSG_ERROR:
                    errm = (struct nlmsgerr *)NLMSG_DATA(nh);
                    if (!errm->error)
                        continue;
                    ret = errm->error;
                    // libbpf_nla_dump_errormsg(nh); too many code to copy...
                    goto done;
                case NLMSG_DONE:
                    return 0;
                default:
                    break;
            }
        }
    }
    ret = 0;
done:
    return ret;
}

рд╢реЗрд╡рдЯреА, рдпреЗрдереЗ рдЖрдордЪреЗ рдХрд╛рд░реНрдп рдЖрд╣реЗ рдЬреЗ рд╕реЙрдХреЗрдЯ рдЙрдШрдбрддреЗ рдЖрдгрд┐ рддреНрдпрд╛рд╕ рдлрд╛рдЗрд▓ рд╡рд░реНрдгрди рдХрд░рдгрд╛рд░рд╛ рдПрдХ рд╡рд┐рд╢реЗрд╖ рд╕рдВрджреЗрд╢ рдкрд╛рдард╡рддреЗ:

static int xdp_attach(int ifindex, int prog_fd)
{
    int sock, seq = 0, ret;
    struct nlattr *nla, *nla_xdp;
    struct {
        struct nlmsghdr  nh;
        struct ifinfomsg ifinfo;
        char             attrbuf[64];
    } req;
    __u32 nl_pid = 0;

    sock = netlink_open(&nl_pid);
    if (sock < 0)
        return sock;

    memset(&req, 0, sizeof(req));
    req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
    req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
    req.nh.nlmsg_type = RTM_SETLINK;
    req.nh.nlmsg_pid = 0;
    req.nh.nlmsg_seq = ++seq;
    req.ifinfo.ifi_family = AF_UNSPEC;
    req.ifinfo.ifi_index = ifindex;

    /* started nested attribute for XDP */
    nla = (struct nlattr *)(((char *)&req)
            + NLMSG_ALIGN(req.nh.nlmsg_len));
    nla->nla_type = NLA_F_NESTED | IFLA_XDP;
    nla->nla_len = NLA_HDRLEN;

    /* add XDP fd */
    nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
    nla_xdp->nla_type = IFLA_XDP_FD;
    nla_xdp->nla_len = NLA_HDRLEN + sizeof(int);
    memcpy((char *)nla_xdp + NLA_HDRLEN, &prog_fd, sizeof(prog_fd));
    nla->nla_len += nla_xdp->nla_len;

    /* if user passed in any flags, add those too */
    __u32 flags = XDP_FLAGS_SKB_MODE;
    nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
    nla_xdp->nla_type = IFLA_XDP_FLAGS;
    nla_xdp->nla_len = NLA_HDRLEN + sizeof(flags);
    memcpy((char *)nla_xdp + NLA_HDRLEN, &flags, sizeof(flags));
    nla->nla_len += nla_xdp->nla_len;

    req.nh.nlmsg_len += NLA_ALIGN(nla->nla_len);

    if (send(sock, &req, req.nh.nlmsg_len, 0) < 0)
        err(1, "send");
    ret = bpf_netlink_recv(sock, nl_pid, seq);

cleanup:
    close(sock);
    return ret;
}

рддрд░, рд╕рд░реНрд╡рдХрд╛рд╣реА рдЪрд╛рдЪрдгреАрд╕рд╛рдареА рддрдпрд╛рд░ рдЖрд╣реЗ:

$ cc nolibbpf.c -o nolibbpf
$ sudo strace -e bpf ./nolibbpf
bpf(BPF_MAP_CREATE, {map_type=BPF_MAP_TYPE_ARRAY, map_name="woo", ...}, 72) = 3
bpf(BPF_PROG_LOAD, {prog_type=BPF_PROG_TYPE_XDP, insn_cnt=15, prog_name="woo", ...}, 72) = 4
+++ exited with 0 +++

рдЪрд▓рд╛ рдкрд╛рд╣реВрдпрд╛ рдЖрдордЪреНрдпрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдорд╢реА рдХрдиреЗрдХреНрдЯ рдЭрд╛рд▓рд╛ рдЖрд╣реЗ рдХрд╛ lo:

$ ip l show dev lo
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 xdpgeneric qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    prog/xdp id 160

рдЪрд▓рд╛ рдкрд┐рдВрдЧреНрд╕ рдкрд╛рдард╡реВ рдЖрдгрд┐ рдирдХрд╛рд╢рд╛ рдкрд╛рд╣реВ:

$ for s in `seq 234`; do sudo ping -f -c 100 127.0.0.1 >/dev/null 2>&1; done
$ sudo bpftool m dump name woo
key: 00 00 00 00  value: 90 01 00 00 00 00 00 00
key: 01 00 00 00  value: 00 00 00 00 00 00 00 00
key: 02 00 00 00  value: 00 00 00 00 00 00 00 00
key: 03 00 00 00  value: 00 00 00 00 00 00 00 00
key: 04 00 00 00  value: 00 00 00 00 00 00 00 00
key: 05 00 00 00  value: 00 00 00 00 00 00 00 00
key: 06 00 00 00  value: 40 b5 00 00 00 00 00 00
key: 07 00 00 00  value: 00 00 00 00 00 00 00 00
Found 8 elements

рд╣реБрд░реНрд░реЗ, рд╕рд░реНрд╡рдХрд╛рд╣реА рдХрд╛рд░реНрдп рдХрд░рддреЗ. рд▓рдХреНрд╖рд╛рдд рдареЗрд╡рд╛, рдЖрдордЪрд╛ рдирдХрд╛рд╢рд╛ рдкреБрдиреНрд╣рд╛ рдмрд╛рдЗрдЯреНрд╕рдЪреНрдпрд╛ рд╕реНрд╡рд░реВрдкрд╛рдд рдкреНрд░рджрд░реНрд╢рд┐рдд рдЭрд╛рд▓рд╛ рдЖрд╣реЗ. рд╣реЗ рддреНрдпрд╛ рд╡рд╕реНрддреБрд╕реНрдерд┐рддреАрдореБрд│реЗ рдЖрд╣реЗ, рд╡рд┐рдкрд░реАрдд libbpf рдЖрдореНрд╣реА рдкреНрд░рдХрд╛рд░ рдорд╛рд╣рд┐рддреА (BTF) рд▓реЛрдб рдХреЗрд▓реА рдирд╛рд╣реА. рдкрдг рдЖрдореНрд╣реА рдкреБрдврдЪреНрдпрд╛ рд╡реЗрд│реА рдпрд╛рдмрджреНрджрд▓ рдЕрдзрд┐рдХ рдмреЛрд▓реВ.

рд╡рд┐рдХрд╛рд╕ рд╕рд╛рдзрдиреЗ

рдпрд╛ рд╡рд┐рднрд╛рдЧрд╛рдд, рдЖрдореНрд╣реА рдХрд┐рдорд╛рди BPF рд╡рд┐рдХрд╕рдХ рдЯреВрд▓рдХрд┐рдЯ рдкрд╛рд╣реВ.

рд╕рд░реНрд╡рд╕рд╛рдзрд╛рд░рдгрдкрдгреЗ, рдмреАрдкреАрдПрдл рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рддреБрдореНрд╣рд╛рд▓рд╛ рд╡рд┐рд╢реЗрд╖ рдХрд╢рд╛рдЪреАрд╣реА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╛рд╣реА - рдмреАрдкреАрдПрдл рдХреЛрдгрддреНрдпрд╛рд╣реА рд╕рднреНрдп рд╡рд┐рддрд░рдг рдХрд░реНрдирд▓рд╡рд░ рдЪрд╛рд▓рддреЗ рдЖрдгрд┐ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╡рд╛рдкрд░реВрди рддрдпрд╛рд░ рдХреЗрд▓реЗ рдЬрд╛рддрд╛рдд clang, рдЬреЗ рдкреЕрдХреЗрдЬрдордзреВрди рдкреБрд░рд╡рд▓реЗ рдЬрд╛рдК рд╢рдХрддреЗ. рддрдерд╛рдкрд┐, рдмреАрдкреАрдПрдл рд╡рд┐рдХрд╛рд╕рд╛рдзреАрди рдЖрд╣реЗ рдпрд╛ рд╡рд╕реНрддреБрд╕реНрдерд┐рддреАрдореБрд│реЗ, рдХрд░реНрдирд▓ рдЖрдгрд┐ рд╕рд╛рдзрдиреЗ рд╕рддрдд рдмрджрд▓рдд рдЖрд╣реЗрдд, рдЬрд░ рддреБрдореНрд╣рд╛рд▓рд╛ 2019 рдкрд╛рд╕реВрди рдЬреБрдиреНрдпрд╛ рдкрджреНрдзрддреАрдВрдЪрд╛ рд╡рд╛рдкрд░ рдХрд░реВрди рдмреАрдкреАрдПрдл рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓рд┐рд╣рд╛рдпрдЪрд╛ рдирд╕реЗрд▓, рддрд░ рддреБрдореНрд╣рд╛рд▓рд╛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рд╛рд╡реЗ рд▓рд╛рдЧреЗрд▓.

  • llvm/clang
  • pahole
  • рддреНрдпрд╛рдЪрд╛ рдЧрд╛рднрд╛
  • bpftool

(рд╕рдВрджрд░реНрднрд╛рд╕рд╛рдареА, рд╣рд╛ рд╡рд┐рднрд╛рдЧ рдЖрдгрд┐ рд▓реЗрдЦрд╛рддреАрд▓ рд╕рд░реНрд╡ рдЙрджрд╛рд╣рд░рдгреЗ рдбреЗрдмрд┐рдпрди 10 рд╡рд░ рдЪрд╛рд▓рд╡рд▓реА рдЧреЗрд▓реА рд╣реЛрддреА.)

llvm/clang

BPF LLVM рд╕рд╣ рдЕрдиреБрдХреВрд▓ рдЖрд╣реЗ рдЖрдгрд┐, рдЬрд░реА рдЕрд▓реАрдХрдбреЗ BPF рд╕рд╛рдареА рдХрд╛рд░реНрдпрдХреНрд░рдо gcc рд╡рд╛рдкрд░реВрди рд╕рдВрдХрд▓рд┐рдд рдХреЗрд▓реЗ рдЬрд╛рдК рд╢рдХрддрд╛рдд, рддрд░реАрд╣реА рд╕рд░реНрд╡ рдЪрд╛рд▓реВ рд╡рд┐рдХрд╛рд╕ LLVM рд╕рд╛рдареА рдХреЗрд▓рд╛ рдЬрд╛рддреЛ. рдореНрд╣рдгреВрди, рд╕рд░реНрд╡ рдкреНрд░рдердо, рдЖрдореНрд╣реА рд╡рд░реНрддрдорд╛рди рдЖрд╡реГрддреНрддреА рддрдпрд╛рд░ рдХрд░реВ clang git рд╡рд░реВрди:

$ sudo apt install ninja-build
$ git clone --depth 1 https://github.com/llvm/llvm-project.git
$ mkdir -p llvm-project/llvm/build/install
$ cd llvm-project/llvm/build
$ cmake .. -G "Ninja" -DLLVM_TARGETS_TO_BUILD="BPF;X86" 
                      -DLLVM_ENABLE_PROJECTS="clang" 
                      -DBUILD_SHARED_LIBS=OFF 
                      -DCMAKE_BUILD_TYPE=Release 
                      -DLLVM_BUILD_RUNTIME=OFF
$ time ninja
... ╨╝╨╜╨╛╨│╨╛ ╨▓╤А╨╡╨╝╨╡╨╜╨╕ ╤Б╨┐╤Г╤Б╤В╤П
$

рдЖрддрд╛ рдЖрдореНрд╣реА рд╕рд░реНрд╡рдХрд╛рд╣реА рдпреЛрдЧреНрдпрд░рд┐рддреНрдпрд╛ рдПрдХрддреНрд░ рдЖрд▓реЗ рдХреА рдирд╛рд╣реА рд╣реЗ рддрдкрд╛рд╕реВ рд╢рдХрддреЛ:

$ ./bin/llc --version
LLVM (http://llvm.org/):
  LLVM version 11.0.0git
  Optimized build.
  Default target: x86_64-unknown-linux-gnu
  Host CPU: znver1

  Registered Targets:
    bpf    - BPF (host endian)
    bpfeb  - BPF (big endian)
    bpfel  - BPF (little endian)
    x86    - 32-bit X86: Pentium-Pro and above
    x86-64 - 64-bit X86: EM64T and AMD64

(рд╡рд┐рдзрд╛рдирд╕рднрд╛ рд╕реВрдЪрдирд╛ clang рдорд╛рдЭреНрдпрд╛рдХрдбреВрди рдШреЗрддрд▓реЗ bpf_devel_QA.)

рдЖрдореНрд╣реА рдиреБрдХрддреЗрдЪ рддрдпрд╛рд░ рдХреЗрд▓реЗрд▓реЗ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдгрд╛рд░ рдирд╛рд╣реА, рдкрд░рдВрддреБ рддреНрдпрд╛рдРрд╡рдЬреА рддреНрдпрд╛рдВрдирд╛ рдЬреЛрдбреВ PATH, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде:

export PATH="`pwd`/bin:$PATH"

(рд╣реЗ рдпрд╛рдд рдЬреЛрдбрд▓реЗ рдЬрд╛рдК рд╢рдХрддреЗ .bashrc рдХрд┐рдВрд╡рд╛ рд╡реЗрдЧрд│реНрдпрд╛ рдлрд╛рдИрд▓рдордзреНрдпреЗ. рд╡реИрдпрдХреНрддрд┐рдХрд░рд┐рддреНрдпрд╛, рдореА рдпрд╛рд╕рд╛рд░рдЦреНрдпрд╛ рдЧреЛрд╖реНрдЯреА рдЬреЛрдбрддреЛ ~/bin/activate-llvm.sh рдЖрдгрд┐ рдЬреЗрд╡реНрд╣рд╛ рдЖрд╡рд╢реНрдпрдХ рдЕрд╕реЗрд▓ рддреЗрд╡реНрд╣рд╛ рдореА рддреЗ рдХрд░рддреЛ . activate-llvm.sh.)

Pahole рдЖрдгрд┐ BTF

рдЙрдкрдпреБрдХреНрддрддрд╛ pahole рдмреАрдЯреАрдПрдл рдлреЙрд░рдореЕрдЯрдордзреНрдпреЗ рдбреАрдмрдЧрд┐рдВрдЧ рдорд╛рд╣рд┐рддреА рддрдпрд╛рд░ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдХрд░реНрдирд▓ рддрдпрд╛рд░ рдХрд░рддрд╛рдирд╛ рд╡рд╛рдкрд░рд▓реЗ рдЬрд╛рддреЗ. рдЖрдореНрд╣реА рдпрд╛ рд▓реЗрдЦрд╛рдд BTF рддрдВрддреНрд░рдЬреНрдЮрд╛рдирд╛рдЪреНрдпрд╛ рддрдкрд╢реАрд▓рд╛рдВрдмрджреНрджрд▓ рддрдкрд╢реАрд▓рд╛рдд рдЬрд╛рдгрд╛рд░ рдирд╛рд╣реА, рддреНрдпрд╛рд╢рд┐рд╡рд╛рдп рддреЗ рд╕реЛрдпреАрдЪреЗ рдЖрд╣реЗ рдЖрдгрд┐ рдЖрдореНрд╣рд╛рд▓рд╛ рддреЗ рд╡рд╛рдкрд░рд╛рдпрдЪреЗ рдЖрд╣реЗ. рдореНрд╣рдгреВрди рдЬрд░ рддреБрдореНрд╣реА рддреБрдордЪрд╛ рдХрд░реНрдирд▓ рддрдпрд╛рд░ рдХрд░рдгрд╛рд░ рдЕрд╕рд╛рд▓ рддрд░ рдкреНрд░рдердо рддрдпрд╛рд░ рдХрд░рд╛ pahole (рд╡рд┐рдирд╛ pahole рддреБрдореНрд╣реА рдкрд░реНрдпрд╛рдпрд╛рд╕рд╣ рдХрд░реНрдирд▓ рддрдпрд╛рд░ рдХрд░реВ рд╢рдХрдгрд╛рд░ рдирд╛рд╣реА CONFIG_DEBUG_INFO_BTF:

$ git clone https://git.kernel.org/pub/scm/devel/pahole/pahole.git
$ cd pahole/
$ sudo apt install cmake
$ mkdir build
$ cd build/
$ cmake -D__LIB=lib ..
$ make
$ sudo make install
$ which pahole
/usr/local/bin/pahole

BPF рд╕рд╣ рдкреНрд░рдпреЛрдЧ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдХрд░реНрдирд▓

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

рдХрд░реНрдирд▓ рддрдпрд╛рд░ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рддреБрдореНрд╣рд╛рд▓рд╛ рдкреНрд░рдердо, рдХрд░реНрдирд▓ рд╕реНрд╡рддрдГ рдЖрдгрд┐ рджреБрд╕рд░реЗ рдореНрд╣рдгрдЬреЗ, рдХрд░реНрдирд▓ рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди рдлрд╛рдЗрд▓ рдЖрд╡рд╢реНрдпрдХ рдЖрд╣реЗ. рдмреАрдкреАрдПрдлрдЪрд╛ рдкреНрд░рдпреЛрдЧ рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА рдЖрдкрдг рдиреЗрд╣рдореАрдЪрд╛ рд╡рд╛рдкрд░реБ рд╢рдХрддреЛ рд╡реНрд╣реЕрдирд┐рд▓рд╛ рдХрд░реНрдирд▓ рдХрд┐рдВрд╡рд╛ рд╡рд┐рдХрд╛рд╕ рдХрд░реНрдирд▓рдкреИрдХреА рдПрдХ. рдРрддрд┐рд╣рд╛рд╕рд┐рдХрджреГрд╖реНрдЯреНрдпрд╛, рдмреАрдкреАрдПрдл рд╡рд┐рдХрд╛рд╕ рд▓рд┐рдирдХреНрд╕ рдиреЗрдЯрд╡рд░реНрдХрд┐рдВрдЧ рд╕рдореБрджрд╛рдпрд╛рдордзреНрдпреЗ рд╣реЛрддреЛ рдЖрдгрд┐ рдореНрд╣рдгреВрдирдЪ рд╕рд░реНрд╡ рдмрджрд▓ рд▓рд╡рдХрд░ рдХрд┐рдВрд╡рд╛ рдирдВрддрд░ рдбреЗрд╡реНрд╣рд┐рдб рдорд┐рд▓рд░, рд▓рд┐рдирдХреНрд╕ рдиреЗрдЯрд╡рд░реНрдХрд┐рдВрдЧ рдореЗрдВрдЯреЗрдирд░рджреНрд╡рд╛рд░реЗ рд╣реЛрддрд╛рдд. рддреНрдпрд╛рдВрдЪреНрдпрд╛ рд╕реНрд╡рднрд╛рд╡рд╛рдиреБрд╕рд╛рд░ - рд╕рдВрдкрд╛рджрдиреЗ рдХрд┐рдВрд╡рд╛ рдирд╡реАрди рд╡реИрд╢рд┐рд╖реНрдЯреНрдпреЗ - рдиреЗрдЯрд╡рд░реНрдХ рдмрджрд▓ рджреЛрдирдкреИрдХреА рдПрдХрд╛ рдХреЛрд░рдордзреНрдпреЗ рдпреЗрддрд╛рдд - net рдХрд┐рдВрд╡рд╛ net-next. BPF рд╕рд╛рдареА рдмрджрд▓ рджрд░рдореНрдпрд╛рди рд╕рдорд╛рди рдкреНрд░рдХрд╛рд░реЗ рд╡рд┐рддрд░реАрдд рдХреЗрд▓реЗ рдЬрд╛рддрд╛рдд bpf ╨╕ bpf-next, рдЬреЗ рдирдВрддрд░ рдЕрдиреБрдХреНрд░рдореЗ рдиреЗрдЯ рдЖрдгрд┐ рдиреЗрдЯ-рдиреЗрдХреНрд╕реНрдЯрдордзреНрдпреЗ рдПрдХрддреНрд░ рдХреЗрд▓реЗ рдЬрд╛рддрд╛рдд. рдЕрдзрд┐рдХ рддрдкрд╢реАрд▓рд╛рдВрд╕рд╛рдареА, рдкрд╣рд╛ bpf_devel_QA ╨╕ netdev-FAQ. рддреНрдпрд╛рдореБрд│реЗ рддреБрдордЪреА рдЪрд╡ рдЖрдгрд┐ рддреБрдореНрд╣реА рдЪрд╛рдЪрдгреА рдХрд░рдд рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рдкреНрд░рдгрд╛рд▓реАрдЪреНрдпрд╛ рд╕реНрдерд┐рд░рддреЗрдЪреНрдпрд╛ рдЧрд░рдЬрд╛рдВрд╡рд░ рдЖрдзрд╛рд░рд┐рдд рдХрд░реНрдирд▓ рдирд┐рд╡рдбрд╛ (*-next рдХрд░реНрдирд▓ рд╕реВрдЪреАрдмрджреНрдз рдХреЗрд▓реЗрд▓реНрдпрд╛рдВрдкреИрдХреА рд╕рд░реНрд╡рд╛рдд рдЕрд╕реНрдерд┐рд░ рдЖрд╣реЗрдд).

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

рд╡рд░реАрд▓ рдХрд░реНрдирд▓рдкреИрдХреА рдПрдХ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░рд╛:

$ git clone git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git
$ cd bpf-next

рдХрд┐рдорд╛рди рдХрд╛рд░реНрдпрд░рдд рдХрд░реНрдирд▓ рдХреЙрдиреНрдлрд┐рдЧрд░реЗрд╢рди рддрдпрд╛рд░ рдХрд░рд╛:

$ cp /boot/config-`uname -r` .config
$ make localmodconfig

рдлрд╛рдЗрд▓рдордзреНрдпреЗ рдмреАрдкреАрдПрдл рдкрд░реНрдпрд╛рдп рд╕рдХреНрд╖рдо рдХрд░рд╛ .config рддреБрдордЪреНрдпрд╛ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ рдирд┐рд╡рдбреАрдиреБрд╕рд╛рд░ (рдмрд╣реБрдзрд╛ CONFIG_BPF systemd рд╡рд╛рдкрд░рдд рдЕрд╕рд▓реНрдпрд╛рдиреЗ рдЖрдзреАрдЪ рд╕рдХреНрд╖рдо рдХреЗрд▓реЗ рдЬрд╛рдИрд▓). рдпрд╛ рд▓реЗрдЦрд╛рд╕рд╛рдареА рд╡рд╛рдкрд░рд▓реЗрд▓реНрдпрд╛ рдХрд░реНрдирд▓рдордзреАрд▓ рдкрд░реНрдпрд╛рдпрд╛рдВрдЪреА рдпрд╛рджреА рдпреЗрдереЗ рдЖрд╣реЗ:

CONFIG_CGROUP_BPF=y
CONFIG_BPF=y
CONFIG_BPF_LSM=y
CONFIG_BPF_SYSCALL=y
CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y
CONFIG_BPF_JIT_ALWAYS_ON=y
CONFIG_BPF_JIT_DEFAULT_ON=y
CONFIG_IPV6_SEG6_BPF=y
# CONFIG_NETFILTER_XT_MATCH_BPF is not set
# CONFIG_BPFILTER is not set
CONFIG_NET_CLS_BPF=y
CONFIG_NET_ACT_BPF=y
CONFIG_BPF_JIT=y
CONFIG_BPF_STREAM_PARSER=y
CONFIG_LWTUNNEL_BPF=y
CONFIG_HAVE_EBPF_JIT=y
CONFIG_BPF_EVENTS=y
CONFIG_BPF_KPROBE_OVERRIDE=y
CONFIG_DEBUG_INFO_BTF=y

рдордЧ рдЖрдореНрд╣реА рдореЙрдбреНрдпреВрд▓реНрд╕ рдЖрдгрд┐ рдХрд░реНрдирд▓ рд╕рд╣рдЬрдкрдгреЗ рдПрдХрддреНрд░ рдЖрдгрд┐ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реВ рд╢рдХрддреЛ (рддрд╕реЗ, рддреБрдореНрд╣реА рдирд╡реАрди рдЕрд╕реЗрдВрдмрд▓ рд╡рд╛рдкрд░реВрди рдХрд░реНрдирд▓ рдПрдХрддреНрд░ рдХрд░реВ рд╢рдХрддрд╛. clangрдорд┐рд│рд╡реВрди CC=clang):

$ make -s -j $(getconf _NPROCESSORS_ONLN)
$ sudo make modules_install
$ sudo make install

рдЖрдгрд┐ рдирд╡реАрди рдХрд░реНрдирд▓рд╕рд╣ рд░реАрдмреВрдЯ рдХрд░рд╛ (рдореА рдпрд╛рд╕рд╛рдареА рд╡рд╛рдкрд░рддреЛ kexec рдкреЕрдХреЗрдЬрдордзреВрди kexec-tools):

v=5.8.0-rc6+ # ╨╡╤Б╨╗╨╕ ╨▓╤Л ╨┐╨╡╤А╨╡╤Б╨╛╨▒╨╕╤А╨░╨╡╤В╨╡ ╤В╨╡╨║╤Г╤Й╨╡╨╡ ╤П╨┤╤А╨╛, ╤В╨╛ ╨╝╨╛╨╢╨╜╨╛ ╨┤╨╡╨╗╨░╤В╤М v=`uname -r`
sudo kexec -l -t bzImage /boot/vmlinuz-$v --initrd=/boot/initrd.img-$v --reuse-cmdline &&
sudo kexec -e

bpftool

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

рдпрд╛ рд▓реЗрдЦрдирд╛рдЪреНрдпрд╛ рд╡реЗрд│реА bpftool рдлрдХреНрдд RHEL, Fedora рдЖрдгрд┐ Ubuntu рд╕рд╛рдареА рд░реЗрдбреАрдореЗрдб рдпреЗрддреЗ (рдкрд╣рд╛, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рд╣рд╛ рдзрд╛рдЧрд╛, рдЬреЗ рдкреЕрдХреЗрдЬрд┐рдВрдЧрдЪреА рдЕрдкреВрд░реНрдг рдХрдерд╛ рд╕рд╛рдВрдЧрддреЗ bpftool рдбреЗрдмрд┐рдпрди рдордзреНрдпреЗ). рдкрд░рдВрддреБ рдЬрд░ рддреБрдореНрд╣реА рддреБрдордЪреЗ рдХрд░реНрдирд▓ рдЖрдзреАрдЪ рддрдпрд╛рд░ рдХреЗрд▓реЗ рдЕрд╕реЗрд▓ рддрд░ рддрдпрд╛рд░ рдХрд░рд╛ bpftool рдкрд╛рдИрд╕рд╛рд░рдЦреЗ рд╕реЛрдкреЗ:

$ cd ${linux}/tools/bpf/bpftool
# ... ╨┐╤А╨╛╨┐╨╕╤И╨╕╤В╨╡ ╨┐╤Г╤В╨╕ ╨║ ╨┐╨╛╤Б╨╗╨╡╨┤╨╜╨╡╨╝╤Г clang, ╨║╨░╨║ ╤А╨░╤Б╤Б╨║╨░╨╖╨░╨╜╨╛ ╨▓╤Л╤И╨╡
$ make -s

Auto-detecting system features:
...                        libbfd: [ on  ]
...        disassembler-four-args: [ on  ]
...                          zlib: [ on  ]
...                        libcap: [ on  ]
...               clang-bpf-co-re: [ on  ]

Auto-detecting system features:
...                        libelf: [ on  ]
...                          zlib: [ on  ]
...                           bpf: [ on  ]

$

(рдпреЗрдереЗ ${linux} - рд╣реА рддреБрдордЪреА рдХрд░реНрдирд▓ рдбрд┐рд░реЗрдХреНрдЯрд░реА рдЖрд╣реЗ.) рдпрд╛ рдХрдорд╛рдВрдбреНрд╕ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХреЗрд▓реНрдпрд╛рдирдВрддрд░ bpftool рдирд┐рд░реНрджреЗрд╢рд┐рдХреЗрдд рдЧреЛрд│рд╛ рдХреЗрд▓реЗ рдЬрд╛рдИрд▓ ${linux}/tools/bpf/bpftool рдЖрдгрд┐ рддреЗ рдорд╛рд░реНрдЧрд╛рдд рдЬреЛрдбрд▓реЗ рдЬрд╛рдК рд╢рдХрддреЗ (рд╕рд░реНрд╡ рдкреНрд░рдердо рд╡рд╛рдкрд░рдХрд░реНрддреНрдпрд╛рд╕рд╛рдареА root) рдХрд┐рдВрд╡рд╛ рдлрдХреНрдд рдХреЙрдкреА рдХрд░рд╛ /usr/local/sbin.

рдЧреЛрд│рд╛ рдХрд░рд╛ bpftool рдирдВрддрд░рдЪреЗ рд╡рд╛рдкрд░рдгреЗ рдЪрд╛рдВрдЧрд▓реЗ clang, рд╡рд░ рд╡рд░реНрдгрди рдХреЗрд▓реНрдпрд╛рдкреНрд░рдорд╛рдгреЗ рдПрдХрддреНрд░ рдХреЗрд▓реЗ рдЖрд╣реЗ, рдЖрдгрд┐ рддреЗ рдпреЛрдЧреНрдпрд░рд┐рддреНрдпрд╛ рдПрдХрддреНрд░ рдХреЗрд▓реЗ рдЖрд╣реЗ рдХреА рдирд╛рд╣реА рддреЗ рддрдкрд╛рд╕рд╛ - рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдХрдорд╛рдВрдб рд╡рд╛рдкрд░реВрди

$ sudo bpftool feature probe kernel
Scanning system configuration...
bpf() syscall for unprivileged users is enabled
JIT compiler is enabled
JIT compiler hardening is disabled
JIT compiler kallsyms exports are enabled for root
...

рдЬреЗ рддреБрдордЪреНрдпрд╛ рдХрд░реНрдирд▓рдордзреНрдпреЗ рдХреЛрдгрддреА BPF рд╡реИрд╢рд┐рд╖реНрдЯреНрдпреЗ рд╕рдХреНрд╖рдо рдЖрд╣реЗрдд рд╣реЗ рджрд░реНрд╢рд╡реЗрд▓.

рддрд╕реЗ, рдорд╛рдЧреАрд▓ рдХрдорд╛рдВрдб рдореНрд╣рдгреВрди рдЪрд╛рд▓рд╡рд┐рд▓реА рдЬрд╛рдК рд╢рдХрддреЗ

# bpftool f p k

рд╣реЗ рдкреЕрдХреЗрдЬрдордзреАрд▓ рдпреБрдЯрд┐рд▓рд┐рдЯрд┐рдЬрдЪреНрдпрд╛ рд╕рд╛рджреГрд╢реНрдпрд╛рдиреЗ рдХреЗрд▓реЗ рдЬрд╛рддреЗ iproute2, рдЬрд┐рдереЗ рдЖрдкрдг, рдЙрджрд╛рд╣рд░рдгрд╛рд░реНрде, рдореНрд╣рдгреВ рд╢рдХрддреЛ ip a s eth0 рддреНрдпрд╛рдРрд╡рдЬреА ip addr show dev eth0.

рдирд┐рд╖реНрдХрд░реНрд╖

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

рдореА рд╣реЗ рд▓рдХреНрд╖рд╛рдд рдШреЗрдК рдЗрдЪреНрдЫрд┐рддреЛ рдХреА, рдорд╛рдЭреНрдпрд╛ рдорддреЗ, рддрдВрддреНрд░рдЬреНрдЮрд╛рди рдЗрддрдХреЗ рд▓реЛрдХрдкреНрд░рд┐рдп рдЭрд╛рд▓реЗ рдЖрд╣реЗ рдХрд╛рд░рдг, рдПрдХреАрдХрдбреЗ, рддреЗ рдХрд░реВ рд╢рдХрддреЗ рдЦреЗрд│рдгреЗ (рдПрдЦрд╛рджреНрдпрд╛ рдпрдВрддреНрд░рд╛рдЪреЗ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдПрдХрд╛ рд╕рдВрдзреНрдпрд╛рдХрд╛рд│реА рдХрдореА-рдЕрдзрд┐рдХ рдкреНрд░рдорд╛рдгрд╛рдд рд╕рдордЬрд▓реЗ рдЬрд╛рдК рд╢рдХрддреЗ), рдЖрдгрд┐ рджреБрд╕рд░реАрдХрдбреЗ, рддреНрдпрд╛рдЪреНрдпрд╛ рджреЗрдЦрд╛рд╡реНрдпрд╛рдкреВрд░реНрд╡реА (рд╕реБрдВрджрд░рдкрдгреЗ) рд╕реЛрдбрд╡рддрд╛ рди рдпреЗрдгрд╛рд▒реНрдпрд╛ рд╕рдорд╕реНрдпрд╛рдВрдЪреЗ рдирд┐рд░рд╛рдХрд░рдг рдХрд░рдгреНрдпрд╛рд╕рд╛рдареА. рд╣реЗ рджреЛрди рдШрдЯрдХ рдПрдХрддреНрд░рд┐рддрдкрдгреЗ рд▓реЛрдХрд╛рдВрдирд╛ рдкреНрд░рдпреЛрдЧ рдХрд░рдгреНрдпрд╛рд╕ рдЖрдгрд┐ рд╕реНрд╡рдкреНрди рдкрд╛рд╣рдгреНрдпрд╛рд╕ рднрд╛рдЧ рдкрд╛рдбрддрд╛рдд, рдЬреНрдпрд╛рдореБрд│реЗ рдЕрдзрд┐рдХрд╛рдзрд┐рдХ рдирд╛рд╡рд┐рдиреНрдпрдкреВрд░реНрдг рдЙрдкрд╛рдпрд╛рдВрдЪрд╛ рдЙрджрдп рд╣реЛрддреЛ.

рд╣рд╛ рд▓реЗрдЦ, рдЬрд░реА рд╡рд┐рд╢реЗрд╖рддрдГ рд▓рд╣рд╛рди рдирд╕рд▓рд╛ рддрд░реА, BPF рдЪреНрдпрд╛ рдЬрдЧрд╛рдЪрд╛ рдХреЗрд╡рд│ рдкрд░рд┐рдЪрдп рдЖрд╣реЗ рдЖрдгрд┐ "рдкреНрд░рдЧрдд" рд╡реИрд╢рд┐рд╖реНрдЯреНрдпреЗ рдЖрдгрд┐ рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░рдЪреНрдпрд╛ рдорд╣рддреНрддреНрд╡рдкреВрд░реНрдг рднрд╛рдЧрд╛рдВрдЪреЗ рд╡рд░реНрдгрди рдХрд░рдд рдирд╛рд╣реА. рдкреБрдвреЗ рдЬрд╛рдгрд╛рд░реА рдпреЛрдЬрдирд╛ рдЕрд╢реА рдЖрд╣реЗ: рдкреБрдвреАрд▓ рд▓реЗрдЦ BPF рдкреНрд░реЛрдЧреНрд░рд╛рдо рдкреНрд░рдХрд╛рд░рд╛рдВрдЪреЗ рд╡рд┐рд╣рдВрдЧрд╛рд╡рд▓реЛрдХрди рдЕрд╕реЗрд▓ (5.8 рдХрд░реНрдирд▓рдордзреНрдпреЗ 30 рдкреНрд░реЛрдЧреНрд░рд╛рдо рдкреНрд░рдХрд╛рд░ рд╕рдорд░реНрдерд┐рдд рдЖрд╣реЗрдд), рдирдВрддрд░ рдЖрдореНрд╣реА рд╢реЗрд╡рдЯреА рдХрд░реНрдирд▓ рдЯреНрд░реЗрд╕рд┐рдВрдЧ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╡рд╛рдкрд░реВрди рд╡рд╛рд╕реНрддрд╡рд┐рдХ BPF рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдХрд╕реЗ рд▓рд┐рд╣рд╛рдпрдЪреЗ рддреЗ рдкрд╛рд╣реВ. рдЙрджрд╛рд╣рд░рдг рдореНрд╣рдгреВрди, BPF рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░рдЪреНрдпрд╛ рдЕрдзрд┐рдХ рд╕рдЦреЛрд▓ рдЕрднреНрдпрд╛рд╕рдХреНрд░рдорд╛рд╕рд╛рдареА, рддреНрдпрд╛рдирдВрддрд░ BPF рдиреЗрдЯрд╡рд░реНрдХрд┐рдВрдЧ рдЖрдгрд┐ рд╕реБрд░рдХреНрд╖рд╛ рдЕрдиреБрдкреНрд░рдпреЛрдЧрд╛рдВрдЪреА рдЙрджрд╛рд╣рд░рдгреЗ рджреЗрдгреНрдпрд╛рдЪреА рд╡реЗрд│ рдЖрд▓реА рдЖрд╣реЗ.

рдпрд╛ рдорд╛рд▓рд┐рдХреЗрддреАрд▓ рдорд╛рдЧреАрд▓ рд▓реЗрдЦ

  1. рд▓рд╣рд╛рди рдореБрд▓рд╛рдВрд╕рд╛рдареА BPF, рднрд╛рдЧ рд╢реВрдиреНрдп: рдХреНрд▓рд╛рд╕рд┐рдХ BPF

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

  1. BPF рдЖрдгрд┐ XDP рд╕рдВрджрд░реНрдн рдорд╛рд░реНрдЧрджрд░реНрд╢рдХ тАФ рд╕рд┐рд▓рд┐рдпрдо рд╡рд░реВрди BPF рд╡рд░ рджрд╕реНрддрдРрд╡рдЬреАрдХрд░рдг, рдХрд┐рдВрд╡рд╛ рдЕрдзрд┐рдХ рддрдВрддреЛрддрдВрдд рдбреЕрдирд┐рдпрд▓ рдмреЛрд░реНрдХрдорди, BPF рдЪреЗ рдирд┐рд░реНрдорд╛рддреЗ рдЖрдгрд┐ рджреЗрдЦрднрд╛рд▓ рдХрд░рдгрд╛рд░реНтАНрдпрд╛рдВрдкреИрдХреА рдПрдХ. рд╣реЗ рдкрд╣рд┐рд▓реЗ рдЧрдВрднреАрд░ рд╡рд░реНрдгрдирд╛рдВрдкреИрдХреА рдПрдХ рдЖрд╣реЗ, рдЬреЗ рдЗрддрд░рд╛рдВрдкреЗрдХреНрд╖рд╛ рд╡реЗрдЧрд│реЗ рдЖрд╣реЗ рдХреА рдбреЕрдирд┐рдпрд▓рд▓рд╛ рдорд╛рд╣рд┐рдд рдЖрд╣реЗ рдХреА рддреЛ рдХрд╢рд╛рдмрджреНрджрд▓ рд▓рд┐рд╣рд┐рдд рдЖрд╣реЗ рдЖрдгрд┐ рддреЗрдереЗ рдХреЛрдгрддреНрдпрд╛рд╣реА рдЪреБрдХрд╛ рдирд╛рд╣реАрдд. рд╡рд┐рд╢реЗрд╖рддрдГ, рд╣рд╛ рджрд╕реНрддрдРрд╡рдЬ рд╕реБрдкреНрд░рд╕рд┐рджреНрдз рдпреБрдЯрд┐рд▓рд┐рдЯреА рд╡рд╛рдкрд░реВрди XDP рдЖрдгрд┐ TC рдкреНрд░рдХрд╛рд░рдЪреНрдпрд╛ BPF рдкреНрд░реЛрдЧреНрд░рд╛рдорд╕рд╣ рдХрд╕реЗ рдХрд╛рд░реНрдп рдХрд░рд╛рд╡реЗ рдпрд╛рдЪреЗ рд╡рд░реНрдгрди рдХрд░рддреЛ. ip рдкреЕрдХреЗрдЬрдордзреВрди iproute2.

  2. Documentation/networking/filter.txt - рдХреНрд▓рд╛рд╕рд┐рдХ рдЖрдгрд┐ рдирдВрддрд░ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдмреАрдкреАрдПрдлрд╕рд╛рдареА рдХрд╛рдЧрджрдкрддреНрд░рд╛рдВрд╕рд╣ рдореВрд│ рдлрд╛рдЗрд▓. рдЬрд░ рддреБрдореНрд╣рд╛рд▓рд╛ рдЕрд╕реЗрдВрдмреНрд▓реА рднрд╛рд╖рд╛ рдЖрдгрд┐ рддрд╛рдВрддреНрд░рд┐рдХ рд╡рд╛рд╕реНрддреБрд╢рд╛рд╕реНрддреНрд░реАрдп рддрдкрд╢реАрд▓рд╛рдВрдЪрд╛ рдЕрднреНрдпрд╛рд╕ рдХрд░рд╛рдпрдЪрд╛ рдЕрд╕реЗрд▓ рддрд░ рдЪрд╛рдВрдЧрд▓реЗ рд╡рд╛рдЪрди.

  3. рдлреЗрд╕рдмреБрдХ рд╡рд░реВрди BPF рдмрджреНрджрд▓ рдмреНрд▓реЙрдЧ. рдЕрд▓реЗрдХреНрд╕реА рд╕реНрдЯрд╛рд░реЛрд╡реЛрдЗрдЯреЛрд╡реНрд╣ (eBPF рдЪреЗ рд▓реЗрдЦрдХ) рдЖрдгрд┐ Andrii Nakryiko - (рджреЗрдЦрднрд╛рд▓ рдХрд░рдгрд╛рд░рд╛) рддреЗрдереЗ рд▓рд┐рд╣рд┐рд▓реНрдпрд╛рдкреНрд░рдорд╛рдгреЗ рддреЗ рдХреНрд╡рдЪрд┐рддрдЪ, рдкрд░рдВрддреБ рдпреЛрдЧреНрдпрд░рд┐рддреНрдпрд╛ рдЕрджреНрдпрддрдирд┐рдд рдХреЗрд▓реЗ рдЬрд╛рддреЗ. libbpf).

  4. bpftool рдЪреЗ рд░рд╣рд╕реНрдп. рдмреАрдкреАрдПрдлрдЯреВрд▓ рд╡рд╛рдкрд░рдгреНрдпрд╛рдЪреА рдЙрджрд╛рд╣рд░рдгреЗ рдЖрдгрд┐ рд░рд╣рд╕реНрдпрд╛рдВрд╕рд╣ рдХреНрд╡реЗрдВрдЯрд┐рди рдореЛрдиреЗрдЯрдЪрд╛ рдПрдХ рдордиреЛрд░рдВрдЬрдХ рдЯреНрд╡рд┐рдЯрд░ рдереНрд░реЗрдб.

  5. BPF рдордзреНрдпреЗ рдЬрд╛: рд╡рд╛рдЪрди рд╕рд╛рдордЧреНрд░реАрдЪреА рдпрд╛рджреА. Quentin Monnet рдХрдбреВрди BPF рджрд╕реНрддрдРрд╡рдЬреАрдХрд░рдгрд╛рдЪреНрдпрд╛ рд▓рд┐рдВрдХреНрд╕рдЪреА рдПрдХ рд╡рд┐рд╢рд╛рд▓ (рдЖрдгрд┐ рдЕрдЬреВрдирд╣реА рд░рд╛рдЦрд▓реЗрд▓реА) рд╕реВрдЪреА.

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

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