Compare commits

...

15 Commits

Author SHA1 Message Date
Yu Watanabe 2e3fa22ef3
Merge pull request #14303 from yuwata/tc-use-typesafe-functions
network: tc: use typesafe functions
2019-12-11 20:07:20 +09:00
Lennart Poettering b65cb5cb7a
Merge pull request #14306 from poettering/markdown-category
beef up systemd.io pages with simple categorization
2019-12-11 11:43:31 +01:00
Lennart Poettering 5d3f5e4081 docs: beef up entrypoint documentation page
Let's use the rough categorization of the markdown pages to add basic
sections, via Jeykll templating. Also, add in a couple of additional
links via a JSON array that lists them.

So much web development, so much wow!
2019-12-11 10:53:14 +01:00
Lennart Poettering 4cdca0af11 docs: place all our markdown docs in rough categories 2019-12-11 10:53:00 +01:00
cheese1 f32d15b0e4 man: fix typos (#14304) 2019-12-11 18:33:13 +09:00
Yu Watanabe 92c7593f5e network: tc: use typesafe functions to append netlink attributes 2019-12-11 16:31:52 +09:00
Yu Watanabe 42b5f7dd32 sd-netlink: make TCA_OPTIONS take NETLINK_TYPE_UNION 2019-12-11 16:30:39 +09:00
Yu Watanabe d8e897d345
Merge pull request #14278 from ssahani/tc
network tc: qdisc parent add support to set ingress
2019-12-11 13:27:14 +09:00
Yu Watanabe 8fb3bda83c
Merge pull request #14297 from poettering/id128-size
cleaning up id128 formatting buffer sizing
2019-12-11 13:26:51 +09:00
AJ Bagwell e92b60b20f ipv4ll: do not reset conflict counter on restart
Don't reset the conflict counter when trying a new pseudo random
address, so that after trying 10 addresses the londer timeout is used in
accordance with the RFC

Fixes #14299.
2019-12-11 13:26:31 +09:00
Yu Watanabe 40821c2ac3 test-network: add a test case for fq-codel 2019-12-11 00:06:31 +09:00
Susant Sahani 4e5ef14919 network tc: Add support to conkfigure CoDel - Controlled-Delay Active Queue Management algorithm
```
$ tc qdisc show dev dummy99
qdisc fq_codel 8005: dev dummy99 root refcnt 2 limit 1000p flows 1024 quantum 1514 target 5.0ms interval 100.0ms memory_limit 32Mb ecn
$ network cat dumm99.network
[Match]
Name=dummy99

[TrafficControlQueueingDiscipline]
Parent=root
FairQueuingControlledDelayPacketLimit=1000

```
2019-12-11 00:06:31 +09:00
Susant Sahani d808102008 network tc: qdisc parent add support to set ingress
```
$ network tc qdisc
qdisc noqueue 0: dev dummy99 root refcnt 2
qdisc ingress ffff: dev dummy99 parent ffff:fff1 ----------------

$ network cat dumm99.network
[Match]
Name=dummy99

[TrafficControlQueueingDiscipline]
Parent=ingress
```
2019-12-11 00:06:31 +09:00
Lennart Poettering 5905d7cf5b tree-wide: use SD_ID128_STRING_MAX where appropriate 2019-12-10 11:56:18 +01:00
Lennart Poettering b5ea030d65 id128: introduce ID128_UUID_STRING_MAX for sizing UUID buffers 2019-12-10 11:56:18 +01:00
55 changed files with 297 additions and 55 deletions

View File

@ -1,5 +1,6 @@
--- ---
title: Automatic Boot Assessment title: Automatic Boot Assessment
category: Booting
--- ---
# Automatic Boot Assessment # Automatic Boot Assessment

View File

@ -1,5 +1,6 @@
--- ---
title: Locking Block Device Access title: Locking Block Device Access
category: Interfaces
--- ---
# Locking Block Device Access # Locking Block Device Access

View File

@ -1,5 +1,6 @@
--- ---
title: The Boot Loader Interface title: The Boot Loader Interface
category: Booting
--- ---
# The Boot Loader Interface # The Boot Loader Interface

View File

@ -1,5 +1,6 @@
--- ---
title: The Boot Loader Specification title: The Boot Loader Specification
category: Booting
--- ---
# The Boot Loader Specification # The Boot Loader Specification

View File

@ -1,5 +1,6 @@
--- ---
title: Control Group APIs and Delegation title: Control Group APIs and Delegation
category: Interfaces
--- ---
# Control Group APIs and Delegation # Control Group APIs and Delegation

View File

@ -1,5 +1,6 @@
--- ---
title: The systemd Community Conduct Guidelines title: The systemd Community Conduct Guidelines
category: Contributing
--- ---
# The systemd Community Conduct Guidelines # The systemd Community Conduct Guidelines

View File

@ -1,5 +1,6 @@
--- ---
title: Code Quality Tools title: Code Quality Tools
category: Contributing
--- ---
# Code Quality Tools # Code Quality Tools

View File

@ -1,5 +1,6 @@
--- ---
title: Coding Style title: Coding Style
category: Contributing
--- ---
# Coding Style # Coding Style

View File

@ -1,5 +1,6 @@
--- ---
title: Contributing title: Contributing
category: Contributing
--- ---
# Contributing # Contributing

View File

@ -1,5 +1,6 @@
--- ---
title: Porting systemd To New Distributions title: Porting systemd To New Distributions
category: Concepts
--- ---
# Porting systemd To New Distributions # Porting systemd To New Distributions

View File

@ -1,5 +1,6 @@
--- ---
title: Known Environment Variables title: Known Environment Variables
category: Interfaces
--- ---
# Known Environment Variables # Known Environment Variables

View File

@ -1,5 +1,6 @@
--- ---
title: Hacking on systemd title: Hacking on systemd
category: Contributing
--- ---
# Hacking on systemd # Hacking on systemd

View File

@ -1,5 +1,6 @@
--- ---
title: Portable Services Introduction title: Portable Services Introduction
category: Concepts
--- ---
# Portable Services Introduction # Portable Services Introduction

View File

@ -1,5 +1,6 @@
--- ---
title: Predictable Network Interface Names title: Predictable Network Interface Names
category: Concepts
--- ---
# Predictable Network Interface Names # Predictable Network Interface Names

View File

@ -1,5 +1,6 @@
--- ---
title: Random Seeds title: Random Seeds
category: Concepts
--- ---
# Random Seeds # Random Seeds

View File

@ -1,5 +1,6 @@
--- ---
title: Steps to a Successful Release title: Steps to a Successful Release
category: Contributing
--- ---
# Steps to a Successful Release # Steps to a Successful Release

View File

@ -1,5 +1,6 @@
--- ---
title: Reporting of security vulnerabilities title: Reporting of security vulnerabilities
category: Contributing
--- ---
# Reporting of security vulnerabilities # Reporting of security vulnerabilities

View File

@ -1,5 +1,6 @@
--- ---
title: Using /tmp/ And /var/tmp/ Safely title: Using /tmp/ And /var/tmp/ Safely
category: Interfaces
--- ---
# Using `/tmp/` And `/var/tmp/` Safely # Using `/tmp/` And `/var/tmp/` Safely

View File

@ -1,5 +1,6 @@
--- ---
title: Testing systemd using sanitizers title: Testing systemd using sanitizers
category: Contributing
--- ---
# Testing systemd using sanitizers # Testing systemd using sanitizers

View File

@ -1,5 +1,6 @@
--- ---
title: What settings are currently available for transient units? title: What settings are currently available for transient units?
category: Interfaces
--- ---
# What settings are currently available for transient units? # What settings are currently available for transient units?

View File

@ -1,5 +1,6 @@
--- ---
title: Notes for Translators title: Notes for Translators
category: Contributing
--- ---
# Notes for Translators # Notes for Translators

View File

@ -1,5 +1,6 @@
--- ---
title: Users, Groups, UIDs and GIDs on `systemd` Systems title: Users, Groups, UIDs and GIDs on `systemd` Systems
category: Concepts
--- ---
# Users, Groups, UIDs and GIDs on `systemd` Systems # Users, Groups, UIDs and GIDs on `systemd` Systems

View File

@ -0,0 +1,10 @@
[
{ "category": "Project", "title": "Brand", "url": "https://brand.systemd.io/" },
{ "category": "Project", "title": "Releases", "url": "https://github.com/systemd/systemd/releases" },
{ "category": "Project", "title": "GitHub Project Page", "url": "https://github.com/systemd/systemd" },
{ "category": "Project", "title": "Issues", "url": "https://github.com/systemd/systemd/issues" },
{ "category": "Project", "title": "Pull Requests", "url": "https://github.com/systemd/systemd/pulls" },
{ "category": "Project", "title": "Mailing List", "url": "https://lists.freedesktop.org/mailman/listinfo/systemd-devel" },
{ "category": "Manual Pages", "title": "Index", "url": "https://www.freedesktop.org/software/systemd/man/" },
{ "category": "Manual Pages", "title": "Directives", "url": "https://www.freedesktop.org/software/systemd/man/systemd.directives.html" }
]

View File

@ -4,8 +4,14 @@ title: systemd Documentation
# systemd Documentation # systemd Documentation
{% for p in site.pages %} {% assign by_category = site.pages | group_by:"category" %}
{% if p.url != page.url and p.title %} {% assign extra_pages = site.data.extra_pages | group_by:"category" %}
* [{{ p.title }}]({{ p.url | relative_url }}) {% assign merged = by_category | concat: extra_pages | sort:"name" %}
{% for pair in merged %}
{% if pair.name != "" %}
## {{ pair.name }}
{% assign sorted = pair.items | sort:"title" %}{% for page in sorted %}
* [{{ page.title }}]({{ page.url | relative_url }}){% endfor %}
{% endif %} {% endif %}
{% endfor %} {% endfor %}

View File

@ -199,7 +199,7 @@
</row> </row>
<row> <row>
<entry><option>enabled-runtime</option></entry> <entry><option>enabled-runtime</option></entry>
<entry>Like <option>enabled</option>, but the the unit files have been made available transiently only, i.e. the <command>attach</command> command has been invoked with the <option>--runtime</option> option.</entry> <entry>Like <option>enabled</option>, but the unit files have been made available transiently only, i.e. the <command>attach</command> command has been invoked with the <option>--runtime</option> option.</entry>
</row> </row>
<row> <row>
<entry><option>running</option></entry> <entry><option>running</option></entry>

View File

@ -60,7 +60,7 @@
</para> </para>
<para>Any access permission errors and attempts to write variables not defined on the local system are <para>Any access permission errors and attempts to write variables not defined on the local system are
logged, but do not cause the the service to fail. Moreover, if a variable assignment is prefixed with a logged, but do not cause the service to fail. Moreover, if a variable assignment is prefixed with a
single <literal>-</literal> character, failure to set the variable will be logged, but will not cause the single <literal>-</literal> character, failure to set the variable will be logged, but will not cause the
service to fail. All other errors when setting variables cause the service to return failure at the end service to fail. All other errors when setting variables cause the service to return failure at the end
(other variables are still processed).</para> (other variables are still processed).</para>

View File

@ -2327,8 +2327,8 @@
<varlistentry> <varlistentry>
<term><varname>Parent=</varname></term> <term><varname>Parent=</varname></term>
<listitem> <listitem>
<para>Specifies the parent Queueing Discipline (qdisc). Takes one of <literal>root</literal> <para>Specifies the parent Queueing Discipline (qdisc). Takes one of <literal>root</literal>,
or <literal>clsact</literal>. Defaults to <literal>root</literal>.</para> <literal>clsact</literal> or <literal>ingress</literal>. Defaults to <literal>root</literal>.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -2442,6 +2442,14 @@
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>FairQueuingControlledDelayPacketLimit=</varname></term>
<listitem>
<para>Specifies the hard limit on the real queue size. When this limit is reached, incoming packets are
dropped. Defaults to unset and kernel's default is used.</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>

View File

@ -859,7 +859,7 @@
effect.</para> effect.</para>
<example> <example>
<title>A service with with the the <varname>SuccessExitStatus=</varname> setting</title> <title>A service with with the <varname>SuccessExitStatus=</varname> setting</title>
<programlisting>SuccessExitStatus=TEMPFAIL 250 SIGUSR1</programlisting> <programlisting>SuccessExitStatus=TEMPFAIL 250 SIGUSR1</programlisting>

View File

@ -103,7 +103,7 @@ static ssize_t write_entry(char *buf, size_t size, Uploader *u) {
_fallthrough_; _fallthrough_;
case ENTRY_BOOT_ID: { case ENTRY_BOOT_ID: {
sd_id128_t boot_id; sd_id128_t boot_id;
char sid[33]; char sid[SD_ID128_STRING_MAX];
r = sd_journal_get_monotonic_usec(u->journal, NULL, &boot_id); r = sd_journal_get_monotonic_usec(u->journal, NULL, &boot_id);
if (r < 0) if (r < 0)

View File

@ -3056,7 +3056,7 @@ static const char* format_timestamp_safe(char *buf, size_t l, usec_t t) {
} }
void journal_file_print_header(JournalFile *f) { void journal_file_print_header(JournalFile *f) {
char a[33], b[33], c[33], d[33]; char a[SD_ID128_STRING_MAX], b[SD_ID128_STRING_MAX], c[SD_ID128_STRING_MAX], d[SD_ID128_STRING_MAX];
char x[FORMAT_TIMESTAMP_MAX], y[FORMAT_TIMESTAMP_MAX], z[FORMAT_TIMESTAMP_MAX]; char x[FORMAT_TIMESTAMP_MAX], y[FORMAT_TIMESTAMP_MAX], z[FORMAT_TIMESTAMP_MAX];
struct stat st; struct stat st;
char bytes[FORMAT_BYTES_MAX]; char bytes[FORMAT_BYTES_MAX];

View File

@ -908,7 +908,7 @@ _public_ int sd_journal_previous_skip(sd_journal *j, uint64_t skip) {
_public_ int sd_journal_get_cursor(sd_journal *j, char **cursor) { _public_ int sd_journal_get_cursor(sd_journal *j, char **cursor) {
Object *o; Object *o;
int r; int r;
char bid[33], sid[33]; char bid[SD_ID128_STRING_MAX], sid[SD_ID128_STRING_MAX];
assert_return(j, -EINVAL); assert_return(j, -EINVAL);
assert_return(!journal_pid_changed(j), -ECHILD); assert_return(!journal_pid_changed(j), -ECHILD);

View File

@ -441,7 +441,7 @@ int sd_ipv4acd_is_running(sd_ipv4acd *acd) {
return acd->state != IPV4ACD_STATE_INIT; return acd->state != IPV4ACD_STATE_INIT;
} }
int sd_ipv4acd_start(sd_ipv4acd *acd) { int sd_ipv4acd_start(sd_ipv4acd *acd, bool reset_conflicts) {
int r; int r;
assert_return(acd, -EINVAL); assert_return(acd, -EINVAL);
@ -458,6 +458,8 @@ int sd_ipv4acd_start(sd_ipv4acd *acd) {
safe_close(acd->fd); safe_close(acd->fd);
acd->fd = r; acd->fd = r;
acd->defend_window = 0; acd->defend_window = 0;
if (reset_conflicts)
acd->n_conflict = 0; acd->n_conflict = 0;
r = sd_event_add_io(acd->event, &acd->receive_message_event_source, acd->fd, EPOLLIN, ipv4acd_on_packet, acd); r = sd_event_add_io(acd->event, &acd->receive_message_event_source, acd->fd, EPOLLIN, ipv4acd_on_packet, acd);

View File

@ -241,7 +241,7 @@ static int ipv4ll_start_internal(sd_ipv4ll *ll, bool reset_generation) {
picked_address = true; picked_address = true;
} }
r = sd_ipv4acd_start(ll->acd); r = sd_ipv4acd_start(ll->acd, reset_generation);
if (r < 0) { if (r < 0) {
/* We couldn't start? If so, let's forget the picked address again, the user might make a change and /* We couldn't start? If so, let's forget the picked address again, the user might make a change and

View File

@ -47,7 +47,7 @@ static int client_run(int ifindex, const struct in_addr *pa, const struct ether_
log_info("starting IPv4ACD client"); log_info("starting IPv4ACD client");
assert_se(sd_ipv4acd_start(acd) >= 0); assert_se(sd_ipv4acd_start(acd, true) >= 0);
assert_se(sd_event_loop(e) >= 0); assert_se(sd_event_loop(e) >= 0);

View File

@ -2672,7 +2672,7 @@ static int process_builtin(sd_bus *bus, sd_bus_message *m) {
r = sd_bus_message_new_method_return(m, &reply); r = sd_bus_message_new_method_return(m, &reply);
else if (streq_ptr(m->member, "GetMachineId")) { else if (streq_ptr(m->member, "GetMachineId")) {
sd_id128_t id; sd_id128_t id;
char sid[33]; char sid[SD_ID128_STRING_MAX];
r = sd_id128_get_machine(&id); r = sd_id128_get_machine(&id);
if (r < 0) if (r < 0)

View File

@ -11,7 +11,7 @@
#include "io-util.h" #include "io-util.h"
#include "stdio-util.h" #include "stdio-util.h"
char *id128_to_uuid_string(sd_id128_t id, char s[37]) { char *id128_to_uuid_string(sd_id128_t id, char s[static ID128_UUID_STRING_MAX]) {
unsigned n, k = 0; unsigned n, k = 0;
assert(s); assert(s);

View File

@ -8,7 +8,9 @@
#include "hash-funcs.h" #include "hash-funcs.h"
#include "macro.h" #include "macro.h"
char *id128_to_uuid_string(sd_id128_t id, char s[37]); #define ID128_UUID_STRING_MAX 37
char *id128_to_uuid_string(sd_id128_t id, char s[static ID128_UUID_STRING_MAX]);
bool id128_is_valid(const char *s) _pure_; bool id128_is_valid(const char *s) _pure_;

View File

@ -439,7 +439,7 @@ static const NLTypeSystemUnion rtnl_link_info_data_type_system_union = {
static const NLType rtnl_link_info_types[] = { static const NLType rtnl_link_info_types[] = {
[IFLA_INFO_KIND] = { .type = NETLINK_TYPE_STRING }, [IFLA_INFO_KIND] = { .type = NETLINK_TYPE_STRING },
[IFLA_INFO_DATA] = { .type = NETLINK_TYPE_UNION, .type_system_union = &rtnl_link_info_data_type_system_union}, [IFLA_INFO_DATA] = { .type = NETLINK_TYPE_UNION, .type_system_union = &rtnl_link_info_data_type_system_union },
/* /*
[IFLA_INFO_XSTATS], [IFLA_INFO_XSTATS],
[IFLA_INFO_SLAVE_KIND] = { .type = NETLINK_TYPE_STRING }, [IFLA_INFO_SLAVE_KIND] = { .type = NETLINK_TYPE_STRING },
@ -734,9 +734,53 @@ static const NLTypeSystem rtnl_nexthop_type_system = {
.types = rtnl_nexthop_types, .types = rtnl_nexthop_types,
}; };
static const NLType rtnl_tca_option_data_tbf_types[] = {
[TCA_TBF_PARMS] = { .size = sizeof(struct tc_tbf_qopt) },
[TCA_TBF_RTAB] = { .size = TC_RTAB_SIZE },
[TCA_TBF_PTAB] = { .size = TC_RTAB_SIZE },
[TCA_TBF_RATE64] = { .type = NETLINK_TYPE_U64 },
[TCA_TBF_PRATE64] = { .type = NETLINK_TYPE_U64 },
[TCA_TBF_BURST] = { .type = NETLINK_TYPE_U32 },
[TCA_TBF_PBURST] = { .type = NETLINK_TYPE_U32 },
};
static const NLType rtnl_tca_option_data_fq_codel_types[] = {
[TCA_FQ_CODEL_TARGET] = { .type = NETLINK_TYPE_U32 },
[TCA_FQ_CODEL_LIMIT] = { .type = NETLINK_TYPE_U32 },
[TCA_FQ_CODEL_INTERVAL] = { .type = NETLINK_TYPE_U32 },
[TCA_FQ_CODEL_ECN] = { .type = NETLINK_TYPE_U32 },
[TCA_FQ_CODEL_FLOWS] = { .type = NETLINK_TYPE_U32 },
[TCA_FQ_CODEL_QUANTUM] = { .type = NETLINK_TYPE_U32 },
[TCA_FQ_CODEL_CE_THRESHOLD] = { .type = NETLINK_TYPE_U32 },
[TCA_FQ_CODEL_DROP_BATCH_SIZE] = { .type = NETLINK_TYPE_U32 },
[TCA_FQ_CODEL_MEMORY_LIMIT] = { .type = NETLINK_TYPE_U32 },
};
static const char* const nl_union_tca_option_data_table[] = {
[NL_UNION_TCA_OPTION_DATA_TBF] = "tbf",
[NL_UNION_TCA_OPTION_DATA_FQ_CODEL] = "fq_codel",
};
DEFINE_STRING_TABLE_LOOKUP(nl_union_tca_option_data, NLUnionTCAOptionData);
static const NLTypeSystem rtnl_tca_option_data_type_systems[] = {
[NL_UNION_TCA_OPTION_DATA_TBF] = { .count = ELEMENTSOF(rtnl_tca_option_data_tbf_types),
.types = rtnl_tca_option_data_tbf_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 },
};
static const NLTypeSystemUnion rtnl_tca_option_data_type_system_union = {
.num = _NL_UNION_TCA_OPTION_DATA_MAX,
.lookup = nl_union_tca_option_data_from_string,
.type_systems = rtnl_tca_option_data_type_systems,
.match_type = NL_MATCH_SIBLING,
.match = TCA_KIND,
};
static const NLType rtnl_qdisc_types[] = { static const NLType rtnl_qdisc_types[] = {
[TCA_KIND] = { .type = NETLINK_TYPE_STRING }, [TCA_KIND] = { .type = NETLINK_TYPE_STRING },
[TCA_OPTIONS] = { .size = sizeof(struct tc_netem_qopt) }, [TCA_OPTIONS] = { .type = NETLINK_TYPE_UNION, .type_system_union = &rtnl_tca_option_data_type_system_union },
[TCA_INGRESS_BLOCK] = { .type = NETLINK_TYPE_U32 }, [TCA_INGRESS_BLOCK] = { .type = NETLINK_TYPE_U32 },
[TCA_EGRESS_BLOCK] = { .type = NETLINK_TYPE_U32 }, [TCA_EGRESS_BLOCK] = { .type = NETLINK_TYPE_U32 },
}; };

View File

@ -90,3 +90,13 @@ typedef enum NLUnionLinkInfoData {
const char *nl_union_link_info_data_to_string(NLUnionLinkInfoData p) _const_; const char *nl_union_link_info_data_to_string(NLUnionLinkInfoData p) _const_;
NLUnionLinkInfoData nl_union_link_info_data_from_string(const char *p) _pure_; NLUnionLinkInfoData nl_union_link_info_data_from_string(const char *p) _pure_;
typedef enum NLUnionTCAOptionData {
NL_UNION_TCA_OPTION_DATA_TBF,
NL_UNION_TCA_OPTION_DATA_FQ_CODEL,
_NL_UNION_TCA_OPTION_DATA_MAX,
_NL_UNION_TCA_OPTION_DATA_INVALID = -1,
} NLUnionTCAOptionData;
const char *nl_union_tca_option_data_to_string(NLUnionTCAOptionData p) _const_;
NLUnionTCAOptionData nl_union_tca_option_data_from_string(const char *p) _pure_;

View File

@ -107,6 +107,8 @@ sources = files('''
networkd-util.h networkd-util.h
networkd-wifi.c networkd-wifi.c
networkd-wifi.h networkd-wifi.h
tc/fq-codel.c
tc/fq-codel.h
tc/netem.c tc/netem.c
tc/netem.h tc/netem.h
tc/qdisc.c tc/qdisc.c

View File

@ -670,7 +670,7 @@ int address_configure(
log_debug("Starting IPv4ACD client. Probing address %s", strna(pretty)); log_debug("Starting IPv4ACD client. Probing address %s", strna(pretty));
} }
r = sd_ipv4acd_start(address->acd); r = sd_ipv4acd_start(address->acd, true);
if (r < 0) if (r < 0)
log_link_warning_errno(link, r, "Failed to start IPv4ACD client, ignoring: %m"); log_link_warning_errno(link, r, "Failed to start IPv4ACD client, ignoring: %m");
} }

View File

@ -258,6 +258,7 @@ TrafficControlQueueingDiscipline.TokenBufferFilterMPUBytes, con
TrafficControlQueueingDiscipline.TokenBufferFilterPeakRate, config_parse_tc_token_buffer_filter_size, 0, 0 TrafficControlQueueingDiscipline.TokenBufferFilterPeakRate, config_parse_tc_token_buffer_filter_size, 0, 0
TrafficControlQueueingDiscipline.TokenBufferFilterLatencySec, config_parse_tc_token_buffer_filter_latency, 0, 0 TrafficControlQueueingDiscipline.TokenBufferFilterLatencySec, config_parse_tc_token_buffer_filter_latency, 0, 0
TrafficControlQueueingDiscipline.StochasticFairnessQueueingPerturbPeriodSec, config_parse_tc_stochastic_fairness_queueing_perturb_period, 0, 0 TrafficControlQueueingDiscipline.StochasticFairnessQueueingPerturbPeriodSec, config_parse_tc_stochastic_fairness_queueing_perturb_period, 0, 0
TrafficControlQueueingDiscipline.FairQueuingControlledDelayPacketLimit, config_parse_tc_fair_queuing_controlled_delay_limit, 0, 0
/* backwards compatibility: do not add new entries to this section */ /* backwards compatibility: do not add new entries to this section */
Network.IPv4LL, config_parse_ipv4ll, 0, offsetof(Network, link_local) Network.IPv4LL, config_parse_ipv4ll, 0, offsetof(Network, link_local)
DHCP.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier) DHCP.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier)

91
src/network/tc/fq-codel.c Normal file
View File

@ -0,0 +1,91 @@
/* SPDX-License-Identifier: LGPL-2.1+
* Copyright © 2019 VMware, Inc. */
#include <linux/pkt_sched.h>
#include "alloc-util.h"
#include "conf-parser.h"
#include "netlink-util.h"
#include "parse-util.h"
#include "qdisc.h"
#include "string-util.h"
int fair_queuing_controlled_delay_new(FairQueuingControlledDelay **ret) {
FairQueuingControlledDelay *fqcd = NULL;
fqcd = new0(FairQueuingControlledDelay, 1);
if (!fqcd)
return -ENOMEM;
*ret = TAKE_PTR(fqcd);
return 0;
}
int fair_queuing_controlled_delay_fill_message(Link *link, const FairQueuingControlledDelay *fqcd, sd_netlink_message *req) {
int r;
assert(link);
assert(fqcd);
assert(req);
r = sd_netlink_message_open_container_union(req, TCA_OPTIONS, "fq_codel");
if (r < 0)
return log_link_error_errno(link, r, "Could not open container TCA_OPTIONS: %m");
r = sd_netlink_message_append_u32(req, TCA_FQ_CODEL_LIMIT, fqcd->limit);
if (r < 0)
return log_link_error_errno(link, r, "Could not append TCA_FQ_CODEL_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_tc_fair_queuing_controlled_delay_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;
Network *network = data;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
r = qdisc_new_static(network, filename, section_line, &qdisc);
if (r < 0)
return r;
if (isempty(rvalue)) {
qdisc->fq_codel.limit = 0;
qdisc = NULL;
return 0;
}
r = safe_atou32(rvalue, &qdisc->fq_codel.limit);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse '%s=', ignoring assignment: %s",
lvalue, rvalue);
return 0;
}
qdisc->has_fair_queuing_controlled_delay = true;
qdisc = NULL;
return 0;
}

17
src/network/tc/fq-codel.h Normal file
View File

@ -0,0 +1,17 @@
/* SPDX-License-Identifier: LGPL-2.1+
* Copyright © 2019 VMware, Inc. */
#pragma once
#include "sd-netlink.h"
#include "conf-parser.h"
#include "networkd-link.h"
typedef struct FairQueuingControlledDelay {
uint32_t limit;
} FairQueuingControlledDelay;
int fair_queuing_controlled_delay_new(FairQueuingControlledDelay **ret);
int fair_queuing_controlled_delay_fill_message(Link *link, const FairQueuingControlledDelay *sfq, sd_netlink_message *req);
CONFIG_PARSER_PROTOTYPE(config_parse_tc_fair_queuing_controlled_delay_limit);

View File

@ -84,6 +84,7 @@ void qdisc_free(QDisc *qdisc) {
network_config_section_free(qdisc->section); network_config_section_free(qdisc->section);
free(qdisc->tca_kind);
free(qdisc); free(qdisc);
} }
@ -116,6 +117,7 @@ static int qdisc_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int qdisc_configure(Link *link, QDisc *qdisc) { int qdisc_configure(Link *link, QDisc *qdisc) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
_cleanup_free_ char *tca_kind = NULL; _cleanup_free_ char *tca_kind = NULL;
char *p;
int r; int r;
assert(link); assert(link);
@ -131,12 +133,8 @@ int qdisc_configure(Link *link, QDisc *qdisc) {
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Could not create tcm_parent message: %m"); return log_link_error_errno(link, r, "Could not create tcm_parent message: %m");
if (qdisc->parent == TC_H_CLSACT) { if (qdisc->handle != TC_H_UNSPEC) {
tca_kind = strdup("clsact"); r = sd_rtnl_message_set_qdisc_handle(req, qdisc->handle);
if (!tca_kind)
return log_oom();
r = sd_rtnl_message_set_qdisc_handle(req, TC_H_MAKE(TC_H_CLSACT, 0));
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Could not set tcm_handle message: %m"); return log_link_error_errno(link, r, "Could not set tcm_handle message: %m");
} }
@ -171,8 +169,19 @@ int qdisc_configure(Link *link, QDisc *qdisc) {
return r; return r;
} }
if (tca_kind) { if (qdisc->has_fair_queuing_controlled_delay) {
r = sd_netlink_message_append_string(req, TCA_KIND, tca_kind); r = free_and_strdup(&tca_kind, "fq_codel");
if (r < 0)
return log_oom();
r = fair_queuing_controlled_delay_fill_message(link, &qdisc->fq_codel, req);
if (r < 0)
return r;
}
p = tca_kind ?:qdisc->tca_kind;
if (p) {
r = sd_netlink_message_append_string(req, TCA_KIND, p);
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Could not append TCA_KIND attribute: %m"); return log_link_error_errno(link, r, "Could not append TCA_KIND attribute: %m");
} }
@ -218,10 +227,10 @@ int qdisc_section_verify(QDisc *qdisc, bool *has_root, bool *has_clsact) {
"Ignoring [TrafficControlQueueingDiscipline] section from line %u.", "Ignoring [TrafficControlQueueingDiscipline] section from line %u.",
qdisc->section->filename, qdisc->section->line); qdisc->section->filename, qdisc->section->line);
*has_root = true; *has_root = true;
} else if (qdisc->parent == TC_H_CLSACT) { } else if (qdisc->parent == TC_H_CLSACT) { /* TC_H_CLSACT == TC_H_INGRESS */
if (*has_clsact) if (*has_clsact)
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
"%s: More than one clsact TrafficControlQueueingDiscipline sections are defined. " "%s: More than one clsact or ingress TrafficControlQueueingDiscipline sections are defined. "
"Ignoring [TrafficControlQueueingDiscipline] section from line %u.", "Ignoring [TrafficControlQueueingDiscipline] section from line %u.",
qdisc->section->filename, qdisc->section->line); qdisc->section->filename, qdisc->section->line);
*has_clsact = true; *has_clsact = true;
@ -255,17 +264,30 @@ int config_parse_tc_qdiscs_parent(
if (r < 0) if (r < 0)
return r; return r;
if (streq(rvalue, "root")) if (streq(rvalue, "root")) {
qdisc->parent = TC_H_ROOT; qdisc->parent = TC_H_ROOT;
else if (streq(rvalue, "clsact")) qdisc->handle = TC_H_UNSPEC;
} else if (streq(rvalue, "clsact")) {
qdisc->parent = TC_H_CLSACT; qdisc->parent = TC_H_CLSACT;
else { qdisc->handle = TC_H_MAKE(TC_H_CLSACT, 0);
} else if (streq(rvalue, "ingress")) {
qdisc->parent = TC_H_INGRESS;
qdisc->handle = TC_H_MAKE(TC_H_INGRESS, 0);
} else {
log_syntax(unit, LOG_ERR, filename, line, r, log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse [QueueDiscs] 'Parent=', ignoring assignment: %s", "Failed to parse 'Parent=', ignoring assignment: %s",
rvalue); rvalue);
return 0; return 0;
} }
if (streq(rvalue, "root"))
qdisc->tca_kind = mfree(qdisc->tca_kind);
else {
r = free_and_strdup(&qdisc->tca_kind, rvalue);
if (r < 0)
return log_oom();
}
qdisc = NULL; qdisc = NULL;
return 0; return 0;

View File

@ -3,6 +3,7 @@
#pragma once #pragma once
#include "conf-parser.h" #include "conf-parser.h"
#include "fq-codel.h"
#include "netem.h" #include "netem.h"
#include "networkd-link.h" #include "networkd-link.h"
#include "networkd-network.h" #include "networkd-network.h"
@ -21,13 +22,16 @@ typedef struct QDisc {
uint32_t handle; uint32_t handle;
uint32_t parent; uint32_t parent;
char *tca_kind;
bool has_network_emulator:1; bool has_network_emulator:1;
bool has_token_buffer_filter:1; bool has_token_buffer_filter:1;
bool has_stochastic_fairness_queueing:1; bool has_stochastic_fairness_queueing:1;
bool has_fair_queuing_controlled_delay:1;
NetworkEmulator ne; NetworkEmulator ne;
TokenBufferFilter tbf; TokenBufferFilter tbf;
StochasticFairnessQueueing sfq; StochasticFairnessQueueing sfq;
FairQueuingControlledDelay fq_codel;
} QDisc; } QDisc;
void qdisc_free(QDisc *qdisc); void qdisc_free(QDisc *qdisc);

View File

@ -74,7 +74,7 @@ int token_buffer_filter_fill_message(Link *link, const TokenBufferFilter *tbf, s
return log_link_error_errno(link, r, "Failed to calculate mtu size: %m"); return log_link_error_errno(link, r, "Failed to calculate mtu size: %m");
} }
r = sd_netlink_message_open_array(req, TCA_OPTIONS); r = sd_netlink_message_open_container_union(req, TCA_OPTIONS, "tbf");
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Could not open container TCA_OPTIONS: %m"); return log_link_error_errno(link, r, "Could not open container TCA_OPTIONS: %m");
@ -87,7 +87,7 @@ int token_buffer_filter_fill_message(Link *link, const TokenBufferFilter *tbf, s
return log_link_error_errno(link, r, "Could not append TCA_TBF_BURST attribute: %m"); return log_link_error_errno(link, r, "Could not append TCA_TBF_BURST attribute: %m");
if (tbf->rate >= (1ULL << 32)) { if (tbf->rate >= (1ULL << 32)) {
r = sd_netlink_message_append_data(req, TCA_TBF_RATE64, &tbf->rate, sizeof(tbf->rate)); r = sd_netlink_message_append_u64(req, TCA_TBF_RATE64, tbf->rate);
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Could not append TCA_TBF_RATE64 attribute: %m"); return log_link_error_errno(link, r, "Could not append TCA_TBF_RATE64 attribute: %m");
} }
@ -98,12 +98,12 @@ int token_buffer_filter_fill_message(Link *link, const TokenBufferFilter *tbf, s
if (opt.peakrate.rate > 0) { if (opt.peakrate.rate > 0) {
if (tbf->peak_rate >= (1ULL << 32)) { if (tbf->peak_rate >= (1ULL << 32)) {
r = sd_netlink_message_append_data(req, TCA_TBF_PRATE64, &tbf->peak_rate, sizeof(tbf->peak_rate)); r = sd_netlink_message_append_u64(req, TCA_TBF_PRATE64, tbf->peak_rate);
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Could not append TCA_TBF_PRATE64 attribute: %m"); return log_link_error_errno(link, r, "Could not append TCA_TBF_PRATE64 attribute: %m");
} }
r = sd_netlink_message_append_data(req, TCA_TBF_PBURST, &tbf->mtu, sizeof(tbf->mtu)); r = sd_netlink_message_append_u32(req, TCA_TBF_PBURST, tbf->mtu);
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Could not append TCA_TBF_PBURST attribute: %m"); return log_link_error_errno(link, r, "Could not append TCA_TBF_PBURST attribute: %m");

View File

@ -2229,9 +2229,9 @@ static int setup_hostname(void) {
static int setup_journal(const char *directory) { static int setup_journal(const char *directory) {
_cleanup_free_ char *d = NULL; _cleanup_free_ char *d = NULL;
char id[SD_ID128_STRING_MAX];
const char *dirname, *p, *q; const char *dirname, *p, *q;
sd_id128_t this_id; sd_id128_t this_id;
char id[33];
bool try; bool try;
int r; int r;
@ -2866,7 +2866,7 @@ static int inner_child(
FDSet *fds) { FDSet *fds) {
_cleanup_free_ char *home = NULL; _cleanup_free_ char *home = NULL;
char as_uuid[37]; char as_uuid[ID128_UUID_STRING_MAX];
size_t n_env = 1; size_t n_env = 1;
const char *envp[] = { const char *envp[] = {
"PATH=" DEFAULT_PATH_COMPAT, "PATH=" DEFAULT_PATH_COMPAT,

View File

@ -17,6 +17,7 @@
#include "format-util.h" #include "format-util.h"
#include "hashmap.h" #include "hashmap.h"
#include "hostname-util.h" #include "hostname-util.h"
#include "id128-util.h"
#include "io-util.h" #include "io-util.h"
#include "journal-internal.h" #include "journal-internal.h"
#include "json.h" #include "json.h"
@ -26,8 +27,8 @@
#include "namespace-util.h" #include "namespace-util.h"
#include "output-mode.h" #include "output-mode.h"
#include "parse-util.h" #include "parse-util.h"
#include "process-util.h"
#include "pretty-print.h" #include "pretty-print.h"
#include "process-util.h"
#include "sparse-endian.h" #include "sparse-endian.h"
#include "stdio-util.h" #include "stdio-util.h"
#include "string-table.h" #include "string-table.h"
@ -654,7 +655,7 @@ static int output_export(
const size_t highlight[2]) { const size_t highlight[2]) {
sd_id128_t boot_id; sd_id128_t boot_id;
char sid[33]; char sid[SD_ID128_STRING_MAX];
int r; int r;
usec_t realtime, monotonic; usec_t realtime, monotonic;
_cleanup_free_ char *cursor = NULL; _cleanup_free_ char *cursor = NULL;
@ -1353,8 +1354,8 @@ int add_matches_for_user_unit(sd_journal *j, const char *unit, uid_t uid) {
static int get_boot_id_for_machine(const char *machine, sd_id128_t *boot_id) { static int get_boot_id_for_machine(const char *machine, sd_id128_t *boot_id) {
_cleanup_close_pair_ int pair[2] = { -1, -1 }; _cleanup_close_pair_ int pair[2] = { -1, -1 };
_cleanup_close_ int pidnsfd = -1, mntnsfd = -1, rootfd = -1; _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, rootfd = -1;
char buf[ID128_UUID_STRING_MAX];
pid_t pid, child; pid_t pid, child;
char buf[37];
ssize_t k; ssize_t k;
int r; int r;

View File

@ -20,6 +20,7 @@
#include <net/ethernet.h> #include <net/ethernet.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <stdbool.h>
#include "sd-event.h" #include "sd-event.h"
@ -44,7 +45,7 @@ int sd_ipv4acd_set_mac(sd_ipv4acd *acd, const struct ether_addr *addr);
int sd_ipv4acd_set_ifindex(sd_ipv4acd *acd, int interface_index); int sd_ipv4acd_set_ifindex(sd_ipv4acd *acd, int interface_index);
int sd_ipv4acd_set_address(sd_ipv4acd *acd, const struct in_addr *address); int sd_ipv4acd_set_address(sd_ipv4acd *acd, const struct in_addr *address);
int sd_ipv4acd_is_running(sd_ipv4acd *acd); int sd_ipv4acd_is_running(sd_ipv4acd *acd);
int sd_ipv4acd_start(sd_ipv4acd *acd); int sd_ipv4acd_start(sd_ipv4acd *acd, bool reset_conflicts);
int sd_ipv4acd_stop(sd_ipv4acd *acd); int sd_ipv4acd_stop(sd_ipv4acd *acd);
sd_ipv4acd *sd_ipv4acd_ref(sd_ipv4acd *acd); sd_ipv4acd *sd_ipv4acd_ref(sd_ipv4acd *acd);
sd_ipv4acd *sd_ipv4acd_unref(sd_ipv4acd *acd); sd_ipv4acd *sd_ipv4acd_unref(sd_ipv4acd *acd);

View File

@ -21,7 +21,7 @@
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
sd_id128_t id, id2; sd_id128_t id, id2;
char t[33], q[37]; char t[SD_ID128_STRING_MAX], q[ID128_UUID_STRING_MAX];
_cleanup_free_ char *b = NULL; _cleanup_free_ char *b = NULL;
_cleanup_close_ int fd = -1; _cleanup_close_ int fd = -1;
int r; int r;

View File

@ -166,7 +166,7 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
static int determine_devices(void) { static int determine_devices(void) {
_cleanup_free_ void *m = NULL; _cleanup_free_ void *m = NULL;
sd_id128_t root_uuid, verity_uuid; sd_id128_t root_uuid, verity_uuid;
char ids[37]; char ids[ID128_UUID_STRING_MAX];
size_t l; size_t l;
int r; int r;

View File

@ -278,3 +278,4 @@ TokenBufferFilterMPUBytes=
TokenBufferFilterPeakRate= TokenBufferFilterPeakRate=
TokenBufferFilterLatencySec= TokenBufferFilterLatencySec=
StochasticFairnessQueueingPerturbPeriodSec= StochasticFairnessQueueingPerturbPeriodSec=
FairQueuingControlledDelayPacketLimit=

View File

@ -13,8 +13,5 @@ NetworkEmulatorLossRate=20%
NetworkEmulatorPacketLimit=100 NetworkEmulatorPacketLimit=100
[TrafficControlQueueingDiscipline] [TrafficControlQueueingDiscipline]
Parent=clsact Parent=ingress
NetworkEmulatorDelaySec=100ms FairQueuingControlledDelayPacketLimit=20480
NetworkEmulatorDelayJitterSec=13ms
NetworkEmulatorLossRate=20.5%
NetworkEmulatorPacketLimit=200

View File

@ -1509,7 +1509,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
'25-neighbor-ip-dummy.network', '25-neighbor-ip-dummy.network',
'25-neighbor-ip.network', '25-neighbor-ip.network',
'25-nexthop.network', '25-nexthop.network',
'25-qdisc-netem.network', '25-qdisc-netem-and-fqcodel.network',
'25-qdisc-tbf-and-sfq.network', '25-qdisc-tbf-and-sfq.network',
'25-route-ipv6-src.network', '25-route-ipv6-src.network',
'25-route-static.network', '25-route-static.network',
@ -2083,7 +2083,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
self.assertRegex(output, '192.168.5.1') self.assertRegex(output, '192.168.5.1')
def test_qdisc(self): def test_qdisc(self):
copy_unit_to_networkd_unit_path('25-qdisc-netem.network', '12-dummy.netdev', copy_unit_to_networkd_unit_path('25-qdisc-netem-and-fqcodel.network', '12-dummy.netdev',
'25-qdisc-tbf-and-sfq.network', '11-dummy.netdev') '25-qdisc-tbf-and-sfq.network', '11-dummy.netdev')
start_networkd() start_networkd()
@ -2093,7 +2093,8 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
print(output) print(output)
self.assertRegex(output, 'qdisc netem') self.assertRegex(output, 'qdisc netem')
self.assertRegex(output, 'limit 100 delay 50.0ms 10.0ms loss 20%') self.assertRegex(output, 'limit 100 delay 50.0ms 10.0ms loss 20%')
self.assertRegex(output, 'limit 200 delay 100.0ms 13.0ms loss 20.5%') self.assertRegex(output, 'qdisc fq_codel')
self.assertRegex(output, 'limit 20480p')
output = check_output('tc qdisc show dev test1') output = check_output('tc qdisc show dev test1')
print(output) print(output)
self.assertRegex(output, 'qdisc tbf') self.assertRegex(output, 'qdisc tbf')