From 807341ec99b946e2ec27f43d27b9ae345a137d4c Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 14 May 2019 17:58:20 +0900 Subject: [PATCH 1/4] network: add missing error check --- src/network/networkd-ipv4ll.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/network/networkd-ipv4ll.c b/src/network/networkd-ipv4ll.c index 8fb8a64e6d..9df5646a7e 100644 --- a/src/network/networkd-ipv4ll.c +++ b/src/network/networkd-ipv4ll.c @@ -34,7 +34,9 @@ static int ipv4ll_address_lost(Link *link) { address->prefixlen = 16; address->scope = RT_SCOPE_LINK; - address_remove(address, link, NULL); + r = address_remove(address, link, NULL); + if (r < 0) + return r; r = route_new(&route); if (r < 0) @@ -44,7 +46,9 @@ static int ipv4ll_address_lost(Link *link) { route->scope = RT_SCOPE_LINK; route->priority = IPV4LL_ROUTE_METRIC; - route_remove(route, link, NULL); + r = route_remove(route, link, NULL); + if (r < 0) + return r; link_check_ready(link); From 5d5003ab355154fea5a332068e725fbbdf9385d3 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 14 May 2019 16:43:14 +0900 Subject: [PATCH 2/4] network: add DefaultRouteOnDevice= setting in [Network] section When enabled, then default route bound to the interface will be created. This is useful when adding routes on point-to-point interfaces. Closes #788. --- man/systemd.network.xml | 9 +++++++ src/network/networkd-network-gperf.gperf | 1 + src/network/networkd-network.c | 5 ++++ src/network/networkd-network.h | 2 ++ src/network/networkd-route.c | 24 +++++++++++++++++++ src/network/networkd-route.h | 1 + .../fuzz-network-parser/directives.network | 1 + 7 files changed, 43 insertions(+) diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 2ce7c7096e..dd0535a06e 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -347,6 +347,15 @@ + + DefaultRouteOnDevice= + + Takes a boolean. If set to true, sets up the default route bound to the interface. + Defaults to false. This is useful when creating routes on point-to-point interfaces. + This is equivalent to e.g. the following. + ip route add default dev veth99 + + IPv6Token= diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index f87d7def44..3c6b5ac100 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -53,6 +53,7 @@ Network.DHCP, config_parse_dhcp, Network.DHCPServer, config_parse_bool, 0, offsetof(Network, dhcp_server) Network.LinkLocalAddressing, config_parse_link_local_address_family_boolean, 0, offsetof(Network, link_local) Network.IPv4LLRoute, config_parse_bool, 0, offsetof(Network, ipv4ll_route) +Network.DefaultRouteOnDevice, config_parse_bool, 0, offsetof(Network, default_route_on_device) Network.IPv6Token, config_parse_ipv6token, 0, offsetof(Network, ipv6_token) Network.LLDP, config_parse_lldp_mode, 0, offsetof(Network, lldp_mode) Network.EmitLLDP, config_parse_lldp_emit, 0, offsetof(Network, lldp_emit) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 56a45379c1..755cd604dc 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -454,6 +454,11 @@ int network_load_one(Manager *manager, const char *filename) { if (r < 0) log_warning_errno(r, "%s: Failed to add IPv4LL route, ignoring: %m", network->filename); + r = network_add_default_route_on_device(network); + if (r < 0) + log_warning_errno(r, "%s: Failed to add default route on device, ignoring: %m", + network->filename); + r = ordered_hashmap_ensure_allocated(&manager->networks, &string_hash_ops); if (r < 0) return r; diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index d00062fe59..22c7dc5afd 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -151,6 +151,8 @@ struct Network { AddressFamilyBoolean link_local; bool ipv4ll_route; + bool default_route_on_device; + /* IPv6 prefix delegation support */ RADVPrefixDelegation router_prefix_delegation; usec_t router_lifetime_usec; diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index 179eeac017..24ef5b46bc 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -712,6 +712,30 @@ int network_add_ipv4ll_route(Network *network) { return 0; } +int network_add_default_route_on_device(Network *network) { + _cleanup_(route_free_or_set_invalidp) Route *n = NULL; + int r; + + assert(network); + + if (!network->default_route_on_device) + return 0; + + /* DefaultRouteOnDevice= is in [Network] section. */ + r = route_new_static(network, NULL, 0, &n); + if (r < 0) + return r; + + r = in_addr_from_string(AF_INET, "169.254.0.0", &n->dst); + if (r < 0) + return r; + + n->family = AF_INET; + + TAKE_PTR(n); + return 0; +} + int config_parse_gateway( const char *unit, const char *filename, diff --git a/src/network/networkd-route.h b/src/network/networkd-route.h index 892da25bd5..4643f77854 100644 --- a/src/network/networkd-route.h +++ b/src/network/networkd-route.h @@ -62,6 +62,7 @@ int route_section_verify(Route *route, Network *network); DEFINE_NETWORK_SECTION_FUNCTIONS(Route, route_free); int network_add_ipv4ll_route(Network *network); +int network_add_default_route_on_device(Network *network); CONFIG_PARSER_PROTOTYPE(config_parse_gateway); CONFIG_PARSER_PROTOTYPE(config_parse_preferred_src); diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network index 06813c29fe..ef29c7951f 100644 --- a/test/fuzz/fuzz-network-parser/directives.network +++ b/test/fuzz/fuzz-network-parser/directives.network @@ -89,6 +89,7 @@ IPMasquerade= ProxyARP= PrimarySlave= IPv4LLRoute= +DefaultRouteOnDevice= Address= IPv6ProxyNDPAddress= IPv6AcceptRA= From 6543b7fd78f907ab103ffc6aec82a92ed165e9ef Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 7 May 2019 06:18:30 +0200 Subject: [PATCH 3/4] test-network: add tests for DefaultRouteOnDevice= --- test/test-network/conf/25-route-static.network | 1 + test/test-network/systemd-networkd-tests.py | 1 + 2 files changed, 2 insertions(+) diff --git a/test/test-network/conf/25-route-static.network b/test/test-network/conf/25-route-static.network index 50b2ce0c3b..4d94ab92a8 100644 --- a/test/test-network/conf/25-route-static.network +++ b/test/test-network/conf/25-route-static.network @@ -5,6 +5,7 @@ Name=dummy98 IPv6AcceptRA=no Address=2001:1234:5:8f63::1/128 Address=149.10.124.58/28 +DefaultRouteOnDevice=yes [Route] Destination=2001:1234:5:8fff:ff:ff:ff:ff/128 diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index e65897561b..ab742d31f5 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -1209,6 +1209,7 @@ class NetworkdNetWorkTests(unittest.TestCase, Utilities): output = subprocess.check_output(['ip', '-4', 'route', 'show', 'dev', 'dummy98', 'default']).rstrip().decode('utf-8') self.assertRegex(output, 'default via 149.10.125.65 proto static onlink') self.assertRegex(output, 'default via 149.10.124.64 proto static') + self.assertRegex(output, 'default proto static') output = subprocess.check_output(['ip', 'route', 'show', 'type', 'blackhole']).rstrip().decode('utf-8') print(output) From 2b00dff809ab69a0944d94d2fc6408365a1b33a6 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 15 May 2019 12:43:36 +0900 Subject: [PATCH 4/4] test-network: add a test for IPv4LLRoute= --- test/test-network/conf/25-route-static.network | 1 + test/test-network/systemd-networkd-tests.py | 1 + 2 files changed, 2 insertions(+) diff --git a/test/test-network/conf/25-route-static.network b/test/test-network/conf/25-route-static.network index 4d94ab92a8..9e12480a65 100644 --- a/test/test-network/conf/25-route-static.network +++ b/test/test-network/conf/25-route-static.network @@ -6,6 +6,7 @@ IPv6AcceptRA=no Address=2001:1234:5:8f63::1/128 Address=149.10.124.58/28 DefaultRouteOnDevice=yes +IPv4LLRoute=yes [Route] Destination=2001:1234:5:8fff:ff:ff:ff:ff/128 diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index ab742d31f5..9c665d9f93 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -1203,6 +1203,7 @@ class NetworkdNetWorkTests(unittest.TestCase, Utilities): print(output) self.assertRegex(output, '149.10.124.48/28 proto kernel scope link src 149.10.124.58') self.assertRegex(output, '149.10.124.64 proto static scope link') + self.assertRegex(output, '169.254.0.0/16 proto static scope link metric 2048') self.assertRegex(output, '192.168.1.1 proto static initcwnd 20') self.assertRegex(output, '192.168.1.2 proto static initrwnd 30')