Compare commits
18 Commits
782a7eb719
...
c3151977d7
Author | SHA1 | Date |
---|---|---|
Topi Miettinen | c3151977d7 | |
Yu Watanabe | 7bda173f6a | |
Yu Watanabe | 970ab1fcc0 | |
Susant Sahani | 7f22402007 | |
Susant Sahani | 7e16f84ea2 | |
Yu Watanabe | 41bb371bb0 | |
Susant Sahani | 1a95964bfa | |
Yu Watanabe | 73136507ac | |
Susant Sahani | 053a2ddbb2 | |
Yu Watanabe | 7b1a31a3d0 | |
Susant Sahani | c853f594d4 | |
Yu Watanabe | 557fa421ff | |
Yu Watanabe | ad365c5de7 | |
Susant Sahani | f5fc04417e | |
Susant Sahani | 5c21b46e49 | |
Yu Watanabe | be94e591fb | |
Susant Sahani | bde4ae88c8 | |
Susant Sahani | 55d228311b |
|
@ -2500,6 +2500,38 @@
|
|||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>[PIE] Section Options</title>
|
||||
<para>The <literal>[PIE]</literal> section manages the queueing discipline
|
||||
(qdisc) of Proportional Integral controller-Enhanced (PIE).</para>
|
||||
|
||||
<variablelist class='network-directives'>
|
||||
<varlistentry>
|
||||
<term><varname>Parent=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies the parent Queueing Discipline (qdisc). Takes one of <literal>root</literal>,
|
||||
<literal>clsact</literal> or <literal>ingress</literal>. Defaults to <literal>root</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>Handle=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies the major number of unique identifier of the qdisc, known as the handle.
|
||||
Takes a number in hexadecimal ranges 1 to ffff. Defaults to unset.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>PacketLimit=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies the hard limit on the queue size in number of packets. When this limit is reached, incoming packets are
|
||||
dropped. An unsigned integer ranges 1 to 4294967294. Defaults to unset and kernel's default is used.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>[StochasticFairBlue] Section Options</title>
|
||||
<para>The <literal>[StochasticFairBlue]</literal> section manages the queueing discipline
|
||||
|
@ -2565,6 +2597,40 @@
|
|||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>[BFIFO] Section Options</title>
|
||||
<para>The <literal>[BFIFO]</literal> section manages the queueing discipline (qdisc) of
|
||||
Byte limited Packet First In First Out (bfifo).</para>
|
||||
|
||||
<variablelist class='network-directives'>
|
||||
<varlistentry>
|
||||
<term><varname>Parent=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies the parent Queueing Discipline (qdisc). Takes one of <literal>root</literal>,
|
||||
<literal>clsact</literal> or <literal>ingress</literal>. Defaults to <literal>root</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>Handle=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies the major number of unique identifier of the qdisc, known as the handle.
|
||||
Takes a number in hexadecimal ranges 1 to ffff. Defaults to unset.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>LimitSize=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies the hard limit on the FIFO size in bytes. The size limit (a buffer size) to prevent it
|
||||
from overflowing in case it is unable to dequeue packets as quickly as it receives them. When this limit
|
||||
is reached, incoming packets are dropped. When suffixed with K, M, or G, the specified size is parsed as
|
||||
Kilobytes, Megabytes, or Gigabytes, respectively, to the base of 1024. Defaults to unset and kernel's default is used.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>[PFIFO] Section Options</title>
|
||||
<para>The <literal>[PFIFO]</literal> section manages the queueing discipline (qdisc) of
|
||||
|
@ -2598,6 +2664,54 @@
|
|||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>[PFIFOHeadDrop] Section Options</title>
|
||||
<para>The <literal>[PFIFOHeadDrop]</literal> section manages the queueing discipline (qdisc) of
|
||||
Packet First In First Out Head Drop (pfifo_head_drop).</para>
|
||||
|
||||
<variablelist class='network-directives'>
|
||||
<varlistentry>
|
||||
<term><varname>Parent=</varname></term>
|
||||
<listitem>
|
||||
<para>As in <literal>[PFIFO]</literal> section.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>Handle=</varname></term>
|
||||
<listitem>
|
||||
<para>As in <literal>[PFIFO]</literal> section..</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>PacketLimit=</varname></term>
|
||||
<listitem>
|
||||
<para>As in <literal>[PFIFO]</literal> section.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>[PFIFOFast] Section Options</title>
|
||||
<para>The <literal>[PFIFOFast]</literal> section manages the queueing discipline (qdisc) of
|
||||
Packet First In First Out Fast (pfifo_fast).</para>
|
||||
|
||||
<variablelist class='network-directives'>
|
||||
<varlistentry>
|
||||
<term><varname>Parent=</varname></term>
|
||||
<listitem>
|
||||
<para>As in <literal>[PFIFO]</literal> section.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>Handle=</varname></term>
|
||||
<listitem>
|
||||
<para>As in <literal>[PFIFO]</literal> section..</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>[CAKE] Section Options</title>
|
||||
<para>The <literal>[CAKE]</literal> section manages the queueing discipline (qdisc) of
|
||||
|
@ -2707,6 +2821,68 @@
|
|||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>[DeficitRoundRobinScheduler] Section Options</title>
|
||||
<para>The <literal>[DeficitRoundRobinScheduler]</literal> section manages the queueing discipline (qdisc) of
|
||||
Deficit Round Robin Scheduler (DRR).</para>
|
||||
|
||||
<variablelist class='network-directives'>
|
||||
<varlistentry>
|
||||
<term><varname>Parent=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies the parent Queueing Discipline (qdisc). Takes one of <literal>root</literal>,
|
||||
<literal>clsact</literal>, <literal>ingress</literal> or a class id. The class id takes the
|
||||
major and minor number in hexadecimal ranges 1 to ffff separated with a colon
|
||||
(<literal>major:minor</literal>). Defaults to <literal>root</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>Handle=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies the major number of unique identifier of the qdisc, known as the handle.
|
||||
Takes a number in hexadecimal ranges 1 to ffff. Defaults to unset.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>[DeficitRoundRobinSchedulerClass] Section Options</title>
|
||||
<para>The <literal>[DeficitRoundRobinSchedulerClass]</literal> section manages the traffic control class of
|
||||
Deficit Round Robin Scheduler (DRR).</para>
|
||||
|
||||
<variablelist class='network-directives'>
|
||||
<varlistentry>
|
||||
<term><varname>Parent=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies the parent Queueing Discipline (qdisc). Takes one of <literal>root</literal>,
|
||||
<literal>clsact</literal>, <literal>ingress</literal> or a class id. The class id takes the
|
||||
major and minor number in hexadecimal ranges 1 to ffff separated with a colon
|
||||
(<literal>major:minor</literal>). Defaults to <literal>root</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>ClassId=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies the major and minur number of unique identifier of the class, known as the
|
||||
class ID. Each number is in hexadecimal ranges 1 to ffff. Defaults to unset.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>Quantum=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies the amount of bytes a flow is allowed to dequeue before the
|
||||
scheduler moves to the next class. An unsigned integer ranges 1 to 4294967294.
|
||||
Defaults to the MTU of the interface.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>[GenericRandomEarlyDetection] Section Options</title>
|
||||
<para>The <literal>[GenericRandomEarlyDetection]</literal> section manages the queueing discipline
|
||||
|
@ -3070,7 +3246,38 @@
|
|||
is used.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>[HeavyHitterFilter] Section Options</title>
|
||||
<para>The <literal>[HeavyHitterFilter]</literal> section manages the queueing discipline
|
||||
(qdisc) of Heavy Hitter Filter (hhf).</para>
|
||||
|
||||
<variablelist class='network-directives'>
|
||||
<varlistentry>
|
||||
<term><varname>Parent=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies the parent Queueing Discipline (qdisc). Takes one of <literal>root</literal>,
|
||||
<literal>clsact</literal> or <literal>ingress</literal>. Defaults to <literal>root</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>Handle=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies the major number of unique identifier of the qdisc, known as the handle.
|
||||
Takes a number in hexadecimal ranges 1 to ffff. Defaults to unset.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>PacketLimit=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies the hard limit on the queue size in number of packets. When this limit is reached, incoming packets are
|
||||
dropped. An unsigned integer ranges 0 to 4294967294. Defaults to unset and kernel's default is used.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
|
|
@ -10,11 +10,11 @@
|
|||
#include "selinux-util.h"
|
||||
#include "smack-util.h"
|
||||
|
||||
int label_fix(const char *path, LabelFixFlags flags) {
|
||||
int label_fix_container(const char *path, const char *inside_path, LabelFixFlags flags) {
|
||||
int r, q;
|
||||
|
||||
r = mac_selinux_fix(path, flags);
|
||||
q = mac_smack_fix(path, flags);
|
||||
r = mac_selinux_fix_container(path, inside_path, flags);
|
||||
q = mac_smack_fix_container(path, inside_path, flags);
|
||||
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
|
|
@ -9,7 +9,10 @@ typedef enum LabelFixFlags {
|
|||
LABEL_IGNORE_EROFS = 1 << 1,
|
||||
} LabelFixFlags;
|
||||
|
||||
int label_fix(const char *path, LabelFixFlags flags);
|
||||
int label_fix_container(const char *path, const char *inside_path, LabelFixFlags flags);
|
||||
static inline int label_fix(const char *path, LabelFixFlags flags) {
|
||||
return label_fix_container(path, path, flags);
|
||||
}
|
||||
|
||||
int mkdir_label(const char *path, mode_t mode);
|
||||
int mkdirat_label(int dirfd, const char *path, mode_t mode);
|
||||
|
|
|
@ -157,7 +157,7 @@ static int mac_selinux_reload(int seqno) {
|
|||
}
|
||||
#endif
|
||||
|
||||
int mac_selinux_fix(const char *path, LabelFixFlags flags) {
|
||||
int mac_selinux_fix_container(const char *path, const char *inside_path, LabelFixFlags flags) {
|
||||
|
||||
#if HAVE_SELINUX
|
||||
char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
|
||||
|
@ -187,7 +187,7 @@ int mac_selinux_fix(const char *path, LabelFixFlags flags) {
|
|||
/* Check for policy reload so 'label_hnd' is kept up-to-date by callbacks */
|
||||
(void) avc_netlink_check_nb();
|
||||
|
||||
if (selabel_lookup_raw(label_hnd, &fcon, path, st.st_mode) < 0) {
|
||||
if (selabel_lookup_raw(label_hnd, &fcon, inside_path, st.st_mode) < 0) {
|
||||
r = -errno;
|
||||
|
||||
/* If there's no label to set, then exit without warning */
|
||||
|
@ -221,7 +221,7 @@ int mac_selinux_fix(const char *path, LabelFixFlags flags) {
|
|||
return 0;
|
||||
|
||||
fail:
|
||||
log_enforcing_errno(r, "Unable to fix SELinux security context of %s: %m", path);
|
||||
log_enforcing_errno(r, "Unable to fix SELinux security context of %s (%s): %m", path, inside_path);
|
||||
if (mac_selinux_enforcing())
|
||||
return r;
|
||||
#endif
|
||||
|
|
|
@ -22,7 +22,11 @@ void mac_selinux_retest(void);
|
|||
int mac_selinux_init(void);
|
||||
void mac_selinux_finish(void);
|
||||
|
||||
int mac_selinux_fix(const char *path, LabelFixFlags flags);
|
||||
int mac_selinux_fix_container(const char *path, const char *inside_path, LabelFixFlags flags);
|
||||
static inline int mac_selinux_fix(const char *path, LabelFixFlags flags) {
|
||||
return mac_selinux_fix_container(path, path, flags);
|
||||
}
|
||||
|
||||
int mac_selinux_apply(const char *path, const char *label);
|
||||
|
||||
int mac_selinux_get_create_label_from_exe(const char *exe, char **label);
|
||||
|
|
|
@ -206,7 +206,7 @@ int mac_smack_fix_at(int dirfd, const char *path, LabelFixFlags flags) {
|
|||
return smack_fix_fd(fd, path, flags);
|
||||
}
|
||||
|
||||
int mac_smack_fix(const char *path, LabelFixFlags flags) {
|
||||
int mac_smack_fix_container(const char *path, const char *inside_path, LabelFixFlags flags) {
|
||||
_cleanup_free_ char *abspath = NULL;
|
||||
_cleanup_close_ int fd = -1;
|
||||
int r;
|
||||
|
@ -228,7 +228,7 @@ int mac_smack_fix(const char *path, LabelFixFlags flags) {
|
|||
return -errno;
|
||||
}
|
||||
|
||||
return smack_fix_fd(fd, abspath, flags);
|
||||
return smack_fix_fd(fd, inside_path, flags);
|
||||
}
|
||||
|
||||
int mac_smack_copy(const char *dest, const char *src) {
|
||||
|
@ -274,7 +274,7 @@ int mac_smack_apply_pid(pid_t pid, const char *label) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int mac_smack_fix(const char *path, LabelFixFlags flags) {
|
||||
int mac_smack_fix_container(const char *path, const char *inside_path, LabelFixFlags flags) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,11 @@ typedef enum SmackAttr {
|
|||
|
||||
bool mac_smack_use(void);
|
||||
|
||||
int mac_smack_fix(const char *path, LabelFixFlags flags);
|
||||
int mac_smack_fix_container(const char *path, const char *inside_path, LabelFixFlags flags);
|
||||
static inline int mac_smack_fix(const char *path, LabelFixFlags flags) {
|
||||
return mac_smack_fix_container(path, path, flags);
|
||||
}
|
||||
|
||||
int mac_smack_fix_at(int dirfd, const char *path, LabelFixFlags flags);
|
||||
|
||||
const char* smack_attr_to_string(SmackAttr i) _const_;
|
||||
|
|
|
@ -690,6 +690,11 @@ static int mount_private_dev(MountEntry *m) {
|
|||
r = log_debug_errno(errno, "Failed to mount tmpfs on '%s': %m", dev);
|
||||
goto fail;
|
||||
}
|
||||
r = label_fix_container(dev, "/dev", 0);
|
||||
if (r < 0) {
|
||||
log_debug_errno(errno, "Failed to fix label of '%s' as /dev: %m", dev);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
devpts = strjoina(temporary_mount, "/dev/pts");
|
||||
(void) mkdir(devpts, 0755);
|
||||
|
|
|
@ -760,6 +760,10 @@ static const NLType rtnl_tca_option_data_codel_types[] = {
|
|||
[TCA_CODEL_CE_THRESHOLD] = { .type = NETLINK_TYPE_U32 },
|
||||
};
|
||||
|
||||
static const NLType rtnl_tca_option_data_drr_types[] = {
|
||||
[TCA_DRR_QUANTUM] = { .type = NETLINK_TYPE_U32 },
|
||||
};
|
||||
|
||||
static const NLType rtnl_tca_option_data_fq_types[] = {
|
||||
[TCA_FQ_PLIMIT] = { .type = NETLINK_TYPE_U32 },
|
||||
[TCA_FQ_FLOW_PLIMIT] = { .type = NETLINK_TYPE_U32 },
|
||||
|
@ -791,6 +795,10 @@ static const NLType rtnl_tca_option_data_gred_types[] = {
|
|||
[TCA_GRED_DPS] = { .size = sizeof(struct tc_gred_sopt) },
|
||||
};
|
||||
|
||||
static const NLType rtnl_tca_option_data_hhf_types[] = {
|
||||
[TCA_HHF_BACKLOG_LIMIT] = { .type = NETLINK_TYPE_U32 },
|
||||
};
|
||||
|
||||
static const NLType rtnl_tca_option_data_htb_types[] = {
|
||||
[TCA_HTB_PARMS] = { .size = sizeof(struct tc_htb_opt) },
|
||||
[TCA_HTB_INIT] = { .size = sizeof(struct tc_htb_glob) },
|
||||
|
@ -800,6 +808,10 @@ static const NLType rtnl_tca_option_data_htb_types[] = {
|
|||
[TCA_HTB_CEIL64] = { .type = NETLINK_TYPE_U64 },
|
||||
};
|
||||
|
||||
static const NLType rtnl_tca_option_data_pie_types[] = {
|
||||
[TCA_PIE_LIMIT] = { .type = NETLINK_TYPE_U32 },
|
||||
};
|
||||
|
||||
static const NLType rtnl_tca_option_data_sfb_types[] = {
|
||||
[TCA_SFB_PARMS] = { .size = sizeof(struct tc_sfb_qopt) },
|
||||
};
|
||||
|
@ -817,10 +829,13 @@ static const NLType rtnl_tca_option_data_tbf_types[] = {
|
|||
static const char* const nl_union_tca_option_data_table[] = {
|
||||
[NL_UNION_TCA_OPTION_DATA_CAKE] = "cake",
|
||||
[NL_UNION_TCA_OPTION_DATA_CODEL] = "codel",
|
||||
[NL_UNION_TCA_OPTION_DATA_DRR] = "drr",
|
||||
[NL_UNION_TCA_OPTION_DATA_FQ] = "fq",
|
||||
[NL_UNION_TCA_OPTION_DATA_FQ_CODEL] = "fq_codel",
|
||||
[NL_UNION_TCA_OPTION_DATA_GRED] = "gred",
|
||||
[NL_UNION_TCA_OPTION_DATA_HHF] = "hhf",
|
||||
[NL_UNION_TCA_OPTION_DATA_HTB] = "htb",
|
||||
[NL_UNION_TCA_OPTION_DATA_PIE] = "pie",
|
||||
[NL_UNION_TCA_OPTION_DATA_SFB] = "sfb",
|
||||
[NL_UNION_TCA_OPTION_DATA_TBF] = "tbf",
|
||||
};
|
||||
|
@ -832,14 +847,20 @@ static const NLTypeSystem rtnl_tca_option_data_type_systems[] = {
|
|||
.types = rtnl_tca_option_data_cake_types },
|
||||
[NL_UNION_TCA_OPTION_DATA_CODEL] = { .count = ELEMENTSOF(rtnl_tca_option_data_codel_types),
|
||||
.types = rtnl_tca_option_data_codel_types },
|
||||
[NL_UNION_TCA_OPTION_DATA_DRR] = { .count = ELEMENTSOF(rtnl_tca_option_data_drr_types),
|
||||
.types = rtnl_tca_option_data_drr_types },
|
||||
[NL_UNION_TCA_OPTION_DATA_FQ] = { .count = ELEMENTSOF(rtnl_tca_option_data_fq_types),
|
||||
.types = rtnl_tca_option_data_fq_types },
|
||||
[NL_UNION_TCA_OPTION_DATA_FQ_CODEL] = { .count = ELEMENTSOF(rtnl_tca_option_data_fq_codel_types),
|
||||
.types = rtnl_tca_option_data_fq_codel_types },
|
||||
[NL_UNION_TCA_OPTION_DATA_GRED] = { .count = ELEMENTSOF(rtnl_tca_option_data_gred_types),
|
||||
.types = rtnl_tca_option_data_gred_types },
|
||||
[NL_UNION_TCA_OPTION_DATA_HHF] = { .count = ELEMENTSOF(rtnl_tca_option_data_hhf_types),
|
||||
.types = rtnl_tca_option_data_hhf_types },
|
||||
[NL_UNION_TCA_OPTION_DATA_HTB] = { .count = ELEMENTSOF(rtnl_tca_option_data_htb_types),
|
||||
.types = rtnl_tca_option_data_htb_types },
|
||||
[NL_UNION_TCA_OPTION_DATA_PIE] = { .count = ELEMENTSOF(rtnl_tca_option_data_pie_types),
|
||||
.types = rtnl_tca_option_data_pie_types },
|
||||
[NL_UNION_TCA_OPTION_DATA_SFB] = { .count = ELEMENTSOF(rtnl_tca_option_data_sfb_types),
|
||||
.types = rtnl_tca_option_data_sfb_types },
|
||||
[NL_UNION_TCA_OPTION_DATA_TBF] = { .count = ELEMENTSOF(rtnl_tca_option_data_tbf_types),
|
||||
|
|
|
@ -98,10 +98,13 @@ NLUnionLinkInfoData nl_union_link_info_data_from_string(const char *p) _pure_;
|
|||
typedef enum NLUnionTCAOptionData {
|
||||
NL_UNION_TCA_OPTION_DATA_CAKE,
|
||||
NL_UNION_TCA_OPTION_DATA_CODEL,
|
||||
NL_UNION_TCA_OPTION_DATA_DRR,
|
||||
NL_UNION_TCA_OPTION_DATA_FQ,
|
||||
NL_UNION_TCA_OPTION_DATA_FQ_CODEL,
|
||||
NL_UNION_TCA_OPTION_DATA_GRED,
|
||||
NL_UNION_TCA_OPTION_DATA_HHF,
|
||||
NL_UNION_TCA_OPTION_DATA_HTB,
|
||||
NL_UNION_TCA_OPTION_DATA_PIE,
|
||||
NL_UNION_TCA_OPTION_DATA_SFB,
|
||||
NL_UNION_TCA_OPTION_DATA_TBF,
|
||||
_NL_UNION_TCA_OPTION_DATA_MAX,
|
||||
|
|
|
@ -111,6 +111,8 @@ sources = files('''
|
|||
tc/cake.h
|
||||
tc/codel.c
|
||||
tc/codel.h
|
||||
tc/drr.c
|
||||
tc/drr.h
|
||||
tc/fifo.c
|
||||
tc/fifo.h
|
||||
tc/fq.c
|
||||
|
@ -119,10 +121,14 @@ sources = files('''
|
|||
tc/fq-codel.h
|
||||
tc/gred.c
|
||||
tc/gred.h
|
||||
tc/hhf.c
|
||||
tc/hhf.h
|
||||
tc/htb.c
|
||||
tc/htb.h
|
||||
tc/netem.c
|
||||
tc/netem.h
|
||||
tc/pie.c
|
||||
tc/pie.h
|
||||
tc/qdisc.c
|
||||
tc/qdisc.h
|
||||
tc/sfb.c
|
||||
|
|
|
@ -258,6 +258,9 @@ CAN.TripleSampling, config_parse_tristate,
|
|||
CAN.Termination, config_parse_tristate, 0, offsetof(Network, can_termination)
|
||||
QDisc.Parent, config_parse_qdisc_parent, _QDISC_KIND_INVALID, 0
|
||||
QDisc.Handle, config_parse_qdisc_handle, _QDISC_KIND_INVALID, 0
|
||||
BFIFO.Parent, config_parse_qdisc_parent, QDISC_KIND_BFIFO, 0
|
||||
BFIFO.Handle, config_parse_qdisc_handle, QDISC_KIND_BFIFO, 0
|
||||
BFIFO.LimitSize, config_parse_bfifo_size, QDISC_KIND_BFIFO, 0
|
||||
CAKE.Parent, config_parse_qdisc_parent, QDISC_KIND_CAKE, 0
|
||||
CAKE.Handle, config_parse_qdisc_handle, QDISC_KIND_CAKE, 0
|
||||
CAKE.Bandwidth, config_parse_cake_bandwidth, QDISC_KIND_CAKE, 0
|
||||
|
@ -269,9 +272,19 @@ ControlledDelay.TargetSec, config_parse_controlled_delay_usec,
|
|||
ControlledDelay.IntervalSec, config_parse_controlled_delay_usec, QDISC_KIND_CODEL, 0
|
||||
ControlledDelay.CEThresholdSec, config_parse_controlled_delay_usec, QDISC_KIND_CODEL, 0
|
||||
ControlledDelay.ECN, config_parse_controlled_delay_bool, QDISC_KIND_CODEL, 0
|
||||
DeficitRoundRobinScheduler.Parent, config_parse_qdisc_parent, QDISC_KIND_DRR, 0
|
||||
DeficitRoundRobinScheduler.Handle, config_parse_qdisc_handle, QDISC_KIND_DRR, 0
|
||||
DeficitRoundRobinSchedulerClass.Parent, config_parse_tclass_parent, TCLASS_KIND_DRR, 0
|
||||
DeficitRoundRobinSchedulerClass.ClassId, config_parse_tclass_classid, TCLASS_KIND_DRR, 0
|
||||
DeficitRoundRobinSchedulerClass.Quantum, config_parse_drr_size, TCLASS_KIND_DRR, 0
|
||||
PFIFO.Parent, config_parse_qdisc_parent, QDISC_KIND_PFIFO, 0
|
||||
PFIFO.Handle, config_parse_qdisc_handle, QDISC_KIND_PFIFO, 0
|
||||
PFIFO.PacketLimit, config_parse_fifo_size, QDISC_KIND_PFIFO, 0
|
||||
PFIFO.PacketLimit, config_parse_pfifo_size, QDISC_KIND_PFIFO, 0
|
||||
PFIFOFast.Parent, config_parse_qdisc_parent, QDISC_KIND_PFIFO_FAST, 0
|
||||
PFIFOFast.Handle, config_parse_qdisc_handle, QDISC_KIND_PFIFO_FAST, 0
|
||||
PFIFOHeadDrop.Parent, config_parse_qdisc_parent, QDISC_KIND_PFIFO_HEAD_DROP, 0
|
||||
PFIFOHeadDrop.Handle, config_parse_qdisc_handle, QDISC_KIND_PFIFO_HEAD_DROP, 0
|
||||
PFIFOHeadDrop.PacketLimit, config_parse_pfifo_size, QDISC_KIND_PFIFO_HEAD_DROP, 0
|
||||
FairQueueing.Parent, config_parse_qdisc_parent, QDISC_KIND_FQ, 0
|
||||
FairQueueing.Handle, config_parse_qdisc_handle, QDISC_KIND_FQ, 0
|
||||
FairQueueing.PacketLimit, config_parse_fair_queueing_u32, QDISC_KIND_FQ, 0
|
||||
|
@ -298,6 +311,9 @@ GenericRandomEarlyDetection.Handle, config_parse_qdisc_handle,
|
|||
GenericRandomEarlyDetection.VirtualQueues, config_parse_generic_random_early_detection_u32, QDISC_KIND_GRED, 0
|
||||
GenericRandomEarlyDetection.DefaultVirtualQueue, config_parse_generic_random_early_detection_u32, QDISC_KIND_GRED, 0
|
||||
GenericRandomEarlyDetection.GenericRIO, config_parse_generic_random_early_detection_bool, QDISC_KIND_GRED, 0
|
||||
HeavyHitterFilter.Parent, config_parse_qdisc_parent, QDISC_KIND_HHF, 0
|
||||
HeavyHitterFilter.Handle, config_parse_qdisc_handle, QDISC_KIND_HHF, 0
|
||||
HeavyHitterFilter.PacketLimit, config_parse_heavy_hitter_filter_packet_limit, QDISC_KIND_HHF, 0
|
||||
HierarchyTokenBucket.Parent, config_parse_qdisc_parent, QDISC_KIND_HTB, 0
|
||||
HierarchyTokenBucket.Handle, config_parse_qdisc_handle, QDISC_KIND_HTB, 0
|
||||
HierarchyTokenBucket.DefaultClass, config_parse_hierarchy_token_bucket_default_class, QDISC_KIND_HTB, 0
|
||||
|
@ -313,6 +329,9 @@ NetworkEmulator.DelayJitterSec, config_parse_network_emulator_delay
|
|||
NetworkEmulator.LossRate, config_parse_network_emulator_rate, QDISC_KIND_NETEM, 0
|
||||
NetworkEmulator.DuplicateRate, config_parse_network_emulator_rate, QDISC_KIND_NETEM, 0
|
||||
NetworkEmulator.PacketLimit, config_parse_network_emulator_packet_limit, QDISC_KIND_NETEM, 0
|
||||
PIE.Parent, config_parse_qdisc_parent, QDISC_KIND_PIE, 0
|
||||
PIE.Handle, config_parse_qdisc_handle, QDISC_KIND_PIE, 0
|
||||
PIE.PacketLimit, config_parse_pie_packet_limit, QDISC_KIND_PIE, 0
|
||||
StochasticFairBlue.Parent, config_parse_qdisc_parent, QDISC_KIND_SFB, 0
|
||||
StochasticFairBlue.Handle, config_parse_qdisc_handle, QDISC_KIND_SFB, 0
|
||||
StochasticFairBlue.PacketLimit, config_parse_stochastic_fair_blue_u32, QDISC_KIND_SFB, 0
|
||||
|
|
|
@ -486,15 +486,22 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
|
|||
"TrafficControlQueueingDiscipline\0"
|
||||
"CAN\0"
|
||||
"QDisc\0"
|
||||
"BFIFO\0"
|
||||
"CAKE\0"
|
||||
"ControlledDelay\0"
|
||||
"DeficitRoundRobinScheduler\0"
|
||||
"DeficitRoundRobinSchedulerClass\0"
|
||||
"PFIFO\0"
|
||||
"PFIFOFast\0"
|
||||
"PFIFOHeadDrop\0"
|
||||
"FairQueueing\0"
|
||||
"FairQueueingControlledDelay\0"
|
||||
"GenericRandomEarlyDetection\0"
|
||||
"HeavyHitterFilter\0"
|
||||
"HierarchyTokenBucket\0"
|
||||
"HierarchyTokenBucketClass\0"
|
||||
"NetworkEmulator\0"
|
||||
"PIE\0"
|
||||
"StochasticFairBlue\0"
|
||||
"StochasticFairnessQueueing\0"
|
||||
"TokenBucketFilter\0"
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+
|
||||
* Copyright © 2020 VMware, Inc. */
|
||||
|
||||
#include <linux/pkt_sched.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "conf-parser.h"
|
||||
#include "drr.h"
|
||||
#include "netlink-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "string-util.h"
|
||||
|
||||
const QDiscVTable drr_vtable = {
|
||||
.object_size = sizeof(DeficitRoundRobinScheduler),
|
||||
.tca_kind = "drr",
|
||||
};
|
||||
|
||||
static int drr_class_fill_message(Link *link, TClass *tclass, sd_netlink_message *req) {
|
||||
DeficitRoundRobinSchedulerClass *drr;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(tclass);
|
||||
assert(req);
|
||||
|
||||
drr = TCLASS_TO_DRR(tclass);
|
||||
|
||||
r = sd_netlink_message_open_container_union(req, TCA_OPTIONS, "drr");
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not open container TCA_OPTIONS: %m");
|
||||
|
||||
if (drr->quantum > 0) {
|
||||
r = sd_netlink_message_append_u32(req, TCA_DRR_QUANTUM, drr->quantum);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append TCA_DRR_QUANTUM, attribute: %m");
|
||||
}
|
||||
|
||||
r = sd_netlink_message_close_container(req);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not close container TCA_OPTIONS: %m");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_drr_size(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
const char *section,
|
||||
unsigned section_line,
|
||||
const char *lvalue,
|
||||
int ltype,
|
||||
const char *rvalue,
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
_cleanup_(tclass_free_or_set_invalidp) TClass *tclass = NULL;
|
||||
DeficitRoundRobinSchedulerClass *drr;
|
||||
Network *network = data;
|
||||
uint64_t u;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = tclass_new_static(TCLASS_KIND_DRR, network, filename, section_line, &tclass);
|
||||
if (r < 0)
|
||||
return log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to create traffic control class, ignoring assignment: %m");
|
||||
|
||||
drr = TCLASS_TO_DRR(tclass);
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
drr->quantum = 0;
|
||||
|
||||
tclass = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = parse_size(rvalue, 1000, &u);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to parse '%s=', ignoring assignment: %s",
|
||||
lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (u > UINT32_MAX) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid '%s=', ignoring assignment: %s",
|
||||
lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
drr->quantum = (uint32_t) u;
|
||||
|
||||
tclass = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const TClassVTable drr_tclass_vtable = {
|
||||
.object_size = sizeof(DeficitRoundRobinSchedulerClass),
|
||||
.tca_kind = "drr",
|
||||
.fill_message = drr_class_fill_message,
|
||||
};
|
|
@ -0,0 +1,23 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+
|
||||
* Copyright © 2020 VMware, Inc. */
|
||||
#pragma once
|
||||
|
||||
#include "qdisc.h"
|
||||
|
||||
typedef struct DeficitRoundRobinScheduler {
|
||||
QDisc meta;
|
||||
} DeficitRoundRobinScheduler;
|
||||
|
||||
DEFINE_QDISC_CAST(DRR, DeficitRoundRobinScheduler);
|
||||
extern const QDiscVTable drr_vtable;
|
||||
|
||||
typedef struct DeficitRoundRobinSchedulerClass {
|
||||
TClass meta;
|
||||
|
||||
uint32_t quantum;
|
||||
} DeficitRoundRobinSchedulerClass;
|
||||
|
||||
DEFINE_TCLASS_CAST(DRR, DeficitRoundRobinSchedulerClass);
|
||||
extern const TClassVTable drr_tclass_vtable;
|
||||
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_drr_size);
|
|
@ -19,7 +19,19 @@ static int fifo_fill_message(Link *link, QDisc *qdisc, sd_netlink_message *req)
|
|||
assert(qdisc);
|
||||
assert(req);
|
||||
|
||||
fifo = PFIFO(qdisc);
|
||||
switch(qdisc->kind) {
|
||||
case QDISC_KIND_PFIFO:
|
||||
fifo = PFIFO(qdisc);
|
||||
break;
|
||||
case QDISC_KIND_BFIFO:
|
||||
fifo = BFIFO(qdisc);
|
||||
break;
|
||||
case QDISC_KIND_PFIFO_HEAD_DROP:
|
||||
fifo = PFIFO_HEAD_DROP(qdisc);
|
||||
break;
|
||||
default:
|
||||
assert_not_reached("Invalid QDisc kind.");
|
||||
}
|
||||
|
||||
opt.limit = fifo->limit;
|
||||
|
||||
|
@ -30,7 +42,7 @@ static int fifo_fill_message(Link *link, QDisc *qdisc, sd_netlink_message *req)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_fifo_size(
|
||||
int config_parse_pfifo_size(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
|
@ -52,14 +64,23 @@ int config_parse_fifo_size(
|
|||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = qdisc_new_static(QDISC_KIND_PFIFO, network, filename, section_line, &qdisc);
|
||||
r = qdisc_new_static(ltype, network, filename, section_line, &qdisc);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0)
|
||||
return log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"More than one kind of queueing discipline, ignoring assignment: %m");
|
||||
|
||||
fifo = PFIFO(qdisc);
|
||||
switch(qdisc->kind) {
|
||||
case QDISC_KIND_PFIFO:
|
||||
fifo = PFIFO(qdisc);
|
||||
break;
|
||||
case QDISC_KIND_PFIFO_HEAD_DROP:
|
||||
fifo = PFIFO_HEAD_DROP(qdisc);
|
||||
break;
|
||||
default:
|
||||
assert_not_reached("Invalid QDisc kind.");
|
||||
}
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
fifo->limit = 0;
|
||||
|
@ -80,8 +101,83 @@ int config_parse_fifo_size(
|
|||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_bfifo_size(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
const char *section,
|
||||
unsigned section_line,
|
||||
const char *lvalue,
|
||||
int ltype,
|
||||
const char *rvalue,
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
_cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
||||
Network *network = data;
|
||||
FirstInFirstOut *fifo;
|
||||
uint64_t u;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = qdisc_new_static(QDISC_KIND_BFIFO, network, filename, section_line, &qdisc);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0)
|
||||
return log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"More than one kind of queueing discipline, ignoring assignment: %m");
|
||||
|
||||
fifo = BFIFO(qdisc);
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
fifo->limit = 0;
|
||||
|
||||
qdisc = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = parse_size(rvalue, 1000, &u);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to parse '%s=', ignoring assignment: %s",
|
||||
lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (u > UINT32_MAX) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid '%s=', ignoring assignment: %s",
|
||||
lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fifo->limit = (uint32_t) u;
|
||||
|
||||
qdisc = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const QDiscVTable pfifo_vtable = {
|
||||
.object_size = sizeof(FirstInFirstOut),
|
||||
.tca_kind = "pfifo",
|
||||
.fill_message = fifo_fill_message,
|
||||
};
|
||||
|
||||
const QDiscVTable bfifo_vtable = {
|
||||
.object_size = sizeof(FirstInFirstOut),
|
||||
.tca_kind = "bfifo",
|
||||
.fill_message = fifo_fill_message,
|
||||
};
|
||||
|
||||
const QDiscVTable pfifo_head_drop_vtable = {
|
||||
.object_size = sizeof(FirstInFirstOut),
|
||||
.tca_kind = "pfifo_head_drop",
|
||||
.fill_message = fifo_fill_message,
|
||||
};
|
||||
|
||||
const QDiscVTable pfifo_fast_vtable = {
|
||||
.object_size = sizeof(FirstInFirstOut),
|
||||
.tca_kind = "pfifo_fast",
|
||||
};
|
||||
|
|
|
@ -12,6 +12,14 @@ typedef struct FirstInFirstOut {
|
|||
} FirstInFirstOut;
|
||||
|
||||
DEFINE_QDISC_CAST(PFIFO, FirstInFirstOut);
|
||||
extern const QDiscVTable pfifo_vtable;
|
||||
DEFINE_QDISC_CAST(BFIFO, FirstInFirstOut);
|
||||
DEFINE_QDISC_CAST(PFIFO_HEAD_DROP, FirstInFirstOut);
|
||||
DEFINE_QDISC_CAST(PFIFO_FAST, FirstInFirstOut);
|
||||
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_fifo_size);
|
||||
extern const QDiscVTable pfifo_vtable;
|
||||
extern const QDiscVTable bfifo_vtable;
|
||||
extern const QDiscVTable pfifo_head_drop_vtable;
|
||||
extern const QDiscVTable pfifo_fast_vtable;
|
||||
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_pfifo_size);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_bfifo_size);
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+
|
||||
* Copyright © 2020 VMware, Inc. */
|
||||
|
||||
#include <linux/pkt_sched.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "conf-parser.h"
|
||||
#include "hhf.h"
|
||||
#include "netlink-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "string-util.h"
|
||||
#include "util.h"
|
||||
|
||||
static int heavy_hitter_filter_fill_message(Link *link, QDisc *qdisc, sd_netlink_message *req) {
|
||||
HeavyHitterFilter *hhf;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(qdisc);
|
||||
assert(req);
|
||||
|
||||
hhf = HHF(qdisc);
|
||||
|
||||
r = sd_netlink_message_open_container_union(req, TCA_OPTIONS, "hhf");
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not open container TCA_OPTIONS: %m");
|
||||
|
||||
if (hhf->packet_limit > 0) {
|
||||
r = sd_netlink_message_append_u32(req, TCA_HHF_BACKLOG_LIMIT, hhf->packet_limit);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append TCA_HHF_BACKLOG_LIMIT attribute: %m");
|
||||
}
|
||||
|
||||
r = sd_netlink_message_close_container(req);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not close container TCA_OPTIONS: %m");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_heavy_hitter_filter_packet_limit(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
const char *section,
|
||||
unsigned section_line,
|
||||
const char *lvalue,
|
||||
int ltype,
|
||||
const char *rvalue,
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
_cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
||||
HeavyHitterFilter *hhf;
|
||||
Network *network = data;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = qdisc_new_static(QDISC_KIND_HHF, network, filename, section_line, &qdisc);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0)
|
||||
return log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"More than one kind of queueing discipline, ignoring assignment: %m");
|
||||
|
||||
hhf = HHF(qdisc);
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
hhf->packet_limit = 0;
|
||||
|
||||
qdisc = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = safe_atou32(rvalue, &hhf->packet_limit);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to parse '%s=', ignoring assignment: %s",
|
||||
lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
qdisc = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const QDiscVTable hhf_vtable = {
|
||||
.object_size = sizeof(HeavyHitterFilter),
|
||||
.tca_kind = "hhf",
|
||||
.fill_message = heavy_hitter_filter_fill_message,
|
||||
};
|
|
@ -0,0 +1,17 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+
|
||||
* Copyright © 2020 VMware, Inc. */
|
||||
#pragma once
|
||||
|
||||
#include "conf-parser.h"
|
||||
#include "qdisc.h"
|
||||
|
||||
typedef struct HeavyHitterFilter {
|
||||
QDisc meta;
|
||||
|
||||
uint32_t packet_limit;
|
||||
} HeavyHitterFilter;
|
||||
|
||||
DEFINE_QDISC_CAST(HHF, HeavyHitterFilter);
|
||||
extern const QDiscVTable hhf_vtable;
|
||||
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_heavy_hitter_filter_packet_limit);
|
|
@ -0,0 +1,95 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+
|
||||
* Copyright © 2020 VMware, Inc. */
|
||||
|
||||
#include <linux/pkt_sched.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "conf-parser.h"
|
||||
#include "pie.h"
|
||||
#include "netlink-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "string-util.h"
|
||||
|
||||
static int pie_fill_message(Link *link, QDisc *qdisc, sd_netlink_message *req) {
|
||||
proportional_integral_controller_enhanced *pie;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
assert(qdisc);
|
||||
assert(req);
|
||||
|
||||
pie = PIE(qdisc);
|
||||
|
||||
r = sd_netlink_message_open_container_union(req, TCA_OPTIONS, "pie");
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not open container TCA_OPTIONS: %m");
|
||||
|
||||
if (pie->packet_limit > 0) {
|
||||
r = sd_netlink_message_append_u32(req, TCA_PIE_LIMIT, pie->packet_limit);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append TCA_PIE_PLIMIT attribute: %m");
|
||||
}
|
||||
|
||||
r = sd_netlink_message_close_container(req);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not close container TCA_OPTIONS: %m");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_pie_packet_limit(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
const char *section,
|
||||
unsigned section_line,
|
||||
const char *lvalue,
|
||||
int ltype,
|
||||
const char *rvalue,
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
_cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
|
||||
proportional_integral_controller_enhanced *pie;
|
||||
Network *network = data;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = qdisc_new_static(QDISC_KIND_PIE, network, filename, section_line, &qdisc);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0)
|
||||
return log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"More than one kind of queueing discipline, ignoring assignment: %m");
|
||||
|
||||
pie = PIE(qdisc);
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
pie->packet_limit = 0;
|
||||
|
||||
qdisc = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = safe_atou32(rvalue, &pie->packet_limit);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r,
|
||||
"Failed to parse '%s=', ignoring assignment: %s",
|
||||
lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
qdisc = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const QDiscVTable pie_vtable = {
|
||||
.object_size = sizeof(proportional_integral_controller_enhanced),
|
||||
.tca_kind = "pie",
|
||||
.fill_message = pie_fill_message,
|
||||
};
|
|
@ -0,0 +1,17 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1+
|
||||
* Copyright © 2020 VMware, Inc. */
|
||||
#pragma once
|
||||
|
||||
#include "conf-parser.h"
|
||||
#include "qdisc.h"
|
||||
|
||||
typedef struct proportional_integral_controller_enhanced {
|
||||
QDisc meta;
|
||||
|
||||
uint32_t packet_limit;
|
||||
} proportional_integral_controller_enhanced;
|
||||
|
||||
DEFINE_QDISC_CAST(PIE, proportional_integral_controller_enhanced);
|
||||
extern const QDiscVTable pie_vtable;
|
||||
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_pie_packet_limit);
|
|
@ -16,14 +16,20 @@
|
|||
#include "tc-util.h"
|
||||
|
||||
const QDiscVTable * const qdisc_vtable[_QDISC_KIND_MAX] = {
|
||||
[QDISC_KIND_BFIFO] = &bfifo_vtable,
|
||||
[QDISC_KIND_CAKE] = &cake_vtable,
|
||||
[QDISC_KIND_CODEL] = &codel_vtable,
|
||||
[QDISC_KIND_DRR] = &drr_vtable,
|
||||
[QDISC_KIND_FQ] = &fq_vtable,
|
||||
[QDISC_KIND_FQ_CODEL] = &fq_codel_vtable,
|
||||
[QDISC_KIND_GRED] = &gred_vtable,
|
||||
[QDISC_KIND_HHF] = &hhf_vtable,
|
||||
[QDISC_KIND_HTB] = &htb_vtable,
|
||||
[QDISC_KIND_NETEM] = &netem_vtable,
|
||||
[QDISC_KIND_PIE] = &pie_vtable,
|
||||
[QDISC_KIND_PFIFO] = &pfifo_vtable,
|
||||
[QDISC_KIND_PFIFO_FAST] = &pfifo_fast_vtable,
|
||||
[QDISC_KIND_PFIFO_HEAD_DROP] = &pfifo_head_drop_vtable,
|
||||
[QDISC_KIND_SFB] = &sfb_vtable,
|
||||
[QDISC_KIND_SFQ] = &sfq_vtable,
|
||||
[QDISC_KIND_TBF] = &tbf_vtable,
|
||||
|
|
|
@ -9,14 +9,20 @@
|
|||
#include "tc.h"
|
||||
|
||||
typedef enum QDiscKind {
|
||||
QDISC_KIND_BFIFO,
|
||||
QDISC_KIND_CAKE,
|
||||
QDISC_KIND_CODEL,
|
||||
QDISC_KIND_DRR,
|
||||
QDISC_KIND_FQ,
|
||||
QDISC_KIND_FQ_CODEL,
|
||||
QDISC_KIND_GRED,
|
||||
QDISC_KIND_HHF,
|
||||
QDISC_KIND_HTB,
|
||||
QDISC_KIND_NETEM,
|
||||
QDISC_KIND_PFIFO,
|
||||
QDISC_KIND_PFIFO_FAST,
|
||||
QDISC_KIND_PFIFO_HEAD_DROP,
|
||||
QDISC_KIND_PIE,
|
||||
QDISC_KIND_SFB,
|
||||
QDISC_KIND_SFQ,
|
||||
QDISC_KIND_TBF,
|
||||
|
@ -84,8 +90,11 @@ CONFIG_PARSER_PROTOTYPE(config_parse_qdisc_handle);
|
|||
#include "fq-codel.h"
|
||||
#include "fq.h"
|
||||
#include "gred.h"
|
||||
#include "hhf.h"
|
||||
#include "htb.h"
|
||||
#include "pie.h"
|
||||
#include "netem.h"
|
||||
#include "drr.h"
|
||||
#include "sfb.h"
|
||||
#include "sfq.h"
|
||||
#include "tbf.h"
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "tclass.h"
|
||||
|
||||
const TClassVTable * const tclass_vtable[_TCLASS_KIND_MAX] = {
|
||||
[TCLASS_KIND_DRR] = &drr_tclass_vtable,
|
||||
[TCLASS_KIND_HTB] = &htb_tclass_vtable,
|
||||
};
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "tc.h"
|
||||
|
||||
typedef enum TClassKind {
|
||||
TCLASS_KIND_DRR,
|
||||
TCLASS_KIND_HTB,
|
||||
_TCLASS_KIND_MAX,
|
||||
_TCLASS_KIND_INVALID = -1,
|
||||
|
@ -64,4 +65,5 @@ DEFINE_TC_CAST(TCLASS, TClass);
|
|||
CONFIG_PARSER_PROTOTYPE(config_parse_tclass_parent);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_tclass_classid);
|
||||
|
||||
#include "drr.h"
|
||||
#include "htb.h"
|
||||
|
|
|
@ -356,10 +356,21 @@ ClassId=
|
|||
Priority=
|
||||
Rate=
|
||||
CeilRate=
|
||||
[BFIFO]
|
||||
Parent=
|
||||
Handle=
|
||||
LimitSize=
|
||||
[PFIFO]
|
||||
Parent=
|
||||
Handle=
|
||||
PacketLimit=
|
||||
[PFIFOHeadDrop]
|
||||
Parent=
|
||||
Handle=
|
||||
PacketLimit=
|
||||
[PFIFOFast]
|
||||
Parent=
|
||||
Handle=
|
||||
[GenericRandomEarlyDetection]
|
||||
Parent=
|
||||
Handle=
|
||||
|
@ -370,3 +381,18 @@ GenericRIO=
|
|||
Parent=
|
||||
Handle=
|
||||
PacketLimit=
|
||||
[PIE]
|
||||
Parent=
|
||||
Handle=
|
||||
PacketLimit=
|
||||
[DeficitRoundRobinScheduler]
|
||||
Parent=
|
||||
Handle=
|
||||
[DeficitRoundRobinSchedulerClass]
|
||||
Parent=
|
||||
ClassId=
|
||||
Quantum=
|
||||
[HeavyHitterFilter]
|
||||
Parent=
|
||||
Handle=
|
||||
PacketLimit=
|
||||
|
|
|
@ -160,3 +160,38 @@ CeilRate=0.5M
|
|||
Parent=2:39
|
||||
Handle=0039
|
||||
PacketLimit=200000
|
||||
|
||||
[HierarchyTokenBucketClass]
|
||||
Parent=root
|
||||
ClassId=0002:003a
|
||||
Priority=1
|
||||
Rate=1M
|
||||
CeilRate=0.5M
|
||||
|
||||
[BFIFO]
|
||||
Parent=2:3a
|
||||
Handle=003a
|
||||
LimitSize=1M
|
||||
|
||||
[HierarchyTokenBucketClass]
|
||||
Parent=root
|
||||
ClassId=0002:003b
|
||||
Priority=1
|
||||
Rate=1M
|
||||
CeilRate=0.5M
|
||||
|
||||
[PFIFOHeadDrop]
|
||||
Parent=2:3b
|
||||
Handle=003b
|
||||
PacketLimit=1023
|
||||
|
||||
[HierarchyTokenBucketClass]
|
||||
Parent=root
|
||||
ClassId=0002:003c
|
||||
Priority=1
|
||||
Rate=1M
|
||||
CeilRate=0.5M
|
||||
|
||||
[PFIFOFast]
|
||||
Parent=2:3c
|
||||
Handle=003c
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
[Match]
|
||||
Name=dummy98
|
||||
|
||||
[Network]
|
||||
IPv6AcceptRA=no
|
||||
Address=10.1.2.3/16
|
||||
|
||||
[DeficitRoundRobinScheduler]
|
||||
Parent=root
|
||||
Handle=0002
|
||||
|
||||
[DeficitRoundRobinSchedulerClass]
|
||||
Parent=root
|
||||
ClassId=0002:0030
|
||||
Quantum=2000
|
|
@ -0,0 +1,11 @@
|
|||
[Match]
|
||||
Name=dummy98
|
||||
|
||||
[Network]
|
||||
IPv6AcceptRA=no
|
||||
Address=10.1.2.3/16
|
||||
|
||||
[HeavyHitterFilter]
|
||||
Parent=root
|
||||
Handle=3a
|
||||
PacketLimit=1022
|
|
@ -0,0 +1,11 @@
|
|||
[Match]
|
||||
Name=dummy98
|
||||
|
||||
[Network]
|
||||
IPv6AcceptRA=no
|
||||
Address=10.1.2.3/16
|
||||
|
||||
[PIE]
|
||||
Parent=root
|
||||
Handle=3a
|
||||
PacketLimit=200000
|
|
@ -169,6 +169,30 @@ def expectedFailureIfCAKEIsNotAvailable():
|
|||
|
||||
return f
|
||||
|
||||
def expectedFailureIfPIEIsNotAvailable():
|
||||
def f(func):
|
||||
call('ip link add dummy98 type dummy', stderr=subprocess.DEVNULL)
|
||||
rc = call('tc qdisc add dev dummy98 parent root pie', stderr=subprocess.DEVNULL)
|
||||
call('ip link del dummy98', stderr=subprocess.DEVNULL)
|
||||
if rc == 0:
|
||||
return func
|
||||
else:
|
||||
return unittest.expectedFailure(func)
|
||||
|
||||
return f
|
||||
|
||||
def expectedFailureIfHHFIsNotAvailable():
|
||||
def f(func):
|
||||
call('ip link add dummy98 type dummy', stderr=subprocess.DEVNULL)
|
||||
rc = call('tc qdisc add dev dummy98 parent root hhf', stderr=subprocess.DEVNULL)
|
||||
call('ip link del dummy98', stderr=subprocess.DEVNULL)
|
||||
if rc == 0:
|
||||
return func
|
||||
else:
|
||||
return unittest.expectedFailure(func)
|
||||
|
||||
return f
|
||||
|
||||
def setUpModule():
|
||||
global running_units
|
||||
|
||||
|
@ -1635,7 +1659,10 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
|||
'25-nexthop.network',
|
||||
'25-qdisc-cake.network',
|
||||
'25-qdisc-clsact-and-htb.network',
|
||||
'25-qdisc-drr.network',
|
||||
'25-qdisc-hhf.network',
|
||||
'25-qdisc-ingress-netem-compat.network',
|
||||
'25-qdisc-pie.network',
|
||||
'25-route-ipv6-src.network',
|
||||
'25-route-static.network',
|
||||
'25-route-vrf.network',
|
||||
|
@ -2316,6 +2343,14 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
|||
self.assertRegex(output, 'qdisc sfb 39: parent 2:39')
|
||||
self.assertRegex(output, 'limit 200000')
|
||||
|
||||
self.assertRegex(output, 'qdisc bfifo 3a: parent 2:3a')
|
||||
self.assertRegex(output, 'limit 1000000')
|
||||
|
||||
self.assertRegex(output, 'qdisc pfifo_head_drop 3b: parent 2:3b')
|
||||
self.assertRegex(output, 'limit 1023p')
|
||||
|
||||
self.assertRegex(output, 'qdisc pfifo_fast 3c: parent 2:3c')
|
||||
|
||||
output = check_output('tc class show dev dummy98')
|
||||
print(output)
|
||||
self.assertRegex(output, 'class htb 2:30 root leaf 30:')
|
||||
|
@ -2328,8 +2363,24 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
|||
self.assertRegex(output, 'class htb 2:37 root leaf 37:')
|
||||
self.assertRegex(output, 'class htb 2:38 root leaf 38:')
|
||||
self.assertRegex(output, 'class htb 2:39 root leaf 39:')
|
||||
self.assertRegex(output, 'class htb 2:3a root leaf 3a:')
|
||||
self.assertRegex(output, 'class htb 2:3b root leaf 3b:')
|
||||
self.assertRegex(output, 'class htb 2:3c root leaf 3c:')
|
||||
self.assertRegex(output, 'prio 1 rate 1Mbit ceil 500Kbit')
|
||||
|
||||
def test_qdisc2(self):
|
||||
copy_unit_to_networkd_unit_path('25-qdisc-drr.network', '12-dummy.netdev')
|
||||
start_networkd()
|
||||
|
||||
self.wait_online(['dummy98:routable'])
|
||||
|
||||
output = check_output('tc qdisc show dev dummy98')
|
||||
print(output)
|
||||
self.assertRegex(output, 'qdisc drr 2: root')
|
||||
output = check_output('tc class show dev dummy98')
|
||||
print(output)
|
||||
self.assertRegex(output, 'class drr 2:30 root quantum 2000b')
|
||||
|
||||
@expectedFailureIfCAKEIsNotAvailable()
|
||||
def test_qdisc_cake(self):
|
||||
copy_unit_to_networkd_unit_path('25-qdisc-cake.network', '12-dummy.netdev')
|
||||
|
@ -2342,6 +2393,28 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
|||
self.assertRegex(output, 'bandwidth 500Mbit')
|
||||
self.assertRegex(output, 'overhead 128')
|
||||
|
||||
@expectedFailureIfPIEIsNotAvailable()
|
||||
def test_qdisc_pie(self):
|
||||
copy_unit_to_networkd_unit_path('25-qdisc-pie.network', '12-dummy.netdev')
|
||||
start_networkd()
|
||||
self.wait_online(['dummy98:routable'])
|
||||
|
||||
output = check_output('tc qdisc show dev dummy98')
|
||||
print(output)
|
||||
self.assertRegex(output, 'qdisc pie 3a: root')
|
||||
self.assertRegex(output, 'limit 200000')
|
||||
|
||||
@expectedFailureIfHHFIsNotAvailable()
|
||||
def test_qdisc_hhf(self):
|
||||
copy_unit_to_networkd_unit_path('25-qdisc-hhf.network', '12-dummy.netdev')
|
||||
start_networkd()
|
||||
self.wait_online(['dummy98:routable'])
|
||||
|
||||
output = check_output('tc qdisc show dev dummy98')
|
||||
print(output)
|
||||
self.assertRegex(output, 'qdisc hhf 3a: root')
|
||||
self.assertRegex(output, 'limit 1022p')
|
||||
|
||||
class NetworkdStateFileTests(unittest.TestCase, Utilities):
|
||||
links = [
|
||||
'dummy98',
|
||||
|
|
Loading…
Reference in New Issue