рдЫреЛрдЯреЛрдВ рдХреЗ рд▓рд┐рдП рдмреАрдкреАрдПрдл, рднрд╛рдЧ рдПрдХ: рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдмреАрдкреАрдПрдл

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

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

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

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

рдмреАрдкреАрдПрдл рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХрд╛ рдкрд░рд┐рдЪрдпред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдмреАрдкреАрдПрдл рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдкрд░ рдПрдХ рд╡рд┐рд╣рдВрдЧрдо рджреГрд╖реНрдЯрд┐ рдбрд╛рд▓реЗрдВрдЧреЗ рдФрд░ рдореБрдЦреНрдп рдШрдЯрдХреЛрдВ рдХреА рд░реВрдкрд░реЗрдЦрд╛ рддреИрдпрд╛рд░ рдХрд░реЗрдВрдЧреЗред

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

BPF рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдЬреАрд╡рди рдЪрдХреНрд░, bpffs рдлрд╝рд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдоред рдЗрд╕ рдЦрдВрдб рдореЗрдВ, рд╣рдо рдмреАрдкреАрдПрдл рд╡рд╕реНрддреБрдУрдВ - рдХрд╛рд░реНрдпрдХреНрд░рдореЛрдВ рдФрд░ рдорд╛рдирдЪрд┐рддреНрд░реЛрдВ рдХреЗ рдЬреАрд╡рди рдЪрдХреНрд░ рдкрд░ рдХрд░реАрдм рд╕реЗ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВрдЧреЗред

рдмреАрдкреАрдПрдл рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╡рд╕реНрддреБрдУрдВ рдХрд╛ рдкреНрд░рдмрдВрдзрди рдХрд░рдирд╛ред рд╕рд┐рд╕реНрдЯрдо рдХреА рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХреБрдЫ рд╕рдордЭ рдХреЗ рд╕рд╛рде, рд╣рдо рдЕрдВрддрддрдГ рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдПрдХ рд╡рд┐рд╢реЗрд╖ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реНрдерд╛рди рд╕реЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреИрд╕реЗ рдмрдирд╛рдПрдВ рдФрд░ рд╣реЗрд░рдлреЗрд░ рдХрд░реЗрдВ - bpf(2).

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

рдХрд░реНрдиреЗрд▓ рд╕рд╣рд╛рдпрдХ. рдпрд╣рд╛рдВ рд╣рдо рд╕реАрдЦреЗрдВрдЧреЗ рдХрд┐ рдмреАрдкреАрдПрдл рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд░реНрдиреЗрд▓ рд╣реЗрд▓реНрдкрд░ рдлрд╝рдВрдХреНрд╢рдВрд╕ рддрдХ рдХреИрд╕реЗ рдкрд╣реБрдВрдЪ рд╕рдХрддреЗ рд╣реИрдВ - рдПрдХ рдЙрдкрдХрд░рдг рдЬреЛ рдорд╛рдирдЪрд┐рддреНрд░реЛрдВ рдХреЗ рд╕рд╛рде, рдХреНрд▓рд╛рд╕рд┐рдХ рдмреАрдкреАрдПрдл рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдирдП рдмреАрдкреАрдПрдл рдХреА рдХреНрд╖рдорддрд╛рдУрдВ рдХреЛ рдореМрд▓рд┐рдХ рд░реВрдк рд╕реЗ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИред

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

рд╡рд┐рдХрд╛рд╕ рдЙрдкрдХрд░рдгред рдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдЙрдкрдпреЛрдЧрд┐рддрд╛рдУрдВ рдФрд░ рдХрд░реНрдиреЗрд▓ рдХреЛ рдХреИрд╕реЗ рдЗрдХрдЯреНрдард╛ рдХрд┐рдпрд╛ рдЬрд╛рдП, рдЗрд╕ рдкрд░ рд╕рд╣рд╛рдпрддрд╛ рдЕрдиреБрднрд╛рдЧред

рдирд┐рд╖реНрдХрд░реНрд╖. рд▓реЗрдЦ рдХреЗ рдЕрдВрдд рдореЗрдВ, рдЬрд┐рди рд▓реЛрдЧреЛрдВ рдиреЗ рдЗрд╕реЗ рдЕрдм рддрдХ рдкрдврд╝рд╛ рд╣реИ рдЙрдиреНрд╣реЗрдВ рдкреНрд░реЗрд░рдХ рд╢рдмреНрдж рдорд┐рд▓реЗрдВрдЧреЗ рдФрд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд▓реЗрдЦреЛрдВ рдореЗрдВ рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдЗрд╕рдХрд╛ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рд╡рд┐рд╡рд░рдг рдорд┐рд▓реЗрдЧрд╛ред рд╣рдо рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рд╕реНрд╡-рдЕрдзреНрдпрдпрди рдХреЗ рд▓рд┐рдП рдХрдИ рд▓рд┐рдВрдХ рднреА рд╕реВрдЪреАрдмрджреНрдз рдХрд░реЗрдВрдЧреЗ рдЬрд┐рдирдХреЗ рдкрд╛рд╕ рдирд┐рд░рдВрддрд░рддрд╛ рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдиреЗ рдХреА рдЗрдЪреНрдЫрд╛ рдпрд╛ рдХреНрд╖рдорддрд╛ рдирд╣реАрдВ рд╣реИред

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

рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рд╣рдо рдмреАрдкреАрдПрдл рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░реЗрдВ, рд╣рдо рдЖрдЦрд┐рд░реА рдмрд╛рд░ (рдУрд╣) рдЗрд╕рдХрд╛ рд╕рдВрджрд░реНрдн рд▓реЗрдВрдЧреЗ рдХреНрд▓рд╛рд╕рд┐рдХ рдмреАрдкреАрдПрдл, рдЬрд┐рд╕реЗ рдЖрд░рдЖрдИрдПрд╕рд╕реА рдорд╢реАрдиреЛрдВ рдХреЗ рдЖрдЧрдорди рдХреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рд╡рд┐рдХрд╕рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдФрд░ рдХреБрд╢рд▓ рдкреИрдХреЗрдЯ рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рдХреА рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдЗрддрдирд╛ рд╕рдлрд▓ рд╕рд╛рдмрд┐рдд рд╣реБрдЖ рдХрд┐, рдмрд░реНрдХрд▓реЗ рдпреВрдирд┐рдХреНрд╕ рдореЗрдВ рдирдмреНрдмреЗ рдХреЗ рджрд╢рдХ рдореЗрдВ рдкреИрджрд╛ рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж, рдЗрд╕реЗ рдЕрдзрд┐рдХрд╛рдВрд╢ рдореМрдЬреВрджрд╛ рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдкреЛрд░реНрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛, рдмреАрд╕ рдХреЗ рджрд╢рдХ рдореЗрдВ рдЬреАрд╡рд┐рдд рд░рд╣рд╛ рдФрд░ рдЕрднреА рднреА рдирдП рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдвреВрдВрдв рд░рд╣рд╛ рд╣реИред

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

рдордЬрд╝рд╛рдХрд┐рдпрд╛ рддрд╕реНрд╡реАрд░

рдЗрд╕рдХреЗ рдореВрд▓ рдореЗрдВ, рдмреАрдкреАрдПрдл рдПрдХ рд╕реИрдВрдбрдмреЙрдХреНрд╕ рд╡рд░реНрдЪреБрдЕрд▓ рдорд╢реАрди рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рд╕реБрд░рдХреНрд╖рд╛ рд╕реЗ рд╕рдордЭреМрддрд╛ рдХрд┐рдП рдмрд┐рдирд╛ рдХрд░реНрдиреЗрд▓ рд╕реНрдкреЗрд╕ рдореЗрдВ "рдордирдорд╛рдирд╛" рдХреЛрдб рдЪрд▓рд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИред рдмреАрдкреАрдПрдл рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реНрдерд╛рди рдореЗрдВ рдмрдирд╛рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдХрд░реНрдиреЗрд▓ рдореЗрдВ рд▓реЛрдб рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдФрд░ рдХреБрдЫ рдИрд╡реЗрдВрдЯ рд╕реНрд░реЛрдд рд╕реЗ рдЬреБрдбрд╝реЗ рд╣реЛрддреЗ рд╣реИрдВред рдПрдХ рдШрдЯрдирд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХрд┐рд╕реА рдиреЗрдЯрд╡рд░реНрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкрд░ рдкреИрдХреЗрдЯ рдХреА рдбрд┐рд▓реАрд╡рд░реА, рдХреБрдЫ рдХрд░реНрдиреЗрд▓ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рд▓реЙрдиреНрдЪ рдЗрддреНрдпрд╛рджрд┐ред рдкреИрдХреЗрдЬ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдмреАрдкреАрдПрдл рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЗ рдкрд╛рд╕ рдкреИрдХреЗрдЬ рдХреЗ рдбреЗрдЯрд╛ рдФрд░ рдореЗрдЯрд╛рдбреЗрдЯрд╛ рддрдХ рдкрд╣реБрдВрдЪ рд╣реЛрдЧреА (рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдкрдврд╝рдиреЗ рдФрд░, рд╕рдВрднрд╡рддрдГ, рд▓рд┐рдЦрдиреЗ рдХреЗ рд▓рд┐рдП); рдХрд░реНрдиреЗрд▓ рдлрд╝рдВрдХреНрд╢рди рдЪрд▓рд╛рдиреЗ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдХреЗ рддрд░реНрдХ рдлрд╝рдВрдХреНрд╢рди, рдЬрд┐рд╕рдореЗрдВ рдХрд░реНрдиреЗрд▓ рдореЗрдореЛрд░реА рдХреЗ рдкреЙрдЗрдВрдЯрд░реНрд╕ рдЖрджрд┐ рд╢рд╛рдорд┐рд▓ рд╣реИрдВред

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

рдЫреЛрдЯреЛрдВ рдХреЗ рд▓рд┐рдП рдмреАрдкреАрдПрдл, рднрд╛рдЧ рдПрдХ: рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдмреАрдкреАрдПрдл

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

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

рдЫреЛрдЯреЛрдВ рдХреЗ рд▓рд┐рдП рдмреАрдкреАрдПрдл, рднрд╛рдЧ рдПрдХ: рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдмреАрдкреАрдПрдл

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

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

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

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

рдЫреЛрдЯреЛрдВ рдХреЗ рд▓рд┐рдП рдмреАрдкреАрдПрдл, рднрд╛рдЧ рдПрдХ: рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдмреАрдкреАрдПрдл

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

рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХрд░реНрдиреЗрд▓ рдореЙрдбреНрдпреВрд▓ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рджрд╛рди рдХреА рдЧрдИ рдХреНрд╖рдорддрд╛рдУрдВ рдХреЗ рд╕рдорд╛рди рд╣реИ, рдЬрд┐рд╕рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмреАрдкреАрдПрдл рдХреЗ рдХреБрдЫ рдлрд╛рдпрджреЗ рд╣реИрдВ (рдмреЗрд╢рдХ, рдЖрдк рдХреЗрд╡рд▓ рд╕рдорд╛рди рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреА рддреБрд▓рдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╕рд┐рд╕реНрдЯрдо рдЯреНрд░реЗрд╕рд┐рдВрдЧ - рдЖрдк рдмреАрдкреАрдПрдл рдХреЗ рд╕рд╛рде рдПрдХ рдордирдорд╛рдирд╛ рдбреНрд░рд╛рдЗрд╡рд░ рдирд╣реАрдВ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ)ред рдЖрдк рдХрдо рдкреНрд░рд╡реЗрд╢ рд╕реАрдорд╛ рдиреЛрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдмреАрдкреАрдПрдл рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реА рдХреБрдЫ рдЙрдкрдпреЛрдЧрд┐рддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдХрд░реНрдиреЗрд▓ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреМрд╢рд▓, рдпрд╛ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рдХреМрд╢рд▓ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ), рд░рдирдЯрд╛рдЗрдо рд╕реБрд░рдХреНрд╖рд╛ (рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рдЕрдкрдирд╛ рд╣рд╛рде рдЙрдард╛рдПрдВ рдЬрд┐рдиреНрд╣реЛрдВрдиреЗ рд▓рд┐рдЦрддреЗ рд╕рдордп рд╕рд┐рд╕реНрдЯрдо рдХреЛ рдирд╣реАрдВ рддреЛрдбрд╝рд╛ рд╣реИ рдпрд╛ рдкрд░реАрдХреНрд╖рдг рдореЙрдбреНрдпреВрд▓), рдкрд░рдорд╛рдгреБрддрд╛ - рдореЙрдбреНрдпреВрд▓ рдХреЛ рдкреБрдирдГ рд▓реЛрдб рдХрд░рддреЗ рд╕рдордп рдбрд╛рдЙрдирдЯрд╛рдЗрдо рд╣реЛрддрд╛ рд╣реИ, рдФрд░ рдмреАрдкреАрдПрдл рд╕рдмрд╕рд┐рд╕реНрдЯрдо рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдХреЛрдИ рднреА рдШрдЯрдирд╛ рдЫреВрдЯ рди рдЬрд╛рдП (рдирд┐рд╖реНрдкрдХреНрд╖ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, рдпрд╣ рд╕рднреА рдкреНрд░рдХрд╛рд░ рдХреЗ рдмреАрдкреАрдПрдл рдХрд╛рд░реНрдпрдХреНрд░рдореЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдЪ рдирд╣реАрдВ рд╣реИ)ред

рдРрд╕реА рдХреНрд╖рдорддрд╛рдУрдВ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдмреАрдкреАрдПрдл рдХреЛ рдХрд░реНрдиреЗрд▓ рдХреЗ рд╡рд┐рд╕реНрддрд╛рд░ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╛рд░реНрд╡рднреМрдорд┐рдХ рдЙрдкрдХрд░рдг рдмрдирд╛рддреА рд╣реИ, рдЬрд┐рд╕рдХреА рдкреБрд╖реНрдЯрд┐ рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ рдХреА рдЬрд╛рддреА рд╣реИ: рдЕрдзрд┐рдХ рд╕реЗ рдЕрдзрд┐рдХ рдирдП рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдмреАрдкреАрдПрдл рдореЗрдВ рдЬреЛрдбрд╝реЗ рдЬрд╛рддреЗ рд╣реИрдВ, рдЕрдзрд┐рдХ рд╕реЗ рдЕрдзрд┐рдХ рдмрдбрд╝реА рдХрдВрдкрдирд┐рдпрд╛рдВ 24├Ч7 рд▓рдбрд╝рд╛рдХреВ рд╕рд░реНрд╡рд░ рдкрд░ рдмреАрдкреАрдПрдл рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреА рд╣реИрдВ, рдЕрдзрд┐рдХ рд╕реЗ рдЕрдзрд┐рдХ рд╕реНрдЯрд╛рд░реНрдЯрдЕрдк рдЕрдкрдирд╛ рд╡реНрдпрд╡рд╕рд╛рдп рдЙрди рд╕рдорд╛рдзрд╛рдиреЛрдВ рдкрд░ рдмрдирд╛рддреЗ рд╣реИрдВ рдЬреЛ рдмреАрдкреАрдПрдл рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реЛрддреЗ рд╣реИрдВред рдмреАрдкреАрдПрдл рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣рд░ рдЬрдЧрд╣ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ: рдбреАрдбреАрдУрдПрд╕ рд╣рдорд▓реЛрдВ рд╕реЗ рдмрдЪрд╛рдиреЗ рдореЗрдВ, рдПрд╕рдбреАрдПрди рдмрдирд╛рдиреЗ рдореЗрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХреБрдмреЗрд░рдиреЗрдЯреНрд╕ рдХреЗ рд▓рд┐рдП рдиреЗрдЯрд╡рд░реНрдХ рд▓рд╛рдЧреВ рдХрд░рдирд╛), рдореБрдЦреНрдп рд╕рд┐рд╕реНрдЯрдо рдЯреНрд░реЗрд╕рд┐рдВрдЧ рдЯреВрд▓ рдФрд░ рд╕рд╛рдВрдЦреНрдпрд┐рдХреА рд╕рдВрдЧреНрд░рд╛рд╣рдХ рдХреЗ рд░реВрдк рдореЗрдВ, рдШреБрд╕рдкреИрда рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рд╡рд╛рд▓реЗ рд╕рд┐рд╕реНрдЯрдо рдФрд░ рд╕реИрдВрдбрдмреЙрдХреНрд╕ рд╕рд┐рд╕реНрдЯрдо рдЖрджрд┐ рдореЗрдВред

рдЖрдЗрдП рд▓реЗрдЦ рдХреЗ рдЕрд╡рд▓реЛрдХрди рднрд╛рдЧ рдХреЛ рдпрд╣реАрдВ рд╕рдорд╛рдкреНрдд рдХрд░реЗрдВ рдФрд░ рд╡рд░реНрдЪреБрдЕрд▓ рдорд╢реАрди рдФрд░ рдмреАрдкреАрдПрдл рдкрд╛рд░рд┐рд╕реНрдерд┐рддрд┐рдХреА рддрдВрддреНрд░ рдХреЛ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рджреЗрдЦреЗрдВред

рд╡рд┐рд╖рдпрд╛рдВрддрд░: рдЙрдкрдпреЛрдЧрд┐рддрд╛рдПрдБ

рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЕрдиреБрднрд╛рдЧреЛрдВ рдореЗрдВ рдЙрджрд╛рд╣рд░рдг рдЪрд▓рд╛рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдХрдо рд╕реЗ рдХрдо рдХрдИ рдЙрдкрдпреЛрдЧрд┐рддрд╛рдУрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛ рд╕рдХрддреА рд╣реИ llvm/clang рдмреАрдкреАрдПрдл рд╕рдорд░реНрдерди рдХреЗ рд╕рд╛рде рдФрд░ bpftoolред рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рд╡рд┐рдХрд╛рд╕ рдЙрдкрдХрд░рдг рдЖрдк рдЙрдкрдпреЛрдЧрд┐рддрд╛рдУрдВ рдХреЛ рдЕрд╕реЗрдВрдмрд▓ рдХрд░рдиреЗ рдХреЗ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЗ рд╕рд╛рде-рд╕рд╛рде рдЕрдкрдиреЗ рдХрд░реНрдиреЗрд▓ рдХреЛ рднреА рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рдЕрдиреБрднрд╛рдЧ рдиреАрдЪреЗ рд░рдЦрд╛ рдЧрдпрд╛ рд╣реИ рддрд╛рдХрд┐ рд╣рдорд╛рд░реА рдкреНрд░рд╕реНрддреБрддрд┐ рдХреЗ рд╕рд╛рдордВрдЬрд╕реНрдп рдореЗрдВ рдЦрд▓рд▓ рди рдкрдбрд╝реЗред

рдмреАрдкреАрдПрдл рд╡рд░реНрдЪреБрдЕрд▓ рдорд╢реАрди рд░рдЬрд┐рд╕реНрдЯрд░ рдФрд░ рдирд┐рд░реНрджреЗрд╢ рдкреНрд░рдгрд╛рд▓реА

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

рдмреАрдкреАрдПрдл рдореЗрдВ рдЧреНрдпрд╛рд░рд╣ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛-рд╕реБрд▓рдн 64-рдмрд┐рдЯ рд░рдЬрд┐рд╕реНрдЯрд░ рд╣реИрдВ r0-r10 рдФрд░ рдПрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд╛рдЙрдВрдЯрд░. рдкрдВрдЬреАрдХрд░рдг рдХрд░рд╡рд╛рдирд╛ r10 рдЗрд╕рдореЗрдВ рдПрдХ рдлрд╝реНрд░реЗрдо рдкреЙрдЗрдВрдЯрд░ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдпрд╣ рдХреЗрд╡рд▓-рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реЛрддрд╛ рд╣реИред рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЗ рдкрд╛рд╕ рд░рдирдЯрд╛рдЗрдо рдкрд░ 512-рдмрд╛рдЗрдЯ рд╕реНрдЯреИрдХ рдФрд░ рдорд╛рдирдЪрд┐рддреНрд░реЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдЕрд╕реАрдорд┐рдд рдорд╛рддреНрд░рд╛ рдореЗрдВ рд╕рд╛рдЭрд╛ рдореЗрдореЛрд░реА рддрдХ рдкрд╣реБрдВрдЪ рд╣реЛрддреА рд╣реИред

рдмреАрдкреАрдПрдл рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛ рдкреНрд░реЛрдЧреНрд░рд╛рдо-рдкреНрд░рдХрд╛рд░ рдХреЗ рдХрд░реНрдиреЗрд▓ рд╣реЗрд▓реНрдкрд░реНрд╕ рдХрд╛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕реЗрдЯ рдФрд░, рд╣рд╛рд▓ рд╣реА рдореЗрдВ, рдирд┐рдпрдорд┐рдд рдлрд╝рдВрдХреНрд╢рди рдЪрд▓рд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рдХреЙрд▓ рдХрд┐рдП рдЧрдП рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдореЗрдВ рдкрд╛рд░рд┐рдд рдкрд╛рдВрдЪ рддрд░реНрдХ рддрдХ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ r1-r5, рдФрд░ рд░рд┐рдЯрд░реНрди рд╡реИрд▓реНрдпреВ рдХреЛ рдкрд╛рд╕ рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ r0. рдпрд╣ рдЧрд╛рд░рдВрдЯреА рджреА рдЬрд╛рддреА рд╣реИ рдХрд┐ рдлрд╝рдВрдХреНрд╢рди рд╕реЗ рд▓реМрдЯрдиреЗ рдХреЗ рдмрд╛рдж, рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдХреА рд╕рд╛рдордЧреНрд░реА r6-r9 рдирд╣реАрдВ рдмрджрд▓реЗрдЧрд╛ред

рдХреБрд╢рд▓ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЕрдиреБрд╡рд╛рдж рдХреЗ рд▓рд┐рдП, рд░рдЬрд┐рд╕реНрдЯрд░ рдХрд░реЗрдВ r0-r11 рд╡рд░реНрддрдорд╛рди рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреА рдПрдмреАрдЖрдИ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП, рд╕рднреА рд╕рдорд░реНрдерд┐рдд рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреЛ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд░реВрдк рд╕реЗ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ рдореЗрдВ рдореИрдк рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХреЗ рд▓рд┐рдП 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 (рдПрдХреНрд╕рдбреАрдкреА рдХреЗ рд▓рд┐рдП) рдпрд╛ рд╕рдВрд░рдЪрдирд╛ struct __sk_buff (рд╡рд┐рднрд┐рдиреНрди рдиреЗрдЯрд╡рд░реНрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЗ рд▓рд┐рдП) рдпрд╛ рд╕рдВрд░рдЪрдирд╛ struct pt_regs (рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдЯреНрд░реЗрд╕рд┐рдВрдЧ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЗ рд▓рд┐рдП), рдЖрджрд┐ред

рддреЛ, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд░рдЬрд┐рд╕реНрдЯрд░реЛрдВ, рдХрд░реНрдиреЗрд▓ рд╣реЗрд▓реНрдкрд░реНрд╕, рдПрдХ рд╕реНрдЯреИрдХ, рдПрдХ рд╕рдВрджрд░реНрдн рд╕реВрдЪрдХ рдФрд░ рдорд╛рдирдЪрд┐рддреНрд░реЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рд╛рдЭрд╛ рдореЗрдореЛрд░реА рдХрд╛ рдПрдХ рд╕реЗрдЯ рдерд╛ред рдРрд╕рд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╛рддреНрд░рд╛ рдкрд░ рдпрд╣ рд╕рдм рдмрд┐рд▓реНрдХреБрд▓ рдЬрд░реВрд░реА рд╣реИ, рд▓реЗрдХрд┐рди...

рдЖрдЗрдП рд╡рд┐рд╡рд░рдг рдЬрд╛рд░реА рд░рдЦреЗрдВ рдФрд░ рдЗрди рд╡рд╕реНрддреБрдУрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдорд╛рдВрдб рд╕рд┐рд╕реНрдЯрдо рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реЗрдВред рд╕рднреА (рд▓рдЧрднрдЧ рд╕рднреА) рдмреАрдкреАрдПрдл рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХрд╛ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд 64-рдмрд┐рдЯ рдЖрдХрд╛рд░ рд╣реЛрддрд╛ рд╣реИред рдпрджрд┐ рдЖрдк 64-рдмрд┐рдЯ рдмрд┐рдЧ рдПрдВрдбрд┐рдпрди рдорд╢реАрди рдкрд░ рдПрдХ рдирд┐рд░реНрджреЗрд╢ рджреЗрдЦреЗрдВрдЧреЗ рддреЛ рдЖрдк рджреЗрдЦреЗрдВрдЧреЗ

рдЫреЛрдЯреЛрдВ рдХреЗ рд▓рд┐рдП рдмреАрдкреАрдПрдл, рднрд╛рдЧ рдПрдХ: рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдмреАрдкреАрдПрдл

рдпрд╣рд╛рдВ Code - рдпрд╣ рдирд┐рд░реНрджреЗрд╢ рдХрд╛ рдПрдиреНрдХреЛрдбрд┐рдВрдЧ рд╣реИ, Dst/Src рдХреНрд░рдорд╢рдГ рд░рд┐рд╕реАрд╡рд░ рдФрд░ рд╕реНрд░реЛрдд рдХреА рдПрдиреНрдХреЛрдбрд┐рдВрдЧ рд╣реИрдВ, Off - 16-рдмрд┐рдЯ рд╣рд╕реНрддрд╛рдХреНрд╖рд░рд┐рдд рдЗрдВрдбреЗрдВрдЯреЗрд╢рди, рдФрд░ Imm рдПрдХ 32-рдмрд┐рдЯ рд╣рд╕реНрддрд╛рдХреНрд╖рд░рд┐рдд рдкреВрд░реНрдгрд╛рдВрдХ рд╣реИ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреБрдЫ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рд╕реАрдмреАрдкреАрдПрдл рд╕реНрдерд┐рд░рд╛рдВрдХ K рдХреЗ рд╕рдорд╛рди)ред рдПрдиреНрдХреЛрдбрд┐рдВрдЧ 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.h ╨╕ bpf_common.h, рдЬреЛ рдмреАрдкреАрдПрдл рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЗ рд╕рдВрдЦреНрдпрд╛рддреНрдордХ рдХреЛрдб рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рд╕реНрд╡рдпрдВ рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХрд╛ рдЕрдзреНрдпрдпрди рдХрд░рддреЗ рд╕рдордп рдФрд░/рдпрд╛ рдмрд╛рдпрдиреЗрд░рд┐рдЬрд╝ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рддреЗ рд╕рдордп, рдЖрдк рдЬрдЯрд┐рд▓рддрд╛ рдХреЗ рдХреНрд░рдо рдореЗрдВ рдХреНрд░рдордмрджреНрдз рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕реНрд░реЛрддреЛрдВ рдореЗрдВ рд╢рдмреНрджрд╛рд░реНрде рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ: рдЕрдиреМрдкрдЪрд╛рд░рд┐рдХ рдИрдмреАрдкреАрдПрдл рд╡рд┐рд╢рд┐рд╖реНрдЯрддрд╛, рдмреАрдкреАрдПрдл рдФрд░ рдПрдХреНрд╕рдбреАрдкреА рд╕рдВрджрд░реНрдн рдЧрд╛рдЗрдб, рдирд┐рд░реНрджреЗрд╢ рд╕реЗрдЯ, рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг/рдиреЗрдЯрд╡рд░реНрдХрд┐рдВрдЧ/рдлрд╝рд┐рд▓реНрдЯрд░.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. рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЬреЗрдПрдордкреА рдХреНрд▓рд╛рд╕ 1 рдСрдкрд░реЗрд╢рди рд╣реИ рдмреАрдкреАрдПрдл_рдЬреЗрдИрдХреНрдпреВ (рдпрджрд┐ рдмрд░рд╛рдмрд░ рд╣реЛ рддреЛ рдХреВрджреЗрдВ)ред рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдмрд┐рдЯ рдХреЗ рдмрд╛рдж рд╕реЗ S рд╢реВрдиреНрдп рд╣реИ, рдпрд╣ рдлрд╝реАрд▓реНрдб рдХреЗ рд╕рд╛рде рд╕реНрд░реЛрдд рд░рдЬрд┐рд╕реНрдЯрд░ рдХреЗ рдореВрд▓реНрдп рдХреА рддреБрд▓рдирд╛ рдХрд░рддрд╛ рд╣реИ Imm. рдпрджрд┐ рдорд╛рди рдореЗрд▓ рдЦрд╛рддреЗ рд╣реИрдВ, рддреЛ рд╕рдВрдХреНрд░рдордг рд╣реЛрддрд╛ рд╣реИ PC + OffрдЬрд╣рд╛рдВ PC, рд╣рдореЗрд╢рд╛ рдХреА рддрд░рд╣, рдЕрдЧрд▓реЗ рдирд┐рд░реНрджреЗрд╢ рдХрд╛ рдкрддрд╛ рд╢рд╛рдорд┐рд▓ рд╣реИред рдЕрдВрдд рдореЗрдВ, рдЬреЗрдПрдордкреА рдХреНрд▓рд╛рд╕ 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, рдЬрдм рд╣рдо рд╕реНрдерд╛рдирд╛рдВрддрд░рдг рдФрд░ рдорд╛рдирдЪрд┐рддреНрд░реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рддреЗ рд╣реИрдВред

рдЙрджрд╛рд╣рд░рдг: рдорд╛рдирдХ рдЙрдкрдХрд░рдгреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдмреАрдкреАрдПрдл рдХреЛ рдЕрд▓рдЧ рдХрд░рдирд╛

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

$ 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 рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдЬреАрд╡рдирдЪрдХреНрд░, bpffs рдлрд╝рд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо

(рдореИрдВрдиреЗ рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рдЗрд╕ рдЙрдкрдзрд╛рд░рд╛ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдХреБрдЫ рд╡рд┐рд╡рд░рдг рдпрд╣рд╛рдВ рд╕реЗ рд╕реАрдЦреЗ рд░реЛрдЬрд╝рд╛ рдПрд▓реЗрдХреНрд╕реА рд╕реНрдЯрд╛рд░реЛрд╡реЛрдЗрдЯреЛрд╡ рдореЗрдВ рдмреАрдкреАрдПрдл рдмреНрд▓реЙрдЧ.)

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

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

рдЫреЛрдЯреЛрдВ рдХреЗ рд▓рд┐рдП рдмреАрдкреАрдПрдл, рднрд╛рдЧ рдПрдХ: рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдмреАрдкреАрдПрдл

рдХрд┐рд╕реА рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдЖрдорддреМрд░ рдкрд░ рдЗрд╕реЗ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреЗ рдЗрд╡реЗрдВрдЯ рдЬрдирд░реЗрдЯрд░ рд╕реЗ рдЬреЛрдбрд╝ рджреЗрддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо рдЗрд╕реЗ рдЖрдиреЗ рд╡рд╛рд▓реЗ рдкреИрдХреЗрдЯреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдпрд╛ рдХреБрдЫ рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдиреЗрдЯрд╡рд░реНрдХ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкрд░ рд░рдЦ рд╕рдХрддреЗ рд╣реИрдВ tracepoint рдореВрд▓ рдореЗрдВ. рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░, рд╕рдВрджрд░реНрдн рдХрд╛рдЙрдВрдЯрд░ рднреА рдПрдХ рд╕реЗ рдмрдврд╝ рдЬрд╛рдПрдЧрд╛ рдФрд░ рд╣рдо рд▓реЛрдбрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдореЗрдВ рдлрд╝рд╛рдЗрд▓ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдХреЛ рдмрдВрдж рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдВрдЧреЗред

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

рдЫреЛрдЯреЛрдВ рдХреЗ рд▓рд┐рдП рдмреАрдкреАрдПрдл, рднрд╛рдЧ рдПрдХ: рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдмреАрдкреАрдПрдл

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

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

рдЫреЛрдЯреЛрдВ рдХреЗ рд▓рд┐рдП рдмреАрдкреАрдПрдл, рднрд╛рдЧ рдПрдХ: рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдмреАрдкреАрдПрдл

рдмреАрдкреАрдПрдлрдПрдл рдореЗрдВ рдлрд╛рдЗрд▓реЗрдВ рдмрдирд╛рдирд╛ рдЬреЛ рдмреАрдкреАрдПрдл рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рддрд╛ рд╣реИ рдЙрд╕реЗ "рдкрд┐рдирд┐рдВрдЧ" рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ (рдЬреИрд╕рд╛ рдХрд┐ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╡рд╛рдХреНрдпрд╛рдВрд╢ рдореЗрдВ рд╣реИ: "рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдмреАрдкреАрдПрдл рдкреНрд░реЛрдЧреНрд░рд╛рдо рдпрд╛ рдореИрдк рдХреЛ рдкрд┐рди рдХрд░ рд╕рдХрддреА рд╣реИ")ред рдмреАрдкреАрдПрдл рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рд▓рд┐рдП рдлрд╝рд╛рдЗрд▓ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдирд╛ рди рдХреЗрд╡рд▓ рд╕реНрдерд╛рдиреАрдп рдСрдмреНрдЬреЗрдХреНрдЯ рдХреЗ рдЬреАрд╡рди рдХреЛ рдмрдврд╝рд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рдмрд▓реНрдХрд┐ рд╡реИрд╢реНрд╡рд┐рдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреА рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдХреЗ рд▓рд┐рдП рднреА рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ - рд╡реИрд╢реНрд╡рд┐рдХ 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, рдЬрд┐рд╕рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рд╣реИ:

#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_PROG_TYPE_XDP, рдЬреЛ рдорд╛рди рд▓реМрдЯрд╛рдПрдЧрд╛ XDP_PASS (рд╕рднреА рдкреИрдХреЗрдЬ рдЫреЛрдбрд╝реЗрдВ)ред BPF рдЕрд╕реЗрдВрдмрд▓рд░ рдореЗрдВ рдпрд╣ рдмрд╣реБрдд рд╕рд░рд▓ рджрд┐рдЦрддрд╛ рд╣реИ:

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_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()
};

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

рдмреАрдкреАрдПрдл рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдЗрд╕реЗ рдХрд░реНрдиреЗрд▓ рдореЗрдВ рд▓реЛрдб рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВред рдорд╛рдкрджрдВрдбреЛрдВ рдХрд╛ рд╣рдорд╛рд░рд╛ рдиреНрдпреВрдирддрдо рд╕реЗрдЯ 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 рдмреАрдкреАрдПрдл рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдореЗрдВ рдмрд╛рдЗрдирд░реА рдХреЛрдб рдХреЗ 16 рдмрд╛рдЗрдЯреНрд╕ - рджреЛ рдирд┐рд░реНрджреЗрд╢ - рд▓рдЧрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЕрдкрдиреЗ рдореВрд▓ рд░реВрдк (x86_64) рдореЗрдВ рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА 40 рдмрд╛рдЗрдЯреНрд╕ рд╣реИред рдЖрдЗрдП рдЕрдкрдиреЗ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЛ рдЙрд╕рдХреЗ рдореВрд▓ рд░реВрдк рдореЗрдВ рджреЗрдЦреЗрдВ:

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

рдХреЛрдИ рдЖрд╢реНрдЪрд░реНрдп рдирд╣реАрдВред рдЕрдм рдЖрдЗрдП JIT рдХрдВрдкрд╛рдЗрд▓рд░ рджреНрд╡рд╛рд░рд╛ рдЙрддреНрдкрдиреНрди рдХреЛрдб рдХреЛ рджреЗрдЦреЗрдВ:

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

рдореИрдкреНрд╕

рдмреАрдкреАрдПрдл рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╕рдВрд░рдЪрд┐рдд рдореЗрдореЛрд░реА рдХреНрд╖реЗрддреНрд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдЕрдиреНрдп рдмреАрдкреАрдПрдл рдкреНрд░реЛрдЧреНрд░рд╛рдо рдФрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реНрдерд╛рди рдореЗрдВ рдкреНрд░реЛрдЧреНрд░рд╛рдо рджреЛрдиреЛрдВ рдХреЗ рд▓рд┐рдП рдкрд╣реБрдВрдЪ рдпреЛрдЧреНрдп рд╣реИрдВред рдЗрди рд╡рд╕реНрддреБрдУрдВ рдХреЛ рдорд╛рдирдЪрд┐рддреНрд░ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕ рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рд╣рдо рджрд┐рдЦрд╛рдПрдВрдЧреЗ рдХрд┐ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЙрдирдореЗрдВ рд╣реЗрд░рдлреЗрд░ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рдП bpf.

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

рдпрджрд┐ рдЖрдк C++ рдореЗрдВ рдПрдХ рд╣реИрд╢ рддрд╛рд▓рд┐рдХрд╛ рдмрдирд╛рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдХрд╣реЗрдВрдЧреЗ unordered_map<int,long> woo, рдЬрд┐рд╕рдХрд╛ рд░реВрд╕реА рдореЗрдВ рдЕрд░реНрде рд╣реИ "рдореБрдЭреЗ рдПрдХ рдЯреЗрдмрд▓ рдЪрд╛рд╣рд┐рдПред" woo рдЕрд╕реАрдорд┐рдд рдЖрдХрд╛рд░, рдЬрд┐рдирдХреА рдХреБрдВрдЬрд┐рдпрд╛рдБ рдкреНрд░рдХрд╛рд░ рдХреА рд╣реЛрддреА рд╣реИрдВ int, рдФрд░ рдорд╛рди рдкреНрд░рдХрд╛рд░ рд╣реИрдВ long" рдмреАрдкреАрдПрдл рд╣реИрд╢ рддрд╛рд▓рд┐рдХрд╛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдмрд╣реБрдд рдХреБрдЫ рд╡рд╣реА рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рд╕рд┐рд╡рд╛рдп рдЗрд╕рдХреЗ рдХрд┐ рд╣рдореЗрдВ рддрд╛рд▓рд┐рдХрд╛ рдХрд╛ рдЕрдзрд┐рдХрддрдо рдЖрдХрд╛рд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛, рдФрд░ рдХреБрдВрдЬрд┐рдпреЛрдВ рдФрд░ рдорд╛рдиреЛрдВ рдХреЗ рдкреНрд░рдХрд╛рд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп, рд╣рдореЗрдВ рдмрд╛рдЗрдЯреНрд╕ рдореЗрдВ рдЙрдирдХреЗ рдЖрдХрд╛рд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ . рдорд╛рдирдЪрд┐рддреНрд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдорд╛рдВрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ 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.

рдЗрд╕рд▓рд┐рдП, рд╣рдо рдмреАрдкреАрдПрдл рдкреНрд░реЛрдЧреНрд░рд╛рдо рдмрдирд╛ рдФрд░ рд▓реЛрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд╕рд╛рде рд╣реА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реНрдерд╛рди рд╕реЗ рдорд╛рдирдЪрд┐рддреНрд░ рдмрдирд╛ рдФрд░ рдкреНрд░рдмрдВрдзрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЕрдм рдпрд╣ рджреЗрдЦрдирд╛ рддрд░реНрдХрд╕рдВрдЧрдд рд╣реИ рдХрд┐ рд╣рдо рдмреАрдкреАрдПрдл рдХрд╛рд░реНрдпрдХреНрд░рдореЛрдВ рд╕реЗ рдорд╛рдирдЪрд┐рддреНрд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╣рдо рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдорд╢реАрди рдореИрдХреНрд░реЛ рдХреЛрдб рдореЗрдВ рдкрдврд╝рдиреЗ рдореЗрдВ рдХрдард┐рди рдкреНрд░реЛрдЧреНрд░рд╛рдореЛрдВ рдХреА рднрд╛рд╖рд╛ рдореЗрдВ рдмрд╛рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ рджрд┐рдЦрд╛рдиреЗ рдХрд╛ рд╕рдордп рдЖ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдмреАрдкреАрдПрдл рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреИрд╕реЗ рд▓рд┐рдЦреЗ рдФрд░ рдмрдирд╛рдП рд░рдЦреЗ рдЬрд╛рддреЗ рд╣реИрдВ - рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ libbpf.

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

Libbpf рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ BPF рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓рд┐рдЦрдирд╛

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

рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЬреИрд╕рд╛ рдХрд┐ рд╣рдо рдЗрд╕ рдФрд░ рдмрд╛рдж рдХреЗ рд▓реЗрдЦреЛрдВ рдореЗрдВ рджреЗрдЦреЗрдВрдЧреЗ, libbpf рдЗрд╕рдХреЗ (рдпрд╛ рдЗрд╕реА рддрд░рд╣ рдХреЗ рдЙрдкрдХрд░рдгреЛрдВ рдХреЗ рдмрд┐рдирд╛) рдХрд╛рдлреА рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ - iproute2, libbcc, libbpf-go, рдЖрджрд┐) рдЬреАрдирд╛ рдЕрд╕рдВрднрд╡ рд╣реИред рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдХреА рдмреЗрд╣рддрд░реАрди рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ libbpf рдмреАрдкреАрдПрдл рд╕реАрдУ-рдЖрд░рдИ (рдПрдХ рдмрд╛рд░ рд╕рдВрдХрд▓рд┐рдд рдХрд░реЗрдВ, рд╣рд░ рдЬрдЧрд╣ рдЪрд▓рд╛рдПрдВ) - рдПрдХ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдЬреЛ рдЖрдкрдХреЛ рдмреАрдкреАрдПрдл рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓рд┐рдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдЬреЛ рдПрдХ рдХрд░реНрдиреЗрд▓ рд╕реЗ рджреВрд╕рд░реЗ рдХрд░реНрдиреЗрд▓ рдореЗрдВ рдкреЛрд░реНрдЯреЗрдмрд▓ рд╣реЛрддреЗ рд╣реИрдВ, рд╡рд┐рднрд┐рдиреНрди рдПрдкреАрдЖрдИ рдкрд░ рдЪрд▓рдиреЗ рдХреА рдХреНрд╖рдорддрд╛ рдХреЗ рд╕рд╛рде (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЬрдм рдХрд░реНрдиреЗрд▓ рд╕рдВрд░рдЪрдирд╛ рд╕рдВрд╕реНрдХрд░рдг рд╕реЗ рдмрджрд▓рддреА рд╣реИ) рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд▓рд┐рдП)ред CO-RE рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЗ рдХрд░реНрдиреЗрд▓ рдХреЛ 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, рдЖрдЗрдП рдХрдИ (рдЕрдзрд┐рдХ рдпрд╛ рдХрдо рдЕрд░реНрдерд╣реАрди) рдкрд░реАрдХреНрд╖рдг рдХрд╛рд░реНрдпрдХреНрд░рдо рд▓рд┐рдЦреЗрдВ рдФрд░ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реЗрдВ рдХрд┐ рдпрд╣ рд╕рдм рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдпрд╣ рд╣рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЕрдиреБрднрд╛рдЧреЛрдВ рдореЗрдВ рдЕрдзрд┐рдХ рдЖрд╕рд╛рдиреА рд╕реЗ рд╕рдордЭрд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдЧрд╛ рдХрд┐ рдмреАрдкреАрдПрдл рдкреНрд░реЛрдЧреНрд░рд╛рдо рдореИрдкреНрд╕, рдХрд░реНрдиреЗрд▓ рд╣реЗрд▓реНрдкрд░реНрд╕, рдмреАрдЯреАрдПрдл рдЖрджрд┐ рдХреЗ рд╕рд╛рде рдХреИрд╕реЗ рдЗрдВрдЯрд░реИрдХреНрдЯ рдХрд░рддреЗ рд╣реИрдВред

рдЖрдорддреМрд░ рдкрд░ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ libbpf GitHub рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреЛ git рд╕рдмрдореЙрдбреНрдпреВрд▓ рдХреЗ рд░реВрдк рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ, рд╣рдо рднреА рдРрд╕рд╛ рд╣реА рдХрд░реЗрдВрдЧреЗ:

$ 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, рдФрд░ рдПрдХ рд╕рд╣рд╛рдпрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓рд┐рдЦреЗрдВ рдЬреЛ рдЗрд╕реЗ рдХрд░реНрдиреЗрд▓ рдореЗрдВ рд▓реЛрдб рдХрд░реЗрдЧрд╛ред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЕрдиреБрднрд╛рдЧреЛрдВ рдореЗрдВ рд╣рдо рдмреАрдкреАрдПрдл рдХрд╛рд░реНрдпрдХреНрд░рдо рдФрд░ рд╕рд╣рд╛рдпрдХ рдХрд╛рд░реНрдпрдХреНрд░рдо рджреЛрдиреЛрдВ рдХреА рдХреНрд╖рдорддрд╛рдУрдВ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░реЗрдВрдЧреЗред

рдЙрджрд╛рд╣рд░рдг: 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, рдЬреЛ рдЪрд░рд┐рддреНрд░ рдХреЛ рдИрдПрд▓рдПрдл рдСрдмреНрдЬреЗрдХреНрдЯ рдлрд╝рд╛рдЗрд▓ рдХреЗ рдЙрдкрдпреБрдХреНрдд рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рднреЗрдЬрддрд╛ рд╣реИред рд╣рдорд╛рд░рд╛ рдХрд╛рд░реНрдпрдХреНрд░рдо рдЕрдиреБрднрд╛рдЧ рдореЗрдВ рдирд┐рд╣рд┐рдд рд╣реИ xdp/simple, рдЬрд╣рд╛рдВ рд╕реНрд▓реИрд╢ рд╕реЗ рдкрд╣рд▓реЗ рд╣рдо рдкреНрд░реЛрдЧреНрд░рд╛рдо рдкреНрд░рдХрд╛рд░ BPF рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддреЗ рд╣реИрдВ - рдпрд╣ рд╡рд╣ рдХрдиреНрд╡реЗрдВрд╢рди рд╣реИ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ libbpf, рдЕрдиреБрднрд╛рдЧ рдирд╛рдо рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдпрд╣ рд╕реНрдЯрд╛рд░реНрдЯрдЕрдк рдкрд░ рд╕рд╣реА рдкреНрд░рдХрд╛рд░ рдХреЛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдЧрд╛ bpf(2). рдмреАрдкреАрдПрдл рдХрд╛рд░реНрдпрдХреНрд░рдо рд╣реА рд╣реИ 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 рд╣рдореЗрдВ рджреЛ рд╡рд┐рдХрд▓реНрдк рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ - рдирд┐рдореНрди-рд╕реНрддрд░реАрдп рдПрдкреАрдЖрдИ рдпрд╛ рдЙрдЪреНрдЪ-рд╕реНрддрд░реАрдп рдПрдкреАрдЖрдИ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред рд╣рдо рджреВрд╕рд░реЗ рд░рд╛рд╕реНрддреЗ рдкрд░ рдЬрд╛рдПрдВрдЧреЗ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рд╕реАрдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рдмреАрдкреАрдПрдл рдХрд╛рд░реНрдпрдХреНрд░рдореЛрдВ рдХреЛ рдЙрдирдХреЗ рдмрд╛рдж рдХреЗ рдЕрдзреНрдпрдпрди рдХреЗ рд▓рд┐рдП рдиреНрдпреВрдирддрдо рдкреНрд░рдпрд╛рд╕ рдХреЗ рд╕рд╛рде рдХреИрд╕реЗ рд▓рд┐рдЦрдирд╛, рд▓реЛрдб рдХрд░рдирд╛ рдФрд░ рдХрдиреЗрдХреНрдЯ рдХрд░рдирд╛ рд╣реИред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдореЗрдВ рдЙрд╕реА рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдкрдиреЗ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХреЗ рдмрд╛рдЗрдирд░реА рд╕реЗ "рдХрдВрдХрд╛рд▓" рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ bpftool - рдмреАрдкреАрдПрдл рджреБрдирд┐рдпрд╛ рдХрд╛ рд╕реНрд╡рд┐рд╕ рдЪрд╛рдХреВ (рдЬрд┐рд╕реЗ рд╢рд╛рдмреНрджрд┐рдХ рд░реВрдк рд╕реЗ рд▓рд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдбреИрдирд┐рдпрд▓ рдмреЛрд░реНрдХрдореИрди, рдмреАрдкреАрдПрдл рдХреЗ рд░рдЪрдирд╛рдХрд╛рд░реЛрдВ рдФрд░ рдЕрдиреБрд░рдХреНрд╖рдХреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ, рд╕реНрд╡рд┐рд╕ рд╣реИ):

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

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

рд╕рдЪ рдХрд╣реВрдБ рддреЛ, рд╣рдорд╛рд░рд╛ рд▓реЛрдбрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдо рддреБрдЪреНрдЫ рд╣реИ:

#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;
};

рд╣рдо рдпрд╣рд╛рдВ рдирд┐рдореНрди-рд╕реНрддрд░реАрдп рдПрдкреАрдЖрдИ рдХреЗ рдирд┐рд╢рд╛рди рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ: рд╕рдВрд░рдЪрдирд╛ 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

рдХреЛрдИ рдирдИ рдЪреАрдЬрд╝! рдкреНрд░реЛрдЧреНрд░рд╛рдо рдиреЗ рд╣рдорд╛рд░реА рд╕реА рд╕реНрд░реЛрдд рдлрд╝рд╛рдЗрд▓ рдХреЗ рдЯреБрдХрдбрд╝реЗ рдореБрджреНрд░рд┐рдд рдХрд┐рдПред рдпрд╣ рдкреБрд╕реНрддрдХрд╛рд▓рдп рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ libbpf, рдЬрд┐рд╕рдиреЗ рдмрд╛рдЗрдирд░реА рдореЗрдВ рдбрд┐рдмрдЧ рдЕрдиреБрднрд╛рдЧ рдкрд╛рдпрд╛, рдЗрд╕реЗ рдмреАрдЯреАрдПрдл рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд рдХрд┐рдпрд╛, рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд░реНрдиреЗрд▓ рдореЗрдВ рд▓реЛрдб рдХрд┐рдпрд╛ BPF_BTF_LOAD, рдФрд░ рдлрд┐рд░ рдХрдорд╛рдВрдб рдХреЗ рд╕рд╛рде рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓реЛрдб рдХрд░рддреЗ рд╕рдордп рдкрд░рд┐рдгрд╛рдореА рдлрд╝рд╛рдЗрд▓ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░реЗрдВ BPG_PROG_LOAD.

рдХрд░реНрдиреЗрд▓ рд╕рд╣рд╛рдпрдХ

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

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

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

BPF_CALL_0(bpf_get_smp_processor_id)
{
    return smp_processor_id();
}

рдмреАрдкреАрдПрдл рд╣реЗрд▓реНрдкрд░ рдлрд╝рдВрдХреНрд╢рди рдкрд░рд┐рднрд╛рд╖рд╛рдПрдБ рд▓рд┐рдирдХреНрд╕ рд╕рд┐рд╕реНрдЯрдо рдХреЙрд▓ рдкрд░рд┐рднрд╛рд╖рд╛рдУрдВ рдХреЗ рд╕рдорд╛рди рд╣реИрдВред рдпрд╣рд╛рдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдХреЛрдИ рддрд░реНрдХ рдирд╣реАрдВ рд╣реИред (рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдЬреЛ рдорд╛рди рд▓реАрдЬрд┐рдП, рддреАрди рддрд░реНрдХ рд▓реЗрддрд╛ рд╣реИ, рдореИрдХреНрд░реЛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ 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;
    ...
    }
}

рдирдП рдмреАрдкреАрдПрдл рдкреНрд░реЛрдЧреНрд░рд╛рдо рдкреНрд░рдХрд╛рд░ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ "рдкрд░рд┐рднрд╛рд╖рд┐рдд" рд╣реИрдВ include/linux/bpf_types.h рдореИрдХреНрд░реЛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ BPF_PROG_TYPE. рдЙрджреНрдзрд░рдгреЛрдВ рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдПрдХ рддрд╛рд░реНрдХрд┐рдХ рдкрд░рд┐рднрд╛рд╖рд╛ рд╣реИ, рдФрд░ рд╕реА рднрд╛рд╖рд╛ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдХрдВрдХреНрд░реАрдЯ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЗ рдкреВрд░реЗ рд╕реЗрдЯ рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рдЕрдиреНрдп рд╕реНрдерд╛рдиреЛрдВ рдкрд░ рд╣реЛрддреА рд╣реИред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рдлрд╝рд╛рдЗрд▓ рдореЗрдВ 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
};

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

рдЖрдЗрдП рдирдП рдХрд░реНрдиреЗрд▓ рд╣реЗрд▓реНрдкрд░ рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ рдФрд░ рдЬрд╛рдиреЗрдВ рдХрд┐ рдмреАрдкреАрдПрдл рдХреИрд╕реЗ рдкреИрд░рд╛рдореАрдЯрд░ рдкрд╛рд╕ рдХрд░рддрд╛ рд╣реИред рдЪрд▓рд┐рдП рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрддреЗ рд╣реИрдВ 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;
}

рд╣рдорд╛рд░рд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЙрд╕ CPU рдХрд╛ рдирдВрдмрд░ рдкреНрд░рд┐рдВрдЯ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕ рдкрд░ рд╡рд╣ рдЪрд▓ рд░рд╣рд╛ рд╣реИред рдЖрдЗрдП рдЗрд╕реЗ рд╕рдВрдХрд▓рд┐рдд рдХрд░реЗрдВ рдФрд░ рдХреЛрдб рджреЗрдЦреЗрдВ:

$ 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

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

рдмреАрдкреАрдПрдл рдХрд╛рд░реНрдпрдХреНрд░рдореЛрдВ рд╕реЗ рдорд╛рдирдЪрд┐рддреНрд░реЛрдВ рддрдХ рдкрд╣реБрдВрдЪ

рдЙрджрд╛рд╣рд░рдг: рдмреАрдкреАрдПрдл рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╕реЗ рдорд╛рдирдЪрд┐рддреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛

рдкрд┐рдЫрд▓реЗ рдЕрдиреБрднрд╛рдЧреЛрдВ рдореЗрдВ рд╣рдордиреЗ рд╕реАрдЦрд╛ рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реНрдерд╛рди рд╕реЗ рдорд╛рдирдЪрд┐рддреНрд░ рдХреИрд╕реЗ рдмрдирд╛рдПрдВ рдФрд░ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ, рдФрд░ рдЕрдм рдХрд░реНрдиреЗрд▓ рднрд╛рдЧ рдХреЛ рджреЗрдЦреЗрдВред рдЖрдЗрдП, рд╣рдореЗрд╢рд╛ рдХреА рддрд░рд╣, рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╕реЗ рд╢реБрд░реВ рдХрд░реЗрдВред рдЖрдЗрдП рдЕрдкрдиреЗ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦреЗрдВ 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 (рд╕реА рдореЗрдВ рд╣рдо рдЗрд╕ рддрд░рд╣ рдХреА рдПрдХ рд╕рд░рдгреА рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВрдЧреЗ u64 woo[8]). рдПрдХ рдХрд╛рд░реНрдпрдХреНрд░рдо рдореЗрдВ "xdp/simple" рд╣рдо рд╡рд░реНрддрдорд╛рди рдкреНрд░реЛрд╕реЗрд╕рд░ рдирдВрдмрд░ рдХреЛ рдПрдХ рд╡реЗрд░рд┐рдПрдмрд▓ рдореЗрдВ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ key рдФрд░ рдлрд┐рд░ рд╕рд╣рд╛рдпрдХ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ bpf_map_lookup_element рд╣рдореЗрдВ рд╕рд░рдгреА рдореЗрдВ рд╕рдВрдмрдВрдзрд┐рдд рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реВрдЪрдХ рдорд┐рд▓рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рд╣рдо рдПрдХ рд╕реЗ рдмрдврд╝рд╛рддреЗ рд╣реИрдВред рд░реВрд╕реА рдореЗрдВ рдЕрдиреБрд╡рд╛рджрд┐рдд: рд╣рдо рдЙрди рдЖрдБрдХрдбрд╝реЛрдВ рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рдирдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╕реАрдкреАрдпреВ рдиреЗ рдЖрдиреЗ рд╡рд╛рд▓реЗ рдкреИрдХреЗрдЯреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ред рдЖрдЗрдП рдкреНрд░реЛрдЧреНрд░рд╛рдо рдЪрд▓рд╛рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВ:

$ 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_mp_*.

рд░рд╣рд╕реНрдпрдордп рд╕реВрдЪрдХрд╛рдВрдХ

рддреЛ, рд╣рдо рдЬреИрд╕реЗ рдХреЙрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдмреАрдкреАрдПрдл рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╕реЗ рдорд╛рдирдЪрд┐рддреНрд░ рддрдХ рдкрд╣реБрдВрдЪ рд╕рдХрддреЗ рд╣реИрдВ

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_MAP_CREATE, рдФрд░ рдЖрдИрдбреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЦреЛрд▓рд╛ рдЧрдпрд╛ BPF_MAP_GET_FD_BY_ID.

рдХреБрд▓, рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп libbpf рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:

  • рд╕рдВрдХрд▓рди рдХреЗ рджреМрд░рд╛рди, рдорд╛рдирдЪрд┐рддреНрд░реЛрдВ рдХреЗ рд▓рд┐рдВрдХ рдХреЗ рд▓рд┐рдП рд╕реНрдерд╛рдирд╛рдВрддрд░рдг рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рд░рд┐рдХреЙрд░реНрдб рдмрдирд╛рдП рдЬрд╛рддреЗ рд╣реИрдВ
  • libbpf рдИрдПрд▓рдПрдл рдСрдмреНрдЬреЗрдХреНрдЯ рдмреБрдХ рдЦреЛрд▓рддрд╛ рд╣реИ, рд╕рднреА рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рдорд╛рдирдЪрд┐рддреНрд░ рдвреВрдВрдврддрд╛ рд╣реИ рдФрд░ рдЙрдирдХреЗ рд▓рд┐рдП рдлрд╝рд╛рдЗрд▓ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдмрдирд╛рддрд╛ рд╣реИ
  • рдлрд╝рд╛рдЗрд▓ рдбрд┐рд╕реНрдХреНрд░рд┐рдкреНрдЯрд░ рдХреЛ рдирд┐рд░реНрджреЗрд╢ рдХреЗ рднрд╛рдЧ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд░реНрдиреЗрд▓ рдореЗрдВ рд▓реЛрдб рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ 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

рдИрдПрд▓рдПрдл рдмрд╛рдЗрдирд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп рдбрд╛рдЙрдирд▓реЛрдб рдХрд░реЗрдВ libbpf рдЕрднреА рдФрд░ рднреА рдмрд╣реБрдд рдХреБрдЫ рдЪрд▓ рд░рд╣рд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдо рдЙрд╕ рдкрд░ рдЕрдиреНрдп рд▓реЗрдЦреЛрдВ рдореЗрдВ рдЪрд░реНрдЪрд╛ рдХрд░реЗрдВрдЧреЗред

libbpf рдХреЗ рдмрд┐рдирд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдФрд░ рдорд╛рдирдЪрд┐рддреНрд░ рд▓реЛрдб рд╣реЛ рд░рд╣реЗ рд╣реИрдВ

рдЬреИрд╕рд╛ рдХрд┐ рд╡рд╛рджрд╛ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдпрд╣рд╛рдВ рдЙрди рдкрд╛рдардХреЛрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрджрд╛рд╣рд░рдг рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдЬреЛ рдЬрд╛рдирдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рдорд╛рдирдЪрд┐рддреНрд░реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдмрд┐рдирд╛ рд╕рд╣рд╛рдпрддрд╛ рдХреЗ рдХреИрд╕реЗ рдмрдирд╛рдпрд╛ рдФрд░ рд▓реЛрдб рдХрд┐рдпрд╛ рдЬрд╛рдП libbpf. рдпрд╣ рддрдм рдЙрдкрдпреЛрдЧреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдЬрдм рдЖрдк рдРрд╕реЗ рд╡рд╛рддрд╛рд╡рд░рдг рдореЗрдВ рдХрд╛рдо рдХрд░ рд░рд╣реЗ рд╣реЛрдВ рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдЖрдк рдирд┐рд░реНрднрд░рддрд╛ рдирд╣реАрдВ рдмрдирд╛ рд╕рдХрддреЗ, рдпрд╛ рд╣рд░ рдмрд┐рдЯ рдХреЛ рд╕рд╣реЗрдЬ рдирд╣реАрдВ рд╕рдХрддреЗ, рдпрд╛ рдХреЛрдИ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓рд┐рдЦ рд░рд╣реЗ рд╣реЛрдВ ply, рдЬреЛ рддреБрд░рдВрдд рдмреАрдкреАрдПрдл рдмрд╛рдЗрдирд░реА рдХреЛрдб рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИред

рддрд░реНрдХ рдХрд╛ рдкрд╛рд▓рди рдХрд░рдирд╛ рдЖрд╕рд╛рди рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЗрди рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЕрдкрдирд╛ рдЙрджрд╛рд╣рд░рдг рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦреЗрдВрдЧреЗ 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 рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреА рдПрдХ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЗ рд░реВрдк рдореЗрдВ рд╣рдорд╛рд░реЗ рдмреАрдкреАрдПрдл рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреА рдкрд░рд┐рднрд╛рд╖рд╛ рд╣реИ 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. рдЬрд┐рди рд▓реЛрдЧреЛрдВ рдиреЗ рдмреАрдкреАрдПрдл рдФрд░ рдПрдХреНрд╕рдбреАрдкреА рдмрдирд╛рдпрд╛, рд╡реЗ рдСрдирд▓рд╛рдЗрди рд▓рд┐рдирдХреНрд╕ рд╕рдореБрджрд╛рдп рд╕реЗ рдереЗ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдЙрдиреНрд╣реЛрдВрдиреЗ рдЕрдкрдиреЗ рд╕рдмрд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд▓рд┐рдирдХреНрд╕ рд╕рдореБрджрд╛рдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ (рд▓реЗрдХрд┐рди рдРрд╕рд╛ рдирд╣реАрдВ рдХрд┐рдпрд╛) рд╕рд╛рдзрд╛рд░рдг рд▓реЛрдЧ) рдХрд░реНрдиреЗрд▓ рдХреЗ рд╕рд╛рде рдЗрдВрдЯрд░реИрдХреНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрдВрдЯрд░рдлрд╝реЗрд╕: рдиреЗрдЯрд▓рд┐рдВрдХ рд╕реЙрдХреЗрдЯ, рдпрд╣ рд╕рднреА рджреЗрдЦреЗрдВ RFC3549. рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рд╕рд░рд▓ рддрд░реАрдХрд╛ 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 рд╣рдордиреЗ рдкреНрд░рдХрд╛рд░ рдХреА рдЬрд╛рдирдХрд╛рд░реА (рдмреАрдЯреАрдПрдл) рд▓реЛрдб рдирд╣реАрдВ рдХреАред рд▓реЗрдХрд┐рди рд╣рдо рдЕрдЧрд▓реА рдмрд╛рд░ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдмрд╛рдд рдХрд░реЗрдВрдЧреЗред

рд╡рд┐рдХрд╛рд╕ рдЙрдкрдХрд░рдг

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

рд╕рд╛рдорд╛рдиреНрдпрддрдпрд╛, рдЖрдкрдХреЛ BPF рдкреНрд░реЛрдЧреНрд░рд╛рдо рд╡рд┐рдХрд╕рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рд╡рд┐рд╢реЗрд╖ рдЪреАрдЬрд╝ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ - BPF рдХрд┐рд╕реА рднреА рдЕрдЪреНрдЫреЗ рд╡рд┐рддрд░рдг рдХрд░реНрдиреЗрд▓ рдкрд░ рдЪрд▓рддрд╛ рд╣реИ, рдФрд░ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ clang, рдЬрд┐рд╕реЗ рдкреИрдХреЗрдЬ рд╕реЗ рдЖрдкреВрд░реНрддрд┐ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рдХрд┐ BPF рд╡рд┐рдХрд╛рд╕ рдХреЗ рдЕрдзреАрди рд╣реИ, рдХрд░реНрдиреЗрд▓ рдФрд░ рдЙрдкрдХрд░рдг рд▓рдЧрд╛рддрд╛рд░ рдмрджрд▓ рд░рд╣реЗ рд╣реИрдВ, рдпрджрд┐ рдЖрдк 2019 рд╕реЗ рдкреБрд░рд╛рдиреЗ рдЬрдорд╛рдиреЗ рдХреЗ рддрд░реАрдХреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ BPF рдкреНрд░реЛрдЧреНрд░рд╛рдо рдирд╣реАрдВ рд▓рд┐рдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ рд╕рдВрдХрд▓рди рдХрд░рдирд╛ рд╣реЛрдЧрд╛

  • llvm/clang
  • pahole
  • рдЗрд╕рдХрд╛ рдореВрд▓
  • bpftool

(рд╕рдВрджрд░реНрдн рдХреЗ рд▓рд┐рдП, рдпрд╣ рдЕрдиреБрднрд╛рдЧ рдФрд░ рд▓реЗрдЦ рдХреЗ рд╕рднреА рдЙрджрд╛рд╣рд░рдг рдбреЗрдмрд┐рдпрди 10 рдкрд░ рдЪрд▓рд╛рдП рдЧрдП рдереЗред)

рдПрд▓рдПрд▓рд╡реАрдПрдо/рдХреНрд▓реИрдВрдЧ

рдмреАрдкреАрдПрдл рдПрд▓рдПрд▓рд╡реАрдПрдо рдХреЗ рд╕рд╛рде рдорд┐рддреНрд░рддрд╛рдкреВрд░реНрдг рд╣реИ рдФрд░, рд╣рд╛рд▓рд╛рдВрдХрд┐ рд╣рд╛рд▓ рд╣реА рдореЗрдВ рдмреАрдкреАрдПрдл рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдпрдХреНрд░рдореЛрдВ рдХреЛ рдЬреАрд╕реАрд╕реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдВрдХрд▓рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд╕рднреА рдореМрдЬреВрджрд╛ рд╡рд┐рдХрд╛рд╕ рдПрд▓рдПрд▓рд╡реАрдПрдо рдХреЗ рд▓рд┐рдП рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рд╡рд░реНрддрдорд╛рди рд╕рдВрд╕реНрдХрд░рдг рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░реЗрдВрдЧреЗ clang рдЧрд┐рдЯ рд╕реЗ:

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

рдмреАрдкреАрдПрдл рдХреЗ рд╕рд╛рде рдкреНрд░рдпреЛрдЧ рдХреЗ рд▓рд┐рдП рдЧреБрдард▓реА

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

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

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

рдЙрдкрд░реЛрдХреНрдд рдХрд░реНрдиреЗрд▓ рдореЗрдВ рд╕реЗ рдПрдХ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░реЗрдВ:

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

рдЗрд╕ рд▓реЗрдЦрди рдХреЗ рд╕рдордп bpftool рдХреЗрд╡рд▓ рдЖрд░рдПрдЪрдИрдПрд▓, рдлреЗрдбреЛрд░рд╛ рдФрд░ рдЙрдмрдВрдЯреВ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рдЖрддрд╛ рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рджреЗрдЦреЗрдВ, рдпрд╣ рдзрд╛рдЧрд╛, рдЬреЛ рдкреИрдХреЗрдЬрд┐рдВрдЧ рдХреА рдЕрдзреВрд░реА рдХрд╣рд╛рдиреА рдмрддрд╛рддрд╛ рд╣реИ 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
...

рдЬреЛ рджрд┐рдЦрд╛рдПрдЧрд╛ рдХрд┐ рдЖрдкрдХреЗ рдХрд░реНрдиреЗрд▓ рдореЗрдВ рдХреМрди рд╕реА рдмреАрдкреАрдПрдл рд╕реБрд╡рд┐рдзрд╛рдПрдБ рд╕рдХреНрд╖рдо рд╣реИрдВред

рд╡реИрд╕реЗ, рдкрд┐рдЫрд▓реА рдХрдорд╛рдВрдб рдХреЛ рдЗрд╕ рддрд░рд╣ рдЪрд▓рд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ

# bpftool f p k

рдпрд╣ рдкреИрдХреЗрдЬ рд╕реЗ рдЙрдкрдпреЛрдЧрд┐рддрд╛рдУрдВ рдХреЗ рдЕрдиреБрд░реВрдк рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ iproute2, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо рдХрд╣рд╛рдВ рдХрд╣ рд╕рдХрддреЗ рд╣реИрдВ ip a s eth0 рдХреЗ рдмрджрд▓реЗ ip addr show dev eth0.

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

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

рдореИрдВ рдпрд╣ рдиреЛрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ рдХрд┐, рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рддрдХрдиреАрдХ рдЗрддрдиреА рд▓реЛрдХрдкреНрд░рд┐рдп рд╣реЛ рдЧрдИ рд╣реИ рдХреНрдпреЛрдВрдХрд┐, рдПрдХ рдУрд░, рдпрд╣ рд╣реЛ рд╕рдХрддреА рд╣реИ рдЦреЗрд▓рдирд╛ (рдПрдХ рдорд╢реАрди рдХреА рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреЛ рдХрдореЛрдмреЗрд╢ рдПрдХ рд╢рд╛рдо рдореЗрдВ рд╕рдордЭрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ), рдФрд░ рджреВрд╕рд░реА рдУрд░, рдЙрди рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдиреНрд╣реЗрдВ рдЗрд╕рдХреЗ рдкреНрд░рдХрдЯ рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ (рдЦреВрдмрд╕реВрд░рддреА рд╕реЗ) рд╣рд▓ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рдерд╛ред рдпреЗ рджреЛрдиреЛрдВ рдШрдЯрдХ рдорд┐рд▓рдХрд░ рд▓реЛрдЧреЛрдВ рдХреЛ рдкреНрд░рдпреЛрдЧ рдХрд░рдиреЗ рдФрд░ рд╕рдкрдиреЗ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рд╕реЗ рдЕрдзрд┐рдХ рд╕реЗ рдЕрдзрд┐рдХ рдирд╡реАрди рд╕рдорд╛рдзрд╛рди рд╕рд╛рдордиреЗ рдЖрддреЗ рд╣реИрдВред

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

рдЗрд╕ рд╢реГрдВрдЦрд▓рд╛ рдореЗрдВ рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ

  1. рдЫреЛрдЯреЛрдВ рдХреЗ рд▓рд┐рдП рдмреАрдкреАрдПрдл, рднрд╛рдЧ рд╢реВрдиреНрдп: рдХреНрд▓рд╛рд╕рд┐рдХ рдмреАрдкреАрдПрдл

рд▓рд┐рдВрдХ

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

  2. рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг/рдиреЗрдЯрд╡рд░реНрдХрд┐рдВрдЧ/рдлрд╝рд┐рд▓реНрдЯрд░.txt - рдХреНрд▓рд╛рд╕рд┐рдХ рдФрд░ рдлрд┐рд░ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдмреАрдкреАрдПрдл рдХреЗ рд▓рд┐рдП рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рдХреЗ рд╕рд╛рде рдореВрд▓ рдлрд╝рд╛рдЗрд▓ред рдпрджрд┐ рдЖрдк рдЕрд╕реЗрдВрдмрд▓реА рднрд╛рд╖рд╛ рдФрд░ рддрдХрдиреАрдХреА рд╡рд╛рд╕реНрддреБрд╢рд┐рд▓реНрдк рд╡рд┐рд╡рд░рдг рдореЗрдВ рдЧрд╣рд░рд╛рдИ рд╕реЗ рдЬрд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рддреЛ рдПрдХ рдЕрдЪреНрдЫрд╛ рд▓реЗрдЦ рдкрдврд╝реЗрдВред

  3. рдлреЗрд╕рдмреБрдХ рд╕реЗ рдмреАрдкреАрдПрдл рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмреНрд▓реЙрдЧ. рдЗрд╕реЗ рд╢рд╛рдпрдж рд╣реА рдХрднреА рдЕрджреНрдпрддрди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЙрдкрдпреБрдХреНрдд рд░реВрдк рд╕реЗ, рдЬреИрд╕рд╛ рдХрд┐ рдПрд▓реЗрдХреНрд╕реА рд╕реНрдЯрд╛рд░реЛрд╡реЛрдЗрдЯреЛрд╡ (рдИрдмреАрдкреАрдПрдл рдХреЗ рд▓реЗрдЦрдХ) рдФрд░ рдПрдВрдбреНрд░реА рдирд╛рдХреНрд░рд┐рдЗрдХреЛ - (рдЕрдиреБрд░рдХреНрд╖рдХ) рдиреЗ рд╡рд╣рд╛рдВ рд▓рд┐рдЦрд╛ рд╣реИ libbpf).

  4. bpftool рдХрд╛ рд░рд╣рд╕реНрдп. bpftool рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдФрд░ рд░рд╣рд╕реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдХреНрд╡реЗрдВрдЯрд┐рди рдореЛрдиреЗрдЯ рдХрд╛ рдПрдХ рдордиреЛрд░рдВрдЬрдХ рдЯреНрд╡рд┐рдЯрд░ рдереНрд░реЗрдбред

  5. рдмреАрдкреАрдПрдл рдореЗрдВ рдЧреЛрддрд╛ рд▓рдЧрд╛рдПрдБ: рдкрдарди рд╕рд╛рдордЧреНрд░реА рдХреА рдПрдХ рд╕реВрдЪреА. рдХреНрд╡реЗрдВрдЯрд┐рди рдореЛрдиреЗрдЯ рд╕реЗ рдмреАрдкреАрдПрдл рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рдХреЗ рд▓рд┐рдВрдХ рдХреА рдПрдХ рд╡рд┐рд╢рд╛рд▓ (рдФрд░ рдЕрднреА рднреА рдмрдиреА рд╣реБрдИ) рд╕реВрдЪреАред

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

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