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
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 10 Jun 2018 13:20:23 -0000
@@ -222,10 +222,13 @@ set_routes(struct in_addr addr, struct i
{
const struct in_addr any = { INADDR_ANY };
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,14 +251,22 @@ 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)) {
/*
* 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 /32 IP assignment
* 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