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,
>