Compare commits

..

15 Commits

Author SHA1 Message Date
Zbigniew Jędrzejewski-Szmek c3b41d8811
Merge pull request #14805 from yuwata/network-ipv6-token-follow-up
network: rename eui64 to static
2020-02-07 17:05:33 +01:00
Zbigniew Jędrzejewski-Szmek 43e8a22aab
Merge pull request #14784 from yuwata/network-rename-qdisc-follow-up
network: introduce [QDisc] section to support Parent=ingress or clsact
2020-02-07 15:41:05 +01:00
Matthew Leeds 68697cdd12 hwdb: Fix touchpad toggle on WeiHeng P325J
On the WeiHeng P325J laptop, Fn+F2 sends LeftWindow (0xe0 0x5b) +
LeftCtrl (0x1d) + F24 (0x76). Add a quirk to remap the 0x76 to F21 which
toggles the touchpad. The Ctrl + Win part is handled in userspace, e.g
by gnome-settings-daemon here:
https://gitlab.gnome.org/GNOME/gnome-settings-daemon/commit/f545950fe

This is analogous to what was done for the T-bao hardware here:
https://github.com/systemd/systemd/commit/d4a5df521d
2020-02-07 15:33:17 +01:00
Yu Watanabe 74deaff118 journal: fix log message 2020-02-07 15:27:43 +01:00
Yu Watanabe 03b76a1977 repart: do not quit earlier when --empty=force
Follow-up for 0ae5ffe063.
2020-02-07 13:48:16 +01:00
Yuri Chornoivan 676047438a l10n: update Ukrainian translation 2020-02-07 20:33:50 +09:00
Yu Watanabe 3d55b5a9de test-network: add test for teql 2020-02-07 17:41:49 +09:00
Yu Watanabe 9b749c11e2 network: tc: support teql
Closes #14792.
2020-02-07 17:41:49 +09:00
Yu Watanabe ab9dc1db47 test-network: add more tests for traffic control 2020-02-07 17:41:43 +09:00
Yu Watanabe f0c1ad308d network: fix ABRT
Fixes #14811 and oss-fuzz#20548.
2020-02-07 17:18:58 +09:00
Yu Watanabe 59bae42570 network: update log message 2020-02-07 13:49:01 +09:00
Yu Watanabe ab119e6338 network: append period if error message provided by kernel does not contain it 2020-02-07 13:49:01 +09:00
Yu Watanabe 4c2724013f network: drop redundant %m 2020-02-07 13:49:01 +09:00
Yu Watanabe 2ed5f6d5de network: introduce new [QDisc] section to support Parent=ingress
Follow-up for 18de0969c5.
2020-02-07 13:48:54 +09:00
Yu Watanabe e2c4070edf network: rename eui64 to static
See RFC 4291.

Follow-up for 5f506a5560.
2020-02-07 13:30:40 +09:00
23 changed files with 433 additions and 48 deletions

View File

@ -1558,6 +1558,14 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnVIA:pnK8N800:pvr*
evdev:name:SIPODEV USB Composite Device:dmi:bvn*:bvr*:bd*:svnVIOS:pnLTH17:pvr*
KEYBOARD_KEY_70073=f21 # Touchpad toggle
###########################################################
# WeiHeng
###########################################################
# P325J
evdev:atkbd:dmi:bvn*:bvr*:bd*:svnINET:pnP325J:pvr*
KEYBOARD_KEY_76=f21 # Touchpad toggle
###########################################################
# Zepto
###########################################################

View File

@ -312,7 +312,7 @@
the mechanism is present, the two parts must be separated with a colon
<literal><replaceable>type</replaceable>:<replaceable>prefix</replaceable></literal>. The
address generation mechanism may be either <constant>prefixstable</constant> or
<constant>eui64</constant>. If not specified, <constant>eui64</constant> is assumed. When
<constant>static</constant>. If not specified, <constant>static</constant> is assumed. When
set to <literal>prefixstable</literal> a method for generating IPv6 Interface Identifiers to
be used with IPv6 Stateless Address Autocon figuration (SLAAC). See
<ulink url="https://tools.ietf.org/html/rfc7217">RFC 7217</ulink>. When IPv6 address is set,
@ -2270,6 +2270,21 @@
</variablelist>
</refsect1>
<refsect1>
<title>[QDisc] Section Options</title>
<para>The <literal>[QDisc]</literal> section manages the traffic control queueing discipline (qdisc).</para>
<variablelist class='network-directives'>
<varlistentry>
<term><varname>Parent=</varname></term>
<listitem>
<para>Specifies the parent Queueing Discipline (qdisc). Takes one of <literal>clsact</literal>
or <literal>ingress</literal>. This is mandatory.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>[NetworkEmulator] Section Options</title>
<para>The <literal>[NetworkEmulator]</literal> section manages the queueing discipline (qdisc) of
@ -2662,6 +2677,31 @@
</variablelist>
</refsect1>
<refsect1>
<title>[TrivialLinkEqualizer] Section Options</title>
<para>The <literal>[TrivialLinkEqualizer]</literal> section manages the queueing discipline (qdisc) of
trivial link equalizer (teql).</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>Id=</varname></term>
<listitem>
<para>Specifies the interface ID <literal>N</literal> of teql. Defaults to <literal>0</literal>.
Note that when teql is used, currently, the module <constant>sch_teql</constant> with
<constant>max_equalizers=N+1</constant> option must be loaded before
<command>systemd-networkd</command> is started.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>[BridgeVLAN] Section Options</title>
<para>The <literal>[BridgeVLAN]</literal> section manages the VLAN ID configuration of a bridge port and accepts

144
po/uk.po
View File

@ -2,13 +2,13 @@
# Ukrainian translation for systemd.
# Eugene Melnik <jeka7js@gmail.com>, 2014.
# Daniel Korostil <ted.korostiled@gmail.com>, 2014, 2016, 2018.
# Yuri Chornoivan <yurchor@ukr.net>, 2019.
# Yuri Chornoivan <yurchor@ukr.net>, 2019, 2020.
msgid ""
msgstr ""
"Project-Id-Version: systemd master\n"
"Report-Msgid-Bugs-To: https://github.com/systemd/systemd/issues\n"
"POT-Creation-Date: 2019-07-29 15:34+0000\n"
"PO-Revision-Date: 2019-08-16 09:11+0300\n"
"POT-Creation-Date: 2020-01-30 15:31+0000\n"
"PO-Revision-Date: 2020-02-07 12:37+0200\n"
"Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
"Language-Team: Ukrainian <kde-i18n-uk@kde.org>\n"
"Language: uk\n"
@ -17,7 +17,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<"
"=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Generator: Lokalize 19.11.70\n"
"X-Generator: Lokalize 20.03.70\n"
#: src/core/org.freedesktop.systemd1.policy.in:22
msgid "Send passphrase back to system"
@ -70,6 +70,60 @@ msgstr "Перезапустити стан системи"
msgid "Authentication is required to reload the systemd state."
msgstr "Потрібна автентифікація, щоб перезапустити стан системи."
#: src/home/org.freedesktop.home1.policy:13
msgid "Create a home"
msgstr "Створення домашньої теки"
#: src/home/org.freedesktop.home1.policy:14
msgid "Authentication is required for creating a user's home."
msgstr "Для створення домашньої теки користувача слід пройти розпізнавання."
#: src/home/org.freedesktop.home1.policy:23
msgid "Remove a home"
msgstr "Вилучення домашньої теки"
#: src/home/org.freedesktop.home1.policy:24
msgid "Authentication is required for removing a user's home."
msgstr "Для вилучення домашньої теки користувача слід пройти розпізнавання."
#: src/home/org.freedesktop.home1.policy:33
msgid "Check credentials of a home"
msgstr "Перевірка реєстраційних даних для доступу до домашньої теки"
#: src/home/org.freedesktop.home1.policy:34
msgid ""
"Authentication is required for checking credentials against a user's home."
msgstr ""
"Для перевірки реєстраційних даних для доступу до домашньої теки користувача"
" слід пройти розпізнавання."
#: src/home/org.freedesktop.home1.policy:43
msgid "Update a home"
msgstr "Оновлення домашньої теки"
#: src/home/org.freedesktop.home1.policy:44
msgid "Authentication is required for updating a user's home."
msgstr "Для оновлення домашньої теки користувача слід пройти розпізнавання."
#: src/home/org.freedesktop.home1.policy:53
msgid "Resize a home"
msgstr "Зміна розмірів домашньої теки"
#: src/home/org.freedesktop.home1.policy:54
msgid "Authentication is required for resizing a user's home."
msgstr ""
"Для зміни розмірів домашньої теки користувача слід пройти розпізнавання."
#: src/home/org.freedesktop.home1.policy:63
msgid "Change password of a home"
msgstr "Зміна пароля до домашньої теки"
#: src/home/org.freedesktop.home1.policy:64
msgid "Authentication is required for changing the password of a user's home."
msgstr ""
"Для зміни пароля для доступу до домашньої теки користувача слід пройти"
" розпізнавання."
#: src/hostname/org.freedesktop.hostname1.policy:20
msgid "Set host name"
msgstr "Встановити назву вузла"
@ -525,6 +579,14 @@ msgstr "Вказати повідомлення на стіні"
msgid "Authentication is required to set a wall message"
msgstr "Потрібна автентифікація, щоб вказати повідомлення на стіні"
#: src/login/org.freedesktop.login1.policy:395
msgid "Change Session"
msgstr "Зміна сеансу"
#: src/login/org.freedesktop.login1.policy:396
msgid "Authentication is required to change the virtual terminal."
msgstr "Для зміни віртуального термінала слід пройти розпізнавання."
#: src/machine/org.freedesktop.machine1.policy:22
msgid "Log into a local container"
msgstr "Увійти в локальний контейнер"
@ -608,66 +670,82 @@ msgid "Authentication is required to set NTP servers."
msgstr "Потрібна автентифікація, щоб встановити сервери NTP."
#: src/network/org.freedesktop.network1.policy:33
#: src/resolve/org.freedesktop.resolve1.policy:44
msgid "Set DNS servers"
msgstr "Встановлення серверів DNS"
#: src/network/org.freedesktop.network1.policy:34
#: src/resolve/org.freedesktop.resolve1.policy:45
msgid "Authentication is required to set DNS servers."
msgstr "Потрібна автентифікація, щоб встановити сервери DNS."
#: src/network/org.freedesktop.network1.policy:44
#: src/resolve/org.freedesktop.resolve1.policy:55
msgid "Set domains"
msgstr "Встановлення доменів"
#: src/network/org.freedesktop.network1.policy:45
#: src/resolve/org.freedesktop.resolve1.policy:56
msgid "Authentication is required to set domains."
msgstr "Потрібна автентифікація, щоб встановити домени."
#: src/network/org.freedesktop.network1.policy:55
#: src/resolve/org.freedesktop.resolve1.policy:66
msgid "Set default route"
msgstr "Встановлення типового маршруту"
#: src/network/org.freedesktop.network1.policy:56
#: src/resolve/org.freedesktop.resolve1.policy:67
msgid "Authentication is required to set default route."
msgstr "Потрібна автентифікація, щоб встановити типовий маршрут."
#: src/network/org.freedesktop.network1.policy:66
#: src/resolve/org.freedesktop.resolve1.policy:77
msgid "Enable/disable LLMNR"
msgstr "Вмикання або вимикання LLMNR"
#: src/network/org.freedesktop.network1.policy:67
#: src/resolve/org.freedesktop.resolve1.policy:78
msgid "Authentication is required to enable or disable LLMNR."
msgstr "Потрібна автентифікація, щоб увімкнути або вимкнути LLMNR."
#: src/network/org.freedesktop.network1.policy:77
#: src/resolve/org.freedesktop.resolve1.policy:88
msgid "Enable/disable multicast DNS"
msgstr "Вмикання або вимикання трансляційного DNS"
#: src/network/org.freedesktop.network1.policy:78
#: src/resolve/org.freedesktop.resolve1.policy:89
msgid "Authentication is required to enable or disable multicast DNS."
msgstr "Потрібна автентифікація, щоб увімкнути або вимкнути трансляційну DNS."
#: src/network/org.freedesktop.network1.policy:88
#: src/resolve/org.freedesktop.resolve1.policy:99
msgid "Enable/disable DNS over TLS"
msgstr "Вмикання і вимикання DNS через TLS"
#: src/network/org.freedesktop.network1.policy:89
#: src/resolve/org.freedesktop.resolve1.policy:100
msgid "Authentication is required to enable or disable DNS over TLS."
msgstr "Потрібна автентифікація, щоб увімкнути або вимкнути DNS через TLS."
#: src/network/org.freedesktop.network1.policy:99
#: src/resolve/org.freedesktop.resolve1.policy:110
msgid "Enable/disable DNSSEC"
msgstr "Вмикання або вимикання DNSSEC"
#: src/network/org.freedesktop.network1.policy:100
#: src/resolve/org.freedesktop.resolve1.policy:111
msgid "Authentication is required to enable or disable DNSSEC."
msgstr "Потрібна автентифікація, щоб увімкнути або вимкнути DNSSEC."
#: src/network/org.freedesktop.network1.policy:110
#: src/resolve/org.freedesktop.resolve1.policy:121
msgid "Set DNSSEC Negative Trust Anchors"
msgstr "Встановлення прив'язок від'ємної довіри DNSSEC"
#: src/network/org.freedesktop.network1.policy:111
#: src/resolve/org.freedesktop.resolve1.policy:122
msgid "Authentication is required to set DNSSEC Negative Trust Anchors."
msgstr ""
"Потрібна автентифікація, щоб встановити прив'язки від'ємної довіри DNSSEC."
@ -677,16 +755,40 @@ msgid "Revert NTP settings"
msgstr "Повернення до початкових параметрів NTP"
#: src/network/org.freedesktop.network1.policy:122
msgid "Authentication is required to revert NTP settings."
msgstr "Потрібна автентифікація, щоб повернутися до початкових параметрів NTP."
msgid "Authentication is required to reset NTP settings."
msgstr "Для скидання параметрів NTP до типових слід пройти розпізнавання."
#: src/network/org.freedesktop.network1.policy:132
msgid "Revert DNS settings"
msgstr "Повернення до початкових параметрів DNS"
#: src/network/org.freedesktop.network1.policy:133
msgid "Authentication is required to revert DNS settings."
msgstr "Потрібна автентифікація, щоб повернутися до початкових параметрів DNS."
msgid "Authentication is required to reset DNS settings."
msgstr "Для скидання параметрів DNS до типових слід пройти розпізнавання."
#: src/network/org.freedesktop.network1.policy:143
msgid "Renew dynamic addresses"
msgstr "Оновлення динамічних адрес"
#: src/network/org.freedesktop.network1.policy:144
msgid "Authentication is required to renew dynamic addresses."
msgstr "Для оновлення динамічних адрес слід пройти розпізнавання."
#: src/network/org.freedesktop.network1.policy:154
msgid "Reload network settings"
msgstr "Перезавантаження параметрів мережі"
#: src/network/org.freedesktop.network1.policy:155
msgid "Authentication is required to reload network settings."
msgstr "Для перезавантаження параметрів мережі слід пройти розпізнавання."
#: src/network/org.freedesktop.network1.policy:165
msgid "Reconfigure network interface"
msgstr "Переналаштування інтерфейсу мережі"
#: src/network/org.freedesktop.network1.policy:166
msgid "Authentication is required to reconfigure network interface."
msgstr "Для зміни налаштувань інтерфейсу мережі слід пройти розпізнавання."
#: src/portable/org.freedesktop.portable1.policy:13
msgid "Inspect a portable service image"
@ -733,6 +835,16 @@ msgstr "Зняти з реєстрації службу DNS-SD"
msgid "Authentication is required to unregister a DNS-SD service"
msgstr "Потрібна автентифікація, щоб зняти з реєстрації службу DNS-SD"
#: src/resolve/org.freedesktop.resolve1.policy:132
msgid "Revert name resolution settings"
msgstr "Повернення до початкових параметрів визначення назв вузлів"
#: src/resolve/org.freedesktop.resolve1.policy:133
msgid "Authentication is required to reset name resolution settings."
msgstr ""
"Для повернення до початкових параметрів визначення назв вузлів за адресами"
" слід пройти розпізнавання."
#: src/timedate/org.freedesktop.timedate1.policy:22
msgid "Set system time"
msgstr "Вказати системний час"
@ -773,38 +885,38 @@ msgstr ""
"Потрібна автентифікація, щоб контролювати, чи синхронізування часу через "
"мережу запущено."
#: src/core/dbus-unit.c:354
#: src/core/dbus-unit.c:355
msgid "Authentication is required to start '$(unit)'."
msgstr "Потрібна автентифікація, щоб запустити «$(unit)»."
#: src/core/dbus-unit.c:355
#: src/core/dbus-unit.c:356
msgid "Authentication is required to stop '$(unit)'."
msgstr "Потрібна автентифікація, щоб зупинити «$(unit)»."
#: src/core/dbus-unit.c:356
#: src/core/dbus-unit.c:357
msgid "Authentication is required to reload '$(unit)'."
msgstr "Потрібна автентифікація, щоб перезавантажити «$(unit)»."
#: src/core/dbus-unit.c:357 src/core/dbus-unit.c:358
#: src/core/dbus-unit.c:358 src/core/dbus-unit.c:359
msgid "Authentication is required to restart '$(unit)'."
msgstr "Потрібна автентифікація, щоб перезапустити «$(unit)»."
#: src/core/dbus-unit.c:530
#: src/core/dbus-unit.c:531
msgid ""
"Authentication is required to send a UNIX signal to the processes of "
"'$(unit)'."
msgstr ""
"Потрібна автентифікація, щоб надіслати сигнал UNIX до процесів «$(unit)»."
#: src/core/dbus-unit.c:561
#: src/core/dbus-unit.c:562
msgid "Authentication is required to reset the \"failed\" state of '$(unit)'."
msgstr "Потрібна автентифікація, щоб скинути «пошкоджений» стан з «$(unit)»."
#: src/core/dbus-unit.c:594
#: src/core/dbus-unit.c:595
msgid "Authentication is required to set properties on '$(unit)'."
msgstr "Потрібна автентифікація, щоб вказати властивості на «$(unit)»."
#: src/core/dbus-unit.c:703
#: src/core/dbus-unit.c:704
msgid ""
"Authentication is required to delete files and directories associated with "
"'$(unit)'."

View File

@ -825,7 +825,7 @@ int server_restore_streams(Server *s, FDSet *fds) {
/* No file descriptor? Then let's delete the state file */
log_debug("Cannot restore stream file %s", de->d_name);
if (unlinkat(dirfd(d), de->d_name, 0) < 0)
log_warning_errno(errno, "Failed to remove %s%s: %m", path, de->d_name);
log_warning_errno(errno, "Failed to remove %s/%s: %m", path, de->d_name);
continue;
}

View File

@ -123,6 +123,8 @@ sources = files('''
tc/tbf.h
tc/tc-util.c
tc/tc-util.h
tc/teql.c
tc/teql.h
'''.split())
systemd_networkd_sources = files('networkd.c')

View File

@ -4305,5 +4305,10 @@ int log_link_message_full_errno(Link *link, sd_netlink_message *m, int level, in
const char *err_msg = NULL;
(void) sd_netlink_message_read_string(m, NLMSGERR_ATTR_MSG, &err_msg);
return log_link_full(link, level, err, "%s: %s%s%m", msg, strempty(err_msg), err_msg ? " " : "");
return log_link_full(link, level, err,
"%s: %s%s%s%m",
msg,
strempty(err_msg),
err_msg && !endswith(err_msg, ".") ? "." : "",
err_msg ? " " : "");
}

View File

@ -278,13 +278,13 @@ static int ndisc_router_generate_address(Link *link, unsigned prefixlen, uint32_
break;
}
}
} else if (j->address_generation_type == IPV6_TOKEN_ADDRESS_GENERATION_EUI64) {
} else if (j->address_generation_type == IPV6_TOKEN_ADDRESS_GENERATION_STATIC) {
memcpy(((uint8_t *)&address->in_addr.in6) + 8, ((uint8_t *) &j->prefix) + 8, 8);
prefix = true;
break;
}
/* eui64 or fallback if prefixstable do not match */
/* fallback to eui64 if prefixstable or static do not match */
if (!prefix) {
/* see RFC4291 section 2.5.1 */
address->in_addr.in6.s6_addr[8] = link->mac.ether_addr_octet[0];
@ -992,15 +992,21 @@ int config_parse_address_generation_type(
if (r < 0)
return log_oom();
if (streq(word, "eui64"))
token->address_generation_type = IPV6_TOKEN_ADDRESS_GENERATION_EUI64;
if (streq(word, "static"))
token->address_generation_type = IPV6_TOKEN_ADDRESS_GENERATION_STATIC;
else if (streq(word, "prefixstable"))
token->address_generation_type = IPV6_TOKEN_ADDRESS_GENERATION_PREFIXSTABLE;
else {
token->address_generation_type = IPV6_TOKEN_ADDRESS_GENERATION_EUI64;
token->address_generation_type = IPV6_TOKEN_ADDRESS_GENERATION_STATIC;
p = rvalue;
}
if (isempty(p)) {
log_syntax(unit, LOG_ERR, filename, line, 0,
"Invalid IPv6Token= , ignoring assignment: %s", rvalue);
return 0;
}
r = in_addr_from_string(AF_INET6, p, &buffer);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,

View File

@ -9,7 +9,7 @@ typedef struct IPv6Token IPv6Token;
typedef enum IPv6TokenAddressGeneration {
IPV6_TOKEN_ADDRESS_GENERATION_NONE,
IPV6_TOKEN_ADDRESS_GENERATION_EUI64,
IPV6_TOKEN_ADDRESS_GENERATION_STATIC,
IPV6_TOKEN_ADDRESS_GENERATION_PREFIXSTABLE,
_IPV6_TOKEN_ADDRESS_GENERATION_MAX,
_IPV6_TOKEN_ADDRESS_GENERATION_INVALID = -1,

View File

@ -251,6 +251,7 @@ CAN.BitRate, config_parse_si_uint64,
CAN.SamplePoint, config_parse_permille, 0, offsetof(Network, can_sample_point)
CAN.RestartSec, config_parse_sec, 0, offsetof(Network, can_restart_us)
CAN.TripleSampling, config_parse_tristate, 0, offsetof(Network, can_triple_sampling)
QDisc.Parent, config_parse_qdisc_parent, _QDISC_KIND_INVALID, 0
ControlledDelay.Parent, config_parse_qdisc_parent, QDISC_KIND_CODEL, 0
ControlledDelay.PacketLimit, config_parse_controlled_delay_u32, QDISC_KIND_CODEL, 0
ControlledDelay.TargetSec, config_parse_controlled_delay_usec, QDISC_KIND_CODEL, 0
@ -292,6 +293,8 @@ TokenBucketFilter.MTUBytes, config_parse_token_bucket_filter_si
TokenBucketFilter.MPUBytes, config_parse_token_bucket_filter_size, QDISC_KIND_TBF, 0
TokenBucketFilter.PeakRate, config_parse_token_bucket_filter_size, QDISC_KIND_TBF, 0
TokenBucketFilter.LatencySec, config_parse_token_bucket_filter_latency, QDISC_KIND_TBF, 0
TrivialLinkEqualizer.Parent, config_parse_qdisc_parent, QDISC_KIND_TEQL, 0
TrivialLinkEqualizer.Id, config_parse_trivial_link_equalizer_id, QDISC_KIND_TEQL, 0
/* backwards compatibility: do not add new entries to this section */
Network.IPv4LL, config_parse_ipv4ll, 0, offsetof(Network, link_local)
DHCP.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier)
@ -320,7 +323,7 @@ DHCP.RapidCommit, config_parse_bool,
DHCP.ForceDHCPv6PDOtherInformation, config_parse_bool, 0, offsetof(Network, dhcp6_force_pd_other_information)
DHCPv4.UseDomainName, config_parse_dhcp_use_domains, 0, offsetof(Network, dhcp_use_domains)
DHCPv4.CriticalConnection, config_parse_tristate, 0, offsetof(Network, dhcp_critical)
TrafficControlQueueingDiscipline.Parent, config_parse_qdisc_parent, QDISC_KIND_NETEM, 0
TrafficControlQueueingDiscipline.Parent, config_parse_qdisc_parent, _QDISC_KIND_INVALID, 0
TrafficControlQueueingDiscipline.NetworkEmulatorDelaySec, config_parse_network_emulator_delay, 0, 0
TrafficControlQueueingDiscipline.NetworkEmulatorDelayJitterSec, config_parse_network_emulator_delay, 0, 0
TrafficControlQueueingDiscipline.NetworkEmulatorLossRate, config_parse_network_emulator_rate, 0, 0

View File

@ -482,12 +482,14 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
"IPv6RoutePrefix\0"
"TrafficControlQueueingDiscipline\0"
"CAN\0"
"QDisc\0"
"ControlledDelay\0"
"FairQueueing\0"
"FairQueueingControlledDelay\0"
"NetworkEmulator\0"
"StochasticFairnessQueueing\0"
"TokenBucketFilter\0",
"TokenBucketFilter\0"
"TrivialLinkEqualizer\0",
config_item_perf_lookup, network_network_gperf_lookup,
CONFIG_PARSE_WARN, network);
if (r < 0)

View File

@ -20,6 +20,7 @@ const QDiscVTable * const qdisc_vtable[_QDISC_KIND_MAX] = {
[QDISC_KIND_NETEM] = &netem_vtable,
[QDISC_KIND_SFQ] = &sfq_vtable,
[QDISC_KIND_TBF] = &tbf_vtable,
[QDISC_KIND_TEQL] = &teql_vtable,
};
static int qdisc_new(QDiscKind kind, QDisc **ret) {
@ -138,7 +139,7 @@ static int qdisc_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
r = sd_netlink_message_get_errno(m);
if (r < 0 && r != -EEXIST) {
log_link_message_error_errno(link, m, r, "Could not set QDisc: %m");
log_link_message_error_errno(link, m, r, "Could not set QDisc");
link_enter_failed(link);
return 1;
}
@ -176,13 +177,21 @@ int qdisc_configure(Link *link, QDisc *qdisc) {
}
if (QDISC_VTABLE(qdisc)) {
if (QDISC_VTABLE(qdisc)->fill_tca_kind) {
r = QDISC_VTABLE(qdisc)->fill_tca_kind(link, qdisc, req);
if (r < 0)
return r;
} else {
r = sd_netlink_message_append_string(req, TCA_KIND, QDISC_VTABLE(qdisc)->tca_kind);
if (r < 0)
return log_link_error_errno(link, r, "Could not append TCA_KIND attribute: %m");
}
if (QDISC_VTABLE(qdisc)->fill_message) {
r = QDISC_VTABLE(qdisc)->fill_message(link, qdisc, req);
if (r < 0)
return r;
}
} else {
r = sd_netlink_message_append_string(req, TCA_KIND, qdisc->tca_kind);
if (r < 0)
@ -218,15 +227,15 @@ int qdisc_section_verify(QDisc *qdisc, bool *has_root, bool *has_clsact) {
if (qdisc->parent == TC_H_ROOT) {
if (*has_root)
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
"%s: More than one root TrafficControlQueueingDiscipline sections are defined. "
"Ignoring [TrafficControlQueueingDiscipline] section from line %u.",
"%s: More than one root qdisc section is defined. "
"Ignoring the qdisc section from line %u.",
qdisc->section->filename, qdisc->section->line);
*has_root = true;
} else if (qdisc->parent == TC_H_CLSACT) { /* TC_H_CLSACT == TC_H_INGRESS */
if (*has_clsact)
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
"%s: More than one clsact or ingress TrafficControlQueueingDiscipline sections are defined. "
"Ignoring [TrafficControlQueueingDiscipline] section from line %u.",
"%s: More than one clsact or ingress qdisc section is defined. "
"Ignoring the qdisc section from line %u.",
qdisc->section->filename, qdisc->section->line);
*has_clsact = true;
}
@ -254,7 +263,6 @@ int config_parse_qdisc_parent(
assert(lvalue);
assert(rvalue);
assert(data);
assert(ltype >= 0 && ltype < _QDISC_KIND_MAX);
r = qdisc_new_static(ltype, network, filename, section_line, &qdisc);
if (r < 0)

View File

@ -14,6 +14,7 @@ typedef enum QDiscKind {
QDISC_KIND_NETEM,
QDISC_KIND_SFQ,
QDISC_KIND_TBF,
QDISC_KIND_TEQL,
_QDISC_KIND_MAX,
_QDISC_KIND_INVALID = -1,
} QDiscKind;
@ -35,6 +36,7 @@ typedef struct QDiscVTable {
const char *tca_kind;
/* called in qdisc_new() */
int (*init)(QDisc *qdisc);
int (*fill_tca_kind)(Link *link, QDisc *qdisc, sd_netlink_message *m);
int (*fill_message)(Link *link, QDisc *qdisc, sd_netlink_message *m);
int (*verify)(QDisc *qdisc);
} QDiscVTable;
@ -71,3 +73,4 @@ CONFIG_PARSER_PROTOTYPE(config_parse_qdisc_parent);
#include "netem.h"
#include "sfq.h"
#include "tbf.h"
#include "teql.h"

90
src/network/tc/teql.c Normal file
View File

@ -0,0 +1,90 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#include "macro.h"
#include "netlink-util.h"
#include "parse-util.h"
#include "stdio-util.h"
#include "string-util.h"
#include "teql.h"
static int trivial_link_equalizer_fill_tca_kind(Link *link, QDisc *qdisc, sd_netlink_message *req) {
char kind[STRLEN("teql") + DECIMAL_STR_MAX(unsigned)];
TrivialLinkEqualizer *teql;
int r;
assert(link);
assert(qdisc);
assert(req);
teql = TEQL(qdisc);
xsprintf(kind, "teql%u", teql->id);
r = sd_netlink_message_append_string(req, TCA_KIND, kind);
if (r < 0)
return log_link_error_errno(link, r, "Could not append TCA_KIND attribute: %m");
return 0;
}
const QDiscVTable teql_vtable = {
.object_size = sizeof(TrivialLinkEqualizer),
.fill_tca_kind = trivial_link_equalizer_fill_tca_kind,
};
int config_parse_trivial_link_equalizer_id(
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;
TrivialLinkEqualizer *teql;
Network *network = data;
unsigned id;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
r = qdisc_new_static(QDISC_KIND_TEQL, 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");
teql = TEQL(qdisc);
if (isempty(rvalue)) {
teql->id = 0;
qdisc = NULL;
return 0;
}
r = safe_atou(rvalue, &id);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r,
"Failed to parse '%s=', ignoring assignment: %s",
lvalue, rvalue);
return 0;
}
if (id > INT_MAX) {
log_syntax(unit, LOG_ERR, filename, line, 0,
"'%s=' is too large, ignoring assignment: %s",
lvalue, rvalue);
}
teql->id = id;
qdisc = NULL;
return 0;
}

16
src/network/tc/teql.h Normal file
View File

@ -0,0 +1,16 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
#include "conf-parser.h"
#include "qdisc.h"
typedef struct TrivialLinkEqualizer {
QDisc meta;
unsigned id;
} TrivialLinkEqualizer;
DEFINE_QDISC_CAST(TEQL, TrivialLinkEqualizer);
extern const QDiscVTable teql_vtable;
CONFIG_PARSER_PROTOTYPE(config_parse_trivial_link_equalizer_id);

View File

@ -2946,7 +2946,7 @@ static int run(int argc, char *argv[]) {
if (r < 0)
return r;
if (context->n_partitions <= 0)
if (context->n_partitions <= 0 && arg_empty != EMPTY_FORCE)
return 0;
r = find_root(&node);

View File

@ -270,6 +270,8 @@ SendOption=
[NextHop]
Id=
Gateway=
[QDisc]
Parent=
[NetworkEmulator]
Parent=
DelaySec=
@ -324,3 +326,6 @@ NetworkEmulatorDelayJitterSec=
NetworkEmulatorLossRate=
NetworkEmulatorDuplicateRate=
NetworkEmulatorPacketLimit=
[TrivialLinkEqualizer]
Parent=
Id=

Binary file not shown.

View File

@ -0,0 +1,12 @@
[Match]
Name=dummy98
[Network]
IPv6AcceptRA=no
Address=10.1.2.3/16
#[TrafficControlQueueingDiscipline]
#Parent=root
[TrafficControlQueueingDiscipline]
Parent=clsact

View File

@ -0,0 +1,16 @@
[Match]
Name=test1
[Network]
IPv6AcceptRA=no
Address=10.1.2.4/16
[TrafficControlQueueingDiscipline]
Parent=root
NetworkEmulatorDelaySec=50ms
NetworkEmulatorDelayJitterSec=10ms
NetworkEmulatorLossRate=20%
NetworkEmulatorPacketLimit=100
[TrafficControlQueueingDiscipline]
Parent=ingress

View File

@ -0,0 +1,12 @@
[Match]
Name=test1
[Network]
IPv6AcceptRA=no
Address=10.1.2.4/16
#[QDisc]
#Parent=root
[QDisc]
Parent=ingress

View File

@ -0,0 +1,10 @@
[Match]
Name=dummy98
[Network]
IPv6AcceptRA=no
Address=10.1.2.3/16
[TrivialLinkEqualizer]
Parent=root
Id=1

View File

@ -1616,9 +1616,13 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
'25-neighbor-ip-dummy.network',
'25-neighbor-ip.network',
'25-nexthop.network',
'25-qdisc-clsact-root-compat.network',
'25-qdisc-fq-codel.network',
'25-qdisc-ingress-netem-compat.network',
'25-qdisc-ingress-root.network',
'25-qdisc-netem-and-fqcodel.network',
'25-qdisc-tbf-and-sfq.network',
'25-qdisc-teql.network',
'25-route-ipv6-src.network',
'25-route-static.network',
'25-gateway-static.network',
@ -2248,10 +2252,11 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
self.assertRegex(output, 'perturb 5sec')
def test_qdisc2(self):
copy_unit_to_networkd_unit_path('25-qdisc-fq-codel.network', '12-dummy.netdev')
copy_unit_to_networkd_unit_path('25-qdisc-fq-codel.network', '12-dummy.netdev',
'25-qdisc-ingress-root.network', '11-dummy.netdev')
start_networkd()
self.wait_online(['dummy98:routable'])
self.wait_online(['dummy98:routable', 'test1:routable'])
output = check_output('tc qdisc show dev dummy98')
print(output)
@ -2262,6 +2267,36 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
self.assertRegex(output, 'maxrate 1Mbit')
self.assertRegex(output, 'qdisc codel')
self.assertRegex(output, 'limit 2000p target 10.0ms ce_threshold 100.0ms interval 50.0ms ecn')
output = check_output('tc qdisc show dev test1')
print(output)
self.assertRegex(output, 'qdisc ingress')
def test_qdisc3(self):
copy_unit_to_networkd_unit_path('25-qdisc-clsact-root-compat.network', '12-dummy.netdev',
'25-qdisc-ingress-netem-compat.network', '11-dummy.netdev')
start_networkd()
self.wait_online(['dummy98:routable', 'test1:routable'])
output = check_output('tc qdisc show dev dummy98')
print(output)
self.assertRegex(output, 'qdisc clsact')
output = check_output('tc qdisc show dev test1')
print(output)
self.assertRegex(output, 'qdisc netem')
self.assertRegex(output, 'limit 100 delay 50.0ms 10.0ms loss 20%')
self.assertRegex(output, 'qdisc ingress')
def test_qdisc4(self):
copy_unit_to_networkd_unit_path('25-qdisc-teql.network', '12-dummy.netdev')
check_output('modprobe sch_teql max_equalizers=2')
start_networkd()
self.wait_online(['dummy98:routable'])
output = check_output('tc qdisc show dev dummy98')
print(output)
self.assertRegex(output, 'qdisc teql1')
class NetworkdStateFileTests(unittest.TestCase, Utilities):
links = [
@ -2645,7 +2680,7 @@ class NetworkdRATests(unittest.TestCase, Utilities):
'25-veth.netdev',
'ipv6-prefix.network',
'ipv6-prefix-veth.network',
'ipv6-prefix-veth-token-eui64.network',
'ipv6-prefix-veth-token-static.network',
'ipv6-prefix-veth-token-prefixstable.network']
def setUp(self):
@ -2671,8 +2706,8 @@ class NetworkdRATests(unittest.TestCase, Utilities):
print(output)
self.assertRegex(output, '2002:da8:1:0')
def test_ipv6_token_eui64(self):
copy_unit_to_networkd_unit_path('25-veth.netdev', 'ipv6-prefix.network', 'ipv6-prefix-veth-token-eui64.network')
def test_ipv6_token_static(self):
copy_unit_to_networkd_unit_path('25-veth.netdev', 'ipv6-prefix.network', 'ipv6-prefix-veth-token-static.network')
start_networkd()
self.wait_online(['veth99:routable', 'veth-peer:degraded'])