1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 #include <linux/icmpv6.h>
5 #include "alloc-util.h"
6 #include "conf-parser.h"
7 #include "in-addr-util.h"
8 #include "missing_network.h"
9 #include "netlink-util.h"
10 #include "networkd-manager.h"
11 #include "networkd-route.h"
12 #include "parse-util.h"
14 #include "string-util.h"
15 #include "sysctl-util.h"
18 #define ROUTES_DEFAULT_MAX_PER_FAMILY 4096U
20 static unsigned routes_max(void) {
21 static thread_local
unsigned cached
= 0;
23 _cleanup_free_
char *s4
= NULL
, *s6
= NULL
;
24 unsigned val4
= ROUTES_DEFAULT_MAX_PER_FAMILY
, val6
= ROUTES_DEFAULT_MAX_PER_FAMILY
;
29 if (sysctl_read("net/ipv4/route/max_size", &s4
) >= 0) {
31 if (safe_atou(s4
, &val4
) >= 0 &&
33 /* This is the default "no limit" value in the kernel */
34 val4
= ROUTES_DEFAULT_MAX_PER_FAMILY
;
37 if (sysctl_read("net/ipv6/route/max_size", &s6
) >= 0) {
39 (void) safe_atou(s6
, &val6
);
42 cached
= MAX(ROUTES_DEFAULT_MAX_PER_FAMILY
, val4
) +
43 MAX(ROUTES_DEFAULT_MAX_PER_FAMILY
, val6
);
47 int route_new(Route
**ret
) {
48 _cleanup_(route_freep
) Route
*route
= NULL
;
50 route
= new(Route
, 1);
56 .scope
= RT_SCOPE_UNIVERSE
,
57 .protocol
= RTPROT_UNSPEC
,
59 .table
= RT_TABLE_MAIN
,
60 .lifetime
= USEC_INFINITY
,
64 *ret
= TAKE_PTR(route
);
69 int route_new_static(Network
*network
, const char *filename
, unsigned section_line
, Route
**ret
) {
70 _cleanup_(network_config_section_freep
) NetworkConfigSection
*n
= NULL
;
71 _cleanup_(route_freep
) Route
*route
= NULL
;
76 assert(!!filename
== (section_line
> 0));
79 r
= network_config_section_new(filename
, section_line
, &n
);
83 route
= hashmap_get(network
->routes_by_section
, n
);
85 *ret
= TAKE_PTR(route
);
91 if (network
->n_static_routes
>= routes_max())
94 r
= route_new(&route
);
98 route
->protocol
= RTPROT_STATIC
;
99 route
->network
= network
;
100 LIST_PREPEND(routes
, network
->static_routes
, route
);
101 network
->n_static_routes
++;
104 route
->section
= TAKE_PTR(n
);
106 r
= hashmap_ensure_allocated(&network
->routes_by_section
, &network_config_hash_ops
);
110 r
= hashmap_put(network
->routes_by_section
, route
->section
, route
);
115 *ret
= TAKE_PTR(route
);
120 void route_free(Route
*route
) {
124 if (route
->network
) {
125 LIST_REMOVE(routes
, route
->network
->static_routes
, route
);
127 assert(route
->network
->n_static_routes
> 0);
128 route
->network
->n_static_routes
--;
131 hashmap_remove(route
->network
->routes_by_section
, route
->section
);
134 network_config_section_free(route
->section
);
137 set_remove(route
->link
->routes
, route
);
138 set_remove(route
->link
->routes_foreign
, route
);
141 sd_event_source_unref(route
->expire
);
146 static void route_hash_func(const Route
*route
, struct siphash
*state
) {
149 siphash24_compress(&route
->family
, sizeof(route
->family
), state
);
151 switch (route
->family
) {
154 /* Equality of routes are given by the 4-touple
155 (dst_prefix,dst_prefixlen,tos,priority,table) */
156 siphash24_compress(&route
->dst
, FAMILY_ADDRESS_SIZE(route
->family
), state
);
157 siphash24_compress(&route
->dst_prefixlen
, sizeof(route
->dst_prefixlen
), state
);
158 siphash24_compress(&route
->tos
, sizeof(route
->tos
), state
);
159 siphash24_compress(&route
->priority
, sizeof(route
->priority
), state
);
160 siphash24_compress(&route
->table
, sizeof(route
->table
), state
);
164 /* treat any other address family as AF_UNSPEC */
169 static int route_compare_func(const Route
*a
, const Route
*b
) {
172 r
= CMP(a
->family
, b
->family
);
179 r
= CMP(a
->dst_prefixlen
, b
->dst_prefixlen
);
183 r
= CMP(a
->tos
, b
->tos
);
187 r
= CMP(a
->priority
, b
->priority
);
191 r
= CMP(a
->table
, b
->table
);
195 return memcmp(&a
->dst
, &b
->dst
, FAMILY_ADDRESS_SIZE(a
->family
));
197 /* treat any other address family as AF_UNSPEC */
202 DEFINE_PRIVATE_HASH_OPS(route_hash_ops
, Route
, route_hash_func
, route_compare_func
);
204 bool route_equal(Route
*r1
, Route
*r2
) {
211 return route_compare_func(r1
, r2
) == 0;
214 int route_get(Link
*link
,
216 const union in_addr_union
*dst
,
217 unsigned char dst_prefixlen
,
223 Route route
, *existing
;
231 .dst_prefixlen
= dst_prefixlen
,
233 .priority
= priority
,
237 existing
= set_get(link
->routes
, &route
);
244 existing
= set_get(link
->routes_foreign
, &route
);
254 static int route_add_internal(
258 const union in_addr_union
*dst
,
259 unsigned char dst_prefixlen
,
265 _cleanup_(route_freep
) Route
*route
= NULL
;
272 r
= route_new(&route
);
276 route
->family
= family
;
278 route
->dst_prefixlen
= dst_prefixlen
;
280 route
->priority
= priority
;
281 route
->table
= table
;
283 r
= set_ensure_allocated(routes
, &route_hash_ops
);
287 r
= set_put(*routes
, route
);
301 int route_add_foreign(
304 const union in_addr_union
*dst
,
305 unsigned char dst_prefixlen
,
311 return route_add_internal(link
, &link
->routes_foreign
, family
, dst
, dst_prefixlen
, tos
, priority
, table
, ret
);
314 int route_add(Link
*link
,
316 const union in_addr_union
*dst
,
317 unsigned char dst_prefixlen
,
326 r
= route_get(link
, family
, dst
, dst_prefixlen
, tos
, priority
, table
, &route
);
328 /* Route does not exist, create a new one */
329 r
= route_add_internal(link
, &link
->routes
, family
, dst
, dst_prefixlen
, tos
, priority
, table
, &route
);
333 /* Take over a foreign route */
334 r
= set_ensure_allocated(&link
->routes
, &route_hash_ops
);
338 r
= set_put(link
->routes
, route
);
342 set_remove(link
->routes_foreign
, route
);
344 /* Route exists, do nothing */
355 void route_update(Route
*route
,
356 const union in_addr_union
*src
,
357 unsigned char src_prefixlen
,
358 const union in_addr_union
*gw
,
359 const union in_addr_union
*prefsrc
,
361 unsigned char protocol
,
362 unsigned char type
) {
365 assert(src
|| src_prefixlen
== 0);
367 route
->src
= src
? *src
: IN_ADDR_NULL
;
368 route
->src_prefixlen
= src_prefixlen
;
369 route
->gw
= gw
? *gw
: IN_ADDR_NULL
;
370 route
->prefsrc
= prefsrc
? *prefsrc
: IN_ADDR_NULL
;
371 route
->scope
= scope
;
372 route
->protocol
= protocol
;
376 static int route_remove_handler(sd_netlink
*rtnl
, sd_netlink_message
*m
, Link
*link
) {
381 assert(link
->ifname
);
383 if (IN_SET(link
->state
, LINK_STATE_FAILED
, LINK_STATE_LINGER
))
386 r
= sd_netlink_message_get_errno(m
);
387 if (r
< 0 && r
!= -ESRCH
)
388 log_link_warning_errno(link
, r
, "Could not drop route: %m");
393 int route_remove(Route
*route
, Link
*link
,
394 link_netlink_message_handler_t callback
) {
396 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*req
= NULL
;
400 assert(link
->manager
);
401 assert(link
->manager
->rtnl
);
402 assert(link
->ifindex
> 0);
403 assert(IN_SET(route
->family
, AF_INET
, AF_INET6
));
405 r
= sd_rtnl_message_new_route(link
->manager
->rtnl
, &req
,
406 RTM_DELROUTE
, route
->family
,
409 return log_error_errno(r
, "Could not create RTM_DELROUTE message: %m");
411 if (in_addr_is_null(route
->family
, &route
->gw
) == 0) {
412 r
= netlink_message_append_in_addr_union(req
, RTA_GATEWAY
, route
->family
, &route
->gw
);
414 return log_error_errno(r
, "Could not append RTA_GATEWAY attribute: %m");
417 if (route
->dst_prefixlen
) {
418 r
= netlink_message_append_in_addr_union(req
, RTA_DST
, route
->family
, &route
->dst
);
420 return log_error_errno(r
, "Could not append RTA_DST attribute: %m");
422 r
= sd_rtnl_message_route_set_dst_prefixlen(req
, route
->dst_prefixlen
);
424 return log_error_errno(r
, "Could not set destination prefix length: %m");
427 if (route
->src_prefixlen
) {
428 r
= netlink_message_append_in_addr_union(req
, RTA_SRC
, route
->family
, &route
->src
);
430 return log_error_errno(r
, "Could not append RTA_SRC attribute: %m");
432 r
= sd_rtnl_message_route_set_src_prefixlen(req
, route
->src_prefixlen
);
434 return log_error_errno(r
, "Could not set source prefix length: %m");
437 if (in_addr_is_null(route
->family
, &route
->prefsrc
) == 0) {
438 r
= netlink_message_append_in_addr_union(req
, RTA_PREFSRC
, route
->family
, &route
->prefsrc
);
440 return log_error_errno(r
, "Could not append RTA_PREFSRC attribute: %m");
443 r
= sd_rtnl_message_route_set_scope(req
, route
->scope
);
445 return log_error_errno(r
, "Could not set scope: %m");
447 r
= sd_netlink_message_append_u32(req
, RTA_PRIORITY
, route
->priority
);
449 return log_error_errno(r
, "Could not append RTA_PRIORITY attribute: %m");
451 if (!IN_SET(route
->type
, RTN_UNREACHABLE
, RTN_PROHIBIT
, RTN_BLACKHOLE
, RTN_THROW
)) {
452 r
= sd_netlink_message_append_u32(req
, RTA_OIF
, link
->ifindex
);
454 return log_error_errno(r
, "Could not append RTA_OIF attribute: %m");
457 r
= netlink_call_async(link
->manager
->rtnl
, NULL
, req
,
458 callback
?: route_remove_handler
,
459 link_netlink_destroy_callback
, link
);
461 return log_error_errno(r
, "Could not send rtnetlink message: %m");
468 int route_expire_handler(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
469 Route
*route
= userdata
;
474 r
= route_remove(route
, route
->link
, NULL
);
476 log_warning_errno(r
, "Could not remove route: %m");
486 link_netlink_message_handler_t callback
) {
488 _cleanup_(sd_netlink_message_unrefp
) sd_netlink_message
*req
= NULL
;
489 _cleanup_(sd_event_source_unrefp
) sd_event_source
*expire
= NULL
;
494 assert(link
->manager
);
495 assert(link
->manager
->rtnl
);
496 assert(link
->ifindex
> 0);
497 assert(IN_SET(route
->family
, AF_INET
, AF_INET6
));
500 if (route_get(link
, route
->family
, &route
->dst
, route
->dst_prefixlen
, route
->tos
, route
->priority
, route
->table
, NULL
) <= 0 &&
501 set_size(link
->routes
) >= routes_max())
505 _cleanup_free_
char *dst
= NULL
, *dst_prefixlen
= NULL
, *src
= NULL
, *gw
= NULL
, *prefsrc
= NULL
;
507 if (!in_addr_is_null(route
->family
, &route
->dst
)) {
508 (void) in_addr_to_string(route
->family
, &route
->dst
, &dst
);
509 (void) asprintf(&dst_prefixlen
, "/%u", route
->dst_prefixlen
);
511 if (!in_addr_is_null(route
->family
, &route
->src
))
512 (void) in_addr_to_string(route
->family
, &route
->src
, &src
);
513 if (!in_addr_is_null(route
->family
, &route
->gw
))
514 (void) in_addr_to_string(route
->family
, &route
->gw
, &gw
);
515 if (!in_addr_is_null(route
->family
, &route
->prefsrc
))
516 (void) in_addr_to_string(route
->family
, &route
->prefsrc
, &prefsrc
);
518 log_link_debug(link
, "Configuring route: dst: %s%s, src: %s, gw: %s, prefsrc: %s",
519 strna(dst
), strempty(dst_prefixlen
), strna(src
), strna(gw
), strna(prefsrc
));
522 r
= sd_rtnl_message_new_route(link
->manager
->rtnl
, &req
,
523 RTM_NEWROUTE
, route
->family
,
526 return log_error_errno(r
, "Could not create RTM_NEWROUTE message: %m");
528 if (in_addr_is_null(route
->family
, &route
->gw
) == 0) {
529 r
= netlink_message_append_in_addr_union(req
, RTA_GATEWAY
, route
->family
, &route
->gw
);
531 return log_error_errno(r
, "Could not append RTA_GATEWAY attribute: %m");
533 r
= sd_rtnl_message_route_set_family(req
, route
->family
);
535 return log_error_errno(r
, "Could not set route family: %m");
538 if (route
->dst_prefixlen
) {
539 r
= netlink_message_append_in_addr_union(req
, RTA_DST
, route
->family
, &route
->dst
);
541 return log_error_errno(r
, "Could not append RTA_DST attribute: %m");
543 r
= sd_rtnl_message_route_set_dst_prefixlen(req
, route
->dst_prefixlen
);
545 return log_error_errno(r
, "Could not set destination prefix length: %m");
548 if (route
->src_prefixlen
) {
549 r
= netlink_message_append_in_addr_union(req
, RTA_SRC
, route
->family
, &route
->src
);
551 return log_error_errno(r
, "Could not append RTA_SRC attribute: %m");
553 r
= sd_rtnl_message_route_set_src_prefixlen(req
, route
->src_prefixlen
);
555 return log_error_errno(r
, "Could not set source prefix length: %m");
558 if (in_addr_is_null(route
->family
, &route
->prefsrc
) == 0) {
559 r
= netlink_message_append_in_addr_union(req
, RTA_PREFSRC
, route
->family
, &route
->prefsrc
);
561 return log_error_errno(r
, "Could not append RTA_PREFSRC attribute: %m");
564 r
= sd_rtnl_message_route_set_scope(req
, route
->scope
);
566 return log_error_errno(r
, "Could not set scope: %m");
568 r
= sd_rtnl_message_route_set_flags(req
, route
->flags
);
570 return log_error_errno(r
, "Could not set flags: %m");
572 if (route
->table
!= RT_TABLE_MAIN
) {
573 if (route
->table
< 256) {
574 r
= sd_rtnl_message_route_set_table(req
, route
->table
);
576 return log_error_errno(r
, "Could not set route table: %m");
578 r
= sd_rtnl_message_route_set_table(req
, RT_TABLE_UNSPEC
);
580 return log_error_errno(r
, "Could not set route table: %m");
582 /* Table attribute to allow more than 256. */
583 r
= sd_netlink_message_append_data(req
, RTA_TABLE
, &route
->table
, sizeof(route
->table
));
585 return log_error_errno(r
, "Could not append RTA_TABLE attribute: %m");
589 r
= sd_netlink_message_append_u32(req
, RTA_PRIORITY
, route
->priority
);
591 return log_error_errno(r
, "Could not append RTA_PRIORITY attribute: %m");
593 r
= sd_netlink_message_append_u8(req
, RTA_PREF
, route
->pref
);
595 return log_error_errno(r
, "Could not append RTA_PREF attribute: %m");
597 if (route
->lifetime
!= USEC_INFINITY
&& kernel_route_expiration_supported()) {
598 r
= sd_netlink_message_append_u32(req
, RTA_EXPIRES
,
599 DIV_ROUND_UP(usec_sub_unsigned(route
->lifetime
, now(clock_boottime_or_monotonic())), USEC_PER_SEC
));
601 return log_error_errno(r
, "Could not append RTA_EXPIRES attribute: %m");
604 r
= sd_rtnl_message_route_set_type(req
, route
->type
);
606 return log_error_errno(r
, "Could not set route type: %m");
608 if (!IN_SET(route
->type
, RTN_UNREACHABLE
, RTN_PROHIBIT
, RTN_BLACKHOLE
, RTN_THROW
)) {
609 r
= sd_netlink_message_append_u32(req
, RTA_OIF
, link
->ifindex
);
611 return log_error_errno(r
, "Could not append RTA_OIF attribute: %m");
614 r
= sd_netlink_message_open_container(req
, RTA_METRICS
);
616 return log_error_errno(r
, "Could not append RTA_METRICS attribute: %m");
618 if (route
->mtu
> 0) {
619 r
= sd_netlink_message_append_u32(req
, RTAX_MTU
, route
->mtu
);
621 return log_error_errno(r
, "Could not append RTAX_MTU attribute: %m");
624 if (route
->initcwnd
> 0) {
625 r
= sd_netlink_message_append_u32(req
, RTAX_INITCWND
, route
->initcwnd
);
627 return log_error_errno(r
, "Could not append RTAX_INITCWND attribute: %m");
630 if (route
->initrwnd
> 0) {
631 r
= sd_netlink_message_append_u32(req
, RTAX_INITRWND
, route
->initrwnd
);
633 return log_error_errno(r
, "Could not append RTAX_INITRWND attribute: %m");
636 if (route
->quickack
!= -1) {
637 r
= sd_netlink_message_append_u32(req
, RTAX_QUICKACK
, route
->quickack
);
639 return log_error_errno(r
, "Could not append RTAX_QUICKACK attribute: %m");
642 r
= sd_netlink_message_close_container(req
);
644 return log_error_errno(r
, "Could not append RTA_METRICS attribute: %m");
646 r
= netlink_call_async(link
->manager
->rtnl
, NULL
, req
, callback
,
647 link_netlink_destroy_callback
, link
);
649 return log_error_errno(r
, "Could not send rtnetlink message: %m");
653 lifetime
= route
->lifetime
;
655 r
= route_add(link
, route
->family
, &route
->dst
, route
->dst_prefixlen
, route
->tos
, route
->priority
, route
->table
, &route
);
657 return log_error_errno(r
, "Could not add route: %m");
659 /* TODO: drop expiration handling once it can be pushed into the kernel */
660 route
->lifetime
= lifetime
;
662 if (route
->lifetime
!= USEC_INFINITY
&& !kernel_route_expiration_supported()) {
663 r
= sd_event_add_time(link
->manager
->event
, &expire
, clock_boottime_or_monotonic(),
664 route
->lifetime
, 0, route_expire_handler
, route
);
666 return log_error_errno(r
, "Could not arm expiration timer: %m");
669 sd_event_source_unref(route
->expire
);
670 route
->expire
= TAKE_PTR(expire
);
675 int config_parse_gateway(
677 const char *filename
,
680 unsigned section_line
,
687 Network
*network
= userdata
;
688 _cleanup_(route_freep
) Route
*n
= NULL
;
697 if (streq(section
, "Network")) {
698 /* we are not in an Route section, so treat
699 * this as the special '0' section */
700 r
= route_new_static(network
, NULL
, 0, &n
);
702 r
= route_new_static(network
, filename
, section_line
, &n
);
707 r
= in_addr_from_string_auto(rvalue
, &n
->family
, &n
->gw
);
709 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Route is invalid, ignoring assignment: %s", rvalue
);
718 int config_parse_preferred_src(
720 const char *filename
,
723 unsigned section_line
,
730 Network
*network
= userdata
;
731 _cleanup_(route_freep
) Route
*n
= NULL
;
740 r
= route_new_static(network
, filename
, section_line
, &n
);
744 r
= in_addr_from_string_auto(rvalue
, &n
->family
, &n
->prefsrc
);
746 log_syntax(unit
, LOG_ERR
, filename
, line
, EINVAL
,
747 "Preferred source is invalid, ignoring assignment: %s", rvalue
);
756 int config_parse_destination(
758 const char *filename
,
761 unsigned section_line
,
768 Network
*network
= userdata
;
769 _cleanup_(route_freep
) Route
*n
= NULL
;
770 union in_addr_union
*buffer
;
771 unsigned char *prefixlen
;
780 r
= route_new_static(network
, filename
, section_line
, &n
);
784 if (streq(lvalue
, "Destination")) {
786 prefixlen
= &n
->dst_prefixlen
;
787 } else if (streq(lvalue
, "Source")) {
789 prefixlen
= &n
->src_prefixlen
;
791 assert_not_reached(lvalue
);
793 r
= in_addr_prefix_from_string_auto(rvalue
, &n
->family
, buffer
, prefixlen
);
795 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
796 "Route %s= prefix is invalid, ignoring assignment: %s",
805 int config_parse_route_priority(
807 const char *filename
,
810 unsigned section_line
,
817 Network
*network
= userdata
;
818 _cleanup_(route_freep
) Route
*n
= NULL
;
827 r
= route_new_static(network
, filename
, section_line
, &n
);
831 r
= safe_atou32(rvalue
, &n
->priority
);
833 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
834 "Could not parse route priority \"%s\", ignoring assignment: %m", rvalue
);
842 int config_parse_route_scope(
844 const char *filename
,
847 unsigned section_line
,
854 Network
*network
= userdata
;
855 _cleanup_(route_freep
) Route
*n
= NULL
;
864 r
= route_new_static(network
, filename
, section_line
, &n
);
868 if (streq(rvalue
, "host"))
869 n
->scope
= RT_SCOPE_HOST
;
870 else if (streq(rvalue
, "link"))
871 n
->scope
= RT_SCOPE_LINK
;
872 else if (streq(rvalue
, "global"))
873 n
->scope
= RT_SCOPE_UNIVERSE
;
875 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Unknown route scope: %s", rvalue
);
883 int config_parse_route_table(
885 const char *filename
,
888 unsigned section_line
,
895 _cleanup_(route_freep
) Route
*n
= NULL
;
896 Network
*network
= userdata
;
905 r
= route_new_static(network
, filename
, section_line
, &n
);
909 r
= safe_atou32(rvalue
, &n
->table
);
911 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
912 "Could not parse route table number \"%s\", ignoring assignment: %m", rvalue
);
920 int config_parse_gateway_onlink(
922 const char *filename
,
925 unsigned section_line
,
932 Network
*network
= userdata
;
933 _cleanup_(route_freep
) Route
*n
= NULL
;
942 r
= route_new_static(network
, filename
, section_line
, &n
);
946 r
= parse_boolean(rvalue
);
948 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
949 "Could not parse gateway onlink \"%s\", ignoring assignment: %m", rvalue
);
953 SET_FLAG(n
->flags
, RTNH_F_ONLINK
, r
);
958 int config_parse_ipv6_route_preference(
960 const char *filename
,
963 unsigned section_line
,
970 Network
*network
= userdata
;
971 _cleanup_(route_freep
) Route
*n
= NULL
;
974 r
= route_new_static(network
, filename
, section_line
, &n
);
978 if (streq(rvalue
, "low"))
979 n
->pref
= ICMPV6_ROUTER_PREF_LOW
;
980 else if (streq(rvalue
, "medium"))
981 n
->pref
= ICMPV6_ROUTER_PREF_MEDIUM
;
982 else if (streq(rvalue
, "high"))
983 n
->pref
= ICMPV6_ROUTER_PREF_HIGH
;
985 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Unknown route preference: %s", rvalue
);
993 int config_parse_route_protocol(
995 const char *filename
,
998 unsigned section_line
,
1005 Network
*network
= userdata
;
1006 _cleanup_(route_freep
) Route
*n
= NULL
;
1009 r
= route_new_static(network
, filename
, section_line
, &n
);
1013 if (streq(rvalue
, "kernel"))
1014 n
->protocol
= RTPROT_KERNEL
;
1015 else if (streq(rvalue
, "boot"))
1016 n
->protocol
= RTPROT_BOOT
;
1017 else if (streq(rvalue
, "static"))
1018 n
->protocol
= RTPROT_STATIC
;
1020 r
= safe_atou8(rvalue
, &n
->protocol
);
1022 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Could not parse route protocol \"%s\", ignoring assignment: %m", rvalue
);
1031 int config_parse_route_type(
1033 const char *filename
,
1035 const char *section
,
1036 unsigned section_line
,
1043 Network
*network
= userdata
;
1044 _cleanup_(route_freep
) Route
*n
= NULL
;
1047 r
= route_new_static(network
, filename
, section_line
, &n
);
1051 if (streq(rvalue
, "unicast"))
1052 n
->type
= RTN_UNICAST
;
1053 else if (streq(rvalue
, "blackhole"))
1054 n
->type
= RTN_BLACKHOLE
;
1055 else if (streq(rvalue
, "unreachable"))
1056 n
->type
= RTN_UNREACHABLE
;
1057 else if (streq(rvalue
, "prohibit"))
1058 n
->type
= RTN_PROHIBIT
;
1059 else if (streq(rvalue
, "throw"))
1060 n
->type
= RTN_THROW
;
1062 log_syntax(unit
, LOG_ERR
, filename
, line
, r
, "Could not parse route type \"%s\", ignoring assignment: %m", rvalue
);
1070 int config_parse_tcp_window(
1072 const char *filename
,
1074 const char *section
,
1075 unsigned section_line
,
1082 _cleanup_(route_freep
) Route
*n
= NULL
;
1083 Network
*network
= userdata
;
1093 r
= route_new_static(network
, filename
, section_line
, &n
);
1097 r
= parse_size(rvalue
, 1024, &k
);
1098 if (r
< 0 || k
> UINT32_MAX
) {
1099 log_syntax(unit
, LOG_ERR
, filename
, line
, r
,
1100 "Could not parse TCP %s \"%s\" bytes, ignoring assignment: %m", rvalue
, lvalue
);
1104 if (streq(lvalue
, "InitialCongestionWindow"))
1106 else if (streq(lvalue
, "InitialAdvertisedReceiveWindow"))
1109 log_syntax(unit
, LOG_ERR
, filename
, line
, 0, "Failed to parse TCP %s: %s", lvalue
, rvalue
);
1117 int config_parse_quickack(
1119 const char *filename
,
1121 const char *section
,
1122 unsigned section_line
,
1129 _cleanup_(route_freep
) Route
*n
= NULL
;
1130 Network
*network
= userdata
;
1139 r
= route_new_static(network
, filename
, section_line
, &n
);
1143 k
= parse_boolean(rvalue
);
1145 log_syntax(unit
, LOG_ERR
, filename
, line
, k
, "Failed to parse TCP quickack, ignoring: %s", rvalue
);
1154 int config_parse_route_mtu(
1156 const char *filename
,
1158 const char *section
,
1159 unsigned section_line
,
1166 Network
*network
= userdata
;
1167 _cleanup_(route_freep
) Route
*n
= NULL
;
1176 r
= route_new_static(network
, filename
, section_line
, &n
);
1180 r
= config_parse_mtu(unit
, filename
, line
, section
, section_line
, lvalue
, ltype
, rvalue
, &n
->mtu
, userdata
);