1 # bash completion for devlink(8) -*- shell-script -*-
3 # Get all the optional commands for devlink
4 _devlink_get_optional_commands()
8 local filter_options=""
9 local options="$(devlink $object help 2>&1 \
10 | command sed -n -e "s/^.*devlink $object //p" \
13 # Remove duplicate options from "devlink $OBJECT help" command
15 for opt in $options; do
16 if [[ $filter_options =~ $opt ]]; then
19 filter_options="$filter_options $opt"
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()
30 local dev port region value
34 value=$(devlink dev show 2>/dev/null)
38 value=$(devlink -j dev param show 2>/dev/null \
39 | jq ".param[\"$dev\"][].name")
42 value=$(devlink -j port show 2>/dev/null \
43 | jq '.port as $ports | $ports | keys[] as $key
44 | ($ports[$key].netdev // $key)')
47 value=$(devlink -j region show 2>/dev/null \
48 | jq '.regions' | jq 'keys[]')
52 value=$(devlink -j region show 2>/dev/null \
53 | jq ".regions[\"$region\"].snapshot[]")
57 value=$(devlink -j trap show 2>/dev/null \
58 | jq ".trap[\"$dev\"][].name")
62 value=$(devlink -j trap group show 2>/dev/null \
63 | jq ".trap_group[\"$dev\"][].name")
67 value=$(devlink -j trap policer show 2>/dev/null \
68 | jq ".trap_policer[\"$dev\"][].policer")
71 value=$(devlink -j health show 2>/dev/null | jq '.health' \
75 dev=${words[cword - 2]}
76 value=$(devlink -j health show 2>/dev/null \
77 | jq ".health[\"$dev\"][].reporter")
81 value=$(devlink -j sb pool show 2>/dev/null \
82 | jq ".pool[\"$dev\"][].pool")
86 value=$(devlink -j sb port pool show 2>/dev/null \
87 | jq ".port_pool[\"$port\"][].pool")
91 value=$(devlink -j sb tc bind show 2>/dev/null \
92 | jq ".tc_bind[\"$port\"][].tc")
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"
102 # Completion for devlink dev eswitch set
103 _devlink_dev_eswitch_set()
107 [inline-mode]=notseen
111 if [[ $cword -eq 5 ]]; then
112 COMPREPLY=( $( compgen -W "mode inline-mode encap-mode" -- "$cur" ) )
117 for word in "${words[@]:5:${#words[@]}-1}"; do
118 if [[ -n $word ]]; then
119 if [[ "${settings[$word]}" ]]; then
127 COMPREPLY=( $( compgen -W "legacy switchdev" -- "$cur" ) )
131 COMPREPLY=( $( compgen -W "none link network transport" -- \
136 COMPREPLY=( $( compgen -W "none basic" -- "$cur" ) )
141 local -a comp_words=()
143 # Add settings not seen to completions
145 for setting in "${!settings[@]}"; do
146 if [ "${settings[$setting]}" = notseen ]; then
147 comp_words+=( "$setting" )
151 COMPREPLY=( $( compgen -W "${comp_words[*]}" -- "$cur" ) )
154 # Completion for devlink dev eswitch
155 _devlink_dev_eswitch()
159 COMPREPLY=( $( compgen -W "show set" -- "$cur" ) )
163 _devlink_direct_complete "dev"
168 case "${words[3]}" in
170 _devlink_dev_eswitch_set
179 # Completion for devlink dev param set
180 _devlink_dev_param_set()
184 COMPREPLY=( $( compgen -W "value" -- "$cur" ) )
192 COMPREPLY=( $( compgen -W "cmode" -- "$cur" ) )
196 COMPREPLY=( $( compgen -W "runtime driverinit permanent" -- \
203 # Completion for devlink dev param
208 COMPREPLY=( $( compgen -W "show set" -- "$cur" ) )
212 _devlink_direct_complete "dev"
216 COMPREPLY=( $( compgen -W "name" -- "$cur" ) )
220 _devlink_direct_complete "param_name"
225 if [[ "${words[3]}" == "set" ]]; then
226 _devlink_dev_param_set
230 # Completion for devlink dev reload
231 _devlink_dev_reload()
235 COMPREPLY=( $( compgen -W "netns" -- "$cur" ) )
239 local nslist=$( ip netns list 2>/dev/null )
240 COMPREPLY=( $( compgen -W "$nslist" -- "$cur" ) )
246 # Completion for devlink dev flash
251 COMPREPLY=( $( compgen -W "file" -- "$cur" ) )
259 COMPREPLY=( $( compgen -W "component" -- "$cur" ) )
265 # Completion for devlink dev
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
278 _devlink_dev_$command
284 # Completion for devlink port set
289 _devlink_direct_complete "port"
293 COMPREPLY=( $( compgen -W "type" -- "$cur" ) )
297 COMPREPLY=( $( compgen -W "eth ib auto" -- "$cur" ) )
303 # Completion for devlink port split
304 _devlink_port_split()
308 _devlink_direct_complete "port"
312 COMPREPLY=( $( compgen -W "count" -- "$cur" ) )
322 # Completion for devlink port
335 if [[ $cword -eq 3 ]]; then
336 _devlink_direct_complete "port"
343 # Completion for devlink dpipe
346 local options="$(devlink dpipe help 2>&1 \
347 | command sed -e '/OBJECT-LIST := /!d' \
348 -e 's/.*{ //' -e 's/}.*//' -e 's/|//g' )"
350 if [[ $cword -eq 2 ]]; then
351 COMPREPLY+=( $( compgen -W "$options" -- "$cur" ) )
355 # Completion for devlink monitor
358 local options="$(devlink monitor help 2>&1 \
359 | command sed -e '/OBJECT-LIST := /!d' \
360 -e 's/.*{ //' -e 's/}.*//' -e 's/|//g' )"
362 if [[ $cword -eq 2 ]]; then
363 COMPREPLY+=( $( compgen -W "all $options" -- "$cur" ) )
367 # Completion for the rest of devlink sb $command
368 _devlink_sb_command_options()
375 if [[ $cword -eq 5 ]]; then
376 COMPREPLY=( $( compgen -W "pool" -- "$cur" ) )
378 if [[ $subcmd == "set" ]]; then
381 COMPREPLY+=( $( compgen -W "size" -- "$cur" ) )
384 COMPREPLY+=( $( compgen -W "thtype" -- "$cur" ) )
391 if [[ $cword -eq 6 ]]; then
392 COMPREPLY+=( $( compgen -W "pool" -- "$cur" ) )
394 if [[ $subcmd == "set" ]]; then
397 COMPREPLY+=( $( compgen -W "th" -- "$cur" ) )
406 COMPREPLY+=( $( compgen -W "tc" -- "$cur" ) )
409 COMPREPLY+=( $( compgen -W "type" -- "$cur" ) )
412 if [[ $subcmd == "set" ]]; then
415 COMPREPLY+=( $( compgen -W "pool" -- "$cur" ) )
418 COMPREPLY+=( $( compgen -W "th" -- "$cur" ) )
426 # Completion for devlink sb
431 COMPREPLY=( $( compgen -W "set show" -- "$cur" ) )
434 COMPREPLY=( $( compgen -W "show snapshot clearmax" -- "$cur" ) )
437 if [[ $cword -eq 3 || $cword -eq 4 ]]; then
438 COMPREPLY=( $( compgen -W "set show" -- "$cur" ) )
439 elif [[ $command == "port" || $command == "tc" ]]; then
440 _devlink_direct_complete "port_pool"
442 _devlink_direct_complete "pool"
446 if [[ $cword -eq 3 ]]; then
447 COMPREPLY=( $( compgen -W "pool" -- "$cur" ) )
450 show|set|snapshot|clearmax)
453 _devlink_direct_complete "dev"
454 if [[ $command == "occupancy" && $prev == "show" ]];then
455 _devlink_direct_complete "port"
459 _devlink_direct_complete "port"
467 COMPREPLY=( $( compgen -W "static dynamic" -- "$cur" ) )
473 if [[ $cword -eq 3 ]]; then
474 COMPREPLY=( $( compgen -W "bind" -- "$cur" ) )
476 _devlink_direct_complete "tc"
480 COMPREPLY=( $( compgen -W "ingress egress" -- "$cur" ) )
484 _devlink_sb_command_options
488 # Completion for devlink resource set path argument
489 _devlink_resource_path()
491 local path parents parent all_path
492 local dev=${words[3]}
496 devlink resource show $dev \
497 | sed -E '# Of resource lines, keep only the name itself.
498 s/name ([^ ]*) .*/\1/
501 # First layer is not aligned enough, align it.
503 # Use slashes as unary code for resource depth.
505 # Separate tally count from resource name.
507 | while read d name; do
508 while ((${#path[@]} > ${#d})); do
509 unset path[$((${#path[@]} - 1))]
511 path[$((${#d} - 1))]=$name
514 | sed '# Convert paths to slash-separated
515 s,^,/,;s, ,/,g;s,$,/,'
517 COMPREPLY=( ${COMPREPLY[@]:-} $( compgen -W "$all_path" -- "$cur" ) )
520 # Completion for devlink resource set
521 _devlink_resource_set()
525 _devlink_direct_complete "dev"
529 COMPREPLY=( $( compgen -W "path" -- "$cur" ) )
533 _devlink_resource_path
537 COMPREPLY=( $( compgen -W "size" -- "$cur" ) )
547 # Completion for devlink resource
552 if [[ $cword -eq 3 ]]; then
553 _devlink_direct_complete "dev"
558 _devlink_resource_set
564 # Completion for devlink region read
565 _devlink_region_read()
569 COMPREPLY=( $( compgen -W "address" -- "$cur" ) )
573 # Address argument, for example: 0x10
577 COMPREPLY=( $( compgen -W "length" -- "$cur" ) )
587 # Completion for devlink region
590 if [[ $cword -eq 3 && $command != "help" ]]; then
591 _devlink_direct_complete "region"
601 COMPREPLY=( $( compgen -W "snapshot" -- "$cur" ) )
604 _devlink_direct_complete "snapshot"
608 if [[ $command == "read" ]]; then
616 # Completion reporter for devlink health
617 _devlink_health_reporter()
623 _devlink_direct_complete "health_dev"
626 COMPREPLY=( $( compgen -W "reporter" -- "$cur" ) )
629 _devlink_direct_complete "reporter"
634 # Completion for devlink health
638 show|recover|diagnose|set)
639 _devlink_health_reporter 0
640 if [[ $command == "set" ]]; then
643 COMPREPLY=( $( compgen -W "grace_period auto_recover" \
649 # Integer argument- msec
652 COMPREPLY=( $( compgen -W "true false" -- \
661 if [[ $cword -eq 3 ]]; then
662 COMPREPLY=( $( compgen -W "show clear" -- "$cur" ) )
665 _devlink_health_reporter 1
671 # Completion for action in devlink trap set
672 _devlink_trap_set_action()
678 COMPREPLY=( $( compgen -W "action" -- "$cur" ) )
681 COMPREPLY=( $( compgen -W "trap drop" -- "$cur" ) )
686 # Completion for devlink trap group set
687 _devlink_trap_group_set()
695 if [[ $cword -eq 7 ]]; then
696 COMPREPLY=( $( compgen -W "action policer nopolicer" -- "$cur" ) )
701 for word in "${words[@]:7:${#words[@]}-1}"; do
702 if [[ -n $word ]]; then
703 if [[ "${settings[$word]}" ]]; then
711 COMPREPLY=( $( compgen -W "trap drop" -- "$cur" ) )
715 _devlink_direct_complete "trap_policer"
720 local -a comp_words=()
722 # Add settings not seen to completions
724 for setting in "${!settings[@]}"; do
725 if [ "${settings[$setting]}" = notseen ]; then
726 comp_words+=( "$setting" )
730 COMPREPLY=( $( compgen -W "${comp_words[*]}" -- "$cur" ) )
733 # Completion for devlink trap group
734 _devlink_trap_group()
738 COMPREPLY=( $( compgen -W "set show" -- "$cur" ) )
742 _devlink_direct_complete "dev"
746 COMPREPLY=( $( compgen -W "group" -- "$cur" ) )
750 _devlink_direct_complete "trap_group"
755 if [[ ${words[3]} == "set" ]]; then
756 _devlink_trap_group_set
760 # Completion for devlink trap policer set
761 _devlink_trap_policer_set()
768 if [[ $cword -eq 7 ]]; then
769 COMPREPLY=( $( compgen -W "rate burst" -- "$cur" ) )
774 for word in "${words[@]:7:${#words[@]}-1}"; do
775 if [[ -n $word ]]; then
776 if [[ "${settings[$word]}" ]]; then
793 local -a comp_words=()
795 # Add settings not seen to completions
797 for setting in "${!settings[@]}"; do
798 if [ "${settings[$setting]}" = notseen ]; then
799 comp_words+=( "$setting" )
803 COMPREPLY=( $( compgen -W "${comp_words[*]}" -- "$cur" ) )
806 # Completion for devlink trap policer
807 _devlink_trap_policer()
811 COMPREPLY=( $( compgen -W "set show" -- "$cur" ) )
815 _devlink_direct_complete "dev"
819 COMPREPLY=( $( compgen -W "policer" -- "$cur" ) )
823 _devlink_direct_complete "trap_policer"
828 if [[ ${words[3]} == "set" ]]; then
829 _devlink_trap_policer_set
833 # Completion for devlink trap
840 _devlink_direct_complete "dev"
843 COMPREPLY=( $( compgen -W "trap" -- "$cur" ) )
846 _devlink_direct_complete "trap"
850 if [[ $command == "set" ]]; then
851 _devlink_trap_set_action 0
856 _devlink_trap_$command
860 _devlink_trap_$command
866 # Complete any devlink command
869 local cur prev words cword
870 local opt='--Version --no-nice-names --json --pretty --verbose \
871 --statistics --force --Netns --batch'
872 local objects="$(devlink help 2>&1 | command sed -e '/OBJECT := /!d' \
873 -e 's/.*{//' -e 's/}.*//' -e \ 's/|//g' )"
875 _init_completion || return
876 # Gets the word-to-complete without considering the colon as word breaks
877 _get_comp_words_by_ref -n : cur prev words cword
879 if [[ $cword -eq 1 ]]; then
882 COMPREPLY=( $( compgen -W "$opt" -- "$cur" ) )
886 COMPREPLY=( $( compgen -W "$objects" -- "$cur" ) )
893 if [[ $prev == -* ]]; then
903 COMPREPLY=( $( compgen -W "--batch" -- "$cur" ) )
907 local nslist=$( ip netns list 2>/dev/null )
908 COMPREPLY=( $( compgen -W "$nslist" -- "$cur" ) )
912 COMPREPLY=( $( compgen -W "--pretty $objects" -- "$cur" ) )
916 COMPREPLY=( $( compgen -W "$objects" -- "$cur" ) )
922 # Remove all options so completions don't have to deal with them.
924 for (( i=1; i < ${#words[@]}; )); do
925 if [[ ${words[i]::1} == - ]]; then
926 words=( "${words[@]:0:i}" "${words[@]:i+1}" )
927 [[ $i -le $cword ]] && cword=$(( cword - 1 ))
933 local object=${words[1]}
934 local command=${words[2]}
935 local pprev=${words[cword - 2]}
937 if [[ $objects =~ $object ]]; then
938 if [[ $cword -eq 2 ]]; then
939 COMPREPLY=( $( compgen -W "help" -- "$cur") )
940 if [[ $object != "monitor" && $object != "dpipe" ]]; then
941 COMPREPLY+=( $( compgen -W \
942 "$(_devlink_get_optional_commands $object)" -- "$cur" ) )
949 complete -F _devlink devlink
951 # ex: ts=4 sw=4 et filetype=sh