Merge ../iproute2-next

This commit is contained in:
Stephen Hemminger 2020-04-06 10:00:12 -07:00
commit 5d10f24fdd
23 changed files with 1841 additions and 87 deletions

View File

@ -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:

951
bash-completion/devlink Normal file
View File

@ -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

View File

@ -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;

View File

@ -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__ */

View File

@ -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,

View File

@ -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] = {

View File

@ -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,
};

View File

@ -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,

View File

@ -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)

View File

@ -13,6 +13,7 @@ enum lwtunnel_encap_types {
LWTUNNEL_ENCAP_SEG6,
LWTUNNEL_ENCAP_BPF,
LWTUNNEL_ENCAP_SEG6_LOCAL,
LWTUNNEL_ENCAP_RPL,
__LWTUNNEL_ENCAP_MAX,
};

View File

@ -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

View File

@ -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,

View File

@ -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__ */

View File

@ -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 */

View File

@ -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;

View File

@ -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

View File

@ -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),

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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);
}