</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
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
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
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
"TrafficControlQueueingDiscipline\0"
"CAN\0"
"QDisc\0"
+ "BFIFO\0"
"CAKE\0"
"ControlledDelay\0"
"DeficitRoundRobinScheduler\0"
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;
+ default:
+ assert_not_reached("Invalid QDisc kind.");
+ }
opt.limit = fifo->limit;
return 0;
}
-int config_parse_fifo_size(
+int config_parse_pfifo_size(
const char *unit,
const char *filename,
unsigned line,
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,
+};
} FirstInFirstOut;
DEFINE_QDISC_CAST(PFIFO, FirstInFirstOut);
+DEFINE_QDISC_CAST(BFIFO, FirstInFirstOut);
+
extern const QDiscVTable pfifo_vtable;
+extern const QDiscVTable bfifo_vtable;
-CONFIG_PARSER_PROTOTYPE(config_parse_fifo_size);
+CONFIG_PARSER_PROTOTYPE(config_parse_pfifo_size);
+CONFIG_PARSER_PROTOTYPE(config_parse_bfifo_size);
#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,
#include "tc.h"
typedef enum QDiscKind {
+ QDISC_KIND_BFIFO,
QDISC_KIND_CAKE,
QDISC_KIND_CODEL,
QDISC_KIND_DRR,
Priority=
Rate=
CeilRate=
+[BFIFO]
+Parent=
+Handle=
+LimitSize=
[PFIFO]
Parent=
Handle=