1# bash completion for devlink(8) -*- shell-script -*- 2 3# Get all the optional commands for devlink 4_devlink_get_optional_commands() 5{ 6 local object=$1; shift 7 8 local filter_options="" 9 local options="$(devlink $object help 2>&1 \ 10 | command sed -n -e "s/^.*devlink $object //p" \ 11 | cut -d " " -f 1)" 12 13 # Remove duplicate options from "devlink $OBJECT help" command 14 local opt 15 for opt in $options; do 16 if [[ $filter_options =~ $opt ]]; then 17 continue 18 else 19 filter_options="$filter_options $opt" 20 fi 21 done 22 23 echo $filter_options 24} 25 26# Complete based on given word, for when an argument or an option name has 27# but a few possible arguments. 28_devlink_direct_complete() 29{ 30 local dev port region value 31 32 case $1 in 33 dev) 34 value=$(devlink dev show 2>/dev/null) 35 ;; 36 param_name) 37 dev=${words[4]} 38 value=$(devlink -j dev param show 2>/dev/null \ 39 | jq ".param[\"$dev\"][].name") 40 ;; 41 port) 42 value=$(devlink -j port show 2>/dev/null \ 43 | jq '.port as $ports | $ports | keys[] as $key 44 | ($ports[$key].netdev // $key)') 45 ;; 46 region) 47 value=$(devlink -j region show 2>/dev/null \ 48 | jq '.regions' | jq 'keys[]') 49 ;; 50 snapshot) 51 region=${words[3]} 52 value=$(devlink -j region show 2>/dev/null \ 53 | jq ".regions[\"$region\"].snapshot[]") 54 ;; 55 trap) 56 dev=${words[3]} 57 value=$(devlink -j trap show 2>/dev/null \ 58 | jq ".trap[\"$dev\"][].name") 59 ;; 60 trap_group) 61 dev=${words[4]} 62 value=$(devlink -j trap group show 2>/dev/null \ 63 | jq ".trap_group[\"$dev\"][].name") 64 ;; 65 trap_policer) 66 dev=${words[4]} 67 value=$(devlink -j trap policer show 2>/dev/null \ 68 | jq ".trap_policer[\"$dev\"][].policer") 69 ;; 70 health_dev) 71 value=$(devlink -j health show 2>/dev/null | jq '.health' \ 72 | jq 'keys[]') 73 ;; 74 reporter) 75 dev=${words[cword - 2]} 76 value=$(devlink -j health show 2>/dev/null \ 77 | jq ".health[\"$dev\"][].reporter") 78 ;; 79 pool) 80 dev=$pprev 81 value=$(devlink -j sb pool show 2>/dev/null \ 82 | jq ".pool[\"$dev\"][].pool") 83 ;; 84 port_pool) 85 port=${words[5]} 86 value=$(devlink -j sb port pool show 2>/dev/null \ 87 | jq ".port_pool[\"$port\"][].pool") 88 ;; 89 tc) 90 port=$pprev 91 value=$(devlink -j sb tc bind show 2>/dev/null \ 92 | jq ".tc_bind[\"$port\"][].tc") 93 ;; 94 esac 95 96 COMPREPLY+=( $( compgen -W "$value" -- "$cur" ) ) 97 # Remove colon containing prefix from COMPREPLY items in order to avoid 98 # wordbreaks with colon. 99 __ltrim_colon_completions "$cur" 100} 101 102# Completion for devlink dev eswitch set 103_devlink_dev_eswitch_set() 104{ 105 local -A settings=( 106 [mode]=notseen 107 [inline-mode]=notseen 108 [encap-mode]=notseen 109 ) 110 111 if [[ $cword -eq 5 ]]; then 112 COMPREPLY=( $( compgen -W "mode inline-mode encap-mode" -- "$cur" ) ) 113 fi 114 115 # Mark seen settings 116 local word 117 for word in "${words[@]:5:${#words[@]}-1}"; do 118 if [[ -n $word ]]; then 119 if [[ "${settings[$word]}" ]]; then 120 settings[$word]=seen 121 fi 122 fi 123 done 124 125 case $prev in 126 mode) 127 COMPREPLY=( $( compgen -W "legacy switchdev" -- "$cur" ) ) 128 return 129 ;; 130 inline-mode) 131 COMPREPLY=( $( compgen -W "none link network transport" -- \ 132 "$cur" ) ) 133 return 134 ;; 135 encap-mode) 136 COMPREPLY=( $( compgen -W "none basic" -- "$cur" ) ) 137 return 138 ;; 139 esac 140 141 local -a comp_words=() 142 143 # Add settings not seen to completions 144 local setting 145 for setting in "${!settings[@]}"; do 146 if [ "${settings[$setting]}" = notseen ]; then 147 comp_words+=( "$setting" ) 148 fi 149 done 150 151 COMPREPLY=( $( compgen -W "${comp_words[*]}" -- "$cur" ) ) 152} 153 154# Completion for devlink dev eswitch 155_devlink_dev_eswitch() 156{ 157 case "$cword" in 158 3) 159 COMPREPLY=( $( compgen -W "show set" -- "$cur" ) ) 160 return 161 ;; 162 4) 163 _devlink_direct_complete "dev" 164 return 165 ;; 166 esac 167 168 case "${words[3]}" in 169 set) 170 _devlink_dev_eswitch_set 171 return 172 ;; 173 show) 174 return 175 ;; 176 esac 177} 178 179# Completion for devlink dev param set 180_devlink_dev_param_set() 181{ 182 case $cword in 183 7) 184 COMPREPLY=( $( compgen -W "value" -- "$cur" ) ) 185 return 186 ;; 187 8) 188 # String argument 189 return 190 ;; 191 9) 192 COMPREPLY=( $( compgen -W "cmode" -- "$cur" ) ) 193 return 194 ;; 195 10) 196 COMPREPLY=( $( compgen -W "runtime driverinit permanent" -- \ 197 "$cur" ) ) 198 return 199 ;; 200 esac 201} 202 203# Completion for devlink dev param 204_devlink_dev_param() 205{ 206 case "$cword" in 207 3) 208 COMPREPLY=( $( compgen -W "show set" -- "$cur" ) ) 209 return 210 ;; 211 4) 212 _devlink_direct_complete "dev" 213 return 214 ;; 215 5) 216 COMPREPLY=( $( compgen -W "name" -- "$cur" ) ) 217 return 218 ;; 219 6) 220 _devlink_direct_complete "param_name" 221 return 222 ;; 223 esac 224 225 if [[ "${words[3]}" == "set" ]]; then 226 _devlink_dev_param_set 227 fi 228} 229 230# Completion for devlink dev reload 231_devlink_dev_reload() 232{ 233 case "$cword" in 234 4) 235 COMPREPLY=( $( compgen -W "netns" -- "$cur" ) ) 236 return 237 ;; 238 5) 239 local nslist=$( ip netns list 2>/dev/null ) 240 COMPREPLY=( $( compgen -W "$nslist" -- "$cur" ) ) 241 return 242 ;; 243 esac 244} 245 246# Completion for devlink dev flash 247_devlink_dev_flash() 248{ 249 case "$cword" in 250 4) 251 COMPREPLY=( $( compgen -W "file" -- "$cur" ) ) 252 return 253 ;; 254 5) 255 _filedir 256 return 257 ;; 258 6) 259 COMPREPLY=( $( compgen -W "component" -- "$cur" ) ) 260 return 261 ;; 262 esac 263} 264 265# Completion for devlink dev 266_devlink_dev() 267{ 268 case $command in 269 show|reload|info|flash) 270 if [[ $cword -le 3 ]]; then 271 _devlink_direct_complete "dev" 272 elif [[ $command == "reload" || $command == "flash" ]];then 273 _devlink_dev_$command 274 fi 275 return 276 ;; 277 eswitch|param) 278 _devlink_dev_$command 279 return 280 ;; 281 esac 282} 283 284# Completion for devlink port set 285_devlink_port_set() 286{ 287 case "$cword" in 288 3) 289 _devlink_direct_complete "port" 290 return 291 ;; 292 4) 293 COMPREPLY=( $( compgen -W "type" -- "$cur" ) ) 294 return 295 ;; 296 5) 297 COMPREPLY=( $( compgen -W "eth ib auto" -- "$cur" ) ) 298 return 299 ;; 300 esac 301} 302 303# Completion for devlink port split 304_devlink_port_split() 305{ 306 case "$cword" in 307 3) 308 _devlink_direct_complete "port" 309 return 310 ;; 311 4) 312 COMPREPLY=( $( compgen -W "count" -- "$cur" ) ) 313 return 314 ;; 315 5) 316 # Integer argument 317 return 318 ;; 319 esac 320} 321 322# Completion for devlink port param set 323_devlink_port_param_set() 324{ 325 case $cword in 326 7) 327 COMPREPLY=( $( compgen -W "value" -- "$cur" ) ) 328 return 329 ;; 330 8) 331 # String argument 332 return 333 ;; 334 9) 335 COMPREPLY=( $( compgen -W "cmode" -- "$cur" ) ) 336 return 337 ;; 338 10) 339 COMPREPLY=( $( compgen -W "runtime driverinit permanent" -- \ 340 "$cur" ) ) 341 return 342 ;; 343 esac 344} 345 346# Completion for devlink port param 347_devlink_port_param() 348{ 349 case "$cword" in 350 3) 351 COMPREPLY=( $( compgen -W "show set" -- "$cur" ) ) 352 return 353 ;; 354 4) 355 _devlink_direct_complete "port" 356 return 357 ;; 358 5) 359 COMPREPLY=( $( compgen -W "name" -- "$cur" ) ) 360 return 361 ;; 362 6) 363 _devlink_direct_complete "param_name" 364 return 365 ;; 366 esac 367 368 if [[ "${words[3]}" == "set" ]]; then 369 _devlink_port_param_set 370 fi 371} 372 373# Completion for devlink port 374_devlink_port() 375{ 376 case $command in 377 set) 378 _devlink_port_set 379 return 380 ;; 381 split) 382 _devlink_port_split 383 return 384 ;; 385 param) 386 _devlink_port_param 387 return 388 ;; 389 show|unsplit) 390 if [[ $cword -eq 3 ]]; then 391 _devlink_direct_complete "port" 392 fi 393 return 394 ;; 395 esac 396} 397 398# Completion for devlink dpipe 399_devlink_dpipe() 400{ 401 local options="$(devlink dpipe help 2>&1 \ 402 | command sed -e '/OBJECT-LIST := /!d' \ 403 -e 's/.*{ //' -e 's/}.*//' -e 's/|//g' )" 404 405 if [[ $cword -eq 2 ]]; then 406 COMPREPLY+=( $( compgen -W "$options" -- "$cur" ) ) 407 fi 408} 409 410# Completion for devlink monitor 411_devlink_monitor() 412{ 413 local options="$(devlink monitor help 2>&1 \ 414 | command sed -e '/OBJECT-LIST := /!d' \ 415 -e 's/.*{ //' -e 's/}.*//' -e 's/|//g' )" 416 417 if [[ $cword -eq 2 ]]; then 418 COMPREPLY+=( $( compgen -W "all $options" -- "$cur" ) ) 419 fi 420} 421 422# Completion for the rest of devlink sb $command 423_devlink_sb_command_options() 424{ 425 local subcmd 426 427 case $command in 428 pool) 429 subcmd=${words[3]} 430 if [[ $cword -eq 5 ]]; then 431 COMPREPLY=( $( compgen -W "pool" -- "$cur" ) ) 432 fi 433 if [[ $subcmd == "set" ]]; then 434 case $cword in 435 7) 436 COMPREPLY+=( $( compgen -W "size" -- "$cur" ) ) 437 ;; 438 9) 439 COMPREPLY+=( $( compgen -W "thtype" -- "$cur" ) ) 440 ;; 441 esac 442 fi 443 ;; 444 port) 445 subcmd=${words[4]} 446 if [[ $cword -eq 6 ]]; then 447 COMPREPLY+=( $( compgen -W "pool" -- "$cur" ) ) 448 fi 449 if [[ $subcmd == "set" ]]; then 450 case $cword in 451 8) 452 COMPREPLY+=( $( compgen -W "th" -- "$cur" ) ) 453 ;; 454 esac 455 fi 456 ;; 457 tc) 458 subcmd=${words[4]} 459 case $cword in 460 6) 461 COMPREPLY+=( $( compgen -W "tc" -- "$cur" ) ) 462 ;; 463 8) 464 COMPREPLY+=( $( compgen -W "type" -- "$cur" ) ) 465 ;; 466 esac 467 if [[ $subcmd == "set" ]]; then 468 case $cword in 469 10) 470 COMPREPLY+=( $( compgen -W "pool" -- "$cur" ) ) 471 ;; 472 12) 473 COMPREPLY+=( $( compgen -W "th" -- "$cur" ) ) 474 ;; 475 esac 476 fi 477 ;; 478 esac 479} 480 481# Completion for devlink sb 482_devlink_sb() 483{ 484 case $prev in 485 bind) 486 COMPREPLY=( $( compgen -W "set show" -- "$cur" ) ) 487 ;; 488 occupancy) 489 COMPREPLY=( $( compgen -W "show snapshot clearmax" -- "$cur" ) ) 490 ;; 491 pool) 492 if [[ $cword -eq 3 || $cword -eq 4 ]]; then 493 COMPREPLY=( $( compgen -W "set show" -- "$cur" ) ) 494 elif [[ $command == "port" || $command == "tc" ]]; then 495 _devlink_direct_complete "port_pool" 496 else 497 _devlink_direct_complete "pool" 498 fi 499 ;; 500 port) 501 if [[ $cword -eq 3 ]]; then 502 COMPREPLY=( $( compgen -W "pool" -- "$cur" ) ) 503 fi 504 ;; 505 show|set|snapshot|clearmax) 506 case $command in 507 show|pool|occupancy) 508 _devlink_direct_complete "dev" 509 if [[ $command == "occupancy" && $prev == "show" ]];then 510 _devlink_direct_complete "port" 511 fi 512 ;; 513 port|tc) 514 _devlink_direct_complete "port" 515 ;; 516 esac 517 ;; 518 size) 519 # Integer argument 520 ;; 521 thtype) 522 COMPREPLY=( $( compgen -W "static dynamic" -- "$cur" ) ) 523 ;; 524 th) 525 # Integer argument 526 ;; 527 tc) 528 if [[ $cword -eq 3 ]]; then 529 COMPREPLY=( $( compgen -W "bind" -- "$cur" ) ) 530 else 531 _devlink_direct_complete "tc" 532 fi 533 ;; 534 type) 535 COMPREPLY=( $( compgen -W "ingress egress" -- "$cur" ) ) 536 ;; 537 esac 538 539 _devlink_sb_command_options 540 return 541} 542 543# Completion for devlink resource set path argument 544_devlink_resource_path() 545{ 546 local path parents parent all_path 547 local dev=${words[3]} 548 local -a path 549 550 local all_path=$( 551 devlink resource show $dev \ 552 | sed -E '# Of resource lines, keep only the name itself. 553 s/name ([^ ]*) .*/\1/ 554 # Drop headers. 555 /:$/d 556 # First layer is not aligned enough, align it. 557 s/^/ / 558 # Use slashes as unary code for resource depth. 559 s, ,/,g 560 # Separate tally count from resource name. 561 s,/*,&\t,' \ 562 | while read d name; do 563 while ((${#path[@]} > ${#d})); do 564 unset path[$((${#path[@]} - 1))] 565 done 566 path[$((${#d} - 1))]=$name 567 echo ${path[@]} 568 done \ 569 | sed '# Convert paths to slash-separated 570 s,^,/,;s, ,/,g;s,$,/,' 571 ) 572 COMPREPLY=( ${COMPREPLY[@]:-} $( compgen -W "$all_path" -- "$cur" ) ) 573} 574 575# Completion for devlink resource set 576_devlink_resource_set() 577{ 578 case "$cword" in 579 3) 580 _devlink_direct_complete "dev" 581 return 582 ;; 583 4) 584 COMPREPLY=( $( compgen -W "path" -- "$cur" ) ) 585 return 586 ;; 587 5) 588 _devlink_resource_path 589 return 590 ;; 591 6) 592 COMPREPLY=( $( compgen -W "size" -- "$cur" ) ) 593 return 594 ;; 595 7) 596 # Integer argument 597 return 598 ;; 599 esac 600} 601 602# Completion for devlink resource 603_devlink_resource() 604{ 605 case $command in 606 show) 607 if [[ $cword -eq 3 ]]; then 608 _devlink_direct_complete "dev" 609 fi 610 return 611 ;; 612 set) 613 _devlink_resource_set 614 return 615 ;; 616 esac 617} 618 619# Completion for devlink region read 620_devlink_region_read() 621{ 622 case "$cword" in 623 6) 624 COMPREPLY=( $( compgen -W "address" -- "$cur" ) ) 625 return 626 ;; 627 7) 628 # Address argument, for example: 0x10 629 return 630 ;; 631 8) 632 COMPREPLY=( $( compgen -W "length" -- "$cur" ) ) 633 return 634 ;; 635 9) 636 # Integer argument 637 return 638 ;; 639 esac 640} 641 642# Completion for devlink region 643_devlink_region() 644{ 645 if [[ $cword -eq 3 && $command != "help" ]]; then 646 _devlink_direct_complete "region" 647 fi 648 649 case $command in 650 show) 651 return 652 ;; 653 del|dump|read) 654 case "$cword" in 655 4) 656 COMPREPLY=( $( compgen -W "snapshot" -- "$cur" ) ) 657 ;; 658 5) 659 _devlink_direct_complete "snapshot" 660 ;; 661 esac 662 663 if [[ $command == "read" ]]; then 664 _devlink_region_read 665 fi 666 return 667 ;; 668 esac 669} 670 671# Completion reporter for devlink health 672_devlink_health_reporter() 673{ 674 local i=$1; shift 675 676 case $cword in 677 $((3 + $i))) 678 _devlink_direct_complete "health_dev" 679 ;; 680 $((4 + $i))) 681 COMPREPLY=( $( compgen -W "reporter" -- "$cur" ) ) 682 ;; 683 $((5 + $i))) 684 _devlink_direct_complete "reporter" 685 ;; 686 esac 687} 688 689# Completion for devlink health 690_devlink_health() 691{ 692 case $command in 693 show|recover|diagnose|set|test) 694 _devlink_health_reporter 0 695 if [[ $command == "set" ]]; then 696 case $cword in 697 6) 698 COMPREPLY=( $( compgen -W "grace_period auto_recover" \ 699 -- "$cur" ) ) 700 ;; 701 7) 702 case $prev in 703 grace_period) 704 # Integer argument- msec 705 ;; 706 auto_recover) 707 COMPREPLY=( $( compgen -W "true false" -- \ 708 "$cur" ) ) 709 ;; 710 esac 711 esac 712 fi 713 return 714 ;; 715 dump) 716 if [[ $cword -eq 3 ]]; then 717 COMPREPLY=( $( compgen -W "show clear" -- "$cur" ) ) 718 fi 719 720 _devlink_health_reporter 1 721 return 722 ;; 723 esac 724} 725 726# Completion for action in devlink trap set 727_devlink_trap_set_action() 728{ 729 local i=$1; shift 730 731 case $cword in 732 $((6 + $i))) 733 COMPREPLY=( $( compgen -W "action" -- "$cur" ) ) 734 ;; 735 $((7 + $i))) 736 COMPREPLY=( $( compgen -W "trap drop mirror" -- "$cur" ) ) 737 ;; 738 esac 739} 740 741# Completion for devlink trap group set 742_devlink_trap_group_set() 743{ 744 local -A settings=( 745 [action]=notseen 746 [policer]=notseen 747 [nopolicer]=notseen 748 ) 749 750 if [[ $cword -eq 7 ]]; then 751 COMPREPLY=( $( compgen -W "action policer nopolicer" -- "$cur" ) ) 752 fi 753 754 # Mark seen settings 755 local word 756 for word in "${words[@]:7:${#words[@]}-1}"; do 757 if [[ -n $word ]]; then 758 if [[ "${settings[$word]}" ]]; then 759 settings[$word]=seen 760 fi 761 fi 762 done 763 764 case $prev in 765 action) 766 COMPREPLY=( $( compgen -W "trap drop mirror" -- "$cur" ) ) 767 return 768 ;; 769 policer) 770 _devlink_direct_complete "trap_policer" 771 return 772 ;; 773 esac 774 775 local -a comp_words=() 776 777 # Add settings not seen to completions 778 local setting 779 for setting in "${!settings[@]}"; do 780 if [ "${settings[$setting]}" = notseen ]; then 781 comp_words+=( "$setting" ) 782 fi 783 done 784 785 COMPREPLY=( $( compgen -W "${comp_words[*]}" -- "$cur" ) ) 786} 787 788# Completion for devlink trap group 789_devlink_trap_group() 790{ 791 case $cword in 792 3) 793 COMPREPLY=( $( compgen -W "set show" -- "$cur" ) ) 794 return 795 ;; 796 4) 797 _devlink_direct_complete "dev" 798 return 799 ;; 800 5) 801 COMPREPLY=( $( compgen -W "group" -- "$cur" ) ) 802 return 803 ;; 804 6) 805 _devlink_direct_complete "trap_group" 806 return 807 ;; 808 esac 809 810 if [[ ${words[3]} == "set" ]]; then 811 _devlink_trap_group_set 812 fi 813} 814 815# Completion for devlink trap policer set 816_devlink_trap_policer_set() 817{ 818 local -A settings=( 819 [rate]=notseen 820 [burst]=notseen 821 ) 822 823 if [[ $cword -eq 7 ]]; then 824 COMPREPLY=( $( compgen -W "rate burst" -- "$cur" ) ) 825 fi 826 827 # Mark seen settings 828 local word 829 for word in "${words[@]:7:${#words[@]}-1}"; do 830 if [[ -n $word ]]; then 831 if [[ "${settings[$word]}" ]]; then 832 settings[$word]=seen 833 fi 834 fi 835 done 836 837 case $prev in 838 rate) 839 # Integer argument 840 return 841 ;; 842 burst) 843 # Integer argument 844 return 845 ;; 846 esac 847 848 local -a comp_words=() 849 850 # Add settings not seen to completions 851 local setting 852 for setting in "${!settings[@]}"; do 853 if [ "${settings[$setting]}" = notseen ]; then 854 comp_words+=( "$setting" ) 855 fi 856 done 857 858 COMPREPLY=( $( compgen -W "${comp_words[*]}" -- "$cur" ) ) 859} 860 861# Completion for devlink trap policer 862_devlink_trap_policer() 863{ 864 case $cword in 865 3) 866 COMPREPLY=( $( compgen -W "set show" -- "$cur" ) ) 867 return 868 ;; 869 4) 870 _devlink_direct_complete "dev" 871 return 872 ;; 873 5) 874 COMPREPLY=( $( compgen -W "policer" -- "$cur" ) ) 875 return 876 ;; 877 6) 878 _devlink_direct_complete "trap_policer" 879 return 880 ;; 881 esac 882 883 if [[ ${words[3]} == "set" ]]; then 884 _devlink_trap_policer_set 885 fi 886} 887 888# Completion for devlink trap 889_devlink_trap() 890{ 891 case $command in 892 show|set) 893 case $cword in 894 3) 895 _devlink_direct_complete "dev" 896 ;; 897 4) 898 COMPREPLY=( $( compgen -W "trap" -- "$cur" ) ) 899 ;; 900 5) 901 _devlink_direct_complete "trap" 902 ;; 903 esac 904 905 if [[ $command == "set" ]]; then 906 _devlink_trap_set_action 0 907 fi 908 return 909 ;; 910 group) 911 _devlink_trap_$command 912 return 913 ;; 914 policer) 915 _devlink_trap_$command 916 return 917 ;; 918 esac 919} 920 921# Complete any devlink command 922_devlink() 923{ 924 local cur prev words cword 925 local opt='--Version --no-nice-names --json --pretty --verbose \ 926 --statistics --force --Netns --batch' 927 local objects="$(devlink help 2>&1 | command sed -e '/OBJECT := /!d' \ 928 -e 's/.*{//' -e 's/}.*//' -e \ 's/|//g' )" 929 930 _init_completion || return 931 # Gets the word-to-complete without considering the colon as word breaks 932 _get_comp_words_by_ref -n : cur prev words cword 933 934 if [[ $cword -eq 1 ]]; then 935 case $cur in 936 -*) 937 COMPREPLY=( $( compgen -W "$opt" -- "$cur" ) ) 938 return 0 939 ;; 940 *) 941 COMPREPLY=( $( compgen -W "$objects" -- "$cur" ) ) 942 return 0 943 ;; 944 esac 945 fi 946 947 # Deal with options 948 if [[ $prev == -* ]]; then 949 case $prev in 950 -V|--Version) 951 return 0 952 ;; 953 -b|--batch) 954 _filedir 955 return 0 956 ;; 957 --force) 958 COMPREPLY=( $( compgen -W "--batch" -- "$cur" ) ) 959 return 0 960 ;; 961 -N|--Netns) 962 local nslist=$( ip netns list 2>/dev/null ) 963 COMPREPLY=( $( compgen -W "$nslist" -- "$cur" ) ) 964 return 0 965 ;; 966 -j|--json) 967 COMPREPLY=( $( compgen -W "--pretty $objects" -- "$cur" ) ) 968 return 0 969 ;; 970 *) 971 COMPREPLY=( $( compgen -W "$objects" -- "$cur" ) ) 972 return 0 973 ;; 974 esac 975 fi 976 977 # Remove all options so completions don't have to deal with them. 978 local i 979 for (( i=1; i < ${#words[@]}; )); do 980 if [[ ${words[i]::1} == - ]]; then 981 words=( "${words[@]:0:i}" "${words[@]:i+1}" ) 982 [[ $i -le $cword ]] && cword=$(( cword - 1 )) 983 else 984 i=$(( ++i )) 985 fi 986 done 987 988 local object=${words[1]} 989 local command=${words[2]} 990 local pprev=${words[cword - 2]} 991 992 if [[ $objects =~ $object ]]; then 993 if [[ $cword -eq 2 ]]; then 994 COMPREPLY=( $( compgen -W "help" -- "$cur") ) 995 if [[ $object != "monitor" && $object != "dpipe" ]]; then 996 COMPREPLY+=( $( compgen -W \ 997 "$(_devlink_get_optional_commands $object)" -- "$cur" ) ) 998 fi 999 fi 1000 "_devlink_$object"
1001 fi 1002 1003} && 1004complete -F _devlink devlink 1005 1006# ex: ts=4 sw=4 et filetype=sh 1007