]> git.proxmox.com Git - mirror_iproute2.git/blob - bash-completion/devlink
bash-completion: devlink: Extend bash-completion for new commands
[mirror_iproute2.git] / bash-completion / devlink
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]=notseen
109 )
110
111 if [[ $cword -eq 5 ]]; then
112 COMPREPLY=( $( compgen -W "mode inline-mode encap" -- "$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)
136 COMPREPLY=( $( compgen -W "disable enable" -- "$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
323 _devlink_port()
324 {
325 case $command in
326 set)
327 _devlink_port_set
328 return
329 ;;
330 split)
331 _devlink_port_split
332 return
333 ;;
334 show|unsplit)
335 if [[ $cword -eq 3 ]]; then
336 _devlink_direct_complete "port"
337 fi
338 return
339 ;;
340 esac
341 }
342
343 # Completion for devlink dpipe
344 _devlink_dpipe()
345 {
346 local options="$(devlink dpipe help 2>&1 \
347 | command sed -e '/OBJECT-LIST := /!d' \
348 -e 's/.*{ //' -e 's/}.*//' -e 's/|//g' )"
349
350 if [[ $cword -eq 2 ]]; then
351 COMPREPLY+=( $( compgen -W "$options" -- "$cur" ) )
352 fi
353 }
354
355 # Completion for devlink monitor
356 _devlink_monitor()
357 {
358 local options="$(devlink monitor help 2>&1 \
359 | command sed -e '/OBJECT-LIST := /!d' \
360 -e 's/.*{ //' -e 's/}.*//' -e 's/|//g' )"
361
362 if [[ $cword -eq 2 ]]; then
363 COMPREPLY+=( $( compgen -W "all $options" -- "$cur" ) )
364 fi
365 }
366
367 # Completion for the rest of devlink sb $command
368 _devlink_sb_command_options()
369 {
370 local subcmd
371
372 case $command in
373 pool)
374 subcmd=${words[3]}
375 if [[ $cword -eq 5 ]]; then
376 COMPREPLY=( $( compgen -W "pool" -- "$cur" ) )
377 fi
378 if [[ $subcmd == "set" ]]; then
379 case $cword in
380 7)
381 COMPREPLY+=( $( compgen -W "size" -- "$cur" ) )
382 ;;
383 9)
384 COMPREPLY+=( $( compgen -W "thtype" -- "$cur" ) )
385 ;;
386 esac
387 fi
388 ;;
389 port)
390 subcmd=${words[4]}
391 if [[ $cword -eq 6 ]]; then
392 COMPREPLY+=( $( compgen -W "pool" -- "$cur" ) )
393 fi
394 if [[ $subcmd == "set" ]]; then
395 case $cword in
396 8)
397 COMPREPLY+=( $( compgen -W "th" -- "$cur" ) )
398 ;;
399 esac
400 fi
401 ;;
402 tc)
403 subcmd=${words[4]}
404 case $cword in
405 6)
406 COMPREPLY+=( $( compgen -W "tc" -- "$cur" ) )
407 ;;
408 8)
409 COMPREPLY+=( $( compgen -W "type" -- "$cur" ) )
410 ;;
411 esac
412 if [[ $subcmd == "set" ]]; then
413 case $cword in
414 10)
415 COMPREPLY+=( $( compgen -W "pool" -- "$cur" ) )
416 ;;
417 12)
418 COMPREPLY+=( $( compgen -W "th" -- "$cur" ) )
419 ;;
420 esac
421 fi
422 ;;
423 esac
424 }
425
426 # Completion for devlink sb
427 _devlink_sb()
428 {
429 case $prev in
430 bind)
431 COMPREPLY=( $( compgen -W "set show" -- "$cur" ) )
432 ;;
433 occupancy)
434 COMPREPLY=( $( compgen -W "show snapshot clearmax" -- "$cur" ) )
435 ;;
436 pool)
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"
441 else
442 _devlink_direct_complete "pool"
443 fi
444 ;;
445 port)
446 if [[ $cword -eq 3 ]]; then
447 COMPREPLY=( $( compgen -W "pool" -- "$cur" ) )
448 fi
449 ;;
450 show|set|snapshot|clearmax)
451 case $command in
452 show|pool|occupancy)
453 _devlink_direct_complete "dev"
454 if [[ $command == "occupancy" && $prev == "show" ]];then
455 _devlink_direct_complete "port"
456 fi
457 ;;
458 port|tc)
459 _devlink_direct_complete "port"
460 ;;
461 esac
462 ;;
463 size)
464 # Integer argument
465 ;;
466 thtype)
467 COMPREPLY=( $( compgen -W "static dynamic" -- "$cur" ) )
468 ;;
469 th)
470 # Integer argument
471 ;;
472 tc)
473 if [[ $cword -eq 3 ]]; then
474 COMPREPLY=( $( compgen -W "bind" -- "$cur" ) )
475 else
476 _devlink_direct_complete "tc"
477 fi
478 ;;
479 type)
480 COMPREPLY=( $( compgen -W "ingress egress" -- "$cur" ) )
481 ;;
482 esac
483
484 _devlink_sb_command_options
485 return
486 }
487
488 # Completion for devlink resource set path argument
489 _devlink_resource_path()
490 {
491 local path parents parent all_path
492 local dev=${words[3]}
493 local -a path
494
495 local all_path=$(
496 devlink resource show $dev \
497 | sed -E '# Of resource lines, keep only the name itself.
498 s/name ([^ ]*) .*/\1/
499 # Drop headers.
500 /:$/d
501 # First layer is not aligned enough, align it.
502 s/^/ /
503 # Use slashes as unary code for resource depth.
504 s, ,/,g
505 # Separate tally count from resource name.
506 s,/*,&\t,' \
507 | while read d name; do
508 while ((${#path[@]} > ${#d})); do
509 unset path[$((${#path[@]} - 1))]
510 done
511 path[$((${#d} - 1))]=$name
512 echo ${path[@]}
513 done \
514 | sed '# Convert paths to slash-separated
515 s,^,/,;s, ,/,g;s,$,/,'
516 )
517 COMPREPLY=( ${COMPREPLY[@]:-} $( compgen -W "$all_path" -- "$cur" ) )
518 }
519
520 # Completion for devlink resource set
521 _devlink_resource_set()
522 {
523 case "$cword" in
524 3)
525 _devlink_direct_complete "dev"
526 return
527 ;;
528 4)
529 COMPREPLY=( $( compgen -W "path" -- "$cur" ) )
530 return
531 ;;
532 5)
533 _devlink_resource_path
534 return
535 ;;
536 6)
537 COMPREPLY=( $( compgen -W "size" -- "$cur" ) )
538 return
539 ;;
540 7)
541 # Integer argument
542 return
543 ;;
544 esac
545 }
546
547 # Completion for devlink resource
548 _devlink_resource()
549 {
550 case $command in
551 show)
552 if [[ $cword -eq 3 ]]; then
553 _devlink_direct_complete "dev"
554 fi
555 return
556 ;;
557 set)
558 _devlink_resource_set
559 return
560 ;;
561 esac
562 }
563
564 # Completion for devlink region read
565 _devlink_region_read()
566 {
567 case "$cword" in
568 6)
569 COMPREPLY=( $( compgen -W "address" -- "$cur" ) )
570 return
571 ;;
572 7)
573 # Address argument, for example: 0x10
574 return
575 ;;
576 8)
577 COMPREPLY=( $( compgen -W "length" -- "$cur" ) )
578 return
579 ;;
580 9)
581 # Integer argument
582 return
583 ;;
584 esac
585 }
586
587 # Completion for devlink region
588 _devlink_region()
589 {
590 if [[ $cword -eq 3 && $command != "help" ]]; then
591 _devlink_direct_complete "region"
592 fi
593
594 case $command in
595 show)
596 return
597 ;;
598 del|dump|read)
599 case "$cword" in
600 4)
601 COMPREPLY=( $( compgen -W "snapshot" -- "$cur" ) )
602 ;;
603 5)
604 _devlink_direct_complete "snapshot"
605 ;;
606 esac
607
608 if [[ $command == "read" ]]; then
609 _devlink_region_read
610 fi
611 return
612 ;;
613 esac
614 }
615
616 # Completion reporter for devlink health
617 _devlink_health_reporter()
618 {
619 local i=$1; shift
620
621 case $cword in
622 $((3 + $i)))
623 _devlink_direct_complete "health_dev"
624 ;;
625 $((4 + $i)))
626 COMPREPLY=( $( compgen -W "reporter" -- "$cur" ) )
627 ;;
628 $((5 + $i)))
629 _devlink_direct_complete "reporter"
630 ;;
631 esac
632 }
633
634 # Completion for devlink health
635 _devlink_health()
636 {
637 case $command in
638 show|recover|diagnose|set)
639 _devlink_health_reporter 0
640 if [[ $command == "set" ]]; then
641 case $cword in
642 6)
643 COMPREPLY=( $( compgen -W "grace_period auto_recover" \
644 -- "$cur" ) )
645 ;;
646 7)
647 case $prev in
648 grace_period)
649 # Integer argument- msec
650 ;;
651 auto_recover)
652 COMPREPLY=( $( compgen -W "true false" -- \
653 "$cur" ) )
654 ;;
655 esac
656 esac
657 fi
658 return
659 ;;
660 dump)
661 if [[ $cword -eq 3 ]]; then
662 COMPREPLY=( $( compgen -W "show clear" -- "$cur" ) )
663 fi
664
665 _devlink_health_reporter 1
666 return
667 ;;
668 esac
669 }
670
671 # Completion for action in devlink trap set
672 _devlink_trap_set_action()
673 {
674 local i=$1; shift
675
676 case $cword in
677 $((6 + $i)))
678 COMPREPLY=( $( compgen -W "action" -- "$cur" ) )
679 ;;
680 $((7 + $i)))
681 COMPREPLY=( $( compgen -W "trap drop" -- "$cur" ) )
682 ;;
683 esac
684 }
685
686 # Completion for devlink trap group set
687 _devlink_trap_group_set()
688 {
689 local -A settings=(
690 [action]=notseen
691 [policer]=notseen
692 [nopolicer]=notseen
693 )
694
695 if [[ $cword -eq 7 ]]; then
696 COMPREPLY=( $( compgen -W "action policer nopolicer" -- "$cur" ) )
697 fi
698
699 # Mark seen settings
700 local word
701 for word in "${words[@]:7:${#words[@]}-1}"; do
702 if [[ -n $word ]]; then
703 if [[ "${settings[$word]}" ]]; then
704 settings[$word]=seen
705 fi
706 fi
707 done
708
709 case $prev in
710 action)
711 COMPREPLY=( $( compgen -W "trap drop" -- "$cur" ) )
712 return
713 ;;
714 policer)
715 _devlink_direct_complete "trap_policer"
716 return
717 ;;
718 esac
719
720 local -a comp_words=()
721
722 # Add settings not seen to completions
723 local setting
724 for setting in "${!settings[@]}"; do
725 if [ "${settings[$setting]}" = notseen ]; then
726 comp_words+=( "$setting" )
727 fi
728 done
729
730 COMPREPLY=( $( compgen -W "${comp_words[*]}" -- "$cur" ) )
731 }
732
733 # Completion for devlink trap group
734 _devlink_trap_group()
735 {
736 case $cword in
737 3)
738 COMPREPLY=( $( compgen -W "set show" -- "$cur" ) )
739 return
740 ;;
741 4)
742 _devlink_direct_complete "dev"
743 return
744 ;;
745 5)
746 COMPREPLY=( $( compgen -W "group" -- "$cur" ) )
747 return
748 ;;
749 6)
750 _devlink_direct_complete "trap_group"
751 return
752 ;;
753 esac
754
755 if [[ ${words[3]} == "set" ]]; then
756 _devlink_trap_group_set
757 fi
758 }
759
760 # Completion for devlink trap policer set
761 _devlink_trap_policer_set()
762 {
763 local -A settings=(
764 [rate]=notseen
765 [burst]=notseen
766 )
767
768 if [[ $cword -eq 7 ]]; then
769 COMPREPLY=( $( compgen -W "rate burst" -- "$cur" ) )
770 fi
771
772 # Mark seen settings
773 local word
774 for word in "${words[@]:7:${#words[@]}-1}"; do
775 if [[ -n $word ]]; then
776 if [[ "${settings[$word]}" ]]; then
777 settings[$word]=seen
778 fi
779 fi
780 done
781
782 case $prev in
783 rate)
784 # Integer argument
785 return
786 ;;
787 burst)
788 # Integer argument
789 return
790 ;;
791 esac
792
793 local -a comp_words=()
794
795 # Add settings not seen to completions
796 local setting
797 for setting in "${!settings[@]}"; do
798 if [ "${settings[$setting]}" = notseen ]; then
799 comp_words+=( "$setting" )
800 fi
801 done
802
803 COMPREPLY=( $( compgen -W "${comp_words[*]}" -- "$cur" ) )
804 }
805
806 # Completion for devlink trap policer
807 _devlink_trap_policer()
808 {
809 case $cword in
810 3)
811 COMPREPLY=( $( compgen -W "set show" -- "$cur" ) )
812 return
813 ;;
814 4)
815 _devlink_direct_complete "dev"
816 return
817 ;;
818 5)
819 COMPREPLY=( $( compgen -W "policer" -- "$cur" ) )
820 return
821 ;;
822 6)
823 _devlink_direct_complete "trap_policer"
824 return
825 ;;
826 esac
827
828 if [[ ${words[3]} == "set" ]]; then
829 _devlink_trap_policer_set
830 fi
831 }
832
833 # Completion for devlink trap
834 _devlink_trap()
835 {
836 case $command in
837 show|set)
838 case $cword in
839 3)
840 _devlink_direct_complete "dev"
841 ;;
842 4)
843 COMPREPLY=( $( compgen -W "trap" -- "$cur" ) )
844 ;;
845 5)
846 _devlink_direct_complete "trap"
847 ;;
848 esac
849
850 if [[ $command == "set" ]]; then
851 _devlink_trap_set_action 0
852 fi
853 return
854 ;;
855 group)
856 _devlink_trap_$command
857 return
858 ;;
859 policer)
860 _devlink_trap_$command
861 return
862 ;;
863 esac
864 }
865
866 # Complete any devlink command
867 _devlink()
868 {
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' )"
874
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
878
879 if [[ $cword -eq 1 ]]; then
880 case $cur in
881 -*)
882 COMPREPLY=( $( compgen -W "$opt" -- "$cur" ) )
883 return 0
884 ;;
885 *)
886 COMPREPLY=( $( compgen -W "$objects" -- "$cur" ) )
887 return 0
888 ;;
889 esac
890 fi
891
892 # Deal with options
893 if [[ $prev == -* ]]; then
894 case $prev in
895 -V|--Version)
896 return 0
897 ;;
898 -b|--batch)
899 _filedir
900 return 0
901 ;;
902 --force)
903 COMPREPLY=( $( compgen -W "--batch" -- "$cur" ) )
904 return 0
905 ;;
906 -N|--Netns)
907 local nslist=$( ip netns list 2>/dev/null )
908 COMPREPLY=( $( compgen -W "$nslist" -- "$cur" ) )
909 return 0
910 ;;
911 -j|--json)
912 COMPREPLY=( $( compgen -W "--pretty $objects" -- "$cur" ) )
913 return 0
914 ;;
915 *)
916 COMPREPLY=( $( compgen -W "$objects" -- "$cur" ) )
917 return 0
918 ;;
919 esac
920 fi
921
922 # Remove all options so completions don't have to deal with them.
923 local i
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 ))
928 else
929 i=$(( ++i ))
930 fi
931 done
932
933 local object=${words[1]}
934 local command=${words[2]}
935 local pprev=${words[cword - 2]}
936
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" ) )
943 fi
944 fi
945 "_devlink_$object"
946 fi
947
948 } &&
949 complete -F _devlink devlink
950
951 # ex: ts=4 sw=4 et filetype=sh