Skip to content

Commit e22710d

Browse files
gyutaebqmonnet
authored andcommitted
bpftool: Add 'prepend' option for tcx attach to insert at chain start
Add support for the 'prepend' option when attaching tcx_ingress and tcx_egress programs. This option allows inserting a BPF program at the beginning of the TCX chain instead of appending it at the end. The implementation uses BPF_F_BEFORE flag which automatically inserts the program at the beginning of the chain when no relative reference is specified. This change includes: - Modify do_attach_tcx() to support prepend insertion using BPF_F_BEFORE - Update documentation to describe the new 'prepend' option - Add bash completion support for the 'prepend' option on tcx attach types - Add example usage in the documentation - Add validation to reject 'overwrite' for non-XDP attach types The 'prepend' option is only valid for tcx_ingress and tcx_egress attach types. For XDP attach types, the existing 'overwrite' option remains available. Example usage: # bpftool net attach tcx_ingress name tc_prog dev lo prepend This feature is useful when the order of program execution in the TCX chain matters and users need to ensure certain programs run first. Co-developed-by: Siwan Kim <siwan.kim@navercorp.com> Signed-off-by: Siwan Kim <siwan.kim@navercorp.com> Signed-off-by: Gyutae Bae <gyutae.bae@navercorp.com> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Reviewed-by: Quentin Monnet <qmo@kernel.org> Acked-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/20260112034516.22723-1-gyutae.opensource@navercorp.com
1 parent 87de20f commit e22710d

File tree

3 files changed

+58
-12
lines changed

3 files changed

+58
-12
lines changed

bash-completion/bpftool

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1142,7 +1142,14 @@ _bpftool()
11421142
return 0
11431143
;;
11441144
8)
1145-
_bpftool_once_attr 'overwrite'
1145+
case ${words[3]} in
1146+
tcx_ingress|tcx_egress)
1147+
_bpftool_once_attr 'prepend'
1148+
;;
1149+
*)
1150+
_bpftool_once_attr 'overwrite'
1151+
;;
1152+
esac
11461153
return 0
11471154
;;
11481155
esac

docs/bpftool-net.rst

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ NET COMMANDS
2424
============
2525

2626
| **bpftool** **net** { **show** | **list** } [ **dev** *NAME* ]
27-
| **bpftool** **net attach** *ATTACH_TYPE* *PROG* **dev** *NAME* [ **overwrite** ]
27+
| **bpftool** **net attach** *ATTACH_TYPE* *PROG* **dev** *NAME* [ **overwrite** | **prepend** ]
2828
| **bpftool** **net detach** *ATTACH_TYPE* **dev** *NAME*
2929
| **bpftool** **net help**
3030
|
@@ -58,11 +58,9 @@ bpftool net { show | list } [ dev *NAME* ]
5858
then all bpf programs attached to non clsact qdiscs, and finally all bpf
5959
programs attached to root and clsact qdisc.
6060

61-
bpftool net attach *ATTACH_TYPE* *PROG* dev *NAME* [ overwrite ]
61+
bpftool net attach *ATTACH_TYPE* *PROG* dev *NAME* [ overwrite | prepend ]
6262
Attach bpf program *PROG* to network interface *NAME* with type specified
63-
by *ATTACH_TYPE*. Previously attached bpf program can be replaced by the
64-
command used with **overwrite** option. Currently, only XDP-related modes
65-
are supported for *ATTACH_TYPE*.
63+
by *ATTACH_TYPE*.
6664

6765
*ATTACH_TYPE* can be of:
6866
**xdp** - try native XDP and fallback to generic XDP if NIC driver does not support it;
@@ -72,11 +70,18 @@ bpftool net attach *ATTACH_TYPE* *PROG* dev *NAME* [ overwrite ]
7270
**tcx_ingress** - Ingress TCX. runs on ingress net traffic;
7371
**tcx_egress** - Egress TCX. runs on egress net traffic;
7472

73+
For XDP-related attach types (**xdp**, **xdpgeneric**, **xdpdrv**,
74+
**xdpoffload**), the **overwrite** option can be used to replace a
75+
previously attached bpf program.
76+
77+
For **tcx_ingress** and **tcx_egress** attach types, the **prepend** option
78+
can be used to attach the program at the beginning of the chain instead of
79+
at the end.
80+
7581
bpftool net detach *ATTACH_TYPE* dev *NAME*
7682
Detach bpf program attached to network interface *NAME* with type specified
7783
by *ATTACH_TYPE*. To detach bpf program, same *ATTACH_TYPE* previously used
78-
for attach must be specified. Currently, only XDP-related modes are
79-
supported for *ATTACH_TYPE*.
84+
for attach must be specified.
8085

8186
bpftool net help
8287
Print short help message.
@@ -191,6 +196,17 @@ EXAMPLES
191196
tc:
192197
lo(1) tcx/ingress tc_prog prog_id 29
193198

199+
|
200+
| **# bpftool net attach tcx_ingress name tc_prog2 dev lo prepend**
201+
| **# bpftool net**
202+
|
203+
204+
::
205+
206+
tc:
207+
lo(1) tcx/ingress tc_prog2 prog_id 30
208+
lo(1) tcx/ingress tc_prog prog_id 29
209+
194210
|
195211
| **# bpftool net attach tcx_ingress name tc_prog dev lo**
196212
| **# bpftool net detach tcx_ingress dev lo**

src/net.c

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -666,10 +666,16 @@ static int get_tcx_type(enum net_attach_type attach_type)
666666
}
667667
}
668668

669-
static int do_attach_tcx(int progfd, enum net_attach_type attach_type, int ifindex)
669+
static int do_attach_tcx(int progfd, enum net_attach_type attach_type, int ifindex, bool prepend)
670670
{
671671
int type = get_tcx_type(attach_type);
672672

673+
if (prepend) {
674+
LIBBPF_OPTS(bpf_prog_attach_opts, opts,
675+
.flags = BPF_F_BEFORE
676+
);
677+
return bpf_prog_attach_opts(progfd, ifindex, type, &opts);
678+
}
673679
return bpf_prog_attach(progfd, ifindex, type, 0);
674680
}
675681

@@ -685,6 +691,7 @@ static int do_attach(int argc, char **argv)
685691
enum net_attach_type attach_type;
686692
int progfd, ifindex, err = 0;
687693
bool overwrite = false;
694+
bool prepend = false;
688695

689696
/* parse attach args */
690697
if (!REQ_ARGS(5))
@@ -709,9 +716,25 @@ static int do_attach(int argc, char **argv)
709716

710717
if (argc) {
711718
if (is_prefix(*argv, "overwrite")) {
719+
if (attach_type != NET_ATTACH_TYPE_XDP &&
720+
attach_type != NET_ATTACH_TYPE_XDP_GENERIC &&
721+
attach_type != NET_ATTACH_TYPE_XDP_DRIVER &&
722+
attach_type != NET_ATTACH_TYPE_XDP_OFFLOAD) {
723+
p_err("'overwrite' is only supported for xdp types");
724+
err = -EINVAL;
725+
goto cleanup;
726+
}
712727
overwrite = true;
728+
} else if (is_prefix(*argv, "prepend")) {
729+
if (attach_type != NET_ATTACH_TYPE_TCX_INGRESS &&
730+
attach_type != NET_ATTACH_TYPE_TCX_EGRESS) {
731+
p_err("'prepend' is only supported for tcx_ingress/tcx_egress");
732+
err = -EINVAL;
733+
goto cleanup;
734+
}
735+
prepend = true;
713736
} else {
714-
p_err("expected 'overwrite', got: '%s'?", *argv);
737+
p_err("expected 'overwrite' or 'prepend', got: '%s'?", *argv);
715738
err = -EINVAL;
716739
goto cleanup;
717740
}
@@ -728,7 +751,7 @@ static int do_attach(int argc, char **argv)
728751
/* attach tcx prog */
729752
case NET_ATTACH_TYPE_TCX_INGRESS:
730753
case NET_ATTACH_TYPE_TCX_EGRESS:
731-
err = do_attach_tcx(progfd, attach_type, ifindex);
754+
err = do_attach_tcx(progfd, attach_type, ifindex, prepend);
732755
break;
733756
default:
734757
break;
@@ -985,7 +1008,7 @@ static int do_help(int argc, char **argv)
9851008

9861009
fprintf(stderr,
9871010
"Usage: %1$s %2$s { show | list } [dev <devname>]\n"
988-
" %1$s %2$s attach ATTACH_TYPE PROG dev <devname> [ overwrite ]\n"
1011+
" %1$s %2$s attach ATTACH_TYPE PROG dev <devname> [ overwrite | prepend ]\n"
9891012
" %1$s %2$s detach ATTACH_TYPE dev <devname>\n"
9901013
" %1$s %2$s help\n"
9911014
"\n"

0 commit comments

Comments
 (0)