@@ -203,6 +203,8 @@ struct bpf_program {
203203 struct bpf_object * obj ;
204204 void * priv ;
205205 bpf_program_clear_priv_t clear_priv ;
206+
207+ enum bpf_attach_type expected_attach_type ;
206208};
207209
208210struct bpf_map {
@@ -1162,21 +1164,31 @@ static int bpf_object__collect_reloc(struct bpf_object *obj)
11621164}
11631165
11641166static int
1165- load_program (enum bpf_prog_type type , const char * name , struct bpf_insn * insns ,
1166- int insns_cnt , char * license , u32 kern_version , int * pfd )
1167+ load_program (enum bpf_prog_type type , enum bpf_attach_type expected_attach_type ,
1168+ const char * name , struct bpf_insn * insns , int insns_cnt ,
1169+ char * license , u32 kern_version , int * pfd )
11671170{
1168- int ret ;
1171+ struct bpf_load_program_attr load_attr ;
11691172 char * log_buf ;
1173+ int ret ;
11701174
1171- if (!insns || !insns_cnt )
1175+ memset (& load_attr , 0 , sizeof (struct bpf_load_program_attr ));
1176+ load_attr .prog_type = type ;
1177+ load_attr .expected_attach_type = expected_attach_type ;
1178+ load_attr .name = name ;
1179+ load_attr .insns = insns ;
1180+ load_attr .insns_cnt = insns_cnt ;
1181+ load_attr .license = license ;
1182+ load_attr .kern_version = kern_version ;
1183+
1184+ if (!load_attr .insns || !load_attr .insns_cnt )
11721185 return - EINVAL ;
11731186
11741187 log_buf = malloc (BPF_LOG_BUF_SIZE );
11751188 if (!log_buf )
11761189 pr_warning ("Alloc log buffer for bpf loader error, continue without log\n" );
11771190
1178- ret = bpf_load_program_name (type , name , insns , insns_cnt , license ,
1179- kern_version , log_buf , BPF_LOG_BUF_SIZE );
1191+ ret = bpf_load_program_xattr (& load_attr , log_buf , BPF_LOG_BUF_SIZE );
11801192
11811193 if (ret >= 0 ) {
11821194 * pfd = ret ;
@@ -1192,18 +1204,18 @@ load_program(enum bpf_prog_type type, const char *name, struct bpf_insn *insns,
11921204 pr_warning ("-- BEGIN DUMP LOG ---\n" );
11931205 pr_warning ("\n%s\n" , log_buf );
11941206 pr_warning ("-- END LOG --\n" );
1195- } else if (insns_cnt >= BPF_MAXINSNS ) {
1196- pr_warning ("Program too large (%d insns), at most %d insns\n" ,
1197- insns_cnt , BPF_MAXINSNS );
1207+ } else if (load_attr . insns_cnt >= BPF_MAXINSNS ) {
1208+ pr_warning ("Program too large (%zu insns), at most %d insns\n" ,
1209+ load_attr . insns_cnt , BPF_MAXINSNS );
11981210 ret = - LIBBPF_ERRNO__PROG2BIG ;
11991211 } else {
12001212 /* Wrong program type? */
1201- if (type != BPF_PROG_TYPE_KPROBE ) {
1213+ if (load_attr . prog_type != BPF_PROG_TYPE_KPROBE ) {
12021214 int fd ;
12031215
1204- fd = bpf_load_program_name ( BPF_PROG_TYPE_KPROBE , name ,
1205- insns , insns_cnt , license ,
1206- kern_version , NULL , 0 );
1216+ load_attr . prog_type = BPF_PROG_TYPE_KPROBE ;
1217+ load_attr . expected_attach_type = 0 ;
1218+ fd = bpf_load_program_xattr ( & load_attr , NULL , 0 );
12071219 if (fd >= 0 ) {
12081220 close (fd );
12091221 ret = - LIBBPF_ERRNO__PROGTYPE ;
@@ -1247,8 +1259,9 @@ bpf_program__load(struct bpf_program *prog,
12471259 pr_warning ("Program '%s' is inconsistent: nr(%d) != 1\n" ,
12481260 prog -> section_name , prog -> instances .nr );
12491261 }
1250- err = load_program (prog -> type , prog -> name , prog -> insns ,
1251- prog -> insns_cnt , license , kern_version , & fd );
1262+ err = load_program (prog -> type , prog -> expected_attach_type ,
1263+ prog -> name , prog -> insns , prog -> insns_cnt ,
1264+ license , kern_version , & fd );
12521265 if (!err )
12531266 prog -> instances .fds [0 ] = fd ;
12541267 goto out ;
@@ -1276,8 +1289,8 @@ bpf_program__load(struct bpf_program *prog,
12761289 continue ;
12771290 }
12781291
1279- err = load_program (prog -> type , prog -> name ,
1280- result .new_insn_ptr ,
1292+ err = load_program (prog -> type , prog -> expected_attach_type ,
1293+ prog -> name , result .new_insn_ptr ,
12811294 result .new_insn_cnt ,
12821295 license , kern_version , & fd );
12831296
@@ -1835,11 +1848,22 @@ BPF_PROG_TYPE_FNS(tracepoint, BPF_PROG_TYPE_TRACEPOINT);
18351848BPF_PROG_TYPE_FNS (xdp , BPF_PROG_TYPE_XDP );
18361849BPF_PROG_TYPE_FNS (perf_event , BPF_PROG_TYPE_PERF_EVENT );
18371850
1838- #define BPF_PROG_SEC (string , type ) { string, sizeof(string) - 1, type }
1851+ static void bpf_program__set_expected_attach_type (struct bpf_program * prog ,
1852+ enum bpf_attach_type type )
1853+ {
1854+ prog -> expected_attach_type = type ;
1855+ }
1856+
1857+ #define BPF_PROG_SEC_FULL (string , ptype , atype ) \
1858+ { string, sizeof(string) - 1, ptype, atype }
1859+
1860+ #define BPF_PROG_SEC (string , ptype ) BPF_PROG_SEC_FULL(string, ptype, 0)
1861+
18391862static const struct {
18401863 const char * sec ;
18411864 size_t len ;
18421865 enum bpf_prog_type prog_type ;
1866+ enum bpf_attach_type expected_attach_type ;
18431867} section_names [] = {
18441868 BPF_PROG_SEC ("socket" , BPF_PROG_TYPE_SOCKET_FILTER ),
18451869 BPF_PROG_SEC ("kprobe/" , BPF_PROG_TYPE_KPROBE ),
@@ -1859,9 +1883,11 @@ static const struct {
18591883 BPF_PROG_SEC ("sk_skb" , BPF_PROG_TYPE_SK_SKB ),
18601884 BPF_PROG_SEC ("sk_msg" , BPF_PROG_TYPE_SK_MSG ),
18611885};
1886+
18621887#undef BPF_PROG_SEC
1888+ #undef BPF_PROG_SEC_FULL
18631889
1864- static enum bpf_prog_type bpf_program__guess_type (struct bpf_program * prog )
1890+ static int bpf_program__identify_section (struct bpf_program * prog )
18651891{
18661892 int i ;
18671893
@@ -1871,13 +1897,13 @@ static enum bpf_prog_type bpf_program__guess_type(struct bpf_program *prog)
18711897 for (i = 0 ; i < ARRAY_SIZE (section_names ); i ++ )
18721898 if (strncmp (prog -> section_name , section_names [i ].sec ,
18731899 section_names [i ].len ) == 0 )
1874- return section_names [ i ]. prog_type ;
1900+ return i ;
18751901
18761902err :
18771903 pr_warning ("failed to guess program type based on section name %s\n" ,
18781904 prog -> section_name );
18791905
1880- return BPF_PROG_TYPE_UNSPEC ;
1906+ return -1 ;
18811907}
18821908
18831909int bpf_map__fd (struct bpf_map * map )
@@ -1976,12 +2002,31 @@ long libbpf_get_error(const void *ptr)
19762002
19772003int bpf_prog_load (const char * file , enum bpf_prog_type type ,
19782004 struct bpf_object * * pobj , int * prog_fd )
2005+ {
2006+ struct bpf_prog_load_attr attr ;
2007+
2008+ memset (& attr , 0 , sizeof (struct bpf_prog_load_attr ));
2009+ attr .file = file ;
2010+ attr .prog_type = type ;
2011+ attr .expected_attach_type = 0 ;
2012+
2013+ return bpf_prog_load_xattr (& attr , pobj , prog_fd );
2014+ }
2015+
2016+ int bpf_prog_load_xattr (const struct bpf_prog_load_attr * attr ,
2017+ struct bpf_object * * pobj , int * prog_fd )
19792018{
19802019 struct bpf_program * prog , * first_prog = NULL ;
2020+ enum bpf_attach_type expected_attach_type ;
2021+ enum bpf_prog_type prog_type ;
19812022 struct bpf_object * obj ;
2023+ int section_idx ;
19822024 int err ;
19832025
1984- obj = bpf_object__open (file );
2026+ if (!attr )
2027+ return - EINVAL ;
2028+
2029+ obj = bpf_object__open (attr -> file );
19852030 if (IS_ERR (obj ))
19862031 return - ENOENT ;
19872032
@@ -1990,15 +2035,23 @@ int bpf_prog_load(const char *file, enum bpf_prog_type type,
19902035 * If type is not specified, try to guess it based on
19912036 * section name.
19922037 */
1993- if (type == BPF_PROG_TYPE_UNSPEC ) {
1994- type = bpf_program__guess_type (prog );
1995- if (type == BPF_PROG_TYPE_UNSPEC ) {
2038+ prog_type = attr -> prog_type ;
2039+ expected_attach_type = attr -> expected_attach_type ;
2040+ if (prog_type == BPF_PROG_TYPE_UNSPEC ) {
2041+ section_idx = bpf_program__identify_section (prog );
2042+ if (section_idx < 0 ) {
19962043 bpf_object__close (obj );
19972044 return - EINVAL ;
19982045 }
2046+ prog_type = section_names [section_idx ].prog_type ;
2047+ expected_attach_type =
2048+ section_names [section_idx ].expected_attach_type ;
19992049 }
20002050
2001- bpf_program__set_type (prog , type );
2051+ bpf_program__set_type (prog , prog_type );
2052+ bpf_program__set_expected_attach_type (prog ,
2053+ expected_attach_type );
2054+
20022055 if (prog -> idx != obj -> efile .text_shndx && !first_prog )
20032056 first_prog = prog ;
20042057 }
0 commit comments