рд╕рд╛рдирд╛рд╣рд░реВрдХрд╛ рд▓рд╛рдЧрд┐ BPF, рднрд╛рдЧ рдПрдХ: рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд BPF

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

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

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

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

BPF рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреЛ рдкрд░рд┐рдЪрдпред рдкрд╣рд┐рд▓реЗ, рд╣рд╛рдореА BPF рд╡рд╛рд╕реНрддреБрдХрд▓рд╛рдХреЛ рдкрдХреНрд╖реАрдХреЛ рдЖрдБрдЦрд╛рдХреЛ рджреГрд╢реНрдп рд▓рд┐рдиреЗрдЫреМрдВ рд░ рдореБрдЦреНрдп рдШрдЯрдХрд╣рд░реВ рд░реВрдкрд░реЗрдЦрд╛ рдЧрд░реНрдиреЗрдЫреМрдВред

BPF рднрд░реНрдЪреБрдЕрд▓ рдореЗрд╕рд┐рдирдХреЛ рджрд░реНрддрд╛ рд░ рдЖрджреЗрд╢ рдкреНрд░рдгрд╛рд▓реАред рдкрд╣рд┐рд▓реЗ рдиреИ рд╕рдордЧреНрд░ рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреЛ рдПрдХ рд╡рд┐рдЪрд╛рд░ рдЫ, рд╣рд╛рдореА BPF рднрд░реНрдЪреБрдЕрд▓ рдореЗрд╕рд┐рди рдХреЛ рд╕рдВрд░рдЪрдирд╛ рд╡рд░реНрдгрди рдЧрд░реНрдиреЗрдЫреМрдВред

BPF рд╡рд╕реНрддреБрд╣рд░реВрдХреЛ рдЬреАрд╡рди рдЪрдХреНрд░, bpffs рдлрд╛рдЗрд▓ рдкреНрд░рдгрд╛рд▓реАред рдпрд╕ рдЦрдгреНрдбрдорд╛, рд╣рд╛рдореА BPF рд╡рд╕реНрддреБрд╣рд░реВ - рдХрд╛рд░реНрдпрдХреНрд░рдорд╣рд░реВ рд░ рдирдХреНрд╕рд╛рд╣рд░реВрдХреЛ рдЬреАрд╡рди рдЪрдХреНрд░рд▓рд╛рдИ рдирдЬрд┐рдХрдмрд╛рдЯ рд╣реЗрд░реНрдиреЗрдЫреМрдВред

Bpf рдкреНрд░рдгрд╛рд▓реА рдХрд▓ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рд╡рд╕реНрддреБрд╣рд░реВ рдкреНрд░рдмрдиреНрдз рдЧрд░реНрдиреБрд╣реЛрд╕реНред рдкрд╣рд┐рд▓реЗ рдиреИ рд╕реНрдерд╛рдирдорд╛ рд░рд╣реЗрдХреЛ рдкреНрд░рдгрд╛рд▓реАрдХреЛ рдХреЗрд╣реА рдмреБрдЭрд╛рдЗрдХреЛ рд╕рд╛рде, рд╣рд╛рдореА рдЕрдиреНрддрдорд╛ рд╡рд┐рд╢реЗрд╖ рдкреНрд░рдгрд╛рд▓реА рдХрд▓ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛ рд╕реНрдкреЗрд╕рдмрд╛рдЯ рд╡рд╕реНрддреБрд╣рд░реВ рдХрд╕рд░реА рд╕рд┐рд░реНрдЬрдирд╛ рд░ рд╣реЗрд░рдлреЗрд░ рдЧрд░реНрдиреЗ рднрдиреЗрд░ рд╣реЗрд░реНрдиреЗрдЫреМрдВ - bpf(2).

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

рдХрд░реНрдиреЗрд▓ рд╕рд╣рдпреЛрдЧреАрд╣рд░реВред рдпрд╣рд╛рдБ рд╣рд╛рдореА BPF рдХрд╛рд░реНрдпрдХреНрд░рдорд╣рд░реВрд▓реЗ рдХрд░реНрдиреЗрд▓ рд╕рд╣рд╛рдпрдХ рдХрд╛рд░реНрдпрд╣рд░реВ рдХрд╕рд░реА рдкрд╣реБрдБрдЪ рдЧрд░реНрди рд╕рдХреНрдЫ рднрдиреНрдиреЗ рдХреБрд░рд╛ рд╕рд┐рдХреНрдиреЗрдЫреМрдВ - рдПрдЙрдЯрд╛ рдЙрдкрдХрд░рдг рдЬрд╕рд▓реЗ рдирдХреНрд╕рд╛рдХреЛ рд╕рд╛рдердорд╛, рдХреНрд▓рд╛рд╕рд┐рдХрдХреЛ рддреБрд▓рдирд╛рдорд╛ рдирдпрд╛рдБ BPF рдХреЛ рдХреНрд╖рдорддрд╛рд╣рд░реВрд▓рд╛рдИ рдореМрд▓рд┐рдХ рд░реВрдкрдорд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдЧрд░реНрдЫред

BPF рдХрд╛рд░реНрдпрдХреНрд░рдорд╣рд░реВрдмрд╛рдЯ рдирдХреНрд╕рд╛рд╣рд░реВрдорд╛ рдкрд╣реБрдБрдЪред рдпрд╕ рдмрд┐рдиреНрджреБрдорд╛, рд╣рд╛рдореА рдирдХреНрд╕рд╛ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреЗ рдХрд╛рд░реНрдпрдХреНрд░рдорд╣рд░реВ рдХрд╕рд░реА рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрди рд╕рдХреНрдЫреМрдВ рднрдиреЗрд░ рдареНрдпрд╛рдХреНрдХреИ рдмреБрдЭреНрдирдХреЛ рд▓рд╛рдЧрд┐ рдкрд░реНрдпрд╛рдкреНрдд рдерд╛рд╣рд╛ рдкрд╛рдЙрдиреЗрдЫреМрдВред рд░ рдорд╣рд╛рдиреН рд░ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдкреНрд░рдорд╛рдгрдХрд░реНрддрд╛рдорд╛ рджреНрд░реБрдд рдЭрд▓рдХ рдкрдирд┐ рд▓рд┐рдФрдВред

рд╡рд┐рдХрд╛рд╕ рдЙрдкрдХрд░рдгрд╣рд░реВред рдкреНрд░рдпреЛрдЧрд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐ рдЖрд╡рд╢реНрдпрдХ рдЙрдкрдпреЛрдЧрд┐рддрд╛рд╣рд░реВ рд░ рдХрд░реНрдиреЗрд▓ рдХрд╕рд░реА рдЬрдореНрдорд╛ рдЧрд░реНрдиреЗ рднрдиреНрдиреЗ рдмрд╛рд░реЗ рдорджреНрджрдд рдЦрдгреНрдбред

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

BPF рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреЛ рдкрд░рд┐рдЪрдп

рд╣рд╛рдореАрд▓реЗ BPF рд╡рд╛рд╕реНрддреБрдХрд▓рд╛рд▓рд╛рдИ рд╡рд┐рдЪрд╛рд░ рдЧрд░реНрди рд╕реБрд░реБ рдЧрд░реНрдиреБ рдЕрдШрд┐, рд╣рд╛рдореА рдЕрдиреНрддрд┐рдо рдкрдЯрдХ (рдУрд╣) рд▓рд╛рдИ рд╕рдиреНрджрд░реНрдн рдЧрд░реНрдиреЗрдЫреМрдВ рдХреНрд▓рд╛рд╕рд┐рдХ BPF, рдЬреБрди RISC рдореЗрд╕рд┐рдирд╣рд░реВрдХреЛ рдЖрдЧрдордирдХреЛ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рдХреЛ рд░реВрдкрдорд╛ рд╡рд┐рдХрд╕рд┐рдд рдЧрд░рд┐рдПрдХреЛ рдерд┐рдпреЛ рд░ рдХреБрд╢рд▓ рдкреНрдпрд╛рдХреЗрдЯ рдлрд┐рд▓реНрдЯрд░рд┐рдЩрдХреЛ рд╕рдорд╕реНрдпрд╛ рд╕рдорд╛рдзрд╛рди рдЧрд░реНтАНрдпреЛред рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдпрддрд┐ рд╕рдлрд▓ рднрдпреЛ рдХрд┐, рдмрд░реНрдХрд▓реЗ UNIX рдорд╛ рдбреНрдпрд╛рд╕рд┐рдЩ рдирдмреНрдмреЗ рдХреЛ рджрд╢рдХ рдорд╛ рдЬрдиреНрдо рднрдПрдХреЛ рдерд┐рдпреЛ, рдпреЛ рдзреЗрд░реИ рдЕрд╡рд╕реНрдерд┐рдд рдЕрдкрд░реЗрдЯрд┐рдЩ рд╕рд┐рд╕реНрдЯрдо рдорд╛ рдкреЛрд░реНрдЯ рдЧрд░рд┐рдПрдХреЛ рдерд┐рдпреЛ, рдкрд╛рдЧрд▓ рдмреАрд╕ рдХреЛ рджрд╢рдХ рдорд╛ рдмрд╛рдБрдЪреЗ рд░ рдЕрдЭреИ рдкрдирд┐ рдирдпрд╛рдБ рдЕрдиреБрдкреНрд░рдпреЛрдЧрд╣рд░реБ рдлреЗрд▓рд╛ рдкрд╛рд░реНрджреИ рдЫред

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

рд╣рд╛рд╕реНрдпрд╛рд╕реНрдкрдж рдЪрд┐рддреНрд░рд╣рд░реБ

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

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

рд╕рд╛рдирд╛рд╣рд░реВрдХрд╛ рд▓рд╛рдЧрд┐ BPF, рднрд╛рдЧ рдПрдХ: рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд BPF

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

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

рд╕рд╛рдирд╛рд╣рд░реВрдХрд╛ рд▓рд╛рдЧрд┐ BPF, рднрд╛рдЧ рдПрдХ: рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд BPF

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

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

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

рдкреНрд░рдгрд╛рд▓реА рдХрд▓ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛рд╣рд░реВрдмрд╛рдЯ рдирдХреНрд╕рд╛ рдкрд╣реБрдБрдЪ рдЧрд░рд┐рдиреНрдЫ bpf(2), рд░ рд╕рд╣рд╛рдпрдХ рдкреНрд░рдХрд╛рд░реНрдпрд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдХрд░реНрдиреЗрд▓рдорд╛ рдЪрд▓рд┐рд░рд╣реЗрдХреЛ BPF рдХрд╛рд░реНрдпрдХреНрд░рдорд╣рд░реВрдмрд╛рдЯред рдпрд╕рдмрд╛рд╣реЗрдХ, рд╕рд╣рдпреЛрдЧреАрд╣рд░реВ рдирдХреНрд╕рд╛рд╣рд░реВрд╕рдБрдЧ рдХрд╛рдо рдЧрд░реНрди рдорд╛рддреНрд░ рд╣реЛрдЗрди, рдЕрдиреНрдп рдХрд░реНрдиреЗрд▓ рдХреНрд╖рдорддрд╛рд╣рд░реВрдорд╛ рдкрд╣реБрдБрдЪ рдЧрд░реНрди рдкрдирд┐ рдЕрд╡рд╕реНрдерд┐рдд рдЫрдиреНред рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐, BPF рдХрд╛рд░реНрдпрдХреНрд░рдорд╣рд░реВрд▓реЗ рдЕрдиреНрдп рдЗрдиреНрдЯрд░рдлреЗрд╕рдорд╛ рдкреНрдпрд╛рдХреЗрдЯрд╣рд░реВ рдлрд░реНрд╡рд╛рд░реНрдб рдЧрд░реНрди, perf рдШрдЯрдирд╛рд╣рд░реВ рдЙрддреНрдкрдиреНрди рдЧрд░реНрди, рдХрд░реНрдиреЗрд▓ рд╕рдВрд░рдЪрдирд╛рд╣рд░реВ рдкрд╣реБрдБрдЪ рдЧрд░реНрди, рд░ рдпрд╕реНрддреИ рдЕрдиреНрдп рдХрд╛рд░реНрдпрд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рд╕рдХреНрдЫред

рд╕рд╛рдирд╛рд╣рд░реВрдХрд╛ рд▓рд╛рдЧрд┐ BPF, рднрд╛рдЧ рдПрдХ: рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд BPF

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

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

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

рд▓реЗрдЦрдХреЛ рд╕рд┐рдВрд╣рд╛рд╡рд▓реЛрдХрди рднрд╛рдЧ рдпрд╣рд╛рдБ рд╕рдорд╛рдкреНрдд рдЧрд░реМрдВ рд░ рднрд░реНрдЪреБрдЕрд▓ рдореЗрд╕рд┐рди рд░ BPF рдЗрдХреЛрд╕рд┐рд╕реНрдЯрдорд▓рд╛рдИ рдердк рд╡рд┐рд╕реНрддрд╛рд░рдорд╛ рд╣реЗрд░реМрдВред

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

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

BPF рднрд░реНрдЪреБрдЕрд▓ рдореЗрд╕рд┐рди рджрд░реНрддрд╛ рд░ рдирд┐рд░реНрджреЗрд╢рди рдкреНрд░рдгрд╛рд▓реА

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

BPF рд╕рдБрдЧ рдПрдШрд╛рд░ рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛-рдкрд╣реБрдБрдЪрдпреЛрдЧреНрдп 64-рдмрд┐рдЯ рджрд░реНрддрд╛рд╣рд░реВ рдЫрдиреН r0-r10 рд░ рдПрдХ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд╛рдЙрдиреНрдЯрд░ред рджрд░реНрддрд╛ рдЧрд░реНрдиреБрд╣реЛрд╕реН r10 рдлреНрд░реЗрдо рд╕реВрдЪрдХ рд╕рдорд╛рд╡реЗрд╢ рдЫ рд░ рдкрдвреНрди рдорд╛рддреНрд░ рдЫред рдХрд╛рд░реНрдпрдХреНрд░рдорд╣рд░реВрд╕рдБрдЧ рд░рдирдЯрд╛рдЗрдордорд╛ 512-рдмрд╛рдЗрдЯ рд╕реНрдЯреНрдпрд╛рдХ рд░ рдирдХреНрд╕рд╛рдХреЛ рд░реВрдкрдорд╛ рд╕рд╛рдЭрд╛ рдореЗрдореЛрд░реАрдХреЛ рдЕрд╕реАрдорд┐рдд рдорд╛рддреНрд░рд╛рдорд╛ рдкрд╣реБрдБрдЪ рдЫред

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

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

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

рд░реЗрдЬрд┐рд╖реНрдЯрд░ рдЧрд░реНрдиреБрд╣реЛрд╕реН r0 рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрдирдХреЛ рдирддрд┐рдЬрд╛ рд░ рджрд░реНрддрд╛рдорд╛ рдлрд░реНрдХрд╛рдЙрди рдкрдирд┐ рдкреНрд░рдпреЛрдЧ рдЧрд░рд┐рдиреНрдЫ r1 рдХрд╛рд░реНрдпрдХреНрд░рдорд▓рд╛рдИ рд╕рдиреНрджрд░реНрднрдорд╛ рдПрдХ рд╕реВрдЪрдХ рдкрд╛рд░рд┐рдд рдЧрд░рд┐рдПрдХреЛ рдЫ - рдХрд╛рд░реНрдпрдХреНрд░рдордХреЛ рдкреНрд░рдХрд╛рд░рдорд╛ рдирд┐рд░реНрднрд░ рдЧрд░реНрджреИ, рдпреЛ рд╣реБрди рд╕рдХреНрдЫ, рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐, рд╕рдВрд░рдЪрдирд╛ struct xdp_md (XDP рдХреЛ рд▓рд╛рдЧрд┐) рд╡рд╛ рд╕рдВрд░рдЪрдирд╛ struct __sk_buff (рднрд┐рдиреНрди рдиреЗрдЯрд╡рд░реНрдХ рдХрд╛рд░реНрдпрдХреНрд░рдорд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐) рд╡рд╛ рд╕рдВрд░рдЪрдирд╛ struct pt_regs (рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░рдХрд╛ рдЯреНрд░реЗрд╕рд┐рдЩ рдХрд╛рд░реНрдпрдХреНрд░рдорд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐), рдЖрджрд┐ред

рддреНрдпрд╕реЛрднрдП, рд╣рд╛рдореАрд╕рдБрдЧ рдирдХреНрд╕рд╛рдХреЛ рд░реВрдкрдорд╛ рджрд░реНрддрд╛рд╣рд░реВ, рдХрд░реНрдиреЗрд▓ рд╕рд╣рдпреЛрдЧреАрд╣рд░реВ, рд╕реНрдЯреНрдпрд╛рдХ, рдПрдХ рд╕рдиреНрджрд░реНрдн рд╕реВрдЪрдХ рд░ рд╕рд╛рдЭрд╛ рдореЗрдореЛрд░реАрдХреЛ рд╕реЗрдЯ рдерд┐рдпреЛред рдпреЛ рд╕рдмреИ рдпрд╛рддреНрд░рд╛ рдорд╛ рдмрд┐рд▓реНрдХреБрд▓ рдЖрд╡рд╢реНрдпрдХ рдЫ рднрдиреНрдиреЗ рдЫреИрди, рддрд░ ...

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

рд╕рд╛рдирд╛рд╣рд░реВрдХрд╛ рд▓рд╛рдЧрд┐ BPF, рднрд╛рдЧ рдПрдХ: рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд BPF

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

рд╕рд╛рдирд╛рд╣рд░реВрдХрд╛ рд▓рд╛рдЧрд┐ BPF, рднрд╛рдЧ рдПрдХ: рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд BPF

рдирд┐рд░реНрджреЗрд╢рди рдХрдХреНрд╖рд╛рд╣рд░реВ 0, 1, 2, 3 рд▓реЗ рдореЗрдореЛрд░реАрд╕рдБрдЧ рдХрд╛рдо рдЧрд░реНрдиреЗ рдЖрджреЗрд╢рд╣рд░реВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдЧрд░реНрджрдЫред рддрд┐рдиреАрд╣рд░реВрд▓реЗ рднрдирд┐рдиреНрдЫ, BPF_LD, BPF_LDX, BPF_ST, BPF_STX, рдХреНрд░рдорд╢рдГред рдХрдХреНрд╖рд╛ рек, рен (BPF_ALU, BPF_ALU64ALU рдирд┐рд░реНрджреЗрд╢рдирд╣рд░реВрдХреЛ рд╕реЗрдЯ рдЧрдарди рдЧрд░реНрдиреБрд╣реЛрд╕реНред рдХрдХреНрд╖рд╛ рел, рем (BPF_JMP, BPF_JMP32) рдЬрдореНрдк рдирд┐рд░реНрджреЗрд╢рдирд╣рд░реВ рд╕рдорд╛рд╡реЗрд╢ рдЧрд░реНрджрдЫред

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

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

рдЙрджрд╛рд╣рд░рдг: рддрдкрд╛рдИрдХреЛ рдЯрд╛рдЙрдХреЛрдорд╛ BPF рдбрд┐рд╕рд╕реЗрдореНрдмрд▓ рдЧрд░реНрджреИ

рдПрдЙрдЯрд╛ рдЙрджрд╛рд╣рд░рдг рд╣реЗрд░реМрдВ рдЬрд╕рдорд╛ рд╣рд╛рдореА рдПрдЙрдЯрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдХрдореНрдкрд╛рдЗрд▓ рдЧрд░реНрдЫреМрдВ readelf-example.c рд░ рдирддрд┐рдЬрд╛ рдмрд╛рдЗрдирд░реА рд╣реЗрд░реНрдиреБрд╣реЛрд╕реНред рд╣рд╛рдореА рдореВрд▓ рд╕рд╛рдордЧреНрд░реА рдкреНрд░рдХрдЯ рдЧрд░реНрдиреЗрдЫреМрдВ readelf-example.c рддрд▓, рд╣рд╛рдореАрд▓реЗ рдмрд╛рдЗрдирд░реА рдХреЛрдбрд╣рд░реВрдмрд╛рдЯ рдпрд╕рдХреЛ рддрд░реНрдХ рдкреБрдирд░реНрд╕реНрдерд╛рдкрдирд╛ рдЧрд░реЗрдкрдЫрд┐:

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

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

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

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

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

рдЕрдкрд░реЗрд╢рди b рд╡рд░реНрдЧ ALU64 рд╣реЛ BPF_MOVред рдпрд╕рд▓реЗ рдЧрдиреНрддрд╡реНрдп рджрд░реНрддрд╛рдорд╛ рдорд╛рди рддреЛрдХреНрдЫред рдпрджрд┐ рдмрд┐рдЯ рд╕реЗрдЯ рдЧрд░рд┐рдПрдХреЛ рдЫ s (рд╕реНрд░реЛрдд), рддреНрдпрд╕рдкрдЫрд┐ рдорд╛рди рд╕реНрд░реЛрдд рджрд░реНрддрд╛рдмрд╛рдЯ рд▓рд┐рдЗрдиреНрдЫ, рд░ рдпрджрд┐, рд╣рд╛рдореНрд░реЛ рдорд╛рдорд▓рд╛рдорд╛, рдпреЛ рд╕реЗрдЯ рдЧрд░рд┐рдПрдХреЛ рдЫреИрди рднрдиреЗ, рдорд╛рди рдлрд┐рд▓реНрдбрдмрд╛рдЯ рд▓рд┐рдЗрдиреНрдЫред Immред рддреНрдпрд╕реИрд▓реЗ рдкрд╣рд┐рд▓реЛ рд░ рддреЗрд╕реНрд░реЛ рдирд┐рд░реНрджреЗрд╢рдирдорд╛ рд╣рд╛рдореА рдЕрдкрд░реЗрд╢рди рдЧрд░реНрдЫреМрдВ r0 = Immред рдпрд╕рдмрд╛рд╣реЗрдХ, JMP рдХрдХреНрд╖рд╛ рез рд╕рдЮреНрдЪрд╛рд▓рди рдЫ BPF_JEQ (рдпрджрд┐ рдмрд░рд╛рдмрд░ рдЫ рднрдиреЗ)ред рд╣рд╛рдореНрд░реЛ рдорд╛рдорд▓рд╛ рдорд╛, рдмрд┐рдЯ рджреЗрдЦрд┐ S рд╢реВрдиреНрдп рдЫ, рдпрд╕рд▓реЗ рд╕реНрд░реЛрдд рджрд░реНрддрд╛рдХреЛ рдорд╛рдирд▓рд╛рдИ рдХреНрд╖реЗрддреНрд░рд╕рдБрдЧ рддреБрд▓рдирд╛ рдЧрд░реНрдЫ Immред рдпрджрд┐ рдорд╛рдирд╣рд░реВ рдореЗрд▓ рдЦрд╛рдиреНрдЫ рднрдиреЗ, рддреНрдпрд╕рдкрдЫрд┐ рд╕рдВрдХреНрд░рдордг рд╣реБрдиреНрдЫ PC + OffрдХрд╣рд╛рдБ PC, рд╕рд╛рдорд╛рдиреНрдп рд░реВрдкрдорд╛, рдЕрд░реНрдХреЛ рдирд┐рд░реНрджреЗрд╢рдирдХреЛ рдареЗрдЧрд╛рдирд╛ рд╕рдорд╛рд╡реЗрд╢ рдЧрд░реНрджрдЫред рдЕрдиреНрддрдорд╛, JMP рдХрдХреНрд╖рд╛ 9 рд╕рдЮреНрдЪрд╛рд▓рди рдЫ BPF_EXITред рдпреЛ рдирд┐рд░реНрджреЗрд╢рдирд▓реЗ рдХрд╛рд░реНрдпрдХреНрд░рдо рд╕рдорд╛рдкреНрдд рдЧрд░реНрдЫ, рдХрд░реНрдиреЗрд▓рдорд╛ рдлрд░реНрдХрдиреНрдЫ r0ред рд╣рд╛рдореНрд░реЛ рддрд╛рд▓рд┐рдХрд╛рдорд╛ рдирдпрд╛рдБ рд╕реНрддрдореНрдн рдердкреМрдВ:

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

рд╣рд╛рдореА рдпрд╕рд▓рд╛рдИ рдердк рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдлрд╛рд░рдордорд╛ рдкреБрди: рд▓реЗрдЦреНрди рд╕рдХреНрдЫреМрдВ:

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

рдпрджрд┐ рд╣рд╛рдореАрд▓реЗ рджрд░реНрддрд╛рдорд╛ рдХреЗ рдЫ рд╕рдореНрдЭрдиреНрдЫреМрдВ r1 рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд░реНрдиреЗрд▓рдмрд╛рдЯ рд╕рдиреНрджрд░реНрднрдорд╛ рдПрдХ рд╕реВрдЪрдХ рдкрд╛рд╕ рдЧрд░рд┐рдПрдХреЛ рдЫ, рд░ рджрд░реНрддрд╛рдорд╛ r0 рдорд╛рди рдХрд░реНрдиреЗрд▓рдорд╛ рдлрд░реНрдХрд╛рдЗрдиреНрдЫ, рддреНрдпрд╕рдкрдЫрд┐ рд╣рд╛рдореА рджреЗрдЦреНрди рд╕рдХреНрдЫреМрдВ рдХрд┐ рдпрджрд┐ рд╕рдиреНрджрд░реНрднрдорд╛ рд╕реВрдЪрдХ рд╢реВрдиреНрдп рдЫ рднрдиреЗ, рд╣рд╛рдореА 1 рдлрд░реНрдХрд╛рдЙрдБрдЫреМрдВ, рд░ рдЕрдиреНрдпрдерд╛ - 2ред рд╕реНрд░реЛрдд рд╣реЗрд░реЗрд░ рд╣рд╛рдореА рд╕рд╣реА рдЫреМрдВ рднрдиреЗрд░ рдЬрд╛рдБрдЪ рдЧрд░реМрдВ:

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

рд╣реЛ, рдпреЛ рдПрдХ рдЕрд░реНрдерд╣реАрди рдХрд╛рд░реНрдпрдХреНрд░рдо рд╣реЛ, рддрд░ рдпрд╕рд▓реЗ рдХреЗрд╡рд▓ рдЪрд╛рд░ рд╕рд░рд▓ рдирд┐рд░реНрджреЗрд╢рдирд╣рд░реВрдорд╛ рдЕрдиреБрд╡рд╛рдж рдЧрд░реНрджрдЫред

рдЕрдкрд╡рд╛рдж рдЙрджрд╛рд╣рд░рдг: 16-рдмрд╛рдЗрдЯ рдирд┐рд░реНрджреЗрд╢рди

рд╣рд╛рдореАрд▓реЗ рдкрд╣рд┐рд▓реЗ рдЙрд▓реНрд▓реЗрдЦ рдЧрд░реЗрдХрд╛ рдерд┐рдпреМрдВ рдХрд┐ рдХреЗрд╣рд┐ рдирд┐рд░реНрджреЗрд╢рдирд╣рд░реВрд▓реЗ 64 рдмрд┐рдЯ рднрдиреНрджрд╛ рдмрдвреА рд▓рд┐рдиреНрдЫрдиреНред рдпреЛ рд▓рд╛рдЧреВ рд╣реБрдиреНрдЫ, рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐, рдирд┐рд░реНрджреЗрд╢рдирд╣рд░реВрдорд╛ lddw (рдХреЛрдб = 0x18 = BPF_LD | BPF_DW | BPF_IMM) тАФ рдлрд┐рд▓реНрдбрдмрд╛рдЯ рдПрдХ рджреЛрд╣реЛрд░реЛ рд╢рдмреНрдж рджрд░реНрддрд╛рдорд╛ рд▓реЛрдб рдЧрд░реНрдиреБрд╣реЛрд╕реН Immред рддрдереНрдп рдпреЛ рд╣реЛ Imm 32 рдХреЛ рд╕рд╛рдЗрдЬ рдЫ, рд░ рдПрдХ рджреЛрд╣реЛрд░реЛ рд╢рдмреНрдж 64 рдмрд┐рдЯ рдЫ, рддреНрдпрд╕реИрд▓реЗ 64-рдмрд┐рдЯ рдирд┐рд░реНрджреЗрд╢рдирдорд╛ 64-рдмрд┐рдЯ рддрддреНрдХрд╛рд▓ рдорд╛рди рдПрдХ рджрд░реНрддрд╛рдорд╛ рд▓реЛрдб рдЧрд░реНрджрд╛ рдХрд╛рдо рдЧрд░реНрджреИрдиред рдпреЛ рдЧрд░реНрдирдХрд╛ рд▓рд╛рдЧрд┐, рдлрд┐рд▓реНрдбрдорд╛ 64-рдмрд┐рдЯ рдорд╛рдирдХреЛ рджреЛрд╕реНрд░реЛ рднрд╛рдЧ рднрдгреНрдбрд╛рд░рдг рдЧрд░реНрди рджреБрдИ рдирдЬрд┐рдХрдХрд╛ рдирд┐рд░реНрджреЗрд╢рдирд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░рд┐рдиреНрдЫ Immред рдЙрджрд╛рд╣рд░рдг:

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

рдмрд╛рдЗрдирд░реА рдХрд╛рд░реНрдпрдХреНрд░рдордорд╛ рдХреЗрд╡рд▓ рджреБрдИ рдирд┐рд░реНрджреЗрд╢рдирд╣рд░реВ рдЫрдиреН:

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

рд╣рд╛рдореА рдирд┐рд░реНрджреЗрд╢рди рд╕рд╣рд┐рдд рдлреЗрд░рд┐ рднреЗрдЯреНрдиреЗрдЫреМрдВ lddw, рдЬрдм рд╣рд╛рдореА рд╕реНрдерд╛рдирд╛рдиреНрддрд░рдг рд░ рдирдХреНрд╕рд╛ рд╕рдВрдЧ рдХрд╛рдо рдЧрд░реНрдиреЗ рдмрд╛рд░реЗ рдХреБрд░рд╛ рдЧрд░реНрдЫреМрдВред

рдЙрджрд╛рд╣рд░рдг: рдорд╛рдирдХ рдЙрдкрдХрд░рдгрд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░реА BPF рдЫреБрдЯреНрдпрд╛рдЙрдиреЗ

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

$ llvm-objdump -d x64.o

Disassembly of section .text:

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

BPF рд╡рд╕реНрддреБрд╣рд░реВрдХреЛ рдЬреАрд╡рдирдЪрдХреНрд░, bpffs рдлрд╛рдЗрд▓ рдкреНрд░рдгрд╛рд▓реА

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

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

рдпрджрд┐ рдХрд╛рд░реНрдпрдХреНрд░рдо рдирдХреНрд╕рд╛ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрджрдЫ, рддреНрдпрд╕рдкрдЫрд┐ refcount рдХрд╛рд░реНрдпрдХреНрд░рдо рд▓реЛрдб рдЧрд░реЗрдкрдЫрд┐ рдпреА рдирдХреНрд╕рд╛рд╣рд░реВ рдПрдХрд▓реЗ рдмрдврд╛рдЗрдиреНрдЫ, рдЕрд░реНрдерд╛рддреНред рддрд┐рдиреАрд╣рд░реВрдХреЛ рдлрд╛рдЗрд▓ рд╡рд░реНрдгрдирдХрд░реНрддрд╛рд╣рд░реВ рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛рдмрд╛рдЯ рдмрдиреНрдж рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫ рд░ рдЕрдЭреИ рдкрдирд┐ refcount рд╢реВрдиреНрдп рд╣реБрдиреЗрдЫреИрди:

рд╕рд╛рдирд╛рд╣рд░реВрдХрд╛ рд▓рд╛рдЧрд┐ BPF, рднрд╛рдЧ рдПрдХ: рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд BPF

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

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

рд╕рд╛рдирд╛рд╣рд░реВрдХрд╛ рд▓рд╛рдЧрд┐ BPF, рднрд╛рдЧ рдПрдХ: рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд BPF

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

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

рд╕рд╛рдирд╛рд╣рд░реВрдХрд╛ рд▓рд╛рдЧрд┐ BPF, рднрд╛рдЧ рдПрдХ: рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд BPF

BPF рд╡рд╕реНрддреБрд╣рд░реВ рд╕рдиреНрджрд░реНрдн рдЧрд░реНрдиреЗ bpffs рдорд╛ рдлрд╛рдЗрд▓рд╣рд░реВ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрдиреБрд▓рд╛рдИ "рдкрд┐рдирд┐рдЩ" рднрдирд┐рдиреНрдЫ (рдирд┐рдореНрди рд╡рд╛рдХреНрдпрд╛рдВрд╢рдорд╛ рдЬрд╕реНрддреИ: "рдкреНрд░рдХреНрд░рд┐рдпрд╛рд▓реЗ BPF рдХрд╛рд░реНрдпрдХреНрд░рдо рд╡рд╛ рдирдХреНрд╕рд╛рд▓рд╛рдИ рдкрд┐рди рдЧрд░реНрди рд╕рдХреНрдЫ")ред BPF рд╡рд╕реНрддреБрд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐ рдлрд╛рдЗрд▓ рд╡рд╕реНрддреБрд╣рд░реВ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрдирд╛рд▓реЗ рд╕реНрдерд╛рдиреАрдп рд╡рд╕реНрддреБрд╣рд░реВрдХреЛ рдЖрдпреБ рдмрдврд╛рдЙрдирдХреЛ рд▓рд╛рдЧрд┐ рдорд╛рддреНрд░ рд╣реЛрдЗрди, рддрд░ рд╡рд┐рд╢реНрд╡рд╡реНрдпрд╛рдкреА рд╡рд╕реНрддреБрд╣рд░реВрдХреЛ рдЙрдкрдпреЛрдЧрд┐рддрд╛рдХреЛ рд▓рд╛рдЧрд┐ рдкрдирд┐ рдЕрд░реНрдердкреВрд░реНрдг рд╣реБрдиреНрдЫ - рд╡рд┐рд╢реНрд╡рд╡реНрдпрд╛рдкреА DDoS рд╕реБрд░рдХреНрд╖рд╛ рдХрд╛рд░реНрдпрдХреНрд░рдордХреЛ рдЙрджрд╛рд╣рд░рдгрдорд╛ рдлрд░реНрдХреЗрд░, рд╣рд╛рдореА рддрдереНрдпрд╛рдЩреНрдХрд╣рд░реВ рд╣реЗрд░реНрди рд╕рдХреНрд╖рдо рд╣реБрди рдЪрд╛рд╣рдиреНрдЫреМрдВред рд╕рдордп рд╕рдордпрдорд╛ред

BPF рдлрд╛рдЗрд▓ рдкреНрд░рдгрд╛рд▓реА рд╕рд╛рдорд╛рдиреНрдпрддрдпрд╛ рдорд╛ рдорд╛рдЙрдиреНрдЯ рдЧрд░рд┐рдПрдХреЛ рдЫ /sys/fs/bpf, рддрд░ рдпреЛ рд╕реНрдерд╛рдиреАрдп рд░реВрдкрдорд╛ рдкрдирд┐ рдорд╛рдЙрдиреНрдЯ рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫ, рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐, рдпреЛ рдЬрд╕реНрддреИ:

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

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

$ 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

рд╡рд╕реНрддреБрд╣рд░реВ рдореЗрдЯрд╛рдЙрдБрджреИ

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

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

рдШрдЯрдирд╛ рд╕реНрд░реЛрддрд╣рд░реВрдорд╛ рдХрд╛рд░реНрдпрдХреНрд░рдорд╣рд░реВ рд╕рдВрд▓рдЧреНрди рдЧрд░реНрджреИ

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

рдмреАрдкреАрдПрдл рдкреНрд░рдгрд╛рд▓реА рдХрд▓ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рд╡рд╕реНрддреБрд╣рд░реВ рд╣реЗрд░рдлреЗрд░ рдЧрд░реНрджреИ

BPF рдХрд╛рд░реНрдпрдХреНрд░рдорд╣рд░реВ

рд╕рдмреИ BPF рд╡рд╕реНрддреБрд╣рд░реВ рдкреНрд░рдгрд╛рд▓реА рдХрд▓ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛ рд╕реНрдкреЗрд╕рдмрд╛рдЯ рд╕рд┐рд░реНрдЬрдирд╛ рд░ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рд╣реБрдиреНрдЫрдиреН bpf, рдирд┐рдореНрди рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рднрдПрдХреЛ:

#include <linux/bpf.h>

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

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

рдЯреЛрд▓реАрдмрд╛рдЯ рд╕реБрд░реБ рдЧрд░реМрдВ BPF_PROG_LOAD, рдЬрд╕рд▓реЗ BPF рдХрд╛рд░реНрдпрдХреНрд░рдорд╣рд░реВ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрджрдЫ - BPF рдирд┐рд░реНрджреЗрд╢рдирд╣рд░реВрдХреЛ рд╕реЗрдЯ рд▓рд┐рдиреНрдЫ рд░ рдХрд░реНрдиреЗрд▓рдорд╛ рд▓реЛрдб рдЧрд░реНрджрдЫред рд▓реЛрдбрд┐рдЩрдХреЛ рдХреНрд╖рдгрдорд╛, рдкреНрд░рдорд╛рдгрд┐рдХрд░рдг рд╕реБрд░реБ рд╣реБрдиреНрдЫ, рд░ рддреНрдпрд╕рдкрдЫрд┐ JIT рдХрдореНрдкрд╛рдЗрд▓рд░ рд░, рд╕рдлрд▓ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрдЫрд┐, рдкреНрд░реЛрдЧреНрд░рд╛рдо рдлрд╛рдЗрд▓ рд╡рд░реНрдгрдирдХрд░реНрддрд╛ рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛рд▓рд╛рдИ рдлрд░реНрдХрд╛рдЗрдиреНрдЫред рд╣рд╛рдореАрд▓реЗ рдЕрдШрд┐рд▓реНрд▓реЛ рдЦрдгреНрдбрдорд╛ рдЙрд╣рд╛рдБрд▓рд╛рдИ рдХреЗ рд╣реБрдиреНрдЫ рджреЗрдЦреНрдпреМрдВ BPF рд╡рд╕реНрддреБрд╣рд░реВрдХреЛ рдЬреАрд╡рди рдЪрдХреНрд░рдХреЛ рдмрд╛рд░реЗрдорд╛.

рд╣рд╛рдореА рдЕрдм рдПрдЙрдЯрд╛ рдХрд╕реНрдЯрдо рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓реЗрдЦреНрдиреЗрдЫреМрдВ рдЬрд╕рд▓реЗ рд╕рд╛рдзрд╛рд░рдг BPF рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓реЛрдб рдЧрд░реНрдиреЗрдЫ, рддрд░ рдкрд╣рд┐рд▓реЗ рд╣рд╛рдореАрд▓реЗ рдХреБрди рдкреНрд░рдХрд╛рд░рдХреЛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓реЛрдб рдЧрд░реНрди рдЪрд╛рд╣рдиреНрдЫреМрдВ рднрдиреЗрд░ рдирд┐рд░реНрдгрдп рдЧрд░реНрди рдЖрд╡рд╢реНрдпрдХ рдЫ - рд╣рд╛рдореАрд▓реЗ рдЪрдпрди рдЧрд░реНрдиреБрдкрд░реНрдиреЗрдЫред рдкреНрд░рдХрд╛рд░ рд░ рдпрд╕ рдкреНрд░рдХрд╛рд░рдХреЛ рдврд╛рдБрдЪрд╛ рднрд┐рддреНрд░, рдПрдЙрдЯрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓реЗрдЦреНрдиреБрд╣реЛрд╕реН рдЬрд╕рд▓реЗ рдкреНрд░рдорд╛рдгрд┐рдХрд░рдг рдкрд░реАрдХреНрд╖рдг рдкрд╛рд╕ рдЧрд░реНрдиреЗрдЫред рдпрджреНрдпрдкрд┐, рдкреНрд░рдХреНрд░рд┐рдпрд╛рд▓рд╛рдИ рдЬрдЯрд┐рд▓ рдирдмрдирд╛рдЙрдирдХреЛ рд▓рд╛рдЧрд┐, рдпрд╣рд╛рдБ рдПрдХ рддрдпрд╛рд░ рд╕рдорд╛рдзрд╛рди рдЫ: рд╣рд╛рдореА рдЬрд╕реНрддреИ рдХрд╛рд░реНрдпрдХреНрд░рдо рд▓рд┐рдиреЗрдЫреМрдВ 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 рдХрд╛рд░реНрдпрдХреНрд░рдоред рдпрд╕ рдЕрд╡рд╕реНрдерд╛рдорд╛, BPF рдХрд╛рд░реНрдпрдХреНрд░рдордХреЛ рдкреНрд░рддреНрдпреЗрдХ рдирд┐рд░реНрджреЗрд╢рди рд╕рдВрд░рдЪрдирд╛рдорд╛ рдкреНрдпрд╛рдХ рдЧрд░рд┐рдПрдХреЛ рдЫ bpf_insnред рдкрд╣рд┐рд▓реЛ рддрддреНрд╡ insns рдирд┐рд░реНрджреЗрд╢рдирд╣рд░реВрдХреЛ рдкрд╛рд▓рдирд╛ рдЧрд░реНрджрдЫ r0 = 2, рджреЛрд╕реНрд░реЛ - exit.

рд░рд┐рдЯреНрд░реАрдЯред рдХрд░реНрдиреЗрд▓рд▓реЗ рдореЗрд╕рд┐рди рдХреЛрдбрд╣рд░реВ рд▓реЗрдЦреНрди рд░ рдХрд░реНрдиреЗрд▓ рд╣реЗрдбрд░ рдлрд╛рдЗрд▓ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдирдХрд╛ рд▓рд╛рдЧрд┐ рдердк рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдореНрдпрд╛рдХреНрд░реЛрд╣рд░реВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдЧрд░реНрджрдЫред tools/include/linux/filter.h рд╣рд╛рдореА рд▓реЗрдЦреНрди рд╕рдХреНрдЫреМрдВ

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

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

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

рдХрд╛рд░реНрдпрдХреНрд░рдордХреЛ рдЕрдиреНрддреНрдпрдорд╛ рд╣рд╛рдореА рдЕрдирдиреНрдд рд▓реВрдкрдорд╛ рдкреБрдЧреНрдЫреМрдВ рдЬрд╕рд▓реЗ рдкреЗрд▓реЛрдбрд▓рд╛рдИ рд╕рд┐рдореБрд▓реЗрдЯ рдЧрд░реНрдЫред рдпреЛ рдмрд┐рдирд╛, рдкреНрд░реЛрдЧреНрд░рд╛рдорд▓рд╛рдИ рдХрд░реНрдиреЗрд▓рджреНрд╡рд╛рд░рд╛ рдорд╛рд░рд┐рдиреЗрдЫ рдЬрдм рдкреНрд░рдгрд╛рд▓реАрд▓реЗ рд╣рд╛рдореАрд▓рд╛рдИ рдлрд┐рд░реНрддрд╛ рдЧрд░реЗрдХреЛ рдлрд╛рдЗрд▓ рд╡рд░реНрдгрдирдХрд░реНрддрд╛ рдмрдиреНрдж рд╣реБрдиреНрдЫред bpf, рд░ рд╣рд╛рдореАрд▓реЗ рдпрд╕рд▓рд╛рдИ рдкреНрд░рдгрд╛рд▓реАрдорд╛ рджреЗрдЦреНрдиреЗ рдЫреИрдиреМрдВред

рдЦреИрд░, рд╣рд╛рдореА рдкрд░реАрдХреНрд╖рдгрдХреЛ рд▓рд╛рдЧрд┐ рддрдпрд╛рд░ рдЫреМрдВред рднреЗрд▓рд╛ рдЧрд░реМрдВ рд░ рдХрд╛рд░реНрдпрдХреНрд░рдо рдЕрдиреНрддрд░реНрдЧрдд рдЪрд▓рд╛рдЙрдиреБрд╣реЛрд╕реН straceрдЬрд╛рдБрдЪ рдЧрд░реНрди рдХреЛ рд▓рд╛рдЧреА рд╕рдмреИ рдХреБрд░рд╛ рдпреЛ рдЬрд╕реНрддреИ рдХрд╛рдо рдЧрд░рд┐рд░рд╣реЗрдХреЛ рдЫ:

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

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

рд╕рдмреИ рдареАрдХ рдЫ, bpf(2) рд╣реНрдпрд╛рдиреНрдбрд▓ 3 рд╣рд╛рдореАрд▓рд╛рдИ рдлрд░реНрдХрд╛рдЗрдпреЛ рд░ рд╣рд╛рдореА рдЕрдирдиреНрдд рд▓реБрдкрдорд╛ рдЧрдпреМрдВ pause()ред рдкреНрд░рдгрд╛рд▓реАрдорд╛ рд╣рд╛рдореНрд░реЛ рдХрд╛рд░реНрдпрдХреНрд░рдо рдлреЗрд▓рд╛ рдкрд╛рд░реНрди рдкреНрд░рдпрд╛рд╕ рдЧрд░реМрдВред рдпреЛ рдЧрд░реНрдирдХреЛ рд▓рд╛рдЧрд┐ рд╣рд╛рдореА рдЕрд░реНрдХреЛ рдЯрд░реНрдорд┐рдирд▓рдорд╛ рдЬрд╛рдиреЗрдЫреМрдВ рд░ рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреЗрдЫреМрдВ bpftool:

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

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

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

рдХреБрдиреИ рдЖрд╢реНрдЪрд░реНрдп рдЫреИрдиред рдЕрдм 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), рддрд░ рдирд┐рд╖реНрдкрдХреНрд╖рддрд╛рдорд╛, рд╣рд╛рдореНрд░реЛ рдХрд╛рд░реНрдпрдХреНрд░рдо рдзреЗрд░реИ рд╕рд░рд▓ рдЫ, рд░ рдЧреИрд░-рддреБрдЪреНрдЫ рдХрд╛рд░реНрдпрдХреНрд░рдорд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐ JIT рдХрдореНрдкрд╛рдЗрд▓рд░рд▓реЗ рдердкреЗрдХреЛ рдкреНрд░рд╕реНрддрд╛рд╡рдирд╛ рд░ рдЙрдкрд╕рдВрд╣рд╛рд░ рдЕрд╡рд╢реНрдп рдкрдирд┐ рдЖрд╡рд╢реНрдпрдХ рдЫред

рдирдХреНрд╕рд╛

BPF рдХрд╛рд░реНрдпрдХреНрд░рдорд╣рд░реВрд▓реЗ рд╕рдВрд░рдЪрд┐рдд рдореЗрдореЛрд░реА рдХреНрд╖реЗрддреНрд░рд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рд╕рдХреНрдЫрдиреН рдЬреБрди рдЕрдиреНрдп BPF рдХрд╛рд░реНрдпрдХреНрд░рдорд╣рд░реВ рд░ рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛ рд╕реНрдкреЗрд╕рдорд╛ рднрдПрдХрд╛ рдХрд╛рд░реНрдпрдХреНрд░рдорд╣рд░реВрдорд╛ рдкрд╣реБрдБрдЪрдпреЛрдЧреНрдп рдЫрдиреНред рдпреА рд╡рд╕реНрддреБрд╣рд░реВрд▓рд╛рдИ рдирдХреНрд╕рд╛ рднрдирд┐рдиреНрдЫ рд░ рдпрд╕ рдЦрдгреНрдбрдорд╛ рд╣рд╛рдореА рддрд┐рдиреАрд╣рд░реВрд▓рд╛рдИ рдкреНрд░рдгрд╛рд▓реА рдХрд▓ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдХрд╕рд░реА рд╣реЗрд░рдлреЗрд░ рдЧрд░реНрдиреЗ рднрдиреЗрд░ рджреЗрдЦрд╛рдЙрдиреЗрдЫреМрдВ bpf.

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

рдпрджрд┐ рддрдкрд╛рдИрдВрд▓реЗ рд╣реНрдпрд╛рд╕ рддрд╛рд▓рд┐рдХрд╛ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрдиреБрднрдпреЛ рднрдиреЗ, рднрдиреНрдиреБрд╣реЛрд╕реН, C++, рддрдкрд╛рдИрдВрд▓реЗ рднрдиреНрдиреБрд╣реБрдиреЗрдЫ unordered_map<int,long> woo, рдЬрд╕рдХреЛ рд░реВрд╕реАрдорд╛ рдЕрд░реНрде "рдорд▓рд╛рдИ рдЯреЗрдмрд▓ рдЪрд╛рд╣рд┐рдиреНрдЫ woo рдЕрд╕реАрдорд┐рдд рдЖрдХрд╛рд░, рдЬрд╕рдХреЛ рдХреБрдЮреНрдЬреА рдкреНрд░рдХрд╛рд░рдХрд╛ рдЫрдиреН int, рд░ рдорд╛рдирд╣рд░реВ рдкреНрд░рдХрд╛рд░ рд╣реБрдиреН long" BPF рд╣реНрдпрд╛рд╕ рддрд╛рд▓рд┐рдХрд╛ рдмрдирд╛рдЙрдирдХреЛ рд▓рд╛рдЧрд┐, рд╣рд╛рдореАрд▓реЗ рддрд╛рд▓рд┐рдХрд╛рдХреЛ рдЕрдзрд┐рдХрддрдо рдЖрдХрд╛рд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЧрд░реНрди рдмрд╛рд╣реЗрдХ, рд╣рд╛рдореАрд▓реЗ рдзреЗрд░реИ рдХреБрд░рд╛рд╣рд░реВ рдЧрд░реНрди рдЖрд╡рд╢реНрдпрдХ рдЫ, рд░ рдХреБрдЮреНрдЬреА рд░ рдорд╛рдирд╣рд░реВрдХреЛ рдкреНрд░рдХрд╛рд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЧрд░реНрдиреБрдХреЛ рд╕рдЯреНрдЯрд╛, рд╣рд╛рдореАрд▓реЗ рдмрд╛рдЗрдЯрд╣рд░реВрдорд╛ рддрд┐рдиреАрд╣рд░реВрдХреЛ рдЖрдХрд╛рд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЧрд░реНрди рдЖрд╡рд╢реНрдпрдХ рдЫред ред рдирдХреНрд╕рд╛ рдмрдирд╛рдЙрди рдЖрджреЗрд╢ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреБрд╣реЛрд╕реН BPF_MAP_CREATE рдкреНрд░рдгрд╛рд▓реА рдХрд▓ bpfред рдирдХреНрд╕рд╛ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрдиреЗ рдХрдо рд╡рд╛ рдХрдо рдиреНрдпреВрдирддрдо рдХрд╛рд░реНрдпрдХреНрд░рдорд▓рд╛рдИ рд╣реЗрд░реМрдВред 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), рдЬрд╕рдорд╛ рдо рдЕрдзрд┐рдХрддрдо рдЪрд╛рд░ рддрддреНрд╡ рд░рд╛рдЦреНрди рд╕рдХреНрдЫреБред" BPF рдирдХреНрд╕рд╛рд╣рд░реВ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрджрд╛, рддрдкрд╛рдЗрдБ рдЕрдиреНрдп рдкреНрдпрд╛рд░рд╛рдорд┐рдЯрд░рд╣рд░реВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ, рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐, рдХрд╛рд░реНрдпрдХреНрд░рдордХреЛ рдЙрджрд╛рд╣рд░рдгрдорд╛ рдЬрд╕реНрддреИ, рд╣рд╛рдореАрд▓реЗ рд╡рд╕реНрддреБрдХреЛ рдирд╛рдо рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЧрд░реЗрдХрд╛ рдЫреМрдВред "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 рд╣рд╛рдореНрд░реЛ рд╡рд╕реНрддреБрдХреЛ рд╡рд┐рд╢реНрд╡рд╡реНрдпрд╛рдкреА ID рд╣реЛред рдкреНрд░рдгрд╛рд▓реАрдорд╛ рдХреБрдиреИ рдкрдирд┐ рдкреНрд░реЛрдЧреНрд░рд╛рдорд▓реЗ рдЖрджреЗрд╢ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдЕрд╡рд╕реНрдерд┐рдд рдирдХреНрд╕рд╛ рдЦреЛрд▓реНрди рдпреЛ ID рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рд╕рдХреНрдЫ 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 рдерд╛рд╣рд╛ рдЫреИрди рд╣реНрдпрд╛рд╕ рддрд╛рд▓рд┐рдХрд╛рдорд╛ рдХреБрди рдкреНрд░рдХрд╛рд░рдХрд╛ рдорд╛рдирд╣рд░реВ рдЫрдиреНред (рдпреЛ рдЬреНрдЮрд╛рди BTF рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдЙрд╕рд▓рд╛рдИ рд╣рд╕реНрддрд╛рдиреНрддрд░рдг рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫ, рддрд░ рдЕрдм рддреНрдпрд╕рдорд╛ рдердкред)

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.

рдареАрдХ рдЫ, рдХреБрдЮреНрдЬреА рез рджреНрд╡рд╛рд░рд╛ рдорд╛рди рдкрд░рд┐рд╡рд░реНрддрди рдЧрд░реМрдВ, рд╣рд╛рдореНрд░реЛ рд╡реНрдпрд╛рдкрд╛рд░ рддрд░реНрдХрд▓рд╛рдИ рджрд░реНрддрд╛ рдЧрд░реНрди рдЖрд╡рд╢реНрдпрдХ рдЫ рднрдиреМрдВред 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 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: рдпрд╕рдХреЛ рд╡рд┐рд╢реНрд╡рд╡реНрдпрд╛рдкреА ID рджреНрд╡рд╛рд░рд╛ рдЕрд╡рд╕реНрдерд┐рдд рдирдХреНрд╕рд╛ рдЦреЛрд▓реНрдиреБрд╣реЛрд╕реН
  • BPF_MAP_LOOKUP_AND_DELETE_ELEM: рдкрд░рдорд╛рдгреБ рд░реВрдкрдорд╛ рд╡рд╕реНрддреБрдХреЛ рдорд╛рди рдЕрджреНрдпрд╛рд╡рдзрд┐рдХ рдЧрд░реНрдиреБрд╣реЛрд╕реН рд░ рдкреБрд░рд╛рдиреЛ рдлрд░реНрдХрд╛рдЙрдиреБрд╣реЛрд╕реН
  • BPF_MAP_FREEZE: рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛ рд╕реНрдерд╛рдирдмрд╛рдЯ рдирдХреНрд╕рд╛ рдЕрдкрд░рд┐рд╡рд░реНрддрдиреАрдп рдмрдирд╛рдЙрдиреБрд╣реЛрд╕реН (рдпрд╕ рдЕрдкрд░реЗрд╢рдирд▓рд╛рдИ рдЕрдиреНрдбреВ рдЧрд░реНрди рд╕рдХрд┐рдБрджреИрди)
  • BPF_MAP_LOOKUP_BATCH, BPF_MAP_LOOKUP_AND_DELETE_BATCH, BPF_MAP_UPDATE_BATCH, BPF_MAP_DELETE_BATCH: рд╕рд╛рдореВрд╣рд┐рдХ рд╕рдЮреНрдЪрд╛рд▓рдиред рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐, BPF_MAP_LOOKUP_AND_DELETE_BATCH - рдпреЛ рдирдХреНрд╕рд╛рдмрд╛рдЯ рд╕рдмреИ рдорд╛рдирд╣рд░реВ рдкрдвреНрди рд░ рд░рд┐рд╕реЗрдЯ рдЧрд░реНрдиреЗ рдорд╛рддреНрд░ рднрд░рдкрд░реНрджреЛ рддрд░рд┐рдХрд╛ рд╣реЛ

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

рдЕрд░реНрдбрд░рдХреЛ рдЦрд╛рддрд┐рд░, рд╣рд╛рдореНрд░реЛ рд╣реНрдпрд╛рд╕ рддрд╛рд▓рд┐рдХрд╛ рдкреНрд░рдпреЛрдЧрд╣рд░реВ рд╕рдорд╛рдкреНрдд рдЧрд░реМрдВред рдпрд╛рдж рдЧрд░реНрдиреБрд╣реЛрд╕реН рдХрд┐ рд╣рд╛рдореАрд▓реЗ рдПрдЙрдЯрд╛ рддрд╛рд▓рд┐рдХрд╛ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрдпреМрдВ рдЬрд╕рдорд╛ рдЪрд╛рд░ рдХреБрдЮреНрдЬреАрд╣рд░реВ рд╕рдорд╛рд╡реЗрд╢ рд╣реБрди рд╕рдХреНрдЫрдиреН? рдХреЗрд╣реА рдердк рддрддреНрд╡рд╣рд░реВ рдердкреМрдВ:

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

рдЕрд╣рд┐рд▓реЗрд╕рдореНрдо рдзреЗрд░реИ рд░рд╛рдореНрд░реЛ:

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

рдЕрд░реНрдХреЛ рдердкреНрди рдкреНрд░рдпрд╛рд╕ рдЧрд░реМрдВ:

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

рдЕрдкреЗрдХреНрд╖рд╛ рдЧрд░реЗрдЕрдиреБрд╕рд╛рд░ рд╣рд╛рдореА рд╕рдлрд▓ рднрдПрдиреМрдВред рддреНрд░реБрдЯрд┐рд▓рд╛рдИ рдердк рд╡рд┐рд╡рд░рдгрдорд╛ рд╣реЗрд░реМрдВ:

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

рд╕рдмреИ рдареАрдХ рдЫ: рдЕрдкреЗрдХреНрд╖рд┐рдд рд░реВрдкрдорд╛, рдЯреЛрд▓реА BPF_MAP_UPDATE_ELEM рдирдпрд╛рдБ, рдкрд╛рдБрдЪреМрдВ, рдХреБрдЮреНрдЬреА рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрдиреЗ рдкреНрд░рдпрд╛рд╕ рдЧрд░реНрдЫ, рддрд░ рдХреНрд░реНрдпрд╛рд╕ рд╣реБрдиреНрдЫ E2BIG.

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

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

Libbpf рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ BPF рдХрд╛рд░реНрдпрдХреНрд░рдорд╣рд░реВ рд▓реЗрдЦреНрджреИ

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

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

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

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

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

рдпрд╕ рдЦрдгреНрдбрдорд╛ рд╣рд╛рдореА рддрдкрд╛рдЗрдБ рдХрд╕рд░реА рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреЗ рдкрд░рд┐рдпреЛрдЬрдирд╛ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫ рднрдиреЗрд░ рд╣реЗрд░реНрдиреЗрдЫреМрдВ libbpf, рдзреЗрд░реИ (рдЕрдзрд┐рдХ рд╡рд╛ рдХрдо рдЕрд░реНрдерд╣реАрди) рдкрд░реАрдХреНрд╖рдг рдХрд╛рд░реНрдпрдХреНрд░рдорд╣рд░реВ рд▓реЗрдЦреМрдВ рд░ рдпреЛ рд╕рдмреИ рдХрд╕рд░реА рдХрд╛рдо рдЧрд░реНрджрдЫ рд╡рд┐рд╕реНрддреГрдд рд░реВрдкрдорд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдЧрд░реМрдВред рдпрд╕рд▓реЗ рд╣рд╛рдореАрд▓рд╛рдИ BPF рдХрд╛рд░реНрдпрдХреНрд░рдорд╣рд░реВрд▓реЗ рдирдХреНрд╕рд╛, рдХрд░реНрдиреЗрд▓ рд╕рд╣рдпреЛрдЧреАрд╣рд░реВ, BTF, рдЗрддреНрдпрд╛рджрд┐рд╕рдБрдЧ рдХрд╕рд░реА рдЕрдиреНрддрд░рдХреНрд░рд┐рдпрд╛ рдЧрд░реНрдЫ рднрдиреЗрд░ рдирд┐рдореНрди рдЦрдгреНрдбрд╣рд░реВрдорд╛ рдЕрдЭ рд╕рдЬрд┐рд▓реИ рд╡реНрдпрд╛рдЦреНрдпрд╛ рдЧрд░реНрди рдЕрдиреБрдорддрд┐ рджрд┐рдиреЗрдЫред

рд╕рд╛рдорд╛рдиреНрдпрддрдпрд╛ рдкрд░рд┐рдпреЛрдЬрдирд╛рд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрджреИ libbpf рдЧрд┐рдЯ рд╕рдмрдореЛрдбреНрдпреБрд▓рдХреЛ рд░реВрдкрдорд╛ GitHub рднрдгреНрдбрд╛рд░ рдердкреНрдиреБрд╣реЛрд╕реН, рд╣рд╛рдореА рддреНрдпрд╕реИ рдЧрд░реНрдиреЗрдЫреМрдВ:

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

рдЬрд╛рдБрджреИ libbpf рдПрдХрджрдо рд╕рдЬрд┐рд▓реЛ:

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

рдпрд╕ рдЦрдгреНрдбрдорд╛ рд╣рд╛рдореНрд░реЛ рдЕрд░реНрдХреЛ рдпреЛрдЬрдирд╛ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдЫ: рд╣рд╛рдореА BPF рдХрд╛рд░реНрдпрдХреНрд░рдо рдЬрд╕реНрддреИ рд▓реЗрдЦреНрдиреЗрдЫреМрдВ BPF_PROG_TYPE_XDP, рдЕрдШрд┐рд▓реНрд▓реЛ рдЙрджрд╛рд╣рд░рдгрдорд╛ рдЬрд╕реНрддреИ, рддрд░ C рдорд╛, рд╣рд╛рдореА рдпрд╕рд▓рд╛рдИ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдХрдореНрдкрд╛рдЗрд▓ рдЧрд░реНрдЫреМрдВ clang, рд░ рдПрдЙрдЯрд╛ рд╕рд╣рд╛рдпрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдо рд▓реЗрдЦреНрдиреБрд╣реЛрд╕реН рдЬрд╕рд▓реЗ рдпрд╕рд▓рд╛рдИ рдХрд░реНрдиреЗрд▓рдорд╛ рд▓реЛрдб рдЧрд░реНрдиреЗрдЫред рдирд┐рдореНрди рдЦрдгреНрдбрд╣рд░реВрдорд╛ рд╣рд╛рдореА BPF рдХрд╛рд░реНрдпрдХреНрд░рдо рд░ рд╕рд╣рд╛рдпрдХ рдХрд╛рд░реНрдпрдХреНрд░рдо рджреБрд╡реИрдХреЛ рдХреНрд╖рдорддрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдЧрд░реНрдиреЗрдЫреМрдВред

рдЙрджрд╛рд╣рд░рдг: libbpf рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдкреВрд░реНрдг рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрджреИ

рд╕реБрд░реБ рдЧрд░реНрди, рд╣рд╛рдореА рдлрд╛рдЗрд▓ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдЫреМрдВ /sys/kernel/btf/vmlinux, рдЬреБрди рдорд╛рдерд┐ рдЙрд▓реНрд▓реЗрдЦ рдЧрд░рд┐рдПрдХреЛ рдерд┐рдпреЛ, рд░ рд╣реЗрдбрд░ рдлрд╛рдЗрд▓рдХреЛ рд░реВрдкрдорд╛ рдпрд╕рдХреЛ рдмрд░рд╛рдмрд░ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрдиреБрд╣реЛрд╕реН:

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

рдпреЛ рдлрд╛рдЗрд▓рд▓реЗ рд╣рд╛рдореНрд░реЛ рдХрд░реНрдиреЗрд▓рдорд╛ рдЙрдкрд▓рдмреНрдз рд╕рдмреИ рдбрд╛рдЯрд╛ рд╕рдВрд░рдЪрдирд╛рд╣рд░реВ рднрдгреНрдбрд╛рд░рдг рдЧрд░реНрдиреЗрдЫ, рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐, рдХрд░реНрдиреЗрд▓рдорд╛ IPv4 рд╣реЗрдбрд░рд▓рд╛рдИ рдпрд╕рд░реА рдкрд░рд┐рднрд╛рд╖рд┐рдд рдЧрд░рд┐рдПрдХреЛ рдЫ:

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

рдЕрдм рд╣рд╛рдореА рд╣рд╛рдореНрд░реЛ BPF рдХрд╛рд░реНрдпрдХреНрд░рдо C рдорд╛ рд▓реЗрдЦреНрдиреЗрдЫреМрдВ:

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

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

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

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

рд╣рд╛рдореА рд╣рд╛рдореНрд░реЛ рдХрд╛рд░реНрдпрдХреНрд░рдо llvm/clang, рд╕рдВрд╕реНрдХрд░рдг >= 10.0.0, рд╡рд╛ рдЕрдЭ рд░рд╛рдореНрд░реЛ, рдареВрд▓реЛ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдХрдореНрдкрд╛рдЗрд▓ рдЧрд░реНрди рд╕рдХреНрдЫреМрдВ (рдЦрдгреНрдб рд╣реЗрд░реНрдиреБрд╣реЛрд╕реН рд╡рд┐рдХрд╛рд╕ рдЙрдкрдХрд░рдгрд╣рд░реВ):

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

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

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

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

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

Disassembly of section xdp/simple:

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

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

рдкрд╣рд┐рд▓реЗ, рд╣рд╛рдореАрд▓реЗ рдЙрд╣реА рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдпрд╕рдХреЛ рдмрд╛рдЗрдирд░реАрдмрд╛рдЯ рд╣рд╛рдореНрд░реЛ рдХрд╛рд░реНрдпрдХреНрд░рдордХреЛ "рдХрдЩреНрдХрд╛рд▓" рдЙрддреНрдкрдиреНрди рдЧрд░реНрди рдЖрд╡рд╢реНрдпрдХ рдЫред bpftool - BPF рд╕рдВрд╕рд╛рд░рдХреЛ рд╕реНрд╡рд┐рд╕ рдЪрдХреНрдХреБ (рдЬрд╕рд▓рд╛рдИ рд╢рд╛рдмреНрджрд┐рдХ рд░реВрдкрдорд╛ рд▓рд┐рди рд╕рдХрд┐рдиреНрдЫ, рдХрд┐рдирдХрд┐ BPF рдХреЛ рд╕рд┐рд░реНрдЬрдирд╛рдХрд░реНрддрд╛ рд░ рд░рдЦрд░рдЦрд╛рд╡рдХрд░реНрддрд╛рд╣рд░реВ рдордзреНрдпреЗ рдПрдХ рдбреЗрдирд┐рдпрд▓ рдмреЛрд░реНрдХрдореНрдпрд╛рди рд╕реНрд╡рд┐рд╕ рд╣реБрдиреН):

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

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

рдХрдбрд╛ рд╢рдмреНрджрдорд╛, рд╣рд╛рдореНрд░реЛ рд▓реЛрдбрд░ рдХрд╛рд░реНрдпрдХреНрд░рдо рддреБрдЪреНрдЫ рдЫ:

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

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

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

    pause();

    xdp_simple_bpf__destroy(obj);
}

рдпреЛ рдЫ struct xdp_simple_bpf рдлрд╛рдЗрд▓рдорд╛ рдкрд░рд┐рднрд╛рд╖рд┐рдд xdp-simple.skel.h рд░ рд╣рд╛рдореНрд░реЛ рд╡рд╕реНрддреБ рдлрд╛рдЗрд▓ рд╡рд░реНрдгрди рдЧрд░реНрджрдЫ:

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

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

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

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

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

рдЕрдм рд╣рд╛рдореНрд░реЛ рдХрд╛рд░реНрдпрдХреНрд░рдо рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рд╣реЗрд░реМрдВ bpftoolред рдЙрдирдХреЛ рдкрд░рд┐рдЪрдп рдкрддреНрд░ рдлреЗрд▓рд╛ рдкрд╛рд░реМрдВ:

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

рд░ рдбрдореНрдк (рд╣рд╛рдореА рдЖрджреЗрд╢рдХреЛ рдЫреЛрдЯреЛ рд░реВрдк рдкреНрд░рдпреЛрдЧ рдЧрд░реНрджрдЫреМрдВ bpftool prog dump xlated):

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

рдХреЗрд╣рд┐ рдирдпрд╛рдБ! рдХрд╛рд░реНрдпрдХреНрд░рдорд▓реЗ рд╣рд╛рдореНрд░реЛ C рд╕реНрд░реЛрдд рдлрд╛рдЗрд▓рдХреЛ рдЯреБрдХреНрд░рд╛ рдкреНрд░рд┐рдиреНрдЯ рдЧрд░реНрдпреЛред рдпреЛ рдкреБрд╕реНрддрдХрд╛рд▓рдпрд▓реЗ рдЧрд░реЗрдХреЛ рдерд┐рдпреЛ libbpf, рдЬрд╕рд▓реЗ рдмрд╛рдЗрдирд░реАрдорд╛ рдбрд┐рдмрдЧ рдЦрдгреНрдб рдлреЗрд▓рд╛ рдкрд╛рд░реНрдпреЛ, рдпрд╕рд▓рд╛рдИ BTF рд╡рд╕реНрддреБрдорд╛ рдХрдореНрдкрд╛рдЗрд▓ рдЧрд░реНрдпреЛ, рдпрд╕рд▓рд╛рдИ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдХрд░реНрдиреЗрд▓рдорд╛ рд▓реЛрдб рдЧрд░реНрдпреЛред BPF_BTF_LOAD, рд░ рддреНрдпрд╕рдкрдЫрд┐ рдЖрджреЗрд╢рдХреЛ рд╕рд╛рде рдХрд╛рд░реНрдпрдХреНрд░рдо рд▓реЛрдб рдЧрд░реНрджрд╛ рдкрд░рд┐рдгрд╛рдо рдлрд╛рдЗрд▓ рд╡рд░реНрдгрдирдХрд░реНрддрд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЧрд░реНрдиреБрд╣реЛрд╕реН BPG_PROG_LOAD.

рдХрд░реНрдиреЗрд▓ рд╕рд╣рдпреЛрдЧреАрд╣рд░реВ

BPF рдХрд╛рд░реНрдпрдХреНрд░рдорд╣рд░реВрд▓реЗ "рдмрд╛рд╣реНрдп" рдкреНрд░рдХрд╛рд░реНрдпрд╣рд░реВ рдЪрд▓рд╛рдЙрди рд╕рдХреНрдЫ - рдХрд░реНрдиреЗрд▓ рд╕рд╣рд╛рдпрдХрд╣рд░реВред рдпреА рд╕рд╣рд╛рдпрдХ рдкреНрд░рдХрд╛рд░реНрдпрд╣рд░реВрд▓реЗ BPF рдХрд╛рд░реНрдпрдХреНрд░рдорд╣рд░реВрд▓рд╛рдИ рдХрд░реНрдиреЗрд▓ рд╕рдВрд░рдЪрдирд╛рд╣рд░реВ рдкрд╣реБрдБрдЪ рдЧрд░реНрди, рдирдХреНрд╕рд╛рд╣рд░реВ рд╡реНрдпрд╡рд╕реНрдерд╛рдкрди рдЧрд░реНрди, рд░ "рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдВрд╕рд╛рд░" рд╕рдБрдЧ рд╕рдЮреНрдЪрд╛рд░ рдЧрд░реНрди рдЕрдиреБрдорддрд┐ рджрд┐рдиреНрдЫ - perf рдШрдЯрдирд╛рд╣рд░реВ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрдиреБрд╣реЛрд╕реН, рд╣рд╛рд░реНрдбрд╡реЗрдпрд░ рдирд┐рдпрдиреНрддреНрд░рдг рдЧрд░реНрдиреБрд╣реЛрд╕реН (рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐, рдкреНрдпрд╛рдХреЗрдЯрд╣рд░реВ рдкреБрди: рдирд┐рд░реНрджреЗрд╢рд┐рдд рдЧрд░реНрдиреБрд╣реЛрд╕реН), рдЖрджрд┐ред

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

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

BPF_CALL_0(bpf_get_smp_processor_id)
{
    return smp_processor_id();
}

BPF рд╕рд╣рд╛рдпрдХ рдкреНрд░рдХрд╛рд░реНрдп рдкрд░рд┐рднрд╛рд╖рд╛рд╣рд░реВ рд▓рд┐рдирдХреНрд╕ рдкреНрд░рдгрд╛рд▓реА рдХрд▓ рдкрд░рд┐рднрд╛рд╖рд╛рд╣рд░реВ рдЬрд╕реНрддреИ рдЫрдиреНред рдпрд╣рд╛рдБ, рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐, рдПрдЙрдЯрд╛ рдкреНрд░рдХрд╛рд░реНрдп рдкрд░рд┐рднрд╛рд╖рд┐рдд рдЧрд░рд┐рдПрдХреЛ рдЫ рдЬрд╕рдорд╛ рдХреБрдиреИ рддрд░реНрдХ рдЫреИрдиред (рдПрдХ рдкреНрд░рдХрд╛рд░реНрдп рдЬрд╕рд▓реЗ рд▓рд┐рдиреНрдЫ, рднрдиреНрдиреБрд╣реЛрд╕реН, рдореНрдпрд╛рдХреНрд░реЛ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рддреАрди рддрд░реНрдХрд╣рд░реВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдЧрд░рд┐рдПрдХреЛ рдЫ BPF_CALL_3ред рддрд░реНрдХрд╣рд░реВрдХреЛ рдЕрдзрд┐рдХрддрдо рд╕рдВрдЦреНрдпрд╛ рдкрд╛рдБрдЪ рд╣реЛред) рдпрджреНрдпрдкрд┐, рдпреЛ рдкрд░рд┐рднрд╛рд╖рд╛рдХреЛ рдкрд╣рд┐рд▓реЛ рднрд╛рдЧ рдорд╛рддреНрд░ рд╣реЛред рджреЛрд╕реНрд░реЛ рднрд╛рдЧ рдкреНрд░рдХрд╛рд░ рд╕рдВрд░рдЪрдирд╛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдЧрд░реНрди рдЫ struct bpf_func_proto, рдЬрд╕рдорд╛ рд╕рд╣рд╛рдпрдХ рдкреНрд░рдХрд╛рд░реНрдпрдХреЛ рд╡рд┐рд╡рд░рдг рд╕рдорд╛рд╡реЗрд╢ рдЫ рдЬреБрди рдкреНрд░рдорд╛рдгрд┐рдХрд░рдгрдХрд░реНрддрд╛рд▓реЗ рдмреБрдЭреНрджрдЫ:

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

рд╕рд╣рд╛рдпрдХ рдХрд╛рд░реНрдпрд╣рд░реВ рджрд░реНрддрд╛ рдЧрд░реНрджреИ

рдпреЛ рдкреНрд░рдХрд╛рд░реНрдп рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдирдХреЛ рд▓рд╛рдЧрд┐ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдкреНрд░рдХрд╛рд░рдХреЛ BPF рдХрд╛рд░реНрдпрдХреНрд░рдорд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐, рддрд┐рдиреАрд╣рд░реВрд▓реЗ рдпрд╕рд▓рд╛рдИ рджрд░реНрддрд╛ рдЧрд░реНрдиреБрдкрд░реНрдЫ, рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐ рдкреНрд░рдХрд╛рд░рдХреЛ рд▓рд╛рдЧрд┐ BPF_PROG_TYPE_XDP рдПрдХ рдкреНрд░рдХрд╛рд░реНрдп рдХрд░реНрдиреЗрд▓ рдорд╛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдЧрд░рд┐рдПрдХреЛ рдЫ xdp_func_proto, рдЬрд╕рд▓реЗ рд╕рд╣рд╛рдпрдХ рдкреНрд░рдХрд╛рд░реНрдп ID рдмрд╛рдЯ XDP рд▓реЗ рдпреЛ рдкреНрд░рдХрд╛рд░реНрдпрд▓рд╛рдИ рд╕рдорд░реНрдерди рдЧрд░реНрдЫ рд╡рд╛ рдЧрд░реНрджреИрди рднрдиреЗрд░ рдирд┐рд░реНрдзрд╛рд░рдг рдЧрд░реНрдЫред рд╣рд╛рдореНрд░реЛ рдХрд╛рд░реНрдп рд╣реЛ рд╕рдорд░реНрдерди рдЧрд░реНрджрдЫ:

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

рдирдпрд╛рдБ BPF рдХрд╛рд░реНрдпрдХреНрд░рдо рдкреНрд░рдХрд╛рд░рд╣рд░реВ рдлрд╛рдЗрд▓рдорд╛ "рдкрд░рд┐рднрд╛рд╖рд┐рдд" рдЫрдиреН include/linux/bpf_types.h рдореНрдпрд╛рдХреНрд░реЛ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрджреИ BPF_PROG_TYPEред рдЙрджреНрдзрд░рдгрд╣рд░реВрдорд╛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдЧрд░рд┐рдПрдХреЛ рдЫ рдХрд┐рдирднрдиреЗ рдпреЛ рддрд╛рд░реНрдХрд┐рдХ рдкрд░рд┐рднрд╛рд╖рд╛ рд╣реЛ, рд░ C рднрд╛рд╖рд╛рдХрд╛ рд╕рд░реНрддрд╣рд░реВрдорд╛ рдареЛрд╕ рд╕рдВрд░рдЪрдирд╛рд╣рд░реВрдХреЛ рд╕рдореНрдкреВрд░реНрдг рд╕реЗрдЯрдХреЛ рдкрд░рд┐рднрд╛рд╖рд╛ рдЕрдиреНрдп рдард╛рдЙрдБрд╣рд░реВрдорд╛ рд╣реБрдиреНрдЫред рд╡рд┐рд╢реЗрд╖ рдЧрд░реА, рдлрд╛рдЗрд▓рдорд╛ kernel/bpf/verifier.c рдлрд╛рдЗрд▓рдмрд╛рдЯ рд╕рдмреИ рдкрд░рд┐рднрд╛рд╖рд╛рд╣рд░реВ bpf_types.h рд╕рдВрд░рдЪрдирд╛рд╣рд░реВрдХреЛ рдПрд░реНрд░реЗ рдмрдирд╛рдЙрди рдкреНрд░рдпреЛрдЧ рдЧрд░рд┐рдиреНрдЫ bpf_verifier_ops[]:

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

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

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

рдпрд╣рд╛рдБ рд╣рд╛рдореА рд╣рд╛рдореНрд░реЛ рдкрд░рд┐рдЪрд┐рдд рдкреНрд░рдХрд╛рд░реНрдп рджреЗрдЦреНрдЫреМрдВ xdp_func_proto, рдЬрд╕рд▓реЗ рдкреНрд░рддреНрдпреЗрдХ рдкрдЯрдХ рдЪреБрдиреМрддреАрдХреЛ рд╕рд╛рдордирд╛ рдЧрд░реНрджрд╛ рдкреНрд░рдорд╛рдгрд┐рдХрд░рдг рдЪрд▓рд╛рдЙрдиреЗрдЫ рдХреЗрд╣рд┐ BPF рдХрд╛рд░реНрдпрдХреНрд░рдо рднрд┐рддреНрд░ рдХрд╛рд░реНрдпрд╣рд░реВ, рд╣реЗрд░реНрдиреБрд╣реЛрд╕реН verifier.c.

рдХрд╛рд▓реНрдкрдирд┐рдХ BPF рдХрд╛рд░реНрдпрдХреНрд░рдорд▓реЗ рдкреНрд░рдХрд╛рд░реНрдпрд▓рд╛рдИ рдХрд╕рд░реА рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдЫ рд╣реЗрд░реМрдВ bpf_get_smp_processor_idред рдпреЛ рдЧрд░реНрдирдХреЛ рд▓рд╛рдЧрд┐, рд╣рд╛рдореА рд╣рд╛рдореНрд░реЛ рдЕрдШрд┐рд▓реНрд▓реЛ рдЦрдгреНрдбрдмрд╛рдЯ рдХрд╛рд░реНрдпрдХреНрд░рдорд▓рд╛рдИ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдкреБрди: рд▓реЗрдЦреНрдЫреМрдВ:

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

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

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

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

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

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

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

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

Disassembly of section xdp/simple:

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

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

рдкрд╣рд┐рд▓реЛ рдкрдЩреНрдХреНрддрд┐рдорд╛ рд╣рд╛рдореА рдирд┐рд░реНрджреЗрд╢рдирд╣рд░реВ рджреЗрдЦреНрдЫреМрдВ call, рдкреНрдпрд╛рд░рд╛рдорд┐рдЯрд░ IMM рдЬреБрди 8 рдХреЛ рдмрд░рд╛рдмрд░ рдЫ, рд░ SRC_REG - рд╢реВрдиреНрдпред рдкреНрд░рдорд╛рдгрд┐рдХрд░рдгрдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рдпреЛрдЧ рдЧрд░рд┐рдПрдХреЛ ABI рд╕рдореНрдЭреМрддрд╛ рдЕрдиреБрд╕рд╛рд░, рдпреЛ рд╕рд╣рд╛рдпрдХ рдкреНрд░рдХрд╛рд░реНрдп рдирдореНрдмрд░ рдЖрда рдХреЛ рд▓рд╛рдЧреА рдХрд▓ рд╣реЛред рдПрдХ рдкрдЯрдХ рдпреЛ рд╕реБрд░реБ рднрдПрдкрдЫрд┐, рддрд░реНрдХ рд╕рд░рд▓ рдЫред рджрд░реНрддрд╛рдмрд╛рдЯ рдореВрд▓реНрдп рдлрд┐рд░реНрддрд╛ рдЧрд░реНрдиреБрд╣реЛрд╕реН r0 рдорд╛ рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдЧрд░рд┐рдпреЛ r1 рд░ рд▓рд╛рдЗрдирд╣рд░реБ 2,3 рдорд╛ рдпреЛ рдЯрд╛рдЗрдк рдорд╛ рд░реВрдкрд╛рдиреНрддрд░рд┐рдд рдЫ u32 - рдорд╛рдерд┐рд▓реНрд▓реЛ 32 рдмрд┐рдЯрд╣рд░реВ рдЦрд╛рд▓реА рдЫрдиреНред рд▓рд╛рдЗрди 4,5,6,7 рдорд╛ рд╣рд╛рдореА 2 рдлрд░реНрдХрд╛рдЙрдБрдЫреМрдВ (XDP_PASS) рд╡рд╛ рез (XDP_DROP) рд░реЗрдЦрд╛ реж рдмрд╛рдЯ рд╕рд╣рд╛рдпрдХ рдкреНрд░рдХрд╛рд░реНрдпрд▓реЗ рд╢реВрдиреНрдп рд╡рд╛ рдЧреИрд░-рд╢реВрдиреНрдп рдорд╛рди рдлрд░реНрдХрд╛рдПрдХреЛрдорд╛ рдирд┐рд░реНрднрд░ рдЧрд░реНрджрдЫред

рдЖрдлреИрд▓рд╛рдИ рдкрд░реАрдХреНрд╖рдг рдЧрд░реМрдВ: рдХрд╛рд░реНрдпрдХреНрд░рдо рд▓реЛрдб рдЧрд░реНрдиреБрд╣реЛрд╕реН рд░ рдЖрдЙрдЯрдкреБрдЯ рд╣реЗрд░реНрдиреБрд╣реЛрд╕реН bpftool prog dump xlated:

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

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

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

рдареАрдХ рдЫ, рдкреНрд░рдорд╛рдгрд┐рдХрд░рдгрдХрд░реНрддрд╛рд▓реЗ рд╕рд╣реА рдХрд░реНрдиреЗрд▓-рд╣реЗрд▓реНрдкрд░ рдлреЗрд▓рд╛ рдкрд╛рд░реНрдпреЛред

рдЙрджрд╛рд╣рд░рдг: рддрд░реНрдХрд╣рд░реВ рдкрд╛рд╕ рдЧрд░реНрджреИ рд░ рдЕрдиреНрддрдорд╛ рдХрд╛рд░реНрдпрдХреНрд░рдо рдЪрд▓рд╛рдЙрдБрджреИ!

рд╕рдмреИ рд░рди-рд╕реНрддрд░ рд╕рд╣рдпреЛрдЧреА рдкреНрд░рдХрд╛рд░реНрдпрд╣рд░реВрд╕рдБрдЧ рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдЫ

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

рд╕рд╣рд╛рдпрдХ рдкреНрд░рдХрд╛рд░реНрдпрд╣рд░реВрдорд╛ рдкреНрдпрд╛рд░рд╛рдорд┐рдЯрд░рд╣рд░реВ рджрд░реНрддрд╛рд╣рд░реВрдорд╛ рдкрд╛рд╕ рд╣реБрдиреНрдЫрдиреН r1-r5, рд░ рдорд╛рди рджрд░реНрддрд╛рдорд╛ рдлрд░реНрдХрд╛рдЗрдиреНрдЫ r0ред рддреНрдпрд╣рд╛рдБ рдкрд╛рдБрдЪ рднрдиреНрджрд╛ рдмрдвреА рддрд░реНрдХрд╣рд░реВ рд▓рд┐рдиреЗ рдХреБрдиреИ рдкреНрд░рдХрд╛рд░реНрдпрд╣рд░реВ рдЫреИрдирдиреН, рд░ рддрд┐рдиреАрд╣рд░реВрдХрд╛ рд▓рд╛рдЧрд┐ рд╕рдорд░реНрдерди рднрд╡рд┐рд╖реНрдпрдорд╛ рдердкрд┐рдиреЗ рдЕрдкреЗрдХреНрд╖рд╛ рдЧрд░рд┐рдПрдХреЛ рдЫреИрдиред

рдирдпрд╛рдБ рдХрд░реНрдиреЗрд▓ рд╣реЗрд▓реНрдкрд░ рд░ BPF рд▓реЗ рдкреНрдпрд╛рд░рд╛рдорд┐рдЯрд░рд╣рд░реВ рдХрд╕рд░реА рдкрд╛рд╕ рдЧрд░реНрдЫ рднрдиреЗрд░ рд╣реЗрд░реМрдВред рдлреЗрд░рд┐ рд▓реЗрдЦреМрдВ xdp-simple.bpf.c рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ (рдмрд╛рдБрдХреА рд░реЗрдЦрд╛рд╣рд░реВ рдкрд░рд┐рд╡рд░реНрддрди рднрдПрдХрд╛ рдЫреИрдирдиреН):

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

рд╣рд╛рдореНрд░реЛ рдХрд╛рд░реНрдпрдХреНрд░рдорд▓реЗ 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 рд╡рд╛ рдПрдХ рдЕрдирдиреНрдд рд▓реВрдк: рд╣рд╛рдореНрд░реЛ рд▓реЛрдбрд░ рдХрд╛рд░реНрдпрдХреНрд░рдо рдмрд╛рд╣рд┐рд░ рдирд┐рд╕реНрдХрдиреЗрдЫ, рддрд░ рдШрдЯрдирд╛ рд╕реНрд░реЛрддрдорд╛ рдЬрдбрд╛рди рднрдПрдХреЛрд▓реЗ BPF рдХрд╛рд░реНрдпрдХреНрд░рдо рдорд╛рд░рд┐рдиреЗрдЫреИрдиред рд╕рдлрд▓ рдбрд╛рдЙрдирд▓реЛрдб рд░ рдЬрдбрд╛рди рдкрдЫрд┐, рдХрд╛рд░реНрдпрдХреНрд░рдо рдкреНрд░рддреНрдпреЗрдХ рдиреЗрдЯрд╡рд░реНрдХ рдкреНрдпрд╛рдХреЗрдЯрдорд╛ рдЖрдЗрдкреБрдЧреНрджрд╛ рд╕реБрд░реБ рдЧрд░рд┐рдиреЗрдЫ lo.

рдХрд╛рд░реНрдпрдХреНрд░рдо рдбрд╛рдЙрдирд▓реЛрдб рдЧрд░реМрдВ рд░ рдЗрдиреНрдЯрд░рдлреЗрд╕ рд╣реЗрд░реМрдВ lo:

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

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

$ ping -c1 localhost

рд░ рдЕрдм рдбрд┐рдмрдЧ рднрд░реНрдЪреБрдЕрд▓ рдлрд╛рдЗрд▓рдХреЛ рд╕рд╛рдордЧреНрд░реА рд╣реЗрд░реМрдВ /sys/kernel/debug/tracing/trace_pipe, рдЬрд╕рдорд╛ bpf_printk рдЖрдлреНрдирд╛ рд╕рдиреНрджреЗрд╢рд╣рд░реВ рд▓реЗрдЦреНрдЫрдиреН:

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

рджреБрдИрд╡рдЯрд╛ рдкреНрдпрд╛рдХреЗрдЬ рднреЗрдЯрд┐рдП lo рд░ CPU0 рдорд╛ рдкреНрд░рд╢реЛрдзрди рдЧрд░рд┐рдпреЛ - рд╣рд╛рдореНрд░реЛ рдкрд╣рд┐рд▓реЛ рдкреВрд░реНрдг рдЕрд░реНрдерд╣реАрди BPF рдХрд╛рд░реНрдпрдХреНрд░рдорд▓реЗ рдХрд╛рдо рдЧрд░реНрдпреЛ!

рдпреЛ рдзреНрдпрд╛рди рджрд┐рди рд▓рд╛рдпрдХ рдЫ bpf_printk рдпреЛ рдбрд┐рдмрдЧ рдлрд╛рдЗрд▓рдорд╛ рд▓реЗрдЦреНрдиреЗ рдХреБрдиреИ рдкрдирд┐ рдХреБрд░рд╛рдХреЛ рд▓рд╛рдЧрд┐ рд╣реЛрдЗрди: рдпреЛ рдЙрддреНрдкрд╛рджрдирдорд╛ рдкреНрд░рдпреЛрдЧрдХреЛ рд▓рд╛рдЧрд┐ рд╕рдмреИрднрдиреНрджрд╛ рд╕рдлрд▓ рд╕рд╣рд╛рдпрдХ рд╣реЛрдЗрди, рддрд░ рд╣рд╛рдореНрд░реЛ рд▓рдХреНрд╖реНрдп рдХреЗрд╣рд┐ рд╕рд░рд▓ рджреЗрдЦрд╛рдЙрдиреЗ рдерд┐рдпреЛред

BPF рдХрд╛рд░реНрдпрдХреНрд░рдорд╣рд░реВрдмрд╛рдЯ рдирдХреНрд╕рд╛рд╣рд░реВ рдкрд╣реБрдБрдЪ рдЧрд░реНрджреИ

рдЙрджрд╛рд╣рд░рдг: BPF рдХрд╛рд░реНрдпрдХреНрд░рдордмрд╛рдЯ рдирдХреНрд╕рд╛ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрджреИ

рдЕрдШрд┐рд▓реНрд▓реЛ рдЦрдгреНрдбрд╣рд░реВрдорд╛ рд╣рд╛рдореАрд▓реЗ рдкреНрд░рдпреЛрдЧрдХрд░реНрддрд╛ рд╕реНрдкреЗрд╕рдмрд╛рдЯ рдирдХреНрд╕рд╛ рдХрд╕рд░реА рдмрдирд╛рдЙрдиреЗ рд░ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреЗ рднрдиреЗрд░ рд╕рд┐рдХреЗрдХрд╛ рдерд┐рдпреМрдВ, рд░ рдЕрдм рдХрд░реНрдиреЗрд▓ рднрд╛рдЧ рд╣реЗрд░реМрдВред рд╕рд╛рдорд╛рдиреНрдп рд░реВрдкрдорд╛, рдЙрджрд╛рд╣рд░рдгрдХреЛ рд╕рд╛рде рд╕реБрд░реВ рдЧрд░реМрдВред рд╣рд╛рдореНрд░реЛ рдХрд╛рд░реНрдпрдХреНрд░рдо рдкреБрди: рд▓реЗрдЦреМрдВ xdp-simple.bpf.c рдирд┐рдореНрди рдЕрдиреБрд╕рд╛рд░:

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

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

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

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

    *val += 1;

    return XDP_PASS;
}

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

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

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

рдЙрд╣рд╛рдБрд╕рдБрдЧ рдЬреЛрдбрд┐рдПрдХреЛ рдЫ рднрдиреЗрд░ рдЬрд╛рдБрдЪ рдЧрд░реМрдВ lo рд░ рдХреЗрд╣реА рдкреНрдпрд╛рдХреЗрдЯ рдкрдард╛рдЙрдиреБрд╣реЛрд╕реН:

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

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

рдЕрдм рдПрд░реЗрдХреЛ рд╕рд╛рдордЧреНрд░реА рд╣реЗрд░реМрдВ:

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

рд▓рдЧрднрдЧ рд╕рдмреИ рдкреНрд░рдХреНрд░рд┐рдпрд╛рд╣рд░реВ CPU7 рдорд╛ рдкреНрд░рд╢реЛрдзрди рдЧрд░рд┐рдПрдХреЛ рдерд┐рдпреЛред рдпреЛ рд╣рд╛рдореНрд░реЛ рд▓рд╛рдЧрд┐ рдорд╣рддреНрддреНрд╡рдкреВрд░реНрдг рдЫреИрди, рдореБрдЦреНрдп рдХреБрд░рд╛ рдпреЛ рд╣реЛ рдХрд┐ рдХрд╛рд░реНрдпрдХреНрд░рдорд▓реЗ рдХрд╛рдо рдЧрд░реНрдЫ рд░ рд╣рд╛рдореАрд▓реЗ BPF рдХрд╛рд░реНрдпрдХреНрд░рдорд╣рд░реВрдмрд╛рдЯ рдирдХреНрд╕рд╛рд╣рд░реВ рдХрд╕рд░реА рдкрд╣реБрдБрдЪ рдЧрд░реНрдиреЗ рднрдиреЗрд░ рдмреБрдЭреНрджрдЫреМрдВ - рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ ╤Е╨╡╨╗╨┐╨╡╤А╨╛╨▓ bpf_mp_*.

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

рддреНрдпрд╕реЛрднрдП, рд╣рд╛рдореА рдХрд▓рд╣рд░реВ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ BPF рдХрд╛рд░реНрдпрдХреНрд░рдордмрд╛рдЯ рдирдХреНрд╕рд╛ рдкрд╣реБрдБрдЪ рдЧрд░реНрди рд╕рдХреНрдЫреМрдВ

val = bpf_map_lookup_elem(&woo, &key);

рдЬрд╣рд╛рдБ рд╕рд╣рд╛рдпрдХ рдкреНрд░рдХрд╛рд░реНрдп рдЬрд╕реНрддреЛ рджреЗрдЦрд┐рдиреНрдЫ

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

рддрд░ рд╣рд╛рдореА рдПрдХ рд╕реВрдЪрдХ рдкрд╛рд╕ рдЧрд░реНрджреИрдЫреМрдВ &woo рдЕрдЬреНрдЮрд╛рдд рд╕рдВрд░рдЪрдирд╛рдорд╛ struct { ... }...

рдпрджрд┐ рд╣рд╛рдореА рдкреНрд░реЛрдЧреНрд░рд╛рдо рдПрд╕реЗрдореНрдмрд▓рд░рд▓рд╛рдИ рд╣реЗрд░реНрдЫреМрдВ рднрдиреЗ, рд╣рд╛рдореА рддреНрдпреЛ рдорд╛рди рджреЗрдЦреНрдЫреМрдВ &woo рд╡рд╛рд╕реНрддрд╡рдорд╛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдЧрд░рд┐рдПрдХреЛ рдЫреИрди (рд▓рд╛рдЗрди рек):

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

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

Disassembly of section xdp/simple:

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

рд░ рд╕реНрдерд╛рдирд╛рдиреНрддрд░рдгрдорд╛ рд╕рдорд╛рд╡реЗрд╢ рдЫ:

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

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

рддрд░ рдпрджрд┐ рд╣рд╛рдореАрд▓реЗ рдкрд╣рд┐рд▓реЗ рдиреИ рд▓реЛрдб рдЧрд░рд┐рдПрдХреЛ рдкреНрд░реЛрдЧреНрд░рд╛рдорд▓рд╛рдИ рд╣реЗрд░реНрдЫреМрдВ рднрдиреЗ, рд╣рд╛рдореАрд▓реЗ рд╕рд╣реА рдирдХреНрд╕рд╛ (рд▓рд╛рдЗрди 4) рдорд╛ рдПрдХ рд╕реВрдЪрдХ рджреЗрдЦреНрдЫреМрдВ:

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

рдпрд╕реИрд▓реЗ, рд╣рд╛рдореА рдирд┐рд╖реНрдХрд░реНрд╖рдорд╛ рдкреБрдЧреНрди рд╕рдХреНрдЫреМрдВ рдХрд┐ рд╣рд╛рдореНрд░реЛ рд▓реЛрдбрд░ рдХрд╛рд░реНрдпрдХреНрд░рдо рд╕реБрд░реБ рдЧрд░реНрдиреЗ рд╕рдордпрдорд╛, рд▓рд┐рдЩреНрдХ &woo рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╕рдВрдЧ рдХреЗрд╣рд┐ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдЧрд░рд┐рдпреЛ libbpfред рдкрд╣рд┐рд▓реЗ рд╣рд╛рдореА рдЖрдЙрдЯрдкреБрдЯ рд╣реЗрд░реНрдиреЗрдЫреМрдВ strace:

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

рд╣рд╛рдореА рддреНрдпреЛ рджреЗрдЦреНрдЫреМрдВ libbpf рдирдХреНрд╕рд╛ рдмрдирд╛рдП woo рд░ рддреНрдпрд╕рдкрдЫрд┐ рд╣рд╛рдореНрд░реЛ рдХрд╛рд░реНрдпрдХреНрд░рдо рдбрд╛рдЙрдирд▓реЛрдб simpleред рд╣рд╛рдореА рдХрд╕рд░реА рдХрд╛рд░реНрдпрдХреНрд░рдо рд▓реЛрдб рдЧрд░реНрдЫреМрдВ рднрдиреЗрд░ рдирдЬрд┐рдХрдмрд╛рдЯ рд╣реЗрд░реМрдВ:

  • рдХрд▓ xdp_simple_bpf__open_and_load рдлрд╛рдЗрд▓рдмрд╛рдЯ xdp-simple.skel.h
  • рдЬрд╕рд▓реЗ рдЧрд░реНрджрд╛ рд╣реБрдиреНрдЫ xdp_simple_bpf__load рдлрд╛рдЗрд▓рдмрд╛рдЯ xdp-simple.skel.h
  • рдЬрд╕рд▓реЗ рдЧрд░реНрджрд╛ рд╣реБрдиреНрдЫ bpf_object__load_skeleton рдлрд╛рдЗрд▓рдмрд╛рдЯ libbpf/src/libbpf.c
  • рдЬрд╕рд▓реЗ рдЧрд░реНрджрд╛ рд╣реБрдиреНрдЫ bpf_object__load_xattr рдмрд╛рдЯ libbpf/src/libbpf.c

рдЕрдиреНрддрд┐рдо рдкреНрд░рдХрд╛рд░реНрдп, рдЕрдиреНрдп рдЪреАрдЬрд╣рд░реВ рдмреАрдЪ, рдХрд▓ рдЧрд░реНрдиреЗрдЫ bpf_object__create_maps, рдЬрд╕рд▓реЗ рдЕрд╡рд╕реНрдерд┐рдд рдирдХреНрд╕рд╛рд╣рд░реВ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрджрдЫ рд╡рд╛ рдЦреЛрд▓реНрдЫ, рддрд┐рдиреАрд╣рд░реВрд▓рд╛рдИ рдлрд╛рдЗрд▓ рд╡рд░реНрдгрдирдХрд░реНрддрд╛рд╣рд░реВрдорд╛ рдкрд░рд┐рдгрдд рдЧрд░реНрджрдЫред (рдпрд╣рд╛рдБ рд╣рд╛рдореА рджреЗрдЦреНрдЫреМрдВ BPF_MAP_CREATE рдЖрдЙрдЯрдкреБрдЯ рдорд╛ strace.) рдЕрд░реНрдХреЛ рдкреНрд░рдХрд╛рд░реНрдп рднрдирд┐рдиреНрдЫ bpf_object__relocate рд░ рдпреЛ рдЙрд╣рд╛рдБ рд╣реЛ рдЬрд╕рд▓реЗ рд╣рд╛рдореАрд▓рд╛рдИ рдЪрд╛рд╕реЛ рд░рд╛рдЦреНрдЫ, рдХрд┐рдирдХрд┐ рд╣рд╛рдореАрд▓реЗ рджреЗрдЦреЗрдХрд╛ рдХреБрд░рд╛ рд╕рдореНрдЭрдиреНрдЫреМрдВ woo рд╕реНрдерд╛рдирд╛рдиреНрддрд░рдг рддрд╛рд▓рд┐рдХрд╛рдорд╛ред рдпрд╕рд▓рд╛рдИ рдЕрдиреНрд╡реЗрд╖рдг рдЧрд░реНрджреИ, рд╣рд╛рдореА рдЕрдиреНрддрддрдГ рдХрд╛рд░реНрдпрдорд╛ рдЖрдлреВрд▓рд╛рдИ рднреЗрдЯреНрдЯрд╛рдЙрдБрдЫреМрдВ bpf_program__relocate, рдЬреБрди рдирдХреНрд╕рд╛ рд╕реНрдерд╛рдирд╛рдиреНрддрд░рдгрд╕рдБрдЧ рд╕рдореНрдмрдиреНрдзрд┐рдд рдЫ:

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

рддреНрдпрд╕реИрд▓реЗ рд╣рд╛рдореА рд╣рд╛рдореНрд░реЛ рдирд┐рд░реНрджреЗрд╢рди рд▓рд┐рдиреНрдЫреМрдВ

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

рд░ рдпрд╕рдорд╛ рд╕реНрд░реЛрдд рджрд░реНрддрд╛ рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрди рдЧрд░реНрдиреБрд╣реЛрд╕реН BPF_PSEUDO_MAP_FD, рд░ рд╣рд╛рдореНрд░реЛ рдирдХреНрд╕рд╛рдХреЛ рдлрд╛рдЗрд▓ рд╡рд░реНрдгрдирдХрд░реНрддрд╛рдорд╛ рдкрд╣рд┐рд▓реЛ IMM рд░, рдпрджрд┐ рдпреЛ рдмрд░рд╛рдмрд░ рдЫ рднрдиреЗ, рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐, 0xdeadbeef, рддреНрдпрд╕рдкрдЫрд┐ рдкрд░рд┐рдгрд╛рдордХреЛ рд░реВрдкрдорд╛ рд╣рд╛рдореАрд▓реЗ рдирд┐рд░реНрджреЗрд╢рди рдкреНрд░рд╛рдкреНрдд рдЧрд░реНрдиреЗрдЫреМрдВ

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

рдпрд╕рд░реА рдирдХреНрд╕рд╛ рдЬрд╛рдирдХрд╛рд░реА рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд▓реЛрдб рдЧрд░рд┐рдПрдХреЛ BPF рдХрд╛рд░реНрдпрдХреНрд░рдордорд╛ рд╕реНрдерд╛рдирд╛рдиреНрддрд░рдг рдЧрд░рд┐рдиреНрдЫред рдпрд╕ рдЕрд╡рд╕реНрдерд╛рдорд╛, рдирдХреНрд╕рд╛ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫ BPF_MAP_CREATE, рд░ ID рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдЦреЛрд▓рд┐рдпреЛ BPF_MAP_GET_FD_BY_ID.

рдХреБрд▓, рдкреНрд░рдпреЛрдЧ рдЧрд░реНрджрд╛ libbpf рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдирд┐рдореНрди рдЫ:

  • рд╕рдВрдХрд▓рдирдХреЛ рдХреНрд░рдордорд╛, рд░реЗрдХрд░реНрдбрд╣рд░реВ рдирдХреНрд╕рд╛рдорд╛ рд▓рд┐рдЩреНрдХрд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐ рд╕реНрдерд╛рдирд╛рдиреНрддрд░рдг рддрд╛рд▓рд┐рдХрд╛рдорд╛ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░рд┐рдиреНрдЫ
  • libbpf ELF рд╡рд╕реНрддреБ рдкреБрд╕реНрддрдХ рдЦреЛрд▓реНрдЫ, рд╕рдмреИ рдкреНрд░рдпреЛрдЧ рдЧрд░рд┐рдПрдХрд╛ рдирдХреНрд╕рд╛рд╣рд░реВ рдлреЗрд▓рд╛ рдкрд╛рд░реНрдЫ рд░ рддрд┐рдиреАрд╣рд░реВрдХрд╛ рд▓рд╛рдЧрд┐ рдлрд╛рдЗрд▓ рд╡рд░реНрдгрдирдХрд░реНрддрд╛рд╣рд░реВ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрджрдЫ
  • рдлрд╛рдЗрд▓ рд╡рд░реНрдгрдирдХрд░реНрддрд╛рд╣рд░реВ рдирд┐рд░реНрджреЗрд╢рдирдХреЛ рднрд╛рдЧрдХреЛ рд░реВрдкрдорд╛ рдХрд░реНрдиреЗрд▓рдорд╛ рд▓реЛрдб рд╣реБрдиреНрдЫрдиреН LD64

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

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

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

(рдкреВрд░реНрдг рдХреЛрдб рдлреЗрд▓рд╛ рдкрд╛рд░реНрди рд╕рдХрд┐рдиреНрдЫ рд▓рд┐рдЩреНрдХ)ред рддреНрдпрд╕реИрд▓реЗ рд╣рд╛рдореА рд╣рд╛рдореНрд░реЛ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рд╡рд┐рд╕реНрддрд╛рд░ рдЧрд░реНрди рд╕рдХреНрдЫреМрдВ:

  • рдХрд╛рд░реНрдпрдХреНрд░рдо рд▓реЛрдб рдЧрд░реНрджрд╛, рдкреНрд░рдорд╛рдгрд┐рдХрд░рдгрдХрд░реНрддрд╛рд▓реЗ рдирдХреНрд╕рд╛рдХреЛ рд╕рд╣реА рдкреНрд░рдпреЛрдЧ рдЬрд╛рдБрдЪ рдЧрд░реНрдЫ рд░ рд╕рдореНрдмрдиреНрдзрд┐рдд рд╕рдВрд░рдЪрдирд╛рдХреЛ рдареЗрдЧрд╛рдирд╛ рд▓реЗрдЦреНрдЫред struct bpf_map

рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ ELF рдмрд╛рдЗрдирд░реА рдбрд╛рдЙрдирд▓реЛрдб рдЧрд░реНрджрд╛ libbpf рддреНрдпрд╣рд╛рдБ рдзреЗрд░реИ рдХреБрд░рд╛ рднрдЗрд░рд╣реЗрдХреЛ рдЫ, рддрд░ рд╣рд╛рдореА рдЕрдиреНрдп рд▓реЗрдЦрд╣рд░реВрдорд╛ рдЫрд▓рдлрд▓ рдЧрд░реНрдиреЗрдЫреМрдВред

libbpf рдмрд┐рдирд╛ рдХрд╛рд░реНрдпрдХреНрд░рдо рд░ рдирдХреНрд╕рд╛ рд▓реЛрдб рдЧрд░реНрджреИ

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

рддрд░реНрдХрд▓рд╛рдИ рдкрдЫреНрдпрд╛рдЙрди рд╕рдЬрд┐рд▓реЛ рдмрдирд╛рдЙрди, рд╣рд╛рдореА рдпреА рдЙрджреНрджреЗрд╢реНрдпрд╣рд░реВрдХреЛ рд▓рд╛рдЧрд┐ рд╣рд╛рдореНрд░реЛ рдЙрджрд╛рд╣рд░рдг рдкреБрди: рд▓реЗрдЦреНрдиреЗрдЫреМрдВ xdp-simpleред рдпрд╕ рдЙрджрд╛рд╣рд░рдгрдорд╛ рдЫрд▓рдлрд▓ рдЧрд░рд┐рдПрдХреЛ рдХрд╛рд░реНрдпрдХреНрд░рдордХреЛ рдкреВрд░реНрдг рд░ рдереЛрд░реИ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХреЛрдб рдпрд╕рдорд╛ рдлреЗрд▓рд╛ рдкрд╛рд░реНрди рд╕рдХрд┐рдиреНрдЫ рд╕рд╛рд░.

рд╣рд╛рдореНрд░реЛ рдЖрд╡реЗрджрди рдХреЛ рддрд░реНрдХ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдЫ:

  • рдПрдХ рдкреНрд░рдХрд╛рд░рдХреЛ рдирдХреНрд╕рд╛ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрдиреБрд╣реЛрд╕реН BPF_MAP_TYPE_ARRAY рдЖрджреЗрд╢ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ BPF_MAP_CREATE,
  • рдпреЛ рдирдХреНрд╕рд╛ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрдиреЗ рдХрд╛рд░реНрдпрдХреНрд░рдо рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрдиреБрд╣реЛрд╕реН,
  • рдХрд╛рд░реНрдпрдХреНрд░рдорд▓рд╛рдИ рдЗрдиреНрдЯрд░рдлреЗрд╕рдорд╛ рдЬрдбрд╛рди рдЧрд░реНрдиреБрд╣реЛрд╕реН lo,

рдЬреБрди рдорд╛рдирд╡рдорд╛ рдЕрдиреБрд╡рд╛рдж рд╣реБрдиреНрдЫ

int main(void)
{
    int map_fd, prog_fd;

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

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

    xdp_attach(1, prog_fd);
}

рдпреЛ рдЫ map_create рд╣рд╛рдореАрд▓реЗ рдкреНрд░рдгрд╛рд▓реА рдХрд▓рдХреЛ рдмрд╛рд░реЗрдорд╛ рдкрд╣рд┐рд▓реЛ рдЙрджрд╛рд╣рд░рдгрдорд╛ рдЧрд░реЗ рдЬрд╕реНрддреИ рдирдХреНрд╕рд╛ рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрджрдЫ bpf - "рдХрд░реНрдиреЗрд▓, рдХреГрдкрдпрд╛ рдорд▓рд╛рдИ 8 рддрддреНрд╡рд╣рд░реВрдХреЛ рдПрд░реНрд░реЗрдХреЛ рд░реВрдкрдорд╛ рдирдпрд╛рдБ рдирдХреНрд╕рд╛ рдмрдирд╛рдЙрдиреБрд╣реЛрд╕реН __u64 рд░ рдорд▓рд╛рдИ рдлрд╛рдЗрд▓ рд╡рд░реНрдгрдирдХрд░реНрддрд╛ рдлрд┐рд░реНрддрд╛ рджрд┐рдиреБрд╣реЛрд╕реН":

static int map_create()
{
    union bpf_attr attr;

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

рдХрд╛рд░реНрдпрдХреНрд░рдо рдкрдирд┐ рд▓реЛрдб рдЧрд░реНрди рд╕рдЬрд┐рд▓реЛ рдЫ:

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

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

рдХрдард┐рди рднрд╛рдЧ prog_load рд╕рдВрд░рдЪрдирд╛рд╣рд░реВрдХреЛ рдПрд░реНрд░реЗрдХреЛ рд░реВрдкрдорд╛ рд╣рд╛рдореНрд░реЛ BPF рдХрд╛рд░реНрдпрдХреНрд░рдордХреЛ рдкрд░рд┐рднрд╛рд╖рд╛ рд╣реЛ struct bpf_insn insns[]ред рддрд░ рд╣рд╛рдореАрд▓реЗ C рдорд╛ рднрдПрдХреЛ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдкреНрд░рдпреЛрдЧ рдЧрд░реНрджреИрдЫреМрдВ, рд╣рд╛рдореА рдереЛрд░реИ рдзреЛрдЦрд╛ рджрд┐рди рд╕рдХреНрдЫреМрдВ:

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

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

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

рдХреБрд▓рдорд╛, рд╣рд╛рдореАрд▓реЗ рд╕рдВрд░рдЪрдирд╛рдХреЛ рд░реВрдкрдорд╛ 14 рдирд┐рд░реНрджреЗрд╢рдирд╣рд░реВ рд▓реЗрдЦреНрди рдЖрд╡рд╢реНрдпрдХ рдЫ struct bpf_insn (рд╕рд▓реНрд▓рд╛рд╣: рдорд╛рдерд┐рдмрд╛рдЯ рдбрдореНрдк рд▓рд┐рдиреБрд╣реЛрд╕реН, рдирд┐рд░реНрджреЗрд╢рди рдЦрдгреНрдб рдкреБрди: рдкрдвреНрдиреБрд╣реЛрд╕реН, рдЦреЛрд▓реНрдиреБрд╣реЛрд╕реН linux/bpf.h ╨╕ linux/bpf_common.h рд░ рдирд┐рд░реНрдзрд╛рд░рдг рдЧрд░реНрди рдкреНрд░рдпрд╛рд╕ рдЧрд░реНрдиреБрд╣реЛрд╕реН struct bpf_insn insns[] рдЖрдлреНрдиреИ рдорд╛):

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

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

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

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

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

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

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

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

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

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

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

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

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

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

рдЬреЛ рдЖрдлреИрд▓реЗ рдпреЛ рд▓реЗрдЦреЗрдХрд╛ рдЫреИрдирдиреН рдХреЛ рд▓рд╛рдЧреА рдПрдХ рдЕрднреНрдпрд╛рд╕ - рдЦреЛрдЬреНрдиреБрд╣реЛрд╕реН map_fd.

рд╣рд╛рдореНрд░реЛ рдХрд╛рд░реНрдпрдХреНрд░рдордорд╛ рдЕрдЭреИ рдПрдХ рдЕрдЬреНрдЮрд╛рдд рднрд╛рдЧ рдмрд╛рдБрдХреА рдЫ - xdp_attachред рджреБрд░реНрднрд╛рдЧреНрдпрд╡рд╢, XDP рдЬрд╕реНрддрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдорд╣рд░реВ рдкреНрд░рдгрд╛рд▓реА рдХрд▓ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдЬрдбрд╛рди рдЧрд░реНрди рд╕рдХрд┐рдБрджреИрди bpfред BPF рд░ XDP рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрдиреЗ рд╡реНрдпрдХреНрддрд┐рд╣рд░реВ рдЕрдирд▓рд╛рдЗрди рд▓рд┐рдирдХреНрд╕ рд╕рдореБрджрд╛рдпрдмрд╛рдЯ рдЖрдПрдХрд╛ рдерд┐рдП, рдЬрд╕рдХреЛ рдорддрд▓рдм рддрд┐рдиреАрд╣рд░реВрд▓реЗ рдЖрдлреВрд▓рд╛рдИ рд╕рдмреИрднрдиреНрджрд╛ рдкрд░рд┐рдЪрд┐рдд рдПрдХ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗ (рддрд░ рд╣реЛрдЗрдиред рд╕рд╛рдорд╛рдиреНрдп рдорд╛рдирд┐рд╕рд╣рд░реВ) рдХрд░реНрдиреЗрд▓рд╕рдБрдЧ рдЕрдиреНрддрд░рдХреНрд░рд┐рдпрд╛ рдЧрд░реНрдирдХреЛ рд▓рд╛рдЧрд┐ рдЗрдиреНрдЯрд░рдлреЗрд╕: рдиреЗрдЯрд▓рд┐рдЩреНрдХ рд╕рдХреЗрдЯрд╣рд░реВ, рдкрдирд┐ рд╣реЗрд░реНрдиреБрд╣реЛрд╕реН 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 рд╣рд╛рдореАрд▓реЗ рдкреНрд░рдХрд╛рд░ рдЬрд╛рдирдХрд╛рд░реА (BTF) рд▓реЛрдб рдЧрд░реЗрдХрд╛ рдЫреИрдиреМрдВред рддрд░ рд╣рд╛рдореА рдЕрд░реНрдХреЛ рдкрдЯрдХ рдпрд╕ рдмрд╛рд░реЗ рдердк рдХреБрд░рд╛ рдЧрд░реНрдиреЗрдЫреМрдВред

рд╡рд┐рдХрд╛рд╕ рдЙрдкрдХрд░рдгрд╣рд░реВ

рдпрд╕ рдЦрдгреНрдбрдорд╛, рд╣рд╛рдореА рдиреНрдпреВрдирддрдо BPF рд╡рд┐рдХрд╛рд╕рдХрд░реНрддрд╛ рдЯреВрд▓рдХрд┐рдЯ рд╣реЗрд░реНрдиреЗрдЫреМрдВред

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

  • llvm/clang
  • pahole
  • рдпрд╕рдХреЛ рдореВрд▓
  • bpftool

(рд╕рдиреНрджрд░реНрднрдХреЛ рд▓рд╛рдЧрд┐, рдпреЛ рдЦрдгреНрдб рд░ рд▓реЗрдЦрдорд╛ рд╕рдмреИ рдЙрджрд╛рд╣рд░рдгрд╣рд░реВ рдбреЗрдмрд┐рдпрди 10 рдорд╛ рдЪрд▓рд╛рдЗрдПрдХреЛ рдерд┐рдпреЛред)

llvm/clang

BPF LLVM рд╕рдБрдЧ рдореИрддреНрд░реА рдЫ рд░, рд╣рд╛рд▓рд╕рд╛рд▓реИ BPF рдХреЛ рд▓рд╛рдЧрд┐ рдХрд╛рд░реНрдпрдХреНрд░рдорд╣рд░реВ gcc рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдХрдореНрдкрд╛рдЗрд▓ рдЧрд░реНрди рд╕рдХрд┐рдиреНрдЫ, рд╕рдмреИ рд╣рд╛рд▓рдХреЛ рд╡рд┐рдХрд╛рд╕ LLVM рдХреЛ рд▓рд╛рдЧреА рдЧрд░рд┐рдиреНрдЫред рддреНрдпрд╕реИрд▓реЗ, рд╕рдмреИ рднрдиреНрджрд╛ рдкрд╣рд┐рд▓реЗ, рд╣рд╛рдореА рд╣рд╛рд▓рдХреЛ рд╕рдВрд╕реНрдХрд░рдг рдирд┐рд░реНрдорд╛рдг рдЧрд░реНрдиреЗрдЫреМрдВ clang git рдмрд╛рдЯ:

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

рдЕрдм рд╣рд╛рдореА рдЬрд╛рдБрдЪ рдЧрд░реНрди рд╕рдХреНрдЫреМрдВ рдХрд┐ рд╕рдмреИ рдХреБрд░рд╛ рд╕рд╣реА рд░реВрдкрдорд╛ рд╕рдБрдЧреИ рдЖрдП:

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

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

(рд╡рд┐рдзрд╛рдирд╕рднрд╛ рдирд┐рд░реНрджреЗрд╢рдирд╣рд░реВ clang рдордмрд╛рдЯ рд▓рд┐рдПрдХреЛ bpf_devel_QA.)

рд╣рд╛рдореАрд▓реЗ рднрд░реНрдЦрд░реИ рдмрдирд╛рдПрдХрд╛ рдкреНрд░реЛрдЧреНрд░рд╛рдорд╣рд░реВ рд╕реНрдерд╛рдкрдирд╛ рдЧрд░реНрдиреЗ рдЫреИрдиреМрдВ, рддрд░ рдмрд░реБ рддрд┐рдиреАрд╣рд░реВрд▓рд╛рдИ рдердкреНрдиреБрд╣реЛрд╕реН PATH, рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐:

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

(рдпреЛ рдердкреНрди рд╕рдХрд┐рдиреНрдЫ .bashrc рд╡рд╛ рдЫреБрдЯреНрдЯреИ рдлрд╛рдЗрд▓рдорд╛ред рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдкрдорд╛, рдо рдпрд╕реНрддрд╛ рдЪреАрдЬрд╣рд░реВ рдердкреНрдЫреБ ~/bin/activate-llvm.sh рд░ рдЖрд╡рд╢реНрдпрдХ рд╣реБрдБрджрд╛ рдо рдЧрд░реНрдЫреБ . activate-llvm.sh.)

Pahole рд░ BTF

рдЙрдкрдпреЛрдЧрд┐рддрд╛ pahole BTF рдврд╛рдБрдЪрд╛рдорд╛ рдбрд┐рдмрдЧрд┐рдЩ рдЬрд╛рдирдХрд╛рд░реА рд╕рд┐рд░реНрдЬрдирд╛ рдЧрд░реНрди рдХрд░реНрдиреЗрд▓ рдирд┐рд░реНрдорд╛рдг рдЧрд░реНрджрд╛ рдкреНрд░рдпреЛрдЧ рдЧрд░рд┐рдиреНрдЫред рд╣рд╛рдореА рдпрд╕ рд▓реЗрдЦрдорд╛ BTF рдкреНрд░рд╡рд┐рдзрд┐рдХреЛ рд╡рд┐рд╡рд░рдгрд╣рд░реВрдХреЛ рдмрд╛рд░реЗрдорд╛ рд╡рд┐рд╕реНрддреГрдд рд░реВрдкрдорд╛ рдЬрд╛рдиреЗрдЫреИрдиреМрдВ, рдпреЛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдЫ рд░ рд╣рд╛рдореА рдпрд╕рд▓рд╛рдИ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрди рдЪрд╛рд╣рдиреНрдЫреМрдВред рддреНрдпрд╕реИрд▓реЗ рдпрджрд┐ рддрдкрд╛рдЗрдБ рдЖрдлреНрдиреЛ рдХрд░реНрдиреЗрд▓ рдирд┐рд░реНрдорд╛рдг рдЧрд░реНрди рдЬрд╛рдБрджреИ рд╣реБрдиреБрд╣реБрдиреНрдЫ рднрдиреЗ, рдкрд╣рд┐рд▓реЗ рдирд┐рд░реНрдорд╛рдг рдЧрд░реНрдиреБрд╣реЛрд╕реН pahole (рдмрд┐рдирд╛) pahole рддрдкрд╛рдИрд▓реЗ рд╡рд┐рдХрд▓реНрдкрдХреЛ рд╕рд╛рде рдХрд░реНрдиреЗрд▓ рдирд┐рд░реНрдорд╛рдг рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреЗ рдЫреИрди CONFIG_DEBUG_INFO_BTF:

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

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

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

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

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

рдорд╛рдерд┐рдХреЛ рдХрд░реНрдиреЗрд▓ рдордзреНрдпреЗ рдПрдЙрдЯрд╛ рдбрд╛рдЙрдирд▓реЛрдб рдЧрд░реНрдиреБрд╣реЛрд╕реН:

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

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

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

рдлрд╛рдЗрд▓рдорд╛ BPF рд╡рд┐рдХрд▓реНрдкрд╣рд░реВ рд╕рдХреНрд╖рдо рдЧрд░реНрдиреБрд╣реЛрд╕реН .config рддрдкрд╛рдИрдХреЛ рдЖрдлреНрдиреИ рдЫрдиреМрдЯрдХреЛ (рд╕рдореНрднрд╡рддрдГ CONFIG_BPF рдкрд╣рд┐рд▓реЗ рдиреИ рд╕рдХреНрд╖рдо рд╣реБрдиреЗрдЫ рдХрд┐рдирднрдиреЗ systemd рдпрд╕рд▓рд╛рдИ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрджрдЫ)ред рдпрд╣рд╛рдБ рдпрд╕ рд▓реЗрдЦрдХреЛ рд▓рд╛рдЧрд┐ рдкреНрд░рдпреЛрдЧ рдЧрд░рд┐рдПрдХреЛ рдХрд░реНрдиреЗрд▓рдмрд╛рдЯ рд╡рд┐рдХрд▓реНрдкрд╣рд░реВрдХреЛ рд╕реВрдЪреА рдЫ:

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

рддреНрдпрд╕реЛрднрдП рд╣рд╛рдореА рд╕рдЬрд┐рд▓реИрд╕рдБрдЧ рдореЛрдбреНрдпреБрд▓рд╣рд░реВ рд░ рдХрд░реНрдиреЗрд▓рд╣рд░реВ рдЬрдореНрдорд╛ рд░ рд╕реНрдерд╛рдкрдирд╛ рдЧрд░реНрди рд╕рдХреНрдЫреМрдВ (рдпрд╕реИрд▓реЗ, рддрдкрд╛рдИрдВрд▓реЗ рднрд░реНрдЦрд░реИ рдЬрдореНрдорд╛ рдЧрд░рд┐рдПрдХреЛ рдкреНрд░рдпреЛрдЧ рдЧрд░реЗрд░ рдХрд░реНрдиреЗрд▓рд▓рд╛рдИ рдПрд╕реЗрдореНрдмрд▓ рдЧрд░реНрди рд╕рдХреНрдиреБрд╣реБрдиреНрдЫред clangрдердкреЗрд░ CC=clang):

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

рд░ рдирдпрд╛рдБ рдХрд░реНрдиреЗрд▓рд╕рдБрдЧ рд░рд┐рдмреБрдЯ рдЧрд░реНрдиреБрд╣реЛрд╕реН (рдо рдпрд╕рдХреЛ рд▓рд╛рдЧрд┐ рдкреНрд░рдпреЛрдЧ рдЧрд░реНрджрдЫреБ kexec рдкреНрдпрд╛рдХреЗрдЬрдмрд╛рдЯ kexec-tools):

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

bpftool

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

рдпреЛ рд▓реЗрдЦрди рдХреЛ рд╕рдордпрдорд╛ bpftool RHEL, Fedora рд░ Ubuntu рдХреЛ рд▓рд╛рдЧрд┐ рдорд╛рддреНрд░ рддрдпрд╛рд░-рдирд┐рд░реНрдорд┐рдд рдЖрдЙрдБрдЫ (рдЙрджрд╛рд╣рд░рдгрдХрд╛ рд▓рд╛рдЧрд┐ рд╣реЗрд░реНрдиреБрд╣реЛрд╕реН, рдпреЛ рдзрд╛рдЧреЛ, рдЬрд╕рд▓реЗ рдкреНрдпрд╛рдХреЗрдЬрд┐рдЩрдХреЛ рдЕрдзреВрд░реЛ рдХрдерд╛ рдмрддрд╛рдЙрдБрдЫ bpftool рдбреЗрдмрд┐рдпрди рдорд╛)ред рддрд░ рдпрджрд┐ рддрдкрд╛рдИрдВрд▓реЗ рдкрд╣рд┐рд▓реЗ рдиреИ рдЖрдлреНрдиреЛ рдХрд░реНрдиреЗрд▓ рдирд┐рд░реНрдорд╛рдг рдЧрд░реНрдиреБрднрдПрдХреЛ рдЫ рднрдиреЗ, рддреНрдпрд╕рдкрдЫрд┐ рдирд┐рд░реНрдорд╛рдг рдЧрд░реНрдиреБрд╣реЛрд╕реН bpftool рдкрд╛рдИ рдЬрд╕реНрддреИ рд╕рдЬрд┐рд▓реЛ:

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

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

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

$

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

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

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

рдЬрд╕рд▓реЗ рддрдкрд╛рдЗрдБрдХреЛ рдХрд░реНрдиреЗрд▓рдорд╛ рдХреБрди BPF рд╕реБрд╡рд┐рдзрд╛рд╣рд░реВ рд╕рдХреНрд╖рдо рдкрд╛рд░рд┐рдПрдХреЛ рджреЗрдЦрд╛рдЙрдиреЗрдЫред

рд╡реИрд╕реЗ, рдЕрдШрд┐рд▓реНрд▓реЛ рдЖрджреЗрд╢ рдХреЛ рд░реВрдкрдорд╛ рдЪрд▓рд╛рдЙрди рд╕рдХрд┐рдиреНрдЫ

# bpftool f p k

рдпреЛ рдкреНрдпрд╛рдХреЗрдЬрдмрд╛рдЯ рдЙрдкрдпреЛрдЧрд┐рддрд╛рд╣рд░реБ рд╕рдВрдЧ рд╕рдорд╛рдирддрд╛ рджреНрд╡рд╛рд░рд╛ рдЧрд░рд┐рдиреНрдЫ iproute2, рдЬрд╣рд╛рдБ рд╣рд╛рдореА, рдЙрджрд╛рд╣рд░рдг рдХреЛ рд▓рд╛рдЧреА, рднрдиреНрди рд╕рдХреНрдЫреМрдВ ip a s eth0 рдХреЛ рд╕рдЯреНрдЯрд╛ ip addr show dev eth0.

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

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

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

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

рдпрд╕ рд╢реНрд░реГрдВрдЦрд▓рд╛рдорд╛ рдЕрдШрд┐рд▓реНрд▓реЛ рд▓реЗрдЦрд╣рд░реВ

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

рд▓рд┐рдЩреНрдХрд╣рд░реВ

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

  2. Documentation/networking/filter.txt - рдХреНрд▓рд╛рд╕рд┐рдХ рд░ рддреНрдпрд╕рдкрдЫрд┐ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд BPF рдХреЛ рд▓рд╛рдЧрд┐ рджрд╕реНрддрд╛рд╡реЗрдЬ рд╕рдВрдЧ рдореВрд▓ рдлрд╛рдЗрд▓ред рдпрджрд┐ рддрдкрд╛рдЗрдБ рд╡рд┐рдзрд╛рдирд╕рднрд╛ рднрд╛рд╖рд╛ рд░ рдкреНрд░рд╛рд╡рд┐рдзрд┐рдХ рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рд╡рд┐рд╡рд░рдгрд╣рд░реВрдорд╛ рдЬрд╛рди рдЪрд╛рд╣рдиреБрд╣реБрдиреНрдЫ рднрдиреЗ рд░рд╛рдореНрд░реЛ рдкрдвреНрдиреБрд╣реЛрд╕реНред

  3. рдлреЗрд╕рдмреБрдХрдмрд╛рдЯ BPF рдмрд╛рд░реЗ рдмреНрд▓рдЧред рдпреЛ рд╡рд┐рд░рд▓реИ рдЕрдкрдбреЗрдЯ рдЧрд░рд┐рдПрдХреЛ рдЫ, рддрд░ рдЙрдкрдпреБрдХреНрдд рд░реВрдкрдорд╛, Alexei Starovoitov (eBPF рдХрд╛ рд▓реЗрдЦрдХ) рд░ Andrii Nakryiko - (рд╕рдВрд░рдХреНрд╖рдгрдХрд░реНрддрд╛) рддреНрдпрд╣рд╛рдБ рд▓реЗрдЦреНрдЫрдиреНред libbpf).

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

  5. BPF рдорд╛ рдбреБрдмреНрдиреБрд╣реЛрд╕реН: рдкрдарди рд╕рд╛рдордЧреНрд░реАрдХреЛ рд╕реВрдЪреАред Quentin Monnet рдмрд╛рдЯ BPF рдХрд╛рдЧрдЬрд╛рддрдорд╛ рд▓рд┐рдЩреНрдХрд╣рд░реВрдХреЛ рд╡рд┐рд╢рд╛рд▓ (рд░ рдЕрдЭреИ рд░рд╛рдЦрд┐рдПрдХреЛ) рд╕реВрдЪреАред

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

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