@@ -133,6 +133,7 @@ static const char * const link_type_name[] = {
133
133
[BPF_LINK_TYPE_KPROBE_MULTI ] = "kprobe_multi" ,
134
134
[BPF_LINK_TYPE_STRUCT_OPS ] = "struct_ops" ,
135
135
[BPF_LINK_TYPE_NETFILTER ] = "netfilter" ,
136
+ [BPF_LINK_TYPE_TCX ] = "tcx" ,
136
137
};
137
138
138
139
static const char * const map_type_name [] = {
@@ -11685,11 +11686,10 @@ static int attach_lsm(const struct bpf_program *prog, long cookie, struct bpf_li
11685
11686
}
11686
11687
11687
11688
static struct bpf_link *
11688
- bpf_program__attach_fd (const struct bpf_program * prog , int target_fd , int btf_id ,
11689
- const char * target_name )
11689
+ bpf_program_attach_fd_opts (const struct bpf_program * prog ,
11690
+ int target_fd , const char * target_name ,
11691
+ const struct bpf_link_create_opts * opts )
11690
11692
{
11691
- DECLARE_LIBBPF_OPTS (bpf_link_create_opts , opts ,
11692
- .target_btf_id = btf_id );
11693
11693
enum bpf_attach_type attach_type ;
11694
11694
char errmsg [STRERR_BUFSIZE ];
11695
11695
struct bpf_link * link ;
@@ -11707,7 +11707,7 @@ bpf_program__attach_fd(const struct bpf_program *prog, int target_fd, int btf_id
11707
11707
link -> detach = & bpf_link__detach_fd ;
11708
11708
11709
11709
attach_type = bpf_program__expected_attach_type (prog );
11710
- link_fd = bpf_link_create (prog_fd , target_fd , attach_type , & opts );
11710
+ link_fd = bpf_link_create (prog_fd , target_fd , attach_type , opts );
11711
11711
if (link_fd < 0 ) {
11712
11712
link_fd = - errno ;
11713
11713
free (link );
@@ -11723,19 +11723,54 @@ bpf_program__attach_fd(const struct bpf_program *prog, int target_fd, int btf_id
11723
11723
struct bpf_link *
11724
11724
bpf_program__attach_cgroup (const struct bpf_program * prog , int cgroup_fd )
11725
11725
{
11726
- return bpf_program__attach_fd (prog , cgroup_fd , 0 , "cgroup" );
11726
+ return bpf_program_attach_fd_opts (prog , cgroup_fd , "cgroup" , NULL );
11727
11727
}
11728
11728
11729
11729
struct bpf_link *
11730
11730
bpf_program__attach_netns (const struct bpf_program * prog , int netns_fd )
11731
11731
{
11732
- return bpf_program__attach_fd (prog , netns_fd , 0 , "netns" );
11732
+ return bpf_program_attach_fd_opts (prog , netns_fd , "netns" , NULL );
11733
11733
}
11734
11734
11735
11735
struct bpf_link * bpf_program__attach_xdp (const struct bpf_program * prog , int ifindex )
11736
11736
{
11737
11737
/* target_fd/target_ifindex use the same field in LINK_CREATE */
11738
- return bpf_program__attach_fd (prog , ifindex , 0 , "xdp" );
11738
+ return bpf_program_attach_fd_opts (prog , ifindex , "xdp" , NULL );
11739
+ }
11740
+
11741
+ struct bpf_link *
11742
+ bpf_program__attach_tcx (const struct bpf_program * prog ,
11743
+ const struct bpf_tcx_opts * opts )
11744
+ {
11745
+ LIBBPF_OPTS (bpf_link_create_opts , link_create_opts );
11746
+ __u32 relative_fd , relative_id ;
11747
+ int ifindex ;
11748
+
11749
+ if (!OPTS_VALID (opts , bpf_tcx_opts ))
11750
+ return libbpf_err_ptr (- EINVAL );
11751
+
11752
+ ifindex = OPTS_GET (opts , ifindex , 0 );
11753
+ if (!ifindex ) {
11754
+ pr_warn ("prog '%s': target netdevice ifindex cannot be zero\n" ,
11755
+ prog -> name );
11756
+ return libbpf_err_ptr (- EINVAL );
11757
+ }
11758
+
11759
+ relative_fd = OPTS_GET (opts , relative_fd , 0 );
11760
+ relative_id = OPTS_GET (opts , relative_id , 0 );
11761
+ if (relative_fd && relative_id ) {
11762
+ pr_warn ("prog '%s': relative_fd and relative_id cannot be set at the same time\n" ,
11763
+ prog -> name );
11764
+ return libbpf_err_ptr (- EINVAL );
11765
+ }
11766
+
11767
+ link_create_opts .tcx .expected_revision = OPTS_GET (opts , expected_revision , 0 );
11768
+ link_create_opts .tcx .relative_fd = relative_fd ;
11769
+ link_create_opts .tcx .relative_id = relative_id ;
11770
+ link_create_opts .flags = OPTS_GET (opts , flags , 0 );
11771
+
11772
+ /* target_fd/target_ifindex use the same field in LINK_CREATE */
11773
+ return bpf_program_attach_fd_opts (prog , ifindex , "tc" , & link_create_opts );
11739
11774
}
11740
11775
11741
11776
struct bpf_link * bpf_program__attach_freplace (const struct bpf_program * prog ,
@@ -11757,11 +11792,15 @@ struct bpf_link *bpf_program__attach_freplace(const struct bpf_program *prog,
11757
11792
}
11758
11793
11759
11794
if (target_fd ) {
11795
+ LIBBPF_OPTS (bpf_link_create_opts , target_opts );
11796
+
11760
11797
btf_id = libbpf_find_prog_btf_id (attach_func_name , target_fd );
11761
11798
if (btf_id < 0 )
11762
11799
return libbpf_err_ptr (btf_id );
11800
+ target_opts .target_btf_id = btf_id ;
11763
11801
11764
- return bpf_program__attach_fd (prog , target_fd , btf_id , "freplace" );
11802
+ return bpf_program_attach_fd_opts (prog , target_fd , "freplace" ,
11803
+ & target_opts );
11765
11804
} else {
11766
11805
/* no target, so use raw_tracepoint_open for compatibility
11767
11806
* with old kernels
0 commit comments