2017-10-26 14:16:05 -07:00
|
|
|
# bpftool(8) bash completion -*- shell-script -*-
|
|
|
|
|
#
|
2018-12-12 19:59:25 -08:00
|
|
|
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
2018-05-03 18:37:16 -07:00
|
|
|
# Copyright (C) 2017-2018 Netronome Systems, Inc.
|
2017-10-26 14:16:05 -07:00
|
|
|
#
|
|
|
|
|
# Author: Quentin Monnet <quentin.monnet@netronome.com>
|
|
|
|
|
|
|
|
|
|
# Takes a list of words in argument; each one of them is added to COMPREPLY if
|
|
|
|
|
# it is not already present on the command line. Returns no value.
|
|
|
|
|
_bpftool_once_attr()
|
|
|
|
|
{
|
|
|
|
|
local w idx found
|
|
|
|
|
for w in $*; do
|
|
|
|
|
found=0
|
|
|
|
|
for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
|
|
|
|
|
if [[ $w == ${words[idx]} ]]; then
|
|
|
|
|
found=1
|
|
|
|
|
break
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
[[ $found -eq 0 ]] && \
|
|
|
|
|
COMPREPLY+=( $( compgen -W "$w" -- "$cur" ) )
|
|
|
|
|
done
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-07 20:27:17 -08:00
|
|
|
# Takes a list of words as argument; if any of those words is present on the
|
|
|
|
|
# command line, return 0. Otherwise, return 1.
|
|
|
|
|
_bpftool_search_list()
|
2017-10-26 14:16:05 -07:00
|
|
|
{
|
|
|
|
|
local w idx
|
|
|
|
|
for w in $*; do
|
|
|
|
|
for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
|
2018-02-07 20:27:17 -08:00
|
|
|
[[ $w == ${words[idx]} ]] && return 0
|
2017-10-26 14:16:05 -07:00
|
|
|
done
|
|
|
|
|
done
|
2018-02-07 20:27:17 -08:00
|
|
|
return 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Takes a list of words in argument; adds them all to COMPREPLY if none of them
|
|
|
|
|
# is already present on the command line. Returns no value.
|
|
|
|
|
_bpftool_one_of_list()
|
|
|
|
|
{
|
|
|
|
|
_bpftool_search_list $* && return 1
|
2017-10-26 14:16:05 -07:00
|
|
|
COMPREPLY+=( $( compgen -W "$*" -- "$cur" ) )
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_bpftool_get_map_ids()
|
|
|
|
|
{
|
|
|
|
|
COMPREPLY+=( $( compgen -W "$( bpftool -jp map 2>&1 | \
|
|
|
|
|
command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) )
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-16 11:10:05 -08:00
|
|
|
# Takes map type and adds matching map ids to the list of suggestions.
|
|
|
|
|
_bpftool_get_map_ids_for_type()
|
2018-05-03 18:37:16 -07:00
|
|
|
{
|
2019-01-16 11:10:05 -08:00
|
|
|
local type="$1"
|
2018-05-03 18:37:16 -07:00
|
|
|
COMPREPLY+=( $( compgen -W "$( bpftool -jp map 2>&1 | \
|
2019-01-16 11:10:05 -08:00
|
|
|
command grep -C2 "$type" | \
|
2018-05-03 18:37:16 -07:00
|
|
|
command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) )
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-13 20:10:37 +01:00
|
|
|
_bpftool_get_map_names()
|
|
|
|
|
{
|
|
|
|
|
COMPREPLY+=( $( compgen -W "$( bpftool -jp map 2>&1 | \
|
|
|
|
|
command sed -n 's/.*"name": \(.*\),$/\1/p' )" -- "$cur" ) )
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Takes map type and adds matching map names to the list of suggestions.
|
|
|
|
|
_bpftool_get_map_names_for_type()
|
|
|
|
|
{
|
|
|
|
|
local type="$1"
|
|
|
|
|
COMPREPLY+=( $( compgen -W "$( bpftool -jp map 2>&1 | \
|
|
|
|
|
command grep -C2 "$type" | \
|
|
|
|
|
command sed -n 's/.*"name": \(.*\),$/\1/p' )" -- "$cur" ) )
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-26 14:16:05 -07:00
|
|
|
_bpftool_get_prog_ids()
|
|
|
|
|
{
|
|
|
|
|
COMPREPLY+=( $( compgen -W "$( bpftool -jp prog 2>&1 | \
|
|
|
|
|
command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) )
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_bpftool_get_prog_tags()
|
|
|
|
|
{
|
|
|
|
|
COMPREPLY+=( $( compgen -W "$( bpftool -jp prog 2>&1 | \
|
|
|
|
|
command sed -n 's/.*"tag": "\(.*\)",$/\1/p' )" -- "$cur" ) )
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-13 20:10:17 +01:00
|
|
|
_bpftool_get_prog_names()
|
|
|
|
|
{
|
|
|
|
|
COMPREPLY+=( $( compgen -W "$( bpftool -jp prog 2>&1 | \
|
|
|
|
|
command sed -n 's/.*"name": "\(.*\)",$/\1/p' )" -- "$cur" ) )
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-25 17:01:01 -07:00
|
|
|
_bpftool_get_btf_ids()
|
|
|
|
|
{
|
2019-08-20 10:31:54 +01:00
|
|
|
COMPREPLY+=( $( compgen -W "$( bpftool -jp btf 2>&1 | \
|
|
|
|
|
command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) )
|
2019-05-25 17:01:01 -07:00
|
|
|
}
|
|
|
|
|
|
2020-04-28 17:16:14 -07:00
|
|
|
_bpftool_get_link_ids()
|
|
|
|
|
{
|
|
|
|
|
COMPREPLY+=( $( compgen -W "$( bpftool -jp link 2>&1 | \
|
|
|
|
|
command sed -n 's/.*"id": \(.*\),$/\1/p' )" -- "$cur" ) )
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-10 14:43:07 -07:00
|
|
|
_bpftool_get_obj_map_names()
|
|
|
|
|
{
|
|
|
|
|
local obj
|
|
|
|
|
|
|
|
|
|
obj=$1
|
|
|
|
|
|
|
|
|
|
maps=$(objdump -j maps -t $obj 2>/dev/null | \
|
|
|
|
|
command awk '/g . maps/ {print $NF}')
|
|
|
|
|
|
|
|
|
|
COMPREPLY+=( $( compgen -W "$maps" -- "$cur" ) )
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_bpftool_get_obj_map_idxs()
|
|
|
|
|
{
|
|
|
|
|
local obj
|
|
|
|
|
|
|
|
|
|
obj=$1
|
|
|
|
|
|
|
|
|
|
nmaps=$(objdump -j maps -t $obj 2>/dev/null | grep -c 'g . maps')
|
|
|
|
|
|
|
|
|
|
COMPREPLY+=( $( compgen -W "$(seq 0 $((nmaps - 1)))" -- "$cur" ) )
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-10 14:42:58 -07:00
|
|
|
_sysfs_get_netdevs()
|
|
|
|
|
{
|
|
|
|
|
COMPREPLY+=( $( compgen -W "$( ls /sys/class/net 2>/dev/null )" -- \
|
|
|
|
|
"$cur" ) )
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-16 11:10:05 -08:00
|
|
|
# Retrieve type of the map that we are operating on.
|
|
|
|
|
_bpftool_map_guess_map_type()
|
2017-10-26 14:16:05 -07:00
|
|
|
{
|
|
|
|
|
local keyword ref
|
|
|
|
|
for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
|
2019-01-16 11:10:05 -08:00
|
|
|
case "${words[$((idx-2))]}" in
|
|
|
|
|
lookup|update)
|
|
|
|
|
keyword=${words[$((idx-1))]}
|
|
|
|
|
ref=${words[$((idx))]}
|
|
|
|
|
;;
|
|
|
|
|
push)
|
|
|
|
|
printf "stack"
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
enqueue)
|
|
|
|
|
printf "queue"
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
esac
|
2017-10-26 14:16:05 -07:00
|
|
|
done
|
|
|
|
|
[[ -z $ref ]] && return 0
|
|
|
|
|
|
|
|
|
|
local type
|
|
|
|
|
type=$(bpftool -jp map show $keyword $ref | \
|
|
|
|
|
command sed -n 's/.*"type": "\(.*\)",$/\1/p')
|
2018-10-20 23:01:50 +01:00
|
|
|
[[ -n $type ]] && printf $type
|
2017-10-26 14:16:05 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_bpftool_map_update_get_id()
|
|
|
|
|
{
|
2019-01-16 11:10:05 -08:00
|
|
|
local command="$1"
|
|
|
|
|
|
2017-10-26 14:16:05 -07:00
|
|
|
# Is it the map to update, or a map to insert into the map to update?
|
|
|
|
|
# Search for "value" keyword.
|
|
|
|
|
local idx value
|
|
|
|
|
for (( idx=7; idx < ${#words[@]}-1; idx++ )); do
|
|
|
|
|
if [[ ${words[idx]} == "value" ]]; then
|
|
|
|
|
value=1
|
|
|
|
|
break
|
|
|
|
|
fi
|
|
|
|
|
done
|
2019-01-16 11:10:05 -08:00
|
|
|
if [[ $value -eq 0 ]]; then
|
|
|
|
|
case "$command" in
|
|
|
|
|
push)
|
|
|
|
|
_bpftool_get_map_ids_for_type stack
|
|
|
|
|
;;
|
|
|
|
|
enqueue)
|
|
|
|
|
_bpftool_get_map_ids_for_type queue
|
|
|
|
|
;;
|
|
|
|
|
*)
|
|
|
|
|
_bpftool_get_map_ids
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
2017-10-26 14:16:05 -07:00
|
|
|
|
|
|
|
|
# Id to complete is for a value. It can be either prog id or map id. This
|
|
|
|
|
# depends on the type of the map to update.
|
2019-01-16 11:10:05 -08:00
|
|
|
local type=$(_bpftool_map_guess_map_type)
|
2017-10-26 14:16:05 -07:00
|
|
|
case $type in
|
|
|
|
|
array_of_maps|hash_of_maps)
|
|
|
|
|
_bpftool_get_map_ids
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
prog_array)
|
|
|
|
|
_bpftool_get_prog_ids
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
*)
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-13 20:10:37 +01:00
|
|
|
_bpftool_map_update_get_name()
|
|
|
|
|
{
|
|
|
|
|
local command="$1"
|
|
|
|
|
|
|
|
|
|
# Is it the map to update, or a map to insert into the map to update?
|
|
|
|
|
# Search for "value" keyword.
|
|
|
|
|
local idx value
|
|
|
|
|
for (( idx=7; idx < ${#words[@]}-1; idx++ )); do
|
|
|
|
|
if [[ ${words[idx]} == "value" ]]; then
|
|
|
|
|
value=1
|
|
|
|
|
break
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
if [[ $value -eq 0 ]]; then
|
|
|
|
|
case "$command" in
|
|
|
|
|
push)
|
|
|
|
|
_bpftool_get_map_names_for_type stack
|
|
|
|
|
;;
|
|
|
|
|
enqueue)
|
|
|
|
|
_bpftool_get_map_names_for_type queue
|
|
|
|
|
;;
|
|
|
|
|
*)
|
|
|
|
|
_bpftool_get_map_names
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# Name to complete is for a value. It can be either prog name or map name. This
|
|
|
|
|
# depends on the type of the map to update.
|
|
|
|
|
local type=$(_bpftool_map_guess_map_type)
|
|
|
|
|
case $type in
|
|
|
|
|
array_of_maps|hash_of_maps)
|
|
|
|
|
_bpftool_get_map_names
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
prog_array)
|
|
|
|
|
_bpftool_get_prog_names
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
*)
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-26 14:16:05 -07:00
|
|
|
_bpftool()
|
|
|
|
|
{
|
|
|
|
|
local cur prev words objword
|
|
|
|
|
_init_completion || return
|
|
|
|
|
|
2018-06-28 14:41:42 -07:00
|
|
|
# Deal with options
|
|
|
|
|
if [[ ${words[cword]} == -* ]]; then
|
2021-07-30 22:54:34 +01:00
|
|
|
local c='--version --json --pretty --bpffs --mapcompat --debug \
|
2021-11-10 11:23:24 -08:00
|
|
|
--use-loader --base-btf --legacy'
|
2018-06-28 14:41:42 -07:00
|
|
|
COMPREPLY=( $( compgen -W "$c" -- "$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
|
2017-10-26 14:16:05 -07:00
|
|
|
# Deal with simplest keywords
|
|
|
|
|
case $prev in
|
bpf: libbpf: bpftool: Print bpf_line_info during prog dump
This patch adds print bpf_line_info function in 'prog dump jitted'
and 'prog dump xlated':
[root@arch-fb-vm1 bpf]# ~/devshare/fb-kernel/linux/tools/bpf/bpftool/bpftool prog dump jited pinned /sys/fs/bpf/test_btf_haskv
[...]
int test_long_fname_2(struct dummy_tracepoint_args * arg):
bpf_prog_44a040bf25481309_test_long_fname_2:
; static int test_long_fname_2(struct dummy_tracepoint_args *arg)
0: push %rbp
1: mov %rsp,%rbp
4: sub $0x30,%rsp
b: sub $0x28,%rbp
f: mov %rbx,0x0(%rbp)
13: mov %r13,0x8(%rbp)
17: mov %r14,0x10(%rbp)
1b: mov %r15,0x18(%rbp)
1f: xor %eax,%eax
21: mov %rax,0x20(%rbp)
25: xor %esi,%esi
; int key = 0;
27: mov %esi,-0x4(%rbp)
; if (!arg->sock)
2a: mov 0x8(%rdi),%rdi
; if (!arg->sock)
2e: cmp $0x0,%rdi
32: je 0x0000000000000070
34: mov %rbp,%rsi
; counts = bpf_map_lookup_elem(&btf_map, &key);
37: add $0xfffffffffffffffc,%rsi
3b: movabs $0xffff8881139d7480,%rdi
45: add $0x110,%rdi
4c: mov 0x0(%rsi),%eax
4f: cmp $0x4,%rax
53: jae 0x000000000000005e
55: shl $0x3,%rax
59: add %rdi,%rax
5c: jmp 0x0000000000000060
5e: xor %eax,%eax
; if (!counts)
60: cmp $0x0,%rax
64: je 0x0000000000000070
; counts->v6++;
66: mov 0x4(%rax),%edi
69: add $0x1,%rdi
6d: mov %edi,0x4(%rax)
70: mov 0x0(%rbp),%rbx
74: mov 0x8(%rbp),%r13
78: mov 0x10(%rbp),%r14
7c: mov 0x18(%rbp),%r15
80: add $0x28,%rbp
84: leaveq
85: retq
[...]
With linum:
[root@arch-fb-vm1 bpf]# ~/devshare/fb-kernel/linux/tools/bpf/bpftool/bpftool prog dump jited pinned /sys/fs/bpf/test_btf_haskv linum
int _dummy_tracepoint(struct dummy_tracepoint_args * arg):
bpf_prog_b07ccb89267cf242__dummy_tracepoint:
; return test_long_fname_1(arg); [file:/data/users/kafai/fb-kernel/linux/tools/testing/selftests/bpf/test_btf_haskv.c line_num:54 line_col:9]
0: push %rbp
1: mov %rsp,%rbp
4: sub $0x28,%rsp
b: sub $0x28,%rbp
f: mov %rbx,0x0(%rbp)
13: mov %r13,0x8(%rbp)
17: mov %r14,0x10(%rbp)
1b: mov %r15,0x18(%rbp)
1f: xor %eax,%eax
21: mov %rax,0x20(%rbp)
25: callq 0x000000000000851e
; return test_long_fname_1(arg); [file:/data/users/kafai/fb-kernel/linux/tools/testing/selftests/bpf/test_btf_haskv.c line_num:54 line_col:2]
2a: xor %eax,%eax
2c: mov 0x0(%rbp),%rbx
30: mov 0x8(%rbp),%r13
34: mov 0x10(%rbp),%r14
38: mov 0x18(%rbp),%r15
3c: add $0x28,%rbp
40: leaveq
41: retq
[...]
Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Acked-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2018-12-07 16:42:32 -08:00
|
|
|
help|hex|opcodes|visual|linum)
|
2017-10-26 14:16:05 -07:00
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
tag)
|
|
|
|
|
_bpftool_get_prog_tags
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
2019-08-13 11:46:20 +09:00
|
|
|
dev)
|
|
|
|
|
_sysfs_get_netdevs
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
2021-07-30 22:54:34 +01:00
|
|
|
file|pinned|-B|--base-btf)
|
2017-10-26 14:16:05 -07:00
|
|
|
_filedir
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
batch)
|
|
|
|
|
COMPREPLY=( $( compgen -W 'file' -- "$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
|
2018-06-28 14:41:42 -07:00
|
|
|
# Remove all options so completions don't have to deal with them.
|
|
|
|
|
local i
|
|
|
|
|
for (( i=1; i < ${#words[@]}; )); do
|
2021-07-30 22:54:34 +01:00
|
|
|
if [[ ${words[i]::1} == - ]] &&
|
|
|
|
|
[[ ${words[i]} != "-B" ]] && [[ ${words[i]} != "--base-btf" ]]; then
|
2018-06-28 14:41:42 -07:00
|
|
|
words=( "${words[@]:0:i}" "${words[@]:i+1}" )
|
|
|
|
|
[[ $i -le $cword ]] && cword=$(( cword - 1 ))
|
|
|
|
|
else
|
|
|
|
|
i=$(( ++i ))
|
|
|
|
|
fi
|
2017-10-26 14:16:05 -07:00
|
|
|
done
|
2018-06-28 14:41:42 -07:00
|
|
|
cur=${words[cword]}
|
|
|
|
|
prev=${words[cword - 1]}
|
2019-04-25 15:30:10 -07:00
|
|
|
pprev=${words[cword - 2]}
|
2017-10-26 14:16:05 -07:00
|
|
|
|
2018-06-28 14:41:42 -07:00
|
|
|
local object=${words[1]} command=${words[2]}
|
|
|
|
|
|
|
|
|
|
if [[ -z $object || $cword -eq 1 ]]; then
|
2017-10-26 14:16:05 -07:00
|
|
|
case $cur in
|
|
|
|
|
*)
|
|
|
|
|
COMPREPLY=( $( compgen -W "$( bpftool help 2>&1 | \
|
|
|
|
|
command sed \
|
|
|
|
|
-e '/OBJECT := /!d' \
|
|
|
|
|
-e 's/.*{//' \
|
|
|
|
|
-e 's/}.*//' \
|
|
|
|
|
-e 's/|//g' )" -- "$cur" ) )
|
|
|
|
|
COMPREPLY+=( $( compgen -W 'batch help' -- "$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
[[ $command == help ]] && return 0
|
|
|
|
|
|
|
|
|
|
# Completion depends on object and command in use
|
|
|
|
|
case $object in
|
|
|
|
|
prog)
|
2019-12-13 20:10:37 +01:00
|
|
|
# Complete id and name, only for subcommands that use prog (but no
|
|
|
|
|
# map) ids/names.
|
2018-11-30 16:25:45 +00:00
|
|
|
case $command in
|
|
|
|
|
show|list|dump|pin)
|
|
|
|
|
case $prev in
|
|
|
|
|
id)
|
|
|
|
|
_bpftool_get_prog_ids
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
2019-12-13 20:10:37 +01:00
|
|
|
name)
|
|
|
|
|
_bpftool_get_prog_names
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
2018-11-30 16:25:45 +00:00
|
|
|
esac
|
|
|
|
|
;;
|
|
|
|
|
esac
|
2017-10-26 14:16:05 -07:00
|
|
|
|
2019-12-13 20:10:17 +01:00
|
|
|
local PROG_TYPE='id pinned tag name'
|
2019-12-13 20:10:37 +01:00
|
|
|
local MAP_TYPE='id pinned name'
|
2021-07-30 22:54:35 +01:00
|
|
|
local METRIC_TYPE='cycles instructions l1d_loads llc_misses \
|
|
|
|
|
itlb_misses dtlb_misses'
|
2017-10-26 14:16:05 -07:00
|
|
|
case $command in
|
2018-01-02 14:48:36 -08:00
|
|
|
show|list)
|
2017-10-26 14:16:05 -07:00
|
|
|
[[ $prev != "$command" ]] && return 0
|
|
|
|
|
COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
dump)
|
|
|
|
|
case $prev in
|
|
|
|
|
$command)
|
|
|
|
|
COMPREPLY+=( $( compgen -W "xlated jited" -- \
|
|
|
|
|
"$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
xlated|jited)
|
|
|
|
|
COMPREPLY=( $( compgen -W "$PROG_TYPE" -- \
|
|
|
|
|
"$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
2019-04-25 15:30:11 -07:00
|
|
|
*)
|
|
|
|
|
_bpftool_once_attr 'file'
|
|
|
|
|
if _bpftool_search_list 'xlated'; then
|
|
|
|
|
COMPREPLY+=( $( compgen -W 'opcodes visual linum' -- \
|
|
|
|
|
"$cur" ) )
|
|
|
|
|
else
|
|
|
|
|
COMPREPLY+=( $( compgen -W 'opcodes linum' -- \
|
|
|
|
|
"$cur" ) )
|
|
|
|
|
fi
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
2017-10-26 14:16:05 -07:00
|
|
|
esac
|
|
|
|
|
;;
|
|
|
|
|
pin)
|
|
|
|
|
if [[ $prev == "$command" ]]; then
|
|
|
|
|
COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
|
|
|
|
|
else
|
|
|
|
|
_filedir
|
|
|
|
|
fi
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
2018-10-15 11:19:50 -07:00
|
|
|
attach|detach)
|
2018-11-30 16:25:45 +00:00
|
|
|
case $cword in
|
|
|
|
|
3)
|
|
|
|
|
COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
4)
|
|
|
|
|
case $prev in
|
|
|
|
|
id)
|
|
|
|
|
_bpftool_get_prog_ids
|
|
|
|
|
;;
|
2019-12-13 20:10:37 +01:00
|
|
|
name)
|
2020-03-09 10:32:18 -07:00
|
|
|
_bpftool_get_prog_names
|
2019-12-13 20:10:37 +01:00
|
|
|
;;
|
2018-11-30 16:25:45 +00:00
|
|
|
pinned)
|
|
|
|
|
_filedir
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
5)
|
bpftool: Use libbpf_bpf_attach_type_str
This change switches bpftool over to using the recently introduced
libbpf_bpf_attach_type_str function instead of maintaining its own
string representation for the bpf_attach_type enum.
Note that contrary to other enum types, the variant names that bpftool
maps bpf_attach_type to do not adhere a simple to follow rule. With
bpf_prog_type, for example, the textual representation can easily be
inferred by stripping the BPF_PROG_TYPE_ prefix and lowercasing the
remaining string. bpf_attach_type violates this rule for various
variants.
We decided to fix up this deficiency with this change, meaning that
bpftool uses the same textual representations as libbpf. Supporting
tests, completion scripts, and man pages have been adjusted accordingly.
However, we did add support for accepting (the now undocumented)
original attach type names when they are provided by users.
For the test (test_bpftool_synctypes.py), I have removed the enum
representation checks, because we no longer mirror the various enum
variant names in bpftool source code. For the man page, help text, and
completion script checks we are now using enum definitions from
uapi/linux/bpf.h as the source of truth directly.
Signed-off-by: Daniel Müller <deso@posteo.net>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Quentin Monnet <quentin@isovalent.com>
Link: https://lore.kernel.org/bpf/20220523230428.3077108-10-deso@posteo.net
2022-05-23 23:04:25 +00:00
|
|
|
local BPFTOOL_PROG_ATTACH_TYPES='sk_msg_verdict \
|
|
|
|
|
sk_skb_verdict sk_skb_stream_verdict sk_skb_stream_parser \
|
2021-07-30 22:54:31 +01:00
|
|
|
flow_dissector'
|
2021-07-30 22:54:29 +01:00
|
|
|
COMPREPLY=( $( compgen -W "$BPFTOOL_PROG_ATTACH_TYPES" -- "$cur" ) )
|
2018-11-30 16:25:45 +00:00
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
6)
|
|
|
|
|
COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
7)
|
|
|
|
|
case $prev in
|
|
|
|
|
id)
|
|
|
|
|
_bpftool_get_map_ids
|
|
|
|
|
;;
|
2019-12-13 20:10:37 +01:00
|
|
|
name)
|
|
|
|
|
_bpftool_get_map_names
|
|
|
|
|
;;
|
2018-11-30 16:25:45 +00:00
|
|
|
pinned)
|
|
|
|
|
_filedir
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
esac
|
2018-10-15 11:19:50 -07:00
|
|
|
;;
|
2018-11-09 08:21:44 -08:00
|
|
|
load|loadall)
|
2018-07-10 14:43:07 -07:00
|
|
|
local obj
|
|
|
|
|
|
2019-07-08 14:05:46 +01:00
|
|
|
# Propose "load/loadall" to complete "bpftool prog load",
|
|
|
|
|
# or bash tries to complete "load" as a filename below.
|
|
|
|
|
if [[ ${#words[@]} -eq 3 ]]; then
|
|
|
|
|
COMPREPLY=( $( compgen -W "load loadall" -- "$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
|
2018-07-10 14:42:58 -07:00
|
|
|
if [[ ${#words[@]} -lt 6 ]]; then
|
|
|
|
|
_filedir
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
|
2018-07-10 14:43:07 -07:00
|
|
|
obj=${words[3]}
|
|
|
|
|
|
|
|
|
|
if [[ ${words[-4]} == "map" ]]; then
|
|
|
|
|
COMPREPLY=( $( compgen -W "id pinned" -- "$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
if [[ ${words[-3]} == "map" ]]; then
|
|
|
|
|
if [[ ${words[-2]} == "idx" ]]; then
|
|
|
|
|
_bpftool_get_obj_map_idxs $obj
|
|
|
|
|
elif [[ ${words[-2]} == "name" ]]; then
|
|
|
|
|
_bpftool_get_obj_map_names $obj
|
|
|
|
|
fi
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
if [[ ${words[-2]} == "map" ]]; then
|
|
|
|
|
COMPREPLY=( $( compgen -W "idx name" -- "$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
|
2018-07-10 14:42:58 -07:00
|
|
|
case $prev in
|
2018-07-10 14:43:00 -07:00
|
|
|
type)
|
2021-07-30 22:54:29 +01:00
|
|
|
local BPFTOOL_PROG_LOAD_TYPES='socket kprobe \
|
2018-11-09 08:21:46 -08:00
|
|
|
kretprobe classifier flow_dissector \
|
|
|
|
|
action tracepoint raw_tracepoint \
|
|
|
|
|
xdp perf_event cgroup/skb cgroup/sock \
|
|
|
|
|
cgroup/dev lwt_in lwt_out lwt_xmit \
|
|
|
|
|
lwt_seg6local sockops sk_skb sk_msg \
|
|
|
|
|
lirc_mode2 cgroup/bind4 cgroup/bind6 \
|
|
|
|
|
cgroup/connect4 cgroup/connect6 \
|
2020-05-19 00:45:47 +02:00
|
|
|
cgroup/getpeername4 cgroup/getpeername6 \
|
|
|
|
|
cgroup/getsockname4 cgroup/getsockname6 \
|
2018-11-09 08:21:46 -08:00
|
|
|
cgroup/sendmsg4 cgroup/sendmsg6 \
|
2019-06-07 01:49:00 +02:00
|
|
|
cgroup/recvmsg4 cgroup/recvmsg6 \
|
2019-04-16 13:13:47 -07:00
|
|
|
cgroup/post_bind4 cgroup/post_bind6 \
|
2019-06-27 13:38:55 -07:00
|
|
|
cgroup/sysctl cgroup/getsockopt \
|
2021-05-25 09:41:39 +08:00
|
|
|
cgroup/setsockopt cgroup/sock_release struct_ops \
|
2021-07-30 22:54:29 +01:00
|
|
|
fentry fexit freplace sk_lookup'
|
|
|
|
|
COMPREPLY=( $( compgen -W "$BPFTOOL_PROG_LOAD_TYPES" -- "$cur" ) )
|
2018-07-10 14:43:00 -07:00
|
|
|
return 0
|
|
|
|
|
;;
|
2018-07-10 14:43:07 -07:00
|
|
|
id)
|
|
|
|
|
_bpftool_get_map_ids
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
2019-12-13 20:10:37 +01:00
|
|
|
name)
|
|
|
|
|
_bpftool_get_map_names
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
2018-11-09 08:21:45 -08:00
|
|
|
pinned|pinmaps)
|
2018-07-10 14:43:07 -07:00
|
|
|
_filedir
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
2018-07-10 14:42:58 -07:00
|
|
|
*)
|
2018-07-10 14:43:07 -07:00
|
|
|
COMPREPLY=( $( compgen -W "map" -- "$cur" ) )
|
2018-07-10 14:43:00 -07:00
|
|
|
_bpftool_once_attr 'type'
|
2018-07-10 14:42:58 -07:00
|
|
|
_bpftool_once_attr 'dev'
|
2018-11-09 08:21:45 -08:00
|
|
|
_bpftool_once_attr 'pinmaps'
|
2018-07-10 14:42:58 -07:00
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
esac
|
2018-02-07 20:27:16 -08:00
|
|
|
;;
|
2018-12-05 10:28:24 +00:00
|
|
|
tracelog)
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
2020-03-09 10:32:17 -07:00
|
|
|
profile)
|
|
|
|
|
case $cword in
|
|
|
|
|
3)
|
|
|
|
|
COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
4)
|
|
|
|
|
case $prev in
|
|
|
|
|
id)
|
|
|
|
|
_bpftool_get_prog_ids
|
|
|
|
|
;;
|
|
|
|
|
name)
|
|
|
|
|
_bpftool_get_prog_names
|
|
|
|
|
;;
|
|
|
|
|
pinned)
|
|
|
|
|
_filedir
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
5)
|
|
|
|
|
COMPREPLY=( $( compgen -W "$METRIC_TYPE duration" -- "$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
6)
|
|
|
|
|
case $prev in
|
|
|
|
|
duration)
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
*)
|
|
|
|
|
COMPREPLY=( $( compgen -W "$METRIC_TYPE" -- "$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
*)
|
|
|
|
|
COMPREPLY=( $( compgen -W "$METRIC_TYPE" -- "$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
;;
|
2019-07-05 18:54:33 +01:00
|
|
|
run)
|
2020-03-12 18:46:08 +00:00
|
|
|
if [[ ${#words[@]} -eq 4 ]]; then
|
|
|
|
|
COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
|
2019-07-05 18:54:33 +01:00
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
case $prev in
|
|
|
|
|
id)
|
|
|
|
|
_bpftool_get_prog_ids
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
2020-03-12 18:46:08 +00:00
|
|
|
name)
|
|
|
|
|
_bpftool_get_prog_names
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
2019-07-05 18:54:33 +01:00
|
|
|
data_in|data_out|ctx_in|ctx_out)
|
|
|
|
|
_filedir
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
repeat|data_size_out|ctx_size_out)
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
*)
|
|
|
|
|
_bpftool_once_attr 'data_in data_out data_size_out \
|
|
|
|
|
ctx_in ctx_out ctx_size_out repeat'
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
;;
|
2017-10-26 14:16:05 -07:00
|
|
|
*)
|
|
|
|
|
[[ $prev == $object ]] && \
|
2019-07-05 18:54:33 +01:00
|
|
|
COMPREPLY=( $( compgen -W 'dump help pin attach detach \
|
2020-03-09 10:32:17 -07:00
|
|
|
load loadall show list tracelog run profile' -- "$cur" ) )
|
2017-10-26 14:16:05 -07:00
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
;;
|
bpftool: Add struct_ops support
This patch adds struct_ops support to the bpftool.
To recap a bit on the recent bpf_struct_ops feature on the kernel side:
It currently supports "struct tcp_congestion_ops" to be implemented
in bpf. At a high level, bpf_struct_ops is struct_ops map populated
with a number of bpf progs. bpf_struct_ops currently supports the
"struct tcp_congestion_ops". However, the bpf_struct_ops design is
generic enough that other kernel struct ops can be supported in
the future.
Although struct_ops is map+progs at a high lever, there are differences
in details. For example,
1) After registering a struct_ops, the struct_ops is held by the kernel
subsystem (e.g. tcp-cc). Thus, there is no need to pin a
struct_ops map or its progs in order to keep them around.
2) To iterate all struct_ops in a system, it iterates all maps
in type BPF_MAP_TYPE_STRUCT_OPS. BPF_MAP_TYPE_STRUCT_OPS is
the current usual filter. In the future, it may need to
filter by other struct_ops specific properties. e.g. filter by
tcp_congestion_ops or other kernel subsystem ops in the future.
3) struct_ops requires the running kernel having BTF info. That allows
more flexibility in handling other kernel structs. e.g. it can
always dump the latest bpf_map_info.
4) Also, "struct_ops" command is not intended to repeat all features
already provided by "map" or "prog". For example, if there really
is a need to pin the struct_ops map, the user can use the "map" cmd
to do that.
While the first attempt was to reuse parts from map/prog.c, it ended up
not a lot to share. The only obvious item is the map_parse_fds() but
that still requires modifications to accommodate struct_ops map specific
filtering (for the immediate and the future needs). Together with the
earlier mentioned differences, it is better to part away from map/prog.c.
The initial set of subcmds are, register, unregister, show, and dump.
For register, it registers all struct_ops maps that can be found in an
obj file. Option can be added in the future to specify a particular
struct_ops map. Also, the common bpf_tcp_cc is stateless (e.g.
bpf_cubic.c and bpf_dctcp.c). The "reuse map" feature is not
implemented in this patch and it can be considered later also.
For other subcmds, please see the man doc for details.
A sample output of dump:
[root@arch-fb-vm1 bpf]# bpftool struct_ops dump name cubic
[{
"bpf_map_info": {
"type": 26,
"id": 64,
"key_size": 4,
"value_size": 256,
"max_entries": 1,
"map_flags": 0,
"name": "cubic",
"ifindex": 0,
"btf_vmlinux_value_type_id": 18452,
"netns_dev": 0,
"netns_ino": 0,
"btf_id": 52,
"btf_key_type_id": 0,
"btf_value_type_id": 0
}
},{
"bpf_struct_ops_tcp_congestion_ops": {
"refcnt": {
"refs": {
"counter": 1
}
},
"state": "BPF_STRUCT_OPS_STATE_INUSE",
"data": {
"list": {
"next": 0,
"prev": 0
},
"key": 0,
"flags": 0,
"init": "void (struct sock *) bictcp_init/prog_id:138",
"release": "void (struct sock *) 0",
"ssthresh": "u32 (struct sock *) bictcp_recalc_ssthresh/prog_id:141",
"cong_avoid": "void (struct sock *, u32, u32) bictcp_cong_avoid/prog_id:140",
"set_state": "void (struct sock *, u8) bictcp_state/prog_id:142",
"cwnd_event": "void (struct sock *, enum tcp_ca_event) bictcp_cwnd_event/prog_id:139",
"in_ack_event": "void (struct sock *, u32) 0",
"undo_cwnd": "u32 (struct sock *) tcp_reno_undo_cwnd/prog_id:144",
"pkts_acked": "void (struct sock *, const struct ack_sample *) bictcp_acked/prog_id:143",
"min_tso_segs": "u32 (struct sock *) 0",
"sndbuf_expand": "u32 (struct sock *) 0",
"cong_control": "void (struct sock *, const struct rate_sample *) 0",
"get_info": "size_t (struct sock *, u32, int *, union tcp_cc_info *) 0",
"name": "bpf_cubic",
"owner": 0
}
}
}
]
Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Quentin Monnet <quentin@isovalent.com>
Link: https://lore.kernel.org/bpf/20200318171656.129650-1-kafai@fb.com
2020-03-18 10:16:56 -07:00
|
|
|
struct_ops)
|
|
|
|
|
local STRUCT_OPS_TYPE='id name'
|
|
|
|
|
case $command in
|
|
|
|
|
show|list|dump|unregister)
|
|
|
|
|
case $prev in
|
|
|
|
|
$command)
|
|
|
|
|
COMPREPLY=( $( compgen -W "$STRUCT_OPS_TYPE" -- "$cur" ) )
|
|
|
|
|
;;
|
|
|
|
|
id)
|
|
|
|
|
_bpftool_get_map_ids_for_type struct_ops
|
|
|
|
|
;;
|
|
|
|
|
name)
|
|
|
|
|
_bpftool_get_map_names_for_type struct_ops
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
register)
|
|
|
|
|
_filedir
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
*)
|
|
|
|
|
[[ $prev == $object ]] && \
|
|
|
|
|
COMPREPLY=( $( compgen -W 'register unregister show list dump help' \
|
|
|
|
|
-- "$cur" ) )
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
;;
|
2020-05-09 10:59:20 -07:00
|
|
|
iter)
|
|
|
|
|
case $command in
|
|
|
|
|
pin)
|
2020-07-23 11:41:19 -07:00
|
|
|
case $prev in
|
|
|
|
|
$command)
|
|
|
|
|
_filedir
|
|
|
|
|
;;
|
|
|
|
|
id)
|
|
|
|
|
_bpftool_get_map_ids
|
|
|
|
|
;;
|
|
|
|
|
name)
|
|
|
|
|
_bpftool_get_map_names
|
|
|
|
|
;;
|
|
|
|
|
pinned)
|
|
|
|
|
_filedir
|
|
|
|
|
;;
|
|
|
|
|
*)
|
|
|
|
|
_bpftool_one_of_list $MAP_TYPE
|
|
|
|
|
;;
|
|
|
|
|
esac
|
2020-05-09 10:59:20 -07:00
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
*)
|
|
|
|
|
[[ $prev == $object ]] && \
|
|
|
|
|
COMPREPLY=( $( compgen -W 'pin help' \
|
|
|
|
|
-- "$cur" ) )
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
;;
|
2017-10-26 14:16:05 -07:00
|
|
|
map)
|
2019-12-13 20:10:37 +01:00
|
|
|
local MAP_TYPE='id pinned name'
|
2017-10-26 14:16:05 -07:00
|
|
|
case $command in
|
2019-08-21 09:52:19 +01:00
|
|
|
show|list|dump|peek|pop|dequeue|freeze)
|
2017-10-26 14:16:05 -07:00
|
|
|
case $prev in
|
|
|
|
|
$command)
|
|
|
|
|
COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
id)
|
2019-01-16 11:10:05 -08:00
|
|
|
case "$command" in
|
|
|
|
|
peek)
|
|
|
|
|
_bpftool_get_map_ids_for_type stack
|
|
|
|
|
_bpftool_get_map_ids_for_type queue
|
|
|
|
|
;;
|
|
|
|
|
pop)
|
|
|
|
|
_bpftool_get_map_ids_for_type stack
|
|
|
|
|
;;
|
|
|
|
|
dequeue)
|
|
|
|
|
_bpftool_get_map_ids_for_type queue
|
|
|
|
|
;;
|
|
|
|
|
*)
|
|
|
|
|
_bpftool_get_map_ids
|
|
|
|
|
;;
|
|
|
|
|
esac
|
2017-10-26 14:16:05 -07:00
|
|
|
return 0
|
|
|
|
|
;;
|
2019-12-13 20:10:37 +01:00
|
|
|
name)
|
|
|
|
|
case "$command" in
|
|
|
|
|
peek)
|
|
|
|
|
_bpftool_get_map_names_for_type stack
|
|
|
|
|
_bpftool_get_map_names_for_type queue
|
|
|
|
|
;;
|
|
|
|
|
pop)
|
|
|
|
|
_bpftool_get_map_names_for_type stack
|
|
|
|
|
;;
|
|
|
|
|
dequeue)
|
|
|
|
|
_bpftool_get_map_names_for_type queue
|
|
|
|
|
;;
|
|
|
|
|
*)
|
|
|
|
|
_bpftool_get_map_names
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
2017-10-26 14:16:05 -07:00
|
|
|
*)
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
;;
|
2018-10-15 16:30:36 -07:00
|
|
|
create)
|
|
|
|
|
case $prev in
|
|
|
|
|
$command)
|
|
|
|
|
_filedir
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
type)
|
2022-07-01 10:38:05 +01:00
|
|
|
local BPFTOOL_MAP_CREATE_TYPES="$(bpftool feature list_builtins map_types 2>/dev/null | \
|
2022-06-29 21:36:37 +01:00
|
|
|
grep -v '^unspec$')"
|
2021-07-30 22:54:29 +01:00
|
|
|
COMPREPLY=( $( compgen -W "$BPFTOOL_MAP_CREATE_TYPES" -- "$cur" ) )
|
2018-10-15 16:30:36 -07:00
|
|
|
return 0
|
|
|
|
|
;;
|
2020-09-10 11:26:52 +01:00
|
|
|
key|value|flags|entries)
|
2018-10-15 16:30:36 -07:00
|
|
|
return 0
|
|
|
|
|
;;
|
2020-09-10 11:26:52 +01:00
|
|
|
inner_map)
|
|
|
|
|
COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
id)
|
|
|
|
|
_bpftool_get_map_ids
|
|
|
|
|
;;
|
|
|
|
|
name)
|
|
|
|
|
case $pprev in
|
|
|
|
|
inner_map)
|
|
|
|
|
_bpftool_get_map_names
|
|
|
|
|
;;
|
|
|
|
|
*)
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
;;
|
2018-10-15 16:30:36 -07:00
|
|
|
*)
|
|
|
|
|
_bpftool_once_attr 'type'
|
|
|
|
|
_bpftool_once_attr 'key'
|
|
|
|
|
_bpftool_once_attr 'value'
|
|
|
|
|
_bpftool_once_attr 'entries'
|
|
|
|
|
_bpftool_once_attr 'name'
|
|
|
|
|
_bpftool_once_attr 'flags'
|
2020-09-10 11:26:52 +01:00
|
|
|
if _bpftool_search_list 'array_of_maps' 'hash_of_maps'; then
|
|
|
|
|
_bpftool_once_attr 'inner_map'
|
|
|
|
|
fi
|
2018-10-15 16:30:36 -07:00
|
|
|
_bpftool_once_attr 'dev'
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
;;
|
2017-10-26 14:16:05 -07:00
|
|
|
lookup|getnext|delete)
|
|
|
|
|
case $prev in
|
|
|
|
|
$command)
|
|
|
|
|
COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
id)
|
|
|
|
|
_bpftool_get_map_ids
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
2019-12-13 20:10:37 +01:00
|
|
|
name)
|
|
|
|
|
_bpftool_get_map_names
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
2017-10-26 14:16:05 -07:00
|
|
|
key)
|
tools: bpftool: make it easier to feed hex bytes to bpftool
bpftool uses hexadecimal values when it dumps map contents:
# bpftool map dump id 1337
key: ff 13 37 ff value: a1 b2 c3 d4 ff ff ff ff
Found 1 element
In order to lookup or update values with bpftool, the natural reflex is
then to copy and paste the values to the command line, and to try to run
something like:
# bpftool map update id 1337 key ff 13 37 ff \
value 00 00 00 00 00 00 1a 2b
Error: error parsing byte: ff
bpftool complains, because it uses strtoul() with a 0 base to parse the
bytes, and that without a "0x" prefix, the bytes are considered as
decimal values (or even octal if they start with "0").
To feed hexadecimal values instead, one needs to add "0x" prefixes
everywhere necessary:
# bpftool map update id 1337 key 0xff 0x13 0x37 0xff \
value 0 0 0 0 0 0 0x1a 0x2b
To make it easier to use hexadecimal values, add an optional "hex"
keyword to put after "key" or "value" to tell bpftool to consider the
digits as hexadecimal. We can now do:
# bpftool map update id 1337 key hex ff 13 37 ff \
value hex 0 0 0 0 0 0 1a 2b
Without the "hex" keyword, the bytes are still parsed according to
normal integer notation (decimal if no prefix, or hexadecimal or octal
if "0x" or "0" prefix is used, respectively).
The patch also add related documentation and bash completion for the
"hex" keyword.
Suggested-by: Daniel Borkmann <daniel@iogearbox.net>
Suggested-by: David Beckett <david.beckett@netronome.com>
Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
Acked-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2018-04-17 19:46:34 -07:00
|
|
|
COMPREPLY+=( $( compgen -W 'hex' -- "$cur" ) )
|
2017-10-26 14:16:05 -07:00
|
|
|
;;
|
|
|
|
|
*)
|
2019-01-16 11:10:05 -08:00
|
|
|
case $(_bpftool_map_guess_map_type) in
|
|
|
|
|
queue|stack)
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
|
2017-10-26 14:16:05 -07:00
|
|
|
_bpftool_once_attr 'key'
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
;;
|
2019-01-16 11:10:05 -08:00
|
|
|
update|push|enqueue)
|
2017-10-26 14:16:05 -07:00
|
|
|
case $prev in
|
|
|
|
|
$command)
|
|
|
|
|
COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
id)
|
2019-01-16 11:10:05 -08:00
|
|
|
_bpftool_map_update_get_id $command
|
2017-10-26 14:16:05 -07:00
|
|
|
return 0
|
|
|
|
|
;;
|
2019-12-13 20:10:37 +01:00
|
|
|
name)
|
|
|
|
|
_bpftool_map_update_get_name $command
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
2017-10-26 14:16:05 -07:00
|
|
|
key)
|
tools: bpftool: make it easier to feed hex bytes to bpftool
bpftool uses hexadecimal values when it dumps map contents:
# bpftool map dump id 1337
key: ff 13 37 ff value: a1 b2 c3 d4 ff ff ff ff
Found 1 element
In order to lookup or update values with bpftool, the natural reflex is
then to copy and paste the values to the command line, and to try to run
something like:
# bpftool map update id 1337 key ff 13 37 ff \
value 00 00 00 00 00 00 1a 2b
Error: error parsing byte: ff
bpftool complains, because it uses strtoul() with a 0 base to parse the
bytes, and that without a "0x" prefix, the bytes are considered as
decimal values (or even octal if they start with "0").
To feed hexadecimal values instead, one needs to add "0x" prefixes
everywhere necessary:
# bpftool map update id 1337 key 0xff 0x13 0x37 0xff \
value 0 0 0 0 0 0 0x1a 0x2b
To make it easier to use hexadecimal values, add an optional "hex"
keyword to put after "key" or "value" to tell bpftool to consider the
digits as hexadecimal. We can now do:
# bpftool map update id 1337 key hex ff 13 37 ff \
value hex 0 0 0 0 0 0 1a 2b
Without the "hex" keyword, the bytes are still parsed according to
normal integer notation (decimal if no prefix, or hexadecimal or octal
if "0x" or "0" prefix is used, respectively).
The patch also add related documentation and bash completion for the
"hex" keyword.
Suggested-by: Daniel Borkmann <daniel@iogearbox.net>
Suggested-by: David Beckett <david.beckett@netronome.com>
Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
Acked-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2018-04-17 19:46:34 -07:00
|
|
|
COMPREPLY+=( $( compgen -W 'hex' -- "$cur" ) )
|
2017-10-26 14:16:05 -07:00
|
|
|
;;
|
|
|
|
|
value)
|
|
|
|
|
# We can have bytes, or references to a prog or a
|
|
|
|
|
# map, depending on the type of the map to update.
|
2019-01-16 11:10:05 -08:00
|
|
|
case "$(_bpftool_map_guess_map_type)" in
|
2017-10-26 14:16:05 -07:00
|
|
|
array_of_maps|hash_of_maps)
|
2019-12-13 20:10:37 +01:00
|
|
|
local MAP_TYPE='id pinned name'
|
2017-10-26 14:16:05 -07:00
|
|
|
COMPREPLY+=( $( compgen -W "$MAP_TYPE" \
|
|
|
|
|
-- "$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
prog_array)
|
2019-12-13 20:10:17 +01:00
|
|
|
local PROG_TYPE='id pinned tag name'
|
2017-10-26 14:16:05 -07:00
|
|
|
COMPREPLY+=( $( compgen -W "$PROG_TYPE" \
|
|
|
|
|
-- "$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
*)
|
tools: bpftool: make it easier to feed hex bytes to bpftool
bpftool uses hexadecimal values when it dumps map contents:
# bpftool map dump id 1337
key: ff 13 37 ff value: a1 b2 c3 d4 ff ff ff ff
Found 1 element
In order to lookup or update values with bpftool, the natural reflex is
then to copy and paste the values to the command line, and to try to run
something like:
# bpftool map update id 1337 key ff 13 37 ff \
value 00 00 00 00 00 00 1a 2b
Error: error parsing byte: ff
bpftool complains, because it uses strtoul() with a 0 base to parse the
bytes, and that without a "0x" prefix, the bytes are considered as
decimal values (or even octal if they start with "0").
To feed hexadecimal values instead, one needs to add "0x" prefixes
everywhere necessary:
# bpftool map update id 1337 key 0xff 0x13 0x37 0xff \
value 0 0 0 0 0 0 0x1a 0x2b
To make it easier to use hexadecimal values, add an optional "hex"
keyword to put after "key" or "value" to tell bpftool to consider the
digits as hexadecimal. We can now do:
# bpftool map update id 1337 key hex ff 13 37 ff \
value hex 0 0 0 0 0 0 1a 2b
Without the "hex" keyword, the bytes are still parsed according to
normal integer notation (decimal if no prefix, or hexadecimal or octal
if "0x" or "0" prefix is used, respectively).
The patch also add related documentation and bash completion for the
"hex" keyword.
Suggested-by: Daniel Borkmann <daniel@iogearbox.net>
Suggested-by: David Beckett <david.beckett@netronome.com>
Signed-off-by: Quentin Monnet <quentin.monnet@netronome.com>
Acked-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2018-04-17 19:46:34 -07:00
|
|
|
COMPREPLY+=( $( compgen -W 'hex' \
|
|
|
|
|
-- "$cur" ) )
|
2017-10-26 14:16:05 -07:00
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
*)
|
2019-01-16 11:10:05 -08:00
|
|
|
case $(_bpftool_map_guess_map_type) in
|
|
|
|
|
queue|stack)
|
|
|
|
|
_bpftool_once_attr 'value'
|
|
|
|
|
return 0;
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
|
2017-10-26 14:16:05 -07:00
|
|
|
_bpftool_once_attr 'key'
|
|
|
|
|
local UPDATE_FLAGS='any exist noexist'
|
|
|
|
|
for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
|
|
|
|
|
if [[ ${words[idx]} == 'value' ]]; then
|
|
|
|
|
# 'value' is present, but is not the last
|
|
|
|
|
# word i.e. we can now have UPDATE_FLAGS.
|
|
|
|
|
_bpftool_one_of_list "$UPDATE_FLAGS"
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
done
|
|
|
|
|
for (( idx=3; idx < ${#words[@]}-1; idx++ )); do
|
|
|
|
|
if [[ ${words[idx]} == 'key' ]]; then
|
|
|
|
|
# 'key' is present, but is not the last
|
|
|
|
|
# word i.e. we can now have 'value'.
|
|
|
|
|
_bpftool_once_attr 'value'
|
|
|
|
|
return 0
|
|
|
|
|
fi
|
|
|
|
|
done
|
2019-01-16 11:10:05 -08:00
|
|
|
|
2017-10-26 14:16:05 -07:00
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
;;
|
|
|
|
|
pin)
|
2020-03-12 18:46:08 +00:00
|
|
|
case $prev in
|
|
|
|
|
$command)
|
|
|
|
|
COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
|
|
|
|
|
;;
|
|
|
|
|
id)
|
|
|
|
|
_bpftool_get_map_ids
|
|
|
|
|
;;
|
|
|
|
|
name)
|
|
|
|
|
_bpftool_get_map_names
|
|
|
|
|
;;
|
|
|
|
|
esac
|
2017-10-26 14:16:05 -07:00
|
|
|
return 0
|
|
|
|
|
;;
|
2018-05-03 18:37:16 -07:00
|
|
|
event_pipe)
|
|
|
|
|
case $prev in
|
|
|
|
|
$command)
|
|
|
|
|
COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
id)
|
2019-01-16 11:10:05 -08:00
|
|
|
_bpftool_get_map_ids_for_type perf_event_array
|
2018-05-03 18:37:16 -07:00
|
|
|
return 0
|
|
|
|
|
;;
|
2019-12-13 20:10:37 +01:00
|
|
|
name)
|
|
|
|
|
_bpftool_get_map_names_for_type perf_event_array
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
2018-05-03 18:37:16 -07:00
|
|
|
cpu)
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
index)
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
*)
|
|
|
|
|
_bpftool_once_attr 'cpu'
|
|
|
|
|
_bpftool_once_attr 'index'
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
;;
|
2017-10-26 14:16:05 -07:00
|
|
|
*)
|
|
|
|
|
[[ $prev == $object ]] && \
|
|
|
|
|
COMPREPLY=( $( compgen -W 'delete dump getnext help \
|
2019-01-16 11:10:05 -08:00
|
|
|
lookup pin event_pipe show list update create \
|
2019-08-21 09:52:19 +01:00
|
|
|
peek push enqueue pop dequeue freeze' -- \
|
2018-05-03 18:37:16 -07:00
|
|
|
"$cur" ) )
|
2017-10-26 14:16:05 -07:00
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
;;
|
2019-04-25 15:30:10 -07:00
|
|
|
btf)
|
2019-12-13 20:10:17 +01:00
|
|
|
local PROG_TYPE='id pinned tag name'
|
2019-12-13 20:10:37 +01:00
|
|
|
local MAP_TYPE='id pinned name'
|
2019-04-25 15:30:10 -07:00
|
|
|
case $command in
|
|
|
|
|
dump)
|
|
|
|
|
case $prev in
|
|
|
|
|
$command)
|
|
|
|
|
COMPREPLY+=( $( compgen -W "id map prog file" -- \
|
|
|
|
|
"$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
prog)
|
|
|
|
|
COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
map)
|
|
|
|
|
COMPREPLY=( $( compgen -W "$MAP_TYPE" -- "$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
id)
|
|
|
|
|
case $pprev in
|
|
|
|
|
prog)
|
|
|
|
|
_bpftool_get_prog_ids
|
|
|
|
|
;;
|
|
|
|
|
map)
|
|
|
|
|
_bpftool_get_map_ids
|
|
|
|
|
;;
|
2019-08-20 10:31:54 +01:00
|
|
|
$command)
|
2019-05-25 17:01:01 -07:00
|
|
|
_bpftool_get_btf_ids
|
|
|
|
|
;;
|
2019-04-25 15:30:10 -07:00
|
|
|
esac
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
2019-12-13 20:10:37 +01:00
|
|
|
name)
|
|
|
|
|
case $pprev in
|
|
|
|
|
prog)
|
|
|
|
|
_bpftool_get_prog_names
|
|
|
|
|
;;
|
|
|
|
|
map)
|
|
|
|
|
_bpftool_get_map_names
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
2019-05-24 11:59:07 -07:00
|
|
|
format)
|
|
|
|
|
COMPREPLY=( $( compgen -W "c raw" -- "$cur" ) )
|
|
|
|
|
;;
|
2019-04-25 15:30:10 -07:00
|
|
|
*)
|
2019-05-24 11:59:07 -07:00
|
|
|
# emit extra options
|
|
|
|
|
case ${words[3]} in
|
|
|
|
|
id|file)
|
|
|
|
|
_bpftool_once_attr 'format'
|
|
|
|
|
;;
|
|
|
|
|
map|prog)
|
|
|
|
|
if [[ ${words[3]} == "map" ]] && [[ $cword == 6 ]]; then
|
|
|
|
|
COMPREPLY+=( $( compgen -W "key value kv all" -- "$cur" ) )
|
|
|
|
|
fi
|
|
|
|
|
_bpftool_once_attr 'format'
|
|
|
|
|
;;
|
|
|
|
|
*)
|
|
|
|
|
;;
|
|
|
|
|
esac
|
2019-04-25 15:30:10 -07:00
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
;;
|
2019-08-20 10:31:54 +01:00
|
|
|
show|list)
|
|
|
|
|
case $prev in
|
|
|
|
|
$command)
|
|
|
|
|
COMPREPLY+=( $( compgen -W "id" -- "$cur" ) )
|
|
|
|
|
;;
|
|
|
|
|
id)
|
|
|
|
|
_bpftool_get_btf_ids
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
2019-04-25 15:30:10 -07:00
|
|
|
*)
|
|
|
|
|
[[ $prev == $object ]] && \
|
2019-08-20 10:31:54 +01:00
|
|
|
COMPREPLY=( $( compgen -W 'dump help show list' \
|
|
|
|
|
-- "$cur" ) )
|
2019-04-25 15:30:10 -07:00
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
;;
|
2019-12-13 17:43:41 -08:00
|
|
|
gen)
|
|
|
|
|
case $command in
|
2021-03-18 12:40:33 -07:00
|
|
|
object)
|
|
|
|
|
_filedir
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
2019-12-13 17:43:41 -08:00
|
|
|
skeleton)
|
2021-03-18 12:40:32 -07:00
|
|
|
case $prev in
|
|
|
|
|
$command)
|
|
|
|
|
_filedir
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
*)
|
|
|
|
|
_bpftool_once_attr 'name'
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
esac
|
2020-03-12 18:46:08 +00:00
|
|
|
;;
|
2022-03-16 23:37:28 +00:00
|
|
|
subskeleton)
|
|
|
|
|
case $prev in
|
|
|
|
|
$command)
|
|
|
|
|
_filedir
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
*)
|
|
|
|
|
_bpftool_once_attr 'name'
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
;;
|
2022-02-15 17:58:52 -05:00
|
|
|
min_core_btf)
|
|
|
|
|
_filedir
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
2019-12-13 17:43:41 -08:00
|
|
|
*)
|
|
|
|
|
[[ $prev == $object ]] && \
|
2022-03-16 23:37:28 +00:00
|
|
|
COMPREPLY=( $( compgen -W 'object skeleton subskeleton help min_core_btf' -- "$cur" ) )
|
2019-12-13 17:43:41 -08:00
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
;;
|
2018-02-07 20:27:17 -08:00
|
|
|
cgroup)
|
|
|
|
|
case $command in
|
2019-07-30 14:03:00 -07:00
|
|
|
show|list|tree)
|
|
|
|
|
case $cword in
|
|
|
|
|
3)
|
|
|
|
|
_filedir
|
|
|
|
|
;;
|
|
|
|
|
4)
|
|
|
|
|
COMPREPLY=( $( compgen -W 'effective' -- "$cur" ) )
|
|
|
|
|
;;
|
|
|
|
|
esac
|
tools/bpf: bpftool: add net support
Add "bpftool net" support. Networking devices are enumerated
to dump device index/name associated with xdp progs.
For each networking device, tc classes and qdiscs are enumerated
in order to check their bpf filters.
In addition, root handle and clsact ingress/egress are also checked for
bpf filters. Not all filter information is printed out. Only ifindex,
kind, filter name, prog_id and tag are printed out, which are good
enough to show attachment information. If the filter action
is a bpf action, its bpf program id, bpf name and tag will be
printed out as well.
For example,
$ ./bpftool net
xdp [
ifindex 2 devname eth0 prog_id 198
]
tc_filters [
ifindex 2 kind qdisc_htb name prefix_matcher.o:[cls_prefix_matcher_htb]
prog_id 111727 tag d08fe3b4319bc2fd act []
ifindex 2 kind qdisc_clsact_ingress name fbflow_icmp
prog_id 130246 tag 3f265c7f26db62c9 act []
ifindex 2 kind qdisc_clsact_egress name prefix_matcher.o:[cls_prefix_matcher_clsact]
prog_id 111726 tag 99a197826974c876
ifindex 2 kind qdisc_clsact_egress name cls_fg_dscp
prog_id 108619 tag dc4630674fd72dcc act []
ifindex 2 kind qdisc_clsact_egress name fbflow_egress
prog_id 130245 tag 72d2d830d6888d2c
]
$ ./bpftool -jp net
[{
"xdp": [{
"ifindex": 2,
"devname": "eth0",
"prog_id": 198
}
],
"tc_filters": [{
"ifindex": 2,
"kind": "qdisc_htb",
"name": "prefix_matcher.o:[cls_prefix_matcher_htb]",
"prog_id": 111727,
"tag": "d08fe3b4319bc2fd",
"act": []
},{
"ifindex": 2,
"kind": "qdisc_clsact_ingress",
"name": "fbflow_icmp",
"prog_id": 130246,
"tag": "3f265c7f26db62c9",
"act": []
},{
"ifindex": 2,
"kind": "qdisc_clsact_egress",
"name": "prefix_matcher.o:[cls_prefix_matcher_clsact]",
"prog_id": 111726,
"tag": "99a197826974c876"
},{
"ifindex": 2,
"kind": "qdisc_clsact_egress",
"name": "cls_fg_dscp",
"prog_id": 108619,
"tag": "dc4630674fd72dcc",
"act": []
},{
"ifindex": 2,
"kind": "qdisc_clsact_egress",
"name": "fbflow_egress",
"prog_id": 130245,
"tag": "72d2d830d6888d2c"
}
]
}
]
Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2018-09-05 16:58:06 -07:00
|
|
|
return 0
|
|
|
|
|
;;
|
2018-02-07 20:27:17 -08:00
|
|
|
attach|detach)
|
2022-07-01 10:38:05 +01:00
|
|
|
local BPFTOOL_CGROUP_ATTACH_TYPES="$(bpftool feature list_builtins attach_types 2>/dev/null | \
|
2022-06-29 21:36:37 +01:00
|
|
|
grep '^cgroup_')"
|
2018-02-07 20:27:17 -08:00
|
|
|
local ATTACH_FLAGS='multi override'
|
2019-12-13 20:10:17 +01:00
|
|
|
local PROG_TYPE='id pinned tag name'
|
2021-07-30 22:54:29 +01:00
|
|
|
# Check for $prev = $command first
|
|
|
|
|
if [ $prev = $command ]; then
|
|
|
|
|
_filedir
|
|
|
|
|
return 0
|
|
|
|
|
# Then check for attach type. This is done outside of the
|
|
|
|
|
# "case $prev in" to avoid writing the whole list of attach
|
|
|
|
|
# types again as pattern to match (where we cannot reuse
|
|
|
|
|
# our variable).
|
|
|
|
|
elif [[ $BPFTOOL_CGROUP_ATTACH_TYPES =~ $prev ]]; then
|
2018-02-07 20:27:17 -08:00
|
|
|
COMPREPLY=( $( compgen -W "$PROG_TYPE" -- \
|
|
|
|
|
"$cur" ) )
|
|
|
|
|
return 0
|
2021-07-30 22:54:29 +01:00
|
|
|
fi
|
|
|
|
|
# case/esac for the other cases
|
|
|
|
|
case $prev in
|
2018-02-07 20:27:17 -08:00
|
|
|
id)
|
|
|
|
|
_bpftool_get_prog_ids
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
*)
|
2021-07-30 22:54:29 +01:00
|
|
|
if ! _bpftool_search_list "$BPFTOOL_CGROUP_ATTACH_TYPES"; then
|
|
|
|
|
COMPREPLY=( $( compgen -W \
|
|
|
|
|
"$BPFTOOL_CGROUP_ATTACH_TYPES" -- "$cur" ) )
|
2018-02-07 20:27:17 -08:00
|
|
|
elif [[ "$command" == "attach" ]]; then
|
|
|
|
|
# We have an attach type on the command line,
|
|
|
|
|
# but it is not the previous word, or
|
2019-12-13 20:10:17 +01:00
|
|
|
# "id|pinned|tag|name" (we already checked for
|
2018-02-07 20:27:17 -08:00
|
|
|
# that). This should only leave the case when
|
|
|
|
|
# we need attach flags for "attach" commamnd.
|
|
|
|
|
_bpftool_one_of_list "$ATTACH_FLAGS"
|
|
|
|
|
fi
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
;;
|
|
|
|
|
*)
|
|
|
|
|
[[ $prev == $object ]] && \
|
|
|
|
|
COMPREPLY=( $( compgen -W 'help attach detach \
|
2018-07-06 14:28:16 -07:00
|
|
|
show list tree' -- "$cur" ) )
|
2018-02-07 20:27:17 -08:00
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
;;
|
tools/bpftool: add perf subcommand
The new command "bpftool perf [show | list]" will traverse
all processes under /proc, and if any fd is associated
with a perf event, it will print out related perf event
information. Documentation is also added.
Below is an example to show the results using bcc commands.
Running the following 4 bcc commands:
kprobe: trace.py '__x64_sys_nanosleep'
kretprobe: trace.py 'r::__x64_sys_nanosleep'
tracepoint: trace.py 't:syscalls:sys_enter_nanosleep'
uprobe: trace.py 'p:/home/yhs/a.out:main'
The bpftool command line and result:
$ bpftool perf
pid 21711 fd 5: prog_id 5 kprobe func __x64_sys_write offset 0
pid 21765 fd 5: prog_id 7 kretprobe func __x64_sys_nanosleep offset 0
pid 21767 fd 5: prog_id 8 tracepoint sys_enter_nanosleep
pid 21800 fd 5: prog_id 9 uprobe filename /home/yhs/a.out offset 1159
$ bpftool -j perf
[{"pid":21711,"fd":5,"prog_id":5,"fd_type":"kprobe","func":"__x64_sys_write","offset":0}, \
{"pid":21765,"fd":5,"prog_id":7,"fd_type":"kretprobe","func":"__x64_sys_nanosleep","offset":0}, \
{"pid":21767,"fd":5,"prog_id":8,"fd_type":"tracepoint","tracepoint":"sys_enter_nanosleep"}, \
{"pid":21800,"fd":5,"prog_id":9,"fd_type":"uprobe","filename":"/home/yhs/a.out","offset":1159}]
$ bpftool prog
5: kprobe name probe___x64_sys tag e495a0c82f2c7a8d gpl
loaded_at 2018-05-15T04:46:37-0700 uid 0
xlated 200B not jited memlock 4096B map_ids 4
7: kprobe name probe___x64_sys tag f2fdee479a503abf gpl
loaded_at 2018-05-15T04:48:32-0700 uid 0
xlated 200B not jited memlock 4096B map_ids 7
8: tracepoint name tracepoint__sys tag 5390badef2395fcf gpl
loaded_at 2018-05-15T04:48:48-0700 uid 0
xlated 200B not jited memlock 4096B map_ids 8
9: kprobe name probe_main_1 tag 0a87bdc2e2953b6d gpl
loaded_at 2018-05-15T04:49:52-0700 uid 0
xlated 200B not jited memlock 4096B map_ids 9
$ ps ax | grep "python ./trace.py"
21711 pts/0 T 0:03 python ./trace.py __x64_sys_write
21765 pts/0 S+ 0:00 python ./trace.py r::__x64_sys_nanosleep
21767 pts/2 S+ 0:00 python ./trace.py t:syscalls:sys_enter_nanosleep
21800 pts/3 S+ 0:00 python ./trace.py p:/home/yhs/a.out:main
22374 pts/1 S+ 0:00 grep --color=auto python ./trace.py
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2018-05-24 11:21:58 -07:00
|
|
|
perf)
|
|
|
|
|
case $command in
|
|
|
|
|
*)
|
|
|
|
|
[[ $prev == $object ]] && \
|
|
|
|
|
COMPREPLY=( $( compgen -W 'help \
|
|
|
|
|
show list' -- "$cur" ) )
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
;;
|
tools/bpf: bpftool: add net support
Add "bpftool net" support. Networking devices are enumerated
to dump device index/name associated with xdp progs.
For each networking device, tc classes and qdiscs are enumerated
in order to check their bpf filters.
In addition, root handle and clsact ingress/egress are also checked for
bpf filters. Not all filter information is printed out. Only ifindex,
kind, filter name, prog_id and tag are printed out, which are good
enough to show attachment information. If the filter action
is a bpf action, its bpf program id, bpf name and tag will be
printed out as well.
For example,
$ ./bpftool net
xdp [
ifindex 2 devname eth0 prog_id 198
]
tc_filters [
ifindex 2 kind qdisc_htb name prefix_matcher.o:[cls_prefix_matcher_htb]
prog_id 111727 tag d08fe3b4319bc2fd act []
ifindex 2 kind qdisc_clsact_ingress name fbflow_icmp
prog_id 130246 tag 3f265c7f26db62c9 act []
ifindex 2 kind qdisc_clsact_egress name prefix_matcher.o:[cls_prefix_matcher_clsact]
prog_id 111726 tag 99a197826974c876
ifindex 2 kind qdisc_clsact_egress name cls_fg_dscp
prog_id 108619 tag dc4630674fd72dcc act []
ifindex 2 kind qdisc_clsact_egress name fbflow_egress
prog_id 130245 tag 72d2d830d6888d2c
]
$ ./bpftool -jp net
[{
"xdp": [{
"ifindex": 2,
"devname": "eth0",
"prog_id": 198
}
],
"tc_filters": [{
"ifindex": 2,
"kind": "qdisc_htb",
"name": "prefix_matcher.o:[cls_prefix_matcher_htb]",
"prog_id": 111727,
"tag": "d08fe3b4319bc2fd",
"act": []
},{
"ifindex": 2,
"kind": "qdisc_clsact_ingress",
"name": "fbflow_icmp",
"prog_id": 130246,
"tag": "3f265c7f26db62c9",
"act": []
},{
"ifindex": 2,
"kind": "qdisc_clsact_egress",
"name": "prefix_matcher.o:[cls_prefix_matcher_clsact]",
"prog_id": 111726,
"tag": "99a197826974c876"
},{
"ifindex": 2,
"kind": "qdisc_clsact_egress",
"name": "cls_fg_dscp",
"prog_id": 108619,
"tag": "dc4630674fd72dcc",
"act": []
},{
"ifindex": 2,
"kind": "qdisc_clsact_egress",
"name": "fbflow_egress",
"prog_id": 130245,
"tag": "72d2d830d6888d2c"
}
]
}
]
Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2018-09-05 16:58:06 -07:00
|
|
|
net)
|
2019-12-13 20:10:17 +01:00
|
|
|
local PROG_TYPE='id pinned tag name'
|
2019-08-13 11:46:20 +09:00
|
|
|
local ATTACH_TYPES='xdp xdpgeneric xdpdrv xdpoffload'
|
tools/bpf: bpftool: add net support
Add "bpftool net" support. Networking devices are enumerated
to dump device index/name associated with xdp progs.
For each networking device, tc classes and qdiscs are enumerated
in order to check their bpf filters.
In addition, root handle and clsact ingress/egress are also checked for
bpf filters. Not all filter information is printed out. Only ifindex,
kind, filter name, prog_id and tag are printed out, which are good
enough to show attachment information. If the filter action
is a bpf action, its bpf program id, bpf name and tag will be
printed out as well.
For example,
$ ./bpftool net
xdp [
ifindex 2 devname eth0 prog_id 198
]
tc_filters [
ifindex 2 kind qdisc_htb name prefix_matcher.o:[cls_prefix_matcher_htb]
prog_id 111727 tag d08fe3b4319bc2fd act []
ifindex 2 kind qdisc_clsact_ingress name fbflow_icmp
prog_id 130246 tag 3f265c7f26db62c9 act []
ifindex 2 kind qdisc_clsact_egress name prefix_matcher.o:[cls_prefix_matcher_clsact]
prog_id 111726 tag 99a197826974c876
ifindex 2 kind qdisc_clsact_egress name cls_fg_dscp
prog_id 108619 tag dc4630674fd72dcc act []
ifindex 2 kind qdisc_clsact_egress name fbflow_egress
prog_id 130245 tag 72d2d830d6888d2c
]
$ ./bpftool -jp net
[{
"xdp": [{
"ifindex": 2,
"devname": "eth0",
"prog_id": 198
}
],
"tc_filters": [{
"ifindex": 2,
"kind": "qdisc_htb",
"name": "prefix_matcher.o:[cls_prefix_matcher_htb]",
"prog_id": 111727,
"tag": "d08fe3b4319bc2fd",
"act": []
},{
"ifindex": 2,
"kind": "qdisc_clsact_ingress",
"name": "fbflow_icmp",
"prog_id": 130246,
"tag": "3f265c7f26db62c9",
"act": []
},{
"ifindex": 2,
"kind": "qdisc_clsact_egress",
"name": "prefix_matcher.o:[cls_prefix_matcher_clsact]",
"prog_id": 111726,
"tag": "99a197826974c876"
},{
"ifindex": 2,
"kind": "qdisc_clsact_egress",
"name": "cls_fg_dscp",
"prog_id": 108619,
"tag": "dc4630674fd72dcc",
"act": []
},{
"ifindex": 2,
"kind": "qdisc_clsact_egress",
"name": "fbflow_egress",
"prog_id": 130245,
"tag": "72d2d830d6888d2c"
}
]
}
]
Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2018-09-05 16:58:06 -07:00
|
|
|
case $command in
|
2019-08-13 11:46:20 +09:00
|
|
|
show|list)
|
|
|
|
|
[[ $prev != "$command" ]] && return 0
|
|
|
|
|
COMPREPLY=( $( compgen -W 'dev' -- "$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
attach)
|
|
|
|
|
case $cword in
|
|
|
|
|
3)
|
|
|
|
|
COMPREPLY=( $( compgen -W "$ATTACH_TYPES" -- "$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
4)
|
|
|
|
|
COMPREPLY=( $( compgen -W "$PROG_TYPE" -- "$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
5)
|
|
|
|
|
case $prev in
|
|
|
|
|
id)
|
|
|
|
|
_bpftool_get_prog_ids
|
|
|
|
|
;;
|
2020-03-12 18:46:08 +00:00
|
|
|
name)
|
|
|
|
|
_bpftool_get_prog_names
|
|
|
|
|
;;
|
2019-08-13 11:46:20 +09:00
|
|
|
pinned)
|
|
|
|
|
_filedir
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
6)
|
|
|
|
|
COMPREPLY=( $( compgen -W 'dev' -- "$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
8)
|
|
|
|
|
_bpftool_once_attr 'overwrite'
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
;;
|
|
|
|
|
detach)
|
|
|
|
|
case $cword in
|
|
|
|
|
3)
|
|
|
|
|
COMPREPLY=( $( compgen -W "$ATTACH_TYPES" -- "$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
4)
|
|
|
|
|
COMPREPLY=( $( compgen -W 'dev' -- "$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
;;
|
tools/bpf: bpftool: add net support
Add "bpftool net" support. Networking devices are enumerated
to dump device index/name associated with xdp progs.
For each networking device, tc classes and qdiscs are enumerated
in order to check their bpf filters.
In addition, root handle and clsact ingress/egress are also checked for
bpf filters. Not all filter information is printed out. Only ifindex,
kind, filter name, prog_id and tag are printed out, which are good
enough to show attachment information. If the filter action
is a bpf action, its bpf program id, bpf name and tag will be
printed out as well.
For example,
$ ./bpftool net
xdp [
ifindex 2 devname eth0 prog_id 198
]
tc_filters [
ifindex 2 kind qdisc_htb name prefix_matcher.o:[cls_prefix_matcher_htb]
prog_id 111727 tag d08fe3b4319bc2fd act []
ifindex 2 kind qdisc_clsact_ingress name fbflow_icmp
prog_id 130246 tag 3f265c7f26db62c9 act []
ifindex 2 kind qdisc_clsact_egress name prefix_matcher.o:[cls_prefix_matcher_clsact]
prog_id 111726 tag 99a197826974c876
ifindex 2 kind qdisc_clsact_egress name cls_fg_dscp
prog_id 108619 tag dc4630674fd72dcc act []
ifindex 2 kind qdisc_clsact_egress name fbflow_egress
prog_id 130245 tag 72d2d830d6888d2c
]
$ ./bpftool -jp net
[{
"xdp": [{
"ifindex": 2,
"devname": "eth0",
"prog_id": 198
}
],
"tc_filters": [{
"ifindex": 2,
"kind": "qdisc_htb",
"name": "prefix_matcher.o:[cls_prefix_matcher_htb]",
"prog_id": 111727,
"tag": "d08fe3b4319bc2fd",
"act": []
},{
"ifindex": 2,
"kind": "qdisc_clsact_ingress",
"name": "fbflow_icmp",
"prog_id": 130246,
"tag": "3f265c7f26db62c9",
"act": []
},{
"ifindex": 2,
"kind": "qdisc_clsact_egress",
"name": "prefix_matcher.o:[cls_prefix_matcher_clsact]",
"prog_id": 111726,
"tag": "99a197826974c876"
},{
"ifindex": 2,
"kind": "qdisc_clsact_egress",
"name": "cls_fg_dscp",
"prog_id": 108619,
"tag": "dc4630674fd72dcc",
"act": []
},{
"ifindex": 2,
"kind": "qdisc_clsact_egress",
"name": "fbflow_egress",
"prog_id": 130245,
"tag": "72d2d830d6888d2c"
}
]
}
]
Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2018-09-05 16:58:06 -07:00
|
|
|
*)
|
|
|
|
|
[[ $prev == $object ]] && \
|
|
|
|
|
COMPREPLY=( $( compgen -W 'help \
|
2019-08-13 11:46:20 +09:00
|
|
|
show list attach detach' -- "$cur" ) )
|
tools/bpf: bpftool: add net support
Add "bpftool net" support. Networking devices are enumerated
to dump device index/name associated with xdp progs.
For each networking device, tc classes and qdiscs are enumerated
in order to check their bpf filters.
In addition, root handle and clsact ingress/egress are also checked for
bpf filters. Not all filter information is printed out. Only ifindex,
kind, filter name, prog_id and tag are printed out, which are good
enough to show attachment information. If the filter action
is a bpf action, its bpf program id, bpf name and tag will be
printed out as well.
For example,
$ ./bpftool net
xdp [
ifindex 2 devname eth0 prog_id 198
]
tc_filters [
ifindex 2 kind qdisc_htb name prefix_matcher.o:[cls_prefix_matcher_htb]
prog_id 111727 tag d08fe3b4319bc2fd act []
ifindex 2 kind qdisc_clsact_ingress name fbflow_icmp
prog_id 130246 tag 3f265c7f26db62c9 act []
ifindex 2 kind qdisc_clsact_egress name prefix_matcher.o:[cls_prefix_matcher_clsact]
prog_id 111726 tag 99a197826974c876
ifindex 2 kind qdisc_clsact_egress name cls_fg_dscp
prog_id 108619 tag dc4630674fd72dcc act []
ifindex 2 kind qdisc_clsact_egress name fbflow_egress
prog_id 130245 tag 72d2d830d6888d2c
]
$ ./bpftool -jp net
[{
"xdp": [{
"ifindex": 2,
"devname": "eth0",
"prog_id": 198
}
],
"tc_filters": [{
"ifindex": 2,
"kind": "qdisc_htb",
"name": "prefix_matcher.o:[cls_prefix_matcher_htb]",
"prog_id": 111727,
"tag": "d08fe3b4319bc2fd",
"act": []
},{
"ifindex": 2,
"kind": "qdisc_clsact_ingress",
"name": "fbflow_icmp",
"prog_id": 130246,
"tag": "3f265c7f26db62c9",
"act": []
},{
"ifindex": 2,
"kind": "qdisc_clsact_egress",
"name": "prefix_matcher.o:[cls_prefix_matcher_clsact]",
"prog_id": 111726,
"tag": "99a197826974c876"
},{
"ifindex": 2,
"kind": "qdisc_clsact_egress",
"name": "cls_fg_dscp",
"prog_id": 108619,
"tag": "dc4630674fd72dcc",
"act": []
},{
"ifindex": 2,
"kind": "qdisc_clsact_egress",
"name": "fbflow_egress",
"prog_id": 130245,
"tag": "72d2d830d6888d2c"
}
]
}
]
Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2018-09-05 16:58:06 -07:00
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
;;
|
2019-01-17 15:27:58 +00:00
|
|
|
feature)
|
|
|
|
|
case $command in
|
|
|
|
|
probe)
|
|
|
|
|
[[ $prev == "prefix" ]] && return 0
|
|
|
|
|
if _bpftool_search_list 'macros'; then
|
2020-02-26 17:59:38 +01:00
|
|
|
_bpftool_once_attr 'prefix'
|
2019-01-17 15:27:58 +00:00
|
|
|
else
|
|
|
|
|
COMPREPLY+=( $( compgen -W 'macros' -- "$cur" ) )
|
|
|
|
|
fi
|
|
|
|
|
_bpftool_one_of_list 'kernel dev'
|
2020-04-29 15:45:05 +01:00
|
|
|
_bpftool_once_attr 'full unprivileged'
|
2019-01-17 15:27:58 +00:00
|
|
|
return 0
|
|
|
|
|
;;
|
2022-07-01 10:38:05 +01:00
|
|
|
list_builtins)
|
bpftool: Add feature list (prog/map/link/attach types, helpers)
Add a "bpftool feature list" subcommand to list BPF "features".
Contrarily to "bpftool feature probe", this is not about the features
available on the system. Instead, it lists all features known to bpftool
from compilation time; in other words, all program, map, attach, link
types known to the libbpf version in use, and all helpers found in the
UAPI BPF header.
The first use case for this feature is bash completion: running the
command provides a list of types that can be used to produce the list of
candidate map types, for example.
Now that bpftool uses "standard" names provided by libbpf for the
program, map, link, and attach types, having the ability to list these
types and helpers could also be useful in scripts to loop over existing
items.
Sample output:
# bpftool feature list prog_types | grep -vw unspec | head -n 6
socket_filter
kprobe
sched_cls
sched_act
tracepoint
xdp
# bpftool -p feature list map_types | jq '.[1]'
"hash"
# bpftool feature list attach_types | grep '^cgroup_'
cgroup_inet_ingress
cgroup_inet_egress
[...]
cgroup_inet_sock_release
# bpftool feature list helpers | grep -vw bpf_unspec | wc -l
207
The "unspec" types and helpers are not filtered out by bpftool, so as to
remain closer to the enums, and to preserve the indices in the JSON
arrays (e.g. "hash" at index 1 == BPF_MAP_TYPE_HASH in map types list).
Signed-off-by: Quentin Monnet <quentin@isovalent.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Daniel Müller <deso@posteo.net>
Link: https://lore.kernel.org/bpf/20220629203637.138944-2-quentin@isovalent.com
2022-06-29 21:36:36 +01:00
|
|
|
[[ $prev != "$command" ]] && return 0
|
|
|
|
|
COMPREPLY=( $( compgen -W 'prog_types map_types \
|
|
|
|
|
attach_types link_types helpers' -- "$cur" ) )
|
|
|
|
|
;;
|
2019-01-17 15:27:58 +00:00
|
|
|
*)
|
|
|
|
|
[[ $prev == $object ]] && \
|
2022-07-01 10:38:05 +01:00
|
|
|
COMPREPLY=( $( compgen -W 'help list_builtins probe' -- "$cur" ) )
|
2019-01-17 15:27:58 +00:00
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
;;
|
2020-04-28 17:16:14 -07:00
|
|
|
link)
|
|
|
|
|
case $command in
|
2020-07-31 11:28:30 -07:00
|
|
|
show|list|pin|detach)
|
2020-04-28 17:16:14 -07:00
|
|
|
case $prev in
|
|
|
|
|
id)
|
|
|
|
|
_bpftool_get_link_ids
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
|
|
|
|
|
local LINK_TYPE='id pinned'
|
|
|
|
|
case $command in
|
|
|
|
|
show|list)
|
|
|
|
|
[[ $prev != "$command" ]] && return 0
|
|
|
|
|
COMPREPLY=( $( compgen -W "$LINK_TYPE" -- "$cur" ) )
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
2020-07-31 11:28:30 -07:00
|
|
|
pin|detach)
|
2020-04-28 17:16:14 -07:00
|
|
|
if [[ $prev == "$command" ]]; then
|
|
|
|
|
COMPREPLY=( $( compgen -W "$LINK_TYPE" -- "$cur" ) )
|
|
|
|
|
else
|
|
|
|
|
_filedir
|
|
|
|
|
fi
|
|
|
|
|
return 0
|
|
|
|
|
;;
|
|
|
|
|
*)
|
|
|
|
|
[[ $prev == $object ]] && \
|
|
|
|
|
COMPREPLY=( $( compgen -W 'help pin show list' -- "$cur" ) )
|
|
|
|
|
;;
|
|
|
|
|
esac
|
|
|
|
|
;;
|
2017-10-26 14:16:05 -07:00
|
|
|
esac
|
|
|
|
|
} &&
|
|
|
|
|
complete -F _bpftool bpftool
|
|
|
|
|
|
|
|
|
|
# ex: ts=4 sw=4 et filetype=sh
|