Compare commits

..

No commits in common. "161bc1b62777b3f32ce645a8e128007a654a2300" and "0d63e7dd0bff07204cf35ed07e56270a03a6055f" have entirely different histories.

21 changed files with 85 additions and 380 deletions

View File

@ -3252,45 +3252,6 @@
</variablelist> </variablelist>
</refsect1> </refsect1>
<refsect1>
<title>[QuickFairQueueing] Section Options</title>
<para>The <literal>[QuickFairQueueing]</literal> section manages the queueing discipline
(qdisc) of Quick Fair Queueing (QFQ).</para>
<variablelist class='network-directives'>
<xi:include href="tc.xml" xpointer="qdisc-parent" />
<xi:include href="tc.xml" xpointer="qdisc-handle" />
</variablelist>
</refsect1>
<refsect1>
<title>[QuickFairQueueingClass] Section Options</title>
<para>The <literal>[QuickFairQueueingClass]</literal> section manages the traffic control class of
Quick Fair Queueing (qfq).</para>
<variablelist class='network-directives'>
<xi:include href="tc.xml" xpointer="tclass-parent" />
<xi:include href="tc.xml" xpointer="tclass-classid" />
<varlistentry>
<term><varname>Weight=</varname></term>
<listitem>
<para>Specifies the weight of the class. Takse an integer in the range 1..1023. Defaults to
unset in which case the kernel default is used.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>MaxPacketSize=</varname></term>
<listitem>
<para>Specifies the maximum packet size in bytes for the class. When suffixed with K, M, or G, the specified
size is parsed as Kilobytes, Megabytes, or Gigabytes, respectively, to the base of 1000. When unset,
the kernel default is used.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1> <refsect1>
<title>[BridgeVLAN] Section Options</title> <title>[BridgeVLAN] Section Options</title>
<para>The <literal>[BridgeVLAN]</literal> section manages the VLAN ID configuration of a bridge port and accepts <para>The <literal>[BridgeVLAN]</literal> section manages the VLAN ID configuration of a bridge port and accepts

View File

@ -39,7 +39,7 @@ static inline void* bsearch_safe(const void *key, const void *base,
* Normal qsort requires base to be nonnull. Here were require * Normal qsort requires base to be nonnull. Here were require
* that only if nmemb > 0. * that only if nmemb > 0.
*/ */
static inline void _qsort_safe(void *base, size_t nmemb, size_t size, __compar_fn_t compar) { static inline void qsort_safe(void *base, size_t nmemb, size_t size, __compar_fn_t compar) {
if (nmemb <= 1) if (nmemb <= 1)
return; return;
@ -52,7 +52,7 @@ static inline void _qsort_safe(void *base, size_t nmemb, size_t size, __compar_f
#define typesafe_qsort(p, n, func) \ #define typesafe_qsort(p, n, func) \
({ \ ({ \
int (*_func_)(const typeof(p[0])*, const typeof(p[0])*) = func; \ int (*_func_)(const typeof(p[0])*, const typeof(p[0])*) = func; \
_qsort_safe((p), (n), sizeof((p)[0]), (__compar_fn_t) _func_); \ qsort_safe((p), (n), sizeof((p)[0]), (__compar_fn_t) _func_); \
}) })
static inline void qsort_r_safe(void *base, size_t nmemb, size_t size, __compar_d_fn_t compar, void *userdata) { static inline void qsort_r_safe(void *base, size_t nmemb, size_t size, __compar_d_fn_t compar, void *userdata) {

View File

@ -19,19 +19,18 @@
#include "util.h" #include "util.h"
int strcmp_ptr(const char *a, const char *b) { int strcmp_ptr(const char *a, const char *b) {
/* Like strcmp(), but tries to make sense of NULL pointers */
/* Like strcmp(), but tries to make sense of NULL pointers */
if (a && b) if (a && b)
return strcmp(a, b); return strcmp(a, b);
return CMP(a, b); /* Direct comparison of pointers, one of which is NULL */
}
int strcasecmp_ptr(const char *a, const char *b) { if (!a && b)
/* Like strcasecmp(), but tries to make sense of NULL pointers */ return -1;
if (a && b) if (a && !b)
return strcasecmp(a, b); return 1;
return CMP(a, b); /* Direct comparison of pointers, one of which is NULL */
return 0;
} }
char* endswith(const char *s, const char *postfix) { char* endswith(const char *s, const char *postfix) {

View File

@ -27,7 +27,6 @@
#define strncaseeq(a, b, n) (strncasecmp((a), (b), (n)) == 0) #define strncaseeq(a, b, n) (strncasecmp((a), (b), (n)) == 0)
int strcmp_ptr(const char *a, const char *b) _pure_; int strcmp_ptr(const char *a, const char *b) _pure_;
int strcasecmp_ptr(const char *a, const char *b) _pure_;
static inline bool streq_ptr(const char *a, const char *b) { static inline bool streq_ptr(const char *a, const char *b) {
return strcmp_ptr(a, b) == 0; return strcmp_ptr(a, b) == 0;

View File

@ -810,11 +810,6 @@ static const NLType rtnl_tca_option_data_pie_types[] = {
[TCA_PIE_LIMIT] = { .type = NETLINK_TYPE_U32 }, [TCA_PIE_LIMIT] = { .type = NETLINK_TYPE_U32 },
}; };
static const NLType rtnl_tca_option_data_qfq_types[] = {
[TCA_QFQ_WEIGHT] = { .type = NETLINK_TYPE_U32 },
[TCA_QFQ_LMAX] = { .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) },
}; };
@ -839,7 +834,6 @@ static const char* const nl_union_tca_option_data_table[] = {
[NL_UNION_TCA_OPTION_DATA_HHF] = "hhf", [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_PIE] = "pie",
[NL_UNION_TCA_OPTION_DATA_QFQ] = "qfq",
[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",
}; };
@ -865,8 +859,6 @@ static const NLTypeSystem rtnl_tca_option_data_type_systems[] = {
.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), [NL_UNION_TCA_OPTION_DATA_PIE] = { .count = ELEMENTSOF(rtnl_tca_option_data_pie_types),
.types = rtnl_tca_option_data_pie_types }, .types = rtnl_tca_option_data_pie_types },
[NL_UNION_TCA_OPTION_DATA_QFQ] = { .count = ELEMENTSOF(rtnl_tca_option_data_qfq_types),
.types = rtnl_tca_option_data_qfq_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),

View File

@ -105,7 +105,6 @@ typedef enum NLUnionTCAOptionData {
NL_UNION_TCA_OPTION_DATA_HHF, 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_PIE,
NL_UNION_TCA_OPTION_DATA_QFQ,
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,

View File

@ -131,8 +131,6 @@ sources = files('''
tc/pie.h tc/pie.h
tc/qdisc.c tc/qdisc.c
tc/qdisc.h tc/qdisc.h
tc/qfq.c
tc/qfq.h
tc/sfb.c tc/sfb.c
tc/sfb.h tc/sfb.h
tc/sfq.c tc/sfq.c

View File

@ -312,12 +312,6 @@ PFIFOFast.Handle, config_parse_qdisc_handle,
PFIFOHeadDrop.Parent, config_parse_qdisc_parent, QDISC_KIND_PFIFO_HEAD_DROP, 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.Handle, config_parse_qdisc_handle, QDISC_KIND_PFIFO_HEAD_DROP, 0
PFIFOHeadDrop.PacketLimit, config_parse_pfifo_size, QDISC_KIND_PFIFO_HEAD_DROP, 0 PFIFOHeadDrop.PacketLimit, config_parse_pfifo_size, QDISC_KIND_PFIFO_HEAD_DROP, 0
QuickFairQueueing.Parent, config_parse_qdisc_parent, QDISC_KIND_QFQ, 0
QuickFairQueueing.Handle, config_parse_qdisc_handle, QDISC_KIND_QFQ, 0
QuickFairQueueingClass.Parent, config_parse_tclass_parent, TCLASS_KIND_QFQ, 0
QuickFairQueueingClass.ClassId, config_parse_tclass_classid, TCLASS_KIND_QFQ, 0
QuickFairQueueingClass.Weight, config_parse_quick_fair_queueing_weight, TCLASS_KIND_QFQ, 0
QuickFairQueueingClass.MaxPacketSize, config_parse_quick_fair_queueing_max_packet, TCLASS_KIND_QFQ, 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

View File

@ -508,6 +508,9 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
"ControlledDelay\0" "ControlledDelay\0"
"DeficitRoundRobinScheduler\0" "DeficitRoundRobinScheduler\0"
"DeficitRoundRobinSchedulerClass\0" "DeficitRoundRobinSchedulerClass\0"
"PFIFO\0"
"PFIFOFast\0"
"PFIFOHeadDrop\0"
"FairQueueing\0" "FairQueueing\0"
"FairQueueingControlledDelay\0" "FairQueueingControlledDelay\0"
"GenericRandomEarlyDetection\0" "GenericRandomEarlyDetection\0"
@ -515,12 +518,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
"HierarchyTokenBucket\0" "HierarchyTokenBucket\0"
"HierarchyTokenBucketClass\0" "HierarchyTokenBucketClass\0"
"NetworkEmulator\0" "NetworkEmulator\0"
"PFIFO\0"
"PFIFOFast\0"
"PFIFOHeadDrop\0"
"PIE\0" "PIE\0"
"QuickFairQueueing\0"
"QuickFairQueueingClass\0"
"StochasticFairBlue\0" "StochasticFairBlue\0"
"StochasticFairnessQueueing\0" "StochasticFairnessQueueing\0"
"TokenBucketFilter\0" "TokenBucketFilter\0"

View File

@ -27,7 +27,6 @@ const QDiscVTable * const qdisc_vtable[_QDISC_KIND_MAX] = {
[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_PIE] = &pie_vtable,
[QDISC_KIND_QFQ] = &qfq_vtable,
[QDISC_KIND_PFIFO] = &pfifo_vtable, [QDISC_KIND_PFIFO] = &pfifo_vtable,
[QDISC_KIND_PFIFO_FAST] = &pfifo_fast_vtable, [QDISC_KIND_PFIFO_FAST] = &pfifo_fast_vtable,
[QDISC_KIND_PFIFO_HEAD_DROP] = &pfifo_head_drop_vtable, [QDISC_KIND_PFIFO_HEAD_DROP] = &pfifo_head_drop_vtable,

View File

@ -23,7 +23,6 @@ typedef enum QDiscKind {
QDISC_KIND_PFIFO_FAST, QDISC_KIND_PFIFO_FAST,
QDISC_KIND_PFIFO_HEAD_DROP, QDISC_KIND_PFIFO_HEAD_DROP,
QDISC_KIND_PIE, QDISC_KIND_PIE,
QDISC_KIND_QFQ,
QDISC_KIND_SFB, QDISC_KIND_SFB,
QDISC_KIND_SFQ, QDISC_KIND_SFQ,
QDISC_KIND_TBF, QDISC_KIND_TBF,
@ -94,7 +93,6 @@ CONFIG_PARSER_PROTOTYPE(config_parse_qdisc_handle);
#include "hhf.h" #include "hhf.h"
#include "htb.h" #include "htb.h"
#include "pie.h" #include "pie.h"
#include "qfq.h"
#include "netem.h" #include "netem.h"
#include "drr.h" #include "drr.h"
#include "sfb.h" #include "sfb.h"

View File

@ -1,170 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1+
* Copyright © 2020 VMware, Inc. */
#include <linux/pkt_sched.h>
#include "parse-util.h"
#include "qdisc.h"
#include "qfq.h"
#include "string-util.h"
#define QFQ_MAX_WEIGHT (1 << 10)
#define QFQ_MIN_MAX_PACKET 512
#define QFQ_MAX_MAX_PACKET (1 << 16)
const QDiscVTable qfq_vtable = {
.object_size = sizeof(QuickFairQueueing),
.tca_kind = "qfq",
};
static int quick_fair_queueing_class_fill_message(Link *link, TClass *tclass, sd_netlink_message *req) {
QuickFairQueueingClass *qfq;
int r;
assert(link);
assert(tclass);
assert(req);
qfq = TCLASS_TO_QFQ(tclass);
r = sd_netlink_message_open_container_union(req, TCA_OPTIONS, "qfq");
if (r < 0)
return log_link_error_errno(link, r, "Could not open container TCA_OPTIONS: %m");
if (qfq->weight > 0) {
r = sd_netlink_message_append_u32(req, TCA_QFQ_WEIGHT, qfq->weight);
if (r < 0)
return log_link_error_errno(link, r, "Could not append TCA_QFQ_WEIGHT attribute: %m");
}
if (qfq->max_packet > 0) {
r = sd_netlink_message_append_u32(req, TCA_QFQ_LMAX, qfq->max_packet);
if (r < 0)
return log_link_error_errno(link, r, "Could not append TCA_QFQ_LMAX 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_quick_fair_queueing_weight(
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;
QuickFairQueueingClass *qfq;
Network *network = data;
uint32_t v;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
r = tclass_new_static(TCLASS_KIND_QFQ, 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");
qfq = TCLASS_TO_QFQ(tclass);
if (isempty(rvalue)) {
qfq->weight = 0;
tclass = NULL;
return 0;
}
r = safe_atou32(rvalue, &v);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse '%s=', ignoring assignment: %s",
lvalue, rvalue);
return 0;
}
if (v == 0 || v > QFQ_MAX_WEIGHT) {
log_syntax(unit, LOG_ERR, filename, line, 0,
"Invalid '%s=', ignoring assignment: %s",
lvalue, rvalue);
return 0;
}
qfq->weight = v;
tclass = NULL;
return 0;
}
int config_parse_quick_fair_queueing_max_packet(
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;
QuickFairQueueingClass *qfq;
Network *network = data;
uint64_t v;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
r = tclass_new_static(TCLASS_KIND_QFQ, 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");
qfq = TCLASS_TO_QFQ(tclass);
if (isempty(rvalue)) {
qfq->max_packet = 0;
tclass = NULL;
return 0;
}
r = parse_size(rvalue, 1000, &v);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse '%s=', ignoring assignment: %s",
lvalue, rvalue);
return 0;
}
if (v < QFQ_MIN_MAX_PACKET || v > QFQ_MAX_MAX_PACKET) {
log_syntax(unit, LOG_ERR, filename, line, 0,
"Invalid '%s=', ignoring assignment: %s",
lvalue, rvalue);
return 0;
}
qfq->max_packet = (uint32_t) v;
tclass = NULL;
return 0;
}
const TClassVTable qfq_tclass_vtable = {
.object_size = sizeof(QuickFairQueueingClass),
.tca_kind = "qfq",
.fill_message = quick_fair_queueing_class_fill_message,
};

View File

@ -1,26 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1+
* Copyright © 2020 VMware, Inc. */
#pragma once
#include "conf-parser.h"
#include "qdisc.h"
typedef struct QuickFairQueueing {
QDisc meta;
} QuickFairQueueing;
DEFINE_QDISC_CAST(QFQ, QuickFairQueueing);
extern const QDiscVTable qfq_vtable;
typedef struct QuickFairQueueingClass {
TClass meta;
uint32_t weight;
uint32_t max_packet;
} QuickFairQueueingClass;
DEFINE_TCLASS_CAST(QFQ, QuickFairQueueingClass);
extern const TClassVTable qfq_tclass_vtable;
CONFIG_PARSER_PROTOTYPE(config_parse_quick_fair_queueing_weight);
CONFIG_PARSER_PROTOTYPE(config_parse_quick_fair_queueing_max_packet);

View File

@ -18,7 +18,6 @@
const TClassVTable * const tclass_vtable[_TCLASS_KIND_MAX] = { const TClassVTable * const tclass_vtable[_TCLASS_KIND_MAX] = {
[TCLASS_KIND_DRR] = &drr_tclass_vtable, [TCLASS_KIND_DRR] = &drr_tclass_vtable,
[TCLASS_KIND_HTB] = &htb_tclass_vtable, [TCLASS_KIND_HTB] = &htb_tclass_vtable,
[TCLASS_KIND_QFQ] = &qfq_tclass_vtable,
}; };
static int tclass_new(TClassKind kind, TClass **ret) { static int tclass_new(TClassKind kind, TClass **ret) {

View File

@ -11,7 +11,6 @@
typedef enum TClassKind { typedef enum TClassKind {
TCLASS_KIND_DRR, TCLASS_KIND_DRR,
TCLASS_KIND_HTB, TCLASS_KIND_HTB,
TCLASS_KIND_QFQ,
_TCLASS_KIND_MAX, _TCLASS_KIND_MAX,
_TCLASS_KIND_INVALID = -1, _TCLASS_KIND_INVALID = -1,
} TClassKind; } TClassKind;
@ -68,4 +67,3 @@ CONFIG_PARSER_PROTOTYPE(config_parse_tclass_classid);
#include "drr.h" #include "drr.h"
#include "htb.h" #include "htb.h"
#include "qfq.h"

View File

@ -101,8 +101,8 @@ typedef struct PStoreEntry {
typedef struct PStoreList { typedef struct PStoreList {
PStoreEntry *entries; PStoreEntry *entries;
size_t n_allocated;
size_t n_entries; size_t n_entries;
size_t n_entries_allocated;
} PStoreList; } PStoreList;
static void pstore_entries_reset(PStoreList *list) { static void pstore_entries_reset(PStoreList *list) {
@ -112,7 +112,8 @@ static void pstore_entries_reset(PStoreList *list) {
list->n_entries = 0; list->n_entries = 0;
} }
static int compare_pstore_entries(const PStoreEntry *a, const PStoreEntry *b) { static int compare_pstore_entries(const void *_a, const void *_b) {
PStoreEntry *a = (PStoreEntry *)_a, *b = (PStoreEntry *)_b;
return strcmp(a->dirent.d_name, b->dirent.d_name); return strcmp(a->dirent.d_name, b->dirent.d_name);
} }
@ -348,7 +349,7 @@ static int list_files(PStoreList *list, const char *sourcepath) {
continue; continue;
} }
if (!GREEDY_REALLOC(list->entries, list->n_allocated, list->n_entries + 1)) if (!GREEDY_REALLOC(list->entries, list->n_entries_allocated, list->n_entries + 1))
return log_oom(); return log_oom();
list->entries[list->n_entries++] = (PStoreEntry) { list->entries[list->n_entries++] = (PStoreEntry) {
@ -393,7 +394,7 @@ static int run(int argc, char *argv[]) {
/* Handle each pstore file */ /* Handle each pstore file */
/* Sort files lexigraphically ascending, generally needed by all */ /* Sort files lexigraphically ascending, generally needed by all */
typesafe_qsort(list.entries, list.n_entries, compare_pstore_entries); qsort_safe(list.entries, list.n_entries, sizeof(PStoreEntry), compare_pstore_entries);
/* Process known file types */ /* Process known file types */
process_dmesg_files(&list); process_dmesg_files(&list);

View File

@ -28,7 +28,6 @@
#include "resolved-def.h" #include "resolved-def.h"
#include "resolved-dns-packet.h" #include "resolved-dns-packet.h"
#include "socket-netlink.h" #include "socket-netlink.h"
#include "sort-util.h"
#include "stdio-util.h" #include "stdio-util.h"
#include "string-table.h" #include "string-table.h"
#include "strv.h" #include "strv.h"
@ -80,21 +79,6 @@ typedef enum StatusMode {
STATUS_NTA, STATUS_NTA,
} StatusMode; } StatusMode;
typedef struct InterfaceInfo {
int index;
const char *name;
} InterfaceInfo;
static int interface_info_compare(const InterfaceInfo *a, const InterfaceInfo *b) {
int r;
r = CMP(a->index, b->index);
if (r != 0)
return r;
return strcmp_ptr(a->name, b->name);
}
int ifname_mangle(const char *s) { int ifname_mangle(const char *s) {
_cleanup_free_ char *iface = NULL; _cleanup_free_ char *iface = NULL;
const char *dot; const char *dot;
@ -1516,6 +1500,10 @@ static int status_ifindex(sd_bus *bus, int ifindex, const char *name, StatusMode
if (r < 0) if (r < 0)
return r; return r;
r = dump_list(table, "DNSSEC NTA:", link_info.ntas);
if (r < 0)
return r;
r = table_print(table, NULL); r = table_print(table, NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to print table: %m"); return log_error_errno(r, "Failed to print table: %m");
@ -1757,6 +1745,11 @@ static int status_global(sd_bus *bus, StatusMode mode, bool *empty_line) {
if (r < 0) if (r < 0)
return r; return r;
strv_sort(global_info.ntas);
r = dump_list(table, "DNSSEC NTA:", global_info.ntas);
if (r < 0)
return r;
r = table_print(table, NULL); r = table_print(table, NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to print table: %m"); return log_error_errno(r, "Failed to print table: %m");
@ -1769,6 +1762,7 @@ static int status_global(sd_bus *bus, StatusMode mode, bool *empty_line) {
static int status_all(sd_bus *bus, StatusMode mode) { static int status_all(sd_bus *bus, StatusMode mode) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL; _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
sd_netlink_message *i;
bool empty_line = false; bool empty_line = false;
int r; int r;
@ -1794,43 +1788,31 @@ static int status_all(sd_bus *bus, StatusMode mode) {
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to enumerate links: %m"); return log_error_errno(r, "Failed to enumerate links: %m");
_cleanup_free_ InterfaceInfo *infos = NULL; r = 0;
size_t n_allocated = 0, n_infos = 0; for (i = reply; i; i = sd_netlink_message_next(i)) {
for (sd_netlink_message *i = reply; i; i = sd_netlink_message_next(i)) {
const char *name; const char *name;
int ifindex; int ifindex, q;
uint16_t type; uint16_t type;
r = sd_netlink_message_get_type(i, &type); q = sd_netlink_message_get_type(i, &type);
if (r < 0) if (q < 0)
return rtnl_log_parse_error(r); return rtnl_log_parse_error(q);
if (type != RTM_NEWLINK) if (type != RTM_NEWLINK)
continue; continue;
r = sd_rtnl_message_link_get_ifindex(i, &ifindex); q = sd_rtnl_message_link_get_ifindex(i, &ifindex);
if (r < 0) if (q < 0)
return rtnl_log_parse_error(r); return rtnl_log_parse_error(q);
if (ifindex == LOOPBACK_IFINDEX) if (ifindex == LOOPBACK_IFINDEX)
continue; continue;
r = sd_netlink_message_read_string(i, IFLA_IFNAME, &name); q = sd_netlink_message_read_string(i, IFLA_IFNAME, &name);
if (r < 0) if (q < 0)
return rtnl_log_parse_error(r); return rtnl_log_parse_error(q);
if (!GREEDY_REALLOC(infos, n_allocated, n_infos + 1)) q = status_ifindex(bus, ifindex, name, mode, &empty_line);
return log_oom();
infos[n_infos++] = (InterfaceInfo) { ifindex, name };
}
typesafe_qsort(infos, n_infos, interface_info_compare);
r = 0;
for (size_t i = 0; i < n_infos; i++) {
int q = status_ifindex(bus, infos[i].index, infos[i].name, mode, &empty_line);
if (q < 0 && r >= 0) if (q < 0 && r >= 0)
r = q; r = q;
} }
@ -3060,7 +3042,7 @@ static int native_main(int argc, char *argv[], sd_bus *bus) {
static int translate(const char *verb, const char *single_arg, size_t num_args, char **args, sd_bus *bus) { static int translate(const char *verb, const char *single_arg, size_t num_args, char **args, sd_bus *bus) {
char **fake, **p; char **fake, **p;
size_t num; size_t num, i;
assert(verb); assert(verb);
assert(num_args == 0 || args); assert(num_args == 0 || args);
@ -3071,7 +3053,7 @@ static int translate(const char *verb, const char *single_arg, size_t num_args,
*p++ = (char *) verb; *p++ = (char *) verb;
if (single_arg) if (single_arg)
*p++ = (char *) single_arg; *p++ = (char *) single_arg;
for (size_t i = 0; i < num_args; i++) for (i = 0; i < num_args; i++)
*p++ = args[i]; *p++ = args[i];
optind = 0; optind = 0;

View File

@ -322,17 +322,28 @@ static bool install_client_side(void) {
} }
static int compare_unit_info(const UnitInfo *a, const UnitInfo *b) { static int compare_unit_info(const UnitInfo *a, const UnitInfo *b) {
const char *d1, *d2;
int r; int r;
/* First, order by machine */ /* First, order by machine */
r = strcasecmp_ptr(a->machine, b->machine); if (!a->machine && b->machine)
if (r != 0) return -1;
return r; if (a->machine && !b->machine)
return 1;
if (a->machine && b->machine) {
r = strcasecmp(a->machine, b->machine);
if (r != 0)
return r;
}
/* Second, order by unit type */ /* Second, order by unit type */
r = strcasecmp_ptr(strrchr(a->id, '.'), strrchr(b->id, '.')); d1 = strrchr(a->id, '.');
if (r != 0) d2 = strrchr(b->id, '.');
return r; if (d1 && d2) {
r = strcasecmp(d1, d2);
if (r != 0)
return r;
}
/* Third, order by name */ /* Third, order by name */
return strcasecmp(a->id, b->id); return strcasecmp(a->id, b->id);
@ -397,6 +408,8 @@ static int output_table(Table *table) {
static int output_units_list(const UnitInfo *unit_infos, unsigned c) { static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
_cleanup_(table_unrefp) Table *table = NULL; _cleanup_(table_unrefp) Table *table = NULL;
const UnitInfo *u;
int job_count = 0;
int r; int r;
table = table_new("", "unit", "load", "active", "sub", "job", "description"); table = table_new("", "unit", "load", "active", "sub", "job", "description");
@ -415,8 +428,7 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
(void) table_set_empty_string(table, "-"); (void) table_set_empty_string(table, "-");
int job_count = 0; for (u = unit_infos; unit_infos && u < unit_infos + c; u++) {
for (const UnitInfo *u = unit_infos; unit_infos && u < unit_infos + c; u++) {
_cleanup_free_ char *j = NULL; _cleanup_free_ char *j = NULL;
const char *on_underline = "", *on_loaded = "", *on_active = ""; const char *on_underline = "", *on_loaded = "", *on_active = "";
const char *on_circle = "", *id; const char *on_circle = "", *id;
@ -963,15 +975,21 @@ static int socket_info_compare(const struct socket_info *a, const struct socket_
assert(a); assert(a);
assert(b); assert(b);
r = strcasecmp_ptr(a->machine, b->machine); if (!a->machine && b->machine)
if (r != 0) return -1;
return r; if (a->machine && !b->machine)
return 1;
if (a->machine && b->machine) {
r = strcasecmp(a->machine, b->machine);
if (r != 0)
return r;
}
r = strcmp(a->path, b->path); r = strcmp(a->path, b->path);
if (r != 0) if (r == 0)
return r; r = strcmp(a->type, b->type);
return strcmp(a->type, b->type); return r;
} }
static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) { static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
@ -1216,9 +1234,15 @@ static int timer_info_compare(const struct timer_info *a, const struct timer_inf
assert(a); assert(a);
assert(b); assert(b);
r = strcasecmp_ptr(a->machine, b->machine); if (!a->machine && b->machine)
if (r != 0) return -1;
return r; if (a->machine && !b->machine)
return 1;
if (a->machine && b->machine) {
r = strcasecmp(a->machine, b->machine);
if (r != 0)
return r;
}
r = CMP(a->next_elapse, b->next_elapse); r = CMP(a->next_elapse, b->next_elapse);
if (r != 0) if (r != 0)

View File

@ -411,14 +411,6 @@ PacketLimit=
Parent= Parent=
Handle= Handle=
PacketLimit= PacketLimit=
[QuickFairQueueing]
Parent=
Handle=
[QuickFairQueueingClass]
Parent=
ClassId=
Weight=
MaxPacketSize=
[DeficitRoundRobinScheduler] [DeficitRoundRobinScheduler]
Parent= Parent=
Handle= Handle=

View File

@ -1,22 +0,0 @@
[Match]
Name=test1
[Network]
IPv6AcceptRA=no
Address=10.1.2.4/16
[QuickFairQueueing]
Parent=root
Handle=0002
[QuickFairQueueingClass]
Parent=root
ClassId=0002:0030
Weight=2
MaxPacketSize=16000
[QuickFairQueueingClass]
Parent=root
ClassId=0002:0031
Weight=10
MaxPacketSize=8000

View File

@ -1676,7 +1676,6 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
'25-qdisc-hhf.network', '25-qdisc-hhf.network',
'25-qdisc-ingress-netem-compat.network', '25-qdisc-ingress-netem-compat.network',
'25-qdisc-pie.network', '25-qdisc-pie.network',
'25-qdisc-qfq.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',
@ -2424,11 +2423,10 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
self.assertRegex(output, 'prio 1 rate 1Mbit ceil 500Kbit') self.assertRegex(output, 'prio 1 rate 1Mbit ceil 500Kbit')
def test_qdisc2(self): def test_qdisc2(self):
copy_unit_to_networkd_unit_path('25-qdisc-drr.network', '12-dummy.netdev', copy_unit_to_networkd_unit_path('25-qdisc-drr.network', '12-dummy.netdev')
'25-qdisc-qfq.network', '11-dummy.netdev')
start_networkd() start_networkd()
self.wait_online(['dummy98:routable', 'test1:routable']) self.wait_online(['dummy98:routable'])
output = check_output('tc qdisc show dev dummy98') output = check_output('tc qdisc show dev dummy98')
print(output) print(output)
@ -2437,14 +2435,6 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
print(output) print(output)
self.assertRegex(output, 'class drr 2:30 root quantum 2000b') self.assertRegex(output, 'class drr 2:30 root quantum 2000b')
output = check_output('tc qdisc show dev test1')
print(output)
self.assertRegex(output, 'qdisc qfq 2: root')
output = check_output('tc class show dev test1')
print(output)
self.assertRegex(output, 'class qfq 2:30 root weight 2 maxpkt 16000')
self.assertRegex(output, 'class qfq 2:31 root weight 10 maxpkt 8000')
@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')