Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1# bpftool(8) bash completion -*- shell-script -*-
2#
3# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
4# Copyright (C) 2017-2018 Netronome Systems, Inc.
5#
6# Author: Quentin Monnet <quentin.monnet@netronome.com>
7
8# Takes a list of words in argument; each one of them is added to COMPREPLY if
9# it is not already present on the command line. Returns no value.
10_bpftool_once_attr()
11{
12 local w idx found
13 for w in $*; do
14 found=0
15 for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
16 if [[ $w == ${words[idx]} ]]; then
17 found=1
18 break
19 fi
20 done
21 [[ $found -eq 0 ]] && \
22 COMPREPLY+=( $( compgen -W "$w" -- "$cur" ) )
23 done
24}
25
26# Takes a list of words as argument; if any of those words is present on the
27# command line, return 0. Otherwise, return 1.
28_bpftool_search_list()
29{
30 local w idx
31 for w in $*; do
32 for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
33 [[ $w == ${words[idx]} ]] && return 0
34 done
35 done
36 return 1
37}
38
39# Takes a list of words in argument; adds them all to COMPREPLY if none of them
40# is already present on the command line. Returns no value.
41_bpftool_one_of_list()
42{
43 _bpftool_search_list $* && return 1
44 COMPREPLY+=( $( compgen -W "$*" -- "$cur" ) )
45}
46
47_bpftool_get_map_ids()
48{
49 COMPREPLY+=( $( compgen -W "$( bpftool -jp map 2>&1 | \
50 command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) )
51}
52
53# Takes map type and adds matching map ids to the list of suggestions.
54_bpftool_get_map_ids_for_type()
55{
56 local type="$1"
57 COMPREPLY+=( $( compgen -W "$( bpftool -jp map 2>&1 | \
58 command grep -C2 "$type" | \
59 command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) )
60}
61
62_bpftool_get_map_names()
63{
64 COMPREPLY+=( $( compgen -W "$( bpftool -jp map 2>&1 | \
65 command sed -n 's/.*"name": \(.*\),$/\1/p' )" -- "$cur" ) )
66}
67
68# Takes map type and adds matching map names to the list of suggestions.
69_bpftool_get_map_names_for_type()
70{
71 local type="$1"
72 COMPREPLY+=( $( compgen -W "$( bpftool -jp map 2>&1 | \
73 command grep -C2 "$type" | \
74 command sed -n 's/.*"name": \(.*\),$/\1/p' )" -- "$cur" ) )
75}
76
77_bpftool_get_prog_ids()
78{
79 COMPREPLY+=( $( compgen -W "$( bpftool -jp prog 2>&1 | \
80 command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) )
81}
82
83_bpftool_get_prog_tags()
84{
85 COMPREPLY+=( $( compgen -W "$( bpftool -jp prog 2>&1 | \
86 command sed -n 's/.*"tag": "\(.*\)",$/\1/p' )" -- "$cur" ) )
87}
88
89_bpftool_get_prog_names()
90{
91 COMPREPLY+=( $( compgen -W "$( bpftool -jp prog 2>&1 | \
92 command sed -n 's/.*"name": "\(.*\)",$/\1/p' )" -- "$cur" ) )
93}
94
95_bpftool_get_btf_ids()
96{
97 COMPREPLY+=( $( compgen -W "$( bpftool -jp btf 2>&1 | \
98 command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) )
99}
100
101_bpftool_get_link_ids()
102{
103 COMPREPLY+=( $( compgen -W "$( bpftool -jp link 2>&1 | \
104 command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) )
105}
106
107_bpftool_get_obj_map_names()
108{
109 local obj
110
111 obj=$1
112
113 maps=$(objdump -j maps -t $obj 2>/dev/null | \
114 command awk '/g . maps/ {print $NF}')
115
116 COMPREPLY+=( $( compgen -W "$maps" -- "$cur" ) )
117}
118
119_bpftool_get_obj_map_idxs()
120{
121 local obj
122
123 obj=$1
124
125 nmaps=$(objdump -j maps -t $obj 2>/dev/null | grep -c 'g . maps')
126
127 COMPREPLY+=( $( compgen -W "$(seq 0 $((nmaps - 1)))" -- "$cur" ) )
128}
129
130_sysfs_get_netdevs()
131{
132 COMPREPLY+=( $( compgen -W "$( ls /sys/class/net 2>/dev/null )" -- \
133 "$cur" ) )
134}
135
136# Retrieve type of the map that we are operating on.
137_bpftool_map_guess_map_type()
138{
139 local keyword ref
140 for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
141 case "${words[$((idx-2))]}" in
142 lookup|update)
143 keyword=${words[$((idx-1))]}
144 ref=${words[$((idx))]}
145 ;;
146 push)
147 printf "stack"
148 return 0
149 ;;
150 enqueue)
151 printf "queue"
152 return 0
153 ;;
154 esac
155 done
156 [[ -z $ref ]] && return 0
157
158 local type
159 type=$(bpftool -jp map show $keyword $ref | \
160 command sed -n 's/.*"type": "\(.*\)",$/\1/p')
161 [[ -n $type ]] && printf $type
162}
163
164_bpftool_map_update_get_id()
165{
166 local command="$1"
167
168 # Is it the map to update, or a map to insert into the map to update?
169 # Search for "value" keyword.
170 local idx value
171 for (( idx=7; idx < ${#words[@]}-1; idx++ )); do
172 if [[ ${words[idx]} == "value" ]]; then
173 value=1
174 break
175 fi
176 done
177 if [[ $value -eq 0 ]]; then
178 case "$command" in
179 push)
180 _bpftool_get_map_ids_for_type stack
181 ;;
182 enqueue)
183 _bpftool_get_map_ids_for_type queue
184 ;;
185 *)
186 _bpftool_get_map_ids
187 ;;
188 esac
189 return 0
190 fi
191
192 # Id to complete is for a value. It can be either prog id or map id. This
193 # depends on the type of the map to update.
194 local type=$(_bpftool_map_guess_map_type)
195 case $type in
196 array_of_maps|hash_of_maps)
197 _bpftool_get_map_ids
198 return 0
199 ;;
200 prog_array)
201 _bpftool_get_prog_ids
202 return 0
203 ;;
204 *)
205 return 0
206 ;;
207 esac
208}
209
210_bpftool_map_update_get_name()
211{
212 local command="$1"
213
214 # Is it the map to update, or a map to insert into the map to update?
215 # Search for "value" keyword.
216 local idx value
217 for (( idx=7; idx < ${#words[@]}-1; idx++ )); do
218 if [[ ${words[idx]} == "value" ]]; then
219 value=1
220 break
221 fi
222 done
223 if [[ $value -eq 0 ]]; then
224 case "$command" in
225 push)
226 _bpftool_get_map_names_for_type stack
227 ;;
228 enqueue)
229 _bpftool_get_map_names_for_type queue
230 ;;
231 *)
232 _bpftool_get_map_names
233 ;;
234 esac
235 return 0
236 fi
237
238 # Name to complete is for a value. It can be either prog name or map name. This
239 # depends on the type of the map to update.
240 local type=$(_bpftool_map_guess_map_type)
241 case $type in
242 array_of_maps|hash_of_maps)
243 _bpftool_get_map_names
244 return 0
245 ;;
246 prog_array)
247 _bpftool_get_prog_names
248 return 0
249 ;;
250 *)
251 return 0
252 ;;
253 esac
254}
255
256_bpftool()
257{
258 local cur prev words objword
259 _init_completion || return
260
261 # Deal with options
262 if [[ ${words[cword]} == -* ]]; then
263 local c='--version --json --pretty --bpffs --mapcompat --debug \
264 --use-loader --base-btf --legacy'
265 COMPREPLY=( $( compgen -W "$c" -- "$cur" ) )
266 return 0
267 fi
268
269 # Deal with simplest keywords
270 case $prev in
271 help|hex|opcodes|visual|linum)
272 return 0
273 ;;
274 tag)
275 _bpftool_get_prog_tags
276 return 0
277 ;;
278 dev)
279 _sysfs_get_netdevs
280 return 0
281 ;;
282 file|pinned|-B|--base-btf)
283 _filedir
284 return 0
285 ;;
286 batch)
287 COMPREPLY=( $( compgen -W 'file' -- "$cur" ) )
288 return 0
289 ;;
290 esac
291
292 # Remove all options so completions don't have to deal with them.
293 local i
294 for (( i=1; i < ${#words[@]}; )); do
295 if [[ ${words[i]::1} == - ]] &&
296 [[ ${words[i]} != "-B" ]] && [[ ${words[i]} != "--base-btf" ]]; then
297 words=( "${words[@]:0:i}" "${words[@]:i+1}" )
298 [[ $i -le $cword ]] && cword=$(( cword - 1 ))
299 else
300 i=$(( ++i ))
301 fi
302 done
303 cur=${words[cword]}
304 prev=${words[cword - 1]}
305 pprev=${words[cword - 2]}
306
307 local object=${words[1]} command=${words[2]}
308
309 if [[ -z $object || $cword -eq 1 ]]; then
310 case $cur in
311 *)
312 COMPREPLY=( $( compgen -W "$( bpftool help 2>&1 | \
313 command sed \
314 -e '/OBJECT := /!d' \
315 -e 's/.*{//' \
316 -e 's/}.*//' \
317 -e 's/|//g' )" -- "$cur" ) )
318 COMPREPLY+=( $( compgen -W 'batch help' -- "$cur" ) )
319 return 0
320 ;;
321 esac
322 fi
323
324 [[ $command == help ]] && return 0
325
326 # Completion depends on object and command in use
327 case $object in
328 prog)
329 # Complete id and name, only for subcommands that use prog (but no
330 # map) ids/names.
331 case $command in
332 show|list|dump|pin)
333 case $prev in
334 id)
335 _bpftool_get_prog_ids
336 return 0
337 ;;
338 name)
339 _bpftool_get_prog_names
340 return 0
341 ;;
342 esac
343 ;;
344 esac
345
346 local PROG_TYPE='id pinned tag name'
347 local MAP_TYPE='id pinned name'
348 local METRIC_TYPE='cycles instructions l1d_loads llc_misses \
349 itlb_misses dtlb_misses'
350 case $command in
351 show|list)
352 [[ $prev != "$command" ]] && return 0
353 COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
354 return 0
355 ;;
356 dump)
357 case $prev in
358 $command)
359 COMPREPLY+=( $( compgen -W "xlated jited" -- \
360 "$cur" ) )
361 return 0
362 ;;
363 xlated|jited)
364 COMPREPLY=( $( compgen -W "$PROG_TYPE" -- \
365 "$cur" ) )
366 return 0
367 ;;
368 *)
369 _bpftool_once_attr 'file'
370 if _bpftool_search_list 'xlated'; then
371 COMPREPLY+=( $( compgen -W 'opcodes visual linum' -- \
372 "$cur" ) )
373 else
374 COMPREPLY+=( $( compgen -W 'opcodes linum' -- \
375 "$cur" ) )
376 fi
377 return 0
378 ;;
379 esac
380 ;;
381 pin)
382 if [[ $prev == "$command" ]]; then
383 COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
384 else
385 _filedir
386 fi
387 return 0
388 ;;
389 attach|detach)
390 case $cword in
391 3)
392 COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
393 return 0
394 ;;
395 4)
396 case $prev in
397 id)
398 _bpftool_get_prog_ids
399 ;;
400 name)
401 _bpftool_get_prog_names
402 ;;
403 pinned)
404 _filedir
405 ;;
406 esac
407 return 0
408 ;;
409 5)
410 local BPFTOOL_PROG_ATTACH_TYPES='sk_msg_verdict \
411 sk_skb_verdict sk_skb_stream_verdict sk_skb_stream_parser \
412 flow_dissector'
413 COMPREPLY=( $( compgen -W "$BPFTOOL_PROG_ATTACH_TYPES" -- "$cur" ) )
414 return 0
415 ;;
416 6)
417 COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
418 return 0
419 ;;
420 7)
421 case $prev in
422 id)
423 _bpftool_get_map_ids
424 ;;
425 name)
426 _bpftool_get_map_names
427 ;;
428 pinned)
429 _filedir
430 ;;
431 esac
432 return 0
433 ;;
434 esac
435 ;;
436 load|loadall)
437 local obj
438
439 # Propose "load/loadall" to complete "bpftool prog load",
440 # or bash tries to complete "load" as a filename below.
441 if [[ ${#words[@]} -eq 3 ]]; then
442 COMPREPLY=( $( compgen -W "load loadall" -- "$cur" ) )
443 return 0
444 fi
445
446 if [[ ${#words[@]} -lt 6 ]]; then
447 _filedir
448 return 0
449 fi
450
451 obj=${words[3]}
452
453 if [[ ${words[-4]} == "map" ]]; then
454 COMPREPLY=( $( compgen -W "id pinned" -- "$cur" ) )
455 return 0
456 fi
457 if [[ ${words[-3]} == "map" ]]; then
458 if [[ ${words[-2]} == "idx" ]]; then
459 _bpftool_get_obj_map_idxs $obj
460 elif [[ ${words[-2]} == "name" ]]; then
461 _bpftool_get_obj_map_names $obj
462 fi
463 return 0
464 fi
465 if [[ ${words[-2]} == "map" ]]; then
466 COMPREPLY=( $( compgen -W "idx name" -- "$cur" ) )
467 return 0
468 fi
469
470 case $prev in
471 type)
472 local BPFTOOL_PROG_LOAD_TYPES='socket kprobe \
473 kretprobe classifier flow_dissector \
474 action tracepoint raw_tracepoint \
475 xdp perf_event cgroup/skb cgroup/sock \
476 cgroup/dev lwt_in lwt_out lwt_xmit \
477 lwt_seg6local sockops sk_skb sk_msg \
478 lirc_mode2 cgroup/bind4 cgroup/bind6 \
479 cgroup/connect4 cgroup/connect6 \
480 cgroup/getpeername4 cgroup/getpeername6 \
481 cgroup/getsockname4 cgroup/getsockname6 \
482 cgroup/sendmsg4 cgroup/sendmsg6 \
483 cgroup/recvmsg4 cgroup/recvmsg6 \
484 cgroup/post_bind4 cgroup/post_bind6 \
485 cgroup/sysctl cgroup/getsockopt \
486 cgroup/setsockopt cgroup/sock_release struct_ops \
487 fentry fexit freplace sk_lookup'
488 COMPREPLY=( $( compgen -W "$BPFTOOL_PROG_LOAD_TYPES" -- "$cur" ) )
489 return 0
490 ;;
491 id)
492 _bpftool_get_map_ids
493 return 0
494 ;;
495 name)
496 _bpftool_get_map_names
497 return 0
498 ;;
499 pinned|pinmaps)
500 _filedir
501 return 0
502 ;;
503 *)
504 COMPREPLY=( $( compgen -W "map" -- "$cur" ) )
505 _bpftool_once_attr 'type'
506 _bpftool_once_attr 'dev'
507 _bpftool_once_attr 'pinmaps'
508 return 0
509 ;;
510 esac
511 ;;
512 tracelog)
513 return 0
514 ;;
515 profile)
516 case $cword in
517 3)
518 COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
519 return 0
520 ;;
521 4)
522 case $prev in
523 id)
524 _bpftool_get_prog_ids
525 ;;
526 name)
527 _bpftool_get_prog_names
528 ;;
529 pinned)
530 _filedir
531 ;;
532 esac
533 return 0
534 ;;
535 5)
536 COMPREPLY=( $( compgen -W "$METRIC_TYPE duration" -- "$cur" ) )
537 return 0
538 ;;
539 6)
540 case $prev in
541 duration)
542 return 0
543 ;;
544 *)
545 COMPREPLY=( $( compgen -W "$METRIC_TYPE" -- "$cur" ) )
546 return 0
547 ;;
548 esac
549 return 0
550 ;;
551 *)
552 COMPREPLY=( $( compgen -W "$METRIC_TYPE" -- "$cur" ) )
553 return 0
554 ;;
555 esac
556 ;;
557 run)
558 if [[ ${#words[@]} -eq 4 ]]; then
559 COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
560 return 0
561 fi
562 case $prev in
563 id)
564 _bpftool_get_prog_ids
565 return 0
566 ;;
567 name)
568 _bpftool_get_prog_names
569 return 0
570 ;;
571 data_in|data_out|ctx_in|ctx_out)
572 _filedir
573 return 0
574 ;;
575 repeat|data_size_out|ctx_size_out)
576 return 0
577 ;;
578 *)
579 _bpftool_once_attr 'data_in data_out data_size_out \
580 ctx_in ctx_out ctx_size_out repeat'
581 return 0
582 ;;
583 esac
584 ;;
585 *)
586 [[ $prev == $object ]] && \
587 COMPREPLY=( $( compgen -W 'dump help pin attach detach \
588 load loadall show list tracelog run profile' -- "$cur" ) )
589 ;;
590 esac
591 ;;
592 struct_ops)
593 local STRUCT_OPS_TYPE='id name'
594 case $command in
595 show|list|dump|unregister)
596 case $prev in
597 $command)
598 COMPREPLY=( $( compgen -W "$STRUCT_OPS_TYPE" -- "$cur" ) )
599 ;;
600 id)
601 _bpftool_get_map_ids_for_type struct_ops
602 ;;
603 name)
604 _bpftool_get_map_names_for_type struct_ops
605 ;;
606 esac
607 return 0
608 ;;
609 register)
610 _filedir
611 return 0
612 ;;
613 *)
614 [[ $prev == $object ]] && \
615 COMPREPLY=( $( compgen -W 'register unregister show list dump help' \
616 -- "$cur" ) )
617 ;;
618 esac
619 ;;
620 iter)
621 case $command in
622 pin)
623 case $prev in
624 $command)
625 _filedir
626 ;;
627 id)
628 _bpftool_get_map_ids
629 ;;
630 name)
631 _bpftool_get_map_names
632 ;;
633 pinned)
634 _filedir
635 ;;
636 *)
637 _bpftool_one_of_list $MAP_TYPE
638 ;;
639 esac
640 return 0
641 ;;
642 *)
643 [[ $prev == $object ]] && \
644 COMPREPLY=( $( compgen -W 'pin help' \
645 -- "$cur" ) )
646 ;;
647 esac
648 ;;
649 map)
650 local MAP_TYPE='id pinned name'
651 case $command in
652 show|list|dump|peek|pop|dequeue|freeze)
653 case $prev in
654 $command)
655 COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
656 return 0
657 ;;
658 id)
659 case "$command" in
660 peek)
661 _bpftool_get_map_ids_for_type stack
662 _bpftool_get_map_ids_for_type queue
663 ;;
664 pop)
665 _bpftool_get_map_ids_for_type stack
666 ;;
667 dequeue)
668 _bpftool_get_map_ids_for_type queue
669 ;;
670 *)
671 _bpftool_get_map_ids
672 ;;
673 esac
674 return 0
675 ;;
676 name)
677 case "$command" in
678 peek)
679 _bpftool_get_map_names_for_type stack
680 _bpftool_get_map_names_for_type queue
681 ;;
682 pop)
683 _bpftool_get_map_names_for_type stack
684 ;;
685 dequeue)
686 _bpftool_get_map_names_for_type queue
687 ;;
688 *)
689 _bpftool_get_map_names
690 ;;
691 esac
692 return 0
693 ;;
694 *)
695 return 0
696 ;;
697 esac
698 ;;
699 create)
700 case $prev in
701 $command)
702 _filedir
703 return 0
704 ;;
705 type)
706 local BPFTOOL_MAP_CREATE_TYPES="$(bpftool feature list_builtins map_types 2>/dev/null | \
707 grep -v '^unspec$')"
708 COMPREPLY=( $( compgen -W "$BPFTOOL_MAP_CREATE_TYPES" -- "$cur" ) )
709 return 0
710 ;;
711 key|value|flags|entries)
712 return 0
713 ;;
714 inner_map)
715 COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
716 return 0
717 ;;
718 id)
719 _bpftool_get_map_ids
720 ;;
721 name)
722 case $pprev in
723 inner_map)
724 _bpftool_get_map_names
725 ;;
726 *)
727 return 0
728 ;;
729 esac
730 ;;
731 *)
732 _bpftool_once_attr 'type'
733 _bpftool_once_attr 'key'
734 _bpftool_once_attr 'value'
735 _bpftool_once_attr 'entries'
736 _bpftool_once_attr 'name'
737 _bpftool_once_attr 'flags'
738 if _bpftool_search_list 'array_of_maps' 'hash_of_maps'; then
739 _bpftool_once_attr 'inner_map'
740 fi
741 _bpftool_once_attr 'dev'
742 return 0
743 ;;
744 esac
745 ;;
746 lookup|getnext|delete)
747 case $prev in
748 $command)
749 COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
750 return 0
751 ;;
752 id)
753 _bpftool_get_map_ids
754 return 0
755 ;;
756 name)
757 _bpftool_get_map_names
758 return 0
759 ;;
760 key)
761 COMPREPLY+=( $( compgen -W 'hex' -- "$cur" ) )
762 ;;
763 *)
764 case $(_bpftool_map_guess_map_type) in
765 queue|stack)
766 return 0
767 ;;
768 esac
769
770 _bpftool_once_attr 'key'
771 return 0
772 ;;
773 esac
774 ;;
775 update|push|enqueue)
776 case $prev in
777 $command)
778 COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
779 return 0
780 ;;
781 id)
782 _bpftool_map_update_get_id $command
783 return 0
784 ;;
785 name)
786 _bpftool_map_update_get_name $command
787 return 0
788 ;;
789 key)
790 COMPREPLY+=( $( compgen -W 'hex' -- "$cur" ) )
791 ;;
792 value)
793 # We can have bytes, or references to a prog or a
794 # map, depending on the type of the map to update.
795 case "$(_bpftool_map_guess_map_type)" in
796 array_of_maps|hash_of_maps)
797 local MAP_TYPE='id pinned name'
798 COMPREPLY+=( $( compgen -W "$MAP_TYPE" \
799 -- "$cur" ) )
800 return 0
801 ;;
802 prog_array)
803 local PROG_TYPE='id pinned tag name'
804 COMPREPLY+=( $( compgen -W "$PROG_TYPE" \
805 -- "$cur" ) )
806 return 0
807 ;;
808 *)
809 COMPREPLY+=( $( compgen -W 'hex' \
810 -- "$cur" ) )
811 return 0
812 ;;
813 esac
814 return 0
815 ;;
816 *)
817 case $(_bpftool_map_guess_map_type) in
818 queue|stack)
819 _bpftool_once_attr 'value'
820 return 0;
821 ;;
822 esac
823
824 _bpftool_once_attr 'key'
825 local UPDATE_FLAGS='any exist noexist'
826 for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
827 if [[ ${words[idx]} == 'value' ]]; then
828 # 'value' is present, but is not the last
829 # word i.e. we can now have UPDATE_FLAGS.
830 _bpftool_one_of_list "$UPDATE_FLAGS"
831 return 0
832 fi
833 done
834 for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
835 if [[ ${words[idx]} == 'key' ]]; then
836 # 'key' is present, but is not the last
837 # word i.e. we can now have 'value'.
838 _bpftool_once_attr 'value'
839 return 0
840 fi
841 done
842
843 return 0
844 ;;
845 esac
846 ;;
847 pin)
848 case $prev in
849 $command)
850 COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
851 ;;
852 id)
853 _bpftool_get_map_ids
854 ;;
855 name)
856 _bpftool_get_map_names
857 ;;
858 esac
859 return 0
860 ;;
861 event_pipe)
862 case $prev in
863 $command)
864 COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
865 return 0
866 ;;
867 id)
868 _bpftool_get_map_ids_for_type perf_event_array
869 return 0
870 ;;
871 name)
872 _bpftool_get_map_names_for_type perf_event_array
873 return 0
874 ;;
875 cpu)
876 return 0
877 ;;
878 index)
879 return 0
880 ;;
881 *)
882 _bpftool_once_attr 'cpu'
883 _bpftool_once_attr 'index'
884 return 0
885 ;;
886 esac
887 ;;
888 *)
889 [[ $prev == $object ]] && \
890 COMPREPLY=( $( compgen -W 'delete dump getnext help \
891 lookup pin event_pipe show list update create \
892 peek push enqueue pop dequeue freeze' -- \
893 "$cur" ) )
894 ;;
895 esac
896 ;;
897 btf)
898 local PROG_TYPE='id pinned tag name'
899 local MAP_TYPE='id pinned name'
900 case $command in
901 dump)
902 case $prev in
903 $command)
904 COMPREPLY+=( $( compgen -W "id map prog file" -- \
905 "$cur" ) )
906 return 0
907 ;;
908 prog)
909 COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
910 return 0
911 ;;
912 map)
913 COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
914 return 0
915 ;;
916 id)
917 case $pprev in
918 prog)
919 _bpftool_get_prog_ids
920 ;;
921 map)
922 _bpftool_get_map_ids
923 ;;
924 $command)
925 _bpftool_get_btf_ids
926 ;;
927 esac
928 return 0
929 ;;
930 name)
931 case $pprev in
932 prog)
933 _bpftool_get_prog_names
934 ;;
935 map)
936 _bpftool_get_map_names
937 ;;
938 esac
939 return 0
940 ;;
941 format)
942 COMPREPLY=( $( compgen -W "c raw" -- "$cur" ) )
943 ;;
944 *)
945 # emit extra options
946 case ${words[3]} in
947 id|file)
948 _bpftool_once_attr 'format'
949 ;;
950 map|prog)
951 if [[ ${words[3]} == "map" ]] && [[ $cword == 6 ]]; then
952 COMPREPLY+=( $( compgen -W "key value kv all" -- "$cur" ) )
953 fi
954 _bpftool_once_attr 'format'
955 ;;
956 *)
957 ;;
958 esac
959 return 0
960 ;;
961 esac
962 ;;
963 show|list)
964 case $prev in
965 $command)
966 COMPREPLY+=( $( compgen -W "id" -- "$cur" ) )
967 ;;
968 id)
969 _bpftool_get_btf_ids
970 ;;
971 esac
972 return 0
973 ;;
974 *)
975 [[ $prev == $object ]] && \
976 COMPREPLY=( $( compgen -W 'dump help show list' \
977 -- "$cur" ) )
978 ;;
979 esac
980 ;;
981 gen)
982 case $command in
983 object)
984 _filedir
985 return 0
986 ;;
987 skeleton)
988 case $prev in
989 $command)
990 _filedir
991 return 0
992 ;;
993 *)
994 _bpftool_once_attr 'name'
995 return 0
996 ;;
997 esac
998 ;;
999 subskeleton)
1000 case $prev in
1001 $command)
1002 _filedir
1003 return 0
1004 ;;
1005 *)
1006 _bpftool_once_attr 'name'
1007 return 0
1008 ;;
1009 esac
1010 ;;
1011 min_core_btf)
1012 _filedir
1013 return 0
1014 ;;
1015 *)
1016 [[ $prev == $object ]] && \
1017 COMPREPLY=( $( compgen -W 'object skeleton subskeleton help min_core_btf' -- "$cur" ) )
1018 ;;
1019 esac
1020 ;;
1021 cgroup)
1022 case $command in
1023 show|list|tree)
1024 case $cword in
1025 3)
1026 _filedir
1027 ;;
1028 4)
1029 COMPREPLY=( $( compgen -W 'effective' -- "$cur" ) )
1030 ;;
1031 esac
1032 return 0
1033 ;;
1034 attach|detach)
1035 local BPFTOOL_CGROUP_ATTACH_TYPES="$(bpftool feature list_builtins attach_types 2>/dev/null | \
1036 grep '^cgroup_')"
1037 local ATTACH_FLAGS='multi override'
1038 local PROG_TYPE='id pinned tag name'
1039 # Check for $prev = $command first
1040 if [ $prev = $command ]; then
1041 _filedir
1042 return 0
1043 # Then check for attach type. This is done outside of the
1044 # "case $prev in" to avoid writing the whole list of attach
1045 # types again as pattern to match (where we cannot reuse
1046 # our variable).
1047 elif [[ $BPFTOOL_CGROUP_ATTACH_TYPES =~ $prev ]]; then
1048 COMPREPLY=( $( compgen -W "$PROG_TYPE" -- \
1049 "$cur" ) )
1050 return 0
1051 fi
1052 # case/esac for the other cases
1053 case $prev in
1054 id)
1055 _bpftool_get_prog_ids
1056 return 0
1057 ;;
1058 *)
1059 if ! _bpftool_search_list "$BPFTOOL_CGROUP_ATTACH_TYPES"; then
1060 COMPREPLY=( $( compgen -W \
1061 "$BPFTOOL_CGROUP_ATTACH_TYPES" -- "$cur" ) )
1062 elif [[ "$command" == "attach" ]]; then
1063 # We have an attach type on the command line,
1064 # but it is not the previous word, or
1065 # "id|pinned|tag|name" (we already checked for
1066 # that). This should only leave the case when
1067 # we need attach flags for "attach" commamnd.
1068 _bpftool_one_of_list "$ATTACH_FLAGS"
1069 fi
1070 return 0
1071 ;;
1072 esac
1073 ;;
1074 *)
1075 [[ $prev == $object ]] && \
1076 COMPREPLY=( $( compgen -W 'help attach detach \
1077 show list tree' -- "$cur" ) )
1078 ;;
1079 esac
1080 ;;
1081 perf)
1082 case $command in
1083 *)
1084 [[ $prev == $object ]] && \
1085 COMPREPLY=( $( compgen -W 'help \
1086 show list' -- "$cur" ) )
1087 ;;
1088 esac
1089 ;;
1090 net)
1091 local PROG_TYPE='id pinned tag name'
1092 local ATTACH_TYPES='xdp xdpgeneric xdpdrv xdpoffload'
1093 case $command in
1094 show|list)
1095 [[ $prev != "$command" ]] && return 0
1096 COMPREPLY=( $( compgen -W 'dev' -- "$cur" ) )
1097 return 0
1098 ;;
1099 attach)
1100 case $cword in
1101 3)
1102 COMPREPLY=( $( compgen -W "$ATTACH_TYPES" -- "$cur" ) )
1103 return 0
1104 ;;
1105 4)
1106 COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
1107 return 0
1108 ;;
1109 5)
1110 case $prev in
1111 id)
1112 _bpftool_get_prog_ids
1113 ;;
1114 name)
1115 _bpftool_get_prog_names
1116 ;;
1117 pinned)
1118 _filedir
1119 ;;
1120 esac
1121 return 0
1122 ;;
1123 6)
1124 COMPREPLY=( $( compgen -W 'dev' -- "$cur" ) )
1125 return 0
1126 ;;
1127 8)
1128 _bpftool_once_attr 'overwrite'
1129 return 0
1130 ;;
1131 esac
1132 ;;
1133 detach)
1134 case $cword in
1135 3)
1136 COMPREPLY=( $( compgen -W "$ATTACH_TYPES" -- "$cur" ) )
1137 return 0
1138 ;;
1139 4)
1140 COMPREPLY=( $( compgen -W 'dev' -- "$cur" ) )
1141 return 0
1142 ;;
1143 esac
1144 ;;
1145 *)
1146 [[ $prev == $object ]] && \
1147 COMPREPLY=( $( compgen -W 'help \
1148 show list attach detach' -- "$cur" ) )
1149 ;;
1150 esac
1151 ;;
1152 feature)
1153 case $command in
1154 probe)
1155 [[ $prev == "prefix" ]] && return 0
1156 if _bpftool_search_list 'macros'; then
1157 _bpftool_once_attr 'prefix'
1158 else
1159 COMPREPLY+=( $( compgen -W 'macros' -- "$cur" ) )
1160 fi
1161 _bpftool_one_of_list 'kernel dev'
1162 _bpftool_once_attr 'full unprivileged'
1163 return 0
1164 ;;
1165 list_builtins)
1166 [[ $prev != "$command" ]] && return 0
1167 COMPREPLY=( $( compgen -W 'prog_types map_types \
1168 attach_types link_types helpers' -- "$cur" ) )
1169 ;;
1170 *)
1171 [[ $prev == $object ]] && \
1172 COMPREPLY=( $( compgen -W 'help list_builtins probe' -- "$cur" ) )
1173 ;;
1174 esac
1175 ;;
1176 link)
1177 case $command in
1178 show|list|pin|detach)
1179 case $prev in
1180 id)
1181 _bpftool_get_link_ids
1182 return 0
1183 ;;
1184 esac
1185 ;;
1186 esac
1187
1188 local LINK_TYPE='id pinned'
1189 case $command in
1190 show|list)
1191 [[ $prev != "$command" ]] && return 0
1192 COMPREPLY=( $( compgen -W "$LINK_TYPE" -- "$cur" ) )
1193 return 0
1194 ;;
1195 pin|detach)
1196 if [[ $prev == "$command" ]]; then
1197 COMPREPLY=( $( compgen -W "$LINK_TYPE" -- "$cur" ) )
1198 else
1199 _filedir
1200 fi
1201 return 0
1202 ;;
1203 *)
1204 [[ $prev == $object ]] && \
1205 COMPREPLY=( $( compgen -W 'help pin show list' -- "$cur" ) )
1206 ;;
1207 esac
1208 ;;
1209 esac
1210} &&
1211complete -F _bpftool bpftool
1212
1213# ex: ts=4 sw=4 et filetype=sh