bpftool 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. # bpftool(8) bash completion -*- shell-script -*-
  2. #
  3. # Copyright (C) 2017 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. # Takes a list of words in argument; each one of them is added to COMPREPLY if
  37. # it is not already present on the command line. Returns no value.
  38. _bpftool_once_attr()
  39. {
  40. local w idx found
  41. for w in $*; do
  42. found=0
  43. for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
  44. if [[ $w == ${words[idx]} ]]; then
  45. found=1
  46. break
  47. fi
  48. done
  49. [[ $found -eq 0 ]] && \
  50. COMPREPLY+=( $( compgen -W "$w" -- "$cur" ) )
  51. done
  52. }
  53. # Takes a list of words as argument; if any of those words is present on the
  54. # command line, return 0. Otherwise, return 1.
  55. _bpftool_search_list()
  56. {
  57. local w idx
  58. for w in $*; do
  59. for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
  60. [[ $w == ${words[idx]} ]] && return 0
  61. done
  62. done
  63. return 1
  64. }
  65. # Takes a list of words in argument; adds them all to COMPREPLY if none of them
  66. # is already present on the command line. Returns no value.
  67. _bpftool_one_of_list()
  68. {
  69. _bpftool_search_list $* && return 1
  70. COMPREPLY+=( $( compgen -W "$*" -- "$cur" ) )
  71. }
  72. _bpftool_get_map_ids()
  73. {
  74. COMPREPLY+=( $( compgen -W "$( bpftool -jp map 2>&1 | \
  75. command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) )
  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. _bpftool_get_prog_tags()
  83. {
  84. COMPREPLY+=( $( compgen -W "$( bpftool -jp prog 2>&1 | \
  85. command sed -n 's/.*"tag": "\(.*\)",$/\1/p' )" -- "$cur" ) )
  86. }
  87. # For bpftool map update: retrieve type of the map to update.
  88. _bpftool_map_update_map_type()
  89. {
  90. local keyword ref
  91. for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
  92. if [[ ${words[$((idx-2))]} == "update" ]]; then
  93. keyword=${words[$((idx-1))]}
  94. ref=${words[$((idx))]}
  95. fi
  96. done
  97. [[ -z $ref ]] && return 0
  98. local type
  99. type=$(bpftool -jp map show $keyword $ref | \
  100. command sed -n 's/.*"type": "\(.*\)",$/\1/p')
  101. printf $type
  102. }
  103. _bpftool_map_update_get_id()
  104. {
  105. # Is it the map to update, or a map to insert into the map to update?
  106. # Search for "value" keyword.
  107. local idx value
  108. for (( idx=7; idx < ${#words[@]}-1; idx++ )); do
  109. if [[ ${words[idx]} == "value" ]]; then
  110. value=1
  111. break
  112. fi
  113. done
  114. [[ $value -eq 0 ]] && _bpftool_get_map_ids && return 0
  115. # Id to complete is for a value. It can be either prog id or map id. This
  116. # depends on the type of the map to update.
  117. local type=$(_bpftool_map_update_map_type)
  118. case $type in
  119. array_of_maps|hash_of_maps)
  120. _bpftool_get_map_ids
  121. return 0
  122. ;;
  123. prog_array)
  124. _bpftool_get_prog_ids
  125. return 0
  126. ;;
  127. *)
  128. return 0
  129. ;;
  130. esac
  131. }
  132. _bpftool()
  133. {
  134. local cur prev words objword
  135. _init_completion || return
  136. # Deal with simplest keywords
  137. case $prev in
  138. help|key|opcodes|visual)
  139. return 0
  140. ;;
  141. tag)
  142. _bpftool_get_prog_tags
  143. return 0
  144. ;;
  145. file|pinned)
  146. _filedir
  147. return 0
  148. ;;
  149. batch)
  150. COMPREPLY=( $( compgen -W 'file' -- "$cur" ) )
  151. return 0
  152. ;;
  153. esac
  154. # Search for object and command
  155. local object command cmdword
  156. for (( cmdword=1; cmdword < ${#words[@]}-1; cmdword++ )); do
  157. [[ -n $object ]] && command=${words[cmdword]} && break
  158. [[ ${words[cmdword]} != -* ]] && object=${words[cmdword]}
  159. done
  160. if [[ -z $object ]]; then
  161. case $cur in
  162. -*)
  163. local c='--version --json --pretty'
  164. COMPREPLY=( $( compgen -W "$c" -- "$cur" ) )
  165. return 0
  166. ;;
  167. *)
  168. COMPREPLY=( $( compgen -W "$( bpftool help 2>&1 | \
  169. command sed \
  170. -e '/OBJECT := /!d' \
  171. -e 's/.*{//' \
  172. -e 's/}.*//' \
  173. -e 's/|//g' )" -- "$cur" ) )
  174. COMPREPLY+=( $( compgen -W 'batch help' -- "$cur" ) )
  175. return 0
  176. ;;
  177. esac
  178. fi
  179. [[ $command == help ]] && return 0
  180. # Completion depends on object and command in use
  181. case $object in
  182. prog)
  183. case $prev in
  184. id)
  185. _bpftool_get_prog_ids
  186. return 0
  187. ;;
  188. esac
  189. local PROG_TYPE='id pinned tag'
  190. case $command in
  191. show|list)
  192. [[ $prev != "$command" ]] && return 0
  193. COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
  194. return 0
  195. ;;
  196. dump)
  197. case $prev in
  198. $command)
  199. COMPREPLY+=( $( compgen -W "xlated jited" -- \
  200. "$cur" ) )
  201. return 0
  202. ;;
  203. xlated|jited)
  204. COMPREPLY=( $( compgen -W "$PROG_TYPE" -- \
  205. "$cur" ) )
  206. return 0
  207. ;;
  208. *)
  209. _bpftool_once_attr 'file'
  210. if _bpftool_search_list 'xlated'; then
  211. COMPREPLY+=( $( compgen -W 'opcodes visual' -- \
  212. "$cur" ) )
  213. else
  214. COMPREPLY+=( $( compgen -W 'opcodes' -- \
  215. "$cur" ) )
  216. fi
  217. return 0
  218. ;;
  219. esac
  220. ;;
  221. pin)
  222. if [[ $prev == "$command" ]]; then
  223. COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
  224. else
  225. _filedir
  226. fi
  227. return 0
  228. ;;
  229. load)
  230. _filedir
  231. return 0
  232. ;;
  233. *)
  234. [[ $prev == $object ]] && \
  235. COMPREPLY=( $( compgen -W 'dump help pin load \
  236. show list' -- "$cur" ) )
  237. ;;
  238. esac
  239. ;;
  240. map)
  241. local MAP_TYPE='id pinned'
  242. case $command in
  243. show|list|dump)
  244. case $prev in
  245. $command)
  246. COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
  247. return 0
  248. ;;
  249. id)
  250. _bpftool_get_map_ids
  251. return 0
  252. ;;
  253. *)
  254. return 0
  255. ;;
  256. esac
  257. ;;
  258. lookup|getnext|delete)
  259. case $prev in
  260. $command)
  261. COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
  262. return 0
  263. ;;
  264. id)
  265. _bpftool_get_map_ids
  266. return 0
  267. ;;
  268. key)
  269. return 0
  270. ;;
  271. *)
  272. _bpftool_once_attr 'key'
  273. return 0
  274. ;;
  275. esac
  276. ;;
  277. update)
  278. case $prev in
  279. $command)
  280. COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
  281. return 0
  282. ;;
  283. id)
  284. _bpftool_map_update_get_id
  285. return 0
  286. ;;
  287. key)
  288. return 0
  289. ;;
  290. value)
  291. # We can have bytes, or references to a prog or a
  292. # map, depending on the type of the map to update.
  293. case $(_bpftool_map_update_map_type) in
  294. array_of_maps|hash_of_maps)
  295. local MAP_TYPE='id pinned'
  296. COMPREPLY+=( $( compgen -W "$MAP_TYPE" \
  297. -- "$cur" ) )
  298. return 0
  299. ;;
  300. prog_array)
  301. local PROG_TYPE='id pinned tag'
  302. COMPREPLY+=( $( compgen -W "$PROG_TYPE" \
  303. -- "$cur" ) )
  304. return 0
  305. ;;
  306. *)
  307. return 0
  308. ;;
  309. esac
  310. return 0
  311. ;;
  312. *)
  313. _bpftool_once_attr 'key'
  314. local UPDATE_FLAGS='any exist noexist'
  315. for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
  316. if [[ ${words[idx]} == 'value' ]]; then
  317. # 'value' is present, but is not the last
  318. # word i.e. we can now have UPDATE_FLAGS.
  319. _bpftool_one_of_list "$UPDATE_FLAGS"
  320. return 0
  321. fi
  322. done
  323. for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
  324. if [[ ${words[idx]} == 'key' ]]; then
  325. # 'key' is present, but is not the last
  326. # word i.e. we can now have 'value'.
  327. _bpftool_once_attr 'value'
  328. return 0
  329. fi
  330. done
  331. return 0
  332. ;;
  333. esac
  334. ;;
  335. pin)
  336. if [[ $prev == "$command" ]]; then
  337. COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
  338. else
  339. _filedir
  340. fi
  341. return 0
  342. ;;
  343. *)
  344. [[ $prev == $object ]] && \
  345. COMPREPLY=( $( compgen -W 'delete dump getnext help \
  346. lookup pin show list update' -- "$cur" ) )
  347. ;;
  348. esac
  349. ;;
  350. cgroup)
  351. case $command in
  352. show|list)
  353. _filedir
  354. return 0
  355. ;;
  356. attach|detach)
  357. local ATTACH_TYPES='ingress egress sock_create sock_ops \
  358. device'
  359. local ATTACH_FLAGS='multi override'
  360. local PROG_TYPE='id pinned tag'
  361. case $prev in
  362. $command)
  363. _filedir
  364. return 0
  365. ;;
  366. ingress|egress|sock_create|sock_ops|device)
  367. COMPREPLY=( $( compgen -W "$PROG_TYPE" -- \
  368. "$cur" ) )
  369. return 0
  370. ;;
  371. id)
  372. _bpftool_get_prog_ids
  373. return 0
  374. ;;
  375. *)
  376. if ! _bpftool_search_list "$ATTACH_TYPES"; then
  377. COMPREPLY=( $( compgen -W "$ATTACH_TYPES" -- \
  378. "$cur" ) )
  379. elif [[ "$command" == "attach" ]]; then
  380. # We have an attach type on the command line,
  381. # but it is not the previous word, or
  382. # "id|pinned|tag" (we already checked for
  383. # that). This should only leave the case when
  384. # we need attach flags for "attach" commamnd.
  385. _bpftool_one_of_list "$ATTACH_FLAGS"
  386. fi
  387. return 0
  388. ;;
  389. esac
  390. ;;
  391. *)
  392. [[ $prev == $object ]] && \
  393. COMPREPLY=( $( compgen -W 'help attach detach \
  394. show list' -- "$cur" ) )
  395. ;;
  396. esac
  397. ;;
  398. esac
  399. } &&
  400. complete -F _bpftool bpftool
  401. # ex: ts=4 sw=4 et filetype=sh