diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 59a217ca2dfd3e..ab666c99f8993e 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -999,6 +999,8 @@ enum bpf_attach_type { BPF_PERF_EVENT, BPF_TRACE_KPROBE_MULTI, BPF_LSM_CGROUP, + BPF_NET_INGRESS, + BPF_NET_EGRESS, __MAX_BPF_ATTACH_TYPE }; @@ -1015,6 +1017,7 @@ enum bpf_link_type { BPF_LINK_TYPE_PERF_EVENT = 7, BPF_LINK_TYPE_KPROBE_MULTI = 8, BPF_LINK_TYPE_STRUCT_OPS = 9, + BPF_LINK_TYPE_TC = 10, MAX_BPF_LINK_TYPE, }; @@ -1373,14 +1376,20 @@ union bpf_attr { }; struct { /* anonymous struct used by BPF_PROG_ATTACH/DETACH commands */ - __u32 target_fd; /* container object to attach to */ + union { + __u32 target_fd; /* container object to attach to */ + __u32 target_ifindex; /* target ifindex */ + }; __u32 attach_bpf_fd; /* eBPF program to attach */ __u32 attach_type; __u32 attach_flags; - __u32 replace_bpf_fd; /* previously attached eBPF + union { + __u32 attach_priority; + __u32 replace_bpf_fd; /* previously attached eBPF * program to replace if * BPF_F_REPLACE is used */ + }; }; struct { /* anonymous struct used by BPF_PROG_TEST_RUN command */ @@ -1426,7 +1435,10 @@ union bpf_attr { } info; struct { /* anonymous struct used by BPF_PROG_QUERY command */ - __u32 target_fd; /* container object to query */ + union { + __u32 target_fd; /* container object to query */ + __u32 target_ifindex; /* target ifindex */ + }; __u32 attach_type; __u32 query_flags; __u32 attach_flags; @@ -1501,6 +1513,9 @@ union bpf_attr { */ __u64 cookie; } tracing; + struct { + __u32 priority; + } tc; }; } link_create; @@ -6147,6 +6162,11 @@ struct bpf_link_info { struct { __u32 ifindex; } xdp; + struct { + __u32 ifindex; + __u32 attach_type; + __u32 priority; + } tc; }; } __attribute__((aligned(8))); diff --git a/tools/lib/bpf/bpf.c b/tools/lib/bpf/bpf.c index 220a197b54899e..c0374a10fd8db7 100644 --- a/tools/lib/bpf/bpf.c +++ b/tools/lib/bpf/bpf.c @@ -741,6 +741,10 @@ int bpf_link_create(int prog_fd, int target_fd, if (!OPTS_ZEROED(opts, tracing)) return libbpf_err(-EINVAL); break; + case BPF_NET_INGRESS: + case BPF_NET_EGRESS: + attr.link_create.tc.priority = OPTS_GET(opts, tc.priority, 0); + break; default: if (!OPTS_ZEROED(opts, flags)) return libbpf_err(-EINVAL); diff --git a/tools/lib/bpf/bpf.h b/tools/lib/bpf/bpf.h index 96de58fecdbc04..93758342132751 100644 --- a/tools/lib/bpf/bpf.h +++ b/tools/lib/bpf/bpf.h @@ -334,6 +334,9 @@ struct bpf_link_create_opts { struct { __u64 cookie; } tracing; + struct { + __u32 priority; + } tc; }; size_t :0; }; diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 50d41815f431a7..2c832a253a375f 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -8458,6 +8458,8 @@ static const struct bpf_sec_def section_defs[] = { SEC_DEF("kretsyscall+", KPROBE, 0, SEC_NONE, attach_ksyscall), SEC_DEF("usdt+", KPROBE, 0, SEC_NONE, attach_usdt), SEC_DEF("tc", SCHED_CLS, 0, SEC_NONE), + SEC_DEF("tc/ingress", SCHED_CLS, BPF_NET_INGRESS, SEC_ATTACHABLE_OPT), + SEC_DEF("tc/egress", SCHED_CLS, BPF_NET_EGRESS, SEC_ATTACHABLE_OPT), SEC_DEF("classifier", SCHED_CLS, 0, SEC_NONE), SEC_DEF("action", SCHED_ACT, 0, SEC_NONE), SEC_DEF("tracepoint+", TRACEPOINT, 0, SEC_NONE, attach_tp), @@ -11205,11 +11207,10 @@ static int attach_lsm(const struct bpf_program *prog, long cookie, struct bpf_li } static struct bpf_link * -bpf_program__attach_fd(const struct bpf_program *prog, int target_fd, int btf_id, - const char *target_name) +bpf_program__attach_fd_opts(const struct bpf_program *prog, + const struct bpf_link_create_opts *opts, + int target_fd, const char *target_name) { - DECLARE_LIBBPF_OPTS(bpf_link_create_opts, opts, - .target_btf_id = btf_id); enum bpf_attach_type attach_type; char errmsg[STRERR_BUFSIZE]; struct bpf_link *link; @@ -11227,7 +11228,7 @@ bpf_program__attach_fd(const struct bpf_program *prog, int target_fd, int btf_id link->detach = &bpf_link__detach_fd; attach_type = bpf_program__expected_attach_type(prog); - link_fd = bpf_link_create(prog_fd, target_fd, attach_type, &opts); + link_fd = bpf_link_create(prog_fd, target_fd, attach_type, opts); if (link_fd < 0) { link_fd = -errno; free(link); @@ -11240,6 +11241,16 @@ bpf_program__attach_fd(const struct bpf_program *prog, int target_fd, int btf_id return link; } +static struct bpf_link * +bpf_program__attach_fd(const struct bpf_program *prog, int target_fd, int btf_id, + const char *target_name) +{ + DECLARE_LIBBPF_OPTS(bpf_link_create_opts, opts, + .target_btf_id = btf_id); + + return bpf_program__attach_fd_opts(prog, &opts, target_fd, target_name); +} + struct bpf_link * bpf_program__attach_cgroup(const struct bpf_program *prog, int cgroup_fd) { @@ -11258,6 +11269,16 @@ struct bpf_link *bpf_program__attach_xdp(const struct bpf_program *prog, int ifi return bpf_program__attach_fd(prog, ifindex, 0, "xdp"); } +struct bpf_link *bpf_program__attach_tc(const struct bpf_program *prog, + int ifindex, __u32 priority) +{ + DECLARE_LIBBPF_OPTS(bpf_link_create_opts, opts, + .tc.priority = priority); + + /* target_fd/target_ifindex use the same field in LINK_CREATE */ + return bpf_program__attach_fd_opts(prog, &opts, ifindex, "tc"); +} + struct bpf_link *bpf_program__attach_freplace(const struct bpf_program *prog, int target_fd, const char *attach_func_name) diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h index 61493c4cddac11..c36dbec51745c5 100644 --- a/tools/lib/bpf/libbpf.h +++ b/tools/lib/bpf/libbpf.h @@ -641,6 +641,8 @@ bpf_program__attach_netns(const struct bpf_program *prog, int netns_fd); LIBBPF_API struct bpf_link * bpf_program__attach_xdp(const struct bpf_program *prog, int ifindex); LIBBPF_API struct bpf_link * +bpf_program__attach_tc(const struct bpf_program *prog, int ifindex, __u32 priority); +LIBBPF_API struct bpf_link * bpf_program__attach_freplace(const struct bpf_program *prog, int target_fd, const char *attach_func_name); diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map index 4df82bab483863..b2d1875b92f353 100644 --- a/tools/lib/bpf/libbpf.map +++ b/tools/lib/bpf/libbpf.map @@ -346,6 +346,7 @@ LIBBPF_0.8.0 { bpf_object__destroy_subskeleton; bpf_object__open_subskeleton; bpf_program__attach_kprobe_multi_opts; + bpf_program__attach_tc; bpf_program__attach_trace_opts; bpf_program__attach_usdt; bpf_program__set_insns;