On Tue, Jun 12, 2018 at 06:01:49PM -0400, Kenneth R Westerback wrote:
> On Sun, Jun 10, 2018 at 02:15:09PM -0400, Kenneth R Westerback wrote:
> > On Sat, Jun 09, 2018 at 02:10:09PM +0200, Claudio Jeker wrote:
> > > On Sat, Jun 09, 2018 at 01:31:20PM +0200, Martin Pieuchot wrote:
> > > > On 08/06/18(Fri) 18:06, Kenneth R Westerback wrote:
> > > > > Testing at the alternate DHCP lab (the one that serves beer) I find
> > > > > that its wifi gives me the lease
> > > > > 
> > > > > lease {
> > > > >   fixed-address 10.112.38.73;
> > > > >   next-server 0.0.0.0;
> > > > >   option subnet-mask 255.255.255.0;
> > > > >   option routers 10.112.33.1;
> > > > >   option domain-name-servers 63.250.111.34,63.250.111.35,8.8.8.8;
> > > > >   option dhcp-lease-time 14400;
> > > > >   option dhcp-message-type 5;
> > > > >   option dhcp-server-identifier 10.112.38.1;
> > > > >   option dhcp-renewal-time 7200;
> > > > >   option dhcp-rebinding-time 12600;
> > > > >   option dhcp-client-identifier 1:9c:4e:36:d6:7e:f8;
> > > > >   epoch 1528494503;
> > > > >   renew 5 2018/06/08 23:48:23 UTC;
> > > > >   rebind 6 2018/06/09 01:18:23 UTC;
> > > > >   expire 6 2018/06/09 01:48:23 UTC;
> > > > > }
> > > > > 
> > > > > See the problem? If so, skip the next paragraph.
> > > > > 
> > > > > Note that I get an address of 10.112.38.73/24 and a default route of
> > > > > 10.112.33.1. When dhclient attempts to add the default route our stack
> > > > > rejects the attempt as 10.112.33.1 is unreachable! Not only does this
> > > > > mean the outside world is unreachable, /etc/resolv.conf will not be
> > > > > updated because the wifi interface will not own the default route, and
> > > > > thus DNS will not work!
> > > > > 
> > > > > As this particular DHCP testing facility not only serves beer but
> > > > > provides paper table coverings and a basket of crayons (although I had
> > > > > to surrender my blue crayon to a young artist at the next table) I
> > > > > was able to do some complex bit calculations and determine that
> > > > > 255.255.240.0 would put the default route and the address in the same
> > > > > subnet. I therefore added
> > > > > 
> > > > > supersede subnet-mask 255.255.240.0;
> > > > > 
> > > > > to my dhclient.conf and viola (sic)! I had net.
> > > > > 
> > > > > Checking the iPhone I see the same issue, but the iPhone does connect
> > > > > to the network without manual magic. A little birdie told me that IOS
> > > > > may be playing games with the provided subnet mask to ensure the
> > > > > default route is reachable.
> > > > 
> > > > Can you check what is the configured address' mask on iOS?
> > > > 
> > > > > I'm wondering if this auto subnet-mask trimming to ensure the default
> > > > > route would be reachable is worthwhile adding? Or if it might break
> > > > > more situations than it fixes.
> > > > 
> > > > I'd say that there's nothing more frustrating than having a non 
> > > > functional
> > > > network connection after having used dhclient(8).  So I doubt we're 
> > > > going
> > > > to break anything.  However I'm wondering what other OSes are doing 
> > > > because
> > > > I'm not sure we should work around broken configs :)
> > > 
> > > Isn't this similar to the google cloud dhcp mode where you get a /32 host
> > > IP and a gateway (which is not part of the the /32 obviously).
> > > IIRC this is what some other systems do more or less.
> > > I think a trick could be to insert the gateway as a /32 cloning route then
> > > arp would resolve the gateway which I assume works just fine. Now how to
> > > do this exactly is an excercise for the reader ;)
> > > 
> > > 
> > > -- 
> > > :wq Claudio
> > 
> > Turning Claudio's idea into a diff gives the diff below.
> > 
> > Testing at DHCP Lab B gives a routing table
> > 
> > Internet:
> > Destination        Gateway            Flags   Refs      Use   Mtu  Prio 
> > Iface Label
> > default            10.112.33.1        GS        29      187     -    12 
> > iwn0 
> > 224/4              127.0.0.1          URS        0       23 32768     8 lo0 
> >  
> > 10.112.33/24       10.112.38.215      CS         1        0     -    12 
> > iwn0 
> > 10.112.33.1        a4:6c:2a:5e:8a:de  HLch       1        5     -    11 
> > iwn0 
> > 10.112.38/24       10.112.38.215      Cn         0        9     -     8 
> > iwn0 
> > 10.112.38.215      9c:4e:36:d6:7e:f8  UHLl       0       35     -     1 
> > iwn0 
> > 10.112.38.255      10.112.38.215      Hb         0        1     -     1 
> > iwn0 
> > 127/8              127.0.0.1          UGRS       0        0 32768     8 lo0 
> >  
> > 127.0.0.1          127.0.0.1          UHhl       1        2 32768     1 lo0 
> >  
> > x230$
> > 
> > and a resolv.conf
> > 
> > # Generated by iwn0 dhclient
> > nameserver 63.250.111.34
> > nameserver 63.250.111.35
> > nameserver 8.8.8.8
> > lookup file bind
> > family inet4
> > 
> > after getting the lease
> > 
> > lease {
> >   fixed-address 10.112.38.215;
> >   next-server 0.0.0.0;
> >   option subnet-mask 255.255.255.0;
> >   option routers 10.112.33.1;
> >   option domain-name-servers 63.250.111.34,63.250.111.35,8.8.8.8;
> >   option dhcp-lease-time 14400;
> >   option dhcp-message-type 5;
> >   option dhcp-server-identifier 10.112.38.1;
> >   option dhcp-renewal-time 7200;
> >   option dhcp-rebinding-time 12600;
> >   option dhcp-client-identifier 1:9c:4e:36:d6:7e:f8;
> >   epoch 1528651658;
> >   renew 0 2018/06/10 19:27:38 UTC;
> >   rebind 0 2018/06/10 20:57:38 UTC;
> >   expire 0 2018/06/10 21:27:38 UTC;
> > }
> > 
> > And it works! As sending this email proves. :-)
> > 
> > Now, whether it is a good idea ... none of the Google incantations I
> > used turned up evidence that this is a normal behaviour.
> > 
> > Thoughts/OK's welcome. Editorial advice on making the
> > comment more coherent and useful also sought. :-)
> > 
> > .... Ken
> >                              *     -cloning -iface $addr
> 
> henning@ points out that the previous diff is adding a /24 route and
> not a /32 route as intended. The existing code was relying on the
> address mask being 255.255.255.255. a.k.a. INADDR_BROADCAST.
> 
> So add a constant 'broadast' alongside the constant 'any' and use that
> when adding the /32 routes.
> 
> The resulting routing table looks like
> 
> Routing tables
> 
> Internet:
> Destination        Gateway            Flags   Refs      Use   Mtu  Prio Iface 
> Label
> default            10.112.33.1        UGS        1       30     -    12 iwn0 
> default            172.16.4.1         GS         0      352     -     8 em0  
> 224/4              127.0.0.1          URS        0     1440 32768     8 lo0  
> 10.112.33.1        a4:6c:2a:5e:8a:de  UHLch      1       11     -    11 iwn0 
> 10.112.33.1/32     10.112.38.159      UCS        1        0     -    12 iwn0 
> 10.112.38/24       10.112.38.159      UCn        0       25     -     8 iwn0 
> 10.112.38.159      9c:4e:36:d6:7e:f8  UHLl       0       17     -     1 iwn0 
> 10.112.38.255      10.112.38.159      UHb        0        0     -     1 iwn0 
> 127/8              127.0.0.1          UGRS       0        0 32768     8 lo0  
> 127.0.0.1          127.0.0.1          UHhl       1        2 32768     1 lo0  
> 172.16.4/24        172.16.4.87        Cn         1       91     -     4 em0  
> 172.16.4.1         link#1             HLch       2       38     -     3 em0  
> 172.16.4.87        3c:97:0e:e7:f4:a5  UHLl       0      138     -     1 em0  
> 172.16.4.255       172.16.4.87        Hb         0       22     -     1 em0  
> 
> If you see this it still works.
> 

I like it. Two comments though.


> Index: kroute.c
> ===================================================================
> RCS file: /cvs/src/sbin/dhclient/kroute.c,v
> retrieving revision 1.155
> diff -u -p -r1.155 kroute.c
> --- kroute.c  6 Feb 2018 00:25:09 -0000       1.155
> +++ kroute.c  12 Jun 2018 13:22:53 -0000
> @@ -221,11 +221,15 @@ set_routes(struct in_addr addr, struct i
>      unsigned int rtstatic_len)
>  {
>       const struct in_addr     any = { INADDR_ANY };
> +     const struct in_addr     broadcast = { INADDR_BROADCAST };
>       struct in_addr           dest, gateway, netmask;
> +     in_addr_t                addrnet, gatewaynet;
>       unsigned int             i, len;
>  
>       flush_routes(rtstatic, rtstatic_len);
>  
> +     addrnet = addr.s_addr & addrmask.s_addr;
> +
>       /* Add classless static routes. */
>       i = 0;
>       while (i < rtstatic_len) {
> @@ -248,19 +252,28 @@ set_routes(struct in_addr addr, struct i
>                       /*
>                        * DEFAULT ROUTE
>                        */
> -                     if (addrmask.s_addr == INADDR_BROADCAST) {
> +                     gatewaynet = gateway.s_addr & addrmask.s_addr;
> +                     if ((addrmask.s_addr == INADDR_BROADCAST) ||
> +                         (gatewaynet != addrnet)) {

If addrmask.s_addr == INADDR_BROADCAST then gatewaynet = gateway.s_addr
and so I think (gatewaynet != addrnet) unless addr.s_addr = gateway.s_addr
(which is not valid or working). So I think

                        gatewaynet = gateway.s_addr & addrmask.s_addr;
                        if (gatewaynet != addrnet) {

is enough to check the direct route case.


>                               /*
>                                * DIRECT ROUTE TO DEFAULT GATEWAY
>                                *
> -                              * To be compatible with ISC DHCP behavior on
> -                              * Linux, if we were given a /32 IP assignment
> +                              * If the default route gateway is not reachable
> +                              * via the address/netmask being configured on
> +                              * the interface then add a direct route for
> +                              * the gateway. Deals with weird configs seen
> +                              * in the wild.
> +                              *
> +                              * e.g if we were given a /32h IP assignment
                                                             ^
                                      Since when we have 32 hours of IP?

Maybe also add cloning to "add a direct route for the gateway."

>                                * then add a /32 direct route for the gateway
> -                              * to make it routable.
> +                              * to make it reachable. a.k.a. "make Google
> +                              * Cloud DHCP work".
>                                *
> -                              * route add -net $gateway -netmask $addrmask
> -                              *     -cloning -iface $addr
> +                              * route add -net $gateway
> +                              *      -netmask 255.255.255.255
> +                              *      -cloning -iface $addr
>                                */
> -                             add_route(gateway, addrmask, addr,
> +                             add_route(gateway, broadcast, addr,
>                                   RTF_STATIC | RTF_CLONING);
>                       }
>                       
> 

Anyway just nitpicking. Diff is OK claudio@

-- 
:wq Claudio

Reply via email to