network: TC introduce PFIFO

This commit is contained in:
Susant Sahani 2020-02-10 16:12:21 +01:00 committed by Yu Watanabe
parent f1de1eb3e3
commit a74760653c
9 changed files with 151 additions and 0 deletions

View File

@ -2500,6 +2500,40 @@
</variablelist>
</refsect1>
<refsect1>
<title>[PFIFO] Section Options</title>
<para>The <literal>[PFIFO]</literal> section manages the queueing discipline (qdisc) of
Packet First In First Out (pfifo).</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 FIFO size in number of packets. 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. An unsigned integer ranges 0 to 4294967294. Defaults to unset and kernel's default is used.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>[ControlledDelay] Section Options</title>
<para>The <literal>[ControlledDelay]</literal> section manages the queueing discipline (qdisc) of

View File

@ -109,6 +109,8 @@ sources = files('''
networkd-wifi.h
tc/codel.c
tc/codel.h
tc/fifo.c
tc/fifo.h
tc/fq.c
tc/fq.h
tc/fq-codel.c

View File

@ -261,6 +261,9 @@ 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
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
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

View File

@ -485,6 +485,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
"CAN\0"
"QDisc\0"
"ControlledDelay\0"
"PFIFO\0"
"FairQueueing\0"
"FairQueueingControlledDelay\0"
"HierarchyTokenBucket\0"

87
src/network/tc/fifo.c Normal file
View File

@ -0,0 +1,87 @@
/* SPDX-License-Identifier: LGPL-2.1+
* Copyright © 2020 VMware, Inc. */
#include <linux/pkt_sched.h>
#include "alloc-util.h"
#include "conf-parser.h"
#include "fifo.h"
#include "netlink-util.h"
#include "parse-util.h"
#include "string-util.h"
static int fifo_fill_message(Link *link, QDisc *qdisc, sd_netlink_message *req) {
struct tc_fifo_qopt opt = {};
FirstInFirstOut *fifo;
int r;
assert(link);
assert(qdisc);
assert(req);
fifo = PFIFO(qdisc);
opt.limit = fifo->limit;
r = sd_netlink_message_append_data(req, TCA_OPTIONS, &opt, sizeof(struct tc_fifo_qopt));
if (r < 0)
return log_link_error_errno(link, r, "Could not append TCA_OPTIONS attribute: %m");
return 0;
}
int config_parse_fifo_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;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
r = qdisc_new_static(QDISC_KIND_PFIFO, 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);
if (isempty(rvalue)) {
fifo->limit = 0;
qdisc = NULL;
return 0;
}
r = safe_atou32(rvalue, &fifo->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 pfifo_vtable = {
.object_size = sizeof(FirstInFirstOut),
.tca_kind = "pfifo",
.fill_message = fifo_fill_message,
};

17
src/network/tc/fifo.h Normal file
View File

@ -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 FirstInFirstOut {
QDisc meta;
uint32_t limit;
} FirstInFirstOut;
DEFINE_QDISC_CAST(PFIFO, FirstInFirstOut);
extern const QDiscVTable pfifo_vtable;
CONFIG_PARSER_PROTOTYPE(config_parse_fifo_size);

View File

@ -21,6 +21,7 @@ const QDiscVTable * const qdisc_vtable[_QDISC_KIND_MAX] = {
[QDISC_KIND_FQ_CODEL] = &fq_codel_vtable,
[QDISC_KIND_HTB] = &htb_vtable,
[QDISC_KIND_NETEM] = &netem_vtable,
[QDISC_KIND_PFIFO] = &pfifo_vtable,
[QDISC_KIND_SFQ] = &sfq_vtable,
[QDISC_KIND_TBF] = &tbf_vtable,
[QDISC_KIND_TEQL] = &teql_vtable,

View File

@ -14,6 +14,7 @@ typedef enum QDiscKind {
QDISC_KIND_FQ_CODEL,
QDISC_KIND_HTB,
QDISC_KIND_NETEM,
QDISC_KIND_PFIFO,
QDISC_KIND_SFQ,
QDISC_KIND_TBF,
QDISC_KIND_TEQL,
@ -75,6 +76,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_qdisc_parent);
CONFIG_PARSER_PROTOTYPE(config_parse_qdisc_handle);
#include "codel.h"
#include "fifo.h"
#include "fq-codel.h"
#include "fq.h"
#include "htb.h"

View File

@ -347,3 +347,7 @@ ClassId=
Priority=
Rate=
CeilRate=
[PFIFO]
Parent=
Handle=
PacketLimit=