mirror of
https://gitee.com/openharmony/third_party_libnl
synced 2024-11-24 02:29:50 +00:00
lib/qdisc: merge branch 'westermo/qdisc-mqprio'
https://github.com/thom311/libnl/pull/196
This commit is contained in:
commit
ebcfdc28b8
138
Makefile.am
138
Makefile.am
@ -23,11 +23,12 @@ DISTCHECK_CONFIGURE_FLAGS = \
|
||||
|
||||
pkgconfig_DATA = \
|
||||
libnl-3.0.pc \
|
||||
libnl-route-3.0.pc \
|
||||
libnl-genl-3.0.pc \
|
||||
libnl-idiag-3.0.pc \
|
||||
libnl-nf-3.0.pc \
|
||||
libnl-route-3.0.pc \
|
||||
libnl-xfrm-3.0.pc \
|
||||
libnl-idiag-3.0.pc
|
||||
$(NULL)
|
||||
|
||||
warn_cppflags = \
|
||||
-Wall \
|
||||
@ -63,24 +64,28 @@ libnlinclude_netlink_HEADERS = \
|
||||
include/netlink/socket.h \
|
||||
include/netlink/types.h \
|
||||
include/netlink/utils.h \
|
||||
include/netlink/version.h
|
||||
include/netlink/version.h \
|
||||
$(NULL)
|
||||
libnlinclude_netlink_fib_lookupdir = $(libnlincludedir)/netlink/fib_lookup
|
||||
libnlinclude_netlink_fib_lookup_HEADERS = \
|
||||
include/netlink/fib_lookup/lookup.h \
|
||||
include/netlink/fib_lookup/request.h
|
||||
include/netlink/fib_lookup/request.h \
|
||||
$(NULL)
|
||||
libnlinclude_netlink_genldir = $(libnlincludedir)/netlink/genl
|
||||
libnlinclude_netlink_genl_HEADERS = \
|
||||
include/netlink/genl/ctrl.h \
|
||||
include/netlink/genl/family.h \
|
||||
include/netlink/genl/genl.h \
|
||||
include/netlink/genl/mngt.h
|
||||
include/netlink/genl/mngt.h \
|
||||
$(NULL)
|
||||
libnlinclude_netlink_idiagdir = $(libnlincludedir)/netlink/idiag
|
||||
libnlinclude_netlink_idiag_HEADERS = \
|
||||
include/netlink/idiag/idiagnl.h \
|
||||
include/netlink/idiag/meminfo.h \
|
||||
include/netlink/idiag/msg.h \
|
||||
include/netlink/idiag/req.h \
|
||||
include/netlink/idiag/vegasinfo.h
|
||||
include/netlink/idiag/vegasinfo.h \
|
||||
$(NULL)
|
||||
libnlinclude_netlink_netfilterdir = $(libnlincludedir)/netlink/netfilter
|
||||
libnlinclude_netlink_netfilter_HEADERS = \
|
||||
include/netlink/netfilter/ct.h \
|
||||
@ -90,7 +95,8 @@ libnlinclude_netlink_netfilter_HEADERS = \
|
||||
include/netlink/netfilter/netfilter.h \
|
||||
include/netlink/netfilter/nfnl.h \
|
||||
include/netlink/netfilter/queue.h \
|
||||
include/netlink/netfilter/queue_msg.h
|
||||
include/netlink/netfilter/queue_msg.h \
|
||||
$(NULL)
|
||||
libnlinclude_netlink_routedir = $(libnlincludedir)/netlink/route
|
||||
libnlinclude_netlink_route_HEADERS = \
|
||||
include/netlink/route/action.h \
|
||||
@ -108,33 +114,38 @@ libnlinclude_netlink_route_HEADERS = \
|
||||
include/netlink/route/rtnl.h \
|
||||
include/netlink/route/rule.h \
|
||||
include/netlink/route/tc-api.h \
|
||||
include/netlink/route/tc.h
|
||||
include/netlink/route/tc.h \
|
||||
$(NULL)
|
||||
libnlinclude_netlink_route_actdir = $(libnlincludedir)/netlink/route/act
|
||||
libnlinclude_netlink_route_act_HEADERS = \
|
||||
include/netlink/route/act/gact.h \
|
||||
include/netlink/route/act/mirred.h \
|
||||
include/netlink/route/act/skbedit.h
|
||||
include/netlink/route/act/skbedit.h \
|
||||
$(NULL)
|
||||
libnlinclude_netlink_route_clsdir = $(libnlincludedir)/netlink/route/cls
|
||||
libnlinclude_netlink_route_cls_HEADERS = \
|
||||
include/netlink/route/cls/basic.h \
|
||||
include/netlink/route/cls/cgroup.h \
|
||||
include/netlink/route/cls/ematch.h \
|
||||
include/netlink/route/cls/fw.h \
|
||||
include/netlink/route/cls/matchall.h \
|
||||
include/netlink/route/cls/police.h \
|
||||
include/netlink/route/cls/u32.h \
|
||||
include/netlink/route/cls/matchall.h
|
||||
$(NULL)
|
||||
libnlinclude_netlink_route_cls_ematchdir = $(libnlincludedir)/netlink/route/cls/ematch
|
||||
libnlinclude_netlink_route_cls_ematch_HEADERS = \
|
||||
include/netlink/route/cls/ematch/cmp.h \
|
||||
include/netlink/route/cls/ematch/meta.h \
|
||||
include/netlink/route/cls/ematch/nbyte.h \
|
||||
include/netlink/route/cls/ematch/text.h
|
||||
include/netlink/route/cls/ematch/text.h \
|
||||
$(NULL)
|
||||
libnlinclude_netlink_route_linkdir = $(libnlincludedir)/netlink/route/link
|
||||
libnlinclude_netlink_route_link_HEADERS = \
|
||||
include/netlink/route/link/api.h \
|
||||
include/netlink/route/link/bonding.h \
|
||||
include/netlink/route/link/bridge.h \
|
||||
include/netlink/route/link/can.h \
|
||||
include/netlink/route/link/geneve.h \
|
||||
include/netlink/route/link/inet.h \
|
||||
include/netlink/route/link/inet6.h \
|
||||
include/netlink/route/link/info-api.h \
|
||||
@ -153,7 +164,7 @@ libnlinclude_netlink_route_link_HEADERS = \
|
||||
include/netlink/route/link/vlan.h \
|
||||
include/netlink/route/link/vrf.h \
|
||||
include/netlink/route/link/vxlan.h \
|
||||
include/netlink/route/link/geneve.h
|
||||
$(NULL)
|
||||
libnlinclude_netlink_route_qdiscdir = $(libnlincludedir)/netlink/route/qdisc
|
||||
libnlinclude_netlink_route_qdisc_HEADERS = \
|
||||
include/netlink/route/qdisc/cbq.h \
|
||||
@ -162,12 +173,14 @@ libnlinclude_netlink_route_qdisc_HEADERS = \
|
||||
include/netlink/route/qdisc/fq_codel.h \
|
||||
include/netlink/route/qdisc/hfsc.h \
|
||||
include/netlink/route/qdisc/htb.h \
|
||||
include/netlink/route/qdisc/mqprio.h \
|
||||
include/netlink/route/qdisc/netem.h \
|
||||
include/netlink/route/qdisc/plug.h \
|
||||
include/netlink/route/qdisc/prio.h \
|
||||
include/netlink/route/qdisc/red.h \
|
||||
include/netlink/route/qdisc/sfq.h \
|
||||
include/netlink/route/qdisc/tbf.h
|
||||
include/netlink/route/qdisc/tbf.h \
|
||||
$(NULL)
|
||||
libnlinclude_netlink_xfrmdir = $(libnlincludedir)/netlink/xfrm
|
||||
libnlinclude_netlink_xfrm_HEADERS = \
|
||||
include/netlink/xfrm/ae.h \
|
||||
@ -175,7 +188,8 @@ libnlinclude_netlink_xfrm_HEADERS = \
|
||||
include/netlink/xfrm/sa.h \
|
||||
include/netlink/xfrm/selector.h \
|
||||
include/netlink/xfrm/sp.h \
|
||||
include/netlink/xfrm/template.h
|
||||
include/netlink/xfrm/template.h \
|
||||
$(NULL)
|
||||
|
||||
if ENABLE_CLI
|
||||
libnlinclude_netlink_clidir = $(libnlincludedir)/netlink/cli
|
||||
@ -191,7 +205,8 @@ libnlinclude_netlink_cli_HEADERS = \
|
||||
include/netlink/cli/route.h \
|
||||
include/netlink/cli/rule.h \
|
||||
include/netlink/cli/tc.h \
|
||||
include/netlink/cli/utils.h
|
||||
include/netlink/cli/utils.h \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
noinst_HEADERS = \
|
||||
@ -252,7 +267,8 @@ noinst_HEADERS = \
|
||||
include/netlink-private/socket.h \
|
||||
include/netlink-private/tc.h \
|
||||
include/netlink-private/types.h \
|
||||
include/netlink-private/utils.h
|
||||
include/netlink-private/utils.h \
|
||||
$(NULL)
|
||||
|
||||
###############################################################################
|
||||
|
||||
@ -284,10 +300,11 @@ lib/route/cls/ematch_syntax.c: lib/route/cls/ematch_syntax.y lib/route/cls/.dirs
|
||||
$(AM_V_GEN) $(YACC) -d $(YFLAGS) -o $@ $<
|
||||
|
||||
grammar_files_sources = \
|
||||
lib/route/cls/ematch_grammar.c \
|
||||
lib/route/cls/ematch_syntax.c \
|
||||
lib/route/pktloc_grammar.c \
|
||||
lib/route/pktloc_syntax.c \
|
||||
lib/route/cls/ematch_grammar.c \
|
||||
lib/route/cls/ematch_syntax.c
|
||||
$(NULL)
|
||||
|
||||
grammar_files_headers = $(grammar_files_sources:%.c=%.h)
|
||||
|
||||
@ -296,10 +313,11 @@ CLEANFILES += \
|
||||
$(grammar_files_headers)
|
||||
|
||||
EXTRA_DIST += \
|
||||
lib/route/cls/ematch_grammar.l \
|
||||
lib/route/cls/ematch_syntax.y \
|
||||
lib/route/pktloc_grammar.l \
|
||||
lib/route/pktloc_syntax.y \
|
||||
lib/route/cls/ematch_grammar.l \
|
||||
lib/route/cls/ematch_syntax.y
|
||||
$(NULL)
|
||||
|
||||
###############################################################################
|
||||
|
||||
@ -324,15 +342,16 @@ lib_libnl_3_la_SOURCES = \
|
||||
lib/data.c \
|
||||
lib/error.c \
|
||||
lib/handlers.c \
|
||||
lib/hash.c \
|
||||
lib/hashtable.c \
|
||||
lib/mpls.c \
|
||||
lib/msg.c \
|
||||
lib/nl.c \
|
||||
lib/object.c \
|
||||
lib/socket.c \
|
||||
lib/utils.c \
|
||||
lib/version.c \
|
||||
lib/hash.c \
|
||||
lib/hashtable.c \
|
||||
lib/mpls.c
|
||||
$(NULL)
|
||||
EXTRA_lib_libnl_3_la_DEPENDENCIES = \
|
||||
libnl-3.sym
|
||||
lib_libnl_3_la_CPPFLAGS = \
|
||||
@ -353,8 +372,8 @@ lib_libnl_route_3_la_SOURCES = \
|
||||
lib/route/addr.c \
|
||||
lib/route/class.c \
|
||||
lib/route/classid.c \
|
||||
lib/route/cls/basic.c \
|
||||
lib/route/cls.c \
|
||||
lib/route/cls/basic.c \
|
||||
lib/route/cls/cgroup.c \
|
||||
lib/route/cls/ematch.c \
|
||||
lib/route/cls/ematch/cmp.c \
|
||||
@ -363,18 +382,19 @@ lib_libnl_route_3_la_SOURCES = \
|
||||
lib/route/cls/ematch/nbyte.c \
|
||||
lib/route/cls/ematch/text.c \
|
||||
lib/route/cls/fw.c \
|
||||
lib/route/cls/mall.c \
|
||||
lib/route/cls/police.c \
|
||||
lib/route/cls/u32.c \
|
||||
lib/route/cls/mall.c \
|
||||
lib/route/link.c \
|
||||
lib/route/link/api.c \
|
||||
lib/route/link/bonding.c \
|
||||
lib/route/link/bridge.c \
|
||||
lib/route/link.c \
|
||||
lib/route/link/can.c \
|
||||
lib/route/link/dummy.c \
|
||||
lib/route/link/geneve.c \
|
||||
lib/route/link/ifb.c \
|
||||
lib/route/link/inet6.c \
|
||||
lib/route/link/inet.c \
|
||||
lib/route/link/inet6.c \
|
||||
lib/route/link/ip6tnl.c \
|
||||
lib/route/link/ipgre.c \
|
||||
lib/route/link/ipip.c \
|
||||
@ -389,7 +409,6 @@ lib_libnl_route_3_la_SOURCES = \
|
||||
lib/route/link/vlan.c \
|
||||
lib/route/link/vrf.c \
|
||||
lib/route/link/vxlan.c \
|
||||
lib/route/link/geneve.c \
|
||||
lib/route/neigh.c \
|
||||
lib/route/neightbl.c \
|
||||
lib/route/netconf.c \
|
||||
@ -397,8 +416,8 @@ lib_libnl_route_3_la_SOURCES = \
|
||||
lib/route/nexthop_encap.c \
|
||||
lib/route/nh_encap_mpls.c \
|
||||
lib/route/pktloc.c \
|
||||
lib/route/qdisc/blackhole.c \
|
||||
lib/route/qdisc.c \
|
||||
lib/route/qdisc/blackhole.c \
|
||||
lib/route/qdisc/cbq.c \
|
||||
lib/route/qdisc/dsmark.c \
|
||||
lib/route/qdisc/fifo.c \
|
||||
@ -406,6 +425,7 @@ lib_libnl_route_3_la_SOURCES = \
|
||||
lib/route/qdisc/hfsc.c \
|
||||
lib/route/qdisc/htb.c \
|
||||
lib/route/qdisc/ingress.c \
|
||||
lib/route/qdisc/mqprio.c \
|
||||
lib/route/qdisc/netem.c \
|
||||
lib/route/qdisc/plug.c \
|
||||
lib/route/qdisc/prio.c \
|
||||
@ -436,11 +456,12 @@ $(lib_libnl_route_3_la_OBJECTS): $(grammar_files_headers)
|
||||
lib_LTLIBRARIES += lib/libnl-idiag-3.la
|
||||
|
||||
lib_libnl_idiag_3_la_SOURCES = \
|
||||
lib/idiag/idiag.c \
|
||||
lib/idiag/idiag_meminfo_obj.c \
|
||||
lib/idiag/idiag_vegasinfo_obj.c \
|
||||
lib/idiag/idiag_msg_obj.c \
|
||||
lib/idiag/idiag_req_obj.c \
|
||||
lib/idiag/idiag.c
|
||||
lib/idiag/idiag_vegasinfo_obj.c \
|
||||
$(NULL)
|
||||
EXTRA_lib_libnl_idiag_3_la_DEPENDENCIES = \
|
||||
libnl-idiag-3.sym
|
||||
lib_libnl_idiag_3_la_CPPFLAGS = \
|
||||
@ -457,7 +478,8 @@ lib_libnl_genl_3_la_SOURCES = \
|
||||
lib/genl/ctrl.c \
|
||||
lib/genl/family.c \
|
||||
lib/genl/genl.c \
|
||||
lib/genl/mngt.c
|
||||
lib/genl/mngt.c \
|
||||
$(NULL)
|
||||
EXTRA_lib_libnl_genl_3_la_DEPENDENCIES = \
|
||||
libnl-genl-3.sym
|
||||
lib_libnl_genl_3_la_CPPFLAGS = \
|
||||
@ -473,6 +495,8 @@ lib_LTLIBRARIES += lib/libnl-nf-3.la
|
||||
lib_libnl_nf_3_la_SOURCES = \
|
||||
lib/netfilter/ct.c \
|
||||
lib/netfilter/ct_obj.c \
|
||||
lib/netfilter/exp.c \
|
||||
lib/netfilter/exp_obj.c \
|
||||
lib/netfilter/log.c \
|
||||
lib/netfilter/log_msg.c \
|
||||
lib/netfilter/log_msg_obj.c \
|
||||
@ -483,8 +507,7 @@ lib_libnl_nf_3_la_SOURCES = \
|
||||
lib/netfilter/queue_msg.c \
|
||||
lib/netfilter/queue_msg_obj.c \
|
||||
lib/netfilter/queue_obj.c \
|
||||
lib/netfilter/exp.c \
|
||||
lib/netfilter/exp_obj.c
|
||||
$(NULL)
|
||||
lib_libnl_nf_3_la_CPPFLAGS = \
|
||||
$(lib_cppflags)
|
||||
EXTRA_lib_libnl_nf_3_la_DEPENDENCIES = \
|
||||
@ -504,7 +527,8 @@ lib_libnl_xfrm_3_la_SOURCES = \
|
||||
lib/xfrm/sa.c \
|
||||
lib/xfrm/selector.c \
|
||||
lib/xfrm/sp.c \
|
||||
lib/xfrm/template.c
|
||||
lib/xfrm/template.c \
|
||||
$(NULL)
|
||||
lib_libnl_xfrm_3_la_CPPFLAGS = \
|
||||
$(lib_cppflags)
|
||||
lib_libnl_xfrm_3_la_LDFLAGS = \
|
||||
@ -517,7 +541,8 @@ lib_libnl_xfrm_3_la_LIBADD = \
|
||||
|
||||
lib_cli_ltlibraries_cls = \
|
||||
lib/cli/cls/basic.la \
|
||||
lib/cli/cls/cgroup.la
|
||||
lib/cli/cls/cgroup.la \
|
||||
$(NULL)
|
||||
lib_cli_ltlibraries_qdisc = \
|
||||
lib/cli/qdisc/bfifo.la \
|
||||
lib/cli/qdisc/blackhole.la \
|
||||
@ -526,7 +551,8 @@ lib_cli_ltlibraries_qdisc = \
|
||||
lib/cli/qdisc/htb.la \
|
||||
lib/cli/qdisc/ingress.la \
|
||||
lib/cli/qdisc/pfifo.la \
|
||||
lib/cli/qdisc/plug.la
|
||||
lib/cli/qdisc/plug.la \
|
||||
$(NULL)
|
||||
|
||||
if ENABLE_CLI
|
||||
pkglib_clsdir = $(pkglibdir)/cli/cls
|
||||
@ -575,18 +601,19 @@ check_LTLIBRARIES += src/lib/libnl-cli-3.la
|
||||
endif
|
||||
|
||||
src_lib_libnl_cli_3_la_SOURCES = \
|
||||
src/lib/utils.c \
|
||||
src/lib/addr.c \
|
||||
src/lib/ct.c \
|
||||
src/lib/link.c \
|
||||
src/lib/neigh.c \
|
||||
src/lib/rule.c \
|
||||
src/lib/route.c \
|
||||
src/lib/tc.c \
|
||||
src/lib/qdisc.c \
|
||||
src/lib/class.c \
|
||||
src/lib/cls.c \
|
||||
src/lib/exp.c
|
||||
src/lib/ct.c \
|
||||
src/lib/exp.c \
|
||||
src/lib/link.c \
|
||||
src/lib/neigh.c \
|
||||
src/lib/qdisc.c \
|
||||
src/lib/route.c \
|
||||
src/lib/rule.c \
|
||||
src/lib/tc.c \
|
||||
src/lib/utils.c \
|
||||
$(NULL)
|
||||
EXTRA_src_lib_libnl_cli_3_la_DEPENDENCIES = \
|
||||
libnl-cli-3.sym
|
||||
src_lib_libnl_cli_3_la_CPPFLAGS = \
|
||||
@ -605,7 +632,8 @@ src_lib_libnl_cli_3_la_LIBADD = \
|
||||
lib/libnl-route-3.la \
|
||||
lib/libnl-nf-3.la \
|
||||
lib/libnl-genl-3.la \
|
||||
-ldl
|
||||
-ldl \
|
||||
$(NULL)
|
||||
|
||||
###############################################################################
|
||||
|
||||
@ -623,7 +651,8 @@ src_ldadd = \
|
||||
lib/libnl-nf-3.la \
|
||||
lib/libnl-genl-3.la \
|
||||
lib/libnl-route-3.la \
|
||||
lib/libnl-idiag-3.la
|
||||
lib/libnl-idiag-3.la \
|
||||
$(NULL)
|
||||
|
||||
cli_programs = \
|
||||
src/genl-ctrl-list \
|
||||
@ -895,11 +924,12 @@ check_programs += tests/check-all
|
||||
endif
|
||||
|
||||
tests_check_all_SOURCES = \
|
||||
tests/util.h \
|
||||
tests/check-all.c \
|
||||
tests/check-addr.c \
|
||||
tests/check-all.c \
|
||||
tests/check-attr.c \
|
||||
tests/check-ematch-tree-clone.c
|
||||
tests/check-ematch-tree-clone.c \
|
||||
tests/util.h \
|
||||
$(NULL)
|
||||
|
||||
tests_check_all_CPPFLAGS = \
|
||||
$(tests_cppflags) \
|
||||
@ -912,12 +942,13 @@ tests_check_all_LDADD = \
|
||||
###############################################################################
|
||||
|
||||
dist_man8_MANS = \
|
||||
man/genl-ctrl-list.8 \
|
||||
man/nl-classid-lookup.8 \
|
||||
man/nl-pktloc-lookup.8 \
|
||||
man/nl-qdisc-add.8 \
|
||||
man/nl-qdisc-delete.8 \
|
||||
man/nl-qdisc-list.8 \
|
||||
man/genl-ctrl-list.8
|
||||
$(NULL)
|
||||
|
||||
###############################################################################
|
||||
|
||||
@ -980,4 +1011,5 @@ EXTRA_DIST += \
|
||||
libnl-idiag-3.sym \
|
||||
libnl-nf-3.sym \
|
||||
libnl-route-3.sym \
|
||||
libnl-xfrm-3.sym
|
||||
libnl-xfrm-3.sym \
|
||||
$(NULL)
|
||||
|
@ -1,3 +1,4 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
#ifndef __LINUX_PKT_SCHED_H
|
||||
#define __LINUX_PKT_SCHED_H
|
||||
|
||||
@ -30,7 +31,7 @@
|
||||
*/
|
||||
|
||||
struct tc_stats {
|
||||
__u64 bytes; /* NUmber of enqueues bytes */
|
||||
__u64 bytes; /* Number of enqueued bytes */
|
||||
__u32 packets; /* Number of enqueued packets */
|
||||
__u32 drops; /* Packets dropped because of lack of resources */
|
||||
__u32 overlimits; /* Number of throttle events when this
|
||||
@ -72,6 +73,11 @@ struct tc_estimator {
|
||||
#define TC_H_UNSPEC (0U)
|
||||
#define TC_H_ROOT (0xFFFFFFFFU)
|
||||
#define TC_H_INGRESS (0xFFFFFFF1U)
|
||||
#define TC_H_CLSACT TC_H_INGRESS
|
||||
|
||||
#define TC_H_MIN_PRIORITY 0xFFE0U
|
||||
#define TC_H_MIN_INGRESS 0xFFF2U
|
||||
#define TC_H_MIN_EGRESS 0xFFF3U
|
||||
|
||||
struct tc_ratespec {
|
||||
unsigned char cell_log;
|
||||
@ -135,17 +141,17 @@ struct tc_multiq_qopt {
|
||||
#define TCQ_PLUG_LIMIT 3
|
||||
|
||||
struct tc_plug_qopt {
|
||||
/* TCQ_PLUG_BUFFER: Inset a plug into the queue and
|
||||
* buffer any incoming packets
|
||||
* TCQ_PLUG_RELEASE_ONE: Dequeue packets from queue head
|
||||
* to beginning of the next plug.
|
||||
* TCQ_PLUG_RELEASE_INDEFINITE: Dequeue all packets from queue.
|
||||
* Stop buffering packets until the next TCQ_PLUG_BUFFER
|
||||
* command is received (just act as a pass-thru queue).
|
||||
* TCQ_PLUG_LIMIT: Increase/decrease queue size
|
||||
*/
|
||||
int action;
|
||||
__u32 limit;
|
||||
/* TCQ_PLUG_BUFFER: Inset a plug into the queue and
|
||||
* buffer any incoming packets
|
||||
* TCQ_PLUG_RELEASE_ONE: Dequeue packets from queue head
|
||||
* to beginning of the next plug.
|
||||
* TCQ_PLUG_RELEASE_INDEFINITE: Dequeue all packets from queue.
|
||||
* Stop buffering packets until the next TCQ_PLUG_BUFFER
|
||||
* command is received (just act as a pass-thru queue).
|
||||
* TCQ_PLUG_LIMIT: Increase/decrease queue size
|
||||
*/
|
||||
int action;
|
||||
__u32 limit;
|
||||
};
|
||||
|
||||
/* TBF section */
|
||||
@ -163,6 +169,11 @@ enum {
|
||||
TCA_TBF_PARMS,
|
||||
TCA_TBF_RTAB,
|
||||
TCA_TBF_PTAB,
|
||||
TCA_TBF_RATE64,
|
||||
TCA_TBF_PRATE64,
|
||||
TCA_TBF_BURST,
|
||||
TCA_TBF_PBURST,
|
||||
TCA_TBF_PAD,
|
||||
__TCA_TBF_MAX,
|
||||
};
|
||||
|
||||
@ -183,25 +194,44 @@ struct tc_sfq_qopt {
|
||||
unsigned flows; /* Maximal number of flows */
|
||||
};
|
||||
|
||||
struct tc_sfqred_stats {
|
||||
__u32 prob_drop; /* Early drops, below max threshold */
|
||||
__u32 forced_drop; /* Early drops, after max threshold */
|
||||
__u32 prob_mark; /* Marked packets, below max threshold */
|
||||
__u32 forced_mark; /* Marked packets, after max threshold */
|
||||
__u32 prob_mark_head; /* Marked packets, below max threshold */
|
||||
__u32 forced_mark_head;/* Marked packets, after max threshold */
|
||||
};
|
||||
|
||||
struct tc_sfq_qopt_v1 {
|
||||
struct tc_sfq_qopt v0;
|
||||
unsigned int depth; /* max number of packets per flow */
|
||||
unsigned int headdrop;
|
||||
/* SFQRED parameters */
|
||||
__u32 limit; /* HARD maximal flow queue length (bytes) */
|
||||
__u32 qth_min; /* Min average length threshold (bytes) */
|
||||
__u32 qth_max; /* Max average length threshold (bytes) */
|
||||
unsigned char Wlog; /* log(W) */
|
||||
unsigned char Plog; /* log(P_max/(qth_max-qth_min)) */
|
||||
unsigned char Scell_log; /* cell size for idle damping */
|
||||
unsigned char flags;
|
||||
__u32 max_P; /* probability, high resolution */
|
||||
/* SFQRED stats */
|
||||
struct tc_sfqred_stats stats;
|
||||
};
|
||||
|
||||
|
||||
struct tc_sfq_xstats {
|
||||
__s32 allot;
|
||||
};
|
||||
|
||||
/*
|
||||
* NOTE: limit, divisor and flows are hardwired to code at the moment.
|
||||
*
|
||||
* limit=flows=128, divisor=1024;
|
||||
*
|
||||
* The only reason for this is efficiency, it is possible
|
||||
* to change these parameters in compile time.
|
||||
*/
|
||||
|
||||
/* RED section */
|
||||
|
||||
enum {
|
||||
TCA_RED_UNSPEC,
|
||||
TCA_RED_PARMS,
|
||||
TCA_RED_STAB,
|
||||
TCA_RED_MAX_P,
|
||||
__TCA_RED_MAX,
|
||||
};
|
||||
|
||||
@ -215,8 +245,9 @@ struct tc_red_qopt {
|
||||
unsigned char Plog; /* log(P_max/(qth_max-qth_min)) */
|
||||
unsigned char Scell_log; /* cell size for idle damping */
|
||||
unsigned char flags;
|
||||
#define TC_RED_ECN 1
|
||||
#define TC_RED_HARDDROP 2
|
||||
#define TC_RED_ECN 1
|
||||
#define TC_RED_HARDDROP 2
|
||||
#define TC_RED_ADAPTATIVE 4
|
||||
};
|
||||
|
||||
struct tc_red_xstats {
|
||||
@ -235,7 +266,9 @@ enum {
|
||||
TCA_GRED_PARMS,
|
||||
TCA_GRED_STAB,
|
||||
TCA_GRED_DPS,
|
||||
__TCA_GRED_MAX,
|
||||
TCA_GRED_MAX_P,
|
||||
TCA_GRED_LIMIT,
|
||||
__TCA_GRED_MAX,
|
||||
};
|
||||
|
||||
#define TCA_GRED_MAX (__TCA_GRED_MAX - 1)
|
||||
@ -274,6 +307,7 @@ enum {
|
||||
TCA_CHOKE_UNSPEC,
|
||||
TCA_CHOKE_PARMS,
|
||||
TCA_CHOKE_STAB,
|
||||
TCA_CHOKE_MAX_P,
|
||||
__TCA_CHOKE_MAX,
|
||||
};
|
||||
|
||||
@ -318,7 +352,7 @@ struct tc_htb_glob {
|
||||
__u32 debug; /* debug flags */
|
||||
|
||||
/* stats */
|
||||
__u32 direct_pkts; /* count of non shapped packets */
|
||||
__u32 direct_pkts; /* count of non shaped packets */
|
||||
};
|
||||
enum {
|
||||
TCA_HTB_UNSPEC,
|
||||
@ -326,6 +360,10 @@ enum {
|
||||
TCA_HTB_INIT,
|
||||
TCA_HTB_CTAB,
|
||||
TCA_HTB_RTAB,
|
||||
TCA_HTB_DIRECT_QLEN,
|
||||
TCA_HTB_RATE64,
|
||||
TCA_HTB_CEIL64,
|
||||
TCA_HTB_PAD,
|
||||
__TCA_HTB_MAX,
|
||||
};
|
||||
|
||||
@ -462,21 +500,6 @@ enum {
|
||||
|
||||
#define TCA_DSMARK_MAX (__TCA_DSMARK_MAX - 1)
|
||||
|
||||
/* fq_codel section */
|
||||
|
||||
enum {
|
||||
TCA_FQ_CODEL_UNSPEC,
|
||||
TCA_FQ_CODEL_TARGET,
|
||||
TCA_FQ_CODEL_LIMIT,
|
||||
TCA_FQ_CODEL_INTERVAL,
|
||||
TCA_FQ_CODEL_ECN,
|
||||
TCA_FQ_CODEL_FLOWS,
|
||||
TCA_FQ_CODEL_QUANTUM,
|
||||
__TCA_FQ_CODEL_MAX
|
||||
};
|
||||
|
||||
#define TCA_FQ_CODEL_MAX (__TCA_FQ_CODEL_MAX - 1)
|
||||
|
||||
/* ATM section */
|
||||
|
||||
enum {
|
||||
@ -501,6 +524,13 @@ enum {
|
||||
TCA_NETEM_REORDER,
|
||||
TCA_NETEM_CORRUPT,
|
||||
TCA_NETEM_LOSS,
|
||||
TCA_NETEM_RATE,
|
||||
TCA_NETEM_ECN,
|
||||
TCA_NETEM_RATE64,
|
||||
TCA_NETEM_PAD,
|
||||
TCA_NETEM_LATENCY64,
|
||||
TCA_NETEM_JITTER64,
|
||||
TCA_NETEM_SLOT,
|
||||
__TCA_NETEM_MAX,
|
||||
};
|
||||
|
||||
@ -531,6 +561,20 @@ struct tc_netem_corrupt {
|
||||
__u32 correlation;
|
||||
};
|
||||
|
||||
struct tc_netem_rate {
|
||||
__u32 rate; /* byte/s */
|
||||
__s32 packet_overhead;
|
||||
__u32 cell_size;
|
||||
__s32 cell_overhead;
|
||||
};
|
||||
|
||||
struct tc_netem_slot {
|
||||
__s64 min_delay; /* nsec */
|
||||
__s64 max_delay;
|
||||
__s32 max_packets;
|
||||
__s32 max_bytes;
|
||||
};
|
||||
|
||||
enum {
|
||||
NETEM_LOSS_UNSPEC,
|
||||
NETEM_LOSS_GI, /* General Intuitive - 4 state model */
|
||||
@ -539,7 +583,7 @@ enum {
|
||||
};
|
||||
#define NETEM_LOSS_MAX (__NETEM_LOSS_MAX - 1)
|
||||
|
||||
/* State transition probablities for 4 state model */
|
||||
/* State transition probabilities for 4 state model */
|
||||
struct tc_netem_gimodel {
|
||||
__u32 p13;
|
||||
__u32 p31;
|
||||
@ -577,6 +621,30 @@ struct tc_drr_stats {
|
||||
#define TC_QOPT_BITMASK 15
|
||||
#define TC_QOPT_MAX_QUEUE 16
|
||||
|
||||
enum {
|
||||
TC_MQPRIO_HW_OFFLOAD_NONE, /* no offload requested */
|
||||
TC_MQPRIO_HW_OFFLOAD_TCS, /* offload TCs, no queue counts */
|
||||
__TC_MQPRIO_HW_OFFLOAD_MAX
|
||||
};
|
||||
|
||||
#define TC_MQPRIO_HW_OFFLOAD_MAX (__TC_MQPRIO_HW_OFFLOAD_MAX - 1)
|
||||
|
||||
enum {
|
||||
TC_MQPRIO_MODE_DCB,
|
||||
TC_MQPRIO_MODE_CHANNEL,
|
||||
__TC_MQPRIO_MODE_MAX
|
||||
};
|
||||
|
||||
#define __TC_MQPRIO_MODE_MAX (__TC_MQPRIO_MODE_MAX - 1)
|
||||
|
||||
enum {
|
||||
TC_MQPRIO_SHAPER_DCB,
|
||||
TC_MQPRIO_SHAPER_BW_RATE, /* Add new shapers below */
|
||||
__TC_MQPRIO_SHAPER_MAX
|
||||
};
|
||||
|
||||
#define __TC_MQPRIO_SHAPER_MAX (__TC_MQPRIO_SHAPER_MAX - 1)
|
||||
|
||||
struct tc_mqprio_qopt {
|
||||
__u8 num_tc;
|
||||
__u8 prio_tc_map[TC_QOPT_BITMASK + 1];
|
||||
@ -585,6 +653,22 @@ struct tc_mqprio_qopt {
|
||||
__u16 offset[TC_QOPT_MAX_QUEUE];
|
||||
};
|
||||
|
||||
#define TC_MQPRIO_F_MODE 0x1
|
||||
#define TC_MQPRIO_F_SHAPER 0x2
|
||||
#define TC_MQPRIO_F_MIN_RATE 0x4
|
||||
#define TC_MQPRIO_F_MAX_RATE 0x8
|
||||
|
||||
enum {
|
||||
TCA_MQPRIO_UNSPEC,
|
||||
TCA_MQPRIO_MODE,
|
||||
TCA_MQPRIO_SHAPER,
|
||||
TCA_MQPRIO_MIN_RATE64,
|
||||
TCA_MQPRIO_MAX_RATE64,
|
||||
__TCA_MQPRIO_MAX,
|
||||
};
|
||||
|
||||
#define TCA_MQPRIO_MAX (__TCA_MQPRIO_MAX - 1)
|
||||
|
||||
/* SFB */
|
||||
|
||||
enum {
|
||||
@ -639,4 +723,207 @@ struct tc_qfq_stats {
|
||||
__u32 lmax;
|
||||
};
|
||||
|
||||
/* CODEL */
|
||||
|
||||
enum {
|
||||
TCA_CODEL_UNSPEC,
|
||||
TCA_CODEL_TARGET,
|
||||
TCA_CODEL_LIMIT,
|
||||
TCA_CODEL_INTERVAL,
|
||||
TCA_CODEL_ECN,
|
||||
TCA_CODEL_CE_THRESHOLD,
|
||||
__TCA_CODEL_MAX
|
||||
};
|
||||
|
||||
#define TCA_CODEL_MAX (__TCA_CODEL_MAX - 1)
|
||||
|
||||
struct tc_codel_xstats {
|
||||
__u32 maxpacket; /* largest packet we've seen so far */
|
||||
__u32 count; /* how many drops we've done since the last time we
|
||||
* entered dropping state
|
||||
*/
|
||||
__u32 lastcount; /* count at entry to dropping state */
|
||||
__u32 ldelay; /* in-queue delay seen by most recently dequeued packet */
|
||||
__s32 drop_next; /* time to drop next packet */
|
||||
__u32 drop_overlimit; /* number of time max qdisc packet limit was hit */
|
||||
__u32 ecn_mark; /* number of packets we ECN marked instead of dropped */
|
||||
__u32 dropping; /* are we in dropping state ? */
|
||||
__u32 ce_mark; /* number of CE marked packets because of ce_threshold */
|
||||
};
|
||||
|
||||
/* FQ_CODEL */
|
||||
|
||||
enum {
|
||||
TCA_FQ_CODEL_UNSPEC,
|
||||
TCA_FQ_CODEL_TARGET,
|
||||
TCA_FQ_CODEL_LIMIT,
|
||||
TCA_FQ_CODEL_INTERVAL,
|
||||
TCA_FQ_CODEL_ECN,
|
||||
TCA_FQ_CODEL_FLOWS,
|
||||
TCA_FQ_CODEL_QUANTUM,
|
||||
TCA_FQ_CODEL_CE_THRESHOLD,
|
||||
TCA_FQ_CODEL_DROP_BATCH_SIZE,
|
||||
TCA_FQ_CODEL_MEMORY_LIMIT,
|
||||
__TCA_FQ_CODEL_MAX
|
||||
};
|
||||
|
||||
#define TCA_FQ_CODEL_MAX (__TCA_FQ_CODEL_MAX - 1)
|
||||
|
||||
enum {
|
||||
TCA_FQ_CODEL_XSTATS_QDISC,
|
||||
TCA_FQ_CODEL_XSTATS_CLASS,
|
||||
};
|
||||
|
||||
struct tc_fq_codel_qd_stats {
|
||||
__u32 maxpacket; /* largest packet we've seen so far */
|
||||
__u32 drop_overlimit; /* number of time max qdisc
|
||||
* packet limit was hit
|
||||
*/
|
||||
__u32 ecn_mark; /* number of packets we ECN marked
|
||||
* instead of being dropped
|
||||
*/
|
||||
__u32 new_flow_count; /* number of time packets
|
||||
* created a 'new flow'
|
||||
*/
|
||||
__u32 new_flows_len; /* count of flows in new list */
|
||||
__u32 old_flows_len; /* count of flows in old list */
|
||||
__u32 ce_mark; /* packets above ce_threshold */
|
||||
__u32 memory_usage; /* in bytes */
|
||||
__u32 drop_overmemory;
|
||||
};
|
||||
|
||||
struct tc_fq_codel_cl_stats {
|
||||
__s32 deficit;
|
||||
__u32 ldelay; /* in-queue delay seen by most recently
|
||||
* dequeued packet
|
||||
*/
|
||||
__u32 count;
|
||||
__u32 lastcount;
|
||||
__u32 dropping;
|
||||
__s32 drop_next;
|
||||
};
|
||||
|
||||
struct tc_fq_codel_xstats {
|
||||
__u32 type;
|
||||
union {
|
||||
struct tc_fq_codel_qd_stats qdisc_stats;
|
||||
struct tc_fq_codel_cl_stats class_stats;
|
||||
};
|
||||
};
|
||||
|
||||
/* FQ */
|
||||
|
||||
enum {
|
||||
TCA_FQ_UNSPEC,
|
||||
|
||||
TCA_FQ_PLIMIT, /* limit of total number of packets in queue */
|
||||
|
||||
TCA_FQ_FLOW_PLIMIT, /* limit of packets per flow */
|
||||
|
||||
TCA_FQ_QUANTUM, /* RR quantum */
|
||||
|
||||
TCA_FQ_INITIAL_QUANTUM, /* RR quantum for new flow */
|
||||
|
||||
TCA_FQ_RATE_ENABLE, /* enable/disable rate limiting */
|
||||
|
||||
TCA_FQ_FLOW_DEFAULT_RATE,/* obsolete, do not use */
|
||||
|
||||
TCA_FQ_FLOW_MAX_RATE, /* per flow max rate */
|
||||
|
||||
TCA_FQ_BUCKETS_LOG, /* log2(number of buckets) */
|
||||
|
||||
TCA_FQ_FLOW_REFILL_DELAY, /* flow credit refill delay in usec */
|
||||
|
||||
TCA_FQ_ORPHAN_MASK, /* mask applied to orphaned skb hashes */
|
||||
|
||||
TCA_FQ_LOW_RATE_THRESHOLD, /* per packet delay under this rate */
|
||||
|
||||
__TCA_FQ_MAX
|
||||
};
|
||||
|
||||
#define TCA_FQ_MAX (__TCA_FQ_MAX - 1)
|
||||
|
||||
struct tc_fq_qd_stats {
|
||||
__u64 gc_flows;
|
||||
__u64 highprio_packets;
|
||||
__u64 tcp_retrans;
|
||||
__u64 throttled;
|
||||
__u64 flows_plimit;
|
||||
__u64 pkts_too_long;
|
||||
__u64 allocation_errors;
|
||||
__s64 time_next_delayed_flow;
|
||||
__u32 flows;
|
||||
__u32 inactive_flows;
|
||||
__u32 throttled_flows;
|
||||
__u32 unthrottle_latency_ns;
|
||||
};
|
||||
|
||||
/* Heavy-Hitter Filter */
|
||||
|
||||
enum {
|
||||
TCA_HHF_UNSPEC,
|
||||
TCA_HHF_BACKLOG_LIMIT,
|
||||
TCA_HHF_QUANTUM,
|
||||
TCA_HHF_HH_FLOWS_LIMIT,
|
||||
TCA_HHF_RESET_TIMEOUT,
|
||||
TCA_HHF_ADMIT_BYTES,
|
||||
TCA_HHF_EVICT_TIMEOUT,
|
||||
TCA_HHF_NON_HH_WEIGHT,
|
||||
__TCA_HHF_MAX
|
||||
};
|
||||
|
||||
#define TCA_HHF_MAX (__TCA_HHF_MAX - 1)
|
||||
|
||||
struct tc_hhf_xstats {
|
||||
__u32 drop_overlimit; /* number of times max qdisc packet limit
|
||||
* was hit
|
||||
*/
|
||||
__u32 hh_overlimit; /* number of times max heavy-hitters was hit */
|
||||
__u32 hh_tot_count; /* number of captured heavy-hitters so far */
|
||||
__u32 hh_cur_count; /* number of current heavy-hitters */
|
||||
};
|
||||
|
||||
/* PIE */
|
||||
enum {
|
||||
TCA_PIE_UNSPEC,
|
||||
TCA_PIE_TARGET,
|
||||
TCA_PIE_LIMIT,
|
||||
TCA_PIE_TUPDATE,
|
||||
TCA_PIE_ALPHA,
|
||||
TCA_PIE_BETA,
|
||||
TCA_PIE_ECN,
|
||||
TCA_PIE_BYTEMODE,
|
||||
__TCA_PIE_MAX
|
||||
};
|
||||
#define TCA_PIE_MAX (__TCA_PIE_MAX - 1)
|
||||
|
||||
struct tc_pie_xstats {
|
||||
__u32 prob; /* current probability */
|
||||
__u32 delay; /* current delay in ms */
|
||||
__u32 avg_dq_rate; /* current average dq_rate in bits/pie_time */
|
||||
__u32 packets_in; /* total number of packets enqueued */
|
||||
__u32 dropped; /* packets dropped due to pie_action */
|
||||
__u32 overlimit; /* dropped due to lack of space in queue */
|
||||
__u32 maxq; /* maximum queue size */
|
||||
__u32 ecn_mark; /* packets marked with ecn*/
|
||||
};
|
||||
|
||||
/* CBS */
|
||||
struct tc_cbs_qopt {
|
||||
__u8 offload;
|
||||
__u8 _pad[3];
|
||||
__s32 hicredit;
|
||||
__s32 locredit;
|
||||
__s32 idleslope;
|
||||
__s32 sendslope;
|
||||
};
|
||||
|
||||
enum {
|
||||
TCA_CBS_UNSPEC,
|
||||
TCA_CBS_PARMS,
|
||||
__TCA_CBS_MAX,
|
||||
};
|
||||
|
||||
#define TCA_CBS_MAX (__TCA_CBS_MAX - 1)
|
||||
|
||||
#endif
|
||||
|
@ -679,6 +679,20 @@ struct rtnl_prio
|
||||
uint32_t qp_mask;
|
||||
};
|
||||
|
||||
struct rtnl_mqprio
|
||||
{
|
||||
uint8_t qm_num_tc;
|
||||
uint8_t qm_prio_map[TC_QOPT_BITMASK + 1];
|
||||
uint8_t qm_hw;
|
||||
uint16_t qm_count[TC_QOPT_MAX_QUEUE];
|
||||
uint16_t qm_offset[TC_QOPT_MAX_QUEUE];
|
||||
uint16_t qm_mode;
|
||||
uint16_t qm_shaper;
|
||||
uint64_t qm_min_rate[TC_QOPT_MAX_QUEUE];
|
||||
uint64_t qm_max_rate[TC_QOPT_MAX_QUEUE];
|
||||
uint32_t qm_mask;
|
||||
};
|
||||
|
||||
struct rtnl_tbf
|
||||
{
|
||||
uint32_t qt_limit;
|
||||
|
48
include/netlink/route/qdisc/mqprio.h
Normal file
48
include/netlink/route/qdisc/mqprio.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* lib/route/qdisc/mqprio.c MQPRIO Qdisc/Class
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* Copyright (c) 2018 Volodymyr Bendiuga <volodymyr.bendiuga@westermo.se>
|
||||
*/
|
||||
|
||||
#ifndef NETLINK_MQPRIO_H_
|
||||
#define NETLINK_MQPRIO_H_
|
||||
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/route/qdisc.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int rtnl_qdisc_mqprio_set_num_tc(struct rtnl_qdisc *qdisc, int num_tc);
|
||||
extern int rtnl_qdisc_mqprio_get_num_tc(struct rtnl_qdisc *qdisc);
|
||||
extern int rtnl_qdisc_mqprio_set_priomap(struct rtnl_qdisc *qdisc, uint8_t priomap[],
|
||||
int len);
|
||||
extern uint8_t *rtnl_qdisc_mqprio_get_priomap(struct rtnl_qdisc *qdisc);
|
||||
extern int rtnl_qdisc_mqprio_hw_offload(struct rtnl_qdisc *qdisc, int offload);
|
||||
extern int rtnl_qdisc_mqprio_get_hw_offload(struct rtnl_qdisc *qdisc);
|
||||
extern int rtnl_qdisc_mqprio_set_queue(struct rtnl_qdisc *qdisc, uint16_t count[],
|
||||
uint16_t offset[], int len);
|
||||
extern int rtnl_qdisc_mqprio_get_queue(struct rtnl_qdisc *qdisc, uint16_t *count,
|
||||
uint16_t *offset);
|
||||
extern int rtnl_qdisc_mqprio_set_mode(struct rtnl_qdisc *qdisc, uint16_t mode);
|
||||
extern int rtnl_qdisc_mqprio_get_mode(struct rtnl_qdisc *qdisc);
|
||||
extern int rtnl_qdisc_mqprio_set_shaper(struct rtnl_qdisc *qdisc, uint16_t shaper);
|
||||
extern int rtnl_qdisc_mqprio_get_shaper(struct rtnl_qdisc *qdisc);
|
||||
extern int rtnl_qdisc_mqprio_set_min_rate(struct rtnl_qdisc *qdisc, uint64_t min[],
|
||||
int len);
|
||||
extern int rtnl_qdisc_mqprio_get_min_rate(struct rtnl_qdisc *qdisc, uint64_t *min);
|
||||
extern int rtnl_qdisc_mqprio_set_max_rate(struct rtnl_qdisc *qdisc, uint64_t max[],
|
||||
int len);
|
||||
extern int rtnl_qdisc_mqprio_get_max_rate(struct rtnl_qdisc *qdisc, uint64_t *max);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NETLINK_MQPRIO_H_ */
|
605
lib/route/qdisc/mqprio.c
Normal file
605
lib/route/qdisc/mqprio.c
Normal file
@ -0,0 +1,605 @@
|
||||
/*
|
||||
* lib/route/qdisc/mqprio.c MQPRIO Qdisc/Class
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* Copyright (c) 2018 Volodymyr Bendiuga <volodymyr.bendiuga@westermo.se>
|
||||
*/
|
||||
|
||||
#include <netlink-private/netlink.h>
|
||||
#include <netlink-private/tc.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/utils.h>
|
||||
#include <netlink-private/route/tc-api.h>
|
||||
#include <netlink/route/qdisc.h>
|
||||
#include <netlink/route/qdisc/mqprio.h>
|
||||
|
||||
/** @cond SKIP */
|
||||
#define SCH_MQPRIO_ATTR_NUMTC (1 << 0)
|
||||
#define SCH_MQPRIO_ATTR_PRIOMAP (1 << 1)
|
||||
#define SCH_MQPRIO_ATTR_HW (1 << 2)
|
||||
#define SCH_MQPRIO_ATTR_QUEUE (1 << 3)
|
||||
#define SCH_MQPRIO_ATTR_MODE (1 << 4)
|
||||
#define SCH_MQPRIO_ATTR_SHAPER (1 << 5)
|
||||
#define SCH_MQPRIO_ATTR_MIN_RATE (1 << 6)
|
||||
#define SCH_MQPRIO_ATTR_MAX_RATE (1 << 7)
|
||||
/** @endcond */
|
||||
|
||||
static struct nla_policy mqprio_policy[TCA_MQPRIO_MAX + 1] = {
|
||||
[TCA_MQPRIO_MODE] = { .minlen = sizeof(uint16_t) },
|
||||
[TCA_MQPRIO_SHAPER] = { .minlen = sizeof(uint16_t) },
|
||||
[TCA_MQPRIO_MIN_RATE64] = { .type = NLA_NESTED },
|
||||
[TCA_MQPRIO_MAX_RATE64] = { .type = NLA_NESTED },
|
||||
};
|
||||
|
||||
static int mqprio_msg_parser(struct rtnl_tc *tc, void *data)
|
||||
{
|
||||
struct rtnl_mqprio *mqprio = data;
|
||||
struct tc_mqprio_qopt *qopt;
|
||||
struct nlattr *attr;
|
||||
int len, rem, i, err;
|
||||
|
||||
if (tc->tc_opts->d_size < sizeof(*qopt))
|
||||
return -NLE_INVAL;
|
||||
|
||||
qopt = (struct tc_mqprio_qopt *) tc->tc_opts->d_data;
|
||||
mqprio->qm_num_tc = qopt->num_tc;
|
||||
mqprio->qm_hw = qopt->hw;
|
||||
memcpy(mqprio->qm_prio_map, qopt->prio_tc_map,
|
||||
TC_QOPT_MAX_QUEUE * sizeof(uint8_t));
|
||||
memcpy(mqprio->qm_count, qopt->count,
|
||||
TC_QOPT_MAX_QUEUE * sizeof(uint16_t));
|
||||
memcpy(mqprio->qm_offset, qopt->offset,
|
||||
TC_QOPT_MAX_QUEUE * sizeof(uint16_t));
|
||||
mqprio->qm_mask = (SCH_MQPRIO_ATTR_NUMTC | SCH_MQPRIO_ATTR_PRIOMAP |
|
||||
SCH_MQPRIO_ATTR_QUEUE | SCH_MQPRIO_ATTR_HW);
|
||||
|
||||
len = tc->tc_opts->d_size - NLA_ALIGN(sizeof(*qopt));
|
||||
|
||||
if (len > 0) {
|
||||
struct nlattr *tb[TCA_MQPRIO_MAX + 1];
|
||||
|
||||
err = nla_parse(tb, TCA_MQPRIO_MAX, (struct nlattr *)
|
||||
(tc->tc_opts->d_data + NLA_ALIGN(sizeof(*qopt))),
|
||||
len, mqprio_policy);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (tb[TCA_MQPRIO_MODE]) {
|
||||
mqprio->qm_mode = nla_get_u16(tb[TCA_MQPRIO_MODE]);
|
||||
mqprio->qm_mask |= SCH_MQPRIO_ATTR_MODE;
|
||||
}
|
||||
|
||||
if (tb[TCA_MQPRIO_SHAPER]) {
|
||||
mqprio->qm_shaper = nla_get_u16(tb[TCA_MQPRIO_SHAPER]);
|
||||
mqprio->qm_mask |= SCH_MQPRIO_ATTR_SHAPER;
|
||||
}
|
||||
|
||||
if (tb[TCA_MQPRIO_MIN_RATE64]) {
|
||||
i = 0;
|
||||
nla_for_each_nested(attr, tb[TCA_MQPRIO_MIN_RATE64], rem) {
|
||||
if (nla_type(attr) != TCA_MQPRIO_MIN_RATE64)
|
||||
return -EINVAL;
|
||||
|
||||
if (i >= mqprio->qm_num_tc)
|
||||
break;
|
||||
|
||||
mqprio->qm_min_rate[i] = nla_get_u64(attr);
|
||||
}
|
||||
|
||||
mqprio->qm_mask |= SCH_MQPRIO_ATTR_MIN_RATE;
|
||||
}
|
||||
|
||||
if (tb[TCA_MQPRIO_MAX_RATE64]) {
|
||||
i = 0;
|
||||
nla_for_each_nested(attr, tb[TCA_MQPRIO_MAX_RATE64], rem) {
|
||||
if (nla_type(attr) != TCA_MQPRIO_MAX_RATE64)
|
||||
return -EINVAL;
|
||||
|
||||
if (i >= mqprio->qm_num_tc)
|
||||
break;
|
||||
|
||||
mqprio->qm_max_rate[i] = nla_get_u64(attr);
|
||||
}
|
||||
|
||||
mqprio->qm_mask |= SCH_MQPRIO_ATTR_MAX_RATE;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mqprio_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg)
|
||||
{
|
||||
struct rtnl_mqprio *mqprio = data;
|
||||
struct tc_mqprio_qopt qopt = { 0 };
|
||||
struct nlattr *nest = NULL;
|
||||
int i;
|
||||
|
||||
if (!mqprio ||
|
||||
!(mqprio->qm_mask & SCH_MQPRIO_ATTR_NUMTC) ||
|
||||
!(mqprio->qm_mask & SCH_MQPRIO_ATTR_PRIOMAP) ||
|
||||
!(mqprio->qm_mask & SCH_MQPRIO_ATTR_QUEUE))
|
||||
return -NLE_INVAL;
|
||||
|
||||
if (!(mqprio->qm_mask & SCH_MQPRIO_ATTR_HW))
|
||||
qopt.hw = 0;
|
||||
else
|
||||
qopt.hw = mqprio->qm_hw;
|
||||
|
||||
qopt.num_tc = mqprio->qm_num_tc;
|
||||
memcpy(qopt.count, mqprio->qm_count, TC_QOPT_MAX_QUEUE * sizeof(uint16_t));
|
||||
memcpy(qopt.offset, mqprio->qm_offset, TC_QOPT_MAX_QUEUE * sizeof(uint16_t));
|
||||
memcpy(qopt.prio_tc_map, mqprio->qm_prio_map, TC_QOPT_MAX_QUEUE * sizeof(uint8_t));
|
||||
|
||||
nlmsg_append(msg, &qopt, sizeof(qopt), NL_DONTPAD);
|
||||
|
||||
if (mqprio->qm_hw) {
|
||||
if (mqprio->qm_mask & SCH_MQPRIO_ATTR_MODE)
|
||||
NLA_PUT_U16(msg, TCA_MQPRIO_MODE, mqprio->qm_mode);
|
||||
|
||||
if (mqprio->qm_mask & SCH_MQPRIO_ATTR_SHAPER)
|
||||
NLA_PUT_U16(msg, TCA_MQPRIO_SHAPER, mqprio->qm_shaper);
|
||||
|
||||
if (mqprio->qm_mask & SCH_MQPRIO_ATTR_MIN_RATE) {
|
||||
nest = nla_nest_start(msg, TCA_MQPRIO_MIN_RATE64);
|
||||
if (!nest)
|
||||
goto nla_put_failure;
|
||||
|
||||
for (i = 0; i < mqprio->qm_num_tc; i++) {
|
||||
if (nla_put(msg, TCA_MQPRIO_MIN_RATE64,
|
||||
sizeof(mqprio->qm_min_rate[i]),
|
||||
&mqprio->qm_min_rate[i]) < 0)
|
||||
goto nla_nest_cancel;
|
||||
}
|
||||
nla_nest_end(msg, nest);
|
||||
}
|
||||
|
||||
if (mqprio->qm_mask & SCH_MQPRIO_ATTR_MAX_RATE) {
|
||||
nest = nla_nest_start(msg, TCA_MQPRIO_MAX_RATE64);
|
||||
if (!nest)
|
||||
goto nla_put_failure;
|
||||
|
||||
for (i = 0; i < mqprio->qm_num_tc; i++) {
|
||||
if (nla_put(msg, TCA_MQPRIO_MAX_RATE64,
|
||||
sizeof(mqprio->qm_max_rate[i]),
|
||||
&mqprio->qm_max_rate[i]) < 0)
|
||||
goto nla_nest_cancel;
|
||||
}
|
||||
nla_nest_end(msg, nest);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
nla_nest_cancel:
|
||||
nla_nest_cancel(msg, nest);
|
||||
return -NLE_MSGSIZE;
|
||||
|
||||
nla_put_failure:
|
||||
return -NLE_MSGSIZE;
|
||||
}
|
||||
|
||||
static void mqprio_dump_line(struct rtnl_tc *tc, void *data,
|
||||
struct nl_dump_params *p)
|
||||
{
|
||||
struct rtnl_mqprio *mqprio = data;
|
||||
|
||||
if (mqprio)
|
||||
nl_dump(p, " num_tc %u", mqprio->qm_num_tc);
|
||||
}
|
||||
|
||||
static void mqprio_dump_details(struct rtnl_tc *tc, void *data,
|
||||
struct nl_dump_params *p)
|
||||
{
|
||||
struct rtnl_mqprio *mqprio = data;
|
||||
int i;
|
||||
|
||||
if (!mqprio)
|
||||
return;
|
||||
|
||||
nl_dump(p, "map [");
|
||||
|
||||
for (i = 0; i <= TC_QOPT_BITMASK; i++)
|
||||
nl_dump(p, "%u%s", mqprio->qm_prio_map[i],
|
||||
i < TC_QOPT_BITMASK ? " " : "");
|
||||
|
||||
nl_dump(p, "]\n");
|
||||
nl_new_line(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Attribute Modification
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Set number of traffic classes.
|
||||
* @arg qdisc MQPRIO qdisc to be modified.
|
||||
* @arg num_tc Number of traffic classes to create.
|
||||
* @return 0 on success or a negative error code.
|
||||
*/
|
||||
int rtnl_qdisc_mqprio_set_num_tc(struct rtnl_qdisc *qdisc, int num_tc)
|
||||
{
|
||||
struct rtnl_mqprio *mqprio;
|
||||
|
||||
if (!(mqprio = rtnl_tc_data(TC_CAST(qdisc))))
|
||||
return -NLE_NOMEM;
|
||||
|
||||
mqprio->qm_num_tc = num_tc;
|
||||
mqprio->qm_mask |= SCH_MQPRIO_ATTR_NUMTC;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number of traffic classes of MQPRIO qdisc.
|
||||
* @arg qdisc MQPRIO qdisc.
|
||||
* @return Number of traffic classes or a negative error code.
|
||||
*/
|
||||
int rtnl_qdisc_mqprio_get_num_tc(struct rtnl_qdisc *qdisc)
|
||||
{
|
||||
struct rtnl_mqprio *mqprio;
|
||||
|
||||
if (!(mqprio = rtnl_tc_data_peek(TC_CAST(qdisc))))
|
||||
return -NLE_INVAL;
|
||||
|
||||
if (mqprio->qm_mask & SCH_MQPRIO_ATTR_NUMTC)
|
||||
return mqprio->qm_num_tc;
|
||||
else
|
||||
return -NLE_MISSING_ATTR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set priomap of the MQPRIO qdisc.
|
||||
* @arg qdisc MQPRIO qdisc to be modified.
|
||||
* @arg priomap New priority mapping.
|
||||
* @arg len Length of priomap (# of elements).
|
||||
* @return 0 on success or a negative error code.
|
||||
*/
|
||||
int rtnl_qdisc_mqprio_set_priomap(struct rtnl_qdisc *qdisc, uint8_t priomap[],
|
||||
int len)
|
||||
{
|
||||
struct rtnl_mqprio *mqprio;
|
||||
int i;
|
||||
|
||||
if (!(mqprio = rtnl_tc_data(TC_CAST(qdisc))))
|
||||
return -NLE_NOMEM;
|
||||
|
||||
if (!(mqprio->qm_mask & SCH_MQPRIO_ATTR_NUMTC))
|
||||
return -NLE_MISSING_ATTR;
|
||||
|
||||
if ((len / sizeof(uint8_t)) > (TC_QOPT_BITMASK+1))
|
||||
return -NLE_RANGE;
|
||||
|
||||
for (i = 0; i <= TC_QOPT_BITMASK; i++) {
|
||||
if (priomap[i] > mqprio->qm_num_tc)
|
||||
return -NLE_RANGE;
|
||||
}
|
||||
|
||||
memcpy(mqprio->qm_prio_map, priomap, len * sizeof(uint8_t));
|
||||
mqprio->qm_mask |= SCH_MQPRIO_ATTR_PRIOMAP;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get priomap of MQPRIO qdisc.
|
||||
* @arg qdisc MQPRIO qdisc.
|
||||
* @return Priority mapping as array of size TC_QOPT_BANDS+1
|
||||
* or NULL if an error occured.
|
||||
*/
|
||||
uint8_t *rtnl_qdisc_mqprio_get_priomap(struct rtnl_qdisc *qdisc)
|
||||
{
|
||||
struct rtnl_mqprio *mqprio;
|
||||
|
||||
if (!(mqprio = rtnl_tc_data_peek(TC_CAST(qdisc))))
|
||||
return NULL;
|
||||
|
||||
if (mqprio->qm_mask & SCH_MQPRIO_ATTR_PRIOMAP)
|
||||
return mqprio->qm_prio_map;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Offload to HW or run in SW (default).
|
||||
* @arg qdisc MQPRIO qdisc to be modified.
|
||||
* @arg offload 1 - offload to HW, 0 - run in SW only (default).
|
||||
* @return 0 on success or a negative error code.
|
||||
*/
|
||||
int rtnl_qdisc_mqprio_hw_offload(struct rtnl_qdisc *qdisc, int offload)
|
||||
{
|
||||
struct rtnl_mqprio *mqprio;
|
||||
|
||||
if (!(mqprio = rtnl_tc_data(TC_CAST(qdisc))))
|
||||
return -NLE_NOMEM;
|
||||
|
||||
switch (offload) {
|
||||
case 0:
|
||||
case 1:
|
||||
mqprio->qm_hw = offload;
|
||||
break;
|
||||
default:
|
||||
return -NLE_INVAL;
|
||||
}
|
||||
|
||||
mqprio->qm_mask |= SCH_MQPRIO_ATTR_HW;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether running in HW or SW.
|
||||
* @arg qdisc MQPRIO qdisc to be modified.
|
||||
* @return 0 if running in SW, otherwise 1 (HW)
|
||||
*/
|
||||
int rtnl_qdisc_mqprio_get_hw_offload(struct rtnl_qdisc *qdisc)
|
||||
{
|
||||
struct rtnl_mqprio *mqprio;
|
||||
|
||||
if (!(mqprio = rtnl_tc_data_peek(TC_CAST(qdisc))))
|
||||
return -NLE_INVAL;
|
||||
|
||||
if (mqprio->qm_mask & SCH_MQPRIO_ATTR_HW)
|
||||
return mqprio->qm_hw;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set tc queue of the MQPRIO qdisc.
|
||||
* @arg qdisc MQPRIO qdisc to be modified.
|
||||
* @arg count count of queue range for each traffic class
|
||||
* @arg offset offset of queue range for each traffic class
|
||||
* @return 0 on success or a negative error code.
|
||||
*/
|
||||
int rtnl_qdisc_mqprio_set_queue(struct rtnl_qdisc *qdisc, uint16_t count[],
|
||||
uint16_t offset[], int len)
|
||||
{
|
||||
struct rtnl_mqprio *mqprio;
|
||||
|
||||
if (!(mqprio = rtnl_tc_data(TC_CAST(qdisc))))
|
||||
return -NLE_NOMEM;
|
||||
|
||||
if (!(mqprio->qm_mask & SCH_MQPRIO_ATTR_NUMTC))
|
||||
return -NLE_MISSING_ATTR;
|
||||
|
||||
if ((len / sizeof(uint16_t)) > TC_QOPT_MAX_QUEUE)
|
||||
return -NLE_RANGE;
|
||||
|
||||
memcpy(mqprio->qm_count, count, len * sizeof(uint16_t));
|
||||
memcpy(mqprio->qm_offset, offset, len * sizeof(uint16_t));
|
||||
mqprio->qm_mask |= SCH_MQPRIO_ATTR_QUEUE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tc queue of the MQPRIO qdisc.
|
||||
* @arg qdisc MQPRIO qdisc to be modified.
|
||||
* @arg count count of queue range for each traffic class
|
||||
* @arg offset offset of queue range for each traffic class
|
||||
* @return 0 on success or a negative error code.
|
||||
*/
|
||||
int rtnl_qdisc_mqprio_get_queue(struct rtnl_qdisc *qdisc, uint16_t *count,
|
||||
uint16_t *offset)
|
||||
{
|
||||
struct rtnl_mqprio *mqprio;
|
||||
|
||||
if (!(mqprio = rtnl_tc_data_peek(TC_CAST(qdisc))))
|
||||
return -NLE_INVAL;
|
||||
|
||||
if (!(mqprio->qm_mask & SCH_MQPRIO_ATTR_QUEUE))
|
||||
return -NLE_MISSING_ATTR;
|
||||
|
||||
memcpy(count, mqprio->qm_count, TC_QOPT_MAX_QUEUE * sizeof(uint16_t));
|
||||
memcpy(offset, mqprio->qm_offset, TC_QOPT_MAX_QUEUE * sizeof(uint16_t));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set mode of mqprio Qdisc
|
||||
* @arg qdisc MQPRIO qdisc to be modified.
|
||||
* @arg mode one of: TC_MQPRIO_MODE_DCB, TC_MQPRIO_MODE_CHANNEL
|
||||
* @return 0 on success or a negative error code.
|
||||
*/
|
||||
int rtnl_qdisc_mqprio_set_mode(struct rtnl_qdisc *qdisc, uint16_t mode)
|
||||
{
|
||||
struct rtnl_mqprio *mqprio;
|
||||
|
||||
if (!(mqprio = rtnl_tc_data(TC_CAST(qdisc))))
|
||||
return -NLE_NOMEM;
|
||||
|
||||
if (!(mqprio->qm_mask & SCH_MQPRIO_ATTR_HW))
|
||||
return -NLE_MISSING_ATTR;
|
||||
|
||||
mqprio->qm_mode = mode;
|
||||
mqprio->qm_mask |= SCH_MQPRIO_ATTR_MODE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mode of mqprio Qdisc
|
||||
* @arg qdisc MQPRIO qdisc.
|
||||
* @return mode on success or negative error code.
|
||||
*/
|
||||
int rtnl_qdisc_mqprio_get_mode(struct rtnl_qdisc *qdisc)
|
||||
{
|
||||
struct rtnl_mqprio *mqprio;
|
||||
|
||||
if (!(mqprio = rtnl_tc_data_peek(TC_CAST(qdisc))))
|
||||
return -NLE_INVAL;
|
||||
|
||||
if (mqprio->qm_mask & SCH_MQPRIO_ATTR_MODE)
|
||||
return mqprio->qm_mode;
|
||||
else
|
||||
return -NLE_MISSING_ATTR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set shaper of mqprio Qdisc
|
||||
* @arg qdisc MQPRIO qdisc to be modified.
|
||||
* @arg shaper one of: TC_MQPRIO_SHAPER_DCB, TC_MQPRIO_SHAPER_BW_RATE
|
||||
* @return 0 on success or a negative error code.
|
||||
*/
|
||||
int rtnl_qdisc_mqprio_set_shaper(struct rtnl_qdisc *qdisc, uint16_t shaper)
|
||||
{
|
||||
struct rtnl_mqprio *mqprio;
|
||||
|
||||
if (!(mqprio = rtnl_tc_data(TC_CAST(qdisc))))
|
||||
return -NLE_NOMEM;
|
||||
|
||||
if (!(mqprio->qm_mask & SCH_MQPRIO_ATTR_HW))
|
||||
return -NLE_MISSING_ATTR;
|
||||
|
||||
mqprio->qm_shaper = shaper;
|
||||
mqprio->qm_mask |= SCH_MQPRIO_ATTR_SHAPER;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get shaper of mqprio Qdisc
|
||||
* @arg qdisc MQPRIO qdisc.
|
||||
* @return shaper on success or negative error code.
|
||||
*/
|
||||
int rtnl_qdisc_mqprio_get_shaper(struct rtnl_qdisc *qdisc)
|
||||
{
|
||||
struct rtnl_mqprio *mqprio;
|
||||
|
||||
if (!(mqprio = rtnl_tc_data_peek(TC_CAST(qdisc))))
|
||||
return -NLE_INVAL;
|
||||
|
||||
if (mqprio->qm_mask & SCH_MQPRIO_ATTR_SHAPER)
|
||||
return mqprio->qm_shaper;
|
||||
else
|
||||
return -NLE_MISSING_ATTR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set minimum value of bandwidth rate limit for each traffic class
|
||||
* @arg qdisc MQPRIO qdisc.
|
||||
* @arg min minimum rate for each traffic class
|
||||
* @return 0 on success or a negative error code.
|
||||
*/
|
||||
int rtnl_qdisc_mqprio_set_min_rate(struct rtnl_qdisc *qdisc, uint64_t min[], int len)
|
||||
{
|
||||
struct rtnl_mqprio *mqprio;
|
||||
|
||||
if (!(mqprio = rtnl_tc_data(TC_CAST(qdisc))))
|
||||
return -NLE_NOMEM;
|
||||
|
||||
if (!(mqprio->qm_mask & SCH_MQPRIO_ATTR_SHAPER))
|
||||
return -NLE_MISSING_ATTR;
|
||||
|
||||
if (mqprio->qm_shaper != TC_MQPRIO_SHAPER_BW_RATE)
|
||||
return -NLE_INVAL;
|
||||
|
||||
if ((len / sizeof(uint64_t)) > TC_QOPT_MAX_QUEUE)
|
||||
return -NLE_RANGE;
|
||||
|
||||
memcpy(mqprio->qm_min_rate, min, len * sizeof(uint64_t));
|
||||
mqprio->qm_mask |= SCH_MQPRIO_ATTR_MIN_RATE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get minimum value of bandwidth rate limit for each traffic class
|
||||
* @arg qdisc MQPRIO qdisc.
|
||||
* @arg min minimum rate for each traffic class
|
||||
* @return 0 on success or a negative error code.
|
||||
*/
|
||||
int rtnl_qdisc_mqprio_get_min_rate(struct rtnl_qdisc *qdisc, uint64_t *min)
|
||||
{
|
||||
struct rtnl_mqprio *mqprio;
|
||||
|
||||
if (!(mqprio = rtnl_tc_data_peek(TC_CAST(qdisc))))
|
||||
return -NLE_INVAL;
|
||||
|
||||
if (mqprio->qm_mask & SCH_MQPRIO_ATTR_MIN_RATE) {
|
||||
memcpy(min, mqprio->qm_min_rate, TC_QOPT_MAX_QUEUE * sizeof(uint64_t));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -NLE_MISSING_ATTR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set maximum value of bandwidth rate limit for each traffic class
|
||||
* @arg qdisc MQPRIO qdisc.
|
||||
* @arg max maximum rate for each traffic class
|
||||
* @return 0 on success or a negative error code.
|
||||
*/
|
||||
int rtnl_qdisc_mqprio_set_max_rate(struct rtnl_qdisc *qdisc, uint64_t max[], int len)
|
||||
{
|
||||
struct rtnl_mqprio *mqprio;
|
||||
|
||||
if (!(mqprio = rtnl_tc_data(TC_CAST(qdisc))))
|
||||
return -NLE_NOMEM;
|
||||
|
||||
if (!(mqprio->qm_mask & SCH_MQPRIO_ATTR_SHAPER))
|
||||
return -NLE_MISSING_ATTR;
|
||||
|
||||
if (mqprio->qm_shaper != TC_MQPRIO_SHAPER_BW_RATE)
|
||||
return -NLE_INVAL;
|
||||
|
||||
if ((len / sizeof(uint64_t)) > TC_QOPT_MAX_QUEUE)
|
||||
return -NLE_RANGE;
|
||||
|
||||
memcpy(mqprio->qm_max_rate, max, len * sizeof(uint64_t));
|
||||
mqprio->qm_mask |= SCH_MQPRIO_ATTR_MAX_RATE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get maximum value of bandwidth rate limit for each traffic class
|
||||
* @arg qdisc MQPRIO qdisc.
|
||||
* @arg min maximum rate for each traffic class
|
||||
* @return 0 on success or a negative error code.
|
||||
*/
|
||||
int rtnl_qdisc_mqprio_get_max_rate(struct rtnl_qdisc *qdisc, uint64_t *max)
|
||||
{
|
||||
struct rtnl_mqprio *mqprio;
|
||||
|
||||
if (!(mqprio = rtnl_tc_data_peek(TC_CAST(qdisc))))
|
||||
return -NLE_INVAL;
|
||||
|
||||
if (mqprio->qm_mask & SCH_MQPRIO_ATTR_MAX_RATE) {
|
||||
memcpy(max, mqprio->qm_max_rate, TC_QOPT_MAX_QUEUE * sizeof(uint64_t));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -NLE_MISSING_ATTR;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
static struct rtnl_tc_ops mqprio_ops = {
|
||||
.to_kind = "mqprio",
|
||||
.to_type = RTNL_TC_TYPE_QDISC,
|
||||
.to_size = sizeof(struct rtnl_mqprio),
|
||||
.to_msg_parser = mqprio_msg_parser,
|
||||
.to_dump = {
|
||||
[NL_DUMP_LINE] = mqprio_dump_line,
|
||||
[NL_DUMP_DETAILS] = mqprio_dump_details,
|
||||
},
|
||||
.to_msg_fill = mqprio_msg_fill,
|
||||
};
|
||||
|
||||
static void __init mqprio_init(void)
|
||||
{
|
||||
rtnl_tc_register(&mqprio_ops);
|
||||
}
|
||||
|
||||
static void __exit mqprio_exit(void)
|
||||
{
|
||||
rtnl_tc_unregister(&mqprio_ops);
|
||||
}
|
||||
|
||||
/** @} */
|
@ -202,14 +202,16 @@ int rtnl_tc_msg_build(struct rtnl_tc *tc, int type, int flags,
|
||||
.tcm_handle = tc->tc_handle,
|
||||
.tcm_parent = tc->tc_parent,
|
||||
};
|
||||
int err = -NLE_MSGSIZE;
|
||||
int err;
|
||||
|
||||
msg = nlmsg_alloc_simple(type, flags);
|
||||
if (!msg)
|
||||
return -NLE_NOMEM;
|
||||
|
||||
if (nlmsg_append(msg, &tchdr, sizeof(tchdr), NLMSG_ALIGNTO) < 0)
|
||||
if (nlmsg_append(msg, &tchdr, sizeof(tchdr), NLMSG_ALIGNTO) < 0) {
|
||||
err = -NLE_MSGSIZE;
|
||||
goto nla_put_failure;
|
||||
}
|
||||
|
||||
if (tc->ce_mask & TCA_ATTR_KIND)
|
||||
NLA_PUT_STRING(msg, TCA_KIND, tc->tc_kind);
|
||||
@ -220,8 +222,10 @@ int rtnl_tc_msg_build(struct rtnl_tc *tc, int type, int flags,
|
||||
void *data = rtnl_tc_data(tc);
|
||||
|
||||
if (ops->to_msg_fill) {
|
||||
if (!(opts = nla_nest_start(msg, TCA_OPTIONS)))
|
||||
if (!(opts = nla_nest_start(msg, TCA_OPTIONS))) {
|
||||
err = -NLE_NOMEM;
|
||||
goto nla_put_failure;
|
||||
}
|
||||
|
||||
if ((err = ops->to_msg_fill(tc, data, msg)) < 0)
|
||||
goto nla_put_failure;
|
||||
|
@ -1109,4 +1109,20 @@ global:
|
||||
rtnl_neigh_get_by_vlan;
|
||||
rtnl_neigh_get_master;
|
||||
rtnl_neigh_set_master;
|
||||
rtnl_qdisc_mqprio_set_num_tc;
|
||||
rtnl_qdisc_mqprio_get_num_tc;
|
||||
rtnl_qdisc_mqprio_set_priomap;
|
||||
rtnl_qdisc_mqprio_get_priomap;
|
||||
rtnl_qdisc_mqprio_hw_offload;
|
||||
rtnl_qdisc_mqprio_get_hw_offload;
|
||||
rtnl_qdisc_mqprio_set_queue;
|
||||
rtnl_qdisc_mqprio_get_queue;
|
||||
rtnl_qdisc_mqprio_set_mode;
|
||||
rtnl_qdisc_mqprio_get_mode;
|
||||
rtnl_qdisc_mqprio_set_shaper;
|
||||
rtnl_qdisc_mqprio_get_shaper;
|
||||
rtnl_qdisc_mqprio_set_min_rate;
|
||||
rtnl_qdisc_mqprio_get_min_rate;
|
||||
rtnl_qdisc_mqprio_set_max_rate;
|
||||
rtnl_qdisc_mqprio_get_max_rate;
|
||||
} libnl_3_4;
|
||||
|
Loading…
Reference in New Issue
Block a user