Merge ../iproute2-next
This commit is contained in:
commit
5d10f24fdd
1
Makefile
1
Makefile
|
|
@ -90,6 +90,7 @@ install: all
|
|||
install -m 0644 $(shell find etc/iproute2 -maxdepth 1 -type f) $(DESTDIR)$(CONFDIR)
|
||||
install -m 0755 -d $(DESTDIR)$(BASH_COMPDIR)
|
||||
install -m 0644 bash-completion/tc $(DESTDIR)$(BASH_COMPDIR)
|
||||
install -m 0644 bash-completion/devlink $(DESTDIR)$(BASH_COMPDIR)
|
||||
install -m 0644 include/bpf_elf.h $(DESTDIR)$(HDRDIR)
|
||||
|
||||
snapshot:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,951 @@
|
|||
# bash completion for devlink(8) -*- shell-script -*-
|
||||
|
||||
# Get all the optional commands for devlink
|
||||
_devlink_get_optional_commands()
|
||||
{
|
||||
local object=$1; shift
|
||||
|
||||
local filter_options=""
|
||||
local options="$(devlink $object help 2>&1 \
|
||||
| command sed -n -e "s/^.*devlink $object //p" \
|
||||
| cut -d " " -f 1)"
|
||||
|
||||
# Remove duplicate options from "devlink $OBJECT help" command
|
||||
local opt
|
||||
for opt in $options; do
|
||||
if [[ $filter_options =~ $opt ]]; then
|
||||
continue
|
||||
else
|
||||
filter_options="$filter_options $opt"
|
||||
fi
|
||||
done
|
||||
|
||||
echo $filter_options
|
||||
}
|
||||
|
||||
# Complete based on given word, for when an argument or an option name has
|
||||
# but a few possible arguments.
|
||||
_devlink_direct_complete()
|
||||
{
|
||||
local dev port region value
|
||||
|
||||
case $1 in
|
||||
dev)
|
||||
value=$(devlink dev show 2>/dev/null)
|
||||
;;
|
||||
param_name)
|
||||
dev=${words[4]}
|
||||
value=$(devlink -j dev param show 2>/dev/null \
|
||||
| jq ".param[\"$dev\"][].name")
|
||||
;;
|
||||
port)
|
||||
value=$(devlink -j port show 2>/dev/null \
|
||||
| jq '.port as $ports | $ports | keys[] as $key
|
||||
| ($ports[$key].netdev // $key)')
|
||||
;;
|
||||
region)
|
||||
value=$(devlink -j region show 2>/dev/null \
|
||||
| jq '.regions' | jq 'keys[]')
|
||||
;;
|
||||
snapshot)
|
||||
region=${words[3]}
|
||||
value=$(devlink -j region show 2>/dev/null \
|
||||
| jq ".regions[\"$region\"].snapshot[]")
|
||||
;;
|
||||
trap)
|
||||
dev=${words[3]}
|
||||
value=$(devlink -j trap show 2>/dev/null \
|
||||
| jq ".trap[\"$dev\"][].name")
|
||||
;;
|
||||
trap_group)
|
||||
dev=${words[4]}
|
||||
value=$(devlink -j trap group show 2>/dev/null \
|
||||
| jq ".trap_group[\"$dev\"][].name")
|
||||
;;
|
||||
trap_policer)
|
||||
dev=${words[4]}
|
||||
value=$(devlink -j trap policer show 2>/dev/null \
|
||||
| jq ".trap_policer[\"$dev\"][].policer")
|
||||
;;
|
||||
health_dev)
|
||||
value=$(devlink -j health show 2>/dev/null | jq '.health' \
|
||||
| jq 'keys[]')
|
||||
;;
|
||||
reporter)
|
||||
dev=${words[cword - 2]}
|
||||
value=$(devlink -j health show 2>/dev/null \
|
||||
| jq ".health[\"$dev\"][].reporter")
|
||||
;;
|
||||
pool)
|
||||
dev=$pprev
|
||||
value=$(devlink -j sb pool show 2>/dev/null \
|
||||
| jq ".pool[\"$dev\"][].pool")
|
||||
;;
|
||||
port_pool)
|
||||
port=${words[5]}
|
||||
value=$(devlink -j sb port pool show 2>/dev/null \
|
||||
| jq ".port_pool[\"$port\"][].pool")
|
||||
;;
|
||||
tc)
|
||||
port=$pprev
|
||||
value=$(devlink -j sb tc bind show 2>/dev/null \
|
||||
| jq ".tc_bind[\"$port\"][].tc")
|
||||
;;
|
||||
esac
|
||||
|
||||
COMPREPLY+=( $( compgen -W "$value" -- "$cur" ) )
|
||||
# Remove colon containing prefix from COMPREPLY items in order to avoid
|
||||
# wordbreaks with colon.
|
||||
__ltrim_colon_completions "$cur"
|
||||
}
|
||||
|
||||
# Completion for devlink dev eswitch set
|
||||
_devlink_dev_eswitch_set()
|
||||
{
|
||||
local -A settings=(
|
||||
[mode]=notseen
|
||||
[inline-mode]=notseen
|
||||
[encap]=notseen
|
||||
)
|
||||
|
||||
if [[ $cword -eq 5 ]]; then
|
||||
COMPREPLY=( $( compgen -W "mode inline-mode encap" -- "$cur" ) )
|
||||
fi
|
||||
|
||||
# Mark seen settings
|
||||
local word
|
||||
for word in "${words[@]:5:${#words[@]}-1}"; do
|
||||
if [[ -n $word ]]; then
|
||||
if [[ "${settings[$word]}" ]]; then
|
||||
settings[$word]=seen
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
case $prev in
|
||||
mode)
|
||||
COMPREPLY=( $( compgen -W "legacy switchdev" -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
inline-mode)
|
||||
COMPREPLY=( $( compgen -W "none link network transport" -- \
|
||||
"$cur" ) )
|
||||
return
|
||||
;;
|
||||
encap)
|
||||
COMPREPLY=( $( compgen -W "disable enable" -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
esac
|
||||
|
||||
local -a comp_words=()
|
||||
|
||||
# Add settings not seen to completions
|
||||
local setting
|
||||
for setting in "${!settings[@]}"; do
|
||||
if [ "${settings[$setting]}" = notseen ]; then
|
||||
comp_words+=( "$setting" )
|
||||
fi
|
||||
done
|
||||
|
||||
COMPREPLY=( $( compgen -W "${comp_words[*]}" -- "$cur" ) )
|
||||
}
|
||||
|
||||
# Completion for devlink dev eswitch
|
||||
_devlink_dev_eswitch()
|
||||
{
|
||||
case "$cword" in
|
||||
3)
|
||||
COMPREPLY=( $( compgen -W "show set" -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
4)
|
||||
_devlink_direct_complete "dev"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
|
||||
case "${words[3]}" in
|
||||
set)
|
||||
_devlink_dev_eswitch_set
|
||||
return
|
||||
;;
|
||||
show)
|
||||
return
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Completion for devlink dev param set
|
||||
_devlink_dev_param_set()
|
||||
{
|
||||
case $cword in
|
||||
7)
|
||||
COMPREPLY=( $( compgen -W "value" -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
8)
|
||||
# String argument
|
||||
return
|
||||
;;
|
||||
9)
|
||||
COMPREPLY=( $( compgen -W "cmode" -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
10)
|
||||
COMPREPLY=( $( compgen -W "runtime driverinit permanent" -- \
|
||||
"$cur" ) )
|
||||
return
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Completion for devlink dev param
|
||||
_devlink_dev_param()
|
||||
{
|
||||
case "$cword" in
|
||||
3)
|
||||
COMPREPLY=( $( compgen -W "show set" -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
4)
|
||||
_devlink_direct_complete "dev"
|
||||
return
|
||||
;;
|
||||
5)
|
||||
COMPREPLY=( $( compgen -W "name" -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
6)
|
||||
_devlink_direct_complete "param_name"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
|
||||
if [[ "${words[3]}" == "set" ]]; then
|
||||
_devlink_dev_param_set
|
||||
fi
|
||||
}
|
||||
|
||||
# Completion for devlink dev reload
|
||||
_devlink_dev_reload()
|
||||
{
|
||||
case "$cword" in
|
||||
4)
|
||||
COMPREPLY=( $( compgen -W "netns" -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
5)
|
||||
local nslist=$( ip netns list 2>/dev/null )
|
||||
COMPREPLY=( $( compgen -W "$nslist" -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Completion for devlink dev flash
|
||||
_devlink_dev_flash()
|
||||
{
|
||||
case "$cword" in
|
||||
4)
|
||||
COMPREPLY=( $( compgen -W "file" -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
5)
|
||||
_filedir
|
||||
return
|
||||
;;
|
||||
6)
|
||||
COMPREPLY=( $( compgen -W "component" -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Completion for devlink dev
|
||||
_devlink_dev()
|
||||
{
|
||||
case $command in
|
||||
show|reload|info|flash)
|
||||
if [[ $cword -le 3 ]]; then
|
||||
_devlink_direct_complete "dev"
|
||||
elif [[ $command == "reload" || $command == "flash" ]];then
|
||||
_devlink_dev_$command
|
||||
fi
|
||||
return
|
||||
;;
|
||||
eswitch|param)
|
||||
_devlink_dev_$command
|
||||
return
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Completion for devlink port set
|
||||
_devlink_port_set()
|
||||
{
|
||||
case "$cword" in
|
||||
3)
|
||||
_devlink_direct_complete "port"
|
||||
return
|
||||
;;
|
||||
4)
|
||||
COMPREPLY=( $( compgen -W "type" -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
5)
|
||||
COMPREPLY=( $( compgen -W "eth ib auto" -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Completion for devlink port split
|
||||
_devlink_port_split()
|
||||
{
|
||||
case "$cword" in
|
||||
3)
|
||||
_devlink_direct_complete "port"
|
||||
return
|
||||
;;
|
||||
4)
|
||||
COMPREPLY=( $( compgen -W "count" -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
5)
|
||||
# Integer argument
|
||||
return
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Completion for devlink port
|
||||
_devlink_port()
|
||||
{
|
||||
case $command in
|
||||
set)
|
||||
_devlink_port_set
|
||||
return
|
||||
;;
|
||||
split)
|
||||
_devlink_port_split
|
||||
return
|
||||
;;
|
||||
show|unsplit)
|
||||
if [[ $cword -eq 3 ]]; then
|
||||
_devlink_direct_complete "port"
|
||||
fi
|
||||
return
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Completion for devlink dpipe
|
||||
_devlink_dpipe()
|
||||
{
|
||||
local options="$(devlink dpipe help 2>&1 \
|
||||
| command sed -e '/OBJECT-LIST := /!d' \
|
||||
-e 's/.*{ //' -e 's/}.*//' -e 's/|//g' )"
|
||||
|
||||
if [[ $cword -eq 2 ]]; then
|
||||
COMPREPLY+=( $( compgen -W "$options" -- "$cur" ) )
|
||||
fi
|
||||
}
|
||||
|
||||
# Completion for devlink monitor
|
||||
_devlink_monitor()
|
||||
{
|
||||
local options="$(devlink monitor help 2>&1 \
|
||||
| command sed -e '/OBJECT-LIST := /!d' \
|
||||
-e 's/.*{ //' -e 's/}.*//' -e 's/|//g' )"
|
||||
|
||||
if [[ $cword -eq 2 ]]; then
|
||||
COMPREPLY+=( $( compgen -W "all $options" -- "$cur" ) )
|
||||
fi
|
||||
}
|
||||
|
||||
# Completion for the rest of devlink sb $command
|
||||
_devlink_sb_command_options()
|
||||
{
|
||||
local subcmd
|
||||
|
||||
case $command in
|
||||
pool)
|
||||
subcmd=${words[3]}
|
||||
if [[ $cword -eq 5 ]]; then
|
||||
COMPREPLY=( $( compgen -W "pool" -- "$cur" ) )
|
||||
fi
|
||||
if [[ $subcmd == "set" ]]; then
|
||||
case $cword in
|
||||
7)
|
||||
COMPREPLY+=( $( compgen -W "size" -- "$cur" ) )
|
||||
;;
|
||||
9)
|
||||
COMPREPLY+=( $( compgen -W "thtype" -- "$cur" ) )
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
port)
|
||||
subcmd=${words[4]}
|
||||
if [[ $cword -eq 6 ]]; then
|
||||
COMPREPLY+=( $( compgen -W "pool" -- "$cur" ) )
|
||||
fi
|
||||
if [[ $subcmd == "set" ]]; then
|
||||
case $cword in
|
||||
8)
|
||||
COMPREPLY+=( $( compgen -W "th" -- "$cur" ) )
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
tc)
|
||||
subcmd=${words[4]}
|
||||
case $cword in
|
||||
6)
|
||||
COMPREPLY+=( $( compgen -W "tc" -- "$cur" ) )
|
||||
;;
|
||||
8)
|
||||
COMPREPLY+=( $( compgen -W "type" -- "$cur" ) )
|
||||
;;
|
||||
esac
|
||||
if [[ $subcmd == "set" ]]; then
|
||||
case $cword in
|
||||
10)
|
||||
COMPREPLY+=( $( compgen -W "pool" -- "$cur" ) )
|
||||
;;
|
||||
12)
|
||||
COMPREPLY+=( $( compgen -W "th" -- "$cur" ) )
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Completion for devlink sb
|
||||
_devlink_sb()
|
||||
{
|
||||
case $prev in
|
||||
bind)
|
||||
COMPREPLY=( $( compgen -W "set show" -- "$cur" ) )
|
||||
;;
|
||||
occupancy)
|
||||
COMPREPLY=( $( compgen -W "show snapshot clearmax" -- "$cur" ) )
|
||||
;;
|
||||
pool)
|
||||
if [[ $cword -eq 3 || $cword -eq 4 ]]; then
|
||||
COMPREPLY=( $( compgen -W "set show" -- "$cur" ) )
|
||||
elif [[ $command == "port" || $command == "tc" ]]; then
|
||||
_devlink_direct_complete "port_pool"
|
||||
else
|
||||
_devlink_direct_complete "pool"
|
||||
fi
|
||||
;;
|
||||
port)
|
||||
if [[ $cword -eq 3 ]]; then
|
||||
COMPREPLY=( $( compgen -W "pool" -- "$cur" ) )
|
||||
fi
|
||||
;;
|
||||
show|set|snapshot|clearmax)
|
||||
case $command in
|
||||
show|pool|occupancy)
|
||||
_devlink_direct_complete "dev"
|
||||
if [[ $command == "occupancy" && $prev == "show" ]];then
|
||||
_devlink_direct_complete "port"
|
||||
fi
|
||||
;;
|
||||
port|tc)
|
||||
_devlink_direct_complete "port"
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
size)
|
||||
# Integer argument
|
||||
;;
|
||||
thtype)
|
||||
COMPREPLY=( $( compgen -W "static dynamic" -- "$cur" ) )
|
||||
;;
|
||||
th)
|
||||
# Integer argument
|
||||
;;
|
||||
tc)
|
||||
if [[ $cword -eq 3 ]]; then
|
||||
COMPREPLY=( $( compgen -W "bind" -- "$cur" ) )
|
||||
else
|
||||
_devlink_direct_complete "tc"
|
||||
fi
|
||||
;;
|
||||
type)
|
||||
COMPREPLY=( $( compgen -W "ingress egress" -- "$cur" ) )
|
||||
;;
|
||||
esac
|
||||
|
||||
_devlink_sb_command_options
|
||||
return
|
||||
}
|
||||
|
||||
# Completion for devlink resource set path argument
|
||||
_devlink_resource_path()
|
||||
{
|
||||
local path parents parent all_path
|
||||
local dev=${words[3]}
|
||||
local -a path
|
||||
|
||||
local all_path=$(
|
||||
devlink resource show $dev \
|
||||
| sed -E '# Of resource lines, keep only the name itself.
|
||||
s/name ([^ ]*) .*/\1/
|
||||
# Drop headers.
|
||||
/:$/d
|
||||
# First layer is not aligned enough, align it.
|
||||
s/^/ /
|
||||
# Use slashes as unary code for resource depth.
|
||||
s, ,/,g
|
||||
# Separate tally count from resource name.
|
||||
s,/*,&\t,' \
|
||||
| while read d name; do
|
||||
while ((${#path[@]} > ${#d})); do
|
||||
unset path[$((${#path[@]} - 1))]
|
||||
done
|
||||
path[$((${#d} - 1))]=$name
|
||||
echo ${path[@]}
|
||||
done \
|
||||
| sed '# Convert paths to slash-separated
|
||||
s,^,/,;s, ,/,g;s,$,/,'
|
||||
)
|
||||
COMPREPLY=( ${COMPREPLY[@]:-} $( compgen -W "$all_path" -- "$cur" ) )
|
||||
}
|
||||
|
||||
# Completion for devlink resource set
|
||||
_devlink_resource_set()
|
||||
{
|
||||
case "$cword" in
|
||||
3)
|
||||
_devlink_direct_complete "dev"
|
||||
return
|
||||
;;
|
||||
4)
|
||||
COMPREPLY=( $( compgen -W "path" -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
5)
|
||||
_devlink_resource_path
|
||||
return
|
||||
;;
|
||||
6)
|
||||
COMPREPLY=( $( compgen -W "size" -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
7)
|
||||
# Integer argument
|
||||
return
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Completion for devlink resource
|
||||
_devlink_resource()
|
||||
{
|
||||
case $command in
|
||||
show)
|
||||
if [[ $cword -eq 3 ]]; then
|
||||
_devlink_direct_complete "dev"
|
||||
fi
|
||||
return
|
||||
;;
|
||||
set)
|
||||
_devlink_resource_set
|
||||
return
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Completion for devlink region read
|
||||
_devlink_region_read()
|
||||
{
|
||||
case "$cword" in
|
||||
6)
|
||||
COMPREPLY=( $( compgen -W "address" -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
7)
|
||||
# Address argument, for example: 0x10
|
||||
return
|
||||
;;
|
||||
8)
|
||||
COMPREPLY=( $( compgen -W "length" -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
9)
|
||||
# Integer argument
|
||||
return
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Completion for devlink region
|
||||
_devlink_region()
|
||||
{
|
||||
if [[ $cword -eq 3 && $command != "help" ]]; then
|
||||
_devlink_direct_complete "region"
|
||||
fi
|
||||
|
||||
case $command in
|
||||
show)
|
||||
return
|
||||
;;
|
||||
del|dump|read)
|
||||
case "$cword" in
|
||||
4)
|
||||
COMPREPLY=( $( compgen -W "snapshot" -- "$cur" ) )
|
||||
;;
|
||||
5)
|
||||
_devlink_direct_complete "snapshot"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [[ $command == "read" ]]; then
|
||||
_devlink_region_read
|
||||
fi
|
||||
return
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Completion reporter for devlink health
|
||||
_devlink_health_reporter()
|
||||
{
|
||||
local i=$1; shift
|
||||
|
||||
case $cword in
|
||||
$((3 + $i)))
|
||||
_devlink_direct_complete "health_dev"
|
||||
;;
|
||||
$((4 + $i)))
|
||||
COMPREPLY=( $( compgen -W "reporter" -- "$cur" ) )
|
||||
;;
|
||||
$((5 + $i)))
|
||||
_devlink_direct_complete "reporter"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Completion for devlink health
|
||||
_devlink_health()
|
||||
{
|
||||
case $command in
|
||||
show|recover|diagnose|set)
|
||||
_devlink_health_reporter 0
|
||||
if [[ $command == "set" ]]; then
|
||||
case $cword in
|
||||
6)
|
||||
COMPREPLY=( $( compgen -W "grace_period auto_recover" \
|
||||
-- "$cur" ) )
|
||||
;;
|
||||
7)
|
||||
case $prev in
|
||||
grace_period)
|
||||
# Integer argument- msec
|
||||
;;
|
||||
auto_recover)
|
||||
COMPREPLY=( $( compgen -W "true false" -- \
|
||||
"$cur" ) )
|
||||
;;
|
||||
esac
|
||||
esac
|
||||
fi
|
||||
return
|
||||
;;
|
||||
dump)
|
||||
if [[ $cword -eq 3 ]]; then
|
||||
COMPREPLY=( $( compgen -W "show clear" -- "$cur" ) )
|
||||
fi
|
||||
|
||||
_devlink_health_reporter 1
|
||||
return
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Completion for action in devlink trap set
|
||||
_devlink_trap_set_action()
|
||||
{
|
||||
local i=$1; shift
|
||||
|
||||
case $cword in
|
||||
$((6 + $i)))
|
||||
COMPREPLY=( $( compgen -W "action" -- "$cur" ) )
|
||||
;;
|
||||
$((7 + $i)))
|
||||
COMPREPLY=( $( compgen -W "trap drop" -- "$cur" ) )
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Completion for devlink trap group set
|
||||
_devlink_trap_group_set()
|
||||
{
|
||||
local -A settings=(
|
||||
[action]=notseen
|
||||
[policer]=notseen
|
||||
[nopolicer]=notseen
|
||||
)
|
||||
|
||||
if [[ $cword -eq 7 ]]; then
|
||||
COMPREPLY=( $( compgen -W "action policer nopolicer" -- "$cur" ) )
|
||||
fi
|
||||
|
||||
# Mark seen settings
|
||||
local word
|
||||
for word in "${words[@]:7:${#words[@]}-1}"; do
|
||||
if [[ -n $word ]]; then
|
||||
if [[ "${settings[$word]}" ]]; then
|
||||
settings[$word]=seen
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
case $prev in
|
||||
action)
|
||||
COMPREPLY=( $( compgen -W "trap drop" -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
policer)
|
||||
_devlink_direct_complete "trap_policer"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
|
||||
local -a comp_words=()
|
||||
|
||||
# Add settings not seen to completions
|
||||
local setting
|
||||
for setting in "${!settings[@]}"; do
|
||||
if [ "${settings[$setting]}" = notseen ]; then
|
||||
comp_words+=( "$setting" )
|
||||
fi
|
||||
done
|
||||
|
||||
COMPREPLY=( $( compgen -W "${comp_words[*]}" -- "$cur" ) )
|
||||
}
|
||||
|
||||
# Completion for devlink trap group
|
||||
_devlink_trap_group()
|
||||
{
|
||||
case $cword in
|
||||
3)
|
||||
COMPREPLY=( $( compgen -W "set show" -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
4)
|
||||
_devlink_direct_complete "dev"
|
||||
return
|
||||
;;
|
||||
5)
|
||||
COMPREPLY=( $( compgen -W "group" -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
6)
|
||||
_devlink_direct_complete "trap_group"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
|
||||
if [[ ${words[3]} == "set" ]]; then
|
||||
_devlink_trap_group_set
|
||||
fi
|
||||
}
|
||||
|
||||
# Completion for devlink trap policer set
|
||||
_devlink_trap_policer_set()
|
||||
{
|
||||
local -A settings=(
|
||||
[rate]=notseen
|
||||
[burst]=notseen
|
||||
)
|
||||
|
||||
if [[ $cword -eq 7 ]]; then
|
||||
COMPREPLY=( $( compgen -W "rate burst" -- "$cur" ) )
|
||||
fi
|
||||
|
||||
# Mark seen settings
|
||||
local word
|
||||
for word in "${words[@]:7:${#words[@]}-1}"; do
|
||||
if [[ -n $word ]]; then
|
||||
if [[ "${settings[$word]}" ]]; then
|
||||
settings[$word]=seen
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
case $prev in
|
||||
rate)
|
||||
# Integer argument
|
||||
return
|
||||
;;
|
||||
burst)
|
||||
# Integer argument
|
||||
return
|
||||
;;
|
||||
esac
|
||||
|
||||
local -a comp_words=()
|
||||
|
||||
# Add settings not seen to completions
|
||||
local setting
|
||||
for setting in "${!settings[@]}"; do
|
||||
if [ "${settings[$setting]}" = notseen ]; then
|
||||
comp_words+=( "$setting" )
|
||||
fi
|
||||
done
|
||||
|
||||
COMPREPLY=( $( compgen -W "${comp_words[*]}" -- "$cur" ) )
|
||||
}
|
||||
|
||||
# Completion for devlink trap policer
|
||||
_devlink_trap_policer()
|
||||
{
|
||||
case $cword in
|
||||
3)
|
||||
COMPREPLY=( $( compgen -W "set show" -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
4)
|
||||
_devlink_direct_complete "dev"
|
||||
return
|
||||
;;
|
||||
5)
|
||||
COMPREPLY=( $( compgen -W "policer" -- "$cur" ) )
|
||||
return
|
||||
;;
|
||||
6)
|
||||
_devlink_direct_complete "trap_policer"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
|
||||
if [[ ${words[3]} == "set" ]]; then
|
||||
_devlink_trap_policer_set
|
||||
fi
|
||||
}
|
||||
|
||||
# Completion for devlink trap
|
||||
_devlink_trap()
|
||||
{
|
||||
case $command in
|
||||
show|set)
|
||||
case $cword in
|
||||
3)
|
||||
_devlink_direct_complete "dev"
|
||||
;;
|
||||
4)
|
||||
COMPREPLY=( $( compgen -W "trap" -- "$cur" ) )
|
||||
;;
|
||||
5)
|
||||
_devlink_direct_complete "trap"
|
||||
;;
|
||||
esac
|
||||
|
||||
if [[ $command == "set" ]]; then
|
||||
_devlink_trap_set_action 0
|
||||
fi
|
||||
return
|
||||
;;
|
||||
group)
|
||||
_devlink_trap_$command
|
||||
return
|
||||
;;
|
||||
policer)
|
||||
_devlink_trap_$command
|
||||
return
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Complete any devlink command
|
||||
_devlink()
|
||||
{
|
||||
local cur prev words cword
|
||||
local opt='--Version --no-nice-names --json --pretty --verbose \
|
||||
--statistics --force --Netns --batch'
|
||||
local objects="$(devlink help 2>&1 | command sed -e '/OBJECT := /!d' \
|
||||
-e 's/.*{//' -e 's/}.*//' -e \ 's/|//g' )"
|
||||
|
||||
_init_completion || return
|
||||
# Gets the word-to-complete without considering the colon as word breaks
|
||||
_get_comp_words_by_ref -n : cur prev words cword
|
||||
|
||||
if [[ $cword -eq 1 ]]; then
|
||||
case $cur in
|
||||
-*)
|
||||
COMPREPLY=( $( compgen -W "$opt" -- "$cur" ) )
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
COMPREPLY=( $( compgen -W "$objects" -- "$cur" ) )
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Deal with options
|
||||
if [[ $prev == -* ]]; then
|
||||
case $prev in
|
||||
-V|--Version)
|
||||
return 0
|
||||
;;
|
||||
-b|--batch)
|
||||
_filedir
|
||||
return 0
|
||||
;;
|
||||
--force)
|
||||
COMPREPLY=( $( compgen -W "--batch" -- "$cur" ) )
|
||||
return 0
|
||||
;;
|
||||
-N|--Netns)
|
||||
local nslist=$( ip netns list 2>/dev/null )
|
||||
COMPREPLY=( $( compgen -W "$nslist" -- "$cur" ) )
|
||||
return 0
|
||||
;;
|
||||
-j|--json)
|
||||
COMPREPLY=( $( compgen -W "--pretty $objects" -- "$cur" ) )
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
COMPREPLY=( $( compgen -W "$objects" -- "$cur" ) )
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Remove all options so completions don't have to deal with them.
|
||||
local i
|
||||
for (( i=1; i < ${#words[@]}; )); do
|
||||
if [[ ${words[i]::1} == - ]]; then
|
||||
words=( "${words[@]:0:i}" "${words[@]:i+1}" )
|
||||
[[ $i -le $cword ]] && cword=$(( cword - 1 ))
|
||||
else
|
||||
i=$(( ++i ))
|
||||
fi
|
||||
done
|
||||
|
||||
local object=${words[1]}
|
||||
local command=${words[2]}
|
||||
local pprev=${words[cword - 2]}
|
||||
|
||||
if [[ $objects =~ $object ]]; then
|
||||
if [[ $cword -eq 2 ]]; then
|
||||
COMPREPLY=( $( compgen -W "help" -- "$cur") )
|
||||
if [[ $object != "monitor" && $object != "dpipe" ]]; then
|
||||
COMPREPLY+=( $( compgen -W \
|
||||
"$(_devlink_get_optional_commands $object)" -- "$cur" ) )
|
||||
fi
|
||||
fi
|
||||
"_devlink_$object"
|
||||
fi
|
||||
|
||||
} &&
|
||||
complete -F _devlink devlink
|
||||
|
||||
# ex: ts=4 sw=4 et filetype=sh
|
||||
|
|
@ -262,6 +262,9 @@ static void ifname_map_free(struct ifname_map *ifname_map)
|
|||
#define DL_OPT_TRAP_ACTION BIT(31)
|
||||
#define DL_OPT_TRAP_GROUP_NAME BIT(32)
|
||||
#define DL_OPT_NETNS BIT(33)
|
||||
#define DL_OPT_TRAP_POLICER_ID BIT(34)
|
||||
#define DL_OPT_TRAP_POLICER_RATE BIT(35)
|
||||
#define DL_OPT_TRAP_POLICER_BURST BIT(36)
|
||||
|
||||
struct dl_opts {
|
||||
uint64_t present; /* flags of present items */
|
||||
|
|
@ -303,6 +306,9 @@ struct dl_opts {
|
|||
enum devlink_trap_action trap_action;
|
||||
bool netns_is_pid;
|
||||
uint32_t netns;
|
||||
uint32_t trap_policer_id;
|
||||
uint64_t trap_policer_rate;
|
||||
uint64_t trap_policer_burst;
|
||||
};
|
||||
|
||||
struct dl {
|
||||
|
|
@ -506,12 +512,16 @@ static const enum mnl_attr_data_type devlink_policy[DEVLINK_ATTR_MAX + 1] = {
|
|||
[DEVLINK_ATTR_TRAP_METADATA] = MNL_TYPE_NESTED,
|
||||
[DEVLINK_ATTR_TRAP_GROUP_NAME] = MNL_TYPE_STRING,
|
||||
[DEVLINK_ATTR_RELOAD_FAILED] = MNL_TYPE_U8,
|
||||
[DEVLINK_ATTR_TRAP_POLICER_ID] = MNL_TYPE_U32,
|
||||
[DEVLINK_ATTR_TRAP_POLICER_RATE] = MNL_TYPE_U64,
|
||||
[DEVLINK_ATTR_TRAP_POLICER_BURST] = MNL_TYPE_U64,
|
||||
};
|
||||
|
||||
static const enum mnl_attr_data_type
|
||||
devlink_stats_policy[DEVLINK_ATTR_STATS_MAX + 1] = {
|
||||
[DEVLINK_ATTR_STATS_RX_PACKETS] = MNL_TYPE_U64,
|
||||
[DEVLINK_ATTR_STATS_RX_BYTES] = MNL_TYPE_U64,
|
||||
[DEVLINK_ATTR_STATS_RX_DROPPED] = MNL_TYPE_U64,
|
||||
};
|
||||
|
||||
static int attr_cb(const struct nlattr *attr, void *data)
|
||||
|
|
@ -1490,6 +1500,32 @@ static int dl_argv_parse(struct dl *dl, uint64_t o_required,
|
|||
opts->netns_is_pid = true;
|
||||
}
|
||||
o_found |= DL_OPT_NETNS;
|
||||
} else if (dl_argv_match(dl, "policer") &&
|
||||
(o_all & DL_OPT_TRAP_POLICER_ID)) {
|
||||
dl_arg_inc(dl);
|
||||
err = dl_argv_uint32_t(dl, &opts->trap_policer_id);
|
||||
if (err)
|
||||
return err;
|
||||
o_found |= DL_OPT_TRAP_POLICER_ID;
|
||||
} else if (dl_argv_match(dl, "nopolicer") &&
|
||||
(o_all & DL_OPT_TRAP_POLICER_ID)) {
|
||||
dl_arg_inc(dl);
|
||||
opts->trap_policer_id = 0;
|
||||
o_found |= DL_OPT_TRAP_POLICER_ID;
|
||||
} else if (dl_argv_match(dl, "rate") &&
|
||||
(o_all & DL_OPT_TRAP_POLICER_RATE)) {
|
||||
dl_arg_inc(dl);
|
||||
err = dl_argv_uint64_t(dl, &opts->trap_policer_rate);
|
||||
if (err)
|
||||
return err;
|
||||
o_found |= DL_OPT_TRAP_POLICER_RATE;
|
||||
} else if (dl_argv_match(dl, "burst") &&
|
||||
(o_all & DL_OPT_TRAP_POLICER_BURST)) {
|
||||
dl_arg_inc(dl);
|
||||
err = dl_argv_uint64_t(dl, &opts->trap_policer_burst);
|
||||
if (err)
|
||||
return err;
|
||||
o_found |= DL_OPT_TRAP_POLICER_BURST;
|
||||
} else {
|
||||
pr_err("Unknown option \"%s\"\n", dl_argv(dl));
|
||||
return -EINVAL;
|
||||
|
|
@ -1617,6 +1653,15 @@ static void dl_opts_put(struct nlmsghdr *nlh, struct dl *dl)
|
|||
opts->netns_is_pid ? DEVLINK_ATTR_NETNS_PID :
|
||||
DEVLINK_ATTR_NETNS_FD,
|
||||
opts->netns);
|
||||
if (opts->present & DL_OPT_TRAP_POLICER_ID)
|
||||
mnl_attr_put_u32(nlh, DEVLINK_ATTR_TRAP_POLICER_ID,
|
||||
opts->trap_policer_id);
|
||||
if (opts->present & DL_OPT_TRAP_POLICER_RATE)
|
||||
mnl_attr_put_u64(nlh, DEVLINK_ATTR_TRAP_POLICER_RATE,
|
||||
opts->trap_policer_rate);
|
||||
if (opts->present & DL_OPT_TRAP_POLICER_BURST)
|
||||
mnl_attr_put_u64(nlh, DEVLINK_ATTR_TRAP_POLICER_BURST,
|
||||
opts->trap_policer_burst);
|
||||
}
|
||||
|
||||
static int dl_argv_parse_put(struct nlmsghdr *nlh, struct dl *dl,
|
||||
|
|
@ -2058,6 +2103,9 @@ static void pr_out_stats(struct dl *dl, struct nlattr *nla_stats)
|
|||
if (tb[DEVLINK_ATTR_STATS_RX_PACKETS])
|
||||
pr_out_u64(dl, "packets",
|
||||
mnl_attr_get_u64(tb[DEVLINK_ATTR_STATS_RX_PACKETS]));
|
||||
if (tb[DEVLINK_ATTR_STATS_RX_DROPPED])
|
||||
pr_out_u64(dl, "dropped",
|
||||
mnl_attr_get_u64(tb[DEVLINK_ATTR_STATS_RX_DROPPED]));
|
||||
pr_out_object_end(dl);
|
||||
pr_out_object_end(dl);
|
||||
}
|
||||
|
|
@ -3150,6 +3198,8 @@ static const char *port_flavour_name(uint16_t flavour)
|
|||
return "pcipf";
|
||||
case DEVLINK_PORT_FLAVOUR_PCI_VF:
|
||||
return "pcivf";
|
||||
case DEVLINK_PORT_FLAVOUR_VIRTUAL:
|
||||
return "virtual";
|
||||
default:
|
||||
return "<unknown flavour>";
|
||||
}
|
||||
|
|
@ -4130,6 +4180,7 @@ static const char *cmd_name(uint8_t cmd)
|
|||
case DEVLINK_CMD_FLASH_UPDATE: return "begin";
|
||||
case DEVLINK_CMD_FLASH_UPDATE_END: return "end";
|
||||
case DEVLINK_CMD_FLASH_UPDATE_STATUS: return "status";
|
||||
case DEVLINK_CMD_HEALTH_REPORTER_RECOVER: return "status";
|
||||
case DEVLINK_CMD_TRAP_GET: return "get";
|
||||
case DEVLINK_CMD_TRAP_SET: return "set";
|
||||
case DEVLINK_CMD_TRAP_NEW: return "new";
|
||||
|
|
@ -4138,6 +4189,10 @@ static const char *cmd_name(uint8_t cmd)
|
|||
case DEVLINK_CMD_TRAP_GROUP_SET: return "set";
|
||||
case DEVLINK_CMD_TRAP_GROUP_NEW: return "new";
|
||||
case DEVLINK_CMD_TRAP_GROUP_DEL: return "del";
|
||||
case DEVLINK_CMD_TRAP_POLICER_GET: return "get";
|
||||
case DEVLINK_CMD_TRAP_POLICER_SET: return "set";
|
||||
case DEVLINK_CMD_TRAP_POLICER_NEW: return "new";
|
||||
case DEVLINK_CMD_TRAP_POLICER_DEL: return "del";
|
||||
default: return "<unknown cmd>";
|
||||
}
|
||||
}
|
||||
|
|
@ -4170,6 +4225,8 @@ static const char *cmd_obj(uint8_t cmd)
|
|||
case DEVLINK_CMD_FLASH_UPDATE_END:
|
||||
case DEVLINK_CMD_FLASH_UPDATE_STATUS:
|
||||
return "flash";
|
||||
case DEVLINK_CMD_HEALTH_REPORTER_RECOVER:
|
||||
return "health";
|
||||
case DEVLINK_CMD_TRAP_GET:
|
||||
case DEVLINK_CMD_TRAP_SET:
|
||||
case DEVLINK_CMD_TRAP_NEW:
|
||||
|
|
@ -4180,6 +4237,11 @@ static const char *cmd_obj(uint8_t cmd)
|
|||
case DEVLINK_CMD_TRAP_GROUP_NEW:
|
||||
case DEVLINK_CMD_TRAP_GROUP_DEL:
|
||||
return "trap-group";
|
||||
case DEVLINK_CMD_TRAP_POLICER_GET:
|
||||
case DEVLINK_CMD_TRAP_POLICER_SET:
|
||||
case DEVLINK_CMD_TRAP_POLICER_NEW:
|
||||
case DEVLINK_CMD_TRAP_POLICER_DEL:
|
||||
return "trap-policer";
|
||||
default: return "<unknown obj>";
|
||||
}
|
||||
}
|
||||
|
|
@ -4231,8 +4293,10 @@ static void pr_out_flash_update(struct dl *dl, struct nlattr **tb)
|
|||
}
|
||||
|
||||
static void pr_out_region(struct dl *dl, struct nlattr **tb);
|
||||
static void pr_out_health(struct dl *dl, struct nlattr **tb_health);
|
||||
static void pr_out_trap(struct dl *dl, struct nlattr **tb, bool array);
|
||||
static void pr_out_trap_group(struct dl *dl, struct nlattr **tb, bool array);
|
||||
static void pr_out_trap_policer(struct dl *dl, struct nlattr **tb, bool array);
|
||||
|
||||
static int cmd_mon_show_cb(const struct nlmsghdr *nlh, void *data)
|
||||
{
|
||||
|
|
@ -4297,6 +4361,14 @@ static int cmd_mon_show_cb(const struct nlmsghdr *nlh, void *data)
|
|||
pr_out_mon_header(genl->cmd);
|
||||
pr_out_flash_update(dl, tb);
|
||||
break;
|
||||
case DEVLINK_CMD_HEALTH_REPORTER_RECOVER:
|
||||
mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
|
||||
if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] ||
|
||||
!tb[DEVLINK_ATTR_HEALTH_REPORTER])
|
||||
return MNL_CB_ERROR;
|
||||
pr_out_mon_header(genl->cmd);
|
||||
pr_out_health(dl, tb);
|
||||
break;
|
||||
case DEVLINK_CMD_TRAP_GET: /* fall through */
|
||||
case DEVLINK_CMD_TRAP_SET: /* fall through */
|
||||
case DEVLINK_CMD_TRAP_NEW: /* fall through */
|
||||
|
|
@ -4325,6 +4397,19 @@ static int cmd_mon_show_cb(const struct nlmsghdr *nlh, void *data)
|
|||
pr_out_mon_header(genl->cmd);
|
||||
pr_out_trap_group(dl, tb, false);
|
||||
break;
|
||||
case DEVLINK_CMD_TRAP_POLICER_GET: /* fall through */
|
||||
case DEVLINK_CMD_TRAP_POLICER_SET: /* fall through */
|
||||
case DEVLINK_CMD_TRAP_POLICER_NEW: /* fall through */
|
||||
case DEVLINK_CMD_TRAP_POLICER_DEL: /* fall through */
|
||||
mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
|
||||
if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] ||
|
||||
!tb[DEVLINK_ATTR_TRAP_POLICER_ID] ||
|
||||
!tb[DEVLINK_ATTR_TRAP_POLICER_RATE] ||
|
||||
!tb[DEVLINK_ATTR_TRAP_POLICER_BURST])
|
||||
return MNL_CB_ERROR;
|
||||
pr_out_mon_header(genl->cmd);
|
||||
pr_out_trap_policer(dl, tb, false);
|
||||
break;
|
||||
}
|
||||
return MNL_CB_OK;
|
||||
}
|
||||
|
|
@ -4339,8 +4424,10 @@ static int cmd_mon_show(struct dl *dl)
|
|||
if (strcmp(cur_obj, "all") != 0 &&
|
||||
strcmp(cur_obj, "dev") != 0 &&
|
||||
strcmp(cur_obj, "port") != 0 &&
|
||||
strcmp(cur_obj, "health") != 0 &&
|
||||
strcmp(cur_obj, "trap") != 0 &&
|
||||
strcmp(cur_obj, "trap-group") != 0) {
|
||||
strcmp(cur_obj, "trap-group") != 0 &&
|
||||
strcmp(cur_obj, "trap-policer") != 0) {
|
||||
pr_err("Unknown object \"%s\"\n", cur_obj);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -4357,7 +4444,7 @@ static int cmd_mon_show(struct dl *dl)
|
|||
static void cmd_mon_help(void)
|
||||
{
|
||||
pr_err("Usage: devlink monitor [ all | OBJECT-LIST ]\n"
|
||||
"where OBJECT-LIST := { dev | port | trap | trap-group }\n");
|
||||
"where OBJECT-LIST := { dev | port | health | trap | trap-group | trap-policer }\n");
|
||||
}
|
||||
|
||||
static int cmd_mon(struct dl *dl)
|
||||
|
|
@ -6919,6 +7006,8 @@ static const char *trap_metadata_name(const struct nlattr *attr)
|
|||
switch (attr->nla_type) {
|
||||
case DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT:
|
||||
return "input_port";
|
||||
case DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE:
|
||||
return "flow_action_cookie";
|
||||
default:
|
||||
return "<unknown metadata type>";
|
||||
}
|
||||
|
|
@ -6984,7 +7073,10 @@ static void cmd_trap_help(void)
|
|||
pr_err("Usage: devlink trap set DEV trap TRAP [ action { trap | drop } ]\n");
|
||||
pr_err(" devlink trap show [ DEV trap TRAP ]\n");
|
||||
pr_err(" devlink trap group set DEV group GROUP [ action { trap | drop } ]\n");
|
||||
pr_err(" [ policer POLICER ] [ nopolicer ]\n");
|
||||
pr_err(" devlink trap group show [ DEV group GROUP ]\n");
|
||||
pr_err(" devlink trap policer set DEV policer POLICER [ rate RATE ] [ burst BURST ]\n");
|
||||
pr_err(" devlink trap policer show DEV policer POLICER\n");
|
||||
}
|
||||
|
||||
static int cmd_trap_show(struct dl *dl)
|
||||
|
|
@ -7039,6 +7131,9 @@ static void pr_out_trap_group(struct dl *dl, struct nlattr **tb, bool array)
|
|||
print_string(PRINT_ANY, "name", "name %s",
|
||||
mnl_attr_get_str(tb[DEVLINK_ATTR_TRAP_GROUP_NAME]));
|
||||
print_bool(PRINT_ANY, "generic", " generic %s", !!tb[DEVLINK_ATTR_TRAP_GENERIC]);
|
||||
if (tb[DEVLINK_ATTR_TRAP_POLICER_ID])
|
||||
print_uint(PRINT_ANY, "policer", " policer %u",
|
||||
mnl_attr_get_u32(tb[DEVLINK_ATTR_TRAP_POLICER_ID]));
|
||||
pr_out_stats(dl, tb[DEVLINK_ATTR_STATS]);
|
||||
pr_out_handle_end(dl);
|
||||
}
|
||||
|
|
@ -7095,7 +7190,7 @@ static int cmd_trap_group_set(struct dl *dl)
|
|||
|
||||
err = dl_argv_parse_put(nlh, dl,
|
||||
DL_OPT_HANDLE | DL_OPT_TRAP_GROUP_NAME,
|
||||
DL_OPT_TRAP_ACTION);
|
||||
DL_OPT_TRAP_ACTION | DL_OPT_TRAP_POLICER_ID);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
@ -7119,6 +7214,104 @@ static int cmd_trap_group(struct dl *dl)
|
|||
return -ENOENT;
|
||||
}
|
||||
|
||||
static void pr_out_trap_policer(struct dl *dl, struct nlattr **tb, bool array)
|
||||
{
|
||||
if (array)
|
||||
pr_out_handle_start_arr(dl, tb);
|
||||
else
|
||||
__pr_out_handle_start(dl, tb, true, false);
|
||||
|
||||
check_indent_newline(dl);
|
||||
print_uint(PRINT_ANY, "policer", "policer %u",
|
||||
mnl_attr_get_u32(tb[DEVLINK_ATTR_TRAP_POLICER_ID]));
|
||||
print_u64(PRINT_ANY, "rate", " rate %llu",
|
||||
mnl_attr_get_u64(tb[DEVLINK_ATTR_TRAP_POLICER_RATE]));
|
||||
print_u64(PRINT_ANY, "burst", " burst %llu",
|
||||
mnl_attr_get_u64(tb[DEVLINK_ATTR_TRAP_POLICER_BURST]));
|
||||
if (tb[DEVLINK_ATTR_STATS])
|
||||
pr_out_stats(dl, tb[DEVLINK_ATTR_STATS]);
|
||||
pr_out_handle_end(dl);
|
||||
}
|
||||
|
||||
static int cmd_trap_policer_show_cb(const struct nlmsghdr *nlh, void *data)
|
||||
{
|
||||
struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh);
|
||||
struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
|
||||
struct dl *dl = data;
|
||||
|
||||
mnl_attr_parse(nlh, sizeof(*genl), attr_cb, tb);
|
||||
if (!tb[DEVLINK_ATTR_BUS_NAME] || !tb[DEVLINK_ATTR_DEV_NAME] ||
|
||||
!tb[DEVLINK_ATTR_TRAP_POLICER_ID] ||
|
||||
!tb[DEVLINK_ATTR_TRAP_POLICER_RATE] ||
|
||||
!tb[DEVLINK_ATTR_TRAP_POLICER_BURST])
|
||||
return MNL_CB_ERROR;
|
||||
|
||||
pr_out_trap_policer(dl, tb, true);
|
||||
|
||||
return MNL_CB_OK;
|
||||
}
|
||||
|
||||
static int cmd_trap_policer_show(struct dl *dl)
|
||||
{
|
||||
uint16_t flags = NLM_F_REQUEST | NLM_F_ACK;
|
||||
struct nlmsghdr *nlh;
|
||||
int err;
|
||||
|
||||
if (dl_argc(dl) == 0)
|
||||
flags |= NLM_F_DUMP;
|
||||
|
||||
nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_TRAP_POLICER_GET, flags);
|
||||
|
||||
if (dl_argc(dl) > 0) {
|
||||
err = dl_argv_parse_put(nlh, dl,
|
||||
DL_OPT_HANDLE | DL_OPT_TRAP_POLICER_ID,
|
||||
0);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
pr_out_section_start(dl, "trap_policer");
|
||||
err = _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_trap_policer_show_cb, dl);
|
||||
pr_out_section_end(dl);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int cmd_trap_policer_set(struct dl *dl)
|
||||
{
|
||||
struct nlmsghdr *nlh;
|
||||
int err;
|
||||
|
||||
nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_TRAP_POLICER_SET,
|
||||
NLM_F_REQUEST | NLM_F_ACK);
|
||||
|
||||
err = dl_argv_parse_put(nlh, dl,
|
||||
DL_OPT_HANDLE | DL_OPT_TRAP_POLICER_ID,
|
||||
DL_OPT_TRAP_POLICER_RATE |
|
||||
DL_OPT_TRAP_POLICER_BURST);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return _mnlg_socket_sndrcv(dl->nlg, nlh, NULL, NULL);
|
||||
}
|
||||
|
||||
static int cmd_trap_policer(struct dl *dl)
|
||||
{
|
||||
if (dl_argv_match(dl, "help")) {
|
||||
cmd_trap_help();
|
||||
return 0;
|
||||
} else if (dl_argv_match(dl, "show") ||
|
||||
dl_argv_match(dl, "list") || dl_no_arg(dl)) {
|
||||
dl_arg_inc(dl);
|
||||
return cmd_trap_policer_show(dl);
|
||||
} else if (dl_argv_match(dl, "set")) {
|
||||
dl_arg_inc(dl);
|
||||
return cmd_trap_policer_set(dl);
|
||||
}
|
||||
pr_err("Command \"%s\" not found\n", dl_argv(dl));
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static int cmd_trap(struct dl *dl)
|
||||
{
|
||||
if (dl_argv_match(dl, "help")) {
|
||||
|
|
@ -7134,6 +7327,9 @@ static int cmd_trap(struct dl *dl)
|
|||
} else if (dl_argv_match(dl, "group")) {
|
||||
dl_arg_inc(dl);
|
||||
return cmd_trap_group(dl);
|
||||
} else if (dl_argv_match(dl, "policer")) {
|
||||
dl_arg_inc(dl);
|
||||
return cmd_trap_policer(dl);
|
||||
}
|
||||
pr_err("Command \"%s\" not found\n", dl_argv(dl));
|
||||
return -ENOENT;
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ struct bpf_insn {
|
|||
/* Key of an a BPF_MAP_TYPE_LPM_TRIE entry */
|
||||
struct bpf_lpm_trie_key {
|
||||
__u32 prefixlen; /* up to 32 for AF_INET, 128 for AF_INET6 */
|
||||
__u8 data[0]; /* Arbitrary size */
|
||||
__u8 data[]; /* Arbitrary size */
|
||||
};
|
||||
|
||||
struct bpf_cgroup_storage_key {
|
||||
|
|
@ -111,6 +111,8 @@ enum bpf_cmd {
|
|||
BPF_MAP_LOOKUP_AND_DELETE_BATCH,
|
||||
BPF_MAP_UPDATE_BATCH,
|
||||
BPF_MAP_DELETE_BATCH,
|
||||
BPF_LINK_CREATE,
|
||||
BPF_LINK_UPDATE,
|
||||
};
|
||||
|
||||
enum bpf_map_type {
|
||||
|
|
@ -181,6 +183,7 @@ enum bpf_prog_type {
|
|||
BPF_PROG_TYPE_TRACING,
|
||||
BPF_PROG_TYPE_STRUCT_OPS,
|
||||
BPF_PROG_TYPE_EXT,
|
||||
BPF_PROG_TYPE_LSM,
|
||||
};
|
||||
|
||||
enum bpf_attach_type {
|
||||
|
|
@ -210,6 +213,8 @@ enum bpf_attach_type {
|
|||
BPF_TRACE_RAW_TP,
|
||||
BPF_TRACE_FENTRY,
|
||||
BPF_TRACE_FEXIT,
|
||||
BPF_MODIFY_RETURN,
|
||||
BPF_LSM_MAC,
|
||||
__MAX_BPF_ATTACH_TYPE
|
||||
};
|
||||
|
||||
|
|
@ -325,44 +330,46 @@ enum bpf_attach_type {
|
|||
#define BPF_PSEUDO_CALL 1
|
||||
|
||||
/* flags for BPF_MAP_UPDATE_ELEM command */
|
||||
#define BPF_ANY 0 /* create new element or update existing */
|
||||
#define BPF_NOEXIST 1 /* create new element if it didn't exist */
|
||||
#define BPF_EXIST 2 /* update existing element */
|
||||
#define BPF_F_LOCK 4 /* spin_lock-ed map_lookup/map_update */
|
||||
enum {
|
||||
BPF_ANY = 0, /* create new element or update existing */
|
||||
BPF_NOEXIST = 1, /* create new element if it didn't exist */
|
||||
BPF_EXIST = 2, /* update existing element */
|
||||
BPF_F_LOCK = 4, /* spin_lock-ed map_lookup/map_update */
|
||||
};
|
||||
|
||||
/* flags for BPF_MAP_CREATE command */
|
||||
#define BPF_F_NO_PREALLOC (1U << 0)
|
||||
enum {
|
||||
BPF_F_NO_PREALLOC = (1U << 0),
|
||||
/* Instead of having one common LRU list in the
|
||||
* BPF_MAP_TYPE_LRU_[PERCPU_]HASH map, use a percpu LRU list
|
||||
* which can scale and perform better.
|
||||
* Note, the LRU nodes (including free nodes) cannot be moved
|
||||
* across different LRU lists.
|
||||
*/
|
||||
#define BPF_F_NO_COMMON_LRU (1U << 1)
|
||||
BPF_F_NO_COMMON_LRU = (1U << 1),
|
||||
/* Specify numa node during map creation */
|
||||
#define BPF_F_NUMA_NODE (1U << 2)
|
||||
|
||||
#define BPF_OBJ_NAME_LEN 16U
|
||||
BPF_F_NUMA_NODE = (1U << 2),
|
||||
|
||||
/* Flags for accessing BPF object from syscall side. */
|
||||
#define BPF_F_RDONLY (1U << 3)
|
||||
#define BPF_F_WRONLY (1U << 4)
|
||||
BPF_F_RDONLY = (1U << 3),
|
||||
BPF_F_WRONLY = (1U << 4),
|
||||
|
||||
/* Flag for stack_map, store build_id+offset instead of pointer */
|
||||
#define BPF_F_STACK_BUILD_ID (1U << 5)
|
||||
BPF_F_STACK_BUILD_ID = (1U << 5),
|
||||
|
||||
/* Zero-initialize hash function seed. This should only be used for testing. */
|
||||
#define BPF_F_ZERO_SEED (1U << 6)
|
||||
BPF_F_ZERO_SEED = (1U << 6),
|
||||
|
||||
/* Flags for accessing BPF object from program side. */
|
||||
#define BPF_F_RDONLY_PROG (1U << 7)
|
||||
#define BPF_F_WRONLY_PROG (1U << 8)
|
||||
BPF_F_RDONLY_PROG = (1U << 7),
|
||||
BPF_F_WRONLY_PROG = (1U << 8),
|
||||
|
||||
/* Clone map from listener for newly accepted socket */
|
||||
#define BPF_F_CLONE (1U << 9)
|
||||
BPF_F_CLONE = (1U << 9),
|
||||
|
||||
/* Enable memory-mapping BPF map */
|
||||
#define BPF_F_MMAPABLE (1U << 10)
|
||||
BPF_F_MMAPABLE = (1U << 10),
|
||||
};
|
||||
|
||||
/* Flags for BPF_PROG_QUERY. */
|
||||
|
||||
|
|
@ -391,6 +398,8 @@ struct bpf_stack_build_id {
|
|||
};
|
||||
};
|
||||
|
||||
#define BPF_OBJ_NAME_LEN 16U
|
||||
|
||||
union bpf_attr {
|
||||
struct { /* anonymous struct used by BPF_MAP_CREATE command */
|
||||
__u32 map_type; /* one of enum bpf_map_type */
|
||||
|
|
@ -534,7 +543,7 @@ union bpf_attr {
|
|||
__u32 prog_cnt;
|
||||
} query;
|
||||
|
||||
struct {
|
||||
struct { /* anonymous struct used by BPF_RAW_TRACEPOINT_OPEN command */
|
||||
__u64 name;
|
||||
__u32 prog_fd;
|
||||
} raw_tracepoint;
|
||||
|
|
@ -562,6 +571,24 @@ union bpf_attr {
|
|||
__u64 probe_offset; /* output: probe_offset */
|
||||
__u64 probe_addr; /* output: probe_addr */
|
||||
} task_fd_query;
|
||||
|
||||
struct { /* struct used by BPF_LINK_CREATE command */
|
||||
__u32 prog_fd; /* eBPF program to attach */
|
||||
__u32 target_fd; /* object to attach to */
|
||||
__u32 attach_type; /* attach type */
|
||||
__u32 flags; /* extra flags */
|
||||
} link_create;
|
||||
|
||||
struct { /* struct used by BPF_LINK_UPDATE command */
|
||||
__u32 link_fd; /* link fd */
|
||||
/* new program fd to update link with */
|
||||
__u32 new_prog_fd;
|
||||
__u32 flags; /* extra flags */
|
||||
/* expected link's program fd; is specified only if
|
||||
* BPF_F_REPLACE flag is set in flags */
|
||||
__u32 old_prog_fd;
|
||||
} link_update;
|
||||
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
/* The description below is an attempt at providing documentation to eBPF
|
||||
|
|
@ -2890,6 +2917,114 @@ union bpf_attr {
|
|||
* Obtain the 64bit jiffies
|
||||
* Return
|
||||
* The 64 bit jiffies
|
||||
*
|
||||
* int bpf_read_branch_records(struct bpf_perf_event_data *ctx, void *buf, u32 size, u64 flags)
|
||||
* Description
|
||||
* For an eBPF program attached to a perf event, retrieve the
|
||||
* branch records (struct perf_branch_entry) associated to *ctx*
|
||||
* and store it in the buffer pointed by *buf* up to size
|
||||
* *size* bytes.
|
||||
* Return
|
||||
* On success, number of bytes written to *buf*. On error, a
|
||||
* negative value.
|
||||
*
|
||||
* The *flags* can be set to **BPF_F_GET_BRANCH_RECORDS_SIZE** to
|
||||
* instead return the number of bytes required to store all the
|
||||
* branch entries. If this flag is set, *buf* may be NULL.
|
||||
*
|
||||
* **-EINVAL** if arguments invalid or **size** not a multiple
|
||||
* of sizeof(struct perf_branch_entry).
|
||||
*
|
||||
* **-ENOENT** if architecture does not support branch records.
|
||||
*
|
||||
* int bpf_get_ns_current_pid_tgid(u64 dev, u64 ino, struct bpf_pidns_info *nsdata, u32 size)
|
||||
* Description
|
||||
* Returns 0 on success, values for *pid* and *tgid* as seen from the current
|
||||
* *namespace* will be returned in *nsdata*.
|
||||
*
|
||||
* On failure, the returned value is one of the following:
|
||||
*
|
||||
* **-EINVAL** if dev and inum supplied don't match dev_t and inode number
|
||||
* with nsfs of current task, or if dev conversion to dev_t lost high bits.
|
||||
*
|
||||
* **-ENOENT** if pidns does not exists for the current task.
|
||||
*
|
||||
* int bpf_xdp_output(void *ctx, struct bpf_map *map, u64 flags, void *data, u64 size)
|
||||
* Description
|
||||
* Write raw *data* blob into a special BPF perf event held by
|
||||
* *map* of type **BPF_MAP_TYPE_PERF_EVENT_ARRAY**. This perf
|
||||
* event must have the following attributes: **PERF_SAMPLE_RAW**
|
||||
* as **sample_type**, **PERF_TYPE_SOFTWARE** as **type**, and
|
||||
* **PERF_COUNT_SW_BPF_OUTPUT** as **config**.
|
||||
*
|
||||
* The *flags* are used to indicate the index in *map* for which
|
||||
* the value must be put, masked with **BPF_F_INDEX_MASK**.
|
||||
* Alternatively, *flags* can be set to **BPF_F_CURRENT_CPU**
|
||||
* to indicate that the index of the current CPU core should be
|
||||
* used.
|
||||
*
|
||||
* The value to write, of *size*, is passed through eBPF stack and
|
||||
* pointed by *data*.
|
||||
*
|
||||
* *ctx* is a pointer to in-kernel struct xdp_buff.
|
||||
*
|
||||
* This helper is similar to **bpf_perf_eventoutput**\ () but
|
||||
* restricted to raw_tracepoint bpf programs.
|
||||
* Return
|
||||
* 0 on success, or a negative error in case of failure.
|
||||
*
|
||||
* u64 bpf_get_netns_cookie(void *ctx)
|
||||
* Description
|
||||
* Retrieve the cookie (generated by the kernel) of the network
|
||||
* namespace the input *ctx* is associated with. The network
|
||||
* namespace cookie remains stable for its lifetime and provides
|
||||
* a global identifier that can be assumed unique. If *ctx* is
|
||||
* NULL, then the helper returns the cookie for the initial
|
||||
* network namespace. The cookie itself is very similar to that
|
||||
* of bpf_get_socket_cookie() helper, but for network namespaces
|
||||
* instead of sockets.
|
||||
* Return
|
||||
* A 8-byte long opaque number.
|
||||
*
|
||||
* u64 bpf_get_current_ancestor_cgroup_id(int ancestor_level)
|
||||
* Description
|
||||
* Return id of cgroup v2 that is ancestor of the cgroup associated
|
||||
* with the current task at the *ancestor_level*. The root cgroup
|
||||
* is at *ancestor_level* zero and each step down the hierarchy
|
||||
* increments the level. If *ancestor_level* == level of cgroup
|
||||
* associated with the current task, then return value will be the
|
||||
* same as that of **bpf_get_current_cgroup_id**\ ().
|
||||
*
|
||||
* The helper is useful to implement policies based on cgroups
|
||||
* that are upper in hierarchy than immediate cgroup associated
|
||||
* with the current task.
|
||||
*
|
||||
* The format of returned id and helper limitations are same as in
|
||||
* **bpf_get_current_cgroup_id**\ ().
|
||||
* Return
|
||||
* The id is returned or 0 in case the id could not be retrieved.
|
||||
*
|
||||
* int bpf_sk_assign(struct sk_buff *skb, struct bpf_sock *sk, u64 flags)
|
||||
* Description
|
||||
* Assign the *sk* to the *skb*. When combined with appropriate
|
||||
* routing configuration to receive the packet towards the socket,
|
||||
* will cause *skb* to be delivered to the specified socket.
|
||||
* Subsequent redirection of *skb* via **bpf_redirect**\ (),
|
||||
* **bpf_clone_redirect**\ () or other methods outside of BPF may
|
||||
* interfere with successful delivery to the socket.
|
||||
*
|
||||
* This operation is only valid from TC ingress path.
|
||||
*
|
||||
* The *flags* argument must be zero.
|
||||
* Return
|
||||
* 0 on success, or a negative errno in case of failure.
|
||||
*
|
||||
* * **-EINVAL** Unsupported flags specified.
|
||||
* * **-ENOENT** Socket is unavailable for assignment.
|
||||
* * **-ENETUNREACH** Socket is unreachable (wrong netns).
|
||||
* * **-EOPNOTSUPP** Unsupported operation, for example a
|
||||
* call from outside of TC ingress.
|
||||
* * **-ESOCKTNOSUPPORT** Socket type not supported (reuseport).
|
||||
*/
|
||||
#define __BPF_FUNC_MAPPER(FN) \
|
||||
FN(unspec), \
|
||||
|
|
@ -3010,7 +3145,13 @@ union bpf_attr {
|
|||
FN(probe_read_kernel_str), \
|
||||
FN(tcp_send_ack), \
|
||||
FN(send_signal_thread), \
|
||||
FN(jiffies64),
|
||||
FN(jiffies64), \
|
||||
FN(read_branch_records), \
|
||||
FN(get_ns_current_pid_tgid), \
|
||||
FN(xdp_output), \
|
||||
FN(get_netns_cookie), \
|
||||
FN(get_current_ancestor_cgroup_id), \
|
||||
FN(sk_assign),
|
||||
|
||||
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
|
||||
* function eBPF program intends to call
|
||||
|
|
@ -3025,69 +3166,100 @@ enum bpf_func_id {
|
|||
/* All flags used by eBPF helper functions, placed here. */
|
||||
|
||||
/* BPF_FUNC_skb_store_bytes flags. */
|
||||
#define BPF_F_RECOMPUTE_CSUM (1ULL << 0)
|
||||
#define BPF_F_INVALIDATE_HASH (1ULL << 1)
|
||||
enum {
|
||||
BPF_F_RECOMPUTE_CSUM = (1ULL << 0),
|
||||
BPF_F_INVALIDATE_HASH = (1ULL << 1),
|
||||
};
|
||||
|
||||
/* BPF_FUNC_l3_csum_replace and BPF_FUNC_l4_csum_replace flags.
|
||||
* First 4 bits are for passing the header field size.
|
||||
*/
|
||||
#define BPF_F_HDR_FIELD_MASK 0xfULL
|
||||
enum {
|
||||
BPF_F_HDR_FIELD_MASK = 0xfULL,
|
||||
};
|
||||
|
||||
/* BPF_FUNC_l4_csum_replace flags. */
|
||||
#define BPF_F_PSEUDO_HDR (1ULL << 4)
|
||||
#define BPF_F_MARK_MANGLED_0 (1ULL << 5)
|
||||
#define BPF_F_MARK_ENFORCE (1ULL << 6)
|
||||
enum {
|
||||
BPF_F_PSEUDO_HDR = (1ULL << 4),
|
||||
BPF_F_MARK_MANGLED_0 = (1ULL << 5),
|
||||
BPF_F_MARK_ENFORCE = (1ULL << 6),
|
||||
};
|
||||
|
||||
/* BPF_FUNC_clone_redirect and BPF_FUNC_redirect flags. */
|
||||
#define BPF_F_INGRESS (1ULL << 0)
|
||||
enum {
|
||||
BPF_F_INGRESS = (1ULL << 0),
|
||||
};
|
||||
|
||||
/* BPF_FUNC_skb_set_tunnel_key and BPF_FUNC_skb_get_tunnel_key flags. */
|
||||
#define BPF_F_TUNINFO_IPV6 (1ULL << 0)
|
||||
enum {
|
||||
BPF_F_TUNINFO_IPV6 = (1ULL << 0),
|
||||
};
|
||||
|
||||
/* flags for both BPF_FUNC_get_stackid and BPF_FUNC_get_stack. */
|
||||
#define BPF_F_SKIP_FIELD_MASK 0xffULL
|
||||
#define BPF_F_USER_STACK (1ULL << 8)
|
||||
enum {
|
||||
BPF_F_SKIP_FIELD_MASK = 0xffULL,
|
||||
BPF_F_USER_STACK = (1ULL << 8),
|
||||
/* flags used by BPF_FUNC_get_stackid only. */
|
||||
#define BPF_F_FAST_STACK_CMP (1ULL << 9)
|
||||
#define BPF_F_REUSE_STACKID (1ULL << 10)
|
||||
BPF_F_FAST_STACK_CMP = (1ULL << 9),
|
||||
BPF_F_REUSE_STACKID = (1ULL << 10),
|
||||
/* flags used by BPF_FUNC_get_stack only. */
|
||||
#define BPF_F_USER_BUILD_ID (1ULL << 11)
|
||||
BPF_F_USER_BUILD_ID = (1ULL << 11),
|
||||
};
|
||||
|
||||
/* BPF_FUNC_skb_set_tunnel_key flags. */
|
||||
#define BPF_F_ZERO_CSUM_TX (1ULL << 1)
|
||||
#define BPF_F_DONT_FRAGMENT (1ULL << 2)
|
||||
#define BPF_F_SEQ_NUMBER (1ULL << 3)
|
||||
enum {
|
||||
BPF_F_ZERO_CSUM_TX = (1ULL << 1),
|
||||
BPF_F_DONT_FRAGMENT = (1ULL << 2),
|
||||
BPF_F_SEQ_NUMBER = (1ULL << 3),
|
||||
};
|
||||
|
||||
/* BPF_FUNC_perf_event_output, BPF_FUNC_perf_event_read and
|
||||
* BPF_FUNC_perf_event_read_value flags.
|
||||
*/
|
||||
#define BPF_F_INDEX_MASK 0xffffffffULL
|
||||
#define BPF_F_CURRENT_CPU BPF_F_INDEX_MASK
|
||||
enum {
|
||||
BPF_F_INDEX_MASK = 0xffffffffULL,
|
||||
BPF_F_CURRENT_CPU = BPF_F_INDEX_MASK,
|
||||
/* BPF_FUNC_perf_event_output for sk_buff input context. */
|
||||
#define BPF_F_CTXLEN_MASK (0xfffffULL << 32)
|
||||
BPF_F_CTXLEN_MASK = (0xfffffULL << 32),
|
||||
};
|
||||
|
||||
/* Current network namespace */
|
||||
#define BPF_F_CURRENT_NETNS (-1L)
|
||||
enum {
|
||||
BPF_F_CURRENT_NETNS = (-1L),
|
||||
};
|
||||
|
||||
/* BPF_FUNC_skb_adjust_room flags. */
|
||||
#define BPF_F_ADJ_ROOM_FIXED_GSO (1ULL << 0)
|
||||
enum {
|
||||
BPF_F_ADJ_ROOM_FIXED_GSO = (1ULL << 0),
|
||||
BPF_F_ADJ_ROOM_ENCAP_L3_IPV4 = (1ULL << 1),
|
||||
BPF_F_ADJ_ROOM_ENCAP_L3_IPV6 = (1ULL << 2),
|
||||
BPF_F_ADJ_ROOM_ENCAP_L4_GRE = (1ULL << 3),
|
||||
BPF_F_ADJ_ROOM_ENCAP_L4_UDP = (1ULL << 4),
|
||||
};
|
||||
|
||||
#define BPF_ADJ_ROOM_ENCAP_L2_MASK 0xff
|
||||
#define BPF_ADJ_ROOM_ENCAP_L2_SHIFT 56
|
||||
enum {
|
||||
BPF_ADJ_ROOM_ENCAP_L2_MASK = 0xff,
|
||||
BPF_ADJ_ROOM_ENCAP_L2_SHIFT = 56,
|
||||
};
|
||||
|
||||
#define BPF_F_ADJ_ROOM_ENCAP_L3_IPV4 (1ULL << 1)
|
||||
#define BPF_F_ADJ_ROOM_ENCAP_L3_IPV6 (1ULL << 2)
|
||||
#define BPF_F_ADJ_ROOM_ENCAP_L4_GRE (1ULL << 3)
|
||||
#define BPF_F_ADJ_ROOM_ENCAP_L4_UDP (1ULL << 4)
|
||||
#define BPF_F_ADJ_ROOM_ENCAP_L2(len) (((__u64)len & \
|
||||
BPF_ADJ_ROOM_ENCAP_L2_MASK) \
|
||||
<< BPF_ADJ_ROOM_ENCAP_L2_SHIFT)
|
||||
|
||||
/* BPF_FUNC_sysctl_get_name flags. */
|
||||
#define BPF_F_SYSCTL_BASE_NAME (1ULL << 0)
|
||||
enum {
|
||||
BPF_F_SYSCTL_BASE_NAME = (1ULL << 0),
|
||||
};
|
||||
|
||||
/* BPF_FUNC_sk_storage_get flags */
|
||||
#define BPF_SK_STORAGE_GET_F_CREATE (1ULL << 0)
|
||||
enum {
|
||||
BPF_SK_STORAGE_GET_F_CREATE = (1ULL << 0),
|
||||
};
|
||||
|
||||
/* BPF_FUNC_read_branch_records flags. */
|
||||
enum {
|
||||
BPF_F_GET_BRANCH_RECORDS_SIZE = (1ULL << 0),
|
||||
};
|
||||
|
||||
/* Mode for BPF_FUNC_skb_adjust_room helper. */
|
||||
enum bpf_adj_room_mode {
|
||||
|
|
@ -3153,6 +3325,7 @@ struct __sk_buff {
|
|||
__u32 wire_len;
|
||||
__u32 gso_segs;
|
||||
__bpf_md_ptr(struct bpf_sock *, sk);
|
||||
__u32 gso_size;
|
||||
};
|
||||
|
||||
struct bpf_tunnel_key {
|
||||
|
|
@ -3505,13 +3678,14 @@ struct bpf_sock_ops {
|
|||
};
|
||||
|
||||
/* Definitions for bpf_sock_ops_cb_flags */
|
||||
#define BPF_SOCK_OPS_RTO_CB_FLAG (1<<0)
|
||||
#define BPF_SOCK_OPS_RETRANS_CB_FLAG (1<<1)
|
||||
#define BPF_SOCK_OPS_STATE_CB_FLAG (1<<2)
|
||||
#define BPF_SOCK_OPS_RTT_CB_FLAG (1<<3)
|
||||
#define BPF_SOCK_OPS_ALL_CB_FLAGS 0xF /* Mask of all currently
|
||||
* supported cb flags
|
||||
*/
|
||||
enum {
|
||||
BPF_SOCK_OPS_RTO_CB_FLAG = (1<<0),
|
||||
BPF_SOCK_OPS_RETRANS_CB_FLAG = (1<<1),
|
||||
BPF_SOCK_OPS_STATE_CB_FLAG = (1<<2),
|
||||
BPF_SOCK_OPS_RTT_CB_FLAG = (1<<3),
|
||||
/* Mask of all currently supported cb flags */
|
||||
BPF_SOCK_OPS_ALL_CB_FLAGS = 0xF,
|
||||
};
|
||||
|
||||
/* List of known BPF sock_ops operators.
|
||||
* New entries can only be added at the end
|
||||
|
|
@ -3590,8 +3764,10 @@ enum {
|
|||
BPF_TCP_MAX_STATES /* Leave at the end! */
|
||||
};
|
||||
|
||||
#define TCP_BPF_IW 1001 /* Set TCP initial congestion window */
|
||||
#define TCP_BPF_SNDCWND_CLAMP 1002 /* Set sndcwnd_clamp */
|
||||
enum {
|
||||
TCP_BPF_IW = 1001, /* Set TCP initial congestion window */
|
||||
TCP_BPF_SNDCWND_CLAMP = 1002, /* Set sndcwnd_clamp */
|
||||
};
|
||||
|
||||
struct bpf_perf_event_value {
|
||||
__u64 counter;
|
||||
|
|
@ -3599,12 +3775,16 @@ struct bpf_perf_event_value {
|
|||
__u64 running;
|
||||
};
|
||||
|
||||
#define BPF_DEVCG_ACC_MKNOD (1ULL << 0)
|
||||
#define BPF_DEVCG_ACC_READ (1ULL << 1)
|
||||
#define BPF_DEVCG_ACC_WRITE (1ULL << 2)
|
||||
enum {
|
||||
BPF_DEVCG_ACC_MKNOD = (1ULL << 0),
|
||||
BPF_DEVCG_ACC_READ = (1ULL << 1),
|
||||
BPF_DEVCG_ACC_WRITE = (1ULL << 2),
|
||||
};
|
||||
|
||||
#define BPF_DEVCG_DEV_BLOCK (1ULL << 0)
|
||||
#define BPF_DEVCG_DEV_CHAR (1ULL << 1)
|
||||
enum {
|
||||
BPF_DEVCG_DEV_BLOCK = (1ULL << 0),
|
||||
BPF_DEVCG_DEV_CHAR = (1ULL << 1),
|
||||
};
|
||||
|
||||
struct bpf_cgroup_dev_ctx {
|
||||
/* access_type encoded as (BPF_DEVCG_ACC_* << 16) | BPF_DEVCG_DEV_* */
|
||||
|
|
@ -3620,8 +3800,10 @@ struct bpf_raw_tracepoint_args {
|
|||
/* DIRECT: Skip the FIB rules and go to FIB table associated with device
|
||||
* OUTPUT: Do lookup from egress perspective; default is ingress
|
||||
*/
|
||||
#define BPF_FIB_LOOKUP_DIRECT (1U << 0)
|
||||
#define BPF_FIB_LOOKUP_OUTPUT (1U << 1)
|
||||
enum {
|
||||
BPF_FIB_LOOKUP_DIRECT = (1U << 0),
|
||||
BPF_FIB_LOOKUP_OUTPUT = (1U << 1),
|
||||
};
|
||||
|
||||
enum {
|
||||
BPF_FIB_LKUP_RET_SUCCESS, /* lookup successful */
|
||||
|
|
@ -3693,9 +3875,11 @@ enum bpf_task_fd_type {
|
|||
BPF_FD_TYPE_URETPROBE, /* filename + offset */
|
||||
};
|
||||
|
||||
#define BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG (1U << 0)
|
||||
#define BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL (1U << 1)
|
||||
#define BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP (1U << 2)
|
||||
enum {
|
||||
BPF_FLOW_DISSECTOR_F_PARSE_1ST_FRAG = (1U << 0),
|
||||
BPF_FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL = (1U << 1),
|
||||
BPF_FLOW_DISSECTOR_F_STOP_AT_ENCAP = (1U << 2),
|
||||
};
|
||||
|
||||
struct bpf_flow_keys {
|
||||
__u16 nhoff;
|
||||
|
|
@ -3761,4 +3945,8 @@ struct bpf_sockopt {
|
|||
__s32 retval;
|
||||
};
|
||||
|
||||
struct bpf_pidns_info {
|
||||
__u32 pid;
|
||||
__u32 tgid;
|
||||
};
|
||||
#endif /* __LINUX_BPF_H__ */
|
||||
|
|
|
|||
|
|
@ -117,6 +117,11 @@ enum devlink_command {
|
|||
DEVLINK_CMD_TRAP_GROUP_NEW,
|
||||
DEVLINK_CMD_TRAP_GROUP_DEL,
|
||||
|
||||
DEVLINK_CMD_TRAP_POLICER_GET, /* can dump */
|
||||
DEVLINK_CMD_TRAP_POLICER_SET,
|
||||
DEVLINK_CMD_TRAP_POLICER_NEW,
|
||||
DEVLINK_CMD_TRAP_POLICER_DEL,
|
||||
|
||||
/* add new commands above here */
|
||||
__DEVLINK_CMD_MAX,
|
||||
DEVLINK_CMD_MAX = __DEVLINK_CMD_MAX - 1
|
||||
|
|
@ -187,6 +192,7 @@ enum devlink_port_flavour {
|
|||
* for the PCI VF. It is an internal
|
||||
* port that faces the PCI VF.
|
||||
*/
|
||||
DEVLINK_PORT_FLAVOUR_VIRTUAL, /* Any virtual port facing the user. */
|
||||
};
|
||||
|
||||
enum devlink_param_cmode {
|
||||
|
|
@ -216,6 +222,7 @@ enum devlink_param_reset_dev_on_drv_probe_value {
|
|||
enum {
|
||||
DEVLINK_ATTR_STATS_RX_PACKETS, /* u64 */
|
||||
DEVLINK_ATTR_STATS_RX_BYTES, /* u64 */
|
||||
DEVLINK_ATTR_STATS_RX_DROPPED, /* u64 */
|
||||
|
||||
__DEVLINK_ATTR_STATS_MAX,
|
||||
DEVLINK_ATTR_STATS_MAX = __DEVLINK_ATTR_STATS_MAX - 1
|
||||
|
|
@ -252,6 +259,8 @@ enum devlink_trap_type {
|
|||
enum {
|
||||
/* Trap can report input port as metadata */
|
||||
DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT,
|
||||
/* Trap can report flow action cookie as metadata */
|
||||
DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE,
|
||||
};
|
||||
|
||||
enum devlink_attr {
|
||||
|
|
@ -426,6 +435,13 @@ enum devlink_attr {
|
|||
DEVLINK_ATTR_NETNS_FD, /* u32 */
|
||||
DEVLINK_ATTR_NETNS_PID, /* u32 */
|
||||
DEVLINK_ATTR_NETNS_ID, /* u32 */
|
||||
|
||||
DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP, /* u8 */
|
||||
|
||||
DEVLINK_ATTR_TRAP_POLICER_ID, /* u32 */
|
||||
DEVLINK_ATTR_TRAP_POLICER_RATE, /* u64 */
|
||||
DEVLINK_ATTR_TRAP_POLICER_BURST, /* u64 */
|
||||
|
||||
/* add new attributes above here, update the policy in devlink.c */
|
||||
|
||||
__DEVLINK_ATTR_MAX,
|
||||
|
|
|
|||
|
|
@ -174,6 +174,16 @@ struct br_vlan_msg {
|
|||
__u32 ifindex;
|
||||
};
|
||||
|
||||
enum {
|
||||
BRIDGE_VLANDB_DUMP_UNSPEC,
|
||||
BRIDGE_VLANDB_DUMP_FLAGS,
|
||||
__BRIDGE_VLANDB_DUMP_MAX,
|
||||
};
|
||||
#define BRIDGE_VLANDB_DUMP_MAX (__BRIDGE_VLANDB_DUMP_MAX - 1)
|
||||
|
||||
/* flags used in BRIDGE_VLANDB_DUMP_FLAGS attribute to affect dumps */
|
||||
#define BRIDGE_VLANDB_DUMPF_STATS (1 << 0) /* Include stats in the dump */
|
||||
|
||||
/* Bridge vlan RTM attributes
|
||||
* [BRIDGE_VLANDB_ENTRY] = {
|
||||
* [BRIDGE_VLANDB_ENTRY_INFO]
|
||||
|
|
@ -192,10 +202,46 @@ enum {
|
|||
BRIDGE_VLANDB_ENTRY_INFO,
|
||||
BRIDGE_VLANDB_ENTRY_RANGE,
|
||||
BRIDGE_VLANDB_ENTRY_STATE,
|
||||
BRIDGE_VLANDB_ENTRY_TUNNEL_INFO,
|
||||
BRIDGE_VLANDB_ENTRY_STATS,
|
||||
__BRIDGE_VLANDB_ENTRY_MAX,
|
||||
};
|
||||
#define BRIDGE_VLANDB_ENTRY_MAX (__BRIDGE_VLANDB_ENTRY_MAX - 1)
|
||||
|
||||
/* [BRIDGE_VLANDB_ENTRY] = {
|
||||
* [BRIDGE_VLANDB_ENTRY_TUNNEL_INFO] = {
|
||||
* [BRIDGE_VLANDB_TINFO_ID]
|
||||
* ...
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
enum {
|
||||
BRIDGE_VLANDB_TINFO_UNSPEC,
|
||||
BRIDGE_VLANDB_TINFO_ID,
|
||||
BRIDGE_VLANDB_TINFO_CMD,
|
||||
__BRIDGE_VLANDB_TINFO_MAX,
|
||||
};
|
||||
#define BRIDGE_VLANDB_TINFO_MAX (__BRIDGE_VLANDB_TINFO_MAX - 1)
|
||||
|
||||
/* [BRIDGE_VLANDB_ENTRY] = {
|
||||
* [BRIDGE_VLANDB_ENTRY_STATS] = {
|
||||
* [BRIDGE_VLANDB_STATS_RX_BYTES]
|
||||
* ...
|
||||
* }
|
||||
* ...
|
||||
* }
|
||||
*/
|
||||
enum {
|
||||
BRIDGE_VLANDB_STATS_UNSPEC,
|
||||
BRIDGE_VLANDB_STATS_RX_BYTES,
|
||||
BRIDGE_VLANDB_STATS_RX_PACKETS,
|
||||
BRIDGE_VLANDB_STATS_TX_BYTES,
|
||||
BRIDGE_VLANDB_STATS_TX_PACKETS,
|
||||
BRIDGE_VLANDB_STATS_PAD,
|
||||
__BRIDGE_VLANDB_STATS_MAX,
|
||||
};
|
||||
#define BRIDGE_VLANDB_STATS_MAX (__BRIDGE_VLANDB_STATS_MAX - 1)
|
||||
|
||||
/* Bridge multicast database attributes
|
||||
* [MDBA_MDB] = {
|
||||
* [MDBA_MDB_ENTRY] = {
|
||||
|
|
|
|||
|
|
@ -461,6 +461,7 @@ enum {
|
|||
IFLA_MACSEC_REPLAY_PROTECT,
|
||||
IFLA_MACSEC_VALIDATION,
|
||||
IFLA_MACSEC_PAD,
|
||||
IFLA_MACSEC_OFFLOAD,
|
||||
__IFLA_MACSEC_MAX,
|
||||
};
|
||||
|
||||
|
|
@ -487,6 +488,7 @@ enum macsec_validation_type {
|
|||
enum macsec_offload {
|
||||
MACSEC_OFFLOAD_OFF = 0,
|
||||
MACSEC_OFFLOAD_PHY = 1,
|
||||
MACSEC_OFFLOAD_MAC = 2,
|
||||
__MACSEC_OFFLOAD_END,
|
||||
MACSEC_OFFLOAD_MAX = __MACSEC_OFFLOAD_END - 1,
|
||||
};
|
||||
|
|
@ -588,6 +590,18 @@ enum ifla_geneve_df {
|
|||
GENEVE_DF_MAX = __GENEVE_DF_END - 1,
|
||||
};
|
||||
|
||||
/* Bareudp section */
|
||||
enum {
|
||||
IFLA_BAREUDP_UNSPEC,
|
||||
IFLA_BAREUDP_PORT,
|
||||
IFLA_BAREUDP_ETHERTYPE,
|
||||
IFLA_BAREUDP_SRCPORT_MIN,
|
||||
IFLA_BAREUDP_MULTIPROTO_MODE,
|
||||
__IFLA_BAREUDP_MAX
|
||||
};
|
||||
|
||||
#define IFLA_BAREUDP_MAX (__IFLA_BAREUDP_MAX - 1)
|
||||
|
||||
/* PPP section */
|
||||
enum {
|
||||
IFLA_PPP_UNSPEC,
|
||||
|
|
@ -958,11 +972,12 @@ enum {
|
|||
#define XDP_FLAGS_SKB_MODE (1U << 1)
|
||||
#define XDP_FLAGS_DRV_MODE (1U << 2)
|
||||
#define XDP_FLAGS_HW_MODE (1U << 3)
|
||||
#define XDP_FLAGS_REPLACE (1U << 4)
|
||||
#define XDP_FLAGS_MODES (XDP_FLAGS_SKB_MODE | \
|
||||
XDP_FLAGS_DRV_MODE | \
|
||||
XDP_FLAGS_HW_MODE)
|
||||
#define XDP_FLAGS_MASK (XDP_FLAGS_UPDATE_IF_NOEXIST | \
|
||||
XDP_FLAGS_MODES)
|
||||
XDP_FLAGS_MODES | XDP_FLAGS_REPLACE)
|
||||
|
||||
/* These are stored into IFLA_XDP_ATTACHED on dump. */
|
||||
enum {
|
||||
|
|
@ -982,6 +997,7 @@ enum {
|
|||
IFLA_XDP_DRV_PROG_ID,
|
||||
IFLA_XDP_SKB_PROG_ID,
|
||||
IFLA_XDP_HW_PROG_ID,
|
||||
IFLA_XDP_EXPECTED_FD,
|
||||
__IFLA_XDP_MAX,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -22,9 +22,11 @@
|
|||
|
||||
#define MACSEC_KEYID_LEN 16
|
||||
|
||||
/* cipher IDs as per IEEE802.1AEbn-2011 */
|
||||
/* cipher IDs as per IEEE802.1AE-2018 (Table 14-1) */
|
||||
#define MACSEC_CIPHER_ID_GCM_AES_128 0x0080C20001000001ULL
|
||||
#define MACSEC_CIPHER_ID_GCM_AES_256 0x0080C20001000002ULL
|
||||
#define MACSEC_CIPHER_ID_GCM_AES_XPN_128 0x0080C20001000003ULL
|
||||
#define MACSEC_CIPHER_ID_GCM_AES_XPN_256 0x0080C20001000004ULL
|
||||
|
||||
/* deprecated cipher ID for GCM-AES-128 */
|
||||
#define MACSEC_DEFAULT_CIPHER_ID 0x0080020001000001ULL
|
||||
|
|
@ -88,11 +90,13 @@ enum macsec_sa_attrs {
|
|||
MACSEC_SA_ATTR_UNSPEC,
|
||||
MACSEC_SA_ATTR_AN, /* config/dump, u8 0..3 */
|
||||
MACSEC_SA_ATTR_ACTIVE, /* config/dump, u8 0..1 */
|
||||
MACSEC_SA_ATTR_PN, /* config/dump, u32 */
|
||||
MACSEC_SA_ATTR_PN, /* config/dump, u32/u64 (u64 if XPN) */
|
||||
MACSEC_SA_ATTR_KEY, /* config, data */
|
||||
MACSEC_SA_ATTR_KEYID, /* config/dump, 128-bit */
|
||||
MACSEC_SA_ATTR_STATS, /* dump, nested, macsec_sa_stats_attr */
|
||||
MACSEC_SA_ATTR_PAD,
|
||||
MACSEC_SA_ATTR_SSCI, /* config/dump, u32 - XPN only */
|
||||
MACSEC_SA_ATTR_SALT, /* config, 96-bit - XPN only */
|
||||
__MACSEC_SA_ATTR_END,
|
||||
NUM_MACSEC_SA_ATTR = __MACSEC_SA_ATTR_END,
|
||||
MACSEC_SA_ATTR_MAX = __MACSEC_SA_ATTR_END - 1,
|
||||
|
|
|
|||
|
|
@ -64,9 +64,11 @@ struct inet_diag_req_raw {
|
|||
enum {
|
||||
INET_DIAG_REQ_NONE,
|
||||
INET_DIAG_REQ_BYTECODE,
|
||||
INET_DIAG_REQ_SK_BPF_STORAGES,
|
||||
__INET_DIAG_REQ_MAX,
|
||||
};
|
||||
|
||||
#define INET_DIAG_REQ_MAX INET_DIAG_REQ_BYTECODE
|
||||
#define INET_DIAG_REQ_MAX (__INET_DIAG_REQ_MAX - 1)
|
||||
|
||||
/* Bytecode is sequence of 4 byte commands followed by variable arguments.
|
||||
* All the commands identified by "code" are conditional jumps forward:
|
||||
|
|
@ -154,6 +156,7 @@ enum {
|
|||
INET_DIAG_CLASS_ID, /* request as INET_DIAG_TCLASS */
|
||||
INET_DIAG_MD5SIG,
|
||||
INET_DIAG_ULP_INFO,
|
||||
INET_DIAG_SK_BPF_STORAGES,
|
||||
__INET_DIAG_MAX,
|
||||
};
|
||||
|
||||
|
|
@ -163,6 +166,7 @@ enum {
|
|||
INET_ULP_INFO_UNSPEC,
|
||||
INET_ULP_INFO_NAME,
|
||||
INET_ULP_INFO_TLS,
|
||||
INET_ULP_INFO_MPTCP,
|
||||
__INET_ULP_INFO_MAX,
|
||||
};
|
||||
#define INET_ULP_INFO_MAX (__INET_ULP_INFO_MAX - 1)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ enum lwtunnel_encap_types {
|
|||
LWTUNNEL_ENCAP_SEG6,
|
||||
LWTUNNEL_ENCAP_BPF,
|
||||
LWTUNNEL_ENCAP_SEG6_LOCAL,
|
||||
LWTUNNEL_ENCAP_RPL,
|
||||
__LWTUNNEL_ENCAP_MAX,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ enum {
|
|||
TCA_ACT_PAD,
|
||||
TCA_ACT_COOKIE,
|
||||
TCA_ACT_FLAGS,
|
||||
TCA_ACT_HW_STATS,
|
||||
TCA_ACT_USED_HW_STATS,
|
||||
__TCA_ACT_MAX
|
||||
};
|
||||
|
||||
|
|
@ -24,6 +26,26 @@ enum {
|
|||
* actions stats.
|
||||
*/
|
||||
|
||||
/* tca HW stats type
|
||||
* When user does not pass the attribute, he does not care.
|
||||
* It is the same as if he would pass the attribute with
|
||||
* all supported bits set.
|
||||
* In case no bits are set, user is not interested in getting any HW statistics.
|
||||
*/
|
||||
#define TCA_ACT_HW_STATS_IMMEDIATE (1 << 0) /* Means that in dump, user
|
||||
* gets the current HW stats
|
||||
* state from the device
|
||||
* queried at the dump time.
|
||||
*/
|
||||
#define TCA_ACT_HW_STATS_DELAYED (1 << 1) /* Means that in dump, user gets
|
||||
* HW stats that might be out of date
|
||||
* for some time, maybe couple of
|
||||
* seconds. This is the case when
|
||||
* driver polls stats updates
|
||||
* periodically or when it gets async
|
||||
* stats update from the device.
|
||||
*/
|
||||
|
||||
#define TCA_ACT_MAX __TCA_ACT_MAX
|
||||
#define TCA_OLD_COMPAT (TCA_ACT_MAX+1)
|
||||
#define TCA_ACT_MAX_PRIO 32
|
||||
|
|
|
|||
|
|
@ -256,6 +256,7 @@ enum {
|
|||
TCA_RED_PARMS,
|
||||
TCA_RED_STAB,
|
||||
TCA_RED_MAX_P,
|
||||
TCA_RED_FLAGS, /* bitfield32 */
|
||||
__TCA_RED_MAX,
|
||||
};
|
||||
|
||||
|
|
@ -268,12 +269,28 @@ struct tc_red_qopt {
|
|||
unsigned char Wlog; /* log(W) */
|
||||
unsigned char Plog; /* log(P_max/(qth_max-qth_min)) */
|
||||
unsigned char Scell_log; /* cell size for idle damping */
|
||||
|
||||
/* This field can be used for flags that a RED-like qdisc has
|
||||
* historically supported. E.g. when configuring RED, it can be used for
|
||||
* ECN, HARDDROP and ADAPTATIVE. For SFQ it can be used for ECN,
|
||||
* HARDDROP. Etc. Because this field has not been validated, and is
|
||||
* copied back on dump, any bits besides those to which a given qdisc
|
||||
* has assigned a historical meaning need to be considered for free use
|
||||
* by userspace tools.
|
||||
*
|
||||
* Any further flags need to be passed differently, e.g. through an
|
||||
* attribute (such as TCA_RED_FLAGS above). Such attribute should allow
|
||||
* passing both recent and historic flags in one value.
|
||||
*/
|
||||
unsigned char flags;
|
||||
#define TC_RED_ECN 1
|
||||
#define TC_RED_HARDDROP 2
|
||||
#define TC_RED_ADAPTATIVE 4
|
||||
#define TC_RED_NODROP 8
|
||||
};
|
||||
|
||||
#define TC_RED_HISTORIC_FLAGS (TC_RED_ECN | TC_RED_HARDDROP | TC_RED_ADAPTATIVE)
|
||||
|
||||
struct tc_red_xstats {
|
||||
__u32 early; /* Early drops */
|
||||
__u32 pdrop; /* Drops due to queue limits */
|
||||
|
|
@ -894,6 +911,8 @@ enum {
|
|||
|
||||
TCA_FQ_CE_THRESHOLD, /* DCTCP-like CE-marking threshold */
|
||||
|
||||
TCA_FQ_TIMER_SLACK, /* timer slack */
|
||||
|
||||
__TCA_FQ_MAX
|
||||
};
|
||||
|
||||
|
|
@ -1197,8 +1216,8 @@ enum {
|
|||
* [TCA_TAPRIO_ATTR_SCHED_ENTRY_INTERVAL]
|
||||
*/
|
||||
|
||||
#define TCA_TAPRIO_ATTR_FLAG_TXTIME_ASSIST BIT(0)
|
||||
#define TCA_TAPRIO_ATTR_FLAG_FULL_OFFLOAD BIT(1)
|
||||
#define TCA_TAPRIO_ATTR_FLAG_TXTIME_ASSIST _BITUL(0)
|
||||
#define TCA_TAPRIO_ATTR_FLAG_FULL_OFFLOAD _BITUL(1)
|
||||
|
||||
enum {
|
||||
TCA_TAPRIO_ATTR_UNSPEC,
|
||||
|
|
|
|||
|
|
@ -36,4 +36,30 @@ enum sknetlink_groups {
|
|||
};
|
||||
#define SKNLGRP_MAX (__SKNLGRP_MAX - 1)
|
||||
|
||||
enum {
|
||||
SK_DIAG_BPF_STORAGE_REQ_NONE,
|
||||
SK_DIAG_BPF_STORAGE_REQ_MAP_FD,
|
||||
__SK_DIAG_BPF_STORAGE_REQ_MAX,
|
||||
};
|
||||
|
||||
#define SK_DIAG_BPF_STORAGE_REQ_MAX (__SK_DIAG_BPF_STORAGE_REQ_MAX - 1)
|
||||
|
||||
enum {
|
||||
SK_DIAG_BPF_STORAGE_REP_NONE,
|
||||
SK_DIAG_BPF_STORAGE,
|
||||
__SK_DIAG_BPF_STORAGE_REP_MAX,
|
||||
};
|
||||
|
||||
#define SK_DIAB_BPF_STORAGE_REP_MAX (__SK_DIAG_BPF_STORAGE_REP_MAX - 1)
|
||||
|
||||
enum {
|
||||
SK_DIAG_BPF_STORAGE_NONE,
|
||||
SK_DIAG_BPF_STORAGE_PAD,
|
||||
SK_DIAG_BPF_STORAGE_MAP_ID,
|
||||
SK_DIAG_BPF_STORAGE_MAP_VALUE,
|
||||
__SK_DIAG_BPF_STORAGE_MAX,
|
||||
};
|
||||
|
||||
#define SK_DIAG_BPF_STORAGE_MAX (__SK_DIAG_BPF_STORAGE_MAX - 1)
|
||||
|
||||
#endif /* __SOCK_DIAG_H__ */
|
||||
|
|
|
|||
|
|
@ -312,6 +312,7 @@ enum {
|
|||
TCP_NLA_REORD_SEEN, /* reordering events seen */
|
||||
TCP_NLA_SRTT, /* smoothed RTT in usecs */
|
||||
TCP_NLA_TIMEOUT_REHASH, /* Timeout-triggered rehash attempts */
|
||||
TCP_NLA_BYTES_NOTSENT, /* Bytes in write queue not yet sent */
|
||||
};
|
||||
|
||||
/* for TCP_MD5SIG socket option */
|
||||
|
|
@ -345,5 +346,7 @@ struct tcp_zerocopy_receive {
|
|||
__u64 address; /* in: address of mapping */
|
||||
__u32 length; /* in/out: number of bytes to map/mapped */
|
||||
__u32 recv_skip_hint; /* out: amount of bytes to skip */
|
||||
__u32 inq; /* out: amount of bytes in read queue */
|
||||
__s32 err; /* out: socket error */
|
||||
};
|
||||
#endif /* _LINUX_TCP_H */
|
||||
|
|
|
|||
|
|
@ -31,6 +31,11 @@ static const char * const validate_str[] = {
|
|||
[MACSEC_VALIDATE_STRICT] = "strict",
|
||||
};
|
||||
|
||||
static const char * const offload_str[] = {
|
||||
[MACSEC_OFFLOAD_OFF] = "off",
|
||||
[MACSEC_OFFLOAD_PHY] = "phy",
|
||||
};
|
||||
|
||||
struct sci {
|
||||
__u64 sci;
|
||||
__u16 port;
|
||||
|
|
@ -93,6 +98,7 @@ static void ipmacsec_usage(void)
|
|||
" ip macsec del DEV rx SCI sa { 0..3 }\n"
|
||||
" ip macsec show\n"
|
||||
" ip macsec show DEV\n"
|
||||
" ip macsec offload DEV [ off | phy ]\n"
|
||||
"where OPTS := [ pn <u32> ] [ on | off ]\n"
|
||||
" ID := 128-bit hex string\n"
|
||||
" KEY := 128-bit or 256-bit hex string\n"
|
||||
|
|
@ -354,6 +360,7 @@ enum cmd {
|
|||
CMD_ADD,
|
||||
CMD_DEL,
|
||||
CMD_UPD,
|
||||
CMD_OFFLOAD,
|
||||
__CMD_MAX
|
||||
};
|
||||
|
||||
|
|
@ -370,6 +377,9 @@ static const enum macsec_nl_commands macsec_commands[__CMD_MAX][2][2] = {
|
|||
[0] = {-1, MACSEC_CMD_DEL_RXSC},
|
||||
[1] = {MACSEC_CMD_DEL_TXSA, MACSEC_CMD_DEL_RXSA},
|
||||
},
|
||||
[CMD_OFFLOAD] = {
|
||||
[0] = {-1, MACSEC_CMD_UPD_OFFLOAD },
|
||||
},
|
||||
};
|
||||
|
||||
static int do_modify_nl(enum cmd c, enum macsec_nl_commands cmd, int ifindex,
|
||||
|
|
@ -529,6 +539,44 @@ static int do_modify(enum cmd c, int argc, char **argv)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int do_offload(enum cmd c, int argc, char **argv)
|
||||
{
|
||||
enum macsec_offload offload;
|
||||
struct rtattr *attr;
|
||||
int ifindex, ret;
|
||||
|
||||
if (argc == 0)
|
||||
ipmacsec_usage();
|
||||
|
||||
ifindex = ll_name_to_index(*argv);
|
||||
if (!ifindex) {
|
||||
fprintf(stderr, "Device \"%s\" does not exist.\n", *argv);
|
||||
return -1;
|
||||
}
|
||||
argc--; argv++;
|
||||
|
||||
if (argc == 0)
|
||||
ipmacsec_usage();
|
||||
|
||||
ret = one_of("offload", *argv, offload_str, ARRAY_SIZE(offload_str),
|
||||
(int *)&offload);
|
||||
if (ret)
|
||||
ipmacsec_usage();
|
||||
|
||||
MACSEC_GENL_REQ(req, MACSEC_BUFLEN, macsec_commands[c][0][1], NLM_F_REQUEST);
|
||||
|
||||
addattr32(&req.n, MACSEC_BUFLEN, MACSEC_ATTR_IFINDEX, ifindex);
|
||||
|
||||
attr = addattr_nest(&req.n, MACSEC_BUFLEN, MACSEC_ATTR_OFFLOAD);
|
||||
addattr8(&req.n, MACSEC_BUFLEN, MACSEC_OFFLOAD_ATTR_TYPE, offload);
|
||||
addattr_nest_end(&req.n, attr);
|
||||
|
||||
if (rtnl_talk(&genl_rth, &req.n, NULL) < 0)
|
||||
return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* dump/show */
|
||||
static struct {
|
||||
int ifindex;
|
||||
|
|
@ -605,6 +653,22 @@ static const char *cs_id_to_name(__u64 cid)
|
|||
}
|
||||
}
|
||||
|
||||
static const char *validate_to_str(__u8 validate)
|
||||
{
|
||||
if (validate >= ARRAY_SIZE(validate_str))
|
||||
return "(unknown)";
|
||||
|
||||
return validate_str[validate];
|
||||
}
|
||||
|
||||
static const char *offload_to_str(__u8 offload)
|
||||
{
|
||||
if (offload >= ARRAY_SIZE(offload_str))
|
||||
return "(unknown)";
|
||||
|
||||
return offload_str[offload];
|
||||
}
|
||||
|
||||
static void print_attrs(struct rtattr *attrs[])
|
||||
{
|
||||
print_flag(attrs, "protect", MACSEC_SECY_ATTR_PROTECT);
|
||||
|
|
@ -613,7 +677,7 @@ static void print_attrs(struct rtattr *attrs[])
|
|||
__u8 val = rta_getattr_u8(attrs[MACSEC_SECY_ATTR_VALIDATE]);
|
||||
|
||||
print_string(PRINT_ANY, "validate",
|
||||
"validate %s ", validate_str[val]);
|
||||
"validate %s ", validate_to_str(val));
|
||||
}
|
||||
|
||||
print_flag(attrs, "sc", MACSEC_RXSC_ATTR_ACTIVE);
|
||||
|
|
@ -997,6 +1061,19 @@ static int process(struct nlmsghdr *n, void *arg)
|
|||
if (attrs[MACSEC_ATTR_RXSC_LIST])
|
||||
print_rxsc_list(attrs[MACSEC_ATTR_RXSC_LIST]);
|
||||
|
||||
if (attrs[MACSEC_ATTR_OFFLOAD]) {
|
||||
struct rtattr *attrs_offload[MACSEC_OFFLOAD_ATTR_MAX + 1];
|
||||
__u8 offload;
|
||||
|
||||
parse_rtattr_nested(attrs_offload, MACSEC_OFFLOAD_ATTR_MAX,
|
||||
attrs[MACSEC_ATTR_OFFLOAD]);
|
||||
|
||||
offload = rta_getattr_u8(attrs_offload[MACSEC_OFFLOAD_ATTR_TYPE]);
|
||||
print_string(PRINT_ANY, "offload",
|
||||
" offload: %s ", offload_to_str(offload));
|
||||
print_nl();
|
||||
}
|
||||
|
||||
close_json_object();
|
||||
|
||||
return 0;
|
||||
|
|
@ -1068,6 +1145,8 @@ int do_ipmacsec(int argc, char **argv)
|
|||
return do_modify(CMD_UPD, argc-1, argv+1);
|
||||
if (matches(*argv, "delete") == 0)
|
||||
return do_modify(CMD_DEL, argc-1, argv+1);
|
||||
if (matches(*argv, "offload") == 0)
|
||||
return do_offload(CMD_OFFLOAD, argc-1, argv+1);
|
||||
|
||||
fprintf(stderr, "Command \"%s\" is unknown, try \"ip macsec help\".\n",
|
||||
*argv);
|
||||
|
|
@ -1137,7 +1216,7 @@ static void macsec_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
|
|||
print_string(PRINT_ANY,
|
||||
"validation",
|
||||
"validate %s ",
|
||||
validate_str[val]);
|
||||
validate_to_str(val));
|
||||
}
|
||||
|
||||
const char *inc_sci, *es, *replay;
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ command is the first in the command line and then the object list.
|
|||
.I OBJECT-LIST
|
||||
is the list of object types that we want to monitor.
|
||||
It may contain
|
||||
.BR dev ", " port ", " trap ", " trap-group .
|
||||
.BR dev ", " port ", " health ", " trap ", " trap-group ", " trap-policer .
|
||||
|
||||
.B devlink
|
||||
opens Devlink Netlink socket, listens on it and dumps state changes.
|
||||
|
|
@ -31,6 +31,7 @@ opens Devlink Netlink socket, listens on it and dumps state changes.
|
|||
.BR devlink-dev (8),
|
||||
.BR devlink-sb (8),
|
||||
.BR devlink-port (8),
|
||||
.BR devlink-health (8),
|
||||
.BR devlink-trap (8),
|
||||
.br
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,17 @@ devlink-trap \- devlink trap configuration
|
|||
.ti -8
|
||||
.BI "devlink trap group set " DEV " group " GROUP
|
||||
.RB "[ " action " { " trap " | " drop " } ]"
|
||||
.br
|
||||
.RB "[ " policer
|
||||
.IB "POLICER " ]
|
||||
.RB "[ " nopolicer " ]"
|
||||
|
||||
.ti -8
|
||||
.BI "devlink trap policer set " DEV " policer " POLICER
|
||||
.RB "[ " rate
|
||||
.IR "RATE " ]
|
||||
.RB "[ " burst
|
||||
.IR "BURST " ]
|
||||
|
||||
.ti -8
|
||||
.B devlink trap help
|
||||
|
|
@ -102,6 +113,32 @@ packet trap action. The action is set for all the packet traps member in the
|
|||
trap group. The actions of non-drop traps cannot be changed and are thus
|
||||
skipped.
|
||||
|
||||
.TP
|
||||
.BI policer " POLICER"
|
||||
packet trap policer. The policer to bind to the packet trap group.
|
||||
|
||||
.TP
|
||||
.B nopolicer
|
||||
Unbind packet trap policer from the packet trap group.
|
||||
|
||||
.SS devlink trap policer set - set attributes of packet trap policer
|
||||
|
||||
.PP
|
||||
.I "DEV"
|
||||
- specifies the devlink device the packet trap policer belongs to.
|
||||
|
||||
.PP
|
||||
.BI "policer " POLICER
|
||||
- specifies the packet trap policer.
|
||||
|
||||
.PP
|
||||
.BI rate " RATE "
|
||||
- packet trap policer rate in packets per second.
|
||||
|
||||
.PP
|
||||
.BI burst " BURST "
|
||||
- packet trap policer burst size in packets.
|
||||
|
||||
.SH "EXAMPLES"
|
||||
.PP
|
||||
devlink trap show
|
||||
|
|
@ -128,6 +165,21 @@ devlink trap set pci/0000:01:00.0 trap source_mac_is_multicast action trap
|
|||
.RS 4
|
||||
Set the action of a specific packet trap to 'trap'.
|
||||
.RE
|
||||
.PP
|
||||
devlink trap policer show
|
||||
.RS 4
|
||||
List available packet trap policers.
|
||||
.RE
|
||||
.PP
|
||||
devlink -s trap policer show pci/0000:01:00.0 policer 1
|
||||
.RS 4
|
||||
Show attributes and statistics of a specific packet trap policer.
|
||||
.RE
|
||||
.PP
|
||||
devlink trap policer set pci/0000:01:00.0 policer 1 rate 1000 burst 128
|
||||
.RS 4
|
||||
Set the rate and burst size of a specific packet trap policer.
|
||||
.RE
|
||||
|
||||
.SH SEE ALSO
|
||||
.BR devlink (8),
|
||||
|
|
|
|||
|
|
@ -53,6 +53,9 @@ ip-macsec \- MACsec device configuration
|
|||
.BI "ip macsec del " DEV " rx " SCI " sa"
|
||||
.RI "{ " 0..3 " }"
|
||||
|
||||
.BI "ip macsec offload " DEV
|
||||
.RB "{ " off " | " phy " }"
|
||||
|
||||
.B ip macsec show
|
||||
.RI [ " DEV " ]
|
||||
|
||||
|
|
@ -102,6 +105,10 @@ type.
|
|||
.SS Display MACsec configuration
|
||||
.nf
|
||||
# ip macsec show
|
||||
.PP
|
||||
.SS Configure offloading on an interface
|
||||
.nf
|
||||
# ip macsec offload macsec0 phy
|
||||
|
||||
.SH NOTES
|
||||
This tool can be used to configure the 802.1AE keys of the interface. Note that 802.1AE uses GCM-AES
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ actions \- independently defined actions in tc
|
|||
] [
|
||||
.I FLAGS
|
||||
] [
|
||||
.I HWSTATSSPEC
|
||||
] [
|
||||
.I CONTROL
|
||||
]
|
||||
|
||||
|
|
@ -77,6 +79,12 @@ ACTNAME
|
|||
:=
|
||||
.I no_percpu
|
||||
|
||||
.I HWSTATSSPEC
|
||||
:=
|
||||
.BR hw_stats " {"
|
||||
.IR immediate " | " delayed " | " disabled
|
||||
.R }
|
||||
|
||||
.I ACTDETAIL
|
||||
:=
|
||||
.I ACTNAME ACTPARAMS
|
||||
|
|
@ -200,6 +208,29 @@ which indicates that action is expected to have minimal software data-path
|
|||
traffic and doesn't need to allocate stat counters with percpu allocator.
|
||||
This option is intended to be used by hardware-offloaded actions.
|
||||
|
||||
.TP
|
||||
.BI hw_stats " HW_STATS"
|
||||
Specifies the type of HW stats of new action. If omitted, any stats counter type
|
||||
is going to be used, according to driver and its resources.
|
||||
The
|
||||
.I HW_STATS
|
||||
indicates the type. Any of the following are valid:
|
||||
.RS
|
||||
.TP
|
||||
.B immediate
|
||||
Means that in dump, user gets the current HW stats state from the device
|
||||
queried at the dump time.
|
||||
.TP
|
||||
.B delayed
|
||||
Means that in dump, user gets HW stats that might be out of date for
|
||||
some time, maybe couple of seconds. This is the case when driver polls
|
||||
stats updates periodically or when it gets async stats update
|
||||
from the device.
|
||||
.TP
|
||||
.B disabled
|
||||
No HW stats are going to be available in dump.
|
||||
.RE
|
||||
|
||||
.TP
|
||||
.BI since " MSTIME"
|
||||
When dumping large number of actions, a millisecond time-filter can be
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ bytes
|
|||
bytes
|
||||
.B [ burst
|
||||
packets
|
||||
.B ] [ ecn ] [ harddrop] [ bandwidth
|
||||
.B ] [ ecn ] [ harddrop ] [ nodrop ] [ bandwidth
|
||||
rate
|
||||
.B ] [ probability
|
||||
chance
|
||||
|
|
@ -123,6 +123,10 @@ If average flow queue size is above
|
|||
.B max
|
||||
bytes, this parameter forces a drop instead of ecn marking.
|
||||
.TP
|
||||
nodrop
|
||||
With this parameter, traffic that should be marked, but is not ECN-capable, is
|
||||
enqueued. Without the parameter it is early-dropped.
|
||||
.TP
|
||||
adaptive
|
||||
(Added in linux-3.3) Sets RED in adaptive mode as described in http://icir.org/floyd/papers/adaptiveRed.pdf
|
||||
.nf
|
||||
|
|
|
|||
|
|
@ -51,8 +51,9 @@ static void act_usage(void)
|
|||
" FL := ls | list | flush | <ACTNAMESPEC>\n"
|
||||
" ACTNAMESPEC := action <ACTNAME>\n"
|
||||
" ACTISPEC := <ACTNAMESPEC> <INDEXSPEC>\n"
|
||||
" ACTSPEC := action <ACTDETAIL> [INDEXSPEC]\n"
|
||||
" ACTSPEC := action <ACTDETAIL> [INDEXSPEC] [HWSTATSSPEC]\n"
|
||||
" INDEXSPEC := index <32 bit indexvalue>\n"
|
||||
" HWSTATSSPEC := hw_stats [ immediate | delayed | disabled ]\n"
|
||||
" ACTDETAIL := <ACTNAME> <ACTPARAMS>\n"
|
||||
" Example ACTNAME is gact, mirred, bpf, etc\n"
|
||||
" Each action has its own parameters (ACTPARAMS)\n"
|
||||
|
|
@ -149,6 +150,59 @@ new_cmd(char **argv)
|
|||
(matches(*argv, "add") == 0);
|
||||
}
|
||||
|
||||
static const struct hw_stats_item {
|
||||
const char *str;
|
||||
__u8 type;
|
||||
} hw_stats_items[] = {
|
||||
{ "immediate", TCA_ACT_HW_STATS_IMMEDIATE },
|
||||
{ "delayed", TCA_ACT_HW_STATS_DELAYED },
|
||||
{ "disabled", 0 }, /* no bit set */
|
||||
};
|
||||
|
||||
static void print_hw_stats(const struct rtattr *arg, bool print_used)
|
||||
{
|
||||
struct nla_bitfield32 *hw_stats_bf = RTA_DATA(arg);
|
||||
__u8 hw_stats;
|
||||
int i;
|
||||
|
||||
hw_stats = hw_stats_bf->value & hw_stats_bf->selector;
|
||||
print_string(PRINT_FP, NULL, "\t", NULL);
|
||||
open_json_array(PRINT_ANY, print_used ? "used_hw_stats" : "hw_stats");
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(hw_stats_items); i++) {
|
||||
const struct hw_stats_item *item;
|
||||
|
||||
item = &hw_stats_items[i];
|
||||
if ((!hw_stats && !item->type) || hw_stats & item->type)
|
||||
print_string(PRINT_ANY, NULL, " %s", item->str);
|
||||
}
|
||||
close_json_array(PRINT_JSON, NULL);
|
||||
print_string(PRINT_FP, NULL, "%s", _SL_);
|
||||
}
|
||||
|
||||
static int parse_hw_stats(const char *str, struct nlmsghdr *n)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(hw_stats_items); i++) {
|
||||
const struct hw_stats_item *item;
|
||||
|
||||
item = &hw_stats_items[i];
|
||||
if (matches(str, item->str) == 0) {
|
||||
struct nla_bitfield32 hw_stats_bf = {
|
||||
.value = item->type,
|
||||
.selector = item->type
|
||||
};
|
||||
|
||||
addattr_l(n, MAX_MSG, TCA_ACT_HW_STATS,
|
||||
&hw_stats_bf, sizeof(hw_stats_bf));
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int parse_action(int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n)
|
||||
{
|
||||
int argc = *argc_p;
|
||||
|
|
@ -250,6 +304,14 @@ done0:
|
|||
addattr_l(n, MAX_MSG, TCA_ACT_COOKIE,
|
||||
&act_ck, act_ck_len);
|
||||
|
||||
if (*argv && matches(*argv, "hw_stats") == 0) {
|
||||
NEXT_ARG();
|
||||
ret = parse_hw_stats(*argv, n);
|
||||
if (ret < 0)
|
||||
invarg("value is invalid\n", *argv);
|
||||
NEXT_ARG_FWD();
|
||||
}
|
||||
|
||||
if (*argv && strcmp(*argv, "no_percpu") == 0) {
|
||||
struct nla_bitfield32 flags =
|
||||
{ TCA_ACT_FLAGS_NO_PERCPU_STATS,
|
||||
|
|
@ -337,6 +399,11 @@ static int tc_print_one_action(FILE *f, struct rtattr *arg)
|
|||
TCA_ACT_FLAGS_NO_PERCPU_STATS);
|
||||
print_string(PRINT_FP, NULL, "%s", _SL_);
|
||||
}
|
||||
if (tb[TCA_ACT_HW_STATS])
|
||||
print_hw_stats(tb[TCA_ACT_HW_STATS], false);
|
||||
|
||||
if (tb[TCA_ACT_USED_HW_STATS])
|
||||
print_hw_stats(tb[TCA_ACT_USED_HW_STATS], true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
25
tc/q_red.c
25
tc/q_red.c
|
|
@ -30,12 +30,17 @@ static void explain(void)
|
|||
fprintf(stderr,
|
||||
"Usage: ... red limit BYTES [min BYTES] [max BYTES] avpkt BYTES [burst PACKETS]\n"
|
||||
" [adaptive] [probability PROBABILITY] [bandwidth KBPS]\n"
|
||||
" [ecn] [harddrop]\n");
|
||||
" [ecn] [harddrop] [nodrop]\n");
|
||||
}
|
||||
|
||||
#define RED_SUPPORTED_FLAGS (TC_RED_HISTORIC_FLAGS | TC_RED_NODROP)
|
||||
|
||||
static int red_parse_opt(struct qdisc_util *qu, int argc, char **argv,
|
||||
struct nlmsghdr *n, const char *dev)
|
||||
{
|
||||
struct nla_bitfield32 flags_bf = {
|
||||
.selector = RED_SUPPORTED_FLAGS,
|
||||
};
|
||||
struct tc_red_qopt opt = {};
|
||||
unsigned int burst = 0;
|
||||
unsigned int avpkt = 0;
|
||||
|
|
@ -95,13 +100,15 @@ static int red_parse_opt(struct qdisc_util *qu, int argc, char **argv,
|
|||
return -1;
|
||||
}
|
||||
} else if (strcmp(*argv, "ecn") == 0) {
|
||||
opt.flags |= TC_RED_ECN;
|
||||
flags_bf.value |= TC_RED_ECN;
|
||||
} else if (strcmp(*argv, "harddrop") == 0) {
|
||||
opt.flags |= TC_RED_HARDDROP;
|
||||
flags_bf.value |= TC_RED_HARDDROP;
|
||||
} else if (strcmp(*argv, "nodrop") == 0) {
|
||||
flags_bf.value |= TC_RED_NODROP;
|
||||
} else if (strcmp(*argv, "adaptative") == 0) {
|
||||
opt.flags |= TC_RED_ADAPTATIVE;
|
||||
flags_bf.value |= TC_RED_ADAPTATIVE;
|
||||
} else if (strcmp(*argv, "adaptive") == 0) {
|
||||
opt.flags |= TC_RED_ADAPTATIVE;
|
||||
flags_bf.value |= TC_RED_ADAPTATIVE;
|
||||
} else if (strcmp(*argv, "help") == 0) {
|
||||
explain();
|
||||
return -1;
|
||||
|
|
@ -154,6 +161,7 @@ static int red_parse_opt(struct qdisc_util *qu, int argc, char **argv,
|
|||
addattr_l(n, 1024, TCA_RED_STAB, sbuf, 256);
|
||||
max_P = probability * pow(2, 32);
|
||||
addattr_l(n, 1024, TCA_RED_MAX_P, &max_P, sizeof(max_P));
|
||||
addattr_l(n, 1024, TCA_RED_FLAGS, &flags_bf, sizeof(flags_bf));
|
||||
addattr_nest_end(n, tail);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -161,6 +169,7 @@ static int red_parse_opt(struct qdisc_util *qu, int argc, char **argv,
|
|||
static int red_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
|
||||
{
|
||||
struct rtattr *tb[TCA_RED_MAX + 1];
|
||||
struct nla_bitfield32 *flags_bf;
|
||||
struct tc_red_qopt *qopt;
|
||||
__u32 max_P = 0;
|
||||
|
||||
|
|
@ -183,6 +192,12 @@ static int red_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
|
|||
RTA_PAYLOAD(tb[TCA_RED_MAX_P]) >= sizeof(__u32))
|
||||
max_P = rta_getattr_u32(tb[TCA_RED_MAX_P]);
|
||||
|
||||
if (tb[TCA_RED_FLAGS] &&
|
||||
RTA_PAYLOAD(tb[TCA_RED_FLAGS]) >= sizeof(*flags_bf)) {
|
||||
flags_bf = RTA_DATA(tb[TCA_RED_FLAGS]);
|
||||
qopt->flags = flags_bf->value;
|
||||
}
|
||||
|
||||
print_uint(PRINT_JSON, "limit", NULL, qopt->limit);
|
||||
print_string(PRINT_FP, NULL, "limit %s ", sprint_size(qopt->limit, b1));
|
||||
print_uint(PRINT_JSON, "min", NULL, qopt->qth_min);
|
||||
|
|
|
|||
|
|
@ -116,4 +116,9 @@ void tc_red_print_flags(__u32 flags)
|
|||
print_bool(PRINT_ANY, "adaptive", "adaptive ", true);
|
||||
else
|
||||
print_bool(PRINT_ANY, "adaptive", NULL, false);
|
||||
|
||||
if (flags & TC_RED_NODROP)
|
||||
print_bool(PRINT_ANY, "nodrop", "nodrop ", true);
|
||||
else
|
||||
print_bool(PRINT_ANY, "nodrop", NULL, false);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue