Route.Type, config_parse_route_type, 0, 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.MTUBytes, config_parse_route_section, ROUTE_METRIC_MTU, 0
+Route.TCPAdvertisedMaximumSegmentSize, config_parse_route_section, ROUTE_METRIC_ADVMSS, 0
+Route.HopLimit, config_parse_route_section, ROUTE_METRIC_HOPLIMIT, 0
+Route.InitialCongestionWindow, config_parse_route_section, ROUTE_METRIC_INITCWND, 0
+Route.TCPRetransmissionTimeoutSec, config_parse_route_section, ROUTE_METRIC_RTO_MIN, 0
+Route.InitialAdvertisedReceiveWindow, config_parse_route_section, ROUTE_METRIC_INITRWND, 0
+Route.QuickAck, config_parse_route_section, ROUTE_METRIC_QUICKACK, 0
+Route.TCPCongestionControlAlgorithm, config_parse_route_section, ROUTE_METRIC_CC_ALGO, 0
+Route.FastOpenNoCookie, config_parse_route_section, ROUTE_METRIC_FASTOPEN_NO_COOKIE, 0
Route.TTLPropagate, config_parse_warn_compat, DISABLED_LEGACY, 0
NextHop.Id, config_parse_nexthop_section, NEXTHOP_ID, 0
NextHop.Gateway, config_parse_nexthop_section, NEXTHOP_GATEWAY, 0
return 0;
}
-static int config_parse_route_metric_advmss_impl(
+static int config_parse_route_metric_advmss(
const char *unit,
const char *filename,
unsigned line,
return 1;
}
-static int config_parse_route_metric_hop_limit_impl(
+static int config_parse_route_metric_hop_limit(
const char *unit,
const char *filename,
unsigned line,
return 1;
}
-static int config_parse_route_metric_tcp_rto_impl(
+static int config_parse_route_metric_tcp_rto(
const char *unit,
const char *filename,
unsigned line,
return 1;
}
-static int config_parse_route_metric_boolean_impl(
+static int config_parse_route_metric_boolean(
const char *unit,
const char *filename,
unsigned line,
return 1;
}
-#define DEFINE_CONFIG_PARSE_ROUTE_METRIC(name, parser) \
- int config_parse_route_metric_##name( \
- 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 = ASSERT_PTR(userdata); \
- _cleanup_(route_unref_or_set_invalidp) Route *route = NULL; \
- uint16_t attr_type = ltype; \
- int r; \
- \
- assert(filename); \
- assert(section); \
- assert(lvalue); \
- assert(rvalue); \
- \
- 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_metric_unset(&route->metric, attr_type); \
- TAKE_PTR(route); \
- return 0; \
- } \
- \
- uint32_t k; \
- r = parser(unit, filename, line, section, section_line, \
- lvalue, /* ltype = */ 0, rvalue, \
- &k, userdata); \
- if (r <= 0) \
- return r; \
- \
- if (route_metric_set_full( \
- &route->metric, \
- attr_type, \
- k, \
- /* force = */ true) < 0) \
- return log_oom(); \
- \
- TAKE_PTR(route); \
- return 0; \
- }
-
-DEFINE_CONFIG_PARSE_ROUTE_METRIC(mtu, config_parse_mtu);
-DEFINE_CONFIG_PARSE_ROUTE_METRIC(advmss, config_parse_route_metric_advmss_impl);
-DEFINE_CONFIG_PARSE_ROUTE_METRIC(hop_limit, config_parse_route_metric_hop_limit_impl);
-DEFINE_CONFIG_PARSE_ROUTE_METRIC(tcp_window, config_parse_tcp_window);
-DEFINE_CONFIG_PARSE_ROUTE_METRIC(tcp_rto, config_parse_route_metric_tcp_rto_impl);
-DEFINE_CONFIG_PARSE_ROUTE_METRIC(boolean, config_parse_route_metric_boolean_impl);
-
-int config_parse_route_metric_tcp_congestion(
+int config_parse_route_metric(
const char *unit,
const char *filename,
unsigned line,
void *data,
void *userdata) {
- Network *network = ASSERT_PTR(userdata);
- _cleanup_(route_unref_or_set_invalidp) Route *route = NULL;
+ static const ConfigSectionParser table[__RTAX_MAX] = {
+ [RTAX_MTU] = { .parser = config_parse_mtu, .ltype = 0, .offset = 0, },
+ [RTAX_ADVMSS] = { .parser = config_parse_route_metric_advmss, .ltype = 0, .offset = 0, },
+ [RTAX_HOPLIMIT] = { .parser = config_parse_route_metric_hop_limit, .ltype = 0, .offset = 0, },
+ [RTAX_INITCWND] = { .parser = config_parse_tcp_window, .ltype = 0, .offset = 0, },
+ [RTAX_RTO_MIN] = { .parser = config_parse_route_metric_tcp_rto, .ltype = 0, .offset = 0, },
+ [RTAX_INITRWND] = { .parser = config_parse_tcp_window, .ltype = 0, .offset = 0, },
+ [RTAX_QUICKACK] = { .parser = config_parse_route_metric_boolean, .ltype = 0, .offset = 0, },
+ [RTAX_FASTOPEN_NO_COOKIE] = { .parser = config_parse_route_metric_boolean, .ltype = 0, .offset = 0, },
+ };
+
+ Route *route = ASSERT_PTR(userdata);
int r;
- assert(filename);
- assert(rvalue);
-
- 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_metric_unset(&route->metric, ltype);
+ TAKE_PTR(route);
+ return 1;
}
- r = config_parse_string(unit, filename, line, section, section_line, lvalue, 0,
- rvalue, &route->metric.tcp_congestion_control_algo, userdata);
+ uint32_t k;
+ r = config_section_parse(table, ELEMENTSOF(table),
+ unit, filename, line, section, section_line, lvalue, ltype, rvalue, &k);
if (r <= 0)
return r;
- TAKE_PTR(route);
- return 0;
+ if (route_metric_set_full(
+ &route->metric,
+ ltype,
+ k,
+ /* force = */ true) < 0)
+ return log_oom();
+
+ return 1;
}
int route_metric_set_netlink_message(const RouteMetric *metric, sd_netlink_message *m);
int route_metric_read_netlink_message(RouteMetric *metric, sd_netlink_message *message);
-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_route_metric);
CONFIG_PARSER_PROTOTYPE(config_parse_tcp_window);
return 0;
}
+int config_parse_route_section(
+ 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) {
+
+ static const ConfigSectionParser table[_ROUTE_CONF_PARSER_MAX] = {
+ [ROUTE_METRIC_MTU] = { .parser = config_parse_route_metric, .ltype = RTAX_MTU, .offset = 0, },
+ [ROUTE_METRIC_ADVMSS] = { .parser = config_parse_route_metric, .ltype = RTAX_ADVMSS, .offset = 0, },
+ [ROUTE_METRIC_HOPLIMIT] = { .parser = config_parse_route_metric, .ltype = RTAX_HOPLIMIT, .offset = 0, },
+ [ROUTE_METRIC_INITCWND] = { .parser = config_parse_route_metric, .ltype = RTAX_INITCWND, .offset = 0, },
+ [ROUTE_METRIC_RTO_MIN] = { .parser = config_parse_route_metric, .ltype = RTAX_RTO_MIN, .offset = 0, },
+ [ROUTE_METRIC_INITRWND] = { .parser = config_parse_route_metric, .ltype = RTAX_INITRWND, .offset = 0, },
+ [ROUTE_METRIC_QUICKACK] = { .parser = config_parse_route_metric, .ltype = RTAX_QUICKACK, .offset = 0, },
+ [ROUTE_METRIC_CC_ALGO] = { .parser = config_parse_string, .ltype = 0, .offset = offsetof(Route, metric.tcp_congestion_control_algo), },
+ [ROUTE_METRIC_FASTOPEN_NO_COOKIE] = { .parser = config_parse_route_metric, .ltype = RTAX_FASTOPEN_NO_COOKIE, .offset = 0, },
+ };
+
+ _cleanup_(route_unref_or_set_invalidp) Route *route = NULL;
+ Network *network = ASSERT_PTR(userdata);
+ int r;
+
+ assert(filename);
+
+ 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_section_parse(table, ELEMENTSOF(table),
+ unit, filename, line, section, section_line, lvalue, ltype, rvalue, route);
+ if (r <= 0)
+ return r;
+
+ TAKE_PTR(route);
+ return 0;
+}
+
int route_section_verify(Route *route) {
int r;
DEFINE_NETWORK_CONFIG_STATE_FUNCTIONS(Route, route);
void manager_mark_routes(Manager *manager, Link *link, NetworkConfigSource source);
+typedef enum RouteConfParserType {
+ ROUTE_METRIC_MTU,
+ ROUTE_METRIC_ADVMSS,
+ ROUTE_METRIC_HOPLIMIT,
+ ROUTE_METRIC_INITCWND,
+ ROUTE_METRIC_RTO_MIN,
+ ROUTE_METRIC_INITRWND,
+ ROUTE_METRIC_QUICKACK,
+ ROUTE_METRIC_CC_ALGO,
+ ROUTE_METRIC_FASTOPEN_NO_COOKIE,
+ _ROUTE_CONF_PARSER_MAX,
+ _ROUTE_CONF_PARSER_INVALID = -EINVAL,
+} RouteConfParserType;
+
+CONFIG_PARSER_PROTOTYPE(config_parse_route_section);
CONFIG_PARSER_PROTOTYPE(config_parse_preferred_src);
CONFIG_PARSER_PROTOTYPE(config_parse_destination);
CONFIG_PARSER_PROTOTYPE(config_parse_route_priority);