On Wed, Dec 04, 2013 at 10:57:41AM -0800, Matthew Dempsky wrote: > On Tue, Dec 03, 2013 at 11:48:05PM -0500, Kenneth Westerback wrote: > > Rfc 3442 is what I referred to. > > I don't think RFC 3442 discusses what to do with /32 IP address > assignments though?
No, that was my point. i.e. don't avoid adding the route when given a /32 address just because class static routes are also present. > > Anyway, below is a revised diff that does the same direct-route magic > for all gateway IPs, not just the default gateway IP. I'll try this > out later today to make sure it still works with Compute Engine. > > Assuming it works as intended, ok? Not from me. This is way bigger that the last three line diff, and I have insufficient routing foo to comment on the usefulness of all these routes. .... Ken > > Index: dhclient.c > =================================================================== > RCS file: /cvs/src/sbin/dhclient/dhclient.c,v > retrieving revision 1.268 > diff -u -p -r1.268 dhclient.c > --- dhclient.c 20 Nov 2013 17:22:46 -0000 1.268 > +++ dhclient.c 4 Dec 2013 18:45:21 -0000 > @@ -107,9 +107,11 @@ struct client_lease *clone_lease(struct > void socket_nonblockmode(int); > void apply_ignore_list(char *); > > -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_default_route(int, struct in_addr, struct in_addr, struct in_addr); > +void add_static_routes(int, struct in_addr, struct in_addr, > + struct option_data *); > +void add_classless_static_routes(int, struct in_addr, struct in_addr, > + struct option_data *); > > int compare_lease(struct client_lease *, struct client_lease *); > > @@ -871,8 +873,8 @@ bind_lease(void) > */ > add_address(ifi->name, ifi->rdomain, client->new->address, mask); > if (options[DHO_CLASSLESS_STATIC_ROUTES].len) { > - add_classless_static_routes(ifi->rdomain, > - &options[DHO_CLASSLESS_STATIC_ROUTES]); > + add_classless_static_routes(ifi->rdomain, client->new->address, > + mask, &options[DHO_CLASSLESS_STATIC_ROUTES]); > } else { > if (options[DHO_ROUTERS].len) { > memset(&gateway, 0, sizeof(gateway)); > @@ -880,11 +882,11 @@ bind_lease(void) > memcpy(&gateway.s_addr, options[DHO_ROUTERS].data, > options[DHO_ROUTERS].len); > add_default_route(ifi->rdomain, client->new->address, > - gateway); > + mask, gateway); > } > if (options[DHO_STATIC_ROUTES].len) > - add_static_routes(ifi->rdomain, > - &options[DHO_STATIC_ROUTES]); > + add_static_routes(ifi->rdomain, client->new->address, > + mask, &options[DHO_STATIC_ROUTES]); > } > > client->new->resolv_conf = resolv_conf_contents( > @@ -2379,6 +2381,23 @@ priv_write_file(struct imsg_write_file * > } > > /* > + * If we were given a /32 IP address assignment, then make sure the > + * gateway address is routable with the equivalent of > + * > + * route add -net $gw -netmask 255.255.255.255 -cloning -iface $addr > + */ > +void > +ensure_direct_route(int rdomain, struct in_addr addr, struct in_addr > addrmask, > + struct in_addr gateway) > +{ > + if (addrmask.s_addr == INADDR_BROADCAST) { > + add_route(rdomain, gateway, addrmask, addr, > + RTA_DST | RTA_NETMASK | RTA_GATEWAY, > + RTF_CLONING | RTF_STATIC); > + } > +} > + > +/* > * add_default_route is the equivalent of > * > * route -q $rdomain add default -iface $router > @@ -2388,11 +2407,14 @@ priv_write_file(struct imsg_write_file * > * route -q $rdomain add default $router > */ > void > -add_default_route(int rdomain, struct in_addr addr, struct in_addr gateway) > +add_default_route(int rdomain, struct in_addr addr, struct in_addr addrmask, > + struct in_addr gateway) > { > struct in_addr netmask, dest; > int addrs, flags; > > + ensure_direct_route(rdomain, addr, addrmask, gateway); > + > memset(&netmask, 0, sizeof(netmask)); > memset(&dest, 0, sizeof(dest)); > addrs = RTA_DST | RTA_NETMASK; > @@ -2412,23 +2434,26 @@ add_default_route(int rdomain, struct in > } > > void > -add_static_routes(int rdomain, struct option_data *static_routes) > +add_static_routes(int rdomain, struct in_addr addr, struct in_addr addrmask, > + struct option_data *static_routes) > { > struct in_addr dest, netmask, gateway; > - u_int8_t *addr; > + u_int8_t *data; > int i; > > memset(&netmask, 0, sizeof(netmask)); /* Not used for CLASSFULL! */ > > for (i = 0; (i + 7) < static_routes->len; i += 8) { > - addr = &static_routes->data[i]; > + data = &static_routes->data[i]; > memset(&dest, 0, sizeof(dest)); > memset(&gateway, 0, sizeof(gateway)); > > - memcpy(&dest.s_addr, addr, 4); > + memcpy(&dest.s_addr, data, 4); > if (dest.s_addr == INADDR_ANY) > continue; /* RFC 2132 says 0.0.0.0 is not allowed. */ > - memcpy(&gateway.s_addr, addr+4, 4); > + memcpy(&gateway.s_addr, data+4, 4); > + > + ensure_direct_route(rdomain, addr, addrmask, gateway); > > /* XXX Order implies priority but we're ignoring that. */ > add_route(rdomain, dest, netmask, gateway, > @@ -2436,8 +2461,9 @@ add_static_routes(int rdomain, struct op > } > } > > -void add_classless_static_routes(int rdomain, > - struct option_data *classless_static_routes) > +void > +add_classless_static_routes(int rdomain, struct in_addr addr, > + struct in_addr addrmask, struct option_data *classless_static_routes) > { > struct in_addr dest, netmask, gateway; > int bits, bytes, i; > @@ -2463,6 +2489,8 @@ void add_classless_static_routes(int rdo > > if (gateway.s_addr == INADDR_ANY) > continue; /* OBSD TCP/IP doesn't support this. */ > + > + ensure_direct_route(rdomain, addr, addrmask, gateway); > > add_route(rdomain, dest, netmask, gateway, > RTA_DST | RTA_GATEWAY | RTA_NETMASK, >