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_obj_map_names()
102{
103 local obj
104
105 obj=$1
106
107 maps=$(objdump -j maps -t $obj 2>/dev/null | \
108 command awk '/g . maps/ {print $NF}')
109
110 COMPREPLY+=( $( compgen -W "$maps" -- "$cur" ) )
111}
112
113_bpftool_get_obj_map_idxs()
114{
115 local obj
116
117 obj=$1
118
119 nmaps=$(objdump -j maps -t $obj 2>/dev/null | grep -c 'g . maps')
120
121 COMPREPLY+=( $( compgen -W "$(seq 0 $((nmaps - 1)))" -- "$cur" ) )
122}
123
124_sysfs_get_netdevs()
125{
126 COMPREPLY+=( $( compgen -W "$( ls /sys/class/net 2>/dev/null )" -- \
127 "$cur" ) )
128}
129
130# Retrieve type of the map that we are operating on.
131_bpftool_map_guess_map_type()
132{
133 local keyword ref
134 for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
135 case "${words[$((idx-2))]}" in
136 lookup|update)
137 keyword=${words[$((idx-1))]}
138 ref=${words[$((idx))]}
139 ;;
140 push)
141 printf "stack"
142 return 0
143 ;;
144 enqueue)
145 printf "queue"
146 return 0
147 ;;
148 esac
149 done
150 [[ -z $ref ]] && return 0
151
152 local type
153 type=$(bpftool -jp map show $keyword $ref | \
154 command sed -n 's/.*"type": "\(.*\)",$/\1/p')
155 [[ -n $type ]] && printf $type
156}
157
158_bpftool_map_update_get_id()
159{
160 local command="$1"
161
162 # Is it the map to update, or a map to insert into the map to update?
163 # Search for "value" keyword.
164 local idx value
165 for (( idx=7; idx < ${#words[@]}-1; idx++ )); do
166 if [[ ${words[idx]} == "value" ]]; then
167 value=1
168 break
169 fi
170 done
171 if [[ $value -eq 0 ]]; then
172 case "$command" in
173 push)
174 _bpftool_get_map_ids_for_type stack
175 ;;
176 enqueue)
177 _bpftool_get_map_ids_for_type queue
178 ;;
179 *)
180 _bpftool_get_map_ids
181 ;;
182 esac
183 return 0
184 fi
185
186 # Id to complete is for a value. It can be either prog id or map id. This
187 # depends on the type of the map to update.
188 local type=$(_bpftool_map_guess_map_type)
189 case $type in
190 array_of_maps|hash_of_maps)
191 _bpftool_get_map_ids
192 return 0
193 ;;
194 prog_array)
195 _bpftool_get_prog_ids
196 return 0
197 ;;
198 *)
199 return 0
200 ;;
201 esac
202}
203
204_bpftool_map_update_get_name()
205{
206 local command="$1"
207
208 # Is it the map to update, or a map to insert into the map to update?
209 # Search for "value" keyword.
210 local idx value
211 for (( idx=7; idx < ${#words[@]}-1; idx++ )); do
212 if [[ ${words[idx]} == "value" ]]; then
213 value=1
214 break
215 fi
216 done
217 if [[ $value -eq 0 ]]; then
218 case "$command" in
219 push)
220 _bpftool_get_map_names_for_type stack
221 ;;
222 enqueue)
223 _bpftool_get_map_names_for_type queue
224 ;;
225 *)
226 _bpftool_get_map_names
227 ;;
228 esac
229 return 0
230 fi
231
232 # Name to complete is for a value. It can be either prog name or map name. This
233 # depends on the type of the map to update.
234 local type=$(_bpftool_map_guess_map_type)
235 case $type in
236 array_of_maps|hash_of_maps)
237 _bpftool_get_map_names
238 return 0
239 ;;
240 prog_array)
241 _bpftool_get_prog_names
242 return 0
243 ;;
244 *)
245 return 0
246 ;;
247 esac
248}
249
250_bpftool()
251{
252 local cur prev words objword
253 _init_completion || return
254
255 # Deal with options
256 if [[ ${words[cword]} == -* ]]; then
257 local c='--version --json --pretty --bpffs --mapcompat --debug'
258 COMPREPLY=( $( compgen -W "$c" -- "$cur" ) )
259 return 0
260 fi
261
262 # Deal with simplest keywords
263 case $prev in
264 help|hex|opcodes|visual|linum)
265 return 0
266 ;;
267 tag)
268 _bpftool_get_prog_tags
269 return 0
270 ;;
271 dev)
272 _sysfs_get_netdevs
273 return 0
274 ;;
275 file|pinned)
276 _filedir
277 return 0
278 ;;
279 batch)
280 COMPREPLY=( $( compgen -W 'file' -- "$cur" ) )
281 return 0
282 ;;
283 esac
284
285 # Remove all options so completions don't have to deal with them.
286 local i
287 for (( i=1; i < ${#words[@]}; )); do
288 if [[ ${words[i]::1} == - ]]; then
289 words=( "${words[@]:0:i}" "${words[@]:i+1}" )
290 [[ $i -le $cword ]] && cword=$(( cword - 1 ))
291 else
292 i=$(( ++i ))
293 fi
294 done
295 cur=${words[cword]}
296 prev=${words[cword - 1]}
297 pprev=${words[cword - 2]}
298
299 local object=${words[1]} command=${words[2]}
300
301 if [[ -z $object || $cword -eq 1 ]]; then
302 case $cur in
303 *)
304 COMPREPLY=( $( compgen -W "$( bpftool help 2>&1 | \
305 command sed \
306 -e '/OBJECT := /!d' \
307 -e 's/.*{//' \
308 -e 's/}.*//' \
309 -e 's/|//g' )" -- "$cur" ) )
310 COMPREPLY+=( $( compgen -W 'batch help' -- "$cur" ) )
311 return 0
312 ;;
313 esac
314 fi
315
316 [[ $command == help ]] && return 0
317
318 # Completion depends on object and command in use
319 case $object in
320 prog)
321 # Complete id and name, only for subcommands that use prog (but no
322 # map) ids/names.
323 case $command in
324 show|list|dump|pin)
325 case $prev in
326 id)
327 _bpftool_get_prog_ids
328 return 0
329 ;;
330 name)
331 _bpftool_get_prog_names
332 return 0
333 ;;
334 esac
335 ;;
336 esac
337
338 local PROG_TYPE='id pinned tag name'
339 local MAP_TYPE='id pinned name'
340 local METRIC_TYPE='cycles instructions l1d_loads llc_misses'
341 case $command in
342 show|list)
343 [[ $prev != "$command" ]] && return 0
344 COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
345 return 0
346 ;;
347 dump)
348 case $prev in
349 $command)
350 COMPREPLY+=( $( compgen -W "xlated jited" -- \
351 "$cur" ) )
352 return 0
353 ;;
354 xlated|jited)
355 COMPREPLY=( $( compgen -W "$PROG_TYPE" -- \
356 "$cur" ) )
357 return 0
358 ;;
359 *)
360 _bpftool_once_attr 'file'
361 if _bpftool_search_list 'xlated'; then
362 COMPREPLY+=( $( compgen -W 'opcodes visual linum' -- \
363 "$cur" ) )
364 else
365 COMPREPLY+=( $( compgen -W 'opcodes linum' -- \
366 "$cur" ) )
367 fi
368 return 0
369 ;;
370 esac
371 ;;
372 pin)
373 if [[ $prev == "$command" ]]; then
374 COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
375 else
376 _filedir
377 fi
378 return 0
379 ;;
380 attach|detach)
381 case $cword in
382 3)
383 COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
384 return 0
385 ;;
386 4)
387 case $prev in
388 id)
389 _bpftool_get_prog_ids
390 ;;
391 name)
392 _bpftool_get_prog_names
393 ;;
394 pinned)
395 _filedir
396 ;;
397 esac
398 return 0
399 ;;
400 5)
401 COMPREPLY=( $( compgen -W 'msg_verdict stream_verdict \
402 stream_parser flow_dissector' -- "$cur" ) )
403 return 0
404 ;;
405 6)
406 COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
407 return 0
408 ;;
409 7)
410 case $prev in
411 id)
412 _bpftool_get_map_ids
413 ;;
414 name)
415 _bpftool_get_map_names
416 ;;
417 pinned)
418 _filedir
419 ;;
420 esac
421 return 0
422 ;;
423 esac
424 ;;
425 load|loadall)
426 local obj
427
428 # Propose "load/loadall" to complete "bpftool prog load",
429 # or bash tries to complete "load" as a filename below.
430 if [[ ${#words[@]} -eq 3 ]]; then
431 COMPREPLY=( $( compgen -W "load loadall" -- "$cur" ) )
432 return 0
433 fi
434
435 if [[ ${#words[@]} -lt 6 ]]; then
436 _filedir
437 return 0
438 fi
439
440 obj=${words[3]}
441
442 if [[ ${words[-4]} == "map" ]]; then
443 COMPREPLY=( $( compgen -W "id pinned" -- "$cur" ) )
444 return 0
445 fi
446 if [[ ${words[-3]} == "map" ]]; then
447 if [[ ${words[-2]} == "idx" ]]; then
448 _bpftool_get_obj_map_idxs $obj
449 elif [[ ${words[-2]} == "name" ]]; then
450 _bpftool_get_obj_map_names $obj
451 fi
452 return 0
453 fi
454 if [[ ${words[-2]} == "map" ]]; then
455 COMPREPLY=( $( compgen -W "idx name" -- "$cur" ) )
456 return 0
457 fi
458
459 case $prev in
460 type)
461 COMPREPLY=( $( compgen -W "socket kprobe \
462 kretprobe classifier flow_dissector \
463 action tracepoint raw_tracepoint \
464 xdp perf_event cgroup/skb cgroup/sock \
465 cgroup/dev lwt_in lwt_out lwt_xmit \
466 lwt_seg6local sockops sk_skb sk_msg \
467 lirc_mode2 cgroup/bind4 cgroup/bind6 \
468 cgroup/connect4 cgroup/connect6 \
469 cgroup/sendmsg4 cgroup/sendmsg6 \
470 cgroup/recvmsg4 cgroup/recvmsg6 \
471 cgroup/post_bind4 cgroup/post_bind6 \
472 cgroup/sysctl cgroup/getsockopt \
473 cgroup/setsockopt struct_ops \
474 fentry fexit freplace" -- \
475 "$cur" ) )
476 return 0
477 ;;
478 id)
479 _bpftool_get_map_ids
480 return 0
481 ;;
482 name)
483 _bpftool_get_map_names
484 return 0
485 ;;
486 pinned|pinmaps)
487 _filedir
488 return 0
489 ;;
490 *)
491 COMPREPLY=( $( compgen -W "map" -- "$cur" ) )
492 _bpftool_once_attr 'type'
493 _bpftool_once_attr 'dev'
494 _bpftool_once_attr 'pinmaps'
495 return 0
496 ;;
497 esac
498 ;;
499 tracelog)
500 return 0
501 ;;
502 profile)
503 case $cword in
504 3)
505 COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
506 return 0
507 ;;
508 4)
509 case $prev in
510 id)
511 _bpftool_get_prog_ids
512 ;;
513 name)
514 _bpftool_get_prog_names
515 ;;
516 pinned)
517 _filedir
518 ;;
519 esac
520 return 0
521 ;;
522 5)
523 COMPREPLY=( $( compgen -W "$METRIC_TYPE duration" -- "$cur" ) )
524 return 0
525 ;;
526 6)
527 case $prev in
528 duration)
529 return 0
530 ;;
531 *)
532 COMPREPLY=( $( compgen -W "$METRIC_TYPE" -- "$cur" ) )
533 return 0
534 ;;
535 esac
536 return 0
537 ;;
538 *)
539 COMPREPLY=( $( compgen -W "$METRIC_TYPE" -- "$cur" ) )
540 return 0
541 ;;
542 esac
543 ;;
544 run)
545 if [[ ${#words[@]} -eq 4 ]]; then
546 COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
547 return 0
548 fi
549 case $prev in
550 id)
551 _bpftool_get_prog_ids
552 return 0
553 ;;
554 name)
555 _bpftool_get_prog_names
556 return 0
557 ;;
558 data_in|data_out|ctx_in|ctx_out)
559 _filedir
560 return 0
561 ;;
562 repeat|data_size_out|ctx_size_out)
563 return 0
564 ;;
565 *)
566 _bpftool_once_attr 'data_in data_out data_size_out \
567 ctx_in ctx_out ctx_size_out repeat'
568 return 0
569 ;;
570 esac
571 ;;
572 *)
573 [[ $prev == $object ]] && \
574 COMPREPLY=( $( compgen -W 'dump help pin attach detach \
575 load loadall show list tracelog run profile' -- "$cur" ) )
576 ;;
577 esac
578 ;;
579 struct_ops)
580 local STRUCT_OPS_TYPE='id name'
581 case $command in
582 show|list|dump|unregister)
583 case $prev in
584 $command)
585 COMPREPLY=( $( compgen -W "$STRUCT_OPS_TYPE" -- "$cur" ) )
586 ;;
587 id)
588 _bpftool_get_map_ids_for_type struct_ops
589 ;;
590 name)
591 _bpftool_get_map_names_for_type struct_ops
592 ;;
593 esac
594 return 0
595 ;;
596 register)
597 _filedir
598 return 0
599 ;;
600 *)
601 [[ $prev == $object ]] && \
602 COMPREPLY=( $( compgen -W 'register unregister show list dump help' \
603 -- "$cur" ) )
604 ;;
605 esac
606 ;;
607 map)
608 local MAP_TYPE='id pinned name'
609 case $command in
610 show|list|dump|peek|pop|dequeue|freeze)
611 case $prev in
612 $command)
613 COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
614 return 0
615 ;;
616 id)
617 case "$command" in
618 peek)
619 _bpftool_get_map_ids_for_type stack
620 _bpftool_get_map_ids_for_type queue
621 ;;
622 pop)
623 _bpftool_get_map_ids_for_type stack
624 ;;
625 dequeue)
626 _bpftool_get_map_ids_for_type queue
627 ;;
628 *)
629 _bpftool_get_map_ids
630 ;;
631 esac
632 return 0
633 ;;
634 name)
635 case "$command" in
636 peek)
637 _bpftool_get_map_names_for_type stack
638 _bpftool_get_map_names_for_type queue
639 ;;
640 pop)
641 _bpftool_get_map_names_for_type stack
642 ;;
643 dequeue)
644 _bpftool_get_map_names_for_type queue
645 ;;
646 *)
647 _bpftool_get_map_names
648 ;;
649 esac
650 return 0
651 ;;
652 *)
653 return 0
654 ;;
655 esac
656 ;;
657 create)
658 case $prev in
659 $command)
660 _filedir
661 return 0
662 ;;
663 type)
664 COMPREPLY=( $( compgen -W 'hash array prog_array \
665 perf_event_array percpu_hash percpu_array \
666 stack_trace cgroup_array lru_hash \
667 lru_percpu_hash lpm_trie array_of_maps \
668 hash_of_maps devmap devmap_hash sockmap cpumap \
669 xskmap sockhash cgroup_storage reuseport_sockarray \
670 percpu_cgroup_storage queue stack' -- \
671 "$cur" ) )
672 return 0
673 ;;
674 key|value|flags|name|entries)
675 return 0
676 ;;
677 *)
678 _bpftool_once_attr 'type'
679 _bpftool_once_attr 'key'
680 _bpftool_once_attr 'value'
681 _bpftool_once_attr 'entries'
682 _bpftool_once_attr 'name'
683 _bpftool_once_attr 'flags'
684 _bpftool_once_attr 'dev'
685 return 0
686 ;;
687 esac
688 ;;
689 lookup|getnext|delete)
690 case $prev in
691 $command)
692 COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
693 return 0
694 ;;
695 id)
696 _bpftool_get_map_ids
697 return 0
698 ;;
699 name)
700 _bpftool_get_map_names
701 return 0
702 ;;
703 key)
704 COMPREPLY+=( $( compgen -W 'hex' -- "$cur" ) )
705 ;;
706 *)
707 case $(_bpftool_map_guess_map_type) in
708 queue|stack)
709 return 0
710 ;;
711 esac
712
713 _bpftool_once_attr 'key'
714 return 0
715 ;;
716 esac
717 ;;
718 update|push|enqueue)
719 case $prev in
720 $command)
721 COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
722 return 0
723 ;;
724 id)
725 _bpftool_map_update_get_id $command
726 return 0
727 ;;
728 name)
729 _bpftool_map_update_get_name $command
730 return 0
731 ;;
732 key)
733 COMPREPLY+=( $( compgen -W 'hex' -- "$cur" ) )
734 ;;
735 value)
736 # We can have bytes, or references to a prog or a
737 # map, depending on the type of the map to update.
738 case "$(_bpftool_map_guess_map_type)" in
739 array_of_maps|hash_of_maps)
740 local MAP_TYPE='id pinned name'
741 COMPREPLY+=( $( compgen -W "$MAP_TYPE" \
742 -- "$cur" ) )
743 return 0
744 ;;
745 prog_array)
746 local PROG_TYPE='id pinned tag name'
747 COMPREPLY+=( $( compgen -W "$PROG_TYPE" \
748 -- "$cur" ) )
749 return 0
750 ;;
751 *)
752 COMPREPLY+=( $( compgen -W 'hex' \
753 -- "$cur" ) )
754 return 0
755 ;;
756 esac
757 return 0
758 ;;
759 *)
760 case $(_bpftool_map_guess_map_type) in
761 queue|stack)
762 _bpftool_once_attr 'value'
763 return 0;
764 ;;
765 esac
766
767 _bpftool_once_attr 'key'
768 local UPDATE_FLAGS='any exist noexist'
769 for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
770 if [[ ${words[idx]} == 'value' ]]; then
771 # 'value' is present, but is not the last
772 # word i.e. we can now have UPDATE_FLAGS.
773 _bpftool_one_of_list "$UPDATE_FLAGS"
774 return 0
775 fi
776 done
777 for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
778 if [[ ${words[idx]} == 'key' ]]; then
779 # 'key' is present, but is not the last
780 # word i.e. we can now have 'value'.
781 _bpftool_once_attr 'value'
782 return 0
783 fi
784 done
785
786 return 0
787 ;;
788 esac
789 ;;
790 pin)
791 case $prev in
792 $command)
793 COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
794 ;;
795 id)
796 _bpftool_get_map_ids
797 ;;
798 name)
799 _bpftool_get_map_names
800 ;;
801 esac
802 return 0
803 ;;
804 event_pipe)
805 case $prev in
806 $command)
807 COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
808 return 0
809 ;;
810 id)
811 _bpftool_get_map_ids_for_type perf_event_array
812 return 0
813 ;;
814 name)
815 _bpftool_get_map_names_for_type perf_event_array
816 return 0
817 ;;
818 cpu)
819 return 0
820 ;;
821 index)
822 return 0
823 ;;
824 *)
825 _bpftool_once_attr 'cpu'
826 _bpftool_once_attr 'index'
827 return 0
828 ;;
829 esac
830 ;;
831 *)
832 [[ $prev == $object ]] && \
833 COMPREPLY=( $( compgen -W 'delete dump getnext help \
834 lookup pin event_pipe show list update create \
835 peek push enqueue pop dequeue freeze' -- \
836 "$cur" ) )
837 ;;
838 esac
839 ;;
840 btf)
841 local PROG_TYPE='id pinned tag name'
842 local MAP_TYPE='id pinned name'
843 case $command in
844 dump)
845 case $prev in
846 $command)
847 COMPREPLY+=( $( compgen -W "id map prog file" -- \
848 "$cur" ) )
849 return 0
850 ;;
851 prog)
852 COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
853 return 0
854 ;;
855 map)
856 COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
857 return 0
858 ;;
859 id)
860 case $pprev in
861 prog)
862 _bpftool_get_prog_ids
863 ;;
864 map)
865 _bpftool_get_map_ids
866 ;;
867 $command)
868 _bpftool_get_btf_ids
869 ;;
870 esac
871 return 0
872 ;;
873 name)
874 case $pprev in
875 prog)
876 _bpftool_get_prog_names
877 ;;
878 map)
879 _bpftool_get_map_names
880 ;;
881 esac
882 return 0
883 ;;
884 format)
885 COMPREPLY=( $( compgen -W "c raw" -- "$cur" ) )
886 ;;
887 *)
888 # emit extra options
889 case ${words[3]} in
890 id|file)
891 _bpftool_once_attr 'format'
892 ;;
893 map|prog)
894 if [[ ${words[3]} == "map" ]] && [[ $cword == 6 ]]; then
895 COMPREPLY+=( $( compgen -W "key value kv all" -- "$cur" ) )
896 fi
897 _bpftool_once_attr 'format'
898 ;;
899 *)
900 ;;
901 esac
902 return 0
903 ;;
904 esac
905 ;;
906 show|list)
907 case $prev in
908 $command)
909 COMPREPLY+=( $( compgen -W "id" -- "$cur" ) )
910 ;;
911 id)
912 _bpftool_get_btf_ids
913 ;;
914 esac
915 return 0
916 ;;
917 *)
918 [[ $prev == $object ]] && \
919 COMPREPLY=( $( compgen -W 'dump help show list' \
920 -- "$cur" ) )
921 ;;
922 esac
923 ;;
924 gen)
925 case $command in
926 skeleton)
927 _filedir
928 ;;
929 *)
930 [[ $prev == $object ]] && \
931 COMPREPLY=( $( compgen -W 'skeleton help' -- "$cur" ) )
932 ;;
933 esac
934 ;;
935 cgroup)
936 case $command in
937 show|list|tree)
938 case $cword in
939 3)
940 _filedir
941 ;;
942 4)
943 COMPREPLY=( $( compgen -W 'effective' -- "$cur" ) )
944 ;;
945 esac
946 return 0
947 ;;
948 attach|detach)
949 local ATTACH_TYPES='ingress egress sock_create sock_ops \
950 device bind4 bind6 post_bind4 post_bind6 connect4 \
951 connect6 sendmsg4 sendmsg6 recvmsg4 recvmsg6 sysctl \
952 getsockopt setsockopt'
953 local ATTACH_FLAGS='multi override'
954 local PROG_TYPE='id pinned tag name'
955 case $prev in
956 $command)
957 _filedir
958 return 0
959 ;;
960 ingress|egress|sock_create|sock_ops|device|bind4|bind6|\
961 post_bind4|post_bind6|connect4|connect6|sendmsg4|\
962 sendmsg6|recvmsg4|recvmsg6|sysctl|getsockopt|\
963 setsockopt)
964 COMPREPLY=( $( compgen -W "$PROG_TYPE" -- \
965 "$cur" ) )
966 return 0
967 ;;
968 id)
969 _bpftool_get_prog_ids
970 return 0
971 ;;
972 *)
973 if ! _bpftool_search_list "$ATTACH_TYPES"; then
974 COMPREPLY=( $( compgen -W "$ATTACH_TYPES" -- \
975 "$cur" ) )
976 elif [[ "$command" == "attach" ]]; then
977 # We have an attach type on the command line,
978 # but it is not the previous word, or
979 # "id|pinned|tag|name" (we already checked for
980 # that). This should only leave the case when
981 # we need attach flags for "attach" commamnd.
982 _bpftool_one_of_list "$ATTACH_FLAGS"
983 fi
984 return 0
985 ;;
986 esac
987 ;;
988 *)
989 [[ $prev == $object ]] && \
990 COMPREPLY=( $( compgen -W 'help attach detach \
991 show list tree' -- "$cur" ) )
992 ;;
993 esac
994 ;;
995 perf)
996 case $command in
997 *)
998 [[ $prev == $object ]] && \
999 COMPREPLY=( $( compgen -W 'help \
1000 show list' -- "$cur" ) )
1001 ;;
1002 esac
1003 ;;
1004 net)
1005 local PROG_TYPE='id pinned tag name'
1006 local ATTACH_TYPES='xdp xdpgeneric xdpdrv xdpoffload'
1007 case $command in
1008 show|list)
1009 [[ $prev != "$command" ]] && return 0
1010 COMPREPLY=( $( compgen -W 'dev' -- "$cur" ) )
1011 return 0
1012 ;;
1013 attach)
1014 case $cword in
1015 3)
1016 COMPREPLY=( $( compgen -W "$ATTACH_TYPES" -- "$cur" ) )
1017 return 0
1018 ;;
1019 4)
1020 COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
1021 return 0
1022 ;;
1023 5)
1024 case $prev in
1025 id)
1026 _bpftool_get_prog_ids
1027 ;;
1028 name)
1029 _bpftool_get_prog_names
1030 ;;
1031 pinned)
1032 _filedir
1033 ;;
1034 esac
1035 return 0
1036 ;;
1037 6)
1038 COMPREPLY=( $( compgen -W 'dev' -- "$cur" ) )
1039 return 0
1040 ;;
1041 8)
1042 _bpftool_once_attr 'overwrite'
1043 return 0
1044 ;;
1045 esac
1046 ;;
1047 detach)
1048 case $cword in
1049 3)
1050 COMPREPLY=( $( compgen -W "$ATTACH_TYPES" -- "$cur" ) )
1051 return 0
1052 ;;
1053 4)
1054 COMPREPLY=( $( compgen -W 'dev' -- "$cur" ) )
1055 return 0
1056 ;;
1057 esac
1058 ;;
1059 *)
1060 [[ $prev == $object ]] && \
1061 COMPREPLY=( $( compgen -W 'help \
1062 show list attach detach' -- "$cur" ) )
1063 ;;
1064 esac
1065 ;;
1066 feature)
1067 case $command in
1068 probe)
1069 [[ $prev == "prefix" ]] && return 0
1070 if _bpftool_search_list 'macros'; then
1071 _bpftool_once_attr 'prefix'
1072 else
1073 COMPREPLY+=( $( compgen -W 'macros' -- "$cur" ) )
1074 fi
1075 _bpftool_one_of_list 'kernel dev'
1076 _bpftool_once_attr 'full'
1077 return 0
1078 ;;
1079 *)
1080 [[ $prev == $object ]] && \
1081 COMPREPLY=( $( compgen -W 'help probe' -- "$cur" ) )
1082 ;;
1083 esac
1084 ;;
1085 esac
1086} &&
1087complete -F _bpftool bpftool
1088
1089# ex: ts=4 sw=4 et filetype=sh