bpftool 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203
  1. # bpftool(8) bash completion -*- shell-script -*-
  2. #
  3. # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
  4. # Copyright (C) 2017-2018 Netronome Systems, Inc.
  5. #
  6. # Author: Quentin Monnet <quentin.monnet@netronome.com>
  7. # Takes a list of words in argument; each one of them is added to COMPREPLY if
  8. # it is not already present on the command line. Returns no value.
  9. _bpftool_once_attr()
  10. {
  11. local w idx found
  12. for w in $*; do
  13. found=0
  14. for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
  15. if [[ $w == ${words[idx]} ]]; then
  16. found=1
  17. break
  18. fi
  19. done
  20. [[ $found -eq 0 ]] && \
  21. COMPREPLY+=( $( compgen -W "$w" -- "$cur" ) )
  22. done
  23. }
  24. # Takes a list of words as argument; if any of those words is present on the
  25. # command line, return 0. Otherwise, return 1.
  26. _bpftool_search_list()
  27. {
  28. local w idx
  29. for w in $*; do
  30. for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
  31. [[ $w == ${words[idx]} ]] && return 0
  32. done
  33. done
  34. return 1
  35. }
  36. # Takes a list of words in argument; adds them all to COMPREPLY if none of them
  37. # is already present on the command line. Returns no value.
  38. _bpftool_one_of_list()
  39. {
  40. _bpftool_search_list $* && return 1
  41. COMPREPLY+=( $( compgen -W "$*" -- "$cur" ) )
  42. }
  43. _bpftool_get_map_ids()
  44. {
  45. COMPREPLY+=( $( compgen -W "$( bpftool -jp map 2>&1 | \
  46. command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) )
  47. }
  48. # Takes map type and adds matching map ids to the list of suggestions.
  49. _bpftool_get_map_ids_for_type()
  50. {
  51. local type="$1"
  52. COMPREPLY+=( $( compgen -W "$( bpftool -jp map 2>&1 | \
  53. command grep -C2 "$type" | \
  54. command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) )
  55. }
  56. _bpftool_get_map_names()
  57. {
  58. COMPREPLY+=( $( compgen -W "$( bpftool -jp map 2>&1 | \
  59. command sed -n 's/.*"name": \(.*\),$/\1/p' )" -- "$cur" ) )
  60. }
  61. # Takes map type and adds matching map names to the list of suggestions.
  62. _bpftool_get_map_names_for_type()
  63. {
  64. local type="$1"
  65. COMPREPLY+=( $( compgen -W "$( bpftool -jp map 2>&1 | \
  66. command grep -C2 "$type" | \
  67. command sed -n 's/.*"name": \(.*\),$/\1/p' )" -- "$cur" ) )
  68. }
  69. _bpftool_get_prog_ids()
  70. {
  71. COMPREPLY+=( $( compgen -W "$( bpftool -jp prog 2>&1 | \
  72. command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) )
  73. }
  74. _bpftool_get_prog_tags()
  75. {
  76. COMPREPLY+=( $( compgen -W "$( bpftool -jp prog 2>&1 | \
  77. command sed -n 's/.*"tag": "\(.*\)",$/\1/p' )" -- "$cur" ) )
  78. }
  79. _bpftool_get_prog_names()
  80. {
  81. COMPREPLY+=( $( compgen -W "$( bpftool -jp prog 2>&1 | \
  82. command sed -n 's/.*"name": "\(.*\)",$/\1/p' )" -- "$cur" ) )
  83. }
  84. _bpftool_get_btf_ids()
  85. {
  86. COMPREPLY+=( $( compgen -W "$( bpftool -jp btf 2>&1 | \
  87. command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) )
  88. }
  89. _bpftool_get_link_ids()
  90. {
  91. COMPREPLY+=( $( compgen -W "$( bpftool -jp link 2>&1 | \
  92. command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) )
  93. }
  94. _bpftool_get_obj_map_names()
  95. {
  96. local obj maps
  97. obj=$1
  98. maps=$(objdump -j .maps -t $obj 2>/dev/null | \
  99. command awk '/g . .maps/ {print $NF}')
  100. COMPREPLY+=( $( compgen -W "$maps" -- "$cur" ) )
  101. }
  102. _bpftool_get_obj_map_idxs()
  103. {
  104. local obj nmaps
  105. obj=$1
  106. nmaps=$(objdump -j maps -t $obj 2>/dev/null | grep -c 'g . maps')
  107. COMPREPLY+=( $( compgen -W "$(seq 0 $((nmaps - 1)))" -- "$cur" ) )
  108. }
  109. _sysfs_get_netdevs()
  110. {
  111. COMPREPLY+=( $( compgen -W "$( ls /sys/class/net 2>/dev/null )" -- \
  112. "$cur" ) )
  113. }
  114. # Retrieve type of the map that we are operating on.
  115. _bpftool_map_guess_map_type()
  116. {
  117. local keyword idx ref=""
  118. for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
  119. case "${words[$((idx-2))]}" in
  120. lookup|update)
  121. keyword=${words[$((idx-1))]}
  122. ref=${words[$((idx))]}
  123. ;;
  124. push)
  125. printf "stack"
  126. return 0
  127. ;;
  128. enqueue)
  129. printf "queue"
  130. return 0
  131. ;;
  132. esac
  133. done
  134. [[ -z $ref ]] && return 0
  135. local type
  136. type=$(bpftool -jp map show $keyword $ref | \
  137. command sed -n 's/.*"type": "\(.*\)",$/\1/p')
  138. [[ -n $type ]] && printf $type
  139. }
  140. _bpftool_map_update_get_id()
  141. {
  142. local command="$1"
  143. # Is it the map to update, or a map to insert into the map to update?
  144. # Search for "value" keyword.
  145. local idx value
  146. for (( idx=7; idx < ${#words[@]}-1; idx++ )); do
  147. if [[ ${words[idx]} == "value" ]]; then
  148. value=1
  149. break
  150. fi
  151. done
  152. if [[ $value -eq 0 ]]; then
  153. case "$command" in
  154. push)
  155. _bpftool_get_map_ids_for_type stack
  156. ;;
  157. enqueue)
  158. _bpftool_get_map_ids_for_type queue
  159. ;;
  160. *)
  161. _bpftool_get_map_ids
  162. ;;
  163. esac
  164. return 0
  165. fi
  166. # Id to complete is for a value. It can be either prog id or map id. This
  167. # depends on the type of the map to update.
  168. local type=$(_bpftool_map_guess_map_type)
  169. case $type in
  170. array_of_maps|hash_of_maps)
  171. _bpftool_get_map_ids
  172. return 0
  173. ;;
  174. prog_array)
  175. _bpftool_get_prog_ids
  176. return 0
  177. ;;
  178. *)
  179. return 0
  180. ;;
  181. esac
  182. }
  183. _bpftool_map_update_get_name()
  184. {
  185. local command="$1"
  186. # Is it the map to update, or a map to insert into the map to update?
  187. # Search for "value" keyword.
  188. local idx value
  189. for (( idx=7; idx < ${#words[@]}-1; idx++ )); do
  190. if [[ ${words[idx]} == "value" ]]; then
  191. value=1
  192. break
  193. fi
  194. done
  195. if [[ $value -eq 0 ]]; then
  196. case "$command" in
  197. push)
  198. _bpftool_get_map_names_for_type stack
  199. ;;
  200. enqueue)
  201. _bpftool_get_map_names_for_type queue
  202. ;;
  203. *)
  204. _bpftool_get_map_names
  205. ;;
  206. esac
  207. return 0
  208. fi
  209. # Name to complete is for a value. It can be either prog name or map name. This
  210. # depends on the type of the map to update.
  211. local type=$(_bpftool_map_guess_map_type)
  212. case $type in
  213. array_of_maps|hash_of_maps)
  214. _bpftool_get_map_names
  215. return 0
  216. ;;
  217. prog_array)
  218. _bpftool_get_prog_names
  219. return 0
  220. ;;
  221. *)
  222. return 0
  223. ;;
  224. esac
  225. }
  226. _bpftool()
  227. {
  228. local cur prev words cword comp_args
  229. local json=0
  230. _init_completion -- "$@" || return
  231. # Deal with options
  232. if [[ ${words[cword]} == -* ]]; then
  233. local c='--version --json --pretty --bpffs --mapcompat --debug \
  234. --use-loader --base-btf'
  235. COMPREPLY=( $( compgen -W "$c" -- "$cur" ) )
  236. return 0
  237. fi
  238. if _bpftool_search_list -j --json -p --pretty; then
  239. json=1
  240. fi
  241. # Deal with simplest keywords
  242. case $prev in
  243. help|hex)
  244. return 0
  245. ;;
  246. tag)
  247. _bpftool_get_prog_tags
  248. return 0
  249. ;;
  250. dev|offload_dev|xdpmeta_dev)
  251. _sysfs_get_netdevs
  252. return 0
  253. ;;
  254. file|pinned|-B|--base-btf)
  255. _filedir
  256. return 0
  257. ;;
  258. batch)
  259. COMPREPLY=( $( compgen -W 'file' -- "$cur" ) )
  260. return 0
  261. ;;
  262. esac
  263. # Remove all options so completions don't have to deal with them.
  264. local i pprev
  265. for (( i=1; i < ${#words[@]}; )); do
  266. if [[ ${words[i]::1} == - ]] &&
  267. [[ ${words[i]} != "-B" ]] && [[ ${words[i]} != "--base-btf" ]]; then
  268. words=( "${words[@]:0:i}" "${words[@]:i+1}" )
  269. [[ $i -le $cword ]] && cword=$(( cword - 1 ))
  270. else
  271. i=$(( ++i ))
  272. fi
  273. done
  274. cur=${words[cword]}
  275. prev=${words[cword - 1]}
  276. pprev=${words[cword - 2]}
  277. local object=${words[1]}
  278. if [[ -z $object || $cword -eq 1 ]]; then
  279. case $cur in
  280. *)
  281. COMPREPLY=( $( compgen -W "$( bpftool help 2>&1 | \
  282. command sed \
  283. -e '/OBJECT := /!d' \
  284. -e 's/.*{//' \
  285. -e 's/}.*//' \
  286. -e 's/|//g' )" -- "$cur" ) )
  287. COMPREPLY+=( $( compgen -W 'batch help' -- "$cur" ) )
  288. return 0
  289. ;;
  290. esac
  291. fi
  292. local command=${words[2]}
  293. [[ $command == help ]] && return 0
  294. local MAP_TYPE='id pinned name'
  295. local PROG_TYPE='id pinned tag name'
  296. # Completion depends on object and command in use
  297. case $object in
  298. prog)
  299. # Complete id and name, only for subcommands that use prog (but no
  300. # map) ids/names.
  301. case $command in
  302. show|list|dump|pin)
  303. case $prev in
  304. id)
  305. _bpftool_get_prog_ids
  306. return 0
  307. ;;
  308. name)
  309. _bpftool_get_prog_names
  310. return 0
  311. ;;
  312. esac
  313. ;;
  314. esac
  315. local METRIC_TYPE='cycles instructions l1d_loads llc_misses \
  316. itlb_misses dtlb_misses'
  317. case $command in
  318. show|list)
  319. [[ $prev != "$command" ]] && return 0
  320. COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
  321. return 0
  322. ;;
  323. dump)
  324. case $prev in
  325. $command)
  326. COMPREPLY+=( $( compgen -W "xlated jited" -- \
  327. "$cur" ) )
  328. return 0
  329. ;;
  330. xlated|jited)
  331. COMPREPLY=( $( compgen -W "$PROG_TYPE" -- \
  332. "$cur" ) )
  333. return 0
  334. ;;
  335. *)
  336. # "file" is not compatible with other keywords here
  337. if _bpftool_search_list 'file'; then
  338. return 0
  339. fi
  340. if ! _bpftool_search_list 'linum opcodes visual'; then
  341. _bpftool_once_attr 'file'
  342. fi
  343. _bpftool_once_attr 'linum opcodes'
  344. if _bpftool_search_list 'xlated' && [[ "$json" == 0 ]]; then
  345. _bpftool_once_attr 'visual'
  346. fi
  347. return 0
  348. ;;
  349. esac
  350. ;;
  351. pin)
  352. if [[ $prev == "$command" ]]; then
  353. COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
  354. else
  355. _filedir
  356. fi
  357. return 0
  358. ;;
  359. attach|detach)
  360. case $cword in
  361. 3)
  362. COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
  363. return 0
  364. ;;
  365. 4)
  366. case $prev in
  367. id)
  368. _bpftool_get_prog_ids
  369. ;;
  370. name)
  371. _bpftool_get_prog_names
  372. ;;
  373. pinned)
  374. _filedir
  375. ;;
  376. esac
  377. return 0
  378. ;;
  379. 5)
  380. local BPFTOOL_PROG_ATTACH_TYPES='sk_msg_verdict \
  381. sk_skb_verdict sk_skb_stream_verdict sk_skb_stream_parser \
  382. flow_dissector'
  383. COMPREPLY=( $( compgen -W "$BPFTOOL_PROG_ATTACH_TYPES" -- "$cur" ) )
  384. return 0
  385. ;;
  386. 6)
  387. COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
  388. return 0
  389. ;;
  390. 7)
  391. case $prev in
  392. id)
  393. _bpftool_get_map_ids
  394. ;;
  395. name)
  396. _bpftool_get_map_names
  397. ;;
  398. pinned)
  399. _filedir
  400. ;;
  401. esac
  402. return 0
  403. ;;
  404. esac
  405. ;;
  406. load|loadall)
  407. local obj
  408. # Propose "load/loadall" to complete "bpftool prog load",
  409. # or bash tries to complete "load" as a filename below.
  410. if [[ ${#words[@]} -eq 3 ]]; then
  411. COMPREPLY=( $( compgen -W "load loadall" -- "$cur" ) )
  412. return 0
  413. fi
  414. if [[ ${#words[@]} -lt 6 ]]; then
  415. _filedir
  416. return 0
  417. fi
  418. obj=${words[3]}
  419. if [[ ${words[-4]} == "map" ]]; then
  420. COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
  421. return 0
  422. fi
  423. if [[ ${words[-3]} == "map" ]]; then
  424. if [[ ${words[-2]} == "idx" ]]; then
  425. _bpftool_get_obj_map_idxs $obj
  426. elif [[ ${words[-2]} == "name" ]]; then
  427. _bpftool_get_obj_map_names $obj
  428. fi
  429. return 0
  430. fi
  431. if [[ ${words[-2]} == "map" ]]; then
  432. COMPREPLY=( $( compgen -W "idx name" -- "$cur" ) )
  433. return 0
  434. fi
  435. case $prev in
  436. type)
  437. local BPFTOOL_PROG_LOAD_TYPES='socket kprobe \
  438. kretprobe classifier flow_dissector \
  439. action tracepoint raw_tracepoint \
  440. xdp perf_event cgroup/skb cgroup/sock \
  441. cgroup/dev lwt_in lwt_out lwt_xmit \
  442. lwt_seg6local sockops sk_skb sk_msg lirc_mode2 \
  443. cgroup/bind4 cgroup/bind6 \
  444. cgroup/connect4 cgroup/connect6 cgroup/connect_unix \
  445. cgroup/getpeername4 cgroup/getpeername6 cgroup/getpeername_unix \
  446. cgroup/getsockname4 cgroup/getsockname6 cgroup/getsockname_unix \
  447. cgroup/sendmsg4 cgroup/sendmsg6 cgroup/sendmsg_unix \
  448. cgroup/recvmsg4 cgroup/recvmsg6 cgroup/recvmsg_unix \
  449. cgroup/post_bind4 cgroup/post_bind6 \
  450. cgroup/sysctl cgroup/getsockopt \
  451. cgroup/setsockopt cgroup/sock_release struct_ops \
  452. fentry fexit freplace sk_lookup'
  453. COMPREPLY=( $( compgen -W "$BPFTOOL_PROG_LOAD_TYPES" -- "$cur" ) )
  454. return 0
  455. ;;
  456. id)
  457. _bpftool_get_map_ids
  458. return 0
  459. ;;
  460. name)
  461. _bpftool_get_map_names
  462. return 0
  463. ;;
  464. pinned|pinmaps)
  465. _filedir
  466. return 0
  467. ;;
  468. *)
  469. COMPREPLY=( $( compgen -W "map" -- "$cur" ) )
  470. _bpftool_once_attr 'type pinmaps autoattach'
  471. _bpftool_one_of_list 'offload_dev xdpmeta_dev'
  472. return 0
  473. ;;
  474. esac
  475. ;;
  476. tracelog)
  477. return 0
  478. ;;
  479. profile)
  480. case $cword in
  481. 3)
  482. COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
  483. return 0
  484. ;;
  485. 4)
  486. case $prev in
  487. id)
  488. _bpftool_get_prog_ids
  489. ;;
  490. name)
  491. _bpftool_get_prog_names
  492. ;;
  493. pinned)
  494. _filedir
  495. ;;
  496. esac
  497. return 0
  498. ;;
  499. 5)
  500. COMPREPLY=( $( compgen -W "$METRIC_TYPE duration" -- "$cur" ) )
  501. return 0
  502. ;;
  503. *)
  504. [[ $prev == duration ]] && return 0
  505. _bpftool_once_attr "$METRIC_TYPE"
  506. return 0
  507. ;;
  508. esac
  509. ;;
  510. run)
  511. if [[ ${#words[@]} -eq 4 ]]; then
  512. COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
  513. return 0
  514. fi
  515. case $prev in
  516. id)
  517. _bpftool_get_prog_ids
  518. return 0
  519. ;;
  520. name)
  521. _bpftool_get_prog_names
  522. return 0
  523. ;;
  524. data_in|data_out|ctx_in|ctx_out)
  525. _filedir
  526. return 0
  527. ;;
  528. repeat|data_size_out|ctx_size_out)
  529. return 0
  530. ;;
  531. *)
  532. _bpftool_once_attr 'data_in data_out data_size_out \
  533. ctx_in ctx_out ctx_size_out repeat'
  534. return 0
  535. ;;
  536. esac
  537. ;;
  538. *)
  539. [[ $prev == $object ]] && \
  540. COMPREPLY=( $( compgen -W 'dump help pin attach detach \
  541. load loadall show list tracelog run profile' -- "$cur" ) )
  542. ;;
  543. esac
  544. ;;
  545. struct_ops)
  546. local STRUCT_OPS_TYPE='id name'
  547. case $command in
  548. show|list|dump|unregister)
  549. case $prev in
  550. $command)
  551. COMPREPLY=( $( compgen -W "$STRUCT_OPS_TYPE" -- "$cur" ) )
  552. ;;
  553. id)
  554. _bpftool_get_map_ids_for_type struct_ops
  555. ;;
  556. name)
  557. _bpftool_get_map_names_for_type struct_ops
  558. ;;
  559. esac
  560. return 0
  561. ;;
  562. register)
  563. [[ $prev == $command ]] && _filedir
  564. return 0
  565. ;;
  566. *)
  567. [[ $prev == $object ]] && \
  568. COMPREPLY=( $( compgen -W 'register unregister show list dump help' \
  569. -- "$cur" ) )
  570. ;;
  571. esac
  572. ;;
  573. iter)
  574. case $command in
  575. pin)
  576. case $prev in
  577. $command)
  578. _filedir
  579. ;;
  580. id)
  581. _bpftool_get_map_ids
  582. ;;
  583. name)
  584. _bpftool_get_map_names
  585. ;;
  586. pinned)
  587. _filedir
  588. ;;
  589. map)
  590. _bpftool_one_of_list $MAP_TYPE
  591. ;;
  592. *)
  593. _bpftool_once_attr 'map'
  594. ;;
  595. esac
  596. return 0
  597. ;;
  598. *)
  599. [[ $prev == $object ]] && \
  600. COMPREPLY=( $( compgen -W 'pin help' \
  601. -- "$cur" ) )
  602. ;;
  603. esac
  604. ;;
  605. map)
  606. case $command in
  607. show|list|dump|peek|pop|dequeue|freeze)
  608. case $prev in
  609. $command)
  610. COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
  611. return 0
  612. ;;
  613. id)
  614. case "$command" in
  615. peek)
  616. _bpftool_get_map_ids_for_type stack
  617. _bpftool_get_map_ids_for_type queue
  618. ;;
  619. pop)
  620. _bpftool_get_map_ids_for_type stack
  621. ;;
  622. dequeue)
  623. _bpftool_get_map_ids_for_type queue
  624. ;;
  625. *)
  626. _bpftool_get_map_ids
  627. ;;
  628. esac
  629. return 0
  630. ;;
  631. name)
  632. case "$command" in
  633. peek)
  634. _bpftool_get_map_names_for_type stack
  635. _bpftool_get_map_names_for_type queue
  636. ;;
  637. pop)
  638. _bpftool_get_map_names_for_type stack
  639. ;;
  640. dequeue)
  641. _bpftool_get_map_names_for_type queue
  642. ;;
  643. *)
  644. _bpftool_get_map_names
  645. ;;
  646. esac
  647. return 0
  648. ;;
  649. *)
  650. return 0
  651. ;;
  652. esac
  653. ;;
  654. create)
  655. case $prev in
  656. $command)
  657. _filedir
  658. return 0
  659. ;;
  660. type)
  661. local BPFTOOL_MAP_CREATE_TYPES="$(bpftool feature list_builtins map_types 2>/dev/null | \
  662. grep -v '^unspec$')"
  663. COMPREPLY=( $( compgen -W "$BPFTOOL_MAP_CREATE_TYPES" -- "$cur" ) )
  664. return 0
  665. ;;
  666. key|value|flags|entries)
  667. return 0
  668. ;;
  669. inner_map)
  670. COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
  671. return 0
  672. ;;
  673. id)
  674. _bpftool_get_map_ids
  675. ;;
  676. name)
  677. case $pprev in
  678. inner_map)
  679. _bpftool_get_map_names
  680. ;;
  681. *)
  682. return 0
  683. ;;
  684. esac
  685. ;;
  686. *)
  687. _bpftool_once_attr 'type key value entries name flags offload_dev'
  688. if _bpftool_search_list 'array_of_maps' 'hash_of_maps'; then
  689. _bpftool_once_attr 'inner_map'
  690. fi
  691. return 0
  692. ;;
  693. esac
  694. ;;
  695. lookup|getnext|delete)
  696. case $prev in
  697. $command)
  698. COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
  699. return 0
  700. ;;
  701. id)
  702. _bpftool_get_map_ids
  703. return 0
  704. ;;
  705. name)
  706. _bpftool_get_map_names
  707. return 0
  708. ;;
  709. key)
  710. COMPREPLY+=( $( compgen -W 'hex' -- "$cur" ) )
  711. ;;
  712. *)
  713. case $(_bpftool_map_guess_map_type) in
  714. queue|stack)
  715. return 0
  716. ;;
  717. esac
  718. _bpftool_once_attr 'key'
  719. return 0
  720. ;;
  721. esac
  722. ;;
  723. update|push|enqueue)
  724. case $prev in
  725. $command)
  726. COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
  727. return 0
  728. ;;
  729. id)
  730. _bpftool_map_update_get_id $command
  731. return 0
  732. ;;
  733. name)
  734. _bpftool_map_update_get_name $command
  735. return 0
  736. ;;
  737. key)
  738. COMPREPLY+=( $( compgen -W 'hex' -- "$cur" ) )
  739. ;;
  740. value)
  741. # We can have bytes, or references to a prog or a
  742. # map, depending on the type of the map to update.
  743. case "$(_bpftool_map_guess_map_type)" in
  744. array_of_maps|hash_of_maps)
  745. COMPREPLY+=( $( compgen -W "$MAP_TYPE" \
  746. -- "$cur" ) )
  747. return 0
  748. ;;
  749. prog_array)
  750. COMPREPLY+=( $( compgen -W "$PROG_TYPE" \
  751. -- "$cur" ) )
  752. return 0
  753. ;;
  754. *)
  755. COMPREPLY+=( $( compgen -W 'hex' \
  756. -- "$cur" ) )
  757. return 0
  758. ;;
  759. esac
  760. return 0
  761. ;;
  762. *)
  763. case $(_bpftool_map_guess_map_type) in
  764. queue|stack)
  765. _bpftool_once_attr 'value'
  766. return 0;
  767. ;;
  768. esac
  769. _bpftool_once_attr 'key'
  770. local UPDATE_FLAGS='any exist noexist' idx
  771. for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
  772. if [[ ${words[idx]} == 'value' ]]; then
  773. # 'value' is present, but is not the last
  774. # word i.e. we can now have UPDATE_FLAGS.
  775. _bpftool_one_of_list "$UPDATE_FLAGS"
  776. return 0
  777. fi
  778. done
  779. for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
  780. if [[ ${words[idx]} == 'key' ]]; then
  781. # 'key' is present, but is not the last
  782. # word i.e. we can now have 'value'.
  783. _bpftool_once_attr 'value'
  784. return 0
  785. fi
  786. done
  787. return 0
  788. ;;
  789. esac
  790. ;;
  791. pin)
  792. case $prev in
  793. $command)
  794. COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
  795. ;;
  796. id)
  797. _bpftool_get_map_ids
  798. ;;
  799. name)
  800. _bpftool_get_map_names
  801. ;;
  802. esac
  803. return 0
  804. ;;
  805. event_pipe)
  806. case $prev in
  807. $command)
  808. COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
  809. return 0
  810. ;;
  811. id)
  812. _bpftool_get_map_ids_for_type perf_event_array
  813. return 0
  814. ;;
  815. name)
  816. _bpftool_get_map_names_for_type perf_event_array
  817. return 0
  818. ;;
  819. cpu)
  820. return 0
  821. ;;
  822. index)
  823. return 0
  824. ;;
  825. *)
  826. _bpftool_once_attr 'cpu index'
  827. return 0
  828. ;;
  829. esac
  830. ;;
  831. *)
  832. [[ $prev == $object ]] && \
  833. COMPREPLY=( $( compgen -W 'delete dump getnext help \
  834. lookup pin event_pipe show list update create \
  835. peek push enqueue pop dequeue freeze' -- \
  836. "$cur" ) )
  837. ;;
  838. esac
  839. ;;
  840. btf)
  841. local MAP_TYPE='id pinned name'
  842. case $command in
  843. dump)
  844. case $prev in
  845. $command)
  846. COMPREPLY+=( $( compgen -W "id map prog file" -- \
  847. "$cur" ) )
  848. return 0
  849. ;;
  850. prog)
  851. COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
  852. return 0
  853. ;;
  854. map)
  855. COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
  856. return 0
  857. ;;
  858. id)
  859. case $pprev in
  860. prog)
  861. _bpftool_get_prog_ids
  862. ;;
  863. map)
  864. _bpftool_get_map_ids
  865. ;;
  866. $command)
  867. _bpftool_get_btf_ids
  868. ;;
  869. esac
  870. return 0
  871. ;;
  872. name)
  873. case $pprev in
  874. prog)
  875. _bpftool_get_prog_names
  876. ;;
  877. map)
  878. _bpftool_get_map_names
  879. ;;
  880. esac
  881. return 0
  882. ;;
  883. format)
  884. COMPREPLY=( $( compgen -W "c raw" -- "$cur" ) )
  885. ;;
  886. c)
  887. COMPREPLY=( $( compgen -W "unsorted" -- "$cur" ) )
  888. ;;
  889. *)
  890. # emit extra options
  891. case ${words[3]} in
  892. id|file)
  893. _bpftool_once_attr 'format'
  894. ;;
  895. map|prog)
  896. if [[ ${words[3]} == "map" ]] && [[ $cword == 6 ]]; then
  897. COMPREPLY+=( $( compgen -W "key value kv all" -- "$cur" ) )
  898. fi
  899. _bpftool_once_attr 'format'
  900. ;;
  901. *)
  902. ;;
  903. esac
  904. return 0
  905. ;;
  906. esac
  907. ;;
  908. show|list)
  909. case $prev in
  910. $command)
  911. COMPREPLY+=( $( compgen -W "id" -- "$cur" ) )
  912. ;;
  913. id)
  914. _bpftool_get_btf_ids
  915. ;;
  916. esac
  917. return 0
  918. ;;
  919. *)
  920. [[ $prev == $object ]] && \
  921. COMPREPLY=( $( compgen -W 'dump help show list' \
  922. -- "$cur" ) )
  923. ;;
  924. esac
  925. ;;
  926. gen)
  927. case $command in
  928. object)
  929. _filedir
  930. return 0
  931. ;;
  932. skeleton)
  933. case $prev in
  934. $command)
  935. _filedir
  936. return 0
  937. ;;
  938. *)
  939. _bpftool_once_attr 'name'
  940. return 0
  941. ;;
  942. esac
  943. ;;
  944. subskeleton)
  945. case $prev in
  946. $command)
  947. _filedir
  948. return 0
  949. ;;
  950. *)
  951. _bpftool_once_attr 'name'
  952. return 0
  953. ;;
  954. esac
  955. ;;
  956. min_core_btf)
  957. _filedir
  958. return 0
  959. ;;
  960. *)
  961. [[ $prev == $object ]] && \
  962. COMPREPLY=( $( compgen -W 'object skeleton subskeleton help min_core_btf' -- "$cur" ) )
  963. ;;
  964. esac
  965. ;;
  966. cgroup)
  967. case $command in
  968. show|list|tree)
  969. case $cword in
  970. 3)
  971. _filedir
  972. ;;
  973. 4)
  974. COMPREPLY=( $( compgen -W 'effective' -- "$cur" ) )
  975. ;;
  976. esac
  977. return 0
  978. ;;
  979. attach|detach)
  980. local BPFTOOL_CGROUP_ATTACH_TYPES="$(bpftool feature list_builtins attach_types 2>/dev/null | \
  981. grep '^cgroup_')"
  982. local ATTACH_FLAGS='multi override'
  983. # Check for $prev = $command first
  984. if [ $prev = $command ]; then
  985. _filedir
  986. return 0
  987. # Then check for attach type. This is done outside of the
  988. # "case $prev in" to avoid writing the whole list of attach
  989. # types again as pattern to match (where we cannot reuse
  990. # our variable).
  991. elif [[ $BPFTOOL_CGROUP_ATTACH_TYPES =~ $prev ]]; then
  992. COMPREPLY=( $( compgen -W "$PROG_TYPE" -- \
  993. "$cur" ) )
  994. return 0
  995. fi
  996. # case/esac for the other cases
  997. case $prev in
  998. id)
  999. _bpftool_get_prog_ids
  1000. return 0
  1001. ;;
  1002. *)
  1003. if ! _bpftool_search_list "$BPFTOOL_CGROUP_ATTACH_TYPES"; then
  1004. COMPREPLY=( $( compgen -W \
  1005. "$BPFTOOL_CGROUP_ATTACH_TYPES" -- "$cur" ) )
  1006. elif [[ "$command" == "attach" ]]; then
  1007. # We have an attach type on the command line,
  1008. # but it is not the previous word, or
  1009. # "id|pinned|tag|name" (we already checked for
  1010. # that). This should only leave the case when
  1011. # we need attach flags for "attach" commamnd.
  1012. _bpftool_one_of_list "$ATTACH_FLAGS"
  1013. fi
  1014. return 0
  1015. ;;
  1016. esac
  1017. ;;
  1018. *)
  1019. [[ $prev == $object ]] && \
  1020. COMPREPLY=( $( compgen -W 'help attach detach \
  1021. show list tree' -- "$cur" ) )
  1022. ;;
  1023. esac
  1024. ;;
  1025. perf)
  1026. case $command in
  1027. *)
  1028. [[ $prev == $object ]] && \
  1029. COMPREPLY=( $( compgen -W 'help \
  1030. show list' -- "$cur" ) )
  1031. ;;
  1032. esac
  1033. ;;
  1034. net)
  1035. local ATTACH_TYPES='xdp xdpgeneric xdpdrv xdpoffload tcx_ingress tcx_egress'
  1036. case $command in
  1037. show|list)
  1038. [[ $prev != "$command" ]] && return 0
  1039. COMPREPLY=( $( compgen -W 'dev' -- "$cur" ) )
  1040. return 0
  1041. ;;
  1042. attach)
  1043. case $cword in
  1044. 3)
  1045. COMPREPLY=( $( compgen -W "$ATTACH_TYPES" -- "$cur" ) )
  1046. return 0
  1047. ;;
  1048. 4)
  1049. COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
  1050. return 0
  1051. ;;
  1052. 5)
  1053. case $prev in
  1054. id)
  1055. _bpftool_get_prog_ids
  1056. ;;
  1057. name)
  1058. _bpftool_get_prog_names
  1059. ;;
  1060. pinned)
  1061. _filedir
  1062. ;;
  1063. esac
  1064. return 0
  1065. ;;
  1066. 6)
  1067. COMPREPLY=( $( compgen -W 'dev' -- "$cur" ) )
  1068. return 0
  1069. ;;
  1070. 8)
  1071. _bpftool_once_attr 'overwrite'
  1072. return 0
  1073. ;;
  1074. esac
  1075. ;;
  1076. detach)
  1077. case $cword in
  1078. 3)
  1079. COMPREPLY=( $( compgen -W "$ATTACH_TYPES" -- "$cur" ) )
  1080. return 0
  1081. ;;
  1082. 4)
  1083. COMPREPLY=( $( compgen -W 'dev' -- "$cur" ) )
  1084. return 0
  1085. ;;
  1086. esac
  1087. ;;
  1088. *)
  1089. [[ $prev == $object ]] && \
  1090. COMPREPLY=( $( compgen -W 'help \
  1091. show list attach detach' -- "$cur" ) )
  1092. ;;
  1093. esac
  1094. ;;
  1095. feature)
  1096. case $command in
  1097. probe)
  1098. [[ $prev == "prefix" ]] && return 0
  1099. if _bpftool_search_list 'macros'; then
  1100. _bpftool_once_attr 'prefix'
  1101. else
  1102. COMPREPLY+=( $( compgen -W 'macros' -- "$cur" ) )
  1103. fi
  1104. _bpftool_one_of_list 'kernel dev'
  1105. _bpftool_once_attr 'full unprivileged'
  1106. return 0
  1107. ;;
  1108. list_builtins)
  1109. [[ $prev != "$command" ]] && return 0
  1110. COMPREPLY=( $( compgen -W 'prog_types map_types \
  1111. attach_types link_types helpers' -- "$cur" ) )
  1112. ;;
  1113. *)
  1114. [[ $prev == $object ]] && \
  1115. COMPREPLY=( $( compgen -W 'help list_builtins probe' -- "$cur" ) )
  1116. ;;
  1117. esac
  1118. ;;
  1119. link)
  1120. case $command in
  1121. show|list|pin|detach)
  1122. case $prev in
  1123. id)
  1124. _bpftool_get_link_ids
  1125. return 0
  1126. ;;
  1127. esac
  1128. ;;
  1129. esac
  1130. local LINK_TYPE='id pinned'
  1131. case $command in
  1132. show|list)
  1133. [[ $prev != "$command" ]] && return 0
  1134. COMPREPLY=( $( compgen -W "$LINK_TYPE" -- "$cur" ) )
  1135. return 0
  1136. ;;
  1137. pin|detach)
  1138. if [[ $prev == "$command" ]]; then
  1139. COMPREPLY=( $( compgen -W "$LINK_TYPE" -- "$cur" ) )
  1140. elif [[ $pprev == "$command" ]]; then
  1141. _filedir
  1142. fi
  1143. return 0
  1144. ;;
  1145. *)
  1146. [[ $prev == $object ]] && \
  1147. COMPREPLY=( $( compgen -W 'help pin detach show list' -- "$cur" ) )
  1148. ;;
  1149. esac
  1150. ;;
  1151. esac
  1152. } &&
  1153. complete -F _bpftool bpftool
  1154. # ex: ts=4 sw=4 et filetype=sh