mirror of
https://github.com/morgan9e/systemd
synced 2026-04-15 00:47:10 +09:00
Merge pull request #24456 from yuwata/network-tcp-congctl
network: introduce TCPCongestionControlAlgorithm=
This commit is contained in:
@@ -1622,6 +1622,15 @@ Table=1234</programlisting></para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>TCPCongestionControlAlgorithm=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies the TCP congestion control algorithm for the route. Takes a name of the algorithm,
|
||||
e.g. <literal>bbr</literal>, <literal>dctcp</literal>, or <literal>vegas</literal>. When unset,
|
||||
the kernel's default will be used.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>MultiPathRoute=<replaceable>address</replaceable>[@<replaceable>name</replaceable>] [<replaceable>weight</replaceable>]</varname></term>
|
||||
<listitem>
|
||||
|
||||
@@ -929,7 +929,7 @@ static const NLAPolicy rtnl_route_metrics_policies[] = {
|
||||
[RTAX_RTO_MIN] = BUILD_POLICY(U32),
|
||||
[RTAX_INITRWND] = BUILD_POLICY(U32),
|
||||
[RTAX_QUICKACK] = BUILD_POLICY(U32),
|
||||
[RTAX_CC_ALGO] = BUILD_POLICY(U32),
|
||||
[RTAX_CC_ALGO] = BUILD_POLICY(STRING),
|
||||
[RTAX_FASTOPEN_NO_COOKIE] = BUILD_POLICY(U32),
|
||||
};
|
||||
|
||||
|
||||
@@ -196,6 +196,7 @@ Route.Type, config_parse_route_type,
|
||||
Route.InitialCongestionWindow, config_parse_tcp_window, 0, 0
|
||||
Route.InitialAdvertisedReceiveWindow, config_parse_tcp_window, 0, 0
|
||||
Route.TCPAdvertisedMaximumSegmentSize, config_parse_tcp_advmss, 0, 0
|
||||
Route.TCPCongestionControlAlgorithm, config_parse_tcp_congestion, 0, 0
|
||||
Route.QuickAck, config_parse_route_boolean, 0, 0
|
||||
Route.FastOpenNoCookie, config_parse_route_boolean, 0, 0
|
||||
Route.TTLPropagate, config_parse_route_boolean, 0, 0
|
||||
|
||||
@@ -107,6 +107,8 @@ Route *route_free(Route *route) {
|
||||
|
||||
sd_event_source_disable_unref(route->expire);
|
||||
|
||||
free(route->tcp_congestion_control_algo);
|
||||
|
||||
return mfree(route);
|
||||
}
|
||||
|
||||
@@ -319,6 +321,7 @@ int route_get(Manager *manager, Link *link, const Route *in, Route **ret) {
|
||||
|
||||
int route_dup(const Route *src, Route **ret) {
|
||||
_cleanup_(route_freep) Route *dest = NULL;
|
||||
int r;
|
||||
|
||||
/* This does not copy mulipath routes. */
|
||||
|
||||
@@ -336,6 +339,11 @@ int route_dup(const Route *src, Route **ret) {
|
||||
dest->manager = NULL;
|
||||
dest->multipath_routes = NULL;
|
||||
dest->expire = NULL;
|
||||
dest->tcp_congestion_control_algo = NULL;
|
||||
|
||||
r = free_and_strdup(&dest->tcp_congestion_control_algo, src->tcp_congestion_control_algo);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
*ret = TAKE_PTR(dest);
|
||||
return 0;
|
||||
@@ -1231,6 +1239,12 @@ static int route_configure(const Route *route, uint32_t lifetime_sec, Link *link
|
||||
return r;
|
||||
}
|
||||
|
||||
if (!isempty(route->tcp_congestion_control_algo)) {
|
||||
r = sd_netlink_message_append_string(m, RTAX_CC_ALGO, route->tcp_congestion_control_algo);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = sd_netlink_message_close_container(m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -2498,6 +2512,46 @@ int config_parse_route_type(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_tcp_congestion(
|
||||
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) {
|
||||
|
||||
Network *network = userdata;
|
||||
_cleanup_(route_free_or_set_invalidp) Route *n = NULL;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(section);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = route_new_static(network, filename, section_line, &n);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to allocate route, ignoring assignment: %m");
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = config_parse_string(unit, filename, line, section, section_line, lvalue, ltype,
|
||||
rvalue, &n->tcp_congestion_control_algo, userdata);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
TAKE_PTR(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_tcp_advmss(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
|
||||
@@ -50,6 +50,7 @@ struct Route {
|
||||
uint32_t initcwnd;
|
||||
uint32_t initrwnd;
|
||||
uint32_t advmss;
|
||||
char *tcp_congestion_control_algo;
|
||||
unsigned char pref;
|
||||
unsigned flags;
|
||||
int gateway_onlink; /* Only used in conf parser and route_section_verify(). */
|
||||
@@ -123,5 +124,6 @@ CONFIG_PARSER_PROTOTYPE(config_parse_route_type);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_tcp_window);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_route_mtu);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_multipath_route);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_tcp_congestion);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_tcp_advmss);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_route_nexthop);
|
||||
|
||||
@@ -189,6 +189,7 @@ Metric=
|
||||
TTLPropagate=
|
||||
MultiPathRoute=
|
||||
TCPAdvertisedMaximumSegmentSize=
|
||||
TCPCongestionControlAlgorithm=
|
||||
NextHop=
|
||||
[Network]
|
||||
KeepMaster=
|
||||
|
||||
16
test/test-network/conf/25-route-congctl.network
Normal file
16
test/test-network/conf/25-route-congctl.network
Normal file
@@ -0,0 +1,16 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
[Match]
|
||||
Name=dummy98
|
||||
|
||||
[Network]
|
||||
IPv6AcceptRA=no
|
||||
Address=2001:1234:5:8f63::1/128
|
||||
Address=149.10.124.58/28
|
||||
|
||||
[Route]
|
||||
Destination=2001:1234:5:8fff:ff:ff:ff:ff/128
|
||||
TCPCongestionControlAlgorithm=dctcp
|
||||
|
||||
[Route]
|
||||
Destination=149.10.124.66
|
||||
TCPCongestionControlAlgorithm=dctcp
|
||||
@@ -2800,6 +2800,24 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
||||
self.assertRegex(output, '149.10.124.48/28 proto kernel scope link src 149.10.124.58')
|
||||
self.assertRegex(output, '149.10.124.66 via inet6 2001:1234:5:8fff:ff:ff:ff:ff proto static')
|
||||
|
||||
@expectedFailureIfModuleIsNotAvailable('tcp_dctcp')
|
||||
def test_route_congctl(self):
|
||||
copy_network_unit('25-route-congctl.network', '12-dummy.netdev')
|
||||
start_networkd()
|
||||
self.wait_online(['dummy98:routable'])
|
||||
|
||||
print('### ip -6 route show dev dummy98 2001:1234:5:8fff:ff:ff:ff:ff')
|
||||
output = check_output('ip -6 route show dev dummy98 2001:1234:5:8fff:ff:ff:ff:ff')
|
||||
print(output)
|
||||
self.assertIn('2001:1234:5:8fff:ff:ff:ff:ff proto static', output)
|
||||
self.assertIn('congctl dctcp', output)
|
||||
|
||||
print('### ip -4 route show dev dummy98 149.10.124.66')
|
||||
output = check_output('ip -4 route show dev dummy98 149.10.124.66')
|
||||
print(output)
|
||||
self.assertIn('149.10.124.66 proto static', output)
|
||||
self.assertIn('congctl dctcp', output)
|
||||
|
||||
@expectedFailureIfModuleIsNotAvailable('vrf')
|
||||
def test_route_vrf(self):
|
||||
copy_network_unit('25-route-vrf.network', '12-dummy.netdev',
|
||||
|
||||
Reference in New Issue
Block a user