src/network/networkd-dhcp4.c: set prefsrc for classless or static routes
authorDan Streetman <ddstreet@canonical.com>
Fri, 5 Jul 2019 20:42:38 +0000 (16:42 -0400)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 5 Jul 2019 22:36:31 +0000 (07:36 +0900)
When a DHCP server provides only a gateway, the networkd-dhcp4 code adds a
default route using that gateway, and sets the just-provided address as
the route's prefsrc; this was added in commit
46b0c76e2c355c0d0cc4792abb98cde07b28bc53

However, if the DHCP server has also provided classless route(s), these
are used instead of a default route using the provided gateway; the
networkd-dhcp4 code sets up the classless routes, but does not use the
just-provided dhcp address as the prefsrc of the route(s).  Note that
it also doesn't set the prefsrc for static routes, though it should.

If the interface has only the dhcp-provided address, this is not usually
a problem, but if it has another address (e.g. a static address), then
traffic sent through the dhcp-provided gateway might not use the
dhcp-provided source address.  If the gateway router only will route
traffic from the dhcp-provided address, then the dhcp client system's
networking through the router will not work.

Fixes: #12969

src/network/networkd-dhcp4.c

index 3e384a4..c0d776f 100644 (file)
@@ -147,6 +147,8 @@ static int link_set_dhcp_routes(Link *link) {
                 route->priority = link->network->dhcp_route_metric;
                 route->table = table;
                 route->scope = route_scope_from_address(route, &address);
+                if (IN_SET(route->scope, RT_SCOPE_LINK, RT_SCOPE_UNIVERSE))
+                        route->prefsrc.in = address;
 
                 r = route_configure(route, link, dhcp4_route_handler);
                 if (r < 0)
@@ -277,6 +279,8 @@ static int dhcp_remove_routes(Link *link, sd_dhcp_lease *lease, sd_dhcp_lease *n
                 route->priority = link->network->dhcp_route_metric;
                 route->table = table;
                 route->scope = route_scope_from_address(route, address);
+                if (IN_SET(route->scope, RT_SCOPE_LINK, RT_SCOPE_UNIVERSE))
+                        route->prefsrc.in = *address;
 
                 if (route_present_in_routes(route, new_routes, m))
                         continue;