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

Reply via email to