From 156ddf8df7e0182254419095e86db98f54ab2912 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 22 Jul 2019 11:22:28 +0900 Subject: [PATCH] network: disable kernel creating prefix route when RouteTable= is set Closes #8726. --- src/network/networkd-dhcp4.c | 55 +++++++++++++++++++++ test/test-network/systemd-networkd-tests.py | 5 +- 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index f20254fc827..356b9e9d316 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -85,6 +85,11 @@ static int route_scope_from_address(const Route *route, const struct in_addr *se return RT_SCOPE_UNIVERSE; } +static bool link_noprefixroute(Link *link) { + return link->network->dhcp_route_table_set && + link->network->dhcp_route_table != RT_TABLE_MAIN; +} + static int dhcp_route_configure(Route **route, Link *link) { int r; @@ -193,6 +198,31 @@ static int link_set_dhcp_routes(Link *link) { if (r < 0) return log_link_warning_errno(link, r, "DHCP error: could not get address: %m"); + if (link_noprefixroute(link)) { + _cleanup_(route_freep) Route *prefix_route = NULL; + struct in_addr netmask; + + r = sd_dhcp_lease_get_netmask(link->dhcp_lease, &netmask); + if (r < 0) + return log_link_error_errno(link, r, "DHCP error: No netmask: %m"); + + r = route_new(&prefix_route); + if (r < 0) + return log_link_error_errno(link, r, "Could not allocate route: %m"); + + prefix_route->family = AF_INET; + prefix_route->dst.in.s_addr = address.s_addr & netmask.s_addr; + prefix_route->dst_prefixlen = in4_addr_netmask_to_prefixlen(&netmask); + prefix_route->prefsrc.in = address; + prefix_route->scope = RT_SCOPE_LINK; + prefix_route->protocol = RTPROT_DHCP; + prefix_route->table = table; + + r = dhcp_route_configure(&prefix_route, link); + if (r < 0) + return log_link_error_errno(link, r, "Could not set prefix route: %m"); + } + n = sd_dhcp_lease_get_routes(link->dhcp_lease, &static_routes); if (n == -ENODATA) log_link_debug_errno(link, n, "DHCP: No routes received from DHCP server: %m"); @@ -443,6 +473,30 @@ static int dhcp_remove_dns_routes(Link *link, sd_dhcp_lease *lease, const struct (void) route_remove(route, link, NULL); } + if (link_noprefixroute(link)) { + _cleanup_(route_freep) Route *prefix_route = NULL; + struct in_addr netmask; + + r = route_new(&prefix_route); + if (r < 0) + return log_link_error_errno(link, r, "Could not allocate route: %m"); + + r = sd_dhcp_lease_get_netmask(lease, &netmask); + if (r < 0) + return log_link_error_errno(link, r, "DHCP error: No netmask: %m"); + + prefix_route->family = AF_INET; + prefix_route->dst.in.s_addr = address->s_addr & netmask.s_addr; + prefix_route->dst_prefixlen = in4_addr_netmask_to_prefixlen(&netmask); + prefix_route->prefsrc.in = *address; + prefix_route->scope = RT_SCOPE_LINK; + prefix_route->protocol = RTPROT_DHCP; + prefix_route->table = table; + + if (remove_all || !set_contains(link->dhcp_routes, prefix_route)) + (void) route_remove(prefix_route, link, NULL); + } + return 0; } @@ -610,6 +664,7 @@ static int dhcp4_update_address(Link *link, addr->cinfo.ifa_valid = lifetime; addr->prefixlen = prefixlen; addr->broadcast.s_addr = address->s_addr | ~netmask->s_addr; + addr->prefix_route = link_noprefixroute(link); /* allow reusing an existing address and simply update its lifetime * in case it already exists */ diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index d73895aeab1..171df79eca4 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -2465,16 +2465,17 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities): self.assertRegex(output, '192.168.5') self.assertRegex(output, '1492') - # issue #8726 print('## ip route show table main dev veth99') output = check_output('ip route show table main dev veth99') print(output) - self.assertNotRegex(output, 'proto dhcp') + # See issue #8726 + self.assertEqual(output, '') print('## ip route show table 211 dev veth99') output = check_output('ip route show table 211 dev veth99') print(output) self.assertRegex(output, 'default via 192.168.5.1 proto dhcp') + self.assertRegex(output, '192.168.5.0/24 proto dhcp') self.assertRegex(output, '192.168.5.0/24 via 192.168.5.5 proto dhcp') self.assertRegex(output, '192.168.5.1 proto dhcp scope link') -- 2.47.3