summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrandon Philips <brandon@ifup.co>2014-03-20 11:28:12 -0700
committerTom Gundersen <teg@jklm.no>2014-03-21 17:52:42 +0100
commit9765ce69e15fd294db9553777b621515fa57f2c6 (patch)
tree9ca1ebec1b4c2d6d99fba93f18e4e5fca6d50df6
parent9e64dd72765ddc2583554ebed24eb2c824564838 (diff)
network: dhcp: create explicit host route to gateway
Some DHCP servers gives you a netmask of 255.255.255.255 so the gateway is not routable. Other DHCP client implementations look through the existing routes to figure out if they should add an explicit host route. See below for a link. However, it makes sense to just create the route explicitly whether it is needed or not since it is explicit, makes the dhcp route entries independent of other entries and saves us from knowing the state of the kernel tables. After patch route table on a machine with a network (common case): default via 10.0.2.2 dev ens3 10.0.2.0/24 dev ens3 proto kernel scope link src 10.0.2.15 10.0.2.2 dev ens3 scope link After patch route table on a machine without a network (this case): default via 10.240.0.1 dev ens4v1 10.240.0.1 dev ens4v1 scope link The code from dhcpcd that works around this issue is on line 637. https://android.googlesource.com/platform/external/dhcpcd/+/master/configure.c
-rw-r--r--src/network/networkd-link.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index a7ba46692c..14cc8715ce 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -228,6 +228,7 @@ static int link_enter_set_routes(Link *link) {
if (link->dhcp_lease) {
_cleanup_route_free_ Route *route = NULL;
+ _cleanup_route_free_ Route *route_gw = NULL;
struct in_addr gateway;
r = sd_dhcp_lease_get_router(link->dhcp_lease, &gateway);
@@ -244,6 +245,30 @@ static int link_enter_set_routes(Link *link) {
return r;
}
+ r = route_new_dynamic(&route_gw);
+ if (r < 0) {
+ log_error_link(link, "Could not allocate route: %s",
+ strerror(-r));
+ return r;
+ }
+
+ /* The dhcp netmask may mask out the gateway. Add an explicit
+ * route for the gw host so that we can route no matter the
+ * netmask or existing kernel route tables. */
+ route_gw->family = AF_INET;
+ route_gw->dst_addr.in = gateway;
+ route_gw->dst_prefixlen = 32;
+ route_gw->scope = RT_SCOPE_LINK;
+
+ r = route_configure(route_gw, link, &route_handler);
+ if (r < 0) {
+ log_warning_link(link,
+ "could not set host route: %s", strerror(-r));
+ return r;
+ }
+
+ link->route_messages ++;
+
route->family = AF_INET;
route->in_addr.in = gateway;