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