From 053a2ddbb28cd819acb292673d101890ece3b2ac Mon Sep 17 00:00:00 2001 From: Susant Sahani Date: Tue, 10 Mar 2020 13:19:56 +0100 Subject: [PATCH] network: TC - introduce pfifo_head_drop This adds the required changes to gain access to the head drop classfull queuing discipline named pfifo_head_drop. --- man/systemd.network.xml | 27 +++++++++++++++++++ src/network/networkd-network-gperf.gperf | 3 +++ src/network/networkd-network.c | 1 + src/network/tc/fifo.c | 23 +++++++++++++--- src/network/tc/fifo.h | 2 ++ src/network/tc/qdisc.c | 1 + src/network/tc/qdisc.h | 1 + .../fuzz-network-parser/directives.network | 4 +++ 8 files changed, 59 insertions(+), 3 deletions(-) diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 6d90c215ab..c6997f1420 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -2664,6 +2664,33 @@ + + [PFIFOHeadDrop] Section Options + The [PFIFOHeadDrop] section manages the queueing discipline (qdisc) of + Packet First In First Out Head Drop (pfifo_head_drop). + + + + Parent= + + As in [PFIFO] section. + + + + Handle= + + As in [PFIFO] section.. + + + + + PacketLimit= + + As in [PFIFO] section. + + + + [CAKE] Section Options The [CAKE] section manages the queueing discipline (qdisc) of diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 223d245a0f..0e8ecabc67 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -280,6 +280,9 @@ DeficitRoundRobinSchedulerClass.Quantum, config_parse_drr_size, PFIFO.Parent, config_parse_qdisc_parent, QDISC_KIND_PFIFO, 0 PFIFO.Handle, config_parse_qdisc_handle, QDISC_KIND_PFIFO, 0 PFIFO.PacketLimit, config_parse_pfifo_size, QDISC_KIND_PFIFO, 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 diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 6e4eb39f86..6b1f00c099 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -492,6 +492,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi "DeficitRoundRobinScheduler\0" "DeficitRoundRobinSchedulerClass\0" "PFIFO\0" + "PFIFOHeadDrop\0" "FairQueueing\0" "FairQueueingControlledDelay\0" "GenericRandomEarlyDetection\0" diff --git a/src/network/tc/fifo.c b/src/network/tc/fifo.c index 7978f7b922..a524b614b9 100644 --- a/src/network/tc/fifo.c +++ b/src/network/tc/fifo.c @@ -26,6 +26,9 @@ static int fifo_fill_message(Link *link, QDisc *qdisc, sd_netlink_message *req) 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."); } @@ -61,14 +64,23 @@ int config_parse_pfifo_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; @@ -147,7 +159,6 @@ int config_parse_bfifo_size( return 0; } - const QDiscVTable pfifo_vtable = { .object_size = sizeof(FirstInFirstOut), .tca_kind = "pfifo", @@ -159,3 +170,9 @@ const QDiscVTable bfifo_vtable = { .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, +}; diff --git a/src/network/tc/fifo.h b/src/network/tc/fifo.h index 7e6a94f16c..bba5f17abe 100644 --- a/src/network/tc/fifo.h +++ b/src/network/tc/fifo.h @@ -13,9 +13,11 @@ typedef struct FirstInFirstOut { DEFINE_QDISC_CAST(PFIFO, FirstInFirstOut); DEFINE_QDISC_CAST(BFIFO, FirstInFirstOut); +DEFINE_QDISC_CAST(PFIFO_HEAD_DROP, FirstInFirstOut); extern const QDiscVTable pfifo_vtable; extern const QDiscVTable bfifo_vtable; +extern const QDiscVTable pfifo_head_drop_vtable; CONFIG_PARSER_PROTOTYPE(config_parse_pfifo_size); CONFIG_PARSER_PROTOTYPE(config_parse_bfifo_size); diff --git a/src/network/tc/qdisc.c b/src/network/tc/qdisc.c index b6acc29f11..da0f43f7d2 100644 --- a/src/network/tc/qdisc.c +++ b/src/network/tc/qdisc.c @@ -27,6 +27,7 @@ const QDiscVTable * const qdisc_vtable[_QDISC_KIND_MAX] = { [QDISC_KIND_NETEM] = &netem_vtable, [QDISC_KIND_PIE] = &pie_vtable, [QDISC_KIND_PFIFO] = &pfifo_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, diff --git a/src/network/tc/qdisc.h b/src/network/tc/qdisc.h index 31a3ca3414..8f348d69e3 100644 --- a/src/network/tc/qdisc.h +++ b/src/network/tc/qdisc.h @@ -19,6 +19,7 @@ typedef enum QDiscKind { QDISC_KIND_HTB, QDISC_KIND_NETEM, QDISC_KIND_PFIFO, + QDISC_KIND_PFIFO_HEAD_DROP, QDISC_KIND_PIE, QDISC_KIND_SFB, QDISC_KIND_SFQ, diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network index c4d13a73dc..c0f71bc13f 100644 --- a/test/fuzz/fuzz-network-parser/directives.network +++ b/test/fuzz/fuzz-network-parser/directives.network @@ -364,6 +364,10 @@ LimitSize= Parent= Handle= PacketLimit= +[PFIFOHeadDrop] +Parent= +Handle= +PacketLimit= [GenericRandomEarlyDetection] Parent= Handle=