diff options
author | Matthew Dempsky <matthew@cvs.openbsd.org> | 2014-10-02 18:04:50 +0000 |
---|---|---|
committer | Matthew Dempsky <matthew@cvs.openbsd.org> | 2014-10-02 18:04:50 +0000 |
commit | ef963bc3850c357867faea5fa8e5c1d85e035d83 (patch) | |
tree | 833cd43d5167b5c59dcc4fef56b24a4aa585f828 /sbin/dhclient/dhclient.c | |
parent | 71c2d335730e3942d301cd9fd07953d4d0307a96 (diff) |
dhclient: add support for RFC 3442 local subnet routes
If the classless-static-routes option specifies the router IP address
as 0.0.0.0, then that indicates the route is a "local subnet route"
that should be directly routable via the interface. This reuses the
"route add -net $dest -netmask $mask -cloning -iface $addr" trick
suggested by claudio@ for r1.272.
Restores interoperability with Google Compute Engine after recent GCE
DHCP server changes.
ok krw, mpi
Diffstat (limited to 'sbin/dhclient/dhclient.c')
-rw-r--r-- | sbin/dhclient/dhclient.c | 51 |
1 files changed, 32 insertions, 19 deletions
diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c index eca0134e8f6..ad3fbb5c72e 100644 --- a/sbin/dhclient/dhclient.c +++ b/sbin/dhclient/dhclient.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dhclient.c,v 1.319 2014/08/11 18:41:13 tobias Exp $ */ +/* $OpenBSD: dhclient.c,v 1.320 2014/10/02 18:04:49 matthew Exp $ */ /* * Copyright 2004 Henning Brauer <henning@openbsd.org> @@ -108,9 +108,10 @@ struct client_lease *clone_lease(struct client_lease *); void socket_nonblockmode(int); void apply_ignore_list(char *); +void add_direct_route(int, struct in_addr, struct in_addr, struct in_addr); void add_default_route(int, struct in_addr, struct in_addr); void add_static_routes(int, struct option_data *); -void add_classless_static_routes(int, struct option_data *); +void add_classless_static_routes(int, struct option_data *, struct in_addr); int compare_lease(struct client_lease *, struct client_lease *); void set_lease_times(struct client_lease *); @@ -872,10 +873,12 @@ bind_lease(void) add_address(ifi->name, ifi->rdomain, client->active->address, mask); if (options[DHO_CLASSLESS_STATIC_ROUTES].len) { add_classless_static_routes(ifi->rdomain, - &options[DHO_CLASSLESS_STATIC_ROUTES]); + &options[DHO_CLASSLESS_STATIC_ROUTES], + client->active->address); } else if (options[DHO_CLASSLESS_MS_STATIC_ROUTES].len) { add_classless_static_routes(ifi->rdomain, - &options[DHO_CLASSLESS_MS_STATIC_ROUTES]); + &options[DHO_CLASSLESS_MS_STATIC_ROUTES], + client->active->address); } else { opt = &options[DHO_ROUTERS]; if (opt->len >= sizeof(gateway)) { @@ -883,17 +886,13 @@ bind_lease(void) gateway.s_addr = ((struct in_addr *)opt->data)->s_addr; /* - * If we were given a /32 IP assignment, then make sure - * the gateway address is routable with equivalent of - * - * route add -net $gw -netmask 255.255.255.255 \ - * -cloning -iface $addr + * To be compatible with ISC DHCP behavior on Linux, if + * we were given a /32 IP assignment, then add a /32 + * direct route for the gateway to make it routable. */ if (mask.s_addr == INADDR_BROADCAST) { - add_route(ifi->rdomain, gateway, mask, - client->active->address, - RTA_DST | RTA_NETMASK | RTA_GATEWAY, - RTF_CLONING | RTF_STATIC); + add_direct_route(ifi->rdomain, gateway, mask, + client->active->address); } add_default_route(ifi->rdomain, client->active->address, @@ -2368,6 +2367,18 @@ priv_write_file(struct imsg_write_file *imsg) } /* + * add_direct_route is the equivalent of + * + * route add -net $dest -netmask $mask -cloning -iface $iface + */ +void +add_direct_route(int rdomain, struct in_addr dest, struct in_addr mask, struct in_addr iface) +{ + add_route(rdomain, dest, mask, iface, + RTA_DST | RTA_NETMASK | RTA_GATEWAY, RTF_CLONING | RTF_STATIC); +} + +/* * add_default_route is the equivalent of * * route -q $rdomain add default -iface $router @@ -2424,7 +2435,9 @@ add_static_routes(int rdomain, struct option_data *static_routes) } } -void add_classless_static_routes(int rdomain, struct option_data *opt) +void +add_classless_static_routes(int rdomain, struct option_data *opt, + struct in_addr iface) { struct in_addr dest, netmask, gateway; int bits, bytes, i; @@ -2454,11 +2467,11 @@ void add_classless_static_routes(int rdomain, struct option_data *opt) i += sizeof(gateway); if (gateway.s_addr == INADDR_ANY) - continue; /* OBSD TCP/IP doesn't support this. */ - - add_route(rdomain, dest, netmask, gateway, - RTA_DST | RTA_GATEWAY | RTA_NETMASK, - RTF_GATEWAY | RTF_STATIC); + add_direct_route(rdomain, dest, netmask, iface); + else + add_route(rdomain, dest, netmask, gateway, + RTA_DST | RTA_GATEWAY | RTA_NETMASK, + RTF_GATEWAY | RTF_STATIC); } } |