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>
|
</variablelist>
|
||||||
</refsect1>
|
</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>
|
<refsect1>
|
||||||
<title>[StochasticFairBlue] Section Options</title>
|
<title>[StochasticFairBlue] Section Options</title>
|
||||||
<para>The <literal>[StochasticFairBlue]</literal> section manages the queueing discipline
|
<para>The <literal>[StochasticFairBlue]</literal> section manages the queueing discipline
|
||||||
|
@ -2565,6 +2597,40 @@
|
||||||
</variablelist>
|
</variablelist>
|
||||||
</refsect1>
|
</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>
|
<refsect1>
|
||||||
<title>[PFIFO] Section Options</title>
|
<title>[PFIFO] Section Options</title>
|
||||||
<para>The <literal>[PFIFO]</literal> section manages the queueing discipline (qdisc) of
|
<para>The <literal>[PFIFO]</literal> section manages the queueing discipline (qdisc) of
|
||||||
|
@ -2598,6 +2664,54 @@
|
||||||
</variablelist>
|
</variablelist>
|
||||||
</refsect1>
|
</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>
|
<refsect1>
|
||||||
<title>[CAKE] Section Options</title>
|
<title>[CAKE] Section Options</title>
|
||||||
<para>The <literal>[CAKE]</literal> section manages the queueing discipline (qdisc) of
|
<para>The <literal>[CAKE]</literal> section manages the queueing discipline (qdisc) of
|
||||||
|
@ -2707,6 +2821,68 @@
|
||||||
</variablelist>
|
</variablelist>
|
||||||
</refsect1>
|
</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>
|
<refsect1>
|
||||||
<title>[GenericRandomEarlyDetection] Section Options</title>
|
<title>[GenericRandomEarlyDetection] Section Options</title>
|
||||||
<para>The <literal>[GenericRandomEarlyDetection]</literal> section manages the queueing discipline
|
<para>The <literal>[GenericRandomEarlyDetection]</literal> section manages the queueing discipline
|
||||||
|
@ -3070,7 +3246,38 @@
|
||||||
is used.</para>
|
is used.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</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>
|
</variablelist>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
|
|
@ -10,11 +10,11 @@
|
||||||
#include "selinux-util.h"
|
#include "selinux-util.h"
|
||||||
#include "smack-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;
|
int r, q;
|
||||||
|
|
||||||
r = mac_selinux_fix(path, flags);
|
r = mac_selinux_fix_container(path, inside_path, flags);
|
||||||
q = mac_smack_fix(path, flags);
|
q = mac_smack_fix_container(path, inside_path, flags);
|
||||||
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
|
@ -9,7 +9,10 @@ typedef enum LabelFixFlags {
|
||||||
LABEL_IGNORE_EROFS = 1 << 1,
|
LABEL_IGNORE_EROFS = 1 << 1,
|
||||||
} LabelFixFlags;
|
} 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 mkdir_label(const char *path, mode_t mode);
|
||||||
int mkdirat_label(int dirfd, 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
|
#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
|
#if HAVE_SELINUX
|
||||||
char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
|
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 */
|
/* Check for policy reload so 'label_hnd' is kept up-to-date by callbacks */
|
||||||
(void) avc_netlink_check_nb();
|
(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;
|
r = -errno;
|
||||||
|
|
||||||
/* If there's no label to set, then exit without warning */
|
/* 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;
|
return 0;
|
||||||
|
|
||||||
fail:
|
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())
|
if (mac_selinux_enforcing())
|
||||||
return r;
|
return r;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -22,7 +22,11 @@ void mac_selinux_retest(void);
|
||||||
int mac_selinux_init(void);
|
int mac_selinux_init(void);
|
||||||
void mac_selinux_finish(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_apply(const char *path, const char *label);
|
||||||
|
|
||||||
int mac_selinux_get_create_label_from_exe(const char *exe, 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);
|
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_free_ char *abspath = NULL;
|
||||||
_cleanup_close_ int fd = -1;
|
_cleanup_close_ int fd = -1;
|
||||||
int r;
|
int r;
|
||||||
|
@ -228,7 +228,7 @@ int mac_smack_fix(const char *path, LabelFixFlags flags) {
|
||||||
return -errno;
|
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) {
|
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;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,11 @@ typedef enum SmackAttr {
|
||||||
|
|
||||||
bool mac_smack_use(void);
|
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);
|
int mac_smack_fix_at(int dirfd, const char *path, LabelFixFlags flags);
|
||||||
|
|
||||||
const char* smack_attr_to_string(SmackAttr i) _const_;
|
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);
|
r = log_debug_errno(errno, "Failed to mount tmpfs on '%s': %m", dev);
|
||||||
goto fail;
|
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");
|
devpts = strjoina(temporary_mount, "/dev/pts");
|
||||||
(void) mkdir(devpts, 0755);
|
(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 },
|
[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[] = {
|
static const NLType rtnl_tca_option_data_fq_types[] = {
|
||||||
[TCA_FQ_PLIMIT] = { .type = NETLINK_TYPE_U32 },
|
[TCA_FQ_PLIMIT] = { .type = NETLINK_TYPE_U32 },
|
||||||
[TCA_FQ_FLOW_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) },
|
[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[] = {
|
static const NLType rtnl_tca_option_data_htb_types[] = {
|
||||||
[TCA_HTB_PARMS] = { .size = sizeof(struct tc_htb_opt) },
|
[TCA_HTB_PARMS] = { .size = sizeof(struct tc_htb_opt) },
|
||||||
[TCA_HTB_INIT] = { .size = sizeof(struct tc_htb_glob) },
|
[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 },
|
[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[] = {
|
static const NLType rtnl_tca_option_data_sfb_types[] = {
|
||||||
[TCA_SFB_PARMS] = { .size = sizeof(struct tc_sfb_qopt) },
|
[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[] = {
|
static const char* const nl_union_tca_option_data_table[] = {
|
||||||
[NL_UNION_TCA_OPTION_DATA_CAKE] = "cake",
|
[NL_UNION_TCA_OPTION_DATA_CAKE] = "cake",
|
||||||
[NL_UNION_TCA_OPTION_DATA_CODEL] = "codel",
|
[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] = "fq",
|
||||||
[NL_UNION_TCA_OPTION_DATA_FQ_CODEL] = "fq_codel",
|
[NL_UNION_TCA_OPTION_DATA_FQ_CODEL] = "fq_codel",
|
||||||
[NL_UNION_TCA_OPTION_DATA_GRED] = "gred",
|
[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_HTB] = "htb",
|
||||||
|
[NL_UNION_TCA_OPTION_DATA_PIE] = "pie",
|
||||||
[NL_UNION_TCA_OPTION_DATA_SFB] = "sfb",
|
[NL_UNION_TCA_OPTION_DATA_SFB] = "sfb",
|
||||||
[NL_UNION_TCA_OPTION_DATA_TBF] = "tbf",
|
[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 },
|
.types = rtnl_tca_option_data_cake_types },
|
||||||
[NL_UNION_TCA_OPTION_DATA_CODEL] = { .count = ELEMENTSOF(rtnl_tca_option_data_codel_types),
|
[NL_UNION_TCA_OPTION_DATA_CODEL] = { .count = ELEMENTSOF(rtnl_tca_option_data_codel_types),
|
||||||
.types = 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),
|
[NL_UNION_TCA_OPTION_DATA_FQ] = { .count = ELEMENTSOF(rtnl_tca_option_data_fq_types),
|
||||||
.types = 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),
|
[NL_UNION_TCA_OPTION_DATA_FQ_CODEL] = { .count = ELEMENTSOF(rtnl_tca_option_data_fq_codel_types),
|
||||||
.types = 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),
|
[NL_UNION_TCA_OPTION_DATA_GRED] = { .count = ELEMENTSOF(rtnl_tca_option_data_gred_types),
|
||||||
.types = 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),
|
[NL_UNION_TCA_OPTION_DATA_HTB] = { .count = ELEMENTSOF(rtnl_tca_option_data_htb_types),
|
||||||
.types = 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),
|
[NL_UNION_TCA_OPTION_DATA_SFB] = { .count = ELEMENTSOF(rtnl_tca_option_data_sfb_types),
|
||||||
.types = 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),
|
[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 {
|
typedef enum NLUnionTCAOptionData {
|
||||||
NL_UNION_TCA_OPTION_DATA_CAKE,
|
NL_UNION_TCA_OPTION_DATA_CAKE,
|
||||||
NL_UNION_TCA_OPTION_DATA_CODEL,
|
NL_UNION_TCA_OPTION_DATA_CODEL,
|
||||||
|
NL_UNION_TCA_OPTION_DATA_DRR,
|
||||||
NL_UNION_TCA_OPTION_DATA_FQ,
|
NL_UNION_TCA_OPTION_DATA_FQ,
|
||||||
NL_UNION_TCA_OPTION_DATA_FQ_CODEL,
|
NL_UNION_TCA_OPTION_DATA_FQ_CODEL,
|
||||||
NL_UNION_TCA_OPTION_DATA_GRED,
|
NL_UNION_TCA_OPTION_DATA_GRED,
|
||||||
|
NL_UNION_TCA_OPTION_DATA_HHF,
|
||||||
NL_UNION_TCA_OPTION_DATA_HTB,
|
NL_UNION_TCA_OPTION_DATA_HTB,
|
||||||
|
NL_UNION_TCA_OPTION_DATA_PIE,
|
||||||
NL_UNION_TCA_OPTION_DATA_SFB,
|
NL_UNION_TCA_OPTION_DATA_SFB,
|
||||||
NL_UNION_TCA_OPTION_DATA_TBF,
|
NL_UNION_TCA_OPTION_DATA_TBF,
|
||||||
_NL_UNION_TCA_OPTION_DATA_MAX,
|
_NL_UNION_TCA_OPTION_DATA_MAX,
|
||||||
|
|
|
@ -111,6 +111,8 @@ sources = files('''
|
||||||
tc/cake.h
|
tc/cake.h
|
||||||
tc/codel.c
|
tc/codel.c
|
||||||
tc/codel.h
|
tc/codel.h
|
||||||
|
tc/drr.c
|
||||||
|
tc/drr.h
|
||||||
tc/fifo.c
|
tc/fifo.c
|
||||||
tc/fifo.h
|
tc/fifo.h
|
||||||
tc/fq.c
|
tc/fq.c
|
||||||
|
@ -119,10 +121,14 @@ sources = files('''
|
||||||
tc/fq-codel.h
|
tc/fq-codel.h
|
||||||
tc/gred.c
|
tc/gred.c
|
||||||
tc/gred.h
|
tc/gred.h
|
||||||
|
tc/hhf.c
|
||||||
|
tc/hhf.h
|
||||||
tc/htb.c
|
tc/htb.c
|
||||||
tc/htb.h
|
tc/htb.h
|
||||||
tc/netem.c
|
tc/netem.c
|
||||||
tc/netem.h
|
tc/netem.h
|
||||||
|
tc/pie.c
|
||||||
|
tc/pie.h
|
||||||
tc/qdisc.c
|
tc/qdisc.c
|
||||||
tc/qdisc.h
|
tc/qdisc.h
|
||||||
tc/sfb.c
|
tc/sfb.c
|
||||||
|
|
|
@ -258,6 +258,9 @@ CAN.TripleSampling, config_parse_tristate,
|
||||||
CAN.Termination, config_parse_tristate, 0, offsetof(Network, can_termination)
|
CAN.Termination, config_parse_tristate, 0, offsetof(Network, can_termination)
|
||||||
QDisc.Parent, config_parse_qdisc_parent, _QDISC_KIND_INVALID, 0
|
QDisc.Parent, config_parse_qdisc_parent, _QDISC_KIND_INVALID, 0
|
||||||
QDisc.Handle, config_parse_qdisc_handle, _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.Parent, config_parse_qdisc_parent, QDISC_KIND_CAKE, 0
|
||||||
CAKE.Handle, config_parse_qdisc_handle, QDISC_KIND_CAKE, 0
|
CAKE.Handle, config_parse_qdisc_handle, QDISC_KIND_CAKE, 0
|
||||||
CAKE.Bandwidth, config_parse_cake_bandwidth, 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.IntervalSec, config_parse_controlled_delay_usec, QDISC_KIND_CODEL, 0
|
||||||
ControlledDelay.CEThresholdSec, 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
|
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.Parent, config_parse_qdisc_parent, QDISC_KIND_PFIFO, 0
|
||||||
PFIFO.Handle, config_parse_qdisc_handle, 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.Parent, config_parse_qdisc_parent, QDISC_KIND_FQ, 0
|
||||||
FairQueueing.Handle, config_parse_qdisc_handle, 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
|
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.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.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
|
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.Parent, config_parse_qdisc_parent, QDISC_KIND_HTB, 0
|
||||||
HierarchyTokenBucket.Handle, config_parse_qdisc_handle, 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
|
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.LossRate, config_parse_network_emulator_rate, QDISC_KIND_NETEM, 0
|
||||||
NetworkEmulator.DuplicateRate, 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
|
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.Parent, config_parse_qdisc_parent, QDISC_KIND_SFB, 0
|
||||||
StochasticFairBlue.Handle, config_parse_qdisc_handle, 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
|
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"
|
"TrafficControlQueueingDiscipline\0"
|
||||||
"CAN\0"
|
"CAN\0"
|
||||||
"QDisc\0"
|
"QDisc\0"
|
||||||
|
"BFIFO\0"
|
||||||
"CAKE\0"
|
"CAKE\0"
|
||||||
"ControlledDelay\0"
|
"ControlledDelay\0"
|
||||||
|
"DeficitRoundRobinScheduler\0"
|
||||||
|
"DeficitRoundRobinSchedulerClass\0"
|
||||||
"PFIFO\0"
|
"PFIFO\0"
|
||||||
|
"PFIFOFast\0"
|
||||||
|
"PFIFOHeadDrop\0"
|
||||||
"FairQueueing\0"
|
"FairQueueing\0"
|
||||||
"FairQueueingControlledDelay\0"
|
"FairQueueingControlledDelay\0"
|
||||||
"GenericRandomEarlyDetection\0"
|
"GenericRandomEarlyDetection\0"
|
||||||
|
"HeavyHitterFilter\0"
|
||||||
"HierarchyTokenBucket\0"
|
"HierarchyTokenBucket\0"
|
||||||
"HierarchyTokenBucketClass\0"
|
"HierarchyTokenBucketClass\0"
|
||||||
"NetworkEmulator\0"
|
"NetworkEmulator\0"
|
||||||
|
"PIE\0"
|
||||||
"StochasticFairBlue\0"
|
"StochasticFairBlue\0"
|
||||||
"StochasticFairnessQueueing\0"
|
"StochasticFairnessQueueing\0"
|
||||||
"TokenBucketFilter\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(qdisc);
|
||||||
assert(req);
|
assert(req);
|
||||||
|
|
||||||
|
switch(qdisc->kind) {
|
||||||
|
case QDISC_KIND_PFIFO:
|
||||||
fifo = PFIFO(qdisc);
|
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;
|
opt.limit = fifo->limit;
|
||||||
|
|
||||||
|
@ -30,7 +42,7 @@ static int fifo_fill_message(Link *link, QDisc *qdisc, sd_netlink_message *req)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int config_parse_fifo_size(
|
int config_parse_pfifo_size(
|
||||||
const char *unit,
|
const char *unit,
|
||||||
const char *filename,
|
const char *filename,
|
||||||
unsigned line,
|
unsigned line,
|
||||||
|
@ -52,14 +64,23 @@ int config_parse_fifo_size(
|
||||||
assert(rvalue);
|
assert(rvalue);
|
||||||
assert(data);
|
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)
|
if (r == -ENOMEM)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_syntax(unit, LOG_ERR, filename, line, r,
|
return log_syntax(unit, LOG_ERR, filename, line, r,
|
||||||
"More than one kind of queueing discipline, ignoring assignment: %m");
|
"More than one kind of queueing discipline, ignoring assignment: %m");
|
||||||
|
|
||||||
|
switch(qdisc->kind) {
|
||||||
|
case QDISC_KIND_PFIFO:
|
||||||
fifo = PFIFO(qdisc);
|
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)) {
|
if (isempty(rvalue)) {
|
||||||
fifo->limit = 0;
|
fifo->limit = 0;
|
||||||
|
@ -80,8 +101,83 @@ int config_parse_fifo_size(
|
||||||
return 0;
|
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 = {
|
const QDiscVTable pfifo_vtable = {
|
||||||
.object_size = sizeof(FirstInFirstOut),
|
.object_size = sizeof(FirstInFirstOut),
|
||||||
.tca_kind = "pfifo",
|
.tca_kind = "pfifo",
|
||||||
.fill_message = fifo_fill_message,
|
.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;
|
} FirstInFirstOut;
|
||||||
|
|
||||||
DEFINE_QDISC_CAST(PFIFO, 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"
|
#include "tc-util.h"
|
||||||
|
|
||||||
const QDiscVTable * const qdisc_vtable[_QDISC_KIND_MAX] = {
|
const QDiscVTable * const qdisc_vtable[_QDISC_KIND_MAX] = {
|
||||||
|
[QDISC_KIND_BFIFO] = &bfifo_vtable,
|
||||||
[QDISC_KIND_CAKE] = &cake_vtable,
|
[QDISC_KIND_CAKE] = &cake_vtable,
|
||||||
[QDISC_KIND_CODEL] = &codel_vtable,
|
[QDISC_KIND_CODEL] = &codel_vtable,
|
||||||
|
[QDISC_KIND_DRR] = &drr_vtable,
|
||||||
[QDISC_KIND_FQ] = &fq_vtable,
|
[QDISC_KIND_FQ] = &fq_vtable,
|
||||||
[QDISC_KIND_FQ_CODEL] = &fq_codel_vtable,
|
[QDISC_KIND_FQ_CODEL] = &fq_codel_vtable,
|
||||||
[QDISC_KIND_GRED] = &gred_vtable,
|
[QDISC_KIND_GRED] = &gred_vtable,
|
||||||
|
[QDISC_KIND_HHF] = &hhf_vtable,
|
||||||
[QDISC_KIND_HTB] = &htb_vtable,
|
[QDISC_KIND_HTB] = &htb_vtable,
|
||||||
[QDISC_KIND_NETEM] = &netem_vtable,
|
[QDISC_KIND_NETEM] = &netem_vtable,
|
||||||
|
[QDISC_KIND_PIE] = &pie_vtable,
|
||||||
[QDISC_KIND_PFIFO] = &pfifo_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_SFB] = &sfb_vtable,
|
||||||
[QDISC_KIND_SFQ] = &sfq_vtable,
|
[QDISC_KIND_SFQ] = &sfq_vtable,
|
||||||
[QDISC_KIND_TBF] = &tbf_vtable,
|
[QDISC_KIND_TBF] = &tbf_vtable,
|
||||||
|
|
|
@ -9,14 +9,20 @@
|
||||||
#include "tc.h"
|
#include "tc.h"
|
||||||
|
|
||||||
typedef enum QDiscKind {
|
typedef enum QDiscKind {
|
||||||
|
QDISC_KIND_BFIFO,
|
||||||
QDISC_KIND_CAKE,
|
QDISC_KIND_CAKE,
|
||||||
QDISC_KIND_CODEL,
|
QDISC_KIND_CODEL,
|
||||||
|
QDISC_KIND_DRR,
|
||||||
QDISC_KIND_FQ,
|
QDISC_KIND_FQ,
|
||||||
QDISC_KIND_FQ_CODEL,
|
QDISC_KIND_FQ_CODEL,
|
||||||
QDISC_KIND_GRED,
|
QDISC_KIND_GRED,
|
||||||
|
QDISC_KIND_HHF,
|
||||||
QDISC_KIND_HTB,
|
QDISC_KIND_HTB,
|
||||||
QDISC_KIND_NETEM,
|
QDISC_KIND_NETEM,
|
||||||
QDISC_KIND_PFIFO,
|
QDISC_KIND_PFIFO,
|
||||||
|
QDISC_KIND_PFIFO_FAST,
|
||||||
|
QDISC_KIND_PFIFO_HEAD_DROP,
|
||||||
|
QDISC_KIND_PIE,
|
||||||
QDISC_KIND_SFB,
|
QDISC_KIND_SFB,
|
||||||
QDISC_KIND_SFQ,
|
QDISC_KIND_SFQ,
|
||||||
QDISC_KIND_TBF,
|
QDISC_KIND_TBF,
|
||||||
|
@ -84,8 +90,11 @@ CONFIG_PARSER_PROTOTYPE(config_parse_qdisc_handle);
|
||||||
#include "fq-codel.h"
|
#include "fq-codel.h"
|
||||||
#include "fq.h"
|
#include "fq.h"
|
||||||
#include "gred.h"
|
#include "gred.h"
|
||||||
|
#include "hhf.h"
|
||||||
#include "htb.h"
|
#include "htb.h"
|
||||||
|
#include "pie.h"
|
||||||
#include "netem.h"
|
#include "netem.h"
|
||||||
|
#include "drr.h"
|
||||||
#include "sfb.h"
|
#include "sfb.h"
|
||||||
#include "sfq.h"
|
#include "sfq.h"
|
||||||
#include "tbf.h"
|
#include "tbf.h"
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "tclass.h"
|
#include "tclass.h"
|
||||||
|
|
||||||
const TClassVTable * const tclass_vtable[_TCLASS_KIND_MAX] = {
|
const TClassVTable * const tclass_vtable[_TCLASS_KIND_MAX] = {
|
||||||
|
[TCLASS_KIND_DRR] = &drr_tclass_vtable,
|
||||||
[TCLASS_KIND_HTB] = &htb_tclass_vtable,
|
[TCLASS_KIND_HTB] = &htb_tclass_vtable,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "tc.h"
|
#include "tc.h"
|
||||||
|
|
||||||
typedef enum TClassKind {
|
typedef enum TClassKind {
|
||||||
|
TCLASS_KIND_DRR,
|
||||||
TCLASS_KIND_HTB,
|
TCLASS_KIND_HTB,
|
||||||
_TCLASS_KIND_MAX,
|
_TCLASS_KIND_MAX,
|
||||||
_TCLASS_KIND_INVALID = -1,
|
_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_parent);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_tclass_classid);
|
CONFIG_PARSER_PROTOTYPE(config_parse_tclass_classid);
|
||||||
|
|
||||||
|
#include "drr.h"
|
||||||
#include "htb.h"
|
#include "htb.h"
|
||||||
|
|
|
@ -356,10 +356,21 @@ ClassId=
|
||||||
Priority=
|
Priority=
|
||||||
Rate=
|
Rate=
|
||||||
CeilRate=
|
CeilRate=
|
||||||
|
[BFIFO]
|
||||||
|
Parent=
|
||||||
|
Handle=
|
||||||
|
LimitSize=
|
||||||
[PFIFO]
|
[PFIFO]
|
||||||
Parent=
|
Parent=
|
||||||
Handle=
|
Handle=
|
||||||
PacketLimit=
|
PacketLimit=
|
||||||
|
[PFIFOHeadDrop]
|
||||||
|
Parent=
|
||||||
|
Handle=
|
||||||
|
PacketLimit=
|
||||||
|
[PFIFOFast]
|
||||||
|
Parent=
|
||||||
|
Handle=
|
||||||
[GenericRandomEarlyDetection]
|
[GenericRandomEarlyDetection]
|
||||||
Parent=
|
Parent=
|
||||||
Handle=
|
Handle=
|
||||||
|
@ -370,3 +381,18 @@ GenericRIO=
|
||||||
Parent=
|
Parent=
|
||||||
Handle=
|
Handle=
|
||||||
PacketLimit=
|
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
|
Parent=2:39
|
||||||
Handle=0039
|
Handle=0039
|
||||||
PacketLimit=200000
|
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
|
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():
|
def setUpModule():
|
||||||
global running_units
|
global running_units
|
||||||
|
|
||||||
|
@ -1635,7 +1659,10 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
||||||
'25-nexthop.network',
|
'25-nexthop.network',
|
||||||
'25-qdisc-cake.network',
|
'25-qdisc-cake.network',
|
||||||
'25-qdisc-clsact-and-htb.network',
|
'25-qdisc-clsact-and-htb.network',
|
||||||
|
'25-qdisc-drr.network',
|
||||||
|
'25-qdisc-hhf.network',
|
||||||
'25-qdisc-ingress-netem-compat.network',
|
'25-qdisc-ingress-netem-compat.network',
|
||||||
|
'25-qdisc-pie.network',
|
||||||
'25-route-ipv6-src.network',
|
'25-route-ipv6-src.network',
|
||||||
'25-route-static.network',
|
'25-route-static.network',
|
||||||
'25-route-vrf.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, 'qdisc sfb 39: parent 2:39')
|
||||||
self.assertRegex(output, 'limit 200000')
|
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')
|
output = check_output('tc class show dev dummy98')
|
||||||
print(output)
|
print(output)
|
||||||
self.assertRegex(output, 'class htb 2:30 root leaf 30:')
|
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:37 root leaf 37:')
|
||||||
self.assertRegex(output, 'class htb 2:38 root leaf 38:')
|
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: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')
|
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()
|
@expectedFailureIfCAKEIsNotAvailable()
|
||||||
def test_qdisc_cake(self):
|
def test_qdisc_cake(self):
|
||||||
copy_unit_to_networkd_unit_path('25-qdisc-cake.network', '12-dummy.netdev')
|
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, 'bandwidth 500Mbit')
|
||||||
self.assertRegex(output, 'overhead 128')
|
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):
|
class NetworkdStateFileTests(unittest.TestCase, Utilities):
|
||||||
links = [
|
links = [
|
||||||
'dummy98',
|
'dummy98',
|
||||||
|
|
Loading…
Reference in New Issue