Merge pull request #30803 from yuwata/network-route-parser-trivial-cleanups
network/route: trivial cleanups for conf parsers
This commit is contained in:
@@ -67,8 +67,10 @@ sources = files(
|
||||
'networkd-nexthop.c',
|
||||
'networkd-queue.c',
|
||||
'networkd-radv.c',
|
||||
'networkd-route-util.c',
|
||||
'networkd-route.c',
|
||||
'networkd-route-metric.c',
|
||||
'networkd-route-nexthop.c',
|
||||
'networkd-route-util.c',
|
||||
'networkd-routing-policy-rule.c',
|
||||
'networkd-setlink.c',
|
||||
'networkd-speed-meter.c',
|
||||
|
||||
@@ -192,23 +192,23 @@ Route.Metric, config_parse_route_priority,
|
||||
Route.Scope, config_parse_route_scope, 0, 0
|
||||
Route.PreferredSource, config_parse_preferred_src, 0, 0
|
||||
Route.Table, config_parse_route_table, 0, 0
|
||||
Route.MTUBytes, config_parse_route_mtu, AF_UNSPEC, 0
|
||||
Route.GatewayOnLink, config_parse_route_boolean, 0, 0
|
||||
Route.GatewayOnlink, config_parse_route_boolean, 0, 0
|
||||
Route.GatewayOnLink, config_parse_route_gateway_onlink, 0, 0
|
||||
Route.GatewayOnlink, config_parse_route_gateway_onlink, 0, 0
|
||||
Route.IPv6Preference, config_parse_ipv6_route_preference, 0, 0
|
||||
Route.Protocol, config_parse_route_protocol, 0, 0
|
||||
Route.Type, config_parse_route_type, 0, 0
|
||||
Route.TCPRetransmissionTimeoutSec, config_parse_route_tcp_rto, 0, 0
|
||||
Route.HopLimit, config_parse_route_hop_limit, 0, 0
|
||||
Route.InitialCongestionWindow, config_parse_route_tcp_window, 0, 0
|
||||
Route.InitialAdvertisedReceiveWindow, config_parse_route_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_warn_compat, DISABLED_LEGACY, 0
|
||||
Route.MultiPathRoute, config_parse_multipath_route, 0, 0
|
||||
Route.NextHop, config_parse_route_nexthop, 0, 0
|
||||
Route.MTUBytes, config_parse_route_metric_mtu, RTAX_MTU, 0
|
||||
Route.TCPAdvertisedMaximumSegmentSize, config_parse_route_metric_advmss, RTAX_ADVMSS, 0
|
||||
Route.HopLimit, config_parse_route_metric_hop_limit, RTAX_HOPLIMIT, 0
|
||||
Route.InitialCongestionWindow, config_parse_route_metric_tcp_window, RTAX_INITCWND, 0
|
||||
Route.TCPRetransmissionTimeoutSec, config_parse_route_metric_tcp_rto, RTAX_RTO_MIN, 0
|
||||
Route.InitialAdvertisedReceiveWindow, config_parse_route_metric_tcp_window, RTAX_INITRWND, 0
|
||||
Route.QuickAck, config_parse_route_metric_boolean, RTAX_QUICKACK, 0
|
||||
Route.TCPCongestionControlAlgorithm, config_parse_route_metric_tcp_congestion, RTAX_CC_ALGO, 0
|
||||
Route.FastOpenNoCookie, config_parse_route_metric_boolean, RTAX_FASTOPEN_NO_COOKIE, 0
|
||||
Route.TTLPropagate, config_parse_warn_compat, DISABLED_LEGACY, 0
|
||||
NextHop.Id, config_parse_nexthop_id, 0, 0
|
||||
NextHop.Gateway, config_parse_nexthop_gateway, 0, 0
|
||||
NextHop.Family, config_parse_nexthop_family, 0, 0
|
||||
|
||||
@@ -0,0 +1,384 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "networkd-route.h"
|
||||
#include "networkd-route-metric.h"
|
||||
#include "parse-util.h"
|
||||
#include "string-util.h"
|
||||
|
||||
int config_parse_route_metric_mtu(
|
||||
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 *route = NULL;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(section);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = route_new_static(network, filename, section_line, &route);
|
||||
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_mtu(unit, filename, line, section, section_line, lvalue, AF_UNSPEC, rvalue, &route->mtu, userdata);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
TAKE_PTR(route);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_route_metric_advmss(
|
||||
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_(route_free_or_set_invalidp) Route *route = NULL;
|
||||
Network *network = userdata;
|
||||
uint64_t u;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(section);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = route_new_static(network, filename, section_line, &route);
|
||||
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;
|
||||
}
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
route->advmss = 0;
|
||||
TAKE_PTR(route);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = parse_size(rvalue, 1024, &u);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Could not parse %s=, ignoring assignment: %s", lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (u == 0 || u > UINT32_MAX) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"Invalid %s=, ignoring assignment: %s", lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
route->advmss = u;
|
||||
|
||||
TAKE_PTR(route);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_route_metric_hop_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_(route_free_or_set_invalidp) Route *route = NULL;
|
||||
Network *network = userdata;
|
||||
uint32_t k;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(section);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = route_new_static(network, filename, section_line, &route);
|
||||
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;
|
||||
}
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
route->hop_limit = 0;
|
||||
TAKE_PTR(route);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = safe_atou32(rvalue, &k);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Could not parse %s=, ignoring assignment: %s", lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (k == 0 || k > 255) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"Invalid %s=, ignoring assignment: %s", lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
route->hop_limit = k;
|
||||
|
||||
TAKE_PTR(route);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_tcp_window(
|
||||
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) {
|
||||
|
||||
uint32_t *window = ASSERT_PTR(data);
|
||||
uint32_t k;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(section);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = safe_atou32(rvalue, &k);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Could not parse %s=, ignoring assignment: %s", lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (k == 0 || k >= 1024) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"Invalid %s=, ignoring assignment: %s", lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*window = k;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_route_metric_tcp_window(
|
||||
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_(route_free_or_set_invalidp) Route *route = NULL;
|
||||
Network *network = userdata;
|
||||
uint32_t *d;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(section);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = route_new_static(network, filename, section_line, &route);
|
||||
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;
|
||||
}
|
||||
|
||||
if (streq(lvalue, "InitialCongestionWindow"))
|
||||
d = &route->initcwnd;
|
||||
else if (streq(lvalue, "InitialAdvertisedReceiveWindow"))
|
||||
d = &route->initrwnd;
|
||||
else
|
||||
assert_not_reached();
|
||||
|
||||
r = config_parse_tcp_window(unit, filename, line, section, section_line, lvalue, ltype, rvalue, d, userdata);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
TAKE_PTR(route);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_route_metric_tcp_rto(
|
||||
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 *route = NULL;
|
||||
usec_t usec;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(section);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = route_new_static(network, filename, section_line, &route);
|
||||
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 = parse_sec(rvalue, &usec);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to parse %s=, ignoring assignment: %s", lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!timestamp_is_set(usec) ||
|
||||
DIV_ROUND_UP(usec, USEC_PER_MSEC) > UINT32_MAX) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"Invalid %s=, ignoring assignment: %s", lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
route->tcp_rto_usec = usec;
|
||||
|
||||
TAKE_PTR(route);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_route_metric_boolean(
|
||||
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 *route = NULL;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(section);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = route_new_static(network, filename, section_line, &route);
|
||||
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 = parse_boolean(rvalue);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Could not parse %s=, ignoring assignment: %s", lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (streq(lvalue, "QuickAck"))
|
||||
route->quickack = r;
|
||||
else if (streq(lvalue, "FastOpenNoCookie"))
|
||||
route->fast_open_no_cookie = r;
|
||||
else
|
||||
assert_not_reached();
|
||||
|
||||
TAKE_PTR(route);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_route_metric_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 *route = NULL;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(section);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = route_new_static(network, filename, section_line, &route);
|
||||
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, 0,
|
||||
rvalue, &route->tcp_congestion_control_algo, userdata);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
TAKE_PTR(route);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "conf-parser.h"
|
||||
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_route_metric_mtu);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_route_metric_advmss);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_route_metric_hop_limit);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_route_metric_tcp_window);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_route_metric_tcp_rto);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_route_metric_boolean);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_route_metric_tcp_congestion);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_tcp_window);
|
||||
@@ -0,0 +1,182 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <linux/nexthop.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "extract-word.h"
|
||||
#include "netlink-util.h"
|
||||
#include "networkd-route.h"
|
||||
#include "networkd-route-nexthop.h"
|
||||
#include "parse-util.h"
|
||||
#include "string-util.h"
|
||||
|
||||
int config_parse_route_nexthop(
|
||||
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 *route = NULL;
|
||||
uint32_t id;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(section);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = route_new_static(network, filename, section_line, &route);
|
||||
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;
|
||||
}
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
route->nexthop_id = 0;
|
||||
TAKE_PTR(route);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = safe_atou32(rvalue, &id);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse nexthop ID, ignoring assignment: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (id == 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid nexthop ID, ignoring assignment: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
route->nexthop_id = id;
|
||||
TAKE_PTR(route);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_multipath_route(
|
||||
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_(multipath_route_freep) MultipathRoute *m = NULL;
|
||||
_cleanup_(route_free_or_set_invalidp) Route *route = NULL;
|
||||
_cleanup_free_ char *word = NULL;
|
||||
Network *network = userdata;
|
||||
union in_addr_union a;
|
||||
int family, r;
|
||||
const char *p;
|
||||
char *dev;
|
||||
|
||||
assert(filename);
|
||||
assert(section);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = route_new_static(network, filename, section_line, &route);
|
||||
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;
|
||||
}
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
route->multipath_routes = ordered_set_free_with_destructor(route->multipath_routes, multipath_route_free);
|
||||
TAKE_PTR(route);
|
||||
return 0;
|
||||
}
|
||||
|
||||
m = new0(MultipathRoute, 1);
|
||||
if (!m)
|
||||
return log_oom();
|
||||
|
||||
p = rvalue;
|
||||
r = extract_first_word(&p, &word, NULL, 0);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r <= 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Invalid multipath route option, ignoring assignment: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev = strchr(word, '@');
|
||||
if (dev) {
|
||||
*dev++ = '\0';
|
||||
|
||||
r = parse_ifindex(dev);
|
||||
if (r > 0)
|
||||
m->ifindex = r;
|
||||
else {
|
||||
if (!ifname_valid_full(dev, IFNAME_VALID_ALTERNATIVE)) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"Invalid interface name '%s' in %s=, ignoring: %s", dev, lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
m->ifname = strdup(dev);
|
||||
if (!m->ifname)
|
||||
return log_oom();
|
||||
}
|
||||
}
|
||||
|
||||
r = in_addr_from_string_auto(word, &family, &a);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Invalid multipath route gateway '%s', ignoring assignment: %m", rvalue);
|
||||
return 0;
|
||||
}
|
||||
m->gateway.address = a;
|
||||
m->gateway.family = family;
|
||||
|
||||
if (!isempty(p)) {
|
||||
r = safe_atou32(p, &m->weight);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Invalid multipath route weight, ignoring assignment: %s", p);
|
||||
return 0;
|
||||
}
|
||||
/* ip command takes weight in the range 1…255, while kernel takes the value in the
|
||||
* range 0…254. MultiPathRoute= setting also takes weight in the same range which ip
|
||||
* command uses, then networkd decreases by one and stores it to match the range which
|
||||
* kernel uses. */
|
||||
if (m->weight == 0 || m->weight > 256) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"Invalid multipath route weight, ignoring assignment: %s", p);
|
||||
return 0;
|
||||
}
|
||||
m->weight--;
|
||||
}
|
||||
|
||||
r = ordered_set_ensure_put(&route->multipath_routes, NULL, m);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to store multipath route, ignoring assignment: %m");
|
||||
return 0;
|
||||
}
|
||||
|
||||
TAKE_PTR(m);
|
||||
TAKE_PTR(route);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "conf-parser.h"
|
||||
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_route_nexthop);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_multipath_route);
|
||||
+89
-605
@@ -45,7 +45,7 @@ int route_new(Route **ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int route_new_static(Network *network, const char *filename, unsigned section_line, Route **ret) {
|
||||
int route_new_static(Network *network, const char *filename, unsigned section_line, Route **ret) {
|
||||
_cleanup_(config_section_freep) ConfigSection *n = NULL;
|
||||
_cleanup_(route_freep) Route *route = NULL;
|
||||
int r;
|
||||
@@ -1930,7 +1930,7 @@ int manager_rtnl_process_route(sd_netlink *rtnl, sd_netlink_message *message, Ma
|
||||
}
|
||||
|
||||
int network_add_ipv4ll_route(Network *network) {
|
||||
_cleanup_(route_free_or_set_invalidp) Route *n = NULL;
|
||||
_cleanup_(route_free_or_set_invalidp) Route *route = NULL;
|
||||
unsigned section_line;
|
||||
int r;
|
||||
|
||||
@@ -1944,28 +1944,28 @@ int network_add_ipv4ll_route(Network *network) {
|
||||
return r;
|
||||
|
||||
/* IPv4LLRoute= is in [Network] section. */
|
||||
r = route_new_static(network, network->filename, section_line, &n);
|
||||
r = route_new_static(network, network->filename, section_line, &route);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = in_addr_from_string(AF_INET, "169.254.0.0", &n->dst);
|
||||
r = in_addr_from_string(AF_INET, "169.254.0.0", &route->dst);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
n->family = AF_INET;
|
||||
n->dst_prefixlen = 16;
|
||||
n->scope = RT_SCOPE_LINK;
|
||||
n->scope_set = true;
|
||||
n->table_set = true;
|
||||
n->priority = IPV4LL_ROUTE_METRIC;
|
||||
n->protocol = RTPROT_STATIC;
|
||||
route->family = AF_INET;
|
||||
route->dst_prefixlen = 16;
|
||||
route->scope = RT_SCOPE_LINK;
|
||||
route->scope_set = true;
|
||||
route->table_set = true;
|
||||
route->priority = IPV4LL_ROUTE_METRIC;
|
||||
route->protocol = RTPROT_STATIC;
|
||||
|
||||
TAKE_PTR(n);
|
||||
TAKE_PTR(route);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int network_add_default_route_on_device(Network *network) {
|
||||
_cleanup_(route_free_or_set_invalidp) Route *n = NULL;
|
||||
_cleanup_(route_free_or_set_invalidp) Route *route = NULL;
|
||||
unsigned section_line;
|
||||
int r;
|
||||
|
||||
@@ -1979,16 +1979,16 @@ int network_add_default_route_on_device(Network *network) {
|
||||
return r;
|
||||
|
||||
/* DefaultRouteOnDevice= is in [Network] section. */
|
||||
r = route_new_static(network, network->filename, section_line, &n);
|
||||
r = route_new_static(network, network->filename, section_line, &route);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
n->family = AF_INET;
|
||||
n->scope = RT_SCOPE_LINK;
|
||||
n->scope_set = true;
|
||||
n->protocol = RTPROT_STATIC;
|
||||
route->family = AF_INET;
|
||||
route->scope = RT_SCOPE_LINK;
|
||||
route->scope_set = true;
|
||||
route->protocol = RTPROT_STATIC;
|
||||
|
||||
TAKE_PTR(n);
|
||||
TAKE_PTR(route);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2005,7 +2005,7 @@ int config_parse_gateway(
|
||||
void *userdata) {
|
||||
|
||||
Network *network = userdata;
|
||||
_cleanup_(route_free_or_set_invalidp) Route *n = NULL;
|
||||
_cleanup_(route_free_or_set_invalidp) Route *route = NULL;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
@@ -2016,7 +2016,7 @@ int config_parse_gateway(
|
||||
|
||||
if (streq(section, "Network")) {
|
||||
/* we are not in an Route section, so use line number instead */
|
||||
r = route_new_static(network, filename, line, &n);
|
||||
r = route_new_static(network, filename, line, &route);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
@@ -2025,7 +2025,7 @@ int config_parse_gateway(
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
r = route_new_static(network, filename, section_line, &n);
|
||||
r = route_new_static(network, filename, section_line, &route);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
@@ -2035,43 +2035,43 @@ int config_parse_gateway(
|
||||
}
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
n->gateway_from_dhcp_or_ra = false;
|
||||
n->gw_family = AF_UNSPEC;
|
||||
n->gw = IN_ADDR_NULL;
|
||||
TAKE_PTR(n);
|
||||
route->gateway_from_dhcp_or_ra = false;
|
||||
route->gw_family = AF_UNSPEC;
|
||||
route->gw = IN_ADDR_NULL;
|
||||
TAKE_PTR(route);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (streq(rvalue, "_dhcp")) {
|
||||
n->gateway_from_dhcp_or_ra = true;
|
||||
TAKE_PTR(n);
|
||||
route->gateway_from_dhcp_or_ra = true;
|
||||
TAKE_PTR(route);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (streq(rvalue, "_dhcp4")) {
|
||||
n->gw_family = AF_INET;
|
||||
n->gateway_from_dhcp_or_ra = true;
|
||||
TAKE_PTR(n);
|
||||
route->gw_family = AF_INET;
|
||||
route->gateway_from_dhcp_or_ra = true;
|
||||
TAKE_PTR(route);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (streq(rvalue, "_ipv6ra")) {
|
||||
n->gw_family = AF_INET6;
|
||||
n->gateway_from_dhcp_or_ra = true;
|
||||
TAKE_PTR(n);
|
||||
route->gw_family = AF_INET6;
|
||||
route->gateway_from_dhcp_or_ra = true;
|
||||
TAKE_PTR(route);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
r = in_addr_from_string_auto(rvalue, &n->gw_family, &n->gw);
|
||||
r = in_addr_from_string_auto(rvalue, &route->gw_family, &route->gw);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Invalid %s='%s', ignoring assignment: %m", lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
n->gateway_from_dhcp_or_ra = false;
|
||||
TAKE_PTR(n);
|
||||
route->gateway_from_dhcp_or_ra = false;
|
||||
TAKE_PTR(route);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2088,7 +2088,7 @@ int config_parse_preferred_src(
|
||||
void *userdata) {
|
||||
|
||||
Network *network = userdata;
|
||||
_cleanup_(route_free_or_set_invalidp) Route *n = NULL;
|
||||
_cleanup_(route_free_or_set_invalidp) Route *route = NULL;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
@@ -2097,7 +2097,7 @@ int config_parse_preferred_src(
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = route_new_static(network, filename, section_line, &n);
|
||||
r = route_new_static(network, filename, section_line, &route);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
@@ -2106,17 +2106,17 @@ int config_parse_preferred_src(
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (n->family == AF_UNSPEC)
|
||||
r = in_addr_from_string_auto(rvalue, &n->family, &n->prefsrc);
|
||||
if (route->family == AF_UNSPEC)
|
||||
r = in_addr_from_string_auto(rvalue, &route->family, &route->prefsrc);
|
||||
else
|
||||
r = in_addr_from_string(n->family, rvalue, &n->prefsrc);
|
||||
r = in_addr_from_string(route->family, rvalue, &route->prefsrc);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, EINVAL,
|
||||
"Invalid %s='%s', ignoring assignment: %m", lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
TAKE_PTR(n);
|
||||
TAKE_PTR(route);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2133,7 +2133,7 @@ int config_parse_destination(
|
||||
void *userdata) {
|
||||
|
||||
Network *network = userdata;
|
||||
_cleanup_(route_free_or_set_invalidp) Route *n = NULL;
|
||||
_cleanup_(route_free_or_set_invalidp) Route *route = NULL;
|
||||
union in_addr_union *buffer;
|
||||
unsigned char *prefixlen;
|
||||
int r;
|
||||
@@ -2144,7 +2144,7 @@ int config_parse_destination(
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = route_new_static(network, filename, section_line, &n);
|
||||
r = route_new_static(network, filename, section_line, &route);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
@@ -2154,27 +2154,27 @@ int config_parse_destination(
|
||||
}
|
||||
|
||||
if (streq(lvalue, "Destination")) {
|
||||
buffer = &n->dst;
|
||||
prefixlen = &n->dst_prefixlen;
|
||||
buffer = &route->dst;
|
||||
prefixlen = &route->dst_prefixlen;
|
||||
} else if (streq(lvalue, "Source")) {
|
||||
buffer = &n->src;
|
||||
prefixlen = &n->src_prefixlen;
|
||||
buffer = &route->src;
|
||||
prefixlen = &route->src_prefixlen;
|
||||
} else
|
||||
assert_not_reached();
|
||||
|
||||
if (n->family == AF_UNSPEC)
|
||||
r = in_addr_prefix_from_string_auto(rvalue, &n->family, buffer, prefixlen);
|
||||
if (route->family == AF_UNSPEC)
|
||||
r = in_addr_prefix_from_string_auto(rvalue, &route->family, buffer, prefixlen);
|
||||
else
|
||||
r = in_addr_prefix_from_string(rvalue, n->family, buffer, prefixlen);
|
||||
r = in_addr_prefix_from_string(rvalue, route->family, buffer, prefixlen);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, EINVAL,
|
||||
"Invalid %s='%s', ignoring assignment: %m", lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
(void) in_addr_mask(n->family, buffer, *prefixlen);
|
||||
(void) in_addr_mask(route->family, buffer, *prefixlen);
|
||||
|
||||
TAKE_PTR(n);
|
||||
TAKE_PTR(route);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2191,7 +2191,7 @@ int config_parse_route_priority(
|
||||
void *userdata) {
|
||||
|
||||
Network *network = userdata;
|
||||
_cleanup_(route_free_or_set_invalidp) Route *n = NULL;
|
||||
_cleanup_(route_free_or_set_invalidp) Route *route = NULL;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
@@ -2200,7 +2200,7 @@ int config_parse_route_priority(
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = route_new_static(network, filename, section_line, &n);
|
||||
r = route_new_static(network, filename, section_line, &route);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
@@ -2209,15 +2209,15 @@ int config_parse_route_priority(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = safe_atou32(rvalue, &n->priority);
|
||||
r = safe_atou32(rvalue, &route->priority);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Could not parse route priority \"%s\", ignoring assignment: %m", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
n->priority_set = true;
|
||||
TAKE_PTR(n);
|
||||
route->priority_set = true;
|
||||
TAKE_PTR(route);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2234,7 +2234,7 @@ int config_parse_route_scope(
|
||||
void *userdata) {
|
||||
|
||||
Network *network = userdata;
|
||||
_cleanup_(route_free_or_set_invalidp) Route *n = NULL;
|
||||
_cleanup_(route_free_or_set_invalidp) Route *route = NULL;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
@@ -2243,7 +2243,7 @@ int config_parse_route_scope(
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = route_new_static(network, filename, section_line, &n);
|
||||
r = route_new_static(network, filename, section_line, &route);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
@@ -2258,62 +2258,9 @@ int config_parse_route_scope(
|
||||
return 0;
|
||||
}
|
||||
|
||||
n->scope = r;
|
||||
n->scope_set = true;
|
||||
TAKE_PTR(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_route_nexthop(
|
||||
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;
|
||||
uint32_t id;
|
||||
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;
|
||||
}
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
n->nexthop_id = 0;
|
||||
TAKE_PTR(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = safe_atou32(rvalue, &id);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse nexthop ID, ignoring assignment: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (id == 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid nexthop ID, ignoring assignment: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
n->nexthop_id = id;
|
||||
TAKE_PTR(n);
|
||||
route->scope = r;
|
||||
route->scope_set = true;
|
||||
TAKE_PTR(route);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2329,7 +2276,7 @@ int config_parse_route_table(
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
_cleanup_(route_free_or_set_invalidp) Route *n = NULL;
|
||||
_cleanup_(route_free_or_set_invalidp) Route *route = NULL;
|
||||
Network *network = userdata;
|
||||
int r;
|
||||
|
||||
@@ -2339,7 +2286,7 @@ int config_parse_route_table(
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = route_new_static(network, filename, section_line, &n);
|
||||
r = route_new_static(network, filename, section_line, &route);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
@@ -2348,19 +2295,19 @@ int config_parse_route_table(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = manager_get_route_table_from_string(network->manager, rvalue, &n->table);
|
||||
r = manager_get_route_table_from_string(network->manager, rvalue, &route->table);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Could not parse route table \"%s\", ignoring assignment: %m", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
n->table_set = true;
|
||||
TAKE_PTR(n);
|
||||
route->table_set = true;
|
||||
TAKE_PTR(route);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_route_boolean(
|
||||
int config_parse_route_gateway_onlink(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
@@ -2373,7 +2320,7 @@ int config_parse_route_boolean(
|
||||
void *userdata) {
|
||||
|
||||
Network *network = userdata;
|
||||
_cleanup_(route_free_or_set_invalidp) Route *n = NULL;
|
||||
_cleanup_(route_free_or_set_invalidp) Route *route = NULL;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
@@ -2382,7 +2329,7 @@ int config_parse_route_boolean(
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = route_new_static(network, filename, section_line, &n);
|
||||
r = route_new_static(network, filename, section_line, &route);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
@@ -2398,16 +2345,9 @@ int config_parse_route_boolean(
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (STR_IN_SET(lvalue, "GatewayOnLink", "GatewayOnlink"))
|
||||
n->gateway_onlink = r;
|
||||
else if (streq(lvalue, "QuickAck"))
|
||||
n->quickack = r;
|
||||
else if (streq(lvalue, "FastOpenNoCookie"))
|
||||
n->fast_open_no_cookie = r;
|
||||
else
|
||||
assert_not_reached();
|
||||
route->gateway_onlink = r;
|
||||
|
||||
TAKE_PTR(n);
|
||||
TAKE_PTR(route);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2424,10 +2364,10 @@ int config_parse_ipv6_route_preference(
|
||||
void *userdata) {
|
||||
|
||||
Network *network = userdata;
|
||||
_cleanup_(route_free_or_set_invalidp) Route *n = NULL;
|
||||
_cleanup_(route_free_or_set_invalidp) Route *route = NULL;
|
||||
int r;
|
||||
|
||||
r = route_new_static(network, filename, section_line, &n);
|
||||
r = route_new_static(network, filename, section_line, &route);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
@@ -2437,18 +2377,18 @@ int config_parse_ipv6_route_preference(
|
||||
}
|
||||
|
||||
if (streq(rvalue, "low"))
|
||||
n->pref = ICMPV6_ROUTER_PREF_LOW;
|
||||
route->pref = ICMPV6_ROUTER_PREF_LOW;
|
||||
else if (streq(rvalue, "medium"))
|
||||
n->pref = ICMPV6_ROUTER_PREF_MEDIUM;
|
||||
route->pref = ICMPV6_ROUTER_PREF_MEDIUM;
|
||||
else if (streq(rvalue, "high"))
|
||||
n->pref = ICMPV6_ROUTER_PREF_HIGH;
|
||||
route->pref = ICMPV6_ROUTER_PREF_HIGH;
|
||||
else {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0, "Unknown route preference: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
n->pref_set = true;
|
||||
TAKE_PTR(n);
|
||||
route->pref_set = true;
|
||||
TAKE_PTR(route);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2465,10 +2405,10 @@ int config_parse_route_protocol(
|
||||
void *userdata) {
|
||||
|
||||
Network *network = userdata;
|
||||
_cleanup_(route_free_or_set_invalidp) Route *n = NULL;
|
||||
_cleanup_(route_free_or_set_invalidp) Route *route = NULL;
|
||||
int r;
|
||||
|
||||
r = route_new_static(network, filename, section_line, &n);
|
||||
r = route_new_static(network, filename, section_line, &route);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
@@ -2484,9 +2424,9 @@ int config_parse_route_protocol(
|
||||
return 0;
|
||||
}
|
||||
|
||||
n->protocol = r;
|
||||
route->protocol = r;
|
||||
|
||||
TAKE_PTR(n);
|
||||
TAKE_PTR(route);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2503,10 +2443,10 @@ int config_parse_route_type(
|
||||
void *userdata) {
|
||||
|
||||
Network *network = userdata;
|
||||
_cleanup_(route_free_or_set_invalidp) Route *n = NULL;
|
||||
_cleanup_(route_free_or_set_invalidp) Route *route = NULL;
|
||||
int t, r;
|
||||
|
||||
r = route_new_static(network, filename, section_line, &n);
|
||||
r = route_new_static(network, filename, section_line, &route);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
@@ -2522,465 +2462,9 @@ int config_parse_route_type(
|
||||
return 0;
|
||||
}
|
||||
|
||||
n->type = (unsigned char) t;
|
||||
route->type = (unsigned char) t;
|
||||
|
||||
TAKE_PTR(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_route_hop_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_(route_free_or_set_invalidp) Route *n = NULL;
|
||||
Network *network = userdata;
|
||||
uint32_t k;
|
||||
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;
|
||||
}
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
n->hop_limit = 0;
|
||||
TAKE_PTR(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = safe_atou32(rvalue, &k);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Could not parse per route hop limit, ignoring assignment: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (k > 255) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"Specified per route hop limit \"%s\" is too large, ignoring assignment: %m", rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (k == 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"Invalid per route hop limit \"%s\", ignoring assignment: %m", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
n->hop_limit = k;
|
||||
|
||||
TAKE_PTR(n);
|
||||
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,
|
||||
unsigned line,
|
||||
const char *section,
|
||||
unsigned section_line,
|
||||
const char *lvalue,
|
||||
int ltype,
|
||||
const char *rvalue,
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
_cleanup_(route_free_or_set_invalidp) Route *n = NULL;
|
||||
Network *network = userdata;
|
||||
uint64_t u;
|
||||
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;
|
||||
}
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
n->advmss = 0;
|
||||
TAKE_PTR(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = parse_size(rvalue, 1024, &u);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Could not parse TCPAdvertisedMaximumSegmentSize= \"%s\", ignoring assignment: %m", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (u == 0 || u > UINT32_MAX) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"Invalid TCPAdvertisedMaximumSegmentSize= \"%s\", ignoring assignment: %m", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
n->advmss = u;
|
||||
|
||||
TAKE_PTR(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_tcp_window(
|
||||
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) {
|
||||
|
||||
uint32_t *window = ASSERT_PTR(data);
|
||||
uint32_t k;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(section);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
r = safe_atou32(rvalue, &k);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Could not parse TCP %s \"%s\", ignoring assignment: %m", lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (k >= 1024) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"Specified TCP %s \"%s\" is too large, ignoring assignment: %m", lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (k == 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"Invalid TCP %s \"%s\", ignoring assignment: %m", lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
*window = k;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_route_tcp_window(
|
||||
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_(route_free_or_set_invalidp) Route *n = NULL;
|
||||
Network *network = userdata;
|
||||
uint32_t *d;
|
||||
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;
|
||||
}
|
||||
|
||||
if (streq(lvalue, "InitialCongestionWindow"))
|
||||
d = &n->initcwnd;
|
||||
else if (streq(lvalue, "InitialAdvertisedReceiveWindow"))
|
||||
d = &n->initrwnd;
|
||||
else
|
||||
assert_not_reached();
|
||||
|
||||
r = config_parse_tcp_window(unit, filename, line, section, section_line, lvalue, ltype, rvalue, d, userdata);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
TAKE_PTR(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_route_mtu(
|
||||
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_mtu(unit, filename, line, section, section_line, lvalue, ltype, rvalue, &n->mtu, userdata);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
TAKE_PTR(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_route_tcp_rto(
|
||||
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;
|
||||
usec_t usec;
|
||||
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 = parse_sec(rvalue, &usec);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to parse route TCP retransmission timeout (RTO), ignoring assignment: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!timestamp_is_set(usec) ||
|
||||
DIV_ROUND_UP(usec, USEC_PER_MSEC) > UINT32_MAX) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"Route TCP retransmission timeout (RTO) must be in the range 0…%"PRIu32"ms, ignoring assignment: %s", UINT32_MAX, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
n->tcp_rto_usec = usec;
|
||||
|
||||
TAKE_PTR(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_multipath_route(
|
||||
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_(multipath_route_freep) MultipathRoute *m = NULL;
|
||||
_cleanup_(route_free_or_set_invalidp) Route *n = NULL;
|
||||
_cleanup_free_ char *word = NULL;
|
||||
Network *network = userdata;
|
||||
union in_addr_union a;
|
||||
int family, r;
|
||||
const char *p;
|
||||
char *dev;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
n->multipath_routes = ordered_set_free_with_destructor(n->multipath_routes, multipath_route_free);
|
||||
return 0;
|
||||
}
|
||||
|
||||
m = new0(MultipathRoute, 1);
|
||||
if (!m)
|
||||
return log_oom();
|
||||
|
||||
p = rvalue;
|
||||
r = extract_first_word(&p, &word, NULL, 0);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r <= 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Invalid multipath route option, ignoring assignment: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev = strchr(word, '@');
|
||||
if (dev) {
|
||||
*dev++ = '\0';
|
||||
|
||||
r = parse_ifindex(dev);
|
||||
if (r > 0)
|
||||
m->ifindex = r;
|
||||
else {
|
||||
if (!ifname_valid_full(dev, IFNAME_VALID_ALTERNATIVE)) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"Invalid interface name '%s' in %s=, ignoring: %s", dev, lvalue, rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
m->ifname = strdup(dev);
|
||||
if (!m->ifname)
|
||||
return log_oom();
|
||||
}
|
||||
}
|
||||
|
||||
r = in_addr_from_string_auto(word, &family, &a);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Invalid multipath route gateway '%s', ignoring assignment: %m", rvalue);
|
||||
return 0;
|
||||
}
|
||||
m->gateway.address = a;
|
||||
m->gateway.family = family;
|
||||
|
||||
if (!isempty(p)) {
|
||||
r = safe_atou32(p, &m->weight);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Invalid multipath route weight, ignoring assignment: %s", p);
|
||||
return 0;
|
||||
}
|
||||
/* ip command takes weight in the range 1…255, while kernel takes the value in the
|
||||
* range 0…254. MultiPathRoute= setting also takes weight in the same range which ip
|
||||
* command uses, then networkd decreases by one and stores it to match the range which
|
||||
* kernel uses. */
|
||||
if (m->weight == 0 || m->weight > 256) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"Invalid multipath route weight, ignoring assignment: %s", p);
|
||||
return 0;
|
||||
}
|
||||
m->weight--;
|
||||
}
|
||||
|
||||
r = ordered_set_ensure_put(&n->multipath_routes, NULL, m);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to store multipath route, ignoring assignment: %m");
|
||||
return 0;
|
||||
}
|
||||
|
||||
TAKE_PTR(m);
|
||||
TAKE_PTR(n);
|
||||
TAKE_PTR(route);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include "conf-parser.h"
|
||||
#include "in-addr-util.h"
|
||||
#include "networkd-link.h"
|
||||
#include "networkd-route-metric.h"
|
||||
#include "networkd-route-nexthop.h"
|
||||
#include "networkd-util.h"
|
||||
|
||||
typedef struct Manager Manager;
|
||||
@@ -80,6 +82,7 @@ struct Route {
|
||||
extern const struct hash_ops route_hash_ops;
|
||||
|
||||
int route_new(Route **ret);
|
||||
int route_new_static(Network *network, const char *filename, unsigned section_line, Route **ret);
|
||||
Route *route_free(Route *route);
|
||||
DEFINE_SECTION_CLEANUP_FUNCTIONS(Route, route_free);
|
||||
int route_dup(const Route *src, Route **ret);
|
||||
@@ -119,16 +122,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_destination);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_route_priority);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_route_scope);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_route_table);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_route_boolean);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_route_gateway_onlink);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_ipv6_route_preference);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_route_protocol);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_route_type);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_route_tcp_window);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_route_hop_limit);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_tcp_window);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_route_tcp_rto);
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user