Linux 5.1.15
[linux/fpc-iii.git] / tools / bpf / bpftool / bash-completion / bpftool
blobb803827d01e8843941d40de02e819a3af8eee079
1 # bpftool(8) bash completion                               -*- shell-script -*-
3 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
4 # Copyright (C) 2017-2018 Netronome Systems, Inc.
6 # Author: Quentin Monnet <quentin.monnet@netronome.com>
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()
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
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()
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
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()
43     _bpftool_search_list $* && return 1
44     COMPREPLY+=( $( compgen -W "$*" -- "$cur" ) )
47 _bpftool_get_map_ids()
49     COMPREPLY+=( $( compgen -W "$( bpftool -jp map  2>&1 | \
50         command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) )
53 # Takes map type and adds matching map ids to the list of suggestions.
54 _bpftool_get_map_ids_for_type()
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" ) )
62 _bpftool_get_prog_ids()
64     COMPREPLY+=( $( compgen -W "$( bpftool -jp prog 2>&1 | \
65         command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) )
68 _bpftool_get_prog_tags()
70     COMPREPLY+=( $( compgen -W "$( bpftool -jp prog 2>&1 | \
71         command sed -n 's/.*"tag": "\(.*\)",$/\1/p' )" -- "$cur" ) )
74 _bpftool_get_obj_map_names()
76     local obj
78     obj=$1
80     maps=$(objdump -j maps -t $obj 2>/dev/null | \
81         command awk '/g     . maps/ {print $NF}')
83     COMPREPLY+=( $( compgen -W "$maps" -- "$cur" ) )
86 _bpftool_get_obj_map_idxs()
88     local obj
90     obj=$1
92     nmaps=$(objdump -j maps -t $obj 2>/dev/null | grep -c 'g     . maps')
94     COMPREPLY+=( $( compgen -W "$(seq 0 $((nmaps - 1)))" -- "$cur" ) )
97 _sysfs_get_netdevs()
99     COMPREPLY+=( $( compgen -W "$( ls /sys/class/net 2>/dev/null )" -- \
100         "$cur" ) )
103 # Retrieve type of the map that we are operating on.
104 _bpftool_map_guess_map_type()
106     local keyword ref
107     for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
108         case "${words[$((idx-2))]}" in
109             lookup|update)
110                 keyword=${words[$((idx-1))]}
111                 ref=${words[$((idx))]}
112                 ;;
113             push)
114                 printf "stack"
115                 return 0
116                 ;;
117             enqueue)
118                 printf "queue"
119                 return 0
120                 ;;
121         esac
122     done
123     [[ -z $ref ]] && return 0
125     local type
126     type=$(bpftool -jp map show $keyword $ref | \
127         command sed -n 's/.*"type": "\(.*\)",$/\1/p')
128     [[ -n $type ]] && printf $type
131 _bpftool_map_update_get_id()
133     local command="$1"
135     # Is it the map to update, or a map to insert into the map to update?
136     # Search for "value" keyword.
137     local idx value
138     for (( idx=7; idx < ${#words[@]}-1; idx++ )); do
139         if [[ ${words[idx]} == "value" ]]; then
140             value=1
141             break
142         fi
143     done
144     if [[ $value -eq 0 ]]; then
145         case "$command" in
146             push)
147                 _bpftool_get_map_ids_for_type stack
148                 ;;
149             enqueue)
150                 _bpftool_get_map_ids_for_type queue
151                 ;;
152             *)
153                 _bpftool_get_map_ids
154                 ;;
155         esac
156         return 0
157     fi
159     # Id to complete is for a value. It can be either prog id or map id. This
160     # depends on the type of the map to update.
161     local type=$(_bpftool_map_guess_map_type)
162     case $type in
163         array_of_maps|hash_of_maps)
164             _bpftool_get_map_ids
165             return 0
166             ;;
167         prog_array)
168             _bpftool_get_prog_ids
169             return 0
170             ;;
171         *)
172             return 0
173             ;;
174     esac
177 _bpftool()
179     local cur prev words objword
180     _init_completion || return
182     # Deal with options
183     if [[ ${words[cword]} == -* ]]; then
184         local c='--version --json --pretty --bpffs --mapcompat'
185         COMPREPLY=( $( compgen -W "$c" -- "$cur" ) )
186         return 0
187     fi
189     # Deal with simplest keywords
190     case $prev in
191         help|hex|opcodes|visual|linum)
192             return 0
193             ;;
194         tag)
195             _bpftool_get_prog_tags
196             return 0
197             ;;
198         file|pinned)
199             _filedir
200             return 0
201             ;;
202         batch)
203             COMPREPLY=( $( compgen -W 'file' -- "$cur" ) )
204             return 0
205             ;;
206     esac
208     # Remove all options so completions don't have to deal with them.
209     local i
210     for (( i=1; i < ${#words[@]}; )); do
211         if [[ ${words[i]::1} == - ]]; then
212             words=( "${words[@]:0:i}" "${words[@]:i+1}" )
213             [[ $i -le $cword ]] && cword=$(( cword - 1 ))
214         else
215             i=$(( ++i ))
216         fi
217     done
218     cur=${words[cword]}
219     prev=${words[cword - 1]}
221     local object=${words[1]} command=${words[2]}
223     if [[ -z $object || $cword -eq 1 ]]; then
224         case $cur in
225             *)
226                 COMPREPLY=( $( compgen -W "$( bpftool help 2>&1 | \
227                     command sed \
228                     -e '/OBJECT := /!d' \
229                     -e 's/.*{//' \
230                     -e 's/}.*//' \
231                     -e 's/|//g' )" -- "$cur" ) )
232                 COMPREPLY+=( $( compgen -W 'batch help' -- "$cur" ) )
233                 return 0
234                 ;;
235         esac
236     fi
238     [[ $command == help ]] && return 0
240     # Completion depends on object and command in use
241     case $object in
242         prog)
243             # Complete id, only for subcommands that use prog (but no map) ids
244             case $command in
245                 show|list|dump|pin)
246                     case $prev in
247                         id)
248                             _bpftool_get_prog_ids
249                             return 0
250                             ;;
251                     esac
252                     ;;
253             esac
255             local PROG_TYPE='id pinned tag'
256             local MAP_TYPE='id pinned'
257             case $command in
258                 show|list)
259                     [[ $prev != "$command" ]] && return 0
260                     COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
261                     return 0
262                     ;;
263                 dump)
264                     case $prev in
265                         $command)
266                             COMPREPLY+=( $( compgen -W "xlated jited" -- \
267                                 "$cur" ) )
268                             return 0
269                             ;;
270                         xlated|jited)
271                             COMPREPLY=( $( compgen -W "$PROG_TYPE" -- \
272                                 "$cur" ) )
273                             return 0
274                             ;;
275                     *)
276                         _bpftool_once_attr 'file'
277                         if _bpftool_search_list 'xlated'; then
278                             COMPREPLY+=( $( compgen -W 'opcodes visual linum' -- \
279                                 "$cur" ) )
280                         else
281                             COMPREPLY+=( $( compgen -W 'opcodes linum' -- \
282                                 "$cur" ) )
283                         fi
284                         return 0
285                         ;;
286                     esac
287                     ;;
288                 pin)
289                     if [[ $prev == "$command" ]]; then
290                         COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
291                     else
292                         _filedir
293                     fi
294                     return 0
295                     ;;
296                 attach|detach)
297                     case $cword in
298                         3)
299                             COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
300                             return 0
301                             ;;
302                         4)
303                             case $prev in
304                                 id)
305                                     _bpftool_get_prog_ids
306                                     ;;
307                                 pinned)
308                                     _filedir
309                                     ;;
310                             esac
311                             return 0
312                             ;;
313                         5)
314                             COMPREPLY=( $( compgen -W 'msg_verdict stream_verdict \
315                                 stream_parser flow_dissector' -- "$cur" ) )
316                             return 0
317                             ;;
318                         6)
319                             COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
320                             return 0
321                             ;;
322                         7)
323                             case $prev in
324                                 id)
325                                     _bpftool_get_map_ids
326                                     ;;
327                                 pinned)
328                                     _filedir
329                                     ;;
330                             esac
331                             return 0
332                             ;;
333                     esac
334                     ;;
335                 load|loadall)
336                     local obj
338                     if [[ ${#words[@]} -lt 6 ]]; then
339                         _filedir
340                         return 0
341                     fi
343                     obj=${words[3]}
345                     if [[ ${words[-4]} == "map" ]]; then
346                         COMPREPLY=( $( compgen -W "id pinned" -- "$cur" ) )
347                         return 0
348                     fi
349                     if [[ ${words[-3]} == "map" ]]; then
350                         if [[ ${words[-2]} == "idx" ]]; then
351                             _bpftool_get_obj_map_idxs $obj
352                         elif [[ ${words[-2]} == "name" ]]; then
353                             _bpftool_get_obj_map_names $obj
354                         fi
355                         return 0
356                     fi
357                     if [[ ${words[-2]} == "map" ]]; then
358                         COMPREPLY=( $( compgen -W "idx name" -- "$cur" ) )
359                         return 0
360                     fi
362                     case $prev in
363                         type)
364                             COMPREPLY=( $( compgen -W "socket kprobe \
365                                 kretprobe classifier flow_dissector \
366                                 action tracepoint raw_tracepoint \
367                                 xdp perf_event cgroup/skb cgroup/sock \
368                                 cgroup/dev lwt_in lwt_out lwt_xmit \
369                                 lwt_seg6local sockops sk_skb sk_msg \
370                                 lirc_mode2 cgroup/bind4 cgroup/bind6 \
371                                 cgroup/connect4 cgroup/connect6 \
372                                 cgroup/sendmsg4 cgroup/sendmsg6 \
373                                 cgroup/post_bind4 cgroup/post_bind6" -- \
374                                                    "$cur" ) )
375                             return 0
376                             ;;
377                         id)
378                             _bpftool_get_map_ids
379                             return 0
380                             ;;
381                         pinned|pinmaps)
382                             _filedir
383                             return 0
384                             ;;
385                         dev)
386                             _sysfs_get_netdevs
387                             return 0
388                             ;;
389                         *)
390                             COMPREPLY=( $( compgen -W "map" -- "$cur" ) )
391                             _bpftool_once_attr 'type'
392                             _bpftool_once_attr 'dev'
393                             _bpftool_once_attr 'pinmaps'
394                             return 0
395                             ;;
396                     esac
397                     ;;
398                 tracelog)
399                     return 0
400                     ;;
401                 *)
402                     [[ $prev == $object ]] && \
403                         COMPREPLY=( $( compgen -W 'dump help pin attach detach load \
404                             show list tracelog' -- "$cur" ) )
405                     ;;
406             esac
407             ;;
408         map)
409             local MAP_TYPE='id pinned'
410             case $command in
411                 show|list|dump|peek|pop|dequeue)
412                     case $prev in
413                         $command)
414                             COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
415                             return 0
416                             ;;
417                         id)
418                             case "$command" in
419                                 peek)
420                                     _bpftool_get_map_ids_for_type stack
421                                     _bpftool_get_map_ids_for_type queue
422                                     ;;
423                                 pop)
424                                     _bpftool_get_map_ids_for_type stack
425                                     ;;
426                                 dequeue)
427                                     _bpftool_get_map_ids_for_type queue
428                                     ;;
429                                 *)
430                                     _bpftool_get_map_ids
431                                     ;;
432                             esac
433                             return 0
434                             ;;
435                         *)
436                             return 0
437                             ;;
438                     esac
439                     ;;
440                 create)
441                     case $prev in
442                         $command)
443                             _filedir
444                             return 0
445                             ;;
446                         type)
447                             COMPREPLY=( $( compgen -W 'hash array prog_array \
448                                 perf_event_array percpu_hash percpu_array \
449                                 stack_trace cgroup_array lru_hash \
450                                 lru_percpu_hash lpm_trie array_of_maps \
451                                 hash_of_maps devmap sockmap cpumap xskmap \
452                                 sockhash cgroup_storage reuseport_sockarray \
453                                 percpu_cgroup_storage queue stack' -- \
454                                                    "$cur" ) )
455                             return 0
456                             ;;
457                         key|value|flags|name|entries)
458                             return 0
459                             ;;
460                         dev)
461                             _sysfs_get_netdevs
462                             return 0
463                             ;;
464                         *)
465                             _bpftool_once_attr 'type'
466                             _bpftool_once_attr 'key'
467                             _bpftool_once_attr 'value'
468                             _bpftool_once_attr 'entries'
469                             _bpftool_once_attr 'name'
470                             _bpftool_once_attr 'flags'
471                             _bpftool_once_attr 'dev'
472                             return 0
473                             ;;
474                     esac
475                     ;;
476                 lookup|getnext|delete)
477                     case $prev in
478                         $command)
479                             COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
480                             return 0
481                             ;;
482                         id)
483                             _bpftool_get_map_ids
484                             return 0
485                             ;;
486                         key)
487                             COMPREPLY+=( $( compgen -W 'hex' -- "$cur" ) )
488                             ;;
489                         *)
490                             case $(_bpftool_map_guess_map_type) in
491                                 queue|stack)
492                                     return 0
493                                     ;;
494                             esac
496                             _bpftool_once_attr 'key'
497                             return 0
498                             ;;
499                     esac
500                     ;;
501                 update|push|enqueue)
502                     case $prev in
503                         $command)
504                             COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
505                             return 0
506                             ;;
507                         id)
508                             _bpftool_map_update_get_id $command
509                             return 0
510                             ;;
511                         key)
512                             COMPREPLY+=( $( compgen -W 'hex' -- "$cur" ) )
513                             ;;
514                         value)
515                             # We can have bytes, or references to a prog or a
516                             # map, depending on the type of the map to update.
517                             case "$(_bpftool_map_guess_map_type)" in
518                                 array_of_maps|hash_of_maps)
519                                     local MAP_TYPE='id pinned'
520                                     COMPREPLY+=( $( compgen -W "$MAP_TYPE" \
521                                         -- "$cur" ) )
522                                     return 0
523                                     ;;
524                                 prog_array)
525                                     local PROG_TYPE='id pinned tag'
526                                     COMPREPLY+=( $( compgen -W "$PROG_TYPE" \
527                                         -- "$cur" ) )
528                                     return 0
529                                     ;;
530                                 *)
531                                     COMPREPLY+=( $( compgen -W 'hex' \
532                                         -- "$cur" ) )
533                                     return 0
534                                     ;;
535                             esac
536                             return 0
537                             ;;
538                         *)
539                             case $(_bpftool_map_guess_map_type) in
540                                 queue|stack)
541                                     _bpftool_once_attr 'value'
542                                     return 0;
543                                     ;;
544                             esac
546                             _bpftool_once_attr 'key'
547                             local UPDATE_FLAGS='any exist noexist'
548                             for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
549                                 if [[ ${words[idx]} == 'value' ]]; then
550                                     # 'value' is present, but is not the last
551                                     # word i.e. we can now have UPDATE_FLAGS.
552                                     _bpftool_one_of_list "$UPDATE_FLAGS"
553                                     return 0
554                                 fi
555                             done
556                             for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
557                                 if [[ ${words[idx]} == 'key' ]]; then
558                                     # 'key' is present, but is not the last
559                                     # word i.e. we can now have 'value'.
560                                     _bpftool_once_attr 'value'
561                                     return 0
562                                 fi
563                             done
565                             return 0
566                             ;;
567                     esac
568                     ;;
569                 pin)
570                     if [[ $prev == "$command" ]]; then
571                         COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
572                     else
573                         _filedir
574                     fi
575                     return 0
576                     ;;
577                 event_pipe)
578                     case $prev in
579                         $command)
580                             COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
581                             return 0
582                             ;;
583                         id)
584                             _bpftool_get_map_ids_for_type perf_event_array
585                             return 0
586                             ;;
587                         cpu)
588                             return 0
589                             ;;
590                         index)
591                             return 0
592                             ;;
593                         *)
594                             _bpftool_once_attr 'cpu'
595                             _bpftool_once_attr 'index'
596                             return 0
597                             ;;
598                     esac
599                     ;;
600                 *)
601                     [[ $prev == $object ]] && \
602                         COMPREPLY=( $( compgen -W 'delete dump getnext help \
603                             lookup pin event_pipe show list update create \
604                             peek push enqueue pop dequeue' -- \
605                             "$cur" ) )
606                     ;;
607             esac
608             ;;
609         cgroup)
610             case $command in
611                 show|list)
612                     _filedir
613                     return 0
614                     ;;
615                 tree)
616                     _filedir
617                     return 0
618                     ;;
619                 attach|detach)
620                     local ATTACH_TYPES='ingress egress sock_create sock_ops \
621                         device bind4 bind6 post_bind4 post_bind6 connect4 \
622                         connect6 sendmsg4 sendmsg6'
623                     local ATTACH_FLAGS='multi override'
624                     local PROG_TYPE='id pinned tag'
625                     case $prev in
626                         $command)
627                             _filedir
628                             return 0
629                             ;;
630                         ingress|egress|sock_create|sock_ops|device|bind4|bind6|\
631                         post_bind4|post_bind6|connect4|connect6|sendmsg4|\
632                         sendmsg6)
633                             COMPREPLY=( $( compgen -W "$PROG_TYPE" -- \
634                                 "$cur" ) )
635                             return 0
636                             ;;
637                         id)
638                             _bpftool_get_prog_ids
639                             return 0
640                             ;;
641                         *)
642                             if ! _bpftool_search_list "$ATTACH_TYPES"; then
643                                 COMPREPLY=( $( compgen -W "$ATTACH_TYPES" -- \
644                                     "$cur" ) )
645                             elif [[ "$command" == "attach" ]]; then
646                                 # We have an attach type on the command line,
647                                 # but it is not the previous word, or
648                                 # "id|pinned|tag" (we already checked for
649                                 # that). This should only leave the case when
650                                 # we need attach flags for "attach" commamnd.
651                                 _bpftool_one_of_list "$ATTACH_FLAGS"
652                             fi
653                             return 0
654                             ;;
655                     esac
656                     ;;
657                 *)
658                     [[ $prev == $object ]] && \
659                         COMPREPLY=( $( compgen -W 'help attach detach \
660                             show list tree' -- "$cur" ) )
661                     ;;
662             esac
663             ;;
664         perf)
665             case $command in
666                 *)
667                     [[ $prev == $object ]] && \
668                         COMPREPLY=( $( compgen -W 'help \
669                             show list' -- "$cur" ) )
670                     ;;
671             esac
672             ;;
673         net)
674             case $command in
675                 *)
676                     [[ $prev == $object ]] && \
677                         COMPREPLY=( $( compgen -W 'help \
678                             show list' -- "$cur" ) )
679                     ;;
680             esac
681             ;;
682         feature)
683             case $command in
684                 probe)
685                     [[ $prev == "dev" ]] && _sysfs_get_netdevs && return 0
686                     [[ $prev == "prefix" ]] && return 0
687                     if _bpftool_search_list 'macros'; then
688                         COMPREPLY+=( $( compgen -W 'prefix' -- "$cur" ) )
689                     else
690                         COMPREPLY+=( $( compgen -W 'macros' -- "$cur" ) )
691                     fi
692                     _bpftool_one_of_list 'kernel dev'
693                     return 0
694                     ;;
695                 *)
696                     [[ $prev == $object ]] && \
697                         COMPREPLY=( $( compgen -W 'help probe' -- "$cur" ) )
698                     ;;
699             esac
700             ;;
701     esac
702 } &&
703 complete -F _bpftool bpftool
705 # ex: ts=4 sw=4 et filetype=sh