Skip to content
Navigation Menu
Toggle navigation
Sign in
In this repository
All GitHub Enterprise
↵
Jump to
↵
No suggested jump to results
In this repository
All GitHub Enterprise
↵
Jump to
↵
In this organization
All GitHub Enterprise
↵
Jump to
↵
In this repository
All GitHub Enterprise
↵
Jump to
↵
Sign in
Reseting focus
You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
Dismiss alert
{{ message }}
mariux64
/
linux
Public
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Issues
2
Pull requests
0
Actions
Projects
0
Wiki
Security
Insights
Additional navigation options
Code
Issues
Pull requests
Actions
Projects
Wiki
Security
Insights
Files
a7d22ca
Documentation
LICENSES
arch
block
certs
crypto
drivers
fs
include
init
ipc
kernel
lib
mm
net
samples
scripts
security
sound
tools
accounting
arch
bpf
bpftool
Documentation
bash-completion
bpftool
.gitignore
Makefile
btf.c
btf_dumper.c
cfg.c
cfg.h
cgroup.c
common.c
feature.c
jit_disasm.c
json_writer.c
json_writer.h
main.c
main.h
map.c
map_perf_ring.c
net.c
netlink_dumper.c
netlink_dumper.h
perf.c
prog.c
tracelog.c
xlated_dumper.c
xlated_dumper.h
.gitignore
Makefile
Makefile.helpers
bpf_asm.c
bpf_dbg.c
bpf_exp.l
bpf_exp.y
bpf_jit_disasm.c
build
cgroup
debugging
firewire
firmware
gpio
hv
iio
include
io_uring
kvm
laptop
leds
lib
memory-model
nfsd
objtool
pci
pcmcia
perf
power
scripts
spi
testing
thermal
time
usb
virtio
vm
wmi
Makefile
usr
virt
.clang-format
.cocciconfig
.get_maintainer.ignore
.gitattributes
.gitignore
.mailmap
COPYING
CREDITS
Kbuild
Kconfig
MAINTAINERS
Makefile
README
Breadcrumbs
linux
/
tools
/
bpf
/
bpftool
/
bash-completion
/
bpftool
Blame
Blame
Latest commit
History
History
879 lines (838 loc) · 31.8 KB
Breadcrumbs
linux
/
tools
/
bpf
/
bpftool
/
bash-completion
/
bpftool
Top
File metadata and controls
Code
Blame
879 lines (838 loc) · 31.8 KB
Raw
# bpftool(8) bash completion -*- shell-script -*- # # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) # Copyright (C) 2017-2018 Netronome Systems, Inc. # # Author: Quentin Monnet <quentin.monnet@netronome.com> # Takes a list of words in argument; each one of them is added to COMPREPLY if # it is not already present on the command line. Returns no value. _bpftool_once_attr() { local w idx found for w in $*; do found=0 for (( idx=3; idx < ${#words[@]}-1; idx++ )); do if [[ $w == ${words[idx]} ]]; then found=1 break fi done [[ $found -eq 0 ]] && \ COMPREPLY+=( $( compgen -W "$w" -- "$cur" ) ) done } # Takes a list of words as argument; if any of those words is present on the # command line, return 0. Otherwise, return 1. _bpftool_search_list() { local w idx for w in $*; do for (( idx=3; idx < ${#words[@]}-1; idx++ )); do [[ $w == ${words[idx]} ]] && return 0 done done return 1 } # Takes a list of words in argument; adds them all to COMPREPLY if none of them # is already present on the command line. Returns no value. _bpftool_one_of_list() { _bpftool_search_list $* && return 1 COMPREPLY+=( $( compgen -W "$*" -- "$cur" ) ) } _bpftool_get_map_ids() { COMPREPLY+=( $( compgen -W "$( bpftool -jp map 2>&1 | \ command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) ) } # Takes map type and adds matching map ids to the list of suggestions. _bpftool_get_map_ids_for_type() { local type="$1" COMPREPLY+=( $( compgen -W "$( bpftool -jp map 2>&1 | \ command grep -C2 "$type" | \ command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) ) } _bpftool_get_prog_ids() { COMPREPLY+=( $( compgen -W "$( bpftool -jp prog 2>&1 | \ command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) ) } _bpftool_get_prog_tags() { COMPREPLY+=( $( compgen -W "$( bpftool -jp prog 2>&1 | \ command sed -n 's/.*"tag": "\(.*\)",$/\1/p' )" -- "$cur" ) ) } _bpftool_get_prog_names() { COMPREPLY+=( $( compgen -W "$( bpftool -jp prog 2>&1 | \ command sed -n 's/.*"name": "\(.*\)",$/\1/p' )" -- "$cur" ) ) } _bpftool_get_btf_ids() { COMPREPLY+=( $( compgen -W "$( bpftool -jp btf 2>&1 | \ command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) ) } _bpftool_get_obj_map_names() { local obj obj=$1 maps=$(objdump -j maps -t $obj 2>/dev/null | \ command awk '/g . maps/ {print $NF}') COMPREPLY+=( $( compgen -W "$maps" -- "$cur" ) ) } _bpftool_get_obj_map_idxs() { local obj obj=$1 nmaps=$(objdump -j maps -t $obj 2>/dev/null | grep -c 'g . maps') COMPREPLY+=( $( compgen -W "$(seq 0 $((nmaps - 1)))" -- "$cur" ) ) } _sysfs_get_netdevs() { COMPREPLY+=( $( compgen -W "$( ls /sys/class/net 2>/dev/null )" -- \ "$cur" ) ) } # Retrieve type of the map that we are operating on. _bpftool_map_guess_map_type() { local keyword ref for (( idx=3; idx < ${#words[@]}-1; idx++ )); do case "${words[$((idx-2))]}" in lookup|update) keyword=${words[$((idx-1))]} ref=${words[$((idx))]} ;; push) printf "stack" return 0 ;; enqueue) printf "queue" return 0 ;; esac done [[ -z $ref ]] && return 0 local type type=$(bpftool -jp map show $keyword $ref | \ command sed -n 's/.*"type": "\(.*\)",$/\1/p') [[ -n $type ]] && printf $type } _bpftool_map_update_get_id() { local command="$1" # Is it the map to update, or a map to insert into the map to update? # Search for "value" keyword. local idx value for (( idx=7; idx < ${#words[@]}-1; idx++ )); do if [[ ${words[idx]} == "value" ]]; then value=1 break fi done if [[ $value -eq 0 ]]; then case "$command" in push) _bpftool_get_map_ids_for_type stack ;; enqueue) _bpftool_get_map_ids_for_type queue ;; *) _bpftool_get_map_ids ;; esac return 0 fi # Id to complete is for a value. It can be either prog id or map id. This # depends on the type of the map to update. local type=$(_bpftool_map_guess_map_type) case $type in array_of_maps|hash_of_maps) _bpftool_get_map_ids return 0 ;; prog_array) _bpftool_get_prog_ids return 0 ;; *) return 0 ;; esac } _bpftool() { local cur prev words objword _init_completion || return # Deal with options if [[ ${words[cword]} == -* ]]; then local c='--version --json --pretty --bpffs --mapcompat --debug' COMPREPLY=( $( compgen -W "$c" -- "$cur" ) ) return 0 fi # Deal with simplest keywords case $prev in help|hex|opcodes|visual|linum) return 0 ;; tag) _bpftool_get_prog_tags return 0 ;; name) _bpftool_get_prog_names return 0 ;; dev) _sysfs_get_netdevs return 0 ;; file|pinned) _filedir return 0 ;; batch) COMPREPLY=( $( compgen -W 'file' -- "$cur" ) ) return 0 ;; esac # Remove all options so completions don't have to deal with them. local i for (( i=1; i < ${#words[@]}; )); do if [[ ${words[i]::1} == - ]]; then words=( "${words[@]:0:i}" "${words[@]:i+1}" ) [[ $i -le $cword ]] && cword=$(( cword - 1 )) else i=$(( ++i )) fi done cur=${words[cword]} prev=${words[cword - 1]} pprev=${words[cword - 2]} local object=${words[1]} command=${words[2]} if [[ -z $object || $cword -eq 1 ]]; then case $cur in *) COMPREPLY=( $( compgen -W "$( bpftool help 2>&1 | \ command sed \ -e '/OBJECT := /!d' \ -e 's/.*{//' \ -e 's/}.*//' \ -e 's/|//g' )" -- "$cur" ) ) COMPREPLY+=( $( compgen -W 'batch help' -- "$cur" ) ) return 0 ;; esac fi [[ $command == help ]] && return 0 # Completion depends on object and command in use case $object in prog) # Complete id, only for subcommands that use prog (but no map) ids case $command in show|list|dump|pin) case $prev in id) _bpftool_get_prog_ids return 0 ;; esac ;; esac local PROG_TYPE='id pinned tag name' local MAP_TYPE='id pinned' case $command in show|list) [[ $prev != "$command" ]] && return 0 COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) ) return 0 ;; dump) case $prev in $command) COMPREPLY+=( $( compgen -W "xlated jited" -- \ "$cur" ) ) return 0 ;; xlated|jited) COMPREPLY=( $( compgen -W "$PROG_TYPE" -- \ "$cur" ) ) return 0 ;; *) _bpftool_once_attr 'file' if _bpftool_search_list 'xlated'; then COMPREPLY+=( $( compgen -W 'opcodes visual linum' -- \ "$cur" ) ) else COMPREPLY+=( $( compgen -W 'opcodes linum' -- \ "$cur" ) ) fi return 0 ;; esac ;; pin) if [[ $prev == "$command" ]]; then COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) ) else _filedir fi return 0 ;; attach|detach) case $cword in 3) COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) ) return 0 ;; 4) case $prev in id) _bpftool_get_prog_ids ;; pinned) _filedir ;; esac return 0 ;; 5) COMPREPLY=( $( compgen -W 'msg_verdict stream_verdict \ stream_parser flow_dissector' -- "$cur" ) ) return 0 ;; 6) COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) ) return 0 ;; 7) case $prev in id) _bpftool_get_map_ids ;; pinned) _filedir ;; esac return 0 ;; esac ;; load|loadall) local obj # Propose "load/loadall" to complete "bpftool prog load", # or bash tries to complete "load" as a filename below. if [[ ${#words[@]} -eq 3 ]]; then COMPREPLY=( $( compgen -W "load loadall" -- "$cur" ) ) return 0 fi if [[ ${#words[@]} -lt 6 ]]; then _filedir return 0 fi obj=${words[3]} if [[ ${words[-4]} == "map" ]]; then COMPREPLY=( $( compgen -W "id pinned" -- "$cur" ) ) return 0 fi if [[ ${words[-3]} == "map" ]]; then if [[ ${words[-2]} == "idx" ]]; then _bpftool_get_obj_map_idxs $obj elif [[ ${words[-2]} == "name" ]]; then _bpftool_get_obj_map_names $obj fi return 0 fi if [[ ${words[-2]} == "map" ]]; then COMPREPLY=( $( compgen -W "idx name" -- "$cur" ) ) return 0 fi case $prev in type) COMPREPLY=( $( compgen -W "socket kprobe \ kretprobe classifier flow_dissector \ action tracepoint raw_tracepoint \ xdp perf_event cgroup/skb cgroup/sock \ cgroup/dev lwt_in lwt_out lwt_xmit \ lwt_seg6local sockops sk_skb sk_msg \ lirc_mode2 cgroup/bind4 cgroup/bind6 \ cgroup/connect4 cgroup/connect6 \ cgroup/sendmsg4 cgroup/sendmsg6 \ cgroup/recvmsg4 cgroup/recvmsg6 \ cgroup/post_bind4 cgroup/post_bind6 \ cgroup/sysctl cgroup/getsockopt \ cgroup/setsockopt" -- \ "$cur" ) ) return 0 ;; id) _bpftool_get_map_ids return 0 ;; pinned|pinmaps) _filedir return 0 ;; *) COMPREPLY=( $( compgen -W "map" -- "$cur" ) ) _bpftool_once_attr 'type' _bpftool_once_attr 'dev' _bpftool_once_attr 'pinmaps' return 0 ;; esac ;; tracelog) return 0 ;; run) if [[ ${#words[@]} -lt 5 ]]; then _filedir return 0 fi case $prev in id) _bpftool_get_prog_ids return 0 ;; data_in|data_out|ctx_in|ctx_out) _filedir return 0 ;; repeat|data_size_out|ctx_size_out) return 0 ;; *) _bpftool_once_attr 'data_in data_out data_size_out \ ctx_in ctx_out ctx_size_out repeat' return 0 ;; esac ;; *) [[ $prev == $object ]] && \ COMPREPLY=( $( compgen -W 'dump help pin attach detach \ load loadall show list tracelog run' -- "$cur" ) ) ;; esac ;; map) local MAP_TYPE='id pinned' case $command in show|list|dump|peek|pop|dequeue|freeze) case $prev in $command) COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) ) return 0 ;; id) case "$command" in peek) _bpftool_get_map_ids_for_type stack _bpftool_get_map_ids_for_type queue ;; pop) _bpftool_get_map_ids_for_type stack ;; dequeue) _bpftool_get_map_ids_for_type queue ;; *) _bpftool_get_map_ids ;; esac return 0 ;; *) return 0 ;; esac ;; create) case $prev in $command) _filedir return 0 ;; type) COMPREPLY=( $( compgen -W 'hash array prog_array \ perf_event_array percpu_hash percpu_array \ stack_trace cgroup_array lru_hash \ lru_percpu_hash lpm_trie array_of_maps \ hash_of_maps devmap devmap_hash sockmap cpumap \ xskmap sockhash cgroup_storage reuseport_sockarray \ percpu_cgroup_storage queue stack' -- \ "$cur" ) ) return 0 ;; key|value|flags|name|entries) return 0 ;; *) _bpftool_once_attr 'type' _bpftool_once_attr 'key' _bpftool_once_attr 'value' _bpftool_once_attr 'entries' _bpftool_once_attr 'name' _bpftool_once_attr 'flags' _bpftool_once_attr 'dev' return 0 ;; esac ;; lookup|getnext|delete) case $prev in $command) COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) ) return 0 ;; id) _bpftool_get_map_ids return 0 ;; key) COMPREPLY+=( $( compgen -W 'hex' -- "$cur" ) ) ;; *) case $(_bpftool_map_guess_map_type) in queue|stack) return 0 ;; esac _bpftool_once_attr 'key' return 0 ;; esac ;; update|push|enqueue) case $prev in $command) COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) ) return 0 ;; id) _bpftool_map_update_get_id $command return 0 ;; key) COMPREPLY+=( $( compgen -W 'hex' -- "$cur" ) ) ;; value) # We can have bytes, or references to a prog or a # map, depending on the type of the map to update. case "$(_bpftool_map_guess_map_type)" in array_of_maps|hash_of_maps) local MAP_TYPE='id pinned' COMPREPLY+=( $( compgen -W "$MAP_TYPE" \ -- "$cur" ) ) return 0 ;; prog_array) local PROG_TYPE='id pinned tag name' COMPREPLY+=( $( compgen -W "$PROG_TYPE" \ -- "$cur" ) ) return 0 ;; *) COMPREPLY+=( $( compgen -W 'hex' \ -- "$cur" ) ) return 0 ;; esac return 0 ;; *) case $(_bpftool_map_guess_map_type) in queue|stack) _bpftool_once_attr 'value' return 0; ;; esac _bpftool_once_attr 'key' local UPDATE_FLAGS='any exist noexist' for (( idx=3; idx < ${#words[@]}-1; idx++ )); do if [[ ${words[idx]} == 'value' ]]; then # 'value' is present, but is not the last # word i.e. we can now have UPDATE_FLAGS. _bpftool_one_of_list "$UPDATE_FLAGS" return 0 fi done for (( idx=3; idx < ${#words[@]}-1; idx++ )); do if [[ ${words[idx]} == 'key' ]]; then # 'key' is present, but is not the last # word i.e. we can now have 'value'. _bpftool_once_attr 'value' return 0 fi done return 0 ;; esac ;; pin) if [[ $prev == "$command" ]]; then COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) ) else _filedir fi return 0 ;; event_pipe) case $prev in $command) COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) ) return 0 ;; id) _bpftool_get_map_ids_for_type perf_event_array return 0 ;; cpu) return 0 ;; index) return 0 ;; *) _bpftool_once_attr 'cpu' _bpftool_once_attr 'index' return 0 ;; esac ;; *) [[ $prev == $object ]] && \ COMPREPLY=( $( compgen -W 'delete dump getnext help \ lookup pin event_pipe show list update create \ peek push enqueue pop dequeue freeze' -- \ "$cur" ) ) ;; esac ;; btf) local PROG_TYPE='id pinned tag name' local MAP_TYPE='id pinned' case $command in dump) case $prev in $command) COMPREPLY+=( $( compgen -W "id map prog file" -- \ "$cur" ) ) return 0 ;; prog) COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) ) return 0 ;; map) COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) ) return 0 ;; id) case $pprev in prog) _bpftool_get_prog_ids ;; map) _bpftool_get_map_ids ;; $command) _bpftool_get_btf_ids ;; esac return 0 ;; format) COMPREPLY=( $( compgen -W "c raw" -- "$cur" ) ) ;; *) # emit extra options case ${words[3]} in id|file) _bpftool_once_attr 'format' ;; map|prog) if [[ ${words[3]} == "map" ]] && [[ $cword == 6 ]]; then COMPREPLY+=( $( compgen -W "key value kv all" -- "$cur" ) ) fi _bpftool_once_attr 'format' ;; *) ;; esac return 0 ;; esac ;; show|list) case $prev in $command) COMPREPLY+=( $( compgen -W "id" -- "$cur" ) ) ;; id) _bpftool_get_btf_ids ;; esac return 0 ;; *) [[ $prev == $object ]] && \ COMPREPLY=( $( compgen -W 'dump help show list' \ -- "$cur" ) ) ;; esac ;; cgroup) case $command in show|list|tree) case $cword in 3) _filedir ;; 4) COMPREPLY=( $( compgen -W 'effective' -- "$cur" ) ) ;; esac return 0 ;; attach|detach) local ATTACH_TYPES='ingress egress sock_create sock_ops \ device bind4 bind6 post_bind4 post_bind6 connect4 \ connect6 sendmsg4 sendmsg6 recvmsg4 recvmsg6 sysctl \ getsockopt setsockopt' local ATTACH_FLAGS='multi override' local PROG_TYPE='id pinned tag name' case $prev in $command) _filedir return 0 ;; ingress|egress|sock_create|sock_ops|device|bind4|bind6|\ post_bind4|post_bind6|connect4|connect6|sendmsg4|\ sendmsg6|recvmsg4|recvmsg6|sysctl|getsockopt|\ setsockopt) COMPREPLY=( $( compgen -W "$PROG_TYPE" -- \ "$cur" ) ) return 0 ;; id) _bpftool_get_prog_ids return 0 ;; *) if ! _bpftool_search_list "$ATTACH_TYPES"; then COMPREPLY=( $( compgen -W "$ATTACH_TYPES" -- \ "$cur" ) ) elif [[ "$command" == "attach" ]]; then # We have an attach type on the command line, # but it is not the previous word, or # "id|pinned|tag|name" (we already checked for # that). This should only leave the case when # we need attach flags for "attach" commamnd. _bpftool_one_of_list "$ATTACH_FLAGS" fi return 0 ;; esac ;; *) [[ $prev == $object ]] && \ COMPREPLY=( $( compgen -W 'help attach detach \ show list tree' -- "$cur" ) ) ;; esac ;; perf) case $command in *) [[ $prev == $object ]] && \ COMPREPLY=( $( compgen -W 'help \ show list' -- "$cur" ) ) ;; esac ;; net) local PROG_TYPE='id pinned tag name' local ATTACH_TYPES='xdp xdpgeneric xdpdrv xdpoffload' case $command in show|list) [[ $prev != "$command" ]] && return 0 COMPREPLY=( $( compgen -W 'dev' -- "$cur" ) ) return 0 ;; attach) case $cword in 3) COMPREPLY=( $( compgen -W "$ATTACH_TYPES" -- "$cur" ) ) return 0 ;; 4) COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) ) return 0 ;; 5) case $prev in id) _bpftool_get_prog_ids ;; pinned) _filedir ;; esac return 0 ;; 6) COMPREPLY=( $( compgen -W 'dev' -- "$cur" ) ) return 0 ;; 8) _bpftool_once_attr 'overwrite' return 0 ;; esac ;; detach) case $cword in 3) COMPREPLY=( $( compgen -W "$ATTACH_TYPES" -- "$cur" ) ) return 0 ;; 4) COMPREPLY=( $( compgen -W 'dev' -- "$cur" ) ) return 0 ;; esac ;; *) [[ $prev == $object ]] && \ COMPREPLY=( $( compgen -W 'help \ show list attach detach' -- "$cur" ) ) ;; esac ;; feature) case $command in probe) [[ $prev == "prefix" ]] && return 0 if _bpftool_search_list 'macros'; then COMPREPLY+=( $( compgen -W 'prefix' -- "$cur" ) ) else COMPREPLY+=( $( compgen -W 'macros' -- "$cur" ) ) fi _bpftool_one_of_list 'kernel dev' return 0 ;; *) [[ $prev == $object ]] && \ COMPREPLY=( $( compgen -W 'help probe' -- "$cur" ) ) ;; esac ;; esac } && complete -F _bpftool bpftool # ex: ts=4 sw=4 et filetype=sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
You can’t perform that action at this time.