cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

bpftool (45318B)


      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='msg_verdict \
    411                                skb_verdict stream_verdict 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='hash array \
    707                                prog_array perf_event_array percpu_hash \
    708                                percpu_array stack_trace cgroup_array lru_hash \
    709                                lru_percpu_hash lpm_trie array_of_maps \
    710                                hash_of_maps devmap devmap_hash sockmap cpumap \
    711                                xskmap sockhash cgroup_storage reuseport_sockarray \
    712                                percpu_cgroup_storage queue stack sk_storage \
    713                                struct_ops ringbuf inode_storage task_storage \
    714                                bloom_filter'
    715                            COMPREPLY=( $( compgen -W "$BPFTOOL_MAP_CREATE_TYPES" -- "$cur" ) )
    716                            return 0
    717                            ;;
    718                        key|value|flags|entries)
    719                            return 0
    720                            ;;
    721                        inner_map)
    722                            COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
    723                            return 0
    724                            ;;
    725                        id)
    726                            _bpftool_get_map_ids
    727                            ;;
    728                        name)
    729                            case $pprev in
    730                                inner_map)
    731                                    _bpftool_get_map_names
    732                                    ;;
    733                                *)
    734                                    return 0
    735                                    ;;
    736                            esac
    737                            ;;
    738                        *)
    739                            _bpftool_once_attr 'type'
    740                            _bpftool_once_attr 'key'
    741                            _bpftool_once_attr 'value'
    742                            _bpftool_once_attr 'entries'
    743                            _bpftool_once_attr 'name'
    744                            _bpftool_once_attr 'flags'
    745                            if _bpftool_search_list 'array_of_maps' 'hash_of_maps'; then
    746                                _bpftool_once_attr 'inner_map'
    747                            fi
    748                            _bpftool_once_attr 'dev'
    749                            return 0
    750                            ;;
    751                    esac
    752                    ;;
    753                lookup|getnext|delete)
    754                    case $prev in
    755                        $command)
    756                            COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
    757                            return 0
    758                            ;;
    759                        id)
    760                            _bpftool_get_map_ids
    761                            return 0
    762                            ;;
    763                        name)
    764                            _bpftool_get_map_names
    765                            return 0
    766                            ;;
    767                        key)
    768                            COMPREPLY+=( $( compgen -W 'hex' -- "$cur" ) )
    769                            ;;
    770                        *)
    771                            case $(_bpftool_map_guess_map_type) in
    772                                queue|stack)
    773                                    return 0
    774                                    ;;
    775                            esac
    776
    777                            _bpftool_once_attr 'key'
    778                            return 0
    779                            ;;
    780                    esac
    781                    ;;
    782                update|push|enqueue)
    783                    case $prev in
    784                        $command)
    785                            COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
    786                            return 0
    787                            ;;
    788                        id)
    789                            _bpftool_map_update_get_id $command
    790                            return 0
    791                            ;;
    792                        name)
    793                            _bpftool_map_update_get_name $command
    794                            return 0
    795                            ;;
    796                        key)
    797                            COMPREPLY+=( $( compgen -W 'hex' -- "$cur" ) )
    798                            ;;
    799                        value)
    800                            # We can have bytes, or references to a prog or a
    801                            # map, depending on the type of the map to update.
    802                            case "$(_bpftool_map_guess_map_type)" in
    803                                array_of_maps|hash_of_maps)
    804                                    local MAP_TYPE='id pinned name'
    805                                    COMPREPLY+=( $( compgen -W "$MAP_TYPE" \
    806                                        -- "$cur" ) )
    807                                    return 0
    808                                    ;;
    809                                prog_array)
    810                                    local PROG_TYPE='id pinned tag name'
    811                                    COMPREPLY+=( $( compgen -W "$PROG_TYPE" \
    812                                        -- "$cur" ) )
    813                                    return 0
    814                                    ;;
    815                                *)
    816                                    COMPREPLY+=( $( compgen -W 'hex' \
    817                                        -- "$cur" ) )
    818                                    return 0
    819                                    ;;
    820                            esac
    821                            return 0
    822                            ;;
    823                        *)
    824                            case $(_bpftool_map_guess_map_type) in
    825                                queue|stack)
    826                                    _bpftool_once_attr 'value'
    827                                    return 0;
    828                                    ;;
    829                            esac
    830
    831                            _bpftool_once_attr 'key'
    832                            local UPDATE_FLAGS='any exist noexist'
    833                            for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
    834                                if [[ ${words[idx]} == 'value' ]]; then
    835                                    # 'value' is present, but is not the last
    836                                    # word i.e. we can now have UPDATE_FLAGS.
    837                                    _bpftool_one_of_list "$UPDATE_FLAGS"
    838                                    return 0
    839                                fi
    840                            done
    841                            for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
    842                                if [[ ${words[idx]} == 'key' ]]; then
    843                                    # 'key' is present, but is not the last
    844                                    # word i.e. we can now have 'value'.
    845                                    _bpftool_once_attr 'value'
    846                                    return 0
    847                                fi
    848                            done
    849
    850                            return 0
    851                            ;;
    852                    esac
    853                    ;;
    854                pin)
    855                    case $prev in
    856                        $command)
    857                            COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
    858                            ;;
    859                        id)
    860                            _bpftool_get_map_ids
    861                            ;;
    862                        name)
    863                            _bpftool_get_map_names
    864                            ;;
    865                    esac
    866                    return 0
    867                    ;;
    868                event_pipe)
    869                    case $prev in
    870                        $command)
    871                            COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
    872                            return 0
    873                            ;;
    874                        id)
    875                            _bpftool_get_map_ids_for_type perf_event_array
    876                            return 0
    877                            ;;
    878                        name)
    879                            _bpftool_get_map_names_for_type perf_event_array
    880                            return 0
    881                            ;;
    882                        cpu)
    883                            return 0
    884                            ;;
    885                        index)
    886                            return 0
    887                            ;;
    888                        *)
    889                            _bpftool_once_attr 'cpu'
    890                            _bpftool_once_attr 'index'
    891                            return 0
    892                            ;;
    893                    esac
    894                    ;;
    895                *)
    896                    [[ $prev == $object ]] && \
    897                        COMPREPLY=( $( compgen -W 'delete dump getnext help \
    898                            lookup pin event_pipe show list update create \
    899                            peek push enqueue pop dequeue freeze' -- \
    900                            "$cur" ) )
    901                    ;;
    902            esac
    903            ;;
    904        btf)
    905            local PROG_TYPE='id pinned tag name'
    906            local MAP_TYPE='id pinned name'
    907            case $command in
    908                dump)
    909                    case $prev in
    910                        $command)
    911                            COMPREPLY+=( $( compgen -W "id map prog file" -- \
    912                                "$cur" ) )
    913                            return 0
    914                            ;;
    915                        prog)
    916                            COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
    917                            return 0
    918                            ;;
    919                        map)
    920                            COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
    921                            return 0
    922                            ;;
    923                        id)
    924                            case $pprev in
    925                                prog)
    926                                    _bpftool_get_prog_ids
    927                                    ;;
    928                                map)
    929                                    _bpftool_get_map_ids
    930                                    ;;
    931                                $command)
    932                                    _bpftool_get_btf_ids
    933                                    ;;
    934                            esac
    935                            return 0
    936                            ;;
    937                        name)
    938                            case $pprev in
    939                                prog)
    940                                    _bpftool_get_prog_names
    941                                    ;;
    942                                map)
    943                                    _bpftool_get_map_names
    944                                    ;;
    945                            esac
    946                            return 0
    947                            ;;
    948                        format)
    949                            COMPREPLY=( $( compgen -W "c raw" -- "$cur" ) )
    950                            ;;
    951                        *)
    952                            # emit extra options
    953                            case ${words[3]} in
    954                                id|file)
    955                                    _bpftool_once_attr 'format'
    956                                    ;;
    957                                map|prog)
    958                                    if [[ ${words[3]} == "map" ]] && [[ $cword == 6 ]]; then
    959                                        COMPREPLY+=( $( compgen -W "key value kv all" -- "$cur" ) )
    960                                    fi
    961                                    _bpftool_once_attr 'format'
    962                                    ;;
    963                                *)
    964                                    ;;
    965                            esac
    966                            return 0
    967                            ;;
    968                    esac
    969                    ;;
    970                show|list)
    971                    case $prev in
    972                        $command)
    973                            COMPREPLY+=( $( compgen -W "id" -- "$cur" ) )
    974                            ;;
    975                        id)
    976                            _bpftool_get_btf_ids
    977                            ;;
    978                    esac
    979                    return 0
    980                    ;;
    981                *)
    982                    [[ $prev == $object ]] && \
    983                        COMPREPLY=( $( compgen -W 'dump help show list' \
    984                            -- "$cur" ) )
    985                    ;;
    986            esac
    987            ;;
    988        gen)
    989            case $command in
    990                object)
    991                    _filedir
    992                    return 0
    993                    ;;
    994                skeleton)
    995                    case $prev in
    996                        $command)
    997                            _filedir
    998                            return 0
    999                            ;;
   1000                        *)
   1001                            _bpftool_once_attr 'name'
   1002                            return 0
   1003                            ;;
   1004                    esac
   1005                    ;;
   1006                subskeleton)
   1007                    case $prev in
   1008                        $command)
   1009                            _filedir
   1010                            return 0
   1011                            ;;
   1012                        *)
   1013                            _bpftool_once_attr 'name'
   1014                            return 0
   1015                            ;;
   1016                    esac
   1017                    ;;
   1018                min_core_btf)
   1019                    _filedir
   1020                    return 0
   1021                    ;;
   1022                *)
   1023                    [[ $prev == $object ]] && \
   1024                        COMPREPLY=( $( compgen -W 'object skeleton subskeleton help min_core_btf' -- "$cur" ) )
   1025                    ;;
   1026            esac
   1027            ;;
   1028        cgroup)
   1029            case $command in
   1030                show|list|tree)
   1031                    case $cword in
   1032                        3)
   1033                            _filedir
   1034                            ;;
   1035                        4)
   1036                            COMPREPLY=( $( compgen -W 'effective' -- "$cur" ) )
   1037                            ;;
   1038                    esac
   1039                    return 0
   1040                    ;;
   1041                attach|detach)
   1042                    local BPFTOOL_CGROUP_ATTACH_TYPES='ingress egress \
   1043                        sock_create sock_ops device \
   1044                        bind4 bind6 post_bind4 post_bind6 connect4 connect6 \
   1045                        getpeername4 getpeername6 getsockname4 getsockname6 \
   1046                        sendmsg4 sendmsg6 recvmsg4 recvmsg6 sysctl getsockopt \
   1047                        setsockopt sock_release'
   1048                    local ATTACH_FLAGS='multi override'
   1049                    local PROG_TYPE='id pinned tag name'
   1050                    # Check for $prev = $command first
   1051                    if [ $prev = $command ]; then
   1052                        _filedir
   1053                        return 0
   1054                    # Then check for attach type. This is done outside of the
   1055                    # "case $prev in" to avoid writing the whole list of attach
   1056                    # types again as pattern to match (where we cannot reuse
   1057                    # our variable).
   1058                    elif [[ $BPFTOOL_CGROUP_ATTACH_TYPES =~ $prev ]]; then
   1059                            COMPREPLY=( $( compgen -W "$PROG_TYPE" -- \
   1060                                "$cur" ) )
   1061                            return 0
   1062                    fi
   1063                    # case/esac for the other cases
   1064                    case $prev in
   1065                        id)
   1066                            _bpftool_get_prog_ids
   1067                            return 0
   1068                            ;;
   1069                        *)
   1070                            if ! _bpftool_search_list "$BPFTOOL_CGROUP_ATTACH_TYPES"; then
   1071                                COMPREPLY=( $( compgen -W \
   1072                                    "$BPFTOOL_CGROUP_ATTACH_TYPES" -- "$cur" ) )
   1073                            elif [[ "$command" == "attach" ]]; then
   1074                                # We have an attach type on the command line,
   1075                                # but it is not the previous word, or
   1076                                # "id|pinned|tag|name" (we already checked for
   1077                                # that). This should only leave the case when
   1078                                # we need attach flags for "attach" commamnd.
   1079                                _bpftool_one_of_list "$ATTACH_FLAGS"
   1080                            fi
   1081                            return 0
   1082                            ;;
   1083                    esac
   1084                    ;;
   1085                *)
   1086                    [[ $prev == $object ]] && \
   1087                        COMPREPLY=( $( compgen -W 'help attach detach \
   1088                            show list tree' -- "$cur" ) )
   1089                    ;;
   1090            esac
   1091            ;;
   1092        perf)
   1093            case $command in
   1094                *)
   1095                    [[ $prev == $object ]] && \
   1096                        COMPREPLY=( $( compgen -W 'help \
   1097                            show list' -- "$cur" ) )
   1098                    ;;
   1099            esac
   1100            ;;
   1101        net)
   1102            local PROG_TYPE='id pinned tag name'
   1103            local ATTACH_TYPES='xdp xdpgeneric xdpdrv xdpoffload'
   1104            case $command in
   1105                show|list)
   1106                    [[ $prev != "$command" ]] && return 0
   1107                    COMPREPLY=( $( compgen -W 'dev' -- "$cur" ) )
   1108                    return 0
   1109                    ;;
   1110                attach)
   1111                    case $cword in
   1112                        3)
   1113                            COMPREPLY=( $( compgen -W "$ATTACH_TYPES" -- "$cur" ) )
   1114                            return 0
   1115                            ;;
   1116                        4)
   1117                            COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
   1118                            return 0
   1119                            ;;
   1120                        5)
   1121                            case $prev in
   1122                                id)
   1123                                    _bpftool_get_prog_ids
   1124                                    ;;
   1125                                name)
   1126                                    _bpftool_get_prog_names
   1127                                    ;;
   1128                                pinned)
   1129                                    _filedir
   1130                                    ;;
   1131                            esac
   1132                            return 0
   1133                            ;;
   1134                        6)
   1135                            COMPREPLY=( $( compgen -W 'dev' -- "$cur" ) )
   1136                            return 0
   1137                            ;;
   1138                        8)
   1139                            _bpftool_once_attr 'overwrite'
   1140                            return 0
   1141                            ;;
   1142                    esac
   1143                    ;;
   1144                detach)
   1145                    case $cword in
   1146                        3)
   1147                            COMPREPLY=( $( compgen -W "$ATTACH_TYPES" -- "$cur" ) )
   1148                            return 0
   1149                            ;;
   1150                        4)
   1151                            COMPREPLY=( $( compgen -W 'dev' -- "$cur" ) )
   1152                            return 0
   1153                            ;;
   1154                    esac
   1155                    ;;
   1156                *)
   1157                    [[ $prev == $object ]] && \
   1158                        COMPREPLY=( $( compgen -W 'help \
   1159                            show list attach detach' -- "$cur" ) )
   1160                    ;;
   1161            esac
   1162            ;;
   1163        feature)
   1164            case $command in
   1165                probe)
   1166                    [[ $prev == "prefix" ]] && return 0
   1167                    if _bpftool_search_list 'macros'; then
   1168                        _bpftool_once_attr 'prefix'
   1169                    else
   1170                        COMPREPLY+=( $( compgen -W 'macros' -- "$cur" ) )
   1171                    fi
   1172                    _bpftool_one_of_list 'kernel dev'
   1173                    _bpftool_once_attr 'full unprivileged'
   1174                    return 0
   1175                    ;;
   1176                *)
   1177                    [[ $prev == $object ]] && \
   1178                        COMPREPLY=( $( compgen -W 'help probe' -- "$cur" ) )
   1179                    ;;
   1180            esac
   1181            ;;
   1182        link)
   1183            case $command in
   1184                show|list|pin|detach)
   1185                    case $prev in
   1186                        id)
   1187                            _bpftool_get_link_ids
   1188                            return 0
   1189                            ;;
   1190                    esac
   1191                    ;;
   1192            esac
   1193
   1194            local LINK_TYPE='id pinned'
   1195            case $command in
   1196                show|list)
   1197                    [[ $prev != "$command" ]] && return 0
   1198                    COMPREPLY=( $( compgen -W "$LINK_TYPE" -- "$cur" ) )
   1199                    return 0
   1200                    ;;
   1201                pin|detach)
   1202                    if [[ $prev == "$command" ]]; then
   1203                        COMPREPLY=( $( compgen -W "$LINK_TYPE" -- "$cur" ) )
   1204                    else
   1205                        _filedir
   1206                    fi
   1207                    return 0
   1208                    ;;
   1209                *)
   1210                    [[ $prev == $object ]] && \
   1211                        COMPREPLY=( $( compgen -W 'help pin show list' -- "$cur" ) )
   1212                    ;;
   1213            esac
   1214            ;;
   1215    esac
   1216} &&
   1217complete -F _bpftool bpftool
   1218
   1219# ex: ts=4 sw=4 et filetype=sh