From owner-freebsd-net@freebsd.org Sun May 29 03:29:53 2016 Return-Path: Delivered-To: freebsd-net@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id E0A8CB5247E for ; Sun, 29 May 2016 03:29:53 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from mailman.ysv.freebsd.org (unknown [127.0.1.3]) by mx1.freebsd.org (Postfix) with ESMTP id CDF8C1334 for ; Sun, 29 May 2016 03:29:53 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: by mailman.ysv.freebsd.org (Postfix) id C9B5EB5247C; Sun, 29 May 2016 03:29:53 +0000 (UTC) Delivered-To: net@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C7108B5247B for ; Sun, 29 May 2016 03:29:53 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from mail109.syd.optusnet.com.au (mail109.syd.optusnet.com.au [211.29.132.80]) by mx1.freebsd.org (Postfix) with ESMTP id 68B931333 for ; Sun, 29 May 2016 03:29:53 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from besplex.bde.org (c110-21-42-169.carlnfd1.nsw.optusnet.com.au [110.21.42.169]) by mail109.syd.optusnet.com.au (Postfix) with ESMTPS id AE409D675D2; Sun, 29 May 2016 13:29:43 +1000 (AEST) Date: Sun, 29 May 2016 13:29:42 +1000 (EST) From: Bruce Evans X-X-Sender: bde@besplex.bde.org To: David DeSimone cc: "net@freebsd.org" Subject: RE: ifconfig creates a bogus(?) route In-Reply-To: Message-ID: <20160529111806.I1012@besplex.bde.org> References: <20160528154122.C1843@besplex.bde.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.1 cv=M8SwUHEs c=1 sm=1 tr=0 a=kDyANCGC9fy361NNEb9EQQ==:117 a=kDyANCGC9fy361NNEb9EQQ==:17 a=L9H7d07YOLsA:10 a=9cW_t1CCXrUA:10 a=s5jvgZ67dGcA:10 a=kj9zAlcOel0A:10 a=DEKfGy55Wbv9R0khD5oA:9 a=CjuIK1q_8ugA:10 X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 29 May 2016 03:29:54 -0000 > Bruce Evans wrote: >> Sometime between r191220 and r201220, ifconfig started creating a bogus(?) static route. >> The following is under r248255 with "ifconfig em0 inet 192.168.2.8" (where 192.168.2.8 is >> for the local host and I don't bother typing the netmsk) done before bringing up lo0: >> >> Routing tables >> >> Internet: >> Destination Gateway Flags Refs Use Netif Expire >> 192.168.2.0/24 link#1 U 0 0 em0 >> 192.168.2.8 link#1 UHS 0 0 lo0 > > Why do you feel the route is bogus? Is it because it has a netmask? It is the second route that is bogus(?). It is bogus(?) because: (a) it is a new "feature" in some version between r191220 and r201220 (b) it is not needed (the defaults work) (c) it doesn't work (it breaks working of the defaults) (d) it produces a route to an unconfigured interface (lo0) when lo0 happens to be configured after em0. It is bogus(?) instead of bogus since it actually looks correct. Utilities obfuscate this a little by not displaying enough raw state and by displaying the state differently (even with -n). The bug seems to be just (d) combined with (a). Before (a), the order of bringing up interfaces didn't matter. After (a), lo0 must be brought up first because (d) doesn't do all the initialization required for the unconfigured lo0 and bringing up lo0 later gives an inconsistent state. I use network_interfaces= and this happens to give an order with after the primary NIC interface in some cases. The default is network_interfaces="auto". This starts with the ifconfig -l order which seems to always put lo0 _last_. However, r149726 moves lo0 first for unstated reasons. Thus most installations don't see the bug. I would have seen it even if I used auto since my userland is older than r149726. > If you don't supply a netmask, ifconfig will assume one based on the "class" (A, B, C) of the IP you've supplied. 192.168.2.8 is a Class C address and gets a /24 netmask by default. Yes, I didn't bother typing one partly because I know that the default is right for em0 and almost anything works for lo0. >> The bogus(?) route points to itself (route get shows this more clearly), and doesn't work. >> I know little about routiing, but can > fix things like this manually. Simply "route delete" >> on the bogus(?) route works in this case. An alias for lo0 also works. > > In router parlance, the route would be called a "connected" route, showing that not only do you have an IP on the subnet, but by virtue of the netmask, you are "connected" to every other IP in the same subnet range, through that interface. It will cause your system to send ARP requests through that interface for any other IP in the range, in order to communicate with them. I still haven't figured out how to set up the bogus(?) route using route add/change, but can now complete the initialization using a "route change" that appears to be null: Test script: X # Try to kill all old interfaces and routes, if any: X ifconfig em0 inet 0 X ifconfig lo0 inet 0 X netstat -rn X X # (Re)initialize in the broken order: X ifconfig em0 inet 192.168.2.8 X ifconfig lo0 inet 127.0.1 X netstat -rn X route -n get 192.168.2.8 X X # Fix up the initialization with a null change: X route change -iface 192.168.2.8 192.168.2.8 X netstat -rn X route -n get 192.168.2.8 X X # This ping works after the fixup, or with the opposite init order: X ping -c1 192.168.2.8 Output: Routing tables Y Internet: Y Destination Gateway Flags Refs Use Netif Expire Y Routing tables Y Y Internet: Y Destination Gateway Flags Refs Use Netif Expire Y 127.0.0.1 link#2 UH 0 0 lo0 Y 192.168.2.0/24 link#1 U 0 0 em0 Y 192.168.2.8 link#1 UHS 0 0 lo0 Y route to: 192.168.2.8 Y destination: 192.168.2.8 Y interface: lo0 Y flags: Y recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire Y 0 0 0 0 0 0 16384 0 Y change host 192.168.2.8: gateway 192.168.2.8 Y Routing tables Y Y Internet: Y Destination Gateway Flags Refs Use Netif Expire Y 127.0.0.1 link#2 UH 0 0 lo0 Y 192.168.2.0/24 link#1 U 0 0 em0 Y 192.168.2.8 192.168.2.8 UHS 0 0 lo0 Y route to: 192.168.2.8 Y destination: 192.168.2.8 Y interface: lo0 Y flags: Y recvpipe sendpipe ssthresh rtt,msec rttvar hopcount mtu expire Y 0 0 0 0 0 0 16384 0 Y PING 192.168.2.8 (192.168.2.8): 56 data bytes Y 64 bytes from 192.168.2.8: icmp_seq=0 ttl=64 time=0.005 ms Y Y --- 192.168.2.8 ping statistics --- Y 1 packets transmitted, 1 packets received, 0% packet loss Y round-trip min/avg/max/stddev = 0.005/0.005/0.005/0.000 ms Note that the "null" route change just echos the current setting and it doesn't change anything according to netstat -rn and route -n, but it fixes up some internal state so that the ping works. When ping works, tcpdump shows it going from 127.0.0.1 to 192.168.2.8 and coming back as expected. When ping hangs, tcpdump shows it going from 0.0.0.0 to 192.168.2.8 and never coming back. The default route doesn't exist in either case. I still get confused using route(8). For the apparently-null fixup, it is necessary to use -iface. The fixup "route change 192.168.2.8 192.168.2.8" also works, but it is not a null change although it looks even more like one. It changes the Gateway according to netstat -rn from link#1 to 192.168.2.8 but doesn't change anything according to route -n get. "G" is not in flags so the Gateway is fairly bogus and is not displayed by route -n get, but something critical changed so it is a bug to not display any changes. link#1 vs 192.168.2.8 shows the difference in a cryptic way. Anyway, I can fix my original problem by unsorting network_interfaces. network_interfaces is documented in rc.conf(5). Ordering requirements for it don't seem to be mentioned there. It has no examples there. Examples in other man pages put lo0 first. Bruce