Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1# bpftool(8) bash completion -*- shell-script -*-
2#
3# Copyright (C) 2017-2018 Netronome Systems, Inc.
4#
5# This software is dual licensed under the GNU General License
6# Version 2, June 1991 as shown in the file COPYING in the top-level
7# directory of this source tree or the BSD 2-Clause License provided
8# below. You have the option to license this software under the
9# complete terms of either license.
10#
11# The BSD 2-Clause License:
12#
13# Redistribution and use in source and binary forms, with or
14# without modification, are permitted provided that the following
15# conditions are met:
16#
17# 1. Redistributions of source code must retain the above
18# copyright notice, this list of conditions and the following
19# disclaimer.
20#
21# 2. Redistributions in binary form must reproduce the above
22# copyright notice, this list of conditions and the following
23# disclaimer in the documentation and/or other materials
24# provided with the distribution.
25#
26# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
30# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
31# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
32# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33# SOFTWARE.
34#
35# Author: Quentin Monnet <quentin.monnet@netronome.com>
36
37# Takes a list of words in argument; each one of them is added to COMPREPLY if
38# it is not already present on the command line. Returns no value.
39_bpftool_once_attr()
40{
41 local w idx found
42 for w in $*; do
43 found=0
44 for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
45 if [[ $w == ${words[idx]} ]]; then
46 found=1
47 break
48 fi
49 done
50 [[ $found -eq 0 ]] && \
51 COMPREPLY+=( $( compgen -W "$w" -- "$cur" ) )
52 done
53}
54
55# Takes a list of words as argument; if any of those words is present on the
56# command line, return 0. Otherwise, return 1.
57_bpftool_search_list()
58{
59 local w idx
60 for w in $*; do
61 for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
62 [[ $w == ${words[idx]} ]] && return 0
63 done
64 done
65 return 1
66}
67
68# Takes a list of words in argument; adds them all to COMPREPLY if none of them
69# is already present on the command line. Returns no value.
70_bpftool_one_of_list()
71{
72 _bpftool_search_list $* && return 1
73 COMPREPLY+=( $( compgen -W "$*" -- "$cur" ) )
74}
75
76_bpftool_get_map_ids()
77{
78 COMPREPLY+=( $( compgen -W "$( bpftool -jp map 2>&1 | \
79 command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) )
80}
81
82_bpftool_get_perf_map_ids()
83{
84 COMPREPLY+=( $( compgen -W "$( bpftool -jp map 2>&1 | \
85 command grep -C2 perf_event_array | \
86 command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) )
87}
88
89
90_bpftool_get_prog_ids()
91{
92 COMPREPLY+=( $( compgen -W "$( bpftool -jp prog 2>&1 | \
93 command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) )
94}
95
96_bpftool_get_prog_tags()
97{
98 COMPREPLY+=( $( compgen -W "$( bpftool -jp prog 2>&1 | \
99 command sed -n 's/.*"tag": "\(.*\)",$/\1/p' )" -- "$cur" ) )
100}
101
102# For bpftool map update: retrieve type of the map to update.
103_bpftool_map_update_map_type()
104{
105 local keyword ref
106 for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
107 if [[ ${words[$((idx-2))]} == "update" ]]; then
108 keyword=${words[$((idx-1))]}
109 ref=${words[$((idx))]}
110 fi
111 done
112 [[ -z $ref ]] && return 0
113
114 local type
115 type=$(bpftool -jp map show $keyword $ref | \
116 command sed -n 's/.*"type": "\(.*\)",$/\1/p')
117 printf $type
118}
119
120_bpftool_map_update_get_id()
121{
122 # Is it the map to update, or a map to insert into the map to update?
123 # Search for "value" keyword.
124 local idx value
125 for (( idx=7; idx < ${#words[@]}-1; idx++ )); do
126 if [[ ${words[idx]} == "value" ]]; then
127 value=1
128 break
129 fi
130 done
131 [[ $value -eq 0 ]] && _bpftool_get_map_ids && return 0
132
133 # Id to complete is for a value. It can be either prog id or map id. This
134 # depends on the type of the map to update.
135 local type=$(_bpftool_map_update_map_type)
136 case $type in
137 array_of_maps|hash_of_maps)
138 _bpftool_get_map_ids
139 return 0
140 ;;
141 prog_array)
142 _bpftool_get_prog_ids
143 return 0
144 ;;
145 *)
146 return 0
147 ;;
148 esac
149}
150
151_bpftool()
152{
153 local cur prev words objword
154 _init_completion || return
155
156 # Deal with simplest keywords
157 case $prev in
158 help|hex|opcodes|visual)
159 return 0
160 ;;
161 tag)
162 _bpftool_get_prog_tags
163 return 0
164 ;;
165 file|pinned)
166 _filedir
167 return 0
168 ;;
169 batch)
170 COMPREPLY=( $( compgen -W 'file' -- "$cur" ) )
171 return 0
172 ;;
173 esac
174
175 # Search for object and command
176 local object command cmdword
177 for (( cmdword=1; cmdword < ${#words[@]}-1; cmdword++ )); do
178 [[ -n $object ]] && command=${words[cmdword]} && break
179 [[ ${words[cmdword]} != -* ]] && object=${words[cmdword]}
180 done
181
182 if [[ -z $object ]]; then
183 case $cur in
184 -*)
185 local c='--version --json --pretty'
186 COMPREPLY=( $( compgen -W "$c" -- "$cur" ) )
187 return 0
188 ;;
189 *)
190 COMPREPLY=( $( compgen -W "$( bpftool help 2>&1 | \
191 command sed \
192 -e '/OBJECT := /!d' \
193 -e 's/.*{//' \
194 -e 's/}.*//' \
195 -e 's/|//g' )" -- "$cur" ) )
196 COMPREPLY+=( $( compgen -W 'batch help' -- "$cur" ) )
197 return 0
198 ;;
199 esac
200 fi
201
202 [[ $command == help ]] && return 0
203
204 # Completion depends on object and command in use
205 case $object in
206 prog)
207 case $prev in
208 id)
209 _bpftool_get_prog_ids
210 return 0
211 ;;
212 esac
213
214 local PROG_TYPE='id pinned tag'
215 case $command in
216 show|list)
217 [[ $prev != "$command" ]] && return 0
218 COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
219 return 0
220 ;;
221 dump)
222 case $prev in
223 $command)
224 COMPREPLY+=( $( compgen -W "xlated jited" -- \
225 "$cur" ) )
226 return 0
227 ;;
228 xlated|jited)
229 COMPREPLY=( $( compgen -W "$PROG_TYPE" -- \
230 "$cur" ) )
231 return 0
232 ;;
233 *)
234 _bpftool_once_attr 'file'
235 if _bpftool_search_list 'xlated'; then
236 COMPREPLY+=( $( compgen -W 'opcodes visual' -- \
237 "$cur" ) )
238 else
239 COMPREPLY+=( $( compgen -W 'opcodes' -- \
240 "$cur" ) )
241 fi
242 return 0
243 ;;
244 esac
245 ;;
246 pin)
247 if [[ $prev == "$command" ]]; then
248 COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
249 else
250 _filedir
251 fi
252 return 0
253 ;;
254 load)
255 _filedir
256 return 0
257 ;;
258 *)
259 [[ $prev == $object ]] && \
260 COMPREPLY=( $( compgen -W 'dump help pin load \
261 show list' -- "$cur" ) )
262 ;;
263 esac
264 ;;
265 map)
266 local MAP_TYPE='id pinned'
267 case $command in
268 show|list|dump)
269 case $prev in
270 $command)
271 COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
272 return 0
273 ;;
274 id)
275 _bpftool_get_map_ids
276 return 0
277 ;;
278 *)
279 return 0
280 ;;
281 esac
282 ;;
283 lookup|getnext|delete)
284 case $prev in
285 $command)
286 COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
287 return 0
288 ;;
289 id)
290 _bpftool_get_map_ids
291 return 0
292 ;;
293 key)
294 COMPREPLY+=( $( compgen -W 'hex' -- "$cur" ) )
295 ;;
296 *)
297 _bpftool_once_attr 'key'
298 return 0
299 ;;
300 esac
301 ;;
302 update)
303 case $prev in
304 $command)
305 COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
306 return 0
307 ;;
308 id)
309 _bpftool_map_update_get_id
310 return 0
311 ;;
312 key)
313 COMPREPLY+=( $( compgen -W 'hex' -- "$cur" ) )
314 ;;
315 value)
316 # We can have bytes, or references to a prog or a
317 # map, depending on the type of the map to update.
318 case $(_bpftool_map_update_map_type) in
319 array_of_maps|hash_of_maps)
320 local MAP_TYPE='id pinned'
321 COMPREPLY+=( $( compgen -W "$MAP_TYPE" \
322 -- "$cur" ) )
323 return 0
324 ;;
325 prog_array)
326 local PROG_TYPE='id pinned tag'
327 COMPREPLY+=( $( compgen -W "$PROG_TYPE" \
328 -- "$cur" ) )
329 return 0
330 ;;
331 *)
332 COMPREPLY+=( $( compgen -W 'hex' \
333 -- "$cur" ) )
334 return 0
335 ;;
336 esac
337 return 0
338 ;;
339 *)
340 _bpftool_once_attr 'key'
341 local UPDATE_FLAGS='any exist noexist'
342 for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
343 if [[ ${words[idx]} == 'value' ]]; then
344 # 'value' is present, but is not the last
345 # word i.e. we can now have UPDATE_FLAGS.
346 _bpftool_one_of_list "$UPDATE_FLAGS"
347 return 0
348 fi
349 done
350 for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
351 if [[ ${words[idx]} == 'key' ]]; then
352 # 'key' is present, but is not the last
353 # word i.e. we can now have 'value'.
354 _bpftool_once_attr 'value'
355 return 0
356 fi
357 done
358 return 0
359 ;;
360 esac
361 ;;
362 pin)
363 if [[ $prev == "$command" ]]; then
364 COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
365 else
366 _filedir
367 fi
368 return 0
369 ;;
370 event_pipe)
371 case $prev in
372 $command)
373 COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
374 return 0
375 ;;
376 id)
377 _bpftool_get_perf_map_ids
378 return 0
379 ;;
380 cpu)
381 return 0
382 ;;
383 index)
384 return 0
385 ;;
386 *)
387 _bpftool_once_attr 'cpu'
388 _bpftool_once_attr 'index'
389 return 0
390 ;;
391 esac
392 ;;
393 *)
394 [[ $prev == $object ]] && \
395 COMPREPLY=( $( compgen -W 'delete dump getnext help \
396 lookup pin event_pipe show list update' -- \
397 "$cur" ) )
398 ;;
399 esac
400 ;;
401 cgroup)
402 case $command in
403 show|list)
404 _filedir
405 return 0
406 ;;
407 attach|detach)
408 local ATTACH_TYPES='ingress egress sock_create sock_ops \
409 device bind4 bind6 post_bind4 post_bind6 connect4 \
410 connect6 sendmsg4 sendmsg6'
411 local ATTACH_FLAGS='multi override'
412 local PROG_TYPE='id pinned tag'
413 case $prev in
414 $command)
415 _filedir
416 return 0
417 ;;
418 ingress|egress|sock_create|sock_ops|device|bind4|bind6|\
419 post_bind4|post_bind6|connect4|connect6|sendmsg4|\
420 sendmsg6)
421 COMPREPLY=( $( compgen -W "$PROG_TYPE" -- \
422 "$cur" ) )
423 return 0
424 ;;
425 id)
426 _bpftool_get_prog_ids
427 return 0
428 ;;
429 *)
430 if ! _bpftool_search_list "$ATTACH_TYPES"; then
431 COMPREPLY=( $( compgen -W "$ATTACH_TYPES" -- \
432 "$cur" ) )
433 elif [[ "$command" == "attach" ]]; then
434 # We have an attach type on the command line,
435 # but it is not the previous word, or
436 # "id|pinned|tag" (we already checked for
437 # that). This should only leave the case when
438 # we need attach flags for "attach" commamnd.
439 _bpftool_one_of_list "$ATTACH_FLAGS"
440 fi
441 return 0
442 ;;
443 esac
444 ;;
445 *)
446 [[ $prev == $object ]] && \
447 COMPREPLY=( $( compgen -W 'help attach detach \
448 show list' -- "$cur" ) )
449 ;;
450 esac
451 ;;
452 perf)
453 case $command in
454 *)
455 [[ $prev == $object ]] && \
456 COMPREPLY=( $( compgen -W 'help \
457 show list' -- "$cur" ) )
458 ;;
459 esac
460 ;;
461 esac
462} &&
463complete -F _bpftool bpftool
464
465# ex: ts=4 sw=4 et filetype=sh